1 /******************************************************************************
2 * Copyright (c) 2004, 2008 IBM Corporation
4 * This program and the accompanying materials
5 * are made available under the terms of the BSD License
6 * which accompanies this distribution, and is available at
7 * http://www.opensource.org/licenses/bsd-license.php
10 * IBM Corporation - initial implementation
11 *****************************************************************************/
20 typedef int rtas_arg_t;
27 rtas_arg_t *rets; /* Pointer to return values in args[]. */
30 rtas_args_t rtas_args;
40 static int instantiate_rtas(void);
41 void rtas_call_entry(rtas_args_t *, void *, void *);
44 rtas_token(const char *service)
51 retVal = of_getprop(_rtas.dev, service, &token, sizeof(token));
59 rtas_call(int token, int nargs, int nret, int *outputs, ...)
64 rtas_args.token = token;
65 rtas_args.nargs = nargs;
66 rtas_args.nret = nret;
67 rtas_args.rets = (rtas_arg_t *) & (rtas_args.args[nargs]);
68 va_start(list, outputs);
69 for (i = 0; i < nargs; ++i) {
70 rtas_args.args[i] = (rtas_arg_t) (va_arg(list, unsigned int));
74 for (i = 0; i < nret; ++i)
75 rtas_args.rets[i] = 0;
77 rtas_call_entry(&rtas_args, _rtas.rtas_start, _rtas.rtas_entry);
78 if (nret > 0 && outputs != 0)
79 for (i = 0; i < nret; i++)
80 outputs[i] = rtas_args.rets[i];
82 printf("rtas call %x %x %x args: %x %x %x %x %x %x %x %x\n",
88 rtas_args.args[4], rtas_args.args[5], outputs[0], outputs[1]);
90 return ((nret > 0) ? rtas_args.rets[0] : 0);
96 instantiate_rtas(void)
98 long long *rtas_mem_space;
101 _rtas.dev = of_finddevice("/rtas");
102 if ((long) _rtas.dev < 0) {
103 printf("\nCould not open /rtas\n");
107 of_getprop(_rtas.dev, "rtas-size", &_rtas.rtas_size,
108 sizeof(_rtas.rtas_size));
110 if (_rtas.rtas_size <= 0) {
111 printf("\nSize of rtas (%x) too small to make sense\n",
116 rtas_mem_space = (long long *) malloc_aligned(_rtas.rtas_size, 0x100);
118 if (!rtas_mem_space) {
119 printf("\nFailed to allocated memory for RTAS\n");
123 ihandle = of_open("/rtas");
125 if ((long) ihandle < 0) {
126 printf("Could not open /rtas\n");
130 if ((long) (_rtas.rtas_entry = of_call_method_3("instantiate-rtas",
132 p32cast rtas_mem_space))
134 _rtas.rtas_start = rtas_mem_space;
136 printf("instantiate-rtas failed\n");
140 printf("\ninstantiate-rtas at %x size %x entry %x\n",
141 _rtas.rtas_start, _rtas.rtas_size, _rtas.rtas_entry);
146 static int read_pci_config_token = 0;
147 static int write_pci_config_token = 0;
148 static int ibm_read_pci_config_token = 0;
149 static int ibm_write_pci_config_token = 0;
150 static int get_time_of_day_token = 0;
156 ret = instantiate_rtas();
159 read_pci_config_token = rtas_token("read-pci-config");
160 ibm_read_pci_config_token = rtas_token("ibm,read-pci-config");
161 write_pci_config_token = rtas_token("write-pci-config");
162 ibm_write_pci_config_token = rtas_token("ibm,write-pci-config");
163 get_time_of_day_token = rtas_token("get-time-of-day");
168 rtas_pci_config_read(long long puid, int size, int bus, int devfn, int offset)
172 if (ibm_read_pci_config_token && puid) {
173 rtas_call(ibm_read_pci_config_token, 4, 2, value,
174 bus << 16 | devfn << 8 | offset,
175 puid >> 32, puid & 0xffffffffULL, size);
176 } else if (read_pci_config_token) {
177 rtas_call(read_pci_config_token, 2, 2, value,
178 bus << 16 | devfn << 8 | offset, size);
185 rtas_pci_config_write(long long puid, int size, int bus, int devfn,
186 int offset, int value)
190 if (ibm_write_pci_config_token && puid) {
191 rtas_call(ibm_write_pci_config_token, 5, 1, &rc,
192 bus << 16 | devfn << 8 | offset,
193 puid >> 32, puid & 0xffffffffULL, size, value);
195 rtas_call(write_pci_config_token, 3, 1, &rc,
196 bus << 16 | devfn << 8 | offset, size, value);
202 rtas_get_time_of_day(dtime * get)
213 if (get_time_of_day_token)
214 rtas_call(get_time_of_day_token, 0, 8, &rc, &year, &month, &day,
215 &hour, &minute, &second, &nano);
221 get->minute = minute;
222 get->second = second;