Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[POWERPC] Early serial debug support for PPC44x

This adds support for early serial debugging via the built in
port on IBM/AMCC PowerPC 44x CPUs. It uses a bolted TLB entry in
address space 1 for the UART's mapping, allowing robust debugging both
before and after the initialization of the MMU.

Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>

authored by

David Gibson and committed by
Paul Mackerras
d9b55a03 f6dfc805

+97 -26
+18 -4
arch/powerpc/Kconfig.debug
··· 139 139 Say Y here to see progress messages from the boot firmware in text 140 140 mode. Requires either BootX or Open Firmware. 141 141 142 - config SERIAL_TEXT_DEBUG 143 - bool "Support for early boot texts over serial port" 144 - depends on 4xx 145 - 146 142 config PPC_EARLY_DEBUG 147 143 bool "Early debugging (dangerous)" 148 144 ··· 203 207 help 204 208 Select this to enable early debugging for Celleb with Beat. 205 209 210 + config PPC_EARLY_DEBUG_44x 211 + bool "Early serial debugging for IBM/AMCC 44x CPUs" 212 + depends on 44x 213 + select PPC_UDBG_16550 214 + help 215 + Select this to enable early debugging for IBM 44x chips via the 216 + inbuilt serial port. 217 + 206 218 endchoice 219 + 220 + config PPC_EARLY_DEBUG_44x_PHYSLOW 221 + hex "Low 32 bits of early debug UART physical address" 222 + depends PPC_EARLY_DEBUG_44x 223 + default "0x40000200" 224 + 225 + config PPC_EARLY_DEBUG_44x_PHYSHIGH 226 + hex "EPRN of early debug UART physical address" 227 + depends PPC_EARLY_DEBUG_44x 228 + default "0x1" 207 229 208 230 endmenu
+13 -21
arch/powerpc/kernel/head_44x.S
··· 172 172 isync 173 173 174 174 4: 175 - #ifdef CONFIG_SERIAL_TEXT_DEBUG 176 - /* 177 - * Add temporary UART mapping for early debug. 178 - * We can map UART registers wherever we want as long as they don't 179 - * interfere with other system mappings (e.g. with pinned entries). 180 - * For an example of how we handle this - see ocotea.h. --ebs 181 - */ 175 + #ifdef CONFIG_PPC_EARLY_DEBUG_44x 176 + /* Add UART mapping for early debug. */ 177 + 182 178 /* pageid fields */ 183 - lis r3,UART0_IO_BASE@h 184 - ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K 179 + lis r3,PPC44x_EARLY_DEBUG_VIRTADDR@h 180 + ori r3,r3,PPC44x_TLB_VALID|PPC44x_TLB_TS|PPC44x_TLB_64K 185 181 186 182 /* xlat fields */ 187 - lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */ 188 - #ifndef CONFIG_440EP 189 - ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */ 190 - #endif 183 + lis r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h 184 + ori r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH 191 185 192 186 /* attrib fields */ 193 - li r5,0 194 - ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G) 187 + li r5,(PPC44x_TLB_SW|PPC44x_TLB_SR|PPC44x_TLB_I|PPC44x_TLB_G) 188 + li r0,62 /* TLB slot 0 */ 195 189 196 - li r0,0 /* TLB slot 0 */ 197 - 198 - tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ 199 - tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ 200 - tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ 190 + tlbwe r3,r0,PPC44x_TLB_PAGEID 191 + tlbwe r4,r0,PPC44x_TLB_XLAT 192 + tlbwe r5,r0,PPC44x_TLB_ATTRIB 201 193 202 194 /* Force context change */ 203 195 isync 204 - #endif /* CONFIG_SERIAL_TEXT_DEBUG */ 196 + #endif /* CONFIG_PPC_EARLY_DEBUG_44x */ 205 197 206 198 /* Establish the interrupt vector offsets */ 207 199 SET_IVOR(0, CriticalInput);
-1
arch/powerpc/kernel/of_platform.c
··· 29 29 #include <asm/ppc-pci.h> 30 30 #include <asm/atomic.h> 31 31 32 - 33 32 /* 34 33 * The list of OF IDs below is used for matching bus types in the 35 34 * system whose devices are to be exposed as of_platform_devices.
+3
arch/powerpc/kernel/udbg.c
··· 51 51 udbg_init_pas_realmode(); 52 52 #elif defined(CONFIG_BOOTX_TEXT) 53 53 udbg_init_btext(); 54 + #elif defined(CONFIG_PPC_EARLY_DEBUG_44x) 55 + /* PPC44x debug */ 56 + udbg_init_44x_as1(); 54 57 #endif 55 58 } 56 59
+23
arch/powerpc/kernel/udbg_16550.c
··· 191 191 udbg_getc_poll = NULL; 192 192 } 193 193 #endif /* CONFIG_PPC_MAPLE */ 194 + 195 + #ifdef CONFIG_PPC_EARLY_DEBUG_44x 196 + #include <platforms/44x/44x.h> 197 + 198 + static void udbg_44x_as1_putc(char c) 199 + { 200 + if (udbg_comport) { 201 + while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0) 202 + /* wait for idle */; 203 + as1_writeb(c, &udbg_comport->thr); eieio(); 204 + if (c == '\n') 205 + udbg_44x_as1_putc('\r'); 206 + } 207 + } 208 + 209 + void __init udbg_init_44x_as1(void) 210 + { 211 + udbg_comport = 212 + (volatile struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR; 213 + 214 + udbg_putc = udbg_44x_as1_putc; 215 + } 216 + #endif /* CONFIG_PPC_EARLY_DEBUG_44x */
+2
arch/powerpc/platforms/44x/44x.h
··· 1 1 #ifndef __POWERPC_PLATFORMS_44X_44X_H 2 2 #define __POWERPC_PLATFORMS_44X_44X_H 3 3 4 + extern u8 as1_readb(volatile u8 __iomem *addr); 5 + extern void as1_writeb(u8 data, volatile u8 __iomem *addr); 4 6 extern void ppc44x_reset_system(char *cmd); 5 7 6 8 #endif /* __POWERPC_PLATFORMS_44X_44X_H */
+31
arch/powerpc/platforms/44x/misc_44x.S
··· 15 15 .text 16 16 17 17 /* 18 + * Do an IO access in AS1 19 + */ 20 + _GLOBAL(as1_readb) 21 + mfmsr r7 22 + ori r0,r7,MSR_DS 23 + sync 24 + mtmsr r0 25 + sync 26 + isync 27 + lbz r3,0(r3) 28 + sync 29 + mtmsr r7 30 + sync 31 + isync 32 + blr 33 + 34 + _GLOBAL(as1_writeb) 35 + mfmsr r7 36 + ori r0,r7,MSR_DS 37 + sync 38 + mtmsr r0 39 + sync 40 + isync 41 + stb r3,0(r4) 42 + sync 43 + mtmsr r7 44 + sync 45 + isync 46 + blr 47 + 48 + /* 18 49 * void ppc44x_reset_system(char *cmd) 19 50 * 20 51 * At present, this routine just applies a system reset.
+6
include/asm-powerpc/mmu-44x.h
··· 64 64 65 65 #endif /* !__ASSEMBLY__ */ 66 66 67 + #ifndef CONFIG_PPC_EARLY_DEBUG_44x 67 68 #define PPC44x_EARLY_TLBS 1 69 + #else 70 + #define PPC44x_EARLY_TLBS 2 71 + #define PPC44x_EARLY_DEBUG_VIRTADDR (ASM_CONST(0xf0000000) \ 72 + | (ASM_CONST(CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW) & 0xffff)) 73 + #endif 68 74 69 75 /* Size of the TLBs used for pinning in lowmem */ 70 76 #define PPC_PIN_SIZE (1 << 28) /* 256M */
+1
include/asm-powerpc/udbg.h
··· 47 47 extern void __init udbg_init_rtas_console(void); 48 48 extern void __init udbg_init_debug_beat(void); 49 49 extern void __init udbg_init_btext(void); 50 + extern void __init udbg_init_44x_as1(void); 50 51 51 52 #endif /* __KERNEL__ */ 52 53 #endif /* _ASM_POWERPC_UDBG_H */