RT-Thread_v4.1.1

This commit is contained in:
2024-10-29 17:12:18 +08:00
parent 78a3c39ba3
commit 0924efffd0
1809 changed files with 645542 additions and 0 deletions

View 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')

View 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

View 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
View 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);
}
/*@}*/

View 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;
}
}
/*@}*/

View 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
View 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;
}
/*@}*/

View 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;
}
/*@}*/

View 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

File diff suppressed because it is too large Load Diff

177
libcpu/arm/s3c44b0/trap.c Normal file
View 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");
}
/*@}*/