aboutsummaryrefslogtreecommitdiffstats
path: root/roms/ipxe/src/arch/i386/include/int13.h
blob: e337ca1d17d2e5b290caaa468991d24716402e4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
#ifndef INT13_H
#define INT13_H

/** @file
 *
 * INT 13 emulation
 *
 */

FILE_LICENCE ( GPL2_OR_LATER );

#include <stdint.h>
#include <ipxe/list.h>
#include <ipxe/edd.h>
#include <realmode.h>

/**
 * @defgroup int13ops INT 13 operation codes
 * @{
 */

/** Reset disk system */
#define INT13_RESET			0x00
/** Get status of last operation */
#define INT13_GET_LAST_STATUS		0x01
/** Read sectors */
#define INT13_READ_SECTORS		0x02
/** Write sectors */
#define INT13_WRITE_SECTORS		0x03
/** Get drive parameters */
#define INT13_GET_PARAMETERS		0x08
/** Get disk type */
#define INT13_GET_DISK_TYPE		0x15
/** Extensions installation check */
#define INT13_EXTENSION_CHECK		0x41
/** Extended read */
#define INT13_EXTENDED_READ		0x42
/** Extended write */
#define INT13_EXTENDED_WRITE		0x43
/** Verify sectors */
#define INT13_EXTENDED_VERIFY		0x44
/** Extended seek */
#define INT13_EXTENDED_SEEK		0x47
/** Get extended drive parameters */
#define INT13_GET_EXTENDED_PARAMETERS	0x48
/** Get CD-ROM status / terminate emulation */
#define INT13_CDROM_STATUS_TERMINATE	0x4b
/** Read CD-ROM boot catalog */
#define INT13_CDROM_READ_BOOT_CATALOG	0x4d

/** @} */

/**
 * @defgroup int13status INT 13 status codes
 * @{
 */

/** Operation completed successfully */
#define INT13_STATUS_SUCCESS		0x00
/** Invalid function or parameter */
#define INT13_STATUS_INVALID		0x01
/** Read error */
#define INT13_STATUS_READ_ERROR		0x04
/** Reset failed */
#define INT13_STATUS_RESET_FAILED	0x05
/** Write error */
#define INT13_STATUS_WRITE_ERROR	0xcc

/** @} */

/** Block size for non-extended INT 13 calls */
#define INT13_BLKSIZE 512

/** @defgroup int13fddtype INT 13 floppy disk drive types
 * @{
 */

/** 360K */
#define INT13_FDD_TYPE_360K		0x01
/** 1.2M */
#define INT13_FDD_TYPE_1M2		0x02
/** 720K */
#define INT13_FDD_TYPE_720K		0x03
/** 1.44M */
#define INT13_FDD_TYPE_1M44		0x04

/** An INT 13 disk address packet */
struct int13_disk_address {
	/** Size of the packet, in bytes */
	uint8_t bufsize;
	/** Reserved */
	uint8_t reserved_a;
	/** Block count */
	uint8_t count;
	/** Reserved */
	uint8_t reserved_b;
	/** Data buffer */
	struct segoff buffer;
	/** Starting block number */
	uint64_t lba;
	/** Data buffer (EDD 3.0+ only) */
	uint64_t buffer_phys;
	/** Block count (EDD 4.0+ only) */
	uint32_t long_count;
	/** Reserved */
	uint32_t reserved_c;
} __attribute__ (( packed ));

/** INT 13 disk parameters */
struct int13_disk_parameters {
	/** Size of this structure */
	uint16_t bufsize;
	/** Flags */
	uint16_t flags;
	/** Number of cylinders */
	uint32_t cylinders;
	/** Number of heads */
	uint32_t heads;
	/** Number of sectors per track */
	uint32_t sectors_per_track;
	/** Total number of sectors on drive */
	uint64_t sectors;
	/** Bytes per sector */
	uint16_t sector_size;
	/** Device parameter table extension */
	struct segoff dpte;
	/** Device path information */
	struct edd_device_path_information dpi;
} __attribute__ (( packed ));

/**
 * @defgroup int13types INT 13 disk types
 * @{
 */

/** No such drive */
#define INT13_DISK_TYPE_NONE	0x00
/** Floppy without change-line support */
#define INT13_DISK_TYPE_FDD	0x01
/** Floppy with change-line support */
#define INT13_DISK_TYPE_FDD_CL	0x02
/** Hard disk */
#define INT13_DISK_TYPE_HDD	0x03

/** @} */

/**
 * @defgroup int13flags INT 13 disk parameter flags
 * @{
 */

/** DMA boundary errors handled transparently */
#define INT13_FL_DMA_TRANSPARENT 0x01
/** CHS information is valid */
#define INT13_FL_CHS_VALID	 0x02
/** Removable drive */
#define INT13_FL_REMOVABLE	 0x04
/** Write with verify supported */
#define INT13_FL_VERIFIABLE	 0x08
/** Has change-line supported (valid only for removable drives) */
#define INT13_FL_CHANGE_LINE	 0x10
/** Drive can be locked (valid only for removable drives) */
#define INT13_FL_LOCKABLE	 0x20
/** CHS is max possible, not current media (valid only for removable drives) */
#define INT13_FL_CHS_MAX	 0x40

/** @} */

/**
 * @defgroup int13exts INT 13 extension flags
 * @{
 */

/** Extended disk access functions supported */
#define INT13_EXTENSION_LINEAR		0x01
/** Removable drive functions supported */
#define INT13_EXTENSION_REMOVABLE	0x02
/** EDD functions supported */
#define INT13_EXTENSION_EDD		0x04
/** 64-bit extensions are present */
#define INT13_EXTENSION_64BIT		0x08

/** @} */

/**
 * @defgroup int13vers INT 13 extension versions
 * @{
 */

/** INT13 extensions version 1.x */
#define INT13_EXTENSION_VER_1_X		0x01
/** INT13 extensions version 2.0 (EDD-1.0) */
#define INT13_EXTENSION_VER_2_0		0x20
/** INT13 extensions version 2.1 (EDD-1.1) */
#define INT13_EXTENSION_VER_2_1		0x21
/** INT13 extensions version 3.0 (EDD-3.0) */
#define INT13_EXTENSION_VER_3_0		0x30

/** @} */ 

/** Maximum number of sectors for which CHS geometry is allowed to be valid
 *
 * This number is taken from the EDD specification.
 */
#define INT13_MAX_CHS_SECTORS		15482880

/** Bootable CD-ROM specification packet */
struct int13_cdrom_specification {
	/** Size of packet in bytes */
	uint8_t size;
	/** Boot media type */
	uint8_t media_type;
	/** Drive number */
	uint8_t drive;
	/** CD-ROM controller number */
	uint8_t controller;
	/** LBA of disk image to emulate */
	uint32_t lba;
	/** Device specification */
	uint16_t device;
	/** Segment of 3K buffer for caching CD-ROM reads */
	uint16_t cache_segment;
	/** Load segment for initial boot image */
	uint16_t load_segment;
	/** Number of 512-byte sectors to load */
	uint16_t load_sectors;
	/** Low 8 bits of cylinder number */
	uint8_t cyl;
	/** Sector number, plus high 2 bits of cylinder number */
	uint8_t cyl_sector;
	/** Head number */
	uint8_t head;
} __attribute__ (( packed ));

/** Bootable CD-ROM boot catalog command packet */
struct int13_cdrom_boot_catalog_command {
	/** Size of packet in bytes */
	uint8_t size;
	/** Number of sectors of boot catalog to read */
	uint8_t count;
	/** Buffer for boot catalog */
	uint32_t buffer;
	/** First sector in boot catalog to transfer */
	uint16_t start;
} __attribute__ (( packed ));

/** A C/H/S address within a partition table entry */
struct partition_chs {
	/** Head number */
	uint8_t head;
	/** Sector number, plus high 2 bits of cylinder number */
	uint8_t cyl_sector;
	/** Low 8 bits of cylinder number */
	uint8_t cyl;
} __attribute__ (( packed ));

#define PART_HEAD(chs) ( (chs).head )
#define PART_SECTOR(chs) ( (chs).cyl_sector & 0x3f )
#define PART_CYLINDER(chs) ( (chs).cyl | ( ( (chs).cyl_sector & 0xc0 ) << 2 ) )

/** A partition table entry within the MBR */
struct partition_table_entry {
	/** Bootable flag */
	uint8_t bootable;
	/** C/H/S start address */
	struct partition_chs chs_start;
	/** System indicator (partition type) */
	uint8_t type;
	/** C/H/S end address */
	struct partition_chs chs_end;
	/** Linear start address */
	uint32_t start;
	/** Linear length */
	uint32_t length;
} __attribute__ (( packed ));

/** A Master Boot Record */
struct master_boot_record {
	/** Code area */
	uint8_t code[440];
	/** Disk signature */
	uint32_t signature;
	/** Padding */
	uint8_t pad[2];
	/** Partition table */
	struct partition_table_entry partitions[4];
	/** 0x55aa MBR signature */
	uint16_t magic;
} __attribute__ (( packed ));

/** MBR magic signature */
#define INT13_MBR_MAGIC 0xaa55

/** A floppy disk geometry */
struct int13_fdd_geometry {
	/** Number of tracks */
	uint8_t tracks;
	/** Number of heads and sectors per track */
	uint8_t heads_spt;
};

/** Define a floppy disk geometry */
#define INT13_FDD_GEOMETRY( cylinders, heads, sectors )			\
	{								\
		.tracks = (cylinders),					\
		.heads_spt = ( ( (heads) << 6 ) | (sectors) ),		\
	}

/** Get floppy disk number of cylinders */
#define INT13_FDD_CYLINDERS( geometry ) ( (geometry)->tracks )

/** Get floppy disk number of heads */
#define INT13_FDD_HEADS( geometry ) ( (geometry)->heads_spt >> 6 )

/** Get floppy disk number of sectors per track */
#define INT13_FDD_SECTORS( geometry ) ( (geometry)->heads_spt & 0x3f )

/** A floppy drive parameter table */
struct int13_fdd_parameters {
	uint8_t step_rate__head_unload;
	uint8_t head_load__ndma;
	uint8_t motor_off_delay;
	uint8_t bytes_per_sector;
	uint8_t sectors_per_track;
	uint8_t gap_length;
	uint8_t data_length;
	uint8_t format_gap_length;
	uint8_t format_filler;
	uint8_t head_settle_time;
	uint8_t motor_start_time;
} __attribute__ (( packed ));

#endif /* INT13_H */