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.


Merge branch 'devel' of palacios@newskysaw.cs.northwestern.edu:/home/palacios/palacio...
Peter Dinda [Thu, 8 Sep 2011 21:14:55 +0000 (16:14 -0500)]
palacios/include/devices/lnx_virtio_pci.h
palacios/src/devices/atapi-types.h
palacios/src/devices/atapi.h
palacios/src/devices/lnx_virtio_blk.c

index e48df2c..f0c5e3d 100644 (file)
  * 
  */
 struct virtio_config {
-    uint32_t host_features;
-    uint32_t guest_features;
-    uint32_t vring_page_num;
-    uint16_t vring_ring_size;
-    uint16_t vring_queue_selector;
-    uint16_t vring_queue_notifier;
-    uint8_t status;
-    uint8_t pci_isr;
+    union {
+       uint8_t buf[20];
+       struct {
+           uint32_t host_features;
+           uint32_t guest_features;
+           uint32_t vring_page_num;
+           uint16_t vring_ring_size;
+           uint16_t vring_queue_selector;
+           uint16_t vring_queue_notifier;
+           uint8_t status;
+           uint8_t pci_isr;
+       } __attribute__((packed));
+    } __attribute__((packed));
 } __attribute__((packed));
 
 
index 300e618..3fd752d 100644 (file)
@@ -188,6 +188,34 @@ struct atapi_rd_toc_resp {
 } __attribute__((packed));
 
 
+struct atapi_mech_status_cmd {
+    uint8_t atapi_cmd;   // 0xbd
+    uint8_t rsvd1        : 5;
+    uint8_t lun          : 3;
+    uint8_t rsvd2[6];
+    uint16_t alloc_len;
+    uint8_t rsvd3;
+    uint8_t link             : 1;
+    uint8_t flag             : 1;
+    uint8_t naca             : 1;
+    uint8_t rsvd5            : 3;
+    uint8_t vendor_specific  : 2;
+} __attribute__((packed));
+
+struct atapi_mech_status_resp {
+    uint8_t cur_slot          : 5;
+    uint8_t changer_state     : 2;
+    uint8_t fault             : 1;
+    uint8_t rsvd1             : 4;
+    uint8_t door_open         : 1;
+    uint8_t cd_dvd_mech_state : 3;
+    uint32_t lba;
+    uint8_t num_slots         : 6;
+    uint8_t rsvd2             : 2;
+    uint16_t slot_table_len;
+} __attribute__((packed));
+
+
 struct atapi_inquiry_cmd {
     uint8_t atapi_cmd;  // 0x12
     uint8_t evpd           : 1; 
index f32ed8d..0892f8c 100644 (file)
@@ -460,6 +460,7 @@ static int atapi_mode_sense(struct ide_internal * ide, struct ide_channel * chan
 }
 
 
+
 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);
@@ -492,6 +493,28 @@ static int atapi_inquiry(struct ide_internal * ide, struct ide_channel * channel
 }
 
 
+static int atapi_mech_status(struct ide_internal * ide, struct ide_channel * channel) {
+    struct ide_drive * drive = get_selected_drive(channel);
+    struct atapi_mech_status_cmd * status_cmd = (struct atapi_mech_status_cmd *)(drive->data_buf);
+    uint16_t alloc_len = be_to_le_16(status_cmd->alloc_len);
+    struct atapi_mech_status_resp * resp = (struct atapi_mech_status_resp *)(drive->data_buf);
+    int xfer_len = sizeof(struct atapi_mech_status_resp);
+
+    memset(resp, 0, sizeof(struct atapi_mech_status_resp));
+
+    resp->lba = le_to_be_32(1);
+    resp->slot_table_len = le_to_be_16(0);
+    
+    if (alloc_len < xfer_len) {
+       xfer_len = alloc_len;
+    }
+
+    atapi_setup_cmd_resp(ide, channel, xfer_len);
+
+    return 0;
+}
+
+
 static int atapi_cmd_is_data_op(uint8_t cmd) {
     switch (cmd) {
        case 0x28: // read (10)
@@ -583,11 +606,18 @@ static int atapi_handle_packet(struct guest_info * core, struct ide_internal * i
           }
           break;
 
+       case 0xbd: // mechanism status 
+          if (atapi_mech_status(ide, channel) == -1) {
+              PrintError("IDE: error in ATAPI Mechanism status query (%x)\n", cmd);
+              return -1;
+          }
+          break;
+
+
        case 0xa8: // read(12)
 
 
        case 0x1b: // start/stop drive
-       case 0xbd: // mechanism status 
 
        case 0xbe: // read cd
 
index d47243a..fd9ec61 100644 (file)
@@ -407,38 +407,44 @@ static int virtio_io_read(struct guest_info * core, uint16_t port, void * dst, u
     PrintDebug("VIRTIO BLOCK Read  for port %d (index =%d), length=%d\n", 
               port, port_idx, length);
 
+
     switch (port_idx) {
        case HOST_FEATURES_PORT:
-           if (length != 4) {
-               PrintError("Illegal read length for host features\n");
+       case HOST_FEATURES_PORT + 1:
+       case HOST_FEATURES_PORT + 2:
+       case HOST_FEATURES_PORT + 3:
+           if (port_idx + length > HOST_FEATURES_PORT + 4) {
+               PrintError("Illegal read length for host features (len=%d)\n", length);
                return -1;
            }
 
-           *(uint32_t *)dst = blk_state->virtio_cfg.host_features;
-       
+           memcpy(dst, &(blk_state->virtio_cfg.host_features), length);
            break;
        case VRING_PG_NUM_PORT:
-           if (length != 4) {
-               PrintError("Illegal read length for page frame number\n");
+       case VRING_PG_NUM_PORT + 1:
+       case VRING_PG_NUM_PORT + 2:
+       case VRING_PG_NUM_PORT + 3:
+           if (port_idx + length > VRING_PG_NUM_PORT + 4) {
+               PrintError("Illegal read length for vring pg num (len=%d)\n", length);
                return -1;
            }
 
-           *(uint32_t *)dst = blk_state->queue.pfn;
-
+           memcpy(dst, &(blk_state->queue.pfn), length);
            break;
        case VRING_SIZE_PORT:
-           if (length != 2) {
-               PrintError("Illegal read length for vring size\n");
+       case VRING_SIZE_PORT + 1:
+           if (length > 2) {
+               PrintError("Illegal read length for vring size (len=%d)\n", length);
                return -1;
            }
-               
-           *(uint16_t *)dst = blk_state->queue.queue_size;
+           
+           memcpy(dst, &(blk_state->queue.queue_size), length);
 
            break;
 
        case VIRTIO_STATUS_PORT:
            if (length != 1) {
-               PrintError("Illegal read length for status\n");
+               PrintError("Illegal read length for status (len=%d)\n", length);
                return -1;
            }