summaryrefslogtreecommitdiff
path: root/arch/arm/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/atags_parse.c7
-rw-r--r--arch/arm/kernel/debug.S47
-rw-r--r--arch/arm/kernel/early_printk.c16
-rw-r--r--arch/arm/kernel/entry-common.S9
-rw-r--r--arch/arm/kernel/setup.c10
-rw-r--r--arch/arm/kernel/traps.c28
6 files changed, 73 insertions, 44 deletions
diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c
index 98fbfd235ac8..c10a3e8ee998 100644
--- a/arch/arm/kernel/atags_parse.c
+++ b/arch/arm/kernel/atags_parse.c
@@ -196,11 +196,8 @@ setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr)
break;
}
- if (!mdesc) {
- early_print("\nError: unrecognized/unsupported machine ID"
- " (r1 = 0x%08x).\n\n", machine_nr);
- dump_machine_table(); /* does not return */
- }
+ if (!mdesc)
+ return NULL;
if (__atags_pointer)
tags = phys_to_virt(__atags_pointer);
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index ea9646cc2a0e..b795dc2408c0 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -55,7 +55,9 @@ ENDPROC(printhex4)
ENTRY(printhex2)
mov r1, #2
-printhex: adr r2, hexbuf
+printhex: adr r2, hexbuf_rel
+ ldr r3, [r2]
+ add r2, r2, r3
add r3, r2, r1
mov r1, #0
strb r1, [r3]
@@ -71,7 +73,11 @@ printhex: adr r2, hexbuf
b printascii
ENDPROC(printhex2)
-hexbuf: .space 16
+ .pushsection .bss
+hexbuf_addr: .space 16
+ .popsection
+ .align
+hexbuf_rel: .long hexbuf_addr - .
.ltorg
@@ -79,25 +85,28 @@ hexbuf: .space 16
ENTRY(printascii)
addruart_current r3, r1, r2
- b 2f
-1: waituart r2, r3
- senduart r1, r3
- busyuart r2, r3
- teq r1, #'\n'
- moveq r1, #'\r'
- beq 1b
-2: teq r0, #0
+1: teq r0, #0
ldrneb r1, [r0], #1
teqne r1, #0
- bne 1b
- ret lr
+ reteq lr
+2: teq r1, #'\n'
+ bne 3f
+ mov r1, #'\r'
+ waituart r2, r3
+ senduart r1, r3
+ busyuart r2, r3
+ mov r1, #'\n'
+3: waituart r2, r3
+ senduart r1, r3
+ busyuart r2, r3
+ b 1b
ENDPROC(printascii)
ENTRY(printch)
addruart_current r3, r1, r2
mov r1, r0
mov r0, #0
- b 1b
+ b 2b
ENDPROC(printch)
#ifdef CONFIG_MMU
@@ -115,16 +124,26 @@ ENTRY(printascii)
mov r1, r0
mov r0, #0x04 @ SYS_WRITE0
ARM( svc #0x123456 )
+#ifdef CONFIG_CPU_V7M
+ THUMB( bkpt #0xab )
+#else
THUMB( svc #0xab )
+#endif
ret lr
ENDPROC(printascii)
ENTRY(printch)
- adr r1, hexbuf
+ adr r1, hexbuf_rel
+ ldr r2, [r1]
+ add r1, r1, r2
strb r0, [r1]
mov r0, #0x03 @ SYS_WRITEC
ARM( svc #0x123456 )
+#ifdef CONFIG_CPU_V7M
+ THUMB( bkpt #0xab )
+#else
THUMB( svc #0xab )
+#endif
ret lr
ENDPROC(printch)
diff --git a/arch/arm/kernel/early_printk.c b/arch/arm/kernel/early_printk.c
index 43076536965c..9257736ec9fa 100644
--- a/arch/arm/kernel/early_printk.c
+++ b/arch/arm/kernel/early_printk.c
@@ -11,16 +11,20 @@
#include <linux/kernel.h>
#include <linux/console.h>
#include <linux/init.h>
+#include <linux/string.h>
-extern void printch(int);
+extern void printascii(const char *);
static void early_write(const char *s, unsigned n)
{
- while (n-- > 0) {
- if (*s == '\n')
- printch('\r');
- printch(*s);
- s++;
+ char buf[128];
+ while (n) {
+ unsigned l = min(n, sizeof(buf)-1);
+ memcpy(buf, s, l);
+ buf[l] = 0;
+ s += l;
+ n -= l;
+ printascii(buf);
}
}
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index ca3614dc6938..cc70bc5650a5 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -394,17 +394,8 @@ ENDPROC(sys_fstatfs64_wrapper)
* offset, we return EINVAL.
*/
sys_mmap2:
-#if PAGE_SHIFT > 12
- tst r5, #PGOFF_MASK
- moveq r5, r5, lsr #PAGE_SHIFT - 12
- streq r5, [sp, #4]
- beq sys_mmap_pgoff
- mov r0, #-EINVAL
- ret lr
-#else
str r5, [sp, #4]
b sys_mmap_pgoff
-#endif
ENDPROC(sys_mmap2)
#ifdef CONFIG_OABI_COMPAT
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8e9a3e40d949..fc40a2b40595 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -1069,6 +1069,16 @@ void __init setup_arch(char **cmdline_p)
mdesc = setup_machine_fdt(__atags_pointer);
if (!mdesc)
mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type);
+ if (!mdesc) {
+ early_print("\nError: invalid dtb and unrecognized/unsupported machine ID\n");
+ early_print(" r1=0x%08x, r2=0x%08x\n", __machine_arch_type,
+ __atags_pointer);
+ if (__atags_pointer)
+ early_print(" r2[]=%*ph\n", 16,
+ phys_to_virt(__atags_pointer));
+ dump_machine_table();
+ }
+
machine_desc = mdesc;
machine_name = mdesc->name;
dump_stack_set_arch_desc("%s", mdesc->name);
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 948c648fea00..0fcd82f01388 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -154,30 +154,26 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
set_fs(fs);
}
-static void dump_instr(const char *lvl, struct pt_regs *regs)
+static void __dump_instr(const char *lvl, struct pt_regs *regs)
{
unsigned long addr = instruction_pointer(regs);
const int thumb = thumb_mode(regs);
const int width = thumb ? 4 : 8;
- mm_segment_t fs;
char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
int i;
/*
- * We need to switch to kernel mode so that we can use __get_user
- * to safely read from kernel space. Note that we now dump the
- * code first, just in case the backtrace kills us.
+ * Note that we now dump the code first, just in case the backtrace
+ * kills us.
*/
- fs = get_fs();
- set_fs(KERNEL_DS);
for (i = -4; i < 1 + !!thumb; i++) {
unsigned int val, bad;
if (thumb)
- bad = __get_user(val, &((u16 *)addr)[i]);
+ bad = get_user(val, &((u16 *)addr)[i]);
else
- bad = __get_user(val, &((u32 *)addr)[i]);
+ bad = get_user(val, &((u32 *)addr)[i]);
if (!bad)
p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
@@ -188,8 +184,20 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
}
}
printk("%sCode: %s\n", lvl, str);
+}
- set_fs(fs);
+static void dump_instr(const char *lvl, struct pt_regs *regs)
+{
+ mm_segment_t fs;
+
+ if (!user_mode(regs)) {
+ fs = get_fs();
+ set_fs(KERNEL_DS);
+ __dump_instr(lvl, regs);
+ set_fs(fs);
+ } else {
+ __dump_instr(lvl, regs);
+ }
}
#ifdef CONFIG_ARM_UNWIND