| 1 | #ifndef OPENPIC_H |
| 2 | #define OPENPIC_H |
| 3 | |
| 4 | #include "hw/core/sysbus.h" |
| 5 | #include "hw/core/cpu.h" |
| 6 | #include "qom/object.h" |
| 7 | |
| 8 | #define MAX_CPU 32 |
| 9 | #define MAX_MSI 8 |
| 10 | #define VID 0x03 /* MPIC version ID */ |
| 11 | |
| 12 | /* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */ |
| 13 | enum { |
| 14 | OPENPIC_OUTPUT_INT = 0, /* IRQ */ |
| 15 | OPENPIC_OUTPUT_CINT, /* critical IRQ */ |
| 16 | OPENPIC_OUTPUT_MCK, /* Machine check event */ |
| 17 | OPENPIC_OUTPUT_DEBUG, /* Unconditional debug event */ |
| 18 | OPENPIC_OUTPUT_RESET, /* Core reset event */ |
| 19 | OPENPIC_OUTPUT_NB, |
| 20 | }; |
| 21 | |
| 22 | typedef struct IrqLines { qemu_irq irq[OPENPIC_OUTPUT_NB]; } IrqLines; |
| 23 | |
| 24 | #define OPENPIC_MODEL_FSL_MPIC_20 1 |
| 25 | #define OPENPIC_MODEL_FSL_MPIC_42 2 |
| 26 | #define OPENPIC_MODEL_KEYLARGO 3 |
| 27 | |
| 28 | #define OPENPIC_MAX_SRC 256 |
| 29 | #define OPENPIC_MAX_TMR 4 |
| 30 | #define OPENPIC_MAX_IPI 4 |
| 31 | #define OPENPIC_MAX_IRQ (OPENPIC_MAX_SRC + OPENPIC_MAX_IPI + \ |
| 32 | OPENPIC_MAX_TMR) |
| 33 | |
| 34 | /* KeyLargo */ |
| 35 | #define KEYLARGO_MAX_CPU 4 |
| 36 | #define KEYLARGO_MAX_EXT 64 |
| 37 | #define KEYLARGO_MAX_IPI 4 |
| 38 | #define KEYLARGO_MAX_IRQ (64 + KEYLARGO_MAX_IPI) |
| 39 | #define KEYLARGO_MAX_TMR 0 |
| 40 | #define KEYLARGO_IPI_IRQ (KEYLARGO_MAX_EXT) /* First IPI IRQ */ |
| 41 | /* Timers don't exist but this makes the code happy... */ |
| 42 | #define KEYLARGO_TMR_IRQ (KEYLARGO_IPI_IRQ + KEYLARGO_MAX_IPI) |
| 43 | |
| 44 | typedef struct FslMpicInfo { |
| 45 | int max_ext; |
| 46 | } FslMpicInfo; |
| 47 | |
| 48 | typedef enum IRQType { |
| 49 | IRQ_TYPE_NORMAL = 0, |
| 50 | IRQ_TYPE_FSLINT, /* FSL internal interrupt -- level only */ |
| 51 | IRQ_TYPE_FSLSPECIAL, /* FSL timer/IPI interrupt, edge, no polarity */ |
| 52 | } IRQType; |
| 53 | |
| 54 | /* |
| 55 | * Round up to the nearest 64 IRQs so that the queue length |
| 56 | * won't change when moving between 32 and 64 bit hosts. |
| 57 | */ |
| 58 | #define IRQQUEUE_SIZE_BITS ROUND_UP(OPENPIC_MAX_IRQ, 64) |
| 59 | |
| 60 | typedef struct IRQQueue { |
| 61 | unsigned long *queue; |
| 62 | int32_t queue_size; /* Only used for VMSTATE_BITMAP */ |
| 63 | int next; |
| 64 | int priority; |
| 65 | } IRQQueue; |
| 66 | |
| 67 | typedef struct IRQSource { |
| 68 | uint32_t ivpr; /* IRQ vector/priority register */ |
| 69 | uint32_t idr; /* IRQ destination register */ |
| 70 | uint32_t destmask; /* bitmap of CPU destinations */ |
| 71 | int last_cpu; |
| 72 | int output; /* IRQ level, e.g. OPENPIC_OUTPUT_INT */ |
| 73 | int pending; /* TRUE if IRQ is pending */ |
| 74 | IRQType type; |
| 75 | bool level:1; /* level-triggered */ |
| 76 | bool nomask:1; /* critical interrupts ignore mask on some FSL MPICs */ |
| 77 | } IRQSource; |
| 78 | |
| 79 | #define IVPR_MASK_SHIFT 31 |
| 80 | #define IVPR_MASK_MASK (1U << IVPR_MASK_SHIFT) |
| 81 | #define IVPR_ACTIVITY_SHIFT 30 |
| 82 | #define IVPR_ACTIVITY_MASK (1U << IVPR_ACTIVITY_SHIFT) |
| 83 | #define IVPR_MODE_SHIFT 29 |
| 84 | #define IVPR_MODE_MASK (1U << IVPR_MODE_SHIFT) |
| 85 | #define IVPR_POLARITY_SHIFT 23 |
| 86 | #define IVPR_POLARITY_MASK (1U << IVPR_POLARITY_SHIFT) |
| 87 | #define IVPR_SENSE_SHIFT 22 |
| 88 | #define IVPR_SENSE_MASK (1U << IVPR_SENSE_SHIFT) |
| 89 | |
| 90 | #define IVPR_PRIORITY_MASK (0xFU << 16) |
| 91 | #define IVPR_PRIORITY(_ivprr_) ((int)(((_ivprr_) & IVPR_PRIORITY_MASK) >> 16)) |
| 92 | #define IVPR_VECTOR(opp, _ivprr_) ((_ivprr_) & (opp)->vector_mask) |
| 93 | |
| 94 | /* IDR[EP/CI] are only for FSL MPIC prior to v4.0 */ |
| 95 | #define IDR_EP 0x80000000 /* external pin */ |
| 96 | #define IDR_CI 0x40000000 /* critical interrupt */ |
| 97 | |
| 98 | typedef struct OpenPICTimer { |
| 99 | uint32_t tccr; /* Global timer current count register */ |
| 100 | uint32_t tbcr; /* Global timer base count register */ |
| 101 | int n_IRQ; |
| 102 | bool qemu_timer_active; /* Is the qemu_timer is running? */ |
| 103 | struct QEMUTimer *qemu_timer; |
| 104 | struct OpenPICState *opp; /* Device timer is part of. */ |
| 105 | /* |
| 106 | * The QEMU_CLOCK_VIRTUAL time (in ns) corresponding to the last |
| 107 | * current_count written or read, only defined if qemu_timer_active. |
| 108 | */ |
| 109 | uint64_t origin_time; |
| 110 | } OpenPICTimer; |
| 111 | |
| 112 | typedef struct OpenPICMSI { |
| 113 | uint32_t msir; /* Shared Message Signaled Interrupt Register */ |
| 114 | } OpenPICMSI; |
| 115 | |
| 116 | typedef struct IRQDest { |
| 117 | int32_t ctpr; /* CPU current task priority */ |
| 118 | IRQQueue raised; |
| 119 | IRQQueue servicing; |
| 120 | qemu_irq *irqs; |
| 121 | |
| 122 | /* Count of IRQ sources asserting on non-INT outputs */ |
| 123 | uint32_t outputs_active[OPENPIC_OUTPUT_NB]; |
| 124 | } IRQDest; |
| 125 | |
| 126 | #define TYPE_OPENPIC "openpic" |
| 127 | OBJECT_DECLARE_SIMPLE_TYPE(OpenPICState, OPENPIC) |
| 128 | |
| 129 | struct OpenPICState { |
| 130 | /*< private >*/ |
| 131 | SysBusDevice parent_obj; |
| 132 | /*< public >*/ |
| 133 | |
| 134 | MemoryRegion mem; |
| 135 | |
| 136 | /* Behavior control */ |
| 137 | FslMpicInfo *fsl; |
| 138 | uint32_t model; |
| 139 | uint32_t flags; |
| 140 | uint32_t nb_irqs; |
| 141 | uint32_t vid; |
| 142 | uint32_t vir; /* Vendor identification register */ |
| 143 | uint32_t vector_mask; |
| 144 | uint32_t tfrr_reset; |
| 145 | uint32_t ivpr_reset; |
| 146 | uint32_t idr_reset; |
| 147 | uint32_t brr1; |
| 148 | uint32_t mpic_mode_mask; |
| 149 | |
| 150 | /* Sub-regions */ |
| 151 | MemoryRegion sub_io_mem[6]; |
| 152 | |
| 153 | /* Global registers */ |
| 154 | uint32_t frr; /* Feature reporting register */ |
| 155 | uint32_t gcr; /* Global configuration register */ |
| 156 | uint32_t pir; /* Processor initialization register */ |
| 157 | uint32_t spve; /* Spurious vector register */ |
| 158 | uint32_t tfrr; /* Timer frequency reporting register */ |
| 159 | /* Source registers */ |
| 160 | IRQSource src[OPENPIC_MAX_IRQ]; |
| 161 | /* Local registers per output pin */ |
| 162 | IRQDest dst[MAX_CPU]; |
| 163 | uint32_t nb_cpus; |
| 164 | /* Timer registers */ |
| 165 | OpenPICTimer timers[OPENPIC_MAX_TMR]; |
| 166 | uint32_t max_tmr; |
| 167 | |
| 168 | /* Shared MSI registers */ |
| 169 | OpenPICMSI msi[MAX_MSI]; |
| 170 | uint32_t max_irq; |
| 171 | uint32_t irq_ipi0; |
| 172 | uint32_t irq_tim0; |
| 173 | uint32_t irq_msi; |
| 174 | }; |
| 175 | |
| 176 | #endif /* OPENPIC_H */ |