/[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.5/mips64.c revision 1 by dpavlin, Sat Oct 6 16:01:44 2007 UTC upstream/dynamips-0.2.7-RC2/mips64.c revision 8 by dpavlin, Sat Oct 6 16:24:54 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_shutdown(cpu);     mips64_set_addr_mode(cpu,32/*64*/);  /* zzz */
72     mts64_init(cpu);     cpu->gen->mts_rebuild(cpu->gen);
    mts_init_memop_vectors(cpu);  
    cpu->mts_rebuild(cpu);  
73    
74     /* Flush JIT structures */     /* Flush JIT structures */
75     mips64_jit_flush(cpu,0);     mips64_jit_flush(cpu,0);
# Line 80  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 = 50000;     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 96  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 112  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 127  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;
144  }  }
145    
146  /* Timer IRQ */  /* Timer IRQ */
# Line 162  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 170  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 192  void *mips64_timer_irq_run(cpu_mips_t *c Line 187  void *mips64_timer_irq_run(cpu_mips_t *c
187     return NULL;     return NULL;
188  }  }
189    
190    #define IDLE_HASH_SIZE  8192
191    
192  /* Idle PC hash item */  /* Idle PC hash item */
193  struct mips64_idle_pc {  struct mips64_idle_pc_hash {
194     m_uint64_t pc;     m_uint64_t pc;
195     u_int count;     u_int count;
196     struct mips64_idle_pc *next;     struct mips64_idle_pc_hash *next;
197  };  };
198    
 #define IDLE_HASH_SIZE  8192  
 #define IDLE_MAX_RES    10  
   
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     struct mips64_idle_pc *res[IDLE_MAX_RES];     cpu_mips_t *mcpu = CPU_MIPS64(cpu);
203     struct mips64_idle_pc **pc_hash,*p;     struct mips64_idle_pc_hash **pc_hash,*p;
204       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     if (cpu->idle_pc != 0) {     cpu->idle_pc_prop_count = 0;
210    
211       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 248  int mips64_get_idling_pc(cpu_mips_t *cpu Line 245  int mips64_get_idling_pc(cpu_mips_t *cpu
245     }     }
246    
247     /* Select PCs */     /* Select PCs */
    memset(res,0,sizeof(res));  
   
248     for(i=0,res_count=0;i<IDLE_HASH_SIZE;i++) {     for(i=0,res_count=0;i<IDLE_HASH_SIZE;i++) {
249        for(p=pc_hash[i];p;p=p->next)        for(p=pc_hash[i];p;p=p->next)
250           if ((p->count >= 20) && (p->count <= 80)) {           if ((p->count >= 20) && (p->count <= 80)) {
251              res[res_count++] = p;              res = &cpu->idle_pc_prop[cpu->idle_pc_prop_count++];
252    
253                res->pc    = p->pc;
254                res->count = p->count;
255    
256              if (res_count >= IDLE_MAX_RES)              if (cpu->idle_pc_prop_count >= CPU_IDLE_PC_MAX_RES)
257                 goto done;                 goto done;
258           }           }
259     }     }
260    
261   done:   done:
262     /* Set idle PC */     /* Set idle PC */
263     if (res_count) {     if (cpu->idle_pc_prop_count) {
264        printf("Done. Suggested idling PC:\n");        printf("Done. Suggested idling PC:\n");
265    
266        for(i=0;i<res_count;i++)        for(i=0;i<cpu->idle_pc_prop_count;i++) {
267           printf("   0x%llx (count=%u)\n",res[i]->pc,res[i]->count);           printf("   0x%llx (count=%u)\n",
268                            cpu->idle_pc_prop[i].pc,
269                    cpu->idle_pc_prop[i].count);
270          }        
271    
272        printf("Restart the emulator with \"--idle-pc=0x%llx\" (for example)\n",        printf("Restart the emulator with \"--idle-pc=0x%llx\" (for example)\n",
273               res[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 429  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 488  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 ]]]\n",cpu->pc);     printf("[[[ Virtual Breakpoint reached at PC=0x%llx RA=0x%llx]]]\n",
537     mips64_dump_regs(cpu);            cpu->pc,cpu->gpr[MIPS_GPR_RA]);
538     memlog_dump(cpu);  
539       mips64_dump_regs(cpu->gen);
540       memlog_dump(cpu->gen);
541    }
542    
543    /* Add a virtual breakpoint */
544    int mips64_add_breakpoint(cpu_gen_t *cpu,m_uint64_t pc)
545    {
546       cpu_mips_t *mcpu = CPU_MIPS64(cpu);
547       int i;
548    
549       for(i=0;i<MIPS64_MAX_BREAKPOINTS;i++)
550          if (!mcpu->breakpoints[i])
551             break;
552    
553       if (i == MIPS64_MAX_BREAKPOINTS)
554          return(-1);
555    
556       mcpu->breakpoints[i] = pc;
557       mcpu->breakpoints_enabled = TRUE;
558       return(0);
559    }
560    
561    /* Remove a virtual breakpoint */
562    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;
566    
567       for(i=0;i<MIPS64_MAX_BREAKPOINTS;i++)
568          if (mcpu->breakpoints[i] == pc)
569          {
570             for(j=i;j<MIPS64_MAX_BREAKPOINTS-1;j++)
571                mcpu->breakpoints[j] = mcpu->breakpoints[j+1];
572    
573             mcpu->breakpoints[MIPS64_MAX_BREAKPOINTS-1] = 0;
574          }
575    
576       for(i=0;i<MIPS64_MAX_BREAKPOINTS;i++)
577          if (mcpu->breakpoints[i] != 0)
578             return;
579    
580       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 514  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 534  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 688  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 746  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 760  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 793  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 805  int mips64_load_raw_image(cpu_mips_t *cp Line 906  int mips64_load_raw_image(cpu_mips_t *cp
906  }  }
907    
908  /* Load an ELF image into the simulated memory */  /* Load an ELF image into the simulated memory */
909  int mips64_load_elf_image(cpu_mips_t *cpu,char *filename,  int mips64_load_elf_image(cpu_mips_t *cpu,char *filename,int skip_load,
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 857  int mips64_load_elf_image(cpu_mips_t *cp Line 959  int mips64_load_elf_image(cpu_mips_t *cp
959        return(-1);        return(-1);
960     }     }
961    
962     for(i=0;i<ehdr->e_shnum;i++) {     if (!skip_load) {
963        scn = elf_getscn(img_elf,i);        for(i=0;i<ehdr->e_shnum;i++) {
964             scn = elf_getscn(img_elf,i);
965    
966             shdr = elf32_getshdr(scn);
967             name = elf_strptr(img_elf, ehdr->e_shstrndx, (size_t)shdr->sh_name);
968             len  = shdr->sh_size;
969    
970             if (!(shdr->sh_flags & SHF_ALLOC) || !len)
971                continue;
972    
973             fseek(bfd,shdr->sh_offset,SEEK_SET);
974             vaddr = sign_extend(shdr->sh_addr,32);
975    
976             if (cpu->vm->debug_level > 0) {
977                printf("   * Adding section at virtual address 0x%8.8llx "
978                       "(len=0x%8.8lx)\n",vaddr & 0xFFFFFFFF,(u_long)len);
979             }
980            
981             while(len > 0)
982             {
983                haddr = cpu->mem_op_lookup(cpu,vaddr);
984      
985                if (!haddr) {
986                   fprintf(stderr,"load_elf_image: invalid load address 0x%llx\n",
987                           vaddr);
988                   return(-1);
989                }
990    
991        shdr = elf32_getshdr(scn);              if (len > MIPS_MIN_PAGE_SIZE)
992        name = elf_strptr(img_elf, ehdr->e_shstrndx, (size_t)shdr->sh_name);                 clen = MIPS_MIN_PAGE_SIZE;
993        len  = shdr->sh_size;              else
994                   clen = len;
995    
996        if (!(shdr->sh_flags & SHF_ALLOC) || !len)              remain = PPC32_MIN_PAGE_SIZE;
997           continue;              remain -= (vaddr - (vaddr & PPC32_MIN_PAGE_MASK));
998    
999        fseek(bfd,shdr->sh_offset,SEEK_SET);              clen = m_min(clen,remain);
       vaddr = sign_extend(shdr->sh_addr,32);  
1000    
1001        if (cpu->vm->debug_level > 0) {              if (fread((u_char *)haddr,clen,1,bfd) < 1)
1002           printf("   * Adding section at virtual address 0x%8.8llx "                 break;
                 "(len=0x%8.8lx)\n",vaddr & 0xFFFFFFFF,(u_long)len);  
       }  
1003    
1004        while(len > 0)              vaddr += clen;
1005        {              len -= clen;
          haddr = cpu->mem_op_lookup(cpu,vaddr);  
     
          if (!haddr) {  
             fprintf(stderr,"load_elf_image: invalid load address 0x%llx\n",  
                     vaddr);  
             return(-1);  
1006           }           }
   
          if (len > MIPS_MIN_PAGE_SIZE)  
             clen = MIPS_MIN_PAGE_SIZE;  
          else  
             clen = len;  
   
          clen = fread((u_char *)haddr,clen,1,bfd);  
   
          if (clen != 1)  
             break;  
   
          vaddr += MIPS_MIN_PAGE_SIZE;  
          len -= clen;  
1007        }        }
1008       } else {
1009          printf("ELF loading skipped, using a ghost RAM file.\n");
1010     }     }
1011    
1012     printf("ELF entry point: 0x%x\n",ehdr->e_entry);     printf("ELF entry point: 0x%x\n",ehdr->e_entry);
# Line 969  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.1  
changed lines
  Added in v.8

  ViewVC Help
Powered by ViewVC 1.1.26