]> git.proxmox.com Git - mirror_qemu.git/blame - target/unicore32/helper.c
semihosting: Move include/hw/semihosting/ -> include/semihosting/
[mirror_qemu.git] / target / unicore32 / helper.c
CommitLineData
6e64da3c 1/*
4f23a1e6 2 * Copyright (C) 2010-2012 Guan Xuetao
6e64da3c
GX
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
c3a8baa9
AF
7 *
8 * Contributions from 2012-04-01 on are considered under GPL version 2,
9 * or (at your option) any later version.
6e64da3c 10 */
6e64da3c 11
5af98cc5 12#include "qemu/osdep.h"
7a7b6632 13#include "qemu/log.h"
6e64da3c 14#include "cpu.h"
63c91552 15#include "exec/exec-all.h"
2ef6175a 16#include "exec/helper-proto.h"
6b5fe137 17#include "semihosting/console.h"
6e64da3c 18
527d9979
GX
19#undef DEBUG_UC32
20
21#ifdef DEBUG_UC32
22#define DPRINTF(fmt, ...) printf("%s: " fmt , __func__, ## __VA_ARGS__)
23#else
24#define DPRINTF(fmt, ...) do {} while (0)
25#endif
26
527d9979
GX
27#ifndef CONFIG_USER_ONLY
28void helper_cp0_set(CPUUniCore32State *env, uint32_t val, uint32_t creg,
29 uint32_t cop)
4f23a1e6 30{
527d9979
GX
31 /*
32 * movc pp.nn, rn, #imm9
33 * rn: UCOP_REG_D
34 * nn: UCOP_REG_N
35 * 1: sys control reg.
36 * 2: page table base reg.
37 * 3: data fault status reg.
38 * 4: insn fault status reg.
39 * 5: cache op. reg.
40 * 6: tlb op. reg.
41 * imm9: split UCOP_IMM10 with bit5 is 0
42 */
43 switch (creg) {
44 case 1:
45 if (cop != 0) {
46 goto unrecognized;
47 }
48 env->cp0.c1_sys = val;
49 break;
50 case 2:
51 if (cop != 0) {
52 goto unrecognized;
53 }
54 env->cp0.c2_base = val;
55 break;
56 case 3:
57 if (cop != 0) {
58 goto unrecognized;
59 }
60 env->cp0.c3_faultstatus = val;
61 break;
62 case 4:
63 if (cop != 0) {
64 goto unrecognized;
65 }
66 env->cp0.c4_faultaddr = val;
67 break;
68 case 5:
69 switch (cop) {
70 case 28:
71 DPRINTF("Invalidate Entire I&D cache\n");
72 return;
73 case 20:
74 DPRINTF("Invalidate Entire Icache\n");
75 return;
76 case 12:
77 DPRINTF("Invalidate Entire Dcache\n");
78 return;
79 case 10:
80 DPRINTF("Clean Entire Dcache\n");
81 return;
82 case 14:
83 DPRINTF("Flush Entire Dcache\n");
84 return;
85 case 13:
86 DPRINTF("Invalidate Dcache line\n");
87 return;
88 case 11:
89 DPRINTF("Clean Dcache line\n");
90 return;
91 case 15:
92 DPRINTF("Flush Dcache line\n");
93 return;
94 }
95 break;
96 case 6:
97 if ((cop <= 6) && (cop >= 2)) {
98 /* invalid all tlb */
31266e68 99 tlb_flush(env_cpu(env));
527d9979
GX
100 return;
101 }
102 break;
103 default:
104 goto unrecognized;
4f23a1e6 105 }
6e64da3c 106 return;
527d9979 107unrecognized:
7a7b6632
PMD
108 qemu_log_mask(LOG_GUEST_ERROR,
109 "Wrong register (%d) or wrong operation (%d) in cp0_set!\n",
110 creg, cop);
6e64da3c
GX
111}
112
527d9979 113uint32_t helper_cp0_get(CPUUniCore32State *env, uint32_t creg, uint32_t cop)
6e64da3c 114{
527d9979
GX
115 /*
116 * movc rd, pp.nn, #imm9
117 * rd: UCOP_REG_D
118 * nn: UCOP_REG_N
119 * 0: cpuid and cachetype
120 * 1: sys control reg.
121 * 2: page table base reg.
122 * 3: data fault status reg.
123 * 4: insn fault status reg.
124 * imm9: split UCOP_IMM10 with bit5 is 0
125 */
126 switch (creg) {
127 case 0:
128 switch (cop) {
129 case 0:
130 return env->cp0.c0_cpuid;
131 case 1:
132 return env->cp0.c0_cachetype;
133 }
134 break;
135 case 1:
136 if (cop == 0) {
137 return env->cp0.c1_sys;
138 }
139 break;
140 case 2:
141 if (cop == 0) {
142 return env->cp0.c2_base;
143 }
144 break;
145 case 3:
146 if (cop == 0) {
147 return env->cp0.c3_faultstatus;
148 }
149 break;
150 case 4:
151 if (cop == 0) {
152 return env->cp0.c4_faultaddr;
153 }
154 break;
155 }
7a7b6632
PMD
156 qemu_log_mask(LOG_GUEST_ERROR,
157 "Wrong register (%d) or wrong operation (%d) in cp0_set!\n",
158 creg, cop);
6e64da3c
GX
159 return 0;
160}
161
c7a856b4 162void helper_cp1_putc(target_ulong regval)
ff5928d0 163{
c7a856b4 164 const char c = regval;
ff5928d0 165
c7a856b4 166 qemu_semihosting_log_out(&c, sizeof(c));
6e64da3c 167}
c7a856b4 168#endif /* !CONFIG_USER_ONLY */
6e64da3c 169
d8bb9159
RH
170bool uc32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
171{
172 if (interrupt_request & CPU_INTERRUPT_HARD) {
173 UniCore32CPU *cpu = UNICORE32_CPU(cs);
174 CPUUniCore32State *env = &cpu->env;
175
176 if (!(env->uncached_asr & ASR_I)) {
177 cs->exception_index = UC32_EXCP_INTR;
178 uc32_cpu_do_interrupt(cs);
179 return true;
180 }
181 }
182 return false;
183}