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.


IDE hard drive works past grub
[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[] = {"NONE", "HARDDISK", "CDROM" };
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
109     uint8_t atapi_cmd;
110     struct atapi_error_recovery err_recovery;
111 };
112
113 struct ide_hd_state {
114     int accessed;
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     uint64_t current_lba;
143
144     // We have a local data buffer that we use for IO port accesses
145     uint8_t data_buf[DATA_BUFFER_SIZE];
146
147
148     void * private_data;
149     
150     union {
151         uint8_t sector_count;             // 0x1f2,0x172
152         struct atapi_irq_flags irq_flags;
153     } __attribute__((packed));
154
155     union {
156         uint8_t sector_num;               // 0x1f3,0x173
157         uint8_t lba0;
158     } __attribute__((packed));
159
160     union {
161         uint16_t cylinder;
162         uint16_t lba12;
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     PrintDebug("Resetting drive %s\n", drive->model);
287     
288     if (drive->drive_type == IDE_CDROM) {
289         drive->cylinder = 0xeb14;
290     } else {
291         drive->cylinder = 0x0000;
292         //drive->hd_state.accessed = 0;
293     }
294
295
296     memset(drive->data_buf, 0, sizeof(drive->data_buf));
297     drive->transfer_index = 0;
298
299     // Send the reset signal to the connected device callbacks
300     //     channel->drives[0].reset();
301     //    channel->drives[1].reset();
302 }
303
304 static void channel_reset(struct ide_channel * channel) {
305     
306     // set busy and seek complete flags
307     channel->status.val = 0x90;
308
309     // Clear errors
310     channel->error_reg.val = 0x01;
311
312     // clear commands
313     channel->cmd_reg = 0x00;
314
315     channel->ctrl_reg.irq_disable = 0;
316 }
317
318 static void channel_reset_complete(struct ide_channel * channel) {
319     channel->status.busy = 0;
320     channel->status.ready = 1;
321
322     channel->drive_head.head_num = 0;    
323     
324     drive_reset(&(channel->drives[0]));
325     drive_reset(&(channel->drives[1]));
326 }
327
328
329 static void ide_abort_command(struct vm_device * dev, struct ide_channel * channel) {
330     channel->status.val = 0x41; // Error + ready
331     channel->error_reg.val = 0x04; // No idea...
332
333     ide_raise_irq(dev, channel);
334 }
335
336
337
338
339
340
341 /* ATAPI functions */
342 #include "atapi.h"
343
344 /* ATA functions */
345 #include "ata.h"
346
347
348
349 /* IO Operations */
350 static int dma_read(struct vm_device * dev, struct ide_channel * channel) {
351     struct ide_drive * drive = get_selected_drive(channel);
352     struct ide_dma_prd prd_entry;
353     uint32_t prd_entry_addr = channel->dma_prd_addr + (sizeof(struct ide_dma_prd) * channel->dma_tbl_index);
354     int ret;
355
356
357     PrintDebug("PRD table address = %x\n", channel->dma_prd_addr);
358
359     ret = read_guest_pa_memory(dev->vm, prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry);
360
361     if (ret != sizeof(struct ide_dma_prd)) {
362         PrintError("Could not read PRD\n");
363         return -1;
364     }
365
366     PrintDebug("PRD Addr: %x, PDR Len: %d, EOT: %d\n", prd_entry.base_addr, prd_entry.size, prd_entry.end_of_table);
367
368     ret = write_guest_pa_memory(dev->vm, prd_entry.base_addr, prd_entry.size, drive->data_buf); 
369
370     if (ret != prd_entry.size) {
371         PrintError("Failed to copy data into guest memory... (ret=%d)\n", ret);
372         return -1;
373     }
374
375     channel->status.busy = 0;
376     channel->status.ready = 1;
377     channel->status.data_req = 0;
378     channel->status.error = 0;
379     channel->status.seek_complete = 1;
380
381     /*
382       drive->irq_flags.io_dir = 1;
383       drive->irq_flags.c_d = 1;
384       drive->irq_flags.rel = 0;
385     */
386
387
388     // set DMA status
389     channel->dma_status.active = 0;
390     channel->dma_status.err = 1;
391     channel->dma_status.int_gen = 1;
392
393     ide_raise_irq(dev, channel);
394
395     return 0;
396 }
397
398
399 static int dma_write(struct vm_device * dev, struct ide_channel * channel) {
400     // unsupported
401     PrintError("DMA writes currently not supported\n");
402     return -1;
403 }
404
405
406 /* 
407  * This is an ugly ugly ugly way to differentiate between the first and second DMA channels 
408  */
409
410 static int write_dma_port(ushort_t port_offset, void * src, uint_t length, struct vm_device * dev, struct ide_channel * channel);
411 static int read_dma_port(ushort_t port_offset, void * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel);
412
413
414 static int write_pri_dma_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
415     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
416     PrintDebug("IDE: Writing PRI DMA Port %x (%s) (val=%x)\n", port, dma_port_to_str(port & 0x7), *(uint32_t *)src);
417     return write_dma_port(port & 0x7, src, length, dev, &(ide->channels[0]));
418 }
419
420 static int write_sec_dma_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
421     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
422     PrintDebug("IDE: Writing SEC DMA Port %x (%s) (val=%x)\n", port, dma_port_to_str(port & 0x7), *(uint32_t *)src);
423     return write_dma_port(port & 0x7, src, length, dev, &(ide->channels[1]));
424 }
425
426
427 static int read_pri_dma_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
428     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
429     PrintDebug("IDE: Reading PRI DMA Port %x (%s)\n", port, dma_port_to_str(port & 0x7));
430     return read_dma_port(port & 0x7, dst, length, dev, &(ide->channels[0]));
431 }
432
433 static int read_sec_dma_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
434     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
435     PrintDebug("IDE: Reading SEC DMA Port %x (%s)\n", port, dma_port_to_str(port & 0x7));
436     return read_dma_port(port & 0x7, dst, length, dev, &(ide->channels[1]));
437 }
438
439
440 #define DMA_CMD_PORT      0x00
441 #define DMA_STATUS_PORT   0x02
442 #define DMA_PRD_PORT0     0x04
443 #define DMA_PRD_PORT1     0x05
444 #define DMA_PRD_PORT2     0x06
445 #define DMA_PRD_PORT3     0x07
446
447
448 static int write_dma_port(ushort_t port_offset, void * src, uint_t length, 
449                           struct vm_device * dev, struct ide_channel * channel) {
450
451     switch (port_offset) {
452         case DMA_CMD_PORT:
453             channel->dma_cmd.val = *(uint8_t *)src;
454
455             if (channel->dma_cmd.start == 0) {
456                 channel->dma_tbl_index = 0;
457             } else {
458                 channel->dma_status.active = 1;
459
460                 if (channel->dma_cmd.read == 1) {
461                     // DMA Read
462                     if (dma_read(dev, channel) == -1) {
463                         PrintError("Failed DMA Read\n");
464                         return -1;
465                     }
466                 } else {
467                     // DMA write
468                     if (dma_write(dev, channel) == -1) {
469                         PrintError("Failed DMA Write\n");
470                         return -1;
471                     }
472                 }
473             }
474
475             break;
476             
477         case DMA_STATUS_PORT:
478             if (length != 1) {
479                 PrintError("Invalid read length for DMA status port\n");
480                 return -1;
481             }
482
483             channel->dma_status.val = *(uint8_t *)src;
484             break;
485             
486         case DMA_PRD_PORT0:
487         case DMA_PRD_PORT1:
488         case DMA_PRD_PORT2:
489         case DMA_PRD_PORT3: {
490             uint_t addr_index = port_offset & 0x3;
491             uint8_t * addr_buf = (uint8_t *)&(channel->dma_prd_addr);
492             int i = 0;
493
494             if (addr_index + length > 4) {
495                 PrintError("DMA Port space overrun port=%x len=%d\n", port_offset, length);
496                 return -1;
497             }
498
499             for (i = 0; i < length; i++) {
500                 addr_buf[addr_index + i] = *((uint8_t *)src + i);
501             }
502
503             PrintDebug("Writing PRD Port %x (val=%x)\n", port_offset, channel->dma_prd_addr);
504
505             break;
506         }
507         default:
508             PrintError("IDE: Invalid DMA Port (%s)\n", dma_port_to_str(port_offset));
509             return -1;
510     }
511
512     return length;
513 }
514
515
516 static int read_dma_port(ushort_t port_offset, void * dst, uint_t length, 
517                          struct vm_device * dev, struct ide_channel * channel) {
518
519     switch (port_offset) {
520         case DMA_CMD_PORT:
521             *(uint8_t *)dst = channel->dma_cmd.val;
522             break;
523
524         case DMA_STATUS_PORT:
525             if (length != 1) {
526                 PrintError("Invalid read length for DMA status port\n");
527                 return -1;
528             }
529
530             *(uint8_t *)dst = channel->dma_status.val;
531             break;
532
533         case DMA_PRD_PORT0:
534         case DMA_PRD_PORT1:
535         case DMA_PRD_PORT2:
536         case DMA_PRD_PORT3: {
537             uint_t addr_index = port_offset & 0x3;
538             uint8_t * addr_buf = (uint8_t *)&(channel->dma_prd_addr);
539             int i = 0;
540
541             if (addr_index + length > 4) {
542                 PrintError("DMA Port space overrun port=%x len=%d\n", port_offset, length);
543                 return -1;
544             }
545
546             for (i = 0; i < length; i++) {
547                 *((uint8_t *)dst + i) = addr_buf[addr_index + i];
548             }
549
550             break;
551         }
552         default:
553             PrintError("IDE: Invalid DMA Port (%s)\n", dma_port_to_str(port_offset));
554             return -1;
555     }
556
557     PrintDebug("\tval=%x\n", *(uint32_t *)dst);
558
559     return length;
560 }
561
562
563
564 static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
565     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
566     struct ide_channel * channel = get_selected_channel(ide, port);
567     struct ide_drive * drive = get_selected_drive(channel);
568
569     if (length != 1) {
570         PrintError("Invalid Write Length on IDE command Port %x\n", port);
571         return -1;
572     }
573
574     PrintDebug("IDE: Writing Command Port %x (%s) (val=%x)\n", port, io_port_to_str(port), *(uint8_t *)src);
575     
576     channel->cmd_reg = *(uint8_t *)src;
577     
578     switch (channel->cmd_reg) {
579
580         case 0xa1: // ATAPI Identify Device Packet
581             if (drive->drive_type != IDE_CDROM) {
582                 drive_reset(drive);
583
584                 // JRL: Should we abort here?
585                 ide_abort_command(dev, channel);
586             } else {
587                 
588                 atapi_identify_device(drive);
589                 
590                 channel->error_reg.val = 0;
591                 channel->status.val = 0x58; // ready, data_req, seek_complete
592             
593                 ide_raise_irq(dev, channel);
594             }
595             break;
596         case 0xec: // Identify Device
597             if (drive->drive_type != IDE_DISK) {
598                 drive_reset(drive);
599
600                 // JRL: Should we abort here?
601                 ide_abort_command(dev, channel);
602             } else {
603                 ata_identify_device(drive);
604
605                 channel->error_reg.val = 0;
606                 channel->status.val = 0x58;
607
608                 ide_raise_irq(dev, channel);
609             }
610             break;
611
612         case 0xa0: // ATAPI Command Packet
613             if (drive->drive_type != IDE_CDROM) {
614                 ide_abort_command(dev, channel);
615             }
616             
617             drive->sector_count = 1;
618
619             channel->status.busy = 0;
620             channel->status.write_fault = 0;
621             channel->status.data_req = 1;
622             channel->status.error = 0;
623
624             // reset the data buffer...
625             drive->transfer_length = ATAPI_PACKET_SIZE;
626             drive->transfer_index = 0;
627
628             break;
629
630         case 0x20: // Read Sectors with Retry
631         case 0x21: // Read Sectors without Retry
632             if (ata_read_sectors(dev, channel) == -1) {
633                 PrintError("Error reading sectors\n");
634                 return -1;
635             }
636             break;
637
638         case 0x24: // Read Sectors Extended
639             if (ata_read_sectors_ext(dev, channel) == -1) {
640                 PrintError("Error reading extended sectors\n");
641                 return -1;
642             }
643             break;
644         case 0xef: // Set Features
645             // Prior to this the features register has been written to. 
646             // This command tells the drive to check if the new value is supported (the value is drive specific)
647             // Common is that bit0=DMA enable
648             // If valid the drive raises an interrupt, if not it aborts.
649
650             // Do some checking here...
651
652             channel->status.busy = 0;
653             channel->status.write_fault = 0;
654             channel->status.error = 0;
655             channel->status.ready = 1;
656             channel->status.seek_complete = 1;
657             
658             ide_raise_irq(dev, channel);
659             break;
660
661         default:
662             PrintError("Unimplemented IDE command (%x)\n", channel->cmd_reg);
663             return -1;
664     }
665
666     return length;
667 }
668
669
670 static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
671     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
672     struct ide_channel * channel = get_selected_channel(ide, port);
673     struct ide_drive * drive = get_selected_drive(channel);
674
675     //    PrintDebug("IDE: Writing Data Port %x (val=%x, len=%d)\n", 
676     //         port, *(uint32_t *)src, length);
677     
678     memcpy(drive->data_buf + drive->transfer_index, src, length);    
679     drive->transfer_index += length;
680
681     // Transfer is complete, dispatch the command
682     if (drive->transfer_index >= drive->transfer_length) {
683         switch (channel->cmd_reg) {
684             case 0x30: // Write Sectors
685                 PrintError("Writing Data not yet implemented\n");
686                 return -1;
687                 
688             case 0xa0: // ATAPI packet command
689                 if (atapi_handle_packet(dev, channel) == -1) {
690                     PrintError("Error handling ATAPI packet\n");
691                     return -1;
692                 }
693                 break;
694             default:
695                 PrintError("Unhandld IDE Command %x\n", channel->cmd_reg);
696                 return -1;
697         }
698     }
699
700     return length;
701 }
702
703
704 static int read_hd_data(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
705     struct ide_drive * drive = get_selected_drive(channel);
706     int data_offset = drive->transfer_index % IDE_SECTOR_SIZE;
707
708
709
710     if (drive->transfer_index >= drive->transfer_length) {
711         PrintError("Buffer overrun... (xfer_len=%d) (cur_idx=%x) (post_idx=%d)\n",
712                    drive->transfer_length, drive->transfer_index,
713                    drive->transfer_index + length);
714         return -1;
715     }
716
717     
718     if ((data_offset == 0) && (drive->transfer_index > 0)) {
719         drive->current_lba++;
720
721         if (ata_read(dev, channel) == -1) {
722             PrintError("Could not read next disk sector\n");
723             return -1;
724         }
725     }
726
727     /*
728       PrintDebug("Reading HD Data (Val=%x), (len=%d) (offset=%d)\n", 
729       *(uint32_t *)(drive->data_buf + data_offset), 
730       length, data_offset);
731     */
732     memcpy(dst, drive->data_buf + data_offset, length);
733
734     drive->transfer_index += length;
735
736     if ((drive->transfer_index % IDE_SECTOR_SIZE) == 0) {
737         if (drive->transfer_index < drive->transfer_length) {
738             // An increment is complete, but there is still more data to be transferred...
739             PrintDebug("Integral Complete, still transferring more sectors\n");
740             channel->status.data_req = 1;
741
742             drive->irq_flags.c_d = 0;
743         } else {
744             PrintDebug("Final Sector Transferred\n");
745             // This was the final read of the request
746             channel->status.data_req = 0;
747
748             
749             drive->irq_flags.c_d = 1;
750             drive->irq_flags.rel = 0;
751         }
752
753         channel->status.ready = 1;
754         drive->irq_flags.io_dir = 1;
755         channel->status.busy = 0;
756
757         ide_raise_irq(dev, channel);
758     }
759
760
761     return length;
762 }
763
764
765
766 static int read_cd_data(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
767     struct ide_drive * drive = get_selected_drive(channel);
768     int data_offset = drive->transfer_index % ATAPI_BLOCK_SIZE;
769     int req_offset = drive->transfer_index % drive->req_len;
770     
771     if (drive->cd_state.atapi_cmd != 0x28) {
772         PrintDebug("IDE: Reading CD Data (len=%d) (req_len=%d)\n", length, drive->req_len);
773     }
774
775     if (drive->transfer_index >= drive->transfer_length) {
776         PrintError("Buffer Overrun... (xfer_len=%d) (cur_idx=%d) (post_idx=%d)\n", 
777                    drive->transfer_length, drive->transfer_index, 
778                    drive->transfer_index + length);
779         return -1;
780     }
781
782
783
784     if ((data_offset == 0) && (drive->transfer_index > 0)) {
785         if (atapi_update_data_buf(dev, channel) == -1) {
786             PrintError("Could not update CDROM data buffer\n");
787             return -1;
788         }
789     }
790
791     memcpy(dst, drive->data_buf + data_offset, length);
792     
793     drive->transfer_index += length;
794
795
796     // Should the req_offset be recalculated here?????
797     if ((req_offset == 0) && (drive->transfer_index > 0)) {
798         if (drive->transfer_index < drive->transfer_length) {
799             // An increment is complete, but there is still more data to be transferred...
800             
801             channel->status.data_req = 1;
802
803             drive->irq_flags.c_d = 0;
804
805             // Update the request length in the cylinder regs
806             if (atapi_update_req_len(dev, channel, drive->transfer_length - drive->transfer_index) == -1) {
807                 PrintError("Could not update request length after completed increment\n");
808                 return -1;
809             }
810         } else {
811             // This was the final read of the request
812             channel->status.data_req = 0;
813             channel->status.ready = 1;
814             
815             drive->irq_flags.c_d = 1;
816             drive->irq_flags.rel = 0;
817         }
818
819         drive->irq_flags.io_dir = 1;
820         channel->status.busy = 0;
821
822         ide_raise_irq(dev, channel);
823     }
824
825     return length;
826 }
827
828
829 static int read_drive_id(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
830     struct ide_drive * drive = get_selected_drive(channel);
831
832     channel->status.busy = 0;
833     channel->status.ready = 1;
834     channel->status.write_fault = 0;
835     channel->status.seek_complete = 1;
836     channel->status.corrected = 0;
837     channel->status.error = 0;
838                 
839     
840     memcpy(dst, drive->data_buf + drive->transfer_index, length);
841     drive->transfer_index += length;
842     
843     if (drive->transfer_index >= drive->transfer_length) {
844         channel->status.data_req = 0;
845     }
846     
847     return length;
848 }
849
850
851 static int ide_read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
852     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
853     struct ide_channel * channel = get_selected_channel(ide, port);
854     struct ide_drive * drive = get_selected_drive(channel);
855
856     //    PrintDebug("IDE: Reading Data Port %x (len=%d)\n", port, length);
857
858     if ((channel->cmd_reg == 0xec) ||
859         (channel->cmd_reg == 0xa1)) {
860         return read_drive_id((uint8_t *)dst, length, dev, channel);
861     }
862
863     if (drive->drive_type == IDE_CDROM) {
864         if (read_cd_data((uint8_t *)dst, length, dev, channel) == -1) {
865             PrintError("IDE: Could not read CD Data\n");
866             return -1;
867         }
868     } else if (drive->drive_type == IDE_DISK) {
869         if (read_hd_data((uint8_t *)dst, length, dev, channel) == -1) {
870             PrintError("IDE: Could not read HD Data\n");
871             return -1;
872         }
873     } else {
874         memset((uint8_t *)dst, 0, length);
875     }
876
877     return length;
878 }
879
880 static int write_port_std(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
881     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
882     struct ide_channel * channel = get_selected_channel(ide, port);
883     struct ide_drive * drive = get_selected_drive(channel);
884             
885     if (length != 1) {
886         PrintError("Invalid Write length on IDE port %x\n", port);
887         return -1;
888     }
889
890     PrintDebug("IDE: Writing Standard Port %x (%s) (val=%x)\n", port, io_port_to_str(port), *(uint8_t *)src);
891
892     switch (port) {
893         // reset and interrupt enable
894         case PRI_CTRL_PORT:
895         case SEC_CTRL_PORT: {
896             struct ide_ctrl_reg * tmp_ctrl = (struct ide_ctrl_reg *)src;
897
898             // only reset channel on a 0->1 reset bit transition
899             if ((!channel->ctrl_reg.soft_reset) && (tmp_ctrl->soft_reset)) {
900                 channel_reset(channel);
901             } else if ((channel->ctrl_reg.soft_reset) && (!tmp_ctrl->soft_reset)) {
902                 channel_reset_complete(channel);
903             }
904
905             channel->ctrl_reg.val = tmp_ctrl->val;          
906             break;
907         }
908         case PRI_FEATURES_PORT:
909         case SEC_FEATURES_PORT:
910             channel->features.val = *(uint8_t *)src;
911             break;
912
913         case PRI_SECT_CNT_PORT:
914         case SEC_SECT_CNT_PORT:
915             channel->drives[0].sector_count = *(uint8_t *)src;
916             channel->drives[1].sector_count = *(uint8_t *)src;
917             break;
918
919         case PRI_SECT_NUM_PORT:
920         case SEC_SECT_NUM_PORT:
921             channel->drives[0].sector_num = *(uint8_t *)src;
922             channel->drives[1].sector_num = *(uint8_t *)src;
923             break;
924         case PRI_CYL_LOW_PORT:
925         case SEC_CYL_LOW_PORT:
926             channel->drives[0].cylinder_low = *(uint8_t *)src;
927             channel->drives[1].cylinder_low = *(uint8_t *)src;
928             break;
929
930         case PRI_CYL_HIGH_PORT:
931         case SEC_CYL_HIGH_PORT:
932             channel->drives[0].cylinder_high = *(uint8_t *)src;
933             channel->drives[1].cylinder_high = *(uint8_t *)src;
934             break;
935
936         case PRI_DRV_SEL_PORT:
937         case SEC_DRV_SEL_PORT: {
938             channel->drive_head.val = *(uint8_t *)src;
939             
940             // make sure the reserved bits are ok..
941             // JRL TODO: check with new ramdisk to make sure this is right...
942             channel->drive_head.val |= 0xa0;
943
944             drive = get_selected_drive(channel);
945
946             // Selecting a non-present device is a no-no
947             if (drive->drive_type == IDE_NONE) {
948                 PrintDebug("Attempting to select a non-present drive\n");
949                 channel->error_reg.abort = 1;
950                 channel->status.error = 1;
951             }
952
953             break;
954         }
955         default:
956             PrintError("IDE: Write to unknown Port %x\n", port);
957             return -1;
958     }
959     return length;
960 }
961
962
963 static int read_port_std(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
964     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
965     struct ide_channel * channel = get_selected_channel(ide, port);
966     struct ide_drive * drive = get_selected_drive(channel);
967     
968     if (length != 1) {
969         PrintError("Invalid Read length on IDE port %x\n", port);
970         return -1;
971     }
972     
973     PrintDebug("IDE: Reading Standard Port %x (%s)\n", port, io_port_to_str(port));
974
975     if ((port == PRI_ADDR_REG_PORT) ||
976         (port == SEC_ADDR_REG_PORT)) {
977         // unused, return 0xff
978         *(uint8_t *)dst = 0xff;
979         return length;
980     }
981
982
983     // if no drive is present just return 0 + reserved bits
984     if (drive->drive_type == IDE_NONE) {
985         if ((port == PRI_DRV_SEL_PORT) ||
986             (port == SEC_DRV_SEL_PORT)) {
987             *(uint8_t *)dst = 0xa0;
988         } else {
989             *(uint8_t *)dst = 0;
990         }
991
992         return length;
993     }
994
995     switch (port) {
996
997         // This is really the error register.
998         case PRI_FEATURES_PORT:
999         case SEC_FEATURES_PORT:
1000             *(uint8_t *)dst = channel->error_reg.val;
1001             break;
1002             
1003         case PRI_SECT_CNT_PORT:
1004         case SEC_SECT_CNT_PORT:
1005             *(uint8_t *)dst = drive->sector_count;
1006             break;
1007
1008         case PRI_SECT_NUM_PORT:
1009         case SEC_SECT_NUM_PORT:
1010             *(uint8_t *)dst = drive->sector_num;
1011             break;
1012
1013         case PRI_CYL_LOW_PORT:
1014         case SEC_CYL_LOW_PORT:
1015             *(uint8_t *)dst = drive->cylinder_low;
1016             break;
1017
1018
1019         case PRI_CYL_HIGH_PORT:
1020         case SEC_CYL_HIGH_PORT:
1021             *(uint8_t *)dst = drive->cylinder_high;
1022             break;
1023
1024         case PRI_DRV_SEL_PORT:
1025         case SEC_DRV_SEL_PORT:  // hard disk drive and head register 0x1f6
1026             *(uint8_t *)dst = channel->drive_head.val;
1027             break;
1028
1029         case PRI_CTRL_PORT:
1030         case SEC_CTRL_PORT:
1031         case PRI_CMD_PORT:
1032         case SEC_CMD_PORT:
1033             // Something about lowering interrupts here....
1034             *(uint8_t *)dst = channel->status.val;
1035             break;
1036
1037         default:
1038             PrintError("Invalid Port: %x\n", port);
1039             return -1;
1040     }
1041
1042     PrintDebug("\tVal=%x\n", *(uint8_t *)dst);
1043
1044     return length;
1045 }
1046
1047
1048
1049 static void init_drive(struct ide_drive * drive) {
1050
1051     drive->sector_count = 0x01;
1052     drive->sector_num = 0x01;
1053     drive->cylinder = 0x0000;
1054
1055     drive->drive_type = IDE_NONE;
1056
1057     memset(drive->model, 0, sizeof(drive->model));
1058
1059     drive->transfer_index = 0;
1060     drive->transfer_length = 0;
1061     memset(drive->data_buf, 0, sizeof(drive->data_buf));
1062
1063
1064     drive->private_data = NULL;
1065     drive->cd_ops = NULL;
1066 }
1067
1068 static void init_channel(struct ide_channel * channel) {
1069     int i = 0;
1070
1071     channel->error_reg.val = 0x01;
1072     channel->drive_head.val = 0x00;
1073     channel->status.val = 0x00;
1074     channel->cmd_reg = 0x00;
1075     channel->ctrl_reg.val = 0x08;
1076
1077
1078     channel->dma_cmd.val = 0;
1079     channel->dma_status.val = 0;
1080     channel->dma_prd_addr = 0;
1081     channel->dma_tbl_index = 0;
1082
1083     for (i = 0; i < 2; i++) {
1084         init_drive(&(channel->drives[i]));
1085     }
1086
1087 }
1088
1089
1090 static int pci_config_update(struct pci_device * pci_dev, uint_t reg_num, int length) {
1091     PrintDebug("Interupt register (Dev=%s), irq=%d\n", pci_dev->name, pci_dev->config_header.intr_line);
1092
1093     return 0;
1094 }
1095
1096 static int init_ide_state(struct vm_device * dev) {
1097     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1098     struct v3_pci_bar bars[6];
1099     struct pci_device * pci_dev = NULL;
1100     int i, j;
1101
1102     for (i = 0; i < 2; i++) {
1103         init_channel(&(ide->channels[i]));
1104
1105         // JRL: this is a terrible hack...
1106         ide->channels[i].irq = PRI_DEFAULT_IRQ + i;
1107
1108         for (j = 0; j < 6; j++) {
1109             bars[j].type = PCI_BAR_NONE;
1110         }
1111
1112
1113         bars[4].type = PCI_BAR_IO;
1114         bars[4].default_base_port = PRI_DEFAULT_DMA_PORT + (i * 0x8);
1115         bars[4].num_ports = 8;
1116         
1117         if (i == 0) {
1118             bars[4].io_read = read_pri_dma_port;
1119             bars[4].io_write = write_pri_dma_port;
1120         } else {
1121             bars[4].io_read = read_sec_dma_port;
1122             bars[4].io_write = write_sec_dma_port;
1123         }
1124
1125         pci_dev = v3_pci_register_device(ide->pci, PCI_STD_DEVICE, 0, "V3_IDE", -1, bars,
1126                                          pci_config_update, NULL, NULL, dev);
1127
1128         if (pci_dev == NULL) {
1129             PrintError("Failed to register IDE BUS %d with PCI\n", i); 
1130             return -1;
1131         }
1132
1133         ide->channels[i].pci_dev = pci_dev;
1134
1135         pci_dev->config_header.vendor_id = 0x1095;
1136         pci_dev->config_header.device_id = 0x0646;
1137         pci_dev->config_header.revision = 0x8f07;
1138         pci_dev->config_header.subclass = 0x01;
1139         pci_dev->config_header.class = 0x01;
1140
1141         pci_dev->config_header.intr_line = PRI_DEFAULT_IRQ + i;
1142         pci_dev->config_header.intr_pin = 1;
1143     }
1144
1145
1146
1147     /* Register PIIX3 Busmaster PCI device */
1148     for (j = 0; j < 6; j++) {
1149         bars[j].type = PCI_BAR_NONE;
1150     }
1151
1152     pci_dev = v3_pci_register_device(ide->pci, PCI_STD_DEVICE, 0, "PIIX3 IDE", -1, bars,
1153                                      NULL, NULL, NULL, dev);
1154     
1155     
1156     ide->busmaster_pci = pci_dev;
1157
1158     pci_dev->config_header.vendor_id = 0x8086;
1159     pci_dev->config_header.device_id = 0x7010;
1160     pci_dev->config_header.revision = 0x80;
1161     pci_dev->config_header.subclass = 0x01;
1162     pci_dev->config_header.class = 0x01;
1163
1164
1165     return 0;
1166 }
1167
1168
1169
1170 static int init_ide(struct vm_device * dev) {
1171     //struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1172
1173     PrintDebug("IDE: Initializing IDE\n");
1174
1175     if (init_ide_state(dev) == -1) {
1176         PrintError("Failed to initialize IDE state\n");
1177         return -1;
1178     }
1179
1180
1181     v3_dev_hook_io(dev, PRI_DATA_PORT, 
1182                    &ide_read_data_port, &write_data_port);
1183     v3_dev_hook_io(dev, PRI_FEATURES_PORT, 
1184                    &read_port_std, &write_port_std);
1185     v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, 
1186                    &read_port_std, &write_port_std);
1187     v3_dev_hook_io(dev, PRI_SECT_NUM_PORT, 
1188                    &read_port_std, &write_port_std);
1189     v3_dev_hook_io(dev, PRI_CYL_LOW_PORT, 
1190                    &read_port_std, &write_port_std);
1191     v3_dev_hook_io(dev, PRI_CYL_HIGH_PORT, 
1192                    &read_port_std, &write_port_std);
1193     v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, 
1194                    &read_port_std, &write_port_std);
1195     v3_dev_hook_io(dev, PRI_CMD_PORT, 
1196                    &read_port_std, &write_cmd_port);
1197
1198     v3_dev_hook_io(dev, SEC_DATA_PORT, 
1199                    &ide_read_data_port, &write_data_port);
1200     v3_dev_hook_io(dev, SEC_FEATURES_PORT, 
1201                    &read_port_std, &write_port_std);
1202     v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, 
1203                    &read_port_std, &write_port_std);
1204     v3_dev_hook_io(dev, SEC_SECT_NUM_PORT, 
1205                    &read_port_std, &write_port_std);
1206     v3_dev_hook_io(dev, SEC_CYL_LOW_PORT, 
1207                    &read_port_std, &write_port_std);
1208     v3_dev_hook_io(dev, SEC_CYL_HIGH_PORT, 
1209                    &read_port_std, &write_port_std);
1210     v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, 
1211                    &read_port_std, &write_port_std);
1212     v3_dev_hook_io(dev, SEC_CMD_PORT, 
1213                    &read_port_std, &write_cmd_port);
1214   
1215
1216     v3_dev_hook_io(dev, PRI_CTRL_PORT, 
1217                    &read_port_std, &write_port_std);
1218
1219     v3_dev_hook_io(dev, SEC_CTRL_PORT, 
1220                    &read_port_std, &write_port_std);
1221   
1222
1223     v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, 
1224                    &read_port_std, &write_port_std);
1225
1226     v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, 
1227                    &read_port_std, &write_port_std);
1228
1229     return 0;
1230 }
1231
1232
1233 static int deinit_ide(struct vm_device * dev) {
1234     // unhook io ports....
1235     // deregister from PCI?
1236     return 0;
1237 }
1238
1239
1240 static struct vm_device_ops dev_ops = {
1241     .init = init_ide,
1242     .deinit = deinit_ide,
1243     .reset = NULL,
1244     .start = NULL,
1245     .stop = NULL,
1246 };
1247
1248
1249 struct vm_device *  v3_create_ide(struct vm_device * pci) {
1250     struct ide_internal * ide  = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal));  
1251     struct vm_device * device = v3_create_device("IDE", &dev_ops, ide);
1252
1253     ide->pci = pci;
1254
1255     PrintDebug("IDE: Creating IDE bus x 2\n");
1256
1257     return device;
1258 }
1259
1260
1261
1262
1263
1264 int v3_ide_register_cdrom(struct vm_device * ide_dev, 
1265                           uint_t bus_num, 
1266                           uint_t drive_num,
1267                           char * dev_name, 
1268                           struct v3_ide_cd_ops * ops, 
1269                           void * private_data) {
1270
1271     struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
1272     struct ide_channel * channel = NULL;
1273     struct ide_drive * drive = NULL;
1274
1275     V3_ASSERT((bus_num >= 0) && (bus_num < 2));
1276     V3_ASSERT((drive_num >= 0) && (drive_num < 2));
1277
1278     channel = &(ide->channels[bus_num]);
1279     drive = &(channel->drives[drive_num]);
1280     
1281     if (drive->drive_type != IDE_NONE) {
1282         PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
1283         return -1;
1284     }
1285
1286     strncpy(drive->model, dev_name, sizeof(drive->model) - 1);
1287
1288     while (strlen((char *)(drive->model)) < 40) {
1289         strcat((char*)(drive->model), " ");
1290     }
1291
1292
1293     drive->drive_type = IDE_CDROM;
1294
1295     drive->cd_ops = ops;
1296
1297     drive->private_data = private_data;
1298
1299     return 0;
1300 }
1301
1302
1303 int v3_ide_register_harddisk(struct vm_device * ide_dev, 
1304                              uint_t bus_num, 
1305                              uint_t drive_num, 
1306                              char * dev_name, 
1307                              struct v3_ide_hd_ops * ops, 
1308                              void * private_data) {
1309
1310     struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
1311     struct ide_channel * channel = NULL;
1312     struct ide_drive * drive = NULL;
1313
1314     V3_ASSERT((bus_num >= 0) && (bus_num < 2));
1315     V3_ASSERT((drive_num >= 0) && (drive_num < 2));
1316
1317     channel = &(ide->channels[bus_num]);
1318     drive = &(channel->drives[drive_num]);
1319     
1320     if (drive->drive_type != IDE_NONE) {
1321         PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
1322         return -1;
1323     }
1324
1325     strncpy(drive->model, dev_name, sizeof(drive->model) - 1);
1326
1327     drive->drive_type = IDE_DISK;
1328
1329     drive->hd_state.accessed = 0;
1330
1331     drive->hd_ops = ops;
1332
1333     drive->private_data = private_data;
1334
1335     return 0;
1336 }
1337
1338
1339