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-common.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
;
34 env
->regs
[R_PC
] = value
;
37 static bool nios2_cpu_has_work(CPUState
*cs
)
39 return cs
->interrupt_request
& (CPU_INTERRUPT_HARD
| CPU_INTERRUPT_NMI
);
42 /* CPUClass::reset() */
43 static void nios2_cpu_reset(CPUState
*cs
)
45 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
46 Nios2CPUClass
*ncc
= NIOS2_CPU_GET_CLASS(cpu
);
47 CPUNios2State
*env
= &cpu
->env
;
49 if (qemu_loglevel_mask(CPU_LOG_RESET
)) {
50 qemu_log("CPU Reset (CPU %d)\n", cs
->cpu_index
);
54 ncc
->parent_reset(cs
);
56 memset(env
->regs
, 0, sizeof(uint32_t) * NUM_CORE_REGS
);
57 env
->regs
[R_PC
] = cpu
->reset_addr
;
59 #if defined(CONFIG_USER_ONLY)
60 /* Start in user mode with interrupts enabled. */
61 env
->regs
[CR_STATUS
] = CR_STATUS_U
| CR_STATUS_PIE
;
63 env
->regs
[CR_STATUS
] = 0;
67 static void nios2_cpu_initfn(Object
*obj
)
69 CPUState
*cs
= CPU(obj
);
70 Nios2CPU
*cpu
= NIOS2_CPU(obj
);
71 CPUNios2State
*env
= &cpu
->env
;
72 static bool tcg_initialized
;
76 #if !defined(CONFIG_USER_ONLY)
80 if (tcg_enabled() && !tcg_initialized
) {
81 tcg_initialized
= true;
86 Nios2CPU
*cpu_nios2_init(const char *cpu_model
)
88 Nios2CPU
*cpu
= NIOS2_CPU(object_new(TYPE_NIOS2_CPU
));
90 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
95 static void nios2_cpu_realizefn(DeviceState
*dev
, Error
**errp
)
97 CPUState
*cs
= CPU(dev
);
98 Nios2CPUClass
*ncc
= NIOS2_CPU_GET_CLASS(dev
);
99 Error
*local_err
= NULL
;
101 cpu_exec_realizefn(cs
, &local_err
);
102 if (local_err
!= NULL
) {
103 error_propagate(errp
, local_err
);
110 ncc
->parent_realize(dev
, errp
);
113 static bool nios2_cpu_exec_interrupt(CPUState
*cs
, int interrupt_request
)
115 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
116 CPUNios2State
*env
= &cpu
->env
;
118 if ((interrupt_request
& CPU_INTERRUPT_HARD
) &&
119 (env
->regs
[CR_STATUS
] & CR_STATUS_PIE
)) {
120 cs
->exception_index
= EXCP_IRQ
;
121 nios2_cpu_do_interrupt(cs
);
128 static void nios2_cpu_disas_set_info(CPUState
*cpu
, disassemble_info
*info
)
130 /* NOTE: NiosII R2 is not supported yet. */
131 info
->mach
= bfd_arch_nios2
;
132 #ifdef TARGET_WORDS_BIGENDIAN
133 info
->print_insn
= print_insn_big_nios2
;
135 info
->print_insn
= print_insn_little_nios2
;
139 static int nios2_cpu_gdb_read_register(CPUState
*cs
, uint8_t *mem_buf
, int n
)
141 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
142 CPUClass
*cc
= CPU_GET_CLASS(cs
);
143 CPUNios2State
*env
= &cpu
->env
;
145 if (n
> cc
->gdb_num_core_regs
) {
149 if (n
< 32) { /* GP regs */
150 return gdb_get_reg32(mem_buf
, env
->regs
[n
]);
151 } else if (n
== 32) { /* PC */
152 return gdb_get_reg32(mem_buf
, env
->regs
[R_PC
]);
153 } else if (n
< 49) { /* Status regs */
154 return gdb_get_reg32(mem_buf
, env
->regs
[n
- 1]);
161 static int nios2_cpu_gdb_write_register(CPUState
*cs
, uint8_t *mem_buf
, int n
)
163 Nios2CPU
*cpu
= NIOS2_CPU(cs
);
164 CPUClass
*cc
= CPU_GET_CLASS(cs
);
165 CPUNios2State
*env
= &cpu
->env
;
167 if (n
> cc
->gdb_num_core_regs
) {
171 if (n
< 32) { /* GP regs */
172 env
->regs
[n
] = ldl_p(mem_buf
);
173 } else if (n
== 32) { /* PC */
174 env
->regs
[R_PC
] = ldl_p(mem_buf
);
175 } else if (n
< 49) { /* Status regs */
176 env
->regs
[n
- 1] = ldl_p(mem_buf
);
182 static Property nios2_properties
[] = {
183 DEFINE_PROP_BOOL("mmu_present", Nios2CPU
, mmu_present
, true),
184 /* ALTR,pid-num-bits */
185 DEFINE_PROP_UINT32("mmu_pid_num_bits", Nios2CPU
, pid_num_bits
, 8),
186 /* ALTR,tlb-num-ways */
187 DEFINE_PROP_UINT32("mmu_tlb_num_ways", Nios2CPU
, tlb_num_ways
, 16),
188 /* ALTR,tlb-num-entries */
189 DEFINE_PROP_UINT32("mmu_pid_num_entries", Nios2CPU
, tlb_num_entries
, 256),
190 DEFINE_PROP_END_OF_LIST(),
194 static void nios2_cpu_class_init(ObjectClass
*oc
, void *data
)
196 DeviceClass
*dc
= DEVICE_CLASS(oc
);
197 CPUClass
*cc
= CPU_CLASS(oc
);
198 Nios2CPUClass
*ncc
= NIOS2_CPU_CLASS(oc
);
200 ncc
->parent_realize
= dc
->realize
;
201 dc
->realize
= nios2_cpu_realizefn
;
202 dc
->props
= nios2_properties
;
203 ncc
->parent_reset
= cc
->reset
;
204 cc
->reset
= nios2_cpu_reset
;
206 cc
->has_work
= nios2_cpu_has_work
;
207 cc
->do_interrupt
= nios2_cpu_do_interrupt
;
208 cc
->cpu_exec_interrupt
= nios2_cpu_exec_interrupt
;
209 cc
->dump_state
= nios2_cpu_dump_state
;
210 cc
->set_pc
= nios2_cpu_set_pc
;
211 cc
->disas_set_info
= nios2_cpu_disas_set_info
;
212 #ifdef CONFIG_USER_ONLY
213 cc
->handle_mmu_fault
= nios2_cpu_handle_mmu_fault
;
215 cc
->do_unaligned_access
= nios2_cpu_do_unaligned_access
;
216 cc
->get_phys_page_debug
= nios2_cpu_get_phys_page_debug
;
218 cc
->gdb_read_register
= nios2_cpu_gdb_read_register
;
219 cc
->gdb_write_register
= nios2_cpu_gdb_write_register
;
220 cc
->gdb_num_core_regs
= 49;
223 static const TypeInfo nios2_cpu_type_info
= {
224 .name
= TYPE_NIOS2_CPU
,
226 .instance_size
= sizeof(Nios2CPU
),
227 .instance_init
= nios2_cpu_initfn
,
228 .class_size
= sizeof(Nios2CPUClass
),
229 .class_init
= nios2_cpu_class_init
,
232 static void nios2_cpu_register_types(void)
234 type_register_static(&nios2_cpu_type_info
);
237 type_init(nios2_cpu_register_types
)