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 "exec/gdbstub.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 bool nios2_cpu_has_work(CPUState
*cs
)
39 return cs
->interrupt_request
& CPU_INTERRUPT_HARD
;
42 static void nios2_cpu_reset(DeviceState
*dev
)
44 CPUState
*cs
= CPU(dev
);
45 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
46 Nios2CPUClass
*ncc
= NIOS2_CPU_GET_CLASS(cpu
);
47 CPUNios2State
*env
= &cpu
->env
;
49 ncc
->parent_reset(dev
);
51 memset(env
->ctrl
, 0, sizeof(env
->ctrl
));
52 env
->pc
= cpu
->reset_addr
;
54 #if defined(CONFIG_USER_ONLY)
55 /* Start in user mode with interrupts enabled. */
56 env
->ctrl
[CR_STATUS
] = CR_STATUS_RSIE
| CR_STATUS_U
| CR_STATUS_PIE
;
57 memset(env
->regs
, 0, sizeof(env
->regs
));
59 env
->ctrl
[CR_STATUS
] = CR_STATUS_RSIE
;
60 nios2_update_crs(env
);
61 memset(env
->shadow_regs
, 0, sizeof(env
->shadow_regs
));
65 #ifndef CONFIG_USER_ONLY
66 static void eic_set_irq(void *opaque
, int irq
, int level
)
68 Nios2CPU
*cpu
= opaque
;
69 CPUState
*cs
= CPU(cpu
);
72 cpu_interrupt(cs
, CPU_INTERRUPT_HARD
);
74 cpu_reset_interrupt(cs
, CPU_INTERRUPT_HARD
);
78 static void iic_set_irq(void *opaque
, int irq
, int level
)
80 Nios2CPU
*cpu
= opaque
;
81 CPUNios2State
*env
= &cpu
->env
;
82 CPUState
*cs
= CPU(cpu
);
84 env
->ctrl
[CR_IPENDING
] = deposit32(env
->ctrl
[CR_IPENDING
], irq
, 1, !!level
);
86 if (env
->ctrl
[CR_IPENDING
]) {
87 cpu_interrupt(cs
, CPU_INTERRUPT_HARD
);
89 cpu_reset_interrupt(cs
, CPU_INTERRUPT_HARD
);
94 static void nios2_cpu_initfn(Object
*obj
)
96 Nios2CPU
*cpu
= NIOS2_CPU(obj
);
98 cpu_set_cpustate_pointers(cpu
);
100 #if !defined(CONFIG_USER_ONLY)
105 static ObjectClass
*nios2_cpu_class_by_name(const char *cpu_model
)
107 return object_class_by_name(TYPE_NIOS2_CPU
);
110 static void realize_cr_status(CPUState
*cs
)
112 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
114 /* Begin with all fields of all registers are reserved. */
115 memset(cpu
->cr_state
, 0, sizeof(cpu
->cr_state
));
118 * The combination of writable and readonly is the set of all
119 * non-reserved fields. We apply writable as a mask to bits,
120 * and merge in existing readonly bits, before storing.
122 #define WR_REG(C) cpu->cr_state[C].writable = -1
123 #define RO_REG(C) cpu->cr_state[C].readonly = -1
124 #define WR_FIELD(C, F) cpu->cr_state[C].writable |= R_##C##_##F##_MASK
125 #define RO_FIELD(C, F) cpu->cr_state[C].readonly |= R_##C##_##F##_MASK
127 WR_FIELD(CR_STATUS
, PIE
);
131 RO_REG(CR_EXCEPTION
);
134 if (cpu
->eic_present
) {
135 WR_FIELD(CR_STATUS
, RSIE
);
136 RO_FIELD(CR_STATUS
, NMI
);
137 WR_FIELD(CR_STATUS
, PRS
);
138 RO_FIELD(CR_STATUS
, CRS
);
139 WR_FIELD(CR_STATUS
, IL
);
140 WR_FIELD(CR_STATUS
, IH
);
142 RO_FIELD(CR_STATUS
, RSIE
);
147 if (cpu
->mmu_present
) {
148 WR_FIELD(CR_STATUS
, U
);
149 WR_FIELD(CR_STATUS
, EH
);
151 WR_FIELD(CR_PTEADDR
, VPN
);
152 WR_FIELD(CR_PTEADDR
, PTBASE
);
154 RO_FIELD(CR_TLBMISC
, D
);
155 RO_FIELD(CR_TLBMISC
, PERM
);
156 RO_FIELD(CR_TLBMISC
, BAD
);
157 RO_FIELD(CR_TLBMISC
, DBL
);
158 WR_FIELD(CR_TLBMISC
, PID
);
159 WR_FIELD(CR_TLBMISC
, WE
);
160 WR_FIELD(CR_TLBMISC
, RD
);
161 WR_FIELD(CR_TLBMISC
, WAY
);
167 * TODO: ECC (config, eccinj) and MPU (config, mpubase, mpuacc) are
168 * unimplemented, so their corresponding control regs remain reserved.
177 static void nios2_cpu_realizefn(DeviceState
*dev
, Error
**errp
)
179 CPUState
*cs
= CPU(dev
);
180 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
181 Nios2CPUClass
*ncc
= NIOS2_CPU_GET_CLASS(dev
);
182 Error
*local_err
= NULL
;
184 #ifndef CONFIG_USER_ONLY
185 if (cpu
->eic_present
) {
186 qdev_init_gpio_in_named(DEVICE(cpu
), eic_set_irq
, "EIC", 1);
188 qdev_init_gpio_in_named(DEVICE(cpu
), iic_set_irq
, "IRQ", 32);
192 cpu_exec_realizefn(cs
, &local_err
);
193 if (local_err
!= NULL
) {
194 error_propagate(errp
, local_err
);
198 realize_cr_status(cs
);
202 /* We have reserved storage for cpuid; might as well use it. */
203 cpu
->env
.ctrl
[CR_CPUID
] = cs
->cpu_index
;
205 ncc
->parent_realize(dev
, errp
);
208 #ifndef CONFIG_USER_ONLY
209 static bool eic_take_interrupt(Nios2CPU
*cpu
)
211 CPUNios2State
*env
= &cpu
->env
;
212 const uint32_t status
= env
->ctrl
[CR_STATUS
];
215 return !(status
& CR_STATUS_NMI
);
217 if (!(status
& CR_STATUS_PIE
)) {
220 if (cpu
->ril
<= FIELD_EX32(status
, CR_STATUS
, IL
)) {
223 if (cpu
->rrs
!= FIELD_EX32(status
, CR_STATUS
, CRS
)) {
226 return status
& CR_STATUS_RSIE
;
229 static bool iic_take_interrupt(Nios2CPU
*cpu
)
231 CPUNios2State
*env
= &cpu
->env
;
233 if (!(env
->ctrl
[CR_STATUS
] & CR_STATUS_PIE
)) {
236 return env
->ctrl
[CR_IPENDING
] & env
->ctrl
[CR_IENABLE
];
239 static bool nios2_cpu_exec_interrupt(CPUState
*cs
, int interrupt_request
)
241 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
243 if (interrupt_request
& CPU_INTERRUPT_HARD
) {
245 ? eic_take_interrupt(cpu
)
246 : iic_take_interrupt(cpu
)) {
247 cs
->exception_index
= EXCP_IRQ
;
248 nios2_cpu_do_interrupt(cs
);
254 #endif /* !CONFIG_USER_ONLY */
256 static void nios2_cpu_disas_set_info(CPUState
*cpu
, disassemble_info
*info
)
258 /* NOTE: NiosII R2 is not supported yet. */
259 info
->mach
= bfd_arch_nios2
;
260 info
->print_insn
= print_insn_nios2
;
263 static int nios2_cpu_gdb_read_register(CPUState
*cs
, GByteArray
*mem_buf
, int n
)
265 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
266 CPUNios2State
*env
= &cpu
->env
;
269 if (n
< 32) { /* GP regs */
271 } else if (n
== 32) { /* PC */
273 } else if (n
< 49) { /* Status regs */
274 unsigned cr
= n
- 33;
275 if (nios2_cr_reserved(&cpu
->cr_state
[cr
])) {
278 val
= env
->ctrl
[n
- 33];
285 return gdb_get_reg32(mem_buf
, val
);
288 static int nios2_cpu_gdb_write_register(CPUState
*cs
, uint8_t *mem_buf
, int n
)
290 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
291 CPUClass
*cc
= CPU_GET_CLASS(cs
);
292 CPUNios2State
*env
= &cpu
->env
;
295 if (n
> cc
->gdb_num_core_regs
) {
298 val
= ldl_p(mem_buf
);
300 if (n
< 32) { /* GP regs */
302 } else if (n
== 32) { /* PC */
304 } else if (n
< 49) { /* Status regs */
305 unsigned cr
= n
- 33;
306 /* ??? Maybe allow the debugger to write to readonly fields. */
307 val
&= cpu
->cr_state
[cr
].writable
;
308 val
|= cpu
->cr_state
[cr
].readonly
& env
->ctrl
[cr
];
311 g_assert_not_reached();
317 static Property nios2_properties
[] = {
318 DEFINE_PROP_BOOL("diverr_present", Nios2CPU
, diverr_present
, true),
319 DEFINE_PROP_BOOL("mmu_present", Nios2CPU
, mmu_present
, true),
320 /* ALTR,pid-num-bits */
321 DEFINE_PROP_UINT32("mmu_pid_num_bits", Nios2CPU
, pid_num_bits
, 8),
322 /* ALTR,tlb-num-ways */
323 DEFINE_PROP_UINT32("mmu_tlb_num_ways", Nios2CPU
, tlb_num_ways
, 16),
324 /* ALTR,tlb-num-entries */
325 DEFINE_PROP_UINT32("mmu_pid_num_entries", Nios2CPU
, tlb_num_entries
, 256),
326 DEFINE_PROP_END_OF_LIST(),
329 #ifndef CONFIG_USER_ONLY
330 #include "hw/core/sysemu-cpu-ops.h"
332 static const struct SysemuCPUOps nios2_sysemu_ops
= {
333 .get_phys_page_debug
= nios2_cpu_get_phys_page_debug
,
337 #include "hw/core/tcg-cpu-ops.h"
339 static const struct TCGCPUOps nios2_tcg_ops
= {
340 .initialize
= nios2_tcg_init
,
342 #ifndef CONFIG_USER_ONLY
343 .tlb_fill
= nios2_cpu_tlb_fill
,
344 .cpu_exec_interrupt
= nios2_cpu_exec_interrupt
,
345 .do_interrupt
= nios2_cpu_do_interrupt
,
346 .do_unaligned_access
= nios2_cpu_do_unaligned_access
,
347 #endif /* !CONFIG_USER_ONLY */
350 static void nios2_cpu_class_init(ObjectClass
*oc
, void *data
)
352 DeviceClass
*dc
= DEVICE_CLASS(oc
);
353 CPUClass
*cc
= CPU_CLASS(oc
);
354 Nios2CPUClass
*ncc
= NIOS2_CPU_CLASS(oc
);
356 device_class_set_parent_realize(dc
, nios2_cpu_realizefn
,
357 &ncc
->parent_realize
);
358 device_class_set_props(dc
, nios2_properties
);
359 device_class_set_parent_reset(dc
, nios2_cpu_reset
, &ncc
->parent_reset
);
361 cc
->class_by_name
= nios2_cpu_class_by_name
;
362 cc
->has_work
= nios2_cpu_has_work
;
363 cc
->dump_state
= nios2_cpu_dump_state
;
364 cc
->set_pc
= nios2_cpu_set_pc
;
365 cc
->disas_set_info
= nios2_cpu_disas_set_info
;
366 #ifndef CONFIG_USER_ONLY
367 cc
->sysemu_ops
= &nios2_sysemu_ops
;
369 cc
->gdb_read_register
= nios2_cpu_gdb_read_register
;
370 cc
->gdb_write_register
= nios2_cpu_gdb_write_register
;
371 cc
->gdb_num_core_regs
= 49;
372 cc
->tcg_ops
= &nios2_tcg_ops
;
375 static const TypeInfo nios2_cpu_type_info
= {
376 .name
= TYPE_NIOS2_CPU
,
378 .instance_size
= sizeof(Nios2CPU
),
379 .instance_init
= nios2_cpu_initfn
,
380 .class_size
= sizeof(Nios2CPUClass
),
381 .class_init
= nios2_cpu_class_init
,
384 static void nios2_cpu_register_types(void)
386 type_register_static(&nios2_cpu_type_info
);
389 type_init(nios2_cpu_register_types
)