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.


86d2b734026387946b5131a0fe187e510cdfe89c
[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     if ((data_offset == 0) && (drive->transfer_index > 0)) {
953         if (atapi_update_data_buf(dev, channel) == -1) {
954             PrintError("Could not update CDROM data buffer\n");
955             return -1;
956         }
957     }
958
959     memcpy(dst, drive->data_buf + data_offset, length);
960     
961     drive->transfer_index += length;
962
963
964     // Should the req_offset be recalculated here?????
965     if ((req_offset == 0) && (drive->transfer_index > 0)) {
966         if (drive->transfer_index < drive->transfer_length) {
967             // An increment is complete, but there is still more data to be transferred...
968             
969             channel->status.data_req = 1;
970
971             drive->irq_flags.c_d = 0;
972
973             // Update the request length in the cylinder regs
974             if (atapi_update_req_len(dev, channel, drive->transfer_length - drive->transfer_index) == -1) {
975                 PrintError("Could not update request length after completed increment\n");
976                 return -1;
977             }
978         } else {
979             // This was the final read of the request
980             channel->status.data_req = 0;
981             channel->status.ready = 1;
982             
983             drive->irq_flags.c_d = 1;
984             drive->irq_flags.rel = 0;
985         }
986
987         drive->irq_flags.io_dir = 1;
988         channel->status.busy = 0;
989
990         ide_raise_irq(dev, channel);
991     }
992
993     return length;
994 }
995
996
997 static int read_drive_id(uint8_t * dst, uint_t length, struct vm_device * dev, struct ide_channel * channel) {
998     struct ide_drive * drive = get_selected_drive(channel);
999
1000     channel->status.busy = 0;
1001     channel->status.ready = 1;
1002     channel->status.write_fault = 0;
1003     channel->status.seek_complete = 1;
1004     channel->status.corrected = 0;
1005     channel->status.error = 0;
1006                 
1007     
1008     memcpy(dst, drive->data_buf + drive->transfer_index, length);
1009     drive->transfer_index += length;
1010     
1011     if (drive->transfer_index >= drive->transfer_length) {
1012         channel->status.data_req = 0;
1013     }
1014     
1015     return length;
1016 }
1017
1018
1019 static int ide_read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
1020     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1021     struct ide_channel * channel = get_selected_channel(ide, port);
1022     struct ide_drive * drive = get_selected_drive(channel);
1023
1024     //    PrintDebug("IDE: Reading Data Port %x (len=%d)\n", port, length);
1025
1026     if ((channel->cmd_reg == 0xec) ||
1027         (channel->cmd_reg == 0xa1)) {
1028         return read_drive_id((uint8_t *)dst, length, dev, channel);
1029     }
1030
1031     if (drive->drive_type == IDE_CDROM) {
1032         if (read_cd_data((uint8_t *)dst, length, dev, channel) == -1) {
1033             PrintError("IDE: Could not read CD Data\n");
1034             return -1;
1035         }
1036     } else if (drive->drive_type == IDE_DISK) {
1037         if (read_hd_data((uint8_t *)dst, length, dev, channel) == -1) {
1038             PrintError("IDE: Could not read HD Data\n");
1039             return -1;
1040         }
1041     } else {
1042         memset((uint8_t *)dst, 0, length);
1043     }
1044
1045     return length;
1046 }
1047
1048 static int write_port_std(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
1049     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1050     struct ide_channel * channel = get_selected_channel(ide, port);
1051     struct ide_drive * drive = get_selected_drive(channel);
1052             
1053     if (length != 1) {
1054         PrintError("Invalid Write length on IDE port %x\n", port);
1055         return -1;
1056     }
1057
1058     PrintDebug("IDE: Writing Standard Port %x (%s) (val=%x)\n", port, io_port_to_str(port), *(uint8_t *)src);
1059
1060     switch (port) {
1061         // reset and interrupt enable
1062         case PRI_CTRL_PORT:
1063         case SEC_CTRL_PORT: {
1064             struct ide_ctrl_reg * tmp_ctrl = (struct ide_ctrl_reg *)src;
1065
1066             // only reset channel on a 0->1 reset bit transition
1067             if ((!channel->ctrl_reg.soft_reset) && (tmp_ctrl->soft_reset)) {
1068                 channel_reset(channel);
1069             } else if ((channel->ctrl_reg.soft_reset) && (!tmp_ctrl->soft_reset)) {
1070                 channel_reset_complete(channel);
1071             }
1072
1073             channel->ctrl_reg.val = tmp_ctrl->val;          
1074             break;
1075         }
1076         case PRI_FEATURES_PORT:
1077         case SEC_FEATURES_PORT:
1078             channel->features.val = *(uint8_t *)src;
1079             break;
1080
1081         case PRI_SECT_CNT_PORT:
1082         case SEC_SECT_CNT_PORT:
1083             channel->drives[0].sector_count = *(uint8_t *)src;
1084             channel->drives[1].sector_count = *(uint8_t *)src;
1085             break;
1086
1087         case PRI_SECT_NUM_PORT:
1088         case SEC_SECT_NUM_PORT:
1089             channel->drives[0].sector_num = *(uint8_t *)src;
1090             channel->drives[1].sector_num = *(uint8_t *)src;
1091             break;
1092         case PRI_CYL_LOW_PORT:
1093         case SEC_CYL_LOW_PORT:
1094             channel->drives[0].cylinder_low = *(uint8_t *)src;
1095             channel->drives[1].cylinder_low = *(uint8_t *)src;
1096             break;
1097
1098         case PRI_CYL_HIGH_PORT:
1099         case SEC_CYL_HIGH_PORT:
1100             channel->drives[0].cylinder_high = *(uint8_t *)src;
1101             channel->drives[1].cylinder_high = *(uint8_t *)src;
1102             break;
1103
1104         case PRI_DRV_SEL_PORT:
1105         case SEC_DRV_SEL_PORT: {
1106             channel->drive_head.val = *(uint8_t *)src;
1107             
1108             // make sure the reserved bits are ok..
1109             // JRL TODO: check with new ramdisk to make sure this is right...
1110             channel->drive_head.val |= 0xa0;
1111
1112             drive = get_selected_drive(channel);
1113
1114             // Selecting a non-present device is a no-no
1115             if (drive->drive_type == IDE_NONE) {
1116                 PrintDebug("Attempting to select a non-present drive\n");
1117                 channel->error_reg.abort = 1;
1118                 channel->status.error = 1;
1119             }
1120
1121             break;
1122         }
1123         default:
1124             PrintError("IDE: Write to unknown Port %x\n", port);
1125             return -1;
1126     }
1127     return length;
1128 }
1129
1130
1131 static int read_port_std(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
1132     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1133     struct ide_channel * channel = get_selected_channel(ide, port);
1134     struct ide_drive * drive = get_selected_drive(channel);
1135     
1136     if (length != 1) {
1137         PrintError("Invalid Read length on IDE port %x\n", port);
1138         return -1;
1139     }
1140     
1141     PrintDebug("IDE: Reading Standard Port %x (%s)\n", port, io_port_to_str(port));
1142
1143     if ((port == PRI_ADDR_REG_PORT) ||
1144         (port == SEC_ADDR_REG_PORT)) {
1145         // unused, return 0xff
1146         *(uint8_t *)dst = 0xff;
1147         return length;
1148     }
1149
1150
1151     // if no drive is present just return 0 + reserved bits
1152     if (drive->drive_type == IDE_NONE) {
1153         if ((port == PRI_DRV_SEL_PORT) ||
1154             (port == SEC_DRV_SEL_PORT)) {
1155             *(uint8_t *)dst = 0xa0;
1156         } else {
1157             *(uint8_t *)dst = 0;
1158         }
1159
1160         return length;
1161     }
1162
1163     switch (port) {
1164
1165         // This is really the error register.
1166         case PRI_FEATURES_PORT:
1167         case SEC_FEATURES_PORT:
1168             *(uint8_t *)dst = channel->error_reg.val;
1169             break;
1170             
1171         case PRI_SECT_CNT_PORT:
1172         case SEC_SECT_CNT_PORT:
1173             *(uint8_t *)dst = drive->sector_count;
1174             break;
1175
1176         case PRI_SECT_NUM_PORT:
1177         case SEC_SECT_NUM_PORT:
1178             *(uint8_t *)dst = drive->sector_num;
1179             break;
1180
1181         case PRI_CYL_LOW_PORT:
1182         case SEC_CYL_LOW_PORT:
1183             *(uint8_t *)dst = drive->cylinder_low;
1184             break;
1185
1186
1187         case PRI_CYL_HIGH_PORT:
1188         case SEC_CYL_HIGH_PORT:
1189             *(uint8_t *)dst = drive->cylinder_high;
1190             break;
1191
1192         case PRI_DRV_SEL_PORT:
1193         case SEC_DRV_SEL_PORT:  // hard disk drive and head register 0x1f6
1194             *(uint8_t *)dst = channel->drive_head.val;
1195             break;
1196
1197         case PRI_CTRL_PORT:
1198         case SEC_CTRL_PORT:
1199         case PRI_CMD_PORT:
1200         case SEC_CMD_PORT:
1201             // Something about lowering interrupts here....
1202             *(uint8_t *)dst = channel->status.val;
1203             break;
1204
1205         default:
1206             PrintError("Invalid Port: %x\n", port);
1207             return -1;
1208     }
1209
1210     PrintDebug("\tVal=%x\n", *(uint8_t *)dst);
1211
1212     return length;
1213 }
1214
1215
1216
1217 static void init_drive(struct ide_drive * drive) {
1218
1219     drive->sector_count = 0x01;
1220     drive->sector_num = 0x01;
1221     drive->cylinder = 0x0000;
1222
1223     drive->drive_type = IDE_NONE;
1224
1225     memset(drive->model, 0, sizeof(drive->model));
1226
1227     drive->transfer_index = 0;
1228     drive->transfer_length = 0;
1229     memset(drive->data_buf, 0, sizeof(drive->data_buf));
1230
1231     drive->num_cylinders = 0;
1232     drive->num_heads = 0;
1233     drive->num_sectors = 0;
1234     
1235
1236     drive->private_data = NULL;
1237     drive->cd_ops = NULL;
1238 }
1239
1240 static void init_channel(struct ide_channel * channel) {
1241     int i = 0;
1242
1243     channel->error_reg.val = 0x01;
1244     channel->drive_head.val = 0x00;
1245     channel->status.val = 0x00;
1246     channel->cmd_reg = 0x00;
1247     channel->ctrl_reg.val = 0x08;
1248
1249
1250     channel->dma_cmd.val = 0;
1251     channel->dma_status.val = 0;
1252     channel->dma_prd_addr = 0;
1253     channel->dma_tbl_index = 0;
1254
1255     for (i = 0; i < 2; i++) {
1256         init_drive(&(channel->drives[i]));
1257     }
1258
1259 }
1260
1261
1262 static int pci_config_update(struct pci_device * pci_dev, uint_t reg_num, int length) {
1263     PrintDebug("PCI Config Update\n");
1264     PrintDebug("\t\tInterupt register (Dev=%s), irq=%d\n", pci_dev->name, pci_dev->config_header.intr_line);
1265
1266     return 0;
1267 }
1268
1269 static int init_ide_state(struct vm_device * dev) {
1270     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1271     int i;
1272
1273     /* 
1274      * Check if the PIIX 3 actually represents both IDE channels in a single PCI entry 
1275      */
1276
1277     for (i = 0; i < 1; i++) {
1278         init_channel(&(ide->channels[i]));
1279
1280         // JRL: this is a terrible hack...
1281         ide->channels[i].irq = PRI_DEFAULT_IRQ + i;
1282     }
1283
1284
1285     return 0;
1286 }
1287
1288
1289
1290 static int init_ide(struct vm_device * dev) {
1291     struct ide_internal * ide = (struct ide_internal *)(dev->private_data);
1292
1293     PrintDebug("IDE: Initializing IDE\n");
1294
1295     if (init_ide_state(dev) == -1) {
1296         PrintError("Failed to initialize IDE state\n");
1297         return -1;
1298     }
1299
1300
1301     v3_dev_hook_io(dev, PRI_DATA_PORT, 
1302                    &ide_read_data_port, &write_data_port);
1303     v3_dev_hook_io(dev, PRI_FEATURES_PORT, 
1304                    &read_port_std, &write_port_std);
1305     v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, 
1306                    &read_port_std, &write_port_std);
1307     v3_dev_hook_io(dev, PRI_SECT_NUM_PORT, 
1308                    &read_port_std, &write_port_std);
1309     v3_dev_hook_io(dev, PRI_CYL_LOW_PORT, 
1310                    &read_port_std, &write_port_std);
1311     v3_dev_hook_io(dev, PRI_CYL_HIGH_PORT, 
1312                    &read_port_std, &write_port_std);
1313     v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, 
1314                    &read_port_std, &write_port_std);
1315     v3_dev_hook_io(dev, PRI_CMD_PORT, 
1316                    &read_port_std, &write_cmd_port);
1317
1318     v3_dev_hook_io(dev, SEC_DATA_PORT, 
1319                    &ide_read_data_port, &write_data_port);
1320     v3_dev_hook_io(dev, SEC_FEATURES_PORT, 
1321                    &read_port_std, &write_port_std);
1322     v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, 
1323                    &read_port_std, &write_port_std);
1324     v3_dev_hook_io(dev, SEC_SECT_NUM_PORT, 
1325                    &read_port_std, &write_port_std);
1326     v3_dev_hook_io(dev, SEC_CYL_LOW_PORT, 
1327                    &read_port_std, &write_port_std);
1328     v3_dev_hook_io(dev, SEC_CYL_HIGH_PORT, 
1329                    &read_port_std, &write_port_std);
1330     v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, 
1331                    &read_port_std, &write_port_std);
1332     v3_dev_hook_io(dev, SEC_CMD_PORT, 
1333                    &read_port_std, &write_cmd_port);
1334   
1335
1336     v3_dev_hook_io(dev, PRI_CTRL_PORT, 
1337                    &read_port_std, &write_port_std);
1338
1339     v3_dev_hook_io(dev, SEC_CTRL_PORT, 
1340                    &read_port_std, &write_port_std);
1341   
1342
1343     v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, 
1344                    &read_port_std, &write_port_std);
1345
1346     v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, 
1347                    &read_port_std, &write_port_std);
1348
1349
1350
1351
1352     if (ide->pci_bus) {
1353         struct v3_pci_bar bars[6];
1354         struct v3_southbridge * southbridge = (struct v3_southbridge *)(ide->southbridge);
1355         struct pci_device * sb_pci = (struct pci_device *)(southbridge->southbridge_pci);
1356         struct pci_device * pci_dev = NULL;
1357         int i;
1358
1359         for (i = 0; i < 6; i++) {
1360             bars[i].type = PCI_BAR_NONE;
1361         }
1362
1363         bars[4].type = PCI_BAR_IO;
1364         bars[4].default_base_port = PRI_DEFAULT_DMA_PORT;
1365         bars[4].num_ports = 16;
1366
1367         bars[4].io_read = read_dma_port;
1368         bars[4].io_write = write_dma_port;
1369         
1370         pci_dev = v3_pci_register_device(ide->pci_bus, PCI_STD_DEVICE, 0, sb_pci->dev_num, 1, 
1371                                          "PIIX3_IDE", bars,
1372                                          pci_config_update, NULL, NULL, dev);
1373
1374         if (pci_dev == NULL) {
1375             PrintError("Failed to register IDE BUS %d with PCI\n", i); 
1376             return -1;
1377         }
1378
1379         /* This is for CMD646 devices 
1380            pci_dev->config_header.vendor_id = 0x1095;
1381            pci_dev->config_header.device_id = 0x0646;
1382            pci_dev->config_header.revision = 0x8f07;
1383         */
1384
1385         pci_dev->config_header.vendor_id = 0x8086;
1386         pci_dev->config_header.device_id = 0x7010;
1387         pci_dev->config_header.revision = 0x00;
1388
1389         pci_dev->config_header.prog_if = 0x80;
1390         pci_dev->config_header.subclass = 0x01;
1391         pci_dev->config_header.class = 0x01;
1392
1393         pci_dev->config_header.command = 0;
1394         pci_dev->config_header.status = 0x0280;
1395
1396         ide->ide_pci = pci_dev;
1397
1398
1399     }
1400
1401     return 0;
1402 }
1403
1404
1405 static int deinit_ide(struct vm_device * dev) {
1406     // unhook io ports....
1407     // deregister from PCI?
1408     return 0;
1409 }
1410
1411
1412 static struct vm_device_ops dev_ops = {
1413     .init = init_ide,
1414     .deinit = deinit_ide,
1415     .reset = NULL,
1416     .start = NULL,
1417     .stop = NULL,
1418 };
1419
1420
1421 struct vm_device *  v3_create_ide(struct vm_device * pci_bus, struct vm_device * southbridge_dev) {
1422     struct ide_internal * ide  = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal));  
1423     struct vm_device * device = v3_create_device("IDE", &dev_ops, ide);
1424
1425     ide->pci_bus = pci_bus;
1426     ide->southbridge = (struct v3_southbridge *)(southbridge_dev->private_data);
1427
1428     PrintDebug("IDE: Creating IDE bus x 2\n");
1429
1430     return device;
1431 }
1432
1433
1434
1435 int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_num, 
1436                         uint32_t * cylinders, uint32_t * heads, uint32_t * sectors) {
1437
1438     struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
1439     struct ide_channel * channel = &(ide->channels[channel_num]);
1440     struct ide_drive * drive = &(channel->drives[drive_num]);
1441     
1442     if (drive->drive_type == IDE_NONE) {
1443         return -1;
1444     }
1445
1446     *cylinders = drive->num_cylinders;
1447     *heads = drive->num_heads;
1448     *sectors = drive->num_sectors;
1449
1450     return 0;
1451 }
1452
1453
1454
1455
1456 int v3_ide_register_cdrom(struct vm_device * ide_dev, 
1457                           uint_t bus_num, 
1458                           uint_t drive_num,
1459                           char * dev_name, 
1460                           struct v3_ide_cd_ops * ops, 
1461                           void * private_data) {
1462
1463     struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
1464     struct ide_channel * channel = NULL;
1465     struct ide_drive * drive = NULL;
1466
1467     V3_ASSERT((bus_num >= 0) && (bus_num < 2));
1468     V3_ASSERT((drive_num >= 0) && (drive_num < 2));
1469
1470     channel = &(ide->channels[bus_num]);
1471     drive = &(channel->drives[drive_num]);
1472     
1473     if (drive->drive_type != IDE_NONE) {
1474         PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
1475         return -1;
1476     }
1477
1478     strncpy(drive->model, dev_name, sizeof(drive->model) - 1);
1479
1480     while (strlen((char *)(drive->model)) < 40) {
1481         strcat((char*)(drive->model), " ");
1482     }
1483
1484
1485     drive->drive_type = IDE_CDROM;
1486
1487     drive->cd_ops = ops;
1488
1489     if (ide->ide_pci) {
1490         // Hardcode this for now, but its not a good idea....
1491         ide->ide_pci->config_space[0x41 + (bus_num * 2)] = 0x80;
1492     }
1493
1494     drive->private_data = private_data;
1495
1496     return 0;
1497 }
1498
1499
1500 int v3_ide_register_harddisk(struct vm_device * ide_dev, 
1501                              uint_t bus_num, 
1502                              uint_t drive_num, 
1503                              char * dev_name, 
1504                              struct v3_ide_hd_ops * ops, 
1505                              void * private_data) {
1506
1507     struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
1508     struct ide_channel * channel = NULL;
1509     struct ide_drive * drive = NULL;
1510
1511     V3_ASSERT((bus_num >= 0) && (bus_num < 2));
1512     V3_ASSERT((drive_num >= 0) && (drive_num < 2));
1513
1514     channel = &(ide->channels[bus_num]);
1515     drive = &(channel->drives[drive_num]);
1516     
1517     if (drive->drive_type != IDE_NONE) {
1518         PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
1519         return -1;
1520     }
1521
1522     strncpy(drive->model, dev_name, sizeof(drive->model) - 1);
1523
1524     drive->drive_type = IDE_DISK;
1525
1526     drive->hd_state.accessed = 0;
1527     drive->hd_state.mult_sector_num = 1;
1528
1529     drive->hd_ops = ops;
1530
1531     /* this is something of a hack... */
1532     drive->num_sectors = 63;
1533     drive->num_heads = 16;
1534     drive->num_cylinders = (ops->get_capacity(private_data) / 512) / (drive->num_sectors * drive->num_heads);
1535
1536     if (ide->ide_pci) {
1537         // Hardcode this for now, but its not a good idea....
1538         ide->ide_pci->config_space[0x41 + (bus_num * 2)] = 0x80;
1539     }
1540
1541
1542
1543     drive->private_data = private_data;
1544
1545     return 0;
1546 }
1547
1548
1549