From f937ff168d942b8624049afa6d22a978430e5d9a Mon Sep 17 00:00:00 2001 From: kettenis Date: Thu, 4 Jan 2018 14:30:08 +0000 Subject: [PATCH] Implement support for calling EFI runtime services and use it to implement a time-of-day clock device based on the GetTime() and SetTime() services. The virtual memory mappings for the runtime services calls are implemented through a separate pmap that is only activated when we make a runtime services call. ok tom@, visa@ tested by naddy@ --- sys/arch/arm64/arm64/machdep.c | 99 ++++++++++-- sys/arch/arm64/arm64/pmap.c | 27 ++-- sys/arch/arm64/conf/GENERIC | 3 +- sys/arch/arm64/conf/RAMDISK | 3 +- sys/arch/arm64/conf/files.arm64 | 6 +- sys/arch/arm64/dev/efi.c | 258 ++++++++++++++++++++++++++++++++ sys/arch/arm64/dev/mainbus.c | 25 +++- sys/arch/arm64/include/pmap.h | 3 +- sys/dev/acpi/efi.h | 75 +++++++++- 9 files changed, 467 insertions(+), 32 deletions(-) create mode 100644 sys/arch/arm64/dev/efi.c diff --git a/sys/arch/arm64/arm64/machdep.c b/sys/arch/arm64/arm64/machdep.c index d1d5a673849..112e3486974 100644 --- a/sys/arch/arm64/arm64/machdep.c +++ b/sys/arch/arm64/arm64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.23 2017/12/11 05:27:40 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.24 2018/01/04 14:30:08 kettenis Exp $ */ /* * Copyright (c) 2014 Patrick Wildt * @@ -755,6 +755,7 @@ initarm(struct arm64_bootparams *abp) paddr_t memstart, memend; void *config = abp->arg2; void *fdt = NULL; + EFI_PHYSICAL_ADDRESS system_table = 0; int (*map_func_save)(bus_space_tag_t, bus_addr_t, bus_size_t, int, bus_space_handle_t *); int (*map_a4x_func_save)(bus_space_tag_t, bus_addr_t, bus_size_t, int, @@ -794,6 +795,10 @@ initarm(struct arm64_bootparams *abp) len = fdt_node_property(node, "openbsd,uefi-mmap-desc-ver", &prop); if (len == sizeof(mmap_desc_ver)) mmap_desc_ver = bemtoh32((uint32_t *)prop); + + len = fdt_node_property(node, "openbsd,uefi-system-table", &prop); + if (len == sizeof(system_table)) + system_table = bemtoh64((uint64_t *)prop); } /* Set the pcpu data, this is needed by pmap_bootstrap */ @@ -874,7 +879,7 @@ initarm(struct arm64_bootparams *abp) for (va = vstart, csize = size; csize > 0; csize -= PAGE_SIZE, va += PAGE_SIZE, pa += PAGE_SIZE) - pmap_kenter_cache(va, pa, PROT_READ, PMAP_CACHE_WB); + pmap_kenter_cache(va, pa, PROT_READ | PROT_WRITE, PMAP_CACHE_WB); mmap = (void *)vstart; vstart += size; @@ -912,6 +917,69 @@ initarm(struct arm64_bootparams *abp) arm64_bs_tag._space_map = map_func_save; arm64_a4x_bs_tag._space_map = map_a4x_func_save; + /* Remap EFI runtime. */ + if (mmap_start != 0 && system_table != 0) { + EFI_SYSTEM_TABLE *st = (EFI_SYSTEM_TABLE *)system_table; + EFI_RUNTIME_SERVICES *rs; + EFI_STATUS status; + EFI_MEMORY_DESCRIPTOR *src; + EFI_MEMORY_DESCRIPTOR *dst; + EFI_PHYSICAL_ADDRESS phys_start = ~0ULL; + EFI_VIRTUAL_ADDRESS virt_start; + vsize_t space; + int i, count = 0; + paddr_t pa; + + /* + * Pick a random address somewhere in the lower half + * of the usable virtual address space. + */ + space = 3 * (VM_MAX_ADDRESS - VM_MIN_ADDRESS) / 4; + virt_start = VM_MIN_ADDRESS + + ((vsize_t)arc4random_uniform(space >> PAGE_SHIFT) << PAGE_SHIFT); + + /* Make sure the EFI system table is mapped. */ + pmap_map_early(system_table, sizeof(EFI_SYSTEM_TABLE)); + rs = st->RuntimeServices; + + /* Make sure memory for EFI runtime services is mapped. */ + src = mmap; + for (i = 0; i < mmap_size / mmap_desc_size; i++) { + if (src->Attribute & EFI_MEMORY_RUNTIME) { + pmap_map_early(src->PhysicalStart, + src->NumberOfPages * PAGE_SIZE); + if (phys_start > src->PhysicalStart) + phys_start = src->PhysicalStart; + count++; + } + src = NextMemoryDescriptor(src, mmap_desc_size); + } + + /* Allocate memory descriptors for new mappings. */ + pa = pmap_steal_avail(count * mmap_desc_size, + mmap_desc_size, NULL); + memset((void *)pa, 0, count * mmap_desc_size); + + src = mmap; + dst = (EFI_MEMORY_DESCRIPTOR *)pa; + for (i = 0; i < mmap_size / mmap_desc_size; i++) { + if (src->Attribute & EFI_MEMORY_RUNTIME) { + src->VirtualStart = virt_start + + (src->PhysicalStart - phys_start); + memcpy(dst, src, mmap_desc_size); + dst = NextMemoryDescriptor(dst, mmap_desc_size); + } + src = NextMemoryDescriptor(src, mmap_desc_size); + } + + /* Install new mappings. */ + dst = (EFI_MEMORY_DESCRIPTOR *)pa; + status = rs->SetVirtualAddressMap(count * mmap_desc_size, + mmap_desc_size, mmap_desc_ver, dst); + if (status != EFI_SUCCESS) + printf("SetVirtualAddressMap failed: %lu\n", status); + } + /* XXX */ pmap_avail_fixup(); @@ -923,6 +991,7 @@ initarm(struct arm64_bootparams *abp) /* Make all other physical memory available to UVM. */ if (mmap && mmap_desc_ver == EFI_MEMORY_DESCRIPTOR_VERSION) { + EFI_MEMORY_DESCRIPTOR *desc = mmap; int i; /* @@ -933,20 +1002,20 @@ initarm(struct arm64_bootparams *abp) */ for (i = 0; i < mmap_size / mmap_desc_size; i++) { printf("type 0x%x pa 0x%llx va 0x%llx pages 0x%llx attr 0x%llx\n", - mmap->Type, mmap->PhysicalStart, - mmap->VirtualStart, mmap->NumberOfPages, - mmap->Attribute); - if (mmap->Type == EfiConventionalMemory && - mmap->NumberOfPages >= 16) { - uvm_page_physload(atop(mmap->PhysicalStart), - atop(mmap->PhysicalStart) + - mmap->NumberOfPages, - atop(mmap->PhysicalStart), - atop(mmap->PhysicalStart) + - mmap->NumberOfPages, 0); - physmem += mmap->NumberOfPages; + desc->Type, desc->PhysicalStart, + desc->VirtualStart, desc->NumberOfPages, + desc->Attribute); + if (desc->Type == EfiConventionalMemory && + desc->NumberOfPages >= 16) { + uvm_page_physload(atop(desc->PhysicalStart), + atop(desc->PhysicalStart) + + desc->NumberOfPages, + atop(desc->PhysicalStart), + atop(desc->PhysicalStart) + + desc->NumberOfPages, 0); + physmem += desc->NumberOfPages; } - mmap = NextMemoryDescriptor(mmap, mmap_desc_size); + desc = NextMemoryDescriptor(desc, mmap_desc_size); } } else { paddr_t start, end; diff --git a/sys/arch/arm64/arm64/pmap.c b/sys/arch/arm64/arm64/pmap.c index f68d2d23b27..c147b00885d 100644 --- a/sys/arch/arm64/arm64/pmap.c +++ b/sys/arch/arm64/arm64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.41 2017/12/31 08:42:04 kettenis Exp $ */ +/* $OpenBSD: pmap.c,v 1.42 2018/01/04 14:30:08 kettenis Exp $ */ /* * Copyright (c) 2008-2009,2014-2016 Dale Rahn * @@ -186,14 +186,14 @@ VP_IDX3(vaddr_t va) } const uint64_t ap_bits_user[8] = { - [PROT_NONE] = ATTR_nG|ATTR_PXN|ATTR_UXN|ATTR_AP(2), - [PROT_READ] = ATTR_nG|ATTR_PXN|ATTR_UXN|ATTR_AF|ATTR_AP(3), - [PROT_WRITE] = ATTR_nG|ATTR_PXN|ATTR_UXN|ATTR_AF|ATTR_AP(1), - [PROT_WRITE|PROT_READ] = ATTR_nG|ATTR_PXN|ATTR_UXN|ATTR_AF|ATTR_AP(1), - [PROT_EXEC] = ATTR_nG|ATTR_PXN|ATTR_AF|ATTR_AP(2), - [PROT_EXEC|PROT_READ] = ATTR_nG|ATTR_PXN|ATTR_AF|ATTR_AP(3), - [PROT_EXEC|PROT_WRITE] = ATTR_nG|ATTR_PXN|ATTR_AF|ATTR_AP(1), - [PROT_EXEC|PROT_WRITE|PROT_READ]= ATTR_nG|ATTR_PXN|ATTR_AF|ATTR_AP(1), + [PROT_NONE] = ATTR_PXN|ATTR_UXN|ATTR_AP(2), + [PROT_READ] = ATTR_PXN|ATTR_UXN|ATTR_AF|ATTR_AP(3), + [PROT_WRITE] = ATTR_PXN|ATTR_UXN|ATTR_AF|ATTR_AP(1), + [PROT_WRITE|PROT_READ] = ATTR_PXN|ATTR_UXN|ATTR_AF|ATTR_AP(1), + [PROT_EXEC] = ATTR_PXN|ATTR_AF|ATTR_AP(2), + [PROT_EXEC|PROT_READ] = ATTR_PXN|ATTR_AF|ATTR_AP(3), + [PROT_EXEC|PROT_WRITE] = ATTR_PXN|ATTR_AF|ATTR_AP(1), + [PROT_EXEC|PROT_WRITE|PROT_READ] = ATTR_PXN|ATTR_AF|ATTR_AP(1), }; const uint64_t ap_bits_kern[8] = { @@ -1081,6 +1081,7 @@ pmap_bootstrap(long kvo, paddr_t lpt1, long kernelstart, long kernelend, pt1pa = pmap_steal_avail(sizeof(struct pmapvp1), Lx_TABLE_ALIGN, &va); vp1 = (struct pmapvp1 *)pt1pa; pmap_kernel()->pm_vp.l1 = (struct pmapvp1 *)va; + pmap_kernel()->pm_privileged = 1; pmap_kernel()->pm_asid = 0; /* allocate Lx entries */ @@ -1205,6 +1206,8 @@ pmap_bootstrap(long kvo, paddr_t lpt1, long kernelstart, long kernelend, printf("all mapped\n"); + curcpu()->ci_curpm = pmap_kernel(); + memhook = (char *)vstart; vstart += PAGE_SIZE; @@ -1496,12 +1499,14 @@ pmap_pte_update(struct pte_desc *pted, uint64_t *pl3) panic("pmap_pte_insert: invalid cache mode"); } - /* kernel mappings are global, so nG should not be set */ - if (pm == pmap_kernel()) + if (pm->pm_privileged) access_bits = ap_bits_kern[pted->pted_pte & PROT_MASK]; else access_bits = ap_bits_user[pted->pted_pte & PROT_MASK]; + if (pted->pted_va < VM_MIN_KERNEL_ADDRESS) + access_bits |= ATTR_nG; + pte = (pted->pted_pte & PTE_RPGN) | attr | access_bits | L3_P; *pl3 = pte; } diff --git a/sys/arch/arm64/conf/GENERIC b/sys/arch/arm64/conf/GENERIC index 7a22c87548b..2e6f23bd2c3 100644 --- a/sys/arch/arm64/conf/GENERIC +++ b/sys/arch/arm64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.47 2018/01/02 22:47:45 kettenis Exp $ +# $OpenBSD: GENERIC,v 1.48 2018/01/04 14:30:08 kettenis Exp $ # # GENERIC machine description file # @@ -36,6 +36,7 @@ config bsd swap generic # The main bus device mainbus0 at root cpu0 at mainbus? +efi0 at mainbus? simplebus* at fdt? scsibus* at scsi? diff --git a/sys/arch/arm64/conf/RAMDISK b/sys/arch/arm64/conf/RAMDISK index 0a2a8ce1407..72b96802626 100644 --- a/sys/arch/arm64/conf/RAMDISK +++ b/sys/arch/arm64/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.41 2018/01/02 22:47:45 kettenis Exp $ +# $OpenBSD: RAMDISK,v 1.42 2018/01/04 14:30:08 kettenis Exp $ # # GENERIC machine description file # @@ -47,6 +47,7 @@ config bsd root on rd0a swap on rd0b # The main bus device mainbus0 at root cpu0 at mainbus? +efi0 at mainbus? simplebus* at fdt? scsibus* at scsi? diff --git a/sys/arch/arm64/conf/files.arm64 b/sys/arch/arm64/conf/files.arm64 index 00a6bac4f73..a4eee2b0e0a 100644 --- a/sys/arch/arm64/conf/files.arm64 +++ b/sys/arch/arm64/conf/files.arm64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.arm64,v 1.15 2017/06/04 14:10:42 patrick Exp $ +# $OpenBSD: files.arm64,v 1.16 2018/01/04 14:30:08 kettenis Exp $ maxpartitions 16 maxusers 2 8 64 @@ -58,6 +58,10 @@ device simplebus: fdt attach simplebus at fdt file arch/arm64/dev/simplebus.c simplebus +device efi +attach efi at fdt +file arch/arm64/dev/efi.c efi + # FDT support file dev/ofw/fdt.c file dev/ofw/ofw_clock.c diff --git a/sys/arch/arm64/dev/efi.c b/sys/arch/arm64/dev/efi.c new file mode 100644 index 00000000000..976e4c08ff2 --- /dev/null +++ b/sys/arch/arm64/dev/efi.c @@ -0,0 +1,258 @@ +/* $OpenBSD: efi.c,v 1.1 2018/01/04 14:30:08 kettenis Exp $ */ + +/* + * Copyright (c) 2017 Mark Kettenis + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include + +#include + +#include + +extern todr_chip_handle_t todr_handle; + +extern uint32_t mmap_size; +extern uint32_t mmap_desc_size; +extern uint32_t mmap_desc_ver; + +extern EFI_MEMORY_DESCRIPTOR *mmap; + +struct efi_softc { + struct device sc_dev; + struct pmap *sc_pm; + EFI_RUNTIME_SERVICES *sc_rs; + int sc_psw; + + struct todr_chip_handle sc_todr; +}; + +int efi_match(struct device *, void *, void *); +void efi_attach(struct device *, struct device *, void *); + +struct cfattach efi_ca = { + sizeof(struct efi_softc), efi_match, efi_attach +}; + +struct cfdriver efi_cd = { + NULL, "efi", DV_DULL +}; + +void efi_enter(struct efi_softc *); +void efi_leave(struct efi_softc *); +int efi_gettime(struct todr_chip_handle *, struct timeval *); +int efi_settime(struct todr_chip_handle *, struct timeval *); + +int +efi_match(struct device *parent, void *match, void *aux) +{ + struct fdt_attach_args *faa = aux; + + return (strcmp(faa->fa_name, "efi") == 0); +} + +void +efi_attach(struct device *parent, struct device *self, void *aux) +{ + struct efi_softc *sc = (struct efi_softc *)self; + struct fdt_attach_args *faa = aux; + uint64_t system_table; + bus_space_handle_t ioh; + EFI_SYSTEM_TABLE *st; + EFI_RUNTIME_SERVICES *rs; + EFI_MEMORY_DESCRIPTOR *desc; + EFI_TIME time; + EFI_STATUS status; + uint16_t major, minor; + int node, i; + + node = OF_finddevice("/chosen"); + KASSERT(node); + + system_table = OF_getpropint64(node, "openbsd,uefi-system-table", 0); + KASSERT(system_table); + + if (bus_space_map(faa->fa_iot, system_table, sizeof(EFI_SYSTEM_TABLE), + BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, &ioh)) { + printf(": can't map system table\n"); + return; + } + + st = bus_space_vaddr(faa->fa_iot, ioh); + rs = st->RuntimeServices; + + major = st->Hdr.Revision >> 16; + minor = st->Hdr.Revision & 0xffff; + printf(": UEFI %d.%d", major, minor / 10); + if (minor % 10) + printf(".%d", minor % 10); + printf("\n"); + + /* + * We don't really want some random executable non-OpenBSD + * code lying around in kernel space. So create a separate + * pmap and only activate it when we call runtime services. + */ + sc->sc_pm = pmap_create(); + sc->sc_pm->pm_privileged = 1; + + desc = mmap; + for (i = 0; i < mmap_size / mmap_desc_size; i++) { + if (desc->Attribute & EFI_MEMORY_RUNTIME) { + vaddr_t va = desc->VirtualStart; + paddr_t pa = desc->PhysicalStart; + int npages = desc->NumberOfPages; + vm_prot_t prot = PROT_READ; + +#ifdef EFI_DEBUG + printf("type 0x%x pa 0x%llx va 0x%llx pages 0x%llx attr 0x%llx\n", + desc->Type, desc->PhysicalStart, + desc->VirtualStart, desc->NumberOfPages, + desc->Attribute); +#endif + + if (desc->Type == EfiRuntimeServicesCode) + prot |= PROT_EXEC; + else + prot |= PROT_WRITE; + while (npages--) { + pmap_enter(sc->sc_pm, va, pa, prot, + prot | PMAP_WIRED); + va += PAGE_SIZE; + pa += PAGE_SIZE; + } + } + desc = NextMemoryDescriptor(desc, mmap_desc_size); + } + + /* + * The FirmwareVendor field has been converted from a physical + * pointer to a virtual pointer, so we have to activate our + * pmap to access it. + */ + if (st->FirmwareVendor) { + printf("%s: ", sc->sc_dev.dv_xname); + efi_enter(sc); + for (i = 0; st->FirmwareVendor[i]; i++) + printf("%c", st->FirmwareVendor[i]); + efi_leave(sc); + printf(" rev 0x%x\n", st->FirmwareRevision); + } + + if (rs == NULL) + return; + + efi_enter(sc); + status = rs->GetTime(&time, NULL); + efi_leave(sc); + if (status != EFI_SUCCESS) + return; + + sc->sc_rs = rs; + sc->sc_todr.cookie = sc; + sc->sc_todr.todr_gettime = efi_gettime; + sc->sc_todr.todr_settime = efi_settime; + todr_handle = &sc->sc_todr; +} + +void +efi_enter(struct efi_softc *sc) +{ + struct pmap *pm = sc->sc_pm; + + sc->sc_psw = disable_interrupts(); + cpu_setttb(((uint64_t)pm->pm_asid << 48) | pm->pm_pt0pa); +} + +void +efi_leave(struct efi_softc *sc) +{ + struct pmap *pm = curcpu()->ci_curpm; + + cpu_setttb(((uint64_t)pm->pm_asid << 48) | pm->pm_pt0pa); + restore_interrupts(sc->sc_psw); +} + +int +efi_gettime(struct todr_chip_handle *handle, struct timeval *tv) +{ + struct efi_softc *sc = handle->cookie; + struct clock_ymdhms dt; + EFI_TIME time; + EFI_STATUS status; + + efi_enter(sc); + status = sc->sc_rs->GetTime(&time, NULL); + efi_leave(sc); + if (status != EFI_SUCCESS) + return EIO; + + dt.dt_year = time.Year; + dt.dt_mon = time.Month; + dt.dt_day = time.Day; + dt.dt_hour = time.Hour; + dt.dt_min = time.Minute; + dt.dt_sec = time.Second; + + if (dt.dt_sec > 59 || dt.dt_min > 59 || dt.dt_hour > 23 || + dt.dt_day > 31 || dt.dt_day == 0 || + dt.dt_mon > 12 || dt.dt_mon == 0 || + dt.dt_year < POSIX_BASE_YEAR) + return EINVAL; + + tv->tv_sec = clock_ymdhms_to_secs(&dt); + tv->tv_usec = 0; + return 0; +} + +int +efi_settime(struct todr_chip_handle *handle, struct timeval *tv) +{ + struct efi_softc *sc = handle->cookie; + struct clock_ymdhms dt; + EFI_TIME time; + EFI_STATUS status; + + clock_secs_to_ymdhms(tv->tv_sec, &dt); + + time.Year = dt.dt_year; + time.Month = dt.dt_mon; + time.Day = dt.dt_day; + time.Hour = dt.dt_hour; + time.Minute = dt.dt_min; + time.Second = dt.dt_sec; + time.Nanosecond = 0; + time.TimeZone = 0; + time.Daylight = 0; + + efi_enter(sc); + status = sc->sc_rs->SetTime(&time); + efi_leave(sc); + if (status != EFI_SUCCESS) + return EIO; + return 0; +} + diff --git a/sys/arch/arm64/dev/mainbus.c b/sys/arch/arm64/dev/mainbus.c index 780c7ed2aff..474e2397b17 100644 --- a/sys/arch/arm64/dev/mainbus.c +++ b/sys/arch/arm64/dev/mainbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mainbus.c,v 1.7 2017/08/23 12:58:00 kettenis Exp $ */ +/* $OpenBSD: mainbus.c,v 1.8 2018/01/04 14:30:08 kettenis Exp $ */ /* * Copyright (c) 2016 Patrick Wildt * Copyright (c) 2017 Mark Kettenis @@ -37,6 +37,7 @@ int mainbus_match_status(struct device *, void *, void *); void mainbus_attach_cpus(struct device *, cfmatch_t); int mainbus_match_primary(struct device *, void *, void *); int mainbus_match_secondary(struct device *, void *, void *); +void mainbus_attach_efi(struct device *); void mainbus_attach_framebuffer(struct device *); struct mainbus_softc { @@ -120,6 +121,8 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) /* Attach primary CPU first. */ mainbus_attach_cpus(self, mainbus_match_primary); + mainbus_attach_efi(self); + sc->sc_rangeslen = OF_getproplen(OF_peer(0), "ranges"); if (sc->sc_rangeslen > 0 && !(sc->sc_rangeslen % sizeof(uint32_t))) { sc->sc_ranges = malloc(sc->sc_rangeslen, M_TEMP, M_WAITOK); @@ -215,6 +218,9 @@ mainbus_match_status(struct device *parent, void *match, void *aux) struct cfdata *cf = match; char buf[32]; + if (fa->fa_node == 0) + return 0; + if (OF_getprop(fa->fa_node, "status", buf, sizeof(buf)) > 0 && strcmp(buf, "disabled") == 0) return 0; @@ -272,6 +278,23 @@ mainbus_match_secondary(struct device *parent, void *match, void *aux) return (*cf->cf_attach->ca_match)(parent, match, aux); } +void +mainbus_attach_efi(struct device *self) +{ + struct mainbus_softc *sc = (struct mainbus_softc *)self; + struct fdt_attach_args fa; + int node = OF_finddevice("/chosen"); + + if (node == 0 || OF_getproplen(node, "openbsd,uefi-system-table") <= 0) + return; + + memset(&fa, 0, sizeof(fa)); + fa.fa_name = "efi"; + fa.fa_iot = sc->sc_iot; + fa.fa_dmat = sc->sc_dmat; + config_found(self, &fa, NULL); +} + void mainbus_attach_framebuffer(struct device *self) { diff --git a/sys/arch/arm64/include/pmap.h b/sys/arch/arm64/include/pmap.h index e4024d2ef0a..0c16ae9eaaf 100644 --- a/sys/arch/arm64/include/pmap.h +++ b/sys/arch/arm64/include/pmap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.h,v 1.7 2017/12/31 08:42:04 kettenis Exp $ */ +/* $OpenBSD: pmap.h,v 1.8 2018/01/04 14:30:08 kettenis Exp $ */ /* * Copyright (c) 2008,2009,2014 Dale Rahn * @@ -71,6 +71,7 @@ struct pmap { } pm_vp; uint64_t pm_pt0pa; int have_4_level_pt; + int pm_privileged; int pm_asid; int pm_refs; /* ref count */ struct pmap_statistics pm_stats; /* pmap statistics */ diff --git a/sys/dev/acpi/efi.h b/sys/dev/acpi/efi.h index 91f8ade4985..a3500787958 100644 --- a/sys/dev/acpi/efi.h +++ b/sys/dev/acpi/efi.h @@ -1,4 +1,4 @@ -/* $OpenBSD: efi.h,v 1.1 2017/05/25 21:21:18 kettenis Exp $ */ +/* $OpenBSD: efi.h,v 1.2 2018/01/04 14:30:08 kettenis Exp $ */ /* Public Domain */ @@ -6,10 +6,22 @@ #define _MACHINE_EFI_H_ typedef uint8_t UINT8; +typedef int16_t INT16; +typedef uint16_t UINT16; typedef uint32_t UINT32; typedef uint64_t UINT64; +typedef u_long UINTN; +typedef uint16_t CHAR16; +typedef void VOID; +typedef uint32_t EFI_GUID[4]; typedef uint64_t EFI_PHYSICAL_ADDRESS; typedef uint64_t EFI_VIRTUAL_ADDRESS; +typedef UINTN EFI_STATUS; +typedef VOID *EFI_HANDLE; + +typedef VOID *EFI_SIMPLE_TEXT_INPUT_PROTOCOL; +typedef VOID *EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL; +typedef VOID *EFI_BOOT_SERVICES; typedef enum { EfiReservedMemoryType, @@ -57,4 +69,65 @@ typedef struct { #define NextMemoryDescriptor(Ptr, Size) \ ((EFI_MEMORY_DESCRIPTOR *)(((UINT8 *)Ptr) + Size)) +typedef struct { + UINT64 Signature; + UINT32 Revision; + UINT32 HeaderSize; + UINT32 CRC32; + UINT32 Reserved; +} EFI_TABLE_HEADER; + +typedef struct { + UINT16 Year; + UINT8 Month; + UINT8 Day; + UINT8 Hour; + UINT8 Minute; + UINT8 Second; + UINT8 Pad1; + UINT32 Nanosecond; + INT16 TimeZone; + UINT8 Daylight; + UINT8 Pad2; +} EFI_TIME; + +typedef VOID *EFI_TIME_CAPABILITIES; + +typedef EFI_STATUS (*EFI_GET_TIME)(EFI_TIME *, EFI_TIME_CAPABILITIES *); +typedef EFI_STATUS (*EFI_SET_TIME)(EFI_TIME *); +typedef EFI_STATUS (*EFI_SET_VIRTUAL_ADDRESS_MAP)(UINTN, UINTN, UINT32, EFI_MEMORY_DESCRIPTOR *); + +typedef struct { + EFI_TABLE_HEADER Hdr; + EFI_GET_TIME GetTime; + EFI_SET_TIME SetTime; + VOID *GetWakeupTime; + VOID *SetWakeupTime; + + EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap; +} EFI_RUNTIME_SERVICES; + +typedef struct { + EFI_GUID VendorGuid; + VOID *VendorTable; +} EFI_CONFIGURATION_TABLE; + +typedef struct { + EFI_TABLE_HEADER Hdr; + CHAR16 *FirmwareVendor; + UINT32 FirmwareRevision; + EFI_HANDLE ConsoleInHandle; + EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn; + EFI_HANDLE ConsoleOutHandle; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; + EFI_HANDLE StandardErrorHandle; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr; + EFI_RUNTIME_SERVICES *RuntimeServices; + EFI_BOOT_SERVICES *BootServices; + UINTN NumberOfTableEntries; + EFI_CONFIGURATION_TABLE *ConfigurationTable; +} EFI_SYSTEM_TABLE; + +#define EFI_SUCCESS 0 + #endif /* _MACHINE_EFI_H_ */ -- 2.20.1