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