]> Git Repo - qemu.git/blob - cpu-exec.c
e1000: correctly handle phy_ctrl reserved & self-clearing bits
[qemu.git] / cpu-exec.c
1 /*
2  *  emulator main execution loop
3  *
4  *  Copyright (c) 2003-2005 Fabrice Bellard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19 #include "config.h"
20 #include "cpu.h"
21 #include "disas/disas.h"
22 #include "tcg.h"
23 #include "qemu/atomic.h"
24 #include "sysemu/qtest.h"
25 #include "qemu/timer.h"
26
27 /* -icount align implementation. */
28
29 typedef struct SyncClocks {
30     int64_t diff_clk;
31     int64_t last_cpu_icount;
32     int64_t realtime_clock;
33 } SyncClocks;
34
35 #if !defined(CONFIG_USER_ONLY)
36 /* Allow the guest to have a max 3ms advance.
37  * The difference between the 2 clocks could therefore
38  * oscillate around 0.
39  */
40 #define VM_CLOCK_ADVANCE 3000000
41 #define THRESHOLD_REDUCE 1.5
42 #define MAX_DELAY_PRINT_RATE 2000000000LL
43 #define MAX_NB_PRINTS 100
44
45 static void align_clocks(SyncClocks *sc, const CPUState *cpu)
46 {
47     int64_t cpu_icount;
48
49     if (!icount_align_option) {
50         return;
51     }
52
53     cpu_icount = cpu->icount_extra + cpu->icount_decr.u16.low;
54     sc->diff_clk += cpu_icount_to_ns(sc->last_cpu_icount - cpu_icount);
55     sc->last_cpu_icount = cpu_icount;
56
57     if (sc->diff_clk > VM_CLOCK_ADVANCE) {
58 #ifndef _WIN32
59         struct timespec sleep_delay, rem_delay;
60         sleep_delay.tv_sec = sc->diff_clk / 1000000000LL;
61         sleep_delay.tv_nsec = sc->diff_clk % 1000000000LL;
62         if (nanosleep(&sleep_delay, &rem_delay) < 0) {
63             sc->diff_clk -= (sleep_delay.tv_sec - rem_delay.tv_sec) * 1000000000LL;
64             sc->diff_clk -= sleep_delay.tv_nsec - rem_delay.tv_nsec;
65         } else {
66             sc->diff_clk = 0;
67         }
68 #else
69         Sleep(sc->diff_clk / SCALE_MS);
70         sc->diff_clk = 0;
71 #endif
72     }
73 }
74
75 static void print_delay(const SyncClocks *sc)
76 {
77     static float threshold_delay;
78     static int64_t last_realtime_clock;
79     static int nb_prints;
80
81     if (icount_align_option &&
82         sc->realtime_clock - last_realtime_clock >= MAX_DELAY_PRINT_RATE &&
83         nb_prints < MAX_NB_PRINTS) {
84         if ((-sc->diff_clk / (float)1000000000LL > threshold_delay) ||
85             (-sc->diff_clk / (float)1000000000LL <
86              (threshold_delay - THRESHOLD_REDUCE))) {
87             threshold_delay = (-sc->diff_clk / 1000000000LL) + 1;
88             printf("Warning: The guest is now late by %.1f to %.1f seconds\n",
89                    threshold_delay - 1,
90                    threshold_delay);
91             nb_prints++;
92             last_realtime_clock = sc->realtime_clock;
93         }
94     }
95 }
96
97 static void init_delay_params(SyncClocks *sc,
98                               const CPUState *cpu)
99 {
100     if (!icount_align_option) {
101         return;
102     }
103     sc->realtime_clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
104     sc->diff_clk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
105                    sc->realtime_clock +
106                    cpu_get_clock_offset();
107     sc->last_cpu_icount = cpu->icount_extra + cpu->icount_decr.u16.low;
108     if (sc->diff_clk < max_delay) {
109         max_delay = sc->diff_clk;
110     }
111     if (sc->diff_clk > max_advance) {
112         max_advance = sc->diff_clk;
113     }
114
115     /* Print every 2s max if the guest is late. We limit the number
116        of printed messages to NB_PRINT_MAX(currently 100) */
117     print_delay(sc);
118 }
119 #else
120 static void align_clocks(SyncClocks *sc, const CPUState *cpu)
121 {
122 }
123
124 static void init_delay_params(SyncClocks *sc, const CPUState *cpu)
125 {
126 }
127 #endif /* CONFIG USER ONLY */
128
129 void cpu_loop_exit(CPUState *cpu)
130 {
131     cpu->current_tb = NULL;
132     siglongjmp(cpu->jmp_env, 1);
133 }
134
135 /* exit the current TB from a signal handler. The host registers are
136    restored in a state compatible with the CPU emulator
137  */
138 #if defined(CONFIG_SOFTMMU)
139 void cpu_resume_from_signal(CPUState *cpu, void *puc)
140 {
141     /* XXX: restore cpu registers saved in host registers */
142
143     cpu->exception_index = -1;
144     siglongjmp(cpu->jmp_env, 1);
145 }
146 #endif
147
148 /* Execute a TB, and fix up the CPU state afterwards if necessary */
149 static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
150 {
151     CPUArchState *env = cpu->env_ptr;
152     uintptr_t next_tb;
153
154 #if defined(DEBUG_DISAS)
155     if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
156 #if defined(TARGET_I386)
157         log_cpu_state(cpu, CPU_DUMP_CCOP);
158 #elif defined(TARGET_M68K)
159         /* ??? Should not modify env state for dumping.  */
160         cpu_m68k_flush_flags(env, env->cc_op);
161         env->cc_op = CC_OP_FLAGS;
162         env->sr = (env->sr & 0xffe0) | env->cc_dest | (env->cc_x << 4);
163         log_cpu_state(cpu, 0);
164 #else
165         log_cpu_state(cpu, 0);
166 #endif
167     }
168 #endif /* DEBUG_DISAS */
169
170     next_tb = tcg_qemu_tb_exec(env, tb_ptr);
171     if ((next_tb & TB_EXIT_MASK) > TB_EXIT_IDX1) {
172         /* We didn't start executing this TB (eg because the instruction
173          * counter hit zero); we must restore the guest PC to the address
174          * of the start of the TB.
175          */
176         CPUClass *cc = CPU_GET_CLASS(cpu);
177         TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
178         if (cc->synchronize_from_tb) {
179             cc->synchronize_from_tb(cpu, tb);
180         } else {
181             assert(cc->set_pc);
182             cc->set_pc(cpu, tb->pc);
183         }
184     }
185     if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) {
186         /* We were asked to stop executing TBs (probably a pending
187          * interrupt. We've now stopped, so clear the flag.
188          */
189         cpu->tcg_exit_req = 0;
190     }
191     return next_tb;
192 }
193
194 /* Execute the code without caching the generated code. An interpreter
195    could be used if available. */
196 static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
197                              TranslationBlock *orig_tb)
198 {
199     CPUState *cpu = ENV_GET_CPU(env);
200     TranslationBlock *tb;
201
202     /* Should never happen.
203        We only end up here when an existing TB is too long.  */
204     if (max_cycles > CF_COUNT_MASK)
205         max_cycles = CF_COUNT_MASK;
206
207     tb = tb_gen_code(cpu, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
208                      max_cycles);
209     cpu->current_tb = tb;
210     /* execute the generated code */
211     cpu_tb_exec(cpu, tb->tc_ptr);
212     cpu->current_tb = NULL;
213     tb_phys_invalidate(tb, -1);
214     tb_free(tb);
215 }
216
217 static TranslationBlock *tb_find_slow(CPUArchState *env,
218                                       target_ulong pc,
219                                       target_ulong cs_base,
220                                       uint64_t flags)
221 {
222     CPUState *cpu = ENV_GET_CPU(env);
223     TranslationBlock *tb, **ptb1;
224     unsigned int h;
225     tb_page_addr_t phys_pc, phys_page1;
226     target_ulong virt_page2;
227
228     tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
229
230     /* find translated block using physical mappings */
231     phys_pc = get_page_addr_code(env, pc);
232     phys_page1 = phys_pc & TARGET_PAGE_MASK;
233     h = tb_phys_hash_func(phys_pc);
234     ptb1 = &tcg_ctx.tb_ctx.tb_phys_hash[h];
235     for(;;) {
236         tb = *ptb1;
237         if (!tb)
238             goto not_found;
239         if (tb->pc == pc &&
240             tb->page_addr[0] == phys_page1 &&
241             tb->cs_base == cs_base &&
242             tb->flags == flags) {
243             /* check next page if needed */
244             if (tb->page_addr[1] != -1) {
245                 tb_page_addr_t phys_page2;
246
247                 virt_page2 = (pc & TARGET_PAGE_MASK) +
248                     TARGET_PAGE_SIZE;
249                 phys_page2 = get_page_addr_code(env, virt_page2);
250                 if (tb->page_addr[1] == phys_page2)
251                     goto found;
252             } else {
253                 goto found;
254             }
255         }
256         ptb1 = &tb->phys_hash_next;
257     }
258  not_found:
259    /* if no translated code available, then translate it now */
260     tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
261
262  found:
263     /* Move the last found TB to the head of the list */
264     if (likely(*ptb1)) {
265         *ptb1 = tb->phys_hash_next;
266         tb->phys_hash_next = tcg_ctx.tb_ctx.tb_phys_hash[h];
267         tcg_ctx.tb_ctx.tb_phys_hash[h] = tb;
268     }
269     /* we add the TB in the virtual pc hash table */
270     cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
271     return tb;
272 }
273
274 static inline TranslationBlock *tb_find_fast(CPUArchState *env)
275 {
276     CPUState *cpu = ENV_GET_CPU(env);
277     TranslationBlock *tb;
278     target_ulong cs_base, pc;
279     int flags;
280
281     /* we record a subset of the CPU state. It will
282        always be the same before a given translated block
283        is executed. */
284     cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
285     tb = cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
286     if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
287                  tb->flags != flags)) {
288         tb = tb_find_slow(env, pc, cs_base, flags);
289     }
290     return tb;
291 }
292
293 static CPUDebugExcpHandler *debug_excp_handler;
294
295 void cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
296 {
297     debug_excp_handler = handler;
298 }
299
300 static void cpu_handle_debug_exception(CPUArchState *env)
301 {
302     CPUState *cpu = ENV_GET_CPU(env);
303     CPUWatchpoint *wp;
304
305     if (!cpu->watchpoint_hit) {
306         QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
307             wp->flags &= ~BP_WATCHPOINT_HIT;
308         }
309     }
310     if (debug_excp_handler) {
311         debug_excp_handler(env);
312     }
313 }
314
315 /* main execution loop */
316
317 volatile sig_atomic_t exit_request;
318
319 int cpu_exec(CPUArchState *env)
320 {
321     CPUState *cpu = ENV_GET_CPU(env);
322 #if !(defined(CONFIG_USER_ONLY) && \
323       (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X)))
324     CPUClass *cc = CPU_GET_CLASS(cpu);
325 #endif
326 #ifdef TARGET_I386
327     X86CPU *x86_cpu = X86_CPU(cpu);
328 #endif
329     int ret, interrupt_request;
330     TranslationBlock *tb;
331     uint8_t *tc_ptr;
332     uintptr_t next_tb;
333     SyncClocks sc;
334
335     /* This must be volatile so it is not trashed by longjmp() */
336     volatile bool have_tb_lock = false;
337
338     if (cpu->halted) {
339         if (!cpu_has_work(cpu)) {
340             return EXCP_HALTED;
341         }
342
343         cpu->halted = 0;
344     }
345
346     current_cpu = cpu;
347
348     /* As long as current_cpu is null, up to the assignment just above,
349      * requests by other threads to exit the execution loop are expected to
350      * be issued using the exit_request global. We must make sure that our
351      * evaluation of the global value is performed past the current_cpu
352      * value transition point, which requires a memory barrier as well as
353      * an instruction scheduling constraint on modern architectures.  */
354     smp_mb();
355
356     if (unlikely(exit_request)) {
357         cpu->exit_request = 1;
358     }
359
360 #if defined(TARGET_I386)
361     /* put eflags in CPU temporary format */
362     CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
363     env->df = 1 - (2 * ((env->eflags >> 10) & 1));
364     CC_OP = CC_OP_EFLAGS;
365     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
366 #elif defined(TARGET_SPARC)
367 #elif defined(TARGET_M68K)
368     env->cc_op = CC_OP_FLAGS;
369     env->cc_dest = env->sr & 0xf;
370     env->cc_x = (env->sr >> 4) & 1;
371 #elif defined(TARGET_ALPHA)
372 #elif defined(TARGET_ARM)
373 #elif defined(TARGET_UNICORE32)
374 #elif defined(TARGET_PPC)
375     env->reserve_addr = -1;
376 #elif defined(TARGET_LM32)
377 #elif defined(TARGET_MICROBLAZE)
378 #elif defined(TARGET_MIPS)
379 #elif defined(TARGET_MOXIE)
380 #elif defined(TARGET_OPENRISC)
381 #elif defined(TARGET_SH4)
382 #elif defined(TARGET_CRIS)
383 #elif defined(TARGET_S390X)
384 #elif defined(TARGET_XTENSA)
385     /* XXXXX */
386 #else
387 #error unsupported target CPU
388 #endif
389     cpu->exception_index = -1;
390
391     /* Calculate difference between guest clock and host clock.
392      * This delay includes the delay of the last cycle, so
393      * what we have to do is sleep until it is 0. As for the
394      * advance/delay we gain here, we try to fix it next time.
395      */
396     init_delay_params(&sc, cpu);
397
398     /* prepare setjmp context for exception handling */
399     for(;;) {
400         if (sigsetjmp(cpu->jmp_env, 0) == 0) {
401             /* if an exception is pending, we execute it here */
402             if (cpu->exception_index >= 0) {
403                 if (cpu->exception_index >= EXCP_INTERRUPT) {
404                     /* exit request from the cpu execution loop */
405                     ret = cpu->exception_index;
406                     if (ret == EXCP_DEBUG) {
407                         cpu_handle_debug_exception(env);
408                     }
409                     break;
410                 } else {
411 #if defined(CONFIG_USER_ONLY)
412                     /* if user mode only, we simulate a fake exception
413                        which will be handled outside the cpu execution
414                        loop */
415 #if defined(TARGET_I386)
416                     cc->do_interrupt(cpu);
417 #endif
418                     ret = cpu->exception_index;
419                     break;
420 #else
421                     cc->do_interrupt(cpu);
422                     cpu->exception_index = -1;
423 #endif
424                 }
425             }
426
427             next_tb = 0; /* force lookup of first TB */
428             for(;;) {
429                 interrupt_request = cpu->interrupt_request;
430                 if (unlikely(interrupt_request)) {
431                     if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) {
432                         /* Mask out external interrupts for this step. */
433                         interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK;
434                     }
435                     if (interrupt_request & CPU_INTERRUPT_DEBUG) {
436                         cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
437                         cpu->exception_index = EXCP_DEBUG;
438                         cpu_loop_exit(cpu);
439                     }
440 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
441     defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
442     defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32)
443                     if (interrupt_request & CPU_INTERRUPT_HALT) {
444                         cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
445                         cpu->halted = 1;
446                         cpu->exception_index = EXCP_HLT;
447                         cpu_loop_exit(cpu);
448                     }
449 #endif
450 #if defined(TARGET_I386)
451                     if (interrupt_request & CPU_INTERRUPT_INIT) {
452                         cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, 0);
453                         do_cpu_init(x86_cpu);
454                         cpu->exception_index = EXCP_HALTED;
455                         cpu_loop_exit(cpu);
456                     }
457 #else
458                     if (interrupt_request & CPU_INTERRUPT_RESET) {
459                         cpu_reset(cpu);
460                     }
461 #endif
462 #if defined(TARGET_I386)
463 #if !defined(CONFIG_USER_ONLY)
464                     if (interrupt_request & CPU_INTERRUPT_POLL) {
465                         cpu->interrupt_request &= ~CPU_INTERRUPT_POLL;
466                         apic_poll_irq(x86_cpu->apic_state);
467                     }
468 #endif
469                     if (interrupt_request & CPU_INTERRUPT_SIPI) {
470                             do_cpu_sipi(x86_cpu);
471                     } else if (env->hflags2 & HF2_GIF_MASK) {
472                         if ((interrupt_request & CPU_INTERRUPT_SMI) &&
473                             !(env->hflags & HF_SMM_MASK)) {
474                             cpu_svm_check_intercept_param(env, SVM_EXIT_SMI,
475                                                           0);
476                             cpu->interrupt_request &= ~CPU_INTERRUPT_SMI;
477                             do_smm_enter(x86_cpu);
478                             next_tb = 0;
479                         } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
480                                    !(env->hflags2 & HF2_NMI_MASK)) {
481                             cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
482                             env->hflags2 |= HF2_NMI_MASK;
483                             do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
484                             next_tb = 0;
485                         } else if (interrupt_request & CPU_INTERRUPT_MCE) {
486                             cpu->interrupt_request &= ~CPU_INTERRUPT_MCE;
487                             do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
488                             next_tb = 0;
489                         } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
490                                    (((env->hflags2 & HF2_VINTR_MASK) && 
491                                      (env->hflags2 & HF2_HIF_MASK)) ||
492                                     (!(env->hflags2 & HF2_VINTR_MASK) && 
493                                      (env->eflags & IF_MASK && 
494                                       !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
495                             int intno;
496                             cpu_svm_check_intercept_param(env, SVM_EXIT_INTR,
497                                                           0);
498                             cpu->interrupt_request &= ~(CPU_INTERRUPT_HARD |
499                                                         CPU_INTERRUPT_VIRQ);
500                             intno = cpu_get_pic_interrupt(env);
501                             qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
502                             do_interrupt_x86_hardirq(env, intno, 1);
503                             /* ensure that no TB jump will be modified as
504                                the program flow was changed */
505                             next_tb = 0;
506 #if !defined(CONFIG_USER_ONLY)
507                         } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
508                                    (env->eflags & IF_MASK) && 
509                                    !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
510                             int intno;
511                             /* FIXME: this should respect TPR */
512                             cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR,
513                                                           0);
514                             intno = ldl_phys(cpu->as,
515                                              env->vm_vmcb
516                                              + offsetof(struct vmcb,
517                                                         control.int_vector));
518                             qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
519                             do_interrupt_x86_hardirq(env, intno, 1);
520                             cpu->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
521                             next_tb = 0;
522 #endif
523                         }
524                     }
525 #elif defined(TARGET_PPC)
526                     if (interrupt_request & CPU_INTERRUPT_HARD) {
527                         ppc_hw_interrupt(env);
528                         if (env->pending_interrupts == 0) {
529                             cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
530                         }
531                         next_tb = 0;
532                     }
533 #elif defined(TARGET_LM32)
534                     if ((interrupt_request & CPU_INTERRUPT_HARD)
535                         && (env->ie & IE_IE)) {
536                         cpu->exception_index = EXCP_IRQ;
537                         cc->do_interrupt(cpu);
538                         next_tb = 0;
539                     }
540 #elif defined(TARGET_MICROBLAZE)
541                     if ((interrupt_request & CPU_INTERRUPT_HARD)
542                         && (env->sregs[SR_MSR] & MSR_IE)
543                         && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
544                         && !(env->iflags & (D_FLAG | IMM_FLAG))) {
545                         cpu->exception_index = EXCP_IRQ;
546                         cc->do_interrupt(cpu);
547                         next_tb = 0;
548                     }
549 #elif defined(TARGET_MIPS)
550                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
551                         cpu_mips_hw_interrupts_pending(env)) {
552                         /* Raise it */
553                         cpu->exception_index = EXCP_EXT_INTERRUPT;
554                         env->error_code = 0;
555                         cc->do_interrupt(cpu);
556                         next_tb = 0;
557                     }
558 #elif defined(TARGET_OPENRISC)
559                     {
560                         int idx = -1;
561                         if ((interrupt_request & CPU_INTERRUPT_HARD)
562                             && (env->sr & SR_IEE)) {
563                             idx = EXCP_INT;
564                         }
565                         if ((interrupt_request & CPU_INTERRUPT_TIMER)
566                             && (env->sr & SR_TEE)) {
567                             idx = EXCP_TICK;
568                         }
569                         if (idx >= 0) {
570                             cpu->exception_index = idx;
571                             cc->do_interrupt(cpu);
572                             next_tb = 0;
573                         }
574                     }
575 #elif defined(TARGET_SPARC)
576                     if (interrupt_request & CPU_INTERRUPT_HARD) {
577                         if (cpu_interrupts_enabled(env) &&
578                             env->interrupt_index > 0) {
579                             int pil = env->interrupt_index & 0xf;
580                             int type = env->interrupt_index & 0xf0;
581
582                             if (((type == TT_EXTINT) &&
583                                   cpu_pil_allowed(env, pil)) ||
584                                   type != TT_EXTINT) {
585                                 cpu->exception_index = env->interrupt_index;
586                                 cc->do_interrupt(cpu);
587                                 next_tb = 0;
588                             }
589                         }
590                     }
591 #elif defined(TARGET_ARM)
592                     if (interrupt_request & CPU_INTERRUPT_FIQ
593                         && !(env->daif & PSTATE_F)) {
594                         cpu->exception_index = EXCP_FIQ;
595                         cc->do_interrupt(cpu);
596                         next_tb = 0;
597                     }
598                     /* ARMv7-M interrupt return works by loading a magic value
599                        into the PC.  On real hardware the load causes the
600                        return to occur.  The qemu implementation performs the
601                        jump normally, then does the exception return when the
602                        CPU tries to execute code at the magic address.
603                        This will cause the magic PC value to be pushed to
604                        the stack if an interrupt occurred at the wrong time.
605                        We avoid this by disabling interrupts when
606                        pc contains a magic address.  */
607                     if (interrupt_request & CPU_INTERRUPT_HARD
608                         && ((IS_M(env) && env->regs[15] < 0xfffffff0)
609                             || !(env->daif & PSTATE_I))) {
610                         cpu->exception_index = EXCP_IRQ;
611                         cc->do_interrupt(cpu);
612                         next_tb = 0;
613                     }
614 #elif defined(TARGET_UNICORE32)
615                     if (interrupt_request & CPU_INTERRUPT_HARD
616                         && !(env->uncached_asr & ASR_I)) {
617                         cpu->exception_index = UC32_EXCP_INTR;
618                         cc->do_interrupt(cpu);
619                         next_tb = 0;
620                     }
621 #elif defined(TARGET_SH4)
622                     if (interrupt_request & CPU_INTERRUPT_HARD) {
623                         cc->do_interrupt(cpu);
624                         next_tb = 0;
625                     }
626 #elif defined(TARGET_ALPHA)
627                     {
628                         int idx = -1;
629                         /* ??? This hard-codes the OSF/1 interrupt levels.  */
630                         switch (env->pal_mode ? 7 : env->ps & PS_INT_MASK) {
631                         case 0 ... 3:
632                             if (interrupt_request & CPU_INTERRUPT_HARD) {
633                                 idx = EXCP_DEV_INTERRUPT;
634                             }
635                             /* FALLTHRU */
636                         case 4:
637                             if (interrupt_request & CPU_INTERRUPT_TIMER) {
638                                 idx = EXCP_CLK_INTERRUPT;
639                             }
640                             /* FALLTHRU */
641                         case 5:
642                             if (interrupt_request & CPU_INTERRUPT_SMP) {
643                                 idx = EXCP_SMP_INTERRUPT;
644                             }
645                             /* FALLTHRU */
646                         case 6:
647                             if (interrupt_request & CPU_INTERRUPT_MCHK) {
648                                 idx = EXCP_MCHK;
649                             }
650                         }
651                         if (idx >= 0) {
652                             cpu->exception_index = idx;
653                             env->error_code = 0;
654                             cc->do_interrupt(cpu);
655                             next_tb = 0;
656                         }
657                     }
658 #elif defined(TARGET_CRIS)
659                     if (interrupt_request & CPU_INTERRUPT_HARD
660                         && (env->pregs[PR_CCS] & I_FLAG)
661                         && !env->locked_irq) {
662                         cpu->exception_index = EXCP_IRQ;
663                         cc->do_interrupt(cpu);
664                         next_tb = 0;
665                     }
666                     if (interrupt_request & CPU_INTERRUPT_NMI) {
667                         unsigned int m_flag_archval;
668                         if (env->pregs[PR_VR] < 32) {
669                             m_flag_archval = M_FLAG_V10;
670                         } else {
671                             m_flag_archval = M_FLAG_V32;
672                         }
673                         if ((env->pregs[PR_CCS] & m_flag_archval)) {
674                             cpu->exception_index = EXCP_NMI;
675                             cc->do_interrupt(cpu);
676                             next_tb = 0;
677                         }
678                     }
679 #elif defined(TARGET_M68K)
680                     if (interrupt_request & CPU_INTERRUPT_HARD
681                         && ((env->sr & SR_I) >> SR_I_SHIFT)
682                             < env->pending_level) {
683                         /* Real hardware gets the interrupt vector via an
684                            IACK cycle at this point.  Current emulated
685                            hardware doesn't rely on this, so we
686                            provide/save the vector when the interrupt is
687                            first signalled.  */
688                         cpu->exception_index = env->pending_vector;
689                         do_interrupt_m68k_hardirq(env);
690                         next_tb = 0;
691                     }
692 #elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
693                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
694                         (env->psw.mask & PSW_MASK_EXT)) {
695                         cc->do_interrupt(cpu);
696                         next_tb = 0;
697                     }
698 #elif defined(TARGET_XTENSA)
699                     if (interrupt_request & CPU_INTERRUPT_HARD) {
700                         cpu->exception_index = EXC_IRQ;
701                         cc->do_interrupt(cpu);
702                         next_tb = 0;
703                     }
704 #endif
705                    /* Don't use the cached interrupt_request value,
706                       do_interrupt may have updated the EXITTB flag. */
707                     if (cpu->interrupt_request & CPU_INTERRUPT_EXITTB) {
708                         cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
709                         /* ensure that no TB jump will be modified as
710                            the program flow was changed */
711                         next_tb = 0;
712                     }
713                 }
714                 if (unlikely(cpu->exit_request)) {
715                     cpu->exit_request = 0;
716                     cpu->exception_index = EXCP_INTERRUPT;
717                     cpu_loop_exit(cpu);
718                 }
719                 spin_lock(&tcg_ctx.tb_ctx.tb_lock);
720                 have_tb_lock = true;
721                 tb = tb_find_fast(env);
722                 /* Note: we do it here to avoid a gcc bug on Mac OS X when
723                    doing it in tb_find_slow */
724                 if (tcg_ctx.tb_ctx.tb_invalidated_flag) {
725                     /* as some TB could have been invalidated because
726                        of memory exceptions while generating the code, we
727                        must recompute the hash index here */
728                     next_tb = 0;
729                     tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
730                 }
731                 if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
732                     qemu_log("Trace %p [" TARGET_FMT_lx "] %s\n",
733                              tb->tc_ptr, tb->pc, lookup_symbol(tb->pc));
734                 }
735                 /* see if we can patch the calling TB. When the TB
736                    spans two pages, we cannot safely do a direct
737                    jump. */
738                 if (next_tb != 0 && tb->page_addr[1] == -1) {
739                     tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
740                                 next_tb & TB_EXIT_MASK, tb);
741                 }
742                 have_tb_lock = false;
743                 spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
744
745                 /* cpu_interrupt might be called while translating the
746                    TB, but before it is linked into a potentially
747                    infinite loop and becomes env->current_tb. Avoid
748                    starting execution if there is a pending interrupt. */
749                 cpu->current_tb = tb;
750                 barrier();
751                 if (likely(!cpu->exit_request)) {
752                     tc_ptr = tb->tc_ptr;
753                     /* execute the generated code */
754                     next_tb = cpu_tb_exec(cpu, tc_ptr);
755                     switch (next_tb & TB_EXIT_MASK) {
756                     case TB_EXIT_REQUESTED:
757                         /* Something asked us to stop executing
758                          * chained TBs; just continue round the main
759                          * loop. Whatever requested the exit will also
760                          * have set something else (eg exit_request or
761                          * interrupt_request) which we will handle
762                          * next time around the loop.
763                          */
764                         tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
765                         next_tb = 0;
766                         break;
767                     case TB_EXIT_ICOUNT_EXPIRED:
768                     {
769                         /* Instruction counter expired.  */
770                         int insns_left;
771                         tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
772                         insns_left = cpu->icount_decr.u32;
773                         if (cpu->icount_extra && insns_left >= 0) {
774                             /* Refill decrementer and continue execution.  */
775                             cpu->icount_extra += insns_left;
776                             if (cpu->icount_extra > 0xffff) {
777                                 insns_left = 0xffff;
778                             } else {
779                                 insns_left = cpu->icount_extra;
780                             }
781                             cpu->icount_extra -= insns_left;
782                             cpu->icount_decr.u16.low = insns_left;
783                         } else {
784                             if (insns_left > 0) {
785                                 /* Execute remaining instructions.  */
786                                 cpu_exec_nocache(env, insns_left, tb);
787                                 align_clocks(&sc, cpu);
788                             }
789                             cpu->exception_index = EXCP_INTERRUPT;
790                             next_tb = 0;
791                             cpu_loop_exit(cpu);
792                         }
793                         break;
794                     }
795                     default:
796                         break;
797                     }
798                 }
799                 cpu->current_tb = NULL;
800                 /* Try to align the host and virtual clocks
801                    if the guest is in advance */
802                 align_clocks(&sc, cpu);
803                 /* reset soft MMU for next block (it can currently
804                    only be set by a memory fault) */
805             } /* for(;;) */
806         } else {
807             /* Reload env after longjmp - the compiler may have smashed all
808              * local variables as longjmp is marked 'noreturn'. */
809             cpu = current_cpu;
810             env = cpu->env_ptr;
811 #if !(defined(CONFIG_USER_ONLY) && \
812       (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X)))
813             cc = CPU_GET_CLASS(cpu);
814 #endif
815 #ifdef TARGET_I386
816             x86_cpu = X86_CPU(cpu);
817 #endif
818             if (have_tb_lock) {
819                 spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
820                 have_tb_lock = false;
821             }
822         }
823     } /* for(;;) */
824
825
826 #if defined(TARGET_I386)
827     /* restore flags in standard format */
828     env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
829         | (env->df & DF_MASK);
830 #elif defined(TARGET_ARM)
831     /* XXX: Save/restore host fpu exception state?.  */
832 #elif defined(TARGET_UNICORE32)
833 #elif defined(TARGET_SPARC)
834 #elif defined(TARGET_PPC)
835 #elif defined(TARGET_LM32)
836 #elif defined(TARGET_M68K)
837     cpu_m68k_flush_flags(env, env->cc_op);
838     env->cc_op = CC_OP_FLAGS;
839     env->sr = (env->sr & 0xffe0)
840               | env->cc_dest | (env->cc_x << 4);
841 #elif defined(TARGET_MICROBLAZE)
842 #elif defined(TARGET_MIPS)
843 #elif defined(TARGET_MOXIE)
844 #elif defined(TARGET_OPENRISC)
845 #elif defined(TARGET_SH4)
846 #elif defined(TARGET_ALPHA)
847 #elif defined(TARGET_CRIS)
848 #elif defined(TARGET_S390X)
849 #elif defined(TARGET_XTENSA)
850     /* XXXXX */
851 #else
852 #error unsupported target CPU
853 #endif
854
855     /* fail safe : never use current_cpu outside cpu_exec() */
856     current_cpu = NULL;
857     return ret;
858 }
This page took 0.071555 seconds and 4 git commands to generate.