Hi Peter. On 5 November 2013 14:54, Peter Maydell <peter.mayd...@linaro.org> wrote: > > On 5 November 2013 11:41, Jan Petrouš <jan.petr...@tieto.com> wrote: > > Linux kernel from version 3.4 requires CM_REFCNT register for sched timer > > for Integrator/CP board (integrator_defconfig). > > > > See > > http://infocenter.arm.com/help/topic/com.arm.doc.dui0138e/ch04s06s11.html > > > > Signed-off-by: Jan Petrous <jan.petr...@tieto.com> > > Hi; thanks for this patch. (I have to wonder why on earth > people are still messing with kernel functionality for such > an ancient devboard :-)). >
Hehe, duno, but when I started learning QEMU the Integrator devboard looked for me the nice start-up point = very simple to understand and only very basic, but still core, device list. And when I moved from precompiled kernels (downloaded from internet) to my own ones I found the issue with default kernel configuration. And because it can help to not fool somebody later I decided to release patch :) > > > diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c > > index c44b2a4..f419764 100644 > > --- a/hw/arm/integratorcp.c > > +++ b/hw/arm/integratorcp.c > > @@ -83,8 +83,11 @@ static uint64_t integratorcm_read(void *opaque, hwaddr > > offset, > > case 9: /* CM_INIT */ > > return s->cm_init; > > case 10: /* CM_REFCT */ > > could you fix this comment to add the 'N' to CM_REFCNT while > you're changing this bit of code, please? Done. > > > > - /* ??? High frequency timer. */ > > - hw_error("integratorcm_read: CM_REFCT"); > > + /* This register, CM_REFCNT, provides a 32-bit count value. > > + * The count increments at the fixed reference clock frequency of 24MHz > > + * and can be used as a real-time counter. > > + */ > > The indent here doesn't look right, I think you have > hardcoded tabs here rather than spaces. If you run your > patch through scripts/checkpatch.pl it should catch this > sort of mistake. > Yes, you are right. My fault. Fixed now. > > > + return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24, 1000); > > case 12: /* CM_FLAGS */ > > return s->cm_flags; > > case 14: /* CM_NVFLAGS */ > > The spec says that this register resets to zero, so I think > it would be good to implement that: put a uint32_t cm_refcnt_offset > in the IntegratorCMState struct, initialize it with the initial > value of muldiv64(etc) in integratorcm_init(), and then in > integratorcm_read() return (uint32_t)muldiv64(etc) - cm_refcnt_offset > for the register read. > Added too. > > (We don't actually implement a proper reset function in this device > at the moment, but putting in the offset field gives us a marker > for doing it right if/when we add a reset function later on.) > > thanks > -- PMM Here is my next version: Linux kernel from version 3.4 requires CM_REFCNT register for sched timer for Integrator/CP board (integrator_defconfig). See http://infocenter.arm.com/help/topic/com.arm.doc.dui0138e/ch04s06s11.html Signed-off-by: Jan Petrous <jan.petr...@tieto.com> --- hw/arm/integratorcp.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index c44b2a4..a759689 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -36,6 +36,7 @@ typedef struct IntegratorCMState { uint32_t cm_init; uint32_t cm_flags; uint32_t cm_nvflags; + uint32_t cm_refcnt_offset; uint32_t int_level; uint32_t irq_enabled; uint32_t fiq_enabled; @@ -82,9 +83,13 @@ static uint64_t integratorcm_read(void *opaque, hwaddr offset, return s->cm_sdram; case 9: /* CM_INIT */ return s->cm_init; - case 10: /* CM_REFCT */ - /* ??? High frequency timer. */ - hw_error("integratorcm_read: CM_REFCT"); + case 10: /* CM_REFCNT */ + /* This register, CM_REFCNT, provides a 32-bit count value. + * The count increments at the fixed reference clock frequency of 24MHz + * and can be used as a real-time counter. + */ + return (uint32_t)muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24, + 1000) - s->cm_refcnt_offset; case 12: /* CM_FLAGS */ return s->cm_flags; case 14: /* CM_NVFLAGS */ @@ -257,6 +262,8 @@ static int integratorcm_init(SysBusDevice *dev) } memcpy(integrator_spd + 73, "QEMU-MEMORY", 11); s->cm_init = 0x00000112; + s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24, + 1000); memory_region_init_ram(&s->flash, OBJECT(s), "integrator.flash", 0x100000); vmstate_register_ram_global(&s->flash); -- 1.7.11.3
From ff26b99b586f5633fc7b876f75e5a5271e141563 Mon Sep 17 00:00:00 2001 From: Jan Petrous <jan.petr...@tieto.com> Date: Tue, 5 Nov 2013 12:13:57 +0100 Subject: [PATCH] integrator/cp: add support for REFCNT register Linux kernel from version 3.4 requires CM_REFCNT register for sched timer for Integrator/CP board (integrator_defconfig). See http://infocenter.arm.com/help/topic/com.arm.doc.dui0138e/ch04s06s11.html Signed-off-by: Jan Petrous <jan.petr...@tieto.com> --- hw/arm/integratorcp.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index c44b2a4..a759689 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -36,6 +36,7 @@ typedef struct IntegratorCMState { uint32_t cm_init; uint32_t cm_flags; uint32_t cm_nvflags; + uint32_t cm_refcnt_offset; uint32_t int_level; uint32_t irq_enabled; uint32_t fiq_enabled; @@ -82,9 +83,13 @@ static uint64_t integratorcm_read(void *opaque, hwaddr offset, return s->cm_sdram; case 9: /* CM_INIT */ return s->cm_init; - case 10: /* CM_REFCT */ - /* ??? High frequency timer. */ - hw_error("integratorcm_read: CM_REFCT"); + case 10: /* CM_REFCNT */ + /* This register, CM_REFCNT, provides a 32-bit count value. + * The count increments at the fixed reference clock frequency of 24MHz + * and can be used as a real-time counter. + */ + return (uint32_t)muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24, + 1000) - s->cm_refcnt_offset; case 12: /* CM_FLAGS */ return s->cm_flags; case 14: /* CM_NVFLAGS */ @@ -257,6 +262,8 @@ static int integratorcm_init(SysBusDevice *dev) } memcpy(integrator_spd + 73, "QEMU-MEMORY", 11); s->cm_init = 0x00000112; + s->cm_refcnt_offset = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24, + 1000); memory_region_init_ram(&s->flash, OBJECT(s), "integrator.flash", 0x100000); vmstate_register_ram_global(&s->flash); -- 1.7.11.3