Date: Sun, 25 Apr 2010 19:36:05 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r207202 - projects/ppc64/sys/boot/powerpc/ps3 Message-ID: <201004251936.o3PJa5pk050674@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: nwhitehorn Date: Sun Apr 25 19:36:05 2010 New Revision: 207202 URL: http://svn.freebsd.org/changeset/base/207202 Log: Fix booting from flash, and fix netbooting completely. The PS3 loader can now load and execute a kernel from NFS. Next, it is time to make that kernel do something. Modified: projects/ppc64/sys/boot/powerpc/ps3/Makefile projects/ppc64/sys/boot/powerpc/ps3/devicename.c projects/ppc64/sys/boot/powerpc/ps3/ldscript.powerpc projects/ppc64/sys/boot/powerpc/ps3/main.c projects/ppc64/sys/boot/powerpc/ps3/ppc64_elf_freebsd.c projects/ppc64/sys/boot/powerpc/ps3/ps3cons.c projects/ppc64/sys/boot/powerpc/ps3/ps3net.c projects/ppc64/sys/boot/powerpc/ps3/start.S Modified: projects/ppc64/sys/boot/powerpc/ps3/Makefile ============================================================================== --- projects/ppc64/sys/boot/powerpc/ps3/Makefile Sun Apr 25 19:22:06 2010 (r207201) +++ projects/ppc64/sys/boot/powerpc/ps3/Makefile Sun Apr 25 19:36:05 2010 (r207202) @@ -61,7 +61,7 @@ LIBFICL= ${.OBJDIR}/../../ficl/libficl.a # Avoid the open-close-dance for every file access as some firmwares perform # an auto-negotiation on every open of the network interface and thus causes # netbooting to take horribly long. -CFLAGS+= -DNETIF_OPEN_CLOSE_ONCE +CFLAGS+= -DNETIF_OPEN_CLOSE_ONCE -mcpu=powerpc64 # Always add MI sources .PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern @@ -71,7 +71,7 @@ CFLAGS+= -I. CLEANFILES+= vers.c loader.help -CFLAGS+= -Wall -ffreestanding -msoft-float -DAIM -DNETIF_DEBUG +CFLAGS+= -Wall -ffreestanding -msoft-float -DAIM # load address. set in linker script RELOC?= 0x0 CFLAGS+= -DRELOC=${RELOC} Modified: projects/ppc64/sys/boot/powerpc/ps3/devicename.c ============================================================================== --- projects/ppc64/sys/boot/powerpc/ps3/devicename.c Sun Apr 25 19:22:06 2010 (r207201) +++ projects/ppc64/sys/boot/powerpc/ps3/devicename.c Sun Apr 25 19:36:05 2010 (r207202) @@ -46,7 +46,7 @@ int ps3_getdev(void **vdev, const char *devspec, const char **path) { struct devdesc **dev = (struct devdesc **)vdev; - int rv; + int rv = 0; /* * If it looks like this is just a path and no @@ -54,10 +54,10 @@ ps3_getdev(void **vdev, const char *devs */ if ((devspec == NULL) || (devspec[0] == '/') || (strchr(devspec, ':') == NULL)) { + rv = ps3_parsedev(dev, getenv("currdev"), NULL); - if (((rv = ps3_parsedev(dev, getenv("currdev"), NULL)) == 0) - && (path != NULL)) - *path = devspec; + if (rv == 0 && path != NULL) + *path = devspec; return(rv); } @@ -157,24 +157,13 @@ ps3_parsedev(struct devdesc **dev, const #endif case DEVT_NET: - unit = 0; + /* + * PS3 only has one network interface (well, two, but + * netbooting over wireless is not something I'm going + * to worry about. + */ - if (*np && (*np != ':')) { - /* get unit number if present */ - unit = strtol(np, &cp, 0); - if (cp == np) { - err = EUNIT; - goto fail; - } - } - if (*cp && (*cp != ':')) { - err = EINVAL; - goto fail; - } - idev->d_unit = unit; - - if (path != NULL) - *path = (*cp == 0) ? cp : cp + 1; + idev->d_unit = 0; break; default: Modified: projects/ppc64/sys/boot/powerpc/ps3/ldscript.powerpc ============================================================================== --- projects/ppc64/sys/boot/powerpc/ps3/ldscript.powerpc Sun Apr 25 19:22:06 2010 (r207201) +++ projects/ppc64/sys/boot/powerpc/ps3/ldscript.powerpc Sun Apr 25 19:36:05 2010 (r207202) @@ -41,9 +41,7 @@ SECTIONS .rela.fini : { *(.rela.fini) } .rela.bss : { *(.rela.bss) } .rela.plt : { *(.rela.plt) } - .rela.sdata : { *(.rela.sdata) } .rela.sbss : { *(.rela.sbss) } - .rela.sdata2 : { *(.rela.sdata2) } .rela.sbss2 : { *(.rela.sbss2) } .text : { @@ -58,7 +56,6 @@ SECTIONS .fini : { *(.fini) } =0 .rodata : { *(.rodata) *(.gnu.linkonce.r*) } .rodata1 : { *(.rodata1) } - .sdata2 : { *(.sdata2) } .sbss2 : { *(.sbss2) } /* Adjust the address for the data segment to the next page up. */ . = ((. + 0x1000) & ~(0x1000 - 1)); @@ -90,10 +87,6 @@ SECTIONS .got : { *(.got) } .got.plt : { *(.got.plt) } PROVIDE (_GOT_END_ = .); - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : { *(.sdata) } _edata = .; PROVIDE (edata = .); .sbss : @@ -112,36 +105,8 @@ SECTIONS *(.bss) *(COMMON) } + . = ALIGN(4096); _end = . ; PROVIDE (end = .); - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* These must appear regardless of . */ } Modified: projects/ppc64/sys/boot/powerpc/ps3/main.c ============================================================================== --- projects/ppc64/sys/boot/powerpc/ps3/main.c Sun Apr 25 19:22:06 2010 (r207201) +++ projects/ppc64/sys/boot/powerpc/ps3/main.c Sun Apr 25 19:36:05 2010 (r207202) @@ -45,6 +45,11 @@ extern char bootprog_date[]; extern char bootprog_maker[]; int ps3_getdev(void **vdev, const char *devspec, const char **path); +ssize_t ps3_copyin(const void *src, vm_offset_t dest, const size_t len); +ssize_t ps3_copyout(vm_offset_t src, void *dest, const size_t len); +ssize_t ps3_readin(const int fd, vm_offset_t dest, const size_t len); +int ps3_autoload(void); +int ps3_setcurrdev(struct env_var *ev, int flags, const void *value); static uint64_t basetb; @@ -67,8 +72,8 @@ main(void) /* * Set the heap to one page after the end of the loader. */ - heapbase = (void *)((((u_long)&_end) + PAGE_SIZE) & ~PAGE_MASK); - setheap(heapbase, heapbase + 0x80000); + heapbase = (void *)(maxmem - 0x80000); + setheap(heapbase, maxmem); /* * March through the device switch probing for things. @@ -83,25 +88,41 @@ main(void) basetb = mftb(); archsw.arch_getdev = ps3_getdev; + archsw.arch_copyin = ps3_copyin; + archsw.arch_copyout = ps3_copyout; + archsw.arch_readin = ps3_readin; + archsw.arch_autoload = ps3_autoload; printf("\n"); printf("%s, Revision %s\n", bootprog_name, bootprog_rev); printf("(%s, %s)\n", bootprog_maker, bootprog_date); printf("Memory: %lldKB\n", maxmem / 1024); - env_setenv("currdev", EV_VOLATILE, "net", NULL, NULL); - env_setenv("loaddev", EV_VOLATILE, "net", NULL, NULL); + env_setenv("currdev", EV_VOLATILE, "net", ps3_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, "net", env_noset, env_nounset); + setenv("LINES", "24", 1); interact(); /* doesn't return */ return (0); } +void +ppc_exception(int code, vm_offset_t where, register_t msr) +{ + mtmsr(PSL_IR | PSL_DR | PSL_RI); + printf("Exception %x at %#lx!\n", code, where); + printf("Rebooting in 5 seconds...\n"); + delay(10000000); + lv1_panic(1); +} + const u_int ns_per_tick = 12; void exit(int code) { + lv1_panic(code); } void @@ -124,6 +145,66 @@ getsecs() time_t time(time_t *tloc) { + time_t rv; + + rv = getsecs(); + if (tloc != NULL) + *tloc = rv; + + return (rv); +} + +ssize_t +ps3_copyin(const void *src, vm_offset_t dest, const size_t len) +{ + bcopy(src, (void *)dest, len); + return (len); +} + +ssize_t +ps3_copyout(vm_offset_t src, void *dest, const size_t len) +{ + bcopy((void *)src, dest, len); + return (len); +} + +ssize_t +ps3_readin(const int fd, vm_offset_t dest, const size_t len) +{ + void *buf; + size_t resid, chunk, get; + ssize_t got; + vm_offset_t p; + + p = dest; + + chunk = min(PAGE_SIZE, len); + buf = malloc(chunk); + if (buf == NULL) { + printf("ps3_readin: buf malloc failed\n"); + return(0); + } + + for (resid = len; resid > 0; resid -= got, p += got) { + get = min(chunk, resid); + got = read(fd, buf, get); + if (got <= 0) { + if (got < 0) + printf("ps3_readin: read failed\n"); + break; + } + + bcopy(buf, (void *)p, got); + } + + free(buf); + return (len - resid); +} + +int +ps3_autoload(void) +{ + /* XXX Load PS3 FDT? */ return (0); } Modified: projects/ppc64/sys/boot/powerpc/ps3/ppc64_elf_freebsd.c ============================================================================== --- projects/ppc64/sys/boot/powerpc/ps3/ppc64_elf_freebsd.c Sun Apr 25 19:22:06 2010 (r207201) +++ projects/ppc64/sys/boot/powerpc/ps3/ppc64_elf_freebsd.c Sun Apr 25 19:36:05 2010 (r207202) @@ -68,7 +68,7 @@ ppc64_elf_exec(struct preloaded_file *fp vm_offset_t mdp; Elf_Ehdr *e; int error; - intptr_t entry; + int (*entry)(u_long, u_long, u_long, void *, u_long); if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) { return(EFTYPE); @@ -76,19 +76,17 @@ ppc64_elf_exec(struct preloaded_file *fp e = (Elf_Ehdr *)&fmp->md_data; /* Handle function descriptor */ - entry = *(uint64_t *)e->e_entry; + entry = (void *)(uintptr_t)(*(uint64_t *)e->e_entry); if ((error = md_load64(fp->f_args, &mdp)) != 0) return (error); - printf("Kernel entry at 0x%lx ...\n", entry); + printf("Kernel entry at %p ...\n", entry); dev_cleanup(); -#if 0 - OF_chain((void *)reloc, end - (char *)reloc, (void *)entry, - (void *)mdp, sizeof(mdp)); -#endif + entry(0 /* FDT */, 0 /* Phys. mem offset */, 0 /* OF entry */, + (void *)mdp, sizeof(mdp)); panic("exec returned"); } Modified: projects/ppc64/sys/boot/powerpc/ps3/ps3cons.c ============================================================================== --- projects/ppc64/sys/boot/powerpc/ps3/ps3cons.c Sun Apr 25 19:22:06 2010 (r207201) +++ projects/ppc64/sys/boot/powerpc/ps3/ps3cons.c Sun Apr 25 19:36:05 2010 (r207202) @@ -120,11 +120,12 @@ ps3cons_putchar(int c) switch (c) { case '\0': + break; case '\r': + x = 0; break; case '\n': y += FONT_SIZE; - x = 0; break; case '\b': x = max(0, x - 8); Modified: projects/ppc64/sys/boot/powerpc/ps3/ps3net.c ============================================================================== --- projects/ppc64/sys/boot/powerpc/ps3/ps3net.c Sun Apr 25 19:22:06 2010 (r207201) +++ projects/ppc64/sys/boot/powerpc/ps3/ps3net.c Sun Apr 25 19:36:05 2010 (r207202) @@ -106,7 +106,7 @@ static int ps3net_put(struct iodesc *desc, void *pkt, size_t len) { volatile static struct gelic_dmadesc txdesc __aligned(32); - volatile static uint64_t txbuf[200] __aligned(128); + volatile static char txbuf[1536] __aligned(128); size_t sendlen; int err; @@ -165,7 +165,7 @@ static int ps3net_get(struct iodesc *desc, void *pkt, size_t len, time_t timeout) { volatile static struct gelic_dmadesc rxdesc __aligned(32); - volatile static uint64_t rxbuf[200] __aligned(128); + volatile static char rxbuf[1536] __aligned(128); int err = 0; if (len == 0) @@ -206,11 +206,14 @@ ps3net_get(struct iodesc *desc, void *pk #endif restartdma: + lv1_net_stop_rx_dma(busid, devid, 0); + powerpc_sync(); + bzero(&rxdesc, sizeof(rxdesc)); rxdesc.paddr = dma_base + (uint32_t)rxbuf; rxdesc.len = sizeof(rxbuf); + rxdesc.next = 0; rxdesc.cmd_stat = GELIC_DESCR_OWNED; - powerpc_sync(); lv1_net_start_rx_dma(busid, devid, dma_base + (uint32_t)&rxdesc, 0); @@ -265,7 +268,6 @@ ps3net_init(struct iodesc *desc, void *m */ ps3net_get(NULL, NULL, 0, 0); - debug = 1; } static void Modified: projects/ppc64/sys/boot/powerpc/ps3/start.S ============================================================================== --- projects/ppc64/sys/boot/powerpc/ps3/start.S Sun Apr 25 19:22:06 2010 (r207201) +++ projects/ppc64/sys/boot/powerpc/ps3/start.S Sun Apr 25 19:36:05 2010 (r207202) @@ -23,6 +23,7 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <machine/trap_aim.h> /* * KBoot and simulators will start this program from the _start symbol, with @@ -38,7 +39,6 @@ #define CACHELINE_SIZE 128 #define SPR_CTRL 136 -#define TMPSTKSZ 4096 /* KBoot thread 0 entry -- do relocation, then jump to main */ .global _start @@ -50,8 +50,7 @@ _start: cmpwi %r4,0 bne relocate_self relocated_start: - lis %r1,(tmpstk+TMPSTKSZ-16)@ha - addi %r1,%r1,(tmpstk+TMPSTKSZ-16)@l + lis %r1,0x100 bl main . = 0x40 @@ -74,43 +73,89 @@ thread1_start: li %r3,secondary_spin_sem@l 1: lwz %r1,0(%r3) /* Spin on SECONDARY_SPIN_SEM_ADDRESS */ cmpwi %r1,0 - beq 1b + beq 1b /* If the semaphore is still zero, spin again */ + + /* We have been woken up by thread 0 */ li %r0,0x100 /* Invalidate reset vector cache line */ icbi 0,%r0 - ba 0x100 /* If non-zero, jump to the reset vector */ + isync + sync + ba 0x100 /* Jump to the reset vector */ -. = 0x100 +. = EXC_RST exc_rst: mfmsr %r31 clrldi %r31,%r31,1 mtmsrd %r31 isync - mfspr %r0,SPR_CTRL + mfspr %r3,SPR_CTRL /* The first two bits of r0 are 01 (thread 1) or 10 (thread 0) */ - cntlzd %r0,%r0 /* Now 0 for thread 0, 1 for thread 1 */ + cntlzw %r3,%r3 /* Now 0 for thread 0, 1 for thread 1 */ - cmpwi %r0,0 + cmpwi %r3,0 bne thread1_start /* Send thread 1 to wait */ b relocated_start /* Main entry point for thread 0 */ +#define EXCEPTION_HANDLER(exc) \ +. = exc; \ + li %r3, exc; \ + mfsrr0 %r4; \ + mfmsr %r5; \ + clrldi %r6,%r6,1; \ + mtmsrd %r31; \ + isync; \ + lis %r1,0x100; \ + bl ppc_exception + +EXCEPTION_HANDLER(EXC_MCHK) +EXCEPTION_HANDLER(EXC_DSI) +EXCEPTION_HANDLER(EXC_DSE) +EXCEPTION_HANDLER(EXC_ISI) +EXCEPTION_HANDLER(EXC_ISE) +EXCEPTION_HANDLER(EXC_EXI) +EXCEPTION_HANDLER(EXC_ALI) +EXCEPTION_HANDLER(EXC_PGM) +EXCEPTION_HANDLER(EXC_FPU) +EXCEPTION_HANDLER(EXC_DECR) +EXCEPTION_HANDLER(EXC_SC) + relocate_self: /* We enter this with r4 the physical offset for our relocation */ lis %r8,_end@ha /* r8: copy length */ addi %r8,%r8,_end@l - li %r5,0 /* r5: dest address */ + li %r5,0x100 /* r5: dest address */ 1: add %r6,%r4,%r5 /* r6: source address */ ld %r7,0(%r6) std %r7,0(%r5) - cmpw %r5,%r8 addi %r5,%r5,8 + cmpw %r5,%r8 blt 1b + /* + * Now invalidate the cacheline with the second half of relocate_self, + * and do an absolute branch there in case we overwrote part of + * ourselves. + */ + + lis %r9,relocate_self_cache@ha + addi %r9,%r9,relocate_self_cache@l + dcbst 0,%r9 + sync + icbi 0,%r9 + sync + isync + ba relocate_self_cache + +relocate_self_cache: /* Now invalidate the icache */ - li %r5,0 + li %r5,0x100 2: dcbst 0,%r5 + sync icbi 0,%r5 + sync + isync cmpw %r5,%r8 addi %r5,%r5,CACHELINE_SIZE blt 2b @@ -118,7 +163,3 @@ relocate_self: /* All done: absolute jump to relocated entry point */ ba relocated_start -.data -.align 4 -tmpstk: - .space TMPSTKSZ
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201004251936.o3PJa5pk050674>