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