diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-01-12 14:50:43 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-01-12 14:50:43 +0900 |
commit | 191d0d24b632eb69767705acded5cbf7449ad457 (patch) | |
tree | 4fda30db2941692bea884685f1df2e751468bd6f /arch/sh/kernel/sh_bios.c | |
parent | ee2760ea58d81fc00bcc2137232ed9bc28202aec (diff) |
sh: Tidy up the sh bios VBR handling.
This moves the VBR handling out of the main trap handling code and in to
the sh-bios helper code. A couple of accessors are added in order to
permit other kernel code to get at the VBR value for state save/restore
paths.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/sh_bios.c')
-rw-r--r-- | arch/sh/kernel/sh_bios.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c index c852f780572..2a5f2e0d505 100644 --- a/arch/sh/kernel/sh_bios.c +++ b/arch/sh/kernel/sh_bios.c @@ -55,3 +55,40 @@ void sh_bios_shutdown(unsigned int how) { sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0); } + +void *gdb_vbr_vector = NULL; + +/* + * Read the old value of the VBR register to initialise the vector + * through which debug and BIOS traps are delegated by the Linux trap + * handler. + */ +void sh_bios_vbr_init(void) +{ + unsigned long vbr; + + if (unlikely(gdb_vbr_vector)) + return; + + __asm__ __volatile__ ("stc vbr, %0" : "=r" (vbr)); + + gdb_vbr_vector = (void *)(vbr + 0x100); + printk(KERN_NOTICE "Setting GDB trap vector to %p\n", gdb_vbr_vector); +} + +/** + * sh_bios_vbr_reload - Re-load the system VBR from the BIOS vector. + * + * This can be used by save/restore code to reinitialize the system VBR + * from the fixed BIOS VBR. A no-op if no BIOS VBR is known. + */ +void sh_bios_vbr_reload(void) +{ + if (gdb_vbr_vector) + __asm__ __volatile__ ( + "ldc %0, vbr" + : + : "r" (((unsigned long) gdb_vbr_vector) - 0x100) + : "memory" + ); +} |