aboutsummaryrefslogtreecommitdiff
path: root/sim/erc32/examples/srt0.S
diff options
context:
space:
mode:
Diffstat (limited to 'sim/erc32/examples/srt0.S')
-rwxr-xr-xsim/erc32/examples/srt0.S449
1 files changed, 449 insertions, 0 deletions
diff --git a/sim/erc32/examples/srt0.S b/sim/erc32/examples/srt0.S
new file mode 100755
index 0000000..1e68951
--- /dev/null
+++ b/sim/erc32/examples/srt0.S
@@ -0,0 +1,449 @@
+/*
+ * 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
+
+
+