-int v3_dev_hook_io(struct vm_device *dev,
+int v3_dev_hook_io(struct vm_device * dev,
ushort_t port,
- int (*read)(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev),
- int (*write)(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev));
+ int (*read)(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data),
+ int (*write)(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data));
int v3_dev_unhook_io(struct vm_device *dev,
ushort_t port);
static int pit_read_channel(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
- struct vm_device * dev = (struct vm_device *)priv_data;
- struct pit * state = (struct pit *)dev->private_data;
+ struct pit * state = (struct pit *)priv_data;
char * val = (char *)dst;
if (length != 1) {
static int pit_write_channel(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
- struct vm_device * dev = (struct vm_device *)priv_data;
- struct pit * state = (struct pit *)dev->private_data;
+ struct pit * state = (struct pit *)priv_data;
char val = *(char *)src;
if (length != 1) {
static int pit_write_command(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
- struct vm_device * dev = (struct vm_device *)priv_data;
- struct pit * state = (struct pit *)dev->private_data;
+ struct pit * state = (struct pit *)priv_data;
struct pit_cmd_word * cmd = (struct pit_cmd_word *)src;
PrintDebug("8254 PIT: Write to PIT Command port\n");
if (state->timer) {
v3_remove_timer(info, state->timer);
}
-
- v3_unhook_io_port(dev->vm, CHANNEL0_PORT);
- v3_unhook_io_port(dev->vm, CHANNEL1_PORT);
- v3_unhook_io_port(dev->vm, CHANNEL2_PORT);
- v3_unhook_io_port(dev->vm, COMMAND_PORT);
- v3_unhook_io_port(dev->vm, SPEAKER_PORT);
-
+
V3_Free(state);
return 0;
}
return -1;
}
- ret |= v3_hook_io_port(vm, CHANNEL0_PORT, &pit_read_channel, &pit_write_channel, dev);
- ret |= v3_hook_io_port(vm, CHANNEL1_PORT, &pit_read_channel, &pit_write_channel, dev);
- ret |= v3_hook_io_port(vm, CHANNEL2_PORT, &pit_read_channel, &pit_write_channel, dev);
- ret |= v3_hook_io_port(vm, COMMAND_PORT, NULL, &pit_write_command, dev);
- ret |= v3_hook_io_port(vm, SPEAKER_PORT, &pit_read_channel, &pit_write_channel, dev);
+ ret |= v3_dev_hook_io(dev, CHANNEL0_PORT, &pit_read_channel, &pit_write_channel);
+ ret |= v3_dev_hook_io(dev, CHANNEL1_PORT, &pit_read_channel, &pit_write_channel);
+ ret |= v3_dev_hook_io(dev, CHANNEL2_PORT, &pit_read_channel, &pit_write_channel);
+ ret |= v3_dev_hook_io(dev, COMMAND_PORT, NULL, &pit_write_command);
+ ret |= v3_dev_hook_io(dev, SPEAKER_PORT, &pit_read_channel, &pit_write_channel);
if (ret != 0) {
PrintError("8254 PIT: Failed to hook IO ports\n");
};
-static int read_master_port1(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
- struct pic_internal * state = (struct pic_internal*)dev->private_data;
+static int read_master_port1(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
+ struct pic_internal * state = (struct pic_internal *)priv_data;
if (length != 1) {
PrintError("8259 PIC: Invalid Read length (rd_Master1)\n");
return 1;
}
-static int read_master_port2(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
- struct pic_internal * state = (struct pic_internal*)dev->private_data;
+static int read_master_port2(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
+ struct pic_internal * state = (struct pic_internal *)priv_data;
if (length != 1) {
PrintError("8259 PIC: Invalid Read length (rd_Master2)\n");
}
-static int read_slave_port1(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
- struct pic_internal * state = (struct pic_internal*)dev->private_data;
+static int read_slave_port1(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
+ struct pic_internal * state = (struct pic_internal *)priv_data;
if (length != 1) {
PrintError("8259 PIC: Invalid Read length (rd_Slave1)\n");
return 1;
}
-static int read_slave_port2(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
- struct pic_internal * state = (struct pic_internal*)dev->private_data;
+static int read_slave_port2(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
+ struct pic_internal * state = (struct pic_internal *)priv_data;
if (length != 1) {
PrintError("8259 PIC: Invalid Read length (rd_Slave2)\n");
}
-static int write_master_port1(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct pic_internal * state = (struct pic_internal*)dev->private_data;
+static int write_master_port1(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct pic_internal * state = (struct pic_internal *)priv_data;
uchar_t cw = *(uchar_t *)src;
PrintDebug("8259 PIC: Write master port 1 with 0x%x\n",cw);
return 1;
}
-static int write_master_port2(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct pic_internal * state = (struct pic_internal*)dev->private_data;
+static int write_master_port2(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct pic_internal * state = (struct pic_internal *)priv_data;
uchar_t cw = *(uchar_t *)src;
PrintDebug("8259 PIC: Write master port 2 with 0x%x\n",cw);
return 1;
}
-static int write_slave_port1(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct pic_internal * state = (struct pic_internal*)dev->private_data;
+static int write_slave_port1(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct pic_internal * state = (struct pic_internal *)priv_data;
uchar_t cw = *(uchar_t *)src;
PrintDebug("8259 PIC: Write slave port 1 with 0x%x\n",cw);
return 1;
}
-static int write_slave_port2(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct pic_internal * state = (struct pic_internal*)dev->private_data;
+static int write_slave_port2(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct pic_internal * state = (struct pic_internal *)priv_data;
uchar_t cw = *(uchar_t *)src;
PrintDebug("8259 PIC: Write slave port 2 with 0x%x\n",cw);
-static int read_elcr_port(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
- struct pic_internal * state = (struct pic_internal*)dev->private_data;
+static int read_elcr_port(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
+ struct pic_internal * state = (struct pic_internal *)priv_data;
if (length != 1) {
PrintError("ELCR read of invalid length %d\n", length);
}
-static int write_elcr_port(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct pic_internal * state = (struct pic_internal*)dev->private_data;
+static int write_elcr_port(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct pic_internal * state = (struct pic_internal *)priv_data;
if (length != 1) {
PrintError("ELCR read of invalid length %d\n", length);
}
-static int ata_read(struct vm_device * dev, struct ide_channel * channel, uint8_t * dst, uint_t sect_cnt) {
+static int ata_read(struct ide_internal * ide, struct ide_channel * channel, uint8_t * dst, uint_t sect_cnt) {
struct ide_drive * drive = get_selected_drive(channel);
if (drive->hd_state.accessed == 0) {
}
-static int ata_write(struct vm_device * dev, struct ide_channel * channel, uint8_t * src, uint_t sect_cnt) {
+static int ata_write(struct ide_internal * ide, struct ide_channel * channel, uint8_t * src, uint_t sect_cnt) {
struct ide_drive * drive = get_selected_drive(channel);
PrintDebug("Writing Drive LBA=%d (count=%d)\n", (uint32_t)(drive->current_lba), sect_cnt);
-static int ata_get_lba(struct vm_device * dev, struct ide_channel * channel, uint64_t * lba) {
+static int ata_get_lba(struct ide_internal * ide, struct ide_channel * channel, uint64_t * lba) {
struct ide_drive * drive = get_selected_drive(channel);
// The if the sector count == 0 then read 256 sectors (cast up to handle that value)
uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
// 28 bit LBA
-static int ata_read_sectors(struct vm_device * dev, struct ide_channel * channel) {
+static int ata_read_sectors(struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
// The if the sector count == 0 then read 256 sectors (cast up to handle that value)
uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
- if (ata_get_lba(dev, channel, &(drive->current_lba)) == -1) {
- ide_abort_command(dev, channel);
+ if (ata_get_lba(ide, channel, &(drive->current_lba)) == -1) {
+ ide_abort_command(ide, channel);
return 0;
}
- if (ata_read(dev, channel, drive->data_buf, 1) == -1) {
+ if (ata_read(ide, channel, drive->data_buf, 1) == -1) {
PrintError("Could not read disk sector\n");
return -1;
}
drive->irq_flags.rel = 0;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
PrintDebug("Returning from read sectors\n");
// 48 bit LBA
-static int ata_read_sectors_ext(struct vm_device * dev, struct ide_channel * channel) {
+static int ata_read_sectors_ext(struct ide_internal * ide, struct ide_channel * channel) {
//struct ide_drive * drive = get_selected_drive(channel);
// The if the sector count == 0 then read 256 sectors (cast up to handle that value)
//uint32_t sector_count = (drive->sector_count == 0) ? 256 : drive->sector_count;
* however the device can change that value
*
*/
-static int atapi_update_req_len(struct vm_device * dev, struct ide_channel * channel, uint_t xfer_len) {
+static int atapi_update_req_len(struct ide_internal * ide, struct ide_channel * channel, uint_t xfer_len) {
struct ide_drive * drive = get_selected_drive(channel);
// PrintDebug("Updating request length (pre=%d)\n", drive->req_len);
// This is for simple commands that don't need to sanity check the req_len
-static void atapi_setup_cmd_resp(struct vm_device * dev, struct ide_channel * channel, uint_t xfer_len) {
+static void atapi_setup_cmd_resp(struct ide_internal * ide, struct ide_channel * channel, uint_t xfer_len) {
struct ide_drive * drive = get_selected_drive(channel);
drive->transfer_length = xfer_len;
channel->status.data_req = 1;
channel->status.error = 0;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
}
-static void atapi_cmd_error(struct vm_device * dev, struct ide_channel * channel,
+static void atapi_cmd_error(struct ide_internal * ide, struct ide_channel * channel,
atapi_sense_key_t sense_key, atapi_add_sense_code_t asc) {
struct ide_drive * drive = get_selected_drive(channel);
drive->irq_flags.c_d = 1;
drive->irq_flags.rel = 0;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
}
-static void atapi_cmd_nop(struct vm_device * dev, struct ide_channel * channel) {
+static void atapi_cmd_nop(struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
channel->status.busy = 0;
drive->irq_flags.c_d = 1;
drive->irq_flags.rel = 0;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
}
-static int atapi_read_chunk(struct vm_device * dev, struct ide_channel * channel) {
+static int atapi_read_chunk(struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
int ret = drive->ops->read(drive->data_buf, drive->current_lba * ATAPI_BLOCK_SIZE, ATAPI_BLOCK_SIZE,
}
-static int atapi_update_data_buf(struct vm_device * dev, struct ide_channel * channel) {
+static int atapi_update_data_buf(struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
switch (drive->cd_state.atapi_cmd) {
drive->current_lba++;
// read the next block
- return atapi_read_chunk(dev, channel);
+ return atapi_read_chunk(ide, channel);
default:
PrintError("Unhandled ATAPI command in update buffer %x\n", drive->cd_state.atapi_cmd);
}
static int atapi_read10(struct guest_info * core,
- struct vm_device * dev,
+ struct ide_internal * ide,
struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
struct atapi_read10_cmd * cmd = (struct atapi_read10_cmd *)(drive->data_buf);
*/
if (xfer_len == 0) {
- atapi_cmd_nop(dev, channel);
+ atapi_cmd_nop(ide, channel);
return 0;
}
PrintError("IDE: xfer len exceeded capacity (lba=%d) (xfer_len=%d) (ReadEnd=%d) (capacity=%d)\n",
lba, xfer_len, lba + xfer_len,
(uint32_t)drive->ops->get_capacity(drive->private_data));
- atapi_cmd_error(dev, channel, ATAPI_SEN_ILL_REQ, ASC_LOG_BLK_OOR);
- ide_raise_irq(dev, channel);
+ atapi_cmd_error(ide, channel, ATAPI_SEN_ILL_REQ, ASC_LOG_BLK_OOR);
+ ide_raise_irq(ide, channel);
return 0;
}
if (channel->features.dma) {
if (channel->dma_status.active == 1) {
- if (dma_read(core, dev, channel) == -1) {
+ if (dma_read(core, ide, channel) == -1) {
PrintError("Error in DMA read for CD Read10 command\n");
return -1;
}
return 0;
}
- if (atapi_read_chunk(dev, channel) == -1) {
+ if (atapi_read_chunk(ide, channel) == -1) {
PrintError("IDE: Could not read initial chunk from CD\n");
return -1;
}
// Length of ATAPI buffer sits in cylinder registers
// This is weird... The host sets this value to say what it would like to transfer,
// if it is larger than the correct size, the device shrinks it to the correct size
- if (atapi_update_req_len(dev, channel, ATAPI_BLOCK_SIZE) == -1) {
+ if (atapi_update_req_len(ide, channel, ATAPI_BLOCK_SIZE) == -1) {
PrintError("Could not update initial request length\n");
return -1;
}
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
return 0;
}
-static void atapi_req_sense(struct vm_device * dev, struct ide_channel * channel) {
+static void atapi_req_sense(struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
memcpy(drive->data_buf, drive->cd_state.sense.buf, sizeof(drive->cd_state.sense.buf));
- atapi_setup_cmd_resp(dev, channel, 18);
+ atapi_setup_cmd_resp(ide, channel, 18);
}
-static int atapi_get_capacity(struct vm_device * dev, struct ide_channel * channel) {
+static int atapi_get_capacity(struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
struct atapi_rd_capacity_resp * resp = (struct atapi_rd_capacity_resp *)(drive->data_buf);
uint32_t capacity = drive->ops->get_capacity(drive->private_data);
resp->lba = le_to_be_32(capacity);
resp->block_len = le_to_be_32(ATAPI_BLOCK_SIZE);
- atapi_setup_cmd_resp(dev, channel, sizeof(struct atapi_rd_capacity_resp));
+ atapi_setup_cmd_resp(ide, channel, sizeof(struct atapi_rd_capacity_resp));
return 0;
}
-static int atapi_get_config(struct vm_device * dev, struct ide_channel * channel) {
+static int atapi_get_config(struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
struct atapi_config_cmd * cmd = (struct atapi_config_cmd *)(drive->data_buf);
uint16_t alloc_len = be_to_le_16(cmd->alloc_len);
xfer_len = alloc_len;
}
- atapi_setup_cmd_resp(dev, channel, xfer_len);
+ atapi_setup_cmd_resp(ide, channel, xfer_len);
return 0;
}
-static int atapi_read_toc(struct vm_device * dev, struct ide_channel * channel) {
+static int atapi_read_toc(struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
struct atapi_rd_toc_cmd * cmd = (struct atapi_rd_toc_cmd *)(drive->data_buf);
uint16_t alloc_len = be_to_le_16(cmd->alloc_len);
xfer_len = alloc_len;
}
- atapi_setup_cmd_resp(dev, channel, xfer_len);
+ atapi_setup_cmd_resp(ide, channel, xfer_len);
} else {
PrintError("Unhandled Format (%d)\n", cmd->format);
return -1;
}
-static int atapi_mode_sense_cur_values(struct vm_device * dev, struct ide_channel * channel,
+static int atapi_mode_sense_cur_values(struct ide_internal * ide, struct ide_channel * channel,
struct atapi_mode_sense_cmd * sense_cmd) {
struct ide_drive * drive = get_selected_drive(channel);
struct atapi_mode_sense_hdr * hdr = (struct atapi_mode_sense_hdr *)(drive->data_buf);
case 0x3f:
default:
PrintError("ATAPI: Mode sense Page Code not supported (%x)\n", sense_cmd->page_code);
- atapi_cmd_error(dev, channel, ATAPI_SEN_ILL_REQ, ASC_INV_CMD_FIELD);
- ide_raise_irq(dev, channel);
+ atapi_cmd_error(ide, channel, ATAPI_SEN_ILL_REQ, ASC_INV_CMD_FIELD);
+ ide_raise_irq(ide, channel);
return 0;
}
drive->transfer_length = (resp_len > alloc_len) ? alloc_len : resp_len;
drive->transfer_index = 0;
- atapi_update_req_len(dev, channel, drive->transfer_length);
+ atapi_update_req_len(ide, channel, drive->transfer_length);
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
return 0;
}
-static int atapi_mode_sense(struct vm_device * dev, struct ide_channel * channel) {
+static int atapi_mode_sense(struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
struct atapi_mode_sense_cmd * sense_cmd = (struct atapi_mode_sense_cmd *)(drive->data_buf);
switch (sense_cmd->page_ctrl) {
case 0x00: // Current values
- return atapi_mode_sense_cur_values(dev, channel, sense_cmd);
+ return atapi_mode_sense_cur_values(ide, channel, sense_cmd);
case 0x01: // Changeable values
case 0x02: // default values
case 0x03: // saved values
}
-static int atapi_inquiry(struct vm_device * dev, struct ide_channel * channel) {
+static int atapi_inquiry(struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
struct atapi_inquiry_cmd * inquiry_cmd = (struct atapi_inquiry_cmd *)(drive->data_buf);
uint16_t alloc_len = be_to_le_16(inquiry_cmd->alloc_len);
xfer_len = alloc_len;
}
- atapi_setup_cmd_resp(dev, channel, xfer_len);
+ atapi_setup_cmd_resp(ide, channel, xfer_len);
return 0;
}
}
-static int atapi_handle_packet(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel) {
+static int atapi_handle_packet(struct guest_info * core, struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
uint8_t cmd = drive->data_buf[0];
switch (cmd) {
case 0x00: // test unit ready
- atapi_cmd_nop(dev, channel);
+ atapi_cmd_nop(ide, channel);
/* if drive not ready:
atapi_cmd_error(... ATAPI_SEN_NOT_RDY, ASC_MEDIA_NOT_PRESENT)
*/
break;
case 0x03: // request sense
- atapi_req_sense(dev, channel);
+ atapi_req_sense(ide, channel);
break;
case 0x1e: // lock door
- atapi_cmd_nop(dev, channel);
+ atapi_cmd_nop(ide, channel);
break;
case 0x28: // read(10)
- if (atapi_read10(core, dev, channel) == -1) {
+ if (atapi_read10(core, ide, channel) == -1) {
PrintError("IDE: Error in ATAPI read (%x)\n", cmd);
return -1;
}
break;
case 0x5a: // mode sense
- if (atapi_mode_sense(dev, channel) == -1) {
+ if (atapi_mode_sense(ide, channel) == -1) {
PrintError("IDE: Error in ATAPI mode sense (%x)\n", cmd);
return -1;
}
case 0x25: // read cdrom capacity
- if (atapi_get_capacity(dev, channel) == -1) {
+ if (atapi_get_capacity(ide, channel) == -1) {
PrintError("IDE: Error getting CDROM capacity (%x)\n", cmd);
return -1;
}
case 0x43: // read TOC
- if (atapi_read_toc(dev, channel) == -1) {
+ if (atapi_read_toc(ide, channel) == -1) {
PrintError("IDE: Error getting CDROM TOC (%x)\n", cmd);
return -1;
}
break;
case 0x46: // get configuration
- if (atapi_get_config(dev, channel) == -1) {
+ if (atapi_get_config(ide, channel) == -1) {
PrintError("IDE: Error getting CDROM Configuration (%x)\n", cmd);
return -1;
}
case 0x51: // read disk info
// no-op to keep the Linux CD-ROM driver happy
PrintDebug("Error: Read disk info no-op to keep the Linux CD-ROM driver happy\n");
- atapi_cmd_error(dev, channel, ATAPI_SEN_ILL_REQ, ASC_INV_CMD_FIELD);
- ide_raise_irq(dev, channel);
+ atapi_cmd_error(ide, channel, ATAPI_SEN_ILL_REQ, ASC_INV_CMD_FIELD);
+ ide_raise_irq(ide, channel);
break;
case 0x12: // inquiry
- if (atapi_inquiry(dev, channel) == -1) {
+ if (atapi_inquiry(ide, channel) == -1) {
PrintError("IDE: Error in ATAPI inquiry (%x)\n", cmd);
return -1;
}
default:
PrintError("Unhandled ATAPI command %x\n", cmd);
- atapi_cmd_error(dev, channel, ATAPI_SEN_ILL_REQ, ASC_INV_CMD_FIELD);
- ide_raise_irq(dev, channel);
+ atapi_cmd_error(ide, channel, ATAPI_SEN_ILL_REQ, ASC_INV_CMD_FIELD);
+ ide_raise_irq(ide, channel);
return -1;
}
};
static int handle_info_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
- struct vm_device * dev = priv_data;
- struct debug_state * state = (struct debug_state *)dev->private_data;
+ struct debug_state * state = (struct debug_state *)priv_data;
state->info_buf[state->info_offset++] = *(char*)src;
static int handle_debug_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
- struct vm_device * dev = priv_data;
- struct debug_state * state = (struct debug_state *)dev->private_data;
+ struct debug_state * state = (struct debug_state *)priv_data;
state->debug_buf[state->debug_offset++] = *(char*)src;
static int handle_console_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
- struct vm_device * dev = priv_data;
- struct debug_state * state = (struct debug_state *)dev->private_data;
+ struct debug_state * state = (struct debug_state *)priv_data;
state->cons_buf[state->cons_offset++] = *(char *)src;
static int handle_gen_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
- //struct vm_device * dev = priv_data;
switch (length) {
case 1:
static int debug_free(struct vm_device * dev) {
struct debug_state * state = dev->private_data;
- v3_unhook_io_port(dev->vm, BOCHS_PORT1);
- v3_unhook_io_port(dev->vm, BOCHS_PORT2);
- v3_unhook_io_port(dev->vm, BOCHS_INFO_PORT);
- v3_unhook_io_port(dev->vm, BOCHS_DEBUG_PORT);
-
V3_Free(state);
return 0;
memset(state->cons_buf, 0, BUF_SIZE);
- ret |= v3_hook_io_port(vm, BOCHS_PORT1, NULL, &handle_gen_write, dev);
- ret |= v3_hook_io_port(vm, BOCHS_PORT2, NULL, &handle_gen_write, dev);
- ret |= v3_hook_io_port(vm, BOCHS_INFO_PORT, NULL, &handle_info_write, dev);
- ret |= v3_hook_io_port(vm, BOCHS_DEBUG_PORT, NULL, &handle_debug_write, dev);
- ret |= v3_hook_io_port(vm, BOCHS_CONSOLE_PORT, NULL, &handle_console_write, dev);
+ ret |= v3_dev_hook_io(dev, BOCHS_PORT1, NULL, &handle_gen_write);
+ ret |= v3_dev_hook_io(dev, BOCHS_PORT2, NULL, &handle_gen_write);
+ ret |= v3_dev_hook_io(dev, BOCHS_INFO_PORT, NULL, &handle_info_write);
+ ret |= v3_dev_hook_io(dev, BOCHS_DEBUG_PORT, NULL, &handle_debug_write);
+ ret |= v3_dev_hook_io(dev, BOCHS_CONSOLE_PORT, NULL, &handle_console_write);
if (ret != 0) {
PrintError("Could not hook Bochs Debug IO Ports\n");
}
static int video_read_port(struct guest_info * core, uint16_t port, void * dest, uint_t length, void * priv_data) {
- struct vm_device * dev = (struct vm_device *)priv_data;
- struct video_internal * video_state = (struct video_internal *)dev->private_data;
+ struct video_internal * video_state = priv_data;
PrintDebug("Video: Read port 0x%x\n", port);
static int video_write_port(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data) {
- struct vm_device * dev = (struct vm_device *)priv_data;
- struct video_internal * video_state = (struct video_internal *)dev->private_data;
+ struct video_internal * video_state = priv_data;
PrintDebug("Video: write port 0x%x...\n", port);
static int crtc_data_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data) {
- struct vm_device * dev = (struct vm_device *)priv_data;
- struct video_internal * video_state = (struct video_internal *)dev->private_data;
+ struct video_internal * video_state = priv_data;
uint8_t val = *(uint8_t *)src;
uint_t index = video_state->crtc_index_reg;
static int crtc_index_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data) {
- struct vm_device * dev = (struct vm_device *)priv_data;
- struct video_internal * video_state = (struct video_internal *)dev->private_data;
+ struct video_internal * video_state = priv_data;
if (length > 2) {
PrintError("Invalid write length for crtc index register port: %d (0x%x)\n",
}
if (length == 2) {
- if (crtc_data_write(core, port + 1, src + 1, length - 1, dev) != (length - 1)) {
+ if (crtc_data_write(core, port + 1, src + 1, length - 1, video_state) != (length - 1)) {
PrintError("could not handle implicit crtc data write\n");
return -1;
}
static int free_device(struct vm_device * dev) {
struct video_internal * video_state = (struct video_internal *)dev->private_data;
- struct v3_vm_info * vm = dev->vm;
if (video_state->framebuf_pa) {
V3_FreePages((void *)(video_state->framebuf_pa), (FRAMEBUF_SIZE / 4096));
v3_unhook_mem(dev->vm, V3_MEM_CORE_ANY, START_ADDR);
- v3_unhook_io_port(vm, 0x3b0);
- v3_unhook_io_port(vm, 0x3b1);
- v3_unhook_io_port(vm, 0x3b2);
- v3_unhook_io_port(vm, 0x3b3);
- v3_unhook_io_port(vm, 0x3b4);
- v3_unhook_io_port(vm, 0x3b5);
- v3_unhook_io_port(vm, 0x3b6);
- v3_unhook_io_port(vm, 0x3b7);
- v3_unhook_io_port(vm, 0x3b8);
- v3_unhook_io_port(vm, 0x3b9);
- v3_unhook_io_port(vm, 0x3ba);
- v3_unhook_io_port(vm, 0x3bb);
- v3_unhook_io_port(vm, 0x3c0);
- v3_unhook_io_port(vm, 0x3c1);
- v3_unhook_io_port(vm, 0x3c2);
- v3_unhook_io_port(vm, 0x3c3);
- v3_unhook_io_port(vm, 0x3c4);
- v3_unhook_io_port(vm, 0x3c5);
- v3_unhook_io_port(vm, 0x3c6);
- v3_unhook_io_port(vm, 0x3c7);
- v3_unhook_io_port(vm, 0x3c8);
- v3_unhook_io_port(vm, 0x3c9);
- v3_unhook_io_port(vm, 0x3ca);
- v3_unhook_io_port(vm, 0x3cb);
- v3_unhook_io_port(vm, 0x3cc);
- v3_unhook_io_port(vm, 0x3cd);
- v3_unhook_io_port(vm, 0x3ce);
- v3_unhook_io_port(vm, 0x3cf);
- v3_unhook_io_port(vm, 0x3d0);
- v3_unhook_io_port(vm, 0x3d1);
- v3_unhook_io_port(vm, 0x3d2);
- v3_unhook_io_port(vm, 0x3d3);
- v3_unhook_io_port(vm, 0x3d4);
- v3_unhook_io_port(vm, 0x3d5);
- v3_unhook_io_port(vm, 0x3d6);
- v3_unhook_io_port(vm, 0x3d7);
- v3_unhook_io_port(vm, 0x3d8);
- v3_unhook_io_port(vm, 0x3d9);
- v3_unhook_io_port(vm, 0x3da);
- v3_unhook_io_port(vm, 0x3db);
- v3_unhook_io_port(vm, 0x3dc);
- v3_unhook_io_port(vm, 0x3dd);
- v3_unhook_io_port(vm, 0x3de);
- v3_unhook_io_port(vm, 0x3df);
V3_Free(video_state);
}
- v3_hook_io_port(vm, 0x3b0, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3b1, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3b2, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3b3, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3b4, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3b5, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3b6, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3b7, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3b8, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3b9, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3ba, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3bb, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3c0, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3c1, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3c2, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3c3, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3c4, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3c5, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3c6, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3c7, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3c8, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3c9, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3ca, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3cb, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3cc, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3cd, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3ce, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3cf, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3d0, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3d1, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3d2, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3d3, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3d4, &video_read_port, &crtc_index_write, dev);
- v3_hook_io_port(vm, 0x3d5, &video_read_port, &crtc_data_write, dev);
- v3_hook_io_port(vm, 0x3d6, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3d7, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3d8, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3d9, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3da, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3db, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3dc, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3dd, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3de, &video_read_port, &video_write_port, dev);
- v3_hook_io_port(vm, 0x3df, &video_read_port, &video_write_port, dev);
+ v3_dev_hook_io(dev, 0x3b0, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3b1, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3b2, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3b3, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3b4, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3b5, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3b6, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3b7, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3b8, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3b9, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3ba, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3bb, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3c0, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3c1, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3c2, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3c3, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3c4, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3c5, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3c6, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3c7, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3c8, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3c9, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3ca, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3cb, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3cc, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3cd, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3ce, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3cf, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3d0, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3d1, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3d2, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3d3, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3d4, &video_read_port, &crtc_index_write);
+ v3_dev_hook_io(dev, 0x3d5, &video_read_port, &crtc_data_write);
+ v3_dev_hook_io(dev, 0x3d6, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3d7, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3d8, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3d9, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3da, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3db, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3dc, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3dd, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3de, &video_read_port, &video_write_port);
+ v3_dev_hook_io(dev, 0x3df, &video_read_port, &video_write_port);
return 0;
GENERIC_PRINT_AND_IGNORE} generic_mode_t;
struct generic_internal {
- struct list_head port_list;
- uint_t num_port_ranges;
-
};
static int generic_free(struct vm_device * dev) {
struct generic_internal * state = (struct generic_internal *)(dev->private_data);
- struct port_range * tmp;
- struct port_range * cur;
PrintDebug("generic: deinit_device\n");
- list_for_each_entry_safe(cur, tmp, &(state->port_list), range_link) {
- uint_t i;
-
- PrintDebug("generic: unhooking ports 0x%x to 0x%x\n",
- cur->start, cur->end);
-
- for (i = cur->start; i <= cur->end; i++) {
- if (v3_unhook_io_port(dev->vm, i)) {
- PrintDebug("generic: can't unhook port 0x%x (already unhooked?)\n", i);
- }
- }
-
- list_del(&(cur->range_link));
- state->num_port_ranges--;
- V3_Free(cur);
- }
-
V3_Free(state);
return 0;
}
static int add_port_range(struct vm_device * dev, uint_t start, uint_t end, generic_mode_t mode) {
- struct generic_internal * state = (struct generic_internal *)(dev->private_data);
- struct port_range * range = (struct port_range *)V3_Malloc(sizeof(struct port_range));
uint_t i = 0;
- range->start = start;
- range->end = end;
- range->mode = mode;
-
PrintDebug("generic: Adding Port Range: 0x%x to 0x%x as %s\n",
start, end,
(mode == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore");
for (i = start; i <= end; i++) {
if (mode == GENERIC_PRINT_AND_PASSTHROUGH) {
- if (v3_hook_io_port(dev->vm, i,
+ if (v3_dev_hook_io(dev, i,
&generic_read_port_passthrough,
- &generic_write_port_passthrough, dev) == -1) {
+ &generic_write_port_passthrough) == -1) {
PrintError("generic: can't hook port 0x%x (already hooked?)\n", i);
return -1;
}
} else if (mode == GENERIC_PRINT_AND_IGNORE) {
- if (v3_hook_io_port(dev->vm, i,
+ if (v3_dev_hook_io(dev, i,
&generic_read_port_ignore,
- &generic_write_port_ignore, dev) == -1) {
+ &generic_write_port_ignore) == -1) {
PrintError("generic: can't hook port 0x%x (already hooked?)\n", i);
return -1;
}
}
}
-
- list_add(&(range->range_link), &(state->port_list));
- state->num_port_ranges++;
return 0;
}
}
memset(state, 0, sizeof(struct generic_internal));
-
- INIT_LIST_HEAD(&(state->port_list));
- state->num_port_ranges = 0;
struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
static int io_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
- // struct vm_device * dev = priv_data;
PrintError("Unhandled read on port %x\n", port);
return -1;
}
static int io_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
- // struct vm_device * dev = priv_data;
PrintError("Unhandled write on port %x\n", port);
return -1;
}
static int i440_free(struct vm_device * dev) {
struct i440_state * state = dev->private_data;
- int i;
-
- for (i = 0; i < 4; i++) {
- v3_unhook_io_port(dev->vm, 0x0cf8 + i);
- v3_unhook_io_port(dev->vm, 0x0cfc + i);
- }
// unregister from PCI
}
for (i = 0; i < 4; i++) {
- v3_hook_io_port(vm, 0x0cf8 + i, &io_read, &io_write, dev);
- v3_hook_io_port(vm, 0x0cfc + i, &io_read, &io_write, dev);
+ v3_dev_hook_io(dev, 0x0cf8 + i, &io_read, &io_write);
+ v3_dev_hook_io(dev, 0x0cfc + i, &io_read, &io_write);
}
for (i = 0; i < 6; i++) {
struct vm_device * pci_bus;
struct pci_device * ide_pci;
+
+ struct v3_vm_info * vm;
};
/* Drive Commands */
-static void ide_raise_irq(struct vm_device * dev, struct ide_channel * channel) {
+static void ide_raise_irq(struct ide_internal * ide, struct ide_channel * channel) {
if (channel->ctrl_reg.irq_disable == 0) {
// PrintError("Raising IDE Interrupt %d\n", channel->irq);
channel->dma_status.int_gen = 1;
- v3_raise_irq(dev->vm, channel->irq);
+ v3_raise_irq(ide->vm, channel->irq);
}
}
}
-static void ide_abort_command(struct vm_device * dev, struct ide_channel * channel) {
+static void ide_abort_command(struct ide_internal * ide, struct ide_channel * channel) {
channel->status.val = 0x41; // Error + ready
channel->error_reg.val = 0x04; // No idea...
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
}
-static int dma_read(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel);
-static int dma_write(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel);
+static int dma_read(struct guest_info * core, struct ide_internal * ide, struct ide_channel * channel);
+static int dma_write(struct guest_info * core, struct ide_internal * ide, struct ide_channel * channel);
/* ATAPI functions */
#endif
/* IO Operations */
-static int dma_read(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel) {
+static int dma_read(struct guest_info * core, struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
// This is at top level scope to do the EOT test at the end
struct ide_dma_prd prd_entry = {};
// Read a sector/block at a time until the prd entry is full.
#ifdef CONFIG_DEBUG_IDE
- print_prd_table(dev, channel);
+ print_prd_table(ide, channel);
#endif
PrintDebug("DMA read for %d bytes\n", bytes_left);
bytes_to_write = (prd_bytes_left > HD_SECTOR_SIZE) ? HD_SECTOR_SIZE : prd_bytes_left;
- if (ata_read(dev, channel, drive->data_buf, 1) == -1) {
+ if (ata_read(ide, channel, drive->data_buf, 1) == -1) {
PrintError("Failed to read next disk sector\n");
return -1;
}
if (atapi_cmd_is_data_op(drive->cd_state.atapi_cmd)) {
bytes_to_write = (prd_bytes_left > ATAPI_BLOCK_SIZE) ? ATAPI_BLOCK_SIZE : prd_bytes_left;
- if (atapi_read_chunk(dev, channel) == -1) {
+ if (atapi_read_chunk(ide, channel) == -1) {
PrintError("Failed to read next disk sector\n");
return -1;
}
channel->dma_status.err = 0;
}
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
return 0;
}
-static int dma_write(struct guest_info * core, struct vm_device * dev, struct ide_channel * channel) {
+static int dma_write(struct guest_info * core, struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
// This is at top level scope to do the EOT test at the end
struct ide_dma_prd prd_entry = {};
PrintDebug("\t DMA ret=%d (prd_bytes_left=%d) (bytes_left=%d)\n", ret, prd_bytes_left, bytes_left);
- if (ata_write(dev, channel, drive->data_buf, 1) == -1) {
+ if (ata_write(ide, channel, drive->data_buf, 1) == -1) {
PrintError("Failed to write data to disk\n");
return -1;
}
channel->dma_status.err = 0;
}
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
return 0;
}
#define DMA_CHANNEL_FLAG 0x08
static int write_dma_port(struct guest_info * core, ushort_t port, void * src, uint_t length, void * private_data) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+ struct ide_internal * ide = (struct ide_internal *)private_data;
uint16_t port_offset = port & (DMA_CHANNEL_FLAG - 1);
uint_t channel_flag = (port & DMA_CHANNEL_FLAG) >> 3;
struct ide_channel * channel = &(ide->channels[channel_flag]);
if (channel->dma_cmd.read == 1) {
// DMA Read
- if (dma_read(core, dev, channel) == -1) {
+ if (dma_read(core, ide, channel) == -1) {
PrintError("Failed DMA Read\n");
return -1;
}
} else {
// DMA write
- if (dma_write(core, dev, channel) == -1) {
+ if (dma_write(core, ide, channel) == -1) {
PrintError("Failed DMA Write\n");
return -1;
}
static int read_dma_port(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * private_data) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+ struct ide_internal * ide = (struct ide_internal *)private_data;
uint16_t port_offset = port & (DMA_CHANNEL_FLAG - 1);
uint_t channel_flag = (port & DMA_CHANNEL_FLAG) >> 3;
struct ide_channel * channel = &(ide->channels[channel_flag]);
-static int write_cmd_port(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+static int write_cmd_port(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct ide_internal * ide = priv_data;
struct ide_channel * channel = get_selected_channel(ide, port);
struct ide_drive * drive = get_selected_drive(channel);
drive_reset(drive);
// JRL: Should we abort here?
- ide_abort_command(dev, channel);
+ ide_abort_command(ide, channel);
} else {
atapi_identify_device(drive);
channel->error_reg.val = 0;
channel->status.val = 0x58; // ready, data_req, seek_complete
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
}
break;
case 0xec: // Identify Device
drive_reset(drive);
// JRL: Should we abort here?
- ide_abort_command(dev, channel);
+ ide_abort_command(ide, channel);
} else {
ata_identify_device(drive);
channel->error_reg.val = 0;
channel->status.val = 0x58;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
}
break;
case 0xa0: // ATAPI Command Packet
if (drive->drive_type != BLOCK_CDROM) {
- ide_abort_command(dev, channel);
+ ide_abort_command(ide, channel);
}
drive->sector_count = 1;
case 0x21: // Read Sectors without Retry
drive->hd_state.cur_sector_num = 1;
- if (ata_read_sectors(dev, channel) == -1) {
+ if (ata_read_sectors(ide, channel) == -1) {
PrintError("Error reading sectors\n");
return -1;
}
case 0x24: // Read Sectors Extended
drive->hd_state.cur_sector_num = 1;
- if (ata_read_sectors_ext(dev, channel) == -1) {
+ if (ata_read_sectors_ext(ide, channel) == -1) {
PrintError("Error reading extended sectors\n");
return -1;
}
case 0xc9: { // Read DMA
uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
- if (ata_get_lba(dev, channel, &(drive->current_lba)) == -1) {
- ide_abort_command(dev, channel);
+ if (ata_get_lba(ide, channel, &(drive->current_lba)) == -1) {
+ ide_abort_command(ide, channel);
return 0;
}
if (channel->dma_status.active == 1) {
// DMA Read
- if (dma_read(core, dev, channel) == -1) {
+ if (dma_read(core, ide, channel) == -1) {
PrintError("Failed DMA Read\n");
return -1;
}
case 0xca: { // Write DMA
uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
- if (ata_get_lba(dev, channel, &(drive->current_lba)) == -1) {
- ide_abort_command(dev, channel);
+ if (ata_get_lba(ide, channel, &(drive->current_lba)) == -1) {
+ ide_abort_command(ide, channel);
return 0;
}
if (channel->dma_status.active == 1) {
// DMA Write
- if (dma_write(core, dev, channel) == -1) {
+ if (dma_write(core, ide, channel) == -1) {
PrintError("Failed DMA Write\n");
return -1;
}
case 0x99: // Sleep Now 2
channel->status.val = 0;
channel->status.ready = 1;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
break;
case 0xef: // Set Features
channel->status.ready = 1;
channel->status.seek_complete = 1;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
break;
case 0x91: // Initialize Drive Parameters
channel->status.error = 0;
channel->status.ready = 1;
channel->status.seek_complete = 1;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
break;
case 0xc6: { // Set multiple mode (IDE Block mode)
// This makes the drive transfer multiple sectors before generating an interrupt
uint32_t tmp_sect_num = drive->sector_num; // GCC SUCKS
if (tmp_sect_num > MAX_MULT_SECTORS) {
- ide_abort_command(dev, channel);
+ ide_abort_command(ide, channel);
break;
}
channel->status.ready = 1;
channel->status.error = 0;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
break;
}
}
-static int write_data_port(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+static int write_data_port(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct ide_internal * ide = priv_data;
struct ide_channel * channel = get_selected_channel(ide, port);
struct ide_drive * drive = get_selected_drive(channel);
return -1;
case 0xa0: // ATAPI packet command
- if (atapi_handle_packet(core, dev, channel) == -1) {
+ if (atapi_handle_packet(core, ide, channel) == -1) {
PrintError("Error handling ATAPI packet\n");
return -1;
}
}
-static int read_hd_data(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
+static int read_hd_data(uint8_t * dst, uint_t length, struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
int data_offset = drive->transfer_index % HD_SECTOR_SIZE;
if ((data_offset == 0) && (drive->transfer_index > 0)) {
drive->current_lba++;
- if (ata_read(dev, channel, drive->data_buf, 1) == -1) {
+ if (ata_read(ide, channel, drive->data_buf, 1) == -1) {
PrintError("Could not read next disk sector\n");
return -1;
}
drive->irq_flags.io_dir = 1;
channel->status.busy = 0;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
}
-static int read_cd_data(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
+static int read_cd_data(uint8_t * dst, uint_t length, struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
int data_offset = drive->transfer_index % ATAPI_BLOCK_SIZE;
int req_offset = drive->transfer_index % drive->req_len;
if ((data_offset == 0) && (drive->transfer_index > 0)) {
- if (atapi_update_data_buf(dev, channel) == -1) {
+ if (atapi_update_data_buf(ide, channel) == -1) {
PrintError("Could not update CDROM data buffer\n");
return -1;
}
drive->irq_flags.c_d = 0;
// Update the request length in the cylinder regs
- if (atapi_update_req_len(dev, channel, drive->transfer_length - drive->transfer_index) == -1) {
+ if (atapi_update_req_len(ide, channel, drive->transfer_length - drive->transfer_index) == -1) {
PrintError("Could not update request length after completed increment\n");
return -1;
}
drive->irq_flags.io_dir = 1;
channel->status.busy = 0;
- ide_raise_irq(dev, channel);
+ ide_raise_irq(ide, channel);
}
return length;
}
-static int read_drive_id( uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
+static int read_drive_id( uint8_t * dst, uint_t length, struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
channel->status.busy = 0;
}
-static int ide_read_data_port(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+static int ide_read_data_port(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
+ struct ide_internal * ide = priv_data;
struct ide_channel * channel = get_selected_channel(ide, port);
struct ide_drive * drive = get_selected_drive(channel);
if ((channel->cmd_reg == 0xec) ||
(channel->cmd_reg == 0xa1)) {
- return read_drive_id((uint8_t *)dst, length, dev, channel);
+ return read_drive_id((uint8_t *)dst, length, ide, channel);
}
if (drive->drive_type == BLOCK_CDROM) {
- if (read_cd_data((uint8_t *)dst, length, dev, channel) == -1) {
+ if (read_cd_data((uint8_t *)dst, length, ide, channel) == -1) {
PrintError("IDE: Could not read CD Data\n");
return -1;
}
} else if (drive->drive_type == BLOCK_DISK) {
- if (read_hd_data((uint8_t *)dst, length, dev, channel) == -1) {
+ if (read_hd_data((uint8_t *)dst, length, ide, channel) == -1) {
PrintError("IDE: Could not read HD Data\n");
return -1;
}
return length;
}
-static int write_port_std(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+static int write_port_std(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct ide_internal * ide = priv_data;
struct ide_channel * channel = get_selected_channel(ide, port);
struct ide_drive * drive = get_selected_drive(channel);
}
-static int read_port_std(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+static int read_port_std(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
+ struct ide_internal * ide = priv_data;
struct ide_channel * channel = get_selected_channel(ide, port);
struct ide_drive * drive = get_selected_drive(channel);
return 0;
}
-static int init_ide_state(struct vm_device * dev) {
- struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+static int init_ide_state(struct ide_internal * ide) {
int i;
/*
memset(ide, 0, sizeof(struct ide_internal));
+ ide->vm = vm;
ide->pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
return -1;
}
- if (init_ide_state(dev) == -1) {
+ if (init_ide_state(ide) == -1) {
PrintError("Failed to initialize IDE state\n");
v3_detach_device(dev);
return -1;
struct queue kbd_queue;
struct queue mouse_queue;
+ struct v3_vm_info * vm;
+
v3_lock_t kb_lock;
};
-static int update_kb_irq(struct vm_device * dev) {
- struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
+static int update_kb_irq(struct keyboard_internal * state) {
int irq_num = 0;
state->status.out_buf_full = 1;
if (state->cmd.irq_en == 1) {
- v3_raise_irq(dev->vm, irq_num);
+ v3_raise_irq(state->vm, irq_num);
}
}
* If we keep reading an empty queue we return the last queue entry
*/
-static int push_to_output_queue(struct vm_device * dev, uint8_t value, uint8_t cmd, uint8_t mouse) {
- struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data);
+static int push_to_output_queue(struct keyboard_internal * state, uint8_t value, uint8_t cmd, uint8_t mouse) {
struct queue * q = NULL;
q->count++;
- update_kb_irq(dev);
+ update_kb_irq(state);
return 0;
}
-static int pull_from_output_queue(struct vm_device * dev, uint8_t * value) {
- struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data);
+static int pull_from_output_queue(struct keyboard_internal * state, uint8_t * value) {
struct queue * q = NULL;
if (state->kbd_queue.count > 0) {
PrintDebug("Read from Queue: %x\n", *value);
PrintDebug("QStart=%d, QEnd=%d\n", q->start, q->end);
- update_kb_irq(dev);
+ update_kb_irq(state);
return 0;
}
static int key_event_handler(struct v3_vm_info * vm,
struct v3_keyboard_event * evt,
void * private_data) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
+ struct keyboard_internal * state = (struct keyboard_internal *)private_data;
PrintDebug("keyboard: injected status 0x%x, and scancode 0x%x\n", evt->status, evt->scan_code);
if ( (state->status.enabled == 1) // onboard is enabled
&& (state->cmd.disable == 0) ) { // keyboard is enabled
- push_to_output_queue(dev, evt->scan_code, DATA, KEYBOARD);
+ push_to_output_queue(state, evt->scan_code, DATA, KEYBOARD);
}
v3_unlock_irqrestore(state->kb_lock, irq_state);
static int mouse_event_handler(struct v3_vm_info * vm,
struct v3_mouse_event * evt,
void * private_data) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data);
+ struct keyboard_internal * kbd = (struct keyboard_internal *)private_data;
int ret = 0;
PrintDebug("keyboard: injected mouse packet 0x %x %x %x\n",
evt->data[0], evt->data[1], evt->data[2]);
- addr_t irq_state = v3_lock_irqsave(state->kb_lock);
+ addr_t irq_state = v3_lock_irqsave(kbd->kb_lock);
- switch (state->mouse_state) {
+ switch (kbd->mouse_state) {
case STREAM:
- if (state->cmd.mouse_disable == 0) {
- push_to_output_queue(dev, evt->data[0], DATA, MOUSE);
- push_to_output_queue(dev, evt->data[1], DATA, MOUSE);
- push_to_output_queue(dev, evt->data[2], DATA, MOUSE);
+ if (kbd->cmd.mouse_disable == 0) {
+ push_to_output_queue(kbd, evt->data[0], DATA, MOUSE);
+ push_to_output_queue(kbd, evt->data[1], DATA, MOUSE);
+ push_to_output_queue(kbd, evt->data[2], DATA, MOUSE);
}
break;
default:
}
- v3_unlock_irqrestore(state->kb_lock, irq_state);
+ v3_unlock_irqrestore(kbd->kb_lock, irq_state);
return ret;
}
-static int keyboard_reset_device(struct vm_device * dev) {
- struct keyboard_internal * data = (struct keyboard_internal *)(dev->private_data);
+static int keyboard_reset_device(struct keyboard_internal * kbd) {
- memset(data, 0, sizeof(struct keyboard_internal));
+ memset(kbd, 0, sizeof(struct keyboard_internal));
- data->state = NORMAL;
- data->mouse_state = STREAM;
+ kbd->state = NORMAL;
+ kbd->mouse_state = STREAM;
// PS2, keyboard+mouse enabled, generic translation
- data->cmd.val = 0;
+ kbd->cmd.val = 0;
- data->cmd.irq_en = 1;
- data->cmd.mouse_irq_en = 1;
- data->cmd.self_test_ok = 1;
+ kbd->cmd.irq_en = 1;
+ kbd->cmd.mouse_irq_en = 1;
+ kbd->cmd.self_test_ok = 1;
/** **/
// buffers empty, no errors
- data->status.val = 0;
+ kbd->status.val = 0;
- data->status.self_test_ok = 1; // self-tests passed
- data->status.enabled = 1;// keyboard ready
+ kbd->status.self_test_ok = 1; // self-tests passed
+ kbd->status.enabled = 1;// keyboard ready
/** **/
- data->output_byte = 0; // ?
+ kbd->output_byte = 0; // ?
- data->input_byte = INPUT_RAM; // we have some
+ kbd->input_byte = INPUT_RAM; // we have some
// also display=color, jumper 0, keyboard enabled
PrintDebug("keyboard: reset device\n");
-static int keyboard_start_device(struct vm_device * dev) {
- PrintDebug("keyboard: start device\n");
- return 0;
-}
-
-
-static int keyboard_stop_device(struct vm_device * dev) {
- PrintDebug("keyboard: stop device\n");
- return 0;
-}
-static int mouse_write_output(struct vm_device * dev, uint8_t data) {
- struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data);
- switch (state->mouse_state) {
+static int mouse_write_output(struct keyboard_internal * kbd, uint8_t data) {
+ switch (kbd->mouse_state) {
case NORMAL:
switch (data) {
case 0xff: //reset
- if (state->mouse_enabled == 0) {
- push_to_output_queue(dev, 0xfe, DATA, MOUSE) ; // no mouse!
+ if (kbd->mouse_enabled == 0) {
+ push_to_output_queue(kbd, 0xfe, DATA, MOUSE) ; // no mouse!
} else {
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
- push_to_output_queue(dev, 0xaa, DATA, MOUSE) ;
- push_to_output_queue(dev, 0x00, DATA, MOUSE) ;
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, 0xaa, DATA, MOUSE) ;
+ push_to_output_queue(kbd, 0x00, DATA, MOUSE) ;
}
break;
/* case 0xfe: //resend */
-/* PushToOutputQueue(dev, 0xfa, OVERWRITE, DATA, MOUSE) ; */
+/* PushToOutputQueue(kbd, 0xfa, OVERWRITE, DATA, MOUSE) ; */
/* PrintDebug(" mouse resend begins "); */
-/* state->mouse_done_after_ack = 0; */
-/* state->mouse_needs_ack = 0; */
-/* state->mouse_state = STREAM1; */
+/* kbd->mouse_done_after_ack = 0; */
+/* kbd->mouse_needs_ack = 0; */
+/* kbd->mouse_state = STREAM1; */
/* return 0; // not done */
/* break; */
case 0xf6: // set defaults
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
PrintDebug(" mouse set defaults ");
break;
case 0xf5: // disable data reporting
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
PrintDebug(" mouse disable data reporting ");
break;
case 0xf4: // enable data reporting
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
PrintDebug(" mouse enable data reporting ");
break;
case 0xf3: // set sample rate
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
- state->mouse_state = SAMPLE;
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
+ kbd->mouse_state = SAMPLE;
PrintDebug(" mouse set sample rate begins ");
break;
case 0xf2: // get device id
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
- push_to_output_queue(dev, 0x0, DATA, MOUSE);
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, 0x0, DATA, MOUSE);
PrintDebug(" mouse get device id begins ");
break;
case 0xf0: // set remote mode
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
PrintDebug(" mouse set remote mode ");
break;
case 0xee: // set wrap mode
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
PrintError(" mouse set wrap mode (ignored) ");
break;
case 0xec: // reset wrap mode
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
PrintError(" mouse reset wrap mode (ignored) ");
break;
case 0xeb: // read data
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
PrintError(" mouse switch to wrap mode (ignored) ");
break;
case 0xea: // set stream mode
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
PrintDebug(" mouse set stream mode ");
break;
case 0xe9: // status request
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
- push_to_output_queue(dev, 0x00, DATA, MOUSE);
- push_to_output_queue(dev, 0x00, DATA, MOUSE);
- push_to_output_queue(dev, 0x00, DATA, MOUSE);
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, 0x00, DATA, MOUSE);
+ push_to_output_queue(kbd, 0x00, DATA, MOUSE);
+ push_to_output_queue(kbd, 0x00, DATA, MOUSE);
PrintDebug(" mouse status request begins ");
break;
case 0xe8: // set resolution
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
PrintDebug(" mouse set resolution begins ");
- state->mouse_state = SET_RES;
+ kbd->mouse_state = SET_RES;
break;
case 0xe7: // set scaling 2:1
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
PrintDebug(" mouse set scaling 2:1 ");
break;
case 0xe6: // set scaling 1:1
- push_to_output_queue(dev, MOUSE_ACK, DATA, MOUSE) ;
+ push_to_output_queue(kbd, MOUSE_ACK, DATA, MOUSE) ;
PrintDebug(" mouse set scaling 1:1 ");
break;
default:
- PrintDebug(" receiving unknown mouse command (0x%x) in acceptable state ", data);
+ PrintDebug(" receiving unknown mouse command (0x%x) in acceptable kbd ", data);
break;
}
case SAMPLE:
case SET_RES:
default:
- PrintDebug(" receiving mouse output in unhandled state (0x%x) ", state->mouse_state);
+ PrintDebug(" receiving mouse output in unhandled kbd (0x%x) ", kbd->mouse_state);
return -1;
}
#if KEYBOARD_DEBUG_80H
-static int keyboard_write_delay(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int keyboard_write_delay(ushort_t port, void * src, uint_t length, void * priv_data) {
if (length == 1) {
PrintDebug("keyboard: write of 0x%x to 80h\n", *((uint8_t*)src));
}
}
-static int keyboard_read_delay(struct guest_info * core, ushort_t port, void * dest, uint_t length, struct vm_device * dev) {
+static int keyboard_read_delay(struct guest_info * core, ushort_t port, void * dest, uint_t length, void * priv_data) {
if (length == 1) {
*(uint8_t *)dest = v3_inb(port);
-static int keyboard_write_command(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data);
+static int keyboard_write_command(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct keyboard_internal * kbd = priv_data;
uint8_t cmd = *(uint8_t *)src;
// Should always be single byte write
}
- addr_t irq_state = v3_lock_irqsave(state->kb_lock);
+ addr_t irq_state = v3_lock_irqsave(kbd->kb_lock);
- if (state->state != NORMAL) {
+ if (kbd->state != NORMAL) {
PrintDebug("keyboard: warning - receiving command on 64h but state != NORMAL\n");
}
switch (cmd) {
case 0x20: // READ COMMAND BYTE (returned in 60h)
- push_to_output_queue(dev, state->cmd.val, COMMAND, KEYBOARD);
- PrintDebug("keyboard: command byte 0x%x returned\n", state->cmd.val);
+ push_to_output_queue(kbd, kbd->cmd.val, COMMAND, KEYBOARD);
+ PrintDebug("keyboard: command byte 0x%x returned\n", kbd->cmd.val);
break;
case 0x60: // WRITE COMMAND BYTE (read from 60h)
- state->state = WRITING_CMD_BYTE; // we need to make sure we send the next 0x60 byte appropriately
+ kbd->state = WRITING_CMD_BYTE; // we need to make sure we send the next 0x60 byte appropriately
PrintDebug("keyboard: prepare to write command byte\n");
break;
// case 0x90-9f - write to output port (?)
case 0xa1: // Get version number
- push_to_output_queue(dev, 0x00, COMMAND, KEYBOARD);
+ push_to_output_queue(kbd, 0x00, COMMAND, KEYBOARD);
PrintDebug("keyboard: version number 0x0 returned\n");
break;
case 0xa4: // is password installed? send result to 0x60
// we don't support passwords
- push_to_output_queue(dev, 0xf1, COMMAND, KEYBOARD);
+ push_to_output_queue(kbd, 0xf1, COMMAND, KEYBOARD);
PrintDebug("keyboard: password not installed\n");
break;
case 0xa5: // new password will arrive on 0x60
- state->state = TRANSMIT_PASSWD;
+ kbd->state = TRANSMIT_PASSWD;
PrintDebug("keyboard: pepare to transmit password\n");
break;
break;
case 0xa7: // disable mouse
- state->cmd.mouse_disable = 1;
+ kbd->cmd.mouse_disable = 1;
PrintDebug("keyboard: mouse disabled\n");
break;
case 0xa8: // enable mouse
- state->cmd.mouse_disable = 0;
+ kbd->cmd.mouse_disable = 0;
PrintDebug("keyboard: mouse enabled\n");
break;
case 0xa9: // mouse interface test (always succeeds)
- push_to_output_queue(dev, 0x00, COMMAND, KEYBOARD);
+ push_to_output_queue(kbd, 0x00, COMMAND, KEYBOARD);
PrintDebug("keyboard: mouse interface test succeeded\n");
break;
case 0xaa: // controller self test (always succeeds)
- push_to_output_queue(dev, 0x55, COMMAND, KEYBOARD);
+ push_to_output_queue(kbd, 0x55, COMMAND, KEYBOARD);
PrintDebug("keyboard: controller self test succeeded\n");
break;
case 0xab: // keyboard interface test (always succeeds)
- push_to_output_queue(dev, 0, COMMAND, KEYBOARD);
+ push_to_output_queue(kbd, 0, COMMAND, KEYBOARD);
PrintDebug("keyboard: keyboard interface test succeeded\n");
break;
case 0xad: // disable keyboard
- state->cmd.disable = 1;
+ kbd->cmd.disable = 1;
PrintDebug("keyboard: keyboard disabled\n");
break;
case 0xae: // enable keyboard
- state->cmd.disable = 0;
+ kbd->cmd.disable = 0;
PrintDebug("keyboard: keyboard enabled\n");
break;
case 0xaf: // get version
- push_to_output_queue(dev, 0x00, COMMAND, KEYBOARD);
+ push_to_output_queue(kbd, 0x00, COMMAND, KEYBOARD);
PrintDebug("keyboard: version 0 returned \n");
break;
case 0xd0: // return microcontroller output on 60h
- push_to_output_queue(dev, state->output_byte, COMMAND, KEYBOARD);
- PrintDebug("keyboard: output byte 0x%x returned\n", state->output_byte);
+ push_to_output_queue(kbd, kbd->output_byte, COMMAND, KEYBOARD);
+ PrintDebug("keyboard: output byte 0x%x returned\n", kbd->output_byte);
break;
case 0xd1: // request to write next byte on 60h to the microcontroller output port
- state->state = WRITING_OUTPUT_PORT;
+ kbd->state = WRITING_OUTPUT_PORT;
PrintDebug("keyboard: prepare to write output byte\n");
break;
case 0xd2: // write keyboard buffer (inject key)
- state->state = INJECTING_KEY;
+ kbd->state = INJECTING_KEY;
PrintDebug("keyboard: prepare to inject key\n");
break;
case 0xd3: // write mouse buffer (inject mouse)
- state->state = INJECTING_MOUSE;
+ kbd->state = INJECTING_MOUSE;
PrintDebug("keyboard: prepare to inject mouse\n");
break;
case 0xd4: // write mouse device (command to mouse?)
- state->state = IN_MOUSE;
+ kbd->state = IN_MOUSE;
PrintDebug("keyboard: prepare to inject mouse command\n");
break;
case 0xc0: // read input port
- push_to_output_queue(dev, state->input_byte, COMMAND, KEYBOARD);
- PrintDebug("keyboard: input byte 0x%x returned\n", state->input_byte);
+ push_to_output_queue(kbd, kbd->input_byte, COMMAND, KEYBOARD);
+ PrintDebug("keyboard: input byte 0x%x returned\n", kbd->input_byte);
break;
case 0xc1: //copy input port lsn to status msn
- state->status.val &= 0x0f;
- state->status.val |= (state->input_byte & 0xf) << 4;
+ kbd->status.val &= 0x0f;
+ kbd->status.val |= (kbd->input_byte & 0xf) << 4;
PrintDebug("keyboard: copied input byte low 4 bits to status reg hi 4 bits\n");
break;
case 0xc2: // copy input port msn to status msn
- state->status.val &= 0x0f;
- state->status.val |= (state->input_byte & 0xf0);
+ kbd->status.val &= 0x0f;
+ kbd->status.val |= (kbd->input_byte & 0xf0);
PrintDebug("keyboard: copied input byte hi 4 bits to status reg hi 4 bits\n");
break;
case 0xe0: // read test port
- push_to_output_queue(dev, state->output_byte >> 6, COMMAND, KEYBOARD);
- PrintDebug("keyboard: read 0x%x from test port\n", state->output_byte >> 6);
+ push_to_output_queue(kbd, kbd->output_byte >> 6, COMMAND, KEYBOARD);
+ PrintDebug("keyboard: read 0x%x from test port\n", kbd->output_byte >> 6);
break;
break;
}
- v3_unlock_irqrestore(state->kb_lock, irq_state);
+ v3_unlock_irqrestore(kbd->kb_lock, irq_state);
return length;
}
-static int keyboard_read_status(struct guest_info * core, ushort_t port, void * dest, uint_t length, struct vm_device * dev) {
- struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
+static int keyboard_read_status(struct guest_info * core, ushort_t port, void * dest, uint_t length, void * priv_data) {
+ struct keyboard_internal * kbd = priv_data;
if (length != 1) {
PrintError("keyboard: >1 byte read for status (64h)\n");
PrintDebug("keyboard: read status (64h): ");
- addr_t irq_state = v3_lock_irqsave(state->kb_lock);
+ addr_t irq_state = v3_lock_irqsave(kbd->kb_lock);
- *(uint8_t *)dest = state->status.val;
+ *(uint8_t *)dest = kbd->status.val;
- v3_unlock_irqrestore(state->kb_lock, irq_state);
+ v3_unlock_irqrestore(kbd->kb_lock, irq_state);
PrintDebug("0x%x\n", *(uint8_t *)dest);
return length;
}
-static int keyboard_write_output(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
+static int keyboard_write_output(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct keyboard_internal * kbd = priv_data;
int ret = length;
if (length != 1) {
PrintDebug("keyboard: output 0x%x on 60h\n", data);
- addr_t irq_state = v3_lock_irqsave(state->kb_lock);
+ addr_t irq_state = v3_lock_irqsave(kbd->kb_lock);
- switch (state->state) {
+ switch (kbd->state) {
case WRITING_CMD_BYTE:
- state->cmd.val = data;
- state->state = NORMAL;
- PrintDebug("keyboard: wrote new command byte 0x%x\n", state->cmd.val);
+ kbd->cmd.val = data;
+ kbd->state = NORMAL;
+ PrintDebug("keyboard: wrote new command byte 0x%x\n", kbd->cmd.val);
break;
case WRITING_OUTPUT_PORT:
- state->output_byte = data;
- state->state = NORMAL;
- PrintDebug("keyboard: wrote new output byte 0x%x\n", state->output_byte);
+ kbd->output_byte = data;
+ kbd->state = NORMAL;
+ PrintDebug("keyboard: wrote new output byte 0x%x\n", kbd->output_byte);
break;
case INJECTING_KEY:
- push_to_output_queue(dev, data, COMMAND, KEYBOARD); // probably should be a call to deliver_key_to_vmm()
- state->state = NORMAL;
+ push_to_output_queue(kbd, data, COMMAND, KEYBOARD); // probably should be a call to deliver_key_to_vmm()
+ kbd->state = NORMAL;
PrintDebug("keyboard: injected key 0x%x\n", data);
break;
case INJECTING_MOUSE:
- push_to_output_queue(dev, data, DATA, MOUSE);
+ push_to_output_queue(kbd, data, DATA, MOUSE);
// PrintDebug("keyboard: ignoring injected mouse event 0x%x\n", data);
PrintDebug("keyboard: injected mouse event 0x%x\n", data);
- state->state = NORMAL;
+ kbd->state = NORMAL;
break;
case IN_MOUSE:
PrintDebug("keyboard: mouse action: ");
- if (mouse_write_output(dev, data)) {
- state->state = NORMAL;
+ if (mouse_write_output(kbd, data)) {
+ kbd->state = NORMAL;
}
PrintDebug("\n");
break;
PrintDebug("keyboard: ignoring password character 0x%x\n",data);
} else {
// end of password
- state->state = NORMAL;
+ kbd->state = NORMAL;
PrintDebug("keyboard: done with password\n");
}
break;
case SET_LEDS:
PrintDebug("Keyboard: LEDs being set...\n");
- push_to_output_queue(dev, 0xfa, COMMAND, KEYBOARD);
- state->state = NORMAL;
+ push_to_output_queue(kbd, 0xfa, COMMAND, KEYBOARD);
+ kbd->state = NORMAL;
break;
case SET_RATE:
PrintDebug("Keyboard: Rate being set...\n");
- push_to_output_queue(dev, 0xfa, COMMAND, KEYBOARD);
- state->state = NORMAL;
+ push_to_output_queue(kbd, 0xfa, COMMAND, KEYBOARD);
+ kbd->state = NORMAL;
break;
default:
// command is being sent to keyboard controller
switch (data) {
case 0xff: // reset
- push_to_output_queue(dev, 0xfa, COMMAND, KEYBOARD); // ack
- push_to_output_queue(dev, 0xaa, COMMAND, KEYBOARD);
+ push_to_output_queue(kbd, 0xfa, COMMAND, KEYBOARD); // ack
+ push_to_output_queue(kbd, 0xaa, COMMAND, KEYBOARD);
PrintDebug("keyboard: reset complete and acked\n");
break;
case 0xf5: // disable scanning
case 0xf4: // enable scanning
// ack
- push_to_output_queue(dev, 0xfa, COMMAND, KEYBOARD);
+ push_to_output_queue(kbd, 0xfa, COMMAND, KEYBOARD);
// should do something here... PAD
PrintDebug("keyboard: %s scanning done and acked\n", (data == 0xf5) ? "disable" : "enable");
break;
case 0xf3:
- push_to_output_queue(dev, 0xfa, COMMAND, KEYBOARD);
- state->state = SET_RATE;
+ push_to_output_queue(kbd, 0xfa, COMMAND, KEYBOARD);
+ kbd->state = SET_RATE;
break;
case 0xf2: // get keyboard ID
- push_to_output_queue(dev, 0xfa, COMMAND, KEYBOARD);
- push_to_output_queue(dev, 0xab, COMMAND, KEYBOARD);
- push_to_output_queue(dev, 0x83, COMMAND, KEYBOARD);
+ push_to_output_queue(kbd, 0xfa, COMMAND, KEYBOARD);
+ push_to_output_queue(kbd, 0xab, COMMAND, KEYBOARD);
+ push_to_output_queue(kbd, 0x83, COMMAND, KEYBOARD);
PrintDebug("Keyboard: Requesting Keyboard ID\n");
break;
case 0xed: // enable keyboard LEDs
- push_to_output_queue(dev, 0xfa, COMMAND, KEYBOARD);
- state->state = SET_LEDS;
+ push_to_output_queue(kbd, 0xfa, COMMAND, KEYBOARD);
+ kbd->state = SET_LEDS;
break;
case 0xee: // echo, used by FreeBSD to probe controller
- push_to_output_queue(dev, 0xee, COMMAND, KEYBOARD);
+ push_to_output_queue(kbd, 0xee, COMMAND, KEYBOARD);
break;
case 0xfe: // resend
default:
PrintError("keyboard: unhandled unknown command 0x%x on output buffer (60h)\n", data);
- state->status.out_buf_full = 1;
+ kbd->status.out_buf_full = 1;
ret = -1;
break;
}
}
}
- v3_unlock_irqrestore(state->kb_lock, irq_state);
+ v3_unlock_irqrestore(kbd->kb_lock, irq_state);
return ret;
}
-static int keyboard_read_input(struct guest_info * core, ushort_t port, void * dest, uint_t length, struct vm_device * dev) {
- struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data);
+static int keyboard_read_input(struct guest_info * core, ushort_t port, void * dest, uint_t length, void * priv_data) {
+ struct keyboard_internal * kbd = priv_data;
if (length != 1) {
PrintError("keyboard: unknown size read from input (60h)\n");
return -1;
}
- addr_t irq_state = v3_lock_irqsave(state->kb_lock);
+ addr_t irq_state = v3_lock_irqsave(kbd->kb_lock);
- pull_from_output_queue(dev, (uint8_t *)dest);
+ pull_from_output_queue(kbd, (uint8_t *)dest);
- v3_unlock_irqrestore(state->kb_lock, irq_state);
+ v3_unlock_irqrestore(kbd->kb_lock, irq_state);
PrintDebug("keyboard: read from input (60h): 0x%x\n", *(uint8_t *)dest);
static int keyboard_free(struct vm_device * dev) {
-
- v3_dev_unhook_io(dev, KEYBOARD_60H);
- v3_dev_unhook_io(dev, KEYBOARD_64H);
-#if KEYBOARD_DEBUG_80H
- v3_dev_unhook_io(dev, KEYBOARD_DELAY_80H);
-#endif
- keyboard_reset_device(dev);
+
return 0;
}
static struct v3_device_ops dev_ops = {
.free = keyboard_free,
- .reset = keyboard_reset_device,
- .start = keyboard_start_device,
- .stop = keyboard_stop_device,
+
};
static int keyboard_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
- struct keyboard_internal * keyboard_state = NULL;
+ struct keyboard_internal * kbd = NULL;
char * dev_id = v3_cfg_val(cfg, "ID");
PrintDebug("keyboard: init_device\n");
- keyboard_state = (struct keyboard_internal *)V3_Malloc(sizeof(struct keyboard_internal));
+ kbd = (struct keyboard_internal *)V3_Malloc(sizeof(struct keyboard_internal));
+
+ memset(kbd, 0, sizeof(struct keyboard_internal));
- memset(keyboard_state, 0, sizeof(struct keyboard_internal));
+ kbd->vm = vm;
- keyboard_state->mouse_queue.start = 0;
- keyboard_state->mouse_queue.end = 0;
- keyboard_state->mouse_queue.count = 0;
+ kbd->mouse_queue.start = 0;
+ kbd->mouse_queue.end = 0;
+ kbd->mouse_queue.count = 0;
- keyboard_state->kbd_queue.start = 0;
- keyboard_state->kbd_queue.end = 0;
- keyboard_state->kbd_queue.count = 0;
+ kbd->kbd_queue.start = 0;
+ kbd->kbd_queue.end = 0;
+ kbd->kbd_queue.count = 0;
- keyboard_state->mouse_enabled = 0;
+ kbd->mouse_enabled = 0;
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, keyboard_state);
+ struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, kbd);
if (v3_attach_device(vm, dev) == -1) {
PrintError("Could not attach device %s\n", dev_id);
return -1;
}
-
- keyboard_reset_device(dev);
+ keyboard_reset_device(kbd);
- v3_lock_init(&(keyboard_state->kb_lock));
+ v3_lock_init(&(kbd->kb_lock));
// hook ports
struct vm_device * ide;
+ struct v3_vm_info * vm;
+
v3_lock_t nvram_lock;
uint_t us; //microseconds - for clock update - zeroed every second
}
-static void update_time( struct vm_device * dev, uint_t period_us) {
- struct nvram_internal * data = (struct nvram_internal *) (dev->private_data);
+static void update_time(struct nvram_internal * data, uint_t period_us) {
struct rtc_stata * stata = (struct rtc_stata *) &((data->mem_state[NVRAM_REG_STAT_A]));
struct rtc_statb * statb = (struct rtc_statb *) &((data->mem_state[NVRAM_REG_STAT_B]));
struct rtc_statc * statc = (struct rtc_statc *) &((data->mem_state[NVRAM_REG_STAT_C]));
// Interrupt associated VM, if needed
if (statc->irq) {
PrintDebug("nvram: injecting interrupt\n");
- v3_raise_irq(dev->vm, NVRAM_RTC_IRQ);
+ v3_raise_irq(data->vm, NVRAM_RTC_IRQ);
}
}
struct v3_timer_event * evt,
void * priv_data) {
- struct vm_device * dev = (struct vm_device *)priv_data;
- if (dev) {
- struct nvram_internal * data = (struct nvram_internal *) (dev->private_data);
-
+ struct nvram_internal * data = priv_data;
+
+ if (data) {
addr_t irq_state = v3_lock_irqsave(data->nvram_lock);
- update_time(dev, evt->period_us);
+ update_time(data, evt->period_us);
v3_unlock_irqrestore(data->nvram_lock, irq_state);
}
}
}
-static int init_nvram_state(struct v3_vm_info * vm, struct vm_device * dev) {
+static int init_nvram_state(struct v3_vm_info * vm, struct nvram_internal * nvram) {
- struct nvram_internal * nvram = (struct nvram_internal *)dev->private_data;
-
memset(nvram->mem_state, 0, NVRAM_REG_MAX);
memset(nvram->reg_map, 0, NVRAM_REG_MAX / 8);
-static int nvram_reset_device(struct vm_device * dev) {
-
- return 0;
-}
-
-
-
-
-
-static int nvram_start_device(struct vm_device * dev) {
- PrintDebug("nvram: start device\n");
- return 0;
-}
-
-
-static int nvram_stop_device(struct vm_device * dev) {
- PrintDebug("nvram: stop device\n");
- return 0;
-}
-
-
static int nvram_write_reg_port(struct guest_info * core, ushort_t port,
- void * src, uint_t length, struct vm_device * dev) {
+ void * src, uint_t length, void * priv_data) {
- struct nvram_internal * data = (struct nvram_internal *)dev->private_data;
+ struct nvram_internal * data = priv_data;
memcpy(&(data->thereg), src, 1);
PrintDebug("Writing To NVRAM reg: 0x%x\n", data->thereg);
}
static int nvram_read_data_port(struct guest_info * core, ushort_t port,
- void * dst, uint_t length, struct vm_device * dev) {
+ void * dst, uint_t length, void * priv_data) {
- struct nvram_internal * data = (struct nvram_internal *)dev->private_data;
+ struct nvram_internal * data = priv_data;
addr_t irq_state = v3_lock_irqsave(data->nvram_lock);
static int nvram_write_data_port(struct guest_info * core, ushort_t port,
- void * src, uint_t length, struct vm_device * dev) {
+ void * src, uint_t length, void * priv_data) {
- struct nvram_internal * data = (struct nvram_internal *)dev->private_data;
+ struct nvram_internal * data = priv_data;
addr_t irq_state = v3_lock_irqsave(data->nvram_lock);
static int nvram_free(struct vm_device * dev) {
- v3_dev_unhook_io(dev, NVRAM_REG_PORT);
- v3_dev_unhook_io(dev, NVRAM_DATA_PORT);
-
return 0;
}
static struct v3_device_ops dev_ops = {
.free = nvram_free,
- .reset = nvram_reset_device,
- .start = nvram_start_device,
- .stop = nvram_stop_device,
};
PrintDebug("nvram: internal at %p\n", (void *)nvram_state);
nvram_state->ide = ide;
+ nvram_state->vm = vm;
struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, nvram_state);
return -1;
}
- init_nvram_state(vm, dev);
+ init_nvram_state(vm, nvram_state);
// hook ports
v3_dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port);
v3_dev_hook_io(dev, NVRAM_DATA_PORT, &nvram_read_data_port, &nvram_write_data_port);
- v3_hook_host_event(vm, HOST_TIMER_EVT, V3_HOST_EVENT_HANDLER(handle_timer_event), dev);
+ v3_hook_host_event(vm, HOST_TIMER_EVT, V3_HOST_EVENT_HANDLER(handle_timer_event), nvram_state);
return 0;
}
};
-static int handle_gen_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct debug_state * state = (struct debug_state *)dev->private_data;
+static int handle_gen_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct debug_state * state = priv_data;
state->debug_buf[state->debug_offset++] = *(char*)src;
}
static int handle_hcall(struct guest_info * info, uint_t hcall_id, void * priv_data) {
- struct vm_device * dev = (struct vm_device *)priv_data;
- struct debug_state * state = (struct debug_state *)dev->private_data;
+ struct debug_state * state = (struct debug_state *)priv_data;
int msg_len = info->vm_regs.rcx;
addr_t msg_gpa = info->vm_regs.rbx;
static int debug_free(struct vm_device * dev) {
- v3_dev_unhook_io(dev, DEBUG_PORT1);
-
return 0;
};
static struct v3_device_ops dev_ops = {
.free = debug_free,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
};
}
v3_dev_hook_io(dev, DEBUG_PORT1, NULL, &handle_gen_write);
- v3_register_hypercall(vm, OS_DEBUG_HCALL, handle_hcall, dev);
+ v3_register_hypercall(vm, OS_DEBUG_HCALL, handle_hcall, state);
state->debug_offset = 0;
memset(state->debug_buf, 0, BUF_SIZE);
-static int addr_port_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
- struct pci_internal * pci_state = (struct pci_internal *)dev->private_data;
+static int addr_port_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
+ struct pci_internal * pci_state = priv_data;
int reg_offset = port & 0x3;
uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset;
}
-static int addr_port_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
- struct pci_internal * pci_state = (struct pci_internal *)dev->private_data;
+static int addr_port_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct pci_internal * pci_state = priv_data;
int reg_offset = port & 0x3;
uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset;
}
-static int data_port_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * vmdev) {
- struct pci_internal * pci_state = (struct pci_internal *)(vmdev->private_data);
+static int data_port_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
+ struct pci_internal * pci_state = priv_data;
struct pci_device * pci_dev = NULL;
uint_t reg_num = (pci_state->addr_reg.reg_num << 2) + (port & 0x3);
int i;
}
-static int data_port_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * vmdev) {
- struct pci_internal * pci_state = (struct pci_internal *)vmdev->private_data;
+static int data_port_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct pci_internal * pci_state = priv_data;
struct pci_device * pci_dev = NULL;
uint_t reg_num = (pci_state->addr_reg.reg_num << 2) + (port & 0x3);
int i;
-static int pci_reset_device(struct vm_device * dev) {
- PrintDebug("pci: reset device\n");
- return 0;
-}
-
-
-static int pci_start_device(struct vm_device * dev) {
- PrintDebug("pci: start device\n");
- return 0;
-}
-
-
-static int pci_stop_device(struct vm_device * dev) {
- PrintDebug("pci: stop device\n");
- return 0;
-}
-
-
-
static int pci_free(struct vm_device * dev) {
- int i = 0;
-
- for (i = 0; i < 4; i++){
- v3_dev_unhook_io(dev, CONFIG_ADDR_PORT + i);
- v3_dev_unhook_io(dev, CONFIG_DATA_PORT + i);
- }
return 0;
}
static struct v3_device_ops dev_ops = {
.free = pci_free,
- .reset = pci_reset_device,
- .start = pci_start_device,
- .stop = pci_stop_device,
+
};
}
static int write_data_port(struct guest_info * core, uint16_t port,
- void * src, uint_t length, struct vm_device * dev) {
- struct serial_state * state = (struct serial_state *)dev->private_data;
+ void * src, uint_t length, void * priv_data) {
+ struct serial_state * state = priv_data;
uint8_t * val = (uint8_t *)src;
struct serial_port * com_port = NULL;
static int read_data_port(struct guest_info * core, uint16_t port,
- void * dst, uint_t length, struct vm_device * dev) {
- struct serial_state * state = (struct serial_state *)dev->private_data;
+ void * dst, uint_t length, void * priv_data) {
+ struct serial_state * state = priv_data;
uint8_t * val = (uint8_t *)dst;
struct serial_port * com_port = NULL;
static int write_ctrl_port(struct guest_info * core, uint16_t port, void * src,
- uint_t length, struct vm_device * dev) {
- struct serial_state * state = (struct serial_state *)dev->private_data;
+ uint_t length, void * priv_data) {
+ struct serial_state * state = priv_data;
uint8_t val = *(uint8_t *)src;
struct serial_port * com_port = NULL;
static int read_ctrl_port(struct guest_info * core, uint16_t port, void * dst,
- uint_t length, struct vm_device * dev) {
- struct serial_state * state = (struct serial_state *)dev->private_data;
+ uint_t length, void * priv_data) {
+ struct serial_state * state = priv_data;
uint8_t * val = (uint8_t *)dst;
struct serial_port * com_port = NULL;
static int write_status_port(struct guest_info * core, uint16_t port, void * src,
- uint_t length, struct vm_device * dev) {
- struct serial_state * state = (struct serial_state *)dev->private_data;
+ uint_t length, void * priv_data) {
+ struct serial_state * state = priv_data;
uint8_t val = *(uint8_t *)src;
struct serial_port * com_port = NULL;
}
static int read_status_port(struct guest_info * core, uint16_t port, void * dst,
- uint_t length, struct vm_device * dev) {
- struct serial_state * state = (struct serial_state *)dev->private_data;
+ uint_t length, void * priv_data) {
+ struct serial_state * state = priv_data;
uint8_t * val = (uint8_t *)dst;
struct serial_port * com_port = NULL;
}
static int serial_deinit(struct vm_device * dev) {
-
-
- v3_dev_unhook_io(dev, COM1_DATA_PORT);
- v3_dev_unhook_io(dev, COM1_IRQ_ENABLE_PORT);
- v3_dev_unhook_io(dev, COM1_FIFO_CTRL_PORT);
- v3_dev_unhook_io(dev, COM1_LINE_CTRL_PORT);
- v3_dev_unhook_io(dev, COM1_MODEM_CTRL_PORT);
- v3_dev_unhook_io(dev, COM1_LINE_STATUS_PORT);
- v3_dev_unhook_io(dev, COM1_MODEM_STATUS_PORT);
- v3_dev_unhook_io(dev, COM1_SCRATCH_PORT);
-
- v3_dev_unhook_io(dev, COM2_DATA_PORT);
- v3_dev_unhook_io(dev, COM2_IRQ_ENABLE_PORT);
- v3_dev_unhook_io(dev, COM2_FIFO_CTRL_PORT);
- v3_dev_unhook_io(dev, COM2_LINE_CTRL_PORT);
- v3_dev_unhook_io(dev, COM2_MODEM_CTRL_PORT);
- v3_dev_unhook_io(dev, COM2_LINE_STATUS_PORT);
- v3_dev_unhook_io(dev, COM2_MODEM_STATUS_PORT);
- v3_dev_unhook_io(dev, COM2_SCRATCH_PORT);
-
- v3_dev_unhook_io(dev, COM3_DATA_PORT);
- v3_dev_unhook_io(dev, COM3_IRQ_ENABLE_PORT);
- v3_dev_unhook_io(dev, COM3_FIFO_CTRL_PORT);
- v3_dev_unhook_io(dev, COM3_LINE_CTRL_PORT);
- v3_dev_unhook_io(dev, COM3_MODEM_CTRL_PORT);
- v3_dev_unhook_io(dev, COM3_LINE_STATUS_PORT);
- v3_dev_unhook_io(dev, COM3_MODEM_STATUS_PORT);
- v3_dev_unhook_io(dev, COM3_SCRATCH_PORT);
-
- v3_dev_unhook_io(dev, COM4_DATA_PORT);
- v3_dev_unhook_io(dev, COM4_IRQ_ENABLE_PORT);
- v3_dev_unhook_io(dev, COM4_FIFO_CTRL_PORT);
- v3_dev_unhook_io(dev, COM4_LINE_CTRL_PORT);
- v3_dev_unhook_io(dev, COM4_MODEM_CTRL_PORT);
- v3_dev_unhook_io(dev, COM4_LINE_STATUS_PORT);
- v3_dev_unhook_io(dev, COM4_MODEM_STATUS_PORT);
- v3_dev_unhook_io(dev, COM4_SCRATCH_PORT);
-
return 0;
}
//.init = serial_init,
.free = serial_deinit,
.reset = NULL,
- .start = NULL,
- .stop = NULL,
};
return 0;
}
-/*
-int v3_init_core_dev_mgr(struct v3_vm_info * vm) {
- struct v3_core_dev_mgr * mgr = &(vm->core_dev_mgr);
-
- INIT_LIST_HEAD(&(mgr->dev_list));
- mgr->dev_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn);
-
- return 0;
-}
-
-int v3_core_dev_mgr_deinit(struct v3_vm_info * vm) {
- struct vm_device * dev;
- struct v3_core_dev_mgr * mgr = &(vm->core_dev_mgr);
- struct vm_device * tmp;
-
- list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) {
- v3_detach_device(dev);
- }
-
- // TODO: Clear hash tables
-
-}
-*/
int v3_create_device(struct v3_vm_info * vm, const char * dev_name, v3_cfg_tree_t * cfg) {
/* The remaining functions are called by the devices themselves */
/****************************************************************/
+struct dev_io_hook {
+ uint16_t port;
+
+ struct list_head node;
+
+};
+
/* IO HOOKS */
int v3_dev_hook_io(struct vm_device * dev, uint16_t port,
- int (*read)(struct guest_info * core, uint16_t port, void * dst, uint_t length, struct vm_device * dev),
- int (*write)(struct guest_info * core, uint16_t port, void * src, uint_t length, struct vm_device * dev)) {
- return v3_hook_io_port(dev->vm, port,
- (int (*)(struct guest_info * core, ushort_t, void *, uint_t, void *))read,
- (int (*)(struct guest_info * core, ushort_t, void *, uint_t, void *))write,
- (void *)dev);
+ int (*read)(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * priv_data),
+ int (*write)(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data)) {
+ struct dev_io_hook * io_hook = NULL;
+ int ret = 0;
+
+ ret = v3_hook_io_port(dev->vm, port,
+ (int (*)(struct guest_info * core, ushort_t, void *, uint_t, void *))read,
+ (int (*)(struct guest_info * core, ushort_t, void *, uint_t, void *))write,
+ (void *)dev->private_data);
+
+ if (ret == -1) {
+ return -1;
+ }
+
+ io_hook = V3_Malloc(sizeof(struct dev_io_hook));
+
+ if (io_hook == NULL) {
+ PrintError("Could not allocate io hook dev state\n");
+ return -1;
+ }
+
+ io_hook->port = port;
+ list_add(&(io_hook->node), &(dev->io_hooks));
+
+ return 0;
}
int v3_dev_unhook_io(struct vm_device * dev, uint16_t port) {
- return v3_unhook_io_port(dev->vm, port);
+ struct dev_io_hook * io_hook = NULL;
+ struct dev_io_hook * tmp;
+
+ list_for_each_entry_safe(io_hook, tmp, &(dev->io_hooks), node) {
+ if (io_hook->port == port) {
+
+ list_del(&(io_hook->node));
+ V3_Free(io_hook);
+
+ return v3_unhook_io_port(dev->vm, port);
+ }
+ }
+
+ return -1;
}
dev = (struct vm_device*)V3_Malloc(sizeof(struct vm_device));
+ INIT_LIST_HEAD(&(dev->io_hooks));
+
strncpy(dev->name, name, 32);
dev->ops = ops;
dev->private_data = private_data;