1/* 2 * Copyright 2011, François Revol, revol@free.fr. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include <string.h> 8#include <stdarg.h> 9 10#include <OS.h> 11 12#include <boot/platform.h> 13#include <boot/stage2.h> 14#include <boot/heap.h> 15#include <boot/platform/cfe/cfe.h> 16#include <platform_arch.h> 17 18typedef uint64 ptr64; // for clarity 19 20status_t cfe_error(int32 err) 21{ 22 // not an error 23 if (err > 0) 24 return err; 25 26 switch (err) { 27 case CFE_OK: 28 return B_OK; 29 case CFE_ERR: 30 return B_ERROR; 31 //TODO:add cases 32 default: 33 return B_ERROR; 34 } 35} 36 37#define CFE_CMD_FW_GETINFO 0 38#define CFE_CMD_FW_RESTART 1 39#define CFE_CMD_FW_BOOT 2 40#define CFE_CMD_FW_CPUCTL 3 41#define CFE_CMD_FW_GETTIME 4 42#define CFE_CMD_FW_MEMENUM 5 43#define CFE_CMD_FW_FLUSHCACHE 6 44 45#define CFE_CMD_DEV_GETHANDLE 9 46#define CFE_CMD_DEV_ENUM 10 47#define CFE_CMD_DEV_OPEN 11 48#define CFE_CMD_DEV_READ 13 49#define CFE_CMD_DEV_WRITE 14 50#define CFE_CMD_DEV_CLOSE 16 51 52 53struct cfe_xiocb_s { 54 cfe_xiocb_s(uint64 fcode, int64 handle = 0, uint64 flags = 0); 55 56 uint64 xiocb_fcode; 57 int64 xiocb_status; 58 int64 xiocb_handle; 59 uint64 xiocb_flags; 60 uint64 xiocb_psize; 61 union { 62 struct { 63 uint64 buf_offset; 64 ptr64 buf_ptr; 65 uint64 buf_length; 66 uint64 buf_retlen; 67 uint64 buf_ioctlcmd; 68 } xiocb_buffer; 69/* 70 struct { 71 } xiocb_inpstat; 72*/ 73 struct { 74 int64 enum_idx; 75 ptr64 name_ptr; 76 int64 name_length; 77 ptr64 val_ptr; 78 int64 val_length; 79 } xiocb_envbuf; 80/* 81 struct { 82 } xiocb_cpuctl; 83*/ 84 struct { 85 int64 ticks; 86 } xiocb_time; 87/* 88 struct { 89 } xiocb_meminfo; 90 struct { 91 } xiocb_fwinfo; 92*/ 93 struct { 94 int64 status; 95 } xiocb_exitstat; 96 } plist; 97}; 98 99typedef struct cfe_xiocb_s cfe_xiocb_t; 100 101cfe_xiocb_s::cfe_xiocb_s(uint64 fcode, int64 handle, uint64 flags) 102 : xiocb_fcode(fcode), 103 xiocb_status(0), 104 xiocb_handle(handle), 105 xiocb_flags(flags), 106 xiocb_psize(0) 107{ 108 switch (fcode) { 109 case CFE_CMD_FW_GETINFO: 110 case CFE_CMD_DEV_READ: 111 case CFE_CMD_DEV_WRITE: 112 case CFE_CMD_DEV_OPEN: 113 xiocb_psize = sizeof(plist.xiocb_buffer); 114 break; 115 case CFE_CMD_FW_RESTART: 116 xiocb_psize = sizeof(plist.xiocb_exitstat); 117 break; 118 case CFE_CMD_FW_GETTIME: 119 xiocb_psize = sizeof(plist.xiocb_time); 120 break; 121 case CFE_CMD_DEV_ENUM: 122 xiocb_psize = sizeof(plist.xiocb_envbuf); 123 break; 124 //XXX: some more... 125 default: 126 break; 127 } 128 memset(&plist, 0, sizeof(plist)); 129}; 130 131 132// CFE handle 133static uint64 sCFEHandle; 134// CFE entry point 135static uint64 sCFEEntry; 136 137static int cfe_iocb_dispatch(cfe_xiocb_t *xiocb) 138{ 139 static int (*dispfunc)(intptr_t handle, intptr_t xiocb); 140 dispfunc = (int(*)(intptr_t, intptr_t))(void *)sCFEEntry; 141 if (dispfunc == NULL) 142 return CFE_ERR; 143 return (*dispfunc)((intptr_t)sCFEHandle, (intptr_t)xiocb); 144} 145 146int 147cfe_init(uint64 handle, uint64 entry) 148{ 149 sCFEHandle = handle; 150 sCFEEntry = entry; 151 152 return CFE_OK; 153} 154 155int 156cfe_exit(int32 warm, int32 status) 157{ 158 cfe_xiocb_t xiocb(CFE_CMD_FW_RESTART, 0, 159 warm ? CFE_FLG_WARMSTART : CFE_FLG_COLDSTART); 160 xiocb.plist.xiocb_exitstat.status = status; 161 162 cfe_iocb_dispatch(&xiocb); 163 164 return xiocb.xiocb_status; 165} 166 167 168int cfe_enumdev(int idx, char *name, int namelen) 169{ 170 cfe_xiocb_t xiocb(CFE_CMD_DEV_ENUM); 171 xiocb.plist.xiocb_envbuf.enum_idx = idx; 172 xiocb.plist.xiocb_envbuf.name_ptr = (uint64)name; 173 xiocb.plist.xiocb_envbuf.name_length = namelen; 174 175 cfe_iocb_dispatch(&xiocb); 176 177 return xiocb.xiocb_status; 178} 179 180 181int 182cfe_getstdhandle(int flag) 183{ 184 cfe_xiocb_t xiocb(CFE_CMD_DEV_GETHANDLE, 0, flag); 185 186 cfe_iocb_dispatch(&xiocb); 187 188 if (xiocb.xiocb_status < 0); 189 return xiocb.xiocb_status; 190 return xiocb.xiocb_handle; 191} 192 193 194int 195cfe_open(const char *name) 196{ 197 cfe_xiocb_t xiocb(CFE_CMD_DEV_OPEN); 198 xiocb.plist.xiocb_buffer.buf_offset = 0; 199 xiocb.plist.xiocb_buffer.buf_ptr = (uint64)name; 200 xiocb.plist.xiocb_buffer.buf_length = strlen(name); 201 202 cfe_iocb_dispatch(&xiocb); 203 204 if (xiocb.xiocb_status < 0); 205 return xiocb.xiocb_status; 206 return xiocb.xiocb_handle; 207} 208 209 210int 211cfe_close(int handle) 212{ 213 cfe_xiocb_t xiocb(CFE_CMD_DEV_CLOSE, handle); 214 215 cfe_iocb_dispatch(&xiocb); 216 217 return xiocb.xiocb_status; 218} 219 220 221uint64 222cfe_getticks(void) 223{ 224 cfe_xiocb_t xiocb(CFE_CMD_FW_GETTIME); 225 226 cfe_iocb_dispatch(&xiocb); 227 228 return xiocb.plist.xiocb_time.ticks; 229} 230 231 232int 233cfe_readblk(int handle, int64 offset, void *buffer, int length) 234{ 235 cfe_xiocb_t xiocb(CFE_CMD_DEV_READ, handle); 236 xiocb.plist.xiocb_buffer.buf_offset = offset; 237 xiocb.plist.xiocb_buffer.buf_ptr = (uint64)buffer; 238 xiocb.plist.xiocb_buffer.buf_length = length; 239 240 cfe_iocb_dispatch(&xiocb); 241 242 if (xiocb.xiocb_status < 0); 243 return xiocb.xiocb_status; 244 return xiocb.plist.xiocb_buffer.buf_retlen; 245} 246 247 248 249int 250cfe_writeblk(int handle, int64 offset, const void *buffer, int length) 251{ 252 cfe_xiocb_t xiocb(CFE_CMD_DEV_WRITE, handle); 253 xiocb.plist.xiocb_buffer.buf_offset = offset; 254 xiocb.plist.xiocb_buffer.buf_ptr = (uint64)buffer; 255 xiocb.plist.xiocb_buffer.buf_length = length; 256 257 cfe_iocb_dispatch(&xiocb); 258 259 if (xiocb.xiocb_status < 0); 260 return xiocb.xiocb_status; 261 return xiocb.plist.xiocb_buffer.buf_retlen; 262} 263 264 265