Skip to content

Commit

Permalink
Merge pull request #6 from yongbok/p5600-mips32r5-PRIP3
Browse files Browse the repository at this point in the history
MAAR and HTW CP0 registers
  • Loading branch information
yongbok committed Sep 12, 2014
2 parents 8f5a2c1 + f10f031 commit 8eaa58c
Show file tree
Hide file tree
Showing 6 changed files with 260 additions and 2 deletions.
9 changes: 9 additions & 0 deletions target-mips/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ typedef struct mips_def_t mips_def_t;
#define MIPS_TC_MAX 5
#define MIPS_FPU_MAX 1
#define MIPS_DSP_ACC 4
#define MIPS_MAAR_MAX 16 /* Must be an even number. */

typedef struct TCState TCState;
struct TCState {
Expand Down Expand Up @@ -237,7 +238,11 @@ struct CPUMIPSState {
int32_t CP0_PageGrain_rw_bitmask;
int32_t CP0_PageGrain;
#define CP0PG_ELPA 29
target_ulong CP0_PWBase;
target_ulong CP0_PWField;
target_ulong CP0_PWSize;
int32_t CP0_Wired;
int32_t CP0_PWCtl;
int32_t CP0_SRSConf0_rw_bitmask;
int32_t CP0_SRSConf0;
#define CP0SRSC0_M 31
Expand Down Expand Up @@ -368,6 +373,7 @@ struct CPUMIPSState {
#define CP0C2_SA 0
int32_t CP0_Config3;
#define CP0C3_M 31
#define CP0C3_PW 24
#define CP0C3_ISA_ON_EXC 16
#define CP0C3_DSPP 10
#define CP0C3_LPA 7
Expand All @@ -388,10 +394,13 @@ struct CPUMIPSState {
#define CP0C5_EVA 28
#define CP0C5_MSAEn 27
#define CP0C5_MVH 5
#define CP0C5_MRP 3
#define CP0C5_UFR 2
#define CP0C5_NFExists 0
int32_t CP0_Config6;
int32_t CP0_Config7;
uint64_t CP0_MAAR[MIPS_MAAR_MAX];
int32_t CP0_MAARI;
/* XXX: Maybe make LLAddr per-TC? */
uint64_t lladdr;
target_ulong llval;
Expand Down
9 changes: 9 additions & 0 deletions target-mips/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ DEF_HELPER_1(mftc0_epc, tl, env)
DEF_HELPER_1(mftc0_ebase, tl, env)
DEF_HELPER_2(mftc0_configx, tl, env, tl)
DEF_HELPER_1(mfc0_lladdr, tl, env)
DEF_HELPER_1(mfc0_maar, tl, env)
DEF_HELPER_1(mfhc0_maar, tl, env)
DEF_HELPER_2(mfc0_watchlo, tl, env, i32)
DEF_HELPER_2(mfc0_watchhi, tl, env, i32)
DEF_HELPER_1(mfc0_debug, tl, env)
Expand All @@ -82,6 +84,7 @@ DEF_HELPER_1(dmfc0_tccontext, tl, env)
DEF_HELPER_1(dmfc0_tcschedule, tl, env)
DEF_HELPER_1(dmfc0_tcschefback, tl, env)
DEF_HELPER_1(dmfc0_lladdr, tl, env)
DEF_HELPER_1(dmfc0_maar, tl, env)
DEF_HELPER_2(dmfc0_watchlo, tl, env, i32)
#endif /* TARGET_MIPS64 */

Expand Down Expand Up @@ -113,12 +116,15 @@ DEF_HELPER_2(mtc0_entrylo1, void, env, tl)
DEF_HELPER_2(mtc0_context, void, env, tl)
DEF_HELPER_2(mtc0_pagemask, void, env, tl)
DEF_HELPER_2(mtc0_pagegrain, void, env, tl)
DEF_HELPER_2(mtc0_pwfield, void, env, tl)
DEF_HELPER_2(mtc0_pwsize, void, env, tl)
DEF_HELPER_2(mtc0_wired, void, env, tl)
DEF_HELPER_2(mtc0_srsconf0, void, env, tl)
DEF_HELPER_2(mtc0_srsconf1, void, env, tl)
DEF_HELPER_2(mtc0_srsconf2, void, env, tl)
DEF_HELPER_2(mtc0_srsconf3, void, env, tl)
DEF_HELPER_2(mtc0_srsconf4, void, env, tl)
DEF_HELPER_2(mtc0_pwctl, void, env, tl)
DEF_HELPER_2(mtc0_hwrena, void, env, tl)
DEF_HELPER_2(mtc0_count, void, env, tl)
DEF_HELPER_2(mtc0_entryhi, void, env, tl)
Expand All @@ -137,6 +143,9 @@ DEF_HELPER_2(mtc0_config2, void, env, tl)
DEF_HELPER_2(mtc0_config4, void, env, tl)
DEF_HELPER_2(mtc0_config5, void, env, tl)
DEF_HELPER_2(mtc0_lladdr, void, env, tl)
DEF_HELPER_2(mtc0_maar, void, env, tl)
DEF_HELPER_2(mthc0_maar, void, env, tl)
DEF_HELPER_2(mtc0_maari, void, env, tl)
DEF_HELPER_3(mtc0_watchlo, void, env, tl, i32)
DEF_HELPER_3(mtc0_watchhi, void, env, tl, i32)
DEF_HELPER_2(mtc0_xcontext, void, env, tl)
Expand Down
16 changes: 16 additions & 0 deletions target-mips/machine.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,11 @@ void cpu_save(QEMUFile *f, void *opaque)
qemu_put_betls(f, &env->CP0_Context);
qemu_put_sbe32s(f, &env->CP0_PageMask);
qemu_put_sbe32s(f, &env->CP0_PageGrain);
qemu_put_betls(f, &env->CP0_PWBase);
qemu_put_betls(f, &env->CP0_PWField);
qemu_put_betls(f, &env->CP0_PWSize);
qemu_put_sbe32s(f, &env->CP0_Wired);
qemu_put_sbe32s(f, &env->CP0_PWCtl);
qemu_put_sbe32s(f, &env->CP0_SRSConf0);
qemu_put_sbe32s(f, &env->CP0_SRSConf1);
qemu_put_sbe32s(f, &env->CP0_SRSConf2);
Expand All @@ -127,6 +131,10 @@ void cpu_save(QEMUFile *f, void *opaque)
qemu_put_sbe32s(f, &env->CP0_Config3);
qemu_put_sbe32s(f, &env->CP0_Config6);
qemu_put_sbe32s(f, &env->CP0_Config7);
for (i = 0; i < MIPS_MAAR_MAX; i++) {
qemu_put_be64s(f, &env->CP0_MAAR[i]);
}
qemu_put_sbe32s(f, &env->CP0_MAARI);
qemu_put_be64s(f, &env->lladdr);
for(i = 0; i < 8; i++)
qemu_put_betls(f, &env->CP0_WatchLo[i]);
Expand Down Expand Up @@ -255,7 +263,11 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
qemu_get_betls(f, &env->CP0_Context);
qemu_get_sbe32s(f, &env->CP0_PageMask);
qemu_get_sbe32s(f, &env->CP0_PageGrain);
qemu_get_betls(f, &env->CP0_PWBase);
qemu_get_betls(f, &env->CP0_PWField);
qemu_get_betls(f, &env->CP0_PWSize);
qemu_get_sbe32s(f, &env->CP0_Wired);
qemu_get_sbe32s(f, &env->CP0_PWCtl);
qemu_get_sbe32s(f, &env->CP0_SRSConf0);
qemu_get_sbe32s(f, &env->CP0_SRSConf1);
qemu_get_sbe32s(f, &env->CP0_SRSConf2);
Expand All @@ -280,6 +292,10 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
qemu_get_sbe32s(f, &env->CP0_Config3);
qemu_get_sbe32s(f, &env->CP0_Config6);
qemu_get_sbe32s(f, &env->CP0_Config7);
for (i = 0; i < MIPS_MAAR_MAX; i++) {
qemu_get_be64s(f, &env->CP0_MAAR[i]);
}
qemu_get_sbe32s(f, &env->CP0_MAARI);
qemu_get_be64s(f, &env->lladdr);
for(i = 0; i < 8; i++)
qemu_get_betls(f, &env->CP0_WatchLo[i]);
Expand Down
112 changes: 112 additions & 0 deletions target-mips/op_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,31 @@ target_ulong helper_mfc0_lladdr(CPUMIPSState *env)
return (int32_t)(env->lladdr >> env->CP0_LLAddr_shift);
}

target_ulong helper_mfc0_maar(CPUMIPSState *env)
{
if (!(env->CP0_Config5 & (1 << CP0C5_MRP))) {
return 0;
}
if (env->CP0_MAARI < MIPS_MAAR_MAX) {
return (int32_t) env->CP0_MAAR[env->CP0_MAARI];
}
return 0;
}

target_ulong helper_mfhc0_maar(CPUMIPSState *env)
{
if (!(env->CP0_Config5 & (1 << CP0C5_MRP))) {
return 0;
}

if (env->CP0_MAARI < MIPS_MAAR_MAX) {
if (env->CP0_PageGrain & (1 << CP0PG_ELPA)) {
return env->CP0_MAAR[env->CP0_MAARI] >> 32;
}
}
return 0;
}

target_ulong helper_mfc0_watchlo(CPUMIPSState *env, uint32_t sel)
{
return (int32_t)env->CP0_WatchLo[sel];
Expand Down Expand Up @@ -932,6 +957,17 @@ target_ulong helper_dmfc0_lladdr(CPUMIPSState *env)
return env->lladdr >> env->CP0_LLAddr_shift;
}

target_ulong helper_dmfc0_maar(CPUMIPSState *env)
{
if (!(env->CP0_Config5 & (1 << CP0C5_MRP))) {
return 0;
}
if (env->CP0_MAARI < MIPS_MAAR_MAX) {
return env->CP0_MAAR[env->CP0_MAARI];
}
return 0;
}

target_ulong helper_dmfc0_watchlo(CPUMIPSState *env, uint32_t sel)
{
return env->CP0_WatchLo[sel];
Expand Down Expand Up @@ -1286,6 +1322,28 @@ void helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1)
#endif
}

void helper_mtc0_pwfield(CPUMIPSState *env, target_ulong arg1)
{
if (env->CP0_Config3 & (1 << CP0C3_PW)) {
#ifdef TARGET_MIPS64
env->CP0_PWField = arg1 & 0x3F3FFFFFFFULL;
#else
env->CP0_PWField = arg1 & 0x3FFFFFFF;
#endif
}
}

void helper_mtc0_pwsize(CPUMIPSState *env, target_ulong arg1)
{
if (env->CP0_Config3 & (1 << CP0C3_PW)) {
#ifdef TARGET_MIPS64
env->CP0_PWSize = arg1 & 0x3F7FFFFFFFULL;
#else
env->CP0_PWSize = arg1 & 0x3FFFFFFF;
#endif
}
}

void helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1)
{
env->CP0_Wired = arg1 % env->tlb->nb_tlb;
Expand Down Expand Up @@ -1316,6 +1374,18 @@ void helper_mtc0_srsconf4(CPUMIPSState *env, target_ulong arg1)
env->CP0_SRSConf4 |= arg1 & env->CP0_SRSConf4_rw_bitmask;
}

void helper_mtc0_pwctl(CPUMIPSState *env, target_ulong arg1)
{
if (env->CP0_Config3 & (1 << CP0C3_PW)) {
/* PWEn = 0. Hardware page table walking is not implemented. */
#ifdef TARGET_MIPS64
env->CP0_PWCtl = (env->CP0_PWCtl & 0x000000C0) | (arg1 & 0x5C00003F);
#else
env->CP0_PWCtl = (env->CP0_PWCtl & 0x000000C0) | (arg1 & 0x0000003F);
#endif
}
}

void helper_mtc0_hwrena(CPUMIPSState *env, target_ulong arg1)
{
env->CP0_HWREna = arg1 & 0x0000000F;
Expand Down Expand Up @@ -1530,6 +1600,48 @@ void helper_mtc0_lladdr(CPUMIPSState *env, target_ulong arg1)
env->lladdr = (env->lladdr & ~mask) | (arg1 & mask);
}

void helper_mtc0_maar(CPUMIPSState *env, target_ulong arg1)
{
uint64_t mask = ((env->PAMask >> 4) & ~0xFFFull) | 0x3;

if (!(env->CP0_Config5 & (1 << CP0C5_MRP))) {
return;
}
if (env->CP0_MAARI < MIPS_MAAR_MAX) {
env->CP0_MAAR[env->CP0_MAARI] = arg1 & mask;
}
}

void helper_mthc0_maar(CPUMIPSState *env, target_ulong arg1)
{
if (!(env->CP0_Config5 & (1 << CP0C5_MRP))) {
return;
}

if (env->CP0_MAARI < MIPS_MAAR_MAX) {
env->CP0_MAAR[env->CP0_MAARI] = (arg1 & (env->PAMask >> 36)) |
(env->CP0_MAAR[env->CP0_MAARI] & 0x00000000ffffffffULL);
}
}

void helper_mtc0_maari(CPUMIPSState *env, target_ulong arg1)
{
int index = arg1 & 0x3f;
if (!(env->CP0_Config5 & (1 << CP0C5_MRP))) {
return;
}
if (index == 0x3f) {
/* Software may write all ones to INDEX to determine the
maximum value supported. */
env->CP0_MAARI = MIPS_MAAR_MAX - 1;
} else if (index < MIPS_MAAR_MAX) {
env->CP0_MAARI = index;
}
/* Other than the all ones, if the
value written is not supported, then INDEX is unchanged
from its previous value. */
}

void helper_mtc0_watchlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
{
/* Watch exceptions for instructions, data loads, data stores
Expand Down
Loading

0 comments on commit 8eaa58c

Please sign in to comment.