32ecadc21a9ef4cc36ad15ec11431882e0f3e52d
[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 /** Get CD-ROM status / terminate emulation */
41 #define INT13_CDROM_STATUS_TERMINATE    0x4b
42
43 /** @} */
44
45 /**
46  * @defgroup int13status INT 13 status codes
47  * @{
48  */
49
50 /** Operation completed successfully */
51 #define INT13_STATUS_SUCCESS            0x00
52 /** Invalid function or parameter */
53 #define INT13_STATUS_INVALID            0x01
54 /** Read error */
55 #define INT13_STATUS_READ_ERROR         0x04
56 /** Write error */
57 #define INT13_STATUS_WRITE_ERROR        0xcc
58
59 /** @} */
60
61 /** Block size for non-extended INT 13 calls */
62 #define INT13_BLKSIZE 512
63
64 /** An INT 13 emulated drive */
65 struct int13_drive {
66         /** List of all registered drives */
67         struct list_head list;
68
69         /** Underlying block device */
70         struct block_device *blockdev;
71
72         /** BIOS drive number (0x80-0xff) */
73         unsigned int drive;
74         /** Number of cylinders
75          *
76          * The cylinder number field in an INT 13 call is ten bits
77          * wide, giving a maximum of 1024 cylinders.  Conventionally,
78          * when the 7.8GB limit of a CHS address is exceeded, it is
79          * the number of cylinders that is increased beyond the
80          * addressable limit.
81          */
82         unsigned int cylinders;
83         /** Number of heads
84          *
85          * The head number field in an INT 13 call is eight bits wide,
86          * giving a maximum of 256 heads.  However, apparently all
87          * versions of MS-DOS up to and including Win95 fail with 256
88          * heads, so the maximum encountered in practice is 255.
89          */
90         unsigned int heads;
91         /** Number of sectors per track
92          *
93          * The sector number field in an INT 13 call is six bits wide,
94          * giving a maximum of 63 sectors, since sector numbering
95          * (unlike head and cylinder numbering) starts at 1, not 0.
96          */
97         unsigned int sectors_per_track;
98
99         /** Status of last operation */
100         int last_status;
101 };
102
103 /** An INT 13 disk address packet */
104 struct int13_disk_address {
105         /** Size of the packet, in bytes */
106         uint8_t bufsize;
107         /** Reserved, must be zero */
108         uint8_t reserved;
109         /** Block count */
110         uint16_t count;
111         /** Data buffer */
112         struct segoff buffer;
113         /** Starting block number */
114         uint64_t lba;
115         /** Data buffer (EDD-3.0 only) */
116         uint64_t buffer_phys;
117 };
118
119 /** INT 13 disk parameters */
120 struct int13_disk_parameters {
121         /** Size of this structure */
122         uint16_t bufsize;
123         /** Flags */
124         uint16_t flags;
125         /** Number of cylinders */
126         uint32_t cylinders;
127         /** Number of heads */
128         uint32_t heads;
129         /** Number of sectors per track */
130         uint32_t sectors_per_track;
131         /** Total number of sectors on drive */
132         uint64_t sectors;
133         /** Bytes per sector */
134         uint16_t sector_size;
135         
136 };
137
138 /**
139  * @defgroup int13types INT 13 disk types
140  * @{
141  */
142
143 /** No such drive */
144 #define INT13_DISK_TYPE_NONE    0x00
145 /** Floppy without change-line support */
146 #define INT13_DISK_TYPE_FDD     0x01
147 /** Floppy with change-line support */
148 #define INT13_DISK_TYPE_FDD_CL  0x02
149 /** Hard disk */
150 #define INT13_DISK_TYPE_HDD     0x03
151
152 /** @} */
153
154 /**
155  * @defgroup int13flags INT 13 disk parameter flags
156  * @{
157  */
158
159 /** DMA boundary errors handled transparently */
160 #define INT13_FL_DMA_TRANSPARENT 0x01
161 /** CHS information is valid */
162 #define INT13_FL_CHS_VALID       0x02
163 /** Removable drive */
164 #define INT13_FL_REMOVABLE       0x04
165 /** Write with verify supported */
166 #define INT13_FL_VERIFIABLE      0x08
167 /** Has change-line supported (valid only for removable drives) */
168 #define INT13_FL_CHANGE_LINE     0x10
169 /** Drive can be locked (valid only for removable drives) */
170 #define INT13_FL_LOCKABLE        0x20
171 /** CHS is max possible, not current media (valid only for removable drives) */
172 #define INT13_FL_CHS_MAX         0x40
173
174 /** @} */
175
176 /**
177  * @defgroup int13exts INT 13 extension flags
178  * @{
179  */
180
181 /** Extended disk access functions supported */
182 #define INT13_EXTENSION_LINEAR          0x01
183 /** Removable drive functions supported */
184 #define INT13_EXTENSION_REMOVABLE       0x02
185 /** EDD functions supported */
186 #define INT13_EXTENSION_EDD             0x04
187
188 /** @} */
189
190 /**
191  * @defgroup int13vers INT 13 extension versions
192  * @{
193  */
194
195 /** INT13 extensions version 1.x */
196 #define INT13_EXTENSION_VER_1_X         0x01
197 /** INT13 extensions version 2.0 (EDD-1.0) */
198 #define INT13_EXTENSION_VER_2_0         0x20
199 /** INT13 extensions version 2.1 (EDD-1.1) */
200 #define INT13_EXTENSION_VER_2_1         0x21
201 /** INT13 extensions version 3.0 (EDD-3.0) */
202 #define INT13_EXTENSION_VER_3_0         0x30
203
204 /** @} */ 
205
206 /** Bootable CD-ROM specification packet */
207 struct int13_cdrom_specification {
208         /** Size of packet in bytes */
209         uint8_t size;
210         /** Boot media type */
211         uint8_t media_type;
212         /** Drive number */
213         uint8_t drive;
214         /** CD-ROM controller number */
215         uint8_t controller;
216         /** LBA of disk image to emulate */
217         uint32_t lba;
218         /** Device specification */
219         uint16_t device;
220         /** Segment of 3K buffer for caching CD-ROM reads */
221         uint16_t cache_segment;
222         /** Load segment for initial boot image */
223         uint16_t load_segment;
224         /** Number of 512-byte sectors to load */
225         uint16_t load_sectors;
226         /** Low 8 bits of cylinder number */
227         uint8_t cyl;
228         /** Sector number, plus high 2 bits of cylinder number */
229         uint8_t cyl_sector;
230         /** Head number */
231         uint8_t head;
232 } __attribute__ (( packed ));
233
234 /** A C/H/S address within a partition table entry */
235 struct partition_chs {
236         /** Head number */
237         uint8_t head;
238         /** Sector number, plus high 2 bits of cylinder number */
239         uint8_t cyl_sector;
240         /** Low 8 bits of cylinder number */
241         uint8_t cyl;
242 } __attribute__ (( packed ));
243
244 #define PART_HEAD(chs) ( (chs).head )
245 #define PART_SECTOR(chs) ( (chs).cyl_sector & 0x3f )
246 #define PART_CYLINDER(chs) ( (chs).cyl | ( ( (chs).cyl_sector & 0xc0 ) << 2 ) )
247
248 /** A partition table entry within the MBR */
249 struct partition_table_entry {
250         /** Bootable flag */
251         uint8_t bootable;
252         /** C/H/S start address */
253         struct partition_chs chs_start;
254         /** System indicator (partition type) */
255         uint8_t type;
256         /** C/H/S end address */
257         struct partition_chs chs_end;
258         /** Linear start address */
259         uint32_t start;
260         /** Linear length */
261         uint32_t length;
262 } __attribute__ (( packed ));
263
264 /** A Master Boot Record */
265 struct master_boot_record {
266         uint8_t pad[446];
267         /** Partition table */
268         struct partition_table_entry partitions[4];
269         /** 0x55aa MBR signature */
270         uint16_t signature;
271 } __attribute__ (( packed ));
272
273 extern void register_int13_drive ( struct int13_drive *drive );
274 extern void unregister_int13_drive ( struct int13_drive *drive );
275 extern int int13_boot ( unsigned int drive );
276
277 #endif /* INT13_H */