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,12 +219,21 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, | ||
219 | unsigned int i; | 219 | unsigned int i; |
220 | long vram_size = 0x100000, prom_offset, initrd_size, kernel_size; | 220 | long vram_size = 0x100000, prom_offset, initrd_size, kernel_size; |
221 | void *iommu, *dma, *main_esp, *main_lance = NULL; | 221 | void *iommu, *dma, *main_esp, *main_lance = NULL; |
222 | + const sparc_def_t *def; | ||
222 | 223 | ||
223 | linux_boot = (kernel_filename != NULL); | 224 | linux_boot = (kernel_filename != NULL); |
224 | 225 | ||
225 | /* init CPUs */ | 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 | for(i = 0; i < smp_cpus; i++) { | 234 | for(i = 0; i < smp_cpus; i++) { |
227 | env = cpu_init(); | 235 | env = cpu_init(); |
236 | + cpu_sparc_register(env, def); | ||
228 | envs[i] = env; | 237 | envs[i] = env; |
229 | if (i != 0) | 238 | if (i != 0) |
230 | env->halted = 1; | 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,10 +266,20 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device, | ||
266 | unsigned int i; | 266 | unsigned int i; |
267 | long prom_offset, initrd_size, kernel_size; | 267 | long prom_offset, initrd_size, kernel_size; |
268 | PCIBus *pci_bus; | 268 | PCIBus *pci_bus; |
269 | + const sparc_def_t *def; | ||
269 | 270 | ||
270 | linux_boot = (kernel_filename != NULL); | 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 | env = cpu_init(); | 281 | env = cpu_init(); |
282 | + cpu_sparc_register(env, def); | ||
273 | register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); | 283 | register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); |
274 | qemu_register_reset(main_cpu_reset, env); | 284 | qemu_register_reset(main_cpu_reset, env); |
275 | 285 |
target-sparc/cpu.h
@@ -152,6 +152,8 @@ | @@ -152,6 +152,8 @@ | ||
152 | /* 2 <= NWINDOWS <= 32. In QEMU it must also be a power of two. */ | 152 | /* 2 <= NWINDOWS <= 32. In QEMU it must also be a power of two. */ |
153 | #define NWINDOWS 8 | 153 | #define NWINDOWS 8 |
154 | 154 | ||
155 | +typedef struct sparc_def_t sparc_def_t; | ||
156 | + | ||
155 | typedef struct CPUSPARCState { | 157 | typedef struct CPUSPARCState { |
156 | target_ulong gregs[8]; /* general registers */ | 158 | target_ulong gregs[8]; /* general registers */ |
157 | target_ulong *regwptr; /* pointer to current register window */ | 159 | target_ulong *regwptr; /* pointer to current register window */ |
@@ -170,6 +172,7 @@ typedef struct CPUSPARCState { | @@ -170,6 +172,7 @@ typedef struct CPUSPARCState { | ||
170 | int psret; /* enable traps */ | 172 | int psret; /* enable traps */ |
171 | uint32_t psrpil; /* interrupt level */ | 173 | uint32_t psrpil; /* interrupt level */ |
172 | int psref; /* enable fpu */ | 174 | int psref; /* enable fpu */ |
175 | + target_ulong version; | ||
173 | jmp_buf jmp_env; | 176 | jmp_buf jmp_env; |
174 | int user_mode_only; | 177 | int user_mode_only; |
175 | int exception_index; | 178 | int exception_index; |
@@ -215,7 +218,6 @@ typedef struct CPUSPARCState { | @@ -215,7 +218,6 @@ typedef struct CPUSPARCState { | ||
215 | uint64_t bgregs[8]; /* backup for normal global registers */ | 218 | uint64_t bgregs[8]; /* backup for normal global registers */ |
216 | uint64_t igregs[8]; /* interrupt general registers */ | 219 | uint64_t igregs[8]; /* interrupt general registers */ |
217 | uint64_t mgregs[8]; /* mmu general registers */ | 220 | uint64_t mgregs[8]; /* mmu general registers */ |
218 | - uint64_t version; | ||
219 | uint64_t fprs; | 221 | uint64_t fprs; |
220 | uint64_t tick_cmpr, stick_cmpr; | 222 | uint64_t tick_cmpr, stick_cmpr; |
221 | uint64_t gsr; | 223 | uint64_t gsr; |
@@ -233,9 +235,6 @@ typedef struct CPUSPARCState { | @@ -233,9 +235,6 @@ typedef struct CPUSPARCState { | ||
233 | #define PUT_FSR64(env, val) do { uint64_t _tmp = val; \ | 235 | #define PUT_FSR64(env, val) do { uint64_t _tmp = val; \ |
234 | env->fsr = _tmp & 0x3fcfc1c3ffULL; \ | 236 | env->fsr = _tmp & 0x3fcfc1c3ffULL; \ |
235 | } while (0) | 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 | #else | 238 | #else |
240 | #define GET_FSR32(env) (env->fsr) | 239 | #define GET_FSR32(env) (env->fsr) |
241 | #define PUT_FSR32(env, val) do { uint32_t _tmp = val; \ | 240 | #define PUT_FSR32(env, val) do { uint32_t _tmp = val; \ |
@@ -246,9 +245,12 @@ typedef struct CPUSPARCState { | @@ -246,9 +245,12 @@ typedef struct CPUSPARCState { | ||
246 | CPUSPARCState *cpu_sparc_init(void); | 245 | CPUSPARCState *cpu_sparc_init(void); |
247 | int cpu_sparc_exec(CPUSPARCState *s); | 246 | int cpu_sparc_exec(CPUSPARCState *s); |
248 | int cpu_sparc_close(CPUSPARCState *s); | 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 | (env->psref? PSR_EF : 0) | \ | 254 | (env->psref? PSR_EF : 0) | \ |
253 | (env->psrpil << 8) | \ | 255 | (env->psrpil << 8) | \ |
254 | (env->psrs? PSR_S : 0) | \ | 256 | (env->psrs? PSR_S : 0) | \ |
target-sparc/translate.c
@@ -55,6 +55,13 @@ typedef struct DisasContext { | @@ -55,6 +55,13 @@ typedef struct DisasContext { | ||
55 | struct TranslationBlock *tb; | 55 | struct TranslationBlock *tb; |
56 | } DisasContext; | 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 | static uint16_t *gen_opc_ptr; | 65 | static uint16_t *gen_opc_ptr; |
59 | static uint32_t *gen_opparam_ptr; | 66 | static uint32_t *gen_opparam_ptr; |
60 | extern FILE *logfile; | 67 | extern FILE *logfile; |
@@ -2751,11 +2758,8 @@ void cpu_reset(CPUSPARCState *env) | @@ -2751,11 +2758,8 @@ void cpu_reset(CPUSPARCState *env) | ||
2751 | env->gregs[1] = ram_size; | 2758 | env->gregs[1] = ram_size; |
2752 | #ifdef TARGET_SPARC64 | 2759 | #ifdef TARGET_SPARC64 |
2753 | env->pstate = PS_PRIV; | 2760 | env->pstate = PS_PRIV; |
2754 | - env->version = GET_VER(env); | ||
2755 | env->pc = 0x1fff0000000ULL; | 2761 | env->pc = 0x1fff0000000ULL; |
2756 | #else | 2762 | #else |
2757 | - env->fsr = 4 << 17; /* FPU version 4 (Meiko) */ | ||
2758 | - env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */ | ||
2759 | env->pc = 0xffd00000; | 2763 | env->pc = 0xffd00000; |
2760 | #endif | 2764 | #endif |
2761 | env->npc = env->pc + 4; | 2765 | env->npc = env->pc + 4; |
@@ -2774,6 +2778,66 @@ CPUSPARCState *cpu_sparc_init(void) | @@ -2774,6 +2778,66 @@ CPUSPARCState *cpu_sparc_init(void) | ||
2774 | return (env); | 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 | #define GET_FLAG(a,b) ((env->psr & a)?b:'-') | 2841 | #define GET_FLAG(a,b) ((env->psr & a)?b:'-') |
2778 | 2842 | ||
2779 | void cpu_dump_state(CPUState *env, FILE *f, | 2843 | void cpu_dump_state(CPUState *env, FILE *f, |
vl.c
@@ -7007,6 +7007,8 @@ int main(int argc, char **argv) | @@ -7007,6 +7007,8 @@ int main(int argc, char **argv) | ||
7007 | arm_cpu_list(); | 7007 | arm_cpu_list(); |
7008 | #elif defined(TARGET_MIPS) | 7008 | #elif defined(TARGET_MIPS) |
7009 | mips_cpu_list(stdout, &fprintf); | 7009 | mips_cpu_list(stdout, &fprintf); |
7010 | +#elif defined(TARGET_SPARC) | ||
7011 | + sparc_cpu_list(stdout, &fprintf); | ||
7010 | #endif | 7012 | #endif |
7011 | exit(1); | 7013 | exit(1); |
7012 | } else { | 7014 | } else { |