diff --git a/base-hw/include/arndale_uart/drivers/serial_log.h b/base-hw/include/arndale_uart/drivers/serial_log.h new file mode 100644 index 000000000..c9f7d711b --- /dev/null +++ b/base-hw/include/arndale_uart/drivers/serial_log.h @@ -0,0 +1,43 @@ +/* + * \brief Serial output driver for console lib + * \author Martin Stein + * \date 2013-01-09 + */ + +/* + * Copyright (C) 2013 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__ARNDALE_UART__DRIVERS__SERIAL_LOG_H_ +#define _INCLUDE__ARNDALE_UART__DRIVERS__SERIAL_LOG_H_ + +/* Genode includes */ +#include +#include + +namespace Genode +{ + /** + * Serial output driver for console lib + */ + class Serial_log : public Arndale_uart_base + { + public: + + /** + * Constructor + * + * \param baud_rate targeted transfer baud-rate + */ + Serial_log(unsigned const baud_rate) : + Arndale_uart_base(Board::UART_2_MMIO_BASE, + Board::UART_2_CLOCK, baud_rate) + { } + }; +} + +#endif /* _INCLUDE__ARNDALE_UART__DRIVERS__SERIAL_LOG_H_ */ + diff --git a/base-hw/mk/spec-hw_arndale.mk b/base-hw/mk/spec-hw_arndale.mk new file mode 100644 index 000000000..18bd21f25 --- /dev/null +++ b/base-hw/mk/spec-hw_arndale.mk @@ -0,0 +1,15 @@ +# +# \brief Offer build configurations that are specific to base-hw and Pandaboard A2 +# \author Martin Stein +# \date 2013-01-09 +# + +# denote wich specs are also fullfilled by this spec +SPECS += hw platform_arndale + +# set address where to link the text segment at +LD_TEXT_ADDR ?= 0x80000000 + +# include implied specs +include $(call select_from_repositories,mk/spec-hw.mk) +include $(call select_from_repositories,mk/spec-platform_arndale.mk) diff --git a/base-hw/src/core/arndale/cpu.h b/base-hw/src/core/arndale/cpu.h new file mode 100644 index 000000000..e3007b883 --- /dev/null +++ b/base-hw/src/core/arndale/cpu.h @@ -0,0 +1,29 @@ +/* + * \brief CPU driver for core + * \author Martin Stein + * \date 2012-04-23 + */ + +/* + * Copyright (C) 2012 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 _ARNDALE__CPU_H_ +#define _ARNDALE__CPU_H_ + +/* core includes */ +#include + +namespace Genode +{ + /** + * CPU driver for core + */ + class Cpu : public Cortex_a15::Cpu { }; +} + +#endif /* _ARNDALE__CPU_H_ */ + diff --git a/base-hw/src/core/arndale/pic.h b/base-hw/src/core/arndale/pic.h new file mode 100644 index 000000000..e3037f5de --- /dev/null +++ b/base-hw/src/core/arndale/pic.h @@ -0,0 +1,42 @@ +/* + * \brief Interrupt controller for kernel + * \author Martin Stein + * \date 2012-04-23 + */ + +/* + * Copyright (C) 2012 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 _ARNDALE__PIC_H_ +#define _ARNDALE__PIC_H_ + +/* core includes */ +#include +#include + +namespace Kernel +{ + /** + * Interrupt controller for kernel + */ + class Pic : public Corelink_gic400::Pic + { + public: + + /** + * Constructor + */ + Pic() : Corelink_gic400::Pic(Genode::Board::GIC_CPU_MMIO_BASE) { } + }; +} + + +bool Arm_gic::Pic::_use_security_ext() { return 0; } + + +#endif /* _ARNDALE__PIC_H_ */ + diff --git a/base-hw/src/core/arndale/platform_support.cc b/base-hw/src/core/arndale/platform_support.cc new file mode 100644 index 000000000..5ea6066e8 --- /dev/null +++ b/base-hw/src/core/arndale/platform_support.cc @@ -0,0 +1,71 @@ +/* + * \brief Parts of platform that are specific to Arndale + * \author Martin Stein + * \date 2012-04-27 + */ + +/* + * Copyright (C) 2012 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 + + +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 * Platform::_irq_regions(unsigned const i) +{ + static Native_region _regions[] = + { + { 0, Kernel::Pic::MAX_INTERRUPT_ID + 1 } + }; + return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; +} + + +Native_region * Platform::_core_only_irq_regions(unsigned const i) +{ + static Native_region _regions[] = + { + { Kernel::Timer::IRQ, 1 }, + }; + return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; +} + + +Native_region * Platform::_mmio_regions(unsigned const i) +{ + static Native_region _regions[] = + { + { Board::MMIO_0_BASE, Board::MMIO_0_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[] = + { + { Board::GIC_CPU_MMIO_BASE, Board::GIC_CPU_MMIO_SIZE }, + }; + return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; +} diff --git a/base-hw/src/core/arndale/target.mk b/base-hw/src/core/arndale/target.mk new file mode 100644 index 000000000..5966f4c9f --- /dev/null +++ b/base-hw/src/core/arndale/target.mk @@ -0,0 +1,44 @@ +# +# \brief Build config for Genodes core process +# \author Stefan Kalkowski +# \author Martin Stein +# \date 2012-10-04 +# + +# declare wich specs must be given to build this target +REQUIRES += platform_arndale + +# add include paths +INC_DIR += $(REP_DIR)/src/core/arndale + +# add C++ sources +SRC_CC += platform_services.cc \ + platform_support.cc \ + syscall.cc + +# add assembly sources +SRC_S += mode_transition.s \ + boot_modules.s \ + crt0.s + +# declare source paths +vpath platform_services.cc $(BASE_DIR)/src/core +vpath platform_support.cc $(REP_DIR)/src/core/arndale +vpath mode_transition.s $(REP_DIR)/src/core/arm_v7 +vpath syscall.cc $(REP_DIR)/src/base/arm +vpath crt0.s $(REP_DIR)/src/core/arm + +# +# Check if there are other images wich shall be linked to core. +# If not use a dummy boot-modules file wich includes only the symbols. +# +ifeq ($(wildcard $(BUILD_BASE_DIR)/boot_modules.s),) + vpath boot_modules.s $(REP_DIR)/src/core/arm +else + INC_DIR += $(BUILD_BASE_DIR) + vpath boot_modules.s $(BUILD_BASE_DIR) +endif + +# include less specific target parts +include $(REP_DIR)/src/core/target.inc + diff --git a/base-hw/src/core/arndale/timer.h b/base-hw/src/core/arndale/timer.h new file mode 100644 index 000000000..26853ff17 --- /dev/null +++ b/base-hw/src/core/arndale/timer.h @@ -0,0 +1,41 @@ +/* + * \brief Timer for kernel + * \author Martin Stein + * \date 2012-04-23 + */ + +/* + * Copyright (C) 2012 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 _ARNDALE__TIMER_H_ +#define _ARNDALE__TIMER_H_ + +/* core includes */ +#include +#include + +namespace Kernel +{ + /** + * Kernel timer + */ + class Timer : public Exynos_pwm::Timer + { + public: + + enum { IRQ = Genode::Board::PWM_IRQ_0 }; + + /** + * Constructor + */ + Timer() : Exynos_pwm::Timer(Genode::Board::PWM_MMIO_BASE, + Genode::Board::PWM_CLOCK) { } + }; +} + +#endif /* _ARNDALE__TIMER_H_ */ + diff --git a/base-hw/src/core/arndale/tlb.h b/base-hw/src/core/arndale/tlb.h new file mode 100644 index 000000000..97619ef6c --- /dev/null +++ b/base-hw/src/core/arndale/tlb.h @@ -0,0 +1,47 @@ +/* + * \brief Translation lookaside buffer + * \author Martin Stein + * \date 2012-04-23 + */ + +/* + * Copyright (C) 2012 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 _ARNDALE__TLB_H_ +#define _ARNDALE__TLB_H_ + +/* core includes */ +#include +#include + +namespace Genode +{ + struct Page_flags : Arm::Page_flags { }; + + class Tlb : public Arm_v7::Section_table { }; + + /** + * Translation lookaside buffer of core + */ + class Core_tlb : public Tlb + { + public: + + /** + * Constructor - ensures that core never gets a pagefault + */ + Core_tlb() + { + using namespace Genode; + map_core_area(Board::RAM_0_BASE, Board::RAM_0_SIZE, 0); + map_core_area(Board::MMIO_0_BASE, Board::MMIO_0_SIZE, 1); + } + }; +} + +#endif /* _ARNDALE__TLB_H_ */ + diff --git a/base-hw/src/core/cpu/cortex_a15.h b/base-hw/src/core/cpu/cortex_a15.h new file mode 100644 index 000000000..c91d803b4 --- /dev/null +++ b/base-hw/src/core/cpu/cortex_a15.h @@ -0,0 +1,44 @@ +/* + * \brief CPU driver for core + * \author Martin stein + * \date 2011-11-03 + */ + +/* + * Copyright (C) 2011-2012 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 _CPU__CORTEX_A15_H_ +#define _CPU__CORTEX_A15_H_ + +/* Genode includes */ +#include +#include + +/* core includes */ +#include +#include + +namespace Cortex_a15 +{ + using namespace Genode; + + /** + * CPU driver for core + */ + struct Cpu : Arm_v7::Cpu + { + /** + * Ensure that TLB insertions get applied + * + * Nothing to do because MMU uses caches on pagetable walks + */ + static void tlb_insertions() { } + }; +} + +#endif /* _CPU__CORTEX_A15_H_ */ + diff --git a/base-hw/src/core/panda/pic.h b/base-hw/src/core/panda/pic.h index edf622238..0f8065fb8 100644 --- a/base-hw/src/core/panda/pic.h +++ b/base-hw/src/core/panda/pic.h @@ -15,15 +15,19 @@ #define _PANDA__PIC_H_ /* core includes */ -#include +#include namespace Kernel { /** * Interrupt controller for kernel */ - class Pic : public Cortex_a9_no_trustzone::Pic { }; + class Pic : public Cortex_a9::Pic { }; } + +bool Arm_gic::Pic::_use_security_ext() { return 0; } + + #endif /* _PANDA__PIC_H_ */ diff --git a/base-hw/src/core/panda/platform_support.cc b/base-hw/src/core/panda/platform_support.cc index 339516f24..6720adc55 100644 --- a/base-hw/src/core/panda/platform_support.cc +++ b/base-hw/src/core/panda/platform_support.cc @@ -12,10 +12,10 @@ */ /* core includes */ -#include -#include #include #include +#include +#include using namespace Genode; @@ -34,7 +34,7 @@ Native_region * Platform::_irq_regions(unsigned const i) { static Native_region _regions[] = { - { 0, Cortex_a9_no_trustzone::Pic::MAX_INTERRUPT_ID + 1 } + { 0, Kernel::Pic::MAX_INTERRUPT_ID + 1 } }; return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; } @@ -45,7 +45,7 @@ Native_region * Platform::_core_only_irq_regions(unsigned const i) static Native_region _regions[] = { /* core timer */ - { Cortex_a9::Cpu::PRIVATE_TIMER_IRQ, 1 }, + { Genode::Cpu::PRIVATE_TIMER_IRQ, 1 }, /* core UART */ { Board::TL16C750_3_IRQ, 1 } diff --git a/base-hw/src/core/pbxa9/pic.h b/base-hw/src/core/pbxa9/pic.h index cf881d050..fe5b2006b 100644 --- a/base-hw/src/core/pbxa9/pic.h +++ b/base-hw/src/core/pbxa9/pic.h @@ -15,15 +15,19 @@ #define _PBXA9__PIC_H_ /* core includes */ -#include +#include namespace Kernel { /** * Interrupt controller for kernel */ - class Pic : public Cortex_a9_no_trustzone::Pic { }; + class Pic : public Cortex_a9::Pic { }; } + +bool Arm_gic::Pic::_use_security_ext() { return 0; } + + #endif /* _PBXA9__PIC_H_ */ diff --git a/base-hw/src/core/pbxa9/platform_support.cc b/base-hw/src/core/pbxa9/platform_support.cc index 2246f4d4c..55ba53c16 100644 --- a/base-hw/src/core/pbxa9/platform_support.cc +++ b/base-hw/src/core/pbxa9/platform_support.cc @@ -12,10 +12,10 @@ */ /* core includes */ -#include #include -#include -#include +#include +#include +#include using namespace Genode; @@ -36,7 +36,7 @@ Native_region * Platform::_irq_regions(unsigned const i) { static Native_region _regions[] = { - { 0, Cortex_a9_no_trustzone::Pic::MAX_INTERRUPT_ID + 1 } + { 0, Kernel::Pic::MAX_INTERRUPT_ID + 1 } }; return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; } diff --git a/base-hw/src/core/pic/arm_gic.h b/base-hw/src/core/pic/arm_gic.h new file mode 100644 index 000000000..a202db6b8 --- /dev/null +++ b/base-hw/src/core/pic/arm_gic.h @@ -0,0 +1,326 @@ +/* + * \brief Programmable interrupt controller for core + * \author Martin stein + * \date 2011-10-26 + */ + +/* + * Copyright (C) 2011-2013 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 _PIC__ARM_GIC_H_ +#define _PIC__ARM_GIC_H_ + +/* Genode includes */ +#include + +namespace Arm_gic +{ + using namespace Genode; + + /** + * Programmable interrupt controller for core + * + * ARM generic interrupt controller, Architecture version 2.0 + */ + class Pic + { + public: + + enum { MAX_INTERRUPT_ID = 1023 }; + + protected: + + enum { + MIN_SPI = 32, + SPURIOUS_ID = 1023, + }; + + /** + * Distributor interface + */ + struct Distr : public Mmio + { + /** + * Constructor + */ + Distr(addr_t const base) : Mmio(base) { } + + /** + * Control register + */ + struct Ctlr : Register<0x000, 32> + { + struct Enable : Bitfield<0,1> { }; + }; + + /** + * Controller type register + */ + struct Typer : Register<0x004, 32> + { + struct It_lines_number : Bitfield<0,5> { }; + struct Cpu_number : Bitfield<5,3> { }; + }; + + /** + * Interrupt group register + */ + struct Igroupr : + Register_array<0x80, 32, MAX_INTERRUPT_ID + 1, 1> + { + struct Group_status : Bitfield<0, 1> { }; + }; + + /** + * Interrupt set enable registers + */ + struct Isenabler : + Register_array<0x100, 32, MAX_INTERRUPT_ID + 1, 1, true> + { + struct Set_enable : Bitfield<0, 1> { }; + }; + + /** + * Interrupt clear enable registers + */ + struct Icenabler : + Register_array<0x180, 32, MAX_INTERRUPT_ID + 1, 1, true> + { + struct Clear_enable : Bitfield<0, 1> { }; + }; + + /** + * Interrupt priority level registers + */ + struct Ipriorityr : + Register_array<0x400, 32, MAX_INTERRUPT_ID + 1, 8> + { + enum { GET_MIN = 0xff }; + + struct Priority : Bitfield<0, 8> { }; + }; + + /** + * Interrupt processor target registers + */ + struct Itargetsr : + Register_array<0x800, 32, MAX_INTERRUPT_ID + 1, 8> + { + enum { ALL = 0xff }; + + struct Cpu_targets : Bitfield<0, 8> { }; + }; + + /** + * Interrupt configuration registers + */ + struct Icfgr : + Register_array<0xc00, 32, MAX_INTERRUPT_ID + 1, 2> + { + struct Edge_triggered : Bitfield<1, 1> { }; + }; + + /** + * Minimum supported interrupt priority + */ + Ipriorityr::access_t min_priority() + { + write(Ipriorityr::GET_MIN, 0); + return read(0); + } + + /** + * Maximum supported interrupt priority + */ + Ipriorityr::access_t max_priority() { return 0; } + + /** + * ID of the maximum supported interrupt + */ + Typer::access_t max_interrupt() + { + enum { LINE_WIDTH_LOG2 = 5 }; + Typer::access_t lnr = read(); + return ((lnr + 1) << LINE_WIDTH_LOG2) - 1; + } + + } _distr; + + /** + * CPU interface + */ + struct Cpu : public Mmio + { + /** + * Constructor + */ + Cpu(addr_t const base) : Mmio(base) { } + + /** + * Control register + */ + struct Ctlr : Register<0x00, 32> + { + /* Without security extension */ + struct Enable : Bitfield<0,1> { }; + + /* In a secure world */ + struct Enable_grp0 : Bitfield<0,1> { }; + struct Enable_grp1 : Bitfield<1,1> { }; + struct Fiq_en : Bitfield<3,1> { }; + }; + + /** + * Priority mask register + */ + struct Pmr : Register<0x04, 32> + { + struct Priority : Bitfield<0,8> { }; + }; + + /** + * Binary point register + */ + struct Bpr : Register<0x08, 32> + { + enum { NO_PREEMPTION = 7 }; + + struct Binary_point : Bitfield<0,3> { }; + }; + + /** + * Interrupt acknowledge register + */ + struct Iar : Register<0x0c, 32, true> + { + struct Irq_id : Bitfield<0,10> { }; + struct Cpu_id : Bitfield<10,3> { }; + }; + + /** + * End of interrupt register + */ + struct Eoir : Register<0x10, 32, true> + { + struct Irq_id : Bitfield<0,10> { }; + struct Cpu_id : Bitfield<10,3> { }; + }; + } _cpu; + + unsigned const _max_interrupt; + unsigned _last_request; + + /** + * Wether the security extension is used or not + */ + inline static bool _use_security_ext(); + + public: + + /** + * Constructor, all interrupts get masked + */ + Pic(addr_t const distr_base, addr_t const cpu_base) : + _distr(distr_base), _cpu(cpu_base), + _max_interrupt(_distr.max_interrupt()), + _last_request(SPURIOUS_ID) + { + /* with security extension any board has its own init */ + if (_use_security_ext()) return; + + /* disable device */ + _distr.write(0); + + /* supported priority range */ + unsigned const min_prio = _distr.min_priority(); + unsigned const max_prio = _distr.max_priority(); + + /* configure every shared peripheral interrupt */ + for (unsigned i=MIN_SPI; i <= _max_interrupt; i++) + { + _distr.write(0, i); + _distr.write(max_prio, i); + _distr.write( + Distr::Itargetsr::ALL, i); + } + + /* disable the priority filter */ + _cpu.write(min_prio); + + /* disable preemption of interrupt handling by interrupts */ + _cpu.write(Cpu::Bpr::NO_PREEMPTION); + + /* enable device */ + _distr.write(1); + _cpu.write(1); + } + + /** + * Get the ID of the last interrupt request + * + * \return True if the request with ID 'i' is treated as accepted + * by the CPU and awaits an subsequently 'finish_request' + * call. Otherwise this returns false and the value of 'i' + * remains useless. + */ + bool take_request(unsigned & i) + { + _last_request = _cpu.read(); + i = _last_request; + return valid(i); + } + + /** + * Complete the last request that was taken via 'take_request' + */ + void finish_request() + { + if (!valid(_last_request)) return; + _cpu.write(Cpu::Eoir::Irq_id::bits(_last_request) | + Cpu::Eoir::Cpu_id::bits(0) ); + _last_request = SPURIOUS_ID; + } + + /** + * Check if 'i' is a valid interrupt request ID at the device + */ + bool valid(unsigned const i) const { return i <= _max_interrupt; } + + /** + * Unmask all interrupts + */ + void unmask() + { + for (unsigned i=0; i <= _max_interrupt; i++) + _distr.write(1, i); + } + + /** + * Unmask interrupt 'i' + */ + void unmask(unsigned const i) { + _distr.write(1, i); } + + /** + * Mask all interrupts + */ + void mask() + { + for (unsigned i=0; i <= _max_interrupt; i++) + _distr.write(1, i); + } + + /** + * Mask interrupt 'i' + */ + void mask(unsigned const i) { + _distr.write(1, i); } + }; +} + +#endif /* _PIC__ARM_GIC_H_ */ + diff --git a/base-hw/src/core/pic/corelink_gic400.h b/base-hw/src/core/pic/corelink_gic400.h new file mode 100644 index 000000000..3e6b3924c --- /dev/null +++ b/base-hw/src/core/pic/corelink_gic400.h @@ -0,0 +1,47 @@ +/* + * \brief Programmable interrupt controller for core + * \author Martin stein + * \date 2013-01-22 + */ + +/* + * Copyright (C) 2013 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 _PIC__CORELINK_GIC400_H_ +#define _PIC__CORELINK_GIC400_H_ + +/* core includes */ +#include + +namespace Corelink_gic400 +{ + using namespace Genode; + + /** + * Programmable interrupt controller for core + * + * CoreLink GIC-400 Revision r0p0 + */ + class Pic : public Arm_gic::Pic + { + enum { + DISTR_OFFSET = 0x1000, + CPU_OFFSET = 0x2000, + }; + + public: + + /** + * Constructor + */ + Pic(addr_t const base) : Arm_gic::Pic(base + DISTR_OFFSET, + base + CPU_OFFSET) { } + }; +} + +#endif /* _PIC__CORELINK_GIC400_H_ */ + diff --git a/base-hw/src/core/pic/cortex_a9.h b/base-hw/src/core/pic/cortex_a9.h index 2d1845a27..0f932f7ad 100644 --- a/base-hw/src/core/pic/cortex_a9.h +++ b/base-hw/src/core/pic/cortex_a9.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2009-2013 Genode Labs GmbH + * Copyright (C) 2011-2013 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. @@ -14,277 +14,24 @@ #ifndef _PIC__CORTEX_A9_H_ #define _PIC__CORTEX_A9_H_ -/* Genode includes */ -#include +/* core includes */ +#include +#include namespace Cortex_a9 { - using namespace Genode; - /** * Programmable interrupt controller for core */ - class Pic + class Pic : public Arm_gic::Pic { public: - enum { MAX_INTERRUPT_ID = 1023 }; - - protected: - - enum { - MIN_SPI = 32, - SPURIOUS_ID = 1023, - }; - /** - * Distributor interface + * Constructor */ - struct Distr : public Mmio - { - Distr() : Mmio(Cortex_a9::Cpu::PL390_DISTRIBUTOR_MMIO_BASE) { } - - /** - * Distributor control register - */ - struct Icddcr : Register<0x000, 32> - { - struct Enable : Bitfield<0,1> { }; - }; - - /** - * Interrupt controller type register - */ - struct Icdictr : Register<0x004, 32> - { - struct It_lines_number : Bitfield<0,5> { }; - struct Cpu_number : Bitfield<5,3> { }; - }; - - /** - * Interrupt security registers - */ - struct Icdisr : Register_array<0x80, 32, MAX_INTERRUPT_ID+1, 1> - { - struct Nonsecure : Bitfield<0, 1> { }; - }; - - /** - * Interrupt set enable registers - */ - struct Icdiser : Register_array<0x100, 32, MAX_INTERRUPT_ID+1, 1, true> - { - struct Set_enable : Bitfield<0, 1> { }; - }; - - /** - * Interrupt clear enable registers - */ - struct Icdicer : Register_array<0x180, 32, MAX_INTERRUPT_ID+1, 1, true> - { - struct Clear_enable : Bitfield<0, 1> { }; - }; - - /** - * Interrupt priority level registers - */ - struct Icdipr : Register_array<0x400, 32, MAX_INTERRUPT_ID+1, 8> - { - struct Priority : Bitfield<0, 8> - { - enum { GET_MIN_PRIORITY = 0xff }; - }; - }; - - /** - * Interrupt processor target registers - */ - struct Icdiptr : Register_array<0x800, 32, MAX_INTERRUPT_ID+1, 8> - { - struct Cpu_targets : Bitfield<0, 8> - { - enum { ALL = 0xff }; - }; - }; - - /** - * Interrupt configuration registers - */ - struct Icdicr : Register_array<0xc00, 32, MAX_INTERRUPT_ID+1, 2> - { - struct Edge_triggered : Bitfield<1, 1> { }; - }; - - /** - * Minimum supported interrupt priority - */ - Icdipr::access_t min_priority() - { - write(Icdipr::Priority::GET_MIN_PRIORITY, 0); - return read(0); - } - - /** - * Maximum supported interrupt priority - */ - Icdipr::access_t max_priority() { return 0; } - - /** - * ID of the maximum supported interrupt - */ - Icdictr::access_t max_interrupt() - { - enum { LINE_WIDTH_LOG2 = 5 }; - Icdictr::access_t lnr = read(); - return ((lnr + 1) << LINE_WIDTH_LOG2) - 1; - } - - } _distr; - - /** - * CPU interface - */ - struct Cpu : public Mmio - { - Cpu() : Mmio(Cortex_a9::Cpu::PL390_CPU_MMIO_BASE) { } - - /** - * CPU interface control register - */ - struct Iccicr : Register<0x00, 32> - { - /* Without security extension */ - struct Enable : Bitfield<0,1> { }; - - /* With security extension */ - struct Enable_s : Bitfield<0,1> { }; - struct Enable_ns : Bitfield<1,1> { }; - struct Ack_ctl : Bitfield<2,1> { }; - struct Fiq_en : Bitfield<3,1> { }; - struct Sbpr : Bitfield<4,1> { }; - }; - - /** - * Priority mask register - */ - struct Iccpmr : Register<0x04, 32> - { - struct Priority : Bitfield<0,8> { }; - }; - - /** - * Binary point register - */ - struct Iccbpr : Register<0x08, 32> - { - struct Binary_point : Bitfield<0,3> - { - enum { NO_PREEMPTION = 7 }; - }; - }; - - /** - * Interrupt acknowledge register - */ - struct Icciar : Register<0x0c, 32, true> - { - struct Ack_int_id : Bitfield<0,10> { }; - struct Cpu_id : Bitfield<10,3> { }; - }; - - /** - * End of interrupt register - */ - struct Icceoir : Register<0x10, 32, true> - { - struct Eoi_int_id : Bitfield<0,10> { }; - struct Cpu_id : Bitfield<10,3> { }; - }; - - /** - * Non-secure Binary point register - */ - struct Iccabpr : Register<0x1c, 32> - { - struct Binary_point : Bitfield<0,3> - { - enum { NO_PREEMPTION = 7 }; - }; - }; - - } _cpu; - - unsigned const _max_interrupt; - unsigned _last_taken_request; - - public: - - /** - * Constructor, all interrupts get masked - */ - Pic() : _max_interrupt(_distr.max_interrupt()), - _last_taken_request(SPURIOUS_ID) { } - - /** - * Get the ID of the last interrupt request - * - * \return True if the request with ID 'i' is treated as accepted - * by the CPU and awaits an subsequently 'finish_request' - * call. Otherwise this returns false and the value of 'i' - * remains useless. - */ - bool take_request(unsigned & i) - { - _last_taken_request = _cpu.read(); - i = _last_taken_request; - return valid(i); - } - - /** - * Complete the last request that was taken via 'take_request' - */ - void finish_request() - { - if (!valid(_last_taken_request)) return; - _cpu.write(Cpu::Icceoir::Eoi_int_id::bits(_last_taken_request) | - Cpu::Icceoir::Cpu_id::bits(0) ); - _last_taken_request = SPURIOUS_ID; - } - - /** - * Check if 'i' is a valid interrupt request ID at the device - */ - bool valid(unsigned const i) const { return i <= _max_interrupt; } - - /** - * Unmask all interrupts - */ - void unmask() - { - for (unsigned i=0; i <= _max_interrupt; i++) - _distr.write(1, i); - } - - /** - * Unmask interrupt 'i' - */ - void unmask(unsigned const i) { - _distr.write(1, i); } - - /** - * Mask all interrupts - */ - void mask() - { - for (unsigned i=0; i <= _max_interrupt; i++) - _distr.write(1, i); - } - - /** - * Mask interrupt 'i' - */ - void mask(unsigned const i) { - _distr.write(1, i); } + Pic() : Arm_gic::Pic(Genode::Cpu::PL390_DISTRIBUTOR_MMIO_BASE, + Genode::Cpu::PL390_CPU_MMIO_BASE) { } }; } diff --git a/base-hw/src/core/pic/cortex_a9_no_trustzone.h b/base-hw/src/core/pic/cortex_a9_no_trustzone.h deleted file mode 100644 index 76ffdf221..000000000 --- a/base-hw/src/core/pic/cortex_a9_no_trustzone.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * \brief Programmable interrupt controller for core - * \author Martin Stein - * \date 2012-10-11 - */ - -/* - * Copyright (C) 2012-2013 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 _PIC__CORTEX_A9_NO_TRUSTZONE_H_ -#define _PIC__CORTEX_A9_NO_TRUSTZONE_H_ - -/* core includes */ -#include -#include - -namespace Cortex_a9_no_trustzone -{ - using namespace Genode; - - /** - * Programmable interrupt controller for core - */ - class Pic : public Cortex_a9::Pic - { - public: - - /** - * Constructor - */ - Pic() - { - /* disable device */ - _distr.write(0); - _cpu.write(0); - mask(); - - /* supported priority range */ - unsigned const min_prio = _distr.min_priority(); - unsigned const max_prio = _distr.max_priority(); - - /* configure every shared peripheral interrupt */ - for (unsigned i=MIN_SPI; i <= _max_interrupt; i++) - { - _distr.write(0, i); - _distr.write(max_prio, i); - _distr.write( - Distr::Icdiptr::Cpu_targets::ALL, i); - } - - /* disable the priority filter */ - _cpu.write(min_prio); - - /* disable preemption of interrupt handling by interrupts */ - _cpu.write( - Cpu::Iccbpr::Binary_point::NO_PREEMPTION); - - /* enable device */ - _distr.write(1); - _cpu.write(1); - } - }; -} - -#endif /* _PIC__CORTEX_A9_NO_TRUSTZONE_H_ */ - diff --git a/base-hw/src/core/pic/vea9x4_trustzone.h b/base-hw/src/core/pic/vea9x4_trustzone.h index 85c756aff..c75be962b 100644 --- a/base-hw/src/core/pic/vea9x4_trustzone.h +++ b/base-hw/src/core/pic/vea9x4_trustzone.h @@ -15,8 +15,8 @@ #define _PIC__VEA9X4_TRUSTZONE_H_ /* core includes */ -#include -#include +#include +#include namespace Vea9x4_trustzone { @@ -25,44 +25,50 @@ namespace Vea9x4_trustzone /** * Programmable interrupt controller for core */ - class Pic : public Cortex_a9::Pic + class Pic : public Arm_gic::Pic { public: /** * Constructor */ - Pic() + Pic() : Arm_gic::Pic(Genode::Cpu::PL390_DISTRIBUTOR_MMIO_BASE, + Genode::Cpu::PL390_CPU_MMIO_BASE) { /* configure every shared peripheral interrupt */ for (unsigned i=MIN_SPI; i <= _max_interrupt; i++) { - _distr.write(0, i); - _distr.write(0, i); - _distr.write(Distr::Icdiptr::Cpu_targets::ALL, i); + _distr.write(0, i); + _distr.write(0, i); + _distr.write( + Distr::Itargetsr::ALL, i); } /* disable the priority filter */ - _cpu.write(0xff); + _cpu.write(0xff); /* signal secure IRQ via FIQ interface */ - _cpu.write(Cpu::Iccicr::Enable_s::bits(1) | - Cpu::Iccicr::Enable_ns::bits(1) | - Cpu::Iccicr::Fiq_en::bits(1)); + _cpu.write(Cpu::Ctlr::Enable_grp0::bits(1) | + Cpu::Ctlr::Enable_grp1::bits(1) | + Cpu::Ctlr::Fiq_en::bits(1)); /* use whole band of prios */ - _cpu.write(Cpu::Iccbpr::Binary_point::NO_PREEMPTION); + _cpu.write(Cpu::Bpr::NO_PREEMPTION); /* enable device */ - _distr.write(Distr::Icddcr::Enable::bits(1)); + _distr.write(Distr::Ctlr::Enable::bits(1)); } /** * Mark interrupt 'i' unsecure */ void unsecure(unsigned const i) { - _distr.write(1, i); } + _distr.write(1, i); } }; } + +bool Arm_gic::Pic::_use_security_ext() { return 1; } + + #endif /* _PIC__VEA9X4_TRUSTZONE_H_ */ diff --git a/base-hw/src/core/timer/exynos_pwm.h b/base-hw/src/core/timer/exynos_pwm.h new file mode 100644 index 000000000..888b2b432 --- /dev/null +++ b/base-hw/src/core/timer/exynos_pwm.h @@ -0,0 +1,166 @@ +/* + * \brief Timer for core + * \author Martin stein + * \date 2013-01-10 + */ + +/* + * Copyright (C) 2013 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 _TIMER__EXYNOS_PWM_H_ +#define _TIMER__EXYNOS_PWM_H_ + +/* Genode includes */ +#include + +namespace Exynos_pwm +{ + using namespace Genode; + + /** + * Timer for core + * + * Exynos 5 PWM timer provides 5 independent 32 bit down count timers. + * This driver uses timer 0 only. + */ + class Timer : public Mmio + { + enum { PRESCALER = 2 }; + + /** + * Timer configuration 0 + */ + struct Cfg0 : Register<0x0, 32> + { + struct Prescaler0 : Bitfield<0, 8> + { + enum { DEFAULT = PRESCALER - 1 }; + }; + }; + + /** + * Timer configuration 1 + */ + struct Cfg1 : Register<0x4, 32> + { + struct Div0 : Bitfield<0, 4> { enum { DISABLE = 0 }; }; + }; + + /** + * Timer control + */ + struct Con : Register<0x8, 32> + { + struct Enable0 : Bitfield<0, 1> { }; + struct Update0 : Bitfield<1, 1> { }; + struct Invert_tout0 : Bitfield<2, 1> { }; + struct Auto_reload0 : Bitfield<3, 1> { }; + struct Deadzone_en : Bitfield<4, 1> { }; + + /** + * Initialization value + */ + static access_t init_value() + { + return Invert_tout0::bits(0) | + Auto_reload0::bits(0) | + Deadzone_en::bits(0); + } + }; + + /** + * Timer 0 count buffer + */ + struct Cntb0 : Register<0xc, 32> { }; + + /** + * Timer 0 compare buffer + */ + struct Cmpb0 : Register<0x10, 32> { }; + + /** + * Timer 0 count observation + */ + struct Cnto0 : Register<0x14, 32> { }; + + /** + * Timer IRQ control and status + */ + struct Int : Register<0x44, 32> + { + struct En0 : Bitfield<0, 1> { }; + struct En1 : Bitfield<1, 1> { }; + struct En2 : Bitfield<2, 1> { }; + struct En3 : Bitfield<3, 1> { }; + struct En4 : Bitfield<4, 1> { }; + struct Stat0 : Bitfield<5, 1> { }; + + /** + * Initialization value + */ + static access_t init_value() + { + return En0::bits(1) | + En1::bits(0) | + En2::bits(0) | + En3::bits(0) | + En4::bits(0); + } + }; + + float const _tics_per_ms; + + public: + + /** + * Constructor + */ + Timer(addr_t const base, unsigned const clk) + : Mmio(base), _tics_per_ms((float)clk / PRESCALER / 1000) + { + write(Cfg0::Prescaler0::DEFAULT); + write(Cfg1::Div0::DISABLE); + write(Int::init_value()); + write(Con::init_value()); + write(0); + } + + /** + * Start a one-shot run + * + * \param tics native timer value used to assess the delay + * of the timer interrupt as of the call + */ + inline void start_one_shot(uint32_t const tics) + { + write(tics); + write(0); + write(1); + write(0); + write(1); + } + + /** + * Translate milliseconds to a native timer value + */ + uint32_t ms_to_tics(unsigned const ms) { + return ms * _tics_per_ms; } + + /** + * Stop the timer and return last timer value + */ + unsigned stop_one_shot() { return read(); } + + /** + * Clear interrupt output line + */ + void clear_interrupt() { write(1); } + }; +} + +#endif /* _TIMER__EXYNOS_PWM_H_ */ + diff --git a/base-hw/src/core/vea9x4/no_trustzone/pic.h b/base-hw/src/core/vea9x4/no_trustzone/pic.h index 5e40569a4..e5ec4f727 100644 --- a/base-hw/src/core/vea9x4/no_trustzone/pic.h +++ b/base-hw/src/core/vea9x4/no_trustzone/pic.h @@ -15,15 +15,19 @@ #define _VEA9X4__NO_TRUSTZONE__PIC_H_ /* core includes */ -#include +#include namespace Kernel { /** * Interrupt controller for kernel */ - class Pic : public Cortex_a9_no_trustzone::Pic { }; + class Pic : public Cortex_a9::Pic { }; } + +bool Arm_gic::Pic::_use_security_ext() { return 0; } + + #endif /* _VEA9X4__NO_TRUSTZONE__PIC_H_ */ diff --git a/base-hw/src/core/vea9x4/no_trustzone/platform_support.cc b/base-hw/src/core/vea9x4/no_trustzone/platform_support.cc index 39456f4e3..b4ff5b4fe 100644 --- a/base-hw/src/core/vea9x4/no_trustzone/platform_support.cc +++ b/base-hw/src/core/vea9x4/no_trustzone/platform_support.cc @@ -12,8 +12,8 @@ */ /* core includes */ -#include #include +#include #include #include @@ -37,7 +37,7 @@ Native_region * Platform::_irq_regions(unsigned const i) { static Native_region _regions[] = { - { 0, Cortex_a9_no_trustzone::Pic::MAX_INTERRUPT_ID + 1 } + { 0, Kernel::Pic::MAX_INTERRUPT_ID + 1 } }; return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; } @@ -48,7 +48,7 @@ Native_region * Platform::_core_only_irq_regions(unsigned const i) static Native_region _regions[] = { /* Core timer */ - { Cortex_a9::Cpu::PRIVATE_TIMER_IRQ, 1 }, + { Genode::Cpu::PRIVATE_TIMER_IRQ, 1 }, /* Core UART */ { Board::PL011_0_IRQ, 1 }