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 { | ... | ... |