The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/acpica/Osd/OsdHardware.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2000, 2001 Michael Smith
    3  * Copyright (c) 2000 BSDi
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  *      $FreeBSD: releng/5.4/sys/dev/acpica/Osd/OsdHardware.c 130694 2004-06-18 17:56:45Z njl $
   28  */
   29 
   30 /*
   31  * 6.7 : Hardware Abstraction
   32  */
   33 
   34 #include "acpi.h"
   35 
   36 #include <machine/bus_pio.h>
   37 #include <machine/bus.h>
   38 #include <machine/pci_cfgreg.h>
   39 #include <dev/pci/pcireg.h>
   40 
   41 /*
   42  * ACPICA's rather gung-ho approach to hardware resource ownership is a little
   43  * troublesome insofar as there is no easy way for us to know in advance 
   44  * exactly which I/O resources it's going to want to use.
   45  * 
   46  * In order to deal with this, we ignore resource ownership entirely, and simply
   47  * use the native I/O space accessor functionality.  This is Evil, but it works.
   48  *
   49  * XXX use an intermediate #define for the tag/handle
   50  */
   51 
   52 #ifdef __i386__
   53 #define ACPI_BUS_SPACE_IO       I386_BUS_SPACE_IO
   54 #define ACPI_BUS_HANDLE         0
   55 #endif
   56 #ifdef __ia64__
   57 #define ACPI_BUS_SPACE_IO       IA64_BUS_SPACE_IO
   58 #define ACPI_BUS_HANDLE         0
   59 #endif
   60 #ifdef __amd64__
   61 #define ACPI_BUS_SPACE_IO       AMD64_BUS_SPACE_IO
   62 #define ACPI_BUS_HANDLE         0
   63 #endif
   64 
   65 ACPI_STATUS
   66 AcpiOsReadPort(ACPI_IO_ADDRESS InPort, UINT32 *Value, UINT32 Width)
   67 {
   68     switch (Width) {
   69     case 8:
   70         *(u_int8_t *)Value = bus_space_read_1(ACPI_BUS_SPACE_IO,
   71             ACPI_BUS_HANDLE, InPort);
   72         break;
   73     case 16:
   74         *(u_int16_t *)Value = bus_space_read_2(ACPI_BUS_SPACE_IO,
   75             ACPI_BUS_HANDLE, InPort);
   76         break;
   77     case 32:
   78         *(u_int32_t *)Value = bus_space_read_4(ACPI_BUS_SPACE_IO,
   79             ACPI_BUS_HANDLE, InPort);
   80         break;
   81     default:
   82         /* debug trap goes here */
   83         break;
   84     }
   85 
   86     return (AE_OK);
   87 }
   88 
   89 ACPI_STATUS
   90 AcpiOsWritePort(ACPI_IO_ADDRESS OutPort, UINT32 Value, UINT32 Width)
   91 {
   92     switch (Width) {
   93     case 8:
   94         bus_space_write_1(ACPI_BUS_SPACE_IO, ACPI_BUS_HANDLE, OutPort, Value);
   95         break;
   96     case 16:
   97         bus_space_write_2(ACPI_BUS_SPACE_IO, ACPI_BUS_HANDLE, OutPort, Value);
   98         break;
   99     case 32:
  100         bus_space_write_4(ACPI_BUS_SPACE_IO, ACPI_BUS_HANDLE, OutPort, Value);
  101         break;
  102     default:
  103         /* debug trap goes here */
  104         break;
  105     }
  106 
  107     return (AE_OK);
  108 }
  109 
  110 ACPI_STATUS
  111 AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, void *Value,
  112     UINT32 Width)
  113 {
  114     u_int32_t   byte_width = Width / 8;
  115     u_int32_t   val;
  116 
  117     if (!pci_cfgregopen())
  118         return (AE_NOT_EXIST);
  119 
  120     val = pci_cfgregread(PciId->Bus, PciId->Device, PciId->Function, Register,
  121         byte_width);
  122     switch (Width) {
  123     case 8:
  124         *(u_int8_t *)Value = val & 0xff;
  125         break;
  126     case 16:
  127         *(u_int16_t *)Value = val & 0xffff;
  128         break;
  129     case 32:
  130         *(u_int32_t *)Value = val;
  131         break;
  132     default:
  133         /* debug trap goes here */
  134         break;
  135     }
  136     
  137     return (AE_OK);
  138 }
  139 
  140 
  141 ACPI_STATUS
  142 AcpiOsWritePciConfiguration (ACPI_PCI_ID *PciId, UINT32 Register,
  143     ACPI_INTEGER Value, UINT32 Width)
  144 {
  145     u_int32_t   byte_width = Width / 8;
  146 
  147     if (!pci_cfgregopen())
  148         return (AE_NOT_EXIST);
  149 
  150     pci_cfgregwrite(PciId->Bus, PciId->Device, PciId->Function, Register,
  151         Value, byte_width);
  152 
  153     return (AE_OK);
  154 }
  155 
  156 /* XXX should use acpivar.h but too many include dependencies */
  157 extern ACPI_STATUS acpi_GetInteger(ACPI_HANDLE handle, char *path, int
  158     *number);
  159 
  160 /*
  161  * Depth-first recursive case for finding the bus, given the slot/function.
  162  */
  163 static int
  164 acpi_bus_number(ACPI_HANDLE root, ACPI_HANDLE curr, ACPI_PCI_ID *PciId)
  165 {
  166     ACPI_HANDLE parent;
  167     ACPI_STATUS status;
  168     ACPI_OBJECT_TYPE type;
  169     UINT32 adr;
  170     int bus, slot, func, class, subclass, header;
  171 
  172     /* Try to get the _BBN object of the root, otherwise assume it is 0. */
  173     bus = 0;
  174     if (root == curr) {
  175         status = acpi_GetInteger(root, "_BBN", &bus);
  176         if (ACPI_FAILURE(status) && bootverbose)
  177             printf("acpi_bus_number: root bus has no _BBN, assuming 0\n");
  178         return (bus);
  179     }
  180     status = AcpiGetParent(curr, &parent);
  181     if (ACPI_FAILURE(status))
  182         return (bus);
  183     
  184     /* First, recurse up the tree until we find the host bus. */
  185     bus = acpi_bus_number(root, parent, PciId);
  186 
  187     /* Validate parent bus device type. */
  188     if (ACPI_FAILURE(AcpiGetType(parent, &type)) || type != ACPI_TYPE_DEVICE) {
  189         printf("acpi_bus_number: not a device, type %d\n", type);
  190         return (bus);
  191     }
  192 
  193     /* Get the parent's slot and function. */
  194     status = acpi_GetInteger(parent, "_ADR", &adr);
  195     if (ACPI_FAILURE(status)) {
  196         printf("acpi_bus_number: can't get _ADR\n");
  197         return (bus);
  198     }
  199     slot = ACPI_HIWORD(adr);
  200     func = ACPI_LOWORD(adr);
  201 
  202     /* Is this a PCI-PCI or Cardbus-PCI bridge? */
  203     class = pci_cfgregread(bus, slot, func, PCIR_CLASS, 1);
  204     if (class != PCIC_BRIDGE)
  205         return (bus);
  206     subclass = pci_cfgregread(bus, slot, func, PCIR_SUBCLASS, 1);
  207 
  208     /* Find the header type, masking off the multifunction bit. */
  209     header = pci_cfgregread(bus, slot, func, PCIR_HDRTYPE, 1) & PCIM_HDRTYPE;
  210     if (header == PCIM_HDRTYPE_BRIDGE && subclass == PCIS_BRIDGE_PCI)
  211         bus = pci_cfgregread(bus, slot, func, PCIR_SECBUS_1, 1);
  212     if (header == PCIM_HDRTYPE_CARDBUS && subclass == PCIS_BRIDGE_CARDBUS)
  213         bus = pci_cfgregread(bus, slot, func, PCIR_SECBUS_2, 1);
  214     return (bus);
  215 }
  216 
  217 /*
  218  * Find the bus number for a device
  219  *
  220  * rhandle: handle for the root bus
  221  * chandle: handle for the device
  222  * PciId: pointer to device slot and function, we fill out bus
  223  */
  224 void
  225 AcpiOsDerivePciId(ACPI_HANDLE rhandle, ACPI_HANDLE chandle, ACPI_PCI_ID **PciId)
  226 {
  227     ACPI_HANDLE parent;
  228     ACPI_STATUS status;
  229     int bus;
  230 
  231     if (pci_cfgregopen() == 0)
  232         panic("AcpiOsDerivePciId unable to initialize pci bus");
  233 
  234     /* Try to read _BBN for bus number if we're at the root */
  235     bus = 0;
  236     if (rhandle == chandle) {
  237         status = acpi_GetInteger(rhandle, "_BBN", &bus);
  238         if (ACPI_FAILURE(status) && bootverbose)
  239             printf("AcpiOsDerivePciId: root bus has no _BBN, assuming 0\n");
  240     }
  241 
  242     /*
  243      * Get the parent handle and call the recursive case.  It is not
  244      * clear why we seem to be getting a chandle that points to a child
  245      * of the desired slot/function but passing in the parent handle
  246      * here works.
  247      */
  248     if (ACPI_SUCCESS(AcpiGetParent(chandle, &parent)))
  249         bus = acpi_bus_number(rhandle, parent, *PciId);
  250     (*PciId)->Bus = bus;
  251     if (bootverbose) {
  252         printf("AcpiOsDerivePciId: bus %d dev %d func %d\n",
  253             (*PciId)->Bus, (*PciId)->Device, (*PciId)->Function);
  254     }
  255 }

Cache object: 9f7aecc93af1b868ba0370268fc051cb


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.