Lines 91-160
acpi_machdep_quirks(int *quirks)
Link Here
|
91 |
} |
91 |
} |
92 |
|
92 |
|
93 |
/* |
93 |
/* |
94 |
* Support for mapping ACPI tables during early boot. Currently this |
94 |
* Map a table. First map the header to determine the table length and then map |
95 |
* uses the crashdump map to map each table. However, the crashdump |
95 |
* the entire table. |
96 |
* map is created in pmap_bootstrap() right after the direct map, so |
|
|
97 |
* we should be able to just use pmap_mapbios() here instead. |
98 |
* |
99 |
* This makes the following assumptions about how we use this KVA: |
100 |
* pages 0 and 1 are used to map in the header of each table found via |
101 |
* the RSDT or XSDT and pages 2 to n are used to map in the RSDT or |
102 |
* XSDT. This has to use 2 pages for the table headers in case a |
103 |
* header spans a page boundary. |
104 |
* |
105 |
* XXX: We don't ensure the table fits in the available address space |
106 |
* in the crashdump map. |
107 |
*/ |
108 |
|
109 |
/* |
110 |
* Map some memory using the crashdump map. 'offset' is an offset in |
111 |
* pages into the crashdump map to use for the start of the mapping. |
112 |
*/ |
113 |
static void * |
114 |
table_map(vm_paddr_t pa, int offset, vm_offset_t length) |
115 |
{ |
116 |
vm_offset_t va, off; |
117 |
void *data; |
118 |
|
119 |
off = pa & PAGE_MASK; |
120 |
length = round_page(length + off); |
121 |
pa = pa & PG_FRAME; |
122 |
va = (vm_offset_t)pmap_kenter_temporary(pa, offset) + |
123 |
(offset * PAGE_SIZE); |
124 |
data = (void *)(va + off); |
125 |
length -= PAGE_SIZE; |
126 |
while (length > 0) { |
127 |
va += PAGE_SIZE; |
128 |
pa += PAGE_SIZE; |
129 |
length -= PAGE_SIZE; |
130 |
pmap_kenter(va, pa); |
131 |
invlpg(va); |
132 |
} |
133 |
return (data); |
134 |
} |
135 |
|
136 |
/* Unmap memory previously mapped with table_map(). */ |
137 |
static void |
138 |
table_unmap(void *data, vm_offset_t length) |
139 |
{ |
140 |
vm_offset_t va, off; |
141 |
|
142 |
va = (vm_offset_t)data; |
143 |
off = va & PAGE_MASK; |
144 |
length = round_page(length + off); |
145 |
va &= ~PAGE_MASK; |
146 |
while (length > 0) { |
147 |
pmap_kremove(va); |
148 |
invlpg(va); |
149 |
va += PAGE_SIZE; |
150 |
length -= PAGE_SIZE; |
151 |
} |
152 |
} |
153 |
|
154 |
/* |
155 |
* Map a table at a given offset into the crashdump map. It first |
156 |
* maps the header to determine the table length and then maps the |
157 |
* entire table. |
158 |
*/ |
96 |
*/ |
159 |
static void * |
97 |
static void * |
160 |
map_table(vm_paddr_t pa, int offset, const char *sig) |
98 |
map_table(vm_paddr_t pa, int offset, const char *sig) |
Lines 163-181
map_table(vm_paddr_t pa, int offset, const char *sig)
Link Here
|
163 |
vm_offset_t length; |
101 |
vm_offset_t length; |
164 |
void *table; |
102 |
void *table; |
165 |
|
103 |
|
166 |
header = table_map(pa, offset, sizeof(ACPI_TABLE_HEADER)); |
104 |
header = pmap_mapbios(pa, sizeof(ACPI_TABLE_HEADER)); |
167 |
if (strncmp(header->Signature, sig, ACPI_NAMESEG_SIZE) != 0) { |
105 |
if (strncmp(header->Signature, sig, ACPI_NAMESEG_SIZE) != 0) { |
168 |
table_unmap(header, sizeof(ACPI_TABLE_HEADER)); |
106 |
pmap_unmapbios((vm_offset_t)header, sizeof(ACPI_TABLE_HEADER)); |
169 |
return (NULL); |
107 |
return (NULL); |
170 |
} |
108 |
} |
171 |
length = header->Length; |
109 |
length = header->Length; |
172 |
table_unmap(header, sizeof(ACPI_TABLE_HEADER)); |
110 |
pmap_unmapbios((vm_offset_t)header, sizeof(ACPI_TABLE_HEADER)); |
173 |
table = table_map(pa, offset, length); |
111 |
table = pmap_mapbios(pa, length); |
174 |
if (ACPI_FAILURE(AcpiTbChecksum(table, length))) { |
112 |
if (ACPI_FAILURE(AcpiTbChecksum(table, length))) { |
175 |
if (bootverbose) |
113 |
if (bootverbose) |
176 |
printf("ACPI: Failed checksum for table %s\n", sig); |
114 |
printf("ACPI: Failed checksum for table %s\n", sig); |
177 |
#if (ACPI_CHECKSUM_ABORT) |
115 |
#if (ACPI_CHECKSUM_ABORT) |
178 |
table_unmap(table, length); |
116 |
pmap_unmapbios((vm_offset_t)table, length); |
179 |
return (NULL); |
117 |
return (NULL); |
180 |
#endif |
118 |
#endif |
181 |
} |
119 |
} |
Lines 190-213
static int
Link Here
|
190 |
probe_table(vm_paddr_t address, const char *sig) |
128 |
probe_table(vm_paddr_t address, const char *sig) |
191 |
{ |
129 |
{ |
192 |
ACPI_TABLE_HEADER *table; |
130 |
ACPI_TABLE_HEADER *table; |
|
|
131 |
int ret; |
193 |
|
132 |
|
194 |
table = table_map(address, 0, sizeof(ACPI_TABLE_HEADER)); |
133 |
table = pmap_mapbios(address, sizeof(ACPI_TABLE_HEADER)); |
195 |
if (table == NULL) { |
|
|
196 |
if (bootverbose) |
197 |
printf("ACPI: Failed to map table at 0x%jx\n", |
198 |
(uintmax_t)address); |
199 |
return (0); |
200 |
} |
201 |
if (bootverbose) |
134 |
if (bootverbose) |
202 |
printf("Table '%.4s' at 0x%jx\n", table->Signature, |
135 |
printf("Table '%.4s' at 0x%jx\n", table->Signature, |
203 |
(uintmax_t)address); |
136 |
(uintmax_t)address); |
204 |
|
137 |
ret = strncmp(table->Signature, sig, ACPI_NAMESEG_SIZE) == 0; |
205 |
if (strncmp(table->Signature, sig, ACPI_NAMESEG_SIZE) != 0) { |
138 |
pmap_unmapbios((vm_offset_t)table, sizeof(ACPI_TABLE_HEADER)); |
206 |
table_unmap(table, sizeof(ACPI_TABLE_HEADER)); |
139 |
return (ret); |
207 |
return (0); |
|
|
208 |
} |
209 |
table_unmap(table, sizeof(ACPI_TABLE_HEADER)); |
210 |
return (1); |
211 |
} |
140 |
} |
212 |
|
141 |
|
213 |
/* |
142 |
/* |
Lines 228-234
acpi_unmap_table(void *table)
Link Here
|
228 |
ACPI_TABLE_HEADER *header; |
157 |
ACPI_TABLE_HEADER *header; |
229 |
|
158 |
|
230 |
header = (ACPI_TABLE_HEADER *)table; |
159 |
header = (ACPI_TABLE_HEADER *)table; |
231 |
table_unmap(table, header->Length); |
160 |
pmap_unmapbios((vm_offset_t)table, header->Length); |
232 |
} |
161 |
} |
233 |
|
162 |
|
234 |
/* |
163 |
/* |
Lines 265-273
acpi_find_table(const char *sig)
Link Here
|
265 |
|
194 |
|
266 |
/* |
195 |
/* |
267 |
* For ACPI >= 2.0, use the XSDT if it is available. |
196 |
* For ACPI >= 2.0, use the XSDT if it is available. |
268 |
* Otherwise, use the RSDT. We map the XSDT or RSDT at page 2 |
197 |
* Otherwise, use the RSDT. |
269 |
* in the crashdump area. Pages 0 and 1 are used to map in the |
|
|
270 |
* headers of candidate ACPI tables. |
271 |
*/ |
198 |
*/ |
272 |
addr = 0; |
199 |
addr = 0; |
273 |
if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) { |
200 |
if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) { |