/[gxemul]/trunk/src/include/cpu.h
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/src/include/cpu.h

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

revision 10 by dpavlin, Mon Oct 8 16:18:27 2007 UTC revision 28 by dpavlin, Mon Oct 8 16:20:26 2007 UTC
# Line 2  Line 2 
2  #define CPU_H  #define CPU_H
3    
4  /*  /*
5   *  Copyright (C) 2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2005-2006  Anders Gavare.  All rights reserved.
6   *   *
7   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
8   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 28  Line 28 
28   *  SUCH DAMAGE.   *  SUCH DAMAGE.
29   *   *
30   *   *
31   *  $Id: cpu.h,v 1.27 2005/06/27 10:43:17 debug Exp $   *  $Id: cpu.h,v 1.84 2006/07/20 21:53:00 debug Exp $
32   *   *
33   *  See cpu.c.   *  CPU-related definitions.
34   */   */
35    
36    
# Line 38  Line 38 
38  #include <inttypes.h>  #include <inttypes.h>
39  #include <sys/time.h>  #include <sys/time.h>
40    
41  /*  This is needed for undefining 'mips' or 'ppc', on weird systems:  */  /*  This is needed for undefining 'mips', 'ppc' etc. on weird systems:  */
42  #include "../../config.h"  #include "../../config.h"
43    
44    /*
45     *  Dyntrans misc declarations, used throughout the dyntrans code.
46     *
47     *  Note that there is place for all instruction calls within a page,
48     *  and then 2 more. The first one of these "extra" instruction slots is
49     *  the end-of-page slot. It transfers control to the first instruction
50     *  slot on the next (virtual) page.
51     *
52     *  The second of these extra instruction slots is an additional
53     *  end-of-page slot for delay-slot architectures. On e.g. MIPS, a branch
54     *  instruction can "nullify" (skip) the delay-slot. If the end-of-page
55     *  slot is skipped, then we end up one step after that. That's where the
56     *  end_of_page2 slot is. :)
57     *
58     *  next_ofs points to the next page in a chain of possible pages.
59     *  (several pages can be in the same chain, but only one matches the
60     *  specific physaddr.)
61     *
62     *  flags contains special flags. Currently only COMBINATIONS, which indicates
63     *  that the page has instruction combinations.
64     *
65     *  translations is a tiny bitmap indicating which parts of the page have
66     *  actual translations. Bit 0 corresponds to the lowest 1/32th of the page,
67     *  bit 1 to the second-lowest 1/32th, and so on.
68     */
69    #define DYNTRANS_MISC_DECLARATIONS(arch,ARCH,addrtype)  struct \
70            arch ## _instr_call {                                   \
71                    void    (*f)(struct cpu *, struct arch ## _instr_call *); \
72                    size_t  arg[ARCH ## _N_IC_ARGS];                        \
73            };                                                              \
74                                                                            \
75            /*  Translation cache struct for each physical page:  */        \
76            struct arch ## _tc_physpage {                                   \
77                    struct arch ## _instr_call ics[ARCH ## _IC_ENTRIES_PER_PAGE+2];\
78                    uint32_t        next_ofs;       /*  (0 for end of chain)  */ \
79                    uint32_t        translations;                           \
80                    int             flags;                                  \
81                    addrtype        physaddr;                               \
82            };                                                              \
83                                                                            \
84            struct arch ## _vpg_tlb_entry {                                 \
85                    uint8_t         valid;                                  \
86                    uint8_t         writeflag;                              \
87                    addrtype        vaddr_page;                             \
88                    addrtype        paddr_page;                             \
89                    unsigned char   *host_page;                             \
90                    int64_t         timestamp;                              \
91            };
92    
93    #define DYNTRANS_MISC64_DECLARATIONS(arch,ARCH,tlbindextype)            \
94            struct arch ## _l3_64_table {                                   \
95                    unsigned char   *host_load[1 << ARCH ## _L3N];          \
96                    unsigned char   *host_store[1 << ARCH ## _L3N];         \
97                    uint64_t        phys_addr[1 << ARCH ## _L3N];           \
98                    tlbindextype    vaddr_to_tlbindex[1 << ARCH ## _L3N];   \
99                    struct arch ## _tc_physpage *phys_page[1 << ARCH ## _L3N]; \
100                    struct arch ## _l3_64_table     *next;                  \
101                    int             refcount;                               \
102            };                                                              \
103            struct arch ## _l2_64_table {                                   \
104                    struct arch ## _l3_64_table     *l3[1 << ARCH ## _L2N]; \
105                    struct arch ## _l2_64_table     *next;                  \
106                    int                             refcount;               \
107            };
108    
109    /*
110     *  Dyntrans "Instruction Translation Cache":
111     *
112     *  cur_physpage is a pointer to the current physpage. (It _HAPPENS_ to
113     *  be the same as cur_ic_page, because all the instrcalls should be placed
114     *  first in the physpage struct!)
115     *
116     *  cur_ic_page is a pointer to an array of xxx_IC_ENTRIES_PER_PAGE
117     *  instruction call entries.
118     *
119     *  next_ic points to the next such instruction call to be executed.
120     *
121     *  combination_check, when set to non-NULL, is executed automatically after
122     *  an instruction has been translated. (It check for combinations of
123     *  instructions; low_addr is the offset of the translated instruction in the
124     *  current page, NOT shifted right.)
125     */
126    #define DYNTRANS_ITC(arch)      struct arch ## _tc_physpage *cur_physpage;  \
127                                    struct arch ## _instr_call  *cur_ic_page;   \
128                                    struct arch ## _instr_call  *next_ic;       \
129                                    struct arch ## _tc_physpage *physpage_template;\
130                                    void (*combination_check)(struct cpu *,     \
131                                        struct arch ## _instr_call *, int low_addr);
132    
133    /*
134     *  Virtual -> physical -> host address translation TLB entries:
135     *  ------------------------------------------------------------
136     *
137     *  Regardless of whether 32-bit or 64-bit address translation is used, the
138     *  same TLB entry structure is used.
139     */
140    #define VPH_TLBS(arch,ARCH)                                             \
141            struct arch ## _vpg_tlb_entry                                   \
142                vph_tlb_entry[ARCH ## _MAX_VPH_TLB_ENTRIES];
143    
144    /*
145     *  32-bit dyntrans emulated Virtual -> physical -> host address translation:
146     *  -------------------------------------------------------------------------
147     *
148     *  This stuff assumes that 4 KB pages are used. 20 bits to select a page
149     *  means just 1 M entries needed. This is small enough that a couple of
150     *  full-size tables can fit in virtual memory on modern hosts (both 32-bit
151     *  and 64-bit hosts). :-)
152     *
153     *  Usage: e.g. VPH32(arm,ARM,uint32_t,uint8_t)
154     *           or VPH32(sparc,SPARC,uint64_t,uint16_t)
155     *
156     *  The vph_tlb_entry entries are cpu dependent tlb entries.
157     *
158     *  The host_load and host_store entries point to host pages; the phys_addr
159     *  entries are uint32_t or uint64_t (emulated physical addresses).
160     *
161     *  phys_page points to translation cache physpages.
162     *
163     *  vaddr_to_tlbindex is a virtual address to tlb index hint table.
164     *  The values in this array are the tlb index plus 1, so a value of, say,
165     *  3 means tlb index 2. A value of 0 would mean a tlb index of -1, which
166     *  is not a valid index. (I.e. no hit.)
167     */
168    #define N_VPH32_ENTRIES         1048576
169    #define VPH32(arch,ARCH,paddrtype,tlbindextype)                         \
170            unsigned char           *host_load[N_VPH32_ENTRIES];            \
171            unsigned char           *host_store[N_VPH32_ENTRIES];           \
172            paddrtype               phys_addr[N_VPH32_ENTRIES];             \
173            struct arch ## _tc_physpage  *phys_page[N_VPH32_ENTRIES];       \
174            tlbindextype            vaddr_to_tlbindex[N_VPH32_ENTRIES];
175    
176    /*
177     *  64-bit dyntrans emulated Virtual -> physical -> host address translation:
178     *  -------------------------------------------------------------------------
179     *
180     *  Usage: e.g. VPH64(alpha,ALPHA,uint8_t)
181     *           or VPH64(sparc,SPARC,uint16_t)
182     *
183     *  l1_64 is an array containing poiners to l2 tables.
184     *
185     *  l2_64_dummy is a pointer to a "dummy l2 table". Instead of having NULL
186     *  pointers in l1_64 for unused slots, a pointer to the dummy table can be
187     *  used.
188     */
189    #define DYNTRANS_L1N            17
190    #define VPH64(arch,ARCH,tlbindextype)                                   \
191            struct arch ## _l3_64_table     *l3_64_dummy;                   \
192            struct arch ## _l3_64_table     *next_free_l3;                  \
193            struct arch ## _l2_64_table     *l2_64_dummy;                   \
194            struct arch ## _l2_64_table     *next_free_l2;                  \
195            struct arch ## _l2_64_table     *l1_64[1 << DYNTRANS_L1N];
196    
197    
198    /*  Include all CPUs' header files here:  */
199    #include "cpu_alpha.h"
200  #include "cpu_arm.h"  #include "cpu_arm.h"
201    #include "cpu_avr.h"
202    #include "cpu_hppa.h"
203    #include "cpu_i960.h"
204    #include "cpu_ia64.h"
205    #include "cpu_m68k.h"
206  #include "cpu_mips.h"  #include "cpu_mips.h"
207  #include "cpu_ppc.h"  #include "cpu_ppc.h"
208  #include "cpu_urisc.h"  #include "cpu_sh.h"
209    #include "cpu_sparc.h"
210    #include "cpu_transputer.h"
211  #include "cpu_x86.h"  #include "cpu_x86.h"
212    
213  struct cpu;  struct cpu;
# Line 68  struct cpu_family { Line 231  struct cpu_family {
231                                      uint64_t *valuep, int *match_register);                                      uint64_t *valuep, int *match_register);
232          int                     (*disassemble_instr)(struct cpu *cpu,          int                     (*disassemble_instr)(struct cpu *cpu,
233                                      unsigned char *instr, int running,                                      unsigned char *instr, int running,
234                                      uint64_t dumpaddr, int bintrans);                                      uint64_t dumpaddr);
235          void                    (*register_dump)(struct cpu *cpu,          void                    (*register_dump)(struct cpu *cpu,
236                                      int gprs, int coprocs);                                      int gprs, int coprocs);
         int                     (*run)(struct emul *emul,  
                                     struct machine *machine);  
237          void                    (*dumpinfo)(struct cpu *cpu);          void                    (*dumpinfo)(struct cpu *cpu);
         void                    (*show_full_statistics)(struct machine *m);  
238          void                    (*tlbdump)(struct machine *m, int x,          void                    (*tlbdump)(struct machine *m, int x,
239                                      int rawflag);                                      int rawflag);
240          int                     (*interrupt)(struct cpu *cpu, uint64_t irq_nr);          int                     (*interrupt)(struct cpu *cpu, uint64_t irq_nr);
241          int                     (*interrupt_ack)(struct cpu *cpu,          int                     (*interrupt_ack)(struct cpu *cpu,
242                                      uint64_t irq_nr);                                      uint64_t irq_nr);
243            void                    (*functioncall_trace)(struct cpu *,
244                                        uint64_t f, int n_args);
245            char                    *(*gdb_stub)(struct cpu *, char *cmd);
246            void                    (*init_tables)(struct cpu *cpu);
247  };  };
248    
249  #ifdef TRACE_NULL_CRASHES  
250  #define TRACE_NULL_N_ENTRIES            16  /*
251  #endif   *  More dyntrans stuff:
252     *
253     *  The translation cache begins with N_BASE_TABLE_ENTRIES uint32_t offsets
254     *  into the cache, for possible translation cache structs for physical pages.
255     */
256    
257    /*  Physpage flags:  */
258    #define COMBINATIONS                    1
259    
260    /*  Meaning of delay_slot:  */
261    #define NOT_DELAYED                     0
262    #define DELAYED                         1
263    #define TO_BE_DELAYED                   2
264    #define EXCEPTION_IN_DELAY_SLOT         0x100
265    
266    #define N_SAFE_DYNTRANS_LIMIT_SHIFT     14
267    #define N_SAFE_DYNTRANS_LIMIT   ((1 << (N_SAFE_DYNTRANS_LIMIT_SHIFT - 1)) - 1)
268    
269    #define DYNTRANS_CACHE_SIZE             (32*1048576)
270    #define DYNTRANS_CACHE_MARGIN           350000
271    
272    #define N_BASE_TABLE_ENTRIES            32768
273    #define PAGENR_TO_TABLE_INDEX(a)        ((a) & (N_BASE_TABLE_ENTRIES-1))
274    
275    
276    /*
277     *  The generic CPU struct:
278     */
279    
280  struct cpu {  struct cpu {
281          /*  Pointer back to the machine this CPU is in:  */          /*  Pointer back to the machine this CPU is in:  */
# Line 95  struct cpu { Line 286  struct cpu {
286          int             dead;          int             dead;
287          int             bootstrap_cpu_flag;          int             bootstrap_cpu_flag;
288          int             cpu_id;          int             cpu_id;
289            int             is_32bit;       /*  0 for 64-bit, 1 for 32-bit  */
290          char            *name;          char            *name;
291    
292          struct memory   *mem;          struct memory   *mem;
293    
294            int             (*run_instr)(struct cpu *cpu);
295          int             (*memory_rw)(struct cpu *cpu,          int             (*memory_rw)(struct cpu *cpu,
296                              struct memory *mem, uint64_t vaddr,                              struct memory *mem, uint64_t vaddr,
297                              unsigned char *data, size_t len,                              unsigned char *data, size_t len,
298                              int writeflag, int cache_flags);                              int writeflag, int cache_flags);
299          int             (*translate_address)(struct cpu *, uint64_t vaddr,          int             (*translate_v2p)(struct cpu *, uint64_t vaddr,
300                              uint64_t *return_addr, int flags);                              uint64_t *return_paddr, int flags);
301          void            (*useremul_syscall)(struct cpu *cpu,          void            (*update_translation_table)(struct cpu *,
302                              uint32_t code);                              uint64_t vaddr_page, unsigned char *host_page,
303                                int writeflag, uint64_t paddr_page);
304            void            (*invalidate_translation_caches)(struct cpu *,
305                                uint64_t paddr, int flags);
306            void            (*invalidate_code_translation)(struct cpu *,
307                                uint64_t paddr, int flags);
308            void            (*useremul_syscall)(struct cpu *cpu, uint32_t code);
309            int             (*instruction_has_delayslot)(struct cpu *cpu,
310                                unsigned char *ib);
311    
         /*  Things that all CPU families have:  */  
312          uint64_t        pc;          uint64_t        pc;
313    
314  #ifdef TRACE_NULL_CRASHES          int             trace_tree_depth;
         uint64_t        trace_null_addr[TRACE_NULL_N_ENTRIES];  
         int             trace_null_index;  
 #endif    
315    
316          /*  CPU-family dependant:  */          /*
317             *  Dynamic translation:
318             */
319            int             running_translated;
320            int             n_translated_instrs;
321            unsigned char   *translation_cache;
322            size_t          translation_cache_cur_ofs;
323    
324            uint64_t        delay_jmpaddr;  /*  only used if delay_slot > 0  */
325            int             delay_slot;
326    
327            /*
328             *  CPU-family dependent:
329             */
330          union {          union {
331                  struct arm_cpu     arm;                  struct alpha_cpu      alpha;
332                  struct mips_cpu    mips;                  struct arm_cpu        arm;
333                  struct ppc_cpu     ppc;                  struct avr_cpu        avr;
334                  struct urisc_cpu   urisc;                  struct hppa_cpu       hppa;
335                  struct x86_cpu     x86;                  struct i960_cpu       i960;
336                    struct ia64_cpu       ia64;
337                    struct m68k_cpu       m68k;
338                    struct mips_cpu       mips;
339                    struct ppc_cpu        ppc;
340                    struct sh_cpu         sh;
341                    struct sparc_cpu      sparc;
342                    struct transputer_cpu transputer;
343                    struct x86_cpu        x86;
344          } cd;          } cd;
345  };  };
346    
# Line 129  struct cpu { Line 348  struct cpu {
348  /*  cpu.c:  */  /*  cpu.c:  */
349  struct cpu *cpu_new(struct memory *mem, struct machine *machine,  struct cpu *cpu_new(struct memory *mem, struct machine *machine,
350          int cpu_id, char *cpu_type_name);          int cpu_id, char *cpu_type_name);
 void cpu_show_full_statistics(struct machine *m);  
351  void cpu_tlbdump(struct machine *m, int x, int rawflag);  void cpu_tlbdump(struct machine *m, int x, int rawflag);
352  void cpu_register_match(struct machine *m, char *name,  void cpu_register_match(struct machine *m, char *name,
353          int writeflag, uint64_t *valuep, int *match_register);          int writeflag, uint64_t *valuep, int *match_register);
354  void cpu_register_dump(struct machine *m, struct cpu *cpu,  void cpu_register_dump(struct machine *m, struct cpu *cpu,
355          int gprs, int coprocs);          int gprs, int coprocs);
356  int cpu_disassemble_instr(struct machine *m, struct cpu *cpu,  int cpu_disassemble_instr(struct machine *m, struct cpu *cpu,
357          unsigned char *instr, int running, uint64_t addr, int bintrans);          unsigned char *instr, int running, uint64_t addr);
358    char *cpu_gdb_stub(struct cpu *cpu, char *cmd);
359  int cpu_interrupt(struct cpu *cpu, uint64_t irq_nr);  int cpu_interrupt(struct cpu *cpu, uint64_t irq_nr);
360  int cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr);  int cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr);
361  void cpu_run_init(struct emul *emul, struct machine *machine);  void cpu_functioncall_trace(struct cpu *cpu, uint64_t f);
362  int cpu_run(struct emul *emul, struct machine *machine);  void cpu_functioncall_trace_return(struct cpu *cpu);
363  void cpu_run_deinit(struct emul *emul, struct machine *machine);  void cpu_create_or_reset_tc(struct cpu *cpu);
364    void cpu_run_init(struct machine *machine);
365    void cpu_run_deinit(struct machine *machine);
366  void cpu_dumpinfo(struct machine *m, struct cpu *cpu);  void cpu_dumpinfo(struct machine *m, struct cpu *cpu);
367  void cpu_list_available_types(void);  void cpu_list_available_types(void);
368  void cpu_show_cycles(struct machine *machine, int forced);  void cpu_show_cycles(struct machine *machine, int forced);
# Line 149  struct cpu_family *cpu_family_ptr_by_num Line 370  struct cpu_family *cpu_family_ptr_by_num
370  void cpu_init(void);  void cpu_init(void);
371    
372    
373    #define JUST_MARK_AS_NON_WRITABLE       1
374    #define INVALIDATE_ALL                  2
375    #define INVALIDATE_PADDR                4
376    #define INVALIDATE_VADDR                8
377    #define INVALIDATE_VADDR_UPPER4         16      /*  useful for PPC emulation  */
378    
379    
380    #define CPU_FAMILY_INIT(n,s)    int n ## _cpu_family_init(              \
381            struct cpu_family *fp) {                                        \
382            /*  Fill in the cpu_family struct with valid data for this arch.  */ \
383            fp->name = s;                                                   \
384            fp->cpu_new = n ## _cpu_new;                                    \
385            fp->list_available_types = n ## _cpu_list_available_types;      \
386            fp->register_match = n ## _cpu_register_match;                  \
387            fp->disassemble_instr = n ## _cpu_disassemble_instr;            \
388            fp->register_dump = n ## _cpu_register_dump;                    \
389            fp->dumpinfo = n ## _cpu_dumpinfo;                              \
390            fp->interrupt = n ## _cpu_interrupt;                            \
391            fp->interrupt_ack = n ## _cpu_interrupt_ack;                    \
392            fp->functioncall_trace = n ## _cpu_functioncall_trace;          \
393            fp->gdb_stub = n ## _cpu_gdb_stub;                              \
394            fp->tlbdump = n ## _cpu_tlbdump;                                \
395            fp->init_tables = n ## _cpu_init_tables;                        \
396            return 1;                                                       \
397            }
398    
399    
400  #endif  /*  CPU_H  */  #endif  /*  CPU_H  */

Legend:
Removed from v.10  
changed lines
  Added in v.28

  ViewVC Help
Powered by ViewVC 1.1.26