/[dynamips]/upstream/dynamips-0.2.7-RC1/cpu.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 /upstream/dynamips-0.2.7-RC1/cpu.c

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

upstream/dynamips-0.2.6-RC5/cpu.c revision 6 by dpavlin, Sat Oct 6 16:09:07 2007 UTC upstream/dynamips-0.2.7-RC1/cpu.c revision 7 by dpavlin, Sat Oct 6 16:23:47 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   * Management of CPU groups (for MP systems).   * Management of CPU groups (for MP systems).
# Line 17  Line 17 
17  #include <fcntl.h>  #include <fcntl.h>
18  #include <pthread.h>  #include <pthread.h>
19    
 #include "mips64.h"  
 #include "dynamips.h"  
20  #include "cpu.h"  #include "cpu.h"
21  #include "memory.h"  #include "memory.h"
22  #include "device.h"  #include "device.h"
23  #include "cp0.h"  #include "mips64.h"
24    #include "mips64_cp0.h"
25  #include "mips64_exec.h"  #include "mips64_exec.h"
26    #include "mips64_jit.h"
27    #include "ppc32.h"
28    #include "ppc32_exec.h"
29    #include "ppc32_jit.h"
30    #include "dynamips.h"
31  #include "vm.h"  #include "vm.h"
32    
33  /* Find a CPU in a group given its ID */  /* Find a CPU in a group given its ID */
34  cpu_mips_t *cpu_group_find_id(cpu_group_t *group,u_int id)  cpu_gen_t *cpu_group_find_id(cpu_group_t *group,u_int id)
35  {  {
36     cpu_mips_t *cpu;     cpu_gen_t *cpu;
37    
38     if (!group)     if (!group)
39        return NULL;        return NULL;
# Line 44  cpu_mips_t *cpu_group_find_id(cpu_group_ Line 48  cpu_mips_t *cpu_group_find_id(cpu_group_
48  /* Find the highest CPU ID in a CPU group */  /* Find the highest CPU ID in a CPU group */
49  int cpu_group_find_highest_id(cpu_group_t *group,u_int *highest_id)  int cpu_group_find_highest_id(cpu_group_t *group,u_int *highest_id)
50  {  {
51     cpu_mips_t *cpu;     cpu_gen_t *cpu;
52     u_int max_id = 0;     u_int max_id = 0;
53    
54     if (!group || group->cpu_list)     if (!group || group->cpu_list)
# Line 59  int cpu_group_find_highest_id(cpu_group_ Line 63  int cpu_group_find_highest_id(cpu_group_
63  }  }
64    
65  /* Add a CPU in a CPU group */  /* Add a CPU in a CPU group */
66  int cpu_group_add(cpu_group_t *group,cpu_mips_t *cpu)  int cpu_group_add(cpu_group_t *group,cpu_gen_t *cpu)
67  {  {
68     if (!group)     if (!group)
69        return(-1);        return(-1);
# Line 92  cpu_group_t *cpu_group_create(char *name Line 96  cpu_group_t *cpu_group_create(char *name
96  /* Delete a CPU group */  /* Delete a CPU group */
97  void cpu_group_delete(cpu_group_t *group)  void cpu_group_delete(cpu_group_t *group)
98  {    {  
99     cpu_mips_t *cpu,*next;     cpu_gen_t *cpu,*next;
100    
101     if (group != NULL) {     if (group != NULL) {
102        for(cpu=group->cpu_list;cpu;cpu=next) {        for(cpu=group->cpu_list;cpu;cpu=next) {
# Line 107  void cpu_group_delete(cpu_group_t *group Line 111  void cpu_group_delete(cpu_group_t *group
111  /* Rebuild the MTS subsystem for a CPU group */  /* Rebuild the MTS subsystem for a CPU group */
112  int cpu_group_rebuild_mts(cpu_group_t *group)  int cpu_group_rebuild_mts(cpu_group_t *group)
113  {  {
114     cpu_mips_t *cpu;     cpu_gen_t *cpu;
115    
116     for(cpu=group->cpu_list;cpu;cpu=cpu->next)     for(cpu=group->cpu_list;cpu;cpu=cpu->next)
117        cpu->mts_rebuild(cpu);        cpu->mts_rebuild(cpu);
# Line 116  int cpu_group_rebuild_mts(cpu_group_t *g Line 120  int cpu_group_rebuild_mts(cpu_group_t *g
120  }  }
121    
122  /* Log a message for a CPU */  /* Log a message for a CPU */
123  void cpu_log(cpu_mips_t *cpu,char *module,char *format,...)  void cpu_log(cpu_gen_t *cpu,char *module,char *format,...)
124  {  {
125     char buffer[256];     char buffer[256];
126     va_list ap;     va_list ap;
# Line 128  void cpu_log(cpu_mips_t *cpu,char *modul Line 132  void cpu_log(cpu_mips_t *cpu,char *modul
132  }  }
133    
134  /* Create a new CPU */  /* Create a new CPU */
135  cpu_mips_t *cpu_create(vm_instance_t *vm,u_int id)  cpu_gen_t *cpu_create(vm_instance_t *vm,u_int type,u_int id)
136  {  {
137     void *(*cpu_run_fn)(void *);     void *(*cpu_run_fn)(void *);
138     cpu_mips_t *cpu;     cpu_gen_t *cpu;
139    
140     if (!(cpu = malloc(sizeof(*cpu))))     if (!(cpu = malloc(sizeof(*cpu))))
141        return NULL;        return NULL;
142    
143     memset(cpu,0,sizeof(*cpu));     memset(cpu,0,sizeof(*cpu));
144     cpu->vm = vm;     cpu->vm = vm;
   
    /* by default, use a standard initialization (CPU exec is suspended) */  
    mips64_init(cpu);  
145     cpu->id = id;     cpu->id = id;
146     cpu->state = MIPS_CPU_SUSPENDED;     cpu->type = type;
147       cpu->state = CPU_STATE_SUSPENDED;
148    
149     cpu_run_fn = (void *)insn_block_execute;     switch(cpu->type) {
150  #if __GNUC__ > 2        case CPU_TYPE_MIPS64:
151     if (!cpu->vm->jit_use) {           CPU_MIPS64(cpu)->vm = vm;
152        cpu_run_fn = (void *)mips64_exec_run_cpu;           CPU_MIPS64(cpu)->gen = cpu;
153     } else {           mips64_init(CPU_MIPS64(cpu));
154        mips64_jit_init(cpu);  
155             cpu_run_fn = (void *)mips64_jit_run_cpu;
156    
157             if (!cpu->vm->jit_use)
158                cpu_run_fn = (void *)mips64_exec_run_cpu;
159             else
160                mips64_jit_init(CPU_MIPS64(cpu));
161             break;
162    
163          case CPU_TYPE_PPC32:
164             CPU_PPC32(cpu)->vm = vm;
165             CPU_PPC32(cpu)->gen = cpu;
166             ppc32_init(CPU_PPC32(cpu));
167    
168             cpu_run_fn = (void *)ppc32_jit_run_cpu;
169    
170             if (!cpu->vm->jit_use)
171                cpu_run_fn = (void *)ppc32_exec_run_cpu;
172             else
173                ppc32_jit_init(CPU_PPC32(cpu));
174             break;
175    
176          default:
177             fprintf(stderr,"CPU type %u is not supported yet\n",cpu->type);
178             abort();
179             break;
180     }     }
 #endif  
181    
182     /* create the CPU thread execution */     /* create the CPU thread execution */
183     if (pthread_create(&cpu->cpu_thread,NULL,cpu_run_fn,cpu) != 0) {     if (pthread_create(&cpu->cpu_thread,NULL,cpu_run_fn,cpu) != 0) {
# Line 164  cpu_mips_t *cpu_create(vm_instance_t *vm Line 190  cpu_mips_t *cpu_create(vm_instance_t *vm
190  }  }
191    
192  /* Delete a CPU */  /* Delete a CPU */
193  void cpu_delete(cpu_mips_t *cpu)  void cpu_delete(cpu_gen_t *cpu)
194  {  {
195     if (cpu) {     if (cpu) {
196        /* Stop activity of this CPU */        /* Stop activity of this CPU */
# Line 172  void cpu_delete(cpu_mips_t *cpu) Line 198  void cpu_delete(cpu_mips_t *cpu)
198        pthread_join(cpu->cpu_thread,NULL);        pthread_join(cpu->cpu_thread,NULL);
199    
200        /* Free resources */        /* Free resources */
201        mips64_delete(cpu);        switch(cpu->type) {
202             case CPU_TYPE_MIPS64:
203                mips64_delete(CPU_MIPS64(cpu));
204                break;
205    
206             case CPU_TYPE_PPC32:
207                ppc32_delete(CPU_PPC32(cpu));
208                break;
209          }
210    
211          free(cpu);
212     }     }
213  }  }
214    
215  /* Start a CPU */  /* Start a CPU */
216  void cpu_start(cpu_mips_t *cpu)  void cpu_start(cpu_gen_t *cpu)
217  {  {
218     if (cpu) {     if (cpu) {
219        cpu_log(cpu,"CPU_STATE","Starting CPU (old state=%u)...\n",cpu->state);        cpu_log(cpu,"CPU_STATE","Starting CPU (old state=%u)...\n",cpu->state);
220        cpu->state = MIPS_CPU_RUNNING;        cpu->state = CPU_STATE_RUNNING;
221     }     }
222  }  }
223    
224  /* Stop a CPU */  /* Stop a CPU */
225  void cpu_stop(cpu_mips_t *cpu)  void cpu_stop(cpu_gen_t *cpu)
226  {  {
227     if (cpu) {     if (cpu) {
228        cpu_log(cpu,"CPU_STATE","Halting CPU (old state=%u)...\n",cpu->state);        cpu_log(cpu,"CPU_STATE","Halting CPU (old state=%u)...\n",cpu->state);
229        cpu->state = MIPS_CPU_HALTED;        cpu->state = CPU_STATE_HALTED;
230     }     }
231  }  }
232    
233  /* Start all CPUs of a CPU group */  /* Start all CPUs of a CPU group */
234  void cpu_group_start_all_cpu(cpu_group_t *group)  void cpu_group_start_all_cpu(cpu_group_t *group)
235  {  {
236     cpu_mips_t *cpu;     cpu_gen_t *cpu;
237        
238     for(cpu=group->cpu_list;cpu;cpu=cpu->next)     for(cpu=group->cpu_list;cpu;cpu=cpu->next)
239        cpu_start(cpu);        cpu_start(cpu);
# Line 206  void cpu_group_start_all_cpu(cpu_group_t Line 242  void cpu_group_start_all_cpu(cpu_group_t
242  /* Stop all CPUs of a CPU group */  /* Stop all CPUs of a CPU group */
243  void cpu_group_stop_all_cpu(cpu_group_t *group)  void cpu_group_stop_all_cpu(cpu_group_t *group)
244  {  {
245     cpu_mips_t *cpu;     cpu_gen_t *cpu;
246        
247     for(cpu=group->cpu_list;cpu;cpu=cpu->next)     for(cpu=group->cpu_list;cpu;cpu=cpu->next)
248        cpu_stop(cpu);        cpu_stop(cpu);
# Line 215  void cpu_group_stop_all_cpu(cpu_group_t Line 251  void cpu_group_stop_all_cpu(cpu_group_t
251  /* Set a state of all CPUs of a CPU group */  /* Set a state of all CPUs of a CPU group */
252  void cpu_group_set_state(cpu_group_t *group,u_int state)  void cpu_group_set_state(cpu_group_t *group,u_int state)
253  {  {
254     cpu_mips_t *cpu;     cpu_gen_t *cpu;
255        
256     for(cpu=group->cpu_list;cpu;cpu=cpu->next)     for(cpu=group->cpu_list;cpu;cpu=cpu->next)
257        cpu->state = state;        cpu->state = state;
# Line 224  void cpu_group_set_state(cpu_group_t *gr Line 260  void cpu_group_set_state(cpu_group_t *gr
260  /* Returns TRUE if all CPUs in a CPU group are inactive */  /* Returns TRUE if all CPUs in a CPU group are inactive */
261  static int cpu_group_check_activity(cpu_group_t *group)  static int cpu_group_check_activity(cpu_group_t *group)
262  {  {
263     cpu_mips_t *cpu;     cpu_gen_t *cpu;
264    
265     for(cpu=group->cpu_list;cpu;cpu=cpu->next) {     for(cpu=group->cpu_list;cpu;cpu=cpu->next) {
266        if (!cpu->cpu_thread_running)        if (!cpu->cpu_thread_running)
267           continue;           continue;
268    
269        if ((cpu->state == MIPS_CPU_RUNNING) || !cpu->seq_state)        if ((cpu->state == CPU_STATE_RUNNING) || !cpu->seq_state)
270           return(FALSE);           return(FALSE);
271     }     }
272    
# Line 240  static int cpu_group_check_activity(cpu_ Line 276  static int cpu_group_check_activity(cpu_
276  /* Synchronize on CPUs (all CPUs must be inactive) */  /* Synchronize on CPUs (all CPUs must be inactive) */
277  int cpu_group_sync_state(cpu_group_t *group)  int cpu_group_sync_state(cpu_group_t *group)
278  {    {  
279     cpu_mips_t *cpu;     cpu_gen_t *cpu;
280     m_tmcnt_t t1,t2;     m_tmcnt_t t1,t2;
281    
282     /* Check that CPU activity is really suspended */     /* Check that CPU activity is really suspended */
# Line 264  int cpu_group_sync_state(cpu_group_t *gr Line 300  int cpu_group_sync_state(cpu_group_t *gr
300  /* Save state of all CPUs */  /* Save state of all CPUs */
301  int cpu_group_save_state(cpu_group_t *group)  int cpu_group_save_state(cpu_group_t *group)
302  {  {
303     cpu_mips_t *cpu;     cpu_gen_t *cpu;
304        
305     for(cpu=group->cpu_list;cpu;cpu=cpu->next)     for(cpu=group->cpu_list;cpu;cpu=cpu->next)
306        cpu->prev_state = cpu->state;        cpu->prev_state = cpu->state;
# Line 275  int cpu_group_save_state(cpu_group_t *gr Line 311  int cpu_group_save_state(cpu_group_t *gr
311  /* Restore state of all CPUs */  /* Restore state of all CPUs */
312  int cpu_group_restore_state(cpu_group_t *group)  int cpu_group_restore_state(cpu_group_t *group)
313  {  {
314     cpu_mips_t *cpu;     cpu_gen_t *cpu;
315        
316     for(cpu=group->cpu_list;cpu;cpu=cpu->next)     for(cpu=group->cpu_list;cpu;cpu=cpu->next)
317        cpu->state = cpu->prev_state;        cpu->state = cpu->prev_state;
318    
319     return(TRUE);     return(TRUE);
320  }  }
321    
322    /* Virtual idle loop */
323    void cpu_idle_loop(cpu_gen_t *cpu)
324    {
325       struct timespec t_spc;
326       m_tmcnt_t expire;
327    
328       expire = m_gettime_usec() + cpu->idle_sleep_time;
329    
330       pthread_mutex_lock(&cpu->idle_mutex);
331       t_spc.tv_sec = expire / 1000000;
332       t_spc.tv_nsec = (expire % 1000000) * 1000;
333       pthread_cond_timedwait(&cpu->idle_cond,&cpu->idle_mutex,&t_spc);
334       pthread_mutex_unlock(&cpu->idle_mutex);
335    }
336    
337    /* Break idle wait state */
338    void cpu_idle_break_wait(cpu_gen_t *cpu)
339    {
340       pthread_cond_signal(&cpu->idle_cond);
341       cpu->idle_count = 0;
342    }

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

  ViewVC Help
Powered by ViewVC 1.1.26