From 662c1577ac1eab66febb35a900e274c33676f834 Mon Sep 17 00:00:00 2001 From: Till Straumann Date: Mon, 4 Sep 2006 23:29:29 +0000 Subject: * startup/bspstart.c, start/start.S: Since the crude memory autodetection code can easily fail (boards with 'reserved' regions - I experienced a hard lockup on a dell precision 490 when writing past the bios-reported memory size) I added code that a) tries to save and use multiboot info, if present b) allows applications to override/set memory size via a weak alias. --- c/src/lib/libbsp/i386/pc386/ChangeLog | 10 ++++ c/src/lib/libbsp/i386/pc386/start/start.S | 25 +++++++++ c/src/lib/libbsp/i386/pc386/startup/bspstart.c | 73 +++++++++++++++++++------- 3 files changed, 88 insertions(+), 20 deletions(-) (limited to 'c/src/lib/libbsp') diff --git a/c/src/lib/libbsp/i386/pc386/ChangeLog b/c/src/lib/libbsp/i386/pc386/ChangeLog index 1f76aea632..186efd0ecf 100644 --- a/c/src/lib/libbsp/i386/pc386/ChangeLog +++ b/c/src/lib/libbsp/i386/pc386/ChangeLog @@ -1,3 +1,13 @@ +2006-09-04 Till Straumann + + * startup/bspstart.c, start/start.S: Since the crude + memory autodetection code can easily fail (boards with + 'reserved' regions - I experienced a hard lockup on a + dell precision 490 when writing past the bios-reported + memory size) I added code that a) tries to save + and use multiboot info, if present b) allows applications + to override/set memory size via a weak alias. + 2006-09-04 Till Straumann * startup/linkcmds: added *(.text.*) *(.data.*) *(.bss.*) diff --git a/c/src/lib/libbsp/i386/pc386/start/start.S b/c/src/lib/libbsp/i386/pc386/start/start.S index c09903e807..361f973c2e 100644 --- a/c/src/lib/libbsp/i386/pc386/start/start.S +++ b/c/src/lib/libbsp/i386/pc386/start/start.S @@ -87,6 +87,22 @@ speakl: jmp speakl # and SPIN!!! nop cli # DISABLE INTERRUPTS!!! cld + + /* Save multiboot info */ + cmp $0x2badb002,eax + jne 1f + /* We have multiboot info; let's hope DS and ES are OK... */ + movl ebx, SYM(_boot_multiboot_info_p) + /* Check for memory size info and save */ + movl ebx, esi + movl $SYM(_boot_multiboot_info), edi + movsd + /* only save flag 1 since that's the only data we save */ + and $1,-4(edi) + je 1f + movl $2,ecx + rep movsd +1: #ifdef DEBUG_EARLY_START /* * Must get video attribute to have a working printk. @@ -178,6 +194,15 @@ SYM (zero_bss): END_CODE BEGIN_DATA + PUBLIC(_boot_multiboot_info_p) +SYM(_boot_multiboot_info_p): + .long 0 + + PUBLIC(_boot_multiboot_info) +SYM(_boot_multiboot_info): + .long 0 /* flags */ + .long 0 /* mem_lower */ + .long 0 /* mem_upper */ PUBLIC(_stack_size) SYM(_stack_size): diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c index d0fe5cd723..c3e2b35640 100644 --- a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c +++ b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c @@ -40,12 +40,28 @@ | Global Variables +--------------------------------------------------------------------------*/ extern uint32_t _end; /* End of BSS. Defined in 'linkcmds'. */ + +/* rudimentary multiboot info */ +struct multiboot_info { + uint32_t flags; /* start.S only raises flags for items actually saved; this allows us to check for the size of the data structure */ + uint32_t mem_lower; /* avail kB in lower memory */ + uint32_t mem_upper; /* avail kB in lower memory */ + /* ... (unimplemented) */ +}; + +extern struct multiboot_info _boot_multiboot_info; /* * Size of heap if it is 0 it will be dynamically defined by memory size, * otherwise the value should be changed by binary patch */ uint32_t _heap_size = 0; +/* Alternative way to hardcode the board's memory size [rather than heap size]. + * Can easily be overridden by application. + */ +extern uint32_t bsp_mem_size __attribute__ ((weak, alias("bsp_mem_size_default"))); +uint32_t bsp_mem_size_default = 0; + /* Size of stack used during initialization. Defined in 'start.s'. */ extern uint32_t _stack_size; @@ -92,26 +108,43 @@ void bsp_pretasking_hook(void) if ( lowest < 2 ) lowest = 2; + /* The memory detection algorithm is very crude; try + * to use multiboot info, if possible (set from start.S) + */ + if ( bsp_mem_size == 0 + && (_boot_multiboot_info.flags & 1) + && _boot_multiboot_info.mem_upper ) { + bsp_mem_size = _boot_multiboot_info.mem_upper * 1024; + } + if (_heap_size == 0) { - /* - * We have to dynamically size memory. Memory size can be anything - * between no less than 2M and 2048M. - * let us first write - */ - for (i=2048; i>=lowest; i--) { - topAddr = i*1024*1024 - 4; - *(volatile uint32_t*)topAddr = topAddr; - } - - for(i=lowest; i<=2048; i++) { - topAddr = i*1024*1024 - 4; - val = *(uint32_t*)topAddr; - if (val != topAddr) { - break; - } - } - - topAddr = (i-1)*1024*1024 - 4; + + if ( bsp_mem_size == 0 ) { + /* + * We have to dynamically size memory. Memory size can be anything + * between no less than 2M and 2048M. + * let us first write + */ + for (i=2048; i>=lowest; i--) { + topAddr = i*1024*1024 - 4; + *(volatile uint32_t*)topAddr = topAddr; + } + + for(i=lowest; i<=2048; i++) { + topAddr = i*1024*1024 - 4; + val = *(uint32_t*)topAddr; + if (val != topAddr) { + break; + } + } + + topAddr = (i-1)*1024*1024 - 4; + + } else { + + topAddr = bsp_mem_size; + + } _heap_size = topAddr - rtemsFreeMemStart; } @@ -143,8 +176,8 @@ void bsp_start_default( void ) */ Calibrate_loop_1ms(); + /* set the value of start of free memory. */ rtemsFreeMemStart = (uint32_t)&_end + _stack_size; - /* set the value of start of free memory. */ /* If we don't have command line arguments set default program name. */ -- cgit v1.2.3