]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/boot/powerpc/ps3/main.c
Re-sync loader.mk and ficl.mk to where they should be
[FreeBSD/FreeBSD.git] / sys / boot / powerpc / ps3 / main.c
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
41 struct arch_switch      archsw;
42 extern void *_end;
43
44 extern char bootprog_info[];
45
46 int ps3_getdev(void **vdev, const char *devspec, const char **path);
47 ssize_t ps3_copyin(const void *src, vm_offset_t dest, const size_t len);
48 ssize_t ps3_copyout(vm_offset_t src, void *dest, const size_t len);
49 ssize_t ps3_readin(const int fd, vm_offset_t dest, const size_t len);
50 int ps3_autoload(void);
51 int ps3_setcurrdev(struct env_var *ev, int flags, const void *value);
52
53 static uint64_t basetb;
54
55 int
56 main(void)
57 {
58         uint64_t maxmem = 0;
59         void *heapbase;
60         int i, err;
61         struct ps3_devdesc currdev;
62         struct open_file f;
63
64         lv1_get_physmem(&maxmem);
65         
66         ps3mmu_init(maxmem);
67
68         /*
69          * Set up console.
70          */
71         cons_probe();
72
73         /*
74          * Set the heap to one page after the end of the loader.
75          */
76         heapbase = (void *)(maxmem - 0x80000);
77         setheap(heapbase, maxmem);
78
79         /*
80          * March through the device switch probing for things.
81          */
82         for (i = 0; devsw[i] != NULL; i++) {
83                 if (devsw[i]->dv_init != NULL) {
84                         err = (devsw[i]->dv_init)();
85                         if (err) {
86                                 printf("\n%s: initialization failed err=%d\n",
87                                         devsw[i]->dv_name, err);
88                                 continue;
89                         }
90                 }
91
92                 currdev.d_dev = devsw[i];
93                 currdev.d_type = currdev.d_dev->dv_type;
94
95                 if (strcmp(devsw[i]->dv_name, "cd") == 0) {
96                         f.f_devdata = &currdev;
97                         currdev.d_unit = 0;
98
99                         if (devsw[i]->dv_open(&f, &currdev) == 0)
100                                 break;
101                 }
102
103                 if (strcmp(devsw[i]->dv_name, "disk") == 0) {
104                         f.f_devdata = &currdev;
105                         currdev.d_unit = 3;
106                         currdev.d_disk.pnum = 1;
107                         currdev.d_disk.ptype = PTYPE_GPT;
108
109                         if (devsw[i]->dv_open(&f, &currdev) == 0)
110                                 break;
111                 }
112
113                 if (strcmp(devsw[i]->dv_name, "net") == 0)
114                         break;
115         }
116
117         if (devsw[i] == NULL)
118                 panic("No boot device found!");
119         else
120                 printf("Boot device: %s\n", devsw[i]->dv_name);
121
122         /*
123          * Get timebase at boot.
124          */
125         basetb = mftb();
126
127         archsw.arch_getdev = ps3_getdev;
128         archsw.arch_copyin = ps3_copyin;
129         archsw.arch_copyout = ps3_copyout;
130         archsw.arch_readin = ps3_readin;
131         archsw.arch_autoload = ps3_autoload;
132
133         printf("\n%s", bootprog_info);
134         printf("Memory: %lldKB\n", maxmem / 1024);
135
136         env_setenv("currdev", EV_VOLATILE, ps3_fmtdev(&currdev),
137             ps3_setcurrdev, env_nounset);
138         env_setenv("loaddev", EV_VOLATILE, ps3_fmtdev(&currdev), env_noset,
139             env_nounset);
140         setenv("LINES", "24", 1);
141         setenv("hw.platform", "ps3", 1);
142
143         interact(NULL);                 /* doesn't return */
144
145         return (0);
146 }
147
148 void
149 ppc_exception(int code, vm_offset_t where, register_t msr)
150 {
151         mtmsr(PSL_IR | PSL_DR | PSL_RI);
152         printf("Exception %x at %#lx!\n", code, where);
153         printf("Rebooting in 5 seconds...\n");
154         delay(10000000);
155         lv1_panic(1);
156 }
157
158 const u_int ns_per_tick = 12;
159
160 void
161 exit(int code)
162 {
163         lv1_panic(code);
164 }
165
166 void
167 delay(int usecs)
168 {
169         uint64_t tb,ttb;
170         tb = mftb();
171
172         ttb = tb + howmany(usecs * 1000, ns_per_tick);
173         while (tb < ttb)
174                 tb = mftb();
175 }
176
177 time_t
178 getsecs(void)
179 {
180         return ((time_t)((mftb() - basetb)*ns_per_tick/1000000000));
181 }
182
183 time_t
184 time(time_t *tloc)
185 {
186         time_t rv;
187         
188         rv = getsecs();
189         if (tloc != NULL)
190                 *tloc = rv;
191
192         return (rv);
193 }
194
195 ssize_t
196 ps3_copyin(const void *src, vm_offset_t dest, const size_t len)
197 {
198         bcopy(src, (void *)dest, len);
199         return (len);
200 }
201
202 ssize_t
203 ps3_copyout(vm_offset_t src, void *dest, const size_t len)
204 {
205         bcopy((void *)src, dest, len);
206         return (len);
207 }
208
209 ssize_t
210 ps3_readin(const int fd, vm_offset_t dest, const size_t len)
211 {
212         void            *buf;
213         size_t          resid, chunk, get;
214         ssize_t         got;
215         vm_offset_t     p;
216
217         p = dest;
218
219         chunk = min(PAGE_SIZE, len);
220         buf = malloc(chunk);
221         if (buf == NULL) {
222                 printf("ps3_readin: buf malloc failed\n");
223                 return(0);
224         }
225
226         for (resid = len; resid > 0; resid -= got, p += got) {
227                 get = min(chunk, resid);
228                 got = read(fd, buf, get);
229                 if (got <= 0) {
230                         if (got < 0)
231                                 printf("ps3_readin: read failed\n");
232                         break;
233                 }
234
235                 bcopy(buf, (void *)p, got);
236         }
237
238         free(buf);
239         return (len - resid);
240 }
241
242 int
243 ps3_autoload(void)
244 {
245
246         return (0);
247 }
248