RT-Thread_v4.1.1
This commit is contained in:
23
libcpu/arm/s3c44b0/SConscript
Normal file
23
libcpu/arm/s3c44b0/SConscript
Normal file
@ -0,0 +1,23 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
|
||||
Import('rtconfig')
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c') + Glob('*.cpp')
|
||||
CPPPATH = [cwd]
|
||||
|
||||
if rtconfig.PLATFORM in ['armcc', 'armclang']:
|
||||
src += Glob('*_rvds.S')
|
||||
|
||||
if rtconfig.PLATFORM in ['gcc']:
|
||||
src += Glob('*_init.S')
|
||||
src += Glob('*_gcc.S')
|
||||
|
||||
if rtconfig.PLATFORM in ['iccarm']:
|
||||
src += Glob('*_iar.S')
|
||||
|
||||
group = DefineGroup('CPU', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
95
libcpu/arm/s3c44b0/context_gcc.S
Normal file
95
libcpu/arm/s3c44b0/context_gcc.S
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-09-06 XuXinming first version
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \addtogroup S3C44B0
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
#define NOINT 0xc0
|
||||
|
||||
/*
|
||||
* 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
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* void rt_hw_interrupt_enable(rt_base_t level);
|
||||
*/
|
||||
.globl rt_hw_interrupt_enable
|
||||
rt_hw_interrupt_enable:
|
||||
msr cpsr, r0
|
||||
mov pc, 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
|
||||
mrs r4, spsr
|
||||
stmfd sp!, {r4} @ push spsr
|
||||
|
||||
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!, {r4} @ pop new task cpsr
|
||||
msr cpsr_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 spsr
|
||||
msr spsr_cxsf, r4
|
||||
ldmfd sp!, {r4} @ pop new task cpsr
|
||||
msr cpsr_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 rt_thread_switch_interrupt_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
|
103
libcpu/arm/s3c44b0/context_rvds.S
Normal file
103
libcpu/arm/s3c44b0/context_rvds.S
Normal file
@ -0,0 +1,103 @@
|
||||
;/*
|
||||
; * Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
; *
|
||||
; * SPDX-License-Identifier: Apache-2.0
|
||||
; *
|
||||
; * Change Logs:
|
||||
; * Date Author Notes
|
||||
; * 2009-01-20 Bernard first version
|
||||
; */
|
||||
|
||||
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
|
||||
MRS r4, spsr
|
||||
STMFD sp!, {r4} ; push spsr
|
||||
|
||||
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!, {r4} ; pop new task cpsr
|
||||
MSR cpsr_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!, {r4} ; pop new task cpsr
|
||||
MSR cpsr_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 rt_thread_switch_interrupt_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
|
118
libcpu/arm/s3c44b0/cpu.c
Normal file
118
libcpu/arm/s3c44b0/cpu.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-09-06 XuXinming first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "s3c44b0.h"
|
||||
|
||||
/**
|
||||
* @addtogroup S3C44B0
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
* This function will enable I-Cache of CPU
|
||||
*
|
||||
*/
|
||||
void rt_hw_cpu_icache_enable()
|
||||
{
|
||||
rt_base_t reg;
|
||||
|
||||
volatile int i;
|
||||
/* flush cycle */
|
||||
for(i = 0x10002000; i < 0x10004800; i+=16)
|
||||
{
|
||||
*((int *)i)=0x0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Init cache
|
||||
* Non-cacheable area (everything outside RAM)
|
||||
* 0x0000:0000 - 0x0C00:0000
|
||||
*/
|
||||
NCACHBE0 = 0xC0000000;
|
||||
NCACHBE1 = 0x00000000;
|
||||
|
||||
/*
|
||||
Enable chache
|
||||
*/
|
||||
reg = SYSCFG;
|
||||
reg |= 0x00000006; /* 8kB */
|
||||
SYSCFG = reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will disable I-Cache of CPU
|
||||
*
|
||||
*/
|
||||
void rt_hw_cpu_icache_disable()
|
||||
{
|
||||
rt_base_t reg;
|
||||
|
||||
reg = SYSCFG;
|
||||
reg &= ~0x00000006; /* 8kB */
|
||||
SYSCFG = reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* this function will get the status of I-Cache
|
||||
*
|
||||
*/
|
||||
rt_base_t rt_hw_cpu_icache_status()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* this function will enable D-Cache of CPU
|
||||
*
|
||||
*/
|
||||
void rt_hw_cpu_dcache_enable()
|
||||
{
|
||||
rt_hw_cpu_icache_enable();
|
||||
}
|
||||
|
||||
/**
|
||||
* this function will disable D-Cache of CPU
|
||||
*
|
||||
*/
|
||||
void rt_hw_cpu_dcache_disable()
|
||||
{
|
||||
rt_hw_cpu_icache_disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* this function will get the status of D-Cache
|
||||
*
|
||||
*/
|
||||
rt_base_t rt_hw_cpu_dcache_status()
|
||||
{
|
||||
return rt_hw_cpu_icache_status();
|
||||
}
|
||||
|
||||
/**
|
||||
* this function will reset CPU
|
||||
*
|
||||
*/
|
||||
RT_WEAK void rt_hw_cpu_reset()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* this function will shutdown CPU
|
||||
*
|
||||
*/
|
||||
RT_WEAK void rt_hw_cpu_shutdown()
|
||||
{
|
||||
rt_kprintf("shutdown...\n");
|
||||
|
||||
while (1);
|
||||
}
|
||||
|
||||
/*@}*/
|
144
libcpu/arm/s3c44b0/interrupt.c
Normal file
144
libcpu/arm/s3c44b0/interrupt.c
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-09-06 XuXinming first version
|
||||
* 2006-09-15 Bernard add interrupt bank 0..3 for more effective
|
||||
* in irq trap
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "s3c44b0.h"
|
||||
|
||||
#define MAX_HANDLERS 26
|
||||
|
||||
extern rt_uint32_t rt_interrupt_nest;
|
||||
|
||||
/* exception and interrupt handler table */
|
||||
rt_isr_handler_t isr_table[MAX_HANDLERS];
|
||||
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
|
||||
rt_uint32_t rt_thread_switch_interrupt_flag;
|
||||
|
||||
unsigned char interrupt_bank0[256];
|
||||
unsigned char interrupt_bank1[256];
|
||||
unsigned char interrupt_bank2[256];
|
||||
unsigned char interrupt_bank3[256];
|
||||
|
||||
/**
|
||||
* @addtogroup S3C44B0
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
void rt_hw_interrupt_handle(int vector)
|
||||
{
|
||||
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will initialize hardware interrupt
|
||||
*/
|
||||
void rt_hw_interrupt_init()
|
||||
{
|
||||
register int i;
|
||||
|
||||
/* all interrupt disabled include global bit */
|
||||
INTMSK = 0x07ffffff;
|
||||
|
||||
/* clear pending register */
|
||||
I_ISPC = 0x03ffffff;
|
||||
|
||||
/* non-vector mode IRQ enable */
|
||||
INTCON = 0x5;
|
||||
|
||||
/* all IRQ mode */
|
||||
INTMOD = 0x0;
|
||||
|
||||
/* init exceptions table */
|
||||
for(i=0; i<MAX_HANDLERS; i++)
|
||||
{
|
||||
isr_table[i] = rt_hw_interrupt_handle;
|
||||
}
|
||||
|
||||
for ( i = 0; i < 256; i++)
|
||||
{
|
||||
interrupt_bank0[i] = 0;
|
||||
interrupt_bank1[i] = 0;
|
||||
interrupt_bank2[i] = 0;
|
||||
interrupt_bank3[i] = 0;
|
||||
}
|
||||
|
||||
/* setup interrupt bank table */
|
||||
interrupt_bank0[1] = 0;
|
||||
interrupt_bank0[2] = 1;
|
||||
interrupt_bank0[4] = 2;
|
||||
interrupt_bank0[8] = 3;
|
||||
interrupt_bank0[16] = 4;
|
||||
interrupt_bank0[32] = 5;
|
||||
interrupt_bank0[64] = 6;
|
||||
interrupt_bank0[128]= 7;
|
||||
|
||||
interrupt_bank1[1] = 8;
|
||||
interrupt_bank1[2] = 9;
|
||||
interrupt_bank1[4] = 10;
|
||||
interrupt_bank1[8] = 11;
|
||||
interrupt_bank1[16] = 12;
|
||||
interrupt_bank1[32] = 13;
|
||||
interrupt_bank1[64] = 14;
|
||||
interrupt_bank1[128]= 15;
|
||||
|
||||
interrupt_bank2[1] = 16;
|
||||
interrupt_bank2[2] = 17;
|
||||
interrupt_bank2[4] = 18;
|
||||
interrupt_bank2[8] = 19;
|
||||
interrupt_bank2[16] = 20;
|
||||
interrupt_bank2[32] = 21;
|
||||
interrupt_bank2[64] = 22;
|
||||
interrupt_bank2[128]= 23;
|
||||
|
||||
interrupt_bank3[1] = 24;
|
||||
interrupt_bank3[2] = 25;
|
||||
|
||||
/* init interrupt nest, and context in thread sp */
|
||||
rt_interrupt_nest = 0;
|
||||
rt_interrupt_from_thread = 0;
|
||||
rt_interrupt_to_thread = 0;
|
||||
rt_thread_switch_interrupt_flag = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will mask a interrupt.
|
||||
* @param vector the interrupt number
|
||||
*/
|
||||
void rt_hw_interrupt_mask(int vector)
|
||||
{
|
||||
INTMSK |= 1 << vector;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will un-mask a interrupt.
|
||||
* @param vector the interrupt number
|
||||
*/
|
||||
void rt_hw_interrupt_umask(int vector)
|
||||
{
|
||||
INTMSK &= ~(1 << vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will install a interrupt service routine to a interrupt.
|
||||
* @param vector the interrupt number
|
||||
* @param new_handler the interrupt service routine to be installed
|
||||
* @param old_handler the old interrupt service routine
|
||||
*/
|
||||
void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
|
||||
{
|
||||
if(vector < MAX_HANDLERS)
|
||||
{
|
||||
if (old_handler != RT_NULL) *old_handler = isr_table[vector];
|
||||
if (new_handler != RT_NULL) isr_table[vector] = new_handler;
|
||||
}
|
||||
}
|
||||
|
||||
/*@}*/
|
342
libcpu/arm/s3c44b0/s3c44b0.h
Normal file
342
libcpu/arm/s3c44b0/s3c44b0.h
Normal file
@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-09-06 XuXinming first version
|
||||
* 2006-09-16 Bernard modify according to code style
|
||||
*/
|
||||
|
||||
#ifndef __S3C44B0_H__
|
||||
#define __S3C44B0_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup S3C44B0
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* ASIC Address Definition
|
||||
*----------------------------------------------------------------------*/
|
||||
#define S3C_REG *(volatile unsigned int *)
|
||||
#define S3C_REGW *(volatile unsigned short *)
|
||||
#define S3C_REGB *(volatile unsigned char *)
|
||||
|
||||
/* System */
|
||||
#define SYSCFG (S3C_REG(0x1c00000))
|
||||
|
||||
/* Cache */
|
||||
#define NCACHBE0 (S3C_REG(0x1c00004))
|
||||
#define NCACHBE1 (S3C_REG(0x1c00008))
|
||||
|
||||
/* Bus control */
|
||||
#define SBUSCON (S3C_REG(0x1c40000))
|
||||
|
||||
/* Memory control */
|
||||
#define BWSCON (S3C_REG(0x1c80000))
|
||||
#define BANKCON0 (S3C_REG(0x1c80004))
|
||||
#define BANKCON1 (S3C_REG(0x1c80008))
|
||||
#define BANKCON2 (S3C_REG(0x1c8000c))
|
||||
#define BANKCON3 (S3C_REG(0x1c80010))
|
||||
#define BANKCON4 (S3C_REG(0x1c80014))
|
||||
#define BANKCON5 (S3C_REG(0x1c80018))
|
||||
#define BANKCON6 (S3C_REG(0x1c8001c))
|
||||
#define BANKCON7 (S3C_REG(0x1c80020))
|
||||
#define REFRESH (S3C_REG(0x1c80024))
|
||||
#define BANKSIZE (S3C_REG(0x1c80028))
|
||||
#define MRSRB6 (S3C_REG(0x1c8002c))
|
||||
#define MRSRB7 (S3C_REG(0x1c80030))
|
||||
|
||||
/* UART */
|
||||
#define ULCON0 (S3C_REG(0x1d00000))
|
||||
#define ULCON1 (S3C_REG(0x1d04000))
|
||||
#define UCON0 (S3C_REG(0x1d00004))
|
||||
#define UCON1 (S3C_REG(0x1d04004))
|
||||
#define UFCON0 (S3C_REG(0x1d00008))
|
||||
#define UFCON1 (S3C_REG(0x1d04008))
|
||||
#define UMCON0 (S3C_REG(0x1d0000c))
|
||||
#define UMCON1 (S3C_REG(0x1d0400c))
|
||||
#define UTRSTAT0 (S3C_REG(0x1d00010))
|
||||
#define UTRSTAT1 (S3C_REG(0x1d04010))
|
||||
#define UERSTAT0 (S3C_REG(0x1d00014))
|
||||
#define UERSTAT1 (S3C_REG(0x1d04014))
|
||||
#define UFSTAT0 (S3C_REG(0x1d00018))
|
||||
#define UFSTAT1 (S3C_REG(0x1d04018))
|
||||
#define UMSTAT0 (S3C_REG(0x1d0001c))
|
||||
#define UMSTAT1 (S3C_REG(0x1d0401c))
|
||||
#define UBRDIV0 (S3C_REG(0x1d00028))
|
||||
#define UBRDIV1 (S3C_REG(0x1d04028))
|
||||
|
||||
#define UTXH0 (S3C_REGB(0x1d00020))
|
||||
#define UTXH1 (S3C_REGB(0x1d04020))
|
||||
#define URXH0 (S3C_REGB(0x1d00024))
|
||||
#define URXH1 (S3C_REGB(0x1d04024))
|
||||
|
||||
/* SIO */
|
||||
#define SIOCON (S3C_REG(0x1d14000))
|
||||
#define SIODAT (S3C_REG(0x1d14004))
|
||||
#define SBRDR (S3C_REG(0x1d14008))
|
||||
#define IVTCNT (S3C_REG(0x1d1400c))
|
||||
#define DCNTZ (S3C_REG(0x1d14010))
|
||||
|
||||
/* IIS */
|
||||
#define IISCON (S3C_REG(0x1d18000))
|
||||
#define IISMOD (S3C_REG(0x1d18004))
|
||||
#define IISPSR (S3C_REG(0x1d18008))
|
||||
#define IISFCON (S3C_REG(0x1d1800c))
|
||||
|
||||
#define IISFIF (S3C_REQW(0x1d18010))
|
||||
|
||||
/* I/O Port */
|
||||
#define PCONA (S3C_REG(0x1d20000))
|
||||
#define PDATA (S3C_REG(0x1d20004))
|
||||
|
||||
#define PCONB (S3C_REG(0x1d20008))
|
||||
#define PDATB (S3C_REG(0x1d2000c))
|
||||
|
||||
#define PCONC (S3C_REG(0x1d20010))
|
||||
#define PDATC (S3C_REG(0x1d20014))
|
||||
#define PUPC (S3C_REG(0x1d20018))
|
||||
|
||||
#define PCOND (S3C_REG(0x1d2001c))
|
||||
#define PDATD (S3C_REG(0x1d20020))
|
||||
#define PUPD (S3C_REG(0x1d20024))
|
||||
|
||||
#define PCONE (S3C_REG(0x1d20028))
|
||||
#define PDATE (S3C_REG(0x1d2002c))
|
||||
#define PUPE (S3C_REG(0x1d20030))
|
||||
|
||||
#define PCONF (S3C_REG(0x1d20034))
|
||||
#define PDATF (S3C_REG(0x1d20038))
|
||||
#define PUPF (S3C_REG(0x1d2003c))
|
||||
|
||||
#define PCONG (S3C_REG(0x1d20040))
|
||||
#define PDATG (S3C_REG(0x1d20044))
|
||||
#define PUPG (S3C_REG(0x1d20048))
|
||||
|
||||
#define SPUCR (S3C_REG(0x1d2004c))
|
||||
#define EXTINT (S3C_REG(0x1d20050))
|
||||
#define EXTINTPND (S3C_REG(0x1d20054))
|
||||
|
||||
/* Watchdog */
|
||||
#define WTCON (S3C_REG(0x1d30000))
|
||||
#define WTDAT (S3C_REG(0x1d30004))
|
||||
#define WTCNT (S3C_REG(0x1d30008))
|
||||
|
||||
/* ADC */
|
||||
#define ADCCON (S3C_REG(0x1d40000))
|
||||
#define ADCPSR (S3C_REG(0x1d40004))
|
||||
#define ADCDAT (S3C_REG(0x1d40008))
|
||||
|
||||
/* Timer */
|
||||
#define TCFG0 (S3C_REG(0x1d50000))
|
||||
#define TCFG1 (S3C_REG(0x1d50004))
|
||||
#define TCON (S3C_REG(0x1d50008))
|
||||
|
||||
#define TCNTB0 (S3C_REG(0x1d5000c))
|
||||
#define TCMPB0 (S3C_REG(0x1d50010))
|
||||
#define TCNTO0 (S3C_REG(0x1d50014))
|
||||
|
||||
#define TCNTB1 (S3C_REG(0x1d50018))
|
||||
#define TCMPB1 (S3C_REG(0x1d5001c))
|
||||
#define TCNTO1 (S3C_REG(0x1d50020))
|
||||
|
||||
#define TCNTB2 (S3C_REG(0x1d50024))
|
||||
#define TCMPB2 (S3C_REG(0x1d50028))
|
||||
#define TCNTO2 (S3C_REG(0x1d5002c))
|
||||
|
||||
#define TCNTB3 (S3C_REG(0x1d50030))
|
||||
#define TCMPB3 (S3C_REG(0x1d50034))
|
||||
#define TCNTO3 (S3C_REG(0x1d50038))
|
||||
|
||||
#define TCNTB4 (S3C_REG(0x1d5003c))
|
||||
#define TCMPB4 (S3C_REG(0x1d50040))
|
||||
#define TCNTO4 (S3C_REG(0x1d50044))
|
||||
|
||||
#define TCNTB5 (S3C_REG(0x1d50048))
|
||||
#define TCNTO5 (S3C_REG(0x1d5004c))
|
||||
|
||||
/* IIC */
|
||||
#define IICCON (S3C_REG(0x1d60000))
|
||||
#define IICSTAT (S3C_REG(0x1d60004))
|
||||
#define IICADD (S3C_REG(0x1d60008))
|
||||
#define IICDS (S3C_REG(0x1d6000c))
|
||||
|
||||
/* RTC */
|
||||
#define RTCCON (S3C_REGB(0x1d70040)
|
||||
#define RTCALM (S3C_REGB(0x1d70050)
|
||||
#define ALMSEC (S3C_REGB(0x1d70054)
|
||||
#define ALMMIN (S3C_REGB(0x1d70058)
|
||||
#define ALMHOUR (S3C_REGB(0x1d7005c)
|
||||
#define ALMDAY (S3C_REGB(0x1d70060)
|
||||
#define ALMMON (S3C_REGB(0x1d70064)
|
||||
#define ALMYEAR (S3C_REGB(0x1d70068)
|
||||
#define RTCRST (S3C_REGB(0x1d7006c)
|
||||
#define BCDSEC (S3C_REGB(0x1d70070)
|
||||
#define BCDMIN (S3C_REGB(0x1d70074)
|
||||
#define BCDHOUR (S3C_REGB(0x1d70078)
|
||||
#define BCDDAY (S3C_REGB(0x1d7007c)
|
||||
#define BCDDATE (S3C_REGB(0x1d70080)
|
||||
#define BCDMON (S3C_REGB(0x1d70084)
|
||||
#define BCDYEAR (S3C_REGB(0x1d70088)
|
||||
#define TICINT (S3C_REGB(0x1d7008c)
|
||||
|
||||
/* Clock & Power management */
|
||||
#define PLLCON (S3C_REG(0x1d80000))
|
||||
#define CLKCON (S3C_REG(0x1d80004))
|
||||
#define CLKSLOW (S3C_REG(0x1d80008))
|
||||
#define LOCKTIME (S3C_REG(0x1d8000c))
|
||||
|
||||
/* Interrupt */
|
||||
#define INTCON (S3C_REG(0x1e00000))
|
||||
#define INTPND (S3C_REG(0x1e00004))
|
||||
#define INTMOD (S3C_REG(0x1e00008))
|
||||
#define INTMSK (S3C_REG(0x1e0000c))
|
||||
|
||||
#define I_PSLV (S3C_REG(0x1e00010))
|
||||
#define I_PMST (S3C_REG(0x1e00014))
|
||||
#define I_CSLV (S3C_REG(0x1e00018))
|
||||
#define I_CMST (S3C_REG(0x1e0001c))
|
||||
#define I_ISPR (S3C_REG(0x1e00020))
|
||||
#define I_ISPC (S3C_REG(0x1e00024))
|
||||
|
||||
#define F_ISPR (S3C_REG(0x1e00038))
|
||||
#define F_ISPC (S3C_REG(0x1e0003c))
|
||||
|
||||
/********************************/
|
||||
/* LCD Controller Registers */
|
||||
/********************************/
|
||||
#define LCDCON1 (S3C_REG(0x300000))
|
||||
#define LCDCON2 (S3C_REG(0x300004))
|
||||
#define LCDSADDR1 (S3C_REG(0x300008))
|
||||
#define LCDSADDR2 (S3C_REG(0x30000c))
|
||||
#define LCDSADDR3 (S3C_REG(0x300010))
|
||||
#define REDLUT (S3C_REG(0x300014))
|
||||
#define GREENLUT (S3C_REG(0x300018))
|
||||
#define BLUELUT (S3C_REG(0x30001c))
|
||||
#define DP1_2 (S3C_REG(0x300020))
|
||||
#define DP4_7 (S3C_REG(0x300024))
|
||||
#define DP3_5 (S3C_REG(0x300028))
|
||||
#define DP2_3 (S3C_REG(0x30002c))
|
||||
#define DP5_7 (S3C_REG(0x300030))
|
||||
#define DP3_4 (S3C_REG(0x300034))
|
||||
#define DP4_5 (S3C_REG(0x300038))
|
||||
#define DP6_7 (S3C_REG(0x30003c))
|
||||
#define LCDCON3 (S3C_REG(0x300040))
|
||||
#define DITHMODE (S3C_REG(0x300044))
|
||||
|
||||
/* ZDMA0 */
|
||||
#define ZDCON0 (S3C_REG(0x1e80000))
|
||||
#define ZDISRC0 (S3C_REG(0x1e80004))
|
||||
#define ZDIDES0 (S3C_REG(0x1e80008))
|
||||
#define ZDICNT0 (S3C_REG(0x1e8000c))
|
||||
#define ZDCSRC0 (S3C_REG(0x1e80010))
|
||||
#define ZDCDES0 (S3C_REG(0x1e80014))
|
||||
#define ZDCCNT0 (S3C_REG(0x1e80018))
|
||||
|
||||
/* ZDMA1 */
|
||||
#define ZDCON1 (S3C_REG(0x1e80020))
|
||||
#define ZDISRC1 (S3C_REG(0x1e80024))
|
||||
#define ZDIDES1 (S3C_REG(0x1e80028))
|
||||
#define ZDICNT1 (S3C_REG(0x1e8002c))
|
||||
#define ZDCSRC1 (S3C_REG(0x1e80030))
|
||||
#define ZDCDES1 (S3C_REG(0x1e80034))
|
||||
#define ZDCCNT1 (S3C_REG(0x1e80038))
|
||||
|
||||
/* BDMA0 */
|
||||
#define BDCON0 (S3C_REG(0x1f80000))
|
||||
#define BDISRC0 (S3C_REG(0x1f80004))
|
||||
#define BDIDES0 (S3C_REG(0x1f80008))
|
||||
#define BDICNT0 (S3C_REG(0x1f8000c))
|
||||
#define BDCSRC0 (S3C_REG(0x1f80010))
|
||||
#define BDCDES0 (S3C_REG(0x1f80014))
|
||||
#define BDCCNT0 (S3C_REG(0x1f80018))
|
||||
|
||||
/* BDMA1 */
|
||||
#define BDCON1 (S3C_REG(0x1f80020))
|
||||
#define BDISRC1 (S3C_REG(0x1f80024))
|
||||
#define BDIDES1 (S3C_REG(0x1f80028))
|
||||
#define BDICNT1 (S3C_REG(0x1f8002c))
|
||||
#define BDCSRC1 (S3C_REG(0x1f80030))
|
||||
#define BDCDES1 (S3C_REG(0x1f80034))
|
||||
#define BDCCNT1 (S3C_REG(0x1f80038))
|
||||
|
||||
/*****************************/
|
||||
/* CPU Mode */
|
||||
/*****************************/
|
||||
#define USERMODE 0x10 /* User Mode(USR) */
|
||||
#define FIQMODE 0x11 /* Fast Interrupt Mode (FIQ) */
|
||||
#define IRQMODE 0x12 /* Interrupt Mode (IRQ) */
|
||||
#define SVCMODE 0x13 /* Supervisor Mode (SVC) */
|
||||
#define ABORTMODE 0x17 /* Abort Mode(ABT) */
|
||||
#define UNDEFMODE 0x1b /* Undefine Mode(UDF) */
|
||||
#define MODEMASK 0x1f /* Processor Mode Mask */
|
||||
#define NOINT 0xc0
|
||||
|
||||
/*****************************/
|
||||
/* INT Define */
|
||||
/*****************************/
|
||||
#define INT_ADC 0x00
|
||||
#define INT_RTC 0x01
|
||||
#define INT_UTXD1 0x02
|
||||
#define INT_UTXD0 0x03
|
||||
#define INT_SIO 0x04
|
||||
#define INT_IIC 0x05
|
||||
#define INT_URXD1 0x06
|
||||
#define INT_URXD0 0x07
|
||||
#define INT_TIMER5 0x08
|
||||
#define INT_TIMER4 0x09
|
||||
#define INT_TIMER3 0x0A
|
||||
#define INT_TIMER2 0x0B
|
||||
#define INT_TIMER1 0x0C
|
||||
#define INT_TIMER0 0x0D
|
||||
#define INT_UERR01 0x0E
|
||||
#define INT_WDT 0x1F
|
||||
#define INT_BDMA1 0x10
|
||||
#define INT_BDMA0 0x11
|
||||
#define INT_ZDMA1 0x12
|
||||
#define INT_ZDMA0 0x13
|
||||
#define INT_TICK 0x14
|
||||
#define INT_EINT4567 0x15
|
||||
#define INT_EINT3 0x16
|
||||
#define INT_EINT2 0x17
|
||||
#define INT_EINT1 0x18
|
||||
#define INT_EINT0 0x19
|
||||
|
||||
#define INT_GLOBAL 26
|
||||
|
||||
struct rt_hw_register
|
||||
{
|
||||
unsigned long r0;
|
||||
unsigned long r1;
|
||||
unsigned long r2;
|
||||
unsigned long r3;
|
||||
unsigned long r4;
|
||||
unsigned long r5;
|
||||
unsigned long r6;
|
||||
unsigned long r7;
|
||||
unsigned long r8;
|
||||
unsigned long r9;
|
||||
unsigned long r10;
|
||||
unsigned long fp;
|
||||
unsigned long ip;
|
||||
unsigned long sp;
|
||||
unsigned long lr;
|
||||
unsigned long pc;
|
||||
unsigned long cpsr;
|
||||
unsigned long ORIG_r0;
|
||||
};
|
||||
|
||||
/*@}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
114
libcpu/arm/s3c44b0/serial.c
Normal file
114
libcpu/arm/s3c44b0/serial.c
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-09-06 XuXinming first version
|
||||
* 2006-09-20 Bernard clean code according code style
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
|
||||
#include "s3c44b0.h"
|
||||
|
||||
void rt_serial_init(void);
|
||||
void rt_console_puts(const char* str);
|
||||
void rt_serial_putc(const char c);
|
||||
|
||||
#define USTAT_RCV_READY 0x01 /* receive data ready */
|
||||
#define USTAT_TXB_EMPTY 0x02 /* tx buffer empty */
|
||||
|
||||
rt_inline void serial_flush_input(void)
|
||||
{
|
||||
volatile unsigned int tmp;
|
||||
|
||||
/* keep on reading as long as the receiver is not empty */
|
||||
while(UTRSTAT0 & USTAT_RCV_READY) tmp = URXH0;
|
||||
}
|
||||
|
||||
rt_inline void serial_flush_output(void)
|
||||
{
|
||||
/* wait until the transmitter is no longer busy */
|
||||
while(!(UTRSTAT0 & USTAT_TXB_EMPTY)) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* @addtogroup S3C44B0
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
* This function is used to display a string on console, normally, it's
|
||||
* invoked by rt_kprintf
|
||||
*
|
||||
* @param str the displayed string
|
||||
*/
|
||||
void rt_console_puts(const char* str)
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
rt_serial_putc (*str++);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function initializes serial
|
||||
*/
|
||||
void rt_serial_init()
|
||||
{
|
||||
rt_uint32_t divisor = 0;
|
||||
|
||||
divisor = 0x20;
|
||||
|
||||
serial_flush_output();
|
||||
serial_flush_input();
|
||||
|
||||
/* UART interrupt off */
|
||||
UCON0 = 0;
|
||||
/* FIFO disable */
|
||||
UFCON0 =0x0;
|
||||
UMCON0 =0x0;
|
||||
/* set baudrate */
|
||||
UBRDIV0 = divisor;
|
||||
|
||||
/* word length=8bit, stop bit = 1, no parity, use external clock */
|
||||
ULCON0 = 0x03|0x00|0x00;
|
||||
|
||||
UCON0 = 0x5;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function read a character from serial without interrupt enable mode
|
||||
*
|
||||
* @return the read char
|
||||
*/
|
||||
char rt_serial_getc()
|
||||
{
|
||||
while ((UTRSTAT0 & USTAT_RCV_READY) == 0);
|
||||
|
||||
return URXH0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will write a character to serial without interrupt enable mode
|
||||
*
|
||||
* @param c the char to write
|
||||
*/
|
||||
void rt_serial_putc(const char c)
|
||||
{
|
||||
/*
|
||||
to be polite with serial console add a line feed
|
||||
to the carriage return character
|
||||
*/
|
||||
if (c=='\n')rt_serial_putc('\r');
|
||||
|
||||
/* wait for room in the transmit FIFO */
|
||||
while(!(UTRSTAT0 & USTAT_TXB_EMPTY));
|
||||
|
||||
UTXH0 = (rt_uint8_t)c;
|
||||
}
|
||||
|
||||
/*@}*/
|
58
libcpu/arm/s3c44b0/stack.c
Normal file
58
libcpu/arm/s3c44b0/stack.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-09-06 XuXinming first version
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include "s3c44b0.h"
|
||||
|
||||
/**
|
||||
* @addtogroup S3C44B0
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
*(--stk) = SVCMODE; /* cpsr */
|
||||
*(--stk) = SVCMODE; /* spsr */
|
||||
|
||||
/* return task's current stack address */
|
||||
return (rt_uint8_t *)stk;
|
||||
}
|
||||
|
||||
/*@}*/
|
253
libcpu/arm/s3c44b0/start_gcc.S
Normal file
253
libcpu/arm/s3c44b0/start_gcc.S
Normal file
@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-09-06 XuXinming first version
|
||||
* 2006-09-20 Bernard clean the code
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup S3C44B0
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
.section .init, "ax"
|
||||
.code 32
|
||||
.globl _start
|
||||
_start:
|
||||
b 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_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
|
||||
|
||||
.text
|
||||
.code 32
|
||||
|
||||
/*
|
||||
* rtthread kernel start and end
|
||||
* which are defined in linker script
|
||||
*/
|
||||
.globl _rtthread_start
|
||||
_rtthread_start:.word _start
|
||||
.globl _rtthread_end
|
||||
_rtthread_end: .word _end
|
||||
|
||||
/*
|
||||
* rtthread bss start and end
|
||||
* which are defined in linker script
|
||||
*/
|
||||
.globl _bss_start
|
||||
_bss_start: .word __bss_start
|
||||
.globl _bss_end
|
||||
_bss_end: .word __bss_end
|
||||
|
||||
#if defined(__FLASH_BUILD__)
|
||||
/*
|
||||
* TEXT_BASE,
|
||||
* which is defined in macro of make
|
||||
*/
|
||||
_TEXT_BASE: .word TEXT_BASE
|
||||
#endif
|
||||
|
||||
.equ WTCON, 0x1d30000
|
||||
.equ INTCON, 0x1e00000
|
||||
.equ INTMSK, 0x1e0000c
|
||||
|
||||
/* the system entry */
|
||||
reset:
|
||||
/* enter svc mode */
|
||||
msr cpsr_c, #SVCMODE|NOINT
|
||||
|
||||
/*watch dog disable */
|
||||
ldr r0,=WTCON
|
||||
ldr r1,=0x0
|
||||
str r1,[r0]
|
||||
|
||||
/* all interrupt disable */
|
||||
ldr r0,=INTMSK
|
||||
ldr r1,=0x07ffffff
|
||||
str r1,[r0]
|
||||
|
||||
ldr r1, =INTCON
|
||||
ldr r0, =0x05
|
||||
str r0, [r1]
|
||||
|
||||
#if defined(__FLASH_BUILD__)
|
||||
/* init lowlevel */
|
||||
bl lowlevel_init
|
||||
#endif
|
||||
|
||||
/* setup stack */
|
||||
bl stack_setup
|
||||
|
||||
#if defined(__FLASH_BUILD__)
|
||||
mov r0, #0x0 /* r0 <- flash base address */
|
||||
ldr r1, _TEXT_BASE /* r1 <- the taget address */
|
||||
|
||||
ldr r2, _rtthread_start
|
||||
ldr r3, _bss_start
|
||||
sub r2, r3, r2 /* r2 <- size of rtthread kernel */
|
||||
add r2, r0, r2 /* r2 <- source end address */
|
||||
|
||||
copy_loop:
|
||||
ldmia r0!, {r3-r10} /* copy from source address [r0] */
|
||||
stmia r1!, {r3-r10} /* copy to target address [r1] */
|
||||
cmp r0, r2 /* until source end address [r2] */
|
||||
ble copy_loop
|
||||
#endif
|
||||
|
||||
/* start RT-Thread Kernel */
|
||||
ldr pc, _rtthread_startup
|
||||
|
||||
_rtthread_startup: .word rtthread_startup
|
||||
|
||||
.equ USERMODE, 0x10
|
||||
.equ FIQMODE, 0x11
|
||||
.equ IRQMODE, 0x12
|
||||
.equ SVCMODE, 0x13
|
||||
.equ ABORTMODE, 0x17
|
||||
.equ UNDEFMODE, 0x1b
|
||||
.equ MODEMASK, 0x1f
|
||||
.equ NOINT, 0xc0
|
||||
|
||||
/* exception handlers */
|
||||
vector_undef: bl rt_hw_trap_udef
|
||||
vector_swi: bl rt_hw_trap_swi
|
||||
vector_pabt: bl rt_hw_trap_pabt
|
||||
vector_dabt: bl rt_hw_trap_dabt
|
||||
vector_resv: bl rt_hw_trap_resv
|
||||
|
||||
.globl rt_interrupt_enter
|
||||
.globl rt_interrupt_leave
|
||||
.globl rt_thread_switch_interrupt_flag
|
||||
.globl rt_interrupt_from_thread
|
||||
.globl rt_interrupt_to_thread
|
||||
vector_irq:
|
||||
stmfd sp!, {r0-r12,lr}
|
||||
bl led_off
|
||||
bl rt_interrupt_enter
|
||||
bl rt_hw_trap_irq
|
||||
bl rt_interrupt_leave
|
||||
|
||||
/* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */
|
||||
ldr r0, =rt_thread_switch_interrupt_flag
|
||||
ldr r1, [r0]
|
||||
cmp r1, #1
|
||||
beq _interrupt_thread_switch
|
||||
|
||||
ldmfd sp!, {r0-r12,lr}
|
||||
subs pc, lr, #4
|
||||
|
||||
.align 5
|
||||
vector_fiq:
|
||||
stmfd sp!,{r0-r7,lr}
|
||||
bl rt_hw_trap_fiq
|
||||
ldmfd sp!,{r0-r7,lr}
|
||||
subs pc,lr,#4
|
||||
|
||||
_interrupt_thread_switch:
|
||||
mov r1, #0 @ clear rt_thread_switch_interrupt_flag
|
||||
str r1, [r0]
|
||||
|
||||
ldmfd sp!, {r0-r12,lr} @ reload saved registers
|
||||
stmfd sp!, {r0-r3} @ save r0-r3
|
||||
mov r1, sp
|
||||
add sp, sp, #16 @ restore sp
|
||||
sub r2, lr, #4 @ save old task's pc to r2
|
||||
|
||||
mrs r3, spsr @ disable interrupt
|
||||
orr r0, r3, #NOINT
|
||||
msr spsr_c, r0
|
||||
|
||||
ldr r0, =.+8 @ switch to interrupted task's stack
|
||||
movs pc, r0
|
||||
|
||||
stmfd sp!, {r2} @ push old task's pc
|
||||
stmfd sp!, {r4-r12,lr} @ push old task's lr,r12-r4
|
||||
mov r4, r1 @ Special optimised code below
|
||||
mov r5, r3
|
||||
ldmfd r4!, {r0-r3}
|
||||
stmfd sp!, {r0-r3} @ push old task's r3-r0
|
||||
stmfd sp!, {r5} @ push old task's psr
|
||||
mrs r4, spsr
|
||||
stmfd sp!, {r4} @ push old task's spsr
|
||||
|
||||
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
|
||||
|
||||
ldmfd sp!, {r4} @ pop new task's spsr
|
||||
msr SPSR_cxsf, r4
|
||||
ldmfd sp!, {r4} @ pop new task's psr
|
||||
msr CPSR_cxsf, r4
|
||||
|
||||
ldmfd sp!, {r0-r12,lr,pc} @ pop new task's r0-r12,lr & pc
|
||||
|
||||
/* each mode stack memory */
|
||||
UNDSTACK_START: .word _undefined_stack_start + 128
|
||||
ABTSTACK_START: .word _abort_stack_start + 128
|
||||
FIQSTACK_START: .word _fiq_stack_start + 1024
|
||||
IRQSTACK_START: .word _irq_stack_start + 1024
|
||||
SVCSTACK_START: .word _svc_stack_start + 4096
|
||||
|
||||
stack_setup:
|
||||
/* undefined instruction mode */
|
||||
msr cpsr_c, #UNDEFMODE|NOINT
|
||||
ldr sp, UNDSTACK_START
|
||||
|
||||
/* abort mode */
|
||||
msr cpsr_c, #ABORTMODE|NOINT
|
||||
ldr sp, ABTSTACK_START
|
||||
|
||||
/* FIQ mode */
|
||||
msr cpsr_c, #FIQMODE|NOINT
|
||||
ldr sp, FIQSTACK_START
|
||||
|
||||
/* IRQ mode */
|
||||
msr cpsr_c, #IRQMODE|NOINT
|
||||
ldr sp, IRQSTACK_START
|
||||
|
||||
/* supervisor mode */
|
||||
msr cpsr_c, #SVCMODE|NOINT
|
||||
ldr sp, SVCSTACK_START
|
||||
|
||||
mov pc,lr @ The LR register may be not valid for the mode changes.
|
||||
|
||||
.globl led_on
|
||||
led_on:
|
||||
ldr r1, =0x1d20014 @ r1<-PDATC
|
||||
ldr r0, [r1] @ r0<-[r1]
|
||||
orr r0, r0, #0x0e @ r0=r0 or 0x0e
|
||||
str r0, [r1] @ r0->[r1]
|
||||
mov pc, lr
|
||||
|
||||
.globl led_off
|
||||
led_off:
|
||||
ldr r1, =0x1d20010 @ r1<-PCONC
|
||||
ldr r0, =0x5f555555 @ r0<-0x5f555555
|
||||
str r0, [r1] @ r0->[r1]
|
||||
|
||||
ldr r1, =0x1d20014 @ r1<-PDATC
|
||||
ldr r0, =0x0 @ r0<-00
|
||||
str r0, [r1] @ r0->[r1]
|
||||
|
||||
mov pc, lr
|
1072
libcpu/arm/s3c44b0/start_rvds.S
Normal file
1072
libcpu/arm/s3c44b0/start_rvds.S
Normal file
File diff suppressed because it is too large
Load Diff
177
libcpu/arm/s3c44b0/trap.c
Normal file
177
libcpu/arm/s3c44b0/trap.c
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-09-06 XuXinming first version
|
||||
* 2006-09-15 Bernard modify rt_hw_trap_irq for more effective
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
|
||||
#include "s3c44b0.h"
|
||||
|
||||
extern unsigned char interrupt_bank0[256];
|
||||
extern unsigned char interrupt_bank1[256];
|
||||
extern unsigned char interrupt_bank2[256];
|
||||
extern unsigned char interrupt_bank3[256];
|
||||
|
||||
extern struct rt_thread *rt_current_thread;
|
||||
|
||||
/**
|
||||
* @addtogroup S3C44B0
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("undefined instruction\n");
|
||||
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)
|
||||
{
|
||||
rt_kprintf("software interrupt\n");
|
||||
rt_hw_show_register(regs);
|
||||
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)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("prefetch abort\n");
|
||||
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)
|
||||
{
|
||||
rt_hw_show_register(regs);
|
||||
|
||||
rt_kprintf("data abort\n");
|
||||
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)
|
||||
{
|
||||
rt_kprintf("not used\n");
|
||||
rt_hw_show_register(regs);
|
||||
rt_hw_cpu_shutdown();
|
||||
}
|
||||
|
||||
extern rt_isr_handler_t isr_table[];
|
||||
void rt_hw_trap_irq()
|
||||
{
|
||||
register unsigned long ispr, intstat;
|
||||
register rt_isr_handler_t isr_func;
|
||||
|
||||
#ifdef BSP_INT_DEBUG
|
||||
rt_kprintf("irq coming, ");
|
||||
#endif
|
||||
intstat = I_ISPR & 0x7ffffff;
|
||||
#ifdef BSP_INT_DEBUG
|
||||
rt_kprintf("I_ISPR: %d\n", intstat);
|
||||
#endif
|
||||
|
||||
ispr = intstat;
|
||||
|
||||
/* to find interrupt */
|
||||
if ( intstat & 0xff ) /* lowest 8bits */
|
||||
{
|
||||
intstat = interrupt_bank0[intstat & 0xff];
|
||||
isr_func = (rt_isr_handler_t)isr_table[ intstat ];
|
||||
}
|
||||
else if ( intstat & 0xff00 ) /* low 8bits */
|
||||
{
|
||||
intstat = interrupt_bank1[(intstat & 0xff00) >> 8];
|
||||
isr_func = (rt_isr_handler_t)isr_table[ intstat ];
|
||||
}
|
||||
else if ( intstat & 0xff0000 ) /* high 8bits */
|
||||
{
|
||||
intstat = interrupt_bank2[(intstat & 0xff0000) >> 16];
|
||||
isr_func = (rt_isr_handler_t)isr_table[ intstat ];
|
||||
}
|
||||
else if ( intstat & 0xff000000 ) /* highest 8bits */
|
||||
{
|
||||
intstat = interrupt_bank3[(intstat & 0xff000000) >> 24];
|
||||
isr_func = (rt_isr_handler_t)isr_table[ intstat ];
|
||||
}
|
||||
else return;
|
||||
|
||||
#ifdef BSP_INT_DEBUG
|
||||
rt_kprintf("irq: %d happen\n", intstat);
|
||||
#endif
|
||||
|
||||
/* turn to interrupt service routine */
|
||||
isr_func(intstat);
|
||||
|
||||
I_ISPC = ispr; /* clear interrupt */
|
||||
}
|
||||
|
||||
void rt_hw_trap_fiq()
|
||||
{
|
||||
rt_kprintf("fast interrupt request\n");
|
||||
}
|
||||
|
||||
/*@}*/
|
Reference in New Issue
Block a user