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