xref: /openbmc/qemu/hw/riscv/riscv-iommu.h (revision 69a9ae48)
10c54acb8STomasz Jeznach /*
20c54acb8STomasz Jeznach  * QEMU emulation of an RISC-V IOMMU
30c54acb8STomasz Jeznach  *
40c54acb8STomasz Jeznach  * Copyright (C) 2022-2023 Rivos Inc.
50c54acb8STomasz Jeznach  *
60c54acb8STomasz Jeznach  * This program is free software; you can redistribute it and/or modify it
70c54acb8STomasz Jeznach  * under the terms and conditions of the GNU General Public License,
80c54acb8STomasz Jeznach  * version 2 or later, as published by the Free Software Foundation.
90c54acb8STomasz Jeznach  *
100c54acb8STomasz Jeznach  * This program is distributed in the hope that it will be useful,
110c54acb8STomasz Jeznach  * but WITHOUT ANY WARRANTY; without even the implied warranty of
120c54acb8STomasz Jeznach  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
130c54acb8STomasz Jeznach  * GNU General Public License for more details.
140c54acb8STomasz Jeznach  *
150c54acb8STomasz Jeznach  * You should have received a copy of the GNU General Public License along
160c54acb8STomasz Jeznach  * with this program; if not, see <http://www.gnu.org/licenses/>.
170c54acb8STomasz Jeznach  */
180c54acb8STomasz Jeznach 
190c54acb8STomasz Jeznach #ifndef HW_RISCV_IOMMU_STATE_H
200c54acb8STomasz Jeznach #define HW_RISCV_IOMMU_STATE_H
210c54acb8STomasz Jeznach 
220c54acb8STomasz Jeznach #include "qom/object.h"
230c54acb8STomasz Jeznach #include "hw/riscv/iommu.h"
240c54acb8STomasz Jeznach 
250c54acb8STomasz Jeznach struct RISCVIOMMUState {
260c54acb8STomasz Jeznach     /*< private >*/
270c54acb8STomasz Jeznach     DeviceState parent_obj;
280c54acb8STomasz Jeznach 
290c54acb8STomasz Jeznach     /*< public >*/
300c54acb8STomasz Jeznach     uint32_t version;     /* Reported interface version number */
310c54acb8STomasz Jeznach     uint32_t pid_bits;    /* process identifier width */
320c54acb8STomasz Jeznach     uint32_t bus;         /* PCI bus mapping for non-root endpoints */
330c54acb8STomasz Jeznach 
340c54acb8STomasz Jeznach     uint64_t cap;         /* IOMMU supported capabilities */
350c54acb8STomasz Jeznach     uint64_t fctl;        /* IOMMU enabled features */
360c54acb8STomasz Jeznach     uint64_t icvec_avail_vectors;  /* Available interrupt vectors in ICVEC */
370c54acb8STomasz Jeznach 
380c54acb8STomasz Jeznach     bool enable_off;      /* Enable out-of-reset OFF mode (DMA disabled) */
390c54acb8STomasz Jeznach     bool enable_msi;      /* Enable MSI remapping */
40*69a9ae48STomasz Jeznach     bool enable_ats;      /* Enable ATS support */
410c54acb8STomasz Jeznach     bool enable_s_stage;  /* Enable S/VS-Stage translation */
420c54acb8STomasz Jeznach     bool enable_g_stage;  /* Enable G-Stage translation */
430c54acb8STomasz Jeznach 
440c54acb8STomasz Jeznach     /* IOMMU Internal State */
450c54acb8STomasz Jeznach     uint64_t ddtp;        /* Validated Device Directory Tree Root Pointer */
460c54acb8STomasz Jeznach 
470c54acb8STomasz Jeznach     dma_addr_t cq_addr;   /* Command queue base physical address */
480c54acb8STomasz Jeznach     dma_addr_t fq_addr;   /* Fault/event queue base physical address */
490c54acb8STomasz Jeznach     dma_addr_t pq_addr;   /* Page request queue base physical address */
500c54acb8STomasz Jeznach 
510c54acb8STomasz Jeznach     uint32_t cq_mask;     /* Command queue index bit mask */
520c54acb8STomasz Jeznach     uint32_t fq_mask;     /* Fault/event queue index bit mask */
530c54acb8STomasz Jeznach     uint32_t pq_mask;     /* Page request queue index bit mask */
540c54acb8STomasz Jeznach 
550c54acb8STomasz Jeznach     /* interrupt notifier */
560c54acb8STomasz Jeznach     void (*notify)(RISCVIOMMUState *iommu, unsigned vector);
570c54acb8STomasz Jeznach 
580c54acb8STomasz Jeznach     /* IOMMU State Machine */
590c54acb8STomasz Jeznach     QemuThread core_proc; /* Background processing thread */
600c54acb8STomasz Jeznach     QemuCond core_cond;   /* Background processing wake up signal */
610c54acb8STomasz Jeznach     unsigned core_exec;   /* Processing thread execution actions */
620c54acb8STomasz Jeznach 
630c54acb8STomasz Jeznach     /* IOMMU target address space */
640c54acb8STomasz Jeznach     AddressSpace *target_as;
650c54acb8STomasz Jeznach     MemoryRegion *target_mr;
660c54acb8STomasz Jeznach 
670c54acb8STomasz Jeznach     /* MSI / MRIF access trap */
680c54acb8STomasz Jeznach     AddressSpace trap_as;
690c54acb8STomasz Jeznach     MemoryRegion trap_mr;
700c54acb8STomasz Jeznach 
710c54acb8STomasz Jeznach     GHashTable *ctx_cache;          /* Device translation Context Cache */
720c54acb8STomasz Jeznach 
739d085a1cSTomasz Jeznach     GHashTable *iot_cache;          /* IO Translated Address Cache */
749d085a1cSTomasz Jeznach     unsigned iot_limit;             /* IO Translation Cache size limit */
759d085a1cSTomasz Jeznach 
760c54acb8STomasz Jeznach     /* MMIO Hardware Interface */
770c54acb8STomasz Jeznach     MemoryRegion regs_mr;
780c54acb8STomasz Jeznach     uint8_t *regs_rw;  /* register state (user write) */
790c54acb8STomasz Jeznach     uint8_t *regs_wc;  /* write-1-to-clear mask */
800c54acb8STomasz Jeznach     uint8_t *regs_ro;  /* read-only mask */
810c54acb8STomasz Jeznach 
820c54acb8STomasz Jeznach     QLIST_ENTRY(RISCVIOMMUState) iommus;
830c54acb8STomasz Jeznach     QLIST_HEAD(, RISCVIOMMUSpace) spaces;
840c54acb8STomasz Jeznach };
850c54acb8STomasz Jeznach 
860c54acb8STomasz Jeznach void riscv_iommu_pci_setup_iommu(RISCVIOMMUState *iommu, PCIBus *bus,
870c54acb8STomasz Jeznach          Error **errp);
880c54acb8STomasz Jeznach 
890c54acb8STomasz Jeznach /* private helpers */
900c54acb8STomasz Jeznach 
910c54acb8STomasz Jeznach /* Register helper functions */
riscv_iommu_reg_mod32(RISCVIOMMUState * s,unsigned idx,uint32_t set,uint32_t clr)920c54acb8STomasz Jeznach static inline uint32_t riscv_iommu_reg_mod32(RISCVIOMMUState *s,
930c54acb8STomasz Jeznach     unsigned idx, uint32_t set, uint32_t clr)
940c54acb8STomasz Jeznach {
950c54acb8STomasz Jeznach     uint32_t val = ldl_le_p(s->regs_rw + idx);
960c54acb8STomasz Jeznach     stl_le_p(s->regs_rw + idx, (val & ~clr) | set);
970c54acb8STomasz Jeznach     return val;
980c54acb8STomasz Jeznach }
990c54acb8STomasz Jeznach 
riscv_iommu_reg_set32(RISCVIOMMUState * s,unsigned idx,uint32_t set)1000c54acb8STomasz Jeznach static inline void riscv_iommu_reg_set32(RISCVIOMMUState *s, unsigned idx,
1010c54acb8STomasz Jeznach                                          uint32_t set)
1020c54acb8STomasz Jeznach {
1030c54acb8STomasz Jeznach     stl_le_p(s->regs_rw + idx, set);
1040c54acb8STomasz Jeznach }
1050c54acb8STomasz Jeznach 
riscv_iommu_reg_get32(RISCVIOMMUState * s,unsigned idx)1060c54acb8STomasz Jeznach static inline uint32_t riscv_iommu_reg_get32(RISCVIOMMUState *s, unsigned idx)
1070c54acb8STomasz Jeznach {
1080c54acb8STomasz Jeznach     return ldl_le_p(s->regs_rw + idx);
1090c54acb8STomasz Jeznach }
1100c54acb8STomasz Jeznach 
riscv_iommu_reg_mod64(RISCVIOMMUState * s,unsigned idx,uint64_t set,uint64_t clr)1110c54acb8STomasz Jeznach static inline uint64_t riscv_iommu_reg_mod64(RISCVIOMMUState *s, unsigned idx,
1120c54acb8STomasz Jeznach                                              uint64_t set, uint64_t clr)
1130c54acb8STomasz Jeznach {
1140c54acb8STomasz Jeznach     uint64_t val = ldq_le_p(s->regs_rw + idx);
1150c54acb8STomasz Jeznach     stq_le_p(s->regs_rw + idx, (val & ~clr) | set);
1160c54acb8STomasz Jeznach     return val;
1170c54acb8STomasz Jeznach }
1180c54acb8STomasz Jeznach 
riscv_iommu_reg_set64(RISCVIOMMUState * s,unsigned idx,uint64_t set)1190c54acb8STomasz Jeznach static inline void riscv_iommu_reg_set64(RISCVIOMMUState *s, unsigned idx,
1200c54acb8STomasz Jeznach                                          uint64_t set)
1210c54acb8STomasz Jeznach {
1220c54acb8STomasz Jeznach     stq_le_p(s->regs_rw + idx, set);
1230c54acb8STomasz Jeznach }
1240c54acb8STomasz Jeznach 
riscv_iommu_reg_get64(RISCVIOMMUState * s,unsigned idx)1250c54acb8STomasz Jeznach static inline uint64_t riscv_iommu_reg_get64(RISCVIOMMUState *s,
1260c54acb8STomasz Jeznach     unsigned idx)
1270c54acb8STomasz Jeznach {
1280c54acb8STomasz Jeznach     return ldq_le_p(s->regs_rw + idx);
1290c54acb8STomasz Jeznach }
1300c54acb8STomasz Jeznach #endif
131