14e98e3e1Schristos /* Simulator for Xilinx MicroBlaze processor 2*0d3e0572Schristos Copyright 2009-2024 Free Software Foundation, Inc. 34e98e3e1Schristos 44e98e3e1Schristos This file is part of GDB, the GNU debugger. 54e98e3e1Schristos 64e98e3e1Schristos This program is free software; you can redistribute it and/or modify 74e98e3e1Schristos it under the terms of the GNU General Public License as published by 8a2e2270fSchristos the Free Software Foundation; either version 3 of the License, or 94e98e3e1Schristos (at your option) any later version. 104e98e3e1Schristos 114e98e3e1Schristos This program is distributed in the hope that it will be useful, 124e98e3e1Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 134e98e3e1Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 144e98e3e1Schristos GNU General Public License for more details. 154e98e3e1Schristos 164e98e3e1Schristos You should have received a copy of the GNU General Public License 17a2e2270fSchristos along with this program; if not, see <http://www.gnu.org/licenses/>. */ 184e98e3e1Schristos 194b169a6bSchristos /* This must come before any other includes. */ 204b169a6bSchristos #include "defs.h" 214b169a6bSchristos 22212397c6Schristos #include <stdlib.h> 23212397c6Schristos #include <string.h> 24212397c6Schristos #include <unistd.h> 254e98e3e1Schristos #include "bfd.h" 264b169a6bSchristos #include "sim/callback.h" 274e98e3e1Schristos #include "libiberty.h" 284b169a6bSchristos #include "sim/sim.h" 29212397c6Schristos 304e98e3e1Schristos #include "sim-main.h" 31212397c6Schristos #include "sim-options.h" 324b169a6bSchristos #include "sim-signal.h" 334b169a6bSchristos #include "sim-syscall.h" 34212397c6Schristos 35*0d3e0572Schristos #include "microblaze-sim.h" 36*0d3e0572Schristos #include "opcodes/microblaze-dis.h" 374e98e3e1Schristos 384559860eSchristos #define target_big_endian (CURRENT_TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) 394e98e3e1Schristos 40212397c6Schristos static unsigned long 414b169a6bSchristos microblaze_extract_unsigned_integer (const unsigned char *addr, int len) 424e98e3e1Schristos { 434e98e3e1Schristos unsigned long retval; 444e98e3e1Schristos unsigned char *p; 454e98e3e1Schristos unsigned char *startaddr = (unsigned char *)addr; 464e98e3e1Schristos unsigned char *endaddr = startaddr + len; 474e98e3e1Schristos 484e98e3e1Schristos if (len > (int) sizeof (unsigned long)) 494e98e3e1Schristos printf ("That operation is not available on integers of more than " 50212397c6Schristos "%zu bytes.", sizeof (unsigned long)); 514e98e3e1Schristos 524e98e3e1Schristos /* Start at the most significant end of the integer, and work towards 534e98e3e1Schristos the least significant. */ 544e98e3e1Schristos retval = 0; 554e98e3e1Schristos 564e98e3e1Schristos if (!target_big_endian) 574e98e3e1Schristos { 584e98e3e1Schristos for (p = endaddr; p > startaddr;) 594e98e3e1Schristos retval = (retval << 8) | * -- p; 604e98e3e1Schristos } 614e98e3e1Schristos else 624e98e3e1Schristos { 634e98e3e1Schristos for (p = startaddr; p < endaddr;) 644e98e3e1Schristos retval = (retval << 8) | * p ++; 654e98e3e1Schristos } 664e98e3e1Schristos 674e98e3e1Schristos return retval; 684e98e3e1Schristos } 694e98e3e1Schristos 70212397c6Schristos static void 714e98e3e1Schristos microblaze_store_unsigned_integer (unsigned char *addr, int len, 724e98e3e1Schristos unsigned long val) 734e98e3e1Schristos { 744e98e3e1Schristos unsigned char *p; 754e98e3e1Schristos unsigned char *startaddr = (unsigned char *)addr; 764e98e3e1Schristos unsigned char *endaddr = startaddr + len; 774e98e3e1Schristos 784e98e3e1Schristos if (!target_big_endian) 794e98e3e1Schristos { 804e98e3e1Schristos for (p = startaddr; p < endaddr;) 814e98e3e1Schristos { 824e98e3e1Schristos *p++ = val & 0xff; 834e98e3e1Schristos val >>= 8; 844e98e3e1Schristos } 854e98e3e1Schristos } 864e98e3e1Schristos else 874e98e3e1Schristos { 884e98e3e1Schristos for (p = endaddr; p > startaddr;) 894e98e3e1Schristos { 904e98e3e1Schristos *--p = val & 0xff; 914e98e3e1Schristos val >>= 8; 924e98e3e1Schristos } 934e98e3e1Schristos } 944e98e3e1Schristos } 954e98e3e1Schristos 964e98e3e1Schristos static void 97212397c6Schristos set_initial_gprs (SIM_CPU *cpu) 984e98e3e1Schristos { 994e98e3e1Schristos int i; 1004e98e3e1Schristos 1014e98e3e1Schristos /* Set up machine just out of reset. */ 1024e98e3e1Schristos PC = 0; 1034e98e3e1Schristos MSR = 0; 1044e98e3e1Schristos 1054e98e3e1Schristos /* Clean out the GPRs */ 1064e98e3e1Schristos for (i = 0; i < 32; i++) 1074e98e3e1Schristos CPU.regs[i] = 0; 1084e98e3e1Schristos CPU.insts = 0; 1094e98e3e1Schristos CPU.cycles = 0; 1104e98e3e1Schristos CPU.imm_enable = 0; 1114e98e3e1Schristos } 1124e98e3e1Schristos 1134e98e3e1Schristos static int tracing = 0; 1144e98e3e1Schristos 1154e98e3e1Schristos void 116212397c6Schristos sim_engine_run (SIM_DESC sd, 117212397c6Schristos int next_cpu_nr, /* ignore */ 118212397c6Schristos int nr_cpus, /* ignore */ 119212397c6Schristos int siggnal) /* ignore */ 1204e98e3e1Schristos { 121212397c6Schristos SIM_CPU *cpu = STATE_CPU (sd, 0); 1224b169a6bSchristos signed_4 inst; 1234e98e3e1Schristos enum microblaze_instr op; 1244e98e3e1Schristos int memops; 1254e98e3e1Schristos int bonus_cycles; 1264e98e3e1Schristos int insts; 1274b169a6bSchristos unsigned_1 carry; 1284b169a6bSchristos bool imm_unsigned; 1294e98e3e1Schristos short ra, rb, rd; 1304b169a6bSchristos unsigned_4 oldpc, newpc; 1314e98e3e1Schristos short delay_slot_enable; 1324e98e3e1Schristos short branch_taken; 1334e98e3e1Schristos short num_delay_slot; /* UNUSED except as reqd parameter */ 1344e98e3e1Schristos enum microblaze_instr_type insn_type; 1354e98e3e1Schristos 1364e98e3e1Schristos memops = 0; 1374e98e3e1Schristos bonus_cycles = 0; 1384e98e3e1Schristos insts = 0; 1394e98e3e1Schristos 140212397c6Schristos while (1) 1414e98e3e1Schristos { 1424e98e3e1Schristos /* Fetch the initial instructions that we'll decode. */ 143212397c6Schristos inst = MEM_RD_WORD (PC & 0xFFFFFFFC); 1444e98e3e1Schristos 1454e98e3e1Schristos op = get_insn_microblaze (inst, &imm_unsigned, &insn_type, 1464e98e3e1Schristos &num_delay_slot); 1474e98e3e1Schristos 1484e98e3e1Schristos if (op == invalid_inst) 1494e98e3e1Schristos fprintf (stderr, "Unknown instruction 0x%04x", inst); 1504e98e3e1Schristos 1514e98e3e1Schristos if (tracing) 1524e98e3e1Schristos fprintf (stderr, "%.4x: inst = %.4x ", PC, inst); 1534e98e3e1Schristos 1544e98e3e1Schristos rd = GET_RD; 1554e98e3e1Schristos rb = GET_RB; 1564e98e3e1Schristos ra = GET_RA; 1574e98e3e1Schristos /* immword = IMM_W; */ 1584e98e3e1Schristos 1594e98e3e1Schristos oldpc = PC; 1604e98e3e1Schristos delay_slot_enable = 0; 1614e98e3e1Schristos branch_taken = 0; 1624e98e3e1Schristos if (op == microblaze_brk) 163212397c6Schristos sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP); 1644e98e3e1Schristos else if (inst == MICROBLAZE_HALT_INST) 1654e98e3e1Schristos { 1664e98e3e1Schristos insts += 1; 1674e98e3e1Schristos bonus_cycles++; 1684b169a6bSchristos TRACE_INSN (cpu, "HALT (%i)", RETREG); 169212397c6Schristos sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_exited, RETREG); 1704e98e3e1Schristos } 1714e98e3e1Schristos else 1724e98e3e1Schristos { 1734e98e3e1Schristos switch(op) 1744e98e3e1Schristos { 1754e98e3e1Schristos #define INSTRUCTION(NAME, OPCODE, TYPE, ACTION) \ 1764e98e3e1Schristos case NAME: \ 1774b169a6bSchristos TRACE_INSN (cpu, #NAME); \ 1784e98e3e1Schristos ACTION; \ 1794e98e3e1Schristos break; 1804e98e3e1Schristos #include "microblaze.isa" 1814e98e3e1Schristos #undef INSTRUCTION 1824e98e3e1Schristos 1834e98e3e1Schristos default: 184212397c6Schristos sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_signalled, 185212397c6Schristos SIM_SIGILL); 1864e98e3e1Schristos fprintf (stderr, "ERROR: Unknown opcode\n"); 1874e98e3e1Schristos } 1884e98e3e1Schristos /* Make R0 consistent */ 1894e98e3e1Schristos CPU.regs[0] = 0; 1904e98e3e1Schristos 1914e98e3e1Schristos /* Check for imm instr */ 1924e98e3e1Schristos if (op == imm) 1934e98e3e1Schristos IMM_ENABLE = 1; 1944e98e3e1Schristos else 1954e98e3e1Schristos IMM_ENABLE = 0; 1964e98e3e1Schristos 1974e98e3e1Schristos /* Update cycle counts */ 1984e98e3e1Schristos insts ++; 1994e98e3e1Schristos if (insn_type == memory_store_inst || insn_type == memory_load_inst) 2004e98e3e1Schristos memops++; 2014e98e3e1Schristos if (insn_type == mult_inst) 2024e98e3e1Schristos bonus_cycles++; 2034e98e3e1Schristos if (insn_type == barrel_shift_inst) 2044e98e3e1Schristos bonus_cycles++; 2054e98e3e1Schristos if (insn_type == anyware_inst) 2064e98e3e1Schristos bonus_cycles++; 2074e98e3e1Schristos if (insn_type == div_inst) 2084e98e3e1Schristos bonus_cycles += 33; 2094e98e3e1Schristos 2104e98e3e1Schristos if ((insn_type == branch_inst || insn_type == return_inst) 2114e98e3e1Schristos && branch_taken) 2124e98e3e1Schristos { 2134e98e3e1Schristos /* Add an extra cycle for taken branches */ 2144e98e3e1Schristos bonus_cycles++; 2154e98e3e1Schristos /* For branch instructions handle the instruction in the delay slot */ 2164e98e3e1Schristos if (delay_slot_enable) 2174e98e3e1Schristos { 2184e98e3e1Schristos newpc = PC; 2194e98e3e1Schristos PC = oldpc + INST_SIZE; 220212397c6Schristos inst = MEM_RD_WORD (PC & 0xFFFFFFFC); 2214e98e3e1Schristos op = get_insn_microblaze (inst, &imm_unsigned, &insn_type, 2224e98e3e1Schristos &num_delay_slot); 2234e98e3e1Schristos if (op == invalid_inst) 2244e98e3e1Schristos fprintf (stderr, "Unknown instruction 0x%04x", inst); 2254e98e3e1Schristos if (tracing) 2264e98e3e1Schristos fprintf (stderr, "%.4x: inst = %.4x ", PC, inst); 2274e98e3e1Schristos rd = GET_RD; 2284e98e3e1Schristos rb = GET_RB; 2294e98e3e1Schristos ra = GET_RA; 2304e98e3e1Schristos /* immword = IMM_W; */ 2314e98e3e1Schristos if (op == microblaze_brk) 2324e98e3e1Schristos { 233212397c6Schristos if (STATE_VERBOSE_P (sd)) 2344e98e3e1Schristos fprintf (stderr, "Breakpoint set in delay slot " 2354e98e3e1Schristos "(at address 0x%x) will not be honored\n", PC); 2364e98e3e1Schristos /* ignore the breakpoint */ 2374e98e3e1Schristos } 2384e98e3e1Schristos else if (insn_type == branch_inst || insn_type == return_inst) 2394e98e3e1Schristos { 240212397c6Schristos if (STATE_VERBOSE_P (sd)) 2414e98e3e1Schristos fprintf (stderr, "Cannot have branch or return instructions " 2424e98e3e1Schristos "in delay slot (at address 0x%x)\n", PC); 243212397c6Schristos sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_signalled, 244212397c6Schristos SIM_SIGILL); 2454e98e3e1Schristos } 2464e98e3e1Schristos else 2474e98e3e1Schristos { 2484e98e3e1Schristos switch(op) 2494e98e3e1Schristos { 2504e98e3e1Schristos #define INSTRUCTION(NAME, OPCODE, TYPE, ACTION) \ 2514e98e3e1Schristos case NAME: \ 2524e98e3e1Schristos ACTION; \ 2534e98e3e1Schristos break; 2544e98e3e1Schristos #include "microblaze.isa" 2554e98e3e1Schristos #undef INSTRUCTION 2564e98e3e1Schristos 2574e98e3e1Schristos default: 258212397c6Schristos sim_engine_halt (sd, NULL, NULL, NULL_CIA, 259212397c6Schristos sim_signalled, SIM_SIGILL); 2604e98e3e1Schristos fprintf (stderr, "ERROR: Unknown opcode at 0x%x\n", PC); 2614e98e3e1Schristos } 2624e98e3e1Schristos /* Update cycle counts */ 2634e98e3e1Schristos insts++; 2644e98e3e1Schristos if (insn_type == memory_store_inst 2654e98e3e1Schristos || insn_type == memory_load_inst) 2664e98e3e1Schristos memops++; 2674e98e3e1Schristos if (insn_type == mult_inst) 2684e98e3e1Schristos bonus_cycles++; 2694e98e3e1Schristos if (insn_type == barrel_shift_inst) 2704e98e3e1Schristos bonus_cycles++; 2714e98e3e1Schristos if (insn_type == anyware_inst) 2724e98e3e1Schristos bonus_cycles++; 2734e98e3e1Schristos if (insn_type == div_inst) 2744e98e3e1Schristos bonus_cycles += 33; 2754e98e3e1Schristos } 2764e98e3e1Schristos /* Restore the PC */ 2774e98e3e1Schristos PC = newpc; 2784e98e3e1Schristos /* Make R0 consistent */ 2794e98e3e1Schristos CPU.regs[0] = 0; 2804e98e3e1Schristos /* Check for imm instr */ 2814e98e3e1Schristos if (op == imm) 2824e98e3e1Schristos IMM_ENABLE = 1; 2834e98e3e1Schristos else 2844e98e3e1Schristos IMM_ENABLE = 0; 2854e98e3e1Schristos } 2864e98e3e1Schristos else 2874b169a6bSchristos { 2884b169a6bSchristos if (op == brki && IMM == 8) 2894b169a6bSchristos { 2904b169a6bSchristos RETREG = sim_syscall (cpu, CPU.regs[12], CPU.regs[5], 2914b169a6bSchristos CPU.regs[6], CPU.regs[7], 2924b169a6bSchristos CPU.regs[8]); 2934b169a6bSchristos PC = RD + INST_SIZE; 2944b169a6bSchristos } 2954b169a6bSchristos 2964e98e3e1Schristos /* no delay slot: increment cycle count */ 2974e98e3e1Schristos bonus_cycles++; 2984e98e3e1Schristos } 2994e98e3e1Schristos } 3004b169a6bSchristos } 3014e98e3e1Schristos 3024e98e3e1Schristos if (tracing) 3034e98e3e1Schristos fprintf (stderr, "\n"); 304212397c6Schristos 305212397c6Schristos if (sim_events_tick (sd)) 306212397c6Schristos sim_events_process (sd); 3074e98e3e1Schristos } 3084e98e3e1Schristos 3094e98e3e1Schristos /* Hide away the things we've cached while executing. */ 3104e98e3e1Schristos /* CPU.pc = pc; */ 3114e98e3e1Schristos CPU.insts += insts; /* instructions done ... */ 3124e98e3e1Schristos CPU.cycles += insts; /* and each takes a cycle */ 3134e98e3e1Schristos CPU.cycles += bonus_cycles; /* and extra cycles for branches */ 3144e98e3e1Schristos CPU.cycles += memops; /* and memop cycle delays */ 3154e98e3e1Schristos } 3164e98e3e1Schristos 317ba340e45Schristos static int 3184b169a6bSchristos microblaze_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length) 3194e98e3e1Schristos { 3204e98e3e1Schristos if (rn < NUM_REGS + NUM_SPECIAL && rn >= 0) 3214e98e3e1Schristos { 3224e98e3e1Schristos if (length == 4) 3234e98e3e1Schristos { 3244e98e3e1Schristos /* misalignment safe */ 3254e98e3e1Schristos long ival = microblaze_extract_unsigned_integer (memory, 4); 3264e98e3e1Schristos if (rn < NUM_REGS) 3274e98e3e1Schristos CPU.regs[rn] = ival; 3284e98e3e1Schristos else 3294e98e3e1Schristos CPU.spregs[rn-NUM_REGS] = ival; 3304e98e3e1Schristos return 4; 3314e98e3e1Schristos } 3324e98e3e1Schristos else 3334e98e3e1Schristos return 0; 3344e98e3e1Schristos } 3354e98e3e1Schristos else 3364e98e3e1Schristos return 0; 3374e98e3e1Schristos } 3384e98e3e1Schristos 339ba340e45Schristos static int 3404b169a6bSchristos microblaze_reg_fetch (SIM_CPU *cpu, int rn, void *memory, int length) 3414e98e3e1Schristos { 3424e98e3e1Schristos long ival; 3434e98e3e1Schristos 3444e98e3e1Schristos if (rn < NUM_REGS + NUM_SPECIAL && rn >= 0) 3454e98e3e1Schristos { 3464e98e3e1Schristos if (length == 4) 3474e98e3e1Schristos { 3484e98e3e1Schristos if (rn < NUM_REGS) 3494e98e3e1Schristos ival = CPU.regs[rn]; 3504e98e3e1Schristos else 3514e98e3e1Schristos ival = CPU.spregs[rn-NUM_REGS]; 3524e98e3e1Schristos 3534e98e3e1Schristos /* misalignment-safe */ 3544e98e3e1Schristos microblaze_store_unsigned_integer (memory, 4, ival); 3554e98e3e1Schristos return 4; 3564e98e3e1Schristos } 3574e98e3e1Schristos else 3584e98e3e1Schristos return 0; 3594e98e3e1Schristos } 3604e98e3e1Schristos else 3614e98e3e1Schristos return 0; 3624e98e3e1Schristos } 3634e98e3e1Schristos 3644e98e3e1Schristos void 365*0d3e0572Schristos sim_info (SIM_DESC sd, bool verbose) 3664e98e3e1Schristos { 367212397c6Schristos SIM_CPU *cpu = STATE_CPU (sd, 0); 368212397c6Schristos host_callback *callback = STATE_CALLBACK (sd); 3694e98e3e1Schristos 3704e98e3e1Schristos callback->printf_filtered (callback, "\n\n# instructions executed %10d\n", 3714e98e3e1Schristos CPU.insts); 3724e98e3e1Schristos callback->printf_filtered (callback, "# cycles %10d\n", 3734e98e3e1Schristos (CPU.cycles) ? CPU.cycles+2 : 0); 3744e98e3e1Schristos } 3754e98e3e1Schristos 376212397c6Schristos static sim_cia 377212397c6Schristos microblaze_pc_get (sim_cpu *cpu) 378212397c6Schristos { 379*0d3e0572Schristos return MICROBLAZE_SIM_CPU (cpu)->spregs[0]; 3804e98e3e1Schristos } 3814e98e3e1Schristos 382212397c6Schristos static void 383212397c6Schristos microblaze_pc_set (sim_cpu *cpu, sim_cia pc) 3844e98e3e1Schristos { 385*0d3e0572Schristos MICROBLAZE_SIM_CPU (cpu)->spregs[0] = pc; 386212397c6Schristos } 3874e98e3e1Schristos 388212397c6Schristos static void 389212397c6Schristos free_state (SIM_DESC sd) 390212397c6Schristos { 391212397c6Schristos if (STATE_MODULES (sd) != NULL) 392212397c6Schristos sim_module_uninstall (sd); 393212397c6Schristos sim_cpu_free_all (sd); 394212397c6Schristos sim_state_free (sd); 395212397c6Schristos } 3964e98e3e1Schristos 3974e98e3e1Schristos SIM_DESC 398ba340e45Schristos sim_open (SIM_OPEN_KIND kind, host_callback *cb, 399ba340e45Schristos struct bfd *abfd, char * const *argv) 4004e98e3e1Schristos { 401212397c6Schristos int i; 402212397c6Schristos SIM_DESC sd = sim_state_alloc (kind, cb); 403212397c6Schristos SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 4044e98e3e1Schristos 405212397c6Schristos /* The cpu data is kept in a separately allocated chunk of memory. */ 406*0d3e0572Schristos if (sim_cpu_alloc_all_extra (sd, 0, sizeof (struct microblaze_regset)) 407*0d3e0572Schristos != SIM_RC_OK) 408212397c6Schristos { 409212397c6Schristos free_state (sd); 410212397c6Schristos return 0; 411212397c6Schristos } 4124e98e3e1Schristos 413212397c6Schristos if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) 414212397c6Schristos { 415212397c6Schristos free_state (sd); 416212397c6Schristos return 0; 417212397c6Schristos } 4184e98e3e1Schristos 419ba340e45Schristos /* The parser will print an error message for us, so we silently return. */ 420212397c6Schristos if (sim_parse_args (sd, argv) != SIM_RC_OK) 421212397c6Schristos { 422212397c6Schristos free_state (sd); 423212397c6Schristos return 0; 424212397c6Schristos } 4254e98e3e1Schristos 426212397c6Schristos /* Check for/establish the a reference program image. */ 4274b169a6bSchristos if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK) 428212397c6Schristos { 429212397c6Schristos free_state (sd); 430212397c6Schristos return 0; 431212397c6Schristos } 4324e98e3e1Schristos 433212397c6Schristos /* Configure/verify the target byte order and other runtime 434212397c6Schristos configuration options. */ 435212397c6Schristos if (sim_config (sd) != SIM_RC_OK) 436212397c6Schristos { 437212397c6Schristos sim_module_uninstall (sd); 438212397c6Schristos return 0; 439212397c6Schristos } 440212397c6Schristos 441212397c6Schristos if (sim_post_argv_init (sd) != SIM_RC_OK) 442212397c6Schristos { 443212397c6Schristos /* Uninstall the modules to avoid memory leaks, 444212397c6Schristos file descriptor leaks, etc. */ 445212397c6Schristos sim_module_uninstall (sd); 446212397c6Schristos return 0; 447212397c6Schristos } 448212397c6Schristos 449212397c6Schristos /* CPU specific initialization. */ 450212397c6Schristos for (i = 0; i < MAX_NR_PROCESSORS; ++i) 451212397c6Schristos { 452212397c6Schristos SIM_CPU *cpu = STATE_CPU (sd, i); 453212397c6Schristos 454ba340e45Schristos CPU_REG_FETCH (cpu) = microblaze_reg_fetch; 455ba340e45Schristos CPU_REG_STORE (cpu) = microblaze_reg_store; 456212397c6Schristos CPU_PC_FETCH (cpu) = microblaze_pc_get; 457212397c6Schristos CPU_PC_STORE (cpu) = microblaze_pc_set; 458212397c6Schristos 459212397c6Schristos set_initial_gprs (cpu); 460212397c6Schristos } 461212397c6Schristos 462212397c6Schristos /* Default to a 8 Mbyte (== 2^23) memory space. */ 463212397c6Schristos sim_do_commandf (sd, "memory-size 0x800000"); 464212397c6Schristos 465212397c6Schristos return sd; 4664e98e3e1Schristos } 4674e98e3e1Schristos 4684e98e3e1Schristos SIM_RC 469ba340e45Schristos sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd, 470ba340e45Schristos char * const *argv, char * const *env) 4714e98e3e1Schristos { 472212397c6Schristos SIM_CPU *cpu = STATE_CPU (sd, 0); 4734e98e3e1Schristos 4744e98e3e1Schristos PC = bfd_get_start_address (prog_bfd); 4754e98e3e1Schristos 4764e98e3e1Schristos return SIM_RC_OK; 4774e98e3e1Schristos } 478