Statistics
| Branch: | Revision:

root / target-openrisc / sys_helper.c @ a2247f8e

History | View | Annotate | Download (8.4 kB)

1 4dd044c6 Jia Liu
/*
2 4dd044c6 Jia Liu
 * OpenRISC system instructions helper routines
3 4dd044c6 Jia Liu
 *
4 4dd044c6 Jia Liu
 * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
5 4dd044c6 Jia Liu
 *                         Zhizhou Zhang <etouzh@gmail.com>
6 4dd044c6 Jia Liu
 *
7 4dd044c6 Jia Liu
 * This library is free software; you can redistribute it and/or
8 4dd044c6 Jia Liu
 * modify it under the terms of the GNU Lesser General Public
9 4dd044c6 Jia Liu
 * License as published by the Free Software Foundation; either
10 4dd044c6 Jia Liu
 * version 2 of the License, or (at your option) any later version.
11 4dd044c6 Jia Liu
 *
12 4dd044c6 Jia Liu
 * This library is distributed in the hope that it will be useful,
13 4dd044c6 Jia Liu
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 4dd044c6 Jia Liu
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 4dd044c6 Jia Liu
 * Lesser General Public License for more details.
16 4dd044c6 Jia Liu
 *
17 4dd044c6 Jia Liu
 * You should have received a copy of the GNU Lesser General Public
18 4dd044c6 Jia Liu
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 4dd044c6 Jia Liu
 */
20 4dd044c6 Jia Liu
21 4dd044c6 Jia Liu
#include "cpu.h"
22 4dd044c6 Jia Liu
#include "helper.h"
23 4dd044c6 Jia Liu
24 4dd044c6 Jia Liu
#define TO_SPR(group, number) (((group) << 11) + (number))
25 4dd044c6 Jia Liu
26 4dd044c6 Jia Liu
void HELPER(mtspr)(CPUOpenRISCState *env,
27 4dd044c6 Jia Liu
                   target_ulong ra, target_ulong rb, target_ulong offset)
28 4dd044c6 Jia Liu
{
29 4dd044c6 Jia Liu
#ifndef CONFIG_USER_ONLY
30 4dd044c6 Jia Liu
    int spr = (ra | offset);
31 4dd044c6 Jia Liu
    int idx;
32 4dd044c6 Jia Liu
33 dd51dc52 Andreas Färber
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
34 259186a7 Andreas Färber
    CPUState *cs = CPU(cpu);
35 4dd044c6 Jia Liu
36 4dd044c6 Jia Liu
    switch (spr) {
37 4dd044c6 Jia Liu
    case TO_SPR(0, 0): /* VR */
38 4dd044c6 Jia Liu
        env->vr = rb;
39 4dd044c6 Jia Liu
        break;
40 4dd044c6 Jia Liu
41 4dd044c6 Jia Liu
    case TO_SPR(0, 16): /* NPC */
42 4dd044c6 Jia Liu
        env->npc = rb;
43 4dd044c6 Jia Liu
        break;
44 4dd044c6 Jia Liu
45 4dd044c6 Jia Liu
    case TO_SPR(0, 17): /* SR */
46 4dd044c6 Jia Liu
        if ((env->sr & (SR_IME | SR_DME | SR_SM)) ^
47 4dd044c6 Jia Liu
            (rb & (SR_IME | SR_DME | SR_SM))) {
48 4dd044c6 Jia Liu
            tlb_flush(env, 1);
49 4dd044c6 Jia Liu
        }
50 4dd044c6 Jia Liu
        env->sr = rb;
51 4dd044c6 Jia Liu
        env->sr |= SR_FO;      /* FO is const equal to 1 */
52 4dd044c6 Jia Liu
        if (env->sr & SR_DME) {
53 4dd044c6 Jia Liu
            env->tlb->cpu_openrisc_map_address_data =
54 4dd044c6 Jia Liu
                &cpu_openrisc_get_phys_data;
55 4dd044c6 Jia Liu
        } else {
56 4dd044c6 Jia Liu
            env->tlb->cpu_openrisc_map_address_data =
57 4dd044c6 Jia Liu
                &cpu_openrisc_get_phys_nommu;
58 4dd044c6 Jia Liu
        }
59 4dd044c6 Jia Liu
60 4dd044c6 Jia Liu
        if (env->sr & SR_IME) {
61 4dd044c6 Jia Liu
            env->tlb->cpu_openrisc_map_address_code =
62 4dd044c6 Jia Liu
                &cpu_openrisc_get_phys_code;
63 4dd044c6 Jia Liu
        } else {
64 4dd044c6 Jia Liu
            env->tlb->cpu_openrisc_map_address_code =
65 4dd044c6 Jia Liu
                &cpu_openrisc_get_phys_nommu;
66 4dd044c6 Jia Liu
        }
67 4dd044c6 Jia Liu
        break;
68 4dd044c6 Jia Liu
69 4dd044c6 Jia Liu
    case TO_SPR(0, 18): /* PPC */
70 4dd044c6 Jia Liu
        env->ppc = rb;
71 4dd044c6 Jia Liu
        break;
72 4dd044c6 Jia Liu
73 4dd044c6 Jia Liu
    case TO_SPR(0, 32): /* EPCR */
74 4dd044c6 Jia Liu
        env->epcr = rb;
75 4dd044c6 Jia Liu
        break;
76 4dd044c6 Jia Liu
77 4dd044c6 Jia Liu
    case TO_SPR(0, 48): /* EEAR */
78 4dd044c6 Jia Liu
        env->eear = rb;
79 4dd044c6 Jia Liu
        break;
80 4dd044c6 Jia Liu
81 4dd044c6 Jia Liu
    case TO_SPR(0, 64): /* ESR */
82 4dd044c6 Jia Liu
        env->esr = rb;
83 4dd044c6 Jia Liu
        break;
84 4dd044c6 Jia Liu
    case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */
85 4dd044c6 Jia Liu
        idx = spr - TO_SPR(1, 512);
86 4dd044c6 Jia Liu
        if (!(rb & 1)) {
87 4dd044c6 Jia Liu
            tlb_flush_page(env, env->tlb->dtlb[0][idx].mr & TARGET_PAGE_MASK);
88 4dd044c6 Jia Liu
        }
89 4dd044c6 Jia Liu
        env->tlb->dtlb[0][idx].mr = rb;
90 4dd044c6 Jia Liu
        break;
91 4dd044c6 Jia Liu
92 4dd044c6 Jia Liu
    case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */
93 4dd044c6 Jia Liu
        idx = spr - TO_SPR(1, 640);
94 4dd044c6 Jia Liu
        env->tlb->dtlb[0][idx].tr = rb;
95 4dd044c6 Jia Liu
        break;
96 4dd044c6 Jia Liu
    case TO_SPR(1, 768) ... TO_SPR(1, 895):   /* DTLBW1MR 0-127 */
97 4dd044c6 Jia Liu
    case TO_SPR(1, 896) ... TO_SPR(1, 1023):  /* DTLBW1TR 0-127 */
98 4dd044c6 Jia Liu
    case TO_SPR(1, 1024) ... TO_SPR(1, 1151): /* DTLBW2MR 0-127 */
99 4dd044c6 Jia Liu
    case TO_SPR(1, 1152) ... TO_SPR(1, 1279): /* DTLBW2TR 0-127 */
100 4dd044c6 Jia Liu
    case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */
101 4dd044c6 Jia Liu
    case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */
102 4dd044c6 Jia Liu
        break;
103 4dd044c6 Jia Liu
    case TO_SPR(2, 512) ... TO_SPR(2, 639):   /* ITLBW0MR 0-127 */
104 4dd044c6 Jia Liu
        idx = spr - TO_SPR(2, 512);
105 4dd044c6 Jia Liu
        if (!(rb & 1)) {
106 4dd044c6 Jia Liu
            tlb_flush_page(env, env->tlb->itlb[0][idx].mr & TARGET_PAGE_MASK);
107 4dd044c6 Jia Liu
        }
108 4dd044c6 Jia Liu
        env->tlb->itlb[0][idx].mr = rb;
109 4dd044c6 Jia Liu
        break;
110 4dd044c6 Jia Liu
111 4dd044c6 Jia Liu
    case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */
112 4dd044c6 Jia Liu
        idx = spr - TO_SPR(2, 640);
113 4dd044c6 Jia Liu
        env->tlb->itlb[0][idx].tr = rb;
114 4dd044c6 Jia Liu
        break;
115 4dd044c6 Jia Liu
    case TO_SPR(2, 768) ... TO_SPR(2, 895):   /* ITLBW1MR 0-127 */
116 4dd044c6 Jia Liu
    case TO_SPR(2, 896) ... TO_SPR(2, 1023):  /* ITLBW1TR 0-127 */
117 4dd044c6 Jia Liu
    case TO_SPR(2, 1024) ... TO_SPR(2, 1151): /* ITLBW2MR 0-127 */
118 4dd044c6 Jia Liu
    case TO_SPR(2, 1152) ... TO_SPR(2, 1279): /* ITLBW2TR 0-127 */
119 4dd044c6 Jia Liu
    case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */
120 4dd044c6 Jia Liu
    case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
121 4dd044c6 Jia Liu
        break;
122 4dd044c6 Jia Liu
    case TO_SPR(9, 0):  /* PICMR */
123 4dd044c6 Jia Liu
        env->picmr |= rb;
124 4dd044c6 Jia Liu
        break;
125 4dd044c6 Jia Liu
    case TO_SPR(9, 2):  /* PICSR */
126 4dd044c6 Jia Liu
        env->picsr &= ~rb;
127 4dd044c6 Jia Liu
        break;
128 4dd044c6 Jia Liu
    case TO_SPR(10, 0): /* TTMR */
129 4dd044c6 Jia Liu
        {
130 4dd044c6 Jia Liu
            int ip = env->ttmr & TTMR_IP;
131 4dd044c6 Jia Liu
132 4dd044c6 Jia Liu
            if (rb & TTMR_IP) {    /* Keep IP bit.  */
133 4dd044c6 Jia Liu
                env->ttmr = (rb & ~TTMR_IP) + ip;
134 4dd044c6 Jia Liu
            } else {    /* Clear IP bit.  */
135 4dd044c6 Jia Liu
                env->ttmr = rb & ~TTMR_IP;
136 259186a7 Andreas Färber
                cs->interrupt_request &= ~CPU_INTERRUPT_TIMER;
137 4dd044c6 Jia Liu
            }
138 4dd044c6 Jia Liu
139 4dd044c6 Jia Liu
            cpu_openrisc_count_update(cpu);
140 4dd044c6 Jia Liu
141 4dd044c6 Jia Liu
            switch (env->ttmr & TTMR_M) {
142 4dd044c6 Jia Liu
            case TIMER_NONE:
143 4dd044c6 Jia Liu
                cpu_openrisc_count_stop(cpu);
144 4dd044c6 Jia Liu
                break;
145 4dd044c6 Jia Liu
            case TIMER_INTR:
146 4dd044c6 Jia Liu
                cpu_openrisc_count_start(cpu);
147 4dd044c6 Jia Liu
                break;
148 4dd044c6 Jia Liu
            case TIMER_SHOT:
149 4dd044c6 Jia Liu
                cpu_openrisc_count_start(cpu);
150 4dd044c6 Jia Liu
                break;
151 4dd044c6 Jia Liu
            case TIMER_CONT:
152 4dd044c6 Jia Liu
                cpu_openrisc_count_start(cpu);
153 4dd044c6 Jia Liu
                break;
154 4dd044c6 Jia Liu
            default:
155 4dd044c6 Jia Liu
                break;
156 4dd044c6 Jia Liu
            }
157 4dd044c6 Jia Liu
        }
158 4dd044c6 Jia Liu
        break;
159 4dd044c6 Jia Liu
160 4dd044c6 Jia Liu
    case TO_SPR(10, 1): /* TTCR */
161 4dd044c6 Jia Liu
        env->ttcr = rb;
162 4dd044c6 Jia Liu
        if (env->ttmr & TIMER_NONE) {
163 4dd044c6 Jia Liu
            return;
164 4dd044c6 Jia Liu
        }
165 4dd044c6 Jia Liu
        cpu_openrisc_count_start(cpu);
166 4dd044c6 Jia Liu
        break;
167 4dd044c6 Jia Liu
    default:
168 4dd044c6 Jia Liu
169 4dd044c6 Jia Liu
        break;
170 4dd044c6 Jia Liu
    }
171 4dd044c6 Jia Liu
#endif
172 4dd044c6 Jia Liu
}
173 4dd044c6 Jia Liu
174 4dd044c6 Jia Liu
target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
175 4dd044c6 Jia Liu
                           target_ulong rd, target_ulong ra, uint32_t offset)
176 4dd044c6 Jia Liu
{
177 4dd044c6 Jia Liu
#ifndef CONFIG_USER_ONLY
178 4dd044c6 Jia Liu
    int spr = (ra | offset);
179 4dd044c6 Jia Liu
    int idx;
180 4dd044c6 Jia Liu
181 dd51dc52 Andreas Färber
    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
182 4dd044c6 Jia Liu
183 4dd044c6 Jia Liu
    switch (spr) {
184 4dd044c6 Jia Liu
    case TO_SPR(0, 0): /* VR */
185 4dd044c6 Jia Liu
        return env->vr & SPR_VR;
186 4dd044c6 Jia Liu
187 4dd044c6 Jia Liu
    case TO_SPR(0, 1): /* UPR */
188 4dd044c6 Jia Liu
        return env->upr;    /* TT, DM, IM, UP present */
189 4dd044c6 Jia Liu
190 4dd044c6 Jia Liu
    case TO_SPR(0, 2): /* CPUCFGR */
191 4dd044c6 Jia Liu
        return env->cpucfgr;
192 4dd044c6 Jia Liu
193 4dd044c6 Jia Liu
    case TO_SPR(0, 3): /* DMMUCFGR */
194 4dd044c6 Jia Liu
        return env->dmmucfgr;    /* 1Way, 64 entries */
195 4dd044c6 Jia Liu
196 4dd044c6 Jia Liu
    case TO_SPR(0, 4): /* IMMUCFGR */
197 4dd044c6 Jia Liu
        return env->immucfgr;
198 4dd044c6 Jia Liu
199 4dd044c6 Jia Liu
    case TO_SPR(0, 16): /* NPC */
200 4dd044c6 Jia Liu
        return env->npc;
201 4dd044c6 Jia Liu
202 4dd044c6 Jia Liu
    case TO_SPR(0, 17): /* SR */
203 4dd044c6 Jia Liu
        return env->sr;
204 4dd044c6 Jia Liu
205 4dd044c6 Jia Liu
    case TO_SPR(0, 18): /* PPC */
206 4dd044c6 Jia Liu
        return env->ppc;
207 4dd044c6 Jia Liu
208 4dd044c6 Jia Liu
    case TO_SPR(0, 32): /* EPCR */
209 4dd044c6 Jia Liu
        return env->epcr;
210 4dd044c6 Jia Liu
211 4dd044c6 Jia Liu
    case TO_SPR(0, 48): /* EEAR */
212 4dd044c6 Jia Liu
        return env->eear;
213 4dd044c6 Jia Liu
214 4dd044c6 Jia Liu
    case TO_SPR(0, 64): /* ESR */
215 4dd044c6 Jia Liu
        return env->esr;
216 4dd044c6 Jia Liu
217 4dd044c6 Jia Liu
    case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */
218 4dd044c6 Jia Liu
        idx = spr - TO_SPR(1, 512);
219 4dd044c6 Jia Liu
        return env->tlb->dtlb[0][idx].mr;
220 4dd044c6 Jia Liu
221 4dd044c6 Jia Liu
    case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */
222 4dd044c6 Jia Liu
        idx = spr - TO_SPR(1, 640);
223 4dd044c6 Jia Liu
        return env->tlb->dtlb[0][idx].tr;
224 4dd044c6 Jia Liu
225 4dd044c6 Jia Liu
    case TO_SPR(1, 768) ... TO_SPR(1, 895):   /* DTLBW1MR 0-127 */
226 4dd044c6 Jia Liu
    case TO_SPR(1, 896) ... TO_SPR(1, 1023):  /* DTLBW1TR 0-127 */
227 4dd044c6 Jia Liu
    case TO_SPR(1, 1024) ... TO_SPR(1, 1151): /* DTLBW2MR 0-127 */
228 4dd044c6 Jia Liu
    case TO_SPR(1, 1152) ... TO_SPR(1, 1279): /* DTLBW2TR 0-127 */
229 4dd044c6 Jia Liu
    case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */
230 4dd044c6 Jia Liu
    case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */
231 4dd044c6 Jia Liu
        break;
232 4dd044c6 Jia Liu
233 4dd044c6 Jia Liu
    case TO_SPR(2, 512) ... TO_SPR(2, 639): /* ITLBW0MR 0-127 */
234 4dd044c6 Jia Liu
        idx = spr - TO_SPR(2, 512);
235 4dd044c6 Jia Liu
        return env->tlb->itlb[0][idx].mr;
236 4dd044c6 Jia Liu
237 4dd044c6 Jia Liu
    case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */
238 4dd044c6 Jia Liu
        idx = spr - TO_SPR(2, 640);
239 4dd044c6 Jia Liu
        return env->tlb->itlb[0][idx].tr;
240 4dd044c6 Jia Liu
241 4dd044c6 Jia Liu
    case TO_SPR(2, 768) ... TO_SPR(2, 895):   /* ITLBW1MR 0-127 */
242 4dd044c6 Jia Liu
    case TO_SPR(2, 896) ... TO_SPR(2, 1023):  /* ITLBW1TR 0-127 */
243 4dd044c6 Jia Liu
    case TO_SPR(2, 1024) ... TO_SPR(2, 1151): /* ITLBW2MR 0-127 */
244 4dd044c6 Jia Liu
    case TO_SPR(2, 1152) ... TO_SPR(2, 1279): /* ITLBW2TR 0-127 */
245 4dd044c6 Jia Liu
    case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */
246 4dd044c6 Jia Liu
    case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
247 4dd044c6 Jia Liu
        break;
248 4dd044c6 Jia Liu
249 4dd044c6 Jia Liu
    case TO_SPR(9, 0):  /* PICMR */
250 4dd044c6 Jia Liu
        return env->picmr;
251 4dd044c6 Jia Liu
252 4dd044c6 Jia Liu
    case TO_SPR(9, 2):  /* PICSR */
253 4dd044c6 Jia Liu
        return env->picsr;
254 4dd044c6 Jia Liu
255 4dd044c6 Jia Liu
    case TO_SPR(10, 0): /* TTMR */
256 4dd044c6 Jia Liu
        return env->ttmr;
257 4dd044c6 Jia Liu
258 4dd044c6 Jia Liu
    case TO_SPR(10, 1): /* TTCR */
259 4dd044c6 Jia Liu
        cpu_openrisc_count_update(cpu);
260 4dd044c6 Jia Liu
        return env->ttcr;
261 4dd044c6 Jia Liu
262 4dd044c6 Jia Liu
    default:
263 4dd044c6 Jia Liu
        break;
264 4dd044c6 Jia Liu
    }
265 4dd044c6 Jia Liu
#endif
266 4dd044c6 Jia Liu
267 4dd044c6 Jia Liu
/*If we later need to add tracepoints (or debug printfs) for the return
268 4dd044c6 Jia Liu
value, it may be useful to structure the code like this:
269 4dd044c6 Jia Liu

270 4dd044c6 Jia Liu
target_ulong ret = 0;
271 4dd044c6 Jia Liu

272 4dd044c6 Jia Liu
switch() {
273 4dd044c6 Jia Liu
case x:
274 4dd044c6 Jia Liu
 ret = y;
275 4dd044c6 Jia Liu
 break;
276 4dd044c6 Jia Liu
case z:
277 4dd044c6 Jia Liu
 ret = 42;
278 4dd044c6 Jia Liu
 break;
279 4dd044c6 Jia Liu
...
280 4dd044c6 Jia Liu
}
281 4dd044c6 Jia Liu

282 4dd044c6 Jia Liu
later something like trace_spr_read(ret);
283 4dd044c6 Jia Liu

284 4dd044c6 Jia Liu
return ret;*/
285 4dd044c6 Jia Liu
286 4dd044c6 Jia Liu
    /* for rd is passed in, if rd unchanged, just keep it back.  */
287 4dd044c6 Jia Liu
    return rd;
288 4dd044c6 Jia Liu
}