SHARED_FLAGS += $(call CHECKCC,-Wformat=2,)
SHARED_FLAGS += $(call CHECKCC,-fno-stack-protector,)
SHARED_FLAGS += $(call CHECKCC,-Wframe-larger-than=512)
+SHARED_FLAGS += $(call CHECKCC,-fdiagnostics-show-option)
OPT_CXXFLAGS += $(call CHECKCXX,-fweb,)
OPT_CFLAGS += $(call CHECKCC,-fweb,)
OPT_SHARED_FLAGS += $(call CHECKCC,-frename-registers,)
# PF: IMX
# PFDESCR: Freescale i.MX
# PFDEPENDS: ARM
-# PFCAN: CAN_ARM_CPU_926
+
+choice
+ prompt "Freescale i.MX"
+ default PF_IMX_51
+
+config PF_IMX_21
+ bool "i.MX21"
+ depends on PF_IMX
+ select CAN_ARM_CPU_926
+ help
+ Choose for i.MX21
+
+config PF_IMX_51
+ bool "i.MX51"
+ depends on PF_IMX
+ select CAN_ARM_CPU_CORTEX_A8
+ help
+ Choose for i.MX51
+
+endchoice
+
+config PF_IMX_RAM_PHYS_BASE
+ hex
+ default 0xc0000000 if PF_IMX_21
+ default 0x90000000 if PF_IMX_51
SUBSYSTEMS += LIBUART
OBJECTS_LIBUART += uart_imx.o
-PREPROCESS_PARTS += imx libuart kern_start_0xd
-CONFIG_KERNEL_LOAD_ADDR := 0xc0000000
+PREPROCESS_PARTS += imx libuart
+PREPROCESS_PARTS += $(if $(CONFIG_PF_IMX_21),imx21 kern_start_0xd)
+PREPROCESS_PARTS += $(if $(CONFIG_PF_IMX_51),imx51 imx_epit \
+ pic_gic pic_gic_mxc_tzic)
+CONFIG_KERNEL_LOAD_ADDR := $(CONFIG_PF_IMX_RAM_PHYS_BASE)
+INTERFACES_KERNEL += $(if $(CONFIG_PF_IMX_51),gic)
+
+SUFFIX-$(CONFIG_PF_IMX_21) = imx21
+SUFFIX-$(CONFIG_PF_IMX_51) = imx51
uart_IMPL += uart-imx
config_IMPL += config-arm-imx
mem_layout_IMPL += mem_layout-arm-imx
-pic_IMPL += pic-arm-imx
+pic_IMPL += pic-arm-$(SUFFIX-y)
bootstrap_IMPL += bootstrap-arm-imx
-timer_IMPL += timer-arm-imx
+timer_IMPL += $(if $(CONFIG_PF_IMX_21),timer-arm-imx21)
+timer_IMPL += $(if $(CONFIG_PF_IMX_51),timer-arm-imx_epit)
kernel_uart_IMPL += kernel_uart-arm-imx
reset_IMPL += reset-arm-imx
clock_IMPL += clock-generic
};
//-----------------------------------------------------------------------------
-IMPLEMENTATION [arm && imx]:
+IMPLEMENTATION [arm && imx21]:
void
map_hw(void *pd)
{
// map devices
map_1mb(pd, Mem_layout::Device_map_base, Mem_layout::Device_phys_base, false, false);
}
+
+//-----------------------------------------------------------------------------
+IMPLEMENTATION [arm && imx51]:
+void
+map_hw(void *pd)
+{
+ map_1mb(pd, Mem_layout::Device_map_base, Mem_layout::Device_phys_base_1, false, false);
+ map_1mb(pd, Mem_layout::Device_map_base_2, Mem_layout::Device_phys_base_2, false, false);
+}
-INTERFACE [arm && imx]:
+INTERFACE [arm && imx21]:
-#define TARGET_NAME "i.MX"
+#define TARGET_NAME "i.MX21"
EXTENSION class Config
{
};
};
+INTERFACE [arm && imx51]:
+
+#define TARGET_NAME "i.MX51"
+
+EXTENSION class Config
+{
+public:
+ enum
+ {
+ Scheduling_irq = 40,
+ scheduler_irq_vector = Scheduling_irq,
+ Max_num_irqs = 130,
+ Max_num_dirqs = 128,
+ Vkey_irq = 128,
+ Tbuf_irq = 129,
+ };
+};
+
-IMPLEMENTATION [arm && imx && serial]:
+IMPLEMENTATION [arm && imx21 && serial]:
#include "mem_layout.h"
if(port!=3) return false;
return Uart::startup(Mem_layout::Uart_base, 20);
}
+
+IMPLEMENTATION [arm && imx51 && serial]:
+
+#include "mem_layout.h"
+
+IMPLEMENT
+bool Kernel_uart::startup(unsigned port, int /*irq*/)
+{
+ if(port!=3) return false;
+ return Uart::startup(Mem_layout::Uart_base, 31);
+}
public:
enum Virt_layout_imx {
Device_map_base = 0xef100000,
+ Device_map_base_2 = 0xef200000,
+ };
+
+ enum Phys_layout {
+ Sdram_phys_base = CONFIG_PF_IMX_RAM_PHYS_BASE,
+ Flush_area_phys_base = 0xe0000000,
+ };
+};
+
+INTERFACE [arm && imx && imx21]: // ---------------------------------------
+
+EXTENSION class Mem_layout
+{
+public:
+ enum Virt_layout_imx21 {
Uart_map_base = 0xef10a000,
Timer_map_base = 0xef103000,
Pll_map_base = 0xef127000,
Uart_base = Uart_map_base,
};
- enum Phys_layout {
+ enum Phys_layout_imx21 {
Device_phys_base = 0x10000000,
- Uart_phys_base = 0x1000a000,
+
Timer_phys_base = 0x10003000,
+ Uart_phys_base = 0x1000a000,
Pll_phys_base = 0x10027000,
Watchdog_phys_base = 0x10002000,
Pic_phys_base = 0x10040000,
- Sdram_phys_base = 0xc0000000,
- Flush_area_phys_base = 0xe0000000,
};
};
+INTERFACE [arm && imx && imx51]: // ---------------------------------------
+
+EXTENSION class Mem_layout
+{
+public:
+ enum Virt_layout_imx51 {
+ Timer_map_base = 0xef1ac000,
+ Uart_map_base = 0xef1bc000,
+ Watchdog_map_base = 0xef198000,
+ Pic_map_base = 0xef200000,
+ Uart_base = Uart_map_base,
+ };
+
+ enum Phys_layout_imx51 {
+ Device_phys_base_1 = 0x73f00000,
+ Device_phys_base_2 = 0xe0000000,
+
+ Watchdog_phys_base = 0x73f98000, // wdog1
+ Timer_phys_base = 0x73fac000, // epit1
+ Uart_phys_base = 0x73fbc000, // uart1
+ Pic_phys_base = 0xe0000000,
+ };
+};
--- /dev/null
+// ---------------------------------------------------------------------
+INTERFACE [arm && imx]:
+
+#include "kmem.h"
+
+class Irq_base;
+
+EXTENSION class Pic
+{
+public:
+ enum
+ {
+ Multi_irq_pending = 0,
+ No_irq_pending = 0,
+ };
+
+ enum
+ {
+ INTCTL = Kmem::Pic_map_base + 0x00,
+ NIMASK = Kmem::Pic_map_base + 0x04,
+ INTENNUM = Kmem::Pic_map_base + 0x08,
+ INTDISNUM = Kmem::Pic_map_base + 0x0c,
+ INTENABLEH = Kmem::Pic_map_base + 0x10,
+ INTENABLEL = Kmem::Pic_map_base + 0x14,
+ INTTYPEH = Kmem::Pic_map_base + 0x18,
+ INTTYPEL = Kmem::Pic_map_base + 0x1c,
+ NIPRIORITY7 = Kmem::Pic_map_base + 0x20,
+ NIPRIORITY0 = Kmem::Pic_map_base + 0x3c,
+ NIVECSR = Kmem::Pic_map_base + 0x40,
+ FIVECSR = Kmem::Pic_map_base + 0x44,
+ INTSRCH = Kmem::Pic_map_base + 0x48,
+ INTSRCL = Kmem::Pic_map_base + 0x4c,
+ INTFRCH = Kmem::Pic_map_base + 0x50,
+ INTFRCL = Kmem::Pic_map_base + 0x54,
+ NIPNDH = Kmem::Pic_map_base + 0x58,
+ NIPNDL = Kmem::Pic_map_base + 0x5c,
+ FIPNDH = Kmem::Pic_map_base + 0x60,
+ FIPNDL = Kmem::Pic_map_base + 0x64,
+
+
+ INTCTL_FIAD = 1 << 19, // Fast Interrupt Arbiter Rise ARM Level
+ INTCTL_NIAD = 1 << 20, // Normal Interrupt Arbiter Rise ARM Level
+ INTCTL_FIDIS = 1 << 21, // Fast Interrupt Disable
+ INTCTL_NIDIS = 1 << 22, // Normal Interrupt Disable
+ };
+};
+
+// ---------------------------------------------------------------------
+IMPLEMENTATION [arm && imx]:
+
+#include "boot_info.h"
+#include "config.h"
+#include "initcalls.h"
+#include "io.h"
+#include "irq.h"
+#include "irq_chip_generic.h"
+#include "irq_pin.h"
+#include "vkey.h"
+
+#include <cstdio>
+
+class Imx_pin : public Irq_pin
+{
+public:
+ explicit Imx_pin(unsigned irq) { payload()[0] = irq; }
+ unsigned irq() const { return payload()[0]; }
+};
+
+PUBLIC
+void
+Imx_pin::unbind_irq()
+{
+ mask();
+ disable();
+ Irq_chip::hw_chip->free(Irq::self(this), irq());
+ replace<Sw_irq_pin>();
+}
+
+PUBLIC
+void
+Imx_pin::do_mask()
+{
+ assert (cpu_lock.test());
+ Io::write<Mword>(irq(), Pic::INTDISNUM); // disable pin
+}
+
+PUBLIC
+void
+Imx_pin::do_mask_and_ack()
+{
+ assert (cpu_lock.test());
+ __mask();
+ Io::write<Mword>(irq(), Pic::INTDISNUM); // disable pin
+ // ack is empty
+}
+
+PUBLIC
+void
+Imx_pin::ack()
+{
+ // ack is empty
+}
+
+PUBLIC
+void
+Imx_pin::hit()
+{
+ Irq::self(this)->Irq::hit();
+}
+
+PUBLIC
+void
+Imx_pin::do_unmask()
+{
+ assert (cpu_lock.test());
+ Io::write<Mword>(irq(), Pic::INTENNUM);
+}
+
+
+PUBLIC
+bool
+Imx_pin::check_debug_irq()
+{
+ return !Vkey::check_(irq());
+}
+
+PUBLIC
+void
+Imx_pin::set_cpu(unsigned)
+{
+}
+
+class Irq_chip_arm_x : public Irq_chip_gen
+{
+};
+
+PUBLIC
+void
+Irq_chip_arm_x::setup(Irq_base *irq, unsigned irqnum)
+{
+ if (irqnum < Config::Max_num_dirqs)
+ irq->pin()->replace<Imx_pin>(irqnum);
+}
+
+IMPLEMENT FIASCO_INIT
+void Pic::init()
+{
+ static Irq_chip_arm_x _ia;
+ Irq_chip::hw_chip = &_ia;
+
+ Io::write<Mword>(0, INTCTL);
+ Io::write<Mword>(0x10, NIMASK); // Do not disable any normal interrupts
+
+ Io::write<Mword>(0, INTTYPEH); // All interrupts generate normal interrupts
+ Io::write<Mword>(0, INTTYPEL);
+
+ // Init interrupt priorities
+ for (int i = 0; i < 8; ++i)
+ Io::write<Mword>(0x1111, NIPRIORITY7 + (i * 4)); // low addresses start with 7
+}
+
+IMPLEMENT inline
+Pic::Status Pic::disable_all_save()
+{
+ Status s = 0;
+ return s;
+}
+
+IMPLEMENT inline
+void Pic::restore_all( Status /*s*/ )
+{
+}
+
+PUBLIC static inline NEEDS["io.h"]
+Unsigned32 Pic::pending()
+{
+ return Io::read<Mword>(NIVECSR) >> 16;
+}
+
+PUBLIC static inline
+Mword Pic::is_pending(Mword &irqs, Mword irq)
+{
+ return irqs == irq;
+}
+
+//---------------------------------------------------------------------------
+IMPLEMENTATION [debug && imx]:
+
+PUBLIC
+char const *
+Imx_pin::pin_type() const
+{ return "HW i.MX IRQ"; }
+
--- /dev/null
+// ---------------------------------------------------------------------
+INTERFACE [arm && imx51]:
+
+#include "gic.h"
+#include "kmem.h"
+
+class Irq_base;
+
+EXTENSION class Pic
+{
+public:
+ enum
+ {
+ Multi_irq_pending = 0,
+ No_irq_pending = 0,
+ };
+private:
+ static Gic gic[1];
+};
+
+// ---------------------------------------------------------------------
+IMPLEMENTATION [arm && imx51]:
+
+#include "boot_info.h"
+#include "config.h"
+#include "initcalls.h"
+#include "io.h"
+#include "irq.h"
+#include "irq_chip_generic.h"
+#include "irq_pin.h"
+#include "vkey.h"
+
+#include <cstdio>
+
+Gic Gic_pin::_gic[1];
+
+class Irq_chip_arm_imx51 : public Irq_chip_gen
+{
+};
+
+PUBLIC
+void
+Irq_chip_arm_imx51::setup(Irq_base *irq, unsigned irqnum)
+{
+ if (irqnum < Config::Max_num_dirqs)
+ irq->pin()->replace<Gic_pin>(0, irqnum);
+}
+
+IMPLEMENT FIASCO_INIT
+void Pic::init()
+{
+ static Irq_chip_arm_imx51 _i;
+ Irq_chip::hw_chip = &_i;
+
+ Gic_pin::_gic[0].init(0, Kmem::Pic_map_base);
+}
+
+IMPLEMENT inline
+Pic::Status Pic::disable_all_save()
+{
+ return 0;
+}
+
+IMPLEMENT inline
+void Pic::restore_all( Status /*s*/ )
+{
+}
+
+PUBLIC static inline NEEDS["io.h"]
+Unsigned32 Pic::pending()
+{
+ return Gic_pin::_gic[0].pending();
+}
+
+PUBLIC static inline
+Mword Pic::is_pending(Mword &irqs, Mword irq)
+{
+ return irqs == irq;
+}
-IMPLEMENTATION [arm && imx]:
+IMPLEMENTATION [arm && imx21]:
#include "io.h"
#include "kmem.h"
pc_reset(void)
{
enum {
- WCR = Kmem::Watchdog_map_base + 0x00,
+ WCR = Kmem::Watchdog_map_base + 0,
WCR_SRS = 1 << 4, // Software Reset Signal
PLL_PCCR1 = Kmem::Pll_map_base + 0x24,
for (;;)
;
}
+
+// ------------------------------------------------------------------------
+IMPLEMENTATION [arm && imx51]:
+
+#include "io.h"
+#include "kmem.h"
+
+void __attribute__ ((noreturn))
+pc_reset(void)
+{
+ enum {
+ WCR = Kmem::Watchdog_map_base + 0,
+ WCR_SRS = 1 << 4, // Software Reset Signal
+ };
+
+ // Assert Software reset signal by making the bit zero
+ Io::write<Unsigned16>(Io::read<Unsigned16>(WCR) & ~WCR_SRS, WCR);
+
+ for (;;)
+ ;
+}
--- /dev/null
+// --------------------------------------------------------------------------
+INTERFACE [arm && imx]:
+
+#include "kmem.h"
+#include "irq_chip.h"
+
+EXTENSION class Timer
+{
+private:
+ enum {
+ TCTL = Kmem::Timer_map_base + 0x00,
+ TPRER = Kmem::Timer_map_base + 0x04,
+ TCMP = Kmem::Timer_map_base + 0x08,
+ TCR = Kmem::Timer_map_base + 0x0c,
+ TCN = Kmem::Timer_map_base + 0x10,
+ TSTAT = Kmem::Timer_map_base + 0x14,
+
+ TCTL_TEN = 1 << 0,
+ TCTL_CLKSOURCE_PERCLK1_TO_PRESCALER = 1 << 1,
+ TCTL_CLKSOURCE_32kHz = 1 << 3,
+ TCTL_COMP_EN = 1 << 4,
+ TCTL_SW_RESET = 1 << 15,
+ };
+private:
+ static Irq_base *irq;
+};
+
+// ----------------------------------------------------------------------
+IMPLEMENTATION [arm && imx]:
+
+#include "config.h"
+#include "kip.h"
+#include "irq_chip.h"
+#include "irq_pin.h"
+#include "io.h"
+
+#include <cstdio>
+
+Irq_base *Timer::irq;
+
+IMPLEMENT
+void Timer::init()
+{
+ Io::write<Mword>(0, TCTL); // Disable
+ Io::write<Mword>(TCTL_SW_RESET, TCTL); // reset timer
+ for (int i = 0; i < 10; ++i)
+ Io::read<Mword>(TCN); // docu says reset takes 5 cycles
+
+ Io::write<Mword>(TCTL_CLKSOURCE_32kHz | TCTL_COMP_EN, TCTL);
+ Io::write<Mword>(0, TPRER);
+ Io::write<Mword>(32, TCMP);
+
+ Irq_chip::hw_chip->reserve(Config::Scheduling_irq);
+
+ static Irq_base ib;
+ Irq_chip::hw_chip->setup(&ib, Config::Scheduling_irq);
+ irq = &ib;
+
+ Io::set<Mword>(TCTL_TEN, TCTL);
+}
+
+static inline
+Unsigned64
+Timer::timer_to_us(Unsigned32 /*cr*/)
+{ return 0; }
+
+static inline
+Unsigned64
+Timer::us_to_timer(Unsigned64 us)
+{ (void)us; return 0; }
+
+IMPLEMENT inline NEEDS["io.h"]
+void Timer::acknowledge()
+{
+ Io::write<Mword>(1, TSTAT);
+}
+
+IMPLEMENT inline NEEDS["irq_pin.h"]
+void Timer::enable()
+{
+ irq->pin()->unmask();
+}
+
+IMPLEMENT inline NEEDS["irq_pin.h"]
+void Timer::disable()
+{
+ irq->pin()->mask();
+}
+
+IMPLEMENT inline NEEDS["kip.h", "io.h", Timer::timer_to_us, Timer::us_to_timer]
+void
+Timer::update_one_shot(Unsigned64 /*wakeup*/)
+{
+}
+
+IMPLEMENT inline NEEDS["config.h", "kip.h", "io.h", Timer::timer_to_us]
+Unsigned64
+Timer::system_clock()
+{
+ if (Config::scheduler_one_shot)
+ //return Kip::k()->clock + timer_to_us(Io::read<Unsigned32>(OSCR));
+ return 0;
+ else
+ return Kip::k()->clock;
+}
+
--- /dev/null
+// --------------------------------------------------------------------------
+INTERFACE [arm && imx_epit]:
+
+#include "kmem.h"
+#include "irq_chip.h"
+
+EXTENSION class Timer
+{
+private:
+ enum {
+ EPITCR = Kmem::Timer_map_base + 0x00,
+ EPITSR = Kmem::Timer_map_base + 0x04,
+ EPITLR = Kmem::Timer_map_base + 0x08,
+ EPITCMPR = Kmem::Timer_map_base + 0x0c,
+ EPITCNR = Kmem::Timer_map_base + 0x10,
+
+ EPITCR_ENABLE = 1 << 0, // enable EPIT
+ EPITCR_ENMOD = 1 << 1, // enable mode
+ EPITCR_OCIEN = 1 << 2, // output compare irq enable
+ EPITCR_RLD = 1 << 3, // reload
+ EPITCR_SWR = 1 << 16, // software reset
+ EPITCR_CLKSRC_IPG_CLK = 1 << 24,
+ EPITCR_CLKSRC_IPG_CLK_HIGHFREQ = 2 << 24,
+ EPITCR_CLKSRC_IPG_CLK_32K = 3 << 24,
+ EPITCR_PRESCALER_SHIFT = 4,
+ EPITCR_PRESCALER_MASK = ((1 << 12) - 1) << EPITCR_PRESCALER_SHIFT,
+
+ EPITSR_OCIF = 1,
+ };
+private:
+ static Irq_base *irq;
+};
+
+// ----------------------------------------------------------------------
+IMPLEMENTATION [arm && imx_epit]:
+
+#include "config.h"
+#include "kip.h"
+#include "irq_chip.h"
+#include "irq_pin.h"
+#include "io.h"
+
+#include <cstdio>
+
+Irq_base *Timer::irq;
+
+IMPLEMENT
+void Timer::init()
+{
+ Io::write<Mword>(0, EPITCR); // Disable
+ Io::write<Mword>(EPITCR_SWR, EPITCR);
+ while (Io::read<Mword>(EPITCR) & EPITCR_SWR)
+ ;
+
+ Io::write<Mword>(EPITSR_OCIF, EPITSR);
+
+ Io::write<Mword>(EPITCR_CLKSRC_IPG_CLK_32K
+ | (0 << EPITCR_PRESCALER_SHIFT)
+ | EPITCR_RLD
+ | EPITCR_OCIEN
+ | EPITCR_ENMOD,
+ EPITCR);
+
+ Io::write<Mword>(0, EPITCMPR);
+
+ Io::write<Mword>(32, EPITLR);
+
+
+ Irq_chip::hw_chip->reserve(Config::Scheduling_irq);
+
+ static Irq_base ib;
+ Irq_chip::hw_chip->setup(&ib, Config::Scheduling_irq);
+ irq = &ib;
+
+ Io::set<Mword>(EPITCR_ENABLE, EPITCR);
+}
+
+static inline
+Unsigned64
+Timer::timer_to_us(Unsigned32 /*cr*/)
+{ return 0; }
+
+static inline
+Unsigned64
+Timer::us_to_timer(Unsigned64 us)
+{ (void)us; return 0; }
+
+IMPLEMENT inline NEEDS["io.h"]
+void Timer::acknowledge()
+{
+ Io::write<Mword>(EPITSR_OCIF, EPITSR);
+}
+
+IMPLEMENT inline NEEDS["irq_pin.h"]
+void Timer::enable()
+{
+ irq->pin()->unmask();
+}
+
+IMPLEMENT inline NEEDS["irq_pin.h"]
+void Timer::disable()
+{
+ irq->pin()->mask();
+}
+
+IMPLEMENT inline NEEDS["kip.h", "io.h", Timer::timer_to_us, Timer::us_to_timer]
+void
+Timer::update_one_shot(Unsigned64 /*wakeup*/)
+{
+}
+
+IMPLEMENT inline NEEDS["config.h", "kip.h", "io.h", Timer::timer_to_us]
+Unsigned64
+Timer::system_clock()
+{
+ if (Config::scheduler_one_shot)
+ //return Kip::k()->clock + timer_to_us(Io::read<Unsigned32>(OSCR));
+ return 0;
+ else
+ return Kip::k()->clock;
+}
+
-IMPLEMENTATION [imx]:
+IMPLEMENTATION [imx21]:
#include "arm/uart_imx.h"
IMPLEMENT L4::Uart *Uart::uart()
{
- static L4::Uart_imx uart(20, 20);
+ static L4::Uart_imx21 uart(20, 20);
+ return &uart;
+}
+
+IMPLEMENTATION [imx51]:
+
+#include "arm/uart_imx.h"
+
+IMPLEMENT L4::Uart *Uart::uart()
+{
+ static L4::Uart_imx51 uart(31, 31);
return &uart;
}
DIST_CONFIG = 0xc00,
DIST_SOFTINT = 0xf00,
+ MXC_TZIC_PRIOMASK = 0x00c,
+ MXC_TZIC_SYNCCTRL = 0x010,
+ MXC_TZIC_PND = 0xd00,
+
CPU_CTRL = 0x00,
CPU_PRIMASK = 0x04,
CPU_BPR = 0x08,
CPU_RUNINT = 0x14,
CPU_PENDING = 0x18,
+ DIST_CTRL_ENABLE = 1,
+
+ MXC_TZIC_CTRL_NSEN = 1 << 16,
+ MXC_TZIC_CTRL_NSENMASK = 1 << 31,
+
CPU_CTRL_ENABLE = 1,
CPU_CTRL_USE_FIQ_FOR_SEC = 8,
};
+
};
+// ------------------------------------------------------------------------
+INTERFACE [arm && pic_gic && pic_gic_mxc_tzic]:
+
+EXTENSION class Gic { enum { Config_mxc_tzic = 1 }; };
+
+// ------------------------------------------------------------------------
+INTERFACE [arm && pic_gic && !pic_gic_mxc_tzic]:
+
+EXTENSION class Gic { enum { Config_mxc_tzic = 0 }; };
+
+// ------------------------------------------------------------------------
+INTERFACE [arm && tz]:
+
+EXTENSION class Gic { enum { Config_tz = 1 }; };
+
+// ------------------------------------------------------------------------
+INTERFACE [arm && !tz]:
+
+EXTENSION class Gic { enum { Config_tz = 0 }; };
+
+// ------------------------------------------------------------------------
+INTERFACE [arm && pic_gic]:
+
class Gic_pin : public Irq_pin
{
public:
intmask |= intmask << 8;
intmask |= intmask << 16;
- for (unsigned i = 32; i < num; i += 16)
- Io::write<Mword>(0, _dist_base + DIST_CONFIG + i * 4 / 16);
- for (unsigned i = 32; i < num; i += 4)
- Io::write<Mword>(intmask, _dist_base + DIST_TARGET + i);
+ if (!Config_mxc_tzic)
+ {
+ for (unsigned i = 32; i < num; i += 16)
+ Io::write<Mword>(0, _dist_base + DIST_CONFIG + i * 4 / 16);
+ for (unsigned i = 32; i < num; i += 4)
+ Io::write<Mword>(intmask, _dist_base + DIST_TARGET + i);
+ }
for (unsigned i = 0; i < num; i += 4)
Io::write<Mword>(0xa0a0a0a0, _dist_base + DIST_PRI + i);
for (unsigned i = 0; i < num; i += 32)
Io::write<Mword>(0xffffffff, _dist_base + DIST_ENABLE_CLEAR + i * 4 / 32);
- Io::write<Mword>(1, _dist_base + DIST_CTRL);
+ if (Config_mxc_tzic && !Config_tz)
+ for (unsigned i = 0; i < num; i += 32)
+ Io::write<Mword>(0xffffffff, _dist_base + DIST_IRQ_SEC + i * 4 / 32);
- Io::write<Mword>(CPU_CTRL_ENABLE, _cpu_base + CPU_CTRL);
- Io::write<Mword>(0xf0, _cpu_base + CPU_PRIMASK);
+ Mword dist_enable = DIST_CTRL_ENABLE;
+ if (Config_mxc_tzic && !Config_tz)
+ dist_enable |= MXC_TZIC_CTRL_NSEN | MXC_TZIC_CTRL_NSENMASK;
+
+ Io::write<Mword>(dist_enable, _dist_base + DIST_CTRL);
+
+ if (Config_mxc_tzic)
+ {
+ Io::write<Mword>(0x0, _dist_base + MXC_TZIC_SYNCCTRL);
+ Io::write<Mword>(0xf0, _dist_base + MXC_TZIC_PRIOMASK);
+ }
+ else
+ {
+ Io::write<Mword>(CPU_CTRL_ENABLE, _cpu_base + CPU_CTRL);
+ Io::write<Mword>(0xf0, _cpu_base + CPU_PRIMASK);
+ }
//enable_tz_support();
}
PUBLIC inline NEEDS [Gic::enable_locked]
void Gic::acknowledge_locked( unsigned irq )
-{ Io::write<Mword>(irq, _cpu_base + CPU_EOI); }
+{
+ if (!Config_mxc_tzic)
+ Io::write<Mword>(irq, _cpu_base + CPU_EOI);
+}
PUBLIC
void
PUBLIC inline NEEDS["io.h"]
Unsigned32 Gic::pending()
-{ return Io::read<Mword>(_cpu_base + CPU_INTACK) & 0x3ff; }
+{
+ if (Config_mxc_tzic)
+ {
+ Address a = _dist_base + MXC_TZIC_PND;
+ for (unsigned g = 0; g < 128; g += 32, a += 4)
+ {
+ Mword v = Io::read<Mword>(a);
+ if (v)
+ return g + 31 - __builtin_clz(v);
+ }
+ return 0;
+ }
+
+ return Io::read<Mword>(_cpu_base + CPU_INTACK) & 0x3ff;
+}
//-------------------------------------------------------------------
IMPLEMENTATION [arm && mp && pic_gic]:
+// base_init() puts those Mem_region_map's on the stack which is slightly
+// larger than our warning limit, it's init code only, so it's ok
+#pragma GCC diagnostic ignored "-Wframe-larger-than="
+
IMPLEMENTATION [ia32,ux,amd64]:
#include <cstdio>
IMPLEMENTATION[ux]:
+// for our init code we do not care about the stack size
+#pragma GCC diagnostic ignored "-Wframe-larger-than="
+
#include <cassert> // for assert
#include <cerrno> // for errno
#include <climits> // for CHAR_BIT
+/*
+ * (c) 2008-2009 Technische Universität Dresden
+ * This file is part of TUD:OS and distributed under the terms of the
+ * GNU General Public License 2.
+ * Please see the COPYING-GPL-2 file for details.
+ */
#include "uart_imx.h"
namespace L4
_base = base;
// 115200Baud, 8n1
- wr(UBIR, 0x0344);
- wr(UBMR, 0x270f);
+ switch (_type)
+ {
+ case Type_imx21:
+ wr(UBIR, 0x0344);
+ wr(UBMR, 0x270f);
+ break;
+ case Type_imx51:
+ wr(UBIR, 0xf);
+ wr(UBMR, 0x120);
+ break;
+ }
wr(UCR1, UCR1_EN);
wr(UCR2, UCR2_SRST | UCR2_RXEN | UCR2_TXEN | UCR2_WS | UCR2_IRTS); // note: no IRQs enabled
+/*
+ * (c) 2008-2009 Technische Universität Dresden
+ * This file is part of TUD:OS and distributed under the terms of the
+ * GNU General Public License 2.
+ * Please see the COPYING-GPL-2 file for details.
+ */
#ifndef L4_CXX_UART_imx_H__
#define L4_CXX_UART_imx_H__
{
class Uart_imx : public Uart
{
- private:
- unsigned long _base;
-
- inline unsigned long rd(unsigned long reg) const;
- inline void wr(unsigned long reg, unsigned long val) const;
-
public:
- Uart_imx(int rx_irq, int tx_irq)
- : Uart(rx_irq, tx_irq), _base(~0UL) {}
+ enum platform_type { Type_imx21, Type_imx51 };
+ Uart_imx(int rx_irq, int tx_irq, enum platform_type type)
+ : Uart(rx_irq, tx_irq), _base(~0UL), _type(type) {}
bool startup(unsigned long base);
void shutdown();
bool enable_rx_irq(bool enable = true);
int char_avail() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count) const;
+
+ private:
+ unsigned long _base;
+ enum platform_type _type;
+
+ inline unsigned long rd(unsigned long reg) const;
+ inline void wr(unsigned long reg, unsigned long val) const;
+ };
+
+ class Uart_imx21 : public Uart_imx
+ {
+ public:
+ Uart_imx21(int rx_irq, int tx_irq)
+ : Uart_imx(rx_irq, tx_irq, Type_imx21) {}
+ };
+
+ class Uart_imx51 : public Uart_imx
+ {
+ public:
+ Uart_imx51(int rx_irq, int tx_irq)
+ : Uart_imx(rx_irq, tx_irq, Type_imx51) {}
};
};
# CONFIG_PF_INTEGRATOR is not set
# CONFIG_PF_QEMU is not set
CONFIG_BSP_NAME="imx"
+CONFIG_PF_IMX_21=y
+# CONFIG_PF_IMX_51 is not set
+CONFIG_PF_IMX_RAM_PHYS_BASE=0xc0000000
CONFIG_ABI_VF=y
CONFIG_CAN_ARM_CPU_926=y
# CONFIG_ARM_PXA is not set
--- /dev/null
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Target configuration
+#
+# CONFIG_IA32 is not set
+# CONFIG_AMD64 is not set
+CONFIG_ARM=y
+# CONFIG_PPC32 is not set
+# CONFIG_PF_PC is not set
+# CONFIG_PF_UX is not set
+# CONFIG_PF_REALVIEW is not set
+CONFIG_PF_IMX=y
+# CONFIG_PF_S3C2410 is not set
+# CONFIG_PF_TEGRA2 is not set
+# CONFIG_PF_OMAP3 is not set
+# CONFIG_PF_MPC52XX is not set
+# CONFIG_PF_XSCALE is not set
+# CONFIG_PF_SA1100 is not set
+# CONFIG_PF_INTEGRATOR is not set
+# CONFIG_PF_QEMU is not set
+CONFIG_BSP_NAME="imx"
+# CONFIG_PF_IMX_21 is not set
+CONFIG_PF_IMX_51=y
+CONFIG_PF_IMX_RAM_PHYS_BASE=0x90000000
+CONFIG_ABI_VF=y
+CONFIG_CAN_ARM_CPU_CORTEX_A8=y
+# CONFIG_ARM_PXA is not set
+# CONFIG_ARM_SA is not set
+# CONFIG_ARM_920T is not set
+# CONFIG_ARM_926 is not set
+# CONFIG_ARM_1176 is not set
+# CONFIG_ARM_MPCORE is not set
+CONFIG_ARM_CORTEX_A8=y
+# CONFIG_ARM_CORTEX_A9 is not set
+# CONFIG_IA32_486 is not set
+# CONFIG_IA32_586 is not set
+# CONFIG_IA32_686 is not set
+# CONFIG_IA32_P2 is not set
+# CONFIG_IA32_P3 is not set
+# CONFIG_IA32_P4 is not set
+# CONFIG_IA32_PM is not set
+# CONFIG_IA32_K6 is not set
+# CONFIG_IA32_K7 is not set
+# CONFIG_IA32_K8 is not set
+# CONFIG_AMD64_K8 is not set
+# CONFIG_PPC32_603e is not set
+# CONFIG_ARM_ALIGNMENT_CHECK is not set
+# CONFIG_FPU is not set
+
+#
+# Kernel options
+#
+CONFIG_CONTEXT_4K=y
+# CONFIG_FINE_GRAINED_CPUTIME is not set
+CONFIG_SCHED_FIXED_PRIO=y
+# CONFIG_SCHED_WFQ is not set
+# CONFIG_SCHED_FP_WFQ is not set
+
+#
+# Debugging
+#
+CONFIG_INLINE=y
+# CONFIG_NDEBUG is not set
+# CONFIG_NO_FRAME_PTR is not set
+# CONFIG_STACK_DEPTH is not set
+# CONFIG_LIST_ALLOC_SANITY is not set
+CONFIG_SERIAL=y
+CONFIG_JDB=y
+# CONFIG_JDB_LOGGING is not set
+# CONFIG_JDB_DISASM is not set
+# CONFIG_JDB_GZIP is not set
+# CONFIG_VMEM_ALLOC_TEST is not set
+# CONFIG_DEBUG_KERNEL_PAGE_FAULTS is not set
+# CONFIG_WARN_NONE is not set
+CONFIG_WARN_WARNING=y
+# CONFIG_WARN_ANY is not set
+
+#
+# Compiling
+#
+CONFIG_CC="gcc"
+CONFIG_CXX="g++"
+CONFIG_HOST_CC="gcc"
+CONFIG_HOST_CXX="g++"
+# CONFIG_VERBOSE is not set
+# CONFIG_MAINTAINER_MODE is not set
+CONFIG_LABEL=""
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_PERF_CNT=y
+CONFIG_BIT32=y
+CONFIG_ARM_V7=y
+CONFIG_ARM_V6PLUS=y
+CONFIG_WARN_LEVEL=1
+CONFIG_XARCH="arm"
+CONFIG_ABI="vf"
SUPPORT_CC_arm-beagleboard:= support_beagleboard.cc
SUPPORT_CC_arm-tegra2 := support_tegra2.cc
SUPPORT_CC_arm-imx21 := support_imx.cc
+SUPPORT_CC_arm-imx51 := support_imx.cc
SUPPORT_CC_arm-om := support_om.cc
DEFAULT_RELOC_arm-imx21 := 0x00200000 # because of blob
DEFINES += -DRAM_BASE=$(RAM_BASE)
DEFINES += -DCMDLINE="\"$(BOOTSTRAP_CMDLINE)\""
DEFINES += -DPLATFORM_TYPE=\"$(PLATFORM_TYPE)\"
+DEFINES += -DPLATFORM_TYPE_$(PLATFORM_TYPE)
MOD_ADDR = 0x02000000
# we need to re-do if some things change
# we do not need to track BOOTSTRACE_CMDLINE as it's only used in startup.cc
# and that is regenerated every time
-REDO_TEXT_CMD = echo "$(ENTRY) '$(COMPRESS)' '$(PLATFORM_TYPE)'"
+REDO_TEXT_CMD = echo "$(ENTRY) '$(COMPRESS)' '$(RAM_SIZE_MB)' '$(PLATFORM_TYPE)'"
.redo-change-tracker: FORCE
$(VERBOSE)if test ! -r "$@" || \
! $(REDO_TEXT_CMD) | cmp -s "$@"; then \
Local customization:
- You can put a Makeconf.local file right into this directory where you
- can specify your own search paths etc. Something like this:
+ You can put a Makeconf.local file right into this directory
+ (bootstrap/server/src) where you can specify your own search paths etc.
+ Note that it is encouraged to have your local configuration in src/conf
+ rather than in this bootstrap directory.
+
+ Makeconf.local could look like this:
BOOTSTRAP_SEARCH_PATH_x86 := ../stuff:/home/joe/dev/l4/kernel/fiasco/build-ia32
void init()
{
- static L4::Uart_imx _uart(20, 20);
+#ifdef PLATFORM_TYPE_imx21
+ static L4::Uart_imx21 _uart(0, 0);
_uart.startup(0x1000A000);
+#elif defined(PLATFORM_TYPE_imx51)
+ static L4::Uart_imx51 _uart(0, 0);
+ _uart.startup(0x73fbc000);
+#else
+#error Which platform type?
+#endif
set_stdio_uart(&_uart);
}
};
{
class Uart_imx : public Uart
{
- private:
- unsigned long _base;
-
- inline unsigned long rd(unsigned long reg) const;
- inline void wr(unsigned long reg, unsigned long val) const;
-
public:
- Uart_imx(int rx_irq, int tx_irq)
- : Uart(rx_irq, tx_irq), _base(~0UL) {}
+ enum platform_type { Type_imx21, Type_imx51 };
+ Uart_imx(int rx_irq, int tx_irq, enum platform_type type)
+ : Uart(rx_irq, tx_irq), _base(~0UL), _type(type) {}
bool startup(unsigned long base);
void shutdown();
bool enable_rx_irq(bool enable = true);
int char_avail() const;
inline void out_char(char c) const;
int write(char const *s, unsigned long count) const;
+
+ private:
+ unsigned long _base;
+ enum platform_type _type;
+
+ inline unsigned long rd(unsigned long reg) const;
+ inline void wr(unsigned long reg, unsigned long val) const;
+ };
+
+ class Uart_imx21 : public Uart_imx
+ {
+ public:
+ Uart_imx21(int rx_irq, int tx_irq)
+ : Uart_imx(rx_irq, tx_irq, Type_imx21) {}
+ };
+
+ class Uart_imx51 : public Uart_imx
+ {
+ public:
+ Uart_imx51(int rx_irq, int tx_irq)
+ : Uart_imx(rx_irq, tx_irq, Type_imx51) {}
};
};
_base = base;
// 115200Baud, 8n1
- wr(UBIR, 0x0344);
- wr(UBMR, 0x270f);
+ switch (_type)
+ {
+ case Type_imx21:
+ wr(UBIR, 0x0344);
+ wr(UBMR, 0x270f);
+ break;
+ case Type_imx51:
+ wr(UBIR, 0xf);
+ wr(UBMR, 0x120);
+ break;
+ }
wr(UCR1, UCR1_EN);
wr(UCR2, UCR2_SRST | UCR2_RXEN | UCR2_TXEN | UCR2_WS | UCR2_IRTS); // note: no IRQs enabled