/[dynamips]/trunk/mips64.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/mips64.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

upstream/dynamips-0.2.6-RC5/mips64.c revision 6 by dpavlin, Sat Oct 6 16:09:07 2007 UTC trunk/mips64.c revision 12 by dpavlin, Sat Oct 6 16:45:40 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   * Cisco 7200 (Predator) simulation platform.   * Cisco router simulation platform.
3   * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)   * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4   *   *
5   * XXX TODO: proper context save/restore for CPUs.   * XXX TODO: proper context save/restore for CPUs.
# Line 16  Line 16 
16  #include <assert.h>  #include <assert.h>
17    
18  #include "rbtree.h"  #include "rbtree.h"
19  #include "mips64.h"  #include "cpu.h"
20  #include "dynamips.h"  #include "mips64_mem.h"
 #include "cp0.h"  
21  #include "mips64_exec.h"  #include "mips64_exec.h"
22    #include "mips64_jit.h"
23    #include "dynamips.h"
24  #include "memory.h"  #include "memory.h"
25  #include "device.h"  #include "device.h"
26    
# Line 67  int mips64_reset(cpu_mips_t *cpu) Line 68  int mips64_reset(cpu_mips_t *cpu)
68     memset(&cpu->cp0.tlb,0,MIPS64_TLB_MAX_ENTRIES*sizeof(tlb_entry_t));     memset(&cpu->cp0.tlb,0,MIPS64_TLB_MAX_ENTRIES*sizeof(tlb_entry_t));
69    
70     /* Restart the MTS subsystem */     /* Restart the MTS subsystem */
71     mts_set_addr_mode(cpu,64);     mips64_set_addr_mode(cpu,32/*64*/);  /* zzz */
72     cpu->mts_rebuild(cpu);     cpu->gen->mts_rebuild(cpu->gen);
73    
74     /* Flush JIT structures */     /* Flush JIT structures */
75     mips64_jit_flush(cpu,0);     mips64_jit_flush(cpu,0);
# Line 78  int mips64_reset(cpu_mips_t *cpu) Line 79  int mips64_reset(cpu_mips_t *cpu)
79  /* Initialize a MIPS64 processor */  /* Initialize a MIPS64 processor */
80  int mips64_init(cpu_mips_t *cpu)  int mips64_init(cpu_mips_t *cpu)
81  {  {
    cpu->state = MIPS_CPU_SUSPENDED;  
82     cpu->addr_bus_mask = 0xFFFFFFFFFFFFFFFFULL;     cpu->addr_bus_mask = 0xFFFFFFFFFFFFFFFFULL;
83     cpu->cp0.reg[MIPS_CP0_PRID] = MIPS_PRID_R4600;     cpu->cp0.reg[MIPS_CP0_PRID] = MIPS_PRID_R4600;
84     cpu->cp0.tlb_entries = MIPS64_TLB_STD_ENTRIES;     cpu->cp0.tlb_entries = MIPS64_TLB_STD_ENTRIES;
85    
86     /* Initialize idle timer */     /* Initialize idle timer */
87     cpu->idle_max = 1500;     cpu->gen->idle_max = 1500;
88     cpu->idle_sleep_time = 30000;     cpu->gen->idle_sleep_time = 30000;
89    
90     /* Timer IRQ parameters (default frequency: 250 Hz <=> 4ms period) */     /* Timer IRQ parameters (default frequency: 250 Hz <=> 4ms period) */
91     cpu->timer_irq_check_itv = 1000;     cpu->timer_irq_check_itv = 1000;
# Line 94  int mips64_init(cpu_mips_t *cpu) Line 94  int mips64_init(cpu_mips_t *cpu)
94     /* Enable fast memory operations */     /* Enable fast memory operations */
95     cpu->fast_memop = TRUE;     cpu->fast_memop = TRUE;
96    
97       /* Enable/Disable direct block jump */
98       cpu->exec_blk_direct_jump = cpu->vm->exec_blk_direct_jump;
99    
100     /* Create the IRQ lock (for non-jit architectures) */     /* Create the IRQ lock (for non-jit architectures) */
101     pthread_mutex_init(&cpu->irq_lock,NULL);     pthread_mutex_init(&cpu->irq_lock,NULL);
102    
103     /* Idle loop mutex and condition */     /* Idle loop mutex and condition */
104     pthread_mutex_init(&cpu->idle_mutex,NULL);     pthread_mutex_init(&cpu->gen->idle_mutex,NULL);
105     pthread_cond_init(&cpu->idle_cond,NULL);     pthread_cond_init(&cpu->gen->idle_cond,NULL);
106    
107       /* Set the CPU methods */
108       cpu->gen->reg_set =  (void *)mips64_reg_set;
109       cpu->gen->reg_dump = (void *)mips64_dump_regs;
110       cpu->gen->mmu_dump = (void *)mips64_tlb_dump;
111       cpu->gen->mmu_raw_dump = (void *)mips64_tlb_raw_dump;
112       cpu->gen->add_breakpoint = (void *)mips64_add_breakpoint;
113       cpu->gen->remove_breakpoint = (void *)mips64_remove_breakpoint;
114       cpu->gen->set_idle_pc = (void *)mips64_set_idle_pc;
115       cpu->gen->get_idling_pc = (void *)mips64_get_idling_pc;
116    
117     /* Set the startup parameters */     /* Set the startup parameters */
118     mips64_reset(cpu);     mips64_reset(cpu);
# Line 110  int mips64_init(cpu_mips_t *cpu) Line 123  int mips64_init(cpu_mips_t *cpu)
123  void mips64_delete(cpu_mips_t *cpu)  void mips64_delete(cpu_mips_t *cpu)
124  {  {
125     if (cpu) {     if (cpu) {
126        mts_shutdown(cpu);        mips64_mem_shutdown(cpu);
127        mips64_jit_shutdown(cpu);        mips64_jit_shutdown(cpu);
       free(cpu);  
128     }     }
129  }  }
130    
# Line 125  void mips64_set_prid(cpu_mips_t *cpu,m_u Line 137  void mips64_set_prid(cpu_mips_t *cpu,m_u
137        cpu->cp0.tlb_entries = MIPS64_TLB_MAX_ENTRIES;        cpu->cp0.tlb_entries = MIPS64_TLB_MAX_ENTRIES;
138  }  }
139    
140  /* Virtual idle loop */  /* Set idle PC value */
141  void mips64_idle_loop(cpu_mips_t *cpu)  void mips64_set_idle_pc(cpu_gen_t *cpu,m_uint64_t addr)
 {  
    struct timespec t_spc;  
    m_tmcnt_t expire;  
   
    expire = m_gettime_usec() + cpu->idle_sleep_time;  
   
    pthread_mutex_lock(&cpu->idle_mutex);  
    t_spc.tv_sec = expire / 1000000;  
    t_spc.tv_nsec = (expire % 1000000) * 1000;  
    pthread_cond_timedwait(&cpu->idle_cond,&cpu->idle_mutex,&t_spc);  
    pthread_mutex_unlock(&cpu->idle_mutex);  
 }  
   
 /* Break idle wait state */  
 void mips64_idle_break_wait(cpu_mips_t *cpu)  
142  {  {
143     pthread_cond_signal(&cpu->idle_cond);     CPU_MIPS64(cpu)->idle_pc = addr;
    cpu->idle_count = 0;  
144  }  }
145    
146  /* Timer IRQ */  /* Timer IRQ */
# Line 161  void *mips64_timer_irq_run(cpu_mips_t *c Line 157  void *mips64_timer_irq_run(cpu_mips_t *c
157     threshold = cpu->timer_irq_freq * 10;     threshold = cpu->timer_irq_freq * 10;
158     expire = m_gettime_usec() + interval;     expire = m_gettime_usec() + interval;
159    
160     while(cpu->state != MIPS_CPU_HALTED) {     while(cpu->gen->state != CPU_STATE_HALTED) {
161        pthread_mutex_lock(&umutex);        pthread_mutex_lock(&umutex);
162        t_spc.tv_sec = expire / 1000000;        t_spc.tv_sec = expire / 1000000;
163        t_spc.tv_nsec = (expire % 1000000) * 1000;        t_spc.tv_nsec = (expire % 1000000) * 1000;
# Line 169  void *mips64_timer_irq_run(cpu_mips_t *c Line 165  void *mips64_timer_irq_run(cpu_mips_t *c
165        pthread_mutex_unlock(&umutex);        pthread_mutex_unlock(&umutex);
166    
167        if (likely(!cpu->irq_disable) &&        if (likely(!cpu->irq_disable) &&
168            likely(cpu->state == MIPS_CPU_RUNNING))            likely(cpu->gen->state == CPU_STATE_RUNNING))
169        {        {
170           cpu->timer_irq_pending++;           cpu->timer_irq_pending++;
171    
# Line 201  struct mips64_idle_pc_hash { Line 197  struct mips64_idle_pc_hash {
197  };  };
198    
199  /* Determine an "idling" PC */  /* Determine an "idling" PC */
200  int mips64_get_idling_pc(cpu_mips_t *cpu)  int mips64_get_idling_pc(cpu_gen_t *cpu)
201  {  {
202       cpu_mips_t *mcpu = CPU_MIPS64(cpu);
203     struct mips64_idle_pc_hash **pc_hash,*p;     struct mips64_idle_pc_hash **pc_hash,*p;
204     struct mips64_idle_pc *res;     struct cpu_idle_pc *res;
205     u_int h_index,res_count;     u_int h_index,res_count;
206     m_uint64_t cur_pc;     m_uint64_t cur_pc;
207     int i;     int i;
208    
209     cpu->idle_pc_prop_count = 0;     cpu->idle_pc_prop_count = 0;
210    
211     if (cpu->idle_pc != 0) {     if (mcpu->idle_pc != 0) {
212        printf("\nYou already use an idle PC, using the calibration would give "        printf("\nYou already use an idle PC, using the calibration would give "
213               "incorrect results.\n");               "incorrect results.\n");
214        return(-1);        return(-1);
# Line 219  int mips64_get_idling_pc(cpu_mips_t *cpu Line 216  int mips64_get_idling_pc(cpu_mips_t *cpu
216    
217     printf("\nPlease wait while gathering statistics...\n");     printf("\nPlease wait while gathering statistics...\n");
218    
219     pc_hash = calloc(IDLE_HASH_SIZE,sizeof(struct mips64_idle_pc *));     pc_hash = calloc(IDLE_HASH_SIZE,sizeof(struct mips64_idle_pc_hash *));
220    
221     /* Disable IRQ */     /* Disable IRQ */
222     cpu->irq_disable = TRUE;     mcpu->irq_disable = TRUE;
223    
224     /* Take 1000 measures, each mesure every 10ms */     /* Take 1000 measures, each mesure every 10ms */
225     for(i=0;i<1000;i++) {     for(i=0;i<1000;i++) {
226        cur_pc = cpu->pc;        cur_pc = mcpu->pc;
227        h_index = (cur_pc >> 2) & (IDLE_HASH_SIZE-1);        h_index = (cur_pc >> 2) & (IDLE_HASH_SIZE-1);
228    
229        for(p=pc_hash[h_index];p;p=p->next)        for(p=pc_hash[h_index];p;p=p->next)
# Line 256  int mips64_get_idling_pc(cpu_mips_t *cpu Line 253  int mips64_get_idling_pc(cpu_mips_t *cpu
253              res->pc    = p->pc;              res->pc    = p->pc;
254              res->count = p->count;              res->count = p->count;
255    
256              if (cpu->idle_pc_prop_count >= MIPS64_IDLE_PC_MAX_RES)              if (cpu->idle_pc_prop_count >= CPU_IDLE_PC_MAX_RES)
257                 goto done;                 goto done;
258           }           }
259     }     }
# Line 276  int mips64_get_idling_pc(cpu_mips_t *cpu Line 273  int mips64_get_idling_pc(cpu_mips_t *cpu
273               cpu->idle_pc_prop[0].pc);               cpu->idle_pc_prop[0].pc);
274     } else {     } else {
275        printf("Done. No suggestion for idling PC\n");        printf("Done. No suggestion for idling PC\n");
276    
277          for(i=0;i<IDLE_HASH_SIZE;i++)
278             for(p=pc_hash[i];p;p=p->next) {
279                printf("  0x%16.16llx (%3u)\n",p->pc,p->count);
280    
281                if (cpu->idle_pc_prop_count < CPU_IDLE_PC_MAX_RES) {
282                   res = &cpu->idle_pc_prop[cpu->idle_pc_prop_count++];
283    
284                   res->pc    = p->pc;
285                   res->count = p->count;
286                }
287             }
288          
289          printf("\n");
290     }     }
291    
292     /* Re-enable IRQ */     /* Re-enable IRQ */
293     cpu->irq_disable = FALSE;     mcpu->irq_disable = FALSE;
294     return(0);     return(0);
295  }  }
296    
297    /* Set an IRQ (VM IRQ standard routing) */
298    void mips64_vm_set_irq(vm_instance_t *vm,u_int irq)
299    {
300       cpu_mips_t *boot_cpu;
301    
302       boot_cpu = CPU_MIPS64(vm->boot_cpu);
303    
304       if (boot_cpu->irq_disable) {
305          boot_cpu->irq_pending = 0;
306          return;
307       }
308    
309       mips64_set_irq(boot_cpu,irq);
310    
311       if (boot_cpu->irq_idle_preempt[irq])
312          cpu_idle_break_wait(vm->boot_cpu);
313    }
314    
315    /* Clear an IRQ (VM IRQ standard routing) */
316    void mips64_vm_clear_irq(vm_instance_t *vm,u_int irq)
317    {
318       cpu_mips_t *boot_cpu;
319    
320       boot_cpu = CPU_MIPS64(vm->boot_cpu);
321       mips64_clear_irq(boot_cpu,irq);
322    }
323    
324  /* Update the IRQ flag (inline) */  /* Update the IRQ flag (inline) */
325  static forced_inline int mips64_update_irq_flag_fast(cpu_mips_t *cpu)  static forced_inline int mips64_update_irq_flag_fast(cpu_mips_t *cpu)
326  {  {
# Line 424  fastcall void mips64_exec_syscall(cpu_mi Line 462  fastcall void mips64_exec_syscall(cpu_mi
462            cpu->gpr[MIPS_GPR_A0], cpu->gpr[MIPS_GPR_A1],            cpu->gpr[MIPS_GPR_A0], cpu->gpr[MIPS_GPR_A1],
463            cpu->gpr[MIPS_GPR_A2], cpu->gpr[MIPS_GPR_A3]);            cpu->gpr[MIPS_GPR_A2], cpu->gpr[MIPS_GPR_A3]);
464  #endif  #endif
465      
466     /* XXX TODO: Branch Delay slot */     /* XXX TODO: Branch Delay slot */
467     mips64_trigger_exception(cpu,MIPS_CP0_CAUSE_SYSCALL,0);     mips64_trigger_exception(cpu,MIPS_CP0_CAUSE_SYSCALL,0);
468  }  }
# Line 433  fastcall void mips64_exec_syscall(cpu_mi Line 471  fastcall void mips64_exec_syscall(cpu_mi
471  fastcall void mips64_exec_break(cpu_mips_t *cpu,u_int code)  fastcall void mips64_exec_break(cpu_mips_t *cpu,u_int code)
472  {  {
473     printf("MIPS64: BREAK instruction (code=%u)\n",code);     printf("MIPS64: BREAK instruction (code=%u)\n",code);
474     mips64_dump_regs(cpu);     mips64_dump_regs(cpu->gen);
475    
476     /* XXX TODO: Branch Delay slot */     /* XXX TODO: Branch Delay slot */
477     mips64_trigger_exception(cpu,MIPS_CP0_CAUSE_BP,0);     mips64_trigger_exception(cpu,MIPS_CP0_CAUSE_BP,0);
# Line 492  fastcall void mips64_exec_mtc1(cpu_mips_ Line 530  fastcall void mips64_exec_mtc1(cpu_mips_
530  /* Virtual breakpoint */  /* Virtual breakpoint */
531  fastcall void mips64_run_breakpoint(cpu_mips_t *cpu)  fastcall void mips64_run_breakpoint(cpu_mips_t *cpu)
532  {  {
533     cpu_log(cpu,"BREAKPOINT",     cpu_log(cpu->gen,"BREAKPOINT",
534             "Virtual breakpoint reached at PC=0x%llx\n",cpu->pc);             "Virtual breakpoint reached at PC=0x%llx\n",cpu->pc);
535    
536     printf("[[[ Virtual Breakpoint reached at PC=0x%llx RA=0x%llx]]]\n",     printf("[[[ Virtual Breakpoint reached at PC=0x%llx RA=0x%llx]]]\n",
537            cpu->pc,cpu->gpr[MIPS_GPR_RA]);            cpu->pc,cpu->gpr[MIPS_GPR_RA]);
538    
539     mips64_dump_regs(cpu);     mips64_dump_regs(cpu->gen);
540     memlog_dump(cpu);     memlog_dump(cpu->gen);
541  }  }
542    
543  /* Add a virtual breakpoint */  /* Add a virtual breakpoint */
544  int mips64_add_breakpoint(cpu_mips_t *cpu,m_uint64_t pc)  int mips64_add_breakpoint(cpu_gen_t *cpu,m_uint64_t pc)
545  {  {
546       cpu_mips_t *mcpu = CPU_MIPS64(cpu);
547     int i;     int i;
548    
549     for(i=0;i<MIPS64_MAX_BREAKPOINTS;i++)     for(i=0;i<MIPS64_MAX_BREAKPOINTS;i++)
550        if (!cpu->breakpoints[i])        if (!mcpu->breakpoints[i])
551           break;           break;
552    
553     if (i == MIPS64_MAX_BREAKPOINTS)     if (i == MIPS64_MAX_BREAKPOINTS)
554        return(-1);        return(-1);
555    
556     cpu->breakpoints[i] = pc;     mcpu->breakpoints[i] = pc;
557     cpu->breakpoints_enabled = TRUE;     mcpu->breakpoints_enabled = TRUE;
558     return(0);     return(0);
559  }  }
560    
561  /* Remove a virtual breakpoint */  /* Remove a virtual breakpoint */
562  void mips64_remove_breakpoint(cpu_mips_t *cpu,m_uint64_t pc)  void mips64_remove_breakpoint(cpu_gen_t *cpu,m_uint64_t pc)
563  {  {  
564       cpu_mips_t *mcpu = CPU_MIPS64(cpu);
565     int i,j;     int i,j;
566    
567     for(i=0;i<MIPS64_MAX_BREAKPOINTS;i++)     for(i=0;i<MIPS64_MAX_BREAKPOINTS;i++)
568        if (cpu->breakpoints[i] == pc)        if (mcpu->breakpoints[i] == pc)
569        {        {
570           for(j=i;j<MIPS64_MAX_BREAKPOINTS-1;j++)           for(j=i;j<MIPS64_MAX_BREAKPOINTS-1;j++)
571              cpu->breakpoints[j] = cpu->breakpoints[j+1];              mcpu->breakpoints[j] = mcpu->breakpoints[j+1];
572    
573           cpu->breakpoints[MIPS64_MAX_BREAKPOINTS-1] = 0;           mcpu->breakpoints[MIPS64_MAX_BREAKPOINTS-1] = 0;
574        }        }
575    
576     for(i=0;i<MIPS64_MAX_BREAKPOINTS;i++)     for(i=0;i<MIPS64_MAX_BREAKPOINTS;i++)
577        if (cpu->breakpoints[i] != 0)        if (mcpu->breakpoints[i] != 0)
578           return;           return;
579    
580     cpu->breakpoints_enabled = TRUE;     mcpu->breakpoints_enabled = FALSE;
581  }  }
582    
583  /* Debugging for register-jump to address 0 */  /* Debugging for register-jump to address 0 */
584  fastcall void mips64_debug_jr0(cpu_mips_t *cpu)  fastcall void mips64_debug_jr0(cpu_mips_t *cpu)
585  {  {
586     printf("MIPS64: cpu %p jumping to address 0...\n",cpu);     printf("MIPS64: cpu %p jumping to address 0...\n",cpu);
587     mips64_dump_regs(cpu);     mips64_dump_regs(cpu->gen);
588    }
589    
590    /* Set a register */
591    void mips64_reg_set(cpu_gen_t *cpu,u_int reg,m_uint64_t val)
592    {
593       if (reg < MIPS64_GPR_NR)
594          CPU_MIPS64(cpu)->gpr[reg] = val;
595  }  }
596    
597  /* Dump registers of a MIPS64 processor */  /* Dump registers of a MIPS64 processor */
598  void mips64_dump_regs(cpu_mips_t *cpu)  void mips64_dump_regs(cpu_gen_t *cpu)
599  {    {
600       cpu_mips_t *mcpu = CPU_MIPS64(cpu);
601     mips_insn_t *ptr,insn;     mips_insn_t *ptr,insn;
602     char buffer[80];     char buffer[80];
603     int i;     int i;
# Line 558  void mips64_dump_regs(cpu_mips_t *cpu) Line 606  void mips64_dump_regs(cpu_mips_t *cpu)
606    
607     for(i=0;i<MIPS64_GPR_NR/2;i++) {     for(i=0;i<MIPS64_GPR_NR/2;i++) {
608        printf("  %s ($%2d) = 0x%16.16llx   %s ($%2d) = 0x%16.16llx\n",        printf("  %s ($%2d) = 0x%16.16llx   %s ($%2d) = 0x%16.16llx\n",
609               mips64_gpr_reg_names[i*2], i*2, cpu->gpr[i*2],               mips64_gpr_reg_names[i*2], i*2, mcpu->gpr[i*2],
610               mips64_gpr_reg_names[(i*2)+1], (i*2)+1, cpu->gpr[(i*2)+1]);               mips64_gpr_reg_names[(i*2)+1], (i*2)+1, mcpu->gpr[(i*2)+1]);
611     }     }
612    
613     printf("  lo = 0x%16.16llx, hi = 0x%16.16llx\n", cpu->lo, cpu->hi);     printf("  lo = 0x%16.16llx, hi = 0x%16.16llx\n", mcpu->lo, mcpu->hi);
614     printf("  pc = 0x%16.16llx, ll_bit = %u\n", cpu->pc, cpu->ll_bit);     printf("  pc = 0x%16.16llx, ll_bit = %u\n", mcpu->pc, mcpu->ll_bit);
615    
616     /* Fetch the current instruction */     /* Fetch the current instruction */
617     ptr = cpu->mem_op_lookup(cpu,cpu->pc);     ptr = mcpu->mem_op_lookup(mcpu,mcpu->pc);
618     if (ptr) {     if (ptr) {
619        insn = vmtoh32(*ptr);        insn = vmtoh32(*ptr);
620    
621        if (mips64_dump_insn(buffer,sizeof(buffer),1,cpu->pc,insn) != -1)        if (mips64_dump_insn(buffer,sizeof(buffer),1,mcpu->pc,insn) != -1)
622           printf("  Instruction: %s\n",buffer);           printf("  Instruction: %s\n",buffer);
623     }     }
624    
# Line 578  void mips64_dump_regs(cpu_mips_t *cpu) Line 626  void mips64_dump_regs(cpu_mips_t *cpu)
626    
627     for(i=0;i<MIPS64_CP0_REG_NR/2;i++) {     for(i=0;i<MIPS64_CP0_REG_NR/2;i++) {
628        printf("  %-10s ($%2d) = 0x%16.16llx   %-10s ($%2d) = 0x%16.16llx\n",        printf("  %-10s ($%2d) = 0x%16.16llx   %-10s ($%2d) = 0x%16.16llx\n",
629               mips64_cp0_reg_names[i*2], i*2, cp0_get_reg(cpu,i*2),               mips64_cp0_reg_names[i*2], i*2,
630               mips64_cp0_reg_names[(i*2)+1], (i*2)+1, cp0_get_reg(cpu,(i*2)+1));               mips64_cp0_get_reg(mcpu,i*2),
631                 mips64_cp0_reg_names[(i*2)+1], (i*2)+1,
632                 mips64_cp0_get_reg(mcpu,(i*2)+1));
633     }     }
634    
635     printf("\n  IRQ count: %llu, IRQ false positives: %llu, "     printf("\n  IRQ count: %llu, IRQ false positives: %llu, "
636            "IRQ Pending: %u\n",            "IRQ Pending: %u\n",
637            cpu->irq_count,cpu->irq_fp_count,cpu->irq_pending);            mcpu->irq_count,mcpu->irq_fp_count,mcpu->irq_pending);
638    
639     printf("  Timer IRQ count: %llu, pending: %u, timer drift: %u\n\n",     printf("  Timer IRQ count: %llu, pending: %u, timer drift: %u\n\n",
640            cpu->timer_irq_count,cpu->timer_irq_pending,cpu->timer_drift);            mcpu->timer_irq_count,mcpu->timer_irq_pending,mcpu->timer_drift);
641    
642       printf("  Device access count: %llu\n",cpu->dev_access_counter);
643     printf("\n");     printf("\n");
644  }  }
645    
# Line 732  int mips64_restore_state(cpu_mips_t *cpu Line 783  int mips64_restore_state(cpu_mips_t *cpu
783        }        }
784    
785        /* cp0 register ? */        /* cp0 register ? */
786        if ((index = cp0_get_reg_index(buffer)) != -1) {        if ((index = mips64_cp0_get_reg_index(buffer)) != -1) {
787           cpu->cp0.reg[index] = mips64_hex_u64(value,NULL);           cpu->cp0.reg[index] = mips64_hex_u64(value,NULL);
788           continue;           continue;
789        }        }
# Line 790  int mips64_restore_state(cpu_mips_t *cpu Line 841  int mips64_restore_state(cpu_mips_t *cpu
841        }        }
842     }     }
843    
844     cp0_map_all_tlb_to_mts(cpu);     mips64_cp0_map_all_tlb_to_mts(cpu);
845    
846     mips64_dump_regs(cpu);     mips64_dump_regs(cpu->gen);
847     tlb_dump(cpu);     mips64_tlb_dump(cpu->gen);
848    
849     fclose(fd);     fclose(fd);
850     return(0);     return(0);
# Line 804  int mips64_load_raw_image(cpu_mips_t *cp Line 855  int mips64_load_raw_image(cpu_mips_t *cp
855  {    {  
856     struct stat file_info;     struct stat file_info;
857     size_t len,clen;     size_t len,clen;
858       m_uint32_t remain;
859     void *haddr;     void *haddr;
860     FILE *bfd;     FILE *bfd;
861    
# Line 837  int mips64_load_raw_image(cpu_mips_t *cp Line 889  int mips64_load_raw_image(cpu_mips_t *cp
889        else        else
890           clen = len;           clen = len;
891    
892          remain = MIPS_MIN_PAGE_SIZE;
893          remain -= (vaddr - (vaddr & MIPS_MIN_PAGE_MASK));
894          
895          clen = m_min(clen,remain);
896    
897        if (fread((u_char *)haddr,clen,1,bfd) != 1)        if (fread((u_char *)haddr,clen,1,bfd) != 1)
898           break;           break;
899                
900        vaddr += MIPS_MIN_PAGE_SIZE;        vaddr += clen;
901        len -= clen;        len -= clen;
902     }     }
903        
# Line 853  int mips64_load_elf_image(cpu_mips_t *cp Line 910  int mips64_load_elf_image(cpu_mips_t *cp
910                            m_uint32_t *entry_point)                            m_uint32_t *entry_point)
911  {  {
912     m_uint64_t vaddr;     m_uint64_t vaddr;
913       m_uint32_t remain;
914     void *haddr;     void *haddr;
915     Elf32_Ehdr *ehdr;     Elf32_Ehdr *ehdr;
916     Elf32_Shdr *shdr;     Elf32_Shdr *shdr;
# Line 935  int mips64_load_elf_image(cpu_mips_t *cp Line 993  int mips64_load_elf_image(cpu_mips_t *cp
993              else              else
994                 clen = len;                 clen = len;
995    
996              clen = fread((u_char *)haddr,clen,1,bfd);              remain = PPC32_MIN_PAGE_SIZE;
997                remain -= (vaddr - (vaddr & PPC32_MIN_PAGE_MASK));
998    
999                clen = m_min(clen,remain);
1000    
1001              if (clen != 1)              if (fread((u_char *)haddr,clen,1,bfd) < 1)
1002                 break;                 break;
1003    
1004              vaddr += MIPS_MIN_PAGE_SIZE;              vaddr += clen;
1005              len -= clen;              len -= clen;
1006           }           }
1007        }        }
# Line 1017  int mips64_sym_load_file(cpu_mips_t *cpu Line 1078  int mips64_sym_load_file(cpu_mips_t *cpu
1078     FILE *fd;     FILE *fd;
1079    
1080     if (!cpu->sym_tree && (mips64_sym_create_tree(cpu) == -1)) {     if (!cpu->sym_tree && (mips64_sym_create_tree(cpu) == -1)) {
1081        fprintf(stderr,"CPU%u: Unable to create symbol tree.\n",cpu->id);        fprintf(stderr,"CPU%u: Unable to create symbol tree.\n",cpu->gen->id);
1082        return(-1);        return(-1);
1083     }     }
1084    

Legend:
Removed from v.6  
changed lines
  Added in v.12

  ViewVC Help
Powered by ViewVC 1.1.26