1/* 2 * Copyright (C) 2000, 2001, 2002 Broadcom Corporation 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 */ 18 19/* ********************************************************************* 20 * 21 * Broadcom Common Firmware Environment (CFE) 22 * 23 * Device Function stubs File: cfe_api.c 24 * 25 * This module contains device function stubs (small routines to 26 * call the standard "iocb" interface entry point to CFE). 27 * There should be one routine here per iocb function call. 28 * 29 * Authors: Mitch Lichtenberg, Chris Demetriou 30 * 31 ********************************************************************* */ 32 33#include "cfe_api.h" 34#include "cfe_api_int.h" 35 36/* Cast from a native pointer to a cfe_xptr_t and back. */ 37#define XPTR_FROM_NATIVE(n) ((cfe_xptr_t) (intptr_t) (n)) 38#define NATIVE_FROM_XPTR(x) ((void *) (intptr_t) (x)) 39 40#ifdef CFE_API_IMPL_NAMESPACE 41#define cfe_iocb_dispatch(a) __cfe_iocb_dispatch(a) 42#endif 43int cfe_iocb_dispatch(cfe_xiocb_t * xiocb); 44 45#if defined(CFE_API_common) || defined(CFE_API_ALL) 46/* 47 * Declare the dispatch function with args of "intptr_t". 48 * This makes sure whatever model we're compiling in 49 * puts the pointers in a single register. For example, 50 * combining -mlong64 and -mips1 or -mips2 would lead to 51 * trouble, since the handle and IOCB pointer will be 52 * passed in two registers each, and CFE expects one. 53 */ 54 55static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb) = 0; 56static cfe_xuint_t cfe_handle = 0; 57 58int cfe_init(cfe_xuint_t handle, cfe_xuint_t ept) 59{ 60 cfe_dispfunc = NATIVE_FROM_XPTR(ept); 61 cfe_handle = handle; 62 return 0; 63} 64 65int cfe_iocb_dispatch(cfe_xiocb_t * xiocb) 66{ 67 if (!cfe_dispfunc) 68 return -1; 69 return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb); 70} 71#endif /* CFE_API_common || CFE_API_ALL */ 72 73#if defined(CFE_API_close) || defined(CFE_API_ALL) 74int cfe_close(int handle) 75{ 76 cfe_xiocb_t xiocb; 77 78 xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE; 79 xiocb.xiocb_status = 0; 80 xiocb.xiocb_handle = handle; 81 xiocb.xiocb_flags = 0; 82 xiocb.xiocb_psize = 0; 83 84 cfe_iocb_dispatch(&xiocb); 85 86 return xiocb.xiocb_status; 87 88} 89#endif /* CFE_API_close || CFE_API_ALL */ 90 91#if defined(CFE_API_cpu_start) || defined(CFE_API_ALL) 92int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1) 93{ 94 cfe_xiocb_t xiocb; 95 96 xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; 97 xiocb.xiocb_status = 0; 98 xiocb.xiocb_handle = 0; 99 xiocb.xiocb_flags = 0; 100 xiocb.xiocb_psize = sizeof(xiocb_cpuctl_t); 101 xiocb.plist.xiocb_cpuctl.cpu_number = cpu; 102 xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START; 103 xiocb.plist.xiocb_cpuctl.gp_val = gp; 104 xiocb.plist.xiocb_cpuctl.sp_val = sp; 105 xiocb.plist.xiocb_cpuctl.a1_val = a1; 106 xiocb.plist.xiocb_cpuctl.start_addr = (long) fn; 107 108 cfe_iocb_dispatch(&xiocb); 109 110 return xiocb.xiocb_status; 111} 112#endif /* CFE_API_cpu_start || CFE_API_ALL */ 113 114#if defined(CFE_API_cpu_stop) || defined(CFE_API_ALL) 115int cfe_cpu_stop(int cpu) 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_STOP; 126 127 cfe_iocb_dispatch(&xiocb); 128 129 return xiocb.xiocb_status; 130} 131#endif /* CFE_API_cpu_stop || CFE_API_ALL */ 132 133#if defined(CFE_API_enumenv) || defined(CFE_API_ALL) 134int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen) 135{ 136 cfe_xiocb_t xiocb; 137 138 xiocb.xiocb_fcode = CFE_CMD_ENV_SET; 139 xiocb.xiocb_status = 0; 140 xiocb.xiocb_handle = 0; 141 xiocb.xiocb_flags = 0; 142 xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); 143 xiocb.plist.xiocb_envbuf.enum_idx = idx; 144 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 145 xiocb.plist.xiocb_envbuf.name_length = namelen; 146 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); 147 xiocb.plist.xiocb_envbuf.val_length = vallen; 148 149 cfe_iocb_dispatch(&xiocb); 150 151 return xiocb.xiocb_status; 152} 153#endif /* CFE_API_enumenv || CFE_API_ALL */ 154 155#if defined(CFE_API_enummem) || defined(CFE_API_ALL) 156int 157cfe_enummem(int idx, int flags, cfe_xuint_t * start, cfe_xuint_t * length, 158 cfe_xuint_t * type) 159{ 160 cfe_xiocb_t xiocb; 161 162 xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM; 163 xiocb.xiocb_status = 0; 164 xiocb.xiocb_handle = 0; 165 xiocb.xiocb_flags = flags; 166 xiocb.xiocb_psize = sizeof(xiocb_meminfo_t); 167 xiocb.plist.xiocb_meminfo.mi_idx = idx; 168 169 cfe_iocb_dispatch(&xiocb); 170 171 if (xiocb.xiocb_status < 0) 172 return xiocb.xiocb_status; 173 174 *start = xiocb.plist.xiocb_meminfo.mi_addr; 175 *length = xiocb.plist.xiocb_meminfo.mi_size; 176 *type = xiocb.plist.xiocb_meminfo.mi_type; 177 178 return 0; 179} 180#endif /* CFE_API_enummem || CFE_API_ALL */ 181 182#if defined(CFE_API_exit) || defined(CFE_API_ALL) 183int cfe_exit(int warm, int status) 184{ 185 cfe_xiocb_t xiocb; 186 187 xiocb.xiocb_fcode = CFE_CMD_FW_RESTART; 188 xiocb.xiocb_status = 0; 189 xiocb.xiocb_handle = 0; 190 xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0; 191 xiocb.xiocb_psize = sizeof(xiocb_exitstat_t); 192 xiocb.plist.xiocb_exitstat.status = status; 193 194 cfe_iocb_dispatch(&xiocb); 195 196 return xiocb.xiocb_status; 197} 198#endif /* CFE_API_exit || CFE_API_ALL */ 199 200#if defined(CFE_API_flushcache) || defined(CFE_API_ALL) 201int cfe_flushcache(int flg) 202{ 203 cfe_xiocb_t xiocb; 204 205 xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE; 206 xiocb.xiocb_status = 0; 207 xiocb.xiocb_handle = 0; 208 xiocb.xiocb_flags = flg; 209 xiocb.xiocb_psize = 0; 210 211 cfe_iocb_dispatch(&xiocb); 212 213 return xiocb.xiocb_status; 214} 215#endif /* CFE_API_flushcache || CFE_API_ALL */ 216 217#if defined(CFE_API_getdevinfo) || defined(CFE_API_ALL) 218int cfe_getdevinfo(char *name) 219{ 220 cfe_xiocb_t xiocb; 221 222 xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO; 223 xiocb.xiocb_status = 0; 224 xiocb.xiocb_handle = 0; 225 xiocb.xiocb_flags = 0; 226 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 227 xiocb.plist.xiocb_buffer.buf_offset = 0; 228 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); 229 xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); 230 231 cfe_iocb_dispatch(&xiocb); 232 233 if (xiocb.xiocb_status < 0) 234 return xiocb.xiocb_status; 235 return xiocb.plist.xiocb_buffer.buf_devflags; 236} 237#endif /* CFE_API_getdevinfo || CFE_API_ALL */ 238 239#if defined(CFE_API_getenv) || defined(CFE_API_ALL) 240int cfe_getenv(char *name, char *dest, int destlen) 241{ 242 cfe_xiocb_t xiocb; 243 244 *dest = 0; 245 246 xiocb.xiocb_fcode = CFE_CMD_ENV_GET; 247 xiocb.xiocb_status = 0; 248 xiocb.xiocb_handle = 0; 249 xiocb.xiocb_flags = 0; 250 xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); 251 xiocb.plist.xiocb_envbuf.enum_idx = 0; 252 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 253 xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); 254 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest); 255 xiocb.plist.xiocb_envbuf.val_length = destlen; 256 257 cfe_iocb_dispatch(&xiocb); 258 259 return xiocb.xiocb_status; 260} 261#endif /* CFE_API_getenv || CFE_API_ALL */ 262 263#if defined(CFE_API_getfwinfo) || defined(CFE_API_ALL) 264int cfe_getfwinfo(cfe_fwinfo_t * info) 265{ 266 cfe_xiocb_t xiocb; 267 268 xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO; 269 xiocb.xiocb_status = 0; 270 xiocb.xiocb_handle = 0; 271 xiocb.xiocb_flags = 0; 272 xiocb.xiocb_psize = sizeof(xiocb_fwinfo_t); 273 274 cfe_iocb_dispatch(&xiocb); 275 276 if (xiocb.xiocb_status < 0) 277 return xiocb.xiocb_status; 278 279 info->fwi_version = xiocb.plist.xiocb_fwinfo.fwi_version; 280 info->fwi_totalmem = xiocb.plist.xiocb_fwinfo.fwi_totalmem; 281 info->fwi_flags = xiocb.plist.xiocb_fwinfo.fwi_flags; 282 info->fwi_boardid = xiocb.plist.xiocb_fwinfo.fwi_boardid; 283 info->fwi_bootarea_va = xiocb.plist.xiocb_fwinfo.fwi_bootarea_va; 284 info->fwi_bootarea_pa = xiocb.plist.xiocb_fwinfo.fwi_bootarea_pa; 285 info->fwi_bootarea_size = 286 xiocb.plist.xiocb_fwinfo.fwi_bootarea_size; 287 288 return 0; 289} 290#endif /* CFE_API_getfwinfo || CFE_API_ALL */ 291 292#if defined(CFE_API_getstdhandle) || defined(CFE_API_ALL) 293int cfe_getstdhandle(int flg) 294{ 295 cfe_xiocb_t xiocb; 296 297 xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE; 298 xiocb.xiocb_status = 0; 299 xiocb.xiocb_handle = 0; 300 xiocb.xiocb_flags = flg; 301 xiocb.xiocb_psize = 0; 302 303 cfe_iocb_dispatch(&xiocb); 304 305 if (xiocb.xiocb_status < 0) 306 return xiocb.xiocb_status; 307 return xiocb.xiocb_handle; 308} 309#endif /* CFE_API_getstdhandle || CFE_API_ALL */ 310 311#if defined(CFE_API_getticks) || defined(CFE_API_ALL) 312int64_t 313#ifdef CFE_API_IMPL_NAMESPACE 314__cfe_getticks(void) 315#else 316cfe_getticks(void) 317#endif 318{ 319 cfe_xiocb_t xiocb; 320 321 xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME; 322 xiocb.xiocb_status = 0; 323 xiocb.xiocb_handle = 0; 324 xiocb.xiocb_flags = 0; 325 xiocb.xiocb_psize = sizeof(xiocb_time_t); 326 xiocb.plist.xiocb_time.ticks = 0; 327 328 cfe_iocb_dispatch(&xiocb); 329 330 return xiocb.plist.xiocb_time.ticks; 331 332} 333#endif /* CFE_API_getticks || CFE_API_ALL */ 334 335#if defined(CFE_API_inpstat) || defined(CFE_API_ALL) 336int cfe_inpstat(int handle) 337{ 338 cfe_xiocb_t xiocb; 339 340 xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT; 341 xiocb.xiocb_status = 0; 342 xiocb.xiocb_handle = handle; 343 xiocb.xiocb_flags = 0; 344 xiocb.xiocb_psize = sizeof(xiocb_inpstat_t); 345 xiocb.plist.xiocb_inpstat.inp_status = 0; 346 347 cfe_iocb_dispatch(&xiocb); 348 349 if (xiocb.xiocb_status < 0) 350 return xiocb.xiocb_status; 351 return xiocb.plist.xiocb_inpstat.inp_status; 352} 353#endif /* CFE_API_inpstat || CFE_API_ALL */ 354 355#if defined(CFE_API_ioctl) || defined(CFE_API_ALL) 356int 357cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer, 358 int length, int *retlen, cfe_xuint_t offset) 359{ 360 cfe_xiocb_t xiocb; 361 362 xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL; 363 xiocb.xiocb_status = 0; 364 xiocb.xiocb_handle = handle; 365 xiocb.xiocb_flags = 0; 366 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 367 xiocb.plist.xiocb_buffer.buf_offset = offset; 368 xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum; 369 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 370 xiocb.plist.xiocb_buffer.buf_length = length; 371 372 cfe_iocb_dispatch(&xiocb); 373 374 if (retlen) 375 *retlen = xiocb.plist.xiocb_buffer.buf_retlen; 376 return xiocb.xiocb_status; 377} 378#endif /* CFE_API_ioctl || CFE_API_ALL */ 379 380#if defined(CFE_API_open) || defined(CFE_API_ALL) 381int cfe_open(char *name) 382{ 383 cfe_xiocb_t xiocb; 384 385 xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN; 386 xiocb.xiocb_status = 0; 387 xiocb.xiocb_handle = 0; 388 xiocb.xiocb_flags = 0; 389 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 390 xiocb.plist.xiocb_buffer.buf_offset = 0; 391 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); 392 xiocb.plist.xiocb_buffer.buf_length = cfe_strlen(name); 393 394 cfe_iocb_dispatch(&xiocb); 395 396 if (xiocb.xiocb_status < 0) 397 return xiocb.xiocb_status; 398 return xiocb.xiocb_handle; 399} 400#endif /* CFE_API_open || CFE_API_ALL */ 401 402#if defined(CFE_API_read) || defined(CFE_API_ALL) 403int cfe_read(int handle, unsigned char *buffer, int length) 404{ 405 return cfe_readblk(handle, 0, buffer, length); 406} 407#endif /* CFE_API_read || CFE_API_ALL */ 408 409#if defined(CFE_API_readblk) || defined(CFE_API_ALL) 410int 411cfe_readblk(int handle, cfe_xint_t offset, unsigned char *buffer, 412 int length) 413{ 414 cfe_xiocb_t xiocb; 415 416 xiocb.xiocb_fcode = CFE_CMD_DEV_READ; 417 xiocb.xiocb_status = 0; 418 xiocb.xiocb_handle = handle; 419 xiocb.xiocb_flags = 0; 420 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 421 xiocb.plist.xiocb_buffer.buf_offset = offset; 422 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 423 xiocb.plist.xiocb_buffer.buf_length = length; 424 425 cfe_iocb_dispatch(&xiocb); 426 427 if (xiocb.xiocb_status < 0) 428 return xiocb.xiocb_status; 429 return xiocb.plist.xiocb_buffer.buf_retlen; 430} 431#endif /* CFE_API_readblk || CFE_API_ALL */ 432 433#if defined(CFE_API_setenv) || defined(CFE_API_ALL) 434int cfe_setenv(char *name, char *val) 435{ 436 cfe_xiocb_t xiocb; 437 438 xiocb.xiocb_fcode = CFE_CMD_ENV_SET; 439 xiocb.xiocb_status = 0; 440 xiocb.xiocb_handle = 0; 441 xiocb.xiocb_flags = 0; 442 xiocb.xiocb_psize = sizeof(xiocb_envbuf_t); 443 xiocb.plist.xiocb_envbuf.enum_idx = 0; 444 xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 445 xiocb.plist.xiocb_envbuf.name_length = cfe_strlen(name); 446 xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); 447 xiocb.plist.xiocb_envbuf.val_length = cfe_strlen(val); 448 449 cfe_iocb_dispatch(&xiocb); 450 451 return xiocb.xiocb_status; 452} 453#endif /* CFE_API_setenv || CFE_API_ALL */ 454 455#if (defined(CFE_API_strlen) || defined(CFE_API_ALL)) && \ 456 !defined(CFE_API_STRLEN_CUSTOM) 457int cfe_strlen(char *name) 458{ 459 int count = 0; 460 461 while (*name++) 462 count++; 463 464 return count; 465} 466#endif /* CFE_API_strlen || CFE_API_ALL */ 467 468#if defined(CFE_API_write) || defined(CFE_API_ALL) 469int cfe_write(int handle, unsigned char *buffer, int length) 470{ 471 return cfe_writeblk(handle, 0, buffer, length); 472} 473#endif /* CFE_API_write || CFE_API_ALL */ 474 475#if defined(CFE_API_writeblk) || defined(CFE_API_ALL) 476int 477cfe_writeblk(int handle, cfe_xint_t offset, unsigned char *buffer, 478 int length) 479{ 480 cfe_xiocb_t xiocb; 481 482 xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE; 483 xiocb.xiocb_status = 0; 484 xiocb.xiocb_handle = handle; 485 xiocb.xiocb_flags = 0; 486 xiocb.xiocb_psize = sizeof(xiocb_buffer_t); 487 xiocb.plist.xiocb_buffer.buf_offset = offset; 488 xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 489 xiocb.plist.xiocb_buffer.buf_length = length; 490 491 cfe_iocb_dispatch(&xiocb); 492 493 if (xiocb.xiocb_status < 0) 494 return xiocb.xiocb_status; 495 return xiocb.plist.xiocb_buffer.buf_retlen; 496} 497#endif /* CFE_API_writeblk || CFE_API_ALL */ 498