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.


huge update for merge
[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     // enable DMA access
60     drive_id->dma_enable = 1;
61
62     // enable LBA access
63     drive_id->lba_enable = 1;
64     
65     // Drive Capacity (28 bit LBA)
66     drive_id->lba_capacity = drive->hd_ops->get_capacity(drive->private_data);
67     
68     // Drive Capacity (48 bit LBA)
69     drive_id->lba_capacity_2 = drive->hd_ops->get_capacity(drive->private_data);
70
71     // lower byte is the maximum multiple sector size...
72     drive_id->rw_multiples = 0x8000 | MAX_MULT_SECTORS;
73
74     // words 64-70, 54-58 valid
75     drive_id->field_valid = 0x0007; // DMA + pkg cmd valid
76
77     // copied from CFA540A
78     drive_id->buf[63] = 0x0103; // variable (DMA stuff)
79     //drive_id->buf[63] = 0x0000; // variable (DMA stuff)
80     
81     //    drive_id->buf[64] = 0x0001; // PIO
82     drive_id->buf[65] = 0x00b4;
83     drive_id->buf[66] = 0x00b4;
84     drive_id->buf[67] = 0x012c;
85     drive_id->buf[68] = 0x00b4;
86
87     drive_id->buf[71] = 30; // faked
88     drive_id->buf[72] = 30; // faked
89
90     //    drive_id->buf[80] = 0x1e; // supports up to ATA/ATAPI-4
91     drive_id->major_rev_num = 0x0040; // supports up to ATA/ATAPI-6
92
93     drive_id->buf[83] |= 0x0400; // supports 48 bit LBA
94
95
96     drive_id->dma_ultra = 0x2020; // Ultra_DMA_Mode_5_Selected | Ultra_DMA_Mode_5_Supported;
97 }
98
99
100 static int ata_read(struct vm_device * dev, struct ide_channel * channel, uint8_t * dst, uint_t sect_cnt) {
101     struct ide_drive * drive = get_selected_drive(channel);
102
103     if (drive->hd_state.accessed == 0) {
104         drive->current_lba = 0;
105         drive->hd_state.accessed = 1;
106     }
107
108     int ret = drive->hd_ops->read(dst, sect_cnt, drive->current_lba, drive->private_data);
109     
110     if (ret == -1) {
111         PrintError("IDE: Error reading HD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba));
112         return -1;
113     }
114
115     return 0;
116 }
117
118
119
120 // 28 bit LBA
121 static int ata_read_sectors(struct vm_device * dev, struct ide_channel * channel) {
122     struct ide_drive * drive = get_selected_drive(channel);
123     // The if the sector count == 0 then read 256 sectors (cast up to handle that value)
124     uint32_t sect_cnt = (drive->sector_count == 0) ? 256 : drive->sector_count;
125
126     union {
127         uint32_t addr;
128         uint8_t buf[4];
129     } __attribute__((packed)) lba_addr;
130
131     /* LBA addr bits:
132        0-8: sector number reg  (drive->lba0)
133        8-16: low cylinder reg (drive->lba1)
134        16-24: high cylinder reg (drive->lba2)
135        24-28:  low 4 bits of drive_head reg (channel->drive_head.head_num)
136      */
137
138     lba_addr.buf[0] = drive->lba0;
139     lba_addr.buf[1] = drive->lba1;
140     lba_addr.buf[2] = drive->lba2;
141     lba_addr.buf[3] = channel->drive_head.lba3;
142
143
144     if (lba_addr.addr + (sect_cnt * IDE_SECTOR_SIZE) > 
145         drive->hd_ops->get_capacity(drive->private_data)) {
146         PrintError("IDE: request size exceeds disk capacity (lba=%d) (sect_cnt=%d) (ReadEnd=%d) (capacity=%p)\n", 
147                    lba_addr.addr, sect_cnt, 
148                    lba_addr.addr + (sect_cnt * IDE_SECTOR_SIZE),
149                    (void *)(addr_t)(drive->hd_ops->get_capacity(drive->private_data)));
150         ide_abort_command(dev, channel);
151         return 0;
152     }
153
154     drive->current_lba = lba_addr.addr;
155     
156     if (ata_read(dev, channel, drive->data_buf, 1) == -1) {
157         PrintError("Could not read disk sector\n");
158         return -1;
159     }
160
161     drive->transfer_length = sect_cnt * IDE_SECTOR_SIZE;
162     drive->transfer_index = 0;
163
164     channel->status.busy = 0;
165     channel->status.ready = 0;
166     channel->status.write_fault = 0;
167     channel->status.data_req = 1;
168     channel->status.error = 0;
169
170     drive->irq_flags.io_dir = 1;
171     drive->irq_flags.c_d = 0;
172     drive->irq_flags.rel = 0;
173
174
175     ide_raise_irq(dev, channel);
176
177     PrintDebug("Returning from read sectors\n");
178
179     return 0;
180 }
181
182
183 // 48 bit LBA
184 static int ata_read_sectors_ext(struct vm_device * dev, struct ide_channel * channel) {
185     //struct ide_drive * drive = get_selected_drive(channel);
186     // The if the sector count == 0 then read 256 sectors (cast up to handle that value)
187     //uint32_t sector_count = (drive->sector_count == 0) ? 256 : drive->sector_count;
188
189     PrintError("Extended Sector read not implemented\n");
190
191     return -1;
192 }