1/*- 2 * Copyright (C) 2010 Nathan Whitehorn 3 * Copyright (C) 2011 glevand (geoffrey.levand@mail.ru) 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include <stand.h> 31#include <sys/param.h> 32 33#define _KERNEL 34#include <machine/cpufunc.h> 35 36#include "bootstrap.h" 37#include "lv1call.h" 38#include "ps3.h" 39#include "ps3devdesc.h" 40 41struct arch_switch archsw; 42extern void *_end; 43 44extern char bootprog_name[]; 45extern char bootprog_rev[]; 46extern char bootprog_date[]; 47extern char bootprog_maker[]; 48 49int ps3_getdev(void **vdev, const char *devspec, const char **path); 50ssize_t ps3_copyin(const void *src, vm_offset_t dest, const size_t len); 51ssize_t ps3_copyout(vm_offset_t src, void *dest, const size_t len); 52ssize_t ps3_readin(const int fd, vm_offset_t dest, const size_t len); 53int ps3_autoload(void); 54int ps3_setcurrdev(struct env_var *ev, int flags, const void *value); 55 56static uint64_t basetb; 57 58int 59main(void) 60{ 61 uint64_t maxmem = 0; 62 void *heapbase; 63 int i, err; 64 struct ps3_devdesc currdev; 65 struct open_file f; 66 67 lv1_get_physmem(&maxmem); 68 69 ps3mmu_init(maxmem); 70 71 /* 72 * Set up console. 73 */ 74 cons_probe(); 75 76 /* 77 * Set the heap to one page after the end of the loader. 78 */ 79 heapbase = (void *)(maxmem - 0x80000); 80 setheap(heapbase, maxmem); 81 82 /* 83 * March through the device switch probing for things. 84 */ 85 for (i = 0; devsw[i] != NULL; i++) { 86 if (devsw[i]->dv_init != NULL) { 87 err = (devsw[i]->dv_init)(); 88 if (err) { 89 printf("\n%s: initialization failed err=%d\n", 90 devsw[i]->dv_name, err); 91 continue; 92 } 93 } 94 95 currdev.d_dev = devsw[i]; 96 currdev.d_type = currdev.d_dev->dv_type; 97 98 if (strcmp(devsw[i]->dv_name, "cd") == 0) { 99 f.f_devdata = &currdev; 100 currdev.d_unit = 0; 101 102 if (devsw[i]->dv_open(&f, &currdev) == 0) 103 break; 104 } 105 106 if (strcmp(devsw[i]->dv_name, "disk") == 0) { 107 f.f_devdata = &currdev; 108 currdev.d_unit = 3; 109 currdev.d_disk.pnum = 1; 110 currdev.d_disk.ptype = PTYPE_GPT; 111 112 if (devsw[i]->dv_open(&f, &currdev) == 0) 113 break; 114 } 115 116 if (strcmp(devsw[i]->dv_name, "net") == 0) 117 break; 118 } 119 120 if (devsw[i] == NULL) 121 panic("No boot device found!"); 122 else 123 printf("Boot device: %s\n", devsw[i]->dv_name); 124 125 /* 126 * Get timebase at boot. 127 */ 128 basetb = mftb(); 129 130 archsw.arch_getdev = ps3_getdev; 131 archsw.arch_copyin = ps3_copyin; 132 archsw.arch_copyout = ps3_copyout; 133 archsw.arch_readin = ps3_readin; 134 archsw.arch_autoload = ps3_autoload; 135 136 printf("\n"); 137 printf("%s, Revision %s\n", bootprog_name, bootprog_rev); 138 printf("(%s, %s)\n", bootprog_maker, bootprog_date); 139 printf("Memory: %lldKB\n", maxmem / 1024); 140 141 env_setenv("currdev", EV_VOLATILE, ps3_fmtdev(&currdev), 142 ps3_setcurrdev, env_nounset); 143 env_setenv("loaddev", EV_VOLATILE, ps3_fmtdev(&currdev), env_noset, 144 env_nounset); 145 setenv("LINES", "24", 1); 146 setenv("hw.platform", "ps3", 1); 147 148 interact(); /* doesn't return */ 149 150 return (0); 151} 152 153void 154ppc_exception(int code, vm_offset_t where, register_t msr) 155{ 156 mtmsr(PSL_IR | PSL_DR | PSL_RI); 157 printf("Exception %x at %#lx!\n", code, where); 158 printf("Rebooting in 5 seconds...\n"); 159 delay(10000000); 160 lv1_panic(1); 161} 162 163const u_int ns_per_tick = 12; 164 165void 166exit(int code) 167{ 168 lv1_panic(code); 169} 170 171void 172delay(int usecs) 173{ 174 uint64_t tb,ttb; 175 tb = mftb(); 176 177 ttb = tb + (usecs * 1000 + ns_per_tick - 1) / ns_per_tick; 178 while (tb < ttb) 179 tb = mftb(); 180} 181 182int 183getsecs() 184{ 185 return ((mftb() - basetb)*ns_per_tick/1000000000); 186} 187 188time_t 189time(time_t *tloc) 190{ 191 time_t rv; 192 193 rv = getsecs(); 194 if (tloc != NULL) 195 *tloc = rv; 196 197 return (rv); 198} 199 200ssize_t 201ps3_copyin(const void *src, vm_offset_t dest, const size_t len) 202{ 203 bcopy(src, (void *)dest, len); 204 return (len); 205} 206 207ssize_t 208ps3_copyout(vm_offset_t src, void *dest, const size_t len) 209{ 210 bcopy((void *)src, dest, len); 211 return (len); 212} 213 214ssize_t 215ps3_readin(const int fd, vm_offset_t dest, const size_t len) 216{ 217 void *buf; 218 size_t resid, chunk, get; 219 ssize_t got; 220 vm_offset_t p; 221 222 p = dest; 223 224 chunk = min(PAGE_SIZE, len); 225 buf = malloc(chunk); 226 if (buf == NULL) { 227 printf("ps3_readin: buf malloc failed\n"); 228 return(0); 229 } 230 231 for (resid = len; resid > 0; resid -= got, p += got) { 232 get = min(chunk, resid); 233 got = read(fd, buf, get); 234 if (got <= 0) { 235 if (got < 0) 236 printf("ps3_readin: read failed\n"); 237 break; 238 } 239 240 bcopy(buf, (void *)p, got); 241 } 242 243 free(buf); 244 return (len - resid); 245} 246 247int 248ps3_autoload(void) 249{ 250 251 return (0); 252} 253 254