1
/* Simulator for MIPS R3000 architecture.
3
THIS SOFTWARE IS NOT COPYRIGHTED
5
Cygnus offers the following for use in the public domain. Cygnus
6
makes no warranty with regard to the software or it's performance
7
and the user accepts the software "AS IS" with all faults.
9
CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
10
THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15
#include "skyeye_config.h"
22
static char *arch_name = "mips";
23
mips_mem_config_t mips_mem_config;
24
extern int trace_level;
25
extern UInt8* mem_bunks;
26
extern void mips_mem_reset ();
27
extern UInt32 mips_real_read_byte (UInt32 addr);
28
extern UInt32 mips_real_read_halfword (UInt32 addr);
29
extern UInt32 mips_real_read_word (UInt32 addr);
30
extern UInt64 mips_real_read_doubleword (UInt32 addr);
31
extern void mips_real_write_byte (UInt32 addr, UInt32 data);
32
extern void mips_real_write_halfword ( UInt32 addr, UInt32 data);
33
extern void mips_real_write_word ( UInt32 addr, UInt32 data);
34
extern void mips_real_write_doubleword ( UInt32 addr, UInt64 data);
37
extern UInt32 mips_io_read_byte (UInt32 addr);
38
extern UInt32 mips_io_read_halfword (UInt32 addr);
39
extern UInt32 mips_io_read_word (UInt32 addr);
40
extern UInt64 mips_io_read_doubleword (UInt32 addr);
41
extern void mips_io_write_byte (UInt32 addr, UInt32 data);
42
extern void mips_io_write_halfword (UInt32 addr, UInt32 data);
43
extern void mips_io_write_word (UInt32 addr, UInt32 data);
44
extern void mips_io_write_doubleword (UInt32 addr, UInt64 data);
47
extern UInt32 mips_flash_read_byte (UInt32 addr);
48
extern UInt32 mips_flash_read_halfword (UInt32 addr);
49
extern UInt32 mips_flash_read_word (UInt32 addr);
50
extern UInt64 mips_flash_read_doubleword ( UInt32 addr);
51
extern void mips_flash_write_byte (UInt32 addr, UInt32 data);
52
extern void mips_flash_write_halfword (UInt32 addr, UInt32 data);
53
extern void mips_flash_write_word (UInt32 addr, UInt32 data);
54
extern void mips_flash_write_doubleword (UInt32 addr, UInt64 data);
56
extern void mips_warn_write_byte (UInt32 addr, UInt32 data);
57
extern void mips_warn_write_halfword (UInt32 addr, UInt32 data);
58
extern void mips_warn_write_word (UInt32 addr, UInt32 data);
59
extern mips_mem_bank_t* mips_bank_ptr (UInt32 addr);
60
extern void mips_mem_write_byte (UInt32 phys_addr, UInt32 v);
61
extern void mips_mem_write_halfword (UInt32 phys_addr, UInt32 v);
62
extern void mips_mem_write_word (UInt32 phys_addr, UInt32 v);
63
extern void mips_mem_write_doubleword (UInt64 phys_addr, UInt64 v);
64
extern UInt32 mips_mem_read_byte (UInt32 phys_addr);
65
extern UInt32 mips_mem_read_halfword (UInt32 phys_addr);
66
extern UInt32 mips_mem_read_word (UInt32 phys_addr);
67
extern UInt64 mips_mem_read_doubleword (UInt64 phys_addr);
68
extern void mipsMul_WriteByte (MIPS_State* mstate, UInt32 vir_addr, UInt32 v);
69
extern void mips_mmu_write_byte (MIPS_State* mstate, UInt32 vir_addr, UInt32 v);
73
int SKYPRINTF(char * fmt,...)
79
mips_init_set(UInt32 addr, UInt8 value, int size)
85
mips_mem_read(UInt32 pa, UInt32 *data, int len)
90
*data = mips_mem_read_byte(pa);
94
*data = mips_mem_read_halfword(pa);
98
*data = mips_mem_read_word(pa);
108
mips_mem_write(UInt32 pa, const UInt32* data, int len)
110
UInt32 addr = bits(pa, 31, 0);
115
mips_mem_write_byte(pa, *data);
119
mips_mem_write_halfword(pa, *data);
123
mips_mem_write_word(pa, *data);
137
for(i = 0; i < Icache_log2_sets; i++)
139
Icache_lru_init(mstate->icache.set[i].Icache_lru);
148
for(i = 0; i < Dcache_log2_sets; i++)
150
Dcache_lru_init(mstate->dcache.set[i].Dcache_lru);
158
for(i = 0;i < tlb_map_size + 1; i++)
160
mstate->tlb_map[i] = NULL;
168
set_bit(mstate->mode, 2);
169
mstate = (MIPS_State* )malloc(sizeof(MIPS_State));
171
printf ("malloc error!\n");
176
mstate->conf.ec = 4; //I don't know what should it be.
178
// set the little endian as the default
179
mstate->bigendSig = 0; //Shi yang 2006-08-18
182
mstate->irq_pending = 0;
189
p_mach = malloc (sizeof (mach_t));
190
init_nedved_mach(p_mach);
191
mstate->p_mach = p_mach;
200
memset(mstate->cp1, 0, sizeof(mstate->cp1[32]));
201
memset(mstate->fpr, 0, sizeof(mstate->fpr[32]));
202
mstate->count_seed = mstate->now;
203
mstate->cp0[PRId] = ImpRev; //Fix me, Shi yang 2006-08-30
204
mstate->cp1[FCR0] = ImpRev;
205
mstate->nop_count = 0;
208
mstate->sync_bit = 0;
210
// Deliver the reset exception.
212
deliver_soft_reset(mstate);
214
deliver_cold_reset(mstate);
216
process_reset(mstate);
220
mips_trigger_irq(MIPS_State* mstate)
224
//Get the content of the cause register
225
UInt32 cause = mstate->cp0[Cause];
227
//When the instruction is in the delay slot, we have to delay an instruction
228
if (!branch_delay_slot(mstate))
231
epc = mstate->pc - 4;
232
cause = set_bit(cause, Cause_BD);
234
mstate->cp0[Cause] = cause;
235
mstate->cp0[EPC] = epc;
237
//Change the pointer pc to deal with the interrupt handler
238
if(bit(mstate->cp0[SR], SR_BEV) )
240
mstate->pc = 0xbfc00380;
242
mstate->pc = 0x80000180;
245
mstate->pipeline = nothing_special;
254
/* Check for interrupts. In real hardware, these have a priority lower
255
* than all exceptions, but simulating this effect is too hard to be
256
* worth the effort (interrupts and resets are not meant to be
257
* delivered accurately anyway.)
259
if(mstate->irq_pending)
261
mips_trigger_irq(mstate);
264
/* Look up the ITLB. It's not clear from the manuals whether the ITLB
265
* stores the ASIDs or not. I assume it does. ITLB has the same size
266
* as in the real hardware, mapping two 4KB pages. Because decoding a
267
* MIPS64 virtual address is far from trivial, ITLB and DTLB actually
268
* improve the simulator's performance: something I cannot say about
272
PA pa; //Shi yang 2006-08-18
275
pa = translate_vaddr(mstate, va, instr_fetch);
277
UInt32 addr = bits(va, 31, 0);
280
instr = fetch(mstate, mstate->pc, pa);
281
int next_state = decode(mstate, instr);
283
switch (mstate->pipeline) {
284
case nothing_special:
288
mstate->pc = mstate->branch_target;
290
case instr_addr_error:
291
process_address_error(mstate, instr_fetch, mstate->branch_target);
293
mstate->pipeline = next_state;
295
mstate->p_mach->io_do_cycle();
299
mips_set_pc(UInt32 addr)
311
mips_write_byte (WORD addr, uint8_t v)
313
mips_mem_write_byte (addr, v);
317
mips_write_byte64(UInt64 addr, UInt8 data)
323
mips_read_byte64(UInt64 addr)
329
mips_parse_cpu(const char* param[])
335
mips_parse_mach(machine_config_t * mach, const char* param[])
341
mips_parse_mem(int num_params, const char* params[])
343
char name[MAX_PARAM_NAME], value[MAX_PARAM_NAME];
345
mips_mem_config_t *mc = &mips_mem_config;
346
mips_mem_bank_t *mb = mc->mem_banks;
348
mc->bank_num = mc->current_num++;
350
num = mc->current_num - 1; /*mem_banks should begin from 0. */
351
mb[num].filename[0] = '\0';
352
for (i = 0; i < num_params; i++) {
353
if (split_param (params[i], name, value) < 0)
355
("Error: mem_bank %d has wrong parameter \"%s\".\n",
358
if (!strncmp ("map", name, strlen (name))) {
359
if (!strncmp ("M", value, strlen (value))) {
360
mb[num].read_byte = mips_real_read_byte;
361
mb[num].write_byte = mips_real_write_byte;
362
mb[num].read_halfword = mips_real_read_halfword;
363
mb[num].write_halfword = mips_real_write_halfword;
364
mb[num].read_word = mips_real_read_word;
365
mb[num].write_word = mips_real_write_word;
366
mb[num].read_doubleword = mips_real_read_doubleword;
367
mb[num].write_doubleword = mips_real_write_doubleword;
368
mb[num].type = MEMTYPE_RAM;
370
else if (!strncmp ("I", value, strlen (value))) {
371
mb[num].read_byte = mips_io_read_byte;
372
mb[num].write_byte = mips_io_write_byte;
373
mb[num].read_halfword = mips_io_read_halfword;
374
mb[num].write_halfword = mips_io_write_halfword;
375
mb[num].read_word = mips_io_read_word;
376
mb[num].write_word = mips_io_write_word;
377
mb[num].read_doubleword = mips_io_read_doubleword;
378
mb[num].write_doubleword = mips_io_write_doubleword;
380
mb[num].type = MEMTYPE_IO;
384
else if (!strncmp ("F", value, strlen (value))) {
385
mb[num].read_byte = mips_flash_read_byte;
386
mb[num].write_byte = mips_flash_write_byte;
387
mb[num].read_halfword = mips_flash_read_halfword;
388
mb[num].write_halfword = mips_flash_write_halfword;
389
mb[num].read_word = mips_flash_read_word;
390
mb[num].write_word = mips_flash_write_word;
391
mb[num].read_doubleword = mips_flash_read_doubleword;
392
mb[num].write_doubleword = mips_flash_write_doubleword;
393
mb[num].type = MEMTYPE_FLASH;
398
("Error: mem_bank %d \"%s\" parameter has wrong value \"%s\"\n",
402
else if (!strncmp ("type", name, strlen (name))) {
403
//chy 2003-09-21: process type
404
if (!strncmp ("R", value, strlen (value))) {
405
if (mb[num].type == MEMTYPE_RAM)
406
mb[num].type = MEMTYPE_ROM;
407
mb[num].write_byte = mips_warn_write_byte;
408
mb[num].write_halfword = mips_warn_write_halfword;
409
mb[num].write_word = mips_warn_write_word;
412
else if (!strncmp ("addr", name, strlen (name))) {
414
if (value[0] == '0' && value[1] == 'x')
415
mb[num].addr = strtoul (value, NULL, 16);
417
mb[num].addr = strtoul (value, NULL, 10);
420
else if (!strncmp ("size", name, strlen (name))) {
422
if (value[0] == '0' && value[1] == 'x')
423
mb[num].len = strtoul (value, NULL, 16);
425
mb[num].len = strtoul (value, NULL, 10);
428
else if (!strncmp ("file", name, strlen (name))) {
429
strncpy (mb[num].filename, value, strlen (value) + 1);
431
else if (!strncmp ("boot", name, strlen (name))) {
432
/*this must be the last parameter. */
433
if (!strncmp ("yes", value, strlen (value)))
434
skyeye_config.start_address = mb[num].addr;
438
("Error: mem_bank %d has unknow parameter \"%s\".\n",
446
static int mips_ICE_read_byte(WORD addr, uint8_t *data){
447
mips_mem_read(addr, *data, 1);
450
static int mips_ICE_write_byte(WORD addr, uint8_t data){
451
mips_mem_write(addr, &data, 1);
458
static arch_config_t mips_arch;
459
mips_arch.arch_name = arch_name;
460
mips_arch.init = mips_init_state;
461
mips_arch.reset = mips_reset_state;
462
mips_arch.step_once = mips_step_once;
463
mips_arch.set_pc = mips_set_pc;
464
mips_arch.get_pc = mips_get_pc;
465
mips_arch.ICE_read_byte = mips_ICE_read_byte;
466
mips_arch.ICE_write_byte = mips_ICE_write_byte;
467
mips_arch.parse_cpu = mips_parse_cpu;
468
mips_arch.parse_mach = mips_parse_mach;
469
mips_arch.parse_mem = mips_parse_mem;
470
register_arch (&mips_arch);