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