]> git.proxmox.com Git - mirror_qemu.git/blame - target/nios2/cpu.c
target/nios2: Remove CPU_INTERRUPT_NMI
[mirror_qemu.git] / target / nios2 / cpu.c
CommitLineData
032c76bc
CW
1/*
2 * QEMU Nios II CPU
3 *
4 * Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see
18 * <http://www.gnu.org/licenses/lgpl-2.1.html>
19 */
20
21#include "qemu/osdep.h"
0b8fa32f 22#include "qemu/module.h"
032c76bc
CW
23#include "qapi/error.h"
24#include "cpu.h"
25#include "exec/log.h"
26#include "exec/gdbstub.h"
27#include "hw/qdev-properties.h"
28
29static void nios2_cpu_set_pc(CPUState *cs, vaddr value)
30{
31 Nios2CPU *cpu = NIOS2_CPU(cs);
32 CPUNios2State *env = &cpu->env;
33
17a406ee 34 env->pc = value;
032c76bc
CW
35}
36
37static bool nios2_cpu_has_work(CPUState *cs)
38{
e8d12542 39 return cs->interrupt_request & CPU_INTERRUPT_HARD;
032c76bc
CW
40}
41
781c67ca 42static void nios2_cpu_reset(DeviceState *dev)
032c76bc 43{
781c67ca 44 CPUState *cs = CPU(dev);
032c76bc
CW
45 Nios2CPU *cpu = NIOS2_CPU(cs);
46 Nios2CPUClass *ncc = NIOS2_CPU_GET_CLASS(cpu);
47 CPUNios2State *env = &cpu->env;
48
781c67ca 49 ncc->parent_reset(dev);
032c76bc 50
b8f036a9
RH
51 memset(env->regs, 0, sizeof(env->regs));
52 memset(env->ctrl, 0, sizeof(env->ctrl));
17a406ee 53 env->pc = cpu->reset_addr;
032c76bc
CW
54
55#if defined(CONFIG_USER_ONLY)
56 /* Start in user mode with interrupts enabled. */
2de70d2d 57 env->ctrl[CR_STATUS] = CR_STATUS_RSIE | CR_STATUS_U | CR_STATUS_PIE;
032c76bc 58#else
2de70d2d 59 env->ctrl[CR_STATUS] = CR_STATUS_RSIE;
032c76bc
CW
60#endif
61}
62
cd2528de
PM
63#ifndef CONFIG_USER_ONLY
64static void nios2_cpu_set_irq(void *opaque, int irq, int level)
65{
66 Nios2CPU *cpu = opaque;
67 CPUNios2State *env = &cpu->env;
68 CPUState *cs = CPU(cpu);
69
b8f036a9 70 env->ctrl[CR_IPENDING] = deposit32(env->ctrl[CR_IPENDING], irq, 1, !!level);
cd2528de 71
b8f036a9 72 if (env->ctrl[CR_IPENDING]) {
cd2528de 73 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
b72c9d59 74 } else {
cd2528de
PM
75 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
76 }
77}
78#endif
79
032c76bc
CW
80static void nios2_cpu_initfn(Object *obj)
81{
032c76bc 82 Nios2CPU *cpu = NIOS2_CPU(obj);
032c76bc 83
7506ed90 84 cpu_set_cpustate_pointers(cpu);
032c76bc
CW
85
86#if !defined(CONFIG_USER_ONLY)
7506ed90 87 mmu_init(&cpu->env);
cd2528de
PM
88
89 /*
90 * These interrupt lines model the IIC (internal interrupt
91 * controller). QEMU does not currently support the EIC
92 * (external interrupt controller) -- if we did it would be
93 * a separate device in hw/intc with a custom interface to
94 * the CPU, and boards using it would not wire up these IRQ lines.
95 */
96 qdev_init_gpio_in_named(DEVICE(cpu), nios2_cpu_set_irq, "IRQ", 32);
032c76bc 97#endif
032c76bc
CW
98}
99
da9cbe02 100static ObjectClass *nios2_cpu_class_by_name(const char *cpu_model)
032c76bc 101{
da9cbe02 102 return object_class_by_name(TYPE_NIOS2_CPU);
032c76bc
CW
103}
104
796945d5
RH
105static void realize_cr_status(CPUState *cs)
106{
107 Nios2CPU *cpu = NIOS2_CPU(cs);
108
109 /* Begin with all fields of all registers are reserved. */
110 memset(cpu->cr_state, 0, sizeof(cpu->cr_state));
111
112 /*
113 * The combination of writable and readonly is the set of all
114 * non-reserved fields. We apply writable as a mask to bits,
115 * and merge in existing readonly bits, before storing.
116 */
117#define WR_REG(C) cpu->cr_state[C].writable = -1
118#define RO_REG(C) cpu->cr_state[C].readonly = -1
119#define WR_FIELD(C, F) cpu->cr_state[C].writable |= R_##C##_##F##_MASK
120#define RO_FIELD(C, F) cpu->cr_state[C].readonly |= R_##C##_##F##_MASK
121
122 WR_FIELD(CR_STATUS, PIE);
123 WR_REG(CR_ESTATUS);
124 WR_REG(CR_BSTATUS);
125 RO_REG(CR_CPUID);
126 RO_REG(CR_EXCEPTION);
127 WR_REG(CR_BADADDR);
128
129 /* TODO: These control registers are not present with the EIC. */
2de70d2d 130 RO_FIELD(CR_STATUS, RSIE);
796945d5
RH
131 WR_REG(CR_IENABLE);
132 RO_REG(CR_IPENDING);
133
134 if (cpu->mmu_present) {
135 WR_FIELD(CR_STATUS, U);
136 WR_FIELD(CR_STATUS, EH);
137
138 WR_FIELD(CR_PTEADDR, VPN);
139 WR_FIELD(CR_PTEADDR, PTBASE);
140
141 RO_FIELD(CR_TLBMISC, D);
142 RO_FIELD(CR_TLBMISC, PERM);
143 RO_FIELD(CR_TLBMISC, BAD);
144 RO_FIELD(CR_TLBMISC, DBL);
145 WR_FIELD(CR_TLBMISC, PID);
146 WR_FIELD(CR_TLBMISC, WE);
147 WR_FIELD(CR_TLBMISC, RD);
148 WR_FIELD(CR_TLBMISC, WAY);
149
150 WR_REG(CR_TLBACC);
151 }
152
153 /*
154 * TODO: ECC (config, eccinj) and MPU (config, mpubase, mpuacc) are
155 * unimplemented, so their corresponding control regs remain reserved.
156 */
157
158#undef WR_REG
159#undef RO_REG
160#undef WR_FIELD
161#undef RO_FIELD
162}
163
032c76bc
CW
164static void nios2_cpu_realizefn(DeviceState *dev, Error **errp)
165{
166 CPUState *cs = CPU(dev);
b05550af 167 Nios2CPU *cpu = NIOS2_CPU(cs);
032c76bc
CW
168 Nios2CPUClass *ncc = NIOS2_CPU_GET_CLASS(dev);
169 Error *local_err = NULL;
170
171 cpu_exec_realizefn(cs, &local_err);
172 if (local_err != NULL) {
173 error_propagate(errp, local_err);
174 return;
175 }
176
796945d5 177 realize_cr_status(cs);
032c76bc
CW
178 qemu_init_vcpu(cs);
179 cpu_reset(cs);
180
b05550af
RH
181 /* We have reserved storage for cpuid; might as well use it. */
182 cpu->env.ctrl[CR_CPUID] = cs->cpu_index;
183
032c76bc
CW
184 ncc->parent_realize(dev, errp);
185}
186
dabfe133 187#ifndef CONFIG_USER_ONLY
032c76bc
CW
188static bool nios2_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
189{
190 Nios2CPU *cpu = NIOS2_CPU(cs);
191 CPUNios2State *env = &cpu->env;
192
193 if ((interrupt_request & CPU_INTERRUPT_HARD) &&
b8f036a9
RH
194 (env->ctrl[CR_STATUS] & CR_STATUS_PIE) &&
195 (env->ctrl[CR_IPENDING] & env->ctrl[CR_IENABLE])) {
032c76bc
CW
196 cs->exception_index = EXCP_IRQ;
197 nios2_cpu_do_interrupt(cs);
198 return true;
199 }
200 return false;
201}
dabfe133 202#endif /* !CONFIG_USER_ONLY */
032c76bc
CW
203
204static void nios2_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
205{
206 /* NOTE: NiosII R2 is not supported yet. */
207 info->mach = bfd_arch_nios2;
dcc99bd8 208 info->print_insn = print_insn_nios2;
032c76bc
CW
209}
210
a010bdbe 211static int nios2_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
032c76bc
CW
212{
213 Nios2CPU *cpu = NIOS2_CPU(cs);
032c76bc 214 CPUNios2State *env = &cpu->env;
796945d5 215 uint32_t val;
032c76bc
CW
216
217 if (n < 32) { /* GP regs */
796945d5 218 val = env->regs[n];
032c76bc 219 } else if (n == 32) { /* PC */
796945d5 220 val = env->pc;
032c76bc 221 } else if (n < 49) { /* Status regs */
796945d5
RH
222 unsigned cr = n - 33;
223 if (nios2_cr_reserved(&cpu->cr_state[cr])) {
224 val = 0;
225 } else {
226 val = env->ctrl[n - 33];
227 }
228 } else {
229 /* Invalid regs */
230 return 0;
032c76bc
CW
231 }
232
796945d5 233 return gdb_get_reg32(mem_buf, val);
032c76bc
CW
234}
235
236static int nios2_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
237{
238 Nios2CPU *cpu = NIOS2_CPU(cs);
239 CPUClass *cc = CPU_GET_CLASS(cs);
240 CPUNios2State *env = &cpu->env;
796945d5 241 uint32_t val;
032c76bc
CW
242
243 if (n > cc->gdb_num_core_regs) {
244 return 0;
245 }
796945d5 246 val = ldl_p(mem_buf);
032c76bc
CW
247
248 if (n < 32) { /* GP regs */
796945d5 249 env->regs[n] = val;
032c76bc 250 } else if (n == 32) { /* PC */
796945d5 251 env->pc = val;
032c76bc 252 } else if (n < 49) { /* Status regs */
796945d5
RH
253 unsigned cr = n - 33;
254 /* ??? Maybe allow the debugger to write to readonly fields. */
255 val &= cpu->cr_state[cr].writable;
256 val |= cpu->cr_state[cr].readonly & env->ctrl[cr];
257 env->ctrl[cr] = val;
258 } else {
259 g_assert_not_reached();
032c76bc
CW
260 }
261
262 return 4;
263}
264
265static Property nios2_properties[] = {
266 DEFINE_PROP_BOOL("mmu_present", Nios2CPU, mmu_present, true),
267 /* ALTR,pid-num-bits */
268 DEFINE_PROP_UINT32("mmu_pid_num_bits", Nios2CPU, pid_num_bits, 8),
269 /* ALTR,tlb-num-ways */
270 DEFINE_PROP_UINT32("mmu_tlb_num_ways", Nios2CPU, tlb_num_ways, 16),
271 /* ALTR,tlb-num-entries */
272 DEFINE_PROP_UINT32("mmu_pid_num_entries", Nios2CPU, tlb_num_entries, 256),
273 DEFINE_PROP_END_OF_LIST(),
274};
275
8b80bd28
PMD
276#ifndef CONFIG_USER_ONLY
277#include "hw/core/sysemu-cpu-ops.h"
278
279static const struct SysemuCPUOps nios2_sysemu_ops = {
08928c6d 280 .get_phys_page_debug = nios2_cpu_get_phys_page_debug,
8b80bd28
PMD
281};
282#endif
283
78271684
CF
284#include "hw/core/tcg-cpu-ops.h"
285
11906557 286static const struct TCGCPUOps nios2_tcg_ops = {
78271684 287 .initialize = nios2_tcg_init,
78271684 288
fb4de9d2 289#ifndef CONFIG_USER_ONLY
fac94cb3 290 .tlb_fill = nios2_cpu_tlb_fill,
dabfe133 291 .cpu_exec_interrupt = nios2_cpu_exec_interrupt,
78271684
CF
292 .do_interrupt = nios2_cpu_do_interrupt,
293 .do_unaligned_access = nios2_cpu_do_unaligned_access,
294#endif /* !CONFIG_USER_ONLY */
295};
032c76bc
CW
296
297static void nios2_cpu_class_init(ObjectClass *oc, void *data)
298{
299 DeviceClass *dc = DEVICE_CLASS(oc);
300 CPUClass *cc = CPU_CLASS(oc);
301 Nios2CPUClass *ncc = NIOS2_CPU_CLASS(oc);
302
bf853881
PMD
303 device_class_set_parent_realize(dc, nios2_cpu_realizefn,
304 &ncc->parent_realize);
4f67d30b 305 device_class_set_props(dc, nios2_properties);
781c67ca 306 device_class_set_parent_reset(dc, nios2_cpu_reset, &ncc->parent_reset);
032c76bc 307
da9cbe02 308 cc->class_by_name = nios2_cpu_class_by_name;
032c76bc 309 cc->has_work = nios2_cpu_has_work;
032c76bc
CW
310 cc->dump_state = nios2_cpu_dump_state;
311 cc->set_pc = nios2_cpu_set_pc;
312 cc->disas_set_info = nios2_cpu_disas_set_info;
0137c93f 313#ifndef CONFIG_USER_ONLY
8b80bd28 314 cc->sysemu_ops = &nios2_sysemu_ops;
032c76bc
CW
315#endif
316 cc->gdb_read_register = nios2_cpu_gdb_read_register;
317 cc->gdb_write_register = nios2_cpu_gdb_write_register;
318 cc->gdb_num_core_regs = 49;
78271684 319 cc->tcg_ops = &nios2_tcg_ops;
032c76bc
CW
320}
321
322static const TypeInfo nios2_cpu_type_info = {
323 .name = TYPE_NIOS2_CPU,
324 .parent = TYPE_CPU,
325 .instance_size = sizeof(Nios2CPU),
326 .instance_init = nios2_cpu_initfn,
327 .class_size = sizeof(Nios2CPUClass),
328 .class_init = nios2_cpu_class_init,
329};
330
331static void nios2_cpu_register_types(void)
332{
333 type_register_static(&nios2_cpu_type_info);
334}
335
336type_init(nios2_cpu_register_types)