mirror of
https://github.com/ipxe/ipxe
synced 2025-12-27 18:12:36 +03:00
Initial revision
This commit is contained in:
45
src/arch/i386/include/bits/byteswap.h
Normal file
45
src/arch/i386/include/bits/byteswap.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef ETHERBOOT_BITS_BYTESWAP_H
|
||||
#define ETHERBOOT_BITS_BYTESWAP_H
|
||||
|
||||
static inline uint16_t __i386_bswap_16(uint16_t x)
|
||||
{
|
||||
__asm__("xchgb %b0,%h0\n\t"
|
||||
: "=q" (x)
|
||||
: "0" (x));
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline uint32_t __i386_bswap_32(uint32_t x)
|
||||
{
|
||||
__asm__("xchgb %b0,%h0\n\t"
|
||||
"rorl $16,%0\n\t"
|
||||
"xchgb %b0,%h0"
|
||||
: "=q" (x)
|
||||
: "0" (x));
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
#define __bswap_constant_16(x) \
|
||||
((uint16_t)((((uint16_t)(x) & 0x00ff) << 8) | \
|
||||
(((uint16_t)(x) & 0xff00) >> 8)))
|
||||
|
||||
#define __bswap_constant_32(x) \
|
||||
((uint32_t)((((uint32_t)(x) & 0x000000ffU) << 24) | \
|
||||
(((uint32_t)(x) & 0x0000ff00U) << 8) | \
|
||||
(((uint32_t)(x) & 0x00ff0000U) >> 8) | \
|
||||
(((uint32_t)(x) & 0xff000000U) >> 24)))
|
||||
|
||||
#define __bswap_16(x) \
|
||||
((uint16_t)(__builtin_constant_p(x) ? \
|
||||
__bswap_constant_16(x) : \
|
||||
__i386_bswap_16(x)))
|
||||
|
||||
|
||||
#define __bswap_32(x) \
|
||||
((uint32_t)(__builtin_constant_p(x) ? \
|
||||
__bswap_constant_32(x) : \
|
||||
__i386_bswap_32(x)))
|
||||
|
||||
|
||||
#endif /* ETHERBOOT_BITS_BYTESWAP_H */
|
||||
243
src/arch/i386/include/bits/cpu.h
Normal file
243
src/arch/i386/include/bits/cpu.h
Normal file
@@ -0,0 +1,243 @@
|
||||
#ifndef I386_BITS_CPU_H
|
||||
#define I386_BITS_CPU_H
|
||||
|
||||
|
||||
/* Sample usage: CPU_FEATURE_P(cpu.x86_capability, FPU) */
|
||||
#define CPU_FEATURE_P(CAP, FEATURE) \
|
||||
(!!(CAP[(X86_FEATURE_##FEATURE)/32] & ((X86_FEATURE_##FEATURE) & 0x1f)))
|
||||
|
||||
#define NCAPINTS 4 /* Currently we have 4 32-bit words worth of info */
|
||||
|
||||
/* Intel-defined CPU features, CPUID level 0x00000001, word 0 */
|
||||
#define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */
|
||||
#define X86_FEATURE_VME (0*32+ 1) /* Virtual Mode Extensions */
|
||||
#define X86_FEATURE_DE (0*32+ 2) /* Debugging Extensions */
|
||||
#define X86_FEATURE_PSE (0*32+ 3) /* Page Size Extensions */
|
||||
#define X86_FEATURE_TSC (0*32+ 4) /* Time Stamp Counter */
|
||||
#define X86_FEATURE_MSR (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
|
||||
#define X86_FEATURE_PAE (0*32+ 6) /* Physical Address Extensions */
|
||||
#define X86_FEATURE_MCE (0*32+ 7) /* Machine Check Architecture */
|
||||
#define X86_FEATURE_CX8 (0*32+ 8) /* CMPXCHG8 instruction */
|
||||
#define X86_FEATURE_APIC (0*32+ 9) /* Onboard APIC */
|
||||
#define X86_FEATURE_SEP (0*32+11) /* SYSENTER/SYSEXIT */
|
||||
#define X86_FEATURE_MTRR (0*32+12) /* Memory Type Range Registers */
|
||||
#define X86_FEATURE_PGE (0*32+13) /* Page Global Enable */
|
||||
#define X86_FEATURE_MCA (0*32+14) /* Machine Check Architecture */
|
||||
#define X86_FEATURE_CMOV (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
|
||||
#define X86_FEATURE_PAT (0*32+16) /* Page Attribute Table */
|
||||
#define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */
|
||||
#define X86_FEATURE_PN (0*32+18) /* Processor serial number */
|
||||
#define X86_FEATURE_CLFLSH (0*32+19) /* Supports the CLFLUSH instruction */
|
||||
#define X86_FEATURE_DTES (0*32+21) /* Debug Trace Store */
|
||||
#define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */
|
||||
#define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */
|
||||
#define X86_FEATURE_FXSR (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
|
||||
/* of FPU context), and CR4.OSFXSR available */
|
||||
#define X86_FEATURE_XMM (0*32+25) /* Streaming SIMD Extensions */
|
||||
#define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */
|
||||
#define X86_FEATURE_SELFSNOOP (0*32+27) /* CPU self snoop */
|
||||
#define X86_FEATURE_HT (0*32+28) /* Hyper-Threading */
|
||||
#define X86_FEATURE_ACC (0*32+29) /* Automatic clock control */
|
||||
#define X86_FEATURE_IA64 (0*32+30) /* IA-64 processor */
|
||||
|
||||
/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
|
||||
/* Don't duplicate feature flags which are redundant with Intel! */
|
||||
#define X86_FEATURE_SYSCALL (1*32+11) /* SYSCALL/SYSRET */
|
||||
#define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */
|
||||
#define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */
|
||||
#define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */
|
||||
#define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */
|
||||
|
||||
/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
|
||||
#define X86_FEATURE_RECOVERY (2*32+ 0) /* CPU in recovery mode */
|
||||
#define X86_FEATURE_LONGRUN (2*32+ 1) /* Longrun power control */
|
||||
#define X86_FEATURE_LRTI (2*32+ 3) /* LongRun table interface */
|
||||
|
||||
/* Other features, Linux-defined mapping, word 3 */
|
||||
/* This range is used for feature bits which conflict or are synthesized */
|
||||
#define X86_FEATURE_CXMMX (3*32+ 0) /* Cyrix MMX extensions */
|
||||
#define X86_FEATURE_K6_MTRR (3*32+ 1) /* AMD K6 nonstandard MTRRs */
|
||||
#define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */
|
||||
#define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */
|
||||
|
||||
#define MAX_X86_VENDOR_ID 16
|
||||
struct cpuinfo_x86 {
|
||||
uint8_t x86; /* CPU family */
|
||||
uint8_t x86_model;
|
||||
uint8_t x86_mask;
|
||||
|
||||
int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */
|
||||
unsigned x86_capability[NCAPINTS];
|
||||
char x86_vendor_id[MAX_X86_VENDOR_ID];
|
||||
};
|
||||
|
||||
|
||||
#define X86_VENDOR_INTEL 0
|
||||
#define X86_VENDOR_CYRIX 1
|
||||
#define X86_VENDOR_AMD 2
|
||||
#define X86_VENDOR_UMC 3
|
||||
#define X86_VENDOR_NEXGEN 4
|
||||
#define X86_VENDOR_CENTAUR 5
|
||||
#define X86_VENDOR_RISE 6
|
||||
#define X86_VENDOR_TRANSMETA 7
|
||||
#define X86_VENDOR_NSC 8
|
||||
#define X86_VENDOR_UNKNOWN 0xff
|
||||
|
||||
/*
|
||||
* EFLAGS bits
|
||||
*/
|
||||
#define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
|
||||
#define X86_EFLAGS_PF 0x00000004 /* Parity Flag */
|
||||
#define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */
|
||||
#define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */
|
||||
#define X86_EFLAGS_SF 0x00000080 /* Sign Flag */
|
||||
#define X86_EFLAGS_TF 0x00000100 /* Trap Flag */
|
||||
#define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */
|
||||
#define X86_EFLAGS_DF 0x00000400 /* Direction Flag */
|
||||
#define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */
|
||||
#define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */
|
||||
#define X86_EFLAGS_NT 0x00004000 /* Nested Task */
|
||||
#define X86_EFLAGS_RF 0x00010000 /* Resume Flag */
|
||||
#define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
|
||||
#define X86_EFLAGS_AC 0x00040000 /* Alignment Check */
|
||||
#define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */
|
||||
#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */
|
||||
#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
|
||||
|
||||
/*
|
||||
* Generic CPUID function
|
||||
*/
|
||||
static inline void cpuid(int op,
|
||||
unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
|
||||
{
|
||||
__asm__("cpuid"
|
||||
: "=a" (*eax),
|
||||
"=b" (*ebx),
|
||||
"=c" (*ecx),
|
||||
"=d" (*edx)
|
||||
: "0" (op));
|
||||
}
|
||||
|
||||
/*
|
||||
* CPUID functions returning a single datum
|
||||
*/
|
||||
static inline unsigned int cpuid_eax(unsigned int op)
|
||||
{
|
||||
unsigned int eax;
|
||||
|
||||
__asm__("cpuid"
|
||||
: "=a" (eax)
|
||||
: "0" (op)
|
||||
: "bx", "cx", "dx");
|
||||
return eax;
|
||||
}
|
||||
static inline unsigned int cpuid_ebx(unsigned int op)
|
||||
{
|
||||
unsigned int eax, ebx;
|
||||
|
||||
__asm__("cpuid"
|
||||
: "=a" (eax), "=b" (ebx)
|
||||
: "0" (op)
|
||||
: "cx", "dx" );
|
||||
return ebx;
|
||||
}
|
||||
static inline unsigned int cpuid_ecx(unsigned int op)
|
||||
{
|
||||
unsigned int eax, ecx;
|
||||
|
||||
__asm__("cpuid"
|
||||
: "=a" (eax), "=c" (ecx)
|
||||
: "0" (op)
|
||||
: "bx", "dx" );
|
||||
return ecx;
|
||||
}
|
||||
static inline unsigned int cpuid_edx(unsigned int op)
|
||||
{
|
||||
unsigned int eax, edx;
|
||||
|
||||
__asm__("cpuid"
|
||||
: "=a" (eax), "=d" (edx)
|
||||
: "0" (op)
|
||||
: "bx", "cx");
|
||||
return edx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Intel CPU features in CR4
|
||||
*/
|
||||
#define X86_CR4_VME 0x0001 /* enable vm86 extensions */
|
||||
#define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */
|
||||
#define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */
|
||||
#define X86_CR4_DE 0x0008 /* enable debugging extensions */
|
||||
#define X86_CR4_PSE 0x0010 /* enable page size extensions */
|
||||
#define X86_CR4_PAE 0x0020 /* enable physical address extensions */
|
||||
#define X86_CR4_MCE 0x0040 /* Machine check enable */
|
||||
#define X86_CR4_PGE 0x0080 /* enable global pages */
|
||||
#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */
|
||||
#define X86_CR4_OSFXSR 0x0200 /* enable fast FPU save and restore */
|
||||
#define X86_CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */
|
||||
|
||||
|
||||
#define MSR_K6_EFER 0xC0000080
|
||||
/* EFER bits: */
|
||||
#define _EFER_SCE 0 /* SYSCALL/SYSRET */
|
||||
#define _EFER_LME 8 /* Long mode enable */
|
||||
#define _EFER_LMA 10 /* Long mode active (read-only) */
|
||||
#define _EFER_NX 11 /* No execute enable */
|
||||
|
||||
#define EFER_SCE (1<<_EFER_SCE)
|
||||
#define EFER_LME (1<<EFER_LME)
|
||||
#define EFER_LMA (1<<EFER_LMA)
|
||||
#define EFER_NX (1<<_EFER_NX)
|
||||
|
||||
#define rdmsr(msr,val1,val2) \
|
||||
__asm__ __volatile__("rdmsr" \
|
||||
: "=a" (val1), "=d" (val2) \
|
||||
: "c" (msr))
|
||||
|
||||
#define wrmsr(msr,val1,val2) \
|
||||
__asm__ __volatile__("wrmsr" \
|
||||
: /* no outputs */ \
|
||||
: "c" (msr), "a" (val1), "d" (val2))
|
||||
|
||||
|
||||
#define read_cr0() ({ \
|
||||
unsigned int __dummy; \
|
||||
__asm__( \
|
||||
"movl %%cr0, %0\n\t" \
|
||||
:"=r" (__dummy)); \
|
||||
__dummy; \
|
||||
})
|
||||
#define write_cr0(x) \
|
||||
__asm__("movl %0,%%cr0": :"r" (x));
|
||||
|
||||
#define read_cr3() ({ \
|
||||
unsigned int __dummy; \
|
||||
__asm__( \
|
||||
"movl %%cr3, %0\n\t" \
|
||||
:"=r" (__dummy)); \
|
||||
__dummy; \
|
||||
})
|
||||
#define write_cr3x(x) \
|
||||
__asm__("movl %0,%%cr3": :"r" (x));
|
||||
|
||||
|
||||
#define read_cr4() ({ \
|
||||
unsigned int __dummy; \
|
||||
__asm__( \
|
||||
"movl %%cr4, %0\n\t" \
|
||||
:"=r" (__dummy)); \
|
||||
__dummy; \
|
||||
})
|
||||
#define write_cr4x(x) \
|
||||
__asm__("movl %0,%%cr4": :"r" (x));
|
||||
|
||||
|
||||
extern struct cpuinfo_x86 cpu_info;
|
||||
#ifdef CONFIG_X86_64
|
||||
extern void cpu_setup(void);
|
||||
#else
|
||||
#define cpu_setup() do {} while(0)
|
||||
#endif
|
||||
|
||||
#endif /* I386_BITS_CPU_H */
|
||||
91
src/arch/i386/include/bits/elf.h
Normal file
91
src/arch/i386/include/bits/elf.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#ifndef I386_BITS_ELF_H
|
||||
#define I386_BITS_ELF_H
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/* ELF Defines for the 64bit version of the current architecture */
|
||||
#define EM_CURRENT_64 EM_X86_64
|
||||
#define EM_CURRENT_64_PRESENT ( \
|
||||
CPU_FEATURE_P(cpu_info.x86_capability, LM) && \
|
||||
CPU_FEATURE_P(cpu_info.x86_capability, PAE) && \
|
||||
CPU_FEATURE_P(cpu_info.x86_capability, PSE))
|
||||
|
||||
#define ELF_CHECK_X86_64_ARCH(x) \
|
||||
(EM_CURRENT_64_PRESENT && ((x).e_machine == EM_X86_64))
|
||||
#define __unused_i386
|
||||
#else
|
||||
#define ELF_CHECK_X86_64_ARCH(x) 0
|
||||
#define __unused_i386 __unused
|
||||
#endif
|
||||
|
||||
|
||||
/* ELF Defines for the current architecture */
|
||||
#define EM_CURRENT EM_386
|
||||
#define ELFDATA_CURRENT ELFDATA2LSB
|
||||
|
||||
#define ELF_CHECK_I386_ARCH(x) \
|
||||
(((x).e_machine == EM_386) || ((x).e_machine == EM_486))
|
||||
|
||||
#define ELF_CHECK_ARCH(x) \
|
||||
((ELF_CHECK_I386_ARCH(x) || ELF_CHECK_X86_64_ARCH(x)) && \
|
||||
((x).e_entry <= 0xffffffffUL))
|
||||
|
||||
#ifdef IMAGE_FREEBSD
|
||||
/*
|
||||
* FreeBSD has this rather strange "feature" of its design.
|
||||
* At some point in its evolution, FreeBSD started to rely
|
||||
* externally on private/static/debug internal symbol information.
|
||||
* That is, some of the interfaces that software uses to access
|
||||
* and work with the FreeBSD kernel are made available not
|
||||
* via the shared library symbol information (the .DYNAMIC section)
|
||||
* but rather the debug symbols. This means that any symbol, not
|
||||
* just publicly defined symbols can be (and are) used by system
|
||||
* tools to make the system work. (such as top, swapinfo, swapon,
|
||||
* etc)
|
||||
*
|
||||
* Even worse, however, is the fact that standard ELF loaders do
|
||||
* not know how to load the symbols since they are not within
|
||||
* an ELF PT_LOAD section. The kernel needs these symbols to
|
||||
* operate so the following changes/additions to the boot
|
||||
* loading of EtherBoot have been made to get the kernel to load.
|
||||
* All of the changes are within IMAGE_FREEBSD such that the
|
||||
* extra/changed code only compiles when FREEBSD support is
|
||||
* enabled.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Section header for FreeBSD (debug symbol kludge!) support
|
||||
*/
|
||||
typedef struct {
|
||||
Elf32_Word sh_name; /* Section name (index into the
|
||||
section header string table). */
|
||||
Elf32_Word sh_type; /* Section type. */
|
||||
Elf32_Word sh_flags; /* Section flags. */
|
||||
Elf32_Addr sh_addr; /* Address in memory image. */
|
||||
Elf32_Off sh_offset; /* Offset in file. */
|
||||
Elf32_Size sh_size; /* Size in bytes. */
|
||||
Elf32_Word sh_link; /* Index of a related section. */
|
||||
Elf32_Word sh_info; /* Depends on section type. */
|
||||
Elf32_Size sh_addralign; /* Alignment in bytes. */
|
||||
Elf32_Size sh_entsize; /* Size of each entry in section. */
|
||||
} Elf32_Shdr;
|
||||
|
||||
/* sh_type */
|
||||
#define SHT_SYMTAB 2 /* symbol table section */
|
||||
#define SHT_STRTAB 3 /* string table section */
|
||||
|
||||
/*
|
||||
* Module information subtypes (for the metadata that we need to build)
|
||||
*/
|
||||
#define MODINFO_END 0x0000 /* End of list */
|
||||
#define MODINFO_NAME 0x0001 /* Name of module (string) */
|
||||
#define MODINFO_TYPE 0x0002 /* Type of module (string) */
|
||||
#define MODINFO_METADATA 0x8000 /* Module-specfic */
|
||||
|
||||
#define MODINFOMD_SSYM 0x0003 /* start of symbols */
|
||||
#define MODINFOMD_ESYM 0x0004 /* end of symbols */
|
||||
|
||||
#endif /* IMAGE_FREEBSD */
|
||||
|
||||
#endif /* I386_BITS_ELF_H */
|
||||
5
src/arch/i386/include/bits/elf_x.h
Normal file
5
src/arch/i386/include/bits/elf_x.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#define ARCH_ELF_CLASS ELFCLASS32
|
||||
#define ARCH_ELF_DATA ELFDATA2LSB
|
||||
#define ARCH_ELF_MACHINE_OK(x) ((x)==EM_386 || (x)==EM_486)
|
||||
typedef Elf32_Ehdr Elf_ehdr;
|
||||
typedef Elf32_Phdr Elf_phdr;
|
||||
3
src/arch/i386/include/bits/eltorito.h
Normal file
3
src/arch/i386/include/bits/eltorito.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#ifndef ELTORITO_PLATFORM
|
||||
#define ELTORITO_PLATFORM ELTORITO_PLATFORM_X86
|
||||
#endif /* ELTORITO_PLATFORM */
|
||||
9
src/arch/i386/include/bits/endian.h
Normal file
9
src/arch/i386/include/bits/endian.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef ETHERBOOT_BITS_ENDIAN_H
|
||||
#define ETHERBOOT_BITS_ENDIAN_H
|
||||
|
||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
|
||||
#define le32_to_cpup(x) (*(uint32_t *)(x))
|
||||
#define cpu_to_le16p(x) (*(uint16_t*)(x))
|
||||
|
||||
#endif /* ETHERBOOT_BITS_ENDIAN_H */
|
||||
99
src/arch/i386/include/bits/string.h
Normal file
99
src/arch/i386/include/bits/string.h
Normal file
@@ -0,0 +1,99 @@
|
||||
#ifndef ETHERBOOT_BITS_STRING_H
|
||||
#define ETHERBOOT_BITS_STRING_H
|
||||
/*
|
||||
* Taken from Linux /usr/include/asm/string.h
|
||||
* All except memcpy, memmove, memset and memcmp removed.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This string-include defines all string functions as inline
|
||||
* functions. Use gcc. It also assumes ds=es=data space, this should be
|
||||
* normal. Most of the string-functions are rather heavily hand-optimized,
|
||||
* see especially strtok,strstr,str[c]spn. They should work, but are not
|
||||
* very easy to understand. Everything is done entirely within the register
|
||||
* set, making the functions fast and clean. String instructions have been
|
||||
* used through-out, making for "slightly" unclear code :-)
|
||||
*
|
||||
* NO Copyright (C) 1991, 1992 Linus Torvalds,
|
||||
* consider these trivial functions to be PD.
|
||||
*/
|
||||
|
||||
|
||||
#define __HAVE_ARCH_MEMMOVE
|
||||
static inline void * memmove(void * dest,const void * src, size_t n)
|
||||
{
|
||||
int d0, d1, d2;
|
||||
if (dest<src)
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"rep\n\t"
|
||||
"movsb"
|
||||
: "=&c" (d0), "=&S" (d1), "=&D" (d2)
|
||||
:"0" (n),"1" (src),"2" (dest)
|
||||
: "memory");
|
||||
else
|
||||
__asm__ __volatile__(
|
||||
"std\n\t"
|
||||
"rep\n\t"
|
||||
"movsb\n\t"
|
||||
"cld"
|
||||
: "=&c" (d0), "=&S" (d1), "=&D" (d2)
|
||||
:"0" (n),
|
||||
"1" (n-1+(const char *)src),
|
||||
"2" (n-1+(char *)dest)
|
||||
:"memory");
|
||||
return dest;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_MEMSET
|
||||
static inline void *memset(void *s, int c,size_t count)
|
||||
{
|
||||
int d0, d1;
|
||||
__asm__ __volatile__(
|
||||
"cld\n\t"
|
||||
"rep\n\t"
|
||||
"stosb"
|
||||
: "=&c" (d0), "=&D" (d1)
|
||||
:"a" (c),"1" (s),"0" (count)
|
||||
:"memory");
|
||||
return s;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_STRNCMP
|
||||
static inline int strncmp(const char * cs,const char * ct,size_t count)
|
||||
{
|
||||
register int __res;
|
||||
int d0, d1, d2;
|
||||
__asm__ __volatile__(
|
||||
"1:\tdecl %3\n\t"
|
||||
"js 2f\n\t"
|
||||
"lodsb\n\t"
|
||||
"scasb\n\t"
|
||||
"jne 3f\n\t"
|
||||
"testb %%al,%%al\n\t"
|
||||
"jne 1b\n"
|
||||
"2:\txorl %%eax,%%eax\n\t"
|
||||
"jmp 4f\n"
|
||||
"3:\tsbbl %%eax,%%eax\n\t"
|
||||
"orb $1,%%al\n"
|
||||
"4:"
|
||||
:"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
|
||||
:"1" (cs),"2" (ct),"3" (count));
|
||||
return __res;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_STRLEN
|
||||
static inline size_t strlen(const char * s)
|
||||
{
|
||||
int d0;
|
||||
register int __res;
|
||||
__asm__ __volatile__(
|
||||
"repne\n\t"
|
||||
"scasb\n\t"
|
||||
"notl %0\n\t"
|
||||
"decl %0"
|
||||
:"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
|
||||
return __res;
|
||||
}
|
||||
|
||||
#endif /* ETHERBOOT_BITS_STRING_H */
|
||||
243
src/arch/i386/include/callbacks_arch.h
Normal file
243
src/arch/i386/include/callbacks_arch.h
Normal file
@@ -0,0 +1,243 @@
|
||||
/* Callout/callback interface for Etherboot
|
||||
*
|
||||
* This file provides the mechanisms for making calls from Etherboot
|
||||
* to external programs and vice-versa.
|
||||
*
|
||||
* Initial version by Michael Brown <mbrown@fensystems.co.uk>, January 2004.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef CALLBACKS_ARCH_H
|
||||
#define CALLBACKS_ARCH_H
|
||||
|
||||
/* Skip the definitions that won't make sense to the assembler */
|
||||
#ifndef ASSEMBLY
|
||||
|
||||
/* Struct to hold general-purpose register values. PUSHAL and POPAL
|
||||
* can work directly with this structure; do not change the order of
|
||||
* registers.
|
||||
*/
|
||||
typedef struct {
|
||||
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;
|
||||
} PACKED;
|
||||
uint16_t bx;
|
||||
uint32_t ebx;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
uint8_t dl;
|
||||
uint8_t dh;
|
||||
} PACKED;
|
||||
uint16_t dx;
|
||||
uint32_t edx;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
uint8_t cl;
|
||||
uint8_t ch;
|
||||
} PACKED;
|
||||
uint16_t cx;
|
||||
uint32_t ecx;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
uint8_t al;
|
||||
uint8_t ah;
|
||||
} PACKED;
|
||||
uint16_t ax;
|
||||
uint32_t eax;
|
||||
};
|
||||
} regs_t;
|
||||
|
||||
/* Struct to hold segment register values. Don't change the order;
|
||||
* many bits of assembly code rely on it.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t cs;
|
||||
uint16_t ss;
|
||||
uint16_t ds;
|
||||
uint16_t es;
|
||||
uint16_t fs;
|
||||
uint16_t gs;
|
||||
} PACKED seg_regs_t;
|
||||
|
||||
/* Struct for a GDT descriptor */
|
||||
typedef struct {
|
||||
uint16_t limit;
|
||||
uint32_t address;
|
||||
uint16_t padding;
|
||||
} PACKED gdt_descriptor_t;
|
||||
|
||||
/* Struct for a GDT entry. Use GDT_SEGMENT() to fill it in.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t limit_0_15;
|
||||
uint16_t base_0_15;
|
||||
uint8_t base_16_23;
|
||||
uint8_t accessed__type__sflag__dpl__present;
|
||||
uint8_t limit_16_19__avl__size__granularity;
|
||||
uint8_t base_24_31;
|
||||
} PACKED gdt_segment_t;
|
||||
|
||||
#define GDT_SEGMENT(base,limit,type,sflag,dpl,avl,size,granularity) \
|
||||
( (gdt_segment_t) { \
|
||||
( (limit) & 0xffff ), \
|
||||
( (base) & 0xffff ), \
|
||||
( ( (base) >> 16 ) & 0xff ), \
|
||||
( ( 1 << 0 ) | ( (type) << 1 ) | \
|
||||
( (sflag) << 4 ) | ( (dpl) << 5 ) | ( 1 << 7 ) ), \
|
||||
( ( (limit) >> 16 ) | \
|
||||
( (avl) << 4 ) | ( (size) << 5 ) | ( (granularity) << 7 ) ),\
|
||||
( (base) >> 24 ) \
|
||||
} )
|
||||
#define GDT_SEGMENT_BASE(gdt_segment) \
|
||||
( (gdt_segment)->base_0_15 | \
|
||||
(gdt_segment)->base_16_23 << 16 | \
|
||||
(gdt_segment)->base_24_31 << 24 )
|
||||
#define GDT_SEGMENT_LIMIT(gdt_segment) \
|
||||
( (gdt_segment)->limit_0_15 | \
|
||||
( ( (gdt_segment)->limit_16_19__avl__size__granularity \
|
||||
& 0xf ) << 16 ) )
|
||||
#define GDT_SEGMENT_GRANULARITY(gdt_segment) \
|
||||
( ( (gdt_segment)->limit_16_19__avl__size__granularity \
|
||||
& 0x80 ) >> 7 )
|
||||
#define GDT_SEGMENT_TYPE(gdt_segment) \
|
||||
( ( (gdt_segment)->accessed__type__sflag__dpl__present & 0x0e ) >> 1 )
|
||||
#define GDT_SEGMENT_SIZE(gdt_segment) \
|
||||
( ( (gdt_segment)->limit_16_19__avl__size__granularity \
|
||||
& 0x60 ) >> 5 )
|
||||
|
||||
#define GDT_TYPE_DATA (0x0)
|
||||
#define GDT_TYPE_STACK (0x2)
|
||||
#define GDT_TYPE_WRITEABLE (0x1)
|
||||
#define GDT_TYPE_CODE (0x6)
|
||||
#define GDT_TYPE_EXEC_ONLY_CODE (0x4)
|
||||
#define GDT_TYPE_CONFORMING (0x1)
|
||||
#define GDT_SFLAG_SYSTEM (0)
|
||||
#define GDT_SFLAG_NORMAL (1)
|
||||
#define GDT_AVL_NORMAL (0)
|
||||
#define GDT_SIZE_16BIT (0x0)
|
||||
#define GDT_SIZE_32BIT (0x2)
|
||||
#define GDT_SIZE_64BIT (0x1)
|
||||
#define GDT_SIZE_UNKNOWN (0x3)
|
||||
#define GDT_GRANULARITY_SMALL (0)
|
||||
#define GDT_GRANULARITY_LARGE (1)
|
||||
#define GDT_SEGMENT_NORMAL(base,limit,type,size,granularity) \
|
||||
GDT_SEGMENT ( base, limit, type, \
|
||||
GDT_SFLAG_NORMAL, 0, GDT_AVL_NORMAL, \
|
||||
size, granularity )
|
||||
|
||||
/* Protected mode code segment */
|
||||
#define GDT_SEGMENT_PMCS(base) GDT_SEGMENT_NORMAL ( \
|
||||
base, 0xfffff, GDT_TYPE_CODE | GDT_TYPE_CONFORMING, \
|
||||
GDT_SIZE_32BIT, GDT_GRANULARITY_LARGE )
|
||||
#define GDT_SEGMENT_PMCS_PHYS GDT_SEGMENT_PMCS(0)
|
||||
/* Protected mode data segment */
|
||||
#define GDT_SEGMENT_PMDS(base) GDT_SEGMENT_NORMAL ( \
|
||||
base, 0xfffff, GDT_TYPE_DATA | GDT_TYPE_WRITEABLE, \
|
||||
GDT_SIZE_32BIT, GDT_GRANULARITY_LARGE )
|
||||
#define GDT_SEGMENT_PMDS_PHYS GDT_SEGMENT_PMDS(0)
|
||||
/* Real mode code segment */
|
||||
/* Not sure if there's any reason to use GDT_TYPE_EXEC_ONLY_CODE
|
||||
* instead of just GDT_TYPE_CODE, but that's what our old GDT did and
|
||||
* it worked, so I'm not changing it.
|
||||
*/
|
||||
#define GDT_SEGMENT_RMCS(base) GDT_SEGMENT_NORMAL ( \
|
||||
base, 0xffff, GDT_TYPE_EXEC_ONLY_CODE | GDT_TYPE_CONFORMING, \
|
||||
GDT_SIZE_16BIT, GDT_GRANULARITY_SMALL )
|
||||
/* Real mode data segment */
|
||||
#define GDT_SEGMENT_RMDS(base) GDT_SEGMENT_NORMAL ( \
|
||||
base, 0xffff, GDT_TYPE_DATA | GDT_TYPE_WRITEABLE, \
|
||||
GDT_SIZE_16BIT, GDT_GRANULARITY_SMALL )
|
||||
/* Long mode code segment */
|
||||
#define GDT_SEGMENT_LMCS(base) GDT_SEGMENT_NORMAL ( \
|
||||
base, 0xfffff, GDT_TYPE_CODE | GDT_TYPE_CONFORMING, \
|
||||
GDT_SIZE_64BIT, GDT_GRANULARITY_LARGE )
|
||||
#define GDT_SEGMENT_LMCS_PHYS GDT_SEGMENT_LMCS(0)
|
||||
/* Long mode data segment */
|
||||
/* AFIACT, GDT_SIZE_64BIT applies only to code segments */
|
||||
#define GDT_SEGMENT_LMDS(base) GDT_SEGMENT_NORMAL ( \
|
||||
base, 0xfffff, GDT_TYPE_DATA | GDT_TYPE_WRITEABLE, \
|
||||
GDT_SIZE_32BIT, GDT_GRANULARITY_LARGE )
|
||||
#define GDT_SEGMENT_LMDS_PHYS GDT_SEGMENT_LMDS(0)
|
||||
|
||||
/* Template for creating GDT structures (including segment register
|
||||
* lists), suitable for passing as parameters to external_call().
|
||||
*/
|
||||
#define GDT_STRUCT_t(num_segments) \
|
||||
struct { \
|
||||
gdt_descriptor_t descriptor; \
|
||||
gdt_segment_t segments[num_segments]; \
|
||||
} PACKED
|
||||
/* And utility function for filling it in */
|
||||
#define GDT_ADJUST(structure) { \
|
||||
(structure)->descriptor.address = \
|
||||
virt_to_phys(&((structure)->descriptor.limit)); \
|
||||
(structure)->descriptor.limit = \
|
||||
sizeof((structure)->segments) + 8 - 1; \
|
||||
(structure)->descriptor.padding = 0; \
|
||||
}
|
||||
|
||||
/* Data passed in to in_call() by assembly wrapper.
|
||||
*/
|
||||
typedef struct {
|
||||
regs_t regs;
|
||||
seg_regs_t seg_regs;
|
||||
gdt_descriptor_t gdt_desc;
|
||||
uint32_t flags;
|
||||
struct {
|
||||
uint32_t offset;
|
||||
uint32_t segment;
|
||||
} ret_addr;
|
||||
} PACKED i386_pm_in_call_data_t;
|
||||
|
||||
typedef struct {
|
||||
seg_regs_t seg_regs;
|
||||
union {
|
||||
uint16_t pad;
|
||||
uint16_t prefix_sp;
|
||||
};
|
||||
uint16_t flags;
|
||||
struct {
|
||||
uint16_t offset;
|
||||
uint16_t segment;
|
||||
} ret_addr;
|
||||
uint32_t orig_opcode;
|
||||
} PACKED i386_rm_in_call_data_t;
|
||||
|
||||
typedef struct {
|
||||
i386_pm_in_call_data_t *pm;
|
||||
i386_rm_in_call_data_t *rm;
|
||||
} i386_in_call_data_t;
|
||||
#define in_call_data_t i386_in_call_data_t
|
||||
|
||||
/* Function prototypes
|
||||
*/
|
||||
extern int install_rm_callback_interface ( void *address, size_t available );
|
||||
|
||||
#endif /* ASSEMBLY */
|
||||
|
||||
#define RM_IN_CALL (0)
|
||||
#define RM_IN_CALL_FAR (2)
|
||||
|
||||
#endif /* CALLBACKS_ARCH_H */
|
||||
21
src/arch/i386/include/hidemem.h
Normal file
21
src/arch/i386/include/hidemem.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef HIDEMEM_H
|
||||
#define HIDEMEM_H
|
||||
|
||||
#include "segoff.h"
|
||||
|
||||
extern int install_e820mangler ( void *new_mangler );
|
||||
extern int hide_etherboot ( void );
|
||||
extern int unhide_etherboot ( void );
|
||||
|
||||
/* Symbols in e820mangler.S */
|
||||
extern void e820mangler ( void );
|
||||
extern void _intercept_int15 ( void );
|
||||
extern segoff_t _intercepted_int15;
|
||||
typedef struct {
|
||||
uint32_t start;
|
||||
uint32_t length;
|
||||
} exclude_range_t;
|
||||
extern exclude_range_t _hide_memory[2];
|
||||
extern uint16_t e820mangler_size;
|
||||
|
||||
#endif /* HIDEMEM_H */
|
||||
9
src/arch/i386/include/hooks.h
Normal file
9
src/arch/i386/include/hooks.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef ETHERBOOT_I386_HOOKS_H
|
||||
#define ETHERBOOT_I386_HOOKS_H
|
||||
|
||||
void arch_main(in_call_data_t *data, va_list params);
|
||||
void arch_on_exit(int status);
|
||||
#define arch_relocate_to(addr)
|
||||
void arch_relocated_from ( uint32_t old_addr );
|
||||
|
||||
#endif /* ETHERBOOT_I386_HOOKS_H */
|
||||
246
src/arch/i386/include/io.h
Normal file
246
src/arch/i386/include/io.h
Normal file
@@ -0,0 +1,246 @@
|
||||
#ifndef ETHERBOOT_IO_H
|
||||
#define ETHERBOOT_IO_H
|
||||
|
||||
|
||||
/* Amount of relocation etherboot is experiencing */
|
||||
extern unsigned long virt_offset;
|
||||
|
||||
/* Don't require identity mapped physical memory,
|
||||
* osloader.c is the only valid user at the moment.
|
||||
*/
|
||||
static inline unsigned long virt_to_phys(volatile const void *virt_addr)
|
||||
{
|
||||
return ((unsigned long)virt_addr) + virt_offset;
|
||||
}
|
||||
|
||||
static inline void *phys_to_virt(unsigned long phys_addr)
|
||||
{
|
||||
return (void *)(phys_addr - virt_offset);
|
||||
}
|
||||
|
||||
/* virt_to_bus converts an addresss inside of etherboot [_start, _end]
|
||||
* into a memory access cards can use.
|
||||
*/
|
||||
#define virt_to_bus virt_to_phys
|
||||
|
||||
|
||||
/* bus_to_virt reverses virt_to_bus, the address must be output
|
||||
* from virt_to_bus to be valid. This function does not work on
|
||||
* all bus addresses.
|
||||
*/
|
||||
#define bus_to_virt phys_to_virt
|
||||
|
||||
/* ioremap converts a random 32bit bus address into something
|
||||
* etherboot can access.
|
||||
*/
|
||||
static inline void *ioremap(unsigned long bus_addr, unsigned long length __unused)
|
||||
{
|
||||
return bus_to_virt(bus_addr);
|
||||
}
|
||||
|
||||
/* iounmap cleans up anything ioremap had to setup */
|
||||
static inline void iounmap(void *virt_addr __unused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This file contains the definitions for the x86 IO instructions
|
||||
* inb/inw/inl/outb/outw/outl and the "string versions" of the same
|
||||
* (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
|
||||
* versions of the single-IO instructions (inb_p/inw_p/..).
|
||||
*
|
||||
* This file is not meant to be obfuscating: it's just complicated
|
||||
* to (a) handle it all in a way that makes gcc able to optimize it
|
||||
* as well as possible and (b) trying to avoid writing the same thing
|
||||
* over and over again with slight variations and possibly making a
|
||||
* mistake somewhere.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Thanks to James van Artsdalen for a better timing-fix than
|
||||
* the two short jumps: using outb's to a nonexistent port seems
|
||||
* to guarantee better timings even on fast machines.
|
||||
*
|
||||
* On the other hand, I'd like to be sure of a non-existent port:
|
||||
* I feel a bit unsafe about using 0x80 (should be safe, though)
|
||||
*
|
||||
* Linus
|
||||
*/
|
||||
|
||||
#ifdef SLOW_IO_BY_JUMPING
|
||||
#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
|
||||
#else
|
||||
#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
|
||||
#endif
|
||||
|
||||
#ifdef REALLY_SLOW_IO
|
||||
#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
|
||||
#else
|
||||
#define SLOW_DOWN_IO __SLOW_DOWN_IO
|
||||
#endif
|
||||
|
||||
/*
|
||||
* readX/writeX() are used to access memory mapped devices. On some
|
||||
* architectures the memory mapped IO stuff needs to be accessed
|
||||
* differently. On the x86 architecture, we just read/write the
|
||||
* memory location directly.
|
||||
*/
|
||||
#define readb(addr) (*(volatile unsigned char *) (addr))
|
||||
#define readw(addr) (*(volatile unsigned short *) (addr))
|
||||
#define readl(addr) (*(volatile unsigned int *) (addr))
|
||||
|
||||
#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
|
||||
#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
|
||||
#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
|
||||
|
||||
#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
|
||||
#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
|
||||
|
||||
/*
|
||||
* Force strict CPU ordering.
|
||||
* And yes, this is required on UP too when we're talking
|
||||
* to devices.
|
||||
*
|
||||
* For now, "wmb()" doesn't actually do anything, as all
|
||||
* Intel CPU's follow what Intel calls a *Processor Order*,
|
||||
* in which all writes are seen in the program order even
|
||||
* outside the CPU.
|
||||
*
|
||||
* I expect future Intel CPU's to have a weaker ordering,
|
||||
* but I'd also expect them to finally get their act together
|
||||
* and add some real memory barriers if so.
|
||||
*
|
||||
* Some non intel clones support out of order store. wmb() ceases to be a
|
||||
* nop for these.
|
||||
*/
|
||||
|
||||
#define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
|
||||
#define rmb() mb()
|
||||
#define wmb() mb();
|
||||
|
||||
|
||||
/*
|
||||
* Talk about misusing macros..
|
||||
*/
|
||||
|
||||
#define __OUT1(s,x) \
|
||||
extern void __out##s(unsigned x value, unsigned short port); \
|
||||
extern inline void __out##s(unsigned x value, unsigned short port) {
|
||||
|
||||
#define __OUT2(s,s1,s2) \
|
||||
__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
|
||||
|
||||
#define __OUT(s,s1,x) \
|
||||
__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); } \
|
||||
__OUT1(s##c,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); } \
|
||||
__OUT1(s##_p,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); SLOW_DOWN_IO; } \
|
||||
__OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); SLOW_DOWN_IO; }
|
||||
|
||||
#define __IN1(s,x) \
|
||||
extern unsigned x __in##s(unsigned short port); \
|
||||
extern inline unsigned x __in##s(unsigned short port) { unsigned x _v;
|
||||
|
||||
#define __IN2(s,s1,s2) \
|
||||
__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
|
||||
|
||||
#define __IN(s,s1,x,i...) \
|
||||
__IN1(s,x) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); return _v; } \
|
||||
__IN1(s##c,x) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); return _v; } \
|
||||
__IN1(s##_p,x) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; return _v; } \
|
||||
__IN1(s##c_p,x) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; }
|
||||
|
||||
#define __INS(s) \
|
||||
extern void ins##s(unsigned short port, void * addr, unsigned long count); \
|
||||
extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \
|
||||
{ __asm__ __volatile__ ("cld ; rep ; ins" #s \
|
||||
: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
|
||||
|
||||
#define __OUTS(s) \
|
||||
extern void outs##s(unsigned short port, const void * addr, unsigned long count); \
|
||||
extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
|
||||
{ __asm__ __volatile__ ("cld ; rep ; outs" #s \
|
||||
: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
|
||||
|
||||
__IN(b,"", char)
|
||||
__IN(w,"",short)
|
||||
__IN(l,"", long)
|
||||
|
||||
__OUT(b,"b",char)
|
||||
__OUT(w,"w",short)
|
||||
__OUT(l,,int)
|
||||
|
||||
__INS(b)
|
||||
__INS(w)
|
||||
__INS(l)
|
||||
|
||||
__OUTS(b)
|
||||
__OUTS(w)
|
||||
__OUTS(l)
|
||||
|
||||
/*
|
||||
* Note that due to the way __builtin_constant_p() works, you
|
||||
* - can't use it inside a inline function (it will never be true)
|
||||
* - you don't have to worry about side effects within the __builtin..
|
||||
*/
|
||||
#define outb(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outbc((val),(port)) : \
|
||||
__outb((val),(port)))
|
||||
|
||||
#define inb(port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__inbc(port) : \
|
||||
__inb(port))
|
||||
|
||||
#define outb_p(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outbc_p((val),(port)) : \
|
||||
__outb_p((val),(port)))
|
||||
|
||||
#define inb_p(port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__inbc_p(port) : \
|
||||
__inb_p(port))
|
||||
|
||||
#define outw(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outwc((val),(port)) : \
|
||||
__outw((val),(port)))
|
||||
|
||||
#define inw(port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__inwc(port) : \
|
||||
__inw(port))
|
||||
|
||||
#define outw_p(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outwc_p((val),(port)) : \
|
||||
__outw_p((val),(port)))
|
||||
|
||||
#define inw_p(port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__inwc_p(port) : \
|
||||
__inw_p(port))
|
||||
|
||||
#define outl(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outlc((val),(port)) : \
|
||||
__outl((val),(port)))
|
||||
|
||||
#define inl(port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__inlc(port) : \
|
||||
__inl(port))
|
||||
|
||||
#define outl_p(val,port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__outlc_p((val),(port)) : \
|
||||
__outl_p((val),(port)))
|
||||
|
||||
#define inl_p(port) \
|
||||
((__builtin_constant_p((port)) && (port) < 256) ? \
|
||||
__inlc_p(port) : \
|
||||
__inl_p(port))
|
||||
|
||||
#endif /* ETHERBOOT_IO_H */
|
||||
10
src/arch/i386/include/latch.h
Normal file
10
src/arch/i386/include/latch.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef LATCH_H
|
||||
#define LATCH_H
|
||||
|
||||
#define TICKS_PER_SEC 18
|
||||
|
||||
/* For different calibrators of the TSC move the declaration of
|
||||
* sleep_latch and the definitions of it's length here...
|
||||
*/
|
||||
|
||||
#endif /* LATCH_H */
|
||||
59
src/arch/i386/include/limits.h
Normal file
59
src/arch/i386/include/limits.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef LIMITS_H
|
||||
#define LIMITS_H 1
|
||||
|
||||
/* Number of bits in a `char' */
|
||||
#define CHAR_BIT 8
|
||||
|
||||
/* Minimum and maximum values a `signed char' can hold */
|
||||
#define SCHAR_MIN (-128)
|
||||
#define SCHAR_MAX 127
|
||||
|
||||
/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */
|
||||
#define UCHAR_MAX 255
|
||||
|
||||
/* Minimum and maximum values a `char' can hold */
|
||||
#define CHAR_MIN SCHAR_MIN
|
||||
#define CHAR_MAX SCHAR_MAX
|
||||
|
||||
/* Minimum and maximum values a `signed short int' can hold */
|
||||
#define SHRT_MIN (-32768)
|
||||
#define SHRT_MAX 32767
|
||||
|
||||
/* Maximum value an `unsigned short' can hold. (Minimum is 0.) */
|
||||
#define USHRT_MAX 65535
|
||||
|
||||
|
||||
/* Minimum and maximum values a `signed int' can hold */
|
||||
#define INT_MIN (-INT_MAX - 1)
|
||||
#define INT_MAX 2147483647
|
||||
|
||||
/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
|
||||
#define UINT_MAX 4294967295U
|
||||
|
||||
|
||||
/* Minimum and maximum values a `signed int' can hold */
|
||||
#define INT_MAX 2147483647
|
||||
#define INT_MIN (-INT_MAX - 1)
|
||||
|
||||
|
||||
/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
|
||||
#define UINT_MAX 4294967295U
|
||||
|
||||
|
||||
/* Minimum and maximum values a `signed long' can hold */
|
||||
#define LONG_MAX 2147483647
|
||||
#define LONG_MIN (-LONG_MAX - 1L)
|
||||
|
||||
/* Maximum value an `unsigned long' can hold. (Minimum is 0.) */
|
||||
#define ULONG_MAX 4294967295UL
|
||||
|
||||
/* Minimum and maximum values a `signed long long' can hold */
|
||||
#define LLONG_MAX 9223372036854775807LL
|
||||
#define LLONG_MIN (-LONG_MAX - 1LL)
|
||||
|
||||
|
||||
/* Maximum value an `unsigned long long' can hold. (Minimum is 0.) */
|
||||
#define ULLONG_MAX 18446744073709551615ULL
|
||||
|
||||
|
||||
#endif /* LIMITS_H */
|
||||
96
src/arch/i386/include/pic8259.h
Normal file
96
src/arch/i386/include/pic8259.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Basic support for controlling the 8259 Programmable Interrupt Controllers.
|
||||
*
|
||||
* Initially written by Michael Brown (mcb30).
|
||||
*/
|
||||
|
||||
#ifndef PIC8259_H
|
||||
#define PIC8259_H
|
||||
|
||||
/* For segoff_t */
|
||||
#include "segoff.h"
|
||||
|
||||
#define IRQ_PIC_CUTOFF (8)
|
||||
|
||||
/* 8259 register locations */
|
||||
#define PIC1_ICW1 (0x20)
|
||||
#define PIC1_OCW2 (0x20)
|
||||
#define PIC1_OCW3 (0x20)
|
||||
#define PIC1_ICR (0x20)
|
||||
#define PIC1_IRR (0x20)
|
||||
#define PIC1_ISR (0x20)
|
||||
#define PIC1_ICW2 (0x21)
|
||||
#define PIC1_ICW3 (0x21)
|
||||
#define PIC1_ICW4 (0x21)
|
||||
#define PIC1_IMR (0x21)
|
||||
#define PIC2_ICW1 (0xa0)
|
||||
#define PIC2_OCW2 (0xa0)
|
||||
#define PIC2_OCW3 (0xa0)
|
||||
#define PIC2_ICR (0xa0)
|
||||
#define PIC2_IRR (0xa0)
|
||||
#define PIC2_ISR (0xa0)
|
||||
#define PIC2_ICW2 (0xa1)
|
||||
#define PIC2_ICW3 (0xa1)
|
||||
#define PIC2_ICW4 (0xa1)
|
||||
#define PIC2_IMR (0xa1)
|
||||
|
||||
/* Register command values */
|
||||
#define OCW3_ID (0x08)
|
||||
#define OCW3_READ_IRR (0x03)
|
||||
#define OCW3_READ_ISR (0x02)
|
||||
#define ICR_EOI_NON_SPECIFIC (0x20)
|
||||
#define ICR_EOI_NOP (0x40)
|
||||
#define ICR_EOI_SPECIFIC (0x60)
|
||||
#define ICR_EOI_SET_PRIORITY (0xc0)
|
||||
|
||||
/* Macros to enable/disable IRQs */
|
||||
#define IMR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_IMR : PIC2_IMR )
|
||||
#define IMR_BIT(x) ( 1 << ( (x) % IRQ_PIC_CUTOFF ) )
|
||||
#define irq_enabled(x) ( ( inb ( IMR_REG(x) ) & IMR_BIT(x) ) == 0 )
|
||||
#define enable_irq(x) outb ( inb( IMR_REG(x) ) & ~IMR_BIT(x), IMR_REG(x) )
|
||||
#define disable_irq(x) outb ( inb( IMR_REG(x) ) | IMR_BIT(x), IMR_REG(x) )
|
||||
|
||||
/* Macros for acknowledging IRQs */
|
||||
#define ICR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_ICR : PIC2_ICR )
|
||||
#define ICR_VALUE(x) ( (x) % IRQ_PIC_CUTOFF )
|
||||
#define CHAINED_IRQ 2
|
||||
|
||||
/* Utility macros to convert IRQ numbers to INT numbers and INT vectors */
|
||||
#define IRQ_INT(x) ( (x)<IRQ_PIC_CUTOFF ? (x)+0x08 : (x)-IRQ_PIC_CUTOFF+0x70 )
|
||||
#define INT_VECTOR(x) ( (segoff_t*) phys_to_virt( 4 * (x) ) )
|
||||
#define IRQ_VECTOR(x) ( INT_VECTOR ( IRQ_INT(x) ) )
|
||||
|
||||
/* Other constants */
|
||||
typedef uint8_t irq_t;
|
||||
#define IRQ_MAX (15)
|
||||
#define IRQ_NONE (0xff)
|
||||
|
||||
/* Function prototypes
|
||||
*/
|
||||
int install_irq_handler ( irq_t irq, segoff_t *handler,
|
||||
uint8_t *previously_enabled,
|
||||
segoff_t *previous_handler );
|
||||
int remove_irq_handler ( irq_t irq, segoff_t *handler,
|
||||
uint8_t *previously_enabled,
|
||||
segoff_t *previous_handler );
|
||||
int install_trivial_irq_handler ( irq_t irq );
|
||||
int remove_trivial_irq_handler ( irq_t irq );
|
||||
int trivial_irq_triggered ( irq_t irq );
|
||||
int copy_trivial_irq_handler ( void *target, size_t target_size );
|
||||
void send_non_specific_eoi ( irq_t irq );
|
||||
void send_specific_eoi ( irq_t irq );
|
||||
void fake_irq ( irq_t irq );
|
||||
#ifdef DEBUG_IRQ
|
||||
void dump_irq_status ( void );
|
||||
#else
|
||||
#define dump_irq_status()
|
||||
#endif
|
||||
|
||||
/* Other code (e.g. undi.c) needs to know the size of the trivial IRQ
|
||||
* handler code, so we put prototypes and the size macro here.
|
||||
*/
|
||||
extern void _trivial_irq_handler ( void );
|
||||
extern void _trivial_irq_handler_end ( void );
|
||||
#define TRIVIAL_IRQ_HANDLER_SIZE FRAGMENT_SIZE(_trivial_irq_handler)
|
||||
|
||||
#endif /* PIC8259_H */
|
||||
33
src/arch/i386/include/pxe_callbacks.h
Normal file
33
src/arch/i386/include/pxe_callbacks.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* Header for pxe_callbacks.c.
|
||||
*/
|
||||
|
||||
#ifndef PXE_CALLBACKS_H
|
||||
#define PXE_CALLBACKS_H
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "segoff.h"
|
||||
#include "pxe.h"
|
||||
|
||||
typedef struct {
|
||||
segoff_t orig_retaddr;
|
||||
uint16_t opcode;
|
||||
segoff_t segoff;
|
||||
} PACKED pxe_call_params_t;
|
||||
|
||||
/*
|
||||
* These values are hard-coded into the PXE spec
|
||||
*/
|
||||
#define PXE_LOAD_SEGMENT (0x0000)
|
||||
#define PXE_LOAD_OFFSET (0x7c00)
|
||||
#define PXE_LOAD_ADDRESS ( ( PXE_LOAD_SEGMENT << 4 ) + PXE_LOAD_OFFSET )
|
||||
|
||||
/* Function prototypes
|
||||
*/
|
||||
extern pxe_stack_t * install_pxe_stack ( void *base );
|
||||
extern void use_undi_ds_for_rm_stack ( uint16_t ds );
|
||||
extern int hook_pxe_stack ( void );
|
||||
extern int unhook_pxe_stack ( void );
|
||||
extern void remove_pxe_stack ( void );
|
||||
extern int xstartpxe ( void );
|
||||
|
||||
#endif /* PXE_CALLBACKS_H */
|
||||
35
src/arch/i386/include/pxe_types.h
Normal file
35
src/arch/i386/include/pxe_types.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Architecture-specific portion of pxe.h for Etherboot
|
||||
*
|
||||
* This file has to define the types SEGOFF16_t, SEGDESC_t and
|
||||
* SEGSEL_t for use in other PXE structures. See pxe.h for details.
|
||||
*/
|
||||
|
||||
#ifndef PXE_TYPES_H
|
||||
#define PXE_TYPES_H
|
||||
|
||||
/* SEGOFF16_t defined in separate header
|
||||
*/
|
||||
#include "segoff.h"
|
||||
typedef segoff_t I386_SEGOFF16_t;
|
||||
#define SEGOFF16_t I386_SEGOFF16_t
|
||||
|
||||
#define IS_NULL_SEGOFF16(x) ( ( (x).segment == 0 ) && ( (x).offset == 0 ) )
|
||||
#define SEGOFF16_TO_PTR(x) ( VIRTUAL( (x).segment, (x).offset ) )
|
||||
#define PTR_TO_SEGOFF16(ptr,segoff16) \
|
||||
(segoff16).segment = SEGMENT(ptr); \
|
||||
(segoff16).offset = OFFSET(ptr);
|
||||
|
||||
typedef struct {
|
||||
uint16_t Seg_Addr;
|
||||
uint32_t Phy_Addr;
|
||||
uint16_t Seg_Size;
|
||||
} PACKED I386_SEGDESC_t; /* PACKED is required, otherwise gcc pads
|
||||
* this out to 12 bytes -
|
||||
* mbrown@fensystems.co.uk (mcb30) 17/5/03 */
|
||||
#define SEGDESC_t I386_SEGDESC_t
|
||||
|
||||
typedef uint16_t I386_SEGSEL_t;
|
||||
#define SEGSEL_t I386_SEGSEL_t
|
||||
|
||||
#endif /* PXE_TYPES_H */
|
||||
124
src/arch/i386/include/realmode.h
Normal file
124
src/arch/i386/include/realmode.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/* Real-mode interface
|
||||
*/
|
||||
|
||||
#ifndef ASSEMBLY
|
||||
|
||||
#include "etherboot.h"
|
||||
#include "segoff.h"
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
union {
|
||||
uint8_t l;
|
||||
uint8_t byte;
|
||||
};
|
||||
uint8_t h;
|
||||
} PACKED;
|
||||
uint16_t word;
|
||||
} PACKED reg16_t;
|
||||
|
||||
typedef union {
|
||||
reg16_t w;
|
||||
uint32_t dword;
|
||||
} PACKED reg32_t;
|
||||
|
||||
/* Macros to help with defining inline real-mode trampoline fragments.
|
||||
*/
|
||||
#define RM_XSTR(x) #x /* Macro hackery needed to stringify */
|
||||
#define RM_STR(x) RM_XSTR(x)
|
||||
#define RM_FRAGMENT(name, asm_code_str) \
|
||||
extern void name ( void ); \
|
||||
extern void name ## _end (void); \
|
||||
__asm__( \
|
||||
".section \".text16\"\n\t" \
|
||||
".code16\n\t" \
|
||||
".arch i386\n\t" \
|
||||
".globl " #name " \n\t" \
|
||||
#name ":\n\t" \
|
||||
asm_code_str "\n\t" \
|
||||
".globl " #name "_end\n\t" \
|
||||
#name "_end:\n\t" \
|
||||
".code32\n\t" \
|
||||
".previous\n\t" \
|
||||
)
|
||||
|
||||
#define FRAGMENT_SIZE(fragment) ( (size_t) ( ( (void*) fragment ## _end )\
|
||||
- ( (void*) (fragment) ) ) )
|
||||
|
||||
/* Data structures in _prot_to_real and _real_to_prot. These
|
||||
* structures are accessed by assembly code as well as C code.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t esp;
|
||||
uint16_t cs;
|
||||
uint16_t ss;
|
||||
uint32_t r2p_params;
|
||||
} PACKED prot_to_real_params_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t ret_addr;
|
||||
uint32_t esp;
|
||||
uint32_t ebx;
|
||||
uint32_t esi;
|
||||
uint32_t edi;
|
||||
uint32_t ebp;
|
||||
uint32_t out_stack;
|
||||
uint32_t out_stack_len;
|
||||
} PACKED real_to_prot_params_t;
|
||||
|
||||
/* Function prototypes: realmode.c
|
||||
*/
|
||||
#define real_call( fragment, in_stack, out_stack ) \
|
||||
_real_call ( fragment, FRAGMENT_SIZE(fragment), \
|
||||
(void*)(in_stack), \
|
||||
( (in_stack) == NULL ? 0 : sizeof(*(in_stack)) ), \
|
||||
(void*)(out_stack), \
|
||||
( (out_stack) == NULL ? 0 : sizeof(*(out_stack)) ) )
|
||||
extern uint16_t _real_call ( void *fragment, int fragment_len,
|
||||
void *in_stack, int in_stack_len,
|
||||
void *out_stack, int out_stack_len );
|
||||
/* Function prototypes: realmode_asm.S
|
||||
*/
|
||||
extern void rm_callback_interface;
|
||||
extern uint16_t rm_callback_interface_size;
|
||||
extern uint32_t rm_etherboot_location;
|
||||
extern void _rm_in_call ( void );
|
||||
extern void _rm_in_call_far ( void );
|
||||
|
||||
extern void _prot_to_real_prefix ( void );
|
||||
extern void _prot_to_real_prefix_end ( void );
|
||||
extern uint16_t prot_to_real_prefix_size;
|
||||
|
||||
extern void _real_to_prot_suffix ( void );
|
||||
extern void _real_to_prot_suffix_end ( void );
|
||||
extern uint16_t real_to_prot_suffix_size;
|
||||
|
||||
/* PXE assembler bits */
|
||||
extern void pxe_callback_interface;
|
||||
extern uint16_t pxe_callback_interface_size;
|
||||
extern void _pxe_in_call_far ( void );
|
||||
extern void _pxenv_in_call_far ( void );
|
||||
extern void _pxe_intercept_int1a ( void );
|
||||
extern segoff_t _pxe_intercepted_int1a;
|
||||
extern segoff_t _pxe_pxenv_location;
|
||||
|
||||
/* Global variables
|
||||
*/
|
||||
extern uint32_t real_mode_stack;
|
||||
extern size_t real_mode_stack_size;
|
||||
extern int lock_real_mode_stack;
|
||||
|
||||
|
||||
/* Function prototypes from basemem.c
|
||||
*/
|
||||
#ifdef LINUXBIOS
|
||||
/* A silly hard code that let's the code compile and work.
|
||||
* When this becomes a problem feel free to implement
|
||||
* something better.
|
||||
*/
|
||||
static inline void allot_real_mode_stack(void) { real_mode_stack = 0x7c00; }
|
||||
#else
|
||||
void allot_real_mode_stack(void);
|
||||
#endif
|
||||
|
||||
#endif /* ASSEMBLY */
|
||||
41
src/arch/i386/include/segoff.h
Normal file
41
src/arch/i386/include/segoff.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Segment:offset types and macros
|
||||
*
|
||||
* Initially written by Michael Brown (mcb30).
|
||||
*/
|
||||
|
||||
#ifndef SEGOFF_H
|
||||
#define SEGOFF_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osdep.h>
|
||||
#include <io.h>
|
||||
|
||||
/* Segment:offset structure. Note that the order within the structure
|
||||
* is offset:segment.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t offset;
|
||||
uint16_t segment;
|
||||
} segoff_t;
|
||||
|
||||
/* Macros for converting from virtual to segment:offset addresses,
|
||||
* when we don't actually care which of the many isomorphic results we
|
||||
* get.
|
||||
*/
|
||||
#ifdef DEBUG_SEGMENT
|
||||
uint16_t SEGMENT ( const void * const ptr ) {
|
||||
uint32_t phys = virt_to_phys ( ptr );
|
||||
if ( phys > 0xfffff ) {
|
||||
printf ( "FATAL ERROR: segment address out of range\n" );
|
||||
}
|
||||
return phys >> 4;
|
||||
}
|
||||
#else
|
||||
#define SEGMENT(x) ( virt_to_phys ( x ) >> 4 )
|
||||
#endif
|
||||
#define OFFSET(x) ( virt_to_phys ( x ) & 0xf )
|
||||
#define SEGOFF(x) { OFFSET(x), SEGMENT(x) }
|
||||
#define VIRTUAL(x,y) ( phys_to_virt ( ( ( x ) << 4 ) + ( y ) ) )
|
||||
|
||||
#endif /* SEGOFF_H */
|
||||
12
src/arch/i386/include/setjmp.h
Normal file
12
src/arch/i386/include/setjmp.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef ETHERBOOT_SETJMP_H
|
||||
#define ETHERBOOT_SETJMP_H
|
||||
|
||||
|
||||
/* Define a type for use by setjmp and longjmp */
|
||||
#define JBLEN 6
|
||||
typedef unsigned long jmp_buf[JBLEN];
|
||||
|
||||
extern int setjmp (jmp_buf env);
|
||||
extern void longjmp (jmp_buf env, int val);
|
||||
|
||||
#endif /* ETHERBOOT_SETJMP_H */
|
||||
16
src/arch/i386/include/stdint.h
Normal file
16
src/arch/i386/include/stdint.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef STDINT_H
|
||||
#define STDINT_H
|
||||
|
||||
typedef unsigned size_t;
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned long uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed long int32_t;
|
||||
typedef signed long long int64_t;
|
||||
|
||||
#endif /* STDINT_H */
|
||||
228
src/arch/i386/include/vga.h
Normal file
228
src/arch/i386/include/vga.h
Normal 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
|
||||
Reference in New Issue
Block a user