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/hw.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 #define PCIE_AER_LOG_MAX_UNSET 0xffff 48 uint16_t log_max; 49 50 /* Error log. log_max-sized array */ 51 PCIEAERErr *log; 52 }; 53 54 /* aer error message: error signaling message has only error severity and 55 source id. See 2.2.8.3 error signaling messages */ 56 struct PCIEAERMsg { 57 /* 58 * PCI_ERR_ROOT_CMD_{COR, NONFATAL, FATAL}_EN 59 * = PCI_EXP_DEVCTL_{CERE, NFERE, FERE} 60 */ 61 uint32_t severity; 62 63 uint16_t source_id; /* bdf */ 64 }; 65 66 static inline bool 67 pcie_aer_msg_is_uncor(const PCIEAERMsg *msg) 68 { 69 return msg->severity == PCI_ERR_ROOT_CMD_NONFATAL_EN || 70 msg->severity == PCI_ERR_ROOT_CMD_FATAL_EN; 71 } 72 73 /* error */ 74 struct PCIEAERErr { 75 uint32_t status; /* error status bits */ 76 uint16_t source_id; /* bdf */ 77 78 #define PCIE_AER_ERR_IS_CORRECTABLE 0x1 /* correctable/uncorrectable */ 79 #define PCIE_AER_ERR_MAYBE_ADVISORY 0x2 /* maybe advisory non-fatal */ 80 #define PCIE_AER_ERR_HEADER_VALID 0x4 /* TLP header is logged */ 81 #define PCIE_AER_ERR_TLP_PREFIX_PRESENT 0x8 /* TLP Prefix is logged */ 82 uint16_t flags; 83 84 uint32_t header[4]; /* TLP header */ 85 uint32_t prefix[4]; /* TLP header prefix */ 86 }; 87 88 extern const VMStateDescription vmstate_pcie_aer_log; 89 90 int pcie_aer_init(PCIDevice *dev, uint16_t offset, uint16_t size); 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 /* error injection */ 104 int pcie_aer_inject_error(PCIDevice *dev, const PCIEAERErr *err); 105 void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg); 106 107 #endif /* QEMU_PCIE_AER_H */ 108