Introduce a generic global variable storage mechanism and switch the

printk buffer management to it.

Build tested and boot tested and result tested on Qemu.

Adding a new global variable is not as easy as it looks, but the
comments in the code should be good enough to tell you how.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Ronald G. Minnich <rminnich@gmail.com>


git-svn-id: svn://coreboot.org/repository/coreboot-v3@760 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
Carl-Daniel Hailfinger 2008-08-14 09:25:58 +00:00
commit 07f3009f43
4 changed files with 31 additions and 13 deletions

View file

@ -70,10 +70,19 @@ void init_archive(struct mem_file *archive)
}
/*
* The name is slightly misleading because this is the initial stack pointer,
* not the address of the first element on the stack.
*/
void *bottom_of_stack(void)
{
/* -4-4 because CONFIG_CARBASE + CONFIG_CARSIZE - 4 is initial %esp */
return (void *)(CONFIG_CARBASE + CONFIG_CARSIZE - 4 - 4);
/* -4 because CONFIG_CARBASE + CONFIG_CARSIZE - 4 is initial %esp */
return (void *)(CONFIG_CARBASE + CONFIG_CARSIZE - 4);
}
struct global_vars *global_vars(void)
{
return (struct global_vars *)(bottom_of_stack() - sizeof(struct global_vars));
}
void dump_mem_range(int msg_level, unsigned char *buf, int size)

View file

@ -202,6 +202,7 @@ static inline __attribute__((always_inline)) void hlt(void)
}
SHARED(bottom_of_stack, void *, void);
SHARED(global_vars, struct global_vars *, void);
#ifdef CONFIG_CONSOLE_BUFFER
#define PRINTK_BUF_SIZE_CAR (CONFIG_CARSIZE / 2)

View file

@ -59,6 +59,18 @@ 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 {
#ifdef CONFIG_CONSOLE_BUFFER
struct printk_buffer *printk_buffer;
#endif
};
SHARED_WITH_ATTRIBUTES(printk, int, __attribute__((format (printf, 2, 3))),
int msg_level, const char *fmt, ...);
SHARED(banner, void, int msg_level, const char *msg);

View file

@ -35,13 +35,16 @@ static unsigned int console_loglevel(void)
}
#ifdef CONFIG_CONSOLE_BUFFER
struct printk_buffer *printk_buffer_addr(void)
{
return global_vars()->printk_buffer;
}
void printk_buffer_move(void *newaddr, int newsize)
{
struct printk_buffer **p;
struct printk_buffer *oldbuf, *newbuf;
int copylen;
p = bottom_of_stack();
oldbuf = *p;
oldbuf = printk_buffer_addr();
newbuf = newaddr;
newbuf->len = newsize;
newbuf->readoffset = 0;
@ -68,17 +71,10 @@ void printk_buffer_move(void *newaddr, int newsize)
&oldbuf->buffer[0], copylen);
newbuf->writeoffset += copylen;
}
*p = newbuf;
global_vars()->printk_buffer = newbuf;
return;
}
struct printk_buffer *printk_buffer_addr(void)
{
struct printk_buffer **p;
p = bottom_of_stack();
return *p;
}
void printk_buffer_init(void)
{
struct printk_buffer *buf = printk_buffer_addr();