binutils-gdb/sim/erc32/examples/srt0.S
1996-05-20 02:46:07 +00:00

450 lines
12 KiB
ArmAsm
Executable File

/*
* srt0.s for ERC32. This file is part of ERC32SIM.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 675
* Mass Ave, Cambridge, MA 02139, USA.
*
*/
/* The traptable has to be the first code in a boot PROM. */
/* Entry for traps which jump to a programmer-specified trap handler. */
#define TRAP(H) mov %psr, %l0; sethi %hi(H), %l4; jmp %l4+%lo(H); nop;
/* Unexcpected trap will halt the processor by forcing it to error state */
#define BAD_TRAP ta 0; nop; nop; nop;
/* Software trap. Treat as BAD_TRAP for the time being... */
#define SOFT_TRAP BAD_TRAP
#define PSR_INIT 0x10c0 /* Disable traps, set s and ps */
#define WIM_INIT 2
#define SP_INIT 0x02100000
WINDOWSIZE = (16 * 4)
ARGPUSHSIZE = (6 * 4)
ARGPUSH = (WINDOWSIZE + 4)
MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4)
#define STACK_ALIGN 8
#define SA(X) (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
.seg "text"
.global _trap_table, _mecini, start
/* Hardware traps */
_trap_table:
TRAP(_mecini); ! 00 reset trap
BAD_TRAP; ! 01 instruction_access_exception
BAD_TRAP; ! 02 illegal_instruction
BAD_TRAP; ! 03 priveleged_instruction
BAD_TRAP; ! 04 fp_disabled
TRAP(_window_overflow); ! 05 window_overflow
TRAP(_window_underflow); ! 06 window_underflow
BAD_TRAP; ! 07 memory_address_not_aligned
BAD_TRAP; ! 08 fp_exception
BAD_TRAP; ! 09 data_access_exception
BAD_TRAP; ! 0A tag_overflow
/* Trap levels from 0B to 0x10 are not defined (used for MEC init) */
_mecini:
sethi %hi(0x01f80000), %g1 ! 0B
sethi %hi(0x001C1000), %g2
or %g1,%lo(0x001C1000),%g1
st %g2, [%g1 + 0x10]
st %g0, [%g1 + 0x18] ! 0C
nop
nop
nop
TRAP(_hardreset); ! 0D
BAD_TRAP; ! 0E undefined
BAD_TRAP; ! 0F undefined
BAD_TRAP; ! 10 undefined
/* Interrupt entries */
BAD_TRAP; ! 11 interrupt level 1
BAD_TRAP; ! 12 interrupt level 2
BAD_TRAP; ! 13 interrupt level 3
BAD_TRAP; ! 14 interrupt level 4
BAD_TRAP; ! 15 interrupt level 5
BAD_TRAP; ! 16 interrupt level 6
BAD_TRAP; ! 17 interrupt level 7
BAD_TRAP; ! 18 interrupt level 8
BAD_TRAP; ! 19 interrupt level 9
BAD_TRAP; ! 1A interrupt level 1
BAD_TRAP; ! 1B interrupt level 11
BAD_TRAP; ! 1C interrupt level 12
BAD_TRAP; ! 1D interrupt level 13
BAD_TRAP; ! 1E interrupt level 14
BAD_TRAP; ! 1F interrupt level 15
BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 20 - 23 undefined
BAD_TRAP; ! 24 cp_disabled
BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 25 - 27 undefined
BAD_TRAP; ! 28 cp_exception
BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 29 - 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; SOFT_TRAP; ! 80 - 82
TRAP(_flush_windows) ! 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
!
! Startup code for standalone system. Wash IU and FPU (if present) registers.
! The registers have to be written to initiate the parity bits.
!
_hardreset:
sethi %hi(0x01FE0),%o0
or %o0,%lo(0x01FE0),%o0
wr %o0, %psr ! Set valid PSR
nop
wr %g0, %wim ! Set window invalid mask register
wr %g0, %y ! Init Y-register
nop
set _hardreset, %g1
wr %g1, %tbr ! Set TBR
sethi %hi(SP_INIT),%sp
or %g0, 1, %o0
ld [%g0], %f0 ! Check if FPU is present
tst %o0
bz fixiu
nop
ba fixfpu
! FPU disabled trap address
clr %i0
jmpl %l2, %g0
rett %l2 + 4
nop
! Wash register files (fix for 90C601E & 90C602E)
fixfpu:
ld [%g0], %f0
ld [%g0], %f1
ld [%g0], %f2
ld [%g0], %f3
ld [%g0], %f4
ld [%g0], %f5
ld [%g0], %f6
ld [%g0], %f7
ld [%g0], %f8
ld [%g0], %f9
ld [%g0], %f10
ld [%g0], %f11
ld [%g0], %f12
ld [%g0], %f13
ld [%g0], %f14
ld [%g0], %f15
ld [%g0], %f16
ld [%g0], %f17
ld [%g0], %f18
ld [%g0], %f19
ld [%g0], %f20
ld [%g0], %f21
ld [%g0], %f22
ld [%g0], %f23
ld [%g0], %f24
ld [%g0], %f25
ld [%g0], %f26
ld [%g0], %f27
ld [%g0], %f28
ld [%g0], %f29
ld [%g0], %f30
ld [%g0], %f31
fixiu:
clr %g1
clr %g2
clr %g3
clr %g4
clr %g5
clr %g6
clr %g7
set 8,%g1
wl0:
clr %i0
clr %i1
clr %i2
clr %i3
clr %i4
clr %i5
clr %i6
clr %i7
clr %l0
clr %l1
clr %l2
clr %l3
clr %l4
clr %l5
clr %l6
clr %l7
save
subcc %g1, 1, %g1
bne wl0
nop
!
! Start the real-time clock with a tick of 150 clocks
!
rtc:
set 0x1f80000, %l0 ! MEC register base
set 149, %l1
st %l1, [%l0 + 0x84] ! RTC scaler = 149
set 0x0d00, %l1
st %l1, [%l0 + 0x98] ! Start RTC
st %g0, [%l0 + 0x64] ! Disable watchdog for now
ld [%l0], %g1
or %g1, 1, %g1
st %g1, [%l0] ! Enable power-down mode
! Initialise some registers
_init:
set PSR_INIT, %g1 ! Initialize psr
wr %g1, %psr
set WIM_INIT, %g1 ! Initialize WIM
wr %g1, %wim
set _trap_table, %g1 ! Initialize TBR
wr %g1, %tbr
nop;nop;nop
set PSR_INIT, %g1
wr %g1, 0x20, %psr ! enable traps
nop; nop; nop;
set 0x02100000, %sp ! Set stack pointer
mov %sp, %fp
nop
start:
/* clear the bss */
sethi %hi(_edata),%g2
or %g2,%lo(_edata),%g2 ! g2 = start of bss
sethi %hi(_end),%g3
or %g3,%lo(_end),%g3 ! g3 = end of bss
mov %g0,%g1 ! so std has two zeros
zerobss:
std %g0,[%g2]
add %g2,8,%g2
cmp %g2,%g3
bleu,a zerobss
nop
/* move data segment to proper location */
relocd:
set (_etext),%g2 ! g2 = start of data in aout file
set (_environ),%g4 ! g4 = start of where data should go
set (_edata),%g3 ! g3 = end of where data should go
subcc %g3, %g4, %g5 ! g5 = length of data
subcc %g4, %g2, %g0 ! need to relocate data ?
ble initok
mvdata:
subcc %g5, 8, %g5
ldd [%g2 + %g5], %g6
bg mvdata
std %g6, [%g4 + %g5]
initok:
call _main
sub %sp, 0x40, %sp ! room for main to save args
nop
ta 0 ! Halt if _main would return ...
nop
/* Number of register windows */
#define NWINDOWS 8
!Window overflow trap handler.
.global _window_overflow
_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
st %l0, [%sp + 0];
st %l1, [%sp + 4];
st %l2, [%sp + 8];
st %l3, [%sp + 12];
st %l4, [%sp + 16];
st %l5, [%sp + 20];
st %l6, [%sp + 24];
st %l7, [%sp + 28];
st %i0, [%sp + 32];
st %i1, [%sp + 36];
st %i2, [%sp + 40];
st %i3, [%sp + 44];
st %i4, [%sp + 48];
st %i5, [%sp + 52];
st %i6, [%sp + 56];
st %i7, [%sp + 60];
restore ! Go back to trap window.
mov %l7, %g1
jmp %l1 ! Re-execute save.
rett %l2
/* Window underflow trap handler. */
.global _window_underflow
_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
ld [%sp + 0], %l0; ! Restore window from the stack
ld [%sp + 4], %l1;
ld [%sp + 8], %l2;
ld [%sp + 12], %l3;
ld [%sp + 16], %l4;
ld [%sp + 20], %l5;
ld [%sp + 24], %l6;
ld [%sp + 28], %l7;
ld [%sp + 32], %i0;
ld [%sp + 36], %i1;
ld [%sp + 40], %i2;
ld [%sp + 44], %i3;
ld [%sp + 48], %i4;
ld [%sp + 52], %i5;
ld [%sp + 56], %i6;
ld [%sp + 60], %i7;
save ! Get back to the trap window.
save
jmp %l1 ! Re-execute restore.
rett %l2
.global _flush_windows
_flush_windows:
mov %psr, %g1
or %g1, 0x0f00, %g2
restore ! enter previous frame (cannot trap)
wr %g2, 0x20, %psr ! enable traps, disable interrupts
nop; nop; nop
save ! 6 save to flush all windows
save
save
save
save
save
restore ! 5 restore to enter trapped frame
restore
restore
restore
restore
wr %g1, %psr ! restore %psr
nop; nop; nop
jmp %l2 ! Jump to nPC
rett %l2 + 4
.seg "data"
.global .bdata
.bdata:
.align 8
.global _environ ! first symbol in sdata
_environ:
.word 0
.global _errno ! not defined elsewhere ..?
_errno:
.word 0