Add support for running barebox on the QEMU ppce500 virtual machine. This enables automated testing of PowerPC e500 support in CI.
The ppce500 machine places CCSRBAR at effective address 0xE0000000 (physical 0xF_E0000000 with 36-bit addressing). The assembly entry sets up TLB entries for RAM, CCSRBAR MMIO, and the boot page, then jumps to C code which parses the timebase-frequency from the QEMU- provided device tree to configure the clocksource correctly (QEMU does not implement the GUTS PORPLLSR register). Poweroff is handled by the existing gpio-poweroff driver, which uses the fsl,qoriq-gpio controller exposed in QEMU's device tree. Co-Authored-By: Claude Opus 4.6 <[email protected]> Signed-off-by: Ahmad Fatoum <[email protected]> --- .github/workflows/test-labgrid-pytest.yml | 4 + arch/powerpc/Makefile | 1 + arch/powerpc/boards/qemu-e500/Makefile | 5 + arch/powerpc/boards/qemu-e500/law.c | 17 ++ arch/powerpc/boards/qemu-e500/qemu-e500.c | 92 ++++++++ arch/powerpc/boards/qemu-e500/tlb.c | 17 ++ arch/powerpc/configs/qemu-ppce500_defconfig | 69 ++++++ arch/powerpc/cpu-85xx/Makefile | 3 + arch/powerpc/cpu-85xx/start-qemu.S | 211 ++++++++++++++++++ arch/powerpc/include/asm/board-qemu-e500.h | 39 ++++ arch/powerpc/include/asm/config.h | 2 + arch/powerpc/include/asm/debug_ll.h | 52 +++++ arch/powerpc/lib/board.c | 6 + arch/powerpc/mach-mpc85xx/Kconfig | 13 ++ arch/powerpc/mach-mpc85xx/barebox.lds.S | 12 + .../include/mach/config_mpc85xx.h | 6 + common/Kconfig.debug_ll | 7 +- test/powerpc/qemu-ppce500_defconfig.yaml | 17 ++ 18 files changed, 572 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/boards/qemu-e500/Makefile create mode 100644 arch/powerpc/boards/qemu-e500/law.c create mode 100644 arch/powerpc/boards/qemu-e500/qemu-e500.c create mode 100644 arch/powerpc/boards/qemu-e500/tlb.c create mode 100644 arch/powerpc/configs/qemu-ppce500_defconfig create mode 100644 arch/powerpc/cpu-85xx/start-qemu.S create mode 100644 arch/powerpc/include/asm/board-qemu-e500.h create mode 100644 arch/powerpc/include/asm/debug_ll.h create mode 100644 test/powerpc/qemu-ppce500_defconfig.yaml diff --git a/.github/workflows/test-labgrid-pytest.yml b/.github/workflows/test-labgrid-pytest.yml index c06bc5f11faa..7e385af65245 100644 --- a/.github/workflows/test-labgrid-pytest.yml +++ b/.github/workflows/test-labgrid-pytest.yml @@ -49,6 +49,10 @@ jobs: lgenv: test/openrisc/generic_defconfig.yaml defconfig: generic_defconfig + - ARCH: powerpc + lgenv: test/powerpc/qemu-ppce500_defconfig.yaml + defconfig: qemu-ppce500_defconfig + - ARCH: x86 lgenv: test/x86/efi_defconfig.yaml defconfig: efi_defconfig diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index ebd8fe60d3f1..fa511c6c1295 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -18,6 +18,7 @@ KBUILD_CPPFLAGS += -Wa,-me500x2 -msoft-float -mno-string endif board-$(CONFIG_MACH_PHYCORE_MPC5200B_TINY) := pcm030 +board-$(CONFIG_QEMU_PPCE500) := qemu-e500 board-$(CONFIG_P1010RDB) := freescale-p1010rdb board-$(CONFIG_P2020RDB) := freescale-p2020rdb board-$(CONFIG_P1022DS) := freescale-p1022ds diff --git a/arch/powerpc/boards/qemu-e500/Makefile b/arch/powerpc/boards/qemu-e500/Makefile new file mode 100644 index 000000000000..15add493eea8 --- /dev/null +++ b/arch/powerpc/boards/qemu-e500/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-y += qemu-e500.o +obj-y += tlb.o +obj-y += law.o diff --git a/arch/powerpc/boards/qemu-e500/law.c b/arch/powerpc/boards/qemu-e500/law.c new file mode 100644 index 000000000000..97683b01a573 --- /dev/null +++ b/arch/powerpc/boards/qemu-e500/law.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * LAW configuration for QEMU ppce500 + * + * QEMU virtual hardware doesn't require LAW (Local Access Window) + * configuration, so we provide an empty table. + */ + +#include <linux/types.h> +#include <linux/array_size.h> +#include <asm/fsl_law.h> + +struct law_entry law_table[] = { + /* No LAW entries needed for QEMU virtual hardware */ +}; + +int num_law_entries = ARRAY_SIZE(law_table); diff --git a/arch/powerpc/boards/qemu-e500/qemu-e500.c b/arch/powerpc/boards/qemu-e500/qemu-e500.c new file mode 100644 index 000000000000..70f22aa9b118 --- /dev/null +++ b/arch/powerpc/boards/qemu-e500/qemu-e500.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Board support for QEMU ppce500 virtual machine + */ + +#include <barebox-info.h> +#include <deep-probe.h> +#include <init.h> +#include <of.h> +#include <linux/libfdt.h> +#include <asm/processor.h> +#include <asm/cache.h> +#include <mach/mpc85xx.h> +#include <mach/clock.h> +#include <debug_ll.h> + +/* Global pointer to device tree */ +static void *fdt; + +/* Called from start-qemu.S assembly */ +void qemu_e500_entry(void *fdt_blob); + +/* Called from board initialization */ +extern void board_init_r(ulong end_of_ram); + +void qemu_e500_entry(void *fdt_blob) +{ + int cpus_off, cpu_off, len; + const fdt32_t *prop; + + /* Initialize debug UART first */ + debug_ll_init(); + + putc_ll('Q'); + putc_ll('E'); + putc_ll('M'); + putc_ll('U'); + putc_ll('\r'); + putc_ll('\n'); + + /* Save FDT to global for later use */ + fdt = fdt_blob; + + /* + * Parse timebase-frequency from QEMU's FDT. The MPC85xx GUTS + * PORPLLSR register is unimplemented in QEMU and reads as zero, + * so the normal register-based clock calculation fails. + */ + cpus_off = fdt_path_offset(fdt_blob, "/cpus"); + if (cpus_off >= 0) { + cpu_off = fdt_first_subnode(fdt_blob, cpus_off); + if (cpu_off >= 0) { + prop = fdt_getprop(fdt_blob, cpu_off, + "timebase-frequency", &len); + if (prop && len == sizeof(*prop)) + fsl_set_timebase_clock(fdt32_to_cpu(*prop)); + } + } + + putc_ll('F'); + putc_ll('D'); + putc_ll('T'); + putc_ll(':'); + puthex_ll((unsigned long)fdt_blob); + putc_ll('\r'); + putc_ll('\n'); + + putc_ll('B'); + putc_ll('R'); + putc_ll('\r'); + putc_ll('\n'); + + board_init_r(256 * 1024 * 1024); +} + +static int qemu_e500_of_init(void) +{ + if (!fdt) + return 0; + + barebox_set_model("QEMU ppce500"); + barebox_set_hostname("qemu-e500"); + + return barebox_register_fdt(fdt); +} +core_initcall(qemu_e500_of_init); + +static const struct of_device_id qemu_e500_of_match[] = { + { .compatible = "fsl,qemu-e500" }, + { /* sentinel */ }, +}; +BAREBOX_DEEP_PROBE_ENABLE(qemu_e500_of_match); diff --git a/arch/powerpc/boards/qemu-e500/tlb.c b/arch/powerpc/boards/qemu-e500/tlb.c new file mode 100644 index 000000000000..a0f31a6fa85d --- /dev/null +++ b/arch/powerpc/boards/qemu-e500/tlb.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * TLB configuration for QEMU ppce500 + * + * QEMU sets up TLB entries before jumping to firmware, so we + * provide a minimal table here just for the API. + */ + +#include <linux/types.h> +#include <linux/array_size.h> +#include <mach/mmu.h> + +struct fsl_e_tlb_entry tlb_table[] = { + /* QEMU already configured TLB - empty table */ +}; + +int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/arch/powerpc/configs/qemu-ppce500_defconfig b/arch/powerpc/configs/qemu-ppce500_defconfig new file mode 100644 index 000000000000..6a0e070f4996 --- /dev/null +++ b/arch/powerpc/configs/qemu-ppce500_defconfig @@ -0,0 +1,69 @@ +CONFIG_ARCH_MPC85XX=y +CONFIG_QEMU_PPCE500=y +CONFIG_NAME="qemu-ppce500_defconfig" +CONFIG_MALLOC_SIZE=0x100000 +CONFIG_RELOCATABLE=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_BOOTM_VERBOSE=y +CONFIG_DEBUG_LL=y +CONFIG_CMD_DMESG=y +CONFIG_LONGHELP=y +CONFIG_CMD_IOMEM=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_NVMEM=y +CONFIG_CMD_GO=y +CONFIG_CMD_LOADY=y +CONFIG_CMD_RESET=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_FINDMNT=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_DEFAULTENV=y +CONFIG_CMD_LOADENV=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_MAGICVAR=y +CONFIG_CMD_MAGICVAR_HELP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_FILETYPE=y +CONFIG_CMD_LN=y +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_SHA1SUM=y +CONFIG_CMD_SHA256SUM=y +CONFIG_CMD_LET=y +CONFIG_CMD_MSLEEP=y +CONFIG_CMD_READF=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_EDIT=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_CRC=y +CONFIG_CMD_CRC_CMP=y +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_DETECT=y +CONFIG_CMD_FLASH=y +CONFIG_CMD_POWEROFF=y +CONFIG_CMD_OF_DIFF=y +CONFIG_CMD_OF_NODE=y +CONFIG_CMD_OF_PROPERTY=y +CONFIG_CMD_OF_FIXUP_STATUS=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_TIME=y +CONFIG_OFDEVICE=y +CONFIG_OF_BAREBOX_DRIVERS=y +CONFIG_DRIVER_SERIAL_NS16550=y +CONFIG_GPIO_MPC8XXX=y +CONFIG_NVMEM=y +CONFIG_NVMEM_RMEM=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_TEST=y +CONFIG_SELFTEST=y +CONFIG_SELFTEST_BASE64=y +CONFIG_SELFTEST_RANGE=y +CONFIG_SELFTEST_MALLOC=y +CONFIG_SELFTEST_PRINTF=y +CONFIG_SELFTEST_OF_MANIPULATION=y +CONFIG_SELFTEST_PROGRESS_NOTIFIER=y +CONFIG_SELFTEST_STRING=y +CONFIG_SELFTEST_RESOURCE=y +CONFIG_SELFTEST_IDR=y diff --git a/arch/powerpc/cpu-85xx/Makefile b/arch/powerpc/cpu-85xx/Makefile index cc85eb759472..a902ecb9c659 100644 --- a/arch/powerpc/cpu-85xx/Makefile +++ b/arch/powerpc/cpu-85xx/Makefile @@ -4,5 +4,8 @@ obj-y += traps.o obj-y += tlb.o obj-y += cache.o obj-$(CONFIG_MMU) += mmu.o +extra-$(CONFIG_QEMU_PPCE500) += start-qemu.o +ifndef CONFIG_QEMU_PPCE500 extra-y += start.o extra-y += resetvec.o +endif diff --git a/arch/powerpc/cpu-85xx/start-qemu.S b/arch/powerpc/cpu-85xx/start-qemu.S new file mode 100644 index 000000000000..fd3a9aeec27e --- /dev/null +++ b/arch/powerpc/cpu-85xx/start-qemu.S @@ -0,0 +1,211 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * ePAPR-compliant entry point for QEMU e500 platforms (mpc8544ds/ppce500) + * + * QEMU sets up the following CPU state before jumping to firmware: + * - r1 = 16MB - 8 (initial stack) + * - r3 = FDT physical address + * - r6 = EPAPR_MAGIC (0x45504150) + * - r7 = Initial TLB map size + * - TLB1[0] = Identity map covering RAM + FDT + */ + +#include <asm/config.h> +#include <asm/processor.h> +#include <asm/ppc_asm.tmpl> +#include <asm/ppc_defs.h> +#include <asm/cache.h> +#include <mach/mmu.h> + +#undef MSR_KERNEL +#define MSR_KERNEL (MSR_ME) /* Machine Check */ + + .section .text_entry + .globl _start_qemu_e500 + .globl _start + +_start: +_start_qemu_e500: + /* + * Entry from QEMU with ePAPR boot convention: + * r3 = FDT pointer (must be preserved) + * r6 = EPAPR_MAGIC + * r1 = initial stack (16MB - 8) + * TLB already set up by QEMU for RAM + */ + + /* Save FDT pointer to r31 (callee-saved) */ + mr r31, r3 + + /* Enable machine check exception */ + li r0, MSR_KERNEL + mtmsr r0 + isync + + /* Invalidate L1 caches */ + li r0, 2 + mtspr L1CSR0, r0 /* invalidate d-cache */ + mtspr L1CSR1, r0 /* invalidate i-cache */ + isync + + /* Clear debug status */ + mfspr r0, DBSR + mtspr DBSR, r0 + isync + + /* Clear and set up timer/exception registers */ + li r0, 0 + lis r1, 0xffff + mtspr DEC, r0 /* prevent dec exceptions */ + mttbl r0 /* prevent fit & wdt exceptions */ + mttbu r0 + mtspr TSR, r1 /* clear all timer exception status */ + mtspr TCR, r0 /* disable all timers */ + mtspr ESR, r0 /* clear exception syndrome register */ + mtspr MCSR, r0 /* machine check syndrome register */ + mtxer r0 /* clear integer exception register */ + + /* Enable machine check and timebase in HID0 */ + lis r0, HID0_EMCP@h + ori r0, r0, HID0_TBEN@l + mtspr HID0, r0 + + /* Setup IVPR for exception vectors */ + lis r0, TEXT_BASE@h + ori r0, r0, TEXT_BASE@l + mtspr IVPR, r0 + isync + + /* + * Set up TLB1[1]: Map CCSRBAR (16MB, cache-inhibited, guarded) + * + * mpc8544ds: CCSRBAR at 0x0_E0000000 (MAS7 = 0x0) + * ppce500: CCSRBAR at 0xF_E0000000 (MAS7 = 0xF) + */ + lis r0, FSL_BOOKE_MAS0(1, 1, 0)@h + ori r0, r0, FSL_BOOKE_MAS0(1, 1, 0)@l + mtspr MAS0, r0 + lis r0, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M)@h + ori r0, r0, FSL_BOOKE_MAS1(1, 1, 0, 0, BOOKE_PAGESZ_16M)@l + mtspr MAS1, r0 + lis r0, FSL_BOOKE_MAS2(CFG_CCSRBAR, (MAS2_I | MAS2_G))@h + ori r0, r0, FSL_BOOKE_MAS2(CFG_CCSRBAR, (MAS2_I | MAS2_G))@l + mtspr MAS2, r0 + lis r0, FSL_BOOKE_MAS3(CFG_CCSRBAR, 0, (MAS3_SX | MAS3_SW | MAS3_SR))@h + ori r0, r0, FSL_BOOKE_MAS3(CFG_CCSRBAR, 0, (MAS3_SX | MAS3_SW | MAS3_SR))@l + mtspr MAS3, r0 + li r0, CFG_CCSRBAR_PHYS_HIGH + mtspr MAS7, r0 + isync + msync + tlbwe + isync + + /* + * Clear BSS before calling C code. + */ + lis r3, __bss_start@h + ori r3, r3, __bss_start@l + lis r4, __bss_stop@h + ori r4, r4, __bss_stop@l + li r0, 0 + cmplw 0, r3, r4 + beq 2f +1: stw r0, 0(r3) + addi r3, r3, 4 + cmplw 0, r3, r4 + blt 1b +2: + + /* Restore stack pointer (was clobbered by timer setup above) */ + lis r1, (16 * 1024 * 1024 - 8)@h + ori r1, r1, (16 * 1024 * 1024 - 8)@l + + /* Clear LR for clean stack traces */ + li r0, 0 + mtlr r0 + + /* Jump to C entry with FDT pointer in r3 */ + mr r3, r31 + lis r4, qemu_e500_entry@h + ori r4, r4, qemu_e500_entry@l + mtctr r4 + bctr + + /* Should never return */ + b . + +/* + * Low-level helper functions required by barebox + */ + +/* get_svr: Return System Version Register */ + .globl get_svr +get_svr: + mfspr r3, SVR + blr + +/* invalidate_icache: Invalidate instruction cache */ + .globl invalidate_icache +invalidate_icache: + mfspr r0, L1CSR1 + ori r0, r0, L1CSR1_ICFI + msync + isync + mtspr L1CSR1, r0 + isync + blr + +/* flush_dcache: Flush data cache */ + .globl flush_dcache +flush_dcache: + mfspr r3, SPRN_L1CFG0 + rlwinm r5, r3, 9, 3 + li r4, 32 + subfic r6, r5, 2 + slw r5, r4, r5 + rlwinm r7, r3, 0, 0xff + mulli r7, r7, 13 + slw r7, r7, r6 + + mfspr r8, SPRN_HID0 + ori r9, r8, HID0_DCFA@l + mtspr SPRN_HID0, r9 + isync + + lis r4, 0 + mtctr r7 + +1: lwz r3, 0(r4) + add r4, r4, r5 + bdnz 1b + + mtspr SPRN_HID0, r8 + isync + blr + +/* trap_init: Initialize exception vectors - simplified for QEMU */ + .globl trap_init +trap_init: + blr + +/* + * void e500_write_tlb(mas0, mas1, mas2, mas3, mas7) + */ + .globl e500_write_tlb +e500_write_tlb: + mtspr MAS0, r3 + mtspr MAS1, r4 + mtspr MAS2, r5 + mtspr MAS3, r6 + mtspr MAS7, r7 + isync + tlbwe + msync + isync + blr + +/* _text_base: Text base address variable */ + .globl _text_base +_text_base: + .long TEXT_BASE diff --git a/arch/powerpc/include/asm/board-qemu-e500.h b/arch/powerpc/include/asm/board-qemu-e500.h new file mode 100644 index 000000000000..625d27b5185d --- /dev/null +++ b/arch/powerpc/include/asm/board-qemu-e500.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * QEMU ppce500 virtual machine configuration + * + * CCSRBAR effective address is 0xE0000000, physical 0xF_E0000000 + * (36-bit, MAS7 = 0xF). + */ + +#ifndef __ASM_BOARD_QEMU_E500_H +#define __ASM_BOARD_QEMU_E500_H + +/* + * Serial clock - QEMU's ns16550 baudbase is 399193, but we use + * 1843200 (standard 16550 crystal) so the divisor calculation + * produces a reasonable value. QEMU ignores the actual baud rate. + */ +#define CFG_SYS_CLK_FREQ 1843200 + +/* + * DDR configuration - QEMU doesn't have a real DDR controller, + * but the define is needed for compilation. + */ +#define CFG_CHIP_SELECTS_PER_CTRL 1 + +#define CFG_SDRAM_BASE 0x00000000 + +/* + * CCSR (CCSRBAR) - SoC register space + * + * QEMU ppce500 maps CCSRBAR at effective address 0xE0000000, + * physical address 0xF_E0000000 (36-bit, MAS7 = 0xF). + */ +#define CFG_CCSRBAR_DEFAULT 0xE0000000 +#define CFG_CCSRBAR 0xE0000000 +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR +#define CFG_CCSRBAR_PHYS_HIGH 0xF +#define CFG_IMMR CFG_CCSRBAR + +#endif /* __ASM_BOARD_QEMU_E500_H */ diff --git a/arch/powerpc/include/asm/config.h b/arch/powerpc/include/asm/config.h index 727daa872f20..59965095b92e 100644 --- a/arch/powerpc/include/asm/config.h +++ b/arch/powerpc/include/asm/config.h @@ -39,6 +39,8 @@ #ifdef CONFIG_MACH_PHYCORE_MPC5200B_TINY #include <asm/board-pcm030.h> +#elif defined(CONFIG_QEMU_PPCE500) +#include <asm/board-qemu-e500.h> #elif defined(CONFIG_P1010RDB) #include <asm/board-p1010rdb.h> #elif defined(CONFIG_P2020RDB) diff --git a/arch/powerpc/include/asm/debug_ll.h b/arch/powerpc/include/asm/debug_ll.h new file mode 100644 index 000000000000..910db2808d81 --- /dev/null +++ b/arch/powerpc/include/asm/debug_ll.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __ASM_DEBUG_LL_H__ +#define __ASM_DEBUG_LL_H__ + +#include <io.h> + +#ifdef CONFIG_DEBUG_QEMU_PPCE500 + +#include <asm/board-qemu-e500.h> + +/* + * QEMU ppce500 NS16550 UART at CCSRBAR + 0x4500 + * Clock is platform clock (400 MHz default) + */ +#define DEBUG_LL_UART_BASE IOMEM(CFG_CCSRBAR + 0x4500) +#define DEBUG_LL_UART_CLK CFG_SYS_CLK_FREQ + +static inline uint8_t debug_ll_read_reg(void __iomem *base, int reg) +{ + return readb(base + reg); +} + +static inline void debug_ll_write_reg(void __iomem *base, int reg, uint8_t val) +{ + writeb(val, base + reg); +} + +#include <debug_ll/ns16550.h> + +static inline void debug_ll_init(void) +{ + uint16_t divisor; + + divisor = debug_ll_ns16550_calc_divisor(DEBUG_LL_UART_CLK); + debug_ll_ns16550_init(DEBUG_LL_UART_BASE, divisor); +} + +static inline void PUTC_LL(int c) +{ + debug_ll_ns16550_putc(DEBUG_LL_UART_BASE, c); +} + +#else + +static inline void debug_ll_init(void) +{ +} + +#endif /* CONFIG_DEBUG_QEMU_PPCE500 */ + +#endif /* __ASM_DEBUG_LL_H__ */ diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index a6111606b68c..3781345926a4 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -43,7 +43,13 @@ void board_init_r (ulong end_of_ram) asm ("sync ; isync"); #ifdef CONFIG_MPC85xx +#ifndef CONFIG_QEMU_PPCE500 + /* Traditional boards relocate to end of RAM */ _text_base = end_of_ram; +#else + /* QEMU: no relocation, stay at link address */ + _text_base = TEXT_BASE; +#endif #endif malloc_end = (_text_base - STACK_SIZE) & ~(4095); diff --git a/arch/powerpc/mach-mpc85xx/Kconfig b/arch/powerpc/mach-mpc85xx/Kconfig index 550c554286d7..7f184babbee1 100644 --- a/arch/powerpc/mach-mpc85xx/Kconfig +++ b/arch/powerpc/mach-mpc85xx/Kconfig @@ -11,11 +11,13 @@ config BTB config TEXT_BASE hex + default 0x00f00000 if QEMU_PPCE500 default 0xeff80000 if P1010RDB || P2020RDB || P1022DS default 0xfff80000 if DA923RC config RESET_VECTOR_ADDRESS hex + default 0x00000000 if QEMU_PPCE500 default 0xfffffffc if DA923RC default 0xeffffffc if P1010RDB || P2020RDB || P1022DS @@ -33,6 +35,7 @@ config E500 choice prompt "Select your board" + config P1010RDB bool "P1010RDB" select P1010 @@ -64,6 +67,16 @@ config DA923RC select FSL_DDR2 help Say Y here if you are using the GE Intelligent Platforms DA923RC + +config QEMU_PPCE500 + bool "QEMU ppce500" + select HAS_DEBUG_LL + select LIBFDT + select GPIOLIB + help + Say Y here for QEMU ppce500 generic paravirt e500 support. + CCSRBAR is at 36-bit physical address 0xFE0000000. + endchoice endif diff --git a/arch/powerpc/mach-mpc85xx/barebox.lds.S b/arch/powerpc/mach-mpc85xx/barebox.lds.S index 5407ecc7e295..989fec7f1def 100644 --- a/arch/powerpc/mach-mpc85xx/barebox.lds.S +++ b/arch/powerpc/mach-mpc85xx/barebox.lds.S @@ -22,7 +22,11 @@ #endif OUTPUT_ARCH(BAREBOX_OUTPUT_ARCH) +#ifdef CONFIG_QEMU_PPCE500 +ENTRY(_start_qemu_e500) +#else ENTRY(_start_e500) +#endif PHDRS { @@ -122,6 +126,8 @@ SECTIONS __init_size = __init_end - _start; +#ifndef CONFIG_QEMU_PPCE500 + /* Boot page and reset vector for flash boot */ .bootpg RESET_VECTOR_ADDRESS - 0xffc : { _text = .; @@ -140,6 +146,12 @@ SECTIONS /* This avoids wrapping around to offset 0 */ . |= 0x10; #endif +#else + /* QEMU entry point: simpler, no boot page or reset vector needed */ + .text_entry : { + arch/powerpc/cpu-85xx/start-qemu.o (.text_entry) + } :text +#endif __bss_start = .; .bss : diff --git a/arch/powerpc/mach-mpc85xx/include/mach/config_mpc85xx.h b/arch/powerpc/mach-mpc85xx/include/mach/config_mpc85xx.h index fad2c47d110f..0a53282c623c 100644 --- a/arch/powerpc/mach-mpc85xx/include/mach/config_mpc85xx.h +++ b/arch/powerpc/mach-mpc85xx/include/mach/config_mpc85xx.h @@ -57,6 +57,12 @@ #define PPC_E500_DEBUG_TLB 2 #define FSL_TSECV2 +#elif defined(CONFIG_QEMU_PPCE500) +#define MAX_CPUS 1 +#define FSL_NUM_LAWS 12 +#define PPC_E500_DEBUG_TLB 0 +/* QEMU e500: generic e500v2 platform, minimal configuration */ + #else #error Processor type not defined for this platform #endif diff --git a/common/Kconfig.debug_ll b/common/Kconfig.debug_ll index a08d29859d27..b11df2b79925 100644 --- a/common/Kconfig.debug_ll +++ b/common/Kconfig.debug_ll @@ -311,6 +311,11 @@ config DEBUG_ZYNQMP_UART Say Y here if you want kernel low-level debugging support on Zynqmp. +config DEBUG_QEMU_PPCE500 + bool "Qemu ppce500 PowerPC ns16550 port" + depends on QEMU_PPCE500 + select DEBUG_LL_NS16550 + config DEBUG_ERIZO bool "Erizo ns16550 port" depends on SOC_ERIZO @@ -382,7 +387,7 @@ endchoice config DEBUG_LL_NS16550 bool help - Selected by RISC-V platforms that use ns16550 for debug_ll + Selected by RISC-V and PowerPC platforms that use ns16550 for debug_ll config DEBUG_IMX_UART_PORT int "i.MX Debug UART Port Selection" if DEBUG_IMX1_UART || \ diff --git a/test/powerpc/qemu-ppce500_defconfig.yaml b/test/powerpc/qemu-ppce500_defconfig.yaml new file mode 100644 index 000000000000..d64f42fc6eca --- /dev/null +++ b/test/powerpc/qemu-ppce500_defconfig.yaml @@ -0,0 +1,17 @@ +targets: + main: + drivers: + QEMUDriver: + qemu_bin: qemu-system-ppc + machine: ppce500 + cpu: e500 + memory: 256M + kernel: barebox + display: qemu-default + BareboxDriver: + prompt: 'barebox:[^ ]+ ' + BareboxTestStrategy: {} +images: + barebox: !template "$LG_BUILDDIR/barebox" +imports: + - ../strategy.py -- 2.47.3
