xref: /netbsd/sys/arch/mips/cfe/cfe_api.c (revision bf9ec67e)
1 /* $NetBSD: cfe_api.c,v 1.1 2002/03/05 23:46:40 simonb Exp $ */
2 
3 /*
4  * Copyright 2000, 2001
5  * Broadcom Corporation. All rights reserved.
6  *
7  * This software is furnished under license and may be used and copied only
8  * in accordance with the following terms and conditions.  Subject to these
9  * conditions, you may download, copy, install, use, modify and distribute
10  * modified or unmodified copies of this software in source and/or binary
11  * form. No title or ownership is transferred hereby.
12  *
13  * 1) Any source code used, modified or distributed must reproduce and
14  *    retain this copyright notice and list of conditions as they appear in
15  *    the source file.
16  *
17  * 2) No right is granted to use any trade name, trademark, or logo of
18  *    Broadcom Corporation. Neither the "Broadcom Corporation" name nor any
19  *    trademark or logo of Broadcom Corporation may be used to endorse or
20  *    promote products derived from this software without the prior written
21  *    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     *  Broadcom Common Firmware Environment (CFE)
38     *
39     *  Device Function stubs			File: cfe_api.c
40     *
41     *  This module contains device function stubs (small routines to
42     *  call the standard "iocb" interface entry point to CFE).
43     *  There should be one routine here per iocb function call.
44     *
45     *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
46     *
47     ********************************************************************* */
48 
49 
50 #include <sys/types.h>
51 
52 #include <mips/cfe/cfe_xiocb.h>
53 #include <mips/cfe/cfe_api.h>
54 
55 typedef long intptr_t;
56 typedef u_long uintptr_t;
57 
58 /*
59  * Declare the dispatch function with args of "intptr_t".
60  * This makes sure whatever model we're compiling in
61  * puts the pointers in a single register.  For example,
62  * combining -mlong64 and -mips1 or -mips2 would lead to
63  * trouble, since the handle and IOCB pointer will be
64  * passed in two registers each, and CFE expects one.
65  */
66 
67 static int (*cfe_dispfunc)(intptr_t handle,intptr_t xiocb) = 0;
68 static cfe_xuint_t cfe_handle = 0;
69 int cfe_iocb_dispatch(cfe_xiocb_t *xiocb);
70 
71 int cfe_init(cfe_xuint_t handle)
72 {
73     u_int *sealloc = (u_int *) (intptr_t) (int)  CFE_APISEAL;
74     if (*sealloc != CFE_EPTSEAL) return -1;
75     cfe_dispfunc = (void *) (cfe_xptr_t) (int) CFE_APIENTRY;
76     if (handle) cfe_handle = handle;
77     return 0;
78 }
79 
80 int cfe_iocb_dispatch(cfe_xiocb_t *xiocb)
81 {
82     if (!cfe_dispfunc) return -1;
83     return (*cfe_dispfunc)((intptr_t) cfe_handle,(intptr_t) xiocb);
84 }
85 
86 static int cfe_strlen(char *name)
87 {
88     int count = 0;
89 
90     while (*name) {
91 	count++;
92 	name++;
93 	}
94 
95     return count;
96 }
97 
98 int cfe_open(char *name)
99 {
100     cfe_xiocb_t xiocb;
101 
102     xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN;
103     xiocb.xiocb_status = 0;
104     xiocb.xiocb_handle = 0;
105     xiocb.xiocb_flags = 0;
106     xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
107     xiocb.plist.xiocb_buffer.buf_offset = 0;
108     xiocb.plist.xiocb_buffer.buf_ptr = (cfe_xptr_t) (intptr_t) name;
109     xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name);
110 
111     cfe_iocb_dispatch(&xiocb);
112 
113     return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.xiocb_handle;
114 }
115 
116 int cfe_close(int handle)
117 {
118     cfe_xiocb_t xiocb;
119 
120     xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE;
121     xiocb.xiocb_status = 0;
122     xiocb.xiocb_handle = handle;
123     xiocb.xiocb_flags = 0;
124     xiocb.xiocb_psize = 0;
125 
126     cfe_iocb_dispatch(&xiocb);
127 
128     return (xiocb.xiocb_status);
129 
130 }
131 
132 int cfe_readblk(int handle,cfe_xint_t offset,u_char *buffer,int length)
133 {
134     cfe_xiocb_t xiocb;
135 
136     xiocb.xiocb_fcode = CFE_CMD_DEV_READ;
137     xiocb.xiocb_status = 0;
138     xiocb.xiocb_handle = handle;
139     xiocb.xiocb_flags = 0;
140     xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
141     xiocb.plist.xiocb_buffer.buf_offset = offset;
142     xiocb.plist.xiocb_buffer.buf_ptr = (cfe_xptr_t) (intptr_t) buffer;
143     xiocb.plist.xiocb_buffer.buf_length = length;
144 
145     cfe_iocb_dispatch(&xiocb);
146 
147     return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.plist.xiocb_buffer.buf_retlen;
148 }
149 
150 int cfe_read(int handle,u_char *buffer,int length)
151 {
152     return cfe_readblk(handle,0,buffer,length);
153 }
154 
155 
156 int cfe_writeblk(int handle,cfe_xint_t offset,u_char *buffer,int length)
157 {
158     cfe_xiocb_t xiocb;
159 
160     xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE;
161     xiocb.xiocb_status = 0;
162     xiocb.xiocb_handle = handle;
163     xiocb.xiocb_flags = 0;
164     xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
165     xiocb.plist.xiocb_buffer.buf_offset = offset;
166     xiocb.plist.xiocb_buffer.buf_ptr = (cfe_xptr_t) (intptr_t) buffer;
167     xiocb.plist.xiocb_buffer.buf_length = length;
168 
169     cfe_iocb_dispatch(&xiocb);
170 
171     return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.plist.xiocb_buffer.buf_retlen;
172 }
173 
174 int cfe_write(int handle,u_char *buffer,int length)
175 {
176     return cfe_writeblk(handle,0,buffer,length);
177 }
178 
179 
180 int cfe_ioctl(int handle,u_int ioctlnum,u_char *buffer,int length,int *retlen)
181 {
182     cfe_xiocb_t xiocb;
183 
184     xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL;
185     xiocb.xiocb_status = 0;
186     xiocb.xiocb_handle = handle;
187     xiocb.xiocb_flags = 0;
188     xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
189     xiocb.plist.xiocb_buffer.buf_ioctlcmd = (cfe_xint_t) ioctlnum;
190     xiocb.plist.xiocb_buffer.buf_ptr = (cfe_xptr_t) (intptr_t) buffer;
191     xiocb.plist.xiocb_buffer.buf_length = length;
192 
193     cfe_iocb_dispatch(&xiocb);
194 
195     if (retlen) *retlen = xiocb.plist.xiocb_buffer.buf_retlen;
196     return xiocb.xiocb_status;
197 }
198 
199 int cfe_inpstat(int handle)
200 {
201     cfe_xiocb_t xiocb;
202 
203     xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT;
204     xiocb.xiocb_status = 0;
205     xiocb.xiocb_handle = handle;
206     xiocb.xiocb_flags = 0;
207     xiocb.xiocb_psize = sizeof(xiocb_inpstat_t);
208     xiocb.plist.xiocb_inpstat.inp_status = 0;
209 
210     cfe_iocb_dispatch(&xiocb);
211 
212     if (xiocb.xiocb_status < 0) return xiocb.xiocb_status;
213 
214     return xiocb.plist.xiocb_inpstat.inp_status;
215 
216 }
217 
218 long long cfe_getticks(void)
219 {
220     cfe_xiocb_t xiocb;
221 
222     xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME;
223     xiocb.xiocb_status = 0;
224     xiocb.xiocb_handle = 0;
225     xiocb.xiocb_flags = 0;
226     xiocb.xiocb_psize = sizeof(xiocb_time_t);
227     xiocb.plist.xiocb_time.ticks = 0;
228 
229     cfe_iocb_dispatch(&xiocb);
230 
231     return xiocb.plist.xiocb_time.ticks;
232 
233 }
234 
235 int cfe_getenv(char *name,char *dest,int destlen)
236 {
237     cfe_xiocb_t xiocb;
238 
239     *dest = 0;
240 
241     xiocb.xiocb_fcode = CFE_CMD_ENV_GET;
242     xiocb.xiocb_status = 0;
243     xiocb.xiocb_handle = 0;
244     xiocb.xiocb_flags = 0;
245     xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
246     xiocb.plist.xiocb_envbuf.enum_idx = 0;
247     xiocb.plist.xiocb_envbuf.name_ptr = (cfe_xptr_t) (intptr_t) name;
248     xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name);
249     xiocb.plist.xiocb_envbuf.val_ptr = (cfe_xptr_t) (intptr_t) dest;
250     xiocb.plist.xiocb_envbuf.val_length = destlen;
251 
252     cfe_iocb_dispatch(&xiocb);
253 
254     return xiocb.xiocb_status;
255 }
256 
257 int cfe_setenv(char *name,char *val)
258 {
259     cfe_xiocb_t xiocb;
260 
261     xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
262     xiocb.xiocb_status = 0;
263     xiocb.xiocb_handle = 0;
264     xiocb.xiocb_flags = 0;
265     xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
266     xiocb.plist.xiocb_envbuf.enum_idx = 0;
267     xiocb.plist.xiocb_envbuf.name_ptr = (cfe_xptr_t) (intptr_t) name;
268     xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name);
269     xiocb.plist.xiocb_envbuf.val_ptr = (cfe_xptr_t) (intptr_t) val;
270     xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val);
271 
272     cfe_iocb_dispatch(&xiocb);
273 
274     return xiocb.xiocb_status;
275 }
276 
277 int cfe_enumenv(int idx,char *name,int namelen,char *val,int vallen)
278 {
279     cfe_xiocb_t xiocb;
280 
281     xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
282     xiocb.xiocb_status = 0;
283     xiocb.xiocb_handle = 0;
284     xiocb.xiocb_flags = 0;
285     xiocb.xiocb_psize = sizeof(xiocb_envbuf_t);
286     xiocb.plist.xiocb_envbuf.enum_idx = idx;
287     xiocb.plist.xiocb_envbuf.name_ptr = (cfe_xptr_t) (intptr_t) name;
288     xiocb.plist.xiocb_envbuf.name_length = namelen;
289     xiocb.plist.xiocb_envbuf.val_ptr = (cfe_xptr_t) (intptr_t) val;
290     xiocb.plist.xiocb_envbuf.val_length = vallen;
291 
292     cfe_iocb_dispatch(&xiocb);
293 
294     return xiocb.xiocb_status;
295 }
296 
297 int cfe_exit(int warm,int status)
298 {
299     cfe_xiocb_t xiocb;
300 
301     xiocb.xiocb_fcode = CFE_CMD_FW_RESTART;
302     xiocb.xiocb_status = 0;
303     xiocb.xiocb_handle = 0;
304     xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0;
305     xiocb.xiocb_psize = sizeof(xiocb_exitstat_t);
306     xiocb.plist.xiocb_exitstat.status = (cfe_xint_t) status;
307 
308     cfe_iocb_dispatch(&xiocb);
309 
310     return (xiocb.xiocb_status);
311 
312 }
313 
314 int cfe_flushcache(int flg)
315 {
316     cfe_xiocb_t xiocb;
317 
318     xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE;
319     xiocb.xiocb_status = 0;
320     xiocb.xiocb_handle = 0;
321     xiocb.xiocb_flags = flg;
322     xiocb.xiocb_psize = 0;
323 
324     cfe_iocb_dispatch(&xiocb);
325 
326     return xiocb.xiocb_status;
327 }
328 
329 int cfe_getstdhandle(int flg)
330 {
331     cfe_xiocb_t xiocb;
332 
333     xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE;
334     xiocb.xiocb_status = 0;
335     xiocb.xiocb_handle = 0;
336     xiocb.xiocb_flags = flg;
337     xiocb.xiocb_psize = 0;
338 
339     cfe_iocb_dispatch(&xiocb);
340 
341     return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : xiocb.xiocb_handle;
342 
343 }
344 
345 int cfe_getdevinfo(char *name)
346 {
347     cfe_xiocb_t xiocb;
348 
349     xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO;
350     xiocb.xiocb_status = 0;
351     xiocb.xiocb_handle = 0;
352     xiocb.xiocb_flags = 0;
353     xiocb.xiocb_psize = sizeof(xiocb_buffer_t);
354     xiocb.plist.xiocb_buffer.buf_offset = 0;
355     xiocb.plist.xiocb_buffer.buf_ptr = (cfe_xptr_t) (intptr_t) name;
356     xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name);
357 
358     cfe_iocb_dispatch(&xiocb);
359 
360     return (xiocb.xiocb_status < 0) ? xiocb.xiocb_status : (int)xiocb.plist.xiocb_buffer.buf_devflags;
361 }
362 
363 int cfe_getmeminfo(int idx,cfe_xuint_t *start,cfe_xuint_t *length,cfe_xuint_t *type)
364 {
365     cfe_xiocb_t xiocb;
366 
367     xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM;
368     xiocb.xiocb_status = 0;
369     xiocb.xiocb_handle = 0;
370     xiocb.xiocb_flags = 0;
371     xiocb.xiocb_psize = sizeof(xiocb_meminfo_t);
372     xiocb.plist.xiocb_meminfo.mi_idx = idx;
373 
374     cfe_iocb_dispatch(&xiocb);
375 
376     if (xiocb.xiocb_status < 0) return xiocb.xiocb_status;
377 
378     *start = xiocb.plist.xiocb_meminfo.mi_addr;
379     *length = xiocb.plist.xiocb_meminfo.mi_size;
380     *type = xiocb.plist.xiocb_meminfo.mi_type;
381 
382     return 0;
383 }
384 
385 int cfe_getfwinfo(xiocb_fwinfo_t *info)
386 {
387     cfe_xiocb_t xiocb;
388 
389     xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO;
390     xiocb.xiocb_status = 0;
391     xiocb.xiocb_handle = 0;
392     xiocb.xiocb_flags = 0;
393     xiocb.xiocb_psize = sizeof(xiocb_fwinfo_t);
394 
395     cfe_iocb_dispatch(&xiocb);
396 
397     if (xiocb.xiocb_status < 0) return xiocb.xiocb_status;
398 
399     info->fwi_version = xiocb.plist.xiocb_fwinfo.fwi_version;
400     info->fwi_totalmem = xiocb.plist.xiocb_fwinfo.fwi_totalmem;
401     info->fwi_flags = xiocb.plist.xiocb_fwinfo.fwi_flags;
402     info->fwi_boardid = xiocb.plist.xiocb_fwinfo.fwi_boardid;
403     info->fwi_bootarea_va = xiocb.plist.xiocb_fwinfo.fwi_bootarea_va;
404     info->fwi_bootarea_pa = xiocb.plist.xiocb_fwinfo.fwi_bootarea_pa;
405     info->fwi_bootarea_size = xiocb.plist.xiocb_fwinfo.fwi_bootarea_size;
406     info->fwi_reserved1 = xiocb.plist.xiocb_fwinfo.fwi_reserved1;
407     info->fwi_reserved2 = xiocb.plist.xiocb_fwinfo.fwi_reserved2;
408     info->fwi_reserved3 = xiocb.plist.xiocb_fwinfo.fwi_reserved3;
409 
410     return 0;
411 }
412