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.


cdrom DMA functional
[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
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         
385         uint32_t prd_entry_addr =  channel->dma_prd_addr + (sizeof(struct ide_dma_prd) * channel->dma_tbl_index);
386         uint_t prd_bytes_left = 0;
387         uint_t prd_offset = 0;
388         int ret;
389             
390         PrintDebug("PRD table address = %x\n", channel->dma_prd_addr);
391         
392         ret = read_guest_pa_memory(dev->vm, prd_entry_addr, sizeof(struct ide_dma_prd), (void *)&prd_entry);
393         
394         if (ret != sizeof(struct ide_dma_prd)) {
395             PrintError("Could not read PRD\n");
396             return -1;
397         }
398         
399         PrintDebug("PRD Addr: %x, PDR Len: %d, EOT: %d\n", 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     /*
470       drive->irq_flags.io_dir = 1;
471       drive->irq_flags.c_d = 1;
472       drive->irq_flags.rel = 0;
473     */
474
475
476     // Update to the next PRD entry
477
478     // set DMA status
479
480     if (prd_entry.end_of_table) {
481         channel->status.busy = 0;
482         channel->status.ready = 1;
483         channel->status.data_req = 0;
484         channel->status.error = 0;
485         channel->status.seek_complete = 1;
486
487         channel->dma_status.active = 0;
488         channel->dma_status.err = 0;
489     }
490
491     ide_raise_irq(dev, channel);
492
493     return 0;
494 }
495
496
497 static int dma_write(struct vm_device * dev, struct ide_channel * channel) {
498     // unsupported
499     PrintError("DMA writes currently not supported\n");
500     return -1;
501 }
502
503
504
505 #define DMA_CMD_PORT      0x00
506 #define DMA_STATUS_PORT   0x02
507 #define DMA_PRD_PORT0     0x04
508 #define DMA_PRD_PORT1     0x05
509 #define DMA_PRD_PORT2     0x06
510 #define DMA_PRD_PORT3     0x07
511
512 #define DMA_CHANNEL_FLAG  0x08
513
514 static int write_dma_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
515     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
516     uint16_t port_offset = port & (DMA_CHANNEL_FLAG - 1);
517     uint_t channel_flag = (port & DMA_CHANNEL_FLAG) >> 3;
518     struct ide_channel * channel = &(ide->channels[channel_flag]);
519
520     PrintDebug("IDE: Writing DMA Port %x (%s) (val=%x) (len=%d) (channel=%d)\n", 
521                port, dma_port_to_str(port_offset), *(uint32_t *)src, length, channel_flag);
522
523     switch (port_offset) {
524         case DMA_CMD_PORT:
525             channel->dma_cmd.val = *(uint8_t *)src;
526
527             if (channel->dma_cmd.start == 0) {
528                 channel->dma_tbl_index = 0;
529             } else {
530                 channel->dma_status.active = 1;
531
532                 if (channel->dma_cmd.read == 1) {
533                     // DMA Read
534                     if (dma_read(dev, channel) == -1) {
535                         PrintError("Failed DMA Read\n");
536                         return -1;
537                     }
538                 } else {
539                     // DMA write
540                     if (dma_write(dev, channel) == -1) {
541                         PrintError("Failed DMA Write\n");
542                         return -1;
543                     }
544                 }
545
546                 channel->dma_cmd.val &= 0x09;
547             }
548
549             break;
550             
551         case DMA_STATUS_PORT: {
552             uint8_t val = *(uint8_t *)src;
553
554             if (length != 1) {
555                 PrintError("Invalid read length for DMA status port\n");
556                 return -1;
557             }
558
559             // weirdness
560             channel->dma_status.val = ((val & 0x60) | 
561                                        (channel->dma_status.val & 0x01) |
562                                        (channel->dma_status.val & ~val & 0x06));
563
564             break;
565         }           
566         case DMA_PRD_PORT0:
567         case DMA_PRD_PORT1:
568         case DMA_PRD_PORT2:
569         case DMA_PRD_PORT3: {
570             uint_t addr_index = port_offset & 0x3;
571             uint8_t * addr_buf = (uint8_t *)&(channel->dma_prd_addr);
572             int i = 0;
573
574             if (addr_index + length > 4) {
575                 PrintError("DMA Port space overrun port=%x len=%d\n", port_offset, length);
576                 return -1;
577             }
578
579             for (i = 0; i < length; i++) {
580                 addr_buf[addr_index + i] = *((uint8_t *)src + i);
581             }
582
583             PrintDebug("Writing PRD Port %x (val=%x)\n", port_offset, channel->dma_prd_addr);
584
585             break;
586         }
587         default:
588             PrintError("IDE: Invalid DMA Port (%s)\n", dma_port_to_str(port_offset));
589             return -1;
590     }
591
592     return length;
593 }
594
595
596 static int read_dma_port(ushort_t port, void * dst, 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("Reading DMA port %d (%x) (channel=%d)\n", port, port, channel_flag);
603
604     switch (port_offset) {
605         case DMA_CMD_PORT:
606             *(uint8_t *)dst = channel->dma_cmd.val;
607             break;
608
609         case DMA_STATUS_PORT:
610             if (length != 1) {
611                 PrintError("Invalid read length for DMA status port\n");
612                 return -1;
613             }
614
615             *(uint8_t *)dst = channel->dma_status.val;
616             break;
617
618         case DMA_PRD_PORT0:
619         case DMA_PRD_PORT1:
620         case DMA_PRD_PORT2:
621         case DMA_PRD_PORT3: {
622             uint_t addr_index = port_offset & 0x3;
623             uint8_t * addr_buf = (uint8_t *)&(channel->dma_prd_addr);
624             int i = 0;
625
626             if (addr_index + length > 4) {
627                 PrintError("DMA Port space overrun port=%x len=%d\n", port_offset, length);
628                 return -1;
629             }
630
631             for (i = 0; i < length; i++) {
632                 *((uint8_t *)dst + i) = addr_buf[addr_index + i];
633             }
634
635             break;
636         }
637         default:
638             PrintError("IDE: Invalid DMA Port (%s)\n", dma_port_to_str(port_offset));
639             return -1;
640     }
641
642     PrintDebug("\tval=%x (len=%d)\n", *(uint32_t *)dst, length);
643
644     return length;
645 }
646
647
648
649 static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
650     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
651     struct ide_channel * channel = get_selected_channel(ide, port);
652     struct ide_drive * drive = get_selected_drive(channel);
653
654     if (length != 1) {
655         PrintError("Invalid Write Length on IDE command Port %x\n", port);
656         return -1;
657     }
658
659     PrintDebug("IDE: Writing Command Port %x (%s) (val=%x)\n", port, io_port_to_str(port), *(uint8_t *)src);
660     
661     channel->cmd_reg = *(uint8_t *)src;
662     
663     switch (channel->cmd_reg) {
664
665         case 0xa1: // ATAPI Identify Device Packet
666             if (drive->drive_type != IDE_CDROM) {
667                 drive_reset(drive);
668
669                 // JRL: Should we abort here?
670                 ide_abort_command(dev, channel);
671             } else {
672                 
673                 atapi_identify_device(drive);
674                 
675                 channel->error_reg.val = 0;
676                 channel->status.val = 0x58; // ready, data_req, seek_complete
677             
678                 ide_raise_irq(dev, channel);
679             }
680             break;
681         case 0xec: // Identify Device
682             if (drive->drive_type != IDE_DISK) {
683                 drive_reset(drive);
684
685                 // JRL: Should we abort here?
686                 ide_abort_command(dev, channel);
687             } else {
688                 ata_identify_device(drive);
689
690                 channel->error_reg.val = 0;
691                 channel->status.val = 0x58;
692
693                 ide_raise_irq(dev, channel);
694             }
695             break;
696
697         case 0xa0: // ATAPI Command Packet
698             if (drive->drive_type != IDE_CDROM) {
699                 ide_abort_command(dev, channel);
700             }
701             
702             drive->sector_count = 1;
703
704             channel->status.busy = 0;
705             channel->status.write_fault = 0;
706             channel->status.data_req = 1;
707             channel->status.error = 0;
708
709             // reset the data buffer...
710             drive->transfer_length = ATAPI_PACKET_SIZE;
711             drive->transfer_index = 0;
712
713             break;
714
715         case 0x20: // Read Sectors with Retry
716         case 0x21: // Read Sectors without Retry
717             drive->hd_state.cur_sector_num = 1;
718
719             if (ata_read_sectors(dev, channel) == -1) {
720                 PrintError("Error reading sectors\n");
721                 return -1;
722             }
723             break;
724
725         case 0x24: // Read Sectors Extended
726             drive->hd_state.cur_sector_num = 1;
727
728             if (ata_read_sectors_ext(dev, channel) == -1) {
729                 PrintError("Error reading extended sectors\n");
730                 return -1;
731             }
732             break;
733
734         case 0xc8: // Read DMA with retry
735         case 0xc9: { // Read DMA
736             uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
737
738             if (ata_get_lba(dev, channel, &(drive->current_lba)) == -1) {
739                 ide_abort_command(dev, channel);
740                 return 0;
741             }
742             
743             drive->hd_state.cur_sector_num = 1;
744             
745             drive->transfer_length = sect_cnt * IDE_SECTOR_SIZE;
746             drive->transfer_index = 0;
747
748             if (channel->dma_status.active == 1) {
749                 // DMA Read
750                 if (dma_read(dev, channel) == -1) {
751                     PrintError("Failed DMA Read\n");
752                     return -1;
753                 }
754             }
755             break;
756         }
757
758
759         case 0xe0: // Standby Now 1
760         case 0xe1: // Set Idle Immediate
761         case 0xe2: // Standby
762         case 0xe3: // Set Idle 1
763         case 0xe6: // Sleep Now 1
764         case 0x94: // Standby Now 2
765         case 0x95: // Idle Immediate (CFA)
766         case 0x96: // Standby 2
767         case 0x97: // Set idle 2
768         case 0x99: // Sleep Now 2
769             channel->status.val = 0;
770             channel->status.ready = 1;
771             ide_raise_irq(dev, channel);
772             break;
773
774         case 0xef: // Set Features
775             // Prior to this the features register has been written to. 
776             // This command tells the drive to check if the new value is supported (the value is drive specific)
777             // Common is that bit0=DMA enable
778             // If valid the drive raises an interrupt, if not it aborts.
779
780             // Do some checking here...
781
782             channel->status.busy = 0;
783             channel->status.write_fault = 0;
784             channel->status.error = 0;
785             channel->status.ready = 1;
786             channel->status.seek_complete = 1;
787             
788             ide_raise_irq(dev, channel);
789             break;
790
791         case 0x91:  // Initialize Drive Parameters
792         case 0x10:  // recalibrate?
793             channel->status.error = 0;
794             channel->status.ready = 1;
795             channel->status.seek_complete = 1;
796             ide_raise_irq(dev, channel);
797             break;
798         case 0xc6: { // Set multiple mode (IDE Block mode) 
799             // This makes the drive transfer multiple sectors before generating an interrupt
800             uint32_t tmp_sect_num = drive->sector_num; // GCC SUCKS
801
802             if (tmp_sect_num > MAX_MULT_SECTORS) {
803                 ide_abort_command(dev, channel);
804                 break;
805             }
806
807             if (drive->sector_count == 0) {
808                 drive->hd_state.mult_sector_num= 1;
809             } else {
810                 drive->hd_state.mult_sector_num = drive->sector_count;
811             }
812
813             channel->status.ready = 1;
814             channel->status.error = 0;
815
816             ide_raise_irq(dev, channel);
817
818             break;
819         }
820         case 0xc4:  // read multiple sectors
821             drive->hd_state.cur_sector_num = drive->hd_state.mult_sector_num;
822         default:
823             PrintError("Unimplemented IDE command (%x)\n", channel->cmd_reg);
824             return -1;
825     }
826
827     return length;
828 }
829
830
831 static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
832     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
833     struct ide_channel * channel = get_selected_channel(ide, port);
834     struct ide_drive * drive = get_selected_drive(channel);
835
836     //    PrintDebug("IDE: Writing Data Port %x (val=%x, len=%d)\n", 
837     //         port, *(uint32_t *)src, length);
838     
839     memcpy(drive->data_buf + drive->transfer_index, src, length);    
840     drive->transfer_index += length;
841
842     // Transfer is complete, dispatch the command
843     if (drive->transfer_index >= drive->transfer_length) {
844         switch (channel->cmd_reg) {
845             case 0x30: // Write Sectors
846                 PrintError("Writing Data not yet implemented\n");
847                 return -1;
848                 
849             case 0xa0: // ATAPI packet command
850                 if (atapi_handle_packet(dev, channel) == -1) {
851                     PrintError("Error handling ATAPI packet\n");
852                     return -1;
853                 }
854                 break;
855             default:
856                 PrintError("Unhandld IDE Command %x\n", channel->cmd_reg);
857                 return -1;
858         }
859     }
860
861     return length;
862 }
863
864
865 static int read_hd_data(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
866     struct ide_drive * drive = get_selected_drive(channel);
867     int data_offset = drive->transfer_index % IDE_SECTOR_SIZE;
868
869
870
871     if (drive->transfer_index >= drive->transfer_length) {
872         PrintError("Buffer overrun... (xfer_len=%d) (cur_idx=%x) (post_idx=%d)\n",
873                    drive->transfer_length, drive->transfer_index,
874                    drive->transfer_index + length);
875         return -1;
876     }
877
878     
879     if ((data_offset == 0) && (drive->transfer_index > 0)) {
880         drive->current_lba++;
881
882         if (ata_read(dev, channel, drive->data_buf, 1) == -1) {
883             PrintError("Could not read next disk sector\n");
884             return -1;
885         }
886     }
887
888     /*
889       PrintDebug("Reading HD Data (Val=%x), (len=%d) (offset=%d)\n", 
890       *(uint32_t *)(drive->data_buf + data_offset), 
891       length, data_offset);
892     */
893     memcpy(dst, drive->data_buf + data_offset, length);
894
895     drive->transfer_index += length;
896
897
898     /* This is the trigger for interrupt injection.
899      * For read single sector commands we interrupt after every sector
900      * For multi sector reads we interrupt only at end of the cluster size (mult_sector_num)
901      * cur_sector_num is configured depending on the operation we are currently running
902      * We also trigger an interrupt if this is the last byte to transfer, regardless of sector count
903      */
904     if (((drive->transfer_index % (IDE_SECTOR_SIZE * drive->hd_state.cur_sector_num)) == 0) || 
905         (drive->transfer_index == drive->transfer_length)) {
906         if (drive->transfer_index < drive->transfer_length) {
907             // An increment is complete, but there is still more data to be transferred...
908             PrintDebug("Integral Complete, still transferring more sectors\n");
909             channel->status.data_req = 1;
910
911             drive->irq_flags.c_d = 0;
912         } else {
913             PrintDebug("Final Sector Transferred\n");
914             // This was the final read of the request
915             channel->status.data_req = 0;
916
917             
918             drive->irq_flags.c_d = 1;
919             drive->irq_flags.rel = 0;
920         }
921
922         channel->status.ready = 1;
923         drive->irq_flags.io_dir = 1;
924         channel->status.busy = 0;
925
926         ide_raise_irq(dev, channel);
927     }
928
929
930     return length;
931 }
932
933
934
935 static int read_cd_data(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
936     struct ide_drive * drive = get_selected_drive(channel);
937     int data_offset = drive->transfer_index % ATAPI_BLOCK_SIZE;
938     int req_offset = drive->transfer_index % drive->req_len;
939     
940     if (drive->cd_state.atapi_cmd != 0x28) {
941         PrintDebug("IDE: Reading CD Data (len=%d) (req_len=%d)\n", length, drive->req_len);
942     }
943
944     if (drive->transfer_index >= drive->transfer_length) {
945         PrintError("Buffer Overrun... (xfer_len=%d) (cur_idx=%d) (post_idx=%d)\n", 
946                    drive->transfer_length, drive->transfer_index, 
947                    drive->transfer_index + length);
948         return -1;
949     }
950
951     {
952         static uint32_t read_cnt = 0;
953         
954         if ((read_cnt % 200) == 0) {
955             PrintError("CD data port read %d\n", read_cnt);
956         }
957         
958         read_cnt++;
959     }
960
961
962     if ((data_offset == 0) && (drive->transfer_index > 0)) {
963         if (atapi_update_data_buf(dev, channel) == -1) {
964             PrintError("Could not update CDROM data buffer\n");
965             return -1;
966         }
967     }
968
969     memcpy(dst, drive->data_buf + data_offset, length);
970     
971     drive->transfer_index += length;
972
973
974     // Should the req_offset be recalculated here?????
975     if ((req_offset == 0) && (drive->transfer_index > 0)) {
976         if (drive->transfer_index < drive->transfer_length) {
977             // An increment is complete, but there is still more data to be transferred...
978             
979             channel->status.data_req = 1;
980
981             drive->irq_flags.c_d = 0;
982
983             // Update the request length in the cylinder regs
984             if (atapi_update_req_len(dev, channel, drive->transfer_length - drive->transfer_index) == -1) {
985                 PrintError("Could not update request length after completed increment\n");
986                 return -1;
987             }
988         } else {
989             // This was the final read of the request
990             channel->status.data_req = 0;
991             channel->status.ready = 1;
992             
993             drive->irq_flags.c_d = 1;
994             drive->irq_flags.rel = 0;
995         }
996
997         drive->irq_flags.io_dir = 1;
998         channel->status.busy = 0;
999
1000         ide_raise_irq(dev, channel);
1001     }
1002
1003     return length;
1004 }
1005
1006
1007 static int read_drive_id(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
1008     struct ide_drive * drive = get_selected_drive(channel);
1009
1010     channel->status.busy = 0;
1011     channel->status.ready = 1;
1012     channel->status.write_fault = 0;
1013     channel->status.seek_complete = 1;
1014     channel->status.corrected = 0;
1015     channel->status.error = 0;
1016                 
1017     
1018     memcpy(dst, drive->data_buf + drive->transfer_index, length);
1019     drive->transfer_index += length;
1020     
1021     if (drive->transfer_index >= drive->transfer_length) {
1022         channel->status.data_req = 0;
1023     }
1024     
1025     return length;
1026 }
1027
1028
1029 static int ide_read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
1030     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1031     struct ide_channel * channel = get_selected_channel(ide, port);
1032     struct ide_drive * drive = get_selected_drive(channel);
1033
1034     //    PrintDebug("IDE: Reading Data Port %x (len=%d)\n", port, length);
1035
1036     if ((channel->cmd_reg == 0xec) ||
1037         (channel->cmd_reg == 0xa1)) {
1038         return read_drive_id((uint8_t *)dst, length, dev, channel);
1039     }
1040
1041     if (drive->drive_type == IDE_CDROM) {
1042         if (read_cd_data((uint8_t *)dst, length, dev, channel) == -1) {
1043             PrintError("IDE: Could not read CD Data\n");
1044             return -1;
1045         }
1046     } else if (drive->drive_type == IDE_DISK) {
1047         if (read_hd_data((uint8_t *)dst, length, dev, channel) == -1) {
1048             PrintError("IDE: Could not read HD Data\n");
1049             return -1;
1050         }
1051     } else {
1052         memset((uint8_t *)dst, 0, length);
1053     }
1054
1055     return length;
1056 }
1057
1058 static int write_port_std(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
1059     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1060     struct ide_channel * channel = get_selected_channel(ide, port);
1061     struct ide_drive * drive = get_selected_drive(channel);
1062             
1063     if (length != 1) {
1064         PrintError("Invalid Write length on IDE port %x\n", port);
1065         return -1;
1066     }
1067
1068     PrintDebug("IDE: Writing Standard Port %x (%s) (val=%x)\n", port, io_port_to_str(port), *(uint8_t *)src);
1069
1070     switch (port) {
1071         // reset and interrupt enable
1072         case PRI_CTRL_PORT:
1073         case SEC_CTRL_PORT: {
1074             struct ide_ctrl_reg * tmp_ctrl = (struct ide_ctrl_reg *)src;
1075
1076             // only reset channel on a 0->1 reset bit transition
1077             if ((!channel->ctrl_reg.soft_reset) && (tmp_ctrl->soft_reset)) {
1078                 channel_reset(channel);
1079             } else if ((channel->ctrl_reg.soft_reset) && (!tmp_ctrl->soft_reset)) {
1080                 channel_reset_complete(channel);
1081             }
1082
1083             channel->ctrl_reg.val = tmp_ctrl->val;          
1084             break;
1085         }
1086         case PRI_FEATURES_PORT:
1087         case SEC_FEATURES_PORT:
1088             channel->features.val = *(uint8_t *)src;
1089             break;
1090
1091         case PRI_SECT_CNT_PORT:
1092         case SEC_SECT_CNT_PORT:
1093             channel->drives[0].sector_count = *(uint8_t *)src;
1094             channel->drives[1].sector_count = *(uint8_t *)src;
1095             break;
1096
1097         case PRI_SECT_NUM_PORT:
1098         case SEC_SECT_NUM_PORT:
1099             channel->drives[0].sector_num = *(uint8_t *)src;
1100             channel->drives[1].sector_num = *(uint8_t *)src;
1101             break;
1102         case PRI_CYL_LOW_PORT:
1103         case SEC_CYL_LOW_PORT:
1104             channel->drives[0].cylinder_low = *(uint8_t *)src;
1105             channel->drives[1].cylinder_low = *(uint8_t *)src;
1106             break;
1107
1108         case PRI_CYL_HIGH_PORT:
1109         case SEC_CYL_HIGH_PORT:
1110             channel->drives[0].cylinder_high = *(uint8_t *)src;
1111             channel->drives[1].cylinder_high = *(uint8_t *)src;
1112             break;
1113
1114         case PRI_DRV_SEL_PORT:
1115         case SEC_DRV_SEL_PORT: {
1116             channel->drive_head.val = *(uint8_t *)src;
1117             
1118             // make sure the reserved bits are ok..
1119             // JRL TODO: check with new ramdisk to make sure this is right...
1120             channel->drive_head.val |= 0xa0;
1121
1122             drive = get_selected_drive(channel);
1123
1124             // Selecting a non-present device is a no-no
1125             if (drive->drive_type == IDE_NONE) {
1126                 PrintDebug("Attempting to select a non-present drive\n");
1127                 channel->error_reg.abort = 1;
1128                 channel->status.error = 1;
1129             }
1130
1131             break;
1132         }
1133         default:
1134             PrintError("IDE: Write to unknown Port %x\n", port);
1135             return -1;
1136     }
1137     return length;
1138 }
1139
1140
1141 static int read_port_std(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
1142     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1143     struct ide_channel * channel = get_selected_channel(ide, port);
1144     struct ide_drive * drive = get_selected_drive(channel);
1145     
1146     if (length != 1) {
1147         PrintError("Invalid Read length on IDE port %x\n", port);
1148         return -1;
1149     }
1150     
1151     PrintDebug("IDE: Reading Standard Port %x (%s)\n", port, io_port_to_str(port));
1152
1153     if ((port == PRI_ADDR_REG_PORT) ||
1154         (port == SEC_ADDR_REG_PORT)) {
1155         // unused, return 0xff
1156         *(uint8_t *)dst = 0xff;
1157         return length;
1158     }
1159
1160
1161     // if no drive is present just return 0 + reserved bits
1162     if (drive->drive_type == IDE_NONE) {
1163         if ((port == PRI_DRV_SEL_PORT) ||
1164             (port == SEC_DRV_SEL_PORT)) {
1165             *(uint8_t *)dst = 0xa0;
1166         } else {
1167             *(uint8_t *)dst = 0;
1168         }
1169
1170         return length;
1171     }
1172
1173     switch (port) {
1174
1175         // This is really the error register.
1176         case PRI_FEATURES_PORT:
1177         case SEC_FEATURES_PORT:
1178             *(uint8_t *)dst = channel->error_reg.val;
1179             break;
1180             
1181         case PRI_SECT_CNT_PORT:
1182         case SEC_SECT_CNT_PORT:
1183             *(uint8_t *)dst = drive->sector_count;
1184             break;
1185
1186         case PRI_SECT_NUM_PORT:
1187         case SEC_SECT_NUM_PORT:
1188             *(uint8_t *)dst = drive->sector_num;
1189             break;
1190
1191         case PRI_CYL_LOW_PORT:
1192         case SEC_CYL_LOW_PORT:
1193             *(uint8_t *)dst = drive->cylinder_low;
1194             break;
1195
1196
1197         case PRI_CYL_HIGH_PORT:
1198         case SEC_CYL_HIGH_PORT:
1199             *(uint8_t *)dst = drive->cylinder_high;
1200             break;
1201
1202         case PRI_DRV_SEL_PORT:
1203         case SEC_DRV_SEL_PORT:  // hard disk drive and head register 0x1f6
1204             *(uint8_t *)dst = channel->drive_head.val;
1205             break;
1206
1207         case PRI_CTRL_PORT:
1208         case SEC_CTRL_PORT:
1209         case PRI_CMD_PORT:
1210         case SEC_CMD_PORT:
1211             // Something about lowering interrupts here....
1212             *(uint8_t *)dst = channel->status.val;
1213             break;
1214
1215         default:
1216             PrintError("Invalid Port: %x\n", port);
1217             return -1;
1218     }
1219
1220     PrintDebug("\tVal=%x\n", *(uint8_t *)dst);
1221
1222     return length;
1223 }
1224
1225
1226
1227 static void init_drive(struct ide_drive * drive) {
1228
1229     drive->sector_count = 0x01;
1230     drive->sector_num = 0x01;
1231     drive->cylinder = 0x0000;
1232
1233     drive->drive_type = IDE_NONE;
1234
1235     memset(drive->model, 0, sizeof(drive->model));
1236
1237     drive->transfer_index = 0;
1238     drive->transfer_length = 0;
1239     memset(drive->data_buf, 0, sizeof(drive->data_buf));
1240
1241     drive->num_cylinders = 0;
1242     drive->num_heads = 0;
1243     drive->num_sectors = 0;
1244     
1245
1246     drive->private_data = NULL;
1247     drive->cd_ops = NULL;
1248 }
1249
1250 static void init_channel(struct ide_channel * channel) {
1251     int i = 0;
1252
1253     channel->error_reg.val = 0x01;
1254     channel->drive_head.val = 0x00;
1255     channel->status.val = 0x00;
1256     channel->cmd_reg = 0x00;
1257     channel->ctrl_reg.val = 0x08;
1258
1259
1260     channel->dma_cmd.val = 0;
1261     channel->dma_status.val = 0;
1262     channel->dma_prd_addr = 0;
1263     channel->dma_tbl_index = 0;
1264
1265     for (i = 0; i < 2; i++) {
1266         init_drive(&(channel->drives[i]));
1267     }
1268
1269 }
1270
1271
1272 static int pci_config_update(struct pci_device * pci_dev, uint_t reg_num, int length) {
1273     PrintDebug("PCI Config Update\n");
1274     PrintDebug("\t\tInterupt register (Dev=%s), irq=%d\n", pci_dev->name, pci_dev->config_header.intr_line);
1275
1276     return 0;
1277 }
1278
1279 static int init_ide_state(struct vm_device * dev) {
1280     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1281     int i;
1282
1283     /* 
1284      * Check if the PIIX 3 actually represents both IDE channels in a single PCI entry 
1285      */
1286
1287     for (i = 0; i < 1; i++) {
1288         init_channel(&(ide->channels[i]));
1289
1290         // JRL: this is a terrible hack...
1291         ide->channels[i].irq = PRI_DEFAULT_IRQ + i;
1292     }
1293
1294
1295     return 0;
1296 }
1297
1298
1299
1300 static int init_ide(struct vm_device * dev) {
1301     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1302
1303     PrintDebug("IDE: Initializing IDE\n");
1304
1305     if (init_ide_state(dev) == -1) {
1306         PrintError("Failed to initialize IDE state\n");
1307         return -1;
1308     }
1309
1310
1311     v3_dev_hook_io(dev, PRI_DATA_PORT, 
1312                    &ide_read_data_port, &write_data_port);
1313     v3_dev_hook_io(dev, PRI_FEATURES_PORT, 
1314                    &read_port_std, &write_port_std);
1315     v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, 
1316                    &read_port_std, &write_port_std);
1317     v3_dev_hook_io(dev, PRI_SECT_NUM_PORT, 
1318                    &read_port_std, &write_port_std);
1319     v3_dev_hook_io(dev, PRI_CYL_LOW_PORT, 
1320                    &read_port_std, &write_port_std);
1321     v3_dev_hook_io(dev, PRI_CYL_HIGH_PORT, 
1322                    &read_port_std, &write_port_std);
1323     v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, 
1324                    &read_port_std, &write_port_std);
1325     v3_dev_hook_io(dev, PRI_CMD_PORT, 
1326                    &read_port_std, &write_cmd_port);
1327
1328     v3_dev_hook_io(dev, SEC_DATA_PORT, 
1329                    &ide_read_data_port, &write_data_port);
1330     v3_dev_hook_io(dev, SEC_FEATURES_PORT, 
1331                    &read_port_std, &write_port_std);
1332     v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, 
1333                    &read_port_std, &write_port_std);
1334     v3_dev_hook_io(dev, SEC_SECT_NUM_PORT, 
1335                    &read_port_std, &write_port_std);
1336     v3_dev_hook_io(dev, SEC_CYL_LOW_PORT, 
1337                    &read_port_std, &write_port_std);
1338     v3_dev_hook_io(dev, SEC_CYL_HIGH_PORT, 
1339                    &read_port_std, &write_port_std);
1340     v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, 
1341                    &read_port_std, &write_port_std);
1342     v3_dev_hook_io(dev, SEC_CMD_PORT, 
1343                    &read_port_std, &write_cmd_port);
1344   
1345
1346     v3_dev_hook_io(dev, PRI_CTRL_PORT, 
1347                    &read_port_std, &write_port_std);
1348
1349     v3_dev_hook_io(dev, SEC_CTRL_PORT, 
1350                    &read_port_std, &write_port_std);
1351   
1352
1353     v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, 
1354                    &read_port_std, &write_port_std);
1355
1356     v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, 
1357                    &read_port_std, &write_port_std);
1358
1359
1360
1361
1362     if (ide->pci_bus) {
1363         struct v3_pci_bar bars[6];
1364         struct v3_southbridge * southbridge = (struct v3_southbridge *)(ide->southbridge);
1365         struct pci_device * sb_pci = (struct pci_device *)(southbridge->southbridge_pci);
1366         struct pci_device * pci_dev = NULL;
1367         int i;
1368
1369         for (i = 0; i < 6; i++) {
1370             bars[i].type = PCI_BAR_NONE;
1371         }
1372
1373         bars[4].type = PCI_BAR_IO;
1374         bars[4].default_base_port = PRI_DEFAULT_DMA_PORT;
1375         bars[4].num_ports = 16;
1376
1377         bars[4].io_read = read_dma_port;
1378         bars[4].io_write = write_dma_port;
1379         
1380         pci_dev = v3_pci_register_device(ide->pci_bus, PCI_STD_DEVICE, 0, sb_pci->dev_num, 1, 
1381                                          "PIIX3_IDE", bars,
1382                                          pci_config_update, NULL, NULL, dev);
1383
1384         if (pci_dev == NULL) {
1385             PrintError("Failed to register IDE BUS %d with PCI\n", i); 
1386             return -1;
1387         }
1388
1389         /* This is for CMD646 devices 
1390            pci_dev->config_header.vendor_id = 0x1095;
1391            pci_dev->config_header.device_id = 0x0646;
1392            pci_dev->config_header.revision = 0x8f07;
1393         */
1394
1395         pci_dev->config_header.vendor_id = 0x8086;
1396         pci_dev->config_header.device_id = 0x7010;
1397         pci_dev->config_header.revision = 0x00;
1398
1399         pci_dev->config_header.prog_if = 0x80;
1400         pci_dev->config_header.subclass = 0x01;
1401         pci_dev->config_header.class = 0x01;
1402
1403         pci_dev->config_header.command = 0;
1404         pci_dev->config_header.status = 0x0280;
1405
1406         ide->ide_pci = pci_dev;
1407
1408
1409     }
1410
1411     return 0;
1412 }
1413
1414
1415 static int deinit_ide(struct vm_device * dev) {
1416     // unhook io ports....
1417     // deregister from PCI?
1418     return 0;
1419 }
1420
1421
1422 static struct vm_device_ops dev_ops = {
1423     .init = init_ide,
1424     .deinit = deinit_ide,
1425     .reset = NULL,
1426     .start = NULL,
1427     .stop = NULL,
1428 };
1429
1430
1431 struct vm_device *  v3_create_ide(struct vm_device * pci_bus, struct vm_device * southbridge_dev) {
1432     struct ide_internal * ide  = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal));  
1433     struct vm_device * device = v3_create_device("IDE", &dev_ops, ide);
1434
1435     ide->pci_bus = pci_bus;
1436     ide->southbridge = (struct v3_southbridge *)(southbridge_dev->private_data);
1437
1438     PrintDebug("IDE: Creating IDE bus x 2\n");
1439
1440     return device;
1441 }
1442
1443
1444
1445 int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_num, 
1446                         uint32_t * cylinders, uint32_t * heads, uint32_t * sectors) {
1447
1448     struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
1449     struct ide_channel * channel = &(ide->channels[channel_num]);
1450     struct ide_drive * drive = &(channel->drives[drive_num]);
1451     
1452     if (drive->drive_type == IDE_NONE) {
1453         return -1;
1454     }
1455
1456     *cylinders = drive->num_cylinders;
1457     *heads = drive->num_heads;
1458     *sectors = drive->num_sectors;
1459
1460     return 0;
1461 }
1462
1463
1464
1465
1466 int v3_ide_register_cdrom(struct vm_device * ide_dev, 
1467                           uint_t bus_num, 
1468                           uint_t drive_num,
1469                           char * dev_name, 
1470                           struct v3_ide_cd_ops * ops, 
1471                           void * private_data) {
1472
1473     struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
1474     struct ide_channel * channel = NULL;
1475     struct ide_drive * drive = NULL;
1476
1477     V3_ASSERT((bus_num >= 0) && (bus_num < 2));
1478     V3_ASSERT((drive_num >= 0) && (drive_num < 2));
1479
1480     channel = &(ide->channels[bus_num]);
1481     drive = &(channel->drives[drive_num]);
1482     
1483     if (drive->drive_type != IDE_NONE) {
1484         PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
1485         return -1;
1486     }
1487
1488     strncpy(drive->model, dev_name, sizeof(drive->model) - 1);
1489
1490     while (strlen((char *)(drive->model)) < 40) {
1491         strcat((char*)(drive->model), " ");
1492     }
1493
1494
1495     drive->drive_type = IDE_CDROM;
1496
1497     drive->cd_ops = ops;
1498
1499     if (ide->ide_pci) {
1500         // Hardcode this for now, but its not a good idea....
1501         ide->ide_pci->config_space[0x41 + (bus_num * 2)] = 0x80;
1502     }
1503
1504     drive->private_data = private_data;
1505
1506     return 0;
1507 }
1508
1509
1510 int v3_ide_register_harddisk(struct vm_device * ide_dev, 
1511                              uint_t bus_num, 
1512                              uint_t drive_num, 
1513                              char * dev_name, 
1514                              struct v3_ide_hd_ops * ops, 
1515                              void * private_data) {
1516
1517     struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
1518     struct ide_channel * channel = NULL;
1519     struct ide_drive * drive = NULL;
1520
1521     V3_ASSERT((bus_num >= 0) && (bus_num < 2));
1522     V3_ASSERT((drive_num >= 0) && (drive_num < 2));
1523
1524     channel = &(ide->channels[bus_num]);
1525     drive = &(channel->drives[drive_num]);
1526     
1527     if (drive->drive_type != IDE_NONE) {
1528         PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
1529         return -1;
1530     }
1531
1532     strncpy(drive->model, dev_name, sizeof(drive->model) - 1);
1533
1534     drive->drive_type = IDE_DISK;
1535
1536     drive->hd_state.accessed = 0;
1537     drive->hd_state.mult_sector_num = 1;
1538
1539     drive->hd_ops = ops;
1540
1541     /* this is something of a hack... */
1542     drive->num_sectors = 63;
1543     drive->num_heads = 16;
1544     drive->num_cylinders = (ops->get_capacity(private_data) / 512) / (drive->num_sectors * drive->num_heads);
1545
1546     if (ide->ide_pci) {
1547         // Hardcode this for now, but its not a good idea....
1548         ide->ide_pci->config_space[0x41 + (bus_num * 2)] = 0x80;
1549     }
1550
1551
1552
1553     drive->private_data = private_data;
1554
1555     return 0;
1556 }
1557
1558
1559