]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/cfe/cfe_api.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / cfe / cfe_api.c
1 /* $NetBSD: cfe_api.c,v 1.5 2005/12/11 12:18:07 christos Exp $ */
2 /* from: SiByte Id: cfe_api.c,v 1.16 2002/07/09 23:29:11 cgd Exp $ */
3
4 /*-
5  * Copyright 2000, 2001, 2002
6  * Broadcom Corporation. All rights reserved.
7  *
8  * This software is furnished under license and may be used and copied only
9  * in accordance with the following terms and conditions.  Subject to these
10  * conditions, you may download, copy, install, use, modify and distribute
11  * modified or unmodified copies of this software in source and/or binary
12  * form. No title or ownership is transferred hereby.
13  *
14  * 1) Any source code used, modified or distributed must reproduce and
15  *    retain this copyright notice and list of conditions as they appear in
16  *    the source file.
17  *
18  * 2) No right is granted to use any trade name, trademark, or logo of
19  *    Broadcom Corporation.  The "Broadcom Corporation" name may not be
20  *    used to endorse or promote products derived from this software
21  *    without the prior written permission of Broadcom Corporation.
22  *
23  * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
24  *    WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
25  *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
26  *    NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
27  *    FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
28  *    LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
31  *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32  *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33  *    OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 /*  *********************************************************************
37     *
38     *  Broadcom Common Firmware Environment (CFE)
39     *
40     *  Device Function stubs                    File: cfe_api.c
41     *
42     *  This module contains device function stubs (small routines to
43     *  call the standard "iocb" interface entry point to CFE).
44     *  There should be one routine here per iocb function call.
45     *
46     *  Authors:  Mitch Lichtenberg, Chris Demetriou
47     *
48     ********************************************************************* */
49
50 #include <sys/cdefs.h>
51 __FBSDID("$FreeBSD$");
52
53 #include <dev/cfe/cfe_api.h>
54 #include <dev/cfe/cfe_api_int.h>
55
56 /* Cast from a native pointer to a cfe_xptr_t and back.  */
57 #define XPTR_FROM_NATIVE(n)     ((cfe_xptr_t) (intptr_t) (n))
58 #define NATIVE_FROM_XPTR(x)     ((void *) (intptr_t) (x))
59
60 #ifdef CFE_API_IMPL_NAMESPACE
61 #define cfe_iocb_dispatch(a)            __cfe_iocb_dispatch(a)
62 #endif
63 int cfe_iocb_dispatch(cfe_xiocb_t *xiocb);
64
65 #if defined(CFE_API_common) || defined(CFE_API_ALL)
66 /*
67  * Declare the dispatch function with args of "intptr_t".
68  * This makes sure whatever model we're compiling in
69  * puts the pointers in a single register.  For example,
70  * combining -mlong64 and -mips1 or -mips2 would lead to
71  * trouble, since the handle and IOCB pointer will be
72  * passed in two registers each, and CFE expects one.
73  */
74
75 static int (*cfe_dispfunc)(intptr_t handle, intptr_t xiocb) = 0;
76 static cfe_xuint_t cfe_handle = 0;
77
78 int
79 cfe_init(cfe_xuint_t handle, cfe_xuint_t ept)
80 {
81     cfe_dispfunc = NATIVE_FROM_XPTR(ept);
82     cfe_handle = handle;
83     return 0;
84 }
85
86 int
87 cfe_iocb_dispatch(cfe_xiocb_t *xiocb)
88 {
89     if (!cfe_dispfunc) return -1;
90     return (*cfe_dispfunc)((intptr_t)cfe_handle, (intptr_t)xiocb);
91 }
92 #endif /* CFE_API_common || CFE_API_ALL */
93
94 #if defined(CFE_API_close) || defined(CFE_API_ALL)
95 int
96 cfe_close(int handle)
97 {
98     cfe_xiocb_t xiocb;
99
100     xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE;
101     xiocb.xiocb_status = 0;
102     xiocb.xiocb_handle = handle;
103     xiocb.xiocb_flags = 0;
104     xiocb.xiocb_psize = 0;
105
106     cfe_iocb_dispatch(&xiocb);
107
108     return xiocb.xiocb_status;
109
110 }
111 #endif /* CFE_API_close || CFE_API_ALL */
112
113 #if defined(CFE_API_cpu_start) || defined(CFE_API_ALL)
114 int
115 cfe_cpu_start(int cpu, void (*fn)(void), long sp, long gp, long a1)
116 {
117     cfe_xiocb_t xiocb;
118
119     xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
120     xiocb.xiocb_status = 0;
121     xiocb.xiocb_handle = 0;
122     xiocb.xiocb_flags  = 0;
123     xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t);
124     xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
125     xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START;
126     xiocb.plist.xiocb_cpuctl.gp_val = gp;
127     xiocb.plist.xiocb_cpuctl.sp_val = sp;
128     xiocb.plist.xiocb_cpuctl.a1_val = a1;
129     xiocb.plist.xiocb_cpuctl.start_addr = (long)fn;
130
131     cfe_iocb_dispatch(&xiocb);
132
133     return xiocb.xiocb_status;
134 }
135 #endif /* CFE_API_cpu_start || CFE_API_ALL */
136
137 #if defined(CFE_API_cpu_stop) || defined(CFE_API_ALL)
138 int
139 cfe_cpu_stop(int cpu)
140 {
141     cfe_xiocb_t xiocb;
142
143     xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
144     xiocb.xiocb_status = 0;
145     xiocb.xiocb_handle = 0;
146     xiocb.xiocb_flags  = 0;
147     xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t);
148     xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
149     xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP;
150
151     cfe_iocb_dispatch(&xiocb);
152
153     return xiocb.xiocb_status;
154 }
155 #endif /* CFE_API_cpu_stop || CFE_API_ALL */
156
157 #if defined(CFE_API_enumenv) || defined(CFE_API_ALL)
158 int
159 cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
160 {
161     cfe_xiocb_t xiocb;
162
163     xiocb.xiocb_fcode = CFE_CMD_ENV_ENUM;
164     xiocb.xiocb_status = 0;
165     xiocb.xiocb_handle = 0;
166     xiocb.xiocb_flags = 0;
167     xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
168     xiocb.plist.xiocb_envbuf.enum_idx = idx;
169     xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
170     xiocb.plist.xiocb_envbuf.name_length = namelen;
171     xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
172     xiocb.plist.xiocb_envbuf.val_length = vallen;
173
174     cfe_iocb_dispatch(&xiocb);
175
176     return xiocb.xiocb_status;
177 }
178 #endif /* CFE_API_enumenv || CFE_API_ALL */
179
180 #if defined(CFE_API_enummem) || defined(CFE_API_ALL)
181 int
182 cfe_enummem(int idx, int flags, cfe_xuint_t *start, cfe_xuint_t *length,
183             cfe_xuint_t *type)
184 {
185     cfe_xiocb_t xiocb;
186
187     xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM;
188     xiocb.xiocb_status = 0;
189     xiocb.xiocb_handle = 0;
190     xiocb.xiocb_flags = flags;
191     xiocb.xiocb_psize = sizeof(xiocb_meminfo_t);
192     xiocb.plist.xiocb_meminfo.mi_idx = idx;
193
194     cfe_iocb_dispatch(&xiocb);
195
196     if (xiocb.xiocb_status < 0)
197         return xiocb.xiocb_status;
198
199     *start = xiocb.plist.xiocb_meminfo.mi_addr;
200     *length = xiocb.plist.xiocb_meminfo.mi_size;
201     *type = xiocb.plist.xiocb_meminfo.mi_type;
202
203     return 0;
204 }
205 #endif /* CFE_API_enummem || CFE_API_ALL */
206
207 #if defined(CFE_API_exit) || defined(CFE_API_ALL)
208 int
209 cfe_exit(int warm, int status)
210 {
211     cfe_xiocb_t xiocb;
212
213     xiocb.xiocb_fcode = CFE_CMD_FW_RESTART;
214     xiocb.xiocb_status = 0;
215     xiocb.xiocb_handle = 0;
216     xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0;
217     xiocb.xiocb_psize = sizeof(xiocb_exitstat_t);
218     xiocb.plist.xiocb_exitstat.status = status;
219
220     cfe_iocb_dispatch(&xiocb);
221
222     return xiocb.xiocb_status;
223 }
224 #endif /* CFE_API_exit || CFE_API_ALL */
225
226 #if defined(CFE_API_flushcache) || defined(CFE_API_ALL)
227 int
228 cfe_flushcache(int flg)
229 {
230     cfe_xiocb_t xiocb;
231
232     xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE;
233     xiocb.xiocb_status = 0;
234     xiocb.xiocb_handle = 0;
235     xiocb.xiocb_flags = flg;
236     xiocb.xiocb_psize = 0;
237
238     cfe_iocb_dispatch(&xiocb);
239
240     return xiocb.xiocb_status;
241 }
242 #endif /* CFE_API_flushcache || CFE_API_ALL */
243
244 #if defined(CFE_API_getdevinfo) || defined(CFE_API_ALL)
245 int
246 cfe_getdevinfo(char *name)
247 {
248     cfe_xiocb_t xiocb;
249
250     xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO;
251     xiocb.xiocb_status = 0;
252     xiocb.xiocb_handle = 0;
253     xiocb.xiocb_flags = 0;
254     xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
255     xiocb.plist.xiocb_buffer.buf_offset = 0;
256     xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
257     xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name);
258
259     cfe_iocb_dispatch(&xiocb);
260
261     if (xiocb.xiocb_status < 0)
262         return xiocb.xiocb_status;
263     return xiocb.plist.xiocb_buffer.buf_devflags;
264 }
265 #endif /* CFE_API_getdevinfo || CFE_API_ALL */
266
267 #if defined(CFE_API_getenv) || defined(CFE_API_ALL)
268 int
269 cfe_getenv(char *name, char *dest, int destlen)
270 {
271     cfe_xiocb_t xiocb;
272
273     *dest = 0;
274
275     xiocb.xiocb_fcode = CFE_CMD_ENV_GET;
276     xiocb.xiocb_status = 0;
277     xiocb.xiocb_handle = 0;
278     xiocb.xiocb_flags = 0;
279     xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
280     xiocb.plist.xiocb_envbuf.enum_idx = 0;
281     xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
282     xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name);
283     xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest);
284     xiocb.plist.xiocb_envbuf.val_length = destlen;
285
286     cfe_iocb_dispatch(&xiocb);
287
288     return xiocb.xiocb_status;
289 }
290 #endif /* CFE_API_getenv || CFE_API_ALL */
291
292 #if defined(CFE_API_getfwinfo) || defined(CFE_API_ALL)
293 int
294 cfe_getfwinfo(cfe_fwinfo_t *info)
295 {
296     cfe_xiocb_t xiocb;
297
298     xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO;
299     xiocb.xiocb_status = 0;
300     xiocb.xiocb_handle = 0;
301     xiocb.xiocb_flags = 0;
302     xiocb.xiocb_psize = sizeof(xiocb_fwinfo_t);
303
304     cfe_iocb_dispatch(&xiocb);
305
306     if (xiocb.xiocb_status < 0)
307         return xiocb.xiocb_status;
308
309     info->fwi_version = xiocb.plist.xiocb_fwinfo.fwi_version;
310     info->fwi_totalmem = xiocb.plist.xiocb_fwinfo.fwi_totalmem;
311     info->fwi_flags = xiocb.plist.xiocb_fwinfo.fwi_flags;
312     info->fwi_boardid = xiocb.plist.xiocb_fwinfo.fwi_boardid;
313     info->fwi_bootarea_va = xiocb.plist.xiocb_fwinfo.fwi_bootarea_va;
314     info->fwi_bootarea_pa = xiocb.plist.xiocb_fwinfo.fwi_bootarea_pa;
315     info->fwi_bootarea_size = xiocb.plist.xiocb_fwinfo.fwi_bootarea_size;
316 #if 0
317     info->fwi_reserved1 = xiocb.plist.xiocb_fwinfo.fwi_reserved1;
318     info->fwi_reserved2 = xiocb.plist.xiocb_fwinfo.fwi_reserved2;
319     info->fwi_reserved3 = xiocb.plist.xiocb_fwinfo.fwi_reserved3;
320 #endif
321
322     return 0;
323 }
324 #endif /* CFE_API_getfwinfo || CFE_API_ALL */
325
326 #if defined(CFE_API_getstdhandle) || defined(CFE_API_ALL)
327 int
328 cfe_getstdhandle(int flg)
329 {
330     cfe_xiocb_t xiocb;
331
332     xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE;
333     xiocb.xiocb_status = 0;
334     xiocb.xiocb_handle = 0;
335     xiocb.xiocb_flags = flg;
336     xiocb.xiocb_psize = 0;
337
338     cfe_iocb_dispatch(&xiocb);
339
340     if (xiocb.xiocb_status < 0)
341         return xiocb.xiocb_status;
342     return xiocb.xiocb_handle;
343
344 }
345 #endif /* CFE_API_getstdhandle || CFE_API_ALL */
346
347 #if defined(CFE_API_getticks) || defined(CFE_API_ALL)
348 int64_t
349 #ifdef CFE_API_IMPL_NAMESPACE
350 __cfe_getticks(void)
351 #else
352 cfe_getticks(void)
353 #endif
354 {
355     cfe_xiocb_t xiocb;
356
357     xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME;
358     xiocb.xiocb_status = 0;
359     xiocb.xiocb_handle = 0;
360     xiocb.xiocb_flags = 0;
361     xiocb.xiocb_psize = sizeof(xiocb_time_t);
362     xiocb.plist.xiocb_time.ticks = 0;
363
364     cfe_iocb_dispatch(&xiocb);
365
366     return xiocb.plist.xiocb_time.ticks;
367
368 }
369 #endif /* CFE_API_getticks || CFE_API_ALL */
370
371 #if defined(CFE_API_inpstat) || defined(CFE_API_ALL)
372 int
373 cfe_inpstat(int handle)
374 {
375     cfe_xiocb_t xiocb;
376
377     xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT;
378     xiocb.xiocb_status = 0;
379     xiocb.xiocb_handle = handle;
380     xiocb.xiocb_flags = 0;
381     xiocb.xiocb_psize = sizeof(xiocb_inpstat_t);
382     xiocb.plist.xiocb_inpstat.inp_status = 0;
383
384     cfe_iocb_dispatch(&xiocb);
385
386     if (xiocb.xiocb_status < 0)
387         return xiocb.xiocb_status;
388     return xiocb.plist.xiocb_inpstat.inp_status;
389
390 }
391 #endif /* CFE_API_inpstat || CFE_API_ALL */
392
393 #if defined(CFE_API_ioctl) || defined(CFE_API_ALL)
394 int
395 cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer, int length,
396           int *retlen, cfe_xuint_t offset)
397 {
398     cfe_xiocb_t xiocb;
399
400     xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL;
401     xiocb.xiocb_status = 0;
402     xiocb.xiocb_handle = handle;
403     xiocb.xiocb_flags = 0;
404     xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
405     xiocb.plist.xiocb_buffer.buf_offset = offset;
406     xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum;
407     xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
408     xiocb.plist.xiocb_buffer.buf_length = length;
409
410     cfe_iocb_dispatch(&xiocb);
411
412     if (retlen)
413         *retlen = xiocb.plist.xiocb_buffer.buf_retlen;
414     return xiocb.xiocb_status;
415 }
416 #endif /* CFE_API_ioctl || CFE_API_ALL */
417
418 #if defined(CFE_API_open) || defined(CFE_API_ALL)
419 int
420 cfe_open(char *name)
421 {
422     cfe_xiocb_t xiocb;
423
424     xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN;
425     xiocb.xiocb_status = 0;
426     xiocb.xiocb_handle = 0;
427     xiocb.xiocb_flags = 0;
428     xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
429     xiocb.plist.xiocb_buffer.buf_offset = 0;
430     xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
431     xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name);
432
433     cfe_iocb_dispatch(&xiocb);
434
435     if (xiocb.xiocb_status < 0)
436         return xiocb.xiocb_status;
437     return xiocb.xiocb_handle;
438 }
439 #endif /* CFE_API_open || CFE_API_ALL */
440
441 #if defined(CFE_API_read) || defined(CFE_API_ALL)
442 int
443 cfe_read(int handle, unsigned char *buffer, int length)
444 {
445     return cfe_readblk(handle, 0, buffer, length);
446 }
447 #endif /* CFE_API_read || CFE_API_ALL */
448
449 #if defined(CFE_API_readblk) || defined(CFE_API_ALL)
450 int
451 cfe_readblk(int handle, cfe_xint_t offset, unsigned char *buffer, int length)
452 {
453     cfe_xiocb_t xiocb;
454
455     xiocb.xiocb_fcode = CFE_CMD_DEV_READ;
456     xiocb.xiocb_status = 0;
457     xiocb.xiocb_handle = handle;
458     xiocb.xiocb_flags = 0;
459     xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
460     xiocb.plist.xiocb_buffer.buf_offset = offset;
461     xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
462     xiocb.plist.xiocb_buffer.buf_length = length;
463
464     cfe_iocb_dispatch(&xiocb);
465
466     if (xiocb.xiocb_status < 0)
467         return xiocb.xiocb_status;
468     return xiocb.plist.xiocb_buffer.buf_retlen;
469 }
470 #endif /* CFE_API_readblk || CFE_API_ALL */
471
472 #if defined(CFE_API_setenv) || defined(CFE_API_ALL)
473 int
474 cfe_setenv(char *name, char *val)
475 {
476     cfe_xiocb_t xiocb;
477
478     xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
479     xiocb.xiocb_status = 0;
480     xiocb.xiocb_handle = 0;
481     xiocb.xiocb_flags = 0;
482     xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
483     xiocb.plist.xiocb_envbuf.enum_idx = 0;
484     xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
485     xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name);
486     xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
487     xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val);
488
489     cfe_iocb_dispatch(&xiocb);
490
491     return xiocb.xiocb_status;
492 }
493 #endif /* CFE_API_setenv || CFE_API_ALL */
494
495 #if (defined(CFE_API_strlen) || defined(CFE_API_ALL)) \
496     && !defined(CFE_API_STRLEN_CUSTOM)
497 int
498 cfe_strlen(char *name)
499 {
500     int count = 0;
501
502     while (*name++)
503         count++;
504
505     return count;
506 }
507 #endif /* CFE_API_strlen || CFE_API_ALL */
508
509 #if defined(CFE_API_write) || defined(CFE_API_ALL)
510 int
511 cfe_write(int handle, unsigned char *buffer, int length)
512 {
513     return cfe_writeblk(handle, 0, buffer, length);
514 }
515 #endif /* CFE_API_write || CFE_API_ALL */
516
517 #if defined(CFE_API_writeblk) || defined(CFE_API_ALL)
518 int
519 cfe_writeblk(int handle, cfe_xint_t offset, unsigned char *buffer, int length)
520 {
521     cfe_xiocb_t xiocb;
522
523     xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE;
524     xiocb.xiocb_status = 0;
525     xiocb.xiocb_handle = handle;
526     xiocb.xiocb_flags = 0;
527     xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
528     xiocb.plist.xiocb_buffer.buf_offset = offset;
529     xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
530     xiocb.plist.xiocb_buffer.buf_length = length;
531
532     cfe_iocb_dispatch(&xiocb);
533
534     if (xiocb.xiocb_status < 0)
535         return xiocb.xiocb_status;
536     return xiocb.plist.xiocb_buffer.buf_retlen;
537 }
538 #endif /* CFE_API_writeblk || CFE_API_ALL */