Home | History | Annotate | Download | only in include
      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