summaryrefslogtreecommitdiffstats
path: root/arch/openrisc/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-05-27 02:27:49 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2022-05-27 02:27:49 +0200
commit7f50d4dfe816dd916a7cbf39039674825c2b388b (patch)
treedb45c022505a355314799e3e9be740bb71a5f31f /arch/openrisc/kernel
parentMerge tag 'arc-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgu... (diff)
parentopenrisc: Allow power off handler overriding (diff)
downloadlinux-7f50d4dfe816dd916a7cbf39039674825c2b388b.tar.xz
linux-7f50d4dfe816dd916a7cbf39039674825c2b388b.zip
Merge tag 'for-linus' of https://github.com/openrisc/linux
Pull OpenRISC updates from Stafford Horne: - A few sparse warning fixups and other cleanups I noticed when working on a recent TLB bug found on a new OpenRISC core bring up. - A few fixup's from me and Jason A Donenfeld to help shutdown OpenRISC platforms when running CI tests * tag 'for-linus' of https://github.com/openrisc/linux: openrisc: Allow power off handler overriding openrisc: Remove unused IMMU tlb workardound openrisc/fault: Fix symbol scope warnings openrisc/delay: Add include to fix symbol not declared warning openrisc/time: Fix symbol scope warnings openrisc/traps: Declare unhandled_exception for asmlinkage openrisc/traps: Remove die_if_kernel function openrisc/traps: Declare file scope symbols as static openrisc: Update litex defconfig to support glibc userland openrisc: Pretty print show_registers memory dumps openrisc: Add syscall details to emergency syscall debugging openrisc: Add support for liteuart emergency printing openrisc: Cleanup emergency print handling openrisc: Add gcc machine instruction flag configuration openrisc: define nop command for simulator reboot openrisc: remove bogus nops and shutdowns openrisc: fix typos in comments
Diffstat (limited to 'arch/openrisc/kernel')
-rw-r--r--arch/openrisc/kernel/entry.S20
-rw-r--r--arch/openrisc/kernel/head.S368
-rw-r--r--arch/openrisc/kernel/process.c19
-rw-r--r--arch/openrisc/kernel/time.c3
-rw-r--r--arch/openrisc/kernel/traps.c63
5 files changed, 167 insertions, 306 deletions
diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S
index 3ca1b1f490b9..54a87bba35ca 100644
--- a/arch/openrisc/kernel/entry.S
+++ b/arch/openrisc/kernel/entry.S
@@ -601,7 +601,7 @@ UNHANDLED_EXCEPTION(_vector_0xb00,0xb00)
*/
_string_syscall_return:
- .string "syscall return %ld \n\r\0"
+ .string "syscall r9:0x%08x -> syscall(%ld) return %ld\0"
.align 4
ENTRY(_sys_call_handler)
@@ -679,15 +679,25 @@ _syscall_return:
_syscall_debug:
l.movhi r3,hi(_string_syscall_return)
l.ori r3,r3,lo(_string_syscall_return)
- l.ori r27,r0,1
+ l.ori r27,r0,2
l.sw -4(r1),r27
l.sw -8(r1),r11
- l.addi r1,r1,-8
+ l.lwz r29,PT_ORIG_GPR11(r1)
+ l.sw -12(r1),r29
+ l.lwz r29,PT_GPR9(r1)
+ l.sw -16(r1),r29
l.movhi r27,hi(_printk)
l.ori r27,r27,lo(_printk)
l.jalr r27
- l.nop
- l.addi r1,r1,8
+ l.addi r1,r1,-16
+ l.addi r1,r1,16
+#endif
+#if 0
+_syscall_show_regs:
+ l.movhi r27,hi(show_registers)
+ l.ori r27,r27,lo(show_registers)
+ l.jalr r27
+ l.or r3,r1,r1
#endif
_syscall_check_trace_leave:
diff --git a/arch/openrisc/kernel/head.S b/arch/openrisc/kernel/head.S
index 2fa6cefa62ca..e11699f3d6bd 100644
--- a/arch/openrisc/kernel/head.S
+++ b/arch/openrisc/kernel/head.S
@@ -297,19 +297,23 @@
/* temporary store r3, r9 into r1, r10 */ ;\
l.addi r1,r3,0x0 ;\
l.addi r10,r9,0x0 ;\
- /* the string referenced by r3 must be low enough */ ;\
+ LOAD_SYMBOL_2_GPR(r9,_string_unhandled_exception) ;\
+ tophys (r3,r9) ;\
l.jal _emergency_print ;\
- l.ori r3,r0,lo(_string_unhandled_exception) ;\
+ l.nop ;\
l.mfspr r3,r0,SPR_NPC ;\
l.jal _emergency_print_nr ;\
- l.andi r3,r3,0x1f00 ;\
- /* the string referenced by r3 must be low enough */ ;\
+ l.andi r3,r3,0x1f00 ;\
+ LOAD_SYMBOL_2_GPR(r9,_string_epc_prefix) ;\
+ tophys (r3,r9) ;\
l.jal _emergency_print ;\
- l.ori r3,r0,lo(_string_epc_prefix) ;\
+ l.nop ;\
l.jal _emergency_print_nr ;\
- l.mfspr r3,r0,SPR_EPCR_BASE ;\
+ l.mfspr r3,r0,SPR_EPCR_BASE ;\
+ LOAD_SYMBOL_2_GPR(r9,_string_nl) ;\
+ tophys (r3,r9) ;\
l.jal _emergency_print ;\
- l.ori r3,r0,lo(_string_nl) ;\
+ l.nop ;\
/* end of printing */ ;\
l.addi r3,r1,0x0 ;\
l.addi r9,r10,0x0 ;\
@@ -1330,274 +1334,110 @@ i_pte_not_present:
/* =================================================[ debugging aids ]=== */
- .align 64
-_immu_trampoline:
- .space 64
-_immu_trampoline_top:
-
-#define TRAMP_SLOT_0 (0x0)
-#define TRAMP_SLOT_1 (0x4)
-#define TRAMP_SLOT_2 (0x8)
-#define TRAMP_SLOT_3 (0xc)
-#define TRAMP_SLOT_4 (0x10)
-#define TRAMP_SLOT_5 (0x14)
-#define TRAMP_FRAME_SIZE (0x18)
-
-ENTRY(_immu_trampoline_workaround)
- // r2 EEA
- // r6 is physical EEA
- tophys(r6,r2)
-
- LOAD_SYMBOL_2_GPR(r5,_immu_trampoline)
- tophys (r3,r5) // r3 is trampoline (physical)
-
- LOAD_SYMBOL_2_GPR(r4,0x15000000)
- l.sw TRAMP_SLOT_0(r3),r4
- l.sw TRAMP_SLOT_1(r3),r4
- l.sw TRAMP_SLOT_4(r3),r4
- l.sw TRAMP_SLOT_5(r3),r4
-
- // EPC = EEA - 0x4
- l.lwz r4,0x0(r6) // load op @ EEA + 0x0 (fc address)
- l.sw TRAMP_SLOT_3(r3),r4 // store it to _immu_trampoline_data
- l.lwz r4,-0x4(r6) // load op @ EEA - 0x4 (f8 address)
- l.sw TRAMP_SLOT_2(r3),r4 // store it to _immu_trampoline_data
-
- l.srli r5,r4,26 // check opcode for write access
- l.sfeqi r5,0 // l.j
- l.bf 0f
- l.sfeqi r5,0x11 // l.jr
- l.bf 1f
- l.sfeqi r5,1 // l.jal
- l.bf 2f
- l.sfeqi r5,0x12 // l.jalr
- l.bf 3f
- l.sfeqi r5,3 // l.bnf
- l.bf 4f
- l.sfeqi r5,4 // l.bf
- l.bf 5f
-99:
- l.nop
- l.j 99b // should never happen
- l.nop 1
-
- // r2 is EEA
- // r3 is trampoline address (physical)
- // r4 is instruction
- // r6 is physical(EEA)
- //
- // r5
-
-2: // l.jal
-
- /* 19 20 aa aa l.movhi r9,0xaaaa
- * a9 29 bb bb l.ori r9,0xbbbb
- *
- * where 0xaaaabbbb is EEA + 0x4 shifted right 2
- */
-
- l.addi r6,r2,0x4 // this is 0xaaaabbbb
-
- // l.movhi r9,0xaaaa
- l.ori r5,r0,0x1920 // 0x1920 == l.movhi r9
- l.sh (TRAMP_SLOT_0+0x0)(r3),r5
- l.srli r5,r6,16
- l.sh (TRAMP_SLOT_0+0x2)(r3),r5
-
- // l.ori r9,0xbbbb
- l.ori r5,r0,0xa929 // 0xa929 == l.ori r9
- l.sh (TRAMP_SLOT_1+0x0)(r3),r5
- l.andi r5,r6,0xffff
- l.sh (TRAMP_SLOT_1+0x2)(r3),r5
-
- /* falthrough, need to set up new jump offset */
-
-
-0: // l.j
- l.slli r6,r4,6 // original offset shifted left 6 - 2
-// l.srli r6,r6,6 // original offset shifted right 2
-
- l.slli r4,r2,4 // old jump position: EEA shifted left 4
-// l.srli r4,r4,6 // old jump position: shifted right 2
-
- l.addi r5,r3,0xc // new jump position (physical)
- l.slli r5,r5,4 // new jump position: shifted left 4
-
- // calculate new jump offset
- // new_off = old_off + (old_jump - new_jump)
-
- l.sub r5,r4,r5 // old_jump - new_jump
- l.add r5,r6,r5 // orig_off + (old_jump - new_jump)
- l.srli r5,r5,6 // new offset shifted right 2
-
- // r5 is new jump offset
- // l.j has opcode 0x0...
- l.sw TRAMP_SLOT_2(r3),r5 // write it back
-
- l.j trampoline_out
- l.nop
-
-/* ----------------------------- */
-
-3: // l.jalr
-
- /* 19 20 aa aa l.movhi r9,0xaaaa
- * a9 29 bb bb l.ori r9,0xbbbb
- *
- * where 0xaaaabbbb is EEA + 0x4 shifted right 2
- */
-
- l.addi r6,r2,0x4 // this is 0xaaaabbbb
-
- // l.movhi r9,0xaaaa
- l.ori r5,r0,0x1920 // 0x1920 == l.movhi r9
- l.sh (TRAMP_SLOT_0+0x0)(r3),r5
- l.srli r5,r6,16
- l.sh (TRAMP_SLOT_0+0x2)(r3),r5
-
- // l.ori r9,0xbbbb
- l.ori r5,r0,0xa929 // 0xa929 == l.ori r9
- l.sh (TRAMP_SLOT_1+0x0)(r3),r5
- l.andi r5,r6,0xffff
- l.sh (TRAMP_SLOT_1+0x2)(r3),r5
-
- l.lhz r5,(TRAMP_SLOT_2+0x0)(r3) // load hi part of jump instruction
- l.andi r5,r5,0x3ff // clear out opcode part
- l.ori r5,r5,0x4400 // opcode changed from l.jalr -> l.jr
- l.sh (TRAMP_SLOT_2+0x0)(r3),r5 // write it back
-
- /* falthrough */
-
-1: // l.jr
- l.j trampoline_out
- l.nop
-
-/* ----------------------------- */
-
-4: // l.bnf
-5: // l.bf
- l.slli r6,r4,6 // original offset shifted left 6 - 2
-// l.srli r6,r6,6 // original offset shifted right 2
-
- l.slli r4,r2,4 // old jump position: EEA shifted left 4
-// l.srli r4,r4,6 // old jump position: shifted right 2
-
- l.addi r5,r3,0xc // new jump position (physical)
- l.slli r5,r5,4 // new jump position: shifted left 4
-
- // calculate new jump offset
- // new_off = old_off + (old_jump - new_jump)
-
- l.add r6,r6,r4 // (orig_off + old_jump)
- l.sub r6,r6,r5 // (orig_off + old_jump) - new_jump
- l.srli r6,r6,6 // new offset shifted right 2
-
- // r6 is new jump offset
- l.lwz r4,(TRAMP_SLOT_2+0x0)(r3) // load jump instruction
- l.srli r4,r4,16
- l.andi r4,r4,0xfc00 // get opcode part
- l.slli r4,r4,16
- l.or r6,r4,r6 // l.b(n)f new offset
- l.sw TRAMP_SLOT_2(r3),r6 // write it back
-
- /* we need to add l.j to EEA + 0x8 */
- tophys (r4,r2) // may not be needed (due to shifts down_
- l.addi r4,r4,(0x8 - 0x8) // jump target = r2 + 0x8 (compensate for 0x8)
- // jump position = r5 + 0x8 (0x8 compensated)
- l.sub r4,r4,r5 // jump offset = target - new_position + 0x8
-
- l.slli r4,r4,4 // the amount of info in imediate of jump
- l.srli r4,r4,6 // jump instruction with offset
- l.sw TRAMP_SLOT_4(r3),r4 // write it to 4th slot
-
- /* fallthrough */
-
-trampoline_out:
- // set up new EPC to point to our trampoline code
- LOAD_SYMBOL_2_GPR(r5,_immu_trampoline)
- l.mtspr r0,r5,SPR_EPCR_BASE
-
- // immu_trampoline is (4x) CACHE_LINE aligned
- // and only 6 instructions long,
- // so we need to invalidate only 2 lines
-
- /* Establish cache block size
- If BS=0, 16;
- If BS=1, 32;
- r14 contain block size
- */
- l.mfspr r21,r0,SPR_ICCFGR
- l.andi r21,r21,SPR_ICCFGR_CBS
- l.srli r21,r21,7
- l.ori r23,r0,16
- l.sll r14,r23,r21
-
- l.mtspr r0,r5,SPR_ICBIR
- l.add r5,r5,r14
- l.mtspr r0,r5,SPR_ICBIR
-
- l.jr r9
- l.nop
-
-
/*
- * DSCR: prints a string referenced by r3.
+ * DESC: Prints ASCII character stored in r7
*
- * PRMS: r3 - address of the first character of null
- * terminated string to be printed
+ * PRMS: r7 - a 32-bit value with an ASCII character in the first byte
+ * position.
*
- * PREQ: UART at UART_BASE_ADD has to be initialized
+ * PREQ: The UART at UART_BASE_ADD has to be initialized
*
- * POST: caller should be aware that r3, r9 are changed
+ * POST: internally used but restores:
+ * r4 - to store UART_BASE_ADD
+ * r5 - for loading OFF_TXFULL / THRE,TEMT
+ * r6 - for storing bitmask (SERIAL_8250)
*/
-ENTRY(_emergency_print)
+ENTRY(_emergency_putc)
EMERGENCY_PRINT_STORE_GPR4
EMERGENCY_PRINT_STORE_GPR5
EMERGENCY_PRINT_STORE_GPR6
- EMERGENCY_PRINT_STORE_GPR7
-2:
- l.lbz r7,0(r3)
- l.sfeq r7,r0
- l.bf 9f
- l.nop
-// putc:
l.movhi r4,hi(UART_BASE_ADD)
+ l.ori r4,r4,lo(UART_BASE_ADD)
+
+#if defined(CONFIG_SERIAL_LITEUART)
+ /* Check OFF_TXFULL status */
+1: l.lwz r5,4(r4)
+ l.andi r5,r5,0xff
+ l.sfnei r5,0
+ l.bf 1b
+ l.nop
+ /* Write character */
+ l.andi r7,r7,0xff
+ l.sw 0(r4),r7
+#elif defined(CONFIG_SERIAL_8250)
+ /* Check UART LSR THRE (hold) bit */
l.addi r6,r0,0x20
1: l.lbz r5,5(r4)
l.andi r5,r5,0x20
l.sfeq r5,r6
l.bnf 1b
- l.nop
+ l.nop
+ /* Write character */
l.sb 0(r4),r7
+ /* Check UART LSR THRE|TEMT (hold, empty) bits */
l.addi r6,r0,0x60
1: l.lbz r5,5(r4)
l.andi r5,r5,0x60
l.sfeq r5,r6
l.bnf 1b
- l.nop
+ l.nop
+#endif
+ EMERGENCY_PRINT_LOAD_GPR6
+ EMERGENCY_PRINT_LOAD_GPR5
+ EMERGENCY_PRINT_LOAD_GPR4
+ l.jr r9
+ l.nop
+
+/*
+ * DSCR: prints a string referenced by r3.
+ *
+ * PRMS: r3 - address of the first character of null
+ * terminated string to be printed
+ *
+ * PREQ: UART at UART_BASE_ADD has to be initialized
+ *
+ * POST: caller should be aware that r3, r9 are changed
+ */
+ENTRY(_emergency_print)
+ EMERGENCY_PRINT_STORE_GPR7
+ EMERGENCY_PRINT_STORE_GPR9
+
+ /* Load character to r7, check for null terminator */
+2: l.lbz r7,0(r3)
+ l.sfeqi r7,0x0
+ l.bf 9f
+ l.nop
+
+ l.jal _emergency_putc
+ l.nop
/* next character */
l.j 2b
- l.addi r3,r3,0x1
+ l.addi r3,r3,0x1
9:
+ EMERGENCY_PRINT_LOAD_GPR9
EMERGENCY_PRINT_LOAD_GPR7
- EMERGENCY_PRINT_LOAD_GPR6
- EMERGENCY_PRINT_LOAD_GPR5
- EMERGENCY_PRINT_LOAD_GPR4
l.jr r9
- l.nop
+ l.nop
+/*
+ * DSCR: prints a number in r3 in hex.
+ *
+ * PRMS: r3 - a 32-bit unsigned integer
+ *
+ * PREQ: UART at UART_BASE_ADD has to be initialized
+ *
+ * POST: caller should be aware that r3, r9 are changed
+ */
ENTRY(_emergency_print_nr)
- EMERGENCY_PRINT_STORE_GPR4
- EMERGENCY_PRINT_STORE_GPR5
- EMERGENCY_PRINT_STORE_GPR6
EMERGENCY_PRINT_STORE_GPR7
EMERGENCY_PRINT_STORE_GPR8
+ EMERGENCY_PRINT_STORE_GPR9
l.addi r8,r0,32 // shift register
@@ -1609,58 +1449,39 @@ ENTRY(_emergency_print_nr)
/* don't skip the last zero if number == 0x0 */
l.sfeqi r8,0x4
l.bf 2f
- l.nop
+ l.nop
l.sfeq r7,r0
l.bf 1b
- l.nop
+ l.nop
2:
l.srl r7,r3,r8
l.andi r7,r7,0xf
l.sflts r8,r0
- l.bf 9f
+ l.bf 9f
+ /* Numbers greater than 9 translate to a-f */
l.sfgtui r7,0x9
l.bnf 8f
- l.nop
+ l.nop
l.addi r7,r7,0x27
-8:
- l.addi r7,r7,0x30
-// putc:
- l.movhi r4,hi(UART_BASE_ADD)
-
- l.addi r6,r0,0x20
-1: l.lbz r5,5(r4)
- l.andi r5,r5,0x20
- l.sfeq r5,r6
- l.bnf 1b
- l.nop
-
- l.sb 0(r4),r7
-
- l.addi r6,r0,0x60
-1: l.lbz r5,5(r4)
- l.andi r5,r5,0x60
- l.sfeq r5,r6
- l.bnf 1b
- l.nop
+ /* Convert to ascii and output character */
+8: l.jal _emergency_putc
+ l.addi r7,r7,0x30
/* next character */
l.j 2b
l.addi r8,r8,-0x4
9:
+ EMERGENCY_PRINT_LOAD_GPR9
EMERGENCY_PRINT_LOAD_GPR8
EMERGENCY_PRINT_LOAD_GPR7
- EMERGENCY_PRINT_LOAD_GPR6
- EMERGENCY_PRINT_LOAD_GPR5
- EMERGENCY_PRINT_LOAD_GPR4
l.jr r9
- l.nop
-
+ l.nop
/*
* This should be used for debugging only.
@@ -1685,7 +1506,9 @@ ENTRY(_emergency_print_nr)
ENTRY(_early_uart_init)
l.movhi r3,hi(UART_BASE_ADD)
+ l.ori r3,r3,lo(UART_BASE_ADD)
+#if defined(CONFIG_SERIAL_8250)
l.addi r4,r0,0x7
l.sb 0x2(r3),r4
@@ -1703,9 +1526,10 @@ ENTRY(_early_uart_init)
l.addi r4,r0,((UART_DIVISOR) & 0x000000ff)
l.sb UART_DLL(r3),r4
l.sb 0x3(r3),r5
+#endif
l.jr r9
- l.nop
+ l.nop
.align 0x1000
.global _secondary_evbar
@@ -1720,13 +1544,13 @@ _secondary_evbar:
.section .rodata
_string_unhandled_exception:
- .string "\n\rRunarunaround: Unhandled exception 0x\0"
+ .string "\r\nRunarunaround: Unhandled exception 0x\0"
_string_epc_prefix:
.string ": EPC=0x\0"
_string_nl:
- .string "\n\r\0"
+ .string "\r\n\0"
/* ========================================[ page aligned structures ]=== */
diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c
index 3c0c91bcdcba..1d4c0921aafa 100644
--- a/arch/openrisc/kernel/process.c
+++ b/arch/openrisc/kernel/process.c
@@ -52,6 +52,8 @@ void machine_restart(char *cmd)
{
do_kernel_restart(cmd);
+ __asm__("l.nop 13");
+
/* Give a grace period for failure to restart of 1s */
mdelay(1000);
@@ -61,6 +63,16 @@ void machine_restart(char *cmd)
}
/*
+ * This is used if pm_power_off has not been set by a power management
+ * driver, in this case we can assume we are on a simulator. On
+ * OpenRISC simulators l.nop 1 will trigger the simulator exit.
+ */
+static void default_power_off(void)
+{
+ __asm__("l.nop 1");
+}
+
+/*
* Similar to machine_power_off, but don't shut off power. Add code
* here to freeze the system for e.g. post-mortem debug purpose when
* possible. This halt has nothing to do with the idle halt.
@@ -75,7 +87,10 @@ void machine_halt(void)
void machine_power_off(void)
{
printk(KERN_INFO "*** MACHINE POWER OFF ***\n");
- __asm__("l.nop 1");
+ if (pm_power_off != NULL)
+ pm_power_off();
+ else
+ default_power_off();
}
/*
@@ -89,7 +104,7 @@ void arch_cpu_idle(void)
mtspr(SPR_PMR, mfspr(SPR_PMR) | SPR_PMR_DME);
}
-void (*pm_power_off) (void) = machine_power_off;
+void (*pm_power_off)(void) = NULL;
EXPORT_SYMBOL(pm_power_off);
/*
diff --git a/arch/openrisc/kernel/time.c b/arch/openrisc/kernel/time.c
index 6d18989d63d0..8e26c1af5441 100644
--- a/arch/openrisc/kernel/time.c
+++ b/arch/openrisc/kernel/time.c
@@ -23,6 +23,7 @@
#include <linux/of_clk.h>
#include <asm/cpuinfo.h>
+#include <asm/time.h>
/* Test the timer ticks to count, used in sync routine */
inline void openrisc_timer_set(unsigned long count)
@@ -61,7 +62,7 @@ static int openrisc_timer_set_next_event(unsigned long delta,
* timers) we cannot enable the PERIODIC feature. The tick timer can run using
* one-shot events, so no problem.
*/
-DEFINE_PER_CPU(struct clock_event_device, clockevent_openrisc_timer);
+static DEFINE_PER_CPU(struct clock_event_device, clockevent_openrisc_timer);
void openrisc_clockevent_init(void)
{
diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
index 0446a3c34372..fd9a0f2b66c4 100644
--- a/arch/openrisc/kernel/traps.c
+++ b/arch/openrisc/kernel/traps.c
@@ -34,11 +34,11 @@
#include <asm/unwinder.h>
#include <asm/sections.h>
-int kstack_depth_to_print = 0x180;
+static int kstack_depth_to_print = 0x180;
int lwa_flag;
-unsigned long __user *lwa_addr;
+static unsigned long __user *lwa_addr;
-void print_trace(void *data, unsigned long addr, int reliable)
+static void print_trace(void *data, unsigned long addr, int reliable)
{
const char *loglvl = data;
@@ -46,6 +46,14 @@ void print_trace(void *data, unsigned long addr, int reliable)
(void *) addr);
}
+static void print_data(unsigned long base_addr, unsigned long word, int i)
+{
+ if (i == 0)
+ printk("(%08lx:)\t%08lx", base_addr + (i * 4), word);
+ else
+ printk(" %08lx:\t%08lx", base_addr + (i * 4), word);
+}
+
/* displays a short stack trace */
void show_stack(struct task_struct *task, unsigned long *esp, const char *loglvl)
{
@@ -99,22 +107,36 @@ void show_registers(struct pt_regs *regs)
printk("\nStack: ");
show_stack(NULL, (unsigned long *)esp, KERN_EMERG);
+ if (esp < PAGE_OFFSET)
+ goto bad_stack;
+
+ printk("\n");
+ for (i = -8; i < 24; i += 1) {
+ unsigned long word;
+
+ if (__get_user(word, &((unsigned long *)esp)[i])) {
+bad_stack:
+ printk(" Bad Stack value.");
+ break;
+ }
+
+ print_data(esp, word, i);
+ }
+
printk("\nCode: ");
if (regs->pc < PAGE_OFFSET)
goto bad;
- for (i = -24; i < 24; i++) {
- unsigned char c;
- if (__get_user(c, &((unsigned char *)regs->pc)[i])) {
+ for (i = -6; i < 6; i += 1) {
+ unsigned long word;
+
+ if (__get_user(word, &((unsigned long *)regs->pc)[i])) {
bad:
printk(" Bad PC value.");
break;
}
- if (i == 0)
- printk("(%02x) ", c);
- else
- printk("%02x ", c);
+ print_data(regs->pc, word, i);
}
}
printk("\n");
@@ -185,13 +207,11 @@ void nommu_dump_state(struct pt_regs *regs,
printk("\nCode: ");
for (i = -24; i < 24; i++) {
- unsigned char c;
- c = ((unsigned char *)(__pa(regs->pc)))[i];
+ unsigned long word;
+
+ word = ((unsigned long *)(__pa(regs->pc)))[i];
- if (i == 0)
- printk("(%02x) ", c);
- else
- printk("%02x ", c);
+ print_data(regs->pc, word, i);
}
printk("\n");
}
@@ -215,16 +235,7 @@ void __noreturn die(const char *str, struct pt_regs *regs, long err)
make_task_dead(SIGSEGV);
}
-/* This is normally the 'Oops' routine */
-void die_if_kernel(const char *str, struct pt_regs *regs, long err)
-{
- if (user_mode(regs))
- return;
-
- die(str, regs, err);
-}
-
-void unhandled_exception(struct pt_regs *regs, int ea, int vector)
+asmlinkage void unhandled_exception(struct pt_regs *regs, int ea, int vector)
{
printk("Unable to handle exception at EA =0x%x, vector 0x%x",
ea, vector);