View | Details | Raw Unified | Return to bug 248746 | Differences between
and this patch

Collapse All | Expand All

(-)sys/amd64/acpica/acpi_machdep.c (-97 / +21 lines)
Lines 91-181 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
 */
96
 */
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 *
97
static void *
114
table_map(vm_paddr_t pa, int offset, vm_offset_t length)
98
map_table(vm_paddr_t pa, const char *sig)
115
{
99
{
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
 */
159
static void *
160
map_table(vm_paddr_t pa, int offset, const char *sig)
161
{
162
	ACPI_TABLE_HEADER *header;
100
	ACPI_TABLE_HEADER *header;
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 183-213 Link Here
183
}
121
}
184
122
185
/*
123
/*
186
 * See if a given ACPI table is the requested table.  Returns the
124
 * See if a given ACPI table is the requested table.  Returns
187
 * length of the able if it matches or zero on failure.
125
 * one on success or zero on failure.
188
 */
126
 */
189
static int
127
static int
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) {
134
	ret = strncmp(table->Signature, sig, ACPI_NAMESEG_SIZE) == 0;
196
		if (bootverbose)
135
	pmap_unmapbios((vm_offset_t)table, sizeof(ACPI_TABLE_HEADER));
197
			printf("ACPI: Failed to map table at 0x%jx\n",
136
	return (ret);
198
			    (uintmax_t)address);
199
		return (0);
200
	}
201
	if (bootverbose)
202
		printf("Table '%.4s' at 0x%jx\n", table->Signature,
203
		    (uintmax_t)address);
204
205
	if (strncmp(table->Signature, sig, ACPI_NAMESEG_SIZE) != 0) {
206
		table_unmap(table, sizeof(ACPI_TABLE_HEADER));
207
		return (0);
208
	}
209
	table_unmap(table, sizeof(ACPI_TABLE_HEADER));
210
	return (1);
211
}
137
}
212
138
213
/*
139
/*
Lines 218-224 Link Here
218
acpi_map_table(vm_paddr_t pa, const char *sig)
144
acpi_map_table(vm_paddr_t pa, const char *sig)
219
{
145
{
220
146
221
	return (map_table(pa, 0, sig));
147
	return (map_table(pa, sig));
222
}
148
}
223
149
224
/* Unmap a table previously mapped via acpi_map_table(). */
150
/* Unmap a table previously mapped via acpi_map_table(). */
Lines 228-234 Link Here
228
	ACPI_TABLE_HEADER *header;
154
	ACPI_TABLE_HEADER *header;
229
155
230
	header = (ACPI_TABLE_HEADER *)table;
156
	header = (ACPI_TABLE_HEADER *)table;
231
	table_unmap(table, header->Length);
157
	pmap_unmapbios((vm_offset_t)table, header->Length);
232
}
158
}
233
159
234
/*
160
/*
Lines 265-273 Link Here
265
191
266
	/*
192
	/*
267
	 * For ACPI >= 2.0, use the XSDT if it is available.
193
	 * 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
194
	 * 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
	 */
195
	 */
272
	addr = 0;
196
	addr = 0;
273
	if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
197
	if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
Lines 281-287 Link Here
281
				printf("ACPI: RSDP failed extended checksum\n");
205
				printf("ACPI: RSDP failed extended checksum\n");
282
			return (0);
206
			return (0);
283
		}
207
		}
284
		xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT);
208
		xsdt = map_table(rsdp->XsdtPhysicalAddress, ACPI_SIG_XSDT);
285
		if (xsdt == NULL) {
209
		if (xsdt == NULL) {
286
			if (bootverbose)
210
			if (bootverbose)
287
				printf("ACPI: Failed to map XSDT\n");
211
				printf("ACPI: Failed to map XSDT\n");
Lines 296-302 Link Here
296
			}
220
			}
297
		acpi_unmap_table(xsdt);
221
		acpi_unmap_table(xsdt);
298
	} else {
222
	} else {
299
		rsdt = map_table(rsdp->RsdtPhysicalAddress, 2, ACPI_SIG_RSDT);
223
		rsdt = map_table(rsdp->RsdtPhysicalAddress, ACPI_SIG_RSDT);
300
		if (rsdt == NULL) {
224
		if (rsdt == NULL) {
301
			if (bootverbose)
225
			if (bootverbose)
302
				printf("ACPI: Failed to map RSDT\n");
226
				printf("ACPI: Failed to map RSDT\n");
Lines 324-330 Link Here
324
	 * Verify that we can map the full table and that its checksum is
248
	 * Verify that we can map the full table and that its checksum is
325
	 * correct, etc.
249
	 * correct, etc.
326
	 */
250
	 */
327
	table = map_table(addr, 0, sig);
251
	table = map_table(addr, sig);
328
	if (table == NULL)
252
	if (table == NULL)
329
		return (0);
253
		return (0);
330
	acpi_unmap_table(table);
254
	acpi_unmap_table(table);
(-)sys/dev/acpica/acpi_apei.c (-7 / +25 lines)
Lines 550-563 Link Here
550
{
550
{
551
	device_t	child;
551
	device_t	child;
552
	int		found;
552
	int		found;
553
	ACPI_TABLE_HEADER *hest;
554
	ACPI_STATUS	status;
553
555
554
	if (acpi_disabled("apei"))
556
	if (acpi_disabled("apei"))
555
		return;
557
		return;
556
	if (acpi_find_table(ACPI_SIG_HEST) == 0)
558
559
	/* Without HEST table we have nothing to do. */
560
	status = AcpiGetTable(ACPI_SIG_HEST, 0, &hest);
561
	if (ACPI_FAILURE(status))
557
		return;
562
		return;
563
	AcpiPutTable(hest);
564
558
	/* Only one APEI device can exist. */
565
	/* Only one APEI device can exist. */
559
	if (devclass_get_device(apei_devclass, 0))
566
	if (devclass_get_device(apei_devclass, 0))
560
		return;
567
		return;
568
561
	/* Search for ACPI error device to be used. */
569
	/* Search for ACPI error device to be used. */
562
	found = 0;
570
	found = 0;
563
	AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
571
	AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
Lines 564-569 Link Here
564
	    100, apei_find, NULL, NULL, (void *)&found);
572
	    100, apei_find, NULL, NULL, (void *)&found);
565
	if (found)
573
	if (found)
566
		return;
574
		return;
575
567
	/* If not found - create a fake one. */
576
	/* If not found - create a fake one. */
568
	child = BUS_ADD_CHILD(parent, 2, "apei", 0);
577
	child = BUS_ADD_CHILD(parent, 2, "apei", 0);
569
	if (child == NULL)
578
	if (child == NULL)
Lines 573-590 Link Here
573
static int
582
static int
574
apei_probe(device_t dev)
583
apei_probe(device_t dev)
575
{
584
{
585
	ACPI_TABLE_HEADER *hest;
586
	ACPI_STATUS	status;
576
	int rv;
587
	int rv;
577
588
578
	if (acpi_disabled("apei"))
589
	if (acpi_disabled("apei"))
579
		return (ENXIO);
590
		return (ENXIO);
580
	if (acpi_find_table(ACPI_SIG_HEST) == 0)
591
581
		return (ENXIO);
592
	if (acpi_get_handle(dev) != NULL) {
582
	if (acpi_get_handle(dev) != NULL)
583
		rv = (ACPI_ID_PROBE(device_get_parent(dev), dev, apei_ids) == NULL);
593
		rv = (ACPI_ID_PROBE(device_get_parent(dev), dev, apei_ids) == NULL);
584
	else
594
		if (rv > 0)
595
			return (rv);
596
	} else
585
		rv = 0;
597
		rv = 0;
586
	if (rv <= 0)
598
587
		device_set_desc(dev, "Platform Error Interface");
599
	/* Without HEST table we have nothing to do. */
600
	status = AcpiGetTable(ACPI_SIG_HEST, 0, &hest);
601
	if (ACPI_FAILURE(status))
602
		return (ENXIO);
603
	AcpiPutTable(hest);
604
605
	device_set_desc(dev, "ACPI Platform Error Interface");
588
	return (rv);
606
	return (rv);
589
}
607
}
590
608
(-)sys/i386/acpica/acpi_machdep.c (-92 / +21 lines)
Lines 109-197 Link Here
109
}
109
}
110
110
111
/*
111
/*
112
 * Support for mapping ACPI tables during early boot.  This abuses the
112
 * Map a table.  First map the header to determine the table length and then map
113
 * crashdump map because the kernel cannot allocate KVA in
113
 * the entire table.
114
 * pmap_mapbios() when this is used.  This makes the following
115
 * assumptions about how we use this KVA: pages 0 and 1 are used to
116
 * map in the header of each table found via the RSDT or XSDT and
117
 * pages 2 to n are used to map in the RSDT or XSDT.  This has to use
118
 * 2 pages for the table headers in case a header spans a page
119
 * boundary.
120
 *
121
 * XXX: We don't ensure the table fits in the available address space
122
 * in the crashdump map.
123
 */
114
 */
124
125
/*
126
 * Map some memory using the crashdump map.  'offset' is an offset in
127
 * pages into the crashdump map to use for the start of the mapping.
128
 */
129
static void *
115
static void *
130
table_map(vm_paddr_t pa, int offset, vm_offset_t length)
116
map_table(vm_paddr_t pa, const char *sig)
131
{
117
{
132
	vm_offset_t va, off;
133
	void *data;
134
135
	off = pa & PAGE_MASK;
136
	length = round_page(length + off);
137
	pa = pa & PG_FRAME;
138
	va = (vm_offset_t)pmap_kenter_temporary(pa, offset) +
139
	    (offset * PAGE_SIZE);
140
	data = (void *)(va + off);
141
	length -= PAGE_SIZE;
142
	while (length > 0) {
143
		va += PAGE_SIZE;
144
		pa += PAGE_SIZE;
145
		length -= PAGE_SIZE;
146
		pmap_kenter(va, pa);
147
		invlpg(va);
148
	}
149
	return (data);
150
}
151
152
/* Unmap memory previously mapped with table_map(). */
153
static void
154
table_unmap(void *data, vm_offset_t length)
155
{
156
	vm_offset_t va, off;
157
158
	va = (vm_offset_t)data;
159
	off = va & PAGE_MASK;
160
	length = round_page(length + off);
161
	va &= ~PAGE_MASK;
162
	while (length > 0) {
163
		pmap_kremove(va);
164
		invlpg(va);
165
		va += PAGE_SIZE;
166
		length -= PAGE_SIZE;
167
	}
168
}
169
170
/*
171
 * Map a table at a given offset into the crashdump map.  It first
172
 * maps the header to determine the table length and then maps the
173
 * entire table.
174
 */
175
static void *
176
map_table(vm_paddr_t pa, int offset, const char *sig)
177
{
178
	ACPI_TABLE_HEADER *header;
118
	ACPI_TABLE_HEADER *header;
179
	vm_offset_t length;
119
	vm_offset_t length;
180
	void *table;
120
	void *table;
181
121
182
	header = table_map(pa, offset, sizeof(ACPI_TABLE_HEADER));
122
	header = pmap_mapbios(pa, sizeof(ACPI_TABLE_HEADER));
183
	if (strncmp(header->Signature, sig, ACPI_NAMESEG_SIZE) != 0) {
123
	if (strncmp(header->Signature, sig, ACPI_NAMESEG_SIZE) != 0) {
184
		table_unmap(header, sizeof(ACPI_TABLE_HEADER));
124
		pmap_unmapbios((vm_offset_t)header, sizeof(ACPI_TABLE_HEADER));
185
		return (NULL);
125
		return (NULL);
186
	}
126
	}
187
	length = header->Length;
127
	length = header->Length;
188
	table_unmap(header, sizeof(ACPI_TABLE_HEADER));
128
	pmap_unmapbios((vm_offset_t)header, sizeof(ACPI_TABLE_HEADER));
189
	table = table_map(pa, offset, length);
129
	table = pmap_mapbios(pa, length);
190
	if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
130
	if (ACPI_FAILURE(AcpiTbChecksum(table, length))) {
191
		if (bootverbose)
131
		if (bootverbose)
192
			printf("ACPI: Failed checksum for table %s\n", sig);
132
			printf("ACPI: Failed checksum for table %s\n", sig);
193
#if (ACPI_CHECKSUM_ABORT)
133
#if (ACPI_CHECKSUM_ABORT)
194
		table_unmap(table, length);
134
		pmap_unmapbios((vm_offset_t)table, length);
195
		return (NULL);
135
		return (NULL);
196
#endif
136
#endif
197
	}
137
	}
Lines 199-229 Link Here
199
}
139
}
200
140
201
/*
141
/*
202
 * See if a given ACPI table is the requested table.  Returns the
142
 * See if a given ACPI table is the requested table.  Returns
203
 * length of the able if it matches or zero on failure.
143
 * one on success or zero on failure.
204
 */
144
 */
205
static int
145
static int
206
probe_table(vm_paddr_t address, const char *sig)
146
probe_table(vm_paddr_t address, const char *sig)
207
{
147
{
208
	ACPI_TABLE_HEADER *table;
148
	ACPI_TABLE_HEADER *table;
149
	int ret;
209
150
210
	table = table_map(address, 0, sizeof(ACPI_TABLE_HEADER));
151
	table = pmap_mapbios(address, sizeof(ACPI_TABLE_HEADER));
211
	if (table == NULL) {
212
		if (bootverbose)
213
			printf("ACPI: Failed to map table at 0x%jx\n",
214
			    (uintmax_t)address);
215
		return (0);
216
	}
217
	if (bootverbose)
152
	if (bootverbose)
218
		printf("Table '%.4s' at 0x%jx\n", table->Signature,
153
		printf("Table '%.4s' at 0x%jx\n", table->Signature,
219
		    (uintmax_t)address);
154
		    (uintmax_t)address);
220
155
	ret = strncmp(table->Signature, sig, ACPI_NAMESEG_SIZE) == 0;
221
	if (strncmp(table->Signature, sig, ACPI_NAMESEG_SIZE) != 0) {
156
	pmap_unmapbios((vm_offset_t)table, sizeof(ACPI_TABLE_HEADER));
222
		table_unmap(table, sizeof(ACPI_TABLE_HEADER));
157
	return (ret);
223
		return (0);
224
	}
225
	table_unmap(table, sizeof(ACPI_TABLE_HEADER));
226
	return (1);
227
}
158
}
228
159
229
/*
160
/*
Lines 234-240 Link Here
234
acpi_map_table(vm_paddr_t pa, const char *sig)
165
acpi_map_table(vm_paddr_t pa, const char *sig)
235
{
166
{
236
167
237
	return (map_table(pa, 0, sig));
168
	return (map_table(pa, sig));
238
}
169
}
239
170
240
/* Unmap a table previously mapped via acpi_map_table(). */
171
/* Unmap a table previously mapped via acpi_map_table(). */
Lines 244-250 Link Here
244
	ACPI_TABLE_HEADER *header;
175
	ACPI_TABLE_HEADER *header;
245
176
246
	header = (ACPI_TABLE_HEADER *)table;
177
	header = (ACPI_TABLE_HEADER *)table;
247
	table_unmap(table, header->Length);
178
	pmap_unmapbios((vm_offset_t)table, header->Length);
248
}
179
}
249
180
250
/*
181
/*
Lines 281-289 Link Here
281
212
282
	/*
213
	/*
283
	 * For ACPI >= 2.0, use the XSDT if it is available.
214
	 * For ACPI >= 2.0, use the XSDT if it is available.
284
	 * Otherwise, use the RSDT.  We map the XSDT or RSDT at page 2
215
	 * Otherwise, use the RSDT.
285
	 * in the crashdump area.  Pages 0 and 1 are used to map in the
286
	 * headers of candidate ACPI tables.
287
	 */
216
	 */
288
	addr = 0;
217
	addr = 0;
289
	if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
218
	if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
Lines 297-303 Link Here
297
				printf("ACPI: RSDP failed extended checksum\n");
226
				printf("ACPI: RSDP failed extended checksum\n");
298
			return (0);
227
			return (0);
299
		}
228
		}
300
		xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT);
229
		xsdt = map_table(rsdp->XsdtPhysicalAddress, ACPI_SIG_XSDT);
301
		if (xsdt == NULL) {
230
		if (xsdt == NULL) {
302
			if (bootverbose)
231
			if (bootverbose)
303
				printf("ACPI: Failed to map XSDT\n");
232
				printf("ACPI: Failed to map XSDT\n");
Lines 312-318 Link Here
312
			}
241
			}
313
		acpi_unmap_table(xsdt);
242
		acpi_unmap_table(xsdt);
314
	} else {
243
	} else {
315
		rsdt = map_table(rsdp->RsdtPhysicalAddress, 2, ACPI_SIG_RSDT);
244
		rsdt = map_table(rsdp->RsdtPhysicalAddress, ACPI_SIG_RSDT);
316
		if (rsdt == NULL) {
245
		if (rsdt == NULL) {
317
			if (bootverbose)
246
			if (bootverbose)
318
				printf("ACPI: Failed to map RSDT\n");
247
				printf("ACPI: Failed to map RSDT\n");
Lines 340-346 Link Here
340
	 * Verify that we can map the full table and that its checksum is
269
	 * Verify that we can map the full table and that its checksum is
341
	 * correct, etc.
270
	 * correct, etc.
342
	 */
271
	 */
343
	table = map_table(addr, 0, sig);
272
	table = map_table(addr, sig);
344
	if (table == NULL)
273
	if (table == NULL)
345
		return (0);
274
		return (0);
346
	acpi_unmap_table(table);
275
	acpi_unmap_table(table);

Return to bug 248746