Commit 62724a3773b5553a696ebc5cdd212908f7572c6a
1 parent
34ee2ede
Sparc32/64 CPU selection
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2534 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
96 additions
and
9 deletions
hw/sun4m.c
| ... | ... | @@ -219,12 +219,21 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, |
| 219 | 219 | unsigned int i; |
| 220 | 220 | long vram_size = 0x100000, prom_offset, initrd_size, kernel_size; |
| 221 | 221 | void *iommu, *dma, *main_esp, *main_lance = NULL; |
| 222 | + const sparc_def_t *def; | |
| 222 | 223 | |
| 223 | 224 | linux_boot = (kernel_filename != NULL); |
| 224 | 225 | |
| 225 | 226 | /* init CPUs */ |
| 227 | + if (cpu_model == NULL) | |
| 228 | + cpu_model = "Fujitsu MB86904"; | |
| 229 | + sparc_find_by_name(cpu_model, &def); | |
| 230 | + if (def == NULL) { | |
| 231 | + fprintf(stderr, "Unable to find Sparc CPU definition\n"); | |
| 232 | + exit(1); | |
| 233 | + } | |
| 226 | 234 | for(i = 0; i < smp_cpus; i++) { |
| 227 | 235 | env = cpu_init(); |
| 236 | + cpu_sparc_register(env, def); | |
| 228 | 237 | envs[i] = env; |
| 229 | 238 | if (i != 0) |
| 230 | 239 | env->halted = 1; | ... | ... |
hw/sun4u.c
| ... | ... | @@ -266,10 +266,20 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, |
| 266 | 266 | unsigned int i; |
| 267 | 267 | long prom_offset, initrd_size, kernel_size; |
| 268 | 268 | PCIBus *pci_bus; |
| 269 | + const sparc_def_t *def; | |
| 269 | 270 | |
| 270 | 271 | linux_boot = (kernel_filename != NULL); |
| 271 | 272 | |
| 273 | + /* init CPUs */ | |
| 274 | + if (cpu_model == NULL) | |
| 275 | + cpu_model = "TI UltraSparc II"; | |
| 276 | + sparc_find_by_name(cpu_model, &def); | |
| 277 | + if (def == NULL) { | |
| 278 | + fprintf(stderr, "Unable to find Sparc CPU definition\n"); | |
| 279 | + exit(1); | |
| 280 | + } | |
| 272 | 281 | env = cpu_init(); |
| 282 | + cpu_sparc_register(env, def); | |
| 273 | 283 | register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); |
| 274 | 284 | qemu_register_reset(main_cpu_reset, env); |
| 275 | 285 | ... | ... |
target-sparc/cpu.h
| ... | ... | @@ -152,6 +152,8 @@ |
| 152 | 152 | /* 2 <= NWINDOWS <= 32. In QEMU it must also be a power of two. */ |
| 153 | 153 | #define NWINDOWS 8 |
| 154 | 154 | |
| 155 | +typedef struct sparc_def_t sparc_def_t; | |
| 156 | + | |
| 155 | 157 | typedef struct CPUSPARCState { |
| 156 | 158 | target_ulong gregs[8]; /* general registers */ |
| 157 | 159 | target_ulong *regwptr; /* pointer to current register window */ |
| ... | ... | @@ -170,6 +172,7 @@ typedef struct CPUSPARCState { |
| 170 | 172 | int psret; /* enable traps */ |
| 171 | 173 | uint32_t psrpil; /* interrupt level */ |
| 172 | 174 | int psref; /* enable fpu */ |
| 175 | + target_ulong version; | |
| 173 | 176 | jmp_buf jmp_env; |
| 174 | 177 | int user_mode_only; |
| 175 | 178 | int exception_index; |
| ... | ... | @@ -215,7 +218,6 @@ typedef struct CPUSPARCState { |
| 215 | 218 | uint64_t bgregs[8]; /* backup for normal global registers */ |
| 216 | 219 | uint64_t igregs[8]; /* interrupt general registers */ |
| 217 | 220 | uint64_t mgregs[8]; /* mmu general registers */ |
| 218 | - uint64_t version; | |
| 219 | 221 | uint64_t fprs; |
| 220 | 222 | uint64_t tick_cmpr, stick_cmpr; |
| 221 | 223 | uint64_t gsr; |
| ... | ... | @@ -233,9 +235,6 @@ typedef struct CPUSPARCState { |
| 233 | 235 | #define PUT_FSR64(env, val) do { uint64_t _tmp = val; \ |
| 234 | 236 | env->fsr = _tmp & 0x3fcfc1c3ffULL; \ |
| 235 | 237 | } while (0) |
| 236 | -// Manuf 0x17, version 0x11, mask 0 (UltraSparc-II) | |
| 237 | -#define GET_VER(env) ((0x17ULL << 48) | (0x11ULL << 32) | \ | |
| 238 | - (0 << 24) | (MAXTL << 8) | (NWINDOWS - 1)) | |
| 239 | 238 | #else |
| 240 | 239 | #define GET_FSR32(env) (env->fsr) |
| 241 | 240 | #define PUT_FSR32(env, val) do { uint32_t _tmp = val; \ |
| ... | ... | @@ -246,9 +245,12 @@ typedef struct CPUSPARCState { |
| 246 | 245 | CPUSPARCState *cpu_sparc_init(void); |
| 247 | 246 | int cpu_sparc_exec(CPUSPARCState *s); |
| 248 | 247 | int cpu_sparc_close(CPUSPARCState *s); |
| 248 | +int sparc_find_by_name (const unsigned char *name, const sparc_def_t **def); | |
| 249 | +void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, | |
| 250 | + ...)); | |
| 251 | +int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def); | |
| 249 | 252 | |
| 250 | -/* Fake impl 0, version 4 */ | |
| 251 | -#define GET_PSR(env) ((0 << 28) | (4 << 24) | (env->psr & PSR_ICC) | \ | |
| 253 | +#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \ | |
| 252 | 254 | (env->psref? PSR_EF : 0) | \ |
| 253 | 255 | (env->psrpil << 8) | \ |
| 254 | 256 | (env->psrs? PSR_S : 0) | \ | ... | ... |
target-sparc/translate.c
| ... | ... | @@ -55,6 +55,13 @@ typedef struct DisasContext { |
| 55 | 55 | struct TranslationBlock *tb; |
| 56 | 56 | } DisasContext; |
| 57 | 57 | |
| 58 | +struct sparc_def_t { | |
| 59 | + const unsigned char *name; | |
| 60 | + target_ulong iu_version; | |
| 61 | + uint32_t fpu_version; | |
| 62 | + uint32_t mmu_version; | |
| 63 | +}; | |
| 64 | + | |
| 58 | 65 | static uint16_t *gen_opc_ptr; |
| 59 | 66 | static uint32_t *gen_opparam_ptr; |
| 60 | 67 | extern FILE *logfile; |
| ... | ... | @@ -2751,11 +2758,8 @@ void cpu_reset(CPUSPARCState *env) |
| 2751 | 2758 | env->gregs[1] = ram_size; |
| 2752 | 2759 | #ifdef TARGET_SPARC64 |
| 2753 | 2760 | env->pstate = PS_PRIV; |
| 2754 | - env->version = GET_VER(env); | |
| 2755 | 2761 | env->pc = 0x1fff0000000ULL; |
| 2756 | 2762 | #else |
| 2757 | - env->fsr = 4 << 17; /* FPU version 4 (Meiko) */ | |
| 2758 | - env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */ | |
| 2759 | 2763 | env->pc = 0xffd00000; |
| 2760 | 2764 | #endif |
| 2761 | 2765 | env->npc = env->pc + 4; |
| ... | ... | @@ -2774,6 +2778,66 @@ CPUSPARCState *cpu_sparc_init(void) |
| 2774 | 2778 | return (env); |
| 2775 | 2779 | } |
| 2776 | 2780 | |
| 2781 | +static const sparc_def_t sparc_defs[] = { | |
| 2782 | +#ifdef TARGET_SPARC64 | |
| 2783 | + { | |
| 2784 | + .name = "TI UltraSparc II", | |
| 2785 | + .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0 << 24) | |
| 2786 | + | (MAXTL << 8) | (NWINDOWS - 1)), | |
| 2787 | + .fpu_version = 0x00000000, | |
| 2788 | + .mmu_version = 0, | |
| 2789 | + }, | |
| 2790 | +#else | |
| 2791 | + { | |
| 2792 | + .name = "Fujitsu MB86904", | |
| 2793 | + .iu_version = 0x04 << 24, /* Impl 0, ver 4 */ | |
| 2794 | + .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ | |
| 2795 | + .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */ | |
| 2796 | + }, | |
| 2797 | +#endif | |
| 2798 | +}; | |
| 2799 | + | |
| 2800 | +int sparc_find_by_name(const unsigned char *name, const sparc_def_t **def) | |
| 2801 | +{ | |
| 2802 | + int ret; | |
| 2803 | + unsigned int i; | |
| 2804 | + | |
| 2805 | + ret = -1; | |
| 2806 | + *def = NULL; | |
| 2807 | + for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) { | |
| 2808 | + if (strcasecmp(name, sparc_defs[i].name) == 0) { | |
| 2809 | + *def = &sparc_defs[i]; | |
| 2810 | + ret = 0; | |
| 2811 | + break; | |
| 2812 | + } | |
| 2813 | + } | |
| 2814 | + | |
| 2815 | + return ret; | |
| 2816 | +} | |
| 2817 | + | |
| 2818 | +void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)) | |
| 2819 | +{ | |
| 2820 | + unsigned int i; | |
| 2821 | + | |
| 2822 | + for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) { | |
| 2823 | + (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n", | |
| 2824 | + sparc_defs[i].name, | |
| 2825 | + sparc_defs[i].iu_version, | |
| 2826 | + sparc_defs[i].fpu_version, | |
| 2827 | + sparc_defs[i].mmu_version); | |
| 2828 | + } | |
| 2829 | +} | |
| 2830 | + | |
| 2831 | +int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def) | |
| 2832 | +{ | |
| 2833 | + env->version = def->iu_version; | |
| 2834 | + env->fsr = def->fpu_version; | |
| 2835 | +#if !defined(TARGET_SPARC64) | |
| 2836 | + env->mmuregs[0] = def->mmu_version; | |
| 2837 | +#endif | |
| 2838 | + return 0; | |
| 2839 | +} | |
| 2840 | + | |
| 2777 | 2841 | #define GET_FLAG(a,b) ((env->psr & a)?b:'-') |
| 2778 | 2842 | |
| 2779 | 2843 | void cpu_dump_state(CPUState *env, FILE *f, | ... | ... |
vl.c
| ... | ... | @@ -7007,6 +7007,8 @@ int main(int argc, char **argv) |
| 7007 | 7007 | arm_cpu_list(); |
| 7008 | 7008 | #elif defined(TARGET_MIPS) |
| 7009 | 7009 | mips_cpu_list(stdout, &fprintf); |
| 7010 | +#elif defined(TARGET_SPARC) | |
| 7011 | + sparc_cpu_list(stdout, &fprintf); | |
| 7010 | 7012 | #endif |
| 7011 | 7013 | exit(1); |
| 7012 | 7014 | } else { | ... | ... |