From ba3f529681d6dc6e911f89b68921384d773b0d1e Mon Sep 17 00:00:00 2001 From: Ziang Wang Date: Thu, 25 Sep 2025 16:09:42 +0800 Subject: [PATCH] drivers/emulation/qemu: Adjust fw_cfg driver for Arm and RISCV According to QEMU docs/specs/fw_cfg.rst, the selector and data register offsets of Arm & RISCV should be 0x8 and 0x0. Besides, the selector register should be in big-endian when using MMIO access. TEST=build and run successfully on QEMU rvvirt machine. Using command "qemu-system-riscv64 -machine virt -bios build/coreboot.rom -nographic -drive if=pflash,file=./build/coreboot.rom,format=raw". Change-Id: I1c4d40a4dbcac4067a7c69ba916e6ff0a21cdcb6 Signed-off-by: Dong Wei Signed-off-by: Ziang Wang Reviewed-on: https://review.coreboot.org/c/coreboot/+/89339 Tested-by: build bot (Jenkins) Reviewed-by: Maximilian Brune Reviewed-by: Paul Menzel Reviewed-by: Patrick Rudolph --- src/drivers/emulation/qemu/fw_cfg.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/drivers/emulation/qemu/fw_cfg.c b/src/drivers/emulation/qemu/fw_cfg.c index 98f2a7b94d..3947a54a11 100644 --- a/src/drivers/emulation/qemu/fw_cfg.c +++ b/src/drivers/emulation/qemu/fw_cfg.c @@ -11,10 +11,17 @@ #include #include +#if CONFIG(ARCH_ARM) || CONFIG(ARCH_RISCV) +#define FW_CFG_PORT_CTL 0x08 +#define FW_CFG_PORT_DATA 0x00 +#define FW_CFG_DMA_ADDR_HIGH 0x10 +#define FW_CFG_DMA_ADDR_LOW 0x14 +#else #define FW_CFG_PORT_CTL 0x0510 #define FW_CFG_PORT_DATA 0x0511 #define FW_CFG_DMA_ADDR_HIGH 0x0514 #define FW_CFG_DMA_ADDR_LOW 0x0518 +#endif static int fw_cfg_detected; static uint8_t fw_ver; @@ -43,10 +50,14 @@ static int fw_cfg_present(void) static void fw_cfg_select(uint16_t entry) { - if (fw_ver & FW_CFG_VERSION_DMA) + if (fw_ver & FW_CFG_VERSION_DMA) { fw_cfg_dma(FW_CFG_DMA_CTL_SELECT | entry << 16, NULL, 0); - else - outw(entry, FW_CFG_PORT_CTL); + } else { +#ifdef __ARCH_GENERIC_IO_H__ + entry = cpu_to_be16 (entry); // Big endian if MMIO +#endif + outw(entry, FW_CFG_PORT_CTL); // Little endian if IO-port + } } static void fw_cfg_read(void *dst, int dstlen)