aboutsummaryrefslogtreecommitdiffstats
path: root/roms/qboot/include
diff options
context:
space:
mode:
Diffstat (limited to 'roms/qboot/include')
-rw-r--r--roms/qboot/include/assembly.h26
-rw-r--r--roms/qboot/include/bios.h92
-rw-r--r--roms/qboot/include/bswap.h34
-rw-r--r--roms/qboot/include/const.h27
-rw-r--r--roms/qboot/include/e820.h44
-rw-r--r--roms/qboot/include/fw_cfg.h120
-rw-r--r--roms/qboot/include/ioport.h50
-rw-r--r--roms/qboot/include/linuxboot.h19
-rw-r--r--roms/qboot/include/memaccess.h30
-rw-r--r--roms/qboot/include/mpspec_def.h182
-rw-r--r--roms/qboot/include/multiboot.h66
-rw-r--r--roms/qboot/include/pci.h78
-rw-r--r--roms/qboot/include/processor-flags.h153
-rw-r--r--roms/qboot/include/segment.h19
-rw-r--r--roms/qboot/include/smbios.h1
-rw-r--r--roms/qboot/include/start_info.h146
-rw-r--r--roms/qboot/include/stdio.h11
-rw-r--r--roms/qboot/include/stdlib.h6
-rw-r--r--roms/qboot/include/string.h40
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