svn commit: r207202 - projects/ppc64/sys/boot/powerpc/ps3

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sun Apr 25 19:36:05 UTC 2010


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 at 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 at ha	/* r8: copy length */
 	addi	%r8,%r8,_end at 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 at ha
+	addi	%r9,%r9,relocate_self_cache at 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


More information about the svn-src-projects mailing list