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.


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