Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


IDE / ATA rewrites (1st step)
[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 #ifndef _DEVICES_ATA_H_
21 #define _DEVICES_ATA_H_
22
23 #define MAX_MULT_SECTORS  255
24
25
26 static void ata_identify_device(struct ide_drive * drive) {
27     struct ide_drive_id * drive_id = (struct ide_drive_id *)(drive->data_buf);
28     const char* serial_number = " VT00001\0\0\0\0\0\0\0\0\0\0\0\0";
29     const char* firmware = "ALPHA1  ";
30
31     drive->transfer_length = 512;
32     drive->transfer_index = 0;
33
34
35     memset(drive_id->buf, 0, sizeof(drive_id->buf));
36
37     drive_id->fixed_drive = 1;
38     drive_id->removable_media = 0;
39
40     // Black magic...
41     drive_id->disk_speed1 = 1;
42     drive_id->disk_speed3 = 1;
43
44     drive_id->cdrom_flag = 0;
45
46     drive_id->num_cylinders = drive->num_cylinders;
47     drive_id->num_heads = drive->num_heads;
48     drive_id->bytes_per_track = drive->num_sectors * HD_SECTOR_SIZE;
49     drive_id->bytes_per_sector = HD_SECTOR_SIZE;
50     drive_id->sectors_per_track = drive->num_sectors;
51
52
53     // These buffers do not contain a terminating "\0"
54     memcpy(drive_id->serial_num, serial_number, strlen(serial_number));
55     memcpy(drive_id->firmware_rev, firmware, strlen(firmware));
56     memcpy(drive_id->model_num, drive->model, 40);
57
58     // 32 bits access
59     drive_id->dword_io = 1;
60
61
62     // enable DMA access
63     // PAD disable DMA capability
64     drive_id->dma_enable = 0; // 1;
65
66     // enable LBA access
67     drive_id->lba_enable = 1;
68     
69     // Drive Capacity (28 bit LBA)
70     drive_id->lba_capacity = drive->ops->get_capacity(drive->private_data) / HD_SECTOR_SIZE;
71     
72     // Drive Capacity (48 bit LBA)
73     drive_id->lba_capacity_2 = drive->ops->get_capacity(drive->private_data) / HD_SECTOR_SIZE;
74
75
76     // lower byte is the maximum multiple sector size...
77     drive_id->rw_multiples = 0x8000 | MAX_MULT_SECTORS;
78
79
80     // words 64-70, 54-58 valid
81     drive_id->field_valid = 0x0007; // DMA + pkg cmd valid
82
83
84     // copied from CFA540A
85     // drive_id->buf[63] = 0x0103; // variable (DMA stuff)
86     //drive_id->buf[63] = 0x0000; // variable (DMA stuff)
87     // 0x0007 => MWDMA modes 0..2 supported - none selected
88     drive_id->buf[63] = 0x0007;
89
90     
91     // PAD: Support PIO mode 0
92     drive_id->buf[64] = 0x0001; // PIO
93
94     // MWDMA transfer min cycle time
95     drive_id->buf[65] = 0x00b4;
96     // MWDMA transfer time recommended
97     drive_id->buf[66] = 0x00b4;
98     // minimum pio transfer time without flow control
99     drive_id->buf[67] = 0x012c;
100     // minimum pio transfer time with IORDY flow control
101     drive_id->buf[68] = 0x00b4;
102
103     drive_id->buf[71] = 30; // faked
104     drive_id->buf[72] = 30; // faked
105
106     // queue depth set to one
107
108     //    drive_id->buf[80] = 0x1e; // supports up to ATA/ATAPI-4
109     drive_id->major_rev_num = 0x0040; // supports up to ATA/ATAPI-6
110
111
112     drive_id->buf[83] |= 0x0400; // supports 48 bit LBA
113
114     // No special features supported
115
116     // PAD: Disable ultra DMA capability
117     //drive_id->dma_ultra = 0x2020; // Ultra_DMA_Mode_5_Selected | Ultra_DMA_Mode_5_Supported;
118
119 }
120
121
122 static int ata_read(struct ide_internal * ide, struct ide_channel * channel, uint8_t * dst, uint_t sect_cnt) {
123     struct ide_drive * drive = get_selected_drive(channel);
124
125     if (drive->hd_state.accessed == 0) {
126         drive->current_lba = 0;
127         drive->hd_state.accessed = 1;
128     }
129
130     PrintDebug(VM_NONE, VCORE_NONE,"Reading Drive LBA=%d (count=%d)\n", (uint32_t)(drive->current_lba), sect_cnt);
131
132     int ret = drive->ops->read(dst, drive->current_lba * HD_SECTOR_SIZE, sect_cnt * HD_SECTOR_SIZE, drive->private_data);
133     
134     if (ret == -1) {
135         PrintError(VM_NONE, VCORE_NONE,"IDE: Error reading HD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba));
136         return -1;
137     }
138
139     return 0;
140 }
141
142
143
144 static int ata_write(struct ide_internal * ide, struct ide_channel * channel, uint8_t * src, uint_t sect_cnt) {
145     struct ide_drive * drive = get_selected_drive(channel);
146
147     if (drive->hd_state.accessed == 0) {
148         PrintError(VM_NONE,VCORE_NONE,"Reseting lba...\n");
149         drive->current_lba = 0;
150         drive->hd_state.accessed = 1;
151     }
152
153     PrintDebug(VM_NONE, VCORE_NONE,"Writing Drive LBA=%d (count=%d)\n", (uint32_t)(drive->current_lba), sect_cnt);
154
155     int ret = drive->ops->write(src, drive->current_lba * HD_SECTOR_SIZE, sect_cnt * HD_SECTOR_SIZE, drive->private_data);
156
157     if (ret == -1) {
158         PrintError(VM_NONE, VCORE_NONE,"IDE: Error writing HD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba));
159         return -1;
160     }
161
162     return 0;
163 }
164
165
166
167 static int ata_get_lba(struct ide_internal * ide, struct ide_channel * channel, uint64_t * lba) {
168     struct ide_drive * drive = get_selected_drive(channel);
169     // The if the sector count == 0 then read 256 sectors (cast up to handle that value)
170     uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
171
172     if (is_lba_enabled(channel)) { 
173         union {
174             uint32_t addr;
175             uint8_t buf[4];
176         } __attribute__((packed)) lba_addr;
177         
178         /* LBA addr bits:
179            0-8: sector number reg  (drive->lba0)
180            8-16: low cylinder reg (drive->lba1)
181            16-24: high cylinder reg (drive->lba2)
182            24-28:  low 4 bits of drive_head reg (channel->drive_head.head_num)
183         */
184         
185         
186         lba_addr.buf[0] = drive->lba0;
187         lba_addr.buf[1] = drive->lba1;
188         lba_addr.buf[2] = drive->lba2;
189         lba_addr.buf[3] = channel->drive_head.lba3;
190         
191         *lba = lba_addr.addr;
192
193         PrintDebug(VM_NONE,VCORE_NONE,"get_lba: lba0=%u (sect), lba1=%u (cyllow), lba2=%u (cylhigh), lba3=%d (head) => lba=%llu\n", drive->lba0, drive->lba1, drive->lba2, channel->drive_head.lba3, *lba);
194
195     } else {
196         // we are in CHS mode....
197
198         *lba = 
199             (drive->cylinder * drive->num_heads + 
200              channel->drive_head.head_num) * drive->num_sectors +
201             // sector number is 1 based
202             (drive->sector_num - 1);
203         
204         
205         PrintDebug(VM_NONE,VCORE_NONE,"get_lba: Huh, 1995 has returned - CHS (%u,%u,%u) addressing on drive of (%u,%u,%u) translated as %llu....\n", 
206                  drive->cylinder, channel->drive_head.head_num, drive->sector_num,
207                  drive->num_cylinders, drive->num_heads, drive->num_sectors, *lba );
208     }
209         
210     if ((*lba + sect_cnt) > 
211         drive->ops->get_capacity(drive->private_data) / HD_SECTOR_SIZE) {
212         PrintError(VM_NONE, VCORE_NONE,"IDE: request size exceeds disk capacity (lba=%llu) (sect_cnt=%u) (ReadEnd=%llu) (capacity=%llu)\n", 
213                    *lba, sect_cnt, 
214                    *lba + (sect_cnt * HD_SECTOR_SIZE),
215                    drive->ops->get_capacity(drive->private_data));
216         return -1;
217     }
218     
219     return 0;
220 }
221
222
223 // 28 bit LBA
224 static int ata_write_sectors(struct ide_internal * ide,  struct ide_channel * channel) {
225     struct ide_drive * drive = get_selected_drive(channel);
226     uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
227
228     if (ata_get_lba(ide, channel, &(drive->current_lba)) == -1) {
229         PrintError(VM_NONE,VCORE_NONE,"Cannot get lba\n");
230         ide_abort_command(ide, channel);
231         return 0;
232     }
233
234     PrintDebug(VM_NONE,VCORE_NONE,"ata write sectors: lba=%llu sect_cnt=%u\n", drive->current_lba, sect_cnt);
235
236     drive->transfer_length = sect_cnt * HD_SECTOR_SIZE ;
237     drive->transfer_index = 0;
238     channel->status.busy = 0;
239     channel->status.ready = 0;
240     channel->status.write_fault = 0;
241     channel->status.data_req = 1;
242     channel->status.error = 0;
243
244     PrintDebug(VM_NONE, VCORE_NONE, "IDE: Returning from write sectors\n");
245
246     return 0;
247 }
248
249
250 // 28 bit LBA
251 static int ata_read_sectors(struct ide_internal * ide,  struct ide_channel * channel) {
252     struct ide_drive * drive = get_selected_drive(channel);
253     // The if the sector count == 0 then read 256 sectors (cast up to handle that value)
254     uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
255
256     if (ata_get_lba(ide, channel, &(drive->current_lba)) == -1) {
257         PrintError(VM_NONE,VCORE_NONE,"Cannot get lba\n");
258         ide_abort_command(ide, channel);
259         return 0;
260     }
261
262     
263     if (ata_read(ide, channel, drive->data_buf, 1) == -1) {
264         PrintError(VM_NONE, VCORE_NONE,"Could not read disk sector\n");
265         return -1;
266     }
267
268     drive->transfer_length = sect_cnt * HD_SECTOR_SIZE;
269     drive->transfer_index = 0;
270
271     channel->status.busy = 0;
272     channel->status.ready = 0;
273     channel->status.write_fault = 0;
274     channel->status.data_req = 1;
275     channel->status.error = 0;
276
277     ide_raise_irq(ide, channel);
278
279     PrintDebug(VM_NONE, VCORE_NONE,"Returning from read sectors\n");
280
281     return 0;
282 }
283
284
285 // 48 bit LBA
286 static int ata_read_sectors_ext(struct ide_internal * ide, struct ide_channel * channel) {
287     //struct ide_drive * drive = get_selected_drive(channel);
288     // The if the sector count == 0 then read 256 sectors (cast up to handle that value)
289     //uint32_t sector_count = (drive->sector_count == 0) ? 256 : drive->sector_count;
290
291     PrintError(VM_NONE, VCORE_NONE, "Extended Sector read not implemented\n");
292
293     return -1;
294 }
295
296 /* ATA COMMANDS as per */
297 /* ACS-2 T13/2015-D Table B.2 Command codes */
298 #define ATA_NOP                         0x00
299 #define CFA_REQ_EXT_ERROR_CODE          0x03 
300 #define ATA_DSM                         0x06
301 #define ATA_DEVICE_RESET                0x08
302 #define ATA_RECAL                       0x10 
303 #define ATA_READ                        0x20 
304 #define ATA_READ_ONCE                   0x21 
305 #define ATA_READ_EXT                    0x24 
306 #define ATA_READDMA_EXT                 0x25 
307 #define ATA_READDMA_QUEUED_EXT          0x26 
308 #define ATA_READ_NATIVE_MAX_EXT         0x27 
309 #define ATA_MULTREAD_EXT                0x29 
310 #define ATA_WRITE                       0x30 
311 #define ATA_WRITE_ONCE                  0x31 
312 #define ATA_WRITE_EXT                   0x34 
313 #define ATA_WRITEDMA_EXT                0x35 
314 #define ATA_WRITEDMA_QUEUED_EXT         0x36 
315 #define ATA_SET_MAX_EXT                 0x37 
316 #define ATA_SET_MAX_EXT                 0x37 
317 #define CFA_WRITE_SECT_WO_ERASE         0x38 
318 #define ATA_MULTWRITE_EXT               0x39 
319 #define ATA_WRITE_VERIFY                0x3C 
320 #define ATA_VERIFY                      0x40 
321 #define ATA_VERIFY_ONCE                 0x41 
322 #define ATA_VERIFY_EXT                  0x42 
323 #define ATA_SEEK                        0x70 
324 #define CFA_TRANSLATE_SECTOR            0x87 
325 #define ATA_DIAGNOSE                    0x90
326 #define ATA_SPECIFY                     0x91 
327 #define ATA_DOWNLOAD_MICROCODE          0x92
328 #define ATA_STANDBYNOW2                 0x94 
329 #define ATA_IDLEIMMEDIATE2              0x95 
330 #define ATA_STANDBY2                    0x96 
331 #define ATA_SETIDLE2                    0x97 
332 #define ATA_CHECKPOWERMODE2             0x98 
333 #define ATA_SLEEPNOW2                   0x99 
334 #define ATA_PACKETCMD                   0xA0 
335 #define ATA_PIDENTIFY                   0xA1 
336 #define ATA_QUEUED_SERVICE              0xA2 
337 #define ATA_SMART                       0xB0 
338 #define CFA_ACCESS_METADATA_STORAGE     0xB8
339 #define CFA_ERASE_SECTORS               0xC0 
340 #define ATA_MULTREAD                    0xC4 
341 #define ATA_MULTWRITE                   0xC5 
342 #define ATA_SETMULT                     0xC6 
343 #define ATA_READDMA                     0xC8 
344 #define ATA_READDMA_ONCE                0xC9 
345 #define ATA_WRITEDMA                    0xCA 
346 #define ATA_WRITEDMA_ONCE               0xCB 
347 #define ATA_WRITEDMA_QUEUED             0xCC 
348 #define CFA_WRITE_MULTI_WO_ERASE        0xCD 
349 #define ATA_GETMEDIASTATUS              0xDA 
350 #define ATA_DOORLOCK                    0xDE 
351 #define ATA_DOORUNLOCK                  0xDF 
352 #define ATA_STANDBYNOW1                 0xE0
353 #define ATA_IDLEIMMEDIATE               0xE1 
354 #define ATA_STANDBY                     0xE2 
355 #define ATA_SETIDLE1                    0xE3
356 #define ATA_READ_BUFFER                 0xE4 
357 #define ATA_CHECKPOWERMODE1             0xE5
358 #define ATA_SLEEPNOW1                   0xE6
359 #define ATA_FLUSH_CACHE                 0xE7
360 #define ATA_WRITE_BUFFER                0xE8 
361 #define ATA_FLUSH_CACHE_EXT             0xEA 
362 #define ATA_IDENTIFY                    0xEC 
363 #define ATA_MEDIAEJECT                  0xED 
364 #define ATA_SETFEATURES                 0xEF 
365 #define IBM_SENSE_CONDITION             0xF0 
366 #define ATA_SECURITY_SET_PASS           0xF1
367 #define ATA_SECURITY_UNLOCK             0xF2
368 #define ATA_SECURITY_ERASE_PREPARE      0xF3
369 #define ATA_SECURITY_ERASE_UNIT         0xF4
370 #define ATA_SECURITY_FREEZE_LOCK        0xF5
371 #define CFA_WEAR_LEVEL                  0xF5 
372 #define ATA_SECURITY_DISABLE            0xF6
373
374 #endif