1、add 'menuconfig' function for XiZi_AIoT with imx6q-sabrelite board;2、add compilation function for AIoT system with imx6q-sabrelite board;3、add newlib base files;4、add startup files and irq function for imx6q-sabrelite
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
# The following three platforms support compatiable instructions.
|
||||
SRC_DIR := $(ARCH_ARMV)
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,8 @@
|
||||
# The following three platforms support compatiable instructions.
|
||||
|
||||
ifeq ($(CONFIG_BOARD_IMX6Q_SABRELITE_EVB),y)
|
||||
SRC_DIR := cortex-a9
|
||||
endif
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := boot.S cache.S exception.S cortexA9.S gic.c interrupt.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef ARCH_INTERRUPT_H__
|
||||
#define ARCH_INTERRUPT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <board.h>
|
||||
#include "gic.h"
|
||||
|
||||
#define ARCH_MAX_IRQ_NUM PLATFORM_MAX_IRQ_NR
|
||||
|
||||
int32_t ArchEnableHwIrq(uint32_t irq_num);
|
||||
int32_t ArchDisableHwIrq(uint32_t irq_num);
|
||||
|
||||
struct ExceptionStackRegister
|
||||
{
|
||||
uint32_t r0;
|
||||
uint32_t r1;
|
||||
uint32_t r2;
|
||||
uint32_t r3;
|
||||
uint32_t r4;
|
||||
uint32_t r5;
|
||||
uint32_t r6;
|
||||
uint32_t r7;
|
||||
uint32_t r8;
|
||||
uint32_t r9;
|
||||
uint32_t r10;
|
||||
uint32_t r11;
|
||||
uint32_t r12;
|
||||
uint32_t r13_sp;
|
||||
uint32_t r14_lr;
|
||||
uint32_t r15_pc;
|
||||
uint32_t cpsr;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,20 +1,21 @@
|
||||
|
||||
.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 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
|
||||
#include <asm_defines.h>
|
||||
|
||||
.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 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
|
||||
.globl _reset
|
||||
|
||||
_start:
|
||||
_reset:
|
||||
|
||||
/* set the cpu to SVC32 mode and disable interrupt */
|
||||
mrs r0, cpsr
|
||||
@@ -36,32 +37,32 @@ _start:
|
||||
mov sp, r0
|
||||
|
||||
@ Enter Undefined Instruction Mode and set its Stack Pointer
|
||||
msr cpsr_c, #Mode_UND|I_Bit|F_Bit
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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 */
|
||||
ldr r1,=__bss_start /* bss start */
|
||||
ldr r2,=__bss_end /* bss end */
|
||||
|
||||
bss_loop:
|
||||
cmp r1,r2 /* check if data to clear */
|
||||
|
||||
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* Copyright (c) 2010-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.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @file cortexA9.s
|
||||
* @brief This file contains cortexA9 functions
|
||||
*
|
||||
*/
|
||||
|
||||
.code 32
|
||||
.section ".text","ax"
|
||||
|
||||
/*
|
||||
* bool arm_set_interrupt_state(bool enable)
|
||||
*/
|
||||
.global arm_set_interrupt_state
|
||||
.func arm_set_interrupt_state
|
||||
arm_set_interrupt_state:
|
||||
mrs r2,CPSR @ read CPSR (Current Program Status Register)
|
||||
teq r0,#0
|
||||
bicne r1,r2,#0xc0 @ disable IRQ and FIQ
|
||||
orreq r1,r2,#0xc0 @ enable IRQ and FIQ
|
||||
msr CPSR_c,r1
|
||||
tst r2,#0x80
|
||||
movne r0,#0
|
||||
moveq r0,#1
|
||||
bx lr
|
||||
.endfunc
|
||||
|
||||
.global cpu_get_current
|
||||
@ int cpu_get_current(void)@
|
||||
@ get current CPU ID
|
||||
.func cpu_get_current
|
||||
cpu_get_current:
|
||||
mrc p15, 0, r0, c0, c0, 5
|
||||
and r0, r0, #3
|
||||
BX lr
|
||||
.endfunc @cpu_get_current()@
|
||||
|
||||
.global enable_neon_fpu
|
||||
.func enable_neon_fpu
|
||||
enable_neon_fpu:
|
||||
/* set NSACR, both Secure and Non-secure access are allowed to NEON */
|
||||
MRC p15, 0, r0, c1, c1, 2
|
||||
ORR r0, r0, #(0x3<<10) @ enable fpu/neon
|
||||
MCR p15, 0, r0, c1, c1, 2
|
||||
/* Set the CPACR for access to CP10 and CP11*/
|
||||
LDR r0, =0xF00000
|
||||
MCR p15, 0, r0, c1, c0, 2
|
||||
/* Set the FPEXC EN bit to enable the FPU */
|
||||
MOV r3, #0x40000000
|
||||
@VMSR FPEXC, r3
|
||||
MCR p10, 7, r3, c8, c0, 0
|
||||
.endfunc
|
||||
|
||||
.global disable_strict_align_check
|
||||
.func disable_strict_align_check
|
||||
disable_strict_align_check:
|
||||
/*Ray's note: disable strict alignment fault checking.
|
||||
without disabling this, data abort will happen when accessing
|
||||
the BPB structure of file system since it is packed.*/
|
||||
|
||||
push {r0, lr}
|
||||
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
bic r0, r0, #(0x1<<1) @clear A bit of SCTLR
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
pop {r0, pc}
|
||||
.endfunc
|
||||
|
||||
.global disable_L1_cache
|
||||
.func disable_L1_cache
|
||||
disable_L1_cache:
|
||||
push {r0-r6, lr}
|
||||
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
bic r0, r0, #(0x1<<12)
|
||||
bic r0, r0, #(0x1<<11)
|
||||
bic r0, r0, #(0x1<<2)
|
||||
bic r0, r0, #(0x1<<0)
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
pop {r0-r6, pc}
|
||||
|
||||
.endfunc
|
||||
|
||||
.global get_arm_private_peripheral_base
|
||||
@ uint32_t get_arm_private_peripheral_base(void)@
|
||||
.func get_arm_private_peripheral_base
|
||||
get_arm_private_peripheral_base:
|
||||
|
||||
@ Get base address of private perpherial space
|
||||
mrc p15, 4, r0, c15, c0, 0 @ Read periph base address
|
||||
bx lr
|
||||
|
||||
.endfunc @get_arm_private_peripheral_base()@
|
||||
|
||||
@ ------------------------------------------------------------
|
||||
@ TLB
|
||||
@ ------------------------------------------------------------
|
||||
|
||||
.global arm_unified_tlb_invalidate
|
||||
@ void arm_unified_tlb_invalidate(void)@
|
||||
.func arm_unified_tlb_invalidate
|
||||
arm_unified_tlb_invalidate:
|
||||
mov r0, #1
|
||||
mcr p15, 0, r0, c8, c7, 0 @ TLBIALL - Invalidate entire unified TLB
|
||||
dsb
|
||||
bx lr
|
||||
.endfunc
|
||||
|
||||
.global arm_unified_tlb_invalidate_is
|
||||
@ void arm_unified_tlb_invalidate_is(void)@
|
||||
.func arm_unified_tlb_invalidate_is
|
||||
arm_unified_tlb_invalidate_is:
|
||||
mov r0, #1
|
||||
mcr p15, 0, r0, c8, c3, 0 @ TLBIALLIS - Invalidate entire unified TLB Inner Shareable
|
||||
dsb
|
||||
bx lr
|
||||
.endfunc
|
||||
|
||||
@ ------------------------------------------------------------
|
||||
@ Branch Prediction
|
||||
@ ------------------------------------------------------------
|
||||
|
||||
.global arm_branch_prediction_enable
|
||||
@ void arm_branch_prediction_enable(void)
|
||||
.func arm_branch_prediction_enable
|
||||
arm_branch_prediction_enable:
|
||||
mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR
|
||||
orr r0, r0, #(1 << 11) @ Set the Z bit (bit 11)
|
||||
mcr p15, 0,r0, c1, c0, 0 @ Write SCTLR
|
||||
bx lr
|
||||
.endfunc
|
||||
|
||||
.global arm_branch_prediction_disable
|
||||
@ void arm_branch_prediction_disable(void)
|
||||
.func arm_branch_prediction_disable
|
||||
arm_branch_prediction_disable:
|
||||
mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR
|
||||
bic r0, r0, #(1 << 11) @ Clear the Z bit (bit 11)
|
||||
mcr p15, 0,r0, c1, c0, 0 @ Write SCTLR
|
||||
bx lr
|
||||
.endfunc
|
||||
|
||||
.global arm_branch_target_cache_invalidate
|
||||
@ void arm_branch_target_cache_invalidate(void)
|
||||
.func arm_branch_target_cache_invalidate
|
||||
arm_branch_target_cache_invalidate:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 6 @ BPIALL - Invalidate entire branch predictor array
|
||||
bx lr
|
||||
.endfunc
|
||||
|
||||
.global arm_branch_target_cache_invalidate_is
|
||||
@ void arm_branch_target_cache_invalidate_is(void)
|
||||
.func arm_branch_target_cache_invalidate_is
|
||||
arm_branch_target_cache_invalidate_is:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c1, 6 @ BPIALLIS - Invalidate entire branch predictor array Inner Shareable
|
||||
bx lr
|
||||
.endfunc
|
||||
|
||||
@ ------------------------------------------------------------
|
||||
@ SCU
|
||||
@ ------------------------------------------------------------
|
||||
|
||||
@ SCU offset from base of private peripheral space --> 0x000
|
||||
|
||||
.global scu_enable
|
||||
@ void scu_enable(void)
|
||||
@ Enables the SCU
|
||||
.func scu_enable
|
||||
scu_enable:
|
||||
|
||||
mrc p15, 4, r0, c15, c0, 0 @ Read periph base address
|
||||
|
||||
ldr r1, [r0, #0x0] @ Read the SCU Control Register
|
||||
orr r1, r1, #0x1 @ Set bit 0 (The Enable bit)
|
||||
str r1, [r0, #0x0] @ Write back modifed value
|
||||
|
||||
bx lr
|
||||
.endfunc
|
||||
|
||||
@ ------------------------------------------------------------
|
||||
|
||||
.global scu_join_smp
|
||||
@ void scu_join_smp(void)
|
||||
@ Set this CPU as participating in SMP
|
||||
.func scu_join_smp
|
||||
scu_join_smp:
|
||||
|
||||
@ SMP status is controlled by bit 6 of the CP15 Aux Ctrl Reg
|
||||
|
||||
mrc p15, 0, r0, c1, c0, 1 @ Read ACTLR
|
||||
orr r0, r0, #0x040 @ Set bit 6
|
||||
mcr p15, 0, r0, c1, c0, 1 @ Write ACTLR
|
||||
|
||||
bx lr
|
||||
.endfunc
|
||||
|
||||
@ ------------------------------------------------------------
|
||||
|
||||
.global scu_leave_smp
|
||||
@ void scu_leave_smp(void)
|
||||
@ Set this CPU as NOT participating in SMP
|
||||
.func scu_leave_smp
|
||||
scu_leave_smp:
|
||||
|
||||
@ SMP status is controlled by bit 6 of the CP15 Aux Ctrl Reg
|
||||
|
||||
mrc p15, 0, r0, c1, c0, 1 @ Read ACTLR
|
||||
bic r0, r0, #0x040 @ Clear bit 6
|
||||
mcr p15, 0, r0, c1, c0, 1 @ Write ACTLR
|
||||
|
||||
bx lr
|
||||
.endfunc
|
||||
|
||||
@ ------------------------------------------------------------
|
||||
|
||||
.global scu_get_cpus_in_smp
|
||||
@ unsigned int scu_get_cpus_in_smp(void)
|
||||
@ The return value is 1 bit per core:
|
||||
@ bit 0 - CPU 0
|
||||
@ bit 1 - CPU 1
|
||||
@ etc...
|
||||
.func scu_get_cpus_in_smp
|
||||
scu_get_cpus_in_smp:
|
||||
|
||||
mrc p15, 4, r0, c15, c0, 0 @ Read periph base address
|
||||
|
||||
ldr r0, [r0, #0x004] @ Read SCU Configuration register
|
||||
mov r0, r0, lsr #4 @ Bits 7:4 gives the cores in SMP mode, shift then mask
|
||||
and r0, r0, #0x0F
|
||||
|
||||
bx lr
|
||||
.endfunc
|
||||
|
||||
@ ------------------------------------------------------------
|
||||
|
||||
.global scu_enable_maintenance_broadcast
|
||||
@ void scu_enable_maintenance_broadcast(void)
|
||||
@ Enable the broadcasting of cache & TLB maintenance operations
|
||||
@ When enabled AND in SMP, broadcast all "inner sharable"
|
||||
@ cache and TLM maintenance operations to other SMP cores
|
||||
.func scu_enable_maintenance_broadcast
|
||||
scu_enable_maintenance_broadcast:
|
||||
mrc p15, 0, r0, c1, c0, 1 @ Read Aux Ctrl register
|
||||
orr r0, r0, #0x01 @ Set the FW bit (bit 0)
|
||||
mcr p15, 0, r0, c1, c0, 1 @ Write Aux Ctrl register
|
||||
|
||||
bx lr
|
||||
.endfunc
|
||||
|
||||
@ ------------------------------------------------------------
|
||||
|
||||
.global scu_disable_maintenance_broadcast
|
||||
@ void scu_disable_maintenance_broadcast(void)
|
||||
@ Disable the broadcasting of cache & TLB maintenance operations
|
||||
.func scu_disable_maintenance_broadcast
|
||||
scu_disable_maintenance_broadcast:
|
||||
mrc p15, 0, r0, c1, c0, 1 @ Read Aux Ctrl register
|
||||
bic r0, r0, #0x01 @ Clear the FW bit (bit 0)
|
||||
mcr p15, 0, r0, c1, c0, 1 @ Write Aux Ctrl register
|
||||
|
||||
bx lr
|
||||
.endfunc
|
||||
|
||||
@ ------------------------------------------------------------
|
||||
|
||||
.global scu_secure_invalidate
|
||||
@ void scu_secure_invalidate(unsigned int cpu, unsigned int ways)
|
||||
@ cpu: 0x0=CPU 0 0x1=CPU 1 etc...
|
||||
@ This function invalidates the SCU copy of the tag rams
|
||||
@ for the specified core. typically only done at start-up.
|
||||
@ Possible flow:
|
||||
@ - Invalidate L1 caches
|
||||
@ - Invalidate SCU copy of TAG RAMs
|
||||
@ - Join SMP
|
||||
.func scu_secure_invalidate
|
||||
scu_secure_invalidate:
|
||||
and r0, r0, #0x03 @ Mask off unused bits of CPU ID
|
||||
mov r0, r0, lsl #2 @ Convert into bit offset (four bits per core)
|
||||
|
||||
and r1, r1, #0x0F @ Mask off unused bits of ways
|
||||
mov r1, r1, lsl r0 @ Shift ways into the correct CPU field
|
||||
|
||||
mrc p15, 4, r2, c15, c0, 0 @ Read periph base address
|
||||
|
||||
str r1, [r2, #0x0C] @ Write to SCU Invalidate All in Secure State
|
||||
|
||||
bx lr
|
||||
|
||||
.endfunc
|
||||
|
||||
@ ------------------------------------------------------------
|
||||
@ End of cortexA9.s
|
||||
@ ------------------------------------------------------------
|
||||
.end
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#if !defined(__CORTEX_A9_H__)
|
||||
#define __CORTEX_A9_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//! @addtogroup cortexa9
|
||||
//! @{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Definitions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! @name Instruction macros
|
||||
//@{
|
||||
#define _ARM_NOP() asm volatile ("nop\n\t")
|
||||
#define _ARM_WFI() asm volatile ("wfi\n\t")
|
||||
#define _ARM_WFE() asm volatile ("wfe\n\t")
|
||||
#define _ARM_SEV() asm volatile ("sev\n\t")
|
||||
#define _ARM_DSB() asm volatile ("dsb\n\t")
|
||||
#define _ARM_ISB() asm volatile ("isb\n\t")
|
||||
|
||||
#define _ARM_MRC(coproc, opcode1, Rt, CRn, CRm, opcode2) \
|
||||
asm volatile ("mrc p" #coproc ", " #opcode1 ", %[output], c" #CRn ", c" #CRm ", " #opcode2 "\n" : [output] "=r" (Rt))
|
||||
|
||||
#define _ARM_MCR(coproc, opcode1, Rt, CRn, CRm, opcode2) \
|
||||
asm volatile ("mcr p" #coproc ", " #opcode1 ", %[input], c" #CRn ", c" #CRm ", " #opcode2 "\n" :: [input] "r" (Rt))
|
||||
//@}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Code
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//! @name Misc
|
||||
//@{
|
||||
//! @brief Enable or disable the IRQ and FIQ state.
|
||||
bool arm_set_interrupt_state(bool enable);
|
||||
|
||||
//! @brief Get current CPU ID.
|
||||
int cpu_get_current(void);
|
||||
|
||||
//! @brief Enable the NEON MPE.
|
||||
void enable_neon_fpu(void);
|
||||
|
||||
//! @brief Disable aborts on unaligned accesses.
|
||||
void disable_strict_align_check(void);
|
||||
|
||||
//! @brief Get base address of private perpherial space.
|
||||
//!
|
||||
//! @return The address of the ARM CPU's private peripherals.
|
||||
uint32_t get_arm_private_peripheral_base(void);
|
||||
//@}
|
||||
|
||||
|
||||
//! @name Data cache operations
|
||||
//@{
|
||||
|
||||
//! @brief Check if dcache is enabled or disabled.
|
||||
int arm_dcache_state_query();
|
||||
|
||||
//! @brief Enables data cache at any available cache level.
|
||||
//!
|
||||
//! Works only if MMU is enabled!
|
||||
void arm_dcache_enable();
|
||||
|
||||
//! @brief Disables the data cache at any available cache level.
|
||||
void arm_dcache_disable();
|
||||
|
||||
//! @brief Invalidates the entire data cache.
|
||||
void arm_dcache_invalidate();
|
||||
|
||||
//! @brief Invalidate a line of data cache.
|
||||
void arm_dcache_invalidate_line(const void * addr);
|
||||
|
||||
//! @brief Invalidate a number of lines of data cache.
|
||||
//!
|
||||
//! Number of lines depends on length parameter and size of line.
|
||||
//! Size of line for A9 L1 cache is 32B.
|
||||
void arm_dcache_invalidate_mlines(const void * addr, size_t length);
|
||||
|
||||
//! @brief Flush (clean) all lines of cache (all sets in all ways).
|
||||
void arm_dcache_flush();
|
||||
|
||||
//! @brief Flush (clean) one line of cache.
|
||||
void arm_dcache_flush_line(const void * addr);
|
||||
|
||||
// @brief Flush (clean) multiple lines of cache.
|
||||
//!
|
||||
//! Number of lines depends on length parameter and size of line.
|
||||
void arm_dcache_flush_mlines(const void * addr, size_t length);
|
||||
//@}
|
||||
|
||||
//! @name Instrution cache operations
|
||||
//@{
|
||||
|
||||
//! @brief Check if icache is enabled or disabled.
|
||||
int arm_icache_state_query();
|
||||
|
||||
//! @brief Enables instruction cache at any available cache level.
|
||||
//!
|
||||
//! Works without enabled MMU too!
|
||||
void arm_icache_enable();
|
||||
|
||||
//! @brief Disables the instruction cache at any available cache level.
|
||||
void arm_icache_disable();
|
||||
|
||||
//! @brief Invalidates the entire instruction cache.
|
||||
void arm_icache_invalidate();
|
||||
|
||||
//! @brief Invalidates the entire instruction cache inner shareable.
|
||||
void arm_icache_invalidate_is();
|
||||
|
||||
//! @brief Invalidate a line of the instruction cache.
|
||||
void arm_icache_invalidate_line(const void * addr);
|
||||
|
||||
//! @brief Invalidate a number of lines of instruction cache.
|
||||
//!
|
||||
//! Number of lines depends on length parameter and size of line.
|
||||
void arm_icache_invalidate_mlines(const void * addr, size_t length);
|
||||
//@}
|
||||
|
||||
//! @name TLB operations
|
||||
//@{
|
||||
//! @brief Invalidate entire unified TLB.
|
||||
void arm_unified_tlb_invalidate(void);
|
||||
|
||||
//! @brief Invalidate entire unified TLB Inner Shareable.
|
||||
void arm_unified_tlb_invalidate_is(void);
|
||||
//@}
|
||||
|
||||
//! @name Branch predictor operations
|
||||
//@{
|
||||
//! @brief Enable branch prediction.
|
||||
void arm_branch_prediction_enable(void);
|
||||
|
||||
//! @brief Disable branch prediction.
|
||||
void arm_branch_prediction_disable(void);
|
||||
|
||||
//! @brief Invalidate entire branch predictor array.
|
||||
void arm_branch_target_cache_invalidate(void);
|
||||
|
||||
//! @brief Invalidate entire branch predictor array Inner Shareable
|
||||
void arm_branch_target_cache_invalidate_is(void);
|
||||
//@}
|
||||
|
||||
//! @name SCU
|
||||
//@{
|
||||
//! @brief Enables the SCU.
|
||||
void scu_enable(void);
|
||||
|
||||
//! @brief Set this CPU as participating in SMP.
|
||||
void scu_join_smp(void);
|
||||
|
||||
//! @brief Set this CPU as not participating in SMP.
|
||||
void scu_leave_smp(void);
|
||||
|
||||
//! @brief Determine which CPUs are participating in SMP.
|
||||
//!
|
||||
//! The return value is 1 bit per core:
|
||||
//! - bit 0 - CPU 0
|
||||
//! - bit 1 - CPU 1
|
||||
//! - etc...
|
||||
unsigned int scu_get_cpus_in_smp(void);
|
||||
|
||||
//! @brief Enable the broadcasting of cache & TLB maintenance operations.
|
||||
//!
|
||||
//! When enabled AND in SMP, broadcast all "inner sharable"
|
||||
//! cache and TLM maintenance operations to other SMP cores
|
||||
void scu_enable_maintenance_broadcast(void);
|
||||
|
||||
//! @brief Disable the broadcasting of cache & TLB maintenance operations.
|
||||
void scu_disable_maintenance_broadcast(void);
|
||||
|
||||
//! @brief Invalidates the SCU copy of the tag rams for the specified core.
|
||||
//!
|
||||
//! Typically only done at start-up.
|
||||
//! Possible flow:
|
||||
//! - Invalidate L1 caches
|
||||
//! - Invalidate SCU copy of TAG RAMs
|
||||
//! - Join SMP
|
||||
//!
|
||||
//! @param cpu 0x0=CPU 0, 0x1=CPU 1, etc...
|
||||
//! @param ways The ways to invalidate. Pass 0xf to invalidate all ways.
|
||||
void scu_secure_invalidate(unsigned int cpu, unsigned int ways);
|
||||
//@}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
//! @}
|
||||
|
||||
#endif // __CORTEX_A9_H__
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// EOF
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <asm_defines.h>
|
||||
|
||||
.section .vectors, "ax"
|
||||
.code 32
|
||||
|
||||
@@ -12,7 +14,7 @@ ExceptionVectors:
|
||||
ldr pc, _IrqException
|
||||
ldr pc, _FiqException
|
||||
|
||||
.globl _start
|
||||
.globl _reset
|
||||
.globl UndefInstrExceptionHandle
|
||||
.globl SwiExceptionHandle
|
||||
.globl PrefetchAbortExceptionHandle
|
||||
@@ -22,7 +24,7 @@ ExceptionVectors:
|
||||
.globl FiqExceptionHandle
|
||||
|
||||
_ResetException:
|
||||
.word _start
|
||||
.word _reset
|
||||
_UndefInstrException:
|
||||
.word UndefInstrExceptionHandle
|
||||
_SwiException:
|
||||
@@ -48,7 +50,7 @@ _FiqException:
|
||||
mrs r6, spsr @/* Save CPSR */
|
||||
str lr, [r0, #15*4] @/* Push PC */
|
||||
str r6, [r0, #16*4] @/* Push CPSR */
|
||||
cps #Mode_SVC
|
||||
cps #MODE_SVC
|
||||
str sp, [r0, #13*4] @/* Save calling SP */
|
||||
str lr, [r0, #14*4] @/* Save calling PC */
|
||||
.endm
|
||||
@@ -63,7 +65,7 @@ UndefInstrExceptionHandle:
|
||||
.globl SwiExceptionHandle
|
||||
SwiExceptionHandle:
|
||||
push_svc_reg
|
||||
bl rt_hw_trap_swi
|
||||
bl DoSvcCallProcess
|
||||
b .
|
||||
|
||||
.align 5
|
||||
@@ -89,55 +91,51 @@ ResvExceptionHandle:
|
||||
.globl ExceptionIsrEntry
|
||||
ExceptionIsrEntry:
|
||||
|
||||
stmfd sp!, {r0-r12,lr}
|
||||
stmfd sp!, {r0-r12,lr}
|
||||
|
||||
bl rt_interrupt_enter
|
||||
bl rt_hw_trap_irq
|
||||
bl rt_interrupt_leave
|
||||
bl DoIrqProcess
|
||||
|
||||
@ if rt_thread_switch_interrupt_flag set, jump to
|
||||
@ rt_hw_context_switch_interrupt_do and don't return
|
||||
ldr r0, =rt_thread_switch_interrupt_flag
|
||||
ldr r1, [r0]
|
||||
cmp r1, #1
|
||||
beq rt_hw_context_switch_interrupt_do
|
||||
@ ldr r0, =rt_thread_switch_interrupt_flag
|
||||
@ ldr r1, [r0]
|
||||
@ cmp r1, #1
|
||||
@ beq rt_hw_context_switch_interrupt_do
|
||||
|
||||
ldmfd sp!, {r0-r12,lr}
|
||||
subs pc, lr, #4
|
||||
ldmfd sp!, {r0-r12,lr}
|
||||
subs pc, lr, #4
|
||||
|
||||
rt_hw_context_switch_interrupt_do:
|
||||
mov r1, #0 @ clear flag
|
||||
str r1, [r0]
|
||||
@ rt_hw_context_switch_interrupt_do:
|
||||
@ mov r1, #0 @ clear flag
|
||||
@ str r1, [r0]
|
||||
|
||||
mov r1, sp @ r1 point to {r0-r3} in stack
|
||||
add sp, sp, #4*4
|
||||
ldmfd sp!, {r4-r12,lr}@ reload saved registers
|
||||
mrs r0, spsr @ get cpsr of interrupt thread
|
||||
sub r2, lr, #4 @ save old task's pc to r2
|
||||
@ mov r1, sp @ r1 point to {r0-r3} in stack
|
||||
@ add sp, sp, #4*4
|
||||
@ ldmfd sp!, {r4-r12,lr}@ reload saved registers
|
||||
@ mrs r0, spsr @ get cpsr of interrupt thread
|
||||
@ sub r2, lr, #4 @ save old task's pc to r2
|
||||
|
||||
@ Switch to SVC mode with no interrupt. If the usr mode guest is
|
||||
@ interrupted, this will just switch to the stack of kernel space.
|
||||
@ save the registers in kernel space won't trigger data abort.
|
||||
msr cpsr_c, #I_Bit|F_Bit|Mode_SVC
|
||||
@ @ Switch to SVC mode with no interrupt. If the usr mode guest is
|
||||
@ @ interrupted, this will just switch to the stack of kernel space.
|
||||
@ @ save the registers in kernel space won't trigger data abort.
|
||||
@ msr cpsr_c, #I_Bit|F_Bit|Mode_SVC
|
||||
|
||||
stmfd sp!, {r2} @ push old task's pc
|
||||
stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4
|
||||
ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread
|
||||
stmfd sp!, {r1-r4} @ push old task's r0-r3
|
||||
stmfd sp!, {r0} @ push old task's cpsr
|
||||
@ stmfd sp!, {r2} @ push old task's pc
|
||||
@ stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4
|
||||
@ ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread
|
||||
@ stmfd sp!, {r1-r4} @ push old task's r0-r3
|
||||
@ stmfd sp!, {r0} @ push old task's cpsr
|
||||
|
||||
ldr r4, =rt_interrupt_from_thread
|
||||
ldr r5, [r4]
|
||||
str sp, [r5] @ store sp in preempted tasks's TCB
|
||||
@ ldr r4, =rt_interrupt_from_thread
|
||||
@ ldr r5, [r4]
|
||||
@ str sp, [r5] @ store sp in preempted tasks's TCB
|
||||
|
||||
ldr r6, =rt_interrupt_to_thread
|
||||
ldr r6, [r6]
|
||||
ldr sp, [r6] @ get new task's stack pointer
|
||||
@ ldr r6, =rt_interrupt_to_thread
|
||||
@ ldr r6, [r6]
|
||||
@ ldr sp, [r6] @ get new task's stack pointer
|
||||
|
||||
ldmfd sp!, {r4} @ pop new task's cpsr to spsr
|
||||
msr spsr_cxsf, r4
|
||||
@ ldmfd sp!, {r4} @ pop new task's cpsr to spsr
|
||||
@ msr spsr_cxsf, r4
|
||||
|
||||
ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
|
||||
@ ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
|
||||
|
||||
|
||||
.align 5
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
|
||||
/**
|
||||
* this function will show registers of CPU
|
||||
*
|
||||
* @param regs the registers point
|
||||
*/
|
||||
void PrintStackFrame(struct rt_hw_exp_stack *regs)
|
||||
{
|
||||
rt_kprintf("Execption:\n");
|
||||
rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
|
||||
rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
|
||||
rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
|
||||
rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
|
||||
rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
|
||||
rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The software interrupt instruction (SWI) is used for entering
|
||||
* Supervisor mode, usually to request a particular supervisor
|
||||
* function.
|
||||
*
|
||||
* @param regs system registers
|
||||
*
|
||||
* @note never invoke this function in application
|
||||
*/
|
||||
void rt_hw_trap_swi(struct rt_hw_exp_stack *regs)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void rt_hw_trap_irq(void)
|
||||
{
|
||||
void *param;
|
||||
rt_isr_handler_t isr_func;
|
||||
extern struct rt_irq_desc isr_table[];
|
||||
|
||||
// vectNum = RESERVED[31:13] | CPUID[12:10] | INTERRUPT_ID[9:0]
|
||||
// send ack and get ID source
|
||||
uint32_t vectNum = gic_read_irq_ack();
|
||||
|
||||
// Check that INT_ID isn't 1023 or 1022 (spurious interrupt)
|
||||
if (vectNum & 0x0200)
|
||||
{
|
||||
gic_write_end_of_irq(vectNum); // send end of irq
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy the local value to the global image of CPUID
|
||||
unsigned cpu = (vectNum >> 10) & 0x7;
|
||||
unsigned irq = vectNum & 0x1FF;
|
||||
|
||||
/* skip warning */
|
||||
cpu = cpu;
|
||||
|
||||
// Call the service routine stored in the handlers array. If there isn't
|
||||
// one for this IRQ, then call the default handler.
|
||||
/* get interrupt service routine */
|
||||
isr_func = isr_table[irq].handler;
|
||||
#ifdef RT_USING_INTERRUPT_INFO
|
||||
isr_table[irq].counter++;
|
||||
#endif
|
||||
if (isr_func)
|
||||
{
|
||||
/* Interrupt for myself. */
|
||||
param = isr_table[irq].param;
|
||||
/* turn to interrupt service routine */
|
||||
isr_func(irq, param);
|
||||
}
|
||||
|
||||
// Signal the end of the irq.
|
||||
gic_write_end_of_irq(vectNum);
|
||||
}
|
||||
}
|
||||
@@ -28,9 +28,9 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include "core/gic.h"
|
||||
#include "gic.h"
|
||||
#include "gic_registers.h"
|
||||
#include "core/cortex_a9.h"
|
||||
#include "cortex_a9.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Prototypes
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) 2011-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.
|
||||
*/
|
||||
#ifndef __GIC_H__
|
||||
#define __GIC_H__
|
||||
|
||||
#include "sdk_types.h"
|
||||
|
||||
//! @addtogroup gic
|
||||
//! @{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Definitions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! @brief Options for sending a software generated interrupt.
|
||||
//!
|
||||
//! These options are used for the @a filter_list parameter of the gic_send_sgi()
|
||||
//! function. They control how to select which CPUs that the interrupt is
|
||||
//! sent to.
|
||||
enum _gicd_sgi_filter
|
||||
{
|
||||
//! Forward the interrupt to the CPU interfaces specified in the @a target_list parameter.
|
||||
kGicSgiFilter_UseTargetList = 0,
|
||||
|
||||
//! Forward the interrupt to all CPU interfaces except that of the processor that requested
|
||||
//! the interrupt.
|
||||
kGicSgiFilter_AllOtherCPUs = 1,
|
||||
|
||||
//! Forward the interrupt only to the CPU interface of the processor that requested the
|
||||
//! interrupt.
|
||||
kGicSgiFilter_OnlyThisCPU = 2
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// API
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//! @name Initialization
|
||||
//@{
|
||||
//! @brief Init interrupt handling.
|
||||
//!
|
||||
//! This function is intended to be called only by the primary CPU init code, so it will
|
||||
//! only be called once during system bootup.
|
||||
//!
|
||||
//! Also inits the current CPU. You don't need to call gic_init_cpu() separately.
|
||||
//!
|
||||
//! @post The interrupt distributor and the current CPU interface are enabled. All interrupts
|
||||
//! that were pending are cleared, and all interrupts are made secure (group 0).
|
||||
void gic_init(void);
|
||||
|
||||
//! @brief Init the current CPU's GIC interface.
|
||||
//!
|
||||
//! @post Enables the CPU interface and sets the priority mask to 255. Interrupt preemption
|
||||
//! is disabled by setting the Binary Point to a value of 7.
|
||||
void gic_init_cpu(void);
|
||||
//@}
|
||||
|
||||
//! @name GIC Interrupt Distributor Functions
|
||||
//@{
|
||||
//! @brief Enable or disable the GIC Distributor.
|
||||
//!
|
||||
//! Enables or disables the GIC distributor passing both secure (group 0) and non-secure
|
||||
//! (group 1) interrupts to the CPU interfaces.
|
||||
//!
|
||||
//! @param enableIt Pass true to enable or false to disable.
|
||||
void gic_enable(bool enableIt);
|
||||
|
||||
//! @brief Set the security mode for an interrupt.
|
||||
//!
|
||||
//! @param irqID The interrupt number.
|
||||
//! @param isSecure Whether the interrupt is taken to secure mode.
|
||||
void gic_set_irq_security(uint32_t irqID, bool isSecure);
|
||||
|
||||
//! @brief Enable or disable an interrupt.
|
||||
//!
|
||||
//! @param irqID The number of the interrupt to control.
|
||||
//! @param isEnabled Pass true to enable or false to disable.
|
||||
void gic_enable_irq(uint32_t irqID, bool isEnabled);
|
||||
|
||||
//! @brief Set whether a CPU will receive a particular interrupt.
|
||||
//!
|
||||
//! @param irqID The interrupt number.
|
||||
//! @param cpuNumber The CPU number. The first CPU core is 0.
|
||||
//! @param enableIt Whether to send the interrupt to the specified CPU. Pass true to enable
|
||||
//! or false to disable.
|
||||
void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt);
|
||||
|
||||
//! @brief Set an interrupt's priority.
|
||||
//!
|
||||
//! @param irq_id The interrupt number.
|
||||
//! @param priority The priority for the interrupt. In the range of 0 through 0xff, with
|
||||
//! 0 being the highest priority.
|
||||
void gic_set_irq_priority(uint32_t irq_id, uint32_t priority);
|
||||
|
||||
//! @brief Send a software generated interrupt to a specific CPU.
|
||||
//!
|
||||
//! @param irq_id The interrupt number to send.
|
||||
//! @param target_list Each bit indicates a CPU to which the interrupt will be forwarded.
|
||||
//! Bit 0 is CPU 0, bit 1 is CPU 1, and so on. If the value is 0, then the interrupt
|
||||
//! will not be forwarded to any CPUs. This parameter is only used if @a filter_list
|
||||
//! is set to #kGicSgiFilter_UseTargetList.
|
||||
//! @param filter_list One of the enums of the #_gicd_sgi_filter enumeration. The selected
|
||||
//! option determines which CPUs the interrupt will be sent to. If the value
|
||||
//! is #kGicSgiFilter_UseTargetList, then the @a target_list parameter is used.
|
||||
void gic_send_sgi(uint32_t irq_id, uint32_t target_list, uint32_t filter_list);
|
||||
//@}
|
||||
|
||||
//! @name GIC CPU Interface Functions
|
||||
//@{
|
||||
//! @brief Enable or disable the interface to the GIC for the current CPU.
|
||||
//!
|
||||
//! @param enableIt Pass true to enable or false to disable.
|
||||
void gic_cpu_enable(bool enableIt);
|
||||
|
||||
//! @brief Set the mask of which interrupt priorities the CPU will receive.
|
||||
//!
|
||||
//! @param priority The lowest priority that will be passed to the current CPU. Pass 0xff to
|
||||
//! allow all priority interrupts to signal the CPU.
|
||||
void gic_set_cpu_priority_mask(uint32_t priority);
|
||||
|
||||
//! @brief Acknowledge starting of interrupt handling and get the interrupt number.
|
||||
//!
|
||||
//! Normally, this function is called at the beginning of the IRQ handler. It tells the GIC
|
||||
//! that you are starting to handle an interupt, and returns the number of the interrupt you
|
||||
//! need to handle. After the interrupt is handled, you should call gic_write_end_of_irq()
|
||||
//! to signal that the interrupt is completely handled.
|
||||
//!
|
||||
//! In some cases, a spurious interrupt might happen. One possibility is if another CPU handles
|
||||
//! the interrupt. When a spurious interrupt occurs, the end of the interrupt should be indicated
|
||||
//! but nothing else.
|
||||
//!
|
||||
//! @return The number for the highest priority interrupt available for the calling CPU. If
|
||||
//! the return value is 1022 or 1023, a spurious interrupt has occurred.
|
||||
uint32_t gic_read_irq_ack(void);
|
||||
|
||||
//! @brief Signal the end of handling an interrupt.
|
||||
//!
|
||||
//! @param irq_id The number of the interrupt for which handling has finished.
|
||||
void gic_write_end_of_irq(uint32_t irq_id);
|
||||
//@}
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
//! @}
|
||||
|
||||
#endif // __GIC_H__
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// EOF
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,92 @@
|
||||
// extern void _svcall(uintptr_t* contex);
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <isr.h>
|
||||
|
||||
unsigned long __attribute__((naked)) DisableLocalInterrupt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void __attribute__((naked)) EnableLocalInterrupt(unsigned long level)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int32_t ArchEnableHwIrq(uint32_t irq_num)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t ArchDisableHwIrq(uint32_t irq_num)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void KTaskOsAssignAfterIrq(void *context);
|
||||
|
||||
void IsrEntry(uint32_t irq_num)
|
||||
{
|
||||
isrManager.done->incCounter();
|
||||
isrManager.done->handleIrq(irq_num);
|
||||
// KTaskOsAssignAfterIrq(NULL);
|
||||
isrManager.done->decCounter();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* this function will show registers of CPU
|
||||
*
|
||||
* @param regs the registers point
|
||||
*/
|
||||
void PrintStackFrame(struct ExceptionStackRegister *regs)
|
||||
{
|
||||
// KPrintf("Execption:\n");
|
||||
// KPrintf("r0: 0x%08x\n", regs->r0);
|
||||
// KPrintf("r1: 0x%08x\n", regs->r1);
|
||||
// KPrintf("r2: 0x%08x\n", regs->r2);
|
||||
// KPrintf("r3: 0x%08x\n", regs->r3);
|
||||
// KPrintf("r4: 0x%08x\n", regs->r4);
|
||||
// KPrintf("r5: 0x%08x\n", regs->r5);
|
||||
// KPrintf("r6: 0x%08x\n", regs->r6);
|
||||
// KPrintf("r7: 0x%08x\n", regs->r7);
|
||||
// KPrintf("r8: 0x%08x\n", regs->r8);
|
||||
// KPrintf("r9: 0x%08x\n", regs->r9);
|
||||
// KPrintf("r10: 0x%08x\n", regs->r10);
|
||||
// KPrintf("r11: 0x%08x\n", regs->r11);
|
||||
// KPrintf("r12: 0x%08x\n", regs->r12);
|
||||
// KPrintf("r13_sp: 0x%08x\n", regs->r13_sp);
|
||||
// KPrintf("r14_lr: 0x%08x\n", regs->r14_lr);
|
||||
// KPrintf("r15_pc: 0x%08x\n", regs->r15_pc);
|
||||
// KPrintf("cpsr: 0x%08x\n", regs->cpsr);
|
||||
}
|
||||
|
||||
|
||||
void DoSvcCallProcess(struct ExceptionStackRegister *regs)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DoIrqProcess(void)
|
||||
{
|
||||
uint32_t iar = gic_read_irq_ack();
|
||||
uint32_t irq_num = iar & 0x3ff;
|
||||
|
||||
if(irq_num >= ARCH_MAX_IRQ_NUM)
|
||||
{
|
||||
gic_write_end_of_irq(irq_num);
|
||||
return;
|
||||
}
|
||||
|
||||
IsrEntry(irq_num);
|
||||
|
||||
gic_write_end_of_irq(irq_num);
|
||||
}
|
||||
// uintptr_t *Svcall(unsigned int ipsr, uintptr_t* contex )
|
||||
// {
|
||||
// #ifdef TASK_ISOLATION
|
||||
// _svcall(contex);
|
||||
// #endif
|
||||
// return contex;
|
||||
// }
|
||||
Reference in New Issue
Block a user