1 /* 2 * Arm SSE Subsystem System Counter 3 * 4 * Copyright (c) 2020 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 "System counter" which is documented in 14 * the Arm SSE-123 Example Subsystem Technical Reference Manual: 15 * https://developer.arm.com/documentation/101370/latest/ 16 * 17 * The system counter is a non-stop 64-bit up-counter. It provides 18 * this count value to other devices like the SSE system timer, 19 * which are driven by this system timestamp rather than directly 20 * from a clock. Internally to the counter the count is actually 21 * 88-bit precision (64.24 fixed point), with a programmable scale factor. 22 * 23 * The hardware has the optional feature that it supports dynamic 24 * clock switching, where two clock inputs are connected, and which 25 * one is used is selected via a CLKSEL input signal. Since the 26 * users of this device in QEMU don't use this feature, we only model 27 * the HWCLKSW=0 configuration. 28 */ 29 #include "qemu/osdep.h" 30 #include "qemu/log.h" 31 #include "qemu/timer.h" 32 #include "qapi/error.h" 33 #include "trace.h" 34 #include "hw/timer/sse-counter.h" 35 #include "hw/sysbus.h" 36 #include "hw/irq.h" 37 #include "hw/registerfields.h" 38 #include "hw/clock.h" 39 #include "hw/qdev-clock.h" 40 #include "migration/vmstate.h" 41 42 /* Registers in the control frame */ 43 REG32(CNTCR, 0x0) 44 FIELD(CNTCR, EN, 0, 1) 45 FIELD(CNTCR, HDBG, 1, 1) 46 FIELD(CNTCR, SCEN, 2, 1) 47 FIELD(CNTCR, INTRMASK, 3, 1) 48 FIELD(CNTCR, PSLVERRDIS, 4, 1) 49 FIELD(CNTCR, INTRCLR, 5, 1) 50 /* 51 * Although CNTCR defines interrupt-related bits, the counter doesn't 52 * appear to actually have an interrupt output. So INTRCLR is 53 * effectively a RAZ/WI bit, as are the reserved bits [31:6]. 54 */ 55 #define CNTCR_VALID_MASK (R_CNTCR_EN_MASK | R_CNTCR_HDBG_MASK | \ 56 R_CNTCR_SCEN_MASK | R_CNTCR_INTRMASK_MASK | \ 57 R_CNTCR_PSLVERRDIS_MASK) 58 REG32(CNTSR, 0x4) 59 REG32(CNTCV_LO, 0x8) 60 REG32(CNTCV_HI, 0xc) 61 REG32(CNTSCR, 0x10) /* Aliased with CNTSCR0 */ 62 REG32(CNTID, 0x1c) 63 FIELD(CNTID, CNTSC, 0, 4) 64 FIELD(CNTID, CNTCS, 16, 1) 65 FIELD(CNTID, CNTSELCLK, 17, 2) 66 FIELD(CNTID, CNTSCR_OVR, 19, 1) 67 REG32(CNTSCR0, 0xd0) 68 REG32(CNTSCR1, 0xd4) 69 70 /* Registers in the status frame */ 71 REG32(STATUS_CNTCV_LO, 0x0) 72 REG32(STATUS_CNTCV_HI, 0x4) 73 74 /* Standard ID registers, present in both frames */ 75 REG32(PID4, 0xFD0) 76 REG32(PID5, 0xFD4) 77 REG32(PID6, 0xFD8) 78 REG32(PID7, 0xFDC) 79 REG32(PID0, 0xFE0) 80 REG32(PID1, 0xFE4) 81 REG32(PID2, 0xFE8) 82 REG32(PID3, 0xFEC) 83 REG32(CID0, 0xFF0) 84 REG32(CID1, 0xFF4) 85 REG32(CID2, 0xFF8) 86 REG32(CID3, 0xFFC) 87 88 /* PID/CID values */ 89 static const int control_id[] = { 90 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ 91 0xba, 0xb0, 0x0b, 0x00, /* PID0..PID3 */ 92 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ 93 }; 94 95 static const int status_id[] = { 96 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */ 97 0xbb, 0xb0, 0x0b, 0x00, /* PID0..PID3 */ 98 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */ 99 }; 100 101 static void sse_counter_notify_users(SSECounter *s) 102 { 103 /* 104 * Notify users of the count timestamp that they may 105 * need to recalculate. 106 */ 107 notifier_list_notify(&s->notifier_list, NULL); 108 } 109 110 static bool sse_counter_enabled(SSECounter *s) 111 { 112 return (s->cntcr & R_CNTCR_EN_MASK) != 0; 113 } 114 115 uint64_t sse_counter_tick_to_time(SSECounter *s, uint64_t tick) 116 { 117 if (!sse_counter_enabled(s)) { 118 return UINT64_MAX; 119 } 120 121 tick -= s->ticks_then; 122 123 if (s->cntcr & R_CNTCR_SCEN_MASK) { 124 /* Adjust the tick count to account for the scale factor */ 125 tick = muldiv64(tick, 0x01000000, s->cntscr0); 126 } 127 128 return s->ns_then + clock_ticks_to_ns(s->clk, tick); 129 } 130 131 void sse_counter_register_consumer(SSECounter *s, Notifier *notifier) 132 { 133 /* 134 * For the moment we assume that both we and the devices 135 * which consume us last for the life of the simulation, 136 * and so there is no mechanism for removing a notifier. 137 */ 138 notifier_list_add(&s->notifier_list, notifier); 139 } 140 141 uint64_t sse_counter_for_timestamp(SSECounter *s, uint64_t now) 142 { 143 /* Return the CNTCV value for a particular timestamp (clock ns value). */ 144 uint64_t ticks; 145 146 if (!sse_counter_enabled(s)) { 147 /* Counter is disabled and does not increment */ 148 return s->ticks_then; 149 } 150 151 ticks = clock_ns_to_ticks(s->clk, now - s->ns_then); 152 if (s->cntcr & R_CNTCR_SCEN_MASK) { 153 /* 154 * Scaling is enabled. The CNTSCR value is the amount added to 155 * the underlying 88-bit counter for every tick of the 156 * underlying clock; CNTCV is the top 64 bits of that full 157 * 88-bit value. Multiplying the tick count by CNTSCR tells us 158 * how much the full 88-bit counter has moved on; we then 159 * divide that by 0x01000000 to find out how much the 64-bit 160 * visible portion has advanced. muldiv64() gives us the 161 * necessary at-least-88-bit precision for the intermediate 162 * result. 163 */ 164 ticks = muldiv64(ticks, s->cntscr0, 0x01000000); 165 } 166 return s->ticks_then + ticks; 167 } 168 169 static uint64_t sse_cntcv(SSECounter *s) 170 { 171 /* Return the CNTCV value for the current time */ 172 return sse_counter_for_timestamp(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); 173 } 174 175 static void sse_write_cntcv(SSECounter *s, uint32_t value, unsigned startbit) 176 { 177 /* 178 * Write one 32-bit half of the counter value; startbit is the 179 * bit position of this half in the 64-bit word, either 0 or 32. 180 */ 181 uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 182 uint64_t cntcv = sse_counter_for_timestamp(s, now); 183 184 cntcv = deposit64(cntcv, startbit, 32, value); 185 s->ticks_then = cntcv; 186 s->ns_then = now; 187 sse_counter_notify_users(s); 188 } 189 190 static uint64_t sse_counter_control_read(void *opaque, hwaddr offset, 191 unsigned size) 192 { 193 SSECounter *s = SSE_COUNTER(opaque); 194 uint64_t r; 195 196 switch (offset) { 197 case A_CNTCR: 198 r = s->cntcr; 199 break; 200 case A_CNTSR: 201 /* 202 * The only bit here is DBGH, indicating that the counter has been 203 * halted via the Halt-on-Debug signal. We don't implement halting 204 * debug, so the whole register always reads as zero. 205 */ 206 r = 0; 207 break; 208 case A_CNTCV_LO: 209 r = extract64(sse_cntcv(s), 0, 32); 210 break; 211 case A_CNTCV_HI: 212 r = extract64(sse_cntcv(s), 32, 32); 213 break; 214 case A_CNTID: 215 /* 216 * For our implementation: 217 * - CNTSCR can only be written when CNTCR.EN == 0 218 * - HWCLKSW=0, so selected clock is always CLK0 219 * - counter scaling is implemented 220 */ 221 r = (1 << R_CNTID_CNTSELCLK_SHIFT) | (1 << R_CNTID_CNTSC_SHIFT); 222 break; 223 case A_CNTSCR: 224 case A_CNTSCR0: 225 r = s->cntscr0; 226 break; 227 case A_CNTSCR1: 228 /* If HWCLKSW == 0, CNTSCR1 is RAZ/WI */ 229 r = 0; 230 break; 231 case A_PID4 ... A_CID3: 232 r = control_id[(offset - A_PID4) / 4]; 233 break; 234 default: 235 qemu_log_mask(LOG_GUEST_ERROR, 236 "SSE System Counter control frame read: bad offset 0x%x", 237 (unsigned)offset); 238 r = 0; 239 break; 240 } 241 242 trace_sse_counter_control_read(offset, r, size); 243 return r; 244 } 245 246 static void sse_counter_control_write(void *opaque, hwaddr offset, 247 uint64_t value, unsigned size) 248 { 249 SSECounter *s = SSE_COUNTER(opaque); 250 251 trace_sse_counter_control_write(offset, value, size); 252 253 switch (offset) { 254 case A_CNTCR: 255 /* 256 * Although CNTCR defines interrupt-related bits, the counter doesn't 257 * appear to actually have an interrupt output. So INTRCLR is 258 * effectively a RAZ/WI bit, as are the reserved bits [31:6]. 259 * The documentation does not explicitly say so, but we assume 260 * that changing the scale factor while the counter is enabled 261 * by toggling CNTCR.SCEN has the same behaviour (making the counter 262 * value UNKNOWN) as changing it by writing to CNTSCR, and so we 263 * don't need to try to recalculate for that case. 264 */ 265 value &= CNTCR_VALID_MASK; 266 if ((value ^ s->cntcr) & R_CNTCR_EN_MASK) { 267 /* 268 * Whether the counter is being enabled or disabled, the 269 * required action is the same: sync the (ns_then, ticks_then) 270 * tuple. 271 */ 272 uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 273 s->ticks_then = sse_counter_for_timestamp(s, now); 274 s->ns_then = now; 275 sse_counter_notify_users(s); 276 } 277 s->cntcr = value; 278 break; 279 case A_CNTCV_LO: 280 sse_write_cntcv(s, value, 0); 281 break; 282 case A_CNTCV_HI: 283 sse_write_cntcv(s, value, 32); 284 break; 285 case A_CNTSCR: 286 case A_CNTSCR0: 287 /* 288 * If the scale registers are changed when the counter is enabled, 289 * the count value becomes UNKNOWN. So we don't try to recalculate 290 * anything here but only do it on a write to CNTCR.EN. 291 */ 292 s->cntscr0 = value; 293 break; 294 case A_CNTSCR1: 295 /* If HWCLKSW == 0, CNTSCR1 is RAZ/WI */ 296 break; 297 case A_CNTSR: 298 case A_CNTID: 299 case A_PID4 ... A_CID3: 300 qemu_log_mask(LOG_GUEST_ERROR, 301 "SSE System Counter control frame: write to RO offset 0x%x\n", 302 (unsigned)offset); 303 break; 304 default: 305 qemu_log_mask(LOG_GUEST_ERROR, 306 "SSE System Counter control frame: write to bad offset 0x%x\n", 307 (unsigned)offset); 308 break; 309 } 310 } 311 312 static uint64_t sse_counter_status_read(void *opaque, hwaddr offset, 313 unsigned size) 314 { 315 SSECounter *s = SSE_COUNTER(opaque); 316 uint64_t r; 317 318 switch (offset) { 319 case A_STATUS_CNTCV_LO: 320 r = extract64(sse_cntcv(s), 0, 32); 321 break; 322 case A_STATUS_CNTCV_HI: 323 r = extract64(sse_cntcv(s), 32, 32); 324 break; 325 case A_PID4 ... A_CID3: 326 r = status_id[(offset - A_PID4) / 4]; 327 break; 328 default: 329 qemu_log_mask(LOG_GUEST_ERROR, 330 "SSE System Counter status frame read: bad offset 0x%x", 331 (unsigned)offset); 332 r = 0; 333 break; 334 } 335 336 trace_sse_counter_status_read(offset, r, size); 337 return r; 338 } 339 340 static void sse_counter_status_write(void *opaque, hwaddr offset, 341 uint64_t value, unsigned size) 342 { 343 trace_sse_counter_status_write(offset, value, size); 344 345 switch (offset) { 346 case A_STATUS_CNTCV_LO: 347 case A_STATUS_CNTCV_HI: 348 case A_PID4 ... A_CID3: 349 qemu_log_mask(LOG_GUEST_ERROR, 350 "SSE System Counter status frame: write to RO offset 0x%x\n", 351 (unsigned)offset); 352 break; 353 default: 354 qemu_log_mask(LOG_GUEST_ERROR, 355 "SSE System Counter status frame: write to bad offset 0x%x\n", 356 (unsigned)offset); 357 break; 358 } 359 } 360 361 static const MemoryRegionOps sse_counter_control_ops = { 362 .read = sse_counter_control_read, 363 .write = sse_counter_control_write, 364 .endianness = DEVICE_LITTLE_ENDIAN, 365 .valid.min_access_size = 4, 366 .valid.max_access_size = 4, 367 }; 368 369 static const MemoryRegionOps sse_counter_status_ops = { 370 .read = sse_counter_status_read, 371 .write = sse_counter_status_write, 372 .endianness = DEVICE_LITTLE_ENDIAN, 373 .valid.min_access_size = 4, 374 .valid.max_access_size = 4, 375 }; 376 377 static void sse_counter_reset(DeviceState *dev) 378 { 379 SSECounter *s = SSE_COUNTER(dev); 380 381 trace_sse_counter_reset(); 382 383 s->cntcr = 0; 384 s->cntscr0 = 0x01000000; 385 s->ns_then = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 386 s->ticks_then = 0; 387 } 388 389 static void sse_clk_callback(void *opaque, ClockEvent event) 390 { 391 SSECounter *s = SSE_COUNTER(opaque); 392 uint64_t now; 393 394 switch (event) { 395 case ClockPreUpdate: 396 /* 397 * Before the clock period updates, set (ticks_then, ns_then) 398 * to the current time and tick count (as calculated with 399 * the old clock period). 400 */ 401 if (sse_counter_enabled(s)) { 402 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 403 s->ticks_then = sse_counter_for_timestamp(s, now); 404 s->ns_then = now; 405 } 406 break; 407 case ClockUpdate: 408 sse_counter_notify_users(s); 409 break; 410 default: 411 break; 412 } 413 } 414 415 static void sse_counter_init(Object *obj) 416 { 417 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 418 SSECounter *s = SSE_COUNTER(obj); 419 420 notifier_list_init(&s->notifier_list); 421 422 s->clk = qdev_init_clock_in(DEVICE(obj), "CLK", sse_clk_callback, s, 423 ClockPreUpdate | ClockUpdate); 424 memory_region_init_io(&s->control_mr, obj, &sse_counter_control_ops, 425 s, "sse-counter-control", 0x1000); 426 memory_region_init_io(&s->status_mr, obj, &sse_counter_status_ops, 427 s, "sse-counter-status", 0x1000); 428 sysbus_init_mmio(sbd, &s->control_mr); 429 sysbus_init_mmio(sbd, &s->status_mr); 430 } 431 432 static void sse_counter_realize(DeviceState *dev, Error **errp) 433 { 434 SSECounter *s = SSE_COUNTER(dev); 435 436 if (!clock_has_source(s->clk)) { 437 error_setg(errp, "SSE system counter: CLK must be connected"); 438 return; 439 } 440 } 441 442 static const VMStateDescription sse_counter_vmstate = { 443 .name = "sse-counter", 444 .version_id = 1, 445 .minimum_version_id = 1, 446 .fields = (VMStateField[]) { 447 VMSTATE_CLOCK(clk, SSECounter), 448 VMSTATE_END_OF_LIST() 449 } 450 }; 451 452 static void sse_counter_class_init(ObjectClass *klass, void *data) 453 { 454 DeviceClass *dc = DEVICE_CLASS(klass); 455 456 dc->realize = sse_counter_realize; 457 dc->vmsd = &sse_counter_vmstate; 458 dc->reset = sse_counter_reset; 459 } 460 461 static const TypeInfo sse_counter_info = { 462 .name = TYPE_SSE_COUNTER, 463 .parent = TYPE_SYS_BUS_DEVICE, 464 .instance_size = sizeof(SSECounter), 465 .instance_init = sse_counter_init, 466 .class_init = sse_counter_class_init, 467 }; 468 469 static void sse_counter_register_types(void) 470 { 471 type_register_static(&sse_counter_info); 472 } 473 474 type_init(sse_counter_register_types); 475