OSDN Git Service

* public snapshot of sid simulator
[pf3gnuchains/pf3gnuchains3x.git] / sid / component / interrupt / arm.cxx
1 // arm.cxx - An implementation of the interrupt controller from the
2 // ARM PID7T development board.  -*- C++ -*-
3
4 // Copyright (C) 1999, 2000 Red Hat.
5 // This file is part of SID and is licensed under the GPL.
6 // See the file COPYING.SID for conditions for redistribution.
7
8 // A more thorough description of this component may be found at
9 // <http://www.arm.com/Documentation/UserMans/rps/#int>.
10
11 #include "config.h"
12 #include "tconfig.h"
13 #include "components.h"
14
15 #include "arm.h"
16
17 #if SIDTARGET_ARM
18
19 void
20 armIntController::irq_src_driven(host_int_4 val, host_int_4 bit_num)
21 {
22   if (val)
23     irq_pending |= 1 << bit_num;
24   else
25     irq_pending &= ~(1 << bit_num);
26
27   drive_irq_interrupts();
28 }
29
30 void
31 armIntController::fiq_src_driven(host_int_4 val, host_int_4 bit_num)
32 {
33   fiq_pending = (val > 0) ? 1 : 0;
34
35   drive_fiq_interrupts();
36 }
37
38 sid::bus::status
39 armIntController::irq_read_word(host_int_4 addr,
40                                 little_int_4 mask,
41                                 little_int_4& le_data)
42 {
43   host_int_4 data;
44
45   switch (addr) {
46   case 0:
47     // IRQStatus.
48     data = irq_pending & irq_enabled;
49     break;
50   case 1:
51     // IRQRawStatus.
52     data = irq_pending;
53     break;
54   case 2:
55     // IRQEnable.
56     data = irq_enabled;
57     break;
58   case 3:       // Reserved.
59   case 4:
60     return bus::unpermitted;
61   default:
62     return bus::unmapped;
63   } 
64   le_data = data;
65   return bus::ok;
66 }
67
68 sid::bus::status
69 armIntController::fiq_read_word(host_int_4 addr,
70                                 little_int_4 mask,
71                                 little_int_4& le_data)
72 {
73   host_int_4 data;
74
75   switch (addr) {
76   case 0:
77     // FIQStatus.
78     data = fiq_pending && fiq_enabled;
79     break;
80   case 1:
81     // FIQRawStatus.
82     data = fiq_pending;
83     break;
84   case 2:
85     // FIQEnable.
86     data = fiq_enabled;
87     break;
88   case 3:       // Reserved.
89     return bus::unpermitted;
90   default:
91     return bus::unmapped;
92   } 
93   le_data = data;
94   return bus::ok;
95 }
96
97 sid::bus::status
98 armIntController::irq_write_word(host_int_4 addr,
99                                  little_int_4 mask,
100                                  little_int_4 le_data)
101 {
102   host_int_4 data = le_data;
103
104   switch (addr) {
105   case 2:
106     // IRQEnableSet.
107     irq_enabled |= data;
108     break;
109   case 3:
110     // IRQEnableClear.
111     irq_enabled &= ~data;
112     break;
113   case 4:
114     // IRQSoft.
115     if (data & 2)
116       {
117         // Bit 1 set.
118         irq_pending |= 2;
119       }
120     else
121       {
122         // Bit 1 clear.
123         irq_pending &= ~2;
124       }
125       break;
126   case 0:  // Reserved.
127   case 1:
128     return bus::unpermitted;
129   default:
130     return bus::unmapped;
131   }
132   // Some pending interrupts may now be enabled.
133   // Some may also now be disabled.  Re-check.
134   drive_interrupts();
135   return bus::ok;
136 }
137
138 sid::bus::status
139 armIntController::fiq_write_word(host_int_4 addr,
140                                  little_int_4 mask,
141                                  little_int_4 le_data)
142 {
143   host_int_4 data = le_data;
144
145   switch (addr) {
146   case 2:
147    // FIQEnableSet.
148     fiq_enabled |= data;
149     break;
150   case 3:
151     fiq_enabled &= ~data;
152     break;
153   case 0:       // Reserved.
154   case 1:
155     return bus::unpermitted;
156   default:
157     return bus::unmapped;
158   }
159   // Some pending interrupts may now be enabled.
160   // Some may also now be disabled.  Re-check.
161   drive_interrupts();
162   return bus::ok;
163 }
164
165 #endif // SIDTARGET_ARM