📄 translate_init.c
字号:
spr_register(env, SPR_MMCR0, "MMCR0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_MMCR1, "MMCR1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_PMC1, "PMC1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_PMC2, "PMC2", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_PMC3, "PMC3", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_PMC4, "PMC4", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_SIA, "SIA", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, SPR_NOACCESS, 0x00000000); spr_register(env, SPR_UMMCR0, "UMMCR0", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); spr_register(env, SPR_UMMCR1, "UMMCR1", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); spr_register(env, SPR_UPMC1, "UPMC1", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); spr_register(env, SPR_UPMC2, "UPMC2", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); spr_register(env, SPR_UPMC3, "UPMC3", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); spr_register(env, SPR_UPMC4, "UPMC4", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); spr_register(env, SPR_USIA, "USIA", &spr_read_ureg, SPR_NOACCESS, &spr_read_ureg, SPR_NOACCESS, 0x00000000); /* Thermal management */ /* XXX : not implemented */ spr_register(env, SPR_THRM1, "THRM1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_THRM2, "THRM2", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_THRM3, "THRM3", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* External access control */ /* XXX : not implemented */ spr_register(env, SPR_EAR, "EAR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000);}/* SPR specific to PowerPC 604 implementation */static void gen_spr_604 (CPUPPCState *env){ /* Processor identification */ spr_register(env, SPR_PIR, "PIR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_pir, 0x00000000); /* Breakpoints */ /* XXX : not implemented */ spr_register(env, SPR_IABR, "IABR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_DABR, "DABR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* Performance counters */ /* XXX : not implemented */ spr_register(env, SPR_MMCR0, "MMCR0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_MMCR1, "MMCR1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_PMC1, "PMC1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_PMC2, "PMC2", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_PMC3, "PMC3", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_PMC4, "PMC4", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_SIA, "SIA", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, SPR_NOACCESS, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_SDA, "SDA", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, SPR_NOACCESS, 0x00000000); /* External access control */ /* XXX : not implemented */ spr_register(env, SPR_EAR, "EAR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000);}// XXX: TODO (64 bits PPC sprs)/* * ASR => SPR 280 (64 bits) * FPECR => SPR 1022 (?) * VRSAVE => SPR 256 (Altivec) * SCOMC => SPR 276 (64 bits ?) * SCOMD => SPR 277 (64 bits ?) * HSPRG0 => SPR 304 (hypervisor) * HSPRG1 => SPR 305 (hypervisor) * HDEC => SPR 310 (hypervisor) * HIOR => SPR 311 (hypervisor) * RMOR => SPR 312 (970) * HRMOR => SPR 313 (hypervisor) * HSRR0 => SPR 314 (hypervisor) * HSRR1 => SPR 315 (hypervisor) * LPCR => SPR 316 (970) * LPIDR => SPR 317 (970) * ... and more (thermal management, performance counters, ...) */static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def){ /* Default MMU definitions */ env->nb_BATs = -1; env->nb_tlb = 0; env->nb_ways = 0; /* XXX: missing: * 32 bits PPC: * - MPC5xx(x) * - MPC8xx(x) * - RCPU (MPC5xx) */ spr_register(env, SPR_PVR, "PVR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, SPR_NOACCESS, def->pvr); switch (def->pvr & def->pvr_mask) { case CPU_PPC_604: /* PPC 604 */ case CPU_PPC_604E: /* PPC 604e */ case CPU_PPC_604R: /* PPC 604r */ gen_spr_generic(env); gen_spr_ne_601(env); /* Memory management */ gen_low_BATs(env); /* Time base */ gen_tbl(env); gen_spr_604(env); /* Hardware implementation registers */ /* XXX : not implemented */ spr_register(env, SPR_HID0, "HID0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_HID1, "HID1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); break; case CPU_PPC_74x: /* PPC 740 / 750 */ case CPU_PPC_74xP: /* PPC 740P / 750P */ case CPU_PPC_750CXE: /* IBM PPC 750cxe */ gen_spr_generic(env); gen_spr_ne_601(env); /* Memory management */ gen_low_BATs(env); /* Time base */ gen_tbl(env); gen_spr_7xx(env); /* XXX : not implemented */ spr_register(env, SPR_L2CR, "L2CR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* Hardware implementation registers */ /* XXX : not implemented */ spr_register(env, SPR_HID0, "HID0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_HID1, "HID1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); break; case CPU_PPC_750FX: /* IBM PPC 750 FX */ case CPU_PPC_750GX: /* IBM PPC 750 GX */ gen_spr_generic(env); gen_spr_ne_601(env); /* Memory management */ gen_low_BATs(env); /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */ gen_high_BATs(env); /* Time base */ gen_tbl(env); gen_spr_7xx(env); /* XXX : not implemented */ spr_register(env, SPR_L2CR, "L2CR", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* Hardware implementation registers */ /* XXX : not implemented */ spr_register(env, SPR_HID0, "HID0", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_HID1, "HID1", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); /* XXX : not implemented */ spr_register(env, SPR_750_HID2, "HID2", SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x00000000); break; default: gen_spr_generic(env); break; } if (env->nb_BATs == -1) env->nb_BATs = 4;}#if defined(PPC_DUMP_CPU)static void dump_sprs (CPUPPCState *env){ ppc_spr_t *spr; uint32_t pvr = env->spr[SPR_PVR]; uint32_t sr, sw, ur, uw; int i, j, n; printf("* SPRs for PVR=%08x\n", pvr); for (i = 0; i < 32; i++) { for (j = 0; j < 32; j++) { n = (i << 5) | j; spr = &env->spr_cb[n]; sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS; sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS; uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS; ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS; if (sw || sr || uw || ur) { printf("%4d (%03x) %8s s%c%c u%c%c\n", (i << 5) | j, (i << 5) | j, spr->name, sw ? 'w' : '-', sr ? 'r' : '-', uw ? 'w' : '-', ur ? 'r' : '-'); } } } fflush(stdout); fflush(stderr);}#endif/*****************************************************************************/#include <stdlib.h>#include <string.h>int fflush (FILE *stream);/* Opcode types */enum { PPC_DIRECT = 0, /* Opcode routine */ PPC_INDIRECT = 1, /* Indirect opcode table */};static inline int is_indirect_opcode (void *handler){ return ((unsigned long)handler & 0x03) == PPC_INDIRECT;}static inline opc_handler_t **ind_table(void *handler){ return (opc_handler_t **)((unsigned long)handler & ~3);}/* Instruction table creation *//* Opcodes tables creation */static void fill_new_table (opc_handler_t **table, int len){ int i; for (i = 0; i < len; i++) table[i] = &invalid_handler;}static int create_new_table (opc_handler_t **table, unsigned char idx){ opc_handler_t **tmp; tmp = malloc(0x20 * sizeof(opc_handler_t)); if (tmp == NULL) return -1; fill_new_table(tmp, 0x20); table[idx] = (opc_handler_t *)((unsigned long)tmp | PPC_INDIRECT); return 0;}static int insert_in_table (opc_handler_t **table, unsigned char idx, opc_handler_t *handler){ if (table[idx] != &invalid_handler) return -1; table[idx] = handler; return 0;}static int register_direct_insn (opc_handler_t **ppc_opcodes, unsigned char idx, opc_handler_t *handler){ if (insert_in_table(ppc_opcodes, idx, handler) < 0) { printf("*** ERROR: opcode %02x already assigned in main " "opcode table\n", idx); return -1; } return 0;}static int register_ind_in_table (opc_handler_t **table, unsigned char idx1, unsigned char idx2, opc_handler_t *handler){ if (table[idx1] == &invalid_handler) { if (create_new_table(table, idx1) < 0) { printf("*** ERROR: unable to create indirect table " "idx=%02x\n", idx1); return -1; } } else { if (!is_indirect_opcode(table[idx1])) { printf("*** ERROR: idx %02x already assigned to a direct " "opcode\n", idx1); return -1; } } if (handler != NULL && insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) { printf("*** ERROR: opcode %02x already assigned in " "opcode table %02x\n", idx2, idx1); return -1; } return 0;}static int register_ind_insn (opc_handler_t **ppc_opcodes, unsigned char idx1, unsigned char idx2, opc_handler_t *handler){ int ret; ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler); return ret;}static int register_dblind_insn (opc_handler_t **ppc_opcodes, unsigned char idx1, unsigned char idx2, unsigned char idx3, opc_handler_t *handler){ if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) { printf("*** ERROR: unable to join indirect table idx " "[%02x-%02x]\n", idx1, idx2); return -1; } if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3, handler) < 0) { printf("*** ERROR: unable to insert opcode " "[%02x-%02x-%02x]\n", idx1, idx2, idx3); return -1; } return 0;}static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn){ if (insn->opc2 != 0xFF) { if (insn->opc3 != 0xFF) { if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2, insn->opc3, &insn->handler) < 0) return -1; } else { if (register_ind_insn(ppc_opcodes, insn->opc1, insn->opc2, &insn->handler) < 0) return -1; } } else { if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0) return -1; } return 0;}static int test_opcode_table (opc_handler_t **table, int len){ int i, count, tmp; for (i = 0, count = 0; i < len; i++) { /* Consistency fixup */ if (table[i] == NULL) table[i] = &invalid_handler; if (table[i] != &invalid_handler) { if (is_indirect_opcode(table[i])) { tmp = test_opcode_table(ind_table(table[i]), 0x20); if (tmp == 0) { free(table[i]); table[i] = &invalid_handler; } else { count++; } } else { count++; } } } return count;}static void fix_opcode_tables (opc_handler_t **ppc_opcodes){ if (test_opcode_table(ppc_opcodes, 0x40) == 0) printf("*** WARNING: no opcode defined !\n");}/*****************************************************************************/static int create_ppc_opcodes (CPUPPCState *env, ppc_def_t *def){ opcode_t *opc, *start, *end; fill_new_table(env->opcodes, 0x40);#if defined(PPC_DUMP_CPU) printf("* PPC instructions for PVR %08x: %s\n", def->pvr, def->name);#endif if (&opc_start < &opc_end) { start = &opc_start; end = &opc_end; } else { start = &opc_end; end = &opc_start; } for (opc = start + 1; opc != end; opc++) { if ((opc->handler.type & def->insns_flags) != 0) { if (register_insn(env->opcodes, opc) < 0) { printf("*** ERROR initializing PPC instruction " "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2, opc->opc3); return -1; }#if defined(PPC_DUMP_CPU) if (opc1 != 0x00) { if (opc->opc3 == 0xFF) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -