void arm_dyncom_init(arm_core_t* core){ cpu_t* cpu = cpu_new(0, 0, arm_arch_func); /* init the reg structure */ cpu->rf.pc = &core->Reg[15]; cpu->rf.phys_pc = &core->Reg[15]; cpu->rf.grf = core->Reg; cpu->rf.srf = core->Spsr; cpu->cpu_data = (conf_object_t*)core; core->dyncom_cpu = get_conf_obj_by_cast(cpu, "cpu_t"); cpu->debug_func = arm_debug_func; sky_pref_t *pref = get_skyeye_pref(); if(pref->user_mode_sim){ cpu->syscall_func = arm_dyncom_syscall; } else cpu->syscall_func = NULL; cpu->dyncom_engine->code_start = 0x8000; cpu->dyncom_engine->code_end = 0x100000; cpu->dyncom_engine->code_entry = 0x80d0; return; }
void arm_user_mode_init(generic_arch_t * arch_instance) { sky_pref_t *pref = get_skyeye_pref(); if (pref->user_mode_sim) { sky_exec_info_t *info = get_skyeye_exec_info(); info->arch_page_size = 0x1000; info->arch_stack_top = 0x1ffffff0;// + 0x401fe7 - 0xff0; /* arbitrary value */ /* stack initial address specific to architecture may be placed here */ /* we need to mmap the stack space, if we are using skyeye space */ if (info->mmap_access) { /* get system stack size */ size_t stacksize = 0; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &stacksize); if (stacksize > info->arch_stack_top) { printf("arch_stack_top is too low\n"); stacksize = info->arch_stack_top; } /* Note: Skyeye is occupating 0x400000 to 0x600000 */ /* We do a mmap */ void* ret = mmap( (info->arch_stack_top) - stacksize, stacksize + 0x1000 , PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if (ret == MAP_FAILED){ /* ideally, we should find an empty space until it works */ printf("mmap error, stack couldn't be mapped: errno %d\n", errno); exit(-1); } else { memset(ret, '\0', stacksize); //printf("stack top has been defined at %x size %x\n", (uint32_t) ret + stacksize, stacksize); //info->arch_stack_top = (uint32_t) ret + stacksize; } } exec_stack_init(); ARM_CPU_State* cpu = get_current_cpu(); arm_core_t* core = &cpu->core[0]; uint32_t sp = info->initial_sp; core->Cpsr = 0x10; /* User mode */ /* FIXME: may need to add thumb */ core->Reg[13] = sp; core->Reg[10] = info->start_data; core->Reg[0] = 0; bus_read(32, sp + 4, &(core->Reg[1])); bus_read(32, sp + 8, &(core->Reg[2])); } }
static void arm_dyncom_syscall(cpu_t* cpu, uint32_t num){ arm_core_t* core = (arm_core_t*)cpu->cpu_data; sky_pref_t* pref = get_skyeye_pref(); if(pref->user_mode_sim) arm_dyncom_SWI(core, num); else ARMul_Abort(core,ARMul_SWIV); }
void tomem (unsigned char *memory, int val) { sky_pref_t* pref = get_skyeye_pref(); //pref->endian = Big_endian; if (pref->endian == Big_endian) { memory[0] = val >> 24; memory[1] = val >> 16; memory[2] = val >> 8; memory[3] = val >> 0; }
int frommem (unsigned char *memory) { sky_pref_t* pref = get_skyeye_pref(); //pref->endian = Big_endian; if (pref->endian == Big_endian) { return (memory[0] << 24) | (memory[1] << 16) | (memory[2] << 8) | (memory[3] << 0); } else { return (memory[3] << 24) | (memory[2] << 16) | (memory[1] << 8) | (memory[0] << 0); } }
static void mpc8641d_io_reset (void *state) { mpc8641d_io_t *io = &mpc8641d_io; /* Just for convience of boot linux */ //io->conf.ccsrbar = 0x000E0000; io->pic_global.frr = 0x6b0102; io->por_conf.porpllsr = 0x40004; io->lb_ctrl.lcrr = 0x80000008; io->i2c_reg.i2csr = 0x81; io->i2c_reg.i2cdfsrr = 0x10; io->pic_ram.ctpr0 = 0x0000000F; io->pic_global.svr = 0xFFFF; io->mpic.ipivpr[0] = io->mpic.ipivpr[1] = io->mpic.ipivpr[2] = io->mpic.ipivpr[3] = 0x80000000; io->uart[0].ier = 0x0; io->uart[0].iir = 0x1; io->uart[0].dlb = 0x1; //gCPU.mpic.iivpr[UART_IRQ] = 0x80800000; /* initialize interrupt controller */ int i = 0; for (; i < 32; i++) { io->pic_ram.iidr[i] = 0x1; io->pic_ram.iivpr[i] = 0x80800000; } /* Match os to select boot setting */ skyeye_config_t *config = get_current_config(); if (!strcmp(config->os->os_name, "linux")) { sky_pref_t* pref = get_skyeye_pref(); if(pref->user_mode_sim) mpc8641d_boot_application(); else mpc8641d_boot_linux(); } else if (!strcmp(config->os->os_name, "vxworks")) { mpc8641d_boot_vxworks(); } }
void mips_dyncom_init(mips_core_t *core) { cpu_t* cpu = cpu_new(0, 0, arch_func_mips); /* init the reg structure */ cpu->rf.pc = &core->pc; cpu->rf.phys_pc = &core->pc; cpu->rf.grf = core->gpr; cpu->rf.frf = core->fpr; cpu->rf.srf = core->cp0; cpu_set_flags_debug(cpu, 0 | CPU_DEBUG_PRINT_IR | CPU_DEBUG_LOG ); cpu_set_flags_codegen(cpu, CPU_CODEGEN_TAG_LIMIT); cpu->cpu_data = (conf_object_t*)core; core->dyncom_cpu = get_conf_obj_by_cast(cpu, "cpu_t"); cpu->debug_func = mips_debug_func; sky_pref_t *pref = get_skyeye_pref(); set_memory_operator(arch_mips_read_memory, arch_mips_write_memory); if(pref->user_mode_sim){ //cpu->syscall_func = mips_dyncom_syscall; cpu->syscall_func = NULL; } else cpu->syscall_func = NULL; cpu->dyncom_engine->code_start = 0x0; cpu->dyncom_engine->code_end = 0x100000; cpu->dyncom_engine->code_entry = 0x0; return; }
/* we will fork another process as the console daemon */ static int create_uart_console(struct uart_link_state * ul_state){ uint8_t buf[1024]; #define MAXHOSTNAME 256 char myhostname[MAXHOSTNAME]; int sv_skt; struct hostent * hp; int on, length; struct sockaddr_in server, from; char * froms; printf("In %s\n", __FUNCTION__); sv_skt = socket(AF_INET, SOCK_STREAM, 0); if (sv_skt < 0) SKYEYE_ERR("opening stream socket"); /* enable the reuse of this socket if this process dies */ if (setsockopt(sv_skt, SOL_SOCKET, SO_REUSEADDR, (uint8_t*)&on, sizeof(on))<0) SKYEYE_ERR("turning on REUSEADDR"); /* bind it */ retry: server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; sky_pref_t* pref = get_skyeye_pref(); server.sin_port = htons(pref->uart_port); /* bind to an OS selected local port */ if (bind(sv_skt, (struct sockaddr *)&server, sizeof(server)) < 0) { switch (errno) { case EAGAIN: goto retry; case EADDRINUSE: SKYEYE_ERR("Port is already in use\n"); default: SKYEYE_ERR("binding tcp stream socket"); } } length = sizeof(server); if (getsockname(sv_skt, (struct sockaddr *) &server, &length)==-1) SKYEYE_ERR("getting socket name"); listen(sv_skt, 1); gethostname(myhostname, MAXHOSTNAME); //printf("In %s, before main loop\n", __FUNCTION__); /* Create the client xterm */ //create_term(myhostname, ntohs(server.sin_port)); /* main loop */ do { if (!ul_state->tty_attached) { /* PRINTF(("\ndumbserial: Waiting for connection to : %s:%d\n", myhostname, ntohs(ds_server.sin_port))); */ //printf("Waiting for connection to %s:%d", myhostname, ntohs(server.sin_port)); length = sizeof(from); ul_state->tty_skt = accept(sv_skt, (struct sockaddr *)&from, (int*)&length); hp = gethostbyaddr((char *)&from.sin_addr, 4, AF_INET); if (hp == (struct hostent *)0) { froms = inet_ntoa(from.sin_addr); fprintf(stderr,"cant resolve hostname for %s\n", froms); } else { froms = hp->h_name; } /* PRINTF(("dumbserial: Accepted connection on %s:%d from %s:%d\n", myhostname, ntohs(ds_server.sin_port), froms, ntohs(from.sin_port))); */ //printf("Accepted connection.\n"); pthread_mutex_lock(&ul_state->tty_lock); ul_state->tty_attached = 1; pthread_mutex_unlock(&ul_state->tty_lock); pthread_cond_signal(&ul_state->tty_cv); } else { /* begin receive data. */ int res; struct pollfd fds; //printf("In %s, begin receive data\n", __FUNCTION__); #define POLL_TIMEOUT -1 /* wait forever ? FIXME ? */ fds.fd = ul_state->tty_skt; fds.events = POLLIN|POLLPRI; #if HOST_OS_SOLARIS9 /* { */ fds.events |= POLLRDNORM|POLLRDBAND; #endif /* } */ fds.revents = 0; res = poll(&fds, 1, POLL_TIMEOUT); if (fds.revents & POLLIN) { res = read(ul_state->tty_skt, buf, sizeof (buf)); if (res == 0) { /* a read of 0 bytes is an EOF */ pthread_mutex_lock(&ul_state->tty_lock); ul_state->tty_attached = 0; pthread_mutex_unlock(&ul_state->tty_lock); pthread_cond_signal(&ul_state->tty_cv); close(ul_state->tty_skt); //SANITY(dsp->tty_skt = -1;); } else if (res<0) { perror("read"); } else { int i; for (i = 0; i < res; i++) { if (ul_state->in.count < ul_state->in.size) { ul_state->in.bufp[ul_state->in.tail] = buf[i]; ul_state->in.tail++; if (ul_state->in.tail >= ul_state->in.size) ul_state->in.tail = 0; ul_state->in.count++; } else { fprintf(stderr, "Overflow for uart link.\n"); } } } }//if (fds.revents & POLLIN) } } while (1); return 0; }
ARMul_State * ARMul_NewState (ARMul_State *state) { unsigned i, j; memset (state, 0, sizeof (ARMul_State)); state->Emulate = RUN; for (i = 0; i < 16; i++) { state->Reg[i] = 0; for (j = 0; j < 7; j++) state->RegBank[j][i] = 0; } for (i = 0; i < 7; i++) state->Spsr[i] = 0; state->Mode = 0; state->CallDebug = FALSE; state->Debug = FALSE; state->VectorCatch = 0; state->Aborted = FALSE; state->Reseted = FALSE; state->Inted = 3; state->LastInted = 3; state->CommandLine = NULL; state->EventSet = 0; state->Now = 0; state->EventPtr = (struct EventNode **) malloc ((unsigned) EVENTLISTSIZE * sizeof (struct EventNode *)); #if DIFF_STATE state->state_log = fopen("/data/state.log", "w"); printf("create pc log file.\n"); #endif if (state->EventPtr == NULL) { printf ("SKYEYE: ARMul_NewState malloc state->EventPtr error\n"); skyeye_exit (-1); } for (i = 0; i < EVENTLISTSIZE; i++) *(state->EventPtr + i) = NULL; #if SAVE_LOG state->state_log = fopen("/tmp/state.log", "w"); printf("create pc log file.\n"); #else #if DIFF_LOG state->state_log = fopen("/tmp/state.log", "r"); printf("loaded pc log file.\n"); #endif #endif #ifdef ARM61 state->prog32Sig = LOW; state->data32Sig = LOW; #else state->prog32Sig = HIGH; state->data32Sig = HIGH; #endif state->lateabtSig = HIGH; state->bigendSig = LOW; //chy:2003-08-19 state->LastTime = 0; state->CP14R0_CCD = -1; /* ahe-ykl: common function for interpret and dyncom */ sky_pref_t *pref = get_skyeye_pref(); if (pref->user_mode_sim) register_callback(arm_user_mode_init, Bootmach_callback); memset(&state->exclusive_tag_array[0], 0xFF, sizeof(state->exclusive_tag_array[0]) * 128); state->exclusive_access_state = 0; //state->cpu = (cpu_config_t *) malloc (sizeof (cpu_config_t)); //state->mem_bank = (mem_config_t *) malloc (sizeof (mem_config_t)); return (state); }
void SIM_init(){ sky_pref_t* pref; char* welcome_str = get_front_message(); /* * get the corrent_config_file and do some initialization */ skyeye_config_t* config = get_current_config(); skyeye_option_init(config); /* * initialization of callback data structure, it needs to * be initialized at very beginning. */ init_callback(); /* * initilize the data structure for command * register some default built-in command */ init_command_list(); init_stepi(); /* * initialization of module manangement */ init_module_list(); /* * initialization of architecture and cores */ init_arch(); /* * initialization of bus and memory module */ init_bus(); /* * initialization of machine module */ init_mach(); /* * initialization of breakpoint, that depends on callback module. */ init_bp(); /* * get the current preference for simulator */ pref = get_skyeye_pref(); /* * loading all the modules in search directory */ if(!pref->module_search_dir) pref->module_search_dir = skyeye_strdup(default_lib_dir); SKY_load_all_modules(pref->module_search_dir, NULL); //skyeye_config_t *config; //config = malloc(sizeof(skyeye_config_t)); /* if(pref->autoboot == True){ SIM_start(); SIM_run(); } */ /* * if we run simulator in GUI or external IDE, we do not need to * launch our CLI. */ if(pref->interactive_mode == True){ SIM_cli(); } else{ SIM_start(); SIM_run(); } }
void SIM_start(void){ sky_pref_t *pref; /* get the current preference for simulator */ pref = get_skyeye_pref(); skyeye_config_t* config = get_current_config(); if(pref->conf_filename) skyeye_read_config(pref->conf_filename); if(config->arch == NULL){ skyeye_log(Error_log, __FUNCTION__, "Should provide valid arch option in your config file.\n"); return; } generic_arch_t *arch_instance = get_arch_instance(config->arch->arch_name); if(config->mach == NULL){ skyeye_log(Error_log, __FUNCTION__, "Should provide valid mach option in your config file.\n"); return; } arch_instance->init(); /* reset all the memory */ mem_reset(); config->mach->mach_init(arch_instance, config->mach); /* reset current arch_instanc */ arch_instance->reset(); /* reset all the values of mach */ io_reset(arch_instance); if(pref->exec_file){ exception_t ret; /* * If no relocation is indicated, we will load elf file by * virtual address */ if((((~pref->exec_load_mask) & pref->exec_load_base) == 0x0) && (arch_instance->mmu_write != NULL)) ret = load_elf(pref->exec_file, Virt_addr); else ret = load_elf(pref->exec_file, Phys_addr); } /* set pc from config */ generic_address_t pc = (config->start_address & pref->exec_load_mask)|pref->exec_load_base; skyeye_log(Info_log, __FUNCTION__, "Set PC to the address 0x%x\n", pc); arch_instance->set_pc(pc); /* Call bootmach callback */ exec_callback(Bootmach_callback, arch_instance); pthread_t id; create_thread(skyeye_loop, arch_instance, &id); /* * At this time, if we set conf file, then we parse it * Or do it later. */ /* if(pref->conf_filename) skyeye_read_config(pref->conf_filename); */ #if 0 else{ /* try to run in batch mode */ if(skyeye_read_config(pref->conf_filename) == No_exp){
int main (int argc, char **argv) { int ret; sky_pref_t* pref = get_skyeye_pref(); assert(pref != NULL); /* initialization of options from command line */ ret = init_option(argc, argv, pref); /* set the current preference for skyeye */ //update_skyeye_pref(pref); /* return non-zero represent not run skyeye */ if(ret != 0) exit(0); else SIM_init(); /* Do anything you want to do , or just deadloop here. */ while(1) ; #if 0 if(ret < 0) goto exit_skyeye; /* set some environment for running */ init_env(); /* initialization of all the data structure of simulation */ if((ret = init ()) < 0) goto exit_skyeye; #endif #if 0 /* load elf file when running elf image */ if (exec_file) { if (tea_load_exec (exec_file, 0)) { fprintf (stderr, "load \"%s\" error\n", exec_file); goto exit_skyeye; } #if !defined(__MINGW32__) /* get its symbol to debug */ init_symbol_table(exec_file); #endif } #endif /* set the start address for pc */ #if 0 if (skyeye_config.start_address != 0){ unsigned long addr = (skyeye_config.start_address & load_mask)|load_base; arch_instance->set_pc (addr); printf ("start addr is set to 0x%08x by exec file.\n", (unsigned int) addr); } #endif /* never return */ //SIM_start(); //fflush(stdout); #if 0 /* running simulaion */ if (remote_debugmode == 0) sim_resume (0); else{ printf ("remote_debugmode= %d, filename = %s, server TCP port is 12345\n", remote_debugmode, skyeye_config_filename); sim_debug (); } #endif exit_skyeye: return ret; }