1 /* 2 * RISC-V ACLINT (Advanced Core Local Interruptor) 3 * URL: https://github.com/riscv/riscv-aclint 4 * 5 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu 6 * Copyright (c) 2017 SiFive, Inc. 7 * Copyright (c) 2021 Western Digital Corporation or its affiliates. 8 * 9 * This provides real-time clock, timer and interprocessor interrupts. 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms and conditions of the GNU General Public License, 13 * version 2 or later, as published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope it will be useful, but WITHOUT 16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 * more details. 19 * 20 * You should have received a copy of the GNU General Public License along with 21 * this program. If not, see <http://www.gnu.org/licenses/>. 22 */ 23 24 #include "qemu/osdep.h" 25 #include "qapi/error.h" 26 #include "qemu/error-report.h" 27 #include "qemu/log.h" 28 #include "qemu/module.h" 29 #include "hw/sysbus.h" 30 #include "target/riscv/cpu.h" 31 #include "hw/qdev-properties.h" 32 #include "hw/intc/riscv_aclint.h" 33 #include "qemu/timer.h" 34 #include "hw/irq.h" 35 36 typedef struct riscv_aclint_mtimer_callback { 37 RISCVAclintMTimerState *s; 38 int num; 39 } riscv_aclint_mtimer_callback; 40 41 static uint64_t cpu_riscv_read_rtc_raw(uint32_t timebase_freq) 42 { 43 return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 44 timebase_freq, NANOSECONDS_PER_SECOND); 45 } 46 47 static uint64_t cpu_riscv_read_rtc(void *opaque) 48 { 49 RISCVAclintMTimerState *mtimer = opaque; 50 return cpu_riscv_read_rtc_raw(mtimer->timebase_freq) + mtimer->time_delta; 51 } 52 53 /* 54 * Called when timecmp is written to update the QEMU timer or immediately 55 * trigger timer interrupt if mtimecmp <= current timer value. 56 */ 57 static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer, 58 RISCVCPU *cpu, 59 int hartid, 60 uint64_t value) 61 { 62 uint32_t timebase_freq = mtimer->timebase_freq; 63 uint64_t next; 64 uint64_t diff; 65 66 uint64_t rtc_r = cpu_riscv_read_rtc(mtimer); 67 68 cpu->env.timecmp = value; 69 if (cpu->env.timecmp <= rtc_r) { 70 /* 71 * If we're setting an MTIMECMP value in the "past", 72 * immediately raise the timer interrupt 73 */ 74 qemu_irq_raise(mtimer->timer_irqs[hartid - mtimer->hartid_base]); 75 return; 76 } 77 78 /* otherwise, set up the future timer interrupt */ 79 qemu_irq_lower(mtimer->timer_irqs[hartid - mtimer->hartid_base]); 80 diff = cpu->env.timecmp - rtc_r; 81 /* back to ns (note args switched in muldiv64) */ 82 uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); 83 84 /* 85 * check if ns_diff overflowed and check if the addition would potentially 86 * overflow 87 */ 88 if ((NANOSECONDS_PER_SECOND > timebase_freq && ns_diff < diff) || 89 ns_diff > INT64_MAX) { 90 next = INT64_MAX; 91 } else { 92 /* 93 * as it is very unlikely qemu_clock_get_ns will return a value 94 * greater than INT64_MAX, no additional check is needed for an 95 * unsigned integer overflow. 96 */ 97 next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns_diff; 98 /* 99 * if ns_diff is INT64_MAX next may still be outside the range 100 * of a signed integer. 101 */ 102 next = MIN(next, INT64_MAX); 103 } 104 105 timer_mod(cpu->env.timer, next); 106 } 107 108 /* 109 * Callback used when the timer set using timer_mod expires. 110 * Should raise the timer interrupt line 111 */ 112 static void riscv_aclint_mtimer_cb(void *opaque) 113 { 114 riscv_aclint_mtimer_callback *state = opaque; 115 116 qemu_irq_raise(state->s->timer_irqs[state->num]); 117 } 118 119 /* CPU read MTIMER register */ 120 static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr, 121 unsigned size) 122 { 123 RISCVAclintMTimerState *mtimer = opaque; 124 125 if (addr >= mtimer->timecmp_base && 126 addr < (mtimer->timecmp_base + (mtimer->num_harts << 3))) { 127 size_t hartid = mtimer->hartid_base + 128 ((addr - mtimer->timecmp_base) >> 3); 129 CPUState *cpu = qemu_get_cpu(hartid); 130 CPURISCVState *env = cpu ? cpu->env_ptr : NULL; 131 if (!env) { 132 qemu_log_mask(LOG_GUEST_ERROR, 133 "aclint-mtimer: invalid hartid: %zu", hartid); 134 } else if ((addr & 0x7) == 0) { 135 /* timecmp_lo for RV32/RV64 or timecmp for RV64 */ 136 uint64_t timecmp = env->timecmp; 137 return (size == 4) ? (timecmp & 0xFFFFFFFF) : timecmp; 138 } else if ((addr & 0x7) == 4) { 139 /* timecmp_hi */ 140 uint64_t timecmp = env->timecmp; 141 return (timecmp >> 32) & 0xFFFFFFFF; 142 } else { 143 qemu_log_mask(LOG_UNIMP, 144 "aclint-mtimer: invalid read: %08x", (uint32_t)addr); 145 return 0; 146 } 147 } else if (addr == mtimer->time_base) { 148 /* time_lo for RV32/RV64 or timecmp for RV64 */ 149 uint64_t rtc = cpu_riscv_read_rtc(mtimer); 150 return (size == 4) ? (rtc & 0xFFFFFFFF) : rtc; 151 } else if (addr == mtimer->time_base + 4) { 152 /* time_hi */ 153 return (cpu_riscv_read_rtc(mtimer) >> 32) & 0xFFFFFFFF; 154 } 155 156 qemu_log_mask(LOG_UNIMP, 157 "aclint-mtimer: invalid read: %08x", (uint32_t)addr); 158 return 0; 159 } 160 161 /* CPU write MTIMER register */ 162 static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, 163 uint64_t value, unsigned size) 164 { 165 RISCVAclintMTimerState *mtimer = opaque; 166 int i; 167 168 if (addr >= mtimer->timecmp_base && 169 addr < (mtimer->timecmp_base + (mtimer->num_harts << 3))) { 170 size_t hartid = mtimer->hartid_base + 171 ((addr - mtimer->timecmp_base) >> 3); 172 CPUState *cpu = qemu_get_cpu(hartid); 173 CPURISCVState *env = cpu ? cpu->env_ptr : NULL; 174 if (!env) { 175 qemu_log_mask(LOG_GUEST_ERROR, 176 "aclint-mtimer: invalid hartid: %zu", hartid); 177 } else if ((addr & 0x7) == 0) { 178 if (size == 4) { 179 /* timecmp_lo for RV32/RV64 */ 180 uint64_t timecmp_hi = env->timecmp >> 32; 181 riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, 182 timecmp_hi << 32 | (value & 0xFFFFFFFF)); 183 } else { 184 /* timecmp for RV64 */ 185 riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, 186 value); 187 } 188 } else if ((addr & 0x7) == 4) { 189 if (size == 4) { 190 /* timecmp_hi for RV32/RV64 */ 191 uint64_t timecmp_lo = env->timecmp; 192 riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, 193 value << 32 | (timecmp_lo & 0xFFFFFFFF)); 194 } else { 195 qemu_log_mask(LOG_GUEST_ERROR, 196 "aclint-mtimer: invalid timecmp_hi write: %08x", 197 (uint32_t)addr); 198 } 199 } else { 200 qemu_log_mask(LOG_UNIMP, 201 "aclint-mtimer: invalid timecmp write: %08x", 202 (uint32_t)addr); 203 } 204 return; 205 } else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) { 206 uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq); 207 208 if (addr == mtimer->time_base) { 209 if (size == 4) { 210 /* time_lo for RV32/RV64 */ 211 mtimer->time_delta = ((rtc_r & ~0xFFFFFFFFULL) | value) - rtc_r; 212 } else { 213 /* time for RV64 */ 214 mtimer->time_delta = value - rtc_r; 215 } 216 } else { 217 if (size == 4) { 218 /* time_hi for RV32/RV64 */ 219 mtimer->time_delta = (value << 32 | (rtc_r & 0xFFFFFFFF)) - rtc_r; 220 } else { 221 qemu_log_mask(LOG_GUEST_ERROR, 222 "aclint-mtimer: invalid time_hi write: %08x", 223 (uint32_t)addr); 224 return; 225 } 226 } 227 228 /* Check if timer interrupt is triggered for each hart. */ 229 for (i = 0; i < mtimer->num_harts; i++) { 230 CPUState *cpu = qemu_get_cpu(mtimer->hartid_base + i); 231 CPURISCVState *env = cpu ? cpu->env_ptr : NULL; 232 if (!env) { 233 continue; 234 } 235 riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), 236 mtimer->hartid_base + i, 237 env->timecmp); 238 } 239 return; 240 } 241 242 qemu_log_mask(LOG_UNIMP, 243 "aclint-mtimer: invalid write: %08x", (uint32_t)addr); 244 } 245 246 static const MemoryRegionOps riscv_aclint_mtimer_ops = { 247 .read = riscv_aclint_mtimer_read, 248 .write = riscv_aclint_mtimer_write, 249 .endianness = DEVICE_LITTLE_ENDIAN, 250 .valid = { 251 .min_access_size = 4, 252 .max_access_size = 8 253 }, 254 .impl = { 255 .min_access_size = 4, 256 .max_access_size = 8, 257 } 258 }; 259 260 static Property riscv_aclint_mtimer_properties[] = { 261 DEFINE_PROP_UINT32("hartid-base", RISCVAclintMTimerState, 262 hartid_base, 0), 263 DEFINE_PROP_UINT32("num-harts", RISCVAclintMTimerState, num_harts, 1), 264 DEFINE_PROP_UINT32("timecmp-base", RISCVAclintMTimerState, 265 timecmp_base, RISCV_ACLINT_DEFAULT_MTIMECMP), 266 DEFINE_PROP_UINT32("time-base", RISCVAclintMTimerState, 267 time_base, RISCV_ACLINT_DEFAULT_MTIME), 268 DEFINE_PROP_UINT32("aperture-size", RISCVAclintMTimerState, 269 aperture_size, RISCV_ACLINT_DEFAULT_MTIMER_SIZE), 270 DEFINE_PROP_UINT32("timebase-freq", RISCVAclintMTimerState, 271 timebase_freq, 0), 272 DEFINE_PROP_END_OF_LIST(), 273 }; 274 275 static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp) 276 { 277 RISCVAclintMTimerState *s = RISCV_ACLINT_MTIMER(dev); 278 int i; 279 280 memory_region_init_io(&s->mmio, OBJECT(dev), &riscv_aclint_mtimer_ops, 281 s, TYPE_RISCV_ACLINT_MTIMER, s->aperture_size); 282 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); 283 284 s->timer_irqs = g_new(qemu_irq, s->num_harts); 285 qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts); 286 287 /* Claim timer interrupt bits */ 288 for (i = 0; i < s->num_harts; i++) { 289 RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i)); 290 if (riscv_cpu_claim_interrupts(cpu, MIP_MTIP) < 0) { 291 error_report("MTIP already claimed"); 292 exit(1); 293 } 294 } 295 } 296 297 static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type) 298 { 299 /* 300 * According to RISC-V ACLINT spec: 301 * - On MTIMER device reset, the MTIME register is cleared to zero. 302 * - On MTIMER device reset, the MTIMECMP registers are in unknown state. 303 */ 304 RISCVAclintMTimerState *mtimer = RISCV_ACLINT_MTIMER(obj); 305 306 /* 307 * Clear mtime register by writing to 0 it. 308 * Pending mtime interrupts will also be cleared at the same time. 309 */ 310 riscv_aclint_mtimer_write(mtimer, mtimer->time_base, 0, 8); 311 } 312 313 static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data) 314 { 315 DeviceClass *dc = DEVICE_CLASS(klass); 316 dc->realize = riscv_aclint_mtimer_realize; 317 device_class_set_props(dc, riscv_aclint_mtimer_properties); 318 ResettableClass *rc = RESETTABLE_CLASS(klass); 319 rc->phases.enter = riscv_aclint_mtimer_reset_enter; 320 } 321 322 static const TypeInfo riscv_aclint_mtimer_info = { 323 .name = TYPE_RISCV_ACLINT_MTIMER, 324 .parent = TYPE_SYS_BUS_DEVICE, 325 .instance_size = sizeof(RISCVAclintMTimerState), 326 .class_init = riscv_aclint_mtimer_class_init, 327 }; 328 329 /* 330 * Create ACLINT MTIMER device. 331 */ 332 DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size, 333 uint32_t hartid_base, uint32_t num_harts, 334 uint32_t timecmp_base, uint32_t time_base, uint32_t timebase_freq, 335 bool provide_rdtime) 336 { 337 int i; 338 DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_MTIMER); 339 340 assert(num_harts <= RISCV_ACLINT_MAX_HARTS); 341 assert(!(addr & 0x7)); 342 assert(!(timecmp_base & 0x7)); 343 assert(!(time_base & 0x7)); 344 345 qdev_prop_set_uint32(dev, "hartid-base", hartid_base); 346 qdev_prop_set_uint32(dev, "num-harts", num_harts); 347 qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base); 348 qdev_prop_set_uint32(dev, "time-base", time_base); 349 qdev_prop_set_uint32(dev, "aperture-size", size); 350 qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq); 351 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 352 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); 353 354 for (i = 0; i < num_harts; i++) { 355 CPUState *cpu = qemu_get_cpu(hartid_base + i); 356 RISCVCPU *rvcpu = RISCV_CPU(cpu); 357 CPURISCVState *env = cpu ? cpu->env_ptr : NULL; 358 riscv_aclint_mtimer_callback *cb = 359 g_new0(riscv_aclint_mtimer_callback, 1); 360 361 if (!env) { 362 g_free(cb); 363 continue; 364 } 365 if (provide_rdtime) { 366 riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, dev); 367 } 368 369 cb->s = RISCV_ACLINT_MTIMER(dev); 370 cb->num = i; 371 env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 372 &riscv_aclint_mtimer_cb, cb); 373 env->timecmp = 0; 374 375 qdev_connect_gpio_out(dev, i, 376 qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER)); 377 } 378 379 return dev; 380 } 381 382 /* CPU read [M|S]SWI register */ 383 static uint64_t riscv_aclint_swi_read(void *opaque, hwaddr addr, 384 unsigned size) 385 { 386 RISCVAclintSwiState *swi = opaque; 387 388 if (addr < (swi->num_harts << 2)) { 389 size_t hartid = swi->hartid_base + (addr >> 2); 390 CPUState *cpu = qemu_get_cpu(hartid); 391 CPURISCVState *env = cpu ? cpu->env_ptr : NULL; 392 if (!env) { 393 qemu_log_mask(LOG_GUEST_ERROR, 394 "aclint-swi: invalid hartid: %zu", hartid); 395 } else if ((addr & 0x3) == 0) { 396 return (swi->sswi) ? 0 : ((env->mip & MIP_MSIP) > 0); 397 } 398 } 399 400 qemu_log_mask(LOG_UNIMP, 401 "aclint-swi: invalid read: %08x", (uint32_t)addr); 402 return 0; 403 } 404 405 /* CPU write [M|S]SWI register */ 406 static void riscv_aclint_swi_write(void *opaque, hwaddr addr, uint64_t value, 407 unsigned size) 408 { 409 RISCVAclintSwiState *swi = opaque; 410 411 if (addr < (swi->num_harts << 2)) { 412 size_t hartid = swi->hartid_base + (addr >> 2); 413 CPUState *cpu = qemu_get_cpu(hartid); 414 CPURISCVState *env = cpu ? cpu->env_ptr : NULL; 415 if (!env) { 416 qemu_log_mask(LOG_GUEST_ERROR, 417 "aclint-swi: invalid hartid: %zu", hartid); 418 } else if ((addr & 0x3) == 0) { 419 if (value & 0x1) { 420 qemu_irq_raise(swi->soft_irqs[hartid - swi->hartid_base]); 421 } else { 422 if (!swi->sswi) { 423 qemu_irq_lower(swi->soft_irqs[hartid - swi->hartid_base]); 424 } 425 } 426 return; 427 } 428 } 429 430 qemu_log_mask(LOG_UNIMP, 431 "aclint-swi: invalid write: %08x", (uint32_t)addr); 432 } 433 434 static const MemoryRegionOps riscv_aclint_swi_ops = { 435 .read = riscv_aclint_swi_read, 436 .write = riscv_aclint_swi_write, 437 .endianness = DEVICE_LITTLE_ENDIAN, 438 .valid = { 439 .min_access_size = 4, 440 .max_access_size = 4 441 } 442 }; 443 444 static Property riscv_aclint_swi_properties[] = { 445 DEFINE_PROP_UINT32("hartid-base", RISCVAclintSwiState, hartid_base, 0), 446 DEFINE_PROP_UINT32("num-harts", RISCVAclintSwiState, num_harts, 1), 447 DEFINE_PROP_UINT32("sswi", RISCVAclintSwiState, sswi, false), 448 DEFINE_PROP_END_OF_LIST(), 449 }; 450 451 static void riscv_aclint_swi_realize(DeviceState *dev, Error **errp) 452 { 453 RISCVAclintSwiState *swi = RISCV_ACLINT_SWI(dev); 454 int i; 455 456 memory_region_init_io(&swi->mmio, OBJECT(dev), &riscv_aclint_swi_ops, swi, 457 TYPE_RISCV_ACLINT_SWI, RISCV_ACLINT_SWI_SIZE); 458 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &swi->mmio); 459 460 swi->soft_irqs = g_new(qemu_irq, swi->num_harts); 461 qdev_init_gpio_out(dev, swi->soft_irqs, swi->num_harts); 462 463 /* Claim software interrupt bits */ 464 for (i = 0; i < swi->num_harts; i++) { 465 RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(swi->hartid_base + i)); 466 /* We don't claim mip.SSIP because it is writeable by software */ 467 if (riscv_cpu_claim_interrupts(cpu, swi->sswi ? 0 : MIP_MSIP) < 0) { 468 error_report("MSIP already claimed"); 469 exit(1); 470 } 471 } 472 } 473 474 static void riscv_aclint_swi_reset_enter(Object *obj, ResetType type) 475 { 476 /* 477 * According to RISC-V ACLINT spec: 478 * - On MSWI device reset, each MSIP register is cleared to zero. 479 * 480 * p.s. SSWI device reset does nothing since SETSIP register always reads 0. 481 */ 482 RISCVAclintSwiState *swi = RISCV_ACLINT_SWI(obj); 483 int i; 484 485 if (!swi->sswi) { 486 for (i = 0; i < swi->num_harts; i++) { 487 /* Clear MSIP registers by lowering software interrupts. */ 488 qemu_irq_lower(swi->soft_irqs[i]); 489 } 490 } 491 } 492 493 static void riscv_aclint_swi_class_init(ObjectClass *klass, void *data) 494 { 495 DeviceClass *dc = DEVICE_CLASS(klass); 496 dc->realize = riscv_aclint_swi_realize; 497 device_class_set_props(dc, riscv_aclint_swi_properties); 498 ResettableClass *rc = RESETTABLE_CLASS(klass); 499 rc->phases.enter = riscv_aclint_swi_reset_enter; 500 } 501 502 static const TypeInfo riscv_aclint_swi_info = { 503 .name = TYPE_RISCV_ACLINT_SWI, 504 .parent = TYPE_SYS_BUS_DEVICE, 505 .instance_size = sizeof(RISCVAclintSwiState), 506 .class_init = riscv_aclint_swi_class_init, 507 }; 508 509 /* 510 * Create ACLINT [M|S]SWI device. 511 */ 512 DeviceState *riscv_aclint_swi_create(hwaddr addr, uint32_t hartid_base, 513 uint32_t num_harts, bool sswi) 514 { 515 int i; 516 DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_SWI); 517 518 assert(num_harts <= RISCV_ACLINT_MAX_HARTS); 519 assert(!(addr & 0x3)); 520 521 qdev_prop_set_uint32(dev, "hartid-base", hartid_base); 522 qdev_prop_set_uint32(dev, "num-harts", num_harts); 523 qdev_prop_set_uint32(dev, "sswi", sswi ? true : false); 524 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 525 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); 526 527 for (i = 0; i < num_harts; i++) { 528 CPUState *cpu = qemu_get_cpu(hartid_base + i); 529 RISCVCPU *rvcpu = RISCV_CPU(cpu); 530 531 qdev_connect_gpio_out(dev, i, 532 qdev_get_gpio_in(DEVICE(rvcpu), 533 (sswi) ? IRQ_S_SOFT : IRQ_M_SOFT)); 534 } 535 536 return dev; 537 } 538 539 static void riscv_aclint_register_types(void) 540 { 541 type_register_static(&riscv_aclint_mtimer_info); 542 type_register_static(&riscv_aclint_swi_info); 543 } 544 545 type_init(riscv_aclint_register_types) 546