~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to target-openrisc/cpu.h

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * OpenRISC virtual CPU header.
3
 
 *
4
 
 * Copyright (c) 2011-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 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 OPENRISC_CPU_H
21
 
#define OPENRISC_CPU_H
22
 
 
23
 
#define TARGET_LONG_BITS 32
24
 
 
25
 
#define CPUArchState struct CPUOpenRISCState
26
 
 
27
 
/* cpu_openrisc_map_address_* in CPUOpenRISCTLBContext need this decl.  */
28
 
struct OpenRISCCPU;
29
 
 
30
 
#include "qemu-common.h"
31
 
#include "exec/cpu-defs.h"
32
 
#include "fpu/softfloat.h"
33
 
#include "qom/cpu.h"
34
 
 
35
 
#define TYPE_OPENRISC_CPU "or32-cpu"
36
 
 
37
 
#define OPENRISC_CPU_CLASS(klass) \
38
 
    OBJECT_CLASS_CHECK(OpenRISCCPUClass, (klass), TYPE_OPENRISC_CPU)
39
 
#define OPENRISC_CPU(obj) \
40
 
    OBJECT_CHECK(OpenRISCCPU, (obj), TYPE_OPENRISC_CPU)
41
 
#define OPENRISC_CPU_GET_CLASS(obj) \
42
 
    OBJECT_GET_CLASS(OpenRISCCPUClass, (obj), TYPE_OPENRISC_CPU)
43
 
 
44
 
/**
45
 
 * OpenRISCCPUClass:
46
 
 * @parent_realize: The parent class' realize handler.
47
 
 * @parent_reset: The parent class' reset handler.
48
 
 *
49
 
 * A OpenRISC CPU model.
50
 
 */
51
 
typedef struct OpenRISCCPUClass {
52
 
    /*< private >*/
53
 
    CPUClass parent_class;
54
 
    /*< public >*/
55
 
 
56
 
    DeviceRealize parent_realize;
57
 
    void (*parent_reset)(CPUState *cpu);
58
 
} OpenRISCCPUClass;
59
 
 
60
 
#define NB_MMU_MODES    3
61
 
 
62
 
enum {
63
 
    MMU_NOMMU_IDX = 0,
64
 
    MMU_SUPERVISOR_IDX = 1,
65
 
    MMU_USER_IDX = 2,
66
 
};
67
 
 
68
 
#define TARGET_PAGE_BITS 13
69
 
 
70
 
#define TARGET_PHYS_ADDR_SPACE_BITS 32
71
 
#define TARGET_VIRT_ADDR_SPACE_BITS 32
72
 
 
73
 
#define SET_FP_CAUSE(reg, v)    do {\
74
 
                                    (reg) = ((reg) & ~(0x3f << 12)) | \
75
 
                                            ((v & 0x3f) << 12);\
76
 
                                } while (0)
77
 
#define GET_FP_ENABLE(reg)       (((reg) >>  7) & 0x1f)
78
 
#define UPDATE_FP_FLAGS(reg, v)   do {\
79
 
                                      (reg) |= ((v & 0x1f) << 2);\
80
 
                                  } while (0)
81
 
 
82
 
/* Version Register */
83
 
#define SPR_VR 0xFFFF003F
84
 
 
85
 
/* Internal flags, delay slot flag */
86
 
#define D_FLAG    1
87
 
 
88
 
/* Interrupt */
89
 
#define NR_IRQS  32
90
 
 
91
 
/* Unit presece register */
92
 
enum {
93
 
    UPR_UP = (1 << 0),
94
 
    UPR_DCP = (1 << 1),
95
 
    UPR_ICP = (1 << 2),
96
 
    UPR_DMP = (1 << 3),
97
 
    UPR_IMP = (1 << 4),
98
 
    UPR_MP = (1 << 5),
99
 
    UPR_DUP = (1 << 6),
100
 
    UPR_PCUR = (1 << 7),
101
 
    UPR_PMP = (1 << 8),
102
 
    UPR_PICP = (1 << 9),
103
 
    UPR_TTP = (1 << 10),
104
 
    UPR_CUP = (255 << 24),
105
 
};
106
 
 
107
 
/* CPU configure register */
108
 
enum {
109
 
    CPUCFGR_NSGF = (15 << 0),
110
 
    CPUCFGR_CGF = (1 << 4),
111
 
    CPUCFGR_OB32S = (1 << 5),
112
 
    CPUCFGR_OB64S = (1 << 6),
113
 
    CPUCFGR_OF32S = (1 << 7),
114
 
    CPUCFGR_OF64S = (1 << 8),
115
 
    CPUCFGR_OV64S = (1 << 9),
116
 
};
117
 
 
118
 
/* DMMU configure register */
119
 
enum {
120
 
    DMMUCFGR_NTW = (3 << 0),
121
 
    DMMUCFGR_NTS = (7 << 2),
122
 
    DMMUCFGR_NAE = (7 << 5),
123
 
    DMMUCFGR_CRI = (1 << 8),
124
 
    DMMUCFGR_PRI = (1 << 9),
125
 
    DMMUCFGR_TEIRI = (1 << 10),
126
 
    DMMUCFGR_HTR = (1 << 11),
127
 
};
128
 
 
129
 
/* IMMU configure register */
130
 
enum {
131
 
    IMMUCFGR_NTW = (3 << 0),
132
 
    IMMUCFGR_NTS = (7 << 2),
133
 
    IMMUCFGR_NAE = (7 << 5),
134
 
    IMMUCFGR_CRI = (1 << 8),
135
 
    IMMUCFGR_PRI = (1 << 9),
136
 
    IMMUCFGR_TEIRI = (1 << 10),
137
 
    IMMUCFGR_HTR = (1 << 11),
138
 
};
139
 
 
140
 
/* Float point control status register */
141
 
enum {
142
 
    FPCSR_FPEE = 1,
143
 
    FPCSR_RM = (3 << 1),
144
 
    FPCSR_OVF = (1 << 3),
145
 
    FPCSR_UNF = (1 << 4),
146
 
    FPCSR_SNF = (1 << 5),
147
 
    FPCSR_QNF = (1 << 6),
148
 
    FPCSR_ZF = (1 << 7),
149
 
    FPCSR_IXF = (1 << 8),
150
 
    FPCSR_IVF = (1 << 9),
151
 
    FPCSR_INF = (1 << 10),
152
 
    FPCSR_DZF = (1 << 11),
153
 
};
154
 
 
155
 
/* Exceptions indices */
156
 
enum {
157
 
    EXCP_RESET    = 0x1,
158
 
    EXCP_BUSERR   = 0x2,
159
 
    EXCP_DPF      = 0x3,
160
 
    EXCP_IPF      = 0x4,
161
 
    EXCP_TICK     = 0x5,
162
 
    EXCP_ALIGN    = 0x6,
163
 
    EXCP_ILLEGAL  = 0x7,
164
 
    EXCP_INT      = 0x8,
165
 
    EXCP_DTLBMISS = 0x9,
166
 
    EXCP_ITLBMISS = 0xa,
167
 
    EXCP_RANGE    = 0xb,
168
 
    EXCP_SYSCALL  = 0xc,
169
 
    EXCP_FPE      = 0xd,
170
 
    EXCP_TRAP     = 0xe,
171
 
    EXCP_NR,
172
 
};
173
 
 
174
 
/* Supervisor register */
175
 
enum {
176
 
    SR_SM = (1 << 0),
177
 
    SR_TEE = (1 << 1),
178
 
    SR_IEE = (1 << 2),
179
 
    SR_DCE = (1 << 3),
180
 
    SR_ICE = (1 << 4),
181
 
    SR_DME = (1 << 5),
182
 
    SR_IME = (1 << 6),
183
 
    SR_LEE = (1 << 7),
184
 
    SR_CE  = (1 << 8),
185
 
    SR_F   = (1 << 9),
186
 
    SR_CY  = (1 << 10),
187
 
    SR_OV  = (1 << 11),
188
 
    SR_OVE = (1 << 12),
189
 
    SR_DSX = (1 << 13),
190
 
    SR_EPH = (1 << 14),
191
 
    SR_FO  = (1 << 15),
192
 
    SR_SUMRA = (1 << 16),
193
 
    SR_SCE = (1 << 17),
194
 
};
195
 
 
196
 
/* OpenRISC Hardware Capabilities */
197
 
enum {
198
 
    OPENRISC_FEATURE_NSGF = (15 << 0),
199
 
    OPENRISC_FEATURE_CGF = (1 << 4),
200
 
    OPENRISC_FEATURE_OB32S = (1 << 5),
201
 
    OPENRISC_FEATURE_OB64S = (1 << 6),
202
 
    OPENRISC_FEATURE_OF32S = (1 << 7),
203
 
    OPENRISC_FEATURE_OF64S = (1 << 8),
204
 
    OPENRISC_FEATURE_OV64S = (1 << 9),
205
 
};
206
 
 
207
 
/* Tick Timer Mode Register */
208
 
enum {
209
 
    TTMR_TP = (0xfffffff),
210
 
    TTMR_IP = (1 << 28),
211
 
    TTMR_IE = (1 << 29),
212
 
    TTMR_M  = (3 << 30),
213
 
};
214
 
 
215
 
/* Timer Mode */
216
 
enum {
217
 
    TIMER_NONE = (0 << 30),
218
 
    TIMER_INTR = (1 << 30),
219
 
    TIMER_SHOT = (2 << 30),
220
 
    TIMER_CONT = (3 << 30),
221
 
};
222
 
 
223
 
/* TLB size */
224
 
enum {
225
 
    DTLB_WAYS = 1,
226
 
    DTLB_SIZE = 64,
227
 
    DTLB_MASK = (DTLB_SIZE-1),
228
 
    ITLB_WAYS = 1,
229
 
    ITLB_SIZE = 64,
230
 
    ITLB_MASK = (ITLB_SIZE-1),
231
 
};
232
 
 
233
 
/* TLB prot */
234
 
enum {
235
 
    URE = (1 << 6),
236
 
    UWE = (1 << 7),
237
 
    SRE = (1 << 8),
238
 
    SWE = (1 << 9),
239
 
 
240
 
    SXE = (1 << 6),
241
 
    UXE = (1 << 7),
242
 
};
243
 
 
244
 
/* check if tlb available */
245
 
enum {
246
 
    TLBRET_INVALID = -3,
247
 
    TLBRET_NOMATCH = -2,
248
 
    TLBRET_BADADDR = -1,
249
 
    TLBRET_MATCH = 0
250
 
};
251
 
 
252
 
typedef struct OpenRISCTLBEntry {
253
 
    uint32_t mr;
254
 
    uint32_t tr;
255
 
} OpenRISCTLBEntry;
256
 
 
257
 
#ifndef CONFIG_USER_ONLY
258
 
typedef struct CPUOpenRISCTLBContext {
259
 
    OpenRISCTLBEntry itlb[ITLB_WAYS][ITLB_SIZE];
260
 
    OpenRISCTLBEntry dtlb[DTLB_WAYS][DTLB_SIZE];
261
 
 
262
 
    int (*cpu_openrisc_map_address_code)(struct OpenRISCCPU *cpu,
263
 
                                         hwaddr *physical,
264
 
                                         int *prot,
265
 
                                         target_ulong address, int rw);
266
 
    int (*cpu_openrisc_map_address_data)(struct OpenRISCCPU *cpu,
267
 
                                         hwaddr *physical,
268
 
                                         int *prot,
269
 
                                         target_ulong address, int rw);
270
 
} CPUOpenRISCTLBContext;
271
 
#endif
272
 
 
273
 
typedef struct CPUOpenRISCState {
274
 
    target_ulong gpr[32];     /* General registers */
275
 
    target_ulong pc;          /* Program counter */
276
 
    target_ulong npc;         /* Next PC */
277
 
    target_ulong ppc;         /* Prev PC */
278
 
    target_ulong jmp_pc;      /* Jump PC */
279
 
 
280
 
    target_ulong machi;       /* Multiply register MACHI */
281
 
    target_ulong maclo;       /* Multiply register MACLO */
282
 
 
283
 
    target_ulong fpmaddhi;    /* Multiply and add float register FPMADDHI */
284
 
    target_ulong fpmaddlo;    /* Multiply and add float register FPMADDLO */
285
 
 
286
 
    target_ulong epcr;        /* Exception PC register */
287
 
    target_ulong eear;        /* Exception EA register */
288
 
 
289
 
    uint32_t sr;              /* Supervisor register */
290
 
    uint32_t vr;              /* Version register */
291
 
    uint32_t upr;             /* Unit presence register */
292
 
    uint32_t cpucfgr;         /* CPU configure register */
293
 
    uint32_t dmmucfgr;        /* DMMU configure register */
294
 
    uint32_t immucfgr;        /* IMMU configure register */
295
 
    uint32_t esr;             /* Exception supervisor register */
296
 
    uint32_t fpcsr;           /* Float register */
297
 
    float_status fp_status;
298
 
 
299
 
    uint32_t flags;           /* cpu_flags, we only use it for exception
300
 
                                 in solt so far.  */
301
 
    uint32_t btaken;          /* the SR_F bit */
302
 
 
303
 
    CPU_COMMON
304
 
 
305
 
    /* Fields from here on are preserved across CPU reset. */
306
 
#ifndef CONFIG_USER_ONLY
307
 
    CPUOpenRISCTLBContext * tlb;
308
 
 
309
 
    QEMUTimer *timer;
310
 
    uint32_t ttmr;          /* Timer tick mode register */
311
 
    uint32_t ttcr;          /* Timer tick count register */
312
 
 
313
 
    uint32_t picmr;         /* Interrupt mask register */
314
 
    uint32_t picsr;         /* Interrupt contrl register*/
315
 
#endif
316
 
    void *irq[32];          /* Interrupt irq input */
317
 
} CPUOpenRISCState;
318
 
 
319
 
/**
320
 
 * OpenRISCCPU:
321
 
 * @env: #CPUOpenRISCState
322
 
 *
323
 
 * A OpenRISC CPU.
324
 
 */
325
 
typedef struct OpenRISCCPU {
326
 
    /*< private >*/
327
 
    CPUState parent_obj;
328
 
    /*< public >*/
329
 
 
330
 
    CPUOpenRISCState env;
331
 
 
332
 
    uint32_t feature;       /* CPU Capabilities */
333
 
} OpenRISCCPU;
334
 
 
335
 
static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env)
336
 
{
337
 
    return container_of(env, OpenRISCCPU, env);
338
 
}
339
 
 
340
 
#define ENV_GET_CPU(e) CPU(openrisc_env_get_cpu(e))
341
 
 
342
 
#define ENV_OFFSET offsetof(OpenRISCCPU, env)
343
 
 
344
 
OpenRISCCPU *cpu_openrisc_init(const char *cpu_model);
345
 
 
346
 
void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf);
347
 
void openrisc_cpu_do_interrupt(CPUState *cpu);
348
 
bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
349
 
void openrisc_cpu_dump_state(CPUState *cpu, FILE *f,
350
 
                             fprintf_function cpu_fprintf, int flags);
351
 
hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
352
 
int openrisc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
353
 
int openrisc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
354
 
void openrisc_translate_init(void);
355
 
int openrisc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address,
356
 
                                  int rw, int mmu_idx);
357
 
int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc);
358
 
 
359
 
#define cpu_list cpu_openrisc_list
360
 
#define cpu_signal_handler cpu_openrisc_signal_handler
361
 
 
362
 
#ifndef CONFIG_USER_ONLY
363
 
extern const struct VMStateDescription vmstate_openrisc_cpu;
364
 
 
365
 
/* hw/openrisc_pic.c */
366
 
void cpu_openrisc_pic_init(OpenRISCCPU *cpu);
367
 
 
368
 
/* hw/openrisc_timer.c */
369
 
void cpu_openrisc_clock_init(OpenRISCCPU *cpu);
370
 
void cpu_openrisc_count_update(OpenRISCCPU *cpu);
371
 
void cpu_openrisc_timer_update(OpenRISCCPU *cpu);
372
 
void cpu_openrisc_count_start(OpenRISCCPU *cpu);
373
 
void cpu_openrisc_count_stop(OpenRISCCPU *cpu);
374
 
 
375
 
void cpu_openrisc_mmu_init(OpenRISCCPU *cpu);
376
 
int cpu_openrisc_get_phys_nommu(OpenRISCCPU *cpu,
377
 
                                hwaddr *physical,
378
 
                                int *prot, target_ulong address, int rw);
379
 
int cpu_openrisc_get_phys_code(OpenRISCCPU *cpu,
380
 
                               hwaddr *physical,
381
 
                               int *prot, target_ulong address, int rw);
382
 
int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
383
 
                               hwaddr *physical,
384
 
                               int *prot, target_ulong address, int rw);
385
 
#endif
386
 
 
387
 
#define cpu_init(cpu_model) CPU(cpu_openrisc_init(cpu_model))
388
 
 
389
 
#include "exec/cpu-all.h"
390
 
 
391
 
static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
392
 
                                        target_ulong *pc,
393
 
                                        target_ulong *cs_base, uint32_t *flags)
394
 
{
395
 
    *pc = env->pc;
396
 
    *cs_base = 0;
397
 
    /* D_FLAG -- branch instruction exception */
398
 
    *flags = (env->flags & D_FLAG);
399
 
}
400
 
 
401
 
static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
402
 
{
403
 
    if (!(env->sr & SR_IME)) {
404
 
        return MMU_NOMMU_IDX;
405
 
    }
406
 
    return (env->sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
407
 
}
408
 
 
409
 
#define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
410
 
 
411
 
#endif /* OPENRISC_CPU_H */