Revision e9845f09

b/hw/i386/pc_piix.c
339 339
    .desc = "Standard PC (i440FX + PIIX, 1996)", \
340 340
    .hot_add_cpu = pc_hot_add_cpu
341 341

  
342
#define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
343
static QEMUMachine pc_i440fx_machine_v1_7 = {
344
    PC_I440FX_1_7_MACHINE_OPTIONS,
345
    .name = "pc-i440fx-1.7",
346
    .alias = "pc",
347
    .init = pc_init_pci,
348
    .is_default = 1,
349
};
350

  
342 351
#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
343 352

  
344 353
static QEMUMachine pc_i440fx_machine_v1_6 = {
345 354
    PC_I440FX_1_6_MACHINE_OPTIONS,
346 355
    .name = "pc-i440fx-1.6",
347
    .alias = "pc",
348 356
    .init = pc_init_pci_1_6,
349
    .is_default = 1,
357
    .compat_props = (GlobalProperty[]) {
358
        PC_COMPAT_1_6,
359
        { /* end of list */ }
360
    },
350 361
};
351 362

  
352 363
static QEMUMachine pc_i440fx_machine_v1_5 = {
......
735 746

  
736 747
static void pc_machine_init(void)
737 748
{
749
    qemu_register_machine(&pc_i440fx_machine_v1_7);
738 750
    qemu_register_machine(&pc_i440fx_machine_v1_6);
739 751
    qemu_register_machine(&pc_i440fx_machine_v1_5);
740 752
    qemu_register_machine(&pc_i440fx_machine_v1_4);
b/hw/i386/pc_q35.c
258 258
    .desc = "Standard PC (Q35 + ICH9, 2009)", \
259 259
    .hot_add_cpu = pc_hot_add_cpu
260 260

  
261
#define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
262

  
263
static QEMUMachine pc_q35_machine_v1_7 = {
264
    PC_Q35_1_7_MACHINE_OPTIONS,
265
    .name = "pc-q35-1.7",
266
    .alias = "q35",
267
    .init = pc_q35_init,
268
};
269

  
261 270
#define PC_Q35_1_6_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
262 271

  
263 272
static QEMUMachine pc_q35_machine_v1_6 = {
264 273
    PC_Q35_1_6_MACHINE_OPTIONS,
265 274
    .name = "pc-q35-1.6",
266
    .alias = "q35",
267 275
    .init = pc_q35_init_1_6,
276
    .compat_props = (GlobalProperty[]) {
277
        PC_COMPAT_1_6,
278
        { /* end of list */ }
279
    },
268 280
};
269 281

  
270 282
static QEMUMachine pc_q35_machine_v1_5 = {
......
293 305

  
294 306
static void pc_q35_machine_init(void)
295 307
{
308
    qemu_register_machine(&pc_q35_machine_v1_7);
296 309
    qemu_register_machine(&pc_q35_machine_v1_6);
297 310
    qemu_register_machine(&pc_q35_machine_v1_5);
298 311
    qemu_register_machine(&pc_q35_machine_v1_4);
b/hw/net/e1000.c
135 135

  
136 136
    QEMUTimer *autoneg_timer;
137 137

  
138
    QEMUTimer *mit_timer;      /* Mitigation timer. */
139
    bool mit_timer_on;         /* Mitigation timer is running. */
140
    bool mit_irq_level;        /* Tracks interrupt pin level. */
141
    uint32_t mit_ide;          /* Tracks E1000_TXD_CMD_IDE bit. */
142

  
138 143
/* Compatibility flags for migration to/from qemu 1.3.0 and older */
139 144
#define E1000_FLAG_AUTONEG_BIT 0
145
#define E1000_FLAG_MIT_BIT 1
140 146
#define E1000_FLAG_AUTONEG (1 << E1000_FLAG_AUTONEG_BIT)
147
#define E1000_FLAG_MIT (1 << E1000_FLAG_MIT_BIT)
141 148
    uint32_t compat_flags;
142 149
} E1000State;
143 150

  
......
158 165
    defreg(TORH),	defreg(TORL),	defreg(TOTH),	defreg(TOTL),
159 166
    defreg(TPR),	defreg(TPT),	defreg(TXDCTL),	defreg(WUFC),
160 167
    defreg(RA),		defreg(MTA),	defreg(CRCERRS),defreg(VFTA),
161
    defreg(VET),
168
    defreg(VET),        defreg(RDTR),   defreg(RADV),   defreg(TADV),
169
    defreg(ITR),
162 170
};
163 171

  
164 172
static void
......
245 253
                E1000_MANC_RMCP_EN,
246 254
};
247 255

  
256
/* Helper function, *curr == 0 means the value is not set */
257
static inline void
258
mit_update_delay(uint32_t *curr, uint32_t value)
259
{
260
    if (value && (*curr == 0 || value < *curr)) {
261
        *curr = value;
262
    }
263
}
264

  
248 265
static void
249 266
set_interrupt_cause(E1000State *s, int index, uint32_t val)
250 267
{
251 268
    PCIDevice *d = PCI_DEVICE(s);
269
    uint32_t pending_ints;
270
    uint32_t mit_delay;
252 271

  
253 272
    if (val && (E1000_DEVID >= E1000_DEV_ID_82547EI_MOBILE)) {
254 273
        /* Only for 8257x */
......
266 285
     */
267 286
    s->mac_reg[ICS] = val;
268 287

  
269
    qemu_set_irq(d->irq[0], (s->mac_reg[IMS] & s->mac_reg[ICR]) != 0);
288
    pending_ints = (s->mac_reg[IMS] & s->mac_reg[ICR]);
289
    if (!s->mit_irq_level && pending_ints) {
290
        /*
291
         * Here we detect a potential raising edge. We postpone raising the
292
         * interrupt line if we are inside the mitigation delay window
293
         * (s->mit_timer_on == 1).
294
         * We provide a partial implementation of interrupt mitigation,
295
         * emulating only RADV, TADV and ITR (lower 16 bits, 1024ns units for
296
         * RADV and TADV, 256ns units for ITR). RDTR is only used to enable
297
         * RADV; relative timers based on TIDV and RDTR are not implemented.
298
         */
299
        if (s->mit_timer_on) {
300
            return;
301
        }
302
        if (s->compat_flags & E1000_FLAG_MIT) {
303
            /* Compute the next mitigation delay according to pending
304
             * interrupts and the current values of RADV (provided
305
             * RDTR!=0), TADV and ITR.
306
             * Then rearm the timer.
307
             */
308
            mit_delay = 0;
309
            if (s->mit_ide &&
310
                    (pending_ints & (E1000_ICR_TXQE | E1000_ICR_TXDW))) {
311
                mit_update_delay(&mit_delay, s->mac_reg[TADV] * 4);
312
            }
313
            if (s->mac_reg[RDTR] && (pending_ints & E1000_ICS_RXT0)) {
314
                mit_update_delay(&mit_delay, s->mac_reg[RADV] * 4);
315
            }
316
            mit_update_delay(&mit_delay, s->mac_reg[ITR]);
317

  
318
            if (mit_delay) {
319
                s->mit_timer_on = 1;
320
                timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
321
                          mit_delay * 256);
322
            }
323
            s->mit_ide = 0;
324
        }
325
    }
326

  
327
    s->mit_irq_level = (pending_ints != 0);
328
    qemu_set_irq(d->irq[0], s->mit_irq_level);
329
}
330

  
331
static void
332
e1000_mit_timer(void *opaque)
333
{
334
    E1000State *s = opaque;
335

  
336
    s->mit_timer_on = 0;
337
    /* Call set_interrupt_cause to update the irq level (if necessary). */
338
    set_interrupt_cause(s, 0, s->mac_reg[ICR]);
270 339
}
271 340

  
272 341
static void
......
307 376
    int i;
308 377

  
309 378
    timer_del(d->autoneg_timer);
379
    timer_del(d->mit_timer);
380
    d->mit_timer_on = 0;
381
    d->mit_irq_level = 0;
382
    d->mit_ide = 0;
310 383
    memset(d->phy_reg, 0, sizeof d->phy_reg);
311 384
    memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init);
312 385
    memset(d->mac_reg, 0, sizeof d->mac_reg);
......
572 645
    struct e1000_context_desc *xp = (struct e1000_context_desc *)dp;
573 646
    struct e1000_tx *tp = &s->tx;
574 647

  
648
    s->mit_ide |= (txd_lower & E1000_TXD_CMD_IDE);
575 649
    if (dtype == E1000_TXD_CMD_DEXT) {	// context descriptor
576 650
        op = le32_to_cpu(xp->cmd_and_length);
577 651
        tp->ipcss = xp->lower_setup.ip_fields.ipcss;
......
1047 1121
    getreg(TORL),	getreg(TOTL),	getreg(IMS),	getreg(TCTL),
1048 1122
    getreg(RDH),	getreg(RDT),	getreg(VET),	getreg(ICS),
1049 1123
    getreg(TDBAL),	getreg(TDBAH),	getreg(RDBAH),	getreg(RDBAL),
1050
    getreg(TDLEN),	getreg(RDLEN),
1124
    getreg(TDLEN),      getreg(RDLEN),  getreg(RDTR),   getreg(RADV),
1125
    getreg(TADV),       getreg(ITR),
1051 1126

  
1052 1127
    [TOTH] = mac_read_clr8,	[TORH] = mac_read_clr8,	[GPRC] = mac_read_clr4,
1053 1128
    [GPTC] = mac_read_clr4,	[TPR] = mac_read_clr4,	[TPT] = mac_read_clr4,
......
1069 1144
    [TDH] = set_16bit,	[RDH] = set_16bit,	[RDT] = set_rdt,
1070 1145
    [IMC] = set_imc,	[IMS] = set_ims,	[ICR] = set_icr,
1071 1146
    [EECD] = set_eecd,	[RCTL] = set_rx_control, [CTRL] = set_ctrl,
1147
    [RDTR] = set_16bit, [RADV] = set_16bit,     [TADV] = set_16bit,
1148
    [ITR] = set_16bit,
1072 1149
    [RA ... RA+31] = &mac_writereg,
1073 1150
    [MTA ... MTA+127] = &mac_writereg,
1074 1151
    [VFTA ... VFTA+127] = &mac_writereg,
......
1150 1227
    E1000State *s = opaque;
1151 1228
    NetClientState *nc = qemu_get_queue(s->nic);
1152 1229

  
1230
    /* If the mitigation timer is active, emulate a timeout now. */
1231
    if (s->mit_timer_on) {
1232
        e1000_mit_timer(s);
1233
    }
1234

  
1153 1235
    if (!(s->compat_flags & E1000_FLAG_AUTONEG)) {
1154 1236
        return;
1155 1237
    }
......
1171 1253
    E1000State *s = opaque;
1172 1254
    NetClientState *nc = qemu_get_queue(s->nic);
1173 1255

  
1256
    if (!(s->compat_flags & E1000_FLAG_MIT)) {
1257
        s->mac_reg[ITR] = s->mac_reg[RDTR] = s->mac_reg[RADV] =
1258
            s->mac_reg[TADV] = 0;
1259
        s->mit_irq_level = false;
1260
    }
1261
    s->mit_ide = 0;
1262
    s->mit_timer_on = false;
1263

  
1174 1264
    /* nc.link_down can't be migrated, so infer link_down according
1175 1265
     * to link status bit in mac_reg[STATUS].
1176 1266
     * Alternatively, restart link negotiation if it was in progress. */
......
1190 1280
    return 0;
1191 1281
}
1192 1282

  
1283
static bool e1000_mit_state_needed(void *opaque)
1284
{
1285
    E1000State *s = opaque;
1286

  
1287
    return s->compat_flags & E1000_FLAG_MIT;
1288
}
1289

  
1290
static const VMStateDescription vmstate_e1000_mit_state = {
1291
    .name = "e1000/mit_state",
1292
    .version_id = 1,
1293
    .minimum_version_id = 1,
1294
    .minimum_version_id_old = 1,
1295
    .fields    = (VMStateField[]) {
1296
        VMSTATE_UINT32(mac_reg[RDTR], E1000State),
1297
        VMSTATE_UINT32(mac_reg[RADV], E1000State),
1298
        VMSTATE_UINT32(mac_reg[TADV], E1000State),
1299
        VMSTATE_UINT32(mac_reg[ITR], E1000State),
1300
        VMSTATE_BOOL(mit_irq_level, E1000State),
1301
        VMSTATE_END_OF_LIST()
1302
    }
1303
};
1304

  
1193 1305
static const VMStateDescription vmstate_e1000 = {
1194 1306
    .name = "e1000",
1195 1307
    .version_id = 2,
......
1267 1379
        VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, MTA, 128),
1268 1380
        VMSTATE_UINT32_SUB_ARRAY(mac_reg, E1000State, VFTA, 128),
1269 1381
        VMSTATE_END_OF_LIST()
1382
    },
1383
    .subsections = (VMStateSubsection[]) {
1384
        {
1385
            .vmsd = &vmstate_e1000_mit_state,
1386
            .needed = e1000_mit_state_needed,
1387
        }, {
1388
            /* empty */
1389
        }
1270 1390
    }
1271 1391
};
1272 1392

  
......
1316 1436

  
1317 1437
    timer_del(d->autoneg_timer);
1318 1438
    timer_free(d->autoneg_timer);
1439
    timer_del(d->mit_timer);
1440
    timer_free(d->mit_timer);
1319 1441
    memory_region_destroy(&d->mmio);
1320 1442
    memory_region_destroy(&d->io);
1321 1443
    qemu_del_nic(d->nic);
......
1371 1493
    add_boot_device_path(d->conf.bootindex, dev, "/ethernet-phy@0");
1372 1494

  
1373 1495
    d->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, e1000_autoneg_timer, d);
1496
    d->mit_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000_mit_timer, d);
1374 1497

  
1375 1498
    return 0;
1376 1499
}
......
1385 1508
    DEFINE_NIC_PROPERTIES(E1000State, conf),
1386 1509
    DEFINE_PROP_BIT("autonegotiation", E1000State,
1387 1510
                    compat_flags, E1000_FLAG_AUTONEG_BIT, true),
1511
    DEFINE_PROP_BIT("mitigation", E1000State,
1512
                    compat_flags, E1000_FLAG_MIT_BIT, true),
1388 1513
    DEFINE_PROP_END_OF_LIST(),
1389 1514
};
1390 1515

  
b/include/hw/i386/pc.h
225 225

  
226 226
int e820_add_entry(uint64_t, uint64_t, uint32_t);
227 227

  
228
#define PC_COMPAT_1_6 \
229
        {\
230
            .driver   = "e1000",\
231
            .property = "mitigation",\
232
            .value    = "off",\
233
        }
234

  
228 235
#define PC_COMPAT_1_5 \
236
        PC_COMPAT_1_6, \
229 237
        {\
230 238
            .driver   = "Conroe-" TYPE_X86_CPU,\
231 239
            .property = "model",\

Also available in: Unified diff