1 /* 2 * ARM CMSDK APB dual-timer emulation 3 * 4 * Copyright (c) 2018 Linaro Limited 5 * Written by Peter Maydell 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 or 9 * (at your option) any later version. 10 */ 11 12 /* 13 * This is a model of the "APB dual-input timer" which is part of the Cortex-M 14 * System Design Kit (CMSDK) and documented in the Cortex-M System 15 * Design Kit Technical Reference Manual (ARM DDI0479C): 16 * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit 17 * 18 * QEMU interface: 19 * + QOM property "pclk-frq": frequency at which the timer is clocked 20 * + sysbus MMIO region 0: the register bank 21 * + sysbus IRQ 0: combined timer interrupt TIMINTC 22 * + sysbus IRO 1: timer block 1 interrupt TIMINT1 23 * + sysbus IRQ 2: timer block 2 interrupt TIMINT2 24 */ 25 26 #ifndef CMSDK_APB_DUALTIMER_H 27 #define CMSDK_APB_DUALTIMER_H 28 29 #include "hw/sysbus.h" 30 #include "hw/ptimer.h" 31 #include "qom/object.h" 32 33 #define TYPE_CMSDK_APB_DUALTIMER "cmsdk-apb-dualtimer" 34 OBJECT_DECLARE_SIMPLE_TYPE(CMSDKAPBDualTimer, CMSDK_APB_DUALTIMER) 35 36 37 /* One of the two identical timer modules in the dual-timer module */ 38 typedef struct CMSDKAPBDualTimerModule { 39 CMSDKAPBDualTimer *parent; 40 struct ptimer_state *timer; 41 qemu_irq timerint; 42 /* 43 * We must track the guest LOAD and VALUE register state by hand 44 * rather than leaving this state only in the ptimer limit/count, 45 * because if CONTROL.SIZE is 0 then only the low 16 bits of the 46 * counter actually counts, but the high half is still guest 47 * accessible. 48 */ 49 uint32_t load; 50 uint32_t value; 51 uint32_t control; 52 uint32_t intstatus; 53 } CMSDKAPBDualTimerModule; 54 55 #define CMSDK_APB_DUALTIMER_NUM_MODULES 2 56 57 struct CMSDKAPBDualTimer { 58 /*< private >*/ 59 SysBusDevice parent_obj; 60 61 /*< public >*/ 62 MemoryRegion iomem; 63 qemu_irq timerintc; 64 uint32_t pclk_frq; 65 66 CMSDKAPBDualTimerModule timermod[CMSDK_APB_DUALTIMER_NUM_MODULES]; 67 uint32_t timeritcr; 68 uint32_t timeritop; 69 }; 70 71 #endif 72