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 19 #include "qemu/osdep.h" 20 #include "qemu/log.h" 21 #include "trace.h" 22 #include "qapi/error.h" 23 #include "qemu/main-loop.h" 24 #include "hw/sysbus.h" 25 #include "hw/registerfields.h" 26 #include "hw/timer/cmsdk-apb-dualtimer.h" 27 28 REG32(TIMER1LOAD, 0x0) 29 REG32(TIMER1VALUE, 0x4) 30 REG32(TIMER1CONTROL, 0x8) 31 FIELD(CONTROL, ONESHOT, 0, 1) 32 FIELD(CONTROL, SIZE, 1, 1) 33 FIELD(CONTROL, PRESCALE, 2, 2) 34 FIELD(CONTROL, INTEN, 5, 1) 35 FIELD(CONTROL, MODE, 6, 1) 36 FIELD(CONTROL, ENABLE, 7, 1) 37 #define R_CONTROL_VALID_MASK (R_CONTROL_ONESHOT_MASK | R_CONTROL_SIZE_MASK | \ 38 R_CONTROL_PRESCALE_MASK | R_CONTROL_INTEN_MASK | \ 39 R_CONTROL_MODE_MASK | R_CONTROL_ENABLE_MASK) 40 REG32(TIMER1INTCLR, 0xc) 41 REG32(TIMER1RIS, 0x10) 42 REG32(TIMER1MIS, 0x14) 43 REG32(TIMER1BGLOAD, 0x18) 44 REG32(TIMER2LOAD, 0x20) 45 REG32(TIMER2VALUE, 0x24) 46 REG32(TIMER2CONTROL, 0x28) 47 REG32(TIMER2INTCLR, 0x2c) 48 REG32(TIMER2RIS, 0x30) 49 REG32(TIMER2MIS, 0x34) 50 REG32(TIMER2BGLOAD, 0x38) 51 REG32(TIMERITCR, 0xf00) 52 FIELD(TIMERITCR, ENABLE, 0, 1) 53 #define R_TIMERITCR_VALID_MASK R_TIMERITCR_ENABLE_MASK 54 REG32(TIMERITOP, 0xf04) 55 FIELD(TIMERITOP, TIMINT1, 0, 1) 56 FIELD(TIMERITOP, TIMINT2, 1, 1) 57 #define R_TIMERITOP_VALID_MASK (R_TIMERITOP_TIMINT1_MASK | \ 58 R_TIMERITOP_TIMINT2_MASK) 59 REG32(PID4, 0xfd0) 60 REG32(PID5, 0xfd4) 61 REG32(PID6, 0xfd8) 62 REG32(PID7, 0xfdc) 63 REG32(PID0, 0xfe0) 64 REG32(PID1, 0xfe4) 65 REG32(PID2, 0xfe8) 66 REG32(PID3, 0xfec) 67 REG32(CID0, 0xff0) 68 REG32(CID1, 0xff4) 69 REG32(CID2, 0xff8) 70 REG32(CID3, 0xffc) 71 72 /* PID/CID values */ 73 static const int timer_id[] = { 74 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ 75 0x23, 0xb8, 0x1b, 0x00, /* PID0..PID3 */ 76 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ 77 }; 78 79 static bool cmsdk_dualtimermod_intstatus(CMSDKAPBDualTimerModule *m) 80 { 81 /* Return masked interrupt status for the timer module */ 82 return m->intstatus && (m->control & R_CONTROL_INTEN_MASK); 83 } 84 85 static void cmsdk_apb_dualtimer_update(CMSDKAPBDualTimer *s) 86 { 87 bool timint1, timint2, timintc; 88 89 if (s->timeritcr) { 90 /* Integration test mode: outputs driven directly from TIMERITOP bits */ 91 timint1 = s->timeritop & R_TIMERITOP_TIMINT1_MASK; 92 timint2 = s->timeritop & R_TIMERITOP_TIMINT2_MASK; 93 } else { 94 timint1 = cmsdk_dualtimermod_intstatus(&s->timermod[0]); 95 timint2 = cmsdk_dualtimermod_intstatus(&s->timermod[1]); 96 } 97 98 timintc = timint1 || timint2; 99 100 qemu_set_irq(s->timermod[0].timerint, timint1); 101 qemu_set_irq(s->timermod[1].timerint, timint2); 102 qemu_set_irq(s->timerintc, timintc); 103 } 104 105 static void cmsdk_dualtimermod_write_control(CMSDKAPBDualTimerModule *m, 106 uint32_t newctrl) 107 { 108 /* Handle a write to the CONTROL register */ 109 uint32_t changed; 110 111 newctrl &= R_CONTROL_VALID_MASK; 112 113 changed = m->control ^ newctrl; 114 115 if (changed & ~newctrl & R_CONTROL_ENABLE_MASK) { 116 /* ENABLE cleared, stop timer before any further changes */ 117 ptimer_stop(m->timer); 118 } 119 120 if (changed & R_CONTROL_PRESCALE_MASK) { 121 int divisor; 122 123 switch (FIELD_EX32(newctrl, CONTROL, PRESCALE)) { 124 case 0: 125 divisor = 1; 126 break; 127 case 1: 128 divisor = 16; 129 break; 130 case 2: 131 divisor = 256; 132 break; 133 case 3: 134 /* UNDEFINED; complain, and arbitrarily treat like 2 */ 135 qemu_log_mask(LOG_GUEST_ERROR, 136 "CMSDK APB dual-timer: CONTROL.PRESCALE==0b11" 137 " is undefined behaviour\n"); 138 divisor = 256; 139 break; 140 default: 141 g_assert_not_reached(); 142 } 143 ptimer_set_freq(m->timer, m->parent->pclk_frq / divisor); 144 } 145 146 if (changed & R_CONTROL_MODE_MASK) { 147 uint32_t load; 148 if (newctrl & R_CONTROL_MODE_MASK) { 149 /* Periodic: the limit is the LOAD register value */ 150 load = m->load; 151 } else { 152 /* Free-running: counter wraps around */ 153 load = ptimer_get_limit(m->timer); 154 if (!(m->control & R_CONTROL_SIZE_MASK)) { 155 load = deposit32(m->load, 0, 16, load); 156 } 157 m->load = load; 158 load = 0xffffffff; 159 } 160 if (!(m->control & R_CONTROL_SIZE_MASK)) { 161 load &= 0xffff; 162 } 163 ptimer_set_limit(m->timer, load, 0); 164 } 165 166 if (changed & R_CONTROL_SIZE_MASK) { 167 /* Timer switched between 16 and 32 bit count */ 168 uint32_t value, load; 169 170 value = ptimer_get_count(m->timer); 171 load = ptimer_get_limit(m->timer); 172 if (newctrl & R_CONTROL_SIZE_MASK) { 173 /* 16 -> 32, top half of VALUE is in struct field */ 174 value = deposit32(m->value, 0, 16, value); 175 } else { 176 /* 32 -> 16: save top half to struct field and truncate */ 177 m->value = value; 178 value &= 0xffff; 179 } 180 181 if (newctrl & R_CONTROL_MODE_MASK) { 182 /* Periodic, timer limit has LOAD value */ 183 if (newctrl & R_CONTROL_SIZE_MASK) { 184 load = deposit32(m->load, 0, 16, load); 185 } else { 186 m->load = load; 187 load &= 0xffff; 188 } 189 } else { 190 /* Free-running, timer limit is set to give wraparound */ 191 if (newctrl & R_CONTROL_SIZE_MASK) { 192 load = 0xffffffff; 193 } else { 194 load = 0xffff; 195 } 196 } 197 ptimer_set_count(m->timer, value); 198 ptimer_set_limit(m->timer, load, 0); 199 } 200 201 if (newctrl & R_CONTROL_ENABLE_MASK) { 202 /* 203 * ENABLE is set; start the timer after all other changes. 204 * We start it even if the ENABLE bit didn't actually change, 205 * in case the timer was an expired one-shot timer that has 206 * now been changed into a free-running or periodic timer. 207 */ 208 ptimer_run(m->timer, !!(newctrl & R_CONTROL_ONESHOT_MASK)); 209 } 210 211 m->control = newctrl; 212 } 213 214 static uint64_t cmsdk_apb_dualtimer_read(void *opaque, hwaddr offset, 215 unsigned size) 216 { 217 CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque); 218 uint64_t r; 219 220 if (offset >= A_TIMERITCR) { 221 switch (offset) { 222 case A_TIMERITCR: 223 r = s->timeritcr; 224 break; 225 case A_PID4 ... A_CID3: 226 r = timer_id[(offset - A_PID4) / 4]; 227 break; 228 default: 229 bad_offset: 230 qemu_log_mask(LOG_GUEST_ERROR, 231 "CMSDK APB dual-timer read: bad offset %x\n", 232 (int) offset); 233 r = 0; 234 break; 235 } 236 } else { 237 int timer = offset >> 5; 238 CMSDKAPBDualTimerModule *m; 239 240 if (timer >= ARRAY_SIZE(s->timermod)) { 241 goto bad_offset; 242 } 243 244 m = &s->timermod[timer]; 245 246 switch (offset & 0x1F) { 247 case A_TIMER1LOAD: 248 case A_TIMER1BGLOAD: 249 if (m->control & R_CONTROL_MODE_MASK) { 250 /* 251 * Periodic: the ptimer limit is the LOAD register value, (or 252 * just the low 16 bits of it if the timer is in 16-bit mode) 253 */ 254 r = ptimer_get_limit(m->timer); 255 if (!(m->control & R_CONTROL_SIZE_MASK)) { 256 r = deposit32(m->load, 0, 16, r); 257 } 258 } else { 259 /* Free-running: LOAD register value is just in m->load */ 260 r = m->load; 261 } 262 break; 263 case A_TIMER1VALUE: 264 r = ptimer_get_count(m->timer); 265 if (!(m->control & R_CONTROL_SIZE_MASK)) { 266 r = deposit32(m->value, 0, 16, r); 267 } 268 break; 269 case A_TIMER1CONTROL: 270 r = m->control; 271 break; 272 case A_TIMER1RIS: 273 r = m->intstatus; 274 break; 275 case A_TIMER1MIS: 276 r = cmsdk_dualtimermod_intstatus(m); 277 break; 278 default: 279 goto bad_offset; 280 } 281 } 282 283 trace_cmsdk_apb_dualtimer_read(offset, r, size); 284 return r; 285 } 286 287 static void cmsdk_apb_dualtimer_write(void *opaque, hwaddr offset, 288 uint64_t value, unsigned size) 289 { 290 CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque); 291 292 trace_cmsdk_apb_dualtimer_write(offset, value, size); 293 294 if (offset >= A_TIMERITCR) { 295 switch (offset) { 296 case A_TIMERITCR: 297 s->timeritcr = value & R_TIMERITCR_VALID_MASK; 298 cmsdk_apb_dualtimer_update(s); 299 break; 300 case A_TIMERITOP: 301 s->timeritop = value & R_TIMERITOP_VALID_MASK; 302 cmsdk_apb_dualtimer_update(s); 303 break; 304 default: 305 bad_offset: 306 qemu_log_mask(LOG_GUEST_ERROR, 307 "CMSDK APB dual-timer write: bad offset %x\n", 308 (int) offset); 309 break; 310 } 311 } else { 312 int timer = offset >> 5; 313 CMSDKAPBDualTimerModule *m; 314 315 if (timer >= ARRAY_SIZE(s->timermod)) { 316 goto bad_offset; 317 } 318 319 m = &s->timermod[timer]; 320 321 switch (offset & 0x1F) { 322 case A_TIMER1LOAD: 323 /* Set the limit, and immediately reload the count from it */ 324 m->load = value; 325 m->value = value; 326 if (!(m->control & R_CONTROL_SIZE_MASK)) { 327 value &= 0xffff; 328 } 329 if (!(m->control & R_CONTROL_MODE_MASK)) { 330 /* 331 * In free-running mode this won't set the limit but will 332 * still change the current count value. 333 */ 334 ptimer_set_count(m->timer, value); 335 } else { 336 if (!value) { 337 ptimer_stop(m->timer); 338 } 339 ptimer_set_limit(m->timer, value, 1); 340 if (value && (m->control & R_CONTROL_ENABLE_MASK)) { 341 /* Force possibly-expired oneshot timer to restart */ 342 ptimer_run(m->timer, 1); 343 } 344 } 345 break; 346 case A_TIMER1BGLOAD: 347 /* Set the limit, but not the current count */ 348 m->load = value; 349 if (!(m->control & R_CONTROL_MODE_MASK)) { 350 /* In free-running mode there is no limit */ 351 break; 352 } 353 if (!(m->control & R_CONTROL_SIZE_MASK)) { 354 value &= 0xffff; 355 } 356 ptimer_set_limit(m->timer, value, 0); 357 break; 358 case A_TIMER1CONTROL: 359 cmsdk_dualtimermod_write_control(m, value); 360 cmsdk_apb_dualtimer_update(s); 361 break; 362 case A_TIMER1INTCLR: 363 m->intstatus = 0; 364 cmsdk_apb_dualtimer_update(s); 365 break; 366 default: 367 goto bad_offset; 368 } 369 } 370 } 371 372 static const MemoryRegionOps cmsdk_apb_dualtimer_ops = { 373 .read = cmsdk_apb_dualtimer_read, 374 .write = cmsdk_apb_dualtimer_write, 375 .endianness = DEVICE_LITTLE_ENDIAN, 376 /* byte/halfword accesses are just zero-padded on reads and writes */ 377 .impl.min_access_size = 4, 378 .impl.max_access_size = 4, 379 .valid.min_access_size = 1, 380 .valid.max_access_size = 4, 381 }; 382 383 static void cmsdk_dualtimermod_tick(void *opaque) 384 { 385 CMSDKAPBDualTimerModule *m = opaque; 386 387 m->intstatus = 1; 388 cmsdk_apb_dualtimer_update(m->parent); 389 } 390 391 static void cmsdk_dualtimermod_reset(CMSDKAPBDualTimerModule *m) 392 { 393 m->control = R_CONTROL_INTEN_MASK; 394 m->intstatus = 0; 395 m->load = 0; 396 m->value = 0xffffffff; 397 ptimer_stop(m->timer); 398 /* 399 * We start in free-running mode, with VALUE at 0xffffffff, and 400 * in 16-bit counter mode. This means that the ptimer count and 401 * limit must both be set to 0xffff, so we wrap at 16 bits. 402 */ 403 ptimer_set_limit(m->timer, 0xffff, 1); 404 ptimer_set_freq(m->timer, m->parent->pclk_frq); 405 } 406 407 static void cmsdk_apb_dualtimer_reset(DeviceState *dev) 408 { 409 CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(dev); 410 int i; 411 412 trace_cmsdk_apb_dualtimer_reset(); 413 414 for (i = 0; i < ARRAY_SIZE(s->timermod); i++) { 415 cmsdk_dualtimermod_reset(&s->timermod[i]); 416 } 417 s->timeritcr = 0; 418 s->timeritop = 0; 419 } 420 421 static void cmsdk_apb_dualtimer_init(Object *obj) 422 { 423 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 424 CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(obj); 425 int i; 426 427 memory_region_init_io(&s->iomem, obj, &cmsdk_apb_dualtimer_ops, 428 s, "cmsdk-apb-dualtimer", 0x1000); 429 sysbus_init_mmio(sbd, &s->iomem); 430 sysbus_init_irq(sbd, &s->timerintc); 431 432 for (i = 0; i < ARRAY_SIZE(s->timermod); i++) { 433 sysbus_init_irq(sbd, &s->timermod[i].timerint); 434 } 435 } 436 437 static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp) 438 { 439 CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(dev); 440 int i; 441 442 if (s->pclk_frq == 0) { 443 error_setg(errp, "CMSDK APB timer: pclk-frq property must be set"); 444 return; 445 } 446 447 for (i = 0; i < ARRAY_SIZE(s->timermod); i++) { 448 CMSDKAPBDualTimerModule *m = &s->timermod[i]; 449 QEMUBH *bh = qemu_bh_new(cmsdk_dualtimermod_tick, m); 450 451 m->parent = s; 452 m->timer = ptimer_init(bh, 453 PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD | 454 PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT | 455 PTIMER_POLICY_NO_IMMEDIATE_RELOAD | 456 PTIMER_POLICY_NO_COUNTER_ROUND_DOWN); 457 } 458 } 459 460 static const VMStateDescription cmsdk_dualtimermod_vmstate = { 461 .name = "cmsdk-apb-dualtimer-module", 462 .version_id = 1, 463 .minimum_version_id = 1, 464 .fields = (VMStateField[]) { 465 VMSTATE_PTIMER(timer, CMSDKAPBDualTimerModule), 466 VMSTATE_UINT32(load, CMSDKAPBDualTimerModule), 467 VMSTATE_UINT32(value, CMSDKAPBDualTimerModule), 468 VMSTATE_UINT32(control, CMSDKAPBDualTimerModule), 469 VMSTATE_UINT32(intstatus, CMSDKAPBDualTimerModule), 470 VMSTATE_END_OF_LIST() 471 } 472 }; 473 474 static const VMStateDescription cmsdk_apb_dualtimer_vmstate = { 475 .name = "cmsdk-apb-dualtimer", 476 .version_id = 1, 477 .minimum_version_id = 1, 478 .fields = (VMStateField[]) { 479 VMSTATE_STRUCT_ARRAY(timermod, CMSDKAPBDualTimer, 480 CMSDK_APB_DUALTIMER_NUM_MODULES, 481 1, cmsdk_dualtimermod_vmstate, 482 CMSDKAPBDualTimerModule), 483 VMSTATE_UINT32(timeritcr, CMSDKAPBDualTimer), 484 VMSTATE_UINT32(timeritop, CMSDKAPBDualTimer), 485 VMSTATE_END_OF_LIST() 486 } 487 }; 488 489 static Property cmsdk_apb_dualtimer_properties[] = { 490 DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBDualTimer, pclk_frq, 0), 491 DEFINE_PROP_END_OF_LIST(), 492 }; 493 494 static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, void *data) 495 { 496 DeviceClass *dc = DEVICE_CLASS(klass); 497 498 dc->realize = cmsdk_apb_dualtimer_realize; 499 dc->vmsd = &cmsdk_apb_dualtimer_vmstate; 500 dc->reset = cmsdk_apb_dualtimer_reset; 501 dc->props = cmsdk_apb_dualtimer_properties; 502 } 503 504 static const TypeInfo cmsdk_apb_dualtimer_info = { 505 .name = TYPE_CMSDK_APB_DUALTIMER, 506 .parent = TYPE_SYS_BUS_DEVICE, 507 .instance_size = sizeof(CMSDKAPBDualTimer), 508 .instance_init = cmsdk_apb_dualtimer_init, 509 .class_init = cmsdk_apb_dualtimer_class_init, 510 }; 511 512 static void cmsdk_apb_dualtimer_register_types(void) 513 { 514 type_register_static(&cmsdk_apb_dualtimer_info); 515 } 516 517 type_init(cmsdk_apb_dualtimer_register_types); 518