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,6 +96,7 @@ typedef struct CPUTLBEntry {
96 96
97 #define CPU_COMMON \ 97 #define CPU_COMMON \
98 struct TranslationBlock *current_tb; /* currently executing TB */ \ 98 struct TranslationBlock *current_tb; /* currently executing TB */ \
  99 + int cpu_halted; /* TRUE if cpu is halted (sleep mode) */ \
99 /* soft mmu support */ \ 100 /* soft mmu support */ \
100 /* in order to avoid passing too many arguments to the memory \ 101 /* in order to avoid passing too many arguments to the memory \
101 write helpers, we store some rarely used information in the CPU \ 102 write helpers, we store some rarely used information in the CPU \
@@ -115,9 +116,9 @@ typedef struct CPUTLBEntry { @@ -115,9 +116,9 @@ typedef struct CPUTLBEntry {
115 int nb_breakpoints; \ 116 int nb_breakpoints; \
116 int singlestep_enabled; \ 117 int singlestep_enabled; \
117 \ 118 \
  119 + void *next_cpu; /* next CPU sharing TB cache */ \
  120 + int cpu_index; /* CPU index (informative) */ \
118 /* user data */ \ 121 /* user data */ \
119 void *opaque; 122 void *opaque;
120 123
121 -  
122 -  
123 #endif 124 #endif
cpu-exec.c
@@ -251,6 +251,8 @@ int cpu_exec(CPUState *env1) @@ -251,6 +251,8 @@ int cpu_exec(CPUState *env1)
251 TranslationBlock *tb; 251 TranslationBlock *tb;
252 uint8_t *tc_ptr; 252 uint8_t *tc_ptr;
253 253
  254 + cpu_single_env = env1;
  255 +
254 /* first we save global registers */ 256 /* first we save global registers */
255 saved_env = env; 257 saved_env = env;
256 env = env1; 258 env = env1;
@@ -755,6 +757,8 @@ int cpu_exec(CPUState *env1) @@ -755,6 +757,8 @@ int cpu_exec(CPUState *env1)
755 T2 = saved_T2; 757 T2 = saved_T2;
756 #endif 758 #endif
757 env = saved_env; 759 env = saved_env;
  760 + /* fail safe : never use cpu_single_env outside cpu_exec() */
  761 + cpu_single_env = NULL;
758 return ret; 762 return ret;
759 } 763 }
760 764
@@ -138,6 +138,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info) @@ -138,6 +138,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
138 values: 138 values:
139 i386 - nonzero means 16 bit code 139 i386 - nonzero means 16 bit code
140 arm - nonzero means thumb code 140 arm - nonzero means thumb code
  141 + ppc - nonzero means little endian
141 other targets - unused 142 other targets - unused
142 */ 143 */
143 void target_disas(FILE *out, target_ulong code, target_ulong size, int flags) 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,7 +178,7 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
177 disasm_info.mach = bfd_mach_sparc_v9b; 178 disasm_info.mach = bfd_mach_sparc_v9b;
178 #endif 179 #endif
179 #elif defined(TARGET_PPC) 180 #elif defined(TARGET_PPC)
180 - if (cpu_single_env->msr[MSR_LE]) 181 + if (flags)
181 disasm_info.endian = BFD_ENDIAN_LITTLE; 182 disasm_info.endian = BFD_ENDIAN_LITTLE;
182 #ifdef TARGET_PPC64 183 #ifdef TARGET_PPC64
183 disasm_info.mach = bfd_mach_ppc64; 184 disasm_info.mach = bfd_mach_ppc64;
@@ -314,6 +315,7 @@ void term_vprintf(const char *fmt, va_list ap); @@ -314,6 +315,7 @@ void term_vprintf(const char *fmt, va_list ap);
314 void term_printf(const char *fmt, ...); 315 void term_printf(const char *fmt, ...);
315 316
316 static int monitor_disas_is_physical; 317 static int monitor_disas_is_physical;
  318 +static CPUState *monitor_disas_env;
317 319
318 static int 320 static int
319 monitor_read_memory (memaddr, myaddr, length, info) 321 monitor_read_memory (memaddr, myaddr, length, info)
@@ -325,7 +327,7 @@ monitor_read_memory (memaddr, myaddr, length, info) @@ -325,7 +327,7 @@ monitor_read_memory (memaddr, myaddr, length, info)
325 if (monitor_disas_is_physical) { 327 if (monitor_disas_is_physical) {
326 cpu_physical_memory_rw(memaddr, myaddr, length, 0); 328 cpu_physical_memory_rw(memaddr, myaddr, length, 0);
327 } else { 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 return 0; 332 return 0;
331 } 333 }
@@ -339,7 +341,8 @@ static int monitor_fprintf(FILE *stream, const char *fmt, ...) @@ -339,7 +341,8 @@ static int monitor_fprintf(FILE *stream, const char *fmt, ...)
339 return 0; 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 int count, i; 347 int count, i;
345 struct disassemble_info disasm_info; 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,6 +350,7 @@ void monitor_disas(target_ulong pc, int nb_insn, int is_physical, int flags)
347 350
348 INIT_DISASSEMBLE_INFO(disasm_info, NULL, monitor_fprintf); 351 INIT_DISASSEMBLE_INFO(disasm_info, NULL, monitor_fprintf);
349 352
  353 + monitor_disas_env = env;
350 monitor_disas_is_physical = is_physical; 354 monitor_disas_is_physical = is_physical;
351 disasm_info.read_memory_func = monitor_read_memory; 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,7 +91,7 @@ int cpu_restore_state_copy(struct TranslationBlock *tb,
91 CPUState *env, unsigned long searched_pc, 91 CPUState *env, unsigned long searched_pc,
92 void *puc); 92 void *puc);
93 void cpu_resume_from_signal(CPUState *env1, void *puc); 93 void cpu_resume_from_signal(CPUState *env1, void *puc);
94 -void cpu_exec_init(void); 94 +void cpu_exec_init(CPUState *env);
95 int page_unprotect(unsigned long address, unsigned long pc, void *puc); 95 int page_unprotect(unsigned long address, unsigned long pc, void *puc);
96 void tb_invalidate_phys_page_range(target_ulong start, target_ulong end, 96 void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
97 int is_cpu_write_access); 97 int is_cpu_write_access);
@@ -74,6 +74,11 @@ int phys_ram_fd; @@ -74,6 +74,11 @@ int phys_ram_fd;
74 uint8_t *phys_ram_base; 74 uint8_t *phys_ram_base;
75 uint8_t *phys_ram_dirty; 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 typedef struct PageDesc { 82 typedef struct PageDesc {
78 /* list of TBs intersecting this ram page */ 83 /* list of TBs intersecting this ram page */
79 TranslationBlock *first_tb; 84 TranslationBlock *first_tb;
@@ -233,19 +238,30 @@ static inline PhysPageDesc *phys_page_find(target_phys_addr_t index) @@ -233,19 +238,30 @@ static inline PhysPageDesc *phys_page_find(target_phys_addr_t index)
233 } 238 }
234 239
235 #if !defined(CONFIG_USER_ONLY) 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 static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr, 242 static void tlb_unprotect_code_phys(CPUState *env, ram_addr_t ram_addr,
239 target_ulong vaddr); 243 target_ulong vaddr);
240 #endif 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 if (!code_gen_ptr) { 251 if (!code_gen_ptr) {
245 code_gen_ptr = code_gen_buffer; 252 code_gen_ptr = code_gen_buffer;
246 page_init(); 253 page_init();
247 io_mem_init(); 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 static inline void invalidate_page_bitmap(PageDesc *p) 267 static inline void invalidate_page_bitmap(PageDesc *p)
@@ -277,8 +293,9 @@ static void page_flush_tb(void) @@ -277,8 +293,9 @@ static void page_flush_tb(void)
277 293
278 /* flush all the translation blocks */ 294 /* flush all the translation blocks */
279 /* XXX: tb_flush is currently not thread safe */ 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 #if defined(DEBUG_FLUSH) 299 #if defined(DEBUG_FLUSH)
283 printf("qemu: flush code_size=%d nb_tbs=%d avg_tb_size=%d\n", 300 printf("qemu: flush code_size=%d nb_tbs=%d avg_tb_size=%d\n",
284 code_gen_ptr - code_gen_buffer, 301 code_gen_ptr - code_gen_buffer,
@@ -286,7 +303,10 @@ void tb_flush(CPUState *env) @@ -286,7 +303,10 @@ void tb_flush(CPUState *env)
286 nb_tbs > 0 ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0); 303 nb_tbs > 0 ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0);
287 #endif 304 #endif
288 nb_tbs = 0; 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 memset (tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof (void *)); 311 memset (tb_phys_hash, 0, CODE_GEN_PHYS_HASH_SIZE * sizeof (void *));
292 page_flush_tb(); 312 page_flush_tb();
@@ -424,6 +444,7 @@ static inline void tb_reset_jump(TranslationBlock *tb, int n) @@ -424,6 +444,7 @@ static inline void tb_reset_jump(TranslationBlock *tb, int n)
424 444
425 static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_addr) 445 static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_addr)
426 { 446 {
  447 + CPUState *env;
427 PageDesc *p; 448 PageDesc *p;
428 unsigned int h, n1; 449 unsigned int h, n1;
429 target_ulong phys_pc; 450 target_ulong phys_pc;
@@ -451,7 +472,10 @@ static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_ad @@ -451,7 +472,10 @@ static inline void tb_phys_invalidate(TranslationBlock *tb, unsigned int page_ad
451 472
452 /* remove the TB from the hash list */ 473 /* remove the TB from the hash list */
453 h = tb_jmp_cache_hash_func(tb->pc); 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 /* suppress this TB from the two jump lists */ 480 /* suppress this TB from the two jump lists */
457 tb_jmp_remove(tb, 0); 481 tb_jmp_remove(tb, 0);
@@ -818,10 +842,7 @@ static inline void tb_alloc_page(TranslationBlock *tb, @@ -818,10 +842,7 @@ static inline void tb_alloc_page(TranslationBlock *tb,
818 protected. So we handle the case where only the first TB is 842 protected. So we handle the case where only the first TB is
819 allocated in a physical page */ 843 allocated in a physical page */
820 if (!last_first_tb) { 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 #endif 847 #endif
827 848
@@ -1246,40 +1267,13 @@ void tlb_flush_page(CPUState *env, target_ulong addr) @@ -1246,40 +1267,13 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
1246 #endif 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 /* update the TLBs so that writes to code in the virtual page 'addr' 1270 /* update the TLBs so that writes to code in the virtual page 'addr'
1259 can be detected */ 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 /* update the TLB so that writes in physical page 'phys_addr' are no longer 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,8 +1311,9 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
1317 if (length == 0) 1311 if (length == 0)
1318 return; 1312 return;
1319 len = length >> TARGET_PAGE_BITS; 1313 len = length >> TARGET_PAGE_BITS;
1320 - env = cpu_single_env;  
1321 #ifdef USE_KQEMU 1314 #ifdef USE_KQEMU
  1315 + /* XXX: should not depend on cpu context */
  1316 + env = first_cpu;
1322 if (env->kqemu_enabled) { 1317 if (env->kqemu_enabled) {
1323 ram_addr_t addr; 1318 ram_addr_t addr;
1324 addr = start; 1319 addr = start;
@@ -1336,10 +1331,12 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, @@ -1336,10 +1331,12 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
1336 /* we modify the TLB cache so that the dirty bit will be set again 1331 /* we modify the TLB cache so that the dirty bit will be set again
1337 when accessing the range */ 1332 when accessing the range */
1338 start1 = start + (unsigned long)phys_ram_base; 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 #if !defined(CONFIG_SOFTMMU) 1341 #if !defined(CONFIG_SOFTMMU)
1345 /* XXX: this is expensive */ 1342 /* XXX: this is expensive */
@@ -1407,9 +1404,9 @@ static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, @@ -1407,9 +1404,9 @@ static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
1407 1404
1408 /* update the TLB corresponding to virtual page vaddr and phys addr 1405 /* update the TLB corresponding to virtual page vaddr and phys addr
1409 addr so that it is no longer dirty */ 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 int i; 1410 int i;
1414 1411
1415 addr &= TARGET_PAGE_MASK; 1412 addr &= TARGET_PAGE_MASK;
@@ -1723,7 +1720,8 @@ void page_unprotect_range(uint8_t *data, unsigned long data_size) @@ -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 #endif /* defined(CONFIG_USER_ONLY) */ 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,7 +1785,7 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t
1787 /* we remove the notdirty callback only if the code has been 1785 /* we remove the notdirty callback only if the code has been
1788 flushed */ 1786 flushed */
1789 if (dirty_flags == 0xff) 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 static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) 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,7 +1806,7 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t
1808 /* we remove the notdirty callback only if the code has been 1806 /* we remove the notdirty callback only if the code has been
1809 flushed */ 1807 flushed */
1810 if (dirty_flags == 0xff) 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 static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) 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,7 +1827,7 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t
1829 /* we remove the notdirty callback only if the code has been 1827 /* we remove the notdirty callback only if the code has been
1830 flushed */ 1828 flushed */
1831 if (dirty_flags == 0xff) 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 static CPUReadMemoryFunc *error_mem_read[3] = { 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,6 +1951,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
1953 if (is_write) { 1951 if (is_write) {
1954 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { 1952 if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
1955 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); 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 if (l >= 4 && ((addr & 3) == 0)) { 1956 if (l >= 4 && ((addr & 3) == 0)) {
1957 /* 32 bit write access */ 1957 /* 32 bit write access */
1958 val = ldl_p(buf); 1958 val = ldl_p(buf);
gdbstub.c
@@ -47,6 +47,7 @@ enum RSState { @@ -47,6 +47,7 @@ enum RSState {
47 static int gdbserver_fd = -1; 47 static int gdbserver_fd = -1;
48 48
49 typedef struct GDBState { 49 typedef struct GDBState {
  50 + CPUState *env; /* current CPU */
50 enum RSState state; /* parsing state */ 51 enum RSState state; /* parsing state */
51 int fd; 52 int fd;
52 char line_buf[4096]; 53 char line_buf[4096];
@@ -576,10 +577,10 @@ static void gdb_vm_stopped(void *opaque, int reason) @@ -576,10 +577,10 @@ static void gdb_vm_stopped(void *opaque, int reason)
576 int ret; 577 int ret;
577 578
578 /* disable single step if it was enable */ 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 if (reason == EXCP_DEBUG) { 582 if (reason == EXCP_DEBUG) {
582 - tb_flush(cpu_single_env); 583 + tb_flush(s->env);
583 ret = SIGTRAP; 584 ret = SIGTRAP;
584 } 585 }
585 else 586 else
@@ -589,8 +590,9 @@ static void gdb_vm_stopped(void *opaque, int reason) @@ -589,8 +590,9 @@ static void gdb_vm_stopped(void *opaque, int reason)
589 } 590 }
590 #endif 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 int i, csum; 596 int i, csum;
595 char reply[1]; 597 char reply[1];
596 598
@@ -676,7 +678,7 @@ gdb_handlesig (CPUState *env, int sig) @@ -676,7 +678,7 @@ gdb_handlesig (CPUState *env, int sig)
676 int i; 678 int i;
677 679
678 for (i = 0; i < n; i++) 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 else if (n == 0 || errno != EAGAIN) 683 else if (n == 0 || errno != EAGAIN)
682 { 684 {
@@ -721,7 +723,7 @@ static void gdb_read(void *opaque) @@ -721,7 +723,7 @@ static void gdb_read(void *opaque)
721 vm_start(); 723 vm_start();
722 } else { 724 } else {
723 for(i = 0; i < size; i++) 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,6 +761,7 @@ static void gdb_accept(void *opaque)
759 return; 761 return;
760 } 762 }
761 #endif 763 #endif
  764 + s->env = first_cpu; /* XXX: allow to change CPU */
762 s->fd = fd; 765 s->fd = fd;
763 766
764 fcntl(fd, F_SETFL, O_NONBLOCK); 767 fcntl(fd, F_SETFL, O_NONBLOCK);
monitor.c
@@ -64,6 +64,8 @@ static int term_outbuf_index; @@ -64,6 +64,8 @@ static int term_outbuf_index;
64 64
65 static void monitor_start_input(void); 65 static void monitor_start_input(void);
66 66
  67 +CPUState *mon_cpu = NULL;
  68 +
67 void term_flush(void) 69 void term_flush(void)
68 { 70 {
69 if (term_outbuf_index > 0) { 71 if (term_outbuf_index > 0) {
@@ -201,17 +203,69 @@ static void do_info_block(void) @@ -201,17 +203,69 @@ static void do_info_block(void)
201 bdrv_info(); 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 static void do_info_registers(void) 228 static void do_info_registers(void)
205 { 229 {
  230 + CPUState *env;
  231 + env = mon_get_cpu();
  232 + if (!env)
  233 + return;
206 #ifdef TARGET_I386 234 #ifdef TARGET_I386
207 - cpu_dump_state(cpu_single_env, NULL, monitor_fprintf, 235 + cpu_dump_state(env, NULL, monitor_fprintf,
208 X86_DUMP_FPU); 236 X86_DUMP_FPU);
209 #else 237 #else
210 - cpu_dump_state(cpu_single_env, NULL, monitor_fprintf, 238 + cpu_dump_state(env, NULL, monitor_fprintf,
211 0); 239 0);
212 #endif 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 static void do_info_jit(void) 269 static void do_info_jit(void)
216 { 270 {
217 dump_exec_info(NULL, monitor_fprintf); 271 dump_exec_info(NULL, monitor_fprintf);
@@ -381,6 +435,7 @@ static void term_printc(int c) @@ -381,6 +435,7 @@ static void term_printc(int c)
381 static void memory_dump(int count, int format, int wsize, 435 static void memory_dump(int count, int format, int wsize,
382 target_ulong addr, int is_physical) 436 target_ulong addr, int is_physical)
383 { 437 {
  438 + CPUState *env;
384 int nb_per_line, l, line_size, i, max_digits, len; 439 int nb_per_line, l, line_size, i, max_digits, len;
385 uint8_t buf[16]; 440 uint8_t buf[16];
386 uint64_t v; 441 uint64_t v;
@@ -388,19 +443,22 @@ static void memory_dump(int count, int format, int wsize, @@ -388,19 +443,22 @@ static void memory_dump(int count, int format, int wsize,
388 if (format == 'i') { 443 if (format == 'i') {
389 int flags; 444 int flags;
390 flags = 0; 445 flags = 0;
  446 + env = mon_get_cpu();
  447 + if (!env && !is_physical)
  448 + return;
391 #ifdef TARGET_I386 449 #ifdef TARGET_I386
392 if (wsize == 2) { 450 if (wsize == 2) {
393 flags = 1; 451 flags = 1;
394 } else if (wsize == 4) { 452 } else if (wsize == 4) {
395 flags = 0; 453 flags = 0;
396 } else { 454 } else {
397 - /* as default we use the current CS size */ 455 + /* as default we use the current CS size */
398 flags = 0; 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 flags = 1; 458 flags = 1;
401 } 459 }
402 #endif 460 #endif
403 - monitor_disas(addr, count, is_physical, flags); 461 + monitor_disas(env, addr, count, is_physical, flags);
404 return; 462 return;
405 } 463 }
406 464
@@ -437,7 +495,10 @@ static void memory_dump(int count, int format, int wsize, @@ -437,7 +495,10 @@ static void memory_dump(int count, int format, int wsize,
437 if (is_physical) { 495 if (is_physical) {
438 cpu_physical_memory_rw(addr, buf, l, 0); 496 cpu_physical_memory_rw(addr, buf, l, 0);
439 } else { 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 i = 0; 503 i = 0;
443 while (i < l) { 504 while (i < l) {
@@ -776,10 +837,14 @@ static void print_pte(uint32_t addr, uint32_t pte, uint32_t mask) @@ -776,10 +837,14 @@ static void print_pte(uint32_t addr, uint32_t pte, uint32_t mask)
776 837
777 static void tlb_info(void) 838 static void tlb_info(void)
778 { 839 {
779 - CPUState *env = cpu_single_env; 840 + CPUState *env;
780 int l1, l2; 841 int l1, l2;
781 uint32_t pgd, pde, pte; 842 uint32_t pgd, pde, pte;
782 843
  844 + env = mon_get_cpu();
  845 + if (!env)
  846 + return;
  847 +
783 if (!(env->cr[0] & CR0_PG_MASK)) { 848 if (!(env->cr[0] & CR0_PG_MASK)) {
784 term_printf("PG disabled\n"); 849 term_printf("PG disabled\n");
785 return; 850 return;
@@ -830,10 +895,14 @@ static void mem_print(uint32_t *pstart, int *plast_prot, @@ -830,10 +895,14 @@ static void mem_print(uint32_t *pstart, int *plast_prot,
830 895
831 static void mem_info(void) 896 static void mem_info(void)
832 { 897 {
833 - CPUState *env = cpu_single_env; 898 + CPUState *env;
834 int l1, l2, prot, last_prot; 899 int l1, l2, prot, last_prot;
835 uint32_t pgd, pde, pte, start, end; 900 uint32_t pgd, pde, pte, start, end;
836 901
  902 + env = mon_get_cpu();
  903 + if (!env)
  904 + return;
  905 +
837 if (!(env->cr[0] & CR0_PG_MASK)) { 906 if (!(env->cr[0] & CR0_PG_MASK)) {
838 term_printf("PG disabled\n"); 907 term_printf("PG disabled\n");
839 return; 908 return;
@@ -874,10 +943,15 @@ static void mem_info(void) @@ -874,10 +943,15 @@ static void mem_info(void)
874 static void do_info_kqemu(void) 943 static void do_info_kqemu(void)
875 { 944 {
876 #ifdef USE_KQEMU 945 #ifdef USE_KQEMU
  946 + CPUState *env;
877 int val; 947 int val;
878 val = 0; 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 term_printf("kqemu is %s\n", val ? "enabled" : "disabled"); 955 term_printf("kqemu is %s\n", val ? "enabled" : "disabled");
882 #else 956 #else
883 term_printf("kqemu support is not compiled\n"); 957 term_printf("kqemu support is not compiled\n");
@@ -934,6 +1008,8 @@ static term_cmd_t term_cmds[] = { @@ -934,6 +1008,8 @@ static term_cmd_t term_cmds[] = {
934 "device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" }, 1008 "device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" },
935 { "usb_del", "s", do_usb_del, 1009 { "usb_del", "s", do_usb_del,
936 "device", "remove USB device 'bus.addr'" }, 1010 "device", "remove USB device 'bus.addr'" },
  1011 + { "cpu", "i", do_cpu_set,
  1012 + "index", "set the default CPU" },
937 { NULL, NULL, }, 1013 { NULL, NULL, },
938 }; 1014 };
939 1015
@@ -946,6 +1022,8 @@ static term_cmd_t info_cmds[] = { @@ -946,6 +1022,8 @@ static term_cmd_t info_cmds[] = {
946 "", "show the block devices" }, 1022 "", "show the block devices" },
947 { "registers", "", do_info_registers, 1023 { "registers", "", do_info_registers,
948 "", "show the cpu registers" }, 1024 "", "show the cpu registers" },
  1025 + { "cpus", "", do_info_cpus,
  1026 + "", "show infos for each CPU" },
949 { "history", "", do_info_history, 1027 { "history", "", do_info_history,
950 "", "show the command line history", }, 1028 "", "show the command line history", },
951 { "irq", "", irq_info, 1029 { "irq", "", irq_info,
@@ -989,63 +1067,85 @@ typedef struct MonitorDef { @@ -989,63 +1067,85 @@ typedef struct MonitorDef {
989 #if defined(TARGET_I386) 1067 #if defined(TARGET_I386)
990 static target_long monitor_get_pc (struct MonitorDef *md, int val) 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 #endif 1075 #endif
995 1076
996 #if defined(TARGET_PPC) 1077 #if defined(TARGET_PPC)
997 static target_long monitor_get_ccr (struct MonitorDef *md, int val) 1078 static target_long monitor_get_ccr (struct MonitorDef *md, int val)
998 { 1079 {
  1080 + CPUState *env = mon_get_cpu();
999 unsigned int u; 1081 unsigned int u;
1000 int i; 1082 int i;
1001 1083
  1084 + if (!env)
  1085 + return 0;
  1086 +
1002 u = 0; 1087 u = 0;
1003 for (i = 0; i < 8; i++) 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 return u; 1091 return u;
1007 } 1092 }
1008 1093
1009 static target_long monitor_get_msr (struct MonitorDef *md, int val) 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 static target_long monitor_get_xer (struct MonitorDef *md, int val) 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 static target_long monitor_get_decr (struct MonitorDef *md, int val) 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 static target_long monitor_get_tbu (struct MonitorDef *md, int val) 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 static target_long monitor_get_tbl (struct MonitorDef *md, int val) 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 #endif 1150 #endif
1051 1151
@@ -1053,13 +1153,19 @@ static target_long monitor_get_tbl (struct MonitorDef *md, int val) @@ -1053,13 +1153,19 @@ static target_long monitor_get_tbl (struct MonitorDef *md, int val)
1053 #ifndef TARGET_SPARC64 1153 #ifndef TARGET_SPARC64
1054 static target_long monitor_get_psr (struct MonitorDef *md, int val) 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 #endif 1161 #endif
1059 1162
1060 static target_long monitor_get_reg(struct MonitorDef *md, int val) 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 #endif 1170 #endif
1065 1171
@@ -1269,6 +1375,7 @@ static void expr_error(const char *fmt) @@ -1269,6 +1375,7 @@ static void expr_error(const char *fmt)
1269 longjmp(expr_env, 1); 1375 longjmp(expr_env, 1);
1270 } 1376 }
1271 1377
  1378 +/* return 0 if OK, -1 if not found, -2 if no CPU defined */
1272 static int get_monitor_def(target_long *pval, const char *name) 1379 static int get_monitor_def(target_long *pval, const char *name)
1273 { 1380 {
1274 MonitorDef *md; 1381 MonitorDef *md;
@@ -1279,7 +1386,10 @@ static int get_monitor_def(target_long *pval, const char *name) @@ -1279,7 +1386,10 @@ static int get_monitor_def(target_long *pval, const char *name)
1279 if (md->get_value) { 1386 if (md->get_value) {
1280 *pval = md->get_value(md, md->offset); 1387 *pval = md->get_value(md, md->offset);
1281 } else { 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 switch(md->type) { 1393 switch(md->type) {
1284 case MD_I32: 1394 case MD_I32:
1285 *pval = *(int32_t *)ptr; 1395 *pval = *(int32_t *)ptr;
@@ -1313,6 +1423,7 @@ static target_long expr_unary(void) @@ -1313,6 +1423,7 @@ static target_long expr_unary(void)
1313 { 1423 {
1314 target_long n; 1424 target_long n;
1315 char *p; 1425 char *p;
  1426 + int ret;
1316 1427
1317 switch(*pch) { 1428 switch(*pch) {
1318 case '+': 1429 case '+':
@@ -1362,8 +1473,11 @@ static target_long expr_unary(void) @@ -1362,8 +1473,11 @@ static target_long expr_unary(void)
1362 while (isspace(*pch)) 1473 while (isspace(*pch))
1363 pch++; 1474 pch++;
1364 *q = 0; 1475 *q = 0;
1365 - if (get_monitor_def(&n, buf)) 1476 + ret = get_monitor_def(&n, buf);
  1477 + if (ret == -1)
1366 expr_error("unknown register"); 1478 expr_error("unknown register");
  1479 + else if (ret == -2)
  1480 + expr_error("no cpu defined");
1367 } 1481 }
1368 break; 1482 break;
1369 case '\0': 1483 case '\0':
@@ -83,8 +83,6 @@ @@ -83,8 +83,6 @@
83 83
84 #include "exec-all.h" 84 #include "exec-all.h"
85 85
86 -//#define DO_TB_FLUSH  
87 -  
88 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" 86 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
89 87
90 //#define DEBUG_UNUSED_IOPORT 88 //#define DEBUG_UNUSED_IOPORT
@@ -109,8 +107,6 @@ @@ -109,8 +107,6 @@
109 107
110 const char *bios_dir = CONFIG_QEMU_SHAREDIR; 108 const char *bios_dir = CONFIG_QEMU_SHAREDIR;
111 char phys_ram_file[1024]; 109 char phys_ram_file[1024];
112 -CPUState *global_env;  
113 -CPUState *cpu_single_env;  
114 void *ioport_opaque[MAX_IOPORTS]; 110 void *ioport_opaque[MAX_IOPORTS];
115 IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; 111 IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
116 IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; 112 IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
@@ -156,6 +152,7 @@ int usb_enabled = 0; @@ -156,6 +152,7 @@ int usb_enabled = 0;
156 USBPort *vm_usb_ports[MAX_VM_USB_PORTS]; 152 USBPort *vm_usb_ports[MAX_VM_USB_PORTS];
157 USBDevice *vm_usb_hub; 153 USBDevice *vm_usb_hub;
158 static VLANState *first_vlan; 154 static VLANState *first_vlan;
  155 +int smp_cpus = 1;
159 156
160 /***********************************************************/ 157 /***********************************************************/
161 /* x86 ISA bus support */ 158 /* x86 ISA bus support */
@@ -427,16 +424,20 @@ int cpu_inl(CPUState *env, int addr) @@ -427,16 +424,20 @@ int cpu_inl(CPUState *env, int addr)
427 void hw_error(const char *fmt, ...) 424 void hw_error(const char *fmt, ...)
428 { 425 {
429 va_list ap; 426 va_list ap;
  427 + CPUState *env;
430 428
431 va_start(ap, fmt); 429 va_start(ap, fmt);
432 fprintf(stderr, "qemu: hardware error: "); 430 fprintf(stderr, "qemu: hardware error: ");
433 vfprintf(stderr, fmt, ap); 431 vfprintf(stderr, fmt, ap);
434 fprintf(stderr, "\n"); 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 #ifdef TARGET_I386 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 #else 437 #else
438 - cpu_dump_state(global_env, stderr, fprintf, 0); 438 + cpu_dump_state(env, stderr, fprintf, 0);
439 #endif 439 #endif
  440 + }
440 va_end(ap); 441 va_end(ap);
441 abort(); 442 abort();
442 } 443 }
@@ -879,13 +880,16 @@ static void host_alarm_handler(int host_signum) @@ -879,13 +880,16 @@ static void host_alarm_handler(int host_signum)
879 qemu_get_clock(vm_clock)) || 880 qemu_get_clock(vm_clock)) ||
880 qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME], 881 qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
881 qemu_get_clock(rt_clock))) { 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 #ifdef USE_KQEMU 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 #endif 891 #endif
  892 + }
889 } 893 }
890 } 894 }
891 895
@@ -2970,9 +2974,6 @@ int qemu_loadvm(const char *filename) @@ -2970,9 +2974,6 @@ int qemu_loadvm(const char *filename)
2970 goto the_end; 2974 goto the_end;
2971 } 2975 }
2972 for(;;) { 2976 for(;;) {
2973 -#if defined (DO_TB_FLUSH)  
2974 - tb_flush(global_env);  
2975 -#endif  
2976 len = qemu_get_byte(f); 2977 len = qemu_get_byte(f);
2977 if (feof(f)) 2978 if (feof(f))
2978 break; 2979 break;
@@ -3583,27 +3584,22 @@ void qemu_system_reset(void) @@ -3583,27 +3584,22 @@ void qemu_system_reset(void)
3583 void qemu_system_reset_request(void) 3584 void qemu_system_reset_request(void)
3584 { 3585 {
3585 reset_requested = 1; 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 void qemu_system_shutdown_request(void) 3591 void qemu_system_shutdown_request(void)
3590 { 3592 {
3591 shutdown_requested = 1; 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 void qemu_system_powerdown_request(void) 3598 void qemu_system_powerdown_request(void)
3596 { 3599 {
3597 powerdown_requested = 1; 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 void main_loop_wait(int timeout) 3605 void main_loop_wait(int timeout)
@@ -3684,14 +3680,42 @@ void main_loop_wait(int timeout) @@ -3684,14 +3680,42 @@ void main_loop_wait(int timeout)
3684 qemu_get_clock(rt_clock)); 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 int main_loop(void) 3704 int main_loop(void)
3688 { 3705 {
3689 int ret, timeout; 3706 int ret, timeout;
3690 - CPUState *env = global_env; 3707 + CPUState *env;
3691 3708
  3709 + cur_cpu = first_cpu;
3692 for(;;) { 3710 for(;;) {
3693 if (vm_running) { 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 if (shutdown_requested) { 3719 if (shutdown_requested) {
3696 ret = EXCP_INTERRUPT; 3720 ret = EXCP_INTERRUPT;
3697 break; 3721 break;
@@ -3774,7 +3798,7 @@ void help(void) @@ -3774,7 +3798,7 @@ void help(void)
3774 " connect the host TAP network interface to VLAN 'n' and use\n" 3798 " connect the host TAP network interface to VLAN 'n' and use\n"
3775 " the network script 'file' (default=%s);\n" 3799 " the network script 'file' (default=%s);\n"
3776 " use 'fd=h' to connect to an already opened TAP interface\n" 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 " connect the vlan 'n' to another VLAN using a socket connection\n" 3802 " connect the vlan 'n' to another VLAN using a socket connection\n"
3779 #endif 3803 #endif
3780 "-net none use it alone to have zero network devices; if no -net option\n" 3804 "-net none use it alone to have zero network devices; if no -net option\n"
@@ -3899,6 +3923,7 @@ enum { @@ -3899,6 +3923,7 @@ enum {
3899 QEMU_OPTION_win2k_hack, 3923 QEMU_OPTION_win2k_hack,
3900 QEMU_OPTION_usb, 3924 QEMU_OPTION_usb,
3901 QEMU_OPTION_usbdevice, 3925 QEMU_OPTION_usbdevice,
  3926 + QEMU_OPTION_smp,
3902 }; 3927 };
3903 3928
3904 typedef struct QEMUOption { 3929 typedef struct QEMUOption {
@@ -3965,6 +3990,7 @@ const QEMUOption qemu_options[] = { @@ -3965,6 +3990,7 @@ const QEMUOption qemu_options[] = {
3965 { "pidfile", HAS_ARG, QEMU_OPTION_pidfile }, 3990 { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
3966 { "win2k-hack", 0, QEMU_OPTION_win2k_hack }, 3991 { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
3967 { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice }, 3992 { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
  3993 + { "smp", HAS_ARG, QEMU_OPTION_smp },
3968 3994
3969 /* temporary options */ 3995 /* temporary options */
3970 { "usb", 0, QEMU_OPTION_usb }, 3996 { "usb", 0, QEMU_OPTION_usb },
@@ -4120,7 +4146,6 @@ int main(int argc, char **argv) @@ -4120,7 +4146,6 @@ int main(int argc, char **argv)
4120 #endif 4146 #endif
4121 int i, cdrom_index; 4147 int i, cdrom_index;
4122 int snapshot, linux_boot; 4148 int snapshot, linux_boot;
4123 - CPUState *env;  
4124 const char *initrd_filename; 4149 const char *initrd_filename;
4125 const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD]; 4150 const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
4126 const char *kernel_filename, *kernel_cmdline; 4151 const char *kernel_filename, *kernel_cmdline;
@@ -4511,6 +4536,13 @@ int main(int argc, char **argv) @@ -4511,6 +4536,13 @@ int main(int argc, char **argv)
4511 optarg); 4536 optarg);
4512 usb_devices_index++; 4537 usb_devices_index++;
4513 break; 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,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 register_savevm("ram", 0, 1, ram_save, ram_load, NULL); 4695 register_savevm("ram", 0, 1, ram_save, ram_load, NULL);
4670 - qemu_register_reset(main_cpu_reset, global_env);  
4671 4696
4672 init_ioports(); 4697 init_ioports();
4673 cpu_calibrate_ticks(); 4698 cpu_calibrate_ticks();
@@ -142,6 +142,7 @@ extern const char *keyboard_layout; @@ -142,6 +142,7 @@ extern const char *keyboard_layout;
142 extern int kqemu_allowed; 142 extern int kqemu_allowed;
143 extern int win2k_install_hack; 143 extern int win2k_install_hack;
144 extern int usb_enabled; 144 extern int usb_enabled;
  145 +extern int smp_cpus;
145 146
146 /* XXX: make it dynamic */ 147 /* XXX: make it dynamic */
147 #if defined (TARGET_PPC) 148 #if defined (TARGET_PPC)
@@ -429,6 +430,9 @@ int register_savevm(const char *idstr, @@ -429,6 +430,9 @@ int register_savevm(const char *idstr,
429 void qemu_get_timer(QEMUFile *f, QEMUTimer *ts); 430 void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
430 void qemu_put_timer(QEMUFile *f, QEMUTimer *ts); 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 /* block.c */ 436 /* block.c */
433 typedef struct BlockDriverState BlockDriverState; 437 typedef struct BlockDriverState BlockDriverState;
434 typedef struct BlockDriver BlockDriver; 438 typedef struct BlockDriver BlockDriver;
@@ -774,6 +778,9 @@ int pit_get_out(PITState *pit, int channel, int64_t current_time); @@ -774,6 +778,9 @@ int pit_get_out(PITState *pit, int channel, int64_t current_time);
774 extern QEMUMachine pc_machine; 778 extern QEMUMachine pc_machine;
775 extern QEMUMachine isapc_machine; 779 extern QEMUMachine isapc_machine;
776 780
  781 +void ioport_set_a20(int enable);
  782 +int ioport_get_a20(void);
  783 +
777 /* ppc.c */ 784 /* ppc.c */
778 extern QEMUMachine prep_machine; 785 extern QEMUMachine prep_machine;
779 extern QEMUMachine core99_machine; 786 extern QEMUMachine core99_machine;