mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
Move stage1 global variable management from asm to C. The stage0 asm
code now unconditionally pushes an empty pointer to the stack which is a placeholder for the pointer to global variable storage. That pointer and the global variable storage are initialized in global_vars_init(). Creating global variables is now a piece of cake. You don't even have to touch any asm code, just add them to struct global_vars. Build tested on all targets, boot tested on Qemu. NOTES: - The code is not yet MP safe, but that's due to v3 not being MP safe in general (and the comments contradict the code regarding MP features). - K8 code now works by accident. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Segher Boessenkool <segher@kernel.crashing.org> git-svn-id: svn://coreboot.org/repository/coreboot-v3@785 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
parent
67accc1f69
commit
1b5c399508
5 changed files with 29 additions and 22 deletions
|
@ -23,7 +23,9 @@
|
|||
#define CacheBase CONFIG_CARBASE
|
||||
#define MEM_TOPK 2048
|
||||
|
||||
/* leave some space for global variable to pass to RAM stage */
|
||||
/* Leave some space for a pointer to the global variables.
|
||||
* This should most likely be 4.
|
||||
*/
|
||||
#define GlobalVarSize 32
|
||||
|
||||
#ifdef CONFIG_CPU_AMD_K10
|
||||
|
|
|
@ -361,13 +361,10 @@ DCacheSetupGood:
|
|||
movw %ax, %ss
|
||||
|
||||
lout:
|
||||
#ifdef CONFIG_CONSOLE_BUFFER
|
||||
/* Store pointer to start of printk buffer, should really use
|
||||
* PRINTK_BUF_ADDR_CAR instead.
|
||||
*/
|
||||
movl $CONFIG_CARBASE, %eax
|
||||
pushl %eax /* printk buffer */
|
||||
#endif
|
||||
/* Store zero for the pointer to the global variables. */
|
||||
movl $0, %eax
|
||||
pushl %eax
|
||||
|
||||
/* Restore the BIST result. */
|
||||
movl %ebp, %eax
|
||||
|
||||
|
|
|
@ -435,13 +435,10 @@ clear_fixed_var_mtrr_out:
|
|||
movw %ax, %ss
|
||||
|
||||
lout:
|
||||
#ifdef CONFIG_CONSOLE_BUFFER
|
||||
/* Store pointer to start of printk buffer, should really use
|
||||
* PRINTK_BUF_ADDR_CAR instead.
|
||||
*/
|
||||
movl $CONFIG_CARBASE, %eax
|
||||
pushl %eax /* printk buffer */
|
||||
#endif
|
||||
/* Store zero for the pointer to the global variables. */
|
||||
movl $0, %eax
|
||||
pushl %eax
|
||||
|
||||
/* Restore the BIST result */
|
||||
movl %ebp, %eax
|
||||
/* We need to set ebp ? No need */
|
||||
|
|
|
@ -82,7 +82,13 @@ void *bottom_of_stack(void)
|
|||
|
||||
struct global_vars *global_vars(void)
|
||||
{
|
||||
return (struct global_vars *)(bottom_of_stack() - sizeof(struct global_vars));
|
||||
return *(struct global_vars **)(bottom_of_stack() - sizeof(struct global_vars *));
|
||||
}
|
||||
|
||||
void global_vars_init(struct global_vars *globvars)
|
||||
{
|
||||
memset(globvars, 0, sizeof(struct global_vars));
|
||||
*(struct global_vars **)(bottom_of_stack() - sizeof(struct global_vars *)) = globvars;
|
||||
}
|
||||
|
||||
void dump_mem_range(int msg_level, unsigned char *buf, int size)
|
||||
|
@ -119,9 +125,11 @@ int legacy(struct mem_file *archive, char *name, void *where, struct lb_memory *
|
|||
/*
|
||||
* This function is called from assembler code with its argument on the
|
||||
* stack. Force the compiler to generate always correct code for this case.
|
||||
* We have cache as ram running and can start executing code in C.
|
||||
*/
|
||||
void __attribute__((stdcall)) stage1_main(u32 bist)
|
||||
{
|
||||
struct global_vars globvars;
|
||||
int ret;
|
||||
struct mem_file archive;
|
||||
void *entry;
|
||||
|
@ -150,10 +158,13 @@ void __attribute__((stdcall)) stage1_main(u32 bist)
|
|||
stop_ap();
|
||||
}
|
||||
|
||||
// We have cache as ram running and can start executing code in C.
|
||||
/* Initialize global variables before we can think of using them.
|
||||
* NEVER run this on an AP!
|
||||
*/
|
||||
global_vars_init(&globvars);
|
||||
|
||||
#ifdef CONFIG_CONSOLE_BUFFER
|
||||
/* Initialize the printk buffer. */
|
||||
/* Initialize the printk buffer. NEVER run this on an AP! */
|
||||
printk_buffer_init();
|
||||
#endif
|
||||
|
||||
|
|
|
@ -60,10 +60,10 @@ struct printk_buffer {
|
|||
#endif
|
||||
|
||||
/*
|
||||
* If you change struct global_vars in any way, you have to fix all stage0 asm
|
||||
* code. The stage0 asm code modification is nontrivial (size of the struct,
|
||||
* alignment, initialization, order of struct members, initialization).
|
||||
* Depending on your compiler, real breakage may happen.
|
||||
* struct global_vars is managed entirely from C code. Keep in mind that there
|
||||
* is NO buffer at the end of the struct, so having zero-sized arrays at the
|
||||
* end or similar stuff for which the compiler can't determine the final size
|
||||
* will corrupt memory. If you don't try to be clever, everything will be fine.
|
||||
*/
|
||||
struct global_vars {
|
||||
#ifdef CONFIG_CONSOLE_BUFFER
|
||||
|
|
Loading…
Add table
Reference in a new issue