From 32f11829266f2ede9afac051f980d4ae9b52f963 Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Tue, 19 Sep 2017 23:18:07 +0300 Subject: [PATCH] ARM: Add a new arch + board for QEMU's 'virt' machine This board builds an U-Boot binary that is bootable with QEMU's 'virt' machine on ARM. The minimal QEMU command line is: qemu-system-arm -machine virt,highmem=off -bios u-boot.bin (Note that the 'highmem=off' parameter to the 'virt' machine is required for PCI to work in U-Boot.) This command line enables the following: - u-boot.bin loaded and executing in the emulated flash at address 0x0 - A generated device tree blob placed at the start of RAM - A freely configurable amount of RAM, described by the DTB - A PL011 serial port, discoverable via the DTB - An ARMv7 architected timer - PSCI for rebooting the system - A generic ECAM-based PCI host controller, discoverable via the DTB Additionally, QEMU allows plugging a bunch of useful peripherals to the PCI bus. The following ones are supported by both U-Boot and Linux: - To add a Serial ATA disk via an Intel ICH9 AHCI controller, pass e.g.: -drive if=none,file=disk.img,id=mydisk -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0 - To add an Intel E1000 network adapter, pass e.g.: -net nic,model=e1000 -net user - To add an EHCI-compliant USB host controller, pass e.g.: -device usb-ehci,id=ehci - To add a NVMe disk, pass e.g.: -drive if=none,file=disk.img,id=mydisk -device nvme,drive=mydisk,serial=foo Signed-off-by: Tuomas Tynkkynen --- arch/arm/Kconfig | 10 +++++++ arch/arm/mach-qemu/Kconfig | 12 ++++++++ board/emulation/qemu-arm/MAINTAINERS | 6 ++++ board/emulation/qemu-arm/Makefile | 5 ++++ board/emulation/qemu-arm/qemu-arm.c | 33 ++++++++++++++++++++ configs/qemu_arm_defconfig | 28 +++++++++++++++++ include/configs/qemu-arm.h | 58 ++++++++++++++++++++++++++++++++++++ 7 files changed, 152 insertions(+) create mode 100644 arch/arm/mach-qemu/Kconfig create mode 100644 board/emulation/qemu-arm/MAINTAINERS create mode 100644 board/emulation/qemu-arm/Makefile create mode 100644 board/emulation/qemu-arm/qemu-arm.c create mode 100644 configs/qemu_arm_defconfig create mode 100644 include/configs/qemu-arm.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5d1ce3e..64e0ee4 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -631,6 +631,14 @@ config ARCH_MX5 select CPU_V7 select BOARD_EARLY_INIT_F +config ARCH_QEMU + bool "QEMU Virtual Platform" + select CPU_V7 + select ARCH_SUPPORT_PSCI + select DM + select DM_SERIAL + select OF_CONTROL + config ARCH_RMOBILE bool "Renesas ARM SoCs" select DM @@ -1171,6 +1179,8 @@ source "arch/arm/mach-rmobile/Kconfig" source "arch/arm/mach-meson/Kconfig" +source "arch/arm/mach-qemu/Kconfig" + source "arch/arm/mach-rockchip/Kconfig" source "arch/arm/mach-s5pc1xx/Kconfig" diff --git a/arch/arm/mach-qemu/Kconfig b/arch/arm/mach-qemu/Kconfig new file mode 100644 index 0000000..3500b56 --- /dev/null +++ b/arch/arm/mach-qemu/Kconfig @@ -0,0 +1,12 @@ +if ARCH_QEMU + +config SYS_VENDOR + default "emulation" + +config SYS_BOARD + default "qemu-arm" + +config SYS_CONFIG_NAME + default "qemu-arm" + +endif diff --git a/board/emulation/qemu-arm/MAINTAINERS b/board/emulation/qemu-arm/MAINTAINERS new file mode 100644 index 0000000..a803061 --- /dev/null +++ b/board/emulation/qemu-arm/MAINTAINERS @@ -0,0 +1,6 @@ +QEMU ARM 'VIRT' BOARD +M: Tuomas Tynkkynen +S: Maintained +F: board/emulation/qemu-arm/ +F: include/configs/qemu-arm.h +F: configs/qemu_arm_defconfig diff --git a/board/emulation/qemu-arm/Makefile b/board/emulation/qemu-arm/Makefile new file mode 100644 index 0000000..716a6e9 --- /dev/null +++ b/board/emulation/qemu-arm/Makefile @@ -0,0 +1,5 @@ +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += qemu-arm.o diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c new file mode 100644 index 0000000..e29ba46 --- /dev/null +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2017 Tuomas Tynkkynen + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include + +int board_init(void) +{ + return 0; +} + +int dram_init(void) +{ + if (fdtdec_setup_memory_size() != 0) + return -EINVAL; + + return 0; +} + +int dram_init_banksize(void) +{ + fdtdec_setup_memory_banksize(); + + return 0; +} + +void *board_fdt_blob_setup(void) +{ + /* QEMU loads a generated DTB for us at the start of RAM. */ + return (void *)CONFIG_SYS_SDRAM_BASE; +} diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig new file mode 100644 index 0000000..2a8594d --- /dev/null +++ b/configs/qemu_arm_defconfig @@ -0,0 +1,28 @@ +CONFIG_ARM=y +CONFIG_ARM_SMCCC=y +CONFIG_ARCH_QEMU=y +CONFIG_AHCI=y +CONFIG_DISTRO_DEFAULTS=y +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_DISPLAY_BOARDINFO is not set +# CONFIG_CMD_IMLS is not set +CONFIG_CMD_PCI=y +CONFIG_CMD_USB=y +CONFIG_OF_BOARD=y +CONFIG_AHCI_PCI=y +CONFIG_BLK=y +# CONFIG_MMC is not set +CONFIG_DM_ETH=y +CONFIG_E1000=y +CONFIG_NVME=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCIE_ECAM_GENERIC=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_PSCI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_PCI=y diff --git a/include/configs/qemu-arm.h b/include/configs/qemu-arm.h new file mode 100644 index 0000000..4376a24 --- /dev/null +++ b/include/configs/qemu-arm.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017 Tuomas Tynkkynen + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +/* Physical memory map */ +#define CONFIG_SYS_TEXT_BASE 0x00000000 + +#define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_SYS_SDRAM_BASE 0x40000000 + +/* The DTB generated by QEMU is placed at start of RAM, stay away from there */ +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M) +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_2M) +#define CONFIG_SYS_MALLOC_LEN SZ_16M + +/* QEMU's PL011 serial port is detected via FDT using the device model */ +#define CONFIG_PL01X_SERIAL + +/* QEMU implements a 62.5MHz architected timer */ +/* FIXME: can we rely on CNTFREQ instead of hardcoding this fact here? */ +#define CONFIG_SYS_ARCH_TIMER +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SYS_HZ_CLOCK 62500000 + +/* For block devices, QEMU emulates an ICH9 AHCI controller over PCI */ +#define CONFIG_SYS_SCSI_MAX_SCSI_ID 6 +#define CONFIG_SCSI_AHCI +#define CONFIG_LIBATA + +/* Environment options */ +#define CONFIG_ENV_SIZE SZ_64K + +#include + +#define BOOT_TARGET_DEVICES(func) \ + func(SCSI, scsi, 0) + +#include + +#define CONFIG_PREBOOT "pci enum" +#define CONFIG_EXTRA_ENV_SETTINGS \ + "fdt_high=0xffffffff\0" \ + "initrd_high=0xffffffff\0" \ + "fdt_addr=0x40000000\0" \ + "scriptaddr=0x40200000\0" \ + "pxefile_addr_r=0x40300000\0" \ + "kernel_addr_r=0x40400000\0" \ + "ramdisk_addr_r=0x44000000\0" \ + BOOTENV + +#endif /* __CONFIG_H */