ia64/xen-unstable

view tools/ioemu/hw/sched.c @ 6946:e703abaf6e3d

Add behaviour to the remove methods to remove the transaction's path itself. This allows us to write Remove(path) to remove the specified path rather than having to slice the path ourselves.
author emellor@ewan
date Sun Sep 18 14:42:13 2005 +0100 (2005-09-18)
parents 8e5fc5fe636c
children
line source
1 /*
2 * QEMU interrupt controller emulation
3 *
4 * Copyright (c) 2003-2004 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 #include "vl.h"
25 //#define DEBUG_IRQ_COUNT
27 /* These registers are used for sending/receiving irqs from/to
28 * different cpu's.
29 */
30 struct sun4m_intreg_percpu {
31 unsigned int tbt; /* Intrs pending for this cpu, by PIL. */
32 /* These next two registers are WRITE-ONLY and are only
33 * "on bit" sensitive, "off bits" written have NO affect.
34 */
35 unsigned int clear; /* Clear this cpus irqs here. */
36 unsigned int set; /* Set this cpus irqs here. */
37 };
38 /*
39 * djhr
40 * Actually the clear and set fields in this struct are misleading..
41 * according to the SLAVIO manual (and the same applies for the SEC)
42 * the clear field clears bits in the mask which will ENABLE that IRQ
43 * the set field sets bits in the mask to DISABLE the IRQ.
44 *
45 * Also the undirected_xx address in the SLAVIO is defined as
46 * RESERVED and write only..
47 *
48 * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor
49 * sun4m machines, for MP the layout makes more sense.
50 */
51 struct sun4m_intreg_master {
52 unsigned int tbt; /* IRQ's that are pending, see sun4m masks. */
53 unsigned int irqs; /* Master IRQ bits. */
55 /* Again, like the above, two these registers are WRITE-ONLY. */
56 unsigned int clear; /* Clear master IRQ's by setting bits here. */
57 unsigned int set; /* Set master IRQ's by setting bits here. */
59 /* This register is both READ and WRITE. */
60 unsigned int undirected_target; /* Which cpu gets undirected irqs. */
61 };
63 #define SUN4M_INT_ENABLE 0x80000000
64 #define SUN4M_INT_E14 0x00000080
65 #define SUN4M_INT_E10 0x00080000
67 #define SUN4M_HARD_INT(x) (0x000000001 << (x))
68 #define SUN4M_SOFT_INT(x) (0x000010000 << (x))
70 #define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */
71 #define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */
72 #define SUN4M_INT_M2S_WRITE 0x20000000 /* write buffer error */
73 #define SUN4M_INT_ECC 0x10000000 /* ecc memory error */
74 #define SUN4M_INT_FLOPPY 0x00400000 /* floppy disk */
75 #define SUN4M_INT_MODULE 0x00200000 /* module interrupt */
76 #define SUN4M_INT_VIDEO 0x00100000 /* onboard video */
77 #define SUN4M_INT_REALTIME 0x00080000 /* system timer */
78 #define SUN4M_INT_SCSI 0x00040000 /* onboard scsi */
79 #define SUN4M_INT_AUDIO 0x00020000 /* audio/isdn */
80 #define SUN4M_INT_ETHERNET 0x00010000 /* onboard ethernet */
81 #define SUN4M_INT_SERIAL 0x00008000 /* serial ports */
82 #define SUN4M_INT_SBUSBITS 0x00003F80 /* sbus int bits */
84 #define SUN4M_INT_SBUS(x) (1 << (x+7))
85 #define SUN4M_INT_VME(x) (1 << (x))
87 typedef struct SCHEDState {
88 uint32_t addr, addrg;
89 uint32_t intreg_pending;
90 uint32_t intreg_enabled;
91 uint32_t intregm_pending;
92 uint32_t intregm_enabled;
93 } SCHEDState;
95 static SCHEDState *ps;
97 #ifdef DEBUG_IRQ_COUNT
98 static uint64_t irq_count[32];
99 #endif
101 static uint32_t intreg_mem_readl(void *opaque, target_phys_addr_t addr)
102 {
103 SCHEDState *s = opaque;
104 uint32_t saddr;
106 saddr = (addr - s->addr) >> 2;
107 switch (saddr) {
108 case 0:
109 return s->intreg_pending;
110 break;
111 default:
112 break;
113 }
114 return 0;
115 }
117 static void intreg_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
118 {
119 SCHEDState *s = opaque;
120 uint32_t saddr;
122 saddr = (addr - s->addr) >> 2;
123 switch (saddr) {
124 case 0:
125 s->intreg_pending = val;
126 break;
127 case 1: // clear
128 s->intreg_enabled &= ~val;
129 break;
130 case 2: // set
131 s->intreg_enabled |= val;
132 break;
133 default:
134 break;
135 }
136 }
138 static CPUReadMemoryFunc *intreg_mem_read[3] = {
139 intreg_mem_readl,
140 intreg_mem_readl,
141 intreg_mem_readl,
142 };
144 static CPUWriteMemoryFunc *intreg_mem_write[3] = {
145 intreg_mem_writel,
146 intreg_mem_writel,
147 intreg_mem_writel,
148 };
150 static uint32_t intregm_mem_readl(void *opaque, target_phys_addr_t addr)
151 {
152 SCHEDState *s = opaque;
153 uint32_t saddr;
155 saddr = (addr - s->addrg) >> 2;
156 switch (saddr) {
157 case 0:
158 return s->intregm_pending;
159 break;
160 case 1:
161 return s->intregm_enabled;
162 break;
163 default:
164 break;
165 }
166 return 0;
167 }
169 static void intregm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
170 {
171 SCHEDState *s = opaque;
172 uint32_t saddr;
174 saddr = (addr - s->addrg) >> 2;
175 switch (saddr) {
176 case 0:
177 s->intregm_pending = val;
178 break;
179 case 1:
180 s->intregm_enabled = val;
181 break;
182 case 2: // clear
183 s->intregm_enabled &= ~val;
184 break;
185 case 3: // set
186 s->intregm_enabled |= val;
187 break;
188 default:
189 break;
190 }
191 }
193 static CPUReadMemoryFunc *intregm_mem_read[3] = {
194 intregm_mem_readl,
195 intregm_mem_readl,
196 intregm_mem_readl,
197 };
199 static CPUWriteMemoryFunc *intregm_mem_write[3] = {
200 intregm_mem_writel,
201 intregm_mem_writel,
202 intregm_mem_writel,
203 };
205 void pic_info(void)
206 {
207 term_printf("per-cpu: pending 0x%08x, enabled 0x%08x\n", ps->intreg_pending, ps->intreg_enabled);
208 term_printf("master: pending 0x%08x, enabled 0x%08x\n", ps->intregm_pending, ps->intregm_enabled);
209 }
211 void irq_info(void)
212 {
213 #ifndef DEBUG_IRQ_COUNT
214 term_printf("irq statistic code not compiled.\n");
215 #else
216 int i;
217 int64_t count;
219 term_printf("IRQ statistics:\n");
220 for (i = 0; i < 32; i++) {
221 count = irq_count[i];
222 if (count > 0)
223 term_printf("%2d: %lld\n", i, count);
224 }
225 #endif
226 }
228 static const unsigned int intr_to_mask[16] = {
229 0, 0, 0, 0, 0, 0, SUN4M_INT_ETHERNET, 0,
230 0, 0, 0, 0, 0, 0, 0, 0,
231 };
233 void pic_set_irq(int irq, int level)
234 {
235 if (irq < 16) {
236 unsigned int mask = intr_to_mask[irq];
237 ps->intreg_pending |= 1 << irq;
238 if (ps->intregm_enabled & mask) {
239 cpu_single_env->interrupt_index = irq;
240 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
241 }
242 }
243 #ifdef DEBUG_IRQ_COUNT
244 if (level == 1)
245 irq_count[irq]++;
246 #endif
247 }
249 void sched_init(uint32_t addr, uint32_t addrg)
250 {
251 int intreg_io_memory, intregm_io_memory;
252 SCHEDState *s;
254 s = qemu_mallocz(sizeof(SCHEDState));
255 if (!s)
256 return;
257 s->addr = addr;
258 s->addrg = addrg;
260 intreg_io_memory = cpu_register_io_memory(0, intreg_mem_read, intreg_mem_write, s);
261 cpu_register_physical_memory(addr, 3, intreg_io_memory);
263 intregm_io_memory = cpu_register_io_memory(0, intregm_mem_read, intregm_mem_write, s);
264 cpu_register_physical_memory(addrg, 5, intregm_io_memory);
266 ps = s;
267 }