10d09e41aSPaolo Bonzini /* 20d09e41aSPaolo Bonzini * pcie_aer.h 30d09e41aSPaolo Bonzini * 40d09e41aSPaolo Bonzini * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp> 50d09e41aSPaolo Bonzini * VA Linux Systems Japan K.K. 60d09e41aSPaolo Bonzini * 70d09e41aSPaolo Bonzini * This program is free software; you can redistribute it and/or modify 80d09e41aSPaolo Bonzini * it under the terms of the GNU General Public License as published by 90d09e41aSPaolo Bonzini * the Free Software Foundation; either version 2 of the License, or 100d09e41aSPaolo Bonzini * (at your option) any later version. 110d09e41aSPaolo Bonzini * 120d09e41aSPaolo Bonzini * This program is distributed in the hope that it will be useful, 130d09e41aSPaolo Bonzini * but WITHOUT ANY WARRANTY; without even the implied warranty of 140d09e41aSPaolo Bonzini * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 150d09e41aSPaolo Bonzini * GNU General Public License for more details. 160d09e41aSPaolo Bonzini * 170d09e41aSPaolo Bonzini * You should have received a copy of the GNU General Public License along 180d09e41aSPaolo Bonzini * with this program; if not, see <http://www.gnu.org/licenses/>. 190d09e41aSPaolo Bonzini */ 200d09e41aSPaolo Bonzini 210d09e41aSPaolo Bonzini #ifndef QEMU_PCIE_AER_H 220d09e41aSPaolo Bonzini #define QEMU_PCIE_AER_H 230d09e41aSPaolo Bonzini 240d09e41aSPaolo Bonzini #include "hw/hw.h" 250d09e41aSPaolo Bonzini 260d09e41aSPaolo Bonzini /* definitions which PCIExpressDevice uses */ 270d09e41aSPaolo Bonzini 280d09e41aSPaolo Bonzini /* AER log */ 290d09e41aSPaolo Bonzini struct PCIEAERLog { 300d09e41aSPaolo Bonzini /* This structure is saved/loaded. 310d09e41aSPaolo Bonzini So explicitly size them instead of unsigned int */ 320d09e41aSPaolo Bonzini 330d09e41aSPaolo Bonzini /* the number of currently recorded log in log member */ 340d09e41aSPaolo Bonzini uint16_t log_num; 350d09e41aSPaolo Bonzini 360d09e41aSPaolo Bonzini /* 370d09e41aSPaolo Bonzini * The maximum number of the log. Errors can be logged up to this. 380d09e41aSPaolo Bonzini * 390d09e41aSPaolo Bonzini * This is configurable property. 400d09e41aSPaolo Bonzini * The specified value will be clipped down to PCIE_AER_LOG_MAX_LIMIT 410d09e41aSPaolo Bonzini * to avoid unreasonable memory usage. 420d09e41aSPaolo Bonzini * I bet that 128 log size would be big enough, otherwise too many errors 430d09e41aSPaolo Bonzini * for system to function normaly. But could consecutive errors occur? 440d09e41aSPaolo Bonzini */ 450d09e41aSPaolo Bonzini #define PCIE_AER_LOG_MAX_DEFAULT 8 460d09e41aSPaolo Bonzini #define PCIE_AER_LOG_MAX_LIMIT 128 470d09e41aSPaolo Bonzini #define PCIE_AER_LOG_MAX_UNSET 0xffff 480d09e41aSPaolo Bonzini uint16_t log_max; 490d09e41aSPaolo Bonzini 500d09e41aSPaolo Bonzini /* Error log. log_max-sized array */ 510d09e41aSPaolo Bonzini PCIEAERErr *log; 520d09e41aSPaolo Bonzini }; 530d09e41aSPaolo Bonzini 54*98a2f30aSChen Fan /* aer error message: error signaling message has only error severity and 550d09e41aSPaolo Bonzini source id. See 2.2.8.3 error signaling messages */ 560d09e41aSPaolo Bonzini struct PCIEAERMsg { 570d09e41aSPaolo Bonzini /* 580d09e41aSPaolo Bonzini * PCI_ERR_ROOT_CMD_{COR, NONFATAL, FATAL}_EN 590d09e41aSPaolo Bonzini * = PCI_EXP_DEVCTL_{CERE, NFERE, FERE} 600d09e41aSPaolo Bonzini */ 610d09e41aSPaolo Bonzini uint32_t severity; 620d09e41aSPaolo Bonzini 630d09e41aSPaolo Bonzini uint16_t source_id; /* bdf */ 640d09e41aSPaolo Bonzini }; 650d09e41aSPaolo Bonzini 660d09e41aSPaolo Bonzini static inline bool 670d09e41aSPaolo Bonzini pcie_aer_msg_is_uncor(const PCIEAERMsg *msg) 680d09e41aSPaolo Bonzini { 690d09e41aSPaolo Bonzini return msg->severity == PCI_ERR_ROOT_CMD_NONFATAL_EN || 700d09e41aSPaolo Bonzini msg->severity == PCI_ERR_ROOT_CMD_FATAL_EN; 710d09e41aSPaolo Bonzini } 720d09e41aSPaolo Bonzini 730d09e41aSPaolo Bonzini /* error */ 740d09e41aSPaolo Bonzini struct PCIEAERErr { 750d09e41aSPaolo Bonzini uint32_t status; /* error status bits */ 760d09e41aSPaolo Bonzini uint16_t source_id; /* bdf */ 770d09e41aSPaolo Bonzini 780d09e41aSPaolo Bonzini #define PCIE_AER_ERR_IS_CORRECTABLE 0x1 /* correctable/uncorrectable */ 790d09e41aSPaolo Bonzini #define PCIE_AER_ERR_MAYBE_ADVISORY 0x2 /* maybe advisory non-fatal */ 800d09e41aSPaolo Bonzini #define PCIE_AER_ERR_HEADER_VALID 0x4 /* TLP header is logged */ 810d09e41aSPaolo Bonzini #define PCIE_AER_ERR_TLP_PREFIX_PRESENT 0x8 /* TLP Prefix is logged */ 820d09e41aSPaolo Bonzini uint16_t flags; 830d09e41aSPaolo Bonzini 840d09e41aSPaolo Bonzini uint32_t header[4]; /* TLP header */ 850d09e41aSPaolo Bonzini uint32_t prefix[4]; /* TLP header prefix */ 860d09e41aSPaolo Bonzini }; 870d09e41aSPaolo Bonzini 880d09e41aSPaolo Bonzini extern const VMStateDescription vmstate_pcie_aer_log; 890d09e41aSPaolo Bonzini 900d09e41aSPaolo Bonzini int pcie_aer_init(PCIDevice *dev, uint16_t offset); 910d09e41aSPaolo Bonzini void pcie_aer_exit(PCIDevice *dev); 920d09e41aSPaolo Bonzini void pcie_aer_write_config(PCIDevice *dev, 930d09e41aSPaolo Bonzini uint32_t addr, uint32_t val, int len); 940d09e41aSPaolo Bonzini 950d09e41aSPaolo Bonzini /* aer root port */ 960d09e41aSPaolo Bonzini void pcie_aer_root_set_vector(PCIDevice *dev, unsigned int vector); 970d09e41aSPaolo Bonzini void pcie_aer_root_init(PCIDevice *dev); 980d09e41aSPaolo Bonzini void pcie_aer_root_reset(PCIDevice *dev); 990d09e41aSPaolo Bonzini void pcie_aer_root_write_config(PCIDevice *dev, 1000d09e41aSPaolo Bonzini uint32_t addr, uint32_t val, int len, 1010d09e41aSPaolo Bonzini uint32_t root_cmd_prev); 1020d09e41aSPaolo Bonzini 1030d09e41aSPaolo Bonzini /* error injection */ 1040d09e41aSPaolo Bonzini int pcie_aer_inject_error(PCIDevice *dev, const PCIEAERErr *err); 1050d09e41aSPaolo Bonzini 1060d09e41aSPaolo Bonzini #endif /* QEMU_PCIE_AER_H */ 107