Revision 4b78a802 hw/pc.c

b/hw/pc.c
411 411
    qemu_register_reset(pc_cmos_init_late, &arg);
412 412
}
413 413

  
414
/* port 92 stuff: could be split off */
415
typedef struct Port92State {
416
    ISADevice dev;
417
    uint8_t outport;
418
    qemu_irq *a20_out;
419
} Port92State;
420

  
421
static void port92_write(void *opaque, uint32_t addr, uint32_t val)
422
{
423
    Port92State *s = opaque;
424

  
425
    DPRINTF("port92: write 0x%02x\n", val);
426
    s->outport = val;
427
    qemu_set_irq(*s->a20_out, (val >> 1) & 1);
428
    if (val & 1) {
429
        qemu_system_reset_request();
430
    }
431
}
432

  
433
static uint32_t port92_read(void *opaque, uint32_t addr)
434
{
435
    Port92State *s = opaque;
436
    uint32_t ret;
437

  
438
    ret = s->outport;
439
    DPRINTF("port92: read 0x%02x\n", ret);
440
    return ret;
441
}
442

  
443
static void port92_init(ISADevice *dev, qemu_irq *a20_out)
444
{
445
    Port92State *s = DO_UPCAST(Port92State, dev, dev);
446

  
447
    s->a20_out = a20_out;
448
}
449

  
450
static const VMStateDescription vmstate_port92_isa = {
451
    .name = "port92",
452
    .version_id = 1,
453
    .minimum_version_id = 1,
454
    .minimum_version_id_old = 1,
455
    .fields      = (VMStateField []) {
456
        VMSTATE_UINT8(outport, Port92State),
457
        VMSTATE_END_OF_LIST()
458
    }
459
};
460

  
461
static void port92_reset(DeviceState *d)
462
{
463
    Port92State *s = container_of(d, Port92State, dev.qdev);
464

  
465
    s->outport &= ~1;
466
}
467

  
468
static int port92_initfn(ISADevice *dev)
469
{
470
    Port92State *s = DO_UPCAST(Port92State, dev, dev);
471

  
472
    register_ioport_read(0x92, 1, 1, port92_read, s);
473
    register_ioport_write(0x92, 1, 1, port92_write, s);
474
    isa_init_ioport(dev, 0x92);
475
    s->outport = 0;
476
    return 0;
477
}
478

  
479
static ISADeviceInfo port92_info = {
480
    .qdev.name     = "port92",
481
    .qdev.size     = sizeof(Port92State),
482
    .qdev.vmsd     = &vmstate_port92_isa,
483
    .qdev.no_user  = 1,
484
    .qdev.reset    = port92_reset,
485
    .init          = port92_initfn,
486
};
487

  
488
static void port92_register(void)
489
{
490
    isa_qdev_register(&port92_info);
491
}
492
device_init(port92_register)
493

  
414 494
static void handle_a20_line_change(void *opaque, int irq, int level)
415 495
{
416 496
    CPUState *cpu = opaque;
417 497

  
418 498
    /* XXX: send to all CPUs ? */
499
    /* XXX: add logic to handle multiple A20 line sources */
419 500
    cpu_x86_set_a20(cpu, level);
420 501
}
421 502

  
......
1027 1108
    PITState *pit;
1028 1109
    qemu_irq rtc_irq = NULL;
1029 1110
    qemu_irq *a20_line;
1030
    ISADevice *i8042;
1111
    ISADevice *i8042, *port92;
1031 1112
    qemu_irq *cpu_exit_irq;
1032 1113

  
1033 1114
    register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
......
1061 1142
        }
1062 1143
    }
1063 1144

  
1064
    a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 1);
1145
    a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2);
1065 1146
    i8042 = isa_create_simple("i8042");
1066
    i8042_setup_a20_line(i8042, a20_line);
1147
    i8042_setup_a20_line(i8042, &a20_line[0]);
1067 1148
    vmmouse_init(i8042);
1149
    port92 = isa_create_simple("port92");
1150
    port92_init(port92, &a20_line[1]);
1068 1151

  
1069 1152
    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
1070 1153
    DMA_init(0, cpu_exit_irq);

Also available in: Unified diff