summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorTill Straumann <strauman@slac.stanford.edu>2006-09-04 23:29:29 +0000
committerTill Straumann <strauman@slac.stanford.edu>2006-09-04 23:29:29 +0000
commit662c1577ac1eab66febb35a900e274c33676f834 (patch)
tree1e38693bb0ebcc1c59953752b83199fd879a8e6c /c
parent * startup/linkcmds: added *(.text.*) *(.data.*) *(.bss.*) (diff)
downloadrtems-662c1577ac1eab66febb35a900e274c33676f834.tar.bz2
* 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.
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libbsp/i386/pc386/ChangeLog10
-rw-r--r--c/src/lib/libbsp/i386/pc386/start/start.S25
-rw-r--r--c/src/lib/libbsp/i386/pc386/startup/bspstart.c73
3 files changed, 88 insertions, 20 deletions
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,5 +1,15 @@
2006-09-04 Till Straumann <strauman@slac.stanford.edu>
+ * 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 <strauman@slac.stanford.edu>
+
* startup/linkcmds: added *(.text.*) *(.data.*) *(.bss.*)
2006-02-01 Joel Sherrill <joel@OARcorp.com>
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. */