Commit ba3c64fb476d57c35013970ac444f04f35893ca9

Authored by bellard
1 parent b9788fc4

Initial SPARC SMP support (Blue Swirl)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1694 c046a42c-6fe2-441c-8c8c-71466251a162
Changelog
... ... @@ -16,6 +16,7 @@ version 0.7.3:
16 16 - MIPS User Linux emulation
17 17 - MIPS fixes to boot Linux (Daniel Jacobowitz)
18 18 - NX bit support
  19 + - Initial SPARC SMP support (Blue Swirl)
19 20  
20 21 version 0.7.2:
21 22  
... ...
cpu-all.h
... ... @@ -734,6 +734,7 @@ extern int code_copy_enabled;
734 734 #define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
735 735 #define CPU_INTERRUPT_TIMER 0x08 /* internal timer exception pending */
736 736 #define CPU_INTERRUPT_FIQ 0x10 /* Fast interrupt pending. */
  737 +#define CPU_INTERRUPT_HALT 0x20 /* CPU halt wanted */
737 738  
738 739 void cpu_interrupt(CPUState *s, int mask);
739 740 void cpu_reset_interrupt(CPUState *env, int mask);
... ...
cpu-exec.c
... ... @@ -274,6 +274,15 @@ int cpu_exec(CPUState *env1)
274 274 return EXCP_HALTED;
275 275 }
276 276 }
  277 +#elif defined(TARGET_SPARC)
  278 + if (env1->halted) {
  279 + if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&
  280 + (env1->psret != 0)) {
  281 + env1->halted = 0;
  282 + } else {
  283 + return EXCP_HALTED;
  284 + }
  285 + }
277 286 #elif defined(TARGET_ARM)
278 287 if (env1->halted) {
279 288 /* An interrupt wakes the CPU even if the I and F CPSR bits are
... ... @@ -522,7 +531,10 @@ int cpu_exec(CPUState *env1)
522 531 } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
523 532 //do_interrupt(0, 0, 0, 0, 0);
524 533 env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
525   - }
  534 + } else if (interrupt_request & CPU_INTERRUPT_HALT) {
  535 + env1->halted = 1;
  536 + return EXCP_HALTED;
  537 + }
526 538 #elif defined(TARGET_ARM)
527 539 if (interrupt_request & CPU_INTERRUPT_FIQ
528 540 && !(env->uncached_cpsr & CPSR_F)) {
... ...
hw/slavio_intctl.c
... ... @@ -53,6 +53,7 @@ typedef struct SLAVIO_INTCTLState {
53 53 #ifdef DEBUG_IRQ_COUNT
54 54 uint64_t irq_count[32];
55 55 #endif
  56 + CPUState *cpu_envs[MAX_CPUS];
56 57 } SLAVIO_INTCTLState;
57 58  
58 59 #define INTCTL_MAXADDR 0xf
... ... @@ -96,6 +97,7 @@ static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr, uint
96 97 case 2: // set softint
97 98 val &= 0xfffe0000;
98 99 s->intreg_pending[cpu] |= val;
  100 + slavio_check_interrupts(s);
99 101 DPRINTF("Set cpu %d irq mask %x, curmask %x\n", cpu, val, s->intreg_pending[cpu]);
100 102 break;
101 103 default:
... ... @@ -216,7 +218,7 @@ static void slavio_check_interrupts(void *opaque)
216 218 CPUState *env;
217 219 SLAVIO_INTCTLState *s = opaque;
218 220 uint32_t pending = s->intregm_pending;
219   - unsigned int i, max = 0;
  221 + unsigned int i, j, max = 0;
220 222  
221 223 pending &= ~s->intregm_disabled;
222 224  
... ... @@ -227,20 +229,52 @@ static void slavio_check_interrupts(void *opaque)
227 229 max = intbit_to_level[i];
228 230 }
229 231 }
230   - env = first_cpu;
231   - if (env->interrupt_index == 0) {
232   - DPRINTF("Triggered pil %d\n", max);
  232 + env = s->cpu_envs[s->target_cpu];
  233 + if (!env) {
  234 + DPRINTF("No CPU %d, not triggered (pending %x)\n", s->target_cpu, pending);
  235 + }
  236 + else {
  237 + if (env->halted)
  238 + env->halted = 0;
  239 + if (env->interrupt_index == 0) {
  240 + DPRINTF("Triggered CPU %d pil %d\n", s->target_cpu, max);
233 241 #ifdef DEBUG_IRQ_COUNT
234   - s->irq_count[max]++;
  242 + s->irq_count[max]++;
235 243 #endif
236   - env->interrupt_index = TT_EXTINT | max;
237   - cpu_interrupt(env, CPU_INTERRUPT_HARD);
  244 + env->interrupt_index = TT_EXTINT | max;
  245 + cpu_interrupt(env, CPU_INTERRUPT_HARD);
  246 + }
  247 + else
  248 + DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, env->interrupt_index);
238 249 }
239   - else
240   - DPRINTF("Not triggered (pending %x), pending exception %x\n", pending, env->interrupt_index);
241 250 }
242 251 else
243 252 DPRINTF("Not triggered (pending %x), disabled %x\n", pending, s->intregm_disabled);
  253 +
  254 + for (i = 0; i < MAX_CPUS; i++) {
  255 + max = 0;
  256 + env = s->cpu_envs[i];
  257 + if (!env)
  258 + continue;
  259 + for (j = 17; j < 32; j++) {
  260 + if (s->intreg_pending[i] & (1 << j)) {
  261 + if (max < j - 16)
  262 + max = j - 16;
  263 + }
  264 + }
  265 + if (max > 0) {
  266 + if (env->halted)
  267 + env->halted = 0;
  268 + if (env->interrupt_index == 0) {
  269 + DPRINTF("Triggered softint %d for cpu %d (pending %x)\n", max, i, pending);
  270 +#ifdef DEBUG_IRQ_COUNT
  271 + s->irq_count[max]++;
  272 +#endif
  273 + env->interrupt_index = TT_EXTINT | max;
  274 + cpu_interrupt(env, CPU_INTERRUPT_HARD);
  275 + }
  276 + }
  277 + }
244 278 }
245 279  
246 280 /*
... ... @@ -251,7 +285,7 @@ void slavio_pic_set_irq(void *opaque, int irq, int level)
251 285 {
252 286 SLAVIO_INTCTLState *s = opaque;
253 287  
254   - DPRINTF("Set irq %d level %d\n", irq, level);
  288 + DPRINTF("Set cpu %d irq %d level %d\n", s->target_cpu, irq, level);
255 289 if (irq < 32) {
256 290 uint32_t mask = 1 << irq;
257 291 uint32_t pil = intbit_to_level[irq];
... ... @@ -269,6 +303,29 @@ void slavio_pic_set_irq(void *opaque, int irq, int level)
269 303 slavio_check_interrupts(s);
270 304 }
271 305  
  306 +void slavio_pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu)
  307 +{
  308 + SLAVIO_INTCTLState *s = opaque;
  309 +
  310 + DPRINTF("Set cpu %d local irq %d level %d\n", cpu, irq, level);
  311 + if (cpu == (unsigned int)-1) {
  312 + slavio_pic_set_irq(opaque, irq, level);
  313 + return;
  314 + }
  315 + if (irq < 32) {
  316 + uint32_t pil = intbit_to_level[irq];
  317 + if (pil > 0) {
  318 + if (level) {
  319 + s->intreg_pending[cpu] |= 1 << pil;
  320 + }
  321 + else {
  322 + s->intreg_pending[cpu] &= ~(1 << pil);
  323 + }
  324 + }
  325 + }
  326 + slavio_check_interrupts(s);
  327 +}
  328 +
272 329 static void slavio_intctl_save(QEMUFile *f, void *opaque)
273 330 {
274 331 SLAVIO_INTCTLState *s = opaque;
... ... @@ -312,6 +369,12 @@ static void slavio_intctl_reset(void *opaque)
312 369 s->target_cpu = 0;
313 370 }
314 371  
  372 +void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env)
  373 +{
  374 + SLAVIO_INTCTLState *s = opaque;
  375 + s->cpu_envs[cpu] = env;
  376 +}
  377 +
315 378 void *slavio_intctl_init(uint32_t addr, uint32_t addrg)
316 379 {
317 380 int slavio_intctl_io_memory, slavio_intctlm_io_memory, i;
... ...
hw/slavio_misc.c
... ... @@ -124,9 +124,8 @@ static void slavio_misc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32
124 124 case 0xa000000:
125 125 MISC_DPRINTF("Write power management %2.2x\n", val & 0xff);
126 126 #if 0
127   - // XXX: halting CPU does not work
128   - raise_exception(EXCP_HLT);
129   - cpu_loop_exit();
  127 + // XXX almost works
  128 + cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT);
130 129 #endif
131 130 break;
132 131 }
... ...
hw/slavio_serial.c
... ... @@ -45,6 +45,8 @@
45 45 #ifdef DEBUG_SERIAL
46 46 #define SER_DPRINTF(fmt, args...) \
47 47 do { printf("SER: " fmt , ##args); } while (0)
  48 +#define pic_set_irq(irq, level) \
  49 +do { printf("SER: set_irq(%d): %d\n", (irq), (level)); pic_set_irq((irq),(level));} while (0)
48 50 #else
49 51 #define SER_DPRINTF(fmt, args...)
50 52 #endif
... ... @@ -174,6 +176,50 @@ static void slavio_serial_reset(void *opaque)
174 176 slavio_serial_reset_chn(&s->chn[1]);
175 177 }
176 178  
  179 +static inline void clr_rxint(ChannelState *s)
  180 +{
  181 + s->rxint = 0;
  182 + if (s->chn == 0)
  183 + s->rregs[3] &= ~0x20;
  184 + else {
  185 + s->otherchn->rregs[3] &= ~4;
  186 + }
  187 + slavio_serial_update_irq(s);
  188 +}
  189 +
  190 +static inline void set_rxint(ChannelState *s)
  191 +{
  192 + s->rxint = 1;
  193 + if (s->chn == 0)
  194 + s->rregs[3] |= 0x20;
  195 + else {
  196 + s->otherchn->rregs[3] |= 4;
  197 + }
  198 + slavio_serial_update_irq(s);
  199 +}
  200 +
  201 +static inline void clr_txint(ChannelState *s)
  202 +{
  203 + s->txint = 0;
  204 + if (s->chn == 0)
  205 + s->rregs[3] &= ~0x10;
  206 + else {
  207 + s->otherchn->rregs[3] &= ~2;
  208 + }
  209 + slavio_serial_update_irq(s);
  210 +}
  211 +
  212 +static inline void set_txint(ChannelState *s)
  213 +{
  214 + s->txint = 1;
  215 + if (s->chn == 0)
  216 + s->rregs[3] |= 0x10;
  217 + else {
  218 + s->otherchn->rregs[3] |= 2;
  219 + }
  220 + slavio_serial_update_irq(s);
  221 +}
  222 +
177 223 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
178 224 {
179 225 SerialState *ser = opaque;
... ... @@ -198,10 +244,14 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint
198 244 newreg |= 0x8;
199 245 break;
200 246 case 0x20:
201   - s->rxint = 0;
  247 + clr_rxint(s);
202 248 break;
203 249 case 0x28:
204   - s->txint = 0;
  250 + clr_txint(s);
  251 + break;
  252 + case 0x38:
  253 + clr_rxint(s);
  254 + clr_txint(s);
205 255 break;
206 256 default:
207 257 break;
... ... @@ -247,12 +297,7 @@ static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr, uint
247 297 s->txint = 1;
248 298 s->rregs[0] |= 4; // Tx buffer empty
249 299 s->rregs[1] |= 1; // All sent
250   - // Interrupts reported only on channel A
251   - if (s->chn == 0)
252   - s->rregs[3] |= 0x10;
253   - else {
254   - s->otherchn->rregs[3] |= 2;
255   - }
  300 + set_txint(s);
256 301 slavio_serial_update_irq(s);
257 302 }
258 303 break;
... ... @@ -280,6 +325,7 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
280 325 return ret;
281 326 case 1:
282 327 s->rregs[0] &= ~1;
  328 + clr_rxint(s);
283 329 if (s->type == kbd)
284 330 ret = get_queue(s);
285 331 else
... ... @@ -304,16 +350,10 @@ static int serial_can_receive(void *opaque)
304 350  
305 351 static void serial_receive_byte(ChannelState *s, int ch)
306 352 {
  353 + SER_DPRINTF("put ch %d\n", ch);
307 354 s->rregs[0] |= 1;
308   - // Interrupts reported only on channel A
309   - if (s->chn == 0)
310   - s->rregs[3] |= 0x20;
311   - else {
312   - s->otherchn->rregs[3] |= 4;
313   - }
314 355 s->rx = ch;
315   - s->rxint = 1;
316   - slavio_serial_update_irq(s);
  356 + set_rxint(s);
317 357 }
318 358  
319 359 static void serial_receive_break(ChannelState *s)
... ...
hw/slavio_timer.c
... ... @@ -42,6 +42,9 @@ do { printf(&quot;TIMER: &quot; fmt , ##args); } while (0)
42 42 * The 31-bit counter is incremented every 500ns by bit 9. Bits 8..0
43 43 * are zero. Bit 31 is 1 when count has been reached.
44 44 *
  45 + * Per-CPU timers interrupt local CPU, system timer uses normal
  46 + * interrupt routing.
  47 + *
45 48 */
46 49  
47 50 typedef struct SLAVIO_TIMERState {
... ... @@ -53,11 +56,11 @@ typedef struct SLAVIO_TIMERState {
53 56 int irq;
54 57 int reached, stopped;
55 58 int mode; // 0 = processor, 1 = user, 2 = system
  59 + unsigned int cpu;
56 60 } SLAVIO_TIMERState;
57 61  
58 62 #define TIMER_MAXADDR 0x1f
59 63 #define CNT_FREQ 2000000
60   -#define MAX_CPUS 16
61 64  
62 65 // Update count, set irq, update expire_time
63 66 static void slavio_timer_get_out(SLAVIO_TIMERState *s)
... ... @@ -73,7 +76,7 @@ static void slavio_timer_get_out(SLAVIO_TIMERState *s)
73 76 else
74 77 ticks = qemu_get_clock(vm_clock) - s->tick_offset;
75 78  
76   - out = (ticks >= s->expire_time);
  79 + out = (ticks > s->expire_time);
77 80 if (out)
78 81 s->reached = 0x80000000;
79 82 if (!s->limit)
... ... @@ -100,7 +103,7 @@ static void slavio_timer_get_out(SLAVIO_TIMERState *s)
100 103 DPRINTF("irq %d limit %d reached %d d %lld count %d s->c %x diff %lld stopped %d mode %d\n", s->irq, limit, s->reached?1:0, (ticks-s->count_load_time), count, s->count, s->expire_time - ticks, s->stopped, s->mode);
101 104  
102 105 if (s->mode != 1)
103   - pic_set_irq(s->irq, out);
  106 + pic_set_irq_cpu(s->irq, out, s->cpu);
104 107 }
105 108  
106 109 // timer callback
... ... @@ -127,7 +130,7 @@ static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
127 130 // part of counter (user mode)
128 131 if (s->mode != 1) {
129 132 // clear irq
130   - pic_set_irq(s->irq, 0);
  133 + pic_set_irq_cpu(s->irq, 0, s->cpu);
131 134 s->count_load_time = qemu_get_clock(vm_clock);
132 135 s->reached = 0;
133 136 return s->limit;
... ... @@ -263,7 +266,7 @@ static void slavio_timer_reset(void *opaque)
263 266 slavio_timer_get_out(s);
264 267 }
265 268  
266   -static void slavio_timer_init_internal(uint32_t addr, int irq, int mode)
  269 +void slavio_timer_init(uint32_t addr, int irq, int mode, unsigned int cpu)
267 270 {
268 271 int slavio_timer_io_memory;
269 272 SLAVIO_TIMERState *s;
... ... @@ -273,6 +276,7 @@ static void slavio_timer_init_internal(uint32_t addr, int irq, int mode)
273 276 return;
274 277 s->irq = irq;
275 278 s->mode = mode;
  279 + s->cpu = cpu;
276 280 s->irq_timer = qemu_new_timer(vm_clock, slavio_timer_irq, s);
277 281  
278 282 slavio_timer_io_memory = cpu_register_io_memory(0, slavio_timer_mem_read,
... ... @@ -282,14 +286,3 @@ static void slavio_timer_init_internal(uint32_t addr, int irq, int mode)
282 286 qemu_register_reset(slavio_timer_reset, s);
283 287 slavio_timer_reset(s);
284 288 }
285   -
286   -void slavio_timer_init(uint32_t addr1, int irq1, uint32_t addr2, int irq2)
287   -{
288   - int i;
289   -
290   - for (i = 0; i < MAX_CPUS; i++) {
291   - slavio_timer_init_internal(addr1 + i * TARGET_PAGE_SIZE, irq1, 0);
292   - }
293   -
294   - slavio_timer_init_internal(addr2, irq2, 2);
295   -}
... ...
hw/sun4m.c
... ... @@ -56,6 +56,7 @@
56 56 #define PHYS_JJ_FDC 0x71400000 /* Floppy */
57 57 #define PHYS_JJ_FLOPPY_IRQ 22
58 58 #define PHYS_JJ_ME_IRQ 30 /* Module error, power fail */
  59 +#define MAX_CPUS 16
59 60  
60 61 /* TSC handling */
61 62  
... ... @@ -128,6 +129,8 @@ static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline,
128 129 nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);
129 130 nvram_set_lword(nvram, 0x10, 0x00000001); /* structure v1 */
130 131 // NVRAM_size, arch not applicable
  132 + m48t59_write(nvram, 0x2D, smp_cpus & 0xff);
  133 + m48t59_write(nvram, 0x2E, 0);
131 134 m48t59_write(nvram, 0x2F, nographic & 0xff);
132 135 nvram_set_lword(nvram, 0x30, RAM_size);
133 136 m48t59_write(nvram, 0x34, boot_device & 0xff);
... ... @@ -179,6 +182,11 @@ void pic_set_irq(int irq, int level)
179 182 slavio_pic_set_irq(slavio_intctl, irq, level);
180 183 }
181 184  
  185 +void pic_set_irq_cpu(int irq, int level, unsigned int cpu)
  186 +{
  187 + slavio_pic_set_irq_cpu(slavio_intctl, irq, level, cpu);
  188 +}
  189 +
182 190 static void *tcx;
183 191  
184 192 void vga_update_display()
... ... @@ -222,7 +230,7 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
222 230 const char *kernel_filename, const char *kernel_cmdline,
223 231 const char *initrd_filename)
224 232 {
225   - CPUState *env;
  233 + CPUState *env, *envs[MAX_CPUS];
226 234 char buf[1024];
227 235 int ret, linux_boot;
228 236 unsigned int i;
... ... @@ -230,19 +238,31 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
230 238  
231 239 linux_boot = (kernel_filename != NULL);
232 240  
233   - env = cpu_init();
234   - register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
235   - qemu_register_reset(main_cpu_reset, env);
236   -
  241 + /* init CPUs */
  242 + for(i = 0; i < smp_cpus; i++) {
  243 + env = cpu_init();
  244 + envs[i] = env;
  245 + if (i != 0)
  246 + env->halted = 1;
  247 + register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
  248 + qemu_register_reset(main_cpu_reset, env);
  249 + }
237 250 /* allocate RAM */
238 251 cpu_register_physical_memory(0, ram_size, 0);
239 252  
240 253 iommu = iommu_init(PHYS_JJ_IOMMU);
241 254 slavio_intctl = slavio_intctl_init(PHYS_JJ_INTR0, PHYS_JJ_INTR_G);
  255 + for(i = 0; i < smp_cpus; i++) {
  256 + slavio_intctl_set_cpu(slavio_intctl, i, envs[i]);
  257 + }
  258 +
242 259 tcx = tcx_init(ds, PHYS_JJ_TCX_FB, phys_ram_base + ram_size, ram_size, vram_size, graphic_width, graphic_height);
243 260 lance_init(&nd_table[0], PHYS_JJ_LE_IRQ, PHYS_JJ_LE, PHYS_JJ_LEDMA);
244 261 nvram = m48t59_init(0, PHYS_JJ_EEPROM, 0, PHYS_JJ_EEPROM_SIZE, 8);
245   - slavio_timer_init(PHYS_JJ_CLOCK, PHYS_JJ_CLOCK_IRQ, PHYS_JJ_CLOCK1, PHYS_JJ_CLOCK1_IRQ);
  262 + for (i = 0; i < MAX_CPUS; i++) {
  263 + slavio_timer_init(PHYS_JJ_CLOCK + i * TARGET_PAGE_SIZE, PHYS_JJ_CLOCK_IRQ, 0, i);
  264 + }
  265 + slavio_timer_init(PHYS_JJ_CLOCK1, PHYS_JJ_CLOCK1_IRQ, 2, (unsigned int)-1);
246 266 slavio_serial_ms_kbd_init(PHYS_JJ_MS_KBD, PHYS_JJ_MS_KBD_IRQ);
247 267 // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
248 268 // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
... ...
monitor.c
... ... @@ -259,6 +259,10 @@ static void do_info_cpus(void)
259 259 term_printf(" nip=0x" TARGET_FMT_lx, env->nip);
260 260 if (env->halted)
261 261 term_printf(" (halted)");
  262 +#elif defined(TARGET_SPARC)
  263 + term_printf(" pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc);
  264 + if (env->halted)
  265 + term_printf(" (halted)");
262 266 #endif
263 267 term_printf("\n");
264 268 }
... ...
target-sparc/cpu.h
... ... @@ -166,6 +166,7 @@ typedef struct CPUSPARCState {
166 166 int exception_index;
167 167 int interrupt_index;
168 168 int interrupt_request;
  169 + int halted;
169 170 /* NOTE: we allow 8 more registers to handle wrapping */
170 171 target_ulong regbase[NWINDOWS * 16 + 8];
171 172  
... ...
... ... @@ -153,6 +153,11 @@ USBPort *vm_usb_ports[MAX_VM_USB_PORTS];
153 153 USBDevice *vm_usb_hub;
154 154 static VLANState *first_vlan;
155 155 int smp_cpus = 1;
  156 +#ifdef TARGET_SPARC
  157 +#define MAX_CPUS 16
  158 +#else
  159 +#define MAX_CPUS 8
  160 +#endif
156 161  
157 162 /***********************************************************/
158 163 /* x86 ISA bus support */
... ... @@ -4547,7 +4552,7 @@ int main(int argc, char **argv)
4547 4552 break;
4548 4553 case QEMU_OPTION_smp:
4549 4554 smp_cpus = atoi(optarg);
4550   - if (smp_cpus < 1 || smp_cpus > 8) {
  4555 + if (smp_cpus < 1 || smp_cpus > MAX_CPUS) {
4551 4556 fprintf(stderr, "Invalid number of CPUs\n");
4552 4557 exit(1);
4553 4558 }
... ...
... ... @@ -806,6 +806,7 @@ void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val);
806 806 /* sun4m.c */
807 807 extern QEMUMachine sun4m_machine;
808 808 uint32_t iommu_translate(uint32_t addr);
  809 +void pic_set_irq_cpu(int irq, int level, unsigned int cpu);
809 810  
810 811 /* iommu.c */
811 812 void *iommu_init(uint32_t addr);
... ... @@ -823,16 +824,18 @@ void tcx_screen_dump(void *opaque, const char *filename);
823 824  
824 825 /* slavio_intctl.c */
825 826 void *slavio_intctl_init();
  827 +void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env);
826 828 void slavio_pic_info(void *opaque);
827 829 void slavio_irq_info(void *opaque);
828 830 void slavio_pic_set_irq(void *opaque, int irq, int level);
  831 +void slavio_pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu);
829 832  
830 833 /* magic-load.c */
831 834 int load_elf(const char *filename, uint8_t *addr);
832 835 int load_aout(const char *filename, uint8_t *addr);
833 836  
834 837 /* slavio_timer.c */
835   -void slavio_timer_init(uint32_t addr1, int irq1, uint32_t addr2, int irq2);
  838 +void slavio_timer_init(uint32_t addr, int irq, int mode, unsigned int cpu);
836 839  
837 840 /* slavio_serial.c */
838 841 SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2);
... ...