]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/arm/bsp/imx/pic-arm-imx.cpp
b71b04dc2f7cbee6ffbc7a7afd7fee1014a908ca
[l4.git] / kernel / fiasco / src / kern / arm / bsp / imx / pic-arm-imx.cpp
1 // ---------------------------------------------------------------------
2 INTERFACE [arm && (imx21 || imx35)]:
3
4 #include "kmem.h"
5
6 class Irq_base;
7
8 EXTENSION class Pic
9 {
10 public:
11   enum
12   {
13     INTCTL      = Kmem::Pic_map_base + 0x00,
14     NIMASK      = Kmem::Pic_map_base + 0x04,
15     INTENNUM    = Kmem::Pic_map_base + 0x08,
16     INTDISNUM   = Kmem::Pic_map_base + 0x0c,
17     INTENABLEH  = Kmem::Pic_map_base + 0x10,
18     INTENABLEL  = Kmem::Pic_map_base + 0x14,
19     INTTYPEH    = Kmem::Pic_map_base + 0x18,
20     INTTYPEL    = Kmem::Pic_map_base + 0x1c,
21     NIPRIORITY7 = Kmem::Pic_map_base + 0x20,
22     NIPRIORITY0 = Kmem::Pic_map_base + 0x3c,
23     NIVECSR     = Kmem::Pic_map_base + 0x40,
24     FIVECSR     = Kmem::Pic_map_base + 0x44,
25     INTSRCH     = Kmem::Pic_map_base + 0x48,
26     INTSRCL     = Kmem::Pic_map_base + 0x4c,
27     INTFRCH     = Kmem::Pic_map_base + 0x50,
28     INTFRCL     = Kmem::Pic_map_base + 0x54,
29     NIPNDH      = Kmem::Pic_map_base + 0x58,
30     NIPNDL      = Kmem::Pic_map_base + 0x5c,
31     FIPNDH      = Kmem::Pic_map_base + 0x60,
32     FIPNDL      = Kmem::Pic_map_base + 0x64,
33
34
35     INTCTL_FIAD  = 1 << 19, // Fast Interrupt Arbiter Rise ARM Level
36     INTCTL_NIAD  = 1 << 20, // Normal Interrupt Arbiter Rise ARM Level
37     INTCTL_FIDIS = 1 << 21, // Fast Interrupt Disable
38     INTCTL_NIDIS = 1 << 22, // Normal Interrupt Disable
39   };
40 };
41
42 // ---------------------------------------------------------------------
43 IMPLEMENTATION [arm && (imx21 || imx35)]:
44
45 #include "io.h"
46 #include "irq_chip_generic.h"
47 #include "irq_mgr.h"
48
49 class Irq_chip_arm_imx : public Irq_chip_gen
50 {
51 public:
52   Irq_chip_arm_imx() : Irq_chip_gen(64) {}
53   unsigned set_mode(Mword, unsigned) { return Irq_base::Trigger_level; }
54   void set_cpu(Mword, unsigned) {}
55   void ack(Mword) { /* ack is empty */ }
56 };
57
58 PUBLIC
59 void
60 Irq_chip_arm_imx::mask(Mword irq)
61 {
62   assert(cpu_lock.test());
63   Io::write<Mword>(irq, Pic::INTDISNUM); // disable pin
64 }
65
66 PUBLIC
67 void
68 Irq_chip_arm_imx::mask_and_ack(Mword irq)
69 {
70   assert(cpu_lock.test());
71   Io::write<Mword>(irq, Pic::INTDISNUM); // disable pin
72   // ack is empty
73 }
74
75 PUBLIC
76 void
77 Irq_chip_arm_imx::unmask(Mword irq)
78 {
79   assert (cpu_lock.test());
80   Io::write<Mword>(irq, Pic::INTENNUM);
81 }
82
83 static Static_object<Irq_mgr_single_chip<Irq_chip_arm_imx> > mgr;
84
85
86 IMPLEMENT FIASCO_INIT
87 void Pic::init()
88 {
89   Irq_mgr::mgr = mgr.construct();
90
91   Io::write<Mword>(0,    INTCTL);
92   Io::write<Mword>(0x10, NIMASK); // Do not disable any normal interrupts
93
94   Io::write<Mword>(0, INTTYPEH); // All interrupts generate normal interrupts
95   Io::write<Mword>(0, INTTYPEL);
96
97   // Init interrupt priorities
98   for (int i = 0; i < 8; ++i)
99     Io::write<Mword>(0x1111, NIPRIORITY7 + (i * 4)); // low addresses start with 7
100 }
101
102 IMPLEMENT inline
103 Pic::Status Pic::disable_all_save()
104 {
105   Status s = 0;
106   return s;
107 }
108
109 IMPLEMENT inline
110 void Pic::restore_all(Status)
111 {}
112
113 PUBLIC static inline NEEDS["io.h"]
114 Unsigned32 Irq_chip_arm_imx::pending()
115 {
116   return Io::read<Mword>(Pic::NIVECSR) >> 16;
117 }
118
119 PUBLIC inline NEEDS[Irq_chip_arm_imx::pending]
120 void
121 Irq_chip_arm_imx::irq_handler()
122 {
123   Unsigned32 p = pending();
124   if (EXPECT_TRUE(p != 0xffff))
125     handle_irq<Irq_chip_arm_imx>(p, 0);
126 }
127
128 extern "C"
129 void irq_handler()
130 { mgr->c.irq_handler(); }
131
132 //---------------------------------------------------------------------------
133 IMPLEMENTATION [debug && imx]:
134
135 PUBLIC
136 char const *
137 Irq_chip_arm_imx::chip_type() const
138 { return "HW i.MX IRQ"; }