common.lds: define vbr alignment

This also creates an example of a VBR+0x100 function in interrupt.cpp
This commit is contained in:
Zack Buhman 2024-04-15 18:22:28 +08:00
parent c1e3e9d074
commit c8e84be5d2
6 changed files with 128 additions and 2 deletions

View File

@ -41,6 +41,15 @@ SECTIONS
*(COMMON) *(COMMON)
} > p1ram } > p1ram
.text.vbr ALIGN(4) : SUBALIGN(4)
{
KEEP(*(.vbr.100))
. = ALIGN(0x300);
KEEP(*(.vbr.400))
. = ALIGN(0x200);
KEEP(*(.vbr.600))
} > p1ram
INCLUDE "debug.lds" INCLUDE "debug.lds"
} }

View File

@ -329,6 +329,7 @@ example/serial_transfer.elf: $(START_OBJ) $(SERIAL_TRANSFER_OBJ)
INTERRUPT_OBJ = \ INTERRUPT_OBJ = \
example/interrupt.o \ example/interrupt.o \
example/illslot.o \
sh7091/serial.o sh7091/serial.o
example/interrupt.elf: LDSCRIPT = $(LIB)/alt.lds example/interrupt.elf: LDSCRIPT = $(LIB)/alt.lds

6
example/illslot.s Normal file
View File

@ -0,0 +1,6 @@
.global _illslot
_illslot:
rts
mova test,r0
test: .long 0x12345678

View File

@ -4,14 +4,103 @@
#include "sh7091/sh7091.hpp" #include "sh7091/sh7091.hpp"
#include "sh7091/sh7091_bits.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() void main()
{ {
uint32_t vbr; uint32_t vbr = reinterpret_cast<uint32_t>(&__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<uint32_t>(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<uint32_t>(vbr); serial::integer<uint32_t>(vbr);
//serial::integer<uint32_t>(vbr2);
serial::integer<uint32_t>(reinterpret_cast<uint32_t>(&vbr100));
uint32_t * test = illslot();
serial::integer<uint32_t>(*test);
while (1); while (1);
} }

17
sh7091/vbr.hpp Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include <cstdint>
__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");

View File

@ -18,3 +18,7 @@ __ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors);
__bss_link_start = ADDR(.bss); __bss_link_start = ADDR(.bss);
__bss_link_end = ADDR(.bss) + SIZEOF(.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);