Subversion Repositories Kolibri OS

Rev

Rev 1628 | Rev 1867 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. #include <ddk.h>
  3. #include <linux/errno.h>
  4. #include <mutex.h>
  5. #include <pci.h>
  6. #include <syscall.h>
  7.  
  8. #include "acpi.h"
  9. #include "acpi_bus.h"
  10.  
  11. #define PREFIX "ACPI: "
  12.  
  13. #define ACPI_BUS_CLASS          "system_bus"
  14. #define ACPI_BUS_HID            "KLBSYBUS"
  15. #define ACPI_BUS_DEVICE_NAME    "System Bus"
  16.  
  17.  
  18. #define ACPI_IS_ROOT_DEVICE(device)    (!(device)->parent)
  19.  
  20. static LIST_HEAD(acpi_device_list);
  21. static LIST_HEAD(acpi_bus_id_list);
  22.  
  23.  
  24. struct acpi_device_bus_id
  25. {
  26.     char bus_id[15];
  27.     unsigned int instance_no;
  28.     struct list_head node;
  29. };
  30.  
  31.  
  32. #define ACPI_NS_ROOT_PATH       "\\"
  33. #define ACPI_NS_SYSTEM_BUS      "_SB_"
  34.  
  35. enum acpi_irq_model_id {
  36.         ACPI_IRQ_MODEL_PIC = 0,
  37.         ACPI_IRQ_MODEL_IOAPIC,
  38.         ACPI_IRQ_MODEL_IOSAPIC,
  39.         ACPI_IRQ_MODEL_PLATFORM,
  40.         ACPI_IRQ_MODEL_COUNT
  41. };
  42.  
  43. enum acpi_bus_removal_type {
  44.     ACPI_BUS_REMOVAL_NORMAL = 0,
  45.     ACPI_BUS_REMOVAL_EJECT,
  46.     ACPI_BUS_REMOVAL_SUPRISE,
  47.     ACPI_BUS_REMOVAL_TYPE_COUNT
  48. };
  49.  
  50.  
  51. #define PCI_MAX_DEVICES 32
  52. #define PCI_MAX_PINS    4
  53.  
  54. #define IRQ_TABLE_ENTRIES   (PCI_MAX_DEVICES * PCI_MAX_PINS)
  55.  
  56. static int irqtable[IRQ_TABLE_ENTRIES];
  57. static ACPI_HANDLE pci_root_handle;
  58.  
  59.  
  60. #define  addr_offset(addr, off) \
  61.     (addr_t)((addr_t)(addr) + (addr_t)(off))
  62.  
  63. //#define acpi_remap( addr ) \
  64. //    (addr_t)((addr_t)(addr) + OS_BASE)
  65.  
  66. #define acpi_remap( addr ) MapIoMem((void*)(addr),4096, 0x01)
  67.  
  68. void print_pci_irqs();
  69.  
  70.  
  71. struct acpi_device *acpi_root;
  72.  
  73. extern struct resource iomem_resource;
  74. extern struct resource ioport_resource;
  75.  
  76. enum pic_mode
  77. {
  78.     IO_PIC  = 0,
  79.     IO_APIC
  80. };
  81.  
  82. static void set_pic_mode(enum pic_mode mode)
  83. {
  84.     ACPI_OBJECT arg1;
  85.     ACPI_OBJECT_LIST args;
  86.     ACPI_STATUS as;
  87.  
  88.     arg1.Type = ACPI_TYPE_INTEGER;
  89.     arg1.Integer.Value = mode;
  90.     args.Count = 1;
  91.     args.Pointer = &arg1;
  92.  
  93.     as = AcpiEvaluateObject(ACPI_ROOT_OBJECT, "_PIC", &args, NULL);
  94.     /*
  95.      * We can silently ignore failure as it may not be implemented, ACPI should
  96.      * provide us with correct information anyway
  97.      */
  98.     if (ACPI_SUCCESS(as))
  99.         dbgprintf(PREFIX "machine set to %s mode\n", mode ? "APIC" : "PIC");
  100. }
  101.  
  102. void print_device_tree(struct acpi_device *device)
  103. {
  104.     struct acpi_device *child;
  105.  
  106.     dbgprintf("%s\n", device->pnp.bus_id);
  107.  
  108.     list_for_each_entry(child, &device->children, node)
  109.     {
  110.         print_device_tree(child);
  111.     };
  112. };
  113.  
  114.  
  115.  
  116.  
  117. static bool pci_use_crs = false;
  118.  
  119. #define IORESOURCE_BUS      0x00001000
  120.  
  121.  
  122. extern struct list_head acpi_pci_roots;
  123.  
  124. #define ACPI_PCI_ROOT_CLASS     "pci_bridge"
  125. #define ACPI_PCI_ROOT_DEVICE_NAME   "PCI Root Bridge"
  126.  
  127. static ACPI_STATUS
  128. get_root_bridge_busnr_callback(ACPI_RESOURCE *resource, void *data)
  129. {
  130.     struct resource *res = data;
  131.     ACPI_RESOURCE_ADDRESS64 address;
  132.  
  133.     if (resource->Type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
  134.         resource->Type != ACPI_RESOURCE_TYPE_ADDRESS32 &&
  135.         resource->Type != ACPI_RESOURCE_TYPE_ADDRESS64)
  136.         return AE_OK;
  137.  
  138.     AcpiResourceToAddress64(resource, &address);
  139.     if ((address.AddressLength > 0) &&
  140.         (address.ResourceType == ACPI_BUS_NUMBER_RANGE)) {
  141.         res->start = address.Minimum;
  142.         res->end = address.Minimum + address.AddressLength - 1;
  143.     }
  144.  
  145.     return AE_OK;
  146. }
  147.  
  148.  
  149.  
  150. static ACPI_STATUS try_get_root_bridge_busnr(ACPI_HANDLE handle,
  151.                          struct resource *res)
  152. {
  153.     ACPI_STATUS status;
  154.  
  155.     res->start = -1;
  156.     status =
  157.         AcpiWalkResources(handle, METHOD_NAME__CRS,
  158.                 get_root_bridge_busnr_callback, res);
  159.     if (ACPI_FAILURE(status))
  160.         return status;
  161.     if (res->start == -1)
  162.         return AE_ERROR;
  163.     return AE_OK;
  164. }
  165.  
  166.  
  167. static void acpi_pci_bridge_scan(struct acpi_device *device)
  168. {
  169.     int status;
  170.     struct acpi_device *child = NULL;
  171.  
  172.     if (device->flags.bus_address)
  173.         if (device->parent && device->parent->ops.bind) {
  174.             status = device->parent->ops.bind(device);
  175.             if (!status) {
  176.                 list_for_each_entry(child, &device->children, node)
  177.                     acpi_pci_bridge_scan(child);
  178.             }
  179.         }
  180. }
  181.  
  182.  
  183.  
  184. struct pci_root_info
  185. {
  186.     struct acpi_device *bridge;
  187.     char *name;
  188.     unsigned int res_num;
  189.     struct resource *res;
  190.     struct pci_bus *bus;
  191.     int busnum;
  192. };
  193.  
  194.  
  195. static ACPI_STATUS
  196. resource_to_addr(ACPI_RESOURCE *resource, ACPI_RESOURCE_ADDRESS64 *addr)
  197. {
  198.     ACPI_STATUS status;
  199.     struct acpi_resource_memory24 *memory24;
  200.     struct acpi_resource_memory32 *memory32;
  201.     struct acpi_resource_fixed_memory32 *fixed_memory32;
  202.  
  203.     memset(addr, 0, sizeof(*addr));
  204.     switch (resource->Type) {
  205.     case ACPI_RESOURCE_TYPE_MEMORY24:
  206.         memory24 = &resource->Data.Memory24;
  207.         addr->ResourceType = ACPI_MEMORY_RANGE;
  208.         addr->Minimum = memory24->Minimum;
  209.         addr->AddressLength = memory24->AddressLength;
  210.         addr->Maximum = addr->Minimum + addr->AddressLength - 1;
  211.         return AE_OK;
  212.     case ACPI_RESOURCE_TYPE_MEMORY32:
  213.         memory32 = &resource->Data.Memory32;
  214.         addr->ResourceType = ACPI_MEMORY_RANGE;
  215.         addr->Minimum = memory32->Minimum;
  216.         addr->AddressLength = memory32->AddressLength;
  217.         addr->Maximum = addr->Minimum + addr->AddressLength - 1;
  218.         return AE_OK;
  219.     case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
  220.         fixed_memory32 = &resource->Data.FixedMemory32;
  221.         addr->ResourceType = ACPI_MEMORY_RANGE;
  222.         addr->Minimum = fixed_memory32->Address;
  223.         addr->AddressLength = fixed_memory32->AddressLength;
  224.         addr->Maximum = addr->Minimum + addr->AddressLength - 1;
  225.         return AE_OK;
  226.     case ACPI_RESOURCE_TYPE_ADDRESS16:
  227.     case ACPI_RESOURCE_TYPE_ADDRESS32:
  228.     case ACPI_RESOURCE_TYPE_ADDRESS64:
  229.         status = AcpiResourceToAddress64(resource, addr);
  230.         if (ACPI_SUCCESS(status) &&
  231.             (addr->ResourceType == ACPI_MEMORY_RANGE ||
  232.             addr->ResourceType == ACPI_IO_RANGE) &&
  233.             addr->AddressLength > 0) {
  234.             return AE_OK;
  235.         }
  236.         break;
  237.     }
  238.     return AE_ERROR;
  239. }
  240.  
  241.  
  242. static ACPI_STATUS
  243. count_resource(ACPI_RESOURCE *acpi_res, void *data)
  244. {
  245.     struct pci_root_info *info = data;
  246.     ACPI_RESOURCE_ADDRESS64 addr;
  247.     ACPI_STATUS status;
  248.  
  249.     status = resource_to_addr(acpi_res, &addr);
  250.     if (ACPI_SUCCESS(status))
  251.         info->res_num++;
  252.     return AE_OK;
  253. }
  254.  
  255.  
  256. static ACPI_STATUS setup_resource(ACPI_RESOURCE *acpi_res, void *data)
  257. {
  258.     struct pci_root_info *info = data;
  259.     struct resource *res;
  260.     struct acpi_resource_address64 addr;
  261.     ACPI_STATUS status;
  262.     unsigned long flags;
  263.     struct resource *root, *conflict;
  264.     u64 start, end;
  265.  
  266.     status = resource_to_addr(acpi_res, &addr);
  267.     if (!ACPI_SUCCESS(status))
  268.         return AE_OK;
  269.  
  270.     if (addr.ResourceType == ACPI_MEMORY_RANGE)
  271.     {
  272.         root = &iomem_resource;
  273.         flags = IORESOURCE_MEM;
  274.         if (addr.Info.Mem.Caching == ACPI_PREFETCHABLE_MEMORY)
  275.             flags |= IORESOURCE_PREFETCH;
  276.     }
  277.     else if (addr.ResourceType == ACPI_IO_RANGE)
  278.     {
  279.         root = &ioport_resource;
  280.         flags = IORESOURCE_IO;
  281.     } else
  282.         return AE_OK;
  283.  
  284.     start = addr.Minimum + addr.TranslationOffset;
  285.     end = addr.Maximum + addr.TranslationOffset;
  286.  
  287.     res = &info->res[info->res_num];
  288.     res->name = info->name;
  289.     res->flags = flags;
  290.     res->start = start;
  291.     res->end = end;
  292.     res->child = NULL;
  293.  
  294.     if (!pci_use_crs) {
  295.         printk("host bridge window %pR (ignored)\n", res);
  296.         return AE_OK;
  297.     }
  298.  
  299. #if 0
  300.     conflict = insert_resource_conflict(root, res);
  301.     if (conflict) {
  302.         dev_err(&info->bridge->dev,
  303.             "address space collision: host bridge window %pR "
  304.             "conflicts with %s %pR\n",
  305.             res, conflict->name, conflict);
  306.     } else {
  307.         pci_bus_add_resource(info->bus, res, 0);
  308.         info->res_num++;
  309.         if (addr.translation_offset)
  310.             dev_info(&info->bridge->dev, "host bridge window %pR "
  311.                  "(PCI address [%#llx-%#llx])\n",
  312.                  res, res->start - addr.translation_offset,
  313.                  res->end - addr.translation_offset);
  314.         else
  315.             dev_info(&info->bridge->dev,
  316.                  "host bridge window %pR\n", res);
  317.     }
  318.     return AE_OK;
  319. #endif
  320. }
  321.  
  322.  
  323.  
  324. static void
  325. get_current_resources(struct acpi_device *device, int busnum,
  326.             int domain, struct pci_bus *bus)
  327. {
  328.     struct pci_root_info info;
  329.     size_t size;
  330.  
  331.     char buf[64];
  332.  
  333. //    if (pci_use_crs)
  334. //        pci_bus_remove_resources(bus);
  335.  
  336.     info.bridge = device;
  337.     info.bus = bus;
  338.     info.res_num = 0;
  339.     AcpiWalkResources(device->handle, METHOD_NAME__CRS, count_resource,
  340.                 &info);
  341.     if (!info.res_num)
  342.         return;
  343.  
  344.     size = sizeof(*info.res) * info.res_num;
  345.     info.res = kmalloc(size, GFP_KERNEL);
  346.     if (!info.res)
  347.         goto res_alloc_fail;
  348.  
  349.     vsprintf(buf,"PCI Bus %04x:%02x", domain, busnum);
  350.     info.name = strdup(buf);
  351.  
  352.     if (!info.name)
  353.         goto name_alloc_fail;
  354.  
  355.     info.res_num = 0;
  356.     AcpiWalkResources(device->handle, METHOD_NAME__CRS, setup_resource,
  357.                 &info);
  358.  
  359.     return;
  360.  
  361. name_alloc_fail:
  362.     kfree(info.res);
  363. res_alloc_fail:
  364.     return;
  365. }
  366.  
  367.  
  368.  
  369.  
  370. struct pci_ops pci_root_ops = {
  371.     .read = NULL,
  372.     .write = NULL,
  373. };
  374.  
  375.  
  376. struct pci_bus*  pci_acpi_scan_root(struct acpi_pci_root *root)
  377. {
  378.     struct acpi_device *device = root->device;
  379.     int domain = root->segment;
  380.     int busnum = root->secondary.start;
  381.     struct pci_bus *bus;
  382.     struct pci_sysdata *sd;
  383.     int node = 0;
  384.  
  385.     if (domain ) {
  386.         printk(KERN_WARNING "pci_bus %04x:%02x: "
  387.                "ignored (multiple domains not supported)\n",
  388.                domain, busnum);
  389.         return NULL;
  390.     }
  391.  
  392.     /* Allocate per-root-bus (not per bus) arch-specific data.
  393.      * TODO: leak; this memory is never freed.
  394.      * It's arguable whether it's worth the trouble to care.
  395.      */
  396.     sd = kzalloc(sizeof(*sd), GFP_KERNEL);
  397.     if (!sd) {
  398.         printk(KERN_WARNING "pci_bus %04x:%02x: "
  399.                "ignored (out of memory)\n", domain, busnum);
  400.         return NULL;
  401.     }
  402.  
  403.     sd->domain = domain;
  404.     sd->node = node;
  405.     /*
  406.      * Maybe the desired pci bus has been already scanned. In such case
  407.      * it is unnecessary to scan the pci bus with the given domain,busnum.
  408.      */
  409.     bus = pci_find_bus(domain, busnum);
  410.     if (bus) {
  411.         /*
  412.          * If the desired bus exits, the content of bus->sysdata will
  413.          * be replaced by sd.
  414.          */
  415.         memcpy(bus->sysdata, sd, sizeof(*sd));
  416.         kfree(sd);
  417.     } else {
  418.         bus = pci_create_bus(busnum, &pci_root_ops, sd);
  419.         if (bus) {
  420.             get_current_resources(device, busnum, domain, bus);
  421.             bus->subordinate = pci_scan_child_bus(bus);
  422.         }
  423.     }
  424.  
  425.     if (!bus)
  426.         kfree(sd);
  427.  
  428.     if (bus && node != -1) {
  429.         printk("on NUMA node %d\n", node);
  430.     }
  431.  
  432.     return bus;
  433. }
  434.  
  435.  
  436.  
  437. static int acpi_pci_root_add(struct acpi_device *device)
  438. {
  439.     unsigned long long segment, bus;
  440.     ACPI_STATUS status;
  441.     int result;
  442.     struct acpi_pci_root *root;
  443.     ACPI_HANDLE handle;
  444.     struct acpi_device *child;
  445.     u32 flags, base_flags;
  446.  
  447.     root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
  448.     if (!root)
  449.         return -ENOMEM;
  450.  
  451.     segment = 0;
  452.     status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL,
  453.                        &segment);
  454.     if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
  455.         printk(KERN_ERR PREFIX "can't evaluate _SEG\n");
  456.         result = -ENODEV;
  457.         goto end;
  458.     }
  459.  
  460.     /* Check _CRS first, then _BBN.  If no _BBN, default to zero. */
  461.     root->secondary.flags = IORESOURCE_BUS;
  462.     status = try_get_root_bridge_busnr(device->handle, &root->secondary);
  463.     if (ACPI_FAILURE(status))
  464.     {
  465.         /*
  466.          * We need both the start and end of the downstream bus range
  467.          * to interpret _CBA (MMCONFIG base address), so it really is
  468.          * supposed to be in _CRS.  If we don't find it there, all we
  469.          * can do is assume [_BBN-0xFF] or [0-0xFF].
  470.          */
  471.         root->secondary.end = 0xFF;
  472.         printk(KERN_WARNING PREFIX
  473.                "no secondary bus range in _CRS\n");
  474.         status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN,                           NULL, &bus);
  475.         if (ACPI_SUCCESS(status))
  476.             root->secondary.start = bus;
  477.         else if (status == AE_NOT_FOUND)
  478.             root->secondary.start = 0;
  479.         else {
  480.             printk(KERN_ERR PREFIX "can't evaluate _BBN\n");
  481.             result = -ENODEV;
  482.             goto end;
  483.         }
  484.     }
  485.  
  486.     INIT_LIST_HEAD(&root->node);
  487.     root->device = device;
  488.     root->segment = segment & 0xFFFF;
  489.     strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
  490.     strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
  491.     device->driver_data = root;
  492.  
  493.     /*
  494.      * All supported architectures that use ACPI have support for
  495.      * PCI domains, so we indicate this in _OSC support capabilities.
  496.      */
  497. //    flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
  498. //    acpi_pci_osc_support(root, flags);
  499.  
  500.     /*
  501.      * TBD: Need PCI interface for enumeration/configuration of roots.
  502.      */
  503.  
  504.     /* TBD: Locking */
  505.     list_add_tail(&root->node, &acpi_pci_roots);
  506.  
  507.     printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n",
  508.            acpi_device_name(device), acpi_device_bid(device),
  509.            root->segment, &root->secondary);
  510.  
  511.     /*
  512.      * Scan the Root Bridge
  513.      * --------------------
  514.      * Must do this prior to any attempt to bind the root device, as the
  515.      * PCI namespace does not get created until this call is made (and
  516.      * thus the root bridge's pci_dev does not exist).
  517.      */
  518.  
  519.     root->bus = pci_acpi_scan_root(root);
  520.     if (!root->bus) {
  521.         printk(KERN_ERR PREFIX
  522.                 "Bus %04x:%02x not present in PCI namespace\n",
  523.                 root->segment, (unsigned int)root->secondary.start);
  524.         result = -ENODEV;
  525.         goto end;
  526.     }
  527.  
  528.     /*
  529.      * Attach ACPI-PCI Context
  530.      * -----------------------
  531.      * Thus binding the ACPI and PCI devices.
  532.      */
  533.     result = acpi_pci_bind_root(device);
  534.     if (result)
  535.         goto end;
  536.  
  537.     /*
  538.      * PCI Routing Table
  539.      * -----------------
  540.      * Evaluate and parse _PRT, if exists.
  541.      */
  542.     status = AcpiGetHandle(device->handle, METHOD_NAME__PRT, &handle);
  543.     if (ACPI_SUCCESS(status))
  544.         result = acpi_pci_irq_add_prt(device->handle, root->bus);
  545.  
  546.     /*
  547.      * Scan and bind all _ADR-Based Devices
  548.      */
  549.     list_for_each_entry(child, &device->children, node)
  550.         acpi_pci_bridge_scan(child);
  551.  
  552.     return 0;
  553.  
  554. end:
  555.     if (!list_empty(&root->node))
  556.         list_del(&root->node);
  557.     kfree(root);
  558.     return result;
  559. }
  560.  
  561.  
  562. static const struct acpi_device_ids root_device_ids[] =
  563. {
  564.     {"PNP0A03", 0},
  565.     {"",        0},
  566. };
  567.  
  568. void acpi_init_pci(struct acpi_device *device)
  569. {
  570.     struct acpi_device *child;
  571.  
  572.     if ( !acpi_match_device_ids(device, root_device_ids) )
  573.     {
  574.         dbgprintf(PREFIX "PCI root %s\n", device->pnp.bus_id);
  575.         acpi_pci_root_add(device);
  576.     };
  577.  
  578.     list_for_each_entry(child, &device->children, node)
  579.     {
  580.         acpi_init_pci(child);
  581.     };
  582.  
  583. };
  584.  
  585.  
  586. u32_t drvEntry(int action, char *cmdline)
  587. {
  588.     u32_t retval;
  589.  
  590.     ACPI_STATUS status;
  591.  
  592.     int i;
  593.  
  594.     if(action != 1)
  595.         return 0;
  596.  
  597.     if( !dbg_open("/rd/1/drivers/acpi.log") )
  598.     {
  599.         printf("Can't open /rd/1/drivers/acpi.log\nExit\n");
  600.         return 0;
  601.     }
  602.  
  603.     status = AcpiReallocateRootTable();
  604.     if (ACPI_FAILURE(status)) {
  605.         dbgprintf("Unable to reallocate ACPI tables\n");
  606.         goto err;
  607.     }
  608.  
  609.     status = AcpiInitializeSubsystem();
  610.     if (status != AE_OK) {
  611.           dbgprintf("AcpiInitializeSubsystem failed (%s)\n",
  612.                      AcpiFormatException(status));
  613.           goto err;
  614.     }
  615.  
  616.     status = AcpiInitializeTables(NULL, 0, TRUE);
  617.     if (status != AE_OK) {
  618.           dbgprintf("AcpiInitializeTables failed (%s)\n",
  619.                      AcpiFormatException(status));
  620.           goto err;
  621.     }
  622.  
  623.     status = AcpiLoadTables();
  624.     if (status != AE_OK) {
  625.           dbgprintf("AcpiLoadTables failed (%s)\n",
  626.                      AcpiFormatException(status));
  627.           goto err;
  628.     }
  629.  
  630. //    u32_t mode = ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE;
  631.  
  632.     status = AcpiEnableSubsystem(0);
  633.     if (status != AE_OK) {
  634.         dbgprintf("AcpiEnableSubsystem failed (%s)\n",
  635.             AcpiFormatException(status));
  636.         goto err;
  637.     }
  638.  
  639.     status = AcpiInitializeObjects (0);
  640.     if (ACPI_FAILURE (status))
  641.     {
  642.         dbgprintf("AcpiInitializeObjects failed (%s)\n",
  643.             AcpiFormatException(status));
  644.         goto err;
  645.     }
  646.  
  647.  
  648.     set_pic_mode(IO_APIC);
  649.  
  650.     acpi_scan();
  651.  
  652. //    print_device_tree(acpi_root);
  653.  
  654.     acpi_init_pci(acpi_root);
  655.  
  656.     print_pci_irqs();
  657.  
  658. /*
  659.     ACPI_HANDLE bus_handle;
  660.     ACPI_HANDLE pci_root;
  661.  
  662.     status = AcpiGetHandle(0, "\\_SB_", &bus_handle);
  663.     dbgprintf("system bus handle %x\n", bus_handle);
  664.  
  665.     status = AcpiGetHandle(bus_handle, "PCI0", &pci_root);
  666.     if (status != AE_OK) {
  667.           dbgprintf("AcpiGetHandle failed (%s)\n",
  668.                      AcpiFormatException(status));
  669.           goto err;
  670.     }
  671.  
  672.     AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 100,
  673.                       get_device_by_hid_callback, NULL, NULL, NULL);
  674. */
  675.  
  676. #if 0
  677.  
  678.     AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 4,
  679.                       get_device_by_hid_callback, NULL, NULL, NULL);
  680.  
  681.     ACPI_OBJECT obj;
  682.     ACPI_HANDLE bus_handle;
  683.     ACPI_HANDLE pci_root;
  684.  
  685.     status = AcpiGetHandle(0, "\\_SB_", &bus_handle);
  686.     dbgprintf("system bus handle %x\n", bus_handle);
  687.  
  688.     status = AcpiGetHandle(bus_handle, "PCI0", &pci_root);
  689.  
  690.     if (status != AE_OK) {
  691.         dbgprintf("AcpiGetHandle failed (%s)\n",
  692.             AcpiFormatException(status));
  693.         goto err;
  694.     }
  695.  
  696.     dbgprintf("pci root handle %x\n\n", pci_root);
  697.  
  698.     ACPI_BUFFER prt_buffer;
  699.  
  700.     prt_buffer.Length = ACPI_ALLOCATE_BUFFER;
  701.     prt_buffer.Pointer = NULL;
  702.  
  703.     status = AcpiGetIrqRoutingTable(pci_root, &prt_buffer);
  704.  
  705.     if (status != AE_OK) {
  706.         dbgprintf("AcpiGetIrqRoutingTable failed (%s)\n",
  707.             AcpiFormatException(status));
  708.         goto err;
  709.     }
  710.  
  711.     prt_walk_table(&prt_buffer);
  712.  
  713.  
  714.     ACPI_OBJECT arg = { ACPI_TYPE_INTEGER };
  715.     ACPI_OBJECT_LIST arg_list = { 1, &arg };
  716.  
  717.     arg.Integer.Value = ACPI_IRQ_MODEL_IOAPIC;
  718.  
  719.     dbgprintf("\nset ioapic mode\n\n");
  720.  
  721.     status = AcpiEvaluateObject(NULL, "\\_PIC", &arg_list, NULL);
  722.  
  723.     if (ACPI_FAILURE(status)) {
  724.         dbgprintf("AcpiEvaluateObject failed (%s)\n",
  725.             AcpiFormatException(status));
  726.  //       goto err;
  727.     }
  728.  
  729.  
  730.     status = AcpiGetIrqRoutingTable(pci_root, &prt_buffer);
  731.  
  732.     if (status != AE_OK) {
  733.         dbgprintf("AcpiGetIrqRoutingTable failed (%s)\n",
  734.             AcpiFormatException(status));
  735.         goto err;
  736.     }
  737.  
  738.     prt_walk_table(&prt_buffer);
  739.  
  740.     u8_t pin = PciRead8 (0, (31<<3) | 1, 0x3D);
  741.     dbgprintf("bus 0 device 31 function 1 pin %d\n", pin-1);
  742.  
  743.     pin = PciRead8 (0, (31<<3) | 2, 0x3D);
  744.     dbgprintf("bus 0 device 31 function 2 pin %d\n", pin-1);
  745.  
  746.     pin = PciRead8 (0, (31<<3) | 3, 0x3D);
  747.     dbgprintf("bus 0 device 31 function 3 pin %d\n", pin-1);
  748.  
  749.     pin = PciRead8 (0, (31<<3) | 4, 0x3D);
  750.     dbgprintf("bus 0 device 31 function 4 pin %d\n", pin-1);
  751.  
  752.     pin = PciRead8 (0, (31<<3) | 5, 0x3D);
  753.     dbgprintf("bus 0 device 31 function 5 pin %d\n", pin-1);
  754.  
  755.     pin = PciRead8 (0, (31<<3) | 6, 0x3D);
  756.     dbgprintf("bus 0 device 31 function 6 pin %d\n", pin-1);
  757.  
  758.     pin = PciRead8 (0, (31<<3) | 7, 0x3D);
  759.     dbgprintf("bus 0 device 31 function 7 pin %d\n", pin-1);
  760. #endif
  761.  
  762. err:
  763.  
  764.     return 0;
  765.  
  766. };
  767.  
  768. #if 0
  769.  
  770. ACPI_STATUS
  771. get_device_by_hid_callback(ACPI_HANDLE obj, u32_t depth, void* context,
  772.     void** retval)
  773. {
  774.     static u32_t counter = 0;
  775.     static char buff[256];
  776.  
  777.     ACPI_STATUS status;
  778.  
  779.     ACPI_BUFFER buffer;
  780.  
  781.     ACPI_DEVICE_INFO *info;
  782.  
  783.    // *retval = NULL;
  784.  
  785.     buffer.Length = 255;
  786.     buffer.Pointer = buff;
  787.  
  788.     status = AcpiGetName(obj, ACPI_FULL_PATHNAME, &buffer);
  789.     if (status != AE_OK) {
  790.         return AE_CTRL_TERMINATE;
  791.     }
  792.  
  793.     buff[buffer.Length] = '\0';
  794.  
  795.     dbgprintf("device %d %s ", counter, buff);
  796.  
  797.     status = AcpiGetObjectInfo(obj, &info);
  798.  
  799.     if (ACPI_SUCCESS (status))
  800.     {
  801.         if (info->Valid & ACPI_VALID_HID)
  802.             dbgprintf (" HID: %s", info->HardwareId.String);
  803.  
  804.     };
  805.  
  806.     dbgprintf("\n");
  807.     counter++;
  808.  
  809.     return AE_OK;
  810. }
  811.  
  812. prt_walk_table(ACPI_BUFFER *prt)
  813. {
  814.     ACPI_PCI_ROUTING_TABLE *entry;
  815.     char *prtptr;
  816.  
  817.     /* First check to see if there is a table to walk. */
  818.     if (prt == NULL || prt->Pointer == NULL)
  819.         return;
  820.  
  821.     /* Walk the table executing the handler function for each entry. */
  822.     prtptr = prt->Pointer;
  823.     entry = (ACPI_PCI_ROUTING_TABLE *)prtptr;
  824.     while (entry->Length != 0)
  825.     {
  826.  
  827.         dbgprintf("adress: %x %x  ", (u32_t)(entry->Address>>32),
  828.                   (u32_t)entry->Address);
  829.         dbgprintf("pin: %d  index: %d  source: %s\n",
  830.                    entry->Pin,
  831.                    entry->SourceIndex,
  832.                    entry->Source);
  833.  
  834. //      handler(entry, arg);
  835.         prtptr += entry->Length;
  836.         entry = (ACPI_PCI_ROUTING_TABLE *)prtptr;
  837.     }
  838. }
  839.  
  840.  
  841. static void add_irq(unsigned dev, unsigned pin, u8_t irq)
  842. {
  843. //    assert(dev < PCI_MAX_DEVICES && pin < PCI_MAX_PINS);
  844.  
  845.     irqtable[dev * PCI_MAX_PINS + pin] = irq;
  846. }
  847.  
  848. static ACPI_STATUS get_irq_resource(ACPI_RESOURCE *res, void *context)
  849. {
  850.     ACPI_PCI_ROUTING_TABLE *tbl = (ACPI_PCI_ROUTING_TABLE *) context;
  851.  
  852.     if (res->Type == ACPI_RESOURCE_TYPE_IRQ)
  853.     {
  854.         ACPI_RESOURCE_IRQ *irq;
  855.  
  856.         irq = &res->Data.Irq;
  857.         add_irq(tbl->Address >> 16, tbl->Pin,
  858.                 irq->Interrupts[tbl->SourceIndex]);
  859.     } else if (res->Type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ)
  860.     {
  861.         ACPI_RESOURCE_EXTENDED_IRQ *irq;
  862.  
  863.         add_irq(tbl->Address >> 16, tbl->Pin,
  864.                 irq->Interrupts[tbl->SourceIndex]);
  865.     }
  866.  
  867.     return AE_OK;
  868. }
  869.  
  870. char buff[4096];
  871.  
  872. static ACPI_STATUS get_pci_irq_routing(ACPI_HANDLE handle)
  873. {
  874.     ACPI_STATUS status;
  875.     ACPI_BUFFER abuff;
  876.     ACPI_PCI_ROUTING_TABLE *tbl;
  877.  
  878.     abuff.Length = sizeof(buff);
  879.     abuff.Pointer = buff;
  880.  
  881.     status = AcpiGetIrqRoutingTable(handle, &abuff);
  882.     if (ACPI_FAILURE(status)) {
  883.         return AE_OK;
  884.     }
  885.  
  886.     for (tbl = (ACPI_PCI_ROUTING_TABLE *)abuff.Pointer; tbl->Length;
  887.             tbl = (ACPI_PCI_ROUTING_TABLE *)
  888.             ((char *)tbl + tbl->Length))
  889.     {
  890.         ACPI_HANDLE src_handle;
  891.  
  892.         if (*(char*)tbl->Source == '\0') {
  893.             add_irq(tbl->Address >> 16, tbl->Pin, tbl->SourceIndex);
  894.             continue;
  895.         }
  896.  
  897.         status = AcpiGetHandle(handle, tbl->Source, &src_handle);
  898.         if (ACPI_FAILURE(status)) {
  899.             printf("Failed AcpiGetHandle\n");
  900.             continue;
  901.         }
  902.         status = AcpiWalkResources(src_handle, METHOD_NAME__CRS,
  903.                 get_irq_resource, tbl);
  904.         if (ACPI_FAILURE(status)) {
  905.             printf("Failed IRQ resource\n");
  906.             continue;
  907.         }
  908.     }
  909.  
  910.     return AE_OK;
  911. }
  912.  
  913. static ACPI_STATUS add_pci_root_dev(ACPI_HANDLE handle,
  914.                 UINT32 level,
  915.                 void *context,
  916.                 void **retval)
  917. {
  918.     int i;
  919.     static unsigned called;
  920.  
  921.     if (++called > 1) {
  922.         dbgprintf("ACPI: Warning! Multi rooted PCI is not supported!\n");
  923.         return AE_OK;
  924.     }
  925.  
  926.     for (i = 0; i < IRQ_TABLE_ENTRIES; i++)
  927.         irqtable[i] = -1;
  928.  
  929.     return get_pci_irq_routing(handle);
  930. }
  931.  
  932. static ACPI_STATUS add_pci_dev(ACPI_HANDLE handle,
  933.                 UINT32 level,
  934.                 void *context,
  935.                 void **retval)
  936. {
  937.     /* skip pci root when we get to it again */
  938.     if (handle == pci_root_handle)
  939.         return AE_OK;
  940.  
  941.     return get_pci_irq_routing(handle);
  942. }
  943.  
  944. static void scan_devices(void)
  945. {
  946.     ACPI_STATUS status;
  947.  
  948.     /* get the root first */
  949.     status = AcpiGetDevices("PNP0A03", add_pci_root_dev, NULL, NULL);
  950.     if (status != AE_OK) {
  951.         dbgprintf("scan_devices failed (%s)\n",
  952.                    AcpiFormatException(status));
  953.           return;
  954.     }
  955.  
  956. //    assert(ACPI_SUCCESS(status));
  957.  
  958.     /* get the rest of the devices that implement _PRT */
  959.     status = AcpiGetDevices(NULL, add_pci_dev, NULL, NULL);
  960. //    assert(ACPI_SUCCESS(status));
  961. }
  962.  
  963. #endif
  964.  
  965. char* strdup(const char *str)
  966. {
  967.     size_t len = strlen (str) + 1;
  968.     char *copy = malloc(len);
  969.     if (copy)
  970.     {
  971.         memcpy (copy, str, len);
  972.     }
  973.     return copy;
  974. }
  975.  
  976.