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