* [PATCH 56/79] RISC-V/PlatformPkg: Updates for the latest OpenSBI [not found] <20220108044518.16375-1-abner.chang@hpe.com> @ 2022-01-08 4:45 ` Abner Chang 0 siblings, 0 replies; 2+ messages in thread From: Abner Chang @ 2022-01-08 4:45 UTC (permalink / raw) To: devel; +Cc: abner.chang (This is migrated from edk2-platforms:Platform) Code changes to incorporate with OpenSBI commit ID: a731c7e36988c3308e1978ecde491f2f6182d490 Cc: Sunil V L <sunilvl@ventanamicro.com> Cc: Daniel Schaefer <daniel.schaefer@hpe.com> Signed-off-by: Abner Chang <abner.chang@hpe.com> Reviewed-by: Daniel Schaefer <daniel.schaefer@hpe.com> Reviewed-by: Sunil V L <sunilvl@ventanamicro.com> --- .../OpensbiPlatformLib/OpensbiPlatformLib.inf | 10 +- .../PlatformPkg/Universal/Sec/SecMain.inf | 4 + .../Library/OpensbiPlatformLib/Platform.c | 57 ---- .../Universal/Sec/Edk2OpenSbiPlatform.c | 149 --------- .../PlatformPkg/Universal/Sec/SecMain.c | 48 ++- .../Universal/Sec/Riscv64/SecEntry.S | 300 ++++++++++-------- 6 files changed, 212 insertions(+), 356 deletions(-) diff --git a/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf index 909fbffa8d..2e1227733a 100644 --- a/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf +++ b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf @@ -51,12 +51,4 @@ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootableHartNumber gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize - gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdU5UartBase - gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdU5PlatformSystemClock - - gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRootFirmwareDomainBaseAddress - gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRootFirmwareDomainSize - gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFirmwareDomainBaseAddress - gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFirmwareDomainSize - gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFirmwareRegionBaseAddress - gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFirmwareRegionSize + diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf index 1cfbef961f..dd5f01ab4d 100644 --- a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf @@ -66,6 +66,10 @@ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootableHartIndexToId gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRootFirmwareDomainBaseAddress gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRootFirmwareDomainSize + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFirmwareDomainBaseAddress + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFirmwareDomainSize + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFirmwareRegionBaseAddress + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFirmwareRegionSize gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize diff --git a/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/Platform.c b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/Platform.c index b477b81d74..c62d235333 100644 --- a/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/Platform.c +++ b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/Platform.c @@ -197,68 +197,11 @@ static u64 generic_tlbr_flush_limit(void) return SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT; } -static int generic_system_reset_check(u32 reset_type, u32 reset_reason) -{ - if (generic_plat && generic_plat->system_reset_check) - return generic_plat->system_reset_check(reset_type, - reset_reason, - generic_plat_match); - return fdt_system_reset_check(reset_type, reset_reason); -} - -static void generic_system_reset(u32 reset_type, u32 reset_reason) -{ - if (generic_plat && generic_plat->system_reset) { - generic_plat->system_reset(reset_type, reset_reason, - generic_plat_match); - return; - } - - fdt_system_reset(reset_type, reset_reason); -} - -#define EDK2_ROOT_FW_REGION 0 -#define EDK2_FW_REGION 1 -#define EDK2_VARIABLE_REGION 2 -#define EDK2_ALL_REGION 3 -#define EDK2_END_REGION 4 -static struct sbi_domain_memregion root_memregs[EDK2_END_REGION + 1] = { 0 }; - -struct sbi_domain_memregion *get_mem_regions(void) { - /* EDK2 root firmware domain memory region */ - root_memregs[EDK2_ROOT_FW_REGION].order = log2roundup(FixedPcdGet32(PcdRootFirmwareDomainSize)); - root_memregs[EDK2_ROOT_FW_REGION].base = FixedPcdGet32(PcdRootFirmwareDomainBaseAddress); - root_memregs[EDK2_ROOT_FW_REGION].flags = 0; - - /*EDK2 firmware domain memory region */ - root_memregs[EDK2_FW_REGION].order = log2roundup(FixedPcdGet32(PcdFirmwareDomainSize)); - root_memregs[EDK2_FW_REGION].base = FixedPcdGet32(PcdFirmwareDomainBaseAddress); - root_memregs[EDK2_FW_REGION].flags = SBI_DOMAIN_MEMREGION_EXECUTABLE | SBI_DOMAIN_MEMREGION_READABLE; - - /*EDK2 firmware domain memory region */ - root_memregs[EDK2_VARIABLE_REGION].order = log2roundup(FixedPcdGet32(PcdVariableFirmwareRegionSize)); - root_memregs[EDK2_VARIABLE_REGION].base = FixedPcdGet32(PcdVariableFirmwareRegionBaseAddress); - root_memregs[EDK2_VARIABLE_REGION].flags = SBI_DOMAIN_MEMREGION_READABLE | SBI_DOMAIN_MEMREGION_WRITEABLE; - - /* EDK2 domain allow everything memory region */ - root_memregs[EDK2_ALL_REGION].order = __riscv_xlen; - root_memregs[EDK2_ALL_REGION].base = 0; - root_memregs[EDK2_ALL_REGION].flags = (SBI_DOMAIN_MEMREGION_READABLE | - SBI_DOMAIN_MEMREGION_WRITEABLE | - SBI_DOMAIN_MEMREGION_EXECUTABLE); - - /* EDK2 domain memory region end */ - root_memregs[EDK2_END_REGION].order = 0; - - return root_memregs; -} - const struct sbi_platform_operations platform_ops = { .early_init = generic_early_init, .final_init = generic_final_init, .early_exit = generic_early_exit, .final_exit = generic_final_exit, - .domains_root_regions = get_mem_regions, .domains_init = generic_domains_init, .console_init = fdt_serial_init, .irqchip_init = fdt_irqchip_init, diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/Edk2OpenSbiPlatform.c b/Platform/RISC-V/PlatformPkg/Universal/Sec/Edk2OpenSbiPlatform.c index 79b2f33675..779705489c 100644 --- a/Platform/RISC-V/PlatformPkg/Universal/Sec/Edk2OpenSbiPlatform.c +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/Edk2OpenSbiPlatform.c @@ -117,18 +117,6 @@ int Edk2OpensbiPlatforMMISAGetXLEN (VOID) return 0; } -/** Get platform specific root domain memory regions */ -struct sbi_domain_memregion * -Edk2OpensbiPlatformGetMemRegions (VOID) -{ - DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); - - if (platform_ops.domains_root_regions) { - return platform_ops.domains_root_regions (); - } - return 0; -} - /** Initialize (or populate) domains for the platform */ int Edk2OpensbiPlatformDomainsInit (VOID) { @@ -140,25 +128,6 @@ int Edk2OpensbiPlatformDomainsInit (VOID) return 0; } -/** Write a character to the platform console output */ -VOID Edk2OpensbiPlatformSerialPutc ( - CHAR8 Ch - ) -{ - if (platform_ops.console_putc) { - return platform_ops.console_putc (Ch); - } -} - -/** Read a character from the platform console input */ -int Edk2OpensbiPlatformSerialGetc (VOID) -{ - if (platform_ops.console_getc) { - return platform_ops.console_getc (); - } - return 0; -} - /** Initialize the platform console */ int Edk2OpensbiPlatformSerialInit (VOID) { @@ -193,30 +162,6 @@ VOID Edk2OpensbiPlatformIrqchipExit (VOID) } } -/** Send IPI to a target HART */ -VOID Edk2OpensbiPlatformIpiSend ( - UINT32 TargetHart - ) -{ - DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); - - if (platform_ops.ipi_send) { - return platform_ops.ipi_send (TargetHart); - } -} - -/** Clear IPI for a target HART */ -VOID Edk2OpensbiPlatformIpiClear ( - UINT32 TargetHart - ) -{ - DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); - - if (platform_ops.ipi_clear) { - return platform_ops.ipi_clear (TargetHart); - } -} - /** Initialize IPI for current HART */ int Edk2OpensbiPlatformIpiInit ( BOOLEAN ColdBoot @@ -251,33 +196,6 @@ UINT64 Edk2OpensbiPlatformTlbrFlushLimit (VOID) return 0; } -/** Get platform timer value */ -UINT64 Edk2OpensbiPlatformTimerValue (VOID) -{ - if (platform_ops.timer_value) { - return platform_ops.timer_value (); - } - return 0; -} - -/** Start platform timer event for current HART */ -VOID Edk2OpensbiPlatformTimerEventStart ( - UINT64 NextEvent - ) -{ - if (platform_ops.timer_event_start) { - return platform_ops.timer_event_start (NextEvent); - } -} - -/** Stop platform timer event for current HART */ -VOID Edk2OpensbiPlatformTimerEventStop (VOID) -{ - if (platform_ops.timer_event_stop) { - return platform_ops.timer_event_stop (); - } -} - /** Initialize platform timer for current HART */ int Edk2OpensbiPlatformTimerInit ( BOOLEAN ColdBoot @@ -301,61 +219,6 @@ VOID Edk2OpensbiPlatformTimerExit (VOID) } } -/** Bringup the given hart */ -int Edk2OpensbiPlatformHartStart ( - UINT32 HartId, - ulong Saddr - ) -{ - DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); - - if (platform_ops.hart_start) { - return platform_ops.hart_start (HartId, Saddr); - } - return 0; -} -/** - Stop the current hart from running. This call doesn't expect to - return if success. -**/ -int Edk2OpensbiPlatformHartStop (VOID) -{ - DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); - - if (platform_ops.hart_stop) { - return platform_ops.hart_stop (); - } - return 0; -} - -/** - Check whether reset type and reason supported by the platform* - -**/ -int Edk2OpensbiPlatformSystemResetCheck ( - UINT32 ResetType, - UINT32 ResetReason - ) -{ - if (platform_ops.system_reset_check) { - return platform_ops.system_reset_check (ResetType, ResetReason); - } - return 0; -} - -/** Reset the platform */ -VOID Edk2OpensbiPlatformSystemReset ( - UINT32 ResetType, - UINT32 ResetReason - ) -{ - DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); - - if (platform_ops.system_reset) { - return platform_ops.system_reset (ResetType, ResetReason); - } -} - /** platform specific SBI extension implementation probe function */ int Edk2OpensbiPlatformVendorExtCheck ( long ExtId @@ -400,27 +263,15 @@ const struct sbi_platform_operations Edk2OpensbiPlatformOps = { .final_exit = Edk2OpensbiPlatformFinalExit, .misa_check_extension = Edk2OpensbiPlatforMMISACheckExtension, .misa_get_xlen = Edk2OpensbiPlatforMMISAGetXLEN, - .domains_root_regions = Edk2OpensbiPlatformGetMemRegions, .domains_init = Edk2OpensbiPlatformDomainsInit, - .console_putc = Edk2OpensbiPlatformSerialPutc, - .console_getc = Edk2OpensbiPlatformSerialGetc, .console_init = Edk2OpensbiPlatformSerialInit, .irqchip_init = Edk2OpensbiPlatformIrqchipInit, .irqchip_exit = Edk2OpensbiPlatformIrqchipExit, - .ipi_send = Edk2OpensbiPlatformIpiSend, - .ipi_clear = Edk2OpensbiPlatformIpiClear, .ipi_init = Edk2OpensbiPlatformIpiInit, .ipi_exit = Edk2OpensbiPlatformIpiExit, .get_tlbr_flush_limit = Edk2OpensbiPlatformTlbrFlushLimit, - .timer_value = Edk2OpensbiPlatformTimerValue, - .timer_event_stop = Edk2OpensbiPlatformTimerEventStop, - .timer_event_start = Edk2OpensbiPlatformTimerEventStart, .timer_init = Edk2OpensbiPlatformTimerInit, .timer_exit = Edk2OpensbiPlatformTimerExit, - .hart_start = Edk2OpensbiPlatformHartStart, - .hart_stop = Edk2OpensbiPlatformHartStop, - .system_reset_check = Edk2OpensbiPlatformSystemResetCheck, - .system_reset = Edk2OpensbiPlatformSystemReset, .vendor_ext_check = Edk2OpensbiPlatformVendorExtCheck, .vendor_ext_provider = Edk2OpensbiPlatformVendorExtProvider, }; diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c index 93ff8a598d..3bc3690047 100644 --- a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c @@ -15,10 +15,12 @@ #include <sbi/riscv_asm.h> #include <sbi/riscv_atomic.h> #include <sbi/sbi_console.h> // Reference to header file in opensbi +#include <sbi/sbi_domain.h> #include <sbi/sbi_hart.h> // Reference to header file in opensbi -#include <sbi/sbi_hartmask.h> // Reference to header file in opensbi +#include <sbi/sbi_hartmask.h> // Reference to header file in opensbi #include <sbi/sbi_scratch.h> // Reference to header file in opensbi #include <sbi/sbi_platform.h> // Reference to header file in opensbi +#include <sbi/sbi_math.h> // Reference to header file in opensbi #include <sbi/sbi_init.h> // Reference to header file in opensbi #include <sbi/sbi_ecall.h> // Reference to header file in opensbi #include <sbi/sbi_trap.h> // Reference to header file in opensbi @@ -31,8 +33,41 @@ extern struct sbi_platform_operations Edk2OpensbiPlatformOps; atomic_t BootHartDone = ATOMIC_INITIALIZER(0); atomic_t NonBootHartMessageLock = ATOMIC_INITIALIZER(0); +int sbi_domain_root_add_memregion(const struct sbi_domain_memregion *reg); + typedef struct sbi_scratch *(*hartid2scratch)(ulong hartid, ulong hartindex); +struct sbi_domain_memregion fw_memregs; + +int SecSetEdk2FwMemoryRegions (VOID) { + int Ret; + + Ret = 0; + + // + // EDK2 PEI domain memory region + // + fw_memregs.order = log2roundup(FixedPcdGet32(PcdFirmwareDomainSize)); + fw_memregs.base = FixedPcdGet32(PcdFirmwareDomainBaseAddress); + fw_memregs.flags = SBI_DOMAIN_MEMREGION_EXECUTABLE | SBI_DOMAIN_MEMREGION_READABLE; + Ret = sbi_domain_root_add_memregion ((const struct sbi_domain_memregion *)&fw_memregs); + if (Ret != 0) { + DEBUG ((DEBUG_ERROR, "%a: Add firmware regiosn of FW Domain fail\n", __FUNCTION__)); + } + + // + // EDK2 EFI Variable domain memory region + // + fw_memregs.order = log2roundup(FixedPcdGet32(PcdVariableFirmwareRegionSize)); + fw_memregs.base = FixedPcdGet32(PcdVariableFirmwareRegionBaseAddress); + fw_memregs.flags = SBI_DOMAIN_MEMREGION_READABLE | SBI_DOMAIN_MEMREGION_WRITEABLE; + Ret = sbi_domain_root_add_memregion ((const struct sbi_domain_memregion *)&fw_memregs); + if (Ret != 0) { + DEBUG ((DEBUG_ERROR, "%a: Add firmware regiosn of variable FW Domain fail\n", __FUNCTION__)); + } + return Ret; +} + /** Locates a section within a series of sections with the specified section type. @@ -405,6 +440,13 @@ SecPostOpenSbiPlatformEarlylInit( DEBUG ((DEBUG_INFO, "%a: Non boot hart %d.\n", __FUNCTION__, HartId)); return 0; } + // + // Setup firmware memory region. + // + if (SecSetEdk2FwMemoryRegions () != 0) { + ASSERT (FALSE); + } + // // Boot HART is already in the process of OpenSBI initialization. // We can let other HART to keep booting. @@ -477,7 +519,7 @@ SecPostOpenSbiPlatformFinalInit ( } } - DEBUG((DEBUG_INFO, "%a: Jump to PEI Core with \n", __FUNCTION__)); + DEBUG((DEBUG_INFO, "%a: Will jump to PEI Core in OpenSBI with \n", __FUNCTION__)); DEBUG((DEBUG_INFO, " sbi_scratch = %x\n", SbiScratch)); DEBUG((DEBUG_INFO, " sbi_platform = %x\n", SbiPlatform)); DEBUG((DEBUG_INFO, " FirmwareContext = %x\n", FirmwareContext)); @@ -793,7 +835,7 @@ VOID EFIAPI SecCoreStartUpWithStack( sbi_init(Scratch); } -void OpensbiDebugPrint (char *debugstr, ...) +VOID OpensbiDebugPrint (CHAR8 *debugstr, ...) { VA_LIST Marker; diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/Riscv64/SecEntry.S b/Platform/RISC-V/PlatformPkg/Universal/Sec/Riscv64/SecEntry.S index f0c3dff0d9..96087738a3 100644 --- a/Platform/RISC-V/PlatformPkg/Universal/Sec/Riscv64/SecEntry.S +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/Riscv64/SecEntry.S @@ -18,6 +18,12 @@ #include <SecMain.h> +.macro MOV_3R __d0, __s0, __d1, __s1, __d2, __s2 + add \__d0, \__s0, zero + add \__d1, \__s1, zero + add \__d2, \__s2, zero +.endm + .text .align 3 @@ -90,7 +96,11 @@ _scratch_init: la a4, _hartid_to_scratch sd a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp) /* Save _hartid_to_scratch function in scratch buffer*/ sd zero, SBI_SCRATCH_TMP0_OFFSET(tp) - + /* Store trap-exit function address in scratch space */ + lla a4, _trap_exit + sd a4, SBI_SCRATCH_TRAP_EXIT_OFFSET(tp) + /* Clear tmp0 in scratch space */ + sd zero, SBI_SCRATCH_TMP0_OFFSET(tp) #ifdef FW_OPTIONS li a4, FW_OPTIONS sd a4, SBI_SCRATCH_OPTIONS_OFFSET(tp) @@ -322,160 +332,174 @@ _uninitialized_hart_wait: wfi j _uninitialized_hart_wait - .align 3 - .section .entry, "ax", %progbits - .align 3 - .globl _trap_handler -_trap_handler: - +.macro TRAP_SAVE_AND_SETUP_SP_T0 /* Swap TP and MSCRATCH */ - csrrw tp, CSR_MSCRATCH, tp + csrrw tp, CSR_MSCRATCH, tp /* Save T0 in scratch space */ - REG_S t0, SBI_SCRATCH_TMP0_OFFSET(tp) + REG_S 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 */ - REG_S t0, SBI_TRAP_REGS_OFFSET(sp)(sp) + /* + * Set T0 to appropriate exception stack + * + * Came_From_M_Mode = ((MSTATUS.MPP < PRV_M) ? 1 : 0) - 1; + * Exception_Stack = TP ^ (Came_From_M_Mode & (SP ^ TP)) + * + * Came_From_M_Mode = 0 ==> Exception_Stack = TP + * Came_From_M_Mode = -1 ==> Exception_Stack = SP + */ + csrr t0, CSR_MSTATUS + srl t0, t0, MSTATUS_MPP_SHIFT + and t0, t0, PRV_M + slti t0, t0, PRV_M + add t0, t0, -1 + xor sp, sp, tp + and t0, t0, sp + xor sp, sp, tp + xor t0, tp, t0 + + /* Save original SP on exception stack */ + REG_S sp, (SBI_TRAP_REGS_OFFSET(sp) - SBI_TRAP_REGS_SIZE)(t0) + + /* Set SP to exception stack and make room for trap registers */ + add sp, t0, -(SBI_TRAP_REGS_SIZE) /* Restore T0 from scratch space */ - REG_L t0, SBI_SCRATCH_TMP0_OFFSET(tp) + REG_L t0, SBI_SCRATCH_TMP0_OFFSET(tp) /* Save T0 on stack */ - REG_S t0, SBI_TRAP_REGS_OFFSET(t0)(sp) + REG_S t0, SBI_TRAP_REGS_OFFSET(t0)(sp) /* Swap TP and MSCRATCH */ - csrrw tp, CSR_MSCRATCH, tp + csrrw tp, CSR_MSCRATCH, tp +.endm +.macro TRAP_SAVE_MEPC_MSTATUS have_mstatush /* Save MEPC and MSTATUS CSRs */ - csrr t0, CSR_MEPC - REG_S t0, SBI_TRAP_REGS_OFFSET(mepc)(sp) - csrr t0, CSR_MSTATUS - REG_S t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp) - REG_S zero, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) -#if __riscv_xlen == 32 - csrr t0, CSR_MISA - srli t0, t0, ('H' - 'A') - andi t0, t0, 0x1 - beq t0, zero, _skip_mstatush_save - csrr t0, CSR_MSTATUSH - REG_S t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) -_skip_mstatush_save: -#endif + csrr t0, CSR_MEPC + REG_S t0, SBI_TRAP_REGS_OFFSET(mepc)(sp) + csrr t0, CSR_MSTATUS + REG_S t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp) +.if \have_mstatush + csrr t0, CSR_MSTATUSH + REG_S t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) +.else + REG_S zero, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) +.endif +.endm + +.macro TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0 + /* Save all general regisers except SP and T0 */ + REG_S zero, SBI_TRAP_REGS_OFFSET(zero)(sp) + REG_S ra, SBI_TRAP_REGS_OFFSET(ra)(sp) + REG_S gp, SBI_TRAP_REGS_OFFSET(gp)(sp) + REG_S tp, SBI_TRAP_REGS_OFFSET(tp)(sp) + REG_S t1, SBI_TRAP_REGS_OFFSET(t1)(sp) + REG_S t2, SBI_TRAP_REGS_OFFSET(t2)(sp) + REG_S s0, SBI_TRAP_REGS_OFFSET(s0)(sp) + REG_S s1, SBI_TRAP_REGS_OFFSET(s1)(sp) + REG_S a0, SBI_TRAP_REGS_OFFSET(a0)(sp) + REG_S a1, SBI_TRAP_REGS_OFFSET(a1)(sp) + REG_S a2, SBI_TRAP_REGS_OFFSET(a2)(sp) + REG_S a3, SBI_TRAP_REGS_OFFSET(a3)(sp) + REG_S a4, SBI_TRAP_REGS_OFFSET(a4)(sp) + REG_S a5, SBI_TRAP_REGS_OFFSET(a5)(sp) + REG_S a6, SBI_TRAP_REGS_OFFSET(a6)(sp) + REG_S a7, SBI_TRAP_REGS_OFFSET(a7)(sp) + REG_S s2, SBI_TRAP_REGS_OFFSET(s2)(sp) + REG_S s3, SBI_TRAP_REGS_OFFSET(s3)(sp) + REG_S s4, SBI_TRAP_REGS_OFFSET(s4)(sp) + REG_S s5, SBI_TRAP_REGS_OFFSET(s5)(sp) + REG_S s6, SBI_TRAP_REGS_OFFSET(s6)(sp) + REG_S s7, SBI_TRAP_REGS_OFFSET(s7)(sp) + REG_S s8, SBI_TRAP_REGS_OFFSET(s8)(sp) + REG_S s9, SBI_TRAP_REGS_OFFSET(s9)(sp) + REG_S s10, SBI_TRAP_REGS_OFFSET(s10)(sp) + REG_S s11, SBI_TRAP_REGS_OFFSET(s11)(sp) + REG_S t3, SBI_TRAP_REGS_OFFSET(t3)(sp) + REG_S t4, SBI_TRAP_REGS_OFFSET(t4)(sp) + REG_S t5, SBI_TRAP_REGS_OFFSET(t5)(sp) + REG_S t6, SBI_TRAP_REGS_OFFSET(t6)(sp) +.endm + +.macro TRAP_CALL_C_ROUTINE + /* Call C routine */ + add a0, sp, zero + call sbi_trap_handler +.endm + +.macro TRAP_RESTORE_GENERAL_REGS_EXCEPT_A0_T0 + /* Restore all general regisers except A0 and T0 */ + REG_L ra, SBI_TRAP_REGS_OFFSET(ra)(a0) + REG_L sp, SBI_TRAP_REGS_OFFSET(sp)(a0) + REG_L gp, SBI_TRAP_REGS_OFFSET(gp)(a0) + REG_L tp, SBI_TRAP_REGS_OFFSET(tp)(a0) + REG_L t1, SBI_TRAP_REGS_OFFSET(t1)(a0) + REG_L t2, SBI_TRAP_REGS_OFFSET(t2)(a0) + REG_L s0, SBI_TRAP_REGS_OFFSET(s0)(a0) + REG_L s1, SBI_TRAP_REGS_OFFSET(s1)(a0) + REG_L a1, SBI_TRAP_REGS_OFFSET(a1)(a0) + REG_L a2, SBI_TRAP_REGS_OFFSET(a2)(a0) + REG_L a3, SBI_TRAP_REGS_OFFSET(a3)(a0) + REG_L a4, SBI_TRAP_REGS_OFFSET(a4)(a0) + REG_L a5, SBI_TRAP_REGS_OFFSET(a5)(a0) + REG_L a6, SBI_TRAP_REGS_OFFSET(a6)(a0) + REG_L a7, SBI_TRAP_REGS_OFFSET(a7)(a0) + REG_L s2, SBI_TRAP_REGS_OFFSET(s2)(a0) + REG_L s3, SBI_TRAP_REGS_OFFSET(s3)(a0) + REG_L s4, SBI_TRAP_REGS_OFFSET(s4)(a0) + REG_L s5, SBI_TRAP_REGS_OFFSET(s5)(a0) + REG_L s6, SBI_TRAP_REGS_OFFSET(s6)(a0) + REG_L s7, SBI_TRAP_REGS_OFFSET(s7)(a0) + REG_L s8, SBI_TRAP_REGS_OFFSET(s8)(a0) + REG_L s9, SBI_TRAP_REGS_OFFSET(s9)(a0) + REG_L s10, SBI_TRAP_REGS_OFFSET(s10)(a0) + REG_L s11, SBI_TRAP_REGS_OFFSET(s11)(a0) + REG_L t3, SBI_TRAP_REGS_OFFSET(t3)(a0) + REG_L t4, SBI_TRAP_REGS_OFFSET(t4)(a0) + REG_L t5, SBI_TRAP_REGS_OFFSET(t5)(a0) + REG_L t6, SBI_TRAP_REGS_OFFSET(t6)(a0) +.endm + +.macro TRAP_RESTORE_MEPC_MSTATUS have_mstatush + /* Restore MEPC and MSTATUS CSRs */ + REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(a0) + csrw CSR_MEPC, t0 + REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(a0) + csrw CSR_MSTATUS, t0 +.if \have_mstatush + REG_L t0, SBI_TRAP_REGS_OFFSET(mstatusH)(a0) + csrw CSR_MSTATUSH, t0 +.endif +.endm + +.macro TRAP_RESTORE_A0_T0 + /* Restore T0 */ + REG_L t0, SBI_TRAP_REGS_OFFSET(t0)(a0) - /* Save all general registers except SP and T0 */ - REG_S zero, SBI_TRAP_REGS_OFFSET(zero)(sp) - REG_S ra, SBI_TRAP_REGS_OFFSET(ra)(sp) - REG_S gp, SBI_TRAP_REGS_OFFSET(gp)(sp) - REG_S tp, SBI_TRAP_REGS_OFFSET(tp)(sp) - REG_S t1, SBI_TRAP_REGS_OFFSET(t1)(sp) - REG_S t2, SBI_TRAP_REGS_OFFSET(t2)(sp) - REG_S s0, SBI_TRAP_REGS_OFFSET(s0)(sp) - REG_S s1, SBI_TRAP_REGS_OFFSET(s1)(sp) - REG_S a0, SBI_TRAP_REGS_OFFSET(a0)(sp) - REG_S a1, SBI_TRAP_REGS_OFFSET(a1)(sp) - REG_S a2, SBI_TRAP_REGS_OFFSET(a2)(sp) - REG_S a3, SBI_TRAP_REGS_OFFSET(a3)(sp) - REG_S a4, SBI_TRAP_REGS_OFFSET(a4)(sp) - REG_S a5, SBI_TRAP_REGS_OFFSET(a5)(sp) - REG_S a6, SBI_TRAP_REGS_OFFSET(a6)(sp) - REG_S a7, SBI_TRAP_REGS_OFFSET(a7)(sp) - REG_S s2, SBI_TRAP_REGS_OFFSET(s2)(sp) - REG_S s3, SBI_TRAP_REGS_OFFSET(s3)(sp) - REG_S s4, SBI_TRAP_REGS_OFFSET(s4)(sp) - REG_S s5, SBI_TRAP_REGS_OFFSET(s5)(sp) - REG_S s6, SBI_TRAP_REGS_OFFSET(s6)(sp) - REG_S s7, SBI_TRAP_REGS_OFFSET(s7)(sp) - REG_S s8, SBI_TRAP_REGS_OFFSET(s8)(sp) - REG_S s9, SBI_TRAP_REGS_OFFSET(s9)(sp) - REG_S s10, SBI_TRAP_REGS_OFFSET(s10)(sp) - REG_S s11, SBI_TRAP_REGS_OFFSET(s11)(sp) - REG_S t3, SBI_TRAP_REGS_OFFSET(t3)(sp) - REG_S t4, SBI_TRAP_REGS_OFFSET(t4)(sp) - REG_S t5, SBI_TRAP_REGS_OFFSET(t5)(sp) - REG_S t6, SBI_TRAP_REGS_OFFSET(t6)(sp) + /* Restore A0 */ + REG_L a0, SBI_TRAP_REGS_OFFSET(a0)(a0) +.endm - /* Call C routine */ - add a0, sp, zero - call sbi_trap_handler - - /* Restore all general registers except SP and T0 */ - REG_L ra, SBI_TRAP_REGS_OFFSET(ra)(sp) - REG_L gp, SBI_TRAP_REGS_OFFSET(gp)(sp) - REG_L tp, SBI_TRAP_REGS_OFFSET(tp)(sp) - REG_L t1, SBI_TRAP_REGS_OFFSET(t1)(sp) - REG_L t2, SBI_TRAP_REGS_OFFSET(t2)(sp) - REG_L s0, SBI_TRAP_REGS_OFFSET(s0)(sp) - REG_L s1, SBI_TRAP_REGS_OFFSET(s1)(sp) - REG_L a0, SBI_TRAP_REGS_OFFSET(a0)(sp) - REG_L a1, SBI_TRAP_REGS_OFFSET(a1)(sp) - REG_L a2, SBI_TRAP_REGS_OFFSET(a2)(sp) - REG_L a3, SBI_TRAP_REGS_OFFSET(a3)(sp) - REG_L a4, SBI_TRAP_REGS_OFFSET(a4)(sp) - REG_L a5, SBI_TRAP_REGS_OFFSET(a5)(sp) - REG_L a6, SBI_TRAP_REGS_OFFSET(a6)(sp) - REG_L a7, SBI_TRAP_REGS_OFFSET(a7)(sp) - REG_L s2, SBI_TRAP_REGS_OFFSET(s2)(sp) - REG_L s3, SBI_TRAP_REGS_OFFSET(s3)(sp) - REG_L s4, SBI_TRAP_REGS_OFFSET(s4)(sp) - REG_L s5, SBI_TRAP_REGS_OFFSET(s5)(sp) - REG_L s6, SBI_TRAP_REGS_OFFSET(s6)(sp) - REG_L s7, SBI_TRAP_REGS_OFFSET(s7)(sp) - REG_L s8, SBI_TRAP_REGS_OFFSET(s8)(sp) - REG_L s9, SBI_TRAP_REGS_OFFSET(s9)(sp) - REG_L s10, SBI_TRAP_REGS_OFFSET(s10)(sp) - REG_L s11, SBI_TRAP_REGS_OFFSET(s11)(sp) - REG_L t3, SBI_TRAP_REGS_OFFSET(t3)(sp) - REG_L t4, SBI_TRAP_REGS_OFFSET(t4)(sp) - REG_L t5, SBI_TRAP_REGS_OFFSET(t5)(sp) - REG_L t6, SBI_TRAP_REGS_OFFSET(t6)(sp) + .section .entry, "ax", %progbits + .align 3 + .globl _trap_handler + .globl _trap_exit +_trap_handler: + TRAP_SAVE_AND_SETUP_SP_T0 - /* Restore MEPC and MSTATUS CSRs */ - REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(sp) - csrw CSR_MEPC, t0 - REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp) - csrw CSR_MSTATUS, t0 -#if __riscv_xlen == 32 - csrr t0, CSR_MISA - srli t0, t0, ('H' - 'A') - andi t0, t0, 0x1 - beq t0, zero, _skip_mstatush_restore - REG_L t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) - csrw CSR_MSTATUSH, t0 -_skip_mstatush_restore: -#endif + TRAP_SAVE_MEPC_MSTATUS 0 - /* Restore T0 */ - REG_L t0, SBI_TRAP_REGS_OFFSET(t0)(sp) + TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0 + + TRAP_CALL_C_ROUTINE + +_trap_exit: + TRAP_RESTORE_GENERAL_REGS_EXCEPT_A0_T0 + + TRAP_RESTORE_MEPC_MSTATUS 0 - /* Restore SP */ - REG_L sp, SBI_TRAP_REGS_OFFSET(sp)(sp) + TRAP_RESTORE_A0_T0 mret -- 2.31.1 ^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH 42/79] RISC-V: Use RISC-V PeiCoreEntryPoint library @ 2022-01-08 7:24 Abner Chang 2022-01-08 7:24 ` [PATCH 56/79] RISC-V/PlatformPkg: Updates for the latest OpenSBI Abner Chang 0 siblings, 1 reply; 2+ messages in thread From: Abner Chang @ 2022-01-08 7:24 UTC (permalink / raw) To: devel; +Cc: abner.chang (This is migrated from edk2-platforms) 1. Use RISC-V PeiCoreEntryPoint library instance for opensbi to switch to the next phase with arg0 as HART Id and arg1 as the SEC to PEI handoff data. 2. Introduce EDK2 opensbi platform operation functions. With this, OEM can has its won platform initialization code before and/or after opensbi vendor platform functions. Cc: Sunil V L <sunilvl@ventanamicro.com> Cc: Daniel Schaefer <daniel.schaefer@hpe.com> Signed-off-by: Abner Chang <abner.chang@hpe.com> Reviewed-by: Daniel Schaefer <daniel.schaefer@hpe.com> Reviewed-by: Sunil V L <sunilvl@ventanamicro.com> --- .../PlatformPkg/Universal/Sec/SecMain.inf | 2 + .../PlatformPkg/Universal/Sec/SecMain.h | 10 + .../Include/IndustryStandard/RiscVOpensbi.h | 8 +- .../Universal/Sec/Edk2OpenSbiPlatform.c | 426 ++++++++++++++++++ .../PlatformPkg/Universal/Sec/SecMain.c | 152 +++++-- 5 files changed, 545 insertions(+), 53 deletions(-) create mode 100644 Platform/RISC-V/PlatformPkg/Universal/Sec/Edk2OpenSbiPlatform.c diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf index bcb8b9f908..4207c83413 100644 --- a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf @@ -23,11 +23,13 @@ [Sources] SecMain.c + Edk2OpenSbiPlatform.c [Sources.RISCV64] Riscv64/SecEntry.S [Packages] + EmbeddedPkg/EmbeddedPkg.dec MdeModulePkg/MdeModulePkg.dec MdePkg/MdePkg.dec Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.h b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.h index 94ea46263c..c04ddbad7f 100644 --- a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.h +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.h @@ -28,6 +28,16 @@ #include <Ppi/TemporaryRamDone.h> #include <Ppi/TemporaryRamSupport.h> +int +SecPostOpenSbiPlatformEarlylInit( + IN BOOLEAN ColdBoot + ); + +int +SecPostOpenSbiPlatformFinalInit ( + IN BOOLEAN ColdBoot + ); + VOID SecMachineModeTrapHandler ( IN VOID diff --git a/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h index e7ac6d26ee..d639429306 100644 --- a/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h +++ b/Silicon/RISC-V/ProcessorPkg/Include/IndustryStandard/RiscVOpensbi.h @@ -1,7 +1,7 @@ /** @file SBI inline function calls. - Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR> + Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR> SPDX-License-Identifier: BSD-2-Clause-Patent @@ -46,8 +46,10 @@ typedef struct { // structure. Referred by both C code and assembly code. typedef struct { - VOID *PeiServiceTable; // PEI Service table - UINT64 FlattenedDeviceTree; // Pointer to Flattened Device tree + UINT64 BootHartId; + VOID *PeiServiceTable; // PEI Service table + UINT64 FlattenedDeviceTree; // Pointer to Flattened Device tree + UINT64 SecPeiHandOffData; // This is EFI_SEC_PEI_HAND_OFF passed to PEI Core. EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *HartSpecific[RISC_V_MAX_HART_SUPPORTED]; } EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT; diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/Edk2OpenSbiPlatform.c b/Platform/RISC-V/PlatformPkg/Universal/Sec/Edk2OpenSbiPlatform.c new file mode 100644 index 0000000000..79b2f33675 --- /dev/null +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/Edk2OpenSbiPlatform.c @@ -0,0 +1,426 @@ +/* + Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + + */ + +#include <Library/DebugAgentLib.h> +#include <Library/DebugLib.h> + +#include <libfdt.h> +#include <sbi/riscv_asm.h> +#include <sbi/sbi_domain.h> +#include <sbi/sbi_hartmask.h> +#include <sbi/sbi_platform.h> +#include <sbi/sbi_string.h> +#include <sbi/sbi_math.h> +#include <sbi_utils/fdt/fdt_domain.h> +#include <sbi_utils/fdt/fdt_fixup.h> +#include <sbi_utils/fdt/fdt_helper.h> +#include <sbi_utils/irqchip/fdt_irqchip.h> +#include <sbi_utils/serial/fdt_serial.h> +#include <sbi_utils/timer/fdt_timer.h> +#include <sbi_utils/ipi/fdt_ipi.h> +#include <sbi_utils/reset/fdt_reset.h> + +#include "SecMain.h" + +extern struct sbi_platform_operations platform_ops; + +int Edk2OpensbiPlatformEarlyInit ( + BOOLEAN ColdBoot + ) +{ + int ReturnCode; + + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.early_init) { + ReturnCode = platform_ops.early_init (ColdBoot); + if (ReturnCode) { + return ReturnCode; + } + } + if (ColdBoot == TRUE) { + return SecPostOpenSbiPlatformEarlylInit(ColdBoot); + } + return 0; +} + +int Edk2OpensbiPlatformFinalInit ( + BOOLEAN ColdBoot + ) +{ + int ReturnCode; + + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.final_init) { + ReturnCode = platform_ops.final_init (ColdBoot); + if (ReturnCode) { + return ReturnCode; + } + } + if (ColdBoot == TRUE) { + return SecPostOpenSbiPlatformFinalInit(ColdBoot); + } + return 0; +} + +VOID Edk2OpensbiPlatformEarlyExit ( + VOID + ) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.early_exit) { + return platform_ops.early_exit (); + } +} + +/** Platform final exit */ +VOID Edk2OpensbiPlatformFinalExit ( + VOID + ) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.early_exit) { + return platform_ops.early_exit (); + } +} + +/** + For platforms that do not implement misa, non-standard + methods are needed to determine cpu extension. +**/ +int Edk2OpensbiPlatforMMISACheckExtension ( + CHAR8 Extension + ) +{ + if (platform_ops.misa_check_extension) { + return platform_ops.misa_check_extension (Extension); + } + return 0; +} + +/** + For platforms that do not implement misa, non-standard + methods are needed to get MXL field of misa. +**/ +int Edk2OpensbiPlatforMMISAGetXLEN (VOID) +{ + if (platform_ops.misa_get_xlen) { + return platform_ops.misa_get_xlen (); + } + return 0; +} + +/** Get platform specific root domain memory regions */ +struct sbi_domain_memregion * +Edk2OpensbiPlatformGetMemRegions (VOID) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.domains_root_regions) { + return platform_ops.domains_root_regions (); + } + return 0; +} + +/** Initialize (or populate) domains for the platform */ +int Edk2OpensbiPlatformDomainsInit (VOID) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.domains_init) { + return platform_ops.domains_init (); + } + return 0; +} + +/** Write a character to the platform console output */ +VOID Edk2OpensbiPlatformSerialPutc ( + CHAR8 Ch + ) +{ + if (platform_ops.console_putc) { + return platform_ops.console_putc (Ch); + } +} + +/** Read a character from the platform console input */ +int Edk2OpensbiPlatformSerialGetc (VOID) +{ + if (platform_ops.console_getc) { + return platform_ops.console_getc (); + } + return 0; +} + +/** Initialize the platform console */ +int Edk2OpensbiPlatformSerialInit (VOID) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.console_init) { + return platform_ops.console_init (); + } + return 0; +} + +/** Initialize the platform interrupt controller for current HART */ +int Edk2OpensbiPlatformIrqchipInit ( + BOOLEAN ColdBoot + ) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.irqchip_init) { + return platform_ops.irqchip_init (ColdBoot); + } + return 0; +} + +/** Exit the platform interrupt controller for current HART */ +VOID Edk2OpensbiPlatformIrqchipExit (VOID) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.irqchip_exit) { + return platform_ops.irqchip_exit (); + } +} + +/** Send IPI to a target HART */ +VOID Edk2OpensbiPlatformIpiSend ( + UINT32 TargetHart + ) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.ipi_send) { + return platform_ops.ipi_send (TargetHart); + } +} + +/** Clear IPI for a target HART */ +VOID Edk2OpensbiPlatformIpiClear ( + UINT32 TargetHart + ) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.ipi_clear) { + return platform_ops.ipi_clear (TargetHart); + } +} + +/** Initialize IPI for current HART */ +int Edk2OpensbiPlatformIpiInit ( + BOOLEAN ColdBoot + ) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.ipi_init) { + return platform_ops.ipi_init (ColdBoot); + } + return 0; +} + +/** Exit IPI for current HART */ +VOID Edk2OpensbiPlatformIpiExit (VOID) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.ipi_exit) { + return platform_ops.ipi_exit (); + } +} + +/** Get tlb flush limit value **/ +UINT64 Edk2OpensbiPlatformTlbrFlushLimit (VOID) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.get_tlbr_flush_limit) { + return platform_ops.get_tlbr_flush_limit (); + } + return 0; +} + +/** Get platform timer value */ +UINT64 Edk2OpensbiPlatformTimerValue (VOID) +{ + if (platform_ops.timer_value) { + return platform_ops.timer_value (); + } + return 0; +} + +/** Start platform timer event for current HART */ +VOID Edk2OpensbiPlatformTimerEventStart ( + UINT64 NextEvent + ) +{ + if (platform_ops.timer_event_start) { + return platform_ops.timer_event_start (NextEvent); + } +} + +/** Stop platform timer event for current HART */ +VOID Edk2OpensbiPlatformTimerEventStop (VOID) +{ + if (platform_ops.timer_event_stop) { + return platform_ops.timer_event_stop (); + } +} + +/** Initialize platform timer for current HART */ +int Edk2OpensbiPlatformTimerInit ( + BOOLEAN ColdBoot + ) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.timer_init) { + return platform_ops.timer_init (ColdBoot); + } + return 0; +} + +/** Exit platform timer for current HART */ +VOID Edk2OpensbiPlatformTimerExit (VOID) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.timer_exit) { + return platform_ops.timer_exit (); + } +} + +/** Bringup the given hart */ +int Edk2OpensbiPlatformHartStart ( + UINT32 HartId, + ulong Saddr + ) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.hart_start) { + return platform_ops.hart_start (HartId, Saddr); + } + return 0; +} +/** + Stop the current hart from running. This call doesn't expect to + return if success. +**/ +int Edk2OpensbiPlatformHartStop (VOID) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.hart_stop) { + return platform_ops.hart_stop (); + } + return 0; +} + +/** + Check whether reset type and reason supported by the platform* + +**/ +int Edk2OpensbiPlatformSystemResetCheck ( + UINT32 ResetType, + UINT32 ResetReason + ) +{ + if (platform_ops.system_reset_check) { + return platform_ops.system_reset_check (ResetType, ResetReason); + } + return 0; +} + +/** Reset the platform */ +VOID Edk2OpensbiPlatformSystemReset ( + UINT32 ResetType, + UINT32 ResetReason + ) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.system_reset) { + return platform_ops.system_reset (ResetType, ResetReason); + } +} + +/** platform specific SBI extension implementation probe function */ +int Edk2OpensbiPlatformVendorExtCheck ( + long ExtId + ) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.vendor_ext_check) { + return platform_ops.vendor_ext_check (ExtId); + } + return 0; +} + + +/** platform specific SBI extension implementation provider */ +int Edk2OpensbiPlatformVendorExtProvider ( + long ExtId, + long FuncId, + const struct sbi_trap_regs *Regs, + unsigned long *OutValue, + struct sbi_trap_info *OutTrap + ) +{ + DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (platform_ops.vendor_ext_provider) { + return platform_ops.vendor_ext_provider ( + ExtId, + FuncId, + Regs, + OutValue, + OutTrap + ); + } + return 0; +} + +const struct sbi_platform_operations Edk2OpensbiPlatformOps = { + .early_init = Edk2OpensbiPlatformEarlyInit, + .final_init = Edk2OpensbiPlatformFinalInit, + .early_exit = Edk2OpensbiPlatformEarlyExit, + .final_exit = Edk2OpensbiPlatformFinalExit, + .misa_check_extension = Edk2OpensbiPlatforMMISACheckExtension, + .misa_get_xlen = Edk2OpensbiPlatforMMISAGetXLEN, + .domains_root_regions = Edk2OpensbiPlatformGetMemRegions, + .domains_init = Edk2OpensbiPlatformDomainsInit, + .console_putc = Edk2OpensbiPlatformSerialPutc, + .console_getc = Edk2OpensbiPlatformSerialGetc, + .console_init = Edk2OpensbiPlatformSerialInit, + .irqchip_init = Edk2OpensbiPlatformIrqchipInit, + .irqchip_exit = Edk2OpensbiPlatformIrqchipExit, + .ipi_send = Edk2OpensbiPlatformIpiSend, + .ipi_clear = Edk2OpensbiPlatformIpiClear, + .ipi_init = Edk2OpensbiPlatformIpiInit, + .ipi_exit = Edk2OpensbiPlatformIpiExit, + .get_tlbr_flush_limit = Edk2OpensbiPlatformTlbrFlushLimit, + .timer_value = Edk2OpensbiPlatformTimerValue, + .timer_event_stop = Edk2OpensbiPlatformTimerEventStop, + .timer_event_start = Edk2OpensbiPlatformTimerEventStart, + .timer_init = Edk2OpensbiPlatformTimerInit, + .timer_exit = Edk2OpensbiPlatformTimerExit, + .hart_start = Edk2OpensbiPlatformHartStart, + .hart_stop = Edk2OpensbiPlatformHartStop, + .system_reset_check = Edk2OpensbiPlatformSystemResetCheck, + .system_reset = Edk2OpensbiPlatformSystemReset, + .vendor_ext_check = Edk2OpensbiPlatformVendorExtCheck, + .vendor_ext_provider = Edk2OpensbiPlatformVendorExtProvider, +}; diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c index e88a7b8e80..44984b0078 100644 --- a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c @@ -23,6 +23,8 @@ #include <sbi/sbi_ecall.h> // Reference to header file in opensbi #include <sbi/sbi_trap.h> // Reference to header file in opensbi +extern struct sbi_platform_operations Edk2OpensbiPlatformOps; + // // Indicates the boot hart (PcdBootHartId) OpenSBI initialization is done. // @@ -31,27 +33,6 @@ atomic_t NonBootHartMessageLock = ATOMIC_INITIALIZER(0); typedef struct sbi_scratch *(*hartid2scratch)(ulong hartid, ulong hartindex); -STATIC EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = { - TemporaryRamMigration -}; - -STATIC EFI_PEI_TEMPORARY_RAM_DONE_PPI mTemporaryRamDonePpi = { - TemporaryRamDone -}; - -STATIC 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. @@ -491,6 +472,91 @@ RegisterFirmwareSbiExtension ( return EFI_SUCCESS; } + +/** + OpenSBI platform early init hook. + +**/ +int +SecPostOpenSbiPlatformEarlylInit( + IN BOOLEAN ColdBoot + ) +{ + // + // Boot HART is already in the process of OpenSBI initialization. + // We can let other HART to keep booting. + // + DEBUG ((DEBUG_INFO, "%a: Set boot hart done.\n", __FUNCTION__)); + atomic_write (&BootHartDone, (UINT64)TRUE); + return 0; +} + +/** + OpenSBI platform final init hook. + We restore the next_arg1 to the pointer of EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT. + +**/ +int +SecPostOpenSbiPlatformFinalInit ( + IN BOOLEAN ColdBoot + ) +{ + UINT32 HartId; + struct sbi_scratch *SbiScratch; + struct sbi_scratch *ScratchSpace; + struct sbi_platform *SbiPlatform; + EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext; + + DEBUG((DEBUG_INFO, "%a: Entry, preparing to jump to PEI Core\n\n", __FUNCTION__)); + + SbiScratch = sbi_scratch_thishart_ptr(); + SbiPlatform = (struct sbi_platform *)sbi_platform_ptr(SbiScratch); + FirmwareContext = (EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *)SbiPlatform->firmware_context; + + // + // Print out scratch address of each hart + // + DEBUG ((DEBUG_INFO, "%a: OpenSBI scratch address for each hart:\n", __FUNCTION__)); + for (HartId = 0; HartId < SBI_HARTMASK_MAX_BITS; HartId ++) { + if (sbi_platform_hart_invalid(SbiPlatform, HartId)) { + continue; + } + ScratchSpace = sbi_hartid_to_scratch (HartId); + if(ScratchSpace != NULL) { + DEBUG((DEBUG_INFO, " Hart %d: 0x%x\n", HartId, ScratchSpace)); + } else { + DEBUG((DEBUG_INFO, " Hart %d not initialized yet\n", HartId)); + } + } + + // + // Set firmware context Hart-specific pointer + // + for (HartId = 0; HartId < SBI_HARTMASK_MAX_BITS; HartId ++) { + if (sbi_platform_hart_invalid(SbiPlatform, HartId)) { + continue; + } + ScratchSpace = sbi_hartid_to_scratch (HartId); + if (ScratchSpace != NULL) { + FirmwareContext->HartSpecific[HartId] = + (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UINT8 *)ScratchSpace - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE); + DEBUG ((DEBUG_INFO, "%a: OpenSBI Hart %d Firmware Context Hart-specific at address: 0x%x\n", + __FUNCTION__, + HartId, + FirmwareContext->HartSpecific [HartId] + )); + } + } + + DEBUG((DEBUG_INFO, "%a: Jump to PEI Core with \n", __FUNCTION__)); + DEBUG((DEBUG_INFO, " sbi_scratch = %x\n", SbiScratch)); + DEBUG((DEBUG_INFO, " sbi_platform = %x\n", SbiPlatform)); + DEBUG((DEBUG_INFO, " FirmwareContext = %x\n", FirmwareContext)); + SbiScratch->next_arg1 = (unsigned long)FirmwareContext; + + return 0; +} + /** Transion from SEC phase to PEI phase. This function transits to S-mode PEI phase from M-mode SEC phase. @@ -508,9 +574,7 @@ VOID EFIAPI PeiCore ( 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_scratch *ScratchSpace; struct sbi_platform *ThisSbiPlatform; - UINT32 HartId; FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint); @@ -524,17 +588,6 @@ VOID EFIAPI PeiCore ( SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + (SecCoreData.TemporaryRamSize >> 1); SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1; - // - // Print out scratch address of each hart - // - DEBUG ((DEBUG_INFO, "%a: OpenSBI scratch address for each hart:\n", __FUNCTION__)); - for (HartId = 0; HartId < SBI_HARTMASK_MAX_BITS; HartId ++) { - ScratchSpace = sbi_hartid_to_scratch (HartId); - if(ScratchSpace != NULL) { - DEBUG((DEBUG_INFO, " Hart %d: 0x%x\n", HartId, ScratchSpace)); - } - } - // // Set up OpepSBI firmware context pointer on boot hart OpenSbi scratch. // Firmware context residents in stack and will be switched to memory when @@ -564,20 +617,10 @@ VOID EFIAPI PeiCore ( FirmwareContext.FlattenedDeviceTree = Scratch->next_arg1; // - // Set firmware context Hart-specific pointer + // Transfer the control to the PEI core // - for (HartId = 0; HartId < SBI_HARTMASK_MAX_BITS; HartId ++) { - ScratchSpace = sbi_hartid_to_scratch (HartId); - if (ScratchSpace != NULL) { - FirmwareContext.HartSpecific[HartId] = - (EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *)((UINT8 *)ScratchSpace - FIRMWARE_CONTEXT_HART_SPECIFIC_SIZE); - DEBUG ((DEBUG_INFO, "%a: OpenSBI Hart %d Firmware Context Hart-specific at address: 0x%x\n", - __FUNCTION__, - HartId, - FirmwareContext.HartSpecific [HartId] - )); - } - } + FirmwareContext.SecPeiHandOffData = (UINT64)&SecCoreData; + // // Set supervisor translation mode to Bare mode // @@ -585,13 +628,12 @@ VOID EFIAPI PeiCore ( RiscVSetSupervisorAddressTranslationRegister ((UINT64)RISCV_SATP_MODE_OFF << RISCV_SATP_MODE_BIT_POSITION); // - // Transfer the control to the PEI core + // Scratch->next_arg1 is the device tree. // - Scratch->next_addr = (UINTN)(*PeiCoreEntryPoint); + Scratch->next_addr = (UINTN)(PeiCoreEntryPoint); Scratch->next_mode = PRV_S; DEBUG ((DEBUG_INFO, "%a: Initializing OpenSBI library for booting hart %d\n", __FUNCTION__, BootHartId)); sbi_init(Scratch); - (*PeiCoreEntryPoint) (&SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable); } /** @@ -715,6 +757,7 @@ VOID EFIAPI SecCoreStartUpWithStack( { UINT64 BootHartDoneSbiInit; UINT64 NonBootHartMessageLockValue; + struct sbi_platform *ThisSbiPlatform; EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *HartFirmwareContext; Scratch->next_arg1 = (unsigned long)GetDeviceTreeAddress (); @@ -737,6 +780,14 @@ VOID EFIAPI SecCoreStartUpWithStack( HartFirmwareContext->MachineImplId.Value64_H = 0; HartFirmwareContext->HartSwitchMode = RiscVOpenSbiHartSwitchMode; + // + // Hook platorm_ops with EDK2 one. Thus we can have interface + // call out to OEM EDK2 platform code in M-mode before switching + // to S-mode in opensbo init. + // + ThisSbiPlatform = (struct sbi_platform *)sbi_platform_ptr(Scratch); + ThisSbiPlatform->platform_ops_addr = (unsigned long)&Edk2OpensbiPlatformOps; + if (HartId == FixedPcdGet32(PcdBootHartId)) { LaunchPeiCore (HartId, Scratch); } @@ -768,6 +819,7 @@ VOID EFIAPI SecCoreStartUpWithStack( // Non boot hart wiil be halted waiting for SBI_HART_STARTING. // Use HSM ecall to start non boot hart (SBI_EXT_HSM_HART_START) later on, // + Scratch->next_mode = PRV_S; sbi_init(Scratch); } -- 2.31.1 ^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH 56/79] RISC-V/PlatformPkg: Updates for the latest OpenSBI 2022-01-08 7:24 [PATCH 42/79] RISC-V: Use RISC-V PeiCoreEntryPoint library Abner Chang @ 2022-01-08 7:24 ` Abner Chang 0 siblings, 0 replies; 2+ messages in thread From: Abner Chang @ 2022-01-08 7:24 UTC (permalink / raw) To: devel; +Cc: abner.chang (This is migrated from edk2-platforms:Platform) Code changes to incorporate with OpenSBI commit ID: a731c7e36988c3308e1978ecde491f2f6182d490 Cc: Sunil V L <sunilvl@ventanamicro.com> Cc: Daniel Schaefer <daniel.schaefer@hpe.com> Signed-off-by: Abner Chang <abner.chang@hpe.com> Reviewed-by: Daniel Schaefer <daniel.schaefer@hpe.com> Reviewed-by: Sunil V L <sunilvl@ventanamicro.com> --- .../OpensbiPlatformLib/OpensbiPlatformLib.inf | 10 +- .../PlatformPkg/Universal/Sec/SecMain.inf | 4 + .../Library/OpensbiPlatformLib/Platform.c | 57 ---- .../Universal/Sec/Edk2OpenSbiPlatform.c | 149 --------- .../PlatformPkg/Universal/Sec/SecMain.c | 48 ++- .../Universal/Sec/Riscv64/SecEntry.S | 300 ++++++++++-------- 6 files changed, 212 insertions(+), 356 deletions(-) diff --git a/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf index 909fbffa8d..2e1227733a 100644 --- a/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf +++ b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf @@ -51,12 +51,4 @@ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootableHartNumber gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize - gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdU5UartBase - gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdU5PlatformSystemClock - - gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRootFirmwareDomainBaseAddress - gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRootFirmwareDomainSize - gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFirmwareDomainBaseAddress - gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFirmwareDomainSize - gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFirmwareRegionBaseAddress - gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFirmwareRegionSize + diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf index 1cfbef961f..dd5f01ab4d 100644 --- a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf @@ -66,6 +66,10 @@ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootableHartIndexToId gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRootFirmwareDomainBaseAddress gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRootFirmwareDomainSize + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFirmwareDomainBaseAddress + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFirmwareDomainSize + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFirmwareRegionBaseAddress + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFirmwareRegionSize gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize diff --git a/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/Platform.c b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/Platform.c index b477b81d74..c62d235333 100644 --- a/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/Platform.c +++ b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/Platform.c @@ -197,68 +197,11 @@ static u64 generic_tlbr_flush_limit(void) return SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT; } -static int generic_system_reset_check(u32 reset_type, u32 reset_reason) -{ - if (generic_plat && generic_plat->system_reset_check) - return generic_plat->system_reset_check(reset_type, - reset_reason, - generic_plat_match); - return fdt_system_reset_check(reset_type, reset_reason); -} - -static void generic_system_reset(u32 reset_type, u32 reset_reason) -{ - if (generic_plat && generic_plat->system_reset) { - generic_plat->system_reset(reset_type, reset_reason, - generic_plat_match); - return; - } - - fdt_system_reset(reset_type, reset_reason); -} - -#define EDK2_ROOT_FW_REGION 0 -#define EDK2_FW_REGION 1 -#define EDK2_VARIABLE_REGION 2 -#define EDK2_ALL_REGION 3 -#define EDK2_END_REGION 4 -static struct sbi_domain_memregion root_memregs[EDK2_END_REGION + 1] = { 0 }; - -struct sbi_domain_memregion *get_mem_regions(void) { - /* EDK2 root firmware domain memory region */ - root_memregs[EDK2_ROOT_FW_REGION].order = log2roundup(FixedPcdGet32(PcdRootFirmwareDomainSize)); - root_memregs[EDK2_ROOT_FW_REGION].base = FixedPcdGet32(PcdRootFirmwareDomainBaseAddress); - root_memregs[EDK2_ROOT_FW_REGION].flags = 0; - - /*EDK2 firmware domain memory region */ - root_memregs[EDK2_FW_REGION].order = log2roundup(FixedPcdGet32(PcdFirmwareDomainSize)); - root_memregs[EDK2_FW_REGION].base = FixedPcdGet32(PcdFirmwareDomainBaseAddress); - root_memregs[EDK2_FW_REGION].flags = SBI_DOMAIN_MEMREGION_EXECUTABLE | SBI_DOMAIN_MEMREGION_READABLE; - - /*EDK2 firmware domain memory region */ - root_memregs[EDK2_VARIABLE_REGION].order = log2roundup(FixedPcdGet32(PcdVariableFirmwareRegionSize)); - root_memregs[EDK2_VARIABLE_REGION].base = FixedPcdGet32(PcdVariableFirmwareRegionBaseAddress); - root_memregs[EDK2_VARIABLE_REGION].flags = SBI_DOMAIN_MEMREGION_READABLE | SBI_DOMAIN_MEMREGION_WRITEABLE; - - /* EDK2 domain allow everything memory region */ - root_memregs[EDK2_ALL_REGION].order = __riscv_xlen; - root_memregs[EDK2_ALL_REGION].base = 0; - root_memregs[EDK2_ALL_REGION].flags = (SBI_DOMAIN_MEMREGION_READABLE | - SBI_DOMAIN_MEMREGION_WRITEABLE | - SBI_DOMAIN_MEMREGION_EXECUTABLE); - - /* EDK2 domain memory region end */ - root_memregs[EDK2_END_REGION].order = 0; - - return root_memregs; -} - const struct sbi_platform_operations platform_ops = { .early_init = generic_early_init, .final_init = generic_final_init, .early_exit = generic_early_exit, .final_exit = generic_final_exit, - .domains_root_regions = get_mem_regions, .domains_init = generic_domains_init, .console_init = fdt_serial_init, .irqchip_init = fdt_irqchip_init, diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/Edk2OpenSbiPlatform.c b/Platform/RISC-V/PlatformPkg/Universal/Sec/Edk2OpenSbiPlatform.c index 79b2f33675..779705489c 100644 --- a/Platform/RISC-V/PlatformPkg/Universal/Sec/Edk2OpenSbiPlatform.c +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/Edk2OpenSbiPlatform.c @@ -117,18 +117,6 @@ int Edk2OpensbiPlatforMMISAGetXLEN (VOID) return 0; } -/** Get platform specific root domain memory regions */ -struct sbi_domain_memregion * -Edk2OpensbiPlatformGetMemRegions (VOID) -{ - DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); - - if (platform_ops.domains_root_regions) { - return platform_ops.domains_root_regions (); - } - return 0; -} - /** Initialize (or populate) domains for the platform */ int Edk2OpensbiPlatformDomainsInit (VOID) { @@ -140,25 +128,6 @@ int Edk2OpensbiPlatformDomainsInit (VOID) return 0; } -/** Write a character to the platform console output */ -VOID Edk2OpensbiPlatformSerialPutc ( - CHAR8 Ch - ) -{ - if (platform_ops.console_putc) { - return platform_ops.console_putc (Ch); - } -} - -/** Read a character from the platform console input */ -int Edk2OpensbiPlatformSerialGetc (VOID) -{ - if (platform_ops.console_getc) { - return platform_ops.console_getc (); - } - return 0; -} - /** Initialize the platform console */ int Edk2OpensbiPlatformSerialInit (VOID) { @@ -193,30 +162,6 @@ VOID Edk2OpensbiPlatformIrqchipExit (VOID) } } -/** Send IPI to a target HART */ -VOID Edk2OpensbiPlatformIpiSend ( - UINT32 TargetHart - ) -{ - DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); - - if (platform_ops.ipi_send) { - return platform_ops.ipi_send (TargetHart); - } -} - -/** Clear IPI for a target HART */ -VOID Edk2OpensbiPlatformIpiClear ( - UINT32 TargetHart - ) -{ - DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); - - if (platform_ops.ipi_clear) { - return platform_ops.ipi_clear (TargetHart); - } -} - /** Initialize IPI for current HART */ int Edk2OpensbiPlatformIpiInit ( BOOLEAN ColdBoot @@ -251,33 +196,6 @@ UINT64 Edk2OpensbiPlatformTlbrFlushLimit (VOID) return 0; } -/** Get platform timer value */ -UINT64 Edk2OpensbiPlatformTimerValue (VOID) -{ - if (platform_ops.timer_value) { - return platform_ops.timer_value (); - } - return 0; -} - -/** Start platform timer event for current HART */ -VOID Edk2OpensbiPlatformTimerEventStart ( - UINT64 NextEvent - ) -{ - if (platform_ops.timer_event_start) { - return platform_ops.timer_event_start (NextEvent); - } -} - -/** Stop platform timer event for current HART */ -VOID Edk2OpensbiPlatformTimerEventStop (VOID) -{ - if (platform_ops.timer_event_stop) { - return platform_ops.timer_event_stop (); - } -} - /** Initialize platform timer for current HART */ int Edk2OpensbiPlatformTimerInit ( BOOLEAN ColdBoot @@ -301,61 +219,6 @@ VOID Edk2OpensbiPlatformTimerExit (VOID) } } -/** Bringup the given hart */ -int Edk2OpensbiPlatformHartStart ( - UINT32 HartId, - ulong Saddr - ) -{ - DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); - - if (platform_ops.hart_start) { - return platform_ops.hart_start (HartId, Saddr); - } - return 0; -} -/** - Stop the current hart from running. This call doesn't expect to - return if success. -**/ -int Edk2OpensbiPlatformHartStop (VOID) -{ - DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); - - if (platform_ops.hart_stop) { - return platform_ops.hart_stop (); - } - return 0; -} - -/** - Check whether reset type and reason supported by the platform* - -**/ -int Edk2OpensbiPlatformSystemResetCheck ( - UINT32 ResetType, - UINT32 ResetReason - ) -{ - if (platform_ops.system_reset_check) { - return platform_ops.system_reset_check (ResetType, ResetReason); - } - return 0; -} - -/** Reset the platform */ -VOID Edk2OpensbiPlatformSystemReset ( - UINT32 ResetType, - UINT32 ResetReason - ) -{ - DEBUG((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); - - if (platform_ops.system_reset) { - return platform_ops.system_reset (ResetType, ResetReason); - } -} - /** platform specific SBI extension implementation probe function */ int Edk2OpensbiPlatformVendorExtCheck ( long ExtId @@ -400,27 +263,15 @@ const struct sbi_platform_operations Edk2OpensbiPlatformOps = { .final_exit = Edk2OpensbiPlatformFinalExit, .misa_check_extension = Edk2OpensbiPlatforMMISACheckExtension, .misa_get_xlen = Edk2OpensbiPlatforMMISAGetXLEN, - .domains_root_regions = Edk2OpensbiPlatformGetMemRegions, .domains_init = Edk2OpensbiPlatformDomainsInit, - .console_putc = Edk2OpensbiPlatformSerialPutc, - .console_getc = Edk2OpensbiPlatformSerialGetc, .console_init = Edk2OpensbiPlatformSerialInit, .irqchip_init = Edk2OpensbiPlatformIrqchipInit, .irqchip_exit = Edk2OpensbiPlatformIrqchipExit, - .ipi_send = Edk2OpensbiPlatformIpiSend, - .ipi_clear = Edk2OpensbiPlatformIpiClear, .ipi_init = Edk2OpensbiPlatformIpiInit, .ipi_exit = Edk2OpensbiPlatformIpiExit, .get_tlbr_flush_limit = Edk2OpensbiPlatformTlbrFlushLimit, - .timer_value = Edk2OpensbiPlatformTimerValue, - .timer_event_stop = Edk2OpensbiPlatformTimerEventStop, - .timer_event_start = Edk2OpensbiPlatformTimerEventStart, .timer_init = Edk2OpensbiPlatformTimerInit, .timer_exit = Edk2OpensbiPlatformTimerExit, - .hart_start = Edk2OpensbiPlatformHartStart, - .hart_stop = Edk2OpensbiPlatformHartStop, - .system_reset_check = Edk2OpensbiPlatformSystemResetCheck, - .system_reset = Edk2OpensbiPlatformSystemReset, .vendor_ext_check = Edk2OpensbiPlatformVendorExtCheck, .vendor_ext_provider = Edk2OpensbiPlatformVendorExtProvider, }; diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c index 93ff8a598d..3bc3690047 100644 --- a/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.c @@ -15,10 +15,12 @@ #include <sbi/riscv_asm.h> #include <sbi/riscv_atomic.h> #include <sbi/sbi_console.h> // Reference to header file in opensbi +#include <sbi/sbi_domain.h> #include <sbi/sbi_hart.h> // Reference to header file in opensbi -#include <sbi/sbi_hartmask.h> // Reference to header file in opensbi +#include <sbi/sbi_hartmask.h> // Reference to header file in opensbi #include <sbi/sbi_scratch.h> // Reference to header file in opensbi #include <sbi/sbi_platform.h> // Reference to header file in opensbi +#include <sbi/sbi_math.h> // Reference to header file in opensbi #include <sbi/sbi_init.h> // Reference to header file in opensbi #include <sbi/sbi_ecall.h> // Reference to header file in opensbi #include <sbi/sbi_trap.h> // Reference to header file in opensbi @@ -31,8 +33,41 @@ extern struct sbi_platform_operations Edk2OpensbiPlatformOps; atomic_t BootHartDone = ATOMIC_INITIALIZER(0); atomic_t NonBootHartMessageLock = ATOMIC_INITIALIZER(0); +int sbi_domain_root_add_memregion(const struct sbi_domain_memregion *reg); + typedef struct sbi_scratch *(*hartid2scratch)(ulong hartid, ulong hartindex); +struct sbi_domain_memregion fw_memregs; + +int SecSetEdk2FwMemoryRegions (VOID) { + int Ret; + + Ret = 0; + + // + // EDK2 PEI domain memory region + // + fw_memregs.order = log2roundup(FixedPcdGet32(PcdFirmwareDomainSize)); + fw_memregs.base = FixedPcdGet32(PcdFirmwareDomainBaseAddress); + fw_memregs.flags = SBI_DOMAIN_MEMREGION_EXECUTABLE | SBI_DOMAIN_MEMREGION_READABLE; + Ret = sbi_domain_root_add_memregion ((const struct sbi_domain_memregion *)&fw_memregs); + if (Ret != 0) { + DEBUG ((DEBUG_ERROR, "%a: Add firmware regiosn of FW Domain fail\n", __FUNCTION__)); + } + + // + // EDK2 EFI Variable domain memory region + // + fw_memregs.order = log2roundup(FixedPcdGet32(PcdVariableFirmwareRegionSize)); + fw_memregs.base = FixedPcdGet32(PcdVariableFirmwareRegionBaseAddress); + fw_memregs.flags = SBI_DOMAIN_MEMREGION_READABLE | SBI_DOMAIN_MEMREGION_WRITEABLE; + Ret = sbi_domain_root_add_memregion ((const struct sbi_domain_memregion *)&fw_memregs); + if (Ret != 0) { + DEBUG ((DEBUG_ERROR, "%a: Add firmware regiosn of variable FW Domain fail\n", __FUNCTION__)); + } + return Ret; +} + /** Locates a section within a series of sections with the specified section type. @@ -405,6 +440,13 @@ SecPostOpenSbiPlatformEarlylInit( DEBUG ((DEBUG_INFO, "%a: Non boot hart %d.\n", __FUNCTION__, HartId)); return 0; } + // + // Setup firmware memory region. + // + if (SecSetEdk2FwMemoryRegions () != 0) { + ASSERT (FALSE); + } + // // Boot HART is already in the process of OpenSBI initialization. // We can let other HART to keep booting. @@ -477,7 +519,7 @@ SecPostOpenSbiPlatformFinalInit ( } } - DEBUG((DEBUG_INFO, "%a: Jump to PEI Core with \n", __FUNCTION__)); + DEBUG((DEBUG_INFO, "%a: Will jump to PEI Core in OpenSBI with \n", __FUNCTION__)); DEBUG((DEBUG_INFO, " sbi_scratch = %x\n", SbiScratch)); DEBUG((DEBUG_INFO, " sbi_platform = %x\n", SbiPlatform)); DEBUG((DEBUG_INFO, " FirmwareContext = %x\n", FirmwareContext)); @@ -793,7 +835,7 @@ VOID EFIAPI SecCoreStartUpWithStack( sbi_init(Scratch); } -void OpensbiDebugPrint (char *debugstr, ...) +VOID OpensbiDebugPrint (CHAR8 *debugstr, ...) { VA_LIST Marker; diff --git a/Platform/RISC-V/PlatformPkg/Universal/Sec/Riscv64/SecEntry.S b/Platform/RISC-V/PlatformPkg/Universal/Sec/Riscv64/SecEntry.S index f0c3dff0d9..96087738a3 100644 --- a/Platform/RISC-V/PlatformPkg/Universal/Sec/Riscv64/SecEntry.S +++ b/Platform/RISC-V/PlatformPkg/Universal/Sec/Riscv64/SecEntry.S @@ -18,6 +18,12 @@ #include <SecMain.h> +.macro MOV_3R __d0, __s0, __d1, __s1, __d2, __s2 + add \__d0, \__s0, zero + add \__d1, \__s1, zero + add \__d2, \__s2, zero +.endm + .text .align 3 @@ -90,7 +96,11 @@ _scratch_init: la a4, _hartid_to_scratch sd a4, SBI_SCRATCH_HARTID_TO_SCRATCH_OFFSET(tp) /* Save _hartid_to_scratch function in scratch buffer*/ sd zero, SBI_SCRATCH_TMP0_OFFSET(tp) - + /* Store trap-exit function address in scratch space */ + lla a4, _trap_exit + sd a4, SBI_SCRATCH_TRAP_EXIT_OFFSET(tp) + /* Clear tmp0 in scratch space */ + sd zero, SBI_SCRATCH_TMP0_OFFSET(tp) #ifdef FW_OPTIONS li a4, FW_OPTIONS sd a4, SBI_SCRATCH_OPTIONS_OFFSET(tp) @@ -322,160 +332,174 @@ _uninitialized_hart_wait: wfi j _uninitialized_hart_wait - .align 3 - .section .entry, "ax", %progbits - .align 3 - .globl _trap_handler -_trap_handler: - +.macro TRAP_SAVE_AND_SETUP_SP_T0 /* Swap TP and MSCRATCH */ - csrrw tp, CSR_MSCRATCH, tp + csrrw tp, CSR_MSCRATCH, tp /* Save T0 in scratch space */ - REG_S t0, SBI_SCRATCH_TMP0_OFFSET(tp) + REG_S 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 */ - REG_S t0, SBI_TRAP_REGS_OFFSET(sp)(sp) + /* + * Set T0 to appropriate exception stack + * + * Came_From_M_Mode = ((MSTATUS.MPP < PRV_M) ? 1 : 0) - 1; + * Exception_Stack = TP ^ (Came_From_M_Mode & (SP ^ TP)) + * + * Came_From_M_Mode = 0 ==> Exception_Stack = TP + * Came_From_M_Mode = -1 ==> Exception_Stack = SP + */ + csrr t0, CSR_MSTATUS + srl t0, t0, MSTATUS_MPP_SHIFT + and t0, t0, PRV_M + slti t0, t0, PRV_M + add t0, t0, -1 + xor sp, sp, tp + and t0, t0, sp + xor sp, sp, tp + xor t0, tp, t0 + + /* Save original SP on exception stack */ + REG_S sp, (SBI_TRAP_REGS_OFFSET(sp) - SBI_TRAP_REGS_SIZE)(t0) + + /* Set SP to exception stack and make room for trap registers */ + add sp, t0, -(SBI_TRAP_REGS_SIZE) /* Restore T0 from scratch space */ - REG_L t0, SBI_SCRATCH_TMP0_OFFSET(tp) + REG_L t0, SBI_SCRATCH_TMP0_OFFSET(tp) /* Save T0 on stack */ - REG_S t0, SBI_TRAP_REGS_OFFSET(t0)(sp) + REG_S t0, SBI_TRAP_REGS_OFFSET(t0)(sp) /* Swap TP and MSCRATCH */ - csrrw tp, CSR_MSCRATCH, tp + csrrw tp, CSR_MSCRATCH, tp +.endm +.macro TRAP_SAVE_MEPC_MSTATUS have_mstatush /* Save MEPC and MSTATUS CSRs */ - csrr t0, CSR_MEPC - REG_S t0, SBI_TRAP_REGS_OFFSET(mepc)(sp) - csrr t0, CSR_MSTATUS - REG_S t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp) - REG_S zero, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) -#if __riscv_xlen == 32 - csrr t0, CSR_MISA - srli t0, t0, ('H' - 'A') - andi t0, t0, 0x1 - beq t0, zero, _skip_mstatush_save - csrr t0, CSR_MSTATUSH - REG_S t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) -_skip_mstatush_save: -#endif + csrr t0, CSR_MEPC + REG_S t0, SBI_TRAP_REGS_OFFSET(mepc)(sp) + csrr t0, CSR_MSTATUS + REG_S t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp) +.if \have_mstatush + csrr t0, CSR_MSTATUSH + REG_S t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) +.else + REG_S zero, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) +.endif +.endm + +.macro TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0 + /* Save all general regisers except SP and T0 */ + REG_S zero, SBI_TRAP_REGS_OFFSET(zero)(sp) + REG_S ra, SBI_TRAP_REGS_OFFSET(ra)(sp) + REG_S gp, SBI_TRAP_REGS_OFFSET(gp)(sp) + REG_S tp, SBI_TRAP_REGS_OFFSET(tp)(sp) + REG_S t1, SBI_TRAP_REGS_OFFSET(t1)(sp) + REG_S t2, SBI_TRAP_REGS_OFFSET(t2)(sp) + REG_S s0, SBI_TRAP_REGS_OFFSET(s0)(sp) + REG_S s1, SBI_TRAP_REGS_OFFSET(s1)(sp) + REG_S a0, SBI_TRAP_REGS_OFFSET(a0)(sp) + REG_S a1, SBI_TRAP_REGS_OFFSET(a1)(sp) + REG_S a2, SBI_TRAP_REGS_OFFSET(a2)(sp) + REG_S a3, SBI_TRAP_REGS_OFFSET(a3)(sp) + REG_S a4, SBI_TRAP_REGS_OFFSET(a4)(sp) + REG_S a5, SBI_TRAP_REGS_OFFSET(a5)(sp) + REG_S a6, SBI_TRAP_REGS_OFFSET(a6)(sp) + REG_S a7, SBI_TRAP_REGS_OFFSET(a7)(sp) + REG_S s2, SBI_TRAP_REGS_OFFSET(s2)(sp) + REG_S s3, SBI_TRAP_REGS_OFFSET(s3)(sp) + REG_S s4, SBI_TRAP_REGS_OFFSET(s4)(sp) + REG_S s5, SBI_TRAP_REGS_OFFSET(s5)(sp) + REG_S s6, SBI_TRAP_REGS_OFFSET(s6)(sp) + REG_S s7, SBI_TRAP_REGS_OFFSET(s7)(sp) + REG_S s8, SBI_TRAP_REGS_OFFSET(s8)(sp) + REG_S s9, SBI_TRAP_REGS_OFFSET(s9)(sp) + REG_S s10, SBI_TRAP_REGS_OFFSET(s10)(sp) + REG_S s11, SBI_TRAP_REGS_OFFSET(s11)(sp) + REG_S t3, SBI_TRAP_REGS_OFFSET(t3)(sp) + REG_S t4, SBI_TRAP_REGS_OFFSET(t4)(sp) + REG_S t5, SBI_TRAP_REGS_OFFSET(t5)(sp) + REG_S t6, SBI_TRAP_REGS_OFFSET(t6)(sp) +.endm + +.macro TRAP_CALL_C_ROUTINE + /* Call C routine */ + add a0, sp, zero + call sbi_trap_handler +.endm + +.macro TRAP_RESTORE_GENERAL_REGS_EXCEPT_A0_T0 + /* Restore all general regisers except A0 and T0 */ + REG_L ra, SBI_TRAP_REGS_OFFSET(ra)(a0) + REG_L sp, SBI_TRAP_REGS_OFFSET(sp)(a0) + REG_L gp, SBI_TRAP_REGS_OFFSET(gp)(a0) + REG_L tp, SBI_TRAP_REGS_OFFSET(tp)(a0) + REG_L t1, SBI_TRAP_REGS_OFFSET(t1)(a0) + REG_L t2, SBI_TRAP_REGS_OFFSET(t2)(a0) + REG_L s0, SBI_TRAP_REGS_OFFSET(s0)(a0) + REG_L s1, SBI_TRAP_REGS_OFFSET(s1)(a0) + REG_L a1, SBI_TRAP_REGS_OFFSET(a1)(a0) + REG_L a2, SBI_TRAP_REGS_OFFSET(a2)(a0) + REG_L a3, SBI_TRAP_REGS_OFFSET(a3)(a0) + REG_L a4, SBI_TRAP_REGS_OFFSET(a4)(a0) + REG_L a5, SBI_TRAP_REGS_OFFSET(a5)(a0) + REG_L a6, SBI_TRAP_REGS_OFFSET(a6)(a0) + REG_L a7, SBI_TRAP_REGS_OFFSET(a7)(a0) + REG_L s2, SBI_TRAP_REGS_OFFSET(s2)(a0) + REG_L s3, SBI_TRAP_REGS_OFFSET(s3)(a0) + REG_L s4, SBI_TRAP_REGS_OFFSET(s4)(a0) + REG_L s5, SBI_TRAP_REGS_OFFSET(s5)(a0) + REG_L s6, SBI_TRAP_REGS_OFFSET(s6)(a0) + REG_L s7, SBI_TRAP_REGS_OFFSET(s7)(a0) + REG_L s8, SBI_TRAP_REGS_OFFSET(s8)(a0) + REG_L s9, SBI_TRAP_REGS_OFFSET(s9)(a0) + REG_L s10, SBI_TRAP_REGS_OFFSET(s10)(a0) + REG_L s11, SBI_TRAP_REGS_OFFSET(s11)(a0) + REG_L t3, SBI_TRAP_REGS_OFFSET(t3)(a0) + REG_L t4, SBI_TRAP_REGS_OFFSET(t4)(a0) + REG_L t5, SBI_TRAP_REGS_OFFSET(t5)(a0) + REG_L t6, SBI_TRAP_REGS_OFFSET(t6)(a0) +.endm + +.macro TRAP_RESTORE_MEPC_MSTATUS have_mstatush + /* Restore MEPC and MSTATUS CSRs */ + REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(a0) + csrw CSR_MEPC, t0 + REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(a0) + csrw CSR_MSTATUS, t0 +.if \have_mstatush + REG_L t0, SBI_TRAP_REGS_OFFSET(mstatusH)(a0) + csrw CSR_MSTATUSH, t0 +.endif +.endm + +.macro TRAP_RESTORE_A0_T0 + /* Restore T0 */ + REG_L t0, SBI_TRAP_REGS_OFFSET(t0)(a0) - /* Save all general registers except SP and T0 */ - REG_S zero, SBI_TRAP_REGS_OFFSET(zero)(sp) - REG_S ra, SBI_TRAP_REGS_OFFSET(ra)(sp) - REG_S gp, SBI_TRAP_REGS_OFFSET(gp)(sp) - REG_S tp, SBI_TRAP_REGS_OFFSET(tp)(sp) - REG_S t1, SBI_TRAP_REGS_OFFSET(t1)(sp) - REG_S t2, SBI_TRAP_REGS_OFFSET(t2)(sp) - REG_S s0, SBI_TRAP_REGS_OFFSET(s0)(sp) - REG_S s1, SBI_TRAP_REGS_OFFSET(s1)(sp) - REG_S a0, SBI_TRAP_REGS_OFFSET(a0)(sp) - REG_S a1, SBI_TRAP_REGS_OFFSET(a1)(sp) - REG_S a2, SBI_TRAP_REGS_OFFSET(a2)(sp) - REG_S a3, SBI_TRAP_REGS_OFFSET(a3)(sp) - REG_S a4, SBI_TRAP_REGS_OFFSET(a4)(sp) - REG_S a5, SBI_TRAP_REGS_OFFSET(a5)(sp) - REG_S a6, SBI_TRAP_REGS_OFFSET(a6)(sp) - REG_S a7, SBI_TRAP_REGS_OFFSET(a7)(sp) - REG_S s2, SBI_TRAP_REGS_OFFSET(s2)(sp) - REG_S s3, SBI_TRAP_REGS_OFFSET(s3)(sp) - REG_S s4, SBI_TRAP_REGS_OFFSET(s4)(sp) - REG_S s5, SBI_TRAP_REGS_OFFSET(s5)(sp) - REG_S s6, SBI_TRAP_REGS_OFFSET(s6)(sp) - REG_S s7, SBI_TRAP_REGS_OFFSET(s7)(sp) - REG_S s8, SBI_TRAP_REGS_OFFSET(s8)(sp) - REG_S s9, SBI_TRAP_REGS_OFFSET(s9)(sp) - REG_S s10, SBI_TRAP_REGS_OFFSET(s10)(sp) - REG_S s11, SBI_TRAP_REGS_OFFSET(s11)(sp) - REG_S t3, SBI_TRAP_REGS_OFFSET(t3)(sp) - REG_S t4, SBI_TRAP_REGS_OFFSET(t4)(sp) - REG_S t5, SBI_TRAP_REGS_OFFSET(t5)(sp) - REG_S t6, SBI_TRAP_REGS_OFFSET(t6)(sp) + /* Restore A0 */ + REG_L a0, SBI_TRAP_REGS_OFFSET(a0)(a0) +.endm - /* Call C routine */ - add a0, sp, zero - call sbi_trap_handler - - /* Restore all general registers except SP and T0 */ - REG_L ra, SBI_TRAP_REGS_OFFSET(ra)(sp) - REG_L gp, SBI_TRAP_REGS_OFFSET(gp)(sp) - REG_L tp, SBI_TRAP_REGS_OFFSET(tp)(sp) - REG_L t1, SBI_TRAP_REGS_OFFSET(t1)(sp) - REG_L t2, SBI_TRAP_REGS_OFFSET(t2)(sp) - REG_L s0, SBI_TRAP_REGS_OFFSET(s0)(sp) - REG_L s1, SBI_TRAP_REGS_OFFSET(s1)(sp) - REG_L a0, SBI_TRAP_REGS_OFFSET(a0)(sp) - REG_L a1, SBI_TRAP_REGS_OFFSET(a1)(sp) - REG_L a2, SBI_TRAP_REGS_OFFSET(a2)(sp) - REG_L a3, SBI_TRAP_REGS_OFFSET(a3)(sp) - REG_L a4, SBI_TRAP_REGS_OFFSET(a4)(sp) - REG_L a5, SBI_TRAP_REGS_OFFSET(a5)(sp) - REG_L a6, SBI_TRAP_REGS_OFFSET(a6)(sp) - REG_L a7, SBI_TRAP_REGS_OFFSET(a7)(sp) - REG_L s2, SBI_TRAP_REGS_OFFSET(s2)(sp) - REG_L s3, SBI_TRAP_REGS_OFFSET(s3)(sp) - REG_L s4, SBI_TRAP_REGS_OFFSET(s4)(sp) - REG_L s5, SBI_TRAP_REGS_OFFSET(s5)(sp) - REG_L s6, SBI_TRAP_REGS_OFFSET(s6)(sp) - REG_L s7, SBI_TRAP_REGS_OFFSET(s7)(sp) - REG_L s8, SBI_TRAP_REGS_OFFSET(s8)(sp) - REG_L s9, SBI_TRAP_REGS_OFFSET(s9)(sp) - REG_L s10, SBI_TRAP_REGS_OFFSET(s10)(sp) - REG_L s11, SBI_TRAP_REGS_OFFSET(s11)(sp) - REG_L t3, SBI_TRAP_REGS_OFFSET(t3)(sp) - REG_L t4, SBI_TRAP_REGS_OFFSET(t4)(sp) - REG_L t5, SBI_TRAP_REGS_OFFSET(t5)(sp) - REG_L t6, SBI_TRAP_REGS_OFFSET(t6)(sp) + .section .entry, "ax", %progbits + .align 3 + .globl _trap_handler + .globl _trap_exit +_trap_handler: + TRAP_SAVE_AND_SETUP_SP_T0 - /* Restore MEPC and MSTATUS CSRs */ - REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(sp) - csrw CSR_MEPC, t0 - REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp) - csrw CSR_MSTATUS, t0 -#if __riscv_xlen == 32 - csrr t0, CSR_MISA - srli t0, t0, ('H' - 'A') - andi t0, t0, 0x1 - beq t0, zero, _skip_mstatush_restore - REG_L t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) - csrw CSR_MSTATUSH, t0 -_skip_mstatush_restore: -#endif + TRAP_SAVE_MEPC_MSTATUS 0 - /* Restore T0 */ - REG_L t0, SBI_TRAP_REGS_OFFSET(t0)(sp) + TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0 + + TRAP_CALL_C_ROUTINE + +_trap_exit: + TRAP_RESTORE_GENERAL_REGS_EXCEPT_A0_T0 + + TRAP_RESTORE_MEPC_MSTATUS 0 - /* Restore SP */ - REG_L sp, SBI_TRAP_REGS_OFFSET(sp)(sp) + TRAP_RESTORE_A0_T0 mret -- 2.31.1 ^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-01-08 8:26 UTC | newest] Thread overview: 2+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <20220108044518.16375-1-abner.chang@hpe.com> 2022-01-08 4:45 ` [PATCH 56/79] RISC-V/PlatformPkg: Updates for the latest OpenSBI Abner Chang 2022-01-08 7:24 [PATCH 42/79] RISC-V: Use RISC-V PeiCoreEntryPoint library Abner Chang 2022-01-08 7:24 ` [PATCH 56/79] RISC-V/PlatformPkg: Updates for the latest OpenSBI Abner Chang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox