*
* 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
*/
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <signal.h>
-#include <assert.h>
#include "cpu.h"
#include "exec-all.h"
return addr;
}
+int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr)
+{
+ /* For user mode, only U0 area is cachable. */
+ return !(addr & 0x80000000);
+}
+
#else /* !CONFIG_USER_ONLY */
#define MMU_OK 0
}
}
- if (loglevel & CPU_LOG_INT) {
+ if (qemu_loglevel_mask(CPU_LOG_INT)) {
const char *expname;
switch (env->exception_index) {
case 0x0e0:
expname = do_irq ? "interrupt" : "???";
break;
}
- fprintf(logfile, "exception 0x%03x [%s] raised\n",
- irq_vector, expname);
- cpu_dump_state(env, logfile, fprintf, 0);
+ qemu_log("exception 0x%03x [%s] raised\n",
+ irq_vector, expname);
+ log_cpu_state(env, 0);
}
env->ssr = env->sr;
for (i = 0; i < nbtlb; i++) {
if (!entries[i].v)
continue; /* Invalid entry */
- if (use_asid && entries[i].asid != asid)
+ if (!entries[i].sh && use_asid && entries[i].asid != asid)
continue; /* Bad ASID */
#if 0
switch (entries[i].sz) {
urb = ((env->mmucr) >> 18) & 0x3f;
urc = ((env->mmucr) >> 10) & 0x3f;
urc++;
- if (urc == urb || urc == UTLB_SIZE - 1)
+ if ((urb > 0 && urc > urb) || urc > (UTLB_SIZE - 1))
urc = 0;
env->mmucr = (env->mmucr & 0xffff03ff) | (urc << 10);
}
Return entry, MMU_ITLB_MISS, MMU_ITLB_MULTIPLE or MMU_DTLB_MULTIPLE
Update the itlb from utlb if update is not 0
*/
-int find_itlb_entry(CPUState * env, target_ulong address,
- int use_asid, int update)
+static int find_itlb_entry(CPUState * env, target_ulong address,
+ int use_asid, int update)
{
int e, n;
/* Find utlb entry
Return entry, MMU_DTLB_MISS, MMU_DTLB_MULTIPLE */
-int find_utlb_entry(CPUState * env, target_ulong address, int use_asid)
+static int find_utlb_entry(CPUState * env, target_ulong address, int use_asid)
{
/* per utlb access */
increment_urc(env);
return n;
}
-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)
{
/* P1, P2 and P4 areas do not use translation */
if ((address >= 0x80000000 && address < 0xc0000000) ||
if (address >= 0x80000000 && address < 0xc0000000) {
/* Mask upper 3 bits for P1 and P2 areas */
*physical = address & 0x1fffffff;
- } else if (address >= 0xfd000000 && address < 0xfe000000) {
- /* PCI memory space */
- *physical = address;
- } else if (address >= 0xfc000000) {
- /*
- * Mask upper 3 bits for control registers in P4 area,
- * to unify access to control registers via P0-P3 area.
- * The addresses for cache store queue, TLB address array
- * are not masked.
- */
- *physical = address & 0x1fffffff;
} else {
- /* access to cache store queue, or TLB address array. */
*physical = address;
}
*prot = PAGE_READ | PAGE_WRITE;
return physical;
}
-void cpu_load_tlb(CPUState * env)
+void cpu_load_tlb(CPUSH4State * env)
{
int n = cpu_mmucr_urc(env->mmucr);
tlb_t * entry = &env->utlb[n];
}
}
- /* per utlb access cannot implemented. */
- increment_urc(env);
-
/* Take values into cpu status from registers. */
entry->asid = (uint8_t)cpu_pteh_asid(env->pteh);
entry->vpn = cpu_pteh_vpn(env->pteh);
uint8_t d = (uint8_t)((mem_value & 0x00000200) >> 9);
uint8_t v = (uint8_t)((mem_value & 0x00000100) >> 8);
uint8_t asid = (uint8_t)(mem_value & 0x000000ff);
+ int use_asid = (s->mmucr & MMUCR_SV) == 0 || (s->sr & SR_MD) == 0;
if (associate) {
int i;
if (!entry->v)
continue;
- if (entry->vpn == vpn && entry->asid == asid) {
+ if (entry->vpn == vpn
+ && (!use_asid || entry->asid == asid || entry->sh)) {
if (utlb_match_entry) {
/* Multiple TLB Exception */
s->exception_index = 0x140;
/* search ITLB */
for (i = 0; i < ITLB_SIZE; i++) {
tlb_t * entry = &s->itlb[i];
- if (entry->vpn == vpn && entry->asid == asid) {
+ if (entry->vpn == vpn
+ && (!use_asid || entry->asid == asid || entry->sh)) {
if (entry->v && !v)
needs_tlb_flush = 1;
if (utlb_match_entry)
}
}
+int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr)
+{
+ int n;
+ int use_asid = (env->mmucr & MMUCR_SV) == 0 || (env->sr & SR_MD) == 0;
+
+ /* check area */
+ if (env->sr & SR_MD) {
+ /* For previledged mode, P2 and P4 area is not cachable. */
+ if ((0xA0000000 <= addr && addr < 0xC0000000) || 0xE0000000 <= addr)
+ return 0;
+ } else {
+ /* For user mode, only U0 area is cachable. */
+ if (0x80000000 <= addr)
+ return 0;
+ }
+
+ /*
+ * TODO : Evaluate CCR and check if the cache is on or off.
+ * Now CCR is not in CPUSH4State, but in SH7750State.
+ * When you move the ccr inot CPUSH4State, the code will be
+ * as follows.
+ */
+#if 0
+ /* check if operand cache is enabled or not. */
+ if (!(env->ccr & 1))
+ return 0;
+#endif
+
+ /* if MMU is off, no check for TLB. */
+ if (env->mmucr & MMUCR_AT)
+ return 1;
+
+ /* check TLB */
+ n = find_tlb_entry(env, addr, env->itlb, ITLB_SIZE, use_asid);
+ if (n >= 0)
+ return env->itlb[n].c;
+
+ n = find_tlb_entry(env, addr, env->utlb, UTLB_SIZE, use_asid);
+ if (n >= 0)
+ return env->utlb[n].c;
+
+ return 0;
+}
+
#endif