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