aboutsummaryrefslogtreecommitdiff
path: root/sys/boot
diff options
context:
space:
mode:
authorMarcel Moolenaar <marcel@FreeBSD.org>2011-02-18 21:39:09 +0000
committerMarcel Moolenaar <marcel@FreeBSD.org>2011-02-18 21:39:09 +0000
commit9b4fcf851a73554063d4a2de9a4f10cd23a0a4f6 (patch)
treef699051130447cd098c44cd4f66287d536761d1b /sys/boot
parent0c21a60cf61c61c3a136a803b9c7645c128c6982 (diff)
parentf6ac113d5ed311c27f61a80ac5314d512a89e262 (diff)
Notes
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/arm/at91/boot0/linker.cfg1
-rw-r--r--sys/boot/arm/at91/linker.cfg3
-rw-r--r--sys/boot/common/loader.88
-rw-r--r--sys/boot/common/ufsread.c2
-rw-r--r--sys/boot/efi/libefi/efinet.c1
-rw-r--r--sys/boot/efi/libefi/efipart.c1
-rw-r--r--sys/boot/fdt/dts/db78100.dts28
-rw-r--r--sys/boot/ficl/Makefile5
-rw-r--r--sys/boot/forth/beastie.4th2
-rw-r--r--sys/boot/forth/loader.conf6
-rw-r--r--sys/boot/i386/Makefile.inc2
-rw-r--r--sys/boot/i386/boot2/Makefile1
-rw-r--r--sys/boot/i386/boot2/boot2.c26
-rw-r--r--sys/boot/i386/gptboot/Makefile1
-rw-r--r--sys/boot/i386/gptzfsboot/Makefile1
-rw-r--r--sys/boot/i386/zfsboot/Makefile1
-rw-r--r--sys/boot/pc98/Makefile2
-rw-r--r--sys/boot/pc98/Makefile.inc2
-rw-r--r--sys/boot/pc98/boot2/Makefile1
-rw-r--r--sys/boot/pc98/boot2/boot2.c7
-rw-r--r--sys/boot/pc98/pc98boot/Makefile25
-rw-r--r--sys/boot/powerpc/Makefile2
-rw-r--r--sys/boot/powerpc/ofw/ldscript.powerpc2
-rw-r--r--sys/boot/powerpc/ps3/Makefile122
-rw-r--r--sys/boot/powerpc/ps3/conf.c119
-rw-r--r--sys/boot/powerpc/ps3/devicename.c238
-rw-r--r--sys/boot/powerpc/ps3/help.ps31
-rw-r--r--sys/boot/powerpc/ps3/ldscript.powerpc110
-rw-r--r--sys/boot/powerpc/ps3/lv1call.S256
-rw-r--r--sys/boot/powerpc/ps3/lv1call.h72
-rw-r--r--sys/boot/powerpc/ps3/main.c211
-rw-r--r--sys/boot/powerpc/ps3/metadata.c355
-rw-r--r--sys/boot/powerpc/ps3/ppc64_elf_freebsd.c98
-rw-r--r--sys/boot/powerpc/ps3/ps3.h35
-rw-r--r--sys/boot/powerpc/ps3/ps3cons.c173
-rw-r--r--sys/boot/powerpc/ps3/ps3mmu.c120
-rw-r--r--sys/boot/powerpc/ps3/ps3net.c278
-rw-r--r--sys/boot/powerpc/ps3/start.S167
-rw-r--r--sys/boot/powerpc/ps3/version6
-rw-r--r--sys/boot/zfs/Makefile5
40 files changed, 2447 insertions, 49 deletions
diff --git a/sys/boot/arm/at91/boot0/linker.cfg b/sys/boot/arm/at91/boot0/linker.cfg
index 8e2c96be1a81..b2318939690f 100644
--- a/sys/boot/arm/at91/boot0/linker.cfg
+++ b/sys/boot/arm/at91/boot0/linker.cfg
@@ -24,7 +24,6 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
"elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(start)
- SEARCH_DIR(/usr/local/arm/2.95.3/arm-linux/lib);
SECTIONS
{
/* Read-only sections, merged into text segment: */
diff --git a/sys/boot/arm/at91/linker.cfg b/sys/boot/arm/at91/linker.cfg
index 40ae7bf270af..8aa095530958 100644
--- a/sys/boot/arm/at91/linker.cfg
+++ b/sys/boot/arm/at91/linker.cfg
@@ -24,9 +24,6 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
"elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(start)
- SEARCH_DIR(/usr/local/arm/2.95.3/arm-linux/lib);
-/* Do we need any of these for elf?
- __DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
diff --git a/sys/boot/common/loader.8 b/sys/boot/common/loader.8
index 56c5199c48e0..94b4e6a38150 100644
--- a/sys/boot/common/loader.8
+++ b/sys/boot/common/loader.8
@@ -609,6 +609,14 @@ Note that
the NBUF parameter will override this limit.
Modifies
.Dv VM_BCACHE_SIZE_MAX .
+.It Va kern.msgbufsize
+Sets the size of the kernel message buffer.
+The default limit of 64KB is usually sufficient unless
+large amounts of trace data need to be collected
+between opportunities to examine the buffer or
+dump it to a file.
+Overrides kernel option
+.Dv MSGBUF_SIZE .
.It Va machdep.disable_mtrrs
Disable the use of i686 MTRRs (x86 only).
.It Va net.inet.tcp.tcbhashsize
diff --git a/sys/boot/common/ufsread.c b/sys/boot/common/ufsread.c
index 5d0e8af56b8e..06539fe90338 100644
--- a/sys/boot/common/ufsread.c
+++ b/sys/boot/common/ufsread.c
@@ -122,7 +122,7 @@ lookup(const char *path)
const char *s;
ino_t ino;
ssize_t n;
- int dt;
+ uint8_t dt;
ino = ROOTINO;
dt = DT_DIR;
diff --git a/sys/boot/efi/libefi/efinet.c b/sys/boot/efi/libefi/efinet.c
index 1eea8606fe15..5b3e401f5c70 100644
--- a/sys/boot/efi/libefi/efinet.c
+++ b/sys/boot/efi/libefi/efinet.c
@@ -262,6 +262,7 @@ efinet_dev_init()
int err, i, nifs;
sz = 0;
+ handles = NULL;
status = BS->LocateHandle(ByProtocol, &sn_guid, 0, &sz, 0);
if (status == EFI_BUFFER_TOO_SMALL) {
handles = (EFI_HANDLE *)malloc(sz);
diff --git a/sys/boot/efi/libefi/efipart.c b/sys/boot/efi/libefi/efipart.c
index 4c8c170f0d96..4abac062dae0 100644
--- a/sys/boot/efi/libefi/efipart.c
+++ b/sys/boot/efi/libefi/efipart.c
@@ -69,6 +69,7 @@ efipart_init(void)
int err;
sz = 0;
+ hin = NULL;
status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz, 0);
if (status == EFI_BUFFER_TOO_SMALL) {
hin = (EFI_HANDLE *)malloc(sz * 2);
diff --git a/sys/boot/fdt/dts/db78100.dts b/sys/boot/fdt/dts/db78100.dts
index 5c9512f4f0d0..015768164826 100644
--- a/sys/boot/fdt/dts/db78100.dts
+++ b/sys/boot/fdt/dts/db78100.dts
@@ -308,8 +308,36 @@
};
};
+ pci0: pcie@f1040000 {
+ compatible = "mrvl,pcie";
+ device_type = "pci";
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <0xf1040000 0x2000>;
+ bus-range = <0 255>;
+ ranges = <0x02000000 0x0 0xf2000000 0xf2000000 0x0 0x04000000
+ 0x01000000 0x0 0x00000000 0xf1100000 0x0 0x00100000>;
+ clock-frequency = <33333333>;
+ interrupt-parent = <&PIC>;
+ interrupts = <68>;
+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+ interrupt-map = <
+ /* IDSEL 0x1 */
+ 0x0800 0x0 0x0 0x1 &PIC 0x20
+ 0x0800 0x0 0x0 0x2 &PIC 0x21
+ 0x0800 0x0 0x0 0x3 &PIC 0x22
+ 0x0800 0x0 0x0 0x4 &PIC 0x23
+ >;
+ };
+
sram@fd000000 {
compatible = "mrvl,cesa-sram";
reg = <0xfd000000 0x00100000>;
};
+
+ chosen {
+ stdin = "serial0";
+ stdout = "serial0";
+ };
};
diff --git a/sys/boot/ficl/Makefile b/sys/boot/ficl/Makefile
index 61760d003280..e4415737317f 100644
--- a/sys/boot/ficl/Makefile
+++ b/sys/boot/ficl/Makefile
@@ -9,10 +9,7 @@ CLEANFILES= softcore.c testmain testmain.o
CFLAGS+= -ffreestanding
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
CFLAGS+= -mpreferred-stack-boundary=2
-CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2
-.endif
-.if ${MACHINE_CPUARCH} == "i386"
-CFLAGS+= -mno-sse3
+CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
.endif
.if ${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_CPUARCH} == "arm"
CFLAGS+= -msoft-float
diff --git a/sys/boot/forth/beastie.4th b/sys/boot/forth/beastie.4th
index 65d5fc03cf3f..1130ed04ec88 100644
--- a/sys/boot/forth/beastie.4th
+++ b/sys/boot/forth/beastie.4th
@@ -193,7 +193,7 @@ at-xy ." `--{__________) "
then
else
menuidx @
- 1+ dup
+ 1+
menuidx !
-2 bootacpikey !
then
diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf
index 4f07b912178b..bfb4ff6f3929 100644
--- a/sys/boot/forth/loader.conf
+++ b/sys/boot/forth/loader.conf
@@ -99,6 +99,7 @@ module_path="/boot/modules" # Set the module search path
#kern.maxswzone="" # Set the max swmeta KVA storage
#kern.maxtsiz="" # Set the max text size
#kern.maxusers="32" # Set size of various static tables
+#kern.msgbufsize="65536" # Set size of kernel message buffer
#kern.nbuf="" # Set the number of buffer headers
#kern.ncallout="" # Set the maximum # of timer events
#kern.ngroups="1023" # Set the maximum # of supplemental groups
@@ -251,6 +252,7 @@ pf_load="NO" # packet filter
### Networking drivers #####################################
##############################################################
+bridgestp_load="NO" # if_bridge(4) support
miibus_load="NO" # miibus support, needed for some drivers
if_ae_load="NO" # Attansic/Atheros L2 FastEthernet
if_age_load="NO" # Attansic/Atheros L1 Gigabit Ethernet
@@ -263,8 +265,10 @@ if_axe_load="NO" # ASIX Electronics AX88172 USB Ethernet
if_bce_load="NO" # Broadcom NetXtreme II Gigabit Ethernet
if_bfe_load="NO" # Broadcom BCM4401
if_bge_load="NO" # Broadcom BCM570x PCI Gigabit Ethernet
+if_bridge_load="NO" # if_bridge(4) devices
if_bwi_load="NO" # Broadcom BCM53xx IEEE 802.11b/g wireness NICs
if_bwn_load="NO" # Broadcom BCM43xx IEEE 802.11 wireless NICs
+if_carp_load="NO" # carp(4) devices
if_cas_load="NO" # Sun Cassini/Cassini+ and NS DP83065 Saturn
if_cm_load="NO" # SMC (90c26, 90c56, 90c66)
if_cs_load="NO" # Crystal Semiconductor CS8920
@@ -295,6 +299,7 @@ if_iwn_load="NO" # Intel Wireless WiFi Link 802.11n wireless
if_ixgb_load="NO" # Intel PRO/10Gb Ethernet
if_ixgbe_load="NO" # Intel PRO/10Gb Ethernet PCI Express
if_jme_load="NO" # JMicron JMC250 Gigabit/JMC260 Fast Ethernet
+if_lagg_load="NO" # lagg(4) devices
if_le_load="NO" # AMD Am7900 LANCE and Am79C9xx PCnet
if_lge_load="NO" # Level 1 LXT1001 NetCellerator PCI Gigabit
# Ethernet
@@ -328,6 +333,7 @@ if_tl_load="NO" # Texas Instruments TNETE100 ("ThunderLAN")
if_tx_load="NO" # SMC 83c17x Fast Ethernet
if_txp_load="NO" # 3Com 3XP Typhoon/Sidewinder (3CR990)
if_vge_load="NO" # VIA VT6122 PCI Gigabit Ethernet
+if_vte_load="NO" # DM&P Vortex86 RDC R6040 Fast Ethernet
if_uath_load="NO" # Atheros USB wireless for AR5005UG & AR5005UX
if_udav_load="NO" # Davicom DM9601 USB Ethernet
if_upgt_load="NO" # Conexant/Intersil PrismGT USB wireless
diff --git a/sys/boot/i386/Makefile.inc b/sys/boot/i386/Makefile.inc
index a25684012c90..f165042df8cd 100644
--- a/sys/boot/i386/Makefile.inc
+++ b/sys/boot/i386/Makefile.inc
@@ -6,7 +6,7 @@ BINDIR?= /boot
LOADER_ADDRESS?=0x200000
CFLAGS+= -ffreestanding -mpreferred-stack-boundary=2 \
- -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3
+ -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
LDFLAGS+= -nostdlib
.if ${MACHINE_CPUARCH} == "amd64"
diff --git a/sys/boot/i386/boot2/Makefile b/sys/boot/i386/boot2/Makefile
index b91a43bccc4e..6e8315ee1d61 100644
--- a/sys/boot/i386/boot2/Makefile
+++ b/sys/boot/i386/boot2/Makefile
@@ -31,7 +31,6 @@ CFLAGS= -Os \
-fno-unit-at-a-time \
-mno-align-long-strings \
-mrtd \
- -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 \
-D${BOOT2_UFS} \
-DFLAGS=${BOOT_BOOT1_FLAGS} \
-DSIOPRT=${BOOT_COMCONSOLE_PORT} \
diff --git a/sys/boot/i386/boot2/boot2.c b/sys/boot/i386/boot2/boot2.c
index 307d4c5df087..38497252450d 100644
--- a/sys/boot/i386/boot2/boot2.c
+++ b/sys/boot/i386/boot2/boot2.c
@@ -132,7 +132,7 @@ static struct dsk {
} dsk;
static char cmd[512], cmddup[512];
static char kname[1024];
-static uint32_t opts;
+static uint16_t opts;
static int comspeed = SIOSPD;
static struct bootinfo bootinfo;
static uint8_t ioctrl = IO_KEYBOARD;
@@ -233,7 +233,7 @@ putc(int c)
int
main(void)
{
- int autoboot;
+ uint8_t autoboot;
ino_t ino;
dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
@@ -320,7 +320,8 @@ load(void)
caddr_t p;
ino_t ino;
uint32_t addr, x;
- int fmt, i, j;
+ int i, j;
+ uint8_t fmt;
if (!(ino = lookup(kname))) {
if (!ls)
@@ -346,23 +347,6 @@ load(void)
p += roundup2(hdr.ex.a_text, PAGE_SIZE);
if (xfsread(ino, p, hdr.ex.a_data))
return;
- p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE);
- bootinfo.bi_symtab = VTOP(p);
- *(uint32_t*)p = hdr.ex.a_syms;
- p += sizeof(hdr.ex.a_syms);
- if (hdr.ex.a_syms) {
- if (xfsread(ino, p, hdr.ex.a_syms))
- return;
- p += hdr.ex.a_syms;
- if (xfsread(ino, p, sizeof(int)))
- return;
- x = *(uint32_t *)p;
- p += sizeof(int);
- x -= sizeof(int);
- if (xfsread(ino, p, x))
- return;
- p += x;
- }
} else {
fs_off = hdr.eh.e_phoff;
for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) {
@@ -394,8 +378,8 @@ load(void)
}
}
addr = hdr.eh.e_entry & 0xffffff;
+ bootinfo.bi_esymtab = VTOP(p);
}
- bootinfo.bi_esymtab = VTOP(p);
bootinfo.bi_kernelname = VTOP(kname);
bootinfo.bi_bios_dev = dsk.drive;
__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
diff --git a/sys/boot/i386/gptboot/Makefile b/sys/boot/i386/gptboot/Makefile
index a0fad610c000..452b100160c5 100644
--- a/sys/boot/i386/gptboot/Makefile
+++ b/sys/boot/i386/gptboot/Makefile
@@ -26,7 +26,6 @@ CFLAGS= -DBOOTPROG=\"gptboot\" \
-fno-unit-at-a-time \
-mno-align-long-strings \
-mrtd \
- -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 \
-DGPT \
-D${GPTBOOT_UFS} \
-DSIOPRT=${BOOT_COMCONSOLE_PORT} \
diff --git a/sys/boot/i386/gptzfsboot/Makefile b/sys/boot/i386/gptzfsboot/Makefile
index 30a5fc78abac..7f5f287bab52 100644
--- a/sys/boot/i386/gptzfsboot/Makefile
+++ b/sys/boot/i386/gptzfsboot/Makefile
@@ -23,7 +23,6 @@ CFLAGS= -DBOOTPROG=\"gptzfsboot\" \
-fno-unit-at-a-time \
-mno-align-long-strings \
-mrtd \
- -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 \
-DGPT -DBOOT2 \
-DSIOPRT=${BOOT_COMCONSOLE_PORT} \
-DSIOFMT=${B2SIOFMT} \
diff --git a/sys/boot/i386/zfsboot/Makefile b/sys/boot/i386/zfsboot/Makefile
index 10616e418acc..38e8a9f663a6 100644
--- a/sys/boot/i386/zfsboot/Makefile
+++ b/sys/boot/i386/zfsboot/Makefile
@@ -24,7 +24,6 @@ CFLAGS= -DBOOTPROG=\"zfsboot\" \
-fno-unit-at-a-time \
-mno-align-long-strings \
-mrtd \
- -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 \
-DBOOT2 \
-DFLAGS=${BOOT_BOOT1_FLAGS} \
-DSIOPRT=${BOOT_COMCONSOLE_PORT} \
diff --git a/sys/boot/pc98/Makefile b/sys/boot/pc98/Makefile
index ca89dbc242de..e8f9dbffe1e0 100644
--- a/sys/boot/pc98/Makefile
+++ b/sys/boot/pc98/Makefile
@@ -1,5 +1,5 @@
# $FreeBSD$
-SUBDIR= btx boot0 boot0.5 boot2 cdboot kgzldr libpc98 loader
+SUBDIR= boot0 boot0.5 pc98boot btx boot2 cdboot kgzldr libpc98 loader
.include <bsd.subdir.mk>
diff --git a/sys/boot/pc98/Makefile.inc b/sys/boot/pc98/Makefile.inc
index 641fbca88e67..62cfc1d9f3a8 100644
--- a/sys/boot/pc98/Makefile.inc
+++ b/sys/boot/pc98/Makefile.inc
@@ -6,7 +6,7 @@ BINDIR?= /boot
LOADER_ADDRESS?=0x200000
CFLAGS+= -ffreestanding -mpreferred-stack-boundary=2 \
- -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 \
+ -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float \
-Os -DPC98
LDFLAGS+= -nostdlib
diff --git a/sys/boot/pc98/boot2/Makefile b/sys/boot/pc98/boot2/Makefile
index dfd8607510c2..035b5dd7ea2c 100644
--- a/sys/boot/pc98/boot2/Makefile
+++ b/sys/boot/pc98/boot2/Makefile
@@ -28,7 +28,6 @@ CFLAGS= -Os \
-fno-unit-at-a-time \
-mno-align-long-strings \
-mrtd \
- -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 \
-D${BOOT2_UFS} \
-DFLAGS=${BOOT_BOOT1_FLAGS} \
-DSIOPRT=${BOOT_COMCONSOLE_PORT} \
diff --git a/sys/boot/pc98/boot2/boot2.c b/sys/boot/pc98/boot2/boot2.c
index 259d5de93fe3..59bbec7e9111 100644
--- a/sys/boot/pc98/boot2/boot2.c
+++ b/sys/boot/pc98/boot2/boot2.c
@@ -134,7 +134,7 @@ static struct dsk {
} dsk;
static char cmd[512], cmddup[512];
static char kname[1024];
-static uint32_t opts;
+static uint16_t opts;
static int comspeed = SIOSPD;
static struct bootinfo bootinfo;
static uint8_t ioctrl = IO_KEYBOARD;
@@ -360,7 +360,7 @@ main(void)
#ifdef GET_BIOSGEOM
int i;
#endif
- int autoboot;
+ uint8_t autoboot;
ino_t ino;
dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
@@ -457,7 +457,8 @@ load(void)
caddr_t p;
ino_t ino;
uint32_t addr, x;
- int fmt, i, j;
+ int i, j;
+ uint8_t fmt;
if (!(ino = lookup(kname))) {
if (!ls)
diff --git a/sys/boot/pc98/pc98boot/Makefile b/sys/boot/pc98/pc98boot/Makefile
new file mode 100644
index 000000000000..73bfba50fbbe
--- /dev/null
+++ b/sys/boot/pc98/pc98boot/Makefile
@@ -0,0 +1,25 @@
+# $FreeBSD$
+
+FILES= ${BOOT}
+CLEANFILES= ${BOOT} ${BOOT}.part
+
+BOOT= pc98boot
+
+.if exists(${.OBJDIR}/../boot0)
+BOOT0= ${.OBJDIR}/../boot0/boot0
+.else
+BOOT0= ${.CURDIR}/../boot0/boot0
+.endif
+.if exists(${.OBJDIR}/../boot0.5)
+BOOT05= ${.OBJDIR}/../boot0.5/boot0.5
+.else
+BOOT05= ${.CURDIR}/../boot0.5/boot0.5
+.endif
+
+${BOOT}: ${BOOT0} ${BOOT05} ${BOOT}.part
+ cat ${BOOT0} ${BOOT}.part ${BOOT05} > ${.TARGET}
+
+${BOOT}.part:
+ dd if=/dev/zero of=${.TARGET} bs=512 count=1
+
+.include <bsd.prog.mk>
diff --git a/sys/boot/powerpc/Makefile b/sys/boot/powerpc/Makefile
index 80a68a672c62..d3652c4e3905 100644
--- a/sys/boot/powerpc/Makefile
+++ b/sys/boot/powerpc/Makefile
@@ -1,5 +1,5 @@
# $FreeBSD$
-SUBDIR= boot1.chrp ofw uboot
+SUBDIR= boot1.chrp ofw ps3 uboot
.include <bsd.subdir.mk>
diff --git a/sys/boot/powerpc/ofw/ldscript.powerpc b/sys/boot/powerpc/ofw/ldscript.powerpc
index e3b7b2c4b4c2..92046fc827c4 100644
--- a/sys/boot/powerpc/ofw/ldscript.powerpc
+++ b/sys/boot/powerpc/ofw/ldscript.powerpc
@@ -4,8 +4,6 @@ OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
OUTPUT_ARCH(powerpc:common)
ENTRY(_start)
SEARCH_DIR(/usr/lib);
-/* Do we need any of these for elf?
- __DYNAMIC = 0; */
PROVIDE (__stack = 0);
SECTIONS
{
diff --git a/sys/boot/powerpc/ps3/Makefile b/sys/boot/powerpc/ps3/Makefile
new file mode 100644
index 000000000000..b3a37be90068
--- /dev/null
+++ b/sys/boot/powerpc/ps3/Makefile
@@ -0,0 +1,122 @@
+# $FreeBSD$
+
+.include <bsd.own.mk>
+MK_SSP= no
+
+PROG= loader.ps3
+NEWVERSWHAT= "Playstation 3 loader" ${MACHINE_ARCH}
+BINDIR?= /boot
+INSTALLFLAGS= -b
+
+# Architecture-specific loader code
+SRCS= start.S conf.c metadata.c vers.c main.c devicename.c ppc64_elf_freebsd.c
+SRCS+= lv1call.S ps3cons.c font.h ps3mmu.c ps3net.c
+SRCS+= ucmpdi2.c
+
+LOADER_DISK_SUPPORT?= yes
+LOADER_UFS_SUPPORT?= yes
+LOADER_CD9660_SUPPORT?= yes
+LOADER_EXT2FS_SUPPORT?= no
+LOADER_NET_SUPPORT?= yes
+LOADER_NFS_SUPPORT?= yes
+LOADER_TFTP_SUPPORT?= no
+LOADER_GZIP_SUPPORT?= yes
+LOADER_FDT_SUPPORT?= no
+LOADER_BZIP2_SUPPORT?= no
+
+.if ${LOADER_DISK_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_DISK_SUPPORT
+.endif
+.if ${LOADER_UFS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_UFS_SUPPORT
+.endif
+.if ${LOADER_CD9660_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_CD9660_SUPPORT
+.endif
+.if ${LOADER_EXT2FS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_EXT2FS_SUPPORT
+.endif
+.if ${LOADER_GZIP_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_GZIP_SUPPORT
+.endif
+.if ${LOADER_BZIP2_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_BZIP2_SUPPORT
+.endif
+.if ${LOADER_NET_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_NET_SUPPORT
+.endif
+.if ${LOADER_NFS_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_NFS_SUPPORT
+.endif
+.if ${LOADER_TFTP_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_TFTP_SUPPORT
+.endif
+.if ${LOADER_FDT_SUPPORT} == "yes"
+CFLAGS+= -I${.CURDIR}/../../fdt
+CFLAGS+= -I${.OBJDIR}/../../fdt
+CFLAGS+= -DLOADER_FDT_SUPPORT
+LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a
+.endif
+
+
+.if ${MK_FORTH} != "no"
+# Enable BootForth
+BOOT_FORTH= yes
+CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/powerpc
+LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
+.endif
+
+# 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 -mcpu=powerpc64
+
+# Always add MI sources
+.PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern
+.include "${.CURDIR}/../../common/Makefile.inc"
+CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../..
+CFLAGS+= -I.
+
+CLEANFILES+= vers.c loader.help
+
+CFLAGS+= -Wall -ffreestanding -msoft-float -DAIM
+# load address. set in linker script
+RELOC?= 0x0
+CFLAGS+= -DRELOC=${RELOC}
+
+LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc
+
+# 64-bit bridge extensions
+CFLAGS+= -Wa,-mppc64bridge
+
+# Pull in common loader code
+#.PATH: ${.CURDIR}/../../ofw/common
+#.include "${.CURDIR}/../../ofw/common/Makefile.inc"
+
+# where to get libstand from
+CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
+
+DPADD= ${LIBFICL} ${LIBOFW} ${LIBSTAND}
+LDADD= ${LIBFICL} ${LIBOFW} -lstand
+
+SC_DFLT_FONT=cp437
+
+font.h:
+ uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h
+
+vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
+ sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
+
+loader.help: help.common help.ps3
+ cat ${.ALLSRC} | \
+ awk -f ${.CURDIR}/../../common/merge_help.awk > ${.TARGET}
+
+.PATH: ${.CURDIR}/../../forth
+FILES= loader.help loader.4th support.4th loader.conf
+FILESDIR_loader.conf= /boot/defaults
+
+.if !exists(${DESTDIR}/boot/loader.rc)
+FILES+= loader.rc
+.endif
+
+.include <bsd.prog.mk>
diff --git a/sys/boot/powerpc/ps3/conf.c b/sys/boot/powerpc/ps3/conf.c
new file mode 100644
index 000000000000..7749a1592c28
--- /dev/null
+++ b/sys/boot/powerpc/ps3/conf.c
@@ -0,0 +1,119 @@
+/*-
+ * Copyright (c) 1999 Michael Smith <msmith@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include "bootstrap.h"
+
+#if defined(LOADER_NET_SUPPORT)
+#include "dev_net.h"
+#endif
+
+/*
+ * We could use linker sets for some or all of these, but
+ * then we would have to control what ended up linked into
+ * the bootstrap. So it's easier to conditionalise things
+ * here.
+ *
+ * XXX rename these arrays to be consistent and less namespace-hostile
+ */
+
+/* Exported for libstand */
+struct devsw *devsw[] = {
+#if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CD9660_SUPPORT)
+#ifdef NOTYET
+ &ps3disk,
+#endif
+#endif
+#if defined(LOADER_NET_SUPPORT)
+ &netdev,
+#endif
+ NULL
+};
+
+struct fs_ops *file_system[] = {
+#if defined(LOADER_UFS_SUPPORT)
+ &ufs_fsops,
+#endif
+#if defined(LOADER_CD9660_SUPPORT)
+ &cd9660_fsops,
+#endif
+#if defined(LOADER_EXT2FS_SUPPORT)
+ &ext2fs_fsops,
+#endif
+#if defined(LOADER_NFS_SUPPORT)
+ &nfs_fsops,
+#endif
+#if defined(LOADER_TFTP_SUPPORT)
+ &tftp_fsops,
+#endif
+#if defined(LOADER_GZIP_SUPPORT)
+ &gzipfs_fsops,
+#endif
+#if defined(LOADER_BZIP2_SUPPORT)
+ &bzipfs_fsops,
+#endif
+ NULL
+};
+
+extern struct netif_driver ps3net;
+
+struct netif_driver *netif_drivers[] = {
+#if defined(LOADER_NET_SUPPORT)
+ &ps3net,
+#endif
+ NULL,
+};
+
+/* Exported for PowerPC only */
+/*
+ * Sort formats so that those that can detect based on arguments
+ * rather than reading the file go first.
+ */
+
+extern struct file_format ppc_elf64;
+
+struct file_format *file_formats[] = {
+ &ppc_elf64,
+ NULL
+};
+
+/*
+ * Consoles
+ */
+extern struct console ps3console;
+
+struct console *consoles[] = {
+ &ps3console,
+ NULL
+};
+
+/*
+ * reloc - our load address
+ */
+vm_offset_t reloc = RELOC;
diff --git a/sys/boot/powerpc/ps3/devicename.c b/sys/boot/powerpc/ps3/devicename.c
new file mode 100644
index 000000000000..b652d9bd587e
--- /dev/null
+++ b/sys/boot/powerpc/ps3/devicename.c
@@ -0,0 +1,238 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/disklabel.h>
+
+#include <stand.h>
+#include <string.h>
+
+#include "bootstrap.h"
+
+static int ps3_parsedev(struct devdesc **dev, const char *devspec,
+ const char **path);
+
+/*
+ * Point (dev) at an allocated device specifier for the device matching the
+ * path in (devspec). If it contains an explicit device specification,
+ * use that. If not, use the default device.
+ */
+int
+ps3_getdev(void **vdev, const char *devspec, const char **path)
+{
+ struct devdesc **dev = (struct devdesc **)vdev;
+ int rv = 0;
+
+ /*
+ * If it looks like this is just a path and no
+ * device, go with the current device.
+ */
+ if ((devspec == NULL) || (devspec[0] == '/') ||
+ (strchr(devspec, ':') == NULL)) {
+ rv = ps3_parsedev(dev, getenv("currdev"), NULL);
+
+ if (rv == 0 && path != NULL)
+ *path = devspec;
+ return(rv);
+ }
+
+ /*
+ * Try to parse the device name off the beginning of the devspec.
+ */
+ return (ps3_parsedev(dev, devspec, path));
+}
+
+/*
+ * Point (dev) at an allocated device specifier matching the string version
+ * at the beginning of (devspec). Return a pointer to the remaining
+ * text in (path).
+ *
+ * In all cases, the beginning of (devspec) is compared to the names
+ * of known devices in the device switch, and then any following text
+ * is parsed according to the rules applied to the device type.
+ *
+ * For disk-type devices, the syntax is:
+ *
+ * disk<unit>[<partition>]:
+ *
+ */
+static int
+ps3_parsedev(struct devdesc **dev, const char *devspec, const char **path)
+{
+ struct devdesc *idev;
+ struct devsw *dv;
+ char *cp;
+ const char *np;
+ int i, unit, pnum, ptype, err;
+
+ /* minimum length check */
+ if (strlen(devspec) < 2)
+ return(EINVAL);
+
+ /* look for a device that matches */
+ for (i = 0, dv = NULL; devsw[i] != NULL; i++) {
+ if (!strncmp(devspec, devsw[i]->dv_name,
+ strlen(devsw[i]->dv_name))) {
+ dv = devsw[i];
+ break;
+ }
+ }
+ if (dv == NULL)
+ return(ENOENT);
+ idev = malloc(sizeof(struct devdesc));
+ err = 0;
+ np = (devspec + strlen(dv->dv_name));
+
+ switch(dv->dv_type) {
+ case DEVT_NONE:
+ break;
+
+#ifdef NOTYET
+ case DEVT_DISK:
+ unit = -1;
+ pnum = -1;
+ ptype = -1;
+ if (*np && (*np != ':')) {
+ /* next comes the unit number */
+ unit = strtol(np, &cp, 10);
+ if (cp == np) {
+ err = EUNIT;
+ goto fail;
+ }
+ if (*cp && (*cp != ':')) {
+ /* get partition */
+ if (*cp == 'p' && *(cp + 1) &&
+ *(cp + 1) != ':') {
+ pnum = strtol(cp + 1, &cp, 10);
+ ptype = PTYPE_GPT;
+ } else {
+ pnum = *cp - 'a';
+ ptype = PTYPE_BSDLABEL;
+ if ((pnum < 0) ||
+ (pnum >= MAXPARTITIONS)) {
+ err = EPART;
+ goto fail;
+ }
+ cp++;
+ }
+ }
+ }
+ if (*cp && (*cp != ':')) {
+ err = EINVAL;
+ goto fail;
+ }
+
+ idev->d_unit = unit;
+ idev->d_disk.pnum = pnum;
+ idev->d_disk.ptype = ptype;
+ idev->d_disk.data = NULL;
+ if (path != NULL)
+ *path = (*cp == 0) ? cp : cp + 1;
+ break;
+#endif
+
+ case DEVT_NET:
+ /*
+ * PS3 only has one network interface (well, two, but
+ * netbooting over wireless is not something I'm going
+ * to worry about.
+ */
+
+ idev->d_unit = 0;
+ break;
+
+ default:
+ err = EINVAL;
+ goto fail;
+ }
+ idev->d_dev = dv;
+ idev->d_type = dv->dv_type;
+ if (dev == NULL) {
+ free(idev);
+ } else {
+ *dev = idev;
+ }
+ return (0);
+
+fail:
+ free(idev);
+ return (err);
+}
+
+
+char *
+ps3_fmtdev(void *vdev)
+{
+ struct devdesc *dev = (struct devdesc *)vdev;
+ char *cp;
+ static char buf[128];
+
+ switch(dev->d_type) {
+ case DEVT_NONE:
+ strcpy(buf, "(no device)");
+ break;
+
+#ifdef NOTYET
+ case DEVT_DISK:
+ cp = buf;
+ cp += sprintf(cp, "%s%d", dev->d_dev->dv_name, dev->d_unit);
+ if (dev->d_kind.disk.pnum >= 0) {
+ if (dev->d_kind.disk.ptype == PTYPE_BSDLABEL)
+ cp += sprintf(cp, "%c",
+ dev->d_kind.disk.pnum + 'a');
+ else if (dev->d_kind.disk.ptype == PTYPE_GPT)
+ cp += sprintf(cp, "p%i",
+ dev->d_kind.disk.pnum);
+ }
+
+ strcat(cp, ":");
+ break;
+#endif
+
+ case DEVT_NET:
+ sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
+ break;
+ }
+ return(buf);
+}
+
+/*
+ * Set currdev to suit the value being supplied in (value).
+ */
+int
+ps3_setcurrdev(struct env_var *ev, int flags, const void *value)
+{
+ struct devdesc *ncurr;
+ int rv;
+
+ if ((rv = ps3_parsedev(&ncurr, value, NULL)) != 0)
+ return (rv);
+ free(ncurr);
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+ return (0);
+}
diff --git a/sys/boot/powerpc/ps3/help.ps3 b/sys/boot/powerpc/ps3/help.ps3
new file mode 100644
index 000000000000..5873eb0512d2
--- /dev/null
+++ b/sys/boot/powerpc/ps3/help.ps3
@@ -0,0 +1 @@
+$FreeBSD$
diff --git a/sys/boot/powerpc/ps3/ldscript.powerpc b/sys/boot/powerpc/ps3/ldscript.powerpc
new file mode 100644
index 000000000000..c425f60ec8e9
--- /dev/null
+++ b/sys/boot/powerpc/ps3/ldscript.powerpc
@@ -0,0 +1,110 @@
+/* $FreeBSD$ */
+
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
+OUTPUT_ARCH(powerpc:common)
+ENTRY(_start)
+SEARCH_DIR(/usr/lib);
+PROVIDE (__stack = 0);
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0x0;
+ .text :
+ {
+ *(.text)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } =0
+ _etext = .;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rela.text :
+ { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+ .rela.data :
+ { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+ .rela.rodata :
+ { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+ .rela.got : { *(.rela.got) }
+ .rela.got1 : { *(.rela.got1) }
+ .rela.got2 : { *(.rela.got2) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rela.init : { *(.rela.init) }
+ .rela.fini : { *(.rela.fini) }
+ .rela.bss : { *(.rela.bss) }
+ .rela.plt : { *(.rela.plt) }
+ .rela.sbss : { *(.rela.sbss) }
+ .rela.sbss2 : { *(.rela.sbss2) }
+ .text :
+ {
+ *(.text)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } =0
+ _etext = .;
+ PROVIDE (etext = .);
+ .init : { *(.init) } =0
+ .fini : { *(.fini) } =0
+ .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
+ .rodata1 : { *(.rodata1) }
+ .sbss2 : { *(.sbss2) }
+ /* Adjust the address for the data segment to the next page up. */
+ . = ((. + 0x1000) & ~(0x1000 - 1));
+ .data :
+ {
+ *(.data)
+ *(.gnu.linkonce.d*)
+ CONSTRUCTORS
+ }
+ .data1 : { *(.data1) }
+ .got1 : { *(.got1) }
+ .dynamic : { *(.dynamic) }
+ /* Put .ctors and .dtors next to the .got2 section, so that the pointers
+ get relocated with -mrelocatable. Also put in the .fixup pointers.
+ The current compiler no longer needs this, but keep it around for 2.7.2 */
+ PROVIDE (_GOT2_START_ = .);
+ .got2 : { *(.got2) }
+ PROVIDE (__CTOR_LIST__ = .);
+ .ctors : { *(.ctors) }
+ PROVIDE (__CTOR_END__ = .);
+ PROVIDE (__DTOR_LIST__ = .);
+ .dtors : { *(.dtors) }
+ PROVIDE (__DTOR_END__ = .);
+ PROVIDE (_FIXUP_START_ = .);
+ .fixup : { *(.fixup) }
+ PROVIDE (_FIXUP_END_ = .);
+ PROVIDE (_GOT2_END_ = .);
+ PROVIDE (_GOT_START_ = .);
+ .got : { *(.got) }
+ .got.plt : { *(.got.plt) }
+ PROVIDE (_GOT_END_ = .);
+ _edata = .;
+ PROVIDE (edata = .);
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .);
+ *(.sbss)
+ *(.scommon)
+ *(.dynsbss)
+ PROVIDE (__sbss_end = .);
+ }
+ .plt : { *(.plt) }
+ .bss :
+ {
+ PROVIDE (__bss_start = .);
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(4096);
+ _end = . ;
+ PROVIDE (end = .);
+}
+
diff --git a/sys/boot/powerpc/ps3/lv1call.S b/sys/boot/powerpc/ps3/lv1call.S
new file mode 100644
index 000000000000..a5dafdd08483
--- /dev/null
+++ b/sys/boot/powerpc/ps3/lv1call.S
@@ -0,0 +1,256 @@
+/*-
+ * Copyright (C) 2010 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/* Hypercall stubs. Note: this is all a hack and should die. */
+
+#define hc .long 0x44000022
+
+#define LD64_IM(r, highest, higher, high, low) \
+ lis r,highest; \
+ addi r,r,higher; \
+ sldi r,r,32; \
+ addis r,r,high; \
+ addi r,r,low;
+
+#define SIMPLE_HVCALL(x, c) \
+.global x; \
+x: \
+ mflr %r0; \
+ stw %r0,4(%r1); \
+ clrldi %r3,%r3,32; \
+ clrldi %r4,%r4,32; \
+ clrldi %r5,%r5,32; \
+ clrldi %r6,%r6,32; \
+ clrldi %r7,%r7,32; \
+ clrldi %r8,%r8,32; \
+ clrldi %r9,%r9,32; \
+ clrldi %r10,%r10,32; \
+ li %r11,c; \
+ hc; \
+ extsw %r3,%r3; \
+ lwz %r0,4(%r1); \
+ mtlr %r0; \
+ blr
+
+SIMPLE_HVCALL(lv1_open_device, 170)
+SIMPLE_HVCALL(lv1_close_device, 171)
+SIMPLE_HVCALL(lv1_gpu_open, 210)
+SIMPLE_HVCALL(lv1_gpu_context_attribute, 225)
+SIMPLE_HVCALL(lv1_panic, 255)
+SIMPLE_HVCALL(lv1_net_start_tx_dma, 187)
+SIMPLE_HVCALL(lv1_net_stop_tx_dma, 188)
+SIMPLE_HVCALL(lv1_net_start_rx_dma, 189)
+SIMPLE_HVCALL(lv1_net_stop_rx_dma, 190)
+
+.global lv1_get_physmem
+lv1_get_physmem:
+ mflr %r0
+ stw %r0,4(%r1)
+ stw %r3,-8(%r1) /* Address for maxmem */
+
+ li %r11,69 /* Get PU ID */
+ hc
+ std %r4,-16(%r1)
+
+ li %r11,74 /* Get LPAR ID */
+ hc
+ std %r4,-24(%r1)
+
+ ld %r3,-24(%r1)
+ LD64_IM(%r4,0x0000,0x0000,0x6269,0x0000 /* "bi" */)
+ LD64_IM(%r5,0x7075,0x0000,0x0000,0x0000 /* "pu" */)
+ ld %r6,-16(%r1)
+ LD64_IM(%r7,0x726d,0x5f73,0x697a,0x6500 /* "rm_size" */)
+ li %r11,91
+ hc
+ extsw %r3,%r3
+
+ lwz %r5,-8(%r1)
+ std %r4,0(%r5)
+
+ lwz %r0,4(%r1)
+ mtlr %r0
+ blr
+
+.global lv1_setup_address_space
+lv1_setup_address_space:
+ mflr %r0
+ stw %r0,4(%r1)
+
+ stw %r3,-4(%r1)
+ stw %r4,-8(%r1)
+
+ li %r3,18 /* PT size: log2(256 KB) */
+ li %r4,2 /* Two page sizes */
+ li %r5,24 /* Page sizes: (24 << 56) | (16 << 48) */
+ sldi %r5,%r5,24
+ li %r6,16
+ sldi %r6,%r6,16
+ or %r5,%r5,%r6
+ sldi %r5,%r5,32
+
+ li %r11,2 /* lv1_construct_virtual_address_space */
+ hc
+
+ lwz %r6,-4(%r1)
+ lwz %r7,-8(%r1)
+ std %r4,0(%r6)
+ std %r5,0(%r7)
+
+ /* AS_ID in r4 */
+ mr %r3,%r4
+ li %r11,7 /* lv1_select_virtual_address_space */
+ hc
+ extsw %r3,%r3
+
+ lwz %r0,4(%r1)
+ mtlr %r0
+ blr
+
+.global lv1_insert_pte
+lv1_insert_pte:
+ mflr %r0
+ stw %r0,4(%r1)
+
+ mr %r11,%r4 /* Save R4 */
+
+ clrldi %r3,%r3,32
+ clrldi %r7,%r5,32
+
+ sldi %r4,%r3,3 /* Convert ptegidx into base PTE slot */
+ li %r3,0 /* Current address space */
+ ld %r5,0(%r11)
+ ld %r6,8(%r11)
+ li %r8,0 /* No other flags */
+
+ li %r11,158
+ hc
+ extsw %r3,%r3
+
+ lwz %r0,4(%r1)
+ mtlr %r0
+ blr
+
+.global lv1_gpu_context_allocate
+lv1_gpu_context_allocate:
+ mflr %r0
+ stw %r0,4(%r1)
+ stw %r7,-4(%r1)
+
+ sldi %r3,%r3,32
+ clrldi %r4,%r4,32
+ ori %r3,%r3,%r4
+ clrldi %r4,%r5,32
+ clrldi %r5,%r6,32
+
+ li %r11,217
+ hc
+ extsw %r3,%r3
+
+ lwz %r7,-4(%r1)
+ std %r4,0(%r7)
+
+ lwz %r0,4(%r1)
+ mtlr %r0
+ blr
+
+.global lv1_gpu_memory_allocate
+lv1_gpu_memory_allocate:
+ mflr %r0
+ stw %r0,4(%r1)
+ stw %r8,-4(%r1)
+ stw %r9,-8(%r1)
+
+ li %r11,214
+ hc
+ extsw %r3,%r3
+
+ lwz %r8,-4(%r1)
+ lwz %r9,-8(%r1)
+ std %r4,0(%r8)
+ std %r5,0(%r9)
+
+ lwz %r0,4(%r1)
+ mtlr %r0
+ blr
+
+.global lv1_net_control
+lv1_net_control:
+ mflr %r0
+ stw %r0,4(%r1)
+ stw %r9,-4(%r1)
+
+ li %r11,194
+ hc
+ extsw %r3,%r3
+
+ lwz %r8,-4(%r1)
+ std %r4,0(%r8)
+
+ lwz %r0,4(%r1)
+ mtlr %r0
+ blr
+
+.global lv1_setup_dma
+lv1_setup_dma:
+ mflr %r0
+ stw %r0,4(%r1)
+ stw %r3,-4(%r1)
+ stw %r4,-8(%r1)
+ stw %r5,-12(%r1)
+
+ lwz %r3,-4(%r1)
+ lwz %r4,-8(%r1)
+ lis %r5,0x0800 /* 128 MB */
+ li %r6,24 /* log2(IO_PAGESIZE) */
+ li %r7,0 /* flags */
+ li %r11,174 /* lv1_allocate_device_dma_region */
+ hc
+ extsw %r3,%r3
+ cmpdi %r3,0
+ bne 1f
+ std %r4,-24(%r1)
+
+ lwz %r3,-4(%r1)
+ lwz %r4,-8(%r1)
+ li %r5,0
+ ld %r6,-24(%r1)
+ lis %r7,0x0800 /* 128 MB */
+ lis %r8,0xf800 /* flags */
+ sldi %r8,%r8,32
+ li %r11,176 /* lv1_map_device_dma_region */
+ hc
+ extsw %r3,%r3
+
+ lwz %r9,-12(%r1)
+ ld %r6,-24(%r1)
+ std %r6,0(%r9)
+
+1: lwz %r0,4(%r1)
+ mtlr %r0
+ blr
+
diff --git a/sys/boot/powerpc/ps3/lv1call.h b/sys/boot/powerpc/ps3/lv1call.h
new file mode 100644
index 000000000000..26e6e14e8551
--- /dev/null
+++ b/sys/boot/powerpc/ps3/lv1call.h
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (C) 2010 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PS3_LV1CALL_H
+#define _PS3_LV1CALL_H
+
+#include <machine/pte.h>
+
+int lv1_get_physmem(uint64_t *maxmem);
+int lv1_setup_address_space(uint64_t *as_id, uint64_t *ptsize);
+int lv1_insert_pte(u_int ptegidx, struct lpte *pte, int lockflags);
+int lv1_panic(int reboot);
+
+#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET 0x0100
+#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x0101
+#define L1GPU_DISPLAY_SYNC_HSYNC 1
+#define L1GPU_DISPLAY_SYNC_VSYNC 2
+#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x0102
+
+int lv1_gpu_open(int);
+int lv1_gpu_context_attribute(int context, int op, int, int, int, int);
+int lv1_gpu_memory_allocate(int size, int, int, int, int, uint64_t *handle,
+ uint64_t *paddr);
+int lv1_gpu_context_allocate(uint64_t handle, int, uint64_t *context);
+
+int lv1_open_device(int, int, int /* 0 */);
+int lv1_close_device(int, int);
+int lv1_setup_dma(int, int, uint64_t *dmabase);
+
+#define GELIC_GET_MAC_ADDRESS 0x0001
+#define GELIC_GET_LINK_STATUS 0x0002
+#define GELIC_LINK_UP 0x0001
+#define GELIC_FULL_DUPLEX 0x0002
+#define GELIC_AUTO_NEG 0x0004
+#define GELIC_SPEED_10 0x0010
+#define GELIC_SPEED_100 0x0020
+#define GELIC_SPEED_1000 0x0040
+#define GELIC_GET_VLAN_ID 0x0004
+
+int lv1_net_init(int bus, int dev);
+int lv1_net_control(int bus, int dev, int, int, int, int, uint64_t *);
+int lv1_net_start_tx_dma(int bus, int dev, uint32_t addr, int);
+int lv1_net_start_rx_dma(int bus, int dev, uint32_t addr, int);
+int lv1_net_stop_tx_dma(int bus, int dev, int);
+int lv1_net_stop_rx_dma(int bus, int dev, int);
+
+#endif
+
diff --git a/sys/boot/powerpc/ps3/main.c b/sys/boot/powerpc/ps3/main.c
new file mode 100644
index 000000000000..22c51fad606f
--- /dev/null
+++ b/sys/boot/powerpc/ps3/main.c
@@ -0,0 +1,211 @@
+/*-
+ * Copyright (C) 2010 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <sys/param.h>
+
+#define _KERNEL
+#include <machine/cpufunc.h>
+
+#include "bootstrap.h"
+#include "lv1call.h"
+#include "ps3.h"
+
+struct arch_switch archsw;
+extern void *_end;
+
+extern char bootprog_name[];
+extern char bootprog_rev[];
+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;
+
+int
+main(void)
+{
+ uint64_t maxmem = 0;
+ void *heapbase;
+ int i;
+
+ lv1_get_physmem(&maxmem);
+
+ ps3mmu_init(maxmem);
+
+ /*
+ * Set up console.
+ */
+ cons_probe();
+
+ /*
+ * Set the heap to one page after the end of the loader.
+ */
+ heapbase = (void *)(maxmem - 0x80000);
+ setheap(heapbase, maxmem);
+
+ /*
+ * March through the device switch probing for things.
+ */
+ for (i = 0; devsw[i] != NULL; i++)
+ if (devsw[i]->dv_init != NULL)
+ (devsw[i]->dv_init)();
+
+ /*
+ * Get timebase at boot.
+ */
+ 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", ps3_setcurrdev, env_nounset);
+ env_setenv("loaddev", EV_VOLATILE, "net", env_noset, env_nounset);
+ setenv("LINES", "24", 1);
+ setenv("hw.platform", "ps3", 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
+delay(int usecs)
+{
+ uint64_t tb,ttb;
+ tb = mftb();
+
+ ttb = tb + (usecs * 1000 + ns_per_tick - 1) / ns_per_tick;
+ while (tb < ttb)
+ tb = mftb();
+}
+
+int
+getsecs()
+{
+ return ((mftb() - basetb)*ns_per_tick/1000000000);
+}
+
+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)
+{
+
+ return (0);
+}
+
diff --git a/sys/boot/powerpc/ps3/metadata.c b/sys/boot/powerpc/ps3/metadata.c
new file mode 100644
index 000000000000..0698cd19c651
--- /dev/null
+++ b/sys/boot/powerpc/ps3/metadata.c
@@ -0,0 +1,355 @@
+/*-
+ * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: FreeBSD: src/sys/boot/sparc64/loader/metadata.c,v 1.6
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <sys/param.h>
+#include <sys/reboot.h>
+#include <sys/linker.h>
+
+#include <machine/metadata.h>
+
+#include "bootstrap.h"
+
+/*
+ * Return a 'boothowto' value corresponding to the kernel arguments in
+ * (kargs) and any relevant environment variables.
+ */
+static struct
+{
+ const char *ev;
+ int mask;
+} howto_names[] = {
+ {"boot_askname", RB_ASKNAME},
+ {"boot_cdrom", RB_CDROM},
+ {"boot_ddb", RB_KDB},
+ {"boot_dfltroot", RB_DFLTROOT},
+ {"boot_gdb", RB_GDB},
+ {"boot_multicons", RB_MULTIPLE},
+ {"boot_mute", RB_MUTE},
+ {"boot_pause", RB_PAUSE},
+ {"boot_serial", RB_SERIAL},
+ {"boot_single", RB_SINGLE},
+ {"boot_verbose", RB_VERBOSE},
+ {NULL, 0}
+};
+
+int
+md_getboothowto(char *kargs)
+{
+ char *cp;
+ int howto;
+ int active;
+ int i;
+
+ /* Parse kargs */
+ howto = 0;
+ if (kargs != NULL) {
+ cp = kargs;
+ active = 0;
+ while (*cp != 0) {
+ if (!active && (*cp == '-')) {
+ active = 1;
+ } else if (active)
+ switch (*cp) {
+ case 'a':
+ howto |= RB_ASKNAME;
+ break;
+ case 'C':
+ howto |= RB_CDROM;
+ break;
+ case 'd':
+ howto |= RB_KDB;
+ break;
+ case 'D':
+ howto |= RB_MULTIPLE;
+ break;
+ case 'm':
+ howto |= RB_MUTE;
+ break;
+ case 'g':
+ howto |= RB_GDB;
+ break;
+ case 'h':
+ howto |= RB_SERIAL;
+ break;
+ case 'p':
+ howto |= RB_PAUSE;
+ break;
+ case 'r':
+ howto |= RB_DFLTROOT;
+ break;
+ case 's':
+ howto |= RB_SINGLE;
+ break;
+ case 'v':
+ howto |= RB_VERBOSE;
+ break;
+ default:
+ active = 0;
+ break;
+ }
+ cp++;
+ }
+ }
+ /* get equivalents from the environment */
+ for (i = 0; howto_names[i].ev != NULL; i++)
+ if (getenv(howto_names[i].ev) != NULL)
+ howto |= howto_names[i].mask;
+ if (!strcmp(getenv("console"), "comconsole"))
+ howto |= RB_SERIAL;
+ if (!strcmp(getenv("console"), "nullconsole"))
+ howto |= RB_MUTE;
+ return(howto);
+}
+
+/*
+ * Copy the environment into the load area starting at (addr).
+ * Each variable is formatted as <name>=<value>, with a single nul
+ * separating each variable, and a double nul terminating the environment.
+ */
+vm_offset_t
+md_copyenv(vm_offset_t addr)
+{
+ struct env_var *ep;
+
+ /* traverse the environment */
+ for (ep = environ; ep != NULL; ep = ep->ev_next) {
+ archsw.arch_copyin(ep->ev_name, addr, strlen(ep->ev_name));
+ addr += strlen(ep->ev_name);
+ archsw.arch_copyin("=", addr, 1);
+ addr++;
+ if (ep->ev_value != NULL) {
+ archsw.arch_copyin(ep->ev_value, addr, strlen(ep->ev_value));
+ addr += strlen(ep->ev_value);
+ }
+ archsw.arch_copyin("", addr, 1);
+ addr++;
+ }
+ archsw.arch_copyin("", addr, 1);
+ addr++;
+ return(addr);
+}
+
+/*
+ * Copy module-related data into the load area, where it can be
+ * used as a directory for loaded modules.
+ *
+ * Module data is presented in a self-describing format. Each datum
+ * is preceded by a 32-bit identifier and a 32-bit size field.
+ *
+ * Currently, the following data are saved:
+ *
+ * MOD_NAME (variable) module name (string)
+ * MOD_TYPE (variable) module type (string)
+ * MOD_ARGS (variable) module parameters (string)
+ * MOD_ADDR sizeof(vm_offset_t) module load address
+ * MOD_SIZE sizeof(size_t) module size
+ * MOD_METADATA (variable) type-specific metadata
+ */
+
+static int align;
+
+#define COPY32(v, a, c) { \
+ u_int32_t x = (v); \
+ if (c) \
+ archsw.arch_copyin(&x, a, sizeof(x)); \
+ a += sizeof(x); \
+}
+
+#define MOD_STR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(strlen(s) + 1, a, c) \
+ if (c) \
+ archsw.arch_copyin(s, a, strlen(s) + 1);\
+ a += roundup(strlen(s) + 1, align); \
+}
+
+#define MOD_NAME(a, s, c) MOD_STR(MODINFO_NAME, a, s, c)
+#define MOD_TYPE(a, s, c) MOD_STR(MODINFO_TYPE, a, s, c)
+#define MOD_ARGS(a, s, c) MOD_STR(MODINFO_ARGS, a, s, c)
+
+#define MOD_VAR(t, a, s, c) { \
+ COPY32(t, a, c); \
+ COPY32(sizeof(s), a, c); \
+ if (c) \
+ archsw.arch_copyin(&s, a, sizeof(s)); \
+ a += roundup(sizeof(s), align); \
+}
+
+#define MOD_ADDR(a, s, c) MOD_VAR(MODINFO_ADDR, a, s, c)
+#define MOD_SIZE(a, s, c) MOD_VAR(MODINFO_SIZE, a, s, c)
+
+#define MOD_METADATA(a, mm, c) { \
+ COPY32(MODINFO_METADATA | mm->md_type, a, c);\
+ COPY32(mm->md_size, a, c); \
+ if (c) \
+ archsw.arch_copyin(mm->md_data, a, mm->md_size);\
+ a += roundup(mm->md_size, align); \
+}
+
+#define MOD_END(a, c) { \
+ COPY32(MODINFO_END, a, c); \
+ COPY32(0, a, c); \
+}
+
+vm_offset_t
+md_copymodules(vm_offset_t addr, int kern64)
+{
+ struct preloaded_file *fp;
+ struct file_metadata *md;
+ uint64_t scratch64;
+ int c;
+
+ c = addr != 0;
+ /* start with the first module on the list, should be the kernel */
+ for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
+
+ MOD_NAME(addr, fp->f_name, c); /* this field must come first */
+ MOD_TYPE(addr, fp->f_type, c);
+ if (fp->f_args)
+ MOD_ARGS(addr, fp->f_args, c);
+ if (kern64) {
+ scratch64 = fp->f_addr;
+ MOD_ADDR(addr, scratch64, c);
+ scratch64 = fp->f_size;
+ MOD_SIZE(addr, scratch64, c);
+ } else {
+ MOD_ADDR(addr, fp->f_addr, c);
+ MOD_SIZE(addr, fp->f_size, c);
+ }
+ for (md = fp->f_metadata; md != NULL; md = md->md_next) {
+ if (!(md->md_type & MODINFOMD_NOCOPY)) {
+ MOD_METADATA(addr, md, c);
+ }
+ }
+ }
+ MOD_END(addr, c);
+ return(addr);
+}
+
+/*
+ * Load the information expected by a powerpc kernel.
+ *
+ * - The 'boothowto' argument is constructed
+ * - The 'bootdev' argument is constructed
+ * - The kernel environment is copied into kernel space.
+ * - Module metadata are formatted and placed in kernel space.
+ */
+int
+md_load_dual(char *args, vm_offset_t *modulep, int kern64)
+{
+ struct preloaded_file *kfp;
+ struct preloaded_file *xp;
+ struct file_metadata *md;
+ vm_offset_t kernend;
+ vm_offset_t addr;
+ vm_offset_t envp;
+ vm_offset_t size;
+ uint64_t scratch64;
+ char *rootdevname;
+ int howto;
+
+ align = kern64 ? 8 : 4;
+ howto = md_getboothowto(args);
+
+ /*
+ * Allow the environment variable 'rootdev' to override the supplied device
+ * This should perhaps go to MI code and/or have $rootdev tested/set by
+ * MI code before launching the kernel.
+ */
+ rootdevname = getenv("rootdev");
+ if (rootdevname == NULL)
+ rootdevname = getenv("currdev");
+ /* Try reading the /etc/fstab file to select the root device */
+ getrootmount(rootdevname);
+
+ /* find the last module in the chain */
+ addr = 0;
+ for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
+ if (addr < (xp->f_addr + xp->f_size))
+ addr = xp->f_addr + xp->f_size;
+ }
+ /* pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+ /* copy our environment */
+ envp = addr;
+ addr = md_copyenv(addr);
+
+ /* pad to a page boundary */
+ addr = roundup(addr, PAGE_SIZE);
+
+ kernend = 0;
+ kfp = file_findfile(NULL, kern64 ? "elf64 kernel" : "elf32 kernel");
+ if (kfp == NULL)
+ kfp = file_findfile(NULL, "elf kernel");
+ if (kfp == NULL)
+ panic("can't find kernel file");
+ file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
+ if (kern64) {
+ scratch64 = envp;
+ file_addmetadata(kfp, MODINFOMD_ENVP, sizeof scratch64, &scratch64);
+ scratch64 = kernend;
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof scratch64, &scratch64);
+ } else {
+ file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
+ file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
+ }
+
+ *modulep = addr;
+ size = md_copymodules(0, kern64);
+ kernend = roundup(addr + size, PAGE_SIZE);
+
+ md = file_findmetadata(kfp, MODINFOMD_KERNEND);
+ if (kern64) {
+ scratch64 = kernend;
+ bcopy(&scratch64, md->md_data, sizeof scratch64);
+ } else {
+ bcopy(&kernend, md->md_data, sizeof kernend);
+ }
+
+ (void)md_copymodules(addr, kern64);
+
+ return(0);
+}
+
+int
+md_load(char *args, vm_offset_t *modulep)
+{
+ return (md_load_dual(args, modulep, 0));
+}
+
+int
+md_load64(char *args, vm_offset_t *modulep)
+{
+ return (md_load_dual(args, modulep, 1));
+}
+
diff --git a/sys/boot/powerpc/ps3/ppc64_elf_freebsd.c b/sys/boot/powerpc/ps3/ppc64_elf_freebsd.c
new file mode 100644
index 000000000000..2892448f1204
--- /dev/null
+++ b/sys/boot/powerpc/ps3/ppc64_elf_freebsd.c
@@ -0,0 +1,98 @@
+/*-
+ * Copyright (c) 2001 Benno Rice <benno@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 64
+
+#include <sys/param.h>
+#include <sys/linker.h>
+
+#include <machine/metadata.h>
+#include <machine/elf.h>
+
+#include <stand.h>
+
+#include "bootstrap.h"
+
+extern char end[];
+extern vm_offset_t reloc; /* From <arch>/conf.c */
+
+int
+ppc64_elf_loadfile(char *filename, u_int64_t dest,
+ struct preloaded_file **result)
+{
+ int r;
+
+ r = __elfN(loadfile)(filename, dest, result);
+ if (r != 0)
+ return (r);
+
+ /*
+ * No need to sync the icache for modules: this will
+ * be done by the kernel after relocation.
+ */
+ if (!strcmp((*result)->f_type, "elf kernel"))
+ __syncicache((void *) (*result)->f_addr, (*result)->f_size);
+ return (0);
+}
+
+int
+ppc64_elf_exec(struct preloaded_file *fp)
+{
+ struct file_metadata *fmp;
+ vm_offset_t mdp;
+ Elf_Ehdr *e;
+ int error;
+ int (*entry)(u_long, u_long, u_long, void *, u_long);
+
+ if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) {
+ return(EFTYPE);
+ }
+ e = (Elf_Ehdr *)&fmp->md_data;
+
+ /* Handle function descriptor */
+ entry = (void *)(uintptr_t)(*(uint64_t *)e->e_entry);
+
+ if ((error = md_load64(fp->f_args, &mdp)) != 0)
+ return (error);
+
+ printf("Kernel entry at %p ...\n", entry);
+
+ dev_cleanup();
+
+ entry(0 /* FDT */, 0 /* Phys. mem offset */, 0 /* OF entry */,
+ (void *)mdp, sizeof(mdp));
+
+ panic("exec returned");
+}
+
+struct file_format ppc_elf64 =
+{
+ ppc64_elf_loadfile,
+ ppc64_elf_exec
+};
diff --git a/sys/boot/powerpc/ps3/ps3.h b/sys/boot/powerpc/ps3/ps3.h
new file mode 100644
index 000000000000..1a770029a5c0
--- /dev/null
+++ b/sys/boot/powerpc/ps3/ps3.h
@@ -0,0 +1,35 @@
+/*-
+ * Copyright (C) 2010 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PS3_H
+#define _PS3_H
+
+int ps3mmu_init(int maxmem);
+int ps3mmu_map(uint64_t va, uint64_t pa);
+void *ps3mmu_mapdev(uint64_t pa, size_t length);
+
+#endif
diff --git a/sys/boot/powerpc/ps3/ps3cons.c b/sys/boot/powerpc/ps3/ps3cons.c
new file mode 100644
index 000000000000..fa9ef321c62a
--- /dev/null
+++ b/sys/boot/powerpc/ps3/ps3cons.c
@@ -0,0 +1,173 @@
+/*-
+ * Copyright (C) 2010 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include "bootstrap.h"
+#include "font.h"
+#include "lv1call.h"
+#include "ps3.h"
+
+#define FONT_SIZE 14
+#define FONT dflt_font_14
+#define XMARGIN 40
+#define YMARGIN 30
+#define BG_COLOR 0x00000000
+#define FG_COLOR 0xffffffff
+
+#define FB_SIZE (16*1024*1024)
+uint64_t fb_paddr = 0;
+uint32_t *fb_vaddr;
+
+int fb_width, fb_height;
+int x, y;
+
+static void ps3cons_probe(struct console *cp);
+static int ps3cons_init(int arg);
+static void ps3cons_putchar(int c);
+static int ps3cons_getchar();
+static int ps3cons_poll();
+
+struct console ps3console = {
+ "ps3",
+ "Playstation 3 Framebuffer",
+ 0,
+ ps3cons_probe,
+ ps3cons_init,
+ ps3cons_putchar,
+ ps3cons_getchar,
+ ps3cons_poll,
+};
+
+static void
+ps3cons_probe(struct console *cp)
+{
+ /* XXX: Get from HV */
+ fb_width = 720;
+ fb_height = 480;
+
+ cp->c_flags |= C_PRESENTIN|C_PRESENTOUT;
+}
+
+static int
+ps3cons_init(int arg)
+{
+ uint64_t fbhandle, fbcontext;
+ int i;
+
+ lv1_gpu_open(0);
+ lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET,
+ 0,0,0,0);
+ lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_MODE_SET,
+ 0,0,1,0);
+ lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
+ 0,L1GPU_DISPLAY_SYNC_VSYNC,0,0);
+ lv1_gpu_context_attribute(0, L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
+ 1,L1GPU_DISPLAY_SYNC_VSYNC,0,0);
+ lv1_gpu_memory_allocate(FB_SIZE, 0, 0, 0, 0, &fbhandle, &fb_paddr);
+ lv1_gpu_context_allocate(fbhandle, 0, &fbcontext);
+
+ lv1_gpu_context_attribute(fbcontext,
+ L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 0, 0, 0, 0);
+ lv1_gpu_context_attribute(fbcontext,
+ L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 1, 0, 0, 0);
+
+ fb_vaddr = ps3mmu_mapdev(fb_paddr, FB_SIZE);
+
+ x = y = 0;
+
+ /* Blank console */
+ for (i = 0; i < fb_width*fb_height; i++)
+ fb_vaddr[i] = BG_COLOR;
+
+ return (0);
+}
+
+static void
+ps3cons_putchar(int c)
+{
+ uint32_t fg, bg;
+ uint32_t *addr;
+ int i, j, k;
+ u_char *p;
+
+ fg = FG_COLOR;
+ bg = BG_COLOR;
+
+ switch (c) {
+ case '\0':
+ break;
+ case '\r':
+ x = 0;
+ break;
+ case '\n':
+ y += FONT_SIZE;
+ break;
+ case '\b':
+ x = max(0, x - 8);
+ break;
+ default:
+ /* Wrap long lines */
+ if (x + XMARGIN + FONT_SIZE > fb_width - XMARGIN) {
+ y += FONT_SIZE;
+ x = 0;
+ }
+
+ if (y + YMARGIN + FONT_SIZE > fb_height - YMARGIN)
+ y = 0;
+
+ addr = fb_vaddr + (y + YMARGIN)*fb_width + (x + XMARGIN);
+ p = FONT + c*FONT_SIZE;
+
+ for (i = 0; i < FONT_SIZE; i++) {
+ for (j = 0, k = 7; j < 8; j++, k--) {
+ if ((p[i] & (1 << k)) == 0)
+ *(addr + j) = bg;
+ else
+ *(addr + j) = fg;
+ }
+
+ addr += fb_width;
+ }
+
+ x += 8;
+ break;
+ }
+}
+
+static int
+ps3cons_getchar()
+{
+ return (-1);
+}
+
+static int
+ps3cons_poll()
+{
+ return (0);
+}
+
diff --git a/sys/boot/powerpc/ps3/ps3mmu.c b/sys/boot/powerpc/ps3/ps3mmu.c
new file mode 100644
index 000000000000..a7005fb9e557
--- /dev/null
+++ b/sys/boot/powerpc/ps3/ps3mmu.c
@@ -0,0 +1,120 @@
+/*-
+ * Copyright (C) 2010 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stand.h>
+#include <stdint.h>
+
+#define _KERNEL
+#include <machine/cpufunc.h>
+#include <machine/psl.h>
+#include <machine/pte.h>
+#include <machine/slb.h>
+#include <machine/param.h>
+
+#include "bootstrap.h"
+#include "lv1call.h"
+#include "ps3.h"
+
+register_t pteg_count, pteg_mask;
+uint64_t as_id;
+uint64_t virtual_avail;
+
+int
+ps3mmu_map(uint64_t va, uint64_t pa)
+{
+ struct lpte pt;
+ int shift;
+ uint64_t vsid, ptegidx;
+
+ if (pa < 0x8000000) { /* Phys mem? */
+ pt.pte_hi = LPTE_BIG;
+ pt.pte_lo = LPTE_M;
+ shift = 24;
+ vsid = 0;
+ } else {
+ pt.pte_hi = 0;
+ pt.pte_lo = LPTE_I | LPTE_G | LPTE_M | LPTE_NOEXEC;
+ shift = ADDR_PIDX_SHFT;
+ vsid = 1;
+ }
+
+ pt.pte_hi |= (vsid << LPTE_VSID_SHIFT) |
+ (((uint64_t)(va & ADDR_PIDX) >> ADDR_API_SHFT64) & LPTE_API);
+ pt.pte_lo |= pa;
+ ptegidx = vsid ^ (((uint64_t)va & ADDR_PIDX) >> shift);
+
+ pt.pte_hi |= LPTE_LOCKED | LPTE_VALID;
+ ptegidx &= pteg_mask;
+
+ return (lv1_insert_pte(ptegidx, &pt, LPTE_LOCKED));
+}
+
+void *
+ps3mmu_mapdev(uint64_t pa, size_t length)
+{
+ uint64_t spa;
+ void *mapstart;
+ int err;
+
+ mapstart = (void *)(uintptr_t)virtual_avail;
+
+ for (spa = pa; spa < pa + length; spa += PAGE_SIZE) {
+ err = ps3mmu_map(virtual_avail, spa);
+ virtual_avail += PAGE_SIZE;
+ if (err != 0)
+ return (NULL);
+ }
+
+ return (mapstart);
+}
+
+int
+ps3mmu_init(int maxmem)
+{
+ uint64_t ptsize;
+ int i;
+
+ i = lv1_setup_address_space(&as_id, &ptsize);
+ pteg_count = ptsize / sizeof(struct lpteg);
+ pteg_mask = pteg_count - 1;
+
+ for (i = 0; i < maxmem; i += 16*1024*1024)
+ ps3mmu_map(i,i);
+
+ virtual_avail = 0x10000000;
+
+ __asm __volatile ("slbia; slbmte %0, %1; slbmte %2,%3" ::
+ "r"((0 << SLBV_VSID_SHIFT) | SLBV_L), "r"(0 | SLBE_VALID),
+ "r"(1 << SLBV_VSID_SHIFT),
+ "r"((1 << SLBE_ESID_SHIFT) | SLBE_VALID | 1));
+
+ mtmsr(mfmsr() | PSL_IR | PSL_DR | PSL_RI | PSL_ME);
+
+ return (0);
+}
+
diff --git a/sys/boot/powerpc/ps3/ps3net.c b/sys/boot/powerpc/ps3/ps3net.c
new file mode 100644
index 000000000000..142eab8243a6
--- /dev/null
+++ b/sys/boot/powerpc/ps3/ps3net.c
@@ -0,0 +1,278 @@
+/*-
+ * Copyright (C) 2010 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+
+#define _KERNEL
+#include <machine/cpufunc.h>
+
+#include <stand.h>
+#include <net.h>
+#include <netif.h>
+#include "bootstrap.h"
+#include "lv1call.h"
+#include "ps3.h"
+
+#define GELIC_DESCR_OWNED 0xa0000000
+#define GELIC_CMDSTAT_NOIPSEC 0x00080000
+#define GELIC_CMDSTAT_LAST 0x00040000
+#define GELIC_RXERRORS 0x7def8000
+
+#define GELIC_POLL_PERIOD 100 /* microseconds */
+
+static int ps3net_probe(struct netif *, void *);
+static int ps3net_match(struct netif *, void *);
+static void ps3net_init(struct iodesc *, void *);
+static int ps3net_get(struct iodesc *, void *, size_t, time_t);
+static int ps3net_put(struct iodesc *, void *, size_t);
+static void ps3net_end(struct netif *);
+
+struct netif_stats ps3net_stats[1];
+struct netif_dif ps3net_ifs[] = {{0, 1, ps3net_stats, 0}};
+
+/* XXX: Get from firmware, not hardcoding */
+static int busid = 1;
+static int devid = 0;
+static int vlan;
+static uint64_t dma_base;
+
+struct gelic_dmadesc {
+ uint32_t paddr;
+ uint32_t len;
+ uint32_t next;
+ uint32_t cmd_stat;
+ uint32_t result_size;
+ uint32_t valid_size;
+ uint32_t data_stat;
+ uint32_t rxerror;
+};
+
+struct netif_driver ps3net = {
+ "net",
+ ps3net_match,
+ ps3net_probe,
+ ps3net_init,
+ ps3net_get,
+ ps3net_put,
+ ps3net_end,
+ ps3net_ifs, 1
+};
+
+static int
+ps3net_match(struct netif *nif, void *machdep_hint)
+{
+ return (1);
+}
+
+static int
+ps3net_probe(struct netif *nif, void *machdep_hint)
+{
+ return (0);
+}
+
+static int
+ps3net_put(struct iodesc *desc, void *pkt, size_t len)
+{
+ volatile static struct gelic_dmadesc txdesc __aligned(32);
+ volatile static char txbuf[1536] __aligned(128);
+ size_t sendlen;
+ int err;
+
+#if defined(NETIF_DEBUG)
+ struct ether_header *eh;
+
+ printf("net_put: desc %p, pkt %p, len %d\n", desc, pkt, len);
+ eh = pkt;
+ printf("dst: %s ", ether_sprintf(eh->ether_dhost));
+ printf("src: %s ", ether_sprintf(eh->ether_shost));
+ printf("type: 0x%x\n", eh->ether_type & 0xffff);
+#endif
+
+ while (txdesc.cmd_stat & GELIC_DESCR_OWNED) {
+ printf("Stalled XMIT!\n");
+ delay(10);
+ }
+
+ /*
+ * We must add 4 extra bytes to this packet to store the destination
+ * VLAN.
+ */
+ memcpy(txbuf, pkt, 12);
+ sendlen = 12;
+
+ if (vlan >= 0) {
+ sendlen += 4;
+ ((uint8_t *)txbuf)[12] = 0x81;
+ ((uint8_t *)txbuf)[13] = 0x00;
+ ((uint8_t *)txbuf)[14] = vlan >> 8;
+ ((uint8_t *)txbuf)[15] = vlan & 0xff;
+ }
+ memcpy((void *)txbuf + sendlen, pkt + 12, len - 12);
+ sendlen += len - 12;
+
+ bzero(&txdesc, sizeof(txdesc));
+ txdesc.paddr = dma_base + (uint32_t)txbuf;
+ txdesc.len = sendlen;
+ txdesc.cmd_stat = GELIC_CMDSTAT_NOIPSEC | GELIC_CMDSTAT_LAST |
+ GELIC_DESCR_OWNED;
+
+ powerpc_sync();
+
+ do {
+ err = lv1_net_start_tx_dma(busid, devid,
+ dma_base + (uint32_t)&txdesc, 0);
+ delay(1);
+ if (err != 0)
+ printf("TX Error: %d\n",err);
+ } while (err != 0);
+
+ return (len);
+}
+
+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 char rxbuf[1536] __aligned(128);
+ int err = 0;
+
+ if (len == 0)
+ goto restartdma;
+
+ timeout *= 1000000; /* convert to microseconds */
+ while (rxdesc.cmd_stat & GELIC_DESCR_OWNED) {
+ if (timeout < GELIC_POLL_PERIOD)
+ return (ETIMEDOUT);
+ delay(GELIC_POLL_PERIOD);
+ timeout -= GELIC_POLL_PERIOD;
+ }
+
+ delay(200);
+ if (rxdesc.rxerror & GELIC_RXERRORS) {
+ err = -1;
+ goto restartdma;
+ }
+
+ /*
+ * Copy the packet to the receive buffer, leaving out the
+ * 2 byte VLAN header.
+ */
+ len = min(len, rxdesc.valid_size - 2);
+ memcpy(pkt, (u_char *)rxbuf + 2, len);
+ err = len;
+
+#if defined(NETIF_DEBUG)
+{
+ struct ether_header *eh;
+
+ printf("net_get: desc %p, pkt %p, len %d\n", desc, pkt, len);
+ eh = pkt;
+ printf("dst: %s ", ether_sprintf(eh->ether_dhost));
+ printf("src: %s ", ether_sprintf(eh->ether_shost));
+ printf("type: 0x%x\n", eh->ether_type & 0xffff);
+}
+#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);
+
+ return (err);
+}
+
+static void
+ps3net_init(struct iodesc *desc, void *machdep_hint)
+{
+ uint64_t mac, val;
+ int i,err;
+
+ err = lv1_open_device(busid, devid, 0);
+
+ lv1_net_stop_tx_dma(busid, devid, 0);
+ lv1_net_stop_rx_dma(busid, devid, 0);
+
+ /*
+ * Wait for link to come up
+ */
+
+ for (i = 0; i < 1000; i++) {
+ lv1_net_control(busid, devid, GELIC_GET_LINK_STATUS, 2, 0,
+ 0, &val);
+ if (val & GELIC_LINK_UP)
+ break;
+ delay(500);
+ }
+
+ /*
+ * Set up DMA IOMMU entries
+ */
+
+ err = lv1_setup_dma(busid, devid, &dma_base);
+
+ /*
+ * Get MAC address and VLAN IDs
+ */
+
+ lv1_net_control(busid, devid, GELIC_GET_MAC_ADDRESS, 0, 0, 0, &mac);
+ bcopy(&((uint8_t *)&mac)[2], desc->myea, sizeof(desc->myea));
+
+ vlan = -1;
+ err = lv1_net_control(busid, devid, GELIC_GET_VLAN_ID, 2, 0,
+ 0, &val);
+ if (err == 0)
+ vlan = val;
+
+ /*
+ * Start RX DMA engine
+ */
+
+ ps3net_get(NULL, NULL, 0, 0);
+}
+
+static void
+ps3net_end(struct netif *nif)
+{
+ lv1_close_device(busid, devid);
+}
+
diff --git a/sys/boot/powerpc/ps3/start.S b/sys/boot/powerpc/ps3/start.S
new file mode 100644
index 000000000000..92b02f048cfa
--- /dev/null
+++ b/sys/boot/powerpc/ps3/start.S
@@ -0,0 +1,167 @@
+/*-
+ * Copyright (C) 2010 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <machine/trap_aim.h>
+
+/*
+ * KBoot and simulators will start this program from the _start symbol, with
+ * r3 pointing to a flattened device tree (kexec), r4 the physical address
+ * at which we were loaded, and r5 0 (kexec) or a pointer to Open Firmware
+ * (simulator). If r4 is non-zero, the first order of business is relocating
+ * ourselves to 0. In the kboot case, the PPE secondary thread will enter
+ * at 0x60.
+ *
+ * If started directly by the LV1 hypervisor, we are loaded to address 0
+ * and execution on both threads begins at 0x100 (EXC_RST).
+ */
+
+#define CACHELINE_SIZE 128
+#define SPR_CTRL 136
+
+/* KBoot thread 0 entry -- do relocation, then jump to main */
+.global _start
+_start:
+ mfmsr %r31
+ clrldi %r31,%r31,1
+ mtmsrd %r31
+ isync
+ cmpwi %r4,0
+ bne relocate_self
+relocated_start:
+ lis %r1,0x100
+ bl main
+
+. = 0x40
+.global secondary_spin_sem
+secondary_spin_sem:
+ .long 0
+
+. = 0x60
+thread1_start_kboot:
+ mfmsr %r31
+ clrldi %r31,%r31,1
+ mtmsrd %r31
+ isync
+
+ ba thread1_start /* kboot copies the first 256 bytes to
+ * address 0, so we are safe to jump
+ * (and stay) there */
+
+thread1_start:
+ li %r3,secondary_spin_sem@l
+1: lwz %r1,0(%r3) /* Spin on SECONDARY_SPIN_SEM_ADDRESS */
+ cmpwi %r1,0
+ 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
+ isync
+ sync
+ ba 0x100 /* Jump to the reset vector */
+
+. = EXC_RST
+exc_rst:
+ mfmsr %r31
+ clrldi %r31,%r31,1
+ mtmsrd %r31
+ isync
+
+ mfspr %r3,SPR_CTRL
+ /* The first two bits of r0 are 01 (thread 1) or 10 (thread 0) */
+ cntlzw %r3,%r3 /* Now 0 for thread 0, 1 for thread 1 */
+
+ 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,%r5,1; \
+ mtmsrd %r6; \
+ 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,0x100 /* r5: dest address */
+1: add %r6,%r4,%r5 /* r6: source address */
+ ld %r7,0(%r6)
+ std %r7,0(%r5)
+ 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,0x100
+2: dcbst 0,%r5
+ sync
+ icbi 0,%r5
+ sync
+ isync
+ cmpw %r5,%r8
+ addi %r5,%r5,CACHELINE_SIZE
+ blt 2b
+
+ /* All done: absolute jump to relocated entry point */
+ ba relocated_start
+
diff --git a/sys/boot/powerpc/ps3/version b/sys/boot/powerpc/ps3/version
new file mode 100644
index 000000000000..fa0b18566fe4
--- /dev/null
+++ b/sys/boot/powerpc/ps3/version
@@ -0,0 +1,6 @@
+$FreeBSD$
+
+NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
+file is important. Make sure the current version number is on line 6.
+
+0.1: Initial PS3/PowerPC version.
diff --git a/sys/boot/zfs/Makefile b/sys/boot/zfs/Makefile
index 91525d77c8d0..a6fba3a85728 100644
--- a/sys/boot/zfs/Makefile
+++ b/sys/boot/zfs/Makefile
@@ -13,10 +13,7 @@ CFLAGS+= -I${.CURDIR}/../../cddl/boot/zfs
CFLAGS+= -ffreestanding
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
CFLAGS+= -mpreferred-stack-boundary=2
-CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2
-.endif
-.if ${MACHINE_CPUARCH} == "i386"
-CFLAGS+= -mno-sse3
+CFLAGS+= -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -msoft-float
.endif
.if ${MACHINE_CPUARCH} == "powerpc" || ${MACHINE_CPUARCH} == "arm"
CFLAGS+= -msoft-float