162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2000, 2001, 2002 Broadcom Corporation 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci/* 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Broadcom Common Firmware Environment (CFE) 962306a36Sopenharmony_ci * 1062306a36Sopenharmony_ci * This module contains device function stubs (small routines to 1162306a36Sopenharmony_ci * call the standard "iocb" interface entry point to CFE). 1262306a36Sopenharmony_ci * There should be one routine here per iocb function call. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * Authors: Mitch Lichtenberg, Chris Demetriou 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_ci#include <linux/init.h> 1762306a36Sopenharmony_ci#include <linux/kernel.h> 1862306a36Sopenharmony_ci#include <linux/printk.h> 1962306a36Sopenharmony_ci#include <asm/mipsregs.h> 2062306a36Sopenharmony_ci#include <asm/fw/cfe/cfe_api.h> 2162306a36Sopenharmony_ci#include "cfe_api_int.h" 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ciunsigned long __initdata cfe_seal; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/* Cast from a native pointer to a cfe_xptr_t and back. */ 2662306a36Sopenharmony_ci#define XPTR_FROM_NATIVE(n) ((cfe_xptr_t) (intptr_t) (n)) 2762306a36Sopenharmony_ci#define NATIVE_FROM_XPTR(x) ((void *) (intptr_t) (x)) 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ciint cfe_iocb_dispatch(struct cfe_xiocb *xiocb); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci/* 3262306a36Sopenharmony_ci * Declare the dispatch function with args of "intptr_t". 3362306a36Sopenharmony_ci * This makes sure whatever model we're compiling in 3462306a36Sopenharmony_ci * puts the pointers in a single register. For example, 3562306a36Sopenharmony_ci * combining -mlong64 and -mips1 or -mips2 would lead to 3662306a36Sopenharmony_ci * trouble, since the handle and IOCB pointer will be 3762306a36Sopenharmony_ci * passed in two registers each, and CFE expects one. 3862306a36Sopenharmony_ci */ 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistatic int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb); 4162306a36Sopenharmony_cistatic u64 cfe_handle; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ciint cfe_init(u64 handle, u64 ept) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci cfe_dispfunc = NATIVE_FROM_XPTR(ept); 4662306a36Sopenharmony_ci cfe_handle = handle; 4762306a36Sopenharmony_ci return 0; 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ciint cfe_iocb_dispatch(struct cfe_xiocb * xiocb) 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci if (!cfe_dispfunc) 5362306a36Sopenharmony_ci return -1; 5462306a36Sopenharmony_ci return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb); 5562306a36Sopenharmony_ci} 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ciint cfe_close(int handle) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci struct cfe_xiocb xiocb; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE; 6262306a36Sopenharmony_ci xiocb.xiocb_status = 0; 6362306a36Sopenharmony_ci xiocb.xiocb_handle = handle; 6462306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 6562306a36Sopenharmony_ci xiocb.xiocb_psize = 0; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci return xiocb.xiocb_status; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci} 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ciint cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci struct cfe_xiocb xiocb; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; 7862306a36Sopenharmony_ci xiocb.xiocb_status = 0; 7962306a36Sopenharmony_ci xiocb.xiocb_handle = 0; 8062306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 8162306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl); 8262306a36Sopenharmony_ci xiocb.plist.xiocb_cpuctl.cpu_number = cpu; 8362306a36Sopenharmony_ci xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START; 8462306a36Sopenharmony_ci xiocb.plist.xiocb_cpuctl.gp_val = gp; 8562306a36Sopenharmony_ci xiocb.plist.xiocb_cpuctl.sp_val = sp; 8662306a36Sopenharmony_ci xiocb.plist.xiocb_cpuctl.a1_val = a1; 8762306a36Sopenharmony_ci xiocb.plist.xiocb_cpuctl.start_addr = (long) fn; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci return xiocb.xiocb_status; 9262306a36Sopenharmony_ci} 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ciint cfe_cpu_stop(int cpu) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci struct cfe_xiocb xiocb; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL; 9962306a36Sopenharmony_ci xiocb.xiocb_status = 0; 10062306a36Sopenharmony_ci xiocb.xiocb_handle = 0; 10162306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 10262306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl); 10362306a36Sopenharmony_ci xiocb.plist.xiocb_cpuctl.cpu_number = cpu; 10462306a36Sopenharmony_ci xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci return xiocb.xiocb_status; 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ciint cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen) 11262306a36Sopenharmony_ci{ 11362306a36Sopenharmony_ci struct cfe_xiocb xiocb; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_ENV_SET; 11662306a36Sopenharmony_ci xiocb.xiocb_status = 0; 11762306a36Sopenharmony_ci xiocb.xiocb_handle = 0; 11862306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 11962306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_envbuf); 12062306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.enum_idx = idx; 12162306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 12262306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.name_length = namelen; 12362306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); 12462306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.val_length = vallen; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci return xiocb.xiocb_status; 12962306a36Sopenharmony_ci} 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ciint 13262306a36Sopenharmony_cicfe_enummem(int idx, int flags, u64 *start, u64 *length, u64 *type) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci struct cfe_xiocb xiocb; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM; 13762306a36Sopenharmony_ci xiocb.xiocb_status = 0; 13862306a36Sopenharmony_ci xiocb.xiocb_handle = 0; 13962306a36Sopenharmony_ci xiocb.xiocb_flags = flags; 14062306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_meminfo); 14162306a36Sopenharmony_ci xiocb.plist.xiocb_meminfo.mi_idx = idx; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci if (xiocb.xiocb_status < 0) 14662306a36Sopenharmony_ci return xiocb.xiocb_status; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci *start = xiocb.plist.xiocb_meminfo.mi_addr; 14962306a36Sopenharmony_ci *length = xiocb.plist.xiocb_meminfo.mi_size; 15062306a36Sopenharmony_ci *type = xiocb.plist.xiocb_meminfo.mi_type; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci return 0; 15362306a36Sopenharmony_ci} 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ciint cfe_exit(int warm, int status) 15662306a36Sopenharmony_ci{ 15762306a36Sopenharmony_ci struct cfe_xiocb xiocb; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_FW_RESTART; 16062306a36Sopenharmony_ci xiocb.xiocb_status = 0; 16162306a36Sopenharmony_ci xiocb.xiocb_handle = 0; 16262306a36Sopenharmony_ci xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0; 16362306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_exitstat); 16462306a36Sopenharmony_ci xiocb.plist.xiocb_exitstat.status = status; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci return xiocb.xiocb_status; 16962306a36Sopenharmony_ci} 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ciint cfe_flushcache(int flg) 17262306a36Sopenharmony_ci{ 17362306a36Sopenharmony_ci struct cfe_xiocb xiocb; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE; 17662306a36Sopenharmony_ci xiocb.xiocb_status = 0; 17762306a36Sopenharmony_ci xiocb.xiocb_handle = 0; 17862306a36Sopenharmony_ci xiocb.xiocb_flags = flg; 17962306a36Sopenharmony_ci xiocb.xiocb_psize = 0; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci return xiocb.xiocb_status; 18462306a36Sopenharmony_ci} 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ciint cfe_getdevinfo(char *name) 18762306a36Sopenharmony_ci{ 18862306a36Sopenharmony_ci struct cfe_xiocb xiocb; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO; 19162306a36Sopenharmony_ci xiocb.xiocb_status = 0; 19262306a36Sopenharmony_ci xiocb.xiocb_handle = 0; 19362306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 19462306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_buffer); 19562306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_offset = 0; 19662306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); 19762306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_length = strlen(name); 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci if (xiocb.xiocb_status < 0) 20262306a36Sopenharmony_ci return xiocb.xiocb_status; 20362306a36Sopenharmony_ci return xiocb.plist.xiocb_buffer.buf_ioctlcmd; 20462306a36Sopenharmony_ci} 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ciint cfe_getenv(char *name, char *dest, int destlen) 20762306a36Sopenharmony_ci{ 20862306a36Sopenharmony_ci struct cfe_xiocb xiocb; 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci *dest = 0; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_ENV_GET; 21362306a36Sopenharmony_ci xiocb.xiocb_status = 0; 21462306a36Sopenharmony_ci xiocb.xiocb_handle = 0; 21562306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 21662306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_envbuf); 21762306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.enum_idx = 0; 21862306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 21962306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.name_length = strlen(name); 22062306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest); 22162306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.val_length = destlen; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci return xiocb.xiocb_status; 22662306a36Sopenharmony_ci} 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ciint cfe_getfwinfo(cfe_fwinfo_t * info) 22962306a36Sopenharmony_ci{ 23062306a36Sopenharmony_ci struct cfe_xiocb xiocb; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO; 23362306a36Sopenharmony_ci xiocb.xiocb_status = 0; 23462306a36Sopenharmony_ci xiocb.xiocb_handle = 0; 23562306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 23662306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_fwinfo); 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci if (xiocb.xiocb_status < 0) 24162306a36Sopenharmony_ci return xiocb.xiocb_status; 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci info->fwi_version = xiocb.plist.xiocb_fwinfo.fwi_version; 24462306a36Sopenharmony_ci info->fwi_totalmem = xiocb.plist.xiocb_fwinfo.fwi_totalmem; 24562306a36Sopenharmony_ci info->fwi_flags = xiocb.plist.xiocb_fwinfo.fwi_flags; 24662306a36Sopenharmony_ci info->fwi_boardid = xiocb.plist.xiocb_fwinfo.fwi_boardid; 24762306a36Sopenharmony_ci info->fwi_bootarea_va = xiocb.plist.xiocb_fwinfo.fwi_bootarea_va; 24862306a36Sopenharmony_ci info->fwi_bootarea_pa = xiocb.plist.xiocb_fwinfo.fwi_bootarea_pa; 24962306a36Sopenharmony_ci info->fwi_bootarea_size = 25062306a36Sopenharmony_ci xiocb.plist.xiocb_fwinfo.fwi_bootarea_size; 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci return 0; 25362306a36Sopenharmony_ci} 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ciint cfe_getstdhandle(int flg) 25662306a36Sopenharmony_ci{ 25762306a36Sopenharmony_ci struct cfe_xiocb xiocb; 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE; 26062306a36Sopenharmony_ci xiocb.xiocb_status = 0; 26162306a36Sopenharmony_ci xiocb.xiocb_handle = 0; 26262306a36Sopenharmony_ci xiocb.xiocb_flags = flg; 26362306a36Sopenharmony_ci xiocb.xiocb_psize = 0; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci if (xiocb.xiocb_status < 0) 26862306a36Sopenharmony_ci return xiocb.xiocb_status; 26962306a36Sopenharmony_ci return xiocb.xiocb_handle; 27062306a36Sopenharmony_ci} 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ciint64_t 27362306a36Sopenharmony_cicfe_getticks(void) 27462306a36Sopenharmony_ci{ 27562306a36Sopenharmony_ci struct cfe_xiocb xiocb; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME; 27862306a36Sopenharmony_ci xiocb.xiocb_status = 0; 27962306a36Sopenharmony_ci xiocb.xiocb_handle = 0; 28062306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 28162306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_time); 28262306a36Sopenharmony_ci xiocb.plist.xiocb_time.ticks = 0; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci return xiocb.plist.xiocb_time.ticks; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci} 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ciint cfe_inpstat(int handle) 29162306a36Sopenharmony_ci{ 29262306a36Sopenharmony_ci struct cfe_xiocb xiocb; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT; 29562306a36Sopenharmony_ci xiocb.xiocb_status = 0; 29662306a36Sopenharmony_ci xiocb.xiocb_handle = handle; 29762306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 29862306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_inpstat); 29962306a36Sopenharmony_ci xiocb.plist.xiocb_inpstat.inp_status = 0; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci if (xiocb.xiocb_status < 0) 30462306a36Sopenharmony_ci return xiocb.xiocb_status; 30562306a36Sopenharmony_ci return xiocb.plist.xiocb_inpstat.inp_status; 30662306a36Sopenharmony_ci} 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ciint 30962306a36Sopenharmony_cicfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer, 31062306a36Sopenharmony_ci int length, int *retlen, u64 offset) 31162306a36Sopenharmony_ci{ 31262306a36Sopenharmony_ci struct cfe_xiocb xiocb; 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL; 31562306a36Sopenharmony_ci xiocb.xiocb_status = 0; 31662306a36Sopenharmony_ci xiocb.xiocb_handle = handle; 31762306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 31862306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_buffer); 31962306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_offset = offset; 32062306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum; 32162306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 32262306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_length = length; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci if (retlen) 32762306a36Sopenharmony_ci *retlen = xiocb.plist.xiocb_buffer.buf_retlen; 32862306a36Sopenharmony_ci return xiocb.xiocb_status; 32962306a36Sopenharmony_ci} 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ciint cfe_open(char *name) 33262306a36Sopenharmony_ci{ 33362306a36Sopenharmony_ci struct cfe_xiocb xiocb; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN; 33662306a36Sopenharmony_ci xiocb.xiocb_status = 0; 33762306a36Sopenharmony_ci xiocb.xiocb_handle = 0; 33862306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 33962306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_buffer); 34062306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_offset = 0; 34162306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name); 34262306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_length = strlen(name); 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci if (xiocb.xiocb_status < 0) 34762306a36Sopenharmony_ci return xiocb.xiocb_status; 34862306a36Sopenharmony_ci return xiocb.xiocb_handle; 34962306a36Sopenharmony_ci} 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ciint cfe_read(int handle, unsigned char *buffer, int length) 35262306a36Sopenharmony_ci{ 35362306a36Sopenharmony_ci return cfe_readblk(handle, 0, buffer, length); 35462306a36Sopenharmony_ci} 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ciint cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length) 35762306a36Sopenharmony_ci{ 35862306a36Sopenharmony_ci struct cfe_xiocb xiocb; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_DEV_READ; 36162306a36Sopenharmony_ci xiocb.xiocb_status = 0; 36262306a36Sopenharmony_ci xiocb.xiocb_handle = handle; 36362306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 36462306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_buffer); 36562306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_offset = offset; 36662306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 36762306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_length = length; 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci if (xiocb.xiocb_status < 0) 37262306a36Sopenharmony_ci return xiocb.xiocb_status; 37362306a36Sopenharmony_ci return xiocb.plist.xiocb_buffer.buf_retlen; 37462306a36Sopenharmony_ci} 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ciint cfe_setenv(char *name, char *val) 37762306a36Sopenharmony_ci{ 37862306a36Sopenharmony_ci struct cfe_xiocb xiocb; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_ENV_SET; 38162306a36Sopenharmony_ci xiocb.xiocb_status = 0; 38262306a36Sopenharmony_ci xiocb.xiocb_handle = 0; 38362306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 38462306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_envbuf); 38562306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.enum_idx = 0; 38662306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name); 38762306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.name_length = strlen(name); 38862306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val); 38962306a36Sopenharmony_ci xiocb.plist.xiocb_envbuf.val_length = strlen(val); 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci return xiocb.xiocb_status; 39462306a36Sopenharmony_ci} 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ciint cfe_write(int handle, const char *buffer, int length) 39762306a36Sopenharmony_ci{ 39862306a36Sopenharmony_ci return cfe_writeblk(handle, 0, buffer, length); 39962306a36Sopenharmony_ci} 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ciint cfe_writeblk(int handle, s64 offset, const char *buffer, int length) 40262306a36Sopenharmony_ci{ 40362306a36Sopenharmony_ci struct cfe_xiocb xiocb; 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE; 40662306a36Sopenharmony_ci xiocb.xiocb_status = 0; 40762306a36Sopenharmony_ci xiocb.xiocb_handle = handle; 40862306a36Sopenharmony_ci xiocb.xiocb_flags = 0; 40962306a36Sopenharmony_ci xiocb.xiocb_psize = sizeof(struct xiocb_buffer); 41062306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_offset = offset; 41162306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer); 41262306a36Sopenharmony_ci xiocb.plist.xiocb_buffer.buf_length = length; 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci cfe_iocb_dispatch(&xiocb); 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci if (xiocb.xiocb_status < 0) 41762306a36Sopenharmony_ci return xiocb.xiocb_status; 41862306a36Sopenharmony_ci return xiocb.plist.xiocb_buffer.buf_retlen; 41962306a36Sopenharmony_ci} 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_civoid __init cfe_die(char *fmt, ...) 42262306a36Sopenharmony_ci{ 42362306a36Sopenharmony_ci unsigned int prid, __maybe_unused rev; 42462306a36Sopenharmony_ci char msg[128]; 42562306a36Sopenharmony_ci va_list ap; 42662306a36Sopenharmony_ci int handle; 42762306a36Sopenharmony_ci unsigned int count; 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci va_start(ap, fmt); 43062306a36Sopenharmony_ci vsprintf(msg, fmt, ap); 43162306a36Sopenharmony_ci strcat(msg, "\r\n"); 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci if (cfe_seal != CFE_EPTSEAL) 43462306a36Sopenharmony_ci goto no_cfe; 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci prid = read_c0_prid(); 43762306a36Sopenharmony_ci if ((prid & PRID_COMP_MASK) != PRID_COMP_BROADCOM) 43862306a36Sopenharmony_ci goto no_cfe; 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci rev = prid & PRID_REV_MASK; 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci /* disable XKS01 so that CFE can access the registers */ 44362306a36Sopenharmony_ci switch (prid & PRID_IMP_MASK) { 44462306a36Sopenharmony_ci#ifdef CONFIG_CPU_BMIPS4380 44562306a36Sopenharmony_ci case PRID_IMP_BMIPS43XX: 44662306a36Sopenharmony_ci if (rev >= PRID_REV_BMIPS4380_LO && 44762306a36Sopenharmony_ci rev <= PRID_REV_BMIPS4380_HI) 44862306a36Sopenharmony_ci __write_32bit_c0_register($22, 3, 44962306a36Sopenharmony_ci __read_32bit_c0_register($22, 3) & ~BIT(12)); 45062306a36Sopenharmony_ci break; 45162306a36Sopenharmony_ci#endif 45262306a36Sopenharmony_ci#ifdef CONFIG_CPU_BMIPS5000 45362306a36Sopenharmony_ci case PRID_IMP_BMIPS5000: 45462306a36Sopenharmony_ci case PRID_IMP_BMIPS5200: 45562306a36Sopenharmony_ci __write_32bit_c0_register($22, 5, 45662306a36Sopenharmony_ci __read_32bit_c0_register($22, 5) & ~BIT(8)); 45762306a36Sopenharmony_ci break; 45862306a36Sopenharmony_ci#endif 45962306a36Sopenharmony_ci default: 46062306a36Sopenharmony_ci break; 46162306a36Sopenharmony_ci } 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); 46462306a36Sopenharmony_ci if (handle < 0) 46562306a36Sopenharmony_ci goto no_cfe; 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci cfe_write(handle, msg, strlen(msg)); 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci for (count = 0; count < 0x7fffffff; count++) 47062306a36Sopenharmony_ci mb(); 47162306a36Sopenharmony_ci cfe_exit(0, 1); 47262306a36Sopenharmony_ci while (1) 47362306a36Sopenharmony_ci ; 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_cino_cfe: 47662306a36Sopenharmony_ci /* probably won't print anywhere useful */ 47762306a36Sopenharmony_ci panic("%s", msg); 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci va_end(ap); 48062306a36Sopenharmony_ci} 481