[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>
This commit is contained in:
Родитель
f6dfc80554
Коммит
d9b55a0361
|
@ -139,10 +139,6 @@ config BOOTX_TEXT
|
||||||
Say Y here to see progress messages from the boot firmware in text
|
Say Y here to see progress messages from the boot firmware in text
|
||||||
mode. Requires either BootX or Open Firmware.
|
mode. Requires either BootX or Open Firmware.
|
||||||
|
|
||||||
config SERIAL_TEXT_DEBUG
|
|
||||||
bool "Support for early boot texts over serial port"
|
|
||||||
depends on 4xx
|
|
||||||
|
|
||||||
config PPC_EARLY_DEBUG
|
config PPC_EARLY_DEBUG
|
||||||
bool "Early debugging (dangerous)"
|
bool "Early debugging (dangerous)"
|
||||||
|
|
||||||
|
@ -207,6 +203,24 @@ config PPC_EARLY_DEBUG_BEAT
|
||||||
help
|
help
|
||||||
Select this to enable early debugging for Celleb with Beat.
|
Select this to enable early debugging for Celleb with Beat.
|
||||||
|
|
||||||
|
config PPC_EARLY_DEBUG_44x
|
||||||
|
bool "Early serial debugging for IBM/AMCC 44x CPUs"
|
||||||
|
depends on 44x
|
||||||
|
select PPC_UDBG_16550
|
||||||
|
help
|
||||||
|
Select this to enable early debugging for IBM 44x chips via the
|
||||||
|
inbuilt serial port.
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
config PPC_EARLY_DEBUG_44x_PHYSLOW
|
||||||
|
hex "Low 32 bits of early debug UART physical address"
|
||||||
|
depends PPC_EARLY_DEBUG_44x
|
||||||
|
default "0x40000200"
|
||||||
|
|
||||||
|
config PPC_EARLY_DEBUG_44x_PHYSHIGH
|
||||||
|
hex "EPRN of early debug UART physical address"
|
||||||
|
depends PPC_EARLY_DEBUG_44x
|
||||||
|
default "0x1"
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -172,36 +172,28 @@ skpinv: addi r4,r4,1 /* Increment */
|
||||||
isync
|
isync
|
||||||
|
|
||||||
4:
|
4:
|
||||||
#ifdef CONFIG_SERIAL_TEXT_DEBUG
|
#ifdef CONFIG_PPC_EARLY_DEBUG_44x
|
||||||
/*
|
/* Add UART mapping for early debug. */
|
||||||
* Add temporary UART mapping for early debug.
|
|
||||||
* We can map UART registers wherever we want as long as they don't
|
|
||||||
* interfere with other system mappings (e.g. with pinned entries).
|
|
||||||
* For an example of how we handle this - see ocotea.h. --ebs
|
|
||||||
*/
|
|
||||||
/* pageid fields */
|
/* pageid fields */
|
||||||
lis r3,UART0_IO_BASE@h
|
lis r3,PPC44x_EARLY_DEBUG_VIRTADDR@h
|
||||||
ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K
|
ori r3,r3,PPC44x_TLB_VALID|PPC44x_TLB_TS|PPC44x_TLB_64K
|
||||||
|
|
||||||
/* xlat fields */
|
/* xlat fields */
|
||||||
lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */
|
lis r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h
|
||||||
#ifndef CONFIG_440EP
|
ori r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH
|
||||||
ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* attrib fields */
|
/* attrib fields */
|
||||||
li r5,0
|
li r5,(PPC44x_TLB_SW|PPC44x_TLB_SR|PPC44x_TLB_I|PPC44x_TLB_G)
|
||||||
ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G)
|
li r0,62 /* TLB slot 0 */
|
||||||
|
|
||||||
li r0,0 /* TLB slot 0 */
|
tlbwe r3,r0,PPC44x_TLB_PAGEID
|
||||||
|
tlbwe r4,r0,PPC44x_TLB_XLAT
|
||||||
tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
|
tlbwe r5,r0,PPC44x_TLB_ATTRIB
|
||||||
tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */
|
|
||||||
tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
|
|
||||||
|
|
||||||
/* Force context change */
|
/* Force context change */
|
||||||
isync
|
isync
|
||||||
#endif /* CONFIG_SERIAL_TEXT_DEBUG */
|
#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
|
||||||
|
|
||||||
/* Establish the interrupt vector offsets */
|
/* Establish the interrupt vector offsets */
|
||||||
SET_IVOR(0, CriticalInput);
|
SET_IVOR(0, CriticalInput);
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include <asm/ppc-pci.h>
|
#include <asm/ppc-pci.h>
|
||||||
#include <asm/atomic.h>
|
#include <asm/atomic.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The list of OF IDs below is used for matching bus types in the
|
* The list of OF IDs below is used for matching bus types in the
|
||||||
* system whose devices are to be exposed as of_platform_devices.
|
* system whose devices are to be exposed as of_platform_devices.
|
||||||
|
|
|
@ -51,6 +51,9 @@ void __init udbg_early_init(void)
|
||||||
udbg_init_pas_realmode();
|
udbg_init_pas_realmode();
|
||||||
#elif defined(CONFIG_BOOTX_TEXT)
|
#elif defined(CONFIG_BOOTX_TEXT)
|
||||||
udbg_init_btext();
|
udbg_init_btext();
|
||||||
|
#elif defined(CONFIG_PPC_EARLY_DEBUG_44x)
|
||||||
|
/* PPC44x debug */
|
||||||
|
udbg_init_44x_as1();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,3 +191,26 @@ void udbg_init_pas_realmode(void)
|
||||||
udbg_getc_poll = NULL;
|
udbg_getc_poll = NULL;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PPC_MAPLE */
|
#endif /* CONFIG_PPC_MAPLE */
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC_EARLY_DEBUG_44x
|
||||||
|
#include <platforms/44x/44x.h>
|
||||||
|
|
||||||
|
static void udbg_44x_as1_putc(char c)
|
||||||
|
{
|
||||||
|
if (udbg_comport) {
|
||||||
|
while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0)
|
||||||
|
/* wait for idle */;
|
||||||
|
as1_writeb(c, &udbg_comport->thr); eieio();
|
||||||
|
if (c == '\n')
|
||||||
|
udbg_44x_as1_putc('\r');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init udbg_init_44x_as1(void)
|
||||||
|
{
|
||||||
|
udbg_comport =
|
||||||
|
(volatile struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR;
|
||||||
|
|
||||||
|
udbg_putc = udbg_44x_as1_putc;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef __POWERPC_PLATFORMS_44X_44X_H
|
#ifndef __POWERPC_PLATFORMS_44X_44X_H
|
||||||
#define __POWERPC_PLATFORMS_44X_44X_H
|
#define __POWERPC_PLATFORMS_44X_44X_H
|
||||||
|
|
||||||
|
extern u8 as1_readb(volatile u8 __iomem *addr);
|
||||||
|
extern void as1_writeb(u8 data, volatile u8 __iomem *addr);
|
||||||
extern void ppc44x_reset_system(char *cmd);
|
extern void ppc44x_reset_system(char *cmd);
|
||||||
|
|
||||||
#endif /* __POWERPC_PLATFORMS_44X_44X_H */
|
#endif /* __POWERPC_PLATFORMS_44X_44X_H */
|
||||||
|
|
|
@ -14,6 +14,37 @@
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do an IO access in AS1
|
||||||
|
*/
|
||||||
|
_GLOBAL(as1_readb)
|
||||||
|
mfmsr r7
|
||||||
|
ori r0,r7,MSR_DS
|
||||||
|
sync
|
||||||
|
mtmsr r0
|
||||||
|
sync
|
||||||
|
isync
|
||||||
|
lbz r3,0(r3)
|
||||||
|
sync
|
||||||
|
mtmsr r7
|
||||||
|
sync
|
||||||
|
isync
|
||||||
|
blr
|
||||||
|
|
||||||
|
_GLOBAL(as1_writeb)
|
||||||
|
mfmsr r7
|
||||||
|
ori r0,r7,MSR_DS
|
||||||
|
sync
|
||||||
|
mtmsr r0
|
||||||
|
sync
|
||||||
|
isync
|
||||||
|
stb r3,0(r4)
|
||||||
|
sync
|
||||||
|
mtmsr r7
|
||||||
|
sync
|
||||||
|
isync
|
||||||
|
blr
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void ppc44x_reset_system(char *cmd)
|
* void ppc44x_reset_system(char *cmd)
|
||||||
*
|
*
|
||||||
|
|
|
@ -64,7 +64,13 @@ typedef struct {
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
#ifndef CONFIG_PPC_EARLY_DEBUG_44x
|
||||||
#define PPC44x_EARLY_TLBS 1
|
#define PPC44x_EARLY_TLBS 1
|
||||||
|
#else
|
||||||
|
#define PPC44x_EARLY_TLBS 2
|
||||||
|
#define PPC44x_EARLY_DEBUG_VIRTADDR (ASM_CONST(0xf0000000) \
|
||||||
|
| (ASM_CONST(CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW) & 0xffff))
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Size of the TLBs used for pinning in lowmem */
|
/* Size of the TLBs used for pinning in lowmem */
|
||||||
#define PPC_PIN_SIZE (1 << 28) /* 256M */
|
#define PPC_PIN_SIZE (1 << 28) /* 256M */
|
||||||
|
|
|
@ -47,6 +47,7 @@ extern void __init udbg_init_rtas_panel(void);
|
||||||
extern void __init udbg_init_rtas_console(void);
|
extern void __init udbg_init_rtas_console(void);
|
||||||
extern void __init udbg_init_debug_beat(void);
|
extern void __init udbg_init_debug_beat(void);
|
||||||
extern void __init udbg_init_btext(void);
|
extern void __init udbg_init_btext(void);
|
||||||
|
extern void __init udbg_init_44x_as1(void);
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
#endif /* _ASM_POWERPC_UDBG_H */
|
#endif /* _ASM_POWERPC_UDBG_H */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче