mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 18:56:29 +00:00
parent
f6ede8cf0d
commit
60fbbc1fd1
43
base-hw/include/arndale_uart/drivers/serial_log.h
Normal file
43
base-hw/include/arndale_uart/drivers/serial_log.h
Normal file
@ -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 <board.h>
|
||||
#include <drivers/uart/arndale_uart_base.h>
|
||||
|
||||
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_ */
|
||||
|
15
base-hw/mk/spec-hw_arndale.mk
Normal file
15
base-hw/mk/spec-hw_arndale.mk
Normal file
@ -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)
|
29
base-hw/src/core/arndale/cpu.h
Normal file
29
base-hw/src/core/arndale/cpu.h
Normal file
@ -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 <cpu/cortex_a15.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
/**
|
||||
* CPU driver for core
|
||||
*/
|
||||
class Cpu : public Cortex_a15::Cpu { };
|
||||
}
|
||||
|
||||
#endif /* _ARNDALE__CPU_H_ */
|
||||
|
42
base-hw/src/core/arndale/pic.h
Normal file
42
base-hw/src/core/arndale/pic.h
Normal file
@ -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 <pic/corelink_gic400.h>
|
||||
#include <board.h>
|
||||
|
||||
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_ */
|
||||
|
71
base-hw/src/core/arndale/platform_support.cc
Normal file
71
base-hw/src/core/arndale/platform_support.cc
Normal file
@ -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 <board.h>
|
||||
#include <platform.h>
|
||||
#include <pic.h>
|
||||
#include <timer.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
44
base-hw/src/core/arndale/target.mk
Normal file
44
base-hw/src/core/arndale/target.mk
Normal file
@ -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
|
||||
|
41
base-hw/src/core/arndale/timer.h
Normal file
41
base-hw/src/core/arndale/timer.h
Normal file
@ -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 <board.h>
|
||||
#include <timer/exynos_pwm.h>
|
||||
|
||||
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_ */
|
||||
|
47
base-hw/src/core/arndale/tlb.h
Normal file
47
base-hw/src/core/arndale/tlb.h
Normal file
@ -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 <board.h>
|
||||
#include <tlb/arm_v7.h>
|
||||
|
||||
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_ */
|
||||
|
44
base-hw/src/core/cpu/cortex_a15.h
Normal file
44
base-hw/src/core/cpu/cortex_a15.h
Normal file
@ -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 <util/register.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
/* core includes */
|
||||
#include <cpu/arm_v7.h>
|
||||
#include <board.h>
|
||||
|
||||
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_ */
|
||||
|
@ -15,15 +15,19 @@
|
||||
#define _PANDA__PIC_H_
|
||||
|
||||
/* core includes */
|
||||
#include <pic/cortex_a9_no_trustzone.h>
|
||||
#include <pic/cortex_a9.h>
|
||||
|
||||
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_ */
|
||||
|
||||
|
@ -12,10 +12,10 @@
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <cpu/cortex_a9.h>
|
||||
#include <pic/cortex_a9_no_trustzone.h>
|
||||
#include <platform.h>
|
||||
#include <board.h>
|
||||
#include <cpu.h>
|
||||
#include <pic.h>
|
||||
|
||||
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 }
|
||||
|
@ -15,15 +15,19 @@
|
||||
#define _PBXA9__PIC_H_
|
||||
|
||||
/* core includes */
|
||||
#include <pic/cortex_a9_no_trustzone.h>
|
||||
#include <pic/cortex_a9.h>
|
||||
|
||||
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_ */
|
||||
|
||||
|
@ -12,10 +12,10 @@
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <board.h>
|
||||
#include <platform.h>
|
||||
#include <cpu/cortex_a9.h>
|
||||
#include <pic/cortex_a9_no_trustzone.h>
|
||||
#include <board.h>
|
||||
#include <cpu.h>
|
||||
#include <pic.h>
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
326
base-hw/src/core/pic/arm_gic.h
Normal file
326
base-hw/src/core/pic/arm_gic.h
Normal file
@ -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 <util/mmio.h>
|
||||
|
||||
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::Priority>(Ipriorityr::GET_MIN, 0);
|
||||
return read<Ipriorityr::Priority>(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<Typer::It_lines_number>();
|
||||
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<Distr::Ctlr::Enable>(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<Distr::Icfgr::Edge_triggered>(0, i);
|
||||
_distr.write<Distr::Ipriorityr::Priority>(max_prio, i);
|
||||
_distr.write<Distr::Itargetsr::Cpu_targets>(
|
||||
Distr::Itargetsr::ALL, i);
|
||||
}
|
||||
|
||||
/* disable the priority filter */
|
||||
_cpu.write<Cpu::Pmr::Priority>(min_prio);
|
||||
|
||||
/* disable preemption of interrupt handling by interrupts */
|
||||
_cpu.write<Cpu::Bpr::Binary_point>(Cpu::Bpr::NO_PREEMPTION);
|
||||
|
||||
/* enable device */
|
||||
_distr.write<Distr::Ctlr::Enable>(1);
|
||||
_cpu.write<Cpu::Ctlr::Enable>(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<Cpu::Iar::Irq_id>();
|
||||
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>(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<Distr::Isenabler::Set_enable>(1, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmask interrupt 'i'
|
||||
*/
|
||||
void unmask(unsigned const i) {
|
||||
_distr.write<Distr::Isenabler::Set_enable>(1, i); }
|
||||
|
||||
/**
|
||||
* Mask all interrupts
|
||||
*/
|
||||
void mask()
|
||||
{
|
||||
for (unsigned i=0; i <= _max_interrupt; i++)
|
||||
_distr.write<Distr::Icenabler::Clear_enable>(1, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mask interrupt 'i'
|
||||
*/
|
||||
void mask(unsigned const i) {
|
||||
_distr.write<Distr::Icenabler::Clear_enable>(1, i); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _PIC__ARM_GIC_H_ */
|
||||
|
47
base-hw/src/core/pic/corelink_gic400.h
Normal file
47
base-hw/src/core/pic/corelink_gic400.h
Normal file
@ -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 <pic/arm_gic.h>
|
||||
|
||||
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_ */
|
||||
|
@ -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 <util/mmio.h>
|
||||
/* core includes */
|
||||
#include <pic/arm_gic.h>
|
||||
#include <cpu.h>
|
||||
|
||||
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>(Icdipr::Priority::GET_MIN_PRIORITY, 0);
|
||||
return read<Icdipr::Priority>(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<Icdictr::It_lines_number>();
|
||||
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<Cpu::Icciar::Ack_int_id>();
|
||||
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>(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<Distr::Icdiser::Set_enable>(1, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmask interrupt 'i'
|
||||
*/
|
||||
void unmask(unsigned const i) {
|
||||
_distr.write<Distr::Icdiser::Set_enable>(1, i); }
|
||||
|
||||
/**
|
||||
* Mask all interrupts
|
||||
*/
|
||||
void mask()
|
||||
{
|
||||
for (unsigned i=0; i <= _max_interrupt; i++)
|
||||
_distr.write<Distr::Icdicer::Clear_enable>(1, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mask interrupt 'i'
|
||||
*/
|
||||
void mask(unsigned const i) {
|
||||
_distr.write<Distr::Icdicer::Clear_enable>(1, i); }
|
||||
Pic() : Arm_gic::Pic(Genode::Cpu::PL390_DISTRIBUTOR_MMIO_BASE,
|
||||
Genode::Cpu::PL390_CPU_MMIO_BASE) { }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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 <cpu/cortex_a9.h>
|
||||
#include <pic/cortex_a9.h>
|
||||
|
||||
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<Distr::Icddcr::Enable>(0);
|
||||
_cpu.write<Cpu::Iccicr::Enable>(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<Distr::Icdicr::Edge_triggered>(0, i);
|
||||
_distr.write<Distr::Icdipr::Priority>(max_prio, i);
|
||||
_distr.write<Distr::Icdiptr::Cpu_targets>(
|
||||
Distr::Icdiptr::Cpu_targets::ALL, i);
|
||||
}
|
||||
|
||||
/* disable the priority filter */
|
||||
_cpu.write<Cpu::Iccpmr::Priority>(min_prio);
|
||||
|
||||
/* disable preemption of interrupt handling by interrupts */
|
||||
_cpu.write<Cpu::Iccbpr::Binary_point>(
|
||||
Cpu::Iccbpr::Binary_point::NO_PREEMPTION);
|
||||
|
||||
/* enable device */
|
||||
_distr.write<Distr::Icddcr::Enable>(1);
|
||||
_cpu.write<Cpu::Iccicr::Enable>(1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _PIC__CORTEX_A9_NO_TRUSTZONE_H_ */
|
||||
|
@ -15,8 +15,8 @@
|
||||
#define _PIC__VEA9X4_TRUSTZONE_H_
|
||||
|
||||
/* core includes */
|
||||
#include <cpu/cortex_a9.h>
|
||||
#include <pic/cortex_a9.h>
|
||||
#include <pic/arm_gic.h>
|
||||
#include <cpu.h>
|
||||
|
||||
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<Distr::Icdicr::Edge_triggered>(0, i);
|
||||
_distr.write<Distr::Icdipr::Priority>(0, i);
|
||||
_distr.write<Distr::Icdiptr::Cpu_targets>(Distr::Icdiptr::Cpu_targets::ALL, i);
|
||||
_distr.write<Distr::Icfgr::Edge_triggered>(0, i);
|
||||
_distr.write<Distr::Ipriorityr::Priority>(0, i);
|
||||
_distr.write<Distr::Itargetsr::Cpu_targets>(
|
||||
Distr::Itargetsr::ALL, i);
|
||||
}
|
||||
|
||||
/* disable the priority filter */
|
||||
_cpu.write<Cpu::Iccpmr::Priority>(0xff);
|
||||
_cpu.write<Cpu::Pmr::Priority>(0xff);
|
||||
|
||||
/* signal secure IRQ via FIQ interface */
|
||||
_cpu.write<Cpu::Iccicr>(Cpu::Iccicr::Enable_s::bits(1) |
|
||||
Cpu::Iccicr::Enable_ns::bits(1) |
|
||||
Cpu::Iccicr::Fiq_en::bits(1));
|
||||
_cpu.write<Cpu::Ctlr>(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>(Cpu::Iccbpr::Binary_point::NO_PREEMPTION);
|
||||
_cpu.write<Cpu::Bpr::Binary_point>(Cpu::Bpr::NO_PREEMPTION);
|
||||
|
||||
/* enable device */
|
||||
_distr.write<Distr::Icddcr>(Distr::Icddcr::Enable::bits(1));
|
||||
_distr.write<Distr::Ctlr>(Distr::Ctlr::Enable::bits(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark interrupt 'i' unsecure
|
||||
*/
|
||||
void unsecure(unsigned const i) {
|
||||
_distr.write<Distr::Icdisr::Nonsecure>(1, i); }
|
||||
_distr.write<Distr::Igroupr::Group_status>(1, i); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
bool Arm_gic::Pic::_use_security_ext() { return 1; }
|
||||
|
||||
|
||||
#endif /* _PIC__VEA9X4_TRUSTZONE_H_ */
|
||||
|
||||
|
166
base-hw/src/core/timer/exynos_pwm.h
Normal file
166
base-hw/src/core/timer/exynos_pwm.h
Normal file
@ -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 <util/mmio.h>
|
||||
|
||||
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>(Cfg0::Prescaler0::DEFAULT);
|
||||
write<Cfg1::Div0>(Cfg1::Div0::DISABLE);
|
||||
write<Int>(Int::init_value());
|
||||
write<Con>(Con::init_value());
|
||||
write<Cmpb0>(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<Cntb0>(tics);
|
||||
write<Con::Enable0>(0);
|
||||
write<Con::Update0>(1);
|
||||
write<Con::Update0>(0);
|
||||
write<Con::Enable0>(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<Cnto0>(); }
|
||||
|
||||
/**
|
||||
* Clear interrupt output line
|
||||
*/
|
||||
void clear_interrupt() { write<Int::Stat0>(1); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _TIMER__EXYNOS_PWM_H_ */
|
||||
|
@ -15,15 +15,19 @@
|
||||
#define _VEA9X4__NO_TRUSTZONE__PIC_H_
|
||||
|
||||
/* core includes */
|
||||
#include <pic/cortex_a9_no_trustzone.h>
|
||||
#include <pic/cortex_a9.h>
|
||||
|
||||
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_ */
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <board.h>
|
||||
#include <platform.h>
|
||||
#include <board.h>
|
||||
#include <cpu.h>
|
||||
#include <pic.h>
|
||||
|
||||
@ -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 }
|
||||
|
Loading…
Reference in New Issue
Block a user