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.


Update to the device framework.
[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 <devices/southbridge.h>
25 #include "ide-types.h"
26 #include "atapi-types.h"
27
28 #ifndef DEBUG_IDE
29 #undef PrintDebug
30 #define PrintDebug(fmt, args...)
31 #endif
32
33 #define PRI_DEFAULT_IRQ 14
34 #define SEC_DEFAULT_IRQ 15
35
36
37 #define PRI_DATA_PORT         0x1f0
38 #define PRI_FEATURES_PORT     0x1f1
39 #define PRI_SECT_CNT_PORT     0x1f2
40 #define PRI_SECT_NUM_PORT     0x1f3
41 #define PRI_CYL_LOW_PORT      0x1f4
42 #define PRI_CYL_HIGH_PORT     0x1f5
43 #define PRI_DRV_SEL_PORT      0x1f6
44 #define PRI_CMD_PORT          0x1f7
45 #define PRI_CTRL_PORT         0x3f6
46 #define PRI_ADDR_REG_PORT     0x3f7
47
48 #define SEC_DATA_PORT         0x170
49 #define SEC_FEATURES_PORT     0x171
50 #define SEC_SECT_CNT_PORT     0x172
51 #define SEC_SECT_NUM_PORT     0x173
52 #define SEC_CYL_LOW_PORT      0x174
53 #define SEC_CYL_HIGH_PORT     0x175
54 #define SEC_DRV_SEL_PORT      0x176
55 #define SEC_CMD_PORT          0x177
56 #define SEC_CTRL_PORT         0x376
57 #define SEC_ADDR_REG_PORT     0x377
58
59
60 #define PRI_DEFAULT_DMA_PORT 0xc000
61 #define SEC_DEFAULT_DMA_PORT 0xc008
62
63 #define DATA_BUFFER_SIZE 2048
64
65 static const char * ide_pri_port_strs[] = {"PRI_DATA", "PRI_FEATURES", "PRI_SECT_CNT", "PRI_SECT_NUM", 
66                                           "PRI_CYL_LOW", "PRI_CYL_HIGH", "PRI_DRV_SEL", "PRI_CMD",
67                                            "PRI_CTRL", "PRI_ADDR_REG"};
68
69
70 static const char * ide_sec_port_strs[] = {"SEC_DATA", "SEC_FEATURES", "SEC_SECT_CNT", "SEC_SECT_NUM", 
71                                           "SEC_CYL_LOW", "SEC_CYL_HIGH", "SEC_DRV_SEL", "SEC_CMD",
72                                            "SEC_CTRL", "SEC_ADDR_REG"};
73
74 static const char * ide_dma_port_strs[] = {"DMA_CMD", NULL, "DMA_STATUS", NULL,
75                                            "DMA_PRD0", "DMA_PRD1", "DMA_PRD2", "DMA_PRD3"};
76
77
78
79 static inline const char * io_port_to_str(uint16_t port) {
80     if ((port >= PRI_DATA_PORT) && (port <= PRI_CMD_PORT)) {
81         return ide_pri_port_strs[port - PRI_DATA_PORT];
82     } else if ((port >= SEC_DATA_PORT) && (port <= SEC_CMD_PORT)) {
83         return ide_sec_port_strs[port - SEC_DATA_PORT];
84     } else if ((port == PRI_CTRL_PORT) || (port == PRI_ADDR_REG_PORT)) {
85         return ide_pri_port_strs[port - PRI_CTRL_PORT + 8];
86     } else if ((port == SEC_CTRL_PORT) || (port == SEC_ADDR_REG_PORT)) {
87         return ide_sec_port_strs[port - SEC_CTRL_PORT + 8];
88     } 
89     return NULL;
90 }
91
92
93 static inline const char * dma_port_to_str(uint16_t port) {
94     return ide_dma_port_strs[port & 0x7];
95 }
96
97
98 static const char * ide_dev_type_strs[] = {"NONE", "HARDDISK", "CDROM" };
99
100
101 static inline const char * device_type_to_str(v3_ide_dev_type_t type) {
102     if (type > 2) {
103         return NULL;
104     }
105
106     return ide_dev_type_strs[type];
107 }
108
109
110
111 struct ide_cd_state {
112     struct atapi_sense_data sense;
113
114     uint8_t atapi_cmd;
115     struct atapi_error_recovery err_recovery;
116 };
117
118 struct ide_hd_state {
119     int accessed;
120
121     /* this is the multiple sector transfer size as configured for read/write multiple sectors*/
122     uint_t mult_sector_num;
123
124     /* This is the current op sector size:
125      * for multiple sector ops this equals mult_sector_num
126      * for standard ops this equals 1
127      */
128     uint_t cur_sector_num;
129 };
130
131 struct ide_drive {
132     // Command Registers
133
134     v3_ide_dev_type_t drive_type;
135
136     union {
137         struct v3_ide_cd_ops * cd_ops;
138         struct v3_ide_hd_ops * hd_ops;
139     };
140
141
142     union {
143         struct ide_cd_state cd_state;
144         struct ide_hd_state hd_state;
145     };
146
147     char model[41];
148
149     // Where we are in the data transfer
150     uint_t transfer_index;
151
152     // the length of a transfer
153     // calculated for easy access
154     uint_t transfer_length;
155
156     uint64_t current_lba;
157
158     // We have a local data buffer that we use for IO port accesses
159     uint8_t data_buf[DATA_BUFFER_SIZE];
160
161
162     uint32_t num_cylinders;
163     uint32_t num_heads;
164     uint32_t num_sectors;
165
166     void * private_data;
167     
168     union {
169         uint8_t sector_count;             // 0x1f2,0x172
170         struct atapi_irq_flags irq_flags;
171     } __attribute__((packed));
172
173     union {
174         uint8_t sector_num;               // 0x1f3,0x173
175         uint8_t lba0;
176     } __attribute__((packed));
177
178     union {
179         uint16_t cylinder;
180         uint16_t lba12;
181         
182         struct {
183             uint8_t cylinder_low;       // 0x1f4,0x174
184             uint8_t cylinder_high;      // 0x1f5,0x175
185         } __attribute__((packed));
186         
187         struct {
188             uint8_t lba1;
189             uint8_t lba2;
190         } __attribute__((packed));
191         
192         
193         // The transfer length requested by the CPU 
194         uint16_t req_len;
195     } __attribute__((packed));
196
197 };
198
199
200
201 struct ide_channel {
202     struct ide_drive drives[2];
203
204     // Command Registers
205     struct ide_error_reg error_reg;     // [read] 0x1f1,0x171
206
207     struct ide_features_reg features;
208
209     struct ide_drive_head_reg drive_head; // 0x1f6,0x176
210
211     struct ide_status_reg status;       // [read] 0x1f7,0x177
212     uint8_t cmd_reg;                // [write] 0x1f7,0x177
213
214     int irq; // this is temporary until we add PCI support
215
216     // Control Registers
217     struct ide_ctrl_reg ctrl_reg; // [write] 0x3f6,0x376
218
219     struct ide_dma_cmd_reg dma_cmd;
220     struct ide_dma_status_reg dma_status;
221     uint32_t dma_prd_addr;
222     uint_t dma_tbl_index;
223 };
224
225
226
227 struct ide_internal {
228     struct ide_channel channels[2];
229
230     struct v3_southbridge * southbridge;
231     struct vm_device * pci_bus;
232
233     struct pci_device * ide_pci;
234 };
235
236
237
238
239
240 /* Utility functions */
241
242 static inline uint16_t be_to_le_16(const uint16_t val) {
243     uint8_t * buf = (uint8_t *)&val;
244     return (buf[0] << 8) | (buf[1]) ;
245 }
246
247 static inline uint16_t le_to_be_16(const uint16_t val) {
248     return be_to_le_16(val);
249 }
250
251
252 static inline uint32_t be_to_le_32(const uint32_t val) {
253     uint8_t * buf = (uint8_t *)&val;
254     return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
255 }
256
257 static inline uint32_t le_to_be_32(const uint32_t val) {
258     return be_to_le_32(val);
259 }
260
261
262 static inline int get_channel_index(ushort_t port) {
263     if (((port & 0xfff8) == 0x1f0) ||
264         ((port & 0xfffe) == 0x3f6) || 
265         ((port & 0xfff8) == 0xc000)) {
266         return 0;
267     } else if (((port & 0xfff8) == 0x170) ||
268                ((port & 0xfffe) == 0x376) ||
269                ((port & 0xfff8) == 0xc008)) {
270         return 1;
271     }
272
273     return -1;
274 }
275
276 static inline struct ide_channel * get_selected_channel(struct ide_internal * ide, ushort_t port) {
277     int channel_idx = get_channel_index(port);    
278     return &(ide->channels[channel_idx]);
279 }
280
281 static inline struct ide_drive * get_selected_drive(struct ide_channel * channel) {
282     return &(channel->drives[channel->drive_head.drive_sel]);
283 }
284
285
286 static inline int is_lba_enabled(struct ide_channel * channel) {
287     return channel->drive_head.lba_mode;
288 }
289
290
291 /* Drive Commands */
292 static void ide_raise_irq(struct vm_device * dev, struct ide_channel * channel) {
293     if (channel->ctrl_reg.irq_disable == 0) {
294         PrintDebug("Raising IDE Interrupt %d\n", channel->irq);
295         channel->dma_status.int_gen = 1;
296         v3_raise_irq(dev->vm, channel->irq);
297     }
298 }
299
300
301 static void drive_reset(struct ide_drive * drive) {
302     drive->sector_count = 0x01;
303     drive->sector_num = 0x01;
304
305     PrintDebug("Resetting drive %s\n", drive->model);
306     
307     if (drive->drive_type == IDE_CDROM) {
308         drive->cylinder = 0xeb14;
309     } else {
310         drive->cylinder = 0x0000;
311         //drive->hd_state.accessed = 0;
312     }
313
314
315     memset(drive->data_buf, 0, sizeof(drive->data_buf));
316     drive->transfer_index = 0;
317
318     // Send the reset signal to the connected device callbacks
319     //     channel->drives[0].reset();
320     //    channel->drives[1].reset();
321 }
322
323 static void channel_reset(struct ide_channel * channel) {
324     
325     // set busy and seek complete flags
326     channel->status.val = 0x90;
327
328     // Clear errors
329     channel->error_reg.val = 0x01;
330
331     // clear commands
332     channel->cmd_reg = 0x00;
333
334     channel->ctrl_reg.irq_disable = 0;
335 }
336
337 static void channel_reset_complete(struct ide_channel * channel) {
338     channel->status.busy = 0;
339     channel->status.ready = 1;
340
341     channel->drive_head.head_num = 0;    
342     
343     drive_reset(&(channel->drives[0]));
344     drive_reset(&(channel->drives[1]));
345 }
346
347
348 static void ide_abort_command(struct vm_device * dev, struct ide_channel * channel) {
349     channel->status.val = 0x41; // Error + ready
350     channel->error_reg.val = 0x04; // No idea...
351
352     ide_raise_irq(dev, channel);
353 }
354
355
356 static int dma_read(struct vm_device * dev, struct ide_channel * channel);
357 static int dma_write(struct vm_device * dev, struct ide_channel * channel);
358
359
360 /* ATAPI functions */
361 #include "atapi.h"
362
363 /* ATA functions */
364 #include "ata.h"
365
366
367 #ifdef DEBUG_IDE
368 static void print_prd_table(struct vm_device * dev, struct ide_channel * channel) {
369     struct ide_dma_prd prd_entry;
370     int index = 0;
371
372     PrintDebug("Dumping PRD table\n");
373
374     while (1) {
375         uint32_t prd_entry_addr = channel->dma_prd_addr + (sizeof(struct ide_dma_prd) * index);
376         int ret;
377
378         ret = read_guest_pa_memory(dev->vm, prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry);
379         
380         if (ret != sizeof(struct ide_dma_prd)) {
381             PrintError("Could not read PRD\n");
382             return;
383         }
384
385         PrintDebug("\tPRD Addr: %x, PRD Len: %d, EOT: %d\n", 
386                    prd_entry.base_addr, prd_entry.size, prd_entry.end_of_table);
387
388         if (prd_entry.end_of_table) {
389             break;
390         }
391
392         index++;
393     }
394
395     return;
396 }
397 #endif
398
399 /* IO Operations */
400 static int dma_read(struct vm_device * dev, struct ide_channel * channel) {
401     struct ide_drive * drive = get_selected_drive(channel);
402     // This is at top level scope to do the EOT test at the end
403     struct ide_dma_prd prd_entry;
404     uint_t bytes_left = drive->transfer_length;
405
406     // Read in the data buffer....
407     // Read a sector/block at a time until the prd entry is full.
408
409 #ifdef DEBUG_IDE
410     print_prd_table(dev, channel);
411 #endif
412
413     PrintDebug("DMA read for %d bytes\n", bytes_left);
414
415     // Loop through the disk data
416     while (bytes_left > 0) {
417         uint32_t prd_entry_addr = channel->dma_prd_addr + (sizeof(struct ide_dma_prd) * channel->dma_tbl_index);
418         uint_t prd_bytes_left = 0;
419         uint_t prd_offset = 0;
420         int ret;
421
422         PrintDebug("PRD table address = %x\n", channel->dma_prd_addr);
423
424         ret = read_guest_pa_memory(dev->vm, prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry);
425
426         if (ret != sizeof(struct ide_dma_prd)) {
427             PrintError("Could not read PRD\n");
428             return -1;
429         }
430
431         PrintDebug("PRD Addr: %x, PRD Len: %d, EOT: %d\n", 
432                    prd_entry.base_addr, prd_entry.size, prd_entry.end_of_table);
433
434         // loop through the PRD data....
435
436         prd_bytes_left = prd_entry.size;
437
438
439         while (prd_bytes_left > 0) {
440             uint_t bytes_to_write = 0;
441
442             if (drive->drive_type == IDE_DISK) {
443                 bytes_to_write = (prd_bytes_left > IDE_SECTOR_SIZE) ? IDE_SECTOR_SIZE : prd_bytes_left;
444
445
446                 if (ata_read(dev, channel, drive->data_buf, 1) == -1) {
447                     PrintError("Failed to read next disk sector\n");
448                     return -1;
449                 }
450             } else if (drive->drive_type == IDE_CDROM) {
451                 if (atapi_cmd_is_data_op(drive->cd_state.atapi_cmd)) {
452                     bytes_to_write = (prd_bytes_left > ATAPI_BLOCK_SIZE) ? ATAPI_BLOCK_SIZE : prd_bytes_left;
453
454                     if (atapi_read_chunk(dev, channel) == -1) {
455                         PrintError("Failed to read next disk sector\n");
456                         return -1;
457                     }
458                 } else {
459                     PrintDebug("DMA of command packet\n");
460                     PrintError("How does this work???\n");
461                     return -1;
462                     bytes_to_write = (prd_bytes_left > bytes_left) ? bytes_left : prd_bytes_left;
463                     prd_bytes_left = bytes_to_write;
464                 }
465             }
466
467             PrintDebug("Writing DMA data to guest Memory ptr=%p, len=%d\n", 
468                        (void *)(addr_t)(prd_entry.base_addr + prd_offset), bytes_to_write);
469
470             drive->current_lba++;
471
472             ret = write_guest_pa_memory(dev->vm, prd_entry.base_addr + prd_offset, bytes_to_write, drive->data_buf); 
473
474             if (ret != bytes_to_write) {
475                 PrintError("Failed to copy data into guest memory... (ret=%d)\n", ret);
476                 return -1;
477             }
478
479             PrintDebug("\t DMA ret=%d, (prd_bytes_left=%d) (bytes_left=%d)\n", ret, prd_bytes_left, bytes_left);
480
481             drive->transfer_index += ret;
482             prd_bytes_left -= ret;
483             prd_offset += ret;
484             bytes_left -= ret;
485         }
486
487         channel->dma_tbl_index++;
488
489         if (drive->drive_type == IDE_DISK) {
490             if (drive->transfer_index % IDE_SECTOR_SIZE) {
491                 PrintError("We currently don't handle sectors that span PRD descriptors\n");
492                 return -1;
493             }
494         } else if (drive->drive_type == IDE_CDROM) {
495             if (atapi_cmd_is_data_op(drive->cd_state.atapi_cmd)) {
496                 if (drive->transfer_index % ATAPI_BLOCK_SIZE) {
497                     PrintError("We currently don't handle ATAPI BLOCKS that span PRD descriptors\n");
498                     PrintError("transfer_index=%d, transfer_length=%d\n", 
499                                drive->transfer_index, drive->transfer_length);
500                     return -1;
501                 }
502             }
503         }
504
505
506         if ((prd_entry.end_of_table == 1) && (bytes_left > 0)) {
507             PrintError("DMA table not large enough for data transfer...\n");
508             return -1;
509         }
510     }
511
512     /*
513       drive->irq_flags.io_dir = 1;
514       drive->irq_flags.c_d = 1;
515       drive->irq_flags.rel = 0;
516     */
517
518
519     // Update to the next PRD entry
520
521     // set DMA status
522
523     if (prd_entry.end_of_table) {
524         channel->status.busy = 0;
525         channel->status.ready = 1;
526         channel->status.data_req = 0;
527         channel->status.error = 0;
528         channel->status.seek_complete = 1;
529
530         channel->dma_status.active = 0;
531         channel->dma_status.err = 0;
532     }
533
534     ide_raise_irq(dev, channel);
535
536     return 0;
537 }
538
539
540 static int dma_write(struct vm_device * dev, struct ide_channel * channel) {
541     struct ide_drive * drive = get_selected_drive(channel);
542     // This is at top level scope to do the EOT test at the end
543     struct ide_dma_prd prd_entry;
544     uint_t bytes_left = drive->transfer_length;
545
546
547     PrintDebug("DMA write from %d bytes\n", bytes_left);
548
549     // Loop through disk data
550     while (bytes_left > 0) {
551         uint32_t prd_entry_addr = channel->dma_prd_addr + (sizeof(struct ide_dma_prd) * channel->dma_tbl_index);
552         uint_t prd_bytes_left = 0;
553         uint_t prd_offset = 0;
554         int ret;
555         
556         PrintDebug("PRD Table address = %x\n", channel->dma_prd_addr);
557
558         ret = read_guest_pa_memory(dev->vm, prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry);
559
560         if (ret != sizeof(struct ide_dma_prd)) {
561             PrintError("Could not read PRD\n");
562             return -1;
563         }
564
565         PrintDebug("PRD Addr: %x, PRD Len: %d, EOT: %d\n", 
566                    prd_entry.base_addr, prd_entry.size, prd_entry.end_of_table);
567
568         prd_bytes_left = prd_entry.size;
569
570         while (prd_bytes_left > 0) {
571             uint_t bytes_to_write = 0;
572
573
574             bytes_to_write = (prd_bytes_left > IDE_SECTOR_SIZE) ? IDE_SECTOR_SIZE : prd_bytes_left;
575
576
577             ret = read_guest_pa_memory(dev->vm, prd_entry.base_addr + prd_offset, bytes_to_write, drive->data_buf);
578
579             if (ret != bytes_to_write) {
580                 PrintError("Faild to copy data from guest memory... (ret=%d)\n", ret);
581                 return -1;
582             }
583
584             PrintDebug("\t DMA ret=%d (prd_bytes_left=%d) (bytes_left=%d)\n", ret, prd_bytes_left, bytes_left);
585
586
587             if (ata_write(dev, channel, drive->data_buf, 1) == -1) {
588                 PrintError("Failed to write data to disk\n");
589                 return -1;
590             }
591             
592             drive->current_lba++;
593
594             drive->transfer_index += ret;
595             prd_bytes_left -= ret;
596             prd_offset += ret;
597             bytes_left -= ret;
598         }
599
600         channel->dma_tbl_index++;
601
602         if (drive->transfer_index % IDE_SECTOR_SIZE) {
603             PrintError("We currently don't handle sectors that span PRD descriptors\n");
604             return -1;
605         }
606
607         if ((prd_entry.end_of_table == 1) && (bytes_left > 0)) {
608             PrintError("DMA table not large enough for data transfer...\n");
609             return -1;
610         }
611     }
612
613     if (prd_entry.end_of_table) {
614         channel->status.busy = 0;
615         channel->status.ready = 1;
616         channel->status.data_req = 0;
617         channel->status.error = 0;
618         channel->status.seek_complete = 1;
619
620         channel->dma_status.active = 0;
621         channel->dma_status.err = 0;
622     }
623
624     ide_raise_irq(dev, channel);
625
626     return 0;
627 }
628
629
630
631 #define DMA_CMD_PORT      0x00
632 #define DMA_STATUS_PORT   0x02
633 #define DMA_PRD_PORT0     0x04
634 #define DMA_PRD_PORT1     0x05
635 #define DMA_PRD_PORT2     0x06
636 #define DMA_PRD_PORT3     0x07
637
638 #define DMA_CHANNEL_FLAG  0x08
639
640 static int write_dma_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
641     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
642     uint16_t port_offset = port & (DMA_CHANNEL_FLAG - 1);
643     uint_t channel_flag = (port & DMA_CHANNEL_FLAG) >> 3;
644     struct ide_channel * channel = &(ide->channels[channel_flag]);
645
646     PrintDebug("IDE: Writing DMA Port %x (%s) (val=%x) (len=%d) (channel=%d)\n", 
647                port, dma_port_to_str(port_offset), *(uint32_t *)src, length, channel_flag);
648
649     switch (port_offset) {
650         case DMA_CMD_PORT:
651             channel->dma_cmd.val = *(uint8_t *)src;
652
653             if (channel->dma_cmd.start == 0) {
654                 channel->dma_tbl_index = 0;
655             } else {
656                 channel->dma_status.active = 1;
657
658                 if (channel->dma_cmd.read == 1) {
659                     // DMA Read
660                     if (dma_read(dev, channel) == -1) {
661                         PrintError("Failed DMA Read\n");
662                         return -1;
663                     }
664                 } else {
665                     // DMA write
666                     if (dma_write(dev, channel) == -1) {
667                         PrintError("Failed DMA Write\n");
668                         return -1;
669                     }
670                 }
671
672                 channel->dma_cmd.val &= 0x09;
673             }
674
675             break;
676             
677         case DMA_STATUS_PORT: {
678             uint8_t val = *(uint8_t *)src;
679
680             if (length != 1) {
681                 PrintError("Invalid read length for DMA status port\n");
682                 return -1;
683             }
684
685             // weirdness
686             channel->dma_status.val = ((val & 0x60) | 
687                                        (channel->dma_status.val & 0x01) |
688                                        (channel->dma_status.val & ~val & 0x06));
689
690             break;
691         }           
692         case DMA_PRD_PORT0:
693         case DMA_PRD_PORT1:
694         case DMA_PRD_PORT2:
695         case DMA_PRD_PORT3: {
696             uint_t addr_index = port_offset & 0x3;
697             uint8_t * addr_buf = (uint8_t *)&(channel->dma_prd_addr);
698             int i = 0;
699
700             if (addr_index + length > 4) {
701                 PrintError("DMA Port space overrun port=%x len=%d\n", port_offset, length);
702                 return -1;
703             }
704
705             for (i = 0; i < length; i++) {
706                 addr_buf[addr_index + i] = *((uint8_t *)src + i);
707             }
708
709             PrintDebug("Writing PRD Port %x (val=%x)\n", port_offset, channel->dma_prd_addr);
710
711             break;
712         }
713         default:
714             PrintError("IDE: Invalid DMA Port (%s)\n", dma_port_to_str(port_offset));
715             return -1;
716     }
717
718     return length;
719 }
720
721
722 static int read_dma_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
723     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
724     uint16_t port_offset = port & (DMA_CHANNEL_FLAG - 1);
725     uint_t channel_flag = (port & DMA_CHANNEL_FLAG) >> 3;
726     struct ide_channel * channel = &(ide->channels[channel_flag]);
727
728     PrintDebug("Reading DMA port %d (%x) (channel=%d)\n", port, port, channel_flag);
729
730     switch (port_offset) {
731         case DMA_CMD_PORT:
732             *(uint8_t *)dst = channel->dma_cmd.val;
733             break;
734
735         case DMA_STATUS_PORT:
736             if (length != 1) {
737                 PrintError("Invalid read length for DMA status port\n");
738                 return -1;
739             }
740
741             *(uint8_t *)dst = channel->dma_status.val;
742             break;
743
744         case DMA_PRD_PORT0:
745         case DMA_PRD_PORT1:
746         case DMA_PRD_PORT2:
747         case DMA_PRD_PORT3: {
748             uint_t addr_index = port_offset & 0x3;
749             uint8_t * addr_buf = (uint8_t *)&(channel->dma_prd_addr);
750             int i = 0;
751
752             if (addr_index + length > 4) {
753                 PrintError("DMA Port space overrun port=%x len=%d\n", port_offset, length);
754                 return -1;
755             }
756
757             for (i = 0; i < length; i++) {
758                 *((uint8_t *)dst + i) = addr_buf[addr_index + i];
759             }
760
761             break;
762         }
763         default:
764             PrintError("IDE: Invalid DMA Port (%s)\n", dma_port_to_str(port_offset));
765             return -1;
766     }
767
768     PrintDebug("\tval=%x (len=%d)\n", *(uint32_t *)dst, length);
769
770     return length;
771 }
772
773
774
775 static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
776     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
777     struct ide_channel * channel = get_selected_channel(ide, port);
778     struct ide_drive * drive = get_selected_drive(channel);
779
780     if (length != 1) {
781         PrintError("Invalid Write Length on IDE command Port %x\n", port);
782         return -1;
783     }
784
785     PrintDebug("IDE: Writing Command Port %x (%s) (val=%x)\n", port, io_port_to_str(port), *(uint8_t *)src);
786     
787     channel->cmd_reg = *(uint8_t *)src;
788     
789     switch (channel->cmd_reg) {
790
791         case 0xa1: // ATAPI Identify Device Packet
792             if (drive->drive_type != IDE_CDROM) {
793                 drive_reset(drive);
794
795                 // JRL: Should we abort here?
796                 ide_abort_command(dev, channel);
797             } else {
798                 
799                 atapi_identify_device(drive);
800                 
801                 channel->error_reg.val = 0;
802                 channel->status.val = 0x58; // ready, data_req, seek_complete
803             
804                 ide_raise_irq(dev, channel);
805             }
806             break;
807         case 0xec: // Identify Device
808             if (drive->drive_type != IDE_DISK) {
809                 drive_reset(drive);
810
811                 // JRL: Should we abort here?
812                 ide_abort_command(dev, channel);
813             } else {
814                 ata_identify_device(drive);
815
816                 channel->error_reg.val = 0;
817                 channel->status.val = 0x58;
818
819                 ide_raise_irq(dev, channel);
820             }
821             break;
822
823         case 0xa0: // ATAPI Command Packet
824             if (drive->drive_type != IDE_CDROM) {
825                 ide_abort_command(dev, channel);
826             }
827             
828             drive->sector_count = 1;
829
830             channel->status.busy = 0;
831             channel->status.write_fault = 0;
832             channel->status.data_req = 1;
833             channel->status.error = 0;
834
835             // reset the data buffer...
836             drive->transfer_length = ATAPI_PACKET_SIZE;
837             drive->transfer_index = 0;
838
839             break;
840
841         case 0x20: // Read Sectors with Retry
842         case 0x21: // Read Sectors without Retry
843             drive->hd_state.cur_sector_num = 1;
844
845             if (ata_read_sectors(dev, channel) == -1) {
846                 PrintError("Error reading sectors\n");
847                 return -1;
848             }
849             break;
850
851         case 0x24: // Read Sectors Extended
852             drive->hd_state.cur_sector_num = 1;
853
854             if (ata_read_sectors_ext(dev, channel) == -1) {
855                 PrintError("Error reading extended sectors\n");
856                 return -1;
857             }
858             break;
859
860         case 0xc8: // Read DMA with retry
861         case 0xc9: { // Read DMA
862             uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
863
864             if (ata_get_lba(dev, channel, &(drive->current_lba)) == -1) {
865                 ide_abort_command(dev, channel);
866                 return 0;
867             }
868             
869             drive->hd_state.cur_sector_num = 1;
870             
871             drive->transfer_length = sect_cnt * IDE_SECTOR_SIZE;
872             drive->transfer_index = 0;
873
874             if (channel->dma_status.active == 1) {
875                 // DMA Read
876                 if (dma_read(dev, channel) == -1) {
877                     PrintError("Failed DMA Read\n");
878                     return -1;
879                 }
880             }
881             break;
882         }
883
884         case 0xca: { // Write DMA
885             uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
886
887             if (ata_get_lba(dev, channel, &(drive->current_lba)) == -1) {
888                 ide_abort_command(dev, channel);
889                 return 0;
890             }
891
892             drive->hd_state.cur_sector_num = 1;
893
894             drive->transfer_length = sect_cnt * IDE_SECTOR_SIZE;
895             drive->transfer_index = 0;
896
897             if (channel->dma_status.active == 1) {
898                 // DMA Write
899                 if (dma_write(dev, channel) == -1) {
900                     PrintError("Failed DMA Write\n");
901                     return -1;
902                 }
903             }
904             break;
905         }
906         case 0xe0: // Standby Now 1
907         case 0xe1: // Set Idle Immediate
908         case 0xe2: // Standby
909         case 0xe3: // Set Idle 1
910         case 0xe6: // Sleep Now 1
911         case 0x94: // Standby Now 2
912         case 0x95: // Idle Immediate (CFA)
913         case 0x96: // Standby 2
914         case 0x97: // Set idle 2
915         case 0x99: // Sleep Now 2
916             channel->status.val = 0;
917             channel->status.ready = 1;
918             ide_raise_irq(dev, channel);
919             break;
920
921         case 0xef: // Set Features
922             // Prior to this the features register has been written to. 
923             // This command tells the drive to check if the new value is supported (the value is drive specific)
924             // Common is that bit0=DMA enable
925             // If valid the drive raises an interrupt, if not it aborts.
926
927             // Do some checking here...
928
929             channel->status.busy = 0;
930             channel->status.write_fault = 0;
931             channel->status.error = 0;
932             channel->status.ready = 1;
933             channel->status.seek_complete = 1;
934             
935             ide_raise_irq(dev, channel);
936             break;
937
938         case 0x91:  // Initialize Drive Parameters
939         case 0x10:  // recalibrate?
940             channel->status.error = 0;
941             channel->status.ready = 1;
942             channel->status.seek_complete = 1;
943             ide_raise_irq(dev, channel);
944             break;
945         case 0xc6: { // Set multiple mode (IDE Block mode) 
946             // This makes the drive transfer multiple sectors before generating an interrupt
947             uint32_t tmp_sect_num = drive->sector_num; // GCC SUCKS
948
949             if (tmp_sect_num > MAX_MULT_SECTORS) {
950                 ide_abort_command(dev, channel);
951                 break;
952             }
953
954             if (drive->sector_count == 0) {
955                 drive->hd_state.mult_sector_num= 1;
956             } else {
957                 drive->hd_state.mult_sector_num = drive->sector_count;
958             }
959
960             channel->status.ready = 1;
961             channel->status.error = 0;
962
963             ide_raise_irq(dev, channel);
964
965             break;
966         }
967         case 0xc4:  // read multiple sectors
968             drive->hd_state.cur_sector_num = drive->hd_state.mult_sector_num;
969         default:
970             PrintError("Unimplemented IDE command (%x)\n", channel->cmd_reg);
971             return -1;
972     }
973
974     return length;
975 }
976
977
978 static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
979     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
980     struct ide_channel * channel = get_selected_channel(ide, port);
981     struct ide_drive * drive = get_selected_drive(channel);
982
983     //    PrintDebug("IDE: Writing Data Port %x (val=%x, len=%d)\n", 
984     //         port, *(uint32_t *)src, length);
985     
986     memcpy(drive->data_buf + drive->transfer_index, src, length);    
987     drive->transfer_index += length;
988
989     // Transfer is complete, dispatch the command
990     if (drive->transfer_index >= drive->transfer_length) {
991         switch (channel->cmd_reg) {
992             case 0x30: // Write Sectors
993                 PrintError("Writing Data not yet implemented\n");
994                 return -1;
995                 
996             case 0xa0: // ATAPI packet command
997                 if (atapi_handle_packet(dev, channel) == -1) {
998                     PrintError("Error handling ATAPI packet\n");
999                     return -1;
1000                 }
1001                 break;
1002             default:
1003                 PrintError("Unhandld IDE Command %x\n", channel->cmd_reg);
1004                 return -1;
1005         }
1006     }
1007
1008     return length;
1009 }
1010
1011
1012 static int read_hd_data(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
1013     struct ide_drive * drive = get_selected_drive(channel);
1014     int data_offset = drive->transfer_index % IDE_SECTOR_SIZE;
1015
1016
1017
1018     if (drive->transfer_index >= drive->transfer_length) {
1019         PrintError("Buffer overrun... (xfer_len=%d) (cur_idx=%x) (post_idx=%d)\n",
1020                    drive->transfer_length, drive->transfer_index,
1021                    drive->transfer_index + length);
1022         return -1;
1023     }
1024
1025     
1026     if ((data_offset == 0) && (drive->transfer_index > 0)) {
1027         drive->current_lba++;
1028
1029         if (ata_read(dev, channel, drive->data_buf, 1) == -1) {
1030             PrintError("Could not read next disk sector\n");
1031             return -1;
1032         }
1033     }
1034
1035     /*
1036       PrintDebug("Reading HD Data (Val=%x), (len=%d) (offset=%d)\n", 
1037       *(uint32_t *)(drive->data_buf + data_offset), 
1038       length, data_offset);
1039     */
1040     memcpy(dst, drive->data_buf + data_offset, length);
1041
1042     drive->transfer_index += length;
1043
1044
1045     /* This is the trigger for interrupt injection.
1046      * For read single sector commands we interrupt after every sector
1047      * For multi sector reads we interrupt only at end of the cluster size (mult_sector_num)
1048      * cur_sector_num is configured depending on the operation we are currently running
1049      * We also trigger an interrupt if this is the last byte to transfer, regardless of sector count
1050      */
1051     if (((drive->transfer_index % (IDE_SECTOR_SIZE * drive->hd_state.cur_sector_num)) == 0) || 
1052         (drive->transfer_index == drive->transfer_length)) {
1053         if (drive->transfer_index < drive->transfer_length) {
1054             // An increment is complete, but there is still more data to be transferred...
1055             PrintDebug("Integral Complete, still transferring more sectors\n");
1056             channel->status.data_req = 1;
1057
1058             drive->irq_flags.c_d = 0;
1059         } else {
1060             PrintDebug("Final Sector Transferred\n");
1061             // This was the final read of the request
1062             channel->status.data_req = 0;
1063
1064             
1065             drive->irq_flags.c_d = 1;
1066             drive->irq_flags.rel = 0;
1067         }
1068
1069         channel->status.ready = 1;
1070         drive->irq_flags.io_dir = 1;
1071         channel->status.busy = 0;
1072
1073         ide_raise_irq(dev, channel);
1074     }
1075
1076
1077     return length;
1078 }
1079
1080
1081
1082 static int read_cd_data(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
1083     struct ide_drive * drive = get_selected_drive(channel);
1084     int data_offset = drive->transfer_index % ATAPI_BLOCK_SIZE;
1085     int req_offset = drive->transfer_index % drive->req_len;
1086     
1087     if (drive->cd_state.atapi_cmd != 0x28) {
1088         PrintDebug("IDE: Reading CD Data (len=%d) (req_len=%d)\n", length, drive->req_len);
1089     }
1090
1091     if (drive->transfer_index >= drive->transfer_length) {
1092         PrintError("Buffer Overrun... (xfer_len=%d) (cur_idx=%d) (post_idx=%d)\n", 
1093                    drive->transfer_length, drive->transfer_index, 
1094                    drive->transfer_index + length);
1095         return -1;
1096     }
1097
1098     
1099     if ((data_offset == 0) && (drive->transfer_index > 0)) {
1100         if (atapi_update_data_buf(dev, channel) == -1) {
1101             PrintError("Could not update CDROM data buffer\n");
1102             return -1;
1103         }
1104     }
1105
1106     memcpy(dst, drive->data_buf + data_offset, length);
1107     
1108     drive->transfer_index += length;
1109
1110
1111     // Should the req_offset be recalculated here?????
1112     if ((req_offset == 0) && (drive->transfer_index > 0)) {
1113         if (drive->transfer_index < drive->transfer_length) {
1114             // An increment is complete, but there is still more data to be transferred...
1115             
1116             channel->status.data_req = 1;
1117
1118             drive->irq_flags.c_d = 0;
1119
1120             // Update the request length in the cylinder regs
1121             if (atapi_update_req_len(dev, channel, drive->transfer_length - drive->transfer_index) == -1) {
1122                 PrintError("Could not update request length after completed increment\n");
1123                 return -1;
1124             }
1125         } else {
1126             // This was the final read of the request
1127             channel->status.data_req = 0;
1128             channel->status.ready = 1;
1129             
1130             drive->irq_flags.c_d = 1;
1131             drive->irq_flags.rel = 0;
1132         }
1133
1134         drive->irq_flags.io_dir = 1;
1135         channel->status.busy = 0;
1136
1137         ide_raise_irq(dev, channel);
1138     }
1139
1140     return length;
1141 }
1142
1143
1144 static int read_drive_id(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
1145     struct ide_drive * drive = get_selected_drive(channel);
1146
1147     channel->status.busy = 0;
1148     channel->status.ready = 1;
1149     channel->status.write_fault = 0;
1150     channel->status.seek_complete = 1;
1151     channel->status.corrected = 0;
1152     channel->status.error = 0;
1153                 
1154     
1155     memcpy(dst, drive->data_buf + drive->transfer_index, length);
1156     drive->transfer_index += length;
1157     
1158     if (drive->transfer_index >= drive->transfer_length) {
1159         channel->status.data_req = 0;
1160     }
1161     
1162     return length;
1163 }
1164
1165
1166 static int ide_read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
1167     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1168     struct ide_channel * channel = get_selected_channel(ide, port);
1169     struct ide_drive * drive = get_selected_drive(channel);
1170
1171     //    PrintDebug("IDE: Reading Data Port %x (len=%d)\n", port, length);
1172
1173     if ((channel->cmd_reg == 0xec) ||
1174         (channel->cmd_reg == 0xa1)) {
1175         return read_drive_id((uint8_t *)dst, length, dev, channel);
1176     }
1177
1178     if (drive->drive_type == IDE_CDROM) {
1179         if (read_cd_data((uint8_t *)dst, length, dev, channel) == -1) {
1180             PrintError("IDE: Could not read CD Data\n");
1181             return -1;
1182         }
1183     } else if (drive->drive_type == IDE_DISK) {
1184         if (read_hd_data((uint8_t *)dst, length, dev, channel) == -1) {
1185             PrintError("IDE: Could not read HD Data\n");
1186             return -1;
1187         }
1188     } else {
1189         memset((uint8_t *)dst, 0, length);
1190     }
1191
1192     return length;
1193 }
1194
1195 static int write_port_std(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
1196     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1197     struct ide_channel * channel = get_selected_channel(ide, port);
1198     struct ide_drive * drive = get_selected_drive(channel);
1199             
1200     if (length != 1) {
1201         PrintError("Invalid Write length on IDE port %x\n", port);
1202         return -1;
1203     }
1204
1205     PrintDebug("IDE: Writing Standard Port %x (%s) (val=%x)\n", port, io_port_to_str(port), *(uint8_t *)src);
1206
1207     switch (port) {
1208         // reset and interrupt enable
1209         case PRI_CTRL_PORT:
1210         case SEC_CTRL_PORT: {
1211             struct ide_ctrl_reg * tmp_ctrl = (struct ide_ctrl_reg *)src;
1212
1213             // only reset channel on a 0->1 reset bit transition
1214             if ((!channel->ctrl_reg.soft_reset) && (tmp_ctrl->soft_reset)) {
1215                 channel_reset(channel);
1216             } else if ((channel->ctrl_reg.soft_reset) && (!tmp_ctrl->soft_reset)) {
1217                 channel_reset_complete(channel);
1218             }
1219
1220             channel->ctrl_reg.val = tmp_ctrl->val;          
1221             break;
1222         }
1223         case PRI_FEATURES_PORT:
1224         case SEC_FEATURES_PORT:
1225             channel->features.val = *(uint8_t *)src;
1226             break;
1227
1228         case PRI_SECT_CNT_PORT:
1229         case SEC_SECT_CNT_PORT:
1230             channel->drives[0].sector_count = *(uint8_t *)src;
1231             channel->drives[1].sector_count = *(uint8_t *)src;
1232             break;
1233
1234         case PRI_SECT_NUM_PORT:
1235         case SEC_SECT_NUM_PORT:
1236             channel->drives[0].sector_num = *(uint8_t *)src;
1237             channel->drives[1].sector_num = *(uint8_t *)src;
1238             break;
1239         case PRI_CYL_LOW_PORT:
1240         case SEC_CYL_LOW_PORT:
1241             channel->drives[0].cylinder_low = *(uint8_t *)src;
1242             channel->drives[1].cylinder_low = *(uint8_t *)src;
1243             break;
1244
1245         case PRI_CYL_HIGH_PORT:
1246         case SEC_CYL_HIGH_PORT:
1247             channel->drives[0].cylinder_high = *(uint8_t *)src;
1248             channel->drives[1].cylinder_high = *(uint8_t *)src;
1249             break;
1250
1251         case PRI_DRV_SEL_PORT:
1252         case SEC_DRV_SEL_PORT: {
1253             channel->drive_head.val = *(uint8_t *)src;
1254             
1255             // make sure the reserved bits are ok..
1256             // JRL TODO: check with new ramdisk to make sure this is right...
1257             channel->drive_head.val |= 0xa0;
1258
1259             drive = get_selected_drive(channel);
1260
1261             // Selecting a non-present device is a no-no
1262             if (drive->drive_type == IDE_NONE) {
1263                 PrintDebug("Attempting to select a non-present drive\n");
1264                 channel->error_reg.abort = 1;
1265                 channel->status.error = 1;
1266             }
1267
1268             break;
1269         }
1270         default:
1271             PrintError("IDE: Write to unknown Port %x\n", port);
1272             return -1;
1273     }
1274     return length;
1275 }
1276
1277
1278 static int read_port_std(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
1279     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1280     struct ide_channel * channel = get_selected_channel(ide, port);
1281     struct ide_drive * drive = get_selected_drive(channel);
1282     
1283     if (length != 1) {
1284         PrintError("Invalid Read length on IDE port %x\n", port);
1285         return -1;
1286     }
1287     
1288     PrintDebug("IDE: Reading Standard Port %x (%s)\n", port, io_port_to_str(port));
1289
1290     if ((port == PRI_ADDR_REG_PORT) ||
1291         (port == SEC_ADDR_REG_PORT)) {
1292         // unused, return 0xff
1293         *(uint8_t *)dst = 0xff;
1294         return length;
1295     }
1296
1297
1298     // if no drive is present just return 0 + reserved bits
1299     if (drive->drive_type == IDE_NONE) {
1300         if ((port == PRI_DRV_SEL_PORT) ||
1301             (port == SEC_DRV_SEL_PORT)) {
1302             *(uint8_t *)dst = 0xa0;
1303         } else {
1304             *(uint8_t *)dst = 0;
1305         }
1306
1307         return length;
1308     }
1309
1310     switch (port) {
1311
1312         // This is really the error register.
1313         case PRI_FEATURES_PORT:
1314         case SEC_FEATURES_PORT:
1315             *(uint8_t *)dst = channel->error_reg.val;
1316             break;
1317             
1318         case PRI_SECT_CNT_PORT:
1319         case SEC_SECT_CNT_PORT:
1320             *(uint8_t *)dst = drive->sector_count;
1321             break;
1322
1323         case PRI_SECT_NUM_PORT:
1324         case SEC_SECT_NUM_PORT:
1325             *(uint8_t *)dst = drive->sector_num;
1326             break;
1327
1328         case PRI_CYL_LOW_PORT:
1329         case SEC_CYL_LOW_PORT:
1330             *(uint8_t *)dst = drive->cylinder_low;
1331             break;
1332
1333
1334         case PRI_CYL_HIGH_PORT:
1335         case SEC_CYL_HIGH_PORT:
1336             *(uint8_t *)dst = drive->cylinder_high;
1337             break;
1338
1339         case PRI_DRV_SEL_PORT:
1340         case SEC_DRV_SEL_PORT:  // hard disk drive and head register 0x1f6
1341             *(uint8_t *)dst = channel->drive_head.val;
1342             break;
1343
1344         case PRI_CTRL_PORT:
1345         case SEC_CTRL_PORT:
1346         case PRI_CMD_PORT:
1347         case SEC_CMD_PORT:
1348             // Something about lowering interrupts here....
1349             *(uint8_t *)dst = channel->status.val;
1350             break;
1351
1352         default:
1353             PrintError("Invalid Port: %x\n", port);
1354             return -1;
1355     }
1356
1357     PrintDebug("\tVal=%x\n", *(uint8_t *)dst);
1358
1359     return length;
1360 }
1361
1362
1363
1364 static void init_drive(struct ide_drive * drive) {
1365
1366     drive->sector_count = 0x01;
1367     drive->sector_num = 0x01;
1368     drive->cylinder = 0x0000;
1369
1370     drive->drive_type = IDE_NONE;
1371
1372     memset(drive->model, 0, sizeof(drive->model));
1373
1374     drive->transfer_index = 0;
1375     drive->transfer_length = 0;
1376     memset(drive->data_buf, 0, sizeof(drive->data_buf));
1377
1378     drive->num_cylinders = 0;
1379     drive->num_heads = 0;
1380     drive->num_sectors = 0;
1381     
1382
1383     drive->private_data = NULL;
1384     drive->cd_ops = NULL;
1385 }
1386
1387 static void init_channel(struct ide_channel * channel) {
1388     int i = 0;
1389
1390     channel->error_reg.val = 0x01;
1391     channel->drive_head.val = 0x00;
1392     channel->status.val = 0x00;
1393     channel->cmd_reg = 0x00;
1394     channel->ctrl_reg.val = 0x08;
1395
1396
1397     channel->dma_cmd.val = 0;
1398     channel->dma_status.val = 0;
1399     channel->dma_prd_addr = 0;
1400     channel->dma_tbl_index = 0;
1401
1402     for (i = 0; i < 2; i++) {
1403         init_drive(&(channel->drives[i]));
1404     }
1405
1406 }
1407
1408
1409 static int pci_config_update(struct pci_device * pci_dev, uint_t reg_num, int length) {
1410     PrintDebug("PCI Config Update\n");
1411     PrintDebug("\t\tInterupt register (Dev=%s), irq=%d\n", pci_dev->name, pci_dev->config_header.intr_line);
1412
1413     return 0;
1414 }
1415
1416 static int init_ide_state(struct vm_device * dev) {
1417     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1418     int i;
1419
1420     /* 
1421      * Check if the PIIX 3 actually represents both IDE channels in a single PCI entry 
1422      */
1423
1424     for (i = 0; i < 1; i++) {
1425         init_channel(&(ide->channels[i]));
1426
1427         // JRL: this is a terrible hack...
1428         ide->channels[i].irq = PRI_DEFAULT_IRQ + i;
1429     }
1430
1431
1432     return 0;
1433 }
1434
1435
1436
1437
1438 static int ide_free(struct vm_device * dev) {
1439     // unhook io ports....
1440     // deregister from PCI?
1441     return 0;
1442 }
1443
1444
1445 static struct v3_device_ops dev_ops = {
1446     .free = ide_free,
1447     .reset = NULL,
1448     .start = NULL,
1449     .stop = NULL,
1450 };
1451
1452
1453
1454 static int ide_init(struct guest_info * vm, void * cfg_data) {
1455     struct ide_internal * ide  = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal));  
1456     struct ide_cfg * cfg = (struct ide_cfg *)(cfg_data);
1457     
1458     PrintDebug("IDE: Initializing IDE\n");
1459     memset(ide, 0, sizeof(struct ide_internal));
1460
1461
1462     if (cfg->pci != NULL) {
1463         if (cfg->southbridge == NULL) {
1464             PrintError("PCI Enabled BUT southbridge is NULL\n");
1465             return -1;
1466         }
1467
1468         ide->pci_bus = v3_find_dev(vm, (char *)cfg->pci);
1469         
1470         if (ide->pci_bus == NULL) {
1471             PrintError("Could not find PCI device\n");
1472             return -1;
1473         }
1474
1475         struct vm_device * southbridge = v3_find_dev(vm, cfg->southbridge);
1476
1477         if (!southbridge) {
1478             PrintError("Could not find southbridge\n");
1479             return -1;
1480         }
1481
1482         ide->southbridge = (struct v3_southbridge *)(southbridge->private_data);
1483     }
1484
1485
1486     PrintDebug("IDE: Creating IDE bus x 2\n");
1487
1488     struct vm_device * dev = v3_allocate_device("IDE", &dev_ops, ide);
1489
1490     if (v3_attach_device(vm, dev) == -1) {
1491         PrintError("Could not attach device %s\n", "IDE");
1492         return -1;
1493     }
1494
1495
1496     if (init_ide_state(dev) == -1) {
1497         PrintError("Failed to initialize IDE state\n");
1498         return -1;
1499     }
1500
1501     PrintDebug("Connecting to IDE IO ports\n");
1502
1503     v3_dev_hook_io(dev, PRI_DATA_PORT, 
1504                    &ide_read_data_port, &write_data_port);
1505     v3_dev_hook_io(dev, PRI_FEATURES_PORT, 
1506                    &read_port_std, &write_port_std);
1507     v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, 
1508                    &read_port_std, &write_port_std);
1509     v3_dev_hook_io(dev, PRI_SECT_NUM_PORT, 
1510                    &read_port_std, &write_port_std);
1511     v3_dev_hook_io(dev, PRI_CYL_LOW_PORT, 
1512                    &read_port_std, &write_port_std);
1513     v3_dev_hook_io(dev, PRI_CYL_HIGH_PORT, 
1514                    &read_port_std, &write_port_std);
1515     v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, 
1516                    &read_port_std, &write_port_std);
1517     v3_dev_hook_io(dev, PRI_CMD_PORT, 
1518                    &read_port_std, &write_cmd_port);
1519
1520     v3_dev_hook_io(dev, SEC_DATA_PORT, 
1521                    &ide_read_data_port, &write_data_port);
1522     v3_dev_hook_io(dev, SEC_FEATURES_PORT, 
1523                    &read_port_std, &write_port_std);
1524     v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, 
1525                    &read_port_std, &write_port_std);
1526     v3_dev_hook_io(dev, SEC_SECT_NUM_PORT, 
1527                    &read_port_std, &write_port_std);
1528     v3_dev_hook_io(dev, SEC_CYL_LOW_PORT, 
1529                    &read_port_std, &write_port_std);
1530     v3_dev_hook_io(dev, SEC_CYL_HIGH_PORT, 
1531                    &read_port_std, &write_port_std);
1532     v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, 
1533                    &read_port_std, &write_port_std);
1534     v3_dev_hook_io(dev, SEC_CMD_PORT, 
1535                    &read_port_std, &write_cmd_port);
1536   
1537
1538     v3_dev_hook_io(dev, PRI_CTRL_PORT, 
1539                    &read_port_std, &write_port_std);
1540
1541     v3_dev_hook_io(dev, SEC_CTRL_PORT, 
1542                    &read_port_std, &write_port_std);
1543   
1544
1545     v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, 
1546                    &read_port_std, &write_port_std);
1547
1548     v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, 
1549                    &read_port_std, &write_port_std);
1550
1551
1552
1553
1554     if (ide->pci_bus) {
1555         struct v3_pci_bar bars[6];
1556         struct v3_southbridge * southbridge = (struct v3_southbridge *)(ide->southbridge);
1557         struct pci_device * sb_pci = (struct pci_device *)(southbridge->southbridge_pci);
1558         struct pci_device * pci_dev = NULL;
1559         int i;
1560
1561         PrintDebug("Connecting IDE to PCI bus\n");
1562
1563         for (i = 0; i < 6; i++) {
1564             bars[i].type = PCI_BAR_NONE;
1565         }
1566
1567         bars[4].type = PCI_BAR_IO;
1568         bars[4].default_base_port = PRI_DEFAULT_DMA_PORT;
1569         bars[4].num_ports = 16;
1570
1571         bars[4].io_read = read_dma_port;
1572         bars[4].io_write = write_dma_port;
1573         
1574         pci_dev = v3_pci_register_device(ide->pci_bus, PCI_STD_DEVICE, 0, sb_pci->dev_num, 1, 
1575                                          "PIIX3_IDE", bars,
1576                                          pci_config_update, NULL, NULL, dev);
1577
1578         if (pci_dev == NULL) {
1579             PrintError("Failed to register IDE BUS %d with PCI\n", i); 
1580             return -1;
1581         }
1582
1583         /* This is for CMD646 devices 
1584            pci_dev->config_header.vendor_id = 0x1095;
1585            pci_dev->config_header.device_id = 0x0646;
1586            pci_dev->config_header.revision = 0x8f07;
1587         */
1588
1589         pci_dev->config_header.vendor_id = 0x8086;
1590         pci_dev->config_header.device_id = 0x7010;
1591         pci_dev->config_header.revision = 0x00;
1592
1593         pci_dev->config_header.prog_if = 0x80; // Master IDE device
1594         pci_dev->config_header.subclass = PCI_STORAGE_SUBCLASS_IDE;
1595         pci_dev->config_header.class = PCI_CLASS_STORAGE;
1596
1597         pci_dev->config_header.command = 0;
1598         pci_dev->config_header.status = 0x0280;
1599
1600         ide->ide_pci = pci_dev;
1601
1602
1603     }
1604
1605     PrintDebug("IDE Initialized\n");
1606
1607     return 0;
1608 }
1609
1610
1611 device_register("IDE", ide_init)
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621 int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_num, 
1622                         uint32_t * cylinders, uint32_t * heads, uint32_t * sectors) {
1623
1624     struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
1625     struct ide_channel * channel = &(ide->channels[channel_num]);
1626     struct ide_drive * drive = &(channel->drives[drive_num]);
1627     
1628     if (drive->drive_type == IDE_NONE) {
1629         return -1;
1630     }
1631
1632     *cylinders = drive->num_cylinders;
1633     *heads = drive->num_heads;
1634     *sectors = drive->num_sectors;
1635
1636     return 0;
1637 }
1638
1639
1640
1641
1642 int v3_ide_register_cdrom(struct vm_device * ide_dev, 
1643                           uint_t bus_num, 
1644                           uint_t drive_num,
1645                           char * dev_name, 
1646                           struct v3_ide_cd_ops * ops, 
1647                           void * private_data) {
1648
1649     struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
1650     struct ide_channel * channel = NULL;
1651     struct ide_drive * drive = NULL;
1652
1653     V3_ASSERT((bus_num >= 0) && (bus_num < 2));
1654     V3_ASSERT((drive_num >= 0) && (drive_num < 2));
1655
1656     channel = &(ide->channels[bus_num]);
1657     drive = &(channel->drives[drive_num]);
1658     
1659     if (drive->drive_type != IDE_NONE) {
1660         PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
1661         return -1;
1662     }
1663
1664     strncpy(drive->model, dev_name, sizeof(drive->model) - 1);
1665
1666     while (strlen((char *)(drive->model)) < 40) {
1667         strcat((char*)(drive->model), " ");
1668     }
1669
1670
1671     drive->drive_type = IDE_CDROM;
1672
1673     drive->cd_ops = ops;
1674
1675     if (ide->ide_pci) {
1676         // Hardcode this for now, but its not a good idea....
1677         ide->ide_pci->config_space[0x41 + (bus_num * 2)] = 0x80;
1678     }
1679
1680     drive->private_data = private_data;
1681
1682     return 0;
1683 }
1684
1685
1686 int v3_ide_register_harddisk(struct vm_device * ide_dev, 
1687                              uint_t bus_num, 
1688                              uint_t drive_num, 
1689                              char * dev_name, 
1690                              struct v3_ide_hd_ops * ops, 
1691                              void * private_data) {
1692
1693     struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
1694     struct ide_channel * channel = NULL;
1695     struct ide_drive * drive = NULL;
1696
1697     V3_ASSERT((bus_num >= 0) && (bus_num < 2));
1698     V3_ASSERT((drive_num >= 0) && (drive_num < 2));
1699
1700     channel = &(ide->channels[bus_num]);
1701     drive = &(channel->drives[drive_num]);
1702     
1703     if (drive->drive_type != IDE_NONE) {
1704         PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
1705         return -1;
1706     }
1707
1708     strncpy(drive->model, dev_name, sizeof(drive->model) - 1);
1709
1710     drive->drive_type = IDE_DISK;
1711
1712     drive->hd_state.accessed = 0;
1713     drive->hd_state.mult_sector_num = 1;
1714
1715     drive->hd_ops = ops;
1716
1717     /* this is something of a hack... */
1718     drive->num_sectors = 63;
1719     drive->num_heads = 16;
1720     drive->num_cylinders = ops->get_capacity(private_data)  / (drive->num_sectors * drive->num_heads);
1721
1722     if (ide->ide_pci) {
1723         // Hardcode this for now, but its not a good idea....
1724         ide->ide_pci->config_space[0x41 + (bus_num * 2)] = 0x80;
1725     }
1726
1727
1728
1729     drive->private_data = private_data;
1730
1731     return 0;
1732 }
1733
1734
1735