Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


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