~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 "or1k-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
#define TARGET_INSN_START_EXTRA_WORDS 1
 
62
 
 
63
enum {
 
64
    MMU_NOMMU_IDX = 0,
 
65
    MMU_SUPERVISOR_IDX = 1,
 
66
    MMU_USER_IDX = 2,
 
67
};
 
68
 
 
69
#define TARGET_PAGE_BITS 13
 
70
 
 
71
#define TARGET_PHYS_ADDR_SPACE_BITS 32
 
72
#define TARGET_VIRT_ADDR_SPACE_BITS 32
 
73
 
 
74
#define SET_FP_CAUSE(reg, v)    do {\
 
75
                                    (reg) = ((reg) & ~(0x3f << 12)) | \
 
76
                                            ((v & 0x3f) << 12);\
 
77
                                } while (0)
 
78
#define GET_FP_ENABLE(reg)       (((reg) >>  7) & 0x1f)
 
79
#define UPDATE_FP_FLAGS(reg, v)   do {\
 
80
                                      (reg) |= ((v & 0x1f) << 2);\
 
81
                                  } while (0)
 
82
 
 
83
/* Version Register */
 
84
#define SPR_VR 0xFFFF003F
 
85
 
 
86
/* Interrupt */
 
87
#define NR_IRQS  32
 
88
 
 
89
/* Unit presece register */
 
90
enum {
 
91
    UPR_UP = (1 << 0),
 
92
    UPR_DCP = (1 << 1),
 
93
    UPR_ICP = (1 << 2),
 
94
    UPR_DMP = (1 << 3),
 
95
    UPR_IMP = (1 << 4),
 
96
    UPR_MP = (1 << 5),
 
97
    UPR_DUP = (1 << 6),
 
98
    UPR_PCUR = (1 << 7),
 
99
    UPR_PMP = (1 << 8),
 
100
    UPR_PICP = (1 << 9),
 
101
    UPR_TTP = (1 << 10),
 
102
    UPR_CUP = (255 << 24),
 
103
};
 
104
 
 
105
/* CPU configure register */
 
106
enum {
 
107
    CPUCFGR_NSGF = (15 << 0),
 
108
    CPUCFGR_CGF = (1 << 4),
 
109
    CPUCFGR_OB32S = (1 << 5),
 
110
    CPUCFGR_OB64S = (1 << 6),
 
111
    CPUCFGR_OF32S = (1 << 7),
 
112
    CPUCFGR_OF64S = (1 << 8),
 
113
    CPUCFGR_OV64S = (1 << 9),
 
114
};
 
115
 
 
116
/* DMMU configure register */
 
117
enum {
 
118
    DMMUCFGR_NTW = (3 << 0),
 
119
    DMMUCFGR_NTS = (7 << 2),
 
120
    DMMUCFGR_NAE = (7 << 5),
 
121
    DMMUCFGR_CRI = (1 << 8),
 
122
    DMMUCFGR_PRI = (1 << 9),
 
123
    DMMUCFGR_TEIRI = (1 << 10),
 
124
    DMMUCFGR_HTR = (1 << 11),
 
125
};
 
126
 
 
127
/* IMMU configure register */
 
128
enum {
 
129
    IMMUCFGR_NTW = (3 << 0),
 
130
    IMMUCFGR_NTS = (7 << 2),
 
131
    IMMUCFGR_NAE = (7 << 5),
 
132
    IMMUCFGR_CRI = (1 << 8),
 
133
    IMMUCFGR_PRI = (1 << 9),
 
134
    IMMUCFGR_TEIRI = (1 << 10),
 
135
    IMMUCFGR_HTR = (1 << 11),
 
136
};
 
137
 
 
138
/* Float point control status register */
 
139
enum {
 
140
    FPCSR_FPEE = 1,
 
141
    FPCSR_RM = (3 << 1),
 
142
    FPCSR_OVF = (1 << 3),
 
143
    FPCSR_UNF = (1 << 4),
 
144
    FPCSR_SNF = (1 << 5),
 
145
    FPCSR_QNF = (1 << 6),
 
146
    FPCSR_ZF = (1 << 7),
 
147
    FPCSR_IXF = (1 << 8),
 
148
    FPCSR_IVF = (1 << 9),
 
149
    FPCSR_INF = (1 << 10),
 
150
    FPCSR_DZF = (1 << 11),
 
151
};
 
152
 
 
153
/* Exceptions indices */
 
154
enum {
 
155
    EXCP_RESET    = 0x1,
 
156
    EXCP_BUSERR   = 0x2,
 
157
    EXCP_DPF      = 0x3,
 
158
    EXCP_IPF      = 0x4,
 
159
    EXCP_TICK     = 0x5,
 
160
    EXCP_ALIGN    = 0x6,
 
161
    EXCP_ILLEGAL  = 0x7,
 
162
    EXCP_INT      = 0x8,
 
163
    EXCP_DTLBMISS = 0x9,
 
164
    EXCP_ITLBMISS = 0xa,
 
165
    EXCP_RANGE    = 0xb,
 
166
    EXCP_SYSCALL  = 0xc,
 
167
    EXCP_FPE      = 0xd,
 
168
    EXCP_TRAP     = 0xe,
 
169
    EXCP_NR,
 
170
};
 
171
 
 
172
/* Supervisor register */
 
173
enum {
 
174
    SR_SM = (1 << 0),
 
175
    SR_TEE = (1 << 1),
 
176
    SR_IEE = (1 << 2),
 
177
    SR_DCE = (1 << 3),
 
178
    SR_ICE = (1 << 4),
 
179
    SR_DME = (1 << 5),
 
180
    SR_IME = (1 << 6),
 
181
    SR_LEE = (1 << 7),
 
182
    SR_CE  = (1 << 8),
 
183
    SR_F   = (1 << 9),
 
184
    SR_CY  = (1 << 10),
 
185
    SR_OV  = (1 << 11),
 
186
    SR_OVE = (1 << 12),
 
187
    SR_DSX = (1 << 13),
 
188
    SR_EPH = (1 << 14),
 
189
    SR_FO  = (1 << 15),
 
190
    SR_SUMRA = (1 << 16),
 
191
    SR_SCE = (1 << 17),
 
192
};
 
193
 
 
194
/* OpenRISC Hardware Capabilities */
 
195
enum {
 
196
    OPENRISC_FEATURE_NSGF = (15 << 0),
 
197
    OPENRISC_FEATURE_CGF = (1 << 4),
 
198
    OPENRISC_FEATURE_OB32S = (1 << 5),
 
199
    OPENRISC_FEATURE_OB64S = (1 << 6),
 
200
    OPENRISC_FEATURE_OF32S = (1 << 7),
 
201
    OPENRISC_FEATURE_OF64S = (1 << 8),
 
202
    OPENRISC_FEATURE_OV64S = (1 << 9),
 
203
};
 
204
 
 
205
/* Tick Timer Mode Register */
 
206
enum {
 
207
    TTMR_TP = (0xfffffff),
 
208
    TTMR_IP = (1 << 28),
 
209
    TTMR_IE = (1 << 29),
 
210
    TTMR_M  = (3 << 30),
 
211
};
 
212
 
 
213
/* Timer Mode */
 
214
enum {
 
215
    TIMER_NONE = (0 << 30),
 
216
    TIMER_INTR = (1 << 30),
 
217
    TIMER_SHOT = (2 << 30),
 
218
    TIMER_CONT = (3 << 30),
 
219
};
 
220
 
 
221
/* TLB size */
 
222
enum {
 
223
    DTLB_WAYS = 1,
 
224
    DTLB_SIZE = 64,
 
225
    DTLB_MASK = (DTLB_SIZE-1),
 
226
    ITLB_WAYS = 1,
 
227
    ITLB_SIZE = 64,
 
228
    ITLB_MASK = (ITLB_SIZE-1),
 
229
};
 
230
 
 
231
/* TLB prot */
 
232
enum {
 
233
    URE = (1 << 6),
 
234
    UWE = (1 << 7),
 
235
    SRE = (1 << 8),
 
236
    SWE = (1 << 9),
 
237
 
 
238
    SXE = (1 << 6),
 
239
    UXE = (1 << 7),
 
240
};
 
241
 
 
242
/* check if tlb available */
 
243
enum {
 
244
    TLBRET_INVALID = -3,
 
245
    TLBRET_NOMATCH = -2,
 
246
    TLBRET_BADADDR = -1,
 
247
    TLBRET_MATCH = 0
 
248
};
 
249
 
 
250
typedef struct OpenRISCTLBEntry {
 
251
    uint32_t mr;
 
252
    uint32_t tr;
 
253
} OpenRISCTLBEntry;
 
254
 
 
255
#ifndef CONFIG_USER_ONLY
 
256
typedef struct CPUOpenRISCTLBContext {
 
257
    OpenRISCTLBEntry itlb[ITLB_WAYS][ITLB_SIZE];
 
258
    OpenRISCTLBEntry dtlb[DTLB_WAYS][DTLB_SIZE];
 
259
 
 
260
    int (*cpu_openrisc_map_address_code)(struct OpenRISCCPU *cpu,
 
261
                                         hwaddr *physical,
 
262
                                         int *prot,
 
263
                                         target_ulong address, int rw);
 
264
    int (*cpu_openrisc_map_address_data)(struct OpenRISCCPU *cpu,
 
265
                                         hwaddr *physical,
 
266
                                         int *prot,
 
267
                                         target_ulong address, int rw);
 
268
} CPUOpenRISCTLBContext;
 
269
#endif
 
270
 
 
271
typedef struct CPUOpenRISCState {
 
272
    target_ulong gpr[32];     /* General registers */
 
273
    target_ulong pc;          /* Program counter */
 
274
    target_ulong ppc;         /* Prev PC */
 
275
    target_ulong jmp_pc;      /* Jump PC */
 
276
 
 
277
    uint64_t mac;             /* Multiply registers MACHI:MACLO */
 
278
 
 
279
    target_ulong epcr;        /* Exception PC register */
 
280
    target_ulong eear;        /* Exception EA register */
 
281
 
 
282
    target_ulong sr_f;        /* the SR_F bit, values 0, 1.  */
 
283
    target_ulong sr_cy;       /* the SR_CY bit, values 0, 1.  */
 
284
    target_long  sr_ov;       /* the SR_OV bit (in the sign bit only) */
 
285
    uint32_t sr;              /* Supervisor register, without SR_{F,CY,OV} */
 
286
    uint32_t vr;              /* Version register */
 
287
    uint32_t upr;             /* Unit presence register */
 
288
    uint32_t cpucfgr;         /* CPU configure register */
 
289
    uint32_t dmmucfgr;        /* DMMU configure register */
 
290
    uint32_t immucfgr;        /* IMMU configure register */
 
291
    uint32_t esr;             /* Exception supervisor register */
 
292
    uint32_t fpcsr;           /* Float register */
 
293
    float_status fp_status;
 
294
 
 
295
    target_ulong lock_addr;
 
296
    target_ulong lock_value;
 
297
 
 
298
    uint32_t dflag;           /* In delay slot (boolean) */
 
299
 
 
300
    /* Fields up to this point are cleared by a CPU reset */
 
301
    struct {} end_reset_fields;
 
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
#define TB_FLAGS_DFLAG 1
 
392
#define TB_FLAGS_R0_0  2
 
393
#define TB_FLAGS_OVE   SR_OVE
 
394
 
 
395
static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env,
 
396
                                        target_ulong *pc,
 
397
                                        target_ulong *cs_base, uint32_t *flags)
 
398
{
 
399
    *pc = env->pc;
 
400
    *cs_base = 0;
 
401
    *flags = (env->dflag
 
402
              | (env->gpr[0] == 0 ? TB_FLAGS_R0_0 : 0)
 
403
              | (env->sr & SR_OVE));
 
404
}
 
405
 
 
406
static inline int cpu_mmu_index(CPUOpenRISCState *env, bool ifetch)
 
407
{
 
408
    if (!(env->sr & SR_IME)) {
 
409
        return MMU_NOMMU_IDX;
 
410
    }
 
411
    return (env->sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
 
412
}
 
413
 
 
414
static inline uint32_t cpu_get_sr(const CPUOpenRISCState *env)
 
415
{
 
416
    return (env->sr
 
417
            + env->sr_f * SR_F
 
418
            + env->sr_cy * SR_CY
 
419
            + (env->sr_ov < 0) * SR_OV);
 
420
}
 
421
 
 
422
static inline void cpu_set_sr(CPUOpenRISCState *env, uint32_t val)
 
423
{
 
424
    env->sr_f = (val & SR_F) != 0;
 
425
    env->sr_cy = (val & SR_CY) != 0;
 
426
    env->sr_ov = (val & SR_OV ? -1 : 0);
 
427
    env->sr = (val & ~(SR_F | SR_CY | SR_OV)) | SR_FO;
 
428
}
 
429
 
 
430
#define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
 
431
 
 
432
#endif /* OPENRISC_CPU_H */