From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MQDoJ-0005Zq-QA for qemu-devel@nongnu.org; Mon, 13 Jul 2009 01:10:43 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MQDoE-0005VS-O1 for qemu-devel@nongnu.org; Mon, 13 Jul 2009 01:10:42 -0400 Received: from [199.232.76.173] (port=49432 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MQDoD-0005Ub-Nr for qemu-devel@nongnu.org; Mon, 13 Jul 2009 01:10:37 -0400 Received: from smtp.srv.ualberta.ca ([129.128.5.19]:56409 helo=mail7.srv.ualberta.ca) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1MQDoD-0003LC-4t for qemu-devel@nongnu.org; Mon, 13 Jul 2009 01:10:37 -0400 From: Logan Gunthorpe Date: Sun, 12 Jul 2009 23:10:21 -0600 Message-Id: <1247461821-20621-4-git-send-email-logang@ece.ualberta.ca> In-Reply-To: <1247461821-20621-1-git-send-email-logang@ece.ualberta.ca> References: <1247461821-20621-1-git-send-email-logang@ece.ualberta.ca> Subject: [Qemu-devel] [PATCH 3/3] Stelaris 16-bit timer mode. List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Logan Gunthorpe - Finished the 16-bit timer mode in the stelaris module which was previously marked as a TODO. --- hw/stellaris.c | 35 ++++++++++++++++++++++++----------- 1 files changed, 24 insertions(+), 11 deletions(-) diff --git a/hw/stellaris.c b/hw/stellaris.c index 4fadeec..f23fb87 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -60,14 +60,16 @@ typedef struct gptm_state { QEMUTimer *timer[2]; /* The timers have an alternate output used to trigger the ADC. */ qemu_irq trigger; - qemu_irq irq; + qemu_irq irq[2]; } gptm_state; static void gptm_update_irq(gptm_state *s) { int level; - level = (s->state & s->mask) != 0; - qemu_set_irq(s->irq, level); + level = ((s->state & s->mask) & 0xf) != 0; + qemu_set_irq(s->irq[0], level); + level = ((s->state & s->mask) & 0xf00) != 0; + qemu_set_irq(s->irq[1], level); } static void gptm_stop(gptm_state *s, int n) @@ -94,7 +96,7 @@ static void gptm_reload(gptm_state *s, int n, int reset) } else if (s->mode[n] == 0xa) { /* PWM mode. Not implemented. */ } else { - hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]); + tick += (int64_t) s->load[n] * system_clock_scale * (s->prescale[n]+1); } s->tick[n] = tick; qemu_mod_timer(s->timer[n], tick); @@ -135,7 +137,15 @@ static void gptm_tick(void *opaque) } else if (s->mode[n] == 0xa) { /* PWM mode. Not implemented. */ } else { - hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]); + s->state |= 1 << n*8; + + if (s->mode[n] & 1) { + /* One-shot. */ + s->control &= ~(1 << n*8); + } else { + /* Periodic. */ + gptm_reload(s, n, 0); + } } gptm_update_irq(s); } @@ -226,11 +236,12 @@ static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value) } break; case 0x18: /* IMR */ - s->mask = value & 0x77; + s->mask = value & 0x0707; gptm_update_irq(s); break; case 0x24: /* CR */ s->state &= ~value; + gptm_update_irq(s); break; case 0x28: /* TAILR */ s->load[0] = value & 0xffff; @@ -265,7 +276,6 @@ static void gptm_write(void *opaque, target_phys_addr_t offset, uint32_t value) default: hw_error("gptm_write: Bad offset 0x%x\n", (int)offset); } - gptm_update_irq(s); } static CPUReadMemoryFunc *gptm_readfn[] = { @@ -344,7 +354,9 @@ static void stellaris_gptm_init(SysBusDevice *dev) int iomemtype; gptm_state *s = FROM_SYSBUS(gptm_state, dev); - sysbus_init_irq(dev, &s->irq); + sysbus_init_irq(dev, &s->irq[0]); + sysbus_init_irq(dev, &s->irq[1]); + qdev_init_gpio_out(&dev->qdev, &s->trigger, 1); iomemtype = cpu_register_io_memory(gptm_readfn, @@ -1317,9 +1329,10 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, } for (i = 0; i < 4; i++) { if (board->dc2 & (0x10000 << i)) { - dev = sysbus_create_simple("stellaris-gptm", - 0x40030000 + i * 0x1000, - pic[timer_irq[i]]); + dev = sysbus_create_varargs("stellaris-gptm", + 0x40030000 + i * 0x1000, + pic[timer_irq[i]], + pic[timer_irq[i]+1], NULL); /* TODO: This is incorrect, but we get away with it because the ADC output is only ever pulsed. */ qdev_connect_gpio_out(dev, 0, adc); -- 1.5.6.5