diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 17962452e31de6..3ac321006ab801 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -89,6 +89,7 @@ * x24 __primary_switch() .. relocate_kernel() current RELR displacement */ SYM_CODE_START(primary_entry) + bl trap_to_vmm bl preserve_boot_args bl init_kernel_el // w0=cpu_boot_mode adrp x23, __PHYS_OFFSET @@ -105,6 +106,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 */ diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 52518a606c06a2..3f44e029b07d55 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -44,6 +44,8 @@ #include "amba-pl011.h" +char __iomem *pl011_debug_addr; + #define UART_NR 14 #define SERIAL_AMBA_MAJOR 204 @@ -2752,6 +2754,9 @@ 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; + index = pl011_probe_dt_alias(index, dev); uap->old_cr = 0; diff --git a/include/linux/amba/serial.h b/include/linux/amba/serial.h index a1307b58cc2c6d..b2c74c7ca450de 100644 --- a/include/linux/amba/serial.h +++ b/include/linux/amba/serial.h @@ -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 { @@ -225,4 +227,13 @@ struct amba_pl011_data { }; #endif +extern char __iomem *pl011_debug_addr; /* save the pl011 debug mmio address, equal to base + UART011_IO_DEBUG */ +#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 diff --git a/init/main.c b/init/main.c index 1f4a209cad6a6d..2f8f4e0687ae4e 100644 --- a/init/main.c +++ b/init/main.c @@ -100,6 +100,7 @@ #include #include #include +#include #include #include @@ -1536,6 +1537,10 @@ static int __ref kernel_init(void *unused) outb(0x41, 0x80); #endif +#ifdef CONFIG_ARM64 + pl011_debug_trap(DEBUG_TRAP_VAL_END_BOOT); +#endif + if (ramdisk_execute_command) { ret = run_init_process(ramdisk_execute_command); if (!ret)