/[dynamips]/trunk/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 /trunk/cpu.c

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

upstream/dynamips-0.2.6-RC2/cpu.c revision 3 by dpavlin, Sat Oct 6 16:05:34 2007 UTC upstream/dynamips-0.2.7-RC3/cpu.c revision 9 by dpavlin, Sat Oct 6 16:26:06 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)
39          return NULL;
40    
41     for(cpu=group->cpu_list;cpu;cpu=cpu->next)     for(cpu=group->cpu_list;cpu;cpu=cpu->next)
42        if (cpu->id == id)        if (cpu->id == id)
# Line 41  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 56  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)
69          return(-1);
70    
71     /* check that we don't already have a CPU with this id */     /* check that we don't already have a CPU with this id */
72     if (cpu_group_find_id(group,cpu->id) != NULL) {     if (cpu_group_find_id(group,cpu->id) != NULL) {
73        fprintf(stderr,"cpu_group_add: CPU%u already present in group.\n",        fprintf(stderr,"cpu_group_add: CPU%u already present in group.\n",
# Line 86  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 101  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 110  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 122  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->jit_op_array_size = MIPS_INSN_PER_PAGE;
152        cpu_run_fn = (void *)mips64_exec_run_cpu;           CPU_MIPS64(cpu)->vm = vm;
153     } else {           CPU_MIPS64(cpu)->gen = cpu;
154        mips64_jit_init(cpu);           mips64_init(CPU_MIPS64(cpu));
155    
156             cpu_run_fn = (void *)mips64_jit_run_cpu;
157    
158             if (!cpu->vm->jit_use)
159                cpu_run_fn = (void *)mips64_exec_run_cpu;
160             else
161                mips64_jit_init(CPU_MIPS64(cpu));
162             break;
163    
164          case CPU_TYPE_PPC32:
165             cpu->jit_op_array_size = PPC32_INSN_PER_PAGE;
166             CPU_PPC32(cpu)->vm = vm;
167             CPU_PPC32(cpu)->gen = cpu;
168             ppc32_init(CPU_PPC32(cpu));
169    
170             cpu_run_fn = (void *)ppc32_jit_run_cpu;
171    
172             if (!cpu->vm->jit_use)
173                cpu_run_fn = (void *)ppc32_exec_run_cpu;
174             else
175                ppc32_jit_init(CPU_PPC32(cpu));
176             break;
177    
178          default:
179             fprintf(stderr,"CPU type %u is not supported yet\n",cpu->type);
180             abort();
181             break;
182     }     }
 #endif  
183    
184     /* create the CPU thread execution */     /* create the CPU thread execution */
185     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 158  cpu_mips_t *cpu_create(vm_instance_t *vm Line 192  cpu_mips_t *cpu_create(vm_instance_t *vm
192  }  }
193    
194  /* Delete a CPU */  /* Delete a CPU */
195  void cpu_delete(cpu_mips_t *cpu)  void cpu_delete(cpu_gen_t *cpu)
196  {  {
197     if (cpu) {     if (cpu) {
198        /* Stop activity of this CPU */        /* Stop activity of this CPU */
# Line 166  void cpu_delete(cpu_mips_t *cpu) Line 200  void cpu_delete(cpu_mips_t *cpu)
200        pthread_join(cpu->cpu_thread,NULL);        pthread_join(cpu->cpu_thread,NULL);
201    
202        /* Free resources */        /* Free resources */
203        mips64_delete(cpu);        switch(cpu->type) {
204             case CPU_TYPE_MIPS64:
205                mips64_delete(CPU_MIPS64(cpu));
206                break;
207    
208             case CPU_TYPE_PPC32:
209                ppc32_delete(CPU_PPC32(cpu));
210                break;
211          }
212    
213          free(cpu);
214     }     }
215  }  }
216    
217  /* Start a CPU */  /* Start a CPU */
218  void cpu_start(cpu_mips_t *cpu)  void cpu_start(cpu_gen_t *cpu)
219  {  {
220     if (cpu) {     if (cpu) {
221        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);
222        cpu->state = MIPS_CPU_RUNNING;        cpu->state = CPU_STATE_RUNNING;
223     }     }
224  }  }
225    
226  /* Stop a CPU */  /* Stop a CPU */
227  void cpu_stop(cpu_mips_t *cpu)  void cpu_stop(cpu_gen_t *cpu)
228  {  {
229     if (cpu) {     if (cpu) {
230        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);
231        cpu->state = MIPS_CPU_HALTED;        cpu->state = CPU_STATE_HALTED;
232     }     }
233  }  }
234    
235  /* Start all CPUs of a CPU group */  /* Start all CPUs of a CPU group */
236  void cpu_group_start_all_cpu(cpu_group_t *group)  void cpu_group_start_all_cpu(cpu_group_t *group)
237  {  {
238     cpu_mips_t *cpu;     cpu_gen_t *cpu;
239        
240     for(cpu=group->cpu_list;cpu;cpu=cpu->next)     for(cpu=group->cpu_list;cpu;cpu=cpu->next)
241        cpu_start(cpu);        cpu_start(cpu);
# Line 200  void cpu_group_start_all_cpu(cpu_group_t Line 244  void cpu_group_start_all_cpu(cpu_group_t
244  /* Stop all CPUs of a CPU group */  /* Stop all CPUs of a CPU group */
245  void cpu_group_stop_all_cpu(cpu_group_t *group)  void cpu_group_stop_all_cpu(cpu_group_t *group)
246  {  {
247     cpu_mips_t *cpu;     cpu_gen_t *cpu;
248        
249     for(cpu=group->cpu_list;cpu;cpu=cpu->next)     for(cpu=group->cpu_list;cpu;cpu=cpu->next)
250        cpu_stop(cpu);        cpu_stop(cpu);
# Line 209  void cpu_group_stop_all_cpu(cpu_group_t Line 253  void cpu_group_stop_all_cpu(cpu_group_t
253  /* Set a state of all CPUs of a CPU group */  /* Set a state of all CPUs of a CPU group */
254  void cpu_group_set_state(cpu_group_t *group,u_int state)  void cpu_group_set_state(cpu_group_t *group,u_int state)
255  {  {
256     cpu_mips_t *cpu;     cpu_gen_t *cpu;
257        
258     for(cpu=group->cpu_list;cpu;cpu=cpu->next)     for(cpu=group->cpu_list;cpu;cpu=cpu->next)
259        cpu->state = state;        cpu->state = state;
# Line 218  void cpu_group_set_state(cpu_group_t *gr Line 262  void cpu_group_set_state(cpu_group_t *gr
262  /* Returns TRUE if all CPUs in a CPU group are inactive */  /* Returns TRUE if all CPUs in a CPU group are inactive */
263  static int cpu_group_check_activity(cpu_group_t *group)  static int cpu_group_check_activity(cpu_group_t *group)
264  {  {
265     cpu_mips_t *cpu;     cpu_gen_t *cpu;
266    
267     for(cpu=group->cpu_list;cpu;cpu=cpu->next) {     for(cpu=group->cpu_list;cpu;cpu=cpu->next) {
268        if (!cpu->cpu_thread_running)        if (!cpu->cpu_thread_running)
269           continue;           continue;
270    
271        if ((cpu->state == MIPS_CPU_RUNNING) || !cpu->seq_state)        if ((cpu->state == CPU_STATE_RUNNING) || !cpu->seq_state)
272           return(FALSE);           return(FALSE);
273     }     }
274    
# Line 234  static int cpu_group_check_activity(cpu_ Line 278  static int cpu_group_check_activity(cpu_
278  /* Synchronize on CPUs (all CPUs must be inactive) */  /* Synchronize on CPUs (all CPUs must be inactive) */
279  int cpu_group_sync_state(cpu_group_t *group)  int cpu_group_sync_state(cpu_group_t *group)
280  {    {  
281     cpu_mips_t *cpu;     cpu_gen_t *cpu;
282     m_tmcnt_t t1,t2;     m_tmcnt_t t1,t2;
283    
284     /* Check that CPU activity is really suspended */     /* Check that CPU activity is really suspended */
# Line 258  int cpu_group_sync_state(cpu_group_t *gr Line 302  int cpu_group_sync_state(cpu_group_t *gr
302  /* Save state of all CPUs */  /* Save state of all CPUs */
303  int cpu_group_save_state(cpu_group_t *group)  int cpu_group_save_state(cpu_group_t *group)
304  {  {
305     cpu_mips_t *cpu;     cpu_gen_t *cpu;
306        
307     for(cpu=group->cpu_list;cpu;cpu=cpu->next)     for(cpu=group->cpu_list;cpu;cpu=cpu->next)
308        cpu->prev_state = cpu->state;        cpu->prev_state = cpu->state;
# Line 269  int cpu_group_save_state(cpu_group_t *gr Line 313  int cpu_group_save_state(cpu_group_t *gr
313  /* Restore state of all CPUs */  /* Restore state of all CPUs */
314  int cpu_group_restore_state(cpu_group_t *group)  int cpu_group_restore_state(cpu_group_t *group)
315  {  {
316     cpu_mips_t *cpu;     cpu_gen_t *cpu;
317        
318     for(cpu=group->cpu_list;cpu;cpu=cpu->next)     for(cpu=group->cpu_list;cpu;cpu=cpu->next)
319        cpu->state = cpu->prev_state;        cpu->state = cpu->prev_state;
320    
321     return(TRUE);     return(TRUE);
322  }  }
323    
324    /* Virtual idle loop */
325    void cpu_idle_loop(cpu_gen_t *cpu)
326    {
327       struct timespec t_spc;
328       m_tmcnt_t expire;
329    
330       expire = m_gettime_usec() + cpu->idle_sleep_time;
331    
332       pthread_mutex_lock(&cpu->idle_mutex);
333       t_spc.tv_sec = expire / 1000000;
334       t_spc.tv_nsec = (expire % 1000000) * 1000;
335       pthread_cond_timedwait(&cpu->idle_cond,&cpu->idle_mutex,&t_spc);
336       pthread_mutex_unlock(&cpu->idle_mutex);
337    }
338    
339    /* Break idle wait state */
340    void cpu_idle_break_wait(cpu_gen_t *cpu)
341    {
342       pthread_cond_signal(&cpu->idle_cond);
343       cpu->idle_count = 0;
344    }

Legend:
Removed from v.3  
changed lines
  Added in v.9

  ViewVC Help
Powered by ViewVC 1.1.26