From patchwork Tue Nov 22 03:25:03 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Chubb X-Patchwork-Id: 126995 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 340101007D1 for ; Tue, 22 Nov 2011 14:25:27 +1100 (EST) Received: from localhost ([::1]:56282 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RSgz6-0001Uf-5z for incoming@patchwork.ozlabs.org; Mon, 21 Nov 2011 22:25:24 -0500 Received: from eggs.gnu.org ([140.186.70.92]:53518) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RSgyz-0001UO-M1 for qemu-devel@nongnu.org; Mon, 21 Nov 2011 22:25:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RSgyy-00041d-29 for qemu-devel@nongnu.org; Mon, 21 Nov 2011 22:25:17 -0500 Received: from lemon.ertos.nicta.com.au ([203.143.174.143]:34155 helo=lemon.ken.nicta.com.au) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RSgyx-00041Z-Lk for qemu-devel@nongnu.org; Mon, 21 Nov 2011 22:25:16 -0500 Received: from [2001:388:d000:800:224:d7ff:feaf:390] (port=45126 helo=Diprotodon.keg.ertos.in.nicta.com.au.chubb.wattle.id.au) by lemon.ken.nicta.com.au with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.72) (envelope-from ) id 1RSgym-0002Ch-KX; Tue, 22 Nov 2011 14:25:08 +1100 Date: Tue, 22 Nov 2011 14:25:03 +1100 Message-ID: From: Peter Chubb To: Andreas =?UTF-8?B?RsOkcmJlcg==?= In-Reply-To: <4ECAD841.1090307@web.de> References: <4ECAD841.1090307@web.de> User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL/10.8 Emacs/23.3 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO) X-Face: GgFg(Z>fx((4\32hvXq<)|jndSniCH~~$D)Ka:P@e@JR1P%Vr}EwUdfwf-4j\rUs#JR{'h# !]])6%Jh~b$VA|ALhnpPiHu[-x~@<"@Iv&|%R)Fq[[, (&Z'O)Q)xCqe1\M[F8#9l8~}#u$S$Rm`S9% \'T@`:&8>Sb*c5d'=eDYI&GF`+t[LfDH="MP5rwOO]w>ALi7'=QJHz&y&C&TE_3j! Organization: National ICT Australia MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") X-SA-Exim-Connect-IP: 2001:388:d000:800:224:d7ff:feaf:390 X-SA-Exim-Mail-From: peter.chubb@nicta.com.au X-SA-Exim-Version: 4.2.1 (built Mon, 22 Mar 2010 06:52:44 +0000) X-SA-Exim-Scanned: Yes (on lemon.ken.nicta.com.au) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 203.143.174.143 Cc: Peter Maydell , davidm@ok-labs.com, qemu-devel@nongnu.org, Peter Chubb , Paul Brook , Peter Chubb , philipo@ok-labs.com Subject: Re: [Qemu-devel] [PATCH] [ARM] Fix sp804 dual-timer X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Properly implement dual-timer read/write for the sp804 dual timer module. Based on ARM specs at http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0271d/index.html Signed-off-by: Hans Jang Signed-off-by: David Mirabito Signed-off-by: Peter Chubb Reviewed-by: Peter Maydell --- hw/arm_timer.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) -- Dr Peter Chubb http://www.gelato.unsw.edu.au peterc AT gelato.unsw.edu.au http://www.ertos.nicta.com.au ERTOS within National ICT Australia Index: qemu-working/hw/arm_timer.c =================================================================== --- qemu-working.orig/hw/arm_timer.c 2011-11-22 14:21:50.873221242 +1100 +++ qemu-working/hw/arm_timer.c 2011-11-22 14:22:21.986129734 +1100 @@ -163,64 +163,93 @@ static arm_timer_state *arm_timer_init(u s->freq = freq; s->control = TIMER_CTRL_IE; bh = qemu_bh_new(arm_timer_tick, s); s->timer = ptimer_init(bh); vmstate_register(NULL, -1, &vmstate_arm_timer, s); return s; } /* ARM PrimeCell SP804 dual timer module. - Docs for this device don't seem to be publicly available. This - implementation is based on guesswork, the linux kernel sources and the - Integrator/CP timer modules. */ + * Docs at + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0271d/index.html +*/ typedef struct { SysBusDevice busdev; MemoryRegion iomem; arm_timer_state *timer[2]; int level[2]; qemu_irq irq; } sp804_state; +static const uint8_t sp804_ids[] = { + /* Timer ID */ + 0x04, 0x18, 0x14, 0, + /* PrimeCell ID */ + 0xd, 0xf0, 0x05, 0xb1 +}; + /* Merge the IRQs from the two component devices. */ static void sp804_set_irq(void *opaque, int irq, int level) { sp804_state *s = (sp804_state *)opaque; s->level[irq] = level; qemu_set_irq(s->irq, s->level[0] || s->level[1]); } static uint64_t sp804_read(void *opaque, target_phys_addr_t offset, unsigned size) { sp804_state *s = (sp804_state *)opaque; - /* ??? Don't know the PrimeCell ID for this device. */ if (offset < 0x20) { return arm_timer_read(s->timer[0], offset); - } else { + } + if (offset < 0x40) { return arm_timer_read(s->timer[1], offset - 0x20); } + + /* TimerPeriphID */ + if (offset >= 0xfe0 && offset <= 0xffc) { + return sp804_ids[(offset - 0xfe0) >> 2]; + } + + switch (offset) { + /* Integration Test control registers, which we won't support */ + case 0xf00: /* TimerITCR */ + case 0xf04: /* TimerITOP (strictly write only but..) */ + return 0; + } + + hw_error("%s: Bad offset %x\n", __func__, (int)offset); + return 0; } static void sp804_write(void *opaque, target_phys_addr_t offset, uint64_t value, unsigned size) { sp804_state *s = (sp804_state *)opaque; if (offset < 0x20) { arm_timer_write(s->timer[0], offset, value); - } else { + return; + } + + if (offset < 0x40) { arm_timer_write(s->timer[1], offset - 0x20, value); + return; } + + /* Technically we could be writing to the Test Registers, but not likely */ + hw_error("%s: Bad offset %x\n", __func__, (int)offset); } static const MemoryRegionOps sp804_ops = { .read = sp804_read, .write = sp804_write, .endianness = DEVICE_NATIVE_ENDIAN, }; static const VMStateDescription vmstate_sp804 = { .name = "sp804",