aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/fw/cfe
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
committerWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
commita07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch)
tree84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/fw/cfe
downloadohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz
ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/fw/cfe')
-rw-r--r--arch/mips/fw/cfe/Makefile6
-rw-r--r--arch/mips/fw/cfe/cfe_api.c414
-rw-r--r--arch/mips/fw/cfe/cfe_api_int.h135
3 files changed, 555 insertions, 0 deletions
diff --git a/arch/mips/fw/cfe/Makefile b/arch/mips/fw/cfe/Makefile
new file mode 100644
index 000000000..55b77633e
--- /dev/null
+++ b/arch/mips/fw/cfe/Makefile
@@ -0,0 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0-only
2#
3# Makefile for the Broadcom Common Firmware Environment support
4#
5
6lib-y += cfe_api.o
diff --git a/arch/mips/fw/cfe/cfe_api.c b/arch/mips/fw/cfe/cfe_api.c
new file mode 100644
index 000000000..0c9c97ab2
--- /dev/null
+++ b/arch/mips/fw/cfe/cfe_api.c
@@ -0,0 +1,414 @@
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}
diff --git a/arch/mips/fw/cfe/cfe_api_int.h b/arch/mips/fw/cfe/cfe_api_int.h
new file mode 100644
index 000000000..61a665d44
--- /dev/null
+++ b/arch/mips/fw/cfe/cfe_api_int.h
@@ -0,0 +1,135 @@
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * Copyright (C) 2000, 2001, 2002 Broadcom Corporation
4 */
5#ifndef CFE_API_INT_H
6#define CFE_API_INT_H
7
8/*
9 * Constants.
10 */
11#define CFE_CMD_FW_GETINFO 0
12#define CFE_CMD_FW_RESTART 1
13#define CFE_CMD_FW_BOOT 2
14#define CFE_CMD_FW_CPUCTL 3
15#define CFE_CMD_FW_GETTIME 4
16#define CFE_CMD_FW_MEMENUM 5
17#define CFE_CMD_FW_FLUSHCACHE 6
18
19#define CFE_CMD_DEV_GETHANDLE 9
20#define CFE_CMD_DEV_ENUM 10
21#define CFE_CMD_DEV_OPEN 11
22#define CFE_CMD_DEV_INPSTAT 12
23#define CFE_CMD_DEV_READ 13
24#define CFE_CMD_DEV_WRITE 14
25#define CFE_CMD_DEV_IOCTL 15
26#define CFE_CMD_DEV_CLOSE 16
27#define CFE_CMD_DEV_GETINFO 17
28
29#define CFE_CMD_ENV_ENUM 20
30#define CFE_CMD_ENV_GET 22
31#define CFE_CMD_ENV_SET 23
32#define CFE_CMD_ENV_DEL 24
33
34#define CFE_CMD_MAX 32
35
36#define CFE_CMD_VENDOR_USE 0x8000 /* codes above this are for customer use */
37
38/*
39 * Structures.
40 */
41
42/* eeek, signed "pointers" */
43typedef s64 cfe_xptr_t;
44
45struct xiocb_buffer {
46 u64 buf_offset; /* offset on device (bytes) */
47 cfe_xptr_t buf_ptr; /* pointer to a buffer */
48 u64 buf_length; /* length of this buffer */
49 u64 buf_retlen; /* returned length (for read ops) */
50 u64 buf_ioctlcmd; /* IOCTL command (used only for IOCTLs) */
51};
52
53struct xiocb_inpstat {
54 u64 inp_status; /* 1 means input available */
55};
56
57struct xiocb_envbuf {
58 s64 enum_idx; /* 0-based enumeration index */
59 cfe_xptr_t name_ptr; /* name string buffer */
60 s64 name_length; /* size of name buffer */
61 cfe_xptr_t val_ptr; /* value string buffer */
62 s64 val_length; /* size of value string buffer */
63};
64
65struct xiocb_cpuctl {
66 u64 cpu_number; /* cpu number to control */
67 u64 cpu_command; /* command to issue to CPU */
68 u64 start_addr; /* CPU start address */
69 u64 gp_val; /* starting GP value */
70 u64 sp_val; /* starting SP value */
71 u64 a1_val; /* starting A1 value */
72};
73
74struct xiocb_time {
75 s64 ticks; /* current time in ticks */
76};
77
78struct xiocb_exitstat{
79 s64 status;
80};
81
82struct xiocb_meminfo {
83 s64 mi_idx; /* 0-based enumeration index */
84 s64 mi_type; /* type of memory block */
85 u64 mi_addr; /* physical start address */
86 u64 mi_size; /* block size */
87};
88
89struct xiocb_fwinfo {
90 s64 fwi_version; /* major, minor, eco version */
91 s64 fwi_totalmem; /* total installed mem */
92 s64 fwi_flags; /* various flags */
93 s64 fwi_boardid; /* board ID */
94 s64 fwi_bootarea_va; /* VA of boot area */
95 s64 fwi_bootarea_pa; /* PA of boot area */
96 s64 fwi_bootarea_size; /* size of boot area */
97 s64 fwi_reserved1;
98 s64 fwi_reserved2;
99 s64 fwi_reserved3;
100};
101
102struct cfe_xiocb {
103 u64 xiocb_fcode; /* IOCB function code */
104 s64 xiocb_status; /* return status */
105 s64 xiocb_handle; /* file/device handle */
106 u64 xiocb_flags; /* flags for this IOCB */
107 u64 xiocb_psize; /* size of parameter list */
108 union {
109 /* buffer parameters */
110 struct xiocb_buffer xiocb_buffer;
111
112 /* input status parameters */
113 struct xiocb_inpstat xiocb_inpstat;
114
115 /* environment function parameters */
116 struct xiocb_envbuf xiocb_envbuf;
117
118 /* CPU control parameters */
119 struct xiocb_cpuctl xiocb_cpuctl;
120
121 /* timer parameters */
122 struct xiocb_time xiocb_time;
123
124 /* memory arena info parameters */
125 struct xiocb_meminfo xiocb_meminfo;
126
127 /* firmware information */
128 struct xiocb_fwinfo xiocb_fwinfo;
129
130 /* Exit Status */
131 struct xiocb_exitstat xiocb_exitstat;
132 } plist;
133};
134
135#endif /* CFE_API_INT_H */