DEBUG_KERNEL - notro/rpi-firmware GitHub Wiki
config DEBUG_KERNEL
bool "Kernel debugging"
config DEBUG_LL
bool "Kernel low-level debugging functions (read help!)"
depends on DEBUG_KERNEL
config DEBUG_BCM2835
bool "Kernel low-level debugging on BCM2835 PL011 UART"
depends on ARCH_BCM2835
select DEBUG_UART_PL01X
config DEBUG_LL_INCLUDE
string
default "debug/pl01x.S" if DEBUG_LL_UART_PL01X || DEBUG_UART_PL01X
default "mach/debug-macro.S"
config DEBUG_UART_PHYS
hex "Physical base address of debug UART"
default 0x20201000 if DEBUG_BCM2835
config DEBUG_UART_VIRT
hex "Virtual base address of debug UART"
default 0xf0201000 if DEBUG_BCM2835
config DEBUG_UNCOMPRESS
bool
depends on ARCH_MULTIPLATFORM || PLAT_SAMSUNG || ARM_SINGLE_ARMV7M
default y if DEBUG_LL && !DEBUG_OMAP2PLUS_UART && \
(!DEBUG_TEGRA_UART || !ZBOOT_ROM)
config UNCOMPRESS_INCLUDE
string
default "debug/uncompress.h" if ARCH_MULTIPLATFORM || ARCH_MSM || \
PLAT_SAMSUNG || ARM_SINGLE_ARMV7M || \
ARCH_SHMOBILE_LEGACY
default "mach/uncompress.h"
Uncompressing Linux... done, booting the kernel.
ARCH_BCM2835
kconfig
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_LL=y
CONFIG_DEBUG_BCM2835=y
CONFIG_DEBUG_LL_INCLUDE="debug/pl01x.S"
CONFIG_DEBUG_UART_PL01X=y
CONFIG_DEBUG_UART_PHYS=0x20201000
CONFIG_DEBUG_UART_VIRT=0xf0201000
CONFIG_DEBUG_UNCOMPRESS=y
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
arch/arm/configs/bcm2835_defconfig
CONFIG_DEBUG_LL=y
CONFIG_EARLY_PRINTK=y
arch/arm/include/debug/uncompress.h
#ifdef CONFIG_DEBUG_UNCOMPRESS
extern void putc(int c);
#else
static inline void putc(int c) {}
#endif
static inline void flush(void) {}
static inline void arch_decomp_setup(void) {}
arch/arm/boot/compressed/Makefile
ifeq ($(CONFIG_DEBUG_UNCOMPRESS),y)
OBJS += debug.o
endif
arch/arm/boot/compressed/debug.S
#include CONFIG_DEBUG_LL_INCLUDE
ENTRY(putc)
addruart r1, r2, r3
waituart r3, r1
senduart r0, r1
busyuart r3, r1
mov pc, lr
ENDPROC(putc)
arch/arm/include/debug/pl01x.S
#ifdef CONFIG_DEBUG_UART_PHYS
.macro addruart, rp, rv, tmp
ldr \rp, =CONFIG_DEBUG_UART_PHYS
ldr \rv, =CONFIG_DEBUG_UART_VIRT
.endm
#endif
.macro senduart,rd,rx
strb \rd, [\rx, #UART01x_DR]
.endm
.macro waituart,rd,rx
1001: ldr \rd, [\rx, #UART01x_FR]
ARM_BE8( rev \rd, \rd )
tst \rd, #UART01x_FR_TXFF
bne 1001b
.endm
.macro busyuart,rd,rx
1001: ldr \rd, [\rx, #UART01x_FR]
ARM_BE8( rev \rd, \rd )
tst \rd, #UART01x_FR_BUSY
bne 1001b
.endm
ARCH_BCM2708
kconfig
# CONFIG_DEBUG_LL is not set
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
CONFIG_UNCOMPRESS_INCLUDE="mach/uncompress.h"
arch/arm/mach-bcm2708/include/mach/uncompress.h
#include <linux/io.h>
#include <linux/amba/serial.h>
#include <mach/hardware.h>
#define UART_BAUD 115200
#define BCM2708_UART_DR __io(UART0_BASE + UART01x_DR)
#define BCM2708_UART_FR __io(UART0_BASE + UART01x_FR)
#define BCM2708_UART_IBRD __io(UART0_BASE + UART011_IBRD)
#define BCM2708_UART_FBRD __io(UART0_BASE + UART011_FBRD)
#define BCM2708_UART_LCRH __io(UART0_BASE + UART011_LCRH)
#define BCM2708_UART_CR __io(UART0_BASE + UART011_CR)
/*
* This does not append a newline
*/
static inline void putc(int c)
{
while (__raw_readl(BCM2708_UART_FR) & UART01x_FR_TXFF)
barrier();
__raw_writel(c, BCM2708_UART_DR);
}
static inline void flush(void)
{
int fr;
do {
fr = __raw_readl(BCM2708_UART_FR);
barrier();
} while ((fr & (UART011_FR_TXFE | UART01x_FR_BUSY)) != UART011_FR_TXFE);
}
static inline void arch_decomp_setup(void)
{
int temp, div, rem, frac;
temp = 16 * UART_BAUD;
div = UART0_CLOCK / temp;
rem = UART0_CLOCK % temp;
temp = (8 * rem) / UART_BAUD;
frac = (temp >> 1) + (temp & 1);
/* Make sure the UART is disabled before we start */
__raw_writel(0, BCM2708_UART_CR);
/* Set the baud rate */
__raw_writel(div, BCM2708_UART_IBRD);
__raw_writel(frac, BCM2708_UART_FBRD);
/* Set the UART to 8n1, FIFO enabled */
__raw_writel(UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN, BCM2708_UART_LCRH);
/* Enable the UART */
__raw_writel(UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_RXE,
BCM2708_UART_CR);
}
/*
* nothing to do
*/
#define arch_decomp_wdog()
arch/arm/mach-bcm2708/include/mach/debug-macro.S
#include <mach/platform.h>
.macro addruart, rp, rv, tmp
ldr \rp, =UART0_BASE
ldr \rv, =IO_ADDRESS(UART0_BASE)
.endm
#include <debug/pl01x.S>
void __init early_print(const char *str, ...)
{
extern void printascii(const char *);
char buf[256];
va_list ap;
va_start(ap, str);
vsnprintf(buf, sizeof(buf), str, ap);
va_end(ap);
#ifdef CONFIG_DEBUG_LL
printascii(buf);
#endif
printk("%s", buf);
}
obj-$(CONFIG_DEBUG_LL) += debug.o
#include CONFIG_DEBUG_LL_INCLUDE
.macro addruart_current, rx, tmp1, tmp2
addruart \tmp1, \tmp2, \rx
mrc p15, 0, \rx, c1, c0
tst \rx, #1
moveq \rx, \tmp1
movne \rx, \tmp2
.endm
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
ldrneb r1, [r0], #1
teqne r1, #0
bne 1b
ret lr
ENDPROC(printascii)