diff --git a/util/baremetal/include/boot/elf.h b/util/baremetal/include/boot/elf.h new file mode 100644 index 0000000000..d7e9e03467 --- /dev/null +++ b/util/baremetal/include/boot/elf.h @@ -0,0 +1,404 @@ +#ifndef ELF_H +#define ELF_H + +/* Standard ELF types. */ + +#include +#include +#include + +/* Type for a 16-bit quantity. */ +typedef uint16_t Elf32_Half; +typedef uint16_t Elf64_Half; + +/* Types for signed and unsigned 32-bit quantities. */ +typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; +typedef uint32_t Elf64_Word; +typedef int32_t Elf64_Sword; + +/* Types for signed and unsigned 64-bit quantities. */ +typedef uint64_t Elf32_Xword; +typedef int64_t Elf32_Sxword; +typedef uint64_t Elf64_Xword; +typedef int64_t Elf64_Sxword; + +/* Type of addresses. */ +typedef uint32_t Elf32_Addr; +typedef uint64_t Elf64_Addr; + +/* Type of file offsets. */ +typedef uint32_t Elf32_Off; +typedef uint64_t Elf64_Off; + +/* Type for section indices, which are 16-bit quantities. */ +typedef uint16_t Elf32_Section; +typedef uint16_t Elf64_Section; + +/* Type of symbol indices. */ +typedef uint32_t Elf32_Symndx; +typedef uint64_t Elf64_Symndx; + + +/* The ELF file header. This appears at the start of every ELF file. */ + +#define EI_NIDENT (16) + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf32_Half e_type; /* Object file type */ + Elf32_Half e_machine; /* Architecture */ + Elf32_Word e_version; /* Object file version */ + Elf32_Addr e_entry; /* Entry point virtual address */ + Elf32_Off e_phoff; /* Program header table file offset */ + Elf32_Off e_shoff; /* Section header table file offset */ + Elf32_Word e_flags; /* Processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size in bytes */ + Elf32_Half e_phentsize; /* Program header table entry size */ + Elf32_Half e_phnum; /* Program header table entry count */ + Elf32_Half e_shentsize; /* Section header table entry size */ + Elf32_Half e_shnum; /* Section header table entry count */ + Elf32_Half e_shstrndx; /* Section header string table index */ +} Elf32_Ehdr; + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf64_Half e_type; /* Object file type */ + Elf64_Half e_machine; /* Architecture */ + Elf64_Word e_version; /* Object file version */ + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; /* Processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size in bytes */ + Elf64_Half e_phentsize; /* Program header table entry size */ + Elf64_Half e_phnum; /* Program header table entry count */ + Elf64_Half e_shentsize; /* Section header table entry size */ + Elf64_Half e_shnum; /* Section header table entry count */ + Elf64_Half e_shstrndx; /* Section header string table index */ +} Elf64_Ehdr; + +/* Fields in the e_ident array. The EI_* macros are indices into the + array. The macros under each EI_* macro are the values the byte + may have. */ + +#define EI_MAG0 0 /* File identification byte 0 index */ +#define ELFMAG0 0x7f /* Magic number byte 0 */ + +#define EI_MAG1 1 /* File identification byte 1 index */ +#define ELFMAG1 'E' /* Magic number byte 1 */ + +#define EI_MAG2 2 /* File identification byte 2 index */ +#define ELFMAG2 'L' /* Magic number byte 2 */ + +#define EI_MAG3 3 /* File identification byte 3 index */ +#define ELFMAG3 'F' /* Magic number byte 3 */ + +/* Conglomeration of the identification bytes, for easy testing as a word. */ +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASSNONE 0 /* Invalid class */ +#define ELFCLASS32 1 /* 32-bit objects */ +#define ELFCLASS64 2 /* 64-bit objects */ +#define ELFCLASSNUM 3 + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATANONE 0 /* Invalid data encoding */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ +#define ELFDATANUM 3 + +#define EI_VERSION 6 /* File version byte index */ + /* Value must be EV_CURRENT */ + +#define EI_OSABI 7 /* OS ABI identification */ +#define ELFOSABI_SYSV 0 /* UNIX System V ABI */ +#define ELFOSABI_HPUX 1 /* HP-UX */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +#define EI_ABIVERSION 8 /* ABI version */ + +#define EI_PAD 9 /* Byte index of padding bytes */ + +/* Legal values for e_type (object file type). */ + +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* Relocatable file */ +#define ET_EXEC 2 /* Executable file */ +#define ET_DYN 3 /* Shared object file */ +#define ET_CORE 4 /* Core file */ +#define ET_NUM 5 /* Number of defined types */ +#define ET_LOPROC 0xff00 /* Processor-specific */ +#define ET_HIPROC 0xffff /* Processor-specific */ + +/* Legal values for e_machine (architecture). */ + +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SUN SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_486 6 /* Intel 80486 */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 big-endian */ +#define EM_S370 9 /* Amdahl */ +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ +#define EM_RS6000 11 /* RS6000 */ + +#define EM_PARISC 15 /* HPPA */ +#define EM_nCUBE 16 /* nCUBE */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ + +#define EM_V800 36 /* NEC V800 series */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH32 */ +#define EM_MMA 39 /* Fujitsu MMA */ +#define EM_ARM 40 /* ARM */ +#define EM_FAKE_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Siemens Tricore */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_NUM 54 + +/* If it is necessary to assign new unofficial EM_* values, please + pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the + chances of collision with official or non-GNU unofficial values. */ + +#define EM_ALPHA 0x9026 + +/* Legal values for e_version (version). */ + +#define EV_NONE 0 /* Invalid ELF version */ +#define EV_CURRENT 1 /* Current version */ +#define EV_NUM 2 + + +/* Program segment header. */ + +typedef struct +{ + Elf32_Word p_type; /* Segment type */ + Elf32_Off p_offset; /* Segment file offset */ + Elf32_Addr p_vaddr; /* Segment virtual address */ + Elf32_Addr p_paddr; /* Segment physical address */ + Elf32_Word p_filesz; /* Segment size in file */ + Elf32_Word p_memsz; /* Segment size in memory */ + Elf32_Word p_flags; /* Segment flags */ + Elf32_Word p_align; /* Segment alignment */ +} Elf32_Phdr; + +typedef struct +{ + Elf64_Word p_type; /* Segment type */ + Elf64_Word p_flags; /* Segment flags */ + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment */ +} Elf64_Phdr; + +/* Legal values for p_type (segment type). */ + +#define PT_NULL 0 /* Program header table entry unused */ +#define PT_LOAD 1 /* Loadable program segment */ +#define PT_DYNAMIC 2 /* Dynamic linking information */ +#define PT_INTERP 3 /* Program interpreter */ +#define PT_NOTE 4 /* Auxiliary information */ +#define PT_SHLIB 5 /* Reserved */ +#define PT_PHDR 6 /* Entry for header table itself */ +#define PT_NUM 7 /* Number of defined types. */ +#define PT_LOOS 0x60000000 /* Start of OS-specific */ +#define PT_HIOS 0x6fffffff /* End of OS-specific */ +#define PT_LOPROC 0x70000000 /* Start of processor-specific */ +#define PT_HIPROC 0x7fffffff /* End of processor-specific */ + +/* Legal values for p_flags (segment flags). */ + +#define PF_X (1 << 0) /* Segment is executable */ +#define PF_W (1 << 1) /* Segment is writable */ +#define PF_R (1 << 2) /* Segment is readable */ +#define PF_MASKPROC 0xf0000000 /* Processor-specific */ + + +/* Note section contents. Each entry in the note section begins with + a header of a fixed form. */ + +typedef struct +{ + Elf32_Word n_namesz; /* Length of the note's name. */ + Elf32_Word n_descsz; /* Length of the note's descriptor. */ + Elf32_Word n_type; /* Type of the note. */ +} Elf32_Nhdr; + +typedef struct +{ + Elf64_Word n_namesz; /* Length of the note's name. */ + Elf64_Word n_descsz; /* Length of the note's descriptor. */ + Elf64_Word n_type; /* Type of the note. */ +} Elf64_Nhdr; + +/* Known names of notes. */ + +/* Solaris entries in the note section have this name. */ +#define ELF_NOTE_SOLARIS "SUNW Solaris" + +/* Note entries for GNU systems have this name. */ +#define ELF_NOTE_GNU "GNU" + + +/* Defined types of notes for Solaris. */ + +/* Value of descriptor (one word) is desired pagesize for the binary. */ +#define ELF_NOTE_PAGESIZE_HINT 1 + + +/* Defined note types for GNU systems. */ + +/* ABI information. The descriptor consists of words: + word 0: OS descriptor + word 1: major version of the ABI + word 2: minor version of the ABI + word 3: subminor version of the ABI +*/ +#define ELF_NOTE_ABI 1 + +/* Known OSes. These value can appear in word 0 of an ELF_NOTE_ABI + note section entry. */ +#define ELF_NOTE_OS_LINUX 0 +#define ELF_NOTE_OS_GNU 1 +#define ELF_NOTE_OS_SOLARIS2 2 + + +/* Motorola 68k specific definitions. */ + +/* Intel 80386 specific definitions. */ + +/* SUN SPARC specific definitions. */ + +/* Values for Elf64_Ehdr.e_flags. */ + +#define EF_SPARCV9_MM 3 +#define EF_SPARCV9_TSO 0 +#define EF_SPARCV9_PSO 1 +#define EF_SPARCV9_RMO 2 +#define EF_SPARC_EXT_MASK 0xFFFF00 +#define EF_SPARC_SUN_US1 0x000200 +#define EF_SPARC_HAL_R1 0x000400 + +/* MIPS R3000 specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ +#define EF_MIPS_PIC 2 /* Contains PIC code */ +#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ +#define EF_MIPS_XGOT 8 +#define EF_MIPS_64BIT_WHIRL 16 +#define EF_MIPS_ABI2 32 +#define EF_MIPS_ABI_ON32 64 +#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ + +/* Legal values for MIPS architecture level. */ + +#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ + +/* Legal values for p_type field of Elf32_Phdr. */ + +#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ +#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ +#define PT_MIPS_OPTIONS 0x70000002 + +/* Special program header types. */ + +#define PF_MIPS_LOCAL 0x10000000 + + +/* HPPA specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_PARISC_TRAPNL 1 /* Trap nil pointer dereference. */ +#define EF_PARISC_EXT 2 /* Program uses arch. extensions. */ +#define EF_PARISC_ARCH 0xffff0000 /* Architecture version. */ +/* Defined values are: + 0x020b PA-RISC 1.0 big-endian + 0x0210 PA-RISC 1.1 big-endian + 0x028b PA-RISC 1.0 little-endian + 0x0290 PA-RISC 1.1 little-endian +*/ + + +/* Alpha specific definitions. */ + +/* Legal values for e_flags field of Elf64_Ehdr. */ + +#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ +#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ + + +/* PowerPC specific declarations */ + +/* ARM specific declarations */ + +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_ARM_RELEXEC 0x01 +#define EF_ARM_HASENTRY 0x02 +#define EF_ARM_INTERWORK 0x04 +#define EF_ARM_APCS_26 0x08 +#define EF_ARM_APCS_FLOAT 0x10 +#define EF_ARM_PIC 0x20 +#define EF_ALIGN8 0x40 /* 8-bit structure alignment is in use */ +#define EF_NEW_ABI 0x80 +#define EF_OLD_ABI 0x100 + +/* ARM-specific program header flags */ +#define PF_ARM_SB 0x10000000 /* Segment contains the location + addressed by the static base */ + +#if ELF_CLASS == ELFCLASS32 +typedef Elf32_Ehdr Elf_ehdr; +typedef Elf32_Phdr Elf_phdr; +#endif + +#if ELF_CLASS == ELFCLASS64 +typedef Elf64_Ehdr Elf_ehdr; +typedef Elf64_Phdr Elf_phdr; +#endif + +extern int elf_check_arch(Elf_ehdr *ehdr); +extern void jmp_to_elf_entry(void *entry, unsigned long buffer); +struct stream; +struct lb_memory; +extern int elfload(struct stream *stream, struct lb_memory *mem, + unsigned char *header, unsigned long header_size); +extern int elfboot(struct stream *stream, struct lb_memory *mem); + +#define FIRMWARE_TYPE "LinuxBIOS" +#define BOOTLOADER "elfboot" +#define BOOTLOADER_VERSION "1.2" + +#endif /* elf.h */ diff --git a/util/baremetal/include/boot/elf_boot.h b/util/baremetal/include/boot/elf_boot.h new file mode 100644 index 0000000000..ee6750d293 --- /dev/null +++ b/util/baremetal/include/boot/elf_boot.h @@ -0,0 +1,89 @@ +#ifndef ELF_BOOT_H +#define ELF_BOOT_H + +#include + +/* This defines the structure of a table of parameters useful for ELF + * bootable images. These parameters are all passed and generated + * by the bootloader to the booted image. For simplicity and + * consistency the Elf Note format is reused. + * + * All of the information must be Position Independent Data. + * That is it must be safe to relocate the whole ELF boot parameter + * block without changing the meaning or correctnes of the data. + * Additionally it must be safe to permute the order of the ELF notes + * to any possible permutation without changing the meaning or correctness + * of the data. + * + */ + +#define ELF_HEAD_SIZE (8*1024) +#define ELF_BOOT_MAGIC 0x0E1FB007 + +typedef uint16_t Elf_Half; +typedef uint32_t Elf_Word; +typedef uint64_t Elf_Xword; + +typedef struct +{ + Elf_Word b_signature; /* "0x0E1FB007" */ + Elf_Word b_size; + Elf_Half b_checksum; + Elf_Half b_records; +} Elf_Bhdr; + +typedef struct +{ + Elf_Word n_namesz; /* Length of the note's name. */ + Elf_Word n_descsz; /* Length of the note's descriptor. */ + Elf_Word n_type; /* Type of the note. */ +} Elf_Nhdr; + + +/* For standard notes n_namesz must be zero */ +/* All of the following standard note types provide a single null + * terminated string in the descriptor. + */ +#define EBN_FIRMWARE_TYPE 0x00000001 +/* On platforms that support multiple classes of firmware this field + * specifies the class of firmware you are loaded under. + */ +#define EBN_BOOTLOADER_NAME 0x00000002 +/* This specifies just the name of the bootloader for easy comparison */ +#define EBN_BOOTLOADER_VERSION 0x00000003 +/* This specifies the version of the bootlader */ +#define EBN_COMMAND_LINE 0x00000004 +/* This specifies a command line that can be set by user interaction, + * and is provided as a free form string to the loaded image. + */ + + +/* Standardized Elf image notes for booting... The name for all of these is ELFBoot */ + +#define ELF_NOTE_BOOT "ELFBoot" + +#define EIN_PROGRAM_NAME 0x00000001 +/* The program in this ELF file */ +#define EIN_PROGRAM_VERSION 0x00000002 +/* The version of the program in this ELF file */ +#define EIN_PROGRAM_CHECKSUM 0x00000003 +/* ip style checksum of the memory image. */ + + +/* Linux image notes for booting... The name for all of these is Linux */ + +#define LINUX_NOTE_BOOT "Linux" + +#define LIN_COMMAND_LINE 0x00000001 +/* The command line to pass to the loaded kernel. */ +#define LIN_ROOT_DEV 0x00000002 +/* The root dev to pass to the loaded kernel. */ +#define LIN_RAMDISK_FLAGS 0x00000003 +/* Various old ramdisk flags */ +#define LIN_INITRD_START 0x00000004 +/* Start of the ramdisk in bytes */ +#define LIN_INITRD_SIZE 0x00000005 +/* Size of the ramdisk in bytes */ + + +#endif /* ELF_BOOT_H */ diff --git a/util/baremetal/include/boot/linuxbios_table.h b/util/baremetal/include/boot/linuxbios_table.h new file mode 100644 index 0000000000..42c0a07dac --- /dev/null +++ b/util/baremetal/include/boot/linuxbios_table.h @@ -0,0 +1,33 @@ +#ifndef LINUXBIOS_TABLE_H +#define LINUXBIOS_TABLE_H + +#include + +struct mem_range; + +/* This file holds function prototypes for building the linuxbios table. */ +unsigned long write_linuxbios_table( + unsigned long *processor_map, + struct mem_range *ram, + unsigned long low_table_start, unsigned long low_table_end, + unsigned long rom_table_start, unsigned long rom_table_end); + +struct lb_header *lb_table_init(unsigned long addr); +struct lb_record *lb_first_record(struct lb_header *header); +struct lb_record *lb_last_record(struct lb_header *header); +struct lb_record *lb_next_record(struct lb_record *rec); +struct lb_record *lb_new_record(struct lb_header *header); +struct lb_memory *lb_memory(struct lb_header *header); +void lb_memory_range(struct lb_memory *mem, + uint32_t type, unsigned long startk, unsigned long sizek); +struct lb_mainboard *lb_mainboard(struct lb_header *header); +unsigned long lb_table_fini(struct lb_header *header); + +/* Routines to extract part so the linuxBIOS table or information + * from the linuxBIOS table. + */ +struct lb_memory *get_lb_mem(void); + +extern struct cmos_option_table option_table; + +#endif /* LINUXBIOS_TABLE_H */ diff --git a/util/baremetal/include/boot/linuxbios_tables.h b/util/baremetal/include/boot/linuxbios_tables.h new file mode 100644 index 0000000000..5f37993807 --- /dev/null +++ b/util/baremetal/include/boot/linuxbios_tables.h @@ -0,0 +1,183 @@ +#ifndef LINUXBIOS_TABLES_H +#define LINUXBIOS_TABLES_H + +#include + +/* The linuxbios table information is for conveying information + * from the firmware to the loaded OS image. Primarily this + * is expected to be information that cannot be discovered by + * other means, such as quering the hardware directly. + * + * All of the information should be Position Independent Data. + * That is it should be safe to relocated any of the information + * without it's meaning/correctnes changing. For table that + * can reasonably be used on multiple architectures the data + * size should be fixed. This should ease the transition between + * 32 bit and 64 bit architectures etc. + * + * The completeness test for the information in this table is: + * - Can all of the hardware be detected? + * - Are the per motherboard constants available? + * - Is there enough to allow a kernel to run that was written before + * a particular motherboard is constructed? (Assuming the kernel + * has drivers for all of the hardware but it does not have + * assumptions on how the hardware is connected together). + * + * With this test it should be straight forward to determine if a + * table entry is required or not. This should remove much of the + * long term compatibility burden as table entries which are + * irrelevant or have been replaced by better alternatives may be + * dropped. Of course it is polite and expidite to include extra + * table entries and be backwards compatible, but it is not required. + */ + + +struct lb_header +{ + uint8_t signature[4]; /* LBIO */ + uint32_t header_bytes; + uint32_t header_checksum; + uint32_t table_bytes; + uint32_t table_checksum; + uint32_t table_entries; +}; + +/* Every entry in the boot enviroment list will correspond to a boot + * info record. Encoding both type and size. The type is obviously + * so you can tell what it is. The size allows you to skip that + * boot enviroment record if you don't know what it easy. This allows + * forward compatibility with records not yet defined. + */ +struct lb_record { + uint32_t tag; /* tag ID */ + uint32_t size; /* size of record (in bytes) */ +}; + +#define LB_TAG_UNUSED 0x0000 + +#define LB_TAG_MEMORY 0x0001 + +struct lb_memory_range { + uint64_t start; + uint64_t size; + uint32_t type; +#define LB_MEM_RAM 1 /* Memory anyone can use */ +#define LB_MEM_RESERVED 2 /* Don't use this memory region */ +#define LB_MEM_TABLE 16 /* Ram configuration tables are kept in */ + +}; + +struct lb_memory { + uint32_t tag; + uint32_t size; + struct lb_memory_range map[0]; +}; + +#define LB_TAG_HWRPB 0x0002 +struct lb_hwrpb { + uint32_t tag; + uint32_t size; + uint64_t hwrpb; +}; + +#define LB_TAG_MAINBOARD 0x0003 +struct lb_mainboard { + uint32_t tag; + uint32_t size; + uint8_t vendor_idx; + uint8_t part_number_idx; + uint8_t strings[0]; +}; + +#define LB_TAG_VERSION 0x0004 +#define LB_TAG_EXTRA_VERSION 0x0005 +#define LB_TAG_BUILD 0x0006 +#define LB_TAG_COMPILE_TIME 0x0007 +#define LB_TAG_COMPILE_BY 0x0008 +#define LB_TAG_COMPILE_HOST 0x0009 +#define LB_TAG_COMPILE_DOMAIN 0x000a +#define LB_TAG_COMPILER 0x000b +#define LB_TAG_LINKER 0x000c +#define LB_TAG_ASSEMBLER 0x000d +struct lb_string { + uint32_t tag; + uint32_t size; + uint8_t string[0]; +}; + +/* The following structures are for the cmos definitions table */ +#define LB_TAG_CMOS_OPTION_TABLE 200 +/* cmos header record */ +struct cmos_option_table { + uint32_t tag; /* CMOS definitions table type */ + uint32_t size; /* size of the entire table */ + uint32_t header_length; /* length of header */ +}; + +/* cmos entry record + This record is variable length. The name field may be + shorter than CMOS_MAX_NAME_LENGTH. The entry may start + anywhere in the byte, but can not span bytes unless it + starts at the beginning of the byte and the length is + fills complete bytes. +*/ +#define LB_TAG_OPTION 201 +struct cmos_entries { + uint32_t tag; /* entry type */ + uint32_t size; /* length of this record */ + uint32_t bit; /* starting bit from start of image */ + uint32_t length; /* length of field in bits */ + uint32_t config; /* e=enumeration, h=hex, r=reserved */ + uint32_t config_id; /* a number linking to an enumeration record */ +#define CMOS_MAX_NAME_LENGTH 32 + uint8_t name[CMOS_MAX_NAME_LENGTH]; /* name of entry in ascii, + variable length int aligned */ +}; + + +/* cmos enumerations record + This record is variable length. The text field may be + shorter than CMOS_MAX_TEXT_LENGTH. +*/ +#define LB_TAG_OPTION_ENUM 202 +struct cmos_enums { + uint32_t tag; /* enumeration type */ + uint32_t size; /* length of this record */ + uint32_t config_id; /* a number identifying the config id */ + uint32_t value; /* the value associated with the text */ +#define CMOS_MAX_TEXT_LENGTH 32 + uint8_t text[CMOS_MAX_TEXT_LENGTH]; /* enum description in ascii, + variable length int aligned */ +}; + +/* cmos defaults record + This record contains default settings for the cmos ram. +*/ +#define LB_TAG_OPTION_DEFAULTS 203 +struct cmos_defaults { + uint32_t tag; /* default type */ + uint32_t size; /* length of this record */ + uint32_t name_length; /* length of the following name field */ + uint8_t name[CMOS_MAX_NAME_LENGTH]; /* name identifying the default */ +#define CMOS_IMAGE_BUFFER_SIZE 128 + uint8_t default_set[CMOS_IMAGE_BUFFER_SIZE]; /* default settings */ +}; + +#define LB_TAG_OPTION_CHECKSUM 204 +struct cmos_checksum { + uint32_t tag; + uint32_t size; + /* In practice everything is byte aligned, but things are measured + * in bits to be consistent. + */ + uint32_t range_start; /* First bit that is checksummed (byte aligned) */ + uint32_t range_end; /* Last bit that is checksummed (byte aligned) */ + uint32_t location; /* First bit of the checksum (byte aligned) */ + uint32_t type; /* Checksum algorithm that is used */ +#define CHECKSUM_NONE 0 +#define CHECKSUM_PCBIOS 1 +}; + + + +#endif /* LINUXBIOS_TABLES_H */ diff --git a/util/baremetal/include/config.h b/util/baremetal/include/config.h new file mode 100644 index 0000000000..a1b3acb104 --- /dev/null +++ b/util/baremetal/include/config.h @@ -0,0 +1,3 @@ +#define SERIAL_CONSOLE +#define PYRO_SERIAL +//#define VIDEO_CONSOLE diff --git a/util/baremetal/include/i386/arch/io.h b/util/baremetal/include/i386/arch/io.h new file mode 100644 index 0000000000..50e6ad3b15 --- /dev/null +++ b/util/baremetal/include/i386/arch/io.h @@ -0,0 +1,197 @@ +#ifndef _ASM_IO_H +#define _ASM_IO_H + +/* + * 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 + */ + + /* + * Bit simplified and optimized by Jan Hubicka + * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999. + */ + +#ifdef SLOW_IO_BY_JUMPING +#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:" +#else +#define __SLOW_DOWN_IO "\noutb %%al,$0x80" +#endif + +#ifdef REALLY_SLOW_IO +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO +#else +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO +#endif + +/* + * Talk about misusing macros.. + */ +#define __OUT1(s,x) \ +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), "Nd" (port)); } \ +__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \ + +#define __IN1(s) \ +extern inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v; + +#define __IN2(s,s1,s2) \ +__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" + +#define __IN(s,s1,i...) \ +__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ +__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ + +#define __INS(s) \ +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 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)); } + +#define RETURN_TYPE unsigned char +__IN(b,"") +#undef RETURN_TYPE +#define RETURN_TYPE unsigned short +__IN(w,"") +#undef RETURN_TYPE +#define RETURN_TYPE unsigned int +__IN(l,"") +#undef RETURN_TYPE + +__OUT(b,"b",char) +__OUT(w,"w",short) +__OUT(l,,int) + +__INS(b) +__INS(w) +__INS(l) + +__OUTS(b) +__OUTS(w) +__OUTS(l) + +#ifdef NONONONONO + +#include +#include + +#define __io_virt(x) ((void *)(PAGE_OFFSET | (unsigned long)(x))) +#define __io_phys(x) ((unsigned long)(x) & ~PAGE_OFFSET) +/* + * Change virtual addresses to physical addresses and vv. + * These are pretty trivial + */ +extern inline unsigned long virt_to_phys(volatile void * address) +{ +#ifdef CONFIG_BIGMEM + return __pa(address); +#else + return __io_phys(address); +#endif +} + +extern inline void * phys_to_virt(unsigned long address) +{ +#ifdef CONFIG_BIGMEM + return __va(address); +#else + return __io_virt(address); +#endif +} + +extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); + +extern inline void * ioremap (unsigned long offset, unsigned long size) +{ + return __ioremap(offset, size, 0); +} + +/* + * This one maps high address device memory and turns off caching for that area. + * it's useful if some control registers are in such an area and write combining + * or read caching is not desirable: + */ +extern inline void * ioremap_nocache (unsigned long offset, unsigned long size) +{ + return __ioremap(offset, size, _PAGE_PCD); +} + +extern void iounmap(void *addr); + +/* + * IO bus memory addresses are also 1:1 with the physical address + */ +#define virt_to_bus virt_to_phys +#define bus_to_virt phys_to_virt + +/* + * 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 *) __io_virt(addr)) +#define readw(addr) (*(volatile unsigned short *) __io_virt(addr)) +#define readl(addr) (*(volatile unsigned int *) __io_virt(addr)) + +#define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b)) +#define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b)) +#define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b)) + +#define memset_io(a,b,c) __memset_generic(__io_virt(a),(b),(c)) +#define memcpy_fromio(a,b,c) __memcpy((a),__io_virt(b),(c)) +#define memcpy_toio(a,b,c) __memcpy(__io_virt(a),(b),(c)) + +/* + * Again, i386 does not require mem IO specific function. + */ + +#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(b),(c),(d)) + +static inline int check_signature(unsigned long io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +#endif /* __KERNEL__ */ + +#endif diff --git a/util/baremetal/include/i386/smp/spinlock.h b/util/baremetal/include/i386/smp/spinlock.h new file mode 100644 index 0000000000..d0cc11c6a7 --- /dev/null +++ b/util/baremetal/include/i386/smp/spinlock.h @@ -0,0 +1,57 @@ +#ifndef ARCH_SMP_SPINLOCK_H +#define ARCH_SMP_SPINLOCK_H + +/* + * Your basic SMP spinlocks, allowing only a single CPU anywhere + */ + +typedef struct { + volatile unsigned int lock; +} spinlock_t; + + +#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 } + +/* + * Simple spin lock operations. There are two variants, one clears IRQ's + * on the local processor, one does not. + * + * We make no fairness assumptions. They have a cost. + */ +#define barrier() __asm__ __volatile__("": : :"memory") +#define spin_is_locked(x) (*(volatile char *)(&(x)->lock) <= 0) +#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x)) + +#define spin_lock_string \ + "\n1:\t" \ + "lock ; decb %0\n\t" \ + "js 2f\n" \ + ".section .text.lock,\"ax\"\n" \ + "2:\t" \ + "cmpb $0,%0\n\t" \ + "rep;nop\n\t" \ + "jle 2b\n\t" \ + "jmp 1b\n" \ + ".previous" + +/* + * This works. Despite all the confusion. + */ +#define spin_unlock_string \ + "movb $1,%0" + +static inline void spin_lock(spinlock_t *lock) +{ + __asm__ __volatile__( + spin_lock_string + :"=m" (lock->lock) : : "memory"); +} + +static inline void spin_unlock(spinlock_t *lock) +{ + __asm__ __volatile__( + spin_unlock_string + :"=m" (lock->lock) : : "memory"); +} + +#endif /* ARCH_SMP_SPINLOCK_H */ diff --git a/util/baremetal/include/ip_checksum.h b/util/baremetal/include/ip_checksum.h new file mode 100644 index 0000000000..c2cb938294 --- /dev/null +++ b/util/baremetal/include/ip_checksum.h @@ -0,0 +1,7 @@ +#ifndef IP_CHECKSUM_H +#define IP_CHECKSUM_H + +unsigned long compute_ip_checksum(void *addr, unsigned long length); +unsigned long add_ip_checksums(unsigned long offset, unsigned long sum, unsigned long new); + +#endif /* IP_CHECKSUM_H */ diff --git a/util/baremetal/include/loglevel.h b/util/baremetal/include/loglevel.h new file mode 100644 index 0000000000..a191b308d3 --- /dev/null +++ b/util/baremetal/include/loglevel.h @@ -0,0 +1,30 @@ +#ifndef LOGLEVEL_H +#define LOGLEVEL_H + +/* Safe for inclusion in assembly */ + +#ifndef MAXIMUM_CONSOLE_LOGLEVEL +#define MAXIMUM_CONSOLE_LOGLEVEL 8 +#endif + +#ifndef DEFAULT_CONSOLE_LOGLEVEL +#define DEFAULT_CONSOLE_LOGLEVEL 8 /* anything MORE serious than BIOS_SPEW */ +#endif + +#if (DEFAULT_CONSOLE_LOGLEVEL <= MAXIMUM_CONSOLE_LOGLEVEL) +#define ASM_CONSOLE_LOGLEVEL DEFAULT_CONSOLE_LOGLEVEL +#else +#define ASM_CONSOLE_LOGLEVEL MAXIMUM_CONSOLE_LOGLEVEL +#endif + +#define BIOS_EMERG 0 /* system is unusable */ +#define BIOS_ALERT 1 /* action must be taken immediately */ +#define BIOS_CRIT 2 /* critical conditions */ +#define BIOS_ERR 3 /* error conditions */ +#define BIOS_WARNING 4 /* warning conditions */ +#define BIOS_NOTICE 5 /* normal but significant condition */ +#define BIOS_INFO 6 /* informational */ +#define BIOS_DEBUG 7 /* debug-level messages */ +#define BIOS_SPEW 8 /* Way too many details */ + +#endif /* LOGLEVEL_H */ diff --git a/util/baremetal/include/part/fallback_boot.h b/util/baremetal/include/part/fallback_boot.h new file mode 100644 index 0000000000..4f6d32e887 --- /dev/null +++ b/util/baremetal/include/part/fallback_boot.h @@ -0,0 +1,16 @@ +#ifndef PART_FALLBACK_BOOT_H +#define PART_FALLBACK_BOOT_H + +#if !defined(ASSEMBLY) + +#if HAVE_FALLBACK_BOOT +void boot_successful(void); +#else +#define boot_successful() +#endif + +#endif /* ASSEMBLY */ + +#define RTC_BOOT_BYTE 48 + +#endif /* PART_FALLBACK_BOOT_H */ diff --git a/util/baremetal/include/part/floppy.h b/util/baremetal/include/part/floppy.h new file mode 100644 index 0000000000..2c1a5194f1 --- /dev/null +++ b/util/baremetal/include/part/floppy.h @@ -0,0 +1,10 @@ +#ifndef PART_FLOPPY_H +#define PART_FLOPPY_H + +#ifdef MUST_ENABLE_FLOPPY +void enable_floppy(void); +#else +# define enable_floppy() do {} while(0) +#endif + +#endif /* PART_FLOPPY_H */ diff --git a/util/baremetal/include/part/framebuffer.h b/util/baremetal/include/part/framebuffer.h new file mode 100644 index 0000000000..4d607708fc --- /dev/null +++ b/util/baremetal/include/part/framebuffer.h @@ -0,0 +1,10 @@ +#ifndef PART_FRAMEBUFFER_H +#define PART_FRAMEBUFFER_H + +#ifdef HAVE_FRAMEBUFFER +void framebuffer_on(void); +#else +# define framebuffer_on() do {} while(0) +#endif /* HAVE_FRAMEBUFFER */ + +#endif /* PART_FRAMEBUFFER_H */ diff --git a/util/baremetal/include/part/hard_reset.h b/util/baremetal/include/part/hard_reset.h new file mode 100644 index 0000000000..51237677ad --- /dev/null +++ b/util/baremetal/include/part/hard_reset.h @@ -0,0 +1,11 @@ +#ifndef PART_HARD_RESET_H +#define PART_HARD_RESET_H + +#ifdef HAVE_HARD_RESET +void hard_reset(void); +#else +#define hard_reset() do {} while(0) +#endif + + +#endif diff --git a/util/baremetal/include/part/keyboard.h b/util/baremetal/include/part/keyboard.h new file mode 100644 index 0000000000..50127239e1 --- /dev/null +++ b/util/baremetal/include/part/keyboard.h @@ -0,0 +1,10 @@ +#ifndef PART_KEYBOARD_H +#define KEYBOARD_H + +#ifndef NO_KEYBOARD +void keyboard_on(void); +#else +# define keyboard_on() do {} while(0) +#endif + +#endif /* PART_KEYBOARD_H */ diff --git a/util/baremetal/include/part/mainboard.h b/util/baremetal/include/part/mainboard.h new file mode 100644 index 0000000000..1a364560e8 --- /dev/null +++ b/util/baremetal/include/part/mainboard.h @@ -0,0 +1,12 @@ +#ifndef PART_MAINBOARD_H +#define PART_MAINBOARD_H + +void mainboard_fixup(void); + +#ifdef FINAL_MAINBOARD_FIXUP +void final_mainboard_fixup(void); +#else +# define final_mainboard_fixup() do {} while(0) +#endif /* FINAL_MAINBOARD_FIXUP */ + +#endif /* PART_MAINBOARD_H */ diff --git a/util/baremetal/include/part/nvram.h b/util/baremetal/include/part/nvram.h new file mode 100644 index 0000000000..b59c91a8c3 --- /dev/null +++ b/util/baremetal/include/part/nvram.h @@ -0,0 +1,7 @@ +#ifndef PART_NVRAM_H +#define PART_NVRAM_H + +/* Turn on full access to the flash chip */ +void nvram_on(void); + +#endif /* PART_NVRAM_H */ diff --git a/util/baremetal/include/part/sizeram.h b/util/baremetal/include/part/sizeram.h new file mode 100644 index 0000000000..50a44f3e82 --- /dev/null +++ b/util/baremetal/include/part/sizeram.h @@ -0,0 +1,7 @@ +#ifndef PART_SIZERAM_H +#define PART_SIZERAM_H + +struct mem_rang; +struct mem_range *sizeram(void); + +#endif /* PART_SIZERAM_H */ diff --git a/util/baremetal/include/pc80/ide.h b/util/baremetal/include/pc80/ide.h new file mode 100644 index 0000000000..2c454f46cc --- /dev/null +++ b/util/baremetal/include/pc80/ide.h @@ -0,0 +1,144 @@ +/* + * UBL, The Universal Talkware Boot Loader + * Copyright (C) 2000 Universal Talkware Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Note: Parts of this code grew out of the Openbios effort that was + * abandoned. Without the info that we were able to learn from + * OpenBios this program would have never worked. We are forever + * grateful for those who came before us. + * + * This code can be retrieved in a machine/human readable form at: + * + * http://www.talkware.net/GPL/UBL + * + * Anyone making changes to this code please send them to us so we + * can include them in the standard release. + * + * $Id$ + * + */ +#if !defined(IDE_H_INCLUDE) +#define IDE_H_INCLUDE + +#define IDE_WRITE + +#include + +typedef struct { + unsigned short controller_port; + unsigned short num_heads; + unsigned short num_cylinders; + unsigned short num_sectors_per_track; + unsigned long num_sectors; /* total */ + unsigned char address_mode; /* am i lba (0x40) or chs (0x00) */ + unsigned char model_number[40]; + unsigned char drive_exists; +} harddisk_info_t; + +#define NUM_HD (2) + +extern harddisk_info_t harddisk_info[NUM_HD]; + +extern int ide_init(void); +extern int ide_read_sector(int driveno, void * buf, unsigned int sector, + int byte_offset, int n_bytes); +#ifdef IDE_WRITE +extern int ide_write_sector(int driveno, void * buf, unsigned int sector); +#endif + +extern int ide_read_data(unsigned base, void * buf, size_t size); +extern int ide_write_data(unsigned base, void * buf, size_t size); +extern int ide_shutdown(void); + + + +#if 1 +#define PORT80(x) (outb_p(x, 0x80)) +#else +#define PORT80(x) (0) +#endif + +#define IDE_SECTOR_SIZE 0x200 + +#define IDE_BASE1 (0x1F0u) /* primary controller */ +#define IDE_BASE2 (0x170u) /* secondary */ +#define IDE_BASE3 (0x0F0u) /* third */ +#define IDE_BASE4 (0x070u) /* fourth */ + +#define IDE_REG_EXTENDED_OFFSET (0x200u) + +#define IDE_REG_DATA(base) ((base) + 0u) /* word register */ +#define IDE_REG_ERROR(base) ((base) + 1u) +#define IDE_REG_PRECOMP(base) ((base) + 1u) +#define IDE_REG_SECTOR_COUNT(base) ((base) + 2u) +#define IDE_REG_SECTOR_NUMBER(base) ((base) + 3u) +#define IDE_REG_CYLINDER_LSB(base) ((base) + 4u) +#define IDE_REG_CYLINDER_MSB(base) ((base) + 5u) +#define IDE_REG_DRIVEHEAD(base) ((base) + 6u) +#define IDE_REG_STATUS(base) ((base) + 7u) +#define IDE_REG_COMMAND(base) ((base) + 7u) +#define IDE_REG_ALTSTATUS(base) ((base) + IDE_REG_EXTENDED_OFFSET + 6u) +#define IDE_REG_CONTROL(base) ((base) + IDE_REG_EXTENDED_OFFSET + 6u) +#define IDE_REG_ADDRESS(base) ((base) + IDE_REG_EXTENDED_OFFSET + 7u) + +typedef struct { + unsigned char precomp; + unsigned char sector_count; + unsigned char sector_number; + unsigned short cylinder; + unsigned char drivehead; +# define IDE_DH_DEFAULT (0xA0) +# define IDE_DH_HEAD(x) ((x) & 0x0F) +# define IDE_DH_MASTER (0x00) +# define IDE_DH_SLAVE (0x10) +# define IDE_DH_DRIVE(x) ((((x) & 1) != 0)?IDE_DH_SLAVE:IDE_DH_MASTER) +# define IDE_DH_LBA (0x40) +# define IDE_DH_CHS (0x00) + +} ide_cmd_param_t; + +#define IDE_DEFAULT_COMMAND { 0xFFu, 0x01, 0x00, 0x0000, IDE_DH_DEFAULT } + +typedef enum { + IDE_CMD_NOOP = 0, + IDE_CMD_RECALIBRATE = 0x10, + IDE_CMD_READ_MULTI_RETRY = 0x20, + IDE_CMD_WRITE_MULTI_RETRY = 0x30, + IDE_CMD_READ_MULTI = IDE_CMD_READ_MULTI_RETRY, + IDE_CMD_READ_MULTI_NORETRY = 0x21, + + IDE_CMD_DRIVE_DIAG = 0x90, + IDE_CMD_SET_PARAMS = 0x91, + IDE_CMD_STANDBY_IMMEDIATE = 0x94, /* 2 byte command- also send + IDE_CMD_STANDBY_IMMEDIATE2 */ + IDE_CMD_SET_MULTIMODE = 0xC6, + IDE_CMD_STANDBY_IMMEDIATE2 = 0xE0, + IDE_CMD_GET_INFO = 0xEC +} ide_command_t; + + +#endif /* IDE_H_INCLUDE */ + + + + + + + + + + diff --git a/util/baremetal/include/pc80/mc146818rtc.h b/util/baremetal/include/pc80/mc146818rtc.h new file mode 100644 index 0000000000..726734f364 --- /dev/null +++ b/util/baremetal/include/pc80/mc146818rtc.h @@ -0,0 +1,104 @@ +#ifndef PC80_MC146818RTC_H +#define PC80_MC146818RTC_H + +#ifndef RTC_BASE_PORT +#define RTC_BASE_PORT 0x70 +#endif + +#define RTC_PORT(x) (RTC_BASE_PORT + (x)) + +/* On PCs, the checksum is built only over bytes 16..45 */ +#define PC_CKS_RANGE_START 16 +#define PC_CKS_RANGE_END 45 +#define PC_CKS_LOC 46 + + +/* control registers - Moto names + */ +#define RTC_REG_A 10 +#define RTC_REG_B 11 +#define RTC_REG_C 12 +#define RTC_REG_D 13 + + +/********************************************************************** + * register details + **********************************************************************/ +#define RTC_FREQ_SELECT RTC_REG_A + +/* update-in-progress - set to "1" 244 microsecs before RTC goes off the bus, + * reset after update (may take 1.984ms @ 32768Hz RefClock) is complete, + * totalling to a max high interval of 2.228 ms. + */ +# define RTC_UIP 0x80 +# define RTC_DIV_CTL 0x70 + /* divider control: refclock values 4.194 / 1.049 MHz / 32.768 kHz */ +# define RTC_REF_CLCK_4MHZ 0x00 +# define RTC_REF_CLCK_1MHZ 0x10 +# define RTC_REF_CLCK_32KHZ 0x20 + /* 2 values for divider stage reset, others for "testing purposes only" */ +# define RTC_DIV_RESET1 0x60 +# define RTC_DIV_RESET2 0x70 + /* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */ +# define RTC_RATE_SELECT 0x0F +# define RTC_RATE_NONE 0x00 +# define RTC_RATE_32786HZ 0x01 +# define RTC_RATE_16384HZ 0x02 +# define RTC_RATE_8192HZ 0x03 +# define RTC_RATE_4096HZ 0x04 +# define RTC_RATE_2048HZ 0x05 +# define RTC_RATE_1024HZ 0x06 +# define RTC_RATE_512HZ 0x07 +# define RTC_RATE_256HZ 0x08 +# define RTC_RATE_128HZ 0x09 +# define RTC_RATE_64HZ 0x0a +# define RTC_RATE_32HZ 0x0b +# define RTC_RATE_16HZ 0x0c +# define RTC_RATE_8HZ 0x0d +# define RTC_RATE_4HZ 0x0e +# define RTC_RATE_2HZ 0x0f + +/**********************************************************************/ +#define RTC_CONTROL RTC_REG_B +# define RTC_SET 0x80 /* disable updates for clock setting */ +# define RTC_PIE 0x40 /* periodic interrupt enable */ +# define RTC_AIE 0x20 /* alarm interrupt enable */ +# define RTC_UIE 0x10 /* update-finished interrupt enable */ +# define RTC_SQWE 0x08 /* enable square-wave output */ +# define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ +# define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ +# define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ + +/**********************************************************************/ +#define RTC_INTR_FLAGS RTC_REG_C +/* caution - cleared by read */ +# define RTC_IRQF 0x80 /* any of the following 3 is active */ +# define RTC_PF 0x40 +# define RTC_AF 0x20 +# define RTC_UF 0x10 + +/**********************************************************************/ +#define RTC_VALID RTC_REG_D +# define RTC_VRT 0x80 /* valid RAM and time */ +/**********************************************************************/ + + +/* On PCs, the checksum is built only over bytes 16..45 */ +#define PC_CKS_RANGE_START 16 +#define PC_CKS_RANGE_END 45 +#define PC_CKS_LOC 46 + +#define LB_CKS_RANGE_START 49 +#define LB_CKS_RANGE_END 125 +#define LB_CKS_LOC 126 + +#if !defined(ASSEMBLY) +void rtc_init(int invalid); +#if USE_OPTION_TABLE == 1 +int get_option(void *dest, char *name); +#else +#define get_option(dest, name) (-2) +#endif +#endif + +#endif /* PC80_MC146818RTC_H */ diff --git a/util/baremetal/include/printk.h b/util/baremetal/include/printk.h new file mode 100644 index 0000000000..8088147b30 --- /dev/null +++ b/util/baremetal/include/printk.h @@ -0,0 +1,57 @@ +#ifndef PRINTK_H +#define PRINTK_H + +#include + +extern int console_loglevel; +int do_printk(int msg_level, const char *fmt, ...); + +#define printk_emerg(fmt, arg...) do_printk(BIOS_EMERG ,fmt, ##arg) +#define printk_alert(fmt, arg...) do_printk(BIOS_ALERT ,fmt, ##arg) +#define printk_crit(fmt, arg...) do_printk(BIOS_CRIT ,fmt, ##arg) +#define printk_err(fmt, arg...) do_printk(BIOS_ERR ,fmt, ##arg) +#define printk_warning(fmt, arg...) do_printk(BIOS_WARNING ,fmt, ##arg) +#define printk_notice(fmt, arg...) do_printk(BIOS_NOTICE ,fmt, ##arg) +#define printk_info(fmt, arg...) do_printk(BIOS_INFO ,fmt, ##arg) +#define printk_debug(fmt, arg...) do_printk(BIOS_DEBUG ,fmt, ##arg) +#define printk_spew(fmt, arg...) do_printk(BIOS_SPEW ,fmt, ##arg) +#define printk(fmt, arg...) do_printk(BIOS_EMERG ,fmt, ##arg) + +#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_EMERG +#undef printk_emerg +#define printk_emerg(fmt, arg...) do {} while(0) +#endif +#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_ALERT +#undef printk_alert +#define printk_alart(fmt, arg...) do {} while(0) +#endif +#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_CRIT +#undef printk_crit +#define printk_crit(fmt, arg...) do {} while(0) +#endif +#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_ERR +#undef printk_err +#define printk_err(fmt, arg...) do {} while(0) +#endif +#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_WARNING +#undef printk_warning +#define printk_warning(fmt, arg...) do {} while(0) +#endif +#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_NOTICE +#undef printk_notice +#define printk_notice(fmt, arg...) do {} while(0) +#endif +#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_INFO +#undef printk_info +#define printk_info(fmt, arg...) do {} while(0) +#endif +#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_DEBUG +#undef printk_debug +#define printk_debug(fmt, arg...) do {} while(0) +#endif +#if MAXIMUM_CONSOLE_LOGLEVEL <= BIOS_SPEW +#undef printk_spew +#define printk_spew(fmt, arg...) do {} while(0) +#endif + +#endif diff --git a/util/baremetal/include/rom/fill_inbuf.h b/util/baremetal/include/rom/fill_inbuf.h new file mode 100644 index 0000000000..515e7a20f7 --- /dev/null +++ b/util/baremetal/include/rom/fill_inbuf.h @@ -0,0 +1,23 @@ +#ifndef ROM_FILL_INBUF_H +#define ROM_FILL_INBUF_H + +extern unsigned char *inbuf; /* input buffer */ +extern unsigned int insize; /* valid bytes in inbuf */ +extern unsigned int inptr; /* index of next byte to be processed in inbuf */ + +extern int fill_inbuf(void); + +#ifndef DEBUG_GET_BYTE +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) +#else +#include +static unsigned char get_byte() { + static int byteno = 0; + unsigned char c = (inptr < insize ? inbuf[inptr++] : fill_inbuf()); + printk_debug("get_byte 0x%x 0x%x\n", byteno++, c); + return c; +} +#endif + + +#endif /* ROM_FILL_INBUF_H */ diff --git a/util/baremetal/include/rom/read_bytes.h b/util/baremetal/include/rom/read_bytes.h new file mode 100644 index 0000000000..3c50d25496 --- /dev/null +++ b/util/baremetal/include/rom/read_bytes.h @@ -0,0 +1,31 @@ +#ifndef ROM_READ_BYTES_H +#define ROM_READ_BYTES_H + +#include + +typedef long byte_offset_t; + +typedef struct tag_t { + char signature[5]; + unsigned char block_count; + unsigned long length; + char data[6]; +} __attribute__ ((packed)) tag_head; + +struct stream { + int (*init)(void); + int (*init_tags)(void); + void (*get_tags)(void *buf); + void (*load_tag)(int tag); + byte_offset_t (*read)(void *vdest, byte_offset_t count); + byte_offset_t (*skip)(byte_offset_t count); + void (*fini)(void); +}; + +#define __stream __attribute__ ((unused,__section__ (".rodata.streams"))) + +/* Defined by the linker... */ +extern struct stream streams[]; +extern struct stream estreams[]; + +#endif /* ROM_READ_BYTES_H */ diff --git a/util/baremetal/include/serial_subr.h b/util/baremetal/include/serial_subr.h new file mode 100644 index 0000000000..2636ed38ef --- /dev/null +++ b/util/baremetal/include/serial_subr.h @@ -0,0 +1,11 @@ +#ifndef _SERIAL_SUBR_H_ +#define _SERIAL_SUBR_H_ + +void ttys0_init(void); +void ttys0_tx_byte(unsigned char data); +unsigned char ttys0_rx_byte(void); +unsigned long ttys0_rx_bytes(char *buffer, unsigned long size); +int iskey(void); + +void uart_init(unsigned base_port, unsigned divisor); +#endif /* _SERIAL_SUBR_H_ */ diff --git a/util/baremetal/include/stdlib.h b/util/baremetal/include/stdlib.h new file mode 100644 index 0000000000..eb67d20fe7 --- /dev/null +++ b/util/baremetal/include/stdlib.h @@ -0,0 +1,14 @@ +#ifndef STDLIB_H +#define STDLIB_H + +#include + +extern void *malloc(size_t size); +void free(void *ptr); + +/* Extensions to malloc... */ +typedef size_t malloc_mark_t; +void malloc_mark(malloc_mark_t *place); +void malloc_release(malloc_mark_t *place); + +#endif /* STDLIB_H */ diff --git a/util/baremetal/include/string.h b/util/baremetal/include/string.h new file mode 100644 index 0000000000..cf9bbb14d2 --- /dev/null +++ b/util/baremetal/include/string.h @@ -0,0 +1,36 @@ +#ifndef STRING_H +#define STRING_H + +#include + +// yes, linux has fancy ones. We don't care. This stuff gets used +// hardly at all. And the pain of including those files is just too high. + +//extern inline void strcpy(char *dst, char *src) {while (*src) *dst++ = *src++;} + +//extern inline int strlen(char *src) { int i = 0; while (*src++) i++; return i;} + +static inline size_t strnlen(const char *src, size_t max) +{ + size_t i = 0; + while((*src++) && (i < max)) { + i++; + } + return i; +} + +static inline size_t strlen(const char *src) +{ + size_t i = 0; + while(*src++) { + i++; + } + return i; +} + +extern void *memcpy(void *dest, const void *src, size_t n); +extern void *memset(void *s, int c, size_t n); +extern int memcmp(const void *s1, const void *s2, size_t n); + +extern int sprintf(char * buf, const char *fmt, ...); +#endif /* STRING_H */ diff --git a/util/baremetal/include/subr.h b/util/baremetal/include/subr.h new file mode 100644 index 0000000000..dc065db73b --- /dev/null +++ b/util/baremetal/include/subr.h @@ -0,0 +1,14 @@ +#ifndef SUBR_H_ +#define SUBR_H_ + +#include + +void displayinit(void); +void display(char msg[]); +void display_tx_byte(unsigned char byte); +void display_tx_break(void); + +void error(char errmsg[]); +void post_code(uint8_t value); + +#endif /* SUBR_H_ */ diff --git a/util/baremetal/include/sys/io.h b/util/baremetal/include/sys/io.h new file mode 100644 index 0000000000..6324d89cad --- /dev/null +++ b/util/baremetal/include/sys/io.h @@ -0,0 +1,3 @@ +#include + +#define iopl(c) (0) diff --git a/util/baremetal/include/types.h b/util/baremetal/include/types.h new file mode 100644 index 0000000000..2aec0f698d --- /dev/null +++ b/util/baremetal/include/types.h @@ -0,0 +1,220 @@ +/* Copyright (C) 1991,92,94,95,96,97,98,99, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* + * POSIX Standard: 2.6 Primitive System Data Types + */ + +#ifndef _SYS_TYPES_H +#define _SYS_TYPES_H 1 + +#include + +__BEGIN_DECLS + +#include + +#ifdef __USE_BSD +typedef __u_char u_char; +typedef __u_short u_short; +typedef __u_int u_int; +typedef __u_long u_long; +typedef __quad_t quad_t; +typedef __u_quad_t u_quad_t; +typedef __fsid_t fsid_t; +#endif + +typedef __loff_t loff_t; + +#ifndef ino_t +# ifndef __USE_FILE_OFFSET64 +typedef __ino_t ino_t; +# else +typedef __ino64_t ino_t; +# endif +# define ino_t ino_t +#endif +#if defined __USE_LARGEFILE64 && !defined ino64_t +typedef __ino64_t ino64_t; +# define ino64_t ino64_t +#endif + +#ifndef dev_t +typedef __dev_t dev_t; +# define dev_t dev_t +#endif + +#ifndef gid_t +typedef __gid_t gid_t; +# define gid_t gid_t +#endif + +#ifndef mode_t +typedef __mode_t mode_t; +# define mode_t mode_t +#endif + +#ifndef nlink_t +typedef __nlink_t nlink_t; +# define nlink_t nlink_t +#endif + +#ifndef uid_t +typedef __uid_t uid_t; +# define uid_t uid_t +#endif + +#ifndef off_t +# ifndef __USE_FILE_OFFSET64 +typedef __off_t off_t; +# else +typedef __off64_t off_t; +# endif +# define off_t off_t +#endif +#if defined __USE_LARGEFILE64 && !defined off64_t +typedef __off64_t off64_t; +# define off64_t off64_t +#endif + +#ifndef pid_t +typedef __pid_t pid_t; +# define pid_t pid_t +#endif + +#if defined __USE_SVID || defined __USE_XOPEN +typedef __id_t id_t; +#endif + +#ifndef ssize_t +typedef __ssize_t ssize_t; +# define ssize_t ssize_t +#endif + +#ifdef __USE_BSD +typedef __daddr_t daddr_t; +typedef __caddr_t caddr_t; +#endif + +#if defined __USE_SVID || defined __USE_XOPEN +typedef __key_t key_t; +#endif + +#ifdef __USE_XOPEN +# define __need_clock_t +#endif +#define __need_time_t +#include + +#define __need_size_t +#include + +#ifdef __USE_MISC +/* Old compatibility names for C types. */ +typedef unsigned long int ulong; +typedef unsigned short int ushort; +typedef unsigned int uint; +#endif + +/* These size-specific names are used by some of the inet code. */ + +#if !defined __GNUC__ || __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) + +/* These types are defined by the ISO C 9x header . */ +# ifndef __int8_t_defined +# define __int8_t_defined +typedef char int8_t; +typedef short int int16_t; +typedef int int32_t; +# ifdef __GNUC__ +__extension__ typedef long long int int64_t; +# endif +# endif + +/* But these were defined by ISO C without the first `_'. */ +typedef unsigned char u_int8_t; +typedef unsigned short int u_int16_t; +typedef unsigned int u_int32_t; +# ifdef __GNUC__ +__extension__ typedef unsigned long long int u_int64_t; +# endif + +typedef int register_t; + +#else + +/* For GCC 2.7 and later, we can use specific type-size attributes. */ +# define __intN_t(N, MODE) \ + typedef int int##N##_t __attribute__ ((__mode__ (MODE))) +# define __u_intN_t(N, MODE) \ + typedef unsigned int u_int##N##_t __attribute__ ((__mode__ (MODE))) + +# ifndef __int8_t_defined +# define __int8_t_defined +__intN_t (8, __QI__); +__intN_t (16, __HI__); +__intN_t (32, __SI__); +__intN_t (64, __DI__); +# endif + +__u_intN_t (8, __QI__); +__u_intN_t (16, __HI__); +__u_intN_t (32, __SI__); +__u_intN_t (64, __DI__); + +typedef int register_t __attribute__ ((__mode__ (__word__))); + + +/* Some code from BIND tests this macro to see if the types above are + defined. */ +#endif +#define __BIT_TYPES_DEFINED__ 1 + + +#ifdef __USE_BSD +/* In BSD is expected to define BYTE_ORDER. */ +# include + +/* It also defines `fd_set' and the FD_* macros for `select'. */ +# include + +/* BSD defines these symbols, so we follow. */ +# include +#endif /* Use BSD. */ + + +/* Types from the Large File Support interface. */ +#ifndef __USE_FILE_OFFSET64 +typedef __blkcnt_t blkcnt_t; /* Type to count number of disk blocks. */ +typedef __fsblkcnt_t fsblkcnt_t; /* Type to count file system blocks. */ +typedef __fsfilcnt_t fsfilcnt_t; /* Type to count file system inodes. */ +#else +typedef __blkcnt64_t blkcnt_t; /* Type to count number of disk blocks. */ +typedef __fsblkcnt64_t fsblkcnt_t; /* Type to count file system blocks. */ +typedef __fsfilcnt64_t fsfilcnt_t; /* Type to count file system inodes. */ +#endif + +#ifdef __USE_LARGEFILE64 +typedef __blkcnt64_t blkcnt64_t; /* Type to count number of disk blocks. */ +typedef __fsblkcnt64_t fsblkcnt64_t; /* Type to count file system blocks. */ +typedef __fsfilcnt64_t fsfilcnt64_t; /* Type to count file system inodes. */ +#endif + +__END_DECLS + +#endif /* sys/types.h */