osl.c (5dff2f34) | osl.c (5cff7825) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 21 unchanged lines hidden (view full) --- 30#pragma ident "%Z%%M% %I% %E% SMI" 31 32 33#include <sys/types.h> 34#include <sys/kmem.h> 35#include <sys/psm.h> 36#include <sys/pci_cfgspace.h> 37#include <sys/ddi.h> | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 21 unchanged lines hidden (view full) --- 30#pragma ident "%Z%%M% %I% %E% SMI" 31 32 33#include <sys/types.h> 34#include <sys/kmem.h> 35#include <sys/psm.h> 36#include <sys/pci_cfgspace.h> 37#include <sys/ddi.h> |
38#include <sys/sunndi.h> |
|
38#include <sys/pci.h> 39#include <sys/kobj.h> 40#include <sys/taskq.h> 41#include <sys/strlog.h> 42#include <sys/note.h> 43 44#include <sys/acpi/acpi.h> 45#include <sys/acpica.h> 46 | 39#include <sys/pci.h> 40#include <sys/kobj.h> 41#include <sys/taskq.h> 42#include <sys/strlog.h> 43#include <sys/note.h> 44 45#include <sys/acpi/acpi.h> 46#include <sys/acpica.h> 47 |
47extern int (*psm_translate_irq)(dev_info_t *, int); 48 | |
49#define MAX_DAT_FILE_SIZE (64*1024) 50 | 48#define MAX_DAT_FILE_SIZE (64*1024) 49 |
51#define D2A_INITLEN 20 52static int d2a_len = 0; 53static int d2a_valid = 0; 54static d2a *d2a_table; 55 56static int acpi_has_broken_bbn = -1; 57 | |
58/* local functions */ 59static int CompressEisaID(char *np); 60 | 50/* local functions */ 51static int CompressEisaID(char *np); 52 |
61static void create_d2a_map(void); 62static void create_d2a_subtree(dev_info_t *dip, ACPI_HANDLE acpiobj, int bus); 63static void new_d2a_entry(dev_info_t *dip, ACPI_HANDLE acpiobj, 64 int bus, int dev, int func); | 53static void scan_d2a_map(void); 54static void scan_d2a_subtree(dev_info_t *dip, ACPI_HANDLE acpiobj, int bus); 55static void acpica_tag_devinfo(dev_info_t *dip, ACPI_HANDLE acpiobj); |
65 66static int acpica_query_bbn_problem(void); 67static int acpica_find_pcibus(int busno, ACPI_HANDLE *rh); 68static int acpica_eval_hid(ACPI_HANDLE dev, char *method, int *rint); | 56 57static int acpica_query_bbn_problem(void); 58static int acpica_find_pcibus(int busno, ACPI_HANDLE *rh); 59static int acpica_eval_hid(ACPI_HANDLE dev, char *method, int *rint); |
60static ACPI_STATUS acpica_set_devinfo(ACPI_HANDLE, dev_info_t *); 61static void acpica_devinfo_handler(ACPI_HANDLE, UINT32, void *); |
|
69 | 62 |
70int acpica_find_pciobj(dev_info_t *dip, ACPI_HANDLE *rh); 71static int acpica_find_pcid2a(ACPI_HANDLE, d2a **); 72int acpica_eval_int(ACPI_HANDLE dev, char *method, int *rint); 73 | |
74/* 75 * Event queue vars 76 */ 77int acpica_eventq_thread_count = 1; 78int acpica_eventq_init = 0; 79ddi_taskq_t *osl_eventq[OSL_EC_BURST_HANDLER+1]; 80 81/* 82 * Note, if you change this path, you need to update 83 * /boot/grub/filelist.ramdisk and pkg SUNWckr/prototype_i386 84 */ 85static char *acpi_table_path = "/boot/acpi/tables/"; 86 | 63/* 64 * Event queue vars 65 */ 66int acpica_eventq_thread_count = 1; 67int acpica_eventq_init = 0; 68ddi_taskq_t *osl_eventq[OSL_EC_BURST_HANDLER+1]; 69 70/* 71 * Note, if you change this path, you need to update 72 * /boot/grub/filelist.ramdisk and pkg SUNWckr/prototype_i386 73 */ 74static char *acpi_table_path = "/boot/acpi/tables/"; 75 |
87/* non-zero while create_d2a_map() is working */ 88static int creating_d2a_map = 0; | 76/* non-zero while scan_d2a_map() is working */ 77static int scanning_d2a_map = 0; 78static int d2a_done = 0; |
89 90/* set by acpi_poweroff() in PSMs */ 91int acpica_powering_off = 0; 92 | 79 80/* set by acpi_poweroff() in PSMs */ 81int acpica_powering_off = 0; 82 |
83/* CPU mapping data */ 84struct cpu_map_item { 85 MADT_PROCESSOR_APIC *mpa; 86 ACPI_HANDLE obj; 87}; 88 89static struct cpu_map_item **cpu_map = NULL; 90static int cpu_map_count = 0; 91static int cpu_map_built = 0; 92 93static int acpi_has_broken_bbn = -1; 94 95#define D2A_DEBUG 96 |
|
93/* 94 * 95 */ 96static void 97discard_event_queues() 98{ 99 int i; 100 --- 41 unchanged lines hidden (view full) --- 142} 143 144/* 145 * 146 */ 147ACPI_STATUS 148AcpiOsInitialize(void) 149{ | 97/* 98 * 99 */ 100static void 101discard_event_queues() 102{ 103 int i; 104 --- 41 unchanged lines hidden (view full) --- 146} 147 148/* 149 * 150 */ 151ACPI_STATUS 152AcpiOsInitialize(void) 153{ |
150 | |
151 return (AE_OK); 152} 153 154/* 155 * 156 */ 157ACPI_STATUS 158AcpiOsTerminate(void) --- 723 unchanged lines hidden (view full) --- 882 * devinfo mapping (which compensates for broken _BBN). 883 * 884 * Default values for bus, segment, device and function are 885 * all 0 when ACPI CA can't figure them out. 886 * 887 * Some BIOSes implement _BBN() by reading PCI config space 888 * on bus #0 - which means that we'll recurse when we attempt 889 * to create the devinfo-to-ACPI map. If Derive is called during | 154 return (AE_OK); 155} 156 157/* 158 * 159 */ 160ACPI_STATUS 161AcpiOsTerminate(void) --- 723 unchanged lines hidden (view full) --- 885 * devinfo mapping (which compensates for broken _BBN). 886 * 887 * Default values for bus, segment, device and function are 888 * all 0 when ACPI CA can't figure them out. 889 * 890 * Some BIOSes implement _BBN() by reading PCI config space 891 * on bus #0 - which means that we'll recurse when we attempt 892 * to create the devinfo-to-ACPI map. If Derive is called during |
890 * create_d2a_map, we don't translate the bus # and return. | 893 * scan_d2a_map, we don't translate the bus # and return. 894 * 895 * We get the parent of the OpRegion, which must be a PCI 896 * node, fetch the associated devinfo node and snag the 897 * b/d/f from it. |
891 */ 892void 893AcpiOsDerivePciId(ACPI_HANDLE rhandle, ACPI_HANDLE chandle, 894 ACPI_PCI_ID **PciId) 895{ 896 ACPI_HANDLE handle; | 898 */ 899void 900AcpiOsDerivePciId(ACPI_HANDLE rhandle, ACPI_HANDLE chandle, 901 ACPI_PCI_ID **PciId) 902{ 903 ACPI_HANDLE handle; |
897 d2a *d2ap; 898 int devfn; | 904 dev_info_t *dip; 905 int bus, device, func, devfn; |
899 900 901 /* | 906 907 908 /* |
902 * See above - avoid recursing during create_d2a_map. | 909 * See above - avoid recursing during scanning_d2a_map. |
903 */ | 910 */ |
904 if (creating_d2a_map) | 911 if (scanning_d2a_map) |
905 return; 906 907 /* | 912 return; 913 914 /* |
908 * We start with the parent node of the OpRegion 909 * and ascend, looking for a matching dip2acpi 910 * node; once located, we use the bus from the d2a 911 * node and the device/function return from the _ADR 912 * method on the ACPI node. 913 * If we encounter any kind of failure, we just 914 * return, possibly after updating the bus value 915 * This is probably always better than nothing. | 915 * Get the OpRegion's parent |
916 */ 917 if (AcpiGetParent(chandle, &handle) != AE_OK) 918 return; 919 | 916 */ 917 if (AcpiGetParent(chandle, &handle) != AE_OK) 918 return; 919 |
920 while (handle != rhandle) { 921 if (acpica_find_pcid2a(handle, &d2ap) == AE_OK) { 922 (*PciId)->Bus = d2ap->bus; 923 if (acpica_eval_int(handle, "_ADR", &devfn) == AE_OK) { 924 (*PciId)->Device = (devfn >> 16) & 0xFFFF; 925 (*PciId)->Function = devfn & 0xFFFF; 926 } 927 break; 928 } 929 930 if (AcpiGetParent(handle, &handle) != AE_OK) 931 break; | 920 /* 921 * If we've mapped the ACPI node to the devinfo 922 * tree, use the devinfo reg property 923 */ 924 if (acpica_get_devinfo(handle, &dip) == AE_OK) { 925 (void) acpica_get_bdf(dip, &bus, &device, &func); 926 (*PciId)->Bus = bus; 927 (*PciId)->Device = device; 928 (*PciId)->Function = func; 929 } else if (acpica_eval_int(handle, "_ADR", &devfn) == AE_OK) { 930 /* no devinfo node - just confirm the d/f */ 931 (*PciId)->Device = (devfn >> 16) & 0xFFFF; 932 (*PciId)->Function = devfn & 0xFFFF; |
932 } 933} 934 935 936/*ARGSUSED*/ 937BOOLEAN 938AcpiOsReadable(void *Pointer, ACPI_SIZE Length) 939{ --- 279 unchanged lines hidden (view full) --- 1219 myu.octets[0] = ((np[0] & 0x1F) << 2) + ((np[1] >> 3) & 0x03); 1220 myu.octets[1] = ((np[1] & 0x07) << 5) + (np[2] & 0x1F); 1221 myu.octets[2] = (hexdig(np[3]) << 4) + hexdig(np[4]); 1222 myu.octets[3] = (hexdig(np[5]) << 4) + hexdig(np[6]); 1223 1224 return (myu.retval); 1225} 1226 | 933 } 934} 935 936 937/*ARGSUSED*/ 938BOOLEAN 939AcpiOsReadable(void *Pointer, ACPI_SIZE Length) 940{ --- 279 unchanged lines hidden (view full) --- 1220 myu.octets[0] = ((np[0] & 0x1F) << 2) + ((np[1] >> 3) & 0x03); 1221 myu.octets[1] = ((np[1] & 0x07) << 5) + (np[2] & 0x1F); 1222 myu.octets[2] = (hexdig(np[3]) << 4) + hexdig(np[4]); 1223 myu.octets[3] = (hexdig(np[5]) << 4) + hexdig(np[6]); 1224 1225 return (myu.retval); 1226} 1227 |
1227int | 1228ACPI_STATUS |
1228acpica_eval_int(ACPI_HANDLE dev, char *method, int *rint) 1229{ 1230 ACPI_STATUS status; 1231 ACPI_BUFFER rb; 1232 ACPI_OBJECT ro; 1233 1234 rb.Pointer = &ro; 1235 rb.Length = sizeof (ro); --- 44 unchanged lines hidden (view full) --- 1280 return (AE_OK); 1281 } else 1282 AcpiOsFree(rv); 1283 } 1284 return (AE_ERROR); 1285} 1286 1287/* | 1229acpica_eval_int(ACPI_HANDLE dev, char *method, int *rint) 1230{ 1231 ACPI_STATUS status; 1232 ACPI_BUFFER rb; 1233 ACPI_OBJECT ro; 1234 1235 rb.Pointer = &ro; 1236 rb.Length = sizeof (ro); --- 44 unchanged lines hidden (view full) --- 1281 return (AE_OK); 1282 } else 1283 AcpiOsFree(rv); 1284 } 1285 return (AE_ERROR); 1286} 1287 1288/* |
1288 * Return the d2a node matching this ACPI_HANDLE, if one exists | 1289 * Create linkage between devinfo nodes and ACPI nodes |
1289 */ | 1290 */ |
1290int 1291acpica_find_pcid2a(ACPI_HANDLE rh, d2a **dp) | 1291static void 1292acpica_tag_devinfo(dev_info_t *dip, ACPI_HANDLE acpiobj) |
1292{ | 1293{ |
1293 d2a *d2ap; 1294 int i; | 1294 ACPI_STATUS status; 1295 ACPI_BUFFER rb; |
1295 | 1296 |
1296 if (d2a_len == 0) 1297 create_d2a_map(); 1298 for (d2ap = d2a_table, i = 0; i < d2a_valid; d2ap++, i++) 1299 if (d2ap->acpiobj == rh) { 1300 *dp = d2ap; 1301 return (AE_OK); 1302 } | 1297 /* 1298 * Tag the ACPI node with the dip 1299 */ 1300 status = acpica_set_devinfo(acpiobj, dip); 1301 ASSERT(status == AE_OK); |
1303 | 1302 |
1304 return (AE_ERROR); | 1303 /* 1304 * Tag the devinfo node with the ACPI name 1305 */ 1306 rb.Pointer = NULL; 1307 rb.Length = ACPI_ALLOCATE_BUFFER; 1308 if (AcpiGetName(acpiobj, ACPI_FULL_PATHNAME, &rb) == AE_OK) { 1309 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, 1310 "acpi-namespace", (char *)rb.Pointer); 1311 AcpiOsFree(rb.Pointer); 1312 } else { 1313 cmn_err(CE_WARN, "acpica: could not get ACPI path!"); 1314 } |
1305} 1306 | 1315} 1316 |
1307 1308/* 1309 * Return the ACPI device node matching this dev_info node, if it 1310 * exists in the ACPI tree. 1311 */ 1312int 1313acpica_find_pciobj(dev_info_t *dip, ACPI_HANDLE *rh) | 1317static void 1318acpica_add_processor_to_map(UINT32 acpi_id, ACPI_HANDLE obj) |
1314{ | 1319{ |
1315 d2a *d2ap; 1316 int i; | 1320 int cpu_id; |
1317 | 1321 |
1318 if (d2a_len == 0) 1319 create_d2a_map(); 1320 for (d2ap = d2a_table, i = 0; i < d2a_valid; d2ap++, i++) 1321 if (d2ap->dip == dip) { 1322 *rh = d2ap->acpiobj; 1323 return (AE_OK); | 1322 /* 1323 * Special case: if we're a uppc system, there won't be 1324 * a CPU map yet. So we create one and use the passed-in 1325 * processor as CPU 0 1326 */ 1327 if (cpu_map == NULL) { 1328 cpu_map = kmem_zalloc(sizeof (cpu_map[0]) * NCPU, KM_SLEEP); 1329 cpu_map[0] = kmem_zalloc(sizeof (*cpu_map[0]), KM_SLEEP); 1330 cpu_map[0]->obj = obj; 1331 cpu_map_count = 1; 1332 return; 1333 } 1334 1335 for (cpu_id = 0; cpu_id < NCPU; cpu_id++) { 1336 if (cpu_map[cpu_id] == NULL) 1337 continue; 1338 1339 if (cpu_map[cpu_id]->mpa->ProcessorId == acpi_id) { 1340 cpu_map[cpu_id]->obj = obj; 1341 break; |
1324 } | 1342 } |
1343 } |
|
1325 | 1344 |
1326 return (AE_ERROR); | |
1327} 1328 1329/* | 1345} 1346 1347/* |
1330 * Create a table mapping PCI dips to ACPI objects | 1348 * |
1331 */ | 1349 */ |
1332static void 1333new_d2a_entry(dev_info_t *dip, ACPI_HANDLE acpiobj, int bus, int dev, int func) | 1350ACPI_STATUS 1351acpica_get_handle_cpu(dev_info_t *dip, ACPI_HANDLE *rh) |
1334{ | 1352{ |
1335 int newsize; 1336 d2a *new_arr, *ep; | 1353 char *device_type_prop; 1354 int cpu_id; |
1337 | 1355 |
1338 if (d2a_valid >= d2a_len) { 1339 /* initially, or re-, allocate array */ | 1356 /* 1357 * if "device_type" != "cpu", error 1358 */ 1359 if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, 1360 "device_type", &device_type_prop) != DDI_PROP_SUCCESS) || 1361 (strcmp("cpu", device_type_prop) != 0)) { 1362 ddi_prop_free(device_type_prop); 1363 return (AE_ERROR); 1364 } 1365 ddi_prop_free(device_type_prop); |
1340 | 1366 |
1341 newsize = (d2a_len ? d2a_len * 2 : D2A_INITLEN); 1342 new_arr = kmem_zalloc(newsize * sizeof (d2a), KM_SLEEP); 1343 if (d2a_len != 0) { 1344 /* realloc: copy data, free old */ 1345 bcopy(d2a_table, new_arr, d2a_len * sizeof (d2a)); 1346 kmem_free(d2a_table, d2a_len * sizeof (d2a)); 1347 } 1348 d2a_len = newsize; 1349 d2a_table = new_arr; | 1367 /* 1368 * if cpu_map itself is NULL, we're a uppc system and 1369 * acpica_build_processor_map() hasn't been called yet. 1370 * So call it here 1371 */ 1372 if (cpu_map == NULL) { 1373 (void) acpica_build_processor_map(); 1374 if (cpu_map == NULL) 1375 return (AE_ERROR); |
1350 } | 1376 } |
1351 ep = &d2a_table[d2a_valid++]; 1352 ep->bus = (unsigned char)bus; 1353 ep->dev = (unsigned char)dev; 1354 ep->func = (unsigned char)func; 1355 ep->dip = dip; 1356 ep->acpiobj = acpiobj; 1357#ifdef D2ADEBUG 1358 { 1359 ACPI_BUFFER rb; 1360 char pathname[60]; 1361 ddi_pathname(dip, pathname); | |
1362 | 1377 |
1378 /* 1379 * get 'reg' and get obj from cpu_map 1380 */ 1381 cpu_id = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1382 "reg", -1); 1383 if ((cpu_id < 0) || (cpu_map[cpu_id] == NULL) || 1384 (cpu_map[cpu_id]->obj == NULL)) 1385 return (AE_ERROR); 1386 1387 /* 1388 * tag devinfo and obj 1389 */ 1390 (void) acpica_tag_devinfo(dip, cpu_map[cpu_id]->obj); 1391 *rh = cpu_map[cpu_id]->obj; 1392 return (AE_OK); 1393} 1394 1395/* 1396 * Determine if this object is a processor 1397 */ 1398static ACPI_STATUS 1399acpica_probe_processor(ACPI_HANDLE obj, UINT32 level, void *ctx, void **rv) 1400{ 1401 ACPI_STATUS status; 1402 ACPI_OBJECT_TYPE objtype; 1403 UINT32 acpi_id; 1404 ACPI_BUFFER rb; 1405 1406 if (AcpiGetType(obj, &objtype) != AE_OK) 1407 return (AE_OK); 1408 1409 if (objtype == ACPI_TYPE_PROCESSOR) { 1410 /* process a Processor */ |
|
1363 rb.Pointer = NULL; 1364 rb.Length = ACPI_ALLOCATE_BUFFER; | 1411 rb.Pointer = NULL; 1412 rb.Length = ACPI_ALLOCATE_BUFFER; |
1365 if (AcpiGetName(acpiobj, ACPI_FULL_PATHNAME, &rb) == AE_OK) { 1366 1367 cmn_err(CE_NOTE, "d2a entry: %s %s %d/0x%x/%d", 1368 pathname, (char *)rb.Pointer, bus, dev, func); 1369 AcpiOsFree(rb.Pointer); | 1413 status = AcpiEvaluateObject(obj, NULL, NULL, &rb); 1414 if (status != AE_OK) { 1415 cmn_err(CE_WARN, "acpica: error probing Processor"); 1416 return (status); |
1370 } | 1417 } |
1418 ASSERT(((ACPI_OBJECT *)rb.Pointer)->Type == 1419 ACPI_TYPE_PROCESSOR); 1420 acpi_id = ((ACPI_OBJECT *)rb.Pointer)->Processor.ProcId; 1421 AcpiOsFree(rb.Pointer); 1422 } else if (objtype == ACPI_TYPE_DEVICE) { 1423 /* process a processor Device */ 1424 cmn_err(CE_WARN, "!acpica: probe found a processor Device\n"); 1425 cmn_err(CE_WARN, "!acpica: no support for processor Devices\n"); 1426 return (AE_OK); |
|
1371 } | 1427 } |
1372#endif | 1428 1429 acpica_add_processor_to_map(acpi_id, obj); 1430 return (AE_OK); |
1373} 1374 | 1431} 1432 |
1433 |
|
1375static void | 1434static void |
1376create_d2a_map(void) | 1435scan_d2a_map(void) |
1377{ 1378 dev_info_t *dip, *cdip; 1379 ACPI_HANDLE acpiobj; 1380 char *device_type_prop; 1381 int bus; 1382 static int map_error = 0; 1383 1384 if (map_error) 1385 return; 1386 | 1436{ 1437 dev_info_t *dip, *cdip; 1438 ACPI_HANDLE acpiobj; 1439 char *device_type_prop; 1440 int bus; 1441 static int map_error = 0; 1442 1443 if (map_error) 1444 return; 1445 |
1387 creating_d2a_map = 1; | 1446 scanning_d2a_map = 1; |
1388 1389 /* 1390 * Find all child-of-root PCI buses, and find their corresponding 1391 * ACPI child-of-root PCI nodes. For each one, add to the 1392 * d2a table. 1393 */ 1394 1395 for (dip = ddi_get_child(ddi_root_node()); --- 21 unchanged lines hidden (view full) --- 1417 if ((cdip = ddi_get_child(dip)) == NULL) 1418 continue; 1419 1420 if (acpica_get_bdf(cdip, &bus, NULL, NULL) < 0) { 1421#ifdef D2ADEBUG 1422 cmn_err(CE_WARN, "Can't get bus number of PCI child?"); 1423#endif 1424 map_error = 1; | 1447 1448 /* 1449 * Find all child-of-root PCI buses, and find their corresponding 1450 * ACPI child-of-root PCI nodes. For each one, add to the 1451 * d2a table. 1452 */ 1453 1454 for (dip = ddi_get_child(ddi_root_node()); --- 21 unchanged lines hidden (view full) --- 1476 if ((cdip = ddi_get_child(dip)) == NULL) 1477 continue; 1478 1479 if (acpica_get_bdf(cdip, &bus, NULL, NULL) < 0) { 1480#ifdef D2ADEBUG 1481 cmn_err(CE_WARN, "Can't get bus number of PCI child?"); 1482#endif 1483 map_error = 1; |
1425 creating_d2a_map = 0; | 1484 scanning_d2a_map = 0; 1485 d2a_done = 1; |
1426 return; 1427 } 1428 1429 if (acpica_find_pcibus(bus, &acpiobj) == AE_ERROR) { 1430#ifdef D2ADEBUG 1431 cmn_err(CE_WARN, "No ACPI bus obj for bus %d?\n", bus); 1432#endif 1433 map_error = 1; 1434 continue; 1435 } 1436 | 1486 return; 1487 } 1488 1489 if (acpica_find_pcibus(bus, &acpiobj) == AE_ERROR) { 1490#ifdef D2ADEBUG 1491 cmn_err(CE_WARN, "No ACPI bus obj for bus %d?\n", bus); 1492#endif 1493 map_error = 1; 1494 continue; 1495 } 1496 |
1437 /* 1438 * map this node, with illegal device and fn numbers 1439 * (since, as a PCI root node, it exists on the system 1440 * bus 1441 */ | 1497 acpica_tag_devinfo(dip, acpiobj); |
1442 | 1498 |
1443 new_d2a_entry(dip, acpiobj, bus, 32, 8); 1444 1445 /* call recursive function to enumerate subtrees */ 1446 create_d2a_subtree(dip, acpiobj, bus); | 1499 /* call recursively to enumerate subtrees */ 1500 scan_d2a_subtree(dip, acpiobj, bus); |
1447 } | 1501 } |
1448 creating_d2a_map = 0; | 1502 1503 scanning_d2a_map = 0; 1504 d2a_done = 1; |
1449} 1450 1451/* 1452 * For all acpi child devices of acpiobj, find their matching 1453 * dip under "dip" argument. (matching means "matches dev/fn"). 1454 * bus is assumed to already be a match from caller, and is 1455 * used here only to record in the d2a entry. Recurse if necessary. 1456 */ 1457static void | 1505} 1506 1507/* 1508 * For all acpi child devices of acpiobj, find their matching 1509 * dip under "dip" argument. (matching means "matches dev/fn"). 1510 * bus is assumed to already be a match from caller, and is 1511 * used here only to record in the d2a entry. Recurse if necessary. 1512 */ 1513static void |
1458create_d2a_subtree(dev_info_t *dip, ACPI_HANDLE acpiobj, int bus) | 1514scan_d2a_subtree(dev_info_t *dip, ACPI_HANDLE acpiobj, int bus) |
1459{ 1460 int acpi_devfn, hid; 1461 ACPI_HANDLE acld; 1462 dev_info_t *dcld; 1463 int dcld_b, dcld_d, dcld_f; 1464 int dev, func; | 1515{ 1516 int acpi_devfn, hid; 1517 ACPI_HANDLE acld; 1518 dev_info_t *dcld; 1519 int dcld_b, dcld_d, dcld_f; 1520 int dev, func; |
1521 char *device_type_prop; |
|
1465 1466 acld = NULL; 1467 while (AcpiGetNextObject(ACPI_TYPE_DEVICE, acpiobj, acld, &acld) 1468 == AE_OK) { | 1522 1523 acld = NULL; 1524 while (AcpiGetNextObject(ACPI_TYPE_DEVICE, acpiobj, acld, &acld) 1525 == AE_OK) { |
1469 1470 /* 1471 * Skip ACPI devices that are obviously not PCI, i.e., 1472 * that have a _HID that is *not* the PCI HID 1473 */ 1474 1475 if (acpica_eval_hid(acld, "_HID", &hid) == AE_OK && 1476 hid != HID_PCI_BUS && hid != HID_PCI_EXPRESS_BUS) 1477 continue; 1478 | |
1479 /* get the dev/func we're looking for in the devinfo tree */ 1480 if (acpica_eval_int(acld, "_ADR", &acpi_devfn) != AE_OK) 1481 continue; 1482 dev = (acpi_devfn >> 16) & 0xFFFF; 1483 func = acpi_devfn & 0xFFFF; 1484 1485 /* look through all the immediate children of dip */ 1486 for (dcld = ddi_get_child(dip); dcld != NULL; 1487 dcld = ddi_get_next_sibling(dcld)) { 1488 if (acpica_get_bdf(dcld, &dcld_b, &dcld_d, &dcld_f) < 0) 1489 continue; 1490 1491 /* dev must match; function must match or wildcard */ 1492 if (dcld_d != dev || 1493 (func != 0xFFFF && func != dcld_f)) 1494 continue; 1495 bus = dcld_b; 1496 1497 /* found a match, record it */ | 1526 /* get the dev/func we're looking for in the devinfo tree */ 1527 if (acpica_eval_int(acld, "_ADR", &acpi_devfn) != AE_OK) 1528 continue; 1529 dev = (acpi_devfn >> 16) & 0xFFFF; 1530 func = acpi_devfn & 0xFFFF; 1531 1532 /* look through all the immediate children of dip */ 1533 for (dcld = ddi_get_child(dip); dcld != NULL; 1534 dcld = ddi_get_next_sibling(dcld)) { 1535 if (acpica_get_bdf(dcld, &dcld_b, &dcld_d, &dcld_f) < 0) 1536 continue; 1537 1538 /* dev must match; function must match or wildcard */ 1539 if (dcld_d != dev || 1540 (func != 0xFFFF && func != dcld_f)) 1541 continue; 1542 bus = dcld_b; 1543 1544 /* found a match, record it */ |
1498 new_d2a_entry(dcld, acld, bus, dev, func); | 1545 acpica_tag_devinfo(dcld, acld); |
1499 | 1546 |
1500 /* recurse from here to pick up child trees */ 1501 create_d2a_subtree(dcld, acld, bus); | 1547 /* if we find a bridge, recurse from here */ 1548 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dcld, 0, 1549 "device_type", &device_type_prop) == 1550 DDI_PROP_SUCCESS) { 1551 if ((strcmp("pci", device_type_prop) == 0) || 1552 (strcmp("pciex", device_type_prop) == 0)) 1553 scan_d2a_subtree(dcld, acld, bus); 1554 ddi_prop_free(device_type_prop); 1555 } |
1502 1503 /* done finding a match, so break now */ 1504 break; 1505 } 1506 } 1507} 1508 1509/* 1510 * Return bus/dev/fn for PCI dip (note: not the parent "pci" node). 1511 */ | 1556 1557 /* done finding a match, so break now */ 1558 break; 1559 } 1560 } 1561} 1562 1563/* 1564 * Return bus/dev/fn for PCI dip (note: not the parent "pci" node). 1565 */ |
1512 | |
1513int 1514acpica_get_bdf(dev_info_t *dip, int *bus, int *device, int *func) 1515{ 1516 pci_regspec_t *pci_rp; 1517 int len; 1518 1519 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1520 "reg", (int **)&pci_rp, (uint_t *)&len) != DDI_SUCCESS) --- 7 unchanged lines hidden (view full) --- 1528 *bus = (int)PCI_REG_BUS_G(pci_rp->pci_phys_hi); 1529 if (device != NULL) 1530 *device = (int)PCI_REG_DEV_G(pci_rp->pci_phys_hi); 1531 if (func != NULL) 1532 *func = (int)PCI_REG_FUNC_G(pci_rp->pci_phys_hi); 1533 ddi_prop_free(pci_rp); 1534 return (0); 1535} | 1566int 1567acpica_get_bdf(dev_info_t *dip, int *bus, int *device, int *func) 1568{ 1569 pci_regspec_t *pci_rp; 1570 int len; 1571 1572 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1573 "reg", (int **)&pci_rp, (uint_t *)&len) != DDI_SUCCESS) --- 7 unchanged lines hidden (view full) --- 1581 *bus = (int)PCI_REG_BUS_G(pci_rp->pci_phys_hi); 1582 if (device != NULL) 1583 *device = (int)PCI_REG_DEV_G(pci_rp->pci_phys_hi); 1584 if (func != NULL) 1585 *func = (int)PCI_REG_FUNC_G(pci_rp->pci_phys_hi); 1586 ddi_prop_free(pci_rp); 1587 return (0); 1588} |
1589 1590/* 1591 * Return the ACPI device node matching this dev_info node, if it 1592 * exists in the ACPI tree. 1593 */ 1594ACPI_STATUS 1595acpica_get_handle(dev_info_t *dip, ACPI_HANDLE *rh) 1596{ 1597 ACPI_STATUS status; 1598 char *acpiname; 1599 1600 if (!d2a_done) 1601 scan_d2a_map(); 1602 1603 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1604 "acpi-namespace", &acpiname) != DDI_PROP_SUCCESS) { 1605 return (acpica_get_handle_cpu(dip, rh)); 1606 } 1607 1608 status = AcpiGetHandle(NULL, acpiname, rh); 1609 ddi_prop_free((void *)acpiname); 1610 return (status); 1611} 1612 1613 1614 1615/* 1616 * Manage OS data attachment to ACPI nodes 1617 */ 1618 1619/* 1620 * Return the (dev_info_t *) associated with the ACPI node. 1621 */ 1622ACPI_STATUS 1623acpica_get_devinfo(ACPI_HANDLE obj, dev_info_t **dipp) 1624{ 1625 ACPI_STATUS status; 1626 void *ptr; 1627 1628 status = AcpiGetData(obj, acpica_devinfo_handler, &ptr); 1629 if (status == AE_OK) 1630 *dipp = (dev_info_t *)ptr; 1631 1632 return (status); 1633} 1634 1635/* 1636 * Set the dev_info_t associated with the ACPI node. 1637 */ 1638static ACPI_STATUS 1639acpica_set_devinfo(ACPI_HANDLE obj, dev_info_t *dip) 1640{ 1641 ACPI_STATUS status; 1642 1643 status = AcpiAttachData(obj, acpica_devinfo_handler, (void *)dip); 1644 return (status); 1645} 1646 1647 1648/* 1649 * 1650 */ 1651void 1652acpica_devinfo_handler(ACPI_HANDLE obj, UINT32 func, void *data) 1653{ 1654 /* noop */ 1655} 1656 1657 1658/* 1659 * 1660 */ 1661void 1662acpica_map_cpu(processorid_t cpuid, MADT_PROCESSOR_APIC *mpa) 1663{ 1664 struct cpu_map_item *item; 1665 1666 if (cpu_map == NULL) 1667 cpu_map = kmem_zalloc(sizeof (item) * NCPU, KM_SLEEP); 1668 1669 item = kmem_zalloc(sizeof (*item), KM_SLEEP); 1670 item->mpa = mpa; 1671 item->obj = NULL; 1672 cpu_map[cpuid] = item; 1673 cpu_map_count++; 1674} 1675 1676void 1677acpica_build_processor_map() 1678{ 1679 ACPI_STATUS status; 1680 void *rv; 1681 1682 /* 1683 * shouldn't be called more than once anyway 1684 */ 1685 if (cpu_map_built) 1686 return; 1687 1688 /* 1689 * Look for Processor objects 1690 */ 1691 status = AcpiWalkNamespace(ACPI_TYPE_PROCESSOR, 1692 ACPI_ROOT_OBJECT, 1693 4, 1694 acpica_probe_processor, 1695 NULL, 1696 &rv); 1697 ASSERT(status == AE_OK); 1698 1699 /* 1700 * Look for processor Device objects 1701 */ 1702 status = AcpiGetDevices("ACPI0007", 1703 acpica_probe_processor, 1704 NULL, 1705 &rv); 1706 ASSERT(status == AE_OK); 1707 cpu_map_built = 1; 1708} |
|