--- trunk/src/include/cpu_ppc.h 2007/10/08 16:18:27 10 +++ trunk/src/include/cpu_ppc.h 2007/10/08 16:18:51 14 @@ -28,7 +28,7 @@ * SUCH DAMAGE. * * - * $Id: cpu_ppc.h,v 1.23 2005/06/26 22:23:43 debug Exp $ + * $Id: cpu_ppc.h,v 1.38 2005/09/24 23:44:19 debug Exp $ */ #include "misc.h" @@ -42,13 +42,17 @@ /* PPC CPU types: */ struct ppc_cpu_type_def { char *name; + int pvr; int bits; int flags; int icache_shift; + int ilinesize; int iway; int dcache_shift; + int dlinesize; int dway; int l2cache_shift; + int l2linesize; int l2way; int altivec; @@ -59,30 +63,64 @@ #define PPC_NOFP 1 /* TODO: Most of these just bogus */ -#define PPC_CPU_TYPE_DEFS { \ - { "PPC405GP", 32, PPC_NOFP, 15, 2, 15, 2, 20, 1, 0 }, \ - { "PPC603e", 32, 0, 14, 4, 14, 4, 0, 0, 0 }, \ - { "MPC7400", 32, 0, 15, 2, 15, 2, 19, 1, 1 }, \ - { "PPC750", 32, 0, 15, 2, 15, 2, 20, 1, 0 }, \ - { "G4e", 32, 0, 15, 8, 15, 8, 18, 8, 1 }, \ - { "PPC970", 64, 0, 16, 1, 15, 2, 19, 1, 1 }, \ - { NULL, 0, 0, 0,0, 0,0, 0,0, 0 } \ - }; +#define PPC_CPU_TYPE_DEFS { \ + { "PPC405GP", 0, 32, PPC_NOFP, 15,5,2, 15,5,2, 20,5,1, 0 }, \ + { "PPC603e", 0, 32, 0, 14,5,4, 14,5,4, 0,0,0, 0 }, \ + { "MPC7400", 0x000c0000, 32, 0, 15,5,2, 15,5,2, 19,5,1, 1 }, \ + { "PPC750", 0x00084202, 32, 0, 15,5,2, 15,5,2, 20,5,1, 0 }, \ + { "G4e", 0, 32, 0, 15,5,8, 15,5,8, 18,5,8, 1 }, \ + { "PPC970", 0x00390000, 64, 0, 16,7,1, 15,7,2, 19,7,1, 1 }, \ + { NULL, 0, 0,0,0,0,0,0,0,0,0,0,0,0 } \ + } #define PPC_NGPRS 32 #define PPC_NFPRS 32 + +#define PPC_N_IC_ARGS 3 +#define PPC_INSTR_ALIGNMENT_SHIFT 2 +#define PPC_IC_ENTRIES_SHIFT 10 +#define PPC_IC_ENTRIES_PER_PAGE (1 << PPC_IC_ENTRIES_SHIFT) +#define PPC_PC_TO_IC_ENTRY(a) (((a)>>PPC_INSTR_ALIGNMENT_SHIFT) \ + & (PPC_IC_ENTRIES_PER_PAGE-1)) +#define PPC_ADDR_TO_PAGENR(a) ((a) >> (PPC_IC_ENTRIES_SHIFT \ + + PPC_INSTR_ALIGNMENT_SHIFT)) + +struct ppc_instr_call { + void (*f)(struct cpu *, struct ppc_instr_call *); + size_t arg[PPC_N_IC_ARGS]; +}; + +/* Translation cache struct for each physical page: */ +struct ppc_tc_physpage { + uint32_t next_ofs; /* or 0 for end of chain */ + uint64_t physaddr; + int flags; + struct ppc_instr_call ics[PPC_IC_ENTRIES_PER_PAGE + 1]; +}; + +#define PPC_N_VPH_ENTRIES 1048576 + +#define PPC_MAX_VPH_TLB_ENTRIES 256 +struct ppc_vpg_tlb_entry { + int valid; + int writeflag; + int64_t timestamp; + unsigned char *host_page; + uint64_t vaddr_page; + uint64_t paddr_page; +}; + struct ppc_cpu { struct ppc_cpu_type_def cpu_type; - int trace_tree_depth; - uint64_t of_emul_addr; - uint64_t pc_last; int mode; /* MODE_PPC or MODE_POWER */ int bits; /* 32 or 64 */ + uint64_t zero; /* A zero register */ + uint32_t cr; /* Condition Register */ uint32_t fpscr; /* FP Status and Control Register */ uint64_t lr; /* Link Register */ @@ -95,6 +133,9 @@ uint32_t tbu; /* Time Base Upper */ uint32_t dec; /* Decrementer */ uint32_t hdec; /* Hypervisor Decrementer */ + uint64_t sdr1; /* Storage Descriptor Register */ + uint64_t srr0; /* Supervisor save/restore 0 */ + uint64_t srr1; /* Supervisor save/restore 1 */ uint64_t ssr0; /* Machine status save/restore register 0 */ uint64_t ssr1; /* Machine status save/restore @@ -104,8 +145,48 @@ uint64_t sprg1; /* Special Purpose Register G1 */ uint64_t sprg2; /* Special Purpose Register G2 */ uint64_t sprg3; /* Special Purpose Register G3 */ + uint64_t dbsr; /* Debug Status Register */ uint32_t pvr; /* Processor Version Register */ uint32_t pir; /* Processor ID */ + + /* TODO: 64-bit SRs? (Segment registers) */ + uint32_t sr[16]; + + /* TODO: 64-bit BATs? */ + uint32_t ibat_u[4]; + uint32_t ibat_l[4]; + uint32_t dbat_u[4]; + uint32_t dbat_l[4]; + + uint64_t ll_addr; /* Load-linked / store-conditional */ + int ll_bit; + + + /* + * Instruction translation cache: + */ + + /* cur_ic_page is a pointer to an array of PPC_IC_ENTRIES_PER_PAGE + instruction call entries. next_ic points to the next such + call to be executed. */ + struct ppc_tc_physpage *cur_physpage; + struct ppc_instr_call *cur_ic_page; + struct ppc_instr_call *next_ic; + + + /* + * Virtual -> physical -> host address translation: + * + * host_load and host_store point to arrays of PPC_N_VPH_ENTRIES + * pointers (to host pages); phys_addr points to an array of + * PPC_N_VPH_ENTRIES uint32_t. + */ + + struct ppc_vpg_tlb_entry vph_tlb_entry[PPC_MAX_VPH_TLB_ENTRIES]; + unsigned char *host_load[PPC_N_VPH_ENTRIES]; + unsigned char *host_store[PPC_N_VPH_ENTRIES]; + uint32_t phys_addr[PPC_N_VPH_ENTRIES]; + struct ppc_tc_physpage *phys_page[PPC_N_VPH_ENTRIES]; }; @@ -136,20 +217,20 @@ /* cpu_ppc.c: */ -void ppc_cpu_show_full_statistics(struct machine *m); -void ppc_cpu_register_match(struct machine *m, char *name, - int writeflag, uint64_t *valuep, int *match_register); -void ppc_cpu_register_dump(struct cpu *cpu, int gprs, int coprocs); -int ppc_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr, - int running, uint64_t addr, int bintrans); -int ppc_cpu_interrupt(struct cpu *cpu, uint64_t irq_nr); -int ppc_cpu_interrupt_ack(struct cpu *cpu, uint64_t irq_nr); -int ppc_cpu_run(struct emul *emul, struct machine *machine); -void ppc_cpu_dumpinfo(struct cpu *cpu); -void ppc_cpu_list_available_types(void); +void ppc_update_translation_table(struct cpu *cpu, uint64_t vaddr_page, + unsigned char *host_page, int writeflag, uint64_t paddr_page); +void ppc32_update_translation_table(struct cpu *cpu, uint64_t vaddr_page, + unsigned char *host_page, int writeflag, uint64_t paddr_page); +void ppc_invalidate_translation_caches_paddr(struct cpu *cpu, uint64_t, int); +void ppc32_invalidate_translation_caches_paddr(struct cpu *cpu, uint64_t, int); +void ppc_invalidate_code_translation(struct cpu *cpu, uint64_t, int); +void ppc32_invalidate_code_translation(struct cpu *cpu, uint64_t, int); int ppc_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags); int ppc_cpu_family_init(struct cpu_family *); +/* memory_ppc.c: */ +int ppc_translate_address(struct cpu *cpu, uint64_t vaddr, + uint64_t *return_addr, int flags); #endif /* CPU_PPC_H */