aboutsummaryrefslogtreecommitdiffstats
path: root/com32/gplinclude/disk/geom.h
blob: 359c7cf918253165d61f6e5721b90eb6c59b58da (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
/* ----------------------------------------------------------------------- *
 *
 *   Copyright 2009 Pierre-Alexandre Meyer
 *
 *   Some parts borrowed from chain.c32:
 *
 *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
 *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
 *
 *   Some parts borrowed from Linux:
 *
 *   Copyright (C) 2002, 2003, 2004 Dell Inc.
 *   by Matt Domsch <Matt_Domsch@dell.com>
 *
 *   This file is part of Syslinux, and is made available under
 *   the terms of the GNU General Public License version 2.
 *
 * ----------------------------------------------------------------------- */

#ifndef _GEOM_H_
#define _GEOM_H_

#include <stdint.h>

/**
 * INT 13 Extensions
 *
 * Note: if the size is less than 30 on call, the final DWORD will not be
 *       returned by a v2.x implementation; similarly for the Device Path info
 **/
struct edd_device_parameters {
    uint16_t len;		/* size of returned data */
	/**
	 * Bitfields for IBM/MS INT 13 Extensions information flags:
	 * Bit(s)    Description    (Table 00274)
	 * 0    DMA boundary errors handled transparently
	 * 1    cylinder/head/sectors-per-track information is valid
	 * 2    removable drive
	 * 3    write with verify supported
	 * 4    drive has change-line support (required if drive >= 80h is removable)
	 * 5    drive can be locked (required if drive >= 80h is removable)
	 * 6    CHS information set to maximum supported values, not current media
	 * 15-7    reserved (0)
	 **/
    uint16_t info;		/* information flags */
    uint32_t cylinders;		/* number of physical cylinders on drive */
    uint32_t heads;		/* number of physical heads on drive */
    uint32_t sectors_per_track;	/* number of physical sectors per track */
    uint64_t sectors;		/* total number of sectors on drive */
    uint16_t bytes_per_sector;	/* bytes per sector */
    /* --- v2.0+ --- */
    uint32_t dpte_pointer;	/* EDD configuration parameters, FFFFh:FFFFh if not available */
    /* --- v3.0 --- */
    uint16_t device_path_information;	/* signature BEDDh to indicate presence of Device Path info */
    uint8_t device_path_length;	/* length of Device Path information, including signature and this byte (24h for v3.0) */
    uint8_t device_path_reserved;	/* reserved (0) */
    uint16_t device_path_reserved_2;	/* reserved (0) */
    uint8_t host_bus_type[4];	/* ASCIZ name of host bus ("ISA" or "PCI") */
    uint8_t interface_type[8];	/* ASCIZ name of interface type
				 *         "ATA"
				 *         "ATAPI"
				 *         "SCSI"
				 *         "USB"
				 *         "1394" IEEE 1394 (FireWire)
				 *         "FIBRE" Fibre Channel
				 */
	/**
	 * Format of EDD v3.0 Interface Path:
	 * Offset    Size    Description    (Table 00275)
	 * ---ISA---
	 * 00h    WORD    16-bit base address
	 * 02h 6 BYTEs    reserved (0)
	 * ---PCI---
	 * 00h    BYTE    PCI bus number
	 * 01h    BYTE    PCI device number
	 * 02h    BYTE    PCI function number
	 * 03h 5 BYTEs    reserved (0)
	 **/
    union {
	struct {
	    uint16_t base_address;
	    uint16_t reserved1;
	    uint32_t reserved2;
	} __attribute__ ((packed)) isa;
	struct {
	    uint8_t bus;
	    uint8_t slot;
	    uint8_t function;
	    uint8_t channel;
	    uint32_t reserved;
	} __attribute__ ((packed)) pci;
	/* pcix is same as pci */
	struct {
	    uint64_t reserved;
	} __attribute__ ((packed)) ibnd;
	struct {
	    uint64_t reserved;
	} __attribute__ ((packed)) xprs;
	struct {
	    uint64_t reserved;
	} __attribute__ ((packed)) htpt;
	struct {
	    uint64_t reserved;
	} __attribute__ ((packed)) unknown;
    } interface_path;
	/**
	 * Format of EDD v3.0 Device Path:
	 * Offset    Size    Description    (Table 00276)
	 * ---ATA---
	 * 00h    BYTE    flag: 00h = master, 01h = slave
	 * 01h 7 BYTEs    reserved (0)
	 * ---ATAPI---
	 * 00h    BYTE    flag: 00h = master, 01h = slave
	 * 01h    BYTE    logical unit number
	 * 02h 6 BYTEs    reserved (0)
	 * ---SCSI---
	 * 00h    BYTE    logical unit number
	 * 01h 7 BYTEs    reserved (0)
	 * ---USB---
	 * 00h    BYTE    to be determined
	 * 01h 7 BYTEs    reserved (0)
	 * ---IEEE1394---
	 * 00h    QWORD    64-bit FireWire General Unique Identifier (GUID)
	 * ---FibreChannel---
	 * 00h    QWORD    Word Wide Number (WWN)
	 **/
    union {
	struct {
	    uint8_t device;
	    uint8_t reserved1;
	    uint16_t reserved2;
	    uint32_t reserved3;
	    uint64_t reserved4;
	} __attribute__ ((packed)) ata;
	struct {
	    uint8_t device;
	    uint8_t lun;
	    uint8_t reserved1;
	    uint8_t reserved2;
	    uint32_t reserved3;
	    uint64_t reserved4;
	} __attribute__ ((packed)) atapi;
	struct {
	    uint16_t id;
	    uint64_t lun;
	    uint16_t reserved1;
	    uint32_t reserved2;
	} __attribute__ ((packed)) scsi;
	struct {
	    uint64_t serial_number;
	    uint64_t reserved;
	} __attribute__ ((packed)) usb;
	struct {
	    uint64_t eui;
	    uint64_t reserved;
	} __attribute__ ((packed)) i1394;
	struct {
	    uint64_t wwid;
	    uint64_t lun;
	} __attribute__ ((packed)) fibre;
	struct {
	    uint64_t identity_tag;
	    uint64_t reserved;
	} __attribute__ ((packed)) i2o;
	struct {
	    uint32_t array_number;
	    uint32_t reserved1;
	    uint64_t reserved2;
	} __attribute__ ((packed)) raid;
	struct {
	    uint8_t device;
	    uint8_t reserved1;
	    uint16_t reserved2;
	    uint32_t reserved3;
	    uint64_t reserved4;
	} __attribute__ ((packed)) sata;
	struct {
	    uint64_t reserved1;
	    uint64_t reserved2;
	} __attribute__ ((packed)) unknown;
    } device_path;
    uint8_t reserved;		/* reserved (0) */
    uint8_t checksum;		/* checksum of bytes 1Eh-40h (two's complement of sum, which makes
				 * the 8-bit sum of bytes 1Eh-41h equal 00h) */
} __attribute__ ((packed));

/*
 * Disk parameters
 */
struct driveinfo {
    int disk;			/* Disk port (0x80 - 0xff) */
    /* Legacy C/H/S */
    int cbios;			/* CHS geometry is valid */
    int legacy_max_head;
    int legacy_max_cylinder;
    int legacy_sectors_per_track;
    int legacy_max_drive;
    int legacy_type;		/* Drive type (AT/PS2 floppies only) */
    /* EDD support */
    int ebios;			/* EBIOS supported on this disk */
    int edd_version;		/* EBIOS major version */
    int edd_functionality_subset;
    struct edd_device_parameters edd_params;	/* EDD parameters */
};

/**
 * Format of Phoenix Enhanced Disk Drive Spec translated drive parameter table:
 * Offset    Size    Description    (Table 00277)
 * 00h    WORD    number of cylinders
 * 02h    BYTE    number of heads
 * 03h    BYTE    A0h (signature indicating translated table)
 * 04h    BYTE    number of physical sectors per track
 * 05h    WORD    starting write precompensation cylinder number
 * 07h    BYTE    reserved
 * 08h    BYTE    control byte (see #03198 at INT 41"DISK 0")
 * 09h    WORD    number of physical cylinders
 * 0Bh    BYTE    number of physical heads
 * 0Ch    WORD    cylinder number of landing zone
 * 0Eh    BYTE    number of logical sectors per track
 * 0Fh    BYTE    checksum
 * Program: the Phoenix Enhanced Disk Drive Specification is an addition to the
 *     IBM/MS INT 13 extensions
 *
 * Format of Phoenix Enhanced Disk Drive Spec Fixed Disk Parameter Table:
 * Offset    Size    Description    (Table 00278)
 * 00h    WORD    physical I/O port base address
 * 02h    WORD    disk-drive control port address
 * 04h    BYTE    drive flags (see #00279)
 * 05h    BYTE    proprietary information
 *         bits 7-4 reserved (0)
 *         bits 3-0: Phoenix proprietary (used by BIOS)
 * 06h    BYTE    IRQ for drive (bits 3-0; bits 7-4 reserved and must be 0)
 * 07h    BYTE    sector count for multi-sector transfers
 * 08h    BYTE    DMA control
 *         bits 7-4: DMA type (0-2) as per ATA-2 specification
 *         bits 3-0: DMA channel
 * 09h    BYTE    programmed I/O control
 *         bits 7-4: reserved (0)
 *         bits 3-0: PIO type (1-4) as per ATA-2 specification
 * 0Ah    WORD    drive options (see #00280)
 * 0Ch 2 BYTEs    reserved (0)
 * 0Eh    BYTE    extension revision level (high nybble=major, low nybble=minor)
 *         (currently 10h for v1.0 and 11h for v1.1-3.0)
 * 0Fh    BYTE    2's complement checksum of bytes 00h-0Eh
 *         8-bit sum of all bytes 00h-0Fh should equal 00h
 * SeeAlso: #00277
 *
 * Bitfields for Phoenix Enhanced Disk Drive Spec drive flags:
 * Bit(s)    Description    (Table 00279)
 * 7    reserved (1)
 * 6    LBA enabled
 * 5    reserved (1)
 * 4    drive is slave
 * 3-0    reserved (0)
 * SeeAlso: #00278,#00280
 *
 * Bitfields for Phoenix Enhanced Disk Drive Spec drive options:
 * Bit(s)    Description    (Table 00280)
 * 0    fast PIO enabled
 * 1    fast DMA access enabled
 * 2    block PIO (multi-sector transfers) enabled
 * 3    CHS translation enabled
 * 4    LBA translation enabled
 * 5    removable media
 * 6    ATAPI device (CD-ROM)
 * 7    32-bit transfer mode
 * ---v1.1+ ---
 * 8    ATAPI device uses DRQ to signal readiness for packet command
 *     (must be 0 if bit 6 is 0)
 * 10-9    translation type (must be 00 if bit 3 is 0)
 *     00 Phoenix bit-shifting translation
 *     01 LBA-assisted translation
 *     10 reserved
 *     11 proprietary translation
 * ---v3.0---
 * 11    Ultra DMA access enabled
 * 15-12    reserved
 **/

/*
 * Values for diskette drive type:
 *     01h    360K
 *     02h    1.2M
 *     03h    720K
 *     04h    1.44M
 *     05h    ???
 *            reportedly an obscure drive type shipped on some IBM machines,
 *            2.88M on some machines (at least AMI 486 BIOS)
 *     06h    2.88M
 *     10h    ATAPI Removable Media Device
 */
enum diskette_drive_types {
    DISKETTE_360K = 1,
    DISKETTE_1_2M = 2,
    DISKETTE_720K = 3,
    DISKETTE_1_44M = 4,
    DISKETTE_2_88M = 6,
    DISKETTE_ATAPI = 10,
};

/**
 * chs_to_lba - compute lba value from cylinder, head and sector number
 **/
static inline int chs_to_lba(const struct driveinfo *drive_info,
			     const unsigned int cylinder,
			     const unsigned int head, const unsigned int sector)
{
    /* Use EDD, if valid */
    if (drive_info->edd_params.sectors_per_track > 0 &&
	drive_info->edd_params.heads > 0)
	return (sector - 1) +
	    (head * drive_info->edd_params.sectors_per_track) +
	    (cylinder * (drive_info->edd_params.heads) *
	     drive_info->edd_params.sectors_per_track);
    else if (drive_info->cbios)
	return (sector - 1) + (head * drive_info->legacy_sectors_per_track) +
	    (cylinder * (drive_info->legacy_max_head + 1) *
	     drive_info->legacy_sectors_per_track);
}

void lba_to_chs(const struct driveinfo *drive_info, const int lba,
		unsigned int *cylinder, unsigned int *head,
		unsigned int *sector);
int get_drive_parameters(struct driveinfo *drive_info);

#endif /* _GEOM_H */