From 00fde4a2f24c326d47b8432bc408f64eb8b28842 Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka" <tadashi.g.takaoka@gmail.com>
Date: Fri, 29 Jun 2018 14:03:09 +0900
Subject: [PATCH] Fix sim driver and simio_timer

- Fix sim driver so that it can handle two bytes read/write.
- Add error message regarding odd size write to sim driver.
- Fix simio_timer constructor so that can accept size.
- Fix simio_timer so that we read/write channels' registers.
---
 drivers/sim.c       | 11 +++++++++--
 simio/simio_timer.c | 11 ++++++-----
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/sim.c b/drivers/sim.c
index b317695..2985a38 100644
--- a/drivers/sim.c
+++ b/drivers/sim.c
@@ -619,7 +619,7 @@ static int sim_readmem(device_t dev_base, address_t addr,
 	}
 
 	/* Read word IO addresses */
-	while (len > 2 && (addr < 0x200)) {
+	while (len >= 2 && addr < 0x200) {
 		uint16_t data = 0;
 
 		simio_read(addr, &data);
@@ -654,7 +654,14 @@ static int sim_writemem(device_t dev_base, address_t addr,
 	}
 
 	/* Write word IO addresses */
-	while (len > 2 && (addr < 0x200)) {
+	if (len == 1 && addr < 0x200) {
+		printc_err("sim: memory write on word IO, "
+                   "at least 2 bytes data are necessary.\n");
+	} else if (len % 2 != 0 && addr < 0x200) {
+		printc_err("sim: memory write on word IO, "
+                   "the last byte is ignored.\n");
+	}
+	while (len >= 2 && addr < 0x200) {
 		simio_write(addr, ((uint16_t)mem[1] << 8) | mem[0]);
 		mem += 2;
 		len -= 2;
diff --git a/simio/simio_timer.c b/simio/simio_timer.c
index cc77411..63aa83d 100644
--- a/simio/simio_timer.c
+++ b/simio/simio_timer.c
@@ -88,6 +88,7 @@ static struct simio_device *timer_create(char **arg_text)
 				   size_text);
 			return NULL;
 		}
+		size = value;
 
 		if (size < 2 || size > MAX_CCRS) {
 			printc_err("timer: invalid size: %d\n", size);
@@ -282,7 +283,7 @@ static int timer_info(struct simio_device *dev)
 	printc("\n");
 
 	for (i = 0; i < tr->size; i++)
-		printc("Channel %2d, TACTL = 0x%04x, TACCR = 0x%04x\n",
+		printc("Channel %2d, TACCTL = 0x%04x, TACCR = 0x%04x\n",
 		       i, tr->ctls[i], tr->ccrs[i]);
 
 	return 0;
@@ -307,7 +308,7 @@ static int timer_write(struct simio_device *dev,
 	}
 
 	if (addr >= tr->base_addr + 2 &&
-	    addr < tr->base_addr + tr->size + 2) {
+	    addr < tr->base_addr + (tr->size << 1) + 2) {
 		int index = ((addr & 0xf) - 2) >> 1;
 
 		tr->ctls[index] = (data & 0xf9f7) |
@@ -316,7 +317,7 @@ static int timer_write(struct simio_device *dev,
 	}
 
 	if (addr >= tr->base_addr + 0x12 &&
-	    addr < tr->base_addr + tr->size + 0x12) {
+	    addr < tr->base_addr + (tr->size << 1) + 0x12) {
 		int index = ((addr & 0xf) - 2) >> 1;
 
 		tr->ccrs[index] = data;
@@ -348,13 +349,13 @@ static int timer_read(struct simio_device *dev,
 	}
 
 	if (addr >= tr->base_addr + 2 &&
-	    addr < tr->base_addr + tr->size + 2) {
+	    addr < tr->base_addr + (tr->size << 1) + 2) {
 		*data = tr->ctls[((addr & 0xf) - 2) >> 1];
 		return 0;
 	}
 
 	if (addr >= tr->base_addr + 0x12 &&
-	    addr < tr->base_addr + tr->size + 0x12) {
+	    addr < tr->base_addr + (tr->size << 1) + 0x12) {
 		*data = tr->ccrs[((addr & 0xf) - 2) >> 1];
 		return 0;
 	}