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}