Statistics
| Branch: | Revision:

root / target-cris / helper.c @ e62b5b13

History | View | Annotate | Download (4.2 kB)

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->debug1 = address;
46
        cpu_dump_state(env, stderr, fprintf, 0);
47
        env->pregs[PR_ERP] = env->pc;
48
        return 1;
49
}
50

    
51
target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
52
{
53
        return addr;
54
}
55

    
56
#else /* !CONFIG_USER_ONLY */
57

    
58

    
59
static void cris_shift_ccs(CPUState *env)
60
{
61
        uint32_t ccs;
62
        /* Apply the ccs shift.  */
63
        ccs = env->pregs[PR_CCS];
64
        ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2);
65
        env->pregs[PR_CCS] = ccs;
66
}
67

    
68
int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
69
                               int mmu_idx, int is_softmmu)
70
{
71
        struct cris_mmu_result_t res;
72
        int prot, miss;
73
        int r = -1;
74
        target_ulong phy;
75

    
76
        D(printf ("%s addr=%x pc=%x\n", __func__, address, env->pc));
77
        address &= TARGET_PAGE_MASK;
78
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
79
        miss = cris_mmu_translate(&res, env, address, rw, mmu_idx);
80
        if (miss)
81
        {
82
                env->exception_index = EXCP_MMU_FAULT;
83
                env->fault_vector = res.bf_vec;
84
                r = 1;
85
        }
86
        else
87
        {
88
                phy = res.phy;
89
                prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
90
                r = tlb_set_page(env, address, phy, prot, mmu_idx, is_softmmu);
91
        }
92
        D(printf("%s returns %d irqreq=%x addr=%x ismmu=%d\n", 
93
                        __func__, r, env->interrupt_request, 
94
                        address, is_softmmu));
95
        return r;
96
}
97

    
98
void do_interrupt(CPUState *env)
99
{
100
        int ex_vec = -1;
101

    
102
        D(fprintf (stderr, "exception index=%d interrupt_req=%d\n",
103
                 env->exception_index,
104
                 env->interrupt_request));
105

    
106
        switch (env->exception_index)
107
        {
108
                case EXCP_BREAK:
109
                        /* These exceptions are genereated by the core itself.
110
                           ERP should point to the insn following the brk.  */
111
                        ex_vec = env->trap_vector;
112
                        env->pregs[PR_ERP] = env->pc + 2;
113
                        break;
114

    
115
                case EXCP_MMU_FAULT:
116
                        /* ERP is already setup by translate-all.c through
117
                           re-translation of the aborted TB combined with 
118
                           pc searching.  */
119
                        ex_vec = env->fault_vector;
120
                        break;
121

    
122
                default:
123
                {
124
                        /* Maybe the irq was acked by sw before we got a
125
                           change to take it.  */
126
                        if (env->interrupt_request & CPU_INTERRUPT_HARD) {
127
                                /* Vectors below 0x30 are internal
128
                                   exceptions, i.e not interrupt requests
129
                                   from the interrupt controller.  */
130
                                if (env->interrupt_vector < 0x30)
131
                                        return;
132
                                /* Is the core accepting interrupts?  */
133
                                if (!(env->pregs[PR_CCS] & I_FLAG)) {
134
                                        return;
135
                                }
136
                                /* The interrupt controller gives us the
137
                                   vector.  */
138
                                ex_vec = env->interrupt_vector;
139
                                /* Normal interrupts are taken between
140
                                   TB's.  env->pc is valid here.  */
141
                                env->pregs[PR_ERP] = env->pc;
142
                        }
143
                }
144
                break;
145
        }
146
        env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
147
        /* Apply the CRIS CCS shift.  */
148
        cris_shift_ccs(env);
149
        D(printf ("%s ebp=%x isr=%x vec=%x\n", __func__, ebp, isr, ex_vec));
150
}
151

    
152
target_phys_addr_t cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
153
{
154
        uint32_t phy = addr;
155
        struct cris_mmu_result_t res;
156
        int miss;
157
        miss = cris_mmu_translate(&res, env, addr, 0, 0);
158
        if (!miss)
159
                phy = res.phy;
160
        D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy));
161
        return phy;
162
}
163
#endif