1 /*
2  *  LatticeMico32 virtual CPU header.
3  *
4  *  Copyright (c) 2010 Michael Walle <michael@walle.cc>
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 
20 #ifndef LM32_CPU_H
21 #define LM32_CPU_H
22 
23 #include "cpu-qom.h"
24 #include "exec/cpu-defs.h"
25 
26 typedef struct CPULM32State CPULM32State;
27 
cpu_mmu_index(CPULM32State * env,bool ifetch)28 static inline int cpu_mmu_index(CPULM32State *env, bool ifetch)
29 {
30     return 0;
31 }
32 
33 /* Exceptions indices */
34 enum {
35     EXCP_RESET = 0,
36     EXCP_BREAKPOINT,
37     EXCP_INSN_BUS_ERROR,
38     EXCP_WATCHPOINT,
39     EXCP_DATA_BUS_ERROR,
40     EXCP_DIVIDE_BY_ZERO,
41     EXCP_IRQ,
42     EXCP_SYSTEMCALL
43 };
44 
45 /* Registers */
46 enum {
47     R_R0 = 0, R_R1, R_R2, R_R3, R_R4, R_R5, R_R6, R_R7, R_R8, R_R9, R_R10,
48     R_R11, R_R12, R_R13, R_R14, R_R15, R_R16, R_R17, R_R18, R_R19, R_R20,
49     R_R21, R_R22, R_R23, R_R24, R_R25, R_R26, R_R27, R_R28, R_R29, R_R30,
50     R_R31
51 };
52 
53 /* Register aliases */
54 enum {
55     R_GP = R_R26,
56     R_FP = R_R27,
57     R_SP = R_R28,
58     R_RA = R_R29,
59     R_EA = R_R30,
60     R_BA = R_R31
61 };
62 
63 /* IE flags */
64 enum {
65     IE_IE  = (1<<0),
66     IE_EIE = (1<<1),
67     IE_BIE = (1<<2),
68 };
69 
70 /* DC flags */
71 enum {
72     DC_SS  = (1<<0),
73     DC_RE  = (1<<1),
74     DC_C0  = (1<<2),
75     DC_C1  = (1<<3),
76     DC_C2  = (1<<4),
77     DC_C3  = (1<<5),
78 };
79 
80 /* CFG mask */
81 enum {
82     CFG_M         = (1<<0),
83     CFG_D         = (1<<1),
84     CFG_S         = (1<<2),
85     CFG_U         = (1<<3),
86     CFG_X         = (1<<4),
87     CFG_CC        = (1<<5),
88     CFG_IC        = (1<<6),
89     CFG_DC        = (1<<7),
90     CFG_G         = (1<<8),
91     CFG_H         = (1<<9),
92     CFG_R         = (1<<10),
93     CFG_J         = (1<<11),
94     CFG_INT_SHIFT = 12,
95     CFG_BP_SHIFT  = 18,
96     CFG_WP_SHIFT  = 22,
97     CFG_REV_SHIFT = 26,
98 };
99 
100 /* CSRs */
101 enum {
102     CSR_IE   = 0x00,
103     CSR_IM   = 0x01,
104     CSR_IP   = 0x02,
105     CSR_ICC  = 0x03,
106     CSR_DCC  = 0x04,
107     CSR_CC   = 0x05,
108     CSR_CFG  = 0x06,
109     CSR_EBA  = 0x07,
110     CSR_DC   = 0x08,
111     CSR_DEBA = 0x09,
112     CSR_JTX  = 0x0e,
113     CSR_JRX  = 0x0f,
114     CSR_BP0  = 0x10,
115     CSR_BP1  = 0x11,
116     CSR_BP2  = 0x12,
117     CSR_BP3  = 0x13,
118     CSR_WP0  = 0x18,
119     CSR_WP1  = 0x19,
120     CSR_WP2  = 0x1a,
121     CSR_WP3  = 0x1b,
122 };
123 
124 enum {
125     LM32_FEATURE_MULTIPLY     =  1,
126     LM32_FEATURE_DIVIDE       =  2,
127     LM32_FEATURE_SHIFT        =  4,
128     LM32_FEATURE_SIGN_EXTEND  =  8,
129     LM32_FEATURE_I_CACHE      = 16,
130     LM32_FEATURE_D_CACHE      = 32,
131     LM32_FEATURE_CYCLE_COUNT  = 64,
132 };
133 
134 enum {
135     LM32_FLAG_IGNORE_MSB = 1,
136 };
137 
138 struct CPULM32State {
139     /* general registers */
140     uint32_t regs[32];
141 
142     /* special registers */
143     uint32_t pc;        /* program counter */
144     uint32_t ie;        /* interrupt enable */
145     uint32_t icc;       /* instruction cache control */
146     uint32_t dcc;       /* data cache control */
147     uint32_t cc;        /* cycle counter */
148     uint32_t cfg;       /* configuration */
149 
150     /* debug registers */
151     uint32_t dc;        /* debug control */
152     uint32_t bp[4];     /* breakpoints */
153     uint32_t wp[4];     /* watchpoints */
154 
155     struct CPUBreakpoint *cpu_breakpoint[4];
156     struct CPUWatchpoint *cpu_watchpoint[4];
157 
158     /* Fields up to this point are cleared by a CPU reset */
159     struct {} end_reset_fields;
160 
161     /* Fields from here on are preserved across CPU reset. */
162     uint32_t eba;       /* exception base address */
163     uint32_t deba;      /* debug exception base address */
164 
165     /* interrupt controller handle for callbacks */
166     DeviceState *pic_state;
167     /* JTAG UART handle for callbacks */
168     DeviceState *juart_state;
169 
170     /* processor core features */
171     uint32_t flags;
172 
173 };
174 
175 /**
176  * LM32CPU:
177  * @env: #CPULM32State
178  *
179  * A LatticeMico32 CPU.
180  */
181 struct LM32CPU {
182     /*< private >*/
183     CPUState parent_obj;
184     /*< public >*/
185 
186     CPUNegativeOffsetState neg;
187     CPULM32State env;
188 
189     uint32_t revision;
190     uint8_t num_interrupts;
191     uint8_t num_breakpoints;
192     uint8_t num_watchpoints;
193     uint32_t features;
194 };
195 
196 
197 #ifndef CONFIG_USER_ONLY
198 extern const VMStateDescription vmstate_lm32_cpu;
199 #endif
200 
201 void lm32_cpu_do_interrupt(CPUState *cpu);
202 bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
203 void lm32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
204 hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
205 int lm32_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
206 int lm32_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
207 
208 typedef enum {
209     LM32_WP_DISABLED = 0,
210     LM32_WP_READ,
211     LM32_WP_WRITE,
212     LM32_WP_READ_WRITE,
213 } lm32_wp_t;
214 
lm32_wp_type(uint32_t dc,int idx)215 static inline lm32_wp_t lm32_wp_type(uint32_t dc, int idx)
216 {
217     assert(idx < 4);
218     return (dc >> (idx+1)*2) & 0x3;
219 }
220 
221 /* you can call this signal handler from your SIGBUS and SIGSEGV
222    signal handlers to inform the virtual CPU of exceptions. non zero
223    is returned if the signal was handled by the virtual CPU.  */
224 int cpu_lm32_signal_handler(int host_signum, void *pinfo,
225                           void *puc);
226 void lm32_cpu_list(void);
227 void lm32_translate_init(void);
228 void cpu_lm32_set_phys_msb_ignore(CPULM32State *env, int value);
229 void QEMU_NORETURN raise_exception(CPULM32State *env, int index);
230 void lm32_debug_excp_handler(CPUState *cs);
231 void lm32_breakpoint_insert(CPULM32State *env, int index, target_ulong address);
232 void lm32_breakpoint_remove(CPULM32State *env, int index);
233 void lm32_watchpoint_insert(CPULM32State *env, int index, target_ulong address,
234         lm32_wp_t wp_type);
235 void lm32_watchpoint_remove(CPULM32State *env, int index);
236 bool lm32_cpu_do_semihosting(CPUState *cs);
237 
238 #define LM32_CPU_TYPE_SUFFIX "-" TYPE_LM32_CPU
239 #define LM32_CPU_TYPE_NAME(model) model LM32_CPU_TYPE_SUFFIX
240 #define CPU_RESOLVING_TYPE TYPE_LM32_CPU
241 
242 #define cpu_list lm32_cpu_list
243 #define cpu_signal_handler cpu_lm32_signal_handler
244 
245 bool lm32_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
246                        MMUAccessType access_type, int mmu_idx,
247                        bool probe, uintptr_t retaddr);
248 
249 typedef CPULM32State CPUArchState;
250 typedef LM32CPU ArchCPU;
251 
252 #include "exec/cpu-all.h"
253 
cpu_get_tb_cpu_state(CPULM32State * env,target_ulong * pc,target_ulong * cs_base,uint32_t * flags)254 static inline void cpu_get_tb_cpu_state(CPULM32State *env, target_ulong *pc,
255                                         target_ulong *cs_base, uint32_t *flags)
256 {
257     *pc = env->pc;
258     *cs_base = 0;
259     *flags = 0;
260 }
261 
262 #endif
263