genode/repos/os/src/server/tz_vmm/vea9x4/tsc_380.h

209 lines
6.6 KiB
C++

/*
* \brief Driver for the CoreLink Trustzone Address Space Controller TSC-380
* \author Stefan Kalkowski
* \date 2012-07-04
*/
/*
* 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 _BASE_HW__SRC__SERVER__VMM__TSC_380_H_
#define _BASE_HW__SRC__SERVER__VMM__TSC_380_H_
/* Genode includes */
#include <util/mmio.h>
class Tsc_380 : Genode::Mmio
{
private:
enum {
REGION0_REG_OFF = 0x100,
REGION1_REG_OFF = 0x110,
REGION2_REG_OFF = 0x120,
REGION3_REG_OFF = 0x130,
REGION4_REG_OFF = 0x140,
REGION5_REG_OFF = 0x150,
REGION6_REG_OFF = 0x160,
REGION7_REG_OFF = 0x170,
REGION8_REG_OFF = 0x180,
REGION9_REG_OFF = 0x190,
REGION10_REG_OFF = 0x1a0,
REGION11_REG_OFF = 0x1b0,
REGION12_REG_OFF = 0x1c0,
REGION13_REG_OFF = 0x1d0,
REGION14_REG_OFF = 0x1e0,
REGION15_REG_OFF = 0x1f0,
REGION_LOW_OFF = 0x0,
REGION_HIGH_OFF = 0x4,
REGION_ATTR_OFF = 0x8,
};
/**
* Configuration register
*/
struct Config : public Register<0, 32>
{
struct Region_number : Bitfield<0,4> { };
struct Address_width : Bitfield<8,6> { };
};
struct Irq_status : public Register<0x10, 32>
{
struct Status : Bitfield<0,1> {};
struct Overrun : Bitfield<1,1> {};
};
struct Irq_clear : public Register<0x14, 32>
{
struct Status : Bitfield<0,1> {};
struct Overrun : Bitfield<1,1> {};
};
/**
* Fail address low register
*/
struct Fail_low : public Register<0x20, 32> { };
template <Genode::off_t OFF>
struct Region_low : public Register<OFF + REGION_LOW_OFF, 32>
{
enum { MASK = ~0UL << 15 };
};
template <Genode::off_t OFF>
struct Region_high : public Register<OFF + REGION_HIGH_OFF, 32> { };
template <Genode::off_t OFF>
struct Region_attr : public Register<OFF + REGION_ATTR_OFF, 32>
{
struct Enable :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<0, 1> { };
struct Size :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<1, 6>
{
enum {
SZ_32K = 14,
SZ_64K,
SZ_128K,
SZ_256K,
SZ_512K,
SZ_1M,
SZ_2M,
SZ_4M,
SZ_8M,
SZ_16M,
SZ_32M,
SZ_64M,
SZ_128M,
SZ_256M,
SZ_512M,
SZ_1G,
};
};
struct Subreg0 :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<8, 1> { };
struct Subreg1 :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<9, 1> { };
struct Subreg2 :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<10, 1> { };
struct Subreg3 :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<11, 1> { };
struct Subreg4 :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<12, 1> { };
struct Subreg5 :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<13, 1> { };
struct Subreg6 :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<14, 1> { };
struct Subreg7 :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<15, 1> { };
struct Normal_write :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<28, 1> { };
struct Normal_read :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<29, 1> { };
struct Secure_write :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<30, 1> { };
struct Secure_read :
Register<OFF + REGION_ATTR_OFF, 32>::template Bitfield<31, 1> { };
};
typedef Region_low<0x100> Region0_low;
public:
Tsc_380(Genode::addr_t const base) : Genode::Mmio(base)
{
/* Access to AACI, MMCI, KMI0/1 */
write<Region_low<REGION15_REG_OFF> >(0x10000000);
write<Region_high<REGION15_REG_OFF> >(0x10008000);
write<Region_attr<REGION15_REG_OFF>::Enable>(1);
write<Region_attr<REGION15_REG_OFF>::Size>(Region_attr<REGION15_REG_OFF>::Size::SZ_32K);
write<Region_attr<REGION15_REG_OFF>::Normal_read>(1);
write<Region_attr<REGION15_REG_OFF>::Normal_write>(1);
write<Region_attr<REGION15_REG_OFF>::Secure_read>(1);
write<Region_attr<REGION15_REG_OFF>::Secure_write>(1);
write<Region_attr<REGION15_REG_OFF>::Subreg0>(1);
write<Region_attr<REGION15_REG_OFF>::Subreg1>(1);
write<Region_attr<REGION15_REG_OFF>::Subreg2>(1);
write<Region_attr<REGION15_REG_OFF>::Subreg3>(1);
/* Access to UART0, and WDT */
write<Region_low<REGION14_REG_OFF> >(0x10008000);
write<Region_high<REGION14_REG_OFF> >(0x10010000);
write<Region_attr<REGION14_REG_OFF>::Enable>(1);
write<Region_attr<REGION14_REG_OFF>::Size>(Region_attr<REGION14_REG_OFF>::Size::SZ_32K);
write<Region_attr<REGION14_REG_OFF>::Normal_read>(1);
write<Region_attr<REGION14_REG_OFF>::Normal_write>(1);
write<Region_attr<REGION14_REG_OFF>::Secure_read>(1);
write<Region_attr<REGION14_REG_OFF>::Secure_write>(1);
write<Region_attr<REGION14_REG_OFF>::Subreg0>(1);
write<Region_attr<REGION14_REG_OFF>::Subreg2>(1);
write<Region_attr<REGION14_REG_OFF>::Subreg3>(1);
write<Region_attr<REGION14_REG_OFF>::Subreg4>(1);
write<Region_attr<REGION14_REG_OFF>::Subreg5>(1);
write<Region_attr<REGION14_REG_OFF>::Subreg6>(1);
/* Access to SP804 2/3, and RTC */
write<Region_low<REGION13_REG_OFF> >(0x10010000);
write<Region_high<REGION13_REG_OFF> >(0x10018000);
write<Region_attr<REGION13_REG_OFF>::Enable>(1);
write<Region_attr<REGION13_REG_OFF>::Size>(Region_attr<REGION13_REG_OFF>::Size::SZ_32K);
write<Region_attr<REGION13_REG_OFF>::Normal_read>(1);
write<Region_attr<REGION13_REG_OFF>::Normal_write>(1);
write<Region_attr<REGION13_REG_OFF>::Secure_read>(1);
write<Region_attr<REGION13_REG_OFF>::Secure_write>(1);
write<Region_attr<REGION13_REG_OFF>::Subreg0>(1);
write<Region_attr<REGION13_REG_OFF>::Subreg1>(1);
write<Region_attr<REGION13_REG_OFF>::Subreg3>(1);
write<Region_attr<REGION13_REG_OFF>::Subreg4>(1);
write<Region_attr<REGION13_REG_OFF>::Subreg5>(1);
write<Region_attr<REGION13_REG_OFF>::Subreg6>(1);
/* Access to Ethernet and USB */
write<Region_low<REGION12_REG_OFF> >(0x4e000000);
write<Region_high<REGION12_REG_OFF> >(0x50000000);
write<Region_attr<REGION12_REG_OFF>::Enable>(1);
write<Region_attr<REGION12_REG_OFF>::Size>(Region_attr<REGION12_REG_OFF>::Size::SZ_32M);
write<Region_attr<REGION12_REG_OFF>::Normal_read>(1);
write<Region_attr<REGION12_REG_OFF>::Normal_write>(1);
write<Region_attr<REGION12_REG_OFF>::Secure_read>(1);
write<Region_attr<REGION12_REG_OFF>::Secure_write>(1);
/* clear interrupts */
write<Irq_clear>(0x3);
}
void* last_failed_access() {
void *ret = (void*) read<Fail_low>();
write<Irq_clear>(0x3);
return ret;
}
};
#endif /* _BASE_HW__SRC__SERVER__VMM__TSC_380_H_ */