Skip to content

Commit

Permalink
debug: enable kernel boot up time measurement
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
jongwu authored and likebreath committed Mar 8, 2023
1 parent 44b63c0 commit cda1c67
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 0 deletions.
16 changes: 16 additions & 0 deletions arch/arm64/kernel/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
* x28 create_idmap() callee preserved temp register
*/
SYM_CODE_START(primary_entry)
bl trap_to_vmm
bl preserve_boot_args
bl init_kernel_el // w0=cpu_boot_mode
mov x20, x0
Expand All @@ -109,6 +110,21 @@ SYM_CODE_START(primary_entry)
b __primary_switch
SYM_CODE_END(primary_entry)

/*
* By writing to mmio region, trap to vmm to print timestamp,
* but corrupt x7 and x8.
* 0x9000f00 is debug region of pl011
* 0x40 is the code specified in cloud hypervisor indicating the first debug
* point of kernel.
*/
SYM_CODE_START(trap_to_vmm)
movz x7, 0x0900, lsl 16
add x7, x7, 0xf00
mov x8, 0x40
str w8, [x7]
ret
SYM_CODE_END(trap_to_vmm)

/*
* Preserve the arguments passed by the bootloader in x0 .. x3
*/
Expand Down
4 changes: 4 additions & 0 deletions drivers/tty/serial/amba-pl011.c
Original file line number Diff line number Diff line change
Expand Up @@ -2730,6 +2730,10 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap,
if (IS_ERR(base))
return PTR_ERR(base);

pl011_debug_addr = (char __iomem *)base;
pl011_debug_addr += UART011_IO_DEBUG;
has_pl011 = 1;

index = pl011_probe_dt_alias(index, dev);

uap->port.dev = dev;
Expand Down
12 changes: 12 additions & 0 deletions include/linux/amba/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@
#define UART01x_RSR_ANY (UART01x_RSR_OE|UART01x_RSR_BE|UART01x_RSR_PE|UART01x_RSR_FE)
#define UART01x_FR_MODEM_ANY (UART01x_FR_DCD|UART01x_FR_DSR|UART01x_FR_CTS)

#define UART011_IO_DEBUG 0xf00 /* used for debug I/O port emulation in VM */

#ifndef __ASSEMBLY__
struct amba_device; /* in uncompress this is included but amba/bus.h is not */
struct amba_pl010_data {
Expand All @@ -225,4 +227,14 @@ struct amba_pl011_data {
};
#endif

extern char __iomem *pl011_debug_addr; /* save the pl011 debug mmio address, equal to base + UART011_IO_DEBUG */
extern int has_pl011;
#define DEBUG_TRAP_VAL_END_BOOT 0x41 /* debug point at the end of kernel boot */

/* wrapper of tricking pl011 debug */
static inline void pl011_debug_trap(char val)
{
writeb_relaxed(val, pl011_debug_addr);
}

#endif
8 changes: 8 additions & 0 deletions init/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
#include <linux/stackdepot.h>
#include <linux/randomize_kstack.h>
#include <net/net_namespace.h>
#include <linux/amba/serial.h>

#include <asm/io.h>
#include <asm/bugs.h>
Expand All @@ -114,6 +115,8 @@

#include <kunit/test.h>

char __iomem *pl011_debug_addr;
int has_pl011 = 0;
static int kernel_init(void *);

extern void init_IRQ(void);
Expand Down Expand Up @@ -1552,6 +1555,11 @@ static int __ref kernel_init(void *unused)
outb(0x41, 0x80);
#endif

#ifdef CONFIG_ARM64
if (has_pl011)
pl011_debug_trap(DEBUG_TRAP_VAL_END_BOOT);
#endif

if (ramdisk_execute_command) {
ret = run_init_process(ramdisk_execute_command);
if (!ret)
Expand Down

0 comments on commit cda1c67

Please sign in to comment.