URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [branches/] [stable_0_1_x/] [or1ksim/] [sim-config.c] - Rev 856
Go to most recent revision | Compare with Previous | Blame | View Log
/* config.c -- Simulator configuration Copyright (C) 1999 Damjan Lampret, lampret@opencores.org This file is part of OpenRISC 1000 Architectural Simulator. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Simulator configuration. Eventually this one will be a lot bigger. */ #include <stdlib.h> #include <limits.h> #include "sim-config.h" #include "abstract.h" #include "sprs.h" #include "spr_defs.h" #include "pic.h" #include "stats.h" #include "icache_model.h" #include "dcache_model.h" #include "profiler.h" #include "mprofiler.h" #define WARNING(s) fprintf (stderr, "WARNING: config.%s: %s\n", sections[section].name, (s)) #define ERROR(s) {fprintf (stderr, "ERROR: config.%s:%s\n", sections[section].name, s); if (runtime.sim.init) exit (1);} #define MERROR(s) {fprintf (stderr, "ERROR: %s\n", s); if (runtime.sim.init) exit (1);} #if !FAST_SIM struct config config; #endif struct runtime runtime; int section = 0; extern struct section { char *name; int flags; } sections[]; void init_defconfig() { int i; #if !FAST_SIM memset(&config, 0, sizeof(config)); /* Sim */ config.sim.exe_log = 0; config.sim.exe_log_type = EXE_LOG_HARDWARE; config.sim.exe_log_start = 0; config.sim.exe_log_end = 0; config.sim.exe_log_marker = 0; config.sim.spr_log = 0; strcpy (config.sim.exe_log_fn, "executed.log"); strcpy (config.sim.spr_log_fn, "spr.log"); config.sim.debug = 0; config.sim.verbose = 1; strcpy (config.sim.prof_fn, "sim.profile"); strcpy (config.sim.mprof_fn, "sim.mprofile"); strcpy (config.sim.fstdout, "stdout.txt"); strcpy (runtime.sim.script_fn, "(default)"); config.sim.clkcycle_ps = 4000; /* 4000 for 4ns (250MHz) */ if (config.sim.clkcycle_ps) config.sim.system_kfreq = (long)((1000000000.0 / (double)config.sim.clkcycle_ps)); else config.sim.system_kfreq = INT_MAX; if (config.sim.system_kfreq <= 0) config.sim.system_kfreq = 1; /* Memory */ config.memory.type = MT_UNKNOWN; config.memory.pattern = 0; config.memory.random_seed = -1; /* Generate new seed */ for (i = 0; i < MAX_MEMORIES; i++) config.memory.table[i].ce = -1; /* memory is disabled by default */ /* IMMU & DMMU*/ config.immu.enabled = 0; config.immu.hitdelay = 1; config.immu.missdelay = 1; config.dmmu.enabled = 0; config.dmmu.hitdelay = 1; config.dmmu.missdelay = 1; /* IC & DC */ config.ic.enabled = 0; config.ic.hitdelay = 1; config.ic.missdelay = 1; config.ic.nways = 0; config.ic.nsets = 0; config.ic.ustates = 0; config.dc.enabled = 0; config.dc.load_hitdelay = 2; config.dc.load_missdelay = 2; config.dc.nways = 0; config.dc.nsets = 0; config.dc.ustates = 0; config.dc.store_hitdelay = 0; config.dc.store_missdelay = 0; /* Memory Controller */ config.mc.enabled = 0; /* Uarts */ config.nuarts = 0; /* DMAs */ config.ndmas = 0; /* VGAs */ config.nvgas = 0; /* Frame buffer */ config.fb.enabled = 0; /* CPU */ config.cpu.superscalar = 0; config.sim.history = 0; config.cpu.hazards = 0; config.cpu.dependstats = 0; config.cpu.sbuf_len = 0; config.cpu.upr = SPR_UPR_UP | SPR_UPR_DCP | SPR_UPR_ICP | SPR_UPR_DMP | SPR_UPR_IMP | SPR_UPR_OB32P | SPR_UPR_DUP | SPR_UPR_PICP | SPR_UPR_PMP | SPR_UPR_TTP; config.cpu.sr = 0x00008003; /* Debug */ config.debug.enabled = 0; config.debug.gdb_enabled = 0; config.debug.server_port = 0; /* VAPI */ config.vapi.enabled = 0; strcpy (config.vapi.vapi_fn, "vapi.log"); /* Ethernet */ config.nethernets = 0; /* GPIO */ config.ngpios = 0; /* PM */ config.pm.enabled = 0; #endif /* Configure runtime */ memset(&runtime, 0, sizeof(runtime)); /* Sim */ runtime.sim.fexe_log = NULL; runtime.sim.fspr_log = NULL; runtime.sim.iprompt = 0; runtime.sim.fprof = NULL; runtime.sim.fmprof = NULL; runtime.sim.init = 1; runtime.sim.script_file_specified = 0; /* VAPI */ runtime.vapi.vapi_file = NULL; runtime.vapi.enabled = 0; } int parse_args(int argc, char *argv[]) { unsigned long val; argv++; argc--; while (argc) { if (strcmp(*argv, "profiler") == 0) { exit (main_profiler (argc, argv)); } else if (strcmp(*argv, "mprofiler") == 0) { exit (main_mprofiler (argc, argv)); } else if (*argv[0] != '-') { runtime.sim.filename = argv[0]; argc--; argv++; } else #if !FAST_SIM /* Constant cfg */ if (strcmp(*argv, "-f") == 0 || strcmp(*argv, "--file") == 0) { argv++; argc--; if (argv[0]) { read_script_file(argv[0]); argv++; argc--; } else { fprintf(stderr, "Configure filename not specified!\n"); return 1; } } else #endif if (strcmp(*argv, "--nosrv") == 0) { /* (CZ) */ config.debug.gdb_enabled = 0; argv++; argc--; } else if (strcmp(*argv, "--srv") == 0) { /* (CZ) */ char *s; if(!--argc) return 1; config.debug.enabled = 1; config.debug.gdb_enabled = 0; config.debug.server_port = strtol(*(++argv),&s,10); if(*s) return 1; argv++; argc--; } else if (strcmp(*argv, "-i") == 0) { runtime.sim.iprompt = 1; argv++; argc--; } else if (strcmp(*argv, "-v") == 0) { version(); exit(0); } else #if !FAST_SIM if (strcmp(*argv, "--profile") == 0) { config.sim.profile = 1; argv++; argc--; } else if (strcmp(*argv, "--mprofile") == 0) { config.sim.mprofile = 1; argv++; argc--; } else #endif if (strcmp(*argv, "--output-cfg") == 0) { runtime.sim.output_cfg = 1; argv++; argc--; } else { fprintf(stderr, "Unknown option: %s\n", *argv); return 1; } } if (!argc) return 0; return 0; } #if !FAST_SIM #define CNV(x) ((isspace(x) || (x) == 0) ? ' ' : (x)) /* Substitute for less powerful fscanf */ int fscanf_ex (FILE *f, char *fmt, void *buf, char *str) { char tmp[STR_SIZE]; char ch; int i = 0; while (*fmt) { switch (*fmt) { case '%': while(*fmt != 0 && !isalpha (*fmt)) tmp[i++] = *(fmt++); tmp[i++] = *(fmt++); if (tmp[i - 1] == 's') { char *cbuf = (char *)buf; i = 0; while (ch = (f ? fgetc (f) : *str++), isspace(ch)) if (f ? feof (f) : *str) return 1; if (f) ungetc (ch, f); else str--; while ((*(cbuf++) = ch = (f ? fgetc (f) : *str++), CNV(ch) ) != *fmt) { if ((f ? feof (f) : *str)) return 1; if (++i >= STR_SIZE) { fprintf (stderr, "ERROR: string too long.\n"); return 1; } } *(--cbuf) = 0; fmt++; } else { tmp[i++] = 0; if (f) fscanf (f, tmp, buf); else sscanf (str, tmp, buf); } break; default: while ((ch = (f ? fgetc (f) : *str++)) != *fmt) { if (!isspace (ch)) { char tmp[200]; sprintf (tmp, "unexpected char '%c' (expecting '%c')\n", ch, *fmt); fprintf (stderr, "WARNING: config.%s: %s\n", sections[section], tmp); WARNING(tmp); } if ((f ? feof (f) : *str)) return 1; } fmt++; break; } } return 0; } #endif /* !FAST_SIM */ void print_config() { if (config.sim.verbose) { char temp[20]; printf("Verbose on, "); if (config.sim.debug) printf("simdebug on, "); else printf("simdebug off, "); if (runtime.sim.iprompt) printf("interactive prompt on\n"); else printf("interactive prompt off\n"); printf("Machine initialization...\n"); generate_time_pretty (temp, config.sim.clkcycle_ps); printf("Clock cycle: %s\n", temp); if (testsprbits(SPR_UPR, SPR_UPR_DCP)) printf("Data cache present.\n"); else printf("No data cache.\n"); if (testsprbits(SPR_UPR, SPR_UPR_ICP)) printf("Insn cache tag present.\n"); else printf("No instruction cache.\n"); if (config.bpb.enabled) printf("BPB simulation on.\n"); else printf("BPB simulation off.\n"); if (config.bpb.btic) printf("BTIC simulation on.\n"); else printf("BTIC simulation off.\n"); } } #if !FAST_SIM /* Forward declarations of functions */ void base_include (); void sim_clkcycle (); void sim_exe_log_type (); void change_device (); void end_device (); void uart_nuarts (); void uart_baseaddr (); void uart_rxfile (); void uart_txfile (); void uart_jitter (); void uart_irq (); void uart_16550 (); void uart_vapi_id (); void dma_ndmas (); void dma_baseaddr (); void dma_irq (); void dma_vapi_id (); void memory_type (); void memory_nmemories (); void memory_ce (); void memory_baseaddr (); void memory_size (); void memory_name (); void memory_log (); void memory_delayr (); void memory_delayw (); void cpu_sbuf_len (); void eth_nethernets (); void eth_baseaddr (); void eth_irq (); void eth_dma (); void eth_rtx_type (); void eth_rx_channel (); void eth_tx_channel (); void eth_rxfile (); void eth_txfile (); void eth_sockif (); void eth_vapi_id (); void gpio_ngpios (); void gpio_baseaddr (); void gpio_irq (); void gpio_base_vapi_id (); void vga_nvgas (); void vga_baseaddr (); void vga_irq (); void vga_refresh_rate (); void vga_filename (); void vga_bufaddr (); void vga_paladdr (); void vga_refresh_rate (); void vga_filename (); void immu_enabled (); void immu_nsets (); void immu_nways (); void immu_pagesize (); void immu_entrysize (); void immu_ustates (); void dmmu_enabled (); void dmmu_nsets (); void dmmu_nways (); void dmmu_pagesize (); void dmmu_entrysize (); void dmmu_ustates (); void ic_enabled (); void ic_nsets (); void ic_nways (); void ic_blocksize (); void ic_ustates (); void dc_enabled (); void dc_nsets (); void dc_nways (); void dc_blocksize (); void dc_ustates (); unsigned long tempL; unsigned long tempUL; char tempS[STR_SIZE]; #define CPF_SUBSECTION 1 #define CPF_SUBFIELD 2 #define CPF_GLOBAL 4 /* Not part of the substructure (group) in config */ struct section sections[] = { {"base", 0}, /* 0 */ {"mc", 0}, {"uart", 0}, {"dma", 0}, {"memory", 0}, {"cpu", 0}, /* 5 */ {"sim", 0}, {"debug", 0}, {"VAPI", 0}, {"ethernet",0}, {"", 0}, /* 10 */ {"immu", 0}, {"dmmu", 0}, {"ic", 0}, {"dc", 0}, {"gpio", 0}, /* 15 */ {"bpb", 0}, {"pm", 0}, {"vga", 0}, {"fb", 0}, {"kbd", 0} /* 20 */ }; /* *INDENT-OFF* */ /* Parameter definitions */ struct config_params { int section; char *name; char *type; void (*func)(); void *addr; int attr; } config_params[] = { {0, "include", "\"%s\"", base_include, (void *)(&tempS), 0}, {1, "enabled", "=%i", NULL, (void *)(&config.mc.enabled), 0}, {1, "baseaddr", "=0x%x", NULL, (void *)(&config.mc.baseaddr), 0}, {1, "POC", "=0x%x", NULL, (void *)(&config.mc.POC), 0}, {2, "nuarts", "=%i", uart_nuarts, (void *)(&tempL), CPF_GLOBAL}, {2, "device", "%i", change_device, (void *)(&tempL), 0}, {2, "enddevice", "", end_device, NULL, 0}, {2, "baseaddr", "=0x%x", uart_baseaddr, (void *)(&tempUL), 0}, {2, "irq", "=%i", uart_irq, (void *)(&tempL), 0}, {2, "16550", "=%i", uart_16550, (void *)(&tempL), 0}, {2, "jitter", "=%i", uart_jitter, (void *)(&tempL), 0}, {2, "rxfile", "=\"%s\"", uart_rxfile, (void *)(&tempS[0]), 0}, {2, "txfile", "=\"%s\"", uart_txfile, (void *)(&tempS[0]), 0}, {2, "vapi_id", "=0x%x", uart_vapi_id, (void *)(&tempUL), 0}, {3, "ndmas", "=%i", dma_ndmas, (void *)(&tempL), CPF_GLOBAL}, {3, "device", "%i", change_device, (void *)(&tempL), 0}, {3, "enddevice", "", end_device, NULL, 0}, {3, "baseaddr", "=0x%x", dma_baseaddr, (void *)(&tempUL), 0}, {3, "irq", "=%i", dma_irq, (void *)(&tempL), 0}, {3, "vapi_id", "=0x%x", dma_vapi_id, (void *)(&tempUL), 0}, {4, "random_seed", "=%i", NULL, (void *)(&config.memory.random_seed), 0}, {4, "pattern", "=%i", NULL, (void *)(&config.memory.pattern), 0}, {4, "type", "=%s ", memory_type, (void *)(&tempS[0]), 0}, {4, "nmemories", "=%i", memory_nmemories,(void *)(&tempL), CPF_GLOBAL}, {4, "device", "%i", change_device, (void *)(&tempL), 0}, {4, "enddevice", "", end_device, NULL, 0}, {4, "ce", "=%i", memory_ce, (void *)(&tempL), 0}, {4, "baseaddr", "=0x%x", memory_baseaddr,(void *)(&tempUL), 0}, {4, "size", "=0x%x", memory_size, (void *)(&tempUL), 0}, {4, "name", "=\"%s\"", memory_name, (void *)(&tempS[0]), 0}, {4, "log", "=\"%s\"", memory_log, (void *)(&tempS[0]), 0}, {4, "delayr", "=%i", memory_delayr, (void *)(&tempL), 0}, {4, "delayw", "=%i", memory_delayw, (void *)(&tempL), 0}, {5, "ver", "=0x%x", NULL, (void *)(&config.cpu.ver), 0}, {5, "rev", "=0x%x", NULL, (void *)(&config.cpu.rev), 0}, {5, "upr", "=0x%x", NULL, (void *)(&config.cpu.upr), 0}, {5, "sr", "=0x%x", NULL, (void *)(&config.cpu.sr), 0}, {5, "hazards", "=%i", NULL, (void *)(&config.cpu.hazards), 0}, {5, "superscalar", "=%i", NULL, (void *)(&config.cpu.superscalar), 0}, {5, "dependstats", "=%i", NULL, (void *)(&config.cpu.dependstats), 0}, {5, "sbuf_len", "=%i", cpu_sbuf_len, (void *)(&config.cpu.sbuf_len), 0}, {6, "debug", "=%i", NULL, (void *)(&config.sim.debug), 0}, {6, "verbose", "=%i", NULL, (void *)(&config.sim.verbose), 0}, {6, "profile", "=%i", NULL, (void *)(&config.sim.profile), 0}, {6, "prof_fn", "=\"%s\"", NULL, (void *)(&config.sim.prof_fn[0]), 0}, {6, "mprofile", "=%i", NULL, (void *)(&config.sim.mprofile), 0}, {6, "mprof_fn", "=\"%s\"", NULL, (void *)(&config.sim.mprof_fn[0]), 0}, {6, "history", "=%i", NULL, (void *)(&config.sim.history), 0}, {6, "exe_log", "=%i", NULL, (void *)(&config.sim.exe_log), 0}, {6, "exe_log_type", "=%s ", sim_exe_log_type, (void *)(&tempS[0]), 0}, {6, "exe_log_start", "=%i", NULL, (void *)(&config.sim.exe_log_start), 0}, {6, "exe_log_end", "=%i", NULL, (void *)(&config.sim.exe_log_end), 0}, {6, "exe_log_marker", "=%i", NULL, (void *)(&config.sim.exe_log_marker), 0}, {6, "exe_log_fn", "=\"%s\"", NULL, (void *)(&config.sim.exe_log_fn[0]), 0}, {6, "spr_log", "=%i", NULL, (void *)(&config.sim.spr_log), 0}, {6, "spr_log_fn", "=\"%s\"", NULL, (void *)(&config.sim.spr_log_fn[0]), 0}, {6, "clkcycle", "=%s ", sim_clkcycle, (void *)(&tempS[0]), 0}, {6, "stdout", "=\"%s\"", NULL, (void *)(&config.sim.fstdout[0]), 0}, {7, "enabled", "=%i", NULL, (void *)(&config.debug.enabled), 0}, {7, "gdb_enabled", "=%i", NULL, (void *)(&config.debug.gdb_enabled), 0}, {7, "server_port", "=%i", NULL, (void *)(&config.debug.server_port), 0}, {7, "vapi_id", "=0x%x", NULL, (void *)(&config.debug.vapi_id), 0}, {8, "enabled", "=%i", NULL, (void *)(&config.vapi.enabled), 0}, {8, "server_port", "=%i", NULL, (void *)(&config.vapi.server_port), 0}, {8, "log_enabled", "=%i", NULL, (void *)(&config.vapi.log_enabled), 0}, {8, "hide_device_id", "=%i", NULL, (void *)(&config.vapi.hide_device_id), 0}, {8, "vapi_log_fn", "=\"%s\"", NULL, (void *)(&config.vapi.vapi_fn[0]), 0}, {9, "nethernets", "=%i", eth_nethernets,(void *)(&tempL), CPF_GLOBAL}, {9, "device", "%i", change_device, (void *)(&tempL), 0}, {9, "irq", "=%i", eth_irq, (void *)(&tempUL), 15}, {9, "enddevice", "", end_device, NULL, 0}, {9, "baseaddr", "=0x%x", eth_baseaddr, (void *)(&tempUL), 0}, {9, "dma", "=%i", eth_dma, (void *)(&tempL), 0}, {9, "rtx_type", "=%i", eth_rtx_type, (void *)(&tempUL), 0}, {9, "rx_channel", "=%i", eth_rx_channel,(void *)(&tempL), 0}, {9, "tx_channel", "=%i", eth_tx_channel,(void *)(&tempL), 0}, {9, "rxfile", "=\"%s\"", eth_rxfile, (void *)(&tempS[0]), 0}, {9, "txfile", "=\"%s\"", eth_txfile, (void *)(&tempS[0]), 0}, {9, "sockif", "=\"%s\"", eth_sockif, (void *)(&tempS[0]), 0}, {9, "vapi_id", "=0x%x", eth_vapi_id, (void *)(&tempUL), 0}, {11, "enabled", "=%i", immu_enabled, (void *)(&tempL), 0}, {11, "nsets", "=%i", immu_nsets, (void *)(&tempL), 0}, {11, "nways", "=%i", immu_nways, (void *)(&tempL), 0}, {11, "pagesize", "=%i", immu_pagesize, (void *)(&tempL), 0}, {11, "entrysize", "=%i", immu_entrysize,(void *)(&tempL), 0}, {11, "ustates", "=%i", immu_ustates, (void *)(&tempL), 0}, {11, "missdelay", "=%i", NULL, (void *)(&config.immu.missdelay), 0}, {11, "hitdelay", "=%i", NULL, (void *)(&config.immu.hitdelay), 0}, {12, "enabled", "=%i", dmmu_enabled, (void *)(&tempL), 0}, {12, "nsets", "=%i", dmmu_nsets, (void *)(&tempL), 0}, {12, "nways", "=%i", dmmu_nways, (void *)(&tempL), 0}, {12, "pagesize", "=%i", dmmu_pagesize, (void *)(&tempL), 0}, {12, "entrysize", "=%i", dmmu_entrysize,(void *)(&tempL), 0}, {12, "ustates", "=%i", dmmu_ustates, (void *)(&tempL), 0}, {12, "missdelay", "=%i", NULL, (void *)(&config.dmmu.missdelay), 0}, {12, "hitdelay", "=%i", NULL, (void *)(&config.dmmu.hitdelay), 0}, {13, "enabled", "=%i", ic_enabled, (void *)(&tempL), 0}, {13, "nsets", "=%i", ic_nsets, (void *)(&tempL), 0}, {13, "nways", "=%i", ic_nways, (void *)(&tempL), 0}, {13, "blocksize", "=%i", ic_blocksize, (void *)(&tempL), 0}, {13, "ustates", "=%i", ic_ustates, (void *)(&tempL), 0}, {13, "missdelay", "=%i", NULL, (void *)(&config.ic.missdelay), 0}, {13, "hitdelay", "=%i", NULL, (void *)(&config.ic.hitdelay), 0}, {14, "enabled", "=%i", dc_enabled, (void *)(&tempL), 0}, {14, "nsets", "=%i", dc_nsets, (void *)(&tempL), 0}, {14, "nways", "=%i", dc_nways, (void *)(&tempL), 0}, {14, "blocksize", "=%i", dc_blocksize, (void *)(&tempL), 0}, {14, "ustates", "=%i", dc_ustates, (void *)(&tempL), 0}, {14, "load_missdelay", "=%i", NULL, (void *)(&config.dc.load_missdelay), 0}, {14, "load_hitdelay", "=%i", NULL, (void *)(&config.dc.load_hitdelay), 0}, {14, "store_missdelay", "=%i", NULL, (void *)(&config.dc.store_missdelay), 0}, {14, "store_hitdelay", "=%i", NULL, (void *)(&config.dc.store_hitdelay), 0}, {15, "ngpios", "=%i", gpio_ngpios, (void *)(&tempL), CPF_GLOBAL}, {15, "device", "%i", change_device, (void *)(&tempL), 0}, {15, "baseaddr", "=0x%x", gpio_baseaddr, (void *)(&tempUL), 0}, {15, "irq", "=%i", gpio_irq, (void *)(&tempL), 0}, {15, "base_vapi_id", "=0x%x", gpio_base_vapi_id, (void *)(&tempUL), 0}, {15, "enddevice", "", end_device, NULL, 0}, {16, "enabled", "=%i", NULL, (void *)(&config.bpb.enabled), 0}, {16, "btic", "=%i", NULL, (void *)(&config.bpb.btic), 0}, {16, "sbp_bnf_fwd", "=%i", NULL, (void *)(&config.bpb.sbp_bnf_fwd), 0}, {16, "sbp_bf_fwd", "=%i", NULL, (void *)(&config.bpb.sbp_bf_fwd), 0}, {16, "missdelay", "=%i", NULL, (void *)(&config.bpb.missdelay), 0}, {16, "hitdelay", "=%i", NULL, (void *)(&config.bpb.hitdelay), 0}, {17, "enabled", "=%i", NULL, (void *)(&config.pm.enabled), 0}, {18, "nvgas", "=%i", vga_nvgas, (void *)(&tempL), CPF_GLOBAL}, {18, "device", "%i", change_device, (void *)(&tempL), 0}, {18, "baseaddr", "=0x%x", vga_baseaddr, (void *)(&tempUL), 0}, {18, "irq", "=%i", vga_irq, (void *)(&tempL), 0}, {18, "refresh_rate", "=%i", vga_refresh_rate, (void *)(&tempUL), 0}, {18, "filename", "=\"%s\"", vga_filename, (void *)(&tempS[0]), 0}, {18, "enddevice", "", end_device, NULL, 0}, {19, "enabled", "=%i", NULL, (void *)(&config.fb.enabled), 0}, {19, "baseaddr", "=0x%x", NULL, (void *)(&config.fb.baseaddr), 0}, {19, "refresh_rate", "=%i", NULL, (void *)(&config.fb.refresh_rate), 0}, {19, "filename", "=\"%s\"", NULL, (void *)(&config.fb.filename), 0}, {20, "enabled", "=%i", NULL, (void *)(&config.kbd.enabled), 0}, {20, "baseaddr", "=0x%x", NULL, (void *)(&config.kbd.baseaddr), 0}, {20, "irq", "=%i", NULL, (void *)(&config.kbd.irq), 0}, {20, "rxfile", "=\"%s\"", NULL, (void *)(&config.kbd.rxfile), 0} }; /* *INDENT-ON* */ int current_device = -1; void change_device () { current_device = tempL; } void end_device () { current_device = -1; } void base_include () { read_script_file (tempS); section = 0; } void sim_clkcycle () { int len = strlen (tempS); int pos = len - 1; long time; if (len < 2) goto err; if (tempS[pos--] != 's') goto err; switch (tempS[pos--]) { case 'p': time = 1; break; case 'n': time = 1000; break; case 'u': time = 1000000; break; case 'm': time = 1000000000; break; default: goto err; } tempS[pos + 1] = 0; config.sim.clkcycle_ps = time * atol (tempS); return; err: ERROR("invalid time format."); } void sim_exe_log_type () { if (strcmp (tempS, "default") == 0) config.sim.exe_log_type = EXE_LOG_HARDWARE; else if (strcmp (tempS, "hardware") == 0) config.sim.exe_log_type = EXE_LOG_HARDWARE; else if (strcmp (tempS, "simple") == 0) config.sim.exe_log_type = EXE_LOG_SIMPLE; else if (strcmp (tempS, "software") == 0) { config.sim.exe_log_type = EXE_LOG_SOFTWARE; } else { char tmp[200]; sprintf (tmp, "invalid execute log type '%s'.\n", tempS); ERROR(tmp); } } void uart_nuarts () { if (tempL >= 0 && tempL < MAX_UARTS) config.nuarts = tempL; else ERROR("invalid number of devices."); } void uart_baseaddr () { if (current_device >= 0 && current_device < config.nuarts) config.uarts[current_device].baseaddr = tempUL; else ERROR("invalid device number."); } void uart_jitter () { if (current_device >= 0 && current_device < config.nuarts) config.uarts[current_device].jitter = tempL; else ERROR("invalid device number."); } void uart_irq () { if (current_device >= 0 && current_device < config.nuarts) config.uarts[current_device].irq = tempL; else ERROR("invalid device number."); } void uart_16550 () { if (current_device >= 0 && current_device < config.nuarts) config.uarts[current_device].uart16550 = tempL; else ERROR("invalid device number."); } void uart_rxfile () { if (current_device >= 0 && current_device < config.nuarts) strcpy (config.uarts[current_device].rxfile, tempS); else ERROR("invalid device number."); } void uart_txfile () { if (current_device >= 0 && current_device < config.nuarts) strcpy (config.uarts[current_device].txfile, tempS); else ERROR("invalid device number."); } void uart_vapi_id () { if (current_device >= 0 && current_device < config.nuarts) config.uarts[current_device].vapi_id = tempUL; else ERROR("invalid device number."); } void dma_ndmas () { if (tempL >= 0 && tempL < MAX_DMAS) config.ndmas = tempL; else ERROR("invalid number of devices."); } void dma_baseaddr () { if (current_device >= 0 && current_device < config.ndmas) config.dmas[current_device].baseaddr = tempUL; else ERROR("invalid device number."); } void dma_irq () { if (current_device >= 0 && current_device < config.ndmas) config.dmas[current_device].irq = tempL; else ERROR("invalid device number."); } void dma_vapi_id () { if (current_device >= 0 && current_device < config.ndmas) config.dmas[current_device].vapi_id = tempUL; else ERROR("invalid device number."); } void memory_nmemories () { if (tempL >= 0 && tempL < MAX_MEMORIES) config.memory.nmemories = tempL; else ERROR("invalid number of devices."); } void memory_type () { if (strcmp (tempS, "unknown") == 0) config.memory.type = MT_UNKNOWN; else if (strcmp (tempS, "random") == 0) config.memory.type = MT_RANDOM; else if (strcmp (tempS, "pattern") == 0) config.memory.type = MT_PATTERN; else if (strcmp (tempS, "zero") == 0) { config.memory.type = MT_PATTERN; config.memory.pattern = 0; } else { char tmp[200]; sprintf (tmp, "invalid memory type '%s'.\n", tempS); ERROR(tmp); } } void memory_ce () { if (current_device >= 0 && current_device < config.memory.nmemories) config.memory.table[current_device].ce = tempL; else ERROR("invalid device number."); } void memory_baseaddr () { if (current_device >= 0 && current_device < config.memory.nmemories) config.memory.table[current_device].baseaddr = tempUL; else ERROR("invalid device number."); } void memory_size () { if (current_device >= 0 && current_device < config.memory.nmemories) config.memory.table[current_device].size = tempUL; else ERROR("invalid device number."); } void memory_name () { if (current_device >= 0 && current_device < config.memory.nmemories) strcpy (config.memory.table[current_device].name, tempS); else ERROR("invalid device number."); } void memory_log () { if (current_device >= 0 && current_device < config.memory.nmemories) strcpy (config.memory.table[current_device].log, tempS); else ERROR("invalid device number."); } void memory_delayr () { if (current_device >= 0 && current_device < config.memory.nmemories) config.memory.table[current_device].delayr = tempL; else ERROR("invalid device number."); } void memory_delayw () { if (current_device >= 0 && current_device < config.memory.nmemories) config.memory.table[current_device].delayw = tempL; else ERROR("invalid device number."); } void cpu_sbuf_len () { if (config.cpu.sbuf_len >= MAX_SBUF_LEN) { config.cpu.sbuf_len = MAX_SBUF_LEN - 1; WARNING("sbuf_len too large; truncated."); } else if (config.cpu.sbuf_len < 0) { config.cpu.sbuf_len = 0; WARNING("sbuf_len negative; disabled."); } } void eth_nethernets () { if (tempL >= 0 && tempL < MAX_ETHERNETS) config.nethernets = tempL; else ERROR("invalid number of devices."); } void eth_baseaddr () { if (current_device >= 0 && current_device < config.nethernets) config.ethernets[current_device].baseaddr = tempUL; else ERROR("invalid device number."); } void eth_dma () { if (current_device >= 0 && current_device < config.nethernets) config.ethernets[current_device].dma = tempL; else ERROR("invalid device number."); } void eth_rtx_type () { if (current_device >= 0 && current_device < config.nethernets) config.ethernets[current_device].rtx_type = tempUL; else ERROR("invalid device number."); } void eth_rx_channel () { if (current_device >= 0 && current_device < config.nethernets) config.ethernets[current_device].rx_channel = tempL; else ERROR("invalid device number."); } void eth_tx_channel () { if (current_device >= 0 && current_device < config.nethernets) config.ethernets[current_device].rx_channel = tempL; else ERROR("invalid device number."); } void eth_rxfile () { if (current_device >= 0 && current_device < config.nethernets) strcpy (config.ethernets[current_device].rxfile, tempS); else ERROR("invalid device number."); } void eth_txfile () { if (current_device >= 0 && current_device < config.nethernets) strcpy (config.ethernets[current_device].txfile, tempS); else ERROR("invalid device number."); } void eth_sockif () { if (current_device >= 0 && current_device < config.nethernets) strcpy (config.ethernets[current_device].sockif, tempS); else ERROR("invalid device number."); } void eth_irq () { if (current_device >= 0 && current_device < config.nethernets) config.ethernets[current_device].irq = tempUL; else ERROR("invalid device number."); } void eth_vapi_id () { if (current_device >= 0 && current_device < config.nethernets) config.ethernets[current_device].vapi_id = tempUL; else ERROR("invalid device number."); } void gpio_ngpios () { if (tempL >= 0 && tempL < MAX_GPIOS) config.ngpios = tempL; else ERROR("invalid number of devices."); } void gpio_baseaddr () { if (current_device >= 0 && current_device < config.ngpios) config.gpios[current_device].baseaddr = tempUL; else ERROR("invalid device number."); } void gpio_irq () { if (current_device >= 0 && current_device < config.ngpios) config.gpios[current_device].irq = tempL; else ERROR("invalid device number."); } void gpio_base_vapi_id () { if (current_device >= 0 && current_device < config.ngpios) config.gpios[current_device].base_vapi_id = tempUL; else ERROR("invalid device number."); } int is_power2 (int x) { while (!(x & 1)) x >>= 1; return x == 1; } void immu_enabled () { setsprbits (SPR_UPR, SPR_UPR_IMP, tempL & 1); config.immu.enabled = tempL; } void dmmu_enabled () { setsprbits (SPR_UPR, SPR_UPR_DMP, tempL & 1); config.dmmu.enabled = tempL; } void immu_nsets () { if (is_power2(tempL) && tempL <= 256) config.immu.nsets = tempL; else ERROR("value of power of two and lower or equal than 256 expected."); } void dmmu_nsets () { if (is_power2(tempL) && tempL <= 256) config.dmmu.nsets = tempL; else ERROR("value of power of two and lower or equal than 256 expected."); } void immu_nways () { if (tempL >= 1 && tempL <= 4) config.immu.nways = tempL; else ERROR("value 1, 2, 3 or 4 expected."); } void dmmu_nways () { if (tempL >= 1 && tempL <= 4) config.dmmu.nways = tempL; else ERROR("value 1, 2, 3 or 4 expected."); } void immu_pagesize () { if (is_power2(tempL)) config.immu.pagesize = tempL; else ERROR("value of power of two expected."); } void dmmu_pagesize () { if (is_power2(tempL)) config.dmmu.pagesize = tempL; else ERROR("value of power of two expected."); } void immu_entrysize () { if (is_power2(tempL)) config.immu.entrysize = tempL; else ERROR("value of power of two expected."); } void dmmu_entrysize () { if (is_power2(tempL)) config.dmmu.entrysize = tempL; else ERROR("value of power of two expected."); } void immu_ustates () { if (tempL >= 2 && tempL <= 4) config.immu.ustates = tempL; else ERROR("invalid USTATE."); } void dmmu_ustates () { if (tempL >= 2 && tempL <= 4) config.dmmu.ustates = tempL; else ERROR("invalid USTATE."); } void ic_enabled () { config.ic.enabled = tempL; setsprbits (SPR_UPR, SPR_UPR_ICP, tempL & 1); } void ic_nsets () { if (is_power2(tempL) && tempL <= MAX_IC_SETS) config.ic.nsets = tempL; else { char tmp[200]; sprintf (tmp, "value of power of two and lower or equal than %i expected.", MAX_IC_SETS); ERROR(tmp); } } void ic_nways () { if (tempL >= 1 && tempL <= MAX_IC_WAYS) config.ic.nways = tempL; else ERROR("value 1, 2, 3 or 4 expected."); } void ic_blocksize () { if (is_power2(tempL)) config.ic.blocksize = tempL; else ERROR("value of power of two expected."); } void ic_ustates () { if (tempL >= 2 && tempL <= 4) config.ic.ustates = tempL; else ERROR("invalid USTATE."); } void dc_enabled () { config.dc.enabled = tempL; setsprbits (SPR_UPR, SPR_UPR_DCP, tempL & 1); } void dc_nsets () { if (is_power2(tempL) && tempL <= MAX_DC_SETS) config.dc.nsets = tempL; else { char tmp[200]; sprintf (tmp, "value of power of two and lower or equal than %i expected.", MAX_DC_SETS); ERROR(tmp); } } void dc_nways () { if (tempL >= 1 && tempL <= MAX_IC_WAYS) config.dc.nways = tempL; else ERROR("value 1, 2, 3 or 4 expected."); } void dc_blocksize () { if (is_power2(tempL)) config.dc.blocksize = tempL; else ERROR("value of power of two expected."); } void dc_ustates () { if (tempL >= 2 && tempL <= 4) config.dc.ustates = tempL; else ERROR("invalid USTATE."); } void vga_nvgas () { if (tempL >= 0 && tempL < MAX_VGAS) config.nvgas = tempL; else ERROR("invalid number of devices."); } void vga_baseaddr () { if (current_device >= 0 && current_device < config.nvgas) config.vgas[current_device].baseaddr = tempUL; else ERROR("invalid device number."); } void vga_irq () { if (current_device >= 0 && current_device < config.nvgas) config.vgas[current_device].irq = tempL; else ERROR("invalid device number."); } void vga_refresh_rate () { if (current_device >= 0 && current_device < config.nvgas) config.vgas[current_device].refresh_rate = tempUL; else ERROR("invalid device number."); } void vga_filename () { if (current_device >= 0 && current_device < config.nvgas) strcpy (config.vgas[current_device].filename, tempS); else ERROR("invalid device number."); } /* Read environment from a script file. Does not fail - assumes default configuration instead. The syntax of script file is: param = value section x data param = value end Example: section mc memory_table_file = sim.mem enable = 1 POC = 0x47892344 end */ void read_script_file (char *filename) { FILE *f; unsigned long memory_needed = 0; char *home = getenv("HOME"); char ctmp[STR_SIZE]; int local = 1; section = 0; sprintf(ctmp, "%s/.or1k/%s", home, filename); if ((f = fopen (filename, "rt")) != NULL || home != NULL && !(local = 0) && (f = fopen (ctmp, "rt")) != NULL) { unsigned long start, length; char type[STR_SIZE]; int nparam; int rd, wd; if (config.sim.verbose && !runtime.sim.output_cfg) printf ("Reading script file from '%s'...\n", local ? filename : ctmp); strcpy (runtime.sim.script_fn, local ? filename : ctmp); while (!feof(f)) { char param[STR_SIZE]; if (fscanf(f, "%s ", ¶m) != 1) break; /* Is this a sections? */ if (strcmp (param, "section") == 0) { int i; section = 0; if (fscanf (f, "%s\n", ¶m) != 1) { fprintf (stderr, "%s: ERROR: Section name required.\n", local ? filename : ctmp); exit (1); } for (i = 1; i < sizeof(sections) / sizeof(struct section); i++) if (strcmp (sections[i].name, param) == 0) { section = i; break; } if (!section) { char tmp[200]; sprintf (tmp, "Unknown section: %s; ignoring.", param); WARNING(tmp); /* just skip section */ while (fscanf (f, "%s\n", ¶m) != 1 && strcmp (param, "end")); } } else if (strcmp (param, "end") == 0) { section = 0; } else if (strncmp (param, "/*", 2) == 0) { char c0 = 0, c1 = 0; while (c0 != '*' || c1 != '/') { c0 = c1; c1 = fgetc(f); if (feof(f)) { fprintf (stderr, "%s: ERROR: Comment reached EOF.\n", local ? filename : ctmp); exit (1); } } } else { int i, found = -1; for (i = 0; i < sizeof(config_params)/sizeof(struct config_params); i++) if (config_params[i].section == section && strcmp (config_params[i].name, param) == 0) { found = i; break; } if (found < 0) { char tmp[200]; sprintf (tmp, "Invalid parameter: %s; ignoring.\n", param); WARNING(tmp); while (fgetc(f) != '\n' || feof(f)); continue; } /* Parse parameter value */ { if (config_params[found].type[0]) if(fscanf_ex (f, config_params[found].type, config_params[found].addr, 0)) exit (1); } if (config_params[found].func) config_params[found].func(); } } fclose (f); runtime.sim.script_file_specified = 1; } else if (config.sim.verbose) fprintf (stderr, "WARNING: Cannot read script file from '%s',\nneither '%s'.\n", filename, ctmp); } /* Utility for execution of set sim command. */ static int set_config (char *s) { char *sec, *item, *params; int noparams = 0, i, noitem = 0; while (*s && isspace (*s)) s++; sec = s; printf ("s:%s\n", s); while (*s && *s != ' ') s++; if (!(*s)) noitem = 1; *s = 0; printf ("sec:%s\n", sec); section = 0; for (i = 1; i < sizeof(sections) / sizeof(struct section); i++) if (strcmp (sections[i].name, sec) == 0) { section = i; break; } if (!section) return 1; if (noitem) return 2; item = ++s; while (*s && *s != ' ') s++; if (!(*s)) { noparams = 1; params = ""; } else params = s + 1; *s = 0; printf ("item:%s\n", item); printf ("params:%s\n", params); { int i, found = -1; for (i = 0; i < sizeof(config_params)/sizeof(struct config_params); i++) if (config_params[i].section == section && strcmp (config_params[i].name, item) == 0) { found = i; break; } if (found < 0) return 2; /* Parse parameter value */ if (config_params[found].type[0]) if(fscanf_ex (0, config_params[found].type, config_params[found].addr, params)) return 3; if (config_params[found].func) config_params[found].func(); } return 0; } /* Executes set sim command, displays error. */ void set_config_command(char *s) { int i; switch (set_config (s)) { case 1: printf ("Invalid or missing section name. One of valid sections must be specified:\n"); for (i = 1; i < sizeof(sections) / sizeof(struct section); i++) printf ("%s ", sections[i].name); printf ("\n"); break; case 2: printf ("Invalid or missing item name. One of valid items must be specified:\n"); for (i = 0; i < sizeof(config_params)/sizeof(struct config_params); i++) if (config_params[i].section == section) printf ("%s ", config_params[i].name); printf ("\n"); break; case 3: printf ("Invalid parameters specified.\n"); break; } } #endif /* !FAST_SIM */ /* Outputs C structure of current config to file */ void output_cfg (FILE *f) { int i, comma; fprintf (f, "/* This file was automatically generated by or1ksim,\n" " using --output-cfg switch (cfg file '%s'). */\n" "const static struct config config = {\n", runtime.sim.script_fn); fprintf (f, " tick:{enabled:%i},\n", config.tick.enabled); fprintf (f, " nuarts:%i, uarts:{", config.nuarts); comma = 0; for (i = 0; i < config.nuarts; i++) { fprintf (f, "%s\n {rxfile:\"%s\", txfile:\"%s\", jitter:%i, baseaddr:0x%08x, irq:%i, vapi_id:0x%08x, uart16550:%i}", comma ? "," :"", config.uarts[i].rxfile, config.uarts[i].txfile, config.uarts[i].jitter, config.uarts[i].baseaddr, config.uarts[i].irq, config.uarts[i].vapi_id, config.uarts[i].uart16550); comma = 1; } fprintf (f, "},\n"); fprintf (f, " ndmas:%i, dmas:{", config.ndmas); comma = 0; for (i = 0; i < config.ndmas; i++) { fprintf (f, "%s\n {baseaddr:0x%08x, irq:%i, vapi_id:0x%08x}", comma ? "," :"", config.dmas[i].baseaddr, config.dmas[i].irq, config.dmas[i].vapi_id); comma = 1; } fprintf (f, "},\n"); fprintf (f, " nethernets:%i, ethernets:{", config.nethernets); comma = 0; for (i = 0; i < config.nethernets; i++) { fprintf (f, "%s\n {baseaddr:0x%08x, dma:%i, tx_channel:0x%08x, rx_channel:0x%08x, rxfile:\"%s\", txfile:\"%s\", vapi_id:0x%08x}", comma ? "," :"", config.ethernets[i].baseaddr, config.ethernets[i].dma, config.ethernets[i].tx_channel, config.ethernets[i].rx_channel, config.ethernets[i].rxfile, config.ethernets[i].txfile, config.ethernets[i].vapi_id); comma = 1; } fprintf (f, "},\n"); fprintf (f, " ngpios:%i, gpios:{", config.ngpios); comma = 0; for (i = 0; i < config.ngpios; i++) { fprintf (f, "%s\n {baseaddr:0x%08x, irq:%i, base_vapi_id:0x%08x}", comma ? "," :"", config.gpios[i].baseaddr, config.gpios[i].irq, config.gpios[i].base_vapi_id); comma = 1; } fprintf (f, "},\n"); fprintf (f, " mc:{enabled:%i, baseaddr:%i, POC:%i},\n", config.mc.enabled, config.mc.baseaddr, config.mc.POC); fprintf (f, " memory:{pattern:%i, random_seed:%i, type:%s, nmemories:%i, table:{", config.memory.pattern, config.memory.random_seed, config.memory.type == MT_UNKNOWN ? "MT_UNKNOWN" : config.memory.type == MT_PATTERN ? "MT_PATTERN" : "MT_RANDOM", config.memory.nmemories); comma = 0; for (i = 0; i < config.memory.nmemories; i++) { fprintf (f, "%s\n {ce:%i, baseaddr:0x%08x, size:0x%08x, name:\"%s\", log:\"%s\", delayr:%i, delayw:%i}", comma ? "," :"", config.memory.table[i].ce, config.memory.table[i].baseaddr, config.memory.table[i].size, config.memory.table[i].name, config.memory.table[i].log, config.memory.table[i].delayr, config.memory.table[i].delayw); comma = 1; } fprintf (f, "}},\n"); fprintf (f, " immu:{enabled:%i, nways:%i, nsets:%i, pagesize:%i, entrysize:%i, ustates:%i, missdelay:%i, hitdelay:%i},\n", config.immu.enabled, config.immu.nways, config.immu.nsets, config.immu.pagesize, config.immu.entrysize, config.immu.ustates, config.immu.missdelay, config.immu.hitdelay); fprintf (f, " dmmu:{enabled:%i, nways:%i, nsets:%i, pagesize:%i, entrysize:%i, ustates:%i, missdelay:%i, hitdelay:%i},\n", config.dmmu.enabled, config.dmmu.nways, config.dmmu.nsets, config.dmmu.pagesize, config.dmmu.entrysize, config.dmmu.ustates, config.dmmu.missdelay, config.dmmu.hitdelay); fprintf (f, " ic:{enabled:%i, nways:%i, nsets:%i, blocksize:%i, ustates:%i, missdelay:%i, hitdelay:%i},\n", config.ic.enabled, config.ic.nways, config.ic.nsets, config.ic.blocksize, config.ic.ustates, config.ic.missdelay, config.ic.hitdelay); fprintf (f, " dc:{enabled:%i, nways:%i, nsets:%i, blocksize:%i, ustates:%i,\n" " load_missdelay:%i, load_hitdelay:%i, store_missdelay:%i, store_hitdelay:%i},\n", config.dc.enabled, config.dc.nways, config.dc.nsets, config.dc.blocksize, config.dc.ustates, config.dc.load_missdelay, config.dc.load_hitdelay, config.dc.store_missdelay, config.dc.store_hitdelay); fprintf (f, " bpb:{enabled:%i, sbp_bnf_fwd:%i, sbp_bf_fwd:%i, btic:%i, missdelay:%i, hitdelay:%i},\n", config.bpb.enabled, config.bpb.sbp_bnf_fwd, config.bpb.sbp_bf_fwd, config.bpb.btic, config.bpb.missdelay, config.bpb.hitdelay); fprintf (f, " cpu:{upr:0x%08x, ver:0x%04x, rev:0x%04x, superscalar:%i, hazards:%i, dependstats:%i,\n" " sr:0x%08x},\n", config.cpu.upr, config.cpu.ver, config.cpu.rev, config.cpu.superscalar, config.cpu.hazards, config.cpu.dependstats, config.cpu.sr); fprintf (f, " sim:{debug:%i, verbose:%i, profile:%i, prof_fn:\"%s\", mprofile:%i, mprof_fn:\"%s\",\n", config.sim.debug, config.sim.verbose, config.sim.profile, config.sim.prof_fn, config.sim.mprofile, config.sim.mprof_fn); fprintf (f, " history:%i, exe_log:%i, exe_log_fn:\"%s\", clkcycle_ps:%i,\n", config.sim.history, config.sim.exe_log, config.sim.exe_log_fn, config.sim.clkcycle_ps); fprintf (f, " spr_log:%i, spr_log_fn:\"%s\"},\n", config.sim.spr_log, config.sim.spr_log_fn); fprintf (f, " debug:{enabled:%i, gdb_enabled:%i, server_port:%i, vapi_id:0x%08x},\n", config.debug.enabled, config.debug.gdb_enabled, config.debug.server_port, config.debug.vapi_id); fprintf (f, " vapi:{enabled:%i, server_port:%i, log_enabled:%i, hide_device_id:%i, vapi_fn:\"%s\"},\n", config.vapi.enabled, config.vapi.server_port, config.vapi.log_enabled, config.vapi.hide_device_id, config.vapi.vapi_fn); fprintf (f, " pm:{enabled:%i}\n", config.pm.enabled); fprintf (f, "};\n"); }
Go to most recent revision | Compare with Previous | Blame | View Log