]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/arm/bsp/kirkwood/pic-arm-kirkwood.cpp
3ce543265ae28988bf6e2f36fadaf4cf9985df8f
[l4.git] / kernel / fiasco / src / kern / arm / bsp / kirkwood / pic-arm-kirkwood.cpp
1 INTERFACE [arm && kirkwood]:
2
3 #include "kmem.h"
4
5 class Irq_base;
6
7 EXTENSION class Pic
8 {
9 public:
10   enum
11   {
12     Main_Irq_cause_low_reg     = Mem_layout::Pic_map_base + 0x20200,
13     Main_Irq_mask_low_reg      = Mem_layout::Pic_map_base + 0x20204,
14     Main_Fiq_mask_low_reg      = Mem_layout::Pic_map_base + 0x20208,
15     Endpoint_irq_mask_low_reg  = Mem_layout::Pic_map_base + 0x2020c,
16     Main_Irq_cause_high_reg    = Mem_layout::Pic_map_base + 0x20210,
17     Main_Irq_mask_high_reg     = Mem_layout::Pic_map_base + 0x20214,
18     Main_Fiq_mask_high_reg     = Mem_layout::Pic_map_base + 0x20218,
19     Endpoint_irq_mask_high_reg = Mem_layout::Pic_map_base + 0x2021c,
20
21     Bridge_int_num = 1,
22   };
23 };
24
25 //-------------------------------------------------------------------
26 IMPLEMENTATION [arm && kirkwood]:
27
28 #include "config.h"
29 #include "initcalls.h"
30 #include "io.h"
31 #include "irq_chip_generic.h"
32 #include "irq_mgr.h"
33
34 class Irq_chip_kirkwood : public Irq_chip_gen
35 {
36 public:
37   Irq_chip_kirkwood() : Irq_chip_gen(64) {}
38   unsigned set_mode(Mword, unsigned) { return Irq_base::Trigger_level; }
39   void set_cpu(Mword, unsigned) {}
40   void ack(Mword) { /* ack is empty */ }
41 };
42
43 PUBLIC
44 void
45 Irq_chip_kirkwood::mask(Mword irq)
46 {
47   assert (cpu_lock.test());
48   Io::clear<Unsigned32>(1 << (irq & 0x1f),
49                         Pic::Main_Irq_mask_low_reg + ((irq & 0x20) >> 1));
50 }
51
52 PUBLIC
53 void
54 Irq_chip_kirkwood::mask_and_ack(Mword irq)
55 {
56   assert(cpu_lock.test());
57   mask(irq);
58   // ack is empty
59 }
60
61 PUBLIC
62 void
63 Irq_chip_kirkwood::unmask(Mword irq)
64 {
65   assert(cpu_lock.test());
66   Io::set<Unsigned32>(1 << (irq & 0x1f),
67                       Pic::Main_Irq_mask_low_reg + ((irq & 0x20) >> 1));
68 }
69
70 static Static_object<Irq_mgr_single_chip<Irq_chip_kirkwood> > mgr;
71
72 IMPLEMENT FIASCO_INIT
73 void Pic::init()
74 {
75   Irq_mgr::mgr = mgr.construct();
76
77   // Disable all interrupts
78   Io::write<Unsigned32>(0U, Main_Irq_mask_low_reg);
79   Io::write<Unsigned32>(0U, Main_Fiq_mask_low_reg);
80   Io::write<Unsigned32>(0U, Main_Irq_mask_high_reg);
81   Io::write<Unsigned32>(0U, Main_Fiq_mask_high_reg);
82
83   // enable bridge (chain) IRQ
84   Io::set<Unsigned32>(1 << Bridge_int_num, Main_Irq_mask_low_reg);
85 }
86
87 IMPLEMENT inline
88 Pic::Status Pic::disable_all_save()
89 { return 0; }
90
91 IMPLEMENT inline
92 void Pic::restore_all(Status)
93 {}
94
95 PUBLIC static inline NEEDS["io.h"]
96 Unsigned32 Irq_chip_kirkwood::pending()
97 {
98   Unsigned32 v;
99
100   v = Io::read<Unsigned32>(Pic::Main_Irq_cause_low_reg);
101   if (v & 1)
102     {
103       v = Io::read<Unsigned32>(Pic::Main_Irq_cause_high_reg);
104       for (int i = 1; i < 32; ++i)
105         if ((1 << i) & v)
106           return 32 + i;
107     }
108   for (int i = 1; i < 32; ++i)
109     if ((1 << i) & v)
110       return i;
111
112   return 64;
113 }
114
115 extern "C"
116 void irq_handler()
117 {
118   Unsigned32 i;
119   while ((i = Irq_chip_kirkwood::pending()) < 64)
120     mgr->c.handle_irq<Irq_chip_kirkwood>(i, 0);
121 }
122
123 //---------------------------------------------------------------------------
124 IMPLEMENTATION [debug && kirkwood]:
125
126 PUBLIC
127 char const *
128 Irq_chip_kirkwood::chip_type() const
129 { return "HW Kirkwood IRQ"; }