[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] qemu/target-mips helper.c cpu.h
From: |
Fabrice Bellard |
Subject: |
[Qemu-devel] qemu/target-mips helper.c cpu.h |
Date: |
Wed, 14 Jun 2006 17:15:19 +0000 |
CVSROOT: /sources/qemu
Module name: qemu
Changes by: Fabrice Bellard <bellard> 06/06/14 17:15:19
Modified files:
target-mips : helper.c cpu.h
Log message:
use constants for TLB handling (Thiemo Seufer)
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemu/target-mips/helper.c?cvsroot=qemu&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/qemu/target-mips/cpu.h?cvsroot=qemu&r1=1.8&r2=1.9
Patches:
Index: helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-mips/helper.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- helper.c 22 May 2006 22:14:43 -0000 1.13
+++ helper.c 14 Jun 2006 17:15:19 -0000 1.14
@@ -28,53 +28,56 @@
#include "cpu.h"
#include "exec-all.h"
+enum {
+ TLBRET_DIRTY = -4,
+ TLBRET_INVALID = -3,
+ TLBRET_NOMATCH = -2,
+ TLBRET_BADADDR = -1,
+ TLBRET_MATCH = 0
+};
+
/* MIPS32 4K MMU emulation */
#ifdef MIPS_USES_R4K_TLB
static int map_address (CPUState *env, target_ulong *physical, int *prot,
target_ulong address, int rw, int access_type)
{
+ target_ulong tag = address & (TARGET_PAGE_MASK << 1);
+ uint8_t ASID = env->CP0_EntryHi & 0xFF;
tlb_t *tlb;
- target_ulong tag;
- uint8_t ASID;
int i, n;
- int ret;
- ret = -2;
- tag = address & 0xFFFFE000;
- ASID = env->CP0_EntryHi & 0xFF;
for (i = 0; i < MIPS_TLB_NB; i++) {
tlb = &env->tlb[i];
/* Check ASID, virtual page number & size */
if ((tlb->G == 1 || tlb->ASID == ASID) &&
tlb->VPN == tag && address < tlb->end2) {
/* TLB match */
- n = (address >> 12) & 1;
+ n = (address >> TARGET_PAGE_BITS) & 1;
/* Check access rights */
if (!(n ? tlb->V1 : tlb->V0))
- return -3;
+ return TLBRET_INVALID;
if (rw == 0 || (n ? tlb->D1 : tlb->D0)) {
- *physical = tlb->PFN[n] | (address & 0xFFF);
+ *physical = tlb->PFN[n] | (address & ~TARGET_PAGE_MASK);
*prot = PAGE_READ;
if (n ? tlb->D1 : tlb->D0)
*prot |= PAGE_WRITE;
- return 0;
+ return TLBRET_MATCH;
}
- return -4;
+ return TLBRET_DIRTY;
}
}
-
- return ret;
+ return TLBRET_NOMATCH;
}
#endif
-int get_physical_address (CPUState *env, target_ulong *physical, int *prot,
- target_ulong address, int rw, int access_type)
+static int get_physical_address (CPUState *env, target_ulong *physical,
+ int *prot, target_ulong address,
+ int rw, int access_type)
{
- int user_mode;
- int ret;
-
/* User mode can only access useg */
- user_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM;
+ int user_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM;
+ int ret = TLBRET_MATCH;
+
#if 0
if (logfile) {
fprintf(logfile, "user mode %d h %08x\n",
@@ -82,8 +85,7 @@
}
#endif
if (user_mode && address > 0x7FFFFFFFUL)
- return -1;
- ret = 0;
+ return TLBRET_BADADDR;
if (address < 0x80000000UL) {
if (!(env->hflags & MIPS_HFLAG_ERL)) {
#ifdef MIPS_USES_R4K_TLB
@@ -181,7 +183,7 @@
access_type = ACCESS_INT;
if (env->user_mode_only) {
/* user mode only emulation */
- ret = -2;
+ ret = TLBRET_NOMATCH;
goto do_fault;
}
ret = get_physical_address(env, &physical, &prot,
@@ -190,14 +192,15 @@
fprintf(logfile, "%s address=%08x ret %d physical %08x prot %d\n",
__func__, address, ret, physical, prot);
}
- if (ret == 0) {
- ret = tlb_set_page(env, address & ~0xFFF, physical & ~0xFFF, prot,
+ if (ret == TLBRET_MATCH) {
+ ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
+ physical & TARGET_PAGE_MASK, prot,
is_user, is_softmmu);
} else if (ret < 0) {
do_fault:
switch (ret) {
default:
- case -1:
+ case TLBRET_BADADDR:
/* Reference to kernel address from user mode or supervisor mode */
/* Reference to supervisor address from user mode */
if (rw)
@@ -205,7 +208,7 @@
else
exception = EXCP_AdEL;
break;
- case -2:
+ case TLBRET_NOMATCH:
/* No TLB match for a mapped address */
if (rw)
exception = EXCP_TLBS;
@@ -213,14 +216,14 @@
exception = EXCP_TLBL;
error_code = 1;
break;
- case -3:
+ case TLBRET_INVALID:
/* TLB match with no valid bit */
if (rw)
exception = EXCP_TLBS;
else
exception = EXCP_TLBL;
break;
- case -4:
+ case TLBRET_DIRTY:
/* TLB match but 'D' bit is cleared */
exception = EXCP_LTLBL;
break;
@@ -231,7 +234,7 @@
env->CP0_Context = (env->CP0_Context & 0xff800000) |
((address >> 9) & 0x007ffff0);
env->CP0_EntryHi =
- (env->CP0_EntryHi & 0xFF) | (address & 0xFFFFE000);
+ (env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1));
env->exception_index = exception;
env->error_code = error_code;
ret = 1;
Index: cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-mips/cpu.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- cpu.h 14 Jun 2006 16:49:24 -0000 1.8
+++ cpu.h 14 Jun 2006 17:15:19 -0000 1.9
@@ -87,7 +87,7 @@
#endif
#if defined(MIPS_USES_R4K_TLB)
- tlb_t tlb[16];
+ tlb_t tlb[MIPS_TLB_NB];
#endif
uint32_t CP0_index;
uint32_t CP0_random;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] qemu/target-mips helper.c cpu.h,
Fabrice Bellard <=