aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2011-04-26 05:47:14 +0000
committerMike Frysinger <vapier@gentoo.org>2011-04-26 05:47:14 +0000
commit054c055baf06037a3971b3cfdb8ebd4a7cf5f289 (patch)
treeba82ec0dc4aabac66416741779ae06e1b7d09eef
parent5e0ba1a39e6fd114a5557a674c6834d6dc1cca08 (diff)
downloadfsf-binutils-gdb-054c055baf06037a3971b3cfdb8ebd4a7cf5f289.zip
fsf-binutils-gdb-054c055baf06037a3971b3cfdb8ebd4a7cf5f289.tar.gz
fsf-binutils-gdb-054c055baf06037a3971b3cfdb8ebd4a7cf5f289.tar.bz2
sim: gpio: add output support
Make all of the pins bidirectional, and support sending signals when software drives the pins as outputs. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r--sim/bfin/ChangeLog8
-rw-r--r--sim/bfin/dv-bfin_gpio.c61
2 files changed, 53 insertions, 16 deletions
diff --git a/sim/bfin/ChangeLog b/sim/bfin/ChangeLog
index a7e80b1..6314e97 100644
--- a/sim/bfin/ChangeLog
+++ b/sim/bfin/ChangeLog
@@ -1,5 +1,13 @@
2011-04-26 Mike Frysinger <vapier@gentoo.org>
+ * dv-bfin_gpio.c (bfin_gpio_forward_ouput): New function.
+ (bfin_gpio_io_write_buffer): Store the current port state into
+ "data", and call bfin_gpio_forward_ouput when the data or dir
+ MMRs are updated.
+ (bfin_gpio_ports): Change p0..p15 to bidirect_port.
+
+2011-04-26 Mike Frysinger <vapier@gentoo.org>
+
* dv-bfin_gpio.c (bfin_gpio): Add "int_state" member.
(bfin_gpio_forward_int, bfin_gpio_forward_ints): New functions.
(bfin_gpio_io_write_buffer): Call bfin_gpio_forward_int when the
diff --git a/sim/bfin/dv-bfin_gpio.c b/sim/bfin/dv-bfin_gpio.c
index 7a6acb6..4d94440 100644
--- a/sim/bfin/dv-bfin_gpio.c
+++ b/sim/bfin/dv-bfin_gpio.c
@@ -76,6 +76,30 @@ bfin_gpio_forward_ints (struct hw *me, struct bfin_gpio *port)
bfin_gpio_forward_int (me, port, port->maskb, 1);
}
+static void
+bfin_gpio_forward_ouput (struct hw *me, struct bfin_gpio *port, bu32 odata)
+{
+ int pin, value, ovalue, bit;
+
+ for (pin = 0; pin < 16; ++pin)
+ {
+ bit = 1 << pin;
+
+ /* Make sure this is an output pin. */
+ if (!(port->dir & bit))
+ continue;
+
+ /* Only signal port if the pin changes value. */
+ value = !!(port->data & bit);
+ ovalue = !!(odata & bit);
+ if (value == ovalue)
+ continue;
+
+ HW_TRACE ((me, "outputting gpio %i changed to %i", pin, value));
+ hw_port_event (me, pin, value);
+ }
+}
+
static unsigned
bfin_gpio_io_write_buffer (struct hw *me, const void *source, int space,
address_word addr, unsigned nr_bytes)
@@ -84,6 +108,7 @@ bfin_gpio_io_write_buffer (struct hw *me, const void *source, int space,
bu32 mmr_off;
bu16 value;
bu16 *valuep;
+ bu32 data = port->data;
value = dv_load_2 (source);
mmr_off = addr - port->base;
@@ -134,6 +159,10 @@ bfin_gpio_io_write_buffer (struct hw *me, const void *source, int space,
/* If updating masks, make sure we send updated port info. */
switch (mmr_off)
{
+ case mmr_offset(dir):
+ case mmr_offset(data) ... mmr_offset(toggle):
+ bfin_gpio_forward_ouput (me, port, data);
+ break;
case mmr_offset(maska) ... mmr_offset(maska_toggle):
bfin_gpio_forward_int (me, port, port->maska, 0);
break;
@@ -199,22 +228,22 @@ static const struct hw_port_descriptor bfin_gpio_ports[] =
{
{ "mask_a", 0, 0, output_port, },
{ "mask_b", 1, 0, output_port, },
- { "p0", 0, 0, input_port, },
- { "p1", 1, 0, input_port, },
- { "p2", 2, 0, input_port, },
- { "p3", 3, 0, input_port, },
- { "p4", 4, 0, input_port, },
- { "p5", 5, 0, input_port, },
- { "p6", 6, 0, input_port, },
- { "p7", 7, 0, input_port, },
- { "p8", 8, 0, input_port, },
- { "p9", 9, 0, input_port, },
- { "p10", 10, 0, input_port, },
- { "p11", 11, 0, input_port, },
- { "p12", 12, 0, input_port, },
- { "p13", 13, 0, input_port, },
- { "p14", 14, 0, input_port, },
- { "p15", 15, 0, input_port, },
+ { "p0", 0, 0, bidirect_port, },
+ { "p1", 1, 0, bidirect_port, },
+ { "p2", 2, 0, bidirect_port, },
+ { "p3", 3, 0, bidirect_port, },
+ { "p4", 4, 0, bidirect_port, },
+ { "p5", 5, 0, bidirect_port, },
+ { "p6", 6, 0, bidirect_port, },
+ { "p7", 7, 0, bidirect_port, },
+ { "p8", 8, 0, bidirect_port, },
+ { "p9", 9, 0, bidirect_port, },
+ { "p10", 10, 0, bidirect_port, },
+ { "p11", 11, 0, bidirect_port, },
+ { "p12", 12, 0, bidirect_port, },
+ { "p13", 13, 0, bidirect_port, },
+ { "p14", 14, 0, bidirect_port, },
+ { "p15", 15, 0, bidirect_port, },
{ NULL, 0, 0, 0, },
};