diff options
Diffstat (limited to 'arch/x86/boot/boot.h')
-rw-r--r-- | arch/x86/boot/boot.h | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h new file mode 100644 index 0000000000..d98b0661cd --- /dev/null +++ b/arch/x86/boot/boot.h @@ -0,0 +1,193 @@ +/* -*- linux-c -*- ------------------------------------------------------- * + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright 2007 rPath, Inc. - All Rights Reserved + * Copyright 2009 Intel Corporation; author H. Peter Anvin + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2. + * + * ----------------------------------------------------------------------- */ + +/** + * @file + * @brief Main declarations for the real mode code + */ + +#ifndef BOOT_BOOT_H +#define BOOT_BOOT_H + +#define STACK_SIZE 512 /* Minimum number of bytes for stack */ + +/** Carry flag */ +#define X86_EFLAGS_CF 0x00000001 + +/** PE flag */ +#define X86_CR0_PE 0x00000001 + +#ifndef __ASSEMBLY__ + +#include <types.h> + +/* we are still in real mode here! */ +#define THIS_IS_REALMODE_CODE asm(".code16gcc"); + +struct biosregs { + union { + struct { + uint32_t edi; + uint32_t esi; + uint32_t ebp; + uint32_t _esp; + uint32_t ebx; + uint32_t edx; + uint32_t ecx; + uint32_t eax; + uint32_t _fsgs; + uint32_t _dses; + uint32_t eflags; + }; + struct { + uint16_t di, hdi; + uint16_t si, hsi; + uint16_t bp, hbp; + uint16_t _sp, _hsp; + uint16_t bx, hbx; + uint16_t dx, hdx; + uint16_t cx, hcx; + uint16_t ax, hax; + uint16_t gs, fs; + uint16_t es, ds; + uint16_t flags, hflags; + }; + struct { + uint8_t dil, dih, edi2, edi3; + uint8_t sil, sih, esi2, esi3; + uint8_t bpl, bph, ebp2, ebp3; + uint8_t _spl, _sph, _esp2, _esp3; + uint8_t bl, bh, ebx2, ebx3; + uint8_t dl, dh, edx2, edx3; + uint8_t cl, ch, ecx2, ecx3; + uint8_t al, ah, eax2, eax3; + }; + }; +}; + +/* functions in the realmode part */ +extern int enable_a20(void); +extern void initregs(struct biosregs *regs); +extern void intcall(uint8_t int_no, const struct biosregs *ireg, struct biosregs *oreg); +extern void boot_puts(char*); +extern void __attribute__((noreturn)) die(void); +extern void __attribute__((noreturn)) protected_mode_jump(void); + +struct gdt_ptr { + uint16_t len; + uint32_t ptr; +} __attribute__((packed)); + +/* These functions are used to reference data in other segments. */ + +static inline uint16_t ds(void) +{ + uint16_t seg; + asm("movw %%ds,%0" : "=rm" (seg)); + return seg; +} + +static inline void set_fs(uint16_t seg) +{ + asm volatile("movw %0,%%fs" : : "rm" (seg)); +} + +static inline uint16_t fs(void) +{ + uint16_t seg; + asm volatile("movw %%fs,%0" : "=rm" (seg)); + return seg; +} + +static inline void set_gs(uint16_t seg) +{ + asm volatile("movw %0,%%gs" : : "rm" (seg)); +} + +static inline uint16_t gs(void) +{ + uint16_t seg; + asm volatile("movw %%gs,%0" : "=rm" (seg)); + return seg; +} + +typedef unsigned int addr_t; + +static inline uint8_t rdfs8(addr_t addr) +{ + uint8_t v; + asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*(uint8_t *)addr)); + return v; +} +static inline uint16_t rdfs16(addr_t addr) +{ + uint16_t v; + asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*(uint16_t *)addr)); + return v; +} +static inline uint32_t rdfs32(addr_t addr) +{ + uint32_t v; + asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*(uint32_t *)addr)); + return v; +} + +static inline void wrfs8(uint8_t v, addr_t addr) +{ + asm volatile("movb %1,%%fs:%0" : "+m" (*(uint8_t *)addr) : "qi" (v)); +} +static inline void wrfs16(uint16_t v, addr_t addr) +{ + asm volatile("movw %1,%%fs:%0" : "+m" (*(uint16_t *)addr) : "ri" (v)); +} +static inline void wrfs32(uint32_t v, addr_t addr) +{ + asm volatile("movl %1,%%fs:%0" : "+m" (*(uint32_t *)addr) : "ri" (v)); +} + +static inline uint8_t rdgs8(addr_t addr) +{ + uint8_t v; + asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*(uint8_t *)addr)); + return v; +} +static inline uint16_t rdgs16(addr_t addr) +{ + uint16_t v; + asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*(uint16_t *)addr)); + return v; +} +static inline uint32_t rdgs32(addr_t addr) +{ + uint32_t v; + asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*(uint32_t *)addr)); + return v; +} + +static inline void wrgs8(uint8_t v, addr_t addr) +{ + asm volatile("movb %1,%%gs:%0" : "+m" (*(uint8_t *)addr) : "qi" (v)); +} +static inline void wrgs16(uint16_t v, addr_t addr) +{ + asm volatile("movw %1,%%gs:%0" : "+m" (*(uint16_t *)addr) : "ri" (v)); +} +static inline void wrgs32(uint32_t v, addr_t addr) +{ + asm volatile("movl %1,%%gs:%0" : "+m" (*(uint32_t *)addr) : "ri" (v)); +} + +/** use the built in memset function for the real mode code */ +#define memset(d,c,l) __builtin_memset(d,c,l) + +#endif /* __ASSEMBLY__ */ + +#endif /* BOOT_BOOT_H */ |