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.


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