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