root/arch/i386/i386/acpi_machdep.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. acpi_map
  2. acpi_unmap
  3. acpi_scan
  4. acpi_probe
  5. acpi_attach_machdep

    1 /*      $OpenBSD: acpi_machdep.c,v 1.6 2007/05/29 08:22:14 gwk Exp $    */
    2 /*
    3  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
    4  *
    5  * Permission to use, copy, modify, and distribute this software for any
    6  * purpose with or without fee is hereby granted, provided that the above
    7  * copyright notice and this permission notice appear in all copies.
    8  *
    9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   16  */
   17 
   18 #include <sys/param.h>
   19 #include <sys/systm.h>
   20 #include <sys/kernel.h>
   21 #include <sys/device.h>
   22 #include <sys/malloc.h>
   23 
   24 #include <uvm/uvm_extern.h>
   25 
   26 #include <machine/bus.h>
   27 #include <i386/isa/isa_machdep.h>
   28 
   29 #include <dev/isa/isareg.h>
   30 #include <dev/acpi/acpireg.h>
   31 #include <dev/acpi/acpivar.h>
   32 
   33 #include "bios.h"
   34 #include "apm.h"
   35 
   36 #if NBIOS > 0
   37 #include <machine/biosvar.h>
   38 #endif
   39 
   40 #define ACPI_BIOS_RSDP_WINDOW_BASE        0xe0000
   41 #define ACPI_BIOS_RSDP_WINDOW_SIZE        0x20000
   42 
   43 #if NAPM > 0 && NBIOS > 0
   44 extern bios_apminfo_t *apm;
   45 #endif
   46 
   47 u_int8_t        *acpi_scan(struct acpi_mem_map *, paddr_t, size_t);
   48 
   49 int
   50 acpi_map(paddr_t pa, size_t len, struct acpi_mem_map *handle)
   51 {
   52         paddr_t pgpa = trunc_page(pa);
   53         paddr_t endpa = round_page(pa + len);
   54         vaddr_t va = uvm_km_valloc(kernel_map, endpa - pgpa);
   55 
   56         if (va == 0)
   57                 return (ENOMEM);
   58 
   59         handle->baseva = va;
   60         handle->va = (u_int8_t *)(va + (u_long)(pa & PGOFSET));
   61         handle->vsize = endpa - pgpa;
   62         handle->pa = pa;
   63 
   64         do {
   65                 pmap_kenter_pa(va, pgpa, VM_PROT_READ | VM_PROT_WRITE);
   66                 va += NBPG;
   67                 pgpa += NBPG;
   68         } while (pgpa < endpa);
   69 
   70         return 0;
   71 }
   72 
   73 void
   74 acpi_unmap(struct acpi_mem_map *handle)
   75 {
   76         pmap_kremove(handle->baseva, handle->vsize);
   77         uvm_km_free(kernel_map, handle->baseva, handle->vsize);
   78 }
   79 
   80 u_int8_t *
   81 acpi_scan(struct acpi_mem_map *handle, paddr_t pa, size_t len)
   82 {
   83         size_t i;
   84         u_int8_t *ptr;
   85         struct acpi_rsdp1 *rsdp;
   86 
   87         if (acpi_map(pa, len, handle))
   88                 return (NULL);
   89         for (ptr = handle->va, i = 0;
   90              i < len;
   91              ptr += 16, i += 16)
   92                 if (memcmp(ptr, RSDP_SIG, sizeof(RSDP_SIG) - 1) == 0) {
   93                         rsdp = (struct acpi_rsdp1 *)ptr;
   94                         /*
   95                          * Only checksum whichever portion of the
   96                          * RSDP that is actually present
   97                          */
   98                         if (rsdp->revision == 0 &&
   99                             acpi_checksum(ptr, sizeof(struct acpi_rsdp1)) == 0)
  100                                 return (ptr);
  101                         else if (rsdp->revision == 2 &&
  102                             acpi_checksum(ptr, sizeof(struct acpi_rsdp)) == 0)
  103                                 return (ptr);
  104                 }
  105         acpi_unmap(handle);
  106 
  107         return (NULL);
  108 }
  109 
  110 int
  111 acpi_probe(struct device *parent, struct cfdata *match, struct acpi_attach_args *aaa)
  112 {
  113         struct acpi_mem_map handle;
  114         u_int8_t *ptr;
  115         paddr_t ebda;
  116 #if NAPM > 0
  117         extern int apm_attached;
  118         
  119         if (apm_attached)
  120                 return (0);     
  121 #endif
  122 #if NBIOS > 0
  123         {
  124                 bios_memmap_t *im;
  125 
  126                 /*
  127                  * First look for ACPI entries in the BIOS memory map
  128                  */
  129                 for (im = bios_memmap; im->type != BIOS_MAP_END; im++)
  130                         if (im->type == BIOS_MAP_ACPI) {
  131                                 if ((ptr = acpi_scan(&handle, im->addr, im->size)))
  132                                         goto havebase;
  133                         }
  134         }
  135 #endif
  136 
  137         /*
  138          * Next try to find ACPI table entries in the EBDA
  139          */
  140         if (acpi_map(0, NBPG, &handle))
  141                 printf("acpi: failed to map BIOS data area\n");
  142         else {
  143                 ebda = *(const u_int16_t *)(&handle.va[0x40e]);
  144                 ebda <<= 4;
  145                 acpi_unmap(&handle);
  146 
  147                 if (ebda && ebda < IOM_BEGIN) {
  148                         if ((ptr = acpi_scan(&handle, ebda, 1024)))
  149                                 goto havebase;
  150                 }
  151         }
  152 
  153         /*
  154          * Finally try to find the ACPI table entries in the
  155          * BIOS memory
  156          */
  157         if ((ptr = acpi_scan(&handle, ACPI_BIOS_RSDP_WINDOW_BASE,
  158             ACPI_BIOS_RSDP_WINDOW_SIZE)))
  159                 goto havebase;
  160 
  161         return (0);
  162 
  163 havebase:
  164         aaa->aaa_pbase = ptr - handle.va + handle.pa;
  165         acpi_unmap(&handle);
  166 
  167         return (1);
  168 }
  169 
  170 void
  171 acpi_attach_machdep(struct acpi_softc *sc)
  172 {
  173 #ifdef ACPI_ENABLE
  174         sc->sc_interrupt = isa_intr_establish(NULL, sc->sc_fadt->sci_int,
  175             IST_LEVEL, IPL_TTY, acpi_interrupt, sc, "acpi");
  176 #endif
  177 }

/* [<][>][^][v][top][bottom][index][help] */