cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cfe_api.c (10330B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (C) 2000, 2001, 2002 Broadcom Corporation
      4 */
      5
      6/*
      7 *
      8 * Broadcom Common Firmware Environment (CFE)
      9 *
     10 * This module contains device function stubs (small routines to
     11 * call the standard "iocb" interface entry point to CFE).
     12 * There should be one routine here per iocb function call.
     13 *
     14 * Authors:  Mitch Lichtenberg, Chris Demetriou
     15 */
     16
     17#include <asm/fw/cfe/cfe_api.h>
     18#include "cfe_api_int.h"
     19
     20/* Cast from a native pointer to a cfe_xptr_t and back.	 */
     21#define XPTR_FROM_NATIVE(n)	((cfe_xptr_t) (intptr_t) (n))
     22#define NATIVE_FROM_XPTR(x)	((void *) (intptr_t) (x))
     23
     24int cfe_iocb_dispatch(struct cfe_xiocb *xiocb);
     25
     26/*
     27 * Declare the dispatch function with args of "intptr_t".
     28 * This makes sure whatever model we're compiling in
     29 * puts the pointers in a single register.  For example,
     30 * combining -mlong64 and -mips1 or -mips2 would lead to
     31 * trouble, since the handle and IOCB pointer will be
     32 * passed in two registers each, and CFE expects one.
     33 */
     34
     35static int (*cfe_dispfunc) (intptr_t handle, intptr_t xiocb);
     36static u64 cfe_handle;
     37
     38int cfe_init(u64 handle, u64 ept)
     39{
     40	cfe_dispfunc = NATIVE_FROM_XPTR(ept);
     41	cfe_handle = handle;
     42	return 0;
     43}
     44
     45int cfe_iocb_dispatch(struct cfe_xiocb * xiocb)
     46{
     47	if (!cfe_dispfunc)
     48		return -1;
     49	return (*cfe_dispfunc) ((intptr_t) cfe_handle, (intptr_t) xiocb);
     50}
     51
     52int cfe_close(int handle)
     53{
     54	struct cfe_xiocb xiocb;
     55
     56	xiocb.xiocb_fcode = CFE_CMD_DEV_CLOSE;
     57	xiocb.xiocb_status = 0;
     58	xiocb.xiocb_handle = handle;
     59	xiocb.xiocb_flags = 0;
     60	xiocb.xiocb_psize = 0;
     61
     62	cfe_iocb_dispatch(&xiocb);
     63
     64	return xiocb.xiocb_status;
     65
     66}
     67
     68int cfe_cpu_start(int cpu, void (*fn) (void), long sp, long gp, long a1)
     69{
     70	struct cfe_xiocb xiocb;
     71
     72	xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
     73	xiocb.xiocb_status = 0;
     74	xiocb.xiocb_handle = 0;
     75	xiocb.xiocb_flags = 0;
     76	xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl);
     77	xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
     78	xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_START;
     79	xiocb.plist.xiocb_cpuctl.gp_val = gp;
     80	xiocb.plist.xiocb_cpuctl.sp_val = sp;
     81	xiocb.plist.xiocb_cpuctl.a1_val = a1;
     82	xiocb.plist.xiocb_cpuctl.start_addr = (long) fn;
     83
     84	cfe_iocb_dispatch(&xiocb);
     85
     86	return xiocb.xiocb_status;
     87}
     88
     89int cfe_cpu_stop(int cpu)
     90{
     91	struct cfe_xiocb xiocb;
     92
     93	xiocb.xiocb_fcode = CFE_CMD_FW_CPUCTL;
     94	xiocb.xiocb_status = 0;
     95	xiocb.xiocb_handle = 0;
     96	xiocb.xiocb_flags = 0;
     97	xiocb.xiocb_psize = sizeof(struct xiocb_cpuctl);
     98	xiocb.plist.xiocb_cpuctl.cpu_number = cpu;
     99	xiocb.plist.xiocb_cpuctl.cpu_command = CFE_CPU_CMD_STOP;
    100
    101	cfe_iocb_dispatch(&xiocb);
    102
    103	return xiocb.xiocb_status;
    104}
    105
    106int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
    107{
    108	struct cfe_xiocb xiocb;
    109
    110	xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
    111	xiocb.xiocb_status = 0;
    112	xiocb.xiocb_handle = 0;
    113	xiocb.xiocb_flags = 0;
    114	xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
    115	xiocb.plist.xiocb_envbuf.enum_idx = idx;
    116	xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
    117	xiocb.plist.xiocb_envbuf.name_length = namelen;
    118	xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
    119	xiocb.plist.xiocb_envbuf.val_length = vallen;
    120
    121	cfe_iocb_dispatch(&xiocb);
    122
    123	return xiocb.xiocb_status;
    124}
    125
    126int
    127cfe_enummem(int idx, int flags, u64 *start, u64 *length, u64 *type)
    128{
    129	struct cfe_xiocb xiocb;
    130
    131	xiocb.xiocb_fcode = CFE_CMD_FW_MEMENUM;
    132	xiocb.xiocb_status = 0;
    133	xiocb.xiocb_handle = 0;
    134	xiocb.xiocb_flags = flags;
    135	xiocb.xiocb_psize = sizeof(struct xiocb_meminfo);
    136	xiocb.plist.xiocb_meminfo.mi_idx = idx;
    137
    138	cfe_iocb_dispatch(&xiocb);
    139
    140	if (xiocb.xiocb_status < 0)
    141		return xiocb.xiocb_status;
    142
    143	*start = xiocb.plist.xiocb_meminfo.mi_addr;
    144	*length = xiocb.plist.xiocb_meminfo.mi_size;
    145	*type = xiocb.plist.xiocb_meminfo.mi_type;
    146
    147	return 0;
    148}
    149
    150int cfe_exit(int warm, int status)
    151{
    152	struct cfe_xiocb xiocb;
    153
    154	xiocb.xiocb_fcode = CFE_CMD_FW_RESTART;
    155	xiocb.xiocb_status = 0;
    156	xiocb.xiocb_handle = 0;
    157	xiocb.xiocb_flags = warm ? CFE_FLG_WARMSTART : 0;
    158	xiocb.xiocb_psize = sizeof(struct xiocb_exitstat);
    159	xiocb.plist.xiocb_exitstat.status = status;
    160
    161	cfe_iocb_dispatch(&xiocb);
    162
    163	return xiocb.xiocb_status;
    164}
    165
    166int cfe_flushcache(int flg)
    167{
    168	struct cfe_xiocb xiocb;
    169
    170	xiocb.xiocb_fcode = CFE_CMD_FW_FLUSHCACHE;
    171	xiocb.xiocb_status = 0;
    172	xiocb.xiocb_handle = 0;
    173	xiocb.xiocb_flags = flg;
    174	xiocb.xiocb_psize = 0;
    175
    176	cfe_iocb_dispatch(&xiocb);
    177
    178	return xiocb.xiocb_status;
    179}
    180
    181int cfe_getdevinfo(char *name)
    182{
    183	struct cfe_xiocb xiocb;
    184
    185	xiocb.xiocb_fcode = CFE_CMD_DEV_GETINFO;
    186	xiocb.xiocb_status = 0;
    187	xiocb.xiocb_handle = 0;
    188	xiocb.xiocb_flags = 0;
    189	xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
    190	xiocb.plist.xiocb_buffer.buf_offset = 0;
    191	xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
    192	xiocb.plist.xiocb_buffer.buf_length = strlen(name);
    193
    194	cfe_iocb_dispatch(&xiocb);
    195
    196	if (xiocb.xiocb_status < 0)
    197		return xiocb.xiocb_status;
    198	return xiocb.plist.xiocb_buffer.buf_ioctlcmd;
    199}
    200
    201int cfe_getenv(char *name, char *dest, int destlen)
    202{
    203	struct cfe_xiocb xiocb;
    204
    205	*dest = 0;
    206
    207	xiocb.xiocb_fcode = CFE_CMD_ENV_GET;
    208	xiocb.xiocb_status = 0;
    209	xiocb.xiocb_handle = 0;
    210	xiocb.xiocb_flags = 0;
    211	xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
    212	xiocb.plist.xiocb_envbuf.enum_idx = 0;
    213	xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
    214	xiocb.plist.xiocb_envbuf.name_length = strlen(name);
    215	xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(dest);
    216	xiocb.plist.xiocb_envbuf.val_length = destlen;
    217
    218	cfe_iocb_dispatch(&xiocb);
    219
    220	return xiocb.xiocb_status;
    221}
    222
    223int cfe_getfwinfo(cfe_fwinfo_t * info)
    224{
    225	struct cfe_xiocb xiocb;
    226
    227	xiocb.xiocb_fcode = CFE_CMD_FW_GETINFO;
    228	xiocb.xiocb_status = 0;
    229	xiocb.xiocb_handle = 0;
    230	xiocb.xiocb_flags = 0;
    231	xiocb.xiocb_psize = sizeof(struct xiocb_fwinfo);
    232
    233	cfe_iocb_dispatch(&xiocb);
    234
    235	if (xiocb.xiocb_status < 0)
    236		return xiocb.xiocb_status;
    237
    238	info->fwi_version = xiocb.plist.xiocb_fwinfo.fwi_version;
    239	info->fwi_totalmem = xiocb.plist.xiocb_fwinfo.fwi_totalmem;
    240	info->fwi_flags = xiocb.plist.xiocb_fwinfo.fwi_flags;
    241	info->fwi_boardid = xiocb.plist.xiocb_fwinfo.fwi_boardid;
    242	info->fwi_bootarea_va = xiocb.plist.xiocb_fwinfo.fwi_bootarea_va;
    243	info->fwi_bootarea_pa = xiocb.plist.xiocb_fwinfo.fwi_bootarea_pa;
    244	info->fwi_bootarea_size =
    245	    xiocb.plist.xiocb_fwinfo.fwi_bootarea_size;
    246
    247	return 0;
    248}
    249
    250int cfe_getstdhandle(int flg)
    251{
    252	struct cfe_xiocb xiocb;
    253
    254	xiocb.xiocb_fcode = CFE_CMD_DEV_GETHANDLE;
    255	xiocb.xiocb_status = 0;
    256	xiocb.xiocb_handle = 0;
    257	xiocb.xiocb_flags = flg;
    258	xiocb.xiocb_psize = 0;
    259
    260	cfe_iocb_dispatch(&xiocb);
    261
    262	if (xiocb.xiocb_status < 0)
    263		return xiocb.xiocb_status;
    264	return xiocb.xiocb_handle;
    265}
    266
    267int64_t
    268cfe_getticks(void)
    269{
    270	struct cfe_xiocb xiocb;
    271
    272	xiocb.xiocb_fcode = CFE_CMD_FW_GETTIME;
    273	xiocb.xiocb_status = 0;
    274	xiocb.xiocb_handle = 0;
    275	xiocb.xiocb_flags = 0;
    276	xiocb.xiocb_psize = sizeof(struct xiocb_time);
    277	xiocb.plist.xiocb_time.ticks = 0;
    278
    279	cfe_iocb_dispatch(&xiocb);
    280
    281	return xiocb.plist.xiocb_time.ticks;
    282
    283}
    284
    285int cfe_inpstat(int handle)
    286{
    287	struct cfe_xiocb xiocb;
    288
    289	xiocb.xiocb_fcode = CFE_CMD_DEV_INPSTAT;
    290	xiocb.xiocb_status = 0;
    291	xiocb.xiocb_handle = handle;
    292	xiocb.xiocb_flags = 0;
    293	xiocb.xiocb_psize = sizeof(struct xiocb_inpstat);
    294	xiocb.plist.xiocb_inpstat.inp_status = 0;
    295
    296	cfe_iocb_dispatch(&xiocb);
    297
    298	if (xiocb.xiocb_status < 0)
    299		return xiocb.xiocb_status;
    300	return xiocb.plist.xiocb_inpstat.inp_status;
    301}
    302
    303int
    304cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
    305	  int length, int *retlen, u64 offset)
    306{
    307	struct cfe_xiocb xiocb;
    308
    309	xiocb.xiocb_fcode = CFE_CMD_DEV_IOCTL;
    310	xiocb.xiocb_status = 0;
    311	xiocb.xiocb_handle = handle;
    312	xiocb.xiocb_flags = 0;
    313	xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
    314	xiocb.plist.xiocb_buffer.buf_offset = offset;
    315	xiocb.plist.xiocb_buffer.buf_ioctlcmd = ioctlnum;
    316	xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
    317	xiocb.plist.xiocb_buffer.buf_length = length;
    318
    319	cfe_iocb_dispatch(&xiocb);
    320
    321	if (retlen)
    322		*retlen = xiocb.plist.xiocb_buffer.buf_retlen;
    323	return xiocb.xiocb_status;
    324}
    325
    326int cfe_open(char *name)
    327{
    328	struct cfe_xiocb xiocb;
    329
    330	xiocb.xiocb_fcode = CFE_CMD_DEV_OPEN;
    331	xiocb.xiocb_status = 0;
    332	xiocb.xiocb_handle = 0;
    333	xiocb.xiocb_flags = 0;
    334	xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
    335	xiocb.plist.xiocb_buffer.buf_offset = 0;
    336	xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(name);
    337	xiocb.plist.xiocb_buffer.buf_length = strlen(name);
    338
    339	cfe_iocb_dispatch(&xiocb);
    340
    341	if (xiocb.xiocb_status < 0)
    342		return xiocb.xiocb_status;
    343	return xiocb.xiocb_handle;
    344}
    345
    346int cfe_read(int handle, unsigned char *buffer, int length)
    347{
    348	return cfe_readblk(handle, 0, buffer, length);
    349}
    350
    351int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length)
    352{
    353	struct cfe_xiocb xiocb;
    354
    355	xiocb.xiocb_fcode = CFE_CMD_DEV_READ;
    356	xiocb.xiocb_status = 0;
    357	xiocb.xiocb_handle = handle;
    358	xiocb.xiocb_flags = 0;
    359	xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
    360	xiocb.plist.xiocb_buffer.buf_offset = offset;
    361	xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
    362	xiocb.plist.xiocb_buffer.buf_length = length;
    363
    364	cfe_iocb_dispatch(&xiocb);
    365
    366	if (xiocb.xiocb_status < 0)
    367		return xiocb.xiocb_status;
    368	return xiocb.plist.xiocb_buffer.buf_retlen;
    369}
    370
    371int cfe_setenv(char *name, char *val)
    372{
    373	struct cfe_xiocb xiocb;
    374
    375	xiocb.xiocb_fcode = CFE_CMD_ENV_SET;
    376	xiocb.xiocb_status = 0;
    377	xiocb.xiocb_handle = 0;
    378	xiocb.xiocb_flags = 0;
    379	xiocb.xiocb_psize = sizeof(struct xiocb_envbuf);
    380	xiocb.plist.xiocb_envbuf.enum_idx = 0;
    381	xiocb.plist.xiocb_envbuf.name_ptr = XPTR_FROM_NATIVE(name);
    382	xiocb.plist.xiocb_envbuf.name_length = strlen(name);
    383	xiocb.plist.xiocb_envbuf.val_ptr = XPTR_FROM_NATIVE(val);
    384	xiocb.plist.xiocb_envbuf.val_length = strlen(val);
    385
    386	cfe_iocb_dispatch(&xiocb);
    387
    388	return xiocb.xiocb_status;
    389}
    390
    391int cfe_write(int handle, const char *buffer, int length)
    392{
    393	return cfe_writeblk(handle, 0, buffer, length);
    394}
    395
    396int cfe_writeblk(int handle, s64 offset, const char *buffer, int length)
    397{
    398	struct cfe_xiocb xiocb;
    399
    400	xiocb.xiocb_fcode = CFE_CMD_DEV_WRITE;
    401	xiocb.xiocb_status = 0;
    402	xiocb.xiocb_handle = handle;
    403	xiocb.xiocb_flags = 0;
    404	xiocb.xiocb_psize = sizeof(struct xiocb_buffer);
    405	xiocb.plist.xiocb_buffer.buf_offset = offset;
    406	xiocb.plist.xiocb_buffer.buf_ptr = XPTR_FROM_NATIVE(buffer);
    407	xiocb.plist.xiocb_buffer.buf_length = length;
    408
    409	cfe_iocb_dispatch(&xiocb);
    410
    411	if (xiocb.xiocb_status < 0)
    412		return xiocb.xiocb_status;
    413	return xiocb.plist.xiocb_buffer.buf_retlen;
    414}