[bios] Add bin-x86_64-pcbios build platform

Move most arch/i386 files to arch/x86, and adjust the contents of the
Makefiles and the include/bits/*.h headers to reflect the new
locations.

This patch makes no substantive code changes, as can be seen using a
rename-aware diff (e.g. "git show -M5").

This patch does not make the pcbios platform functional for x86_64; it
merely allows it to compile without errors.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2016-02-16 15:19:01 +00:00
parent 43515f9f1a
commit f468f12b1e
155 changed files with 198 additions and 240 deletions

View File

@@ -0,0 +1,35 @@
#ifndef _BASEMEM_H
#define _BASEMEM_H
/** @file
*
* Base memory allocation
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <realmode.h>
#include <bios.h>
/**
* Read the BIOS free base memory counter
*
* @ret fbms Free base memory counter (in kB)
*/
static inline unsigned int get_fbms ( void ) {
uint16_t fbms;
get_real ( fbms, BDA_SEG, BDA_FBMS );
return fbms;
}
extern void set_fbms ( unsigned int new_fbms );
/* Actually in hidemem.c, but putting it here avoids polluting the
* architecture-independent include/hidemem.h.
*/
extern void hide_basemem ( void );
#endif /* _BASEMEM_H */

View File

@@ -0,0 +1,15 @@
#ifndef BASEMEM_PACKET_H
#define BASEMEM_PACKET_H
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <realmode.h>
/** Maximum length of base memory packet buffer */
#define BASEMEM_PACKET_LEN 1514
/** Base memory packet buffer */
extern char __bss16_array ( basemem_packet, [BASEMEM_PACKET_LEN] );
#define basemem_packet __use_data16 ( basemem_packet )
#endif /* BASEMEM_PACKET_H */

View File

@@ -0,0 +1,14 @@
#ifndef BIOS_H
#define BIOS_H
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define BDA_SEG 0x0040
#define BDA_EQUIPMENT_WORD 0x0010
#define BDA_FBMS 0x0013
#define BDA_REBOOT 0x0072
#define BDA_REBOOT_WARM 0x1234
#define BDA_NUM_DRIVES 0x0075
#define BDA_CHAR_HEIGHT 0x0085
#endif /* BIOS_H */

View File

@@ -0,0 +1,69 @@
#ifndef BIOS_DISKS_H
#define BIOS_DISKS_H
#include "dev.h"
/*
* Constants
*
*/
#define BIOS_DISK_MAX_NAME_LEN 6
struct bios_disk_sector {
char data[512];
};
/*
* The location of a BIOS disk
*
*/
struct bios_disk_loc {
uint8_t drive;
};
/*
* A physical BIOS disk device
*
*/
struct bios_disk_device {
char name[BIOS_DISK_MAX_NAME_LEN];
uint8_t drive;
uint8_t type;
};
/*
* A BIOS disk driver, with a valid device ID range and naming
* function.
*
*/
struct bios_disk_driver {
void ( *fill_drive_name ) ( char *buf, uint8_t drive );
uint8_t min_drive;
uint8_t max_drive;
};
/*
* Define a BIOS disk driver
*
*/
#define BIOS_DISK_DRIVER( _name, _fill_drive_name, _min_drive, _max_drive ) \
static struct bios_disk_driver _name = { \
.fill_drive_name = _fill_drive_name, \
.min_drive = _min_drive, \
.max_drive = _max_drive, \
}
/*
* Functions in bios_disks.c
*
*/
/*
* bios_disk bus global definition
*
*/
extern struct bus_driver bios_disk_driver;
#endif /* BIOS_DISKS_H */

View File

@@ -0,0 +1,34 @@
#ifndef BIOSINT_H
#define BIOSINT_H
/**
* @file BIOS interrupts
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <realmode.h>
struct segoff;
/**
* Hooked interrupt count
*
* At exit, after unhooking all possible interrupts, this counter
* should be examined. If it is non-zero, it means that we failed to
* unhook at least one interrupt vector, and so must not free up the
* memory we are using. (Note that this also implies that we should
* re-hook INT 15 in order to hide ourselves from the memory map).
*/
extern uint16_t __text16 ( hooked_bios_interrupts );
#define hooked_bios_interrupts __use_text16 ( hooked_bios_interrupts )
extern void hook_bios_interrupt ( unsigned int interrupt, unsigned int handler,
struct segoff *chain_vector );
extern int unhook_bios_interrupt ( unsigned int interrupt,
unsigned int handler,
struct segoff *chain_vector );
extern void check_bios_interrupts ( void );
#endif /* BIOSINT_H */

View File

@@ -0,0 +1,14 @@
#ifndef _BITS_ENTROPY_H
#define _BITS_ENTROPY_H
/** @file
*
* x86-specific entropy API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/rtc_entropy.h>
#endif /* _BITS_ENTROPY_H */

View File

@@ -0,0 +1,15 @@
#ifndef _BITS_NAP_H
#define _BITS_NAP_H
/** @file
*
* x86-specific CPU sleeping API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/bios_nap.h>
#include <ipxe/efi/efix86_nap.h>
#endif /* _BITS_MAP_H */

View File

@@ -0,0 +1,14 @@
#ifndef _BITS_REBOOT_H
#define _BITS_REBOOT_H
/** @file
*
* x86-specific reboot API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/bios_reboot.h>
#endif /* _BITS_REBOOT_H */

View File

@@ -0,0 +1,14 @@
#ifndef _BITS_SANBOOT_H
#define _BITS_SANBOOT_H
/** @file
*
* x86-specific sanboot API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/bios_sanboot.h>
#endif /* _BITS_SANBOOT_H */

View File

@@ -0,0 +1,14 @@
#ifndef _BITS_SMBIOS_H
#define _BITS_SMBIOS_H
/** @file
*
* x86-specific SMBIOS API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/bios_smbios.h>
#endif /* _BITS_SMBIOS_H */

View File

@@ -0,0 +1,14 @@
#ifndef _BITS_TIME_H
#define _BITS_TIME_H
/** @file
*
* x86-specific time API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/rtc_time.h>
#endif /* _BITS_TIME_H */

View File

@@ -0,0 +1,15 @@
#ifndef _BITS_TIMER_H
#define _BITS_TIMER_H
/** @file
*
* x86-specific timer API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/bios_timer.h>
#include <ipxe/rdtsc_timer.h>
#endif /* _BITS_TIMER_H */

View File

@@ -0,0 +1,14 @@
#ifndef _BITS_UACCESS_H
#define _BITS_UACCESS_H
/** @file
*
* x86-specific user access API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <librm.h>
#endif /* _BITS_UACCESS_H */

View File

@@ -0,0 +1,14 @@
#ifndef _BITS_UMALLOC_H
#define _BITS_UMALLOC_H
/** @file
*
* x86-specific user memory allocation API implementations
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/memtop_umalloc.h>
#endif /* _BITS_UMALLOC_H */

View File

@@ -0,0 +1,34 @@
#ifndef BOCHS_H
#define BOCHS_H
/** @file
*
* bochs breakpoints
*
* This file defines @c bochsbp, the magic breakpoint instruction that
* is incredibly useful when debugging under bochs. This file should
* never be included in production code.
*
* Use the pseudo-instruction @c bochsbp in assembly code, or the
* bochsbp() function in C code.
*
*/
#ifdef ASSEMBLY
/* Breakpoint for when debugging under bochs */
#define bochsbp xchgw %bx, %bx
#define BOCHSBP bochsbp
#else /* ASSEMBLY */
/** Breakpoint for when debugging under bochs */
static inline void bochsbp ( void ) {
__asm__ __volatile__ ( "xchgw %bx, %bx" );
}
#endif /* ASSEMBLY */
#warning "bochs.h should not be included into production code"
#endif /* BOCHS_H */

View File

@@ -0,0 +1,14 @@
#ifndef _BOOTSECTOR_H
#define _BOOTSECTOR_H
/** @file
*
* x86 bootsector image format
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
extern int call_bootsector ( unsigned int segment, unsigned int offset,
unsigned int drive );
#endif /* _BOOTSECTOR_H */

View File

@@ -0,0 +1,142 @@
#ifndef _BZIMAGE_H
#define _BZIMAGE_H
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
/**
* A bzImage header
*
* As documented in Documentation/i386/boot.txt
*/
struct bzimage_header {
/** The size of the setup in sectors
*
* If this field contains 0, assume it contains 4.
*/
uint8_t setup_sects;
/** If set, the root is mounted readonly */
uint16_t root_flags;
/** DO NOT USE - for bootsect.S use only */
uint16_t syssize;
/** DO NOT USE - obsolete */
uint16_t swap_dev;
/** DO NOT USE - for bootsect.S use only */
uint16_t ram_size;
/** Video mode control */
uint16_t vid_mode;
/** Default root device number */
uint16_t root_dev;
/** 0xAA55 magic number */
uint16_t boot_flag;
/** Jump instruction */
uint16_t jump;
/** Magic signature "HdrS" */
uint32_t header;
/** Boot protocol version supported */
uint16_t version;
/** Boot loader hook (see below) */
uint32_t realmode_swtch;
/** The load-low segment (0x1000) (obsolete) */
uint16_t start_sys;
/** Pointer to kernel version string */
uint16_t kernel_version;
/** Boot loader identifier */
uint8_t type_of_loader;
/** Boot protocol option flags */
uint8_t loadflags;
/** Move to high memory size (used with hooks) */
uint16_t setup_move_size;
/** Boot loader hook (see below) */
uint32_t code32_start;
/** initrd load address (set by boot loader) */
uint32_t ramdisk_image;
/** initrd size (set by boot loader) */
uint32_t ramdisk_size;
/** DO NOT USE - for bootsect.S use only */
uint32_t bootsect_kludge;
/** Free memory after setup end */
uint16_t heap_end_ptr;
/** Unused */
uint16_t pad1;
/** 32-bit pointer to the kernel command line */
uint32_t cmd_line_ptr;
/** Highest legal initrd address */
uint32_t initrd_addr_max;
/** Physical addr alignment required for kernel */
uint32_t kernel_alignment;
/** Whether kernel is relocatable or not */
uint8_t relocatable_kernel;
/** Unused */
uint8_t pad2[3];
/** Maximum size of the kernel command line */
uint32_t cmdline_size;
} __attribute__ (( packed ));
/** Offset of bzImage header within kernel image */
#define BZI_HDR_OFFSET 0x1f1
/** bzImage boot flag value */
#define BZI_BOOT_FLAG 0xaa55
/** bzImage magic signature value */
#define BZI_SIGNATURE 0x53726448
/** bzImage boot loader identifier for Etherboot */
#define BZI_LOADER_TYPE_ETHERBOOT 0x40
/** bzImage boot loader identifier for iPXE
*
* We advertise ourselves as Etherboot version 6.
*/
#define BZI_LOADER_TYPE_IPXE ( BZI_LOADER_TYPE_ETHERBOOT | 0x06 )
/** bzImage "load high" flag */
#define BZI_LOAD_HIGH 0x01
/** Load address for high-loaded kernels */
#define BZI_LOAD_HIGH_ADDR 0x100000
/** Load address for low-loaded kernels */
#define BZI_LOAD_LOW_ADDR 0x10000
/** bzImage "kernel can use heap" flag */
#define BZI_CAN_USE_HEAP 0x80
/** bzImage special video mode "normal" */
#define BZI_VID_MODE_NORMAL 0xffff
/** bzImage special video mode "ext" */
#define BZI_VID_MODE_EXT 0xfffe
/** bzImage special video mode "ask" */
#define BZI_VID_MODE_ASK 0xfffd
/** bzImage maximum initrd address for versions < 2.03 */
#define BZI_INITRD_MAX 0x37ffffff
/** bzImage command-line structure used by older kernels */
struct bzimage_cmdline {
/** Magic signature */
uint16_t magic;
/** Offset to command line */
uint16_t offset;
} __attribute__ (( packed ));
/** Offset of bzImage command-line structure within kernel image */
#define BZI_CMDLINE_OFFSET 0x20
/** bzImage command line present magic marker value */
#define BZI_CMDLINE_MAGIC 0xa33f
/** Assumed size of real-mode portion (including .bss) */
#define BZI_ASSUMED_RM_SIZE 0x8000
/** Amount of stack space to provide */
#define BZI_STACK_SIZE 0x1000
/** Maximum size of command line */
#define BZI_CMDLINE_SIZE 0x7ff
#endif /* _BZIMAGE_H */

View File

@@ -0,0 +1,9 @@
#ifndef _FAKEE820_H
#define _FAKEE820_H
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
extern void fake_e820 ( void );
extern void unfake_e820 ( void );
#endif /* _FAKEE820_H */

View File

@@ -0,0 +1,30 @@
#ifndef _INITRD_H
#define _INITRD_H
/** @file
*
* Initial ramdisk (initrd) reshuffling
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/uaccess.h>
/** Minimum alignment for initrds
*
* Some versions of Linux complain about initrds that are not
* page-aligned.
*/
#define INITRD_ALIGN 4096
/** Minimum free space required to reshuffle initrds
*
* Chosen to avoid absurdly long reshuffling times
*/
#define INITRD_MIN_FREE_LEN ( 512 * 1024 )
extern void initrd_reshuffle ( userptr_t bottom );
extern int initrd_reshuffle_check ( size_t len, userptr_t bottom );
#endif /* _INITRD_H */

View File

@@ -0,0 +1,333 @@
#ifndef INT13_H
#define INT13_H
/** @file
*
* INT 13 emulation
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/list.h>
#include <ipxe/edd.h>
#include <realmode.h>
/**
* @defgroup int13ops INT 13 operation codes
* @{
*/
/** Reset disk system */
#define INT13_RESET 0x00
/** Get status of last operation */
#define INT13_GET_LAST_STATUS 0x01
/** Read sectors */
#define INT13_READ_SECTORS 0x02
/** Write sectors */
#define INT13_WRITE_SECTORS 0x03
/** Get drive parameters */
#define INT13_GET_PARAMETERS 0x08
/** Get disk type */
#define INT13_GET_DISK_TYPE 0x15
/** Extensions installation check */
#define INT13_EXTENSION_CHECK 0x41
/** Extended read */
#define INT13_EXTENDED_READ 0x42
/** Extended write */
#define INT13_EXTENDED_WRITE 0x43
/** Verify sectors */
#define INT13_EXTENDED_VERIFY 0x44
/** Extended seek */
#define INT13_EXTENDED_SEEK 0x47
/** Get extended drive parameters */
#define INT13_GET_EXTENDED_PARAMETERS 0x48
/** Get CD-ROM status / terminate emulation */
#define INT13_CDROM_STATUS_TERMINATE 0x4b
/** Read CD-ROM boot catalog */
#define INT13_CDROM_READ_BOOT_CATALOG 0x4d
/** @} */
/**
* @defgroup int13status INT 13 status codes
* @{
*/
/** Operation completed successfully */
#define INT13_STATUS_SUCCESS 0x00
/** Invalid function or parameter */
#define INT13_STATUS_INVALID 0x01
/** Read error */
#define INT13_STATUS_READ_ERROR 0x04
/** Reset failed */
#define INT13_STATUS_RESET_FAILED 0x05
/** Write error */
#define INT13_STATUS_WRITE_ERROR 0xcc
/** @} */
/** Block size for non-extended INT 13 calls */
#define INT13_BLKSIZE 512
/** @defgroup int13fddtype INT 13 floppy disk drive types
* @{
*/
/** 360K */
#define INT13_FDD_TYPE_360K 0x01
/** 1.2M */
#define INT13_FDD_TYPE_1M2 0x02
/** 720K */
#define INT13_FDD_TYPE_720K 0x03
/** 1.44M */
#define INT13_FDD_TYPE_1M44 0x04
/** An INT 13 disk address packet */
struct int13_disk_address {
/** Size of the packet, in bytes */
uint8_t bufsize;
/** Reserved */
uint8_t reserved_a;
/** Block count */
uint8_t count;
/** Reserved */
uint8_t reserved_b;
/** Data buffer */
struct segoff buffer;
/** Starting block number */
uint64_t lba;
/** Data buffer (EDD 3.0+ only) */
uint64_t buffer_phys;
/** Block count (EDD 4.0+ only) */
uint32_t long_count;
/** Reserved */
uint32_t reserved_c;
} __attribute__ (( packed ));
/** INT 13 disk parameters */
struct int13_disk_parameters {
/** Size of this structure */
uint16_t bufsize;
/** Flags */
uint16_t flags;
/** Number of cylinders */
uint32_t cylinders;
/** Number of heads */
uint32_t heads;
/** Number of sectors per track */
uint32_t sectors_per_track;
/** Total number of sectors on drive */
uint64_t sectors;
/** Bytes per sector */
uint16_t sector_size;
/** Device parameter table extension */
struct segoff dpte;
/** Device path information */
struct edd_device_path_information dpi;
} __attribute__ (( packed ));
/**
* @defgroup int13types INT 13 disk types
* @{
*/
/** No such drive */
#define INT13_DISK_TYPE_NONE 0x00
/** Floppy without change-line support */
#define INT13_DISK_TYPE_FDD 0x01
/** Floppy with change-line support */
#define INT13_DISK_TYPE_FDD_CL 0x02
/** Hard disk */
#define INT13_DISK_TYPE_HDD 0x03
/** @} */
/**
* @defgroup int13flags INT 13 disk parameter flags
* @{
*/
/** DMA boundary errors handled transparently */
#define INT13_FL_DMA_TRANSPARENT 0x01
/** CHS information is valid */
#define INT13_FL_CHS_VALID 0x02
/** Removable drive */
#define INT13_FL_REMOVABLE 0x04
/** Write with verify supported */
#define INT13_FL_VERIFIABLE 0x08
/** Has change-line supported (valid only for removable drives) */
#define INT13_FL_CHANGE_LINE 0x10
/** Drive can be locked (valid only for removable drives) */
#define INT13_FL_LOCKABLE 0x20
/** CHS is max possible, not current media (valid only for removable drives) */
#define INT13_FL_CHS_MAX 0x40
/** @} */
/**
* @defgroup int13exts INT 13 extension flags
* @{
*/
/** Extended disk access functions supported */
#define INT13_EXTENSION_LINEAR 0x01
/** Removable drive functions supported */
#define INT13_EXTENSION_REMOVABLE 0x02
/** EDD functions supported */
#define INT13_EXTENSION_EDD 0x04
/** 64-bit extensions are present */
#define INT13_EXTENSION_64BIT 0x08
/** @} */
/**
* @defgroup int13vers INT 13 extension versions
* @{
*/
/** INT13 extensions version 1.x */
#define INT13_EXTENSION_VER_1_X 0x01
/** INT13 extensions version 2.0 (EDD-1.0) */
#define INT13_EXTENSION_VER_2_0 0x20
/** INT13 extensions version 2.1 (EDD-1.1) */
#define INT13_EXTENSION_VER_2_1 0x21
/** INT13 extensions version 3.0 (EDD-3.0) */
#define INT13_EXTENSION_VER_3_0 0x30
/** @} */
/** Maximum number of sectors for which CHS geometry is allowed to be valid
*
* This number is taken from the EDD specification.
*/
#define INT13_MAX_CHS_SECTORS 15482880
/** Bootable CD-ROM specification packet */
struct int13_cdrom_specification {
/** Size of packet in bytes */
uint8_t size;
/** Boot media type */
uint8_t media_type;
/** Drive number */
uint8_t drive;
/** CD-ROM controller number */
uint8_t controller;
/** LBA of disk image to emulate */
uint32_t lba;
/** Device specification */
uint16_t device;
/** Segment of 3K buffer for caching CD-ROM reads */
uint16_t cache_segment;
/** Load segment for initial boot image */
uint16_t load_segment;
/** Number of 512-byte sectors to load */
uint16_t load_sectors;
/** Low 8 bits of cylinder number */
uint8_t cyl;
/** Sector number, plus high 2 bits of cylinder number */
uint8_t cyl_sector;
/** Head number */
uint8_t head;
} __attribute__ (( packed ));
/** Bootable CD-ROM boot catalog command packet */
struct int13_cdrom_boot_catalog_command {
/** Size of packet in bytes */
uint8_t size;
/** Number of sectors of boot catalog to read */
uint8_t count;
/** Buffer for boot catalog */
uint32_t buffer;
/** First sector in boot catalog to transfer */
uint16_t start;
} __attribute__ (( packed ));
/** A C/H/S address within a partition table entry */
struct partition_chs {
/** Head number */
uint8_t head;
/** Sector number, plus high 2 bits of cylinder number */
uint8_t cyl_sector;
/** Low 8 bits of cylinder number */
uint8_t cyl;
} __attribute__ (( packed ));
#define PART_HEAD(chs) ( (chs).head )
#define PART_SECTOR(chs) ( (chs).cyl_sector & 0x3f )
#define PART_CYLINDER(chs) ( (chs).cyl | ( ( (chs).cyl_sector & 0xc0 ) << 2 ) )
/** A partition table entry within the MBR */
struct partition_table_entry {
/** Bootable flag */
uint8_t bootable;
/** C/H/S start address */
struct partition_chs chs_start;
/** System indicator (partition type) */
uint8_t type;
/** C/H/S end address */
struct partition_chs chs_end;
/** Linear start address */
uint32_t start;
/** Linear length */
uint32_t length;
} __attribute__ (( packed ));
/** A Master Boot Record */
struct master_boot_record {
/** Code area */
uint8_t code[440];
/** Disk signature */
uint32_t signature;
/** Padding */
uint8_t pad[2];
/** Partition table */
struct partition_table_entry partitions[4];
/** 0x55aa MBR signature */
uint16_t magic;
} __attribute__ (( packed ));
/** MBR magic signature */
#define INT13_MBR_MAGIC 0xaa55
/** A floppy disk geometry */
struct int13_fdd_geometry {
/** Number of tracks */
uint8_t tracks;
/** Number of heads and sectors per track */
uint8_t heads_spt;
};
/** Define a floppy disk geometry */
#define INT13_FDD_GEOMETRY( cylinders, heads, sectors ) \
{ \
.tracks = (cylinders), \
.heads_spt = ( ( (heads) << 6 ) | (sectors) ), \
}
/** Get floppy disk number of cylinders */
#define INT13_FDD_CYLINDERS( geometry ) ( (geometry)->tracks )
/** Get floppy disk number of heads */
#define INT13_FDD_HEADS( geometry ) ( (geometry)->heads_spt >> 6 )
/** Get floppy disk number of sectors per track */
#define INT13_FDD_SECTORS( geometry ) ( (geometry)->heads_spt & 0x3f )
/** A floppy drive parameter table */
struct int13_fdd_parameters {
uint8_t step_rate__head_unload;
uint8_t head_load__ndma;
uint8_t motor_off_delay;
uint8_t bytes_per_sector;
uint8_t sectors_per_track;
uint8_t gap_length;
uint8_t data_length;
uint8_t format_gap_length;
uint8_t format_filler;
uint8_t head_settle_time;
uint8_t motor_start_time;
} __attribute__ (( packed ));
#endif /* INT13_H */

View File

@@ -0,0 +1,18 @@
#ifndef _IPXE_BIOS_NAP_H
#define _IPXE_BIOS_NAP_H
/** @file
*
* BIOS CPU sleeping
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef NAP_PCBIOS
#define NAP_PREFIX_pcbios
#else
#define NAP_PREFIX_pcbios __pcbios_
#endif
#endif /* _IPXE_BIOS_NAP_H */

View File

@@ -0,0 +1,18 @@
#ifndef _IPXE_BIOS_REBOOT_H
#define _IPXE_BIOS_REBOOT_H
/** @file
*
* Standard PC-BIOS reboot mechanism
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef REBOOT_PCBIOS
#define REBOOT_PREFIX_pcbios
#else
#define REBOOT_PREFIX_pcbios __pcbios_
#endif
#endif /* _IPXE_BIOS_REBOOT_H */

View File

@@ -0,0 +1,29 @@
#ifndef _IPXE_BIOS_SANBOOT_H
#define _IPXE_BIOS_SANBOOT_H
/** @file
*
* Standard PC-BIOS sanboot interface
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef SANBOOT_PCBIOS
#define SANBOOT_PREFIX_pcbios
#else
#define SANBOOT_PREFIX_pcbios __pcbios_
#endif
/**
* Get default SAN drive number
*
* @ret drive Default drive number
*/
static inline __always_inline unsigned int
SANBOOT_INLINE ( pcbios, san_default_drive ) ( void ) {
/* Default to booting from first hard disk */
return 0x80;
}
#endif /* _IPXE_BIOS_SANBOOT_H */

View File

@@ -0,0 +1,18 @@
#ifndef _IPXE_BIOS_SMBIOS_H
#define _IPXE_BIOS_SMBIOS_H
/** @file
*
* Standard PC-BIOS SMBIOS interface
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef SMBIOS_PCBIOS
#define SMBIOS_PREFIX_pcbios
#else
#define SMBIOS_PREFIX_pcbios __pcbios_
#endif
#endif /* _IPXE_BIOS_SMBIOS_H */

View File

@@ -0,0 +1,44 @@
#ifndef _IPXE_BIOS_TIMER_H
#define _IPXE_BIOS_TIMER_H
/** @file
*
* BIOS timer
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef TIMER_PCBIOS
#define TIMER_PREFIX_pcbios
#else
#define TIMER_PREFIX_pcbios __pcbios_
#endif
#include <ipxe/pit8254.h>
/**
* Delay for a fixed number of microseconds
*
* @v usecs Number of microseconds for which to delay
*/
static inline __always_inline void
TIMER_INLINE ( pcbios, udelay ) ( unsigned long usecs ) {
/* BIOS timer is not high-resolution enough for udelay(), so
* we use the 8254 Programmable Interval Timer.
*/
pit8254_udelay ( usecs );
}
/**
* Get number of ticks per second
*
* @ret ticks_per_sec Number of ticks per second
*/
static inline __always_inline unsigned long
TIMER_INLINE ( pcbios, ticks_per_sec ) ( void ) {
/* BIOS timer ticks over at 18.2 ticks per second */
return 18;
}
#endif /* _IPXE_BIOS_TIMER_H */

View File

@@ -0,0 +1,115 @@
#ifndef _IPXE_ERRNO_PCBIOS_H
#define _IPXE_ERRNO_PCBIOS_H
/**
* @file
*
* PC-BIOS platform error codes
*
* We use the PXE-specified error codes as the platform error codes
* for the PC-BIOS platform.
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <pxe_error.h>
/**
* Convert platform error code to platform component of iPXE error code
*
* @v platform Platform error code
* @ret errno Platform component of iPXE error code
*/
#define PLATFORM_TO_ERRNO( platform ) ( (platform) & 0xff )
/**
* Convert iPXE error code to platform error code
*
* @v errno iPXE error code
* @ret platform Platform error code
*/
#define ERRNO_TO_PLATFORM( errno ) ( (errno) & 0xff )
/* Platform-specific error codes */
#define PLATFORM_ENOERR PXENV_STATUS_SUCCESS
#define PLATFORM_E2BIG PXENV_STATUS_BAD_FUNC
#define PLATFORM_EACCES PXENV_STATUS_TFTP_ACCESS_VIOLATION
#define PLATFORM_EADDRINUSE PXENV_STATUS_UDP_OPEN
#define PLATFORM_EADDRNOTAVAIL PXENV_STATUS_UDP_OPEN
#define PLATFORM_EAFNOSUPPORT PXENV_STATUS_UNSUPPORTED
#define PLATFORM_EAGAIN PXENV_STATUS_FAILURE
#define PLATFORM_EALREADY PXENV_STATUS_UDP_OPEN
#define PLATFORM_EBADF PXENV_STATUS_TFTP_CLOSED
#define PLATFORM_EBADMSG PXENV_STATUS_FAILURE
#define PLATFORM_EBUSY PXENV_STATUS_OUT_OF_RESOURCES
#define PLATFORM_ECANCELED PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE
#define PLATFORM_ECHILD PXENV_STATUS_TFTP_FILE_NOT_FOUND
#define PLATFORM_ECONNABORTED PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION
#define PLATFORM_ECONNREFUSED PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION
#define PLATFORM_ECONNRESET PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION
#define PLATFORM_EDEADLK PXENV_STATUS_FAILURE
#define PLATFORM_EDESTADDRREQ PXENV_STATUS_BAD_FUNC
#define PLATFORM_EDOM PXENV_STATUS_FAILURE
#define PLATFORM_EDQUOT PXENV_STATUS_FAILURE
#define PLATFORM_EEXIST PXENV_STATUS_FAILURE
#define PLATFORM_EFAULT PXENV_STATUS_MCOPY_PROBLEM
#define PLATFORM_EFBIG PXENV_STATUS_MCOPY_PROBLEM
#define PLATFORM_EHOSTUNREACH PXENV_STATUS_ARP_TIMEOUT
#define PLATFORM_EIDRM PXENV_STATUS_FAILURE
#define PLATFORM_EILSEQ PXENV_STATUS_FAILURE
#define PLATFORM_EINPROGRESS PXENV_STATUS_FAILURE
#define PLATFORM_EINTR PXENV_STATUS_FAILURE
#define PLATFORM_EINVAL PXENV_STATUS_BAD_FUNC
#define PLATFORM_EIO PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION
#define PLATFORM_EISCONN PXENV_STATUS_UDP_OPEN
#define PLATFORM_EISDIR PXENV_STATUS_FAILURE
#define PLATFORM_ELOOP PXENV_STATUS_FAILURE
#define PLATFORM_EMFILE PXENV_STATUS_OUT_OF_RESOURCES
#define PLATFORM_EMLINK PXENV_STATUS_FAILURE
#define PLATFORM_EMSGSIZE PXENV_STATUS_BAD_FUNC
#define PLATFORM_EMULTIHOP PXENV_STATUS_FAILURE
#define PLATFORM_ENAMETOOLONG PXENV_STATUS_FAILURE
#define PLATFORM_ENETDOWN PXENV_STATUS_ARP_TIMEOUT
#define PLATFORM_ENETRESET PXENV_STATUS_FAILURE
#define PLATFORM_ENETUNREACH PXENV_STATUS_ARP_TIMEOUT
#define PLATFORM_ENFILE PXENV_STATUS_OUT_OF_RESOURCES
#define PLATFORM_ENOBUFS PXENV_STATUS_OUT_OF_RESOURCES
#define PLATFORM_ENODATA PXENV_STATUS_FAILURE
#define PLATFORM_ENODEV PXENV_STATUS_TFTP_FILE_NOT_FOUND
#define PLATFORM_ENOENT PXENV_STATUS_TFTP_FILE_NOT_FOUND
#define PLATFORM_ENOEXEC PXENV_STATUS_FAILURE
#define PLATFORM_ENOLCK PXENV_STATUS_FAILURE
#define PLATFORM_ENOLINK PXENV_STATUS_FAILURE
#define PLATFORM_ENOMEM PXENV_STATUS_OUT_OF_RESOURCES
#define PLATFORM_ENOMSG PXENV_STATUS_FAILURE
#define PLATFORM_ENOPROTOOPT PXENV_STATUS_UNSUPPORTED
#define PLATFORM_ENOSPC PXENV_STATUS_OUT_OF_RESOURCES
#define PLATFORM_ENOSR PXENV_STATUS_OUT_OF_RESOURCES
#define PLATFORM_ENOSTR PXENV_STATUS_FAILURE
#define PLATFORM_ENOSYS PXENV_STATUS_UNSUPPORTED
#define PLATFORM_ENOTCONN PXENV_STATUS_FAILURE
#define PLATFORM_ENOTDIR PXENV_STATUS_FAILURE
#define PLATFORM_ENOTEMPTY PXENV_STATUS_FAILURE
#define PLATFORM_ENOTSOCK PXENV_STATUS_FAILURE
#define PLATFORM_ENOTSUP PXENV_STATUS_UNSUPPORTED
#define PLATFORM_ENOTTY PXENV_STATUS_FAILURE
#define PLATFORM_ENXIO PXENV_STATUS_TFTP_FILE_NOT_FOUND
#define PLATFORM_EOPNOTSUPP PXENV_STATUS_UNSUPPORTED
#define PLATFORM_EOVERFLOW PXENV_STATUS_FAILURE
#define PLATFORM_EPERM PXENV_STATUS_TFTP_ACCESS_VIOLATION
#define PLATFORM_EPIPE PXENV_STATUS_FAILURE
#define PLATFORM_EPROTO PXENV_STATUS_FAILURE
#define PLATFORM_EPROTONOSUPPORT PXENV_STATUS_UNSUPPORTED
#define PLATFORM_EPROTOTYPE PXENV_STATUS_FAILURE
#define PLATFORM_ERANGE PXENV_STATUS_FAILURE
#define PLATFORM_EROFS PXENV_STATUS_FAILURE
#define PLATFORM_ESPIPE PXENV_STATUS_FAILURE
#define PLATFORM_ESRCH PXENV_STATUS_TFTP_FILE_NOT_FOUND
#define PLATFORM_ESTALE PXENV_STATUS_FAILURE
#define PLATFORM_ETIME PXENV_STATUS_FAILURE
#define PLATFORM_ETIMEDOUT PXENV_STATUS_TFTP_READ_TIMEOUT
#define PLATFORM_ETXTBSY PXENV_STATUS_FAILURE
#define PLATFORM_EWOULDBLOCK PXENV_STATUS_TFTP_OPEN
#define PLATFORM_EXDEV PXENV_STATUS_FAILURE
#endif /* _IPXE_ERRNO_PCBIOS_H */

View File

@@ -0,0 +1,18 @@
#ifndef _IPXE_MEMTOP_UMALLOC_H
#define _IPXE_MEMTOP_UMALLOC_H
/** @file
*
* External memory allocation
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef UMALLOC_MEMTOP
#define UMALLOC_PREFIX_memtop
#else
#define UMALLOC_PREFIX_memtop __memtop_
#endif
#endif /* _IPXE_MEMTOP_UMALLOC_H */

View File

@@ -0,0 +1,39 @@
#ifndef _IPXE_RDTSC_TIMER_H
#define _IPXE_RDTSC_TIMER_H
/** @file
*
* RDTSC timer
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef TIMER_RDTSC
#define TIMER_PREFIX_rdtsc
#else
#define TIMER_PREFIX_rdtsc __rdtsc_
#endif
/**
* RDTSC values can easily overflow an unsigned long. We discard the
* low-order bits in order to obtain sensibly-scaled values.
*/
#define TSC_SHIFT 8
/**
* Get current system time in ticks
*
* @ret ticks Current time, in ticks
*/
static inline __always_inline unsigned long
TIMER_INLINE ( rdtsc, currticks ) ( void ) {
unsigned long ticks;
__asm__ __volatile__ ( "rdtsc\n\t"
"shrdl %1, %%edx, %%eax\n\t"
: "=a" ( ticks ) : "i" ( TSC_SHIFT ) : "edx" );
return ticks;
}
#endif /* _IPXE_RDTSC_TIMER_H */

View File

@@ -0,0 +1,62 @@
#ifndef _IPXE_RTC_ENTROPY_H
#define _IPXE_RTC_ENTROPY_H
/** @file
*
* RTC-based entropy source
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#ifdef ENTROPY_RTC
#define ENTROPY_PREFIX_rtc
#else
#define ENTROPY_PREFIX_rtc __rtc_
#endif
/**
* min-entropy per sample
*
* @ret min_entropy min-entropy of each sample
*/
static inline __always_inline double
ENTROPY_INLINE ( rtc, min_entropy_per_sample ) ( void ) {
/* The min-entropy has been measured on several platforms
* using the entropy_sample test code. Modelling the samples
* as independent, and using a confidence level of 99.99%, the
* measurements were as follows:
*
* qemu-kvm : 7.38 bits
* VMware : 7.46 bits
* Physical hardware : 2.67 bits
*
* We choose the lowest of these (2.67 bits) and apply a 50%
* safety margin to allow for some potential non-independence
* of samples.
*/
return 1.3;
}
extern uint8_t rtc_sample ( void );
/**
* Get noise sample
*
* @ret noise Noise sample
* @ret rc Return status code
*/
static inline __always_inline int
ENTROPY_INLINE ( rtc, get_noise ) ( noise_sample_t *noise ) {
/* Get sample */
*noise = rtc_sample();
/* Always successful */
return 0;
}
#endif /* _IPXE_RTC_ENTROPY_H */

View File

@@ -0,0 +1,18 @@
#ifndef _IPXE_RTC_TIME_H
#define _IPXE_RTC_TIME_H
/** @file
*
* RTC-based time source
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef TIME_RTC
#define TIME_PREFIX_rtc
#else
#define TIME_PREFIX_rtc __rtc_
#endif
#endif /* _IPXE_RTC_TIME_H */

View File

@@ -0,0 +1,210 @@
#ifndef _IPXE_VESAFB_H
#define _IPXE_VESAFB_H
/** @file
*
* VESA frame buffer console
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <realmode.h>
/** INT 10,4f00: return controller information */
#define VBE_CONTROLLER_INFO 0x4f00
/** VBE controller information */
struct vbe_controller_info {
/** VBE signature */
uint32_t vbe_signature;
/** VBE minor version */
uint8_t vbe_minor_version;
/** VBE major version */
uint8_t vbe_major_version;
/** Pointer to OEM string */
struct segoff oem_string_ptr;
/** Capabilities of graphics controller */
uint32_t capabilities;
/** Pointer to video mode list */
struct segoff video_mode_ptr;
/** Number of 64kB memory blocks */
uint16_t total_memory;
/** VBE implementation software revision */
uint16_t oem_software_rev;
/** Pointer to vendor name string */
struct segoff oem_vendor_name_ptr;
/** Pointer to product name string */
struct segoff oem_product_name_ptr;
/** Pointer to product revision string */
struct segoff oem_product_rev_ptr;
/** Reserved for VBE implementation scratch area */
uint8_t reserved[222];
/* VBE2.0 defines an additional 256-byte data area for
* including the OEM strings inline within the VBE information
* block; we omit this to reduce the amount of base memory
* required for VBE calls.
*/
} __attribute__ (( packed ));
/** VBE controller information signature */
#define VBE_CONTROLLER_SIGNATURE \
( ( 'V' << 0 ) | ( 'E' << 8 ) | ( 'S' << 16 ) | ( 'A' << 24 ) )
/** VBE mode list end marker */
#define VBE_MODE_END 0xffff
/** INT 10,4f01: return VBE mode information */
#define VBE_MODE_INFO 0x4f01
/** VBE mode information */
struct vbe_mode_info {
/** Mode attributes */
uint16_t mode_attributes;
/** Window A attributes */
uint8_t win_a_attributes;
/** Window B attributes */
uint8_t win_b_attributes;
/** Window granularity */
uint16_t win_granularity;
/** Window size */
uint16_t win_size;
/** Window A start segment */
uint16_t win_a_segment;
/** Window B start segment */
uint16_t win_b_segment;
/** Pointer to window function */
struct segoff win_func_ptr;
/** Bytes per scan line */
uint16_t bytes_per_scan_line;
/** Horizontal resolution in pixels or characters */
uint16_t x_resolution;
/** Vertical resolution in pixels or characters */
uint16_t y_resolution;
/** Character cell width in pixels */
uint8_t x_char_size;
/** Character cell height in pixels */
uint8_t y_char_size;
/** Number of memory planes */
uint8_t number_of_planes;
/** Bits per pixel */
uint8_t bits_per_pixel;
/** Number of banks */
uint8_t number_of_banks;
/** Memory model type */
uint8_t memory_model;
/** Bank size in kB */
uint8_t bank_size;
/** Number of images */
uint8_t number_of_image_pages;
/** Reserved for page function */
uint8_t reserved_1;
/** Size of direct colour red mask in bits */
uint8_t red_mask_size;
/** Bit position of LSB of red mask */
uint8_t red_field_position;
/** Size of direct colour green mask in bits */
uint8_t green_mask_size;
/** Bit position of LSB of green mask */
uint8_t green_field_position;
/** Size of direct colour blue mask in bits */
uint8_t blue_mask_size;
/** Bit position of LSB of blue mask */
uint8_t blue_field_position;
/** Size of direct colour reserved mask in bits */
uint8_t rsvd_mask_size;
/** Bit position of LSB of reserved mask */
uint8_t rsvd_field_position;
/** Direct colour mode attributes */
uint8_t direct_colour_mode_info;
/** Physical address for flat memory frame buffer */
uint32_t phys_base_ptr;
/** Pointer to start of off-screen memory */
uint32_t off_screen_mem_offset;
/** Amount of off-screen memory in 1kB units */
uint16_t off_screen_mem_size;
/** Reserved */
uint8_t reserved_2[206];
} __attribute__ (( packed ));
/** VBE mode attributes */
enum vbe_mode_attributes {
/** Mode supported in hardware */
VBE_MODE_ATTR_SUPPORTED = 0x0001,
/** TTY output functions supported by BIOS */
VBE_MODE_ATTR_TTY = 0x0004,
/** Colour mode */
VBE_MODE_ATTR_COLOUR = 0x0008,
/** Graphics mode */
VBE_MODE_ATTR_GRAPHICS = 0x0010,
/** Not a VGA compatible mode */
VBE_MODE_ATTR_NOT_VGA = 0x0020,
/** VGA compatible windowed memory mode is not available */
VBE_MODE_ATTR_NOT_WINDOWED = 0x0040,
/** Linear frame buffer mode is available */
VBE_MODE_ATTR_LINEAR = 0x0080,
/** Double scan mode is available */
VBE_MODE_ATTR_DOUBLE = 0x0100,
/** Interlaced mode is available */
VBE_MODE_ATTR_INTERLACED = 0x0200,
/** Hardware triple buffering support */
VBE_MODE_ATTR_TRIPLE_BUF = 0x0400,
/** Hardware stereoscopic display support */
VBE_MODE_ATTR_STEREO = 0x0800,
/** Dual display start address support */
VBE_MODE_ATTR_DUAL = 0x1000,
};
/** VBE mode memory models */
enum vbe_mode_memory_model {
/** Text mode */
VBE_MODE_MODEL_TEXT = 0x00,
/** CGA graphics mode */
VBE_MODE_MODEL_CGA = 0x01,
/** Hercules graphics mode */
VBE_MODE_MODEL_HERCULES = 0x02,
/** Planar mode */
VBE_MODE_MODEL_PLANAR = 0x03,
/** Packed pixel mode */
VBE_MODE_MODEL_PACKED_PIXEL = 0x04,
/** Non-chain 4, 256 colour mode */
VBE_MODE_MODEL_NON_CHAIN_4 = 0x05,
/** Direct colour mode */
VBE_MODE_MODEL_DIRECT_COLOUR = 0x06,
/** YUV mode */
VBE_MODE_MODEL_YUV = 0x07,
};
/** INT 10,4f02: set VBE mode */
#define VBE_SET_MODE 0x4f02
/** VBE linear frame buffer mode bit */
#define VBE_MODE_LINEAR 0x4000
/** INT 10,1130: get font information */
#define VBE_GET_FONT 0x1130
/** Font sets */
enum vbe_font_set {
/** 8x14 character font */
VBE_FONT_8x14 = 0x0200,
/** 8x8 double dot font */
VBE_FONT_8x8_DOUBLE = 0x0300,
/** 8x8 double dot font (high 128 characters) */
VBE_FONT_8x8_DOUBLE_HIGH = 0x0400,
/** 9x14 alpha alternate font */
VBE_FONT_9x14_ALPHA_ALT = 0x0500,
/** 8x16 font */
VBE_FONT_8x16 = 0x0600,
/** 9x16 alternate font */
VBE_FONT_9x16_ALT = 0x0700,
};
/** INT 10,00: set VGA mode */
#define VBE_SET_VGA_MODE 0x0000
/** INT 10,0f: get VGA mode */
#define VBE_GET_VGA_MODE 0x0f00
#endif /* _IPXE_VESAFB_H */

View File

@@ -0,0 +1,18 @@
#ifndef KIR_H
#define KIR_H
#ifndef KEEP_IT_REAL
#error "kir.h can be used only with -DKEEP_IT_REAL"
#endif
#ifdef ASSEMBLY
#define code32 code16gcc
#else /* ASSEMBLY */
__asm__ ( ".code16gcc" );
#endif /* ASSEMBLY */
#endif /* KIR_H */

View File

@@ -0,0 +1,233 @@
#ifndef LIBKIR_H
#define LIBKIR_H
#include "realmode.h"
#ifndef ASSEMBLY
/*
* Full API documentation for these functions is in realmode.h.
*
*/
/* Access to variables in .data16 and .text16 in a way compatible with librm */
#define __data16( variable ) variable
#define __data16_array( variable, array ) variable array
#define __bss16( variable ) variable
#define __bss16_array( variable, array ) variable array
#define __text16( variable ) variable
#define __text16_array( variable,array ) variable array
#define __use_data16( variable ) variable
#define __use_text16( variable ) variable
#define __from_data16( pointer ) pointer
#define __from_text16( pointer ) pointer
/* Real-mode data and code segments */
static inline __attribute__ (( always_inline )) unsigned int _rm_cs ( void ) {
uint16_t cs;
__asm__ __volatile__ ( "movw %%cs, %w0" : "=r" ( cs ) );
return cs;
}
static inline __attribute__ (( always_inline )) unsigned int _rm_ds ( void ) {
uint16_t ds;
__asm__ __volatile__ ( "movw %%ds, %w0" : "=r" ( ds ) );
return ds;
}
#define rm_cs ( _rm_cs() )
#define rm_ds ( _rm_ds() )
/* Copy to/from base memory */
static inline void copy_to_real_libkir ( unsigned int dest_seg,
unsigned int dest_off,
const void *src, size_t n ) {
unsigned int discard_D, discard_S, discard_c;
__asm__ __volatile__ ( "pushw %%es\n\t"
"movw %3, %%es\n\t"
"rep movsb\n\t"
"popw %%es\n\t"
: "=D" ( discard_D ), "=S" ( discard_S ),
"=c" ( discard_c )
: "r" ( dest_seg ), "D" ( dest_off ),
"S" ( src ),
"c" ( n )
: "memory" );
}
static inline void copy_from_real_libkir ( void *dest,
unsigned int src_seg,
unsigned int src_off,
size_t n ) {
unsigned int discard_D, discard_S, discard_c;
__asm__ __volatile__ ( "pushw %%ds\n\t"
"movw %4, %%ds\n\t"
"rep movsb\n\t"
"popw %%ds\n\t"
: "=D" ( discard_D ), "=S" ( discard_S ),
"=c" ( discard_c )
: "D" ( dest ),
"r" ( src_seg ), "S" ( src_off ),
"c" ( n )
: "memory" );
}
#define copy_to_real copy_to_real_libkir
#define copy_from_real copy_from_real_libkir
/*
* Transfer individual values to/from base memory. There may well be
* a neater way to do this. We have two versions: one for constant
* offsets (where the mov instruction must be of the form "mov
* %es:123, %xx") and one for non-constant offsets (where the mov
* instruction must be of the form "mov %es:(%xx), %yx". If it's
* possible to incorporate both forms into one __asm__ instruction, I
* don't know how to do it.
*
* Ideally, the mov instruction should be "mov%z0"; the "%z0" is meant
* to expand to either "b", "w" or "l" depending on the size of
* operand 0. This would remove the (minor) ambiguity in the mov
* instruction. However, gcc on at least my system barfs with an
* "internal compiler error" when confronted with %z0.
*
*/
#define put_real_kir_const_off( var, seg, off ) \
__asm__ ( "movw %w1, %%es\n\t" \
"mov %0, %%es:%c2\n\t" \
"pushw %%ds\n\t" /* restore %es */ \
"popw %%es\n\t" \
: \
: "r,r" ( var ), "rm,rm" ( seg ), "i,!r" ( off ) \
)
#define put_real_kir_nonconst_off( var, seg, off ) \
__asm__ ( "movw %w1, %%es\n\t" \
"mov %0, %%es:(%2)\n\t" \
"pushw %%ds\n\t" /* restore %es */ \
"popw %%es\n\t" \
: \
: "r" ( var ), "rm" ( seg ), "r" ( off ) \
)
#define put_real_kir( var, seg, off ) \
do { \
if ( __builtin_constant_p ( off ) ) \
put_real_kir_const_off ( var, seg, off ); \
else \
put_real_kir_nonconst_off ( var, seg, off ); \
} while ( 0 )
#define get_real_kir_const_off( var, seg, off ) \
__asm__ ( "movw %w1, %%es\n\t" \
"mov %%es:%c2, %0\n\t" \
"pushw %%ds\n\t" /* restore %es */ \
"popw %%es\n\t" \
: "=r,r" ( var ) \
: "rm,rm" ( seg ), "i,!r" ( off ) \
)
#define get_real_kir_nonconst_off( var, seg, off ) \
__asm__ ( "movw %w1, %%es\n\t" \
"mov %%es:(%2), %0\n\t" \
"pushw %%ds\n\t" /* restore %es */ \
"popw %%es\n\t" \
: "=r" ( var ) \
: "rm" ( seg ), "r" ( off ) \
)
#define get_real_kir( var, seg, off ) \
do { \
if ( __builtin_constant_p ( off ) ) \
get_real_kir_const_off ( var, seg, off ); \
else \
get_real_kir_nonconst_off ( var, seg, off ); \
} while ( 0 )
#define put_real put_real_kir
#define get_real get_real_kir
/**
* A pointer to a user buffer
*
* This is actually a struct segoff, but encoded as a uint32_t to
* ensure that gcc passes it around efficiently.
*/
typedef uint32_t userptr_t;
/**
* Copy data to user buffer
*
* @v buffer User buffer
* @v offset Offset within user buffer
* @v src Source
* @v len Length
*/
static inline __attribute__ (( always_inline )) void
copy_to_user ( userptr_t buffer, off_t offset, const void *src, size_t len ) {
copy_to_real ( ( buffer >> 16 ), ( ( buffer & 0xffff ) + offset ),
src, len );
}
/**
* Copy data from user buffer
*
* @v dest Destination
* @v buffer User buffer
* @v offset Offset within user buffer
* @v len Length
*/
static inline __attribute__ (( always_inline )) void
copy_from_user ( void *dest, userptr_t buffer, off_t offset, size_t len ) {
copy_from_real ( dest, ( buffer >> 16 ),
( ( buffer & 0xffff ) + offset ), len );
}
/**
* Convert segment:offset address to user buffer
*
* @v segment Real-mode segment
* @v offset Real-mode offset
* @ret buffer User buffer
*/
static inline __attribute__ (( always_inline )) userptr_t
real_to_user ( unsigned int segment, unsigned int offset ) {
return ( ( segment << 16 ) | offset );
}
/**
* Convert virtual address to user buffer
*
* @v virtual Virtual address
* @ret buffer User buffer
*
* This constructs a user buffer from an ordinary pointer. Use it
* when you need to pass a pointer to an internal buffer to a function
* that expects a @c userptr_t.
*/
static inline __attribute__ (( always_inline )) userptr_t
virt_to_user ( void * virtual ) {
return real_to_user ( rm_ds, ( intptr_t ) virtual );
}
/* TEXT16_CODE: declare a fragment of code that resides in .text16 */
#define TEXT16_CODE( asm_code_str ) \
".section \".text16\", \"ax\", @progbits\n\t" \
".code16\n\t" \
".arch i386\n\t" \
asm_code_str "\n\t" \
".code16gcc\n\t" \
".previous\n\t"
/* REAL_CODE: declare a fragment of code that executes in real mode */
#define REAL_CODE( asm_code_str ) \
".code16\n\t" \
asm_code_str "\n\t" \
".code16gcc\n\t"
#endif /* ASSEMBLY */
#endif /* LIBKIR_H */

View File

@@ -0,0 +1,276 @@
#ifndef LIBRM_H
#define LIBRM_H
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/* Segment selectors as used in our protected-mode GDTs.
*
* Don't change these unless you really know what you're doing.
*/
#define VIRTUAL_CS 0x08
#define VIRTUAL_DS 0x10
#define PHYSICAL_CS 0x18
#define PHYSICAL_DS 0x20
#define REAL_CS 0x28
#define REAL_DS 0x30
#if 0
#define LONG_CS 0x38
#define LONG_DS 0x40
#endif
#ifndef ASSEMBLY
#ifdef UACCESS_LIBRM
#define UACCESS_PREFIX_librm
#else
#define UACCESS_PREFIX_librm __librm_
#endif
/* Variables in librm.S */
extern unsigned long virt_offset;
/**
* Convert physical address to user pointer
*
* @v phys_addr Physical address
* @ret userptr User pointer
*/
static inline __always_inline userptr_t
UACCESS_INLINE ( librm, phys_to_user ) ( unsigned long phys_addr ) {
return ( phys_addr - virt_offset );
}
/**
* Convert user buffer to physical address
*
* @v userptr User pointer
* @v offset Offset from user pointer
* @ret phys_addr Physical address
*/
static inline __always_inline unsigned long
UACCESS_INLINE ( librm, user_to_phys ) ( userptr_t userptr, off_t offset ) {
return ( userptr + offset + virt_offset );
}
static inline __always_inline userptr_t
UACCESS_INLINE ( librm, virt_to_user ) ( volatile const void *addr ) {
return trivial_virt_to_user ( addr );
}
static inline __always_inline void *
UACCESS_INLINE ( librm, user_to_virt ) ( userptr_t userptr, off_t offset ) {
return trivial_user_to_virt ( userptr, offset );
}
static inline __always_inline userptr_t
UACCESS_INLINE ( librm, userptr_add ) ( userptr_t userptr, off_t offset ) {
return trivial_userptr_add ( userptr, offset );
}
static inline __always_inline off_t
UACCESS_INLINE ( librm, userptr_sub ) ( userptr_t userptr,
userptr_t subtrahend ) {
return trivial_userptr_sub ( userptr, subtrahend );
}
static inline __always_inline void
UACCESS_INLINE ( librm, memcpy_user ) ( userptr_t dest, off_t dest_off,
userptr_t src, off_t src_off,
size_t len ) {
trivial_memcpy_user ( dest, dest_off, src, src_off, len );
}
static inline __always_inline void
UACCESS_INLINE ( librm, memmove_user ) ( userptr_t dest, off_t dest_off,
userptr_t src, off_t src_off,
size_t len ) {
trivial_memmove_user ( dest, dest_off, src, src_off, len );
}
static inline __always_inline int
UACCESS_INLINE ( librm, memcmp_user ) ( userptr_t first, off_t first_off,
userptr_t second, off_t second_off,
size_t len ) {
return trivial_memcmp_user ( first, first_off, second, second_off, len);
}
static inline __always_inline void
UACCESS_INLINE ( librm, memset_user ) ( userptr_t buffer, off_t offset,
int c, size_t len ) {
trivial_memset_user ( buffer, offset, c, len );
}
static inline __always_inline size_t
UACCESS_INLINE ( librm, strlen_user ) ( userptr_t buffer, off_t offset ) {
return trivial_strlen_user ( buffer, offset );
}
static inline __always_inline off_t
UACCESS_INLINE ( librm, memchr_user ) ( userptr_t buffer, off_t offset,
int c, size_t len ) {
return trivial_memchr_user ( buffer, offset, c, len );
}
/******************************************************************************
*
* Access to variables in .data16 and .text16
*
*/
extern char *data16;
extern char *text16;
#define __data16( variable ) \
__attribute__ (( section ( ".data16" ) )) \
_data16_ ## variable __asm__ ( #variable )
#define __data16_array( variable, array ) \
__attribute__ (( section ( ".data16" ) )) \
_data16_ ## variable array __asm__ ( #variable )
#define __bss16( variable ) \
__attribute__ (( section ( ".bss16" ) )) \
_data16_ ## variable __asm__ ( #variable )
#define __bss16_array( variable, array ) \
__attribute__ (( section ( ".bss16" ) )) \
_data16_ ## variable array __asm__ ( #variable )
#define __text16( variable ) \
__attribute__ (( section ( ".text16.data" ) )) \
_text16_ ## variable __asm__ ( #variable )
#define __text16_array( variable, array ) \
__attribute__ (( section ( ".text16.data" ) )) \
_text16_ ## variable array __asm__ ( #variable )
#define __use_data16( variable ) \
( * ( ( typeof ( _data16_ ## variable ) * ) \
& ( data16 [ ( size_t ) & ( _data16_ ## variable ) ] ) ) )
#define __use_text16( variable ) \
( * ( ( typeof ( _text16_ ## variable ) * ) \
& ( text16 [ ( size_t ) & ( _text16_ ## variable ) ] ) ) )
#define __from_data16( pointer ) \
( ( unsigned int ) \
( ( ( void * ) (pointer) ) - ( ( void * ) data16 ) ) )
#define __from_text16( pointer ) \
( ( unsigned int ) \
( ( ( void * ) (pointer) ) - ( ( void * ) text16 ) ) )
/* Variables in librm.S, present in the normal data segment */
extern uint16_t rm_sp;
extern uint16_t rm_ss;
extern uint16_t __text16 ( rm_cs );
#define rm_cs __use_text16 ( rm_cs )
extern uint16_t __text16 ( rm_ds );
#define rm_ds __use_text16 ( rm_ds )
extern uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size );
extern void remove_user_from_rm_stack ( userptr_t data, size_t size );
/* CODE_DEFAULT: restore default .code32/.code64 directive */
#ifdef __x86_64__
#define CODE_DEFAULT ".code64"
#else
#define CODE_DEFAULT ".code32"
#endif
/* TEXT16_CODE: declare a fragment of code that resides in .text16 */
#define TEXT16_CODE( asm_code_str ) \
".section \".text16\", \"ax\", @progbits\n\t" \
".code16\n\t" \
asm_code_str "\n\t" \
CODE_DEFAULT "\n\t" \
".previous\n\t"
/* REAL_CODE: declare a fragment of code that executes in real mode */
#define REAL_CODE( asm_code_str ) \
"push $1f\n\t" \
"call real_call\n\t" \
"addl $4, %%esp\n\t" \
TEXT16_CODE ( "\n1:\n\t" \
asm_code_str \
"\n\t" \
"ret\n\t" )
/* PHYS_CODE: declare a fragment of code that executes in flat physical mode */
#define PHYS_CODE( asm_code_str ) \
"call _virt_to_phys\n\t" \
".code32\n\t" \
asm_code_str \
"call _phys_to_virt\n\t" \
CODE_DEFAULT "\n\t"
/** Number of interrupts */
#define NUM_INT 256
/** An interrupt descriptor table register */
struct idtr {
/** Limit */
uint16_t limit;
/** Base */
uint32_t base;
} __attribute__ (( packed ));
/** An interrupt descriptor table entry */
struct interrupt_descriptor {
/** Low 16 bits of address */
uint16_t low;
/** Code segment */
uint16_t segment;
/** Unused */
uint8_t unused;
/** Type and attributes */
uint8_t attr;
/** High 16 bits of address */
uint16_t high;
} __attribute__ (( packed ));
/** Interrupt descriptor is present */
#define IDTE_PRESENT 0x80
/** Interrupt descriptor 32-bit interrupt gate type */
#define IDTE_TYPE_IRQ32 0x0e
/** An interrupt vector
*
* Each interrupt vector comprises an eight-byte fragment of code:
*
* 60 pushal
* b0 xx movb $INT, %al
* e9 xx xx xx xx jmp interrupt_wrapper
*/
struct interrupt_vector {
/** "pushal" instruction */
uint8_t pushal;
/** "movb" instruction */
uint8_t movb;
/** Interrupt number */
uint8_t intr;
/** "jmp" instruction */
uint8_t jmp;
/** Interrupt wrapper address offset */
uint32_t offset;
/** Next instruction after jump */
uint8_t next[0];
} __attribute__ (( packed ));
/** "pushal" instruction */
#define PUSHAL_INSN 0x60
/** "movb" instruction */
#define MOVB_INSN 0xb0
/** "jmp" instruction */
#define JMP_INSN 0xe9
extern void set_interrupt_vector ( unsigned int intr, void *vector );
#endif /* ASSEMBLY */
#endif /* LIBRM_H */

View File

@@ -0,0 +1,19 @@
#ifndef _MEMSIZES_H
#define _MEMSIZES_H
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <basemem.h>
/**
* Get size of base memory from BIOS free base memory counter
*
* @ret basemem Base memory size, in kB
*/
static inline unsigned int basememsize ( void ) {
return get_fbms();
}
extern unsigned int extmemsize ( void );
#endif /* _MEMSIZES_H */

View File

@@ -0,0 +1,149 @@
#ifndef _MULTIBOOT_H
#define _MULTIBOOT_H
/**
* @file
*
* Multiboot operating systems
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
/** The magic number for the Multiboot header */
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
/** Boot modules must be page aligned */
#define MB_FLAG_PGALIGN 0x00000001
/** Memory map must be provided */
#define MB_FLAG_MEMMAP 0x00000002
/** Video mode information must be provided */
#define MB_FLAG_VIDMODE 0x00000004
/** Image is a raw multiboot image (not ELF) */
#define MB_FLAG_RAW 0x00010000
/**
* The magic number passed by a Multiboot-compliant boot loader
*
* Must be passed in register %eax when jumping to the Multiboot OS
* image.
*/
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
/** Multiboot information structure mem_* fields are valid */
#define MBI_FLAG_MEM 0x00000001
/** Multiboot information structure boot_device field is valid */
#define MBI_FLAG_BOOTDEV 0x00000002
/** Multiboot information structure cmdline field is valid */
#define MBI_FLAG_CMDLINE 0x00000004
/** Multiboot information structure module fields are valid */
#define MBI_FLAG_MODS 0x00000008
/** Multiboot information structure a.out symbol table is valid */
#define MBI_FLAG_AOUT 0x00000010
/** Multiboot information struture ELF section header table is valid */
#define MBI_FLAG_ELF 0x00000020
/** Multiboot information structure memory map is valid */
#define MBI_FLAG_MMAP 0x00000040
/** Multiboot information structure drive list is valid */
#define MBI_FLAG_DRIVES 0x00000080
/** Multiboot information structure ROM configuration field is valid */
#define MBI_FLAG_CFGTBL 0x00000100
/** Multiboot information structure boot loader name field is valid */
#define MBI_FLAG_LOADER 0x00000200
/** Multiboot information structure APM table is valid */
#define MBI_FLAG_APM 0x00000400
/** Multiboot information structure video information is valid */
#define MBI_FLAG_VBE 0x00000800
/** A multiboot header */
struct multiboot_header {
uint32_t magic;
uint32_t flags;
uint32_t checksum;
uint32_t header_addr;
uint32_t load_addr;
uint32_t load_end_addr;
uint32_t bss_end_addr;
uint32_t entry_addr;
} __attribute__ (( packed, may_alias ));
/** A multiboot a.out symbol table */
struct multiboot_aout_symbol_table {
uint32_t tabsize;
uint32_t strsize;
uint32_t addr;
uint32_t reserved;
} __attribute__ (( packed, may_alias ));
/** A multiboot ELF section header table */
struct multiboot_elf_section_header_table {
uint32_t num;
uint32_t size;
uint32_t addr;
uint32_t shndx;
} __attribute__ (( packed, may_alias ));
/** A multiboot information structure */
struct multiboot_info {
uint32_t flags;
uint32_t mem_lower;
uint32_t mem_upper;
uint32_t boot_device;
uint32_t cmdline;
uint32_t mods_count;
uint32_t mods_addr;
union {
struct multiboot_aout_symbol_table aout_syms;
struct multiboot_elf_section_header_table elf_sections;
} syms;
uint32_t mmap_length;
uint32_t mmap_addr;
uint32_t drives_length;
uint32_t drives_addr;
uint32_t config_table;
uint32_t boot_loader_name;
uint32_t apm_table;
uint32_t vbe_control_info;
uint32_t vbe_mode_info;
uint16_t vbe_mode;
uint16_t vbe_interface_seg;
uint16_t vbe_interface_off;
uint16_t vbe_interface_len;
} __attribute__ (( packed, may_alias ));
/** A multiboot module structure */
struct multiboot_module {
uint32_t mod_start;
uint32_t mod_end;
uint32_t string;
uint32_t reserved;
} __attribute__ (( packed, may_alias ));
/** A multiboot memory map entry */
struct multiboot_memory_map {
uint32_t size;
uint64_t base_addr;
uint64_t length;
uint32_t type;
} __attribute__ (( packed, may_alias ));
/** Usable RAM */
#define MBMEM_RAM 1
#endif /* _MULTIBOOT_H */

View File

@@ -0,0 +1,17 @@
#ifndef _PNPBIOS_H
#define _PNPBIOS_H
/** @file
*
* PnP BIOS
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/* BIOS segment address */
#define BIOS_SEG 0xf000
extern int find_pnp_bios ( void );
#endif /* _PNPBIOS_H */

200
src/arch/x86/include/pxe.h Normal file
View File

@@ -0,0 +1,200 @@
#ifndef PXE_H
#define PXE_H
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include "pxe_types.h"
#include "pxe_error.h"
#include "pxe_api.h"
#include <ipxe/device.h>
#include <ipxe/tables.h>
/** PXE API invalid function code */
#define PXENV_UNKNOWN 0xffff
/** Parameter block for pxenv_unknown() */
struct s_PXENV_UNKNOWN {
PXENV_STATUS_t Status; /**< PXE status code */
} __attribute__ (( packed ));
typedef struct s_PXENV_UNKNOWN PXENV_UNKNOWN_t;
/* Union used for PXE API calls; we don't know the type of the
* structure until we interpret the opcode. Also, Status is available
* in the same location for any opcode, and it's convenient to have
* non-specific access to it.
*/
union u_PXENV_ANY {
/* Make it easy to read status for any operation */
PXENV_STATUS_t Status;
struct s_PXENV_UNKNOWN unknown;
struct s_PXENV_UNLOAD_STACK unload_stack;
struct s_PXENV_GET_CACHED_INFO get_cached_info;
struct s_PXENV_TFTP_READ_FILE restart_tftp;
struct s_PXENV_START_UNDI start_undi;
struct s_PXENV_STOP_UNDI stop_undi;
struct s_PXENV_START_BASE start_base;
struct s_PXENV_STOP_BASE stop_base;
struct s_PXENV_TFTP_OPEN tftp_open;
struct s_PXENV_TFTP_CLOSE tftp_close;
struct s_PXENV_TFTP_READ tftp_read;
struct s_PXENV_TFTP_READ_FILE tftp_read_file;
struct s_PXENV_TFTP_GET_FSIZE tftp_get_fsize;
struct s_PXENV_UDP_OPEN udp_open;
struct s_PXENV_UDP_CLOSE udp_close;
struct s_PXENV_UDP_WRITE udp_write;
struct s_PXENV_UDP_READ udp_read;
struct s_PXENV_UNDI_STARTUP undi_startup;
struct s_PXENV_UNDI_CLEANUP undi_cleanup;
struct s_PXENV_UNDI_INITIALIZE undi_initialize;
struct s_PXENV_UNDI_RESET undi_reset_adapter;
struct s_PXENV_UNDI_SHUTDOWN undi_shutdown;
struct s_PXENV_UNDI_OPEN undi_open;
struct s_PXENV_UNDI_CLOSE undi_close;
struct s_PXENV_UNDI_TRANSMIT undi_transmit;
struct s_PXENV_UNDI_SET_MCAST_ADDRESS undi_set_mcast_address;
struct s_PXENV_UNDI_SET_STATION_ADDRESS undi_set_station_address;
struct s_PXENV_UNDI_SET_PACKET_FILTER undi_set_packet_filter;
struct s_PXENV_UNDI_GET_INFORMATION undi_get_information;
struct s_PXENV_UNDI_GET_STATISTICS undi_get_statistics;
struct s_PXENV_UNDI_CLEAR_STATISTICS undi_clear_statistics;
struct s_PXENV_UNDI_INITIATE_DIAGS undi_initiate_diags;
struct s_PXENV_UNDI_FORCE_INTERRUPT undi_force_interrupt;
struct s_PXENV_UNDI_GET_MCAST_ADDRESS undi_get_mcast_address;
struct s_PXENV_UNDI_GET_NIC_TYPE undi_get_nic_type;
struct s_PXENV_UNDI_GET_IFACE_INFO undi_get_iface_info;
struct s_PXENV_UNDI_GET_STATE undi_get_state;
struct s_PXENV_UNDI_ISR undi_isr;
struct s_PXENV_FILE_OPEN file_open;
struct s_PXENV_FILE_CLOSE file_close;
struct s_PXENV_FILE_SELECT file_select;
struct s_PXENV_FILE_READ file_read;
struct s_PXENV_GET_FILE_SIZE get_file_size;
struct s_PXENV_FILE_EXEC file_exec;
struct s_PXENV_FILE_API_CHECK file_api_check;
struct s_PXENV_FILE_EXIT_HOOK file_exit_hook;
};
typedef union u_PXENV_ANY PXENV_ANY_t;
/** A PXE API call */
struct pxe_api_call {
/** Entry point
*
* @v params PXE API call parameters
* @ret exit PXE API call exit code
*/
PXENV_EXIT_t ( * entry ) ( union u_PXENV_ANY *params );
/** Length of parameters */
uint16_t params_len;
/** Opcode */
uint16_t opcode;
};
/** PXE API call table */
#define PXE_API_CALLS __table ( struct pxe_api_call, "pxe_api_calls" )
/** Declare a PXE API call */
#define __pxe_api_call __table_entry ( PXE_API_CALLS, 01 )
/**
* Define a PXE API call
*
* @v _opcode Opcode
* @v _entry Entry point
* @v _params_type Type of parameter structure
* @ret call PXE API call
*/
#define PXE_API_CALL( _opcode, _entry, _params_type ) { \
.entry = ( ( ( ( PXENV_EXIT_t ( * ) ( _params_type *params ) ) NULL ) \
== ( ( typeof ( _entry ) * ) NULL ) ) \
? ( ( PXENV_EXIT_t ( * ) \
( union u_PXENV_ANY *params ) ) _entry ) \
: ( ( PXENV_EXIT_t ( * ) \
( union u_PXENV_ANY *params ) ) _entry ) ), \
.params_len = sizeof ( _params_type ), \
.opcode = _opcode, \
}
/** An UNDI expansion ROM header */
struct undi_rom_header {
/** Signature
*
* Must be equal to @c ROM_SIGNATURE
*/
UINT16_t Signature;
/** ROM length in 512-byte blocks */
UINT8_t ROMLength;
/** Unused */
UINT8_t unused[0x13];
/** Offset of the PXE ROM ID structure */
UINT16_t PXEROMID;
/** Offset of the PCI ROM structure */
UINT16_t PCIRHeader;
} __attribute__ (( packed ));
/** Signature for an expansion ROM */
#define ROM_SIGNATURE 0xaa55
/** An UNDI ROM ID structure */
struct undi_rom_id {
/** Signature
*
* Must be equal to @c UNDI_ROM_ID_SIGNATURE
*/
UINT32_t Signature;
/** Length of structure */
UINT8_t StructLength;
/** Checksum */
UINT8_t StructCksum;
/** Structure revision
*
* Must be zero.
*/
UINT8_t StructRev;
/** UNDI revision
*
* Version 2.1.0 is encoded as the byte sequence 0x00, 0x01, 0x02.
*/
UINT8_t UNDIRev[3];
/** Offset to UNDI loader */
UINT16_t UNDILoader;
/** Minimum required stack segment size */
UINT16_t StackSize;
/** Minimum required data segment size */
UINT16_t DataSize;
/** Minimum required code segment size */
UINT16_t CodeSize;
} __attribute__ (( packed ));
/** Signature for an UNDI ROM ID structure */
#define UNDI_ROM_ID_SIGNATURE \
( ( 'U' << 0 ) + ( 'N' << 8 ) + ( 'D' << 16 ) + ( 'I' << 24 ) )
/** A PCI expansion header */
struct pcir_header {
/** Signature
*
* Must be equal to @c PCIR_SIGNATURE
*/
uint32_t signature;
/** PCI vendor ID */
uint16_t vendor_id;
/** PCI device ID */
uint16_t device_id;
} __attribute__ (( packed ));
/** Signature for an UNDI ROM ID structure */
#define PCIR_SIGNATURE \
( ( 'P' << 0 ) + ( 'C' << 8 ) + ( 'I' << 16 ) + ( 'R' << 24 ) )
extern struct net_device *pxe_netdev;
extern const char *pxe_cmdline;
extern void pxe_set_netdev ( struct net_device *netdev );
extern void pxe_fake_cached_info ( void );
extern PXENV_EXIT_t pxenv_tftp_read_file ( struct s_PXENV_TFTP_READ_FILE
*tftp_read_file );
extern PXENV_EXIT_t undi_loader ( struct s_UNDI_LOADER *undi_loader );
#endif /* PXE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,43 @@
#ifndef _PXE_CALL_H
#define _PXE_CALL_H
/** @file
*
* PXE API entry point
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <pxe_api.h>
#include <realmode.h>
#include <rmsetjmp.h>
struct net_device;
/** PXE load address segment */
#define PXE_LOAD_SEGMENT 0
/** PXE load address offset */
#define PXE_LOAD_OFFSET 0x7c00
/** PXE physical load address */
#define PXE_LOAD_PHYS ( ( PXE_LOAD_SEGMENT << 4 ) + PXE_LOAD_OFFSET )
/** !PXE structure */
extern struct s_PXE __text16 ( ppxe );
#define ppxe __use_text16 ( ppxe )
/** PXENV+ structure */
extern struct s_PXENV __text16 ( pxenv );
#define pxenv __use_text16 ( pxenv )
/** PXENV_RESTART_TFTP jump buffer */
extern rmjmp_buf pxe_restart_nbp;
extern void pxe_activate ( struct net_device *netdev );
extern int pxe_deactivate ( void );
extern int pxe_start_nbp ( void );
extern __asmcall void pxe_api_call ( struct i386_all_regs *ix86 );
extern int pxe_api_call_weak ( struct i386_all_regs *ix86 );
#endif /* _PXE_CALL_H */

View File

@@ -0,0 +1,123 @@
#ifndef PXE_ERROR_H
#define PXE_ERROR_H
/** @file
*
* Preboot eXecution Environment (PXE) error definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/**
* @defgroup pxeerrors PXE error codes
*
* @{
*/
/* Generic errors */
#define PXENV_STATUS_SUCCESS 0x0000
#define PXENV_STATUS_FAILURE 0x0001
#define PXENV_STATUS_BAD_FUNC 0x0002
#define PXENV_STATUS_UNSUPPORTED 0x0003
#define PXENV_STATUS_KEEP_UNDI 0x0004
#define PXENV_STATUS_KEEP_ALL 0x0005
#define PXENV_STATUS_OUT_OF_RESOURCES 0x0006
/* ARP errors (0x0010 to 0x001f) */
#define PXENV_STATUS_ARP_TIMEOUT 0x0011
/* Base-Code state errors */
#define PXENV_STATUS_UDP_CLOSED 0x0018
#define PXENV_STATUS_UDP_OPEN 0x0019
#define PXENV_STATUS_TFTP_CLOSED 0x001a
#define PXENV_STATUS_TFTP_OPEN 0x001b
/* BIOS/system errors (0x0020 to 0x002f) */
#define PXENV_STATUS_MCOPY_PROBLEM 0x0020
#define PXENV_STATUS_BIS_INTEGRITY_FAILURE 0x0021
#define PXENV_STATUS_BIS_VALIDATE_FAILURE 0x0022
#define PXENV_STATUS_BIS_INIT_FAILURE 0x0023
#define PXENV_STATUS_BIS_SHUTDOWN_FAILURE 0x0024
#define PXENV_STATUS_BIS_GBOA_FAILURE 0x0025
#define PXENV_STATUS_BIS_FREE_FAILURE 0x0026
#define PXENV_STATUS_BIS_GSI_FAILURE 0x0027
#define PXENV_STATUS_BIS_BAD_CKSUM 0x0028
/* TFTP/MTFTP errors (0x0030 to 0x003f) */
#define PXENV_STATUS_TFTP_CANNOT_ARP_ADDRESS 0x0030
#define PXENV_STATUS_TFTP_OPEN_TIMEOUT 0x0032
#define PXENV_STATUS_TFTP_UNKNOWN_OPCODE 0x0033
#define PXENV_STATUS_TFTP_READ_TIMEOUT 0x0035
#define PXENV_STATUS_TFTP_ERROR_OPCODE 0x0036
#define PXENV_STATUS_TFTP_CANNOT_OPEN_CONNECTION 0x0038
#define PXENV_STATUS_TFTP_CANNOT_READ_FROM_CONNECTION 0x0039
#define PXENV_STATUS_TFTP_TOO_MANY_PACKAGES 0x003a
#define PXENV_STATUS_TFTP_FILE_NOT_FOUND 0x003b
#define PXENV_STATUS_TFTP_ACCESS_VIOLATION 0x003c
#define PXENV_STATUS_TFTP_NO_MCAST_ADDRESS 0x003d
#define PXENV_STATUS_TFTP_NO_FILESIZE 0x003e
#define PXENV_STATUS_TFTP_INVALID_PACKET_SIZE 0x003f
/* Reserved errors 0x0040 to 0x004f) */
/* DHCP/BOOTP errors (0x0050 to 0x005f) */
#define PXENV_STATUS_DHCP_TIMEOUT 0x0051
#define PXENV_STATUS_DHCP_NO_IP_ADDRESS 0x0052
#define PXENV_STATUS_DHCP_NO_BOOTFILE_NAME 0x0053
#define PXENV_STATUS_DHCP_BAD_IP_ADDRESS 0x0054
/* Driver errors (0x0060 to 0x006f) */
#define PXENV_STATUS_UNDI_INVALID_FUNCTION 0x0060
#define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x0061
#define PXENV_STATUS_UNDI_CANNOT_INIT_NIC_FOR_MCAST 0x0062
#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_NIC 0x0063
#define PXENV_STATUS_UNDI_CANNOT_INITIALIZE_PHY 0x0064
#define PXENV_STATUS_UNDI_CANNOT_READ_CONFIG_DATA 0x0065
#define PXENV_STATUS_UNDI_CANNOT_READ_INIT_DATA 0x0066
#define PXENV_STATUS_UNDI_BAD_MAC_ADDRESS 0x0067
#define PXENV_STATUS_UNDI_BAD_EEPROM_CHECKSUM 0x0068
#define PXENV_STATUS_UNDI_ERROR_SETTING_ISR 0x0069
#define PXENV_STATUS_UNDI_INVALID_STATE 0x006a
#define PXENV_STATUS_UNDI_TRANSMIT_ERROR 0x006b
#define PXENV_STATUS_UNDI_INVALID_PARAMETER 0x006c
/* ROM and NBP bootstrap errors (0x0070 to 0x007f) */
#define PXENV_STATUS_BSTRAP_PROMPT_MENU 0x0074
#define PXENV_STATUS_BSTRAP_MCAST_ADDR 0x0076
#define PXENV_STATUS_BSTRAP_MISSING_LIST 0x0077
#define PXENV_STATUS_BSTRAP_NO_RESPONSE 0x0078
#define PXENV_STATUS_BSTRAP_FILE_TOO_BIG 0x0079
/* Environment NBP errors (0x0080 to 0x008f) */
/* Reserved errors (0x0090 to 0x009f) */
/* Miscellaneous errors (0x00a0 to 0x00af) */
#define PXENV_STATUS_BINL_CANCELED_BY_KEYSTROKE 0x00a0
#define PXENV_STATUS_BINL_NO_PXE_SERVER 0x00a1
#define PXENV_STATUS_NOT_AVAILABLE_IN_PMODE 0x00a2
#define PXENV_STATUS_NOT_AVAILABLE_IN_RMODE 0x00a3
/* BUSD errors (0x00b0 to 0x00bf) */
#define PXENV_STATUS_BUSD_DEVICE_NOT_SUPPORTED 0x00b0
/* Loader errors (0x00c0 to 0x00cf) */
#define PXENV_STATUS_LOADER_NO_FREE_BASE_MEMORY 0x00c0
#define PXENV_STATUS_LOADER_NO_BC_ROMID 0x00c1
#define PXENV_STATUS_LOADER_BAD_BC_ROMID 0x00c2
#define PXENV_STATUS_LOADER_BAD_BC_RUNTIME_IMAGE 0x00c3
#define PXENV_STATUS_LOADER_NO_UNDI_ROMID 0x00c4
#define PXENV_STATUS_LOADER_BAD_UNDI_ROMID 0x00c5
#define PXENV_STATUS_LOADER_BAD_UNDI_DRIVER_IMAGE 0x00c6
#define PXENV_STATUS_LOADER_NO_PXE_STRUCT 0x00c8
#define PXENV_STATUS_LOADER_NO_PXENV_STRUCT 0x00c9
#define PXENV_STATUS_LOADER_UNDI_START 0x00ca
#define PXENV_STATUS_LOADER_BC_START 0x00cb
/** @} */
/** Derive PXENV_STATUS code from iPXE error number */
#define PXENV_STATUS( rc ) ( (-(rc)) & 0x00ff )
#endif /* PXE_ERROR_H */

View File

@@ -0,0 +1,127 @@
#ifndef PXE_TYPES_H
#define PXE_TYPES_H
/** @file
*
* PXE data types
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <errno.h> /* PXE status codes */
/** @addtogroup pxe Preboot eXecution Environment (PXE) API
* @{
*/
/** @defgroup pxe_types PXE data types
*
* Basic PXE data types such as #UINT16_t, #ADDR32_t, #SEGSEL_t etc.
*
* These definitions are based on Table 1-1 ("Data Type Definitions")
* in the Intel PXE specification version 2.1. They have been
* generalised to non-x86 architectures where possible.
*
* @{
*/
/** An 8-bit unsigned integer */
typedef uint8_t UINT8_t;
/** A 16-bit unsigned integer */
typedef uint16_t UINT16_t;
/** A 32-bit unsigned integer */
typedef uint32_t UINT32_t;
/** A PXE exit code.
*
* Permitted values are #PXENV_EXIT_SUCCESS and #PXENV_EXIT_FAILURE.
*
*/
typedef UINT16_t PXENV_EXIT_t;
#define PXENV_EXIT_SUCCESS 0x0000 /**< No error occurred */
#define PXENV_EXIT_FAILURE 0x0001 /**< An error occurred */
/** A PXE status code.
*
* Status codes are defined in errno.h.
*
*/
typedef UINT16_t PXENV_STATUS_t;
/** An IPv4 address.
*
* @note This data type is in network (big-endian) byte order.
*
*/
typedef UINT32_t IP4_t;
/** A UDP port.
*
* @note This data type is in network (big-endian) byte order.
*
*/
typedef UINT16_t UDP_PORT_t;
/** Maximum length of a MAC address */
#define MAC_ADDR_LEN 16
/** A MAC address */
typedef UINT8_t MAC_ADDR_t[MAC_ADDR_LEN];
#ifndef HAVE_ARCH_ADDR32
/** A physical address.
*
* For x86, this is a 32-bit physical address, and is therefore
* limited to the low 4GB.
*
*/
typedef UINT32_t ADDR32_t;
#endif
#ifndef HAVE_ARCH_SEGSEL
/** A segment selector.
*
* For x86, this is a real mode segment (0x0000-0xffff), or a
* protected-mode segment selector, such as could be loaded into a
* segment register.
*
*/
typedef UINT16_t SEGSEL_t;
#endif
#ifndef HAVE_ARCH_OFF16
/** An offset within a segment identified by #SEGSEL
*
* For x86, this is a 16-bit offset.
*
*/
typedef UINT16_t OFF16_t;
#endif
/** A segment:offset address
*
* For x86, this is a 16-bit real-mode or protected-mode
* segment:offset address.
*
*/
typedef struct s_SEGOFF16 {
OFF16_t offset; /**< Offset within the segment */
SEGSEL_t segment; /**< Segment selector */
} __attribute__ (( packed )) SEGOFF16_t;
/** A segment descriptor */
typedef struct s_SEGDESC {
SEGSEL_t segment_address; /**< Segment selector */
ADDR32_t Physical_address; /**< Segment base address */
OFF16_t Seg_size; /**< Size of the segment */
} __attribute__ (( packed )) SEGDESC_t;
/** @} */ /* pxe_types */
/** @} */ /* pxe */
#endif /* PXE_TYPES_H */

View File

@@ -0,0 +1,11 @@
#ifndef PXEPARENT_H
#define PXEPARENT_H
FILE_LICENCE ( GPL2_OR_LATER );
#include <pxe_types.h>
extern int pxeparent_call ( SEGOFF16_t entry, unsigned int function,
void *params, size_t params_len );
#endif

View File

@@ -0,0 +1,139 @@
#ifndef REALMODE_H
#define REALMODE_H
#include <stdint.h>
#include <registers.h>
#include <ipxe/uaccess.h>
/*
* Data structures and type definitions
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/*
* Declaration of variables in .data16
*
* To place a variable in the .data16 segment, declare it using the
* pattern:
*
* int __data16 ( foo );
* #define foo __use_data16 ( foo );
*
* extern uint32_t __data16 ( bar );
* #define bar __use_data16 ( bar );
*
* static long __data16 ( baz ) = 0xff000000UL;
* #define baz __use_data16 ( baz );
*
* i.e. take a normal declaration, add __data16() around the variable
* name, and add a line saying "#define <name> __use_data16 ( <name> )
*
* You can then access them just like any other variable, for example
*
* int x = foo + bar;
*
* This magic is achieved at a cost of only around 7 extra bytes per
* group of accesses to .data16 variables. When using KEEP_IT_REAL,
* there is no extra cost.
*
* You should place variables in .data16 when they need to be accessed
* by real-mode code. Real-mode assembly (e.g. as created by
* REAL_CODE()) can access these variables via the usual data segment.
* You can therefore write something like
*
* static uint16_t __data16 ( foo );
* #define foo __use_data16 ( foo )
*
* int bar ( void ) {
* __asm__ __volatile__ ( REAL_CODE ( "int $0xff\n\t"
* "movw %ax, foo" )
* : : );
* return foo;
* }
*
* Variables may also be placed in .text16 using __text16 and
* __use_text16. Some variables (e.g. chained interrupt vectors) fit
* most naturally in .text16; most should be in .data16.
*
* If you have only a pointer to a magic symbol within .data16 or
* .text16, rather than the symbol itself, you can attempt to extract
* the underlying symbol name using __from_data16() or
* __from_text16(). This is not for the faint-hearted; check the
* assembler output to make sure that it's doing the right thing.
*/
/**
* Convert segment:offset address to user buffer
*
* @v segment Real-mode segment
* @v offset Real-mode offset
* @ret buffer User buffer
*/
static inline __always_inline userptr_t
real_to_user ( unsigned int segment, unsigned int offset ) {
return ( phys_to_user ( ( segment << 4 ) + offset ) );
}
/**
* Copy data to base memory
*
* @v dest_seg Destination segment
* @v dest_off Destination offset
* @v src Source
* @v len Length
*/
static inline __always_inline void
copy_to_real ( unsigned int dest_seg, unsigned int dest_off,
void *src, size_t n ) {
copy_to_user ( real_to_user ( dest_seg, dest_off ), 0, src, n );
}
/**
* Copy data to base memory
*
* @v dest Destination
* @v src_seg Source segment
* @v src_off Source offset
* @v len Length
*/
static inline __always_inline void
copy_from_real ( void *dest, unsigned int src_seg,
unsigned int src_off, size_t n ) {
copy_from_user ( dest, real_to_user ( src_seg, src_off ), 0, n );
}
/**
* Write a single variable to base memory
*
* @v var Variable to write
* @v dest_seg Destination segment
* @v dest_off Destination offset
*/
#define put_real( var, dest_seg, dest_off ) \
copy_to_real ( (dest_seg), (dest_off), &(var), sizeof (var) )
/**
* Read a single variable from base memory
*
* @v var Variable to read
* @v src_seg Source segment
* @v src_off Source offset
*/
#define get_real( var, src_seg, src_off ) \
copy_from_real ( &(var), (src_seg), (src_off), sizeof (var) )
/*
* REAL_CODE ( asm_code_str )
*
* This can be used in inline assembly to create a fragment of code
* that will execute in real mode. For example: to write a character
* to the BIOS console using INT 10, you would do something like:
*
* __asm__ __volatile__ ( REAL_CODE ( "int $0x16" )
* : "=a" ( character ) : "a" ( 0x0000 ) );
*
*/
#endif /* REALMODE_H */

View File

@@ -0,0 +1,198 @@
#ifndef REGISTERS_H
#define REGISTERS_H
/** @file
*
* i386 registers.
*
* This file defines data structures that allow easy access to i386
* register dumps.
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
/**
* A 16-bit general register.
*
* This type encapsulates a 16-bit register such as %ax, %bx, %cx,
* %dx, %si, %di, %bp or %sp.
*
*/
typedef union {
struct {
union {
uint8_t l;
uint8_t byte;
};
uint8_t h;
} __attribute__ (( packed ));
uint16_t word;
} __attribute__ (( packed )) reg16_t;
/**
* A 32-bit general register.
*
* This type encapsulates a 32-bit register such as %eax, %ebx, %ecx,
* %edx, %esi, %edi, %ebp or %esp.
*
*/
typedef union {
struct {
union {
uint8_t l;
uint8_t byte;
};
uint8_t h;
} __attribute__ (( packed ));
uint16_t word;
uint32_t dword;
} __attribute__ (( packed )) reg32_t;
/**
* A 32-bit general register dump.
*
* This is the data structure that is created on the stack by the @c
* pushal instruction, and can be read back using the @c popal
* instruction.
*
*/
struct i386_regs {
union {
uint16_t di;
uint32_t edi;
};
union {
uint16_t si;
uint32_t esi;
};
union {
uint16_t bp;
uint32_t ebp;
};
union {
uint16_t sp;
uint32_t esp;
};
union {
struct {
uint8_t bl;
uint8_t bh;
} __attribute__ (( packed ));
uint16_t bx;
uint32_t ebx;
};
union {
struct {
uint8_t dl;
uint8_t dh;
} __attribute__ (( packed ));
uint16_t dx;
uint32_t edx;
};
union {
struct {
uint8_t cl;
uint8_t ch;
} __attribute__ (( packed ));
uint16_t cx;
uint32_t ecx;
};
union {
struct {
uint8_t al;
uint8_t ah;
} __attribute__ (( packed ));
uint16_t ax;
uint32_t eax;
};
} __attribute__ (( packed ));
/**
* A segment register dump.
*
* The i386 has no equivalent of the @c pushal or @c popal
* instructions for the segment registers. We adopt the convention of
* always using the sequences
*
* @code
*
* pushw %gs ; pushw %fs ; pushw %es ; pushw %ds ; pushw %ss ; pushw %cs
*
* @endcode
*
* and
*
* @code
*
* addw $4, %sp ; popw %ds ; popw %es ; popw %fs ; popw %gs
*
* @endcode
*
* This is the data structure that is created and read back by these
* instruction sequences.
*
*/
struct i386_seg_regs {
uint16_t cs;
uint16_t ss;
uint16_t ds;
uint16_t es;
uint16_t fs;
uint16_t gs;
} __attribute__ (( packed ));
/**
* A full register dump.
*
* This data structure is created by the instructions
*
* @code
*
* pushfl
* pushal
* pushw %gs ; pushw %fs ; pushw %es ; pushw %ds ; pushw %ss ; pushw %cs
*
* @endcode
*
* and can be read back using the instructions
*
* @code
*
* addw $4, %sp ; popw %ds ; popw %es ; popw %fs ; popw %gs
* popal
* popfl
*
* @endcode
*
* prot_call() and kir_call() create this data structure on the stack
* and pass in a pointer to this structure.
*
*/
struct i386_all_regs {
struct i386_seg_regs segs;
struct i386_regs regs;
uint32_t flags;
} __attribute__ (( packed ));
/* Flags */
#define CF ( 1 << 0 )
#define PF ( 1 << 2 )
#define AF ( 1 << 4 )
#define ZF ( 1 << 6 )
#define SF ( 1 << 7 )
#define OF ( 1 << 11 )
/* Segment:offset structure. Note that the order within the structure
* is offset:segment.
*/
struct segoff {
uint16_t offset;
uint16_t segment;
} __attribute__ (( packed ));
typedef struct segoff segoff_t;
#endif /* REGISTERS_H */

View File

@@ -0,0 +1,28 @@
#ifndef _RMSETJMP_H
#define _RMSETJMP_H
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <setjmp.h>
#include <realmode.h>
/** A real-mode-extended jump buffer */
typedef struct {
/** Jump buffer */
jmp_buf env;
/** Real-mode stack pointer */
segoff_t rm_stack;
} rmjmp_buf[1];
#define rmsetjmp( _env ) ( { \
(_env)->rm_stack.segment = rm_ss; \
(_env)->rm_stack.offset = rm_sp; \
setjmp ( (_env)->env ); } ) \
#define rmlongjmp( _env, _val ) do { \
rm_ss = (_env)->rm_stack.segment; \
rm_sp = (_env)->rm_stack.offset; \
longjmp ( (_env)->env, (_val) ); \
} while ( 0 )
#endif /* _RMSETJMP_H */

View File

@@ -0,0 +1,83 @@
#ifndef _RTC_H
#define _RTC_H
/** @file
*
* CMOS Real-Time Clock (RTC)
*
* The CMOS/RTC registers are documented (with varying degrees of
* accuracy and consistency) at
*
* http://www.nondot.org/sabre/os/files/MiscHW/RealtimeClockFAQ.txt
* http://wiki.osdev.org/RTC
* http://wiki.osdev.org/CMOS
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <pic8259.h>
/** RTC IRQ */
#define RTC_IRQ 8
/** RTC interrupt vector */
#define RTC_INT IRQ_INT ( RTC_IRQ )
/** CMOS/RTC address (and NMI) register */
#define CMOS_ADDRESS 0x70
/** NMI disable bit */
#define CMOS_DISABLE_NMI 0x80
/** CMOS/RTC data register */
#define CMOS_DATA 0x71
/** RTC seconds */
#define RTC_SEC 0x00
/** RTC minutes */
#define RTC_MIN 0x02
/** RTC hours */
#define RTC_HOUR 0x04
/** RTC weekday */
#define RTC_WDAY 0x06
/** RTC day of month */
#define RTC_MDAY 0x07
/** RTC month */
#define RTC_MON 0x08
/** RTC year */
#define RTC_YEAR 0x09
/** RTC status register A */
#define RTC_STATUS_A 0x0a
/** RTC update in progress bit */
#define RTC_STATUS_A_UPDATE_IN_PROGRESS 0x80
/** RTC status register B */
#define RTC_STATUS_B 0x0b
/** RTC 24 hour format bit */
#define RTC_STATUS_B_24_HOUR 0x02
/** RTC binary mode bit */
#define RTC_STATUS_B_BINARY 0x04
/** RTC Periodic Interrupt Enabled bit */
#define RTC_STATUS_B_PIE 0x40
/** RTC status register C */
#define RTC_STATUS_C 0x0c
/** RTC status register D */
#define RTC_STATUS_D 0x0d
/** CMOS default address */
#define CMOS_DEFAULT_ADDRESS RTC_STATUS_D
#endif /* _RTC_H */

View File

@@ -0,0 +1,39 @@
#ifndef _SDI_H
#define _SDI_H
/** @file
*
* System Deployment Image (SDI)
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/** SDI image header */
struct sdi_header {
/** Signature */
uint32_t magic;
/** Version (as an ASCII string) */
uint32_t version;
/** Reserved */
uint8_t reserved[8];
/** Boot code offset */
uint64_t boot_offset;
/** Boot code size */
uint64_t boot_size;
} __attribute__ (( packed ));
/** SDI image signature */
#define SDI_MAGIC \
( ( '$' << 0 ) | ( 'S' << 8 ) | ( 'D' << 16 ) | ( 'I' << 24 ) )
/** SDI boot segment */
#define SDI_BOOT_SEG 0x0000
/** SDI boot offset */
#define SDI_BOOT_OFF 0x7c00
/** Constant to binary-OR with physical address of SDI image */
#define SDI_WTF 0x41
#endif /* _SDI_H */

106
src/arch/x86/include/undi.h Normal file
View File

@@ -0,0 +1,106 @@
#ifndef _UNDI_H
#define _UNDI_H
/** @file
*
* UNDI driver
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifndef ASSEMBLY
#include <ipxe/device.h>
#include <pxe_types.h>
/** An UNDI device
*
* This structure is used by assembly code as well as C; do not alter
* this structure without editing pxeprefix.S to match.
*/
struct undi_device {
/** PXENV+ structure address */
SEGOFF16_t pxenv;
/** !PXE structure address */
SEGOFF16_t ppxe;
/** Entry point */
SEGOFF16_t entry;
/** Free base memory after load */
UINT16_t fbms;
/** Free base memory prior to load */
UINT16_t restore_fbms;
/** PCI bus:dev.fn, or @c UNDI_NO_PCI_BUSDEVFN */
UINT16_t pci_busdevfn;
/** ISAPnP card select number, or @c UNDI_NO_ISAPNP_CSN */
UINT16_t isapnp_csn;
/** ISAPnP read port, or @c UNDI_NO_ISAPNP_READ_PORT */
UINT16_t isapnp_read_port;
/** PCI vendor ID
*
* Filled in only for the preloaded UNDI device by pxeprefix.S
*/
UINT16_t pci_vendor;
/** PCI device ID
*
* Filled in only for the preloaded UNDI device by pxeprefix.S
*/
UINT16_t pci_device;
/** Flags
*
* This is the bitwise OR of zero or more UNDI_FL_XXX
* constants.
*/
UINT16_t flags;
/** Generic device */
struct device dev;
/** Driver-private data
*
* Use undi_set_drvdata() and undi_get_drvdata() to access this
* field.
*/
void *priv;
} __attribute__ (( packed ));
/**
* Set UNDI driver-private data
*
* @v undi UNDI device
* @v priv Private data
*/
static inline void undi_set_drvdata ( struct undi_device *undi, void *priv ) {
undi->priv = priv;
}
/**
* Get UNDI driver-private data
*
* @v undi UNDI device
* @ret priv Private data
*/
static inline void * undi_get_drvdata ( struct undi_device *undi ) {
return undi->priv;
}
#endif /* ASSEMBLY */
/** PCI bus:dev.fn field is invalid */
#define UNDI_NO_PCI_BUSDEVFN 0xffff
/** ISAPnP card select number field is invalid */
#define UNDI_NO_ISAPNP_CSN 0xffff
/** ISAPnP read port field is invalid */
#define UNDI_NO_ISAPNP_READ_PORT 0xffff
/** UNDI flag: START_UNDI has been called */
#define UNDI_FL_STARTED 0x0001
/** UNDI flag: UNDI_STARTUP and UNDI_INITIALIZE have been called */
#define UNDI_FL_INITIALIZED 0x0002
/** UNDI flag: keep stack resident */
#define UNDI_FL_KEEP_ALL 0x0004
#endif /* _UNDI_H */

View File

@@ -0,0 +1,35 @@
#ifndef _UNDILOAD_H
#define _UNDILOAD_H
/** @file
*
* UNDI load/unload
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct undi_device;
struct undi_rom;
extern int undi_load ( struct undi_device *undi, struct undi_rom *undirom );
extern int undi_unload ( struct undi_device *undi );
/**
* Call UNDI loader to create a pixie
*
* @v undi UNDI device
* @v undirom UNDI ROM
* @v pci_busdevfn PCI bus:dev.fn
* @ret rc Return status code
*/
static inline int undi_load_pci ( struct undi_device *undi,
struct undi_rom *undirom,
unsigned int pci_busdevfn ) {
undi->pci_busdevfn = pci_busdevfn;
undi->isapnp_csn = UNDI_NO_ISAPNP_CSN;
undi->isapnp_read_port = UNDI_NO_ISAPNP_READ_PORT;
return undi_load ( undi, undirom );
}
#endif /* _UNDILOAD_H */

View File

@@ -0,0 +1,17 @@
#ifndef _UNDINET_H
#define _UNDINET_H
/** @file
*
* UNDI network device driver
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
struct undi_device;
extern int undinet_probe ( struct undi_device *undi );
extern void undinet_remove ( struct undi_device *undi );
#endif /* _UNDINET_H */

View File

@@ -0,0 +1,18 @@
#ifndef _UNDIPRELOAD_H
#define _UNDIPRELOAD_H
/** @file
*
* Preloaded UNDI stack
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <realmode.h>
#include <undi.h>
extern struct undi_device __data16 ( preloaded_undi );
#define preloaded_undi __use_data16 ( preloaded_undi )
#endif /* _UNDIPRELOAD_H */

View File

@@ -0,0 +1,53 @@
#ifndef _UNDIROM_H
#define _UNDIROM_H
/** @file
*
* UNDI expansion ROMs
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <pxe_types.h>
/** An UNDI PCI device ID */
struct undi_pci_device_id {
/** PCI vendor ID */
unsigned int vendor_id;
/** PCI device ID */
unsigned int device_id;
};
/** An UNDI device ID */
union undi_device_id {
/** PCI device ID */
struct undi_pci_device_id pci;
};
/** An UNDI ROM */
struct undi_rom {
/** List of UNDI ROMs */
struct list_head list;
/** ROM segment address */
unsigned int rom_segment;
/** UNDI loader entry point */
SEGOFF16_t loader_entry;
/** Code segment size */
size_t code_size;
/** Data segment size */
size_t data_size;
/** Bus type
*
* Values are as used by @c PXENV_UNDI_GET_NIC_TYPE
*/
unsigned int bus_type;
/** Device ID */
union undi_device_id bus_id;
};
extern struct undi_rom * undirom_find_pci ( unsigned int vendor_id,
unsigned int device_id,
unsigned int rombase );
#endif /* _UNDIROM_H */

228
src/arch/x86/include/vga.h Normal file
View File

@@ -0,0 +1,228 @@
/*
*
* modified
* by Steve M. Gehlbach <steve@kesa.com>
*
* Originally from linux/drivers/video/vga16.c by
* Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz>
* Copyright 1999 Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz>
* Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm
* Based on VESA framebuffer (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
*
*/
#ifndef VGA_H_INCL
#define VGA_H_INCL 1
//#include <cpu/p5/io.h>
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned int
#define __u32 u32
#define VERROR -1
#define CHAR_HEIGHT 16
#define LINES 25
#define COLS 80
// macros for writing to vga regs
#define write_crtc(data,addr) outb(addr,CRT_IC); outb(data,CRT_DC)
#define write_att(data,addr) inb(IS1_RC); inb(0x80); outb(addr,ATT_IW); inb(0x80); outb(data,ATT_IW); inb(0x80)
#define write_seq(data,addr) outb(addr,SEQ_I); outb(data,SEQ_D)
#define write_gra(data,addr) outb(addr,GRA_I); outb(data,GRA_D)
u8 read_seq_b(u16 addr);
u8 read_gra_b(u16 addr);
u8 read_crtc_b(u16 addr);
u8 read_att_b(u16 addr);
#ifdef VGA_HARDWARE_FIXUP
void vga_hardware_fixup(void);
#else
#define vga_hardware_fixup() do{} while(0)
#endif
#define SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */
#define SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */
#define SYNC_EXT 4 /* external sync */
#define SYNC_COMP_HIGH_ACT 8 /* composite sync high active */
#define SYNC_BROADCAST 16 /* broadcast video timings */
/* vtotal = 144d/288n/576i => PAL */
/* vtotal = 121d/242n/484i => NTSC */
#define SYNC_ON_GREEN 32 /* sync on green */
#define VMODE_NONINTERLACED 0 /* non interlaced */
#define VMODE_INTERLACED 1 /* interlaced */
#define VMODE_DOUBLE 2 /* double scan */
#define VMODE_MASK 255
#define VMODE_YWRAP 256 /* ywrap instead of panning */
#define VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
#define VMODE_CONUPDATE 512 /* don't update x/yoffset */
/* VGA data register ports */
#define CRT_DC 0x3D5 /* CRT Controller Data Register - color emulation */
#define CRT_DM 0x3B5 /* CRT Controller Data Register - mono emulation */
#define ATT_R 0x3C1 /* Attribute Controller Data Read Register */
#define GRA_D 0x3CF /* Graphics Controller Data Register */
#define SEQ_D 0x3C5 /* Sequencer Data Register */
#define MIS_R 0x3CC // Misc Output Read Register
#define MIS_W 0x3C2 // Misc Output Write Register
#define IS1_RC 0x3DA /* Input Status Register 1 - color emulation */
#define IS1_RM 0x3BA /* Input Status Register 1 - mono emulation */
#define PEL_D 0x3C9 /* PEL Data Register */
#define PEL_MSK 0x3C6 /* PEL mask register */
/* EGA-specific registers */
#define GRA_E0 0x3CC /* Graphics enable processor 0 */
#define GRA_E1 0x3CA /* Graphics enable processor 1 */
/* VGA index register ports */
#define CRT_IC 0x3D4 /* CRT Controller Index - color emulation */
#define CRT_IM 0x3B4 /* CRT Controller Index - mono emulation */
#define ATT_IW 0x3C0 /* Attribute Controller Index & Data Write Register */
#define GRA_I 0x3CE /* Graphics Controller Index */
#define SEQ_I 0x3C4 /* Sequencer Index */
#define PEL_IW 0x3C8 /* PEL Write Index */
#define PEL_IR 0x3C7 /* PEL Read Index */
/* standard VGA indexes max counts */
#define CRTC_C 25 /* 25 CRT Controller Registers sequentially set*/
// the remainder are not in the par array
#define ATT_C 21 /* 21 Attribute Controller Registers */
#define GRA_C 9 /* 9 Graphics Controller Registers */
#define SEQ_C 5 /* 5 Sequencer Registers */
#define MIS_C 1 /* 1 Misc Output Register */
#define CRTC_H_TOTAL 0
#define CRTC_H_DISP 1
#define CRTC_H_BLANK_START 2
#define CRTC_H_BLANK_END 3
#define CRTC_H_SYNC_START 4
#define CRTC_H_SYNC_END 5
#define CRTC_V_TOTAL 6
#define CRTC_OVERFLOW 7
#define CRTC_PRESET_ROW 8
#define CRTC_MAX_SCAN 9
#define CRTC_CURSOR_START 0x0A
#define CRTC_CURSOR_END 0x0B
#define CRTC_START_HI 0x0C
#define CRTC_START_LO 0x0D
#define CRTC_CURSOR_HI 0x0E
#define CRTC_CURSOR_LO 0x0F
#define CRTC_V_SYNC_START 0x10
#define CRTC_V_SYNC_END 0x11
#define CRTC_V_DISP_END 0x12
#define CRTC_OFFSET 0x13
#define CRTC_UNDERLINE 0x14
#define CRTC_V_BLANK_START 0x15
#define CRTC_V_BLANK_END 0x16
#define CRTC_MODE 0x17
#define CRTC_LINE_COMPARE 0x18
#define ATC_MODE 0x10
#define ATC_OVERSCAN 0x11
#define ATC_PLANE_ENABLE 0x12
#define ATC_PEL 0x13
#define ATC_COLOR_PAGE 0x14
#define SEQ_CLOCK_MODE 0x01
#define SEQ_PLANE_WRITE 0x02
#define SEQ_CHARACTER_MAP 0x03
#define SEQ_MEMORY_MODE 0x04
#define GDC_SR_VALUE 0x00
#define GDC_SR_ENABLE 0x01
#define GDC_COMPARE_VALUE 0x02
#define GDC_DATA_ROTATE 0x03
#define GDC_PLANE_READ 0x04
#define GDC_MODE 0x05
#define GDC_MISC 0x06
#define GDC_COMPARE_MASK 0x07
#define GDC_BIT_MASK 0x08
// text attributes
#define VGA_ATTR_CLR_RED 0x4
#define VGA_ATTR_CLR_GRN 0x2
#define VGA_ATTR_CLR_BLU 0x1
#define VGA_ATTR_CLR_YEL (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN)
#define VGA_ATTR_CLR_CYN (VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU)
#define VGA_ATTR_CLR_MAG (VGA_ATTR_CLR_BLU | VGA_ATTR_CLR_RED)
#define VGA_ATTR_CLR_BLK 0
#define VGA_ATTR_CLR_WHT (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU)
#define VGA_ATTR_BNK 0x80
#define VGA_ATTR_ITN 0x08
/*
* vga register parameters
* these are copied to the
* registers.
*
*/
struct vga_par {
u8 crtc[CRTC_C];
u8 atc[ATT_C];
u8 gdc[GRA_C];
u8 seq[SEQ_C];
u8 misc; // the misc register, MIS_W
u8 vss;
};
/* Interpretation of offset for color fields: All offsets are from the right,
* inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
* can use the offset as right argument to <<). A pixel afterwards is a bit
* stream and is written to video memory as that unmodified. This implies
* big-endian byte order if bits_per_pixel is greater than 8.
*/
struct fb_bitfield {
__u32 offset; /* beginning of bitfield */
__u32 length; /* length of bitfield */
__u32 msb_right; /* != 0 : Most significant bit is */
/* right */
};
struct screeninfo {
__u32 xres; /* visible resolution */
__u32 yres;
__u32 xres_virtual; /* virtual resolution */
__u32 yres_virtual;
__u32 xoffset; /* offset from virtual to visible */
__u32 yoffset; /* resolution */
__u32 bits_per_pixel; /* guess what */
__u32 grayscale; /* != 0 Graylevels instead of colors */
struct fb_bitfield red; /* bitfield in fb mem if true color, */
struct fb_bitfield green; /* else only length is significant */
struct fb_bitfield blue;
struct fb_bitfield transp; /* transparency */
__u32 nonstd; /* != 0 Non standard pixel format */
__u32 activate; /* see FB_ACTIVATE_* */
__u32 height; /* height of picture in mm */
__u32 width; /* width of picture in mm */
__u32 accel_flags; /* acceleration flags (hints) */
/* Timing: All values in pixclocks, except pixclock (of course) */
__u32 pixclock; /* pixel clock in ps (pico seconds) */
__u32 left_margin; /* time from sync to picture */
__u32 right_margin; /* time from picture to sync */
__u32 upper_margin; /* time from sync to picture */
__u32 lower_margin;
__u32 hsync_len; /* length of horizontal sync */
__u32 vsync_len; /* length of vertical sync */
__u32 sync; /* sync polarity */
__u32 vmode; /* interlaced etc */
__u32 reserved[6]; /* Reserved for future compatibility */
};
#endif