1 /* $NetBSD: pci_machdep.h,v 1.15 2018/04/19 21:50:07 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2002,2007 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Klaus Klein and Tim Rightnour 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef _PCI_MACHDEP_H_ 33 #define _PCI_MACHDEP_H_ 34 35 #include <prop/proplib.h> 36 37 /* 38 * Machine-specific definitions for PCI autoconfiguration. 39 */ 40 41 #define __HAVE_PCI_CONF_HOOK 42 #define __HAVE_PCI_MSI_MSIX 43 44 /* 45 * Types provided to machine-independent PCI code 46 */ 47 typedef struct genppc_pci_chipset *pci_chipset_tag_t; 48 typedef int pcitag_t; 49 typedef int pci_intr_handle_t; 50 51 /* 52 * Forward declarations. 53 */ 54 struct pci_attach_args; 55 struct pcibus_attach_args; 56 57 static __inline pci_chipset_tag_t pcibus_attach_args_pc( 58 struct pcibus_attach_args *); 59 static __inline pci_chipset_tag_t pci_attach_args_pc( 60 const struct pci_attach_args *); 61 62 #include <dev/pci/pcireg.h> 63 64 #ifdef _KERNEL 65 extern struct powerpc_bus_dma_tag pci_bus_dma_tag; 66 67 typedef enum { 68 PCI_INTR_TYPE_INTX = 0, 69 PCI_INTR_TYPE_MSI, 70 PCI_INTR_TYPE_MSIX, 71 PCI_INTR_TYPE_SIZE, 72 } pci_intr_type_t; 73 #endif 74 75 76 #if defined(_KERNEL) && (defined(_MODULE) || defined(__PCI_NOINLINE)) 77 void pci_attach_hook(device_t, device_t, 78 struct pcibus_attach_args *); 79 80 int pci_bus_maxdevs(pci_chipset_tag_t, int); 81 pcitag_t pci_make_tag(pci_chipset_tag_t, int, int, int); 82 pcireg_t pci_conf_read(pci_chipset_tag_t, pcitag_t, int); 83 void pci_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t); 84 void pci_decompose_tag(pci_chipset_tag_t, pcitag_t, 85 int *, int *, int *); 86 87 const char * pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t, 88 char *, size_t); 89 const struct evcnt * 90 pci_intr_evcnt(pci_chipset_tag_t, pci_intr_handle_t); 91 void * pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t, 92 int, int (*)(void *), void *); 93 void * pci_intr_establish_xname(pci_chipset_tag_t, pci_intr_handle_t, 94 int, int (*)(void *), void *, const char *); 95 void pci_intr_disestablish(pci_chipset_tag_t, void *); 96 int pci_intr_map(const struct pci_attach_args *, 97 pci_intr_handle_t *ihp); 98 int pci_intr_setattr(pci_chipset_tag_t, pci_intr_handle_t *, 99 int, uint64_t); 100 101 pci_intr_type_t pci_intr_type(pci_chipset_tag_t, pci_intr_handle_t); 102 int pci_intr_alloc(const struct pci_attach_args *, 103 pci_intr_handle_t **, int *, pci_intr_type_t); 104 void pci_intr_release(pci_chipset_tag_t, pci_intr_handle_t *, int); 105 int pci_intx_alloc(const struct pci_attach_args *, 106 pci_intr_handle_t **); 107 108 /* experimental MSI support */ 109 int pci_msi_alloc(const struct pci_attach_args *, 110 pci_intr_handle_t **, int *); 111 int pci_msi_alloc_exact(const struct pci_attach_args *, 112 pci_intr_handle_t **, int); 113 114 /* experimental MSI-X support */ 115 int pci_msix_alloc(const struct pci_attach_args *, 116 pci_intr_handle_t **, int *); 117 int pci_msix_alloc_exact(const struct pci_attach_args *, 118 pci_intr_handle_t **, int); 119 int pci_msix_alloc_map(const struct pci_attach_args *, 120 pci_intr_handle_t **, u_int *, int); 121 122 void pci_conf_interrupt(pci_chipset_tag_t, int, int, int, 123 int, int *); 124 int pci_conf_hook(pci_chipset_tag_t, int, int, int, pcireg_t); 125 #endif /* _KERNEL && (_MODULE || __PCI_NOINLINE) */ 126 127 /* Per bus information structure */ 128 struct genppc_pci_chipset_businfo { 129 SIMPLEQ_ENTRY(genppc_pci_chipset_businfo) next; 130 prop_dictionary_t pbi_properties; /* chipset properties */ 131 }; 132 133 #if !defined(_MODULE) 134 /* 135 * Generic PPC PCI structure and type definitions. 136 * NOT TO BE USED DIRECTLY BY MACHINE INDEPENDENT CODE. 137 */ 138 struct genppc_pci_chipset { 139 void *pc_conf_v; 140 void (*pc_attach_hook)(device_t, device_t, 141 struct pcibus_attach_args *); 142 int (*pc_bus_maxdevs)(void *, int); 143 pcitag_t (*pc_make_tag)(void *, int, int, int); 144 pcireg_t (*pc_conf_read)(void *, pcitag_t, int); 145 void (*pc_conf_write)(void *, pcitag_t, int, pcireg_t); 146 147 void *pc_intr_v; 148 int (*pc_intr_map)(const struct pci_attach_args *, 149 pci_intr_handle_t *); 150 const char *(*pc_intr_string)(void *, pci_intr_handle_t, char *, 151 size_t); 152 const struct evcnt *(*pc_intr_evcnt)(void *, pci_intr_handle_t); 153 void *(*pc_intr_establish)(void *, pci_intr_handle_t, 154 int, int (*)(void *), void *, const char *); 155 void (*pc_intr_disestablish)(void *, void *); 156 int (*pc_intr_setattr)(void *, pci_intr_handle_t *, 157 int, uint64_t); 158 159 pci_intr_type_t (*pc_intr_type)(void *, pci_intr_handle_t); 160 int (*pc_intr_alloc)(const struct pci_attach_args *, 161 pci_intr_handle_t **, int *, pci_intr_type_t); 162 void (*pc_intr_release)(void *, pci_intr_handle_t *, int); 163 int (*pc_intx_alloc)(const struct pci_attach_args *, 164 pci_intr_handle_t **); 165 166 /* experimental MSI support */ 167 void *pc_msi_v; 168 int (*pc_msi_alloc)(const struct pci_attach_args *, 169 pci_intr_handle_t **, int *, bool); 170 171 /* experimental MSI-X support */ 172 void *pc_msix_v; 173 int (*pc_msix_alloc)(const struct pci_attach_args *, 174 pci_intr_handle_t **, u_int *, int *, bool); 175 176 void (*pc_conf_interrupt)(void *, int, int, int, int, int *); 177 void (*pc_decompose_tag)(void *, pcitag_t, int *, 178 int *, int *); 179 int (*pc_conf_hook)(void *, int, int, int, pcireg_t); 180 181 uint32_t *pc_addr; 182 uint32_t *pc_data; 183 int pc_node; 184 int pc_ihandle; 185 int pc_bus; 186 bus_space_tag_t pc_memt; 187 bus_space_tag_t pc_iot; 188 189 SIMPLEQ_HEAD(, genppc_pci_chipset_businfo) pc_pbi; 190 }; 191 192 #ifdef _KERNEL 193 194 #ifdef __PCI_NOINLINE 195 #define __pci_inline 196 #else 197 #define __pci_inline static __inline 198 #endif 199 200 /* 201 * Functions provided to machine-independent PCI code. 202 */ 203 __pci_inline void 204 pci_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba) 205 { 206 (*pcibus_attach_args_pc(pba)->pc_attach_hook)(parent, self, pba); 207 } 208 209 __pci_inline int 210 pci_bus_maxdevs(pci_chipset_tag_t pc, int busno) 211 { 212 return (*pc->pc_bus_maxdevs)(pc->pc_conf_v, busno); 213 } 214 215 __pci_inline pcitag_t 216 pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function) 217 { 218 return (*pc->pc_make_tag)(pc->pc_conf_v, bus, device, function); 219 } 220 221 __pci_inline pcireg_t 222 pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg) 223 { 224 return (*pc->pc_conf_read)(pc->pc_conf_v, tag, reg); 225 } 226 227 __pci_inline void 228 pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t val) 229 { 230 (*pc->pc_conf_write)(pc->pc_conf_v, tag, reg, val); 231 } 232 233 __pci_inline void 234 pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *bp, int *dp, int *fp) 235 { 236 (*pc->pc_decompose_tag)(pc->pc_conf_v, tag, bp, dp, fp); 237 } 238 239 __pci_inline int 240 pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp) 241 { 242 return (*pci_attach_args_pc(pa)->pc_intr_map)(pa, ihp); 243 } 244 245 __pci_inline const char * 246 pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih, char * buf, 247 size_t len) 248 { 249 return (*pc->pc_intr_string)(pc->pc_intr_v, ih, buf, len); 250 } 251 252 __pci_inline const struct evcnt * 253 pci_intr_evcnt(pci_chipset_tag_t pc, pci_intr_handle_t ih) 254 { 255 return (*pc->pc_intr_evcnt)(pc->pc_intr_v, ih); 256 } 257 258 __pci_inline void * 259 pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int ipl, 260 int (*handler)(void *), void *arg) 261 { 262 return (*pc->pc_intr_establish)(pc->pc_intr_v, ih, ipl, handler, arg, 263 NULL); 264 } 265 266 __pci_inline void * 267 pci_intr_establish_xname(pci_chipset_tag_t pc, pci_intr_handle_t ih, int ipl, 268 int (*handler)(void *), void *arg, const char *xname) 269 { 270 return (*pc->pc_intr_establish)(pc->pc_intr_v, ih, ipl, handler, arg, 271 xname); 272 } 273 274 __pci_inline void 275 pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie) 276 { 277 (*pc->pc_intr_disestablish)(pc->pc_intr_v, cookie); 278 } 279 280 __pci_inline int 281 pci_intr_setattr(pci_chipset_tag_t pc, pci_intr_handle_t *ihp, int attr, 282 uint64_t data) 283 { 284 return (*pc->pc_intr_setattr)(pc->pc_intr_v, ihp, attr, data); 285 } 286 287 __pci_inline pci_intr_type_t 288 pci_intr_type(pci_chipset_tag_t pc, pci_intr_handle_t ih) 289 { 290 return (*pc->pc_intr_type)(pc->pc_intr_v, ih); 291 } 292 293 __pci_inline int 294 pci_intr_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps, 295 int *count, pci_intr_type_t max_type) 296 { 297 pci_chipset_tag_t pc = pci_attach_args_pc(pa); 298 return (*pc->pc_intr_alloc)(pa, ihps, count, max_type); 299 } 300 301 __pci_inline void 302 pci_intr_release(pci_chipset_tag_t pc, pci_intr_handle_t *ihp, int count) 303 { 304 (*pc->pc_intr_release)(pc->pc_intr_v, ihp, count); 305 } 306 307 __pci_inline int 308 pci_intx_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps) 309 { 310 pci_chipset_tag_t pc = pci_attach_args_pc(pa); 311 return (*pc->pc_intx_alloc)(pa, ihps); 312 } 313 314 315 __pci_inline void 316 pci_conf_interrupt(pci_chipset_tag_t pc, int bus, int device, int pin, 317 int swiz, int *iline) 318 { 319 (*pc->pc_conf_interrupt)(pc->pc_conf_v, bus, device, pin, swiz, iline); 320 } 321 322 __pci_inline int 323 pci_conf_hook(pci_chipset_tag_t pc, int bus, int device, int function, 324 pcireg_t id) 325 { 326 return (*pc->pc_conf_hook)(pc->pc_conf_v, bus, device, function, id); 327 } 328 329 330 /* experimental MSI support */ 331 __pci_inline int 332 pci_msi_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps, 333 int *count) 334 { 335 pci_chipset_tag_t pc = pci_attach_args_pc(pa); 336 return (*pc->pc_msi_alloc)(pa, ihps, count, false); 337 } 338 339 __pci_inline int 340 pci_msi_alloc_exact(const struct pci_attach_args *pa, pci_intr_handle_t **ihps, 341 int count) 342 { 343 pci_chipset_tag_t pc = pci_attach_args_pc(pa); 344 return (*pc->pc_msi_alloc)(pa, ihps, &count, true); 345 } 346 347 /* experimental MSI-X support */ 348 __pci_inline int 349 pci_msix_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps, 350 int *count) 351 { 352 pci_chipset_tag_t pc = pci_attach_args_pc(pa); 353 return (*pc->pc_msix_alloc)(pa, ihps, NULL, count, false); 354 } 355 356 __pci_inline int 357 pci_msix_alloc_exact(const struct pci_attach_args *pa, pci_intr_handle_t **ihps, 358 int count) 359 { 360 pci_chipset_tag_t pc = pci_attach_args_pc(pa); 361 return (*pc->pc_msix_alloc)(pa, ihps, NULL, &count, true); 362 } 363 364 __pci_inline int 365 pci_msix_alloc_map(const struct pci_attach_args *pa, pci_intr_handle_t **ihps, 366 u_int *table_indexes, int count) 367 { 368 pci_chipset_tag_t pc = pci_attach_args_pc(pa); 369 return (*pc->pc_msix_alloc)(pa, ihps, table_indexes, &count, true); 370 } 371 372 #undef __pci_inline 373 374 /* 375 * Generic PowerPC PCI functions. Override if necc. 376 */ 377 378 int genppc_pci_bus_maxdevs(void *, int); 379 380 int genppc_pci_intr_map(const struct pci_attach_args *, 381 pci_intr_handle_t *); 382 const char *genppc_pci_intr_string(void *, pci_intr_handle_t, char *, size_t); 383 const struct evcnt *genppc_pci_intr_evcnt(void *, pci_intr_handle_t); 384 void *genppc_pci_intr_establish(void *, pci_intr_handle_t, int, int (*)(void *), 385 void *, const char *); 386 void genppc_pci_intr_disestablish(void *, void *); 387 int genppc_pci_intr_setattr(void *, pci_intr_handle_t *, int, uint64_t); 388 pci_intr_type_t genppc_pci_intr_type(void *, pci_intr_handle_t); 389 int genppc_pci_intr_alloc(const struct pci_attach_args *, pci_intr_handle_t **, 390 int *, pci_intr_type_t); 391 void genppc_pci_intr_release(void *, pci_intr_handle_t *, int); 392 int genppc_pci_intx_alloc(const struct pci_attach_args *, pci_intr_handle_t **); 393 394 /* experimental MSI support */ 395 int genppc_pci_msi_alloc(const struct pci_attach_args *, pci_intr_handle_t **, 396 int *, bool); 397 398 /* experimental MSI-X support */ 399 int genppc_pci_msix_alloc(const struct pci_attach_args *, pci_intr_handle_t **, 400 u_int *, int *, bool); 401 402 void genppc_pci_chipset_msi_init(pci_chipset_tag_t pc); 403 void genppc_pci_chipset_msix_init(pci_chipset_tag_t pc); 404 405 #define GENPPC_PCI_MSI_INITIALIZER \ 406 .pc_msi_alloc = genppc_pci_msi_alloc 407 408 #define GENPPC_PCI_MSIX_INITIALIZER \ 409 .pc_msix_alloc = genppc_pci_msix_alloc 410 411 void genppc_pci_conf_interrupt(void *, int, int, int, int, int *); 412 int genppc_pci_conf_hook(void *, int, int, int, pcireg_t); 413 414 /* generic indirect PCI functions */ 415 void genppc_pci_indirect_attach_hook(device_t, device_t, 416 struct pcibus_attach_args *); 417 pcitag_t genppc_pci_indirect_make_tag(void *, int, int, int); 418 pcireg_t genppc_pci_indirect_conf_read(void *, pcitag_t, int); 419 void genppc_pci_indirect_conf_write(void *, pcitag_t, int, pcireg_t); 420 void genppc_pci_indirect_decompose_tag(void *, pcitag_t, int *, int *, int *); 421 422 /* generic OFW method PCI functions */ 423 void genppc_pci_ofmethod_attach_hook(device_t, device_t, 424 struct pcibus_attach_args *); 425 pcitag_t genppc_pci_ofmethod_make_tag(void *, int, int, int); 426 pcireg_t genppc_pci_ofmethod_conf_read(void *, pcitag_t, int); 427 void genppc_pci_ofmethod_conf_write(void *, pcitag_t, int, pcireg_t); 428 void genppc_pci_ofmethod_decompose_tag(void *, pcitag_t, int *, int *, int *); 429 430 /* Generic OFW PCI functions */ 431 432 int genofw_find_picnode(int); 433 void genofw_find_ofpics(int); 434 void genofw_fixup_picnode_offsets(void); 435 void genofw_setup_pciintr_map(void *, struct genppc_pci_chipset_businfo *, int); 436 int genofw_find_node_by_devfunc(int, int, int, int); 437 int genofw_pci_intr_map(const struct pci_attach_args *, pci_intr_handle_t *); 438 int genofw_pci_conf_hook(void *, int, int, int, pcireg_t); 439 440 /* OFW PCI structures and defines */ 441 #define PICNODE_TYPE_OPENPIC 1 442 #define PICNODE_TYPE_8259 2 443 #define PICNODE_TYPE_HEATHROW 3 444 #define PICNODE_TYPE_OHARE 4 445 #define PICNODE_TYPE_IVR 5 446 447 typedef struct _ofw_pic_node_t { 448 int node; 449 int parent; 450 int16_t cells; 451 int16_t intrs; 452 int16_t offset; 453 int16_t type; 454 } ofw_pic_node_t; 455 456 #endif /* _KERNEL */ 457 458 #endif /* !_MODULE */ 459 460 #endif /* _PCI_MACHDEP_H_ */ 461