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 39 struct SH7750State *s;
40 40  
41 41 if (!cpu_model)
42   - cpu_model = "any";
  42 + cpu_model = "SH7751R";
43 43  
44 44 env = cpu_init(cpu_model);
45 45 if (!env) {
... ...
hw/sh7750.c
... ... @@ -249,12 +249,12 @@ static uint32_t sh7750_mem_readl(void *opaque, target_phys_addr_t addr)
249 249 return s->cpu->intevt;
250 250 case SH7750_CCR_A7:
251 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 258 default:
259 259 error_access("long read", addr);
260 260 assert(0);
... ... @@ -529,14 +529,6 @@ static struct intc_group groups_pci[] = {
529 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 533 Memory mapped cache and TLB
542 534 **********************************************************************/
... ... @@ -644,7 +636,6 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
644 636 SH7750State *s;
645 637 int sh7750_io_memory;
646 638 int sh7750_mm_cache_and_tlb; /* memory mapped cache and tlb */
647   - int cpu_model = SH_CPU_SH7751R; /* for now */
648 639  
649 640 s = qemu_mallocz(sizeof(SH7750State));
650 641 s->cpu = cpu;
... ... @@ -664,7 +655,7 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
664 655 _INTC_ARRAY(mask_registers),
665 656 _INTC_ARRAY(prio_registers));
666 657  
667   - sh_intc_register_sources(&s->intc,
  658 + sh_intc_register_sources(&s->intc,
668 659 _INTC_ARRAY(vectors),
669 660 _INTC_ARRAY(groups));
670 661  
... ... @@ -692,20 +683,20 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
692 683 sh_intc_source(&s->intc, TMU2_TUNI),
693 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 688 _INTC_ARRAY(vectors_dma4),
698 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 694 _INTC_ARRAY(vectors_dma8),
704 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 700 _INTC_ARRAY(vectors_tmu34),
710 701 NULL, 0);
711 702 tmu012_init(0x1e100000, 0, s->periph_freq,
... ... @@ -714,14 +705,14 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
714 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 710 _INTC_ARRAY(vectors_pci),
720 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 716 _INTC_ARRAY(vectors_irlm),
726 717 NULL, 0);
727 718 }
... ...
target-sh4/cpu.h
... ... @@ -27,6 +27,15 @@
27 27  
28 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 39 #include "cpu-defs.h"
31 40  
32 41 #include "softfloat.h"
... ... @@ -80,6 +89,8 @@ typedef struct tlb_t {
80 89 #define NB_MMU_MODES 2
81 90  
82 91 typedef struct CPUSH4State {
  92 + int id; /* CPU model */
  93 +
83 94 uint32_t flags; /* general execution flags */
84 95 uint32_t gregs[24]; /* general registers */
85 96 float32 fregs[32]; /* floating point registers */
... ... @@ -112,6 +123,10 @@ typedef struct CPUSH4State {
112 123 uint32_t expevt; /* exception event register */
113 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 130 CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */
116 131 tlb_t itlb[ITLB_SIZE]; /* instruction translation table */
117 132 void *intc_handle;
... ... @@ -122,6 +137,7 @@ CPUSH4State *cpu_sh4_init(const char *cpu_model);
122 137 int cpu_sh4_exec(CPUSH4State * s);
123 138 int cpu_sh4_signal_handler(int host_signum, void *pinfo,
124 139 void *puc);
  140 +void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
125 141 void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
126 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 148 #define cpu_exec cpu_sh4_exec
133 149 #define cpu_gen_code cpu_sh4_gen_code
134 150 #define cpu_signal_handler cpu_sh4_signal_handler
  151 +#define cpu_list sh4_cpu_list
135 152  
136 153 /* MMU modes definitions */
137 154 #define MMU_MODE0_SUFFIX _kernel
... ...
target-sh4/translate.c
... ... @@ -176,16 +176,75 @@ void cpu_sh4_reset(CPUSH4State * env)
176 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 233 CPUSH4State *cpu_sh4_init(const char *cpu_model)
180 234 {
181 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 241 env = qemu_mallocz(sizeof(CPUSH4State));
184 242 if (!env)
185 243 return NULL;
186 244 cpu_exec_init(env);
187 245 sh4_translate_init();
188 246 cpu_sh4_reset(env);
  247 + cpu_sh4_register(env, def);
189 248 tlb_flush(env, 1);
190 249 return env;
191 250 }
... ...