diff mbox series

[2/4] xen/arm: debug-pl011: Add support for 32-bit only MMIO

Message ID 20230607092727.19654-3-michal.orzel@amd.com (mailing list archive)
State New, archived
Headers show
Series xen/arm: pl011: Use correct accessors | expand

Commit Message

Michal Orzel June 7, 2023, 9:27 a.m. UTC
There are implementations of PL011 that can only handle 32-bit accesses
as oppose to the normal behavior where accesses are 8/16-bit wide. This
is usually advertised by setting a dt property 'reg-io-width' to 4.

Introduce CONFIG_EARLY_UART_PL011_MMIO32 Kconfig option to be able to
enable the use of 32-bit only accessors in PL011 early printk code.
Define macros PL011_{STRH,STRB,LDRH} to distinguish accessors for normal
case from 32-bit MMIO one and use them in arm32/arm64 pl011 early printk
code.

Update documentation accordingly.

Signed-off-by: Michal Orzel <michal.orzel@amd.com>
---
I might want to align the indentation of operands but doing so in this patch
is rather no go as it would limit the visibility of the scope of this patch.
Something to do in the future.
---
 docs/misc/arm/early-printk.txt        |  3 +++
 xen/arch/arm/Kconfig.debug            |  7 +++++++
 xen/arch/arm/arm32/debug-pl011.inc    | 12 ++++++------
 xen/arch/arm/arm64/debug-pl011.inc    | 12 ++++++------
 xen/arch/arm/include/asm/pl011-uart.h | 19 +++++++++++++++++++
 5 files changed, 41 insertions(+), 12 deletions(-)

Comments

Henry Wang June 13, 2023, 2:59 a.m. UTC | #1
Hi Michal,

> -----Original Message-----
> Subject: [PATCH 2/4] xen/arm: debug-pl011: Add support for 32-bit only
> MMIO
> 
> There are implementations of PL011 that can only handle 32-bit accesses
> as oppose to the normal behavior where accesses are 8/16-bit wide. This
> is usually advertised by setting a dt property 'reg-io-width' to 4.
> 
> Introduce CONFIG_EARLY_UART_PL011_MMIO32 Kconfig option to be able to
> enable the use of 32-bit only accessors in PL011 early printk code.
> Define macros PL011_{STRH,STRB,LDRH} to distinguish accessors for normal
> case from 32-bit MMIO one and use them in arm32/arm64 pl011 early printk
> code.
> 
> Update documentation accordingly.
> 
> Signed-off-by: Michal Orzel <michal.orzel@amd.com>

I've tested this patch on top of today's staging on FVP arm32 and arm64 and
confirm this patch will not break existing functionality. So:

Tested-by: Henry Wang <Henry.Wang@arm.com>

Kind regards,
Henry
Stefano Stabellini June 15, 2023, 1:42 a.m. UTC | #2
On Wed, 7 Jun 2023, Michal Orzel wrote:
> There are implementations of PL011 that can only handle 32-bit accesses
> as oppose to the normal behavior where accesses are 8/16-bit wide. This
> is usually advertised by setting a dt property 'reg-io-width' to 4.
> 
> Introduce CONFIG_EARLY_UART_PL011_MMIO32 Kconfig option to be able to
> enable the use of 32-bit only accessors in PL011 early printk code.
> Define macros PL011_{STRH,STRB,LDRH} to distinguish accessors for normal
> case from 32-bit MMIO one and use them in arm32/arm64 pl011 early printk
> code.
> 
> Update documentation accordingly.
> 
> Signed-off-by: Michal Orzel <michal.orzel@amd.com>

Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>

With the caveat of the potential change to patch #1 that would affect
this patch too


> ---
> I might want to align the indentation of operands but doing so in this patch
> is rather no go as it would limit the visibility of the scope of this patch.
> Something to do in the future.
> ---
>  docs/misc/arm/early-printk.txt        |  3 +++
>  xen/arch/arm/Kconfig.debug            |  7 +++++++
>  xen/arch/arm/arm32/debug-pl011.inc    | 12 ++++++------
>  xen/arch/arm/arm64/debug-pl011.inc    | 12 ++++++------
>  xen/arch/arm/include/asm/pl011-uart.h | 19 +++++++++++++++++++
>  5 files changed, 41 insertions(+), 12 deletions(-)
> 
> diff --git a/docs/misc/arm/early-printk.txt b/docs/misc/arm/early-printk.txt
> index aa22826075a4..bc2d65aa2ea3 100644
> --- a/docs/misc/arm/early-printk.txt
> +++ b/docs/misc/arm/early-printk.txt
> @@ -26,6 +26,9 @@ Other options depends on the driver selected:
>        If CONFIG_EARLY_UART_PL011_BAUD_RATE  is set to 0 then the code will
>        not try to initialize the UART, so that bootloader or firmware
>        settings can be used for maximum compatibility.
> +
> +    - CONFIG_EARLY_UART_PL011_MMIO32 is, optionally, used to enable 32-bit
> +      only accesses to registers.
>    - scif
>      - CONFIG_EARLY_UART_SCIF_VERSION_* is, optionally, the interface version
>        of the UART. Default to version NONE.
> diff --git a/xen/arch/arm/Kconfig.debug b/xen/arch/arm/Kconfig.debug
> index 842d768280c4..eec860e88e0b 100644
> --- a/xen/arch/arm/Kconfig.debug
> +++ b/xen/arch/arm/Kconfig.debug
> @@ -253,6 +253,13 @@ config EARLY_UART_PL011_BAUD_RATE
>  	default 115200 if EARLY_PRINTK_FASTMODEL
>  	default 0
>  
> +config EARLY_UART_PL011_MMIO32
> +	bool "32-bit only MMIO for PL011 early printk"
> +	depends on EARLY_UART_PL011
> +	help
> +	  If specified, all accesses to PL011 registers made from early printk code
> +	  will be done using 32-bit only accessors.
> +
>  config EARLY_UART_INIT
>  	depends on EARLY_UART_PL011 && EARLY_UART_PL011_BAUD_RATE != 0
>  	def_bool y
> diff --git a/xen/arch/arm/arm32/debug-pl011.inc b/xen/arch/arm/arm32/debug-pl011.inc
> index 9fe0c2503831..5833da2a235c 100644
> --- a/xen/arch/arm/arm32/debug-pl011.inc
> +++ b/xen/arch/arm/arm32/debug-pl011.inc
> @@ -26,13 +26,13 @@
>   */
>  .macro early_uart_init rb, rc, rd
>          mov   \rc, #(7372800 / CONFIG_EARLY_UART_PL011_BAUD_RATE % 16)
> -        strb  \rc, [\rb, #FBRD]     /* -> UARTFBRD (Baud divisor fraction) */
> +        PL011_STRB  \rc, [\rb, #FBRD]  /* -> UARTFBRD (Baud divisor fraction) */
>          mov   \rc, #(7372800 / CONFIG_EARLY_UART_PL011_BAUD_RATE / 16)
> -        strh  \rc, [\rb, #IBRD]     /* -> UARTIBRD (Baud divisor integer) */
> +        PL011_STRH  \rc, [\rb, #IBRD]  /* -> UARTIBRD (Baud divisor integer) */
>          mov   \rc, #WLEN_8          /* 8n1 */
> -        strb  \rc, [\rb, #LCR_H]     /* -> UARTLCR_H (Line control) */
> +        PL011_STRB  \rc, [\rb, #LCR_H] /* -> UARTLCR_H (Line control) */
>          ldr   \rc, =(RXE | TXE | UARTEN)      /* RXE | TXE | UARTEN */
> -        strh  \rc, [\rb, #CR]     /* -> UARTCR (Control Register) */
> +        PL011_STRH  \rc, [\rb, #CR]    /* -> UARTCR (Control Register) */
>  .endm
>  
>  /*
> @@ -42,7 +42,7 @@
>   */
>  .macro early_uart_ready rb, rc
>  1:
> -        ldrh  \rc, [\rb, #FR]       /* <- UARTFR (Flag register) */
> +        PL011_LDRH  \rc, [\rb, #FR] /* <- UARTFR (Flag register) */
>          tst   \rc, #BUSY             /* Check BUSY bit */
>          bne   1b                    /* Wait for the UART to be ready */
>  .endm
> @@ -53,7 +53,7 @@
>   * rt: register which contains the character to transmit
>   */
>  .macro early_uart_transmit rb, rt
> -        strb  \rt, [\rb, #DR]            /* -> UARTDR (Data Register) */
> +        PL011_STRB  \rt, [\rb, #DR]      /* -> UARTDR (Data Register) */
>  .endm
>  
>  /*
> diff --git a/xen/arch/arm/arm64/debug-pl011.inc b/xen/arch/arm/arm64/debug-pl011.inc
> index df713eff4922..430594610b2c 100644
> --- a/xen/arch/arm/arm64/debug-pl011.inc
> +++ b/xen/arch/arm/arm64/debug-pl011.inc
> @@ -25,13 +25,13 @@
>   */
>  .macro early_uart_init xb, c
>          mov   x\c, #(7372800 / CONFIG_EARLY_UART_PL011_BAUD_RATE % 16)
> -        strb  w\c, [\xb, #FBRD]      /* -> UARTFBRD (Baud divisor fraction) */
> +        PL011_STRB  w\c, [\xb, #FBRD]  /* -> UARTFBRD (Baud divisor fraction) */
>          mov   x\c, #(7372800 / CONFIG_EARLY_UART_PL011_BAUD_RATE / 16)
> -        strh  w\c, [\xb, #IBRD]      /* -> UARTIBRD (Baud divisor integer) */
> +        PL011_STRH  w\c, [\xb, #IBRD]  /* -> UARTIBRD (Baud divisor integer) */
>          mov   x\c, #WLEN_8           /* 8n1 */
> -        strb  w\c, [\xb, #LCR_H]     /* -> UARTLCR_H (Line control) */
> +        PL011_STRB  w\c, [\xb, #LCR_H] /* -> UARTLCR_H (Line control) */
>          ldr   x\c, =(RXE | TXE | UARTEN)
> -        strh  w\c, [\xb, #CR]        /* -> UARTCR (Control Register) */
> +        PL011_STRH  w\c, [\xb, #CR]    /* -> UARTCR (Control Register) */
>  .endm
>  
>  /*
> @@ -41,7 +41,7 @@
>   */
>  .macro early_uart_ready xb, c
>  1:
> -        ldrh  w\c, [\xb, #FR]        /* <- UARTFR (Flag register) */
> +        PL011_LDRH  w\c, [\xb, #FR]  /* <- UARTFR (Flag register) */
>          tst   w\c, #BUSY             /* Check BUSY bit */
>          b.ne  1b                     /* Wait for the UART to be ready */
>  .endm
> @@ -52,7 +52,7 @@
>   * wt: register which contains the character to transmit
>   */
>  .macro early_uart_transmit xb, wt
> -        strb  \wt, [\xb, #DR]        /* -> UARTDR (Data Register) */
> +        PL011_STRB  \wt, [\xb, #DR]  /* -> UARTDR (Data Register) */
>  .endm
>  
>  /*
> diff --git a/xen/arch/arm/include/asm/pl011-uart.h b/xen/arch/arm/include/asm/pl011-uart.h
> index 5bb563ec0814..27c9bfa444cb 100644
> --- a/xen/arch/arm/include/asm/pl011-uart.h
> +++ b/xen/arch/arm/include/asm/pl011-uart.h
> @@ -21,6 +21,25 @@
>  #ifndef __ASM_ARM_PL011_H
>  #define __ASM_ARM_PL011_H
>  
> +#ifdef __ASSEMBLY__
> +
> +/*
> + * PL011 registers are 8/16-bit wide. However, there are implementations that
> + * can only handle 32-bit accesses. The following macros used in early printk
> + * are defined to distinguish accessors for normal case from 32-bit MMIO one.
> + */
> +#ifdef CONFIG_EARLY_UART_PL011_MMIO32
> +#define PL011_STRH str
> +#define PL011_STRB str
> +#define PL011_LDRH ldr
> +#else
> +#define PL011_STRH strh
> +#define PL011_STRB strb
> +#define PL011_LDRH ldrh
> +#endif
> +
> +#endif /* __ASSEMBLY__ */
> +
>  /* PL011 register addresses */
>  #define DR     (0x00)
>  #define RSR    (0x04)
> -- 
> 2.25.1
>
diff mbox series

Patch

diff --git a/docs/misc/arm/early-printk.txt b/docs/misc/arm/early-printk.txt
index aa22826075a4..bc2d65aa2ea3 100644
--- a/docs/misc/arm/early-printk.txt
+++ b/docs/misc/arm/early-printk.txt
@@ -26,6 +26,9 @@  Other options depends on the driver selected:
       If CONFIG_EARLY_UART_PL011_BAUD_RATE  is set to 0 then the code will
       not try to initialize the UART, so that bootloader or firmware
       settings can be used for maximum compatibility.
+
+    - CONFIG_EARLY_UART_PL011_MMIO32 is, optionally, used to enable 32-bit
+      only accesses to registers.
   - scif
     - CONFIG_EARLY_UART_SCIF_VERSION_* is, optionally, the interface version
       of the UART. Default to version NONE.
diff --git a/xen/arch/arm/Kconfig.debug b/xen/arch/arm/Kconfig.debug
index 842d768280c4..eec860e88e0b 100644
--- a/xen/arch/arm/Kconfig.debug
+++ b/xen/arch/arm/Kconfig.debug
@@ -253,6 +253,13 @@  config EARLY_UART_PL011_BAUD_RATE
 	default 115200 if EARLY_PRINTK_FASTMODEL
 	default 0
 
+config EARLY_UART_PL011_MMIO32
+	bool "32-bit only MMIO for PL011 early printk"
+	depends on EARLY_UART_PL011
+	help
+	  If specified, all accesses to PL011 registers made from early printk code
+	  will be done using 32-bit only accessors.
+
 config EARLY_UART_INIT
 	depends on EARLY_UART_PL011 && EARLY_UART_PL011_BAUD_RATE != 0
 	def_bool y
diff --git a/xen/arch/arm/arm32/debug-pl011.inc b/xen/arch/arm/arm32/debug-pl011.inc
index 9fe0c2503831..5833da2a235c 100644
--- a/xen/arch/arm/arm32/debug-pl011.inc
+++ b/xen/arch/arm/arm32/debug-pl011.inc
@@ -26,13 +26,13 @@ 
  */
 .macro early_uart_init rb, rc, rd
         mov   \rc, #(7372800 / CONFIG_EARLY_UART_PL011_BAUD_RATE % 16)
-        strb  \rc, [\rb, #FBRD]     /* -> UARTFBRD (Baud divisor fraction) */
+        PL011_STRB  \rc, [\rb, #FBRD]  /* -> UARTFBRD (Baud divisor fraction) */
         mov   \rc, #(7372800 / CONFIG_EARLY_UART_PL011_BAUD_RATE / 16)
-        strh  \rc, [\rb, #IBRD]     /* -> UARTIBRD (Baud divisor integer) */
+        PL011_STRH  \rc, [\rb, #IBRD]  /* -> UARTIBRD (Baud divisor integer) */
         mov   \rc, #WLEN_8          /* 8n1 */
-        strb  \rc, [\rb, #LCR_H]     /* -> UARTLCR_H (Line control) */
+        PL011_STRB  \rc, [\rb, #LCR_H] /* -> UARTLCR_H (Line control) */
         ldr   \rc, =(RXE | TXE | UARTEN)      /* RXE | TXE | UARTEN */
-        strh  \rc, [\rb, #CR]     /* -> UARTCR (Control Register) */
+        PL011_STRH  \rc, [\rb, #CR]    /* -> UARTCR (Control Register) */
 .endm
 
 /*
@@ -42,7 +42,7 @@ 
  */
 .macro early_uart_ready rb, rc
 1:
-        ldrh  \rc, [\rb, #FR]       /* <- UARTFR (Flag register) */
+        PL011_LDRH  \rc, [\rb, #FR] /* <- UARTFR (Flag register) */
         tst   \rc, #BUSY             /* Check BUSY bit */
         bne   1b                    /* Wait for the UART to be ready */
 .endm
@@ -53,7 +53,7 @@ 
  * rt: register which contains the character to transmit
  */
 .macro early_uart_transmit rb, rt
-        strb  \rt, [\rb, #DR]            /* -> UARTDR (Data Register) */
+        PL011_STRB  \rt, [\rb, #DR]      /* -> UARTDR (Data Register) */
 .endm
 
 /*
diff --git a/xen/arch/arm/arm64/debug-pl011.inc b/xen/arch/arm/arm64/debug-pl011.inc
index df713eff4922..430594610b2c 100644
--- a/xen/arch/arm/arm64/debug-pl011.inc
+++ b/xen/arch/arm/arm64/debug-pl011.inc
@@ -25,13 +25,13 @@ 
  */
 .macro early_uart_init xb, c
         mov   x\c, #(7372800 / CONFIG_EARLY_UART_PL011_BAUD_RATE % 16)
-        strb  w\c, [\xb, #FBRD]      /* -> UARTFBRD (Baud divisor fraction) */
+        PL011_STRB  w\c, [\xb, #FBRD]  /* -> UARTFBRD (Baud divisor fraction) */
         mov   x\c, #(7372800 / CONFIG_EARLY_UART_PL011_BAUD_RATE / 16)
-        strh  w\c, [\xb, #IBRD]      /* -> UARTIBRD (Baud divisor integer) */
+        PL011_STRH  w\c, [\xb, #IBRD]  /* -> UARTIBRD (Baud divisor integer) */
         mov   x\c, #WLEN_8           /* 8n1 */
-        strb  w\c, [\xb, #LCR_H]     /* -> UARTLCR_H (Line control) */
+        PL011_STRB  w\c, [\xb, #LCR_H] /* -> UARTLCR_H (Line control) */
         ldr   x\c, =(RXE | TXE | UARTEN)
-        strh  w\c, [\xb, #CR]        /* -> UARTCR (Control Register) */
+        PL011_STRH  w\c, [\xb, #CR]    /* -> UARTCR (Control Register) */
 .endm
 
 /*
@@ -41,7 +41,7 @@ 
  */
 .macro early_uart_ready xb, c
 1:
-        ldrh  w\c, [\xb, #FR]        /* <- UARTFR (Flag register) */
+        PL011_LDRH  w\c, [\xb, #FR]  /* <- UARTFR (Flag register) */
         tst   w\c, #BUSY             /* Check BUSY bit */
         b.ne  1b                     /* Wait for the UART to be ready */
 .endm
@@ -52,7 +52,7 @@ 
  * wt: register which contains the character to transmit
  */
 .macro early_uart_transmit xb, wt
-        strb  \wt, [\xb, #DR]        /* -> UARTDR (Data Register) */
+        PL011_STRB  \wt, [\xb, #DR]  /* -> UARTDR (Data Register) */
 .endm
 
 /*
diff --git a/xen/arch/arm/include/asm/pl011-uart.h b/xen/arch/arm/include/asm/pl011-uart.h
index 5bb563ec0814..27c9bfa444cb 100644
--- a/xen/arch/arm/include/asm/pl011-uart.h
+++ b/xen/arch/arm/include/asm/pl011-uart.h
@@ -21,6 +21,25 @@ 
 #ifndef __ASM_ARM_PL011_H
 #define __ASM_ARM_PL011_H
 
+#ifdef __ASSEMBLY__
+
+/*
+ * PL011 registers are 8/16-bit wide. However, there are implementations that
+ * can only handle 32-bit accesses. The following macros used in early printk
+ * are defined to distinguish accessors for normal case from 32-bit MMIO one.
+ */
+#ifdef CONFIG_EARLY_UART_PL011_MMIO32
+#define PL011_STRH str
+#define PL011_STRB str
+#define PL011_LDRH ldr
+#else
+#define PL011_STRH strh
+#define PL011_STRB strb
+#define PL011_LDRH ldrh
+#endif
+
+#endif /* __ASSEMBLY__ */
+
 /* PL011 register addresses */
 #define DR     (0x00)
 #define RSR    (0x04)