Skip to content

Commit 1d232cf

Browse files
jongwurbradford
authored andcommitted
debug: enable kernel boot up time measurement
To measure kernel boot up time, reserved region in pl011 is used as trap MMIO region to record kernel boot timestamp. For now, we trap at 2 point: the first is nearly the first instruction of kernel start; the second is just before call the init bin for userspace. These 2 points can cover the whole kernel boot time. If there is no pl011, the first write is still there but the second won't happen. Signed-off-by: Jianyong Wu <[email protected]>
1 parent cc2434f commit 1d232cf

File tree

4 files changed

+40
-0
lines changed

4 files changed

+40
-0
lines changed

arch/arm64/kernel/head.S

+16
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
* x24 __primary_switch() .. relocate_kernel() current RELR displacement
9090
*/
9191
SYM_CODE_START(primary_entry)
92+
bl trap_to_vmm
9293
bl preserve_boot_args
9394
bl init_kernel_el // w0=cpu_boot_mode
9495
adrp x23, __PHYS_OFFSET
@@ -105,6 +106,21 @@ SYM_CODE_START(primary_entry)
105106
b __primary_switch
106107
SYM_CODE_END(primary_entry)
107108

109+
/*
110+
* By writing to mmio region, trap to vmm to print timestamp,
111+
* but corrupt x7 and x8.
112+
* 0x9000f00 is debug region of pl011
113+
* 0x40 is the code specified in cloud hypervisor indicating the first debug
114+
* point of kernel.
115+
*/
116+
SYM_CODE_START(trap_to_vmm)
117+
movz x7, 0x0900, lsl 16
118+
add x7, x7, 0xf00
119+
mov x8, 0x40
120+
str w8, [x7]
121+
ret
122+
SYM_CODE_END(trap_to_vmm)
123+
108124
/*
109125
* Preserve the arguments passed by the bootloader in x0 .. x3
110126
*/

drivers/tty/serial/amba-pl011.c

+4
Original file line numberDiff line numberDiff line change
@@ -2691,6 +2691,10 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap,
26912691
if (IS_ERR(base))
26922692
return PTR_ERR(base);
26932693

2694+
pl011_debug_addr = (char __iomem *)base;
2695+
pl011_debug_addr += UART011_IO_DEBUG;
2696+
has_pl011 = 1;
2697+
26942698
index = pl011_probe_dt_alias(index, dev);
26952699

26962700
uap->port.dev = dev;

include/linux/amba/serial.h

+12
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@
206206
#define UART01x_RSR_ANY (UART01x_RSR_OE|UART01x_RSR_BE|UART01x_RSR_PE|UART01x_RSR_FE)
207207
#define UART01x_FR_MODEM_ANY (UART01x_FR_DCD|UART01x_FR_DSR|UART01x_FR_CTS)
208208

209+
#define UART011_IO_DEBUG 0xf00 /* used for debug I/O port emulation in VM */
210+
209211
#ifndef __ASSEMBLY__
210212
struct amba_device; /* in uncompress this is included but amba/bus.h is not */
211213
struct amba_pl010_data {
@@ -225,4 +227,14 @@ struct amba_pl011_data {
225227
};
226228
#endif
227229

230+
extern char __iomem *pl011_debug_addr; /* save the pl011 debug mmio address, equal to base + UART011_IO_DEBUG */
231+
extern int has_pl011;
232+
#define DEBUG_TRAP_VAL_END_BOOT 0x41 /* debug point at the end of kernel boot */
233+
234+
/* wrapper of tricking pl011 debug */
235+
static inline void pl011_debug_trap(char val)
236+
{
237+
writeb_relaxed(val, pl011_debug_addr);
238+
}
239+
228240
#endif

init/main.c

+8
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
#include <linux/init_syscalls.h>
101101
#include <linux/stackdepot.h>
102102
#include <net/net_namespace.h>
103+
#include <linux/amba/serial.h>
103104

104105
#include <asm/io.h>
105106
#include <asm/bugs.h>
@@ -112,6 +113,8 @@
112113

113114
#include <kunit/test.h>
114115

116+
char __iomem *pl011_debug_addr;
117+
int has_pl011 = 0;
115118
static int kernel_init(void *);
116119

117120
extern void init_IRQ(void);
@@ -1529,6 +1532,11 @@ static int __ref kernel_init(void *unused)
15291532
outb(0x41, 0x80);
15301533
#endif
15311534

1535+
#ifdef CONFIG_ARM64
1536+
if (has_pl011)
1537+
pl011_debug_trap(DEBUG_TRAP_VAL_END_BOOT);
1538+
#endif
1539+
15321540
if (ramdisk_execute_command) {
15331541
ret = run_init_process(ramdisk_execute_command);
15341542
if (!ret)

0 commit comments

Comments
 (0)