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.


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