iPXE
Data Structures | Macros | Functions | Variables
int13.c File Reference

INT 13 emulation. More...

#include <stdint.h>
#include <stdlib.h>
#include <limits.h>
#include <byteswap.h>
#include <errno.h>
#include <assert.h>
#include <ipxe/blockdev.h>
#include <ipxe/io.h>
#include <ipxe/acpi.h>
#include <ipxe/sanboot.h>
#include <ipxe/device.h>
#include <ipxe/pci.h>
#include <ipxe/eltorito.h>
#include <realmode.h>
#include <bios.h>
#include <biosint.h>
#include <bootsector.h>
#include <int13.h>

Go to the source code of this file.

Data Structures

struct  int13_data
 INT 13 SAN device private data. More...
 

Macros

#define int13_vector   __use_text16 ( int13_vector )
 
#define int13_fdd_params   __use_data16 ( int13_fdd_params )
 
#define num_fdds   __use_text16 ( num_fdds )
 
#define num_drives   __use_text16 ( num_drives )
 
#define eltorito_cmd   __use_data16 ( eltorito_cmd )
 
#define eltorito_address   __use_data16 ( eltorito_address )
 
#define XBFTAB_SIZE   768
 Maximum size of boot firmware table(s) More...
 
#define XBFTAB_ALIGN   16
 Alignment of boot firmware table entries. More...
 
#define xbftab   __use_data16 ( xbftab )
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static struct segoff __text16 (int13_vector)
 Vector for chaining to other INT 13 handlers. More...
 
void int13_wrapper (void)
 Assembly wrapper. More...
 
static struct int13_fdd_parameters __data16 (int13_fdd_params)
 Dummy floppy disk parameter table. More...
 
static uint8_t __text16 (num_fdds)
 Number of BIOS floppy disk drives. More...
 
static uint8_t __text16 (num_drives)
 Number of BIOS hard disk drives. More...
 
static uint32_t int13_capacity32 (struct san_device *sandev)
 Calculate SAN device capacity (limited to 32 bits) More...
 
static int int13_is_fdd (struct san_device *sandev)
 Test if SAN device is a floppy disk drive. More...
 
static int int13_parse_eltorito (struct san_device *sandev, void *scratch)
 Parse El Torito parameters. More...
 
static int int13_guess_geometry_hdd (struct san_device *sandev, void *scratch, unsigned int *heads, unsigned int *sectors)
 Guess INT 13 hard disk drive geometry. More...
 
static int int13_guess_geometry_fdd (struct san_device *sandev, unsigned int *heads, unsigned int *sectors)
 Guess INT 13 floppy disk drive geometry. More...
 
static int int13_guess_geometry (struct san_device *sandev, void *scratch)
 Guess INT 13 drive geometry. More...
 
static void int13_sync_num_drives (void)
 Update BIOS drive count. More...
 
static void int13_check_num_drives (void)
 Check number of drives. More...
 
static int int13_reset (struct san_device *sandev, struct i386_all_regs *ix86 __unused)
 INT 13, 00 - Reset disk system. More...
 
static int int13_get_last_status (struct san_device *sandev, struct i386_all_regs *ix86 __unused)
 INT 13, 01 - Get status of last operation. More...
 
static int int13_rw_sectors (struct san_device *sandev, struct i386_all_regs *ix86, int(*sandev_rw)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer))
 Read / write sectors. More...
 
static int int13_read_sectors (struct san_device *sandev, struct i386_all_regs *ix86)
 INT 13, 02 - Read sectors. More...
 
static int int13_write_sectors (struct san_device *sandev, struct i386_all_regs *ix86)
 INT 13, 03 - Write sectors. More...
 
static int int13_get_parameters (struct san_device *sandev, struct i386_all_regs *ix86)
 INT 13, 08 - Get drive parameters. More...
 
static int int13_get_disk_type (struct san_device *sandev, struct i386_all_regs *ix86)
 INT 13, 15 - Get disk type. More...
 
static int int13_extension_check (struct san_device *sandev, struct i386_all_regs *ix86)
 INT 13, 41 - Extensions installation check. More...
 
static int int13_extended_rw (struct san_device *sandev, struct i386_all_regs *ix86, int(*sandev_rw)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer))
 Extended read / write. More...
 
static int int13_extended_read (struct san_device *sandev, struct i386_all_regs *ix86)
 INT 13, 42 - Extended read. More...
 
static int int13_extended_write (struct san_device *sandev, struct i386_all_regs *ix86)
 INT 13, 43 - Extended write. More...
 
static int int13_extended_verify (struct san_device *sandev, struct i386_all_regs *ix86)
 INT 13, 44 - Verify sectors. More...
 
static int int13_extended_seek (struct san_device *sandev, struct i386_all_regs *ix86)
 INT 13, 44 - Extended seek. More...
 
static int int13_device_path_info (struct san_device *sandev, struct edd_device_path_information *dpi)
 Build device path information. More...
 
static int int13_get_extended_parameters (struct san_device *sandev, struct i386_all_regs *ix86)
 INT 13, 48 - Get extended parameters. More...
 
static int int13_cdrom_status_terminate (struct san_device *sandev, struct i386_all_regs *ix86)
 INT 13, 4b - Get status or terminate CD-ROM emulation. More...
 
static int int13_cdrom_read_boot_catalog (struct san_device *sandev, struct i386_all_regs *ix86)
 INT 13, 4d - Read CD-ROM boot catalog. More...
 
static __asmcall __used void int13 (struct i386_all_regs *ix86)
 INT 13 handler. More...
 
static void int13_hook_vector (void)
 Hook INT 13 handler. More...
 
static void int13_unhook_vector (void)
 Unhook INT 13 handler. More...
 
static int int13_hook (unsigned int drive, struct uri **uris, unsigned int count, unsigned int flags)
 Hook INT 13 SAN device. More...
 
static void int13_unhook (unsigned int drive)
 Unhook INT 13 SAN device. More...
 
static int int13_load_mbr (unsigned int drive, struct segoff *address)
 Load and verify master boot record from INT 13 drive. More...
 
static struct int13_cdrom_boot_catalog_command __data16 (eltorito_cmd)
 El Torito boot catalog command packet. More...
 
static struct int13_disk_address __bss16 (eltorito_address)
 El Torito disk address packet. More...
 
static int int13_load_eltorito (unsigned int drive, struct segoff *address)
 Load and verify El Torito boot record from INT 13 drive. More...
 
static int int13_boot (unsigned int drive, const char *filename __unused)
 Attempt to boot from an INT 13 drive. More...
 
static uint8_t __bss16_array (xbftab, [XBFTAB_SIZE])
 The boot firmware table(s) generated by iPXE. More...
 
static int int13_install (struct acpi_header *acpi)
 Install ACPI table. More...
 
static int int13_describe (void)
 Describe SAN devices for SAN-booted operating system. More...
 
 PROVIDE_SANBOOT (pcbios, san_hook, int13_hook)
 
 PROVIDE_SANBOOT (pcbios, san_unhook, int13_unhook)
 
 PROVIDE_SANBOOT (pcbios, san_boot, int13_boot)
 
 PROVIDE_SANBOOT (pcbios, san_describe, int13_describe)
 

Variables

static uint16_t equipment_word
 Equipment word. More...
 
static const struct int13_fdd_geometry int13_fdd_geometries []
 Recognised floppy disk geometries. More...
 
static size_t xbftab_used
 Total used length of boot firmware tables. More...
 

Detailed Description

INT 13 emulation.

This module provides a mechanism for exporting block devices via the BIOS INT 13 disk interrupt interface.

Definition in file int13.c.

Macro Definition Documentation

◆ int13_vector

#define int13_vector   __use_text16 ( int13_vector )

Definition at line 101 of file int13.c.

◆ int13_fdd_params

#define int13_fdd_params   __use_data16 ( int13_fdd_params )

Definition at line 113 of file int13.c.

◆ num_fdds

#define num_fdds   __use_text16 ( num_fdds )

Definition at line 130 of file int13.c.

◆ num_drives

#define num_drives   __use_text16 ( num_drives )

Definition at line 140 of file int13.c.

◆ eltorito_cmd

#define eltorito_cmd   __use_data16 ( eltorito_cmd )

Definition at line 1415 of file int13.c.

◆ eltorito_address

#define eltorito_address   __use_data16 ( eltorito_address )

Definition at line 1419 of file int13.c.

◆ XBFTAB_SIZE

#define XBFTAB_SIZE   768

Maximum size of boot firmware table(s)

Definition at line 1545 of file int13.c.

◆ XBFTAB_ALIGN

#define XBFTAB_ALIGN   16

Alignment of boot firmware table entries.

Definition at line 1548 of file int13.c.

◆ xbftab

#define xbftab   __use_data16 ( xbftab )

Definition at line 1553 of file int13.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ __text16() [1/3]

static struct segoff __text16 ( int13_vector  )
static

Vector for chaining to other INT 13 handlers.

◆ int13_wrapper()

void int13_wrapper ( void  )

Assembly wrapper.

Referenced by int13_hook_vector(), and int13_unhook_vector().

◆ __data16() [1/2]

static struct int13_fdd_parameters __data16 ( int13_fdd_params  )
static

Dummy floppy disk parameter table.

◆ __text16() [2/3]

static uint8_t __text16 ( num_fdds  )
static

Number of BIOS floppy disk drives.

This is derived from the equipment word. It is held in .text16 to allow for easy access by the INT 13,08 wrapper.

◆ __text16() [3/3]

static uint8_t __text16 ( num_drives  )
static

Number of BIOS hard disk drives.

This is a cached copy of the BIOS Data Area number of hard disk drives at 40:75. It is held in .text16 to allow for easy access by the INT 13,08 wrapper.

◆ int13_capacity32()

static uint32_t int13_capacity32 ( struct san_device sandev)
inlinestatic

Calculate SAN device capacity (limited to 32 bits)

Parameters
sandevSAN device
Return values
blocksNumber of blocks

Definition at line 148 of file int13.c.

148  {
149  uint64_t capacity = sandev_capacity ( sandev );
150  return ( ( capacity <= 0xffffffffUL ) ? capacity : 0xffffffff );
151 }
unsigned long long uint64_t
Definition: stdint.h:13
static uint64_t sandev_capacity(struct san_device *sandev)
Calculate SAN device capacity.
Definition: sanboot.h:222

References sandev_capacity().

Referenced by int13_get_disk_type(), and int13_guess_geometry().

◆ int13_is_fdd()

static int int13_is_fdd ( struct san_device sandev)
inlinestatic

Test if SAN device is a floppy disk drive.

Parameters
sandevSAN device
Return values
is_fddSAN device is a floppy disk drive

Definition at line 159 of file int13.c.

159  {
160  return ( ! ( sandev->drive & 0x80 ) );
161 }
unsigned int drive
Drive number.
Definition: sanboot.h:54

References san_device::drive.

Referenced by int13_extended_rw(), int13_extension_check(), int13_get_disk_type(), int13_get_parameters(), int13_guess_geometry(), and int13_sync_num_drives().

◆ int13_parse_eltorito()

static int int13_parse_eltorito ( struct san_device sandev,
void *  scratch 
)
static

Parse El Torito parameters.

Parameters
sandevSAN device
scratchScratch area for single-sector reads
Return values
rcReturn status code

Reads and parses El Torito parameters, if present.

Definition at line 172 of file int13.c.

172  {
173  struct int13_data *int13 = sandev->priv;
174  static const struct eltorito_descriptor_fixed boot_check = {
176  .id = ISO9660_ID,
177  .version = 1,
178  .system_id = "EL TORITO SPECIFICATION",
179  };
180  struct eltorito_descriptor *boot = scratch;
181  int rc;
182 
183  /* Read boot record volume descriptor */
184  if ( ( rc = sandev_read ( sandev, ELTORITO_LBA, 1,
185  virt_to_user ( boot ) ) ) != 0 ) {
186  DBGC ( sandev, "INT13 drive %02x could not read El Torito boot "
187  "record volume descriptor: %s\n",
188  sandev->drive, strerror ( rc ) );
189  return rc;
190  }
191 
192  /* Check for an El Torito boot catalog */
193  if ( memcmp ( boot, &boot_check, sizeof ( boot_check ) ) == 0 ) {
194  int13->boot_catalog = boot->sector;
195  DBGC ( sandev, "INT13 drive %02x has an El Torito boot catalog "
196  "at LBA %08x\n", sandev->drive, int13->boot_catalog );
197  } else {
198  DBGC ( sandev, "INT13 drive %02x has no El Torito boot "
199  "catalog\n", sandev->drive );
200  }
201 
202  return 0;
203 }
uint8_t type
Descriptor type.
Definition: eltorito.h:19
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static __asmcall __used void int13(struct i386_all_regs *ix86)
INT 13 handler.
Definition: int13.c:1067
#define DBGC(...)
Definition: compiler.h:505
#define ISO9660_ID
ISO9660 identifier.
Definition: iso9660.h:42
An El Torito Boot Record Volume Descriptor.
Definition: eltorito.h:29
unsigned int drive
Drive number.
Definition: sanboot.h:54
An El Torito Boot Record Volume Descriptor (fixed portion)
Definition: eltorito.h:17
uint32_t sector
Boot catalog sector.
Definition: eltorito.h:35
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Read from SAN device.
Definition: sanboot.c:636
#define ISO9660_TYPE_BOOT
ISO9660 Boot Volume Descriptor type.
Definition: iso9660.h:39
void * priv
Driver private data.
Definition: sanboot.h:78
#define ELTORITO_LBA
El Torito Boot Record Volume Descriptor block address.
Definition: eltorito.h:39
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
INT 13 SAN device private data.
Definition: int13.c:55

References DBGC, san_device::drive, ELTORITO_LBA, int13(), ISO9660_ID, ISO9660_TYPE_BOOT, memcmp(), san_device::priv, rc, sandev_read(), eltorito_descriptor::sector, strerror(), eltorito_descriptor_fixed::type, and virt_to_user().

Referenced by int13_hook().

◆ int13_guess_geometry_hdd()

static int int13_guess_geometry_hdd ( struct san_device sandev,
void *  scratch,
unsigned int *  heads,
unsigned int *  sectors 
)
static

Guess INT 13 hard disk drive geometry.

Parameters
sandevSAN device
scratchScratch area for single-sector reads
Return values
headsGuessed number of heads
sectorsGuessed number of sectors per track
rcReturn status code

Guesses the drive geometry by inspecting the partition table.

Definition at line 216 of file int13.c.

218  {
219  struct master_boot_record *mbr = scratch;
220  struct partition_table_entry *partition;
221  unsigned int i;
222  unsigned int start_cylinder;
223  unsigned int start_head;
224  unsigned int start_sector;
225  unsigned int end_head;
226  unsigned int end_sector;
227  int rc;
228 
229  /* Read partition table */
230  if ( ( rc = sandev_read ( sandev, 0, 1, virt_to_user ( mbr ) ) ) != 0 ) {
231  DBGC ( sandev, "INT13 drive %02x could not read "
232  "partition table to guess geometry: %s\n",
233  sandev->drive, strerror ( rc ) );
234  return rc;
235  }
236  DBGC2 ( sandev, "INT13 drive %02x has MBR:\n", sandev->drive );
237  DBGC2_HDA ( sandev, 0, mbr, sizeof ( *mbr ) );
238  DBGC ( sandev, "INT13 drive %02x has signature %08x\n",
239  sandev->drive, mbr->signature );
240 
241  /* Scan through partition table and modify guesses for
242  * heads and sectors_per_track if we find any used
243  * partitions.
244  */
245  *heads = 0;
246  *sectors = 0;
247  for ( i = 0 ; i < 4 ; i++ ) {
248 
249  /* Skip empty partitions */
250  partition = &mbr->partitions[i];
251  if ( ! partition->type )
252  continue;
253 
254  /* If partition starts on cylinder 0 then we can
255  * unambiguously determine the number of sectors.
256  */
257  start_cylinder = PART_CYLINDER ( partition->chs_start );
258  start_head = PART_HEAD ( partition->chs_start );
259  start_sector = PART_SECTOR ( partition->chs_start );
260  if ( ( start_cylinder == 0 ) && ( start_head != 0 ) ) {
261  *sectors = ( ( partition->start + 1 - start_sector ) /
262  start_head );
263  DBGC ( sandev, "INT13 drive %02x guessing C/H/S "
264  "xx/xx/%d based on partition %d\n",
265  sandev->drive, *sectors, ( i + 1 ) );
266  }
267 
268  /* If partition ends on a higher head or sector number
269  * than our current guess, then increase the guess.
270  */
271  end_head = PART_HEAD ( partition->chs_end );
272  end_sector = PART_SECTOR ( partition->chs_end );
273  if ( ( end_head + 1 ) > *heads ) {
274  *heads = ( end_head + 1 );
275  DBGC ( sandev, "INT13 drive %02x guessing C/H/S "
276  "xx/%d/xx based on partition %d\n",
277  sandev->drive, *heads, ( i + 1 ) );
278  }
279  if ( end_sector > *sectors ) {
280  *sectors = end_sector;
281  DBGC ( sandev, "INT13 drive %02x guessing C/H/S "
282  "xx/xx/%d based on partition %d\n",
283  sandev->drive, *sectors, ( i + 1 ) );
284  }
285  }
286 
287  /* Default guess is xx/255/63 */
288  if ( ! *heads )
289  *heads = 255;
290  if ( ! *sectors )
291  *sectors = 63;
292 
293  return 0;
294 }
#define PART_CYLINDER(chs)
Definition: int13.h:259
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t signature
Disk signature.
Definition: int13.h:282
struct partition_table_entry partitions[4]
Partition table.
Definition: int13.h:286
uint32_t heads
Number of heads.
Definition: int13.h:18
struct partition_chs chs_end
C/H/S end address.
Definition: int13.h:270
uint32_t start
Linear start address.
Definition: int13.h:272
#define DBGC(...)
Definition: compiler.h:505
uint8_t type
System indicator (partition type)
Definition: int13.h:268
#define PART_HEAD(chs)
Definition: int13.h:257
unsigned int drive
Drive number.
Definition: sanboot.h:54
A Master Boot Record.
Definition: int13.h:278
#define DBGC2_HDA(...)
Definition: compiler.h:523
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Read from SAN device.
Definition: sanboot.c:636
struct partition_chs chs_start
C/H/S start address.
Definition: int13.h:266
#define DBGC2(...)
Definition: compiler.h:522
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
uint64_t sectors
Total number of sectors on drive.
Definition: int13.h:22
A partition table entry within the MBR.
Definition: int13.h:262
#define PART_SECTOR(chs)
Definition: int13.h:258

References partition_table_entry::chs_end, partition_table_entry::chs_start, DBGC, DBGC2, DBGC2_HDA, san_device::drive, heads, PART_CYLINDER, PART_HEAD, PART_SECTOR, master_boot_record::partitions, rc, sandev_read(), sectors, master_boot_record::signature, partition_table_entry::start, strerror(), partition_table_entry::type, and virt_to_user().

Referenced by int13_guess_geometry().

◆ int13_guess_geometry_fdd()

static int int13_guess_geometry_fdd ( struct san_device sandev,
unsigned int *  heads,
unsigned int *  sectors 
)
static

Guess INT 13 floppy disk drive geometry.

Parameters
sandevSAN device
Return values
headsGuessed number of heads
sectorsGuessed number of sectors per track
rcReturn status code

Guesses the drive geometry by inspecting the disk size.

Definition at line 330 of file int13.c.

332  {
333  unsigned int blocks = sandev_capacity ( sandev );
334  const struct int13_fdd_geometry *geometry;
335  unsigned int cylinders;
336  unsigned int i;
337 
338  /* Look for a match against a known geometry */
339  for ( i = 0 ; i < ( sizeof ( int13_fdd_geometries ) /
340  sizeof ( int13_fdd_geometries[0] ) ) ; i++ ) {
341  geometry = &int13_fdd_geometries[i];
342  cylinders = INT13_FDD_CYLINDERS ( geometry );
343  *heads = INT13_FDD_HEADS ( geometry );
344  *sectors = INT13_FDD_SECTORS ( geometry );
345  if ( ( cylinders * (*heads) * (*sectors) ) == blocks ) {
346  DBGC ( sandev, "INT13 drive %02x guessing C/H/S "
347  "%d/%d/%d based on size %dK\n", sandev->drive,
348  cylinders, *heads, *sectors, ( blocks / 2 ) );
349  return 0;
350  }
351  }
352 
353  /* Otherwise, assume a partial disk image in the most common
354  * format (1440K, 80/2/18).
355  */
356  *heads = 2;
357  *sectors = 18;
358  DBGC ( sandev, "INT13 drive %02x guessing C/H/S xx/%d/%d based on size "
359  "%dK\n", sandev->drive, *heads, *sectors, ( blocks / 2 ) );
360  return 0;
361 }
#define INT13_FDD_SECTORS(geometry)
Get floppy disk number of sectors per track.
Definition: int13.h:316
uint32_t heads
Number of heads.
Definition: int13.h:18
uint32_t blocks
Number of blocks within the block description.
Definition: pccrc.h:17
#define DBGC(...)
Definition: compiler.h:505
#define INT13_FDD_HEADS(geometry)
Get floppy disk number of heads.
Definition: int13.h:313
static const struct int13_fdd_geometry int13_fdd_geometries[]
Recognised floppy disk geometries.
Definition: int13.c:297
#define INT13_FDD_CYLINDERS(geometry)
Get floppy disk number of cylinders.
Definition: int13.h:310
unsigned int drive
Drive number.
Definition: sanboot.h:54
static uint64_t sandev_capacity(struct san_device *sandev)
Calculate SAN device capacity.
Definition: sanboot.h:222
A floppy disk geometry.
Definition: int13.h:295
uint32_t cylinders
Number of cylinders.
Definition: int13.h:16
uint64_t sectors
Total number of sectors on drive.
Definition: int13.h:22

References blocks, cylinders, DBGC, san_device::drive, heads, INT13_FDD_CYLINDERS, int13_fdd_geometries, INT13_FDD_HEADS, INT13_FDD_SECTORS, sandev_capacity(), and sectors.

Referenced by int13_guess_geometry().

◆ int13_guess_geometry()

static int int13_guess_geometry ( struct san_device sandev,
void *  scratch 
)
static

Guess INT 13 drive geometry.

Parameters
sandevSAN device
scratchScratch area for single-sector reads
Return values
rcReturn status code

Definition at line 370 of file int13.c.

370  {
371  struct int13_data *int13 = sandev->priv;
372  unsigned int guessed_heads;
373  unsigned int guessed_sectors;
374  unsigned int blocks;
375  unsigned int blocks_per_cyl;
376  int rc;
377 
378  /* Guess geometry according to drive type */
379  if ( int13_is_fdd ( sandev ) ) {
380  if ( ( rc = int13_guess_geometry_fdd ( sandev, &guessed_heads,
381  &guessed_sectors )) != 0)
382  return rc;
383  } else {
384  if ( ( rc = int13_guess_geometry_hdd ( sandev, scratch,
385  &guessed_heads,
386  &guessed_sectors )) != 0)
387  return rc;
388  }
389 
390  /* Apply guesses if no geometry already specified */
391  if ( ! int13->heads )
392  int13->heads = guessed_heads;
393  if ( ! int13->sectors_per_track )
394  int13->sectors_per_track = guessed_sectors;
395  if ( ! int13->cylinders ) {
396  /* Avoid attempting a 64-bit divide on a 32-bit system */
397  blocks = int13_capacity32 ( sandev );
398  blocks_per_cyl = ( int13->heads * int13->sectors_per_track );
399  assert ( blocks_per_cyl != 0 );
400  int13->cylinders = ( blocks / blocks_per_cyl );
401  if ( int13->cylinders > 1024 )
402  int13->cylinders = 1024;
403  }
404 
405  return 0;
406 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int int13_is_fdd(struct san_device *sandev)
Test if SAN device is a floppy disk drive.
Definition: int13.c:159
static __asmcall __used void int13(struct i386_all_regs *ix86)
INT 13 handler.
Definition: int13.c:1067
uint32_t blocks
Number of blocks within the block description.
Definition: pccrc.h:17
static int int13_guess_geometry_fdd(struct san_device *sandev, unsigned int *heads, unsigned int *sectors)
Guess INT 13 floppy disk drive geometry.
Definition: int13.c:330
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static int int13_guess_geometry_hdd(struct san_device *sandev, void *scratch, unsigned int *heads, unsigned int *sectors)
Guess INT 13 hard disk drive geometry.
Definition: int13.c:216
void * priv
Driver private data.
Definition: sanboot.h:78
static uint32_t int13_capacity32(struct san_device *sandev)
Calculate SAN device capacity (limited to 32 bits)
Definition: int13.c:148
INT 13 SAN device private data.
Definition: int13.c:55

References assert(), blocks, int13(), int13_capacity32(), int13_guess_geometry_fdd(), int13_guess_geometry_hdd(), int13_is_fdd(), san_device::priv, and rc.

Referenced by int13_hook().

◆ int13_sync_num_drives()

static void int13_sync_num_drives ( void  )
static

Update BIOS drive count.

Definition at line 411 of file int13.c.

411  {
412  struct san_device *sandev;
413  struct int13_data *int13;
414  uint8_t *counter;
415  uint8_t max_drive;
416  uint8_t required;
417 
418  /* Get current drive counts */
421  num_fdds = ( ( equipment_word & 0x0001 ) ?
422  ( ( ( equipment_word >> 6 ) & 0x3 ) + 1 ) : 0 );
423 
424  /* Ensure count is large enough to cover all of our SAN devices */
425  for_each_sandev ( sandev ) {
426  int13 = sandev->priv;
427  counter = ( int13_is_fdd ( sandev ) ? &num_fdds : &num_drives );
428  max_drive = sandev->drive;
429  if ( max_drive < int13->natural_drive )
430  max_drive = int13->natural_drive;
431  required = ( ( max_drive & 0x7f ) + 1 );
432  if ( *counter < required ) {
433  *counter = required;
434  DBGC ( sandev, "INT13 drive %02x added to drive count: "
435  "%d HDDs, %d FDDs\n",
436  sandev->drive, num_drives, num_fdds );
437  }
438  }
439 
440  /* Update current drive count */
441  equipment_word &= ~( ( 0x3 << 6 ) | 0x0001 );
442  if ( num_fdds ) {
443  equipment_word |= ( 0x0001 |
444  ( ( ( num_fdds - 1 ) & 0x3 ) << 6 ) );
445  }
448 }
static int int13_is_fdd(struct san_device *sandev)
Test if SAN device is a floppy disk drive.
Definition: int13.c:159
static __asmcall __used void int13(struct i386_all_regs *ix86)
INT 13 handler.
Definition: int13.c:1067
#define get_real
Definition: libkir.h:151
#define DBGC(...)
Definition: compiler.h:505
#define put_real
Definition: libkir.h:150
unsigned int drive
Drive number.
Definition: sanboot.h:54
#define num_fdds
Definition: int13.c:130
A SAN device.
Definition: sanboot.h:47
unsigned char uint8_t
Definition: stdint.h:10
#define BDA_NUM_DRIVES
Definition: bios.h:19
#define for_each_sandev(sandev)
Iterate over all SAN devices.
Definition: sanboot.h:173
#define BDA_EQUIPMENT_WORD
Definition: bios.h:8
#define BDA_SEG
Definition: bios.h:6
#define num_drives
Definition: int13.c:140
void * priv
Driver private data.
Definition: sanboot.h:78
unsigned int natural_drive
BIOS natural drive number (0x00-0xff)
Definition: int13.c:66
static uint16_t equipment_word
Equipment word.
Definition: int13.c:121
INT 13 SAN device private data.
Definition: int13.c:55

References BDA_EQUIPMENT_WORD, BDA_NUM_DRIVES, BDA_SEG, DBGC, san_device::drive, equipment_word, for_each_sandev, get_real, int13(), int13_is_fdd(), int13_data::natural_drive, num_drives, num_fdds, san_device::priv, and put_real.

Referenced by int13_check_num_drives(), and int13_hook().

◆ int13_check_num_drives()

static void int13_check_num_drives ( void  )
static

Check number of drives.

Definition at line 453 of file int13.c.

453  {
454  uint16_t check_equipment_word;
455  uint8_t check_num_drives;
456 
457  get_real ( check_equipment_word, BDA_SEG, BDA_EQUIPMENT_WORD );
458  get_real ( check_num_drives, BDA_SEG, BDA_NUM_DRIVES );
459  if ( ( check_equipment_word != equipment_word ) ||
460  ( check_num_drives != num_drives ) ) {
462  }
463 }
unsigned short uint16_t
Definition: stdint.h:11
#define get_real
Definition: libkir.h:151
static void int13_sync_num_drives(void)
Update BIOS drive count.
Definition: int13.c:411
unsigned char uint8_t
Definition: stdint.h:10
#define BDA_NUM_DRIVES
Definition: bios.h:19
#define BDA_EQUIPMENT_WORD
Definition: bios.h:8
#define BDA_SEG
Definition: bios.h:6
#define num_drives
Definition: int13.c:140
static uint16_t equipment_word
Equipment word.
Definition: int13.c:121

References BDA_EQUIPMENT_WORD, BDA_NUM_DRIVES, BDA_SEG, equipment_word, get_real, int13_sync_num_drives(), and num_drives.

Referenced by int13().

◆ int13_reset()

static int int13_reset ( struct san_device sandev,
struct i386_all_regs *ix86  __unused 
)
static

INT 13, 00 - Reset disk system.

Parameters
sandevSAN device
Return values
statusStatus code

Definition at line 471 of file int13.c.

472  {
473  int rc;
474 
475  DBGC2 ( sandev, "Reset drive\n" );
476 
477  /* Reset SAN device */
478  if ( ( rc = sandev_reset ( sandev ) ) != 0 )
480 
481  return 0;
482 }
int sandev_reset(struct san_device *sandev)
Reset SAN device.
Definition: sanboot.c:565
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define INT13_STATUS_RESET_FAILED
Reset failed.
Definition: int13.h:65
#define DBGC2(...)
Definition: compiler.h:522

References DBGC2, INT13_STATUS_RESET_FAILED, rc, and sandev_reset().

Referenced by int13().

◆ int13_get_last_status()

static int int13_get_last_status ( struct san_device sandev,
struct i386_all_regs *ix86  __unused 
)
static

INT 13, 01 - Get status of last operation.

Parameters
sandevSAN device
Return values
statusStatus code

Definition at line 490 of file int13.c.

491  {
492  struct int13_data *int13 = sandev->priv;
493 
494  DBGC2 ( sandev, "Get status of last operation\n" );
495  return int13->last_status;
496 }
static __asmcall __used void int13(struct i386_all_regs *ix86)
INT 13 handler.
Definition: int13.c:1067
#define DBGC2(...)
Definition: compiler.h:522
void * priv
Driver private data.
Definition: sanboot.h:78
INT 13 SAN device private data.
Definition: int13.c:55

References DBGC2, int13(), and san_device::priv.

Referenced by int13().

◆ int13_rw_sectors()

static int int13_rw_sectors ( struct san_device sandev,
struct i386_all_regs ix86,
int(*)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer sandev_rw 
)
static

Read / write sectors.

Parameters
sandevSAN device
alNumber of sectors to read or write (must be nonzero)
chLow bits of cylinder number
cl(bits 7:6) High bits of cylinder number
cl(bits 5:0) Sector number
dhHead number
es:bxData buffer
sandev_rwSAN device read/write method
Return values
statusStatus code
alNumber of sectors read or written

Definition at line 512 of file int13.c.

517  {
518  struct int13_data *int13 = sandev->priv;
519  unsigned int cylinder, head, sector;
520  unsigned long lba;
521  unsigned int count;
523  int rc;
524 
525  /* Validate blocksize */
526  if ( sandev_blksize ( sandev ) != INT13_BLKSIZE ) {
527  DBGC ( sandev, "\nINT 13 drive %02x invalid blocksize (%zd) "
528  "for non-extended read/write\n",
529  sandev->drive, sandev_blksize ( sandev ) );
530  return -INT13_STATUS_INVALID;
531  }
532 
533  /* Calculate parameters */
534  cylinder = ( ( ( ix86->regs.cl & 0xc0 ) << 2 ) | ix86->regs.ch );
535  head = ix86->regs.dh;
536  sector = ( ix86->regs.cl & 0x3f );
537  if ( ( cylinder >= int13->cylinders ) ||
538  ( head >= int13->heads ) ||
539  ( sector < 1 ) || ( sector > int13->sectors_per_track ) ) {
540  DBGC ( sandev, "C/H/S %d/%d/%d out of range for geometry "
541  "%d/%d/%d\n", cylinder, head, sector, int13->cylinders,
542  int13->heads, int13->sectors_per_track );
543  return -INT13_STATUS_INVALID;
544  }
545  lba = ( ( ( ( cylinder * int13->heads ) + head )
546  * int13->sectors_per_track ) + sector - 1 );
547  count = ix86->regs.al;
548  buffer = real_to_user ( ix86->segs.es, ix86->regs.bx );
549 
550  DBGC2 ( sandev, "C/H/S %d/%d/%d = LBA %08lx <-> %04x:%04x (count %d)\n",
551  cylinder, head, sector, lba, ix86->segs.es, ix86->regs.bx,
552  count );
553 
554  /* Read from / write to block device */
555  if ( ( rc = sandev_rw ( sandev, lba, count, buffer ) ) != 0 ){
556  DBGC ( sandev, "INT13 drive %02x I/O failed: %s\n",
557  sandev->drive, strerror ( rc ) );
558  return -INT13_STATUS_READ_ERROR;
559  }
560 
561  return 0;
562 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct i386_seg_regs segs
Definition: registers.h:175
uint32_t lba
Start address.
Definition: scsi.h:23
static __asmcall __used void int13(struct i386_all_regs *ix86)
INT 13 handler.
Definition: int13.c:1067
uint16_t es
Definition: registers.h:142
uint8_t dh
Definition: registers.h:90
static int sandev_rw(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer, int(*block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, userptr_t buffer, size_t len))
Read from or write to SAN device.
Definition: sanboot.c:587
#define DBGC(...)
Definition: compiler.h:505
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
uint8_t head
Head number.
Definition: int13.h:34
#define INT13_STATUS_READ_ERROR
Read error.
Definition: int13.h:63
#define INT13_BLKSIZE
Block size for non-extended INT 13 calls.
Definition: int13.h:72
uint32_t sector
Boot catalog sector.
Definition: eltorito.h:17
struct i386_regs regs
Definition: registers.h:176
unsigned int drive
Drive number.
Definition: sanboot.h:54
#define INT13_STATUS_INVALID
Invalid function or parameter.
Definition: int13.h:61
uint16_t bx
Definition: registers.h:84
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint8_t cl
Definition: registers.h:97
#define DBGC2(...)
Definition: compiler.h:522
void * priv
Driver private data.
Definition: sanboot.h:78
uint16_t count
Number of entries.
Definition: ena.h:22
static size_t sandev_blksize(struct san_device *sandev)
Calculate SAN device block size.
Definition: sanboot.h:212
static __always_inline userptr_t real_to_user(unsigned int segment, unsigned int offset)
Convert segment:offset address to user buffer.
Definition: realmode.h:75
uint8_t al
Definition: registers.h:105
uint8_t ch
Definition: registers.h:98
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
INT 13 SAN device private data.
Definition: int13.c:55

References i386_regs::al, buffer, i386_regs::bx, i386_regs::ch, i386_regs::cl, count, DBGC, DBGC2, i386_regs::dh, san_device::drive, i386_seg_regs::es, head, int13(), INT13_BLKSIZE, INT13_STATUS_INVALID, INT13_STATUS_READ_ERROR, lba, san_device::priv, rc, real_to_user(), i386_all_regs::regs, sandev_blksize(), sandev_rw(), sector, i386_all_regs::segs, and strerror().

Referenced by int13_read_sectors(), and int13_write_sectors().

◆ int13_read_sectors()

static int int13_read_sectors ( struct san_device sandev,
struct i386_all_regs ix86 
)
static

INT 13, 02 - Read sectors.

Parameters
sandevSAN device
alNumber of sectors to read (must be nonzero)
chLow bits of cylinder number
cl(bits 7:6) High bits of cylinder number
cl(bits 5:0) Sector number
dhHead number
es:bxData buffer
Return values
statusStatus code
alNumber of sectors read

Definition at line 577 of file int13.c.

578  {
579 
580  DBGC2 ( sandev, "Read: " );
581  return int13_rw_sectors ( sandev, ix86, sandev_read );
582 }
static int int13_rw_sectors(struct san_device *sandev, struct i386_all_regs *ix86, int(*sandev_rw)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer))
Read / write sectors.
Definition: int13.c:512
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Read from SAN device.
Definition: sanboot.c:636
#define DBGC2(...)
Definition: compiler.h:522

References DBGC2, int13_rw_sectors(), and sandev_read().

Referenced by int13().

◆ int13_write_sectors()

static int int13_write_sectors ( struct san_device sandev,
struct i386_all_regs ix86 
)
static

INT 13, 03 - Write sectors.

Parameters
sandevSAN device
alNumber of sectors to write (must be nonzero)
chLow bits of cylinder number
cl(bits 7:6) High bits of cylinder number
cl(bits 5:0) Sector number
dhHead number
es:bxData buffer
Return values
statusStatus code
alNumber of sectors written

Definition at line 597 of file int13.c.

598  {
599 
600  DBGC2 ( sandev, "Write: " );
601  return int13_rw_sectors ( sandev, ix86, sandev_write );
602 }
static int int13_rw_sectors(struct san_device *sandev, struct i386_all_regs *ix86, int(*sandev_rw)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer))
Read / write sectors.
Definition: int13.c:512
#define DBGC2(...)
Definition: compiler.h:522
int sandev_write(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Write to SAN device.
Definition: sanboot.c:656

References DBGC2, int13_rw_sectors(), and sandev_write().

Referenced by int13().

◆ int13_get_parameters()

static int int13_get_parameters ( struct san_device sandev,
struct i386_all_regs ix86 
)
static

INT 13, 08 - Get drive parameters.

Parameters
sandevSAN device
Return values
statusStatus code
chLow bits of maximum cylinder number
cl(bits 7:6) High bits of maximum cylinder number
cl(bits 5:0) Maximum sector number
dhMaximum head number
dlNumber of drives

Definition at line 615 of file int13.c.

616  {
617  struct int13_data *int13 = sandev->priv;
618  unsigned int max_cylinder = int13->cylinders - 1;
619  unsigned int max_head = int13->heads - 1;
620  unsigned int max_sector = int13->sectors_per_track; /* sic */
621 
622  DBGC2 ( sandev, "Get drive parameters\n" );
623 
624  /* Validate blocksize */
625  if ( sandev_blksize ( sandev ) != INT13_BLKSIZE ) {
626  DBGC ( sandev, "\nINT 13 drive %02x invalid blocksize (%zd) "
627  "for non-extended parameters\n",
628  sandev->drive, sandev_blksize ( sandev ) );
629  return -INT13_STATUS_INVALID;
630  }
631 
632  /* Common parameters */
633  ix86->regs.ch = ( max_cylinder & 0xff );
634  ix86->regs.cl = ( ( ( max_cylinder >> 8 ) << 6 ) | max_sector );
635  ix86->regs.dh = max_head;
636  ix86->regs.dl = ( int13_is_fdd ( sandev ) ? num_fdds : num_drives );
637 
638  /* Floppy-specific parameters */
639  if ( int13_is_fdd ( sandev ) ) {
640  ix86->regs.bl = INT13_FDD_TYPE_1M44;
641  ix86->segs.es = rm_ds;
642  ix86->regs.di = __from_data16 ( &int13_fdd_params );
643  }
644 
645  return 0;
646 }
struct i386_seg_regs segs
Definition: registers.h:175
static int int13_is_fdd(struct san_device *sandev)
Test if SAN device is a floppy disk drive.
Definition: int13.c:159
static __asmcall __used void int13(struct i386_all_regs *ix86)
INT 13 handler.
Definition: int13.c:1067
uint16_t es
Definition: registers.h:142
uint8_t dh
Definition: registers.h:90
#define DBGC(...)
Definition: compiler.h:505
#define rm_ds
Definition: libkir.h:39
#define INT13_BLKSIZE
Block size for non-extended INT 13 calls.
Definition: int13.h:72
uint8_t bl
Definition: registers.h:81
struct i386_regs regs
Definition: registers.h:176
unsigned int drive
Drive number.
Definition: sanboot.h:54
#define INT13_STATUS_INVALID
Invalid function or parameter.
Definition: int13.h:61
#define int13_fdd_params
Definition: int13.c:113
#define num_fdds
Definition: int13.c:130
#define INT13_FDD_TYPE_1M44
1.44M
Definition: int13.h:85
uint8_t cl
Definition: registers.h:97
uint16_t di
Definition: registers.h:64
#define DBGC2(...)
Definition: compiler.h:522
#define num_drives
Definition: int13.c:140
#define __from_data16(pointer)
Definition: libkir.h:22
void * priv
Driver private data.
Definition: sanboot.h:78
static size_t sandev_blksize(struct san_device *sandev)
Calculate SAN device block size.
Definition: sanboot.h:212
uint8_t ch
Definition: registers.h:98
INT 13 SAN device private data.
Definition: int13.c:55
uint8_t dl
Definition: registers.h:89

References __from_data16, i386_regs::bl, i386_regs::ch, i386_regs::cl, DBGC, DBGC2, i386_regs::dh, i386_regs::di, i386_regs::dl, san_device::drive, i386_seg_regs::es, int13(), INT13_BLKSIZE, int13_fdd_params, INT13_FDD_TYPE_1M44, int13_is_fdd(), INT13_STATUS_INVALID, num_drives, num_fdds, san_device::priv, i386_all_regs::regs, rm_ds, sandev_blksize(), and i386_all_regs::segs.

Referenced by int13().

◆ int13_get_disk_type()

static int int13_get_disk_type ( struct san_device sandev,
struct i386_all_regs ix86 
)
static

INT 13, 15 - Get disk type.

Parameters
sandevSAN device
Return values
ahType code
cx:dxSector count
statusStatus code / disk type

Definition at line 656 of file int13.c.

657  {
659 
660  DBGC2 ( sandev, "Get disk type\n" );
661 
662  if ( int13_is_fdd ( sandev ) ) {
663  return INT13_DISK_TYPE_FDD;
664  } else {
665  blocks = int13_capacity32 ( sandev );
666  ix86->regs.cx = ( blocks >> 16 );
667  ix86->regs.dx = ( blocks & 0xffff );
668  return INT13_DISK_TYPE_HDD;
669  }
670 }
static int int13_is_fdd(struct san_device *sandev)
Test if SAN device is a floppy disk drive.
Definition: int13.c:159
uint32_t blocks
Number of blocks within the block description.
Definition: pccrc.h:17
#define INT13_DISK_TYPE_HDD
Hard disk.
Definition: int13.h:143
struct i386_regs regs
Definition: registers.h:176
uint16_t cx
Definition: registers.h:100
uint16_t dx
Definition: registers.h:92
#define INT13_DISK_TYPE_FDD
Floppy without change-line support.
Definition: int13.h:139
unsigned int uint32_t
Definition: stdint.h:12
#define DBGC2(...)
Definition: compiler.h:522
static uint32_t int13_capacity32(struct san_device *sandev)
Calculate SAN device capacity (limited to 32 bits)
Definition: int13.c:148

References blocks, i386_regs::cx, DBGC2, i386_regs::dx, int13_capacity32(), INT13_DISK_TYPE_FDD, INT13_DISK_TYPE_HDD, int13_is_fdd(), and i386_all_regs::regs.

Referenced by int13().

◆ int13_extension_check()

static int int13_extension_check ( struct san_device sandev,
struct i386_all_regs ix86 
)
static

INT 13, 41 - Extensions installation check.

Parameters
sandevSAN device
bx0x55aa
Return values
bx0xaa55
cxExtensions API support bitmap
statusStatus code / API version

Definition at line 681 of file int13.c.

682  {
683 
684  if ( ( ix86->regs.bx == 0x55aa ) && ! int13_is_fdd ( sandev ) ) {
685  DBGC2 ( sandev, "INT13 extensions installation check\n" );
686  ix86->regs.bx = 0xaa55;
687  ix86->regs.cx = ( INT13_EXTENSION_LINEAR |
691  } else {
692  return -INT13_STATUS_INVALID;
693  }
694 }
static int int13_is_fdd(struct san_device *sandev)
Test if SAN device is a floppy disk drive.
Definition: int13.c:159
#define INT13_EXTENSION_EDD
EDD functions supported.
Definition: int13.h:179
#define INT13_EXTENSION_LINEAR
Extended disk access functions supported.
Definition: int13.h:175
struct i386_regs regs
Definition: registers.h:176
uint16_t cx
Definition: registers.h:100
#define INT13_EXTENSION_VER_3_0
INT13 extensions version 3.0 (EDD-3.0)
Definition: int13.h:197
#define INT13_STATUS_INVALID
Invalid function or parameter.
Definition: int13.h:61
uint16_t bx
Definition: registers.h:84
#define INT13_EXTENSION_64BIT
64-bit extensions are present
Definition: int13.h:181
#define DBGC2(...)
Definition: compiler.h:522

References i386_regs::bx, i386_regs::cx, DBGC2, INT13_EXTENSION_64BIT, INT13_EXTENSION_EDD, INT13_EXTENSION_LINEAR, INT13_EXTENSION_VER_3_0, int13_is_fdd(), INT13_STATUS_INVALID, and i386_all_regs::regs.

Referenced by int13().

◆ int13_extended_rw()

static int int13_extended_rw ( struct san_device sandev,
struct i386_all_regs ix86,
int(*)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer sandev_rw 
)
static

Extended read / write.

Parameters
sandevSAN device
ds:siDisk address packet
sandev_rwSAN device read/write method
Return values
statusStatus code

Definition at line 704 of file int13.c.

709  {
710  struct int13_disk_address addr;
712  uint64_t lba;
713  unsigned long count;
715  int rc;
716 
717  /* Extended reads are not allowed on floppy drives.
718  * ELTORITO.SYS seems to assume that we are really a CD-ROM if
719  * we support extended reads for a floppy drive.
720  */
721  if ( int13_is_fdd ( sandev ) )
722  return -INT13_STATUS_INVALID;
723 
724  /* Get buffer size */
725  get_real ( bufsize, ix86->segs.ds,
726  ( ix86->regs.si + offsetof ( typeof ( addr ), bufsize ) ) );
727  if ( bufsize < offsetof ( typeof ( addr ), buffer_phys ) ) {
728  DBGC2 ( sandev, "<invalid buffer size %#02x\n>\n", bufsize );
729  return -INT13_STATUS_INVALID;
730  }
731 
732  /* Read parameters from disk address structure */
733  memset ( &addr, 0, sizeof ( addr ) );
734  copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, bufsize );
735  lba = addr.lba;
736  DBGC2 ( sandev, "LBA %08llx <-> ", ( ( unsigned long long ) lba ) );
737  if ( ( addr.count == 0xff ) ||
738  ( ( addr.buffer.segment == 0xffff ) &&
739  ( addr.buffer.offset == 0xffff ) ) ) {
740  buffer = phys_to_user ( addr.buffer_phys );
741  DBGC2 ( sandev, "%08llx",
742  ( ( unsigned long long ) addr.buffer_phys ) );
743  } else {
744  buffer = real_to_user ( addr.buffer.segment,
745  addr.buffer.offset );
746  DBGC2 ( sandev, "%04x:%04x", addr.buffer.segment,
747  addr.buffer.offset );
748  }
749  if ( addr.count <= 0x7f ) {
750  count = addr.count;
751  } else if ( addr.count == 0xff ) {
752  count = addr.long_count;
753  } else {
754  DBGC2 ( sandev, " <invalid count %#02x>\n", addr.count );
755  return -INT13_STATUS_INVALID;
756  }
757  DBGC2 ( sandev, " (count %ld)\n", count );
758 
759  /* Read from / write to block device */
760  if ( ( rc = sandev_rw ( sandev, lba, count, buffer ) ) != 0 ) {
761  DBGC ( sandev, "INT13 drive %02x extended I/O failed: %s\n",
762  sandev->drive, strerror ( rc ) );
763  /* Record that no blocks were transferred successfully */
764  addr.count = 0;
765  put_real ( addr.count, ix86->segs.ds,
766  ( ix86->regs.si +
767  offsetof ( typeof ( addr ), count ) ) );
768  return -INT13_STATUS_READ_ERROR;
769  }
770 
771  return 0;
772 }
uint64_t buffer_phys
Data buffer (EDD 3.0+ only)
Definition: int13.h:24
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct i386_seg_regs segs
Definition: registers.h:175
static int int13_is_fdd(struct san_device *sandev)
Test if SAN device is a floppy disk drive.
Definition: int13.c:159
uint32_t lba
Start address.
Definition: scsi.h:23
static int sandev_rw(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer, int(*block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, userptr_t buffer, size_t len))
Read from or write to SAN device.
Definition: sanboot.c:587
An INT 13 disk address packet.
Definition: int13.h:88
#define get_real
Definition: libkir.h:151
#define DBGC(...)
Definition: compiler.h:505
unsigned long long uint64_t
Definition: stdint.h:13
userptr_t phys_to_user(unsigned long phys_addr)
Convert physical address to user pointer.
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
#define INT13_STATUS_READ_ERROR
Read error.
Definition: int13.h:63
#define put_real
Definition: libkir.h:150
struct i386_regs regs
Definition: registers.h:176
unsigned int drive
Drive number.
Definition: sanboot.h:54
#define INT13_STATUS_INVALID
Invalid function or parameter.
Definition: int13.h:61
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint16_t ds
Definition: registers.h:141
u32 addr
Definition: sky2.h:8
unsigned char uint8_t
Definition: stdint.h:10
#define copy_from_real
Definition: libkir.h:79
#define DBGC2(...)
Definition: compiler.h:522
uint16_t count
Number of entries.
Definition: ena.h:22
static __always_inline userptr_t real_to_user(unsigned int segment, unsigned int offset)
Convert segment:offset address to user buffer.
Definition: realmode.h:75
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
uint16_t si
Definition: registers.h:68
uint8_t bufsize
Size of the packet, in bytes.
Definition: int13.h:12
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
void * memset(void *dest, int character, size_t len) __nonnull

References addr, buffer, buffer_phys, bufsize, copy_from_real, count, DBGC, DBGC2, san_device::drive, i386_seg_regs::ds, get_real, int13_is_fdd(), INT13_STATUS_INVALID, INT13_STATUS_READ_ERROR, lba, memset(), offsetof, phys_to_user(), put_real, rc, real_to_user(), i386_all_regs::regs, sandev_rw(), i386_all_regs::segs, i386_regs::si, strerror(), and typeof().

Referenced by int13_extended_read(), and int13_extended_write().

◆ int13_extended_read()

static int int13_extended_read ( struct san_device sandev,
struct i386_all_regs ix86 
)
static

INT 13, 42 - Extended read.

Parameters
sandevSAN device
ds:siDisk address packet
Return values
statusStatus code

Definition at line 781 of file int13.c.

782  {
783 
784  DBGC2 ( sandev, "Extended read: " );
785  return int13_extended_rw ( sandev, ix86, sandev_read );
786 }
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Read from SAN device.
Definition: sanboot.c:636
#define DBGC2(...)
Definition: compiler.h:522
static int int13_extended_rw(struct san_device *sandev, struct i386_all_regs *ix86, int(*sandev_rw)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer))
Extended read / write.
Definition: int13.c:704

References DBGC2, int13_extended_rw(), and sandev_read().

Referenced by int13().

◆ int13_extended_write()

static int int13_extended_write ( struct san_device sandev,
struct i386_all_regs ix86 
)
static

INT 13, 43 - Extended write.

Parameters
sandevSAN device
ds:siDisk address packet
Return values
statusStatus code

Definition at line 795 of file int13.c.

796  {
797 
798  DBGC2 ( sandev, "Extended write: " );
799  return int13_extended_rw ( sandev, ix86, sandev_write );
800 }
#define DBGC2(...)
Definition: compiler.h:522
static int int13_extended_rw(struct san_device *sandev, struct i386_all_regs *ix86, int(*sandev_rw)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer))
Extended read / write.
Definition: int13.c:704
int sandev_write(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Write to SAN device.
Definition: sanboot.c:656

References DBGC2, int13_extended_rw(), and sandev_write().

Referenced by int13().

◆ int13_extended_verify()

static int int13_extended_verify ( struct san_device sandev,
struct i386_all_regs ix86 
)
static

INT 13, 44 - Verify sectors.

Parameters
sandevSAN device
ds:siDisk address packet
Return values
statusStatus code

Definition at line 809 of file int13.c.

810  {
811  struct int13_disk_address addr;
812  uint64_t lba;
813  unsigned long count;
814 
815  /* Read parameters from disk address structure */
816  if ( DBG_EXTRA ) {
817  copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si,
818  sizeof ( addr ));
819  lba = addr.lba;
820  count = addr.count;
821  DBGC2 ( sandev, "Verify: LBA %08llx (count %ld)\n",
822  ( ( unsigned long long ) lba ), count );
823  }
824 
825  /* We have no mechanism for verifying sectors */
826  return -INT13_STATUS_INVALID;
827 }
struct i386_seg_regs segs
Definition: registers.h:175
uint32_t lba
Start address.
Definition: scsi.h:23
An INT 13 disk address packet.
Definition: int13.h:88
unsigned long long uint64_t
Definition: stdint.h:13
struct i386_regs regs
Definition: registers.h:176
#define INT13_STATUS_INVALID
Invalid function or parameter.
Definition: int13.h:61
uint16_t ds
Definition: registers.h:141
u32 addr
Definition: sky2.h:8
#define copy_from_real
Definition: libkir.h:79
#define DBGC2(...)
Definition: compiler.h:522
uint16_t count
Number of entries.
Definition: ena.h:22
#define DBG_EXTRA
Definition: compiler.h:319
uint16_t si
Definition: registers.h:68

References addr, copy_from_real, count, DBG_EXTRA, DBGC2, i386_seg_regs::ds, INT13_STATUS_INVALID, lba, i386_all_regs::regs, i386_all_regs::segs, and i386_regs::si.

Referenced by int13().

◆ int13_extended_seek()

static int int13_extended_seek ( struct san_device sandev,
struct i386_all_regs ix86 
)
static

INT 13, 44 - Extended seek.

Parameters
sandevSAN device
ds:siDisk address packet
Return values
statusStatus code

Definition at line 836 of file int13.c.

837  {
838  struct int13_disk_address addr;
839  uint64_t lba;
840  unsigned long count;
841 
842  /* Read parameters from disk address structure */
843  if ( DBG_EXTRA ) {
844  copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si,
845  sizeof ( addr ));
846  lba = addr.lba;
847  count = addr.count;
848  DBGC2 ( sandev, "Seek: LBA %08llx (count %ld)\n",
849  ( ( unsigned long long ) lba ), count );
850  }
851 
852  /* Ignore and return success */
853  return 0;
854 }
struct i386_seg_regs segs
Definition: registers.h:175
uint32_t lba
Start address.
Definition: scsi.h:23
An INT 13 disk address packet.
Definition: int13.h:88
unsigned long long uint64_t
Definition: stdint.h:13
struct i386_regs regs
Definition: registers.h:176
uint16_t ds
Definition: registers.h:141
u32 addr
Definition: sky2.h:8
#define copy_from_real
Definition: libkir.h:79
#define DBGC2(...)
Definition: compiler.h:522
uint16_t count
Number of entries.
Definition: ena.h:22
#define DBG_EXTRA
Definition: compiler.h:319
uint16_t si
Definition: registers.h:68

References addr, copy_from_real, count, DBG_EXTRA, DBGC2, i386_seg_regs::ds, lba, i386_all_regs::regs, i386_all_regs::segs, and i386_regs::si.

Referenced by int13().

◆ int13_device_path_info()

static int int13_device_path_info ( struct san_device sandev,
struct edd_device_path_information dpi 
)
static

Build device path information.

Parameters
sandevSAN device
dpiDevice path information
Return values
rcReturn status code

Definition at line 863 of file int13.c.

864  {
865  struct san_path *sanpath;
866  struct device *device;
867  struct device_description *desc;
868  unsigned int i;
869  uint8_t sum = 0;
870  int rc;
871 
872  /* Reopen block device if necessary */
873  if ( sandev_needs_reopen ( sandev ) &&
874  ( ( rc = sandev_reopen ( sandev ) ) != 0 ) )
875  return rc;
876  sanpath = sandev->active;
877  assert ( sanpath != NULL );
878 
879  /* Get underlying hardware device */
880  device = identify_device ( &sanpath->block );
881  if ( ! device ) {
882  DBGC ( sandev, "INT13 drive %02x cannot identify hardware "
883  "device\n", sandev->drive );
884  return -ENODEV;
885  }
886 
887  /* Fill in bus type and interface path */
888  desc = &device->desc;
889  switch ( desc->bus_type ) {
890  case BUS_TYPE_PCI:
892  dpi->interface_path.pci.bus = PCI_BUS ( desc->location );
893  dpi->interface_path.pci.slot = PCI_SLOT ( desc->location );
894  dpi->interface_path.pci.function = PCI_FUNC ( desc->location );
895  dpi->interface_path.pci.channel = 0xff; /* unused */
896  break;
897  default:
898  DBGC ( sandev, "INT13 drive %02x unrecognised bus type %d\n",
899  sandev->drive, desc->bus_type );
900  return -ENOTSUP;
901  }
902 
903  /* Get EDD block device description */
904  if ( ( rc = edd_describe ( &sanpath->block, &dpi->interface_type,
905  &dpi->device_path ) ) != 0 ) {
906  DBGC ( sandev, "INT13 drive %02x cannot identify block device: "
907  "%s\n", sandev->drive, strerror ( rc ) );
908  return rc;
909  }
910 
911  /* Fill in common fields and fix checksum */
913  dpi->len = sizeof ( *dpi );
914  for ( i = 0 ; i < sizeof ( *dpi ) ; i++ )
915  sum += *( ( ( uint8_t * ) dpi ) + i );
916  dpi->checksum -= sum;
917 
918  return 0;
919 }
#define PCI_FUNC(busdevfn)
Definition: pci.h:281
struct edd_host_bus_type host_bus_type
Host bus type.
Definition: edd.h:170
#define PCI_BUS(busdevfn)
Definition: pci.h:279
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct edd_interface_type interface_type
Interface type.
Definition: edd.h:172
uint8_t slot
Slot.
Definition: edd.h:87
int edd_describe(struct interface *intf, struct edd_interface_type *type, union edd_device_path *path)
Describe a disk device using EDD.
Definition: edd.c:44
#define DBGC(...)
Definition: compiler.h:505
struct interface block
Underlying block device interface.
Definition: sanboot.h:36
#define EDD_BUS_TYPE_PCI
EDD PCI bus type.
Definition: edd.h:27
#define EDD_DEVICE_PATH_INFO_KEY
EDD device path information key.
Definition: edd.h:184
uint8_t channel
Channel number.
Definition: edd.h:91
static int sandev_needs_reopen(struct san_device *sandev)
Check if SAN device needs to be reopened.
Definition: sanboot.h:232
uint16_t device
Device ID.
Definition: ena.h:24
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
A hardware device description.
Definition: device.h:19
union edd_device_path device_path
Device path.
Definition: edd.h:176
uint8_t bus
Bus.
Definition: edd.h:85
A hardware device.
Definition: device.h:73
#define BUS_TYPE_PCI
PCI bus type.
Definition: device.h:43
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
A SAN path.
Definition: sanboot.h:25
unsigned int drive
Drive number.
Definition: sanboot.h:54
uint8_t len
Length of this structure.
Definition: edd.h:166
struct edd_device_path_information dpi
Device path information.
Definition: int13.h:28
unsigned int location
Location.
Definition: device.h:29
uint16_t key
Key.
Definition: edd.h:164
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define PCI_SLOT(busdevfn)
Definition: pci.h:280
#define ENODEV
No such device.
Definition: errno.h:509
unsigned char uint8_t
Definition: stdint.h:10
unsigned int bus_type
Bus type.
Definition: device.h:24
uint8_t function
Function.
Definition: edd.h:89
struct device_description desc
Device description.
Definition: device.h:79
struct device * identify_device(struct interface *intf)
Identify a device behind an interface.
Definition: device.c:125
uint8_t checksum
Checksum.
Definition: edd.h:180
struct san_path * active
Current active path.
Definition: sanboot.h:83
union edd_interface_path interface_path
Interface path.
Definition: edd.h:174
int sandev_reopen(struct san_device *sandev)
(Re)open SAN device
Definition: sanboot.c:365
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
uint32_t type
Type.
Definition: edd.h:18

References san_device::active, assert(), san_path::block, edd_interface_path::bus, device_description::bus_type, BUS_TYPE_PCI, edd_interface_path::channel, edd_device_path_information::checksum, DBGC, device::desc, device, edd_device_path_information::device_path, dpi, san_device::drive, EDD_BUS_TYPE_PCI, edd_describe(), EDD_DEVICE_PATH_INFO_KEY, ENODEV, ENOTSUP, edd_interface_path::function, edd_device_path_information::host_bus_type, identify_device(), edd_device_path_information::interface_path, edd_device_path_information::interface_type, edd_device_path_information::key, edd_device_path_information::len, device_description::location, NULL, PCI_BUS, PCI_FUNC, PCI_SLOT, rc, sandev_needs_reopen(), sandev_reopen(), edd_interface_path::slot, strerror(), and edd_host_bus_type::type.

Referenced by int13_get_extended_parameters().

◆ int13_get_extended_parameters()

static int int13_get_extended_parameters ( struct san_device sandev,
struct i386_all_regs ix86 
)
static

INT 13, 48 - Get extended parameters.

Parameters
sandevSAN device
ds:siDrive parameter table
Return values
statusStatus code

Definition at line 928 of file int13.c.

929  {
930  struct int13_data *int13 = sandev->priv;
931  struct int13_disk_parameters params;
932  struct segoff address;
933  size_t len = sizeof ( params );
935  int rc;
936 
937  /* Get buffer size */
938  get_real ( bufsize, ix86->segs.ds,
939  ( ix86->regs.si + offsetof ( typeof ( params ), bufsize )));
940 
941  DBGC2 ( sandev, "Get extended drive parameters to %04x:%04x+%02x\n",
942  ix86->segs.ds, ix86->regs.si, bufsize );
943 
944  /* Build drive parameters */
945  memset ( &params, 0, sizeof ( params ) );
946  params.flags = INT13_FL_DMA_TRANSPARENT;
947  if ( ( int13->cylinders < 1024 ) &&
948  ( sandev_capacity ( sandev ) <= INT13_MAX_CHS_SECTORS ) ) {
949  params.flags |= INT13_FL_CHS_VALID;
950  }
951  params.cylinders = int13->cylinders;
952  params.heads = int13->heads;
953  params.sectors_per_track = int13->sectors_per_track;
954  params.sectors = sandev_capacity ( sandev );
955  params.sector_size = sandev_blksize ( sandev );
956  memset ( &params.dpte, 0xff, sizeof ( params.dpte ) );
957  if ( ( rc = int13_device_path_info ( sandev, &params.dpi ) ) != 0 ) {
958  DBGC ( sandev, "INT13 drive %02x could not provide device "
959  "path information: %s\n",
960  sandev->drive, strerror ( rc ) );
961  len = offsetof ( typeof ( params ), dpi );
962  }
963 
964  /* Calculate returned "buffer size" (which will be less than
965  * the length actually copied if device path information is
966  * present).
967  */
968  if ( bufsize < offsetof ( typeof ( params ), dpte ) )
969  return -INT13_STATUS_INVALID;
970  if ( bufsize < offsetof ( typeof ( params ), dpi ) ) {
971  params.bufsize = offsetof ( typeof ( params ), dpte );
972  } else {
973  params.bufsize = offsetof ( typeof ( params ), dpi );
974  }
975 
976  DBGC ( sandev, "INT 13 drive %02x described using extended "
977  "parameters:\n", sandev->drive );
978  address.segment = ix86->segs.ds;
979  address.offset = ix86->regs.si;
980  DBGC_HDA ( sandev, address, &params, len );
981 
982  /* Return drive parameters */
983  if ( len > bufsize )
984  len = bufsize;
985  copy_to_real ( ix86->segs.ds, ix86->regs.si, &params, len );
986 
987  return 0;
988 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
struct i386_seg_regs segs
Definition: registers.h:175
static __asmcall __used void int13(struct i386_all_regs *ix86)
INT 13 handler.
Definition: int13.c:1067
uint64_t address
Base address.
Definition: ena.h:24
#define get_real
Definition: libkir.h:151
#define DBGC(...)
Definition: compiler.h:505
static int int13_device_path_info(struct san_device *sandev, struct edd_device_path_information *dpi)
Build device path information.
Definition: int13.c:863
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
struct i386_regs regs
Definition: registers.h:176
#define DBGC_HDA(...)
Definition: compiler.h:506
unsigned int drive
Drive number.
Definition: sanboot.h:54
static uint64_t sandev_capacity(struct san_device *sandev)
Calculate SAN device capacity.
Definition: sanboot.h:222
#define INT13_MAX_CHS_SECTORS
Maximum number of sectors for which CHS geometry is allowed to be valid.
Definition: int13.h:205
struct edd_device_path_information dpi
Device path information.
Definition: int13.h:28
#define INT13_STATUS_INVALID
Invalid function or parameter.
Definition: int13.h:61
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define copy_to_real
Definition: libkir.h:78
uint16_t ds
Definition: registers.h:141
#define INT13_FL_DMA_TRANSPARENT
DMA boundary errors handled transparently.
Definition: int13.h:153
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
#define INT13_FL_CHS_VALID
CHS information is valid.
Definition: int13.h:155
void * priv
Driver private data.
Definition: sanboot.h:78
struct segoff dpte
Device parameter table extension.
Definition: int13.h:26
static size_t sandev_blksize(struct san_device *sandev)
Calculate SAN device block size.
Definition: sanboot.h:212
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
uint16_t si
Definition: registers.h:68
uint8_t bufsize
Size of the packet, in bytes.
Definition: int13.h:12
INT 13 SAN device private data.
Definition: int13.c:55
void * memset(void *dest, int character, size_t len) __nonnull
INT 13 disk parameters.
Definition: int13.h:110

References address, bufsize, int13_disk_parameters::bufsize, copy_to_real, int13_disk_parameters::cylinders, DBGC, DBGC2, DBGC_HDA, dpi, int13_disk_parameters::dpi, dpte, int13_disk_parameters::dpte, san_device::drive, i386_seg_regs::ds, int13_disk_parameters::flags, get_real, int13_disk_parameters::heads, int13(), int13_device_path_info(), INT13_FL_CHS_VALID, INT13_FL_DMA_TRANSPARENT, INT13_MAX_CHS_SECTORS, INT13_STATUS_INVALID, len, memset(), offsetof, san_device::priv, rc, i386_all_regs::regs, sandev_blksize(), sandev_capacity(), int13_disk_parameters::sector_size, int13_disk_parameters::sectors, int13_disk_parameters::sectors_per_track, i386_all_regs::segs, i386_regs::si, strerror(), and typeof().

Referenced by int13().

◆ int13_cdrom_status_terminate()

static int int13_cdrom_status_terminate ( struct san_device sandev,
struct i386_all_regs ix86 
)
static

INT 13, 4b - Get status or terminate CD-ROM emulation.

Parameters
sandevSAN device
ds:siSpecification packet
Return values
statusStatus code

Definition at line 997 of file int13.c.

998  {
999  struct int13_cdrom_specification specification;
1000 
1001  DBGC2 ( sandev, "Get CD-ROM emulation status to %04x:%04x%s\n",
1002  ix86->segs.ds, ix86->regs.si,
1003  ( ix86->regs.al ? "" : " and terminate" ) );
1004 
1005  /* Fail if we are not a CD-ROM */
1006  if ( ! sandev->is_cdrom ) {
1007  DBGC ( sandev, "INT13 drive %02x is not a CD-ROM\n",
1008  sandev->drive );
1009  return -INT13_STATUS_INVALID;
1010  }
1011 
1012  /* Build specification packet */
1013  memset ( &specification, 0, sizeof ( specification ) );
1014  specification.size = sizeof ( specification );
1015  specification.drive = sandev->drive;
1016 
1017  /* Return specification packet */
1018  copy_to_real ( ix86->segs.ds, ix86->regs.si, &specification,
1019  sizeof ( specification ) );
1020 
1021  return 0;
1022 }
struct i386_seg_regs segs
Definition: registers.h:175
#define DBGC(...)
Definition: compiler.h:505
struct i386_regs regs
Definition: registers.h:176
unsigned int drive
Drive number.
Definition: sanboot.h:54
#define INT13_STATUS_INVALID
Invalid function or parameter.
Definition: int13.h:61
int is_cdrom
Drive is a CD-ROM.
Definition: sanboot.h:75
#define copy_to_real
Definition: libkir.h:78
uint16_t ds
Definition: registers.h:141
Bootable CD-ROM specification packet.
Definition: int13.h:208
#define DBGC2(...)
Definition: compiler.h:522
uint16_t si
Definition: registers.h:68
uint8_t al
Definition: registers.h:105
void * memset(void *dest, int character, size_t len) __nonnull

References i386_regs::al, copy_to_real, DBGC, DBGC2, san_device::drive, int13_cdrom_specification::drive, i386_seg_regs::ds, INT13_STATUS_INVALID, san_device::is_cdrom, memset(), i386_all_regs::regs, i386_all_regs::segs, i386_regs::si, and int13_cdrom_specification::size.

Referenced by int13().

◆ int13_cdrom_read_boot_catalog()

static int int13_cdrom_read_boot_catalog ( struct san_device sandev,
struct i386_all_regs ix86 
)
static

INT 13, 4d - Read CD-ROM boot catalog.

Parameters
sandevSAN device
ds:siCommand packet
Return values
statusStatus code

Definition at line 1032 of file int13.c.

1033  {
1034  struct int13_data *int13 = sandev->priv;
1036  unsigned int start;
1037  int rc;
1038 
1039  /* Read parameters from command packet */
1040  copy_from_real ( &command, ix86->segs.ds, ix86->regs.si,
1041  sizeof ( command ) );
1042  DBGC2 ( sandev, "Read CD-ROM boot catalog to %08x\n", command.buffer );
1043 
1044  /* Fail if we have no boot catalog */
1045  if ( ! int13->boot_catalog ) {
1046  DBGC ( sandev, "INT13 drive %02x has no boot catalog\n",
1047  sandev->drive );
1048  return -INT13_STATUS_INVALID;
1049  }
1050  start = ( int13->boot_catalog + command.start );
1051 
1052  /* Read from boot catalog */
1053  if ( ( rc = sandev_read ( sandev, start, command.count,
1054  phys_to_user ( command.buffer ) ) ) != 0 ) {
1055  DBGC ( sandev, "INT13 drive %02x could not read boot catalog: "
1056  "%s\n", sandev->drive, strerror ( rc ) );
1057  return -INT13_STATUS_READ_ERROR;
1058  }
1059 
1060  return 0;
1061 }
Bootable CD-ROM boot catalog command packet.
Definition: int13.h:236
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct i386_seg_regs segs
Definition: registers.h:175
static __asmcall __used void int13(struct i386_all_regs *ix86)
INT 13 handler.
Definition: int13.c:1067
A command-line command.
Definition: command.h:9
#define DBGC(...)
Definition: compiler.h:505
userptr_t phys_to_user(unsigned long phys_addr)
Convert physical address to user pointer.
#define INT13_STATUS_READ_ERROR
Read error.
Definition: int13.h:63
uint32_t start
Starting offset.
Definition: netvsc.h:12
struct i386_regs regs
Definition: registers.h:176
unsigned int drive
Drive number.
Definition: sanboot.h:54
#define INT13_STATUS_INVALID
Invalid function or parameter.
Definition: int13.h:61
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Read from SAN device.
Definition: sanboot.c:636
uint16_t ds
Definition: registers.h:141
#define copy_from_real
Definition: libkir.h:79
#define DBGC2(...)
Definition: compiler.h:522
void * priv
Driver private data.
Definition: sanboot.h:78
uint16_t si
Definition: registers.h:68
INT 13 SAN device private data.
Definition: int13.c:55

References copy_from_real, DBGC, DBGC2, san_device::drive, i386_seg_regs::ds, int13(), INT13_STATUS_INVALID, INT13_STATUS_READ_ERROR, phys_to_user(), san_device::priv, rc, i386_all_regs::regs, sandev_read(), i386_all_regs::segs, i386_regs::si, start, and strerror().

Referenced by int13().

◆ int13()

static __asmcall __used void int13 ( struct i386_all_regs ix86)
static

INT 13 handler.

Definition at line 1067 of file int13.c.

1067  {
1068  int command = ix86->regs.ah;
1069  unsigned int bios_drive = ix86->regs.dl;
1070  struct san_device *sandev;
1071  struct int13_data *int13;
1072  int status;
1073 
1074  /* Check BIOS hasn't killed off our drive */
1076 
1077  for_each_sandev ( sandev ) {
1078 
1079  int13 = sandev->priv;
1080  if ( bios_drive != sandev->drive ) {
1081  /* Remap any accesses to this drive's natural number */
1082  if ( bios_drive == int13->natural_drive ) {
1083  DBGC2 ( sandev, "INT13,%02x (%02x) remapped to "
1084  "(%02x)\n", ix86->regs.ah,
1085  bios_drive, sandev->drive );
1086  ix86->regs.dl = sandev->drive;
1087  return;
1088  } else if ( ( ( bios_drive & 0x7f ) == 0x7f ) &&
1090  && sandev->is_cdrom ) {
1091  /* Catch non-drive-specific CD-ROM calls */
1092  } else {
1093  continue;
1094  }
1095  }
1096 
1097  DBGC2 ( sandev, "INT13,%02x (%02x): ",
1098  ix86->regs.ah, bios_drive );
1099 
1100  switch ( command ) {
1101  case INT13_RESET:
1102  status = int13_reset ( sandev, ix86 );
1103  break;
1104  case INT13_GET_LAST_STATUS:
1105  status = int13_get_last_status ( sandev, ix86 );
1106  break;
1107  case INT13_READ_SECTORS:
1108  status = int13_read_sectors ( sandev, ix86 );
1109  break;
1110  case INT13_WRITE_SECTORS:
1111  status = int13_write_sectors ( sandev, ix86 );
1112  break;
1113  case INT13_GET_PARAMETERS:
1114  status = int13_get_parameters ( sandev, ix86 );
1115  break;
1116  case INT13_GET_DISK_TYPE:
1117  status = int13_get_disk_type ( sandev, ix86 );
1118  break;
1119  case INT13_EXTENSION_CHECK:
1120  status = int13_extension_check ( sandev, ix86 );
1121  break;
1122  case INT13_EXTENDED_READ:
1123  status = int13_extended_read ( sandev, ix86 );
1124  break;
1125  case INT13_EXTENDED_WRITE:
1126  status = int13_extended_write ( sandev, ix86 );
1127  break;
1128  case INT13_EXTENDED_VERIFY:
1129  status = int13_extended_verify ( sandev, ix86 );
1130  break;
1131  case INT13_EXTENDED_SEEK:
1132  status = int13_extended_seek ( sandev, ix86 );
1133  break;
1135  status = int13_get_extended_parameters ( sandev, ix86 );
1136  break;
1138  status = int13_cdrom_status_terminate ( sandev, ix86 );
1139  break;
1141  status = int13_cdrom_read_boot_catalog ( sandev, ix86 );
1142  break;
1143  default:
1144  DBGC2 ( sandev, "*** Unrecognised INT13 ***\n" );
1146  break;
1147  }
1148 
1149  /* Store status for INT 13,01 */
1150  int13->last_status = status;
1151 
1152  /* Negative status indicates an error */
1153  if ( status < 0 ) {
1154  status = -status;
1155  DBGC ( sandev, "INT13,%02x (%02x) failed with status "
1156  "%02x\n", ix86->regs.ah, sandev->drive, status );
1157  } else {
1158  ix86->flags &= ~CF;
1159  }
1160  ix86->regs.ah = status;
1161 
1162  /* Set OF to indicate to wrapper not to chain this call */
1163  ix86->flags |= OF;
1164 
1165  return;
1166  }
1167 }
static int int13_extended_seek(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 44 - Extended seek.
Definition: int13.c:836
#define INT13_GET_DISK_TYPE
Get disk type.
Definition: int13.h:33
#define CF
Definition: registers.h:181
static __asmcall __used void int13(struct i386_all_regs *ix86)
INT 13 handler.
Definition: int13.c:1067
#define INT13_EXTENSION_CHECK
Extensions installation check.
Definition: int13.h:35
static int int13_get_last_status(struct san_device *sandev, struct i386_all_regs *ix86 __unused)
INT 13, 01 - Get status of last operation.
Definition: int13.c:490
#define INT13_EXTENDED_WRITE
Extended write.
Definition: int13.h:39
A command-line command.
Definition: command.h:9
static int int13_get_parameters(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 08 - Get drive parameters.
Definition: int13.c:615
static int int13_extended_write(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 43 - Extended write.
Definition: int13.c:795
#define DBGC(...)
Definition: compiler.h:505
uint32_t flags
Definition: registers.h:177
#define INT13_EXTENDED_VERIFY
Verify sectors.
Definition: int13.h:41
static int int13_extended_verify(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 44 - Verify sectors.
Definition: int13.c:809
static void int13_check_num_drives(void)
Check number of drives.
Definition: int13.c:453
uint8_t status
Status.
Definition: ena.h:16
#define INT13_READ_SECTORS
Read sectors.
Definition: int13.h:27
static int int13_get_disk_type(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 15 - Get disk type.
Definition: int13.c:656
#define INT13_EXTENDED_SEEK
Extended seek.
Definition: int13.h:43
#define INT13_GET_PARAMETERS
Get drive parameters.
Definition: int13.h:31
struct i386_regs regs
Definition: registers.h:176
unsigned int drive
Drive number.
Definition: sanboot.h:54
#define INT13_STATUS_INVALID
Invalid function or parameter.
Definition: int13.h:61
static int int13_read_sectors(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 02 - Read sectors.
Definition: int13.c:577
static int int13_get_extended_parameters(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 48 - Get extended parameters.
Definition: int13.c:928
static int int13_extended_read(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 42 - Extended read.
Definition: int13.c:781
int is_cdrom
Drive is a CD-ROM.
Definition: sanboot.h:75
uint8_t ah
Definition: registers.h:106
static int int13_cdrom_read_boot_catalog(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 4d - Read CD-ROM boot catalog.
Definition: int13.c:1032
static int int13_cdrom_status_terminate(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 4b - Get status or terminate CD-ROM emulation.
Definition: int13.c:997
A SAN device.
Definition: sanboot.h:47
#define for_each_sandev(sandev)
Iterate over all SAN devices.
Definition: sanboot.h:173
static int int13_write_sectors(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 03 - Write sectors.
Definition: int13.c:597
static int int13_reset(struct san_device *sandev, struct i386_all_regs *ix86 __unused)
INT 13, 00 - Reset disk system.
Definition: int13.c:471
#define INT13_CDROM_STATUS_TERMINATE
Get CD-ROM status / terminate emulation.
Definition: int13.h:47
#define DBGC2(...)
Definition: compiler.h:522
void * priv
Driver private data.
Definition: sanboot.h:78
#define INT13_CDROM_READ_BOOT_CATALOG
Read CD-ROM boot catalog.
Definition: int13.h:49
#define INT13_GET_EXTENDED_PARAMETERS
Get extended drive parameters.
Definition: int13.h:45
#define INT13_RESET
Reset disk system.
Definition: int13.h:23
#define INT13_GET_LAST_STATUS
Get status of last operation.
Definition: int13.h:25
#define OF
Definition: registers.h:186
static int int13_extension_check(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 41 - Extensions installation check.
Definition: int13.c:681
#define INT13_WRITE_SECTORS
Write sectors.
Definition: int13.h:29
#define INT13_EXTENDED_READ
Extended read.
Definition: int13.h:37
INT 13 SAN device private data.
Definition: int13.c:55
uint8_t dl
Definition: registers.h:89

References i386_regs::ah, CF, DBGC, DBGC2, i386_regs::dl, san_device::drive, i386_all_regs::flags, for_each_sandev, INT13_CDROM_READ_BOOT_CATALOG, int13_cdrom_read_boot_catalog(), INT13_CDROM_STATUS_TERMINATE, int13_cdrom_status_terminate(), int13_check_num_drives(), INT13_EXTENDED_READ, int13_extended_read(), INT13_EXTENDED_SEEK, int13_extended_seek(), INT13_EXTENDED_VERIFY, int13_extended_verify(), INT13_EXTENDED_WRITE, int13_extended_write(), INT13_EXTENSION_CHECK, int13_extension_check(), INT13_GET_DISK_TYPE, int13_get_disk_type(), INT13_GET_EXTENDED_PARAMETERS, int13_get_extended_parameters(), INT13_GET_LAST_STATUS, int13_get_last_status(), INT13_GET_PARAMETERS, int13_get_parameters(), INT13_READ_SECTORS, int13_read_sectors(), INT13_RESET, int13_reset(), INT13_STATUS_INVALID, INT13_WRITE_SECTORS, int13_write_sectors(), san_device::is_cdrom, OF, san_device::priv, i386_all_regs::regs, and status.

Referenced by int13_cdrom_read_boot_catalog(), int13_get_extended_parameters(), int13_get_last_status(), int13_get_parameters(), int13_guess_geometry(), int13_hook(), int13_hook_vector(), int13_parse_eltorito(), int13_rw_sectors(), and int13_sync_num_drives().

◆ int13_hook_vector()

static void int13_hook_vector ( void  )
static

Hook INT 13 handler.

Definition at line 1173 of file int13.c.

1173  {
1174  /* Assembly wrapper to call int13(). int13() sets OF if we
1175  * should not chain to the previous handler. (The wrapper
1176  * clears CF and OF before calling int13()).
1177  */
1179  TEXT16_CODE ( "\nint13_wrapper:\n\t"
1180  /* Preserve %ax and %dx for future reference */
1181  "pushw %%bp\n\t"
1182  "movw %%sp, %%bp\n\t"
1183  "pushw %%ax\n\t"
1184  "pushw %%dx\n\t"
1185  /* Clear OF, set CF, call int13() */
1186  "orb $0, %%al\n\t"
1187  "stc\n\t"
1188  VIRT_CALL ( int13 )
1189  /* Chain if OF not set */
1190  "jo 1f\n\t"
1191  "pushfw\n\t"
1192  "lcall *%%cs:int13_vector\n\t"
1193  "\n1:\n\t"
1194  /* Overwrite flags for iret */
1195  "pushfw\n\t"
1196  "popw 6(%%bp)\n\t"
1197  /* Fix up %dl:
1198  *
1199  * INT 13,15 : do nothing if hard disk
1200  * INT 13,08 : load with number of drives
1201  * all others: restore original value
1202  */
1203  "cmpb $0x15, -1(%%bp)\n\t"
1204  "jne 2f\n\t"
1205  "testb $0x80, -4(%%bp)\n\t"
1206  "jnz 3f\n\t"
1207  "\n2:\n\t"
1208  "movb -4(%%bp), %%dl\n\t"
1209  "cmpb $0x08, -1(%%bp)\n\t"
1210  "jne 3f\n\t"
1211  "testb $0x80, %%dl\n\t"
1212  "movb %%cs:num_drives, %%dl\n\t"
1213  "jnz 3f\n\t"
1214  "movb %%cs:num_fdds, %%dl\n\t"
1215  /* Return */
1216  "\n3:\n\t"
1217  "movw %%bp, %%sp\n\t"
1218  "popw %%bp\n\t"
1219  "iret\n\t" ) : : );
1220 
1222 }
#define VIRT_CALL(function)
Call C function from real-mode code.
Definition: librm.h:78
static __asmcall __used void int13(struct i386_all_regs *ix86)
INT 13 handler.
Definition: int13.c:1067
unsigned long intptr_t
Definition: stdint.h:21
void hook_bios_interrupt(unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
Hook INT vector.
Definition: biosint.c:24
void int13_wrapper(void)
Assembly wrapper.
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
__asm__(".section \".rodata\", \"a\", " PROGBITS "\n\t" "\nprivate_key_data:\n\t" ".size private_key_data, ( . - private_key_data )\n\t" ".equ private_key_len, ( . - private_key_data )\n\t" ".previous\n\t")
#define int13_vector
Definition: int13.c:101
#define TEXT16_CODE(asm_code_str)
Definition: libkir.h:217

References __asm__(), __volatile__(), hook_bios_interrupt(), int13(), int13_vector, int13_wrapper(), TEXT16_CODE, and VIRT_CALL.

Referenced by int13_hook().

◆ int13_unhook_vector()

static void int13_unhook_vector ( void  )
static

Unhook INT 13 handler.

Definition at line 1227 of file int13.c.

1227  {
1229  &int13_vector );
1230 }
unsigned long intptr_t
Definition: stdint.h:21
int unhook_bios_interrupt(unsigned int interrupt, unsigned int handler, struct segoff *chain_vector)
Unhook INT vector.
Definition: biosint.c:69
void int13_wrapper(void)
Assembly wrapper.
#define int13_vector
Definition: int13.c:101

References int13_vector, int13_wrapper(), and unhook_bios_interrupt().

Referenced by int13_unhook().

◆ int13_hook()

static int int13_hook ( unsigned int  drive,
struct uri **  uris,
unsigned int  count,
unsigned int  flags 
)
static

Hook INT 13 SAN device.

Parameters
driveDrive number
urisList of URIs
countNumber of URIs
flagsFlags
Return values
driveDrive number, or negative error

Registers the drive with the INT 13 emulation subsystem, and hooks the INT 13 interrupt vector (if not already hooked).

Definition at line 1244 of file int13.c.

1245  {
1246  struct san_device *sandev;
1247  struct int13_data *int13;
1248  unsigned int natural_drive;
1249  void *scratch;
1250  int need_hook = ( ! have_sandevs() );
1251  int rc;
1252 
1253  /* Calculate natural drive number */
1255  natural_drive = ( ( drive & 0x80 ) ? ( num_drives | 0x80 ) : num_fdds );
1256 
1257  /* Use natural drive number if directed to do so */
1258  if ( ( drive & 0x7f ) == 0x7f )
1259  drive = natural_drive;
1260 
1261  /* Allocate SAN device */
1262  sandev = alloc_sandev ( uris, count, sizeof ( *int13 ) );
1263  if ( ! sandev ) {
1264  rc = -ENOMEM;
1265  goto err_alloc;
1266  }
1267  int13 = sandev->priv;
1268  int13->natural_drive = natural_drive;
1269 
1270  /* Register SAN device */
1271  if ( ( rc = register_sandev ( sandev, drive, flags ) ) != 0 ) {
1272  DBGC ( sandev, "INT13 drive %02x could not register: %s\n",
1273  drive, strerror ( rc ) );
1274  goto err_register;
1275  }
1276 
1277  /* Allocate scratch area */
1278  scratch = malloc ( sandev_blksize ( sandev ) );
1279  if ( ! scratch )
1280  goto err_alloc_scratch;
1281 
1282  /* Parse parameters, if present */
1283  if ( sandev->is_cdrom &&
1284  ( ( rc = int13_parse_eltorito ( sandev, scratch ) ) != 0 ) )
1285  goto err_parse_eltorito;
1286 
1287  /* Give drive a default geometry, if applicable */
1288  if ( ( sandev_blksize ( sandev ) == INT13_BLKSIZE ) &&
1289  ( ( rc = int13_guess_geometry ( sandev, scratch ) ) != 0 ) )
1290  goto err_guess_geometry;
1291 
1292  DBGC ( sandev, "INT13 drive %02x (naturally %02x) registered with "
1293  "C/H/S geometry %d/%d/%d\n",
1294  sandev->drive, int13->natural_drive, int13->cylinders,
1295  int13->heads, int13->sectors_per_track );
1296 
1297  /* Hook INT 13 vector if not already hooked */
1298  if ( need_hook ) {
1300  devices_get();
1301  }
1302 
1303  /* Update BIOS drive count */
1305 
1306  free ( scratch );
1307  return drive;
1308 
1309  err_guess_geometry:
1310  err_parse_eltorito:
1311  free ( scratch );
1312  err_alloc_scratch:
1313  unregister_sandev ( sandev );
1314  err_register:
1315  sandev_put ( sandev );
1316  err_alloc:
1317  return rc;
1318 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static __asmcall __used void int13(struct i386_all_regs *ix86)
INT 13 handler.
Definition: int13.c:1067
void unregister_sandev(struct san_device *sandev)
Unregister SAN device.
Definition: sanboot.c:925
#define DBGC(...)
Definition: compiler.h:505
static void sandev_put(struct san_device *sandev)
Drop reference to SAN device.
Definition: sanboot.h:202
uint8_t drive
Drive number.
Definition: int13.h:16
static void int13_hook_vector(void)
Hook INT 13 handler.
Definition: int13.c:1173
#define INT13_BLKSIZE
Block size for non-extended INT 13 calls.
Definition: int13.h:72
static void int13_sync_num_drives(void)
Update BIOS drive count.
Definition: int13.c:411
static int int13_parse_eltorito(struct san_device *sandev, void *scratch)
Parse El Torito parameters.
Definition: int13.c:172
static int have_sandevs(void)
There exist some SAN devices.
Definition: sanboot.h:180
#define ENOMEM
Not enough space.
Definition: errno.h:534
static void devices_get(void)
Prevent devices from being removed on shutdown.
Definition: device.h:161
unsigned int drive
Drive number.
Definition: sanboot.h:54
int register_sandev(struct san_device *sandev, unsigned int drive, unsigned int flags)
Register SAN device.
Definition: sanboot.c:868
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
int is_cdrom
Drive is a CD-ROM.
Definition: sanboot.h:75
#define num_fdds
Definition: int13.c:130
A SAN device.
Definition: sanboot.h:47
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
#define num_drives
Definition: int13.c:140
void * priv
Driver private data.
Definition: sanboot.h:78
unsigned int natural_drive
BIOS natural drive number (0x00-0xff)
Definition: int13.c:66
uint16_t count
Number of entries.
Definition: ena.h:22
static size_t sandev_blksize(struct san_device *sandev)
Calculate SAN device block size.
Definition: sanboot.h:212
struct san_device * alloc_sandev(struct uri **uris, unsigned int count, size_t priv_size)
Allocate SAN device.
Definition: sanboot.c:825
static int int13_guess_geometry(struct san_device *sandev, void *scratch)
Guess INT 13 drive geometry.
Definition: int13.c:370
INT 13 SAN device private data.
Definition: int13.c:55
uint8_t flags
Flags.
Definition: ena.h:18

References alloc_sandev(), count, DBGC, devices_get(), drive, san_device::drive, ENOMEM, flags, free, have_sandevs(), int13(), INT13_BLKSIZE, int13_guess_geometry(), int13_hook_vector(), int13_parse_eltorito(), int13_sync_num_drives(), san_device::is_cdrom, malloc(), int13_data::natural_drive, num_drives, num_fdds, san_device::priv, rc, register_sandev(), sandev_blksize(), sandev_put(), strerror(), and unregister_sandev().

◆ int13_unhook()

static void int13_unhook ( unsigned int  drive)
static

Unhook INT 13 SAN device.

Parameters
driveDrive number

Unregisters the drive from the INT 13 emulation subsystem. If this is the last SAN device, the INT 13 vector is unhooked (if possible).

Definition at line 1329 of file int13.c.

1329  {
1330  struct san_device *sandev;
1331 
1332  /* Find drive */
1333  sandev = sandev_find ( drive );
1334  if ( ! sandev ) {
1335  DBG ( "INT13 cannot find drive %02x\n", drive );
1336  return;
1337  }
1338 
1339  /* Unregister SAN device */
1340  unregister_sandev ( sandev );
1341 
1342  /* Should adjust BIOS drive count, but it's difficult
1343  * to do so reliably.
1344  */
1345 
1346  DBGC ( sandev, "INT13 drive %02x unregistered\n", sandev->drive );
1347 
1348  /* Unhook INT 13 vector if no more drives */
1349  if ( ! have_sandevs() ) {
1350  devices_put();
1352  }
1353 
1354  /* Drop reference to drive */
1355  sandev_put ( sandev );
1356 }
static void devices_put(void)
Allow devices to be removed on shutdown.
Definition: device.h:169
void unregister_sandev(struct san_device *sandev)
Unregister SAN device.
Definition: sanboot.c:925
#define DBGC(...)
Definition: compiler.h:505
static void sandev_put(struct san_device *sandev)
Drop reference to SAN device.
Definition: sanboot.h:202
uint8_t drive
Drive number.
Definition: int13.h:16
static int have_sandevs(void)
There exist some SAN devices.
Definition: sanboot.h:180
unsigned int drive
Drive number.
Definition: sanboot.h:54
static void int13_unhook_vector(void)
Unhook INT 13 handler.
Definition: int13.c:1227
A SAN device.
Definition: sanboot.h:47
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
Definition: sanboot.c:100
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498

References DBG, DBGC, devices_put(), drive, san_device::drive, have_sandevs(), int13_unhook_vector(), sandev_find(), sandev_put(), and unregister_sandev().

◆ int13_load_mbr()

static int int13_load_mbr ( unsigned int  drive,
struct segoff address 
)
static

Load and verify master boot record from INT 13 drive.

Parameters
driveDrive number
addressBoot code address to fill in
Return values
rcReturn status code

Definition at line 1365 of file int13.c.

1365  {
1366  uint16_t status;
1367  int discard_b, discard_c, discard_d;
1368  uint16_t magic;
1369 
1370  /* Use INT 13, 02 to read the MBR */
1371  address->segment = 0;
1372  address->offset = 0x7c00;
1373  __asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t"
1374  "pushl %%ebx\n\t"
1375  "popw %%bx\n\t"
1376  "popw %%es\n\t"
1377  "stc\n\t"
1378  "sti\n\t"
1379  "int $0x13\n\t"
1380  "sti\n\t" /* BIOS bugs */
1381  "jc 1f\n\t"
1382  "xorw %%ax, %%ax\n\t"
1383  "\n1:\n\t"
1384  "popw %%es\n\t" )
1385  : "=a" ( status ), "=b" ( discard_b ),
1386  "=c" ( discard_c ), "=d" ( discard_d )
1387  : "a" ( 0x0201 ), "b" ( *address ),
1388  "c" ( 1 ), "d" ( drive ) );
1389  if ( status ) {
1390  DBG ( "INT13 drive %02x could not read MBR (status %04x)\n",
1391  drive, status );
1392  return -EIO;
1393  }
1394 
1395  /* Check magic signature */
1396  get_real ( magic, address->segment,
1397  ( address->offset +
1398  offsetof ( struct master_boot_record, magic ) ) );
1399  if ( magic != INT13_MBR_MAGIC ) {
1400  DBG ( "INT13 drive %02x does not contain a valid MBR\n",
1401  drive );
1402  return -ENOEXEC;
1403  }
1404 
1405  return 0;
1406 }
unsigned short uint16_t
Definition: stdint.h:11
#define INT13_MBR_MAGIC
MBR magic signature.
Definition: int13.h:292
uint64_t address
Base address.
Definition: ena.h:24
#define ENOEXEC
Exec format error.
Definition: errno.h:519
#define get_real
Definition: libkir.h:151
uint32_t magic
Magic signature.
Definition: fdt.h:12
uint8_t drive
Drive number.
Definition: int13.h:16
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
uint8_t status
Status.
Definition: ena.h:16
A Master Boot Record.
Definition: int13.h:278
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
__asm__(".section \".rodata\", \"a\", " PROGBITS "\n\t" "\nprivate_key_data:\n\t" ".size private_key_data, ( . - private_key_data )\n\t" ".equ private_key_len, ( . - private_key_data )\n\t" ".previous\n\t")
#define EIO
Input/output error.
Definition: errno.h:433
long discard_c
Definition: bigint.h:32
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226

References __asm__(), __volatile__(), address, DBG, discard_c, drive, EIO, ENOEXEC, get_real, INT13_MBR_MAGIC, magic, offsetof, REAL_CODE, and status.

Referenced by int13_boot().

◆ __data16() [2/2]

static struct int13_cdrom_boot_catalog_command __data16 ( eltorito_cmd  )
static

El Torito boot catalog command packet.

◆ __bss16()

static struct int13_disk_address __bss16 ( eltorito_address  )
static

El Torito disk address packet.

◆ int13_load_eltorito()

static int int13_load_eltorito ( unsigned int  drive,
struct segoff address 
)
static

Load and verify El Torito boot record from INT 13 drive.

Parameters
driveDrive number
addressBoot code address to fill in
Return values
rcReturn status code

Definition at line 1428 of file int13.c.

1428  {
1429  struct {
1430  struct eltorito_validation_entry valid;
1431  struct eltorito_boot_entry boot;
1432  } __attribute__ (( packed )) catalog;
1433  uint16_t status;
1434 
1435  /* Use INT 13, 4d to read the boot catalog */
1436  __asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
1437  "sti\n\t"
1438  "int $0x13\n\t"
1439  "sti\n\t" /* BIOS bugs */
1440  "jc 1f\n\t"
1441  "xorw %%ax, %%ax\n\t"
1442  "\n1:\n\t" )
1443  : "=a" ( status )
1444  : "a" ( 0x4d00 ), "d" ( drive ),
1445  "S" ( __from_data16 ( &eltorito_cmd ) ) );
1446  if ( status ) {
1447  DBG ( "INT13 drive %02x could not read El Torito boot catalog "
1448  "(status %04x)\n", drive, status );
1449  return -EIO;
1450  }
1451  copy_from_user ( &catalog, phys_to_user ( eltorito_cmd.buffer ), 0,
1452  sizeof ( catalog ) );
1453 
1454  /* Sanity checks */
1455  if ( catalog.valid.platform_id != ELTORITO_PLATFORM_X86 ) {
1456  DBG ( "INT13 drive %02x El Torito specifies unknown platform "
1457  "%02x\n", drive, catalog.valid.platform_id );
1458  return -ENOEXEC;
1459  }
1460  if ( catalog.boot.indicator != ELTORITO_BOOTABLE ) {
1461  DBG ( "INT13 drive %02x El Torito is not bootable\n", drive );
1462  return -ENOEXEC;
1463  }
1464  if ( catalog.boot.media_type != ELTORITO_NO_EMULATION ) {
1465  DBG ( "INT13 drive %02x El Torito requires emulation "
1466  "type %02x\n", drive, catalog.boot.media_type );
1467  return -ENOTSUP;
1468  }
1469  DBG ( "INT13 drive %02x El Torito boot image at LBA %08x (count %d)\n",
1470  drive, catalog.boot.start, catalog.boot.length );
1471  address->segment = ( catalog.boot.load_segment ?
1472  catalog.boot.load_segment : 0x7c0 );
1473  address->offset = 0;
1474  DBG ( "INT13 drive %02x El Torito boot image loads at %04x:%04x\n",
1475  drive, address->segment, address->offset );
1476 
1477  /* Use INT 13, 42 to read the boot image */
1478  eltorito_address.bufsize =
1480  eltorito_address.count = catalog.boot.length;
1481  eltorito_address.buffer = *address;
1482  eltorito_address.lba = catalog.boot.start;
1483  __asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
1484  "sti\n\t"
1485  "int $0x13\n\t"
1486  "sti\n\t" /* BIOS bugs */
1487  "jc 1f\n\t"
1488  "xorw %%ax, %%ax\n\t"
1489  "\n1:\n\t" )
1490  : "=a" ( status )
1491  : "a" ( 0x4200 ), "d" ( drive ),
1492  "S" ( __from_data16 ( &eltorito_address ) ) );
1493  if ( status ) {
1494  DBG ( "INT13 drive %02x could not read El Torito boot image "
1495  "(status %04x)\n", drive, status );
1496  return -EIO;
1497  }
1498 
1499  return 0;
1500 }
uint64_t buffer_phys
Data buffer (EDD 3.0+ only)
Definition: int13.h:24
#define __attribute__(x)
Definition: compiler.h:10
unsigned short uint16_t
Definition: stdint.h:11
A bootable entry in the El Torito Boot Catalog.
Definition: eltorito.h:70
uint64_t address
Base address.
Definition: ena.h:24
#define ENOEXEC
Exec format error.
Definition: errno.h:519
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
An El Torito Boot Catalog Validation Entry.
Definition: eltorito.h:42
userptr_t phys_to_user(unsigned long phys_addr)
Convert physical address to user pointer.
#define ELTORITO_BOOTABLE
Boot indicator for a bootable ISO image.
Definition: eltorito.h:95
uint8_t drive
Drive number.
Definition: int13.h:16
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
uint8_t status
Status.
Definition: ena.h:16
#define eltorito_address
Definition: int13.c:1419
#define eltorito_cmd
Definition: int13.c:1415
__asm__ __volatile__("\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" :"=&D"(discard_D), "=&c"(discard_c), "+m"(*value) :"r"(data), "g"(pad_len), "0"(value0), "1"(len) :"eax")
__asm__(".section \".rodata\", \"a\", " PROGBITS "\n\t" "\nprivate_key_data:\n\t" ".size private_key_data, ( . - private_key_data )\n\t" ".equ private_key_len, ( . - private_key_data )\n\t" ".previous\n\t")
#define __from_data16(pointer)
Definition: libkir.h:22
#define EIO
Input/output error.
Definition: errno.h:433
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define REAL_CODE(asm_code_str)
Definition: libkir.h:226
No emulation.
Definition: eltorito.h:100

References __asm__(), __attribute__, __from_data16, __volatile__(), address, buffer_phys, copy_from_user(), DBG, drive, EIO, eltorito_address, ELTORITO_BOOTABLE, eltorito_cmd, ELTORITO_NO_EMULATION, ELTORITO_PLATFORM_X86, ENOEXEC, ENOTSUP, offsetof, phys_to_user(), REAL_CODE, status, and typeof().

Referenced by int13_boot().

◆ int13_boot()

static int int13_boot ( unsigned int  drive,
const char *filename  __unused 
)
static

Attempt to boot from an INT 13 drive.

Parameters
driveDrive number
filenameFilename (or NULL to use default)
Return values
rcReturn status code

This boots from the specified INT 13 drive by loading the Master Boot Record to 0000:7c00 and jumping to it. INT 18 is hooked to capture an attempt by the MBR to boot the next device. (This is the closest thing to a return path from an MBR).

Note that this function can never return success, by definition.

Definition at line 1516 of file int13.c.

1516  {
1517  struct memory_map memmap;
1518  struct segoff address;
1519  int rc;
1520 
1521  /* Look for a usable boot sector */
1522  if ( ( ( rc = int13_load_mbr ( drive, &address ) ) != 0 ) &&
1523  ( ( rc = int13_load_eltorito ( drive, &address ) ) != 0 ) )
1524  return rc;
1525 
1526  /* Dump out memory map prior to boot, if memmap debugging is
1527  * enabled. Not required for program flow, but we have so
1528  * many problems that turn out to be memory-map related that
1529  * it's worth doing.
1530  */
1531  get_memmap ( &memmap );
1532 
1533  /* Jump to boot sector */
1534  if ( ( rc = call_bootsector ( address.segment, address.offset,
1535  drive ) ) != 0 ) {
1536  DBG ( "INT13 drive %02x boot returned: %s\n",
1537  drive, strerror ( rc ) );
1538  return rc;
1539  }
1540 
1541  return -ECANCELED; /* -EIMPOSSIBLE */
1542 }
int call_bootsector(unsigned int segment, unsigned int offset, unsigned int drive)
Jump to preloaded bootsector.
Definition: bootsector.c:64
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void get_memmap(struct memory_map *memmap)
Get memory map.
static int int13_load_eltorito(unsigned int drive, struct segoff *address)
Load and verify El Torito boot record from INT 13 drive.
Definition: int13.c:1428
uint64_t address
Base address.
Definition: ena.h:24
uint8_t drive
Drive number.
Definition: int13.h:16
A memory map.
Definition: io.h:499
#define ECANCELED
Operation canceled.
Definition: errno.h:343
static int int13_load_mbr(unsigned int drive, struct segoff *address)
Load and verify master boot record from INT 13 drive.
Definition: int13.c:1365
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498

References address, call_bootsector(), DBG, drive, ECANCELED, get_memmap(), int13_load_eltorito(), int13_load_mbr(), rc, and strerror().

◆ __bss16_array()

static uint8_t __bss16_array ( xbftab  )
static

The boot firmware table(s) generated by iPXE.

◆ int13_install()

static int int13_install ( struct acpi_header acpi)
static

Install ACPI table.

Parameters
acpiACPI description header
Return values
rcReturn status code

Definition at line 1564 of file int13.c.

1564  {
1565  struct segoff xbft_address;
1566  struct acpi_header *installed;
1567  size_t len;
1568 
1569  /* Check length */
1570  len = acpi->length;
1571  if ( len > ( sizeof ( xbftab ) - xbftab_used ) ) {
1572  DBGC ( acpi, "INT13 out of space for %s table\n",
1573  acpi_name ( acpi->signature ) );
1574  return -ENOSPC;
1575  }
1576 
1577  /* Install table */
1578  installed = ( ( ( void * ) xbftab ) + xbftab_used );
1579  memcpy ( installed, acpi, len );
1580  xbft_address.segment = rm_ds;
1581  xbft_address.offset = __from_data16 ( installed );
1582 
1583  /* Fill in common parameters */
1584  strncpy ( installed->oem_id, "FENSYS",
1585  sizeof ( installed->oem_id ) );
1586  strncpy ( installed->oem_table_id, "iPXE",
1587  sizeof ( installed->oem_table_id ) );
1588 
1589  /* Fix checksum */
1590  acpi_fix_checksum ( installed );
1591 
1592  /* Update used length */
1593  xbftab_used = ( ( xbftab_used + len + XBFTAB_ALIGN - 1 ) &
1594  ~( XBFTAB_ALIGN - 1 ) );
1595 
1596  DBGC ( acpi, "INT13 installed %s:\n",
1597  acpi_name ( installed->signature ) );
1598  DBGC_HDA ( acpi, xbft_address, installed, len );
1599  return 0;
1600 }
char oem_table_id[8]
OEM table identification.
Definition: acpi.h:175
uint32_t signature
ACPI signature (4 ASCII characters)
Definition: acpi.h:165
#define DBGC(...)
Definition: compiler.h:505
#define rm_ds
Definition: libkir.h:39
char * strncpy(char *dest, const char *src, size_t max)
Copy string.
Definition: string.c:347
void * memcpy(void *dest, const void *src, size_t len) __nonnull
char oem_id[6]
OEM identification.
Definition: acpi.h:173
#define DBGC_HDA(...)
Definition: compiler.h:506
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:62
void acpi_fix_checksum(struct acpi_header *acpi)
Fix up ACPI table checksum.
Definition: acpi.c:85
static size_t xbftab_used
Total used length of boot firmware tables.
Definition: int13.c:1556
#define XBFTAB_ALIGN
Alignment of boot firmware table entries.
Definition: int13.c:1548
An ACPI description header.
Definition: acpi.h:163
#define ENOSPC
No space left on device.
Definition: errno.h:549
uint32_t len
Length.
Definition: ena.h:14
#define __from_data16(pointer)
Definition: libkir.h:22
static const char * acpi_name(uint32_t signature)
Transcribe ACPI table signature (for debugging)
Definition: acpi.h:190
#define xbftab
Definition: int13.c:1553

References __from_data16, acpi, acpi_fix_checksum(), acpi_name(), DBGC, DBGC_HDA, ENOSPC, len, memcpy(), acpi_header::oem_id, acpi_header::oem_table_id, segoff::offset, rm_ds, segoff::segment, acpi_header::signature, strncpy(), xbftab, XBFTAB_ALIGN, and xbftab_used.

Referenced by int13_describe().

◆ int13_describe()

static int int13_describe ( void  )
static

Describe SAN devices for SAN-booted operating system.

Return values
rcReturn status code

Definition at line 1607 of file int13.c.

1607  {
1608  int rc;
1609 
1610  /* Clear tables */
1611  memset ( &xbftab, 0, sizeof ( xbftab ) );
1612  xbftab_used = 0;
1613 
1614  /* Install ACPI tables */
1615  if ( ( rc = acpi_install ( int13_install ) ) != 0 ) {
1616  DBG ( "INT13 could not install ACPI tables: %s\n",
1617  strerror ( rc ) );
1618  return rc;
1619  }
1620 
1621  return 0;
1622 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int int13_install(struct acpi_header *acpi)
Install ACPI table.
Definition: int13.c:1564
int acpi_install(int(*install)(struct acpi_header *acpi))
Install ACPI tables.
Definition: acpi.c:336
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t xbftab_used
Total used length of boot firmware tables.
Definition: int13.c:1556
#define xbftab
Definition: int13.c:1553
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
void * memset(void *dest, int character, size_t len) __nonnull

References acpi_install(), DBG, int13_install(), memset(), rc, strerror(), xbftab, and xbftab_used.

◆ PROVIDE_SANBOOT() [1/4]

PROVIDE_SANBOOT ( pcbios  ,
san_hook  ,
int13_hook   
)

◆ PROVIDE_SANBOOT() [2/4]

PROVIDE_SANBOOT ( pcbios  ,
san_unhook  ,
int13_unhook   
)

◆ PROVIDE_SANBOOT() [3/4]

PROVIDE_SANBOOT ( pcbios  ,
san_boot  ,
int13_boot   
)

◆ PROVIDE_SANBOOT() [4/4]

PROVIDE_SANBOOT ( pcbios  ,
san_describe  ,
int13_describe   
)

Variable Documentation

◆ equipment_word

uint16_t equipment_word
static

Equipment word.

This is a cached copy of the BIOS Data Area equipment word at 40:10.

Definition at line 121 of file int13.c.

Referenced by int13_check_num_drives(), and int13_sync_num_drives().

◆ int13_fdd_geometries

const struct int13_fdd_geometry int13_fdd_geometries[]
static
Initial value:
= {
INT13_FDD_GEOMETRY ( 40, 1, 8 ),
INT13_FDD_GEOMETRY ( 40, 1, 9 ),
INT13_FDD_GEOMETRY ( 40, 2, 8 ),
INT13_FDD_GEOMETRY ( 40, 1, 9 ),
INT13_FDD_GEOMETRY ( 80, 2, 8 ),
INT13_FDD_GEOMETRY ( 80, 2, 9 ),
INT13_FDD_GEOMETRY ( 80, 2, 15 ),
INT13_FDD_GEOMETRY ( 80, 2, 18 ),
INT13_FDD_GEOMETRY ( 80, 2, 20 ),
INT13_FDD_GEOMETRY ( 80, 2, 21 ),
INT13_FDD_GEOMETRY ( 82, 2, 21 ),
INT13_FDD_GEOMETRY ( 83, 2, 21 ),
INT13_FDD_GEOMETRY ( 80, 2, 22 ),
INT13_FDD_GEOMETRY ( 80, 2, 23 ),
INT13_FDD_GEOMETRY ( 80, 2, 24 ),
INT13_FDD_GEOMETRY ( 80, 2, 36 ),
INT13_FDD_GEOMETRY ( 80, 2, 39 ),
INT13_FDD_GEOMETRY ( 80, 2, 40 ),
INT13_FDD_GEOMETRY ( 80, 2, 44 ),
INT13_FDD_GEOMETRY ( 80, 2, 48 ),
}
#define INT13_FDD_GEOMETRY(cylinders, heads, sectors)
Define a floppy disk geometry.
Definition: int13.h:303

Recognised floppy disk geometries.

Definition at line 297 of file int13.c.

Referenced by int13_guess_geometry_fdd().

◆ xbftab_used

size_t xbftab_used
static

Total used length of boot firmware tables.

Definition at line 1556 of file int13.c.

Referenced by int13_describe(), and int13_install().