|
|
1.1 ! root 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: #if defined(CONFIG_USER_ONLY) ! 32: ! 33: void do_interrupt (CPUState *env) ! 34: { ! 35: env->exception_index = -1; ! 36: } ! 37: ! 38: int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw, ! 39: int mmu_idx, int is_softmmu) ! 40: { ! 41: env->exception_index = 0xaa; ! 42: env->debug1 = address; ! 43: cpu_dump_state(env, stderr, fprintf, 0); ! 44: printf("%s addr=%x env->pc=%x\n", __func__, address, env->pc); ! 45: return 1; ! 46: } ! 47: ! 48: target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) ! 49: { ! 50: return addr; ! 51: } ! 52: ! 53: #else /* !CONFIG_USER_ONLY */ ! 54: ! 55: int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw, ! 56: int mmu_idx, int is_softmmu) ! 57: { ! 58: struct cris_mmu_result_t res; ! 59: int prot, miss; ! 60: target_ulong phy; ! 61: ! 62: address &= TARGET_PAGE_MASK; ! 63: prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; ! 64: // printf ("%s pc=%x %x w=%d smmu=%d\n", __func__, env->pc, address, rw, is_softmmu); ! 65: miss = cris_mmu_translate(&res, env, address, rw, mmu_idx); ! 66: if (miss) ! 67: { ! 68: /* handle the miss. */ ! 69: phy = 0; ! 70: env->exception_index = EXCP_MMU_MISS; ! 71: } ! 72: else ! 73: { ! 74: phy = res.phy; ! 75: } ! 76: // printf ("a=%x phy=%x\n", address, phy); ! 77: return tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu); ! 78: } ! 79: ! 80: ! 81: static void cris_shift_ccs(CPUState *env) ! 82: { ! 83: uint32_t ccs; ! 84: /* Apply the ccs shift. */ ! 85: ccs = env->pregs[SR_CCS]; ! 86: ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2); ! 87: // printf ("ccs=%x %x\n", env->pregs[SR_CCS], ccs); ! 88: env->pregs[SR_CCS] = ccs; ! 89: } ! 90: ! 91: void do_interrupt(CPUState *env) ! 92: { ! 93: uint32_t ebp, isr; ! 94: int irqnum; ! 95: ! 96: fflush(NULL); ! 97: ! 98: #if 0 ! 99: printf ("exception index=%d interrupt_req=%d\n", ! 100: env->exception_index, ! 101: env->interrupt_request); ! 102: #endif ! 103: ! 104: switch (env->exception_index) ! 105: { ! 106: case EXCP_BREAK: ! 107: // printf ("BREAK! %d\n", env->trapnr); ! 108: irqnum = env->trapnr; ! 109: ebp = env->pregs[SR_EBP]; ! 110: isr = ldl_code(ebp + irqnum * 4); ! 111: env->pregs[SR_ERP] = env->pc + 2; ! 112: env->pc = isr; ! 113: ! 114: cris_shift_ccs(env); ! 115: ! 116: break; ! 117: case EXCP_MMU_MISS: ! 118: // printf ("MMU miss\n"); ! 119: irqnum = 4; ! 120: ebp = env->pregs[SR_EBP]; ! 121: isr = ldl_code(ebp + irqnum * 4); ! 122: env->pregs[SR_ERP] = env->pc; ! 123: env->pc = isr; ! 124: cris_shift_ccs(env); ! 125: break; ! 126: ! 127: default: ! 128: { ! 129: /* Maybe the irq was acked by sw before we got a ! 130: change to take it. */ ! 131: if (env->interrupt_request & CPU_INTERRUPT_HARD) { ! 132: if (!env->pending_interrupts) ! 133: return; ! 134: if (!(env->pregs[SR_CCS] & I_FLAG)) { ! 135: return; ! 136: } ! 137: ! 138: irqnum = 31 - clz32(env->pending_interrupts); ! 139: irqnum += 0x30; ! 140: ebp = env->pregs[SR_EBP]; ! 141: isr = ldl_code(ebp + irqnum * 4); ! 142: env->pregs[SR_ERP] = env->pc; ! 143: env->pc = isr; ! 144: ! 145: cris_shift_ccs(env); ! 146: #if 0 ! 147: printf ("%s ebp=%x %x isr=%x %d" ! 148: " ir=%x pending=%x\n", ! 149: __func__, ! 150: ebp, ebp + irqnum * 4, ! 151: isr, env->exception_index, ! 152: env->interrupt_request, ! 153: env->pending_interrupts); ! 154: #endif ! 155: } ! 156: ! 157: } ! 158: break; ! 159: } ! 160: } ! 161: ! 162: target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr) ! 163: { ! 164: // printf ("%s\n", __func__); ! 165: uint32_t phy = addr; ! 166: struct cris_mmu_result_t res; ! 167: int miss; ! 168: miss = cris_mmu_translate(&res, env, addr, 0, 0); ! 169: if (!miss) ! 170: phy = res.phy; ! 171: return phy; ! 172: } ! 173: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.