4 * Copyright (c) 2012 Chris Wulff <crwulff@gmail.com>
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.
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.
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>
21 #include "qemu/osdep.h"
22 #include "qemu/module.h"
23 #include "qapi/error.h"
26 #include "gdbstub/helpers.h"
27 #include "hw/qdev-properties.h"
29 static void nios2_cpu_set_pc(CPUState
*cs
, vaddr value
)
31 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
32 CPUNios2State
*env
= &cpu
->env
;
37 static vaddr
nios2_cpu_get_pc(CPUState
*cs
)
39 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
40 CPUNios2State
*env
= &cpu
->env
;
45 static void nios2_restore_state_to_opc(CPUState
*cs
,
46 const TranslationBlock
*tb
,
49 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
50 CPUNios2State
*env
= &cpu
->env
;
55 static bool nios2_cpu_has_work(CPUState
*cs
)
57 return cs
->interrupt_request
& CPU_INTERRUPT_HARD
;
60 static void nios2_cpu_reset_hold(Object
*obj
)
62 CPUState
*cs
= CPU(obj
);
63 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
64 Nios2CPUClass
*ncc
= NIOS2_CPU_GET_CLASS(cpu
);
65 CPUNios2State
*env
= &cpu
->env
;
67 if (ncc
->parent_phases
.hold
) {
68 ncc
->parent_phases
.hold(obj
);
71 memset(env
->ctrl
, 0, sizeof(env
->ctrl
));
72 env
->pc
= cpu
->reset_addr
;
74 #if defined(CONFIG_USER_ONLY)
75 /* Start in user mode with interrupts enabled. */
76 env
->ctrl
[CR_STATUS
] = CR_STATUS_RSIE
| CR_STATUS_U
| CR_STATUS_PIE
;
77 memset(env
->regs
, 0, sizeof(env
->regs
));
79 env
->ctrl
[CR_STATUS
] = CR_STATUS_RSIE
;
80 nios2_update_crs(env
);
81 memset(env
->shadow_regs
, 0, sizeof(env
->shadow_regs
));
85 #ifndef CONFIG_USER_ONLY
86 static void eic_set_irq(void *opaque
, int irq
, int level
)
88 Nios2CPU
*cpu
= opaque
;
89 CPUState
*cs
= CPU(cpu
);
92 cpu_interrupt(cs
, CPU_INTERRUPT_HARD
);
94 cpu_reset_interrupt(cs
, CPU_INTERRUPT_HARD
);
98 static void iic_set_irq(void *opaque
, int irq
, int level
)
100 Nios2CPU
*cpu
= opaque
;
101 CPUNios2State
*env
= &cpu
->env
;
102 CPUState
*cs
= CPU(cpu
);
104 env
->ctrl
[CR_IPENDING
] = deposit32(env
->ctrl
[CR_IPENDING
], irq
, 1, !!level
);
106 if (env
->ctrl
[CR_IPENDING
]) {
107 cpu_interrupt(cs
, CPU_INTERRUPT_HARD
);
109 cpu_reset_interrupt(cs
, CPU_INTERRUPT_HARD
);
114 static void nios2_cpu_initfn(Object
*obj
)
116 Nios2CPU
*cpu
= NIOS2_CPU(obj
);
118 cpu_set_cpustate_pointers(cpu
);
120 #if !defined(CONFIG_USER_ONLY)
125 static ObjectClass
*nios2_cpu_class_by_name(const char *cpu_model
)
127 return object_class_by_name(TYPE_NIOS2_CPU
);
130 static void realize_cr_status(CPUState
*cs
)
132 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
134 /* Begin with all fields of all registers are reserved. */
135 memset(cpu
->cr_state
, 0, sizeof(cpu
->cr_state
));
138 * The combination of writable and readonly is the set of all
139 * non-reserved fields. We apply writable as a mask to bits,
140 * and merge in existing readonly bits, before storing.
142 #define WR_REG(C) cpu->cr_state[C].writable = -1
143 #define RO_REG(C) cpu->cr_state[C].readonly = -1
144 #define WR_FIELD(C, F) cpu->cr_state[C].writable |= R_##C##_##F##_MASK
145 #define RO_FIELD(C, F) cpu->cr_state[C].readonly |= R_##C##_##F##_MASK
147 WR_FIELD(CR_STATUS
, PIE
);
151 RO_REG(CR_EXCEPTION
);
154 if (cpu
->eic_present
) {
155 WR_FIELD(CR_STATUS
, RSIE
);
156 RO_FIELD(CR_STATUS
, NMI
);
157 WR_FIELD(CR_STATUS
, PRS
);
158 RO_FIELD(CR_STATUS
, CRS
);
159 WR_FIELD(CR_STATUS
, IL
);
160 WR_FIELD(CR_STATUS
, IH
);
162 RO_FIELD(CR_STATUS
, RSIE
);
167 if (cpu
->mmu_present
) {
168 WR_FIELD(CR_STATUS
, U
);
169 WR_FIELD(CR_STATUS
, EH
);
171 WR_FIELD(CR_PTEADDR
, VPN
);
172 WR_FIELD(CR_PTEADDR
, PTBASE
);
174 RO_FIELD(CR_TLBMISC
, D
);
175 RO_FIELD(CR_TLBMISC
, PERM
);
176 RO_FIELD(CR_TLBMISC
, BAD
);
177 RO_FIELD(CR_TLBMISC
, DBL
);
178 WR_FIELD(CR_TLBMISC
, PID
);
179 WR_FIELD(CR_TLBMISC
, WE
);
180 WR_FIELD(CR_TLBMISC
, RD
);
181 WR_FIELD(CR_TLBMISC
, WAY
);
187 * TODO: ECC (config, eccinj) and MPU (config, mpubase, mpuacc) are
188 * unimplemented, so their corresponding control regs remain reserved.
197 static void nios2_cpu_realizefn(DeviceState
*dev
, Error
**errp
)
199 CPUState
*cs
= CPU(dev
);
200 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
201 Nios2CPUClass
*ncc
= NIOS2_CPU_GET_CLASS(dev
);
202 Error
*local_err
= NULL
;
204 #ifndef CONFIG_USER_ONLY
205 if (cpu
->eic_present
) {
206 qdev_init_gpio_in_named(DEVICE(cpu
), eic_set_irq
, "EIC", 1);
208 qdev_init_gpio_in_named(DEVICE(cpu
), iic_set_irq
, "IRQ", 32);
212 cpu_exec_realizefn(cs
, &local_err
);
213 if (local_err
!= NULL
) {
214 error_propagate(errp
, local_err
);
218 realize_cr_status(cs
);
222 /* We have reserved storage for cpuid; might as well use it. */
223 cpu
->env
.ctrl
[CR_CPUID
] = cs
->cpu_index
;
225 ncc
->parent_realize(dev
, errp
);
228 #ifndef CONFIG_USER_ONLY
229 static bool eic_take_interrupt(Nios2CPU
*cpu
)
231 CPUNios2State
*env
= &cpu
->env
;
232 const uint32_t status
= env
->ctrl
[CR_STATUS
];
235 return !(status
& CR_STATUS_NMI
);
237 if (!(status
& CR_STATUS_PIE
)) {
240 if (cpu
->ril
<= FIELD_EX32(status
, CR_STATUS
, IL
)) {
243 if (cpu
->rrs
!= FIELD_EX32(status
, CR_STATUS
, CRS
)) {
246 return status
& CR_STATUS_RSIE
;
249 static bool iic_take_interrupt(Nios2CPU
*cpu
)
251 CPUNios2State
*env
= &cpu
->env
;
253 if (!(env
->ctrl
[CR_STATUS
] & CR_STATUS_PIE
)) {
256 return env
->ctrl
[CR_IPENDING
] & env
->ctrl
[CR_IENABLE
];
259 static bool nios2_cpu_exec_interrupt(CPUState
*cs
, int interrupt_request
)
261 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
263 if (interrupt_request
& CPU_INTERRUPT_HARD
) {
265 ? eic_take_interrupt(cpu
)
266 : iic_take_interrupt(cpu
)) {
267 cs
->exception_index
= EXCP_IRQ
;
268 nios2_cpu_do_interrupt(cs
);
274 #endif /* !CONFIG_USER_ONLY */
276 static void nios2_cpu_disas_set_info(CPUState
*cpu
, disassemble_info
*info
)
278 /* NOTE: NiosII R2 is not supported yet. */
279 info
->mach
= bfd_arch_nios2
;
280 info
->print_insn
= print_insn_nios2
;
283 static int nios2_cpu_gdb_read_register(CPUState
*cs
, GByteArray
*mem_buf
, int n
)
285 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
286 CPUNios2State
*env
= &cpu
->env
;
289 if (n
< 32) { /* GP regs */
291 } else if (n
== 32) { /* PC */
293 } else if (n
< 49) { /* Status regs */
294 unsigned cr
= n
- 33;
295 if (nios2_cr_reserved(&cpu
->cr_state
[cr
])) {
298 val
= env
->ctrl
[n
- 33];
305 return gdb_get_reg32(mem_buf
, val
);
308 static int nios2_cpu_gdb_write_register(CPUState
*cs
, uint8_t *mem_buf
, int n
)
310 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
311 CPUClass
*cc
= CPU_GET_CLASS(cs
);
312 CPUNios2State
*env
= &cpu
->env
;
315 if (n
> cc
->gdb_num_core_regs
) {
318 val
= ldl_p(mem_buf
);
320 if (n
< 32) { /* GP regs */
322 } else if (n
== 32) { /* PC */
324 } else if (n
< 49) { /* Status regs */
325 unsigned cr
= n
- 33;
326 /* ??? Maybe allow the debugger to write to readonly fields. */
327 val
&= cpu
->cr_state
[cr
].writable
;
328 val
|= cpu
->cr_state
[cr
].readonly
& env
->ctrl
[cr
];
331 g_assert_not_reached();
337 static Property nios2_properties
[] = {
338 DEFINE_PROP_BOOL("diverr_present", Nios2CPU
, diverr_present
, true),
339 DEFINE_PROP_BOOL("mmu_present", Nios2CPU
, mmu_present
, true),
340 /* ALTR,pid-num-bits */
341 DEFINE_PROP_UINT32("mmu_pid_num_bits", Nios2CPU
, pid_num_bits
, 8),
342 /* ALTR,tlb-num-ways */
343 DEFINE_PROP_UINT32("mmu_tlb_num_ways", Nios2CPU
, tlb_num_ways
, 16),
344 /* ALTR,tlb-num-entries */
345 DEFINE_PROP_UINT32("mmu_pid_num_entries", Nios2CPU
, tlb_num_entries
, 256),
346 DEFINE_PROP_END_OF_LIST(),
349 #ifndef CONFIG_USER_ONLY
350 #include "hw/core/sysemu-cpu-ops.h"
352 static const struct SysemuCPUOps nios2_sysemu_ops
= {
353 .get_phys_page_debug
= nios2_cpu_get_phys_page_debug
,
357 #include "hw/core/tcg-cpu-ops.h"
359 static const struct TCGCPUOps nios2_tcg_ops
= {
360 .initialize
= nios2_tcg_init
,
361 .restore_state_to_opc
= nios2_restore_state_to_opc
,
363 #ifndef CONFIG_USER_ONLY
364 .tlb_fill
= nios2_cpu_tlb_fill
,
365 .cpu_exec_interrupt
= nios2_cpu_exec_interrupt
,
366 .do_interrupt
= nios2_cpu_do_interrupt
,
367 .do_unaligned_access
= nios2_cpu_do_unaligned_access
,
368 #endif /* !CONFIG_USER_ONLY */
371 static void nios2_cpu_class_init(ObjectClass
*oc
, void *data
)
373 DeviceClass
*dc
= DEVICE_CLASS(oc
);
374 CPUClass
*cc
= CPU_CLASS(oc
);
375 Nios2CPUClass
*ncc
= NIOS2_CPU_CLASS(oc
);
376 ResettableClass
*rc
= RESETTABLE_CLASS(oc
);
378 device_class_set_parent_realize(dc
, nios2_cpu_realizefn
,
379 &ncc
->parent_realize
);
380 device_class_set_props(dc
, nios2_properties
);
381 resettable_class_set_parent_phases(rc
, NULL
, nios2_cpu_reset_hold
, NULL
,
382 &ncc
->parent_phases
);
384 cc
->class_by_name
= nios2_cpu_class_by_name
;
385 cc
->has_work
= nios2_cpu_has_work
;
386 cc
->dump_state
= nios2_cpu_dump_state
;
387 cc
->set_pc
= nios2_cpu_set_pc
;
388 cc
->get_pc
= nios2_cpu_get_pc
;
389 cc
->disas_set_info
= nios2_cpu_disas_set_info
;
390 #ifndef CONFIG_USER_ONLY
391 cc
->sysemu_ops
= &nios2_sysemu_ops
;
393 cc
->gdb_read_register
= nios2_cpu_gdb_read_register
;
394 cc
->gdb_write_register
= nios2_cpu_gdb_write_register
;
395 cc
->gdb_num_core_regs
= 49;
396 cc
->tcg_ops
= &nios2_tcg_ops
;
399 static const TypeInfo nios2_cpu_type_info
= {
400 .name
= TYPE_NIOS2_CPU
,
402 .instance_size
= sizeof(Nios2CPU
),
403 .instance_init
= nios2_cpu_initfn
,
404 .class_size
= sizeof(Nios2CPUClass
),
405 .class_init
= nios2_cpu_class_init
,
408 static void nios2_cpu_register_types(void)
410 type_register_static(&nios2_cpu_type_info
);
413 type_init(nios2_cpu_register_types
)