Statistics
| Branch: | Revision:

root / target-cris / helper.c @ e62b5b13

History | View | Annotate | Download (4.2 kB)

1 81fdc5f8 ths
/*
2 81fdc5f8 ths
 *  CRIS helper routines.
3 81fdc5f8 ths
 *
4 81fdc5f8 ths
 *  Copyright (c) 2007 AXIS Communications AB
5 81fdc5f8 ths
 *  Written by Edgar E. Iglesias.
6 81fdc5f8 ths
 *
7 81fdc5f8 ths
 * This library is free software; you can redistribute it and/or
8 81fdc5f8 ths
 * modify it under the terms of the GNU Lesser General Public
9 81fdc5f8 ths
 * License as published by the Free Software Foundation; either
10 81fdc5f8 ths
 * version 2 of the License, or (at your option) any later version.
11 81fdc5f8 ths
 *
12 81fdc5f8 ths
 * This library is distributed in the hope that it will be useful,
13 81fdc5f8 ths
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 81fdc5f8 ths
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 81fdc5f8 ths
 * Lesser General Public License for more details.
16 81fdc5f8 ths
 *
17 81fdc5f8 ths
 * You should have received a copy of the GNU Lesser General Public
18 81fdc5f8 ths
 * License along with this library; if not, write to the Free Software
19 81fdc5f8 ths
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 81fdc5f8 ths
 */
21 81fdc5f8 ths
22 81fdc5f8 ths
#include <stdio.h>
23 81fdc5f8 ths
#include <string.h>
24 81fdc5f8 ths
25 81fdc5f8 ths
#include "config.h"
26 81fdc5f8 ths
#include "cpu.h"
27 81fdc5f8 ths
#include "mmu.h"
28 81fdc5f8 ths
#include "exec-all.h"
29 941db528 ths
#include "host-utils.h"
30 81fdc5f8 ths
31 e62b5b13 edgar_igl
#define D(x)
32 e62b5b13 edgar_igl
33 81fdc5f8 ths
#if defined(CONFIG_USER_ONLY)
34 81fdc5f8 ths
35 81fdc5f8 ths
void do_interrupt (CPUState *env)
36 81fdc5f8 ths
{
37 bbaf29c7 edgar_igl
        env->exception_index = -1;
38 bbaf29c7 edgar_igl
        env->pregs[PR_ERP] = env->pc;
39 81fdc5f8 ths
}
40 81fdc5f8 ths
41 81fdc5f8 ths
int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
42 6ebbf390 j_mayer
                             int mmu_idx, int is_softmmu)
43 81fdc5f8 ths
{
44 bbaf29c7 edgar_igl
        env->exception_index = 0xaa;
45 bbaf29c7 edgar_igl
        env->debug1 = address;
46 bbaf29c7 edgar_igl
        cpu_dump_state(env, stderr, fprintf, 0);
47 bbaf29c7 edgar_igl
        env->pregs[PR_ERP] = env->pc;
48 bbaf29c7 edgar_igl
        return 1;
49 81fdc5f8 ths
}
50 81fdc5f8 ths
51 81fdc5f8 ths
target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
52 81fdc5f8 ths
{
53 bbaf29c7 edgar_igl
        return addr;
54 81fdc5f8 ths
}
55 81fdc5f8 ths
56 81fdc5f8 ths
#else /* !CONFIG_USER_ONLY */
57 81fdc5f8 ths
58 e62b5b13 edgar_igl
59 e62b5b13 edgar_igl
static void cris_shift_ccs(CPUState *env)
60 e62b5b13 edgar_igl
{
61 e62b5b13 edgar_igl
        uint32_t ccs;
62 e62b5b13 edgar_igl
        /* Apply the ccs shift.  */
63 e62b5b13 edgar_igl
        ccs = env->pregs[PR_CCS];
64 e62b5b13 edgar_igl
        ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2);
65 e62b5b13 edgar_igl
        env->pregs[PR_CCS] = ccs;
66 e62b5b13 edgar_igl
}
67 e62b5b13 edgar_igl
68 81fdc5f8 ths
int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
69 6ebbf390 j_mayer
                               int mmu_idx, int is_softmmu)
70 81fdc5f8 ths
{
71 81fdc5f8 ths
        struct cris_mmu_result_t res;
72 81fdc5f8 ths
        int prot, miss;
73 e62b5b13 edgar_igl
        int r = -1;
74 81fdc5f8 ths
        target_ulong phy;
75 81fdc5f8 ths
76 e62b5b13 edgar_igl
        D(printf ("%s addr=%x pc=%x\n", __func__, address, env->pc));
77 81fdc5f8 ths
        address &= TARGET_PAGE_MASK;
78 81fdc5f8 ths
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
79 6ebbf390 j_mayer
        miss = cris_mmu_translate(&res, env, address, rw, mmu_idx);
80 81fdc5f8 ths
        if (miss)
81 81fdc5f8 ths
        {
82 e62b5b13 edgar_igl
                env->exception_index = EXCP_MMU_FAULT;
83 e62b5b13 edgar_igl
                env->fault_vector = res.bf_vec;
84 e62b5b13 edgar_igl
                r = 1;
85 81fdc5f8 ths
        }
86 81fdc5f8 ths
        else
87 81fdc5f8 ths
        {
88 81fdc5f8 ths
                phy = res.phy;
89 e62b5b13 edgar_igl
                prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
90 e62b5b13 edgar_igl
                r = tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu);
91 81fdc5f8 ths
        }
92 e62b5b13 edgar_igl
        D(printf("%s returns %d irqreq=%x addr=%x ismmu=%d\n", 
93 e62b5b13 edgar_igl
                        __func__, r, env->interrupt_request, 
94 e62b5b13 edgar_igl
                        address, is_softmmu));
95 e62b5b13 edgar_igl
        return r;
96 81fdc5f8 ths
}
97 81fdc5f8 ths
98 81fdc5f8 ths
void do_interrupt(CPUState *env)
99 81fdc5f8 ths
{
100 e62b5b13 edgar_igl
        int ex_vec = -1;
101 81fdc5f8 ths
102 e62b5b13 edgar_igl
        D(fprintf (stderr, "exception index=%d interrupt_req=%d\n",
103 e62b5b13 edgar_igl
                 env->exception_index,
104 e62b5b13 edgar_igl
                 env->interrupt_request));
105 81fdc5f8 ths
106 81fdc5f8 ths
        switch (env->exception_index)
107 81fdc5f8 ths
        {
108 81fdc5f8 ths
                case EXCP_BREAK:
109 e62b5b13 edgar_igl
                        /* These exceptions are genereated by the core itself.
110 e62b5b13 edgar_igl
                           ERP should point to the insn following the brk.  */
111 e62b5b13 edgar_igl
                        ex_vec = env->trap_vector;
112 9004627f edgar_igl
                        env->pregs[PR_ERP] = env->pc + 2;
113 81fdc5f8 ths
                        break;
114 e62b5b13 edgar_igl
115 e62b5b13 edgar_igl
                case EXCP_MMU_FAULT:
116 e62b5b13 edgar_igl
                        /* ERP is already setup by translate-all.c through
117 e62b5b13 edgar_igl
                           re-translation of the aborted TB combined with 
118 e62b5b13 edgar_igl
                           pc searching.  */
119 e62b5b13 edgar_igl
                        ex_vec = env->fault_vector;
120 81fdc5f8 ths
                        break;
121 81fdc5f8 ths
122 81fdc5f8 ths
                default:
123 81fdc5f8 ths
                {
124 81fdc5f8 ths
                        /* Maybe the irq was acked by sw before we got a
125 81fdc5f8 ths
                           change to take it.  */
126 81fdc5f8 ths
                        if (env->interrupt_request & CPU_INTERRUPT_HARD) {
127 e62b5b13 edgar_igl
                                /* Vectors below 0x30 are internal
128 e62b5b13 edgar_igl
                                   exceptions, i.e not interrupt requests
129 e62b5b13 edgar_igl
                                   from the interrupt controller.  */
130 e62b5b13 edgar_igl
                                if (env->interrupt_vector < 0x30)
131 81fdc5f8 ths
                                        return;
132 e62b5b13 edgar_igl
                                /* Is the core accepting interrupts?  */
133 9004627f edgar_igl
                                if (!(env->pregs[PR_CCS] & I_FLAG)) {
134 81fdc5f8 ths
                                        return;
135 81fdc5f8 ths
                                }
136 e62b5b13 edgar_igl
                                /* The interrupt controller gives us the
137 e62b5b13 edgar_igl
                                   vector.  */
138 e62b5b13 edgar_igl
                                ex_vec = env->interrupt_vector;
139 e62b5b13 edgar_igl
                                /* Normal interrupts are taken between
140 e62b5b13 edgar_igl
                                   TB's.  env->pc is valid here.  */
141 9004627f edgar_igl
                                env->pregs[PR_ERP] = env->pc;
142 81fdc5f8 ths
                        }
143 81fdc5f8 ths
                }
144 81fdc5f8 ths
                break;
145 81fdc5f8 ths
        }
146 e62b5b13 edgar_igl
        env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
147 e62b5b13 edgar_igl
        /* Apply the CRIS CCS shift.  */
148 e62b5b13 edgar_igl
        cris_shift_ccs(env);
149 e62b5b13 edgar_igl
        D(printf ("%s ebp=%x isr=%x vec=%x\n", __func__, ebp, isr, ex_vec));
150 81fdc5f8 ths
}
151 81fdc5f8 ths
152 81fdc5f8 ths
target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
153 81fdc5f8 ths
{
154 81fdc5f8 ths
        uint32_t phy = addr;
155 81fdc5f8 ths
        struct cris_mmu_result_t res;
156 81fdc5f8 ths
        int miss;
157 81fdc5f8 ths
        miss = cris_mmu_translate(&res, env, addr, 0, 0);
158 81fdc5f8 ths
        if (!miss)
159 81fdc5f8 ths
                phy = res.phy;
160 e62b5b13 edgar_igl
        D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy));
161 81fdc5f8 ths
        return phy;
162 81fdc5f8 ths
}
163 81fdc5f8 ths
#endif