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.


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