Added geometry-guessing code based on the partition table
[people/xl0/gpxe.git] / src / arch / i386 / include / int13.h
1 #ifndef INT13_H
2 #define INT13_H
3
4 /** @file
5  *
6  * INT 13 emulation
7  *
8  */
9
10 #include <stdint.h>
11 #include <gpxe/list.h>
12
13 struct block_device;
14
15 /**
16  * @defgroup int13ops INT 13 operation codes
17  * @{
18  */
19
20 /** Reset disk system */
21 #define INT13_RESET                     0x00
22 /** Get status of last operation */
23 #define INT13_GET_LAST_STATUS           0x01
24 /** Read sectors */
25 #define INT13_READ_SECTORS              0x02
26 /** Write sectors */
27 #define INT13_WRITE_SECTORS             0x03
28 /** Get drive parameters */
29 #define INT13_GET_PARAMETERS            0x08
30 /** Get disk type */
31 #define INT13_GET_DISK_TYPE             0x15
32 /** Extensions installation check */
33 #define INT13_EXTENSION_CHECK           0x41
34 /** Extended read */
35 #define INT13_EXTENDED_READ             0x42
36 /** Extended write */
37 #define INT13_EXTENDED_WRITE            0x43
38 /** Get extended drive parameters */
39 #define INT13_GET_EXTENDED_PARAMETERS   0x48
40
41 /** @} */
42
43 /**
44  * @defgroup int13status INT 13 status codes
45  * @{
46  */
47
48 /** Operation completed successfully */
49 #define INT13_STATUS_SUCCESS            0x00
50 /** Invalid function or parameter */
51 #define INT13_STATUS_INVALID            0x01
52 /** Read error */
53 #define INT13_STATUS_READ_ERROR         0x04
54 /** Write error */
55 #define INT13_STATUS_WRITE_ERROR        0xcc
56
57 /** @} */
58
59 /** Block size for non-extended INT 13 calls */
60 #define INT13_BLKSIZE 512
61
62 /** An INT 13 emulated drive */
63 struct int13_drive {
64         /** List of all registered drives */
65         struct list_head list;
66
67         /** Underlying block device */
68         struct block_device *blockdev;
69
70         /** BIOS drive number (0x80-0xff) */
71         unsigned int drive;
72         /** Number of cylinders
73          *
74          * The cylinder number field in an INT 13 call is ten bits
75          * wide, giving a maximum of 1024 cylinders.  Conventionally,
76          * when the 7.8GB limit of a CHS address is exceeded, it is
77          * the number of cylinders that is increased beyond the
78          * addressable limit.
79          */
80         unsigned int cylinders;
81         /** Number of heads
82          *
83          * The head number field in an INT 13 call is eight bits wide,
84          * giving a maximum of 256 heads.  However, apparently all
85          * versions of MS-DOS up to and including Win95 fail with 256
86          * heads, so the maximum encountered in practice is 255.
87          */
88         unsigned int heads;
89         /** Number of sectors per track
90          *
91          * The sector number field in an INT 13 call is six bits wide,
92          * giving a maximum of 63 sectors, since sector numbering
93          * (unlike head and cylinder numbering) starts at 1, not 0.
94          */
95         unsigned int sectors_per_track;
96
97         /** Status of last operation */
98         int last_status;
99 };
100
101 /** An INT 13 disk address packet */
102 struct int13_disk_address {
103         /** Size of the packet, in bytes */
104         uint8_t bufsize;
105         /** Reserved, must be zero */
106         uint8_t reserved;
107         /** Block count */
108         uint16_t count;
109         /** Data buffer */
110         struct segoff buffer;
111         /** Starting block number */
112         uint64_t lba;
113         /** Data buffer (EDD-3.0 only) */
114         uint64_t buffer_phys;
115 };
116
117 /** INT 13 disk parameters */
118 struct int13_disk_parameters {
119         /** Size of this structure */
120         uint16_t bufsize;
121         /** Flags */
122         uint16_t flags;
123         /** Number of cylinders */
124         uint32_t cylinders;
125         /** Number of heads */
126         uint32_t heads;
127         /** Number of sectors per track */
128         uint32_t sectors_per_track;
129         /** Total number of sectors on drive */
130         uint64_t sectors;
131         /** Bytes per sector */
132         uint16_t sector_size;
133         
134 };
135
136 /**
137  * @defgroup int13types INT 13 disk types
138  * @{
139  */
140
141 /** No such drive */
142 #define INT13_DISK_TYPE_NONE    0x00
143 /** Floppy without change-line support */
144 #define INT13_DISK_TYPE_FDD     0x01
145 /** Floppy with change-line support */
146 #define INT13_DISK_TYPE_FDD_CL  0x02
147 /** Hard disk */
148 #define INT13_DISK_TYPE_HDD     0x03
149
150 /** @} */
151
152 /**
153  * @defgroup int13flags INT 13 disk parameter flags
154  * @{
155  */
156
157 /** DMA boundary errors handled transparently */
158 #define INT13_FL_DMA_TRANSPARENT 0x01
159 /** CHS information is valid */
160 #define INT13_FL_CHS_VALID       0x02
161 /** Removable drive */
162 #define INT13_FL_REMOVABLE       0x04
163 /** Write with verify supported */
164 #define INT13_FL_VERIFIABLE      0x08
165 /** Has change-line supported (valid only for removable drives) */
166 #define INT13_FL_CHANGE_LINE     0x10
167 /** Drive can be locked (valid only for removable drives) */
168 #define INT13_FL_LOCKABLE        0x20
169 /** CHS is max possible, not current media (valid only for removable drives) */
170 #define INT13_FL_CHS_MAX         0x40
171
172 /** @} */
173
174 /**
175  * @defgroup int13exts INT 13 extension flags
176  * @{
177  */
178
179 /** Extended disk access functions supported */
180 #define INT13_EXTENSION_LINEAR          0x01
181 /** Removable drive functions supported */
182 #define INT13_EXTENSION_REMOVABLE       0x02
183 /** EDD functions supported */
184 #define INT13_EXTENSION_EDD             0x04
185
186 /** @} */
187
188 /**
189  * @defgroup int13vers INT 13 extension versions
190  * @{
191  */
192
193 /** INT13 extensions version 1.x */
194 #define INT13_EXTENSION_VER_1_X         0x01
195 /** INT13 extensions version 2.0 (EDD-1.0) */
196 #define INT13_EXTENSION_VER_2_0         0x20
197 /** INT13 extensions version 2.1 (EDD-1.1) */
198 #define INT13_EXTENSION_VER_2_1         0x21
199 /** INT13 extensions version 3.0 (EDD-3.0) */
200 #define INT13_EXTENSION_VER_3_0         0x30
201
202 /** @} */ 
203
204 /** A C/H/S address within a partition table entry */
205 struct partition_chs {
206         /** Head number */
207         uint8_t head;
208         /** Sector number, plus high 2 bits of cylinder number */
209         uint8_t cyl_sector;
210         /** Low 8 bits of cylinder number */
211         uint8_t cyl;
212 } __attribute__ (( packed ));
213
214 #define PART_HEAD(chs) ( (chs).head )
215 #define PART_SECTOR(chs) ( (chs).cyl_sector & 0x3f )
216 #define PART_CYLINDER(chs) ( (chs).cyl | ( ( (chs).cyl_sector & 0xc0 ) << 2 ) )
217
218 /** A partition table entry within the MBR */
219 struct partition_table_entry {
220         /** Bootable flag */
221         uint8_t bootable;
222         /** C/H/S start address */
223         struct partition_chs chs_start;
224         /** System indicator (partition type) */
225         uint8_t type;
226         /** C/H/S end address */
227         struct partition_chs chs_end;
228         /** Linear start address */
229         uint32_t start;
230         /** Linear length */
231         uint32_t length;
232 } __attribute__ (( packed ));
233
234 /** A Master Boot Record */
235 struct master_boot_record {
236         uint8_t pad[446];
237         /** Partition table */
238         struct partition_table_entry partitions[4];
239         /** 0x55aa MBR signature */
240         uint16_t signature;
241 } __attribute__ (( packed ));
242
243 extern void register_int13_drive ( struct int13_drive *drive );
244 extern void unregister_int13_drive ( struct int13_drive *drive );
245 extern int int13_boot ( unsigned int drive );
246
247 #endif /* INT13_H */