summaryrefslogtreecommitdiff
path: root/io_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'io_device.c')
-rw-r--r--io_device.c155
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;
+ }
+}
+/*--------------------------------------------------------------------------*/