diff options
Diffstat (limited to 'roms/qboot/include')
-rw-r--r-- | roms/qboot/include/assembly.h | 26 | ||||
-rw-r--r-- | roms/qboot/include/bios.h | 92 | ||||
-rw-r--r-- | roms/qboot/include/bswap.h | 34 | ||||
-rw-r--r-- | roms/qboot/include/const.h | 27 | ||||
-rw-r--r-- | roms/qboot/include/e820.h | 44 | ||||
-rw-r--r-- | roms/qboot/include/fw_cfg.h | 120 | ||||
-rw-r--r-- | roms/qboot/include/ioport.h | 50 | ||||
-rw-r--r-- | roms/qboot/include/linuxboot.h | 19 | ||||
-rw-r--r-- | roms/qboot/include/memaccess.h | 30 | ||||
-rw-r--r-- | roms/qboot/include/mpspec_def.h | 182 | ||||
-rw-r--r-- | roms/qboot/include/multiboot.h | 66 | ||||
-rw-r--r-- | roms/qboot/include/pci.h | 78 | ||||
-rw-r--r-- | roms/qboot/include/processor-flags.h | 153 | ||||
-rw-r--r-- | roms/qboot/include/segment.h | 19 | ||||
-rw-r--r-- | roms/qboot/include/smbios.h | 1 | ||||
-rw-r--r-- | roms/qboot/include/start_info.h | 146 | ||||
-rw-r--r-- | roms/qboot/include/stdio.h | 11 | ||||
-rw-r--r-- | roms/qboot/include/stdlib.h | 6 | ||||
-rw-r--r-- | roms/qboot/include/string.h | 40 |
19 files changed, 1144 insertions, 0 deletions
diff --git a/roms/qboot/include/assembly.h b/roms/qboot/include/assembly.h new file mode 100644 index 000000000..dce958d7a --- /dev/null +++ b/roms/qboot/include/assembly.h @@ -0,0 +1,26 @@ +#ifndef ASSEMBLY_H_ +#define ASSEMBLY_H_ + +#define __ASSEMBLY__ + +#define __ALIGN .p2align 4, 0x90 +#define ENTRY(name) \ + __ALIGN; \ + .globl name; \ + name: + +#define GLOBAL(name) \ + .globl name; \ + name: + +#define ENTRY_END(name) GLOBAL(name##_end) +#define END(name) GLOBAL(name##_end) + +/* + * gas produces size override prefix with which + * we are unhappy, lets make it hardcoded for + * 16 bit mode + */ +#define IRET .byte 0xcf + +#endif /* ASSEMBLY_H_ */ diff --git a/roms/qboot/include/bios.h b/roms/qboot/include/bios.h new file mode 100644 index 000000000..7f8f67767 --- /dev/null +++ b/roms/qboot/include/bios.h @@ -0,0 +1,92 @@ +#ifndef BIOS_H_ +#define BIOS_H_ + +#include <stdint.h> +#include <stddef.h> +#include <stdbool.h> + +/* + * When interfacing with assembler code we need to be sure how + * arguments are passed in real mode. + */ +#define bioscall __attribute__((regparm(3))) + +#ifndef __ASSEMBLER__ + +struct biosregs { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t ds; + uint32_t es; + uint32_t fs; + uint16_t ip; + uint16_t cs; + uint16_t eflags; +} __attribute__((packed)); + +/* + * BIOS32 is called via a far call, so eflags is pushed by our + * entry point and lies below CS:EIP. We do not include CS:EIP + * at all in this struct. + */ +struct bios32regs { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + uint32_t ds; + uint32_t es; + uint32_t fs; + uint32_t eflags; +} __attribute__((packed)); + +extern bioscall void int10_handler(struct biosregs *regs); +extern bioscall void int15_handler(struct biosregs *regs); +extern bioscall void e820_query_map(struct biosregs *regs); +extern bioscall void pcibios_handler(struct bios32regs *regs); + +extern void bios_intfake(void); +extern void bios_irq(void); +extern void bios_int10(void); +extern void bios_int15(void); +extern void bios32_entry(void); + +extern uint32_t pic_base(void); + +extern void setup_pci(void); +extern bool setup_hw(void); +extern bool setup_mmconfig(void); +extern void setup_mptable(void); +extern void extract_acpi(void); +extern void boot_from_fwcfg(void); + +extern uint8_t max_bus; +extern uint16_t e820_seg; +extern uint32_t lowmem; + +extern uint8_t stext; +extern uint8_t edata; +extern uint8_t sinit; +extern uint8_t einit; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + +static inline void __attribute__((noreturn)) panic(void) +{ + asm volatile("cli; hlt"); + for(;;); +} + +#endif + +#endif /* BIOS_H_ */ diff --git a/roms/qboot/include/bswap.h b/roms/qboot/include/bswap.h new file mode 100644 index 000000000..67b3c4f71 --- /dev/null +++ b/roms/qboot/include/bswap.h @@ -0,0 +1,34 @@ +#ifndef BSWAP_H +#define BSWAP_H 1 + +static inline uint16_t bswap16(uint16_t x) +{ + return __builtin_bswap16(x); +} + +static inline uint32_t bswap32(uint32_t x) +{ + return __builtin_bswap32(x); +} + +static inline uint64_t bswap64(uint64_t x) +{ + return __builtin_bswap64(x); +} + +static inline uint32_t ldl_le_p(const void *p) +{ + uint32_t val; + memcpy(&val, p, 4); + return val; +} + +static inline uint32_t ldl_be_p(const void *p) +{ + uint32_t val; + memcpy(&val, p, 4); + return bswap32(val); +} + + +#endif diff --git a/roms/qboot/include/const.h b/roms/qboot/include/const.h new file mode 100644 index 000000000..18f2350a2 --- /dev/null +++ b/roms/qboot/include/const.h @@ -0,0 +1,27 @@ +/* const.h: Macros for dealing with constants. */ + +#ifndef BIOS_CONST_H +#define BIOS_CONST_H + +/* Some constant macros are used in both assembler and + * C code. Therefore we cannot annotate them always with + * 'UL' and other type specifiers unilaterally. We + * use the following macros to deal with this. + * + * Similarly, _AT() will cast an expression with a type in C, but + * leave it unchanged in asm. + */ + +#ifdef __ASSEMBLY__ +#define _AC(X,Y) X +#define _AT(T,X) X +#else +#define __AC(X,Y) (X##Y) +#define _AC(X,Y) __AC(X,Y) +#define _AT(T,X) ((T)(X)) +#endif + +#define BITUL(x) (_AC(1,UL) << (x)) +#define BITULL(x) (_AC(1,ULL) << (x)) + +#endif /* BIOS_CONST_H */ diff --git a/roms/qboot/include/e820.h b/roms/qboot/include/e820.h new file mode 100644 index 000000000..09b8f0138 --- /dev/null +++ b/roms/qboot/include/e820.h @@ -0,0 +1,44 @@ +#ifndef BIOS_E820_H +#define BIOS_E820_H + +#define SMAP 0x534d4150 /* ASCII "SMAP" */ + +#define E820_RAM 1 +#define E820_RESERVED 2 +#define E820_ACPI 3 +#define E820_NVS 4 +#define E820_UNUSABLE 5 + + +/* + * reserved RAM used by kernel itself + * if CONFIG_INTEL_TXT is enabled, memory of this type will be + * included in the S3 integrity calculation and so should not include + * any memory that BIOS might alter over the S3 transition + */ +#define E820_RESERVED_KERN 128 + +struct e820entry { + uint64_t addr; /* start of memory segment */ + uint64_t size; /* size of memory segment */ + uint32_t type; /* type of memory segment */ +} __attribute__((packed)); + +struct e820map { + uint32_t nr_map; + struct e820entry map[]; +}; + +extern struct e820map *e820; + +#define ISA_START_ADDRESS 0xa0000 +#define ISA_END_ADDRESS 0x100000 + +#define BIOS_BEGIN 0x000a0000 +#define BIOS_END 0x00100000 + +#define BIOS_ROM_BASE 0xffe00000 +#define BIOS_ROM_END 0xffffffff + + +#endif /* BIOS_E820_H */ diff --git a/roms/qboot/include/fw_cfg.h b/roms/qboot/include/fw_cfg.h new file mode 100644 index 000000000..1ddfc1f7e --- /dev/null +++ b/roms/qboot/include/fw_cfg.h @@ -0,0 +1,120 @@ +#ifndef BIOS_FW_CFG_H +#define BIOS_FW_CFG_H 1 + +// List of QEMU fw_cfg entries. DO NOT ADD MORE. (All new content +// should be passed via the fw_cfg "file" interface.) +#define FW_CFG_SIGNATURE 0x00 +#define FW_CFG_ID 0x01 +#define FW_CFG_UUID 0x02 +#define FW_CFG_RAM_SIZE 0x03 +#define FW_CFG_NOGRAPHIC 0x04 +#define FW_CFG_NB_CPUS 0x05 +#define FW_CFG_MACHINE_ID 0x06 +#define FW_CFG_KERNEL_ADDR 0x07 +#define FW_CFG_KERNEL_SIZE 0x08 +#define FW_CFG_KERNEL_CMDLINE 0x09 +#define FW_CFG_INITRD_ADDR 0x0a +#define FW_CFG_INITRD_SIZE 0x0b +#define FW_CFG_BOOT_DEVICE 0x0c +#define FW_CFG_NUMA 0x0d +#define FW_CFG_BOOT_MENU 0x0e +#define FW_CFG_MAX_CPUS 0x0f +#define FW_CFG_KERNEL_ENTRY 0x10 +#define FW_CFG_KERNEL_DATA 0x11 +#define FW_CFG_INITRD_DATA 0x12 +#define FW_CFG_CMDLINE_ADDR 0x13 +#define FW_CFG_CMDLINE_SIZE 0x14 +#define FW_CFG_CMDLINE_DATA 0x15 +#define FW_CFG_SETUP_ADDR 0x16 +#define FW_CFG_SETUP_SIZE 0x17 +#define FW_CFG_SETUP_DATA 0x18 +#define FW_CFG_FILE_DIR 0x19 +#define FW_CFG_FILE_FIRST 0x20 +#define FW_CFG_ARCH_LOCAL 0x8000 +#define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0) +#define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1) +#define FW_CFG_IRQ0_OVERRIDE (FW_CFG_ARCH_LOCAL + 2) +#define FW_CFG_E820_TABLE (FW_CFG_ARCH_LOCAL + 3) + +#define FW_CFG_VERSION 0x01 +#define FW_CFG_VERSION_DMA 0x02 + +#define FW_CFG_DMA_CTL_ERROR 0x01 +#define FW_CFG_DMA_CTL_READ 0x02 +#define FW_CFG_DMA_CTL_SKIP 0x04 +#define FW_CFG_DMA_CTL_SELECT 0x08 + +#define FW_CFG_CTL 0x510 +#define FW_CFG_DATA 0x511 +#define FW_CFG_DMA_ADDR_HIGH 0x514 +#define FW_CFG_DMA_ADDR_LOW 0x518 + +#include "ioport.h" + +static inline void fw_cfg_select(uint16_t f) +{ + outw(FW_CFG_CTL, f); +} + +static inline uint32_t fw_cfg_readb(void) +{ + return inb(FW_CFG_DATA); +} + +static inline uint32_t fw_cfg_readw_be(void) +{ + uint32_t val; + + val = inb(FW_CFG_DATA); + val = (val << 8) | inb(FW_CFG_DATA); + return val; +} + +static inline uint32_t fw_cfg_readw_le(void) +{ + uint32_t val; + + val = inb(FW_CFG_DATA); + val = (inb(FW_CFG_DATA) << 8) | val; + return val; +} + +static inline uint32_t fw_cfg_readl_be(void) +{ + uint32_t val; + + val = inb(FW_CFG_DATA); + val = (val << 8) | inb(FW_CFG_DATA); + val = (val << 8) | inb(FW_CFG_DATA); + val = (val << 8) | inb(FW_CFG_DATA); + return val; +} + +static inline uint32_t fw_cfg_readl_le(void) +{ + uint32_t val; + + val = inb(FW_CFG_DATA); + val = (inb(FW_CFG_DATA) << 8) | val; + val = (inb(FW_CFG_DATA) << 16) | val; + val = (inb(FW_CFG_DATA) << 24) | val; + return val; +} + +static inline void fw_cfg_skip(int len) +{ + while (len--) + inb(FW_CFG_DATA); +} + +void fw_cfg_setup(void); +int fw_cfg_file_id(char *name); +uint32_t fw_cfg_file_size(int id); +void fw_cfg_file_select(int id); + +void fw_cfg_read(void *buf, int len); +void fw_cfg_read_entry(int e, void *buf, int len); +void fw_cfg_dma(int control, void *buf, int len); +void fw_cfg_read_file(int e, void *buf, int len); + +#endif diff --git a/roms/qboot/include/ioport.h b/roms/qboot/include/ioport.h new file mode 100644 index 000000000..08a8dbd9b --- /dev/null +++ b/roms/qboot/include/ioport.h @@ -0,0 +1,50 @@ +#ifndef BIOS_IOPORT_H +#define BIOS_IOPORT_H 1 + +static inline void outsb(unsigned short port, void *buf, int len) +{ + asm volatile("rep outsb %%ds:(%0), %3" : "=S" (buf), "=c" (len) : "m"(buf), "Nd"(port), "0" (buf), "1" (len)); +} + +static inline void insb(void *buf, unsigned short port, int len) +{ + asm volatile("rep insb %3, %%es:(%0)" : "=D" (buf), "=c" (len), "=m"(buf) : "Nd"(port), "0" (buf), "1" (len)); +} + +static inline unsigned char inb(unsigned short port) +{ + unsigned char val; + asm volatile("inb %1, %0" : "=a"(val) : "Nd"(port)); + return val; +} + +static inline unsigned short inw(unsigned short port) +{ + unsigned short val; + asm volatile("inw %1, %0" : "=a"(val) : "Nd"(port)); + return val; +} + +static inline unsigned inl(unsigned short port) +{ + unsigned val; + asm volatile("inl %1, %0" : "=a"(val) : "Nd"(port)); + return val; +} + +static inline void outb(unsigned short port, unsigned char val) +{ + asm volatile("outb %0, %1" : : "a"(val), "Nd"(port)); +} + +static inline void outw(unsigned short port, unsigned short val) +{ + asm volatile("outw %0, %1" : : "a"(val), "Nd"(port)); +} + +static inline void outl(unsigned short port, unsigned val) +{ + asm volatile("outl %0, %1" : : "a"(val), "Nd"(port)); +} + +#endif diff --git a/roms/qboot/include/linuxboot.h b/roms/qboot/include/linuxboot.h new file mode 100644 index 000000000..6e865f0f2 --- /dev/null +++ b/roms/qboot/include/linuxboot.h @@ -0,0 +1,19 @@ +#ifndef BIOS_LINUXBOOT_H +#define BIOS_LINUXBOOT_H 1 + +#include <stdbool.h> + +struct linuxboot_args { + /* Output */ + void *setup_addr, *cmdline_addr, *kernel_addr, *initrd_addr; + uint32_t setup_size, kernel_size; + + /* Input */ + uint32_t cmdline_size, vmlinuz_size, initrd_size; + uint8_t header[8192]; +}; + +bool parse_bzimage(struct linuxboot_args *args); +void boot_bzimage(struct linuxboot_args *args); + +#endif diff --git a/roms/qboot/include/memaccess.h b/roms/qboot/include/memaccess.h new file mode 100644 index 000000000..900b47e63 --- /dev/null +++ b/roms/qboot/include/memaccess.h @@ -0,0 +1,30 @@ +#ifndef MEMACCESS_H_ +#define MEMACCESS_H_ + +#include "string.h" + +static inline uint16_t lduw_p(void *p) +{ + uint16_t val; + memcpy(&val, p, 2); + return val; +} + +static inline uint32_t ldl_p(void *p) +{ + uint32_t val; + memcpy(&val, p, 4); + return val; +} + +static inline void stw_p(void *p, uint16_t val) +{ + memcpy(p, &val, 2); +} + +static inline void stl_p(void *p, uint32_t val) +{ + memcpy(p, &val, 4); +} + +#endif /* MEMACCESS_H_ */ diff --git a/roms/qboot/include/mpspec_def.h b/roms/qboot/include/mpspec_def.h new file mode 100644 index 000000000..6fb923a34 --- /dev/null +++ b/roms/qboot/include/mpspec_def.h @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_X86_MPSPEC_DEF_H +#define _ASM_X86_MPSPEC_DEF_H + +/* + * Structure definitions for SMP machines following the + * Intel Multiprocessing Specification 1.1 and 1.4. + */ + +/* + * This tag identifies where the SMP configuration + * information is. + */ + +#define SMP_MAGIC_IDENT (('_'<<24) | ('P'<<16) | ('M'<<8) | '_') + +#ifdef CONFIG_X86_32 +# define MAX_MPC_ENTRY 1024 +#endif + +/* Intel MP Floating Pointer Structure */ +struct mpf_intel { + char signature[4]; /* "_MP_" */ + unsigned int physptr; /* Configuration table address */ + unsigned char length; /* Our length (paragraphs) */ + unsigned char specification; /* Specification version */ + unsigned char checksum; /* Checksum (makes sum 0) */ + unsigned char feature1; /* Standard or configuration ? */ + unsigned char feature2; /* Bit7 set for IMCR|PIC */ + unsigned char feature3; /* Unused (0) */ + unsigned char feature4; /* Unused (0) */ + unsigned char feature5; /* Unused (0) */ +}; + +#define MPC_SIGNATURE "PCMP" + +struct mpc_table { + char signature[4]; + unsigned short length; /* Size of table */ + char spec; /* 0x01 */ + char checksum; + char oem[8]; + char productid[12]; + unsigned int oemptr; /* 0 if not present */ + unsigned short oemsize; /* 0 if not present */ + unsigned short oemcount; + unsigned int lapic; /* APIC address */ + unsigned int reserved; +}; + +/* Followed by entries */ + +#define MP_PROCESSOR 0 +#define MP_BUS 1 +#define MP_IOAPIC 2 +#define MP_INTSRC 3 +#define MP_LINTSRC 4 +/* Used by IBM NUMA-Q to describe node locality */ +#define MP_TRANSLATION 192 + +#define CPU_ENABLED 1 /* Processor is available */ +#define CPU_BOOTPROCESSOR 2 /* Processor is the boot CPU */ + +#define CPU_STEPPING_MASK 0x000F +#define CPU_MODEL_MASK 0x00F0 +#define CPU_FAMILY_MASK 0x0F00 + +struct mpc_cpu { + unsigned char type; + unsigned char apicid; /* Local APIC number */ + unsigned char apicver; /* Its versions */ + unsigned char cpuflag; + unsigned int cpufeature; + unsigned int featureflag; /* CPUID feature value */ + unsigned int reserved[2]; +}; + +struct mpc_bus { + unsigned char type; + unsigned char busid; + unsigned char bustype[6]; +}; + +/* List of Bus Type string values, Intel MP Spec. */ +#define BUSTYPE_EISA "EISA" +#define BUSTYPE_ISA "ISA" +#define BUSTYPE_INTERN "INTERN" /* Internal BUS */ +#define BUSTYPE_MCA "MCA" /* Obsolete */ +#define BUSTYPE_VL "VL" /* Local bus */ +#define BUSTYPE_PCI "PCI" +#define BUSTYPE_PCMCIA "PCMCIA" +#define BUSTYPE_CBUS "CBUS" +#define BUSTYPE_CBUSII "CBUSII" +#define BUSTYPE_FUTURE "FUTURE" +#define BUSTYPE_MBI "MBI" +#define BUSTYPE_MBII "MBII" +#define BUSTYPE_MPI "MPI" +#define BUSTYPE_MPSA "MPSA" +#define BUSTYPE_NUBUS "NUBUS" +#define BUSTYPE_TC "TC" +#define BUSTYPE_VME "VME" +#define BUSTYPE_XPRESS "XPRESS" + +#define MPC_APIC_USABLE 0x01 + +struct mpc_ioapic { + unsigned char type; + unsigned char apicid; + unsigned char apicver; + unsigned char flags; + unsigned int apicaddr; +}; + +struct mpc_intsrc { + unsigned char type; + unsigned char irqtype; + unsigned short irqflag; + unsigned char srcbus; + unsigned char srcbusirq; + unsigned char dstapic; + unsigned char dstirq; +}; + +enum mp_irq_source_types { + mp_INT = 0, + mp_NMI = 1, + mp_SMI = 2, + mp_ExtINT = 3 +}; + +#define MP_IRQPOL_DEFAULT 0x0 +#define MP_IRQPOL_ACTIVE_HIGH 0x1 +#define MP_IRQPOL_RESERVED 0x2 +#define MP_IRQPOL_ACTIVE_LOW 0x3 +#define MP_IRQPOL_MASK 0x3 + +#define MP_IRQTRIG_DEFAULT 0x0 +#define MP_IRQTRIG_EDGE 0x4 +#define MP_IRQTRIG_RESERVED 0x8 +#define MP_IRQTRIG_LEVEL 0xc +#define MP_IRQTRIG_MASK 0xc + +#define MP_APIC_ALL 0xFF + +struct mpc_lintsrc { + unsigned char type; + unsigned char irqtype; + unsigned short irqflag; + unsigned char srcbusid; + unsigned char srcbusirq; + unsigned char destapic; + unsigned char destapiclint; +}; + +#define MPC_OEM_SIGNATURE "_OEM" + +struct mpc_oemtable { + char signature[4]; + unsigned short length; /* Size of table */ + char rev; /* 0x01 */ + char checksum; + char mpc[8]; +}; + +/* + * Default configurations + * + * 1 2 CPU ISA 82489DX + * 2 2 CPU EISA 82489DX neither IRQ 0 timer nor IRQ 13 DMA chaining + * 3 2 CPU EISA 82489DX + * 4 2 CPU MCA 82489DX + * 5 2 CPU ISA+PCI + * 6 2 CPU EISA+PCI + * 7 2 CPU MCA+PCI + */ + +enum mp_bustype { + MP_BUS_ISA = 1, + MP_BUS_EISA, + MP_BUS_PCI, +}; +#endif /* _ASM_X86_MPSPEC_DEF_H */ diff --git a/roms/qboot/include/multiboot.h b/roms/qboot/include/multiboot.h new file mode 100644 index 000000000..d3d4528f5 --- /dev/null +++ b/roms/qboot/include/multiboot.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013 Kevin Wolf <kwolf@redhat.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MULTIBOOT_H +#define MULTIBOOT_H + +#include <stdint.h> + +struct mb_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; + char syms[16]; + 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)); + +struct mb_module { + uint32_t mod_start; + uint32_t mod_end; + uint32_t string; + uint32_t reserved; +} __attribute__((packed)); + +struct mb_mmap_entry { + uint32_t size; + uint64_t base_addr; + uint64_t length; + uint32_t type; +} __attribute__((packed)); + +#endif diff --git a/roms/qboot/include/pci.h b/roms/qboot/include/pci.h new file mode 100644 index 000000000..7f40f3833 --- /dev/null +++ b/roms/qboot/include/pci.h @@ -0,0 +1,78 @@ +#ifndef BIOS_PCI_H +#define BIOS_PCI_H + +#include "ioport.h" + +static inline void pci_config_writel(uint16_t bdf, uint32_t addr, uint32_t val) +{ + outl(0xcf8, 0x80000000 | (bdf << 8) | (addr & 0xfc)); + outl(0xcfc, val); +} + +static inline void pci_config_writew(uint16_t bdf, uint32_t addr, uint16_t val) +{ + outl(0xcf8, 0x80000000 | (bdf << 8) | (addr & 0xfc)); + outw(0xcfc | (addr & 2), val); +} + +static inline void pci_config_writeb(uint16_t bdf, uint32_t addr, uint8_t val) +{ + outl(0xcf8, 0x80000000 | (bdf << 8) | (addr & 0xfc)); + outb(0xcfc | (addr & 3), val); +} + +static inline uint32_t pci_config_readl(uint16_t bdf, uint32_t addr) +{ + outl(0xcf8, 0x80000000 | (bdf << 8) | (addr & 0xfc)); + return inl(0xcfc); +} + +static inline uint16_t pci_config_readw(uint16_t bdf, uint32_t addr) +{ + outl(0xcf8, 0x80000000 | (bdf << 8) | (addr & 0xfc)); + return inw(0xcfc | (addr & 2)); +} + +static inline uint8_t pci_config_readb(uint16_t bdf, uint32_t addr) +{ + outl(0xcf8, 0x80000000 | (bdf << 8) | (addr & 0xfc)); + return inb(0xcfc | (addr & 3)); +} + +#define PCI_VENDOR_ID 0x00 +#define PCI_DEVICE_ID 0x02 +#define PCI_COMMAND 0x04 +#define PCI_CLASS_DEVICE 0x0a +#define PCI_HEADER_TYPE 0x0e +#define PCI_PRIMARY_BUS 0x18 +#define PCI_SECONDARY_BUS 0x19 +#define PCI_SUBORDINATE_BUS 0x1a +#define PCI_INTERRUPT_LINE 0x3c +#define PCI_INTERRUPT_PIN 0x3d +#define PCI_BRIDGE_CONTROL 0x3e + +/* PCI_COMMAND */ +#define PCI_COMMAND_DIS_INTX 0x400 + +/* PCI_CLASS_DEVICE */ +#define PCI_CLASS_STORAGE_IDE 0x0101 +#define PCI_CLASS_BRIDGE_PCI 0x0604 + +/* PCI_HEADER_TYPE */ +#define PCI_HEADER_TYPE_BRIDGE 1 +#define PCI_HEADER_TYPE_MULTI_FUNCTION 0x80 + +/* PCI_BRIDGE_CONTROL */ +#define PCI_BRIDGE_CTL_SERR 0x02 + +/* PCI_VENDOR_ID / PCI_DEVICE_ID */ +#define PCI_VENDOR_ID_INTEL 0x8086 +#define PCI_DEVICE_ID_INTEL_82441 0x1237 +#define PCI_DEVICE_ID_INTEL_Q35_MCH 0x29c0 +#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 +#define PCI_DEVICE_ID_INTEL_82371AB 0x7111 + +#define PCIE_MMCONFIG_BASE 0xb0000000 +#define PCIE_MMCONFIG_SIZE (256 * 1024 * 1024) + +#endif diff --git a/roms/qboot/include/processor-flags.h b/roms/qboot/include/processor-flags.h new file mode 100644 index 000000000..d56cc83a2 --- /dev/null +++ b/roms/qboot/include/processor-flags.h @@ -0,0 +1,153 @@ +#ifndef BIOS_X86_PROCESSOR_FLAGS_H +#define BIOS_X86_PROCESSOR_FLAGS_H +/* Various flags defined: can be included from assembler. */ + +#include "const.h" + +/* + * EFLAGS bits + */ +#define X86_EFLAGS_CF_BIT 0 /* Carry Flag */ +#define X86_EFLAGS_CF BITUL(X86_EFLAGS_CF_BIT) +#define X86_EFLAGS_FIXED_BIT 1 /* Bit 1 - always on */ +#define X86_EFLAGS_FIXED BITUL(X86_EFLAGS_FIXED_BIT) +#define X86_EFLAGS_PF_BIT 2 /* Parity Flag */ +#define X86_EFLAGS_PF BITUL(X86_EFLAGS_PF_BIT) +#define X86_EFLAGS_AF_BIT 4 /* Auxiliary carry Flag */ +#define X86_EFLAGS_AF BITUL(X86_EFLAGS_AF_BIT) +#define X86_EFLAGS_ZF_BIT 6 /* Zero Flag */ +#define X86_EFLAGS_ZF BITUL(X86_EFLAGS_ZF_BIT) +#define X86_EFLAGS_SF_BIT 7 /* Sign Flag */ +#define X86_EFLAGS_SF BITUL(X86_EFLAGS_SF_BIT) +#define X86_EFLAGS_TF_BIT 8 /* Trap Flag */ +#define X86_EFLAGS_TF BITUL(X86_EFLAGS_TF_BIT) +#define X86_EFLAGS_IF_BIT 9 /* Interrupt Flag */ +#define X86_EFLAGS_IF BITUL(X86_EFLAGS_IF_BIT) +#define X86_EFLAGS_DF_BIT 10 /* Direction Flag */ +#define X86_EFLAGS_DF BITUL(X86_EFLAGS_DF_BIT) +#define X86_EFLAGS_OF_BIT 11 /* Overflow Flag */ +#define X86_EFLAGS_OF BITUL(X86_EFLAGS_OF_BIT) +#define X86_EFLAGS_IOPL_BIT 12 /* I/O Privilege Level (2 bits) */ +#define X86_EFLAGS_IOPL (_AC(3,UL) << X86_EFLAGS_IOPL_BIT) +#define X86_EFLAGS_NT_BIT 14 /* Nested Task */ +#define X86_EFLAGS_NT BITUL(X86_EFLAGS_NT_BIT) +#define X86_EFLAGS_RF_BIT 16 /* Resume Flag */ +#define X86_EFLAGS_RF BITUL(X86_EFLAGS_RF_BIT) +#define X86_EFLAGS_VM_BIT 17 /* Virtual Mode */ +#define X86_EFLAGS_VM BITUL(X86_EFLAGS_VM_BIT) +#define X86_EFLAGS_AC_BIT 18 /* Alignment Check/Access Control */ +#define X86_EFLAGS_AC BITUL(X86_EFLAGS_AC_BIT) +#define X86_EFLAGS_AC_BIT 18 /* Alignment Check/Access Control */ +#define X86_EFLAGS_AC BITUL(X86_EFLAGS_AC_BIT) +#define X86_EFLAGS_VIF_BIT 19 /* Virtual Interrupt Flag */ +#define X86_EFLAGS_VIF BITUL(X86_EFLAGS_VIF_BIT) +#define X86_EFLAGS_VIP_BIT 20 /* Virtual Interrupt Pending */ +#define X86_EFLAGS_VIP BITUL(X86_EFLAGS_VIP_BIT) +#define X86_EFLAGS_ID_BIT 21 /* CPUID detection */ +#define X86_EFLAGS_ID BITUL(X86_EFLAGS_ID_BIT) + +/* + * Basic CPU control in CR0 + */ +#define X86_CR0_PE_BIT 0 /* Protection Enable */ +#define X86_CR0_PE BITUL(X86_CR0_PE_BIT) +#define X86_CR0_MP_BIT 1 /* Monitor Coprocessor */ +#define X86_CR0_MP BITUL(X86_CR0_MP_BIT) +#define X86_CR0_EM_BIT 2 /* Emulation */ +#define X86_CR0_EM BITUL(X86_CR0_EM_BIT) +#define X86_CR0_TS_BIT 3 /* Task Switched */ +#define X86_CR0_TS BITUL(X86_CR0_TS_BIT) +#define X86_CR0_ET_BIT 4 /* Extension Type */ +#define X86_CR0_ET BITUL(X86_CR0_ET_BIT) +#define X86_CR0_NE_BIT 5 /* Numeric Error */ +#define X86_CR0_NE BITUL(X86_CR0_NE_BIT) +#define X86_CR0_WP_BIT 16 /* Write Protect */ +#define X86_CR0_WP BITUL(X86_CR0_WP_BIT) +#define X86_CR0_AM_BIT 18 /* Alignment Mask */ +#define X86_CR0_AM BITUL(X86_CR0_AM_BIT) +#define X86_CR0_NW_BIT 29 /* Not Write-through */ +#define X86_CR0_NW BITUL(X86_CR0_NW_BIT) +#define X86_CR0_CD_BIT 30 /* Cache Disable */ +#define X86_CR0_CD BITUL(X86_CR0_CD_BIT) +#define X86_CR0_PG_BIT 31 /* Paging */ +#define X86_CR0_PG BITUL(X86_CR0_PG_BIT) + +/* + * Paging options in CR3 + */ +#define X86_CR3_PWT_BIT 3 /* Page Write Through */ +#define X86_CR3_PWT BITUL(X86_CR3_PWT_BIT) +#define X86_CR3_PCD_BIT 4 /* Page Cache Disable */ +#define X86_CR3_PCD BITUL(X86_CR3_PCD_BIT) +#define X86_CR3_PCID_MASK _AC(0x00000fff,UL) /* PCID Mask */ + +/* + * Intel CPU features in CR4 + */ +#define X86_CR4_VME_BIT 0 /* enable vm86 extensions */ +#define X86_CR4_VME BITUL(X86_CR4_VME_BIT) +#define X86_CR4_PVI_BIT 1 /* virtual interrupts flag enable */ +#define X86_CR4_PVI BITUL(X86_CR4_PVI_BIT) +#define X86_CR4_TSD_BIT 2 /* disable time stamp at ipl 3 */ +#define X86_CR4_TSD BITUL(X86_CR4_TSD_BIT) +#define X86_CR4_DE_BIT 3 /* enable debugging extensions */ +#define X86_CR4_DE BITUL(X86_CR4_DE_BIT) +#define X86_CR4_PSE_BIT 4 /* enable page size extensions */ +#define X86_CR4_PSE BITUL(X86_CR4_PSE_BIT) +#define X86_CR4_PAE_BIT 5 /* enable physical address extensions */ +#define X86_CR4_PAE BITUL(X86_CR4_PAE_BIT) +#define X86_CR4_MCE_BIT 6 /* Machine check enable */ +#define X86_CR4_MCE BITUL(X86_CR4_MCE_BIT) +#define X86_CR4_PGE_BIT 7 /* enable global pages */ +#define X86_CR4_PGE BITUL(X86_CR4_PGE_BIT) +#define X86_CR4_PCE_BIT 8 /* enable performance counters at ipl 3 */ +#define X86_CR4_PCE BITUL(X86_CR4_PCE_BIT) +#define X86_CR4_OSFXSR_BIT 9 /* enable fast FPU save and restore */ +#define X86_CR4_OSFXSR BITUL(X86_CR4_OSFXSR_BIT) +#define X86_CR4_OSXMMEXCPT_BIT 10 /* enable unmasked SSE exceptions */ +#define X86_CR4_OSXMMEXCPT BITUL(X86_CR4_OSXMMEXCPT_BIT) +#define X86_CR4_VMXE_BIT 13 /* enable VMX virtualization */ +#define X86_CR4_VMXE BITUL(X86_CR4_VMXE_BIT) +#define X86_CR4_SMXE_BIT 14 /* enable safer mode (TXT) */ +#define X86_CR4_SMXE BITUL(X86_CR4_SMXE_BIT) +#define X86_CR4_FSGSBASE_BIT 16 /* enable RDWRFSGS support */ +#define X86_CR4_FSGSBASE BITUL(X86_CR4_FSGSBASE_BIT) +#define X86_CR4_PCIDE_BIT 17 /* enable PCID support */ +#define X86_CR4_PCIDE BITUL(X86_CR4_PCIDE_BIT) +#define X86_CR4_OSXSAVE_BIT 18 /* enable xsave and xrestore */ +#define X86_CR4_OSXSAVE BITUL(X86_CR4_OSXSAVE_BIT) +#define X86_CR4_SMEP_BIT 20 /* enable SMEP support */ +#define X86_CR4_SMEP BITUL(X86_CR4_SMEP_BIT) +#define X86_CR4_SMAP_BIT 21 /* enable SMAP support */ +#define X86_CR4_SMAP BITUL(X86_CR4_SMAP_BIT) + +/* + * x86-64 Task Priority Register, CR8 + */ +#define X86_CR8_TPR _AC(0x0000000f,UL) /* task priority register */ + +/* + * AMD and Transmeta use MSRs for configuration; see <asm/msr-index.h> + */ + +/* + * NSC/Cyrix CPU configuration register indexes + */ +#define CX86_PCR0 0x20 +#define CX86_GCR 0xb8 +#define CX86_CCR0 0xc0 +#define CX86_CCR1 0xc1 +#define CX86_CCR2 0xc2 +#define CX86_CCR3 0xc3 +#define CX86_CCR4 0xe8 +#define CX86_CCR5 0xe9 +#define CX86_CCR6 0xea +#define CX86_CCR7 0xeb +#define CX86_PCR1 0xf0 +#define CX86_DIR0 0xfe +#define CX86_DIR1 0xff +#define CX86_ARR_BASE 0xc4 +#define CX86_RCR_BASE 0xdc + + +#endif /* BIOS_X86_PROCESSOR_FLAGS_H */ diff --git a/roms/qboot/include/segment.h b/roms/qboot/include/segment.h new file mode 100644 index 000000000..18afb5310 --- /dev/null +++ b/roms/qboot/include/segment.h @@ -0,0 +1,19 @@ +#ifndef BIOS_SEGMENT_H +#define BIOS_SEGMENT_H + +static inline uint32_t segment_to_flat(uint16_t selector, uint16_t offset) +{ + return ((uint32_t)selector << 4) + (uint32_t) offset; +} + +static inline uint16_t flat_to_seg16(uint32_t address) +{ + return (address >> 4) & 0xf000; +} + +static inline uint16_t flat_to_off16(uint32_t address) +{ + return address & 65535; +} + +#endif /* KVM_SEGMENT_H */ diff --git a/roms/qboot/include/smbios.h b/roms/qboot/include/smbios.h new file mode 100644 index 000000000..ec033cec2 --- /dev/null +++ b/roms/qboot/include/smbios.h @@ -0,0 +1 @@ +void extract_smbios(void); diff --git a/roms/qboot/include/start_info.h b/roms/qboot/include/start_info.h new file mode 100644 index 000000000..348779eb1 --- /dev/null +++ b/roms/qboot/include/start_info.h @@ -0,0 +1,146 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2016, Citrix Systems, Inc. + */ + +#ifndef __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ +#define __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ + +/* + * Start of day structure passed to PVH guests and to HVM guests in %ebx. + * + * NOTE: nothing will be loaded at physical address 0, so a 0 value in any + * of the address fields should be treated as not present. + * + * 0 +----------------+ + * | magic | Contains the magic value XEN_HVM_START_MAGIC_VALUE + * | | ("xEn3" with the 0x80 bit of the "E" set). + * 4 +----------------+ + * | version | Version of this structure. Current version is 1. New + * | | versions are guaranteed to be backwards-compatible. + * 8 +----------------+ + * | flags | SIF_xxx flags. + * 12 +----------------+ + * | nr_modules | Number of modules passed to the kernel. + * 16 +----------------+ + * | modlist_paddr | Physical address of an array of modules + * | | (layout of the structure below). + * 24 +----------------+ + * | cmdline_paddr | Physical address of the command line, + * | | a zero-terminated ASCII string. + * 32 +----------------+ + * | rsdp_paddr | Physical address of the RSDP ACPI data structure. + * 40 +----------------+ + * | memmap_paddr | Physical address of the (optional) memory map. Only + * | | present in version 1 and newer of the structure. + * 48 +----------------+ + * | memmap_entries | Number of entries in the memory map table. Only + * | | present in version 1 and newer of the structure. + * | | Zero if there is no memory map being provided. + * 52 +----------------+ + * | reserved | Version 1 and newer only. + * 56 +----------------+ + * + * The layout of each entry in the module structure is the following: + * + * 0 +----------------+ + * | paddr | Physical address of the module. + * 8 +----------------+ + * | size | Size of the module in bytes. + * 16 +----------------+ + * | cmdline_paddr | Physical address of the command line, + * | | a zero-terminated ASCII string. + * 24 +----------------+ + * | reserved | + * 32 +----------------+ + * + * The layout of each entry in the memory map table is as follows: + * + * 0 +----------------+ + * | addr | Base address + * 8 +----------------+ + * | size | Size of mapping in bytes + * 16 +----------------+ + * | type | Type of mapping as defined between the hypervisor + * | | and guest it's starting. E820_TYPE_xxx, for example. + * 20 +----------------| + * | reserved | + * 24 +----------------+ + * + * The address and sizes are always a 64bit little endian unsigned integer. + * + * NB: Xen on x86 will always try to place all the data below the 4GiB + * boundary. + * + * Version numbers of the hvm_start_info structure have evolved like this: + * + * Version 0: + * + * Version 1: Added the memmap_paddr/memmap_entries fields (plus 4 bytes of + * padding) to the end of the hvm_start_info struct. These new + * fields can be used to pass a memory map to the guest. The + * memory map is optional and so guests that understand version 1 + * of the structure must check that memmap_entries is non-zero + * before trying to read the memory map. + */ +#define XEN_HVM_START_MAGIC_VALUE 0x336ec578 + +/* + * C representation of the x86/HVM start info layout. + * + * The canonical definition of this layout is above, this is just a way to + * represent the layout described there using C types. + */ +struct hvm_start_info { + uint32_t magic; /* Contains the magic value 0x336ec578 */ + /* ("xEn3" with the 0x80 bit of the "E" set).*/ + uint32_t version; /* Version of this structure. */ + uint32_t flags; /* SIF_xxx flags. */ + uint32_t nr_modules; /* Number of modules passed to the kernel. */ + uint64_t modlist_paddr; /* Physical address of an array of */ + /* hvm_modlist_entry. */ + uint64_t cmdline_paddr; /* Physical address of the command line. */ + uint64_t rsdp_paddr; /* Physical address of the RSDP ACPI data */ + /* structure. */ + uint64_t memmap_paddr; /* Physical address of an array of */ + /* hvm_memmap_table_entry. Only present in */ + /* version 1 and newer of the structure */ + uint32_t memmap_entries; /* Number of entries in the memmap table. */ + /* Only present in version 1 and newer of */ + /* the structure. Value will be zero if */ + /* there is no memory map being provided. */ + uint32_t reserved; +}; + +struct hvm_modlist_entry { + uint64_t paddr; /* Physical address of the module. */ + uint64_t size; /* Size of the module in bytes. */ + uint64_t cmdline_paddr; /* Physical address of the command line. */ + uint64_t reserved; +}; + +struct hvm_memmap_table_entry { + uint64_t addr; /* Base address of the memory region */ + uint64_t size; /* Size of the memory region in bytes */ + uint32_t type; /* Mapping type */ + uint32_t reserved; +}; + +#endif /* __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ */ diff --git a/roms/qboot/include/stdio.h b/roms/qboot/include/stdio.h new file mode 100644 index 000000000..c15493340 --- /dev/null +++ b/roms/qboot/include/stdio.h @@ -0,0 +1,11 @@ +#ifndef BIOS_STDIO_H +#define BIOS_STDIO_H 1 + +#include <stdarg.h> + +extern int puts(const char *s); +extern int printf(const char *fmt, ...); +extern int snprintf(char *buf, int size, const char *fmt, ...); +extern int vsnprintf(char *buf, int size, const char *fmt, va_list va); + +#endif diff --git a/roms/qboot/include/stdlib.h b/roms/qboot/include/stdlib.h new file mode 100644 index 000000000..8de2f316e --- /dev/null +++ b/roms/qboot/include/stdlib.h @@ -0,0 +1,6 @@ +#ifndef BIOS_STDLIB_H +#define BIOS_STDLIB_H 1 + +extern long atol(const char *ptr); + +#endif diff --git a/roms/qboot/include/string.h b/roms/qboot/include/string.h new file mode 100644 index 000000000..39decfab1 --- /dev/null +++ b/roms/qboot/include/string.h @@ -0,0 +1,40 @@ +#ifndef BIOS_STRING_H +#define BIOS_STRING_H + +#include <stddef.h> +#include <stdint.h> + +unsigned long strlen(const char *buf); +char *strcat(char *dest, const char *src); +char *strcpy(char *dest, const char *src); +int strcmp(const char *a, const char *b); +char *strchr(const char *s, int c); +char *strstr(const char *s1, const char *s2); +int memcmp(const void *s1, const void *s2, size_t n); +void *memmove(void *dest, const void *src, size_t n); +void *memchr(const void *s, int c, size_t n); +uint8_t csum8(uint8_t *buf, uint32_t len); + +static inline void *memset(void *s, int c, size_t n) +{ + return __builtin_memset(s, c, n); +} + +static inline void *memcpy(void *dest, const void *src, size_t n) +{ + return __builtin_memcpy(dest, src, n); +} + +void *malloc_align(int n, int align); +void *malloc_fseg_align(int n, int align); + +static inline void *malloc(int n) +{ + return malloc_align(n, 16); +} + +static inline void *malloc_fseg(int n) +{ + return malloc_fseg_align(n, 16); +} +#endif |