mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-11 03:24:58 -06:00
io port API change
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@664 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
c4b1fcc0f9
commit
b41a2cd1e4
7 changed files with 192 additions and 157 deletions
10
hw/i8254.c
10
hw/i8254.c
|
@ -201,7 +201,7 @@ static inline void pit_load_count(PITChannelState *s, int val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pit_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
int channel, access;
|
int channel, access;
|
||||||
PITChannelState *s;
|
PITChannelState *s;
|
||||||
|
@ -246,7 +246,7 @@ void pit_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t pit_ioport_read(CPUState *env, uint32_t addr)
|
static uint32_t pit_ioport_read(void *opaque, uint32_t addr)
|
||||||
{
|
{
|
||||||
int ret, count;
|
int ret, count;
|
||||||
PITChannelState *s;
|
PITChannelState *s;
|
||||||
|
@ -279,7 +279,7 @@ uint32_t pit_ioport_read(CPUState *env, uint32_t addr)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pit_init(void)
|
void pit_init(int base)
|
||||||
{
|
{
|
||||||
PITChannelState *s;
|
PITChannelState *s;
|
||||||
int i;
|
int i;
|
||||||
|
@ -291,7 +291,7 @@ void pit_init(void)
|
||||||
pit_load_count(s, 0);
|
pit_load_count(s, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
register_ioport_write(0x40, 4, pit_ioport_write, 1);
|
register_ioport_write(base, 4, 1, pit_ioport_write, NULL);
|
||||||
register_ioport_read(0x40, 3, pit_ioport_read, 1);
|
register_ioport_read(base, 3, 1, pit_ioport_read, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
hw/i8259.c
22
hw/i8259.c
|
@ -46,6 +46,8 @@
|
||||||
/* debug PIC */
|
/* debug PIC */
|
||||||
//#define DEBUG_PIC
|
//#define DEBUG_PIC
|
||||||
|
|
||||||
|
//#define DEBUG_IRQ_LATENCY
|
||||||
|
|
||||||
typedef struct PicState {
|
typedef struct PicState {
|
||||||
uint8_t last_irr; /* edge detection */
|
uint8_t last_irr; /* edge detection */
|
||||||
uint8_t irr; /* interrupt request register */
|
uint8_t irr; /* interrupt request register */
|
||||||
|
@ -220,15 +222,14 @@ int cpu_x86_get_pic_interrupt(CPUState *env)
|
||||||
return intno;
|
return intno;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
PicState *s;
|
PicState *s = opaque;
|
||||||
int priority, cmd, irq;
|
int priority, cmd, irq;
|
||||||
|
|
||||||
#ifdef DEBUG_PIC
|
#ifdef DEBUG_PIC
|
||||||
printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val);
|
printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val);
|
||||||
#endif
|
#endif
|
||||||
s = &pics[addr >> 7];
|
|
||||||
addr &= 1;
|
addr &= 1;
|
||||||
if (addr == 0) {
|
if (addr == 0) {
|
||||||
if (val & 0x10) {
|
if (val & 0x10) {
|
||||||
|
@ -334,14 +335,13 @@ static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t pic_ioport_read(CPUState *env, uint32_t addr1)
|
static uint32_t pic_ioport_read(void *opaque, uint32_t addr1)
|
||||||
{
|
{
|
||||||
PicState *s;
|
PicState *s = opaque;
|
||||||
unsigned int addr;
|
unsigned int addr;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
addr = addr1;
|
addr = addr1;
|
||||||
s = &pics[addr >> 7];
|
|
||||||
addr &= 1;
|
addr &= 1;
|
||||||
if (s->poll) {
|
if (s->poll) {
|
||||||
ret = pic_poll_read(s, addr1);
|
ret = pic_poll_read(s, addr1);
|
||||||
|
@ -378,11 +378,9 @@ uint32_t pic_intack_read(CPUState *env)
|
||||||
|
|
||||||
void pic_init(void)
|
void pic_init(void)
|
||||||
{
|
{
|
||||||
#if defined (TARGET_I386) || defined (TARGET_PPC)
|
register_ioport_write(0x20, 2, 1, pic_ioport_write, &pics[0]);
|
||||||
register_ioport_write(0x20, 2, pic_ioport_write, 1);
|
register_ioport_read(0x20, 2, 1, pic_ioport_read, &pics[0]);
|
||||||
register_ioport_read(0x20, 2, pic_ioport_read, 1);
|
register_ioport_write(0xa0, 2, 1, pic_ioport_write, &pics[1]);
|
||||||
register_ioport_write(0xa0, 2, pic_ioport_write, 1);
|
register_ioport_read(0xa0, 2, 1, pic_ioport_read, &pics[1]);
|
||||||
register_ioport_read(0xa0, 2, pic_ioport_read, 1);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,9 +69,9 @@
|
||||||
|
|
||||||
RTCState rtc_state;
|
RTCState rtc_state;
|
||||||
|
|
||||||
static void cmos_ioport_write(CPUState *env, uint32_t addr, uint32_t data)
|
static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
|
||||||
{
|
{
|
||||||
RTCState *s = &rtc_state;
|
RTCState *s = opaque;
|
||||||
|
|
||||||
if ((addr & 1) == 0) {
|
if ((addr & 1) == 0) {
|
||||||
s->cmos_index = data & 0x7f;
|
s->cmos_index = data & 0x7f;
|
||||||
|
@ -134,9 +134,9 @@ static void cmos_update_time(RTCState *s)
|
||||||
s->cmos_data[REG_IBM_PS2_CENTURY_BYTE] = s->cmos_data[REG_IBM_CENTURY_BYTE];
|
s->cmos_data[REG_IBM_PS2_CENTURY_BYTE] = s->cmos_data[REG_IBM_CENTURY_BYTE];
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t cmos_ioport_read(CPUState *env, uint32_t addr)
|
static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
|
||||||
{
|
{
|
||||||
RTCState *s = &rtc_state;
|
RTCState *s = opaque;
|
||||||
int ret;
|
int ret;
|
||||||
if ((addr & 1) == 0) {
|
if ((addr & 1) == 0) {
|
||||||
return 0xff;
|
return 0xff;
|
||||||
|
@ -197,7 +197,7 @@ void rtc_init(int base, int irq)
|
||||||
s->cmos_data[RTC_REG_C] = 0x00;
|
s->cmos_data[RTC_REG_C] = 0x00;
|
||||||
s->cmos_data[RTC_REG_D] = 0x80;
|
s->cmos_data[RTC_REG_D] = 0x80;
|
||||||
|
|
||||||
register_ioport_write(base, 2, cmos_ioport_write, 1);
|
register_ioport_write(base, 2, 1, cmos_ioport_write, s);
|
||||||
register_ioport_read(base, 2, cmos_ioport_read, 1);
|
register_ioport_read(base, 2, 1, cmos_ioport_read, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
90
hw/ne2000.c
90
hw/ne2000.c
|
@ -46,8 +46,7 @@
|
||||||
/* debug NE2000 card */
|
/* debug NE2000 card */
|
||||||
//#define DEBUG_NE2000
|
//#define DEBUG_NE2000
|
||||||
|
|
||||||
/***********************************************************/
|
#define MAX_ETH_FRAME_SIZE 1514
|
||||||
/* ne2000 emulation */
|
|
||||||
|
|
||||||
#define E8390_CMD 0x00 /* The command register (for all pages) */
|
#define E8390_CMD 0x00 /* The command register (for all pages) */
|
||||||
/* Page 0 register offsets. */
|
/* Page 0 register offsets. */
|
||||||
|
@ -143,23 +142,16 @@ typedef struct NE2000State {
|
||||||
uint8_t curpag;
|
uint8_t curpag;
|
||||||
uint8_t mult[8]; /* multicast mask array */
|
uint8_t mult[8]; /* multicast mask array */
|
||||||
int irq;
|
int irq;
|
||||||
|
NetDriverState *nd;
|
||||||
uint8_t mem[NE2000_MEM_SIZE];
|
uint8_t mem[NE2000_MEM_SIZE];
|
||||||
} NE2000State;
|
} NE2000State;
|
||||||
|
|
||||||
static NE2000State ne2000_state;
|
|
||||||
int net_fd = -1;
|
|
||||||
|
|
||||||
static void ne2000_reset(NE2000State *s)
|
static void ne2000_reset(NE2000State *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
s->isr = ENISR_RESET;
|
s->isr = ENISR_RESET;
|
||||||
s->mem[0] = 0x52;
|
memcpy(s->mem, s->nd->macaddr, 6);
|
||||||
s->mem[1] = 0x54;
|
|
||||||
s->mem[2] = 0x00;
|
|
||||||
s->mem[3] = 0x12;
|
|
||||||
s->mem[4] = 0x34;
|
|
||||||
s->mem[5] = 0x56;
|
|
||||||
s->mem[14] = 0x57;
|
s->mem[14] = 0x57;
|
||||||
s->mem[15] = 0x57;
|
s->mem[15] = 0x57;
|
||||||
|
|
||||||
|
@ -180,10 +172,10 @@ static void ne2000_update_irq(NE2000State *s)
|
||||||
pic_set_irq(s->irq, 0);
|
pic_set_irq(s->irq, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return true if the NE2000 can receive more data */
|
/* return the max buffer size if the NE2000 can receive more data */
|
||||||
int ne2000_can_receive(void)
|
static int ne2000_can_receive(void *opaque)
|
||||||
{
|
{
|
||||||
NE2000State *s = &ne2000_state;
|
NE2000State *s = opaque;
|
||||||
int avail, index, boundary;
|
int avail, index, boundary;
|
||||||
|
|
||||||
if (s->cmd & E8390_STOP)
|
if (s->cmd & E8390_STOP)
|
||||||
|
@ -196,19 +188,30 @@ int ne2000_can_receive(void)
|
||||||
avail = (s->stop - s->start) - (index - boundary);
|
avail = (s->stop - s->start) - (index - boundary);
|
||||||
if (avail < (MAX_ETH_FRAME_SIZE + 4))
|
if (avail < (MAX_ETH_FRAME_SIZE + 4))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return MAX_ETH_FRAME_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ne2000_receive(uint8_t *buf, int size)
|
#define MIN_BUF_SIZE 60
|
||||||
|
|
||||||
|
static void ne2000_receive(void *opaque, const uint8_t *buf, int size)
|
||||||
{
|
{
|
||||||
NE2000State *s = &ne2000_state;
|
NE2000State *s = opaque;
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
int total_len, next, avail, len, index;
|
int total_len, next, avail, len, index;
|
||||||
|
uint8_t buf1[60];
|
||||||
|
|
||||||
#if defined(DEBUG_NE2000)
|
#if defined(DEBUG_NE2000)
|
||||||
printf("NE2000: received len=%d\n", size);
|
printf("NE2000: received len=%d\n", size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* if too small buffer, then expand it */
|
||||||
|
if (size < MIN_BUF_SIZE) {
|
||||||
|
memcpy(buf1, buf, size);
|
||||||
|
memset(buf1 + size, 0, MIN_BUF_SIZE - size);
|
||||||
|
buf = buf1;
|
||||||
|
size = MIN_BUF_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
index = s->curpag << 8;
|
index = s->curpag << 8;
|
||||||
/* 4 bytes for header */
|
/* 4 bytes for header */
|
||||||
total_len = size + 4;
|
total_len = size + 4;
|
||||||
|
@ -244,9 +247,9 @@ void ne2000_receive(uint8_t *buf, int size)
|
||||||
ne2000_update_irq(s);
|
ne2000_update_irq(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ne2000_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
NE2000State *s = &ne2000_state;
|
NE2000State *s = opaque;
|
||||||
int offset, page;
|
int offset, page;
|
||||||
|
|
||||||
addr &= 0xf;
|
addr &= 0xf;
|
||||||
|
@ -264,7 +267,7 @@ static void ne2000_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
||||||
ne2000_update_irq(s);
|
ne2000_update_irq(s);
|
||||||
}
|
}
|
||||||
if (val & E8390_TRANS) {
|
if (val & E8390_TRANS) {
|
||||||
net_send_packet(net_fd, s->mem + (s->tpsr << 8), s->tcnt);
|
net_send_packet(s->nd, s->mem + (s->tpsr << 8), s->tcnt);
|
||||||
/* signal end of transfert */
|
/* signal end of transfert */
|
||||||
s->tsr = ENTSR_PTX;
|
s->tsr = ENTSR_PTX;
|
||||||
s->isr |= ENISR_TX;
|
s->isr |= ENISR_TX;
|
||||||
|
@ -329,9 +332,9 @@ static void ne2000_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t ne2000_ioport_read(CPUState *env, uint32_t addr)
|
static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
|
||||||
{
|
{
|
||||||
NE2000State *s = &ne2000_state;
|
NE2000State *s = opaque;
|
||||||
int offset, page, ret;
|
int offset, page, ret;
|
||||||
|
|
||||||
addr &= 0xf;
|
addr &= 0xf;
|
||||||
|
@ -370,9 +373,9 @@ static uint32_t ne2000_ioport_read(CPUState *env, uint32_t addr)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ne2000_asic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
NE2000State *s = &ne2000_state;
|
NE2000State *s = opaque;
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
|
|
||||||
#ifdef DEBUG_NE2000
|
#ifdef DEBUG_NE2000
|
||||||
|
@ -401,9 +404,9 @@ static void ne2000_asic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t ne2000_asic_ioport_read(CPUState *env, uint32_t addr)
|
static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
|
||||||
{
|
{
|
||||||
NE2000State *s = &ne2000_state;
|
NE2000State *s = opaque;
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -433,33 +436,40 @@ static uint32_t ne2000_asic_ioport_read(CPUState *env, uint32_t addr)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ne2000_reset_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
/* nothing to do (end of reset pulse) */
|
/* nothing to do (end of reset pulse) */
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t ne2000_reset_ioport_read(CPUState *env, uint32_t addr)
|
static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
|
||||||
{
|
{
|
||||||
NE2000State *s = &ne2000_state;
|
NE2000State *s = opaque;
|
||||||
ne2000_reset(s);
|
ne2000_reset(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ne2000_init(int base, int irq)
|
void ne2000_init(int base, int irq, NetDriverState *nd)
|
||||||
{
|
{
|
||||||
NE2000State *s = &ne2000_state;
|
NE2000State *s;
|
||||||
|
|
||||||
register_ioport_write(base, 16, ne2000_ioport_write, 1);
|
s = qemu_mallocz(sizeof(NE2000State));
|
||||||
register_ioport_read(base, 16, ne2000_ioport_read, 1);
|
if (!s)
|
||||||
|
return;
|
||||||
|
|
||||||
|
register_ioport_write(base, 16, 1, ne2000_ioport_write, s);
|
||||||
|
register_ioport_read(base, 16, 1, ne2000_ioport_read, s);
|
||||||
|
|
||||||
register_ioport_write(base + 0x10, 1, ne2000_asic_ioport_write, 1);
|
register_ioport_write(base + 0x10, 1, 1, ne2000_asic_ioport_write, s);
|
||||||
register_ioport_read(base + 0x10, 1, ne2000_asic_ioport_read, 1);
|
register_ioport_read(base + 0x10, 1, 1, ne2000_asic_ioport_read, s);
|
||||||
register_ioport_write(base + 0x10, 2, ne2000_asic_ioport_write, 2);
|
register_ioport_write(base + 0x10, 2, 2, ne2000_asic_ioport_write, s);
|
||||||
register_ioport_read(base + 0x10, 2, ne2000_asic_ioport_read, 2);
|
register_ioport_read(base + 0x10, 2, 2, ne2000_asic_ioport_read, s);
|
||||||
|
|
||||||
register_ioport_write(base + 0x1f, 1, ne2000_reset_ioport_write, 1);
|
register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
|
||||||
register_ioport_read(base + 0x1f, 1, ne2000_reset_ioport_read, 1);
|
register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
|
||||||
s->irq = irq;
|
s->irq = irq;
|
||||||
|
s->nd = nd;
|
||||||
|
|
||||||
ne2000_reset(s);
|
ne2000_reset(s);
|
||||||
|
|
||||||
|
add_fd_read_handler(nd->fd, ne2000_can_receive, ne2000_receive, s);
|
||||||
}
|
}
|
||||||
|
|
98
hw/pc.c
98
hw/pc.c
|
@ -43,6 +43,9 @@
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "vl.h"
|
#include "vl.h"
|
||||||
|
|
||||||
|
/* output Bochs bios info messages */
|
||||||
|
//#define DEBUG_BIOS
|
||||||
|
|
||||||
#define BIOS_FILENAME "bios.bin"
|
#define BIOS_FILENAME "bios.bin"
|
||||||
#define VGABIOS_FILENAME "vgabios.bin"
|
#define VGABIOS_FILENAME "vgabios.bin"
|
||||||
#define LINUX_BOOT_FILENAME "linux_boot.bin"
|
#define LINUX_BOOT_FILENAME "linux_boot.bin"
|
||||||
|
@ -55,7 +58,7 @@
|
||||||
int speaker_data_on;
|
int speaker_data_on;
|
||||||
int dummy_refresh_clock;
|
int dummy_refresh_clock;
|
||||||
|
|
||||||
static void ioport80_write(CPUState *env, uint32_t addr, uint32_t data)
|
static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +68,7 @@ static void cmos_init(int ram_size, int boot_device)
|
||||||
{
|
{
|
||||||
RTCState *s = &rtc_state;
|
RTCState *s = &rtc_state;
|
||||||
int val;
|
int val;
|
||||||
|
int fd0, fd1, nb;
|
||||||
|
|
||||||
/* various important CMOS locations needed by PC/Bochs bios */
|
/* various important CMOS locations needed by PC/Bochs bios */
|
||||||
|
|
||||||
|
@ -99,12 +103,11 @@ static void cmos_init(int ram_size, int boot_device)
|
||||||
s->cmos_data[0x3d] = 0x03; /* CD-ROM boot */
|
s->cmos_data[0x3d] = 0x03; /* CD-ROM boot */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void cmos_register_fd (uint8_t fd0, uint8_t fd1)
|
/* floppy type */
|
||||||
{
|
|
||||||
RTCState *s = &rtc_state;
|
fd0 = fdctrl_get_drive_type(0);
|
||||||
int nb = 0;
|
fd1 = fdctrl_get_drive_type(1);
|
||||||
|
|
||||||
s->cmos_data[0x10] = 0;
|
s->cmos_data[0x10] = 0;
|
||||||
switch (fd0) {
|
switch (fd0) {
|
||||||
|
@ -135,6 +138,7 @@ void cmos_register_fd (uint8_t fd0, uint8_t fd1)
|
||||||
s->cmos_data[0x10] |= 0x02;
|
s->cmos_data[0x10] |= 0x02;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
nb = 0;
|
||||||
if (fd0 < 3)
|
if (fd0 < 3)
|
||||||
nb++;
|
nb++;
|
||||||
if (fd1 < 3)
|
if (fd1 < 3)
|
||||||
|
@ -151,13 +155,13 @@ void cmos_register_fd (uint8_t fd0, uint8_t fd1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void speaker_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
speaker_data_on = (val >> 1) & 1;
|
speaker_data_on = (val >> 1) & 1;
|
||||||
pit_set_gate(&pit_channels[2], val & 1);
|
pit_set_gate(&pit_channels[2], val & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t speaker_ioport_read(CPUState *env, uint32_t addr)
|
static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
|
||||||
{
|
{
|
||||||
int out;
|
int out;
|
||||||
out = pit_get_out(&pit_channels[2]);
|
out = pit_get_out(&pit_channels[2]);
|
||||||
|
@ -166,28 +170,10 @@ uint32_t speaker_ioport_read(CPUState *env, uint32_t addr)
|
||||||
(dummy_refresh_clock << 4);
|
(dummy_refresh_clock << 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************/
|
|
||||||
/* PC floppy disk controler emulation glue */
|
|
||||||
#define PC_FDC_DMA 0x2
|
|
||||||
#define PC_FDC_IRQ 0x6
|
|
||||||
#define PC_FDC_BASE 0x3F0
|
|
||||||
|
|
||||||
static void fdctrl_register (unsigned char **disknames, int ro,
|
|
||||||
char boot_device)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
fdctrl_init(PC_FDC_IRQ, PC_FDC_DMA, 0, PC_FDC_BASE, boot_device);
|
|
||||||
for (i = 0; i < MAX_FD; i++) {
|
|
||||||
if (disknames[i] != NULL)
|
|
||||||
fdctrl_disk_change(i, disknames[i], ro);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
/* Bochs BIOS debug ports */
|
/* Bochs BIOS debug ports */
|
||||||
|
|
||||||
void bochs_bios_write(CPUX86State *env, uint32_t addr, uint32_t val)
|
void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
/* Bochs BIOS messages */
|
/* Bochs BIOS messages */
|
||||||
|
@ -218,15 +204,15 @@ void bochs_bios_write(CPUX86State *env, uint32_t addr, uint32_t val)
|
||||||
|
|
||||||
void bochs_bios_init(void)
|
void bochs_bios_init(void)
|
||||||
{
|
{
|
||||||
register_ioport_write(0x400, 1, bochs_bios_write, 2);
|
register_ioport_write(0x400, 1, 2, bochs_bios_write, NULL);
|
||||||
register_ioport_write(0x401, 1, bochs_bios_write, 2);
|
register_ioport_write(0x401, 1, 2, bochs_bios_write, NULL);
|
||||||
register_ioport_write(0x402, 1, bochs_bios_write, 1);
|
register_ioport_write(0x402, 1, 1, bochs_bios_write, NULL);
|
||||||
register_ioport_write(0x403, 1, bochs_bios_write, 1);
|
register_ioport_write(0x403, 1, 1, bochs_bios_write, NULL);
|
||||||
|
|
||||||
register_ioport_write(0x501, 1, bochs_bios_write, 2);
|
register_ioport_write(0x501, 1, 2, bochs_bios_write, NULL);
|
||||||
register_ioport_write(0x502, 1, bochs_bios_write, 2);
|
register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL);
|
||||||
register_ioport_write(0x500, 1, bochs_bios_write, 1);
|
register_ioport_write(0x500, 1, 1, bochs_bios_write, NULL);
|
||||||
register_ioport_write(0x503, 1, bochs_bios_write, 1);
|
register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -261,6 +247,15 @@ int load_kernel(const char *filename, uint8_t *addr,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const int ide_iobase[2] = { 0x1f0, 0x170 };
|
||||||
|
static const int ide_iobase2[2] = { 0x3f6, 0x376 };
|
||||||
|
static const int ide_irq[2] = { 14, 15 };
|
||||||
|
|
||||||
|
#define NE2000_NB_MAX 6
|
||||||
|
|
||||||
|
static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
|
||||||
|
static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
|
||||||
|
|
||||||
/* PC hardware initialisation */
|
/* PC hardware initialisation */
|
||||||
void pc_init(int ram_size, int vga_ram_size, int boot_device,
|
void pc_init(int ram_size, int vga_ram_size, int boot_device,
|
||||||
DisplayState *ds, const char **fd_filename, int snapshot,
|
DisplayState *ds, const char **fd_filename, int snapshot,
|
||||||
|
@ -268,7 +263,7 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
|
||||||
const char *initrd_filename)
|
const char *initrd_filename)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
int ret, linux_boot, initrd_size;
|
int ret, linux_boot, initrd_size, i, nb_nics1, fd;
|
||||||
|
|
||||||
linux_boot = (kernel_filename != NULL);
|
linux_boot = (kernel_filename != NULL);
|
||||||
|
|
||||||
|
@ -344,25 +339,38 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init basic PC hardware */
|
/* init basic PC hardware */
|
||||||
register_ioport_write(0x80, 1, ioport80_write, 1);
|
register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
|
||||||
|
|
||||||
vga_initialize(ds, phys_ram_base + ram_size, ram_size,
|
vga_initialize(ds, phys_ram_base + ram_size, ram_size,
|
||||||
vga_ram_size);
|
vga_ram_size);
|
||||||
|
|
||||||
rtc_init(0x70, 8);
|
rtc_init(0x70, 8);
|
||||||
cmos_init(ram_size, boot_device);
|
register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
|
||||||
register_ioport_read(0x61, 1, speaker_ioport_read, 1);
|
register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
|
||||||
register_ioport_write(0x61, 1, speaker_ioport_write, 1);
|
|
||||||
|
|
||||||
pic_init();
|
pic_init();
|
||||||
pit_init();
|
pit_init(0x40);
|
||||||
serial_init(0x3f8, 4);
|
|
||||||
ne2000_init(0x300, 9);
|
fd = serial_open_device();
|
||||||
ide_init();
|
serial_init(0x3f8, 4, fd);
|
||||||
|
|
||||||
|
nb_nics1 = nb_nics;
|
||||||
|
if (nb_nics1 > NE2000_NB_MAX)
|
||||||
|
nb_nics1 = NE2000_NB_MAX;
|
||||||
|
for(i = 0; i < nb_nics1; i++) {
|
||||||
|
ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < 2; i++) {
|
||||||
|
ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
|
||||||
|
bs_table[2 * i], bs_table[2 * i + 1]);
|
||||||
|
}
|
||||||
kbd_init();
|
kbd_init();
|
||||||
AUD_init();
|
AUD_init();
|
||||||
DMA_init();
|
DMA_init();
|
||||||
SB16_init();
|
SB16_init();
|
||||||
|
|
||||||
fdctrl_register((unsigned char **)fd_filename, snapshot, boot_device);
|
fdctrl_init(6, 2, 0, 0x3f0, fd_table);
|
||||||
|
|
||||||
|
cmos_init(ram_size, boot_device);
|
||||||
}
|
}
|
||||||
|
|
36
hw/pckbd.c
36
hw/pckbd.c
|
@ -189,7 +189,7 @@ static void kbd_update_irq(KBDState *s)
|
||||||
|
|
||||||
static void kbd_queue(KBDState *s, int b, int aux)
|
static void kbd_queue(KBDState *s, int b, int aux)
|
||||||
{
|
{
|
||||||
KBDQueue *q = &kbd_state.queues[aux];
|
KBDQueue *q = &s->queues[aux];
|
||||||
|
|
||||||
#if defined(DEBUG_MOUSE) || defined(DEBUG_KBD)
|
#if defined(DEBUG_MOUSE) || defined(DEBUG_KBD)
|
||||||
if (aux)
|
if (aux)
|
||||||
|
@ -214,9 +214,9 @@ void kbd_put_keycode(int keycode)
|
||||||
kbd_queue(s, keycode, 0);
|
kbd_queue(s, keycode, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t kbd_read_status(CPUState *env, uint32_t addr)
|
static uint32_t kbd_read_status(void *opaque, uint32_t addr)
|
||||||
{
|
{
|
||||||
KBDState *s = &kbd_state;
|
KBDState *s = opaque;
|
||||||
int val;
|
int val;
|
||||||
val = s->status;
|
val = s->status;
|
||||||
#if defined(DEBUG_KBD)
|
#if defined(DEBUG_KBD)
|
||||||
|
@ -225,9 +225,9 @@ static uint32_t kbd_read_status(CPUState *env, uint32_t addr)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kbd_write_command(CPUState *env, uint32_t addr, uint32_t val)
|
static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
KBDState *s = &kbd_state;
|
KBDState *s = opaque;
|
||||||
|
|
||||||
#ifdef DEBUG_KBD
|
#ifdef DEBUG_KBD
|
||||||
printf("kbd: write cmd=0x%02x\n", val);
|
printf("kbd: write cmd=0x%02x\n", val);
|
||||||
|
@ -285,10 +285,10 @@ static void kbd_write_command(CPUState *env, uint32_t addr, uint32_t val)
|
||||||
break;
|
break;
|
||||||
#ifdef TARGET_I386
|
#ifdef TARGET_I386
|
||||||
case KBD_CCMD_ENABLE_A20:
|
case KBD_CCMD_ENABLE_A20:
|
||||||
cpu_x86_set_a20(env, 1);
|
cpu_x86_set_a20(cpu_single_env, 1);
|
||||||
break;
|
break;
|
||||||
case KBD_CCMD_DISABLE_A20:
|
case KBD_CCMD_DISABLE_A20:
|
||||||
cpu_x86_set_a20(env, 0);
|
cpu_x86_set_a20(cpu_single_env, 0);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case KBD_CCMD_RESET:
|
case KBD_CCMD_RESET:
|
||||||
|
@ -304,9 +304,9 @@ static void kbd_write_command(CPUState *env, uint32_t addr, uint32_t val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t kbd_read_data(CPUState *env, uint32_t addr)
|
static uint32_t kbd_read_data(void *opaque, uint32_t addr)
|
||||||
{
|
{
|
||||||
KBDState *s = &kbd_state;
|
KBDState *s = opaque;
|
||||||
KBDQueue *q;
|
KBDQueue *q;
|
||||||
int val, index;
|
int val, index;
|
||||||
|
|
||||||
|
@ -605,9 +605,9 @@ static void kbd_write_mouse(KBDState *s, int val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void kbd_write_data(CPUState *env, uint32_t addr, uint32_t val)
|
void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
KBDState *s = &kbd_state;
|
KBDState *s = opaque;
|
||||||
|
|
||||||
#ifdef DEBUG_KBD
|
#ifdef DEBUG_KBD
|
||||||
printf("kbd: write data=0x%02x\n", val);
|
printf("kbd: write data=0x%02x\n", val);
|
||||||
|
@ -629,7 +629,7 @@ void kbd_write_data(CPUState *env, uint32_t addr, uint32_t val)
|
||||||
break;
|
break;
|
||||||
case KBD_CCMD_WRITE_OUTPORT:
|
case KBD_CCMD_WRITE_OUTPORT:
|
||||||
#ifdef TARGET_I386
|
#ifdef TARGET_I386
|
||||||
cpu_x86_set_a20(env, (val >> 1) & 1);
|
cpu_x86_set_a20(cpu_single_env, (val >> 1) & 1);
|
||||||
#endif
|
#endif
|
||||||
if (!(val & 1)) {
|
if (!(val & 1)) {
|
||||||
reset_requested = 1;
|
reset_requested = 1;
|
||||||
|
@ -664,9 +664,11 @@ void kbd_reset(KBDState *s)
|
||||||
|
|
||||||
void kbd_init(void)
|
void kbd_init(void)
|
||||||
{
|
{
|
||||||
kbd_reset(&kbd_state);
|
KBDState *s = &kbd_state;
|
||||||
register_ioport_read(0x60, 1, kbd_read_data, 1);
|
|
||||||
register_ioport_write(0x60, 1, kbd_write_data, 1);
|
kbd_reset(s);
|
||||||
register_ioport_read(0x64, 1, kbd_read_status, 1);
|
register_ioport_read(0x60, 1, 1, kbd_read_data, s);
|
||||||
register_ioport_write(0x64, 1, kbd_write_command, 1);
|
register_ioport_write(0x60, 1, 1, kbd_write_data, s);
|
||||||
|
register_ioport_read(0x64, 1, 1, kbd_read_status, s);
|
||||||
|
register_ioport_write(0x64, 1, 1, kbd_write_command, s);
|
||||||
}
|
}
|
||||||
|
|
81
hw/serial.c
81
hw/serial.c
|
@ -90,7 +90,7 @@
|
||||||
#define UART_LSR_OE 0x02 /* Overrun error indicator */
|
#define UART_LSR_OE 0x02 /* Overrun error indicator */
|
||||||
#define UART_LSR_DR 0x01 /* Receiver data ready */
|
#define UART_LSR_DR 0x01 /* Receiver data ready */
|
||||||
|
|
||||||
typedef struct SerialState {
|
struct SerialState {
|
||||||
uint8_t divider;
|
uint8_t divider;
|
||||||
uint8_t rbr; /* receive register */
|
uint8_t rbr; /* receive register */
|
||||||
uint8_t ier;
|
uint8_t ier;
|
||||||
|
@ -104,14 +104,11 @@ typedef struct SerialState {
|
||||||
it can be reset while reading iir */
|
it can be reset while reading iir */
|
||||||
int thr_ipending;
|
int thr_ipending;
|
||||||
int irq;
|
int irq;
|
||||||
} SerialState;
|
int out_fd;
|
||||||
|
};
|
||||||
|
|
||||||
SerialState serial_ports[1];
|
static void serial_update_irq(SerialState *s)
|
||||||
|
|
||||||
void serial_update_irq(void)
|
|
||||||
{
|
{
|
||||||
SerialState *s = &serial_ports[0];
|
|
||||||
|
|
||||||
if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
|
if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
|
||||||
s->iir = UART_IIR_RDI;
|
s->iir = UART_IIR_RDI;
|
||||||
} else if (s->thr_ipending && (s->ier & UART_IER_THRI)) {
|
} else if (s->thr_ipending && (s->ier & UART_IER_THRI)) {
|
||||||
|
@ -126,9 +123,9 @@ void serial_update_irq(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
{
|
{
|
||||||
SerialState *s = &serial_ports[0];
|
SerialState *s = opaque;
|
||||||
unsigned char ch;
|
unsigned char ch;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -144,16 +141,16 @@ void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
||||||
} else {
|
} else {
|
||||||
s->thr_ipending = 0;
|
s->thr_ipending = 0;
|
||||||
s->lsr &= ~UART_LSR_THRE;
|
s->lsr &= ~UART_LSR_THRE;
|
||||||
serial_update_irq();
|
serial_update_irq(s);
|
||||||
|
|
||||||
ch = val;
|
ch = val;
|
||||||
do {
|
do {
|
||||||
ret = write(1, &ch, 1);
|
ret = write(s->out_fd, &ch, 1);
|
||||||
} while (ret != 1);
|
} while (ret != 1);
|
||||||
s->thr_ipending = 1;
|
s->thr_ipending = 1;
|
||||||
s->lsr |= UART_LSR_THRE;
|
s->lsr |= UART_LSR_THRE;
|
||||||
s->lsr |= UART_LSR_TEMT;
|
s->lsr |= UART_LSR_TEMT;
|
||||||
serial_update_irq();
|
serial_update_irq(s);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -161,7 +158,7 @@ void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
||||||
s->divider = (s->divider & 0x00ff) | (val << 8);
|
s->divider = (s->divider & 0x00ff) | (val << 8);
|
||||||
} else {
|
} else {
|
||||||
s->ier = val;
|
s->ier = val;
|
||||||
serial_update_irq();
|
serial_update_irq(s);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -183,9 +180,9 @@ void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t serial_ioport_read(CPUState *env, uint32_t addr)
|
static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
|
||||||
{
|
{
|
||||||
SerialState *s = &serial_ports[0];
|
SerialState *s = opaque;
|
||||||
uint32_t ret;
|
uint32_t ret;
|
||||||
|
|
||||||
addr &= 7;
|
addr &= 7;
|
||||||
|
@ -197,7 +194,7 @@ uint32_t serial_ioport_read(CPUState *env, uint32_t addr)
|
||||||
} else {
|
} else {
|
||||||
ret = s->rbr;
|
ret = s->rbr;
|
||||||
s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
|
s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
|
||||||
serial_update_irq();
|
serial_update_irq(s);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -212,7 +209,7 @@ uint32_t serial_ioport_read(CPUState *env, uint32_t addr)
|
||||||
/* reset THR pending bit */
|
/* reset THR pending bit */
|
||||||
if ((ret & 0x7) == UART_IIR_THRI)
|
if ((ret & 0x7) == UART_IIR_THRI)
|
||||||
s->thr_ipending = 0;
|
s->thr_ipending = 0;
|
||||||
serial_update_irq();
|
serial_update_irq(s);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
ret = s->lcr;
|
ret = s->lcr;
|
||||||
|
@ -244,38 +241,58 @@ uint32_t serial_ioport_read(CPUState *env, uint32_t addr)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int serial_can_receive(void)
|
int serial_can_receive(SerialState *s)
|
||||||
{
|
{
|
||||||
SerialState *s = &serial_ports[0];
|
|
||||||
return !(s->lsr & UART_LSR_DR);
|
return !(s->lsr & UART_LSR_DR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_receive_byte(int ch)
|
void serial_receive_byte(SerialState *s, int ch)
|
||||||
{
|
{
|
||||||
SerialState *s = &serial_ports[0];
|
|
||||||
|
|
||||||
s->rbr = ch;
|
s->rbr = ch;
|
||||||
s->lsr |= UART_LSR_DR;
|
s->lsr |= UART_LSR_DR;
|
||||||
serial_update_irq();
|
serial_update_irq(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_receive_break(void)
|
void serial_receive_break(SerialState *s)
|
||||||
{
|
{
|
||||||
SerialState *s = &serial_ports[0];
|
|
||||||
|
|
||||||
s->rbr = 0;
|
s->rbr = 0;
|
||||||
s->lsr |= UART_LSR_BI | UART_LSR_DR;
|
s->lsr |= UART_LSR_BI | UART_LSR_DR;
|
||||||
serial_update_irq();
|
serial_update_irq(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_init(int base, int irq)
|
static int serial_can_receive1(void *opaque)
|
||||||
{
|
{
|
||||||
SerialState *s = &serial_ports[0];
|
SerialState *s = opaque;
|
||||||
|
return serial_can_receive(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void serial_receive1(void *opaque, const uint8_t *buf, int size)
|
||||||
|
{
|
||||||
|
SerialState *s = opaque;
|
||||||
|
serial_receive_byte(s, buf[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If fd is zero, it means that the serial device uses the console */
|
||||||
|
SerialState *serial_init(int base, int irq, int fd)
|
||||||
|
{
|
||||||
|
SerialState *s;
|
||||||
|
|
||||||
|
s = qemu_mallocz(sizeof(SerialState));
|
||||||
|
if (!s)
|
||||||
|
return NULL;
|
||||||
s->irq = irq;
|
s->irq = irq;
|
||||||
s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
|
s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
|
||||||
s->iir = UART_IIR_NO_INT;
|
s->iir = UART_IIR_NO_INT;
|
||||||
|
|
||||||
register_ioport_write(base, 8, serial_ioport_write, 1);
|
register_ioport_write(base, 8, 1, serial_ioport_write, s);
|
||||||
register_ioport_read(base, 8, serial_ioport_read, 1);
|
register_ioport_read(base, 8, 1, serial_ioport_read, s);
|
||||||
|
|
||||||
|
if (fd != 0) {
|
||||||
|
add_fd_read_handler(fd, serial_can_receive1, serial_receive1, s);
|
||||||
|
s->out_fd = fd;
|
||||||
|
} else {
|
||||||
|
serial_console = s;
|
||||||
|
s->out_fd = 1;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue