Naman Govil (namangov@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/10527
-gerrit
commit 01bf3d703250022854eda3897c694c232af4ad92 Author: Naman Govil namangov@gmail.com Date: Wed Jul 15 02:51:36 2015 -0400
armv8 : coreboot for qemu aarch64 #Work in progress#
This patchset aims to add a new mainboard (emulation) for arm64. By the end of this work, we will have coreboot running on a qemu-system-aarch64.
Change-Id: I5550dcaae9981908e0c3bf6961206a70bebac5d1 Signed-off-by: Naman Govil namangov@gmail.com --- src/arch/arm64/armv8/bootblock_simple.c | 2 +- src/arch/arm64/c_entry.c | 22 ++- src/arch/arm64/cpu.c | 3 +- src/arch/arm64/cpu.h | 204 +++++++++++++++++++++ src/arch/arm64/include/arch/cpu.h | 204 +++++++++++++++++++++ src/arch/arm64/include/armv8/arch/secmon.h | 4 +- src/cpu/armltd/armv8/Kconfig | 11 ++ src/mainboard/emulation/qemu-armv8/Kconfig | 57 ++++++ src/mainboard/emulation/qemu-armv8/Kconfig.name | 2 + src/mainboard/emulation/qemu-armv8/Makefile.inc | 40 ++++ src/mainboard/emulation/qemu-armv8/board_info.txt | 3 + .../emulation/qemu-armv8/bootblock-common.h | 19 ++ src/mainboard/emulation/qemu-armv8/bootblock.c | 22 +++ src/mainboard/emulation/qemu-armv8/cbmem.c | 25 +++ src/mainboard/emulation/qemu-armv8/cpu_lib.S | 29 +++ src/mainboard/emulation/qemu-armv8/devicetree.cb | 20 ++ src/mainboard/emulation/qemu-armv8/mainboard.c | 27 +++ src/mainboard/emulation/qemu-armv8/media.c | 25 +++ src/mainboard/emulation/qemu-armv8/memlayout.ld | 48 +++++ src/mainboard/emulation/qemu-armv8/romstage.c | 24 +++ src/mainboard/emulation/qemu-armv8/timer.c | 27 +++ src/mainboard/emulation/qemu-armv8/uart.c | 24 +++ 22 files changed, 829 insertions(+), 13 deletions(-)
diff --git a/src/arch/arm64/armv8/bootblock_simple.c b/src/arch/arm64/armv8/bootblock_simple.c index c93a100..681bbf9 100644 --- a/src/arch/arm64/armv8/bootblock_simple.c +++ b/src/arch/arm64/armv8/bootblock_simple.c @@ -51,7 +51,7 @@ void main(void) */
if (boot_cpu()) { - bootblock_cpu_init(); + //bootblock_cpu_init(); bootblock_mainboard_init(); }
diff --git a/src/arch/arm64/c_entry.c b/src/arch/arm64/c_entry.c index 5970405..3f672a3 100644 --- a/src/arch/arm64/c_entry.c +++ b/src/arch/arm64/c_entry.c @@ -63,22 +63,26 @@ static void arm64_init(void) main(); }
-static void secondary_cpu_start(void) -{ -#ifndef __PRE_RAM__ - mmu_enable(); - exception_hwinit(); +//static void secondary_cpu_start(void) +//{ +//#ifndef __PRE_RAM__ +// mmu_enable(); +// exception_hwinit();
/* This will never return. */ - arch_secondary_cpu_init(); -#endif -} +// arch_secondary_cpu_init(); +//#endif +//}
/* * This variable holds entry point for CPUs starting up. The first * element is the BSP path, and the second is the non-BSP path. */ -void (*c_entry[2])(void) = { &arm64_init, &arch_secondary_cpu_init }; +#ifdef __PRE_RAM__ +void (*c_entry[2])(void) = { &arm64_init, NULL}; +#else +void (*c_entry[2])(void) = { &arm64_init, &arch_secondary_cpu_init}; +#endif
void *prepare_secondary_cpu_startup(void) { diff --git a/src/arch/arm64/cpu.c b/src/arch/arm64/cpu.c index 3cf73ae..1026434 100644 --- a/src/arch/arm64/cpu.c +++ b/src/arch/arm64/cpu.c @@ -219,8 +219,9 @@ void arch_cpu_wait_for_action(void) action_queue_complete(q, orig); } } - +#ifdef __PRE_RAM__ int boot_cpu(void) { return cpu_is_bsp(); } +#endif diff --git a/src/arch/arm64/cpu.h b/src/arch/arm64/cpu.h new file mode 100644 index 0000000..ae16fa1 --- /dev/null +++ b/src/arch/arm64/cpu.h @@ -0,0 +1,204 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2014 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +#ifndef __ARCH_CPU_H__ +#define __ARCH_CPU_H__ + +#define asmlinkage + +#if !defined(__PRE_RAM__) +#include <arch/barrier.h> +#include <arch/mpidr.h> +#include <device/device.h> + +enum { + CPU_ID_END = 0x00000000, +}; + +struct cpu_device_id { + uint32_t midr; +}; + +struct cpu_driver { + /* This is excessive as init() is the only one called. */ + struct device_operations *ops; + const struct cpu_device_id *id_table; +}; + +/* Action to run. */ +struct cpu_action { + void (*run)(void *arg); + void *arg; +}; + +/* + * Actions are queued to 'todo'. When picked up 'todo' is cleared. The + * 'completed' field is set to the original 'todo' value when the action + * is complete. + */ +struct cpu_action_queue { + struct cpu_action *todo; + struct cpu_action *completed; +}; + +struct cpu_info { + device_t cpu; + struct cpu_action_queue action_queue; + unsigned int online; + /* Current assumption is that id matches smp_processor_id(). */ + unsigned int id; + uint64_t mpidr; +}; + +/* Obtain cpu_info for current executing CPU. */ +struct cpu_info *cpu_info(void); + +extern struct cpu_info *bsp_cpu_info; +extern struct cpu_info cpu_infos[CONFIG_MAX_CPUS]; + +static inline struct cpu_info *cpu_info_for_cpu(unsigned int id) +{ + return &cpu_infos[id]; +} + +/* Ran only by BSP at initial boot strapping. */ +static inline void cpu_set_bsp(void) +{ + bsp_cpu_info = cpu_info(); +} + +static inline int cpu_is_bsp(void) +{ + return cpu_info() == bsp_cpu_info; +} + +static inline int cpu_online(struct cpu_info *ci) +{ + return load_acquire(&ci->online) != 0; +} + +static inline void cpu_mark_online(struct cpu_info *ci) +{ + ci->mpidr = read_affinity_mpidr(); + store_release(&ci->online, 1); +} + +/* Provide number of CPUs online. */ +size_t cpus_online(void); + +/* Control routines for starting CPUs. */ +struct cpu_control_ops { + /* Return the maximum number of CPUs supported. */ + size_t (*total_cpus)(void); + /* + * Start the requested CPU and have it start running entry(). + * Returns 0 on success, < 0 on error. + */ + int (*start_cpu)(unsigned int id, void (*entry)(void)); +}; + +/* + * Initialize all DEVICE_PATH_CPUS under the DEVICE_PATH_CPU_CLUSTER cluster. + * type DEVICE_PATH_CPUS. Start up is controlled by cntrl_ops. + */ +void arch_initialize_cpus(device_t cluster, struct cpu_control_ops *cntrl_ops); + +/* + * Run cpu_action returning < 0 on error, 0 on success. There are synchronous + * and asynchronous methods. Both cases ensure the action has been picked up + * by the target cpu. The synchronous variants will wait for the action to + * be completed before returning. + * + * Though the current implementation allows queuing actions on the main cpu, + * the main cpu doesn't process its own queue. + */ +int arch_run_on_cpu(unsigned int cpu, struct cpu_action *action); +int arch_run_on_all_cpus(struct cpu_action *action); +int arch_run_on_all_cpus_but_self(struct cpu_action *action); +int arch_run_on_cpu_async(unsigned int cpu, struct cpu_action *action); +int arch_run_on_all_cpus_async(struct cpu_action *action); +int arch_run_on_all_cpus_but_self_async(struct cpu_action *action); + +/* Wait for actions to be perfomed. */ +void arch_cpu_wait_for_action(void); + +#endif /* !__PRE_RAM__ */ + +/* + * Returns logical cpu in range [0:MAX_CPUS). SoC should define this. + * Additionally, this is needed early in arm64 init so it should not + * rely on a stack. Standard clobber list is fair game: x0-x7 and x0 + * returns the logical cpu number. + */ +unsigned int smp_processor_id(void); + +/* + * Stages and rmodules have 2 entry points: BSP and non-BSP. Provided + * a pointer the correct non-BSP entry point will be returned. The + * first instruction is for BSP and the 2nd is for non-BSP. Instructions + * are all 32-bit on arm64. + */ +static inline void *secondary_entry_point(void *e) +{ + uintptr_t nonbsp = (uintptr_t)e; + + return (void *)(nonbsp + sizeof(uint32_t)); +} + +/* + * The arm64_cpu_startup() initializes a CPU's exception stack and regular + * stack as well initializing the C environment for the processor. It + * calls into the array of function pointers at symbol c_entry depending + * on BSP state. Note that arm64_cpu_startup contains secondary entry + * point which can be obtained by secondary_entry_point(). + */ +void arm64_cpu_startup(void); + +/* + * The arm64_cpu_startup_resume() initializes a CPU's exception stack and + * regular stack as well initializing the C environment for the processor. It + * calls into the array of function pointers at symbol c_entry depending + * on BSP state. Note that arm64_cpu_startup contains secondary entry + * point which can be obtained by secondary_entry_point(). + * Additionally, it also restores saved register data and enables MMU, caches + * and exceptions before jumping to C environment for both BSP and non-BSP CPUs. + */ +void arm64_cpu_startup_resume(void); + +/* + * The arm64_arch_timer_init() initializes the per CPU's cntfrq register of + * ARM arch timer. + */ +void arm64_arch_timer_init(void); + +/* + * The cortex_a57_cpu_power_down sequence as per A57/A53/A72 TRM. + * L2 flush by HW(0) or SW(1), if system/HW driven L2 flush is supported. + */ +#define NO_L2_FLUSH 0 +#define L2_FLUSH_HW 0 +#define L2_FLUSH_SW 1 + +#if IS_ENABLED(CONFIG_ARCH_ARM64_CORTEX_A57_POWER_DOWN_SUPPORT) +void cortex_a57_cpu_power_down(int l2_flush); +#else +static inline void cortex_a57_cpu_power_down(int l2_flush) {} +#endif + +#endif /* __ARCH_CPU_H__ */ diff --git a/src/arch/arm64/include/arch/cpu.h b/src/arch/arm64/include/arch/cpu.h new file mode 100644 index 0000000..ae16fa1 --- /dev/null +++ b/src/arch/arm64/include/arch/cpu.h @@ -0,0 +1,204 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2014 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +#ifndef __ARCH_CPU_H__ +#define __ARCH_CPU_H__ + +#define asmlinkage + +#if !defined(__PRE_RAM__) +#include <arch/barrier.h> +#include <arch/mpidr.h> +#include <device/device.h> + +enum { + CPU_ID_END = 0x00000000, +}; + +struct cpu_device_id { + uint32_t midr; +}; + +struct cpu_driver { + /* This is excessive as init() is the only one called. */ + struct device_operations *ops; + const struct cpu_device_id *id_table; +}; + +/* Action to run. */ +struct cpu_action { + void (*run)(void *arg); + void *arg; +}; + +/* + * Actions are queued to 'todo'. When picked up 'todo' is cleared. The + * 'completed' field is set to the original 'todo' value when the action + * is complete. + */ +struct cpu_action_queue { + struct cpu_action *todo; + struct cpu_action *completed; +}; + +struct cpu_info { + device_t cpu; + struct cpu_action_queue action_queue; + unsigned int online; + /* Current assumption is that id matches smp_processor_id(). */ + unsigned int id; + uint64_t mpidr; +}; + +/* Obtain cpu_info for current executing CPU. */ +struct cpu_info *cpu_info(void); + +extern struct cpu_info *bsp_cpu_info; +extern struct cpu_info cpu_infos[CONFIG_MAX_CPUS]; + +static inline struct cpu_info *cpu_info_for_cpu(unsigned int id) +{ + return &cpu_infos[id]; +} + +/* Ran only by BSP at initial boot strapping. */ +static inline void cpu_set_bsp(void) +{ + bsp_cpu_info = cpu_info(); +} + +static inline int cpu_is_bsp(void) +{ + return cpu_info() == bsp_cpu_info; +} + +static inline int cpu_online(struct cpu_info *ci) +{ + return load_acquire(&ci->online) != 0; +} + +static inline void cpu_mark_online(struct cpu_info *ci) +{ + ci->mpidr = read_affinity_mpidr(); + store_release(&ci->online, 1); +} + +/* Provide number of CPUs online. */ +size_t cpus_online(void); + +/* Control routines for starting CPUs. */ +struct cpu_control_ops { + /* Return the maximum number of CPUs supported. */ + size_t (*total_cpus)(void); + /* + * Start the requested CPU and have it start running entry(). + * Returns 0 on success, < 0 on error. + */ + int (*start_cpu)(unsigned int id, void (*entry)(void)); +}; + +/* + * Initialize all DEVICE_PATH_CPUS under the DEVICE_PATH_CPU_CLUSTER cluster. + * type DEVICE_PATH_CPUS. Start up is controlled by cntrl_ops. + */ +void arch_initialize_cpus(device_t cluster, struct cpu_control_ops *cntrl_ops); + +/* + * Run cpu_action returning < 0 on error, 0 on success. There are synchronous + * and asynchronous methods. Both cases ensure the action has been picked up + * by the target cpu. The synchronous variants will wait for the action to + * be completed before returning. + * + * Though the current implementation allows queuing actions on the main cpu, + * the main cpu doesn't process its own queue. + */ +int arch_run_on_cpu(unsigned int cpu, struct cpu_action *action); +int arch_run_on_all_cpus(struct cpu_action *action); +int arch_run_on_all_cpus_but_self(struct cpu_action *action); +int arch_run_on_cpu_async(unsigned int cpu, struct cpu_action *action); +int arch_run_on_all_cpus_async(struct cpu_action *action); +int arch_run_on_all_cpus_but_self_async(struct cpu_action *action); + +/* Wait for actions to be perfomed. */ +void arch_cpu_wait_for_action(void); + +#endif /* !__PRE_RAM__ */ + +/* + * Returns logical cpu in range [0:MAX_CPUS). SoC should define this. + * Additionally, this is needed early in arm64 init so it should not + * rely on a stack. Standard clobber list is fair game: x0-x7 and x0 + * returns the logical cpu number. + */ +unsigned int smp_processor_id(void); + +/* + * Stages and rmodules have 2 entry points: BSP and non-BSP. Provided + * a pointer the correct non-BSP entry point will be returned. The + * first instruction is for BSP and the 2nd is for non-BSP. Instructions + * are all 32-bit on arm64. + */ +static inline void *secondary_entry_point(void *e) +{ + uintptr_t nonbsp = (uintptr_t)e; + + return (void *)(nonbsp + sizeof(uint32_t)); +} + +/* + * The arm64_cpu_startup() initializes a CPU's exception stack and regular + * stack as well initializing the C environment for the processor. It + * calls into the array of function pointers at symbol c_entry depending + * on BSP state. Note that arm64_cpu_startup contains secondary entry + * point which can be obtained by secondary_entry_point(). + */ +void arm64_cpu_startup(void); + +/* + * The arm64_cpu_startup_resume() initializes a CPU's exception stack and + * regular stack as well initializing the C environment for the processor. It + * calls into the array of function pointers at symbol c_entry depending + * on BSP state. Note that arm64_cpu_startup contains secondary entry + * point which can be obtained by secondary_entry_point(). + * Additionally, it also restores saved register data and enables MMU, caches + * and exceptions before jumping to C environment for both BSP and non-BSP CPUs. + */ +void arm64_cpu_startup_resume(void); + +/* + * The arm64_arch_timer_init() initializes the per CPU's cntfrq register of + * ARM arch timer. + */ +void arm64_arch_timer_init(void); + +/* + * The cortex_a57_cpu_power_down sequence as per A57/A53/A72 TRM. + * L2 flush by HW(0) or SW(1), if system/HW driven L2 flush is supported. + */ +#define NO_L2_FLUSH 0 +#define L2_FLUSH_HW 0 +#define L2_FLUSH_SW 1 + +#if IS_ENABLED(CONFIG_ARCH_ARM64_CORTEX_A57_POWER_DOWN_SUPPORT) +void cortex_a57_cpu_power_down(int l2_flush); +#else +static inline void cortex_a57_cpu_power_down(int l2_flush) {} +#endif + +#endif /* __ARCH_CPU_H__ */ diff --git a/src/arch/arm64/include/armv8/arch/secmon.h b/src/arch/arm64/include/armv8/arch/secmon.h index f8351b5..6458893 100644 --- a/src/arch/arm64/include/armv8/arch/secmon.h +++ b/src/arch/arm64/include/armv8/arch/secmon.h @@ -24,8 +24,8 @@
struct secmon_params { size_t online_cpus; - struct cpu_action bsp; - struct cpu_action secondary; + struct cpu_action *bsp; + struct cpu_action *secondary; };
void secmon_run(void (*entry)(void *), void *arg); diff --git a/src/cpu/armltd/armv8/Kconfig b/src/cpu/armltd/armv8/Kconfig new file mode 100644 index 0000000..e73980c --- /dev/null +++ b/src/cpu/armltd/armv8/Kconfig @@ -0,0 +1,11 @@ +config CPU_ARMLTD_ARMV8 + bool + select ARCH_BOOTBLOCK_ARMV8_64 + select ARCH_VERSTAGE_ARMV8_64 + select ARCH_ROMSTAGE_ARMV8_64 + select ARCH_RAMSTAGE_ARMV8_64 + default n + +if CPU_ARMLTD_ARMV8 + +endif diff --git a/src/mainboard/emulation/qemu-armv8/Kconfig b/src/mainboard/emulation/qemu-armv8/Kconfig new file mode 100644 index 0000000..f1ef32b --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/Kconfig @@ -0,0 +1,57 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2015, Naman Govil namangov@gmail.com +## +## This software is licensed under the terms of the GNU General Public +## License version 2, as published by the Free Software Foundation, and +## may be copied, distributed, and modified under those terms. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +# WRITE THE INSTRUCTIONS TO EXECUTE +# To execute, do: +# export QEMU_AUDIO_DRV=none +# qemu-system-arm -M vexpress-a9 -m 1024M -nographic -kernel build/coreboot.rom + +if BOARD_EMULATION_QEMU_ARMV8 + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select ARCH_ARM64_CPU_CORTEX_A57 + select ARCH_ARM64_CORTEX_A57_POWER_DOWN_SUPPORT + select DRIVERS_UART_PL011 + select BOOTBLOCK_CONSOLE + select EARLY_CONSOLE + select CONSOLE_SERIAL + select ARCH_BOOTBLOCK_ARMV8_64 + select ARCH_VERSTAGE_ARMV8_64 + select ARCH_ROMSTAGE_ARMV8_64 + select ARCH_RAMSTAGE_ARMV8_64 + select BOARD_ROMSIZE_KB_4096 + + +config MAINBOARD_DIR + string + default emulation/qemu-armv8 + +config MAINBOARD_PART_NUMBER + string + default "QEMU ARMv8" + +config MAX_CPUS + int + default 2 + +config MAINBOARD_VENDOR + string + default "ARM Ltd." + +config DRAM_SIZE_MB + int + default 1024 + +endif # BOARD_EMULATION_QEMU_ARMV8 diff --git a/src/mainboard/emulation/qemu-armv8/Kconfig.name b/src/mainboard/emulation/qemu-armv8/Kconfig.name new file mode 100644 index 0000000..bb3a0e4 --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/Kconfig.name @@ -0,0 +1,2 @@ +config BOARD_EMULATION_QEMU_ARMV8 + bool "QEMU armv8" diff --git a/src/mainboard/emulation/qemu-armv8/Makefile.inc b/src/mainboard/emulation/qemu-armv8/Makefile.inc new file mode 100644 index 0000000..7fa8880 --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/Makefile.inc @@ -0,0 +1,40 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2013 Google Inc. +## Copyright (C) 2015, Naman Govil namangov@gmail.com +## +## This software is licensed under the terms of the GNU General Public +## License version 2, as published by the Free Software Foundation, and +## may be copied, distributed, and modified under those terms. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +romstage-y += romstage.c + +romstage-y += cbmem.c +ramstage-y += cbmem.c + +bootblock-y += media.c +romstage-y += media.c +ramstage-y += media.c + +bootblock-y += timer.c +romstage-y += timer.c +ramstage-y += timer.c + +bootblock-y += uart.c +romstage-y += uart.c +ramstage-y += uart.c + +bootblock-y += memlayout.ld +romstage-y += memlayout.ld +ramstage-y += memlayout.ld + +bootblock-y += cpu_lib.S +romstage-y += cpu_lib.S +ramstage-y += cpu_lib.S + diff --git a/src/mainboard/emulation/qemu-armv8/board_info.txt b/src/mainboard/emulation/qemu-armv8/board_info.txt new file mode 100644 index 0000000..69c5eb6 --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/board_info.txt @@ -0,0 +1,3 @@ +Board name: QEMU armv8 +Category: emulation +Board URL: http://fabrice.bellard.free.fr/qemu/ diff --git a/src/mainboard/emulation/qemu-armv8/bootblock-common.h b/src/mainboard/emulation/qemu-armv8/bootblock-common.h new file mode 100644 index 0000000..09cff10 --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/bootblock-common.h @@ -0,0 +1,19 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Naman Govil, namangov@gmail.com + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <stdlib.h> +#include <console/console.h> + +void bootblock_cpu_init(void); diff --git a/src/mainboard/emulation/qemu-armv8/bootblock.c b/src/mainboard/emulation/qemu-armv8/bootblock.c new file mode 100644 index 0000000..d198a43 --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/bootblock.c @@ -0,0 +1,22 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Naman Govil, namangov@gmail.com + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <stdlib.h> +#include <console/console.h> +#include "bootblock-common.h" + +void bootblock_cpu_init(void) +{ +} diff --git a/src/mainboard/emulation/qemu-armv8/cbmem.c b/src/mainboard/emulation/qemu-armv8/cbmem.c new file mode 100644 index 0000000..d3a2d6f --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/cbmem.c @@ -0,0 +1,25 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +#include <stddef.h> +#include <cbmem.h> +#include <symbols.h> + +void *cbmem_top(void) +{ + return _dram + (CONFIG_DRAM_SIZE_MB << 20); +} diff --git a/src/mainboard/emulation/qemu-armv8/cpu_lib.S b/src/mainboard/emulation/qemu-armv8/cpu_lib.S new file mode 100644 index 0000000..13eed4b --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/cpu_lib.S @@ -0,0 +1,29 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2014 Google Inc. + * Copyright 2015, Naman Govil namangov@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + + +.text +.global smp_processor_id +smp_processor_id: + /* Core 0 and 1 are encoded in the Aff0 (7:0) field of MPIDR_EL1. */ + /* Multiprocessor Afinity Register (MPIDR) contains CPU ID for a57 */ + mrs x0, mpidr_el1 + uxtb w0, w0 + ret diff --git a/src/mainboard/emulation/qemu-armv8/devicetree.cb b/src/mainboard/emulation/qemu-armv8/devicetree.cb new file mode 100644 index 0000000..fa3c03a --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/devicetree.cb @@ -0,0 +1,20 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2013 Google, Inc. +## +## This software is licensed under the terms of the GNU General Public +## License version 2, as published by the Free Software Foundation, and +## may be copied, distributed, and modified under those terms. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. + +# TODO fill with Versatile Express board data in QEMU. +chip cpu/armltd/armv8 + chip drivers/generic/generic # I2C0 controller + device i2c 6 on end # Fake component for testing + end +end diff --git a/src/mainboard/emulation/qemu-armv8/mainboard.c b/src/mainboard/emulation/qemu-armv8/mainboard.c new file mode 100644 index 0000000..b73ab9d --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/mainboard.c @@ -0,0 +1,27 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google, Inc. + * Copyright (C) 2015 Naman Govil, namangov@gmail.com + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <device/device.h> + +static void mainboard_enable(device_t dev) +{ + printk(BIOS_INFO, "Enable qemu/armv8 device...\n"); +} + +struct chip_operations mainboard_ops = { + .enable_dev = mainboard_enable, +}; diff --git a/src/mainboard/emulation/qemu-armv8/media.c b/src/mainboard/emulation/qemu-armv8/media.c new file mode 100644 index 0000000..4d4edd8 --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/media.c @@ -0,0 +1,25 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <boot_device.h> + +/* Maps directly to qemu memory mapped space of 0x10000 up to rom size. */ +static const struct mem_region_device boot_dev = + MEM_REGION_DEV_INIT((void *)0x10000, CONFIG_ROM_SIZE); + +const struct region_device *boot_device_ro(void) +{ + return &boot_dev.rdev; +} diff --git a/src/mainboard/emulation/qemu-armv8/memlayout.ld b/src/mainboard/emulation/qemu-armv8/memlayout.ld new file mode 100644 index 0000000..ee8132d --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/memlayout.ld @@ -0,0 +1,48 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Google Inc. + * Copyright (C )2015, Naman Govil namangov@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +#include <memlayout.h> + +#include <arch/header.ld> + +/* + * Memory map for qemu armv8: + * + * 0x0000_0000: jump instruction (required by qemu) + * 0x0001_0000: bootblock (entry of kernel / firmware) + * 0x0002_0000: romstage, assume up to 128KB in size. + * 0x0007_ff00: stack pointer + * 0x0010_0000: CBFS header + * 0x0011_0000: CBFS data + * 0x0100_0000: reserved for ramstage + * 0x1000_0000: I/O map address + */ + +SECTIONS +{ + /* TODO: does this thing emulate SRAM? */ + + BOOTBLOCK(0x10000, 64K) + ROMSTAGE(0x20000, 128K) + STACK(0x000FC000, 16K) + + DRAM_START(0x01000000) + RAMSTAGE(0x01000000, 16M) +} diff --git a/src/mainboard/emulation/qemu-armv8/romstage.c b/src/mainboard/emulation/qemu-armv8/romstage.c new file mode 100644 index 0000000..158989f --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/romstage.c @@ -0,0 +1,24 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google, Inc. + * Copyright (C) 2015, Naman Govil namangov@gmail.com + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <program_loading.h> + +void main(void) +{ + console_init(); + run_ramstage(); +} diff --git a/src/mainboard/emulation/qemu-armv8/timer.c b/src/mainboard/emulation/qemu-armv8/timer.c new file mode 100644 index 0000000..b6d048b --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/timer.c @@ -0,0 +1,27 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google, Inc. + * Copyright (C) 2015, Naman Govil namangov@gmail.com + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +void udelay(unsigned int n); +void udelay(unsigned int n) +{ + /* TODO provide delay here. */ +} + +int init_timer(void); +int init_timer(void) +{ + return 0; +} diff --git a/src/mainboard/emulation/qemu-armv8/uart.c b/src/mainboard/emulation/qemu-armv8/uart.c new file mode 100644 index 0000000..d751b15 --- /dev/null +++ b/src/mainboard/emulation/qemu-armv8/uart.c @@ -0,0 +1,24 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Naman Govil, namangov@gmail.com + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <console/uart.h> + +#define UART0_IO_ADDRESS (0x90000000) + +uintptr_t uart_platform_base(int idx) +{ + return UART0_IO_ADDRESS; +}