--- trunk/src/include/cpu_ppc.h 2007/10/08 16:18:38 12 +++ trunk/src/include/cpu_ppc.h 2007/10/08 16:19:56 24 @@ -2,7 +2,7 @@ #define CPU_PPC_H /* - * Copyright (C) 2005 Anders Gavare. All rights reserved. + * Copyright (C) 2005-2006 Anders Gavare. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -28,7 +28,7 @@ * SUCH DAMAGE. * * - * $Id: cpu_ppc.h,v 1.29 2005/08/14 23:44:23 debug Exp $ + * $Id: cpu_ppc.h,v 1.64 2006/03/05 16:51:55 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; @@ -57,21 +61,31 @@ /* Flags: */ #define PPC_NOFP 1 +#define PPC_601 2 +#define PPC_603 4 +#define PPC_NO_DEC 8 /* No DEC (decrementer) SPR */ + /* 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", 0x40110000, 32, PPC_NOFP|PPC_NO_DEC, \ + 13,5,2, 13,5,2, 0,5,1, 0 }, \ + { "PPC601", 0, 32, PPC_601, 14,5,4, 14,5,4, 0,0,0, 0 },\ + { "PPC603", 0x00030302, 32, PPC_603, 14,5,4, 14,5,4, 0,0,0, 0 },\ + { "PPC603e", 0x00060104, 32, PPC_603, 14,5,4, 14,5,4, 0,0,0, 0 },\ + { "PPC604", 0x00040304, 32, 0, 15,5,4, 15,5,4, 0,0,0, 0 }, \ + { "PPC620", 0x00140000, 64, 0, 15,5,4, 15,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_NVRS 32 +#define PPC_N_TGPRS 4 #define PPC_N_IC_ARGS 3 #define PPC_INSTR_ALIGNMENT_SHIFT 2 @@ -82,92 +96,53 @@ #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]; -}; +#define PPC_L2N 17 +#define PPC_L3N 18 -/* 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]; -}; +DYNTRANS_MISC_DECLARATIONS(ppc,PPC,uint64_t) +DYNTRANS_MISC64_DECLARATIONS(ppc,PPC,uint8_t) -#define PPC_N_VPH_ENTRIES 1048576 +#define PPC_MAX_VPH_TLB_ENTRIES 128 -#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; uint64_t of_emul_addr; - uint64_t pc_last; int mode; /* MODE_PPC or MODE_POWER */ int bits; /* 32 or 64 */ + int irq_asserted; /* External Interrupt flag */ + int dec_intr_pending;/* Decrementer interrupt pending */ uint64_t zero; /* A zero register */ uint32_t cr; /* Condition Register */ uint32_t fpscr; /* FP Status and Control Register */ - uint64_t lr; /* Link Register */ - uint64_t ctr; /* Count Register */ uint64_t gpr[PPC_NGPRS]; /* General Purpose Registers */ - uint64_t xer; /* FP Exception Register */ uint64_t fpr[PPC_NFPRS]; /* Floating-Point Registers */ - uint32_t tbl; /* Time Base Lower */ - uint32_t tbu; /* Time Base Upper */ - uint32_t dec; /* Decrementer */ - uint32_t hdec; /* Hypervisor Decrementer */ - uint64_t ssr0; /* Machine status save/restore - register 0 */ - uint64_t ssr1; /* Machine status save/restore - register 1 */ - uint64_t msr; /* Machine state register */ - uint64_t sprg0; /* Special Purpose Register G0 */ - uint64_t sprg1; /* Special Purpose Register G1 */ - uint64_t sprg2; /* Special Purpose Register G2 */ - uint64_t sprg3; /* Special Purpose Register G3 */ - uint32_t pvr; /* Processor Version Register */ - uint32_t pir; /* Processor ID */ + uint64_t vr_hi[PPC_NVRS];/* 128-bit Vector registers */ + uint64_t vr_lo[PPC_NVRS];/* (Hi and lo 64-bit parts) */ + uint64_t msr; /* Machine state register */ + uint64_t tgpr[PPC_N_TGPRS];/*Temporary gpr 0..3 */ - /* - * Instruction translation cache: - */ + uint32_t sr[16]; /* Segment registers. */ + uint64_t spr[1024]; - /* 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; + uint64_t ll_addr; /* Load-linked / store-conditional */ + int ll_bit; /* - * 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. + * Instruction translation cache and Virtual->Physical->Host + * address translation: */ - - 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]; + DYNTRANS_ITC(ppc) + VPH_TLBS(ppc,PPC) + VPH32(ppc,PPC,uint64_t,uint8_t) + VPH64(ppc,PPC,uint8_t) }; @@ -176,35 +151,69 @@ /* bits 62..61 are reserved */ #define PPC_MSR_HV (1ULL << 60) /* Hypervisor */ /* bits 59..17 are reserved */ +#define PPC_MSR_VEC (1 << 25) /* Altivec Enable */ +#define PPC_MSR_TGPR (1 << 17) /* Temporary gpr0..3 */ #define PPC_MSR_ILE (1 << 16) /* Interrupt Little-Endian Mode */ #define PPC_MSR_EE (1 << 15) /* External Interrupt Enable */ -#define PPC_MSR_PR (1 << 14) /* Problem State */ +#define PPC_MSR_PR (1 << 14) /* Problem/Privilege State */ #define PPC_MSR_FP (1 << 13) /* Floating-Point Available */ #define PPC_MSR_ME (1 << 12) /* Machine Check Interrupt Enable */ #define PPC_MSR_FE0 (1 << 11) /* Floating-Point Exception Mode 0 */ #define PPC_MSR_SE (1 << 10) /* Single-Step Trace Enable */ #define PPC_MSR_BE (1 << 9) /* Branch Trace Enable */ #define PPC_MSR_FE1 (1 << 8) /* Floating-Point Exception Mode 1 */ +#define PPC_MSR_IP (1 << 6) /* Vector Table at 0xfff00000 */ #define PPC_MSR_IR (1 << 5) /* Instruction Relocate */ #define PPC_MSR_DR (1 << 4) /* Data Relocate */ #define PPC_MSR_PMM (1 << 2) /* Performance Monitor Mark */ #define PPC_MSR_RI (1 << 1) /* Recoverable Interrupt */ #define PPC_MSR_LE (1) /* Little-Endian Mode */ +/* Floating-point Status: */ +#define PPC_FPSCR_FX (1 << 31) /* Exception summary */ +#define PPC_FPSCR_FEX (1 << 30) /* Enabled Exception summary */ +#define PPC_FPSCR_VX (1 << 29) /* Invalid Operation summary */ +/* .. TODO */ +#define PPC_FPSCR_VXNAN (1 << 24) +/* .. TODO */ +#define PPC_FPSCR_FPCC 0x0000f000 +#define PPC_FPSCR_FPCC_SHIFT 12 +#define PPC_FPSCR_FL (1 << 15) /* Less than */ +#define PPC_FPSCR_FG (1 << 14) /* Greater than */ +#define PPC_FPSCR_FE (1 << 13) /* Equal or Zero */ +#define PPC_FPSCR_FU (1 << 12) /* Unordered or NaN */ + +/* Exceptions: */ +#define PPC_EXCEPTION_DSI 0x3 /* Data Storage Interrupt */ +#define PPC_EXCEPTION_ISI 0x4 /* Instruction Storage Interrupt */ +#define PPC_EXCEPTION_EI 0x5 /* External interrupt */ +#define PPC_EXCEPTION_FPU 0x8 /* Floating-Point unavailable */ +#define PPC_EXCEPTION_DEC 0x9 /* Decrementer */ +#define PPC_EXCEPTION_SC 0xc /* Syscall */ + /* XER bits: */ -#define PPC_XER_SO (1 << 31) /* Summary Overflow */ +#define PPC_XER_SO (1UL << 31) /* Summary Overflow */ #define PPC_XER_OV (1 << 30) /* Overflow */ #define PPC_XER_CA (1 << 29) /* Carry */ /* cpu_ppc.c: */ +void ppc_exception(struct cpu *cpu, int exception_nr); void ppc_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 paddr); -void ppc_invalidate_code_translation_caches(struct cpu *cpu); +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(struct cpu *cpu, uint64_t, int); +void ppc32_invalidate_translation_caches(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); +void ppc_init_64bit_dummy_tables(struct cpu *cpu); 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 */