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