]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/boot/powerpc/ps3/main.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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_name[];
45 extern char bootprog_rev[];
46 extern char bootprog_date[];
47 extern char bootprog_maker[];
48
49 int ps3_getdev(void **vdev, const char *devspec, const char **path);
50 ssize_t ps3_copyin(const void *src, vm_offset_t dest, const size_t len);
51 ssize_t ps3_copyout(vm_offset_t src, void *dest, const size_t len);
52 ssize_t ps3_readin(const int fd, vm_offset_t dest, const size_t len);
53 int ps3_autoload(void);
54 int ps3_setcurrdev(struct env_var *ev, int flags, const void *value);
55
56 static uint64_t basetb;
57
58 int
59 main(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
153 void
154 ppc_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
163 const u_int ns_per_tick = 12;
164
165 void
166 exit(int code)
167 {
168         lv1_panic(code);
169 }
170
171 void
172 delay(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
182 int
183 getsecs()
184 {
185         return ((mftb() - basetb)*ns_per_tick/1000000000);
186 }
187
188 time_t
189 time(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
200 ssize_t
201 ps3_copyin(const void *src, vm_offset_t dest, const size_t len)
202 {
203         bcopy(src, (void *)dest, len);
204         return (len);
205 }
206
207 ssize_t
208 ps3_copyout(vm_offset_t src, void *dest, const size_t len)
209 {
210         bcopy((void *)src, dest, len);
211         return (len);
212 }
213
214 ssize_t
215 ps3_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
247 int
248 ps3_autoload(void)
249 {
250
251         return (0);
252 }
253