Merge remote-tracking branch 'remotes/dgilbert-gitlab/tags/pull-migration-20210726a...
[qemu/armbru.git] / pc-bios / vof / ci.c
blobfc4821b3e970600431af31e39134ff119f0e4127
1 #include "vof.h"
3 struct prom_args {
4 uint32_t service;
5 uint32_t nargs;
6 uint32_t nret;
7 uint32_t args[10];
8 };
10 typedef unsigned long prom_arg_t;
12 #define ADDR(x) (uint32_t)(x)
14 static int prom_handle(struct prom_args *pargs)
16 void *rtasbase;
17 uint32_t rtassize = 0;
18 phandle rtas;
20 if (strcmp("call-method", (void *)(unsigned long)pargs->service)) {
21 return -1;
24 if (strcmp("instantiate-rtas", (void *)(unsigned long)pargs->args[0])) {
25 return -1;
28 rtas = ci_finddevice("/rtas");
29 /* rtas-size is set by QEMU depending of FWNMI support */
30 ci_getprop(rtas, "rtas-size", &rtassize, sizeof(rtassize));
31 if (rtassize < hv_rtas_size) {
32 return -1;
35 rtasbase = (void *)(unsigned long) pargs->args[2];
37 memcpy(rtasbase, hv_rtas, hv_rtas_size);
38 pargs->args[pargs->nargs] = 0;
39 pargs->args[pargs->nargs + 1] = pargs->args[2];
41 return 0;
44 void prom_entry(uint32_t args)
46 if (prom_handle((void *)(unsigned long) args)) {
47 ci_entry(args);
51 static int call_ci(const char *service, int nargs, int nret, ...)
53 int i;
54 struct prom_args args;
55 va_list list;
57 args.service = ADDR(service);
58 args.nargs = nargs;
59 args.nret = nret;
61 va_start(list, nret);
62 for (i = 0; i < nargs; i++) {
63 args.args[i] = va_arg(list, prom_arg_t);
65 va_end(list);
67 for (i = 0; i < nret; i++) {
68 args.args[nargs + i] = 0;
71 if (ci_entry((uint32_t)(&args)) < 0) {
72 return -1;
75 return (nret > 0) ? args.args[nargs] : 0;
78 void ci_panic(const char *str)
80 call_ci("exit", 0, 0);
83 phandle ci_finddevice(const char *path)
85 return call_ci("finddevice", 1, 1, path);
88 uint32_t ci_getprop(phandle ph, const char *propname, void *prop, int len)
90 return call_ci("getprop", 4, 1, ph, propname, prop, len);