1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * IOCB dispatcher File: cfe_xreq.c 5 * 6 * This routine is the main API dispatch for CFE. User API 7 * calls, via the ROM entry point, get dispatched to routines 8 * in this module. 9 * 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. 16 * 17 * Should the normal cfe_iocb interface change, this one should 18 * be kept the same for backward compatibility reasons. 19 * 20 * Author: Mitch Lichtenberg (mpl@broadcom.com) 21 * 22 ********************************************************************* 23 * 24 * Copyright 2000,2001,2002,2003 25 * Broadcom Corporation. All rights reserved. 26 * 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. 33 * 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. 37 * 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. 43 * 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 ********************************************************************* */ 58 59 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" 66#include "cfe_iocb.h" 67#include "cfe_xiocb.h" 68#if CFG_VENDOR_EXTENSIONS 69#include "cfe_vendor_iocb.h" 70#include "cfe_vendor_xiocb.h" 71#endif 72#include "cfe_error.h" 73#include "cfe_device.h" 74#include "cfe_timer.h" 75#include "cfe_mem.h" 76#include "env_subr.h" 77#include "cfe.h" 78 79 80/* ********************************************************************* 81 * Constants 82 ********************************************************************* */ 83 84/* enum values for various plist types */ 85 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 */ 94 95/* ********************************************************************* 96 * Structures 97 ********************************************************************* */ 98 99struct cfe_xcmd_dispatch_s { 100 int xplistsize; 101 int iplistsize; 102 int plisttype; 103}; 104 105 106/* ********************************************************************* 107 * Command conversion table 108 * This table contains useful information for converting 109 * iocbs to xiocbs. 110 ********************************************************************* */ 111 112const 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 : */ 145}; 146 147 148/* ********************************************************************* 149 * Externs 150 ********************************************************************* */ 151 152extern int cfe_iocb_dispatch(cfe_iocb_t *iocb); 153cfe_int_t cfe_doxreq(cfe_xiocb_t *xiocb); 154#if CFG_VENDOR_EXTENSIONS 155extern cfe_int_t cfe_vendor_doxreq(cfe_vendor_xiocb_t *xiocb); 156#endif 157 158/* ********************************************************************* 159 * cfe_doxreq(xiocb) 160 * 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. 164 * 165 * Input parameters: 166 * xiocb - pointer to user xiocb 167 * 168 * Return value: 169 * command status, <0 if error occured 170 ********************************************************************* */ 171 172cfe_int_t cfe_doxreq(cfe_xiocb_t *xiocb) 173{ 174 const struct cfe_xcmd_dispatch_s *disp; 175 cfe_iocb_t iiocb; 176 cfe_int_t res; 177 178 /* 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. 183 */ 184 if (xiocb->xiocb_fcode >= CFE_CMD_VENDOR_USE) { 185#if CFG_VENDOR_EXTENSIONS 186 return cfe_vendor_doxreq((cfe_vendor_xiocb_t *)xiocb); 187#else 188 return CFE_ERR_INV_COMMAND; 189#endif 190 } 191 192 /* 193 * Check for commands codes out of range 194 */ 195 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; 199 } 200 201 /* 202 * Check for command codes in range but invalid 203 */ 204 205 disp = &cfe_xcmd_dispatch_table[xiocb->xiocb_fcode]; 206 207 if (disp->xplistsize < 0) { 208 xiocb->xiocb_status = CFE_ERR_INV_COMMAND; 209 return xiocb->xiocb_status; 210 } 211 212 /* 213 * Check for invalid parameter list size 214 */ 215 216 if (disp->xplistsize != xiocb->xiocb_psize) { 217 xiocb->xiocb_status = CFE_ERR_INV_PARAM; 218 return xiocb->xiocb_status; 219 } 220 221 /* 222 * Okay, copy parameters into the internal IOCB. 223 * First, the fixed header. 224 */ 225 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; 231 232 /* 233 * Now the parameter list 234 */ 235 236 switch (disp->plisttype) { 237 case PLBUF: 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; 243 break; 244 case PLCPU: 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; 251 break; 252 case PLMEM: 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; 257 break; 258 case PLENV: 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; 264 break; 265 case PLINP: 266 iiocb.plist.iocb_inpstat.inp_status = (int) xiocb->plist.xiocb_inpstat.inp_status; 267 break; 268 case PLTIM: 269 iiocb.plist.iocb_time.ticks = (long long) xiocb->plist.xiocb_time.ticks; 270 break; 271 case PLINF: 272 break; 273 case PLEXIT: 274 iiocb.plist.iocb_exitstat.status = (long long) xiocb->plist.xiocb_exitstat.status; 275 break; 276 } 277 278 /* 279 * Do the internal function dispatch 280 */ 281 282 res = (cfe_int_t) cfe_iocb_dispatch(&iiocb); 283 284 /* 285 * Now convert the parameter list members back 286 */ 287 288 switch (disp->plisttype) { 289 case PLBUF: 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; 295 break; 296 case PLCPU: 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; 300 break; 301 case PLMEM: 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; 306 break; 307 case PLENV: 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; 313 break; 314 case PLINP: 315 xiocb->plist.xiocb_inpstat.inp_status = (cfe_int_t) iiocb.plist.iocb_inpstat.inp_status; 316 break; 317 case PLTIM: 318 xiocb->plist.xiocb_time.ticks = (cfe_int_t) iiocb.plist.iocb_time.ticks; 319 break; 320 case PLINF: 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; 331 break; 332 case PLEXIT: 333 xiocb->plist.xiocb_exitstat.status = (cfe_int_t) iiocb.plist.iocb_exitstat.status; 334 break; 335 } 336 337 /* 338 * And the fixed header 339 */ 340 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; 344 345 return xiocb->xiocb_status; 346} 347