qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] target-sh4: Support CPU versioning.
@ 2007-12-03  8:40 Paul Mundt
  2007-12-05 14:32 ` [Qemu-devel] " Magnus Damm
  0 siblings, 1 reply; 2+ messages in thread
From: Paul Mundt @ 2007-12-03  8:40 UTC (permalink / raw)
  To: qemu-devel

Trivial patch adding CPU listing and the ability to do per-subtype
CVR/PVR/PRR values. The existing semantics aren't changed, as only
the SH7751R values are stubbed in for the moment, but the kernel is at
least able to get the cache probing correct.

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>

---

 hw/sh7750.c            |   42 ++++++++++++++++-------------------------
 target-sh4/cpu.h       |   17 ++++++++++++++++
 target-sh4/translate.c |   50 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 84 insertions(+), 25 deletions(-)

Index: hw/sh7750.c
===================================================================
RCS file: /sources/qemu/qemu/hw/sh7750.c,v
retrieving revision 1.12
diff -u -p -r1.12 sh7750.c
--- hw/sh7750.c	2 Dec 2007 06:18:24 -0000	1.12
+++ hw/sh7750.c	3 Dec 2007 08:34:08 -0000
@@ -247,12 +247,12 @@ static uint32_t sh7750_mem_readl(void *o
 	return s->cpu->intevt;
     case SH7750_CCR_A7:
 	return s->ccr;
-    case 0x1f000030:		/* Processor version PVR */
-	return 0x00050000;	/* SH7750R */
-    case 0x1f000040:		/* Processor version CVR */
-	return 0x00110000;	/* Minimum caches */
-    case 0x1f000044:		/* Processor version PRR */
-	return 0x00000100;	/* SH7750R */
+    case 0x1f000030:		/* Processor version */
+	return s->cpu->pvr;
+    case 0x1f000040:		/* Cache version */
+	return s->cpu->cvr;
+    case 0x1f000044:		/* Processor revision */
+	return s->cpu->prr;
     default:
 	error_access("long read", addr);
 	assert(0);
@@ -521,19 +521,11 @@ static struct intc_group groups_pci[] = 
 		   PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3),
 };
 
-#define SH_CPU_SH7750  (1 << 0)
-#define SH_CPU_SH7750S (1 << 1)
-#define SH_CPU_SH7750R (1 << 2)
-#define SH_CPU_SH7751  (1 << 3)
-#define SH_CPU_SH7751R (1 << 4)
-#define SH_CPU_SH7750_ALL (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7750R)
-#define SH_CPU_SH7751_ALL (SH_CPU_SH7751 | SH_CPU_SH7751R)
 
 SH7750State *sh7750_init(CPUSH4State * cpu)
 {
     SH7750State *s;
     int sh7750_io_memory;
-    int cpu_model = SH_CPU_SH7751R; /* for now */
 
     s = qemu_mallocz(sizeof(SH7750State));
     s->cpu = cpu;
@@ -547,7 +539,7 @@ SH7750State *sh7750_init(CPUSH4State * c
 		 _INTC_ARRAY(mask_registers),
 		 _INTC_ARRAY(prio_registers));
 
-    sh_intc_register_sources(&s->intc, 
+    sh_intc_register_sources(&s->intc,
 			     _INTC_ARRAY(vectors),
 			     _INTC_ARRAY(groups));
 
@@ -562,33 +554,33 @@ SH7750State *sh7750_init(CPUSH4State * c
 		s->periph_freq);
 
 
-    if (cpu_model & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) {
-        sh_intc_register_sources(&s->intc, 
+    if (cpu->id & (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7751)) {
+        sh_intc_register_sources(&s->intc,
 				 _INTC_ARRAY(vectors_dma4),
 				 _INTC_ARRAY(groups_dma4));
     }
 
-    if (cpu_model & (SH_CPU_SH7750R | SH_CPU_SH7751R)) {
-        sh_intc_register_sources(&s->intc, 
+    if (cpu->id & (SH_CPU_SH7750R | SH_CPU_SH7751R)) {
+        sh_intc_register_sources(&s->intc,
 				 _INTC_ARRAY(vectors_dma8),
 				 _INTC_ARRAY(groups_dma8));
     }
 
-    if (cpu_model & (SH_CPU_SH7750R | SH_CPU_SH7751 | SH_CPU_SH7751R)) {
-        sh_intc_register_sources(&s->intc, 
+    if (cpu->id & (SH_CPU_SH7750R | SH_CPU_SH7751 | SH_CPU_SH7751R)) {
+        sh_intc_register_sources(&s->intc,
 				 _INTC_ARRAY(vectors_tmu34),
 				 NULL, 0);
         tmu012_init(0x1e100000, 0, s->periph_freq);
     }
 
-    if (cpu_model & (SH_CPU_SH7751_ALL)) {
-        sh_intc_register_sources(&s->intc, 
+    if (cpu->id & (SH_CPU_SH7751_ALL)) {
+        sh_intc_register_sources(&s->intc,
 				 _INTC_ARRAY(vectors_pci),
 				 _INTC_ARRAY(groups_pci));
     }
 
-    if (cpu_model & (SH_CPU_SH7750S | SH_CPU_SH7750R | SH_CPU_SH7751_ALL)) {
-        sh_intc_register_sources(&s->intc, 
+    if (cpu->id & (SH_CPU_SH7750S | SH_CPU_SH7750R | SH_CPU_SH7751_ALL)) {
+        sh_intc_register_sources(&s->intc,
 				 _INTC_ARRAY(vectors_irlm),
 				 NULL, 0);
     }
Index: target-sh4/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/cpu.h,v
retrieving revision 1.14
diff -u -p -r1.14 cpu.h
--- target-sh4/cpu.h	2 Dec 2007 06:18:24 -0000	1.14
+++ target-sh4/cpu.h	3 Dec 2007 08:34:09 -0000
@@ -27,6 +27,15 @@
 
 #define ELF_MACHINE	EM_SH
 
+/* CPU Subtypes */
+#define SH_CPU_SH7750  (1 << 0)
+#define SH_CPU_SH7750S (1 << 1)
+#define SH_CPU_SH7750R (1 << 2)
+#define SH_CPU_SH7751  (1 << 3)
+#define SH_CPU_SH7751R (1 << 4)
+#define SH_CPU_SH7750_ALL (SH_CPU_SH7750 | SH_CPU_SH7750S | SH_CPU_SH7750R)
+#define SH_CPU_SH7751_ALL (SH_CPU_SH7751 | SH_CPU_SH7751R)
+
 #include "cpu-defs.h"
 
 #include "softfloat.h"
@@ -80,6 +89,8 @@ typedef struct tlb_t {
 #define NB_MMU_MODES 2
 
 typedef struct CPUSH4State {
+    int id;			/* CPU model */
+
     uint32_t flags;		/* general execution flags */
     uint32_t gregs[24];		/* general registers */
     float32 fregs[32];		/* floating point registers */
@@ -114,6 +125,10 @@ typedef struct CPUSH4State {
     uint32_t expevt;		/* exception event register */
     uint32_t intevt;		/* interrupt event register */
 
+    uint32_t pvr;		/* Processor Version Register */
+    uint32_t prr;		/* Processor Revision Register */
+    uint32_t cvr;		/* Cache Version Register */
+
     jmp_buf jmp_env;
     int user_mode_only;
     int interrupt_request;
@@ -128,6 +143,7 @@ CPUSH4State *cpu_sh4_init(const char *cp
 int cpu_sh4_exec(CPUSH4State * s);
 int cpu_sh4_signal_handler(int host_signum, void *pinfo,
                            void *puc);
+void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
 
 #include "softfloat.h"
 
@@ -136,6 +152,7 @@ int cpu_sh4_signal_handler(int host_sign
 #define cpu_exec cpu_sh4_exec
 #define cpu_gen_code cpu_sh4_gen_code
 #define cpu_signal_handler cpu_sh4_signal_handler
+#define cpu_list sh4_cpu_list
 
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _kernel
Index: target-sh4/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-sh4/translate.c,v
retrieving revision 1.21
diff -u -p -r1.21 translate.c
--- target-sh4/translate.c	2 Dec 2007 06:10:04 -0000	1.21
+++ target-sh4/translate.c	3 Dec 2007 08:34:09 -0000
@@ -151,15 +151,65 @@ void cpu_sh4_reset(CPUSH4State * env)
     env->mmucr = 0;
 }
 
+typedef struct {
+	const unsigned char *name;
+	int id;
+	uint32_t pvr;
+	uint32_t prr;
+	uint32_t cvr;
+} sh4_def_t;
+
+static sh4_def_t sh4_defs[] = {
+    {
+	.name = "SH7751R",
+	.id = SH_CPU_SH7751R,
+	.pvr = 0x04050005,
+	.prr = 0x00000113,
+	.cvr = 0x20480000,
+    },
+};
+
+static const sh4_def_t *cpu_sh4_find_by_name(const unsigned char *name)
+{
+    int i;
+
+    for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++)
+	if (strcasecmp(name, sh4_defs[i].name) == 0)
+	    return &sh4_defs[i];
+
+    return NULL;
+}
+
+void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+{
+    int i;
+
+    for (i = 0; i < sizeof(sh4_defs) / sizeof(*sh4_defs); i++)
+	(*cpu_fprintf)(f, "%s\n", sh4_defs[i].name);
+}
+
+static int cpu_sh4_register(CPUSH4State *env, const sh4_def_t *def)
+{
+    env->pvr = def->pvr;
+    env->prr = def->prr;
+    env->cvr = def->cvr;
+    env->id = def->id;
+}
+
 CPUSH4State *cpu_sh4_init(const char *cpu_model)
 {
     CPUSH4State *env;
+    const sh4_def_t *def;
 
+    def = cpu_sh4_find_by_name(cpu_model);
+    if (!def)
+	return NULL;
     env = qemu_mallocz(sizeof(CPUSH4State));
     if (!env)
 	return NULL;
     cpu_exec_init(env);
     cpu_sh4_reset(env);
+    cpu_sh4_register(env, def);
     tlb_flush(env, 1);
     return env;
 }

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [Qemu-devel] Re: [PATCH] target-sh4: Support CPU versioning.
  2007-12-03  8:40 [Qemu-devel] [PATCH] target-sh4: Support CPU versioning Paul Mundt
@ 2007-12-05 14:32 ` Magnus Damm
  0 siblings, 0 replies; 2+ messages in thread
From: Magnus Damm @ 2007-12-05 14:32 UTC (permalink / raw)
  To: Paul Mundt; +Cc: qemu-devel

On Dec 3, 2007 5:40 PM, Paul Mundt <lethal@linux-sh.org> wrote:
> Trivial patch adding CPU listing and the ability to do per-subtype
> CVR/PVR/PRR values. The existing semantics aren't changed, as only
> the SH7751R values are stubbed in for the moment, but the kernel is at
> least able to get the cache probing correct.
>
> 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>

Thank you for implementing this. Good idea. There is however a small
glitch introduced with this patch - both the r2d and the shix board
can pass "any" as cpu string when calling cpu_init(). This results in
a "Unable to find CPU definition" error unless the cpu type is
specified on the command line using the -cpu option. Maybe a better
solution would be to pass "SH7751R" from r2d and "SH7750" from shix by
default?

/ magnus

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2007-12-05 14:32 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-03  8:40 [Qemu-devel] [PATCH] target-sh4: Support CPU versioning Paul Mundt
2007-12-05 14:32 ` [Qemu-devel] " Magnus Damm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).