/* * nios2sim-ng -- Nios II Simulator (Next Generation) * * Copyright (C) 2010 Tobias Klauser * * Based on Nios-sim, which is: * Copyright (C) 2010 chysun2000@gmail.com * * 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include #include #include #include "nios2sim-ng.h" #include "image.h" #include "nios2.h" #include "memory.h" #include "device.h" #include "simulator.h" #define PROGRAM_NAME "nios2sim-ng" #define PROGRAM_VERSION VERSION /* Set in Makefile */ #define DEFAULT_MEM_SIZE (16 * 1024 * 1024) bool verbose = false; static void usage_and_exit(const int ret) { fprintf(stdout, "Usage: %s [OPTION...] IMAGE\n" " -b BASE, --baseaddr=BASE\n" " specify image base address\n" " -c CMDLINE, --cmdline=CMDLINE\n" " specify kernel command line\n" " -m MEMSIZE, --memsize=MEMSIZE\n" " set memory size for simulator (default %zu%s)\n" " -M, --mmu simulate Nios II with MMU\n" " -e, --elf image is in ELF format (default)\n" " -s, --srec image is in SREC format\n" " -d, --debug enable debug mode\n" " -v, --verbose enable verbose outputs\n" " -V, --version print version information and exit\n" " -h, --help print this help and exit\n" "\n" "Example:\n" " %s -s -m 32M -d -c console=ttyJ0 init=/bin/sh\n" "", PROGRAM_NAME, size_scale(DEFAULT_MEM_SIZE), size_postfix(DEFAULT_MEM_SIZE), PROGRAM_NAME); exit(ret); } static const struct option long_opts[] = { { "baseaddr", required_argument, NULL, 'b' }, { "cmdline", required_argument, NULL, 'c' }, { "memsize", required_argument, NULL, 'm' }, { "mmu", no_argument, NULL, 'M' }, { "elf", no_argument, NULL, 'e' }, { "srec", no_argument, NULL, 's' }, { "debug", no_argument, NULL, 'd' }, { "verbose", no_argument, NULL, 'v' }, { "version", no_argument, NULL, 'V' }, { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 } }; static const char *short_opts = "c:m:MesdvVh"; static size_t parse_mem_size(char *opt) { size_t len = strlen(opt); size_t mem_size; size_t mul = 1; switch (opt[len - 1]) { case 'k': case 'K': mul = 1024; opt[len - 1] = '\0'; break; case 'm': case 'M': mul = 1024 * 1024; opt[len - 1] = '\0'; break; } errno = 0; mem_size = strtoul(opt, NULL, 0); if (errno != 0) { err("Invalid memory size: %s\n", opt); exit(EXIT_FAILURE); } mem_size *= mul; return round_up(mem_size, 4); } int main(int argc, char *argv[]) { char *image_path; char *cmdline = ""; int image_format = FORMAT_ELF; struct nios2 cpu; struct memory mem; int c; mem.size = DEFAULT_MEM_SIZE; mem.image_base = IMAGE_BASE_UNINITIALIZED; while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { switch(c) { case 'b': mem.image_base = strtoul(optarg, NULL, 0); break; case 'c': cmdline = optarg; break; case 'm': mem.size = parse_mem_size(optarg); break; case 'M': cpu.has_mmu = true; break; case 'e': image_format = FORMAT_ELF; break; case 's': image_format = FORMAT_SREC; break; case 'd': // set_debug_mode(get_nios_cpu()); break; case 'v': verbose = true; break; case 'V': info("%s %s\n", PROGRAM_NAME, PROGRAM_VERSION); exit(EXIT_SUCCESS); /* never reached */ case 'h': usage_and_exit(EXIT_SUCCESS); /* never reached */ default: usage_and_exit(EXIT_FAILURE); } } if (optind >= argc) { err("No image file specified\n"); exit(EXIT_FAILURE); } image_path = argv[optind]; if (mem.image_base != IMAGE_BASE_UNINITIALIZED && mem.image_base >= mem.size) { err("Image base address points beyond memory\n"); exit(EXIT_FAILURE); } mem.base = zalloc(mem.size); if (unlikely(mem.base == NULL)) { err("Failed to allocate memory\n"); exit(EXIT_FAILURE); } memset(mem.base, 0xfe, mem.size); /* Load the image to memory */ if (image_load(image_path, image_format, &mem)) exit(EXIT_FAILURE); /* Initialize devices */ if (device_init_all() < 0) exit(EXIT_FAILURE); /* XXX: tmp */ mem.image_base = 0x00500000; vinfo(" Image file: %s\n", image_path); vinfo(" Image format: %s\n", image_format_str(image_format)); vinfo(" Memory size: %zu %sbytes\n", size_scale(mem.size), size_postfix(mem.size)); vinfo(" Memory base: %p\n", mem.base); vinfo(" Image base: 0x%08x\n", mem.image_base); vinfo(" Kernel command line: %s\n", cmdline); #if 0 printf("Base address:0x%08X, Entry address:0x%08X\n",image_info.base_addr, image_info.entry_addr); printf("Set command line:%s\n", cmd_line); printf("Initrd: 0x%08x size:0x%08x\n",initrd_start, initrd_size); printf("rootfs: %s \n",fs_image); #endif cpu.mem = &mem; simulator_run(&cpu); exit(EXIT_SUCCESS); }