1 /* Copyright 2013-2014 IBM Corp. 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 * implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef __INTERRUPTS_H 18 #define __INTERRUPTS_H 19 20 #include <stdint.h> 21 #include <ccan/list/list.h> 22 23 /* Note about interrupt numbers on P8 24 * ================================== 25 * 26 * On P8 the interrupts numbers are just a flat space of 19-bit, 27 * there is no BUID or similar. 28 * 29 * However, various unit tend to require blocks of interrupt that 30 * are naturally power-of-two aligned 31 * 32 * Our P8 Interrupt map consits thus of dividing the chip space 33 * into "blocks" of 2048 interrupts. Block 0 is for random chip 34 * interrupt sources (NX, PSI, OCC, ...) and keeps sources 0..15 35 * clear to avoid conflits with IPIs etc.... Block 1..n are assigned 36 * to PHB 0..n respectively. The number of blocks is determined by the 37 * number of bits assigned to chips. 38 * 39 * That gives us an interrupt number made of: 40 * 18 n+1 n 11 10 0 41 * | | | | | | 42 * +--------------------+------+-----------------------------+ 43 * | Chip# | PHB# | IVE# | 44 * +--------------------+------+-----------------------------+ 45 * 46 * Where n = 18 - p8_chip_id_bits 47 * 48 * For P8 we have 6 bits for Chip# as defined by p8_chip_id_bits. We 49 * therefore support a max of 2^6 = 64 chips. 50 * 51 * For P8NVL we have an extra PHB and so we assign 5 bits for Chip# 52 * and therefore support a max of 32 chips. 53 * 54 * Each PHB supports 2K interrupt sources, which is shared by 55 * LSI and MSI. With default configuration, MSI would use range 56 * [0, 0x7f7] and LSI would use [0x7f8, 0x7ff]. The interrupt 57 * source should be combined with IRSN to form final hardware 58 * IRQ. 59 * 60 */ 61 62 uint32_t p8_chip_irq_block_base(uint32_t chip, uint32_t block); 63 uint32_t p8_chip_irq_phb_base(uint32_t chip, uint32_t phb); 64 uint32_t p8_irq_to_chip(uint32_t irq); 65 uint32_t p8_irq_to_block(uint32_t irq); 66 uint32_t p8_irq_to_phb(uint32_t irq); 67 68 /* Total number of bits in the P8 interrupt space */ 69 #define P8_IRQ_BITS 19 70 71 /* Number of bits per block */ 72 #define P8_IVE_BITS 11 73 74 #define P8_IRQ_BLOCK_MISC 0 75 #define P8_IRQ_BLOCK_PHB_BASE 1 76 77 /* Assignment of the "MISC" block: 78 * ------------------------------- 79 * 80 * PSI interface has 6 interrupt sources: 81 * 82 * FSP, OCC, FSI, LPC, Local error, Host error 83 * 84 * and thus needs a block of 8 85 */ 86 #define P8_IRQ_MISC_PSI_BASE 0x10 /* 0x10..0x17 */ 87 88 /* These are handled by skiboot */ 89 #define P8_IRQ_PSI_FSP 0 90 #define P8_IRQ_PSI_OCC 1 91 #define P8_IRQ_PSI_FSI 2 92 #define P8_IRQ_PSI_LPC 3 93 #define P8_IRQ_PSI_LOCAL_ERR 4 94 #define P8_IRQ_PSI_EXTERNAL 5 /* Used for UART */ 95 #define P8_IRQ_PSI_IRQ_COUNT 6 96 97 /* TBD: NX, AS, ... 98 */ 99 100 /* Note about interrupt numbers on P9 101 * ================================== 102 * 103 * P9 uses a completely different interrupt controller, XIVE. 104 * 105 * It targets objects using a combination of block number and 106 * index within a block. However, we try to avoid exposing that 107 * split to the OS in order to keep some abstraction in case the 108 * way we allocate these change. 109 * 110 * The lowest level entity in Xive is the ESB (state bits). 111 * 112 * Those are spread between PHBs, PSI bridge and XIVE itself which 113 * provide a large amount of state bits for IPIs and other SW and HW 114 * generated interrupts by sources that don't have their own ESB logic 115 * 116 * Due to that spread, they aren't a good representation of a global 117 * interrupt number. 118 * 119 * Each such source however needs to be targetted at an EAS (IVT) 120 * entry in a table which will control targetting information and 121 * associate that interrupt with a logical number. 122 * 123 * Thus that table entry number represents a good "global interrupt 124 * number". Additionally, for the host OS, we will keep the logical 125 * number equal to the global number. 126 * 127 * The details of how these are assigned on P9 can be found in 128 * hw/xive.c. P9 HW will only use a subset of the definitions and 129 * functions in this file (or the corresponding core/interrupts.c). 130 */ 131 132 struct irq_source; 133 134 /* 135 * IRQ sources register themselves here. 136 * 137 * The "attributes" callback provides various attributes specific to 138 * a given interrupt, such as whether it's targetted at OPAL or the 139 * OS, or whether it's frequent or infrequent. The latter will be used 140 * later to optimize the lookup of the sources array by providing a small 141 * cache of the frequent interrupts. 142 * 143 * The "eoi" callback is used for XIVE interrupts in XICS emulation 144 * though we might expose it at some point in XIVE native mode for 145 * interrupts that require special EOI operations such as possibly 146 * the LPC interrupts on P9 that need a latch cleared in the LPCHC. 147 * 148 * The "name" callback returns a name for the interrupt in a new 149 * malloc()'ed block. The caller will free() it. NULL is acceptable. 150 */ 151 struct irq_source_ops { 152 int64_t (*set_xive)(struct irq_source *is, uint32_t isn, 153 uint16_t server, uint8_t priority); 154 int64_t (*get_xive)(struct irq_source *is, uint32_t isn, 155 uint16_t *server, uint8_t *priority); 156 uint64_t (*attributes)(struct irq_source *is, uint32_t isn); 157 /* LSB is the target */ 158 #define IRQ_ATTR_TARGET_OPAL 0x0 159 #define IRQ_ATTR_TARGET_LINUX 0x1 160 /* For OPAL interrupts, estimate frequency */ 161 #define IRQ_ATTR_TARGET_RARE 0x0 162 #define IRQ_ATTR_TARGET_FREQUENT 0x2 163 /* For OPAL interrupts, level vs. edge setting */ 164 #define IRQ_ATTR_TYPE_LSI 0x0 165 #define IRQ_ATTR_TYPE_MSI 0x4 166 void (*interrupt)(struct irq_source *is, uint32_t isn); 167 void (*eoi)(struct irq_source *is, uint32_t isn); 168 char *(*name)(struct irq_source *is, uint32_t isn); 169 }; 170 171 struct irq_source { 172 uint32_t start; 173 uint32_t end; 174 const struct irq_source_ops *ops; 175 void *data; 176 struct list_node link; 177 }; 178 179 extern void __register_irq_source(struct irq_source *is, bool secondary); 180 extern void register_irq_source(const struct irq_source_ops *ops, void *data, 181 uint32_t start, uint32_t count); 182 extern void unregister_irq_source(uint32_t start, uint32_t count); 183 extern struct irq_source *irq_find_source(uint32_t isn); 184 185 /* Warning: callback is called with internal source lock held 186 * so don't call back into any of our irq_ APIs from it 187 */ 188 extern void irq_for_each_source(void (*cb)(struct irq_source *, void *), 189 void *data); 190 191 extern uint32_t get_psi_interrupt(uint32_t chip_id); 192 193 extern struct dt_node *add_ics_node(void); 194 extern void add_opal_interrupts(void); 195 extern uint32_t get_ics_phandle(void); 196 197 struct cpu_thread; 198 199 extern void reset_cpu_icp(void); 200 extern void reset_cpu_xive(void); 201 extern void icp_send_eoi(uint32_t interrupt); 202 extern void icp_prep_for_pm(void); 203 extern void icp_kick_cpu(struct cpu_thread *cpu); 204 205 extern void init_interrupts(void); 206 207 extern bool irq_source_eoi(uint32_t isn); 208 extern bool __irq_source_eoi(struct irq_source *is, uint32_t isn); 209 210 211 #endif /* __INTERRUPTS_H */ 212