fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 343 lines 7.2 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/arch/simarm/main.c * 7 * Created: 2004-11-04 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2004-2022 Hampa Hug <hampa@hampa.ch> * 9 * Copyright: (C) 2004-2006 Lukas Ruf <ruf@lpr.ch> * 10 *****************************************************************************/ 11 12/***************************************************************************** 13 * This program is free software. You can redistribute it and / or modify it * 14 * under the terms of the GNU General Public License version 2 as published * 15 * by the Free Software Foundation. * 16 * * 17 * This program is distributed in the hope that it will be useful, but * 18 * WITHOUT ANY WARRANTY, without even the implied warranty of * 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 20 * Public License for more details. * 21 *****************************************************************************/ 22 23/***************************************************************************** 24 * This software was developed at the Computer Engineering and Networks * 25 * Laboratory (TIK), Swiss Federal Institute of Technology (ETH) Zurich. * 26 *****************************************************************************/ 27 28 29#include "main.h" 30 31#include <stdio.h> 32#include <stdlib.h> 33#include <stdarg.h> 34#include <signal.h> 35 36#include "cmd_arm.h" 37#include "simarm.h" 38 39#include <lib/cfg.h> 40#include <lib/cmd.h> 41#include <lib/console.h> 42#include <lib/getopt.h> 43#include <lib/log.h> 44#include <lib/monitor.h> 45#include <lib/path.h> 46#include <lib/sysdep.h> 47 48#include <libini/libini.h> 49 50 51static pce_option_t opts[] = { 52 { '?', 0, "help", NULL, "Print usage information" }, 53 { 'c', 1, "config", "string", "Set the config file name [none]" }, 54 { 'd', 1, "path", "string", "Add a directory to the search path" }, 55 { 'i', 1, "ini-prefix", "string", "Add an ini string before the config file" }, 56 { 'I', 1, "ini-append", "string", "Add an ini string after the config file" }, 57 { 'l', 1, "log", "string", "Set the log file name [none]" }, 58 { 'q', 0, "quiet", NULL, "Set the log level to error [no]" }, 59 { 'r', 0, "run", NULL, "Start running immediately [no]" }, 60 { 'v', 0, "verbose", NULL, "Set the log level to debug [no]" }, 61 { 'V', 0, "version", NULL, "Print version information" }, 62 { -1, 0, NULL, NULL, NULL } 63}; 64 65 66unsigned par_xlat = ARM_XLAT_CPU; 67 68simarm_t *par_sim = NULL; 69 70unsigned par_sig_int = 0; 71 72ini_sct_t *par_cfg = NULL; 73 74static ini_strings_t par_ini_str; 75 76 77static 78void print_help (void) 79{ 80 pce_getopt_help ( 81 "pce-simarm: ARM emulator", 82 "usage: pce-simarm [options]", 83 opts 84 ); 85 86 fflush (stdout); 87} 88 89static 90void print_version (void) 91{ 92 fputs ( 93 "pce-simarm version " PCE_VERSION_STR 94 "\n\n" 95 "Copyright (C) 1995-" PCE_YEAR " Hampa Hug <hampa@hampa.ch>\n", 96 stdout 97 ); 98 99 fflush (stdout); 100} 101 102static 103void sim_log_banner (void) 104{ 105 pce_log_inf ( 106 "pce-simarm version " PCE_VERSION_STR "\n" 107 "Copyright (C) 2004-" PCE_YEAR " Hampa Hug <hampa@hampa.ch>\n" 108 ); 109} 110 111static 112void sig_int (int s) 113{ 114 fprintf (stderr, "\npce-simarm: sigint\n"); 115 fflush (stderr); 116 117 par_sim->brk = PCE_BRK_STOP; 118} 119 120static 121void sig_term (int s) 122{ 123 fprintf (stderr, "\npce-simarm: sigterm\n"); 124 fflush (stderr); 125 126 if (par_sim->brk == PCE_BRK_ABORT) { 127 pce_set_fd_interactive (0, 1); 128 exit (1); 129 } 130 131 par_sim->brk = PCE_BRK_ABORT; 132} 133 134static 135void sig_segv (int s) 136{ 137 fprintf (stderr, "pce-simarm: segmentation fault\n"); 138 139 if ((par_sim != NULL) && (par_sim->cpu != NULL)) { 140 sarm_prt_state_cpu (par_sim->cpu, stderr); 141 } 142 143 fflush (stderr); 144 145 pce_set_fd_interactive (0, 1); 146 147 exit (1); 148} 149 150static 151int cmd_get_sym (simarm_t *sim, const char *sym, unsigned long *val) 152{ 153 if (arm_get_reg (sim->cpu, sym, val) == 0) { 154 return (0); 155 } 156 157 return (1); 158} 159 160static 161int cmd_set_sym (simarm_t *sim, const char *sym, unsigned long val) 162{ 163 if (arm_set_reg (sim->cpu, sym, val) == 0) { 164 return (0); 165 } 166 167 return (1); 168} 169 170static 171unsigned char sim_get_mem8 (simarm_t *sim, unsigned long addr) 172{ 173 unsigned char val; 174 175 if (arm_get_mem8 (sim->cpu, addr, par_xlat, &val)) { 176 val = 0xff; 177 } 178 179 return (val); 180} 181 182static 183void sim_set_mem8 (simarm_t *sim, unsigned long addr, unsigned char val) 184{ 185 if (arm_set_mem8 (sim->cpu, addr, par_xlat, val)) { 186 ; /* TLB miss */ 187 } 188} 189 190int main (int argc, char *argv[]) 191{ 192 int r; 193 char **optarg; 194 int run; 195 char *cfg; 196 ini_sct_t *sct; 197 monitor_t mon; 198 199 cfg = NULL; 200 run = 0; 201 202 pce_log_init(); 203 pce_log_add_fp (stderr, 0, MSG_INF); 204 205 par_cfg = ini_sct_new (NULL); 206 207 if (par_cfg == NULL) { 208 return (1); 209 } 210 211 ini_str_init (&par_ini_str); 212 213 while (1) { 214 r = pce_getopt (argc, argv, &optarg, opts); 215 216 if (r == GETOPT_DONE) { 217 break; 218 } 219 220 if (r < 0) { 221 return (1); 222 } 223 224 switch (r) { 225 case '?': 226 print_help(); 227 return (0); 228 229 case 'V': 230 print_version(); 231 return (0); 232 233 case 'c': 234 cfg = optarg[0]; 235 break; 236 237 case 'd': 238 pce_path_set (optarg[0]); 239 break; 240 241 case 'i': 242 if (ini_read_str (par_cfg, optarg[0])) { 243 fprintf (stderr, 244 "%s: error parsing ini string (%s)\n", 245 argv[0], optarg[0] 246 ); 247 return (1); 248 } 249 break; 250 251 case 'I': 252 ini_str_add (&par_ini_str, optarg[0], "\n", NULL); 253 break; 254 255 case 'l': 256 pce_log_add_fname (optarg[0], MSG_DEB); 257 break; 258 259 case 'q': 260 pce_log_set_level (stderr, MSG_ERR); 261 break; 262 263 case 'r': 264 run = 1; 265 break; 266 267 case 'v': 268 pce_log_set_level (stderr, MSG_DEB); 269 break; 270 271 case 0: 272 fprintf (stderr, "%s: unknown option (%s)\n", 273 argv[0], optarg[0] 274 ); 275 return (1); 276 277 default: 278 return (1); 279 } 280 } 281 282 sim_log_banner(); 283 284 if (pce_load_config (par_cfg, cfg)) { 285 return (1); 286 } 287 288 sct = ini_next_sct (par_cfg, NULL, "simarm"); 289 290 if (sct == NULL) { 291 sct = par_cfg; 292 } 293 294 if (ini_str_eval (&par_ini_str, sct, 1)) { 295 return (1); 296 } 297 298 pce_path_ini (sct); 299 300 par_sim = sarm_new (sct); 301 302 signal (SIGINT, sig_int); 303 signal (SIGTERM, sig_term); 304 signal (SIGSEGV, sig_segv); 305 306#ifdef SIGPIPE 307 signal (SIGPIPE, SIG_IGN); 308#endif 309 310 pce_console_init (stdin, stdout); 311 312 mon_init (&mon); 313 mon_set_cmd_fct (&mon, sarm_do_cmd, par_sim); 314 mon_set_msg_fct (&mon, sarm_set_msg, par_sim); 315 mon_set_get_mem_fct (&mon, par_sim, sim_get_mem8); 316 mon_set_set_mem_fct (&mon, par_sim, sim_set_mem8); 317 mon_set_memory_mode (&mon, 0); 318 319 cmd_init (par_sim, cmd_get_sym, cmd_set_sym); 320 sarm_cmd_init (par_sim, &mon); 321 322 sarm_reset (par_sim); 323 324 if (run) { 325 sarm_run (par_sim); 326 if (par_sim->brk != PCE_BRK_ABORT) { 327 fputs ("\n", stdout); 328 } 329 } 330 else { 331 pce_puts ("type 'h' for help\n"); 332 } 333 334 mon_run (&mon); 335 336 sarm_del (par_sim); 337 338 mon_free (&mon); 339 pce_console_done(); 340 pce_log_done(); 341 342 return (0); 343}