diff --git a/stand/powerpc/kboot/Makefile b/stand/powerpc/kboot/Makefile --- a/stand/powerpc/kboot/Makefile +++ b/stand/powerpc/kboot/Makefile @@ -18,8 +18,8 @@ # Architecture-specific loader code SRCS= conf.c vers.c main.c ppc64_elf_freebsd.c -SRCS+= host_syscall.S hostcons.c hostdisk.c kerneltramp.S kbootfdt.c -SRCS+= ucmpdi2.c gfx_fb.c +SRCS+= host_init.S host_syscall.S hostcons.c hostdisk.c kerneltramp.S +SRCS+= kbootfdt.c ucmpdi2.c gfx_fb.c CFLAGS.gfx_fb.c += -I${SRCTOP}/contrib/pnglite CFLAGS.gfx_fb.c += -I${SRCTOP}/sys/teken diff --git a/stand/powerpc/kboot/host_init.S b/stand/powerpc/kboot/host_init.S new file mode 100644 --- /dev/null +++ b/stand/powerpc/kboot/host_init.S @@ -0,0 +1,51 @@ +/* + * + * $FreeBSD$ + */ + +#include + +/* + * Linux-style entry point: + * r1: Initial sp + * r2: Intialized by ENTRY macro + * r3: Need to load argc + * r4: Need to load argv + * r5: Need to load envp + * r6: Need to load auxv + * r7: atexit pointer or 0 + */ +ENTRY(_start) + /* Use r6 to traverse the stack. */ + mr %r6, %r1 + + /* Set up initial stack frame. */ + addi %r1, %r1, -16 + /* Ensure we're aligned. */ + clrrwi %r1, %r1, 4 + + li %r0, 0 + /* Ensure the backchain is disconnected. */ + stw %r0, 0(%r1) + + lwz %r3, 0(%r6) /* argc */ + addi %r6, %r6, 4 /* next dword */ + mr %r4, %r6 /* argv */ + mulli %r5, %r3, 4 /* compute argv size */ + add %r6, %r6, %r5 /* skip over argv */ + addi %r6, %r6, 4 /* next dword */ + mr %r5, %r6 /* envp */ + /* + * Don't bother with auxv for now. If we end up needing it, it's a + * word past the first null pointer in envp. + */ + li %r6, 0 + + /* This appears to be set to &_start on PPC32. We don't care. */ + li %r7, 0 + + bl main + /* Exit via syscall. */ + b host_exit + +END(_start) diff --git a/stand/powerpc/kboot/host_syscall.S b/stand/powerpc/kboot/host_syscall.S --- a/stand/powerpc/kboot/host_syscall.S +++ b/stand/powerpc/kboot/host_syscall.S @@ -5,6 +5,12 @@ #include +ENTRY(host_exit) + li %r0, 1 # SYS_exit + sc + trap +END(host_exit) + ENTRY(host_read) li %r0, 3 # SYS_read sc diff --git a/stand/powerpc/kboot/main.c b/stand/powerpc/kboot/main.c --- a/stand/powerpc/kboot/main.c +++ b/stand/powerpc/kboot/main.c @@ -250,11 +250,12 @@ } int -main(int argc, const char **argv) +main(int argc, const char **argv, char **envp) { void *heapbase; const size_t heapsize = 15*1024*1024; const char *bootdev; + char **env; /* * Set the heap to one page after the end of the loader. @@ -262,6 +263,12 @@ heapbase = host_getmem(heapsize); setheap(heapbase, heapbase + heapsize); + /* + * Copy out environment. + */ + for (env = envp; *env != NULL; env++) + putenv(*env); + /* * Set up console. */ @@ -480,23 +487,6 @@ *ptr = &loaded_segments[0]; } -void -_start(int argc, const char **argv, char **env) -{ -// This makes error "variable 'sp' is uninitialized" be just a warning on clang. -// Initializing 'sp' is not desired here as it would overwrite "r1" original value -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic warning "-Wuninitialized" -#endif - register volatile void **sp asm("r1"); - main((int)sp[0], (const char **)&sp[1]); -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - -} - /* * Since proper fdt command handling function is defined in fdt_loader_cmd.c, * and declaring it as extern is in contradiction with COMMAND_SET() macro