675 lines
11 KiB
ArmAsm

/*
Copyright 2020 Shenzhen Academy of Aerospace Technology
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
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