1 /* ----------------------------------------------------------------------- * 2 * 3 * Copyright 2009 Pierre-Alexandre Meyer 4 * 5 * Some parts borrowed from chain.c32: 6 * 7 * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved 8 * Copyright 2009 Intel Corporation; author: H. Peter Anvin 9 * 10 * Some parts borrowed from Linux: 11 * 12 * Copyright (C) 2002, 2003, 2004 Dell Inc. 13 * by Matt Domsch <Matt_Domsch (at) dell.com> 14 * 15 * This file is part of Syslinux, and is made available under 16 * the terms of the GNU General Public License version 2. 17 * 18 * ----------------------------------------------------------------------- */ 19 20 #ifndef _GEOM_H_ 21 #define _GEOM_H_ 22 23 #include <stdint.h> 24 25 /** 26 * INT 13 Extensions 27 * 28 * Note: if the size is less than 30 on call, the final DWORD will not be 29 * returned by a v2.x implementation; similarly for the Device Path info 30 **/ 31 struct edd_device_parameters { 32 uint16_t len; /* size of returned data */ 33 /** 34 * Bitfields for IBM/MS INT 13 Extensions information flags: 35 * Bit(s) Description (Table 00274) 36 * 0 DMA boundary errors handled transparently 37 * 1 cylinder/head/sectors-per-track information is valid 38 * 2 removable drive 39 * 3 write with verify supported 40 * 4 drive has change-line support (required if drive >= 80h is removable) 41 * 5 drive can be locked (required if drive >= 80h is removable) 42 * 6 CHS information set to maximum supported values, not current media 43 * 15-7 reserved (0) 44 **/ 45 uint16_t info; /* information flags */ 46 uint32_t cylinders; /* number of physical cylinders on drive */ 47 uint32_t heads; /* number of physical heads on drive */ 48 uint32_t sectors_per_track; /* number of physical sectors per track */ 49 uint64_t sectors; /* total number of sectors on drive */ 50 uint16_t bytes_per_sector; /* bytes per sector */ 51 /* --- v2.0+ --- */ 52 uint32_t dpte_pointer; /* EDD configuration parameters, FFFFh:FFFFh if not available */ 53 /* --- v3.0 --- */ 54 uint16_t device_path_information; /* signature BEDDh to indicate presence of Device Path info */ 55 uint8_t device_path_length; /* length of Device Path information, including signature and this byte (24h for v3.0) */ 56 uint8_t device_path_reserved; /* reserved (0) */ 57 uint16_t device_path_reserved_2; /* reserved (0) */ 58 uint8_t host_bus_type[4]; /* ASCIZ name of host bus ("ISA" or "PCI") */ 59 uint8_t interface_type[8]; /* ASCIZ name of interface type 60 * "ATA" 61 * "ATAPI" 62 * "SCSI" 63 * "USB" 64 * "1394" IEEE 1394 (FireWire) 65 * "FIBRE" Fibre Channel 66 */ 67 /** 68 * Format of EDD v3.0 Interface Path: 69 * Offset Size Description (Table 00275) 70 * ---ISA--- 71 * 00h WORD 16-bit base address 72 * 02h 6 BYTEs reserved (0) 73 * ---PCI--- 74 * 00h BYTE PCI bus number 75 * 01h BYTE PCI device number 76 * 02h BYTE PCI function number 77 * 03h 5 BYTEs reserved (0) 78 **/ 79 union { 80 struct { 81 uint16_t base_address; 82 uint16_t reserved1; 83 uint32_t reserved2; 84 } __attribute__ ((packed)) isa; 85 struct { 86 uint8_t bus; 87 uint8_t slot; 88 uint8_t function; 89 uint8_t channel; 90 uint32_t reserved; 91 } __attribute__ ((packed)) pci; 92 /* pcix is same as pci */ 93 struct { 94 uint64_t reserved; 95 } __attribute__ ((packed)) ibnd; 96 struct { 97 uint64_t reserved; 98 } __attribute__ ((packed)) xprs; 99 struct { 100 uint64_t reserved; 101 } __attribute__ ((packed)) htpt; 102 struct { 103 uint64_t reserved; 104 } __attribute__ ((packed)) unknown; 105 } interface_path; 106 /** 107 * Format of EDD v3.0 Device Path: 108 * Offset Size Description (Table 00276) 109 * ---ATA--- 110 * 00h BYTE flag: 00h = master, 01h = slave 111 * 01h 7 BYTEs reserved (0) 112 * ---ATAPI--- 113 * 00h BYTE flag: 00h = master, 01h = slave 114 * 01h BYTE logical unit number 115 * 02h 6 BYTEs reserved (0) 116 * ---SCSI--- 117 * 00h BYTE logical unit number 118 * 01h 7 BYTEs reserved (0) 119 * ---USB--- 120 * 00h BYTE to be determined 121 * 01h 7 BYTEs reserved (0) 122 * ---IEEE1394--- 123 * 00h QWORD 64-bit FireWire General Unique Identifier (GUID) 124 * ---FibreChannel--- 125 * 00h QWORD Word Wide Number (WWN) 126 **/ 127 union { 128 struct { 129 uint8_t device; 130 uint8_t reserved1; 131 uint16_t reserved2; 132 uint32_t reserved3; 133 uint64_t reserved4; 134 } __attribute__ ((packed)) ata; 135 struct { 136 uint8_t device; 137 uint8_t lun; 138 uint8_t reserved1; 139 uint8_t reserved2; 140 uint32_t reserved3; 141 uint64_t reserved4; 142 } __attribute__ ((packed)) atapi; 143 struct { 144 uint16_t id; 145 uint64_t lun; 146 uint16_t reserved1; 147 uint32_t reserved2; 148 } __attribute__ ((packed)) scsi; 149 struct { 150 uint64_t serial_number; 151 uint64_t reserved; 152 } __attribute__ ((packed)) usb; 153 struct { 154 uint64_t eui; 155 uint64_t reserved; 156 } __attribute__ ((packed)) i1394; 157 struct { 158 uint64_t wwid; 159 uint64_t lun; 160 } __attribute__ ((packed)) fibre; 161 struct { 162 uint64_t identity_tag; 163 uint64_t reserved; 164 } __attribute__ ((packed)) i2o; 165 struct { 166 uint32_t array_number; 167 uint32_t reserved1; 168 uint64_t reserved2; 169 } __attribute__ ((packed)) raid; 170 struct { 171 uint8_t device; 172 uint8_t reserved1; 173 uint16_t reserved2; 174 uint32_t reserved3; 175 uint64_t reserved4; 176 } __attribute__ ((packed)) sata; 177 struct { 178 uint64_t reserved1; 179 uint64_t reserved2; 180 } __attribute__ ((packed)) unknown; 181 } device_path; 182 uint8_t reserved; /* reserved (0) */ 183 uint8_t checksum; /* checksum of bytes 1Eh-40h (two's complement of sum, which makes 184 * the 8-bit sum of bytes 1Eh-41h equal 00h) */ 185 } __attribute__ ((packed)); 186 187 /* 188 * Disk parameters 189 */ 190 struct driveinfo { 191 int disk; /* Disk port (0x80 - 0xff) */ 192 /* Legacy C/H/S */ 193 int cbios; /* CHS geometry is valid */ 194 int legacy_max_head; 195 int legacy_max_cylinder; 196 int legacy_sectors_per_track; 197 int legacy_max_drive; 198 int legacy_type; /* Drive type (AT/PS2 floppies only) */ 199 /* EDD support */ 200 int ebios; /* EBIOS supported on this disk */ 201 int edd_version; /* EBIOS major version */ 202 int edd_functionality_subset; 203 struct edd_device_parameters edd_params; /* EDD parameters */ 204 }; 205 206 /** 207 * Format of Phoenix Enhanced Disk Drive Spec translated drive parameter table: 208 * Offset Size Description (Table 00277) 209 * 00h WORD number of cylinders 210 * 02h BYTE number of heads 211 * 03h BYTE A0h (signature indicating translated table) 212 * 04h BYTE number of physical sectors per track 213 * 05h WORD starting write precompensation cylinder number 214 * 07h BYTE reserved 215 * 08h BYTE control byte (see #03198 at INT 41"DISK 0") 216 * 09h WORD number of physical cylinders 217 * 0Bh BYTE number of physical heads 218 * 0Ch WORD cylinder number of landing zone 219 * 0Eh BYTE number of logical sectors per track 220 * 0Fh BYTE checksum 221 * Program: the Phoenix Enhanced Disk Drive Specification is an addition to the 222 * IBM/MS INT 13 extensions 223 * 224 * Format of Phoenix Enhanced Disk Drive Spec Fixed Disk Parameter Table: 225 * Offset Size Description (Table 00278) 226 * 00h WORD physical I/O port base address 227 * 02h WORD disk-drive control port address 228 * 04h BYTE drive flags (see #00279) 229 * 05h BYTE proprietary information 230 * bits 7-4 reserved (0) 231 * bits 3-0: Phoenix proprietary (used by BIOS) 232 * 06h BYTE IRQ for drive (bits 3-0; bits 7-4 reserved and must be 0) 233 * 07h BYTE sector count for multi-sector transfers 234 * 08h BYTE DMA control 235 * bits 7-4: DMA type (0-2) as per ATA-2 specification 236 * bits 3-0: DMA channel 237 * 09h BYTE programmed I/O control 238 * bits 7-4: reserved (0) 239 * bits 3-0: PIO type (1-4) as per ATA-2 specification 240 * 0Ah WORD drive options (see #00280) 241 * 0Ch 2 BYTEs reserved (0) 242 * 0Eh BYTE extension revision level (high nybble=major, low nybble=minor) 243 * (currently 10h for v1.0 and 11h for v1.1-3.0) 244 * 0Fh BYTE 2's complement checksum of bytes 00h-0Eh 245 * 8-bit sum of all bytes 00h-0Fh should equal 00h 246 * SeeAlso: #00277 247 * 248 * Bitfields for Phoenix Enhanced Disk Drive Spec drive flags: 249 * Bit(s) Description (Table 00279) 250 * 7 reserved (1) 251 * 6 LBA enabled 252 * 5 reserved (1) 253 * 4 drive is slave 254 * 3-0 reserved (0) 255 * SeeAlso: #00278,#00280 256 * 257 * Bitfields for Phoenix Enhanced Disk Drive Spec drive options: 258 * Bit(s) Description (Table 00280) 259 * 0 fast PIO enabled 260 * 1 fast DMA access enabled 261 * 2 block PIO (multi-sector transfers) enabled 262 * 3 CHS translation enabled 263 * 4 LBA translation enabled 264 * 5 removable media 265 * 6 ATAPI device (CD-ROM) 266 * 7 32-bit transfer mode 267 * ---v1.1+ --- 268 * 8 ATAPI device uses DRQ to signal readiness for packet command 269 * (must be 0 if bit 6 is 0) 270 * 10-9 translation type (must be 00 if bit 3 is 0) 271 * 00 Phoenix bit-shifting translation 272 * 01 LBA-assisted translation 273 * 10 reserved 274 * 11 proprietary translation 275 * ---v3.0--- 276 * 11 Ultra DMA access enabled 277 * 15-12 reserved 278 **/ 279 280 /* 281 * Values for diskette drive type: 282 * 01h 360K 283 * 02h 1.2M 284 * 03h 720K 285 * 04h 1.44M 286 * 05h ??? 287 * reportedly an obscure drive type shipped on some IBM machines, 288 * 2.88M on some machines (at least AMI 486 BIOS) 289 * 06h 2.88M 290 * 10h ATAPI Removable Media Device 291 */ 292 enum diskette_drive_types { 293 DISKETTE_360K = 1, 294 DISKETTE_1_2M = 2, 295 DISKETTE_720K = 3, 296 DISKETTE_1_44M = 4, 297 DISKETTE_2_88M = 6, 298 DISKETTE_ATAPI = 10, 299 }; 300 301 /** 302 * chs_to_lba - compute lba value from cylinder, head and sector number 303 **/ 304 static inline int chs_to_lba(const struct driveinfo *drive_info, 305 const unsigned int cylinder, 306 const unsigned int head, const unsigned int sector) 307 { 308 /* Use EDD, if valid */ 309 if (drive_info->edd_params.sectors_per_track > 0 && 310 drive_info->edd_params.heads > 0) 311 return (sector - 1) + 312 (head * drive_info->edd_params.sectors_per_track) + 313 (cylinder * (drive_info->edd_params.heads) * 314 drive_info->edd_params.sectors_per_track); 315 else if (drive_info->cbios) 316 return (sector - 1) + (head * drive_info->legacy_sectors_per_track) + 317 (cylinder * (drive_info->legacy_max_head + 1) * 318 drive_info->legacy_sectors_per_track); 319 } 320 321 void lba_to_chs(const struct driveinfo *drive_info, const int lba, 322 unsigned int *cylinder, unsigned int *head, 323 unsigned int *sector); 324 int get_drive_parameters(struct driveinfo *drive_info); 325 326 #endif /* _GEOM_H */ 327