genode/base-hw/src/core/imx53/trustzone/csu.h
Stefan Kalkowski 379c6c1cd4 i.MX53: fix incorrect DMA protection settings
Within the central security unit of the i.MX53 SoC, one can set protection
level of various DMA bus master requests, distinguishing them between normal,
and secure access. Although, the access level was meant to be set correctly,
the enumeration values that denoted the kind of access were incorrect. Thereby,
until now every DMA requests was set as being secure. This commit corrects
the enumeration values, and sets all DMA operations as being unsecure, accept
from the graphical subsystem which is controlled by the secure world only.

Thanks to Andrea Barisani and Andrej Rosano from Inverse Path for discovering
this bug, as well as the hardware limitation!
2014-02-28 10:11:13 +01:00

226 lines
6.3 KiB
C++

/*
* \brief Driver for the Central Security Unit
* \author Stefan Kalkowski
* \date 2012-11-06
*/
/*
* 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 _SRC__SERVER__VMM__INCLUDE__CSU_H_
#define _SRC__SERVER__VMM__INCLUDE__CSU_H_
/* Genode includes */
#include <util/mmio.h>
#include <util/register.h>
namespace Genode
{
class Csu : Mmio
{
private:
template <off_t OFF>
struct Csl : public Register<OFF, 32>
{
enum {
SECURE = 0x33,
UNSECURE = 0xff,
};
struct Slave_a : Register<OFF, 32>::template Bitfield<0, 9> { };
struct Slave_b : Register<OFF, 32>::template Bitfield<16, 9> { };
};
struct Master : public Register<0x218, 32>
{
enum {
SECURE_UNLOCKED,
UNSECURE_UNLOCKED,
SECURE_LOCKED,
UNSECURE_LOCKED
};
struct Esdhc3 : Bitfield<0,2> { };
struct Cortex : Bitfield<2,2> { };
struct Sdma : Bitfield<4,2> { };
struct Gpu : Bitfield<6,2> { };
struct Usb : Bitfield<8,2> { };
struct Pata : Bitfield<10,2> { };
struct Mlb : Bitfield<14,2> { };
struct Rtic : Bitfield<18,2> { };
struct Esdhc4 : Bitfield<20,2> { };
struct Fec : Bitfield<22,2> { };
struct Dap : Bitfield<24,2> { };
struct Esdhc1 : Bitfield<26,2> { };
struct Esdhc2 : Bitfield<28,2> { };
};
struct Alarm_mask : public Register<0x230, 32> { };
struct Irq_ctrl : public Register<0x368, 32> { };
public:
typedef Csl<0x00> Csl00;
typedef Csl<0x04> Csl01;
typedef Csl<0x08> Csl02;
typedef Csl<0x0c> Csl03;
typedef Csl<0x10> Csl04;
typedef Csl<0x14> Csl05;
typedef Csl<0x18> Csl06;
typedef Csl<0x1c> Csl07;
typedef Csl<0x20> Csl08;
typedef Csl<0x24> Csl09;
typedef Csl<0x28> Csl10;
typedef Csl<0x2c> Csl11;
typedef Csl<0x30> Csl12;
typedef Csl<0x34> Csl13;
typedef Csl<0x38> Csl14;
typedef Csl<0x3c> Csl15;
typedef Csl<0x40> Csl16;
typedef Csl<0x44> Csl17;
typedef Csl<0x48> Csl18;
typedef Csl<0x4c> Csl19;
typedef Csl<0x50> Csl20;
typedef Csl<0x54> Csl21;
typedef Csl<0x58> Csl22;
typedef Csl<0x5c> Csl23;
typedef Csl<0x60> Csl24;
typedef Csl<0x64> Csl25;
typedef Csl<0x68> Csl26;
typedef Csl<0x6c> Csl27;
typedef Csl<0x70> Csl28;
typedef Csl<0x74> Csl29;
typedef Csl<0x78> Csl30;
typedef Csl<0x7c> Csl31;
Csu(addr_t const base) : Mmio(base)
{
/* Power (CCM, SRC, DPLLIP1-4, GPC and OWIRE) */
write<Csl09::Slave_a>(Csl00::UNSECURE);
/* AHBMAX S0-S2 */
write<Csl09::Slave_b>(Csl00::UNSECURE);
write<Csl20::Slave_a>(Csl00::UNSECURE);
write<Csl06::Slave_b>(Csl00::UNSECURE);
/* AHBMAX M6 */
write<Csl10::Slave_a>(Csl00::UNSECURE);
/* Timer (EPIT, GPT) TODO */
write<Csl04::Slave_a>(Csl00::UNSECURE);
/* UART 1-5 */
write<Csl07::Slave_b>(Csl00::UNSECURE);
write<Csl08::Slave_a>(Csl00::UNSECURE);
write<Csl26::Slave_a>(Csl00::UNSECURE);
write<Csl30::Slave_b>(Csl00::UNSECURE);
write<Csl19::Slave_a>(Csl00::UNSECURE);
/* GPIO */
write<Csl00::Slave_b>(Csl00::SECURE);
write<Csl01::Slave_a>(Csl00::SECURE);
write<Csl01::Slave_b>(Csl00::SECURE);
write<Csl02::Slave_a>(Csl00::SECURE);
/* IOMUXC TODO */
write<Csl05::Slave_a>(Csl00::UNSECURE);
/* SDMA TODO */
write<Csl15::Slave_a>(Csl00::UNSECURE);
/* USB */
write<Csl00::Slave_a>(Csl00::UNSECURE);
/* TVE */
write<Csl22::Slave_b>(Csl00::SECURE);
/* I2C */
write<Csl18::Slave_a>(Csl00::SECURE);
write<Csl17::Slave_b>(Csl00::SECURE);
write<Csl31::Slave_a>(Csl00::SECURE);
/* IPU */
write<Csl24::Slave_a>(Csl00::SECURE);
/* Audio */
write<Csl18::Slave_b>(Csl00::UNSECURE);
/* SATA */
write<Csl07::Slave_a>(Csl00::UNSECURE);
/* FEC */
write<Csl22::Slave_a>(Csl00::UNSECURE);
/* SDHCI 1-4 */
write<Csl25::Slave_a>(Csl00::UNSECURE);
write<Csl25::Slave_b>(Csl00::UNSECURE);
write<Csl28::Slave_a>(Csl00::UNSECURE);
write<Csl28::Slave_b>(Csl00::UNSECURE);
/* SPDIF */
write<Csl29::Slave_a>(Csl00::UNSECURE);
/* GPU 2D */
write<Csl24::Slave_b>(Csl00::SECURE);
/* GPU 3D */
write<Csl27::Slave_b>(Csl00::SECURE);
write<Csl02::Slave_b>(Csl00::UNSECURE);
write<Csl03::Slave_a>(Csl00::UNSECURE);
write<Csl03::Slave_b>(Csl00::UNSECURE);
write<Csl04::Slave_b>(Csl00::UNSECURE); // SRTC
write<Csl05::Slave_b>(Csl00::UNSECURE);
write<Csl06::Slave_a>(Csl00::UNSECURE);
write<Csl08::Slave_b>(Csl00::UNSECURE);
write<Csl10::Slave_b>(Csl00::UNSECURE);
write<Csl11::Slave_a>(Csl00::UNSECURE);
write<Csl11::Slave_b>(Csl00::UNSECURE);
write<Csl12::Slave_a>(Csl00::UNSECURE);
write<Csl12::Slave_b>(Csl00::UNSECURE);
write<Csl13::Slave_a>(Csl00::UNSECURE);
write<Csl13::Slave_b>(Csl00::UNSECURE);
write<Csl14::Slave_a>(Csl00::UNSECURE);
write<Csl14::Slave_b>(Csl00::UNSECURE);
write<Csl15::Slave_b>(Csl00::UNSECURE); // SCC
write<Csl16::Slave_a>(Csl00::UNSECURE);
write<Csl16::Slave_b>(Csl00::UNSECURE); // RTIC
write<Csl17::Slave_a>(Csl00::UNSECURE);
write<Csl19::Slave_b>(Csl00::UNSECURE);
write<Csl20::Slave_b>(Csl00::UNSECURE);
write<Csl21::Slave_a>(Csl00::UNSECURE);
write<Csl21::Slave_b>(Csl00::UNSECURE);
write<Csl23::Slave_a>(Csl00::SECURE); //VPU
write<Csl23::Slave_b>(Csl00::UNSECURE);
write<Csl26::Slave_b>(Csl00::UNSECURE);
write<Csl27::Slave_a>(Csl00::UNSECURE);
write<Csl29::Slave_b>(Csl00::UNSECURE);
write<Csl30::Slave_a>(Csl00::UNSECURE);
write<Csl31::Slave_b>(Csl00::UNSECURE);
/* DMA from graphical subsystem is considered to be secure */
write<Master::Gpu>(Master::SECURE_UNLOCKED);
/* all other DMA operations are insecure */
write<Master::Sdma>(Master::UNSECURE_UNLOCKED);
write<Master::Usb>(Master::UNSECURE_UNLOCKED);
write<Master::Pata>(Master::UNSECURE_UNLOCKED);
write<Master::Fec>(Master::UNSECURE_UNLOCKED);
write<Master::Dap>(Master::UNSECURE_UNLOCKED);
write<Master::Esdhc1>(Master::UNSECURE_UNLOCKED);
write<Master::Esdhc2>(Master::UNSECURE_UNLOCKED);
write<Master::Esdhc3>(Master::UNSECURE_UNLOCKED);
write<Master::Esdhc4>(Master::UNSECURE_UNLOCKED);
}
};
}
#endif /* _BASE_HW__SRC__SERVER__VMM__TSC_380_H_ */