VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/Library/CpuExceptionHandlerLib/LoongArch/DxeExceptionLib.c

最後變更 在這個檔案是 105670,由 vboxsync 提交於 8 月 前

Devices/EFI/FirmwareNew: Merge edk2-stable-202405 and make it build on aarch64, bugref:4643

  • 屬性 svn:eol-style 設為 native
檔案大小: 6.5 KB
 
1/** @file DxeExceptionLib.c
2
3 LoongArch exception library implemenation for DXE modules.
4
5 Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8**/
9
10#include <Library/BaseLib.h>
11#include <Library/CpuExceptionHandlerLib.h>
12#include <Library/CpuLib.h>
13#include <Library/CacheMaintenanceLib.h>
14#include <Library/DebugLib.h>
15#include <Library/SerialPortLib.h>
16#include <Protocol/DebugSupport.h>
17#include <Register/LoongArch64/Csr.h>
18
19#include "ExceptionCommon.h"
20
21EFI_EXCEPTION_CALLBACK ExternalInterruptHandler[MAX_LOONGARCH_INTERRUPT + 1] = { 0 };
22EFI_EXCEPTION_CALLBACK ExceptionHandler[MAX_LOONGARCH_EXCEPTION + 1] = { 0 };
23
24/**
25 Registers a function to be called from the processor interrupt or exception handler.
26
27 This function registers and enables the handler specified by InterruptHandler for a processor
28 interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the
29 handler for the processor interrupt or exception type specified by InterruptType is uninstalled.
30 The installed handler is called once for each processor interrupt or exception.
31
32 @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts
33 are enabled and FALSE if interrupts are disabled.
34 @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called
35 when a processor interrupt occurs. If this parameter is NULL, then the handler
36 will be uninstalled.
37
38 @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
39 @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was
40 previously installed.
41 @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not
42 previously installed.
43 @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
44
45**/
46EFI_STATUS
47RegisterCpuInterruptHandler (
48 IN EFI_EXCEPTION_TYPE InterruptType,
49 IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
50 )
51{
52 EFI_EXCEPTION_TYPE ExceptionType;
53
54 ExceptionType = InterruptType & CSR_ESTAT_EXC;
55
56 if (ExceptionType != 0) {
57 //
58 // Exception >>= CSR_ESTAT_EXC_SHIFT, convert to ECODE
59 //
60 ExceptionType >>= CSR_ESTAT_EXC_SHIFT;
61
62 if (ExceptionType > EXCEPT_LOONGARCH_FPE) {
63 return EFI_UNSUPPORTED;
64 }
65
66 if ((InterruptHandler == NULL) && (ExceptionHandler[InterruptType] == NULL)) {
67 return EFI_INVALID_PARAMETER;
68 }
69
70 if ((InterruptHandler != NULL) && (ExceptionHandler[ExceptionType] != NULL)) {
71 return EFI_ALREADY_STARTED;
72 }
73
74 ExceptionHandler[ExceptionType] = InterruptHandler;
75 } else {
76 //
77 // Interrupt
78 //
79 if (InterruptType > MAX_LOONGARCH_INTERRUPT) {
80 return EFI_UNSUPPORTED;
81 }
82
83 if ((InterruptHandler == NULL) && (ExternalInterruptHandler[InterruptType] == NULL)) {
84 return EFI_INVALID_PARAMETER;
85 }
86
87 if ((InterruptHandler != NULL) && (ExternalInterruptHandler[InterruptType] != NULL)) {
88 return EFI_ALREADY_STARTED;
89 }
90
91 ExternalInterruptHandler[InterruptType] = InterruptHandler;
92 }
93
94 return EFI_SUCCESS;
95}
96
97/**
98 Common exception handler.
99
100 @param ExceptionType Exception type.
101 @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
102
103**/
104VOID
105EFIAPI
106CommonExceptionHandler (
107 IN EFI_EXCEPTION_TYPE ExceptionType,
108 IN OUT EFI_SYSTEM_CONTEXT SystemContext
109 )
110{
111 EFI_EXCEPTION_TYPE InterruptType;
112
113 if (ExceptionType == EXCEPT_LOONGARCH_INT) {
114 //
115 // Interrupt
116 //
117 InterruptType = GetInterruptType (SystemContext);
118 if (InterruptType == 0xFF) {
119 ExceptionType = InterruptType;
120 } else {
121 if ((ExternalInterruptHandler != NULL) && (ExternalInterruptHandler[InterruptType] != NULL)) {
122 ExternalInterruptHandler[InterruptType](InterruptType, SystemContext);
123 return;
124 }
125 }
126 } else if (ExceptionType == EXCEPT_LOONGARCH_FPD) {
127 EnableFloatingPointUnits ();
128 InitializeFloatingPointUnits ();
129 return;
130 } else {
131 //
132 // Exception
133 //
134 ExceptionType >>= CSR_ESTAT_EXC_SHIFT;
135 if ((ExceptionHandler != NULL) && (ExceptionHandler[ExceptionType] != NULL)) {
136 ExceptionHandler[ExceptionType](ExceptionType, SystemContext);
137 return;
138 }
139 }
140
141 //
142 // Only the TLB refill exception use the same entry point as normal exceptions.
143 //
144 if (CsrRead (LOONGARCH_CSR_TLBRERA) & 0x1) {
145 ExceptionType = mExceptionKnownNameNum - 1; // Use only to dump the exception context.
146 }
147
148 DefaultExceptionHandler (ExceptionType, SystemContext);
149}
150
151/**
152 Initializes all CPU exceptions entries and provides the default exception handlers.
153
154 Caller should try to get an array of interrupt and/or exception vectors that are in use and need to
155 persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.
156 If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL.
157 If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.
158
159 @param[in] VectorInfo Pointer to reserved vector list.
160
161 @retval EFI_SUCCESS CPU Exception Entries have been successfully initialized
162 with default exception handlers.
163 @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.
164 @retval EFI_UNSUPPORTED This function is not supported.
165
166**/
167EFI_STATUS
168EFIAPI
169InitializeCpuExceptionHandlers (
170 IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL
171 )
172{
173 return EFI_SUCCESS;
174}
175
176/**
177 Setup separate stacks for certain exception handlers.
178 If the input Buffer and BufferSize are both NULL, use global variable if possible.
179
180 @param[in] Buffer Point to buffer used to separate exception stack.
181 @param[in, out] BufferSize On input, it indicates the byte size of Buffer.
182 If the size is not enough, the return status will
183 be EFI_BUFFER_TOO_SMALL, and output BufferSize
184 will be the size it needs.
185
186 @retval EFI_SUCCESS The stacks are assigned successfully.
187 @retval EFI_UNSUPPORTED This function is not supported.
188 @retval EFI_BUFFER_TOO_SMALL This BufferSize is too small.
189**/
190EFI_STATUS
191EFIAPI
192InitializeSeparateExceptionStacks (
193 IN VOID *Buffer,
194 IN OUT UINTN *BufferSize
195 )
196{
197 return EFI_SUCCESS;
198}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette