1*07ede913Sjmcneill /* $NetBSD: acpi_platform.c,v 1.38 2024/12/08 20:55:18 jmcneill Exp $ */ 297d57f80Sjmcneill 397d57f80Sjmcneill /*- 497d57f80Sjmcneill * Copyright (c) 2018 The NetBSD Foundation, Inc. 597d57f80Sjmcneill * All rights reserved. 697d57f80Sjmcneill * 797d57f80Sjmcneill * This code is derived from software contributed to The NetBSD Foundation 897d57f80Sjmcneill * by Jared McNeill <jmcneill@invisible.ca>. 997d57f80Sjmcneill * 1097d57f80Sjmcneill * Redistribution and use in source and binary forms, with or without 1197d57f80Sjmcneill * modification, are permitted provided that the following conditions 1297d57f80Sjmcneill * are met: 1397d57f80Sjmcneill * 1. Redistributions of source code must retain the above copyright 1497d57f80Sjmcneill * notice, this list of conditions and the following disclaimer. 1597d57f80Sjmcneill * 2. Redistributions in binary form must reproduce the above copyright 1697d57f80Sjmcneill * notice, this list of conditions and the following disclaimer in the 1797d57f80Sjmcneill * documentation and/or other materials provided with the distribution. 1897d57f80Sjmcneill * 1997d57f80Sjmcneill * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 2097d57f80Sjmcneill * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2197d57f80Sjmcneill * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2297d57f80Sjmcneill * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2397d57f80Sjmcneill * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2497d57f80Sjmcneill * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2597d57f80Sjmcneill * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2697d57f80Sjmcneill * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2797d57f80Sjmcneill * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2897d57f80Sjmcneill * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2997d57f80Sjmcneill * POSSIBILITY OF SUCH DAMAGE. 3097d57f80Sjmcneill */ 3197d57f80Sjmcneill 32f4511081Sjmcneill #include "com.h" 33f4511081Sjmcneill #include "plcom.h" 3456949079Sjmcneill #include "opt_efi.h" 356f2828aaSryo #include "opt_multiprocessor.h" 36f4511081Sjmcneill 3797d57f80Sjmcneill #include <sys/cdefs.h> 38*07ede913Sjmcneill __KERNEL_RCSID(0, "$NetBSD: acpi_platform.c,v 1.38 2024/12/08 20:55:18 jmcneill Exp $"); 3997d57f80Sjmcneill 4097d57f80Sjmcneill #include <sys/param.h> 4197d57f80Sjmcneill #include <sys/bus.h> 4297d57f80Sjmcneill #include <sys/cpu.h> 4397d57f80Sjmcneill #include <sys/device.h> 4497d57f80Sjmcneill #include <sys/termios.h> 453771b87fSjmcneill #include <sys/kprintf.h> 4697d57f80Sjmcneill 4797d57f80Sjmcneill #include <dev/fdt/fdtvar.h> 4897d57f80Sjmcneill 4997d57f80Sjmcneill #include <uvm/uvm_extern.h> 5097d57f80Sjmcneill 5197d57f80Sjmcneill #include <machine/bootconfig.h> 5297d57f80Sjmcneill #include <arm/cpufunc.h> 5397d57f80Sjmcneill #include <arm/locore.h> 5497d57f80Sjmcneill 5597d57f80Sjmcneill #include <arm/cortex/gtmr_var.h> 5697d57f80Sjmcneill 5781be3b13Sjmcneill #include <arm/arm/smccc.h> 5897d57f80Sjmcneill #include <arm/arm/psci.h> 5997d57f80Sjmcneill #include <arm/fdt/psci_fdtvar.h> 6097d57f80Sjmcneill 6197d57f80Sjmcneill #include <evbarm/fdt/platform.h> 6297d57f80Sjmcneill 6397d57f80Sjmcneill #include <evbarm/dev/plcomreg.h> 6497d57f80Sjmcneill #include <evbarm/dev/plcomvar.h> 6597d57f80Sjmcneill #include <dev/ic/ns16550reg.h> 6697d57f80Sjmcneill #include <dev/ic/comreg.h> 67f4511081Sjmcneill #include <dev/ic/comvar.h> 6897d57f80Sjmcneill 69fd3e8957Sjmcneill #if NCOM > 0 70fd3e8957Sjmcneill #include <dev/pci/pcireg.h> 71fd3e8957Sjmcneill #include <dev/pci/pcivar.h> 72fd3e8957Sjmcneill #include <dev/pci/pucvar.h> 73fd3e8957Sjmcneill #endif 74fd3e8957Sjmcneill 7556949079Sjmcneill #ifdef EFI_RUNTIME 7656949079Sjmcneill #include <arm/arm/efi_runtime.h> 7756949079Sjmcneill #endif 7856949079Sjmcneill 7997d57f80Sjmcneill #include <dev/acpi/acpireg.h> 8097d57f80Sjmcneill #include <dev/acpi/acpivar.h> 8156949079Sjmcneill #include <arm/acpi/acpi_table.h> 82397fdee4Sjmcneill #include <dev/acpi/acpi_srat.h> 8356949079Sjmcneill 8456949079Sjmcneill #include <libfdt.h> 8597d57f80Sjmcneill 86e4cf01d0Sjmcneill #define SPCR_BAUD_DEFAULT 0 87c538a2a4Sjmcneill #define SPCR_BAUD_9600 3 88c538a2a4Sjmcneill #define SPCR_BAUD_19200 4 89c538a2a4Sjmcneill #define SPCR_BAUD_57600 6 90c538a2a4Sjmcneill #define SPCR_BAUD_115200 7 9197d57f80Sjmcneill 92e4cf01d0Sjmcneill static const struct acpi_spcr_baud_rate { 93e4cf01d0Sjmcneill uint8_t id; 944285aa16Sjmcneill int baud_rate; 95e4cf01d0Sjmcneill } acpi_spcr_baud_rates[] = { 96bdd7567cSjmcneill /* 97bdd7567cSjmcneill * SPCR_BAUD_DEFAULT means: 98bdd7567cSjmcneill * "As is, operating system relies on the current configuration 99bdd7567cSjmcneill * of serial port until the full featured driver will be 100bdd7567cSjmcneill * initialized." 101bdd7567cSjmcneill * 102bdd7567cSjmcneill * We don't currently have a good way of telling the UART driver 103bdd7567cSjmcneill * to detect the currently configured baud rate, so just pick 104bdd7567cSjmcneill * something sensible here. 105bdd7567cSjmcneill * 106bdd7567cSjmcneill * In the past we have tried baud_rate values of 0 and -1, but 107bdd7567cSjmcneill * these cause problems with the com(4) driver. 108bdd7567cSjmcneill */ 109bdd7567cSjmcneill { SPCR_BAUD_DEFAULT, 115200 }, 110e4cf01d0Sjmcneill { SPCR_BAUD_9600, 9600 }, 111e4cf01d0Sjmcneill { SPCR_BAUD_19200, 19200 }, 112e4cf01d0Sjmcneill { SPCR_BAUD_57600, 57600 }, 113e4cf01d0Sjmcneill { SPCR_BAUD_115200, 115200 }, 114e4cf01d0Sjmcneill }; 115e4cf01d0Sjmcneill 11697d57f80Sjmcneill extern struct bus_space arm_generic_bs_tag; 11797d57f80Sjmcneill 1188d7bb3e1Srjs #if NPLCOM > 0 11997d57f80Sjmcneill static struct plcom_instance plcom_console; 1208d7bb3e1Srjs #endif 12197d57f80Sjmcneill 1224ed488bfSjmcneill struct arm32_bus_dma_tag acpi_coherent_dma_tag; 1234ed488bfSjmcneill static struct arm32_dma_range acpi_coherent_ranges[] = { 124e85f76feSjmcneill [0] = { 125e85f76feSjmcneill .dr_sysbase = 0, 126e85f76feSjmcneill .dr_busbase = 0, 127e85f76feSjmcneill .dr_len = UINTPTR_MAX, 128e85f76feSjmcneill .dr_flags = _BUS_DMAMAP_COHERENT, 129e85f76feSjmcneill } 130e85f76feSjmcneill }; 131e85f76feSjmcneill 13297d57f80Sjmcneill static const struct pmap_devmap * 13397d57f80Sjmcneill acpi_platform_devmap(void) 13497d57f80Sjmcneill { 13597d57f80Sjmcneill static const struct pmap_devmap devmap[] = { 13697d57f80Sjmcneill DEVMAP_ENTRY_END 13797d57f80Sjmcneill }; 13897d57f80Sjmcneill 13997d57f80Sjmcneill return devmap; 14097d57f80Sjmcneill } 14197d57f80Sjmcneill 14297d57f80Sjmcneill static void 14397d57f80Sjmcneill acpi_platform_bootstrap(void) 14497d57f80Sjmcneill { 145e85f76feSjmcneill extern struct arm32_bus_dma_tag arm_generic_dma_tag; 146e85f76feSjmcneill 1474ed488bfSjmcneill acpi_coherent_dma_tag = arm_generic_dma_tag; 1484ed488bfSjmcneill acpi_coherent_dma_tag._ranges = acpi_coherent_ranges; 1494ed488bfSjmcneill acpi_coherent_dma_tag._nranges = __arraycount(acpi_coherent_ranges); 15097d57f80Sjmcneill } 15197d57f80Sjmcneill 15297d57f80Sjmcneill static void 153e4cf01d0Sjmcneill acpi_platform_attach_uart(ACPI_TABLE_SPCR *spcr) 15497d57f80Sjmcneill { 155e4cf01d0Sjmcneill #if NCOM > 0 156e4cf01d0Sjmcneill struct com_regs regs; 157e4cf01d0Sjmcneill bus_space_handle_t dummy_bsh; 158e4cf01d0Sjmcneill u_int reg_shift; 1596f2828aaSryo #endif 160e4cf01d0Sjmcneill int baud_rate, n; 16197d57f80Sjmcneill 16297d57f80Sjmcneill /* 163e4cf01d0Sjmcneill * Only MMIO access is supported today. 16497d57f80Sjmcneill */ 165e4cf01d0Sjmcneill if (spcr->SerialPort.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) { 166e4cf01d0Sjmcneill return; 167e4cf01d0Sjmcneill } 168e4cf01d0Sjmcneill if (le64toh(spcr->SerialPort.Address) == 0) { 169e4cf01d0Sjmcneill return; 170c538a2a4Sjmcneill } 17197d57f80Sjmcneill 172e4cf01d0Sjmcneill /* 173e4cf01d0Sjmcneill * Lookup SPCR baud rate. 174e4cf01d0Sjmcneill */ 175e4cf01d0Sjmcneill baud_rate = 0; 176e4cf01d0Sjmcneill for (n = 0; n < __arraycount(acpi_spcr_baud_rates); n++) { 177e4cf01d0Sjmcneill if (acpi_spcr_baud_rates[n].id == spcr->BaudRate) { 178e4cf01d0Sjmcneill baud_rate = acpi_spcr_baud_rates[n].baud_rate; 179e4cf01d0Sjmcneill break; 180e4cf01d0Sjmcneill } 181e4cf01d0Sjmcneill } 182e4cf01d0Sjmcneill 183e4cf01d0Sjmcneill /* 184e4cf01d0Sjmcneill * Attach console device. 185e4cf01d0Sjmcneill */ 186f4511081Sjmcneill switch (spcr->InterfaceType) { 187f4511081Sjmcneill #if NPLCOM > 0 1884fcf9709Sjmcneill case ACPI_DBG2_ARM_PL011: 1894fcf9709Sjmcneill case ACPI_DBG2_ARM_SBSA_32BIT: 1904fcf9709Sjmcneill case ACPI_DBG2_ARM_SBSA_GENERIC: 191820c39ceSmlelstv if (spcr->InterfaceType == ACPI_DBG2_ARM_PL011) 192f4511081Sjmcneill plcom_console.pi_type = PLCOM_TYPE_PL011; 193820c39ceSmlelstv else 194820c39ceSmlelstv plcom_console.pi_type = PLCOM_TYPE_GENERIC_UART; 195f4511081Sjmcneill plcom_console.pi_iot = &arm_generic_bs_tag; 196e4736b55Sjmcneill plcom_console.pi_iobase = le64toh(spcr->SerialPort.Address); 197f4511081Sjmcneill plcom_console.pi_size = PL011COM_UART_SIZE; 198f4511081Sjmcneill plcom_console.pi_flags = PLC_FLAG_32BIT_ACCESS; 199f4511081Sjmcneill 200c538a2a4Sjmcneill plcomcnattach(&plcom_console, baud_rate, 0, TTYDEF_CFLAG, -1); 201c538a2a4Sjmcneill break; 202f4511081Sjmcneill #endif 203e4cf01d0Sjmcneill 204f4511081Sjmcneill #if NCOM > 0 2054fcf9709Sjmcneill case ACPI_DBG2_16550_COMPATIBLE: 2064fcf9709Sjmcneill case ACPI_DBG2_16550_SUBSET: 20701e56d5dSskrll case ACPI_DBG2_16550_WITH_GAS: 208e4cf01d0Sjmcneill memset(&dummy_bsh, 0, sizeof(dummy_bsh)); 209bdd7567cSjmcneill switch (spcr->SerialPort.BitWidth) { 210bdd7567cSjmcneill case 8: 21167d944e4Sjmcneill reg_shift = 0; 212bdd7567cSjmcneill break; 213bdd7567cSjmcneill case 16: 214bdd7567cSjmcneill reg_shift = 1; 215bdd7567cSjmcneill break; 216bdd7567cSjmcneill case 32: 21767d944e4Sjmcneill reg_shift = 2; 218bdd7567cSjmcneill break; 219bdd7567cSjmcneill default: 220bdd7567cSjmcneill /* 221bdd7567cSjmcneill * Bit width 0 is possible for types 0 and 1. Otherwise, 222bdd7567cSjmcneill * possibly buggy firmware. 223bdd7567cSjmcneill */ 224bdd7567cSjmcneill if (spcr->InterfaceType == ACPI_DBG2_16550_COMPATIBLE) { 225e4cf01d0Sjmcneill reg_shift = 0; 22649ebf0dbSjmcneill } else { 227e4cf01d0Sjmcneill reg_shift = 2; 22849ebf0dbSjmcneill } 229bdd7567cSjmcneill break; 23067d944e4Sjmcneill } 231e4cf01d0Sjmcneill com_init_regs_stride(®s, &arm_generic_bs_tag, dummy_bsh, 232e4cf01d0Sjmcneill le64toh(spcr->SerialPort.Address), reg_shift); 233e4cf01d0Sjmcneill comcnattach1(®s, baud_rate, -1, COM_TYPE_NORMAL, 234e4cf01d0Sjmcneill TTYDEF_CFLAG); 23549ebf0dbSjmcneill break; 236e4cf01d0Sjmcneill 2374fcf9709Sjmcneill case ACPI_DBG2_BCM2835: 238e4cf01d0Sjmcneill memset(&dummy_bsh, 0, sizeof(dummy_bsh)); 239e4cf01d0Sjmcneill com_init_regs_stride(®s, &arm_generic_bs_tag, dummy_bsh, 240e4cf01d0Sjmcneill le64toh(spcr->SerialPort.Address) + 0x40, 2); 241e4cf01d0Sjmcneill comcnattach1(®s, baud_rate, -1, COM_TYPE_BCMAUXUART, 242e4cf01d0Sjmcneill TTYDEF_CFLAG); 243f4511081Sjmcneill cn_set_magic("+++++"); 244f4511081Sjmcneill break; 245f4511081Sjmcneill #endif 246e4cf01d0Sjmcneill 247f4511081Sjmcneill default: 248e4cf01d0Sjmcneill printf("SPCR: kernel does not support interface type %#x\n", 249e4cf01d0Sjmcneill spcr->InterfaceType); 250f4511081Sjmcneill break; 251c538a2a4Sjmcneill } 252e4cf01d0Sjmcneill 2533771b87fSjmcneill /* 2543771b87fSjmcneill * UEFI firmware may leave the console in an undesireable state (wrong 2553771b87fSjmcneill * foreground/background colour, etc). Reset the terminal and clear 256075aa194Sskrll * text from the cursor to the end of the screen. 2573771b87fSjmcneill */ 2583771b87fSjmcneill printf_flags(TOCONS|NOTSTAMP, "\033[0m"); 2593771b87fSjmcneill printf_flags(TOCONS|NOTSTAMP, "\033[0J"); 26097d57f80Sjmcneill } 261e4cf01d0Sjmcneill 262e4cf01d0Sjmcneill static void 263e4cf01d0Sjmcneill acpi_platform_startup(void) 264e4cf01d0Sjmcneill { 265e4cf01d0Sjmcneill ACPI_TABLE_SPCR *spcr; 266e4cf01d0Sjmcneill ACPI_TABLE_FADT *fadt; 267e4cf01d0Sjmcneill #ifdef MULTIPROCESSOR 268e4cf01d0Sjmcneill ACPI_TABLE_MADT *madt; 269e4cf01d0Sjmcneill #endif 270e4cf01d0Sjmcneill 271e4cf01d0Sjmcneill /* 272e4cf01d0Sjmcneill * Setup serial console device 273e4cf01d0Sjmcneill */ 274e4cf01d0Sjmcneill if (ACPI_SUCCESS(acpi_table_find(ACPI_SIG_SPCR, (void **)&spcr))) { 275e4cf01d0Sjmcneill acpi_platform_attach_uart(spcr); 27697d57f80Sjmcneill acpi_table_unmap((ACPI_TABLE_HEADER *)spcr); 27797d57f80Sjmcneill } 27897d57f80Sjmcneill 27997d57f80Sjmcneill /* 28097d57f80Sjmcneill * Initialize PSCI 0.2+ if implemented 28197d57f80Sjmcneill */ 28297d57f80Sjmcneill if (ACPI_SUCCESS(acpi_table_find(ACPI_SIG_FADT, (void **)&fadt))) { 283e4cf01d0Sjmcneill const uint16_t boot_flags = le16toh(fadt->ArmBootFlags); 284e4cf01d0Sjmcneill if ((boot_flags & ACPI_FADT_PSCI_COMPLIANT) != 0) { 285e4cf01d0Sjmcneill if ((boot_flags & ACPI_FADT_PSCI_USE_HVC) != 0) { 28697d57f80Sjmcneill psci_init(psci_call_hvc); 28797d57f80Sjmcneill } else { 28897d57f80Sjmcneill psci_init(psci_call_smc); 28997d57f80Sjmcneill } 29054b2fae0Sjmcneill smccc_probe(); 29197d57f80Sjmcneill } 29297d57f80Sjmcneill acpi_table_unmap((ACPI_TABLE_HEADER *)fadt); 29397d57f80Sjmcneill } 29497d57f80Sjmcneill 2956f2828aaSryo #ifdef MULTIPROCESSOR 29697d57f80Sjmcneill /* 29797d57f80Sjmcneill * Count CPUs 29897d57f80Sjmcneill */ 29997d57f80Sjmcneill if (ACPI_SUCCESS(acpi_table_find(ACPI_SIG_MADT, (void **)&madt))) { 300e4736b55Sjmcneill char *end = (char *)madt + le32toh(madt->Header.Length); 30197d57f80Sjmcneill char *where = (char *)madt + sizeof(ACPI_TABLE_MADT); 30297d57f80Sjmcneill while (where < end) { 303e4cf01d0Sjmcneill ACPI_SUBTABLE_HEADER *subtable = 304e4cf01d0Sjmcneill (ACPI_SUBTABLE_HEADER *)where; 30597d57f80Sjmcneill if (subtable->Type == ACPI_MADT_TYPE_GENERIC_INTERRUPT) 30697d57f80Sjmcneill arm_cpu_max++; 30797d57f80Sjmcneill where += subtable->Length; 30897d57f80Sjmcneill } 30997d57f80Sjmcneill acpi_table_unmap((ACPI_TABLE_HEADER *)madt); 31097d57f80Sjmcneill } 3116f2828aaSryo #endif /* MULTIPROCESSOR */ 31297d57f80Sjmcneill } 31397d57f80Sjmcneill 31497d57f80Sjmcneill static void 31597d57f80Sjmcneill acpi_platform_init_attach_args(struct fdt_attach_args *faa) 31697d57f80Sjmcneill { 31797d57f80Sjmcneill extern struct bus_space arm_generic_bs_tag; 31897d57f80Sjmcneill 31997d57f80Sjmcneill faa->faa_bst = &arm_generic_bs_tag; 3204ed488bfSjmcneill faa->faa_dmat = &acpi_coherent_dma_tag; 32197d57f80Sjmcneill } 32297d57f80Sjmcneill 32397d57f80Sjmcneill static void 32497d57f80Sjmcneill acpi_platform_device_register(device_t self, void *aux) 32597d57f80Sjmcneill { 326fd3e8957Sjmcneill #if NCOM > 0 327fd3e8957Sjmcneill prop_dictionary_t prop = device_properties(self); 328e4cf01d0Sjmcneill ACPI_STATUS rv; 329fd3e8957Sjmcneill 3300aeb60a2Sjmcneill if (device_is_a(self, "com")) { 331fd3e8957Sjmcneill ACPI_TABLE_SPCR *spcr; 332fd3e8957Sjmcneill 333e4cf01d0Sjmcneill rv = acpi_table_find(ACPI_SIG_SPCR, (void **)&spcr); 334e4cf01d0Sjmcneill if (ACPI_FAILURE(rv)) { 335fd3e8957Sjmcneill return; 336e4cf01d0Sjmcneill } 3370aeb60a2Sjmcneill 338e4cf01d0Sjmcneill if (spcr->SerialPort.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) { 339fd3e8957Sjmcneill goto spcr_unmap; 340e4cf01d0Sjmcneill } 341e4cf01d0Sjmcneill if (le64toh(spcr->SerialPort.Address) == 0) { 342fd3e8957Sjmcneill goto spcr_unmap; 343e4cf01d0Sjmcneill } 344fd3e8957Sjmcneill if (spcr->InterfaceType != ACPI_DBG2_16550_COMPATIBLE && 345e4cf01d0Sjmcneill spcr->InterfaceType != ACPI_DBG2_16550_SUBSET) { 346fd3e8957Sjmcneill goto spcr_unmap; 347e4cf01d0Sjmcneill } 348fd3e8957Sjmcneill 3490aeb60a2Sjmcneill if (device_is_a(device_parent(self), "puc")) { 3500aeb60a2Sjmcneill const struct puc_attach_args * const paa = aux; 3510aeb60a2Sjmcneill int b, d, f; 3520aeb60a2Sjmcneill 3530aeb60a2Sjmcneill const int s = pci_get_segment(paa->pc); 3540aeb60a2Sjmcneill pci_decompose_tag(paa->pc, paa->tag, &b, &d, &f); 3550aeb60a2Sjmcneill 356fd3e8957Sjmcneill if (spcr->PciSegment == s && spcr->PciBus == b && 357e4cf01d0Sjmcneill spcr->PciDevice == d && spcr->PciFunction == f) { 358e4cf01d0Sjmcneill prop_dictionary_set_bool(prop, 359e4cf01d0Sjmcneill "force_console", true); 360e4cf01d0Sjmcneill } 3610aeb60a2Sjmcneill } 3620aeb60a2Sjmcneill 3630aeb60a2Sjmcneill if (device_is_a(device_parent(self), "acpi")) { 3640aeb60a2Sjmcneill struct acpi_attach_args * const aa = aux; 3650aeb60a2Sjmcneill struct acpi_resources res; 3660aeb60a2Sjmcneill struct acpi_mem *mem; 3670aeb60a2Sjmcneill 368e4cf01d0Sjmcneill if (ACPI_FAILURE(acpi_resource_parse(self, 369e4cf01d0Sjmcneill aa->aa_node->ad_handle, "_CRS", &res, 370e4cf01d0Sjmcneill &acpi_resource_parse_ops_quiet))) { 3710aeb60a2Sjmcneill goto spcr_unmap; 372e4cf01d0Sjmcneill } 3730aeb60a2Sjmcneill 3740aeb60a2Sjmcneill mem = acpi_res_mem(&res, 0); 375e4cf01d0Sjmcneill if (mem == NULL) { 3760aeb60a2Sjmcneill goto crs_cleanup; 377e4cf01d0Sjmcneill } 3780aeb60a2Sjmcneill 379e4cf01d0Sjmcneill if (mem->ar_base == le64toh(spcr->SerialPort.Address)) { 380e4cf01d0Sjmcneill prop_dictionary_set_bool(prop, 381e4cf01d0Sjmcneill "force_console", true); 382e4cf01d0Sjmcneill } 3830aeb60a2Sjmcneill 3840aeb60a2Sjmcneill crs_cleanup: 3850aeb60a2Sjmcneill acpi_resource_cleanup(&res); 3860aeb60a2Sjmcneill } 387fd3e8957Sjmcneill 388fd3e8957Sjmcneill spcr_unmap: 389fd3e8957Sjmcneill acpi_table_unmap((ACPI_TABLE_HEADER *)spcr); 390fd3e8957Sjmcneill } 391fd3e8957Sjmcneill #endif 39297d57f80Sjmcneill } 39397d57f80Sjmcneill 3940cc6a8cbSjmcneill static void 395397fdee4Sjmcneill acpi_platform_device_register_post_config(device_t self, void *aux) 396397fdee4Sjmcneill { 397397fdee4Sjmcneill if (device_is_a(self, "acpi")) { 398397fdee4Sjmcneill acpisrat_load_uvm(); 399397fdee4Sjmcneill } 400397fdee4Sjmcneill } 401397fdee4Sjmcneill 402397fdee4Sjmcneill static void 4030cc6a8cbSjmcneill acpi_platform_reset(void) 4040cc6a8cbSjmcneill { 405*07ede913Sjmcneill if (psci_available()) { 4060cc6a8cbSjmcneill psci_system_reset(); 4070cc6a8cbSjmcneill } 4080cc6a8cbSjmcneill 409*07ede913Sjmcneill #ifdef EFI_RUNTIME 410*07ede913Sjmcneill arm_efirt_reset(EFI_RESET_COLD); 411*07ede913Sjmcneill #endif 412*07ede913Sjmcneill } 413*07ede913Sjmcneill 41497d57f80Sjmcneill static u_int 41597d57f80Sjmcneill acpi_platform_uart_freq(void) 41697d57f80Sjmcneill { 41797d57f80Sjmcneill return 0; 41897d57f80Sjmcneill } 41997d57f80Sjmcneill 4208d564c5dSskrll static const struct fdt_platform acpi_platform = { 4218d564c5dSskrll .fp_devmap = acpi_platform_devmap, 4228d564c5dSskrll .fp_bootstrap = acpi_platform_bootstrap, 4238d564c5dSskrll .fp_startup = acpi_platform_startup, 4248d564c5dSskrll .fp_init_attach_args = acpi_platform_init_attach_args, 4258d564c5dSskrll .fp_device_register = acpi_platform_device_register, 426397fdee4Sjmcneill .fp_device_register_post_config = acpi_platform_device_register_post_config, 4278d564c5dSskrll .fp_reset = acpi_platform_reset, 4288d564c5dSskrll .fp_delay = gtmr_delay, 4298d564c5dSskrll .fp_uart_freq = acpi_platform_uart_freq, 43097d57f80Sjmcneill }; 43197d57f80Sjmcneill 4328d564c5dSskrll FDT_PLATFORM(acpi, "netbsd,generic-acpi", &acpi_platform); 433