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 more ATAPI functions, should now boot Linux
Jack Lange [Sun, 29 Mar 2009 21:26:12 +0000 (16:26 -0500)]
palacios/src/devices/atapi-types.h
palacios/src/devices/atapi.h

index 849a151..7635998 100644 (file)
@@ -131,6 +131,27 @@ struct atapi_rd_capacity_resp {
     uint32_t block_len;
 } __attribute__((packed));
 
+struct atapi_config_cmd {
+    uint8_t atapi_cmd;  // 0x46
+    uint8_t rt               : 2;
+    uint8_t rsvd1            : 3;
+    uint8_t lun              : 3;
+    uint16_t start_feature_num;
+    uint8_t rsvd2[3];
+    uint16_t alloc_len;
+    uint8_t link             : 1;
+    uint8_t flag             : 1;
+    uint8_t naca             : 1;
+    uint8_t rsvd3            : 3;
+    uint8_t vendor_specific  : 2;
+} __attribute__((packed));
+
+struct atapi_config_resp {
+    uint32_t data_len;
+    uint16_t rsvd;
+    uint16_t cur_profile;
+} __attribute__((packed));
+
 
 struct atapi_rd_toc_cmd {
     uint8_t atapi_cmd;  // 0x43
index 30d829f..f60d956 100644 (file)
@@ -233,19 +233,57 @@ static int atapi_get_capacity(struct vm_device * dev, struct ide_channel * chann
     return 0;
 }
 
+static int atapi_get_config(struct vm_device * dev, 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);
+    struct atapi_config_resp * resp = (struct atapi_config_resp *)(drive->data_buf);
+    int xfer_len = 8;
+
+    memset(resp, 0, sizeof(struct atapi_config_resp));
+
+    resp->data_len = le_to_be_32(xfer_len - 4);
+
+    if (alloc_len < xfer_len) {
+       xfer_len = alloc_len;
+    }
+    
+    atapi_setup_cmd_resp(dev, channel, xfer_len);
+    
+    return 0;
+}
+
 
 static int atapi_read_toc(struct vm_device * dev, 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);
-    
-
     struct atapi_rd_toc_resp * resp = (struct atapi_rd_toc_resp *)(drive->data_buf);
 
-    resp->data_len = 10;
+    int xfer_len = 12;
+
+    memset(resp, 0, sizeof(struct atapi_rd_toc_resp));
+    
+    resp->data_len = le_to_be_16(10);
+    resp->first_track_num = 1;
+    resp->last_track_num = 1;
+
+    // we don't handle multi session
+    // we'll just treat it the same as single session
+    if ((cmd->format == 0) || (cmd->format == 1)) {
+       memset(&(resp->track_descs[0]), 0, 8);
+       
+       if (alloc_len < xfer_len) {
+           xfer_len = alloc_len;
+       }
 
-    return -1;
+       atapi_setup_cmd_resp(dev, channel, xfer_len);
+    } else {
+       PrintError("Unhandled Format (%d)\n", cmd->format);
+       return -1;
+    }
 
+    return 0;
 }
 
 
@@ -401,6 +439,22 @@ static int atapi_handle_packet(struct vm_device * dev, struct ide_channel * chan
           }
           break;
 
+       case 0x46: // get configuration
+          if (atapi_get_config(dev, channel) == -1) {
+              PrintError("IDE: Error getting CDROM Configuration (%x)\n", cmd);
+              return -1;
+          }
+          break;
+
+       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);
+          break;
+
+
+
        case 0xa8: // read(12)
 
 
@@ -415,7 +469,7 @@ static int atapi_handle_packet(struct vm_device * dev, struct ide_channel * chan
        case 0x2b: // seek
        case 0x1e: // lock door
        case 0x42: // read sub-channel
-       case 0x51: // read disk info
+
 
           
        case 0x55: // mode select
@@ -429,7 +483,7 @@ static int atapi_handle_packet(struct vm_device * dev, struct ide_channel * chan
        case 0xba: // scan
        case 0xbb: // set cd speed
        case 0x4e: // stop play/scan
-       case 0x46: // ???
        case 0x4a: // ???
        default:
           PrintError("Unhandled ATAPI command %x\n", cmd);