]> rtime.felk.cvut.cz Git - l4.git/commitdiff
update
authorl4check <l4check@d050ee49-bd90-4346-b210-929a50b99cfc>
Mon, 14 Jun 2010 15:23:40 +0000 (15:23 +0000)
committerl4check <l4check@d050ee49-bd90-4346-b210-929a50b99cfc>
Mon, 14 Jun 2010 15:23:40 +0000 (15:23 +0000)
git-svn-id: http://svn.tudos.org/repos/oc/tudos/trunk@7 d050ee49-bd90-4346-b210-929a50b99cfc

25 files changed:
kernel/fiasco/src/Makeconf
kernel/fiasco/src/kern/arm/bsp/imx/Kconfig
kernel/fiasco/src/kern/arm/bsp/imx/Modules
kernel/fiasco/src/kern/arm/bsp/imx/bootstrap-arm-imx.cpp
kernel/fiasco/src/kern/arm/bsp/imx/config-arm-imx.cpp
kernel/fiasco/src/kern/arm/bsp/imx/kernel_uart-arm-imx.cpp
kernel/fiasco/src/kern/arm/bsp/imx/mem_layout-arm-imx.cpp
kernel/fiasco/src/kern/arm/bsp/imx/pic-arm-imx21.cpp [new file with mode: 0644]
kernel/fiasco/src/kern/arm/bsp/imx/pic-arm-imx51.cpp [new file with mode: 0644]
kernel/fiasco/src/kern/arm/bsp/imx/reset-arm-imx.cpp
kernel/fiasco/src/kern/arm/bsp/imx/timer-arm-imx21.cpp [new file with mode: 0644]
kernel/fiasco/src/kern/arm/bsp/imx/timer-arm-imx_epit.cpp [new file with mode: 0644]
kernel/fiasco/src/kern/arm/bsp/imx/uart-imx.cpp
kernel/fiasco/src/kern/arm/gic.cpp
kernel/fiasco/src/kern/ia32/kmem_alloc-ia32.cpp
kernel/fiasco/src/kern/ux/boot_info-ux.cpp
kernel/fiasco/src/lib/uart/arm/uart_imx.cc
kernel/fiasco/src/lib/uart/arm/uart_imx.h
kernel/fiasco/src/templates/globalconfig.out.arm-imx21
kernel/fiasco/src/templates/globalconfig.out.arm-imx51 [new file with mode: 0644]
l4/pkg/bootstrap/server/src/Make.rules
l4/pkg/bootstrap/server/src/README
l4/pkg/bootstrap/server/src/support_imx.cc
l4/pkg/drivers/uart/include/uart_imx.h
l4/pkg/drivers/uart/src/uart_imx.cc

index cd277a9b5b13dfbd0792d70d4b1efb1883cd7c2d..4f9dd0c305f27c094ad5e41a35a458dcc487ae48 100644 (file)
@@ -105,6 +105,7 @@ SHARED_FLAGS                += -Wno-parentheses
 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,)
index 7fcc3c9f1c48699f667092f854dba4866e97b3f0..efc240338ccf8f555a6e18255ba45acbaa8e2fe7 100644 (file)
@@ -1,4 +1,28 @@
 # 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
index d899591d052864c024aecc7917efdf4defa02ca8..3138232f1bbe6d6d32781f28f456b41080e68584 100644 (file)
@@ -2,16 +2,24 @@
 
 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
index 66e2ca6115ba86830a1bfb9c0b45556983b51e14..40d38bed465e161afa8e213a87d1a3c4374ba8d4 100644 (file)
@@ -6,10 +6,19 @@ enum {
 };
 
 //-----------------------------------------------------------------------------
-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);
+}
index 1e2d39030bcbf2e7087e1bafc1848198df4cbb72..5e5cbc316b48ad1af6946be35bf155805c7312d8 100644 (file)
@@ -1,6 +1,6 @@
-INTERFACE [arm && imx]:
+INTERFACE [arm && imx21]:
 
-#define TARGET_NAME "i.MX"
+#define TARGET_NAME "i.MX21"
 
 EXTENSION class Config
 {
@@ -16,3 +16,21 @@ public:
   };
 };
 
+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,
+  };
+};
+
index 9ab4a9269de763b93f343a2433e772e9570c27ee..9ea1ffd74d81fb50975d8099d5634e2d5cc1aaf2 100644 (file)
@@ -1,4 +1,4 @@
-IMPLEMENTATION [arm && imx && serial]:
+IMPLEMENTATION [arm && imx21 && serial]:
 
 #include "mem_layout.h"
 
@@ -8,3 +8,14 @@ bool Kernel_uart::startup(unsigned port, int /*irq*/)
   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);
+}
index 10e60fa72447fd1fed5eda13e724f93d4f7eff3c..7e7ace0a4bbf16844ad64ee8a0966293710ee60b 100644 (file)
@@ -5,6 +5,21 @@ EXTENSION class Mem_layout
 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,
@@ -13,15 +28,37 @@ public:
     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,
+  };
+};
diff --git a/kernel/fiasco/src/kern/arm/bsp/imx/pic-arm-imx21.cpp b/kernel/fiasco/src/kern/arm/bsp/imx/pic-arm-imx21.cpp
new file mode 100644 (file)
index 0000000..a0d044b
--- /dev/null
@@ -0,0 +1,193 @@
+// ---------------------------------------------------------------------
+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"; }
+
diff --git a/kernel/fiasco/src/kern/arm/bsp/imx/pic-arm-imx51.cpp b/kernel/fiasco/src/kern/arm/bsp/imx/pic-arm-imx51.cpp
new file mode 100644 (file)
index 0000000..316a6af
--- /dev/null
@@ -0,0 +1,79 @@
+// ---------------------------------------------------------------------
+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;
+}
index 60d20767bafcb9ac3cf20678e257397afd835ef9..67aea5d10ba894f4c8e3792751b1529c17355fd0 100644 (file)
@@ -1,4 +1,4 @@
-IMPLEMENTATION [arm && imx]:
+IMPLEMENTATION [arm && imx21]:
 
 #include "io.h"
 #include "kmem.h"
@@ -7,7 +7,7 @@ void __attribute__ ((noreturn))
 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,
@@ -23,3 +23,24 @@ pc_reset(void)
   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 (;;)
+    ;
+}
diff --git a/kernel/fiasco/src/kern/arm/bsp/imx/timer-arm-imx21.cpp b/kernel/fiasco/src/kern/arm/bsp/imx/timer-arm-imx21.cpp
new file mode 100644 (file)
index 0000000..ac20ba1
--- /dev/null
@@ -0,0 +1,106 @@
+// --------------------------------------------------------------------------
+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;
+}
+
diff --git a/kernel/fiasco/src/kern/arm/bsp/imx/timer-arm-imx_epit.cpp b/kernel/fiasco/src/kern/arm/bsp/imx/timer-arm-imx_epit.cpp
new file mode 100644 (file)
index 0000000..1f45546
--- /dev/null
@@ -0,0 +1,122 @@
+// --------------------------------------------------------------------------
+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;
+}
+
index f8f7020bb1d315b9f790ca8a6f61ace901e5435c..eafffbc2f78c2e63b9bbb906ea1539d988cda0ea 100644 (file)
@@ -1,9 +1,19 @@
-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;
 }
index a2a87d79948093d3541b9bc7aa5d8c35657a3743..aaa7dbddb84230c7e7dd3f30b570ab8e18d9ad6d 100644 (file)
@@ -23,6 +23,10 @@ private:
     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,
@@ -31,11 +35,40 @@ private:
     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:
@@ -124,19 +157,38 @@ Gic::init(Address cpu_base, Address dist_base)
   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();
 }
@@ -151,7 +203,10 @@ void Gic::enable_locked(unsigned irq, unsigned /*prio*/)
 
 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
@@ -251,7 +306,21 @@ Gic_pin::set_cpu(unsigned)
 
 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]:
index 657ee62e2fe313256475cdeb1868aecf92e71c06..637b031b1e6a7d30329b89c0d6144b5b2b269b4e 100644 (file)
@@ -1,3 +1,7 @@
+// 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>
index 84e93ac4d77d41db25c1fed56a6bd41aacfa76ef..4c47a668fb4a7cf8562d2a2c0d6114cced7dd048 100644 (file)
@@ -44,6 +44,9 @@ private:
 
 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
index c6ee9e7bf3a1e45640ddf0d8bb5345571b5aef52..cd1a88b292acd2a7d7a37df15ebd8b97383293f6 100644 (file)
@@ -1,3 +1,9 @@
+/*
+ * (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
@@ -84,8 +90,17 @@ 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
index dba0eedbd02160b57eaa2abc6bb06f94fcc06de9..b5e594fce43672205a43e6190dc8b589b34284f3 100644 (file)
@@ -1,3 +1,9 @@
+/*
+ * (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__
 
@@ -7,15 +13,10 @@ namespace L4
 {
   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);
@@ -25,6 +26,27 @@ namespace L4
     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) {}
   };
 };
 
index 95e547a3242554846dcde62fb027049969a04e2a..0f88f6b23179230f9a6624b1b9453d6983186b39 100644 (file)
@@ -22,6 +22,9 @@ CONFIG_PF_IMX=y
 # 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
diff --git a/kernel/fiasco/src/templates/globalconfig.out.arm-imx51 b/kernel/fiasco/src/templates/globalconfig.out.arm-imx51
new file mode 100644 (file)
index 0000000..b0f2f13
--- /dev/null
@@ -0,0 +1,98 @@
+#
+# 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"
index 2d6b47980264c90f6e6722b143bfcf62fb11eea4..9264c013f67041ea2ef2cd637cc4a2e74acb28fd 100644 (file)
@@ -74,6 +74,7 @@ SUPPORT_CC_arm-omap3evm   := support_omap3evm.cc
 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
 
@@ -106,6 +107,7 @@ OPTS                 = -g -Os $(CARCHFLAGS_$(ARCH)) $(CARCHFLAGS_$(ARCH)_$(CPU))
 DEFINES         += -DRAM_BASE=$(RAM_BASE)
 DEFINES         += -DCMDLINE="\"$(BOOTSTRAP_CMDLINE)\""
 DEFINES         += -DPLATFORM_TYPE=\"$(PLATFORM_TYPE)\"
+DEFINES         += -DPLATFORM_TYPE_$(PLATFORM_TYPE)
 
 MOD_ADDR         = 0x02000000
 
@@ -151,7 +153,7 @@ ENTRY_FN := $(shell echo "$(ENTRY)" | tr '[ ]' '[_]' )
 # 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 \
index 7cb9f19b80f3be5cd000d8ff8731d28fdfde3677..afef5a585ab64798c41792a0d5de950a52e5f1b0 100644 (file)
@@ -47,8 +47,12 @@ Generating bootstrap in single-image-mode:
 
 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
 
index 989e4feb086a696c9636d1b0af92d81cc131cb37..e55fd4d419adeb066cfb044dc8e1e0f660d624b4 100644 (file)
@@ -23,8 +23,15 @@ class Platform_arm_imx : public Platform_single_region_ram
 
   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);
   }
 };
index bb188f2f97b612d5175c970817a9aca7e6b6f286..b5e594fce43672205a43e6190dc8b589b34284f3 100644 (file)
@@ -13,15 +13,10 @@ namespace L4
 {
   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);
@@ -31,6 +26,27 @@ namespace L4
     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) {}
   };
 };
 
index 45cc52c5427891fdb5439530c5ae0055d9329e15..cd1a88b292acd2a7d7a37df15ebd8b97383293f6 100644 (file)
@@ -90,8 +90,17 @@ 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