diff options
Diffstat (limited to 'io_device.c')
-rw-r--r-- | io_device.c | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/io_device.c b/io_device.c new file mode 100644 index 0000000..e650608 --- /dev/null +++ b/io_device.c @@ -0,0 +1,155 @@ +/* + 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; + } +} +/*--------------------------------------------------------------------------*/ |