Commit 28bab059a23aac6bb129b307410e5b63e132a290
1 parent
6dea1ba1c8
Exists in
master
and in
7 other branches
unicore32 additional architecture files: low-level lib: ocd debug
This patch implements low-level debug libraries with On-Chip-Debugger hardware support. Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn> Acked-by: Arnd Bergmann <arnd@arndb.de>
Showing 4 changed files with 269 additions and 0 deletions Side-by-side Diff
arch/unicore32/include/mach/ocd.h
1 | +/* | |
2 | + * linux/arch/unicore32/include/mach/ocd.h | |
3 | + * | |
4 | + * Code specific to PKUnity SoC and UniCore ISA | |
5 | + * | |
6 | + * Copyright (C) 2001-2010 GUAN Xue-tao | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or modify | |
9 | + * it under the terms of the GNU General Public License version 2 as | |
10 | + * published by the Free Software Foundation. | |
11 | + */ | |
12 | + | |
13 | +#ifndef __MACH_PUV3_OCD_H__ | |
14 | +#define __MACH_PUV3_OCD_H__ | |
15 | + | |
16 | +#if defined(CONFIG_DEBUG_OCD) | |
17 | +static inline void ocd_putc(unsigned int c) | |
18 | +{ | |
19 | + int status, i = 0x2000000; | |
20 | + | |
21 | + do { | |
22 | + if (--i < 0) | |
23 | + return; | |
24 | + | |
25 | + asm volatile ("movc %0, p1.c0, #0" : "=r" (status)); | |
26 | + } while (status & 2); | |
27 | + | |
28 | + asm("movc p1.c1, %0, #1" : : "r" (c)); | |
29 | +} | |
30 | + | |
31 | +#define putc(ch) ocd_putc(ch) | |
32 | +#else | |
33 | +#define putc(ch) | |
34 | +#endif | |
35 | + | |
36 | +#endif |
arch/unicore32/kernel/debug-macro.S
1 | +/* | |
2 | + * linux/arch/unicore32/kernel/debug-macro.S | |
3 | + * | |
4 | + * Code specific to PKUnity SoC and UniCore ISA | |
5 | + * | |
6 | + * Copyright (C) 2001-2010 GUAN Xue-tao | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or modify | |
9 | + * it under the terms of the GNU General Public License version 2 as | |
10 | + * published by the Free Software Foundation. | |
11 | + * | |
12 | + * Debugging macro include header | |
13 | + */ | |
14 | +#include <generated/asm-offsets.h> | |
15 | +#include <mach/hardware.h> | |
16 | + | |
17 | + .macro put_word_ocd, rd, rx=r16 | |
18 | +1001: movc \rx, p1.c0, #0 | |
19 | + cand.a \rx, #2 | |
20 | + bne 1001b | |
21 | + movc p1.c1, \rd, #1 | |
22 | + .endm | |
23 | + | |
24 | +#ifdef CONFIG_DEBUG_OCD | |
25 | + /* debug using UniCore On-Chip-Debugger */ | |
26 | + .macro addruart, rx | |
27 | + .endm | |
28 | + | |
29 | + .macro senduart, rd, rx | |
30 | + put_word_ocd \rd, \rx | |
31 | + .endm | |
32 | + | |
33 | + .macro busyuart, rd, rx | |
34 | + .endm | |
35 | + | |
36 | + .macro waituart, rd, rx | |
37 | + .endm | |
38 | +#else | |
39 | +#define UART_CLK_DEFAULT 3686400 * 20 | |
40 | + /* Uartclk = MCLK/ 2, The MCLK on my board is 3686400 * 40 */ | |
41 | +#define BAUD_RATE_DEFAULT 115200 | |
42 | + /* The baud rate of the serial port */ | |
43 | + | |
44 | +#define UART_DIVISOR_DEFAULT (UART_CLK_DEFAULT \ | |
45 | + / (16 * BAUD_RATE_DEFAULT) - 1) | |
46 | + | |
47 | + .macro addruart,rx | |
48 | + mrc p0, #0, \rx, c1, c0 | |
49 | + tst \rx, #1 @ MMU enabled? | |
50 | + moveq \rx, #0xee000000 @ physical base address | |
51 | + movne \rx, #0x6e000000 @ virtual address | |
52 | + | |
53 | + @ We probe for the active serial port here | |
54 | + @ However, now we assume UART0 is active: epip4d | |
55 | + @ We assume r1 and r2 can be clobbered. | |
56 | + | |
57 | + movl r2, #UART_DIVISOR_DEFAULT | |
58 | + mov r1, #0x80 | |
59 | + str r1, [\rx, #UART_LCR_OFFSET] | |
60 | + and r1, r2, #0xff00 | |
61 | + mov r1, r1, lsr #8 | |
62 | + str r1, [\rx, #UART_DLH_OFFSET] | |
63 | + and r1, r2, #0xff | |
64 | + str r1, [\rx, #UART_DLL_OFFSET] | |
65 | + mov r1, #0x7 | |
66 | + str r1, [\rx, #UART_FCR_OFFSET] | |
67 | + mov r1, #0x3 | |
68 | + str r1, [\rx, #UART_LCR_OFFSET] | |
69 | + mov r1, #0x0 | |
70 | + str r1, [\rx, #UART_IER_OFFSET] | |
71 | + .endm | |
72 | + | |
73 | + .macro senduart,rd,rx | |
74 | + str \rd, [\rx, #UART_THR_OFFSET] | |
75 | + .endm | |
76 | + | |
77 | + .macro waituart,rd,rx | |
78 | +1001: ldr \rd, [\rx, #UART_LSR_OFFSET] | |
79 | + tst \rd, #UART_LSR_THRE | |
80 | + beq 1001b | |
81 | + .endm | |
82 | + | |
83 | + .macro busyuart,rd,rx | |
84 | +1001: ldr \rd, [\rx, #UART_LSR_OFFSET] | |
85 | + tst \rd, #UART_LSR_TEMT | |
86 | + bne 1001b | |
87 | + .endm | |
88 | +#endif |
arch/unicore32/kernel/debug.S
1 | +/* | |
2 | + * linux/arch/unicore32/kernel/debug.S | |
3 | + * | |
4 | + * Code specific to PKUnity SoC and UniCore ISA | |
5 | + * | |
6 | + * Copyright (C) 2001-2010 GUAN Xue-tao | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or modify | |
9 | + * it under the terms of the GNU General Public License version 2 as | |
10 | + * published by the Free Software Foundation. | |
11 | + * | |
12 | + * 32-bit debugging code | |
13 | + */ | |
14 | +#include <linux/linkage.h> | |
15 | +#include <asm/assembler.h> | |
16 | + | |
17 | + .text | |
18 | + | |
19 | +/* | |
20 | + * Some debugging routines (useful if you've got MM problems and | |
21 | + * printk isn't working). For DEBUGGING ONLY!!! Do not leave | |
22 | + * references to these in a production kernel! | |
23 | + */ | |
24 | +#include "debug-macro.S" | |
25 | + | |
26 | +/* | |
27 | + * Useful debugging routines | |
28 | + */ | |
29 | +ENTRY(printhex8) | |
30 | + mov r1, #8 | |
31 | + b printhex | |
32 | +ENDPROC(printhex8) | |
33 | + | |
34 | +ENTRY(printhex4) | |
35 | + mov r1, #4 | |
36 | + b printhex | |
37 | +ENDPROC(printhex4) | |
38 | + | |
39 | +ENTRY(printhex2) | |
40 | + mov r1, #2 | |
41 | +printhex: adr r2, hexbuf | |
42 | + add r3, r2, r1 | |
43 | + mov r1, #0 | |
44 | + stb r1, [r3] | |
45 | +1: and r1, r0, #15 | |
46 | + mov r0, r0 >> #4 | |
47 | + csub.a r1, #10 | |
48 | + beg 2f | |
49 | + add r1, r1, #'0' - 'a' + 10 | |
50 | +2: add r1, r1, #'a' - 10 | |
51 | + stb.w r1, [r3+], #-1 | |
52 | + cxor.a r3, r2 | |
53 | + bne 1b | |
54 | + mov r0, r2 | |
55 | + b printascii | |
56 | +ENDPROC(printhex2) | |
57 | + | |
58 | + .ltorg | |
59 | + | |
60 | +ENTRY(printascii) | |
61 | + addruart r3 | |
62 | + b 2f | |
63 | +1: waituart r2, r3 | |
64 | + senduart r1, r3 | |
65 | + busyuart r2, r3 | |
66 | + cxor.a r1, #'\n' | |
67 | + cmoveq r1, #'\r' | |
68 | + beq 1b | |
69 | +2: cxor.a r0, #0 | |
70 | + beq 3f | |
71 | + ldb.w r1, [r0]+, #1 | |
72 | + cxor.a r1, #0 | |
73 | + bne 1b | |
74 | +3: mov pc, lr | |
75 | +ENDPROC(printascii) | |
76 | + | |
77 | +ENTRY(printch) | |
78 | + addruart r3 | |
79 | + mov r1, r0 | |
80 | + mov r0, #0 | |
81 | + b 1b | |
82 | +ENDPROC(printch) | |
83 | + | |
84 | +hexbuf: .space 16 |
arch/unicore32/kernel/early_printk.c
1 | +/* | |
2 | + * linux/arch/unicore32/kernel/early_printk.c | |
3 | + * | |
4 | + * Code specific to PKUnity SoC and UniCore ISA | |
5 | + * | |
6 | + * Copyright (C) 2001-2010 GUAN Xue-tao | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or modify | |
9 | + * it under the terms of the GNU General Public License version 2 as | |
10 | + * published by the Free Software Foundation. | |
11 | + */ | |
12 | +#include <linux/console.h> | |
13 | +#include <linux/init.h> | |
14 | +#include <linux/string.h> | |
15 | +#include <mach/ocd.h> | |
16 | + | |
17 | +/* On-Chip-Debugger functions */ | |
18 | + | |
19 | +static void early_ocd_write(struct console *con, const char *s, unsigned n) | |
20 | +{ | |
21 | + while (*s && n-- > 0) { | |
22 | + if (*s == '\n') | |
23 | + ocd_putc((int)'\r'); | |
24 | + ocd_putc((int)*s); | |
25 | + s++; | |
26 | + } | |
27 | +} | |
28 | + | |
29 | +static struct console early_ocd_console = { | |
30 | + .name = "earlyocd", | |
31 | + .write = early_ocd_write, | |
32 | + .flags = CON_PRINTBUFFER, | |
33 | + .index = -1, | |
34 | +}; | |
35 | + | |
36 | +/* Direct interface for emergencies */ | |
37 | +static struct console *early_console = &early_ocd_console; | |
38 | + | |
39 | +static int __initdata keep_early; | |
40 | + | |
41 | +static int __init setup_early_printk(char *buf) | |
42 | +{ | |
43 | + if (!buf) | |
44 | + return 0; | |
45 | + | |
46 | + if (strstr(buf, "keep")) | |
47 | + keep_early = 1; | |
48 | + | |
49 | + if (!strncmp(buf, "ocd", 3)) | |
50 | + early_console = &early_ocd_console; | |
51 | + | |
52 | + if (keep_early) | |
53 | + early_console->flags &= ~CON_BOOT; | |
54 | + else | |
55 | + early_console->flags |= CON_BOOT; | |
56 | + register_console(early_console); | |
57 | + return 0; | |
58 | +} | |
59 | +early_param("earlyprintk", setup_early_printk); |