1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * IOCB dispatcher File: cfe_xreq.c
6 * This routine is the main API dispatch for CFE. User API
7 * calls, via the ROM entry point, get dispatched to routines
10 * This module looks similar to cfe_iocb_dispatch - it is different
11 * in that the data structure used, cfe_xiocb_t, uses fixed
12 * size field members (specifically, all 64-bits) no matter how
13 * the firmware is compiled. This ensures a consistent API
14 * interface on any implementation. When you call CFE
15 * from another program, the entry vector comes here first.
17 * Should the normal cfe_iocb interface change, this one should
18 * be kept the same for backward compatibility reasons.
20 * Author: Mitch Lichtenberg (mpl@broadcom.com)
22 *********************************************************************
24 * Copyright 2000,2001,2002,2003
25 * Broadcom Corporation. All rights reserved.
27 * This software is furnished under license and may be used and
28 * copied only in accordance with the following terms and
29 * conditions. Subject to these conditions, you may download,
30 * copy, install, use, modify and distribute modified or unmodified
31 * copies of this software in source and/or binary form. No title
32 * or ownership is transferred hereby.
34 * 1) Any source code used, modified or distributed must reproduce
35 * and retain this copyright notice and list of conditions
36 * as they appear in the source file.
38 * 2) No right is granted to use any trade name, trademark, or
39 * logo of Broadcom Corporation. The "Broadcom Corporation"
40 * name may not be used to endorse or promote products derived
41 * from this software without the prior written permission of
42 * Broadcom Corporation.
44 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
45 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
46 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
47 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
48 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
49 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
50 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
52 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
53 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
54 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
55 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
56 * THE POSSIBILITY OF SUCH DAMAGE.
57 ********************************************************************* */
60 #include "bsp_config.h"
61 #include "lib_types.h"
62 #include "lib_malloc.h"
63 #include "lib_queue.h"
64 #include "lib_printf.h"
65 #include "lib_string.h"
67 #include "cfe_xiocb.h"
68 #if CFG_VENDOR_EXTENSIONS
69 #include "cfe_vendor_iocb.h"
70 #include "cfe_vendor_xiocb.h"
72 #include "cfe_error.h"
73 #include "cfe_device.h"
74 #include "cfe_timer.h"
80 /* *********************************************************************
82 ********************************************************************* */
84 /* enum values for various plist types */
86 #define PLBUF 1 /* iocb_buffer_t */
87 #define PLCPU 2 /* iocb_cpuctl_t */
88 #define PLMEM 3 /* iocb_meminfo_t */
89 #define PLENV 4 /* iocb_envbuf_t */
90 #define PLINP 5 /* iocb_inpstat_t */
91 #define PLTIM 6 /* iocb_time_t */
92 #define PLINF 7 /* iocb_fwinfo_t */
93 #define PLEXIT 8 /* iocb_exitstat_t */
95 /* *********************************************************************
97 ********************************************************************* */
99 struct cfe_xcmd_dispatch_s
{
106 /* *********************************************************************
107 * Command conversion table
108 * This table contains useful information for converting
110 ********************************************************************* */
112 const static struct cfe_xcmd_dispatch_s cfe_xcmd_dispatch_table
[CFE_CMD_MAX
] = {
113 {sizeof(xiocb_fwinfo_t
), sizeof(iocb_fwinfo_t
), PLINF
}, /* 0 : CFE_CMD_FW_GETINFO */
114 {sizeof(xiocb_exitstat_t
),sizeof(iocb_exitstat_t
),PLEXIT
}, /* 1 : CFE_CMD_FW_RESTART */
115 {sizeof(xiocb_buffer_t
), sizeof(iocb_buffer_t
), PLBUF
}, /* 2 : CFE_CMD_FW_BOOT */
116 {sizeof(xiocb_cpuctl_t
), sizeof(iocb_cpuctl_t
), PLCPU
}, /* 3 : CFE_CMD_FW_CPUCTL */
117 {sizeof(xiocb_time_t
), sizeof(iocb_time_t
), PLTIM
}, /* 4 : CFE_CMD_FW_GETTIME */
118 {sizeof(xiocb_meminfo_t
),sizeof(iocb_meminfo_t
),PLMEM
}, /* 5 : CFE_CMD_FW_MEMENUM */
119 {0, 0, 0}, /* 6 : CFE_CMD_FW_FLUSHCACHE */
120 {-1, 0, 0}, /* 7 : */
121 {-1, 0, 0}, /* 8 : */
122 {0, 0, 0}, /* 9 : CFE_CMD_DEV_GETHANDLE */
123 {sizeof(xiocb_envbuf_t
), sizeof(iocb_envbuf_t
), PLENV
}, /* 10 : CFE_CMD_DEV_ENUM */
124 {sizeof(xiocb_buffer_t
), sizeof(iocb_buffer_t
), PLBUF
}, /* 11 : CFE_CMD_DEV_OPEN_*/
125 {sizeof(xiocb_inpstat_t
),sizeof(iocb_inpstat_t
),PLINP
}, /* 12 : CFE_CMD_DEV_INPSTAT */
126 {sizeof(xiocb_buffer_t
), sizeof(iocb_buffer_t
), PLBUF
}, /* 13 : CFE_CMD_DEV_READ */
127 {sizeof(xiocb_buffer_t
), sizeof(iocb_buffer_t
), PLBUF
}, /* 14 : CFE_CMD_DEV_WRITE */
128 {sizeof(xiocb_buffer_t
), sizeof(iocb_buffer_t
), PLBUF
}, /* 15 : CFE_CMD_DEV_IOCTL */
129 {0, 0, 0}, /* 16 : CFE_CMD_DEV_CLOSE */
130 {sizeof(xiocb_buffer_t
), sizeof(iocb_buffer_t
), PLBUF
}, /* 17 : CFE_CMD_DEV_GETINFO */
131 {-1, 0, 0}, /* 18 : */
132 {-1, 0, 0}, /* 19 : */
133 {sizeof(xiocb_envbuf_t
), sizeof(iocb_envbuf_t
), PLENV
}, /* 20 : CFE_CMD_ENV_ENUM */
134 {-1, 0, 0}, /* 21 : */
135 {sizeof(xiocb_envbuf_t
), sizeof(iocb_envbuf_t
), PLENV
}, /* 22 : CFE_CMD_ENV_GET */
136 {sizeof(xiocb_envbuf_t
), sizeof(iocb_envbuf_t
), PLENV
}, /* 23 : CFE_CMD_ENV_SET */
137 {sizeof(xiocb_envbuf_t
), sizeof(iocb_envbuf_t
), PLENV
}, /* 24 : CFE_CMD_ENV_DEL */
138 {-1, 0, 0}, /* 25 : */
139 {-1, 0, 0}, /* 26 : */
140 {-1, 0, 0}, /* 27 : */
141 {-1, 0, 0}, /* 28 : */
142 {-1, 0, 0}, /* 29 : */
143 {-1, 0, 0}, /* 30 : */
144 {-1, 0, 0} /* 31 : */
148 /* *********************************************************************
150 ********************************************************************* */
152 extern int cfe_iocb_dispatch(cfe_iocb_t
*iocb
);
153 cfe_int_t
cfe_doxreq(cfe_xiocb_t
*xiocb
);
154 #if CFG_VENDOR_EXTENSIONS
155 extern cfe_int_t
cfe_vendor_doxreq(cfe_vendor_xiocb_t
*xiocb
);
158 /* *********************************************************************
161 * Process an xiocb request. This routine converts an xiocb
162 * into an iocb, calls the IOCB dispatcher, converts the results
163 * back into the xiocb, and returns.
166 * xiocb - pointer to user xiocb
169 * command status, <0 if error occured
170 ********************************************************************* */
172 cfe_int_t
cfe_doxreq(cfe_xiocb_t
*xiocb
)
174 const struct cfe_xcmd_dispatch_s
*disp
;
179 * Call out to customer-specific IOCBs. Customers may choose
180 * to implement their own XIOCBs directly, or go through their own
181 * translation layer (xiocb->iocb like CFE does) to insulate
182 * themselves from IOCB changes in the future.
184 if (xiocb
->xiocb_fcode
>= CFE_CMD_VENDOR_USE
) {
185 #if CFG_VENDOR_EXTENSIONS
186 return cfe_vendor_doxreq((cfe_vendor_xiocb_t
*)xiocb
);
188 return CFE_ERR_INV_COMMAND
;
193 * Check for commands codes out of range
196 if ((xiocb
->xiocb_fcode
< 0) || (xiocb
->xiocb_fcode
>= CFE_CMD_MAX
)) {
197 xiocb
->xiocb_status
= CFE_ERR_INV_COMMAND
;
198 return xiocb
->xiocb_status
;
202 * Check for command codes in range but invalid
205 disp
= &cfe_xcmd_dispatch_table
[xiocb
->xiocb_fcode
];
207 if (disp
->xplistsize
< 0) {
208 xiocb
->xiocb_status
= CFE_ERR_INV_COMMAND
;
209 return xiocb
->xiocb_status
;
213 * Check for invalid parameter list size
216 if (disp
->xplistsize
!= xiocb
->xiocb_psize
) {
217 xiocb
->xiocb_status
= CFE_ERR_INV_PARAM
;
218 return xiocb
->xiocb_status
;
222 * Okay, copy parameters into the internal IOCB.
223 * First, the fixed header.
226 iiocb
.iocb_fcode
= (unsigned int) xiocb
->xiocb_fcode
;
227 iiocb
.iocb_status
= (int) xiocb
->xiocb_status
;
228 iiocb
.iocb_handle
= (int) xiocb
->xiocb_handle
;
229 iiocb
.iocb_flags
= (unsigned int) xiocb
->xiocb_flags
;
230 iiocb
.iocb_psize
= (unsigned int) disp
->iplistsize
;
233 * Now the parameter list
236 switch (disp
->plisttype
) {
238 iiocb
.plist
.iocb_buffer
.buf_offset
= (cfe_offset_t
) xiocb
->plist
.xiocb_buffer
.buf_offset
;
239 iiocb
.plist
.iocb_buffer
.buf_ptr
= (unsigned char *) (uintptr_t) xiocb
->plist
.xiocb_buffer
.buf_ptr
;
240 iiocb
.plist
.iocb_buffer
.buf_length
= (unsigned int) xiocb
->plist
.xiocb_buffer
.buf_length
;
241 iiocb
.plist
.iocb_buffer
.buf_retlen
= (unsigned int) xiocb
->plist
.xiocb_buffer
.buf_retlen
;
242 iiocb
.plist
.iocb_buffer
.buf_ioctlcmd
= (unsigned int) xiocb
->plist
.xiocb_buffer
.buf_ioctlcmd
;
245 iiocb
.plist
.iocb_cpuctl
.cpu_number
= (unsigned int) xiocb
->plist
.xiocb_cpuctl
.cpu_number
;
246 iiocb
.plist
.iocb_cpuctl
.cpu_command
= (unsigned int) xiocb
->plist
.xiocb_cpuctl
.cpu_command
;
247 iiocb
.plist
.iocb_cpuctl
.start_addr
= (unsigned long) xiocb
->plist
.xiocb_cpuctl
.start_addr
;
248 iiocb
.plist
.iocb_cpuctl
.gp_val
= (unsigned long) xiocb
->plist
.xiocb_cpuctl
.gp_val
;
249 iiocb
.plist
.iocb_cpuctl
.sp_val
= (unsigned long) xiocb
->plist
.xiocb_cpuctl
.sp_val
;
250 iiocb
.plist
.iocb_cpuctl
.a1_val
= (unsigned long) xiocb
->plist
.xiocb_cpuctl
.a1_val
;
253 iiocb
.plist
.iocb_meminfo
.mi_idx
= (int) xiocb
->plist
.xiocb_meminfo
.mi_idx
;
254 iiocb
.plist
.iocb_meminfo
.mi_type
= (int) xiocb
->plist
.xiocb_meminfo
.mi_type
;
255 iiocb
.plist
.iocb_meminfo
.mi_addr
= (unsigned long long) xiocb
->plist
.xiocb_meminfo
.mi_addr
;
256 iiocb
.plist
.iocb_meminfo
.mi_size
= (unsigned long long) xiocb
->plist
.xiocb_meminfo
.mi_size
;
259 iiocb
.plist
.iocb_envbuf
.enum_idx
= (int) xiocb
->plist
.xiocb_envbuf
.enum_idx
;
260 iiocb
.plist
.iocb_envbuf
.name_ptr
= (unsigned char *) (uintptr_t) xiocb
->plist
.xiocb_envbuf
.name_ptr
;
261 iiocb
.plist
.iocb_envbuf
.name_length
= (int) xiocb
->plist
.xiocb_envbuf
.name_length
;
262 iiocb
.plist
.iocb_envbuf
.val_ptr
= (unsigned char *) (uintptr_t) xiocb
->plist
.xiocb_envbuf
.val_ptr
;
263 iiocb
.plist
.iocb_envbuf
.val_length
= (int) xiocb
->plist
.xiocb_envbuf
.val_length
;
266 iiocb
.plist
.iocb_inpstat
.inp_status
= (int) xiocb
->plist
.xiocb_inpstat
.inp_status
;
269 iiocb
.plist
.iocb_time
.ticks
= (long long) xiocb
->plist
.xiocb_time
.ticks
;
274 iiocb
.plist
.iocb_exitstat
.status
= (long long) xiocb
->plist
.xiocb_exitstat
.status
;
279 * Do the internal function dispatch
282 res
= (cfe_int_t
) cfe_iocb_dispatch(&iiocb
);
285 * Now convert the parameter list members back
288 switch (disp
->plisttype
) {
290 xiocb
->plist
.xiocb_buffer
.buf_offset
= (cfe_uint_t
) iiocb
.plist
.iocb_buffer
.buf_offset
;
291 xiocb
->plist
.xiocb_buffer
.buf_ptr
= (cfe_xptr_t
) (uintptr_t) iiocb
.plist
.iocb_buffer
.buf_ptr
;
292 xiocb
->plist
.xiocb_buffer
.buf_length
= (cfe_uint_t
) iiocb
.plist
.iocb_buffer
.buf_length
;
293 xiocb
->plist
.xiocb_buffer
.buf_retlen
= (cfe_uint_t
) iiocb
.plist
.iocb_buffer
.buf_retlen
;
294 xiocb
->plist
.xiocb_buffer
.buf_ioctlcmd
= (cfe_uint_t
) iiocb
.plist
.iocb_buffer
.buf_ioctlcmd
;
297 xiocb
->plist
.xiocb_cpuctl
.cpu_number
= (cfe_uint_t
) iiocb
.plist
.iocb_cpuctl
.cpu_number
;
298 xiocb
->plist
.xiocb_cpuctl
.cpu_command
= (cfe_uint_t
) iiocb
.plist
.iocb_cpuctl
.cpu_command
;
299 xiocb
->plist
.xiocb_cpuctl
.start_addr
= (cfe_uint_t
) iiocb
.plist
.iocb_cpuctl
.start_addr
;
302 xiocb
->plist
.xiocb_meminfo
.mi_idx
= (cfe_int_t
) iiocb
.plist
.iocb_meminfo
.mi_idx
;
303 xiocb
->plist
.xiocb_meminfo
.mi_type
= (cfe_int_t
) iiocb
.plist
.iocb_meminfo
.mi_type
;
304 xiocb
->plist
.xiocb_meminfo
.mi_addr
= (cfe_int64_t
) iiocb
.plist
.iocb_meminfo
.mi_addr
;
305 xiocb
->plist
.xiocb_meminfo
.mi_size
= (cfe_int64_t
) iiocb
.plist
.iocb_meminfo
.mi_size
;
308 xiocb
->plist
.xiocb_envbuf
.enum_idx
= (cfe_int_t
) iiocb
.plist
.iocb_envbuf
.enum_idx
;
309 xiocb
->plist
.xiocb_envbuf
.name_ptr
= (cfe_xptr_t
) (uintptr_t) iiocb
.plist
.iocb_envbuf
.name_ptr
;
310 xiocb
->plist
.xiocb_envbuf
.name_length
= (cfe_int_t
) iiocb
.plist
.iocb_envbuf
.name_length
;
311 xiocb
->plist
.xiocb_envbuf
.val_ptr
= (cfe_xptr_t
) (uintptr_t) iiocb
.plist
.iocb_envbuf
.val_ptr
;
312 xiocb
->plist
.xiocb_envbuf
.val_length
= (cfe_int_t
) iiocb
.plist
.iocb_envbuf
.val_length
;
315 xiocb
->plist
.xiocb_inpstat
.inp_status
= (cfe_int_t
) iiocb
.plist
.iocb_inpstat
.inp_status
;
318 xiocb
->plist
.xiocb_time
.ticks
= (cfe_int_t
) iiocb
.plist
.iocb_time
.ticks
;
321 xiocb
->plist
.xiocb_fwinfo
.fwi_version
= iiocb
.plist
.iocb_fwinfo
.fwi_version
;
322 xiocb
->plist
.xiocb_fwinfo
.fwi_totalmem
= iiocb
.plist
.iocb_fwinfo
.fwi_totalmem
;
323 xiocb
->plist
.xiocb_fwinfo
.fwi_flags
= iiocb
.plist
.iocb_fwinfo
.fwi_flags
;
324 xiocb
->plist
.xiocb_fwinfo
.fwi_boardid
= iiocb
.plist
.iocb_fwinfo
.fwi_boardid
;
325 xiocb
->plist
.xiocb_fwinfo
.fwi_bootarea_va
= iiocb
.plist
.iocb_fwinfo
.fwi_bootarea_va
;
326 xiocb
->plist
.xiocb_fwinfo
.fwi_bootarea_pa
= iiocb
.plist
.iocb_fwinfo
.fwi_bootarea_pa
;
327 xiocb
->plist
.xiocb_fwinfo
.fwi_bootarea_size
= iiocb
.plist
.iocb_fwinfo
.fwi_bootarea_size
;
328 xiocb
->plist
.xiocb_fwinfo
.fwi_reserved1
= iiocb
.plist
.iocb_fwinfo
.fwi_reserved1
;
329 xiocb
->plist
.xiocb_fwinfo
.fwi_reserved2
= iiocb
.plist
.iocb_fwinfo
.fwi_reserved2
;
330 xiocb
->plist
.xiocb_fwinfo
.fwi_reserved3
= iiocb
.plist
.iocb_fwinfo
.fwi_reserved3
;
333 xiocb
->plist
.xiocb_exitstat
.status
= (cfe_int_t
) iiocb
.plist
.iocb_exitstat
.status
;
338 * And the fixed header
341 xiocb
->xiocb_status
= (cfe_int_t
) iiocb
.iocb_status
;
342 xiocb
->xiocb_handle
= (cfe_int_t
) iiocb
.iocb_handle
;
343 xiocb
->xiocb_flags
= (cfe_uint_t
) iiocb
.iocb_flags
;
345 return xiocb
->xiocb_status
;