Common RISC-V SEC module for RISC-V platforms.
Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
---
Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S | 438 ++++++++++++++++++++
Platform/RiscV/Universal/Sec/SecMain.c | 524 ++++++++++++++++++++++++
Platform/RiscV/Universal/Sec/SecMain.h | 57 +++
Platform/RiscV/Universal/Sec/SecMain.inf | 75 ++++
4 files changed, 1094 insertions(+)
create mode 100644 Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
create mode 100644 Platform/RiscV/Universal/Sec/SecMain.c
create mode 100644 Platform/RiscV/Universal/Sec/SecMain.h
create mode 100644 Platform/RiscV/Universal/Sec/SecMain.inf
diff --git a/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S b/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
new file mode 100644
index 00000000..18b54b84
--- /dev/null
+++ b/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
@@ -0,0 +1,438 @@
+/*
+ * Copyright (c) 2019 , Hewlett Packard Enterprise Development LP. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel@wdc.com>
+ *
+ */
+
+#include <Base.h>
+#include <RiscV.h>
+#include <sbi/riscv_asm.h>
+#include <sbi/riscv_encoding.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_trap.h>
+
+#include <SecMain.h>
+#include <sbi/SbiFirmwareContext.h>
+
+.text
+.align 3
+.global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ /*
+ * Jump to warm-boot if this is not the selected core booting,
+ */
+ csrr a6, CSR_MHARTID
+ li a5, FixedPcdGet32 (PcdBootHartId)
+ bne a6, a5, _wait_for_boot_hart
+
+ // light LED on
+ li a5, 0x54002000
+ li a4, 0xff
+ sw a4, 0x08(a5)
+ li a4, 0x11
+ sw a4, 0x0c(a5)
+
+ li ra, 0
+ call _reset_regs
+
+ /* Preload HART details
+ * s7 -> HART Count
+ * s8 -> HART Stack Size
+ */
+ li s7, FixedPcdGet32 (PcdHartCount)
+ li s8, FixedPcdGet32 (PcdOpenSbiStackSize)
+
+ /* Setup scratch space for all the HARTs*/
+ li tp, FixedPcdGet32 (PcdScratchRamBase)
+ mul a5, s7, s8
+ add tp, tp, a5
+ /* Keep a copy of tp */
+ add t3, tp, zero
+ /* Counter */
+ li t2, 1
+ /* hartid 0 is mandated by ISA */
+ li t1, 0
+_scratch_init:
+ add tp, t3, zero
+ mul a5, s8, t1
+ sub tp, tp, a5
+ li a5, SBI_SCRATCH_SIZE
+ sub tp, tp, a5
+
+ /* Initialize scratch space */
+ li a4, FixedPcdGet32 (PcdFwStartAddress)
+ li a5, FixedPcdGet32 (PcdFwEndAddress)
+ sub a5, a5, a4
+ sd a4, SBI_SCRATCH_FW_START_OFFSET(tp)
+ sd a5, SBI_SCRATCH_FW_SIZE_OFFSET(tp)
+ /* Note: fw_next_arg1() uses a0, a1, and ra */
+ call fw_next_arg1
+ sd a0, SBI_SCRATCH_NEXT_ARG1_OFFSET(tp)
+ /* Note: fw_next_addr() uses a0, a1, and ra */
+ call fw_next_addr
+ sd a0, SBI_SCRATCH_NEXT_ADDR_OFFSET(tp)
+ li a4, PRV_S
+ sd a4, SBI_SCRATCH_NEXT_MODE_OFFSET(tp)
+ la a4, _start_warm
+ sd a4, SBI_SCRATCH_WARMBOOT_ADDR_OFFSET(tp)
+ la a4, platform
+ sd a4, SBI_SCRATCH_PLATFORM_ADDR_OFFSET(tp)
+ la a4, _hartid_to_scratch
+ sd a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp)
+ sd zero, SBI_SCRATCH_TMP0_OFFSET(tp)
+#ifdef FW_OPTIONS
+ li a4, FW_OPTIONS
+ sd a4, SBI_SCRATCH_OPTIONS_OFFSET(tp)
+#else
+ sd zero, SBI_SCRATCH_OPTIONS_OFFSET(tp)
+#endif
+ add t1, t1, t2
+ blt t1, s7, _scratch_init
+
+ /* Fill-out temporary memory with 55aa*/
+ li a4, FixedPcdGet32 (PcdTemporaryRamBase)
+ li a5, FixedPcdGet32 (PcdTemporaryRamSize)
+ add a5, a4, a5
+1:
+ li a3, 0x5AA55AA55AA55AA5
+ sd a3, (a4)
+ add a4, a4, __SIZEOF_POINTER__
+ blt a4, a5, 1b
+
+ /* Update boot hart flag */
+ la a4, _boot_hart_done
+ li a5, 1
+ sd a5, (a4)
+
+ /* Wait for boot hart */
+_wait_for_boot_hart:
+ la a4, _boot_hart_done
+ ld a5, (a4)
+ /* Reduce the bus traffic so that boot hart may proceed faster */
+ nop
+ nop
+ nop
+ beqz a5, _wait_for_boot_hart
+
+_start_warm:
+ li ra, 0
+ call _reset_regs
+
+ /* Disable and clear all interrupts */
+ csrw CSR_MIE, zero
+ csrw CSR_MIP, zero
+
+ li s7, FixedPcdGet32 (PcdHartCount)
+ li s8, FixedPcdGet32 (PcdOpenSbiStackSize)
+
+ /* HART ID should be within expected limit */
+ csrr s6, CSR_MHARTID
+ bge s6, s7, _start_hang
+
+ /* find the scratch space for this hart */
+ li tp, FixedPcdGet32 (PcdScratchRamBase)
+ mul a5, s7, s8
+ add tp, tp, a5
+ mul a5, s8, s6
+ sub tp, tp, a5
+ li a5, SBI_SCRATCH_SIZE
+ sub tp, tp, a5
+
+ /* update the mscratch */
+ csrw CSR_MSCRATCH, tp
+
+ /*make room for Hart specific Firmware Context*/
+ li a5, FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE
+ sub tp, tp, a5
+
+ /* Setup stack */
+ add sp, tp, zero
+
+ /* Setup stack for the Hart executing EFI to top of temporary ram*/
+ csrr a6, CSR_MHARTID
+ li a5, FixedPcdGet32 (PcdBootHartId)
+ bne a6, a5, 1f
+
+ li a4, FixedPcdGet32(PcdTemporaryRamBase)
+ li a5, FixedPcdGet32(PcdTemporaryRamSize)
+ add sp, a4, a5
+ 1:
+
+ /* Setup trap handler */
+ la a4, _trap_handler
+ csrw CSR_MTVEC, a4
+ /* Make sure that mtvec is updated */
+ 1:
+ csrr a5, CSR_MTVEC
+ bne a4, a5, 1b
+
+ /* Call library constructors before jup to SEC core */
+ call ProcessLibraryConstructorList
+
+ /* jump to SEC Core C */
+ csrr a0, CSR_MHARTID
+ csrr a1, CSR_MSCRATCH
+ call SecCoreStartUpWithStack
+
+ /* We do not expect to reach here hence just hang */
+ j _start_hang
+
+ .align 3
+ .section .data, "aw"
+_boot_hart_done:
+ RISCV_PTR 0
+
+ .align 3
+ .section .entry, "ax", %progbits
+ .globl _hartid_to_scratch
+_hartid_to_scratch:
+ add sp, sp, -(3 * __SIZEOF_POINTER__)
+ sd s0, (sp)
+ sd s1, (__SIZEOF_POINTER__)(sp)
+ sd s2, (__SIZEOF_POINTER__ * 2)(sp)
+ /*
+ * a0 -> HART ID (passed by caller)
+ * s0 -> HART Stack Size
+ * s1 -> HART Stack End
+ * s2 -> Temporary
+ */
+ la s2, platform
+#if __riscv_xlen == 64
+ lwu s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
+ lwu s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
+#else
+ lw s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
+ lw s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
+#endif
+ mul s2, s2, s0
+ li s1, FixedPcdGet32 (PcdScratchRamBase)
+ add s1, s1, s2
+ mul s2, s0, a0
+ sub s1, s1, s2
+ li s2, SBI_SCRATCH_SIZE
+ sub a0, s1, s2
+ ld s0, (sp)
+ ld s1, (__SIZEOF_POINTER__)(sp)
+ ld s2, (__SIZEOF_POINTER__ * 2)(sp)
+ add sp, sp, (3 * __SIZEOF_POINTER__)
+ ret
+
+ .align 3
+ .section .entry, "ax", %progbits
+ .globl _start_hang
+_start_hang:
+ wfi
+ j _start_hang
+
+ .align 3
+ .section .entry, "ax", %progbits
+ .globl _trap_handler
+_trap_handler:
+ /* Swap TP and MSCRATCH */
+ csrrw tp, CSR_MSCRATCH, tp
+
+ /* Save T0 in scratch space */
+ sd t0, SBI_SCRATCH_TMP0_OFFSET(tp)
+
+ /* Check which mode we came from */
+ csrr t0, CSR_MSTATUS
+ srl t0, t0, MSTATUS_MPP_SHIFT
+ and t0, t0, PRV_M
+ xori t0, t0, PRV_M
+ beq t0, zero, _trap_handler_m_mode
+
+ /* We came from S-mode or U-mode */
+_trap_handler_s_mode:
+ /* Set T0 to original SP */
+ add t0, sp, zero
+
+ /* Setup exception stack */
+ add sp, tp, -(SBI_TRAP_REGS_SIZE)
+
+ /* Jump to code common for all modes */
+ j _trap_handler_all_mode
+
+ /* We came from M-mode */
+_trap_handler_m_mode:
+ /* Set T0 to original SP */
+ add t0, sp, zero
+
+ /* Re-use current SP as exception stack */
+ add sp, sp, -(SBI_TRAP_REGS_SIZE)
+
+_trap_handler_all_mode:
+ /* Save original SP (from T0) on stack */
+ sd t0, SBI_TRAP_REGS_OFFSET(sp)(sp)
+
+ /* Restore T0 from scratch space */
+ ld t0, SBI_SCRATCH_TMP0_OFFSET(tp)
+
+ /* Save T0 on stack */
+ sd t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
+
+ /* Swap TP and MSCRATCH */
+ csrrw tp, CSR_MSCRATCH, tp
+
+ /* Save MEPC and MSTATUS CSRs */
+ csrr t0, CSR_MEPC
+ sd t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
+ csrr t0, CSR_MSTATUS
+ sd t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
+
+ /* Save all general regisers except SP and T0 */
+ sd zero, SBI_TRAP_REGS_OFFSET(zero)(sp)
+ sd ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
+ sd gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
+ sd tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
+ sd t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
+ sd t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
+ sd s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
+ sd s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
+ sd a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
+ sd a1, SBI_TRAP_REGS_OFFSET(a1)(sp)
+ sd a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
+ sd a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
+ sd a4, SBI_TRAP_REGS_OFFSET(a4)(sp)
+ sd a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
+ sd a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
+ sd a7, SBI_TRAP_REGS_OFFSET(a7)(sp)
+ sd s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
+ sd s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
+ sd s4, SBI_TRAP_REGS_OFFSET(s4)(sp)
+ sd s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
+ sd s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
+ sd s7, SBI_TRAP_REGS_OFFSET(s7)(sp)
+ sd s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
+ sd s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
+ sd s10, SBI_TRAP_REGS_OFFSET(s10)(sp)
+ sd s11, SBI_TRAP_REGS_OFFSET(s11)(sp)
+ sd t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
+ sd t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
+ sd t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
+ sd t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
+
+ /* Call C routine */
+ add a0, sp, zero
+ csrr a1, CSR_MSCRATCH
+ call sbi_trap_handler
+
+ /* Restore all general regisers except SP and T0 */
+ ld ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
+ ld gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
+ ld tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
+ ld t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
+ ld t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
+ ld s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
+ ld s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
+ ld a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
+ ld a1, SBI_TRAP_REGS_OFFSET(a1)(sp)
+ ld a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
+ ld a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
+ ld a4, SBI_TRAP_REGS_OFFSET(a4)(sp)
+ ld a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
+ ld a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
+ ld a7, SBI_TRAP_REGS_OFFSET(a7)(sp)
+ ld s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
+ ld s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
+ ld s4, SBI_TRAP_REGS_OFFSET(s4)(sp)
+ ld s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
+ ld s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
+ ld s7, SBI_TRAP_REGS_OFFSET(s7)(sp)
+ ld s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
+ ld s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
+ ld s10, SBI_TRAP_REGS_OFFSET(s10)(sp)
+ ld s11, SBI_TRAP_REGS_OFFSET(s11)(sp)
+ ld t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
+ ld t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
+ ld t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
+ ld t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
+
+ /* Restore MEPC and MSTATUS CSRs */
+ ld t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
+ csrw CSR_MEPC, t0
+ ld t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
+ csrw CSR_MSTATUS, t0
+
+ /* Restore T0 */
+ ld t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
+
+ /* Restore SP */
+ ld sp, SBI_TRAP_REGS_OFFSET(sp)(sp)
+
+ mret
+
+ .align 3
+ .section .entry, "ax", %progbits
+ .globl _reset_regs
+_reset_regs:
+
+ /* flush the instruction cache */
+ fence.i
+ /* Reset all registers except ra, a0,a1 */
+ li sp, 0
+ li gp, 0
+ li tp, 0
+ li t0, 0
+ li t1, 0
+ li t2, 0
+ li s0, 0
+ li s1, 0
+ li a2, 0
+ li a3, 0
+ li a4, 0
+ li a5, 0
+ li a6, 0
+ li a7, 0
+ li s2, 0
+ li s3, 0
+ li s4, 0
+ li s5, 0
+ li s6, 0
+ li s7, 0
+ li s8, 0
+ li s9, 0
+ li s10, 0
+ li s11, 0
+ li t3, 0
+ li t4, 0
+ li t5, 0
+ li t6, 0
+ csrw CSR_MSCRATCH, 0
+ ret
+
+ .align 3
+ .section .entry, "ax", %progbits
+ .global fw_prev_arg1
+fw_prev_arg1:
+ /* We return previous arg1 in 'a0' */
+ add a0, zero, zero
+ ret
+
+ .align 3
+ .section .entry, "ax", %progbits
+ .global fw_next_arg1
+fw_next_arg1:
+ /* We return next arg1 in 'a0' */
+ li a0, FixedPcdGet32(PcdRiscVPeiFvBase)
+ ret
+
+ .align 3
+ .section .entry, "ax", %progbits
+ .global fw_next_addr
+fw_next_addr:
+ /* We return next address in 'a0' */
+ la a0, _jump_addr
+ ld a0, (a0)
+ ret
+
+ .align 3
+ .section .entry, "ax", %progbits
+_jump_addr:
+ RISCV_PTR SecCoreStartUpWithStack
diff --git a/Platform/RiscV/Universal/Sec/SecMain.c b/Platform/RiscV/Universal/Sec/SecMain.c
new file mode 100644
index 00000000..40b351ca
--- /dev/null
+++ b/Platform/RiscV/Universal/Sec/SecMain.c
@@ -0,0 +1,524 @@
+/** @file
+ RISC-V SEC phase module.
+
+ Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SecMain.h"
+#include <Library/SerialPortLib.h>
+#include <Library/PrintLib.h>
+#include <Library/DebugPrintErrorLevelLib.h>
+#include <sbi/sbi_hart.h>
+#include <sbi/sbi_scratch.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi.h>
+#include <sbi/sbi_init.h>
+#include <sbi/SbiFirmwareContext.h>
+
+int HartsIn = 0;
+
+EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
+ TemporaryRamMigration
+};
+
+EFI_PEI_TEMPORARY_RAM_DONE_PPI mTemporaryRamDonePpi = {
+ TemporaryRamDone
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gEfiTemporaryRamSupportPpiGuid,
+ &mTemporaryRamSupportPpi
+ },
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiTemporaryRamDonePpiGuid,
+ &mTemporaryRamDonePpi
+ },
+};
+
+/**
+ Locates a section within a series of sections
+ with the specified section type.
+
+ The Instance parameter indicates which instance of the section
+ type to return. (0 is first instance, 1 is second...)
+
+ @param[in] Sections The sections to search
+ @param[in] SizeOfSections Total size of all sections
+ @param[in] SectionType The section type to locate
+ @param[in] Instance The section instance number
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsSectionInstance (
+ IN VOID *Sections,
+ IN UINTN SizeOfSections,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN Instance,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfSections;
+ EFI_COMMON_SECTION_HEADER *Section;
+ EFI_PHYSICAL_ADDRESS EndOfSection;
+
+ //
+ // Loop through the FFS file sections within the PEI Core FFS file
+ //
+ EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
+ EndOfSections = EndOfSection + SizeOfSections;
+ for (;;) {
+ if (EndOfSection == EndOfSections) {
+ break;
+ }
+ CurrentAddress = (EndOfSection + 3) & ~(3ULL);
+ if (CurrentAddress >= EndOfSections) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+
+ Size = SECTION_SIZE (Section);
+ if (Size < sizeof (*Section)) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ EndOfSection = CurrentAddress + Size;
+ if (EndOfSection > EndOfSections) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ //
+ // Look for the requested section type
+ //
+ if (Section->Type == SectionType) {
+ if (Instance == 0) {
+ *FoundSection = Section;
+ return EFI_SUCCESS;
+ } else {
+ Instance--;
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Locates a section within a series of sections
+ with the specified section type.
+
+ @param[in] Sections The sections to search
+ @param[in] SizeOfSections Total size of all sections
+ @param[in] SectionType The section type to locate
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsSectionInSections (
+ IN VOID *Sections,
+ IN UINTN SizeOfSections,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ return FindFfsSectionInstance (
+ Sections,
+ SizeOfSections,
+ SectionType,
+ 0,
+ FoundSection
+ );
+}
+
+/**
+ Locates a FFS file with the specified file type and a section
+ within that file with the specified section type.
+
+ @param[in] Fv The firmware volume to search
+ @param[in] FileType The file type to locate
+ @param[in] SectionType The section type to locate
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsFileAndSection (
+ IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
+ IN EFI_FV_FILETYPE FileType,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
+ EFI_FFS_FILE_HEADER *File;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfFile;
+
+ if (Fv->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header signature\n", Fv));
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
+ EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
+
+ //
+ // Loop through the FFS files in the Boot Firmware Volume
+ //
+ for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
+
+ CurrentAddress = (EndOfFile + 7) & ~(7ULL);
+ if (CurrentAddress > EndOfFirmwareVolume) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+ Size = *(UINT32*) File->Size & 0xffffff;
+ if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ EndOfFile = CurrentAddress + Size;
+ if (EndOfFile > EndOfFirmwareVolume) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ //
+ // Look for the request file type
+ //
+ if (File->Type != FileType) {
+ continue;
+ }
+
+ Status = FindFfsSectionInSections (
+ (VOID*) (File + 1),
+ (UINTN) EndOfFile - (UINTN) (File + 1),
+ SectionType,
+ FoundSection
+ );
+ if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
+ return Status;
+ }
+ }
+}
+
+/**
+ Locates the PEI Core entry point address
+
+ @param[in] Fv The firmware volume to search
+ @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindPeiCoreImageBaseInFv (
+ IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
+ )
+{
+ EFI_STATUS Status;
+ EFI_COMMON_SECTION_HEADER *Section;
+
+ Status = FindFfsFileAndSection (
+ Fv,
+ EFI_FV_FILETYPE_PEI_CORE,
+ EFI_SECTION_PE32,
+ &Section
+ );
+ if (EFI_ERROR (Status)) {
+ Status = FindFfsFileAndSection (
+ Fv,
+ EFI_FV_FILETYPE_PEI_CORE,
+ EFI_SECTION_TE,
+ &Section
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n"));
+ return Status;
+ }
+ }
+ DEBUG ((DEBUG_ERROR, "PeiCoreImageBase found\n"));
+ *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
+ return EFI_SUCCESS;
+}
+
+/**
+ Locates the PEI Core entry point address
+
+ @param[in,out] Fv The firmware volume to search
+ @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+VOID
+FindPeiCoreImageBase (
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv,
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
+ )
+{
+ *PeiCoreImageBase = 0;
+
+ DEBUG ((DEBUG_INFO, "FindPeiCoreImageBaseInFv\n"));
+ FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
+}
+
+/*
+ Find and return Pei Core entry point.
+
+ It also find SEC and PEI Core file debug inforamtion. It will report them if
+ remote debug is enabled.
+
+**/
+VOID
+FindAndReportEntryPoints (
+ IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
+ OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
+
+ DEBUG ((DEBUG_INFO, "FindAndReportEntryPoints\n"));
+
+ FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
+ //
+ // Find PEI Core entry point
+ //
+ Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
+ if (EFI_ERROR(Status)) {
+ *PeiCoreEntryPoint = 0;
+ }
+ DEBUG ((DEBUG_INFO, "PeCoffLoaderGetEntryPoint success: %x\n", *PeiCoreEntryPoint));
+
+ return;
+}
+/*
+ Print out the content of firmware context.
+
+**/
+VOID
+DebutPrintFirmwareContext (
+ EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext
+ )
+{
+ DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Firmware Context at 0x%x\n", FirmwareContext));
+ DEBUG ((DEBUG_INFO, " PEI Service at 0x%x\n\n", FirmwareContext->PeiServiceTable));
+}
+
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ )
+{
+ VOID *OldHeap;
+ VOID *NewHeap;
+ VOID *OldStack;
+ VOID *NewStack;
+ struct sbi_platform *ThisSbiPlatform;
+
+ DEBUG ((DEBUG_INFO,
+ "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
+ TemporaryMemoryBase,
+ PermanentMemoryBase,
+ (UINT64)CopySize
+ ));
+
+ OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
+ NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
+
+ OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
+ NewStack = (VOID*)(UINTN)PermanentMemoryBase;
+
+ CopyMem (NewHeap, OldHeap, CopySize >> 1); // Migrate Heap
+ CopyMem (NewStack, OldStack, CopySize >> 1); // Migrate Stack
+
+ //
+ // Reset firmware context pointer
+ //
+ ThisSbiPlatform = (struct sbi_platform *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
+ ThisSbiPlatform->firmware_context += (unsigned long)((UINTN)NewStack - (UINTN)OldStack);
+ //
+ // Relocate PEI Service **
+ //
+ ((EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)ThisSbiPlatform->firmware_context)->PeiServiceTable += (unsigned long)((UINTN)NewStack - (UINTN)OldStack);
+ DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Firmware Context is relocated to 0x%x\n", ThisSbiPlatform->firmware_context));
+ DebutPrintFirmwareContext ((EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)ThisSbiPlatform->firmware_context);
+
+ register uintptr_t a0 asm ("a0") = (uintptr_t)((UINTN)NewStack - (UINTN)OldStack);
+ asm volatile ("add sp, sp, a0"::"r"(a0):);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS EFIAPI TemporaryRamDone (VOID)
+{
+ DEBUG ((DEBUG_INFO, "2nd time PEI core, temporary ram done.\n"));
+ return EFI_SUCCESS;
+}
+
+#if 1
+#define GPIO_CTRL_ADDR 0x54002000
+#define GPIO_OUTPUT_VAL 0x0C
+static volatile UINT32 * const gpio = (void *)GPIO_CTRL_ADDR;
+#define REG32(p, i) ((p)[(i)>>2])
+#endif
+
+static VOID EFIAPI PeiCore(VOID)
+{
+ EFI_SEC_PEI_HAND_OFF SecCoreData;
+ EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
+ EFI_FIRMWARE_VOLUME_HEADER *BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)FixedPcdGet32(PcdRiscVPeiFvBase);
+ EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT FirmwareContext;
+ struct sbi_platform *ThisSbiPlatform;
+ UINT32 HartId;
+
+ REG32(gpio, GPIO_OUTPUT_VAL) = 0x88;
+ FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
+
+ SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
+ SecCoreData.BootFirmwareVolumeBase = BootFv;
+ SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
+ SecCoreData.TemporaryRamBase = (VOID*)(UINT64) FixedPcdGet32(PcdTemporaryRamBase);
+ SecCoreData.TemporaryRamSize = (UINTN) FixedPcdGet32(PcdTemporaryRamSize);
+ SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
+ SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1;
+ SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + (SecCoreData.TemporaryRamSize >> 1);
+ SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;
+
+ //
+ // Print out scratch address of each hart
+ //
+ DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI scratch address for each hart:\n"));
+ for (HartId = 0; HartId < FixedPcdGet32 (PcdHartCount); HartId ++) {
+ DEBUG ((DEBUG_INFO, " Hart %d: 0x%x\n", HartId, sbi_hart_id_to_scratch(sbi_scratch_thishart_ptr(), HartId)));
+ }
+
+ //
+ // Set up OpepSBI firmware context poitner on boot hart OpenSbi scratch. Firmware context residents in stack and will be
+ // switched to memory when temporary ram migration.
+ //
+ ZeroMem ((VOID *)&FirmwareContext, sizeof (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT));
+ ThisSbiPlatform = (struct sbi_platform *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
+ if (ThisSbiPlatform->opensbi_version > OPENSBI_VERSION) {
+ DEBUG ((DEBUG_ERROR, "[OpenSBI]: OpenSBI platform table version 0x%x is newer than OpenSBI version 0x%x.\n"
+ "There maybe be some backward compatable issues.\n",
+ ThisSbiPlatform->opensbi_version,
+ OPENSBI_VERSION
+ ));
+ ASSERT(FALSE);
+ }
+ DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI platform table at address: 0x%x\nFirmware Context is located at 0x%x\n",
+ ThisSbiPlatform,
+ &FirmwareContext
+ ));
+ ThisSbiPlatform->firmware_context = (unsigned long)&FirmwareContext;
+ //
+ // Set firmware context Hart-specific pointer
+ //
+ for (HartId = 0; HartId < FixedPcdGet32 (PcdHartCount); HartId ++) {
+ FirmwareContext.HartSpecific [HartId] = \
+ (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UINT8 *)sbi_hart_id_to_scratch(sbi_scratch_thishart_ptr(), HartId) - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);
+ DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Hart %d Firmware Context Hart-specific at address: 0x%x\n",
+ HartId,
+ FirmwareContext.HartSpecific [HartId]
+ ));
+ }
+
+ //
+ // Transfer the control to the PEI core
+ //
+ (*PeiCoreEntryPoint) (&SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);
+}
+/**
+ This function initilizes hart specific information and SBI.
+ For the boot hart, it boots system through PEI core and initial SBI in the DXE IPL.
+ For others, it goes to initial SBI and halt.
+
+ the lay out of memory region for each hart is as below delineates,
+
+ _ ____
+ |----Scratch ends | |
+ | | sizeof (sbi_scratch) |
+ | _| |
+ |----Scratch buffer start s <----- *scratch |
+ |----Firmware Context Hart-specific ends _ |
+ | | |
+ | | FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE |
+ | | | PcdOpenSbiStackSize
+ | _| |
+ |----Firmware Context Hart-specific starts <----- **HartFirmwareContext |
+ |----Hart stack top _ |
+ | | |
+ | | |
+ | | Stack |
+ | | |
+ | _| ____|
+ |----Hart stack bottom
+
+**/
+VOID EFIAPI SecCoreStartUpWithStack(unsigned long hartid, struct sbi_scratch *scratch)
+{
+ EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *HartFirmwareContext;
+
+ //
+ // Setup EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC for each hart.
+ //
+ HartFirmwareContext = (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UINT8 *)scratch - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);
+ HartFirmwareContext->IsaExtensionSupported = RiscVReadMisa ();
+ HartFirmwareContext->MachineVendorId.Value64_L = RiscVReadMVendorId ();
+ HartFirmwareContext->MachineVendorId.Value64_H = 0;
+ HartFirmwareContext->MachineArchId.Value64_L = RiscVReadMArchId ();
+ HartFirmwareContext->MachineArchId.Value64_H = 0;
+ HartFirmwareContext->MachineImplId.Value64_L = RiscVReadMImplId ();
+ HartFirmwareContext->MachineImplId.Value64_H = 0;
+
+#if 0
+ while (HartsIn != hartid);
+ DEBUG ((DEBUG_INFO, "[OpenSBI]: Initial Firmware Context Hart-specific for HART ID:%d\n", hartid));
+ DEBUG ((DEBUG_INFO, " Scratch at address: 0x%x\n", scratch));
+ DEBUG ((DEBUG_INFO, " Firmware Context Hart-specific at address: 0x%x\n", HartFirmwareContext));
+ DEBUG ((DEBUG_INFO, " stack pointer at address: 0x%x\n", stack_point));
+ DEBUG ((DEBUG_INFO, " MISA: 0x%x\n", HartFirmwareContext->IsaExtensionSupported));
+ DEBUG ((DEBUG_INFO, " MVENDORID: 0x%x\n", HartFirmwareContext->MachineVendorId.Value64_L));
+ DEBUG ((DEBUG_INFO, " MARCHID: 0x%x\n", HartFirmwareContext->MachineArchId.Value64_L));
+ DEBUG ((DEBUG_INFO, " MIMPID: 0x%x\n\n", HartFirmwareContext->MachineImplId.Value64_L));
+ HartsIn ++;
+ for (;;);
+#endif
+
+ if (hartid == FixedPcdGet32(PcdBootHartId)) {
+ PeiCore();
+ }
+ sbi_init(scratch);
+}
diff --git a/Platform/RiscV/Universal/Sec/SecMain.h b/Platform/RiscV/Universal/Sec/SecMain.h
new file mode 100644
index 00000000..e7565f5e
--- /dev/null
+++ b/Platform/RiscV/Universal/Sec/SecMain.h
@@ -0,0 +1,57 @@
+/** @file
+ RISC-V SEC phase module definitions..
+
+ Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SECMAIN_H_
+#define _SECMAIN_H_
+
+#include <PiPei.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/IoLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/PeCoffGetEntryPointLib.h>
+#include <Library/PeCoffExtraActionLib.h>
+#include <Library/ExtractGuidedSectionLib.h>
+#include <Library/HobLib.h>
+#include <Ppi/TemporaryRamSupport.h>
+#include <Ppi/TemporaryRamDone.h>
+#include <Library/RiscVCpuLib.h>
+
+VOID
+SecMachineModeTrapHandler (
+ IN VOID
+ );
+
+VOID
+EFIAPI
+SecStartupPhase2 (
+ IN VOID *Context
+ );
+
+EFI_STATUS
+EFIAPI
+TemporaryRamMigration (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
+ IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
+ IN UINTN CopySize
+ );
+
+EFI_STATUS
+EFIAPI
+TemporaryRamDone (
+ VOID
+ );
+
+#endif // _SECMAIN_H_
diff --git a/Platform/RiscV/Universal/Sec/SecMain.inf b/Platform/RiscV/Universal/Sec/SecMain.inf
new file mode 100644
index 00000000..c408fc8d
--- /dev/null
+++ b/Platform/RiscV/Universal/Sec/SecMain.inf
@@ -0,0 +1,75 @@
+## @file
+# RISC-V SEC module.
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SecMain
+ FILE_GUID = df1ccef6-f301-4a63-9661-fc6030dcc880
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SecMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = RISCV64 EBC
+#
+
+[Sources]
+ SecMain.c
+
+[Sources.RISCV64]
+ Riscv64/SecEntry.s
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RiscVPkg/RiscVPkg.dec
+ Platform/RiscV/RiscVPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ BaseMemoryLib
+ PcdLib
+ DebugAgentLib
+ IoLib
+ PeCoffLib
+ PeCoffGetEntryPointLib
+ PeCoffExtraActionLib
+ ExtractGuidedSectionLib
+ RiscVCpuLib
+ PrintLib
+ SerialPortLib
+ RiscVOpensbiLib
+ OpenSbiPlatformLib # This is required library which
+ # provides platform level opensbi
+ # functions.
+
+[Ppis]
+ gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
+ gEfiTemporaryRamDonePpiGuid # PPI ALWAYS_PRODUCED
+
+[Guids]
+ gUefiRiscVMachineContextGuid
+
+[FixedPcd]
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvBase
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvSize
+
+[Pcd]
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwStartAddress
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwEndAddress
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamBase
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamSize
--
2.12.0.windows.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#47539): https://edk2.groups.io/g/devel/message/47539
Mute This Topic: https://groups.io/mt/34196353/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
On Thu, Sep 19, 2019 at 11:51:23AM +0800, Gilbert Chen wrote:
> Common RISC-V SEC module for RISC-V platforms.
If this is common to RISC-V platforms, this really should live in
edk2/RiscVPkg.
> Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> ---
> Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S | 438 ++++++++++++++++++++
> Platform/RiscV/Universal/Sec/SecMain.c | 524 ++++++++++++++++++++++++
> Platform/RiscV/Universal/Sec/SecMain.h | 57 +++
> Platform/RiscV/Universal/Sec/SecMain.inf | 75 ++++
> 4 files changed, 1094 insertions(+)
> create mode 100644 Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
> create mode 100644 Platform/RiscV/Universal/Sec/SecMain.c
> create mode 100644 Platform/RiscV/Universal/Sec/SecMain.h
> create mode 100644 Platform/RiscV/Universal/Sec/SecMain.inf
>
> diff --git a/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S b/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
> new file mode 100644
> index 00000000..18b54b84
> --- /dev/null
> +++ b/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
> @@ -0,0 +1,438 @@
> +/*
> + * Copyright (c) 2019 , Hewlett Packard Enterprise Development LP. All rights reserved.
> + *
> + * SPDX-License-Identifier: BSD-2-Clause
> + *
> + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> + *
> + * Authors:
> + * Anup Patel <anup.patel@wdc.com>
If Anup is the author, he should be indicated in the commit as the
Author.
If you further modify the patch, you can add a comment above your
signed-off-by: of the form
[Updated coding style issues.]
Signed-off-by: ...
> + *
> + */
> +
> +#include <Base.h>
> +#include <RiscV.h>
> +#include <sbi/riscv_asm.h>
> +#include <sbi/riscv_encoding.h>
> +#include <sbi/sbi_platform.h>
> +#include <sbi/sbi_scratch.h>
> +#include <sbi/sbi_trap.h>
> +
> +#include <SecMain.h>
> +#include <sbi/SbiFirmwareContext.h>
> +
> +.text
> +.align 3
> +.global ASM_PFX(_ModuleEntryPoint)
> +ASM_PFX(_ModuleEntryPoint):
> + /*
> + * Jump to warm-boot if this is not the selected core booting,
> + */
> + csrr a6, CSR_MHARTID
> + li a5, FixedPcdGet32 (PcdBootHartId)
> + bne a6, a5, _wait_for_boot_hart
We don't actually have a coding style for assembler, but I find it
really helps readability to have the arguments aligned across all
lines. Compare (for example) with OvmfPkg/Sec/X64/SecEntry.nasm.
> +
> + // light LED on
> + li a5, 0x54002000
> + li a4, 0xff
> + sw a4, 0x08(a5)
> + li a4, 0x11
> + sw a4, 0x0c(a5)
> +
> + li ra, 0
> + call _reset_regs
> +
> + /* Preload HART details
> + * s7 -> HART Count
> + * s8 -> HART Stack Size
> + */
> + li s7, FixedPcdGet32 (PcdHartCount)
> + li s8, FixedPcdGet32 (PcdOpenSbiStackSize)
> +
> + /* Setup scratch space for all the HARTs*/
> + li tp, FixedPcdGet32 (PcdScratchRamBase)
> + mul a5, s7, s8
> + add tp, tp, a5
> + /* Keep a copy of tp */
> + add t3, tp, zero
> + /* Counter */
> + li t2, 1
> + /* hartid 0 is mandated by ISA */
> + li t1, 0
> +_scratch_init:
> + add tp, t3, zero
> + mul a5, s8, t1
> + sub tp, tp, a5
> + li a5, SBI_SCRATCH_SIZE
> + sub tp, tp, a5
> +
> + /* Initialize scratch space */
> + li a4, FixedPcdGet32 (PcdFwStartAddress)
> + li a5, FixedPcdGet32 (PcdFwEndAddress)
> + sub a5, a5, a4
> + sd a4, SBI_SCRATCH_FW_START_OFFSET(tp)
> + sd a5, SBI_SCRATCH_FW_SIZE_OFFSET(tp)
Can you add a blank line here?
> + /* Note: fw_next_arg1() uses a0, a1, and ra */
> + call fw_next_arg1
> + sd a0, SBI_SCRATCH_NEXT_ARG1_OFFSET(tp)
Can you add a blank line here?
> + /* Note: fw_next_addr() uses a0, a1, and ra */
> + call fw_next_addr
Can you add a blank line here?
> + sd a0, SBI_SCRATCH_NEXT_ADDR_OFFSET(tp)
> + li a4, PRV_S
> + sd a4, SBI_SCRATCH_NEXT_MODE_OFFSET(tp)
> + la a4, _start_warm
> + sd a4, SBI_SCRATCH_WARMBOOT_ADDR_OFFSET(tp)
> + la a4, platform
> + sd a4, SBI_SCRATCH_PLATFORM_ADDR_OFFSET(tp)
> + la a4, _hartid_to_scratch
> + sd a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp)
> + sd zero, SBI_SCRATCH_TMP0_OFFSET(tp)
Can you add a blank line here?
> +#ifdef FW_OPTIONS
> + li a4, FW_OPTIONS
> + sd a4, SBI_SCRATCH_OPTIONS_OFFSET(tp)
> +#else
> + sd zero, SBI_SCRATCH_OPTIONS_OFFSET(tp)
> +#endif
Can you add a blank line here?
> + add t1, t1, t2
> + blt t1, s7, _scratch_init
> +
> + /* Fill-out temporary memory with 55aa*/
> + li a4, FixedPcdGet32 (PcdTemporaryRamBase)
> + li a5, FixedPcdGet32 (PcdTemporaryRamSize)
> + add a5, a4, a5
> +1:
> + li a3, 0x5AA55AA55AA55AA5
> + sd a3, (a4)
> + add a4, a4, __SIZEOF_POINTER__
> + blt a4, a5, 1b
> +
> + /* Update boot hart flag */
> + la a4, _boot_hart_done
> + li a5, 1
> + sd a5, (a4)
> +
> + /* Wait for boot hart */
> +_wait_for_boot_hart:
> + la a4, _boot_hart_done
> + ld a5, (a4)
> + /* Reduce the bus traffic so that boot hart may proceed faster */
> + nop
> + nop
> + nop
> + beqz a5, _wait_for_boot_hart
> +
> +_start_warm:
> + li ra, 0
> + call _reset_regs
> +
> + /* Disable and clear all interrupts */
> + csrw CSR_MIE, zero
> + csrw CSR_MIP, zero
> +
> + li s7, FixedPcdGet32 (PcdHartCount)
> + li s8, FixedPcdGet32 (PcdOpenSbiStackSize)
> +
> + /* HART ID should be within expected limit */
> + csrr s6, CSR_MHARTID
> + bge s6, s7, _start_hang
> +
> + /* find the scratch space for this hart */
> + li tp, FixedPcdGet32 (PcdScratchRamBase)
> + mul a5, s7, s8
> + add tp, tp, a5
> + mul a5, s8, s6
> + sub tp, tp, a5
> + li a5, SBI_SCRATCH_SIZE
> + sub tp, tp, a5
> +
> + /* update the mscratch */
> + csrw CSR_MSCRATCH, tp
> +
> + /*make room for Hart specific Firmware Context*/
> + li a5, FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE
> + sub tp, tp, a5
> +
> + /* Setup stack */
> + add sp, tp, zero
> +
> + /* Setup stack for the Hart executing EFI to top of temporary ram*/
> + csrr a6, CSR_MHARTID
> + li a5, FixedPcdGet32 (PcdBootHartId)
> + bne a6, a5, 1f
> +
> + li a4, FixedPcdGet32(PcdTemporaryRamBase)
> + li a5, FixedPcdGet32(PcdTemporaryRamSize)
> + add sp, a4, a5
> + 1:
> +
> + /* Setup trap handler */
> + la a4, _trap_handler
> + csrw CSR_MTVEC, a4
Can you add a blank line here?
> + /* Make sure that mtvec is updated */
> + 1:
> + csrr a5, CSR_MTVEC
> + bne a4, a5, 1b
> +
> + /* Call library constructors before jup to SEC core */
> + call ProcessLibraryConstructorList
> +
> + /* jump to SEC Core C */
> + csrr a0, CSR_MHARTID
> + csrr a1, CSR_MSCRATCH
> + call SecCoreStartUpWithStack
> +
> + /* We do not expect to reach here hence just hang */
> + j _start_hang
> +
> + .align 3
> + .section .data, "aw"
> +_boot_hart_done:
> + RISCV_PTR 0
> +
> + .align 3
> + .section .entry, "ax", %progbits
> + .globl _hartid_to_scratch
> +_hartid_to_scratch:
> + add sp, sp, -(3 * __SIZEOF_POINTER__)
> + sd s0, (sp)
> + sd s1, (__SIZEOF_POINTER__)(sp)
> + sd s2, (__SIZEOF_POINTER__ * 2)(sp)
Can you add a blank line here?
> + /*
> + * a0 -> HART ID (passed by caller)
> + * s0 -> HART Stack Size
> + * s1 -> HART Stack End
> + * s2 -> Temporary
> + */
> + la s2, platform
> +#if __riscv_xlen == 64
> + lwu s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
> + lwu s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
> +#else
> + lw s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
> + lw s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
> +#endif
> + mul s2, s2, s0
> + li s1, FixedPcdGet32 (PcdScratchRamBase)
> + add s1, s1, s2
> + mul s2, s0, a0
> + sub s1, s1, s2
> + li s2, SBI_SCRATCH_SIZE
> + sub a0, s1, s2
> + ld s0, (sp)
> + ld s1, (__SIZEOF_POINTER__)(sp)
> + ld s2, (__SIZEOF_POINTER__ * 2)(sp)
> + add sp, sp, (3 * __SIZEOF_POINTER__)
> + ret
> +
> + .align 3
> + .section .entry, "ax", %progbits
> + .globl _start_hang
> +_start_hang:
> + wfi
> + j _start_hang
> +
> + .align 3
> + .section .entry, "ax", %progbits
> + .globl _trap_handler
> +_trap_handler:
> + /* Swap TP and MSCRATCH */
> + csrrw tp, CSR_MSCRATCH, tp
> +
> + /* Save T0 in scratch space */
> + sd t0, SBI_SCRATCH_TMP0_OFFSET(tp)
> +
> + /* Check which mode we came from */
> + csrr t0, CSR_MSTATUS
> + srl t0, t0, MSTATUS_MPP_SHIFT
> + and t0, t0, PRV_M
> + xori t0, t0, PRV_M
> + beq t0, zero, _trap_handler_m_mode
> +
> + /* We came from S-mode or U-mode */
> +_trap_handler_s_mode:
> + /* Set T0 to original SP */
> + add t0, sp, zero
> +
> + /* Setup exception stack */
> + add sp, tp, -(SBI_TRAP_REGS_SIZE)
> +
> + /* Jump to code common for all modes */
> + j _trap_handler_all_mode
> +
> + /* We came from M-mode */
> +_trap_handler_m_mode:
> + /* Set T0 to original SP */
> + add t0, sp, zero
> +
> + /* Re-use current SP as exception stack */
> + add sp, sp, -(SBI_TRAP_REGS_SIZE)
> +
> +_trap_handler_all_mode:
> + /* Save original SP (from T0) on stack */
> + sd t0, SBI_TRAP_REGS_OFFSET(sp)(sp)
> +
> + /* Restore T0 from scratch space */
> + ld t0, SBI_SCRATCH_TMP0_OFFSET(tp)
> +
> + /* Save T0 on stack */
> + sd t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
> +
> + /* Swap TP and MSCRATCH */
> + csrrw tp, CSR_MSCRATCH, tp
> +
> + /* Save MEPC and MSTATUS CSRs */
> + csrr t0, CSR_MEPC
> + sd t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
> + csrr t0, CSR_MSTATUS
> + sd t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
> +
> + /* Save all general regisers except SP and T0 */
> + sd zero, SBI_TRAP_REGS_OFFSET(zero)(sp)
> + sd ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
> + sd gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
> + sd tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
> + sd t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
> + sd t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
> + sd s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
> + sd s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
> + sd a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
> + sd a1, SBI_TRAP_REGS_OFFSET(a1)(sp)
> + sd a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
> + sd a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
> + sd a4, SBI_TRAP_REGS_OFFSET(a4)(sp)
> + sd a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
> + sd a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
> + sd a7, SBI_TRAP_REGS_OFFSET(a7)(sp)
> + sd s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
> + sd s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
> + sd s4, SBI_TRAP_REGS_OFFSET(s4)(sp)
> + sd s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
> + sd s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
> + sd s7, SBI_TRAP_REGS_OFFSET(s7)(sp)
> + sd s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
> + sd s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
> + sd s10, SBI_TRAP_REGS_OFFSET(s10)(sp)
> + sd s11, SBI_TRAP_REGS_OFFSET(s11)(sp)
> + sd t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
> + sd t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
> + sd t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
> + sd t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
> +
> + /* Call C routine */
> + add a0, sp, zero
> + csrr a1, CSR_MSCRATCH
> + call sbi_trap_handler
> +
> + /* Restore all general regisers except SP and T0 */
> + ld ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
> + ld gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
> + ld tp, SBI_TRAP_REGS_OFFSET(tp)(sp)
> + ld t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
> + ld t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
> + ld s0, SBI_TRAP_REGS_OFFSET(s0)(sp)
> + ld s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
> + ld a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
> + ld a1, SBI_TRAP_REGS_OFFSET(a1)(sp)
> + ld a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
> + ld a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
> + ld a4, SBI_TRAP_REGS_OFFSET(a4)(sp)
> + ld a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
> + ld a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
> + ld a7, SBI_TRAP_REGS_OFFSET(a7)(sp)
> + ld s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
> + ld s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
> + ld s4, SBI_TRAP_REGS_OFFSET(s4)(sp)
> + ld s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
> + ld s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
> + ld s7, SBI_TRAP_REGS_OFFSET(s7)(sp)
> + ld s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
> + ld s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
> + ld s10, SBI_TRAP_REGS_OFFSET(s10)(sp)
> + ld s11, SBI_TRAP_REGS_OFFSET(s11)(sp)
> + ld t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
> + ld t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
> + ld t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
> + ld t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
> +
> + /* Restore MEPC and MSTATUS CSRs */
> + ld t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
> + csrw CSR_MEPC, t0
> + ld t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
> + csrw CSR_MSTATUS, t0
> +
> + /* Restore T0 */
> + ld t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
> +
> + /* Restore SP */
> + ld sp, SBI_TRAP_REGS_OFFSET(sp)(sp)
> +
> + mret
> +
> + .align 3
> + .section .entry, "ax", %progbits
> + .globl _reset_regs
> +_reset_regs:
> +
> + /* flush the instruction cache */
> + fence.i
> + /* Reset all registers except ra, a0,a1 */
> + li sp, 0
> + li gp, 0
> + li tp, 0
> + li t0, 0
> + li t1, 0
> + li t2, 0
> + li s0, 0
> + li s1, 0
> + li a2, 0
> + li a3, 0
> + li a4, 0
> + li a5, 0
> + li a6, 0
> + li a7, 0
> + li s2, 0
> + li s3, 0
> + li s4, 0
> + li s5, 0
> + li s6, 0
> + li s7, 0
> + li s8, 0
> + li s9, 0
> + li s10, 0
> + li s11, 0
> + li t3, 0
> + li t4, 0
> + li t5, 0
> + li t6, 0
> + csrw CSR_MSCRATCH, 0
> + ret
> +
> + .align 3
> + .section .entry, "ax", %progbits
> + .global fw_prev_arg1
> +fw_prev_arg1:
> + /* We return previous arg1 in 'a0' */
> + add a0, zero, zero
> + ret
> +
> + .align 3
> + .section .entry, "ax", %progbits
> + .global fw_next_arg1
> +fw_next_arg1:
> + /* We return next arg1 in 'a0' */
> + li a0, FixedPcdGet32(PcdRiscVPeiFvBase)
> + ret
> +
> + .align 3
> + .section .entry, "ax", %progbits
> + .global fw_next_addr
> +fw_next_addr:
> + /* We return next address in 'a0' */
> + la a0, _jump_addr
> + ld a0, (a0)
> + ret
> +
> + .align 3
> + .section .entry, "ax", %progbits
> +_jump_addr:
> + RISCV_PTR SecCoreStartUpWithStack
> diff --git a/Platform/RiscV/Universal/Sec/SecMain.c b/Platform/RiscV/Universal/Sec/SecMain.c
> new file mode 100644
> index 00000000..40b351ca
> --- /dev/null
> +++ b/Platform/RiscV/Universal/Sec/SecMain.c
> @@ -0,0 +1,524 @@
> +/** @file
> + RISC-V SEC phase module.
> +
> + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "SecMain.h"
> +#include <Library/SerialPortLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/DebugPrintErrorLevelLib.h>
> +#include <sbi/sbi_hart.h>
> +#include <sbi/sbi_scratch.h>
> +#include <sbi/sbi_platform.h>
> +#include <sbi/sbi.h>
> +#include <sbi/sbi_init.h>
Please sort includes alphabetically.
> +#include <sbi/SbiFirmwareContext.h>
> +
> +int HartsIn = 0;
UINTN?
> +
> +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
> + TemporaryRamMigration
> +};
> +
> +EFI_PEI_TEMPORARY_RAM_DONE_PPI mTemporaryRamDonePpi = {
> + TemporaryRamDone
> +};
> +
> +EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
> + {
> + EFI_PEI_PPI_DESCRIPTOR_PPI,
> + &gEfiTemporaryRamSupportPpiGuid,
> + &mTemporaryRamSupportPpi
> + },
> + {
> + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> + &gEfiTemporaryRamDonePpiGuid,
> + &mTemporaryRamDonePpi
> + },
> +};
Can the above three variables all be made STATIC?
> +
> +/**
> + Locates a section within a series of sections
> + with the specified section type.
> +
> + The Instance parameter indicates which instance of the section
> + type to return. (0 is first instance, 1 is second...)
> +
> + @param[in] Sections The sections to search
> + @param[in] SizeOfSections Total size of all sections
> + @param[in] SectionType The section type to locate
> + @param[in] Instance The section instance number
> + @param[out] FoundSection The FFS section if found
> +
> + @retval EFI_SUCCESS The file and section was found
> + @retval EFI_NOT_FOUND The file and section was not found
> + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsSectionInstance (
This is a note, not something that needs to be addressed for setting
up the -devel branch: but this function is identical to the one in
<edk2>/OvmfPkg/Sec/SecMain.c and the one in
Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
We should address this.
> + IN VOID *Sections,
> + IN UINTN SizeOfSections,
> + IN EFI_SECTION_TYPE SectionType,
> + IN UINTN Instance,
> + OUT EFI_COMMON_SECTION_HEADER **FoundSection
> + )
> +{
> + EFI_PHYSICAL_ADDRESS CurrentAddress;
> + UINT32 Size;
> + EFI_PHYSICAL_ADDRESS EndOfSections;
> + EFI_COMMON_SECTION_HEADER *Section;
> + EFI_PHYSICAL_ADDRESS EndOfSection;
> +
> + //
> + // Loop through the FFS file sections within the PEI Core FFS file
> + //
> + EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
> + EndOfSections = EndOfSection + SizeOfSections;
> + for (;;) {
> + if (EndOfSection == EndOfSections) {
> + break;
> + }
> + CurrentAddress = (EndOfSection + 3) & ~(3ULL);
> + if (CurrentAddress >= EndOfSections) {
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
> +
> + Size = SECTION_SIZE (Section);
> + if (Size < sizeof (*Section)) {
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + EndOfSection = CurrentAddress + Size;
> + if (EndOfSection > EndOfSections) {
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + //
> + // Look for the requested section type
> + //
> + if (Section->Type == SectionType) {
> + if (Instance == 0) {
> + *FoundSection = Section;
> + return EFI_SUCCESS;
> + } else {
> + Instance--;
> + }
> + }
> + }
> +
> + return EFI_NOT_FOUND;
> +}
> +
> +/**
> + Locates a section within a series of sections
> + with the specified section type.
> +
> + @param[in] Sections The sections to search
> + @param[in] SizeOfSections Total size of all sections
> + @param[in] SectionType The section type to locate
> + @param[out] FoundSection The FFS section if found
> +
> + @retval EFI_SUCCESS The file and section was found
> + @retval EFI_NOT_FOUND The file and section was not found
> + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsSectionInSections (
The same applies to this one.
> + IN VOID *Sections,
> + IN UINTN SizeOfSections,
> + IN EFI_SECTION_TYPE SectionType,
> + OUT EFI_COMMON_SECTION_HEADER **FoundSection
> + )
> +{
> + return FindFfsSectionInstance (
> + Sections,
> + SizeOfSections,
> + SectionType,
> + 0,
> + FoundSection
> + );
> +}
> +
> +/**
> + Locates a FFS file with the specified file type and a section
> + within that file with the specified section type.
> +
> + @param[in] Fv The firmware volume to search
> + @param[in] FileType The file type to locate
> + @param[in] SectionType The section type to locate
> + @param[out] FoundSection The FFS section if found
> +
> + @retval EFI_SUCCESS The file and section was found
> + @retval EFI_NOT_FOUND The file and section was not found
> + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindFfsFileAndSection (
And this one.
> + IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
> + IN EFI_FV_FILETYPE FileType,
> + IN EFI_SECTION_TYPE SectionType,
> + OUT EFI_COMMON_SECTION_HEADER **FoundSection
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS CurrentAddress;
> + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
> + EFI_FFS_FILE_HEADER *File;
> + UINT32 Size;
> + EFI_PHYSICAL_ADDRESS EndOfFile;
> +
> + if (Fv->Signature != EFI_FVH_SIGNATURE) {
> + DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header signature\n", Fv));
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
> + EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
> +
> + //
> + // Loop through the FFS files in the Boot Firmware Volume
> + //
> + for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
> +
> + CurrentAddress = (EndOfFile + 7) & ~(7ULL);
> + if (CurrentAddress > EndOfFirmwareVolume) {
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> + Size = *(UINT32*) File->Size & 0xffffff;
> + if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + EndOfFile = CurrentAddress + Size;
> + if (EndOfFile > EndOfFirmwareVolume) {
> + return EFI_VOLUME_CORRUPTED;
> + }
> +
> + //
> + // Look for the request file type
> + //
> + if (File->Type != FileType) {
> + continue;
> + }
> +
> + Status = FindFfsSectionInSections (
> + (VOID*) (File + 1),
> + (UINTN) EndOfFile - (UINTN) (File + 1),
> + SectionType,
> + FoundSection
> + );
> + if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
> + return Status;
> + }
> + }
> +}
> +
> +/**
> + Locates the PEI Core entry point address
> +
> + @param[in] Fv The firmware volume to search
> + @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
> +
> + @retval EFI_SUCCESS The file and section was found
> + @retval EFI_NOT_FOUND The file and section was not found
> + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> +
> +**/
> +EFI_STATUS
> +FindPeiCoreImageBaseInFv (
And this.
> + IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
> + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
> + )
> +{
> + EFI_STATUS Status;
> + EFI_COMMON_SECTION_HEADER *Section;
> +
> + Status = FindFfsFileAndSection (
> + Fv,
> + EFI_FV_FILETYPE_PEI_CORE,
> + EFI_SECTION_PE32,
> + &Section
> + );
> + if (EFI_ERROR (Status)) {
> + Status = FindFfsFileAndSection (
> + Fv,
> + EFI_FV_FILETYPE_PEI_CORE,
> + EFI_SECTION_TE,
> + &Section
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n"));
> + return Status;
> + }
> + }
> + DEBUG ((DEBUG_ERROR, "PeiCoreImageBase found\n"));
> + *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Locates the PEI Core entry point address
> +
> + @param[in,out] Fv The firmware volume to search
> + @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
> +
> + @retval EFI_SUCCESS The file and section was found
> + @retval EFI_NOT_FOUND The file and section was not found
> + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> +
> +**/
> +VOID
> +FindPeiCoreImageBase (
> + IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv,
> + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
> + )
> +{
> + *PeiCoreImageBase = 0;
> +
> + DEBUG ((DEBUG_INFO, "FindPeiCoreImageBaseInFv\n"));
This one is the same with S3 support ripped out, and the above line added.
Can you delete the message, or change it to something more human
friendly? I personally would interpret that as something that was
printed _from_ that function (and in that situation should be using %a
__FUNCTION__).
> + FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
> +}
> +
> +/*
> + Find and return Pei Core entry point.
> +
> + It also find SEC and PEI Core file debug inforamtion. It will report them if
> + remote debug is enabled.
> +
> +**/
> +VOID
> +FindAndReportEntryPoints (
> + IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
> + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
> + )
> +{
> + EFI_STATUS Status;
> + EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
> +
> + DEBUG ((DEBUG_INFO, "FindAndReportEntryPoints\n"));
Use %a __FUNCTION__.
> +
> + FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
> + //
> + // Find PEI Core entry point
> + //
> + Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
> + if (EFI_ERROR(Status)) {
> + *PeiCoreEntryPoint = 0;
> + }
> + DEBUG ((DEBUG_INFO, "PeCoffLoaderGetEntryPoint success: %x\n", *PeiCoreEntryPoint));
> +
> + return;
> +}
> +/*
> + Print out the content of firmware context.
> +
> +**/
> +VOID
> +DebutPrintFirmwareContext (
Debut -> Debug?
> + EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext
> + )
> +{
> + DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Firmware Context at 0x%x\n", FirmwareContext));
Please drop the [OpenSBI] prefix.
> + DEBUG ((DEBUG_INFO, " PEI Service at 0x%x\n\n", FirmwareContext->PeiServiceTable));
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +TemporaryRamMigration (
> + IN CONST EFI_PEI_SERVICES **PeiServices,
> + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
> + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
> + IN UINTN CopySize
> + )
> +{
> + VOID *OldHeap;
> + VOID *NewHeap;
> + VOID *OldStack;
> + VOID *NewStack;
> + struct sbi_platform *ThisSbiPlatform;
> +
> + DEBUG ((DEBUG_INFO,
> + "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
%a
__FUNCTION__
> + TemporaryMemoryBase,
> + PermanentMemoryBase,
> + (UINT64)CopySize
> + ));
> +
> + OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
> + NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
> +
> + OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
> + NewStack = (VOID*)(UINTN)PermanentMemoryBase;
> +
> + CopyMem (NewHeap, OldHeap, CopySize >> 1); // Migrate Heap
> + CopyMem (NewStack, OldStack, CopySize >> 1); // Migrate Stack
> +
> + //
> + // Reset firmware context pointer
> + //
> + ThisSbiPlatform = (struct sbi_platform *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
> + ThisSbiPlatform->firmware_context += (unsigned long)((UINTN)NewStack - (UINTN)OldStack);
"unsigned long" is not a type that exists in UEFI.
Please use UINTN. Applies throughout.
> + //
> + // Relocate PEI Service **
> + //
> + ((EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)ThisSbiPlatform->firmware_context)->PeiServiceTable += (unsigned long)((UINTN)NewStack - (UINTN)OldStack);
The above line is begging for a temporary pointer for the firmware_context.
> + DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Firmware Context is relocated to 0x%x\n", ThisSbiPlatform->firmware_context));
Please
> + DebutPrintFirmwareContext ((EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)ThisSbiPlatform->firmware_context);
> +
> + register uintptr_t a0 asm ("a0") = (uintptr_t)((UINTN)NewStack - (UINTN)OldStack);
> + asm volatile ("add sp, sp, a0"::"r"(a0):);
Urgh.
Is there any way this could be broken out into a separate assembler
function instead? If not, we still need to get rid of the uintptr_t:s.
> + return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS EFIAPI TemporaryRamDone (VOID)
> +{
> + DEBUG ((DEBUG_INFO, "2nd time PEI core, temporary ram done.\n"));
> + return EFI_SUCCESS;
> +}
> +
> +#if 1
Just delete the #if 1?
> +#define GPIO_CTRL_ADDR 0x54002000
> +#define GPIO_OUTPUT_VAL 0x0C
> +static volatile UINT32 * const gpio = (void *)GPIO_CTRL_ADDR;
> +#define REG32(p, i) ((p)[(i)>>2])
> +#endif
And the #endif
Moreover, please move the ADDRESS/VALUE macros to SecMain.h, and use
IoLib instead of defining your own variables and macros.
> +
> +static VOID EFIAPI PeiCore(VOID)
STATIC
Also, please follow coding style for function definition, this is
supposed to be over multiple lines.
> +{
> + EFI_SEC_PEI_HAND_OFF SecCoreData;
> + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
> + EFI_FIRMWARE_VOLUME_HEADER *BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)FixedPcdGet32(PcdRiscVPeiFvBase);
> + EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT FirmwareContext;
> + struct sbi_platform *ThisSbiPlatform;
> + UINT32 HartId;
> +
> + REG32(gpio, GPIO_OUTPUT_VAL) = 0x88;
> + FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
> +
> + SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
> + SecCoreData.BootFirmwareVolumeBase = BootFv;
> + SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
> + SecCoreData.TemporaryRamBase = (VOID*)(UINT64) FixedPcdGet32(PcdTemporaryRamBase);
> + SecCoreData.TemporaryRamSize = (UINTN) FixedPcdGet32(PcdTemporaryRamSize);
> + SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
> + SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1;
> + SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + (SecCoreData.TemporaryRamSize >> 1);
Please don't use UINT8 * to get away from pointer arithmetic. It
disguises what function is actually being performed.
(VOID *)((UINTN) ...) is a much preferred form where that level of
description is required.
> + SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;
> +
> + //
> + // Print out scratch address of each hart
> + //
> + DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI scratch address for each hart:\n"));
Please drop [OpenSBI] tag.
> + for (HartId = 0; HartId < FixedPcdGet32 (PcdHartCount); HartId ++) {
> + DEBUG ((DEBUG_INFO, " Hart %d: 0x%x\n", HartId, sbi_hart_id_to_scratch(sbi_scratch_thishart_ptr(), HartId)));
Please wrap long line.
> + }
> +
> + //
> + // Set up OpepSBI firmware context poitner on boot hart OpenSbi scratch. Firmware context residents in stack and will be
Please wrap long line.
> + // switched to memory when temporary ram migration.
> + //
> + ZeroMem ((VOID *)&FirmwareContext, sizeof (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT));
> + ThisSbiPlatform = (struct sbi_platform *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
> + if (ThisSbiPlatform->opensbi_version > OPENSBI_VERSION) {
> + DEBUG ((DEBUG_ERROR, "[OpenSBI]: OpenSBI platform table version 0x%x is newer than OpenSBI version 0x%x.\n"
> + "There maybe be some backward compatable issues.\n",
Please drop [OpenSBI] tag. Please convert the two lines to two
separate DEBUG prints.
> + ThisSbiPlatform->opensbi_version,
> + OPENSBI_VERSION
> + ));
> + ASSERT(FALSE);
> + }
> + DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI platform table at address: 0x%x\nFirmware Context is located at 0x%x\n",
Please drop [OpenSBI] tag.
> + ThisSbiPlatform,
> + &FirmwareContext
> + ));
> + ThisSbiPlatform->firmware_context = (unsigned long)&FirmwareContext;
UINTN (probably best to do a global search and replace on this).
> + //
> + // Set firmware context Hart-specific pointer
> + //
> + for (HartId = 0; HartId < FixedPcdGet32 (PcdHartCount); HartId ++) {
> + FirmwareContext.HartSpecific [HartId] = \
> + (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UINT8 *)sbi_hart_id_to_scratch(sbi_scratch_thishart_ptr(), HartId) - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);
Please don't use (UINT8 *) to get away from pointer arithmetic.
UINTN should work fine in this context.
Screaming out for a temporary variable.
> + DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Hart %d Firmware Context Hart-specific at address: 0x%x\n",
Please drop [OpenSBI] tag.
> + HartId,
> + FirmwareContext.HartSpecific [HartId]
> + ));
> + }
> +
> + //
> + // Transfer the control to the PEI core
> + //
> + (*PeiCoreEntryPoint) (&SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);
> +}
> +/**
> + This function initilizes hart specific information and SBI.
> + For the boot hart, it boots system through PEI core and initial SBI in the DXE IPL.
> + For others, it goes to initial SBI and halt.
> +
> + the lay out of memory region for each hart is as below delineates,
> +
> + _ ____
> + |----Scratch ends | |
> + | | sizeof (sbi_scratch) |
> + | _| |
> + |----Scratch buffer start s <----- *scratch |
> + |----Firmware Context Hart-specific ends _ |
> + | | |
> + | | FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE |
> + | | | PcdOpenSbiStackSize
> + | _| |
> + |----Firmware Context Hart-specific starts <----- **HartFirmwareContext |
> + |----Hart stack top _ |
> + | | |
> + | | |
> + | | Stack |
> + | | |
> + | _| ____|
> + |----Hart stack bottom
> +
> +**/
> +VOID EFIAPI SecCoreStartUpWithStack(unsigned long hartid, struct sbi_scratch *scratch)
Split up over multiple lines.
> +{
> + EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *HartFirmwareContext;
> +
> + //
> + // Setup EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC for each hart.
> + //
> + HartFirmwareContext = (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UINT8 *)scratch - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);
Please don't use UINT8 * to get away from pointer arithmetic.
In this context, UINTN should work just fine.
> + HartFirmwareContext->IsaExtensionSupported = RiscVReadMisa ();
> + HartFirmwareContext->MachineVendorId.Value64_L = RiscVReadMVendorId ();
> + HartFirmwareContext->MachineVendorId.Value64_H = 0;
> + HartFirmwareContext->MachineArchId.Value64_L = RiscVReadMArchId ();
> + HartFirmwareContext->MachineArchId.Value64_H = 0;
> + HartFirmwareContext->MachineImplId.Value64_L = RiscVReadMImplId ();
> + HartFirmwareContext->MachineImplId.Value64_H = 0;
> +
> +#if 0
Please don't leave unused code in.
If you want to keep the printouts for extreme debugging sessions,
change the loglevel to DEBUG_VERBOSE.
> + while (HartsIn != hartid);
> + DEBUG ((DEBUG_INFO, "[OpenSBI]: Initial Firmware Context Hart-specific for HART ID:%d\n", hartid));
Please drop [OpenSBI] tag.
> + DEBUG ((DEBUG_INFO, " Scratch at address: 0x%x\n", scratch));
> + DEBUG ((DEBUG_INFO, " Firmware Context Hart-specific at address: 0x%x\n", HartFirmwareContext));
> + DEBUG ((DEBUG_INFO, " stack pointer at address: 0x%x\n", stack_point));
> + DEBUG ((DEBUG_INFO, " MISA: 0x%x\n", HartFirmwareContext->IsaExtensionSupported));
> + DEBUG ((DEBUG_INFO, " MVENDORID: 0x%x\n", HartFirmwareContext->MachineVendorId.Value64_L));
> + DEBUG ((DEBUG_INFO, " MARCHID: 0x%x\n", HartFirmwareContext->MachineArchId.Value64_L));
> + DEBUG ((DEBUG_INFO, " MIMPID: 0x%x\n\n", HartFirmwareContext->MachineImplId.Value64_L));
> + HartsIn ++;
> + for (;;);
> +#endif
> +
> + if (hartid == FixedPcdGet32(PcdBootHartId)) {
> + PeiCore();
> + }
> + sbi_init(scratch);
> +}
> diff --git a/Platform/RiscV/Universal/Sec/SecMain.h b/Platform/RiscV/Universal/Sec/SecMain.h
> new file mode 100644
> index 00000000..e7565f5e
> --- /dev/null
> +++ b/Platform/RiscV/Universal/Sec/SecMain.h
> @@ -0,0 +1,57 @@
> +/** @file
> + RISC-V SEC phase module definitions..
> +
> + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _SECMAIN_H_
> +#define _SECMAIN_H_
Plese drop leading _.
> +
> +#include <PiPei.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/DebugAgentLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PeCoffLib.h>
> +#include <Library/PeCoffGetEntryPointLib.h>
> +#include <Library/PeCoffExtraActionLib.h>
> +#include <Library/ExtractGuidedSectionLib.h>
> +#include <Library/HobLib.h>
> +#include <Ppi/TemporaryRamSupport.h>
> +#include <Ppi/TemporaryRamDone.h>
> +#include <Library/RiscVCpuLib.h>
Please drop all include statements not required by this file, and add
them instead in the files that do use them.
> +
> +VOID
> +SecMachineModeTrapHandler (
> + IN VOID
> + );
> +
> +VOID
> +EFIAPI
> +SecStartupPhase2 (
> + IN VOID *Context
> + );
> +
> +EFI_STATUS
> +EFIAPI
> +TemporaryRamMigration (
> + IN CONST EFI_PEI_SERVICES **PeiServices,
> + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
> + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
> + IN UINTN CopySize
> + );
> +
> +EFI_STATUS
> +EFIAPI
> +TemporaryRamDone (
> + VOID
> + );
> +
> +#endif // _SECMAIN_H_
> diff --git a/Platform/RiscV/Universal/Sec/SecMain.inf b/Platform/RiscV/Universal/Sec/SecMain.inf
> new file mode 100644
> index 00000000..c408fc8d
> --- /dev/null
> +++ b/Platform/RiscV/Universal/Sec/SecMain.inf
> @@ -0,0 +1,75 @@
> +## @file
> +# RISC-V SEC module.
> +#
> +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
Can this be updated to a recent specification version.
> + BASE_NAME = SecMain
> + FILE_GUID = df1ccef6-f301-4a63-9661-fc6030dcc880
> + MODULE_TYPE = SEC
> + VERSION_STRING = 1.0
> + ENTRY_POINT = SecMain
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +# VALID_ARCHITECTURES = RISCV64 EBC
Pretty sure EBC is not valid here.
> +#
> +
> +[Sources]
> + SecMain.c
> +
> +[Sources.RISCV64]
> + Riscv64/SecEntry.s
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + RiscVPkg/RiscVPkg.dec
> + Platform/RiscV/RiscVPlatformPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + BaseMemoryLib
> + PcdLib
> + DebugAgentLib
> + IoLib
> + PeCoffLib
> + PeCoffGetEntryPointLib
> + PeCoffExtraActionLib
> + ExtractGuidedSectionLib
> + RiscVCpuLib
> + PrintLib
> + SerialPortLib
> + RiscVOpensbiLib
> + OpenSbiPlatformLib # This is required library which
> + # provides platform level opensbi
> + # functions.
I don't doubt it, but I can tell it's required from the fact that it
is listed. And the name itself says all of the rest. The comment is
superfluous and can be deleted.
> +
> +[Ppis]
> + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
> + gEfiTemporaryRamDonePpiGuid # PPI ALWAYS_PRODUCED
> +
> +[Guids]
> + gUefiRiscVMachineContextGuid
> +
> +[FixedPcd]
> + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvBase
> + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvSize
> +
> +[Pcd]
> + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwStartAddress
> + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwEndAddress
> + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
> + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId
> + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase
> + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize
> + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize
> + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamBase
> + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamSize
Please sort the above alphabetically (
apart from where it makes sense not to - for example
PcdFwStartAddress
before
PcdFwEndAddress
makes more sense than the other way around).
/
Leif
> --
> 2.12.0.windows.1
>
>
>
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#48392): https://edk2.groups.io/g/devel/message/48392
Mute This Topic: https://groups.io/mt/34196353/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Leif Lindholm
> Sent: Thursday, October 3, 2019 3:43 AM
> To: devel@edk2.groups.io; Chen, Gilbert <gilbert.chen@hpe.com>
> Cc: Palmer Dabbelt <palmer@sifive.com>
> Subject: Re: [edk2-devel] [plaforms/devel-riscv-v2 PATCHv2 06/14]
> RiscV/Universal: Initial version of common RISC-V SEC module
>
> On Thu, Sep 19, 2019 at 11:51:23AM +0800, Gilbert Chen wrote:
> > Common RISC-V SEC module for RISC-V platforms.
>
> If this is common to RISC-V platforms, this really should live in edk2/RiscVPkg.
Edk2/RiscVPlatformPkg is the package of SEC module now. You will see this in v3 edk2-staging patches.
>
> > Signed-off-by: Gilbert Chen <gilbert.chen@hpe.com>
> > ---
> > Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S | 438
> ++++++++++++++++++++
> > Platform/RiscV/Universal/Sec/SecMain.c | 524
> ++++++++++++++++++++++++
> > Platform/RiscV/Universal/Sec/SecMain.h | 57 +++
> > Platform/RiscV/Universal/Sec/SecMain.inf | 75 ++++
> > 4 files changed, 1094 insertions(+)
> > create mode 100644 Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
> > create mode 100644 Platform/RiscV/Universal/Sec/SecMain.c
> > create mode 100644 Platform/RiscV/Universal/Sec/SecMain.h
> > create mode 100644 Platform/RiscV/Universal/Sec/SecMain.inf
> >
> > diff --git a/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
> > b/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
> > new file mode 100644
> > index 00000000..18b54b84
> > --- /dev/null
> > +++ b/Platform/RiscV/Universal/Sec/Riscv64/SecEntry.S
> > @@ -0,0 +1,438 @@
> > +/*
> > + * Copyright (c) 2019 , Hewlett Packard Enterprise Development LP. All
> rights reserved.
> > + *
> > + * SPDX-License-Identifier: BSD-2-Clause
> > + *
> > + * Copyright (c) 2019 Western Digital Corporation or its affiliates.
> > + *
> > + * Authors:
> > + * Anup Patel <anup.patel@wdc.com>
>
> If Anup is the author, he should be indicated in the commit as the Author.
>
> If you further modify the patch, you can add a comment above your
> signed-off-by: of the form
> [Updated coding style issues.]
> Signed-off-by: ...
>
> > + *
> > + */
> > +
> > +#include <Base.h>
> > +#include <RiscV.h>
> > +#include <sbi/riscv_asm.h>
> > +#include <sbi/riscv_encoding.h>
> > +#include <sbi/sbi_platform.h>
> > +#include <sbi/sbi_scratch.h>
> > +#include <sbi/sbi_trap.h>
> > +
> > +#include <SecMain.h>
> > +#include <sbi/SbiFirmwareContext.h>
> > +
> > +.text
> > +.align 3
> > +.global ASM_PFX(_ModuleEntryPoint)
> > +ASM_PFX(_ModuleEntryPoint):
> > + /*
> > + * Jump to warm-boot if this is not the selected core booting,
> > + */
> > + csrr a6, CSR_MHARTID
> > + li a5, FixedPcdGet32 (PcdBootHartId)
> > + bne a6, a5, _wait_for_boot_hart
>
> We don't actually have a coding style for assembler, but I find it really helps
> readability to have the arguments aligned across all lines. Compare (for
> example) with OvmfPkg/Sec/X64/SecEntry.nasm.
>
> > +
> > + // light LED on
> > + li a5, 0x54002000
> > + li a4, 0xff
> > + sw a4, 0x08(a5)
> > + li a4, 0x11
> > + sw a4, 0x0c(a5)
> > +
> > + li ra, 0
> > + call _reset_regs
> > +
> > + /* Preload HART details
> > + * s7 -> HART Count
> > + * s8 -> HART Stack Size
> > + */
> > + li s7, FixedPcdGet32 (PcdHartCount) li s8, FixedPcdGet32
> > + (PcdOpenSbiStackSize)
> > +
> > + /* Setup scratch space for all the HARTs*/
> > + li tp, FixedPcdGet32 (PcdScratchRamBase)
> > + mul a5, s7, s8
> > + add tp, tp, a5
> > + /* Keep a copy of tp */
> > + add t3, tp, zero
> > + /* Counter */
> > + li t2, 1
> > + /* hartid 0 is mandated by ISA */
> > + li t1, 0
> > +_scratch_init:
> > + add tp, t3, zero
> > + mul a5, s8, t1
> > + sub tp, tp, a5
> > + li a5, SBI_SCRATCH_SIZE
> > + sub tp, tp, a5
> > +
> > + /* Initialize scratch space */
> > + li a4, FixedPcdGet32 (PcdFwStartAddress) li a5, FixedPcdGet32
> > + (PcdFwEndAddress) sub a5, a5, a4 sd a4,
> > + SBI_SCRATCH_FW_START_OFFSET(tp) sd a5,
> > + SBI_SCRATCH_FW_SIZE_OFFSET(tp)
>
> Can you add a blank line here?
>
> > + /* Note: fw_next_arg1() uses a0, a1, and ra */ call fw_next_arg1
> > + sd a0, SBI_SCRATCH_NEXT_ARG1_OFFSET(tp)
>
> Can you add a blank line here?
>
> > + /* Note: fw_next_addr() uses a0, a1, and ra */ call fw_next_addr
>
> Can you add a blank line here?
>
> > + sd a0, SBI_SCRATCH_NEXT_ADDR_OFFSET(tp) li a4, PRV_S sd a4,
> > + SBI_SCRATCH_NEXT_MODE_OFFSET(tp) la a4, _start_warm sd a4,
> > + SBI_SCRATCH_WARMBOOT_ADDR_OFFSET(tp)
> > + la a4, platform
> > + sd a4, SBI_SCRATCH_PLATFORM_ADDR_OFFSET(tp)
> > + la a4, _hartid_to_scratch
> > + sd a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp)
> > + sd zero, SBI_SCRATCH_TMP0_OFFSET(tp)
>
> Can you add a blank line here?
>
> > +#ifdef FW_OPTIONS
> > + li a4, FW_OPTIONS
> > + sd a4, SBI_SCRATCH_OPTIONS_OFFSET(tp) #else
> > + sd zero, SBI_SCRATCH_OPTIONS_OFFSET(tp) #endif
>
> Can you add a blank line here?
>
> > + add t1, t1, t2
> > + blt t1, s7, _scratch_init
> > +
> > + /* Fill-out temporary memory with 55aa*/
> > + li a4, FixedPcdGet32 (PcdTemporaryRamBase)
> > + li a5, FixedPcdGet32 (PcdTemporaryRamSize)
> > + add a5, a4, a5
> > +1:
> > + li a3, 0x5AA55AA55AA55AA5
> > + sd a3, (a4)
> > + add a4, a4, __SIZEOF_POINTER__
> > + blt a4, a5, 1b
> > +
> > + /* Update boot hart flag */
> > + la a4, _boot_hart_done
> > + li a5, 1
> > + sd a5, (a4)
> > +
> > + /* Wait for boot hart */
> > +_wait_for_boot_hart:
> > + la a4, _boot_hart_done
> > + ld a5, (a4)
> > + /* Reduce the bus traffic so that boot hart may proceed faster */
> > + nop
> > + nop
> > + nop
> > + beqz a5, _wait_for_boot_hart
> > +
> > +_start_warm:
> > + li ra, 0
> > + call _reset_regs
> > +
> > + /* Disable and clear all interrupts */ csrw CSR_MIE, zero csrw
> > + CSR_MIP, zero
> > +
> > + li s7, FixedPcdGet32 (PcdHartCount) li s8, FixedPcdGet32
> > + (PcdOpenSbiStackSize)
> > +
> > + /* HART ID should be within expected limit */ csrr s6, CSR_MHARTID
> > + bge s6, s7, _start_hang
> > +
> > + /* find the scratch space for this hart */ li tp, FixedPcdGet32
> > + (PcdScratchRamBase) mul a5, s7, s8 add tp, tp, a5 mul a5, s8, s6
> > + sub tp, tp, a5 li a5, SBI_SCRATCH_SIZE sub tp, tp, a5
> > +
> > + /* update the mscratch */
> > + csrw CSR_MSCRATCH, tp
> > +
> > + /*make room for Hart specific Firmware Context*/ li a5,
> > + FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE
> > + sub tp, tp, a5
> > +
> > + /* Setup stack */
> > + add sp, tp, zero
> > +
> > + /* Setup stack for the Hart executing EFI to top of temporary ram*/
> > + csrr a6, CSR_MHARTID li a5, FixedPcdGet32 (PcdBootHartId) bne a6,
> > + a5, 1f
> > +
> > + li a4, FixedPcdGet32(PcdTemporaryRamBase)
> > + li a5, FixedPcdGet32(PcdTemporaryRamSize)
> > + add sp, a4, a5
> > + 1:
> > +
> > + /* Setup trap handler */
> > + la a4, _trap_handler
> > + csrw CSR_MTVEC, a4
>
> Can you add a blank line here?
>
> > + /* Make sure that mtvec is updated */
> > + 1:
> > + csrr a5, CSR_MTVEC
> > + bne a4, a5, 1b
> > +
> > + /* Call library constructors before jup to SEC core */ call
> > + ProcessLibraryConstructorList
> > +
> > + /* jump to SEC Core C */
> > + csrr a0, CSR_MHARTID
> > + csrr a1, CSR_MSCRATCH
> > + call SecCoreStartUpWithStack
> > +
> > + /* We do not expect to reach here hence just hang */ j _start_hang
> > +
> > + .align 3
> > + .section .data, "aw"
> > +_boot_hart_done:
> > + RISCV_PTR 0
> > +
> > + .align 3
> > + .section .entry, "ax", %progbits
> > + .globl _hartid_to_scratch
> > +_hartid_to_scratch:
> > + add sp, sp, -(3 * __SIZEOF_POINTER__)
> > + sd s0, (sp)
> > + sd s1, (__SIZEOF_POINTER__)(sp)
> > + sd s2, (__SIZEOF_POINTER__ * 2)(sp)
>
> Can you add a blank line here?
>
> > + /*
> > + * a0 -> HART ID (passed by caller)
> > + * s0 -> HART Stack Size
> > + * s1 -> HART Stack End
> > + * s2 -> Temporary
> > + */
> > + la s2, platform
> > +#if __riscv_xlen == 64
> > + lwu s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
> > + lwu s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
> > +#else
> > + lw s0, SBI_PLATFORM_HART_STACK_SIZE_OFFSET(s2)
> > + lw s2, SBI_PLATFORM_HART_COUNT_OFFSET(s2)
> > +#endif
> > + mul s2, s2, s0
> > + li s1, FixedPcdGet32 (PcdScratchRamBase)
> > + add s1, s1, s2
> > + mul s2, s0, a0
> > + sub s1, s1, s2
> > + li s2, SBI_SCRATCH_SIZE
> > + sub a0, s1, s2
> > + ld s0, (sp)
> > + ld s1, (__SIZEOF_POINTER__)(sp)
> > + ld s2, (__SIZEOF_POINTER__ * 2)(sp)
> > + add sp, sp, (3 * __SIZEOF_POINTER__)
> > + ret
> > +
> > + .align 3
> > + .section .entry, "ax", %progbits
> > + .globl _start_hang
> > +_start_hang:
> > + wfi
> > + j _start_hang
> > +
> > + .align 3
> > + .section .entry, "ax", %progbits
> > + .globl _trap_handler
> > +_trap_handler:
> > + /* Swap TP and MSCRATCH */
> > + csrrw tp, CSR_MSCRATCH, tp
> > +
> > + /* Save T0 in scratch space */
> > + sd t0, SBI_SCRATCH_TMP0_OFFSET(tp)
> > +
> > + /* Check which mode we came from */ csrr t0, CSR_MSTATUS srl t0,
> > + t0, MSTATUS_MPP_SHIFT and t0, t0, PRV_M xori t0, t0, PRV_M beq
> > + t0, zero, _trap_handler_m_mode
> > +
> > + /* We came from S-mode or U-mode */
> > +_trap_handler_s_mode:
> > + /* Set T0 to original SP */
> > + add t0, sp, zero
> > +
> > + /* Setup exception stack */
> > + add sp, tp, -(SBI_TRAP_REGS_SIZE)
> > +
> > + /* Jump to code common for all modes */ j _trap_handler_all_mode
> > +
> > + /* We came from M-mode */
> > +_trap_handler_m_mode:
> > + /* Set T0 to original SP */
> > + add t0, sp, zero
> > +
> > + /* Re-use current SP as exception stack */ add sp, sp,
> > + -(SBI_TRAP_REGS_SIZE)
> > +
> > +_trap_handler_all_mode:
> > + /* Save original SP (from T0) on stack */
> > + sd t0, SBI_TRAP_REGS_OFFSET(sp)(sp)
> > +
> > + /* Restore T0 from scratch space */ ld t0,
> > + SBI_SCRATCH_TMP0_OFFSET(tp)
> > +
> > + /* Save T0 on stack */
> > + sd t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
> > +
> > + /* Swap TP and MSCRATCH */
> > + csrrw tp, CSR_MSCRATCH, tp
> > +
> > + /* Save MEPC and MSTATUS CSRs */
> > + csrr t0, CSR_MEPC
> > + sd t0, SBI_TRAP_REGS_OFFSET(mepc)(sp) csrr t0, CSR_MSTATUS sd t0,
> > + SBI_TRAP_REGS_OFFSET(mstatus)(sp)
> > +
> > + /* Save all general regisers except SP and T0 */ sd zero,
> > + SBI_TRAP_REGS_OFFSET(zero)(sp) sd ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
> > + sd gp, SBI_TRAP_REGS_OFFSET(gp)(sp) sd tp,
> > + SBI_TRAP_REGS_OFFSET(tp)(sp) sd t1, SBI_TRAP_REGS_OFFSET(t1)(sp)
> > + sd t2, SBI_TRAP_REGS_OFFSET(t2)(sp) sd s0,
> > + SBI_TRAP_REGS_OFFSET(s0)(sp) sd s1, SBI_TRAP_REGS_OFFSET(s1)(sp)
> > + sd a0, SBI_TRAP_REGS_OFFSET(a0)(sp) sd a1,
> > + SBI_TRAP_REGS_OFFSET(a1)(sp) sd a2, SBI_TRAP_REGS_OFFSET(a2)(sp)
> > + sd a3, SBI_TRAP_REGS_OFFSET(a3)(sp) sd a4,
> > + SBI_TRAP_REGS_OFFSET(a4)(sp) sd a5, SBI_TRAP_REGS_OFFSET(a5)(sp)
> > + sd a6, SBI_TRAP_REGS_OFFSET(a6)(sp) sd a7,
> > + SBI_TRAP_REGS_OFFSET(a7)(sp) sd s2, SBI_TRAP_REGS_OFFSET(s2)(sp)
> > + sd s3, SBI_TRAP_REGS_OFFSET(s3)(sp) sd s4,
> > + SBI_TRAP_REGS_OFFSET(s4)(sp) sd s5, SBI_TRAP_REGS_OFFSET(s5)(sp)
> > + sd s6, SBI_TRAP_REGS_OFFSET(s6)(sp) sd s7,
> > + SBI_TRAP_REGS_OFFSET(s7)(sp) sd s8, SBI_TRAP_REGS_OFFSET(s8)(sp)
> > + sd s9, SBI_TRAP_REGS_OFFSET(s9)(sp) sd s10,
> > + SBI_TRAP_REGS_OFFSET(s10)(sp) sd s11,
> SBI_TRAP_REGS_OFFSET(s11)(sp)
> > + sd t3, SBI_TRAP_REGS_OFFSET(t3)(sp) sd t4,
> > + SBI_TRAP_REGS_OFFSET(t4)(sp) sd t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
> > + sd t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
> > +
> > + /* Call C routine */
> > + add a0, sp, zero
> > + csrr a1, CSR_MSCRATCH
> > + call sbi_trap_handler
> > +
> > + /* Restore all general regisers except SP and T0 */ ld ra,
> > + SBI_TRAP_REGS_OFFSET(ra)(sp) ld gp, SBI_TRAP_REGS_OFFSET(gp)(sp)
> > + ld tp, SBI_TRAP_REGS_OFFSET(tp)(sp) ld t1,
> > + SBI_TRAP_REGS_OFFSET(t1)(sp) ld t2, SBI_TRAP_REGS_OFFSET(t2)(sp)
> > + ld s0, SBI_TRAP_REGS_OFFSET(s0)(sp) ld s1,
> > + SBI_TRAP_REGS_OFFSET(s1)(sp) ld a0, SBI_TRAP_REGS_OFFSET(a0)(sp)
> > + ld a1, SBI_TRAP_REGS_OFFSET(a1)(sp) ld a2,
> > + SBI_TRAP_REGS_OFFSET(a2)(sp) ld a3, SBI_TRAP_REGS_OFFSET(a3)(sp)
> > + ld a4, SBI_TRAP_REGS_OFFSET(a4)(sp) ld a5,
> > + SBI_TRAP_REGS_OFFSET(a5)(sp) ld a6, SBI_TRAP_REGS_OFFSET(a6)(sp)
> > + ld a7, SBI_TRAP_REGS_OFFSET(a7)(sp) ld s2,
> > + SBI_TRAP_REGS_OFFSET(s2)(sp) ld s3, SBI_TRAP_REGS_OFFSET(s3)(sp)
> > + ld s4, SBI_TRAP_REGS_OFFSET(s4)(sp) ld s5,
> > + SBI_TRAP_REGS_OFFSET(s5)(sp) ld s6, SBI_TRAP_REGS_OFFSET(s6)(sp)
> > + ld s7, SBI_TRAP_REGS_OFFSET(s7)(sp) ld s8,
> > + SBI_TRAP_REGS_OFFSET(s8)(sp) ld s9, SBI_TRAP_REGS_OFFSET(s9)(sp)
> > + ld s10, SBI_TRAP_REGS_OFFSET(s10)(sp) ld s11,
> > + SBI_TRAP_REGS_OFFSET(s11)(sp) ld t3, SBI_TRAP_REGS_OFFSET(t3)(sp)
> > + ld t4, SBI_TRAP_REGS_OFFSET(t4)(sp) ld t5,
> > + SBI_TRAP_REGS_OFFSET(t5)(sp) ld t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
> > +
> > + /* Restore MEPC and MSTATUS CSRs */ ld t0,
> > + SBI_TRAP_REGS_OFFSET(mepc)(sp) csrw CSR_MEPC, t0 ld t0,
> > + SBI_TRAP_REGS_OFFSET(mstatus)(sp) csrw CSR_MSTATUS, t0
> > +
> > + /* Restore T0 */
> > + ld t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
> > +
> > + /* Restore SP */
> > + ld sp, SBI_TRAP_REGS_OFFSET(sp)(sp)
> > +
> > + mret
> > +
> > + .align 3
> > + .section .entry, "ax", %progbits
> > + .globl _reset_regs
> > +_reset_regs:
> > +
> > + /* flush the instruction cache */
> > + fence.i
> > + /* Reset all registers except ra, a0,a1 */ li sp, 0 li gp, 0 li
> > + tp, 0 li t0, 0 li t1, 0 li t2, 0 li s0, 0 li s1, 0 li a2, 0
> > + li a3, 0 li a4, 0 li a5, 0 li a6, 0 li a7, 0 li s2, 0 li s3, 0
> > + li s4, 0 li s5, 0 li s6, 0 li s7, 0 li s8, 0 li s9, 0 li s10,
> > + 0 li s11, 0 li t3, 0 li t4, 0 li t5, 0 li t6, 0 csrw
> > + CSR_MSCRATCH, 0 ret
> > +
> > + .align 3
> > + .section .entry, "ax", %progbits
> > + .global fw_prev_arg1
> > +fw_prev_arg1:
> > + /* We return previous arg1 in 'a0' */
> > + add a0, zero, zero
> > + ret
> > +
> > + .align 3
> > + .section .entry, "ax", %progbits
> > + .global fw_next_arg1
> > +fw_next_arg1:
> > + /* We return next arg1 in 'a0' */
> > + li a0, FixedPcdGet32(PcdRiscVPeiFvBase)
> > + ret
> > +
> > + .align 3
> > + .section .entry, "ax", %progbits
> > + .global fw_next_addr
> > +fw_next_addr:
> > + /* We return next address in 'a0' */
> > + la a0, _jump_addr
> > + ld a0, (a0)
> > + ret
> > +
> > + .align 3
> > + .section .entry, "ax", %progbits
> > +_jump_addr:
> > + RISCV_PTR SecCoreStartUpWithStack
> > diff --git a/Platform/RiscV/Universal/Sec/SecMain.c
> > b/Platform/RiscV/Universal/Sec/SecMain.c
> > new file mode 100644
> > index 00000000..40b351ca
> > --- /dev/null
> > +++ b/Platform/RiscV/Universal/Sec/SecMain.c
> > @@ -0,0 +1,524 @@
> > +/** @file
> > + RISC-V SEC phase module.
> > +
> > + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > + rights reserved.<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "SecMain.h"
> > +#include <Library/SerialPortLib.h>
> > +#include <Library/PrintLib.h>
> > +#include <Library/DebugPrintErrorLevelLib.h>
> > +#include <sbi/sbi_hart.h>
> > +#include <sbi/sbi_scratch.h>
> > +#include <sbi/sbi_platform.h>
> > +#include <sbi/sbi.h>
> > +#include <sbi/sbi_init.h>
>
> Please sort includes alphabetically.
>
> > +#include <sbi/SbiFirmwareContext.h>
> > +
> > +int HartsIn = 0;
>
> UINTN?
>
> > +
> > +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi =
> {
> > + TemporaryRamMigration
> > +};
> > +
> > +EFI_PEI_TEMPORARY_RAM_DONE_PPI mTemporaryRamDonePpi = {
> > + TemporaryRamDone
> > +};
> > +
> > +EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
> > + {
> > + EFI_PEI_PPI_DESCRIPTOR_PPI,
> > + &gEfiTemporaryRamSupportPpiGuid,
> > + &mTemporaryRamSupportPpi
> > + },
> > + {
> > + (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
> > + &gEfiTemporaryRamDonePpiGuid,
> > + &mTemporaryRamDonePpi
> > + },
> > +};
>
> Can the above three variables all be made STATIC?
>
> > +
> > +/**
> > + Locates a section within a series of sections
> > + with the specified section type.
> > +
> > + The Instance parameter indicates which instance of the section
> > + type to return. (0 is first instance, 1 is second...)
> > +
> > + @param[in] Sections The sections to search
> > + @param[in] SizeOfSections Total size of all sections
> > + @param[in] SectionType The section type to locate
> > + @param[in] Instance The section instance number
> > + @param[out] FoundSection The FFS section if found
> > +
> > + @retval EFI_SUCCESS The file and section was found
> > + @retval EFI_NOT_FOUND The file and section was not found
> > + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> > +
> > +**/
> > +EFI_STATUS
> > +FindFfsSectionInstance (
>
> This is a note, not something that needs to be addressed for setting up the -
> devel branch: but this function is identical to the one in
> <edk2>/OvmfPkg/Sec/SecMain.c and the one in
> Platform/Intel/SimicsOpenBoardPkg/SecCore/SecMain.c
> We should address this.
>
> > + IN VOID *Sections,
> > + IN UINTN SizeOfSections,
> > + IN EFI_SECTION_TYPE SectionType,
> > + IN UINTN Instance,
> > + OUT EFI_COMMON_SECTION_HEADER **FoundSection
> > + )
> > +{
> > + EFI_PHYSICAL_ADDRESS CurrentAddress;
> > + UINT32 Size;
> > + EFI_PHYSICAL_ADDRESS EndOfSections;
> > + EFI_COMMON_SECTION_HEADER *Section;
> > + EFI_PHYSICAL_ADDRESS EndOfSection;
> > +
> > + //
> > + // Loop through the FFS file sections within the PEI Core FFS file
> > + // EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
> > + EndOfSections = EndOfSection + SizeOfSections; for (;;) {
> > + if (EndOfSection == EndOfSections) {
> > + break;
> > + }
> > + CurrentAddress = (EndOfSection + 3) & ~(3ULL);
> > + if (CurrentAddress >= EndOfSections) {
> > + return EFI_VOLUME_CORRUPTED;
> > + }
> > +
> > + Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
> > +
> > + Size = SECTION_SIZE (Section);
> > + if (Size < sizeof (*Section)) {
> > + return EFI_VOLUME_CORRUPTED;
> > + }
> > +
> > + EndOfSection = CurrentAddress + Size;
> > + if (EndOfSection > EndOfSections) {
> > + return EFI_VOLUME_CORRUPTED;
> > + }
> > +
> > + //
> > + // Look for the requested section type
> > + //
> > + if (Section->Type == SectionType) {
> > + if (Instance == 0) {
> > + *FoundSection = Section;
> > + return EFI_SUCCESS;
> > + } else {
> > + Instance--;
> > + }
> > + }
> > + }
> > +
> > + return EFI_NOT_FOUND;
> > +}
> > +
> > +/**
> > + Locates a section within a series of sections
> > + with the specified section type.
> > +
> > + @param[in] Sections The sections to search
> > + @param[in] SizeOfSections Total size of all sections
> > + @param[in] SectionType The section type to locate
> > + @param[out] FoundSection The FFS section if found
> > +
> > + @retval EFI_SUCCESS The file and section was found
> > + @retval EFI_NOT_FOUND The file and section was not found
> > + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> > +
> > +**/
> > +EFI_STATUS
> > +FindFfsSectionInSections (
>
> The same applies to this one.
>
> > + IN VOID *Sections,
> > + IN UINTN SizeOfSections,
> > + IN EFI_SECTION_TYPE SectionType,
> > + OUT EFI_COMMON_SECTION_HEADER **FoundSection
> > + )
> > +{
> > + return FindFfsSectionInstance (
> > + Sections,
> > + SizeOfSections,
> > + SectionType,
> > + 0,
> > + FoundSection
> > + );
> > +}
> > +
> > +/**
> > + Locates a FFS file with the specified file type and a section
> > + within that file with the specified section type.
> > +
> > + @param[in] Fv The firmware volume to search
> > + @param[in] FileType The file type to locate
> > + @param[in] SectionType The section type to locate
> > + @param[out] FoundSection The FFS section if found
> > +
> > + @retval EFI_SUCCESS The file and section was found
> > + @retval EFI_NOT_FOUND The file and section was not found
> > + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> > +
> > +**/
> > +EFI_STATUS
> > +FindFfsFileAndSection (
>
> And this one.
>
> > + IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
> > + IN EFI_FV_FILETYPE FileType,
> > + IN EFI_SECTION_TYPE SectionType,
> > + OUT EFI_COMMON_SECTION_HEADER **FoundSection
> > + )
> > +{
> > + EFI_STATUS Status;
> > + EFI_PHYSICAL_ADDRESS CurrentAddress;
> > + EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
> > + EFI_FFS_FILE_HEADER *File;
> > + UINT32 Size;
> > + EFI_PHYSICAL_ADDRESS EndOfFile;
> > +
> > + if (Fv->Signature != EFI_FVH_SIGNATURE) {
> > + DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header
> signature\n", Fv));
> > + return EFI_VOLUME_CORRUPTED;
> > + }
> > +
> > + CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
> > + EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
> > +
> > + //
> > + // Loop through the FFS files in the Boot Firmware Volume // for
> > + (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
> > +
> > + CurrentAddress = (EndOfFile + 7) & ~(7ULL);
> > + if (CurrentAddress > EndOfFirmwareVolume) {
> > + return EFI_VOLUME_CORRUPTED;
> > + }
> > +
> > + File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
> > + Size = *(UINT32*) File->Size & 0xffffff;
> > + if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
> > + return EFI_VOLUME_CORRUPTED;
> > + }
> > +
> > + EndOfFile = CurrentAddress + Size;
> > + if (EndOfFile > EndOfFirmwareVolume) {
> > + return EFI_VOLUME_CORRUPTED;
> > + }
> > +
> > + //
> > + // Look for the request file type
> > + //
> > + if (File->Type != FileType) {
> > + continue;
> > + }
> > +
> > + Status = FindFfsSectionInSections (
> > + (VOID*) (File + 1),
> > + (UINTN) EndOfFile - (UINTN) (File + 1),
> > + SectionType,
> > + FoundSection
> > + );
> > + if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
> > + return Status;
> > + }
> > + }
> > +}
> > +
> > +/**
> > + Locates the PEI Core entry point address
> > +
> > + @param[in] Fv The firmware volume to search
> > + @param[out] PeiCoreEntryPoint The entry point of the PEI Core
> > + image
> > +
> > + @retval EFI_SUCCESS The file and section was found
> > + @retval EFI_NOT_FOUND The file and section was not found
> > + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> > +
> > +**/
> > +EFI_STATUS
> > +FindPeiCoreImageBaseInFv (
>
> And this.
>
> > + IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
> > + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
> > + )
> > +{
> > + EFI_STATUS Status;
> > + EFI_COMMON_SECTION_HEADER *Section;
> > +
> > + Status = FindFfsFileAndSection (
> > + Fv,
> > + EFI_FV_FILETYPE_PEI_CORE,
> > + EFI_SECTION_PE32,
> > + &Section
> > + );
> > + if (EFI_ERROR (Status)) {
> > + Status = FindFfsFileAndSection (
> > + Fv,
> > + EFI_FV_FILETYPE_PEI_CORE,
> > + EFI_SECTION_TE,
> > + &Section
> > + );
> > + if (EFI_ERROR (Status)) {
> > + DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n"));
> > + return Status;
> > + }
> > + }
> > + DEBUG ((DEBUG_ERROR, "PeiCoreImageBase found\n"));
> > + *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
> > + return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > + Locates the PEI Core entry point address
> > +
> > + @param[in,out] Fv The firmware volume to search
> > + @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
> > +
> > + @retval EFI_SUCCESS The file and section was found
> > + @retval EFI_NOT_FOUND The file and section was not found
> > + @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
> > +
> > +**/
> > +VOID
> > +FindPeiCoreImageBase (
> > + IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv,
> > + OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
> > + )
> > +{
> > + *PeiCoreImageBase = 0;
> > +
> > + DEBUG ((DEBUG_INFO, "FindPeiCoreImageBaseInFv\n"));
>
> This one is the same with S3 support ripped out, and the above line added.
> Can you delete the message, or change it to something more human friendly?
> I personally would interpret that as something that was printed _from_ that
> function (and in that situation should be using %a __FUNCTION__).
>
> > + FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase); }
> > +
> > +/*
> > + Find and return Pei Core entry point.
> > +
> > + It also find SEC and PEI Core file debug inforamtion. It will
> > + report them if remote debug is enabled.
> > +
> > +**/
> > +VOID
> > +FindAndReportEntryPoints (
> > + IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
> > + OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
> > + )
> > +{
> > + EFI_STATUS Status;
> > + EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
> > +
> > + DEBUG ((DEBUG_INFO, "FindAndReportEntryPoints\n"));
>
> Use %a __FUNCTION__.
>
> > +
> > + FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
> > + // // Find PEI Core entry point // Status =
> > + PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase,
> > + (VOID**) PeiCoreEntryPoint); if (EFI_ERROR(Status)) {
> > + *PeiCoreEntryPoint = 0;
> > + }
> > + DEBUG ((DEBUG_INFO, "PeCoffLoaderGetEntryPoint success: %x\n",
> > + *PeiCoreEntryPoint));
> > +
> > + return;
> > +}
> > +/*
> > + Print out the content of firmware context.
> > +
> > +**/
> > +VOID
> > +DebutPrintFirmwareContext (
>
> Debut -> Debug?
>
> > + EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext
> > + )
> > +{
> > + DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Firmware Context at
> > +0x%x\n", FirmwareContext));
>
> Please drop the [OpenSBI] prefix.
>
> > + DEBUG ((DEBUG_INFO, " PEI Service at 0x%x\n\n",
> FirmwareContext->PeiServiceTable));
> > +}
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +TemporaryRamMigration (
> > + IN CONST EFI_PEI_SERVICES **PeiServices,
> > + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
> > + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
> > + IN UINTN CopySize
> > + )
> > +{
> > + VOID *OldHeap;
> > + VOID *NewHeap;
> > + VOID *OldStack;
> > + VOID *NewStack;
> > + struct sbi_platform *ThisSbiPlatform;
> > +
> > + DEBUG ((DEBUG_INFO,
> > + "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
>
> %a
> __FUNCTION__
>
> > + TemporaryMemoryBase,
> > + PermanentMemoryBase,
> > + (UINT64)CopySize
> > + ));
> > +
> > + OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
> > + NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
> > +
> > + OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
> > + NewStack = (VOID*)(UINTN)PermanentMemoryBase;
> > +
> > + CopyMem (NewHeap, OldHeap, CopySize >> 1); // Migrate Heap
> > + CopyMem (NewStack, OldStack, CopySize >> 1); // Migrate Stack
> > +
> > + //
> > + // Reset firmware context pointer
> > + //
> > + ThisSbiPlatform = (struct sbi_platform
> > + *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
> > + ThisSbiPlatform->firmware_context += (unsigned
> > + long)((UINTN)NewStack - (UINTN)OldStack);
>
> "unsigned long" is not a type that exists in UEFI.
> Please use UINTN. Applies throughout.
>
> > + //
> > + // Relocate PEI Service **
> > + //
> > + ((EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT
> > + *)ThisSbiPlatform->firmware_context)->PeiServiceTable += (unsigned
> > + long)((UINTN)NewStack - (UINTN)OldStack);
>
> The above line is begging for a temporary pointer for the firmware_context.
>
> > + DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Firmware Context is
> > + relocated to 0x%x\n", ThisSbiPlatform->firmware_context));
>
> Please
>
> > + DebutPrintFirmwareContext
> ((EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT
> > + *)ThisSbiPlatform->firmware_context);
> > +
> > + register uintptr_t a0 asm ("a0") = (uintptr_t)((UINTN)NewStack -
> > + (UINTN)OldStack); asm volatile ("add sp, sp, a0"::"r"(a0):);
>
> Urgh.
> Is there any way this could be broken out into a separate assembler function
> instead? If not, we still need to get rid of the uintptr_t:s.
>
> > + return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS EFIAPI TemporaryRamDone (VOID) {
> > + DEBUG ((DEBUG_INFO, "2nd time PEI core, temporary ram done.\n"));
> > + return EFI_SUCCESS;
> > +}
> > +
> > +#if 1
>
> Just delete the #if 1?
>
> > +#define GPIO_CTRL_ADDR 0x54002000
> > +#define GPIO_OUTPUT_VAL 0x0C
> > +static volatile UINT32 * const gpio = (void *)GPIO_CTRL_ADDR;
> > +#define REG32(p, i) ((p)[(i)>>2])
> > +#endif
>
> And the #endif
>
> Moreover, please move the ADDRESS/VALUE macros to SecMain.h, and use
> IoLib instead of defining your own variables and macros.
>
> > +
> > +static VOID EFIAPI PeiCore(VOID)
>
> STATIC
> Also, please follow coding style for function definition, this is supposed to be
> over multiple lines.
>
> > +{
> > + EFI_SEC_PEI_HAND_OFF SecCoreData;
> > + EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
> > + EFI_FIRMWARE_VOLUME_HEADER *BootFv =
> (EFI_FIRMWARE_VOLUME_HEADER
> > +*)FixedPcdGet32(PcdRiscVPeiFvBase);
> > + EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT FirmwareContext;
> > + struct sbi_platform *ThisSbiPlatform;
> > + UINT32 HartId;
> > +
> > + REG32(gpio, GPIO_OUTPUT_VAL) = 0x88; FindAndReportEntryPoints
> > + (&BootFv, &PeiCoreEntryPoint);
> > +
> > + SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
> > + SecCoreData.BootFirmwareVolumeBase = BootFv;
> > + SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
> > + SecCoreData.TemporaryRamBase = (VOID*)(UINT64)
> FixedPcdGet32(PcdTemporaryRamBase);
> > + SecCoreData.TemporaryRamSize = (UINTN)
> FixedPcdGet32(PcdTemporaryRamSize);
> > + SecCoreData.PeiTemporaryRamBase =
> SecCoreData.TemporaryRamBase;
> > + SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize
> >> 1;
> > + SecCoreData.StackBase = (UINT8
> *)SecCoreData.TemporaryRamBase + (SecCoreData.TemporaryRamSize >>
> 1);
>
> Please don't use UINT8 * to get away from pointer arithmetic. It disguises
> what function is actually being performed.
> (VOID *)((UINTN) ...) is a much preferred form where that level of
> description is required.
>
> > + SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;
> > +
> > + //
> > + // Print out scratch address of each hart // DEBUG ((DEBUG_INFO,
> > + "[OpenSBI]: OpenSBI scratch address for each hart:\n"));
>
> Please drop [OpenSBI] tag.
>
> > + for (HartId = 0; HartId < FixedPcdGet32 (PcdHartCount); HartId ++) {
> > + DEBUG ((DEBUG_INFO, " Hart %d: 0x%x\n", HartId,
> sbi_hart_id_to_scratch(sbi_scratch_thishart_ptr(), HartId)));
>
> Please wrap long line.
>
> > + }
> > +
> > + //
> > + // Set up OpepSBI firmware context poitner on boot hart OpenSbi
> > + scratch. Firmware context residents in stack and will be
>
> Please wrap long line.
>
> > + // switched to memory when temporary ram migration.
> > + //
> > + ZeroMem ((VOID *)&FirmwareContext, sizeof
> > + (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT));
> > + ThisSbiPlatform = (struct sbi_platform
> > + *)sbi_platform_ptr(sbi_scratch_thishart_ptr());
> > + if (ThisSbiPlatform->opensbi_version > OPENSBI_VERSION) {
> > + DEBUG ((DEBUG_ERROR, "[OpenSBI]: OpenSBI platform table version
> 0x%x is newer than OpenSBI version 0x%x.\n"
> > + "There maybe be some backward compatable
> > + issues.\n",
>
> Please drop [OpenSBI] tag. Please convert the two lines to two separate
> DEBUG prints.
>
> > + ThisSbiPlatform->opensbi_version,
> > + OPENSBI_VERSION
> > + ));
> > + ASSERT(FALSE);
> > + }
> > + DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI platform table at address:
> > + 0x%x\nFirmware Context is located at 0x%x\n",
>
> Please drop [OpenSBI] tag.
>
> > + ThisSbiPlatform,
> > + &FirmwareContext
> > + ));
> > + ThisSbiPlatform->firmware_context = (unsigned
> > + long)&FirmwareContext;
>
> UINTN (probably best to do a global search and replace on this).
>
> > + //
> > + // Set firmware context Hart-specific pointer // for (HartId = 0;
> > + HartId < FixedPcdGet32 (PcdHartCount); HartId ++) {
> > + FirmwareContext.HartSpecific [HartId] = \
> > + (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UINT8
> > + *)sbi_hart_id_to_scratch(sbi_scratch_thishart_ptr(), HartId) -
> > + FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);
>
> Please don't use (UINT8 *) to get away from pointer arithmetic.
> UINTN should work fine in this context.
>
> Screaming out for a temporary variable.
>
> > + DEBUG ((DEBUG_INFO, "[OpenSBI]: OpenSBI Hart %d Firmware
> Context
> > + Hart-specific at address: 0x%x\n",
>
> Please drop [OpenSBI] tag.
>
> > + HartId,
> > + FirmwareContext.HartSpecific [HartId]
> > + ));
> > + }
> > +
> > + //
> > + // Transfer the control to the PEI core
> > + //
> > + (*PeiCoreEntryPoint) (&SecCoreData, (EFI_PEI_PPI_DESCRIPTOR
> > +*)&mPrivateDispatchTable); }
> > +/**
> > + This function initilizes hart specific information and SBI.
> > + For the boot hart, it boots system through PEI core and initial SBI in the
> DXE IPL.
> > + For others, it goes to initial SBI and halt.
> > +
> > + the lay out of memory region for each hart is as below delineates,
> > +
> > + _ ____
> > + |----Scratch ends | |
> > + | | sizeof (sbi_scratch) |
> > + | _| |
> > + |----Scratch buffer start s <----- *scratch |
> > + |----Firmware Context Hart-specific ends _ |
> > + | | |
> > + | | FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE
> |
> > + | | | PcdOpenSbiStackSize
> > + | _| |
> > + |----Firmware Context Hart-specific starts <-----
> **HartFirmwareContext |
> > + |----Hart stack top _ |
> > + | | |
> > + | | |
> > + | | Stack |
> > + | | |
> > + | _| ____|
> > + |----Hart stack bottom
> > +
> > +**/
> > +VOID EFIAPI SecCoreStartUpWithStack(unsigned long hartid, struct
> > +sbi_scratch *scratch)
>
> Split up over multiple lines.
>
> > +{
> > + EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
> *HartFirmwareContext;
> > +
> > + //
> > + // Setup EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC for each hart.
> > + //
> > + HartFirmwareContext =
> (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC
> > + *)((UINT8 *)scratch - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE);
>
> Please don't use UINT8 * to get away from pointer arithmetic.
> In this context, UINTN should work just fine.
>
> > + HartFirmwareContext->IsaExtensionSupported = RiscVReadMisa ();
> > + HartFirmwareContext->MachineVendorId.Value64_L =
> RiscVReadMVendorId
> > + (); HartFirmwareContext->MachineVendorId.Value64_H = 0;
> > + HartFirmwareContext->MachineArchId.Value64_L = RiscVReadMArchId
> ();
> > + HartFirmwareContext->MachineArchId.Value64_H = 0;
> > + HartFirmwareContext->MachineImplId.Value64_L = RiscVReadMImplId ();
> > + HartFirmwareContext->MachineImplId.Value64_H = 0;
> > +
> > +#if 0
>
> Please don't leave unused code in.
> If you want to keep the printouts for extreme debugging sessions, change
> the loglevel to DEBUG_VERBOSE.
>
> > + while (HartsIn != hartid);
> > + DEBUG ((DEBUG_INFO, "[OpenSBI]: Initial Firmware Context
> > + Hart-specific for HART ID:%d\n", hartid));
>
> Please drop [OpenSBI] tag.
>
> > + DEBUG ((DEBUG_INFO, " Scratch at address: 0x%x\n", scratch));
> > + DEBUG ((DEBUG_INFO, " Firmware Context Hart-specific at address:
> 0x%x\n", HartFirmwareContext));
> > + DEBUG ((DEBUG_INFO, " stack pointer at address: 0x%x\n",
> stack_point));
> > + DEBUG ((DEBUG_INFO, " MISA: 0x%x\n",
> HartFirmwareContext->IsaExtensionSupported));
> > + DEBUG ((DEBUG_INFO, " MVENDORID: 0x%x\n",
> HartFirmwareContext->MachineVendorId.Value64_L));
> > + DEBUG ((DEBUG_INFO, " MARCHID: 0x%x\n",
> HartFirmwareContext->MachineArchId.Value64_L));
> > + DEBUG ((DEBUG_INFO, " MIMPID: 0x%x\n\n",
> HartFirmwareContext->MachineImplId.Value64_L));
> > + HartsIn ++;
> > + for (;;);
> > +#endif
> > +
> > + if (hartid == FixedPcdGet32(PcdBootHartId)) {
> > + PeiCore();
> > + }
> > + sbi_init(scratch);
> > +}
> > diff --git a/Platform/RiscV/Universal/Sec/SecMain.h
> > b/Platform/RiscV/Universal/Sec/SecMain.h
> > new file mode 100644
> > index 00000000..e7565f5e
> > --- /dev/null
> > +++ b/Platform/RiscV/Universal/Sec/SecMain.h
> > @@ -0,0 +1,57 @@
> > +/** @file
> > + RISC-V SEC phase module definitions..
> > +
> > + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > + rights reserved.<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef _SECMAIN_H_
> > +#define _SECMAIN_H_
>
> Plese drop leading _.
>
> > +
> > +#include <PiPei.h>
> > +#include <Library/PeimEntryPoint.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/PeiServicesLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/DebugAgentLib.h>
> > +#include <Library/IoLib.h>
> > +#include <Library/PeCoffLib.h>
> > +#include <Library/PeCoffGetEntryPointLib.h>
> > +#include <Library/PeCoffExtraActionLib.h> #include
> > +<Library/ExtractGuidedSectionLib.h>
> > +#include <Library/HobLib.h>
> > +#include <Ppi/TemporaryRamSupport.h>
> > +#include <Ppi/TemporaryRamDone.h>
> > +#include <Library/RiscVCpuLib.h>
>
> Please drop all include statements not required by this file, and add them
> instead in the files that do use them.
>
> > +
> > +VOID
> > +SecMachineModeTrapHandler (
> > + IN VOID
> > + );
> > +
> > +VOID
> > +EFIAPI
> > +SecStartupPhase2 (
> > + IN VOID *Context
> > + );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +TemporaryRamMigration (
> > + IN CONST EFI_PEI_SERVICES **PeiServices,
> > + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
> > + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
> > + IN UINTN CopySize
> > + );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +TemporaryRamDone (
> > + VOID
> > + );
> > +
> > +#endif // _SECMAIN_H_
> > diff --git a/Platform/RiscV/Universal/Sec/SecMain.inf
> > b/Platform/RiscV/Universal/Sec/SecMain.inf
> > new file mode 100644
> > index 00000000..c408fc8d
> > --- /dev/null
> > +++ b/Platform/RiscV/Universal/Sec/SecMain.inf
> > @@ -0,0 +1,75 @@
> > +## @file
> > +# RISC-V SEC module.
> > +#
> > +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All
> > +rights reserved.<BR> # # SPDX-License-Identifier:
> > +BSD-2-Clause-Patent # ##
> > +
> > +[Defines]
> > + INF_VERSION = 0x00010005
>
> Can this be updated to a recent specification version.
>
> > + BASE_NAME = SecMain
> > + FILE_GUID = df1ccef6-f301-4a63-9661-fc6030dcc880
> > + MODULE_TYPE = SEC
> > + VERSION_STRING = 1.0
> > + ENTRY_POINT = SecMain
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build tools.
> > +#
> > +# VALID_ARCHITECTURES = RISCV64 EBC
>
> Pretty sure EBC is not valid here.
>
> > +#
> > +
> > +[Sources]
> > + SecMain.c
> > +
> > +[Sources.RISCV64]
> > + Riscv64/SecEntry.s
> > +
> > +[Packages]
> > + MdePkg/MdePkg.dec
> > + MdeModulePkg/MdeModulePkg.dec
> > + RiscVPkg/RiscVPkg.dec
> > + Platform/RiscV/RiscVPlatformPkg.dec
> > +
> > +[LibraryClasses]
> > + BaseLib
> > + DebugLib
> > + BaseMemoryLib
> > + PcdLib
> > + DebugAgentLib
> > + IoLib
> > + PeCoffLib
> > + PeCoffGetEntryPointLib
> > + PeCoffExtraActionLib
> > + ExtractGuidedSectionLib
> > + RiscVCpuLib
> > + PrintLib
> > + SerialPortLib
> > + RiscVOpensbiLib
> > + OpenSbiPlatformLib # This is required library which
> > + # provides platform level opensbi
> > + # functions.
>
> I don't doubt it, but I can tell it's required from the fact that it is listed. And
> the name itself says all of the rest. The comment is superfluous and can be
> deleted.
>
> > +
> > +[Ppis]
> > + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
> > + gEfiTemporaryRamDonePpiGuid # PPI ALWAYS_PRODUCED
> > +
> > +[Guids]
> > + gUefiRiscVMachineContextGuid
> > +
> > +[FixedPcd]
> > + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvBase
> > + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvSize
> > +
> > +[Pcd]
> > + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwStartAddress
> > + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFwEndAddress
> > + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
> > + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId
> > + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase
> > + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize
> > + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize
> > + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamBase
> > + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamSize
>
> Please sort the above alphabetically (
> apart from where it makes sense not to - for example PcdFwStartAddress
> before PcdFwEndAddress makes more sense than the other way around).
>
> /
> Leif
>
> > --
> > 2.12.0.windows.1
> >
> >
> >
> >
>
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#49014): https://edk2.groups.io/g/devel/message/49014
Mute This Topic: https://groups.io/mt/34196353/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2026 Red Hat, Inc.