[BACK]Return to acpi_machdep.c CVS log [TXT][DIR] Up to [local] / sys / arch / i386 / i386

Annotation of sys/arch/i386/i386/acpi_machdep.c, Revision 1.1

1.1     ! nbrk        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: }

CVSweb