X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fide.c;h=4c0667719bfb9b407a603a48fde2f3cb0577287a;hb=96a71766125d211be08d7670c93938cf0ea09c04;hp=dae06af7e1ff07bb2e3a89ca6f927c7a9e34a030;hpb=a0d3be5212e7a5053ba213ce7bd26c7124cf01e3;p=palacios.git diff --git a/palacios/src/devices/ide.c b/palacios/src/devices/ide.c index dae06af..4c06677 100644 --- a/palacios/src/devices/ide.c +++ b/palacios/src/devices/ide.c @@ -357,7 +357,7 @@ static int dma_write(struct guest_info * core, struct ide_internal * ide, struct #ifdef CONFIG_DEBUG_IDE -static void print_prd_table(struct vm_device * dev, struct ide_channel * channel) { +static void print_prd_table(struct ide_internal * ide, struct ide_channel * channel) { struct ide_dma_prd prd_entry; int index = 0; @@ -367,7 +367,7 @@ static void print_prd_table(struct vm_device * dev, struct ide_channel * channel uint32_t prd_entry_addr = channel->dma_prd_addr + (sizeof(struct ide_dma_prd) * index); int ret; - ret = v3_read_gpa_memory(&(dev->vm->cores[0]), prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry); + ret = v3_read_gpa_memory(&(ide->vm->cores[0]), prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry); if (ret != sizeof(struct ide_dma_prd)) { PrintError("Could not read PRD\n"); @@ -956,6 +956,26 @@ static int write_cmd_port(struct guest_info * core, ushort_t port, void * src, u break; } + + case 0x08: // Reset Device + drive_reset(drive); + channel->error_reg.val = 0x01; + channel->status.busy = 0; + channel->status.ready = 1; + channel->status.seek_complete = 1; + channel->status.write_fault = 0; + channel->status.error = 0; + break; + + case 0xe5: // Check power mode + drive->sector_count = 0xff; /* 0x00=standby, 0x80=idle, 0xff=active or idle */ + channel->status.busy = 0; + channel->status.ready = 1; + channel->status.write_fault = 0; + channel->status.data_req = 0; + channel->status.error = 0; + break; + case 0xc4: // read multiple sectors drive->hd_state.cur_sector_num = drive->hd_state.mult_sector_num; default: @@ -1400,8 +1420,8 @@ static void init_channel(struct ide_channel * channel) { static int pci_config_update(uint_t reg_num, void * src, uint_t length, void * private_data) { PrintDebug("PCI Config Update\n"); - /* 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); PrintDebug("\t\tInterupt register (Dev=%s), irq=%d\n", ide->ide_pci->name, ide->ide_pci->config_header.intr_line); */ @@ -1430,20 +1450,18 @@ static int init_ide_state(struct ide_internal * ide) { -static int ide_free(struct vm_device * dev) { - // unhook io ports.... - +static int ide_free(struct ide_internal * ide) { // deregister from PCI? - + V3_Free(ide); return 0; } static struct v3_device_ops dev_ops = { - .free = ide_free, + .free = (int (*)(void *))ide_free, }; @@ -1524,6 +1542,7 @@ static int connect_fn(struct v3_vm_info * vm, static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct ide_internal * ide = NULL; char * dev_id = v3_cfg_val(cfg, "ID"); + int ret = 0; PrintDebug("IDE: Initializing IDE\n"); @@ -1537,7 +1556,6 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { memset(ide, 0, sizeof(struct ide_internal)); ide->vm = vm; - ide->pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus")); if (ide->pci_bus != NULL) { @@ -1554,72 +1572,76 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { PrintDebug("IDE: Creating IDE bus x 2\n"); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, ide); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, ide); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); - v3_free_device(dev); V3_Free(ide); return -1; } if (init_ide_state(ide) == -1) { PrintError("Failed to initialize IDE state\n"); - v3_detach_device(dev); + v3_remove_device(dev); return -1; } PrintDebug("Connecting to IDE IO ports\n"); - v3_dev_hook_io(dev, PRI_DATA_PORT, - &ide_read_data_port, &write_data_port); - v3_dev_hook_io(dev, PRI_FEATURES_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_SECT_NUM_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_CYL_LOW_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_CYL_HIGH_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_CMD_PORT, - &read_port_std, &write_cmd_port); - - v3_dev_hook_io(dev, SEC_DATA_PORT, - &ide_read_data_port, &write_data_port); - v3_dev_hook_io(dev, SEC_FEATURES_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_SECT_NUM_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_CYL_LOW_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_CYL_HIGH_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_CMD_PORT, - &read_port_std, &write_cmd_port); + ret |= v3_dev_hook_io(dev, PRI_DATA_PORT, + &ide_read_data_port, &write_data_port); + ret |= v3_dev_hook_io(dev, PRI_FEATURES_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_SECT_NUM_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_CYL_LOW_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_CYL_HIGH_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_CMD_PORT, + &read_port_std, &write_cmd_port); + + ret |= v3_dev_hook_io(dev, SEC_DATA_PORT, + &ide_read_data_port, &write_data_port); + ret |= v3_dev_hook_io(dev, SEC_FEATURES_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_SECT_NUM_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_CYL_LOW_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_CYL_HIGH_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_CMD_PORT, + &read_port_std, &write_cmd_port); - v3_dev_hook_io(dev, PRI_CTRL_PORT, - &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_CTRL_PORT, + &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_CTRL_PORT, - &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_CTRL_PORT, + &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, - &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, + &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, - &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, + &read_port_std, &write_port_std); + if (ret != 0) { + PrintError("Error hooking IDE IO port\n"); + v3_remove_device(dev); + return -1; + } if (ide->pci_bus) { @@ -1642,14 +1664,15 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { bars[4].io_read = read_dma_port; bars[4].io_write = write_dma_port; - bars[4].private_data = dev; + bars[4].private_data = ide; pci_dev = v3_pci_register_device(ide->pci_bus, PCI_STD_DEVICE, 0, sb_pci->dev_num, 1, "PIIX3_IDE", bars, - pci_config_update, NULL, NULL, dev); + pci_config_update, NULL, NULL, ide); if (pci_dev == NULL) { PrintError("Failed to register IDE BUS %d with PCI\n", i); + v3_remove_device(dev); return -1; } @@ -1677,7 +1700,7 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (v3_dev_add_blk_frontend(vm, dev_id, connect_fn, (void *)ide) == -1) { PrintError("Could not register %s as frontend\n", dev_id); - v3_detach_device(dev); + v3_remove_device(dev); return -1; } @@ -1693,10 +1716,10 @@ device_register("IDE", ide_init) -int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_num, +int v3_ide_get_geometry(void * ide_data, int channel_num, int drive_num, uint32_t * cylinders, uint32_t * heads, uint32_t * sectors) { - struct ide_internal * ide = (struct ide_internal *)(ide_dev->private_data); + struct ide_internal * ide = ide_data; struct ide_channel * channel = &(ide->channels[channel_num]); struct ide_drive * drive = &(channel->drives[drive_num]);