Garbage-collect loader.ps3. It is currently disconnected from the build and

is superseded by either direct loading of the kernel by petitboot (soon to
become the installer default) or loader.kboot.
This commit is contained in:
Nathan Whitehorn 2017-12-30 20:27:13 +00:00
parent 3fca788024
commit 3159111ed6
23 changed files with 0 additions and 3510 deletions

View File

@ -1,47 +0,0 @@
# $FreeBSD$
LOADER_UFS_SUPPORT?= yes
LOADER_CD9660_SUPPORT?= yes
LOADER_EXT2FS_SUPPORT?= yes
LOADER_NET_SUPPORT?= yes
LOADER_NFS_SUPPORT?= yes
LOADER_TFTP_SUPPORT?= no
LOADER_GZIP_SUPPORT?= yes
LOADER_BZIP2_SUPPORT?= no
.include <bsd.init.mk>
MK_SSP= no
MAN=
PROG= loader.ps3
NEWVERSWHAT= "Playstation 3 loader" ${MACHINE_ARCH}
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 ps3repo.c \
ps3stor.c ps3disk.c ps3cdrom.c
SRCS+= ucmpdi2.c
CFLAGS+= -mcpu=powerpc64
# Always add MI sources
.include "${BOOTSRC}/loader.mk"
.PATH: ${SYSDIR}/libkern
CFLAGS+= -Wall -DAIM
# load address. set in linker script
RELOC?= 0x0
CFLAGS+= -DRELOC=${RELOC}
LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc
DPADD= ${LIBFICL} ${LIBOFW} ${LIBSA}
LDADD= ${LIBFICL} ${LIBOFW} ${LIBSA}
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
.include <bsd.prog.mk>

View File

@ -1,123 +0,0 @@
/*-
* 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
extern struct devsw ps3disk;
extern struct devsw ps3cdrom;
/*
* 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_CD9660_SUPPORT)
&ps3cdrom,
#endif
#if defined(LOADER_DISK_SUPPORT)
&ps3disk,
#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;

View File

@ -1,238 +0,0 @@
/*-
* 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"
#include "ps3.h"
#include "ps3devdesc.h"
static int ps3_parsedev(struct ps3_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 ps3_devdesc **dev = (struct ps3_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 ps3_devdesc **dev, const char *devspec, const char **path)
{
struct ps3_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 ps3_devdesc));
err = 0;
np = (devspec + strlen(dv->dv_name));
switch(dv->dv_type) {
case DEVT_NONE:
break;
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;
case DEVT_NET:
case DEVT_CD:
/*
* 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 ps3_devdesc *dev = (struct ps3_devdesc *)vdev;
char *cp;
static char buf[128];
switch(dev->d_type) {
case DEVT_NONE:
strcpy(buf, "(no device)");
break;
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;
case DEVT_NET:
case DEVT_CD:
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 ps3_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);
}

View File

@ -1,111 +0,0 @@
/* $FreeBSD$ */
OUTPUT_FORMAT("elf32-powerpc-freebsd", "elf32-powerpc-freebsd",
"elf32-powerpc-freebsd")
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 = .);
}

View File

@ -1,346 +0,0 @@
/*-
* Copyright (C) 2010 Nathan Whitehorn
* Copyright (C) 2011 glevand (geoffrey.levand@mail.ru)
* 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
or %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
.global lv1_get_repository_node_value
lv1_get_repository_node_value:
mflr %r0
stw %r0,4(%r1)
sldi %r3,%r3,32
clrldi %r4,%r4,32
or %r3,%r3,%r4
sldi %r4,%r5,32
clrldi %r5,%r6,32
or %r4,%r4,%r5
sldi %r5,%r7,32
clrldi %r6,%r8,32
or %r5,%r5,%r6
sldi %r6,%r9,32
clrldi %r7,%r10,32
or %r6,%r6,%r7
lwz %r7,8(%r1)
lwz %r8,12(%r1)
sldi %r7,%r7,32
or %r7,%r7,%r8
li %r11,91
hc
extsw %r3,%r3
lwz %r6,16(%r1)
std %r4,0(%r6)
lwz %r6,20(%r1)
std %r5,0(%r6)
lwz %r0,4(%r1)
mtlr %r0
blr
.global lv1_storage_read
lv1_storage_read:
mflr %r0
stw %r0,4(%r1)
sldi %r3,%r3,32
clrldi %r4,%r4,32
or %r3,%r3,%r4
sldi %r4,%r5,32
clrldi %r5,%r6,32
or %r4,%r4,%r5
sldi %r5,%r7,32
clrldi %r6,%r8,32
or %r5,%r5,%r6
sldi %r6,%r9,32
clrldi %r7,%r10,32
or %r6,%r6,%r7
ld %r7,8(%r1)
ld %r8,16(%r1)
li %r11,245
hc
extsw %r3,%r3
lwz %r5,24(%r1)
std %r4,0(%r5)
lwz %r0,4(%r1)
mtlr %r0
blr
.global lv1_storage_check_async_status
lv1_storage_check_async_status:
mflr %r0
stw %r0,4(%r1)
stw %r7,-4(%r1)
sldi %r3,%r3,32
clrldi %r4,%r4,32
or %r3,%r3,%r4
sldi %r4,%r5,32
clrldi %r5,%r6,32
or %r4,%r4,%r5
li %r11,254
hc
extsw %r3,%r3
lwz %r5,-4(%r1)
std %r4,0(%r5)
lwz %r0,4(%r1)
mtlr %r0
blr

View File

@ -1,80 +0,0 @@
/*-
* 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);
int lv1_get_repository_node_value(uint64_t lpar_id, uint64_t n1, uint64_t n2,
uint64_t n3, uint64_t n4, uint64_t *v1, uint64_t *v2);
int lv1_storage_read(uint64_t dev_id, uint64_t region_id, uint64_t start_sector,
uint64_t sector_count, uint64_t flags, uint64_t buf, uint64_t *tag);
int lv1_storage_check_async_status(uint64_t dev_id, uint64_t tag,
uint64_t *status);
#endif

View File

@ -1,248 +0,0 @@
/*-
* Copyright (C) 2010 Nathan Whitehorn
* Copyright (C) 2011 glevand (geoffrey.levand@mail.ru)
* 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"
#include "ps3devdesc.h"
struct arch_switch archsw;
extern void *_end;
extern char bootprog_info[];
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, err;
struct ps3_devdesc currdev;
struct open_file f;
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) {
err = (devsw[i]->dv_init)();
if (err) {
printf("\n%s: initialization failed err=%d\n",
devsw[i]->dv_name, err);
continue;
}
}
currdev.d_dev = devsw[i];
currdev.d_type = currdev.d_dev->dv_type;
if (strcmp(devsw[i]->dv_name, "cd") == 0) {
f.f_devdata = &currdev;
currdev.d_unit = 0;
if (devsw[i]->dv_open(&f, &currdev) == 0)
break;
}
if (strcmp(devsw[i]->dv_name, "disk") == 0) {
f.f_devdata = &currdev;
currdev.d_unit = 3;
currdev.d_disk.pnum = 1;
currdev.d_disk.ptype = PTYPE_GPT;
if (devsw[i]->dv_open(&f, &currdev) == 0)
break;
}
if (strcmp(devsw[i]->dv_name, "net") == 0)
break;
}
if (devsw[i] == NULL)
panic("No boot device found!");
else
printf("Boot device: %s\n", devsw[i]->dv_name);
/*
* 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%s", bootprog_info);
printf("Memory: %lldKB\n", maxmem / 1024);
env_setenv("currdev", EV_VOLATILE, ps3_fmtdev(&currdev),
ps3_setcurrdev, env_nounset);
env_setenv("loaddev", EV_VOLATILE, ps3_fmtdev(&currdev), 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 + howmany(usecs * 1000, ns_per_tick);
while (tb < ttb)
tb = mftb();
}
time_t
getsecs(void)
{
return ((time_t)((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);
}

View File

@ -1,333 +0,0 @@
/*-
* 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 <sys/boot.h>
#include <machine/metadata.h>
#include "bootstrap.h"
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));
}

View File

@ -1,101 +0,0 @@
/*-
* 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 for ELFv1 kernels */
if ((e->e_flags & 3) == 2)
entry = e->e_entry;
else
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, 0xfb5d104d);
panic("exec returned");
}
struct file_format ppc_elf64 =
{
ppc64_elf_loadfile,
ppc64_elf_exec
};

View File

@ -1,35 +0,0 @@
/*-
* 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

View File

@ -1,41 +0,0 @@
/*-
* Copyright (C) 2011 glevand (geoffrey.levand@mail.ru)
* 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_BUS_H
#define _PS3_BUS_H
enum {
PS3_BUS_TYPE_STOR = 5,
};
enum {
PS3_DEV_TYPE_STOR_DISK = 0,
PS3_DEV_TYPE_STOR_CDROM = 5,
PS3_DEV_TYPE_STOR_FLASH = 14,
};
#endif

View File

@ -1,156 +0,0 @@
/*-
* Copyright (C) 2011 glevand <geoffrey.levand@mail.ru>
* 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 <sys/param.h>
#include <sys/endian.h>
#include <machine/stdarg.h>
#include <stand.h>
#include "bootstrap.h"
#include "ps3bus.h"
#include "ps3devdesc.h"
#include "ps3stor.h"
#define dev_printf(dev, fmt, args...) \
printf("%s%d: " fmt "\n", dev->d_dev->dv_name, dev->d_unit, ##args)
#ifdef CD_DEBUG
#define DEBUG(fmt, args...) printf("%s:%d: " fmt "\n", __func__, __LINE__, ##args)
#else
#define DEBUG(fmt, args...)
#endif
static int ps3cdrom_init(void);
static int ps3cdrom_strategy(void *devdata, int flag, daddr_t dblk,
size_t size, char *buf, size_t *rsize);
static int ps3cdrom_open(struct open_file *f, ...);
static int ps3cdrom_close(struct open_file *f);
static int ps3cdrom_print(int verbose);
struct devsw ps3cdrom = {
"cd",
DEVT_CD,
ps3cdrom_init,
ps3cdrom_strategy,
ps3cdrom_open,
ps3cdrom_close,
noioctl,
ps3cdrom_print,
};
static struct ps3_stordev stor_dev;
static int ps3cdrom_init(void)
{
int err;
err = ps3stor_setup(&stor_dev, PS3_DEV_TYPE_STOR_CDROM);
if (err)
return err;
return 0;
}
static int ps3cdrom_strategy(void *devdata, int flag, daddr_t dblk,
size_t size, char *buf, size_t *rsize)
{
struct ps3_devdesc *dev = (struct ps3_devdesc *) devdata;
int err;
DEBUG("d_unit=%u dblk=%llu size=%u", dev->d_unit, dblk, size);
flag &= F_MASK;
if (flag != F_READ) {
dev_printf(dev, "write operation is not supported!");
return EROFS;
}
if (dblk % (stor_dev.sd_blksize / DEV_BSIZE) != 0)
return EINVAL;
dblk /= (stor_dev.sd_blksize / DEV_BSIZE);
if (size % stor_dev.sd_blksize) {
dev_printf(dev,
"size=%u is not multiple of device block size=%llu", size,
stor_dev.sd_blksize);
return EINVAL;
}
if (rsize)
*rsize = 0;
err = ps3stor_read_sectors(&stor_dev, dev->d_unit, dblk,
size / stor_dev.sd_blksize, 0, buf);
if (!err && rsize)
*rsize = size;
if (err)
dev_printf(dev,
"read operation failed dblk=%llu size=%d err=%d", dblk,
size, err);
return err;
}
static int ps3cdrom_open(struct open_file *f, ...)
{
char buf[2048];
va_list ap;
struct ps3_devdesc *dev;
int err;
va_start(ap, f);
dev = va_arg(ap, struct ps3_devdesc *);
va_end(ap);
if (dev->d_unit > 0) {
dev_printf(dev, "attempt to open nonexistent disk");
return ENXIO;
}
err = ps3stor_read_sectors(&stor_dev, dev->d_unit, 16, 1, 0, buf);
if (err)
return EIO;
/* Do not attach if not ISO9660 (workaround for buggy firmware) */
if (memcmp(buf, "\001CD001", 6) != 0)
return EIO;
return 0;
}
static int ps3cdrom_close(struct open_file *f)
{
return 0;
}
static int ps3cdrom_print(int verbose)
{
return (0);
}

View File

@ -1,173 +0,0 @@
/*-
* 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);
}

View File

@ -1,53 +0,0 @@
/*-
* Copyright (C) 2000 Benno Rice.
* Copyright (C) 2007 Semihalf, Rafal Jaworowski <raj@semihalf.com>
* Copyright (C) 2011 glevand (geoffrey.levand@mail.ru)
* 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_DEV_DESC_H
#define _PS3_DEV_DESC_H
/* Note: Must match the 'struct devdesc' in bootstrap.h */
struct ps3_devdesc {
struct devsw *d_dev;
int d_type;
int d_unit;
union {
struct {
void *data;
int pnum;
int ptype;
} disk;
} d_kind;
};
#define d_disk d_kind.disk
#define PTYPE_BSDLABEL 1
#define PTYPE_GPT 2
#endif

View File

@ -1,315 +0,0 @@
/*-
* Copyright (C) 2008 Semihalf, Rafal Jaworowski
* Copyright (C) 2009 Semihalf, Piotr Ziecik
* Copyright (C) 2011 glevand (geoffrey.levand@mail.ru)
* 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 <sys/endian.h>
#include <machine/stdarg.h>
#include <stand.h>
#include <uuid.h>
#define FSTYPENAMES
#include <sys/disklabel.h>
#include <sys/diskmbr.h>
#include <sys/gpt.h>
#include "bootstrap.h"
#include "ps3bus.h"
#include "ps3devdesc.h"
#include "ps3stor.h"
#define dev_printf(dev, fmt, args...) \
printf("%s%d: " fmt "\n" , dev->d_dev->dv_name, dev->d_unit, ##args)
#ifdef DISK_DEBUG
#define DEBUG(fmt, args...) printf("%s:%d: " fmt "\n" , __func__ , __LINE__, ##args)
#else
#define DEBUG(fmt, args...)
#endif
struct open_dev;
static int ps3disk_open_gpt(struct ps3_devdesc *dev, struct open_dev *od);
static void ps3disk_uuid_letoh(uuid_t *uuid);
static int ps3disk_init(void);
static int ps3disk_strategy(void *devdata, int flag, daddr_t dblk,
size_t size, char *buf, size_t *rsize);
static int ps3disk_open(struct open_file *f, ...);
static int ps3disk_close(struct open_file *f);
static int ps3disk_print(int verbose);
struct devsw ps3disk = {
"disk",
DEVT_DISK,
ps3disk_init,
ps3disk_strategy,
ps3disk_open,
ps3disk_close,
noioctl,
ps3disk_print,
};
struct gpt_part {
int gp_index;
uuid_t gp_type;
uint64_t gp_start;
uint64_t gp_end;
};
struct open_dev {
uint64_t od_start;
union {
struct {
int nparts;
struct gpt_part *parts;
} gpt;
} od_kind;
};
#define od_gpt_nparts od_kind.gpt.nparts
#define od_gpt_parts od_kind.gpt.parts
static struct ps3_stordev stor_dev;
static int ps3disk_init(void)
{
int err;
err = ps3stor_setup(&stor_dev, PS3_DEV_TYPE_STOR_DISK);
if (err)
return err;
return 0;
}
static int ps3disk_strategy(void *devdata, int flag, daddr_t dblk,
size_t size, char *buf, size_t *rsize)
{
struct ps3_devdesc *dev = (struct ps3_devdesc *) devdata;
struct open_dev *od = (struct open_dev *) dev->d_disk.data;
int err;
flag &= F_MASK;
if (flag != F_READ) {
dev_printf(dev, "write operation is not supported!\n");
return EROFS;
}
if (size % stor_dev.sd_blksize) {
dev_printf(dev, "size=%u is not multiple of device block size=%llu\n",
size, stor_dev.sd_blksize);
return EIO;
}
if (rsize)
*rsize = 0;
err = ps3stor_read_sectors(&stor_dev, dev->d_unit, od->od_start + dblk,
size / stor_dev.sd_blksize, 0, buf);
if (!err && rsize)
*rsize = size;
if (err)
dev_printf(dev, "read operation failed dblk=%llu size=%d err=%d\n",
dblk, size, err);
return err;
}
static int ps3disk_open(struct open_file *f, ...)
{
va_list ap;
struct ps3_devdesc *dev;
struct open_dev *od;
int err;
va_start(ap, f);
dev = va_arg(ap, struct ps3_devdesc *);
va_end(ap);
od = malloc(sizeof(struct open_dev));
if (!od) {
dev_printf(dev, "couldn't allocate memory for new open_dev\n");
return ENOMEM;
}
err = ps3disk_open_gpt(dev, od);
if (err) {
dev_printf(dev, "couldn't open GPT disk error=%d\n", err);
free(od);
} else {
((struct ps3_devdesc *) (f->f_devdata))->d_disk.data = od;
}
return err;
}
static int ps3disk_close(struct open_file *f)
{
struct ps3_devdesc *dev = f->f_devdata;
struct open_dev *od = dev->d_disk.data;
if (dev->d_disk.ptype == PTYPE_GPT && od->od_gpt_nparts)
free(od->od_gpt_parts);
free(od);
dev->d_disk.data = NULL;
return 0;
}
static int ps3disk_print(int verbose)
{
return (0);
}
static int ps3disk_open_gpt(struct ps3_devdesc *dev, struct open_dev *od)
{
char buf[512];
struct gpt_hdr *hdr;
struct gpt_ent *ent;
daddr_t slba, elba, lba;
int nparts, eps, i, part, err;
od->od_gpt_nparts = 0;
od->od_gpt_parts = NULL;
err = ps3stor_read_sectors(&stor_dev, dev->d_unit, 0, 1, 0, buf);
if (err) {
err = EIO;
goto out;
}
if (le16toh(*((uint16_t *) (buf + DOSMAGICOFFSET))) != DOSMAGIC) {
err = ENXIO;
goto out;
}
err = ps3stor_read_sectors(&stor_dev, dev->d_unit, 1, 1, 0, buf);
if (err) {
err = EIO;
goto out;
}
hdr = (struct gpt_hdr *) buf;
if (bcmp(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig)) ||
le64toh(hdr->hdr_lba_self) != 1 || le32toh(hdr->hdr_revision) < 0x00010000 ||
le32toh(hdr->hdr_entsz) < sizeof(struct gpt_ent) ||
stor_dev.sd_blksize % le32toh(hdr->hdr_entsz) != 0) {
err = ENXIO;
goto out;
}
nparts = 0;
eps = stor_dev.sd_blksize / le32toh(hdr->hdr_entsz);
slba = le64toh(hdr->hdr_lba_table);
elba = slba + le32toh(hdr->hdr_entries) / eps;
for (lba = slba; lba < elba; lba++) {
err = ps3stor_read_sectors(&stor_dev, dev->d_unit, lba, 1, 0, buf);
if (err) {
err = EIO;
goto out;
}
ent = (struct gpt_ent *) buf;
for (i = 0; i < eps; i++) {
if (uuid_is_nil(&ent[i].ent_type, NULL) ||
le64toh(ent[i].ent_lba_start) == 0 ||
le64toh(ent[i].ent_lba_end) < le64toh(ent[i].ent_lba_start))
continue;
nparts++;
}
}
if (nparts) {
od->od_gpt_nparts = nparts;
od->od_gpt_parts = malloc(nparts * sizeof(struct gpt_part));
if (!od->od_gpt_parts) {
err = ENOMEM;
goto out;
}
for (lba = slba, part = 0; lba < elba; lba++) {
err = ps3stor_read_sectors(&stor_dev, dev->d_unit, lba, 1, 0, buf);
if (err) {
err = EIO;
goto out;
}
ent = (struct gpt_ent *) buf;
for (i = 0; i < eps; i++) {
if (uuid_is_nil(&ent[i].ent_type, NULL) ||
le64toh(ent[i].ent_lba_start) == 0 ||
le64toh(ent[i].ent_lba_end) < le64toh(ent[i].ent_lba_start))
continue;
od->od_gpt_parts[part].gp_index = (lba - slba) * eps + i + 1;
od->od_gpt_parts[part].gp_type = ent[i].ent_type;
od->od_gpt_parts[part].gp_start = le64toh(ent[i].ent_lba_start);
od->od_gpt_parts[part].gp_end = le64toh(ent[i].ent_lba_end);
ps3disk_uuid_letoh(&od->od_gpt_parts[part].gp_type);
part++;
}
}
}
dev->d_disk.ptype = PTYPE_GPT;
if (od->od_gpt_nparts && !dev->d_disk.pnum)
dev->d_disk.pnum = od->od_gpt_parts[0].gp_index;
for (i = 0; i < od->od_gpt_nparts; i++)
if (od->od_gpt_parts[i].gp_index == dev->d_disk.pnum)
od->od_start = od->od_gpt_parts[i].gp_start;
err = 0;
out:
if (err && od->od_gpt_parts)
free(od->od_gpt_parts);
return err;
}
static void ps3disk_uuid_letoh(uuid_t *uuid)
{
uuid->time_low = le32toh(uuid->time_low);
uuid->time_mid = le16toh(uuid->time_mid);
uuid->time_hi_and_version = le16toh(uuid->time_hi_and_version);
}

View File

@ -1,120 +0,0 @@
/*-
* 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(PSL_IR | PSL_DR | PSL_RI | PSL_ME);
return (0);
}

View File

@ -1,278 +0,0 @@
/*-
* 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);
}

View File

@ -1,249 +0,0 @@
/*-
* Copyright (C) 2011 glevand (geoffrey.levand@mail.ru)
* 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 <stand.h>
#include "lv1call.h"
#include "ps3.h"
#include "ps3repo.h"
static uint64_t make_n1(const char *text, unsigned int index)
{
uint64_t n1;
n1 = 0;
strncpy((char *) &n1, text, sizeof(n1));
n1 = (n1 >> 32) + index;
return n1;
}
static uint64_t make_n(const char *text, unsigned int index)
{
uint64_t n;
n = 0;
strncpy((char *) &n, text, sizeof(n));
n = n + index;
return n;
}
int ps3repo_read_bus_type(unsigned int bus_index, uint64_t *bus_type)
{
uint64_t v1, v2;
int err;
err = lv1_get_repository_node_value(PS3_LPAR_ID_PME, make_n1("bus", bus_index),
make_n("type", 0), 0, 0, &v1, &v2);
*bus_type = v1;
return err;
}
int ps3repo_read_bus_id(unsigned int bus_index, uint64_t *bus_id)
{
uint64_t v1, v2;
int err;
err = lv1_get_repository_node_value(PS3_LPAR_ID_PME, make_n1("bus", bus_index),
make_n("id", 0), 0, 0, &v1, &v2);
*bus_id = v1;
return err;
}
int ps3repo_read_bus_num_dev(unsigned int bus_index, uint64_t *num_dev)
{
uint64_t v1, v2;
int err;
err = lv1_get_repository_node_value(PS3_LPAR_ID_PME, make_n1("bus", bus_index),
make_n("num_dev", 0), 0, 0, &v1, &v2);
*num_dev = v1;
return err;
}
int ps3repo_read_bus_dev_type(unsigned int bus_index, unsigned int dev_index, uint64_t *dev_type)
{
uint64_t v1, v2;
int err;
err = lv1_get_repository_node_value(PS3_LPAR_ID_PME, make_n1("bus", bus_index),
make_n("dev", dev_index), make_n("type", 0), 0, &v1, &v2);
*dev_type = v1;
return err;
}
int ps3repo_read_bus_dev_id(unsigned int bus_index, unsigned int dev_index, uint64_t *dev_id)
{
uint64_t v1, v2;
int err;
err = lv1_get_repository_node_value(PS3_LPAR_ID_PME, make_n1("bus", bus_index),
make_n("dev", dev_index), make_n("id", 0), 0, &v1, &v2);
*dev_id = v1;
return err;
}
int ps3repo_read_bus_dev_blk_size(unsigned int bus_index, unsigned int dev_index, uint64_t *blk_size)
{
uint64_t v1, v2;
int err;
err = lv1_get_repository_node_value(PS3_LPAR_ID_PME, make_n1("bus", bus_index),
make_n("dev", dev_index), make_n("blk_size", 0), 0, &v1, &v2);
*blk_size = v1;
return err;
}
int ps3repo_read_bus_dev_nblocks(unsigned int bus_index, unsigned int dev_index, uint64_t *nblocks)
{
uint64_t v1, v2;
int err;
err = lv1_get_repository_node_value(PS3_LPAR_ID_PME, make_n1("bus", bus_index),
make_n("dev", dev_index), make_n("n_blocks", 0), 0, &v1, &v2);
*nblocks = v1;
return err;
}
int ps3repo_read_bus_dev_nregs(unsigned int bus_index, unsigned int dev_index, uint64_t *nregs)
{
uint64_t v1, v2;
int err;
err = lv1_get_repository_node_value(PS3_LPAR_ID_PME, make_n1("bus", bus_index),
make_n("dev", dev_index), make_n("n_regs", 0), 0, &v1, &v2);
*nregs = v1;
return err;
}
int ps3repo_read_bus_dev_reg_id(unsigned int bus_index, unsigned int dev_index,
unsigned int reg_index, uint64_t *reg_id)
{
uint64_t v1, v2;
int err;
err = lv1_get_repository_node_value(PS3_LPAR_ID_PME, make_n1("bus", bus_index),
make_n("dev", dev_index), make_n("region", reg_index), make_n("id", 0), &v1, &v2);
*reg_id = v1;
return err;
}
int ps3repo_read_bus_dev_reg_start(unsigned int bus_index, unsigned int dev_index,
unsigned int reg_index, uint64_t *reg_start)
{
uint64_t v1, v2;
int err;
err = lv1_get_repository_node_value(PS3_LPAR_ID_PME, make_n1("bus", bus_index),
make_n("dev", dev_index), make_n("region", reg_index), make_n("start", 0), &v1, &v2);
*reg_start = v1;
return err;
}
int ps3repo_read_bus_dev_reg_size(unsigned int bus_index, unsigned int dev_index,
unsigned int reg_index, uint64_t *reg_size)
{
uint64_t v1, v2;
int err;
err = lv1_get_repository_node_value(PS3_LPAR_ID_PME, make_n1("bus", bus_index),
make_n("dev", dev_index), make_n("region", reg_index), make_n("size", 0), &v1, &v2);
*reg_size = v1;
return err;
}
int ps3repo_find_bus_by_type(uint64_t bus_type, unsigned int *bus_index)
{
unsigned int i;
uint64_t type;
int err;
for (i = 0; i < 10; i++) {
err = ps3repo_read_bus_type(i, &type);
if (err) {
*bus_index = (unsigned int) -1;
return err;
}
if (type == bus_type) {
*bus_index = i;
return 0;
}
}
*bus_index = (unsigned int) -1;
return ENODEV;
}
int ps3repo_find_bus_dev_by_type(unsigned int bus_index, uint64_t dev_type,
unsigned int *dev_index)
{
unsigned int i;
uint64_t type;
int err;
for (i = 0; i < 10; i++) {
err = ps3repo_read_bus_dev_type(bus_index, i, &type);
if (err) {
*dev_index = (unsigned int) -1;
return err;
}
if (type == dev_type) {
*dev_index = i;
return 0;
}
}
*dev_index = (unsigned int) -1;
return ENODEV;
}

View File

@ -1,51 +0,0 @@
/*-
* Copyright (C) 2011 glevand (geoffrey.levand@mail.ru)
* 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_REPO_H
#define _PS3_REPO_H
#define PS3_LPAR_ID_PME 1
int ps3repo_read_bus_type(unsigned int bus_index, uint64_t *bus_type);
int ps3repo_read_bus_id(unsigned int bus_index, uint64_t *bus_id);
int ps3repo_read_bus_num_dev(unsigned int bus_index, uint64_t *num_dev);
int ps3repo_read_bus_dev_type(unsigned int bus_index, unsigned int dev_index, uint64_t *dev_type);
int ps3repo_read_bus_dev_id(unsigned int bus_index, unsigned int dev_index, uint64_t *dev_id);
int ps3repo_read_bus_dev_blk_size(unsigned int bus_index, unsigned int dev_index, uint64_t *blk_size);
int ps3repo_read_bus_dev_nblocks(unsigned int bus_index, unsigned int dev_index, uint64_t *nblocks);
int ps3repo_read_bus_dev_nregs(unsigned int bus_index, unsigned int dev_index, uint64_t *nregs);
int ps3repo_read_bus_dev_reg_id(unsigned int bus_index, unsigned int dev_index,
unsigned int reg_index, uint64_t *reg_id);
int ps3repo_read_bus_dev_reg_start(unsigned int bus_index, unsigned int dev_index,
unsigned int reg_index, uint64_t *reg_start);
int ps3repo_read_bus_dev_reg_size(unsigned int bus_index, unsigned int dev_index,
unsigned int reg_index, uint64_t *reg_size);
int ps3repo_find_bus_by_type(uint64_t bus_type, unsigned int *bus_index);
int ps3repo_find_bus_dev_by_type(unsigned int bus_index, uint64_t dev_type,
unsigned int *dev_index);
#endif

View File

@ -1,176 +0,0 @@
/*-
* Copyright (C) 2011 glevand (geoffrey.levand@mail.ru)
* 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 <stand.h>
#include "bootstrap.h"
#include "lv1call.h"
#include "ps3bus.h"
#include "ps3repo.h"
#include "ps3stor.h"
int ps3stor_setup(struct ps3_stordev *sd, int type)
{
unsigned int i;
int err;
sd->sd_type = type;
err = ps3repo_find_bus_by_type(PS3_BUS_TYPE_STOR, &sd->sd_busidx);
if (err)
goto out;
err = ps3repo_read_bus_id(sd->sd_busidx, &sd->sd_busid);
if (err)
goto out;
err = ps3repo_find_bus_dev_by_type(sd->sd_busidx, type, &sd->sd_devidx);
if (err)
goto out;
err = ps3repo_read_bus_dev_id(sd->sd_busidx, sd->sd_devidx,
&sd->sd_devid);
if (err)
goto out;
err = ps3repo_read_bus_dev_blk_size(sd->sd_busidx, sd->sd_devidx,
&sd->sd_blksize);
if (err)
goto out;
err = ps3repo_read_bus_dev_nblocks(sd->sd_busidx, sd->sd_devidx,
&sd->sd_nblocks);
if (err)
goto out;
err = ps3repo_read_bus_dev_nregs(sd->sd_busidx, sd->sd_devidx,
&sd->sd_nregs);
if (err)
goto out;
for (i = 0; i < sd->sd_nregs; i++) {
err = ps3repo_read_bus_dev_reg_id(sd->sd_busidx, sd->sd_devidx,
i, &sd->sd_regs[i].sr_id);
if (err)
goto out;
err = ps3repo_read_bus_dev_reg_start(sd->sd_busidx,
sd->sd_devidx, i, &sd->sd_regs[i].sr_start);
if (err)
goto out;
err = ps3repo_read_bus_dev_reg_size(sd->sd_busidx,
sd->sd_devidx, i, &sd->sd_regs[i].sr_size);
if (err)
goto out;
}
if (!sd->sd_nregs) {
err = ENODEV;
goto out;
}
err = lv1_open_device(sd->sd_busid, sd->sd_devid, 0);
if (err)
goto out;
err = lv1_setup_dma(sd->sd_busid, sd->sd_devid, &sd->sd_dmabase);
if (err)
goto close_dev;
return 0;
close_dev:
lv1_close_device(sd->sd_busid, sd->sd_devid);
out:
return err;
}
static char dma_buf[2048] __aligned(2048);
int ps3stor_read_sectors(struct ps3_stordev *sd, int regidx,
uint64_t start_sector, uint64_t sector_count, uint64_t flags, char *buf)
{
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
#define BOUNCE_SECTORS (sizeof(dma_buf) / sd->sd_blksize)
#define ASYNC_STATUS_POLL_PERIOD 100 /* microseconds */
struct ps3_storreg *reg = &sd->sd_regs[regidx];
uint64_t nleft, nread, nsectors;
uint64_t tag, status;
unsigned int timeout;
int err = 0;
nleft = sector_count;
nread = 0;
while (nleft) {
nsectors = MIN(nleft, BOUNCE_SECTORS);
err = lv1_storage_read(sd->sd_devid, reg->sr_id,
start_sector + nread, nsectors, flags, (uint32_t)dma_buf,
&tag);
if (err)
return err;
timeout = 5000000; /* microseconds */
while (1) {
if (timeout < ASYNC_STATUS_POLL_PERIOD)
return ETIMEDOUT;
err = lv1_storage_check_async_status(sd->sd_devid, tag,
&status);
if (!err && !status)
break;
delay(ASYNC_STATUS_POLL_PERIOD);
timeout -= ASYNC_STATUS_POLL_PERIOD;
}
if (status != 0)
return EIO;
memcpy(buf + nread * sd->sd_blksize, (u_char *)dma_buf,
nsectors * sd->sd_blksize);
nread += nsectors;
nleft -= nsectors;
}
return err;
#undef MIN
#undef BOUNCE_SECTORS
#undef ASYNC_STATUS_POLL_PERIOD
}
void ps3stor_print(struct ps3_stordev *sd)
{
}

View File

@ -1,59 +0,0 @@
/*-
* Copyright (C) 2011 glevand (geoffrey.levand@mail.ru)
* 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_STOR_H
#define _PS3_STOR_H
#define PS3_STOR_DEV_MAXREGS 8
struct ps3_storreg {
uint64_t sr_id;
uint64_t sr_start;
uint64_t sr_size;
};
struct ps3_stordev {
int sd_type;
unsigned int sd_busidx;
unsigned int sd_devidx;
uint64_t sd_busid;
uint64_t sd_devid;
uint64_t sd_blksize;
uint64_t sd_nblocks;
uint64_t sd_nregs;
struct ps3_storreg sd_regs[PS3_STOR_DEV_MAXREGS];
uint64_t sd_dmabase;
};
int ps3stor_setup(struct ps3_stordev *sd, int type);
int ps3stor_read_sectors(struct ps3_stordev *sd, int regidx,
uint64_t start_sector, uint64_t sector_count, uint64_t flags, char *buf);
void ps3stor_print(struct ps3_stordev *sd);
#endif

View File

@ -1,169 +0,0 @@
/*-
* 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$
*/
#define LOCORE
#include <machine/trap.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

View File

@ -1,8 +0,0 @@
$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.3: Added GPT support to disk.
0.2: Added disk support.
0.1: Initial PS3/PowerPC version.