1 /* ----------------------------------------------------------------------- *
3 * Copyright 2009-2011 Erwan Velu - All Rights Reserved
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
14 * The above copyright notice and this permission notice shall
15 * be included in all copies or substantial portions of the Software.
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.
26 * -----------------------------------------------------------------------
34 #include "acpi/acpi.h"
36 /* Parse the apic structures */
37 static uint8_t *add_apic_structure(s_acpi
* acpi
, uint8_t * q
)
43 s_processor_local_apic
*sla
;
45 s_interrupt_source_override
*siso
;
47 s_local_apic_nmi
*slan
;
48 s_local_apic_address_override
*slaao
;
51 s_madt
*madt
= &acpi
->madt
;
54 case PROCESSOR_LOCAL_APIC
:
55 sla
= &madt
->processor_local_apic
[madt
->processor_local_apic_count
];
58 cp_struct(&sla
->acpi_id
);
59 cp_struct(&sla
->apic_id
);
60 cp_struct(&sla
->flags
);
61 madt
->processor_local_apic_count
++;
64 sio
= &madt
->io_apic
[madt
->io_apic_count
];
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
++;
73 case INTERRUPT_SOURCE_OVERRIDE
:
75 &madt
->interrupt_source_override
[madt
->
76 interrupt_source_override_count
];
78 siso
->length
= length
;
83 cp_struct(&siso
->global_system_interrupt
);
84 cp_struct(&siso
->flags
);
85 madt
->interrupt_source_override_count
++;
88 snmi
= &madt
->nmi
[madt
->nmi_count
];
90 snmi
->length
= length
;
91 cp_struct(&snmi
->flags
);
92 cp_struct(&snmi
->global_system_interrupt
);
95 case LOCAL_APIC_NMI_STRUCTURE
:
96 slan
= &madt
->local_apic_nmi
[madt
->local_apic_nmi_count
];
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
++;
104 case LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE
:
106 &madt
->local_apic_address_override
[madt
->
107 local_apic_address_override_count
];
109 slaao
->length
= length
;
110 cp_struct(&slaao
->reserved
);
111 cp_struct(&slaao
->local_apic_address
);
112 madt
->local_apic_address_override_count
++;
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
++;
125 sls
= &madt
->local_sapic
[madt
->local_sapic_count
];
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
;
140 madt
->local_sapic_count
++;
143 printf("Unkown APIC structure type %u, size=%u \n", type
, length
);
150 void parse_madt(s_acpi
* acpi
)
152 /* Let's seach for FADT table */
153 uint8_t *q
, *max_address
;
154 s_madt
*m
= &acpi
->madt
;
156 /* Fixing table name */
157 memcpy(m
->header
.signature
, APIC
, sizeof(APIC
));
159 /* Copying remaining structs */
160 q
= (uint8_t *)m
->address
;
161 q
+= ACPI_HEADER_SIZE
;
163 max_address
= (uint8_t *)m
->address
;
164 max_address
+= m
->header
.length
;
166 cp_struct(&m
->local_apic_address
);
167 cp_struct(&m
->flags
);
169 while (q
< max_address
) {
170 q
= add_apic_structure(acpi
, q
);