1*0d09e41aSPaolo Bonzini /* 2*0d09e41aSPaolo Bonzini * pcie_aer.h 3*0d09e41aSPaolo Bonzini * 4*0d09e41aSPaolo Bonzini * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp> 5*0d09e41aSPaolo Bonzini * VA Linux Systems Japan K.K. 6*0d09e41aSPaolo Bonzini * 7*0d09e41aSPaolo Bonzini * This program is free software; you can redistribute it and/or modify 8*0d09e41aSPaolo Bonzini * it under the terms of the GNU General Public License as published by 9*0d09e41aSPaolo Bonzini * the Free Software Foundation; either version 2 of the License, or 10*0d09e41aSPaolo Bonzini * (at your option) any later version. 11*0d09e41aSPaolo Bonzini * 12*0d09e41aSPaolo Bonzini * This program is distributed in the hope that it will be useful, 13*0d09e41aSPaolo Bonzini * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*0d09e41aSPaolo Bonzini * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*0d09e41aSPaolo Bonzini * GNU General Public License for more details. 16*0d09e41aSPaolo Bonzini * 17*0d09e41aSPaolo Bonzini * You should have received a copy of the GNU General Public License along 18*0d09e41aSPaolo Bonzini * with this program; if not, see <http://www.gnu.org/licenses/>. 19*0d09e41aSPaolo Bonzini */ 20*0d09e41aSPaolo Bonzini 21*0d09e41aSPaolo Bonzini #ifndef QEMU_PCIE_AER_H 22*0d09e41aSPaolo Bonzini #define QEMU_PCIE_AER_H 23*0d09e41aSPaolo Bonzini 24*0d09e41aSPaolo Bonzini #include "hw/hw.h" 25*0d09e41aSPaolo Bonzini 26*0d09e41aSPaolo Bonzini /* definitions which PCIExpressDevice uses */ 27*0d09e41aSPaolo Bonzini 28*0d09e41aSPaolo Bonzini /* AER log */ 29*0d09e41aSPaolo Bonzini struct PCIEAERLog { 30*0d09e41aSPaolo Bonzini /* This structure is saved/loaded. 31*0d09e41aSPaolo Bonzini So explicitly size them instead of unsigned int */ 32*0d09e41aSPaolo Bonzini 33*0d09e41aSPaolo Bonzini /* the number of currently recorded log in log member */ 34*0d09e41aSPaolo Bonzini uint16_t log_num; 35*0d09e41aSPaolo Bonzini 36*0d09e41aSPaolo Bonzini /* 37*0d09e41aSPaolo Bonzini * The maximum number of the log. Errors can be logged up to this. 38*0d09e41aSPaolo Bonzini * 39*0d09e41aSPaolo Bonzini * This is configurable property. 40*0d09e41aSPaolo Bonzini * The specified value will be clipped down to PCIE_AER_LOG_MAX_LIMIT 41*0d09e41aSPaolo Bonzini * to avoid unreasonable memory usage. 42*0d09e41aSPaolo Bonzini * I bet that 128 log size would be big enough, otherwise too many errors 43*0d09e41aSPaolo Bonzini * for system to function normaly. But could consecutive errors occur? 44*0d09e41aSPaolo Bonzini */ 45*0d09e41aSPaolo Bonzini #define PCIE_AER_LOG_MAX_DEFAULT 8 46*0d09e41aSPaolo Bonzini #define PCIE_AER_LOG_MAX_LIMIT 128 47*0d09e41aSPaolo Bonzini #define PCIE_AER_LOG_MAX_UNSET 0xffff 48*0d09e41aSPaolo Bonzini uint16_t log_max; 49*0d09e41aSPaolo Bonzini 50*0d09e41aSPaolo Bonzini /* Error log. log_max-sized array */ 51*0d09e41aSPaolo Bonzini PCIEAERErr *log; 52*0d09e41aSPaolo Bonzini }; 53*0d09e41aSPaolo Bonzini 54*0d09e41aSPaolo Bonzini /* aer error message: error signaling message has only error sevirity and 55*0d09e41aSPaolo Bonzini source id. See 2.2.8.3 error signaling messages */ 56*0d09e41aSPaolo Bonzini struct PCIEAERMsg { 57*0d09e41aSPaolo Bonzini /* 58*0d09e41aSPaolo Bonzini * PCI_ERR_ROOT_CMD_{COR, NONFATAL, FATAL}_EN 59*0d09e41aSPaolo Bonzini * = PCI_EXP_DEVCTL_{CERE, NFERE, FERE} 60*0d09e41aSPaolo Bonzini */ 61*0d09e41aSPaolo Bonzini uint32_t severity; 62*0d09e41aSPaolo Bonzini 63*0d09e41aSPaolo Bonzini uint16_t source_id; /* bdf */ 64*0d09e41aSPaolo Bonzini }; 65*0d09e41aSPaolo Bonzini 66*0d09e41aSPaolo Bonzini static inline bool 67*0d09e41aSPaolo Bonzini pcie_aer_msg_is_uncor(const PCIEAERMsg *msg) 68*0d09e41aSPaolo Bonzini { 69*0d09e41aSPaolo Bonzini return msg->severity == PCI_ERR_ROOT_CMD_NONFATAL_EN || 70*0d09e41aSPaolo Bonzini msg->severity == PCI_ERR_ROOT_CMD_FATAL_EN; 71*0d09e41aSPaolo Bonzini } 72*0d09e41aSPaolo Bonzini 73*0d09e41aSPaolo Bonzini /* error */ 74*0d09e41aSPaolo Bonzini struct PCIEAERErr { 75*0d09e41aSPaolo Bonzini uint32_t status; /* error status bits */ 76*0d09e41aSPaolo Bonzini uint16_t source_id; /* bdf */ 77*0d09e41aSPaolo Bonzini 78*0d09e41aSPaolo Bonzini #define PCIE_AER_ERR_IS_CORRECTABLE 0x1 /* correctable/uncorrectable */ 79*0d09e41aSPaolo Bonzini #define PCIE_AER_ERR_MAYBE_ADVISORY 0x2 /* maybe advisory non-fatal */ 80*0d09e41aSPaolo Bonzini #define PCIE_AER_ERR_HEADER_VALID 0x4 /* TLP header is logged */ 81*0d09e41aSPaolo Bonzini #define PCIE_AER_ERR_TLP_PREFIX_PRESENT 0x8 /* TLP Prefix is logged */ 82*0d09e41aSPaolo Bonzini uint16_t flags; 83*0d09e41aSPaolo Bonzini 84*0d09e41aSPaolo Bonzini uint32_t header[4]; /* TLP header */ 85*0d09e41aSPaolo Bonzini uint32_t prefix[4]; /* TLP header prefix */ 86*0d09e41aSPaolo Bonzini }; 87*0d09e41aSPaolo Bonzini 88*0d09e41aSPaolo Bonzini extern const VMStateDescription vmstate_pcie_aer_log; 89*0d09e41aSPaolo Bonzini 90*0d09e41aSPaolo Bonzini int pcie_aer_init(PCIDevice *dev, uint16_t offset); 91*0d09e41aSPaolo Bonzini void pcie_aer_exit(PCIDevice *dev); 92*0d09e41aSPaolo Bonzini void pcie_aer_write_config(PCIDevice *dev, 93*0d09e41aSPaolo Bonzini uint32_t addr, uint32_t val, int len); 94*0d09e41aSPaolo Bonzini 95*0d09e41aSPaolo Bonzini /* aer root port */ 96*0d09e41aSPaolo Bonzini void pcie_aer_root_set_vector(PCIDevice *dev, unsigned int vector); 97*0d09e41aSPaolo Bonzini void pcie_aer_root_init(PCIDevice *dev); 98*0d09e41aSPaolo Bonzini void pcie_aer_root_reset(PCIDevice *dev); 99*0d09e41aSPaolo Bonzini void pcie_aer_root_write_config(PCIDevice *dev, 100*0d09e41aSPaolo Bonzini uint32_t addr, uint32_t val, int len, 101*0d09e41aSPaolo Bonzini uint32_t root_cmd_prev); 102*0d09e41aSPaolo Bonzini 103*0d09e41aSPaolo Bonzini /* error injection */ 104*0d09e41aSPaolo Bonzini int pcie_aer_inject_error(PCIDevice *dev, const PCIEAERErr *err); 105*0d09e41aSPaolo Bonzini 106*0d09e41aSPaolo Bonzini #endif /* QEMU_PCIE_AER_H */ 107