ARM Packages: Fixed line endings
This large code change only modifies the line endings to be CRLF to be compliant with the EDK2 coding convention document. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14088 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -1,191 +1,191 @@
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
.text
|
||||
.align 3
|
||||
|
||||
GCC_ASM_EXPORT(ExceptionHandlersStart)
|
||||
GCC_ASM_EXPORT(ExceptionHandlersEnd)
|
||||
GCC_ASM_EXPORT(CommonExceptionEntry)
|
||||
GCC_ASM_EXPORT(AsmCommonExceptionEntry)
|
||||
GCC_ASM_EXPORT(CommonCExceptionHandler)
|
||||
|
||||
ASM_PFX(ExceptionHandlersStart):
|
||||
|
||||
ASM_PFX(Reset):
|
||||
b ASM_PFX(ResetEntry)
|
||||
|
||||
ASM_PFX(UndefinedInstruction):
|
||||
b ASM_PFX(UndefinedInstructionEntry)
|
||||
|
||||
ASM_PFX(SoftwareInterrupt):
|
||||
b ASM_PFX(SoftwareInterruptEntry)
|
||||
|
||||
ASM_PFX(PrefetchAbort):
|
||||
b ASM_PFX(PrefetchAbortEntry)
|
||||
|
||||
ASM_PFX(DataAbort):
|
||||
b ASM_PFX(DataAbortEntry)
|
||||
|
||||
ASM_PFX(ReservedException):
|
||||
b ASM_PFX(ReservedExceptionEntry)
|
||||
|
||||
ASM_PFX(Irq):
|
||||
b ASM_PFX(IrqEntry)
|
||||
|
||||
ASM_PFX(Fiq):
|
||||
b ASM_PFX(FiqEntry)
|
||||
|
||||
ASM_PFX(ResetEntry):
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#0
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(UndefinedInstructionEntry):
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#1
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(SoftwareInterruptEntry):
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#2
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(PrefetchAbortEntry):
|
||||
sub LR,LR,#4
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#3
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(DataAbortEntry):
|
||||
sub LR,LR,#8
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#4
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(ReservedExceptionEntry):
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#5
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(IrqEntry):
|
||||
sub LR,LR,#4
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#6
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(FiqEntry):
|
||||
sub LR,LR,#4
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#7
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(CommonExceptionEntry):
|
||||
.byte 0x12
|
||||
.byte 0x34
|
||||
.byte 0x56
|
||||
.byte 0x78
|
||||
|
||||
ASM_PFX(ExceptionHandlersEnd):
|
||||
|
||||
ASM_PFX(AsmCommonExceptionEntry):
|
||||
mrc p15, 0, R1, c6, c0, 2 @ Read IFAR
|
||||
str R1, [SP, #0x50] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
|
||||
|
||||
mrc p15, 0, R1, c5, c0, 1 @ Read IFSR
|
||||
str R1, [SP, #0x4c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
|
||||
|
||||
mrc p15, 0, R1, c6, c0, 0 @ Read DFAR
|
||||
str R1, [SP, #0x48] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
|
||||
|
||||
mrc p15, 0, R1, c5, c0, 0 @ Read DFSR
|
||||
str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
|
||||
|
||||
ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
|
||||
str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
|
||||
and r1, r1, #0x1f @ Check to see if User or System Mode
|
||||
cmp r1, #0x1f
|
||||
cmpne r1, #0x10
|
||||
add R2, SP, #0x38 @ Store it in EFI_SYSTEM_CONTEXT_ARM.LR
|
||||
ldmneed r2, {lr}^ @ User or System mode, use unbanked register
|
||||
ldmneed r2, {lr} @ All other modes used banked register
|
||||
|
||||
ldr R1, [SP, #0x58] @ PC is the LR pushed by srsdb
|
||||
str R1, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC
|
||||
|
||||
sub R1, SP, #0x60 @ We pused 0x60 bytes on the stack
|
||||
str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP
|
||||
|
||||
@ R0 is exception type
|
||||
mov R1,SP @ Prepare System Context pointer as an argument for the exception handler
|
||||
blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler
|
||||
|
||||
ldr R2,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR
|
||||
str R2,[SP,#0x5c] @ Store it back to srsdb stack slot so it can be restored
|
||||
|
||||
ldr R2,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC
|
||||
str R2,[SP,#0x58] @ Store it back to srsdb stack slot so it can be restored
|
||||
|
||||
ldmfd SP!,{R0-R12} @ Restore general purpose registers
|
||||
@ Exception handler can not change SP or LR as we would blow chunks
|
||||
|
||||
add SP,SP,#0x20 @ Clear out the remaining stack space
|
||||
ldmfd SP!,{LR} @ restore the link register for this context
|
||||
rfefd SP! @ return from exception via srsdb stack slot
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
.text
|
||||
.align 3
|
||||
|
||||
GCC_ASM_EXPORT(ExceptionHandlersStart)
|
||||
GCC_ASM_EXPORT(ExceptionHandlersEnd)
|
||||
GCC_ASM_EXPORT(CommonExceptionEntry)
|
||||
GCC_ASM_EXPORT(AsmCommonExceptionEntry)
|
||||
GCC_ASM_EXPORT(CommonCExceptionHandler)
|
||||
|
||||
ASM_PFX(ExceptionHandlersStart):
|
||||
|
||||
ASM_PFX(Reset):
|
||||
b ASM_PFX(ResetEntry)
|
||||
|
||||
ASM_PFX(UndefinedInstruction):
|
||||
b ASM_PFX(UndefinedInstructionEntry)
|
||||
|
||||
ASM_PFX(SoftwareInterrupt):
|
||||
b ASM_PFX(SoftwareInterruptEntry)
|
||||
|
||||
ASM_PFX(PrefetchAbort):
|
||||
b ASM_PFX(PrefetchAbortEntry)
|
||||
|
||||
ASM_PFX(DataAbort):
|
||||
b ASM_PFX(DataAbortEntry)
|
||||
|
||||
ASM_PFX(ReservedException):
|
||||
b ASM_PFX(ReservedExceptionEntry)
|
||||
|
||||
ASM_PFX(Irq):
|
||||
b ASM_PFX(IrqEntry)
|
||||
|
||||
ASM_PFX(Fiq):
|
||||
b ASM_PFX(FiqEntry)
|
||||
|
||||
ASM_PFX(ResetEntry):
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#0
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(UndefinedInstructionEntry):
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#1
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(SoftwareInterruptEntry):
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#2
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(PrefetchAbortEntry):
|
||||
sub LR,LR,#4
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#3
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(DataAbortEntry):
|
||||
sub LR,LR,#8
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#4
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(ReservedExceptionEntry):
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#5
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(IrqEntry):
|
||||
sub LR,LR,#4
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#6
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(FiqEntry):
|
||||
sub LR,LR,#4
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov r0,#7
|
||||
ldr r1,ASM_PFX(CommonExceptionEntry)
|
||||
bx r1
|
||||
|
||||
ASM_PFX(CommonExceptionEntry):
|
||||
.byte 0x12
|
||||
.byte 0x34
|
||||
.byte 0x56
|
||||
.byte 0x78
|
||||
|
||||
ASM_PFX(ExceptionHandlersEnd):
|
||||
|
||||
ASM_PFX(AsmCommonExceptionEntry):
|
||||
mrc p15, 0, R1, c6, c0, 2 @ Read IFAR
|
||||
str R1, [SP, #0x50] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
|
||||
|
||||
mrc p15, 0, R1, c5, c0, 1 @ Read IFSR
|
||||
str R1, [SP, #0x4c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
|
||||
|
||||
mrc p15, 0, R1, c6, c0, 0 @ Read DFAR
|
||||
str R1, [SP, #0x48] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
|
||||
|
||||
mrc p15, 0, R1, c5, c0, 0 @ Read DFSR
|
||||
str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
|
||||
|
||||
ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
|
||||
str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
|
||||
and r1, r1, #0x1f @ Check to see if User or System Mode
|
||||
cmp r1, #0x1f
|
||||
cmpne r1, #0x10
|
||||
add R2, SP, #0x38 @ Store it in EFI_SYSTEM_CONTEXT_ARM.LR
|
||||
ldmneed r2, {lr}^ @ User or System mode, use unbanked register
|
||||
ldmneed r2, {lr} @ All other modes used banked register
|
||||
|
||||
ldr R1, [SP, #0x58] @ PC is the LR pushed by srsdb
|
||||
str R1, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC
|
||||
|
||||
sub R1, SP, #0x60 @ We pused 0x60 bytes on the stack
|
||||
str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP
|
||||
|
||||
@ R0 is exception type
|
||||
mov R1,SP @ Prepare System Context pointer as an argument for the exception handler
|
||||
blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler
|
||||
|
||||
ldr R2,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR
|
||||
str R2,[SP,#0x5c] @ Store it back to srsdb stack slot so it can be restored
|
||||
|
||||
ldr R2,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC
|
||||
str R2,[SP,#0x58] @ Store it back to srsdb stack slot so it can be restored
|
||||
|
||||
ldmfd SP!,{R0-R12} @ Restore general purpose registers
|
||||
@ Exception handler can not change SP or LR as we would blow chunks
|
||||
|
||||
add SP,SP,#0x20 @ Clear out the remaining stack space
|
||||
ldmfd SP!,{LR} @ restore the link register for this context
|
||||
rfefd SP! @ return from exception via srsdb stack slot
|
||||
|
@@ -1,152 +1,152 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
//
|
||||
// This program and the accompanying materials
|
||||
// are licensed and made available under the terms and conditions of the BSD License
|
||||
// which accompanies this distribution. The full text of the license may be found at
|
||||
// http://opensource.org/licenses/bsd-license.php
|
||||
//
|
||||
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
EXPORT ExceptionHandlersStart
|
||||
EXPORT ExceptionHandlersEnd
|
||||
EXPORT CommonExceptionEntry
|
||||
EXPORT AsmCommonExceptionEntry
|
||||
IMPORT CommonCExceptionHandler
|
||||
|
||||
PRESERVE8
|
||||
AREA DxeExceptionHandlers, CODE, READONLY
|
||||
|
||||
ExceptionHandlersStart
|
||||
|
||||
Reset
|
||||
b ResetEntry
|
||||
|
||||
UndefinedInstruction
|
||||
b UndefinedInstructionEntry
|
||||
|
||||
SoftwareInterrupt
|
||||
b SoftwareInterruptEntry
|
||||
|
||||
PrefetchAbort
|
||||
b PrefetchAbortEntry
|
||||
|
||||
DataAbort
|
||||
b DataAbortEntry
|
||||
|
||||
ReservedException
|
||||
b ReservedExceptionEntry
|
||||
|
||||
Irq
|
||||
b IrqEntry
|
||||
|
||||
Fiq
|
||||
b FiqEntry
|
||||
|
||||
ResetEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#0
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
UndefinedInstructionEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#1
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
SoftwareInterruptEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#2
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
PrefetchAbortEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#3
|
||||
SUB LR,LR,#4
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
DataAbortEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#4
|
||||
SUB LR,LR,#8
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
ReservedExceptionEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#5
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
IrqEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#6
|
||||
SUB LR,LR,#4
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
FiqEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#7
|
||||
SUB LR,LR,#4
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
CommonExceptionEntry
|
||||
dcd 0x12345678
|
||||
|
||||
ExceptionHandlersEnd
|
||||
|
||||
AsmCommonExceptionEntry
|
||||
mrc p15, 0, r1, c6, c0, 2 ; Read IFAR
|
||||
stmfd SP!,{R1} ; Store the IFAR
|
||||
|
||||
mrc p15, 0, r1, c5, c0, 1 ; Read IFSR
|
||||
stmfd SP!,{R1} ; Store the IFSR
|
||||
|
||||
mrc p15, 0, r1, c6, c0, 0 ; Read DFAR
|
||||
stmfd SP!,{R1} ; Store the DFAR
|
||||
|
||||
mrc p15, 0, r1, c5, c0, 0 ; Read DFSR
|
||||
stmfd SP!,{R1} ; Store the DFSR
|
||||
|
||||
mrs R1,SPSR ; Read SPSR (which is the pre-exception CPSR)
|
||||
stmfd SP!,{R1} ; Store the SPSR
|
||||
|
||||
stmfd SP!,{LR} ; Store the link register (which is the pre-exception PC)
|
||||
stmfd SP,{SP,LR}^ ; Store user/system mode stack pointer and link register
|
||||
nop ; Required by ARM architecture
|
||||
SUB SP,SP,#0x08 ; Adjust stack pointer
|
||||
stmfd SP!,{R2-R12} ; Store general purpose registers
|
||||
|
||||
ldr R3,[SP,#0x50] ; Read saved R1 from the stack (it was saved by the exception entry routine)
|
||||
ldr R2,[SP,#0x4C] ; Read saved R0 from the stack (it was saved by the exception entry routine)
|
||||
stmfd SP!,{R2-R3} ; Store general purpose registers R0 and R1
|
||||
|
||||
mov R1,SP ; Prepare System Context pointer as an argument for the exception handler
|
||||
|
||||
sub SP,SP,#4 ; Adjust SP to preserve 8-byte alignment
|
||||
blx CommonCExceptionHandler ; Call exception handler
|
||||
add SP,SP,#4 ; Adjust SP back to where we were
|
||||
|
||||
ldr R2,[SP,#0x40] ; Load CPSR from context, in case it has changed
|
||||
MSR SPSR_cxsf,R2 ; Store it back to the SPSR to be restored when exiting this handler
|
||||
|
||||
ldmfd SP!,{R0-R12} ; Restore general purpose registers
|
||||
ldm SP,{SP,LR}^ ; Restore user/system mode stack pointer and link register
|
||||
nop ; Required by ARM architecture
|
||||
add SP,SP,#0x08 ; Adjust stack pointer
|
||||
ldmfd SP!,{LR} ; Restore the link register (which is the pre-exception PC)
|
||||
add SP,SP,#0x1C ; Clear out the remaining stack space
|
||||
movs PC,LR ; Return from exception
|
||||
|
||||
END
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
||||
//
|
||||
// This program and the accompanying materials
|
||||
// are licensed and made available under the terms and conditions of the BSD License
|
||||
// which accompanies this distribution. The full text of the license may be found at
|
||||
// http://opensource.org/licenses/bsd-license.php
|
||||
//
|
||||
// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
EXPORT ExceptionHandlersStart
|
||||
EXPORT ExceptionHandlersEnd
|
||||
EXPORT CommonExceptionEntry
|
||||
EXPORT AsmCommonExceptionEntry
|
||||
IMPORT CommonCExceptionHandler
|
||||
|
||||
PRESERVE8
|
||||
AREA DxeExceptionHandlers, CODE, READONLY
|
||||
|
||||
ExceptionHandlersStart
|
||||
|
||||
Reset
|
||||
b ResetEntry
|
||||
|
||||
UndefinedInstruction
|
||||
b UndefinedInstructionEntry
|
||||
|
||||
SoftwareInterrupt
|
||||
b SoftwareInterruptEntry
|
||||
|
||||
PrefetchAbort
|
||||
b PrefetchAbortEntry
|
||||
|
||||
DataAbort
|
||||
b DataAbortEntry
|
||||
|
||||
ReservedException
|
||||
b ReservedExceptionEntry
|
||||
|
||||
Irq
|
||||
b IrqEntry
|
||||
|
||||
Fiq
|
||||
b FiqEntry
|
||||
|
||||
ResetEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#0
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
UndefinedInstructionEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#1
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
SoftwareInterruptEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#2
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
PrefetchAbortEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#3
|
||||
SUB LR,LR,#4
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
DataAbortEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#4
|
||||
SUB LR,LR,#8
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
ReservedExceptionEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#5
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
IrqEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#6
|
||||
SUB LR,LR,#4
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
FiqEntry
|
||||
stmfd SP!,{R0-R1}
|
||||
mov R0,#7
|
||||
SUB LR,LR,#4
|
||||
ldr R1,CommonExceptionEntry
|
||||
bx R1
|
||||
|
||||
CommonExceptionEntry
|
||||
dcd 0x12345678
|
||||
|
||||
ExceptionHandlersEnd
|
||||
|
||||
AsmCommonExceptionEntry
|
||||
mrc p15, 0, r1, c6, c0, 2 ; Read IFAR
|
||||
stmfd SP!,{R1} ; Store the IFAR
|
||||
|
||||
mrc p15, 0, r1, c5, c0, 1 ; Read IFSR
|
||||
stmfd SP!,{R1} ; Store the IFSR
|
||||
|
||||
mrc p15, 0, r1, c6, c0, 0 ; Read DFAR
|
||||
stmfd SP!,{R1} ; Store the DFAR
|
||||
|
||||
mrc p15, 0, r1, c5, c0, 0 ; Read DFSR
|
||||
stmfd SP!,{R1} ; Store the DFSR
|
||||
|
||||
mrs R1,SPSR ; Read SPSR (which is the pre-exception CPSR)
|
||||
stmfd SP!,{R1} ; Store the SPSR
|
||||
|
||||
stmfd SP!,{LR} ; Store the link register (which is the pre-exception PC)
|
||||
stmfd SP,{SP,LR}^ ; Store user/system mode stack pointer and link register
|
||||
nop ; Required by ARM architecture
|
||||
SUB SP,SP,#0x08 ; Adjust stack pointer
|
||||
stmfd SP!,{R2-R12} ; Store general purpose registers
|
||||
|
||||
ldr R3,[SP,#0x50] ; Read saved R1 from the stack (it was saved by the exception entry routine)
|
||||
ldr R2,[SP,#0x4C] ; Read saved R0 from the stack (it was saved by the exception entry routine)
|
||||
stmfd SP!,{R2-R3} ; Store general purpose registers R0 and R1
|
||||
|
||||
mov R1,SP ; Prepare System Context pointer as an argument for the exception handler
|
||||
|
||||
sub SP,SP,#4 ; Adjust SP to preserve 8-byte alignment
|
||||
blx CommonCExceptionHandler ; Call exception handler
|
||||
add SP,SP,#4 ; Adjust SP back to where we were
|
||||
|
||||
ldr R2,[SP,#0x40] ; Load CPSR from context, in case it has changed
|
||||
MSR SPSR_cxsf,R2 ; Store it back to the SPSR to be restored when exiting this handler
|
||||
|
||||
ldmfd SP!,{R0-R12} ; Restore general purpose registers
|
||||
ldm SP,{SP,LR}^ ; Restore user/system mode stack pointer and link register
|
||||
nop ; Required by ARM architecture
|
||||
add SP,SP,#0x08 ; Adjust stack pointer
|
||||
ldmfd SP!,{LR} ; Restore the link register (which is the pre-exception PC)
|
||||
add SP,SP,#0x1C ; Clear out the remaining stack space
|
||||
movs PC,LR ; Return from exception
|
||||
|
||||
END
|
||||
|
||||
|
||||
|
@@ -1,297 +1,297 @@
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Use ARMv6 instruction to operate on a single stack
|
||||
#
|
||||
# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
/*
|
||||
|
||||
This is the stack constructed by the exception handler (low address to high address)
|
||||
# R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM
|
||||
Reg Offset
|
||||
=== ======
|
||||
R0 0x00 # stmfd SP!,{R0-R12}
|
||||
R1 0x04
|
||||
R2 0x08
|
||||
R3 0x0c
|
||||
R4 0x10
|
||||
R5 0x14
|
||||
R6 0x18
|
||||
R7 0x1c
|
||||
R8 0x20
|
||||
R9 0x24
|
||||
R10 0x28
|
||||
R11 0x2c
|
||||
R12 0x30
|
||||
SP 0x34 # reserved via adding 0x20 (32) to the SP
|
||||
LR 0x38
|
||||
PC 0x3c
|
||||
CPSR 0x40
|
||||
DFSR 0x44
|
||||
DFAR 0x48
|
||||
IFSR 0x4c
|
||||
IFAR 0x50
|
||||
|
||||
LR 0x54 # SVC Link register (we need to restore it)
|
||||
|
||||
LR 0x58 # pushed by srsfd
|
||||
CPSR 0x5c
|
||||
|
||||
*/
|
||||
|
||||
|
||||
GCC_ASM_EXPORT(ExceptionHandlersStart)
|
||||
GCC_ASM_EXPORT(ExceptionHandlersEnd)
|
||||
GCC_ASM_EXPORT(CommonExceptionEntry)
|
||||
GCC_ASM_EXPORT(AsmCommonExceptionEntry)
|
||||
GCC_ASM_EXPORT(CommonCExceptionHandler)
|
||||
|
||||
.text
|
||||
#if !defined(__APPLE__)
|
||||
.fpu neon @ makes vpush/vpop assemble
|
||||
#endif
|
||||
.align 5
|
||||
|
||||
|
||||
//
|
||||
// This code gets copied to the ARM vector table
|
||||
// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
|
||||
//
|
||||
ASM_PFX(ExceptionHandlersStart):
|
||||
|
||||
ASM_PFX(Reset):
|
||||
b ASM_PFX(ResetEntry)
|
||||
|
||||
ASM_PFX(UndefinedInstruction):
|
||||
b ASM_PFX(UndefinedInstructionEntry)
|
||||
|
||||
ASM_PFX(SoftwareInterrupt):
|
||||
b ASM_PFX(SoftwareInterruptEntry)
|
||||
|
||||
ASM_PFX(PrefetchAbort):
|
||||
b ASM_PFX(PrefetchAbortEntry)
|
||||
|
||||
ASM_PFX(DataAbort):
|
||||
b ASM_PFX(DataAbortEntry)
|
||||
|
||||
ASM_PFX(ReservedException):
|
||||
b ASM_PFX(ReservedExceptionEntry)
|
||||
|
||||
ASM_PFX(Irq):
|
||||
b ASM_PFX(IrqEntry)
|
||||
|
||||
ASM_PFX(Fiq):
|
||||
b ASM_PFX(FiqEntry)
|
||||
|
||||
ASM_PFX(ResetEntry):
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
@ We are already in SVC mode
|
||||
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#0 @ ExceptionType
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(UndefinedInstructionEntry):
|
||||
sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#1 @ ExceptionType
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(SoftwareInterruptEntry):
|
||||
sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
@ We are already in SVC mode
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#2 @ ExceptionType
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(PrefetchAbortEntry):
|
||||
sub LR,LR,#4
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#3 @ ExceptionType
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(DataAbortEntry):
|
||||
sub LR,LR,#8
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#4
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(ReservedExceptionEntry):
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#5
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(IrqEntry):
|
||||
sub LR,LR,#4
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#6 @ ExceptionType
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(FiqEntry):
|
||||
sub LR,LR,#4
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
@ Since we have already switch to SVC R8_fiq - R12_fiq
|
||||
@ never get used or saved
|
||||
mov R0,#7 @ ExceptionType
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
//
|
||||
// This gets patched by the C code that patches in the vector table
|
||||
//
|
||||
ASM_PFX(CommonExceptionEntry):
|
||||
.word ASM_PFX(AsmCommonExceptionEntry)
|
||||
|
||||
ASM_PFX(ExceptionHandlersEnd):
|
||||
|
||||
//
|
||||
// This code runs from CpuDxe driver loaded address. It is patched into
|
||||
// CommonExceptionEntry.
|
||||
//
|
||||
ASM_PFX(AsmCommonExceptionEntry):
|
||||
mrc p15, 0, R1, c6, c0, 2 @ Read IFAR
|
||||
str R1, [SP, #0x50] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
|
||||
|
||||
mrc p15, 0, R1, c5, c0, 1 @ Read IFSR
|
||||
str R1, [SP, #0x4c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
|
||||
|
||||
mrc p15, 0, R1, c6, c0, 0 @ Read DFAR
|
||||
str R1, [SP, #0x48] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
|
||||
|
||||
mrc p15, 0, R1, c5, c0, 0 @ Read DFSR
|
||||
str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
|
||||
|
||||
ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
|
||||
str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
|
||||
|
||||
add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
|
||||
and R3, R1, #0x1f @ Check CPSR to see if User or System Mode
|
||||
cmp R3, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1df))
|
||||
cmpne R3, #0x10 @
|
||||
stmeqed R2, {lr}^ @ save unbanked lr
|
||||
@ else
|
||||
stmneed R2, {lr} @ save SVC lr
|
||||
|
||||
|
||||
ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd
|
||||
@ Check to see if we have to adjust for Thumb entry
|
||||
sub r4, r0, #1 @ if (ExceptionType == 1 || ExceptionType ==2)) {
|
||||
cmp r4, #1 @ // UND & SVC have differnt LR adjust for Thumb
|
||||
bhi NoAdjustNeeded
|
||||
|
||||
tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry
|
||||
addne R5, R5, #2 @ PC += 2@
|
||||
str R5,[SP,#0x58] @ Update LR value pused by srsfd
|
||||
|
||||
NoAdjustNeeded:
|
||||
|
||||
str R5, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC
|
||||
|
||||
sub R1, SP, #0x60 @ We pused 0x60 bytes on the stack
|
||||
str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP
|
||||
|
||||
@ R0 is ExceptionType
|
||||
mov R1,SP @ R1 is SystemContext
|
||||
|
||||
#if (FixedPcdGet32(PcdVFPEnabled))
|
||||
vpush {d0-d15} @ save vstm registers in case they are used in optimizations
|
||||
#endif
|
||||
|
||||
/*
|
||||
VOID
|
||||
EFIAPI
|
||||
CommonCExceptionHandler (
|
||||
IN EFI_EXCEPTION_TYPE ExceptionType, R0
|
||||
IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
|
||||
)
|
||||
|
||||
*/
|
||||
blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler
|
||||
|
||||
#if (FixedPcdGet32(PcdVFPEnabled))
|
||||
vpop {d0-d15}
|
||||
#endif
|
||||
|
||||
ldr R1, [SP, #0x4c] @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
|
||||
mcr p15, 0, R1, c5, c0, 1 @ Write IFSR
|
||||
|
||||
ldr R1, [SP, #0x44] @ sRestore EFI_SYSTEM_CONTEXT_ARM.DFSR
|
||||
mcr p15, 0, R1, c5, c0, 0 @ Write DFSR
|
||||
|
||||
ldr R1,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC
|
||||
str R1,[SP,#0x58] @ Store it back to srsfd stack slot so it can be restored
|
||||
|
||||
ldr R1,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR
|
||||
str R1,[SP,#0x5c] @ Store it back to srsfd stack slot so it can be restored
|
||||
|
||||
add R3, SP, #0x54 @ Make R3 point to SVC LR saved on entry
|
||||
add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
|
||||
and R1, R1, #0x1f @ Check to see if User or System Mode
|
||||
cmp R1, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f))
|
||||
cmpne R1, #0x10 @
|
||||
ldmeqed R2, {lr}^ @ restore unbanked lr
|
||||
@ else
|
||||
ldmneed R3, {lr} @ restore SVC lr, via ldmfd SP!, {LR}
|
||||
|
||||
ldmfd SP!,{R0-R12} @ Restore general purpose registers
|
||||
@ Exception handler can not change SP
|
||||
|
||||
add SP,SP,#0x20 @ Clear out the remaining stack space
|
||||
ldmfd SP!,{LR} @ restore the link register for this context
|
||||
rfefd SP! @ return from exception via srsfd stack slot
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Use ARMv6 instruction to operate on a single stack
|
||||
#
|
||||
# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
/*
|
||||
|
||||
This is the stack constructed by the exception handler (low address to high address)
|
||||
# R0 - IFAR is EFI_SYSTEM_CONTEXT for ARM
|
||||
Reg Offset
|
||||
=== ======
|
||||
R0 0x00 # stmfd SP!,{R0-R12}
|
||||
R1 0x04
|
||||
R2 0x08
|
||||
R3 0x0c
|
||||
R4 0x10
|
||||
R5 0x14
|
||||
R6 0x18
|
||||
R7 0x1c
|
||||
R8 0x20
|
||||
R9 0x24
|
||||
R10 0x28
|
||||
R11 0x2c
|
||||
R12 0x30
|
||||
SP 0x34 # reserved via adding 0x20 (32) to the SP
|
||||
LR 0x38
|
||||
PC 0x3c
|
||||
CPSR 0x40
|
||||
DFSR 0x44
|
||||
DFAR 0x48
|
||||
IFSR 0x4c
|
||||
IFAR 0x50
|
||||
|
||||
LR 0x54 # SVC Link register (we need to restore it)
|
||||
|
||||
LR 0x58 # pushed by srsfd
|
||||
CPSR 0x5c
|
||||
|
||||
*/
|
||||
|
||||
|
||||
GCC_ASM_EXPORT(ExceptionHandlersStart)
|
||||
GCC_ASM_EXPORT(ExceptionHandlersEnd)
|
||||
GCC_ASM_EXPORT(CommonExceptionEntry)
|
||||
GCC_ASM_EXPORT(AsmCommonExceptionEntry)
|
||||
GCC_ASM_EXPORT(CommonCExceptionHandler)
|
||||
|
||||
.text
|
||||
#if !defined(__APPLE__)
|
||||
.fpu neon @ makes vpush/vpop assemble
|
||||
#endif
|
||||
.align 5
|
||||
|
||||
|
||||
//
|
||||
// This code gets copied to the ARM vector table
|
||||
// ExceptionHandlersStart - ExceptionHandlersEnd gets copied
|
||||
//
|
||||
ASM_PFX(ExceptionHandlersStart):
|
||||
|
||||
ASM_PFX(Reset):
|
||||
b ASM_PFX(ResetEntry)
|
||||
|
||||
ASM_PFX(UndefinedInstruction):
|
||||
b ASM_PFX(UndefinedInstructionEntry)
|
||||
|
||||
ASM_PFX(SoftwareInterrupt):
|
||||
b ASM_PFX(SoftwareInterruptEntry)
|
||||
|
||||
ASM_PFX(PrefetchAbort):
|
||||
b ASM_PFX(PrefetchAbortEntry)
|
||||
|
||||
ASM_PFX(DataAbort):
|
||||
b ASM_PFX(DataAbortEntry)
|
||||
|
||||
ASM_PFX(ReservedException):
|
||||
b ASM_PFX(ReservedExceptionEntry)
|
||||
|
||||
ASM_PFX(Irq):
|
||||
b ASM_PFX(IrqEntry)
|
||||
|
||||
ASM_PFX(Fiq):
|
||||
b ASM_PFX(FiqEntry)
|
||||
|
||||
ASM_PFX(ResetEntry):
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
@ We are already in SVC mode
|
||||
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#0 @ ExceptionType
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(UndefinedInstructionEntry):
|
||||
sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#1 @ ExceptionType
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(SoftwareInterruptEntry):
|
||||
sub LR, LR, #4 @ Only -2 for Thumb, adjust in CommonExceptionEntry
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
@ We are already in SVC mode
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#2 @ ExceptionType
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(PrefetchAbortEntry):
|
||||
sub LR,LR,#4
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#3 @ ExceptionType
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(DataAbortEntry):
|
||||
sub LR,LR,#8
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#4
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(ReservedExceptionEntry):
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#5
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(IrqEntry):
|
||||
sub LR,LR,#4
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
|
||||
mov R0,#6 @ ExceptionType
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
ASM_PFX(FiqEntry):
|
||||
sub LR,LR,#4
|
||||
srsdb #0x13! @ Store return state on SVC stack
|
||||
cps #0x13 @ Switch to SVC for common stack
|
||||
stmfd SP!,{LR} @ Store the link register for the current mode
|
||||
sub SP,SP,#0x20 @ Save space for SP, LR, PC, IFAR - CPSR
|
||||
stmfd SP!,{R0-R12} @ Store the register state
|
||||
@ Since we have already switch to SVC R8_fiq - R12_fiq
|
||||
@ never get used or saved
|
||||
mov R0,#7 @ ExceptionType
|
||||
ldr R1,ASM_PFX(CommonExceptionEntry)
|
||||
bx R1
|
||||
|
||||
//
|
||||
// This gets patched by the C code that patches in the vector table
|
||||
//
|
||||
ASM_PFX(CommonExceptionEntry):
|
||||
.word ASM_PFX(AsmCommonExceptionEntry)
|
||||
|
||||
ASM_PFX(ExceptionHandlersEnd):
|
||||
|
||||
//
|
||||
// This code runs from CpuDxe driver loaded address. It is patched into
|
||||
// CommonExceptionEntry.
|
||||
//
|
||||
ASM_PFX(AsmCommonExceptionEntry):
|
||||
mrc p15, 0, R1, c6, c0, 2 @ Read IFAR
|
||||
str R1, [SP, #0x50] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFAR
|
||||
|
||||
mrc p15, 0, R1, c5, c0, 1 @ Read IFSR
|
||||
str R1, [SP, #0x4c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.IFSR
|
||||
|
||||
mrc p15, 0, R1, c6, c0, 0 @ Read DFAR
|
||||
str R1, [SP, #0x48] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFAR
|
||||
|
||||
mrc p15, 0, R1, c5, c0, 0 @ Read DFSR
|
||||
str R1, [SP, #0x44] @ Store it in EFI_SYSTEM_CONTEXT_ARM.DFSR
|
||||
|
||||
ldr R1, [SP, #0x5c] @ srsdb saved pre-exception CPSR on the stack
|
||||
str R1, [SP, #0x40] @ Store it in EFI_SYSTEM_CONTEXT_ARM.CPSR
|
||||
|
||||
add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
|
||||
and R3, R1, #0x1f @ Check CPSR to see if User or System Mode
|
||||
cmp R3, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1df))
|
||||
cmpne R3, #0x10 @
|
||||
stmeqed R2, {lr}^ @ save unbanked lr
|
||||
@ else
|
||||
stmneed R2, {lr} @ save SVC lr
|
||||
|
||||
|
||||
ldr R5, [SP, #0x58] @ PC is the LR pushed by srsfd
|
||||
@ Check to see if we have to adjust for Thumb entry
|
||||
sub r4, r0, #1 @ if (ExceptionType == 1 || ExceptionType ==2)) {
|
||||
cmp r4, #1 @ // UND & SVC have differnt LR adjust for Thumb
|
||||
bhi NoAdjustNeeded
|
||||
|
||||
tst r1, #0x20 @ if ((CPSR & T)) == T) { // Thumb Mode on entry
|
||||
addne R5, R5, #2 @ PC += 2@
|
||||
str R5,[SP,#0x58] @ Update LR value pused by srsfd
|
||||
|
||||
NoAdjustNeeded:
|
||||
|
||||
str R5, [SP, #0x3c] @ Store it in EFI_SYSTEM_CONTEXT_ARM.PC
|
||||
|
||||
sub R1, SP, #0x60 @ We pused 0x60 bytes on the stack
|
||||
str R1, [SP, #0x34] @ Store it in EFI_SYSTEM_CONTEXT_ARM.SP
|
||||
|
||||
@ R0 is ExceptionType
|
||||
mov R1,SP @ R1 is SystemContext
|
||||
|
||||
#if (FixedPcdGet32(PcdVFPEnabled))
|
||||
vpush {d0-d15} @ save vstm registers in case they are used in optimizations
|
||||
#endif
|
||||
|
||||
/*
|
||||
VOID
|
||||
EFIAPI
|
||||
CommonCExceptionHandler (
|
||||
IN EFI_EXCEPTION_TYPE ExceptionType, R0
|
||||
IN OUT EFI_SYSTEM_CONTEXT SystemContext R1
|
||||
)
|
||||
|
||||
*/
|
||||
blx ASM_PFX(CommonCExceptionHandler) @ Call exception handler
|
||||
|
||||
#if (FixedPcdGet32(PcdVFPEnabled))
|
||||
vpop {d0-d15}
|
||||
#endif
|
||||
|
||||
ldr R1, [SP, #0x4c] @ Restore EFI_SYSTEM_CONTEXT_ARM.IFSR
|
||||
mcr p15, 0, R1, c5, c0, 1 @ Write IFSR
|
||||
|
||||
ldr R1, [SP, #0x44] @ sRestore EFI_SYSTEM_CONTEXT_ARM.DFSR
|
||||
mcr p15, 0, R1, c5, c0, 0 @ Write DFSR
|
||||
|
||||
ldr R1,[SP,#0x3c] @ EFI_SYSTEM_CONTEXT_ARM.PC
|
||||
str R1,[SP,#0x58] @ Store it back to srsfd stack slot so it can be restored
|
||||
|
||||
ldr R1,[SP,#0x40] @ EFI_SYSTEM_CONTEXT_ARM.CPSR
|
||||
str R1,[SP,#0x5c] @ Store it back to srsfd stack slot so it can be restored
|
||||
|
||||
add R3, SP, #0x54 @ Make R3 point to SVC LR saved on entry
|
||||
add R2, SP, #0x38 @ Make R2 point to EFI_SYSTEM_CONTEXT_ARM.LR
|
||||
and R1, R1, #0x1f @ Check to see if User or System Mode
|
||||
cmp R1, #0x1f @ if ((CPSR == 0x10) || (CPSR == 0x1f))
|
||||
cmpne R1, #0x10 @
|
||||
ldmeqed R2, {lr}^ @ restore unbanked lr
|
||||
@ else
|
||||
ldmneed R3, {lr} @ restore SVC lr, via ldmfd SP!, {LR}
|
||||
|
||||
ldmfd SP!,{R0-R12} @ Restore general purpose registers
|
||||
@ Exception handler can not change SP
|
||||
|
||||
add SP,SP,#0x20 @ Clear out the remaining stack space
|
||||
ldmfd SP!,{LR} @ restore the link register for this context
|
||||
rfefd SP! @ return from exception via srsfd stack slot
|
||||
|
||||
|
@@ -53,7 +53,7 @@
|
||||
gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
|
||||
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
|
||||
|
||||
[FeaturePcd]
|
||||
[FeaturePcd]
|
||||
gEmbeddedTokenSpaceGuid.PcdCacheEnable
|
||||
|
||||
[depex]
|
||||
|
@@ -1,425 +1,425 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
|
||||
Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
|
||||
Portions copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
Gic.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Driver implementing the GIC interrupt controller protocol
|
||||
|
||||
--*/
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/ArmGicLib.h>
|
||||
|
||||
#include <Protocol/Cpu.h>
|
||||
#include <Protocol/HardwareInterrupt.h>
|
||||
|
||||
#define ARM_GIC_DEFAULT_PRIORITY 0x80
|
||||
|
||||
extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol;
|
||||
|
||||
//
|
||||
// Notifications
|
||||
//
|
||||
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
|
||||
|
||||
// Maximum Number of Interrupts
|
||||
UINTN mGicNumInterrupts = 0;
|
||||
|
||||
HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL;
|
||||
|
||||
/**
|
||||
Register Handler for the specified interrupt source.
|
||||
|
||||
@param This Instance pointer for this protocol
|
||||
@param Source Hardware source of the interrupt
|
||||
@param Handler Callback for interrupt. NULL to unregister
|
||||
|
||||
@retval EFI_SUCCESS Source was updated to support Handler.
|
||||
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RegisterInterruptSource (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN HARDWARE_INTERRUPT_HANDLER Handler
|
||||
)
|
||||
{
|
||||
if (Source > mGicNumInterrupts) {
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
gRegisteredInterruptHandlers[Source] = Handler;
|
||||
|
||||
// If the interrupt handler is unregistered then disable the interrupt
|
||||
if (NULL == Handler){
|
||||
return This->DisableInterruptSource (This, Source);
|
||||
} else {
|
||||
return This->EnableInterruptSource (This, Source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Enable interrupt source Source.
|
||||
|
||||
@param This Instance pointer for this protocol
|
||||
@param Source Hardware source of the interrupt
|
||||
|
||||
@retval EFI_SUCCESS Source interrupt enabled.
|
||||
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EnableInterruptSource (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
)
|
||||
{
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
|
||||
if (Source > mGicNumInterrupts) {
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// Calculate enable register offset and bit position
|
||||
RegOffset = Source / 32;
|
||||
RegShift = Source % 32;
|
||||
|
||||
// Write set-enable register
|
||||
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset), 1 << RegShift);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Disable interrupt source Source.
|
||||
|
||||
@param This Instance pointer for this protocol
|
||||
@param Source Hardware source of the interrupt
|
||||
|
||||
@retval EFI_SUCCESS Source interrupt disabled.
|
||||
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DisableInterruptSource (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
)
|
||||
{
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
|
||||
if (Source > mGicNumInterrupts) {
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// Calculate enable register offset and bit position
|
||||
RegOffset = Source / 32;
|
||||
RegShift = Source % 32;
|
||||
|
||||
// Write set-enable register
|
||||
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDICER + (4*RegOffset), 1 << RegShift);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Return current state of interrupt source Source.
|
||||
|
||||
@param This Instance pointer for this protocol
|
||||
@param Source Hardware source of the interrupt
|
||||
@param InterruptState TRUE: source enabled, FALSE: source disabled.
|
||||
|
||||
@retval EFI_SUCCESS InterruptState is valid
|
||||
@retval EFI_DEVICE_ERROR InterruptState is not valid
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetInterruptSourceState (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN BOOLEAN *InterruptState
|
||||
)
|
||||
{
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
|
||||
if (Source > mGicNumInterrupts) {
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// calculate enable register offset and bit position
|
||||
RegOffset = Source / 32;
|
||||
RegShift = Source % 32;
|
||||
|
||||
if ((MmioRead32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset)) & (1<<RegShift)) == 0) {
|
||||
*InterruptState = FALSE;
|
||||
} else {
|
||||
*InterruptState = TRUE;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Signal to the hardware that the End Of Intrrupt state
|
||||
has been reached.
|
||||
|
||||
@param This Instance pointer for this protocol
|
||||
@param Source Hardware source of the interrupt
|
||||
|
||||
@retval EFI_SUCCESS Source interrupt EOI'ed.
|
||||
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EndOfInterrupt (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
)
|
||||
{
|
||||
if (Source > mGicNumInterrupts) {
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCEIOR, Source);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
|
||||
|
||||
@param InterruptType Defines the type of interrupt or exception that
|
||||
occurred on the processor.This parameter is processor architecture specific.
|
||||
@param SystemContext A pointer to the processor context when
|
||||
the interrupt occurred on the processor.
|
||||
|
||||
@return None
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
IrqInterruptHandler (
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
UINT32 GicInterrupt;
|
||||
HARDWARE_INTERRUPT_HANDLER InterruptHandler;
|
||||
|
||||
GicInterrupt = MmioRead32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCIAR);
|
||||
|
||||
// Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt).
|
||||
if (GicInterrupt >= mGicNumInterrupts) {
|
||||
// The special interrupt do not need to be acknowledge
|
||||
return;
|
||||
}
|
||||
|
||||
InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt];
|
||||
if (InterruptHandler != NULL) {
|
||||
// Call the registered interrupt handler.
|
||||
InterruptHandler (GicInterrupt, SystemContext);
|
||||
} else {
|
||||
DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
|
||||
}
|
||||
|
||||
EndOfInterrupt (&gHardwareInterruptProtocol, GicInterrupt);
|
||||
}
|
||||
|
||||
//
|
||||
// Making this global saves a few bytes in image size
|
||||
//
|
||||
EFI_HANDLE gHardwareInterruptHandle = NULL;
|
||||
|
||||
//
|
||||
// The protocol instance produced by this driver
|
||||
//
|
||||
EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol = {
|
||||
RegisterInterruptSource,
|
||||
EnableInterruptSource,
|
||||
DisableInterruptSource,
|
||||
GetInterruptSourceState,
|
||||
EndOfInterrupt
|
||||
};
|
||||
|
||||
/**
|
||||
Shutdown our hardware
|
||||
|
||||
DXE Core will disable interrupts and turn off the timer and disable interrupts
|
||||
after all the event handlers have run.
|
||||
|
||||
@param[in] Event The Event that is being processed
|
||||
@param[in] Context Event Context
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ExitBootServicesEvent (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
// Acknowledge all pending interrupts
|
||||
for (Index = 0; Index < mGicNumInterrupts; Index++) {
|
||||
DisableInterruptSource (&gHardwareInterruptProtocol, Index);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < mGicNumInterrupts; Index++) {
|
||||
EndOfInterrupt (&gHardwareInterruptProtocol, Index);
|
||||
}
|
||||
|
||||
// Disable Gic Interface
|
||||
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x0);
|
||||
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0x0);
|
||||
|
||||
// Disable Gic Distributor
|
||||
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x0);
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize the state information for the CPU Architectural Protocol
|
||||
|
||||
@param ImageHandle of the loaded driver
|
||||
@param SystemTable Pointer to the System Table
|
||||
|
||||
@retval EFI_SUCCESS Protocol registered
|
||||
@retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
|
||||
@retval EFI_DEVICE_ERROR Hardware problems
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
InterruptDxeInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
EFI_CPU_ARCH_PROTOCOL *Cpu;
|
||||
UINT32 CpuTarget;
|
||||
|
||||
// Check PcdGicPrimaryCoreId has been set in case the Primary Core is not the core 0 of Cluster 0
|
||||
DEBUG_CODE_BEGIN();
|
||||
if ((PcdGet32(PcdArmPrimaryCore) != 0) && (PcdGet32 (PcdGicPrimaryCoreId) == 0)) {
|
||||
DEBUG((EFI_D_WARN,"Warning: the PCD PcdGicPrimaryCoreId does not seem to be set up for the configuration.\n"));
|
||||
}
|
||||
DEBUG_CODE_END();
|
||||
|
||||
// Make sure the Interrupt Controller Protocol is not already installed in the system.
|
||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
|
||||
|
||||
mGicNumInterrupts = ArmGicGetMaxNumInterrupts (PcdGet32(PcdGicDistributorBase));
|
||||
|
||||
for (Index = 0; Index < mGicNumInterrupts; Index++) {
|
||||
DisableInterruptSource (&gHardwareInterruptProtocol, Index);
|
||||
|
||||
// Set Priority
|
||||
RegOffset = Index / 4;
|
||||
RegShift = (Index % 4) * 8;
|
||||
MmioAndThenOr32 (
|
||||
PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPR + (4*RegOffset),
|
||||
~(0xff << RegShift),
|
||||
ARM_GIC_DEFAULT_PRIORITY << RegShift
|
||||
);
|
||||
}
|
||||
|
||||
// Configure interrupts for Primary Cpu
|
||||
CpuTarget = (1 << PcdGet32 (PcdGicPrimaryCoreId));
|
||||
CpuTarget |= (CpuTarget << 24) | (CpuTarget << 16) | (CpuTarget << 8);
|
||||
for (Index = 0; Index < (mGicNumInterrupts / 4); Index++) {
|
||||
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPTR + (Index*4), CpuTarget);
|
||||
}
|
||||
|
||||
// Set binary point reg to 0x7 (no preemption)
|
||||
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCBPR, 0x7);
|
||||
|
||||
// Set priority mask reg to 0xff to allow all priorities through
|
||||
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0xff);
|
||||
|
||||
// Enable gic cpu interface
|
||||
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x1);
|
||||
|
||||
// Enable gic distributor
|
||||
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x1);
|
||||
|
||||
// Initialize the array for the Interrupt Handlers
|
||||
gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&gHardwareInterruptHandle,
|
||||
&gHardwareInterruptProtocolGuid, &gHardwareInterruptProtocol,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Get the CPU protocol that this driver requires.
|
||||
//
|
||||
Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
//
|
||||
// Unregister the default exception handler.
|
||||
//
|
||||
Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, NULL);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
//
|
||||
// Register to receive interrupts
|
||||
//
|
||||
Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, IrqInterruptHandler);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
// Register for an ExitBootServicesEvent
|
||||
Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
/*++
|
||||
|
||||
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
|
||||
Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
|
||||
Portions copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
Gic.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Driver implementing the GIC interrupt controller protocol
|
||||
|
||||
--*/
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/ArmGicLib.h>
|
||||
|
||||
#include <Protocol/Cpu.h>
|
||||
#include <Protocol/HardwareInterrupt.h>
|
||||
|
||||
#define ARM_GIC_DEFAULT_PRIORITY 0x80
|
||||
|
||||
extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol;
|
||||
|
||||
//
|
||||
// Notifications
|
||||
//
|
||||
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
|
||||
|
||||
// Maximum Number of Interrupts
|
||||
UINTN mGicNumInterrupts = 0;
|
||||
|
||||
HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL;
|
||||
|
||||
/**
|
||||
Register Handler for the specified interrupt source.
|
||||
|
||||
@param This Instance pointer for this protocol
|
||||
@param Source Hardware source of the interrupt
|
||||
@param Handler Callback for interrupt. NULL to unregister
|
||||
|
||||
@retval EFI_SUCCESS Source was updated to support Handler.
|
||||
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RegisterInterruptSource (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN HARDWARE_INTERRUPT_HANDLER Handler
|
||||
)
|
||||
{
|
||||
if (Source > mGicNumInterrupts) {
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
gRegisteredInterruptHandlers[Source] = Handler;
|
||||
|
||||
// If the interrupt handler is unregistered then disable the interrupt
|
||||
if (NULL == Handler){
|
||||
return This->DisableInterruptSource (This, Source);
|
||||
} else {
|
||||
return This->EnableInterruptSource (This, Source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Enable interrupt source Source.
|
||||
|
||||
@param This Instance pointer for this protocol
|
||||
@param Source Hardware source of the interrupt
|
||||
|
||||
@retval EFI_SUCCESS Source interrupt enabled.
|
||||
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EnableInterruptSource (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
)
|
||||
{
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
|
||||
if (Source > mGicNumInterrupts) {
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// Calculate enable register offset and bit position
|
||||
RegOffset = Source / 32;
|
||||
RegShift = Source % 32;
|
||||
|
||||
// Write set-enable register
|
||||
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset), 1 << RegShift);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Disable interrupt source Source.
|
||||
|
||||
@param This Instance pointer for this protocol
|
||||
@param Source Hardware source of the interrupt
|
||||
|
||||
@retval EFI_SUCCESS Source interrupt disabled.
|
||||
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DisableInterruptSource (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
)
|
||||
{
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
|
||||
if (Source > mGicNumInterrupts) {
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// Calculate enable register offset and bit position
|
||||
RegOffset = Source / 32;
|
||||
RegShift = Source % 32;
|
||||
|
||||
// Write set-enable register
|
||||
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDICER + (4*RegOffset), 1 << RegShift);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Return current state of interrupt source Source.
|
||||
|
||||
@param This Instance pointer for this protocol
|
||||
@param Source Hardware source of the interrupt
|
||||
@param InterruptState TRUE: source enabled, FALSE: source disabled.
|
||||
|
||||
@retval EFI_SUCCESS InterruptState is valid
|
||||
@retval EFI_DEVICE_ERROR InterruptState is not valid
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetInterruptSourceState (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN BOOLEAN *InterruptState
|
||||
)
|
||||
{
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
|
||||
if (Source > mGicNumInterrupts) {
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// calculate enable register offset and bit position
|
||||
RegOffset = Source / 32;
|
||||
RegShift = Source % 32;
|
||||
|
||||
if ((MmioRead32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset)) & (1<<RegShift)) == 0) {
|
||||
*InterruptState = FALSE;
|
||||
} else {
|
||||
*InterruptState = TRUE;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Signal to the hardware that the End Of Intrrupt state
|
||||
has been reached.
|
||||
|
||||
@param This Instance pointer for this protocol
|
||||
@param Source Hardware source of the interrupt
|
||||
|
||||
@retval EFI_SUCCESS Source interrupt EOI'ed.
|
||||
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
EndOfInterrupt (
|
||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source
|
||||
)
|
||||
{
|
||||
if (Source > mGicNumInterrupts) {
|
||||
ASSERT(FALSE);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCEIOR, Source);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
|
||||
|
||||
@param InterruptType Defines the type of interrupt or exception that
|
||||
occurred on the processor.This parameter is processor architecture specific.
|
||||
@param SystemContext A pointer to the processor context when
|
||||
the interrupt occurred on the processor.
|
||||
|
||||
@return None
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
IrqInterruptHandler (
|
||||
IN EFI_EXCEPTION_TYPE InterruptType,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
UINT32 GicInterrupt;
|
||||
HARDWARE_INTERRUPT_HANDLER InterruptHandler;
|
||||
|
||||
GicInterrupt = MmioRead32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCIAR);
|
||||
|
||||
// Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt).
|
||||
if (GicInterrupt >= mGicNumInterrupts) {
|
||||
// The special interrupt do not need to be acknowledge
|
||||
return;
|
||||
}
|
||||
|
||||
InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt];
|
||||
if (InterruptHandler != NULL) {
|
||||
// Call the registered interrupt handler.
|
||||
InterruptHandler (GicInterrupt, SystemContext);
|
||||
} else {
|
||||
DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
|
||||
}
|
||||
|
||||
EndOfInterrupt (&gHardwareInterruptProtocol, GicInterrupt);
|
||||
}
|
||||
|
||||
//
|
||||
// Making this global saves a few bytes in image size
|
||||
//
|
||||
EFI_HANDLE gHardwareInterruptHandle = NULL;
|
||||
|
||||
//
|
||||
// The protocol instance produced by this driver
|
||||
//
|
||||
EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol = {
|
||||
RegisterInterruptSource,
|
||||
EnableInterruptSource,
|
||||
DisableInterruptSource,
|
||||
GetInterruptSourceState,
|
||||
EndOfInterrupt
|
||||
};
|
||||
|
||||
/**
|
||||
Shutdown our hardware
|
||||
|
||||
DXE Core will disable interrupts and turn off the timer and disable interrupts
|
||||
after all the event handlers have run.
|
||||
|
||||
@param[in] Event The Event that is being processed
|
||||
@param[in] Context Event Context
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ExitBootServicesEvent (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
// Acknowledge all pending interrupts
|
||||
for (Index = 0; Index < mGicNumInterrupts; Index++) {
|
||||
DisableInterruptSource (&gHardwareInterruptProtocol, Index);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < mGicNumInterrupts; Index++) {
|
||||
EndOfInterrupt (&gHardwareInterruptProtocol, Index);
|
||||
}
|
||||
|
||||
// Disable Gic Interface
|
||||
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x0);
|
||||
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0x0);
|
||||
|
||||
// Disable Gic Distributor
|
||||
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x0);
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize the state information for the CPU Architectural Protocol
|
||||
|
||||
@param ImageHandle of the loaded driver
|
||||
@param SystemTable Pointer to the System Table
|
||||
|
||||
@retval EFI_SUCCESS Protocol registered
|
||||
@retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
|
||||
@retval EFI_DEVICE_ERROR Hardware problems
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
InterruptDxeInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
UINT32 RegOffset;
|
||||
UINTN RegShift;
|
||||
EFI_CPU_ARCH_PROTOCOL *Cpu;
|
||||
UINT32 CpuTarget;
|
||||
|
||||
// Check PcdGicPrimaryCoreId has been set in case the Primary Core is not the core 0 of Cluster 0
|
||||
DEBUG_CODE_BEGIN();
|
||||
if ((PcdGet32(PcdArmPrimaryCore) != 0) && (PcdGet32 (PcdGicPrimaryCoreId) == 0)) {
|
||||
DEBUG((EFI_D_WARN,"Warning: the PCD PcdGicPrimaryCoreId does not seem to be set up for the configuration.\n"));
|
||||
}
|
||||
DEBUG_CODE_END();
|
||||
|
||||
// Make sure the Interrupt Controller Protocol is not already installed in the system.
|
||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
|
||||
|
||||
mGicNumInterrupts = ArmGicGetMaxNumInterrupts (PcdGet32(PcdGicDistributorBase));
|
||||
|
||||
for (Index = 0; Index < mGicNumInterrupts; Index++) {
|
||||
DisableInterruptSource (&gHardwareInterruptProtocol, Index);
|
||||
|
||||
// Set Priority
|
||||
RegOffset = Index / 4;
|
||||
RegShift = (Index % 4) * 8;
|
||||
MmioAndThenOr32 (
|
||||
PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPR + (4*RegOffset),
|
||||
~(0xff << RegShift),
|
||||
ARM_GIC_DEFAULT_PRIORITY << RegShift
|
||||
);
|
||||
}
|
||||
|
||||
// Configure interrupts for Primary Cpu
|
||||
CpuTarget = (1 << PcdGet32 (PcdGicPrimaryCoreId));
|
||||
CpuTarget |= (CpuTarget << 24) | (CpuTarget << 16) | (CpuTarget << 8);
|
||||
for (Index = 0; Index < (mGicNumInterrupts / 4); Index++) {
|
||||
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPTR + (Index*4), CpuTarget);
|
||||
}
|
||||
|
||||
// Set binary point reg to 0x7 (no preemption)
|
||||
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCBPR, 0x7);
|
||||
|
||||
// Set priority mask reg to 0xff to allow all priorities through
|
||||
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0xff);
|
||||
|
||||
// Enable gic cpu interface
|
||||
MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x1);
|
||||
|
||||
// Enable gic distributor
|
||||
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x1);
|
||||
|
||||
// Initialize the array for the Interrupt Handlers
|
||||
gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&gHardwareInterruptHandle,
|
||||
&gHardwareInterruptProtocolGuid, &gHardwareInterruptProtocol,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Get the CPU protocol that this driver requires.
|
||||
//
|
||||
Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
//
|
||||
// Unregister the default exception handler.
|
||||
//
|
||||
Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, NULL);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
//
|
||||
// Register to receive interrupts
|
||||
//
|
||||
Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, IrqInterruptHandler);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
// Register for an ExitBootServicesEvent
|
||||
Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@@ -1,57 +1,57 @@
|
||||
#/** @file
|
||||
#
|
||||
# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
|
||||
# Copyright (c) 2012, ARM Ltd. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = PL390GicDxe
|
||||
FILE_GUID = DE371F7C-DEC4-4D21-ADF1-593ABCC15882
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
|
||||
ENTRY_POINT = InterruptDxeInitialize
|
||||
|
||||
|
||||
[Sources.common]
|
||||
PL390Gic.c
|
||||
PL390GicDxe.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
ArmPkg/ArmPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
DebugLib
|
||||
PrintLib
|
||||
MemoryAllocationLib
|
||||
UefiDriverEntryPoint
|
||||
IoLib
|
||||
|
||||
[Protocols]
|
||||
gHardwareInterruptProtocolGuid
|
||||
gEfiCpuArchProtocolGuid
|
||||
|
||||
[FixedPcd.common]
|
||||
gArmTokenSpaceGuid.PcdGicDistributorBase
|
||||
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
|
||||
|
||||
gArmTokenSpaceGuid.PcdArmPrimaryCore
|
||||
gArmTokenSpaceGuid.PcdGicPrimaryCoreId
|
||||
|
||||
[Depex]
|
||||
gEfiCpuArchProtocolGuid
|
||||
#/** @file
|
||||
#
|
||||
# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
|
||||
# Copyright (c) 2012, ARM Ltd. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = PL390GicDxe
|
||||
FILE_GUID = DE371F7C-DEC4-4D21-ADF1-593ABCC15882
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
|
||||
ENTRY_POINT = InterruptDxeInitialize
|
||||
|
||||
|
||||
[Sources.common]
|
||||
PL390Gic.c
|
||||
PL390GicDxe.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
ArmPkg/ArmPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
DebugLib
|
||||
PrintLib
|
||||
MemoryAllocationLib
|
||||
UefiDriverEntryPoint
|
||||
IoLib
|
||||
|
||||
[Protocols]
|
||||
gHardwareInterruptProtocolGuid
|
||||
gEfiCpuArchProtocolGuid
|
||||
|
||||
[FixedPcd.common]
|
||||
gArmTokenSpaceGuid.PcdGicDistributorBase
|
||||
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
|
||||
|
||||
gArmTokenSpaceGuid.PcdArmPrimaryCore
|
||||
gArmTokenSpaceGuid.PcdGicPrimaryCoreId
|
||||
|
||||
[Depex]
|
||||
gEfiCpuArchProtocolGuid
|
||||
|
@@ -1,380 +1,380 @@
|
||||
/** @file
|
||||
Timer Architecture Protocol driver of the ARM flavor
|
||||
|
||||
Copyright (c) 2011 ARM Ltd. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/ArmV7ArchTimerLib.h>
|
||||
|
||||
#include <Protocol/Timer.h>
|
||||
#include <Protocol/HardwareInterrupt.h>
|
||||
|
||||
// The notification function to call on every timer interrupt.
|
||||
EFI_TIMER_NOTIFY mTimerNotifyFunction = (EFI_TIMER_NOTIFY)NULL;
|
||||
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
|
||||
|
||||
// The current period of the timer interrupt
|
||||
UINT64 mTimerPeriod = 0;
|
||||
|
||||
// Cached copy of the Hardware Interrupt protocol instance
|
||||
EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
|
||||
|
||||
/**
|
||||
This function registers the handler NotifyFunction so it is called every time
|
||||
the timer interrupt fires. It also passes the amount of time since the last
|
||||
handler call to the NotifyFunction. If NotifyFunction is NULL, then the
|
||||
handler is unregistered. If the handler is registered, then EFI_SUCCESS is
|
||||
returned. If the CPU does not support registering a timer interrupt handler,
|
||||
then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler
|
||||
when a handler is already registered, then EFI_ALREADY_STARTED is returned.
|
||||
If an attempt is made to unregister a handler when a handler is not registered,
|
||||
then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to
|
||||
register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
|
||||
is returned.
|
||||
|
||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||
@param NotifyFunction The function to call when a timer interrupt fires. This
|
||||
function executes at TPL_HIGH_LEVEL. The DXE Core will
|
||||
register a handler for the timer interrupt, so it can know
|
||||
how much time has passed. This information is used to
|
||||
signal timer based events. NULL will unregister the handler.
|
||||
@retval EFI_SUCCESS The timer handler was registered.
|
||||
@retval EFI_UNSUPPORTED The platform does not support timer interrupts.
|
||||
@retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already
|
||||
registered.
|
||||
@retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not
|
||||
previously registered.
|
||||
@retval EFI_DEVICE_ERROR The timer handler could not be registered.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerDriverRegisterHandler (
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This,
|
||||
IN EFI_TIMER_NOTIFY NotifyFunction
|
||||
)
|
||||
{
|
||||
if ((NotifyFunction == NULL) && (mTimerNotifyFunction == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((NotifyFunction != NULL) && (mTimerNotifyFunction != NULL)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
mTimerNotifyFunction = NotifyFunction;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Disable the timer
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ExitBootServicesEvent (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
ArmArchTimerDisableTimer ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
This function adjusts the period of timer interrupts to the value specified
|
||||
by TimerPeriod. If the timer period is updated, then the selected timer
|
||||
period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If
|
||||
the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
|
||||
If an error occurs while attempting to update the timer period, then the
|
||||
timer hardware will be put back in its state prior to this call, and
|
||||
EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt
|
||||
is disabled. This is not the same as disabling the CPU's interrupts.
|
||||
Instead, it must either turn off the timer hardware, or it must adjust the
|
||||
interrupt controller so that a CPU interrupt is not generated when the timer
|
||||
interrupt fires.
|
||||
|
||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||
@param TimerPeriod The rate to program the timer interrupt in 100 nS units. If
|
||||
the timer hardware is not programmable, then EFI_UNSUPPORTED is
|
||||
returned. If the timer is programmable, then the timer period
|
||||
will be rounded up to the nearest timer period that is supported
|
||||
by the timer hardware. If TimerPeriod is set to 0, then the
|
||||
timer interrupts will be disabled.
|
||||
|
||||
|
||||
@retval EFI_SUCCESS The timer period was changed.
|
||||
@retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt.
|
||||
@retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerDriverSetTimerPeriod (
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This,
|
||||
IN UINT64 TimerPeriod
|
||||
)
|
||||
{
|
||||
UINT64 TimerTicks;
|
||||
|
||||
// Always disable the timer
|
||||
ArmArchTimerDisableTimer ();
|
||||
|
||||
if (TimerPeriod != 0) {
|
||||
// Convert TimerPeriod to micro sec units
|
||||
TimerTicks = DivU64x32 (TimerPeriod, 10);
|
||||
|
||||
TimerTicks = MultU64x32 (TimerTicks, (PcdGet32(PcdArmArchTimerFreqInHz)/1000000));
|
||||
|
||||
ArmArchTimerSetTimerVal((UINTN)TimerTicks);
|
||||
|
||||
// Enable the timer
|
||||
ArmArchTimerEnableTimer ();
|
||||
}
|
||||
|
||||
// Save the new timer period
|
||||
mTimerPeriod = TimerPeriod;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This function retrieves the period of timer interrupts in 100 ns units,
|
||||
returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod
|
||||
is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is
|
||||
returned, then the timer is currently disabled.
|
||||
|
||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||
@param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If
|
||||
0 is returned, then the timer is currently disabled.
|
||||
|
||||
|
||||
@retval EFI_SUCCESS The timer period was returned in TimerPeriod.
|
||||
@retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerDriverGetTimerPeriod (
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This,
|
||||
OUT UINT64 *TimerPeriod
|
||||
)
|
||||
{
|
||||
if (TimerPeriod == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*TimerPeriod = mTimerPeriod;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This function generates a soft timer interrupt. If the platform does not support soft
|
||||
timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
|
||||
If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
|
||||
service, then a soft timer interrupt will be generated. If the timer interrupt is
|
||||
enabled when this service is called, then the registered handler will be invoked. The
|
||||
registered handler should not be able to distinguish a hardware-generated timer
|
||||
interrupt from a software-generated timer interrupt.
|
||||
|
||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||
|
||||
@retval EFI_SUCCESS The soft timer interrupt was generated.
|
||||
@retval EFI_UNSUPPORTED The platform does not support the generation of soft timer interrupts.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerDriverGenerateSoftInterrupt (
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
Interface structure for the Timer Architectural Protocol.
|
||||
|
||||
@par Protocol Description:
|
||||
This protocol provides the services to initialize a periodic timer
|
||||
interrupt, and to register a handler that is called each time the timer
|
||||
interrupt fires. It may also provide a service to adjust the rate of the
|
||||
periodic timer interrupt. When a timer interrupt occurs, the handler is
|
||||
passed the amount of time that has passed since the previous timer
|
||||
interrupt.
|
||||
|
||||
@param RegisterHandler
|
||||
Registers a handler that will be called each time the
|
||||
timer interrupt fires. TimerPeriod defines the minimum
|
||||
time between timer interrupts, so TimerPeriod will also
|
||||
be the minimum time between calls to the registered
|
||||
handler.
|
||||
|
||||
@param SetTimerPeriod
|
||||
Sets the period of the timer interrupt in 100 nS units.
|
||||
This function is optional, and may return EFI_UNSUPPORTED.
|
||||
If this function is supported, then the timer period will
|
||||
be rounded up to the nearest supported timer period.
|
||||
|
||||
|
||||
@param GetTimerPeriod
|
||||
Retrieves the period of the timer interrupt in 100 nS units.
|
||||
|
||||
@param GenerateSoftInterrupt
|
||||
Generates a soft timer interrupt that simulates the firing of
|
||||
the timer interrupt. This service can be used to invoke the registered handler if the timer interrupt has been masked for
|
||||
a period of time.
|
||||
|
||||
**/
|
||||
EFI_TIMER_ARCH_PROTOCOL gTimer = {
|
||||
TimerDriverRegisterHandler,
|
||||
TimerDriverSetTimerPeriod,
|
||||
TimerDriverGetTimerPeriod,
|
||||
TimerDriverGenerateSoftInterrupt
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
C Interrupt Handler called in the interrupt context when Source interrupt is active.
|
||||
|
||||
|
||||
@param Source Source of the interrupt. Hardware routing off a specific platform defines
|
||||
what source means.
|
||||
|
||||
@param SystemContext Pointer to system register context. Mostly used by debuggers and will
|
||||
update the system context after the return from the interrupt if
|
||||
modified. Don't change these values unless you know what you are doing
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
TimerInterruptHandler (
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
EFI_TPL OriginalTPL;
|
||||
|
||||
//
|
||||
// DXE core uses this callback for the EFI timer tick. The DXE core uses locks
|
||||
// that raise to TPL_HIGH and then restore back to current level. Thus we need
|
||||
// to make sure TPL level is set to TPL_HIGH while we are handling the timer tick.
|
||||
//
|
||||
OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
||||
|
||||
// Check if the timer interrupt is active
|
||||
if ((ArmArchTimerGetTimerCtrlReg () ) & ARM_ARCH_TIMER_ISTATUS) {
|
||||
|
||||
// Signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers
|
||||
gInterrupt->EndOfInterrupt (gInterrupt, Source);
|
||||
|
||||
if (mTimerNotifyFunction) {
|
||||
mTimerNotifyFunction (mTimerPeriod);
|
||||
}
|
||||
|
||||
// Reload the Timer
|
||||
TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod));
|
||||
}
|
||||
|
||||
// Enable timer interrupts
|
||||
gInterrupt->EnableInterruptSource (gInterrupt, Source);
|
||||
|
||||
gBS->RestoreTPL (OriginalTPL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initialize the state information for the Timer Architectural Protocol and
|
||||
the Timer Debug support protocol that allows the debugger to break into a
|
||||
running program.
|
||||
|
||||
@param ImageHandle of the loaded driver
|
||||
@param SystemTable Pointer to the System Table
|
||||
|
||||
@retval EFI_SUCCESS Protocol registered
|
||||
@retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
|
||||
@retval EFI_DEVICE_ERROR Hardware problems
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_HANDLE Handle = NULL;
|
||||
EFI_STATUS Status;
|
||||
UINTN TimerCtrlReg;
|
||||
|
||||
if (ArmIsArchTimerImplemented () == 0) {
|
||||
DEBUG ((EFI_D_ERROR, "ARM Architectural Timer is not available in the CPU, hence cann't use this Driver \n"));
|
||||
ASSERT (0);
|
||||
}
|
||||
|
||||
// Find the interrupt controller protocol. ASSERT if not found.
|
||||
Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// Disable the timer
|
||||
Status = TimerDriverSetTimerPeriod (&gTimer, 0);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// Install secure and Non-secure interrupt handlers
|
||||
// Note: Because it is not possible to determine the security state of the
|
||||
// CPU dynamically, we just install interrupt handler for both sec and non-sec
|
||||
// timer PPI
|
||||
Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerSecIntrNum), TimerInterruptHandler);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerIntrNum), TimerInterruptHandler);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// Unmask timer interrupts
|
||||
TimerCtrlReg = ArmArchTimerGetTimerCtrlReg ();
|
||||
TimerCtrlReg &= ~ARM_ARCH_TIMER_IMASK;
|
||||
ArmArchTimerSetTimerCtrlReg (TimerCtrlReg);
|
||||
|
||||
// Set up default timer
|
||||
Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// Install the Timer Architectural Protocol onto a new handle
|
||||
Status = gBS->InstallMultipleProtocolInterfaces(
|
||||
&Handle,
|
||||
&gEfiTimerArchProtocolGuid, &gTimer,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
// enable Secure timer interrupts
|
||||
Status = gInterrupt->EnableInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerSecIntrNum));
|
||||
|
||||
// enable NonSecure timer interrupts
|
||||
Status = gInterrupt->EnableInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerIntrNum));
|
||||
|
||||
// Register for an ExitBootServicesEvent
|
||||
Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
/** @file
|
||||
Timer Architecture Protocol driver of the ARM flavor
|
||||
|
||||
Copyright (c) 2011 ARM Ltd. All rights reserved.<BR>
|
||||
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Library/ArmLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/ArmV7ArchTimerLib.h>
|
||||
|
||||
#include <Protocol/Timer.h>
|
||||
#include <Protocol/HardwareInterrupt.h>
|
||||
|
||||
// The notification function to call on every timer interrupt.
|
||||
EFI_TIMER_NOTIFY mTimerNotifyFunction = (EFI_TIMER_NOTIFY)NULL;
|
||||
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
|
||||
|
||||
// The current period of the timer interrupt
|
||||
UINT64 mTimerPeriod = 0;
|
||||
|
||||
// Cached copy of the Hardware Interrupt protocol instance
|
||||
EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
|
||||
|
||||
/**
|
||||
This function registers the handler NotifyFunction so it is called every time
|
||||
the timer interrupt fires. It also passes the amount of time since the last
|
||||
handler call to the NotifyFunction. If NotifyFunction is NULL, then the
|
||||
handler is unregistered. If the handler is registered, then EFI_SUCCESS is
|
||||
returned. If the CPU does not support registering a timer interrupt handler,
|
||||
then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler
|
||||
when a handler is already registered, then EFI_ALREADY_STARTED is returned.
|
||||
If an attempt is made to unregister a handler when a handler is not registered,
|
||||
then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to
|
||||
register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
|
||||
is returned.
|
||||
|
||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||
@param NotifyFunction The function to call when a timer interrupt fires. This
|
||||
function executes at TPL_HIGH_LEVEL. The DXE Core will
|
||||
register a handler for the timer interrupt, so it can know
|
||||
how much time has passed. This information is used to
|
||||
signal timer based events. NULL will unregister the handler.
|
||||
@retval EFI_SUCCESS The timer handler was registered.
|
||||
@retval EFI_UNSUPPORTED The platform does not support timer interrupts.
|
||||
@retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already
|
||||
registered.
|
||||
@retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not
|
||||
previously registered.
|
||||
@retval EFI_DEVICE_ERROR The timer handler could not be registered.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerDriverRegisterHandler (
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This,
|
||||
IN EFI_TIMER_NOTIFY NotifyFunction
|
||||
)
|
||||
{
|
||||
if ((NotifyFunction == NULL) && (mTimerNotifyFunction == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((NotifyFunction != NULL) && (mTimerNotifyFunction != NULL)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
mTimerNotifyFunction = NotifyFunction;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Disable the timer
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
ExitBootServicesEvent (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
ArmArchTimerDisableTimer ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
This function adjusts the period of timer interrupts to the value specified
|
||||
by TimerPeriod. If the timer period is updated, then the selected timer
|
||||
period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If
|
||||
the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
|
||||
If an error occurs while attempting to update the timer period, then the
|
||||
timer hardware will be put back in its state prior to this call, and
|
||||
EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt
|
||||
is disabled. This is not the same as disabling the CPU's interrupts.
|
||||
Instead, it must either turn off the timer hardware, or it must adjust the
|
||||
interrupt controller so that a CPU interrupt is not generated when the timer
|
||||
interrupt fires.
|
||||
|
||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||
@param TimerPeriod The rate to program the timer interrupt in 100 nS units. If
|
||||
the timer hardware is not programmable, then EFI_UNSUPPORTED is
|
||||
returned. If the timer is programmable, then the timer period
|
||||
will be rounded up to the nearest timer period that is supported
|
||||
by the timer hardware. If TimerPeriod is set to 0, then the
|
||||
timer interrupts will be disabled.
|
||||
|
||||
|
||||
@retval EFI_SUCCESS The timer period was changed.
|
||||
@retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt.
|
||||
@retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerDriverSetTimerPeriod (
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This,
|
||||
IN UINT64 TimerPeriod
|
||||
)
|
||||
{
|
||||
UINT64 TimerTicks;
|
||||
|
||||
// Always disable the timer
|
||||
ArmArchTimerDisableTimer ();
|
||||
|
||||
if (TimerPeriod != 0) {
|
||||
// Convert TimerPeriod to micro sec units
|
||||
TimerTicks = DivU64x32 (TimerPeriod, 10);
|
||||
|
||||
TimerTicks = MultU64x32 (TimerTicks, (PcdGet32(PcdArmArchTimerFreqInHz)/1000000));
|
||||
|
||||
ArmArchTimerSetTimerVal((UINTN)TimerTicks);
|
||||
|
||||
// Enable the timer
|
||||
ArmArchTimerEnableTimer ();
|
||||
}
|
||||
|
||||
// Save the new timer period
|
||||
mTimerPeriod = TimerPeriod;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This function retrieves the period of timer interrupts in 100 ns units,
|
||||
returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod
|
||||
is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is
|
||||
returned, then the timer is currently disabled.
|
||||
|
||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||
@param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If
|
||||
0 is returned, then the timer is currently disabled.
|
||||
|
||||
|
||||
@retval EFI_SUCCESS The timer period was returned in TimerPeriod.
|
||||
@retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerDriverGetTimerPeriod (
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This,
|
||||
OUT UINT64 *TimerPeriod
|
||||
)
|
||||
{
|
||||
if (TimerPeriod == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*TimerPeriod = mTimerPeriod;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
This function generates a soft timer interrupt. If the platform does not support soft
|
||||
timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
|
||||
If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
|
||||
service, then a soft timer interrupt will be generated. If the timer interrupt is
|
||||
enabled when this service is called, then the registered handler will be invoked. The
|
||||
registered handler should not be able to distinguish a hardware-generated timer
|
||||
interrupt from a software-generated timer interrupt.
|
||||
|
||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||
|
||||
@retval EFI_SUCCESS The soft timer interrupt was generated.
|
||||
@retval EFI_UNSUPPORTED The platform does not support the generation of soft timer interrupts.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerDriverGenerateSoftInterrupt (
|
||||
IN EFI_TIMER_ARCH_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
Interface structure for the Timer Architectural Protocol.
|
||||
|
||||
@par Protocol Description:
|
||||
This protocol provides the services to initialize a periodic timer
|
||||
interrupt, and to register a handler that is called each time the timer
|
||||
interrupt fires. It may also provide a service to adjust the rate of the
|
||||
periodic timer interrupt. When a timer interrupt occurs, the handler is
|
||||
passed the amount of time that has passed since the previous timer
|
||||
interrupt.
|
||||
|
||||
@param RegisterHandler
|
||||
Registers a handler that will be called each time the
|
||||
timer interrupt fires. TimerPeriod defines the minimum
|
||||
time between timer interrupts, so TimerPeriod will also
|
||||
be the minimum time between calls to the registered
|
||||
handler.
|
||||
|
||||
@param SetTimerPeriod
|
||||
Sets the period of the timer interrupt in 100 nS units.
|
||||
This function is optional, and may return EFI_UNSUPPORTED.
|
||||
If this function is supported, then the timer period will
|
||||
be rounded up to the nearest supported timer period.
|
||||
|
||||
|
||||
@param GetTimerPeriod
|
||||
Retrieves the period of the timer interrupt in 100 nS units.
|
||||
|
||||
@param GenerateSoftInterrupt
|
||||
Generates a soft timer interrupt that simulates the firing of
|
||||
the timer interrupt. This service can be used to invoke the registered handler if the timer interrupt has been masked for
|
||||
a period of time.
|
||||
|
||||
**/
|
||||
EFI_TIMER_ARCH_PROTOCOL gTimer = {
|
||||
TimerDriverRegisterHandler,
|
||||
TimerDriverSetTimerPeriod,
|
||||
TimerDriverGetTimerPeriod,
|
||||
TimerDriverGenerateSoftInterrupt
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
C Interrupt Handler called in the interrupt context when Source interrupt is active.
|
||||
|
||||
|
||||
@param Source Source of the interrupt. Hardware routing off a specific platform defines
|
||||
what source means.
|
||||
|
||||
@param SystemContext Pointer to system register context. Mostly used by debuggers and will
|
||||
update the system context after the return from the interrupt if
|
||||
modified. Don't change these values unless you know what you are doing
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
TimerInterruptHandler (
|
||||
IN HARDWARE_INTERRUPT_SOURCE Source,
|
||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||
)
|
||||
{
|
||||
EFI_TPL OriginalTPL;
|
||||
|
||||
//
|
||||
// DXE core uses this callback for the EFI timer tick. The DXE core uses locks
|
||||
// that raise to TPL_HIGH and then restore back to current level. Thus we need
|
||||
// to make sure TPL level is set to TPL_HIGH while we are handling the timer tick.
|
||||
//
|
||||
OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
|
||||
|
||||
// Check if the timer interrupt is active
|
||||
if ((ArmArchTimerGetTimerCtrlReg () ) & ARM_ARCH_TIMER_ISTATUS) {
|
||||
|
||||
// Signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers
|
||||
gInterrupt->EndOfInterrupt (gInterrupt, Source);
|
||||
|
||||
if (mTimerNotifyFunction) {
|
||||
mTimerNotifyFunction (mTimerPeriod);
|
||||
}
|
||||
|
||||
// Reload the Timer
|
||||
TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod));
|
||||
}
|
||||
|
||||
// Enable timer interrupts
|
||||
gInterrupt->EnableInterruptSource (gInterrupt, Source);
|
||||
|
||||
gBS->RestoreTPL (OriginalTPL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initialize the state information for the Timer Architectural Protocol and
|
||||
the Timer Debug support protocol that allows the debugger to break into a
|
||||
running program.
|
||||
|
||||
@param ImageHandle of the loaded driver
|
||||
@param SystemTable Pointer to the System Table
|
||||
|
||||
@retval EFI_SUCCESS Protocol registered
|
||||
@retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
|
||||
@retval EFI_DEVICE_ERROR Hardware problems
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
TimerInitialize (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_HANDLE Handle = NULL;
|
||||
EFI_STATUS Status;
|
||||
UINTN TimerCtrlReg;
|
||||
|
||||
if (ArmIsArchTimerImplemented () == 0) {
|
||||
DEBUG ((EFI_D_ERROR, "ARM Architectural Timer is not available in the CPU, hence cann't use this Driver \n"));
|
||||
ASSERT (0);
|
||||
}
|
||||
|
||||
// Find the interrupt controller protocol. ASSERT if not found.
|
||||
Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// Disable the timer
|
||||
Status = TimerDriverSetTimerPeriod (&gTimer, 0);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// Install secure and Non-secure interrupt handlers
|
||||
// Note: Because it is not possible to determine the security state of the
|
||||
// CPU dynamically, we just install interrupt handler for both sec and non-sec
|
||||
// timer PPI
|
||||
Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerSecIntrNum), TimerInterruptHandler);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerIntrNum), TimerInterruptHandler);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// Unmask timer interrupts
|
||||
TimerCtrlReg = ArmArchTimerGetTimerCtrlReg ();
|
||||
TimerCtrlReg &= ~ARM_ARCH_TIMER_IMASK;
|
||||
ArmArchTimerSetTimerCtrlReg (TimerCtrlReg);
|
||||
|
||||
// Set up default timer
|
||||
Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod)); // TIMER_DEFAULT_PERIOD
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
// Install the Timer Architectural Protocol onto a new handle
|
||||
Status = gBS->InstallMultipleProtocolInterfaces(
|
||||
&Handle,
|
||||
&gEfiTimerArchProtocolGuid, &gTimer,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
// enable Secure timer interrupts
|
||||
Status = gInterrupt->EnableInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerSecIntrNum));
|
||||
|
||||
// enable NonSecure timer interrupts
|
||||
Status = gInterrupt->EnableInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerIntrNum));
|
||||
|
||||
// Register for an ExitBootServicesEvent
|
||||
Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
@@ -1,59 +1,59 @@
|
||||
#/** @file
|
||||
#
|
||||
# Component description file for Timer DXE module
|
||||
#
|
||||
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = ArmTimerDxe
|
||||
FILE_GUID = 49ea041e-6752-42ca-b0b1-7344fe2546b7
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
|
||||
ENTRY_POINT = TimerInitialize
|
||||
|
||||
[Sources.common]
|
||||
TimerDxe.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
ArmPkg/ArmPkg.dec
|
||||
ArmPlatformPkg/ArmPlatformPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
ArmLib
|
||||
BaseLib
|
||||
UefiRuntimeServicesTableLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
UefiDriverEntryPoint
|
||||
IoLib
|
||||
|
||||
[Guids]
|
||||
|
||||
[Protocols]
|
||||
gEfiTimerArchProtocolGuid
|
||||
gHardwareInterruptProtocolGuid
|
||||
|
||||
[Pcd.common]
|
||||
gEmbeddedTokenSpaceGuid.PcdTimerPeriod
|
||||
gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum
|
||||
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum
|
||||
gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz
|
||||
|
||||
[Depex]
|
||||
gHardwareInterruptProtocolGuid
|
||||
|
||||
#/** @file
|
||||
#
|
||||
# Component description file for Timer DXE module
|
||||
#
|
||||
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = ArmTimerDxe
|
||||
FILE_GUID = 49ea041e-6752-42ca-b0b1-7344fe2546b7
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
|
||||
ENTRY_POINT = TimerInitialize
|
||||
|
||||
[Sources.common]
|
||||
TimerDxe.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
EmbeddedPkg/EmbeddedPkg.dec
|
||||
ArmPkg/ArmPkg.dec
|
||||
ArmPlatformPkg/ArmPlatformPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
ArmLib
|
||||
BaseLib
|
||||
UefiRuntimeServicesTableLib
|
||||
UefiLib
|
||||
UefiBootServicesTableLib
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
UefiDriverEntryPoint
|
||||
IoLib
|
||||
|
||||
[Guids]
|
||||
|
||||
[Protocols]
|
||||
gEfiTimerArchProtocolGuid
|
||||
gHardwareInterruptProtocolGuid
|
||||
|
||||
[Pcd.common]
|
||||
gEmbeddedTokenSpaceGuid.PcdTimerPeriod
|
||||
gArmTokenSpaceGuid.PcdArmArchTimerSecIntrNum
|
||||
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum
|
||||
gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz
|
||||
|
||||
[Depex]
|
||||
gHardwareInterruptProtocolGuid
|
||||
|
Reference in New Issue
Block a user