|
|
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.