Xiang Wang has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/29789
Change subject: sifive uart: Add memory barrier instruction ......................................................................
sifive uart: Add memory barrier instruction
If the memory barrier instruction is missing, the following code will be optimized.
source code: do { v = *reg; } while (v & mask);
Optimized code: v = *reg; do { } while (v & mask);
In order to prevent such optimization, you need to add memory barrier instructions, the source code is modified as follows. do { v = *reg; asm volatile ("":::"memory"); } while (v & mask);
Change-Id: I7fdf178485af1ef0fd8d10f1f4919b9e31284457 Signed-off-by: Xiang Wang wxjstz@126.com --- M src/drivers/uart/sifive.c 1 file changed, 7 insertions(+), 7 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/89/29789/1
diff --git a/src/drivers/uart/sifive.c b/src/drivers/uart/sifive.c index ce8ead0..1a7370c 100644 --- a/src/drivers/uart/sifive.c +++ b/src/drivers/uart/sifive.c @@ -66,17 +66,15 @@ sifive_uart_init(uart_platform_baseptr(idx), div); }
-static bool uart_can_tx(struct sifive_uart_registers *regs) -{ - return !(read32(®s->txdata) & TXDATA_FULL); -} - void uart_tx_byte(int idx, unsigned char data) { struct sifive_uart_registers *regs = uart_platform_baseptr(idx); + uint32_t txdata;
- while (!uart_can_tx(regs)) - ; /* TODO: implement a timeout */ + do { + txdata = read32(regs->txdata); + asm volatile ("":::"memory"); + } while (txdata & TXDATA_FULL)
write32(®s->txdata, data); } @@ -89,6 +87,7 @@ /* Use the TX watermark bit to find out if the TX FIFO is empty */ do { ip = read32(®s->ip); + asm volatile ("":::"memory"); } while (!(ip & IP_TXWM)); }
@@ -99,6 +98,7 @@
do { rxdata = read32(®s->rxdata); + asm volatile ("":::"memory"); } while (rxdata & RXDATA_EMPTY);
return rxdata & 0xff;