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 i, env->timecmp); 237 } 238 return; 239 } 240 241 qemu_log_mask(LOG_UNIMP, 242 "aclint-mtimer: invalid write: %08x", (uint32_t)addr); 243 } 244 245 static const MemoryRegionOps riscv_aclint_mtimer_ops = { 246 .read = riscv_aclint_mtimer_read, 247 .write = riscv_aclint_mtimer_write, 248 .endianness = DEVICE_LITTLE_ENDIAN, 249 .valid = { 250 .min_access_size = 4, 251 .max_access_size = 8 252 }, 253 .impl = { 254 .min_access_size = 4, 255 .max_access_size = 8, 256 } 257 }; 258 259 static Property riscv_aclint_mtimer_properties[] = { 260 DEFINE_PROP_UINT32("hartid-base", RISCVAclintMTimerState, 261 hartid_base, 0), 262 DEFINE_PROP_UINT32("num-harts", RISCVAclintMTimerState, num_harts, 1), 263 DEFINE_PROP_UINT32("timecmp-base", RISCVAclintMTimerState, 264 timecmp_base, RISCV_ACLINT_DEFAULT_MTIMECMP), 265 DEFINE_PROP_UINT32("time-base", RISCVAclintMTimerState, 266 time_base, RISCV_ACLINT_DEFAULT_MTIME), 267 DEFINE_PROP_UINT32("aperture-size", RISCVAclintMTimerState, 268 aperture_size, RISCV_ACLINT_DEFAULT_MTIMER_SIZE), 269 DEFINE_PROP_UINT32("timebase-freq", RISCVAclintMTimerState, 270 timebase_freq, 0), 271 DEFINE_PROP_END_OF_LIST(), 272 }; 273 274 static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp) 275 { 276 RISCVAclintMTimerState *s = RISCV_ACLINT_MTIMER(dev); 277 int i; 278 279 memory_region_init_io(&s->mmio, OBJECT(dev), &riscv_aclint_mtimer_ops, 280 s, TYPE_RISCV_ACLINT_MTIMER, s->aperture_size); 281 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); 282 283 s->timer_irqs = g_new(qemu_irq, s->num_harts); 284 qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts); 285 286 /* Claim timer interrupt bits */ 287 for (i = 0; i < s->num_harts; i++) { 288 RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i)); 289 if (riscv_cpu_claim_interrupts(cpu, MIP_MTIP) < 0) { 290 error_report("MTIP already claimed"); 291 exit(1); 292 } 293 } 294 } 295 296 static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type) 297 { 298 /* 299 * According to RISC-V ACLINT spec: 300 * - On MTIMER device reset, the MTIME register is cleared to zero. 301 * - On MTIMER device reset, the MTIMECMP registers are in unknown state. 302 */ 303 RISCVAclintMTimerState *mtimer = RISCV_ACLINT_MTIMER(obj); 304 305 /* 306 * Clear mtime register by writing to 0 it. 307 * Pending mtime interrupts will also be cleared at the same time. 308 */ 309 riscv_aclint_mtimer_write(mtimer, mtimer->time_base, 0, 8); 310 } 311 312 static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data) 313 { 314 DeviceClass *dc = DEVICE_CLASS(klass); 315 dc->realize = riscv_aclint_mtimer_realize; 316 device_class_set_props(dc, riscv_aclint_mtimer_properties); 317 ResettableClass *rc = RESETTABLE_CLASS(klass); 318 rc->phases.enter = riscv_aclint_mtimer_reset_enter; 319 } 320 321 static const TypeInfo riscv_aclint_mtimer_info = { 322 .name = TYPE_RISCV_ACLINT_MTIMER, 323 .parent = TYPE_SYS_BUS_DEVICE, 324 .instance_size = sizeof(RISCVAclintMTimerState), 325 .class_init = riscv_aclint_mtimer_class_init, 326 }; 327 328 /* 329 * Create ACLINT MTIMER device. 330 */ 331 DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size, 332 uint32_t hartid_base, uint32_t num_harts, 333 uint32_t timecmp_base, uint32_t time_base, uint32_t timebase_freq, 334 bool provide_rdtime) 335 { 336 int i; 337 DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_MTIMER); 338 339 assert(num_harts <= RISCV_ACLINT_MAX_HARTS); 340 assert(!(addr & 0x7)); 341 assert(!(timecmp_base & 0x7)); 342 assert(!(time_base & 0x7)); 343 344 qdev_prop_set_uint32(dev, "hartid-base", hartid_base); 345 qdev_prop_set_uint32(dev, "num-harts", num_harts); 346 qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base); 347 qdev_prop_set_uint32(dev, "time-base", time_base); 348 qdev_prop_set_uint32(dev, "aperture-size", size); 349 qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq); 350 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 351 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); 352 353 for (i = 0; i < num_harts; i++) { 354 CPUState *cpu = qemu_get_cpu(hartid_base + i); 355 RISCVCPU *rvcpu = RISCV_CPU(cpu); 356 CPURISCVState *env = cpu ? cpu->env_ptr : NULL; 357 riscv_aclint_mtimer_callback *cb = 358 g_new0(riscv_aclint_mtimer_callback, 1); 359 360 if (!env) { 361 g_free(cb); 362 continue; 363 } 364 if (provide_rdtime) { 365 riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, dev); 366 } 367 368 cb->s = RISCV_ACLINT_MTIMER(dev); 369 cb->num = i; 370 env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, 371 &riscv_aclint_mtimer_cb, cb); 372 env->timecmp = 0; 373 374 qdev_connect_gpio_out(dev, i, 375 qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER)); 376 } 377 378 return dev; 379 } 380 381 /* CPU read [M|S]SWI register */ 382 static uint64_t riscv_aclint_swi_read(void *opaque, hwaddr addr, 383 unsigned size) 384 { 385 RISCVAclintSwiState *swi = opaque; 386 387 if (addr < (swi->num_harts << 2)) { 388 size_t hartid = swi->hartid_base + (addr >> 2); 389 CPUState *cpu = qemu_get_cpu(hartid); 390 CPURISCVState *env = cpu ? cpu->env_ptr : NULL; 391 if (!env) { 392 qemu_log_mask(LOG_GUEST_ERROR, 393 "aclint-swi: invalid hartid: %zu", hartid); 394 } else if ((addr & 0x3) == 0) { 395 return (swi->sswi) ? 0 : ((env->mip & MIP_MSIP) > 0); 396 } 397 } 398 399 qemu_log_mask(LOG_UNIMP, 400 "aclint-swi: invalid read: %08x", (uint32_t)addr); 401 return 0; 402 } 403 404 /* CPU write [M|S]SWI register */ 405 static void riscv_aclint_swi_write(void *opaque, hwaddr addr, uint64_t value, 406 unsigned size) 407 { 408 RISCVAclintSwiState *swi = opaque; 409 410 if (addr < (swi->num_harts << 2)) { 411 size_t hartid = swi->hartid_base + (addr >> 2); 412 CPUState *cpu = qemu_get_cpu(hartid); 413 CPURISCVState *env = cpu ? cpu->env_ptr : NULL; 414 if (!env) { 415 qemu_log_mask(LOG_GUEST_ERROR, 416 "aclint-swi: invalid hartid: %zu", hartid); 417 } else if ((addr & 0x3) == 0) { 418 if (value & 0x1) { 419 qemu_irq_raise(swi->soft_irqs[hartid - swi->hartid_base]); 420 } else { 421 if (!swi->sswi) { 422 qemu_irq_lower(swi->soft_irqs[hartid - swi->hartid_base]); 423 } 424 } 425 return; 426 } 427 } 428 429 qemu_log_mask(LOG_UNIMP, 430 "aclint-swi: invalid write: %08x", (uint32_t)addr); 431 } 432 433 static const MemoryRegionOps riscv_aclint_swi_ops = { 434 .read = riscv_aclint_swi_read, 435 .write = riscv_aclint_swi_write, 436 .endianness = DEVICE_LITTLE_ENDIAN, 437 .valid = { 438 .min_access_size = 4, 439 .max_access_size = 4 440 } 441 }; 442 443 static Property riscv_aclint_swi_properties[] = { 444 DEFINE_PROP_UINT32("hartid-base", RISCVAclintSwiState, hartid_base, 0), 445 DEFINE_PROP_UINT32("num-harts", RISCVAclintSwiState, num_harts, 1), 446 DEFINE_PROP_UINT32("sswi", RISCVAclintSwiState, sswi, false), 447 DEFINE_PROP_END_OF_LIST(), 448 }; 449 450 static void riscv_aclint_swi_realize(DeviceState *dev, Error **errp) 451 { 452 RISCVAclintSwiState *swi = RISCV_ACLINT_SWI(dev); 453 int i; 454 455 memory_region_init_io(&swi->mmio, OBJECT(dev), &riscv_aclint_swi_ops, swi, 456 TYPE_RISCV_ACLINT_SWI, RISCV_ACLINT_SWI_SIZE); 457 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &swi->mmio); 458 459 swi->soft_irqs = g_new(qemu_irq, swi->num_harts); 460 qdev_init_gpio_out(dev, swi->soft_irqs, swi->num_harts); 461 462 /* Claim software interrupt bits */ 463 for (i = 0; i < swi->num_harts; i++) { 464 RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(swi->hartid_base + i)); 465 /* We don't claim mip.SSIP because it is writeable by software */ 466 if (riscv_cpu_claim_interrupts(cpu, swi->sswi ? 0 : MIP_MSIP) < 0) { 467 error_report("MSIP already claimed"); 468 exit(1); 469 } 470 } 471 } 472 473 static void riscv_aclint_swi_reset_enter(Object *obj, ResetType type) 474 { 475 /* 476 * According to RISC-V ACLINT spec: 477 * - On MSWI device reset, each MSIP register is cleared to zero. 478 * 479 * p.s. SSWI device reset does nothing since SETSIP register always reads 0. 480 */ 481 RISCVAclintSwiState *swi = RISCV_ACLINT_SWI(obj); 482 int i; 483 484 if (!swi->sswi) { 485 for (i = 0; i < swi->num_harts; i++) { 486 /* Clear MSIP registers by lowering software interrupts. */ 487 qemu_irq_lower(swi->soft_irqs[i]); 488 } 489 } 490 } 491 492 static void riscv_aclint_swi_class_init(ObjectClass *klass, void *data) 493 { 494 DeviceClass *dc = DEVICE_CLASS(klass); 495 dc->realize = riscv_aclint_swi_realize; 496 device_class_set_props(dc, riscv_aclint_swi_properties); 497 ResettableClass *rc = RESETTABLE_CLASS(klass); 498 rc->phases.enter = riscv_aclint_swi_reset_enter; 499 } 500 501 static const TypeInfo riscv_aclint_swi_info = { 502 .name = TYPE_RISCV_ACLINT_SWI, 503 .parent = TYPE_SYS_BUS_DEVICE, 504 .instance_size = sizeof(RISCVAclintSwiState), 505 .class_init = riscv_aclint_swi_class_init, 506 }; 507 508 /* 509 * Create ACLINT [M|S]SWI device. 510 */ 511 DeviceState *riscv_aclint_swi_create(hwaddr addr, uint32_t hartid_base, 512 uint32_t num_harts, bool sswi) 513 { 514 int i; 515 DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_SWI); 516 517 assert(num_harts <= RISCV_ACLINT_MAX_HARTS); 518 assert(!(addr & 0x3)); 519 520 qdev_prop_set_uint32(dev, "hartid-base", hartid_base); 521 qdev_prop_set_uint32(dev, "num-harts", num_harts); 522 qdev_prop_set_uint32(dev, "sswi", sswi ? true : false); 523 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 524 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); 525 526 for (i = 0; i < num_harts; i++) { 527 CPUState *cpu = qemu_get_cpu(hartid_base + i); 528 RISCVCPU *rvcpu = RISCV_CPU(cpu); 529 530 qdev_connect_gpio_out(dev, i, 531 qdev_get_gpio_in(DEVICE(rvcpu), 532 (sswi) ? IRQ_S_SOFT : IRQ_M_SOFT)); 533 } 534 535 return dev; 536 } 537 538 static void riscv_aclint_register_types(void) 539 { 540 type_register_static(&riscv_aclint_mtimer_info); 541 type_register_static(&riscv_aclint_swi_info); 542 } 543 544 type_init(riscv_aclint_register_types) 545