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 implements the "Check power mode" IDE command which allows the latest...
[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 0xe5: // Check power mode
971             drive->sector_count = 0xff; /* 0x00=standby, 0x80=idle, 0xff=active or idle */
972             channel->status.busy = 0;
973             channel->status.ready = 1;
974             channel->status.write_fault = 0;
975             channel->status.data_req = 0;
976             channel->status.error = 0;
977             break;
978
979         case 0xc4:  // read multiple sectors
980             drive->hd_state.cur_sector_num = drive->hd_state.mult_sector_num;
981         default:
982             PrintError("Unimplemented IDE command (%x)\n", channel->cmd_reg);
983             return -1;
984     }
985
986     return length;
987 }
988
989
990 static int write_data_port(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
991     struct ide_internal * ide = priv_data;
992     struct ide_channel * channel = get_selected_channel(ide, port);
993     struct ide_drive * drive = get_selected_drive(channel);
994
995     //    PrintDebug("IDE: Writing Data Port %x (val=%x, len=%d)\n", 
996     //         port, *(uint32_t *)src, length);
997     
998     memcpy(drive->data_buf + drive->transfer_index, src, length);    
999     drive->transfer_index += length;
1000
1001     // Transfer is complete, dispatch the command
1002     if (drive->transfer_index >= drive->transfer_length) {
1003         switch (channel->cmd_reg) {
1004             case 0x30: // Write Sectors
1005                 PrintError("Writing Data not yet implemented\n");
1006                 return -1;
1007                 
1008             case 0xa0: // ATAPI packet command
1009                 if (atapi_handle_packet(core, ide, channel) == -1) {
1010                     PrintError("Error handling ATAPI packet\n");
1011                     return -1;
1012                 }
1013                 break;
1014             default:
1015                 PrintError("Unhandld IDE Command %x\n", channel->cmd_reg);
1016                 return -1;
1017         }
1018     }
1019
1020     return length;
1021 }
1022
1023
1024 static int read_hd_data(uint8_t * dst, uint_t length, struct ide_internal * ide, struct ide_channel * channel) {
1025     struct ide_drive * drive = get_selected_drive(channel);
1026     int data_offset = drive->transfer_index % HD_SECTOR_SIZE;
1027
1028
1029
1030     if (drive->transfer_index >= drive->transfer_length) {
1031         PrintError("Buffer overrun... (xfer_len=%d) (cur_idx=%x) (post_idx=%d)\n",
1032                    drive->transfer_length, drive->transfer_index,
1033                    drive->transfer_index + length);
1034         return -1;
1035     }
1036
1037     
1038     if ((data_offset == 0) && (drive->transfer_index > 0)) {
1039         drive->current_lba++;
1040
1041         if (ata_read(ide, channel, drive->data_buf, 1) == -1) {
1042             PrintError("Could not read next disk sector\n");
1043             return -1;
1044         }
1045     }
1046
1047     /*
1048       PrintDebug("Reading HD Data (Val=%x), (len=%d) (offset=%d)\n", 
1049       *(uint32_t *)(drive->data_buf + data_offset), 
1050       length, data_offset);
1051     */
1052     memcpy(dst, drive->data_buf + data_offset, length);
1053
1054     drive->transfer_index += length;
1055
1056
1057     /* This is the trigger for interrupt injection.
1058      * For read single sector commands we interrupt after every sector
1059      * For multi sector reads we interrupt only at end of the cluster size (mult_sector_num)
1060      * cur_sector_num is configured depending on the operation we are currently running
1061      * We also trigger an interrupt if this is the last byte to transfer, regardless of sector count
1062      */
1063     if (((drive->transfer_index % (HD_SECTOR_SIZE * drive->hd_state.cur_sector_num)) == 0) || 
1064         (drive->transfer_index == drive->transfer_length)) {
1065         if (drive->transfer_index < drive->transfer_length) {
1066             // An increment is complete, but there is still more data to be transferred...
1067             PrintDebug("Integral Complete, still transferring more sectors\n");
1068             channel->status.data_req = 1;
1069
1070             drive->irq_flags.c_d = 0;
1071         } else {
1072             PrintDebug("Final Sector Transferred\n");
1073             // This was the final read of the request
1074             channel->status.data_req = 0;
1075
1076             
1077             drive->irq_flags.c_d = 1;
1078             drive->irq_flags.rel = 0;
1079         }
1080
1081         channel->status.ready = 1;
1082         drive->irq_flags.io_dir = 1;
1083         channel->status.busy = 0;
1084
1085         ide_raise_irq(ide, channel);
1086     }
1087
1088
1089     return length;
1090 }
1091
1092
1093
1094 static int read_cd_data(uint8_t * dst, uint_t length, struct ide_internal * ide, struct ide_channel * channel) {
1095     struct ide_drive * drive = get_selected_drive(channel);
1096     int data_offset = drive->transfer_index % ATAPI_BLOCK_SIZE;
1097     int req_offset = drive->transfer_index % drive->req_len;
1098     
1099     if (drive->cd_state.atapi_cmd != 0x28) {
1100         PrintDebug("IDE: Reading CD Data (len=%d) (req_len=%d)\n", length, drive->req_len);
1101     }
1102
1103     if (drive->transfer_index >= drive->transfer_length) {
1104         PrintError("Buffer Overrun... (xfer_len=%d) (cur_idx=%d) (post_idx=%d)\n", 
1105                    drive->transfer_length, drive->transfer_index, 
1106                    drive->transfer_index + length);
1107         return -1;
1108     }
1109
1110     
1111     if ((data_offset == 0) && (drive->transfer_index > 0)) {
1112         if (atapi_update_data_buf(ide, channel) == -1) {
1113             PrintError("Could not update CDROM data buffer\n");
1114             return -1;
1115         }
1116     }
1117
1118     memcpy(dst, drive->data_buf + data_offset, length);
1119     
1120     drive->transfer_index += length;
1121
1122
1123     // Should the req_offset be recalculated here?????
1124     if ((req_offset == 0) && (drive->transfer_index > 0)) {
1125         if (drive->transfer_index < drive->transfer_length) {
1126             // An increment is complete, but there is still more data to be transferred...
1127             
1128             channel->status.data_req = 1;
1129
1130             drive->irq_flags.c_d = 0;
1131
1132             // Update the request length in the cylinder regs
1133             if (atapi_update_req_len(ide, channel, drive->transfer_length - drive->transfer_index) == -1) {
1134                 PrintError("Could not update request length after completed increment\n");
1135                 return -1;
1136             }
1137         } else {
1138             // This was the final read of the request
1139             channel->status.data_req = 0;
1140             channel->status.ready = 1;
1141             
1142             drive->irq_flags.c_d = 1;
1143             drive->irq_flags.rel = 0;
1144         }
1145
1146         drive->irq_flags.io_dir = 1;
1147         channel->status.busy = 0;
1148
1149         ide_raise_irq(ide, channel);
1150     }
1151
1152     return length;
1153 }
1154
1155
1156 static int read_drive_id( uint8_t * dst, uint_t length, struct ide_internal * ide, struct ide_channel * channel) {
1157     struct ide_drive * drive = get_selected_drive(channel);
1158
1159     channel->status.busy = 0;
1160     channel->status.ready = 1;
1161     channel->status.write_fault = 0;
1162     channel->status.seek_complete = 1;
1163     channel->status.corrected = 0;
1164     channel->status.error = 0;
1165                 
1166     
1167     memcpy(dst, drive->data_buf + drive->transfer_index, length);
1168     drive->transfer_index += length;
1169     
1170     if (drive->transfer_index >= drive->transfer_length) {
1171         channel->status.data_req = 0;
1172     }
1173     
1174     return length;
1175 }
1176
1177
1178 static int ide_read_data_port(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
1179     struct ide_internal * ide = priv_data;
1180     struct ide_channel * channel = get_selected_channel(ide, port);
1181     struct ide_drive * drive = get_selected_drive(channel);
1182
1183        PrintDebug("IDE: Reading Data Port %x (len=%d)\n", port, length);
1184
1185     if ((channel->cmd_reg == 0xec) ||
1186         (channel->cmd_reg == 0xa1)) {
1187         return read_drive_id((uint8_t *)dst, length, ide, channel);
1188     }
1189
1190     if (drive->drive_type == BLOCK_CDROM) {
1191         if (read_cd_data((uint8_t *)dst, length, ide, channel) == -1) {
1192             PrintError("IDE: Could not read CD Data\n");
1193             return -1;
1194         }
1195     } else if (drive->drive_type == BLOCK_DISK) {
1196         if (read_hd_data((uint8_t *)dst, length, ide, channel) == -1) {
1197             PrintError("IDE: Could not read HD Data\n");
1198             return -1;
1199         }
1200     } else {
1201         memset((uint8_t *)dst, 0, length);
1202     }
1203
1204     return length;
1205 }
1206
1207 static int write_port_std(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
1208     struct ide_internal * ide = priv_data;
1209     struct ide_channel * channel = get_selected_channel(ide, port);
1210     struct ide_drive * drive = get_selected_drive(channel);
1211             
1212     if (length != 1) {
1213         PrintError("Invalid Write length on IDE port %x\n", port);
1214         return -1;
1215     }
1216
1217     PrintDebug("IDE: Writing Standard Port %x (%s) (val=%x)\n", port, io_port_to_str(port), *(uint8_t *)src);
1218
1219     switch (port) {
1220         // reset and interrupt enable
1221         case PRI_CTRL_PORT:
1222         case SEC_CTRL_PORT: {
1223             struct ide_ctrl_reg * tmp_ctrl = (struct ide_ctrl_reg *)src;
1224
1225             // only reset channel on a 0->1 reset bit transition
1226             if ((!channel->ctrl_reg.soft_reset) && (tmp_ctrl->soft_reset)) {
1227                 channel_reset(channel);
1228             } else if ((channel->ctrl_reg.soft_reset) && (!tmp_ctrl->soft_reset)) {
1229                 channel_reset_complete(channel);
1230             }
1231
1232             channel->ctrl_reg.val = tmp_ctrl->val;          
1233             break;
1234         }
1235         case PRI_FEATURES_PORT:
1236         case SEC_FEATURES_PORT:
1237             channel->features.val = *(uint8_t *)src;
1238             break;
1239
1240         case PRI_SECT_CNT_PORT:
1241         case SEC_SECT_CNT_PORT:
1242             channel->drives[0].sector_count = *(uint8_t *)src;
1243             channel->drives[1].sector_count = *(uint8_t *)src;
1244             break;
1245
1246         case PRI_SECT_NUM_PORT:
1247         case SEC_SECT_NUM_PORT:
1248             channel->drives[0].sector_num = *(uint8_t *)src;
1249             channel->drives[1].sector_num = *(uint8_t *)src;
1250             break;
1251         case PRI_CYL_LOW_PORT:
1252         case SEC_CYL_LOW_PORT:
1253             channel->drives[0].cylinder_low = *(uint8_t *)src;
1254             channel->drives[1].cylinder_low = *(uint8_t *)src;
1255             break;
1256
1257         case PRI_CYL_HIGH_PORT:
1258         case SEC_CYL_HIGH_PORT:
1259             channel->drives[0].cylinder_high = *(uint8_t *)src;
1260             channel->drives[1].cylinder_high = *(uint8_t *)src;
1261             break;
1262
1263         case PRI_DRV_SEL_PORT:
1264         case SEC_DRV_SEL_PORT: {
1265             channel->drive_head.val = *(uint8_t *)src;
1266             
1267             // make sure the reserved bits are ok..
1268             // JRL TODO: check with new ramdisk to make sure this is right...
1269             channel->drive_head.val |= 0xa0;
1270
1271             drive = get_selected_drive(channel);
1272
1273             // Selecting a non-present device is a no-no
1274             if (drive->drive_type == BLOCK_NONE) {
1275                 PrintDebug("Attempting to select a non-present drive\n");
1276                 channel->error_reg.abort = 1;
1277                 channel->status.error = 1;
1278             }
1279
1280             break;
1281         }
1282         default:
1283             PrintError("IDE: Write to unknown Port %x\n", port);
1284             return -1;
1285     }
1286     return length;
1287 }
1288
1289
1290 static int read_port_std(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
1291     struct ide_internal * ide = priv_data;
1292     struct ide_channel * channel = get_selected_channel(ide, port);
1293     struct ide_drive * drive = get_selected_drive(channel);
1294     
1295     if (length != 1) {
1296         PrintError("Invalid Read length on IDE port %x\n", port);
1297         return -1;
1298     }
1299     
1300     PrintDebug("IDE: Reading Standard Port %x (%s)\n", port, io_port_to_str(port));
1301
1302     if ((port == PRI_ADDR_REG_PORT) ||
1303         (port == SEC_ADDR_REG_PORT)) {
1304         // unused, return 0xff
1305         *(uint8_t *)dst = 0xff;
1306         return length;
1307     }
1308
1309
1310     // if no drive is present just return 0 + reserved bits
1311     if (drive->drive_type == BLOCK_NONE) {
1312         if ((port == PRI_DRV_SEL_PORT) ||
1313             (port == SEC_DRV_SEL_PORT)) {
1314             *(uint8_t *)dst = 0xa0;
1315         } else {
1316             *(uint8_t *)dst = 0;
1317         }
1318
1319         return length;
1320     }
1321
1322     switch (port) {
1323
1324         // This is really the error register.
1325         case PRI_FEATURES_PORT:
1326         case SEC_FEATURES_PORT:
1327             *(uint8_t *)dst = channel->error_reg.val;
1328             break;
1329             
1330         case PRI_SECT_CNT_PORT:
1331         case SEC_SECT_CNT_PORT:
1332             *(uint8_t *)dst = drive->sector_count;
1333             break;
1334
1335         case PRI_SECT_NUM_PORT:
1336         case SEC_SECT_NUM_PORT:
1337             *(uint8_t *)dst = drive->sector_num;
1338             break;
1339
1340         case PRI_CYL_LOW_PORT:
1341         case SEC_CYL_LOW_PORT:
1342             *(uint8_t *)dst = drive->cylinder_low;
1343             break;
1344
1345
1346         case PRI_CYL_HIGH_PORT:
1347         case SEC_CYL_HIGH_PORT:
1348             *(uint8_t *)dst = drive->cylinder_high;
1349             break;
1350
1351         case PRI_DRV_SEL_PORT:
1352         case SEC_DRV_SEL_PORT:  // hard disk drive and head register 0x1f6
1353             *(uint8_t *)dst = channel->drive_head.val;
1354             break;
1355
1356         case PRI_CTRL_PORT:
1357         case SEC_CTRL_PORT:
1358         case PRI_CMD_PORT:
1359         case SEC_CMD_PORT:
1360             // Something about lowering interrupts here....
1361             *(uint8_t *)dst = channel->status.val;
1362             break;
1363
1364         default:
1365             PrintError("Invalid Port: %x\n", port);
1366             return -1;
1367     }
1368
1369     PrintDebug("\tVal=%x\n", *(uint8_t *)dst);
1370
1371     return length;
1372 }
1373
1374
1375
1376 static void init_drive(struct ide_drive * drive) {
1377
1378     drive->sector_count = 0x01;
1379     drive->sector_num = 0x01;
1380     drive->cylinder = 0x0000;
1381
1382     drive->drive_type = BLOCK_NONE;
1383
1384     memset(drive->model, 0, sizeof(drive->model));
1385
1386     drive->transfer_index = 0;
1387     drive->transfer_length = 0;
1388     memset(drive->data_buf, 0, sizeof(drive->data_buf));
1389
1390     drive->num_cylinders = 0;
1391     drive->num_heads = 0;
1392     drive->num_sectors = 0;
1393     
1394
1395     drive->private_data = NULL;
1396     drive->ops = NULL;
1397 }
1398
1399 static void init_channel(struct ide_channel * channel) {
1400     int i = 0;
1401
1402     channel->error_reg.val = 0x01;
1403     channel->drive_head.val = 0x00;
1404     channel->status.val = 0x00;
1405     channel->cmd_reg = 0x00;
1406     channel->ctrl_reg.val = 0x08;
1407
1408
1409     channel->dma_cmd.val = 0;
1410     channel->dma_status.val = 0;
1411     channel->dma_prd_addr = 0;
1412     channel->dma_tbl_index = 0;
1413
1414     for (i = 0; i < 2; i++) {
1415         init_drive(&(channel->drives[i]));
1416     }
1417
1418 }
1419
1420
1421 static int pci_config_update(uint_t reg_num, void * src, uint_t length, void * private_data) {
1422     PrintDebug("PCI Config Update\n");
1423     /*
1424     struct ide_internal * ide = (struct ide_internal *)(private_data);
1425
1426     PrintDebug("\t\tInterupt register (Dev=%s), irq=%d\n", ide->ide_pci->name, ide->ide_pci->config_header.intr_line);
1427     */
1428
1429     return 0;
1430 }
1431
1432 static int init_ide_state(struct ide_internal * ide) {
1433     int i;
1434
1435     /* 
1436      * Check if the PIIX 3 actually represents both IDE channels in a single PCI entry 
1437      */
1438
1439     for (i = 0; i < 1; i++) {
1440         init_channel(&(ide->channels[i]));
1441
1442         // JRL: this is a terrible hack...
1443         ide->channels[i].irq = PRI_DEFAULT_IRQ + i;
1444     }
1445
1446
1447     return 0;
1448 }
1449
1450
1451
1452
1453 static int ide_free(struct ide_internal * ide) {
1454
1455     // deregister from PCI?
1456
1457     V3_Free(ide);
1458
1459     return 0;
1460 }
1461
1462
1463 static struct v3_device_ops dev_ops = {
1464     .free = (int (*)(void *))ide_free,
1465
1466 };
1467
1468
1469
1470
1471 static int connect_fn(struct v3_vm_info * vm, 
1472                       void * frontend_data, 
1473                       struct v3_dev_blk_ops * ops, 
1474                       v3_cfg_tree_t * cfg, 
1475                       void * private_data) {
1476     struct ide_internal * ide  = (struct ide_internal *)(frontend_data);  
1477     struct ide_channel * channel = NULL;
1478     struct ide_drive * drive = NULL;
1479
1480     char * bus_str = v3_cfg_val(cfg, "bus_num");
1481     char * drive_str = v3_cfg_val(cfg, "drive_num");
1482     char * type_str = v3_cfg_val(cfg, "type");
1483     char * model_str = v3_cfg_val(cfg, "model");
1484     uint_t bus_num = 0;
1485     uint_t drive_num = 0;
1486
1487
1488     if ((!type_str) || (!drive_str) || (!bus_str)) {
1489         PrintError("Incomplete IDE Configuration\n");
1490         return -1;
1491     }
1492
1493     bus_num = atoi(bus_str);
1494     drive_num = atoi(drive_str);
1495
1496     channel = &(ide->channels[bus_num]);
1497     drive = &(channel->drives[drive_num]);
1498
1499     if (drive->drive_type != BLOCK_NONE) {
1500         PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
1501         return -1;
1502     }
1503
1504     strncpy(drive->model, model_str, sizeof(drive->model) - 1);
1505     
1506     if (strcasecmp(type_str, "cdrom") == 0) {
1507         drive->drive_type = BLOCK_CDROM;
1508
1509         while (strlen((char *)(drive->model)) < 40) {
1510             strcat((char*)(drive->model), " ");
1511         }
1512
1513     } else if (strcasecmp(type_str, "hd") == 0) {
1514         drive->drive_type = BLOCK_DISK;
1515
1516         drive->hd_state.accessed = 0;
1517         drive->hd_state.mult_sector_num = 1;
1518
1519         drive->num_sectors = 63;
1520         drive->num_heads = 16;
1521         drive->num_cylinders = (ops->get_capacity(private_data) / HD_SECTOR_SIZE) / (drive->num_sectors * drive->num_heads);
1522     } else {
1523         PrintError("invalid IDE drive type\n");
1524         return -1;
1525     }
1526  
1527     drive->ops = ops;
1528
1529     if (ide->ide_pci) {
1530         // Hardcode this for now, but its not a good idea....
1531         ide->ide_pci->config_space[0x41 + (bus_num * 2)] = 0x80;
1532     }
1533  
1534     drive->private_data = private_data;
1535
1536     return 0;
1537 }
1538
1539
1540
1541
1542 static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1543     struct ide_internal * ide  = NULL;
1544     char * dev_id = v3_cfg_val(cfg, "ID");
1545     int ret = 0;
1546
1547     PrintDebug("IDE: Initializing IDE\n");
1548
1549     ide = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal));
1550
1551     if (ide == NULL) {
1552         PrintError("Error allocating IDE state\n");
1553         return -1;
1554     }
1555
1556     memset(ide, 0, sizeof(struct ide_internal));
1557
1558     ide->vm = vm;
1559     ide->pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
1560
1561     if (ide->pci_bus != NULL) {
1562         struct vm_device * southbridge = v3_find_dev(vm, v3_cfg_val(cfg, "controller"));
1563
1564         if (!southbridge) {
1565             PrintError("Could not find southbridge\n");
1566             V3_Free(ide);
1567             return -1;
1568         }
1569
1570         ide->southbridge = (struct v3_southbridge *)(southbridge->private_data);
1571     }
1572
1573     PrintDebug("IDE: Creating IDE bus x 2\n");
1574
1575     struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, ide);
1576
1577     if (dev == NULL) {
1578         PrintError("Could not attach device %s\n", dev_id);
1579         V3_Free(ide);
1580         return -1;
1581     }
1582
1583     if (init_ide_state(ide) == -1) {
1584         PrintError("Failed to initialize IDE state\n");
1585         v3_remove_device(dev);
1586         return -1;
1587     }
1588
1589     PrintDebug("Connecting to IDE IO ports\n");
1590
1591     ret |= v3_dev_hook_io(dev, PRI_DATA_PORT, 
1592                           &ide_read_data_port, &write_data_port);
1593     ret |= v3_dev_hook_io(dev, PRI_FEATURES_PORT, 
1594                           &read_port_std, &write_port_std);
1595     ret |= v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, 
1596                           &read_port_std, &write_port_std);
1597     ret |= v3_dev_hook_io(dev, PRI_SECT_NUM_PORT, 
1598                           &read_port_std, &write_port_std);
1599     ret |= v3_dev_hook_io(dev, PRI_CYL_LOW_PORT, 
1600                           &read_port_std, &write_port_std);
1601     ret |= v3_dev_hook_io(dev, PRI_CYL_HIGH_PORT, 
1602                           &read_port_std, &write_port_std);
1603     ret |= v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, 
1604                           &read_port_std, &write_port_std);
1605     ret |= v3_dev_hook_io(dev, PRI_CMD_PORT, 
1606                           &read_port_std, &write_cmd_port);
1607
1608     ret |= v3_dev_hook_io(dev, SEC_DATA_PORT, 
1609                           &ide_read_data_port, &write_data_port);
1610     ret |= v3_dev_hook_io(dev, SEC_FEATURES_PORT, 
1611                           &read_port_std, &write_port_std);
1612     ret |= v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, 
1613                           &read_port_std, &write_port_std);
1614     ret |= v3_dev_hook_io(dev, SEC_SECT_NUM_PORT, 
1615                           &read_port_std, &write_port_std);
1616     ret |= v3_dev_hook_io(dev, SEC_CYL_LOW_PORT, 
1617                           &read_port_std, &write_port_std);
1618     ret |= v3_dev_hook_io(dev, SEC_CYL_HIGH_PORT, 
1619                           &read_port_std, &write_port_std);
1620     ret |= v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, 
1621                           &read_port_std, &write_port_std);
1622     ret |= v3_dev_hook_io(dev, SEC_CMD_PORT, 
1623                           &read_port_std, &write_cmd_port);
1624   
1625
1626     ret |= v3_dev_hook_io(dev, PRI_CTRL_PORT, 
1627                           &read_port_std, &write_port_std);
1628
1629     ret |= v3_dev_hook_io(dev, SEC_CTRL_PORT, 
1630                           &read_port_std, &write_port_std);
1631   
1632
1633     ret |= v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, 
1634                           &read_port_std, &write_port_std);
1635
1636     ret |= v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, 
1637                           &read_port_std, &write_port_std);
1638
1639
1640     if (ret != 0) {
1641         PrintError("Error hooking IDE IO port\n");
1642         v3_remove_device(dev);
1643         return -1;
1644     }
1645
1646
1647     if (ide->pci_bus) {
1648         struct v3_pci_bar bars[6];
1649         struct v3_southbridge * southbridge = (struct v3_southbridge *)(ide->southbridge);
1650         struct pci_device * sb_pci = (struct pci_device *)(southbridge->southbridge_pci);
1651         struct pci_device * pci_dev = NULL;
1652         int i;
1653
1654         PrintDebug("Connecting IDE to PCI bus\n");
1655
1656         for (i = 0; i < 6; i++) {
1657             bars[i].type = PCI_BAR_NONE;
1658         }
1659
1660         bars[4].type = PCI_BAR_IO;
1661         //      bars[4].default_base_port = PRI_DEFAULT_DMA_PORT;
1662         bars[4].default_base_port = -1;
1663         bars[4].num_ports = 16;
1664
1665         bars[4].io_read = read_dma_port;
1666         bars[4].io_write = write_dma_port;
1667         bars[4].private_data = ide;
1668
1669         pci_dev = v3_pci_register_device(ide->pci_bus, PCI_STD_DEVICE, 0, sb_pci->dev_num, 1, 
1670                                          "PIIX3_IDE", bars,
1671                                          pci_config_update, NULL, NULL, ide);
1672
1673         if (pci_dev == NULL) {
1674             PrintError("Failed to register IDE BUS %d with PCI\n", i); 
1675             v3_remove_device(dev);
1676             return -1;
1677         }
1678
1679         /* This is for CMD646 devices 
1680            pci_dev->config_header.vendor_id = 0x1095;
1681            pci_dev->config_header.device_id = 0x0646;
1682            pci_dev->config_header.revision = 0x8f07;
1683         */
1684
1685         pci_dev->config_header.vendor_id = 0x8086;
1686         pci_dev->config_header.device_id = 0x7010;
1687         pci_dev->config_header.revision = 0x00;
1688
1689         pci_dev->config_header.prog_if = 0x80; // Master IDE device
1690         pci_dev->config_header.subclass = PCI_STORAGE_SUBCLASS_IDE;
1691         pci_dev->config_header.class = PCI_CLASS_STORAGE;
1692
1693         pci_dev->config_header.command = 0;
1694         pci_dev->config_header.status = 0x0280;
1695
1696         ide->ide_pci = pci_dev;
1697
1698
1699     }
1700
1701     if (v3_dev_add_blk_frontend(vm, dev_id, connect_fn, (void *)ide) == -1) {
1702         PrintError("Could not register %s as frontend\n", dev_id);
1703         v3_remove_device(dev);
1704         return -1;
1705     }
1706     
1707
1708     PrintDebug("IDE Initialized\n");
1709
1710     return 0;
1711 }
1712
1713
1714 device_register("IDE", ide_init)
1715
1716
1717
1718
1719 int v3_ide_get_geometry(void * ide_data, int channel_num, int drive_num, 
1720                         uint32_t * cylinders, uint32_t * heads, uint32_t * sectors) {
1721
1722     struct ide_internal * ide  = ide_data;  
1723     struct ide_channel * channel = &(ide->channels[channel_num]);
1724     struct ide_drive * drive = &(channel->drives[drive_num]);
1725     
1726     if (drive->drive_type == BLOCK_NONE) {
1727         return -1;
1728     }
1729
1730     *cylinders = drive->num_cylinders;
1731     *heads = drive->num_heads;
1732     *sectors = drive->num_sectors;
1733
1734     return 0;
1735 }