Revision 61620c2f

b/hw/ioh3420.c
36 36
#define IOH_EP_EXP_OFFSET               0x90
37 37
#define IOH_EP_AER_OFFSET               0x100
38 38

  
39
/*
40
 * If two MSI vector are allocated, Advanced Error Interrupt Message Number
41
 * is 1. otherwise 0.
42
 * 17.12.5.10 RPERRSTS,  32:27 bit Advanced Error Interrupt Message Number.
43
 */
44
static uint8_t ioh3420_aer_vector(const PCIDevice *d)
45
{
46
    switch (msi_nr_vectors_allocated(d)) {
47
    case 1:
48
        return 0;
49
    case 2:
50
        return 1;
51
    case 4:
52
    case 8:
53
    case 16:
54
    case 32:
55
    default:
56
        break;
57
    }
58
    abort();
59
    return 0;
60
}
61

  
62
static void ioh3420_aer_vector_update(PCIDevice *d)
63
{
64
    pcie_aer_root_set_vector(d, ioh3420_aer_vector(d));
65
}
66

  
39 67
static void ioh3420_write_config(PCIDevice *d,
40 68
                                   uint32_t address, uint32_t val, int len)
41 69
{
70
    uint32_t root_cmd =
71
        pci_get_long(d->config + d->exp.aer_cap + PCI_ERR_ROOT_COMMAND);
72

  
42 73
    pci_bridge_write_config(d, address, val, len);
43 74
    msi_write_config(d, address, val, len);
75
    ioh3420_aer_vector_update(d);
44 76
    pcie_cap_slot_write_config(d, address, val, len);
45
    /* TODO: AER */
77
    pcie_aer_write_config(d, address, val, len);
78
    pcie_aer_root_write_config(d, address, val, len, root_cmd);
46 79
}
47 80

  
48 81
static void ioh3420_reset(DeviceState *qdev)
49 82
{
50 83
    PCIDevice *d = DO_UPCAST(PCIDevice, qdev, qdev);
51 84
    msi_reset(d);
85
    ioh3420_aer_vector_update(d);
52 86
    pcie_cap_root_reset(d);
53 87
    pcie_cap_deverr_reset(d);
54 88
    pcie_cap_slot_reset(d);
89
    pcie_aer_root_reset(d);
55 90
    pci_bridge_reset(qdev);
56 91
    pci_bridge_disable_base_limit(d);
57
    /* TODO: AER */
58 92
}
59 93

  
60 94
static int ioh3420_initfn(PCIDevice *d)
......
63 97
    PCIEPort *p = DO_UPCAST(PCIEPort, br, br);
64 98
    PCIESlot *s = DO_UPCAST(PCIESlot, port, p);
65 99
    int rc;
100
    int tmp;
66 101

  
67 102
    rc = pci_bridge_initfn(d);
68 103
    if (rc < 0) {
......
78 113
    rc = pci_bridge_ssvid_init(d, IOH_EP_SSVID_OFFSET,
79 114
                               IOH_EP_SSVID_SVID, IOH_EP_SSVID_SSID);
80 115
    if (rc < 0) {
81
        return rc;
116
        goto err_bridge;
82 117
    }
83 118
    rc = msi_init(d, IOH_EP_MSI_OFFSET, IOH_EP_MSI_NR_VECTOR,
84 119
                  IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
85 120
                  IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT);
86 121
    if (rc < 0) {
87
        return rc;
122
        goto err_bridge;
88 123
    }
89 124
    rc = pcie_cap_init(d, IOH_EP_EXP_OFFSET, PCI_EXP_TYPE_ROOT_PORT, p->port);
90 125
    if (rc < 0) {
91
        return rc;
126
        goto err_msi;
92 127
    }
93 128
    pcie_cap_deverr_init(d);
94 129
    pcie_cap_slot_init(d, s->slot);
95 130
    pcie_chassis_create(s->chassis);
96 131
    rc = pcie_chassis_add_slot(s);
97 132
    if (rc < 0) {
133
        goto err_pcie_cap;
98 134
        return rc;
99 135
    }
100 136
    pcie_cap_root_init(d);
101
    /* TODO: AER */
137
    rc = pcie_aer_init(d, IOH_EP_AER_OFFSET);
138
    if (rc < 0) {
139
        goto err;
140
    }
141
    pcie_aer_root_init(d);
142
    ioh3420_aer_vector_update(d);
102 143
    return 0;
144

  
145
err:
146
    pcie_chassis_del_slot(s);
147
err_pcie_cap:
148
    pcie_cap_exit(d);
149
err_msi:
150
    msi_uninit(d);
151
err_bridge:
152
    tmp = pci_bridge_exitfn(d);
153
    assert(!tmp);
154
    return rc;
103 155
}
104 156

  
105 157
static int ioh3420_exitfn(PCIDevice *d)
106 158
{
107
    /* TODO: AER */
108
    msi_uninit(d);
159
    PCIBridge* br = DO_UPCAST(PCIBridge, dev, d);
160
    PCIEPort *p = DO_UPCAST(PCIEPort, br, br);
161
    PCIESlot *s = DO_UPCAST(PCIESlot, port, p);
162

  
163
    pcie_aer_exit(d);
164
    pcie_chassis_del_slot(s);
109 165
    pcie_cap_exit(d);
166
    msi_uninit(d);
110 167
    return pci_bridge_exitfn(d);
111 168
}
112 169

  
......
142 199
    .post_load = pcie_cap_slot_post_load,
143 200
    .fields = (VMStateField[]) {
144 201
        VMSTATE_PCIE_DEVICE(port.br.dev, PCIESlot),
145
        /* TODO: AER */
202
        VMSTATE_STRUCT(port.br.dev.exp.aer_log, PCIESlot, 0,
203
                       vmstate_pcie_aer_log, PCIEAERLog),
146 204
        VMSTATE_END_OF_LIST()
147 205
    }
148 206
};
......
164 222
        DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0),
165 223
        DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
166 224
        DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
167
        /* TODO: AER */
225
        DEFINE_PROP_UINT16("aer_log_max", PCIESlot,
226
                           port.br.dev.exp.aer_log.log_max,
227
                           PCIE_AER_LOG_MAX_DEFAULT),
168 228
        DEFINE_PROP_END_OF_LIST(),
169 229
    }
170 230
};

Also available in: Unified diff