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 /* AER log */ 29 struct PCIEAERLog { 30 /* This structure is saved/loaded. 31 So explicitly size them instead of unsigned int */ 32 33 /* the number of currently recorded log in log member */ 34 uint16_t log_num; 35 36 /* 37 * The maximum number of the log. Errors can be logged up to this. 38 * 39 * This is configurable property. 40 * The specified value will be clipped down to PCIE_AER_LOG_MAX_LIMIT 41 * to avoid unreasonable memory usage. 42 * I bet that 128 log size would be big enough, otherwise too many errors 43 * for system to function normaly. But could consecutive errors occur? 44 */ 45 #define PCIE_AER_LOG_MAX_DEFAULT 8 46 #define PCIE_AER_LOG_MAX_LIMIT 128 47 uint16_t log_max; 48 49 /* Error log. log_max-sized array */ 50 PCIEAERErr *log; 51 }; 52 53 /* aer error message: error signaling message has only error severity and 54 source id. See 2.2.8.3 error signaling messages */ 55 struct PCIEAERMsg { 56 /* 57 * PCI_ERR_ROOT_CMD_{COR, NONFATAL, FATAL}_EN 58 * = PCI_EXP_DEVCTL_{CERE, NFERE, FERE} 59 */ 60 uint32_t severity; 61 62 uint16_t source_id; /* bdf */ 63 }; 64 65 static inline bool 66 pcie_aer_msg_is_uncor(const PCIEAERMsg *msg) 67 { 68 return msg->severity == PCI_ERR_ROOT_CMD_NONFATAL_EN || 69 msg->severity == PCI_ERR_ROOT_CMD_FATAL_EN; 70 } 71 72 /* error */ 73 struct PCIEAERErr { 74 uint32_t status; /* error status bits */ 75 uint16_t source_id; /* bdf */ 76 77 #define PCIE_AER_ERR_IS_CORRECTABLE 0x1 /* correctable/uncorrectable */ 78 #define PCIE_AER_ERR_MAYBE_ADVISORY 0x2 /* maybe advisory non-fatal */ 79 #define PCIE_AER_ERR_HEADER_VALID 0x4 /* TLP header is logged */ 80 #define PCIE_AER_ERR_TLP_PREFIX_PRESENT 0x8 /* TLP Prefix is logged */ 81 uint16_t flags; 82 83 uint32_t header[4]; /* TLP header */ 84 uint32_t prefix[4]; /* TLP header prefix */ 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