Commit 0fd3ca30c44bad68aebf0068403d9c9ce68fb3f6

Authored by aurel32
1 parent 86e0abc7

sh4: CPU versioning.

Trivial patch adding CPU listing and the ability to do per-subtype
CVR/PVR/PRR values. Presently SH7750R and SH7751R definitions are
provided, as these are the ones in present use in-tree.

The CVR value for SH7751R is intentionally restricted so the kernel
boots, though this will want to be switched to the proper CVR value
once system emulation has sufficiently stabilized.

This also makes it trivial to abstract subtype specific registers like
MMU_PTEA and to set up feature bits in line with the kernel probing for
things like conditionalizing FPU/DSP context.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5133 c046a42c-6fe2-441c-8c8c-71466251a162
hw/r2d.c
@@ -39,7 +39,7 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size, @@ -39,7 +39,7 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
39 struct SH7750State *s; 39 struct SH7750State *s;
40 40
41 if (!cpu_model) 41 if (!cpu_model)
42 - cpu_model = "any"; 42 + cpu_model = "SH7751R";
43 43
44 env = cpu_init(cpu_model); 44 env = cpu_init(cpu_model);
45 if (!env) { 45 if (!env) {
hw/sh7750.c
@@ -249,12 +249,12 @@ static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr) @@ -249,12 +249,12 @@ static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr)
249 return s->cpu->intevt; 249 return s->cpu->intevt;
250 case SH7750_CCR_A7: 250 case SH7750_CCR_A7:
251 return s->ccr; 251 return s->ccr;
252 - case 0x1f000030: /* Processor version PVR */  
253 - return 0x00050000; /* SH7750R */  
254 - case 0x1f000040: /* Processor version CVR */  
255 - return 0x00110000; /* Minimum caches */  
256 - case 0x1f000044: /* Processor version PRR */  
257 - return 0x00000100; /* SH7750R */ 252 + case 0x1f000030: /* Processor version */
  253 + return s->cpu->pvr;
  254 + case 0x1f000040: /* Cache version */
  255 + return s->cpu->cvr;
  256 + case 0x1f000044: /* Processor revision */
  257 + return s->cpu->prr;
258 default: 258 default:
259 error_access("long read", addr); 259 error_access("long read", addr);
260 assert(0); 260 assert(0);
@@ -529,14 +529,6 @@ static struct intc_group groups_pci[] = { @@ -529,14 +529,6 @@ static struct intc_group groups_pci[] = {
529 PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3), 529 PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3),
530 }; 530 };
531 531
532 -#define SH_CPU_SH7750 (1 << 0)  
533 -#define SH_CPU_SH7750S (1 << 1)  
534 -#define SH_CPU_SH7750R (1 << 2)  
535 -#define SH_CPU_SH7751 (1 << 3)  
536 -#define SH_CPU_SH7751R (1 << 4)  
537 -#define SH_CPU_SH7750_ALL (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7750R)  
538 -#define SH_CPU_SH7751_ALL (SH_CPU_SH7751 | SH_CPU_SH7751R)  
539 -  
540 /********************************************************************** 532 /**********************************************************************
541 Memory mapped cache and TLB 533 Memory mapped cache and TLB
542 **********************************************************************/ 534 **********************************************************************/
@@ -644,7 +636,6 @@ SH7750State *sh7750_init(CPUSH4State * cpu) @@ -644,7 +636,6 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
644 SH7750State *s; 636 SH7750State *s;
645 int sh7750_io_memory; 637 int sh7750_io_memory;
646 int sh7750_mm_cache_and_tlb; /* memory mapped cache and tlb */ 638 int sh7750_mm_cache_and_tlb; /* memory mapped cache and tlb */
647 - int cpu_model = SH_CPU_SH7751R; /* for now */  
648 639
649 s = qemu_mallocz(sizeof(SH7750State)); 640 s = qemu_mallocz(sizeof(SH7750State));
650 s->cpu = cpu; 641 s->cpu = cpu;
@@ -664,7 +655,7 @@ SH7750State *sh7750_init(CPUSH4State * cpu) @@ -664,7 +655,7 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
664 _INTC_ARRAY(mask_registers), 655 _INTC_ARRAY(mask_registers),
665 _INTC_ARRAY(prio_registers)); 656 _INTC_ARRAY(prio_registers));
666 657
667 - sh_intc_register_sources(&s->intc, 658 + sh_intc_register_sources(&s->intc,
668 _INTC_ARRAY(vectors), 659 _INTC_ARRAY(vectors),
669 _INTC_ARRAY(groups)); 660 _INTC_ARRAY(groups));
670 661
@@ -692,20 +683,20 @@ SH7750State *sh7750_init(CPUSH4State * cpu) @@ -692,20 +683,20 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
692 sh_intc_source(&s->intc, TMU2_TUNI), 683 sh_intc_source(&s->intc, TMU2_TUNI),
693 sh_intc_source(&s->intc, TMU2_TICPI)); 684 sh_intc_source(&s->intc, TMU2_TICPI));
694 685
695 - if (cpu_model & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) {  
696 - sh_intc_register_sources(&s->intc, 686 + if (cpu->id & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) {
  687 + sh_intc_register_sources(&s->intc,
697 _INTC_ARRAY(vectors_dma4), 688 _INTC_ARRAY(vectors_dma4),
698 _INTC_ARRAY(groups_dma4)); 689 _INTC_ARRAY(groups_dma4));
699 } 690 }
700 691
701 - if (cpu_model & (SH_CPU_SH7750R | SH_CPU_SH7751R)) {  
702 - sh_intc_register_sources(&s->intc, 692 + if (cpu->id & (SH_CPU_SH7750R | SH_CPU_SH7751R)) {
  693 + sh_intc_register_sources(&s->intc,
703 _INTC_ARRAY(vectors_dma8), 694 _INTC_ARRAY(vectors_dma8),
704 _INTC_ARRAY(groups_dma8)); 695 _INTC_ARRAY(groups_dma8));
705 } 696 }
706 697
707 - if (cpu_model & (SH_CPU_SH7750R | SH_CPU_SH7751 | SH_CPU_SH7751R)) {  
708 - sh_intc_register_sources(&s->intc, 698 + if (cpu->id & (SH_CPU_SH7750R | SH_CPU_SH7751 | SH_CPU_SH7751R)) {
  699 + sh_intc_register_sources(&s->intc,
709 _INTC_ARRAY(vectors_tmu34), 700 _INTC_ARRAY(vectors_tmu34),
710 NULL, 0); 701 NULL, 0);
711 tmu012_init(0x1e100000, 0, s->periph_freq, 702 tmu012_init(0x1e100000, 0, s->periph_freq,
@@ -714,14 +705,14 @@ SH7750State *sh7750_init(CPUSH4State * cpu) @@ -714,14 +705,14 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
714 NULL, NULL); 705 NULL, NULL);
715 } 706 }
716 707
717 - if (cpu_model & (SH_CPU_SH7751_ALL)) {  
718 - sh_intc_register_sources(&s->intc, 708 + if (cpu->id & (SH_CPU_SH7751_ALL)) {
  709 + sh_intc_register_sources(&s->intc,
719 _INTC_ARRAY(vectors_pci), 710 _INTC_ARRAY(vectors_pci),
720 _INTC_ARRAY(groups_pci)); 711 _INTC_ARRAY(groups_pci));
721 } 712 }
722 713
723 - if (cpu_model & (SH_CPU_SH7750S | SH_CPU_SH7750R | SH_CPU_SH7751_ALL)) {  
724 - sh_intc_register_sources(&s->intc, 714 + if (cpu->id & (SH_CPU_SH7750S | SH_CPU_SH7750R | SH_CPU_SH7751_ALL)) {
  715 + sh_intc_register_sources(&s->intc,
725 _INTC_ARRAY(vectors_irlm), 716 _INTC_ARRAY(vectors_irlm),
726 NULL, 0); 717 NULL, 0);
727 } 718 }
target-sh4/cpu.h
@@ -27,6 +27,15 @@ @@ -27,6 +27,15 @@
27 27
28 #define ELF_MACHINE EM_SH 28 #define ELF_MACHINE EM_SH
29 29
  30 +/* CPU Subtypes */
  31 +#define SH_CPU_SH7750 (1 << 0)
  32 +#define SH_CPU_SH7750S (1 << 1)
  33 +#define SH_CPU_SH7750R (1 << 2)
  34 +#define SH_CPU_SH7751 (1 << 3)
  35 +#define SH_CPU_SH7751R (1 << 4)
  36 +#define SH_CPU_SH7750_ALL (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7750R)
  37 +#define SH_CPU_SH7751_ALL (SH_CPU_SH7751 | SH_CPU_SH7751R)
  38 +
30 #include "cpu-defs.h" 39 #include "cpu-defs.h"
31 40
32 #include "softfloat.h" 41 #include "softfloat.h"
@@ -80,6 +89,8 @@ typedef struct tlb_t { @@ -80,6 +89,8 @@ typedef struct tlb_t {
80 #define NB_MMU_MODES 2 89 #define NB_MMU_MODES 2
81 90
82 typedef struct CPUSH4State { 91 typedef struct CPUSH4State {
  92 + int id; /* CPU model */
  93 +
83 uint32_t flags; /* general execution flags */ 94 uint32_t flags; /* general execution flags */
84 uint32_t gregs[24]; /* general registers */ 95 uint32_t gregs[24]; /* general registers */
85 float32 fregs[32]; /* floating point registers */ 96 float32 fregs[32]; /* floating point registers */
@@ -112,6 +123,10 @@ typedef struct CPUSH4State { @@ -112,6 +123,10 @@ typedef struct CPUSH4State {
112 uint32_t expevt; /* exception event register */ 123 uint32_t expevt; /* exception event register */
113 uint32_t intevt; /* interrupt event register */ 124 uint32_t intevt; /* interrupt event register */
114 125
  126 + uint32_t pvr; /* Processor Version Register */
  127 + uint32_t prr; /* Processor Revision Register */
  128 + uint32_t cvr; /* Cache Version Register */
  129 +
115 CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ 130 CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */
116 tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ 131 tlb_t itlb[ITLB_SIZE]; /* instruction translation table */
117 void *intc_handle; 132 void *intc_handle;
@@ -122,6 +137,7 @@ CPUSH4State *cpu_sh4_init(const char *cpu_model); @@ -122,6 +137,7 @@ CPUSH4State *cpu_sh4_init(const char *cpu_model);
122 int cpu_sh4_exec(CPUSH4State * s); 137 int cpu_sh4_exec(CPUSH4State * s);
123 int cpu_sh4_signal_handler(int host_signum, void *pinfo, 138 int cpu_sh4_signal_handler(int host_signum, void *pinfo,
124 void *puc); 139 void *puc);
  140 +void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
125 void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, 141 void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
126 uint32_t mem_value); 142 uint32_t mem_value);
127 143
@@ -132,6 +148,7 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr, @@ -132,6 +148,7 @@ void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
132 #define cpu_exec cpu_sh4_exec 148 #define cpu_exec cpu_sh4_exec
133 #define cpu_gen_code cpu_sh4_gen_code 149 #define cpu_gen_code cpu_sh4_gen_code
134 #define cpu_signal_handler cpu_sh4_signal_handler 150 #define cpu_signal_handler cpu_sh4_signal_handler
  151 +#define cpu_list sh4_cpu_list
135 152
136 /* MMU modes definitions */ 153 /* MMU modes definitions */
137 #define MMU_MODE0_SUFFIX _kernel 154 #define MMU_MODE0_SUFFIX _kernel
target-sh4/translate.c
@@ -176,16 +176,75 @@ void cpu_sh4_reset(CPUSH4State * env) @@ -176,16 +176,75 @@ void cpu_sh4_reset(CPUSH4State * env)
176 env->mmucr = 0; 176 env->mmucr = 0;
177 } 177 }
178 178
  179 +typedef struct {
  180 + const unsigned char *name;
  181 + int id;
  182 + uint32_t pvr;
  183 + uint32_t prr;
  184 + uint32_t cvr;
  185 +} sh4_def_t;
  186 +
  187 +static sh4_def_t sh4_defs[] = {
  188 + {
  189 + .name = "SH7750R",
  190 + .id = SH_CPU_SH7750R,
  191 + .pvr = 0x00050000,
  192 + .prr = 0x00000100,
  193 + .cvr = 0x00110000,
  194 + }, {
  195 + .name = "SH7751R",
  196 + .id = SH_CPU_SH7751R,
  197 + .pvr = 0x04050005,
  198 + .prr = 0x00000113,
  199 + .cvr = 0x00110000, /* Neutered caches, should be 0x20480000 */
  200 + },
  201 +};
  202 +
  203 +static const sh4_def_t *cpu_sh4_find_by_name(const unsigned char *name)
  204 +{
  205 + int i;
  206 +
  207 + if (strcasecmp(name, "any") == 0)
  208 + return &sh4_defs[0];
  209 +
  210 + for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++)
  211 + if (strcasecmp(name, sh4_defs[i].name) == 0)
  212 + return &sh4_defs[i];
  213 +
  214 + return NULL;
  215 +}
  216 +
  217 +void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
  218 +{
  219 + int i;
  220 +
  221 + for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++)
  222 + (*cpu_fprintf)(f, "%s\n", sh4_defs[i].name);
  223 +}
  224 +
  225 +static int cpu_sh4_register(CPUSH4State *env, const sh4_def_t *def)
  226 +{
  227 + env->pvr = def->pvr;
  228 + env->prr = def->prr;
  229 + env->cvr = def->cvr;
  230 + env->id = def->id;
  231 +}
  232 +
179 CPUSH4State *cpu_sh4_init(const char *cpu_model) 233 CPUSH4State *cpu_sh4_init(const char *cpu_model)
180 { 234 {
181 CPUSH4State *env; 235 CPUSH4State *env;
  236 + const sh4_def_t *def;
182 237
  238 + def = cpu_sh4_find_by_name(cpu_model);
  239 + if (!def)
  240 + return NULL;
183 env = qemu_mallocz(sizeof(CPUSH4State)); 241 env = qemu_mallocz(sizeof(CPUSH4State));
184 if (!env) 242 if (!env)
185 return NULL; 243 return NULL;
186 cpu_exec_init(env); 244 cpu_exec_init(env);
187 sh4_translate_init(); 245 sh4_translate_init();
188 cpu_sh4_reset(env); 246 cpu_sh4_reset(env);
  247 + cpu_sh4_register(env, def);
189 tlb_flush(env, 1); 248 tlb_flush(env, 1);
190 return env; 249 return env;
191 } 250 }