forked from xuos/xiuos
add armv7-a start file
This commit is contained in:
parent
a3094c1dd6
commit
4f7f98b0e9
|
@ -0,0 +1,45 @@
|
||||||
|
extern void _svcall(uintptr_t* contex);
|
||||||
|
|
||||||
|
x_base __attribute__((naked)) DisableLocalInterrupt()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__((naked)) EnableLocalInterrupt(x_base level)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 ArchEnableHwIrq(uint32_t irq_num)
|
||||||
|
{
|
||||||
|
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 ArchDisableHwIrq(uint32_t irq_num)
|
||||||
|
{
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void KTaskOsAssignAfterIrq(void *context);
|
||||||
|
|
||||||
|
void IsrEntry()
|
||||||
|
{
|
||||||
|
uint32_t ipsr;
|
||||||
|
|
||||||
|
// __asm__ volatile("MRS %0, IPSR" : "=r"(ipsr));
|
||||||
|
|
||||||
|
isrManager.done->incCounter();
|
||||||
|
isrManager.done->handleIrq(ipsr);
|
||||||
|
KTaskOsAssignAfterIrq(NONE);
|
||||||
|
isrManager.done->decCounter();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t *Svcall(unsigned int ipsr, uintptr_t* contex )
|
||||||
|
{
|
||||||
|
#ifdef TASK_ISOLATION
|
||||||
|
_svcall(contex);
|
||||||
|
#endif
|
||||||
|
return contex;
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
|
||||||
|
.equ Mode_USR, 0x10
|
||||||
|
.equ Mode_FIQ, 0x11
|
||||||
|
.equ Mode_IRQ, 0x12
|
||||||
|
.equ Mode_SVC, 0x13
|
||||||
|
.equ Mode_ABT, 0x17
|
||||||
|
.equ Mode_UND, 0x1B
|
||||||
|
.equ Mode_SYS, 0x1F
|
||||||
|
|
||||||
|
.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled
|
||||||
|
.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled
|
||||||
|
|
||||||
|
.equ STACK_SIZE, 0x00000100
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
/* set the cpu to SVC32 mode and disable interrupt */
|
||||||
|
mrs r0, cpsr
|
||||||
|
bic r0, r0, #0x1f
|
||||||
|
orr r0, r0, #0x13
|
||||||
|
msr cpsr_c, r0
|
||||||
|
|
||||||
|
mrc p15, 0, r0, c1, c0, 0
|
||||||
|
bic r0, #(1 << 12) /* i cache */
|
||||||
|
bic r0, #(1 << 2) /* d cache */
|
||||||
|
bic r0, #(1 << 0) /* mmu */
|
||||||
|
mcr p15, 0, r0, c1, c0, 0
|
||||||
|
|
||||||
|
ldr r0, =stack_top
|
||||||
|
|
||||||
|
@ Set the startup stack for svc
|
||||||
|
mov sp, r0
|
||||||
|
|
||||||
|
@ Enter Undefined Instruction Mode and set its Stack Pointer
|
||||||
|
msr cpsr_c, #Mode_UND|I_Bit|F_Bit
|
||||||
|
mov sp, r0
|
||||||
|
sub r0, r0, #STACK_SIZE
|
||||||
|
|
||||||
|
@ Enter Abort Mode and set its Stack Pointer
|
||||||
|
msr cpsr_c, #Mode_ABT|I_Bit|F_Bit
|
||||||
|
mov sp, r0
|
||||||
|
sub r0, r0, #STACK_SIZE
|
||||||
|
|
||||||
|
@ Enter FIQ Mode and set its Stack Pointer
|
||||||
|
msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit
|
||||||
|
mov sp, r0
|
||||||
|
sub r0, r0, #STACK_SIZE
|
||||||
|
|
||||||
|
@ Enter IRQ Mode and set its Stack Pointer
|
||||||
|
msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit
|
||||||
|
mov sp, r0
|
||||||
|
sub r0, r0, #STACK_SIZE
|
||||||
|
|
||||||
|
/* come back to SVC mode */
|
||||||
|
msr cpsr_c, #Mode_SVC|I_Bit|F_Bit
|
||||||
|
|
||||||
|
/* clear .bss */
|
||||||
|
mov r0, #0 /* get a zero */
|
||||||
|
ldr r1,=BSS_START /* bss start */
|
||||||
|
ldr r2,=BSS_END /* bss end */
|
||||||
|
|
||||||
|
bss_loop:
|
||||||
|
cmp r1,r2 /* check if data to clear */
|
||||||
|
strlo r0,[r1],#4 /* clear 4 bytes */
|
||||||
|
blo bss_loop /* loop until done */
|
||||||
|
|
||||||
|
/* call C++ constructors of global objects */
|
||||||
|
ldr r0, =__ctors_start__
|
||||||
|
ldr r1, =__ctors_end__
|
||||||
|
bss_end:
|
||||||
|
|
||||||
|
ctor_loop:
|
||||||
|
cmp r0, r1
|
||||||
|
beq ctor_end
|
||||||
|
ldr r2, [r0], #4
|
||||||
|
stmfd sp!, {r0-r1}
|
||||||
|
mov lr, pc
|
||||||
|
bx r2
|
||||||
|
ldmfd sp!, {r0-r1}
|
||||||
|
b ctor_loop
|
||||||
|
ctor_end:
|
||||||
|
|
||||||
|
bl start_kernel
|
||||||
|
|
||||||
|
_loop_here:
|
||||||
|
b _loop_here
|
|
@ -0,0 +1,66 @@
|
||||||
|
.section .vectors, "ax"
|
||||||
|
.code 32
|
||||||
|
|
||||||
|
.globl ExceptionVectors
|
||||||
|
ExceptionVectors:
|
||||||
|
ldr pc, _ResetException
|
||||||
|
ldr pc, _UndefInstrException
|
||||||
|
ldr pc, _SwiException
|
||||||
|
ldr pc, _PrefetchAbortException
|
||||||
|
ldr pc, _DataAbortAbortException
|
||||||
|
ldr pc, _ResvException
|
||||||
|
ldr pc, _IrqException
|
||||||
|
ldr pc, _FiqException
|
||||||
|
|
||||||
|
.globl Reset_Handler
|
||||||
|
.globl UndefInstrExceptionHandle
|
||||||
|
.globl SwiExceptionHandle
|
||||||
|
.globl PrefetchAbortExceptionHandle
|
||||||
|
.globl DataAbortExceptionHandle
|
||||||
|
.globl ResvExceptionHandle
|
||||||
|
.globl ExceptionIsrEntry
|
||||||
|
.globl FiqExceptionHandle
|
||||||
|
|
||||||
|
_ResetException:
|
||||||
|
.word Reset_Handler
|
||||||
|
_UndefInstrException:
|
||||||
|
.word UndefInstrExceptionHandle
|
||||||
|
_SwiException:
|
||||||
|
.word SwiExceptionHandle
|
||||||
|
_PrefetchAbortException:
|
||||||
|
.word PrefetchAbortExceptionHandle
|
||||||
|
_DataAbortAbortException:
|
||||||
|
.word DataAbortExceptionHandle
|
||||||
|
_ResvException:
|
||||||
|
.word ResvExceptionHandle
|
||||||
|
_IrqException:
|
||||||
|
.word ExceptionIsrEntry
|
||||||
|
_FiqException:
|
||||||
|
.word FiqExceptionHandle
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
Reset_Handler:
|
||||||
|
b _start
|
||||||
|
|
||||||
|
UndefInstrExceptionHandle:
|
||||||
|
b UndefInstrIsrEntry
|
||||||
|
|
||||||
|
SwiExceptionHandle:
|
||||||
|
b SvcIsrEntry
|
||||||
|
|
||||||
|
PrefetchAbortExceptionHandle:
|
||||||
|
b PrefetchAbortIsrEntry
|
||||||
|
|
||||||
|
DataAbortExceptionHandle:
|
||||||
|
b UndefInstrIsrEntry
|
||||||
|
|
||||||
|
ResvExceptionHandle:
|
||||||
|
b DataAbortIsrEntry
|
||||||
|
|
||||||
|
ExceptionIsrEntry:
|
||||||
|
stmfd sp!, {r0-r12,lr}
|
||||||
|
|
||||||
|
bl IsrEntry
|
||||||
|
|
||||||
|
FiqExceptionHandle:
|
||||||
|
b FiqIsrEntry
|
|
@ -0,0 +1,89 @@
|
||||||
|
|
||||||
|
.equ Mode_USR, 0x10
|
||||||
|
.equ Mode_FIQ, 0x11
|
||||||
|
.equ Mode_IRQ, 0x12
|
||||||
|
.equ Mode_SVC, 0x13
|
||||||
|
.equ Mode_ABT, 0x17
|
||||||
|
.equ Mode_UND, 0x1B
|
||||||
|
.equ Mode_SYS, 0x1F
|
||||||
|
|
||||||
|
.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled
|
||||||
|
.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled
|
||||||
|
|
||||||
|
.equ STACK_SIZE, 0x00000100
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
|
||||||
|
/* set the cpu to SVC32 mode and disable interrupt */
|
||||||
|
mrs r0, cpsr
|
||||||
|
bic r0, r0, #0x1f
|
||||||
|
orr r0, r0, #0x13
|
||||||
|
msr cpsr_c, r0
|
||||||
|
|
||||||
|
/* disable i/d cache mmu*/
|
||||||
|
mrc p15, 0, r0, c1, c0, 0
|
||||||
|
bic r0, #(1 << 12) /* i cache */
|
||||||
|
bic r0, #(1 << 2) /* d cache */
|
||||||
|
bic r0, #(1 << 0) /* mmu */
|
||||||
|
mcr p15, 0, r0, c1, c0, 0
|
||||||
|
|
||||||
|
ldr r0, =stack_top
|
||||||
|
|
||||||
|
@ Set the startup stack for svc
|
||||||
|
mov sp, r0
|
||||||
|
|
||||||
|
@ Enter Undefined Instruction Mode and set its Stack Pointer
|
||||||
|
msr cpsr_c, #Mode_UND|I_Bit|F_Bit
|
||||||
|
mov sp, r0
|
||||||
|
sub r0, r0, #STACK_SIZE
|
||||||
|
|
||||||
|
@ Enter Abort Mode and set its Stack Pointer
|
||||||
|
msr cpsr_c, #Mode_ABT|I_Bit|F_Bit
|
||||||
|
mov sp, r0
|
||||||
|
sub r0, r0, #STACK_SIZE
|
||||||
|
|
||||||
|
@ Enter FIQ Mode and set its Stack Pointer
|
||||||
|
msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit
|
||||||
|
mov sp, r0
|
||||||
|
sub r0, r0, #STACK_SIZE
|
||||||
|
|
||||||
|
@ Enter IRQ Mode and set its Stack Pointer
|
||||||
|
msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit
|
||||||
|
mov sp, r0
|
||||||
|
sub r0, r0, #STACK_SIZE
|
||||||
|
|
||||||
|
/* come back to SVC mode */
|
||||||
|
msr cpsr_c, #Mode_SVC|I_Bit|F_Bit
|
||||||
|
|
||||||
|
/* clear .bss */
|
||||||
|
mov r0, #0 /* get a zero */
|
||||||
|
ldr r1,=BSS_START /* bss start */
|
||||||
|
ldr r2,=BSS_END /* bss end */
|
||||||
|
|
||||||
|
bss_loop:
|
||||||
|
cmp r1,r2 /* check if data to clear */
|
||||||
|
strlo r0,[r1],#4 /* clear 4 bytes */
|
||||||
|
blo bss_loop /* loop until done */
|
||||||
|
|
||||||
|
/* call C++ constructors of global objects */
|
||||||
|
ldr r0, =__ctors_start__
|
||||||
|
ldr r1, =__ctors_end__
|
||||||
|
bss_end:
|
||||||
|
|
||||||
|
ctor_loop:
|
||||||
|
cmp r0, r1
|
||||||
|
beq ctor_end
|
||||||
|
ldr r2, [r0], #4
|
||||||
|
stmfd sp!, {r0-r1}
|
||||||
|
mov lr, pc
|
||||||
|
bx r2
|
||||||
|
ldmfd sp!, {r0-r1}
|
||||||
|
b ctor_loop
|
||||||
|
ctor_end:
|
||||||
|
|
||||||
|
bl start_kernel
|
||||||
|
|
||||||
|
_loop_here:
|
||||||
|
b _loop_here
|
|
@ -0,0 +1,66 @@
|
||||||
|
.section .vectors, "ax"
|
||||||
|
.code 32
|
||||||
|
|
||||||
|
.globl ExceptionVectors
|
||||||
|
ExceptionVectors:
|
||||||
|
ldr pc, _ResetException
|
||||||
|
ldr pc, _UndefInstrException
|
||||||
|
ldr pc, _SwiException
|
||||||
|
ldr pc, _PrefetchAbortException
|
||||||
|
ldr pc, _DataAbortAbortException
|
||||||
|
ldr pc, _ResvException
|
||||||
|
ldr pc, _IrqException
|
||||||
|
ldr pc, _FiqException
|
||||||
|
|
||||||
|
.globl Reset_Handler
|
||||||
|
.globl UndefInstrExceptionHandle
|
||||||
|
.globl SwiExceptionHandle
|
||||||
|
.globl PrefetchAbortExceptionHandle
|
||||||
|
.globl DataAbortExceptionHandle
|
||||||
|
.globl ResvExceptionHandle
|
||||||
|
.globl ExceptionIsrEntry
|
||||||
|
.globl FiqExceptionHandle
|
||||||
|
|
||||||
|
_ResetException:
|
||||||
|
.word Reset_Handler
|
||||||
|
_UndefInstrException:
|
||||||
|
.word UndefInstrExceptionHandle
|
||||||
|
_SwiException:
|
||||||
|
.word SwiExceptionHandle
|
||||||
|
_PrefetchAbortException:
|
||||||
|
.word PrefetchAbortExceptionHandle
|
||||||
|
_DataAbortAbortException:
|
||||||
|
.word DataAbortExceptionHandle
|
||||||
|
_ResvException:
|
||||||
|
.word ResvExceptionHandle
|
||||||
|
_IrqException:
|
||||||
|
.word ExceptionIsrEntry
|
||||||
|
_FiqException:
|
||||||
|
.word FiqExceptionHandle
|
||||||
|
|
||||||
|
.globl _start
|
||||||
|
Reset_Handler:
|
||||||
|
b _start
|
||||||
|
|
||||||
|
UndefInstrExceptionHandle:
|
||||||
|
b UndefInstrIsrEntry
|
||||||
|
|
||||||
|
SwiExceptionHandle:
|
||||||
|
b SvcIsrEntry
|
||||||
|
|
||||||
|
PrefetchAbortExceptionHandle:
|
||||||
|
b PrefetchAbortIsrEntry
|
||||||
|
|
||||||
|
DataAbortExceptionHandle:
|
||||||
|
b DataAbortIsrEntry
|
||||||
|
|
||||||
|
ResvExceptionHandle:
|
||||||
|
b ResvIsrEntry
|
||||||
|
|
||||||
|
ExceptionIsrEntry:
|
||||||
|
stmfd sp!, {r0-r12,lr}
|
||||||
|
|
||||||
|
b IsrEntry
|
||||||
|
|
||||||
|
FiqExceptionHandle:
|
||||||
|
b FiqIsrEntry
|
|
@ -0,0 +1,243 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, Freescale Semiconductor, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* o Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include "core/gic.h"
|
||||||
|
#include "gic_registers.h"
|
||||||
|
#include "core/cortex_a9.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Prototypes
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static inline gicd_t * gic_get_gicd(void);
|
||||||
|
static inline gicc_t * gic_get_gicc(void);
|
||||||
|
static inline uint32_t irq_get_register_offset(uint32_t irqID);
|
||||||
|
static inline uint32_t irq_get_bit_offset(uint32_t irqID);
|
||||||
|
static inline uint32_t irq_get_bit_mask(uint32_t irqID);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Code
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static inline gicd_t * gic_get_gicd(void)
|
||||||
|
{
|
||||||
|
uint32_t base = get_arm_private_peripheral_base() + kGICDBaseOffset;
|
||||||
|
return (gicd_t *)base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gicc_t * gic_get_gicc(void)
|
||||||
|
{
|
||||||
|
uint32_t base = get_arm_private_peripheral_base() + kGICCBaseOffset;
|
||||||
|
return (gicc_t *)base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t irq_get_register_offset(uint32_t irqID)
|
||||||
|
{
|
||||||
|
return irqID / 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t irq_get_bit_offset(uint32_t irqID)
|
||||||
|
{
|
||||||
|
return irqID & 0x1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t irq_get_bit_mask(uint32_t irqID)
|
||||||
|
{
|
||||||
|
return 1 << irq_get_bit_offset(irqID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_enable(bool enableIt)
|
||||||
|
{
|
||||||
|
gicd_t * gicd = gic_get_gicd();
|
||||||
|
|
||||||
|
if (enableIt)
|
||||||
|
{
|
||||||
|
// Enable both secure and non-secure.
|
||||||
|
gicd->CTLR |= kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Clear the enable bits.
|
||||||
|
gicd->CTLR &= ~(kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_set_irq_security(uint32_t irqID, bool isSecure)
|
||||||
|
{
|
||||||
|
gicd_t * gicd = gic_get_gicd();
|
||||||
|
|
||||||
|
uint32_t reg = irq_get_register_offset(irqID);
|
||||||
|
uint32_t mask = irq_get_bit_mask(irqID);
|
||||||
|
|
||||||
|
uint32_t value = gicd->IGROUPRn[reg];
|
||||||
|
if (!isSecure)
|
||||||
|
{
|
||||||
|
value &= ~mask;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value |= mask;
|
||||||
|
}
|
||||||
|
gicd->IGROUPRn[reg] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_enable_irq(uint32_t irqID, bool isEnabled)
|
||||||
|
{
|
||||||
|
gicd_t * gicd = gic_get_gicd();
|
||||||
|
|
||||||
|
uint32_t reg = irq_get_register_offset(irqID);
|
||||||
|
uint32_t mask = irq_get_bit_mask(irqID);
|
||||||
|
|
||||||
|
// Select set-enable or clear-enable register based on enable flag.
|
||||||
|
if (isEnabled)
|
||||||
|
{
|
||||||
|
gicd->ISENABLERn[reg] = mask;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gicd->ICENABLERn[reg] = mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_set_irq_priority(uint32_t ID, uint32_t priority)
|
||||||
|
{
|
||||||
|
gicd_t * gicd = gic_get_gicd();
|
||||||
|
|
||||||
|
// Update the priority register. The priority registers are byte accessible, and the register
|
||||||
|
// struct has the priority registers as a byte array, so we can just index directly by the
|
||||||
|
// interrupt ID.
|
||||||
|
gicd->IPRIORITYRn[ID] = priority & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt)
|
||||||
|
{
|
||||||
|
// Make sure the CPU number is valid.
|
||||||
|
assert(cpuNumber <= 7);
|
||||||
|
|
||||||
|
gicd_t * gicd = gic_get_gicd();
|
||||||
|
uint8_t cpuMask = 1 << cpuNumber;
|
||||||
|
|
||||||
|
// Like the priority registers, the target registers are byte accessible, and the register
|
||||||
|
// struct has the them as a byte array, so we can just index directly by the
|
||||||
|
// interrupt ID.
|
||||||
|
if (enableIt)
|
||||||
|
{
|
||||||
|
gicd->ITARGETSRn[irqID] |= (cpuMask & 0xff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gicd->ITARGETSRn[irqID] &= ~(cpuMask & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_send_sgi(uint32_t irqID, uint32_t target_list, uint32_t filter_list)
|
||||||
|
{
|
||||||
|
gicd_t * gicd = gic_get_gicd();
|
||||||
|
|
||||||
|
gicd->SGIR = (filter_list << kBP_GICD_SGIR_TargetListFilter)
|
||||||
|
| (target_list << kBP_GICD_SGIR_CPUTargetList)
|
||||||
|
| (irqID & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_cpu_enable(bool enableIt)
|
||||||
|
{
|
||||||
|
gicc_t * gicc = gic_get_gicc();
|
||||||
|
|
||||||
|
if (enableIt)
|
||||||
|
{
|
||||||
|
gicc->CTLR |= kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gicc->CTLR &= ~(kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_set_cpu_priority_mask(uint32_t priority)
|
||||||
|
{
|
||||||
|
gicc_t * gicc = gic_get_gicc();
|
||||||
|
gicc->PMR = priority & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t gic_read_irq_ack(void)
|
||||||
|
{
|
||||||
|
gicc_t * gicc = gic_get_gicc();
|
||||||
|
return gicc->IAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_write_end_of_irq(uint32_t irqID)
|
||||||
|
{
|
||||||
|
gicc_t * gicc = gic_get_gicc();
|
||||||
|
gicc->EOIR = irqID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_init(void)
|
||||||
|
{
|
||||||
|
gicd_t * gicd = gic_get_gicd();
|
||||||
|
|
||||||
|
// First disable the distributor.
|
||||||
|
gic_enable(false);
|
||||||
|
|
||||||
|
// Clear all pending interrupts.
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 32; ++i)
|
||||||
|
{
|
||||||
|
gicd->ICPENDRn[i] = 0xffffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set all interrupts to secure.
|
||||||
|
for (i = 0; i < 8; ++i)
|
||||||
|
{
|
||||||
|
gicd->IGROUPRn[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init the GIC CPU interface.
|
||||||
|
gic_init_cpu();
|
||||||
|
|
||||||
|
// Now enable the distributor.
|
||||||
|
gic_enable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gic_init_cpu(void)
|
||||||
|
{
|
||||||
|
// Init the GIC CPU interface.
|
||||||
|
gic_set_cpu_priority_mask(0xff);
|
||||||
|
|
||||||
|
// Disable preemption.
|
||||||
|
gicc_t * gicc = gic_get_gicc();
|
||||||
|
gicc->BPR = 7;
|
||||||
|
|
||||||
|
// Enable signaling the CPU.
|
||||||
|
gic_cpu_enable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// EOF
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2012, Freescale Semiconductor, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* o Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include "sdk_types.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Definitions
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//! @brief Offsets to the GIC registers.
|
||||||
|
enum _gic_base_offsets
|
||||||
|
{
|
||||||
|
kGICDBaseOffset = 0x1000, //!< GIC distributor offset.
|
||||||
|
kGICCBaseOffset = 0x100 //!< GIC CPU interface offset.
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief GIC distributor registers.
|
||||||
|
//!
|
||||||
|
//! Uses the GICv2 register names, but does not include GICv2 registers.
|
||||||
|
//!
|
||||||
|
//! The IPRIORITYRn and ITARGETSRn registers are byte accessible, so their types are uint8_t
|
||||||
|
//! instead of uint32_t to reflect this. These members are indexed directly with the interrupt
|
||||||
|
//! number.
|
||||||
|
struct _gicd_registers
|
||||||
|
{
|
||||||
|
uint32_t CTLR; //!< Distributor Control Register.
|
||||||
|
uint32_t TYPER; //!< Interrupt Controller Type Register.
|
||||||
|
uint32_t IIDR; //!< Distributor Implementer Identification Register.
|
||||||
|
uint32_t _reserved0[29];
|
||||||
|
uint32_t IGROUPRn[8]; //!< Interrupt Group Registers.
|
||||||
|
uint32_t _reserved1[24];
|
||||||
|
uint32_t ISENABLERn[32]; //!< Interrupt Set-Enable Registers.
|
||||||
|
uint32_t ICENABLERn[32]; //!< Interrupt Clear-Enable Registers.
|
||||||
|
uint32_t ISPENDRn[32]; //!< Interrupt Set-Pending Registers.
|
||||||
|
uint32_t ICPENDRn[32]; //!< Interrupt Clear-Pending Registers.
|
||||||
|
uint32_t ICDABRn[32]; //!< Active Bit Registers.
|
||||||
|
uint32_t _reserved2[32];
|
||||||
|
uint8_t IPRIORITYRn[255 * sizeof(uint32_t)]; //!< Interrupt Priority Registers. (Byte accessible)
|
||||||
|
uint32_t _reserved3;
|
||||||
|
uint8_t ITARGETSRn[255 * sizeof(uint32_t)]; //!< Interrupt Processor Targets Registers. (Byte accessible)
|
||||||
|
uint32_t _reserved4;
|
||||||
|
uint32_t ICFGRn[64]; //!< Interrupt Configuration Registers.
|
||||||
|
uint32_t _reserved5[128];
|
||||||
|
uint32_t SGIR; //!< Software Generated Interrupt Register
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Bitfields constants for the GICD_CTLR register.
|
||||||
|
enum _gicd_ctlr_fields
|
||||||
|
{
|
||||||
|
kBM_GICD_CTLR_EnableGrp1 = (1 << 1),
|
||||||
|
kBM_GICD_CTLR_EnableGrp0 = (1 << 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Bitfields constants for the GICD_SGIR register.
|
||||||
|
enum _gicd_sgir_fields
|
||||||
|
{
|
||||||
|
kBP_GICD_SGIR_TargetListFilter = 24,
|
||||||
|
kBM_GICD_SGIR_TargetListFilter = (0x3 << kBP_GICD_SGIR_TargetListFilter),
|
||||||
|
|
||||||
|
kBP_GICD_SGIR_CPUTargetList = 16,
|
||||||
|
kBM_GICD_SGIR_CPUTargetList = (0xff << kBP_GICD_SGIR_CPUTargetList),
|
||||||
|
|
||||||
|
kBP_GICD_SGIR_NSATT = 15,
|
||||||
|
kBM_GICD_SGIR_NSATT = (1 << kBP_GICD_SGIR_NSATT),
|
||||||
|
|
||||||
|
kBP_GICD_SGIR_SGIINTID = 0,
|
||||||
|
kBM_GICD_SGIR_SGIINTID = 0xf
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief GIC CPU interface registers.
|
||||||
|
//!
|
||||||
|
//! Uses the GICv2 register names. Does not include GICv2 registers.
|
||||||
|
struct _gicc_registers
|
||||||
|
{
|
||||||
|
uint32_t CTLR; //!< CPU Interface Control Register.
|
||||||
|
uint32_t PMR; //!< Interrupt Priority Mask Register.
|
||||||
|
uint32_t BPR; //!< Binary Point Register.
|
||||||
|
uint32_t IAR; //!< Interrupt Acknowledge Register.
|
||||||
|
uint32_t EOIR; //!< End of Interrupt Register.
|
||||||
|
uint32_t RPR; //!< Running Priority Register.
|
||||||
|
uint32_t HPPIR; //!< Highest Priority Pending Interrupt Register.
|
||||||
|
uint32_t ABPR; //!< Aliased Binary Point Register. (only visible with a secure access)
|
||||||
|
uint32_t _reserved[56];
|
||||||
|
uint32_t IIDR; //!< CPU Interface Identification Register.
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brief Bitfields constants for the GICC_CTLR register.
|
||||||
|
enum _gicc_ctlr_fields
|
||||||
|
{
|
||||||
|
kBP_GICC_CTLR_EnableS = 0,
|
||||||
|
kBM_GICC_CTLR_EnableS = (1 << 0),
|
||||||
|
|
||||||
|
kBP_GICC_CTLR_EnableNS = 1,
|
||||||
|
kBM_GICC_CTLR_EnableNS = (1 << 1),
|
||||||
|
|
||||||
|
kBP_GICC_CTLR_AckCtl = 2,
|
||||||
|
kBM_GICC_CTLR_AckCtl = (1 << 2),
|
||||||
|
|
||||||
|
kBP_GICC_CTLR_FIQEn = 3,
|
||||||
|
kBM_GICC_CTLR_FIQEn = (1 << 3),
|
||||||
|
|
||||||
|
kBP_GICC_CTLR_SBPR = 4,
|
||||||
|
kBM_GICC_CTLR_SBPR = (1 << 4)
|
||||||
|
};
|
||||||
|
|
||||||
|
//! @brier Type for the GIC distributor registers.
|
||||||
|
typedef volatile struct _gicd_registers gicd_t;
|
||||||
|
|
||||||
|
//! @brier Type for the GIC CPU interface registers.
|
||||||
|
typedef volatile struct _gicc_registers gicc_t;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// EOF
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
|
@ -79,7 +79,7 @@ MEMORY
|
||||||
sram_oc_ecc2 (rwx) : ORIGIN = 0x20350000, LENGTH = 0x10000 /* 64K bytes (alias RAM7) */
|
sram_oc_ecc2 (rwx) : ORIGIN = 0x20350000, LENGTH = 0x10000 /* 64K bytes (alias RAM7) */
|
||||||
|
|
||||||
/* define extern sdram 32MB*/
|
/* define extern sdram 32MB*/
|
||||||
board_sdram (rwx) : ORIGIN = 0x80000000, LENGTH = 0x2000000 /* 64M bytes (alias RAM8) */
|
board_sdram (rwx) : ORIGIN = 0x80000000, LENGTH = 0x2000000 /* 32M bytes (alias RAM8) */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue