仓库迁移

This commit is contained in:
andy
2023-06-10 11:52:00 +08:00
parent e4616bfae5
commit 077c27f2bb
499 changed files with 199745 additions and 92 deletions

View File

@@ -0,0 +1,79 @@
;/*
; * Copyright (c) 2006-2018, RT-Thread Development Team
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
; * 2011-08-14 weety copy from mini2440
; */
#define NOINT 0xC0
.text
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
.globl rt_hw_interrupt_disable
rt_hw_interrupt_disable:
MRS R0, CPSR
ORR R1, R0, #NOINT
MSR CPSR_c, R1
BX LR
/*
* void rt_hw_interrupt_enable(rt_base_t level);
*/
.globl rt_hw_interrupt_enable
rt_hw_interrupt_enable:
MSR CPSR, R0
BX LR
/*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
* r0 --> from
* r1 --> to
*/
.globl rt_hw_context_switch
rt_hw_context_switch:
STMFD SP!, {LR} @; push pc (lr should be pushed in place of pc)
STMFD SP!, {R0-R12, LR} @; push lr & register file
MRS R4, CPSR
STMFD SP!, {R4} @; push cpsr
STR SP, [R0] @; store sp in preempted tasks tcb
LDR SP, [R1] @; get new task stack pointer
LDMFD SP!, {R4} @; pop new task spsr
MSR SPSR_cxsf, R4
LDMFD SP!, {R0-R12, LR, PC}^ @; pop new task r0-r12, lr & pc
/*
* void rt_hw_context_switch_to(rt_uint32 to);
* r0 --> to
*/
.globl rt_hw_context_switch_to
rt_hw_context_switch_to:
LDR SP, [R0] @; get new task stack pointer
LDMFD SP!, {R4} @; pop new task cpsr
MSR SPSR_cxsf, R4
LDMFD SP!, {R0-R12, LR, PC}^ @; pop new task r0-r12, lr & pc
/*
* void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
*/
.globl rt_thread_switch_interrupt_flag
.globl rt_interrupt_from_thread
.globl rt_interrupt_to_thread
.globl rt_hw_context_switch_interrupt
rt_hw_context_switch_interrupt:
LDR R2, =rt_thread_switch_interrupt_flag
LDR R3, [R2]
CMP R3, #1
BEQ _reswitch
MOV R3, #1 @; set flag to 1
STR R3, [R2]
LDR R2, =rt_interrupt_from_thread @; set rt_interrupt_from_thread
STR R0, [R2]
_reswitch:
LDR R2, =rt_interrupt_to_thread @; set rt_interrupt_to_thread
STR R1, [R2]
BX LR

View File

@@ -0,0 +1,82 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-08-14 weety copy from mini2440
* 2015-04-15 ArdaFu convert from context_gcc.s
*/
#define NOINT 0xc0
SECTION .text:CODE(6)
/*
* rt_base_t rt_hw_interrupt_disable();
*/
PUBLIC rt_hw_interrupt_disable
rt_hw_interrupt_disable:
MRS R0, CPSR
ORR R1, R0, #NOINT
MSR CPSR_C, R1
MOV PC, LR
/*
* void rt_hw_interrupt_enable(rt_base_t level);
*/
PUBLIC rt_hw_interrupt_enable
rt_hw_interrupt_enable:
MSR CPSR_CXSF, R0
MOV PC, LR
/*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
* r0 --> from
* r1 --> to
*/
PUBLIC rt_hw_context_switch
rt_hw_context_switch:
STMFD SP!, {LR} ; push pc (lr should be pushed in place of PC)
STMFD SP!, {R0-R12, LR} ; push lr & register file
MRS R4, CPSR
STMFD SP!, {R4} ; push cpsr
STR SP, [R0] ; store sp in preempted tasks TCB
LDR SP, [R1] ; get new task stack pointer
LDMFD SP!, {R4} ; pop new task spsr
MSR SPSR_cxsf, R4
LDMFD SP!, {R0-R12, LR, PC}^ ; pop new task r0-r12, lr & pc
/*
* void rt_hw_context_switch_to(rt_uint32 to);
* r0 --> to
*/
PUBLIC rt_hw_context_switch_to
rt_hw_context_switch_to:
LDR SP, [R0] ; get new task stack pointer
LDMFD SP!, {R4} ; pop new task spsr
MSR SPSR_cxsf, R4
LDMFD SP!, {R0-R12, LR, PC}^ ; pop new task r0-r12, lr & pc
/*
* void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
*/
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
PUBLIC rt_hw_context_switch_interrupt
rt_hw_context_switch_interrupt:
LDR R2, =rt_thread_switch_interrupt_flag
LDR R3, [R2]
CMP R3, #1
BEQ _reswitch
MOV R3, #1 ; set flag to 1
STR R3, [R2]
LDR R2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
STR R0, [R2]
_reswitch:
LDR R2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
STR R1, [R2]
MOV PC, LR
END

View File

@@ -0,0 +1,91 @@
;/*
; * Copyright (c) 2006-2018, RT-Thread Development Team
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
; * 2011-08-14 weety copy from mini2440
; */
NOINT EQU 0XC0 ; disable interrupt in psr
AREA |.TEXT|, CODE, READONLY, ALIGN=2
ARM
REQUIRE8
PRESERVE8
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
rt_hw_interrupt_disable PROC
EXPORT rt_hw_interrupt_disable
MRS R0, CPSR
ORR R1, R0, #NOINT
MSR CPSR_C, R1
BX LR
ENDP
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable proc
export rt_hw_interrupt_enable
msr cpsr_c, r0
bx lr
endp
;/*
; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
; * r0 --> from
; * r1 --> to
; */
rt_hw_context_switch proc
export rt_hw_context_switch
stmfd sp!, {lr} ; push pc (lr should be pushed in place of pc)
stmfd sp!, {r0-r12, lr} ; push lr & register file
mrs r4, cpsr
stmfd sp!, {r4} ; push cpsr
str sp, [r0] ; store sp in preempted tasks tcb
ldr sp, [r1] ; get new task stack pointer
ldmfd sp!, {r4} ; pop new task spsr
msr spsr_cxsf, r4
ldmfd sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc
endp
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; */
rt_hw_context_switch_to proc
export rt_hw_context_switch_to
ldr sp, [r0] ; get new task stack pointer
ldmfd sp!, {r4} ; pop new task spsr
msr spsr_cxsf, r4
ldmfd sp!, {r0-r12, lr, pc}^ ; pop new task r0-r12, lr & pc
endp
;/*
; * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
; */
import rt_thread_switch_interrupt_flag
import rt_interrupt_from_thread
import rt_interrupt_to_thread
rt_hw_context_switch_interrupt proc
export rt_hw_context_switch_interrupt
ldr r2, =rt_thread_switch_interrupt_flag
ldr r3, [r2]
cmp r3, #1
beq _reswitch
mov r3, #1 ; set flag to 1
str r3, [r2]
ldr r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread
str r0, [r2]
_reswitch
ldr r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread
str r1, [r2]
bx lr
endp
end

View File

@@ -0,0 +1,216 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-01-13 weety modified from mini2440
* 2015-04-15 ArdaFu Add code for IAR
*/
#include <rthw.h>
#include <rtthread.h>
#define ICACHE_MASK (rt_uint32_t)(1 << 12)
#define DCACHE_MASK (rt_uint32_t)(1 << 2)
extern void machine_reset(void);
extern void machine_shutdown(void);
#if defined(__GNUC__) || defined(__ICCARM__)
rt_inline rt_uint32_t cp15_rd(void)
{
rt_uint32_t i;
__asm volatile("mrc p15, 0, %0, c1, c0, 0":"=r"(i));
return i;
}
rt_inline void cache_enable(rt_uint32_t bit)
{
__asm volatile(\
"mrc p15,0,r0,c1,c0,0\n\t" \
"orr r0,r0,%0\n\t" \
"mcr p15,0,r0,c1,c0,0" \
: \
: "r"(bit) \
: "memory");
}
rt_inline void cache_disable(rt_uint32_t bit)
{
__asm volatile(\
"mrc p15,0,r0,c1,c0,0\n\t" \
"bic r0,r0,%0\n\t" \
"mcr p15,0,r0,c1,c0,0" \
: \
: "r"(bit) \
: "memory");
}
#endif
#if defined(__CC_ARM)
rt_inline rt_uint32_t cp15_rd(void)
{
rt_uint32_t i;
__asm volatile
{
mrc p15, 0, i, c1, c0, 0
}
return i;
}
rt_inline void cache_enable(rt_uint32_t bit)
{
rt_uint32_t value;
__asm volatile
{
mrc p15, 0, value, c1, c0, 0
orr value, value, bit
mcr p15, 0, value, c1, c0, 0
}
}
rt_inline void cache_disable(rt_uint32_t bit)
{
rt_uint32_t value;
__asm volatile
{
mrc p15, 0, value, c1, c0, 0
bic value, value, bit
mcr p15, 0, value, c1, c0, 0
}
}
#endif
/**
* enable I-Cache
*
*/
void rt_hw_cpu_icache_enable()
{
cache_enable(ICACHE_MASK);
}
/**
* disable I-Cache
*
*/
void rt_hw_cpu_icache_disable()
{
cache_disable(ICACHE_MASK);
}
/**
* return the status of I-Cache
*
*/
rt_base_t rt_hw_cpu_icache_status()
{
return (cp15_rd() & ICACHE_MASK);
}
/**
* enable D-Cache
*
*/
void rt_hw_cpu_dcache_enable()
{
cache_enable(DCACHE_MASK);
}
/**
* disable D-Cache
*
*/
void rt_hw_cpu_dcache_disable()
{
cache_disable(DCACHE_MASK);
}
/**
* return the status of D-Cache
*
*/
rt_base_t rt_hw_cpu_dcache_status()
{
return (cp15_rd() & DCACHE_MASK);
}
/**
* reset cpu by dog's time-out
*
*/
void rt_hw_cpu_reset()
{
rt_kprintf("Restarting system...\n");
machine_reset();
while (1); /* loop forever and wait for reset to happen */
/* NEVER REACHED */
}
/**
* shutdown CPU
*
*/
void rt_hw_cpu_shutdown()
{
rt_uint32_t level;
rt_kprintf("shutdown...\n");
level = rt_hw_interrupt_disable();
machine_shutdown();
while (level)
{
RT_ASSERT(0);
}
}
#ifdef RT_USING_CPU_FFS
/**
* This function finds the first bit set (beginning with the least significant bit)
* in value and return the index of that bit.
*
* Bits are numbered starting at 1 (the least significant bit). A return value of
* zero from any of these functions means that the argument was zero.
*
* @return return the index of the first bit set. If value is 0, then this function
* shall return 0.
*/
#if defined(__CC_ARM)
int __rt_ffs(int value)
{
register rt_uint32_t x;
if (value == 0)
return value;
__asm
{
rsb x, value, #0
and x, x, value
clz x, x
rsb x, x, #32
}
return x;
}
#elif defined(__GNUC__) || defined(__ICCARM__)
int __rt_ffs(int value)
{
return __builtin_ffs(value);
}
#endif
#endif
/*@}*/

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-02-08 RT-Thread the first version
*/
#include <rthw.h>
#include <rtthread.h>
RT_WEAK void machine_reset(void)
{
rt_kprintf("reboot system...\n");
rt_hw_interrupt_disable();
while (1);
}
RT_WEAK void machine_shutdown(void)
{
rt_kprintf("shutdown...\n");
rt_hw_interrupt_disable();
while (1);
}

View File

@@ -0,0 +1,443 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-04-15 ArdaFu Add code for IAR
*/
#include "mmu.h"
/*----- Keil -----------------------------------------------------------------*/
#ifdef __CC_ARM
void mmu_setttbase(rt_uint32_t i)
{
register rt_uint32_t value;
/* Invalidates all TLBs.Domain access is selected as
* client by configuring domain access register,
* in that case access controlled by permission value
* set by page table entry
*/
value = 0;
__asm volatile{ mcr p15, 0, value, c8, c7, 0 }
value = 0x55555555;
__asm volatile { mcr p15, 0, value, c3, c0, 0 }
__asm volatile { mcr p15, 0, i, c2, c0, 0 }
}
void mmu_set_domain(rt_uint32_t i)
{
__asm volatile { mcr p15, 0, i, c3, c0, 0 }
}
void mmu_enable()
{
register rt_uint32_t value;
__asm volatile
{
mrc p15, 0, value, c1, c0, 0
orr value, value, #0x01
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_disable()
{
register rt_uint32_t value;
__asm volatile
{
mrc p15, 0, value, c1, c0, 0
bic value, value, #0x01
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_enable_icache()
{
register rt_uint32_t value;
__asm volatile
{
mrc p15, 0, value, c1, c0, 0
orr value, value, #0x1000
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_enable_dcache()
{
register rt_uint32_t value;
__asm volatile
{
mrc p15, 0, value, c1, c0, 0
orr value, value, #0x04
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_disable_icache()
{
register rt_uint32_t value;
__asm volatile
{
mrc p15, 0, value, c1, c0, 0
bic value, value, #0x1000
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_disable_dcache()
{
register rt_uint32_t value;
__asm volatile
{
mrc p15, 0, value, c1, c0, 0
bic value, value, #0x04
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_enable_alignfault()
{
register rt_uint32_t value;
__asm volatile
{
mrc p15, 0, value, c1, c0, 0
orr value, value, #0x02
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_disable_alignfault()
{
register rt_uint32_t value;
__asm volatile
{
mrc p15, 0, value, c1, c0, 0
bic value, value, #0x02
mcr p15, 0, value, c1, c0, 0
}
}
void mmu_clean_invalidated_cache_index(int index)
{
__asm volatile { mcr p15, 0, index, c7, c14, 2 }
}
void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
{
unsigned int ptr;
ptr = buffer & ~(CACHE_LINE_SIZE - 1);
while (ptr < buffer + size)
{
__asm volatile { MCR p15, 0, ptr, c7, c14, 1 }
ptr += CACHE_LINE_SIZE;
}
}
void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
{
unsigned int ptr;
ptr = buffer & ~(CACHE_LINE_SIZE - 1);
while (ptr < buffer + size)
{
__asm volatile { MCR p15, 0, ptr, c7, c10, 1 }
ptr += CACHE_LINE_SIZE;
}
}
void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
{
unsigned int ptr;
ptr = buffer & ~(CACHE_LINE_SIZE - 1);
while (ptr < buffer + size)
{
__asm volatile { MCR p15, 0, ptr, c7, c6, 1 }
ptr += CACHE_LINE_SIZE;
}
}
void mmu_invalidate_tlb()
{
register rt_uint32_t value;
value = 0;
__asm volatile { mcr p15, 0, value, c8, c7, 0 }
}
void mmu_invalidate_icache()
{
register rt_uint32_t value;
value = 0;
__asm volatile { mcr p15, 0, value, c7, c5, 0 }
}
void mmu_invalidate_dcache_all()
{
register rt_uint32_t value;
value = 0;
__asm volatile { mcr p15, 0, value, c7, c6, 0 }
}
/*----- GNU ------------------------------------------------------------------*/
#elif defined(__GNUC__) || defined(__ICCARM__)
void mmu_setttbase(register rt_uint32_t i)
{
register rt_uint32_t value;
/* Invalidates all TLBs.Domain access is selected as
* client by configuring domain access register,
* in that case access controlled by permission value
* set by page table entry
*/
value = 0;
asm volatile("mcr p15, 0, %0, c8, c7, 0"::"r"(value));
value = 0x55555555;
asm volatile("mcr p15, 0, %0, c3, c0, 0"::"r"(value));
asm volatile("mcr p15, 0, %0, c2, c0, 0"::"r"(i));
}
void mmu_set_domain(register rt_uint32_t i)
{
asm volatile("mcr p15,0, %0, c3, c0, 0": :"r"(i));
}
void mmu_enable()
{
asm volatile
(
"mrc p15, 0, r0, c1, c0, 0 \n"
"orr r0, r0, #0x1 \n"
"mcr p15, 0, r0, c1, c0, 0 \n"
:::"r0"
);
}
void mmu_disable()
{
asm volatile
(
"mrc p15, 0, r0, c1, c0, 0 \n"
"bic r0, r0, #0x1 \n"
"mcr p15, 0, r0, c1, c0, 0 \n"
:::"r0"
);
}
void mmu_enable_icache()
{
asm volatile
(
"mrc p15, 0, r0, c1, c0, 0 \n"
"orr r0, r0, #(1<<12) \n"
"mcr p15, 0, r0, c1, c0, 0 \n"
:::"r0"
);
}
void mmu_enable_dcache()
{
asm volatile
(
"mrc p15, 0, r0, c1, c0, 0 \n"
"orr r0, r0, #(1<<2) \n"
"mcr p15, 0, r0, c1, c0, 0 \n"
:::"r0"
);
}
void mmu_disable_icache()
{
asm volatile
(
"mrc p15, 0, r0, c1, c0, 0 \n"
"bic r0, r0, #(1<<12) \n"
"mcr p15, 0, r0, c1, c0, 0 \n"
:::"r0"
);
}
void mmu_disable_dcache()
{
asm volatile
(
"mrc p15, 0, r0, c1, c0, 0 \n"
"bic r0, r0, #(1<<2) \n"
"mcr p15, 0, r0, c1, c0, 0 \n"
:::"r0"
);
}
void mmu_enable_alignfault()
{
asm volatile
(
"mrc p15, 0, r0, c1, c0, 0 \n"
"orr r0, r0, #1 \n"
"mcr p15, 0, r0, c1, c0, 0 \n"
:::"r0"
);
}
void mmu_disable_alignfault()
{
asm volatile
(
"mrc p15, 0, r0, c1, c0, 0 \n"
"bic r0, r0, #1 \n"
"mcr p15, 0, r0, c1, c0, 0 \n"
:::"r0"
);
}
void mmu_clean_invalidated_cache_index(int index)
{
asm volatile("mcr p15, 0, %0, c7, c14, 2": :"r"(index));
}
void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
{
unsigned int ptr;
ptr = buffer & ~(CACHE_LINE_SIZE - 1);
while (ptr < buffer + size)
{
asm volatile("mcr p15, 0, %0, c7, c14, 1": :"r"(ptr));
ptr += CACHE_LINE_SIZE;
}
}
void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
{
unsigned int ptr;
ptr = buffer & ~(CACHE_LINE_SIZE - 1);
while (ptr < buffer + size)
{
asm volatile("mcr p15, 0, %0, c7, c10, 1": :"r"(ptr));
ptr += CACHE_LINE_SIZE;
}
}
void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
{
unsigned int ptr;
ptr = buffer & ~(CACHE_LINE_SIZE - 1);
while (ptr < buffer + size)
{
asm volatile("mcr p15, 0, %0, c7, c6, 1": :"r"(ptr));
ptr += CACHE_LINE_SIZE;
}
}
void mmu_invalidate_tlb()
{
asm volatile("mcr p15, 0, %0, c8, c7, 0": :"r"(0));
}
void mmu_invalidate_icache()
{
asm volatile("mcr p15, 0, %0, c7, c5, 0": :"r"(0));
}
void mmu_invalidate_dcache_all()
{
asm volatile("mcr p15, 0, %0, c7, c6, 0": :"r"(0));
}
#endif
/* level1 page table */
#if defined(__ICCARM__)
#pragma data_alignment=(16*1024)
static volatile rt_uint32_t _page_table[4 * 1024];
#else
static volatile rt_uint32_t _page_table[4 * 1024] \
__attribute__((aligned(16 * 1024)));
#endif
void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd,
rt_uint32_t paddrStart, rt_uint32_t attr)
{
volatile rt_uint32_t *pTT;
volatile int nSec;
int i = 0;
pTT = (rt_uint32_t *)_page_table + (vaddrStart >> 20);
nSec = (vaddrEnd >> 20) - (vaddrStart >> 20);
for (i = 0; i <= nSec; i++)
{
*pTT = attr | (((paddrStart >> 20) + i) << 20);
pTT++;
}
}
void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size)
{
/* disable I/D cache */
mmu_disable_dcache();
mmu_disable_icache();
mmu_disable();
mmu_invalidate_tlb();
/* set page table */
for (; size > 0; size--)
{
mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end,
mdesc->paddr_start, mdesc->attr);
mdesc++;
}
/* set MMU table address */
mmu_setttbase((rt_uint32_t)_page_table);
/* enables MMU */
mmu_enable();
/* enable Instruction Cache */
mmu_enable_icache();
/* enable Data Cache */
mmu_enable_dcache();
mmu_invalidate_icache();
mmu_invalidate_dcache_all();
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-02-08 RT-Thread the first version
*/
#ifndef __MMU_H__
#define __MMU_H__
#include <rtthread.h>
#define CACHE_LINE_SIZE 32
#define DESC_SEC (0x2|(1<<4))
#define CB (3<<2) //cache_on, write_back
#define CNB (2<<2) //cache_on, write_through
#define NCB (1<<2) //cache_off,WR_BUF on
#define NCNB (0<<2) //cache_off,WR_BUF off
#define AP_RW (3<<10) //supervisor=RW, user=RW
#define AP_RO (2<<10) //supervisor=RW, user=RO
#define DOMAIN_FAULT (0x0)
#define DOMAIN_CHK (0x1)
#define DOMAIN_NOTCHK (0x3)
#define DOMAIN0 (0x0<<5)
#define DOMAIN1 (0x1<<5)
#define DOMAIN0_ATTR (DOMAIN_CHK<<0)
#define DOMAIN1_ATTR (DOMAIN_FAULT<<2)
#define RW_CB (AP_RW|DOMAIN0|CB|DESC_SEC) /* Read/Write, cache, write back */
#define RW_CNB (AP_RW|DOMAIN0|CNB|DESC_SEC) /* Read/Write, cache, write through */
#define RW_NCNB (AP_RW|DOMAIN0|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
#define RW_FAULT (AP_RW|DOMAIN1|NCNB|DESC_SEC) /* Read/Write without cache and write buffer */
struct mem_desc
{
rt_uint32_t vaddr_start;
rt_uint32_t vaddr_end;
rt_uint32_t paddr_start;
rt_uint32_t attr;
};
void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size);
void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size);
void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size);
void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size);
#endif

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-01-13 weety copy from mini2440
*/
#include <rtthread.h>
/*****************************/
/* CPU Mode */
/*****************************/
#define USERMODE 0x10
#define FIQMODE 0x11
#define IRQMODE 0x12
#define SVCMODE 0x13
#define ABORTMODE 0x17
#define UNDEFMODE 0x1b
#define MODEMASK 0x1f
#define NOINT 0xc0
/**
* This function will initialize thread stack
*
* @param tentry the entry of thread
* @param parameter the parameter of entry
* @param stack_addr the beginning stack address
* @param texit the function will be called when thread exit
*
* @return stack address
*/
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
rt_uint8_t *stack_addr, void *texit)
{
rt_uint32_t *stk;
stack_addr += sizeof(rt_uint32_t);
stack_addr = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
stk = (rt_uint32_t *)stack_addr;
*(--stk) = (rt_uint32_t)tentry; /* entry point */
*(--stk) = (rt_uint32_t)texit; /* lr */
*(--stk) = 0xdeadbeef; /* r12 */
*(--stk) = 0xdeadbeef; /* r11 */
*(--stk) = 0xdeadbeef; /* r10 */
*(--stk) = 0xdeadbeef; /* r9 */
*(--stk) = 0xdeadbeef; /* r8 */
*(--stk) = 0xdeadbeef; /* r7 */
*(--stk) = 0xdeadbeef; /* r6 */
*(--stk) = 0xdeadbeef; /* r5 */
*(--stk) = 0xdeadbeef; /* r4 */
*(--stk) = 0xdeadbeef; /* r3 */
*(--stk) = 0xdeadbeef; /* r2 */
*(--stk) = 0xdeadbeef; /* r1 */
*(--stk) = (rt_uint32_t)parameter; /* r0 : argument */
/* cpsr */
if ((rt_uint32_t)tentry & 0x01)
*(--stk) = SVCMODE | 0x20; /* thumb mode */
else
*(--stk) = SVCMODE; /* arm mode */
/* return task's current stack address */
return (rt_uint8_t *)stk;
}

View File

@@ -0,0 +1,330 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-01-13 weety first version
* 2015-04-15 ArdaFu Split from AT91SAM9260 BSP
* 2015-04-21 ArdaFu Remove remap code. Using mmu to map vector table
* 2015-06-04 aozima Align stack address to 8 byte.
*/
.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 MODEMASK, 0x1F
.equ NOINT, 0xC0
.equ I_BIT, 0x80
.equ F_BIT, 0x40
.equ UND_STACK_SIZE, 0x00000100
.equ SVC_STACK_SIZE, 0x00000100
.equ ABT_STACK_SIZE, 0x00000100
.equ FIQ_STACK_SIZE, 0x00000100
.equ IRQ_STACK_SIZE, 0x00000100
.equ SYS_STACK_SIZE, 0x00000100
/*
***************************************
* Interrupt vector table
***************************************
*/
.section .vectors
.code 32
.global system_vectors
system_vectors:
ldr pc, _vector_reset
ldr pc, _vector_undef
ldr pc, _vector_swi
ldr pc, _vector_pabt
ldr pc, _vector_dabt
ldr pc, _vector_resv
ldr pc, _vector_irq
ldr pc, _vector_fiq
_vector_reset:
.word reset
_vector_undef:
.word vector_undef
_vector_swi:
.word vector_swi
_vector_pabt:
.word vector_pabt
_vector_dabt:
.word vector_dabt
_vector_resv:
.word vector_resv
_vector_irq:
.word vector_irq
_vector_fiq:
.word vector_fiq
.balignl 16,0xdeadbeef
/*
***************************************
* Stack and Heap Definitions
***************************************
*/
.section .data
.space UND_STACK_SIZE
.align 3
.global und_stack_start
und_stack_start:
.space ABT_STACK_SIZE
.align 3
.global abt_stack_start
abt_stack_start:
.space FIQ_STACK_SIZE
.align 3
.global fiq_stack_start
fiq_stack_start:
.space IRQ_STACK_SIZE
.align 3
.global irq_stack_start
irq_stack_start:
.skip SYS_STACK_SIZE
.align 3
.global sys_stack_start
sys_stack_start:
.space SVC_STACK_SIZE
.align 3
.global svc_stack_start
svc_stack_start:
/*
***************************************
* Startup Code
***************************************
*/
.section .text
.global reset
reset:
/* Enter svc mode and mask interrupts */
mrs r0, cpsr
bic r0, r0, #MODEMASK
orr r0, r0, #MODE_SVC|NOINT
msr cpsr_cxsf, r0
/* init cpu */
bl cpu_init_crit
/* todo:copyself to link address */
/* Copy vector to the correct address */
ldr r0, =system_vectors
mrc p15, 0, r2, c1, c0, 0
ands r2, r2, #(1 << 13)
ldreq r1, =0x00000000
ldrne r1, =0xffff0000
ldmia r0!, {r2-r8, r10}
stmia r1!, {r2-r8, r10}
ldmia r0!, {r2-r8, r10}
stmia r1!, {r2-r8, r10}
/* turn off the watchdog */
ldr r0, =0x01C20CB8
mov r1, #0x0
str r1, [r0]
/* mask all IRQs source */
ldr r1, =0xffffffff
ldr r0, =0x01C20430
str r1, [r0], #0x04
str r1, [r0]
/* Call low level init function */
ldr sp, =svc_stack_start
ldr r0, =rt_low_level_init
blx r0
/* init stack */
bl stack_setup
/* clear bss */
mov r0, #0
ldr r1, =__bss_start
ldr r2, =__bss_end
bss_clear_loop:
cmp r1, r2
strlo r0, [r1], #4
blo bss_clear_loop
/* call c++ constructors of global objects */
/*
ldr r0, =__ctors_start__
ldr r1, =__ctors_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:
*/
/* start RT-Thread Kernel */
ldr pc, _rtthread_startup
_rtthread_startup:
.word rtthread_startup
cpu_init_crit:
/* invalidate I/D caches */
mov r0, #0
mcr p15, 0, r0, c7, c7, 0
mcr p15, 0, r0, c8, c7, 0
/* disable MMU stuff and caches */
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300
bic r0, r0, #0x00000087
orr r0, r0, #0x00000002
orr r0, r0, #0x00001000
mcr p15, 0, r0, c1, c0, 0
bx lr
stack_setup:
/* Setup Stack for each mode */
mrs r0, cpsr
bic r0, r0, #MODEMASK
orr r1, r0, #MODE_UND|NOINT
msr cpsr_cxsf, r1
ldr sp, =und_stack_start
orr r1, r0, #MODE_ABT|NOINT
msr cpsr_cxsf, r1
ldr sp, =abt_stack_start
orr r1, r0, #MODE_IRQ|NOINT
msr cpsr_cxsf, r1
ldr sp, =irq_stack_start
orr r1, r0, #MODE_FIQ|NOINT
msr cpsr_cxsf, r1
ldr sp, =fiq_stack_start
orr r1, r0, #MODE_SYS|NOINT
msr cpsr_cxsf,r1
ldr sp, =sys_stack_start
orr r1, r0, #MODE_SVC|NOINT
msr cpsr_cxsf, r1
ldr sp, =svc_stack_start
bx lr
/*
***************************************
* exception handlers
***************************************
*/
/* Interrupt */
vector_fiq:
stmfd sp!,{r0-r7,lr}
bl rt_hw_trap_fiq
ldmfd sp!,{r0-r7,lr}
subs pc, lr, #4
vector_irq:
stmfd sp!, {r0-r12,lr}
bl rt_interrupt_enter
bl rt_hw_trap_irq
bl rt_interrupt_leave
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
rt_hw_context_switch_interrupt_do:
mov r1, #0
str r1, [r0]
mov r1, sp
add sp, sp, #4*4
ldmfd sp!, {r4-r12,lr}
mrs r0, spsr
sub r2, lr, #4
msr cpsr_c, #I_BIT|F_BIT|MODE_SVC
stmfd sp!, {r2}
stmfd sp!, {r4-r12,lr}
ldmfd r1, {r1-r4}
stmfd sp!, {r1-r4}
stmfd sp!, {r0}
ldr r4, =rt_interrupt_from_thread
ldr r5, [r4]
str sp, [r5]
ldr r6, =rt_interrupt_to_thread
ldr r6, [r6]
ldr sp, [r6]
ldmfd sp!, {r4}
msr spsr_cxsf, r4
ldmfd sp!, {r0-r12,lr,pc}^
/* Exception */
.macro push_svc_reg
sub sp, sp, #17 * 4
stmia sp, {r0 - r12}
mov r0, sp
mrs r6, spsr
str lr, [r0, #15*4]
str r6, [r0, #16*4]
str sp, [r0, #13*4]
str lr, [r0, #14*4]
.endm
vector_swi:
push_svc_reg
bl rt_hw_trap_swi
b .
vector_undef:
push_svc_reg
bl rt_hw_trap_udef
b .
vector_pabt:
push_svc_reg
bl rt_hw_trap_pabt
b .
vector_dabt:
push_svc_reg
bl rt_hw_trap_dabt
b .
vector_resv:
push_svc_reg
bl rt_hw_trap_resv
b .

View File

@@ -0,0 +1,278 @@
;/*
; * Copyright (c) 2006-2018, RT-Thread Development Team
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
; * 2011-01-13 weety first version
; * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP
; * 2015-04-21 ArdaFu Remove remap code. Using mmu to map vector table
; * 2015-06-04 aozima Align stack address to 8 byte.
; */
#include "rt_low_level_init.h"
#define S_FRAME_SIZE (18*4) ;72
;#define S_SPSR (17*4) ;SPSR
;#define S_CPSR (16*4) ;CPSR
#define S_PC (15*4) ;R15
;#define S_LR (14*4) ;R14
;#define S_SP (13*4) ;R13
;#define S_IP (12*4) ;R12
;#define S_FP (11*4) ;R11
;#define S_R10 (10*4)
;#define S_R9 (9*4)
;#define S_R8 (8*4)
;#define S_R7 (7*4)
;#define S_R6 (6*4)
;#define S_R5 (5*4)
;#define S_R4 (4*4)
;#define S_R3 (3*4)
;#define S_R2 (2*4)
;#define S_R1 (1*4)
;#define S_R0 (0*4)
#define MODE_SYS 0x1F
#define MODE_FIQ 0x11
#define MODE_IRQ 0x12
#define MODE_SVC 0x13
#define MODE_ABT 0x17
#define MODE_UND 0x1B
#define MODEMASK 0x1F
#define NOINT 0xC0
;----------------------- Stack and Heap Definitions ----------------------------
MODULE ?cstartup
SECTION .noinit:DATA:NOROOT(3)
DATA
ALIGNRAM 3
DS8 UND_STK_SIZE
PUBLIC UND_STACK_START
UND_STACK_START:
ALIGNRAM 3
DS8 ABT_STK_SIZE
PUBLIC ABT_STACK_START
ABT_STACK_START:
ALIGNRAM 3
DS8 FIQ_STK_SIZE
PUBLIC FIQ_STACK_START
FIQ_STACK_START:
ALIGNRAM 3
DS8 IRQ_STK_SIZE
PUBLIC IRQ_STACK_START
IRQ_STACK_START:
ALIGNRAM 3
DS8 SYS_STK_SIZE
PUBLIC SYS_STACK_START
SYS_STACK_START:
ALIGNRAM 3
DS8 SVC_STK_SIZE
PUBLIC SVC_STACK_START
SVC_STACK_START:
;--------------Jump vector table------------------------------------------------
SECTION .intvec:CODE:ROOT(2)
ARM
PUBLIC Entry_Point
Entry_Point:
__iar_init$$done: ; The interrupt vector is not needed
; until after copy initialization is done
LDR PC, vector_reset
LDR PC, vector_undef
LDR PC, vector_swi
LDR PC, vector_pabt
LDR PC, vector_dabt
LDR PC, vector_resv
LDR PC, vector_irq
LDR PC, vector_fiq
vector_reset:
DC32 Reset_Handler
vector_undef:
DC32 Undef_Handler
vector_swi:
DC32 SWI_Handler
vector_pabt:
DC32 PAbt_Handler
vector_dabt:
DC32 DAbt_Handler
vector_resv:
DC32 Resv_Handler
vector_irq:
DC32 IRQ_Handler
vector_fiq:
DC32 FIQ_Handler
;----------------- Reset Handler -----------------------------------------------
EXTERN rt_low_level_init
EXTERN ?main
PUBLIC __iar_program_start
__iar_program_start:
Reset_Handler:
; Set the cpu to SVC32 mode
MRS R0, CPSR
BIC R0, R0, #MODEMASK
ORR R0, R0, #MODE_SVC|NOINT
MSR CPSR_cxsf, R0
; Set CO-Processor
; little-enddisbale I/D Cache MMU, vector table is 0x00000000
MRC P15, 0, R0, C1, C0, 0 ; Read CP15
LDR R1, =0x00003085 ; set clear bits
BIC R0, R0, R1
MCR P15, 0, R0, C1, C0, 0 ; Write CP15
; Call low level init function,
; disable and clear all IRQs, Init MMU, Init interrupt controller, etc.
LDR SP, =SVC_STACK_START
LDR R0, =rt_low_level_init
BLX R0
Setup_Stack:
; Setup Stack for each mode
MRS R0, CPSR
BIC R0, R0, #MODEMASK
ORR R1, R0, #MODE_UND|NOINT
MSR CPSR_cxsf, R1 ; Undef mode
LDR SP, =UND_STACK_START
ORR R1,R0,#MODE_ABT|NOINT
MSR CPSR_cxsf,R1 ; Abort mode
LDR SP, =ABT_STACK_START
ORR R1,R0,#MODE_IRQ|NOINT
MSR CPSR_cxsf,R1 ; IRQ mode
LDR SP, =IRQ_STACK_START
ORR R1,R0,#MODE_FIQ|NOINT
MSR CPSR_cxsf,R1 ; FIQ mode
LDR SP, =FIQ_STACK_START
ORR R1,R0,#MODE_SYS|NOINT
MSR CPSR_cxsf,R1 ; SYS/User mode
LDR SP, =SYS_STACK_START
ORR R1,R0,#MODE_SVC|NOINT
MSR CPSR_cxsf,R1 ; SVC mode
LDR SP, =SVC_STACK_START
; Enter the C code
LDR R0, =?main
BLX R0
;----------------- Exception Handler -------------------------------------------
IMPORT rt_hw_trap_udef
IMPORT rt_hw_trap_swi
IMPORT rt_hw_trap_pabt
IMPORT rt_hw_trap_dabt
IMPORT rt_hw_trap_resv
IMPORT rt_hw_trap_irq
IMPORT rt_hw_trap_fiq
IMPORT rt_interrupt_enter
IMPORT rt_interrupt_leave
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
SECTION .text:CODE:ROOT(2)
ARM
Undef_Handler:
SUB SP, SP, #S_FRAME_SIZE
STMIA SP, {R0 - R12} ; Calling R0-R12
ADD R8, SP, #S_PC
STMDB R8, {SP, LR} ; Calling SP, LR
STR LR, [R8, #0] ; Save calling PC
MRS R6, SPSR
STR R6, [R8, #4] ; Save CPSR
STR R0, [R8, #8] ; Save SPSR
MOV R0, SP
BL rt_hw_trap_udef
SWI_Handler:
BL rt_hw_trap_swi
PAbt_Handler:
BL rt_hw_trap_pabt
DAbt_Handler:
SUB SP, SP, #S_FRAME_SIZE
STMIA SP, {R0 - R12} ; Calling R0-R12
ADD R8, SP, #S_PC
STMDB R8, {SP, LR} ; Calling SP, LR
STR LR, [R8, #0] ; Save calling PC
MRS R6, SPSR
STR R6, [R8, #4] ; Save CPSR
STR R0, [R8, #8] ; Save SPSR
MOV R0, SP
BL rt_hw_trap_dabt
Resv_Handler:
BL rt_hw_trap_resv
IRQ_Handler:
STMFD SP!, {R0-R12,LR}
BL rt_interrupt_enter
BL rt_hw_trap_irq
BL rt_interrupt_leave
; 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
LDMFD SP!, {R0-R12,LR}
SUBS PC, LR, #4
FIQ_Handler:
STMFD SP!, {R0-R7,LR}
BL rt_hw_trap_fiq
LDMFD SP!, {R0-R7,LR}
SUBS PC, LR, #4
;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) -----------------
rt_hw_context_switch_interrupt_do:
MOV R1, #0 ; Clear flag
STR R1, [R0] ; Save to flag variable
LDMFD SP!, {R0-R12,LR} ; Reload saved registers
STMFD SP, {R0-R2} ; Save R0-R2
SUB R1, SP, #4*3 ; Save old task's SP to R1
SUB R2, LR, #4 ; Save old task's PC to R2
MRS R0, SPSR ; Get CPSR of interrupt thread
MSR CPSR_c, #MODE_SVC|NOINT ; Switch to SVC mode and no interrupt
STMFD SP!, {R2} ; Push old task's PC
STMFD SP!, {R3-R12,LR} ; Push old task's LR,R12-R3
LDMFD R1, {R1-R3}
STMFD SP!, {R1-R3} ; Push old task's R2-R0
STMFD SP!, {R0} ; Push old task's CPSR
LDR R4, =rt_interrupt_from_thread
LDR R5, [R4] ; R5 = stack ptr in old tasks's TCB
STR SP, [R5] ; Store SP in preempted tasks's TCB
LDR R6, =rt_interrupt_to_thread
LDR R6, [R6] ; R6 = stack ptr in new tasks's TCB
LDR SP, [R6] ; Get new task's stack pointer
LDMFD SP!, {R4} ; Pop new task's SPSR
MSR SPSR_cxsf, R4
LDMFD SP!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC SPSR to CPSR
END

View File

@@ -0,0 +1,301 @@
;/*
; * Copyright (c) 2006-2018, RT-Thread Development Team
; *
; * SPDX-License-Identifier: Apache-2.0
; *
; * Change Logs:
; * Date Author Notes
; * 2011-08-14 weety first version
; * 2015-04-15 ArdaFu Split from AT91SAM9260 BSP
; * 2015-04-21 ArdaFu Remove remap code. Using mmu to map vector table
; * 2015-06-04 aozima Align stack address to 8 byte.
; */
UND_STK_SIZE EQU 512
SVC_STK_SIZE EQU 4096
ABT_STK_SIZE EQU 512
IRQ_STK_SIZE EQU 1024
FIQ_STK_SIZE EQU 1024
SYS_STK_SIZE EQU 512
Heap_Size EQU 512
S_FRAME_SIZE EQU (18*4) ;72
S_PC EQU (15*4) ;R15
MODE_USR EQU 0X10
MODE_FIQ EQU 0X11
MODE_IRQ EQU 0X12
MODE_SVC EQU 0X13
MODE_ABT EQU 0X17
MODE_UND EQU 0X1B
MODE_SYS EQU 0X1F
MODEMASK EQU 0X1F
NOINT EQU 0xC0
;----------------------- Stack and Heap Definitions ----------------------------
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem
SPACE UND_STK_SIZE
EXPORT UND_STACK_START
UND_STACK_START
ALIGN 8
SPACE ABT_STK_SIZE
EXPORT ABT_STACK_START
ABT_STACK_START
ALIGN 8
SPACE FIQ_STK_SIZE
EXPORT FIQ_STACK_START
FIQ_STACK_START
ALIGN 8
SPACE IRQ_STK_SIZE
EXPORT IRQ_STACK_START
IRQ_STACK_START
ALIGN 8
SPACE SYS_STK_SIZE
EXPORT SYS_STACK_START
SYS_STACK_START
ALIGN 8
SPACE SVC_STK_SIZE
EXPORT SVC_STACK_START
SVC_STACK_START
Stack_Top
__initial_sp
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
;--------------Jump vector table------------------------------------------------
EXPORT Entry_Point
AREA RESET, CODE, READONLY
ARM
Entry_Point
LDR PC, vector_reset
LDR PC, vector_undef
LDR PC, vector_swi
LDR PC, vector_pabt
LDR PC, vector_dabt
LDR PC, vector_resv
LDR PC, vector_irq
LDR PC, vector_fiq
vector_reset
DCD Reset_Handler
vector_undef
DCD Undef_Handler
vector_swi
DCD SWI_Handler
vector_pabt
DCD PAbt_Handler
vector_dabt
DCD DAbt_Handler
vector_resv
DCD Resv_Handler
vector_irq
DCD IRQ_Handler
vector_fiq
DCD FIQ_Handler
;----------------- Reset Handler -----------------------------------------------
IMPORT rt_low_level_init
IMPORT __main
EXPORT Reset_Handler
Reset_Handler
; set the cpu to SVC32 mode
MRS R0,CPSR
BIC R0,R0,#MODEMASK
ORR R0,R0,#MODE_SVC:OR:NOINT
MSR CPSR_cxsf,R0
; Set CO-Processor
; little-enddisbale I/D Cache MMU, vector table is 0x00000000
MRC p15, 0, R0, c1, c0, 0 ; Read CP15
LDR R1, =0x00003085 ; set clear bits
BIC R0, R0, R1
MCR p15, 0, R0, c1, c0, 0 ; Write CP15
; Call low level init function,
; disable and clear all IRQs, Init MMU, Init interrupt controller, etc.
LDR SP, =SVC_STACK_START
LDR R0, =rt_low_level_init
BLX R0
Setup_Stack
; Setup Stack for each mode
MRS R0, CPSR
BIC R0, R0, #MODEMASK
ORR R1, R0, #MODE_UND:OR:NOINT
MSR CPSR_cxsf, R1 ; Undef mode
LDR SP, =UND_STACK_START
ORR R1,R0,#MODE_ABT:OR:NOINT
MSR CPSR_cxsf,R1 ; Abort mode
LDR SP, =ABT_STACK_START
ORR R1,R0,#MODE_IRQ:OR:NOINT
MSR CPSR_cxsf,R1 ; IRQ mode
LDR SP, =IRQ_STACK_START
ORR R1,R0,#MODE_FIQ:OR:NOINT
MSR CPSR_cxsf,R1 ; FIQ mode
LDR SP, =FIQ_STACK_START
ORR R1,R0,#MODE_SYS:OR:NOINT
MSR CPSR_cxsf,R1 ; SYS/User mode
LDR SP, =SYS_STACK_START
ORR R1,R0,#MODE_SVC:OR:NOINT
MSR CPSR_cxsf,R1 ; SVC mode
LDR SP, =SVC_STACK_START
; Enter the C code
LDR R0, =__main
BLX R0
;----------------- Exception Handler -------------------------------------------
IMPORT rt_hw_trap_udef
IMPORT rt_hw_trap_swi
IMPORT rt_hw_trap_pabt
IMPORT rt_hw_trap_dabt
IMPORT rt_hw_trap_resv
IMPORT rt_hw_trap_irq
IMPORT rt_hw_trap_fiq
IMPORT rt_interrupt_enter
IMPORT rt_interrupt_leave
IMPORT rt_thread_switch_interrupt_flag
IMPORT rt_interrupt_from_thread
IMPORT rt_interrupt_to_thread
Undef_Handler PROC
SUB SP, SP, #S_FRAME_SIZE
STMIA SP, {R0 - R12} ; Calling R0-R12
ADD R8, SP, #S_PC
STMDB R8, {SP, LR} ; Calling SP, LR
STR LR, [R8, #0] ; Save calling PC
MRS R6, SPSR
STR R6, [R8, #4] ; Save CPSR
STR R0, [R8, #8] ; Save SPSR
MOV R0, SP
BL rt_hw_trap_udef
ENDP
SWI_Handler PROC
BL rt_hw_trap_swi
ENDP
PAbt_Handler PROC
BL rt_hw_trap_pabt
ENDP
DAbt_Handler PROC
SUB SP, SP, #S_FRAME_SIZE
STMIA SP, {R0 - R12} ; Calling R0-R12
ADD R8, SP, #S_PC
STMDB R8, {SP, LR} ; Calling SP, LR
STR LR, [R8, #0] ; Save calling PC
MRS R6, SPSR
STR R6, [R8, #4] ; Save CPSR
STR R0, [R8, #8] ; Save SPSR
MOV R0, SP
BL rt_hw_trap_dabt
ENDP
Resv_Handler PROC
BL rt_hw_trap_resv
ENDP
FIQ_Handler PROC
STMFD SP!, {R0-R7,LR}
BL rt_hw_trap_fiq
LDMFD SP!, {R0-R7,LR}
SUBS PC, LR, #4
ENDP
IRQ_Handler PROC
STMFD SP!, {R0-R12,LR}
BL rt_interrupt_enter
BL rt_hw_trap_irq
BL rt_interrupt_leave
; 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
LDMFD SP!, {R0-R12,LR}
SUBS PC, LR, #4
ENDP
;------ void rt_hw_context_switch_interrupt_do(rt_base_t flag) -----------------
rt_hw_context_switch_interrupt_do PROC
MOV R1, #0 ; Clear flag
STR R1, [R0] ; Save to flag variable
LDMFD SP!, {R0-R12,LR} ; Reload saved registers
STMFD SP, {R0-R2} ; Save R0-R2
SUB R1, SP, #4*3 ; Save old task's SP to R1
SUB R2, LR, #4 ; Save old task's PC to R2
MRS R0, SPSR ; Get CPSR of interrupt thread
MSR CPSR_c, #MODE_SVC:OR:NOINT ; Switch to SVC mode and no interrupt
STMFD SP!, {R2} ; Push old task's PC
STMFD SP!, {R3-R12,LR} ; Push old task's LR,R12-R3
LDMFD R1, {R1-R3}
STMFD SP!, {R1-R3} ; Push old task's R2-R0
STMFD SP!, {R0} ; Push old task's CPSR
LDR R4, =rt_interrupt_from_thread
LDR R5, [R4] ; R5 = stack ptr in old tasks's TCB
STR SP, [R5] ; Store SP in preempted tasks's TCB
LDR R6, =rt_interrupt_to_thread
LDR R6, [R6] ; R6 = stack ptr in new tasks's TCB
LDR SP, [R6] ; Get new task's stack pointer
LDMFD SP!, {R4} ; Pop new task's SPSR
MSR SPSR_cxsf, R4
LDMFD SP!, {R0-R12,LR,PC}^ ; pop new task's R0-R12,LR & PC SPSR to CPSR
ENDP
;*******************************************************************************
; User Stack and Heap initialization
;*******************************************************************************
IF :DEF:__MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem ; heap base
LDR R1, = SVC_STACK_START ; stack base (top-address)
LDR R2, = (Heap_Mem + Heap_Size) ; heap limit
LDR R3, = (SVC_STACK_START - SVC_STK_SIZE) ; stack limit (low-address)
BX LR
ALIGN
ENDIF
END

View File

@@ -0,0 +1,210 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-01-13 weety modified from mini2440
* 2015-04-15 ArdaFu Split from AT91SAM9260 BSP
*/
#include <rtthread.h>
#include <rthw.h>
#define INT_IRQ 0x00
#define INT_FIQ 0x01
extern struct rt_thread *rt_current_thread;
#ifdef RT_USING_FINSH
extern long list_thread(void);
#endif
struct rt_hw_register
{
rt_uint32_t r0;
rt_uint32_t r1;
rt_uint32_t r2;
rt_uint32_t r3;
rt_uint32_t r4;
rt_uint32_t r5;
rt_uint32_t r6;
rt_uint32_t r7;
rt_uint32_t r8;
rt_uint32_t r9;
rt_uint32_t r10;
rt_uint32_t fp;
rt_uint32_t ip;
rt_uint32_t sp;
rt_uint32_t lr;
rt_uint32_t pc;
rt_uint32_t cpsr;
rt_uint32_t ORIG_r0;
};
static rt_err_t (*rt_exception_hook)(void *context) = RT_NULL;
void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context))
{
rt_exception_hook = exception_handle;
}
/**
* this function will show registers of CPU
*
* @param regs the registers point
*/
void rt_hw_show_register(struct rt_hw_register *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);
}
/**
* When ARM7TDMI comes across an instruction which it cannot handle,
* it takes the undefined instruction trap.
*
* @param regs system registers
*
* @note never invoke this function in application
*/
void rt_hw_trap_udef(struct rt_hw_register *regs)
{
if (rt_exception_hook != RT_NULL)
{
rt_err_t result;
result = rt_exception_hook(regs);
if (result == RT_EOK) return;
}
rt_hw_show_register(regs);
rt_kprintf("undefined instruction\n");
rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
#ifdef RT_USING_FINSH
list_thread();
#endif
rt_hw_cpu_shutdown();
}
/**
* 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_register *regs)
{
if (rt_exception_hook != RT_NULL)
{
rt_err_t result;
result = rt_exception_hook(regs);
if (result == RT_EOK) return;
}
rt_hw_show_register(regs);
rt_kprintf("software interrupt\n");
rt_hw_cpu_shutdown();
}
/**
* An abort indicates that the current memory access cannot be completed,
* which occurs during an instruction prefetch.
*
* @param regs system registers
*
* @note never invoke this function in application
*/
void rt_hw_trap_pabt(struct rt_hw_register *regs)
{
if (rt_exception_hook != RT_NULL)
{
rt_err_t result;
result = rt_exception_hook(regs);
if (result == RT_EOK) return;
}
rt_hw_show_register(regs);
rt_kprintf("prefetch abort\n");
rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name);
#ifdef RT_USING_FINSH
list_thread();
#endif
rt_hw_cpu_shutdown();
}
/**
* An abort indicates that the current memory access cannot be completed,
* which occurs during a data access.
*
* @param regs system registers
*
* @note never invoke this function in application
*/
void rt_hw_trap_dabt(struct rt_hw_register *regs)
{
if (rt_exception_hook != RT_NULL)
{
rt_err_t result;
result = rt_exception_hook(regs);
if (result == RT_EOK) return;
}
rt_hw_show_register(regs);
rt_kprintf("data abort\n");
rt_kprintf("thread - %s stack:\n", RT_NAME_MAX, rt_current_thread->name);
#ifdef RT_USING_FINSH
list_thread();
#endif
rt_hw_cpu_shutdown();
}
/**
* Normally, system will never reach here
*
* @param regs system registers
*
* @note never invoke this function in application
*/
void rt_hw_trap_resv(struct rt_hw_register *regs)
{
if (rt_exception_hook != RT_NULL)
{
rt_err_t result;
result = rt_exception_hook(regs);
if (result == RT_EOK) return;
}
rt_kprintf("not used\n");
rt_hw_show_register(regs);
rt_hw_cpu_shutdown();
}
extern void rt_interrupt_dispatch(rt_uint32_t fiq_irq);
void rt_hw_trap_irq(void)
{
rt_interrupt_dispatch(INT_IRQ);
}
void rt_hw_trap_fiq(void)
{
rt_interrupt_dispatch(INT_FIQ);
}