| 1 | /* |
| 2 | * RISC-V ACLINT (Advanced Core Local Interruptor) interface |
| 3 | * |
| 4 | * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu |
| 5 | * Copyright (c) 2017 SiFive, Inc. |
| 6 | * Copyright (c) 2021 Western Digital Corporation or its affiliates. |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify it |
| 9 | * under the terms and conditions of the GNU General Public License, |
| 10 | * version 2 or later, as published by the Free Software Foundation. |
| 11 | * |
| 12 | * This program is distributed in the hope it will be useful, but WITHOUT |
| 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
| 15 | * more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU General Public License along with |
| 18 | * this program. If not, see <http://www.gnu.org/licenses/>. |
| 19 | */ |
| 20 | |
| 21 | #ifndef HW_RISCV_ACLINT_H |
| 22 | #define HW_RISCV_ACLINT_H |
| 23 | |
| 24 | #include "hw/core/sysbus.h" |
| 25 | |
| 26 | #define TYPE_RISCV_ACLINT_MTIMER "riscv.aclint.mtimer" |
| 27 | |
| 28 | #define RISCV_ACLINT_MTIMER(obj) \ |
| 29 | OBJECT_CHECK(RISCVAclintMTimerState, (obj), TYPE_RISCV_ACLINT_MTIMER) |
| 30 | |
| 31 | typedef struct RISCVAclintMTimerState { |
| 32 | /*< private >*/ |
| 33 | SysBusDevice parent_obj; |
| 34 | uint64_t time_delta; |
| 35 | uint64_t *timecmp; |
| 36 | QEMUTimer **timers; |
| 37 | |
| 38 | /*< public >*/ |
| 39 | MemoryRegion mmio; |
| 40 | uint32_t hartid_base; |
| 41 | uint32_t num_harts; |
| 42 | uint32_t timecmp_base; |
| 43 | uint32_t time_base; |
| 44 | uint32_t aperture_size; |
| 45 | uint32_t timebase_freq; |
| 46 | qemu_irq *timer_irqs; |
| 47 | } RISCVAclintMTimerState; |
| 48 | |
| 49 | DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size, |
| 50 | uint32_t hartid_base, uint32_t num_harts, |
| 51 | uint32_t timecmp_base, uint32_t time_base, uint32_t timebase_freq, |
| 52 | bool provide_rdtime); |
| 53 | |
| 54 | #define TYPE_RISCV_ACLINT_SWI "riscv.aclint.swi" |
| 55 | |
| 56 | #define RISCV_ACLINT_SWI(obj) \ |
| 57 | OBJECT_CHECK(RISCVAclintSwiState, (obj), TYPE_RISCV_ACLINT_SWI) |
| 58 | |
| 59 | typedef struct RISCVAclintSwiState { |
| 60 | /*< private >*/ |
| 61 | SysBusDevice parent_obj; |
| 62 | |
| 63 | /*< public >*/ |
| 64 | MemoryRegion mmio; |
| 65 | uint32_t hartid_base; |
| 66 | uint32_t num_harts; |
| 67 | uint32_t sswi; |
| 68 | qemu_irq *soft_irqs; |
| 69 | } RISCVAclintSwiState; |
| 70 | |
| 71 | DeviceState *riscv_aclint_swi_create(hwaddr addr, uint32_t hartid_base, |
| 72 | uint32_t num_harts, bool sswi); |
| 73 | |
| 74 | enum { |
| 75 | RISCV_ACLINT_DEFAULT_MTIMECMP = 0x0, |
| 76 | RISCV_ACLINT_DEFAULT_MTIME = 0x7ff8, |
| 77 | RISCV_ACLINT_DEFAULT_MTIMER_SIZE = 0x8000, |
| 78 | RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ = 10000000, |
| 79 | RISCV_ACLINT_MAX_HARTS = 4095, |
| 80 | RISCV_ACLINT_SWI_SIZE = 0x4000 |
| 81 | }; |
| 82 | |
| 83 | #define VMSTATE_TIMER_PTR_VARRAY(_f, _s, _f_n) \ |
| 84 | VMSTATE_VARRAY_OF_POINTER_UINT32(_f, _s, _f_n, 0, vmstate_info_timer, \ |
| 85 | QEMUTimer) |
| 86 | |
| 87 | #endif |