From eaae11e17f022188755c67e4dd3436875e84110d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 20 May 2015 17:09:34 +0200 Subject: make a bootable BIOS includes source from kvm-unit-tests Signed-off-by: Paolo Bonzini --- include/assembly.h | 4 ++++ include/bios.h | 36 ++++++++---------------------------- include/ioport.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/pci.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ include/segment.h | 6 +++--- include/stdio.h | 11 +++++++++++ include/stdlib.h | 6 ++++++ include/string.h | 18 ++++++++++++++++++ 8 files changed, 144 insertions(+), 31 deletions(-) create mode 100644 include/ioport.h create mode 100644 include/pci.h create mode 100644 include/stdio.h create mode 100644 include/stdlib.h create mode 100644 include/string.h (limited to 'include') diff --git a/include/assembly.h b/include/assembly.h index 3601024..6965583 100644 --- a/include/assembly.h +++ b/include/assembly.h @@ -3,6 +3,10 @@ #define __ASSEMBLY__ +#define BIOS2FLAT(x) ((x) - _start + 0xf0000) +#define BIOS2FLATROM(x) ((x) - _start + 0xffff0000) +_start = 0 + #define ORG(x) \ .section .fixedaddr._##x diff --git a/include/bios.h b/include/bios.h index 153c887..22a912a 100644 --- a/include/bios.h +++ b/include/bios.h @@ -4,32 +4,6 @@ #include /* - * X86-32 Memory Map (typical) - * start end - * Real Mode Interrupt Vector Table 0x00000000 0x000003FF - * BDA area 0x00000400 0x000004FF - * Conventional Low Memory 0x00000500 0x0009FBFF - * EBDA area 0x0009FC00 0x0009FFFF - * VIDEO RAM 0x000A0000 0x000BFFFF - * VIDEO ROM (BIOS) 0x000C0000 0x000C7FFF - * ROMs & unus. space (mapped hw & misc)0x000C8000 0x000EFFFF 160 KiB (typically) - * Motherboard BIOS 0x000F0000 0x000FFFFF - * Extended Memory 0x00100000 0xFEBFFFFF - * Reserved (configs, ACPI, PnP, etc) 0xFEC00000 0xFFFFFFFF - */ - -#define REAL_MODE_IVT_BEGIN 0x00000000 -#define REAL_MODE_IVT_END 0x000003ff - -#define BDA_START 0x00000400 -#define BDA_END 0x000004ff - -#define EBDA_START 0x0009fc00 -#define EBDA_END 0x0009ffff - -#define E820_MAP_START EBDA_START - -/* * When interfacing with assembler code we need to be sure how * arguments are passed in real mode. */ @@ -37,8 +11,6 @@ #ifndef __ASSEMBLER__ -#include - struct biosregs { uint32_t eax; uint32_t ebx; @@ -59,6 +31,14 @@ 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 struct e820map e820; + +static inline void __attribute__((noreturn)) panic(void) +{ + asm volatile("cli; hlt"); + for(;;); +} + #endif #endif /* BIOS_H_ */ diff --git a/include/ioport.h b/include/ioport.h new file mode 100644 index 0000000..bbec982 --- /dev/null +++ b/include/ioport.h @@ -0,0 +1,50 @@ +#ifndef _IOPORT_H +#define _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/include/pci.h b/include/pci.h new file mode 100644 index 0000000..e6b445c --- /dev/null +++ b/include/pci.h @@ -0,0 +1,44 @@ +#ifndef _PCI_H +#define _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); +} + +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); +} + +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); +} + +uint32_t pci_config_readl(uint16_t bdf, uint32_t addr) +{ + outl(0xcf8, 0x80000000 | (bdf << 8) | (addr & 0xfc)); + return inl(0xcfc); +} + +uint16_t pci_config_readw(uint16_t bdf, uint32_t addr) +{ + outl(0xcf8, 0x80000000 | (bdf << 8) | (addr & 0xfc)); + return inw(0xcfc | (addr & 2)); +} + +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 0 + +#endif diff --git a/include/segment.h b/include/segment.h index 694eb4b..7b68706 100644 --- a/include/segment.h +++ b/include/segment.h @@ -8,12 +8,12 @@ static inline uint32_t segment_to_flat(uint16_t selector, uint16_t offset) static inline uint16_t flat_to_seg16(uint32_t address) { - return address >> 4; + return (address >> 4) & 0xf000; } -static inline uint16_t flat_to_off16(uint32_t address, uint32_t segment) +static inline uint16_t flat_to_off16(uint32_t address) { - return address - (segment << 4); + return address & 65535; } #endif /* KVM_SEGMENT_H */ diff --git a/include/stdio.h b/include/stdio.h new file mode 100644 index 0000000..c154933 --- /dev/null +++ b/include/stdio.h @@ -0,0 +1,11 @@ +#ifndef BIOS_STDIO_H +#define BIOS_STDIO_H 1 + +#include + +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/include/stdlib.h b/include/stdlib.h new file mode 100644 index 0000000..8de2f31 --- /dev/null +++ b/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/include/string.h b/include/string.h new file mode 100644 index 0000000..962b07e --- /dev/null +++ b/include/string.h @@ -0,0 +1,18 @@ +#ifndef _STRING_H +#define _STRING_H + +#include + +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); +void *memset(void *s, int c, size_t n); +void *memcpy(void *dest, const void *src, size_t n); +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); + +#endif -- cgit v1.1