[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC] sparc32 MXCC support
From: |
Robert Reif |
Subject: |
[Qemu-devel] [RFC] sparc32 MXCC support |
Date: |
Sat, 13 Oct 2007 16:43:42 -0400 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4.2) Gecko/20040308 |
I'm trying to add SuperSparc II MXCC support and need some feedback.
Is there a better way to read and write physical memory in 64bit chunks?
I'm not sure what I'm doing is portable between 32/64 and big/little endian.
Index: hw/sun4m.c
===================================================================
RCS file: /sources/qemu/qemu/hw/sun4m.c,v
retrieving revision 1.55
diff -p -u -r1.55 sun4m.c
--- hw/sun4m.c 6 Oct 2007 11:28:21 -0000 1.55
+++ hw/sun4m.c 13 Oct 2007 20:35:48 -0000
@@ -327,7 +327,7 @@ static void *sun4m_hw_init(const struct
for(i = 0; i < smp_cpus; i++) {
env = cpu_init();
- cpu_sparc_register(env, def);
+ cpu_sparc_register(env, def, i);
envs[i] = env;
if (i == 0) {
qemu_register_reset(main_cpu_reset, env);
Index: linux-user/main.c
===================================================================
RCS file: /sources/qemu/qemu/linux-user/main.c,v
retrieving revision 1.132
diff -p -u -r1.132 main.c
--- linux-user/main.c 12 Oct 2007 06:47:46 -0000 1.132
+++ linux-user/main.c 13 Oct 2007 20:35:49 -0000
@@ -2139,7 +2139,7 @@ int main(int argc, char **argv)
fprintf(stderr, "Unable to find Sparc CPU definition\n");
exit(1);
}
- cpu_sparc_register(env, def);
+ cpu_sparc_register(env, def, 0);
env->pc = regs->pc;
env->npc = regs->npc;
env->y = regs->y;
Index: target-sparc/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/cpu.h,v
retrieving revision 1.53
diff -p -u -r1.53 cpu.h
--- target-sparc/cpu.h 12 Oct 2007 06:47:46 -0000 1.53
+++ target-sparc/cpu.h 13 Oct 2007 20:35:49 -0000
@@ -210,6 +210,8 @@ typedef struct CPUSPARCState {
uint64_t dtlb_tte[64];
#else
uint32_t mmuregs[16];
+ uint64_t mxccdata[4];
+ uint64_t mxccregs[8];
#endif
/* temporary float registers */
float32 ft0, ft1;
@@ -266,7 +268,7 @@ int cpu_sparc_close(CPUSPARCState *s);
int sparc_find_by_name (const unsigned char *name, const sparc_def_t **def);
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
...));
-int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def);
+int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def, int cpu);
#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \
(env->psref? PSR_EF : 0) | \
Index: target-sparc/op_helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v
retrieving revision 1.41
diff -p -u -r1.41 op_helper.c
--- target-sparc/op_helper.c 1 Oct 2007 17:07:58 -0000 1.41
+++ target-sparc/op_helper.c 13 Oct 2007 20:35:51 -0000
@@ -2,6 +2,7 @@
//#define DEBUG_PCALL
//#define DEBUG_MMU
+#define DEBUG_MXCC
//#define DEBUG_UNALIGNED
//#define DEBUG_UNASSIGNED
@@ -139,12 +140,68 @@ GEN_FCMP(fcmped_fcc3, float64, DT0, DT1,
#ifndef TARGET_SPARC64
#ifndef CONFIG_USER_ONLY
+
+#ifdef DEBUG_MXCC
+void dump_mxcc(CPUState *env)
+{
+ printf("mxccdata: %016llx %016llx %016llx %016llx\n",
+ env->mxccdata[0], env->mxccdata[1], env->mxccdata[2],
env->mxccdata[3]);
+ printf("mxccregs: %016llx %016llx %016llx %016llx\n"
+ " %016llx %016llx %016llx %016llx\n",
+ env->mxccregs[0], env->mxccregs[1], env->mxccregs[2], env->mxccregs[3],
+ env->mxccregs[4], env->mxccregs[5], env->mxccregs[6],
env->mxccregs[7]);
+}
+#endif
+
void helper_ld_asi(int asi, int size, int sign)
{
uint32_t ret = 0;
+#ifdef DEBUG_MXCC
+ uint32_t last_T0 = T0;
+#endif
switch (asi) {
case 2: /* SuperSparc MXCC registers */
+ switch (T0) {
+ case 0x01c00a00: /* MXCC control register */
+ if (size == 8) {
+ ret = env->mxccregs[3];
+ T0 = env->mxccregs[3] >> 32;
+ }
+#ifdef DEBUG_MXCC
+ else
+ printf("ERROR: helper_ld_asi(asi = %d, size = %d, sign = %d)
T0 = %08x: unsupported size\n", asi, size, sign, T0);
+#endif
+ break;
+ case 0x01c00a04: /* MXCC control register */
+ if (size == 4)
+ ret = env->mxccregs[3];
+#ifdef DEBUG_MXCC
+ else
+ printf("ERROR: helper_ld_asi(asi = %d, size = %d, sign = %d)
T0 = %08x: unsupported size\n", asi, size, sign, T0);
+#endif
+ break;
+ case 0x01c00f00: /* MBus port address register */
+ if (size == 8) {
+ ret = env->mxccregs[7];
+ T0 = env->mxccregs[7] >> 32;
+ }
+#ifdef DEBUG_MXCC
+ else
+ printf("ERROR: helper_ld_asi(asi = %d, size = %d, sign = %d)
T0 = %08x: unsupported size\n", asi, size, sign, T0);
+#endif
+ break;
+ default:
+#ifdef DEBUG_MXCC
+ printf("ERROR: helper_ld_asi(asi = %d, size = %d, sign = %d) T0 =
%08x: unsupported address\n", asi, size, sign, T0);
+#endif
+ ret = 0;
+ break;
+ }
+#ifdef DEBUG_MXCC
+ printf("helper_ld_asi(asi = %d, size = %d, sign = %d) T0 = %08x: ret =
%08x, T0 = %08x\n", asi, size, sign, last_T0, ret, T0);
+ dump_mxcc(env);
+#endif
break;
case 3: /* MMU probe */
{
@@ -302,6 +359,116 @@ void helper_st_asi(int asi, int size)
{
switch(asi) {
case 2: /* SuperSparc MXCC registers */
+ switch (T0) {
+ case 0x01c00000: /* MXCC stream data register 0 */
+ if (size == 8)
+ env->mxccdata[0] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+ else
+ printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x,
T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+ break;
+ case 0x01c00008: /* MXCC stream data register 1 */
+ if (size == 8)
+ env->mxccdata[1] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+ else
+ printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x,
T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+ break;
+ case 0x01c00010: /* MXCC stream data register 2 */
+ if (size == 8)
+ env->mxccdata[2] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+ else
+ printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x,
T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+ break;
+ case 0x01c00018: /* MXCC stream data register 3 */
+ if (size == 8)
+ env->mxccdata[3] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+ else
+ printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x,
T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+ break;
+ case 0x01c00100: /* MXCC stream source */
+ if (size == 8)
+ env->mxccregs[0] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+ else
+ printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x,
T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+ env->mxccdata[0] =
(uint64_t)ldl_phys((target_phys_addr_t)((env->mxccregs[0] + 4) &
0xffffffffULL)) +
+ ((uint64_t)(ldl_phys((target_phys_addr_t)((env->mxccregs[0] +
0) & 0xffffffffULL))) << 32);
+ env->mxccdata[1] =
(uint64_t)ldl_phys((target_phys_addr_t)((env->mxccregs[0] + 12) &
0xffffffffULL)) +
+ ((uint64_t)(ldl_phys((target_phys_addr_t)((env->mxccregs[0] +
8) & 0xffffffffULL))) << 32);
+ env->mxccdata[2] =
(uint64_t)ldl_phys((target_phys_addr_t)((env->mxccregs[0] + 20) &
0xffffffffULL)) +
+ ((uint64_t)(ldl_phys((target_phys_addr_t)((env->mxccregs[0] +
16) & 0xffffffffULL))) << 32);
+ env->mxccdata[3] =
(uint64_t)ldl_phys((target_phys_addr_t)((env->mxccregs[0] + 28) &
0xffffffffULL)) +
+ ((uint64_t)(ldl_phys((target_phys_addr_t)((env->mxccregs[0] +
24) & 0xffffffffULL))) << 32);
+ break;
+ case 0x01c00200: /* MXCC stream destination */
+ if (size == 8)
+ env->mxccregs[1] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+ else
+ printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x,
T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+ stl_phys((target_phys_addr_t)((env->mxccregs[1] + 0) &
0xffffffffULL), env->mxccdata[0] >> 32);
+ stl_phys((target_phys_addr_t)((env->mxccregs[1] + 4) &
0xffffffffULL), env->mxccdata[0]);
+ stl_phys((target_phys_addr_t)((env->mxccregs[1] + 8) &
0xffffffffULL), env->mxccdata[1] >> 32);
+ stl_phys((target_phys_addr_t)((env->mxccregs[1] + 12) &
0xffffffffULL), env->mxccdata[1]);
+ stl_phys((target_phys_addr_t)((env->mxccregs[1] + 16) &
0xffffffffULL), env->mxccdata[2] >> 32);
+ stl_phys((target_phys_addr_t)((env->mxccregs[1] + 20) &
0xffffffffULL), env->mxccdata[2]);
+ stl_phys((target_phys_addr_t)((env->mxccregs[1] + 24) &
0xffffffffULL), env->mxccdata[3] >> 32);
+ stl_phys((target_phys_addr_t)((env->mxccregs[1] + 28) &
0xffffffffULL), env->mxccdata[3]);
+ break;
+ case 0x01c00a00: /* MXCC control register */
+ if (size == 8)
+ env->mxccregs[3] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+ else
+ printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x,
T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+ break;
+ case 0x01c00a04: /* MXCC control register */
+ if (size == 4)
+ env->mxccregs[3] = (env->mxccregs[0xa] & 0xffffffff00000000) |
T1;
+#ifdef DEBUG_MXCC
+ else
+ printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x,
T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+ break;
+ case 0x01c00e00: /* MXCC error register */
+ if (size == 8)
+ env->mxccregs[6] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+ else
+ printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x,
T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+ if (env->mxccregs[6] == 0xffffffffffffffffULL) {
+ // this is probably a reset
+ }
+ break;
+ case 0x01c00f00: /* MBus port address register */
+ if (size == 8)
+ env->mxccregs[7] = ((uint64_t)T1 << 32) | T2;
+#ifdef DEBUG_MXCC
+ else
+ printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x,
T1 = %08x: unsupported size\n", asi, size, T0, T1);
+#endif
+ break;
+ default:
+#ifdef DEBUG_MXCC
+ printf("ERROR: helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 =
%08x: unsupported address\n", asi, size, T0, T1);
+#endif
+ break;
+ }
+#ifdef DEBUG_MXCC
+ printf("helper_st_asi(asi = %d, size = %d) T0 = %08x, T1 = %08x\n",
asi, size, T0, T1);
+ dump_mxcc(env);
+#endif
break;
case 3: /* MMU flush */
{
Index: target-sparc/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-sparc/translate.c,v
retrieving revision 1.74
diff -p -u -r1.74 translate.c
--- target-sparc/translate.c 10 Oct 2007 19:11:54 -0000 1.74
+++ target-sparc/translate.c 13 Oct 2007 20:35:53 -0000
@@ -3618,12 +3618,13 @@ void sparc_cpu_list (FILE *f, int (*cpu_
}
}
-int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def)
+int cpu_sparc_register (CPUSPARCState *env, const sparc_def_t *def, int cpu)
{
env->version = def->iu_version;
env->fsr = def->fpu_version;
#if !defined(TARGET_SPARC64)
env->mmuregs[0] |= def->mmu_version;
+ env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
#endif
return 0;
}
- [Qemu-devel] [RFC] sparc32 MXCC support,
Robert Reif <=