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