From 40b31876d27dd6143bdad65acda8ef244e7c3d50 Mon Sep 17 00:00:00 2001 From: Johannes Schlatow Date: Wed, 2 Sep 2015 13:59:31 +0200 Subject: [PATCH] base-hw: Add basic Zynq-7000 support (QEMU) Ref #1599 --- repos/base-hw/lib/mk/platform_zynq/core.mk | 8 + .../lib/mk/platform_zynq/test-hw_info.mk | 12 ++ repos/base-hw/lib/mk/zynq/core.inc | 16 ++ repos/base-hw/mk/spec-hw_zynq.mk | 18 +++ .../base-hw/src/core/include/spec/arm/pl310.h | 100 +++++++++++++ .../src/core/include/spec/panda/board.h | 141 +++++++----------- .../src/core/include/spec/xilinx/serial.h | 44 ++++++ .../src/core/include/spec/zynq/board.h | 53 +++++++ .../src/core/spec/panda/platform_support.cc | 4 +- .../src/core/spec/zynq/platform_support.cc | 75 ++++++++++ .../include/drivers/uart/xilinx_uartps_base.h | 129 ++++++++++++++++ .../platform/zynq_qemu/drivers/board_base.h | 38 +++++ repos/base/include/zynq/drivers/board_base.h | 77 ++++++++++ repos/base/mk/spec-platform_zynq.mk | 9 ++ repos/base/mk/spec-zynq.mk | 6 + tool/builddir/etc/build.conf.hw_zynq | 7 + tool/create_builddir | 4 + tool/run/power_on/qemu | 4 + 18 files changed, 655 insertions(+), 90 deletions(-) create mode 100644 repos/base-hw/lib/mk/platform_zynq/core.mk create mode 100644 repos/base-hw/lib/mk/platform_zynq/test-hw_info.mk create mode 100644 repos/base-hw/lib/mk/zynq/core.inc create mode 100644 repos/base-hw/mk/spec-hw_zynq.mk create mode 100644 repos/base-hw/src/core/include/spec/arm/pl310.h create mode 100644 repos/base-hw/src/core/include/spec/xilinx/serial.h create mode 100644 repos/base-hw/src/core/include/spec/zynq/board.h create mode 100644 repos/base-hw/src/core/spec/zynq/platform_support.cc create mode 100644 repos/base/include/drivers/uart/xilinx_uartps_base.h create mode 100644 repos/base/include/platform/zynq_qemu/drivers/board_base.h create mode 100644 repos/base/include/zynq/drivers/board_base.h create mode 100644 repos/base/mk/spec-platform_zynq.mk create mode 100644 repos/base/mk/spec-zynq.mk create mode 100644 tool/builddir/etc/build.conf.hw_zynq diff --git a/repos/base-hw/lib/mk/platform_zynq/core.mk b/repos/base-hw/lib/mk/platform_zynq/core.mk new file mode 100644 index 0000000000..9ae399752a --- /dev/null +++ b/repos/base-hw/lib/mk/platform_zynq/core.mk @@ -0,0 +1,8 @@ +# +# \brief Build config for Genodes core process +# \author Johannes Schlatow +# \date 2014-12-15 +# + +# include less specific configuration +include $(REP_DIR)/lib/mk/zynq/core.inc diff --git a/repos/base-hw/lib/mk/platform_zynq/test-hw_info.mk b/repos/base-hw/lib/mk/platform_zynq/test-hw_info.mk new file mode 100644 index 0000000000..384f523f04 --- /dev/null +++ b/repos/base-hw/lib/mk/platform_zynq/test-hw_info.mk @@ -0,0 +1,12 @@ +# +# \brief Build config for a core that prints hardware information +# \author Johannes Schlatow +# \author Martin Stein +# \date 2011-12-16 +# + +# add C++ sources +SRC_CC += spec/arm_v7/info.cc + +# decrlare source directories +vpath % $(REP_DIR)/src/test/hw_info diff --git a/repos/base-hw/lib/mk/zynq/core.inc b/repos/base-hw/lib/mk/zynq/core.inc new file mode 100644 index 0000000000..dea9258edf --- /dev/null +++ b/repos/base-hw/lib/mk/zynq/core.inc @@ -0,0 +1,16 @@ +# +# \brief Build config for Genodes core process +# \author Johannes Schlatow +# \date 2014-12-15 +# + +# add include paths +INC_DIR += $(REP_DIR)/src/core/include/spec/zynq +INC_DIR += $(REP_DIR)/src/core/include/spec/xilinx + +# add C++ sources +SRC_CC += platform_services.cc +SRC_CC += spec/zynq/platform_support.cc + +# include less specific configuration +include $(REP_DIR)/lib/mk/cortex_a9/core.inc diff --git a/repos/base-hw/mk/spec-hw_zynq.mk b/repos/base-hw/mk/spec-hw_zynq.mk new file mode 100644 index 0000000000..388a5a7628 --- /dev/null +++ b/repos/base-hw/mk/spec-hw_zynq.mk @@ -0,0 +1,18 @@ +# +# \brief Offer build configurations that are specific to base-hw and Zynq +# \author Johannes Schlatow +# \date 2014-12-15 +# + +# denote which specs are also fulfilled by this spec +SPECS += hw platform_zynq + +# configure multiprocessor mode +NR_OF_CPUS = 1 + +# set address where to link the text segment at +LD_TEXT_ADDR ?= 0x00100000 + +# include implied specs +include $(call select_from_repositories,mk/spec-hw.mk) +include $(call select_from_repositories,mk/spec-platform_zynq.mk) diff --git a/repos/base-hw/src/core/include/spec/arm/pl310.h b/repos/base-hw/src/core/include/spec/arm/pl310.h new file mode 100644 index 0000000000..be62e40cf3 --- /dev/null +++ b/repos/base-hw/src/core/include/spec/arm/pl310.h @@ -0,0 +1,100 @@ +/* + * \brief L2 outer cache controller ARM PL310 + * \author Johannes Schlatow + * \author Stefan Kalkowski + * \author Martin Stein + * \date 2014-06-02 + */ + +/* + * Copyright (C) 2014-2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _SPEC__ARM__PL310_H_ +#define _SPEC__ARM__PL310_H_ + +/* Genode includes */ +#include + +namespace Arm +{ + using Genode::addr_t; + + class Pl310; +} + +/** + * L2 outer cache controller + */ +class Arm::Pl310 : Genode::Mmio +{ + protected: + + struct Control : Register <0x100, 32> + { + struct Enable : Bitfield<0,1> { }; + }; + + struct Aux : Register<0x104, 32> + { + struct Associativity : Bitfield<16,1> { }; + struct Way_size : Bitfield<17,3> { }; + struct Share_override : Bitfield<22,1> { }; + struct Reserved : Bitfield<25,1> { }; + struct Ns_lockdown : Bitfield<26,1> { }; + struct Ns_irq_ctrl : Bitfield<27,1> { }; + struct Data_prefetch : Bitfield<28,1> { }; + struct Inst_prefetch : Bitfield<29,1> { }; + struct Early_bresp : Bitfield<30,1> { }; + + static access_t init_value() + { + access_t v = 0; + Associativity::set(v, 1); + Way_size::set(v, 3); + Share_override::set(v, 1); + Reserved::set(v, 1); + Ns_lockdown::set(v, 1); + Ns_irq_ctrl::set(v, 1); + Data_prefetch::set(v, 1); + Inst_prefetch::set(v, 1); + Early_bresp::set(v, 1); + return v; + } + }; + + struct Irq_mask : Register <0x214, 32> { }; + struct Irq_clear : Register <0x220, 32> { }; + struct Cache_sync : Register <0x730, 32> { }; + struct Invalidate_by_way : Register <0x77c, 32> { }; + struct Clean_invalidate_by_way : Register <0x7fc, 32> { }; + + inline void _sync() { while (read()) ; } + + void _init() + { + write(0); + write(~0); + } + + public: + + Pl310(addr_t const base) : Mmio(base) { } + + void flush() + { + write((1 << 16) - 1); + _sync(); + } + + void invalidate() + { + write((1 << 16) - 1); + _sync(); + } +}; + +#endif /* _SPEC__ARM__PL310_H_ */ diff --git a/repos/base-hw/src/core/include/spec/panda/board.h b/repos/base-hw/src/core/include/spec/panda/board.h index 185dcae4cc..711cdee905 100644 --- a/repos/base-hw/src/core/include/spec/panda/board.h +++ b/repos/base-hw/src/core/include/spec/panda/board.h @@ -1,11 +1,12 @@ /* * \brief Board driver for core on pandaboard * \author Stefan Kalkowski + * \author Martin Stein * \date 2014-06-02 */ /* - * Copyright (C) 2014 Genode Labs GmbH + * Copyright (C) 2014-2015 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -15,105 +16,69 @@ #define _BOARD_H_ /* core includes */ -#include #include +#include namespace Genode { - struct Board : Cortex_a9::Board - { - /** - * L2 outer cache controller - */ - struct Pl310 : Mmio { + class Pl310; + class Board; +} - enum Trustzone_hypervisor_syscalls { - L2_CACHE_SET_DEBUG_REG = 0x100, - L2_CACHE_ENABLE_REG = 0x102, - L2_CACHE_AUX_REG = 0x109, - }; +/** + * L2 outer cache controller + */ +class Genode::Pl310 : public Arm::Pl310 +{ + private: - static inline void - trustzone_hypervisor_call(addr_t func, addr_t val) - { - register addr_t _func asm("r12") = func; - register addr_t _val asm("r0") = val; - asm volatile("dsb; smc #0" :: "r" (_func), "r" (_val) - : "memory", "cc", "r1", "r2", "r3", "r4", "r5", - "r6", "r7", "r8", "r9", "r10", "r11"); - } - - struct Control : Register <0x100, 32> - { - struct Enable : Bitfield<0,1> {}; - }; - - struct Aux : Register<0x104, 32> - { - struct Associativity : Bitfield<16,1> { }; - struct Way_size : Bitfield<17,3> { }; - struct Share_override : Bitfield<22,1> { }; - struct Reserved : Bitfield<25,1> { }; - struct Ns_lockdown : Bitfield<26,1> { }; - struct Ns_irq_ctrl : Bitfield<27,1> { }; - struct Data_prefetch : Bitfield<28,1> { }; - struct Inst_prefetch : Bitfield<29,1> { }; - struct Early_bresp : Bitfield<30,1> { }; - - static access_t init_value() - { - access_t v = 0; - Associativity::set(v, 1); - Way_size::set(v, 3); - Share_override::set(v, 1); - Reserved::set(v, 1); - Ns_lockdown::set(v, 1); - Ns_irq_ctrl::set(v, 1); - Data_prefetch::set(v, 1); - Inst_prefetch::set(v, 1); - Early_bresp::set(v, 1); - return v; - } - }; - - struct Irq_mask : Register <0x214, 32> {}; - struct Irq_clear : Register <0x220, 32> {}; - struct Cache_sync : Register <0x730, 32> {}; - struct Invalidate_by_way : Register <0x77c, 32> {}; - struct Clean_invalidate_by_way : Register <0x7fc, 32> {}; - - inline void sync() { while (read()) ; } - - void invalidate() - { - write((1 << 16) - 1); - sync(); - } - - void flush() - { - trustzone_hypervisor_call(L2_CACHE_SET_DEBUG_REG, 0x3); - write((1 << 16) - 1); - sync(); - trustzone_hypervisor_call(L2_CACHE_SET_DEBUG_REG, 0x0); - } - - Pl310(addr_t const base) : Mmio(base) - { - trustzone_hypervisor_call(L2_CACHE_AUX_REG, - Pl310::Aux::init_value()); - trustzone_hypervisor_call(L2_CACHE_ENABLE_REG, 1); - write(0); - write(0xffffffff); - } + enum Secure_monitor_syscalls + { + L2_CACHE_SET_DEBUG_REG = 0x100, + L2_CACHE_ENABLE_REG = 0x102, + L2_CACHE_AUX_REG = 0x109, }; + static inline void _secure_monitor_call(addr_t func, addr_t val) + { + register addr_t _func asm("r12") = func; + register addr_t _val asm("r0") = val; + asm volatile( + "dsb; smc #0" :: + "r" (_func), "r" (_val) : + "memory", "cc", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11"); + } + + public: + + void flush() + { + _secure_monitor_call(L2_CACHE_SET_DEBUG_REG, 0x3); + Arm::Pl310::flush(); + _secure_monitor_call(L2_CACHE_SET_DEBUG_REG, 0x0); + } + + Pl310(addr_t const base) : Arm::Pl310(base) + { + _secure_monitor_call(L2_CACHE_AUX_REG, Aux::init_value()); + _secure_monitor_call(L2_CACHE_ENABLE_REG, 1); + _init(); + } +}; + +/** + * Board driver for core + */ +class Genode::Board : public Cortex_a9::Board +{ + public: + static void outer_cache_invalidate(); static void outer_cache_flush(); static void prepare_kernel(); static void secondary_cpus_ip(void * const ip) { } static bool is_smp() { return true; } - }; -} +}; #endif /* _BOARD_H_ */ diff --git a/repos/base-hw/src/core/include/spec/xilinx/serial.h b/repos/base-hw/src/core/include/spec/xilinx/serial.h new file mode 100644 index 0000000000..1b5deb40c4 --- /dev/null +++ b/repos/base-hw/src/core/include/spec/xilinx/serial.h @@ -0,0 +1,44 @@ +/* + * \brief Serial output driver for core + * \author Johannes Schlatow + * \date 2014-12-15 + */ + +/* + * Copyright (C) 2014-2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _SERIAL_H_ +#define _SERIAL_H_ + +/* core includes */ +#include + +/* Genode includes */ +#include + +namespace Genode { class Serial; } + +/** + * Serial output driver for core + */ +class Genode::Serial : public Xilinx_uartps_base +{ + public: + + /** + * Constructor + * + * \param baud_rate targeted transfer baud-rate + */ + Serial(unsigned const baud_rate) + : + Xilinx_uartps_base(Board::UART_0_MMIO_BASE, + Board::UART_CLOCK, baud_rate) + { } +}; + +#endif /* _SERIAL_H_ */ diff --git a/repos/base-hw/src/core/include/spec/zynq/board.h b/repos/base-hw/src/core/include/spec/zynq/board.h new file mode 100644 index 0000000000..85c0692acb --- /dev/null +++ b/repos/base-hw/src/core/include/spec/zynq/board.h @@ -0,0 +1,53 @@ +/* + * \brief Board driver for core on Zynq + * \author Johannes Schlatow + * \author Stefan Kalkowski + * \author Martin Stein + * \date 2014-06-02 + */ + +/* + * Copyright (C) 2014-2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/* core includes */ +#include +#include + +namespace Genode +{ + class Pl310; + class Board; +} + +/** + * L2 outer cache controller + */ +class Genode::Pl310 : public Arm::Pl310 +{ + public: + + Pl310(addr_t const base) : Arm::Pl310(base) { _init(); } +}; + +/** + * Board driver for core + */ +class Genode::Board : public Cortex_a9::Board +{ + public: + + static void outer_cache_invalidate(); + static void outer_cache_flush(); + static void prepare_kernel(); + static void secondary_cpus_ip(void * const ip) { } + static bool is_smp() { return true; } +}; + +#endif /* _BOARD_H_ */ diff --git a/repos/base-hw/src/core/spec/panda/platform_support.cc b/repos/base-hw/src/core/spec/panda/platform_support.cc index b8822244bd..ac7b590ac8 100644 --- a/repos/base-hw/src/core/spec/panda/platform_support.cc +++ b/repos/base-hw/src/core/spec/panda/platform_support.cc @@ -62,8 +62,8 @@ Native_region * Platform::_core_only_mmio_regions(unsigned const i) } -static Board::Pl310 * l2_cache() { - return unmanaged_singleton(Board::PL310_MMIO_BASE); } +static Genode::Pl310 * l2_cache() { + return unmanaged_singleton(Board::PL310_MMIO_BASE); } void Board::outer_cache_invalidate() { l2_cache()->invalidate(); } diff --git a/repos/base-hw/src/core/spec/zynq/platform_support.cc b/repos/base-hw/src/core/spec/zynq/platform_support.cc new file mode 100644 index 0000000000..c35efa276e --- /dev/null +++ b/repos/base-hw/src/core/spec/zynq/platform_support.cc @@ -0,0 +1,75 @@ +/* + * \brief Platform implementations specific for base-hw and Zynq + * \author Johannes Schlatow + * \date 2014-12-15 + */ + +/* + * Copyright (C) 2012-2014 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* core includes */ +#include +#include +#include +#include +#include + +using namespace Genode; + +Native_region * Platform::_ram_regions(unsigned const i) +{ + static Native_region _regions[] = + { + { Board::RAM_0_BASE, Board::RAM_0_SIZE } + }; + return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; +} + + +Native_region * mmio_regions(unsigned const i) +{ + static Native_region _regions[] = + { + { Board::MMIO_0_BASE, Board::MMIO_0_SIZE }, + { Board::MMIO_1_BASE, Board::MMIO_1_SIZE }, + { Board::QSPI_MMIO_BASE, Board::QSPI_MMIO_SIZE }, + { Board::OCM_MMIO_BASE, Board::OCM_MMIO_SIZE }, + { Board::AXI_0_MMIO_BASE, Board::AXI_0_MMIO_SIZE }, + { Board::AXI_1_MMIO_BASE, Board::AXI_1_MMIO_SIZE } + }; + return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; +} + + +Native_region * Platform::_core_only_mmio_regions(unsigned const i) +{ + static Native_region _regions[] = + { + /* core timer and PIC */ + { Board::CORTEX_A9_PRIVATE_MEM_BASE, + Board::CORTEX_A9_PRIVATE_MEM_SIZE }, + + /* core UART */ + { Board::UART_0_MMIO_BASE, Board::UART_SIZE }, + + /* L2 cache controller */ + { Board::PL310_MMIO_BASE, Board::PL310_MMIO_SIZE } + }; + return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; +} + + +Cpu::User_context::User_context() { cpsr = Psr::init_user(); } + + +static Genode::Pl310 * l2_cache() { + return unmanaged_singleton(Board::PL310_MMIO_BASE); } + + +void Genode::Board::outer_cache_invalidate() { l2_cache()->invalidate(); } +void Genode::Board::outer_cache_flush() { l2_cache()->flush(); } +void Genode::Board::prepare_kernel() { l2_cache()->invalidate(); } diff --git a/repos/base/include/drivers/uart/xilinx_uartps_base.h b/repos/base/include/drivers/uart/xilinx_uartps_base.h new file mode 100644 index 0000000000..8552b4dc82 --- /dev/null +++ b/repos/base/include/drivers/uart/xilinx_uartps_base.h @@ -0,0 +1,129 @@ +/* + * \brief Base UART driver for the Xilinx UART PS used on Zynq devices + * \author Johannes Schlatow + * \date 2014-12-15 + */ + +/* + * Copyright (C) 2014-2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__DRIVERS__UART__XILINX_UARTPS_BASE_H_ +#define _INCLUDE__DRIVERS__UART__XILINX_UARTPS_BASE_H_ + +/* Genode includes */ +#include + +namespace Genode { class Xilinx_uartps_base; } + +/** + * Base driver Xilinx UART PS module + */ +class Genode::Xilinx_uartps_base : public Mmio +{ + protected: + + /** + * Control register + */ + struct Uart_cr : Register<0x00, 32> + { + struct Rx_reset : Bitfield<0, 1> { }; + struct Tx_reset : Bitfield<1, 1> { }; + struct Rx_enable : Bitfield<2, 1> { }; + struct Tx_enable : Bitfield<4, 1> { }; + }; + + /** + * Mode register + */ + struct Uart_mr : Register<0x04, 32> + { + struct Clock_sel : Bitfield<0, 1> { }; + struct Parity : Bitfield<3, 3> { enum { NO_PARITY = 4 }; }; + }; + + /** + * Baudgen register + */ + struct Uart_baudgen : Register<0x18, 32> + { + struct Clock_div : Bitfield<0, 16> { }; + }; + + /** + * Status register + */ + struct Uart_sr : Register<0x2C, 32> + { + struct Tx_full : Bitfield<4, 1> { }; + }; + + /** + * FIFO register + */ + struct Uart_fifo : Register<0x30, 32> + { + struct Data : Bitfield<0, 8> { }; + }; + + /** + * Bauddiv register + */ + struct Uart_bauddiv : Register<0x34, 32> + { + struct Bdiv : Bitfield<0,8> { }; + }; + + public: + + /** + * Constructor + * + * \param base MMIO base address + * \param clock reference clock + * \param baud_rate targeted baud rate + */ + Xilinx_uartps_base(addr_t const base, unsigned long const clock, + unsigned long const baud_rate) : Mmio(base) + { + /* reset UART */ + Uart_cr::access_t uart_cr = 0; + Uart_cr::Tx_reset::set(uart_cr, 1); + Uart_cr::Rx_reset::set(uart_cr, 1); + write(uart_cr); + + /* set baud rate */ + constexpr unsigned div = 4; + write(div); + write(clock / baud_rate / (div + 1)); + + /* set 8N1 */ + Uart_mr::access_t uart_mr = 0; + Uart_mr::Parity::set(uart_mr, Uart_mr::Parity::NO_PARITY); + write(uart_mr); + + /* enable */ + uart_cr = 0; + Uart_cr::Rx_enable::set(uart_cr, 1); + Uart_cr::Tx_enable::set(uart_cr, 1); + write(uart_cr); + } + + /** + * Transmit ASCII char 'c' + */ + void put_char(char const c) + { + /* wait as long as the transmission buffer is full */ + while (read()) ; + + /* transmit character */ + write(c); + } +}; + +#endif /* _INCLUDE__DRIVERS__UART__XILINX_UARTPS_BASE_H_ */ diff --git a/repos/base/include/platform/zynq_qemu/drivers/board_base.h b/repos/base/include/platform/zynq_qemu/drivers/board_base.h new file mode 100644 index 0000000000..36fc48ef4f --- /dev/null +++ b/repos/base/include/platform/zynq_qemu/drivers/board_base.h @@ -0,0 +1,38 @@ +/* + * \brief Base driver for the Zynq (QEMU) + * \author Johannes Schlatow + * \date 2015-06-30 + */ + +/* + * Copyright (C) 2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__PLATFORM__DRIVERS__BOARD_BASE_H_ +#define _INCLUDE__PLATFORM__DRIVERS__BOARD_BASE_H_ + +#include + +namespace Genode { struct Board_base; } + +/** + * Base driver for the Zynq platform + */ +struct Genode::Board_base : Zynq::Board_base +{ + enum + { + /* clocks (assuming 6:2:1 mode) */ + CPU_1X_CLOCK = 111111115, + CPU_6X4X_CLOCK = 6 * CPU_1X_CLOCK, + + /* CPU */ + CORTEX_A9_CLOCK = CPU_6X4X_CLOCK, + CORTEX_A9_PRIVATE_TIMER_CLK = CORTEX_A9_CLOCK, + }; +}; + +#endif /* _INCLUDE__PLATFORM__DRIVERS__BOARD_BASE_H_ */ diff --git a/repos/base/include/zynq/drivers/board_base.h b/repos/base/include/zynq/drivers/board_base.h new file mode 100644 index 0000000000..b40b5e52f0 --- /dev/null +++ b/repos/base/include/zynq/drivers/board_base.h @@ -0,0 +1,77 @@ +/* + * \brief Base driver for Xilinx Zynq platforms + * \author Mark Albers + * \author Timo Wischer + * \author Johannes Schlatow + * \date 2014-12-15 + */ + +/* + * Copyright (C) 2014-2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__DRIVERS__BOARD_BASE_H_ +#define _INCLUDE__DRIVERS__BOARD_BASE_H_ + +namespace Zynq { struct Board_base; } + +/** + * Base driver for the Zynq platform + */ +struct Zynq::Board_base +{ + enum + { + /* device IO memory */ + MMIO_0_BASE = 0xe0000000, /* IOP devices */ + MMIO_0_SIZE = 0x10000000, + MMIO_1_BASE = 0xF8000000, /* Programmable register via APB */ + MMIO_1_SIZE = 0x02000000, + QSPI_MMIO_BASE = 0xFC000000, /* Quad-SPI */ + QSPI_MMIO_SIZE = 0x01000000, + OCM_MMIO_BASE = 0xFFFC0000, /* OCM upper address range */ + OCM_MMIO_SIZE = 0x00040000, + + /* normal RAM */ + RAM_0_BASE = 0x00000000, + RAM_0_SIZE = 0x40000000, /* 1GiB */ + + /* AXI */ + AXI_0_MMIO_BASE = 0x40000000, /* PL AXI Slave port #0 */ + AXI_0_MMIO_SIZE = 0x40000000, + AXI_1_MMIO_BASE = 0x80000000, /* PL AXI Slave port #1 */ + AXI_1_MMIO_SIZE = 0x40000000, + + /* UART controllers */ + UART_0_MMIO_BASE = MMIO_0_BASE, + UART_SIZE = 0x1000, + UART_CLOCK = 50*1000*1000, + + /* CPU */ + CORTEX_A9_PRIVATE_MEM_BASE = 0xf8f00000, + CORTEX_A9_PRIVATE_MEM_SIZE = 0x00002000, + + /* CPU cache */ + PL310_MMIO_BASE = MMIO_1_BASE + 0xF02000, + PL310_MMIO_SIZE = 0x1000, + CACHE_LINE_SIZE_LOG2 = 2, /* FIXME get correct value from board spec */ + + /* TTC (triple timer counter) */ + TTC0_MMIO_BASE = MMIO_1_BASE + 0x1000, + TTC0_MMIO_SIZE = 0xfff, + TTC0_IRQ_0 = 42, + + /* Ethernet MAC PS */ + EMAC_0_MMIO_BASE = 0xE000B000, + EMAC_0_MMIO_SIZE = 0x1000, + EMAC_0_IRQ = 54, + + /* wether board provides security extension */ + SECURITY_EXTENSION = 0, + }; +}; + +#endif /* _INCLUDE__DRIVERS__BOARD_BASE_H_ */ diff --git a/repos/base/mk/spec-platform_zynq.mk b/repos/base/mk/spec-platform_zynq.mk new file mode 100644 index 0000000000..70ce85b92f --- /dev/null +++ b/repos/base/mk/spec-platform_zynq.mk @@ -0,0 +1,9 @@ +# +# Pull in CPU specifics +# +SPECS += zynq cadence_gem + + +REP_INC_DIR += include/platform/zynq_qemu + +include $(call select_from_repositories,mk/spec-zynq.mk) diff --git a/repos/base/mk/spec-zynq.mk b/repos/base/mk/spec-zynq.mk new file mode 100644 index 0000000000..d2aa72fdfe --- /dev/null +++ b/repos/base/mk/spec-zynq.mk @@ -0,0 +1,6 @@ +# +# Pull in CPU specifics +# +SPECS += cortex_a9 arm_v7a + +include $(call select_from_repositories,mk/spec-cortex_a9.mk) diff --git a/tool/builddir/etc/build.conf.hw_zynq b/tool/builddir/etc/build.conf.hw_zynq new file mode 100644 index 0000000000..c2f7ae9584 --- /dev/null +++ b/tool/builddir/etc/build.conf.hw_zynq @@ -0,0 +1,7 @@ +REPOSITORIES += $(GENODE_DIR)/repos/base-hw + +## +## Kernel-specific run tool configuration +## + +RUN_OPT = --include boot_dir/hw --include power_on/qemu --include log/qemu diff --git a/tool/create_builddir b/tool/create_builddir index d716f19c68..edad13a53f 100755 --- a/tool/create_builddir +++ b/tool/create_builddir @@ -36,6 +36,7 @@ usage: @echo " 'hw_arndale'" @echo " 'hw_odroid_xu'" @echo " 'hw_rpi'" + @echo " 'hw_zynq'" @echo " 'hw_x86_64'" @echo " 'hw_x86_64_muen'" @echo " 'foc_x86_32'" @@ -252,6 +253,9 @@ hw_rpi:: @echo "SPECS = genode hw_rpi" > $(BUILD_DIR)/etc/specs.conf @echo "SPECS += perf_counter" >> $(BUILD_DIR)/etc/specs.conf +hw_zynq:: + @echo "SPECS = genode hw_zynq" > $(BUILD_DIR)/etc/specs.conf + hw_odroid_xu:: @echo "SPECS = genode hw_odroid_xu" > $(BUILD_DIR)/etc/specs.conf @echo "SPECS += perf_counter" >> $(BUILD_DIR)/etc/specs.conf diff --git a/tool/run/power_on/qemu b/tool/run/power_on/qemu index 9c63b6100d..d3eb4be9b1 100644 --- a/tool/run/power_on/qemu +++ b/tool/run/power_on/qemu @@ -50,11 +50,15 @@ proc run_power_on { } { append qemu_args " -M realview-pbx-a9" } if {[have_spec platform_vpb926]} { append qemu_args " -M versatilepb -m 128 " } + if {[have_spec platform_zynq]} { append qemu_args " -M xilinx-zynq-a9 -cpu cortex-a9 -m 256 " } if {[have_spec hw_x86_64]} { regsub -all {\-m ([0-9])+} $qemu_args "" qemu_args append qemu_args " -m 512 " } + # add devices for specific platforms + if {[have_spec platform_zynq] && [have_spec cadence_gem]} { append qemu_args " -net nic,model=cadence_gem" } + # on x86, we support booting via pxe or iso/disk image if {[have_spec x86]} { if {[have_include "load/tftp"]} {