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 */ 29struct 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 */ 56struct 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 66static inline bool 67pcie_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 */ 74struct 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 88extern const VMStateDescription vmstate_pcie_aer_log; 89 90int pcie_aer_init(PCIDevice *dev, uint16_t offset, uint16_t size); 91void pcie_aer_exit(PCIDevice *dev); 92void pcie_aer_write_config(PCIDevice *dev, 93 uint32_t addr, uint32_t val, int len); 94 95/* aer root port */ 96void pcie_aer_root_set_vector(PCIDevice *dev, unsigned int vector); 97void pcie_aer_root_init(PCIDevice *dev); 98void pcie_aer_root_reset(PCIDevice *dev); 99void 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 */ 104int pcie_aer_inject_error(PCIDevice *dev, const PCIEAERErr *err); 105void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg); 106 107#endif /* QEMU_PCIE_AER_H */ 108