blob: dd74c6b296f64574817465779cd0a2ea6e372979 [file] [log] [blame]
#------------------------------------------------------------------------------
#
# Start for Loongson LoongArch processor
#
# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
# @par Glossary:
# - CSR - CPU Status Register
# - EBASE - Exception Base Address
#------------------------------------------------------------------------------
#ifndef __ASSEMBLY__
#define __ASSEMBLY__
#endif
#include <Library/BaseMemoryLib.h>
#include <Register/LoongArch64/Csr.h>
#include <Protocol/DebugSupport.h>
#define BOOTCORE_ID 0
//
// For coding convenience, define the maximum valid
// LoongArch exception.
// Since UEFI V2.11, it will be present in DebugSupport.h.
//
#define MAX_LOONGARCH_EXCEPTION 64
ASM_GLOBAL ASM_PFX(_ModuleEntryPoint)
ASM_PFX(_ModuleEntryPoint):
/* Disable global interrupt */
bl DisableInterrupts
/* Disable all local interrupt */
li.w $a0, 0x1FFF
bl DisableLocalInterrupts
/* Read physical cpu number id */
bl GetApicId
li.d $t0, BOOTCORE_ID //0
bne $a0, $t0, SlaveMain
/* Set BSP stack */
li.d $t0, FixedPcdGet64(PcdOvmfSecPeiTempRamBase) + FixedPcdGet32(PcdOvmfSecPeiTempRamSize) # stack base
move $sp, $t0
addi.d $sp, $sp, -0x8
/* Load the exception vector base address */
li.d $s0, FixedPcdGet64(PcdLoongArchExceptionVectorBaseAddress)
/* Construct SEC and PEI step exception environment */
la.pcrel $a1, ExceptionEntryStart
la.pcrel $t0, ExceptionEntryEnd
sub.d $a2, $t0, $a1
li.w $t0, (MAX_LOONGARCH_EXCEPTION + MAX_LOONGARCH_INTERRUPT) * 512
bgeu $a2, $t0, DeadLoop
move $a0, $s0
bl CopyMem
/* Configure BSP reset ebase */
move $a0, $s0
bl SetExceptionBaseAddress
CallEntry:
/* Call C function make sure parameter true */
li.d $a0, FixedPcdGet64(PcdOvmfFdBaseAddress) # FW base
addi.d $a1, $sp, 0x8
bl SecCoreStartupWithStack
# End of _ModuleEntryPoint
ASM_PFX(ClearMailBox):
/* Clear mailbox */
li.d $t1, LOONGARCH_IOCSR_MBUF3
iocsrwr.d $zero, $t1
li.d $t1, LOONGARCH_IOCSR_MBUF2
iocsrwr.d $zero, $t1
li.d $t1, LOONGARCH_IOCSR_MBUF1
iocsrwr.d $zero, $t1
li.d $t1, LOONGARCH_IOCSR_MBUF0
iocsrwr.d $zero, $t1
jirl $zero, $ra, 0
# End of ClearMailBox
ASM_PFX(EnableIPI):
/* Enable IPI interrupt */
li.w $t1, BIT12
csrxchg $t1, $t1, LOONGARCH_CSR_ECFG
li.w $t2, 0xFFFFFFFFU
li.d $t1, LOONGARCH_IOCSR_IPI_EN
iocsrwr.w $t2, $t1
jirl $zero, $ra, 0
# End of EeableIPI
#/**
# Get APIC ID for every CPU.
#
# @param NULL
# @return APICID
#
# UINTN
# EFI_API
# GetApicId (
# VOID
# )
#**/
ASM_PFX(GetApicId):
csrrd $a0, LOONGARCH_CSR_CPUNUM
andi $a0, $a0, 0x3ff
jirl $zero, $ra, 0
# End of GetApicId
ASM_PFX(ApInitStack):
li.d $t1, SIZE_1KB
csrrd $t0, LOONGARCH_CSR_TMID
mul.d $t1, $t0, $t1
li.d $t2, FixedPcdGet32(PcdCpuMaxLogicalProcessorNumber)
bgeu $t0, $t2, DeadLoop
li.d $t0, FixedPcdGet64(PcdOvmfSecPeiTempRamBase) + FixedPcdGet32(PcdOvmfSecPeiTempRamSize) - SIZE_64KB
sub.d $sp, $t0, $t1
addi.d $sp, $sp, -0x8
jirl $zero, $ra, 0
# End of ApInitStack
ASM_PFX(SlaveMain):
/* Set AP exception handle in flash */
la.pcrel $a0, ApException
bl SetExceptionBaseAddress
/* Clean up local mail box and open INT */
bl ClearMailBox
bl EnableIPI
bl EnableInterrupts
WaitForWake:
/* Wait for wakeup */
bl CpuSleep
b WaitForWake
# End of SlaveMain
.align 12
ASM_PFX(ApException):
csrrd $t0, LOONGARCH_CSR_ESTAT
srli.d $t0, $t0, 12
andi $t0, $t0, 0x1
beqz $t0, DeadLoop
li.d $t0, LOONGARCH_IOCSR_IPI_STATUS
iocsrrd.w $t1, $t0
li.d $t0, LOONGARCH_IOCSR_IPI_CLEAR
iocsrwr.w $t1, $t0
/* Read mail buf and jump to specified entry */
li.d $t1, LOONGARCH_IOCSR_MBUF0
iocsrrd.d $t0, $t1
beqz $t0, OutOfException
csrwr $t0, LOONGARCH_CSR_ERA
li.d $t0, LOONGARCH_IOCSR_MBUF3
iocsrrd.d $a1, $t0
bl ClearMailBox
beqz $a1, NoParameterCall
//
// If the parameters are not NULL, then calling happened in FW ENV.
// Set the EBASE to be the same as BSP.
//
li.d $a0, FixedPcdGet64(PcdLoongArchExceptionVectorBaseAddress)
bl SetExceptionBaseAddress
bl ApInitStack
bl GetApicId
b OutOfException
NoParameterCall:
li.w $t0, BIT2 // IE
csrxchg $zero, $t0, LOONGARCH_CSR_PRMD // Clean PIE
OutOfException:
ertn
# End of ApException
ASM_PFX(DeadLoop):
b DeadLoop
# End of DeadLoop
.end