aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/sh_bios.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-01-12 04:42:52 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-01-12 04:42:52 -0500
commit94cd049522136c2f3bbe063d2e98b2b8d4286fd3 (patch)
tree7c521604861235e113715ecfb627398f5b941359 /arch/sh/kernel/sh_bios.c
parenta99eae5417a09e0be66bf574a9a79a2a7388c967 (diff)
sh: sh_bios detection.
This adds some VBR sanity checks in the sh_bios code to ensure that the BIOS VBR is in range before blindly trapping in to it. This permits boards with varying boot loader configurations to always leave support for sh-bios enabled and it will just be disabled at run-time if not found. 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.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c
index 29cd2526e5c4..47475cca068a 100644
--- a/arch/sh/kernel/sh_bios.c
+++ b/arch/sh/kernel/sh_bios.c
@@ -23,6 +23,8 @@
23#define BIOS_CALL_SHUTDOWN 11 23#define BIOS_CALL_SHUTDOWN 11
24#define BIOS_CALL_GDB_DETACH 0xff 24#define BIOS_CALL_GDB_DETACH 0xff
25 25
26void *gdb_vbr_vector = NULL;
27
26static inline long sh_bios_call(long func, long arg0, long arg1, long arg2, 28static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
27 long arg3) 29 long arg3)
28{ 30{
@@ -32,6 +34,9 @@ static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
32 register long r6 __asm__("r6") = arg2; 34 register long r6 __asm__("r6") = arg2;
33 register long r7 __asm__("r7") = arg3; 35 register long r7 __asm__("r7") = arg3;
34 36
37 if (!gdb_vbr_vector)
38 return -ENOSYS;
39
35 __asm__ __volatile__("trapa #0x3f":"=z"(r0) 40 __asm__ __volatile__("trapa #0x3f":"=z"(r0)
36 :"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7) 41 :"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7)
37 :"memory"); 42 :"memory");
@@ -60,8 +65,6 @@ void sh_bios_shutdown(unsigned int how)
60 sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0); 65 sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0);
61} 66}
62 67
63void *gdb_vbr_vector = NULL;
64
65/* 68/*
66 * Read the old value of the VBR register to initialise the vector 69 * Read the old value of the VBR register to initialise the vector
67 * through which debug and BIOS traps are delegated by the Linux trap 70 * through which debug and BIOS traps are delegated by the Linux trap
@@ -76,8 +79,12 @@ void sh_bios_vbr_init(void)
76 79
77 __asm__ __volatile__ ("stc vbr, %0" : "=r" (vbr)); 80 __asm__ __volatile__ ("stc vbr, %0" : "=r" (vbr));
78 81
79 gdb_vbr_vector = (void *)(vbr + 0x100); 82 if (vbr) {
80 printk(KERN_NOTICE "Setting GDB trap vector to %p\n", gdb_vbr_vector); 83 gdb_vbr_vector = (void *)(vbr + 0x100);
84 printk(KERN_NOTICE "Setting GDB trap vector to %p\n",
85 gdb_vbr_vector);
86 } else
87 printk(KERN_NOTICE "SH-BIOS not detected\n");
81} 88}
82 89
83/** 90/**