diff options
Diffstat (limited to 'libcpu')
| -rw-r--r-- | libcpu/sparc-v8/SConscript | 16 | ||||
| -rw-r--r-- | libcpu/sparc-v8/bm3803/SConscript | 17 | ||||
| -rw-r--r-- | libcpu/sparc-v8/bm3803/bm3803.h | 99 | ||||
| -rw-r--r-- | libcpu/sparc-v8/bm3803/context_gcc.S | 83 | ||||
| -rw-r--r-- | libcpu/sparc-v8/bm3803/interrupt.c | 90 | ||||
| -rw-r--r-- | libcpu/sparc-v8/bm3803/interrupt.h | 20 | ||||
| -rw-r--r-- | libcpu/sparc-v8/bm3803/stack.c | 63 | ||||
| -rw-r--r-- | libcpu/sparc-v8/bm3803/start_gcc.S | 664 | ||||
| -rw-r--r-- | libcpu/sparc-v8/bm3803/trap.c | 28 | ||||
| -rw-r--r-- | libcpu/sparc-v8/bm3803/vector_gcc.S | 168 | ||||
| -rw-r--r-- | libcpu/sparc-v8/common/SConscript | 23 |
11 files changed, 1271 insertions, 0 deletions
diff --git a/libcpu/sparc-v8/SConscript b/libcpu/sparc-v8/SConscript new file mode 100644 index 0000000000..f6ea13fb91 --- /dev/null +++ b/libcpu/sparc-v8/SConscript @@ -0,0 +1,16 @@ +# RT-Thread building script for bridge + +import os +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() + +# add common code files +group = SConscript(os.path.join('common', 'SConscript')) + +# cpu porting code files +group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript')) + +Return('group') diff --git a/libcpu/sparc-v8/bm3803/SConscript b/libcpu/sparc-v8/bm3803/SConscript new file mode 100644 index 0000000000..1e96ff5837 --- /dev/null +++ b/libcpu/sparc-v8/bm3803/SConscript @@ -0,0 +1,17 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/sparc-v8/bm3803/bm3803.h b/libcpu/sparc-v8/bm3803/bm3803.h new file mode 100644 index 0000000000..a90663f199 --- /dev/null +++ b/libcpu/sparc-v8/bm3803/bm3803.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ +#ifndef __BM3803_H__ +#define __BM3803_H__ + +struct lregs +{ + /* address = 0x80000000 */ + unsigned int memcfg1; /* 0x00 */ + unsigned int memcfg2; + unsigned int memcfg3; + unsigned int failaddr; + + unsigned int memstatus; /* 0x10 */ + unsigned int cachectrl; + unsigned int powerdown; + unsigned int writeprot1; + + unsigned int writeprot2; /* 0x20 */ + unsigned int pcr; + unsigned int dummy2; + unsigned int dummy3; + + unsigned int dummy4; /* 0x30 */ + unsigned int dummy5; + unsigned int dummy6; + unsigned int dummy7; + + unsigned int timercnt1; /* 0x40 */ + unsigned int timerload1; + unsigned int timerctrl1; + unsigned int wdog; + + unsigned int timercnt2; /* 0x50 */ + unsigned int timerload2; + unsigned int timerctrl2; + unsigned int dummy8; + + unsigned int scalercnt; /* 0x60 */ + unsigned int scalerload; + unsigned int dummy9; + unsigned int dummy10; + + unsigned int uartdata1; /* 0x70 */ + unsigned int uartstatus1; + unsigned int uartctrl1; + unsigned int uartscaler1; + + unsigned int uartdata2; /* 0x80 */ + unsigned int uartstatus2; + unsigned int uartctrl2; + unsigned int uartscaler2; + + unsigned int irqmask; /* 0x90 */ + unsigned int irqpend; + unsigned int irqforce; + unsigned int irqclear; + + unsigned int piodata; /* 0xA0 */ + unsigned int piodir; + unsigned int pioirq; + unsigned int dummy11; + + unsigned int imask2; /* 0xB0 */ + unsigned int ipend2; + unsigned int istat2; + unsigned int dummy12; + + unsigned int dummy13; /* 0xC0 */ + unsigned int dcomstatus; + unsigned int dcomctrl; + unsigned int dcomscaler; + + unsigned int dummy14; /* 0xD0 */ + unsigned int dummy15; + unsigned int dummy16; + unsigned int dummy17; + + unsigned int uartdata3; /* 0xE0 */ + unsigned int uartstatus3; + unsigned int uartctrl3; + unsigned int uartscaler3; +}; + +#define PREGS 0x80000000 + +#define UART1_BASE (PREGS + 0x70) + +#define TIMER2_TT 0x19 +#define UART1_TT 0x13 + +#endif diff --git a/libcpu/sparc-v8/bm3803/context_gcc.S b/libcpu/sparc-v8/bm3803/context_gcc.S new file mode 100644 index 0000000000..c0344a81d5 --- /dev/null +++ b/libcpu/sparc-v8/bm3803/context_gcc.S @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ + +#define SPARC_PSR_PIL_MASK 0x00000F00 +#define SPARC_PSR_ET_MASK 0x00000020 + +/* + * rt_base_t rt_hw_interrupt_disable(); + */ +.globl rt_hw_interrupt_disable +rt_hw_interrupt_disable: + mov %psr, %o0 + or %o0, SPARC_PSR_PIL_MASK, %o1 + mov %o1, %psr + nop + nop + nop + retl + nop + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ +.globl rt_hw_interrupt_enable +rt_hw_interrupt_enable: + mov %o0, %psr + nop + nop + nop + retl + nop + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); + * o0 --> from + * o1 --> to + */ +.globl rt_hw_context_switch +rt_hw_context_switch: + ta 2 + retl + nop + +/* + * void rt_hw_context_switch_to(rt_uint32 to); + * o0 --> to + */ +.globl rt_hw_context_switch_to +rt_hw_context_switch_to: + mov %o0, %o1 + ta 3 + retl + nop + +/* + * 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: + set rt_thread_switch_interrupt_flag, %o2 + ld [%o2], %o3 + cmp %o3, 1 + be _reswitch + nop + mov 1, %o3 + st %o3, [%o2] + set rt_interrupt_from_thread, %o2 + st %o0, [%o2] +_reswitch: + set rt_interrupt_to_thread, %o2 + st %o1, [%o2] + retl + nop diff --git a/libcpu/sparc-v8/bm3803/interrupt.c b/libcpu/sparc-v8/bm3803/interrupt.c new file mode 100644 index 0000000000..e3f9b5b3de --- /dev/null +++ b/libcpu/sparc-v8/bm3803/interrupt.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ + +#include <rthw.h> +#include <rtthread.h> + +#include "bm3803.h" +#include "interrupt.h" + +#define MAX_HANDLERS 256 + +extern volatile rt_uint8_t rt_interrupt_nest; +struct rt_irq_desc isr_table[MAX_HANDLERS]; +rt_uint32_t rt_interrupt_from_thread; +rt_uint32_t rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; + +/** + * This function will initialize hardware interrupt + */ +void rt_hw_interrupt_init(void) +{ + /* init exceptions table */ + rt_memset(isr_table, 0x00, sizeof(isr_table)); + + /* 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) +{ + if (vector > 0x1F || vector < 0x11) + return; + volatile struct lregs *regs = (struct lregs*)PREGS; + regs->irqmask &= ~(1 << (vector - 0x10)); +} + +/** + * This function will un-mask a interrupt. + * @param vector the interrupt number + */ +void rt_hw_interrupt_umask(int vector) +{ + if (vector > 0x1F || vector < 0x11) + return; + volatile struct lregs *regs = (struct lregs*)PREGS; + regs->irqmask |= 1 << (vector - 0x10); +} + +/** + * 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 + */ +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, const char *name) +{ + rt_isr_handler_t old_handler = RT_NULL; + + if(vector < MAX_HANDLERS || vector >= 0) + { + old_handler = isr_table[vector].handler; + + if (handler != RT_NULL) + { +#ifdef RT_USING_INTERRUPT_INFO + rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX); +#endif /* RT_USING_INTERRUPT_INFO */ + isr_table[vector].handler = handler; + isr_table[vector].param = param; + } + } + + return old_handler; +} diff --git a/libcpu/sparc-v8/bm3803/interrupt.h b/libcpu/sparc-v8/bm3803/interrupt.h new file mode 100644 index 0000000000..7632195e70 --- /dev/null +++ b/libcpu/sparc-v8/bm3803/interrupt.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ + +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +void rt_hw_interrupt_control(int vector, int priority, int route); +int rt_hw_interrupt_get_active(int fiq_irq); +void rt_hw_interrupt_ack(int fiq_irq); +void rt_hw_interrupt_trigger(int vector); +void rt_hw_interrupt_clear(int vector); + +#endif diff --git a/libcpu/sparc-v8/bm3803/stack.c b/libcpu/sparc-v8/bm3803/stack.c new file mode 100644 index 0000000000..3563692cdd --- /dev/null +++ b/libcpu/sparc-v8/bm3803/stack.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ +#include <rtthread.h> + +/** + * 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; + int window_index; + int register_index; + + 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 -= 24; + stk -= 8; + + for (register_index = 0; register_index != 8; register_index++) + stk[register_index] = 0xdeadbeef; + + for (window_index = 0; window_index != 8; window_index++) + { + stk -= 16; + for (register_index = 0; register_index != 16; register_index++) + stk[register_index] = 0xdeadbeef; + if (window_index == 0) + { + stk[8] = (rt_uint32_t)parameter; + stk[15] = (rt_uint32_t)texit - 8; + } + } + + stk -= 34; + for (register_index = 0; register_index != 34; register_index++) + stk[register_index] = 0; + + stk -= 4; + stk[0] = (rt_uint32_t)tentry; //pc + stk[1] = (rt_uint32_t)tentry + 4; //npc + stk[2] = 0x10C7; //psr + stk[3] = 0x2; //wim + + /* return task's current stack address */ + return (rt_uint8_t *)stk; +} diff --git a/libcpu/sparc-v8/bm3803/start_gcc.S b/libcpu/sparc-v8/bm3803/start_gcc.S new file mode 100644 index 0000000000..0f87aa17db --- /dev/null +++ b/libcpu/sparc-v8/bm3803/start_gcc.S @@ -0,0 +1,664 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ + +#define PSR_INIT 0x10C0 +#define PREGS 0x80000000 +#define IMASK 0x90 +#define ICLEAR 0x9c +#define NWINDOWS 8 +#define CPU_INTERRUPT_FRAME_SIZE (0x60 + 0x50 + 34 * 4) +#define SPARC_PSR_PIL_MASK 0x00000F00 +#define SPARC_PSR_ET_MASK 0x00000020 +#define SPARC_PSR_CWP_MASK 0x07 + +.text + +.globl system_vectors +.globl _reset +.globl _context_switch + +_reset: + mov %g0, %asr16 + mov %g0, %asr17 + nop + nop + nop + + set PSR_INIT, %g1 + mov %g1, %psr + nop + nop + nop + + mov %g0, %wim + nop + nop + nop + + mov %g0, %g1 + mov %g0, %g2 + mov %g0, %g3 + mov %g0, %g4 + mov %g0, %g5 + mov %g0, %g6 + mov %g0, %g7 + + mov 0x8, %g1 +1: + mov %g0, %l0 + mov %g0, %l1 + mov %g0, %l2 + mov %g0, %l3 + mov %g0, %l4 + mov %g0, %l5 + mov %g0, %l6 + mov %g0, %l7 + mov %g0, %i0 + mov %g0, %i1 + mov %g0, %i2 + mov %g0, %i3 + mov %g0, %i4 + mov %g0, %i5 + mov %g0, %i6 + mov %g0, %i7 + subcc %g1, 1, %g1 + save + bne 1b + nop + + set 2, %g1 + mov %g1, %wim + nop + nop + nop + + sethi %hi(system_vectors), %g1 + mov %g1, %tbr + nop + nop + nop + + set PREGS, %g1 + set 0xffff, %g2 + st %g2, [%g1 + ICLEAR] + st %g0, [%g1 + IMASK] + + set 0x7C47907F, %g2 + st %g2, [%g1 + 4] + + set PSR_INIT | 0x20, %g1 + mov %g1, %psr + nop + nop + nop + + set _fsrinit, %g1 + ld [%g1], %fsr + nop + nop + nop + + set _fpdata, %g1 + ldd [%g1], %f0 + ldd [%g1], %f2 + ldd [%g1], %f4 + ldd [%g1], %f6 + ldd [%g1], %f8 + ldd [%g1], %f10 + ldd [%g1], %f12 + ldd [%g1], %f14 + ldd [%g1], %f16 + ldd [%g1], %f18 + ldd [%g1], %f20 + ldd [%g1], %f22 + ldd [%g1], %f24 + ldd [%g1], %f26 + ldd [%g1], %f28 + ldd [%g1], %f30 + + set __bss_start, %g2 + set __bss_end, %g3 + mov %g0, %g1 +bss_loop: + std %g0, [%g2] + add %g2, 8, %g2 + cmp %g2, %g3 + bleu,a bss_loop + nop + + set 0x401FFF00, %g1 + mov %g1, %sp + + /* start RT-Thread Kernel */ + call rtthread_startup + nop + +/* +l0 = psr +l1 = pc +l2 = npc +l3 = tbr +*/ +.globl _ISR_Handler +_ISR_Handler: + mov %g4, %l4 + mov %g5, %l5 + mov %wim, %g4 + srl %g4, %l0, %g5 + cmp %g5, 1 + bne dont_do_the_window + nop + srl %g4, 1, %g5 + sll %g4, NWINDOWS - 1, %g4 + or %g4, %g5, %g4 + save + mov %g4, %wim + nop + nop + nop + + std %l0, [%sp + 0x00] + std %l2, [%sp + 0x08] + std %l4, [%sp + 0x10] + std %l6, [%sp + 0x18] + + std %i0, [%sp + 0x20] + std %i2, [%sp + 0x28] + std %i4, [%sp + 0x30] + std %i6, [%sp + 0x38] + + restore + nop + +dont_do_the_window: + sub %fp, CPU_INTERRUPT_FRAME_SIZE, %sp + + std %l0, [%sp + 0x60] + st %l2, [%sp + 0x68] + st %g1, [%sp + 0x6c] + std %g2, [%sp + 0x70] + std %l4, [%sp + 0x78] + std %g6, [%sp + 0x80] + + std %i0, [%sp + 0x88] + std %i2, [%sp + 0x90] + std %i4, [%sp + 0x98] + std %i6, [%sp + 0xA0] + + mov %y, %g1 + st %g1, [%sp + 0xA8] + st %l6, [%sp + 0xAc] + + std %f0, [%sp + 0xB0 + 8 * 0x0] + std %f2, [%sp + 0xB0 + 8 * 0x1] + std %f4, [%sp + 0xB0 + 8 * 0x2] + std %f6, [%sp + 0xB0 + 8 * 0x3] + std %f8, [%sp + 0xB0 + 8 * 0x4] + std %f10, [%sp + 0xB0 + 8 * 0x5] + std %f12, [%sp + 0xB0 + 8 * 0x6] + std %f14, [%sp + 0xB0 + 8 * 0x7] + std %f16, [%sp + 0xB0 + 8 * 0x8] + std %f18, [%sp + 0xB0 + 8 * 0x9] + std %f20, [%sp + 0xB0 + 8 * 0xA] + std %f22, [%sp + 0xB0 + 8 * 0xB] + std %f24, [%sp + 0xB0 + 8 * 0xC] + std %f26, [%sp + 0xB0 + 8 * 0xD] + std %f28, [%sp + 0xB0 + 8 * 0xE] + std %f30, [%sp + 0xB0 + 8 * 0xF] + st %fsr, [%sp + 0xB0 + 8 * 0x10] + + mov %l0, %g5 + or %g5, SPARC_PSR_PIL_MASK, %g5 + wr %g5, SPARC_PSR_ET_MASK, %psr + nop + nop + nop + + call rt_interrupt_enter + nop + + and %l3, 0x0FF0, %l3 + srl %l3, 4, %o0 + mov %sp, %o1 + + call rt_hw_trap + nop + + call rt_interrupt_leave + nop + + mov %l0, %psr + nop + nop + nop + + ld [%sp + 0xA8], %l5 + mov %l5, %y + ldd [%sp + 0x60], %l0 + ld [%sp + 0x68], %l2 + + ld [%sp + 0x6c], %g1 + ldd [%sp + 0x70], %g2 + ldd [%sp + 0x78], %g4 + ldd [%sp + 0x80], %g6 + + ldd [%sp + 0x88], %i0 + ldd [%sp + 0x90], %i2 + ldd [%sp + 0x98], %i4 + ldd [%sp + 0xA0], %i6 + + ldd [%sp + 0xB0 + 8 * 0x0], %f0 + ldd [%sp + 0xB0 + 8 * 0x1], %f2 + ldd [%sp + 0xB0 + 8 * 0x2], %f4 + ldd [%sp + 0xB0 + 8 * 0x3], %f6 + ldd [%sp + 0xB0 + 8 * 0x4], %f8 + ldd [%sp + 0xB0 + 8 * 0x5], %f10 + ldd [%sp + 0xB0 + 8 * 0x6], %f12 + ldd [%sp + 0xB0 + 8 * 0x7], %f14 + ldd [%sp + 0xB0 + 8 * 0x8], %f16 + ldd [%sp + 0xB0 + 8 * 0x9], %f18 + ldd [%sp + 0xB0 + 8 * 0xA], %f20 + ldd [%sp + 0xB0 + 8 * 0xB], %f22 + ldd [%sp + 0xB0 + 8 * 0xC], %f24 + ldd [%sp + 0xB0 + 8 * 0xD], %f26 + ldd [%sp + 0xB0 + 8 * 0xE], %f28 + ldd [%sp + 0xB0 + 8 * 0xF], %f30 + ld [%sp + 0xB0 + 8 * 0x10], %fsr + nop + nop + nop + + mov %wim, %l4 + add %l0, 1, %l6 + and %l6, SPARC_PSR_CWP_MASK, %l6 + srl %l4, %l6, %l5 + cmp %l5, 1 + bne good_task_window + nop + sll %l4, 1, %l5 + srl %l4, NWINDOWS - 1, %l4 + or %l4, %l5, %l4 + mov %l4, %wim + nop + nop + nop + + restore + ldd [%sp + 0], %l0 ! Restore window from the stack + ldd [%sp + 8], %l2 + ldd [%sp + 16], %l4 + ldd [%sp + 24], %l6 + ldd [%sp + 32], %i0 + ldd [%sp + 40], %i2 + ldd [%sp + 48], %i4 + ldd [%sp + 56], %i6 + save + +good_task_window: + set rt_thread_switch_interrupt_flag, %l4 + ld [%l4], %l5 + cmp %l5, 1 + be rt_hw_context_switch_interrupt_do + nop + + mov %l0, %psr + nop + nop + nop + + jmp %l1 + rett %l2 + +rt_hw_context_switch_interrupt_do: + st %g0, [%l4] + + sub %fp, 0x20, %sp + std %g0, [%sp + 0x00] + std %g2, [%sp + 0x08] + std %g4, [%sp + 0x10] + std %g6, [%sp + 0x18] + + mov %sp, %g3 + mov %l1, %g4 + mov %l2, %g5 + mov %l0, %g6 + mov %wim, %g7 + + mov %g0, %wim + nop + nop + nop + set 0xFFFFFFF8, %g1 + and %g1, %g6, %g1 + mov %g1, %psr + nop + nop + nop + + mov %g0, %g1 +save_loop: + save + sub %g3, 0x40, %g3 + std %l0, [%g3 + 0x00] + std %l2, [%g3 + 0x08] + std %l4, [%g3 + 0x10] + std %l6, [%g3 + 0x18] + std %i0, [%g3 + 0x20] + std %i2, [%g3 + 0x28] + std %i4, [%g3 + 0x30] + std %i6, [%g3 + 0x38] + inc %g1 + cmp %g1, NWINDOWS + bne save_loop + nop + + sub %g3, 0x88, %g3 + std %f0, [%g3 + 0x00] + std %f2, [%g3 + 0x08] + std %f4, [%g3 + 0x10] + std %f6, [%g3 + 0x18] + std %f8, [%g3 + 0x20] + std %f10, [%g3 + 0x28] + std %f12, [%g3 + 0x30] + std %f14, [%g3 + 0x38] + std %f16, [%g3 + 0x40] + std %f18, [%g3 + 0x48] + std %f20, [%g3 + 0x50] + std %f22, [%g3 + 0x58] + std %f24, [%g3 + 0x60] + std %f26, [%g3 + 0x68] + std %f28, [%g3 + 0x70] + std %f30, [%g3 + 0x78] + mov %y, %g1 + st %g1, [%g3 + 0x80] + st %fsr, [%g3 + 0x84] + + sub %g3, 0x10, %g3 + std %g4, [%g3 + 0x00] + std %g6, [%g3 + 0x08] + + set rt_interrupt_from_thread, %g1 + ld [%g1], %g2 + st %g3, [%g2] + + set rt_interrupt_to_thread, %g1 + ld [%g1], %g1 + ld [%g1], %g3 + + ldd [%g3 + 0x00], %g4 + ldd [%g3 + 0x08], %g6 + add %g3, 0x10, %g3 + + ldd [%g3 + 0x00], %f0 + ldd [%g3 + 0x08], %f2 + ldd [%g3 + 0x10], %f4 + ldd [%g3 + 0x18], %f6 + ldd [%g3 + 0x20], %f8 + ldd [%g3 + 0x28], %f10 + ldd [%g3 + 0x30], %f12 + ldd [%g3 + 0x38], %f14 + ldd [%g3 + 0x40], %f16 + ldd [%g3 + 0x48], %f18 + ldd [%g3 + 0x50], %f20 + ldd [%g3 + 0x58], %f22 + ldd [%g3 + 0x60], %f24 + ldd [%g3 + 0x68], %f26 + ldd [%g3 + 0x70], %f28 + ldd [%g3 + 0x78], %f30 + ld [%g3 + 0x80], %g1 + mov %g1, %y + ld [%g3 + 0x84], %fsr + add %g3, 0x88, %g3 + + set NWINDOWS - 1, %g1 + or %g1, %g6, %g1 + mov %g1, %psr + nop + nop + nop + + mov %g0, %g1 +restore_loop: + restore + ldd [%g3 + 0x00], %l0 + ldd [%g3 + 0x08], %l2 + ldd [%g3 + 0x10], %l4 + ldd [%g3 + 0x18], %l6 + ldd [%g3 + 0x20], %i0 + ldd [%g3 + 0x28], %i2 + ldd [%g3 + 0x30], %i4 + ldd [%g3 + 0x38], %i6 + add %g3, 0x40, %g3 + inc %g1 + cmp %g1, NWINDOWS + bne restore_loop + nop + + mov %g6, %psr + nop + nop + nop + mov %g7, %wim + nop + nop + nop + + mov %g4, %l1 + mov %g5, %l2 + mov %g3, %sp + + ldd [%sp + 0x00], %g0 + ldd [%sp + 0x08], %g2 + ldd [%sp + 0x10], %g4 + ldd [%sp + 0x18], %g6 + add %sp, 0x20, %fp + jmp %l1 + rett %l2 + +/* +l0 = psr +l1 = pc +l2 = npc +l3 = tbr +*/ +_context_switch: + mov %l2, %l1 + add %l2, 4, %l2 + + mov %g4, %l4 + mov %g5, %l5 + mov %wim, %g4 + srl %g4, %l0, %g5 + cmp %g5, 1 + bne good_window + nop + srl %g4, 1, %g5 + sll %g4, NWINDOWS - 1, %g4 + or %g4, %g5, %g4 + save + mov %g4, %wim + nop + nop + nop + + std %l0, [%sp + 0x00] + std %l2, [%sp + 0x08] + std %l4, [%sp + 0x10] + std %l6, [%sp + 0x18] + + std %i0, [%sp + 0x20] + std %i2, [%sp + 0x28] + std %i4, [%sp + 0x30] + std %i6, [%sp + 0x38] + + restore + nop + +good_window: + and %l3, 0x0FF0, %l3 + srl %l3, 4, %l4 + cmp %l4, 0x82 + bne switch_to + nop + + sub %fp, 0x20, %sp + std %g0, [%sp + 0x00] + std %g2, [%sp + 0x08] + std %g4, [%sp + 0x10] + std %g6, [%sp + 0x18] + + mov %sp, %g3 + mov %l1, %g4 + mov %l2, %g5 + mov %l0, %g6 + mov %wim, %g7 + + mov %g0, %wim + nop + nop + nop + set 0xFFFFFFF8, %g1 + and %g1, %g6, %g1 + mov %g1, %psr + nop + nop + nop + + mov %g0, %g1 +save_window: + save + sub %g3, 0x40, %g3 + std %l0, [%g3 + 0x00] + std %l2, [%g3 + 0x08] + std %l4, [%g3 + 0x10] + std %l6, [%g3 + 0x18] + std %i0, [%g3 + 0x20] + std %i2, [%g3 + 0x28] + std %i4, [%g3 + 0x30] + std %i6, [%g3 + 0x38] + inc %g1 + cmp %g1, NWINDOWS + bne save_window + nop + + sub %g3, 0x88, %g3 + std %f0, [%g3 + 0x00] + std %f2, [%g3 + 0x08] + std %f4, [%g3 + 0x10] + std %f6, [%g3 + 0x18] + std %f8, [%g3 + 0x20] + std %f10, [%g3 + 0x28] + std %f12, [%g3 + 0x30] + std %f14, [%g3 + 0x38] + std %f16, [%g3 + 0x40] + std %f18, [%g3 + 0x48] + std %f20, [%g3 + 0x50] + std %f22, [%g3 + 0x58] + std %f24, [%g3 + 0x60] + std %f26, [%g3 + 0x68] + std %f28, [%g3 + 0x70] + std %f30, [%g3 + 0x78] + mov %y, %g1 + st %g1, [%g3 + 0x80] + st %fsr, [%g3 + 0x84] + + sub %g3, 0x10, %g3 + std %g4, [%g3 + 0x00] + std %g6, [%g3 + 0x08] + + mov %g6, %psr + nop + nop + nop + + st %g3, [%i0] +switch_to: + mov %g0, %wim + nop + nop + nop + ld [%i1], %g3 + + ldd [%g3 + 0x00], %g4 + ldd [%g3 + 0x08], %g6 + add %g3, 0x10, %g3 + + ldd [%g3 + 0x00], %f0 + ldd [%g3 + 0x08], %f2 + ldd [%g3 + 0x10], %f4 + ldd [%g3 + 0x18], %f6 + ldd [%g3 + 0x20], %f8 + ldd [%g3 + 0x28], %f10 + ldd [%g3 + 0x30], %f12 + ldd [%g3 + 0x38], %f14 + ldd [%g3 + 0x40], %f16 + ldd [%g3 + 0x48], %f18 + ldd [%g3 + 0x50], %f20 + ldd [%g3 + 0x58], %f22 + ldd [%g3 + 0x60], %f24 + ldd [%g3 + 0x68], %f26 + ldd [%g3 + 0x70], %f28 + ldd [%g3 + 0x78], %f30 + ld [%g3 + 0x80], %g1 + mov %g1, %y + ld [%g3 + 0x84], %fsr + add %g3, 0x88, %g3 + + set NWINDOWS - 1, %g1 + or %g1, %g6, %g1 + mov %g1, %psr + nop + nop + nop + + mov %g0, %g1 +restore_window: + restore + ldd [%g3 + 0x00], %l0 + ldd [%g3 + 0x08], %l2 + ldd [%g3 + 0x10], %l4 + ldd [%g3 + 0x18], %l6 + ldd [%g3 + 0x20], %i0 + ldd [%g3 + 0x28], %i2 + ldd [%g3 + 0x30], %i4 + ldd [%g3 + 0x38], %i6 + add %g3, 0x40, %g3 + inc %g1 + cmp %g1, NWINDOWS + bne restore_window + nop + + mov %g6, %psr + nop + nop + nop + mov %g7, %wim + nop + nop + nop + + mov %g4, %l1 + mov %g5, %l2 + mov %g3, %sp + + ldd [%sp + 0x00], %g0 + ldd [%sp + 0x08], %g2 + ldd [%sp + 0x10], %g4 + ldd [%sp + 0x18], %g6 + add %sp, 0x20, %fp + jmp %l1 + rett %l2 + +.data +.align 8 +_fpdata: + .word 0, 0 +_fsrinit: + .word 0 diff --git a/libcpu/sparc-v8/bm3803/trap.c b/libcpu/sparc-v8/bm3803/trap.c new file mode 100644 index 0000000000..05a0416dfa --- /dev/null +++ b/libcpu/sparc-v8/bm3803/trap.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ + +#include <rtthread.h> +#include <rthw.h> + +extern struct rt_irq_desc isr_table[]; + +void rt_hw_trap(int tt, unsigned int *sp) +{ + void *param; + rt_isr_handler_t isr_func; + + /* get interrupt service routine */ + isr_func = isr_table[tt].handler; + param = isr_table[tt].param; + + /* turn to interrupt service routine */ + if (isr_func != RT_NULL) + isr_func(tt, param); +} diff --git a/libcpu/sparc-v8/bm3803/vector_gcc.S b/libcpu/sparc-v8/bm3803/vector_gcc.S new file mode 100644 index 0000000000..0d243bee33 --- /dev/null +++ b/libcpu/sparc-v8/bm3803/vector_gcc.S @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-10-16 Dystopia the first version + */ + +#define TRAPL(H) mov %g0, %l0; sethi %hi(H), %l4; jmp %l4 + %lo(H); nop; +#define TRAP(H) mov %psr, %l0; sethi %hi(H), %l4; jmp %l4 + %lo(H); nop; +#define TRAP_ENTRY(H) mov %psr, %l0; sethi %hi(H), %l4; jmp %l4 + %lo(H); mov %tbr, %l3; +#define BAD_TRAP ta 0; nop; nop; nop; +#define SOFT_TRAP BAD_TRAP +#define NWINDOWS 8 + +.section .vectors, "ax" + +.globl _ISR_Handler +.globl _window_overflow +.globl _window_underflow +.globl _reset +.globl _context_switch + +.globl system_vectors +system_vectors: + TRAPL(_reset); ! 00 reset trap + BAD_TRAP; ! 01 instruction_access_exception + BAD_TRAP; ! 02 illegal_instruction + BAD_TRAP; ! 03 priveleged_instruction + BAD_TRAP; + TRAP(_window_overflow); ! 05 window_overflow + TRAP(_window_underflow); ! 06 window_underflow + BAD_TRAP; ! 07 memory_add0ress_not_aligned + BAD_TRAP; ! 08 fp_exception + BAD_TRAP; ! 09 data_access_exception + BAD_TRAP; ! 0A tag_overflow + BAD_TRAP; ! 0B undefined + BAD_TRAP; ! 0C undefined + BAD_TRAP; ! 0D undefined + BAD_TRAP; ! 0E undefined + BAD_TRAP; ! 0F undefined + BAD_TRAP; ! 10 undefined + + /* Interrupt entries */ + TRAP_ENTRY(_ISR_Handler) ! 11 interrupt level 1 + TRAP_ENTRY(_ISR_Handler) ! 12 interrupt level 2 + TRAP_ENTRY(_ISR_Handler) ! 13 interrupt level 3 + TRAP_ENTRY(_ISR_Handler) ! 14 interrupt level 4 + TRAP_ENTRY(_ISR_Handler) ! 15 interrupt level 5 + TRAP_ENTRY(_ISR_Handler) ! 16 interrupt level 6 + TRAP_ENTRY(_ISR_Handler) ! 17 interrupt level 7 + TRAP_ENTRY(_ISR_Handler) ! 18 interrupt level 8 + TRAP_ENTRY(_ISR_Handler) ! 19 interrupt level 9 + TRAP_ENTRY(_ISR_Handler) ! 1A interrupt level 1 + TRAP_ENTRY(_ISR_Handler) ! 1B interrupt level 11 + TRAP_ENTRY(_ISR_Handler) ! 1C interrupt level 12 + TRAP_ENTRY(_ISR_Handler) ! 1D interrupt level 13 + TRAP_ENTRY(_ISR_Handler) ! 1E interrupt level 14 + TRAP_ENTRY(_ISR_Handler) ! 1F interrupt level 15 + + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 20 - 23 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 24 - 27 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 28 - 2B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 2C - 2F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30 - 33 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34 - 37 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38 - 3B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 3C - 3F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40 - 43 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44 - 47 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48 - 4B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4C - 4F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50 - 53 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54 - 57 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58 - 5B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5C - 5F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60 - 63 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64 - 67 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68 - 6B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6C - 6F undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70 - 73 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74 - 77 undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78 - 7B undefined + BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 7C - 7F undefined + + /* Software traps */ + SOFT_TRAP; SOFT_TRAP; TRAP_ENTRY(_context_switch); TRAP_ENTRY(_context_switch) ! 80 - 83 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 84 - 87 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 88 - 8B + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 8C - 8F + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 90 - 93 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 94 - 97 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 98 - 9B + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! 9C - 9F + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A0 - A3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A4 - A7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! A8 - AB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! AC - AF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B0 - B3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B4 - B7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! B8 - BB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! BC - BF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C0 - C3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C4 - C7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! C8 - CB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! CC - CF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D0 - D3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D4 - D7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! D8 - DB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! DC - DF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E0 - E3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E4 - E7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! E8 - EB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! EC - EF + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F0 - F3 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F4 - F7 + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! F8 - FB + SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; ! FC - FF + +_window_overflow: + mov %wim, %l3 ! Calculate next WIM + mov %g1, %l7 + srl %l3, 1, %g1 + sll %l3, NWINDOWS - 1, %l4 + or %l4, %g1, %g1 + save ! Get into window to be saved. + mov %g1, %wim + nop + nop + nop + std %l0, [%sp + 0] + std %l2, [%sp + 8] + std %l4, [%sp + 16] + std %l6, [%sp + 24] + std %i0, [%sp + 32] + std %i2, [%sp + 40] + std %i4, [%sp + 48] + std %i6, [%sp + 56] + restore ! Go back to trap window. + mov %l7, %g1 + jmp %l1 ! Re-execute save. + rett %l2 + +_window_underflow: + mov %wim, %l3 ! Calculate next WIM + sll %l3, 1, %l4 + srl %l3, NWINDOWS - 1, %l5 + or %l5, %l4, %l5 + mov %l5, %wim + nop + nop + nop + restore ! Two restores to get into the + restore ! window to restore + ldd [%sp + 0], %l0 ! Restore window from the stack + ldd [%sp + 8], %l2 + ldd [%sp + 16], %l4 + ldd [%sp + 24], %l6 + ldd [%sp + 32], %i0 + ldd [%sp + 40], %i2 + ldd [%sp + 48], %i4 + ldd [%sp + 56], %i6 + save ! Get back to the trap window. + save + jmp %l1 ! Re-execute restore. + rett %l2 diff --git a/libcpu/sparc-v8/common/SConscript b/libcpu/sparc-v8/common/SConscript new file mode 100644 index 0000000000..9ff30a796b --- /dev/null +++ b/libcpu/sparc-v8/common/SConscript @@ -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 == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') |
