cpu.cc Source File

Back to the index.

cpu.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2018 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * Common routines for CPU emulation. (Not specific to any CPU type.)
29  */
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <sys/types.h>
34 #include <sys/mman.h>
35 #include <string.h>
36 
37 #include "cpu.h"
38 #include "machine.h"
39 #include "memory.h"
40 #include "settings.h"
41 #include "timer.h"
42 
43 
44 extern size_t dyntrans_cache_size;
45 
46 static struct cpu_family *first_cpu_family = NULL;
47 
48 
49 /*
50  * cpu_new():
51  *
52  * Create a new cpu object. Each family is tried in sequence until a
53  * CPU family recognizes the cpu_type_name.
54  *
55  * If there was no match, NULL is returned. Otherwise, a pointer to an
56  * initialized cpu struct is returned.
57  */
58 struct cpu *cpu_new(struct memory *mem, struct machine *machine,
59  int cpu_id, char *name)
60 {
61  struct cpu *cpu;
62  struct cpu_family *fp;
63  char *cpu_type_name;
64  char tmpstr[30];
65 
66  if (name == NULL) {
67  fprintf(stderr, "cpu_new(): cpu name = NULL?\n");
68  exit(1);
69  }
70 
71  CHECK_ALLOCATION(cpu_type_name = strdup(name));
72 
73  cpu = (struct cpu *) zeroed_alloc(sizeof(struct cpu));
74 
75  CHECK_ALLOCATION(cpu->path = (char *) malloc(strlen(machine->path) + 15));
76  snprintf(cpu->path, strlen(machine->path) + 15,
77  "%s.cpu[%i]", machine->path, cpu_id);
78 
79  cpu->memory_rw = NULL;
80  cpu->name = cpu_type_name;
81  cpu->mem = mem;
82  cpu->machine = machine;
83  cpu->cpu_id = cpu_id;
85  cpu->running = 0;
86 
87  /* Create settings, and attach to the machine: */
88  cpu->settings = settings_new();
89  snprintf(tmpstr, sizeof(tmpstr), "cpu[%i]", cpu_id);
90  settings_add(machine->settings, tmpstr, 1,
92 
94  SETTINGS_FORMAT_STRING, (void *) &cpu->name);
95  settings_add(cpu->settings, "running", 0, SETTINGS_TYPE_UINT8,
96  SETTINGS_FORMAT_YESNO, (void *) &cpu->running);
97 
99 
100  fp = first_cpu_family;
101 
102  while (fp != NULL) {
103  if (fp->cpu_new != NULL) {
104  if (fp->cpu_new(cpu, mem, machine, cpu_id,
105  cpu_type_name)) {
106  /* Sanity check: */
107  if (cpu->memory_rw == NULL) {
108  fatal("\ncpu_new(): memory_rw == "
109  "NULL\n");
110  exit(1);
111  }
112  break;
113  }
114  }
115 
116  fp = fp->next;
117  }
118 
119  if (fp == NULL) {
120  fatal("\ncpu_new(): unknown cpu type '%s'\n", cpu_type_name);
121  return NULL;
122  }
123 
124  fp->init_tables(cpu);
125 
126  if (cpu->byte_order == EMUL_UNDEFINED_ENDIAN) {
127  fatal("\ncpu_new(): Internal bug: Endianness not set.\n");
128  exit(1);
129  }
130 
131  return cpu;
132 }
133 
134 
135 /*
136  * cpu_destroy():
137  *
138  * Destroy a cpu object.
139  */
140 void cpu_destroy(struct cpu *cpu)
141 {
142  settings_remove(cpu->settings, "name");
143  settings_remove(cpu->settings, "running");
144 
145  /* Remove any remaining level-1 settings: */
147 
149 
150  if (cpu->path != NULL)
151  free(cpu->path);
152 
153  /* TODO: This assumes that zeroed_alloc() actually succeeded
154  with using mmap(), and not malloc()! */
155  munmap((void *)cpu, sizeof(struct cpu));
156 }
157 
158 
159 /*
160  * cpu_tlbdump():
161  *
162  * Called from the debugger to dump the TLB in a readable format.
163  * x is the cpu number to dump, or -1 to dump all CPUs.
164  *
165  * If rawflag is nonzero, then the TLB contents isn't formated nicely,
166  * just dumped.
167  */
168 void cpu_tlbdump(struct machine *m, int x, int rawflag)
169 {
170  if (m->cpu_family == NULL || m->cpu_family->tlbdump == NULL)
171  fatal("cpu_tlbdump(): NULL\n");
172  else
173  m->cpu_family->tlbdump(m, x, rawflag);
174 }
175 
176 
177 /*
178  * cpu_disassemble_instr():
179  *
180  * Convert an instruction word into human readable format, for instruction
181  * tracing.
182  */
183 int cpu_disassemble_instr(struct machine *m, struct cpu *cpu,
184  unsigned char *instr, int running, uint64_t addr)
185 {
186  if (m->cpu_family == NULL || m->cpu_family->disassemble_instr == NULL) {
187  fatal("cpu_disassemble_instr(): NULL\n");
188  return 0;
189  } else
190  return m->cpu_family->disassemble_instr(cpu, instr,
191  running, addr);
192 }
193 
194 
195 /*
196  * cpu_register_dump():
197  *
198  * Dump cpu registers in a relatively readable format.
199  *
200  * gprs: set to non-zero to dump GPRs. (CPU dependent.)
201  * coprocs: set bit 0..x to dump registers in coproc 0..x. (CPU dependent.)
202  */
203 void cpu_register_dump(struct machine *m, struct cpu *cpu,
204  int gprs, int coprocs)
205 {
206  if (m->cpu_family == NULL || m->cpu_family->register_dump == NULL)
207  fatal("cpu_register_dump(): NULL\n");
208  else
209  m->cpu_family->register_dump(cpu, gprs, coprocs);
210 }
211 
212 
213 /*
214  * cpu_functioncall_trace():
215  *
216  * This function should be called if machine->show_trace_tree is enabled, and
217  * a function call is being made. f contains the address of the function.
218  */
219 void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
220 {
221  int show_symbolic_function_name = 1;
222  int i, n_args = -1;
223  char *symbol;
224  uint64_t offset;
225 
226  /* Special hack for M88K userspace: */
227  if (cpu->machine->arch == ARCH_M88K &&
228  !(cpu->cd.m88k.cr[M88K_CR_PSR] & M88K_PSR_MODE))
229  show_symbolic_function_name = 0;
230 
231  if (cpu->machine->ncpus > 1)
232  fatal("cpu%i:\t", cpu->cpu_id);
233 
234  if (cpu->trace_tree_depth > 100)
235  cpu->trace_tree_depth = 100;
236  for (i=0; i<cpu->trace_tree_depth; i++)
237  fatal(" ");
238 
239  cpu->trace_tree_depth ++;
240 
241  fatal("<");
243  f, &offset, &n_args);
244  if (symbol != NULL && show_symbolic_function_name && offset == 0)
245  fatal("%s", symbol);
246  else {
247  if (cpu->is_32bit)
248  fatal("0x%" PRIx32, (uint32_t) f);
249  else
250  fatal("0x%" PRIx64, (uint64_t) f);
251  }
252  fatal("(");
253 
254  if (cpu->machine->cpu_family->functioncall_trace != NULL)
255  cpu->machine->cpu_family->functioncall_trace(cpu, n_args);
256 
257  fatal(")>\n");
258 
259 #ifdef PRINT_MEMORY_CHECKSUM
260  /* Temporary hack for finding bugs: */
261  fatal("call chksum=%016" PRIx64"\n", memory_checksum(cpu->mem));
262 #endif
263 }
264 
265 
266 /*
267  * cpu_functioncall_trace_return():
268  *
269  * This function should be called if machine->show_trace_tree is enabled, and
270  * a function is being returned from.
271  *
272  * TODO: Print return value? This could be implemented similar to the
273  * cpu->functioncall_trace function call above.
274  */
276 {
277  cpu->trace_tree_depth --;
278  if (cpu->trace_tree_depth < 0)
279  cpu->trace_tree_depth = 0;
280 }
281 
282 
283 /*
284  * cpu_create_or_reset_tc():
285  *
286  * Create the translation cache in memory (ie allocate memory for it), if
287  * necessary, and then reset it to an initial state.
288  */
290 {
292 
293  if (cpu->translation_cache == NULL)
294  cpu->translation_cache = (unsigned char *) zeroed_alloc(s);
295 
296  /* Create an empty table at the beginning of the translation cache: */
297  memset(cpu->translation_cache, 0, sizeof(uint32_t)
299 
301  N_BASE_TABLE_ENTRIES * sizeof(uint32_t);
302 
303  /*
304  * There might be other translation pointers that still point to
305  * within the translation_cache region. Let's invalidate those too:
306  */
307  if (cpu->invalidate_code_translation != NULL)
309 }
310 
311 
312 /*
313  * cpu_dumpinfo():
314  *
315  * Dumps info about a CPU using debug(). "cpu0: CPUNAME, running" (or similar)
316  * is outputed, and it is up to CPU dependent code to complete the line.
317  */
318 void cpu_dumpinfo(struct machine *m, struct cpu *cpu)
319 {
320  debug("cpu%i: %s, %s", cpu->cpu_id, cpu->name,
321  cpu->running? "running" : "stopped");
322 
323  if (m->cpu_family == NULL || m->cpu_family->dumpinfo == NULL)
324  fatal("cpu_dumpinfo(): NULL\n");
325  else
326  m->cpu_family->dumpinfo(cpu);
327 }
328 
329 
330 /*
331  * cpu_list_available_types():
332  *
333  * Print a list of available CPU types for each cpu family.
334  */
336 {
337  struct cpu_family *fp;
338  int iadd = DEBUG_INDENTATION;
339 
340  fp = first_cpu_family;
341 
342  if (fp == NULL) {
343  debug("No CPUs defined!\n");
344  return;
345  }
346 
347  while (fp != NULL) {
348  debug("%s:\n", fp->name);
349  debug_indentation(iadd);
350  if (fp->list_available_types != NULL)
351  fp->list_available_types();
352  else
353  debug("(internal error: list_available_types"
354  " = NULL)\n");
355  debug_indentation(-iadd);
356 
357  fp = fp->next;
358  }
359 }
360 
361 
362 /*
363  * cpu_run_deinit():
364  *
365  * Shuts down all CPUs in a machine when ending a simulation. (This function
366  * should only need to be called once for each machine.)
367  */
369 {
370  int te;
371 
372  /*
373  * Two last ticks of every hardware device. This will allow e.g.
374  * framebuffers to draw the last updates to the screen before halting.
375  *
376  * TODO: This should be refactored when redesigning the mainbus
377  * concepts!
378  */
379  for (te=0; te<machine->tick_functions.n_entries; te++) {
380  machine->tick_functions.f[te](machine->cpus[0],
381  machine->tick_functions.extra[te]);
382  machine->tick_functions.f[te](machine->cpus[0],
383  machine->tick_functions.extra[te]);
384  }
385 
386  if (machine->show_nr_of_instructions)
387  cpu_show_cycles(machine, 1);
388 
389  fflush(stdout);
390 }
391 
392 
393 /*
394  * cpu_show_cycles():
395  *
396  * If show_nr_of_instructions is on, then print a line to stdout about how
397  * many instructions/cycles have been executed so far.
398  */
399 void cpu_show_cycles(struct machine *machine, int forced)
400 {
401  uint64_t offset, pc;
402  char *symbol;
403  int64_t mseconds, ninstrs, is, avg;
404  struct timeval tv;
405  struct cpu *cpu = machine->cpus[machine->bootstrap_cpu];
406 
407  static int64_t mseconds_last = 0;
408  static int64_t ninstrs_last = -1;
409 
410  pc = cpu->pc;
411 
412  gettimeofday(&tv, NULL);
413  mseconds = (tv.tv_sec - cpu->starttime.tv_sec) * 1000
414  + (tv.tv_usec - cpu->starttime.tv_usec) / 1000;
415 
416  if (mseconds == 0)
417  mseconds = 1;
418 
419  if (mseconds - mseconds_last == 0)
420  mseconds ++;
421 
422  ninstrs = cpu->ninstrs_since_gettimeofday;
423 
424  /* RETURN here, unless show_nr_of_instructions (-N) is turned on: */
425  if (!machine->show_nr_of_instructions && !forced)
426  goto do_return;
427 
428  printf("[ %" PRIi64" instrs", (int64_t) cpu->ninstrs);
429 
430  /* Instructions per second, and average so far: */
431  is = 1000 * (ninstrs-ninstrs_last) / (mseconds-mseconds_last);
432  avg = (long long)1000 * ninstrs / mseconds;
433  if (is < 0)
434  is = 0;
435  if (avg < 0)
436  avg = 0;
437 
438  if (cpu->has_been_idling) {
439  printf("; idling");
440  cpu->has_been_idling = 0;
441  } else
442  printf("; i/s=%" PRIi64" avg=%" PRIi64, is, avg);
443 
444  symbol = get_symbol_name(&machine->symbol_context, pc, &offset);
445 
446  if (machine->ncpus == 1) {
447  if (cpu->is_32bit)
448  printf("; pc=0x%08" PRIx32, (uint32_t) pc);
449  else
450  printf("; pc=0x%016" PRIx64, (uint64_t) pc);
451  }
452 
453  /* Special hack for M88K userland: (Don't show symbols.) */
454  if (cpu->machine->arch == ARCH_M88K &&
455  !(cpu->cd.m88k.cr[M88K_CR_PSR] & M88K_PSR_MODE))
456  symbol = NULL;
457 
458  if (symbol != NULL)
459  printf(" <%s>", symbol);
460  printf(" ]\n");
461 
462 do_return:
463  ninstrs_last = ninstrs;
464  mseconds_last = mseconds;
465 }
466 
467 
468 /*
469  * cpu_run_init():
470  *
471  * Prepare to run instructions on all CPUs in this machine. (This function
472  * should only need to be called once for each machine.)
473  */
475 {
476  int i;
477 
478  if (machine->ncpus == 0) {
479  printf("Machine with no CPUs? TODO.\n");
480  exit(1);
481  }
482 
483  for (i=0; i<machine->ncpus; i++) {
484  struct cpu *cpu = machine->cpus[i];
485 
486  cpu->ninstrs_flush = 0;
487  cpu->ninstrs = 0;
488  cpu->ninstrs_show = 0;
489 
490  /* For performance measurement: */
491  gettimeofday(&cpu->starttime, NULL);
493  }
494 }
495 
496 
497 /*
498  * add_cpu_family():
499  *
500  * Allocates a cpu_family struct and calls an init function for the
501  * family to fill in reasonable data and pointers.
502  */
503 static void add_cpu_family(int (*family_init)(struct cpu_family *), int arch)
504 {
505  struct cpu_family *fp, *tmp;
506  int res;
507 
508  CHECK_ALLOCATION(fp = (struct cpu_family *) malloc(sizeof(struct cpu_family)));
509  memset(fp, 0, sizeof(struct cpu_family));
510 
511  /*
512  * family_init() returns 1 if the struct has been filled with
513  * valid data, 0 if suppor for the cpu family isn't compiled
514  * into the emulator.
515  */
516  res = family_init(fp);
517  if (!res) {
518  free(fp);
519  return;
520  }
521  fp->arch = arch;
522  fp->next = NULL;
523 
524  /* Add last in family chain: */
525  tmp = first_cpu_family;
526  if (tmp == NULL) {
527  first_cpu_family = fp;
528  } else {
529  while (tmp->next != NULL)
530  tmp = tmp->next;
531  tmp->next = fp;
532  }
533 }
534 
535 
536 /*
537  * cpu_family_ptr_by_number():
538  *
539  * Returns a pointer to a CPU family based on the ARCH_* integers.
540  */
542 {
543  struct cpu_family *fp;
544  fp = first_cpu_family;
545 
546  /* YUCK! This is too hardcoded! TODO */
547 
548  while (fp != NULL) {
549  if (arch == fp->arch)
550  return fp;
551  fp = fp->next;
552  }
553 
554  return NULL;
555 }
556 
557 
558 /*
559  * cpu_init():
560  *
561  * Should be called before any other cpu_*() function.
562  *
563  * This function calls add_cpu_family() for each processor architecture.
564  * ADD_ALL_CPU_FAMILIES is defined in the config.h file generated by the
565  * configure script.
566  */
567 void cpu_init(void)
568 {
569  ADD_ALL_CPU_FAMILIES;
570 }
571 
void cpu_list_available_types(void)
Definition: cpu.cc:335
#define SETTINGS_TYPE_UINT8
Definition: settings.h:46
void * zeroed_alloc(size_t s)
Definition: memory.cc:118
void ** extra
Definition: machine.h:77
void fatal(const char *fmt,...)
Definition: main.cc:152
char * name
Definition: cpu.h:334
#define EMUL_UNDEFINED_ENDIAN
Definition: misc.h:163
#define DEBUG_INDENTATION
Definition: misc.h:212
void cpu_dumpinfo(struct machine *m, struct cpu *cpu)
Definition: cpu.cc:318
#define SETTINGS_FORMAT_YESNO
Definition: settings.h:58
struct settings * settings_new(void)
Definition: settings.cc:88
uint8_t is_32bit
Definition: cpu.h:350
void(* list_available_types)(void)
Definition: cpu.h:272
#define INVALIDATE_ALL
Definition: cpu.h:478
#define DYNTRANS_CACHE_MARGIN
Definition: cpu.h:316
void cpu_tlbdump(struct machine *m, int x, int rawflag)
Definition: cpu.cc:168
#define M88K_PSR_MODE
Definition: m88k_psl.h:70
void(* dumpinfo)(struct cpu *cpu)
Definition: cpu.h:284
union cpu::@1 cd
struct memory * mem
Definition: cpu.h:362
#define SETTINGS_TYPE_STRING
Definition: settings.h:39
void(** f)(struct cpu *, void *)
Definition: machine.h:76
void cpu_run_deinit(struct machine *machine)
Definition: cpu.cc:368
struct machine * machine
Definition: cpu.h:328
struct cpu * cpu_new(struct memory *mem, struct machine *machine, int cpu_id, char *name)
Definition: cpu.cc:58
void f(int s, int func, int only_name)
#define instr(n)
struct settings * settings
Definition: cpu.h:331
void(* functioncall_trace)(struct cpu *, int n_args)
Definition: cpu.h:292
char * get_symbol_name(struct symbol_context *, uint64_t addr, uint64_t *offset)
Definition: symbol.cc:188
struct cpu ** cpus
Definition: machine.h:140
int64_t ninstrs_flush
Definition: cpu.h:342
void cpu_show_cycles(struct machine *machine, int forced)
Definition: cpu.cc:399
int ncpus
Definition: machine.h:139
uint64_t pc
Definition: cpu.h:383
void(* register_dump)(struct cpu *cpu, int gprs, int coprocs)
Definition: cpu.h:280
#define CHECK_ALLOCATION(ptr)
Definition: misc.h:239
uint64_t memory_checksum(struct memory *mem)
Definition: memory.cc:563
char * path
Definition: machine.h:108
#define M88K_CR_PSR
int bootstrap_cpu
Definition: machine.h:136
void cpu_destroy(struct cpu *cpu)
Definition: cpu.cc:140
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
Definition: cpu.h:365
void settings_remove(struct settings *settings, const char *name)
Definition: settings.cc:383
char * path
Definition: cpu.h:337
void settings_destroy(struct settings *settings)
Definition: settings.cc:105
int64_t ninstrs
Definition: cpu.h:340
void(* tlbdump)(struct machine *m, int x, int rawflag)
Definition: cpu.h:287
size_t translation_cache_cur_ofs
Definition: cpu.h:429
int arch
Definition: cpu.h:258
#define SETTINGS_FORMAT_STRING
Definition: settings.h:59
uint8_t running
Definition: cpu.h:353
unsigned char * translation_cache
Definition: cpu.h:428
void cpu_register_dump(struct machine *m, struct cpu *cpu, int gprs, int coprocs)
Definition: cpu.cc:203
struct cpu_family * cpu_family_ptr_by_number(int arch)
Definition: cpu.cc:541
char has_been_idling
Definition: cpu.h:398
void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
Definition: cpu.cc:219
int(* disassemble_instr)(struct cpu *cpu, unsigned char *instr, int running, uint64_t dumpaddr)
Definition: cpu.h:275
uint32_t addr
#define ARCH_M88K
Definition: machine.h:208
int trace_tree_depth
Definition: cpu.h:386
#define debug
Definition: dev_adb.cc:57
void cpu_functioncall_trace_return(struct cpu *cpu)
Definition: cpu.cc:275
int cpu_id
Definition: cpu.h:359
#define SETTINGS_TYPE_SUBSETTINGS
Definition: settings.h:38
uint32_t cr[N_M88K_CONTROL_REGS]
Definition: cpu_m88k.h:241
Definition: cpu.h:326
char * name
Definition: cpu.h:261
void COMBINE() strlen(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
void debug_indentation(int diff)
Definition: main.cc:120
int64_t ninstrs_since_gettimeofday
Definition: cpu.h:343
struct symbol_context symbol_context
Definition: machine.h:144
void settings_remove_all(struct settings *settings)
Definition: settings.cc:441
void settings_add(struct settings *settings, const char *name, int writable, int type, int format, void *ptr)
Definition: settings.cc:334
struct settings * settings
Definition: machine.h:102
void cpu_run_init(struct machine *machine)
Definition: cpu.cc:474
int(* cpu_new)(struct cpu *cpu, struct memory *mem, struct machine *machine, int cpu_id, char *cpu_type_name)
Definition: cpu.h:264
int64_t ninstrs_show
Definition: cpu.h:341
uint8_t byte_order
Definition: cpu.h:347
#define N_BASE_TABLE_ENTRIES
Definition: cpu.h:318
size_t dyntrans_cache_size
Definition: main.cc:65
char * get_symbol_name_and_n_args(struct symbol_context *, uint64_t addr, uint64_t *offset, int *n_argsp)
Definition: symbol.cc:110
Definition: memory.h:75
int cpu_disassemble_instr(struct machine *m, struct cpu *cpu, unsigned char *instr, int running, uint64_t addr)
Definition: cpu.cc:183
void cpu_init(void)
Definition: cpu.cc:567
Definition: symbol.h:37
struct timeval starttime
Definition: cpu.h:344
int arch
Definition: machine.h:110
void cpu_create_or_reset_tc(struct cpu *cpu)
Definition: cpu.cc:289
struct cpu_family * next
Definition: cpu.h:257
struct m88k_cpu m88k
Definition: cpu.h:442
void(* invalidate_code_translation)(struct cpu *, uint64_t paddr, int flags)
Definition: cpu.h:376
int show_nr_of_instructions
Definition: machine.h:163
struct tick_functions tick_functions
Definition: machine.h:131
int n_entries
Definition: machine.h:71
struct cpu_family * cpu_family
Definition: machine.h:124
void(* init_tables)(struct cpu *cpu)
Definition: cpu.h:269

Generated on Fri Dec 7 2018 19:52:23 for GXemul by doxygen 1.8.13