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.


getting things working again
[palacios.git] / palacios / src / devices / ata.h
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 #define MAX_MULT_SECTORS  255
21
22
23 static void ata_identify_device(struct ide_drive * drive) {
24     struct ide_drive_id * drive_id = (struct ide_drive_id *)(drive->data_buf);
25     const char* serial_number = " VT00001\0\0\0\0\0\0\0\0\0\0\0\0";
26     const char* firmware = "ALPHA1  ";
27
28     drive->transfer_length = 512;
29     drive->transfer_index = 0;
30
31
32     memset(drive_id->buf, 0, sizeof(drive_id->buf));
33
34     drive_id->fixed_drive = 1;
35     drive_id->removable_media = 0;
36
37     // Black magic...
38     drive_id->disk_speed1 = 1;
39     drive_id->disk_speed3 = 1;
40
41     drive_id->cdrom_flag = 0;
42
43     // Make it the simplest drive possible (1 head, 1 cyl, 1 sect/track)
44     drive_id->num_cylinders = 1;
45     drive_id->num_heads = 1;
46     drive_id->bytes_per_track = IDE_SECTOR_SIZE;
47     drive_id->bytes_per_sector = IDE_SECTOR_SIZE;
48     drive_id->sectors_per_track = 1;
49
50
51     // These buffers do not contain a terminating "\0"
52     memcpy(drive_id->serial_num, serial_number, strlen(serial_number));
53     memcpy(drive_id->firmware_rev, firmware, strlen(firmware));
54     memcpy(drive_id->model_num, drive->model, 40);
55
56     // 32 bits access
57     drive_id->dword_io = 1;
58
59 #if 0
60     // enable DMA access
61     drive_id->dma_enable = 1;
62 #endif
63     // enable LBA access
64     drive_id->lba_enable = 1;
65     
66     // Drive Capacity (28 bit LBA)
67     drive_id->lba_capacity = drive->hd_ops->get_capacity(drive->private_data);
68     
69     // Drive Capacity (48 bit LBA)
70     drive_id->lba_capacity_2 = drive->hd_ops->get_capacity(drive->private_data);
71
72 #if 0
73     // lower byte is the maximum multiple sector size...
74     drive_id->rw_multiples = 0x8000 | MAX_MULT_SECTORS;
75 #endif
76
77 #if 0
78     // words 64-70, 54-58 valid
79     drive_id->field_valid = 0x0007; // DMA + pkg cmd valid
80 #endif
81
82     // copied from CFA540A
83     drive_id->buf[63] = 0x0103; // variable (DMA stuff)
84     //drive_id->buf[63] = 0x0000; // variable (DMA stuff)
85     
86     //    drive_id->buf[64] = 0x0001; // PIO
87     drive_id->buf[65] = 0x00b4;
88     drive_id->buf[66] = 0x00b4;
89     drive_id->buf[67] = 0x012c;
90     drive_id->buf[68] = 0x00b4;
91
92     drive_id->buf[71] = 30; // faked
93     drive_id->buf[72] = 30; // faked
94
95     //    drive_id->buf[80] = 0x1e; // supports up to ATA/ATAPI-4
96     drive_id->major_rev_num = 0x0040; // supports up to ATA/ATAPI-6
97
98 #if 0
99     drive_id->buf[83] |= 0x0400; // supports 48 bit LBA
100
101
102     drive_id->dma_ultra = 0x2020; // Ultra_DMA_Mode_5_Selected | Ultra_DMA_Mode_5_Supported;
103 #endif
104 }
105
106
107 static int ata_read(struct vm_device * dev, struct ide_channel * channel, uint8_t * dst, uint_t sect_cnt) {
108     struct ide_drive * drive = get_selected_drive(channel);
109
110     if (drive->hd_state.accessed == 0) {
111         drive->current_lba = 0;
112         drive->hd_state.accessed = 1;
113     }
114
115     int ret = drive->hd_ops->read(dst, sect_cnt, drive->current_lba, drive->private_data);
116     
117     if (ret == -1) {
118         PrintError("IDE: Error reading HD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba));
119         return -1;
120     }
121
122     return 0;
123 }
124
125
126
127 // 28 bit LBA
128 static int ata_read_sectors(struct vm_device * dev, struct ide_channel * channel) {
129     struct ide_drive * drive = get_selected_drive(channel);
130     // The if the sector count == 0 then read 256 sectors (cast up to handle that value)
131     uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
132
133     union {
134         uint32_t addr;
135         uint8_t buf[4];
136     } __attribute__((packed)) lba_addr;
137
138     /* LBA addr bits:
139        0-8: sector number reg  (drive->lba0)
140        8-16: low cylinder reg (drive->lba1)
141        16-24: high cylinder reg (drive->lba2)
142        24-28:  low 4 bits of drive_head reg (channel->drive_head.head_num)
143      */
144
145     lba_addr.buf[0] = drive->lba0;
146     lba_addr.buf[1] = drive->lba1;
147     lba_addr.buf[2] = drive->lba2;
148     lba_addr.buf[3] = channel->drive_head.lba3;
149
150
151     if (lba_addr.addr + (sect_cnt * IDE_SECTOR_SIZE) > 
152         drive->hd_ops->get_capacity(drive->private_data)) {
153         PrintError("IDE: request size exceeds disk capacity (lba=%d) (sect_cnt=%d) (ReadEnd=%d) (capacity=%p)\n", 
154                    lba_addr.addr, sect_cnt, 
155                    lba_addr.addr + (sect_cnt * IDE_SECTOR_SIZE),
156                    (void *)(addr_t)(drive->hd_ops->get_capacity(drive->private_data)));
157         ide_abort_command(dev, channel);
158         return 0;
159     }
160
161     drive->current_lba = lba_addr.addr;
162     
163     if (ata_read(dev, channel, drive->data_buf, 1) == -1) {
164         PrintError("Could not read disk sector\n");
165         return -1;
166     }
167
168     drive->transfer_length = sect_cnt * IDE_SECTOR_SIZE;
169     drive->transfer_index = 0;
170
171     channel->status.busy = 0;
172     channel->status.ready = 0;
173     channel->status.write_fault = 0;
174     channel->status.data_req = 1;
175     channel->status.error = 0;
176
177     drive->irq_flags.io_dir = 1;
178     drive->irq_flags.c_d = 0;
179     drive->irq_flags.rel = 0;
180
181
182     ide_raise_irq(dev, channel);
183
184     PrintDebug("Returning from read sectors\n");
185
186     return 0;
187 }
188
189
190 // 48 bit LBA
191 static int ata_read_sectors_ext(struct vm_device * dev, struct ide_channel * channel) {
192     //struct ide_drive * drive = get_selected_drive(channel);
193     // The if the sector count == 0 then read 256 sectors (cast up to handle that value)
194     //uint32_t sector_count = (drive->sector_count == 0) ? 256 : drive->sector_count;
195
196     PrintError("Extended Sector read not implemented\n");
197
198     return -1;
199 }