X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/80e1b265f4505149ba256ab6e18be942830072d0..d6a6922f3bebbf95e2d5194a9cb8a21e3d5ddfdd:/target-cris/mmu.c
diff --git a/target-cris/mmu.c b/target-cris/mmu.c
index 9ae398db6d..512e28b481 100644
--- a/target-cris/mmu.c
+++ b/target-cris/mmu.c
@@ -15,28 +15,23 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see .
*/
#ifndef CONFIG_USER_ONLY
-#include
-#include
-#include
-
-#include "config.h"
#include "cpu.h"
#include "mmu.h"
-#include "exec-all.h"
#ifdef DEBUG
#define D(x) x
+#define D_LOG(...) qemu_log(__VA_ARGS__)
#else
-#define D(x)
+#define D(x) do { } while (0)
+#define D_LOG(...) do { } while (0)
#endif
-void cris_mmu_init(CPUState *env)
+void cris_mmu_init(CPUCRISState *env)
{
env->mmu_rand_lfsr = 0xcccc;
}
@@ -54,6 +49,17 @@ static inline unsigned int compute_polynom(unsigned int sr)
return f;
}
+static void cris_mmu_update_rand_lfsr(CPUCRISState *env)
+{
+ unsigned int f;
+
+ /* Update lfsr at every fault. */
+ f = compute_polynom(env->mmu_rand_lfsr);
+ env->mmu_rand_lfsr >>= 1;
+ env->mmu_rand_lfsr |= (f << 15);
+ env->mmu_rand_lfsr &= 0xffff;
+}
+
static inline int cris_mmu_enabled(uint32_t rw_gc_cfg)
{
return (rw_gc_cfg & 12) != 0;
@@ -64,7 +70,7 @@ static inline int cris_mmu_segmented_addr(int seg, uint32_t rw_mm_cfg)
return (1 << seg) & rw_mm_cfg;
}
-static uint32_t cris_mmu_translate_seg(CPUState *env, int seg)
+static uint32_t cris_mmu_translate_seg(CPUCRISState *env, int seg)
{
uint32_t base;
int i;
@@ -100,7 +106,7 @@ static inline void set_field(uint32_t *dst, unsigned int val,
}
#ifdef DEBUG
-static void dump_tlb(CPUState *env, int mmu)
+static void dump_tlb(CPUCRISState *env, int mmu)
{
int set;
int idx;
@@ -121,9 +127,9 @@ static void dump_tlb(CPUState *env, int mmu)
#endif
/* rw 0 = read, 1 = write, 2 = exec. */
-static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
- CPUState *env, uint32_t vaddr,
- int rw, int usermode)
+static int cris_mmu_translate_page(struct cris_mmu_result *res,
+ CPUCRISState *env, uint32_t vaddr,
+ int rw, int usermode, int debug)
{
unsigned int vpage;
unsigned int idx;
@@ -180,9 +186,8 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
tlb_pid = EXTRACT_FIELD(hi, 0, 7);
tlb_g = EXTRACT_FIELD(lo, 4, 4);
- D(fprintf(logfile,
- "TLB[%d][%d][%d] v=%x vpage=%x lo=%x hi=%x\n",
- mmu, set, idx, tlb_vpn, vpage, lo, hi));
+ D_LOG("TLB[%d][%d][%d] v=%x vpage=%x lo=%x hi=%x\n",
+ mmu, set, idx, tlb_vpn, vpage, lo, hi);
if ((tlb_g || (tlb_pid == pid))
&& tlb_vpn == vpage) {
match = 1;
@@ -240,7 +245,7 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
res->prot |= PAGE_READ;
if (tlb_w)
res->prot |= PAGE_WRITE;
- if (tlb_x)
+ if (mmu == 0 && (cfg_x || tlb_x))
res->prot |= PAGE_EXEC;
}
else
@@ -250,15 +255,9 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
set = env->mmu_rand_lfsr & 3;
}
- if (!match) {
- unsigned int f;
+ if (!match && !debug) {
+ cris_mmu_update_rand_lfsr(env);
- /* Update lfsr at every fault. */
- f = compute_polynom(env->mmu_rand_lfsr);
- env->mmu_rand_lfsr >>= 1;
- env->mmu_rand_lfsr |= (f << 15);
- env->mmu_rand_lfsr &= 0xffff;
-
/* Compute index. */
idx = vpage & 15;
@@ -289,7 +288,7 @@ static int cris_mmu_translate_page(struct cris_mmu_result_t *res,
return !match;
}
-void cris_mmu_flush_pid(CPUState *env, uint32_t pid)
+void cris_mmu_flush_pid(CPUCRISState *env, uint32_t pid)
{
target_ulong vaddr;
unsigned int idx;
@@ -314,9 +313,8 @@ void cris_mmu_flush_pid(CPUState *env, uint32_t pid)
if (tlb_v && !tlb_g && (tlb_pid == pid)) {
vaddr = tlb_vpn << TARGET_PAGE_BITS;
- D(fprintf(logfile,
- "flush pid=%x vaddr=%x\n",
- pid, vaddr));
+ D_LOG("flush pid=%x vaddr=%x\n",
+ pid, vaddr);
tlb_flush_page(env, vaddr);
}
}
@@ -324,11 +322,10 @@ void cris_mmu_flush_pid(CPUState *env, uint32_t pid)
}
}
-int cris_mmu_translate(struct cris_mmu_result_t *res,
- CPUState *env, uint32_t vaddr,
- int rw, int mmu_idx)
+int cris_mmu_translate(struct cris_mmu_result *res,
+ CPUCRISState *env, uint32_t vaddr,
+ int rw, int mmu_idx, int debug)
{
- uint32_t phy = vaddr;
int seg;
int miss = 0;
int is_user = mmu_idx == MMU_USER_IDX;
@@ -346,18 +343,18 @@ int cris_mmu_translate(struct cris_mmu_result_t *res,
}
seg = vaddr >> 28;
- if (cris_mmu_segmented_addr(seg, env->sregs[SFR_RW_MM_CFG]))
+ if (!is_user && cris_mmu_segmented_addr(seg, env->sregs[SFR_RW_MM_CFG]))
{
uint32_t base;
miss = 0;
base = cris_mmu_translate_seg(env, seg);
- phy = base | (0x0fffffff & vaddr);
- res->phy = phy;
+ res->phy = base | (0x0fffffff & vaddr);
res->prot = PAGE_BITS;
+ } else {
+ miss = cris_mmu_translate_page(res, env, vaddr, rw,
+ is_user, debug);
}
- else
- miss = cris_mmu_translate_page(res, env, vaddr, rw, is_user);
done:
env->pregs[PR_SRS] = old_srs;
return miss;