1217044Snwhitehorn/*- 2217044Snwhitehorn * Copyright (C) 2010 Nathan Whitehorn 3224106Snwhitehorn * Copyright (C) 2011 glevand (geoffrey.levand@mail.ru) 4217044Snwhitehorn * All rights reserved. 5217044Snwhitehorn * 6217044Snwhitehorn * Redistribution and use in source and binary forms, with or without 7217044Snwhitehorn * modification, are permitted provided that the following conditions 8217044Snwhitehorn * are met: 9217044Snwhitehorn * 1. Redistributions of source code must retain the above copyright 10217044Snwhitehorn * notice, this list of conditions and the following disclaimer. 11217044Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 12217044Snwhitehorn * notice, this list of conditions and the following disclaimer in the 13217044Snwhitehorn * documentation and/or other materials provided with the distribution. 14217044Snwhitehorn * 15217044Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16217044Snwhitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17217044Snwhitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18217044Snwhitehorn * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19217044Snwhitehorn * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20217044Snwhitehorn * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21217044Snwhitehorn * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22217044Snwhitehorn * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23217044Snwhitehorn * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24217044Snwhitehorn * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25217044Snwhitehorn */ 26217044Snwhitehorn 27217044Snwhitehorn#include <sys/cdefs.h> 28217044Snwhitehorn__FBSDID("$FreeBSD$"); 29217044Snwhitehorn 30217044Snwhitehorn#include <stand.h> 31217044Snwhitehorn#include <sys/param.h> 32217044Snwhitehorn 33217044Snwhitehorn#define _KERNEL 34217044Snwhitehorn#include <machine/cpufunc.h> 35217044Snwhitehorn 36217044Snwhitehorn#include "bootstrap.h" 37217044Snwhitehorn#include "lv1call.h" 38217044Snwhitehorn#include "ps3.h" 39224106Snwhitehorn#include "ps3devdesc.h" 40217044Snwhitehorn 41217044Snwhitehornstruct arch_switch archsw; 42217044Snwhitehornextern void *_end; 43217044Snwhitehorn 44217044Snwhitehornextern char bootprog_name[]; 45217044Snwhitehornextern char bootprog_rev[]; 46217044Snwhitehornextern char bootprog_date[]; 47217044Snwhitehornextern char bootprog_maker[]; 48217044Snwhitehorn 49217044Snwhitehornint ps3_getdev(void **vdev, const char *devspec, const char **path); 50217044Snwhitehornssize_t ps3_copyin(const void *src, vm_offset_t dest, const size_t len); 51217044Snwhitehornssize_t ps3_copyout(vm_offset_t src, void *dest, const size_t len); 52217044Snwhitehornssize_t ps3_readin(const int fd, vm_offset_t dest, const size_t len); 53217044Snwhitehornint ps3_autoload(void); 54217044Snwhitehornint ps3_setcurrdev(struct env_var *ev, int flags, const void *value); 55217044Snwhitehorn 56217044Snwhitehornstatic uint64_t basetb; 57217044Snwhitehorn 58217044Snwhitehornint 59217044Snwhitehornmain(void) 60217044Snwhitehorn{ 61217044Snwhitehorn uint64_t maxmem = 0; 62217044Snwhitehorn void *heapbase; 63224106Snwhitehorn int i, err; 64224106Snwhitehorn struct ps3_devdesc currdev; 65224106Snwhitehorn struct open_file f; 66217044Snwhitehorn 67217044Snwhitehorn lv1_get_physmem(&maxmem); 68217044Snwhitehorn 69217044Snwhitehorn ps3mmu_init(maxmem); 70217044Snwhitehorn 71217044Snwhitehorn /* 72217044Snwhitehorn * Set up console. 73217044Snwhitehorn */ 74217044Snwhitehorn cons_probe(); 75217044Snwhitehorn 76217044Snwhitehorn /* 77217044Snwhitehorn * Set the heap to one page after the end of the loader. 78217044Snwhitehorn */ 79217044Snwhitehorn heapbase = (void *)(maxmem - 0x80000); 80217044Snwhitehorn setheap(heapbase, maxmem); 81217044Snwhitehorn 82217044Snwhitehorn /* 83217044Snwhitehorn * March through the device switch probing for things. 84217044Snwhitehorn */ 85224106Snwhitehorn for (i = 0; devsw[i] != NULL; i++) { 86224106Snwhitehorn if (devsw[i]->dv_init != NULL) { 87224106Snwhitehorn err = (devsw[i]->dv_init)(); 88224106Snwhitehorn if (err) { 89224106Snwhitehorn printf("\n%s: initialization failed err=%d\n", 90224106Snwhitehorn devsw[i]->dv_name, err); 91224106Snwhitehorn continue; 92224106Snwhitehorn } 93224106Snwhitehorn } 94217044Snwhitehorn 95224106Snwhitehorn currdev.d_dev = devsw[i]; 96224106Snwhitehorn currdev.d_type = currdev.d_dev->dv_type; 97224106Snwhitehorn 98224857Snwhitehorn if (strcmp(devsw[i]->dv_name, "cd") == 0) { 99224857Snwhitehorn f.f_devdata = &currdev; 100224857Snwhitehorn currdev.d_unit = 0; 101224857Snwhitehorn 102224857Snwhitehorn if (devsw[i]->dv_open(&f, &currdev) == 0) 103224857Snwhitehorn break; 104224857Snwhitehorn } 105224857Snwhitehorn 106224106Snwhitehorn if (strcmp(devsw[i]->dv_name, "disk") == 0) { 107224106Snwhitehorn f.f_devdata = &currdev; 108224106Snwhitehorn currdev.d_unit = 3; 109224106Snwhitehorn currdev.d_disk.pnum = 1; 110224106Snwhitehorn currdev.d_disk.ptype = PTYPE_GPT; 111224106Snwhitehorn 112224106Snwhitehorn if (devsw[i]->dv_open(&f, &currdev) == 0) 113224106Snwhitehorn break; 114224106Snwhitehorn } 115224106Snwhitehorn 116224106Snwhitehorn if (strcmp(devsw[i]->dv_name, "net") == 0) 117224106Snwhitehorn break; 118224106Snwhitehorn } 119224106Snwhitehorn 120224106Snwhitehorn if (devsw[i] == NULL) 121224106Snwhitehorn panic("No boot device found!"); 122224857Snwhitehorn else 123224857Snwhitehorn printf("Boot device: %s\n", devsw[i]->dv_name); 124224106Snwhitehorn 125217044Snwhitehorn /* 126217044Snwhitehorn * Get timebase at boot. 127217044Snwhitehorn */ 128217044Snwhitehorn basetb = mftb(); 129217044Snwhitehorn 130217044Snwhitehorn archsw.arch_getdev = ps3_getdev; 131217044Snwhitehorn archsw.arch_copyin = ps3_copyin; 132217044Snwhitehorn archsw.arch_copyout = ps3_copyout; 133217044Snwhitehorn archsw.arch_readin = ps3_readin; 134217044Snwhitehorn archsw.arch_autoload = ps3_autoload; 135217044Snwhitehorn 136217044Snwhitehorn printf("\n"); 137217044Snwhitehorn printf("%s, Revision %s\n", bootprog_name, bootprog_rev); 138217044Snwhitehorn printf("(%s, %s)\n", bootprog_maker, bootprog_date); 139217044Snwhitehorn printf("Memory: %lldKB\n", maxmem / 1024); 140217044Snwhitehorn 141224106Snwhitehorn env_setenv("currdev", EV_VOLATILE, ps3_fmtdev(&currdev), 142224106Snwhitehorn ps3_setcurrdev, env_nounset); 143224106Snwhitehorn env_setenv("loaddev", EV_VOLATILE, ps3_fmtdev(&currdev), env_noset, 144224106Snwhitehorn env_nounset); 145217044Snwhitehorn setenv("LINES", "24", 1); 146217044Snwhitehorn setenv("hw.platform", "ps3", 1); 147217044Snwhitehorn 148217044Snwhitehorn interact(); /* doesn't return */ 149217044Snwhitehorn 150217044Snwhitehorn return (0); 151217044Snwhitehorn} 152217044Snwhitehorn 153217044Snwhitehornvoid 154217044Snwhitehornppc_exception(int code, vm_offset_t where, register_t msr) 155217044Snwhitehorn{ 156217044Snwhitehorn mtmsr(PSL_IR | PSL_DR | PSL_RI); 157217044Snwhitehorn printf("Exception %x at %#lx!\n", code, where); 158217044Snwhitehorn printf("Rebooting in 5 seconds...\n"); 159217044Snwhitehorn delay(10000000); 160217044Snwhitehorn lv1_panic(1); 161217044Snwhitehorn} 162217044Snwhitehorn 163217044Snwhitehornconst u_int ns_per_tick = 12; 164217044Snwhitehorn 165217044Snwhitehornvoid 166217044Snwhitehornexit(int code) 167217044Snwhitehorn{ 168217044Snwhitehorn lv1_panic(code); 169217044Snwhitehorn} 170217044Snwhitehorn 171217044Snwhitehornvoid 172217044Snwhitehorndelay(int usecs) 173217044Snwhitehorn{ 174217044Snwhitehorn uint64_t tb,ttb; 175217044Snwhitehorn tb = mftb(); 176217044Snwhitehorn 177217044Snwhitehorn ttb = tb + (usecs * 1000 + ns_per_tick - 1) / ns_per_tick; 178217044Snwhitehorn while (tb < ttb) 179217044Snwhitehorn tb = mftb(); 180217044Snwhitehorn} 181217044Snwhitehorn 182217044Snwhitehornint 183217044Snwhitehorngetsecs() 184217044Snwhitehorn{ 185217044Snwhitehorn return ((mftb() - basetb)*ns_per_tick/1000000000); 186217044Snwhitehorn} 187217044Snwhitehorn 188217044Snwhitehorntime_t 189217044Snwhitehorntime(time_t *tloc) 190217044Snwhitehorn{ 191217044Snwhitehorn time_t rv; 192217044Snwhitehorn 193217044Snwhitehorn rv = getsecs(); 194217044Snwhitehorn if (tloc != NULL) 195217044Snwhitehorn *tloc = rv; 196217044Snwhitehorn 197217044Snwhitehorn return (rv); 198217044Snwhitehorn} 199217044Snwhitehorn 200217044Snwhitehornssize_t 201217044Snwhitehornps3_copyin(const void *src, vm_offset_t dest, const size_t len) 202217044Snwhitehorn{ 203217044Snwhitehorn bcopy(src, (void *)dest, len); 204217044Snwhitehorn return (len); 205217044Snwhitehorn} 206217044Snwhitehorn 207217044Snwhitehornssize_t 208217044Snwhitehornps3_copyout(vm_offset_t src, void *dest, const size_t len) 209217044Snwhitehorn{ 210217044Snwhitehorn bcopy((void *)src, dest, len); 211217044Snwhitehorn return (len); 212217044Snwhitehorn} 213217044Snwhitehorn 214217044Snwhitehornssize_t 215217044Snwhitehornps3_readin(const int fd, vm_offset_t dest, const size_t len) 216217044Snwhitehorn{ 217217044Snwhitehorn void *buf; 218217044Snwhitehorn size_t resid, chunk, get; 219217044Snwhitehorn ssize_t got; 220217044Snwhitehorn vm_offset_t p; 221217044Snwhitehorn 222217044Snwhitehorn p = dest; 223217044Snwhitehorn 224217044Snwhitehorn chunk = min(PAGE_SIZE, len); 225217044Snwhitehorn buf = malloc(chunk); 226217044Snwhitehorn if (buf == NULL) { 227217044Snwhitehorn printf("ps3_readin: buf malloc failed\n"); 228217044Snwhitehorn return(0); 229217044Snwhitehorn } 230217044Snwhitehorn 231217044Snwhitehorn for (resid = len; resid > 0; resid -= got, p += got) { 232217044Snwhitehorn get = min(chunk, resid); 233217044Snwhitehorn got = read(fd, buf, get); 234217044Snwhitehorn if (got <= 0) { 235217044Snwhitehorn if (got < 0) 236217044Snwhitehorn printf("ps3_readin: read failed\n"); 237217044Snwhitehorn break; 238217044Snwhitehorn } 239217044Snwhitehorn 240217044Snwhitehorn bcopy(buf, (void *)p, got); 241217044Snwhitehorn } 242217044Snwhitehorn 243217044Snwhitehorn free(buf); 244217044Snwhitehorn return (len - resid); 245217044Snwhitehorn} 246217044Snwhitehorn 247217044Snwhitehornint 248217044Snwhitehornps3_autoload(void) 249217044Snwhitehorn{ 250217044Snwhitehorn 251217044Snwhitehorn return (0); 252217044Snwhitehorn} 253217044Snwhitehorn 254