mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
sparc64: fix registers dealing with client (Igor Kovalenko)
Signed-off-by: igor.v.kovalenko@gmail.com git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@508 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
committed by
Blue Swirl
parent
853aec9291
commit
5f5b8d6f8c
@@ -125,19 +125,10 @@ int aout_load(struct sys_info *info, const char *filename)
|
|||||||
debug("entry point is %#lx\n", start);
|
debug("entry point is %#lx\n", start);
|
||||||
printf("Jumping to entry point...\n");
|
printf("Jumping to entry point...\n");
|
||||||
|
|
||||||
#if 1
|
|
||||||
{
|
{
|
||||||
int (*entry)(unsigned long p1, unsigned long p2, unsigned long p3,
|
extern int sparc64_of_client_interface( int *params );
|
||||||
unsigned long p4, unsigned long p5);
|
image_retval = start_client_image(addr_fixup(start), (uint64_t)&sparc64_of_client_interface);
|
||||||
extern int of_client_interface( int *params );
|
|
||||||
|
|
||||||
entry = (void *) addr_fixup(start);
|
|
||||||
|
|
||||||
__asm__ __volatile__("clr %i3\n");
|
|
||||||
|
|
||||||
image_retval = entry(0, 0, 0, 0, (unsigned long)&of_client_interface);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
printf("Image returned with return value %#x\n", image_retval);
|
printf("Image returned with return value %#x\n", image_retval);
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ void boot(void)
|
|||||||
if (kernel_size) {
|
if (kernel_size) {
|
||||||
void (*entry)(unsigned long p1, unsigned long p2, unsigned long p3,
|
void (*entry)(unsigned long p1, unsigned long p2, unsigned long p3,
|
||||||
unsigned long p4, unsigned long p5);
|
unsigned long p4, unsigned long p5);
|
||||||
extern int of_client_interface( int *params );
|
extern int sparc64_of_client_interface( int *params );
|
||||||
|
|
||||||
printk("[sparc64] Kernel already loaded\n");
|
printk("[sparc64] Kernel already loaded\n");
|
||||||
entry = (void *) (unsigned long)kernel_image;
|
entry = (void *) (unsigned long)kernel_image;
|
||||||
entry(0, 0, 0, 0, (unsigned long)&of_client_interface);
|
entry(0, 0, 0, 0, (unsigned long)&sparc64_of_client_interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!path) {
|
if(!path) {
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ int linux_load(struct sys_info *info, const char *file, const char *cmdline);
|
|||||||
int fcode_load(const char *filename);
|
int fcode_load(const char *filename);
|
||||||
|
|
||||||
// context.c
|
// context.c
|
||||||
extern struct context *__context;
|
extern struct context * volatile __context;
|
||||||
uint64_t start_elf(uint64_t entry_point, uint64_t param);
|
uint64_t start_elf(uint64_t entry_point, uint64_t param);
|
||||||
|
uint64_t start_client_image(uint64_t entry_point, uint64_t cif_handler);
|
||||||
|
|
||||||
// boot.c
|
// boot.c
|
||||||
extern struct sys_info sys_info;
|
extern struct sys_info sys_info;
|
||||||
|
|||||||
@@ -29,6 +29,10 @@
|
|||||||
<rule><![CDATA[ $(SRCDIR)/arch/sparc64/vectors.S
|
<rule><![CDATA[ $(SRCDIR)/arch/sparc64/vectors.S
|
||||||
$(CC) $$EXTRACFLAGS $(AS_FLAGS) $(CFLAGS) $(INCLUDES) -c -o $@ $^]]></rule>
|
$(CC) $$EXTRACFLAGS $(AS_FLAGS) $(CFLAGS) $(INCLUDES) -c -o $@ $^]]></rule>
|
||||||
</executable>
|
</executable>
|
||||||
|
<executable name="target/arch/sparc64/call-client.o" target="target">
|
||||||
|
<rule><![CDATA[ $(SRCDIR)/arch/sparc64/call-client.S
|
||||||
|
$(CC) $$EXTRACFLAGS $(AS_FLAGS) $(CFLAGS) $(INCLUDES) -c -o $@ $^]]></rule>
|
||||||
|
</executable>
|
||||||
|
|
||||||
<executable name="openbios-plain.elf" target="target" condition="IMAGE_ELF">
|
<executable name="openbios-plain.elf" target="target" condition="IMAGE_ELF">
|
||||||
<rule>
|
<rule>
|
||||||
@@ -39,6 +43,7 @@
|
|||||||
<object source="plainboot.c"/>
|
<object source="plainboot.c"/>
|
||||||
<external-object source="target/arch/sparc64/vectors.o"/>
|
<external-object source="target/arch/sparc64/vectors.o"/>
|
||||||
<external-object source="target/arch/sparc64/entry.o"/>
|
<external-object source="target/arch/sparc64/entry.o"/>
|
||||||
|
<external-object source="target/arch/sparc64/call-client.o"/>
|
||||||
<external-object source="libsparc64.a"/>
|
<external-object source="libsparc64.a"/>
|
||||||
<external-object source="libbootstrap.a"/>
|
<external-object source="libbootstrap.a"/>
|
||||||
<external-object source="libdrivers.a"/>
|
<external-object source="libdrivers.a"/>
|
||||||
@@ -77,6 +82,7 @@
|
|||||||
<external-object source="target/arch/sparc64/vectors.o"/>
|
<external-object source="target/arch/sparc64/vectors.o"/>
|
||||||
<external-object source="target/arch/sparc64/entry.o"/>
|
<external-object source="target/arch/sparc64/entry.o"/>
|
||||||
<external-object source="target/arch/sparc64/builtin.o"/>
|
<external-object source="target/arch/sparc64/builtin.o"/>
|
||||||
|
<external-object source="target/arch/sparc64/call-client.o"/>
|
||||||
<external-object source="libsparc64.a"/>
|
<external-object source="libsparc64.a"/>
|
||||||
<external-object source="libbootstrap.a"/>
|
<external-object source="libbootstrap.a"/>
|
||||||
<external-object source="libdrivers.a"/>
|
<external-object source="libdrivers.a"/>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include "boot.h"
|
#include "boot.h"
|
||||||
|
|
||||||
#define MAIN_STACK_SIZE 16384
|
#define MAIN_STACK_SIZE 16384
|
||||||
#define IMAGE_STACK_SIZE 4096
|
#define IMAGE_STACK_SIZE 4096*2
|
||||||
|
|
||||||
#define debug printk
|
#define debug printk
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ void __exit_context(void); /* assembly routine */
|
|||||||
* to start us up.
|
* to start us up.
|
||||||
*/
|
*/
|
||||||
static struct context main_ctx = {
|
static struct context main_ctx = {
|
||||||
.regs[REG_SP] = (uint64_t) &_estack - 2047 - 96,
|
.regs[REG_SP] = (uint64_t) &_estack - STACK_BIAS - 96,
|
||||||
.pc = (uint64_t) start_main,
|
.pc = (uint64_t) start_main,
|
||||||
.npc = (uint64_t) start_main + 4,
|
.npc = (uint64_t) start_main + 4,
|
||||||
.return_addr = (uint64_t) __exit_context,
|
.return_addr = (uint64_t) __exit_context,
|
||||||
@@ -31,7 +31,7 @@ static struct context main_ctx = {
|
|||||||
|
|
||||||
/* This is used by assembly routine to load/store the context which
|
/* This is used by assembly routine to load/store the context which
|
||||||
* it is to switch/switched. */
|
* it is to switch/switched. */
|
||||||
struct context *__context = &main_ctx;
|
struct context * volatile __context = &main_ctx;
|
||||||
|
|
||||||
/* Stack for loaded ELF image */
|
/* Stack for loaded ELF image */
|
||||||
static uint8_t image_stack[IMAGE_STACK_SIZE];
|
static uint8_t image_stack[IMAGE_STACK_SIZE];
|
||||||
@@ -62,19 +62,25 @@ static void start_main(void)
|
|||||||
__context = boot_ctx;
|
__context = boot_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t ALIGN_SIZE(uint64_t x, uint64_t a)
|
||||||
|
{
|
||||||
|
return (x + a - 1) & ~(a-1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup a new context using the given stack.
|
/* Setup a new context using the given stack.
|
||||||
*/
|
*/
|
||||||
struct context *
|
struct context *
|
||||||
init_context(uint8_t *stack, uint64_t stack_size, int num_params)
|
init_context(uint8_t *stack, uint64_t stack_size, int num_params)
|
||||||
{
|
{
|
||||||
struct context *ctx;
|
struct context *ctx;
|
||||||
|
uint8_t *stack_top = stack + stack_size;
|
||||||
|
|
||||||
ctx = (struct context *)
|
ctx = (struct context *)
|
||||||
(stack + stack_size - (sizeof(*ctx) + num_params*sizeof(uint32_t)));
|
(stack_top - ALIGN_SIZE(sizeof(*ctx) + num_params*sizeof(uint64_t), sizeof(uint64_t)));
|
||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
|
|
||||||
/* Fill in reasonable default for flat memory model */
|
/* Fill in reasonable default for flat memory model */
|
||||||
ctx->regs[REG_SP] = virt_to_phys(SP_LOC(ctx));
|
ctx->regs[REG_SP] = virt_to_phys(stack_top - STACK_BIAS - 192);
|
||||||
ctx->return_addr = virt_to_phys(__exit_context);
|
ctx->return_addr = virt_to_phys(__exit_context);
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
@@ -85,10 +91,11 @@ struct context *switch_to(struct context *ctx)
|
|||||||
{
|
{
|
||||||
struct context *save, *ret;
|
struct context *save, *ret;
|
||||||
|
|
||||||
debug("switching to new context:\n");
|
debug("switching to new context: entry point %#llx stack 0x%016llx\n", ctx->pc, ctx->regs[REG_SP]);
|
||||||
save = __context;
|
save = __context;
|
||||||
__context = ctx;
|
__context = ctx;
|
||||||
//asm ("pushl %cs; call __switch_context");
|
//asm ("pushl %cs; call __switch_context");
|
||||||
|
asm ("call __switch_context_nosave; nop");
|
||||||
ret = __context;
|
ret = __context;
|
||||||
__context = save;
|
__context = save;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -109,3 +116,18 @@ uint64_t start_elf(uint64_t entry_point, uint64_t param)
|
|||||||
//return ctx->eax;
|
//return ctx->eax;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Start client image */
|
||||||
|
uint64_t start_client_image(uint64_t entry_point, uint64_t cif_handler)
|
||||||
|
{
|
||||||
|
struct context *ctx;
|
||||||
|
|
||||||
|
ctx = init_context(image_stack, sizeof image_stack, 0);
|
||||||
|
ctx->pc = entry_point;
|
||||||
|
ctx->npc = entry_point+4;
|
||||||
|
ctx->regs[REG_O0+4] = cif_handler;
|
||||||
|
|
||||||
|
ctx = switch_to(ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef SPARC64_CONTEXT_H
|
#ifndef SPARC64_CONTEXT_H
|
||||||
#define SPARC64_CONTEXT_H
|
#define SPARC64_CONTEXT_H
|
||||||
|
|
||||||
|
#define STACK_BIAS 2047
|
||||||
|
|
||||||
struct context {
|
struct context {
|
||||||
/* General registers */
|
/* General registers */
|
||||||
uint64_t regs[32];
|
uint64_t regs[32];
|
||||||
|
|||||||
@@ -24,7 +24,12 @@
|
|||||||
|
|
||||||
/* XXX: totally bogus for sparc, need to save and restore all windows */
|
/* XXX: totally bogus for sparc, need to save and restore all windows */
|
||||||
__switch_context:
|
__switch_context:
|
||||||
|
|
||||||
|
/* make sure caller's windows are on caller's stack */
|
||||||
|
flushw;
|
||||||
|
|
||||||
/* Save everything in current stack */
|
/* Save everything in current stack */
|
||||||
|
|
||||||
setx __context, %g2, %g1
|
setx __context, %g2, %g1
|
||||||
stx %g3, [%g1 + 24]
|
stx %g3, [%g1 + 24]
|
||||||
stx %g4, [%g1 + 32]
|
stx %g4, [%g1 + 32]
|
||||||
@@ -61,7 +66,8 @@ __switch_context:
|
|||||||
|
|
||||||
__switch_context_nosave:
|
__switch_context_nosave:
|
||||||
/* Interrupts are not allowed... */
|
/* Interrupts are not allowed... */
|
||||||
|
/* make sure caller's windows are on caller's stack */
|
||||||
|
flushw
|
||||||
/* Load all registers
|
/* Load all registers
|
||||||
*/
|
*/
|
||||||
setx __context, %g2, %g1
|
setx __context, %g2, %g1
|
||||||
|
|||||||
Reference in New Issue
Block a user