From c8e84be5d234551bd13ac01fd3abddcb79994f90 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Mon, 15 Apr 2024 18:22:28 +0800 Subject: [PATCH] common.lds: define vbr alignment This also creates an example of a VBR+0x100 function in interrupt.cpp --- common.lds | 9 +++++ example/example.mk | 1 + example/illslot.s | 6 +++ example/interrupt.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++- sh7091/vbr.hpp | 17 ++++++++ symbols.lds | 4 ++ 6 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 example/illslot.s create mode 100644 sh7091/vbr.hpp diff --git a/common.lds b/common.lds index 0f36d99..37ff231 100644 --- a/common.lds +++ b/common.lds @@ -41,6 +41,15 @@ SECTIONS *(COMMON) } > p1ram + .text.vbr ALIGN(4) : SUBALIGN(4) + { + KEEP(*(.vbr.100)) + . = ALIGN(0x300); + KEEP(*(.vbr.400)) + . = ALIGN(0x200); + KEEP(*(.vbr.600)) + } > p1ram + INCLUDE "debug.lds" } diff --git a/example/example.mk b/example/example.mk index 3dd3627..4f02d54 100644 --- a/example/example.mk +++ b/example/example.mk @@ -329,6 +329,7 @@ example/serial_transfer.elf: $(START_OBJ) $(SERIAL_TRANSFER_OBJ) INTERRUPT_OBJ = \ example/interrupt.o \ + example/illslot.o \ sh7091/serial.o example/interrupt.elf: LDSCRIPT = $(LIB)/alt.lds diff --git a/example/illslot.s b/example/illslot.s new file mode 100644 index 0000000..76deb3c --- /dev/null +++ b/example/illslot.s @@ -0,0 +1,6 @@ + .global _illslot +_illslot: + rts + mova test,r0 + +test: .long 0x12345678 diff --git a/example/interrupt.cpp b/example/interrupt.cpp index ca2756b..3116687 100644 --- a/example/interrupt.cpp +++ b/example/interrupt.cpp @@ -4,14 +4,103 @@ #include "sh7091/sh7091.hpp" #include "sh7091/sh7091_bits.hpp" +#include "sh7091/vbr.hpp" +#include "systembus.hpp" +void vbr100() +{ + serial::string("vbr100\n"); + serial::string("expevt "); + serial::integer(sh7091.CCN.EXPEVT); + serial::string("intevt "); + serial::integer(sh7091.CCN.INTEVT); + uint32_t spc; + uint32_t ssr; + asm volatile ("stc spc,%0" + : "=r" (spc) + ); + asm volatile ("stc ssr,%0" + : "=r" (ssr) + ); + + serial::string("spc "); + serial::integer(spc); + serial::string("ssr "); + serial::integer(ssr); + while (1); +} + +void vbr400() +{ + serial::string("vbr400"); + while (1); +} + +void vbr600() +{ + serial::string("vbr600"); + while (1); +} + +extern "C" uint32_t * illslot(void); void main() { - uint32_t vbr; + uint32_t vbr = reinterpret_cast(&__vbr_link_start) - 0x100; - asm ("stc vbr,%0" : "=r" (vbr)); + system.IML2NRM = 0; + system.IML2ERR = 0; + system.IML2EXT = 0; + + system.IML4NRM = 0; + system.IML4ERR = 0; + system.IML4EXT = 0; + + system.IML6NRM = 0; + system.IML6ERR = 0; + system.IML6EXT = 0; + + sh7091.CCN.INTEVT = 0; + sh7091.CCN.EXPEVT = 0; + + uint32_t zero = 0; + asm volatile ("ldc %0,spc" + : + : "r" (zero)); + + asm volatile ("ldc %0,ssr" + : + : "r" (zero)); + + asm volatile ("ldc %0,vbr" + : + : "r" (vbr)); + + + uint32_t sr; + asm volatile ("stc sr,%0" + : "=r" (sr)); + + serial::string("sr "); + serial::integer(sr); + + sr = sr & (~(1 << 28)); // BL + + asm volatile ("ldc %0, sr" + : + : "r" (sr)); + + /* + uint32_t vbr2; + asm volatile ("stc vbr,%0" + : "=r" (vbr2)); + */ serial::integer(vbr); + //serial::integer(vbr2); + serial::integer(reinterpret_cast(&vbr100)); + + uint32_t * test = illslot(); + serial::integer(*test); while (1); } diff --git a/sh7091/vbr.hpp b/sh7091/vbr.hpp new file mode 100644 index 0000000..fd348ef --- /dev/null +++ b/sh7091/vbr.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include + +__attribute__((section(".vbr.100"))) +__attribute__((interrupt_handler)) +void vbr100(); + +__attribute__((section(".vbr.400"))) +__attribute__((interrupt_handler)) +void vbr400(); + +__attribute__((section(".vbr.600"))) +__attribute__((interrupt_handler)) +void vbr600(); + +extern uint32_t __vbr_link_start __asm("__vbr_link_start"); diff --git a/symbols.lds b/symbols.lds index 36d00f8..74c01e4 100644 --- a/symbols.lds +++ b/symbols.lds @@ -18,3 +18,7 @@ __ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors); __bss_link_start = ADDR(.bss); __bss_link_end = ADDR(.bss) + SIZEOF(.bss); + +__vbr_link_start = ADDR(.text.vbr); +__vbr_link_end = ADDR(.text.vbr) + SIZEOF(.text.vbr); +__vbr_load_end = LOADADDR(.text.vbr);