From 17f0f4b68fae98bccf5012ca8c3dba3c353ca555 Mon Sep 17 00:00:00 2001 From: milek7 Date: Thu, 31 Mar 2022 02:11:15 +0200 Subject: [PATCH] arm64: Discover UART device from ACPI. Change-Id: I4e97b05dcfcaf6abddff81fbbf676c38fe337775 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5271 Tested-by: Commit checker robot Reviewed-by: Adrien Destugues --- headers/private/kernel/acpi.h | 37 +++++++++++++ .../kernel/boot/platform/efi/arch_acpi.h | 15 ++++++ src/system/boot/platform/efi/acpi.cpp | 8 +++ .../boot/platform/efi/arch/arm64/Jamfile | 5 +- .../platform/efi/arch/arm64/arch_acpi.cpp | 52 +++++++++++++++++++ src/system/boot/platform/efi/dtb.cpp | 3 -- 6 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 headers/private/kernel/boot/platform/efi/arch_acpi.h create mode 100644 src/system/boot/platform/efi/arch/arm64/arch_acpi.cpp diff --git a/headers/private/kernel/acpi.h b/headers/private/kernel/acpi.h index fc1cc285eb..1c0a5b4c04 100644 --- a/headers/private/kernel/acpi.h +++ b/headers/private/kernel/acpi.h @@ -10,6 +10,7 @@ #define ACPI_RSDT_SIGNATURE "RSDT" #define ACPI_XSDT_SIGNATURE "XSDT" #define ACPI_MADT_SIGNATURE "APIC" +#define ACPI_SPCR_SIGNATURE "SPCR" #define ACPI_LOCAL_APIC_ENABLED 0x01 @@ -202,5 +203,41 @@ typedef struct acpi_local_x2_apic_nmi { uint8 reserved3; /* reserved (must be set to zero) */ } _PACKED acpi_local_x2_apic_nmi; +typedef struct acpi_gas { + uint8 address_space_id; + uint8 bit_width; + uint8 bit_offset; + uint8 access_size; + uint64 address; +} _PACKED acpi_gas; + +typedef struct acpi_spcr { + acpi_descriptor_header header; + uint32 interface_type; + acpi_gas base_address; + uint8 interrupt_type; + uint8 irq; + uint32 gisv; + uint8 baud; + uint8 parity; + uint8 stop_bits; + uint8 flow_control; + uint8 terminal_type; + uint8 language; + uint16 pci_device_id; + uint16 pci_vendor_id; + uint8 pci_bus_num; + uint8 pci_vendor_num; + uint8 pci_function_num; + uint32 pci_flags; + uint8 pci_segment; + uint32 clock; +} _PACKED acpi_spcr; + +enum { + ACPI_SPCR_INTERFACE_TYPE_16550 = 0, + ACPI_SPCR_INTERFACE_TYPE_PL011 = 3, +}; + #endif /* _KERNEL_ACPI_H */ diff --git a/headers/private/kernel/boot/platform/efi/arch_acpi.h b/headers/private/kernel/boot/platform/efi/arch_acpi.h new file mode 100644 index 0000000000..0e65acc4a4 --- /dev/null +++ b/headers/private/kernel/boot/platform/efi/arch_acpi.h @@ -0,0 +1,15 @@ +/* + * Copyright 2021 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef KERNEL_BOOT_PLATFORM_EFI_ARCH_ACPI_H +#define KERNEL_BOOT_PLATFORM_EFI_ARCH_ACPI_H + + +#include + + +void arch_handle_acpi(void); + + +#endif /* KERNEL_BOOT_PLATFORM_EFI_ARCH_ACPI_H */ diff --git a/src/system/boot/platform/efi/acpi.cpp b/src/system/boot/platform/efi/acpi.cpp index ae8b165c6d..8ad6252b78 100644 --- a/src/system/boot/platform/efi/acpi.cpp +++ b/src/system/boot/platform/efi/acpi.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -195,6 +196,12 @@ acpi_find_table(const char* signature) } +void __attribute__((weak)) +arch_handle_acpi() +{ +} + + void acpi_init() { @@ -213,6 +220,7 @@ acpi_init() if (rsdp != NULL && acpi_check_rsdt(rsdp) == B_OK) { gKernelArgs.arch_args.acpi_root = rsdp; + arch_handle_acpi(); break; } } diff --git a/src/system/boot/platform/efi/arch/arm64/Jamfile b/src/system/boot/platform/efi/arch/arm64/Jamfile index 06db6b312d..292fdef6a5 100644 --- a/src/system/boot/platform/efi/arch/arm64/Jamfile +++ b/src/system/boot/platform/efi/arch/arm64/Jamfile @@ -24,12 +24,13 @@ for platform in [ MultiBootSubDirSetup efi ] { exceptions.S cache.S relocation_func.cpp + arch_acpi.cpp + arch_cache.cpp + arch_dtb.cpp arch_mmu.cpp arch_smp.cpp arch_start.cpp arch_timer.cpp - arch_cache.cpp - arch_dtb.cpp ; BootMergeObject boot_platform_efi_arm64.o : diff --git a/src/system/boot/platform/efi/arch/arm64/arch_acpi.cpp b/src/system/boot/platform/efi/arch/arm64/arch_acpi.cpp new file mode 100644 index 0000000000..f6ead5dfe9 --- /dev/null +++ b/src/system/boot/platform/efi/arch/arm64/arch_acpi.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2019-2022 Haiku, Inc. All rights reserved. + * Released under the terms of the MIT License. + */ + +#include "string.h" + +#include +#include +#include + +#include "serial.h" +#include "acpi.h" + +#include +#include + + +static void arch_acpi_get_uart_pl011(const uart_info &uart) +{ + static char sUART[sizeof(ArchUARTPL011)]; + gUART = new(sUART) ArchUARTPL011(uart.regs.start, + uart.clock != 0 ? uart.clock : 0x16e3600); +} + + +void +arch_handle_acpi() +{ + acpi_spcr *spcr = (acpi_spcr*)acpi_find_table(ACPI_SPCR_SIGNATURE); + if (spcr != NULL) { + uart_info &uart = gKernelArgs.arch_args.uart; + + if (spcr->interface_type == ACPI_SPCR_INTERFACE_TYPE_PL011) { + strcpy(uart.kind, UART_KIND_PL011); + } else if (spcr->interface_type == ACPI_SPCR_INTERFACE_TYPE_16550) { + strcpy(uart.kind, UART_KIND_8250); + } + + uart.regs.start = spcr->base_address.address; + uart.regs.size = B_PAGE_SIZE; + uart.irq = spcr->gisv; + uart.clock = spcr->clock; + + if (spcr->interface_type == ACPI_SPCR_INTERFACE_TYPE_PL011) { + arch_acpi_get_uart_pl011(uart); + } + + dprintf("discovered uart from acpi: base=%lx, irq=%u, clock=%lu\n", + uart.regs.start, uart.irq, uart.clock); + } +} diff --git a/src/system/boot/platform/efi/dtb.cpp b/src/system/boot/platform/efi/dtb.cpp index 07bd3ba78c..0d4f853d8a 100644 --- a/src/system/boot/platform/efi/dtb.cpp +++ b/src/system/boot/platform/efi/dtb.cpp @@ -564,9 +564,6 @@ dtb_init() efi_configuration_table *table = kSystemTable->ConfigurationTable; size_t entries = kSystemTable->NumberOfTableEntries; - // Ensure uart is empty before we scan for one - memset(&gKernelArgs.arch_args.uart, 0, sizeof(uart_info)); - INFO("Probing for device trees from UEFI...\n"); // Try to find an FDT