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/arm64/acpica/acpi_machdep.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) 2001 Mitsuru IWASAKI
    3  * Copyright (c) 2015 The FreeBSD Foundation
    4  * All rights reserved.
    5  *
    6  * This software was developed by Andrew Turner under
    7  * sponsorship from the FreeBSD Foundation.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD$");
   33 
   34 #include <sys/param.h>
   35 #include <sys/bus.h>
   36 #include <sys/kernel.h>
   37 
   38 #include <vm/vm.h>
   39 #include <vm/pmap.h>
   40 
   41 #include <machine/machdep.h>
   42 
   43 #include <contrib/dev/acpica/include/acpi.h>
   44 #include <contrib/dev/acpica/include/accommon.h>
   45 #include <contrib/dev/acpica/include/actables.h>
   46 
   47 #include <dev/acpica/acpivar.h>
   48 
   49 extern struct bus_space memmap_bus;
   50 
   51 int
   52 acpi_machdep_init(device_t dev)
   53 {
   54 
   55         return (0);
   56 }
   57 
   58 int
   59 acpi_machdep_quirks(int *quirks)
   60 {
   61 
   62         return (0);
   63 }
   64 
   65 static void *
   66 map_table(vm_paddr_t pa, const char *sig)
   67 {
   68         ACPI_TABLE_HEADER *header;
   69         vm_size_t length;
   70         void *table;
   71 
   72         header = pmap_mapbios(pa, sizeof(ACPI_TABLE_HEADER));
   73         if (strncmp(header->Signature, sig, ACPI_NAMESEG_SIZE) != 0) {
   74                 pmap_unmapbios(header, sizeof(ACPI_TABLE_HEADER));
   75                 return (NULL);
   76         }
   77         length = header->Length;
   78         pmap_unmapbios(header, sizeof(ACPI_TABLE_HEADER));
   79 
   80         table = pmap_mapbios(pa, length);
   81         if (ACPI_FAILURE(AcpiUtChecksum(table, length))) {
   82                 if (bootverbose)
   83                         printf("ACPI: Failed checksum for table %s\n", sig);
   84 #if (ACPI_CHECKSUM_ABORT)
   85                 pmap_unmapbios(table, length);
   86                 return (NULL);
   87 #endif
   88         }
   89         return (table);
   90 }
   91 
   92 /*
   93  * See if a given ACPI table is the requested table.  Returns the
   94  * length of the table if it matches or zero on failure.
   95  */
   96 static int
   97 probe_table(vm_paddr_t address, const char *sig)
   98 {
   99         ACPI_TABLE_HEADER *table;
  100 
  101         table = pmap_mapbios(address, sizeof(ACPI_TABLE_HEADER));
  102         if (table == NULL) {
  103                 if (bootverbose)
  104                         printf("ACPI: Failed to map table at 0x%jx\n",
  105                             (uintmax_t)address);
  106                 return (0);
  107         }
  108 
  109         if (strncmp(table->Signature, sig, ACPI_NAMESEG_SIZE) != 0) {
  110                 pmap_unmapbios(table, sizeof(ACPI_TABLE_HEADER));
  111                 return (0);
  112         }
  113         pmap_unmapbios(table, sizeof(ACPI_TABLE_HEADER));
  114         return (1);
  115 }
  116 
  117 /* Unmap a table previously mapped via acpi_map_table(). */
  118 void
  119 acpi_unmap_table(void *table)
  120 {
  121         ACPI_TABLE_HEADER *header;
  122 
  123         header = (ACPI_TABLE_HEADER *)table;
  124         pmap_unmapbios(table, header->Length);
  125 }
  126 
  127 /*
  128  * Try to map a table at a given physical address previously returned
  129  * by acpi_find_table().
  130  */
  131 void *
  132 acpi_map_table(vm_paddr_t pa, const char *sig)
  133 {
  134 
  135         return (map_table(pa, sig));
  136 }
  137 
  138 /*
  139  * Return the physical address of the requested table or zero if one
  140  * is not found.
  141  */
  142 vm_paddr_t
  143 acpi_find_table(const char *sig)
  144 {
  145         ACPI_PHYSICAL_ADDRESS rsdp_ptr;
  146         ACPI_TABLE_RSDP *rsdp;
  147         ACPI_TABLE_XSDT *xsdt;
  148         ACPI_TABLE_HEADER *table;
  149         vm_paddr_t addr;
  150         int i, count;
  151 
  152         if (resource_disabled("acpi", 0))
  153                 return (0);
  154 
  155         /*
  156          * Map in the RSDP.  Since ACPI uses AcpiOsMapMemory() which in turn
  157          * calls pmap_mapbios() to find the RSDP, we assume that we can use
  158          * pmap_mapbios() to map the RSDP.
  159          */
  160         if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0)
  161                 return (0);
  162         rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP));
  163         if (rsdp == NULL) {
  164                 printf("ACPI: Failed to map RSDP\n");
  165                 return (0);
  166         }
  167 
  168         addr = 0;
  169         if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) {
  170                 /*
  171                  * AcpiOsGetRootPointer only verifies the checksum for
  172                  * the version 1.0 portion of the RSDP.  Version 2.0 has
  173                  * an additional checksum that we verify first.
  174                  */
  175                 if (AcpiUtChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) {
  176                         printf("ACPI: RSDP failed extended checksum\n");
  177                         pmap_unmapbios(rsdp, sizeof(ACPI_TABLE_RSDP));
  178                         return (0);
  179                 }
  180                 xsdt = map_table(rsdp->XsdtPhysicalAddress, ACPI_SIG_XSDT);
  181                 if (xsdt == NULL) {
  182                         printf("ACPI: Failed to map XSDT\n");
  183                         pmap_unmapbios(rsdp, sizeof(ACPI_TABLE_RSDP));
  184                         return (0);
  185                 }
  186                 count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) /
  187                     sizeof(UINT64);
  188                 for (i = 0; i < count; i++)
  189                         if (probe_table(xsdt->TableOffsetEntry[i], sig)) {
  190                                 addr = xsdt->TableOffsetEntry[i];
  191                                 break;
  192                         }
  193                 acpi_unmap_table(xsdt);
  194         } else {
  195                 printf("ACPI: Unsupported RSDP version %d and XSDT %#lx\n",
  196                     rsdp->Revision, rsdp->XsdtPhysicalAddress);
  197         }
  198         pmap_unmapbios(rsdp, sizeof(ACPI_TABLE_RSDP));
  199 
  200         if (addr == 0)
  201                 return (0);
  202 
  203         /*
  204          * Verify that we can map the full table and that its checksum is
  205          * correct, etc.
  206          */
  207         table = map_table(addr, sig);
  208         if (table == NULL)
  209                 return (0);
  210         acpi_unmap_table(table);
  211 
  212         return (addr);
  213 }
  214 
  215 int
  216 acpi_map_addr(struct acpi_generic_address *addr, bus_space_tag_t *tag,
  217     bus_space_handle_t *handle, bus_size_t size)
  218 {
  219         bus_addr_t phys;
  220 
  221         /* Check if the device is Memory mapped */
  222         if (addr->SpaceId != 0)
  223                 return (ENXIO);
  224 
  225         phys = addr->Address;
  226         *tag = &memmap_bus;
  227 
  228         return (bus_space_map(*tag, phys, size, 0, handle));
  229 }
  230 
  231 #if MAXMEMDOM > 1
  232 static void
  233 parse_pxm_tables(void *dummy)
  234 {
  235         uint64_t mmfr0, parange;
  236 
  237         /* Only parse ACPI tables when booting via ACPI */
  238         if (arm64_bus_method != ARM64_BUS_ACPI)
  239                 return;
  240 
  241         if (!get_kernel_reg(ID_AA64MMFR0_EL1, &mmfr0)) {
  242                 /* chosen arbitrarily */
  243                 mmfr0 = ID_AA64MMFR0_PARange_1T;
  244         }
  245 
  246         switch (ID_AA64MMFR0_PARange_VAL(mmfr0)) {
  247         case ID_AA64MMFR0_PARange_4G:
  248                 parange = (vm_paddr_t)4 << 30 /* GiB */;
  249                 break;
  250         case ID_AA64MMFR0_PARange_64G:
  251                 parange = (vm_paddr_t)64 << 30 /* GiB */;
  252                 break;
  253         case ID_AA64MMFR0_PARange_1T:
  254                 parange = (vm_paddr_t)1 << 40 /* TiB */;
  255                 break;
  256         case ID_AA64MMFR0_PARange_4T:
  257                 parange = (vm_paddr_t)4 << 40 /* TiB */;
  258                 break;
  259         case ID_AA64MMFR0_PARange_16T:
  260                 parange = (vm_paddr_t)16 << 40 /* TiB */;
  261                 break;
  262         case ID_AA64MMFR0_PARange_256T:
  263                 parange = (vm_paddr_t)256 << 40 /* TiB */;
  264                 break;
  265         case ID_AA64MMFR0_PARange_4P:
  266                 parange = (vm_paddr_t)4 << 50 /* PiB */;
  267                 break;
  268         default:
  269                 /* chosen arbitrarily */
  270                 parange = (vm_paddr_t)1 << 40 /* TiB */;
  271                 printf("Unknown value for PARange in mmfr0 (%#lx)\n", mmfr0);
  272                 break;
  273         }
  274 
  275         acpi_pxm_init(MAXCPU, parange);
  276         acpi_pxm_parse_tables();
  277         acpi_pxm_set_mem_locality();
  278 }
  279 SYSINIT(parse_pxm_tables, SI_SUB_VM - 1, SI_ORDER_FIRST, parse_pxm_tables,
  280     NULL);
  281 #endif

Cache object: 5cfcb45ac66259c69503c62993c16602


[ 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.