/[gxemul]/trunk/src/include/cpu_mips.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_mips.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 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 2  Line 2 
2  #define CPU_MIPS_H  #define CPU_MIPS_H
3    
4  /*  /*
5   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2007  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_mips.h,v 1.16 2005/06/26 22:23:43 debug Exp $   *  $Id: cpu_mips.h,v 1.59 2007/06/07 15:36:25 debug Exp $
32   */   */
33    
34    #include "interrupt.h"
35  #include "misc.h"  #include "misc.h"
36    
 /*    
  *  ENABLE_MIPS16 should be defined on the cc commandline using -D, if you  
  *  want it. (This is done by ./configure --mips16)  
  */  
 /*  #define MFHILO_DELAY  */  
   
37  struct cpu_family;  struct cpu_family;
38  struct emul;  struct emul;
39  struct machine;  struct machine;
40    struct timer;
41    
42  /*  /*
43   *  CPU type definitions:  See mips_cpu_types.h.   *  CPU type definitions:  See mips_cpu_types.h.
# Line 55  struct mips_cpu_type_def { Line 51  struct mips_cpu_type_def {
51          char            exc_model;              /*  EXC3K or EXC4K  */          char            exc_model;              /*  EXC3K or EXC4K  */
52          char            mmu_model;              /*  MMU3K or MMU4K  */          char            mmu_model;              /*  MMU3K or MMU4K  */
53          char            isa_level;              /*  1, 2, 3, 4, 5, 32, 64  */          char            isa_level;              /*  1, 2, 3, 4, 5, 32, 64  */
54            char            isa_revision;           /*  1 or 2 (for MIPS32/64)  */
55          int             nr_of_tlb_entries;      /*  32, 48, 64, ...  */          int             nr_of_tlb_entries;      /*  32, 48, 64, ...  */
56          char            instrs_per_cycle;       /*  simplified, 1, 2, or 4  */          char            instrs_per_cycle;       /*  simplified, 1, 2, or 4  */
57          int             default_picache;          int             picache;
58          int             default_pdcache;          int             pilinesize;
59          int             default_pilinesize;          int             piways;
60          int             default_pdlinesize;          int             pdcache;
61          int             default_scache;          int             pdlinesize;
62          int             default_slinesize;          int             pdways;
63            int             scache;
64            int             slinesize;
65            int             sways;
66  };  };
67    
68  #define INITIAL_PC                      0xffffffffbfc00000ULL  #define INITIAL_PC                      0xffffffffbfc00000ULL
# Line 71  struct mips_cpu_type_def { Line 71  struct mips_cpu_type_def {
71    
72  /*  /*
73   *  Coproc 0:   *  Coproc 0:
74     *
75     *  NOTE:
76     *      On R3000, only hi and lo0 are used, and then only the lowest 32 bits.
77   */   */
78  #define N_MIPS_COPROC_REGS      32  #define N_MIPS_COPROC_REGS      32
79  struct mips_tlb {  struct mips_tlb {
# Line 84  struct mips_tlb { Line 87  struct mips_tlb {
87  /*  /*
88   *  Coproc 1:   *  Coproc 1:
89   */   */
90  #define N_MIPS_FCRS             32  /*  FPU control registers:  */
91    #define N_MIPS_FCRS                     32
92    #define MIPS_FPU_FCIR                   0
93    #define MIPS_FPU_FCCR                   25
94    #define MIPS_FPU_FCSR                   31
95    #define    MIPS_FCSR_FCC0_SHIFT            23
96    #define    MIPS_FCSR_FCC1_SHIFT            25
97    
98    #define N_VADDR_TO_TLB_INDEX_ENTRIES    (1 << 20)
99    
100  struct mips_coproc {  struct mips_coproc {
101          int             coproc_nr;          int             coproc_nr;
# Line 153  struct mips_coproc { Line 164  struct mips_coproc {
164  #define MIPS_GPR_FP             30              /*  fp  */  #define MIPS_GPR_FP             30              /*  fp  */
165  #define MIPS_GPR_RA             31              /*  ra  */  #define MIPS_GPR_RA             31              /*  ra  */
166    
 /*  Meaning of delay_slot:  */  
 #define NOT_DELAYED             0  
 #define DELAYED                 1  
 #define TO_BE_DELAYED           2  
   
167  #define N_HI6                   64  #define N_HI6                   64
168  #define N_SPECIAL               64  #define N_SPECIAL               64
169  #define N_REGIMM                32  #define N_REGIMM                32
170    
 /*  Number of "tiny" translation cache entries:  */  
 #define N_TRANSLATION_CACHE_INSTR       5  
 #define N_TRANSLATION_CACHE_DATA        5  
   
 struct translation_cache_entry {  
         int             wf;  
         uint64_t        vaddr_pfn;  
         uint64_t        paddr;  
 };  
   
 /*  This should be a value which the program counter  
     can "never" have:  */  
 #define PC_LAST_PAGE_IMPOSSIBLE_VALUE   3  
171    
172  /*  An "impossible" paddr:  */  /*  An "impossible" paddr:  */
173  #define IMPOSSIBLE_PADDR                0x1212343456566767ULL  #define IMPOSSIBLE_PADDR                0x1212343456566767ULL
# Line 189  struct r3000_cache_line { Line 182  struct r3000_cache_line {
182  #define R3000_TAG_VALID         1  #define R3000_TAG_VALID         1
183  #define R3000_TAG_DIRTY         2  #define R3000_TAG_DIRTY         2
184    
 struct r4000_cache_line {  
         char            dummy;  
 };  
185    
186  #define BINTRANS_DONT_RUN_NEXT          0x1000000  #define MIPS_IC_ENTRIES_SHIFT           10
 #define BINTRANS_N_MASK                 0x0ffffff  
187    
188  #define N_SAFE_BINTRANS_LIMIT_SHIFT     14  #define MIPS_N_IC_ARGS                  3
189  #define N_SAFE_BINTRANS_LIMIT   ((1 << (N_SAFE_BINTRANS_LIMIT_SHIFT - 1)) - 1)  #define MIPS_INSTR_ALIGNMENT_SHIFT      2
190    #define MIPS_IC_ENTRIES_PER_PAGE        (1 << MIPS_IC_ENTRIES_SHIFT)
191    #define MIPS_PC_TO_IC_ENTRY(a)          (((a)>>MIPS_INSTR_ALIGNMENT_SHIFT) \
192                                            & (MIPS_IC_ENTRIES_PER_PAGE-1))
193    #define MIPS_ADDR_TO_PAGENR(a)          ((a) >> (MIPS_IC_ENTRIES_SHIFT \
194                                            + MIPS_INSTR_ALIGNMENT_SHIFT))
195    
196  #define N_BINTRANS_VADDR_TO_HOST        20  #define MIPS_L2N                17
197    #define MIPS_L3N                18
198    
199    #define MIPS_MAX_VPH_TLB_ENTRIES        128
200    
201    DYNTRANS_MISC_DECLARATIONS(mips,MIPS,uint64_t)
202    DYNTRANS_MISC64_DECLARATIONS(mips,MIPS,uint8_t)
203    
 /*  Virtual to host address translation tables:  */  
 struct vth32_table {  
         void                    *haddr_entry[1024 * 2];  
         uint32_t                paddr_entry[1024];  
         uint32_t                *bintrans_chunks[1024];  
         struct vth32_table      *next_free;  
         int                     refcount;  
 };  
204    
205  struct mips_cpu {  struct mips_cpu {
206          struct mips_cpu_type_def cpu_type;          struct mips_cpu_type_def cpu_type;
207    
208          struct mips_coproc *coproc[N_MIPS_COPROCS];          /*  General purpose registers:  */
209            uint64_t        gpr[N_MIPS_GPRS];
210    
211          int             compare_register_set;          /*  Dummy destination register when writing to the zero register:  */
212            uint64_t        scratch;
213    
214          /*  Special purpose registers:  */          /*  Special purpose registers:  */
         uint64_t        pc_last;                /*  PC of last instruction   */  
215          uint64_t        hi;          uint64_t        hi;
216          uint64_t        lo;          uint64_t        lo;
217    
218          /*  General purpose registers:  */          /*  Coprocessors:  */
219          uint64_t        gpr[N_MIPS_GPRS];          struct mips_coproc *coproc[N_MIPS_COPROCS];
220            uint64_t        cop0_config_select1;
221    
222          /*          int             last_written_tlb_index;
          *  The translation_cached stuff is used to speed up the  
          *  most recent lookups into the TLB.  Whenever the TLB is  
          *  written to, translation_cached[] must be filled with zeros.  
          */  
 #ifdef USE_TINY_CACHE  
         struct translation_cache_entry  
                         translation_cache_instr[N_TRANSLATION_CACHE_INSTR];  
         struct translation_cache_entry  
                         translation_cache_data[N_TRANSLATION_CACHE_DATA];  
 #endif  
223    
224          /*          /*  Count/compare timer:  */
225           *  For faster memory lookup when running instructions:          int             compare_register_set;
226           *          int             compare_interrupts_pending;
227           *  Reading memory to load instructions is a very common thing in the          struct interrupt irq_compare;
228           *  emulator, and an instruction is very often read from the address          struct timer    *timer;
          *  following the previously executed instruction. That means that we  
          *  don't have to go through the TLB each time.  
          *  
          *  We then get the vaddr -> paddr translation for free. There is an  
          *  even better case when the paddr is a RAM address (as opposed to an  
          *  address in a memory mapped device). Then we can figure out the  
          *  address in the host's memory directly, and skip the paddr -> host  
          *  address calculation as well.  
          *  
          *  A modification to the TLB should set the virtual_page variable to  
          *  an "impossible" value, so that there won't be a hit on the next  
          *  instruction.  
          */  
         uint64_t        pc_last_virtual_page;  
         uint64_t        pc_last_physical_page;  
         unsigned char   *pc_last_host_4k_page;  
   
 #ifdef BINTRANS  
         int             dont_run_next_bintrans;  
         int             bintrans_instructions_executed;  /*  set to the  
                                 number of bintranslated instructions executed  
                                 when running a bintrans codechunk  */  
         int             pc_bintrans_paddr_valid;  
         uint64_t        pc_bintrans_paddr;  
         unsigned char   *pc_bintrans_host_4kpage;  
   
         /*  Chunk base address:  */  
         unsigned char   *chunk_base_address;  
   
         /*  This should work for 32-bit MIPS emulation:  */  
         struct vth32_table *vaddr_to_hostaddr_nulltable;  
         struct vth32_table *vaddr_to_hostaddr_r2k3k_icachetable;  
         struct vth32_table *vaddr_to_hostaddr_r2k3k_dcachetable;  
         struct vth32_table **vaddr_to_hostaddr_table0_kernel;  
         struct vth32_table **vaddr_to_hostaddr_table0_cacheisol_i;  
         struct vth32_table **vaddr_to_hostaddr_table0_cacheisol_d;  
         struct vth32_table **vaddr_to_hostaddr_table0_user;  
         struct vth32_table **vaddr_to_hostaddr_table0;  /*  should point to kernel or user  */  
         struct vth32_table *next_free_vth_table;  
   
         /*  For 64-bit (generic) emulation:  */  
         unsigned char   *(*fast_vaddr_to_hostaddr)(struct cpu *cpu,  
                             uint64_t vaddr, int writeflag);  
         int             bintrans_next_index;  
         int             bintrans_data_writable[N_BINTRANS_VADDR_TO_HOST];  
         uint64_t        bintrans_data_vaddr[N_BINTRANS_VADDR_TO_HOST];  
         unsigned char   *bintrans_data_hostpage[N_BINTRANS_VADDR_TO_HOST];  
   
         void            (*bintrans_load_32bit)(struct cpu *);   /*  Note: incorrect args  */  
         void            (*bintrans_store_32bit)(struct cpu *);  /*  Note: incorrect args  */  
         void            (*bintrans_jump_to_32bit_pc)(struct cpu *);  
         void            (*bintrans_simple_exception)(struct cpu *, int);  
         void            (*bintrans_fast_rfe)(struct cpu *);  
         void            (*bintrans_fast_eret)(struct cpu *);  
         void            (*bintrans_fast_tlbwri)(struct cpu *, int);  
         void            (*bintrans_fast_tlbpr)(struct cpu *, int);  
 #endif  
   
 #ifdef ENABLE_MIPS16  
         int             mips16;                 /*  non-zero if MIPS16 code is allowed  */  
         uint16_t        mips16_extend;          /*  set on 'extend' instructions to the entire 16-bit extend instruction  */  
 #endif  
   
 #ifdef ENABLE_INSTRUCTION_DELAYS  
         int             instruction_delay;  
 #endif  
   
         int             trace_tree_depth;  
   
         uint64_t        delay_jmpaddr;          /*  only used if delay_slot > 0  */  
         int             delay_slot;  
         int             nullify_next;           /*  set to 1 if next instruction  
                                                         is to be nullified  */  
   
         /*  This is set to non-zero, if it is possible at all that an  
             interrupt will occur.  */  
         int             cached_interrupt_is_possible;  
   
         int             show_trace_delay;       /*  0=normal, > 0 = delay until show_trace  */  
         uint64_t        show_trace_addr;  
   
         int             last_was_jumptoself;  
         int             jump_to_self_reg;  
   
 #ifdef MFHILO_DELAY  
         int             mfhi_delay;     /*  instructions since last mfhi  */  
         int             mflo_delay;     /*  instructions since last mflo  */  
 #endif  
229    
230          int             rmw;            /*  Read-Modify-Write  */          int             rmw;            /*  Read-Modify-Write  */
231          int             rmw_len;        /*  Length of rmw modification  */          uint64_t        rmw_len;        /*  Length of rmw modification  */
232          uint64_t        rmw_addr;       /*  Address of rmw modification  */          uint64_t        rmw_addr;       /*  Address of rmw modification  */
233    
234          /*          /*
235           *  TODO:  The R5900 has 128-bit registers. I'm not really sure           *  NOTE:  The R5900 has 128-bit registers. I'm not really sure
236           *  whether they are used a lot or not, at least with code produced           *  whether they are used a lot or not, at least with code produced
237           *  with gcc they are not. An important case however is lq and sq           *  with gcc they are not. An important case however is lq and sq
238           *  (load and store of 128-bit values). These "upper halves" of R5900           *  (load and store of 128-bit values). These "upper halves" of R5900
239           *  quadwords can be used in those cases.           *  quadwords can be used in those cases.
240           *           *
241             *  hi1 and lo1 are the high 64-bit parts of the hi and lo registers.
242             *  sa is a 32-bit "shift amount" register.
243             *
244           *  TODO:  Generalize this.           *  TODO:  Generalize this.
245           */           */
246          uint64_t        gpr_quadhi[N_MIPS_GPRS];          uint64_t        gpr_quadhi[N_MIPS_GPRS];
247            uint64_t        hi1;
248            uint64_t        lo1;
249            uint32_t        r5900_sa;
250    
251    
252          /*          /*
253           *  Statistics:           *  Data and Instruction caches:
254           */           */
         long            stats_opcode[N_HI6];  
         long            stats__special[N_SPECIAL];  
         long            stats__regimm[N_REGIMM];  
         long            stats__special2[N_SPECIAL];  
255    
256          /*  Data and Instruction caches:  */          /*  Cache sizes: (1 << x) x=0 for default values  */
257            /*  This is legacy stuff. TODO: Clean up!  */
258            int             cache_picache;
259            int             cache_pdcache;
260            int             cache_secondary;
261            int             cache_picache_linesize;
262            int             cache_pdcache_linesize;
263            int             cache_secondary_linesize;
264    
265          unsigned char   *cache[2];          unsigned char   *cache[2];
266          void            *cache_tags[2];          void            *cache_tags[2];
267          uint64_t        cache_last_paddr[2];          uint64_t        cache_last_paddr[2];
268          int             cache_size[2];          int             cache_size[2];
269          int             cache_linesize[2];          int             cache_linesize[2];
270          int             cache_mask[2];          int             cache_mask[2];
         int             cache_miss_penalty[2];  
271    
272          /*  Other stuff:  */  
273          uint64_t        cop0_config_select1;          /*
274             *  Instruction translation cache and Virtual->Physical->Host
275             *  address translation:
276             */
277            DYNTRANS_ITC(mips)
278            VPH_TLBS(mips,MIPS)
279            VPH32(mips,MIPS)
280            VPH64(mips,MIPS)
281  };  };
282    
283    
284  /*  cpu_mips.c:  */  /*  cpu_mips.c:  */
285  void mips_cpu_show_full_statistics(struct machine *m);  void mips_cpu_interrupt_assert(struct interrupt *interrupt);
286    void mips_cpu_interrupt_deassert(struct interrupt *interrupt);
287    int mips_cpu_instruction_has_delayslot(struct cpu *cpu, unsigned char *ib);
288  void mips_cpu_tlbdump(struct machine *m, int x, int rawflag);  void mips_cpu_tlbdump(struct machine *m, int x, int rawflag);
289  void mips_cpu_register_match(struct machine *m, char *name,  void mips_cpu_register_match(struct machine *m, char *name,
290          int writeflag, uint64_t *valuep, int *match_register);          int writeflag, uint64_t *valuep, int *match_register);
291  void mips_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs);  void mips_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs);
292  int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,  int mips_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
293          int running, uint64_t addr, int bintrans);          int running, uint64_t addr);
 int mips_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr);  
 int mips_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr);  
294  void mips_cpu_exception(struct cpu *cpu, int exccode, int tlb, uint64_t vaddr,  void mips_cpu_exception(struct cpu *cpu, int exccode, int tlb, uint64_t vaddr,
295          /*  uint64_t pagemask,  */  int coproc_nr, uint64_t vaddr_vpn2,          /*  uint64_t pagemask,  */  int coproc_nr, uint64_t vaddr_vpn2,
296          int vaddr_asid, int x_64);          int vaddr_asid, int x_64);
 void mips_cpu_cause_simple_exception(struct cpu *cpu, int exc_code);  
297  int mips_cpu_run(struct emul *emul, struct machine *machine);  int mips_cpu_run(struct emul *emul, struct machine *machine);
298  void mips_cpu_dumpinfo(struct cpu *cpu);  void mips_cpu_dumpinfo(struct cpu *cpu);
299  void mips_cpu_list_available_types(void);  void mips_cpu_list_available_types(void);
# Line 395  void mips_coproc_tlb_set_entry(struct cp Line 306  void mips_coproc_tlb_set_entry(struct cp
306          uint64_t vaddr, uint64_t paddr0, uint64_t paddr1,          uint64_t vaddr, uint64_t paddr0, uint64_t paddr1,
307          int valid0, int valid1, int dirty0, int dirty1, int global, int asid,          int valid0, int valid1, int dirty0, int dirty1, int global, int asid,
308          int cachealgo0, int cachealgo1);          int cachealgo0, int cachealgo1);
 void update_translation_table(struct cpu *cpu, uint64_t vaddr_page,  
         unsigned char *host_page, int writeflag, uint64_t paddr_page);  
 void clear_all_chunks_from_all_tables(struct cpu *cpu);  
 void mips_invalidate_translation_caches_paddr(struct cpu *cpu, uint64_t paddr);  
309  void coproc_register_read(struct cpu *cpu,  void coproc_register_read(struct cpu *cpu,
310          struct mips_coproc *cp, int reg_nr, uint64_t *ptr, int select);          struct mips_coproc *cp, int reg_nr, uint64_t *ptr, int select);
311  void coproc_register_write(struct cpu *cpu,  void coproc_register_write(struct cpu *cpu,
# Line 418  int memory_cache_R3000(struct cpu *cpu, Line 325  int memory_cache_R3000(struct cpu *cpu,
325  int mips_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr,  int mips_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr,
326          unsigned char *data, size_t len, int writeflag, int cache_flags);          unsigned char *data, size_t len, int writeflag, int cache_flags);
327    
328    int translate_v2p_mmu3k(struct cpu *cpu, uint64_t vaddr,
329  /*  mips16.c:  */          uint64_t *return_addr, int flags);
330  int mips16_to_32(struct cpu *cpu, unsigned char *instr16, unsigned char *instr);  int translate_v2p_mmu8k(struct cpu *cpu, uint64_t vaddr,
331            uint64_t *return_addr, int flags);
332    int translate_v2p_mmu10k(struct cpu *cpu, uint64_t vaddr,
333            uint64_t *return_addr, int flags);
334    int translate_v2p_mmu4100(struct cpu *cpu, uint64_t vaddr,
335            uint64_t *return_addr, int flags);
336    int translate_v2p_generic(struct cpu *cpu, uint64_t vaddr,
337            uint64_t *return_addr, int flags);
338    
339    
340    /*  Dyntrans unaligned load/store:  */
341    void mips_unaligned_loadstore(struct cpu *cpu, struct mips_instr_call *ic,
342            int is_left, int wlen, int store);
343    
344    
345    int mips_run_instr(struct cpu *cpu);
346    void mips_timer_sample_tick(struct timer *, void *);
347    void mips_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,
348            unsigned char *host_page, int writeflag, uint64_t paddr_page);
349    void mips_invalidate_translation_caches(struct cpu *cpu, uint64_t, int);
350    void mips_invalidate_code_translation(struct cpu *cpu, uint64_t, int);
351    int mips32_run_instr(struct cpu *cpu);
352    void mips32_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,
353            unsigned char *host_page, int writeflag, uint64_t paddr_page);
354    void mips32_invalidate_translation_caches(struct cpu *cpu, uint64_t, int);
355    void mips32_invalidate_code_translation(struct cpu *cpu, uint64_t, int);
356    
357    
358  #endif  /*  CPU_MIPS_H  */  #endif  /*  CPU_MIPS_H  */

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

  ViewVC Help
Powered by ViewVC 1.1.26