Commit 6a00d60127dc0e1d4efadafe1feb88f05030fe52

Authored by bellard
1 parent f0aca822

SMP support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1640 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-defs.h
... ... @@ -96,6 +96,7 @@ typedef struct CPUTLBEntry {
96 96  
97 97 #define CPU_COMMON \
98 98 struct TranslationBlock *current_tb; /* currently executing TB */ \
  99 + int cpu_halted; /* TRUE if cpu is halted (sleep mode) */ \
99 100 /* soft mmu support */ \
100 101 /* in order to avoid passing too many arguments to the memory \
101 102 write helpers, we store some rarely used information in the CPU \
... ... @@ -115,9 +116,9 @@ typedef struct CPUTLBEntry {
115 116 int nb_breakpoints; \
116 117 int singlestep_enabled; \
117 118 \
  119 + void *next_cpu; /* next CPU sharing TB cache */ \
  120 + int cpu_index; /* CPU index (informative) */ \
118 121 /* user data */ \
119 122 void *opaque;
120 123  
121   -
122   -
123 124 #endif
... ...
cpu-exec.c
... ... @@ -251,6 +251,8 @@ int cpu_exec(CPUState *env1)
251 251 TranslationBlock *tb;
252 252 uint8_t *tc_ptr;
253 253  
  254 + cpu_single_env = env1;
  255 +
254 256 /* first we save global registers */
255 257 saved_env = env;
256 258 env = env1;
... ... @@ -755,6 +757,8 @@ int cpu_exec(CPUState *env1)
755 757 T2 = saved_T2;
756 758 #endif
757 759 env = saved_env;
  760 + /* fail safe : never use cpu_single_env outside cpu_exec() */
  761 + cpu_single_env = NULL;
758 762 return ret;
759 763 }
760 764  
... ...
... ... @@ -138,6 +138,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
138 138 values:
139 139 i386 - nonzero means 16 bit code
140 140 arm - nonzero means thumb code
  141 + ppc - nonzero means little endian
141 142 other targets - unused
142 143 */
143 144 void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
... ... @@ -177,7 +178,7 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
177 178 disasm_info.mach = bfd_mach_sparc_v9b;
178 179 #endif
179 180 #elif defined(TARGET_PPC)
180   - if (cpu_single_env->msr[MSR_LE])
  181 + if (flags)
181 182 disasm_info.endian = BFD_ENDIAN_LITTLE;
182 183 #ifdef TARGET_PPC64
183 184 disasm_info.mach = bfd_mach_ppc64;
... ... @@ -314,6 +315,7 @@ void term_vprintf(const char *fmt, va_list ap);
314 315 void term_printf(const char *fmt, ...);
315 316  
316 317 static int monitor_disas_is_physical;
  318 +static CPUState *monitor_disas_env;
317 319  
318 320 static int
319 321 monitor_read_memory (memaddr, myaddr, length, info)
... ... @@ -325,7 +327,7 @@ monitor_read_memory (memaddr, myaddr, length, info)
325 327 if (monitor_disas_is_physical) {
326 328 cpu_physical_memory_rw(memaddr, myaddr, length, 0);
327 329 } else {
328   - cpu_memory_rw_debug(cpu_single_env, memaddr,myaddr, length, 0);
  330 + cpu_memory_rw_debug(monitor_disas_env, memaddr,myaddr, length, 0);
329 331 }
330 332 return 0;
331 333 }
... ... @@ -339,7 +341,8 @@ static int monitor_fprintf(FILE *stream, const char *fmt, ...)
339 341 return 0;
340 342 }
341 343  
342   -void monitor_disas(target_ulong pc, int nb_insn, int is_physical, int flags)
  344 +void monitor_disas(CPUState *env,
  345 + target_ulong pc, int nb_insn, int is_physical, int flags)
343 346 {
344 347 int count, i;
345 348 struct disassemble_info disasm_info;
... ... @@ -347,6 +350,7 @@ void monitor_disas(target_ulong pc, int nb_insn, int is_physical, int flags)
347 350  
348 351 INIT_DISASSEMBLE_INFO(disasm_info, NULL, monitor_fprintf);
349 352  
  353 + monitor_disas_env = env;
350 354 monitor_disas_is_physical = is_physical;
351 355 disasm_info.read_memory_func = monitor_read_memory;
352 356  
... ...
exec-all.h
... ... @@ -91,7 +91,7 @@ int cpu_restore_state_copy(struct TranslationBlock *tb,
91 91 CPUState *env, unsigned long searched_pc,
92 92 void *puc);
93 93 void cpu_resume_from_signal(CPUState *env1, void *puc);
94   -void cpu_exec_init(void);
  94 +void cpu_exec_init(CPUState *env);
95 95 int page_unprotect(unsigned long address, unsigned long pc, void *puc);
96 96 void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
97 97 int is_cpu_write_access);
... ...
... ... @@ -74,6 +74,11 @@ int phys_ram_fd;
74 74 uint8_t *phys_ram_base;
75 75 uint8_t *phys_ram_dirty;
76 76  
  77 +CPUState *first_cpu;
  78 +/* current CPU in the current thread. It is only valid inside
  79 + cpu_exec() */
  80 +CPUState *cpu_single_env;
  81 +
77 82 typedef struct PageDesc {
78 83 /* list of TBs intersecting this ram page */
79 84 TranslationBlock *first_tb;
... ... @@ -233,19 +238,30 @@ static inline PhysPageDesc *phys_page_find(target_phys_addr_t index)
233 238 }
234 239  
235 240 #if !defined(CONFIG_USER_ONLY)
236   -static void tlb_protect_code(CPUState *env, ram_addr_t ram_addr,
237   - target_ulong vaddr);
  241 +static void tlb_protect_code(ram_addr_t ram_addr);
238 242 static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
239 243 target_ulong vaddr);
240 244 #endif
241 245  
242   -void cpu_exec_init(void)
  246 +void cpu_exec_init(CPUState *env)
243 247 {
  248 + CPUState **penv;
  249 + int cpu_index;
  250 +
244 251 if (!code_gen_ptr) {
245 252 code_gen_ptr = code_gen_buffer;
246 253 page_init();
247 254 io_mem_init();
248 255 }
  256 + env->next_cpu = NULL;
  257 + penv = &first_cpu;
  258 + cpu_index = 0;
  259 + while (*penv != NULL) {
  260 + penv = (CPUState **)&(*penv)->next_cpu;
  261 + cpu_index++;
  262 + }
  263 + env->cpu_index = cpu_index;
  264 + *penv = env;
249 265 }
250 266  
251 267 static inline void invalidate_page_bitmap(PageDesc *p)
... ... @@ -277,8 +293,9 @@ static void page_flush_tb(void)
277 293  
278 294 /* flush all the translation blocks */
279 295 /* XXX: tb_flush is currently not thread safe */
280   -void tb_flush(CPUState *env)
  296 +void tb_flush(CPUState *env1)
281 297 {
  298 + CPUState *env;
282 299 #if defined(DEBUG_FLUSH)
283 300 printf("qemu: flush code_size=%d nb_tbs=%d avg_tb_size=%d\n",
284 301 code_gen_ptr - code_gen_buffer,
... ... @@ -286,7 +303,10 @@ void tb_flush(CPUState *env)
286 303 nb_tbs > 0 ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0);
287 304 #endif
288 305 nb_tbs = 0;
289   - memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
  306 +
  307 + for(env = first_cpu; env != NULL; env = env->next_cpu) {
  308 + memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
  309 + }
290 310  
291 311 memset (tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof (void *));
292 312 page_flush_tb();
... ... @@ -424,6 +444,7 @@ static inline void tb_reset_jump(TranslationBlock *tb, int n)
424 444  
425 445 static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_addr)
426 446 {
  447 + CPUState *env;
427 448 PageDesc *p;
428 449 unsigned int h, n1;
429 450 target_ulong phys_pc;
... ... @@ -451,7 +472,10 @@ static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_ad
451 472  
452 473 /* remove the TB from the hash list */
453 474 h = tb_jmp_cache_hash_func(tb->pc);
454   - cpu_single_env->tb_jmp_cache[h] = NULL;
  475 + for(env = first_cpu; env != NULL; env = env->next_cpu) {
  476 + if (env->tb_jmp_cache[h] == tb)
  477 + env->tb_jmp_cache[h] = NULL;
  478 + }
455 479  
456 480 /* suppress this TB from the two jump lists */
457 481 tb_jmp_remove(tb, 0);
... ... @@ -818,10 +842,7 @@ static inline void tb_alloc_page(TranslationBlock *tb,
818 842 protected. So we handle the case where only the first TB is
819 843 allocated in a physical page */
820 844 if (!last_first_tb) {
821   - target_ulong virt_addr;
822   -
823   - virt_addr = (tb->pc & TARGET_PAGE_MASK) + (n << TARGET_PAGE_BITS);
824   - tlb_protect_code(cpu_single_env, page_addr, virt_addr);
  845 + tlb_protect_code(page_addr);
825 846 }
826 847 #endif
827 848  
... ... @@ -1246,40 +1267,13 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
1246 1267 #endif
1247 1268 }
1248 1269  
1249   -static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, target_ulong addr)
1250   -{
1251   - if (addr == (tlb_entry->address &
1252   - (TARGET_PAGE_MASK | TLB_INVALID_MASK)) &&
1253   - (tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
1254   - tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
1255   - }
1256   -}
1257   -
1258 1270 /* update the TLBs so that writes to code in the virtual page 'addr'
1259 1271 can be detected */
1260   -static void tlb_protect_code(CPUState *env, ram_addr_t ram_addr,
1261   - target_ulong vaddr)
  1272 +static void tlb_protect_code(ram_addr_t ram_addr)
1262 1273 {
1263   - int i;
1264   -
1265   - vaddr &= TARGET_PAGE_MASK;
1266   - i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1267   - tlb_protect_code1(&env->tlb_write[0][i], vaddr);
1268   - tlb_protect_code1(&env->tlb_write[1][i], vaddr);
1269   -
1270   -#ifdef USE_KQEMU
1271   - if (env->kqemu_enabled) {
1272   - kqemu_set_notdirty(env, ram_addr);
1273   - }
1274   -#endif
1275   - phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] &= ~CODE_DIRTY_FLAG;
1276   -
1277   -#if !defined(CONFIG_SOFTMMU)
1278   - /* NOTE: as we generated the code for this page, it is already at
1279   - least readable */
1280   - if (vaddr < MMAP_AREA_END)
1281   - mprotect((void *)vaddr, TARGET_PAGE_SIZE, PROT_READ);
1282   -#endif
  1274 + cpu_physical_memory_reset_dirty(ram_addr,
  1275 + ram_addr + TARGET_PAGE_SIZE,
  1276 + CODE_DIRTY_FLAG);
1283 1277 }
1284 1278  
1285 1279 /* update the TLB so that writes in physical page 'phys_addr' are no longer
... ... @@ -1317,8 +1311,9 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
1317 1311 if (length == 0)
1318 1312 return;
1319 1313 len = length >> TARGET_PAGE_BITS;
1320   - env = cpu_single_env;
1321 1314 #ifdef USE_KQEMU
  1315 + /* XXX: should not depend on cpu context */
  1316 + env = first_cpu;
1322 1317 if (env->kqemu_enabled) {
1323 1318 ram_addr_t addr;
1324 1319 addr = start;
... ... @@ -1336,10 +1331,12 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
1336 1331 /* we modify the TLB cache so that the dirty bit will be set again
1337 1332 when accessing the range */
1338 1333 start1 = start + (unsigned long)phys_ram_base;
1339   - for(i = 0; i < CPU_TLB_SIZE; i++)
1340   - tlb_reset_dirty_range(&env->tlb_write[0][i], start1, length);
1341   - for(i = 0; i < CPU_TLB_SIZE; i++)
1342   - tlb_reset_dirty_range(&env->tlb_write[1][i], start1, length);
  1334 + for(env = first_cpu; env != NULL; env = env->next_cpu) {
  1335 + for(i = 0; i < CPU_TLB_SIZE; i++)
  1336 + tlb_reset_dirty_range(&env->tlb_write[0][i], start1, length);
  1337 + for(i = 0; i < CPU_TLB_SIZE; i++)
  1338 + tlb_reset_dirty_range(&env->tlb_write[1][i], start1, length);
  1339 + }
1343 1340  
1344 1341 #if !defined(CONFIG_SOFTMMU)
1345 1342 /* XXX: this is expensive */
... ... @@ -1407,9 +1404,9 @@ static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
1407 1404  
1408 1405 /* update the TLB corresponding to virtual page vaddr and phys addr
1409 1406 addr so that it is no longer dirty */
1410   -static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr)
  1407 +static inline void tlb_set_dirty(CPUState *env,
  1408 + unsigned long addr, target_ulong vaddr)
1411 1409 {
1412   - CPUState *env = cpu_single_env;
1413 1410 int i;
1414 1411  
1415 1412 addr &= TARGET_PAGE_MASK;
... ... @@ -1723,7 +1720,8 @@ void page_unprotect_range(uint8_t *data, unsigned long data_size)
1723 1720 }
1724 1721 }
1725 1722  
1726   -static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr)
  1723 +static inline void tlb_set_dirty(CPUState *env,
  1724 + unsigned long addr, target_ulong vaddr)
1727 1725 {
1728 1726 }
1729 1727 #endif /* defined(CONFIG_USER_ONLY) */
... ... @@ -1787,7 +1785,7 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t
1787 1785 /* we remove the notdirty callback only if the code has been
1788 1786 flushed */
1789 1787 if (dirty_flags == 0xff)
1790   - tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
  1788 + tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
1791 1789 }
1792 1790  
1793 1791 static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
... ... @@ -1808,7 +1806,7 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t
1808 1806 /* we remove the notdirty callback only if the code has been
1809 1807 flushed */
1810 1808 if (dirty_flags == 0xff)
1811   - tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
  1809 + tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
1812 1810 }
1813 1811  
1814 1812 static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
... ... @@ -1829,7 +1827,7 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t
1829 1827 /* we remove the notdirty callback only if the code has been
1830 1828 flushed */
1831 1829 if (dirty_flags == 0xff)
1832   - tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
  1830 + tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
1833 1831 }
1834 1832  
1835 1833 static CPUReadMemoryFunc *error_mem_read[3] = {
... ... @@ -1953,6 +1951,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
1953 1951 if (is_write) {
1954 1952 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
1955 1953 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
  1954 + /* XXX: could force cpu_single_env to NULL to avoid
  1955 + potential bugs */
1956 1956 if (l >= 4 && ((addr & 3) == 0)) {
1957 1957 /* 32 bit write access */
1958 1958 val = ldl_p(buf);
... ...
gdbstub.c
... ... @@ -47,6 +47,7 @@ enum RSState {
47 47 static int gdbserver_fd = -1;
48 48  
49 49 typedef struct GDBState {
  50 + CPUState *env; /* current CPU */
50 51 enum RSState state; /* parsing state */
51 52 int fd;
52 53 char line_buf[4096];
... ... @@ -576,10 +577,10 @@ static void gdb_vm_stopped(void *opaque, int reason)
576 577 int ret;
577 578  
578 579 /* disable single step if it was enable */
579   - cpu_single_step(cpu_single_env, 0);
  580 + cpu_single_step(s->env, 0);
580 581  
581 582 if (reason == EXCP_DEBUG) {
582   - tb_flush(cpu_single_env);
  583 + tb_flush(s->env);
583 584 ret = SIGTRAP;
584 585 }
585 586 else
... ... @@ -589,8 +590,9 @@ static void gdb_vm_stopped(void *opaque, int reason)
589 590 }
590 591 #endif
591 592  
592   -static void gdb_read_byte(GDBState *s, CPUState *env, int ch)
  593 +static void gdb_read_byte(GDBState *s, int ch)
593 594 {
  595 + CPUState *env = s->env;
594 596 int i, csum;
595 597 char reply[1];
596 598  
... ... @@ -676,7 +678,7 @@ gdb_handlesig (CPUState *env, int sig)
676 678 int i;
677 679  
678 680 for (i = 0; i < n; i++)
679   - gdb_read_byte (s, env, buf[i]);
  681 + gdb_read_byte (s, buf[i]);
680 682 }
681 683 else if (n == 0 || errno != EAGAIN)
682 684 {
... ... @@ -721,7 +723,7 @@ static void gdb_read(void *opaque)
721 723 vm_start();
722 724 } else {
723 725 for(i = 0; i < size; i++)
724   - gdb_read_byte(s, cpu_single_env, buf[i]);
  726 + gdb_read_byte(s, buf[i]);
725 727 }
726 728 }
727 729  
... ... @@ -759,6 +761,7 @@ static void gdb_accept(void *opaque)
759 761 return;
760 762 }
761 763 #endif
  764 + s->env = first_cpu; /* XXX: allow to change CPU */
762 765 s->fd = fd;
763 766  
764 767 fcntl(fd, F_SETFL, O_NONBLOCK);
... ...
monitor.c
... ... @@ -64,6 +64,8 @@ static int term_outbuf_index;
64 64  
65 65 static void monitor_start_input(void);
66 66  
  67 +CPUState *mon_cpu = NULL;
  68 +
67 69 void term_flush(void)
68 70 {
69 71 if (term_outbuf_index > 0) {
... ... @@ -201,17 +203,69 @@ static void do_info_block(void)
201 203 bdrv_info();
202 204 }
203 205  
  206 +/* get the current CPU defined by the user */
  207 +int mon_set_cpu(int cpu_index)
  208 +{
  209 + CPUState *env;
  210 +
  211 + for(env = first_cpu; env != NULL; env = env->next_cpu) {
  212 + if (env->cpu_index == cpu_index) {
  213 + mon_cpu = env;
  214 + return 0;
  215 + }
  216 + }
  217 + return -1;
  218 +}
  219 +
  220 +CPUState *mon_get_cpu(void)
  221 +{
  222 + if (!mon_cpu) {
  223 + mon_set_cpu(0);
  224 + }
  225 + return mon_cpu;
  226 +}
  227 +
204 228 static void do_info_registers(void)
205 229 {
  230 + CPUState *env;
  231 + env = mon_get_cpu();
  232 + if (!env)
  233 + return;
206 234 #ifdef TARGET_I386
207   - cpu_dump_state(cpu_single_env, NULL, monitor_fprintf,
  235 + cpu_dump_state(env, NULL, monitor_fprintf,
208 236 X86_DUMP_FPU);
209 237 #else
210   - cpu_dump_state(cpu_single_env, NULL, monitor_fprintf,
  238 + cpu_dump_state(env, NULL, monitor_fprintf,
211 239 0);
212 240 #endif
213 241 }
214 242  
  243 +static void do_info_cpus(void)
  244 +{
  245 + CPUState *env;
  246 +
  247 + /* just to set the default cpu if not already done */
  248 + mon_get_cpu();
  249 +
  250 + for(env = first_cpu; env != NULL; env = env->next_cpu) {
  251 + term_printf("%c CPU #%d:",
  252 + (env == mon_cpu) ? '*' : ' ',
  253 + env->cpu_index);
  254 +#if defined(TARGET_I386)
  255 + term_printf(" pc=0x" TARGET_FMT_lx, env->eip + env->segs[R_CS].base);
  256 + if (env->cpu_halted)
  257 + term_printf(" (halted)");
  258 +#endif
  259 + term_printf("\n");
  260 + }
  261 +}
  262 +
  263 +static void do_cpu_set(int index)
  264 +{
  265 + if (mon_set_cpu(index) < 0)
  266 + term_printf("Invalid CPU index\n");
  267 +}
  268 +
215 269 static void do_info_jit(void)
216 270 {
217 271 dump_exec_info(NULL, monitor_fprintf);
... ... @@ -381,6 +435,7 @@ static void term_printc(int c)
381 435 static void memory_dump(int count, int format, int wsize,
382 436 target_ulong addr, int is_physical)
383 437 {
  438 + CPUState *env;
384 439 int nb_per_line, l, line_size, i, max_digits, len;
385 440 uint8_t buf[16];
386 441 uint64_t v;
... ... @@ -388,19 +443,22 @@ static void memory_dump(int count, int format, int wsize,
388 443 if (format == 'i') {
389 444 int flags;
390 445 flags = 0;
  446 + env = mon_get_cpu();
  447 + if (!env && !is_physical)
  448 + return;
391 449 #ifdef TARGET_I386
392 450 if (wsize == 2) {
393 451 flags = 1;
394 452 } else if (wsize == 4) {
395 453 flags = 0;
396 454 } else {
397   - /* as default we use the current CS size */
  455 + /* as default we use the current CS size */
398 456 flags = 0;
399   - if (!(cpu_single_env->segs[R_CS].flags & DESC_B_MASK))
  457 + if (env && !(env->segs[R_CS].flags & DESC_B_MASK))
400 458 flags = 1;
401 459 }
402 460 #endif
403   - monitor_disas(addr, count, is_physical, flags);
  461 + monitor_disas(env, addr, count, is_physical, flags);
404 462 return;
405 463 }
406 464  
... ... @@ -437,7 +495,10 @@ static void memory_dump(int count, int format, int wsize,
437 495 if (is_physical) {
438 496 cpu_physical_memory_rw(addr, buf, l, 0);
439 497 } else {
440   - cpu_memory_rw_debug(cpu_single_env, addr, buf, l, 0);
  498 + env = mon_get_cpu();
  499 + if (!env)
  500 + break;
  501 + cpu_memory_rw_debug(env, addr, buf, l, 0);
441 502 }
442 503 i = 0;
443 504 while (i < l) {
... ... @@ -776,10 +837,14 @@ static void print_pte(uint32_t addr, uint32_t pte, uint32_t mask)
776 837  
777 838 static void tlb_info(void)
778 839 {
779   - CPUState *env = cpu_single_env;
  840 + CPUState *env;
780 841 int l1, l2;
781 842 uint32_t pgd, pde, pte;
782 843  
  844 + env = mon_get_cpu();
  845 + if (!env)
  846 + return;
  847 +
783 848 if (!(env->cr[0] & CR0_PG_MASK)) {
784 849 term_printf("PG disabled\n");
785 850 return;
... ... @@ -830,10 +895,14 @@ static void mem_print(uint32_t *pstart, int *plast_prot,
830 895  
831 896 static void mem_info(void)
832 897 {
833   - CPUState *env = cpu_single_env;
  898 + CPUState *env;
834 899 int l1, l2, prot, last_prot;
835 900 uint32_t pgd, pde, pte, start, end;
836 901  
  902 + env = mon_get_cpu();
  903 + if (!env)
  904 + return;
  905 +
837 906 if (!(env->cr[0] & CR0_PG_MASK)) {
838 907 term_printf("PG disabled\n");
839 908 return;
... ... @@ -874,10 +943,15 @@ static void mem_info(void)
874 943 static void do_info_kqemu(void)
875 944 {
876 945 #ifdef USE_KQEMU
  946 + CPUState *env;
877 947 int val;
878 948 val = 0;
879   - if (cpu_single_env)
880   - val = cpu_single_env->kqemu_enabled;
  949 + env = mon_get_cpu();
  950 + if (!env) {
  951 + term_printf("No cpu initialized yet");
  952 + return;
  953 + }
  954 + val = env->kqemu_enabled;
881 955 term_printf("kqemu is %s\n", val ? "enabled" : "disabled");
882 956 #else
883 957 term_printf("kqemu support is not compiled\n");
... ... @@ -934,6 +1008,8 @@ static term_cmd_t term_cmds[] = {
934 1008 "device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" },
935 1009 { "usb_del", "s", do_usb_del,
936 1010 "device", "remove USB device 'bus.addr'" },
  1011 + { "cpu", "i", do_cpu_set,
  1012 + "index", "set the default CPU" },
937 1013 { NULL, NULL, },
938 1014 };
939 1015  
... ... @@ -946,6 +1022,8 @@ static term_cmd_t info_cmds[] = {
946 1022 "", "show the block devices" },
947 1023 { "registers", "", do_info_registers,
948 1024 "", "show the cpu registers" },
  1025 + { "cpus", "", do_info_cpus,
  1026 + "", "show infos for each CPU" },
949 1027 { "history", "", do_info_history,
950 1028 "", "show the command line history", },
951 1029 { "irq", "", irq_info,
... ... @@ -989,63 +1067,85 @@ typedef struct MonitorDef {
989 1067 #if defined(TARGET_I386)
990 1068 static target_long monitor_get_pc (struct MonitorDef *md, int val)
991 1069 {
992   - return cpu_single_env->eip + cpu_single_env->segs[R_CS].base;
  1070 + CPUState *env = mon_get_cpu();
  1071 + if (!env)
  1072 + return 0;
  1073 + return env->eip + env->segs[R_CS].base;
993 1074 }
994 1075 #endif
995 1076  
996 1077 #if defined(TARGET_PPC)
997 1078 static target_long monitor_get_ccr (struct MonitorDef *md, int val)
998 1079 {
  1080 + CPUState *env = mon_get_cpu();
999 1081 unsigned int u;
1000 1082 int i;
1001 1083  
  1084 + if (!env)
  1085 + return 0;
  1086 +
1002 1087 u = 0;
1003 1088 for (i = 0; i < 8; i++)
1004   - u |= cpu_single_env->crf[i] << (32 - (4 * i));
  1089 + u |= env->crf[i] << (32 - (4 * i));
1005 1090  
1006 1091 return u;
1007 1092 }
1008 1093  
1009 1094 static target_long monitor_get_msr (struct MonitorDef *md, int val)
1010 1095 {
1011   - return (cpu_single_env->msr[MSR_POW] << MSR_POW) |
1012   - (cpu_single_env->msr[MSR_ILE] << MSR_ILE) |
1013   - (cpu_single_env->msr[MSR_EE] << MSR_EE) |
1014   - (cpu_single_env->msr[MSR_PR] << MSR_PR) |
1015   - (cpu_single_env->msr[MSR_FP] << MSR_FP) |
1016   - (cpu_single_env->msr[MSR_ME] << MSR_ME) |
1017   - (cpu_single_env->msr[MSR_FE0] << MSR_FE0) |
1018   - (cpu_single_env->msr[MSR_SE] << MSR_SE) |
1019   - (cpu_single_env->msr[MSR_BE] << MSR_BE) |
1020   - (cpu_single_env->msr[MSR_FE1] << MSR_FE1) |
1021   - (cpu_single_env->msr[MSR_IP] << MSR_IP) |
1022   - (cpu_single_env->msr[MSR_IR] << MSR_IR) |
1023   - (cpu_single_env->msr[MSR_DR] << MSR_DR) |
1024   - (cpu_single_env->msr[MSR_RI] << MSR_RI) |
1025   - (cpu_single_env->msr[MSR_LE] << MSR_LE);
  1096 + CPUState *env = mon_get_cpu();
  1097 + if (!env)
  1098 + return 0;
  1099 + return (env->msr[MSR_POW] << MSR_POW) |
  1100 + (env->msr[MSR_ILE] << MSR_ILE) |
  1101 + (env->msr[MSR_EE] << MSR_EE) |
  1102 + (env->msr[MSR_PR] << MSR_PR) |
  1103 + (env->msr[MSR_FP] << MSR_FP) |
  1104 + (env->msr[MSR_ME] << MSR_ME) |
  1105 + (env->msr[MSR_FE0] << MSR_FE0) |
  1106 + (env->msr[MSR_SE] << MSR_SE) |
  1107 + (env->msr[MSR_BE] << MSR_BE) |
  1108 + (env->msr[MSR_FE1] << MSR_FE1) |
  1109 + (env->msr[MSR_IP] << MSR_IP) |
  1110 + (env->msr[MSR_IR] << MSR_IR) |
  1111 + (env->msr[MSR_DR] << MSR_DR) |
  1112 + (env->msr[MSR_RI] << MSR_RI) |
  1113 + (env->msr[MSR_LE] << MSR_LE);
1026 1114 }
1027 1115  
1028 1116 static target_long monitor_get_xer (struct MonitorDef *md, int val)
1029 1117 {
1030   - return (cpu_single_env->xer[XER_SO] << XER_SO) |
1031   - (cpu_single_env->xer[XER_OV] << XER_OV) |
1032   - (cpu_single_env->xer[XER_CA] << XER_CA) |
1033   - (cpu_single_env->xer[XER_BC] << XER_BC);
  1118 + CPUState *env = mon_get_cpu();
  1119 + if (!env)
  1120 + return 0;
  1121 + return (env->xer[XER_SO] << XER_SO) |
  1122 + (env->xer[XER_OV] << XER_OV) |
  1123 + (env->xer[XER_CA] << XER_CA) |
  1124 + (env->xer[XER_BC] << XER_BC);
1034 1125 }
1035 1126  
1036 1127 static target_long monitor_get_decr (struct MonitorDef *md, int val)
1037 1128 {
1038   - return cpu_ppc_load_decr(cpu_single_env);
  1129 + CPUState *env = mon_get_cpu();
  1130 + if (!env)
  1131 + return 0;
  1132 + return cpu_ppc_load_decr(env);
1039 1133 }
1040 1134  
1041 1135 static target_long monitor_get_tbu (struct MonitorDef *md, int val)
1042 1136 {
1043   - return cpu_ppc_load_tbu(cpu_single_env);
  1137 + CPUState *env = mon_get_cpu();
  1138 + if (!env)
  1139 + return 0;
  1140 + return cpu_ppc_load_tbu(env);
1044 1141 }
1045 1142  
1046 1143 static target_long monitor_get_tbl (struct MonitorDef *md, int val)
1047 1144 {
1048   - return cpu_ppc_load_tbl(cpu_single_env);
  1145 + CPUState *env = mon_get_cpu();
  1146 + if (!env)
  1147 + return 0;
  1148 + return cpu_ppc_load_tbl(env);
1049 1149 }
1050 1150 #endif
1051 1151  
... ... @@ -1053,13 +1153,19 @@ static target_long monitor_get_tbl (struct MonitorDef *md, int val)
1053 1153 #ifndef TARGET_SPARC64
1054 1154 static target_long monitor_get_psr (struct MonitorDef *md, int val)
1055 1155 {
1056   - return GET_PSR(cpu_single_env);
  1156 + CPUState *env = mon_get_cpu();
  1157 + if (!env)
  1158 + return 0;
  1159 + return GET_PSR(env);
1057 1160 }
1058 1161 #endif
1059 1162  
1060 1163 static target_long monitor_get_reg(struct MonitorDef *md, int val)
1061 1164 {
1062   - return cpu_single_env->regwptr[val];
  1165 + CPUState *env = mon_get_cpu();
  1166 + if (!env)
  1167 + return 0;
  1168 + return env->regwptr[val];
1063 1169 }
1064 1170 #endif
1065 1171  
... ... @@ -1269,6 +1375,7 @@ static void expr_error(const char *fmt)
1269 1375 longjmp(expr_env, 1);
1270 1376 }
1271 1377  
  1378 +/* return 0 if OK, -1 if not found, -2 if no CPU defined */
1272 1379 static int get_monitor_def(target_long *pval, const char *name)
1273 1380 {
1274 1381 MonitorDef *md;
... ... @@ -1279,7 +1386,10 @@ static int get_monitor_def(target_long *pval, const char *name)
1279 1386 if (md->get_value) {
1280 1387 *pval = md->get_value(md, md->offset);
1281 1388 } else {
1282   - ptr = (uint8_t *)cpu_single_env + md->offset;
  1389 + CPUState *env = mon_get_cpu();
  1390 + if (!env)
  1391 + return -2;
  1392 + ptr = (uint8_t *)env + md->offset;
1283 1393 switch(md->type) {
1284 1394 case MD_I32:
1285 1395 *pval = *(int32_t *)ptr;
... ... @@ -1313,6 +1423,7 @@ static target_long expr_unary(void)
1313 1423 {
1314 1424 target_long n;
1315 1425 char *p;
  1426 + int ret;
1316 1427  
1317 1428 switch(*pch) {
1318 1429 case '+':
... ... @@ -1362,8 +1473,11 @@ static target_long expr_unary(void)
1362 1473 while (isspace(*pch))
1363 1474 pch++;
1364 1475 *q = 0;
1365   - if (get_monitor_def(&n, buf))
  1476 + ret = get_monitor_def(&n, buf);
  1477 + if (ret == -1)
1366 1478 expr_error("unknown register");
  1479 + else if (ret == -2)
  1480 + expr_error("no cpu defined");
1367 1481 }
1368 1482 break;
1369 1483 case '\0':
... ...
... ... @@ -83,8 +83,6 @@
83 83  
84 84 #include "exec-all.h"
85 85  
86   -//#define DO_TB_FLUSH
87   -
88 86 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
89 87  
90 88 //#define DEBUG_UNUSED_IOPORT
... ... @@ -109,8 +107,6 @@
109 107  
110 108 const char *bios_dir = CONFIG_QEMU_SHAREDIR;
111 109 char phys_ram_file[1024];
112   -CPUState *global_env;
113   -CPUState *cpu_single_env;
114 110 void *ioport_opaque[MAX_IOPORTS];
115 111 IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
116 112 IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
... ... @@ -156,6 +152,7 @@ int usb_enabled = 0;
156 152 USBPort *vm_usb_ports[MAX_VM_USB_PORTS];
157 153 USBDevice *vm_usb_hub;
158 154 static VLANState *first_vlan;
  155 +int smp_cpus = 1;
159 156  
160 157 /***********************************************************/
161 158 /* x86 ISA bus support */
... ... @@ -427,16 +424,20 @@ int cpu_inl(CPUState *env, int addr)
427 424 void hw_error(const char *fmt, ...)
428 425 {
429 426 va_list ap;
  427 + CPUState *env;
430 428  
431 429 va_start(ap, fmt);
432 430 fprintf(stderr, "qemu: hardware error: ");
433 431 vfprintf(stderr, fmt, ap);
434 432 fprintf(stderr, "\n");
  433 + for(env = first_cpu; env != NULL; env = env->next_cpu) {
  434 + fprintf(stderr, "CPU #%d:\n", env->cpu_index);
435 435 #ifdef TARGET_I386
436   - cpu_dump_state(global_env, stderr, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP);
  436 + cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU);
437 437 #else
438   - cpu_dump_state(global_env, stderr, fprintf, 0);
  438 + cpu_dump_state(env, stderr, fprintf, 0);
439 439 #endif
  440 + }
440 441 va_end(ap);
441 442 abort();
442 443 }
... ... @@ -879,13 +880,16 @@ static void host_alarm_handler(int host_signum)
879 880 qemu_get_clock(vm_clock)) ||
880 881 qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
881 882 qemu_get_clock(rt_clock))) {
882   - /* stop the cpu because a timer occured */
883   - cpu_interrupt(global_env, CPU_INTERRUPT_EXIT);
  883 + CPUState *env = cpu_single_env;
  884 + if (env) {
  885 + /* stop the currently executing cpu because a timer occured */
  886 + cpu_interrupt(env, CPU_INTERRUPT_EXIT);
884 887 #ifdef USE_KQEMU
885   - if (global_env->kqemu_enabled) {
886   - kqemu_cpu_interrupt(global_env);
887   - }
  888 + if (env->kqemu_enabled) {
  889 + kqemu_cpu_interrupt(env);
  890 + }
888 891 #endif
  892 + }
889 893 }
890 894 }
891 895  
... ... @@ -2970,9 +2974,6 @@ int qemu_loadvm(const char *filename)
2970 2974 goto the_end;
2971 2975 }
2972 2976 for(;;) {
2973   -#if defined (DO_TB_FLUSH)
2974   - tb_flush(global_env);
2975   -#endif
2976 2977 len = qemu_get_byte(f);
2977 2978 if (feof(f))
2978 2979 break;
... ... @@ -3583,27 +3584,22 @@ void qemu_system_reset(void)
3583 3584 void qemu_system_reset_request(void)
3584 3585 {
3585 3586 reset_requested = 1;
3586   - cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
  3587 + if (cpu_single_env)
  3588 + cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
3587 3589 }
3588 3590  
3589 3591 void qemu_system_shutdown_request(void)
3590 3592 {
3591 3593 shutdown_requested = 1;
3592   - cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
  3594 + if (cpu_single_env)
  3595 + cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
3593 3596 }
3594 3597  
3595 3598 void qemu_system_powerdown_request(void)
3596 3599 {
3597 3600 powerdown_requested = 1;
3598   - cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
3599   -}
3600   -
3601   -static void main_cpu_reset(void *opaque)
3602   -{
3603   -#if defined(TARGET_I386) || defined(TARGET_SPARC)
3604   - CPUState *env = opaque;
3605   - cpu_reset(env);
3606   -#endif
  3601 + if (cpu_single_env)
  3602 + cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
3607 3603 }
3608 3604  
3609 3605 void main_loop_wait(int timeout)
... ... @@ -3684,14 +3680,42 @@ void main_loop_wait(int timeout)
3684 3680 qemu_get_clock(rt_clock));
3685 3681 }
3686 3682  
  3683 +static CPUState *cur_cpu;
  3684 +
  3685 +static CPUState *find_next_cpu(void)
  3686 +{
  3687 + CPUState *env;
  3688 + env = cur_cpu;
  3689 + for(;;) {
  3690 + /* get next cpu */
  3691 + env = env->next_cpu;
  3692 + if (!env)
  3693 + env = first_cpu;
  3694 + if (!env->cpu_halted)
  3695 + break;
  3696 + /* all CPUs are halted ? */
  3697 + if (env == cur_cpu)
  3698 + return NULL;
  3699 + }
  3700 + cur_cpu = env;
  3701 + return env;
  3702 +}
  3703 +
3687 3704 int main_loop(void)
3688 3705 {
3689 3706 int ret, timeout;
3690   - CPUState *env = global_env;
  3707 + CPUState *env;
3691 3708  
  3709 + cur_cpu = first_cpu;
3692 3710 for(;;) {
3693 3711 if (vm_running) {
3694   - ret = cpu_exec(env);
  3712 + /* find next cpu to run */
  3713 + /* XXX: handle HLT correctly */
  3714 + env = find_next_cpu();
  3715 + if (!env)
  3716 + ret = EXCP_HLT;
  3717 + else
  3718 + ret = cpu_exec(env);
3695 3719 if (shutdown_requested) {
3696 3720 ret = EXCP_INTERRUPT;
3697 3721 break;
... ... @@ -3774,7 +3798,7 @@ void help(void)
3774 3798 " connect the host TAP network interface to VLAN 'n' and use\n"
3775 3799 " the network script 'file' (default=%s);\n"
3776 3800 " use 'fd=h' to connect to an already opened TAP interface\n"
3777   - "-net socket[,vlan=n][,fd=x][,listen=[host]:port][,connect=host:port]\n"
  3801 + "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
3778 3802 " connect the vlan 'n' to another VLAN using a socket connection\n"
3779 3803 #endif
3780 3804 "-net none use it alone to have zero network devices; if no -net option\n"
... ... @@ -3899,6 +3923,7 @@ enum {
3899 3923 QEMU_OPTION_win2k_hack,
3900 3924 QEMU_OPTION_usb,
3901 3925 QEMU_OPTION_usbdevice,
  3926 + QEMU_OPTION_smp,
3902 3927 };
3903 3928  
3904 3929 typedef struct QEMUOption {
... ... @@ -3965,6 +3990,7 @@ const QEMUOption qemu_options[] = {
3965 3990 { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
3966 3991 { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
3967 3992 { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
  3993 + { "smp", HAS_ARG, QEMU_OPTION_smp },
3968 3994  
3969 3995 /* temporary options */
3970 3996 { "usb", 0, QEMU_OPTION_usb },
... ... @@ -4120,7 +4146,6 @@ int main(int argc, char **argv)
4120 4146 #endif
4121 4147 int i, cdrom_index;
4122 4148 int snapshot, linux_boot;
4123   - CPUState *env;
4124 4149 const char *initrd_filename;
4125 4150 const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
4126 4151 const char *kernel_filename, *kernel_cmdline;
... ... @@ -4511,6 +4536,13 @@ int main(int argc, char **argv)
4511 4536 optarg);
4512 4537 usb_devices_index++;
4513 4538 break;
  4539 + case QEMU_OPTION_smp:
  4540 + smp_cpus = atoi(optarg);
  4541 + if (smp_cpus < 1 || smp_cpus > 8) {
  4542 + fprintf(stderr, "Invalid number of CPUs\n");
  4543 + exit(1);
  4544 + }
  4545 + break;
4514 4546 }
4515 4547 }
4516 4548 }
... ... @@ -4659,15 +4691,8 @@ int main(int argc, char **argv)
4659 4691 }
4660 4692 }
4661 4693  
4662   - /* init CPU state */
4663   - env = cpu_init();
4664   - global_env = env;
4665   - cpu_single_env = env;
4666   -
4667   - register_savevm("timer", 0, 1, timer_save, timer_load, env);
4668   - register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
  4694 + register_savevm("timer", 0, 1, timer_save, timer_load, NULL);
4669 4695 register_savevm("ram", 0, 1, ram_save, ram_load, NULL);
4670   - qemu_register_reset(main_cpu_reset, global_env);
4671 4696  
4672 4697 init_ioports();
4673 4698 cpu_calibrate_ticks();
... ...
... ... @@ -142,6 +142,7 @@ extern const char *keyboard_layout;
142 142 extern int kqemu_allowed;
143 143 extern int win2k_install_hack;
144 144 extern int usb_enabled;
  145 +extern int smp_cpus;
145 146  
146 147 /* XXX: make it dynamic */
147 148 #if defined (TARGET_PPC)
... ... @@ -429,6 +430,9 @@ int register_savevm(const char *idstr,
429 430 void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
430 431 void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
431 432  
  433 +void cpu_save(QEMUFile *f, void *opaque);
  434 +int cpu_load(QEMUFile *f, void *opaque, int version_id);
  435 +
432 436 /* block.c */
433 437 typedef struct BlockDriverState BlockDriverState;
434 438 typedef struct BlockDriver BlockDriver;
... ... @@ -774,6 +778,9 @@ int pit_get_out(PITState *pit, int channel, int64_t current_time);
774 778 extern QEMUMachine pc_machine;
775 779 extern QEMUMachine isapc_machine;
776 780  
  781 +void ioport_set_a20(int enable);
  782 +int ioport_get_a20(void);
  783 +
777 784 /* ppc.c */
778 785 extern QEMUMachine prep_machine;
779 786 extern QEMUMachine core99_machine;
... ...