Hopefully this is my last commit of major infrasture changes for a while.

Highlights:
 - elfboot.c Now can load images to the ram location where linuxBIOS is running
 - Added the standalone directory for bootloaders built from the linuxBIOS source

Other things:
- Correctly maode fallback_boot.c conditional
- Added entry32.lds to do the math for segment descriptor table entries
- Merged ldscript.cacheram and ldscript.base
- Moved assembly code to the sections .rom.text and .rom.data
- Modified linuxBIOS so C code completely runs from RAM as the SiS630
  case does
- Updated and commented example config files for the supermicro p4dc6
- Bumped the elfboot loader version to 1.0
- Removed extra carriage returns in dump_northbridge.inc (DOS->UNIX)
- General cleanups to the config of the supermicro p4dc6
This commit is contained in:
Eric W. Biederman 2002-01-16 05:54:23 +00:00
parent 5346fd33f9
commit 0f7f76fb40
56 changed files with 1194 additions and 378 deletions

View file

@ -2,6 +2,8 @@
#include <boot/elf.h>
#include <boot/elf_boot.h>
#include <string.h>
#include <printk.h>
#ifndef CMD_LINE
#define CMD_LINE ""
@ -65,21 +67,115 @@ int elf_check_arch(Elf_ehdr *ehdr)
}
void jmp_to_elf_entry(void *entry)
void jmp_to_elf_entry(void *entry, unsigned long buffer)
{
unsigned long type = 0x0E1FB007;
extern unsigned char _ram_seg, _eram_seg;
unsigned long lb_start, lb_size;
unsigned long adjust, adjusted_boot_notes;
unsigned long type;
elf_boot_notes.hdr.b_checksum =
compute_ip_checksum(&elf_boot_notes, sizeof(elf_boot_notes));
type = 0x0E1FB007;
lb_start = (unsigned long)&_ram_seg;
lb_size = (unsigned long)(&_eram_seg - &_ram_seg);
adjust = buffer + lb_size - lb_start;
adjusted_boot_notes = (unsigned long)&elf_boot_notes;
adjusted_boot_notes += adjust;
printk_spew("entry = 0x%08lx\n", (unsigned long)entry);
printk_spew("lb_start = 0x%08lx\n", lb_start);
printk_spew("lb_size = 0x%08lx\n", lb_size);
printk_spew("adjust = 0x%08lx\n", adjust);
printk_spew("buffer = 0x%08lx\n", buffer);
printk_spew("adjusted_boot_notes = 0x%08lx\n", adjusted_boot_notes);
/* Jump to kernel */
__asm__ __volatile__(
"pushl %0\n\t"
"pushl %1\n\t"
"pushl %2\n\t"
"popl %%ebx\n\t"
"popl %%eax\n\t"
"ret\n\t"
:: "g" (entry), "g"(type), "g"(&elf_boot_notes));
" cld \n\t"
/* Save the callee save registers... */
" pushl %%esi\n\t"
" pushl %%edi\n\t"
" pushl %%ebx\n\t"
/* Save the parameters I was passed */
" pushl $0\n\t" /* 20 adjust */
" pushl %0\n\t" /* 16 lb_start */
" pushl %1\n\t" /* 12 buffer */
" pushl %2\n\t" /* 8 lb_size */
" pushl %3\n\t" /* 4 entry */
" pushl %4\n\t" /* 0 elf_boot_notes */
/* Compute the adjustment */
" xorl %%eax, %%eax\n\t"
" subl 16(%%esp), %%eax\n\t"
" addl 12(%%esp), %%eax\n\t"
" addl 8(%%esp), %%eax\n\t"
" movl %%eax, 20(%%esp)\n\t"
/* Place a copy of linuxBIOS in it's new location */
/* Move ``longs'' the linuxBIOS size is 4 byte aligned */
" movl 12(%%esp), %%edi\n\t"
" addl 8(%%esp), %%edi\n\t"
" movl 16(%%esp), %%esi\n\t"
" movl 8(%%esp), %%ecx\n\n"
" shrl $2, %%ecx\n\t"
" rep movsl\n\t"
/* Adjust the stack pointer to point into the new linuxBIOS image */
" addl 20(%%esp), %%esp\n\t"
/* Adjust the instruction pointer to point into the new linuxBIOS image */
" movl $1f, %%eax\n\t"
" addl 20(%%esp), %%eax\n\t"
" jmp *%%eax\n\t"
"1: \n\t"
/* Copy the linuxBIOS bounce buffer over linuxBIOS */
/* Move ``longs'' the linuxBIOS size is 4 byte aligned */
" movl 16(%%esp), %%edi\n\t"
" movl 12(%%esp), %%esi\n\t"
" movl 8(%%esp), %%ecx\n\t"
" shrl $2, %%ecx\n\t"
" rep movsl\n\t"
/* Now jump to the loaded image */
" movl 0(%%esp), %%eax\n\t"
" movl $0x0E1FB007, %%ebx\n\t"
" call *4(%%esp)\n\t"
/* The loaded image returned? */
" cli \n\t"
" cld \n\t"
/* Copy the saved copy of linuxBIOS where linuxBIOS runs */
/* Move ``longs'' the linuxBIOS size is 4 byte aligned */
" movl 16(%%esp), %%edi\n\t"
" movl 12(%%esp), %%esi\n\t"
" addl 8(%%esp), %%esi\n\t"
" movl 8(%%esp), %%ecx\n\t"
" shrl $2, %%ecx\n\t"
" rep movsl\n\t"
/* Adjust the stack pointer to point into the old linuxBIOS image */
" subl 20(%%esp), %%esp\n\t"
/* Adjust the instruction pointer to point into the old linuxBIOS image */
" movl $1f, %%eax\n\t"
" subl 20(%%esp), %%eax\n\t"
" jmp *%%eax\n\t"
"1: \n\t"
/* Drop the parameters I was passed */
" addl $24, %%esp\n\t"
/* Restore the callee save registers */
" popl %%ebx\n\t"
" popl %%edi\n\t"
" popl %%esi\n\t"
::
"g" (lb_start), "g" (buffer), "g" (lb_size),
"g" (entry), "g"(&adjusted_boot_notes)
);
}

View file

@ -142,11 +142,16 @@ unsigned long lb_table_fini(struct lb_header *head)
return (unsigned long)rec;
}
unsigned long setup_memory_table(
struct lb_memory *mem,
unsigned long totalram,
unsigned long low_table_start, unsigned long low_table_end)
/* Routines to extract part so the linuxBIOS table or
* information from the linuxBIOS table after we have written it.
* Currently get_lb_mem relies on a global we can change the
* implementaiton.
*/
static struct lb_memory *mem_ranges = 0;
struct lb_memory *get_lb_mem(void)
{
return mem_ranges;
}
unsigned long write_linuxbios_table(
@ -173,5 +178,8 @@ unsigned long write_linuxbios_table(
lb_memory_range(mem, LB_MEM_RAM, 0x00100000, (totalram - 1024) << 10);
low_table_end = lb_table_fini(head);
/* Remember where my valid memory ranges are */
mem_ranges = mem;
return low_table_end;
}

View file

@ -1,4 +1,4 @@
/*
/* -*- asm -*-
* $ $
*
*/
@ -11,20 +11,14 @@
#include <cpu/p6/apic.h>
#endif
/*
* This is the entry code (the mkrom(8) utility makes a jumpvector
* to this adddess.
* This is the entry code the code in .reset section
* jumps to this address.
*
* When we get here we are in x86 real mode.
*
* %cs = 0xf000 %ip = 0x0000
* %ds = 0x0000 %es = 0x0000
* %dx = 0x0yxx (y = 3 for i386, 5 for pentium, 6 for P6,
* where x is undefined)
* %fl = 0x0002
*/
.text
.section ".rom.data", "a", @progbits
.section ".rom.text", "ax", @progbits
CRT0_PARAMETERS
#include "crt0_includes.h"
CONSOLE_DEBUG_TX_STRING($str_after_ram)
@ -41,15 +35,20 @@ __main:
cld /* clear direction flag */
/* copy data segment from FLASH ROM to RAM */
leal EXT(_ldata), %esi
leal EXT(_data), %edi
movl $EXT(_eldata), %ecx
/* copy linuxBIOS from it's initial load location to
* the location it is compiled to run at.
* Normally this is copying from FLASH ROM to RAM.
*/
leal EXT(_liseg), %esi
leal EXT(_iseg), %edi
cmpl %esi, %edi
jz .Lnocopy
movl $EXT(_eliseg), %ecx
subl %esi, %ecx
jz .Lnodata /* should not happen */
jz .Lnocopy /* should not happen */
rep
movsb
.Lnodata:
.Lnocopy:
intel_chip_post_macro(0x12) /* post 12 */
/** clear stack */
@ -124,7 +123,7 @@ __main:
hlt
jmp .Lhlt
.section ".rodata"
.section ".rom.data"
str_after_ram: .string "Ram Initialize?\r\n"
str_pre_main: .string "before main\r\n"
.previous

View file

@ -33,18 +33,32 @@ ENTRY(_start)
SECTIONS
{
. = DEFINED(_ROMBASE)? _ROMBASE : _RAMBASE;
/* This section might be better named .setup */
.rom . : {
_rom = .;
*(.rom.text);
*(.rom.data);
. = ALIGN(16);
_erom = .;
}
_lrom = LOADADDR(.rom);
_elrom = LOADADDR(.rom) + SIZEOF(.rom);
. = DEFINED(_ROMBASE)? _RAMBASE : . ;
/*
* First we place the code and read only data (typically const declared).
* This get placed in rom.
*/
. = _ROMBASE;
.text (.) : {
.text . : AT (_elrom) {
_text = .;
*(.text);
*(.text.*);
. = ALIGN(16);
_etext = .;
}
.rodata (.) : {
_ltext = LOADADDR(.text);
_eltext = LOADADDR(.text) + SIZEOF(.text);
.rodata . : AT(_eltext){
_rodata = .;
. = ALIGN(4);
streams = . ;
@ -53,10 +67,9 @@ SECTIONS
*(.rodata)
*(.rodata.*)
_erodata = .;
}
. = _RAMBASE;
}
_lrodata = LOADADDR(.rodata);
_elrodata = LOADADDR(.rodata) + SIZEOF(.rodata);
/*
* After the code we place initialized data (typically initialized
* global variables). This gets copied into ram by startup code.
@ -64,19 +77,26 @@ SECTIONS
* whereas __data_loadstart and __data_loadend shows where in rom to
* copy from.
*/
.data (.): AT(_erodata) {
.data . : AT(_elrodata) {
_data = .;
*(.data)
_edata = .;
}
_ldata = LOADADDR(.data);
_eldata = LOADADDR(.data) + SIZEOF(.data);
/* The initialized data segment.
* This is all of the data that we copy from rom into the ram.
*/
_iseg = _text;
_eiseg = _edata;
_liseg = _ltext;
_eliseg = _eldata;
/*
* bss does not contain data, it is just a space that should be zero
* initialized on startup. (typically uninitialized global variables)
* crt0.S fills between _bss and _ebss with zeroes.
*/
.bss (.): {
.bss . : {
_bss = .;
*(.bss)
*(.sbss)
@ -84,20 +104,24 @@ SECTIONS
_ebss = .;
}
_end = .;
.heap (.): {
_heap = .;
/* Reserve 256K for the heap */
. = HEAP_SIZE ;
_eheap = .;
}
.stack (.) : {
.stack . : {
_stack = .;
/* Reserve a stack for each possible cpu, +1 extra */
. = ((MAX_CPUS * STACK_SIZE) + STACK_SIZE) ;
_estack = .;
}
.heap . : {
_heap = .;
/* Reserve 256K for the heap */
. = HEAP_SIZE ;
. = ALIGN(4);
_eheap = .;
}
/* The ram segment
* This is all address of the memory resident copy of linuxBIOS.
*/
_ram_seg = _text;
_eram_seg = _eheap;
/DISCARD/ : {
*(.comment)
*(.note)

View file

@ -13,9 +13,7 @@ option STACK_SIZE=0x2000
# By default on x86 we have a memory hole between 640K and 1MB
option MEMORY_HOLE=1
option USE_DEFAULT_LAYOUT=1
ldscript arch/i386/config/ldscript.base USE_DEFAULT_LAYOUT
ldscript arch/i386/config/ldscript.cacheram USE_CACHE_RAM
ldscript arch/i386/config/ldscript.base
# How do I add -mprefered-stack-boundary=2 if the compiler supports it?
# On x86 tt results in a code size reduction.

View file

@ -6,11 +6,18 @@
#endif
#if !defined(ASSEMBLY)
#define CACHE_RAM_SEG_BASE (((unsigned long)CACHE_RAM_BASE) - ((unsigned long)_RAMBASE))
extern char _cache_ram_seg_base[];
#define CACHE_RAM_SEG_BASE ((unsigned long)_cache_ram_seg_base)
#else
#define CACHE_RAM_SEG_BASE (CACHE_RAM_BASE - _RAMBASE)
#define CACHE_RAM_SEG_BASE (_cache_ram_seg_base)
#endif
#if !defined(ASSEMBLY)
extern char _rom_code_seg_base[];
#define ROM_CODE_SEG_BASE ((unsigned long)_rom_code_seg_base)
#else
#define ROM_CODE_SEG_BASE (_rom_code_seg_base)
#endif
#if !defined(ASSEMBLY)

View file

@ -4,17 +4,16 @@ jmp cpu_reset_out
#include <loglevel.h>
.section ".rodata"
.section ".rom.data"
#if ASM_CONSOLE_LOGLEVEL >= BIOS_SPEW
cpu_reset_str: .string "cpu_reset\r\n";
cpu_apic_str: .string "apic: ";
cpu_size_set_str: .string "cpu memory size set\r\n";
#endif
.previous
.text
__cpu_reset:
CONSOLE_SPEW_TX_STRING($cpu_reset_str)

View file

@ -0,0 +1,25 @@
/*
* $ $
*
*/
#include <arch/asm.h>
#include <arch/intel.h>
.section ".rom.data", "a", @progbits
.section ".rom.text", "ax", @progbits
#include "crt0_includes.h"
.globl _start
_start:
/* set new stack */
movl $_estack, %esp
call EXT(standalonemain)
/*NOTREACHED*/
.Lhlt:
intel_chip_post_macro(0xee) /* post fe */
hlt
jmp .Lhlt

View file

@ -25,8 +25,11 @@ addaction linuxbios nm -n linuxbios > linuxbios.map
makerule linuxbios.a : $(OBJECTS-1) ; rm -f linuxbios.a
addaction linuxbios.a ar cr linuxbios.a $(OBJECTS-1)
makerule crt0.s: crt0.S ; @echo "$(CPP) ... $< > $crt0.s "
addaction crt0.s @$(CPP) $(CPPFLAGS) -I$(TOP)/src $< > crt0.s
option CRT0=$(TOP)/src/arch/$(ARCH)/config/crt0.base
makerule crt0.S: $(CRT0) ; cp $< $@
makerule crt0.s: crt0.S crt0_includes.h $(CRT0_INCLUDES); @echo "$(CPP) ... $< > $@ "
addaction crt0.s @$(CPP) $(CPPFLAGS) -I$(TOP)/src $< > $@.new && mv $@.new $@
makerule crt0.o : crt0.s; @echo $(CC) ... -o $@ $<
addaction crt0.o @$(CC) -c $(CPU_OPT) -o $@ $<

View file

@ -25,7 +25,7 @@ it with the version available from LANL.
* protected mode.
*/
.text
/* .section ".rom.text" */
.code16
.globl EXT(_start)
.type EXT(_start), @function
@ -102,8 +102,8 @@ EXT(_start):
.align 4
.globl EXT(gdtptr16)
EXT(gdtptr16):
.word 4*8-1
.long gdt /* we know the offset */
.word gdt_end - gdt -1 /* compute the table limit */
.long gdt /* we know the offset */
.globl EXT(_estart)
EXT(_estart):

View file

@ -2,7 +2,7 @@
#include <arch/cache_ram.h>
.text
/* .section ".rom.text" */
.code32
/** This gdt has a 4 Gb code segment at 0x10, and a 4 GB data segment
@ -16,16 +16,16 @@
.align 4
.globl EXT(gdtptr)
EXT(gdtptr):
.word 4*8-1
.long gdt /* we know the offset */
.word gdt_end - gdt -1 /* compute the table limit */
.long gdt /* we know the offset */
gdt:
.word 0x0000, 0x0000 /* dummy */
.byte 0x00, 0x00, 0x00, 0x00
.word 0xffff, (CACHE_RAM_SEG_BASE & 0xffff) /* flat offset data segment */
.byte ((CACHE_RAM_SEG_BASE >> 16)& 0xff), 0x93, 0xcf
.byte ((CACHE_RAM_SEG_BASE >> 24) & 0xff)
.word 0xffff, _cache_ram_seg_base_low /* flat cache ram offset data segment */
.byte _cache_ram_seg_base_middle, 0x93, 0xcf
.byte _cache_ram_seg_base_high
.word 0xffff, 0x0000 /* flat code segment */
.byte 0x00, 0x9b, 0xcf, 0x00
@ -33,6 +33,12 @@ gdt:
.word 0xffff, 0x0000 /* flat data segment */
.byte 0x00, 0x93, 0xcf, 0x00
.word 0xffff, _rom_code_seg_base_low /* flat rom offset code segment */
.byte _rom_code_seg_base_middle, 0x9b, 0xcf
.byte _rom_code_seg_base_high
gdt_end:
/*
* When we come here we are in protected mode. We expand
* the stack and copies the data segment from ROM to the

12
src/cpu/i386/entry32.lds Normal file
View file

@ -0,0 +1,12 @@
_cache_ram_seg_base = DEFINED(CACHE_RAM_BASE)? CACHE_RAM_BASE - _rodata : 0;
_cache_ram_seg_base_low = (_cache_ram_seg_base) & 0xffff;
_cache_ram_seg_base_middle = (_cache_ram_seg_base >> 16) & 0xff;
_cache_ram_seg_base_high = (_cache_ram_seg_base >> 24) & 0xff;
_rom_code_seg_base = _ltext - _text;
_rom_code_seg_base_low = (_rom_code_seg_base) & 0xffff;
_rom_code_seg_base_middle = (_rom_code_seg_base >> 16) & 0xff;
_rom_code_seg_base_high = (_rom_code_seg_base >> 24) & 0xff;

View file

@ -0,0 +1,3 @@
_clrodata = _lrodata - _cache_ram_seg_base;
_celdata = _eldata - _cache_ram_seg_base;
___cache_ram_code_start = __cache_ram_code_start - _rom_code_seg_base;

View file

@ -1,9 +1,9 @@
#include <arch/cache_ram.h>
/* copy data segment from FLASH ROM to CACHE */
movl $(EXT(_ldata) - CACHE_RAM_SEG_BASE), %esi
movl $EXT(_data), %edi
movl $(EXT(_eldata) - CACHE_RAM_SEG_BASE), %ecx
movl $_clrodata, %esi
movl $_rodata, %edi
movl $_celdata, %ecx
subl %esi, %ecx
jz 1f /* should not happen */
rep
@ -23,5 +23,21 @@
/* set new stack */
movl $(_stack + STACK_SIZE), %esp
call cache_ram_start
/* The next bit is tricky.
* - I change code segments to handle the cache ram case.
* - I force the rom_code code segment again
* when I call cache_ram_start to avoid strange processor
* behavoir. A simple call instruction does not work at
* this point. This is due either to virutally mapped
* instruction caches, or address wrap around.
* - I change teh code segments back to my normal segment with
* a 4GB limit and a base address of 0.
*/
ljmp $0x20, $___cache_ram_code_start
.globl __cache_ram_code_start
__cache_ram_code_start:
lcall $0x20, $cache_ram_start
ljmp $0x10, $__cache_ram_code_done
.globl __cache_ram_code_done
__cache_ram_code_done:

View file

@ -390,11 +390,13 @@ typedef Elf64_Phdr Elf_phdr;
#endif
extern int elf_check_arch(Elf_ehdr *ehdr);
extern void jmp_to_elf_entry(void *entry);
extern int elfboot(void);
extern void jmp_to_elf_entry(void *entry, unsigned long buffer);
struct stream;
struct lb_memory;
extern int elfboot(struct stream *stream, struct lb_memory *mem);
#define FIRMWARE_TYPE "LinuxBIOS"
#define BOOTLOADER "elfboot"
#define BOOTLOADER_VERSION "0.99999"
#define BOOTLOADER_VERSION "1.0"
#endif /* elf.h */

View file

@ -20,4 +20,9 @@ void lb_memory_range(struct lb_memory *mem,
uint32_t type, unsigned long start, unsigned long size);
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);
#endif /* LINUXBIOS_TABLE_H */

View file

@ -3,7 +3,11 @@
#if !defined(ASSEMBLY)
#if HAVE_FALLBACK_BOOT
void boot_successful(void);
#else
#define boot_successful()
#endif
#endif /* ASSEMBLY */

View file

@ -15,5 +15,5 @@ object elfboot.o
object do_inflate.o
object floppy_subr.o
object delay.o
object fallback_boot.o
object fallback_boot.o HAVE_FALLBACK_BOOT
object compute_ip_checksum.o

View file

@ -3,68 +3,238 @@
#include <part/fallback_boot.h>
#include <boot/elf.h>
#include <boot/elf_boot.h>
#include <boot/linuxbios_tables.h>
#include <rom/read_bytes.h>
#include <string.h>
#include <subr.h>
#include <stdint.h>
#include <stdlib.h>
/* Maximum physical address we can use for the linuxBIOS bounce buffer.
*/
#ifndef MAX_ADDR
#define MAX_ADDR -1UL
#endif
extern unsigned char _text;
extern unsigned char _etext;
extern unsigned char _rodata;
extern unsigned char _erodata;
extern unsigned char _data;
extern unsigned char _edata;
extern unsigned char _bss;
extern unsigned char _ebss;
extern unsigned char _heap;
extern unsigned char _eheap;
extern unsigned char _stack;
extern unsigned char _estack;
struct range {
unsigned long start;
unsigned long end;
};
#define RANGE(SEGMENT) { (unsigned long)&_ ## SEGMENT, (unsigned long)&_e ## SEGMENT }
static struct range bad_ranges[] = {
RANGE(text),
RANGE(rodata),
RANGE(data),
RANGE(bss),
RANGE(heap),
RANGE(stack),
extern unsigned char _ram_seg;
extern unsigned char _eram_seg;
struct segment {
struct segment *next;
struct segment *prev;
unsigned long s_addr;
unsigned long s_memsz;
unsigned long s_offset;
unsigned long s_filesz;
};
static int safe_range(unsigned long start, unsigned long len)
/* The problem:
* Static executables all want to share the same addresses
* in memory because only a few addresses are reliably present on
* a machine, and implementing general relocation is hard.
*
* The solution:
* - Allocate a buffer twice the size of the linuxBIOS image.
* - Anything that would overwrite linuxBIOS copy into the lower half of
* the buffer.
* - After loading an ELF image copy linuxBIOS to the upper half of the
* buffer.
* - Then jump to the loaded image.
*
* Benefits:
* - Nearly arbitrary standalone executables can be loaded.
* - LinuxBIOS is preserved, so it can be returned to.
* - The implementation is still relatively simple,
* and much simpler then the general case implemented in kexec.
*
*/
static unsigned long get_bounce_buffer(struct lb_memory *mem)
{
/* Check through all of the segments and see if the segment
* that was passed in overlaps with any of them.
unsigned long lb_size;
unsigned long mem_entries;
unsigned long buffer;
int i;
lb_size = (unsigned long)(&_eram_seg - &_ram_seg);
/* Double linuxBIOS size so I have somewhere to place a copy to return to */
lb_size = lb_size + lb_size;
mem_entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
buffer = 0;
for(i = 0; i < mem_entries; i++) {
unsigned long mstart, mend;
unsigned long msize;
unsigned long tbuffer;
if (mem->map[i].type != LB_MEM_RAM)
continue;
if (mem->map[i].start > MAX_ADDR)
continue;
if (mem->map[i].size < lb_size)
continue;
mstart = mem->map[i].start;
msize = MAX_ADDR - mstart +1;
if (msize > mem->map[i].size)
msize = mem->map[i].size;
mend = mstart + msize;
tbuffer = mend - lb_size;
if (tbuffer < buffer)
continue;
buffer = tbuffer;
}
return buffer;
}
static int safe_range(struct lb_memory *mem, unsigned long buffer,
unsigned long start, unsigned long len)
{
/* Check through all of the memory segments and ensure
* the segment that was passed in is completely contained
* in RAM.
*/
int i;
unsigned long end = start + len;
for(i = 0; i < sizeof(bad_ranges)/sizeof(bad_ranges[0]); i++) {
if ((start < bad_ranges[i].end) &&
(end > bad_ranges[i].start)) {
printk_err(__FUNCTION__ " start 0x%x end 0x%x\n",
start, end);
printk_err(__FUNCTION__ " Conflicts with range %d\n",
i);
printk_err(" which starts at 0x%x ends at 0x%x\n",
bad_ranges[i].start, bad_ranges[i].end);
return 0;
unsigned long mem_entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]);
/* See if I conflict with the bounce buffer */
if (end >= buffer) {
return 0;
}
/* Walk through the table of valid memory ranges and see if I
* have a match.
*/
for(i = 0; i < mem_entries; i++) {
uint64_t mstart, mend;
uint32_t mtype;
mtype = mem->map[i].type;
mstart = mem->map[i].start;
mend = mstart + mem->map[i].size;
if ((mtype == LB_MEM_RAM) && (start < mend) && (end > mstart)) {
break;
}
}
if (i == mem_entries) {
printk_err("No matching ram area found for range:\n");
printk_err(" [0x%016lx, 0x%016lx)\n", start, end);
printk_err("Ram areas\n");
for(i = 0; i < mem_entries; i++) {
uint64_t mstart, mend;
uint32_t mtype;
mtype = mem->map[i].type;
mstart = mem->map[i].start;
mend = mstart + mem->map[i].size;
printk_err(" [0x%016lx, 0x%016lx) %s\n",
(unsigned long)mstart,
(unsigned long)mend,
(mtype == LB_MEM_RAM)?"RAM":"Reserved");
}
return 0;
}
return 1;
}
int elfboot(void)
static void bounce_segments(unsigned long buffer, struct segment *head)
{
/* Modify all segments that want to load onto linuxBIOS
* to load onto the bounce buffer instead.
*/
unsigned long lb_start = (unsigned long)&_ram_seg;
unsigned long lb_end = (unsigned long)&_eram_seg;
struct segment *ptr;
printk_spew("lb: [0x%016lx, 0x%016lx)\n",
lb_start, lb_end);
for(ptr = head->next; ptr != head; ptr = ptr->next) {
unsigned long start, middle, end;
start = ptr->s_addr;
middle = start + ptr->s_filesz;
end = start + ptr->s_memsz;
/* I don't conflict with linuxBIOS so get out of here */
if ((end <= lb_start) || (start >= lb_end))
continue;
printk_spew("segment: [0x%016lx, 0x%016lx, 0x%016lx)\n",
start, middle, end);
/* Slice off a piece at the beginning
* that doesn't conflict with linuxBIOS.
*/
if (start < lb_start) {
struct segment *new;
unsigned long len = lb_start - start;
new = malloc(sizeof(*new));
*new = *ptr;
new->s_memsz = len;
ptr->s_memsz -= len;
ptr->s_addr += len;
ptr->s_offset += len;
if (ptr->s_filesz > len) {
new->s_filesz = len;
ptr->s_filesz -= len;
} else {
ptr->s_filesz = 0;
}
new->next = ptr;
ptr->prev = new;
start = ptr->s_addr;
printk_spew(" early: [0x%016lx, 0x%016lx, 0x%016lx)\n",
new->s_addr,
new->s_addr + new->s_filesz,
new->s_addr + new->s_memsz);
}
/* Slice off a piece at the end
* that doesn't conflict with linuxBIOS
*/
if (end > lb_end) {
struct segment *new;
unsigned long len = end - lb_end;
new = malloc(sizeof(*new));
*new = *ptr;
ptr->s_memsz = len;
new->s_memsz -= len;
new->s_addr += len;
new->s_offset += len;
if (ptr->s_filesz > len) {
ptr->s_filesz = len;
new->s_filesz -= len;
} else {
new->s_filesz = 0;
}
ptr->next = new;
new->prev = ptr;
end = start + len;
printk_spew(" late: [0x%016lx, 0x%016lx, 0x%016lx)\n",
new->s_addr,
new->s_addr + new->s_filesz,
new->s_addr + new->s_memsz);
}
/* Now retarget this segment onto the bounce buffer */
ptr->s_addr = buffer + (ptr->s_addr - lb_start);
printk_spew(" bounce: [0x%016lx, 0x%016lx, 0x%016lx)\n",
ptr->s_addr,
ptr->s_addr + ptr->s_filesz,
ptr->s_addr + ptr->s_memsz);
}
}
int elfboot(struct stream *stream, struct lb_memory *mem)
{
static unsigned char header[ELF_HEAD_SIZE];
unsigned long offset;
Elf_ehdr *ehdr;
Elf_phdr *phdr;
int header_offset;
void *ptr, *entry;
unsigned long bounce_buffer;
struct segment dummy;
struct segment *head, *ptr;
void *entry;
int i;
byte_offset_t amtread;
@ -73,14 +243,22 @@ int elfboot(void)
printk_info("January 2002, Eric Biederman.\n");
printk_info("Version %s\n", BOOTLOADER_VERSION);
printk_info("\n");
if (streams->init() < 0) {
if (stream->init() < 0) {
printk_err("Could not initialize driver...\n");
goto out;
}
/* Find a bounce buffer so I can load to linuxBIOS's current location */
bounce_buffer = get_bounce_buffer(mem);
if (!bounce_buffer) {
printk_err("Could not find a bounce buffer...\n");
goto out;
}
post_code(0xf8);
/* Read in the initial ELF_HEAD_SIZE bytes */
if (streams->read(header, ELF_HEAD_SIZE) != ELF_HEAD_SIZE) {
if (stream->read(header, ELF_HEAD_SIZE) != ELF_HEAD_SIZE) {
printk_err("Read failed...\n");
goto out;
}
@ -113,79 +291,65 @@ int elfboot(void)
entry = (void *)(ehdr->e_entry);
phdr = (Elf_phdr *)&header[ehdr->e_phoff + header_offset];
/* Sanity check the segments and zero the extra bytes */
/* Create an ordered table of the segments */
memset(&dummy, 0, sizeof(dummy));
head = &dummy;
head->next = head->prev = head;
for(i = 0; i < ehdr->e_phnum; i++) {
unsigned char *dest, *end;
struct segment *new;
new = malloc(sizeof(*new));
new->s_addr = phdr[i].p_paddr;
new->s_memsz = phdr[i].p_memsz;
new->s_offset = phdr[i].p_offset;
new->s_filesz = phdr[i].p_filesz;
/* Clean up the values */
if (new->s_filesz > new->s_memsz) {
new->s_filesz = new->s_memsz;
}
for(ptr = head->next; ptr != head; ptr = ptr->next) {
if (new->s_offset < ptr->s_offset)
break;
}
new->next = ptr;
new->prev = ptr->prev;
ptr->prev->next = new;
ptr->prev = new;
}
if (!safe_range(phdr[i].p_paddr, phdr[i].p_memsz)) {
printk_err("Bad memory range: [0x%016lx, 0x%016lx)\n",
phdr[i].p_paddr, phdr[i].p_memsz);
/* Sanity check the segments */
for(ptr = head->next; ptr != head; ptr = ptr->next) {
if (!safe_range(mem, bounce_buffer, ptr->s_addr, ptr->s_memsz)) {
goto out;
}
dest = (unsigned char *)(phdr[i].p_paddr);
end = dest + phdr[i].p_memsz;
dest += phdr[i].p_filesz;
if (dest < end) {
printk_debug("Clearing Section: addr: 0x%016lx memsz: 0x%016lx\n",
(unsigned long)dest, end - dest);
/* Zero the extra bytes */
while(dest < end) {
*(dest++) = 0;
}
}
}
offset = 0;
while(1) {
Elf_phdr *cur_phdr = 0;
int i,len;
unsigned long start_offset;
unsigned char *dest, *middle, *end;
/* Find the program header that descibes the current piece
* of the file.
*/
for(i = 0; i < ehdr->e_phnum; i++) {
if (phdr[i].p_type != PT_LOAD) {
continue;
}
if (phdr[i].p_filesz == 0) {
continue;
}
if (phdr[i].p_filesz > phdr[i].p_memsz) {
continue;
}
if (phdr[i].p_offset >= offset) {
if (!cur_phdr ||
(cur_phdr->p_offset > phdr[i].p_offset)) {
cur_phdr = &phdr[i];
}
}
}
/* If we are out of sections we are done */
if (!cur_phdr) {
break;
}
/* Modify all segments that want to load onto linuxBIOS
* to load onto the bounce buffer instead.
*/
bounce_segments(bounce_buffer, head);
/* Load the segments */
offset = 0;
for(ptr = head->next; ptr != head; ptr = ptr->next) {
unsigned long start_offset;
unsigned long skip_bytes, read_bytes;
unsigned char *dest, *middle, *end;
byte_offset_t result;
printk_debug("Loading Section: addr: 0x%016lx memsz: 0x%016lx filesz: 0x%016lx\n",
cur_phdr->p_paddr, cur_phdr->p_memsz, cur_phdr->p_filesz);
ptr->s_addr, ptr->s_memsz, ptr->s_filesz);
/* Compute the boundaries of the section */
dest = (unsigned char *)(cur_phdr->p_paddr);
printk_debug("dest %p\n", dest);
end = dest + cur_phdr->p_memsz;
printk_debug("end %p\n", end);
len = cur_phdr->p_filesz;
printk_debug("len %d\n", len);
if (len > cur_phdr->p_memsz) {
len = cur_phdr->p_memsz;
}
middle = dest + len;
printk_debug("middle %d\n", middle);
start_offset = cur_phdr->p_offset;
dest = (unsigned char *)(ptr->s_addr);
end = dest + ptr->s_memsz;
middle = dest + ptr->s_filesz;
start_offset = ptr->s_offset;
printk_spew("[ 0x%016lx, %016lx, 0x%016lx) <- %016lx\n",
(unsigned long)dest,
(unsigned long)middle,
(unsigned long)end,
(unsigned long)start_offset);
printk_debug("start_offset %d\n", start_offset);
/* Skip intial buffer unused bytes */
if (offset < (ELF_HEAD_SIZE - header_offset)) {
if (start_offset < (ELF_HEAD_SIZE - header_offset)) {
@ -195,10 +359,12 @@ int elfboot(void)
}
}
printk_debug(__FUNCTION__ " skip %d\n", start_offset - offset);
/* Skip the unused bytes */
if (streams->skip(start_offset - offset) != (start_offset - offset)) {
printk_err("skip failed\n");
skip_bytes = start_offset - offset;
if (skip_bytes &&
((result = stream->skip(skip_bytes)) != skip_bytes)) {
printk_err("ERROR: Skip of %ld bytes skiped %ld bytes\n",
skip_bytes, result);
goto out;
}
offset = start_offset;
@ -206,55 +372,53 @@ int elfboot(void)
/* Copy data from the initial buffer */
if (offset < (ELF_HEAD_SIZE - header_offset)) {
size_t len;
if ((cur_phdr->p_filesz + start_offset) > ELF_HEAD_SIZE) {
if ((ptr->s_filesz + start_offset) > ELF_HEAD_SIZE) {
len = ELF_HEAD_SIZE - start_offset;
}
else {
len = cur_phdr->p_filesz;
len = ptr->s_filesz;
}
memcpy(dest, &header[header_offset + start_offset], len);
dest += len;
}
/* Read the section into memory */
printk_debug(__FUNCTION__ " read to %p size %d\n",
dest, middle-dest);
amtread = streams->read(dest, middle - dest);
if ( amtread /*!=*/ < (middle - dest)) {
printk_err("Read for section failed...\n");
printk_err("Wanted %d got %d\n", middle-dest, amtread);
read_bytes = middle - dest;
if (read_bytes &&
((result = stream->read(dest, read_bytes)) != read_bytes)) {
printk_err("ERROR: Read of %ld bytes read %ld bytes...\n",
read_bytes, result);
goto out;
}
offset += cur_phdr->p_filesz;
/* The extra bytes between dest & end have been zeroed */
offset += ptr->s_filesz;
/* Zero the extra bytes between middle & end */
if (middle < end) {
printk_debug("Clearing Section: addr: 0x%016lx memsz: 0x%016lx\n",
(unsigned long)middle, end - middle);
/* Zero the extra bytes */
memset(middle, 0, end - middle);
}
}
/* Reset to booting from this image as late as possible */
streams->fini();
stream->fini();
boot_successful();
printk_debug("Jumping to boot code\n");
post_code(0xfe);
/* Jump to kernel */
jmp_to_elf_entry(entry);
jmp_to_elf_entry(entry, bounce_buffer);
return 1;
out:
printk_err("Bad ELF Image\n");
for(i = 0; i < sizeof(*ehdr); i++) {
if ((i & 0xf) == 0) {
printk_err("\n");
}
printk_err("%02x ", header[i]);
}
printk_err("\n");
printk_err("Cannot Load ELF Image\n");
/* Reset to booting from this image as late as possible */
streams->fini();
#if 0
boot_successful();
#endif
/* Shutdown the stream device */
stream->fini();
return 0;
}

View file

@ -24,6 +24,7 @@
#include <rom/read_bytes.h>
#include <string.h>
#include <stdlib.h>
#include <boot/linuxbios_table.h>
#if USE_ELF_BOOT
#include <boot/elf.h>
@ -51,7 +52,7 @@ int linuxbiosmain(unsigned long base, unsigned long totalram)
#endif /* USE_TFTP */
#if USE_ELF_BOOT
return elfboot();
return elfboot(streams, get_lb_mem());
#else /* !ELF_BOOT */
printk_info("\n");
printk_info("Welcome to start32, the open sourced starter.\n");

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit northbridge/amd/amd76x/reset_test.inc
mainboardinit cpu/k7/earlymtrr.inc

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit northbridge/acer/m1631/chipset_init.inc
mainboardinit superio/acer/m1535/setup_serial.inc

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit superio/sis/950/setup_serial.inc
mainboardinit pc80/serial.inc

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds

View file

@ -3,6 +3,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds
@ -23,43 +24,44 @@ option XIP_ROM_BASE=0xffff0000
option XIP_ROM_SIZE=0x10000
option STACK_SIZE=0x2000
#######
## Testing of the cache ram idea on a PIII
#######
option CACHE_RAM_BASE=0xfff00000
option CACHE_RAM_SIZE=0x00010000
option USE_CACHE_RAM=1
nooption USE_DEFAULT_LAYOUT
option RAMTEST=1
mainboardinit cpu/i786/earlymtrr.inc
#mainboardinit ram/ramtest.inc
mainboardinit cpu/p6/cache_ram_init.inc
#mainboardinit mainboard/supermicro/p4dc6/cache_test.inc
mainboardinit cpu/p6/cache_ram_start.inc
mainboardinit cpu/p6/cache_ram_fini.inc
option USE_GENERIC_SDRAM=1
option USE_GENERIC_SDRAM_ENABLE=1
option USE_PIIX4E_SMBUS=1
option USE_GENERIC_DUMP_SPD=1
option USE_GENERIC_ZERO_ECC_SDRAM=1
option USE_RAMTEST=1
object mainboard_raminit.c
option SMBUS_MEM_DEVICE_START=0x50
option SMBUS_MEM_DEVICE_END=0x53
option SMBUS_MEM_DEVICE_INC=1
dir /src/sdram
dir /src/ram
#######
# Disable the cache as ram code until we can get a fully working version
########
### Testing of the cache ram idea on a PIII
########
#
#option CACHE_RAM_BASE=0xfff00000
#option CACHE_RAM_SIZE=0x00010000
#option USE_CACHE_RAM=1
#nooption USE_DEFAULT_LAYOUT
#option RAMTEST=1
#
#mainboardinit cpu/i786/earlymtrr.inc
##mainboardinit ram/ramtest.inc
#mainboardinit cpu/p6/cache_ram_init.inc
##mainboardinit mainboard/supermicro/p4dc6/cache_test.inc
#mainboardinit cpu/p6/cache_ram_start.inc
#mainboardinit cpu/p6/cache_ram_fini.inc
#
#option USE_GENERIC_SDRAM=1
#option USE_GENERIC_SDRAM_ENABLE=1
#option USE_PIIX4E_SMBUS=1
#option USE_GENERIC_DUMP_SPD=1
#option USE_GENERIC_ZERO_ECC_SDRAM=1
#option USE_RAMTEST=1
#object mainboard_raminit.c
#
#option SMBUS_MEM_DEVICE_START=0x50
#option SMBUS_MEM_DEVICE_END=0x53
#option SMBUS_MEM_DEVICE_INC=1
#dir /src/sdram
#dir /src/ram
#
#
########
northbridge intel/440gx
southbridge intel/piix4e
#mainboardinit cpu/p6/earlymtrr.inc
mainboardinit cpu/p6/earlymtrr.inc
superio NSC/pc87309

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit superio/sis/950/setup_serial.inc
mainboardinit pc80/serial.inc

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit superio/sis/950/setup_serial.inc
mainboardinit pc80/serial.inc

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
# These are ONLY used for doc.
#mainboardinit cpu/i386/reset16.inc

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit superio/sis/950/setup_serial.inc
mainboardinit pc80/serial.inc

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit superio/via/vt82c686/setup_serial.inc
mainboardinit pc80/serial.inc

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit superio/sis/950/setup_serial.inc
mainboardinit pc80/serial.inc

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit pc80/serial.inc
mainboardinit arch/i386/lib/console.inc

View file

@ -1,88 +1,226 @@
##
## Set all of the defaults for an x86 architecture
##
arch i386
##
## Build our 16 bit and 32 bit linuxBIOS entry code
##
mainboardinit cpu/i386/entry16.inc
ldscript cpu/i386/entry16.lds
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
##
## Build our reset vector (This is where linuxBIOS is entered)
##
mainboardinit cpu/i386/reset16.inc USE_FALLBACK_IMAGE
ldscript cpu/i386/reset16.lds USE_FALLBACK_IMAGE
mainboardinit cpu/i386/reset32.inc USE_NORMAL_IMAGE
ldscript cpu/i386/reset32.lds USE_NORMAL_IMAGE
option ROM_IMAGE_SIZE=32768
rambase 0x00008000
option USE_CACHE_RAM=1
option CACHE_RAM_BASE=0xfff70000
option CACHE_RAM_SIZE=0x00010000
nooption USE_DEFAULT_LAYOUT
option STACK_SIZE=0x2000
option USE_FALLBACK_IMAGE=0
option ROM_SIZE=524288
expr USE_NORMAL_IMAGE=!USE_FALLBACK_IMAGE
expr ROM_SECTION_SIZE =(USE_FALLBACK_IMAGE*65536)+(USE_NORMAL_IMAGE*(ROM_SIZE - 65536))
expr ROM_SECTION_OFFSET=(USE_FALLBACK_IMAGE*(ROM_SIZE-65536))+(USE_NORMAL_IMAGE*0)
expr ZKERNEL_START =(0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
expr PAYLOAD_SIZE =ROM_SECTION_SIZE - ROM_IMAGE_SIZE
expr _ROMBASE =ZKERNEL_START + PAYLOAD_SIZE
expr XIP_ROM_SIZE = 65536
expr XIP_ROM_BASE = _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE
## This is the early phase of linuxBIOS startup
## Things are delicate and we test to see if we should
## failover to another image.
mainboardinit northbridge/intel/82860/reset_test.inc
mainboardinit arch/i386/lib/noop_failover.inc USE_NORMAL_IMAGE
mainboardinit southbridge/intel/82801/cmos_failover.inc USE_FALLBACK_IMAGE
ldscript arch/i386/lib/failover.lds USE_FALLBACK_IMAGE
###
### O.k. We aren't just an intermediary anymore!
###
##
## Setup our mtrrs
##
mainboardinit cpu/i786/earlymtrr.inc
##
## Setup the serial port
##
mainboardinit superio/winbond/w83627hf/setup_serial.inc
mainboardinit pc80/serial.inc
mainboardinit arch/i386/lib/console.inc
#mainboardinit ram/ramtest.inc
#mainboardinit northbridge/intel/82860/reset_test.inc
##
## Switch temporarily into C code to setup RAM
##
mainboardinit cpu/i786/cache_ram_init.inc
#mainboardinit mainboard/supermicro/p4dc6/cache_test.inc
mainboardinit cpu/i786/cache_ram_start.inc
mainboardinit cpu/i786/cache_ram_fini.inc
ldscript cpu/i786/cache_ram.lds
##
## Include the secondary Configuration files
##
northbridge intel/82860
southbridge intel/82801
southbridge intel/82806
nsuperio winbond/w83627hf com1={1} com2={1} floppy=1 lpt=1 keyboard=1
dir /src/pc80
dir /src/superio/winbond/w83627hf
cpu p5
cpu p6
cpu i786
option RAMTEST=1
option NO_KEYBOARD
option ENABLE_FIXED_AND_VARIABLE_MTRRS
#option FINAL_MAINBOARD_FIXUP
#object cacheramtest.o
##
## Build the objects we have code for in this directory.
##
object mainboard.o
object mtrr_values.o
object mptable.o HAVE_MP_TABLE
object irq_tables.o HAVE_PIRQ_TABLE
#keyboard pc80
dir ../../../pc80
dir /src/superio/winbond/w83627hf
# FIXME are the SMBUS DIMM locations documented anywhere?
###
### Build options
###
##
## Location of the DIMM EEPROMS on the SMBUS
## This is fixed into a narrow range by the DIMM package standard.
##
option SMBUS_MEM_DEVICE_START=(0xa << 3)
option SMBUS_MEM_DEVICE_END=(SMBUS_MEM_DEVICE_START +3)
option SMBUS_MEM_DEVICE_INC=1
##
## Customize our winbond superio chip for this motherboard
##
option SIO_BASE=0x2e
option SIO_SYSTEM_CLK_INPUT=SIO_SYSTEM_CLK_INPUT_48MHZ
option SMP=1
option IOAPIC=1
option HAVE_MP_TABLE=1
option HAVE_PIRQ_TABLE=1
option MAX_CPUS=2
option HAVE_MTRR_TABLE=1
#option FINAL_MAINBOARD_FIXUP=1
##
## Build code for the fallback boot
##
option HAVE_FALLBACK_BOOT=1
##
## Build code for using cache as RAM
##
option USE_CACHE_RAM=1
##
## Build code to reset the motherboard from linuxBIOS
##
option HAVE_HARD_RESET=1
##
## Build code to export a programmable irq routing table
##
option HAVE_PIRQ_TABLE=1
##
## Do not build special code to the keyboard
##
option NO_KEYBOARD
##
## Build code to export an x86 MP table
## Useful for specifying IRQ routing values
##
option HAVE_MP_TABLE=1
##
## Build code for SMP support
## Only worry about 2 micro processors
##
option SMP=1
option MAX_CPUS=2
##
## Build code to setup a generic IOAPIC
##
option IOAPIC=1
##
## MEMORY_HOLE instructs earlymtrr.inc to
## enable caching from 0-640KB and to disable
## caching from 640KB-1MB using fixed MTRRs
##
## Enabling this option breaks SMP because secondary
## CPU identification depends on only variable MTRRs
## being enabled.
##
nooption MEMORY_HOLE
cpu p5
cpu p6
cpu i786
##
## Don't do a generic MTRR setup
## Instead use values from the fixed_mtrr_values array
##
option HAVE_MTRR_TABLE=1
##
## Enable both fixed and variable MTRRS
## When we setup MTRRs in mtrr.c
##
## We must setup the fixed mtrrs or we confuse SMP secondary
## processor identification
##
option ENABLE_FIXED_AND_VARIABLE_MTRRS
##
## Figure out which type of linuxBIOS image to build
## If we aren't a fallback image we must be a normal image
## This is useful for optional includes
##
option USE_FALLBACK_IMAGE=0
expr USE_NORMAL_IMAGE=!USE_FALLBACK_IMAGE
###
### LinuxBIOS layout values
###
## ROM_SIZE is the size of boot ROM that this board will use.
option ROM_SIZE=524288
## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
option ROM_IMAGE_SIZE=49152
## LinuxBIOS C code runs at this location in RAM
option _RAMBASE=0x00008000
## For the trick of using cache as ram
## put the fake ram location at this address
#option CACHE_RAM_BASE=0xfff70000
option CACHE_RAM_SIZE=0x00010000
##
## Use a small 8K stack
##
option STACK_SIZE=0x2000
##
## Use a small 8K heap
##
option HEAP_SIZE=0x2000
##
## Compute the location and size of where this firmware image
## (linuxBIOS plus bootloader) will linv in the boot rom chip.
##
expr ROM_SECTION_SIZE =(USE_FALLBACK_IMAGE*65536)+(USE_NORMAL_IMAGE*(ROM_SIZE - 65536))
expr ROM_SECTION_OFFSET=(USE_FALLBACK_IMAGE*(ROM_SIZE-65536))+(USE_NORMAL_IMAGE*0)
##
## Compute the start location and size size of
## The linuxBIOS bootloader.
##
expr ZKERNEL_START =(0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
expr PAYLOAD_SIZE =ROM_SECTION_SIZE - ROM_IMAGE_SIZE
##
## Compute where this copy of linuxBIOS will start in the boot rom
##
expr _ROMBASE =ZKERNEL_START + PAYLOAD_SIZE
##
## Compute a range of ROM that can cached to speed of linuxBIOS,
## execution speed.
##
expr XIP_ROM_SIZE = 65536
expr XIP_ROM_BASE = _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE

View file

@ -1,37 +1,104 @@
# This will make a target directory of ./winfast
# Note that this is RELATIVE TO WHERE YOU ARE WHEN YOU RUN THE
# CONFIG TOOL. Make it absolute if you like
target /home/eric/projects/freebios/p4dc6-build/normal
## This will make a target directory of ./fallback
## This is relative to where the configuration file resides in the filesystem
target ./fallback
mainboard supermicro/p4dc6
## Build a fallback not a normal image.
option USE_FALLBACK_IMAGE=1
## Build an image for a 512KB rom
## ./fallback/romimage is just the last 64KB which we reserve for the fallback image.
option ROM_SIZE=524288
#option ROM_SIZE=1048576
option ROM_IMAGE_SIZE=32768
## Select the maximum size the linuxBIOS code can compile to.
## Allow linuxBIOS to be up to 48KB in size
option ROM_IMAGE_SIZE=49152
# Enable Serial Console for debugging
# It will come up at 115200,8n1
##
### The Serial Console
##
## Hardware flow control is currently ignored.
## Enable the Serial Console
option SERIAL_CONSOLE=1
#nooption SERIAL_CONSOLE
#option TTYS0_BAUD=9600
## Select the serial console baud rate.
option TTYS0_BAUD=115200
#option TTYS0_BAUD=57600
#option TTYS0_BAUD=38400
#option TTYS0_BAUD=19200
#option TTYS0_BAUD=9600
#option TTYS0_BAUD=4800
#option TTYS0_BAUD=2400
#option TTYS0_BAUD=1200
# Generate debugging output
# Select the serial console base port
option TTYS0_BASE=0x3f8
# Select the serial protocol
# This defaults to 8 data bits, 1 stop bit, and no parity
option TTYS0_LCS=0x3
##
### Select the linuxBIOS loglevel
##
## EMERG 1 system is unusable
## ALERT 2 action must be taken immediately
## CRIT 3 critical conditions
## ERR 4 error conditions
## WARNING 5 warning conditions
## NOTICE 6 normal but significant condition
## INFO 7 informational
## DEBUG 8 debug-level messages
## SPEW 9 Way too many details
## Request this level of debugging output
option DEFAULT_CONSOLE_LOGLEVEL=9
## At a maximum only compile in this level of debugging
option MAXIMUM_CONSOLE_LOGLEVEL=6
#option DEFAULT_CONSOLE_LOGLEVEL=5
# Select the boot device
#option USE_CACHE_RAM=1
## Use the elf bootloader
option USE_ELF_BOOT=1
## Select the boot device
option USE_GENERIC_ROM=1
#option BOOT_FLOPPY=1
#option USE_SERIAL_FILL_INBUF=1
#option BOOT_IDE=1
# Use the elf bootloader
option USE_ELF_BOOT=1
# Load etherboot with the elf bootloader
# The payload command is relative the build directory
# So .. is the directory this config file resides in
payload ../eepro100.ebi
##
## Cpu Speed
##
option CPU_CLOCK_MULTIPLIER XEON_X8
#option CPU_CLOCK_MULTIPLIER XEON_X9
#option CPU_CLOCK_MULTIPLIER XEON_X10
#option CPU_CLOCK_MULTIPLIER XEON_X11
#option CPU_CLOCK_MULTIPLIER XEON_X12
#option CPU_CLOCK_MULTIPLIER XEON_X13
#option CPU_CLOCK_MULTIPLIER XEON_X14
#option CPU_CLOCK_MULTIPLIER XEON_X15
#option CPU_CLOCK_MULTIPLIER XEON_X16
#option CPU_CLOCK_MULTIPLIER XEON_X17
#option CPU_CLOCK_MULTIPLIER XEON_X18
#option CPU_CLOCK_MULTIPLIER XEON_X19
#option CPU_CLOCK_MULTIPLIER XEON_X19
#option CPU_CLOCK_MULTIPLIER XEON_X20
#option CPU_CLOCK_MULTIPLIER XEON_X21
#option CPU_CLOCK_MULTIPLIER XEON_X22
#option CPU_CLOCK_MULTIPLIER XEON_X23
##
## Select power on after power fail setting
option MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBARD_POWER_ON
#option MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBARD_POWER_ON

View file

@ -1,37 +1,105 @@
# This will make a target directory of ./winfast
# Note that this is RELATIVE TO WHERE YOU ARE WHEN YOU RUN THE
# CONFIG TOOL. Make it absolute if you like
target /home/eric/projects/freebios/p4dc6-build/normal
## This will make a target directory of ./normal
## This is relative to where the configuration file resides in the filesystem
target ./normal
mainboard supermicro/p4dc6
## Build a normal not a fallback image.
option USE_FALLBACK_IMAGE=0
## Build an image for a 512KB rom
## ./normal/romimage is the entire rom image except for the last 64KB
## which are reserved for the fallback image.
option ROM_SIZE=524288
#option ROM_SIZE=1048576
## Select the maximum size the linuxBIOS code can compile to.
## Allow linuxBIOS to be up to 48KB in size
option ROM_IMAGE_SIZE=49152
# Enable Serial Console for debugging
# It will come up at 115200,8n1
##
### The Serial Console
##
## Hardware flow control is currently ignored.
## Enable the Serial Console
option SERIAL_CONSOLE=1
#nooption SERIAL_CONSOLE
#option TTYS0_BAUD=9600
## Select the serial console baud rate.
option TTYS0_BAUD=115200
#option TTYS0_BAUD=57600
#option TTYS0_BAUD=38400
#option TTYS0_BAUD=19200
#option TTYS0_BAUD=9600
#option TTYS0_BAUD=4800
#option TTYS0_BAUD=2400
#option TTYS0_BAUD=1200
# Generate debugging output
# Select the serial console base port
option TTYS0_BASE=0x3f8
# Select the serial protocol
# This defaults to 8 data bits, 1 stop bit, and no parity
option TTYS0_LCS=0x3
##
### Select the linuxBIOS loglevel
##
## EMERG 1 system is unusable
## ALERT 2 action must be taken immediately
## CRIT 3 critical conditions
## ERR 4 error conditions
## WARNING 5 warning conditions
## NOTICE 6 normal but significant condition
## INFO 7 informational
## DEBUG 8 debug-level messages
## SPEW 9 Way too many details
## Request this level of debugging output
option DEFAULT_CONSOLE_LOGLEVEL=9
## At a maximum only compile in this level of debugging
option MAXIMUM_CONSOLE_LOGLEVEL=8
#option DEFAULT_CONSOLE_LOGLEVEL=5
# Select the boot device
#option USE_CACHE_RAM=1
## Use the elf bootloader
option USE_ELF_BOOT=1
## Select the boot device
option USE_GENERIC_ROM=1
#option BOOT_FLOPPY=1
#option USE_SERIAL_FILL_INBUF=1
#option BOOT_IDE=1
# Use the elf bootloader
option USE_ELF_BOOT=1
# Load etherboot with the elf bootloader
# The payload command is relative the build directory
# So .. is the directory this config file resides in
payload ../eepro100.ebi
##
## Cpu Speed
##
#option CPU_CLOCK_MULTIPLIER XEON_X8
#option CPU_CLOCK_MULTIPLIER XEON_X9
#option CPU_CLOCK_MULTIPLIER XEON_X10
#option CPU_CLOCK_MULTIPLIER XEON_X11
#option CPU_CLOCK_MULTIPLIER XEON_X12
#option CPU_CLOCK_MULTIPLIER XEON_X13
#option CPU_CLOCK_MULTIPLIER XEON_X14
#option CPU_CLOCK_MULTIPLIER XEON_X15
#option CPU_CLOCK_MULTIPLIER XEON_X16
option CPU_CLOCK_MULTIPLIER XEON_X17
#option CPU_CLOCK_MULTIPLIER XEON_X18
#option CPU_CLOCK_MULTIPLIER XEON_X19
#option CPU_CLOCK_MULTIPLIER XEON_X19
#option CPU_CLOCK_MULTIPLIER XEON_X20
#option CPU_CLOCK_MULTIPLIER XEON_X21
#option CPU_CLOCK_MULTIPLIER XEON_X22
#option CPU_CLOCK_MULTIPLIER XEON_X23
##
## Select power on after power fail setting
option MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBARD_POWER_ON
#option MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBARD_POWER_ON

View file

@ -24,7 +24,32 @@ unsigned long initial_apicid[MAX_CPUS] =
0, 6
};
#ifndef CPU_CLOCK_MULTIPLIER
#define CPU_CLOCK_MULTIPLIER XEON_X17
#endif
#define MAINBOARD_POWER_ON 1
#define MAINBOARD_POWER_OFF 2
#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL
#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
#endif
static void set_power_on_after_power_fail(int setting)
{
switch(setting) {
case MAINBOARD_POWER_ON:
default:
ich2_power_after_power_fail(1);
w832627hf_power_after_power_fail(POWER_ON);
break;
case MAINBOARD_POWER_OFF:
ich2_power_after_power_fail(0);
w832627hf_power_after_power_fail(POWER_OFF);
break;
}
}
void mainboard_fixup(void)
{
ich2_enable_ioapic();
@ -33,12 +58,10 @@ void mainboard_fixup(void)
ich2_rtc_init();
ich2_lpc_route_dma(0xff);
isa_dma_init();
#if 1
/* FIXME don't hard code these */
ich2_set_cpu_multiplier(XEON_X17);
#endif
ich2_power_after_power_fail(1);
w832627hf_power_after_power_fail(POWER_ON);
ich2_set_cpu_multiplier(CPU_CLOCK_MULTIPLIER);
set_power_on_after_power_fail(MAINBOARD_POWER_ON_AFTER_POWER_FAIL);
return;
}
@ -66,6 +89,7 @@ void cache_ram_start(void)
{
int error;
error = 0;
/* displayinit MUST PRECEDE ALL PRINTK! */
displayinit();
printk_info("printk: Testing %d %s\n", 123, "testing!!!");

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds

View file

@ -2,6 +2,7 @@ arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit superio/via/vt82c686/setup_serial.inc
mainboardinit pc80/serial.inc

View file

@ -3,14 +3,15 @@
*/
jmp dumpnorth_skip
.section ".rodata"
.section ".rom.data"
dn_banner: .string "dump northbridge: \r\n"
dn_done: .string "Done.\r\n"
dn_before: .string "Before setting values: \r\n"
dn_after: .string "After setting values: \r\n"
.previous
.text
dumpnorth:
mov %esp, %ebp
CONSOLE_INFO_TX_STRING($dn_banner)

View file

@ -5,15 +5,15 @@
*/
jmp rt_skip
.section ".rodata"
.section ".rom.data"
rt_test: .string "Testing SDRAM : "
rt_fill: .string "SDRAM fill:\r\n"
rt_verify: .string "SDRAM verify:\r\n"
rt_toomany: .string "Too many errors.\r\n"
rt_done: .string "Done.\r\n"
.previous
.text
ramtest:
#ifdef RAMTEST
mov %eax, %esi

2
src/standalone/Config Normal file
View file

@ -0,0 +1,2 @@
nooption _ROMBASE
option CRT0=$(TOP)/src/arch/$(ARCH)/standalone/crt0.S

View file

@ -0,0 +1,8 @@
# Load the default standalone application options
dir ..
option _RAMBASE=0x00004000
object lbbl.o
payload /dev/null
option USE_ELF_BOOT=1

View file

@ -0,0 +1,18 @@
# This will make a target directory of ./lbbl
target ./lbbl
arch i386
dir src/standalone/lbbl
# Generate debugging output
option DEFAULT_CONSOLE_LOGLEVEL=9
option MAXIMUM_CONSOLE_LOGLEVEL=8
#option DEFAULT_CONSOLE_LOGLEVEL=5
option SERIAL_CONSOLE=1
option TTYS0_BAUD=115200
option BOOT_IDE=0
option BOOT_FLOPPY=1
option USE_SERIAL_FILL_INBUF=0
#option USE_GENERIC_ROM=0

100
src/standalone/lbbl/lbbl.c Normal file
View file

@ -0,0 +1,100 @@
#include <printk.h>
#include <subr.h>
#include <boot/elf.h>
#include <rom/read_bytes.h>
#include <boot/linuxbios_tables.h>
#include <ip_checksum.h>
#include <stdlib.h>
static unsigned long count_lb_records(void *start, unsigned long length)
{
struct lb_record *rec;
void *end;
unsigned long count;
count = 0;
end = ((char *)start) + length;
for(rec = start; ((void *)rec < end) &&
((signed long)rec->size <= (end - (void *)rec));
rec = (void *)(((char *)rec) + rec->size)) {
count++;
}
return count;
}
static int find_lb_table(struct lb_header **result, void *start, void *end)
{
unsigned char *ptr;
/* For now be stupid.... */
for(ptr = start; (void *)ptr < end; ptr += 16) {
struct lb_header *head = (void *)ptr;
if ((head->signature[0] == 'L') &&
(head->signature[1] == 'B') &&
(head->signature[2] == 'I') &&
(head->signature[3] == 'O') &&
(head->header_bytes == sizeof(*head)) &&
(compute_ip_checksum(head, sizeof(*head)) == 0) &&
(compute_ip_checksum(ptr + sizeof(*head), head->table_bytes) ==
head->table_checksum) &&
(count_lb_records(ptr + sizeof(*head), head->table_bytes) ==
head->table_entries)
) {
*result = (struct lb_header *)ptr;
return 1;
}
}
return 0;
}
static struct lb_memory *lookup_meminfo(void)
{
struct lb_header *head;
struct lb_record *rec;
void *start, *end;
if (!find_lb_table(&head, (void *)0x00000, (void *)0x1000)) {
if (!find_lb_table(&head, (void *)0xf0000, (void*)0x100000)) {
printk_err("Cannot find linuxbios table...\n");
while(1);
}
}
start = ((unsigned char *)head) + sizeof(*head);
end = ((char *)start) + head->table_bytes;
for(rec = start; ((void *)rec < end) &&
((long)rec->size <= (end - (void *)rec));
rec = (void *)(((char *)rec) + rec->size)) {
switch(rec->tag) {
case LB_TAG_MEMORY:
return (struct lb_memory *)rec;
}
}
printk_err("Cannot find memory range table\n");
while(1);
}
void standalonemain(void)
{
int i;
int max;
malloc_mark_t place;
struct lb_memory *mem;
/* displayinit MUST PRECEDE ALL PRINTK! */
displayinit();
printk_info("LBBL\n");
max = estreams - streams;
mem = lookup_meminfo();
printk_info("%d boot devices present\n", max);
for(i = 0; i < max; i++) {
int result = 1;
malloc_mark(&place);
printk_info("Trying to boot from %d\n", i);
result = elfboot(&streams[i], mem);
malloc_release(&place);
if (result) {
/* displayinit MUST PRECEDE ALL PRINTK! */
displayinit();
}
}
printk_err("All boot devices failed\n");
}

View file

@ -26,7 +26,6 @@ numsuperio = 0
# Architecture variables
arch = ''
makebase = ''
crt0base = ''
ldscriptbase = ''
makeoptions = {}
@ -241,15 +240,13 @@ def common_command_action(dir, type, name):
# <my_arch> is typically i386 or alpha.
# Set various variables and execute a make.base file.
def set_arch(dir, my_arch):
global arch, makebase, crt0base
global arch, makebase
arch = my_arch
configpath = os.path.join(treetop, "src/arch/", my_arch, "config")
makebase = os.path.join(configpath, "make.base")
crt0base = os.path.join(configpath, "crt0.base")
print "Now Process the ", my_arch, " base files"
if (debug):
print "Makebase is :", makebase, ":"
makedefine(dir, "ARCH="+my_arch)
doconfigfile(treetop, makebase)
# COMMAND: dir <name>
@ -865,25 +862,18 @@ def doconfigfile(dir, filename):
# Functions for writing output files
# -----------------------------------------------------------------------------
# Write out crt0.S (top-level assembly language) file.
def writecrt0(path):
crt0filepath = os.path.join(path, "crt0.S")
# Write out crt0_includes.h (top-level assembly language) include file.
def writecrt0_includes(path):
crt0filepath = os.path.join(path, "crt0_includes.h")
print "Creating", crt0filepath
file = open(crt0filepath, 'w+')
crt0lines = readfile(crt0base)
if (debug):
print "CRT0 ", crt0lines
for line in crt0lines:
if (string.strip(line) <> "CRT0_PARAMETERS"):
file.write(line)
else:
for mbifile in mainboardinit_files:
if mbifile[1]:
file.write("#if %s == 1\n" %mbifile[1])
file.write("#include <%s>\n" % mbifile[0])
if mbifile[1]:
file.write("#endif\n")
for mbifile in mainboardinit_files:
if mbifile[1]:
file.write("#if %s == 1\n" %mbifile[1])
file.write("#include <%s>\n" % mbifile[0])
if mbifile[1]:
file.write("#endif\n")
file.close();
@ -938,7 +928,8 @@ def writemakefilesettings(path):
file = open(filename, 'w+')
writemakefileheader(file, filename)
file.write("TOP=%s\n" % (treetop))
file.write("TOP:=%s\n" % (treetop))
file.write("ARCH:=%s\n" % (arch))
keys = makeoptions.keys()
keys.sort()
@ -962,9 +953,10 @@ def writemakefilesettings(path):
file.write("%s " % key)
file.write("\n");
file.close();
# write the makefile
# we're not sure whether to write crt0.S yet. We'll see.
# let's try the Makefile
# first, dump all the -D stuff
@ -1015,6 +1007,13 @@ CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))
else:
file.write("LDSUBSCRIPTS-1 += %s\n" % (script))
# Print out the dependencies for crt0_includes.h
file.write("\n# Dependencies for crt0_includes.h\n")
file.write("CRT0_INCLUDES:=\n")
for mbifile in mainboardinit_files:
file.write("CRT0_INCLUDES += $(TOP)/src/%s\n" % mbifile[0])
file.write("\nSOURCES=\n")
@ -1045,39 +1044,30 @@ CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))
file.write("%s: %s\n" % (objrule[0], source))
file.write("%s\n" % objrule[2])
# Print out the dependencies for crt0.s
file.write("\n# Dependencies for crt0.s\n")
for mbifile in mainboardinit_files:
file.write("crt0.s: $(TOP)/src/%s\n" % mbifile[0])
# Print out the rules that will make cause the files
# generated by NLBConfig.py to be remade if any dependencies change.
# It would seem sensible to write a rule with multiple targets, e.g.
# Makefile Makefile.settings crt0.S nsuperio.c: ...dependencies...
# but 'make' will run the rule for Makefile.settings (if out of date)
# and then run it again for Makefile, not realizing that Makefile
# was updated by the same command that updated Makefile.settings.
# I haven't found a way to get 'make' to do the right thing, and
# while it's not really harmful to run NLBConfig.py twice, it seems
# silly and wasteful. So the workaround is to let Makefile
# represent all of the files generated by NLBConfig.py.
# Note that crt0.base should be a dependency of crt0.S only,
# but for the above reason, we make it a dependency of Makefile.
file.write("\n# Remember the automatically generated files\n")
file.write("GENERATED:=\n")
for genfile in [ 'Makefile',
'Makefile.settings'
'crt0_includes.h'
'nsuperio.c'
'LinuxBIOSDoc.config' ]:
file.write("GENERATED += %s\n" % genfile)
file.write("\n# Remake Makefile (and the other files generated by\n")
file.write("# NLBConfig.py) if any config dependencies change.\n")
for cfile in config_file_list:
file.write("Makefile: %s\n" % topify(cfile))
file.write("$(GENERATED): %s\n" % topify(cfile))
for depfile in [ '$(TOP)/src/arch/$(ARCH)/config/crt0.base',
'%s' % top_config_file, # This a duplicate, remove?
for depfile in [ '%s' % top_config_file, # This a duplicate, remove?
'$(TOP)/util/config/NLBConfig.py',
'$(TOP)/src/arch/$(ARCH)/config/make.base' ]:
file.write("Makefile:\t%s\n" % depfile)
file.write("$(GENERATED): %s\n" % depfile)
file.write("Makefile:\n")
file.write("$(GENERATED):\n")
file.write("\tpython $(TOP)/util/config/NLBConfig.py %s $(TOP)\n"
% top_config_file)
@ -1085,7 +1075,7 @@ CPUFLAGS := $(foreach _var_,$(VARIABLES),$(call D_item,$(_var_)))
keys.sort()
file.write("\necho:\n")
for key in keys:
file.write("\t@echo %s='$(%s)'\n"% (key,key))
file.write("\t@echo %s='$(%s)'\n"% (key,key))
file.close();
@ -1126,8 +1116,10 @@ doxyscriptbase = os.path.join(treetop, "src/config/doxyscript.base")
doconfigfile(treetop, top_config_file)
# ...and write out the Makefile and other files.
writemakefile(target_dir)
# All submakfiles (Makefile.settings) must be written
# before the Makefile itself or there is a dependency issue
writemakefilesettings(target_dir)
writecrt0(target_dir)
writemakefile(target_dir)
writecrt0_includes(target_dir)
writesuperiofile(target_dir)
writedoxygenfile(target_dir)