diff options
author | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-10-14 17:07:21 +0000 |
---|---|---|
committer | blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-10-14 17:07:21 +0000 |
commit | 6f27aba62e90b382d3d8e35e6d72046470c270a8 (patch) | |
tree | 0b705ceb04392e1ea165141c25176e0cb463ee12 /target-sparc/op_helper.c | |
parent | 952a328ff50c323b28fb07658ccbc6604cf26a45 (diff) |
Sparc64 hypervisor mode
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3398 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sparc/op_helper.c')
-rw-r--r-- | target-sparc/op_helper.c | 98 |
1 files changed, 68 insertions, 30 deletions
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index ac88b55d52..28c18b4036 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -789,7 +789,8 @@ void helper_ld_asi(int asi, int size, int sign) { uint64_t ret = 0; - if (asi < 0x80 && (env->pstate & PS_PRIV) == 0) + if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) + || (asi >= 0x30 && asi < 0x80) && !(env->hpstate & HS_PRIV)) raise_exception(TT_PRIV_ACT); switch (asi) { @@ -800,20 +801,38 @@ void helper_ld_asi(int asi, int size, int sign) case 0x88: // Primary LE case 0x8a: // Primary no-fault LE if ((asi & 0x80) && (env->pstate & PS_PRIV)) { - switch(size) { - case 1: - ret = ldub_kernel(T0); - break; - case 2: - ret = lduw_kernel(T0 & ~1); - break; - case 4: - ret = ldl_kernel(T0 & ~3); - break; - default: - case 8: - ret = ldq_kernel(T0 & ~7); - break; + if (env->hpstate & HS_PRIV) { + switch(size) { + case 1: + ret = ldub_hypv(T0); + break; + case 2: + ret = lduw_hypv(T0 & ~1); + break; + case 4: + ret = ldl_hypv(T0 & ~3); + break; + default: + case 8: + ret = ldq_hypv(T0 & ~7); + break; + } + } else { + switch(size) { + case 1: + ret = ldub_kernel(T0); + break; + case 2: + ret = lduw_kernel(T0 & ~1); + break; + case 4: + ret = ldl_kernel(T0 & ~3); + break; + default: + case 8: + ret = ldq_kernel(T0 & ~7); + break; + } } } else { switch(size) { @@ -987,7 +1006,8 @@ void helper_ld_asi(int asi, int size, int sign) void helper_st_asi(int asi, int size) { - if (asi < 0x80 && (env->pstate & PS_PRIV) == 0) + if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) + || (asi >= 0x30 && asi < 0x80) && !(env->hpstate & HS_PRIV)) raise_exception(TT_PRIV_ACT); /* Convert to little endian */ @@ -1022,20 +1042,38 @@ void helper_st_asi(int asi, int size) case 0x80: // Primary case 0x88: // Primary LE if ((asi & 0x80) && (env->pstate & PS_PRIV)) { - switch(size) { - case 1: - stb_kernel(T0, T1); - break; - case 2: - stw_kernel(T0 & ~1, T1); - break; - case 4: - stl_kernel(T0 & ~3, T1); - break; - case 8: - default: - stq_kernel(T0 & ~7, T1); - break; + if (env->hpstate & HS_PRIV) { + switch(size) { + case 1: + stb_hypv(T0, T1); + break; + case 2: + stw_hypv(T0 & ~1, T1); + break; + case 4: + stl_hypv(T0 & ~3, T1); + break; + case 8: + default: + stq_hypv(T0 & ~7, T1); + break; + } + } else { + switch(size) { + case 1: + stb_kernel(T0, T1); + break; + case 2: + stw_kernel(T0 & ~1, T1); + break; + case 4: + stl_kernel(T0 & ~3, T1); + break; + case 8: + default: + stq_kernel(T0 & ~7, T1); + break; + } } } else { switch(size) { |