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.


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