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.


360505034ed01c1bb343ad0f3f72f878305e7ad5
[palacios.git] / palacios / src / devices / ide.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm.h>
21 #include <palacios/vm_guest_mem.h>
22 #include <devices/ide.h>
23 #include <devices/pci.h>
24 #include "ide-types.h"
25 #include "atapi-types.h"
26
27 #define PRI_DEFAULT_IRQ 14
28 #define SEC_DEFAULT_IRQ 15
29
30
31 #define PRI_DATA_PORT         0x1f0
32 #define PRI_FEATURES_PORT     0x1f1
33 #define PRI_SECT_CNT_PORT     0x1f2
34 #define PRI_SECT_NUM_PORT     0x1f3
35 #define PRI_CYL_LOW_PORT      0x1f4
36 #define PRI_CYL_HIGH_PORT     0x1f5
37 #define PRI_DRV_SEL_PORT      0x1f6
38 #define PRI_CMD_PORT          0x1f7
39 #define PRI_CTRL_PORT         0x3f6
40 #define PRI_ADDR_REG_PORT     0x3f7
41
42 #define SEC_DATA_PORT         0x170
43 #define SEC_FEATURES_PORT     0x171
44 #define SEC_SECT_CNT_PORT     0x172
45 #define SEC_SECT_NUM_PORT     0x173
46 #define SEC_CYL_LOW_PORT      0x174
47 #define SEC_CYL_HIGH_PORT     0x175
48 #define SEC_DRV_SEL_PORT      0x176
49 #define SEC_CMD_PORT          0x177
50 #define SEC_CTRL_PORT         0x376
51 #define SEC_ADDR_REG_PORT     0x377
52
53
54 #define PRI_DEFAULT_DMA_PORT 0xc000
55 #define SEC_DEFAULT_DMA_PORT 0xc008
56
57
58 #define DATA_BUFFER_SIZE 2048
59
60 static const char * ide_pri_port_strs[] = {"PRI_DATA", "PRI_FEATURES", "PRI_SECT_CNT", "PRI_SECT_NUM", 
61                                           "PRI_CYL_LOW", "PRI_CYL_HIGH", "PRI_DRV_SEL", "PRI_CMD",
62                                            "PRI_CTRL", "PRI_ADDR_REG"};
63
64
65 static const char * ide_sec_port_strs[] = {"SEC_DATA", "SEC_FEATURES", "SEC_SECT_CNT", "SEC_SECT_NUM", 
66                                           "SEC_CYL_LOW", "SEC_CYL_HIGH", "SEC_DRV_SEL", "SEC_CMD",
67                                            "SEC_CTRL", "SEC_ADDR_REG"};
68
69 static const char * ide_dma_port_strs[] = {"DMA_CMD", NULL, "DMA_STATUS", NULL,
70                                            "DMA_PRD0", "DMA_PRD1", "DMA_PRD2", "DMA_PRD3"};
71
72
73
74 static inline const char * io_port_to_str(uint16_t port) {
75     if ((port >= PRI_DATA_PORT) && (port <= PRI_CMD_PORT)) {
76         return ide_pri_port_strs[port - PRI_DATA_PORT];
77     } else if ((port >= SEC_DATA_PORT) && (port <= SEC_CMD_PORT)) {
78         return ide_sec_port_strs[port - SEC_DATA_PORT];
79     } else if ((port == PRI_CTRL_PORT) || (port == PRI_ADDR_REG_PORT)) {
80         return ide_pri_port_strs[port - PRI_CTRL_PORT + 8];
81     } else if ((port == SEC_CTRL_PORT) || (port == SEC_ADDR_REG_PORT)) {
82         return ide_sec_port_strs[port - SEC_CTRL_PORT + 8];
83     } 
84     return NULL;
85 }
86
87
88 static inline const char * dma_port_to_str(uint16_t port) {
89     return ide_dma_port_strs[port & 0x7];
90 }
91
92
93 static const char * ide_dev_type_strs[] = {"HARDDISK", "CDROM", "NONE"};
94
95
96 static inline const char * device_type_to_str(v3_ide_dev_type_t type) {
97     if (type > 2) {
98         return NULL;
99     }
100
101     return ide_dev_type_strs[type];
102 }
103
104
105
106 struct ide_cd_state {
107     struct atapi_sense_data sense;
108     uint_t current_lba;
109     uint8_t atapi_cmd;
110     struct atapi_error_recovery err_recovery;
111 };
112
113 struct ide_hd_state {
114
115 };
116
117 struct ide_drive {
118     // Command Registers
119
120     v3_ide_dev_type_t drive_type;
121
122     union {
123         struct v3_ide_cd_ops * cd_ops;
124         struct v3_ide_hd_ops * hd_ops;
125     };
126
127
128     union {
129         struct ide_cd_state cd_state;
130         struct ide_hd_state hd_state;
131     };
132
133     char model[41];
134
135     // Where we are in the data transfer
136     uint_t transfer_index;
137
138     // the length of a transfer
139     // calculated for easy access
140     uint_t transfer_length;
141
142
143     // We have a local data buffer that we use for IO port accesses
144     uint8_t data_buf[DATA_BUFFER_SIZE];
145
146
147     void * private_data;
148     
149     union {
150         uint8_t sector_count;             // 0x1f2,0x172
151         struct atapi_irq_flags irq_flags;
152     } __attribute__((packed));
153
154     union {
155         uint8_t sector_num;               // 0x1f3,0x173
156         uint8_t lba0;
157     };
158
159     union {
160         uint16_t cylinder;
161         uint16_t lba12;
162
163
164         struct {
165             uint8_t cylinder_low;       // 0x1f4,0x174
166             uint8_t cylinder_high;      // 0x1f5,0x175
167         } __attribute__((packed));
168
169         struct {
170             uint8_t lba1;
171             uint8_t lba2;
172         } __attribute__((packed));
173
174
175         // The transfer length requested by the CPU 
176         uint16_t req_len;
177     } __attribute__((packed));
178
179 };
180
181
182
183 struct ide_channel {
184     struct ide_drive drives[2];
185
186     // Command Registers
187     struct ide_error_reg error_reg;     // [read] 0x1f1,0x171
188
189     struct ide_features_reg features;
190
191     struct ide_drive_head_reg drive_head; // 0x1f6,0x176
192
193     struct ide_status_reg status;       // [read] 0x1f7,0x177
194     uint8_t cmd_reg;                // [write] 0x1f7,0x177
195
196     int irq; // this is temporary until we add PCI support
197
198     struct pci_device * pci_dev;
199
200     // Control Registers
201     struct ide_ctrl_reg ctrl_reg; // [write] 0x3f6,0x376
202
203     struct ide_dma_cmd_reg dma_cmd;
204     struct ide_dma_status_reg dma_status;
205     uint32_t dma_prd_addr;
206     uint_t dma_tbl_index;
207 };
208
209
210
211 struct ide_internal {
212     struct ide_channel channels[2];
213     struct vm_device * pci;
214     struct pci_device * busmaster_pci;
215 };
216
217
218
219
220
221 /* Utility functions */
222
223 static inline uint16_t be_to_le_16(const uint16_t val) {
224     uint8_t * buf = (uint8_t *)&val;
225     return (buf[0] << 8) | (buf[1]) ;
226 }
227
228 static inline uint16_t le_to_be_16(const uint16_t val) {
229     return be_to_le_16(val);
230 }
231
232
233 static inline uint32_t be_to_le_32(const uint32_t val) {
234     uint8_t * buf = (uint8_t *)&val;
235     return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
236 }
237
238 static inline uint32_t le_to_be_32(const uint32_t val) {
239     return be_to_le_32(val);
240 }
241
242
243 static inline int get_channel_index(ushort_t port) {
244     if (((port & 0xfff8) == 0x1f0) ||
245         ((port & 0xfffe) == 0x3f6) || 
246         ((port & 0xfff8) == 0xc000)) {
247         return 0;
248     } else if (((port & 0xfff8) == 0x170) ||
249                ((port & 0xfffe) == 0x376) ||
250                ((port & 0xfff8) == 0xc008)) {
251         return 1;
252     }
253
254     return -1;
255 }
256
257 static inline struct ide_channel * get_selected_channel(struct ide_internal * ide, ushort_t port) {
258     int channel_idx = get_channel_index(port);    
259     return &(ide->channels[channel_idx]);
260 }
261
262 static inline struct ide_drive * get_selected_drive(struct ide_channel * channel) {
263     return &(channel->drives[channel->drive_head.drive_sel]);
264 }
265
266
267 static inline int is_lba_enabled(struct ide_channel * channel) {
268     return channel->drive_head.lba_mode;
269 }
270
271
272 /* Drive Commands */
273 static void ide_raise_irq(struct vm_device * dev, struct ide_channel * channel) {
274     if (channel->ctrl_reg.irq_disable == 0) {
275         PrintDebug("Raising IDE Interrupt %d\n", channel->irq);
276         channel->dma_status.int_gen = 1;
277         v3_raise_irq(dev->vm, channel->irq);
278     }
279 }
280
281
282 static void drive_reset(struct ide_drive * drive) {
283     drive->sector_count = 0x01;
284     drive->sector_num = 0x01;
285     
286     if (drive->drive_type == IDE_CDROM) {
287         drive->cylinder = 0xeb14;
288     } else {
289         drive->cylinder = 0x0000;
290     }
291
292
293     memset(drive->data_buf, 0, sizeof(drive->data_buf));
294     drive->transfer_index = 0;
295
296     // Send the reset signal to the connected device callbacks
297     //     channel->drives[0].reset();
298     //    channel->drives[1].reset();
299 }
300
301 static void channel_reset(struct ide_channel * channel) {
302     
303     // set busy and seek complete flags
304     channel->status.val = 0x90;
305
306     // Clear errors
307     channel->error_reg.val = 0x01;
308
309     // clear commands
310     channel->cmd_reg = 0x00;
311
312     channel->ctrl_reg.irq_disable = 0;
313 }
314
315 static void channel_reset_complete(struct ide_channel * channel) {
316     channel->status.busy = 0;
317     channel->status.ready = 1;
318
319     channel->drive_head.head_num = 0;    
320     
321     drive_reset(&(channel->drives[0]));
322     drive_reset(&(channel->drives[1]));
323 }
324
325
326 static void ide_abort_command(struct vm_device * dev, struct ide_channel * channel) {
327     channel->status.val = 0x41; // Error + ready
328     channel->error_reg.val = 0x04; // No idea...
329
330     ide_raise_irq(dev, channel);
331 }
332
333
334
335 static void ide_identify_device(struct ide_drive * drive) {
336     struct ide_drive_id * drive_id = (struct ide_drive_id *)(drive->data_buf);
337     const char* serial_number = " VT00001\0\0\0\0\0\0\0\0\0\0\0\0";
338     const char* firmware = "ALPHA1  ";
339
340     drive->transfer_length = 512;
341     drive->transfer_index = 0;
342
343
344     memset(drive_id->buf, 0, sizeof(drive_id->buf));
345
346     drive_id->fixed_drive = 1;
347     drive_id->removable_media = 0;
348
349     // Black magic...
350     drive_id->disk_speed1 = 1;
351     drive_id->disk_speed3 = 1;
352
353     drive_id->cdrom_flag = 0;
354
355     // Make it the simplest drive possible (1 head, 1 cyl, 1 sect/track)
356     drive_id->num_cylinders = 1;
357     drive_id->num_heads = 1;
358     drive_id->bytes_per_track = IDE_SECTOR_SIZE;
359     drive_id->bytes_per_sector = IDE_SECTOR_SIZE;
360     drive_id->sectors_per_track = 1;
361
362
363     // These buffers do not contain a terminating "\0"
364     memcpy(drive_id->serial_num, serial_number, strlen(serial_number));
365     memcpy(drive_id->firmware_rev, firmware, strlen(firmware));
366     memcpy(drive_id->model_num, drive->model, 40);
367
368     // 32 bits access
369     drive_id->dword_io = 1;
370
371     // enable DMA access
372     drive_id->dma_enable = 1;
373
374     // enable LBA access
375     drive_id->lba_enable = 1;
376     
377     // Drive Capacity
378     drive_id->lba_capacity = drive->hd_ops->get_capacity(drive->private_data);
379
380     drive_id->rw_multiples = 0x80ff;
381
382     // words 64-70, 54-58 valid
383     drive_id->field_valid = 0x0007; // DMA + pkg cmd valid
384
385     // copied from CFA540A
386     drive_id->buf[63] = 0x0103; // variable (DMA stuff)
387     //drive_id->buf[63] = 0x0000; // variable (DMA stuff)
388     
389     //    drive_id->buf[64] = 0x0001; // PIO
390     drive_id->buf[65] = 0x00b4;
391     drive_id->buf[66] = 0x00b4;
392     drive_id->buf[67] = 0x012c;
393     drive_id->buf[68] = 0x00b4;
394
395     drive_id->buf[71] = 30; // faked
396     drive_id->buf[72] = 30; // faked
397
398     //    drive_id->buf[80] = 0x1e; // supports up to ATA/ATAPI-4
399     drive_id->major_rev_num = 0x0040; // supports up to ATA/ATAPI-6
400
401     drive_id->dma_ultra = 0x2020; // Ultra_DMA_Mode_5_Selected | Ultra_DMA_Mode_5_Supported;
402 }
403
404
405
406
407
408
409
410
411 /* ATAPI functions */
412 #include "atapi.h"
413
414
415
416 /* IO Operations */
417 static int dma_read(struct vm_device * dev, struct ide_channel * channel) {
418     struct ide_drive * drive = get_selected_drive(channel);
419     struct ide_dma_prd prd_entry;
420     uint32_t prd_entry_addr = channel->dma_prd_addr + (sizeof(struct ide_dma_prd) * channel->dma_tbl_index);
421     int ret;
422
423
424     PrintDebug("PRD table address = %x\n", channel->dma_prd_addr);
425
426     ret = read_guest_pa_memory(dev->vm, prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry);
427
428     if (ret != sizeof(struct ide_dma_prd)) {
429         PrintError("Could not read PRD\n");
430         return -1;
431     }
432
433     PrintDebug("PRD Addr: %x, PDR Len: %d, EOT: %d\n", prd_entry.base_addr, prd_entry.size, prd_entry.end_of_table);
434
435     ret = write_guest_pa_memory(dev->vm, prd_entry.base_addr, prd_entry.size, drive->data_buf); 
436
437     if (ret != prd_entry.size) {
438         PrintError("Failed to copy data into guest memory... (ret=%d)\n", ret);
439         return -1;
440     }
441
442     channel->status.busy = 0;
443     channel->status.ready = 1;
444     channel->status.data_req = 0;
445     channel->status.error = 0;
446     channel->status.seek_complete = 1;
447
448     /*
449       drive->irq_flags.io_dir = 1;
450       drive->irq_flags.c_d = 1;
451       drive->irq_flags.rel = 0;
452     */
453
454
455     // set DMA status
456     channel->dma_status.active = 0;
457     channel->dma_status.err = 1;
458     channel->dma_status.int_gen = 1;
459
460     ide_raise_irq(dev, channel);
461
462     return 0;
463 }
464
465
466 static int dma_write(struct vm_device * dev, struct ide_channel * channel) {
467     // unsupported
468     PrintError("DMA writes currently not supported\n");
469     return -1;
470 }
471
472
473 /* 
474  * This is an ugly ugly ugly way to differentiate between the first and second DMA channels 
475  */
476
477 static int write_dma_port(ushort_t port_offset, void * src, uint_t length, struct vm_device * dev, struct ide_channel * channel);
478 static int read_dma_port(ushort_t port_offset, void * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel);
479
480
481 static int write_pri_dma_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
482     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
483     PrintDebug("IDE: Writing PRI DMA Port %x (%s) (val=%x)\n", port, dma_port_to_str(port & 0x7), *(uint32_t *)src);
484     return write_dma_port(port & 0x7, src, length, dev, &(ide->channels[0]));
485 }
486
487 static int write_sec_dma_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
488     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
489     PrintDebug("IDE: Writing SEC DMA Port %x (%s) (val=%x)\n", port, dma_port_to_str(port & 0x7), *(uint32_t *)src);
490     return write_dma_port(port & 0x7, src, length, dev, &(ide->channels[1]));
491 }
492
493
494 static int read_pri_dma_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
495     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
496     PrintDebug("IDE: Reading PRI DMA Port %x (%s)\n", port, dma_port_to_str(port & 0x7));
497     return read_dma_port(port & 0x7, dst, length, dev, &(ide->channels[0]));
498 }
499
500 static int read_sec_dma_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
501     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
502     PrintDebug("IDE: Reading SEC DMA Port %x (%s)\n", port, dma_port_to_str(port & 0x7));
503     return read_dma_port(port & 0x7, dst, length, dev, &(ide->channels[1]));
504 }
505
506
507 #define DMA_CMD_PORT      0x00
508 #define DMA_STATUS_PORT   0x02
509 #define DMA_PRD_PORT0     0x04
510 #define DMA_PRD_PORT1     0x05
511 #define DMA_PRD_PORT2     0x06
512 #define DMA_PRD_PORT3     0x07
513
514
515 static int write_dma_port(ushort_t port_offset, void * src, uint_t length, 
516                           struct vm_device * dev, struct ide_channel * channel) {
517
518     switch (port_offset) {
519         case DMA_CMD_PORT:
520             channel->dma_cmd.val = *(uint8_t *)src;
521
522             if (channel->dma_cmd.start == 0) {
523                 channel->dma_tbl_index = 0;
524             } else {
525                 channel->dma_status.active = 1;
526
527                 if (channel->dma_cmd.read == 1) {
528                     // DMA Read
529                     if (dma_read(dev, channel) == -1) {
530                         PrintError("Failed DMA Read\n");
531                         return -1;
532                     }
533                 } else {
534                     // DMA write
535                     if (dma_write(dev, channel) == -1) {
536                         PrintError("Failed DMA Write\n");
537                         return -1;
538                     }
539                 }
540             }
541
542             break;
543             
544         case DMA_STATUS_PORT:
545             if (length != 1) {
546                 PrintError("Invalid read length for DMA status port\n");
547                 return -1;
548             }
549
550             channel->dma_status.val = *(uint8_t *)src;
551             break;
552             
553         case DMA_PRD_PORT0:
554         case DMA_PRD_PORT1:
555         case DMA_PRD_PORT2:
556         case DMA_PRD_PORT3: {
557             uint_t addr_index = port_offset & 0x3;
558             uint8_t * addr_buf = (uint8_t *)&(channel->dma_prd_addr);
559             int i = 0;
560
561             if (addr_index + length > 4) {
562                 PrintError("DMA Port space overrun port=%x len=%d\n", port_offset, length);
563                 return -1;
564             }
565
566             for (i = 0; i < length; i++) {
567                 addr_buf[addr_index + i] = *((uint8_t *)src + i);
568             }
569
570             PrintDebug("Writing PRD Port %x (val=%x)\n", port_offset, channel->dma_prd_addr);
571
572             break;
573         }
574         default:
575             PrintError("IDE: Invalid DMA Port (%s)\n", dma_port_to_str(port_offset));
576             return -1;
577     }
578
579     return length;
580 }
581
582
583 static int read_dma_port(ushort_t port_offset, void * dst, uint_t length, 
584                          struct vm_device * dev, struct ide_channel * channel) {
585
586     switch (port_offset) {
587         case DMA_CMD_PORT:
588             *(uint8_t *)dst = channel->dma_cmd.val;
589             break;
590
591         case DMA_STATUS_PORT:
592             if (length != 1) {
593                 PrintError("Invalid read length for DMA status port\n");
594                 return -1;
595             }
596
597             *(uint8_t *)dst = channel->dma_status.val;
598             break;
599
600         case DMA_PRD_PORT0:
601         case DMA_PRD_PORT1:
602         case DMA_PRD_PORT2:
603         case DMA_PRD_PORT3: {
604             uint_t addr_index = port_offset & 0x3;
605             uint8_t * addr_buf = (uint8_t *)&(channel->dma_prd_addr);
606             int i = 0;
607
608             if (addr_index + length > 4) {
609                 PrintError("DMA Port space overrun port=%x len=%d\n", port_offset, length);
610                 return -1;
611             }
612
613             for (i = 0; i < length; i++) {
614                 *((uint8_t *)dst + i) = addr_buf[addr_index + i];
615             }
616
617             break;
618         }
619         default:
620             PrintError("IDE: Invalid DMA Port (%s)\n", dma_port_to_str(port_offset));
621             return -1;
622     }
623
624     PrintDebug("\tval=%x\n", *(uint32_t *)dst);
625
626     return length;
627 }
628
629
630
631 static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
632     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
633     struct ide_channel * channel = get_selected_channel(ide, port);
634     struct ide_drive * drive = get_selected_drive(channel);
635
636     if (length != 1) {
637         PrintError("Invalid Write Length on IDE command Port %x\n", port);
638         return -1;
639     }
640
641     PrintDebug("IDE: Writing Command Port %x (%s) (val=%x)\n", port, io_port_to_str(port), *(uint8_t *)src);
642     
643     channel->cmd_reg = *(uint8_t *)src;
644     
645     switch (channel->cmd_reg) {
646         
647         case 0xa0: // ATAPI Command Packet
648             if (drive->drive_type != IDE_CDROM) {
649                 ide_abort_command(dev, channel);
650             }
651             
652             drive->sector_count = 1;
653
654             channel->status.busy = 0;
655             channel->status.write_fault = 0;
656             channel->status.data_req = 1;
657             channel->status.error = 0;
658
659             // reset the data buffer...
660             drive->transfer_length = ATAPI_PACKET_SIZE;
661             drive->transfer_index = 0;
662
663             break;
664         case 0xa1: // ATAPI Identify Device Packet
665             atapi_identify_device(drive);
666
667             channel->error_reg.val = 0;
668             channel->status.val = 0x58; // ready, data_req, seek_complete
669             
670             ide_raise_irq(dev, channel);
671             break;
672         case 0xec: // Identify Device
673             if (drive->drive_type != IDE_DISK) {
674                 drive_reset(drive);
675
676                 // JRL: Should we abort here?
677                 ide_abort_command(dev, channel);
678             } else {
679                 ide_identify_device(drive);
680
681                 channel->error_reg.val = 0;
682                 channel->status.val = 0x58;
683
684                 ide_raise_irq(dev, channel);
685             }
686             break;
687
688         case 0xef: // Set Features
689             // Prior to this the features register has been written to. 
690             // This command tells the drive to check if the new value is supported (the value is drive specific)
691             // Common is that bit0=DMA enable
692             // If valid the drive raises an interrupt, if not it aborts.
693
694             // Do some checking here...
695
696             channel->status.busy = 0;
697             channel->status.write_fault = 0;
698             channel->status.error = 0;
699             channel->status.ready = 1;
700             channel->status.seek_complete = 1;
701             
702             ide_raise_irq(dev, channel);
703             break;
704         default:
705             PrintError("Unimplemented IDE command (%x)\n", channel->cmd_reg);
706             return -1;
707     }
708
709     return length;
710 }
711
712
713 static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
714     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
715     struct ide_channel * channel = get_selected_channel(ide, port);
716     struct ide_drive * drive = get_selected_drive(channel);
717
718     //    PrintDebug("IDE: Writing Data Port %x (val=%x, len=%d)\n", 
719     //         port, *(uint32_t *)src, length);
720     
721     memcpy(drive->data_buf + drive->transfer_index, src, length);    
722     drive->transfer_index += length;
723
724     // Transfer is complete, dispatch the command
725     if (drive->transfer_index >= drive->transfer_length) {
726         switch (channel->cmd_reg) {
727             case 0x30: // Write Sectors
728                 PrintError("Writing Data not yet implemented\n");
729                 return -1;
730                 
731             case 0xa0: // ATAPI packet command
732                 if (atapi_handle_packet(dev, channel) == -1) {
733                     PrintError("Error handling ATAPI packet\n");
734                     return -1;
735                 }
736                 break;
737             default:
738                 PrintError("Unhandld IDE Command %x\n", channel->cmd_reg);
739                 return -1;
740         }
741     }
742
743     return length;
744 }
745
746
747 static int read_hd_data(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
748     PrintError("Harddrive data port read not implemented\n");
749     return -1;
750 }
751
752
753
754 static int read_cd_data(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
755     struct ide_drive * drive = get_selected_drive(channel);
756     int data_offset = drive->transfer_index % DATA_BUFFER_SIZE;
757     int req_offset = drive->transfer_index % drive->req_len;
758     
759     if (drive->cd_state.atapi_cmd != 0x28) {
760         PrintDebug("IDE: Reading CD Data (len=%d) (req_len=%d)\n", length, drive->req_len);
761     }
762
763     if (drive->transfer_index >= drive->transfer_length) {
764         PrintError("Buffer Overrun... (xfer_len=%d) (cur_idx=%d) (post_idx=%d)\n", 
765                    drive->transfer_length, drive->transfer_index, 
766                    drive->transfer_index + length);
767         return -1;
768     }
769
770
771
772     if ((data_offset == 0) && (drive->transfer_index > 0)) {
773         
774         if (drive->drive_type == IDE_CDROM) {
775             if (atapi_update_data_buf(dev, channel) == -1) {
776                 PrintError("Could not update CDROM data buffer\n");
777                 return -1;
778             } 
779         } else {
780             PrintError("IDE Harddrives not implemented\n");
781             return -1;
782         }
783     }
784
785     memcpy(dst, drive->data_buf + data_offset, length);
786     
787     drive->transfer_index += length;
788
789     if ((req_offset == 0) && (drive->transfer_index > 0)) {
790         if (drive->transfer_index < drive->transfer_length) {
791             // An increment is complete, but there is still more data to be transferred...
792             
793             channel->status.data_req = 1;
794
795             drive->irq_flags.c_d = 0;
796
797             // Update the request length in the cylinder regs
798             if (atapi_update_req_len(dev, channel, drive->transfer_length - drive->transfer_index) == -1) {
799                 PrintError("Could not update request length after completed increment\n");
800                 return -1;
801             }
802         } else {
803             // This was the final read of the request
804             channel->status.data_req = 0;
805             channel->status.ready = 1;
806             
807             drive->irq_flags.c_d = 1;
808             drive->irq_flags.rel = 0;
809         }
810
811         drive->irq_flags.io_dir = 1;
812         channel->status.busy = 0;
813
814         ide_raise_irq(dev, channel);
815     }
816
817     return length;
818 }
819
820
821 static int read_drive_id(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
822     struct ide_drive * drive = get_selected_drive(channel);
823
824     channel->status.busy = 0;
825     channel->status.ready = 1;
826     channel->status.write_fault = 0;
827     channel->status.seek_complete = 1;
828     channel->status.corrected = 0;
829     channel->status.error = 0;
830                 
831     
832     memcpy(dst, drive->data_buf + drive->transfer_index, length);
833     drive->transfer_index += length;
834     
835     if (drive->transfer_index >= drive->transfer_length) {
836         channel->status.data_req = 0;
837     }
838     
839     return length;
840 }
841
842
843 static int ide_read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
844     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
845     struct ide_channel * channel = get_selected_channel(ide, port);
846     struct ide_drive * drive = get_selected_drive(channel);
847
848     //    PrintDebug("IDE: Reading Data Port %x (len=%d)\n", port, length);
849
850     if ((channel->cmd_reg == 0xec) ||
851         (channel->cmd_reg == 0xa1)) {
852         return read_drive_id((uint8_t *)dst, length, dev, channel);
853     }
854
855     if (drive->drive_type == IDE_CDROM) {
856         if (read_cd_data((uint8_t *)dst, length, dev, channel) == -1) {
857             PrintError("IDE: Could not read CD Data\n");
858             return -1;
859         }
860     } else if (drive->drive_type == IDE_DISK) {
861         if (read_hd_data((uint8_t *)dst, length, dev, channel) == -1) {
862             PrintError("IDE: Could not read HD Data\n");
863             return -1;
864         }
865     } else {
866         memset((uint8_t *)dst, 0, length);
867     }
868
869     return length;
870 }
871
872 static int write_port_std(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
873     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
874     struct ide_channel * channel = get_selected_channel(ide, port);
875     struct ide_drive * drive = get_selected_drive(channel);
876             
877     if (length != 1) {
878         PrintError("Invalid Write length on IDE port %x\n", port);
879         return -1;
880     }
881
882     PrintDebug("IDE: Writing Standard Port %x (%s) (val=%x)\n", port, io_port_to_str(port), *(uint8_t *)src);
883
884     switch (port) {
885         // reset and interrupt enable
886         case PRI_CTRL_PORT:
887         case SEC_CTRL_PORT: {
888             struct ide_ctrl_reg * tmp_ctrl = (struct ide_ctrl_reg *)src;
889
890             // only reset channel on a 0->1 reset bit transition
891             if ((!channel->ctrl_reg.soft_reset) && (tmp_ctrl->soft_reset)) {
892                 channel_reset(channel);
893             } else if ((channel->ctrl_reg.soft_reset) && (!tmp_ctrl->soft_reset)) {
894                 channel_reset_complete(channel);
895             }
896
897             channel->ctrl_reg.val = tmp_ctrl->val;          
898             break;
899         }
900         case PRI_FEATURES_PORT:
901         case SEC_FEATURES_PORT:
902             channel->features.val = *(uint8_t *)src;
903             break;
904
905         case PRI_SECT_CNT_PORT:
906         case SEC_SECT_CNT_PORT:
907             drive->sector_count = *(uint8_t *)src;
908             break;
909
910         case PRI_SECT_NUM_PORT:
911         case SEC_SECT_NUM_PORT:
912             drive->sector_num = *(uint8_t *)src;
913
914         case PRI_CYL_LOW_PORT:
915         case SEC_CYL_LOW_PORT:
916             drive->cylinder_low = *(uint8_t *)src;
917             break;
918
919         case PRI_CYL_HIGH_PORT:
920         case SEC_CYL_HIGH_PORT:
921             drive->cylinder_high = *(uint8_t *)src;
922             break;
923
924         case PRI_DRV_SEL_PORT:
925         case SEC_DRV_SEL_PORT: {
926             channel->drive_head.val = *(uint8_t *)src;
927             
928             // make sure the reserved bits are ok..
929             // JRL TODO: check with new ramdisk to make sure this is right...
930             channel->drive_head.val |= 0xa0;
931
932             drive = get_selected_drive(channel);
933
934             // Selecting a non-present device is a no-no
935             if (drive->drive_type == IDE_NONE) {
936                 PrintDebug("Attempting to select a non-present drive\n");
937                 channel->error_reg.abort = 1;
938                 channel->status.error = 1;
939             }
940
941             break;
942         }
943         default:
944             PrintError("IDE: Write to unknown Port %x\n", port);
945             return -1;
946     }
947     return length;
948 }
949
950
951 static int read_port_std(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
952     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
953     struct ide_channel * channel = get_selected_channel(ide, port);
954     struct ide_drive * drive = get_selected_drive(channel);
955     
956     if (length != 1) {
957         PrintError("Invalid Read length on IDE port %x\n", port);
958         return -1;
959     }
960     
961     PrintDebug("IDE: Reading Standard Port %x (%s)\n", port, io_port_to_str(port));
962
963     if ((port == PRI_ADDR_REG_PORT) ||
964         (port == SEC_ADDR_REG_PORT)) {
965         // unused, return 0xff
966         *(uint8_t *)dst = 0xff;
967         return length;
968     }
969
970
971     // if no drive is present just return 0 + reserved bits
972     if (drive->drive_type == IDE_NONE) {
973         if ((port == PRI_DRV_SEL_PORT) ||
974             (port == SEC_DRV_SEL_PORT)) {
975             *(uint8_t *)dst = 0xa0;
976         } else {
977             *(uint8_t *)dst = 0;
978         }
979
980         return length;
981     }
982
983     switch (port) {
984
985         // This is really the error register.
986         case PRI_FEATURES_PORT:
987         case SEC_FEATURES_PORT:
988             *(uint8_t *)dst = channel->error_reg.val;
989             break;
990             
991         case PRI_SECT_CNT_PORT:
992         case SEC_SECT_CNT_PORT:
993             *(uint8_t *)dst = drive->sector_count;
994             break;
995
996         case PRI_SECT_NUM_PORT:
997         case SEC_SECT_NUM_PORT:
998             *(uint8_t *)dst = drive->sector_num;
999             break;
1000
1001         case PRI_CYL_LOW_PORT:
1002         case SEC_CYL_LOW_PORT:
1003             *(uint8_t *)dst = drive->cylinder_low;
1004             break;
1005
1006
1007         case PRI_CYL_HIGH_PORT:
1008         case SEC_CYL_HIGH_PORT:
1009             *(uint8_t *)dst = drive->cylinder_high;
1010             break;
1011
1012         case PRI_DRV_SEL_PORT:
1013         case SEC_DRV_SEL_PORT:  // hard disk drive and head register 0x1f6
1014             *(uint8_t *)dst = channel->drive_head.val;
1015             break;
1016
1017         case PRI_CTRL_PORT:
1018         case SEC_CTRL_PORT:
1019         case PRI_CMD_PORT:
1020         case SEC_CMD_PORT:
1021             // Something about lowering interrupts here....
1022             *(uint8_t *)dst = channel->status.val;
1023             break;
1024
1025         default:
1026             PrintError("Invalid Port: %x\n", port);
1027             return -1;
1028     }
1029
1030     PrintDebug("\tVal=%x\n", *(uint8_t *)dst);
1031
1032     return length;
1033 }
1034
1035
1036
1037 static void init_drive(struct ide_drive * drive) {
1038
1039     drive->sector_count = 0x01;
1040     drive->sector_num = 0x01;
1041     drive->cylinder = 0x0000;
1042
1043     drive->drive_type = IDE_NONE;
1044
1045     memset(drive->model, 0, sizeof(drive->model));
1046
1047     drive->transfer_index = 0;
1048     drive->transfer_length = 0;
1049     memset(drive->data_buf, 0, sizeof(drive->data_buf));
1050
1051
1052
1053     drive->private_data = NULL;
1054     drive->cd_ops = NULL;
1055 }
1056
1057 static void init_channel(struct ide_channel * channel) {
1058     int i = 0;
1059
1060     channel->error_reg.val = 0x01;
1061     channel->drive_head.val = 0x00;
1062     channel->status.val = 0x00;
1063     channel->cmd_reg = 0x00;
1064     channel->ctrl_reg.val = 0x08;
1065
1066
1067     channel->dma_cmd.val = 0;
1068     channel->dma_status.val = 0;
1069     channel->dma_prd_addr = 0;
1070     channel->dma_tbl_index = 0;
1071
1072     for (i = 0; i < 2; i++) {
1073         init_drive(&(channel->drives[i]));
1074     }
1075
1076 }
1077
1078
1079 static int pci_config_update(struct pci_device * pci_dev, uint_t reg_num, int length) {
1080     PrintDebug("Interupt register (Dev=%s), irq=%d\n", pci_dev->name, pci_dev->config_header.intr_line);
1081
1082     return 0;
1083 }
1084
1085 static int init_ide_state(struct vm_device * dev) {
1086     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1087     struct v3_pci_bar bars[6];
1088     struct pci_device * pci_dev = NULL;
1089     int i, j;
1090
1091     for (i = 0; i < 2; i++) {
1092         init_channel(&(ide->channels[i]));
1093
1094         // JRL: this is a terrible hack...
1095         ide->channels[i].irq = PRI_DEFAULT_IRQ + i;
1096
1097         for (j = 0; j < 6; j++) {
1098             bars[j].type = PCI_BAR_NONE;
1099         }
1100
1101
1102         bars[4].type = PCI_BAR_IO;
1103         bars[4].default_base_port = PRI_DEFAULT_DMA_PORT + (i * 0x8);
1104         bars[4].num_ports = 8;
1105         
1106         if (i == 0) {
1107             bars[4].io_read = read_pri_dma_port;
1108             bars[4].io_write = write_pri_dma_port;
1109         } else {
1110             bars[4].io_read = read_sec_dma_port;
1111             bars[4].io_write = write_sec_dma_port;
1112         }
1113
1114         pci_dev = v3_pci_register_device(ide->pci, PCI_STD_DEVICE, 0, "V3_IDE", -1, bars,
1115                                          pci_config_update, NULL, NULL, dev);
1116
1117         if (pci_dev == NULL) {
1118             PrintError("Failed to register IDE BUS %d with PCI\n", i); 
1119             return -1;
1120         }
1121
1122         ide->channels[i].pci_dev = pci_dev;
1123
1124         pci_dev->config_header.vendor_id = 0x1095;
1125         pci_dev->config_header.device_id = 0x0646;
1126         pci_dev->config_header.revision = 0x8f07;
1127         pci_dev->config_header.subclass = 0x01;
1128         pci_dev->config_header.class = 0x01;
1129
1130         pci_dev->config_header.intr_line = PRI_DEFAULT_IRQ + i;
1131         pci_dev->config_header.intr_pin = 1;
1132     }
1133
1134
1135
1136     /* Register PIIX3 Busmaster PCI device */
1137     for (j = 0; j < 6; j++) {
1138         bars[j].type = PCI_BAR_NONE;
1139     }
1140
1141     pci_dev = v3_pci_register_device(ide->pci, PCI_STD_DEVICE, 0, "PIIX3 IDE", -1, bars,
1142                                      NULL, NULL, NULL, dev);
1143     
1144     
1145     ide->busmaster_pci = pci_dev;
1146
1147     pci_dev->config_header.vendor_id = 0x8086;
1148     pci_dev->config_header.device_id = 0x7010;
1149     pci_dev->config_header.revision = 0x80;
1150     pci_dev->config_header.subclass = 0x01;
1151     pci_dev->config_header.class = 0x01;
1152
1153
1154     return 0;
1155 }
1156
1157
1158
1159 static int init_ide(struct vm_device * dev) {
1160     //struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1161
1162     PrintDebug("IDE: Initializing IDE\n");
1163
1164     if (init_ide_state(dev) == -1) {
1165         PrintError("Failed to initialize IDE state\n");
1166         return -1;
1167     }
1168
1169
1170     v3_dev_hook_io(dev, PRI_DATA_PORT, 
1171                    &ide_read_data_port, &write_data_port);
1172     v3_dev_hook_io(dev, PRI_FEATURES_PORT, 
1173                    &read_port_std, &write_port_std);
1174     v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, 
1175                    &read_port_std, &write_port_std);
1176     v3_dev_hook_io(dev, PRI_SECT_NUM_PORT, 
1177                    &read_port_std, &write_port_std);
1178     v3_dev_hook_io(dev, PRI_CYL_LOW_PORT, 
1179                    &read_port_std, &write_port_std);
1180     v3_dev_hook_io(dev, PRI_CYL_HIGH_PORT, 
1181                    &read_port_std, &write_port_std);
1182     v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, 
1183                    &read_port_std, &write_port_std);
1184     v3_dev_hook_io(dev, PRI_CMD_PORT, 
1185                    &read_port_std, &write_cmd_port);
1186
1187     v3_dev_hook_io(dev, SEC_DATA_PORT, 
1188                    &ide_read_data_port, &write_data_port);
1189     v3_dev_hook_io(dev, SEC_FEATURES_PORT, 
1190                    &read_port_std, &write_port_std);
1191     v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, 
1192                    &read_port_std, &write_port_std);
1193     v3_dev_hook_io(dev, SEC_SECT_NUM_PORT, 
1194                    &read_port_std, &write_port_std);
1195     v3_dev_hook_io(dev, SEC_CYL_LOW_PORT, 
1196                    &read_port_std, &write_port_std);
1197     v3_dev_hook_io(dev, SEC_CYL_HIGH_PORT, 
1198                    &read_port_std, &write_port_std);
1199     v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, 
1200                    &read_port_std, &write_port_std);
1201     v3_dev_hook_io(dev, SEC_CMD_PORT, 
1202                    &read_port_std, &write_cmd_port);
1203   
1204
1205     v3_dev_hook_io(dev, PRI_CTRL_PORT, 
1206                    &read_port_std, &write_port_std);
1207
1208     v3_dev_hook_io(dev, SEC_CTRL_PORT, 
1209                    &read_port_std, &write_port_std);
1210   
1211
1212     v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, 
1213                    &read_port_std, &write_port_std);
1214
1215     v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, 
1216                    &read_port_std, &write_port_std);
1217
1218     return 0;
1219 }
1220
1221
1222 static int deinit_ide(struct vm_device * dev) {
1223     // unhook io ports....
1224     // deregister from PCI?
1225     return 0;
1226 }
1227
1228
1229 static struct vm_device_ops dev_ops = {
1230     .init = init_ide,
1231     .deinit = deinit_ide,
1232     .reset = NULL,
1233     .start = NULL,
1234     .stop = NULL,
1235 };
1236
1237
1238 struct vm_device *  v3_create_ide(struct vm_device * pci) {
1239     struct ide_internal * ide  = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal));  
1240     struct vm_device * device = v3_create_device("IDE", &dev_ops, ide);
1241
1242     ide->pci = pci;
1243
1244     PrintDebug("IDE: Creating IDE bus x 2\n");
1245
1246     return device;
1247 }
1248
1249
1250
1251
1252
1253 int v3_ide_register_cdrom(struct vm_device * ide_dev, 
1254                           uint_t bus_num, 
1255                           uint_t drive_num,
1256                           char * dev_name, 
1257                           struct v3_ide_cd_ops * ops, 
1258                           void * private_data) {
1259
1260     struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
1261     struct ide_channel * channel = NULL;
1262     struct ide_drive * drive = NULL;
1263
1264     V3_ASSERT((bus_num >= 0) && (bus_num < 2));
1265     V3_ASSERT((drive_num >= 0) && (drive_num < 2));
1266
1267     channel = &(ide->channels[bus_num]);
1268     drive = &(channel->drives[drive_num]);
1269     
1270     if (drive->drive_type != IDE_NONE) {
1271         PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
1272         return -1;
1273     }
1274
1275     strncpy(drive->model, dev_name, sizeof(drive->model) - 1);
1276
1277     while (strlen((char *)(drive->model)) < 40) {
1278         strcat((char*)(drive->model), " ");
1279     }
1280
1281
1282     drive->drive_type = IDE_CDROM;
1283
1284     drive->cd_ops = ops;
1285
1286     drive->private_data = private_data;
1287
1288     return 0;
1289 }
1290
1291
1292 int v3_ide_register_harddisk(struct vm_device * ide_dev, 
1293                              uint_t bus_num, 
1294                              uint_t drive_num, 
1295                              char * dev_name, 
1296                              struct v3_ide_hd_ops * ops, 
1297                              void * private_data) {
1298
1299     struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
1300     struct ide_channel * channel = NULL;
1301     struct ide_drive * drive = NULL;
1302
1303     V3_ASSERT((bus_num >= 0) && (bus_num < 2));
1304     V3_ASSERT((drive_num >= 0) && (drive_num < 2));
1305
1306     channel = &(ide->channels[bus_num]);
1307     drive = &(channel->drives[drive_num]);
1308     
1309     if (drive->drive_type != IDE_NONE) {
1310         PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
1311         return -1;
1312     }
1313
1314     strncpy(drive->model, dev_name, sizeof(drive->model) - 1);
1315
1316     drive->drive_type = IDE_DISK;
1317
1318     drive->hd_ops = ops;
1319
1320     drive->private_data = private_data;
1321
1322     return 0;
1323 }
1324
1325
1326