/* * parse command line arguments */ void parse_arguments(int argc, char *argv[]) { int c, i; char quantum_arg[MAX_ARG_SIZE], prio_arg[MAX_ARG_SIZE], policy_buf[MAX_ARG_SIZE], *endptr; prio_set = quantum_set = 0; opterr = 0; while (1) { int option_index = 0; /* define the allowable options */ static struct option long_options[] = { {"help",no_argument, 0,'h'}, {"dump",no_argument, 0,'d'}, {"ppvals",no_argument, 0,'v'}, {"aggregate", required_argument,0,'a'}, {"scheduler", required_argument,0,'s'}, {"priority", required_argument,0,'p'}, {"quantum", required_argument, 0, 'q'}, {0,0,0,0} }; c = getopt_long(argc, argv, "hds:p:q", long_options,&option_index); if (c == -1) break; switch (c) { case 'h': printf("%s", short_usage); printf("%s", long_usage); exit(0); case 'v': ppvals = 1; break; case 'a': errno = 0; aggregate = strtol(optarg, &endptr, 10); if (errno) { perror("parsing aggregate"); exit(1); } break; case 's': if (strcasecmp(optarg,"normal") == 0) { sched_policy = SCHED_NORMAL; } else if (strcasecmp(optarg,"other_rr") == 0) { sched_policy = SCHED_OTHER_RR; } else { printf("Error: invalid scheduling policy: %s\n", optarg); printf("%s", try_help); exit(1); } get_policy_str(policy_buf, sched_policy); break; case 'p': strcpy(prio_arg, optarg); prio_set = 1; break; case 'q': strcpy(quantum_arg, optarg); quantum_set = 1; break; case '?': /* getopt_long already printed an error message */ break; } } if ( (argc - optind) != 2 ) { printf("%s", short_usage); printf("%s", try_help); exit(1); } num_threads = atoi(argv[optind]); if (MIN_THREADS > num_threads || num_threads > MAX_THREADS) { printf("Error: invalid number of threads: %d\n", num_threads); printf("Number of threads must be between %d and %d\n", MIN_THREADS, MAX_THREADS); exit(1); } buffer_size = parse_buf_size(argv[optind+1]); if (prio_set) { if (sched_policy != SCHED_NORMAL) { printf("Error: thread priorities specified with %s scheduling policy\n" "Thread priorities are only valid with the normal scheduling policy\n", policy_buf); exit(1); } prio_array = parse_prio_array(prio_arg); } else { prio_array = malloc(num_threads * sizeof(int)); if (prio_array == NULL) { printf("Error: out of memory creating prio_array\n"); exit(1); } for (i=0; i<num_threads; i++) { prio_array[i] = 0; } } if (quantum_set) { if (sched_policy != SCHED_OTHER_RR) { printf("Error: quantum specified with %s scheduling policy\n" "A quantum value is only valid with the other_rr scheduling policy\n", policy_buf); exit(1); } quantum = parse_quantum(quantum_arg); } }
/* * User's entry point. */ int sc_main(int argc , char * argv[]) { /* * Initialize simulation */ scx::scx_initialize("Dhrystone"); /* * Components */ amba_pv::amba_pv_memory<64> memory("Memory", 0x34000100); scx_evs_Dhrystone dhrystone("Dhrystone"); /* * Number of instructions to run per quantum */ double quantum = parse_quantum(argc, argv); /* * Simulation configuration */ /* From command-line options */ scx::scx_parse_and_configure(argc, argv, help_quantum); /* Semi-hosting configuration */ bool v; if (scx::scx_get_parameter("Dhrystone.Core.cpu1.semihosting-enable", v)) { /* MP core */ scx::scx_set_parameter("*.Core.cpu1.semihosting-enable", true); scx::scx_set_parameter("*.Core.cpu1.semihosting-ARM_SVC", 0x123456); scx::scx_set_parameter("*.Core.cpu1.semihosting-Thumb_SVC", 0xAB); scx::scx_set_parameter("*.Core.cpu1.semihosting-heap_base", 0x32800000); scx::scx_set_parameter("*.Core.cpu1.semihosting-heap_limit", 0x0800000); scx::scx_set_parameter("*.Core.cpu1.semihosting-stack_base", 0x33800000); scx::scx_set_parameter("*.Core.cpu1.semihosting-stack_limit", 0x0800000); } if (scx::scx_get_parameter("Dhrystone.Core.cpu0.semihosting-enable", v)) { /* MP core */ scx::scx_set_parameter("*.Core.cpu0.semihosting-enable", true); scx::scx_set_parameter("*.Core.cpu0.semihosting-ARM_SVC", 0x123456); scx::scx_set_parameter("*.Core.cpu0.semihosting-Thumb_SVC", 0xAB); scx::scx_set_parameter("*.Core.cpu0.semihosting-heap_base", 0x32000000); scx::scx_set_parameter("*.Core.cpu0.semihosting-heap_limit", 0x0800000); scx::scx_set_parameter("*.Core.cpu0.semihosting-stack_base", 0x33000000); scx::scx_set_parameter("*.Core.cpu0.semihosting-stack_limit", 0x0800000); } else { /* UP core */ scx::scx_set_parameter("*.Core.semihosting-enable", true); scx::scx_set_parameter("*.Core.semihosting-ARM_SVC", 0x123456); scx::scx_set_parameter("*.Core.semihosting-Thumb_SVC", 0xAB); scx::scx_set_parameter("*.Core.semihosting-heap_base", 0x32000000); scx::scx_set_parameter("*.Core.semihosting-heap_limit", 0x0800000); scx::scx_set_parameter("*.Core.semihosting-stack_base", 0x33000000); scx::scx_set_parameter("*.Core.semihosting-stack_limit", 0x0800000); } /* Simulation quantum, i.e. seconds to run per quantum */ tlm::tlm_global_quantum::instance().set(sc_core::sc_time(quantum / 100000000, sc_core::SC_SEC)); /* * Bindings */ dhrystone.amba_pv_m(memory.amba_pv_s); /* * Start of simulation */ sc_core::sc_start(); return EXIT_SUCCESS; }