source: bootcd/isolinux/syslinux-6.03/com32/gpllib/acpi/madt.c @ e16e8f2

Last change on this file since e16e8f2 was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/* ----------------------------------------------------------------------- *
2 *
3 *   Copyright 2009-2011 Erwan Velu - All Rights Reserved
4 *
5 *   Permission is hereby granted, free of charge, to any person
6 *   obtaining a copy of this software and associated documentation
7 *   files (the "Software"), to deal in the Software without
8 *   restriction, including without limitation the rights to use,
9 *   copy, modify, merge, publish, distribute, sublicense, and/or
10 *   sell copies of the Software, and to permit persons to whom
11 *   the Software is furnished to do so, subject to the following
12 *   conditions:
13 *
14 *   The above copyright notice and this permission notice shall
15 *   be included in all copies or substantial portions of the Software.
16 *
17 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 *   OTHER DEALINGS IN THE SOFTWARE.
25 *
26 * -----------------------------------------------------------------------
27*/
28
29#include <stdio.h>
30#include <string.h>
31#include <memory.h>
32#include <dprintf.h>
33#include <stdlib.h>
34#include "acpi/acpi.h"
35
36/* Parse the apic structures */
37static uint8_t *add_apic_structure(s_acpi * acpi, uint8_t * q)
38{
39    uint8_t type = *q;
40    q++;
41    uint8_t length = *q;
42    q++;
43    s_processor_local_apic *sla;
44    s_io_apic *sio;
45    s_interrupt_source_override *siso;
46    s_nmi *snmi;
47    s_local_apic_nmi *slan;
48    s_local_apic_address_override *slaao;
49    s_io_sapic *siosapic;
50    s_local_sapic *sls;
51    s_madt *madt = &acpi->madt;
52
53    switch (type) {
54    case PROCESSOR_LOCAL_APIC:
55        sla = &madt->processor_local_apic[madt->processor_local_apic_count];
56        sla->type = type;
57        sla->length = length;
58        cp_struct(&sla->acpi_id);
59        cp_struct(&sla->apic_id);
60        cp_struct(&sla->flags);
61        madt->processor_local_apic_count++;
62        break;
63    case IO_APIC:
64        sio = &madt->io_apic[madt->io_apic_count];
65        sio->type = type;
66        sio->length = length;
67        cp_struct(&sio->io_apic_id);
68        cp_struct(&sio->reserved);
69        cp_struct(&sio->io_apic_address);
70        cp_struct(&sio->global_system_interrupt_base);
71        madt->io_apic_count++;
72        break;
73    case INTERRUPT_SOURCE_OVERRIDE:
74        siso =
75            &madt->interrupt_source_override[madt->
76                                             interrupt_source_override_count];
77        siso->type = type;
78        siso->length = length;
79        siso->bus = *q;
80        q++;
81        siso->source = *q;
82        q++;
83        cp_struct(&siso->global_system_interrupt);
84        cp_struct(&siso->flags);
85        madt->interrupt_source_override_count++;
86        break;
87    case NMI:
88        snmi = &madt->nmi[madt->nmi_count];
89        snmi->type = type;
90        snmi->length = length;
91        cp_struct(&snmi->flags);
92        cp_struct(&snmi->global_system_interrupt);
93        madt->nmi_count++;
94        break;
95    case LOCAL_APIC_NMI_STRUCTURE:
96        slan = &madt->local_apic_nmi[madt->local_apic_nmi_count];
97        slan->type = type;
98        slan->length = length;
99        cp_struct(&slan->acpi_processor_id);
100        cp_struct(&slan->flags);
101        cp_struct(&slan->local_apic_lint);
102        madt->local_apic_nmi_count++;
103        break;
104    case LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE:
105        slaao =
106            &madt->local_apic_address_override[madt->
107                                               local_apic_address_override_count];
108        slaao->type = type;
109        slaao->length = length;
110        cp_struct(&slaao->reserved);
111        cp_struct(&slaao->local_apic_address);
112        madt->local_apic_address_override_count++;
113        break;
114    case IO_SAPIC:
115        siosapic = &madt->io_sapic[madt->io_sapic_count];
116        siosapic->type = type;
117        siosapic->length = length;
118        cp_struct(&siosapic->io_apic_id);
119        cp_struct(&siosapic->reserved);
120        cp_struct(&siosapic->global_system_interrupt_base);
121        cp_struct(&siosapic->io_sapic_address);
122        madt->io_sapic_count++;
123        break;
124    case LOCAL_SAPIC:
125        sls = &madt->local_sapic[madt->local_sapic_count];
126        sls->type = type;
127        sls->length = length;
128        cp_struct(&sls->acpi_processor_id);
129        cp_struct(&sls->local_sapic_id);
130        cp_struct(&sls->local_sapic_eid);
131        cp_struct(sls->reserved);
132        cp_struct(&sls->flags);
133        cp_struct(&sls->acpi_processor_uid_value);
134        if ((sls->acpi_processor_uid_string =
135             malloc(length - ACPI_PROCESSOR_UID_STRING_OFFSET)) != NULL) {
136            memcpy(sls->acpi_processor_uid_string, q,
137                   length - ACPI_PROCESSOR_UID_STRING_OFFSET);
138            q += length - ACPI_PROCESSOR_UID_STRING_OFFSET;
139        }
140        madt->local_sapic_count++;
141        break;
142    default:
143        printf("Unkown APIC structure type %u, size=%u \n", type, length);
144        q += length - 2;
145        break;
146    }
147    return q;
148}
149
150void parse_madt(s_acpi * acpi)
151{
152    /* Let's seach for FADT table */
153    uint8_t *q, *max_address;
154    s_madt *m = &acpi->madt;
155
156    /* Fixing table name */
157    memcpy(m->header.signature, APIC, sizeof(APIC));
158
159    /* Copying remaining structs */
160    q = (uint8_t *)m->address;
161    q += ACPI_HEADER_SIZE;
162   
163    max_address = (uint8_t *)m->address;
164    max_address += m->header.length;
165
166    cp_struct(&m->local_apic_address);
167    cp_struct(&m->flags);
168
169    while (q <  max_address) {
170        q = add_apic_structure(acpi, q);
171    }
172}
Note: See TracBrowser for help on using the repository browser.