]> Git Repo - qemu.git/blob - target/unicore32/helper.c
nbd: add empty .bdrv_reopen_prepare
[qemu.git] / target / unicore32 / helper.c
1 /*
2  * Copyright (C) 2010-2012 Guan Xuetao
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.
7  *
8  * Contributions from 2012-04-01 on are considered under GPL version 2,
9  * or (at your option) any later version.
10  */
11
12 #include "qemu/osdep.h"
13 #include "cpu.h"
14 #include "exec/exec-all.h"
15 #include "exec/gdbstub.h"
16 #include "exec/helper-proto.h"
17 #include "qemu/host-utils.h"
18 #ifndef CONFIG_USER_ONLY
19 #include "ui/console.h"
20 #endif
21
22 #undef DEBUG_UC32
23
24 #ifdef DEBUG_UC32
25 #define DPRINTF(fmt, ...) printf("%s: " fmt , __func__, ## __VA_ARGS__)
26 #else
27 #define DPRINTF(fmt, ...) do {} while (0)
28 #endif
29
30 #ifndef CONFIG_USER_ONLY
31 void helper_cp0_set(CPUUniCore32State *env, uint32_t val, uint32_t creg,
32         uint32_t cop)
33 {
34     /*
35      * movc pp.nn, rn, #imm9
36      *      rn: UCOP_REG_D
37      *      nn: UCOP_REG_N
38      *          1: sys control reg.
39      *          2: page table base reg.
40      *          3: data fault status reg.
41      *          4: insn fault status reg.
42      *          5: cache op. reg.
43      *          6: tlb op. reg.
44      *      imm9: split UCOP_IMM10 with bit5 is 0
45      */
46     switch (creg) {
47     case 1:
48         if (cop != 0) {
49             goto unrecognized;
50         }
51         env->cp0.c1_sys = val;
52         break;
53     case 2:
54         if (cop != 0) {
55             goto unrecognized;
56         }
57         env->cp0.c2_base = val;
58         break;
59     case 3:
60         if (cop != 0) {
61             goto unrecognized;
62         }
63         env->cp0.c3_faultstatus = val;
64         break;
65     case 4:
66         if (cop != 0) {
67             goto unrecognized;
68         }
69         env->cp0.c4_faultaddr = val;
70         break;
71     case 5:
72         switch (cop) {
73         case 28:
74             DPRINTF("Invalidate Entire I&D cache\n");
75             return;
76         case 20:
77             DPRINTF("Invalidate Entire Icache\n");
78             return;
79         case 12:
80             DPRINTF("Invalidate Entire Dcache\n");
81             return;
82         case 10:
83             DPRINTF("Clean Entire Dcache\n");
84             return;
85         case 14:
86             DPRINTF("Flush Entire Dcache\n");
87             return;
88         case 13:
89             DPRINTF("Invalidate Dcache line\n");
90             return;
91         case 11:
92             DPRINTF("Clean Dcache line\n");
93             return;
94         case 15:
95             DPRINTF("Flush Dcache line\n");
96             return;
97         }
98         break;
99     case 6:
100         if ((cop <= 6) && (cop >= 2)) {
101             /* invalid all tlb */
102             tlb_flush(env_cpu(env));
103             return;
104         }
105         break;
106     default:
107         goto unrecognized;
108     }
109     return;
110 unrecognized:
111     DPRINTF("Wrong register (%d) or wrong operation (%d) in cp0_set!\n",
112             creg, cop);
113 }
114
115 uint32_t helper_cp0_get(CPUUniCore32State *env, uint32_t creg, uint32_t cop)
116 {
117     /*
118      * movc rd, pp.nn, #imm9
119      *      rd: UCOP_REG_D
120      *      nn: UCOP_REG_N
121      *          0: cpuid and cachetype
122      *          1: sys control reg.
123      *          2: page table base reg.
124      *          3: data fault status reg.
125      *          4: insn fault status reg.
126      *      imm9: split UCOP_IMM10 with bit5 is 0
127      */
128     switch (creg) {
129     case 0:
130         switch (cop) {
131         case 0:
132             return env->cp0.c0_cpuid;
133         case 1:
134             return env->cp0.c0_cachetype;
135         }
136         break;
137     case 1:
138         if (cop == 0) {
139             return env->cp0.c1_sys;
140         }
141         break;
142     case 2:
143         if (cop == 0) {
144             return env->cp0.c2_base;
145         }
146         break;
147     case 3:
148         if (cop == 0) {
149             return env->cp0.c3_faultstatus;
150         }
151         break;
152     case 4:
153         if (cop == 0) {
154             return env->cp0.c4_faultaddr;
155         }
156         break;
157     }
158     DPRINTF("Wrong register (%d) or wrong operation (%d) in cp0_set!\n",
159             creg, cop);
160     return 0;
161 }
162
163 #ifdef CONFIG_CURSES
164
165 /* KEY_EVENT is defined in wincon.h and in curses.h. Avoid redefinition. */
166 #undef KEY_EVENT
167 #include <curses.h>
168 #undef KEY_EVENT
169
170 /*
171  * FIXME:
172  *     1. curses windows will be blank when switching back
173  *     2. backspace is not handled yet
174  */
175 static void putc_on_screen(unsigned char ch)
176 {
177     static WINDOW *localwin;
178     static int init;
179
180     if (!init) {
181         /* Assume 80 * 30 screen to minimize the implementation */
182         localwin = newwin(30, 80, 0, 0);
183         scrollok(localwin, TRUE);
184         init = TRUE;
185     }
186
187     if (isprint(ch)) {
188         wprintw(localwin, "%c", ch);
189     } else {
190         switch (ch) {
191         case '\n':
192             wprintw(localwin, "%c", ch);
193             break;
194         case '\r':
195             /* If '\r' is put before '\n', the curses window will destroy the
196              * last print line. And meanwhile, '\n' implifies '\r' inside. */
197             break;
198         default: /* Not handled, so just print it hex code */
199             wprintw(localwin, "-- 0x%x --", ch);
200         }
201     }
202
203     wrefresh(localwin);
204 }
205 #else
206 #define putc_on_screen(c)               do { } while (0)
207 #endif
208
209 void helper_cp1_putc(target_ulong x)
210 {
211     putc_on_screen((unsigned char)x);   /* Output to screen */
212     DPRINTF("%c", x);                   /* Output to stdout */
213 }
214 #endif
215
216 bool uc32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
217 {
218     if (interrupt_request & CPU_INTERRUPT_HARD) {
219         UniCore32CPU *cpu = UNICORE32_CPU(cs);
220         CPUUniCore32State *env = &cpu->env;
221
222         if (!(env->uncached_asr & ASR_I)) {
223             cs->exception_index = UC32_EXCP_INTR;
224             uc32_cpu_do_interrupt(cs);
225             return true;
226         }
227     }
228     return false;
229 }
This page took 0.036538 seconds and 4 git commands to generate.