symbian-qemu-0.9.1-12/qemu-symbian-svp/target-cris/helper.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  *  CRIS helper routines.
       
     3  *
       
     4  *  Copyright (c) 2007 AXIS Communications AB
       
     5  *  Written by Edgar E. Iglesias.
       
     6  *
       
     7  * This library is free software; you can redistribute it and/or
       
     8  * modify it under the terms of the GNU Lesser General Public
       
     9  * License as published by the Free Software Foundation; either
       
    10  * version 2 of the License, or (at your option) any later version.
       
    11  *
       
    12  * This library is distributed in the hope that it will be useful,
       
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    15  * Lesser General Public License for more details.
       
    16  *
       
    17  * You should have received a copy of the GNU Lesser General Public
       
    18  * License along with this library; if not, write to the Free Software
       
    19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    20  */
       
    21 
       
    22 #include <stdio.h>
       
    23 #include <string.h>
       
    24 
       
    25 #include "config.h"
       
    26 #include "cpu.h"
       
    27 #include "mmu.h"
       
    28 #include "exec-all.h"
       
    29 #include "host-utils.h"
       
    30 
       
    31 #define D(x)
       
    32 
       
    33 #if defined(CONFIG_USER_ONLY)
       
    34 
       
    35 void do_interrupt (CPUState *env)
       
    36 {
       
    37 	env->exception_index = -1;
       
    38 	env->pregs[PR_ERP] = env->pc;
       
    39 }
       
    40 
       
    41 int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
       
    42                              int mmu_idx, int is_softmmu)
       
    43 {
       
    44 	env->exception_index = 0xaa;
       
    45 	env->pregs[PR_EDA] = address;
       
    46 	cpu_dump_state(env, stderr, fprintf, 0);
       
    47 	return 1;
       
    48 }
       
    49 
       
    50 target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
       
    51 {
       
    52 	return addr;
       
    53 }
       
    54 
       
    55 #else /* !CONFIG_USER_ONLY */
       
    56 
       
    57 
       
    58 static void cris_shift_ccs(CPUState *env)
       
    59 {
       
    60 	uint32_t ccs;
       
    61 	/* Apply the ccs shift.  */
       
    62 	ccs = env->pregs[PR_CCS];
       
    63 	ccs = ((ccs & 0xc0000000) | ((ccs << 12) >> 2)) & ~0x3ff;
       
    64 	env->pregs[PR_CCS] = ccs;
       
    65 }
       
    66 
       
    67 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
       
    68                                int mmu_idx, int is_softmmu)
       
    69 {
       
    70 	struct cris_mmu_result_t res;
       
    71 	int prot, miss;
       
    72 	int r = -1;
       
    73 	target_ulong phy;
       
    74 
       
    75 	D(printf ("%s addr=%x pc=%x rw=%x\n", __func__, address, env->pc, rw));
       
    76 	address &= TARGET_PAGE_MASK;
       
    77 	miss = cris_mmu_translate(&res, env, address, rw, mmu_idx);
       
    78 	if (miss)
       
    79 	{
       
    80 		if (env->exception_index == EXCP_BUSFAULT)
       
    81 			cpu_abort(env, 
       
    82 				  "CRIS: Illegal recursive bus fault."
       
    83 				  "addr=%x rw=%d\n",
       
    84 				  address, rw);
       
    85 
       
    86 		env->exception_index = EXCP_BUSFAULT;
       
    87 		env->fault_vector = res.bf_vec;
       
    88 		r = 1;
       
    89 	}
       
    90 	else
       
    91 	{
       
    92 		/*
       
    93 		 * Mask off the cache selection bit. The ETRAX busses do not
       
    94 		 * see the top bit.
       
    95 		 */
       
    96 		phy = res.phy & ~0x80000000;
       
    97 		prot = res.prot;
       
    98 		r = tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu);
       
    99 	}
       
   100 	if (r > 0)
       
   101 		D(fprintf(logfile, "%s returns %d irqreq=%x addr=%x"
       
   102 			  " phy=%x ismmu=%d vec=%x pc=%x\n", 
       
   103 			  __func__, r, env->interrupt_request, 
       
   104 			  address, res.phy, is_softmmu, res.bf_vec, env->pc));
       
   105 	return r;
       
   106 }
       
   107 
       
   108 void do_interrupt(CPUState *env)
       
   109 {
       
   110 	int ex_vec = -1;
       
   111 
       
   112 	D(fprintf (logfile, "exception index=%d interrupt_req=%d\n",
       
   113 		   env->exception_index,
       
   114 		   env->interrupt_request));
       
   115 
       
   116 	switch (env->exception_index)
       
   117 	{
       
   118 		case EXCP_BREAK:
       
   119 			/* These exceptions are genereated by the core itself.
       
   120 			   ERP should point to the insn following the brk.  */
       
   121 			ex_vec = env->trap_vector;
       
   122 			env->pregs[PR_ERP] = env->pc;
       
   123 			break;
       
   124 
       
   125 		case EXCP_NMI:
       
   126 			/* NMI is hardwired to vector zero.  */
       
   127 			ex_vec = 0;
       
   128 			env->pregs[PR_CCS] &= ~M_FLAG;
       
   129 			env->pregs[PR_NRP] = env->pc;
       
   130 			break;
       
   131 
       
   132 		case EXCP_BUSFAULT:
       
   133 			ex_vec = env->fault_vector;
       
   134 			env->pregs[PR_ERP] = env->pc;
       
   135 			break;
       
   136 
       
   137 		default:
       
   138 			/* The interrupt controller gives us the vector.  */
       
   139 			ex_vec = env->interrupt_vector;
       
   140 			/* Normal interrupts are taken between
       
   141 			   TB's.  env->pc is valid here.  */
       
   142 			env->pregs[PR_ERP] = env->pc;
       
   143 			break;
       
   144 	}
       
   145 
       
   146 	/* Fill in the IDX field.  */
       
   147 	env->pregs[PR_EXS] = (ex_vec & 0xff) << 8;
       
   148 
       
   149 	if (env->dslot) {
       
   150 		D(fprintf(logfile, "excp isr=%x PC=%x ds=%d SP=%x"
       
   151 			  " ERP=%x pid=%x ccs=%x cc=%d %x\n",
       
   152 			  ex_vec, env->pc, env->dslot,
       
   153 			  env->regs[R_SP],
       
   154 			  env->pregs[PR_ERP], env->pregs[PR_PID],
       
   155 			  env->pregs[PR_CCS],
       
   156 			  env->cc_op, env->cc_mask));
       
   157 		/* We loose the btarget, btaken state here so rexec the
       
   158 		   branch.  */
       
   159 		env->pregs[PR_ERP] -= env->dslot;
       
   160 		/* Exception starts with dslot cleared.  */
       
   161 		env->dslot = 0;
       
   162 	}
       
   163 	
       
   164 	env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
       
   165 
       
   166 	if (env->pregs[PR_CCS] & U_FLAG) {
       
   167 		/* Swap stack pointers.  */
       
   168 		env->pregs[PR_USP] = env->regs[R_SP];
       
   169 		env->regs[R_SP] = env->ksp;
       
   170 	}
       
   171 
       
   172 	/* Apply the CRIS CCS shift. Clears U if set.  */
       
   173 	cris_shift_ccs(env);
       
   174 	D(fprintf (logfile, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n", 
       
   175 		   __func__, env->pc, ex_vec, 
       
   176 		   env->pregs[PR_CCS],
       
   177 		   env->pregs[PR_PID], 
       
   178 		   env->pregs[PR_ERP]));
       
   179 }
       
   180 
       
   181 target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
       
   182 {
       
   183 	uint32_t phy = addr;
       
   184 	struct cris_mmu_result_t res;
       
   185 	int miss;
       
   186 	miss = cris_mmu_translate(&res, env, addr, 0, 0);
       
   187 	if (!miss)
       
   188 		phy = res.phy;
       
   189 	D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy));
       
   190 	return phy;
       
   191 }
       
   192 #endif