forked from Imagelibrary/rtems
* 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.
This commit is contained in:
@@ -1,3 +1,13 @@
|
|||||||
|
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>
|
2006-09-04 Till Straumann <strauman@slac.stanford.edu>
|
||||||
|
|
||||||
* startup/linkcmds: added *(.text.*) *(.data.*) *(.bss.*)
|
* startup/linkcmds: added *(.text.*) *(.data.*) *(.bss.*)
|
||||||
|
|||||||
@@ -87,6 +87,22 @@ speakl: jmp speakl # and SPIN!!!
|
|||||||
nop
|
nop
|
||||||
cli # DISABLE INTERRUPTS!!!
|
cli # DISABLE INTERRUPTS!!!
|
||||||
cld
|
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
|
#ifdef DEBUG_EARLY_START
|
||||||
/*
|
/*
|
||||||
* Must get video attribute to have a working printk.
|
* Must get video attribute to have a working printk.
|
||||||
@@ -178,6 +194,15 @@ SYM (zero_bss):
|
|||||||
END_CODE
|
END_CODE
|
||||||
|
|
||||||
BEGIN_DATA
|
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)
|
PUBLIC(_stack_size)
|
||||||
SYM(_stack_size):
|
SYM(_stack_size):
|
||||||
|
|||||||
@@ -40,12 +40,28 @@
|
|||||||
| Global Variables
|
| Global Variables
|
||||||
+--------------------------------------------------------------------------*/
|
+--------------------------------------------------------------------------*/
|
||||||
extern uint32_t _end; /* End of BSS. Defined in 'linkcmds'. */
|
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,
|
* Size of heap if it is 0 it will be dynamically defined by memory size,
|
||||||
* otherwise the value should be changed by binary patch
|
* otherwise the value should be changed by binary patch
|
||||||
*/
|
*/
|
||||||
uint32_t _heap_size = 0;
|
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'. */
|
/* Size of stack used during initialization. Defined in 'start.s'. */
|
||||||
extern uint32_t _stack_size;
|
extern uint32_t _stack_size;
|
||||||
|
|
||||||
@@ -92,26 +108,43 @@ void bsp_pretasking_hook(void)
|
|||||||
if ( lowest < 2 )
|
if ( lowest < 2 )
|
||||||
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) {
|
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++) {
|
if ( bsp_mem_size == 0 ) {
|
||||||
topAddr = i*1024*1024 - 4;
|
/*
|
||||||
val = *(uint32_t*)topAddr;
|
* We have to dynamically size memory. Memory size can be anything
|
||||||
if (val != topAddr) {
|
* between no less than 2M and 2048M.
|
||||||
break;
|
* let us first write
|
||||||
}
|
*/
|
||||||
}
|
for (i=2048; i>=lowest; i--) {
|
||||||
|
topAddr = i*1024*1024 - 4;
|
||||||
|
*(volatile uint32_t*)topAddr = topAddr;
|
||||||
|
}
|
||||||
|
|
||||||
topAddr = (i-1)*1024*1024 - 4;
|
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;
|
_heap_size = topAddr - rtemsFreeMemStart;
|
||||||
}
|
}
|
||||||
@@ -143,8 +176,8 @@ void bsp_start_default( void )
|
|||||||
*/
|
*/
|
||||||
Calibrate_loop_1ms();
|
Calibrate_loop_1ms();
|
||||||
|
|
||||||
|
/* set the value of start of free memory. */
|
||||||
rtemsFreeMemStart = (uint32_t)&_end + _stack_size;
|
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. */
|
/* If we don't have command line arguments set default program name. */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user