From bb950bd77046528f2b1da75b604ee89a15ca4f74 Mon Sep 17 00:00:00 2001 From: Matheus Pecoraro Date: Tue, 16 Jul 2024 19:40:13 -0300 Subject: [PATCH] x86_64/amd64: ACPI support for the AMD64 BSP - Implements necessary ACPICA OS Services Layer interfaces; - Retrieve the RSDP from the FreeBSD Bootloader for amd64 or from multiboot2 for amd64efi; - Add ACPI initialization routine; - Use ACPI in bsp_reset. --- bsps/x86_64/amd64/acpi/acpi.c | 70 ++++++ bsps/x86_64/amd64/acpi/osl/osl_environment.c | 60 ++++++ bsps/x86_64/amd64/acpi/osl/osl_hardware.c | 97 +++++++++ bsps/x86_64/amd64/acpi/osl/osl_interrupts.c | 57 +++++ bsps/x86_64/amd64/acpi/osl/osl_memory.c | 132 ++++++++++++ bsps/x86_64/amd64/acpi/osl/osl_tables.c | 61 ++++++ bsps/x86_64/amd64/include/acpi/acpi.h | 47 ++++ .../include/acpi/acpica/platform/acrtems.h | 50 +++++ bsps/x86_64/amd64/include/freebsd_loader.h | 44 ++++ bsps/x86_64/amd64/start/bspreset.c | 12 +- bsps/x86_64/amd64/start/freebsd_loader.c | 200 ++++++++++++++++++ bsps/x86_64/amd64/start/multiboot2.c | 14 ++ bsps/x86_64/amd64/start/start.S | 22 +- .../cpu/x86_64/include/rtems/score/cpu_asm.h | 28 +++ spec/build/bsps/x86_64/amd64/bspamd64.yml | 1 + spec/build/bsps/x86_64/amd64/grp.yml | 2 + spec/build/bsps/x86_64/amd64/obj.yml | 14 +- 17 files changed, 907 insertions(+), 4 deletions(-) create mode 100644 bsps/x86_64/amd64/acpi/acpi.c create mode 100644 bsps/x86_64/amd64/acpi/osl/osl_environment.c create mode 100644 bsps/x86_64/amd64/acpi/osl/osl_hardware.c create mode 100644 bsps/x86_64/amd64/acpi/osl/osl_interrupts.c create mode 100644 bsps/x86_64/amd64/acpi/osl/osl_memory.c create mode 100644 bsps/x86_64/amd64/acpi/osl/osl_tables.c create mode 100644 bsps/x86_64/amd64/include/acpi/acpi.h create mode 100644 bsps/x86_64/amd64/include/acpi/acpica/platform/acrtems.h create mode 100644 bsps/x86_64/amd64/include/freebsd_loader.h create mode 100644 bsps/x86_64/amd64/start/freebsd_loader.c diff --git a/bsps/x86_64/amd64/acpi/acpi.c b/bsps/x86_64/amd64/acpi/acpi.c new file mode 100644 index 0000000000..f7700b302f --- /dev/null +++ b/bsps/x86_64/amd64/acpi/acpi.c @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsX8664AMD64 + * + * @ingroup RTEMSBSPsX8664AMD64EFI + * + * @brief ACPI implementation + */ + +/* + * Copyright (C) 2024 Matheus Pecoraro + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +uint64_t acpi_rsdp_addr = 0; + +static void initialize_acpi(void) +{ + ACPI_STATUS status; + status = AcpiInitializeSubsystem(); + assert(status == (AE_OK)); + + status = AcpiInitializeTables(NULL, ACPI_MAX_INIT_TABLES, FALSE); + assert(status == (AE_OK)); + + status = AcpiLoadTables(); + assert(status == (AE_OK)); + + /* System Control Interrupts not supported */ + status = AcpiEnableSubsystem(ACPI_NO_HANDLER_INIT); + assert(status == (AE_OK)); + + /* General Purpose Events not supported */ + status = AcpiInitializeObjects(ACPI_NO_EVENT_INIT); + assert(status == (AE_OK)); +} + +RTEMS_SYSINIT_ITEM( + initialize_acpi, + RTEMS_SYSINIT_DEVICE_DRIVERS, + RTEMS_SYSINIT_ORDER_MIDDLE +); diff --git a/bsps/x86_64/amd64/acpi/osl/osl_environment.c b/bsps/x86_64/amd64/acpi/osl/osl_environment.c new file mode 100644 index 0000000000..1a2a3c6d93 --- /dev/null +++ b/bsps/x86_64/amd64/acpi/osl/osl_environment.c @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsX8664AMD64 + * + * @ingroup RTEMSBSPsX8664AMD64EFI + * + * @brief ACPICA OS Services Layer interfaces + */ + +/* + * Copyright (C) 2024 Matheus Pecoraro + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +ACPI_STATUS AcpiOsInitialize(void) +{ + return (AE_OK); +} + +ACPI_STATUS AcpiOsTerminate(void) +{ + return (AE_OK); +} + +ACPI_STATUS AcpiOsPredefinedOverride( + const ACPI_PREDEFINED_NAMES* InitVal, + ACPI_STRING* NewVal +) +{ + if (InitVal == NULL || NewVal == NULL) { + return (AE_BAD_PARAMETER); + } + + return (AE_OK); +} diff --git a/bsps/x86_64/amd64/acpi/osl/osl_hardware.c b/bsps/x86_64/amd64/acpi/osl/osl_hardware.c new file mode 100644 index 0000000000..788beb6383 --- /dev/null +++ b/bsps/x86_64/amd64/acpi/osl/osl_hardware.c @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsX8664AMD64 + * + * @ingroup RTEMSBSPsX8664AMD64EFI + * + * @brief ACPICA OS Services Layer interfaces + */ + +/* + * Copyright (C) 2024 Matheus Pecoraro + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +ACPI_STATUS AcpiOsReadPort(ACPI_IO_ADDRESS InPort, UINT32* Value, UINT32 Width) +{ + switch (Width) { + case 8: + *Value = inport_byte((uint16_t) InPort); + break; + case 16: + *Value = inport_word((uint16_t) InPort); + break; + case 32: + *Value = inport_long((uint16_t) InPort); + break; + default: + return (AE_BAD_PARAMETER); + } + + return (AE_OK); +} + +ACPI_STATUS AcpiOsWritePort(ACPI_IO_ADDRESS OutPort, UINT32 Value, UINT32 Width) +{ + switch (Width) { + case 8: + outport_byte((uint16_t) OutPort, (uint8_t) Value); + break; + case 16: + outport_word((uint16_t) OutPort, (uint16_t) Value); + break; + case 32: + outport_long((uint16_t) OutPort, Value); + break; + default: + return (AE_BAD_PARAMETER); + } + + return (AE_OK); +} + +ACPI_STATUS AcpiOsReadPciConfiguration( + ACPI_PCI_ID *PciId, + UINT32 Register, + UINT64 *Value, + UINT32 Width +) +{ + return (AE_SUPPORT); +} + +ACPI_STATUS AcpiOsWritePciConfiguration( + ACPI_PCI_ID *PciId, + UINT32 Register, + UINT64 Value, + UINT32 Width +) +{ + return (AE_SUPPORT); +} diff --git a/bsps/x86_64/amd64/acpi/osl/osl_interrupts.c b/bsps/x86_64/amd64/acpi/osl/osl_interrupts.c new file mode 100644 index 0000000000..42416a895a --- /dev/null +++ b/bsps/x86_64/amd64/acpi/osl/osl_interrupts.c @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsX8664AMD64 + * + * @ingroup RTEMSBSPsX8664AMD64EFI + * + * @brief ACPICA OS Services Layer interfaces + */ + +/* + * Copyright (C) 2024 Matheus Pecoraro + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +ACPI_STATUS AcpiOsInstallInterruptHandler( + UINT32 InterruptNumber, + ACPI_OSD_HANDLER ServiceRoutine, + void* Context +) +{ + /* TODO: We currently don't have I/O APIC support implemented */ + return (AE_SUPPORT); +} + +ACPI_STATUS AcpiOsRemoveInterruptHandler( + UINT32 InterruptNumber, + ACPI_OSD_HANDLER ServiceRoutine +) +{ + /* TODO: We currently don't have I/O APIC support implemented */ + return (AE_SUPPORT); +} diff --git a/bsps/x86_64/amd64/acpi/osl/osl_memory.c b/bsps/x86_64/amd64/acpi/osl/osl_memory.c new file mode 100644 index 0000000000..7fed648e01 --- /dev/null +++ b/bsps/x86_64/amd64/acpi/osl/osl_memory.c @@ -0,0 +1,132 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsX8664AMD64 + * + * @ingroup RTEMSBSPsX8664AMD64EFI + * + * @brief ACPICA OS Services Layer interfaces + */ + +/* + * Copyright (C) 2024 Matheus Pecoraro + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include + +void* AcpiOsAllocate(ACPI_SIZE Size) +{ + return malloc(Size); +} + +void AcpiOsFree(void* Memory) +{ + free(Memory); +} + +void* AcpiOsMapMemory(ACPI_PHYSICAL_ADDRESS PhysicalAddress, ACPI_SIZE Length) +{ + /* We have an identity map set up, simply return the address */ + return (void*) PhysicalAddress; +} + +void AcpiOsUnmapMemory(void* LogicalAddress, ACPI_SIZE Length) +{ + /* We have an identity map set up, do nothing */ + return; +} + +ACPI_STATUS AcpiOsGetPhysicalAddress( + void* LogicalAddress, + ACPI_PHYSICAL_ADDRESS* PhysicalAddress +) +{ + /* We have an identity map set up, simply return the address */ + *PhysicalAddress = (uint64_t) LogicalAddress; + return (AE_OK); +} + +BOOLEAN AcpiOsReadable(void* Pointer, ACPI_SIZE Length) +{ + return (TRUE); +} + +BOOLEAN AcpiOsWritable(void* Pointer, ACPI_SIZE Length) +{ + return (TRUE); +} + +ACPI_STATUS AcpiOsReadMemory( + ACPI_PHYSICAL_ADDRESS Address, + UINT64* Value, + UINT32 Width +) +{ + /* We have an identity map set up, simply use the physical address */ + switch (Width) { + case 8: + *Value = *(volatile uint8_t*) Address; + break; + case 16: + *Value = *(volatile uint16_t*) Address; + break; + case 32: + *Value = *(volatile uint32_t*) Address; + break; + case 64: + *Value = *(volatile uint64_t*) Address; + break; + } + + return (AE_OK); +} + +ACPI_STATUS AcpiOsWriteMemory( + ACPI_PHYSICAL_ADDRESS Address, + UINT64 Value, + UINT32 Width +) +{ + /* We have an identity map set up, simply use the physical address */ + switch (Width) { + case 8: + *(volatile uint8_t*) Address = (uint8_t) Value; + break; + case 16: + *(volatile uint16_t*) Address = (uint16_t) Value; + break; + case 32: + *(volatile uint32_t*) Address = (uint32_t) Value; + break; + case 64: + *(volatile uint64_t*) Address = (uint64_t) Value; + break; + } + + return (AE_OK); +} diff --git a/bsps/x86_64/amd64/acpi/osl/osl_tables.c b/bsps/x86_64/amd64/acpi/osl/osl_tables.c new file mode 100644 index 0000000000..102cc252c5 --- /dev/null +++ b/bsps/x86_64/amd64/acpi/osl/osl_tables.c @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsX8664AMD64 + * + * @ingroup RTEMSBSPsX8664AMD64EFI + * + * @brief ACPICA OS Services Layer interfaces + */ + +/* + * Copyright (C) 2024 Matheus Pecoraro + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +ACPI_PHYSICAL_ADDRESS AcpiOsGetRootPointer(void) +{ + return acpi_rsdp_addr; +} + +ACPI_STATUS AcpiOsTableOverride( + ACPI_TABLE_HEADER* ExistingTable, + ACPI_TABLE_HEADER** NewTable +) +{ + return (AE_SUPPORT); +} + +ACPI_STATUS AcpiOsPhysicalTableOverride( + ACPI_TABLE_HEADER* ExistingTable, + ACPI_PHYSICAL_ADDRESS* NewAddress, + UINT32* NewTableLength +) +{ + return (AE_SUPPORT); +} \ No newline at end of file diff --git a/bsps/x86_64/amd64/include/acpi/acpi.h b/bsps/x86_64/amd64/include/acpi/acpi.h new file mode 100644 index 0000000000..980d84a5e3 --- /dev/null +++ b/bsps/x86_64/amd64/include/acpi/acpi.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsX8664AMD64 + * + * @ingroup RTEMSBSPsX8664AMD64EFI + * + * @brief ACPI header file + */ + +/* + * Copyright (C) 2024 Matheus Pecoraro + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _AMD64_ACPI_H_ +#define _AMD64_ACPI_H_ + +#include + +#define ACPI_MAX_INIT_TABLES 16 + +extern uint64_t acpi_rsdp_addr; + +#endif /* _AMD64_ACPI_H_ */ diff --git a/bsps/x86_64/amd64/include/acpi/acpica/platform/acrtems.h b/bsps/x86_64/amd64/include/acpi/acpica/platform/acrtems.h new file mode 100644 index 0000000000..bda332ddc1 --- /dev/null +++ b/bsps/x86_64/amd64/include/acpi/acpica/platform/acrtems.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2024 Matheus Pecoraro + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ACRTEMS_H__ +#define __ACRTEMS_H__ + +#include + +#define ACPI_MACHINE_WIDTH 64 + +#define COMPILER_DEPENDENT_INT64 int64_t +#define COMPILER_DEPENDENT_UINT64 uint64_t + +#define ACPI_UINTPTR_T uintptr_t + +#define ACPI_TO_INTEGER(p) ((uintptr_t)(p)) +#define ACPI_OFFSET(d, f) __offsetof(d, f) + +#define ACPI_USE_DO_WHILE_0 +#define ACPI_USE_LOCAL_CACHE +#define ACPI_USE_NATIVE_DIVIDE +#define ACPI_USE_NATIVE_MATH64 +#define ACPI_USE_SYSTEM_CLIBRARY +#define ACPI_USE_STANDARD_HEADERS + +#endif /* __ACRTEMS_H__ */ diff --git a/bsps/x86_64/amd64/include/freebsd_loader.h b/bsps/x86_64/amd64/include/freebsd_loader.h new file mode 100644 index 0000000000..8daa127049 --- /dev/null +++ b/bsps/x86_64/amd64/include/freebsd_loader.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsX8664AMD64 + * + * @brief Routines for parsing information passed by the FreeBSD bootloader + */ + +/* + * Copyright (C) 2024 Matheus Pecoraro + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _AMD64_FREEBSD_LOADER_H +#define _AMD64_FREEBSD_LOADER_H + +#include + +/* Will be called by start.S */ +void retrieve_info_from_freebsd_loader(uint32_t modules_metadata_addr); + +#endif /* _AMD64_FREEBSD_LOADER_H */ diff --git a/bsps/x86_64/amd64/start/bspreset.c b/bsps/x86_64/amd64/start/bspreset.c index 92d411e4cf..bc8a84f311 100644 --- a/bsps/x86_64/amd64/start/bspreset.c +++ b/bsps/x86_64/amd64/start/bspreset.c @@ -5,6 +5,8 @@ * * @ingroup RTEMSBSPsX8664AMD64 * + * @ingroup RTEMSBSPsX8664AMD64EFI + * * @brief BSP reset code */ @@ -33,13 +35,21 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include #include #define KEYBOARD_CONTROLLER_PORT 0x64 #define PULSE_RESET_LINE 0xFE -/* TODO: Update this method once APICA is implemented */ void bsp_reset(void) { + ACPI_STATUS status = AcpiEnterSleepStatePrep(ACPI_STATE_S5); + + if (status == AE_OK) { + amd64_disable_interrupts(); + AcpiEnterSleepState(ACPI_STATE_S5); + } + + /* Should be unreachable. As a fallback try the keyboard controller method */ outport_byte(KEYBOARD_CONTROLLER_PORT, PULSE_RESET_LINE); } diff --git a/bsps/x86_64/amd64/start/freebsd_loader.c b/bsps/x86_64/amd64/start/freebsd_loader.c new file mode 100644 index 0000000000..beab98cfd2 --- /dev/null +++ b/bsps/x86_64/amd64/start/freebsd_loader.c @@ -0,0 +1,200 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSBSPsX8664AMD64 + * + * @brief Routines for parsing information passed by the FreeBSD bootloader + */ + +/* + * Copyright (C) 2024 Matheus Pecoraro + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include + +#define MODINFO_NAME 0x0001 /* Name of module (string) */ +#define MODINFO_TYPE 0x0002 /* Type of module (string) */ + +#define MODINFOMD_ENVP 0x0006 /* env variables (envp[]) */ +#define MODINFO_METADATA 0x8000 /* Module-specfic */ + +static char* modules_metadata = NULL; + +/** + * Retrieves the handle to the metadata of the module. + * + * This routine was taken from sys/kern/subr_module.c in the FreeBSD source code + * and modified for readability and coding convention purposes. + * + * Copyright (c) 1998 Michael Smith + * All rights reserved. + * Copyright (c) 2020 NetApp Inc. + * Copyright (c) 2020 Klara Inc. + */ +static const char* modules_metadata_search_by_type(const char* type) +{ + if (modules_metadata != NULL) { + const char* curr_addr = modules_metadata; + const char* last_name = NULL; + + for (;;) { + int next; + uint32_t* hdr = (uint32_t*) curr_addr; + + if (hdr[0] == 0 && hdr[1] == 0) { + break; + } + + /* Remember the start of each record */ + if (hdr[0] == MODINFO_NAME) { + last_name = curr_addr; + } + + /* Search for a MODINFO_TYPE field */ + if ((hdr[0] == MODINFO_TYPE) && + !strcmp(type, curr_addr + sizeof(uint32_t) * 2)) + { + return last_name; + } + + /* Skip to next field */ + next = sizeof(uint32_t) * 2 + hdr[1]; + next = roundup(next, sizeof(u_long)); + curr_addr += next; + } + } + + return NULL; +} + +/** + * Given a module metadata handle return the specified attribute + * + * This routine was taken from sys/kern/subr_module.c in the FreeBSD source code + * and modified for readability and coding convention purposes. + * + * Copyright (c) 1998 Michael Smith + * All rights reserved. + * Copyright (c) 2020 NetApp Inc. + * Copyright (c) 2020 Klara Inc. + */ +static const char* module_metadata_search_info(const char* mod, int info) +{ + const char* curr_addr; + uint32_t type = 0; + + if (mod == NULL) { + return (NULL); + } + + curr_addr = mod; + for (;;) { + uint32_t *hdr; + int next; + + hdr = (uint32_t*) curr_addr; + + /* End of module data? */ + if (hdr[0] == 0 && hdr[1] == 0) { + break; + } + + /* + * We give up once we've looped back to what we were looking at + * first - this should normally be a MODINFO_NAME field. + */ + if (type == 0) { + type = hdr[0]; + } + else if (hdr[0] == type) { + break; + } + + /* + * Attribute match? Return pointer to data. + * Consumer may safely assume that size value precedes data. + */ + if (hdr[0] == info) + return(curr_addr + (sizeof(uint32_t) * 2)); + + /* Skip to next field */ + next = sizeof(uint32_t) * 2 + hdr[1]; + next = roundup(next, sizeof(u_long)); + curr_addr += next; + } + + return NULL; +} + +static const char* get_static_env(const char* envp, const char* name) +{ + size_t name_len = strlen(name); + + while (*envp != '\0') { + if (strncmp(envp, name, name_len) == 0 && envp[name_len] == '=') { + return envp + name_len + 1; + } + + while (*envp != '\0') { + envp++; + } + envp++; + } + + return NULL; +} + +void retrieve_info_from_freebsd_loader(uint32_t modules_metadata_addr) +{ + const char* kernel_mod = NULL; + const char* envp = NULL; + const char* rsdp_str = NULL; + long rsdp_addr = 0; + + modules_metadata = (char*) ((uint64_t) modules_metadata_addr); + + kernel_mod = modules_metadata_search_by_type("elf kernel"); + if (kernel_mod == NULL) { + kernel_mod = modules_metadata_search_by_type("elf64 kernel"); + } + + envp = module_metadata_search_info(kernel_mod, MODINFO_METADATA | MODINFOMD_ENVP); + if (envp != NULL) { + envp = (char*) *((uint64_t*) envp); + } + + rsdp_str = get_static_env(envp, "acpi.rsdp"); + if (rsdp_str != NULL) { + char* end_ptr; + rsdp_addr = strtol(rsdp_str, &end_ptr, 16); + acpi_rsdp_addr = rsdp_addr; + } +} diff --git a/bsps/x86_64/amd64/start/multiboot2.c b/bsps/x86_64/amd64/start/multiboot2.c index 1c9fe6c74f..3162319dc7 100644 --- a/bsps/x86_64/amd64/start/multiboot2.c +++ b/bsps/x86_64/amd64/start/multiboot2.c @@ -33,6 +33,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -115,6 +116,19 @@ process_multiboot2_info() fbtag->common.framebuffer_pitch, fbtag->common.framebuffer_bpp, fbtag->common.framebuffer_type); break; + case MULTIBOOT_TAG_TYPE_ACPI_OLD: + if (acpi_rsdp_addr != 0) { + break; + } + struct multiboot_tag_new_acpi* rsdp_old_tag = (struct multiboot_tag_new_acpi*) tag; + printf("Multiboot2: ACPI 1.0 RSDP address: %p\n", rsdp_old_tag->rsdp); + acpi_rsdp_addr = (uint64_t) rsdp_old_tag->rsdp; + break; + case MULTIBOOT_TAG_TYPE_ACPI_NEW: + struct multiboot_tag_new_acpi* rsdp_new_tag = (struct multiboot_tag_new_acpi*) tag; + printf("Multiboot2: ACPI 2.0 RSDP address: %p\n", rsdp_new_tag->rsdp); + acpi_rsdp_addr = (uint64_t) rsdp_new_tag->rsdp; + break; #ifdef BSP_USE_EFI_BOOT_SERVICES case MULTIBOOT_TAG_TYPE_EFI64: printf("EFI64 system table @ 0x%llx\n", ((struct multiboot_tag_efi64 *) tag)->pointer); diff --git a/bsps/x86_64/amd64/start/start.S b/bsps/x86_64/amd64/start/start.S index adb3672d5b..c6ad69f524 100644 --- a/bsps/x86_64/amd64/start/start.S +++ b/bsps/x86_64/amd64/start/start.S @@ -39,6 +39,7 @@ .type _start, @function _start: .cfi_startproc + movq %rsp, %rbp /* * _ISR_Stack_area_end is aligned to CPU_INTERRUPT_STACK_ALIGNMENT (64 bits) * by compiler directive at /cpukit/include/rtems/confdefs/percpu.h @@ -46,6 +47,22 @@ _start: * instruction will decrement the %rsp and then save the value of %rip */ movabsq $_ISR_Stack_area_end, %rsp + +#ifndef BSP_MULTIBOOT_SUPPORT + /** + * The FreeBSD bootloader gives us control with the following stack: + * 0(%rsp) = 32 bit return address (cannot be used) + * 4(%rsp) = 32 bit modulep + * 8(%rsp) = 32 bit kernend + * + * We will extract the necessary info set up by the FreeBSD bootloader + * before dynamic memory is set up since it is stored in memory after + * the kernel + */ + movl 4(%rbp), %edi + call retrieve_info_from_freebsd_loader +#endif + .cfi_def_cfa_offset 16 xorl %edi, %edi #ifdef BSP_MULTIBOOT_SUPPORT @@ -96,8 +113,9 @@ info_requests_start: #else .long 0 #endif - /* padding to 8 byte tags allignment */ - .long 0 + .long MULTIBOOT_TAG_TYPE_ACPI_OLD + .long MULTIBOOT_TAG_TYPE_ACPI_NEW + .long 0 info_requests_end: /* header end*/ .short MULTIBOOT_HEADER_TAG_END diff --git a/cpukit/score/cpu/x86_64/include/rtems/score/cpu_asm.h b/cpukit/score/cpu/x86_64/include/rtems/score/cpu_asm.h index 10e0887cb9..896a258493 100644 --- a/cpukit/score/cpu/x86_64/include/rtems/score/cpu_asm.h +++ b/cpukit/score/cpu/x86_64/include/rtems/score/cpu_asm.h @@ -40,11 +40,39 @@ static inline uint8_t inport_byte(uint16_t port) return ret; } +static inline uint16_t inport_word(uint16_t port) +{ + uint16_t ret; + __asm__ volatile ( "inw %1, %0" + : "=a" (ret) + : "Nd" (port) ); + return ret; +} + +static inline uint32_t inport_long(uint16_t port) +{ + uint32_t ret; + __asm__ volatile ( "inl %1, %0" + : "=a" (ret) + : "Nd" (port) ); + return ret; +} + static inline void outport_byte(uint16_t port, uint8_t val) { __asm__ volatile ( "outb %0, %1" : : "a" (val), "Nd" (port) ); } +static inline void outport_word(uint16_t port, uint16_t val) +{ + __asm__ volatile ( "outw %0, %1" : : "a" (val), "Nd" (port) ); +} + +static inline void outport_long(uint16_t port, uint32_t val) +{ + __asm__ volatile ( "outl %0, %1" : : "a" (val), "Nd" (port) ); +} + static inline uint16_t amd64_get_cs(void) { uint16_t segment = 0; diff --git a/spec/build/bsps/x86_64/amd64/bspamd64.yml b/spec/build/bsps/x86_64/amd64/bspamd64.yml index eefe8c4230..b8d3f0fc66 100644 --- a/spec/build/bsps/x86_64/amd64/bspamd64.yml +++ b/spec/build/bsps/x86_64/amd64/bspamd64.yml @@ -18,4 +18,5 @@ links: source: - bsps/x86_64/amd64/clock/clock.c - bsps/x86_64/amd64/console/console.c +- bsps/x86_64/amd64/start/freebsd_loader.c type: build diff --git a/spec/build/bsps/x86_64/amd64/grp.yml b/spec/build/bsps/x86_64/amd64/grp.yml index c5f54b94f1..0cab2c2526 100644 --- a/spec/build/bsps/x86_64/amd64/grp.yml +++ b/spec/build/bsps/x86_64/amd64/grp.yml @@ -24,6 +24,8 @@ links: uid: ../../objirq - role: build-dependency uid: ../../objmem +- role: build-dependency + uid: ../../objacpi - role: build-dependency uid: ../../bspopts type: build diff --git a/spec/build/bsps/x86_64/amd64/obj.yml b/spec/build/bsps/x86_64/amd64/obj.yml index bbddbc2b63..dd8c8094ed 100644 --- a/spec/build/bsps/x86_64/amd64/obj.yml +++ b/spec/build/bsps/x86_64/amd64/obj.yml @@ -10,11 +10,17 @@ includes: [] install: - destination: ${BSP_INCLUDEDIR} source: - - bsps/x86_64/amd64/include/apic.h - bsps/x86_64/amd64/include/bsp.h - bsps/x86_64/amd64/include/clock.h + - bsps/x86_64/amd64/include/freebsd_loader.h - bsps/x86_64/amd64/include/pic.h - bsps/x86_64/amd64/include/start.h +- destination: ${BSP_INCLUDEDIR}/acpi + source: + - bsps/x86_64/amd64/include/acpi/acpi.h +- destination: ${BSP_INCLUDEDIR}/acpi/acpica/platform + source: + - bsps/x86_64/amd64/include/acpi/acpica/platform/acrtems.h - destination: ${BSP_LIBDIR} source: - bsps/x86_64/amd64/start/linkcmds @@ -29,6 +35,12 @@ source: - bsps/shared/start/bspfatal-default.c - bsps/shared/start/gettargethash-default.c - bsps/shared/start/sbrk.c +- bsps/x86_64/amd64/acpi/acpi.c +- bsps/x86_64/amd64/acpi/osl/osl_environment.c +- bsps/x86_64/amd64/acpi/osl/osl_hardware.c +- bsps/x86_64/amd64/acpi/osl/osl_interrupts.c +- bsps/x86_64/amd64/acpi/osl/osl_memory.c +- bsps/x86_64/amd64/acpi/osl/osl_tables.c - bsps/x86_64/amd64/interrupts/idt.c - bsps/x86_64/amd64/interrupts/isr_handler.S - bsps/x86_64/amd64/interrupts/pic.c