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, struct san_boot_config *config __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 1422 of file int13.c.

◆ eltorito_address

#define eltorito_address   __use_data16 ( eltorito_address )

Definition at line 1426 of file int13.c.

◆ XBFTAB_SIZE

#define XBFTAB_SIZE   768

Maximum size of boot firmware table(s)

Definition at line 1554 of file int13.c.

◆ XBFTAB_ALIGN

#define XBFTAB_ALIGN   16

Alignment of boot firmware table entries.

Definition at line 1557 of file int13.c.

◆ xbftab

#define xbftab   __use_data16 ( xbftab )

Definition at line 1562 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:245

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:65

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->drive, "INT13 drive %02x could not read El "
187  "Torito boot 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->drive, "INT13 drive %02x has an El Torito boot "
196  "catalog at LBA %08x\n", sandev->drive,
197  int13->boot_catalog );
198  } else {
199  DBGC ( sandev->drive, "INT13 drive %02x has no El Torito boot "
200  "catalog\n", sandev->drive );
201  }
202 
203  return 0;
204 }
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:1074
#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:65
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:645
#define ISO9660_TYPE_BOOT
ISO9660 Boot Volume Descriptor type.
Definition: iso9660.h:39
void * priv
Driver private data.
Definition: sanboot.h:89
#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 217 of file int13.c.

219  {
220  struct master_boot_record *mbr = scratch;
221  struct partition_table_entry *partition;
222  unsigned int i;
223  unsigned int start_cylinder;
224  unsigned int start_head;
225  unsigned int start_sector;
226  unsigned int end_head;
227  unsigned int end_sector;
228  int rc;
229 
230  /* Read partition table */
231  if ( ( rc = sandev_read ( sandev, 0, 1, virt_to_user ( mbr ) ) ) != 0 ) {
232  DBGC ( sandev->drive, "INT13 drive %02x could not read "
233  "partition table to guess geometry: %s\n",
234  sandev->drive, strerror ( rc ) );
235  return rc;
236  }
237  DBGC2 ( sandev->drive, "INT13 drive %02x has MBR:\n", sandev->drive );
238  DBGC2_HDA ( sandev->drive, 0, mbr, sizeof ( *mbr ) );
239  DBGC ( sandev->drive, "INT13 drive %02x has signature %08x\n",
240  sandev->drive, mbr->signature );
241 
242  /* Scan through partition table and modify guesses for
243  * heads and sectors_per_track if we find any used
244  * partitions.
245  */
246  *heads = 0;
247  *sectors = 0;
248  for ( i = 0 ; i < 4 ; i++ ) {
249 
250  /* Skip empty partitions */
251  partition = &mbr->partitions[i];
252  if ( ! partition->type )
253  continue;
254 
255  /* If partition starts on cylinder 0 then we can
256  * unambiguously determine the number of sectors.
257  */
258  start_cylinder = PART_CYLINDER ( partition->chs_start );
259  start_head = PART_HEAD ( partition->chs_start );
260  start_sector = PART_SECTOR ( partition->chs_start );
261  if ( ( start_cylinder == 0 ) && ( start_head != 0 ) ) {
262  *sectors = ( ( partition->start + 1 - start_sector ) /
263  start_head );
264  DBGC ( sandev->drive, "INT13 drive %02x guessing "
265  "C/H/S xx/xx/%d based on partition %d\n",
266  sandev->drive, *sectors, ( i + 1 ) );
267  }
268 
269  /* If partition ends on a higher head or sector number
270  * than our current guess, then increase the guess.
271  */
272  end_head = PART_HEAD ( partition->chs_end );
273  end_sector = PART_SECTOR ( partition->chs_end );
274  if ( ( end_head + 1 ) > *heads ) {
275  *heads = ( end_head + 1 );
276  DBGC ( sandev->drive, "INT13 drive %02x guessing "
277  "C/H/S xx/%d/xx based on partition %d\n",
278  sandev->drive, *heads, ( i + 1 ) );
279  }
280  if ( end_sector > *sectors ) {
281  *sectors = end_sector;
282  DBGC ( sandev->drive, "INT13 drive %02x guessing "
283  "C/H/S xx/xx/%d based on partition %d\n",
284  sandev->drive, *sectors, ( i + 1 ) );
285  }
286  }
287 
288  /* Default guess is xx/255/63 */
289  if ( ! *heads )
290  *heads = 255;
291  if ( ! *sectors )
292  *sectors = 63;
293 
294  return 0;
295 }
#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:65
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:645
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 331 of file int13.c.

333  {
334  unsigned int blocks = sandev_capacity ( sandev );
335  const struct int13_fdd_geometry *geometry;
336  unsigned int cylinders;
337  unsigned int i;
338 
339  /* Look for a match against a known geometry */
340  for ( i = 0 ; i < ( sizeof ( int13_fdd_geometries ) /
341  sizeof ( int13_fdd_geometries[0] ) ) ; i++ ) {
342  geometry = &int13_fdd_geometries[i];
343  cylinders = INT13_FDD_CYLINDERS ( geometry );
344  *heads = INT13_FDD_HEADS ( geometry );
345  *sectors = INT13_FDD_SECTORS ( geometry );
346  if ( ( cylinders * (*heads) * (*sectors) ) == blocks ) {
347  DBGC ( sandev->drive, "INT13 drive %02x guessing "
348  "C/H/S %d/%d/%d based on size %dK\n",
349  sandev->drive, cylinders, *heads, *sectors,
350  ( blocks / 2 ) );
351  return 0;
352  }
353  }
354 
355  /* Otherwise, assume a partial disk image in the most common
356  * format (1440K, 80/2/18).
357  */
358  *heads = 2;
359  *sectors = 18;
360  DBGC ( sandev->drive, "INT13 drive %02x guessing C/H/S xx/%d/%d "
361  "based on size %dK\n", sandev->drive, *heads, *sectors,
362  ( blocks / 2 ) );
363  return 0;
364 }
#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:298
#define INT13_FDD_CYLINDERS(geometry)
Get floppy disk number of cylinders.
Definition: int13.h:310
unsigned int drive
Drive number.
Definition: sanboot.h:65
static uint64_t sandev_capacity(struct san_device *sandev)
Calculate SAN device capacity.
Definition: sanboot.h:245
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 373 of file int13.c.

373  {
374  struct int13_data *int13 = sandev->priv;
375  unsigned int guessed_heads;
376  unsigned int guessed_sectors;
377  unsigned int blocks;
378  unsigned int blocks_per_cyl;
379  int rc;
380 
381  /* Guess geometry according to drive type */
382  if ( int13_is_fdd ( sandev ) ) {
383  if ( ( rc = int13_guess_geometry_fdd ( sandev, &guessed_heads,
384  &guessed_sectors )) != 0)
385  return rc;
386  } else {
387  if ( ( rc = int13_guess_geometry_hdd ( sandev, scratch,
388  &guessed_heads,
389  &guessed_sectors )) != 0)
390  return rc;
391  }
392 
393  /* Apply guesses if no geometry already specified */
394  if ( ! int13->heads )
395  int13->heads = guessed_heads;
396  if ( ! int13->sectors_per_track )
397  int13->sectors_per_track = guessed_sectors;
398  if ( ! int13->cylinders ) {
399  /* Avoid attempting a 64-bit divide on a 32-bit system */
400  blocks = int13_capacity32 ( sandev );
401  blocks_per_cyl = ( int13->heads * int13->sectors_per_track );
402  assert ( blocks_per_cyl != 0 );
403  int13->cylinders = ( blocks / blocks_per_cyl );
404  if ( int13->cylinders > 1024 )
405  int13->cylinders = 1024;
406  }
407 
408  return 0;
409 }
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:1074
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:331
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:217
void * priv
Driver private data.
Definition: sanboot.h:89
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 414 of file int13.c.

414  {
415  struct san_device *sandev;
416  struct int13_data *int13;
417  uint8_t *counter;
418  uint8_t max_drive;
419  uint8_t required;
420 
421  /* Get current drive counts */
424  num_fdds = ( ( equipment_word & 0x0001 ) ?
425  ( ( ( equipment_word >> 6 ) & 0x3 ) + 1 ) : 0 );
426 
427  /* Ensure count is large enough to cover all of our SAN devices */
428  for_each_sandev ( sandev ) {
429  int13 = sandev->priv;
430  counter = ( int13_is_fdd ( sandev ) ? &num_fdds : &num_drives );
431  max_drive = sandev->drive;
432  if ( max_drive < int13->natural_drive )
433  max_drive = int13->natural_drive;
434  required = ( ( max_drive & 0x7f ) + 1 );
435  if ( *counter < required ) {
436  *counter = required;
437  DBGC ( sandev->drive, "INT13 drive %02x added to "
438  "drive count: %d HDDs, %d FDDs\n",
439  sandev->drive, num_drives, num_fdds );
440  }
441  }
442 
443  /* Update current drive count */
444  equipment_word &= ~( ( 0x3 << 6 ) | 0x0001 );
445  if ( num_fdds ) {
446  equipment_word |= ( 0x0001 |
447  ( ( ( num_fdds - 1 ) & 0x3 ) << 6 ) );
448  }
451 }
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:1074
#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:65
#define num_fdds
Definition: int13.c:130
A SAN device.
Definition: sanboot.h:58
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:196
#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:89
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 456 of file int13.c.

456  {
457  uint16_t check_equipment_word;
458  uint8_t check_num_drives;
459 
460  get_real ( check_equipment_word, BDA_SEG, BDA_EQUIPMENT_WORD );
461  get_real ( check_num_drives, BDA_SEG, BDA_NUM_DRIVES );
462  if ( ( check_equipment_word != equipment_word ) ||
463  ( check_num_drives != num_drives ) ) {
465  }
466 }
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:414
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 474 of file int13.c.

475  {
476  int rc;
477 
478  DBGC2 ( sandev->drive, "Reset drive\n" );
479 
480  /* Reset SAN device */
481  if ( ( rc = sandev_reset ( sandev ) ) != 0 )
483 
484  return 0;
485 }
int sandev_reset(struct san_device *sandev)
Reset SAN device.
Definition: sanboot.c:574
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned int drive
Drive number.
Definition: sanboot.h:65
#define INT13_STATUS_RESET_FAILED
Reset failed.
Definition: int13.h:65
#define DBGC2(...)
Definition: compiler.h:522

References DBGC2, san_device::drive, 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 493 of file int13.c.

494  {
495  struct int13_data *int13 = sandev->priv;
496 
497  DBGC2 ( sandev->drive, "Get status of last operation\n" );
498  return int13->last_status;
499 }
static __asmcall __used void int13(struct i386_all_regs *ix86)
INT 13 handler.
Definition: int13.c:1074
unsigned int drive
Drive number.
Definition: sanboot.h:65
#define DBGC2(...)
Definition: compiler.h:522
void * priv
Driver private data.
Definition: sanboot.h:89
INT 13 SAN device private data.
Definition: int13.c:55

References DBGC2, san_device::drive, 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 515 of file int13.c.

520  {
521  struct int13_data *int13 = sandev->priv;
522  unsigned int cylinder, head, sector;
523  unsigned long lba;
524  unsigned int count;
526  int rc;
527 
528  /* Validate blocksize */
529  if ( sandev_blksize ( sandev ) != INT13_BLKSIZE ) {
530  DBGC ( sandev->drive, "\nINT 13 drive %02x invalid blocksize "
531  "(%zd) for non-extended read/write\n",
532  sandev->drive, sandev_blksize ( sandev ) );
533  return -INT13_STATUS_INVALID;
534  }
535 
536  /* Calculate parameters */
537  cylinder = ( ( ( ix86->regs.cl & 0xc0 ) << 2 ) | ix86->regs.ch );
538  head = ix86->regs.dh;
539  sector = ( ix86->regs.cl & 0x3f );
540  if ( ( cylinder >= int13->cylinders ) ||
541  ( head >= int13->heads ) ||
542  ( sector < 1 ) || ( sector > int13->sectors_per_track ) ) {
543  DBGC ( sandev->drive, "C/H/S %d/%d/%d out of range for "
544  "geometry %d/%d/%d\n", cylinder, head, sector,
545  int13->cylinders, int13->heads,
546  int13->sectors_per_track );
547  return -INT13_STATUS_INVALID;
548  }
549  lba = ( ( ( ( cylinder * int13->heads ) + head )
550  * int13->sectors_per_track ) + sector - 1 );
551  count = ix86->regs.al;
552  buffer = real_to_user ( ix86->segs.es, ix86->regs.bx );
553 
554  DBGC2 ( sandev->drive, "C/H/S %d/%d/%d = LBA %08lx <-> %04x:%04x "
555  "(count %d)\n", cylinder, head, sector, lba, ix86->segs.es,
556  ix86->regs.bx, count );
557 
558  /* Read from / write to block device */
559  if ( ( rc = sandev_rw ( sandev, lba, count, buffer ) ) != 0 ){
560  DBGC ( sandev->drive, "INT13 drive %02x I/O failed: %s\n",
561  sandev->drive, strerror ( rc ) );
562  return -INT13_STATUS_READ_ERROR;
563  }
564 
565  return 0;
566 }
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:1074
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:596
#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:65
#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:89
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:235
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 581 of file int13.c.

582  {
583 
584  DBGC2 ( sandev->drive, "Read: " );
585  return int13_rw_sectors ( sandev, ix86, sandev_read );
586 }
unsigned int drive
Drive number.
Definition: sanboot.h:65
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:515
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Read from SAN device.
Definition: sanboot.c:645
#define DBGC2(...)
Definition: compiler.h:522

References DBGC2, san_device::drive, 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 601 of file int13.c.

602  {
603 
604  DBGC2 ( sandev->drive, "Write: " );
605  return int13_rw_sectors ( sandev, ix86, sandev_write );
606 }
unsigned int drive
Drive number.
Definition: sanboot.h:65
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:515
#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:665

References DBGC2, san_device::drive, 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 619 of file int13.c.

620  {
621  struct int13_data *int13 = sandev->priv;
622  unsigned int max_cylinder = int13->cylinders - 1;
623  unsigned int max_head = int13->heads - 1;
624  unsigned int max_sector = int13->sectors_per_track; /* sic */
625 
626  DBGC2 ( sandev->drive, "Get drive parameters\n" );
627 
628  /* Validate blocksize */
629  if ( sandev_blksize ( sandev ) != INT13_BLKSIZE ) {
630  DBGC ( sandev->drive, "\nINT 13 drive %02x invalid blocksize "
631  "(%zd) for non-extended parameters\n",
632  sandev->drive, sandev_blksize ( sandev ) );
633  return -INT13_STATUS_INVALID;
634  }
635 
636  /* Common parameters */
637  ix86->regs.ch = ( max_cylinder & 0xff );
638  ix86->regs.cl = ( ( ( max_cylinder >> 8 ) << 6 ) | max_sector );
639  ix86->regs.dh = max_head;
640  ix86->regs.dl = ( int13_is_fdd ( sandev ) ? num_fdds : num_drives );
641 
642  /* Floppy-specific parameters */
643  if ( int13_is_fdd ( sandev ) ) {
644  ix86->regs.bl = INT13_FDD_TYPE_1M44;
645  ix86->segs.es = rm_ds;
646  ix86->regs.di = __from_data16 ( &int13_fdd_params );
647  }
648 
649  return 0;
650 }
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:1074
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:65
#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:89
static size_t sandev_blksize(struct san_device *sandev)
Calculate SAN device block size.
Definition: sanboot.h:235
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 660 of file int13.c.

661  {
663 
664  DBGC2 ( sandev->drive, "Get disk type\n" );
665 
666  if ( int13_is_fdd ( sandev ) ) {
667  return INT13_DISK_TYPE_FDD;
668  } else {
669  blocks = int13_capacity32 ( sandev );
670  ix86->regs.cx = ( blocks >> 16 );
671  ix86->regs.dx = ( blocks & 0xffff );
672  return INT13_DISK_TYPE_HDD;
673  }
674 }
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
unsigned int drive
Drive number.
Definition: sanboot.h:65
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, san_device::drive, 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 685 of file int13.c.

686  {
687 
688  if ( ( ix86->regs.bx == 0x55aa ) && ! int13_is_fdd ( sandev ) ) {
689  DBGC2 ( sandev->drive, "INT13 extensions check\n" );
690  ix86->regs.bx = 0xaa55;
691  ix86->regs.cx = ( INT13_EXTENSION_LINEAR |
695  } else {
696  return -INT13_STATUS_INVALID;
697  }
698 }
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
unsigned int drive
Drive number.
Definition: sanboot.h:65
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, san_device::drive, 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 708 of file int13.c.

713  {
714  struct int13_disk_address addr;
716  uint64_t lba;
717  unsigned long count;
719  int rc;
720 
721  /* Extended reads are not allowed on floppy drives.
722  * ELTORITO.SYS seems to assume that we are really a CD-ROM if
723  * we support extended reads for a floppy drive.
724  */
725  if ( int13_is_fdd ( sandev ) )
726  return -INT13_STATUS_INVALID;
727 
728  /* Get buffer size */
729  get_real ( bufsize, ix86->segs.ds,
730  ( ix86->regs.si + offsetof ( typeof ( addr ), bufsize ) ) );
731  if ( bufsize < offsetof ( typeof ( addr ), buffer_phys ) ) {
732  DBGC2 ( sandev->drive, "<invalid buffer size %#02x\n>\n",
733  bufsize );
734  return -INT13_STATUS_INVALID;
735  }
736 
737  /* Read parameters from disk address structure */
738  memset ( &addr, 0, sizeof ( addr ) );
739  copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si, bufsize );
740  lba = addr.lba;
741  DBGC2 ( sandev->drive, "LBA %08llx <-> ",
742  ( ( unsigned long long ) lba ) );
743  if ( ( addr.count == 0xff ) ||
744  ( ( addr.buffer.segment == 0xffff ) &&
745  ( addr.buffer.offset == 0xffff ) ) ) {
746  buffer = phys_to_user ( addr.buffer_phys );
747  DBGC2 ( sandev->drive, "%08llx",
748  ( ( unsigned long long ) addr.buffer_phys ) );
749  } else {
750  buffer = real_to_user ( addr.buffer.segment,
751  addr.buffer.offset );
752  DBGC2 ( sandev->drive, "%04x:%04x", addr.buffer.segment,
753  addr.buffer.offset );
754  }
755  if ( addr.count <= 0x7f ) {
756  count = addr.count;
757  } else if ( addr.count == 0xff ) {
758  count = addr.long_count;
759  } else {
760  DBGC2 ( sandev->drive, " <invalid count %#02x>\n", addr.count );
761  return -INT13_STATUS_INVALID;
762  }
763  DBGC2 ( sandev->drive, " (count %ld)\n", count );
764 
765  /* Read from / write to block device */
766  if ( ( rc = sandev_rw ( sandev, lba, count, buffer ) ) != 0 ) {
767  DBGC ( sandev->drive, "INT13 drive %02x extended I/O failed: "
768  "%s\n", sandev->drive, strerror ( rc ) );
769  /* Record that no blocks were transferred successfully */
770  addr.count = 0;
771  put_real ( addr.count, ix86->segs.ds,
772  ( ix86->regs.si +
773  offsetof ( typeof ( addr ), count ) ) );
774  return -INT13_STATUS_READ_ERROR;
775  }
776 
777  return 0;
778 }
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:596
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:65
#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 787 of file int13.c.

788  {
789 
790  DBGC2 ( sandev->drive, "Extended read: " );
791  return int13_extended_rw ( sandev, ix86, sandev_read );
792 }
unsigned int drive
Drive number.
Definition: sanboot.h:65
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Read from SAN device.
Definition: sanboot.c:645
#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:708

References DBGC2, san_device::drive, 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 801 of file int13.c.

802  {
803 
804  DBGC2 ( sandev->drive, "Extended write: " );
805  return int13_extended_rw ( sandev, ix86, sandev_write );
806 }
unsigned int drive
Drive number.
Definition: sanboot.h:65
#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:708
int sandev_write(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Write to SAN device.
Definition: sanboot.c:665

References DBGC2, san_device::drive, 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 815 of file int13.c.

816  {
817  struct int13_disk_address addr;
818  uint64_t lba;
819  unsigned long count;
820 
821  /* Read parameters from disk address structure */
822  if ( DBG_EXTRA ) {
823  copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si,
824  sizeof ( addr ));
825  lba = addr.lba;
826  count = addr.count;
827  DBGC2 ( sandev->drive, "Verify: LBA %08llx (count %ld)\n",
828  ( ( unsigned long long ) lba ), count );
829  }
830 
831  /* We have no mechanism for verifying sectors */
832  return -INT13_STATUS_INVALID;
833 }
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
unsigned int drive
Drive number.
Definition: sanboot.h:65
#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, san_device::drive, 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 842 of file int13.c.

843  {
844  struct int13_disk_address addr;
845  uint64_t lba;
846  unsigned long count;
847 
848  /* Read parameters from disk address structure */
849  if ( DBG_EXTRA ) {
850  copy_from_real ( &addr, ix86->segs.ds, ix86->regs.si,
851  sizeof ( addr ));
852  lba = addr.lba;
853  count = addr.count;
854  DBGC2 ( sandev->drive, "Seek: LBA %08llx (count %ld)\n",
855  ( ( unsigned long long ) lba ), count );
856  }
857 
858  /* Ignore and return success */
859  return 0;
860 }
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
unsigned int drive
Drive number.
Definition: sanboot.h:65
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, san_device::drive, 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 869 of file int13.c.

870  {
871  struct san_path *sanpath;
872  struct device *device;
873  struct device_description *desc;
874  unsigned int i;
875  uint8_t sum = 0;
876  int rc;
877 
878  /* Reopen block device if necessary */
879  if ( sandev_needs_reopen ( sandev ) &&
880  ( ( rc = sandev_reopen ( sandev ) ) != 0 ) )
881  return rc;
882  sanpath = sandev->active;
883  assert ( sanpath != NULL );
884 
885  /* Get underlying hardware device */
886  device = identify_device ( &sanpath->block );
887  if ( ! device ) {
888  DBGC ( sandev->drive, "INT13 drive %02x cannot identify "
889  "hardware device\n", sandev->drive );
890  return -ENODEV;
891  }
892 
893  /* Fill in bus type and interface path */
894  desc = &device->desc;
895  switch ( desc->bus_type ) {
896  case BUS_TYPE_PCI:
898  dpi->interface_path.pci.bus = PCI_BUS ( desc->location );
899  dpi->interface_path.pci.slot = PCI_SLOT ( desc->location );
900  dpi->interface_path.pci.function = PCI_FUNC ( desc->location );
901  dpi->interface_path.pci.channel = 0xff; /* unused */
902  break;
903  default:
904  DBGC ( sandev->drive, "INT13 drive %02x unrecognised bus "
905  "type %d\n", sandev->drive, desc->bus_type );
906  return -ENOTSUP;
907  }
908 
909  /* Get EDD block device description */
910  if ( ( rc = edd_describe ( &sanpath->block, &dpi->interface_type,
911  &dpi->device_path ) ) != 0 ) {
912  DBGC ( sandev->drive, "INT13 drive %02x cannot identify "
913  "block device: %s\n", sandev->drive, strerror ( rc ) );
914  return rc;
915  }
916 
917  /* Fill in common fields and fix checksum */
919  dpi->len = sizeof ( *dpi );
920  for ( i = 0 ; i < sizeof ( *dpi ) ; i++ )
921  sum += *( ( ( uint8_t * ) dpi ) + i );
922  dpi->checksum -= sum;
923 
924  return 0;
925 }
#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
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#define DBGC(...)
Definition: compiler.h:505
struct interface block
Underlying block device interface.
Definition: sanboot.h:47
#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:255
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:36
unsigned int drive
Drive number.
Definition: sanboot.h:65
uint8_t len
Length of this structure.
Definition: edd.h:166
struct edd_device_path_information dpi
Device path information.
Definition: int13.h:28
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
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:94
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:371
#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, BUS_TYPE_PCI, edd_interface_path::channel, edd_device_path_information::checksum, DBGC, desc, 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, 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 934 of file int13.c.

935  {
936  struct int13_data *int13 = sandev->priv;
937  struct int13_disk_parameters params;
938  struct segoff address;
939  size_t len = sizeof ( params );
941  int rc;
942 
943  /* Get buffer size */
944  get_real ( bufsize, ix86->segs.ds,
945  ( ix86->regs.si + offsetof ( typeof ( params ), bufsize )));
946 
947  DBGC2 ( sandev->drive, "Get extended drive parameters to "
948  "%04x:%04x+%02x\n", ix86->segs.ds, ix86->regs.si, bufsize );
949 
950  /* Build drive parameters */
951  memset ( &params, 0, sizeof ( params ) );
952  params.flags = INT13_FL_DMA_TRANSPARENT;
953  if ( ( int13->cylinders < 1024 ) &&
954  ( sandev_capacity ( sandev ) <= INT13_MAX_CHS_SECTORS ) ) {
955  params.flags |= INT13_FL_CHS_VALID;
956  }
957  params.cylinders = int13->cylinders;
958  params.heads = int13->heads;
959  params.sectors_per_track = int13->sectors_per_track;
960  params.sectors = sandev_capacity ( sandev );
961  params.sector_size = sandev_blksize ( sandev );
962  memset ( &params.dpte, 0xff, sizeof ( params.dpte ) );
963  if ( ( rc = int13_device_path_info ( sandev, &params.dpi ) ) != 0 ) {
964  DBGC ( sandev->drive, "INT13 drive %02x could not provide "
965  "device path information: %s\n",
966  sandev->drive, strerror ( rc ) );
967  len = offsetof ( typeof ( params ), dpi );
968  }
969 
970  /* Calculate returned "buffer size" (which will be less than
971  * the length actually copied if device path information is
972  * present).
973  */
974  if ( bufsize < offsetof ( typeof ( params ), dpte ) )
975  return -INT13_STATUS_INVALID;
976  if ( bufsize < offsetof ( typeof ( params ), dpi ) ) {
977  params.bufsize = offsetof ( typeof ( params ), dpte );
978  } else {
979  params.bufsize = offsetof ( typeof ( params ), dpi );
980  }
981 
982  DBGC ( sandev->drive, "INT 13 drive %02x described using extended "
983  "parameters:\n", sandev->drive );
984  address.segment = ix86->segs.ds;
985  address.offset = ix86->regs.si;
986  DBGC_HDA ( sandev->drive, address, &params, len );
987 
988  /* Return drive parameters */
989  if ( len > bufsize )
990  len = bufsize;
991  copy_to_real ( ix86->segs.ds, ix86->regs.si, &params, len );
992 
993  return 0;
994 }
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:1074
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:869
#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:65
static uint64_t sandev_capacity(struct san_device *sandev)
Calculate SAN device capacity.
Definition: sanboot.h:245
#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:89
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:235
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 1003 of file int13.c.

1004  {
1005  struct int13_cdrom_specification specification;
1006 
1007  DBGC2 ( sandev->drive, "Get CD-ROM emulation status to %04x:%04x%s\n",
1008  ix86->segs.ds, ix86->regs.si,
1009  ( ix86->regs.al ? "" : " and terminate" ) );
1010 
1011  /* Fail if we are not a CD-ROM */
1012  if ( ! sandev->is_cdrom ) {
1013  DBGC ( sandev->drive, "INT13 drive %02x is not a CD-ROM\n",
1014  sandev->drive );
1015  return -INT13_STATUS_INVALID;
1016  }
1017 
1018  /* Build specification packet */
1019  memset ( &specification, 0, sizeof ( specification ) );
1020  specification.size = sizeof ( specification );
1021  specification.drive = sandev->drive;
1022 
1023  /* Return specification packet */
1024  copy_to_real ( ix86->segs.ds, ix86->regs.si, &specification,
1025  sizeof ( specification ) );
1026 
1027  return 0;
1028 }
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:65
#define INT13_STATUS_INVALID
Invalid function or parameter.
Definition: int13.h:61
int is_cdrom
Drive is a CD-ROM.
Definition: sanboot.h:86
#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 1038 of file int13.c.

1039  {
1040  struct int13_data *int13 = sandev->priv;
1042  unsigned int start;
1043  int rc;
1044 
1045  /* Read parameters from command packet */
1046  copy_from_real ( &command, ix86->segs.ds, ix86->regs.si,
1047  sizeof ( command ) );
1048  DBGC2 ( sandev->drive, "Read CD-ROM boot catalog to %08x\n",
1049  command.buffer );
1050 
1051  /* Fail if we have no boot catalog */
1052  if ( ! int13->boot_catalog ) {
1053  DBGC ( sandev->drive, "INT13 drive %02x has no boot catalog\n",
1054  sandev->drive );
1055  return -INT13_STATUS_INVALID;
1056  }
1057  start = ( int13->boot_catalog + command.start );
1058 
1059  /* Read from boot catalog */
1060  if ( ( rc = sandev_read ( sandev, start, command.count,
1061  phys_to_user ( command.buffer ) ) ) != 0 ) {
1062  DBGC ( sandev->drive, "INT13 drive %02x could not read boot "
1063  "catalog: %s\n", sandev->drive, strerror ( rc ) );
1064  return -INT13_STATUS_READ_ERROR;
1065  }
1066 
1067  return 0;
1068 }
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:1074
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:65
#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:645
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:89
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 1074 of file int13.c.

1074  {
1075  int command = ix86->regs.ah;
1076  unsigned int bios_drive = ix86->regs.dl;
1077  struct san_device *sandev;
1078  struct int13_data *int13;
1079  int status;
1080 
1081  /* Check BIOS hasn't killed off our drive */
1083 
1084  for_each_sandev ( sandev ) {
1085 
1086  int13 = sandev->priv;
1087  if ( bios_drive != sandev->drive ) {
1088  /* Remap any accesses to this drive's natural number */
1089  if ( bios_drive == int13->natural_drive ) {
1090  DBGC2 ( sandev->drive, "INT13,%02x (%02x) "
1091  "remapped to (%02x)\n", ix86->regs.ah,
1092  bios_drive, sandev->drive );
1093  ix86->regs.dl = sandev->drive;
1094  return;
1095  } else if ( ( ( bios_drive & 0x7f ) == 0x7f ) &&
1097  && sandev->is_cdrom ) {
1098  /* Catch non-drive-specific CD-ROM calls */
1099  } else {
1100  continue;
1101  }
1102  }
1103 
1104  DBGC2 ( sandev->drive, "INT13,%02x (%02x): ",
1105  ix86->regs.ah, bios_drive );
1106 
1107  switch ( command ) {
1108  case INT13_RESET:
1109  status = int13_reset ( sandev, ix86 );
1110  break;
1111  case INT13_GET_LAST_STATUS:
1112  status = int13_get_last_status ( sandev, ix86 );
1113  break;
1114  case INT13_READ_SECTORS:
1115  status = int13_read_sectors ( sandev, ix86 );
1116  break;
1117  case INT13_WRITE_SECTORS:
1118  status = int13_write_sectors ( sandev, ix86 );
1119  break;
1120  case INT13_GET_PARAMETERS:
1121  status = int13_get_parameters ( sandev, ix86 );
1122  break;
1123  case INT13_GET_DISK_TYPE:
1124  status = int13_get_disk_type ( sandev, ix86 );
1125  break;
1126  case INT13_EXTENSION_CHECK:
1127  status = int13_extension_check ( sandev, ix86 );
1128  break;
1129  case INT13_EXTENDED_READ:
1130  status = int13_extended_read ( sandev, ix86 );
1131  break;
1132  case INT13_EXTENDED_WRITE:
1133  status = int13_extended_write ( sandev, ix86 );
1134  break;
1135  case INT13_EXTENDED_VERIFY:
1136  status = int13_extended_verify ( sandev, ix86 );
1137  break;
1138  case INT13_EXTENDED_SEEK:
1139  status = int13_extended_seek ( sandev, ix86 );
1140  break;
1142  status = int13_get_extended_parameters ( sandev, ix86 );
1143  break;
1145  status = int13_cdrom_status_terminate ( sandev, ix86 );
1146  break;
1148  status = int13_cdrom_read_boot_catalog ( sandev, ix86 );
1149  break;
1150  default:
1151  DBGC2 ( sandev->drive, "*** Unrecognised INT13 ***\n" );
1153  break;
1154  }
1155 
1156  /* Store status for INT 13,01 */
1157  int13->last_status = status;
1158 
1159  /* Negative status indicates an error */
1160  if ( status < 0 ) {
1161  status = -status;
1162  DBGC ( sandev->drive, "INT13,%02x (%02x) failed with "
1163  "status %02x\n", ix86->regs.ah, sandev->drive,
1164  status );
1165  } else {
1166  ix86->flags &= ~CF;
1167  }
1168  ix86->regs.ah = status;
1169 
1170  /* Set OF to indicate to wrapper not to chain this call */
1171  ix86->flags |= OF;
1172 
1173  return;
1174  }
1175 }
static int int13_extended_seek(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 44 - Extended seek.
Definition: int13.c:842
#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:1074
#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:493
#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:619
static int int13_extended_write(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 43 - Extended write.
Definition: int13.c:801
#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:815
static void int13_check_num_drives(void)
Check number of drives.
Definition: int13.c:456
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:660
#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:65
#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:581
static int int13_get_extended_parameters(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 48 - Get extended parameters.
Definition: int13.c:934
static int int13_extended_read(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 42 - Extended read.
Definition: int13.c:787
int is_cdrom
Drive is a CD-ROM.
Definition: sanboot.h:86
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:1038
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:1003
A SAN device.
Definition: sanboot.h:58
#define for_each_sandev(sandev)
Iterate over all SAN devices.
Definition: sanboot.h:196
static int int13_write_sectors(struct san_device *sandev, struct i386_all_regs *ix86)
INT 13, 03 - Write sectors.
Definition: int13.c:601
static int int13_reset(struct san_device *sandev, struct i386_all_regs *ix86 __unused)
INT 13, 00 - Reset disk system.
Definition: int13.c:474
#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:89
#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:685
#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 1181 of file int13.c.

1181  {
1182  /* Assembly wrapper to call int13(). int13() sets OF if we
1183  * should not chain to the previous handler. (The wrapper
1184  * clears CF and OF before calling int13()).
1185  */
1187  TEXT16_CODE ( "\nint13_wrapper:\n\t"
1188  /* Preserve %ax and %dx for future reference */
1189  "pushw %%bp\n\t"
1190  "movw %%sp, %%bp\n\t"
1191  "pushw %%ax\n\t"
1192  "pushw %%dx\n\t"
1193  /* Clear OF, set CF, call int13() */
1194  "orb $0, %%al\n\t"
1195  "stc\n\t"
1196  VIRT_CALL ( int13 )
1197  /* Chain if OF not set */
1198  "jo 1f\n\t"
1199  "pushfw\n\t"
1200  "lcall *%%cs:int13_vector\n\t"
1201  "\n1:\n\t"
1202  /* Overwrite flags for iret */
1203  "pushfw\n\t"
1204  "popw 6(%%bp)\n\t"
1205  /* Fix up %dl:
1206  *
1207  * INT 13,15 : do nothing if hard disk
1208  * INT 13,08 : load with number of drives
1209  * all others: restore original value
1210  */
1211  "cmpb $0x15, -1(%%bp)\n\t"
1212  "jne 2f\n\t"
1213  "testb $0x80, -4(%%bp)\n\t"
1214  "jnz 3f\n\t"
1215  "\n2:\n\t"
1216  "movb -4(%%bp), %%dl\n\t"
1217  "cmpb $0x08, -1(%%bp)\n\t"
1218  "jne 3f\n\t"
1219  "testb $0x80, %%dl\n\t"
1220  "movb %%cs:num_drives, %%dl\n\t"
1221  "jnz 3f\n\t"
1222  "movb %%cs:num_fdds, %%dl\n\t"
1223  /* Return */
1224  "\n3:\n\t"
1225  "movw %%bp, %%sp\n\t"
1226  "popw %%bp\n\t"
1227  "iret\n\t" ) : : );
1228 
1230 }
#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:1074
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 1235 of file int13.c.

1235  {
1237  &int13_vector );
1238 }
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 1252 of file int13.c.

1253  {
1254  struct san_device *sandev;
1255  struct int13_data *int13;
1256  unsigned int natural_drive;
1257  void *scratch;
1258  int need_hook = ( ! have_sandevs() );
1259  int rc;
1260 
1261  /* Calculate natural drive number */
1263  natural_drive = ( ( drive & 0x80 ) ? ( num_drives | 0x80 ) : num_fdds );
1264 
1265  /* Use natural drive number if directed to do so */
1266  if ( ( drive & 0x7f ) == 0x7f )
1267  drive = natural_drive;
1268 
1269  /* Allocate SAN device */
1270  sandev = alloc_sandev ( uris, count, sizeof ( *int13 ) );
1271  if ( ! sandev ) {
1272  rc = -ENOMEM;
1273  goto err_alloc;
1274  }
1275  int13 = sandev->priv;
1276  int13->natural_drive = natural_drive;
1277 
1278  /* Register SAN device */
1279  if ( ( rc = register_sandev ( sandev, drive, flags ) ) != 0 ) {
1280  DBGC ( drive, "INT13 drive %02x could not register: %s\n",
1281  drive, strerror ( rc ) );
1282  goto err_register;
1283  }
1284 
1285  /* Allocate scratch area */
1286  scratch = malloc ( sandev_blksize ( sandev ) );
1287  if ( ! scratch )
1288  goto err_alloc_scratch;
1289 
1290  /* Parse parameters, if present */
1291  if ( sandev->is_cdrom &&
1292  ( ( rc = int13_parse_eltorito ( sandev, scratch ) ) != 0 ) )
1293  goto err_parse_eltorito;
1294 
1295  /* Give drive a default geometry, if applicable */
1296  if ( ( sandev_blksize ( sandev ) == INT13_BLKSIZE ) &&
1297  ( ( rc = int13_guess_geometry ( sandev, scratch ) ) != 0 ) )
1298  goto err_guess_geometry;
1299 
1300  DBGC ( drive, "INT13 drive %02x (naturally %02x) registered with "
1301  "C/H/S geometry %d/%d/%d\n", drive, int13->natural_drive,
1302  int13->cylinders, int13->heads, int13->sectors_per_track );
1303 
1304  /* Hook INT 13 vector if not already hooked */
1305  if ( need_hook ) {
1307  devices_get();
1308  }
1309 
1310  /* Update BIOS drive count */
1312 
1313  free ( scratch );
1314  return drive;
1315 
1316  err_guess_geometry:
1317  err_parse_eltorito:
1318  free ( scratch );
1319  err_alloc_scratch:
1320  unregister_sandev ( sandev );
1321  err_register:
1322  sandev_put ( sandev );
1323  err_alloc:
1324  return rc;
1325 }
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:1074
void unregister_sandev(struct san_device *sandev)
Unregister SAN device.
Definition: sanboot.c:939
#define DBGC(...)
Definition: compiler.h:505
static void sandev_put(struct san_device *sandev)
Drop reference to SAN device.
Definition: sanboot.h:225
uint8_t drive
Drive number.
Definition: int13.h:16
static void int13_hook_vector(void)
Hook INT 13 handler.
Definition: int13.c:1181
#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:414
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:203
#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
int register_sandev(struct san_device *sandev, unsigned int drive, unsigned int flags)
Register SAN device.
Definition: sanboot.c:877
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:86
#define num_fdds
Definition: int13.c:130
A SAN device.
Definition: sanboot.h:58
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:89
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:235
struct san_device * alloc_sandev(struct uri **uris, unsigned int count, size_t priv_size)
Allocate SAN device.
Definition: sanboot.c:834
static int int13_guess_geometry(struct san_device *sandev, void *scratch)
Guess INT 13 drive geometry.
Definition: int13.c:373
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, 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 1336 of file int13.c.

1336  {
1337  struct san_device *sandev;
1338 
1339  /* Find drive */
1340  sandev = sandev_find ( drive );
1341  if ( ! sandev ) {
1342  DBGC ( drive, "INT13 drive %02x is not a SAN drive\n", drive );
1343  return;
1344  }
1345 
1346  /* Unregister SAN device */
1347  unregister_sandev ( sandev );
1348 
1349  /* Should adjust BIOS drive count, but it's difficult
1350  * to do so reliably.
1351  */
1352 
1353  DBGC ( drive, "INT13 drive %02x unregistered\n", drive );
1354 
1355  /* Unhook INT 13 vector if no more drives */
1356  if ( ! have_sandevs() ) {
1357  devices_put();
1359  }
1360 
1361  /* Drop reference to drive */
1362  sandev_put ( sandev );
1363 }
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:939
#define DBGC(...)
Definition: compiler.h:505
static void sandev_put(struct san_device *sandev)
Drop reference to SAN device.
Definition: sanboot.h:225
uint8_t drive
Drive number.
Definition: int13.h:16
static int have_sandevs(void)
There exist some SAN devices.
Definition: sanboot.h:203
static void int13_unhook_vector(void)
Unhook INT 13 handler.
Definition: int13.c:1235
A SAN device.
Definition: sanboot.h:58
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
Definition: sanboot.c:90

References DBGC, devices_put(), 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 1372 of file int13.c.

1372  {
1373  uint16_t status;
1374  int discard_b, discard_c, discard_d;
1375  uint16_t magic;
1376 
1377  /* Use INT 13, 02 to read the MBR */
1378  address->segment = 0;
1379  address->offset = 0x7c00;
1380  __asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t"
1381  "pushl %%ebx\n\t"
1382  "popw %%bx\n\t"
1383  "popw %%es\n\t"
1384  "stc\n\t"
1385  "sti\n\t"
1386  "int $0x13\n\t"
1387  "sti\n\t" /* BIOS bugs */
1388  "jc 1f\n\t"
1389  "xorw %%ax, %%ax\n\t"
1390  "\n1:\n\t"
1391  "popw %%es\n\t" )
1392  : "=a" ( status ), "=b" ( discard_b ),
1393  "=c" ( discard_c ), "=d" ( discard_d )
1394  : "a" ( 0x0201 ), "b" ( *address ),
1395  "c" ( 1 ), "d" ( drive ) );
1396  if ( status ) {
1397  DBGC ( drive, "INT13 drive %02x could not read MBR (status "
1398  "%04x)\n", drive, status );
1399  return -EIO;
1400  }
1401 
1402  /* Check magic signature */
1403  get_real ( magic, address->segment,
1404  ( address->offset +
1405  offsetof ( struct master_boot_record, magic ) ) );
1406  if ( magic != INT13_MBR_MAGIC ) {
1407  DBGC ( drive, "INT13 drive %02x does not contain a valid MBR\n",
1408  drive );
1409  return -ENOEXEC;
1410  }
1411 
1412  return 0;
1413 }
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
#define DBGC(...)
Definition: compiler.h:505
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 REAL_CODE(asm_code_str)
Definition: libkir.h:226

References __asm__(), __volatile__(), address, DBGC, 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 1435 of file int13.c.

1435  {
1436  struct {
1437  struct eltorito_validation_entry valid;
1438  struct eltorito_boot_entry boot;
1439  } __attribute__ (( packed )) catalog;
1440  uint16_t status;
1441 
1442  /* Use INT 13, 4d to read the boot catalog */
1443  __asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
1444  "sti\n\t"
1445  "int $0x13\n\t"
1446  "sti\n\t" /* BIOS bugs */
1447  "jc 1f\n\t"
1448  "xorw %%ax, %%ax\n\t"
1449  "\n1:\n\t" )
1450  : "=a" ( status )
1451  : "a" ( 0x4d00 ), "d" ( drive ),
1452  "S" ( __from_data16 ( &eltorito_cmd ) ) );
1453  if ( status ) {
1454  DBGC ( drive, "INT13 drive %02x could not read El Torito boot "
1455  "catalog (status %04x)\n", drive, status );
1456  return -EIO;
1457  }
1458  copy_from_user ( &catalog, phys_to_user ( eltorito_cmd.buffer ), 0,
1459  sizeof ( catalog ) );
1460 
1461  /* Sanity checks */
1462  if ( catalog.valid.platform_id != ELTORITO_PLATFORM_X86 ) {
1463  DBGC ( drive, "INT13 drive %02x El Torito specifies unknown "
1464  "platform %02x\n", drive, catalog.valid.platform_id );
1465  return -ENOEXEC;
1466  }
1467  if ( catalog.boot.indicator != ELTORITO_BOOTABLE ) {
1468  DBGC ( drive, "INT13 drive %02x El Torito is not bootable\n",
1469  drive );
1470  return -ENOEXEC;
1471  }
1472  if ( catalog.boot.media_type != ELTORITO_NO_EMULATION ) {
1473  DBGC ( drive, "INT13 drive %02x El Torito requires emulation "
1474  "type %02x\n", drive, catalog.boot.media_type );
1475  return -ENOTSUP;
1476  }
1477  DBGC ( drive, "INT13 drive %02x El Torito boot image at LBA %08x "
1478  "(count %d)\n", drive, catalog.boot.start, catalog.boot.length );
1479  address->segment = ( catalog.boot.load_segment ?
1480  catalog.boot.load_segment : 0x7c0 );
1481  address->offset = 0;
1482  DBGC ( drive, "INT13 drive %02x El Torito boot image loads at "
1483  "%04x:%04x\n", drive, address->segment, address->offset );
1484 
1485  /* Use INT 13, 42 to read the boot image */
1486  eltorito_address.bufsize =
1488  eltorito_address.count = catalog.boot.length;
1489  eltorito_address.buffer = *address;
1490  eltorito_address.lba = catalog.boot.start;
1491  __asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
1492  "sti\n\t"
1493  "int $0x13\n\t"
1494  "sti\n\t" /* BIOS bugs */
1495  "jc 1f\n\t"
1496  "xorw %%ax, %%ax\n\t"
1497  "\n1:\n\t" )
1498  : "=a" ( status )
1499  : "a" ( 0x4200 ), "d" ( drive ),
1500  "S" ( __from_data16 ( &eltorito_address ) ) );
1501  if ( status ) {
1502  DBGC ( drive, "INT13 drive %02x could not read El Torito boot "
1503  "image (status %04x)\n", drive, status );
1504  return -EIO;
1505  }
1506 
1507  return 0;
1508 }
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
#define DBGC(...)
Definition: compiler.h:505
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:1426
#define eltorito_cmd
Definition: int13.c:1422
__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 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(), DBGC, 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,
struct san_boot_config *config  __unused 
)
static

Attempt to boot from an INT 13 drive.

Parameters
driveDrive number
configBoot configuration parameters
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 1524 of file int13.c.

1525  {
1526  struct memory_map memmap;
1527  struct segoff address;
1528  int rc;
1529 
1530  /* Look for a usable boot sector */
1531  if ( ( ( rc = int13_load_mbr ( drive, &address ) ) != 0 ) &&
1532  ( ( rc = int13_load_eltorito ( drive, &address ) ) != 0 ) )
1533  return rc;
1534 
1535  /* Dump out memory map prior to boot, if memmap debugging is
1536  * enabled. Not required for program flow, but we have so
1537  * many problems that turn out to be memory-map related that
1538  * it's worth doing.
1539  */
1540  get_memmap ( &memmap );
1541 
1542  /* Jump to boot sector */
1543  if ( ( rc = call_bootsector ( address.segment, address.offset,
1544  drive ) ) != 0 ) {
1545  DBGC ( drive, "INT13 drive %02x boot returned: %s\n",
1546  drive, strerror ( rc ) );
1547  return rc;
1548  }
1549 
1550  return -ECANCELED; /* -EIMPOSSIBLE */
1551 }
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:1435
uint64_t address
Base address.
Definition: ena.h:24
#define DBGC(...)
Definition: compiler.h:505
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:1372
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78

References address, call_bootsector(), DBGC, 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 1573 of file int13.c.

1573  {
1574  struct segoff xbft_address;
1575  struct acpi_header *installed;
1576  size_t len;
1577 
1578  /* Check length */
1579  len = acpi->length;
1580  if ( len > ( sizeof ( xbftab ) - xbftab_used ) ) {
1581  DBGC ( acpi, "INT13 out of space for %s table\n",
1582  acpi_name ( acpi->signature ) );
1583  return -ENOSPC;
1584  }
1585 
1586  /* Install table */
1587  installed = ( ( ( void * ) xbftab ) + xbftab_used );
1588  memcpy ( installed, acpi, len );
1589  xbft_address.segment = rm_ds;
1590  xbft_address.offset = __from_data16 ( installed );
1591 
1592  /* Fill in common parameters */
1593  strncpy ( installed->oem_id, "FENSYS",
1594  sizeof ( installed->oem_id ) );
1595  strncpy ( installed->oem_table_id, "iPXE",
1596  sizeof ( installed->oem_table_id ) );
1597 
1598  /* Fix checksum */
1599  acpi_fix_checksum ( installed );
1600 
1601  /* Update used length */
1602  xbftab_used = ( ( xbftab_used + len + XBFTAB_ALIGN - 1 ) &
1603  ~( XBFTAB_ALIGN - 1 ) );
1604 
1605  DBGC ( acpi, "INT13 installed %s:\n",
1606  acpi_name ( installed->signature ) );
1607  DBGC_HDA ( acpi, xbft_address, installed, len );
1608  return 0;
1609 }
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:65
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:1565
#define XBFTAB_ALIGN
Alignment of boot firmware table entries.
Definition: int13.c:1557
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:1562

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 1616 of file int13.c.

1616  {
1617  int rc;
1618 
1619  /* Clear tables */
1620  memset ( &xbftab, 0, sizeof ( xbftab ) );
1621  xbftab_used = 0;
1622 
1623  /* Install ACPI tables */
1624  if ( ( rc = acpi_install ( int13_install ) ) != 0 ) {
1625  DBG ( "INT13 could not install ACPI tables: %s\n",
1626  strerror ( rc ) );
1627  return rc;
1628  }
1629 
1630  return 0;
1631 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int int13_install(struct acpi_header *acpi)
Install ACPI table.
Definition: int13.c:1573
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:1565
#define xbftab
Definition: int13.c:1562
#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 298 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 1565 of file int13.c.

Referenced by int13_describe(), and int13_install().