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