From patchwork Sun Apr 28 23:02:07 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 16490 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f200.google.com (mail-qc0-f200.google.com [209.85.216.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 962062395E for ; Sun, 28 Apr 2013 23:03:51 +0000 (UTC) Received: by mail-qc0-f200.google.com with SMTP id j34sf8680315qco.3 for ; Sun, 28 Apr 2013 16:02:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:mime-version:x-beenthere:x-received:received-spf :x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:x-received:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-google-group-id:list-post:list-help:list-archive:list-unsubscribe; bh=4hA53nAk0W46UoJ3CAlw8ndA0127WtQK+BiM6Q5yQUg=; b=FLxuFGRdguPhXy8TpiBOhDMee9RHvSfaN7/XOlDtKyuiLoxdok6BozOGmQBztkd5K/ AghC2YlRLodsGgfjGhUOMbtO28KZE0FU862Gs4GlJEdX2ihYuRlOUxJMkoJiViLHBEsP uwD5sOzsED7R3wXTXvvimyxUgHaMUiseqiu3U7TwKX2sJutzHtc+n0OA3OqqSal1PO84 xQJy3y1/BQTjV8IaG+ZJRdwVFEfphJGtKsQZtdBlCWkbZjvqM/Gr7+/omXVwcUshMtts dp5HCl3JJHXFirgJ5tqqIxvoCEEaTLdQ3vSLzNoWpQS4vsv1zBuxgWupUmjUu/UIcfXO sVcw== X-Received: by 10.224.58.77 with SMTP id f13mr38766443qah.7.1367190170505; Sun, 28 Apr 2013 16:02:50 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.24.6 with SMTP id q6ls1899185qef.35.gmail; Sun, 28 Apr 2013 16:02:50 -0700 (PDT) X-Received: by 10.52.231.231 with SMTP id tj7mr27556669vdc.111.1367190170316; Sun, 28 Apr 2013 16:02:50 -0700 (PDT) Received: from mail-ve0-x22e.google.com (mail-ve0-x22e.google.com [2607:f8b0:400c:c01::22e]) by mx.google.com with ESMTPS id gr7si8965892vdc.77.2013.04.28.16.02.50 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 28 Apr 2013 16:02:50 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400c:c01::22e is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=2607:f8b0:400c:c01::22e; Received: by mail-ve0-f174.google.com with SMTP id b10so2646095vea.19 for ; Sun, 28 Apr 2013 16:02:50 -0700 (PDT) X-Received: by 10.52.69.109 with SMTP id d13mr5232825vdu.75.1367190170150; Sun, 28 Apr 2013 16:02:50 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.58.127.98 with SMTP id nf2csp33808veb; Sun, 28 Apr 2013 16:02:49 -0700 (PDT) X-Received: by 10.180.20.37 with SMTP id k5mr14037067wie.27.1367190169115; Sun, 28 Apr 2013 16:02:49 -0700 (PDT) Received: from mail-wi0-x234.google.com (mail-wi0-x234.google.com [2a00:1450:400c:c05::234]) by mx.google.com with ESMTPS id 16si2302580wjw.99.2013.04.28.16.02.48 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 28 Apr 2013 16:02:49 -0700 (PDT) Received-SPF: neutral (google.com: 2a00:1450:400c:c05::234 is neither permitted nor denied by best guess record for domain of julien.grall@linaro.org) client-ip=2a00:1450:400c:c05::234; Received: by mail-wi0-f180.google.com with SMTP id h11so2216774wiv.7 for ; Sun, 28 Apr 2013 16:02:48 -0700 (PDT) X-Received: by 10.180.20.37 with SMTP id k5mr14037048wie.27.1367190168692; Sun, 28 Apr 2013 16:02:48 -0700 (PDT) Received: from belegaer.uk.xensource.com. (firewall.ctxuk.citrix.com. [46.33.159.2]) by mx.google.com with ESMTPSA id k5sm18711393wiy.5.2013.04.28.16.02.47 for (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 28 Apr 2013 16:02:48 -0700 (PDT) From: Julien Grall To: xen-devel@lists.xen.org Cc: ian.campbell@citrix.com, patches@linaro.org, anthony.perard@citrix.com, stefano.stabellini@eu.citrix.com, Julien Grall Subject: [RFC 24/29] xen/arm: Don't use pl011 UART by default for early printk Date: Mon, 29 Apr 2013 00:02:07 +0100 Message-Id: <29c9b83854141ee04ee872e7477b8963e538be54.1367188423.git.julien.grall@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: References: X-Gm-Message-State: ALoCoQm8L1Te3oqSLKn863j0I68n/XEBAGZSjpQ3Pref295q1jSC55obzwhvTSkhXKeI6p70OTTp X-Original-Sender: julien.grall@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400c:c01::22e is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Add CONFIG_EARLY_PRINTK options in configs/arm{32,64}.mk to let the user to choose if he wants to have early output, ie before the console is initialized. This code is specific for each UART. When CONFIG_EARLY_PRINTK is enabled, Xen will only be able to run on a board with this UART. If a developper wants to add support for a new UART, he must implement the following function/variable: - early_uart_paddr: variable which contains the physical base address for the UART - early_uart_init: initialize the UART - early_uart_ready: check and wait until the UART can transmit a new character - early_uart_transmit: transmit a character For more details about the parameters of each function, see arm{32,64}/debug-pl011.S comments. Signed-off-by: Julien Grall --- config/arm32.mk | 11 ++++++ config/arm64.mk | 11 ++++++ xen/arch/arm/Makefile | 2 +- xen/arch/arm/Rules.mk | 9 +++++ xen/arch/arm/arm32/Makefile | 5 ++- xen/arch/arm/arm32/debug-pl011.S | 64 +++++++++++++++++++++++++++++++++ xen/arch/arm/arm32/debug.S | 33 +++++++++++++++++ xen/arch/arm/arm32/head.S | 66 ++++++++++++++++------------------ xen/arch/arm/arm64/Makefile | 3 ++ xen/arch/arm/arm64/debug-pl011.S | 64 +++++++++++++++++++++++++++++++++ xen/arch/arm/arm64/debug.S | 33 +++++++++++++++++ xen/arch/arm/arm64/head.S | 69 +++++++++++++++++------------------- xen/arch/arm/early_printk.c | 16 +-------- xen/include/asm-arm/config.h | 2 -- xen/include/asm-arm/early_printk.h | 2 +- 15 files changed, 298 insertions(+), 92 deletions(-) create mode 100644 xen/arch/arm/arm32/debug-pl011.S create mode 100644 xen/arch/arm/arm32/debug.S create mode 100644 xen/arch/arm/arm64/debug-pl011.S create mode 100644 xen/arch/arm/arm64/debug.S diff --git a/config/arm32.mk b/config/arm32.mk index f64f0c1..83a7767 100644 --- a/config/arm32.mk +++ b/config/arm32.mk @@ -7,6 +7,17 @@ CONFIG_ARM_$(XEN_OS) := y # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: CFLAGS += -marm +# Xen early debugging function +# This is helpful if you are debbuging code that executes before the console +# is initialized. +# Note that selecting this option will limit Xen to a single UART +# definition. Attempting to boot Xen image on a different platform *will +# not work*, so this option should not be enable for Xens that are +# intended to be portable. +# Possible value: +# - none: no early printk +# - pl011: printk with PL011 UART +CONFIG_EARLY_PRINTK := none HAS_PL011 := y # Use only if calling $(LD) directly. diff --git a/config/arm64.mk b/config/arm64.mk index b2457eb..6187df8 100644 --- a/config/arm64.mk +++ b/config/arm64.mk @@ -4,6 +4,17 @@ CONFIG_ARM_$(XEN_OS) := y CFLAGS += #-marm -march= -mcpu= etc +# Xen early debugging function +# This is helpful if you are debbuging code that executes before the console +# is initialized. +# Note that selecting this option will limit Xen to a single UART +# definition. Attempting to boot Xen image on a different platform *will +# not work*, so this option should not be enable for Xens that are +# intended to be portable. +# Possible value: +# - none: no early printk +# - pl011: printk with PL011 UART +CONFIG_EARLY_PRINTK := none HAS_PL011 := y # Use only if calling $(LD) directly. diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index 981ad78..498777b 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -2,7 +2,7 @@ subdir-$(arm32) += arm32 subdir-$(arm64) += arm64 subdir-y += platforms -obj-y += early_printk.o +obj-$(EARLY_PRINTK) += early_printk.o obj-y += cpu.o obj-y += domain.o obj-y += domctl.o diff --git a/xen/arch/arm/Rules.mk b/xen/arch/arm/Rules.mk index a0a14e0..2053b1e 100644 --- a/xen/arch/arm/Rules.mk +++ b/xen/arch/arm/Rules.mk @@ -36,3 +36,12 @@ endif ifneq ($(call cc-option,$(CC),-fvisibility=hidden,n),n) CFLAGS += -DGCC_HAS_VISIBILITY_ATTRIBUTE endif + +EARLY_PRINTK := n + +ifeq ($(CONFIG_EARLY_PRINTK), pl011) +EARLY_PRINTK := y +CONFIG_EARLY_PL011 := y +endif + +CFLAGS-$(EARLY_PRINTK) += -DEARLY_PRINTK diff --git a/xen/arch/arm/arm32/Makefile b/xen/arch/arm/arm32/Makefile index 1ad3364..6af8ca3 100644 --- a/xen/arch/arm/arm32/Makefile +++ b/xen/arch/arm/arm32/Makefile @@ -5,4 +5,7 @@ obj-y += mode_switch.o obj-y += proc-ca15.o obj-y += traps.o -obj-y += domain.o \ No newline at end of file +obj-y += domain.o + +obj-$(EARLY_PRINTK) += debug.o +obj-$(CONFIG_EARLY_PL011) += debug-pl011.o diff --git a/xen/arch/arm/arm32/debug-pl011.S b/xen/arch/arm/arm32/debug-pl011.S new file mode 100644 index 0000000..b00bb1f --- /dev/null +++ b/xen/arch/arm/arm32/debug-pl011.S @@ -0,0 +1,64 @@ +/* + * xen/arch/arm/arm32/debug-pl011.S + * + * PL011 specific debug code + * + * Copyright (c) 2013 Citrix Systems. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +#define PL011_UART_BASE_ADDRESS 0x1c090000 + +.globl early_uart_paddr +early_uart_paddr: .word PL011_UART_BASE_ADDRESS + +/* PL011 UART initialization + * r11: UART base address + * Clobber r1 */ +.globl early_uart_init +early_uart_init: + mov r1, #0x0 + str r1, [r11, #0x28] /* -> UARTFBRD (Baud divisor fraction) */ + mov r1, #0x4 /* 7.3728MHz / 0x4 == 16 * 115200 */ + str r1, [r11, #0x24] /* -> UARTIBRD (Baud divisor integer) */ + mov r1, #0x60 /* 8n1 */ + str r1, [r11, #0x2C] /* -> UARTLCR_H (Line control) */ + ldr r1, =0x00000301 /* RXE | TXE | UARTEN */ + str r1, [r11, #0x30] /* -> UARTCR (Control Register) */ + mov pc, lr + +/* PL011 UART wait UART to be ready to transmit + * r11: UART base address + * Clobber r2 */ +.globl early_uart_ready +early_uart_ready: + ldr r2, [r11, #0x18] /* <- UARTFR (Flag register) */ + tst r2, #0x8 /* Check BUSY bit */ + bne early_uart_ready /* Wait for the UART to be ready */ + mov pc, lr + +/* PL011 UART transmit character + * r2: character to transmit + * r11: UART base address */ +.globl early_uart_transmit +early_uart_transmit: + str r2, [r11] /* -> UARTDR (Data Register) */ + mov pc, lr + +/* + * Local variables: + * mode: ASM + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/arm/arm32/debug.S b/xen/arch/arm/arm32/debug.S new file mode 100644 index 0000000..af1b412 --- /dev/null +++ b/xen/arch/arm/arm32/debug.S @@ -0,0 +1,33 @@ +/* + * xen/arch/arm/arm32/debug.S + * + * Wrapper for early printk + * + * Julien Grall + * Copyright (c) 2013 Linaro Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +.globl early_putch +/* Print a character on the UART - this function is called by C + * r0: character to print */ +early_putch: + mov r1, fp /* Preserve fp aka r11 */ + mov r3, lr /* Save link register */ + ldr r11, =FIXMAP_ADDR(FIXMAP_CONSOLE) + bl early_uart_ready + mov r2, r0 + bl early_uart_transmit + mov fp, r1 /* Restore fp */ + mov pc, r3 diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S index 0b4cfde..55781cd 100644 --- a/xen/arch/arm/arm32/head.S +++ b/xen/arch/arm/arm32/head.S @@ -34,7 +34,7 @@ /* Macro to print a string to the UART, if there is one. * Clobbers r0-r3. */ -#ifdef EARLY_UART_ADDRESS +#ifdef EARLY_PRINTK #define PRINT(_s) \ adr r0, 98f ; \ bl puts ; \ @@ -42,9 +42,9 @@ 98: .asciz _s ; \ .align 2 ; \ 99: -#else +#else /* EARLY_PRINTK */ #define PRINT(s) -#endif +#endif /* !EARLY_PRINTK */ .arm @@ -106,8 +106,10 @@ past_zImage: bne 1b boot_cpu: -#ifdef EARLY_UART_ADDRESS - ldr r11, =EARLY_UART_ADDRESS /* r11 := UART base address */ +#ifdef EARLY_PRINTK + ldr r0, =early_uart_paddr /* VA of early_uart_paddr */ + add r0, r0, r10 /* PA of early_uart_paddr */ + ldr r11, [r0] /* r11 := UART base address */ teq r12, #0 /* CPU 0 sets up the UART too */ bleq init_uart PRINT("- CPU ") @@ -216,7 +218,7 @@ skip_bss: bne pt_ready /* console fixmap */ -#ifdef EARLY_UART_ADDRESS +#if defined(EARLY_PRINTK) ldr r1, =xen_fixmap add r1, r1, r10 /* r1 := paddr (xen_fixmap) */ mov r3, #0 @@ -279,7 +281,7 @@ pt_ready: paging: -#ifdef EARLY_UART_ADDRESS +#ifdef EARLY_PRINTK /* Use a virtual address to access the UART. */ ldr r11, =FIXMAP_ADDR(FIXMAP_CONSOLE) #endif @@ -345,58 +347,52 @@ fail: PRINT("- Boot failed -\r\n") 1: wfe b 1b -#ifdef EARLY_UART_ADDRESS -/* Bring up the UART. Specific to the PL011 UART. - * Clobbers r0-r2 */ +#ifdef EARLY_PRINTK +/* Bring up the UART. + * Clobbers r0-r3 */ init_uart: - mov r1, #0x0 - str r1, [r11, #0x28] /* -> UARTFBRD (Baud divisor fraction) */ - mov r1, #0x4 /* 7.3728MHz / 0x4 == 16 * 115200 */ - str r1, [r11, #0x24] /* -> UARTIBRD (Baud divisor integer) */ - mov r1, #0x60 /* 8n1 */ - str r1, [r11, #0x2C] /* -> UARTLCR_H (Line control) */ - ldr r1, =0x00000301 /* RXE | TXE | UARTEN */ - str r1, [r11, #0x30] /* -> UARTCR (Control Register) */ + mov r3, lr /* Save link register */ + bl early_uart_init adr r0, 1f - b puts + b 2f /* Jump to puts */ 1: .asciz "- UART enabled -\r\n" .align 4 -/* Print early debug messages. Specific to the PL011 UART. +/* Print early debug messages. * r0: Nul-terminated string to print. - * Clobbers r0-r2 */ + * Clobbers r0-r3 */ puts: - ldr r2, [r11, #0x18] /* <- UARTFR (Flag register) */ - tst r2, #0x8 /* Check BUSY bit */ - bne puts /* Wait for the UART to be ready */ + mov r3, lr /* Save link register */ +2: + bl early_uart_ready ldrb r2, [r0], #1 /* Load next char */ teq r2, #0 /* Exit on nul */ - moveq pc, lr - str r2, [r11] /* -> UARTDR (Data Register) */ - b puts + moveq pc, r3 + bl early_uart_transmit + b 2b /* Print a 32-bit number in hex. Specific to the PL011 UART. * r0: Number to print. - * clobbers r0-r3 */ + * clobbers r0-r4 */ putn: + mov r4, lr /* Save link register */ adr r1, hex mov r3, #8 -1: ldr r2, [r11, #0x18] /* <- UARTFR (Flag register) */ - tst r2, #0x8 /* Check BUSY bit */ - bne 1b /* Wait for the UART to be ready */ +1: + bl early_uart_ready and r2, r0, #0xf0000000 /* Mask off the top nybble */ ldrb r2, [r1, r2, lsr #28] /* Convert to a char */ - str r2, [r11] /* -> UARTDR (Data Register) */ + bl early_uart_transmit lsl r0, #4 /* Roll it through one nybble at a time */ subs r3, r3, #1 bne 1b - mov pc, lr + mov pc, r4 hex: .ascii "0123456789abcdef" .align 2 -#else /* EARLY_UART_ADDRESS */ +#else /* EARLY_PRINTK */ init_uart: .global early_puts @@ -404,7 +400,7 @@ early_puts: puts: putn: mov pc, lr -#endif /* EARLY_UART_ADDRESS */ +#endif /* !EARLY_PRINTK */ /* * Local variables: diff --git a/xen/arch/arm/arm64/Makefile b/xen/arch/arm/arm64/Makefile index be41f43..d612f87 100644 --- a/xen/arch/arm/arm64/Makefile +++ b/xen/arch/arm/arm64/Makefile @@ -5,3 +5,6 @@ obj-y += mode_switch.o obj-y += traps.o obj-y += domain.o + +obj-$(EARLY_PRINTK) += debug.o +obj-$(CONFIG_EARLY_PL011) += debug-pl011.o diff --git a/xen/arch/arm/arm64/debug-pl011.S b/xen/arch/arm/arm64/debug-pl011.S new file mode 100644 index 0000000..1f55fcd --- /dev/null +++ b/xen/arch/arm/arm64/debug-pl011.S @@ -0,0 +1,64 @@ +/* + * xen/arch/arm/arm64/debug-pl011.S + * + * PL011 specific debug code + * + * Copyright (c) 2013 Citrix Systems. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +#define PL011_UART_BASE_ADDRESS 0x1c090000 + +.globl early_uart_paddr +early_uart_paddr: .dword PL011_UART_BASE_ADDRESS + +/* PL011 UART initialization + * x23: UART base address + * Clobber x1 */ +.globl early_uart_init +early_uart_init: + mov x1, #0x0 + strh w1, [x23, #0x28] /* -> UARTFBRD (Baud divisor fraction) */ + mov x1, #0x4 /* 7.3728MHz / 0x4 == 16 * 115200 */ + strh w1, [x23, #0x24] /* -> UARTIBRD (Baud divisor integer) */ + mov x1, #0x60 /* 8n1 */ + str w1, [x23, #0x2C] /* -> UARTLCR_H (Line control) */ + ldr x1, =0x00000301 /* RXE | TXE | UARTEN */ + str w1, [x23, #0x30] /* -> UARTCR (Control Register) */ + ret + +/* PL011 UART wait UART to be ready to transmit + * x23: UART base address + * Clobber x2 */ +.globl early_uart_ready +early_uart_ready: + ldrh w2, [x23, #0x18] /* <- UARTFR (Flag register) */ + tst w2, #0x8 /* Check BUSY bit */ + b.ne early_uart_ready /* Wait for the UART to be ready */ + ret + +/* PL011 UART transmit character + * x2: character to transmit + * x23: UART base address */ +.globl early_uart_transmit +early_uart_transmit: + strb w2, [x23] /* -> UARTDR (Data Register) */ + ret + +/* + * Local variables: + * mode: ASM + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/arm/arm64/debug.S b/xen/arch/arm/arm64/debug.S new file mode 100644 index 0000000..d1d5b36 --- /dev/null +++ b/xen/arch/arm/arm64/debug.S @@ -0,0 +1,33 @@ +/* + * xen/arch/arm/arm64/debug.S + * + * Wrapper for early printk + * + * Julien Grall + * Copyright (c) 2013 Linaro Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +.globl early_putch +/* Print a charact on the UART - this function is called by C + * x0: character to print */ +early_putch: + mov x3, x30 /* Save link register */ + ldr x23, =FIXMAP_ADDR(FIXMAP_CONSOLE) + bl early_uart_ready + mov x2, x0 + bl early_uart_transmit + + mov x30, x3 /* Restore link register */ + ret diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S index ef02899..9908a12 100644 --- a/xen/arch/arm/arm64/head.S +++ b/xen/arch/arm/arm64/head.S @@ -30,8 +30,8 @@ #define PT_DEV_L3 0xe73 /* nG=1 AF=1 SH=10 AP=01 NS=1 ATTR=100 T=1 P=1 */ /* Macro to print a string to the UART, if there is one. - * Clobbers r0-r3. */ -#ifdef EARLY_UART_ADDRESS + * Clobbers x0-x3. */ +#ifdef EARLY_PRINTK #define PRINT(_s) \ adr x0, 98f ; \ bl puts ; \ @@ -39,9 +39,9 @@ 98: .asciz _s ; \ .align 2 ; \ 99: -#else +#else /* EARLY_PRINTK */ #define PRINT(s) -#endif +#endif /* !EARLY_PRINTK */ /*.aarch64*/ @@ -109,8 +109,10 @@ real_start: 2: boot_cpu: -#ifdef EARLY_UART_ADDRESS - ldr x23, =EARLY_UART_ADDRESS /* x23 := UART base address */ +#ifdef EARLY_PRINTK + ldr x0, =early_uart_paddr /* VA of early_uart_paddr */ + add x0, x0, x20 /* PA of early_uart_paddr */ + ldr x23, [x0] /* x23 := UART base address */ cbnz x22, 1f bl init_uart /* CPU 0 sets up the UART too */ 1: PRINT("- CPU ") @@ -206,7 +208,6 @@ skip_bss: mov x4, x1 /* Next level into xen_first */ /* console fixmap */ -#ifdef EARLY_UART_ADDRESS ldr x1, =xen_fixmap add x1, x1, x20 /* x1 := paddr (xen_fixmap) */ lsr x2, x23, #12 @@ -214,7 +215,6 @@ skip_bss: mov x3, #PT_DEV_L3 orr x2, x2, x3 /* x2 := 4K dev map including UART */ str x2, [x1, #(FIXMAP_CONSOLE*8)] /* Map it in the first fixmap's slot */ -#endif /* Build the baseline idle pagetable's first-level entries */ ldr x1, =xen_second @@ -266,10 +266,8 @@ pt_ready: br x1 /* Get a proper vaddr into PC */ paging: -#ifdef EARLY_UART_ADDRESS /* Use a virtual address to access the UART. */ ldr x23, =FIXMAP_ADDR(FIXMAP_CONSOLE) -#endif PRINT("- Ready -\r\n") @@ -329,60 +327,57 @@ fail: PRINT("- Boot failed -\r\n") 1: wfe b 1b -#ifdef EARLY_UART_ADDRESS +#ifdef EARLY_PRINTK -/* Bring up the UART. Specific to the PL011 UART. - * Clobbers r0-r2 */ +/* Bring up the UART. + * Clobbers x0-x3 */ init_uart: - mov x1, #0x0 - strh w1, [x23, #0x24] /* -> UARTIBRD (Baud divisor fraction) */ - mov x1, #0x4 /* 7.3728MHz / 0x4 == 16 * 115200 */ - strh w1, [x23, #0x24] /* -> UARTIBRD (Baud divisor integer) */ - mov x1, #0x60 /* 8n1 */ - strh w1, [x23, #0x24] /* -> UARTLCR_H (Line control) */ - ldr x1, =0x00000301 /* RXE | TXE | UARTEN */ - strh w1, [x23, #0x30] /* -> UARTCR (Control Register) */ + mov x3, x30 /* Save link register */ + bl early_uart_init adr x0, 1f - b puts + b 2f /* Jump to puts */ 1: .asciz "- UART enabled -\r\n" .align 4 -/* Print early debug messages. Specific to the PL011 UART. - * r0: Nul-terminated string to print. - * Clobbers r0-r2 */ +/* Print early debug messages. + * x0: Nul-terminated string to print. + * Clobbers x0-x3 */ puts: - ldrh w2, [x23, #0x18] /* <- UARTFR (Flag register) */ - tst w2, #0x8 /* Check BUSY bit */ - b.ne puts /* Wait for the UART to be ready */ + mov x3, x30 /* Save link register */ +2: + bl early_uart_ready ldrb w2, [x0], #1 /* Load next char */ cbz w2, 1f /* Exit on nul */ - str w2, [x23] /* -> UARTDR (Data Register) */ + bl early_uart_transmit b puts + 1: + mov x30, x3 /* Restore link register */ ret /* Print a 32-bit number in hex. Specific to the PL011 UART. - * r0: Number to print. - * clobbers r0-r3 */ + * x0: Number to print. + * clobbers x0-x4 */ putn: + mov x4, x30 /* Save link register */ adr x1, hex mov x3, #8 -1: ldrh w2, [x23, #0x18] /* <- UARTFR (Flag register) */ - tst w2, #0x8 /* Check BUSY bit */ - b.ne 1b /* Wait for the UART to be ready */ +1: + bl early_uart_ready and x2, x0, #0xf0000000 /* Mask off the top nybble */ lsr x2, x2, #28 ldrb w2, [x1, x2] /* Convert to a char */ - strb w2, [x23] /* -> UARTDR (Data Register) */ + bl early_uart_transmit lsl x0, x0, #4 /* Roll it through one nybble at a time */ subs x3, x3, #1 b.ne 1b + mov x30, x3 /* Restore link register */ ret hex: .ascii "0123456789abcdef" .align 2 -#else /* EARLY_UART_ADDRESS */ +#else /* EARLY_PRINTK */ init_uart: .global early_puts @@ -390,4 +385,4 @@ early_puts: puts: putn: ret -#endif /* EARLY_UART_ADDRESS */ +#endif /* EARLY_PRINTK */ diff --git a/xen/arch/arm/early_printk.c b/xen/arch/arm/early_printk.c index b21f572..7df511a 100644 --- a/xen/arch/arm/early_printk.c +++ b/xen/arch/arm/early_printk.c @@ -15,19 +15,7 @@ #include #include -#ifdef EARLY_UART_ADDRESS - -void __init early_putch(char c) -{ - volatile uint32_t *r; - - r = (uint32_t *)(XEN_VIRT_START + (1 << 21)); - - /* XXX: assuming a PL011 UART. */ - while(*(r + 0x6) & 0x8) - ; - *r = c; -} +void early_putch(char c); static void __init early_puts(const char *s) { @@ -67,5 +55,3 @@ early_panic(const char *fmt, ...) while(1); } - -#endif /* #ifdef EARLY_UART_ADDRESS */ diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h index 1f327c7..943175f 100644 --- a/xen/include/asm-arm/config.h +++ b/xen/include/asm-arm/config.h @@ -141,8 +141,6 @@ extern unsigned long frametable_virt_end; #define watchdog_disable() ((void)0) #define watchdog_enable() ((void)0) -/* Board-specific: base address of PL011 UART */ -#define EARLY_UART_ADDRESS 0x1c090000 /* Board-specific: base address of GIC + its regs */ #define GIC_BASE_ADDRESS 0x2c000000 #define GIC_DR_OFFSET 0x1000 diff --git a/xen/include/asm-arm/early_printk.h b/xen/include/asm-arm/early_printk.h index a0297a7..b72fce7 100644 --- a/xen/include/asm-arm/early_printk.h +++ b/xen/include/asm-arm/early_printk.h @@ -12,7 +12,7 @@ #include -#ifdef EARLY_UART_ADDRESS +#ifdef EARLY_PRINTK void early_printk(const char *fmt, ...); void early_panic(const char *fmt, ...) __attribute__((noreturn));