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