Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


added atapi identify and command port handler
Jack Lange [Wed, 18 Mar 2009 23:44:56 +0000 (18:44 -0500)]
palacios/src/devices/ide-types.h
palacios/src/devices/ide.c
palacios/src/devices/ramdisk.c
palacios/src/palacios/vmm_config.c

index f881157..fab4fa0 100644 (file)
@@ -92,21 +92,77 @@ struct ide_features_reg {
     } __attribute__((packed));
 } __attribute__((packed));
 
+typedef enum {IDE_CTRL_NOT_SPECIFIED, 
+             IDE_CTRL_SINGLE_PORT, 
+             IDE_CTRL_DUAL_PORT, 
+             IDE_CTRL_DUAL_PORT_CACHE} ide_controller_type;
 
-typedef enum { 
-    READ_SECT_W_RETRY = 0x20,
-    READ_SECT = 0x21,
-    READ_LONG_W_RETRY = 0x22,
-    READ_LONG = 0x23,
-    READ_VRFY_SECT_W_RETRY = 0x40,
-    READ_VRFY_SECT = 0x41,
-    FORMAT_TRACK = 0x50,
-    EXEC_DRV_DIAG = 0x90,
-    INIT_DRIVE_PARAM = 0x91,
+struct ide_drive_id {
+    union {
+       uint16_t buf[256];
+       struct {
+           uint_t rsvd1           : 1;
+           uint_t hard_sectors    : 1;
+           uint_t no_soft_sectors : 1;
+           uint_t no_mfm_enc      : 1;
+           uint_t head_switch_time : 1;
+           uint_t spnd_mot_ctrl   : 1;
+           uint_t fixed_drive     : 1;
+           uint_t removable_media : 1;
+           uint_t disk_speed1     : 1;
+           uint_t disk_speed2     : 1;
+           uint_t disk_speed3     : 1;
+           uint_t rpm_tolerance   : 1;
+           uint_t data_strobe_offset : 1;
+           uint_t track_offset_option : 1;
+           uint_t fmt_speed_tol   : 1;
+           uint_t cdrom_flag      : 1;
+
+           uint16_t num_cylinders;
+           uint16_t rsvd2;
+           uint16_t num_heads;
+
+           uint16_t bytes_per_track;
+           uint16_t bytes_per_sector;
+           uint16_t sectors_per_track;
+
+           uint16_t sector_gap;
+           
+           uint8_t phase_lock_bytes;
+           uint8_t rsvd3;
+
+           uint16_t num_vendor_wds;
+           
+           uint8_t serial_num[20]; // right aligned, padded with 0x20
+           
+
+           uint16_t controller_type;
+
+           uint16_t buffer_size; // in 512 byte chunks
 
-} ide_cmd_t;
+           uint16_t num_ecc_bytes;
 
+           uint8_t firmware_rev[8]; // space padded
+           uint8_t model_num[40]; // space padded
+           
+           uint16_t rw_multiples;
 
+           uint16_t dword_io;
+
+           uint8_t rsvd4;
+           uint8_t lba_enable;
+           
+
+           uint16_t rsvd6;
+
+           uint16_t min_PIO_cycle;
+           uint16_t min_DMA_cycle;
+
+           uint16_t rsvd7[503];
+
+       } __attribute__((packed));
+    } __attribute__((packed));
+} __attribute__((packed));
 
 
 #endif // ! __V3VEE__
index 87e10c3..7534f1e 100644 (file)
@@ -21,7 +21,8 @@
 #include <devices/ide.h>
 #include "ide-types.h"
 
-
+#define PRI_DEFAULT_IRQ 14
+#define SEC_DEFAULT_IRQ 15
 
 #define PRI_DATA_PORT         0x1f0
 #define PRI_FEATURES_PORT     0x1f1
@@ -74,6 +75,12 @@ struct ide_drive {
 
 
     char model[41];
+
+    uint_t data_offset;
+
+    // data buffer...
+    uint8_t buffer[2048];
+
     void * private_data;
 
     uint8_t sector_count;               // 0x1f2,0x172
@@ -104,6 +111,8 @@ struct ide_channel {
     struct ide_status_reg status;       // [read] 0x1f7,0x177
     uint8_t command_reg;                // [write] 0x1f7,0x177
 
+    int irq; // this is temporary until we add PCI support
+
     // Control Registers
     struct ide_ctrl_reg ctrl_reg; // [write] 0x3f6,0x376
 };
@@ -144,6 +153,13 @@ static inline int is_lba_enabled(struct ide_channel * channel) {
 }
 
 
+static void ide_raise_irq(struct vm_device * dev, struct ide_channel * channel) {
+    if (channel->ctrl_reg.irq_disable == 0) {
+       v3_raise_irq(dev->vm, channel->irq);
+    }
+}
+
+
 static void drive_reset(struct ide_drive * drive) {
     drive->sector_count = 0x01;
     drive->sector_num = 0x01;
@@ -184,9 +200,74 @@ static void channel_reset_complete(struct ide_channel * channel) {
 }
 
 
+static void ide_abort_command(struct vm_device * dev, struct ide_channel * channel) {
+    channel->status.val = 0x41; // Error + ready
+    channel->error_reg.val = 0x04; // No idea...
+
+    ide_raise_irq(dev, channel);
+}
+
+
+
+
+// Include the ATAPI interface handlers
+#include "atapi.h"
+
+
+
 
 static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+    struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
+    struct ide_channel * channel = get_selected_channel(ide, port);
+    struct ide_drive * drive = get_selected_drive(channel);
+
+    if (length != 1) {
+       PrintError("Invalid Write Length on IDE command Port %x\n", port);
+       return -1;
+    }
+
+    channel->command_reg = *(uint8_t *)src;
+    
+
     PrintDebug("IDE: Writing Command Port %x (val=%x)\n", port, *(uint8_t *)src);
+
+    switch (channel->command_reg) {
+       
+       case 0xa0: // ATAPI Command Packet
+           if (drive->drive_type != IDE_CDROM) {
+               ide_abort_command(dev, channel);
+           }
+           
+           drive->sector_count = 1;
+
+           channel->status.busy = 0;
+           channel->status.write_fault = 0;
+           channel->status.data_req = 1;
+           channel->status.error = 0;
+           
+           drive->data_offset = 0;
+
+       case 0xa1: // ATAPI Identify Device Packet
+           atapi_identify_device(drive);
+
+           channel->error_reg.val = 0;
+           channel->status.val = 0x58; // ready, data_req, seek_complete
+           
+           ide_raise_irq(dev, channel);
+       case 0xec: // Identify Device
+           if (drive->drive_type != IDE_DISK) {
+               drive_reset(drive);
+
+               // JRL: Should we abort here?
+               ide_abort_command(dev, channel);
+           } else {
+               PrintError("IDE Disks currently not implemented\n");
+               return -1;
+           }
+           break;
+           
+    }
+
     return -1;
 }
 
@@ -362,6 +443,8 @@ static int read_port_std(ushort_t port, void * dst, uint_t length, struct vm_dev
            return -1;
     }
 
+    PrintDebug("\tVal=%x\n", *(uint8_t *)dst);
+
     return length;
 }
 
@@ -375,8 +458,11 @@ static void init_drive(struct ide_drive * drive) {
 
     drive->drive_type = IDE_NONE;
 
+    drive->data_offset = 0;
     memset(drive->model, 0, sizeof(drive->model));
+    memset(drive->buffer, 0, sizeof(drive->buffer));
 
+    drive->private_data = NULL;
     drive->cd_ops = NULL;
 }
 
@@ -389,6 +475,7 @@ static void init_channel(struct ide_channel * channel) {
     channel->command_reg = 0x00;
     channel->ctrl_reg.val = 0x08;
 
+
     for (i = 0; i < 2; i++) {
        init_drive(&(channel->drives[i]));
     }
@@ -400,6 +487,9 @@ static void init_ide_state(struct ide_internal * ide) {
 
     for (i = 0; i < 2; i++) {
        init_channel(&(ide->channels[i]));
+
+       // JRL: this is a terrible hack...
+       ide->channels[i].irq = PRI_DEFAULT_IRQ + i;
     }
 }
 
@@ -521,6 +611,11 @@ int v3_ide_register_cdrom(struct vm_device * ide_dev,
 
     strncpy(drive->model, dev_name, sizeof(drive->model) - 1);
 
+    while (strlen((char *)(drive->model)) < 40) {
+       strcat((char*)(drive->model), " ");
+    }
+
+
     drive->drive_type = IDE_CDROM;
 
     drive->cd_ops = ops;
index 7ad7f9b..d2a14ce 100644 (file)
@@ -2239,14 +2239,7 @@ void rd_identify_ATAPI_drive(struct vm_device * dev, struct channel_t * channel)
        drive->id_drive[i] = 0;
     }
 
-    // now convert the id_drive array (native 256 word format) to
-    // the controller buffer (512 bytes)
-    Bit16u temp16;
-    for (i = 0; i <= 255; i++) {
-       temp16 = drive->id_drive[i];
-       controller->buffer[i * 2] = temp16 & 0x00ff;
-       controller->buffer[i * 2 + 1] = temp16 >> 8;
-    }
+
 
     return;
 }
index 38d7210..88db635 100644 (file)
@@ -34,7 +34,7 @@
 #include <devices/nvram.h>
 #include <devices/generic.h>
 #include <devices/ide.h>
-//#include <devices/cdrom.h>
+#include <devices/ram_cd.h>
 #include <devices/bochs_debug.h>
 #include <devices/os_debug.h>
 #include <devices/apic.h>
@@ -278,7 +278,7 @@ static int setup_memory_map(struct guest_info * info, struct v3_vm_config * conf
 
 static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr) {
     struct vm_device * ide = NULL;
-    //    struct vm_device * cdrom = NULL;
+    struct vm_device * ram_cd = NULL;
 #ifdef DEBUG_PCI
     struct vm_device * pci = v3_create_pci();
 #endif
@@ -303,7 +303,9 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_
 
     if (use_ramdisk) {
        PrintDebug("Creating Ramdisk\n");
-       //      cdrom = v3_create_cdrom(ramdisk, config_ptr->ramdisk, config_ptr->ramdisk_size);
+       ram_cd = v3_create_ram_cd(ide, 0, 0, 
+                                 (addr_t)(config_ptr->ramdisk), 
+                                 config_ptr->ramdisk_size);
     }
     
     
@@ -332,8 +334,7 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_
     v3_attach_device(info, ide);
 
     if (use_ramdisk) {
-
-       //      v3_attach_device(info, cdrom);
+       v3_attach_device(info, ram_cd);
     }
 
     if (use_generic) {