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