xref: /openbmc/qemu/pc-bios/vof/ci.c (revision fc32b91a88cc9cd560da5488bdca4d69f2bac620)
1fc8c745dSAlexey Kardashevskiy #include "vof.h"
2fc8c745dSAlexey Kardashevskiy 
3fc8c745dSAlexey Kardashevskiy struct prom_args {
4fc8c745dSAlexey Kardashevskiy     uint32_t service;
5fc8c745dSAlexey Kardashevskiy     uint32_t nargs;
6fc8c745dSAlexey Kardashevskiy     uint32_t nret;
7fc8c745dSAlexey Kardashevskiy     uint32_t args[10];
8fc8c745dSAlexey Kardashevskiy };
9fc8c745dSAlexey Kardashevskiy 
10fc8c745dSAlexey Kardashevskiy typedef unsigned long prom_arg_t;
11fc8c745dSAlexey Kardashevskiy 
12fc8c745dSAlexey Kardashevskiy #define ADDR(x) (uint32_t)(x)
13fc8c745dSAlexey Kardashevskiy 
prom_handle(struct prom_args * pargs)14fc8c745dSAlexey Kardashevskiy static int prom_handle(struct prom_args *pargs)
15fc8c745dSAlexey Kardashevskiy {
16fc8c745dSAlexey Kardashevskiy     void *rtasbase;
17fc8c745dSAlexey Kardashevskiy     uint32_t rtassize = 0;
18fc8c745dSAlexey Kardashevskiy     phandle rtas;
19fc8c745dSAlexey Kardashevskiy 
20fc8c745dSAlexey Kardashevskiy     if (strcmp("call-method", (void *)(unsigned long)pargs->service)) {
21fc8c745dSAlexey Kardashevskiy         return -1;
22fc8c745dSAlexey Kardashevskiy     }
23fc8c745dSAlexey Kardashevskiy 
24fc8c745dSAlexey Kardashevskiy     if (strcmp("instantiate-rtas", (void *)(unsigned long)pargs->args[0])) {
25fc8c745dSAlexey Kardashevskiy         return -1;
26fc8c745dSAlexey Kardashevskiy     }
27fc8c745dSAlexey Kardashevskiy 
28fc8c745dSAlexey Kardashevskiy     rtas = ci_finddevice("/rtas");
29fc8c745dSAlexey Kardashevskiy     /* rtas-size is set by QEMU depending of FWNMI support */
30fc8c745dSAlexey Kardashevskiy     ci_getprop(rtas, "rtas-size", &rtassize, sizeof(rtassize));
31fc8c745dSAlexey Kardashevskiy     if (rtassize < hv_rtas_size) {
32fc8c745dSAlexey Kardashevskiy         return -1;
33fc8c745dSAlexey Kardashevskiy     }
34fc8c745dSAlexey Kardashevskiy 
35fc8c745dSAlexey Kardashevskiy     rtasbase = (void *)(unsigned long) pargs->args[2];
36fc8c745dSAlexey Kardashevskiy 
37fc8c745dSAlexey Kardashevskiy     memcpy(rtasbase, hv_rtas, hv_rtas_size);
38fc8c745dSAlexey Kardashevskiy     pargs->args[pargs->nargs] = 0;
39fc8c745dSAlexey Kardashevskiy     pargs->args[pargs->nargs + 1] = pargs->args[2];
40fc8c745dSAlexey Kardashevskiy 
41fc8c745dSAlexey Kardashevskiy     return 0;
42fc8c745dSAlexey Kardashevskiy }
43fc8c745dSAlexey Kardashevskiy 
prom_entry(uint32_t args)44fc8c745dSAlexey Kardashevskiy void prom_entry(uint32_t args)
45fc8c745dSAlexey Kardashevskiy {
46fc8c745dSAlexey Kardashevskiy     if (prom_handle((void *)(unsigned long) args)) {
47fc8c745dSAlexey Kardashevskiy         ci_entry(args);
48fc8c745dSAlexey Kardashevskiy     }
49fc8c745dSAlexey Kardashevskiy }
50fc8c745dSAlexey Kardashevskiy 
call_ci(const char * service,int nargs,int nret,...)51fc8c745dSAlexey Kardashevskiy static int call_ci(const char *service, int nargs, int nret, ...)
52fc8c745dSAlexey Kardashevskiy {
53fc8c745dSAlexey Kardashevskiy     int i;
54fc8c745dSAlexey Kardashevskiy     struct prom_args args;
55fc8c745dSAlexey Kardashevskiy     va_list list;
56fc8c745dSAlexey Kardashevskiy 
57fc8c745dSAlexey Kardashevskiy     args.service = ADDR(service);
58fc8c745dSAlexey Kardashevskiy     args.nargs = nargs;
59fc8c745dSAlexey Kardashevskiy     args.nret = nret;
60fc8c745dSAlexey Kardashevskiy 
61fc8c745dSAlexey Kardashevskiy     va_start(list, nret);
62fc8c745dSAlexey Kardashevskiy     for (i = 0; i < nargs; i++) {
63fc8c745dSAlexey Kardashevskiy         args.args[i] = va_arg(list, prom_arg_t);
64fc8c745dSAlexey Kardashevskiy     }
65fc8c745dSAlexey Kardashevskiy     va_end(list);
66fc8c745dSAlexey Kardashevskiy 
67fc8c745dSAlexey Kardashevskiy     for (i = 0; i < nret; i++) {
68fc8c745dSAlexey Kardashevskiy         args.args[nargs + i] = 0;
69fc8c745dSAlexey Kardashevskiy     }
70fc8c745dSAlexey Kardashevskiy 
71fc8c745dSAlexey Kardashevskiy     if (ci_entry((uint32_t)(&args)) < 0) {
72*21bde1ecSAlexey Kardashevskiy         return -1;
73fc8c745dSAlexey Kardashevskiy     }
74fc8c745dSAlexey Kardashevskiy 
75fc8c745dSAlexey Kardashevskiy     return (nret > 0) ? args.args[nargs] : 0;
76fc8c745dSAlexey Kardashevskiy }
77fc8c745dSAlexey Kardashevskiy 
ci_panic(const char * str)78fc8c745dSAlexey Kardashevskiy void ci_panic(const char *str)
79fc8c745dSAlexey Kardashevskiy {
80fc8c745dSAlexey Kardashevskiy     call_ci("exit", 0, 0);
81fc8c745dSAlexey Kardashevskiy }
82fc8c745dSAlexey Kardashevskiy 
ci_finddevice(const char * path)83fc8c745dSAlexey Kardashevskiy phandle ci_finddevice(const char *path)
84fc8c745dSAlexey Kardashevskiy {
85fc8c745dSAlexey Kardashevskiy     return call_ci("finddevice", 1, 1, path);
86fc8c745dSAlexey Kardashevskiy }
87fc8c745dSAlexey Kardashevskiy 
ci_getprop(phandle ph,const char * propname,void * prop,int len)88fc8c745dSAlexey Kardashevskiy uint32_t ci_getprop(phandle ph, const char *propname, void *prop, int len)
89fc8c745dSAlexey Kardashevskiy {
90fc8c745dSAlexey Kardashevskiy     return call_ci("getprop", 4, 1, ph, propname, prop, len);
91fc8c745dSAlexey Kardashevskiy }
92