From a65b25d148fb0a9ef7dd5fba4ae2709f5bcae0c6 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 7 May 2015 21:34:08 +0800 Subject: [PATCH] x86: Support QEMU x86 targets This commit introduces the initial U-Boot support for QEMU x86 targets. U-Boot can boot from coreboot as a payload, or directly without coreboot. Signed-off-by: Bin Meng Acked-by: Simon Glass Tested-by: Simon Glass Merged in patch 'x86: qemu: Add CMD_NET to qemu-x86_defconfig https://patchwork.ozlabs.org/patch/479745/ --- arch/x86/Kconfig | 5 +++ arch/x86/cpu/Makefile | 1 + arch/x86/cpu/qemu/Kconfig | 21 ++++++++++ arch/x86/cpu/qemu/Makefile | 8 ++++ arch/x86/cpu/qemu/car.S | 26 ++++++++++++ arch/x86/cpu/qemu/dram.c | 46 +++++++++++++++++++++ arch/x86/cpu/qemu/pci.c | 49 +++++++++++++++++++++++ arch/x86/cpu/qemu/qemu.c | 37 +++++++++++++++++ arch/x86/dts/Makefile | 3 +- arch/x86/dts/qemu-x86.dts | 34 ++++++++++++++++ arch/x86/include/asm/arch-qemu/gpio.h | 13 ++++++ arch/x86/include/asm/arch-qemu/qemu.h | 17 ++++++++ board/emulation/Kconfig | 25 ++++++++++++ board/emulation/qemu-x86/Kconfig | 24 +++++++++++ board/emulation/qemu-x86/MAINTAINERS | 6 +++ board/emulation/qemu-x86/Makefile | 7 ++++ board/emulation/qemu-x86/qemu-x86.c | 13 ++++++ board/emulation/qemu-x86/start.S | 9 +++++ configs/qemu-x86_defconfig | 7 ++++ include/configs/qemu-x86.h | 57 +++++++++++++++++++++++++++ 20 files changed, 407 insertions(+), 1 deletion(-) create mode 100644 arch/x86/cpu/qemu/Kconfig create mode 100644 arch/x86/cpu/qemu/Makefile create mode 100644 arch/x86/cpu/qemu/car.S create mode 100644 arch/x86/cpu/qemu/dram.c create mode 100644 arch/x86/cpu/qemu/pci.c create mode 100644 arch/x86/cpu/qemu/qemu.c create mode 100644 arch/x86/dts/qemu-x86.dts create mode 100644 arch/x86/include/asm/arch-qemu/gpio.h create mode 100644 arch/x86/include/asm/arch-qemu/qemu.h create mode 100644 board/emulation/Kconfig create mode 100644 board/emulation/qemu-x86/Kconfig create mode 100644 board/emulation/qemu-x86/MAINTAINERS create mode 100644 board/emulation/qemu-x86/Makefile create mode 100644 board/emulation/qemu-x86/qemu-x86.c create mode 100644 board/emulation/qemu-x86/start.S create mode 100644 configs/qemu-x86_defconfig create mode 100644 include/configs/qemu-x86.h diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 8e734fdfb4..3d0262052f 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -17,6 +17,9 @@ choice config VENDOR_COREBOOT bool "coreboot" +config VENDOR_EMULATION + bool "emulation" + config VENDOR_GOOGLE bool "Google" @@ -27,6 +30,7 @@ endchoice # board-specific options below source "board/coreboot/Kconfig" +source "board/emulation/Kconfig" source "board/google/Kconfig" source "board/intel/Kconfig" @@ -34,6 +38,7 @@ source "board/intel/Kconfig" source "arch/x86/cpu/baytrail/Kconfig" source "arch/x86/cpu/coreboot/Kconfig" source "arch/x86/cpu/ivybridge/Kconfig" +source "arch/x86/cpu/qemu/Kconfig" source "arch/x86/cpu/quark/Kconfig" source "arch/x86/cpu/queensbay/Kconfig" diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 043bea258c..307545ac75 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -14,6 +14,7 @@ obj-y += interrupts.o cpu.o call64.o obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/ obj-$(CONFIG_SYS_COREBOOT) += coreboot/ +obj-$(CONFIG_QEMU) += qemu/ obj-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += ivybridge/ obj-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += ivybridge/ obj-$(CONFIG_INTEL_QUARK) += quark/ diff --git a/arch/x86/cpu/qemu/Kconfig b/arch/x86/cpu/qemu/Kconfig new file mode 100644 index 0000000000..fb775d7d28 --- /dev/null +++ b/arch/x86/cpu/qemu/Kconfig @@ -0,0 +1,21 @@ +# +# Copyright (C) 2015, Bin Meng +# +# SPDX-License-Identifier: GPL-2.0+ +# + +config QEMU + bool + select TSC_CALIBRATION_BYPASS + +if QEMU + +config SYS_CAR_ADDR + hex + default 0xd0000 + +config SYS_CAR_SIZE + hex + default 0x10000 + +endif diff --git a/arch/x86/cpu/qemu/Makefile b/arch/x86/cpu/qemu/Makefile new file mode 100644 index 0000000000..be79723a67 --- /dev/null +++ b/arch/x86/cpu/qemu/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (C) 2015, Bin Meng +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += car.o dram.o qemu.o +obj-$(CONFIG_PCI) += pci.o diff --git a/arch/x86/cpu/qemu/car.S b/arch/x86/cpu/qemu/car.S new file mode 100644 index 0000000000..13b3aea3ff --- /dev/null +++ b/arch/x86/cpu/qemu/car.S @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +.globl car_init +car_init: + /* Save the BIST result */ + movl %eax, %ebp + + post_code(POST_CAR_START) + + /* + * Since we know we are running inside emulator, + * we can do nothing here for CAR initialization. + */ + + /* Restore the BIST result */ + movl %ebp, %eax + + post_code(POST_CAR_CPU_CACHE) + jmp car_init_ret diff --git a/arch/x86/cpu/qemu/dram.c b/arch/x86/cpu/qemu/dram.c new file mode 100644 index 0000000000..a88d0d2654 --- /dev/null +++ b/arch/x86/cpu/qemu/dram.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + u32 ram; + + outb(HIGH_RAM_ADDR, CMOS_ADDR_PORT); + ram = ((u32)inb(CMOS_DATA_PORT)) << 14; + outb(LOW_RAM_ADDR, CMOS_ADDR_PORT); + ram |= ((u32)inb(CMOS_DATA_PORT)) << 6; + ram += 16 * 1024; + + gd->ram_size = ram * 1024; + post_code(POST_DRAM); + + return 0; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = 0; + gd->bd->bi_dram[0].size = gd->ram_size; +} + +/* + * This function looks for the highest region of memory lower than 4GB which + * has enough space for U-Boot where U-Boot is aligned on a page boundary. + * It overrides the default implementation found elsewhere which simply + * picks the end of ram, wherever that may be. The location of the stack, + * the relocation address, and how far U-Boot is moved by relocation are + * set in the global data structure. + */ +ulong board_get_usable_ram_top(ulong total_size) +{ + return gd->ram_size; +} diff --git a/arch/x86/cpu/qemu/pci.c b/arch/x86/cpu/qemu/pci.c new file mode 100644 index 0000000000..d50ab752d3 --- /dev/null +++ b/arch/x86/cpu/qemu/pci.c @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +void board_pci_setup_hose(struct pci_controller *hose) +{ + hose->first_busno = 0; + hose->last_busno = 0; + + /* PCI memory space */ + pci_set_region(hose->regions + 0, + CONFIG_PCI_MEM_BUS, + CONFIG_PCI_MEM_PHYS, + CONFIG_PCI_MEM_SIZE, + PCI_REGION_MEM); + + /* PCI IO space */ + pci_set_region(hose->regions + 1, + CONFIG_PCI_IO_BUS, + CONFIG_PCI_IO_PHYS, + CONFIG_PCI_IO_SIZE, + PCI_REGION_IO); + + pci_set_region(hose->regions + 2, + CONFIG_PCI_PREF_BUS, + CONFIG_PCI_PREF_PHYS, + CONFIG_PCI_PREF_SIZE, + PCI_REGION_PREFETCH); + + pci_set_region(hose->regions + 3, + 0, + 0, + gd->ram_size, + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + + hose->region_count = 4; +} + +int board_pci_post_scan(struct pci_controller *hose) +{ + return 0; +} diff --git a/arch/x86/cpu/qemu/qemu.c b/arch/x86/cpu/qemu/qemu.c new file mode 100644 index 0000000000..0f984768e9 --- /dev/null +++ b/arch/x86/cpu/qemu/qemu.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +int arch_cpu_init(void) +{ + int ret; + + post_code(POST_CPU_INIT); +#ifdef CONFIG_SYS_X86_TSC_TIMER + timer_set_base(rdtsc()); +#endif + + ret = x86_cpu_init_f(); + if (ret) + return ret; + + return 0; +} + +int print_cpuinfo(void) +{ + post_code(POST_CPU_INFO); + return default_print_cpuinfo(); +} + +void reset_cpu(ulong addr) +{ + /* cold reset */ + x86_full_reset(); +} diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile index 431bbd8a0d..ca2eab3fa2 100644 --- a/arch/x86/dts/Makefile +++ b/arch/x86/dts/Makefile @@ -2,7 +2,8 @@ dtb-y += chromebook_link.dtb \ chromebox_panther.dtb \ crownbay.dtb \ galileo.dtb \ - minnowmax.dtb + minnowmax.dtb \ + qemu-x86.dtb targets += $(dtb-y) diff --git a/arch/x86/dts/qemu-x86.dts b/arch/x86/dts/qemu-x86.dts new file mode 100644 index 0000000000..f1291b5da7 --- /dev/null +++ b/arch/x86/dts/qemu-x86.dts @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; + +/include/ "skeleton.dtsi" +/include/ "serial.dtsi" + +/ { + model = "QEMU x86"; + compatible = "qemu,x86"; + + config { + silent_console = <0>; + }; + + chosen { + stdout-path = "/serial"; + }; + + pci { + compatible = "pci-x86"; + #address-cells = <3>; + #size-cells = <2>; + u-boot,dm-pre-reloc; + ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0 0x10000000 + 0x42000000 0x0 0xd0000000 0xd0000000 0 0x10000000 + 0x01000000 0x0 0x2000 0x2000 0 0xe000>; + }; + +}; diff --git a/arch/x86/include/asm/arch-qemu/gpio.h b/arch/x86/include/asm/arch-qemu/gpio.h new file mode 100644 index 0000000000..ca8cba4f97 --- /dev/null +++ b/arch/x86/include/asm/arch-qemu/gpio.h @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _X86_ARCH_GPIO_H_ +#define _X86_ARCH_GPIO_H_ + +/* Where in config space is the register that points to the GPIO registers? */ +#define PCI_CFG_GPIOBASE 0x44 + +#endif /* _X86_ARCH_GPIO_H_ */ diff --git a/arch/x86/include/asm/arch-qemu/qemu.h b/arch/x86/include/asm/arch-qemu/qemu.h new file mode 100644 index 0000000000..8d7e9861ca --- /dev/null +++ b/arch/x86/include/asm/arch-qemu/qemu.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ARCH_QEMU_H_ +#define _ARCH_QEMU_H_ + +/* I/O Ports */ +#define CMOS_ADDR_PORT 0x70 +#define CMOS_DATA_PORT 0x71 + +#define LOW_RAM_ADDR 0x34 +#define HIGH_RAM_ADDR 0x35 + +#endif /* _ARCH_QEMU_H_ */ diff --git a/board/emulation/Kconfig b/board/emulation/Kconfig new file mode 100644 index 0000000000..36809fd376 --- /dev/null +++ b/board/emulation/Kconfig @@ -0,0 +1,25 @@ +# +# Copyright (C) 2015, Bin Meng +# +# SPDX-License-Identifier: GPL-2.0+ +# + +if VENDOR_EMULATION + +choice + prompt "Mainboard model" + +config TARGET_QEMU_X86 + bool "QEMU x86" + help + This is the QEMU emulated x86 board. U-Boot supports running + as a coreboot payload as well as bare boot without coreboot. + There are two types of x86 boards supported by QEMU which are + supported by U-Boot. They are via QEMU '-M pc', an i440FX/PIIX + chipset platform and '-M q35', a Q35/ICH9 chipset platform. + +endchoice + +source "board/emulation/qemu-x86/Kconfig" + +endif diff --git a/board/emulation/qemu-x86/Kconfig b/board/emulation/qemu-x86/Kconfig new file mode 100644 index 0000000000..e777ef4409 --- /dev/null +++ b/board/emulation/qemu-x86/Kconfig @@ -0,0 +1,24 @@ +if TARGET_QEMU_X86 + +config SYS_BOARD + default "qemu-x86" + +config SYS_VENDOR + default "emulation" + +config SYS_SOC + default "qemu" + +config SYS_CONFIG_NAME + default "qemu-x86" + +config SYS_TEXT_BASE + default 0xfff00000 + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select X86_RESET_VECTOR + select QEMU + select BOARD_ROMSIZE_KB_1024 + +endif diff --git a/board/emulation/qemu-x86/MAINTAINERS b/board/emulation/qemu-x86/MAINTAINERS new file mode 100644 index 0000000000..ea4dd19354 --- /dev/null +++ b/board/emulation/qemu-x86/MAINTAINERS @@ -0,0 +1,6 @@ +QEMU X86 BOARD +M: Bin Meng +S: Maintained +F: board/emulation/qemu-x86/ +F: include/configs/qemu-x86.h +F: configs/qemu-x86_defconfig diff --git a/board/emulation/qemu-x86/Makefile b/board/emulation/qemu-x86/Makefile new file mode 100644 index 0000000000..ad2bbb94a2 --- /dev/null +++ b/board/emulation/qemu-x86/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2015, Bin Meng +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += qemu-x86.o start.o diff --git a/board/emulation/qemu-x86/qemu-x86.c b/board/emulation/qemu-x86/qemu-x86.c new file mode 100644 index 0000000000..fedea81abc --- /dev/null +++ b/board/emulation/qemu-x86/qemu-x86.c @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + +int board_eth_init(bd_t *bis) +{ + return pci_eth_init(bis); +} diff --git a/board/emulation/qemu-x86/start.S b/board/emulation/qemu-x86/start.S new file mode 100644 index 0000000000..a71db69be9 --- /dev/null +++ b/board/emulation/qemu-x86/start.S @@ -0,0 +1,9 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +.globl early_board_init +early_board_init: + jmp early_board_init_ret diff --git a/configs/qemu-x86_defconfig b/configs/qemu-x86_defconfig new file mode 100644 index 0000000000..53cb553fa4 --- /dev/null +++ b/configs/qemu-x86_defconfig @@ -0,0 +1,7 @@ +CONFIG_X86=y +CONFIG_VENDOR_EMULATION=y +CONFIG_TARGET_QEMU_X86=y +CONFIG_CMD_NET=y +CONFIG_OF_CONTROL=y +CONFIG_OF_SEPARATE=y +CONFIG_DEFAULT_DEVICE_TREE="qemu-x86" diff --git a/include/configs/qemu-x86.h b/include/configs/qemu-x86.h new file mode 100644 index 0000000000..463620d809 --- /dev/null +++ b/include/configs/qemu-x86.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * board/config.h - configuration options, board specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +#define CONFIG_SYS_MONITOR_LEN (1 << 20) + +#define CONFIG_NR_DRAM_BANKS 1 + +#define CONFIG_X86_SERIAL + +#define CONFIG_PCI_MEM_BUS 0xc0000000 +#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS +#define CONFIG_PCI_MEM_SIZE 0x10000000 + +#define CONFIG_PCI_PREF_BUS 0xd0000000 +#define CONFIG_PCI_PREF_PHYS CONFIG_PCI_PREF_BUS +#define CONFIG_PCI_PREF_SIZE 0x10000000 + +#define CONFIG_PCI_IO_BUS 0x2000 +#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS +#define CONFIG_PCI_IO_SIZE 0xe000 + +#define CONFIG_PCI_PNP +#define CONFIG_E1000 + +#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial\0" \ + "stdout=serial\0" \ + "stderr=serial\0" + +#define CONFIG_SCSI_DEV_LIST \ + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1} + +/* GPIO is not supported */ +#undef CONFIG_INTEL_ICH6_GPIO +#undef CONFIG_CMD_GPIO + +/* SPI is not supported */ +#undef CONFIG_ICH_SPI +#undef CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_ENV_IS_NOWHERE + +/* Video is not supported */ +#undef CONFIG_VIDEO +#undef CONFIG_CFB_CONSOLE + +#endif /* __CONFIG_H */