cpu.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /*
  2. * QEMU OpenRISC CPU
  3. *
  4. * Copyright (c) 2012 Jia Liu <proljc@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 <http://www.gnu.org/licenses/>.
  18. */
  19. #include "qemu/osdep.h"
  20. #include "qapi/error.h"
  21. #include "qemu/qemu-print.h"
  22. #include "cpu.h"
  23. #include "exec/exec-all.h"
  24. #include "exec/translation-block.h"
  25. #include "fpu/softfloat-helpers.h"
  26. #include "tcg/tcg.h"
  27. static void openrisc_cpu_set_pc(CPUState *cs, vaddr value)
  28. {
  29. OpenRISCCPU *cpu = OPENRISC_CPU(cs);
  30. cpu->env.pc = value;
  31. cpu->env.dflag = 0;
  32. }
  33. static vaddr openrisc_cpu_get_pc(CPUState *cs)
  34. {
  35. OpenRISCCPU *cpu = OPENRISC_CPU(cs);
  36. return cpu->env.pc;
  37. }
  38. static void openrisc_cpu_synchronize_from_tb(CPUState *cs,
  39. const TranslationBlock *tb)
  40. {
  41. OpenRISCCPU *cpu = OPENRISC_CPU(cs);
  42. tcg_debug_assert(!tcg_cflags_has(cs, CF_PCREL));
  43. cpu->env.pc = tb->pc;
  44. }
  45. static void openrisc_restore_state_to_opc(CPUState *cs,
  46. const TranslationBlock *tb,
  47. const uint64_t *data)
  48. {
  49. OpenRISCCPU *cpu = OPENRISC_CPU(cs);
  50. cpu->env.pc = data[0];
  51. cpu->env.dflag = data[1] & 1;
  52. if (data[1] & 2) {
  53. cpu->env.ppc = cpu->env.pc - 4;
  54. }
  55. }
  56. #ifndef CONFIG_USER_ONLY
  57. static bool openrisc_cpu_has_work(CPUState *cs)
  58. {
  59. return cs->interrupt_request & (CPU_INTERRUPT_HARD |
  60. CPU_INTERRUPT_TIMER);
  61. }
  62. #endif /* !CONFIG_USER_ONLY */
  63. static int openrisc_cpu_mmu_index(CPUState *cs, bool ifetch)
  64. {
  65. CPUOpenRISCState *env = cpu_env(cs);
  66. if (env->sr & (ifetch ? SR_IME : SR_DME)) {
  67. /* The mmu is enabled; test supervisor state. */
  68. return env->sr & SR_SM ? MMU_SUPERVISOR_IDX : MMU_USER_IDX;
  69. }
  70. return MMU_NOMMU_IDX; /* mmu is disabled */
  71. }
  72. static void openrisc_disas_set_info(CPUState *cpu, disassemble_info *info)
  73. {
  74. info->endian = BFD_ENDIAN_BIG;
  75. info->print_insn = print_insn_or1k;
  76. }
  77. static void openrisc_cpu_reset_hold(Object *obj, ResetType type)
  78. {
  79. CPUState *cs = CPU(obj);
  80. OpenRISCCPU *cpu = OPENRISC_CPU(cs);
  81. OpenRISCCPUClass *occ = OPENRISC_CPU_GET_CLASS(obj);
  82. if (occ->parent_phases.hold) {
  83. occ->parent_phases.hold(obj, type);
  84. }
  85. memset(&cpu->env, 0, offsetof(CPUOpenRISCState, end_reset_fields));
  86. cpu->env.pc = 0x100;
  87. cpu->env.sr = SR_FO | SR_SM;
  88. cpu->env.lock_addr = -1;
  89. cs->exception_index = -1;
  90. cpu_set_fpcsr(&cpu->env, 0);
  91. set_float_detect_tininess(float_tininess_before_rounding,
  92. &cpu->env.fp_status);
  93. /*
  94. * TODO: this is probably not the correct NaN propagation rule for
  95. * this architecture.
  96. */
  97. set_float_2nan_prop_rule(float_2nan_prop_x87, &cpu->env.fp_status);
  98. /* Default NaN: sign bit clear, frac msb set */
  99. set_float_default_nan_pattern(0b01000000, &cpu->env.fp_status);
  100. #ifndef CONFIG_USER_ONLY
  101. cpu->env.picmr = 0x00000000;
  102. cpu->env.picsr = 0x00000000;
  103. cpu->env.ttmr = 0x00000000;
  104. #endif
  105. }
  106. #ifndef CONFIG_USER_ONLY
  107. static void openrisc_cpu_set_irq(void *opaque, int irq, int level)
  108. {
  109. OpenRISCCPU *cpu = (OpenRISCCPU *)opaque;
  110. CPUState *cs = CPU(cpu);
  111. uint32_t irq_bit;
  112. if (irq > 31 || irq < 0) {
  113. return;
  114. }
  115. irq_bit = 1U << irq;
  116. if (level) {
  117. cpu->env.picsr |= irq_bit;
  118. } else {
  119. cpu->env.picsr &= ~irq_bit;
  120. }
  121. if (cpu->env.picsr & cpu->env.picmr) {
  122. cpu_interrupt(cs, CPU_INTERRUPT_HARD);
  123. } else {
  124. cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
  125. }
  126. }
  127. #endif
  128. static void openrisc_cpu_realizefn(DeviceState *dev, Error **errp)
  129. {
  130. CPUState *cs = CPU(dev);
  131. OpenRISCCPUClass *occ = OPENRISC_CPU_GET_CLASS(dev);
  132. Error *local_err = NULL;
  133. cpu_exec_realizefn(cs, &local_err);
  134. if (local_err != NULL) {
  135. error_propagate(errp, local_err);
  136. return;
  137. }
  138. qemu_init_vcpu(cs);
  139. cpu_reset(cs);
  140. #ifndef CONFIG_USER_ONLY
  141. cpu_openrisc_clock_init(OPENRISC_CPU(dev));
  142. #endif
  143. occ->parent_realize(dev, errp);
  144. }
  145. static void openrisc_cpu_initfn(Object *obj)
  146. {
  147. #ifndef CONFIG_USER_ONLY
  148. qdev_init_gpio_in_named(DEVICE(obj), openrisc_cpu_set_irq, "IRQ", NR_IRQS);
  149. #endif
  150. }
  151. /* CPU models */
  152. static ObjectClass *openrisc_cpu_class_by_name(const char *cpu_model)
  153. {
  154. ObjectClass *oc;
  155. char *typename;
  156. typename = g_strdup_printf(OPENRISC_CPU_TYPE_NAME("%s"), cpu_model);
  157. oc = object_class_by_name(typename);
  158. g_free(typename);
  159. return oc;
  160. }
  161. static void or1200_initfn(Object *obj)
  162. {
  163. OpenRISCCPU *cpu = OPENRISC_CPU(obj);
  164. cpu->env.vr = 0x13000008;
  165. cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP | UPR_PMP;
  166. cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_OF32S |
  167. CPUCFGR_EVBARP;
  168. /* 1Way, TLB_SIZE entries. */
  169. cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2))
  170. | (DMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
  171. cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2))
  172. | (IMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
  173. }
  174. static void openrisc_any_initfn(Object *obj)
  175. {
  176. OpenRISCCPU *cpu = OPENRISC_CPU(obj);
  177. cpu->env.vr = 0x13000040; /* Obsolete VER + UVRP for new SPRs */
  178. cpu->env.vr2 = 0; /* No version specific id */
  179. cpu->env.avr = 0x01030000; /* Architecture v1.3 */
  180. cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP | UPR_PMP;
  181. cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_OF32S |
  182. CPUCFGR_AVRP | CPUCFGR_EVBARP | CPUCFGR_OF64A32S;
  183. /* 1Way, TLB_SIZE entries. */
  184. cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2))
  185. | (DMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
  186. cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2))
  187. | (IMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
  188. }
  189. #ifndef CONFIG_USER_ONLY
  190. #include "hw/core/sysemu-cpu-ops.h"
  191. static const struct SysemuCPUOps openrisc_sysemu_ops = {
  192. .has_work = openrisc_cpu_has_work,
  193. .get_phys_page_debug = openrisc_cpu_get_phys_page_debug,
  194. };
  195. #endif
  196. #include "accel/tcg/cpu-ops.h"
  197. static const TCGCPUOps openrisc_tcg_ops = {
  198. .initialize = openrisc_translate_init,
  199. .translate_code = openrisc_translate_code,
  200. .synchronize_from_tb = openrisc_cpu_synchronize_from_tb,
  201. .restore_state_to_opc = openrisc_restore_state_to_opc,
  202. #ifndef CONFIG_USER_ONLY
  203. .tlb_fill = openrisc_cpu_tlb_fill,
  204. .cpu_exec_interrupt = openrisc_cpu_exec_interrupt,
  205. .cpu_exec_halt = openrisc_cpu_has_work,
  206. .do_interrupt = openrisc_cpu_do_interrupt,
  207. #endif /* !CONFIG_USER_ONLY */
  208. };
  209. static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
  210. {
  211. OpenRISCCPUClass *occ = OPENRISC_CPU_CLASS(oc);
  212. CPUClass *cc = CPU_CLASS(occ);
  213. DeviceClass *dc = DEVICE_CLASS(oc);
  214. ResettableClass *rc = RESETTABLE_CLASS(oc);
  215. device_class_set_parent_realize(dc, openrisc_cpu_realizefn,
  216. &occ->parent_realize);
  217. resettable_class_set_parent_phases(rc, NULL, openrisc_cpu_reset_hold, NULL,
  218. &occ->parent_phases);
  219. cc->class_by_name = openrisc_cpu_class_by_name;
  220. cc->mmu_index = openrisc_cpu_mmu_index;
  221. cc->dump_state = openrisc_cpu_dump_state;
  222. cc->set_pc = openrisc_cpu_set_pc;
  223. cc->get_pc = openrisc_cpu_get_pc;
  224. cc->gdb_read_register = openrisc_cpu_gdb_read_register;
  225. cc->gdb_write_register = openrisc_cpu_gdb_write_register;
  226. #ifndef CONFIG_USER_ONLY
  227. dc->vmsd = &vmstate_openrisc_cpu;
  228. cc->sysemu_ops = &openrisc_sysemu_ops;
  229. #endif
  230. cc->gdb_num_core_regs = 32 + 3;
  231. cc->disas_set_info = openrisc_disas_set_info;
  232. cc->tcg_ops = &openrisc_tcg_ops;
  233. }
  234. #define DEFINE_OPENRISC_CPU_TYPE(cpu_model, initfn) \
  235. { \
  236. .parent = TYPE_OPENRISC_CPU, \
  237. .instance_init = initfn, \
  238. .name = OPENRISC_CPU_TYPE_NAME(cpu_model), \
  239. }
  240. static const TypeInfo openrisc_cpus_type_infos[] = {
  241. { /* base class should be registered first */
  242. .name = TYPE_OPENRISC_CPU,
  243. .parent = TYPE_CPU,
  244. .instance_size = sizeof(OpenRISCCPU),
  245. .instance_align = __alignof(OpenRISCCPU),
  246. .instance_init = openrisc_cpu_initfn,
  247. .abstract = true,
  248. .class_size = sizeof(OpenRISCCPUClass),
  249. .class_init = openrisc_cpu_class_init,
  250. },
  251. DEFINE_OPENRISC_CPU_TYPE("or1200", or1200_initfn),
  252. DEFINE_OPENRISC_CPU_TYPE("any", openrisc_any_initfn),
  253. };
  254. DEFINE_TYPES(openrisc_cpus_type_infos)