diff options
-rw-r--r-- | custom_instr.c | 34 | ||||
-rw-r--r-- | io_device.c | 155 | ||||
-rw-r--r-- | io_device.h | 65 | ||||
-rw-r--r-- | load_image.c | 620 | ||||
-rw-r--r-- | niosii.c | 603 | ||||
-rw-r--r-- | niosii.h | 182 | ||||
-rw-r--r-- | public.h | 85 |
7 files changed, 0 insertions, 1744 deletions
diff --git a/custom_instr.c b/custom_instr.c deleted file mode 100644 index c9e5abf..0000000 --- a/custom_instr.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - Nios-sim - one simple NIOSII simulator only for personal interest and fun. - 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 <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "public.h" -#include "niosii.h" -#include "instruction.h" - -uint32_t custom_instr(struct NIOS_CPU * cpu, uint32_t code) -{ - printf("%s\n",__func__); - return PC_INC_NORMAL; -} - -/*----------------------------------------------------------------------------*/ - diff --git a/io_device.c b/io_device.c deleted file mode 100644 index e650608..0000000 --- a/io_device.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - Nios-sim - one simple NIOSII simulator only for personal interest and fun. - 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 <stdio.h> -#include "public.h" -#include "io_device.h" -#include "jtag_uart.h" -#include "timer.h" -#include "uart_core.h" -#include "nor_flash.h" - -static struct io_device * devices[] = { - &jtag_uart_io_device, - &timer_core, - &uart_core, - &nor_flash_core -}; - -#define DEVICES_COUNT (sizeof(devices)/sizeof(devices[0])) - -static struct io_device * last_used_device = NULL; - -struct io_device * get_device(uint32_t address) -{ - struct io_device * ret_val = NULL; - uint32_t i = 0; - - if (last_used_device != NULL){ - if(last_used_device->is_belong(address) == ADDR_IS_DEV){ - return last_used_device; - } - } - - for (i=0;i<DEVICES_COUNT; i++){ - if (devices[i]->is_belong != NULL){ - if (devices[i]->is_belong(address) == ADDR_IS_DEV){ - ret_val = devices[i]; - last_used_device = ret_val; - break; - } - } - } - - return ret_val; -} - -void init_devices(void) -{ - uint32_t i = 0; - - printf("--------------------------------------------------\n"); - printf(" Init H/W Device Module!\n"); - printf("--------------------------------------------------\n"); - for (i=0;i<DEVICES_COUNT; i++){ - if (devices[i]->init != NULL){ - devices[i]->init(devices[i]); - } - } - printf("--------------------------------------------------\n"); -} - -static const uint32_t data_mask[5] = { - [1] = 0xFF, - [2] = 0xFFFF, - [4] = 0xFFFFFFFF, -}; - -uint32_t io_write_data(uint32_t old_data, uint32_t new_data, - uint32_t data_len) -{ - uint32_t mask = data_mask[data_len]; - - old_data = old_data & (~mask); - new_data = new_data & mask; - return (old_data | new_data); -} - -uint32_t io_write_data_mask(uint32_t old_data, uint32_t new_data, - uint32_t data_len, uint32_t valid_mask, - uint32_t only_read_mask) -{ - uint32_t mask = data_mask[data_len]; - - new_data = new_data & mask; /* remove as the access bus width */ - new_data = new_data & valid_mask; /* remove as the valid bits */ - new_data = new_data & (~only_read_mask); /* remove the read-only bits */ - - old_data = old_data &(~mask | only_read_mask); - - return (old_data | new_data); -} - -uint32_t io_read_data(unsigned old_data, uint32_t data_len) -{ - uint32_t mask = data_mask[data_len]; - return (old_data & mask); -} - -void hw_simulating(void) -{ - int i = 0; - struct io_device * device = NULL; - - for (i=0;i<DEVICES_COUNT; i++){ - device = devices[i]; - if(device->simulate != NULL){ - device->simulate(device); - } - } -} - -uint32_t get_io_irq_status(void) -{ - int i = 0; - uint32_t irq_mask = 0; - struct io_device * device = NULL; - - for (i=0;i<DEVICES_COUNT; i++){ - device = devices[i]; - if(device->has_irq != NULL){ - if (device->has_irq(device) == DEV_HAS_IRQ){ - irq_mask |= device->irq_enable_mask; - } - } - } - - return irq_mask; -} - -uint32_t check_reg_bit(uint32_t value, uint32_t mask) -{ - if ((value & mask) == mask){ - return SIM_TRUE; - } - else { - return SIM_FALSE; - } -} -/*--------------------------------------------------------------------------*/ diff --git a/io_device.h b/io_device.h deleted file mode 100644 index e520ff0..0000000 --- a/io_device.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - Nios-sim - one simple NIOSII simulator only for personal interest and fun. - 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. -*/ - - -#ifndef __IO_DEVICE_H__ -#define __IO_DEVICE_H__ -#include <stdio.h> - -#define ADDR_IS_NOT_DEV (0) -#define ADDR_IS_DEV (1) - -#define DEV_HAS_IRQ (1) -#define DEV_NO_IRQ (0) - -struct io_device; -struct io_device { - void * priv_data; - char * name; - uint32_t irq_enable_mask; - void (*init)(struct io_device * self); - int32_t (*is_belong)(uint32_t address); - uint32_t (*read_data)(struct io_device * self, uint32_t addr, uint32_t data_len); - void (*write_data)(struct io_device * self, uint32_t addr, uint32_t data, uint32_t data_len); - int32_t (*has_irq)(struct io_device * self); - void (*simulate)(struct io_device * self); - -}; - -struct io_reg { - uint32_t addr; - uint32_t value; - uint32_t valid_mask; - uint32_t only_read_mask; -}; - -extern void init_devices(void); -extern struct io_device * get_device(uint32_t address); - -extern uint32_t io_write_data(uint32_t old_data, uint32_t new_data, uint32_t data_len); -extern uint32_t io_read_data(uint32_t old_data, uint32_t data_len); -extern uint32_t io_write_data_mask(uint32_t old_data, uint32_t new_data, uint32_t data_len, - uint32_t valid_mask, uint32_t only_read_mask); -extern void hw_simulating(void); -extern uint32_t get_io_irq_status(void); - -extern uint32_t check_reg_bit(uint32_t value, uint32_t mask); -#endif - - diff --git a/load_image.c b/load_image.c deleted file mode 100644 index 6a10e47..0000000 --- a/load_image.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - Nios-sim - one simple NIOSII simulator only for personal interest and fun. - 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 <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "public.h" -#include "nor_flash.h" - -typedef enum { - S_INVALID = 0x00, - S0 = 0x01, - S1 = 0x02, - S2 = 0x03, - S3 = 0x04, - S4 = 0x05, - S5 = 0x06, - S6 = 0x07, - S7 = 0x08, - S8 = 0x09, - S9 = 0x0A -} SREC_TYPE; - -static struct image_info image_info; - -static int32_t is_line_end(char data) -{ - if (data == '\n'){ - return 0; - } - else{ - return -1; - } -} - -static void get_line(FILE * fp, char * buf, int32_t buf_len, int32_t * line_len) -{ - char data = '\0'; - int32_t index = 0; - - memset(buf, 0x00, buf_len); - while(1){ - if(feof(fp) != 0 || ferror(fp) != 0){ - return ; - } - - data = '\0'; - if (fread(&data, 1, 1, fp) == 1){ - if (is_line_end(data) != 0){ - buf[index++] = data; - *line_len = index; - } - else { - return ; - } - } - else { - return ; - } - } -} - -static SREC_TYPE get_srec_type(char * buf) -{ - if (buf[1] >= 0x30 && buf[1] <= 0x39){ - return S0 + buf[1] - 0x30; - } - else{ - return S_INVALID; - } -} - -static uint32_t __factors [] = { - 1, - 16, - 256, - 16 * 16 * 16, - 16 * 16 * 16 * 16, - 16 * 16 * 16 * 16 * 16, - 16 * 16 * 16 * 16 * 16 * 16, - 16 * 16 * 16 * 16 * 16 * 16 * 16 -}; - -static uint32_t single_ascii_to_hex(char data) -{ - if (data >= 0x30 && data <= 0x39) - return data - 0x30; - if (data >= 0x41 && data <= 0x46) - return data - 0x41 + 10; - if (data >= 0x61 && data <= 0x66) - return data - 0x61 + 10; - return 0; -} - -uint32_t ascii_to_hex(char * buf, uint32_t buf_len) -{ - uint32_t ret = 0x0000; - int32_t i = 0; - for (i=0;i<buf_len;i++){ - ret = ret + (single_ascii_to_hex(buf[i]) * __factors[buf_len - i - 1]); - } - return ret; -} - -static uint32_t get_srec_data_count(char * buf) -{ - uint32_t count = 0; - count = ascii_to_hex(buf + 2, 2); - return count; -} - -static uint32_t to_le(uint32_t data) -{ - uint32_t ret = 0; - ret = ret | ((data & 0xFF000000) >> 24); - ret = ret | ((data & 0x00FF0000) >> 8); - ret = ret | ((data & 0x0000FF00) << 8); - ret = ret | ((data & 0x000000FF) << 24); - return ret; -} - -#define S0_DATA_OFFSET (8) -#define S0_ADDR_CRC_CNT (3) -static uint32_t handle_S0(char * buf, uint32_t data_count, uint32_t * mem_base) -{ - int32_t i = 0; - char * data_buf = buf; - - data_buf = data_buf + S0_DATA_OFFSET; - for (i=0;i<data_count - S0_ADDR_CRC_CNT; i++){ - data_buf += 2; - } - return 0; -} - -#define S3_ADDR_OFFSET (4) -#define S3_DATA_OFFSET (S3_ADDR_OFFSET + 8) -#define S3_ADDR_CRC_CNT (5) - -static uint32_t get_S3_address(char * buf) -{ - uint32_t ret = 0; - buf = buf + S3_ADDR_OFFSET; - ret = ascii_to_hex(buf, 8); - return ret; -} - -static uint32_t handle_S3(char * buf, uint32_t data_count, uint32_t * mem_base, - uint32_t base_addr) -{ - uint32_t start_addr = 0; - uint32_t offset = 0; - uint32_t data = 0; - char * data_buf = buf; - int32_t i; - - start_addr = get_S3_address(buf); - - if (base_addr == 0){ - offset = 0; - } - else{ - offset = (start_addr - base_addr)/4; - } - data_buf = data_buf + S3_DATA_OFFSET; - for (i=0;i<(data_count-S3_ADDR_CRC_CNT)/4;i++){ - data = to_le(ascii_to_hex(data_buf, 8)); - data_buf += 8; - mem_base[offset + i] = data; - } - - return start_addr; -} - -#define S2_ADDR_OFFSET (4) -#define S2_DATA_OFFSET (S2_ADDR_OFFSET + 6) -#define S2_ADDR_CRC_CNT (4) - -static uint32_t get_S2_address(char * buf) -{ - uint32_t ret = 0; - buf = buf + S2_ADDR_OFFSET; - ret = ascii_to_hex(buf, 6); - return ret; -} - -static uint32_t handle_S2(char * buf, uint32_t data_count, uint32_t * mem_base, - uint32_t base_addr) -{ - uint32_t start_addr = 0; - uint32_t offset = 0; - uint32_t data = 0; - char * data_buf = buf; - int32_t i; - - start_addr = get_S2_address(buf); - - if (base_addr == 0){ - offset = 0; - } - else{ - offset = (start_addr - base_addr)/4; - } - - data_buf = data_buf + S2_DATA_OFFSET; - for (i=0;i<(data_count-S2_ADDR_CRC_CNT)/4;i++){ - data = to_le(ascii_to_hex(data_buf, 8)); - data_buf += 8; - mem_base[offset + i] = data; - } - - return start_addr; -} - - -#define S7_DATA_OFFSET (4) -#define S7_CRC_CNT (2) -static uint32_t handle_S7(char * buf, uint32_t data_count, uint32_t * mem_base) -{ - char * data_buf = buf; - - data_buf = data_buf + S7_DATA_OFFSET; - return ascii_to_hex(data_buf, 8); -} - -#define S8_DATA_OFFSET (4) -#define S8_CRC_CNT (2) -static uint32_t handle_S8(char * buf, uint32_t data_count, uint32_t * mem_base) -{ - char * data_buf = buf; - - data_buf = data_buf + S8_DATA_OFFSET; - return ascii_to_hex(data_buf, 6); -} - -static void dummy_srec_handler(char * name) -{ - printf("%s: for %s\n",__func__, name); -} - -static void handle_srec_line(char * buf, int line_len, uint32_t * mem_base) -{ - SREC_TYPE srec_type = S_INVALID; - uint32_t data_count = 0; - uint32_t start_addr = 0; - - srec_type = get_srec_type(buf); - data_count = get_srec_data_count(buf); - - switch(srec_type){ - case S0: - handle_S0(buf, data_count, mem_base); - break; - case S1: - dummy_srec_handler("S1"); - break; - case S2: - if (image_info.base_addr == 0){ - image_info.base_addr = handle_S2(buf, data_count, mem_base, image_info.base_addr); - } - else { - handle_S2(buf, data_count, mem_base, image_info.base_addr); - } - break; - case S3: - if (image_info.base_addr == 0){ - image_info.base_addr = handle_S3(buf, data_count, mem_base, image_info.base_addr); - } - else { - handle_S3(buf, data_count, mem_base, image_info.base_addr); - } - break; - case S4: - dummy_srec_handler("S4"); - break; - case S5: - dummy_srec_handler("S5"); - break; - case S6: - dummy_srec_handler("S6"); - break; - case S7: - start_addr = handle_S7(buf, data_count, mem_base); - set_image_entry_addr(start_addr); - break; - case S8: - start_addr = handle_S8(buf, data_count, mem_base); - set_image_entry_addr(start_addr); - break; - case S9: - dummy_srec_handler("S9"); - break; - default: - return; - } - return; -} - -#define SREC_LINE_LENGTH (515) -static char data_buf[SREC_LINE_LENGTH] = {0}; - -static void load_srec(const char * image_path_name, uint32_t * image_addr) -{ - FILE * fp = NULL; - int32_t line_len = 0; - - fp = fopen(image_path_name, "r"); - if (fp != NULL){ - while(1){ - memset(data_buf, 0x00, SREC_LINE_LENGTH); - line_len = 0; - get_line(fp, data_buf, SREC_LINE_LENGTH, &line_len); - if (line_len == 0){ - break; - } - else - { - handle_srec_line(data_buf, line_len, image_addr); - } - } - fclose(fp); - } - else{ - printf("ERROR--> can not open image at %s\n", image_path_name); - } -} - -void load_image(void) -{ - switch(image_info.image_format){ - case SREC_FMT: - load_srec(image_info.path_name, image_info.mem_base); - break; - default: - break; - } -} - -void alloc_image_mem(void) -{ - char * address = NULL; - struct image_info * info = &image_info; - uint32_t temp = 0; - - address = (char *)malloc(info->mem_size); - temp = info->mem_size % 4; - if (temp != 0){ - address = address + temp; - } - info->mem_base = (uint32_t *)address; -} - -void set_image_pathname(char * pathname) -{ - image_info.path_name = pathname; -} - -void set_image_format(IMG_FORMAT format) -{ - image_info.image_format = format; -} - -void set_image_memsize(char * size) -{ - int32_t str_len = strlen(size); - char * temp = NULL; - - if (size[str_len - 1] == 'M' || size[str_len - 1] == 'm'){ - temp = malloc(str_len); - memset(temp, 0x00, str_len); - memcpy(temp, size, str_len); - temp[str_len - 1] = '\0'; - image_info.mem_size = atoi(temp) * 1024 * 1024; - free(temp); - } -} - -void set_image_entry_addr(uint32_t addr) -{ - image_info.entry_addr = addr; -} - -void set_image_base_addr(char * addr) -{ - sscanf(addr, "0x%X\n", &image_info.base_addr); -} -static char cmd_line[256] = {0}; -static uint32_t initrd_start = 0; -static uint32_t initrd_size = 0; -static char fs_image[256] = {0}; - -void print_image_info(void) -{ - printf("--------------------------------------------------\n"); - printf(" NIOS Simulator (Built at %s-%s)\n",__DATE__,__TIME__); - printf("--------------------------------------------------\n"); - printf("Image File:%s\n",image_info.path_name); - - if (image_info.image_format == SREC_FMT){ - printf("Format:SREC\n"); - } - - printf("Mem size:0x%08X, loading at %p\n", image_info.mem_size, - image_info.mem_base); - 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); - printf("--------------------------------------------------\n"); -} - -struct image_info * get_image_info(void) -{ - return &image_info; -} - -static struct symbol_obj * sym_hash[256] = {NULL}; - -static struct symbol_obj * get_head_list(uint32_t addr) -{ - return sym_hash[addr % 256]; -} - -static void insert_symbol_obj(struct symbol_obj * list, struct symbol_obj * obj) -{ - if (list == NULL){ - sym_hash[obj->addr % 256] = obj; - } - else{ - while(list != NULL){ - if (list->next != NULL){ - list = list->next; - } - else{ - break; - } - - } - list->next = obj; - } -} - -static struct symbol_obj * alloc_symbol_obj(char * addr, char * name) -{ - struct symbol_obj * obj = NULL; - uint32_t size = 0; - - obj = (struct symbol_obj *)malloc(sizeof(struct symbol_obj)); - memset(obj, 0x00, sizeof(struct symbol_obj)); - - if (obj != NULL){ - obj->addr = ascii_to_hex(addr, 8); - obj->next = NULL; - size = strlen(name) + 1; - obj->sym_name = (char *)malloc(size); - if (obj->sym_name != NULL){ - memset(obj->sym_name, 0x00, size); - strncpy(obj->sym_name, name, size - 1); - } - else{ - printf("[ERROR] %s --> can not allocate symname %s \n",__func__, name); - } - } - - return obj; -} - -static void handle_symbol_line(char * line) -{ - char addr[10] = {0}; - char sym_name[64] = {0}; - char type[2] = {0}; - struct symbol_obj * obj = NULL; - struct symbol_obj * list = NULL; - - memset(sym_name, 0x00, 64); - sscanf(line, "%s %s %s\n", addr, type, sym_name); - obj = alloc_symbol_obj(addr, sym_name); - - if (obj != NULL){ - list = get_head_list(obj->addr); - insert_symbol_obj(list, obj); - } -} - -void load_symbol_file(char * symbol_file) -{ - char line[256] = {0}; - int32_t line_len = 0; - FILE * fp = NULL; - - memset(sym_hash, 0x00, sizeof(sym_hash)); - fp = fopen(symbol_file, "r"); - if (fp != NULL){ - while(1){ - memset(line, 0x00, 256); - line_len = 0; - get_line(fp, line, 256, &line_len); - if (line_len == 0){ - break; - } - else{ - line[line_len] = '\0'; - handle_symbol_line(line); - } - } - fclose(fp); - } -} - -static struct symbol_obj * find_symbol_obj(struct symbol_obj * list, uint32_t addr) -{ - struct symbol_obj * ret = NULL; - - ret = list; - while(ret != NULL){ - if (ret->addr == addr){ - break; - } - else{ - ret = ret->next; - } - } - return ret; -} - -struct symbol_obj * get_symbol(uint32_t addr) -{ - struct symbol_obj * ret = NULL; - struct symbol_obj * lst = NULL; - - lst = get_head_list(addr); - if (lst != NULL){ - ret = find_symbol_obj(lst, addr); - } - - return ret; -} - -void set_cmdline(char * optarg) -{ - strcpy(cmd_line,optarg); -} - -void init_cmdline(struct NIOS_CPU * cpu) -{ - - char * addr = (char *)image_info.mem_base; - - /* R7 is stored the start address of command line */ - memcpy((char *)(addr + 0x700000), cmd_line, 255); - /* Set magic number. - * this is copied from arch/nios2/kernel/setup.c <setup_arch> - */ - if (cmd_line[0] != '\0'){ - cpu->gp_regs[4] = 0x534f494e; - cpu->gp_regs[7] = 0xF00000; - } - -} - -void set_initrd(char * optarg) -{ - sscanf(optarg,"0x%08x,0x%08x",&initrd_start,&initrd_size); -} - -void init_initrd(struct NIOS_CPU * cpu) -{ - cpu->gp_regs[5] = initrd_start & 0xFFFFFFFC; - cpu->gp_regs[6] = (initrd_start + initrd_size) & 0xFFFFFFFC; -} - -void set_fs_image(char * optarg) -{ - sscanf(optarg,"%s",fs_image); -} - -void init_fs_image(struct NIOS_CPU * cpu) -{ - int32_t fd = open(fs_image,O_RDWR); - int32_t size = 0; - uint8_t buf [256] = {0}; - uint8_t * mem_load_addr = NULL; - - /* set the load memory address */ - mem_load_addr = nor_flash_mem_addr(); - - if (fd){ - printf("loading rootfs at %p\n", mem_load_addr); - while((size = read(fd,buf, 256)) > 0){ - memcpy(mem_load_addr, buf, size); - mem_load_addr += size; - } - - close(fd); - } - else { - printf("Can not load rootfs image at %s\n",fs_image); - } -} - -/*----------------------------------------------------------------------------*/ - diff --git a/niosii.c b/niosii.c deleted file mode 100644 index 4db4ce2..0000000 --- a/niosii.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - Nios-sim - one simple NIOSII simulator only for personal interest and fun. - 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 <stdio.h> -#include <string.h> -#include <ctype.h> - -#include "public.h" -#include "niosii.h" -#include "io_device.h" -#include "instruction.h" - -static struct NIOS_CPU cpu; -static struct image_info * img_info = NULL; - -void reset_cpu(void) -{ - img_info = get_image_info(); - memset(&cpu, 0x00, sizeof(struct NIOS_CPU)); - /* set the default to control register */ - cpu.ctrl_regs[status] = 0x00800000; - cpu.gp_regs[4] = 0x00; - cpu.gp_regs[7] = 0x00; - cpu.trace_index = 0; -} - -static uint32_t get_opcode(uint32_t intr) -{ - struct i_type_code * code = (struct i_type_code*)&intr; - return code->op; -} - -static uint32_t get_opxcode(uint32_t intr) -{ - struct r_type_code * code = (struct r_type_code *)&intr; - return code->opx; -} - -struct NIOS_CPU * get_nios_cpu(void) -{ - return &cpu; -} - -static uint32_t handle_r_type_code(uint32_t opxcode, uint32_t code) -{ - return (r_type_handlers[opxcode]).handler(&cpu, code); -} - -static uint32_t handle_i_type_code(uint32_t opcode, uint32_t code) -{ - return i_type_handlers[opcode].handler(&cpu, code); -} - -static uint32_t handle_j_type_code(uint32_t opcode, uint32_t code) -{ - return j_type_handlers[opcode].handler(&cpu, code); -} - -uint32_t get_offset_pc(uint32_t pc, uint32_t base_addr) -{ - return (pc - base_addr) / 4; -} - -uint32_t get_instruct(struct NIOS_CPU * cpu, uint32_t * mem_base, - uint32_t base_addr) -{ - uint32_t code = 0; - uint32_t offset = get_offset_pc(cpu->pc, base_addr); - - code = mem_base[offset]; - return code; -} - -static int is_j_type(uint32_t opcode) -{ - if (opcode == CALL || opcode == JMPI){ - return SIM_TRUE; - } - else { - return SIM_FALSE; - } -} - -uint32_t execute(uint32_t code) -{ - uint32_t opcode = 0; - uint32_t opxcode = 0; - uint32_t pc_mod_type = 0; - - opcode = get_opcode(code); - - if (is_j_type(opcode) == SIM_TRUE){ - pc_mod_type = handle_j_type_code(opcode, code); - } - else if (opcode != OP_R_TYPE){ - pc_mod_type = handle_i_type_code(opcode, code); - } - else{ - opxcode = get_opxcode(code); - pc_mod_type = handle_r_type_code(opxcode, code); - } - return pc_mod_type; -} - -int32_t get_addr_type(uint32_t addr) -{ - if ((addr >= img_info->base_addr) - && ((addr - img_info->base_addr) <= img_info->mem_size)){ - return MEM_ADDR; - } - else{ - return IO_ADDR; - } -} - -uint8_t get_byte(uint32_t addr) -{ - if (get_addr_type(addr) == MEM_ADDR){ - uint8_t * buf = (uint8_t *)img_info->mem_base; - return buf[addr - img_info->base_addr]; - } - else{ - struct io_device * dev = get_device(addr); - if (dev != NULL){ - return dev->read_data(dev, addr, 1); - } - else { - printf("%s->error at %x\n",__func__,addr); - return 0; - } - } -} - -void store_byte(uint32_t addr, unsigned char data) -{ - if(get_addr_type(addr) == MEM_ADDR){ - uint8_t * buf = (uint8_t *)img_info->mem_base; - buf[addr - img_info->base_addr] = data; - } - else { - struct io_device * dev = get_device(addr); - if (dev != NULL){ - dev->write_data(dev, addr, data, 1); - } - else { - printf("%s->unhandled data:%x at %x\n",__func__,data,addr); - } - } -} - -uint16_t get_half_word(uint32_t addr) -{ - if (get_addr_type(addr) == MEM_ADDR){ - uint16_t * buf = (uint16_t *)img_info->mem_base; - return buf[(addr - img_info->base_addr)/2]; - } - else { - struct io_device * dev = get_device(addr); - if (dev != NULL){ - return dev->read_data(dev, addr, 2); - } - else { - printf("%s->error at %x\n",__func__,addr); - return 0; - } - } -} - -void store_half_word(uint32_t addr, unsigned short data) -{ - if (get_addr_type(addr) == MEM_ADDR){ - uint16_t * buf = (uint16_t *)img_info->mem_base; - buf[(addr - img_info->base_addr) / 2] = data; - } - else { - struct io_device * dev = get_device(addr); - if (dev != NULL){ - dev->write_data(dev, addr, data, 2); - } - else { - printf("%s->unhandled data:%x at %x\n",__func__,data,addr); - } - } -} - -uint32_t get_word(uint32_t addr) -{ - if (get_addr_type(addr) == MEM_ADDR){ - uint32_t * buf = (uint32_t * )img_info->mem_base; - return buf[(addr - img_info->base_addr) / 4]; - } - else { - struct io_device * dev = get_device(addr); - if (dev != NULL){ - return dev->read_data(dev, addr, 4); - } - else { - printf("%s->error at %x\n",__func__,addr); - return 0; - } - } -} - -void store_word(uint32_t addr, uint32_t data) -{ - if (get_addr_type(addr) == MEM_ADDR){ - uint32_t * buf = (uint32_t *)img_info->mem_base; - buf[(addr - img_info->base_addr) / 4] = data; - } - else { - struct io_device * dev = get_device(addr); - if (dev != NULL){ - dev->write_data(dev, addr, data, 4); - } - else { - printf("%s->unhandled data:%x at %x\n",__func__,data,addr); - } - } -} - -static uint32_t has_irq(struct NIOS_CPU * cpu) -{ - uint32_t ret_val = CPU_HAS_NO_EVENT; - uint32_t irq_mask = 0; - uint32_t temp = 0; - - /* 1. judge the device has irq */ - irq_mask = get_io_irq_status(); - - if (irq_mask != 0){ - if ((cpu->ctrl_regs[status] & REG_STATUS_PIE) == REG_STATUS_PIE){ - temp = cpu->ctrl_regs[ienable] & irq_mask; -#if 1 - if (temp != 0 && (temp != cpu->ctrl_regs[ipending])){ -#else - if (temp != 0){ -#endif - /* 2. modify the control register */ - cpu->ctrl_regs[ipending] |= temp; - ret_val = CPU_HAS_IRQ; - } - } - } - - return ret_val; -} - -static uint32_t has_exception(struct NIOS_CPU * cpu) -{ - uint32_t ret_val = CPU_HAS_NO_EVENT; - - return ret_val; -} - -static uint32_t get_cpu_status(struct NIOS_CPU * cpu) -{ - uint32_t ret_val = CPU_HAS_NO_EVENT; - ret_val |= has_irq(cpu); - ret_val |= has_exception(cpu); - - return ret_val; -} - -static void handle_irq(struct NIOS_CPU * cpu) -{ - uint32_t reg_status_val = 0; - uint32_t temp_pc = 0; - /* according to the kind of interrupt or exception, - * set PC to the address of IRQ or exception vector. - */ - temp_pc = cpu->pc; - cpu->pc = EXCEPTION_HANDLER_ADDR; - reg_status_val = cpu->ctrl_regs[status]; - cpu->ctrl_regs[status] &= 0xFFFFFFFE; /* clear PIE */ - if((reg_status_val & REG_STATUS_EH) == 0){ - cpu->ctrl_regs[estatus] = reg_status_val; - cpu->gp_regs[ea] = temp_pc + 4; - } -} - -static void handle_exception(struct NIOS_CPU * cpu) -{ - -} - -void handle_irq_exception(struct NIOS_CPU * cpu) -{ - uint32_t cpu_status = CPU_HAS_NO_EVENT; - - cpu_status = get_cpu_status(cpu); - if(cpu_status & CPU_HAS_IRQ){ - handle_irq(cpu); - } - else if (cpu_status & CPU_HAS_EXCEPTION){ - handle_exception(cpu); - } -} - -static void dump_j_code(uint32_t code) -{ - def_j_type_code; - - printf("TYPE: J Code [%08X]\n", code); - printf("OP: 0x%02X\n",instr->op); - printf("IMM26: 0x%X\n",instr->imm26); -} - -static void dump_r_code(uint32_t code) -{ - def_r_type_code; - - printf("TYPE: R Code [%08X]\n", code); - printf("OP: 0x%02X\n", instr->op); - printf("A=0x%X B=0x%X C=0x%X OPX=0x%X N=0x%X\n", - instr->a, instr->b, instr->c, instr->opx, instr->n); -} - -static void dump_i_code(uint32_t code) -{ - def_i_type_code; - - printf("TYPE: I Code [%08X]\n", code); - printf("OP: 0x%02X\n", instr->op); - printf("A=0x%X B=0x%X IMM16=0x%04X\n", instr->a, instr->b, instr->imm16); -} - -static void dump_code(uint32_t code) -{ - uint32_t code_type = get_opcode(code); - printf("\n"); - printf("--------------Code Dump--------------\n"); - switch(code_type){ - case OP_J_TYPE: - dump_j_code(code); - break; - case OP_R_TYPE: - dump_r_code(code); - break; - default: - dump_i_code(code); - break; - } - printf("-------------------------------------\n"); -} - -void dump_curr_code(uint32_t code) -{ - dump_code(code); -} - -void dump_next_code(struct NIOS_CPU * cpu) -{ - uint32_t code = get_instruct(cpu,img_info->mem_base, img_info->base_addr); - dump_code(code); -} - -void dump_pc(struct NIOS_CPU * cpu) -{ - int32_t i = 0; - printf("============================================================\n"); - printf("ERROR PC=%08X\n",cpu->pc); - printf("PC Trace Index :%d\n", cpu->trace_index); - printf("============================================================\n"); - for (i=0;i<PC_TRACE_CNT;i++){ - if (i == (cpu->trace_index - 1)){ - printf("(%08X) ",cpu->pc_trace[i]); - } - else { - printf("%08X ",cpu->pc_trace[i]); - } - if (((i+1)% 8) == 0){ - printf("\n"); - } - } - printf("\n============================================================\n"); -} - -static const char * g_regs_name[] = { - " ZERO", - " AT", - "REG02", - "REG03", - "REG04", - "REG05", - "REG06", - "REG07", - "REG08", - "REG09", - "REG10", - "REG11", - "REG12", - "REG13", - "REG14", - "REG15", - "REG16", - "REG17", - "REG18", - "REG19", - "REG20", - "REG21", - "REG22", - "REG23", - " ET", - " BT", - " GP", - " SP", - " FP", - " EA", - " BA", - " RA" -}; - -static const char * c_regs_name[] = { - "SSTAT", - "ESTAT", - "BSTAT", - "IENAB", - "IPEND", - "CPUID", - "RESER", - "EXCEP", - "PTEAD", - "TLBAD", - "TLBMI", - "RESER", - "BADAD", - "CONFI", - "MPUBA", - "MPUAD" -}; - -void dump_register(struct NIOS_CPU * cpu) -{ - int32_t i = 0; - - printf("\n"); - printf("============================================================\n"); - printf("[Genernal Register]\n"); - printf("============================================================\n"); - for (i=0;i<NIOS_REG_CNT;i++){ - printf("%s=%08X ",g_regs_name[i],cpu->gp_regs[i]); - if (((i+1) % 4) == 0) - printf("\n"); - } - printf("============================================================\n"); - printf("[Control Register]\n"); - printf("============================================================\n"); - for (i=0;i<16;i++){ - printf("%s=%08X ",c_regs_name[i],cpu->ctrl_regs[i]); - if (((i+1) % 4) == 0) - printf("\n"); - } - printf("============================================================\n"); -} - -/** - * Parse the options of break command - */ -#define SPACE_CHAR (' ') -#define BREAK_CMD_LEN (16) -extern char break_func_name[256]; -static uint32_t get_break_pc(char * input) -{ - uint32_t ret_pc = 0x0; - uint32_t input_len = 0; - - input_len = strlen(input); - /* - * TODO: the judgement of option's format is not full implemented. - */ - if (input_len == BREAK_CMD_LEN){ - sscanf(input, "break 0x%08x\n", &ret_pc); - } - - if (strstr(input, "func") != NULL){ - memset(break_func_name, 0x00, 256); - sscanf(input, "break func=%s", break_func_name); - return 0xFFFFFFFF; - } - return ret_pc; -} - -void set_break(struct NIOS_CPU * cpu, char * input) -{ - uint32_t break_pc = 0x0; - - break_pc = get_break_pc(input); - if (break_pc != 0x0){ - if (break_pc == 0xFFFFFFFF){ - cpu->mode = BREAK_MODE; - } - else { - cpu->mode = BREAK_MODE; - cpu->break_pc = break_pc; - } - } - else{ - printf("Error Address\n"); - cpu->mode = SINGLE_STEP; - } -} - -static void output_char(char c) -{ - if (c == '\r' || c == '\n'){ - printf("."); - } - else { - printf("%c",c); - } -} -static void output_ascii(uint32_t * buf) -{ - uint32_t val = 0; - char temp = 0; - uint32_t i = 0; - - printf("\t"); - for (i = 0; i < 4; i++){ - val = buf[i]; - temp = val & 0xFF; - output_char(temp); - temp = (val >> 8) & 0xFF; - output_char(temp); - temp = (val >> 16) & 0xFF; - output_char(temp); - temp = (val >> 24) & 0xFF; - output_char(temp); - } -} -/* - * dump the content of memory - */ -void dump_mem(struct NIOS_CPU * cpu, char * input) -{ - uint32_t addr, size; - struct image_info * info = get_image_info(); - int32_t i = 0; - uint32_t * buf = NULL; - uint32_t temp_buf[4] = {0}; - uint32_t index = 0; - sscanf(input, "dump 0x%X %d", &addr, &size); - - addr = addr & (~0x3); - size = size / 4 * 4; - if (addr >= info->base_addr && size < info->mem_size){ - buf = info->mem_base + (addr - info->base_addr) / 4 ; - printf("================================================\n"); - printf("[Memory Dump start:0x%08X size:%d]\n", addr, size); - printf("================================================\n"); - for (i=0;i<size/4;i++){ - temp_buf[index] = buf[i]; - index = index + 1; - if (i % 4 == 0){ - printf("[%08X]",addr + i * 4); - } - printf("%08X ", (uint32_t)buf[i]); - - if (((i+1) % 4) == 0){ - output_ascii(temp_buf); - index = 0; - printf("\n"); - } - else if (i == (size/4 - 1)){ - printf("\n"); - } - } - printf("================================================\n"); - } -} - -void clean_ipending(uint32_t mask) -{ - cpu.ctrl_regs[ipending] &= (~mask); -} - -/* Record the pc trace. It is used when segment fault happening. */ -void trace_pc(struct NIOS_CPU * cpu) -{ - cpu->pc_trace[cpu->trace_index] = cpu->pc; - cpu->trace_index ++; - if (cpu->trace_index >= PC_TRACE_CNT){ - cpu->trace_index = 0; - } -} -/*----------------------------------------------------------------------------*/ - diff --git a/niosii.h b/niosii.h deleted file mode 100644 index 9cbef49..0000000 --- a/niosii.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - Nios-sim - one simple NIOSII simulator only for personal interest and fun. - 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. -*/ - -#ifndef __NIOS_II_H__ -#define __NIOS_II_H__ - -#include <stdio.h> -#include "public.h" - -#define NIOS_REG_CNT (32) -#define D_CACHE_SIZE (16 * 1024) -#define I_CACHE_SIZE (16 * 1024) -#define PC_TRACE_CNT (128) - -enum { - NORMAL_MODE = 0x00, - SINGLE_STEP = 0x01, - BREAK_MODE = 0x02, -}; - -struct NIOS_CPU { - uint32_t gp_regs[NIOS_REG_CNT]; /* default value is 0 */ - uint32_t ctrl_regs[NIOS_REG_CNT]; /* is defined in Processor Reference Handbook */ - uint32_t pc; - uint32_t break_pc; - uint32_t mode; - uint32_t pc_trace[PC_TRACE_CNT]; - uint32_t trace_index; -}; - -#define EXCEPTION_HANDLER_ADDR (0x00800020) /* exc_hook, exception handler address */ -#define BREAK_HANDLER_ADDRESS (0x00000000) /* break handler address */ - -#define OP_R_TYPE 0x3A -#define OP_J_TYPE 0x00 - -struct i_type_handler { - uint32_t (*handler)(struct NIOS_CPU * cpu, uint32_t code); -}; - -struct r_type_handler{ - uint32_t (*handler)(struct NIOS_CPU * cpu, uint32_t code); -}; - -struct j_type_handler{ - uint32_t (*handler)(struct NIOS_CPU * cpu, uint32_t code); -}; - -struct custom_type_handler{ - uint32_t (*handler)(struct NIOS_CPU * cpu, uint32_t code); -}; - -extern struct i_type_handler i_type_handlers[]; -extern struct r_type_handler r_type_handlers[]; -extern struct j_type_handler j_type_handlers[]; - -struct i_type_code{ - uint32_t op:6; - uint32_t imm16:16; - uint32_t b:5; - uint32_t a:5; -} __attribute__ ((__packed__)); - -struct j_type_code{ - uint32_t op:6; - uint32_t imm26:26; -} __attribute__ ((__packed__)); - -struct r_type_code{ - uint32_t op:6; - uint32_t n:5; - uint32_t opx:6; - uint32_t c:5; - uint32_t b:5; - uint32_t a:5; -} __attribute__ ((__packed__)); - -#define handler_item(func) {.handler = func} - -struct custom_type_code { - uint32_t op:6; - uint32_t n:8; - uint32_t rc:1; - uint32_t rb:1; - uint32_t ra:1; - uint32_t c:5; - uint32_t b:5; - uint32_t a:5; -}; - -enum GP_REG_ALIAS{ - zero = 0, - at = 1, - et = 24, - bt = 25, - gp = 26, - sp = 27, - fp = 28, - ea = 29, - ba = 30, - ra = 31, -}; -enum CTRL_REG_ALIAS{ - status = 0, - estatus, - bstatus, - ienable, - ipending, - cpuid, - exception = 7, - pteaddr, - tlbacc, - tlbmisc, - badaddr = 12, - config, - mpubase, - mpuacc -}; - - - -#define MEM_ADDR (0) -#define IO_ADDR (1) - -#define PC_INC_NORMAL (0) -#define PC_INC_BY_INSTR (1) - -extern uint32_t custom_instr(struct NIOS_CPU * cpu, uint32_t code); -extern void reset_cpu(void); -extern struct NIOS_CPU * get_nios_cpu(void); -extern uint32_t execute(uint32_t code); -extern int32_t get_addr_type(uint32_t addr); -extern uint8_t get_byte(uint32_t addr); -extern void store_byte(uint32_t addr, uint8_t data); -extern uint16_t get_half_word(uint32_t addr); -extern void store_half_word(uint32_t addr, uint16_t data); -extern uint32_t get_word(uint32_t addr); -extern void store_word(uint32_t addr, uint32_t data); -extern uint32_t get_instruct(struct NIOS_CPU * cpu, uint32_t * mem_base, - uint32_t base_addr); -extern void dump_register(struct NIOS_CPU * cpu); -extern void dump_curr_code(uint32_t code); -extern void dump_next_code(struct NIOS_CPU * cpu); -extern void dump_pc(struct NIOS_CPU * cpu); -extern void set_break(struct NIOS_CPU * cpu, char * input); -extern void dump_mem(struct NIOS_CPU * cpu, char * input); -extern uint32_t ascii_to_hex(char * buf, uint32_t buf_len); - -#define def_i_type_code struct i_type_code * instr = (struct i_type_code *)&code -#define def_j_type_code struct j_type_code * instr = (struct j_type_code *)&code -#define def_r_type_code struct r_type_code * instr = (struct r_type_code *)&code - - -/* BIT Definition for Control register */ -#define REG_STATUS_PIE (0x01) -#define REG_STATUS_EH (1<<2) - -#define CPU_HAS_IRQ (0x01) -#define CPU_HAS_EXCEPTION (0x02) -#define CPU_HAS_NO_EVENT (0) - -extern void handle_irq_exception(struct NIOS_CPU * cpu); -extern void clean_ipending(uint32_t mask); -extern void trace_pc(struct NIOS_CPU * cpu); -#endif - diff --git a/public.h b/public.h deleted file mode 100644 index a84b6f6..0000000 --- a/public.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - Nios-sim - one simple NIOSII simulator only for personal interest and fun. - 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. -*/ - -#ifndef __PUBLIC_H__ -#define __PUBLIC_H__ - -#include <stdio.h> -#include <stdint.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -#include "niosii.h" - -#define SIM_FALSE (0) -#define SIM_TRUE (1) - -typedef enum { - INVALID_FMT=0x00, - SREC_FMT=0x01 -}IMG_FORMAT; - -struct image_info{ - char * path_name; - IMG_FORMAT image_format; - uint32_t mem_size; - uint32_t * mem_base; - uint32_t entry_addr; - uint32_t base_addr; -}; - -struct symbol_obj; - -struct symbol_obj{ - char * sym_name; - uint32_t addr; - struct symbol_obj * next; -}; - -extern void load_image(void); -extern void alloc_image_mem(void); -extern void set_image_pathname(char * pathname); -extern void set_image_format(IMG_FORMAT format); -extern void set_image_memsize(char * size); -extern void set_image_entry_addr(uint32_t addr); -extern void set_image_base_addr(char * addr); -extern void set_cmdline(char * optarg); -extern void set_initrd(char * optarg); -extern void set_fs_image(char * optarg); -extern void init_cmdline(struct NIOS_CPU * cpu); -extern void init_initrd(struct NIOS_CPU * cpu); -extern void init_fs_image(struct NIOS_CPU * cpu); -extern void print_image_info(void); -extern void simulating(void); -extern struct image_info * get_image_info(void); -extern void set_debug_mode(struct NIOS_CPU * cpu); -extern void load_symbol_file(char * symbol_file); -extern struct symbol_obj * get_symbol(uint32_t addr); - -#define SIM_MODE (0) -#define DEBUG_MODE (1) -#define EXIT_MODE (2) -extern int32_t get_run_mode(void); - -#endif /*__PUBLIC_H__*/ - - |