|
|
1.1 root 1: /******************************************************************************
2: * Copyright (c) 2004, 2008 IBM Corporation
3: * All rights reserved.
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
8: *
9: * Contributors:
10: * IBM Corporation - initial implementation
11: *****************************************************************************/
12:
13: #include <stdarg.h>
14: #include <stdio.h>
15: #include <rtas.h>
16: #include <of.h>
17: #include <types.h>
18: #include "kernel.h"
19:
20: typedef int rtas_arg_t;
21:
22: typedef struct {
23: int token;
24: int nargs;
25: int nret;
26: rtas_arg_t args[16];
27: rtas_arg_t *rets; /* Pointer to return values in args[]. */
28: } rtas_args_t;
29:
30: rtas_args_t rtas_args;
31:
32: typedef struct {
33: void *rtas_start;
34: void *rtas_entry;
35: int rtas_size;
36: phandle_t dev;
37: } rtas_t;
38:
39: extern rtas_t _rtas;
40: static int instantiate_rtas(void);
41: void rtas_call_entry(rtas_args_t *, void *, void *);
42:
43: int
44: rtas_token(const char *service)
45: {
46: int token;
47: int retVal;
48: if (_rtas.dev == 0)
49: instantiate_rtas();
50:
51: retVal = of_getprop(_rtas.dev, service, &token, sizeof(token));
52: if (retVal == -1) {
53: token = 0;
54: }
55: return token;
56: }
57:
58: int
59: rtas_call(int token, int nargs, int nret, int *outputs, ...)
60: {
61: va_list list;
62: int i;
63:
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));
71: }
72: va_end(list);
73:
74: for (i = 0; i < nret; ++i)
75: rtas_args.rets[i] = 0;
76:
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];
81: #if 0
82: printf("rtas call %x %x %x args: %x %x %x %x %x %x %x %x\n",
83: token, nargs, nret,
84: rtas_args.args[0],
85: rtas_args.args[1],
86: rtas_args.args[2],
87: rtas_args.args[3],
88: rtas_args.args[4], rtas_args.args[5], outputs[0], outputs[1]);
89: #endif
90: return ((nret > 0) ? rtas_args.rets[0] : 0);
91: }
92:
93: rtas_t _rtas;
94:
95: static int
96: instantiate_rtas(void)
97: {
98: long long *rtas_mem_space;
99: ihandle_t ihandle;
100: _rtas.dev = of_finddevice("/rtas");
101: if ((long) _rtas.dev < 0) {
102: printf("Could not open /rtas\n");
103: return -1;
104: }
105:
106: of_getprop(_rtas.dev, "rtas-size", &_rtas.rtas_size,
107: sizeof(_rtas.rtas_size));
108:
109: if (_rtas.rtas_size <= 0) {
110: printf("Size of rtas (%x) too small to make sense\n",
111: _rtas.rtas_size);
112: return -1;
113: }
114:
115: rtas_mem_space = (long long *) malloc_aligned(_rtas.rtas_size, 0x100);
116:
117: if (!rtas_mem_space) {
118: printf("Failed to allocated memory for RTAS\n");
119: return -1;
120: }
121:
122: ihandle = of_open("/rtas");
123:
124: if ((long) ihandle < 0) {
125: printf("Could not open /rtas\n");
126: return -1;
127: }
128:
129: if ((long) (_rtas.rtas_entry = of_call_method_3("instantiate-rtas",
130: ihandle,
131: p32cast rtas_mem_space))
132: > 0) {
133: _rtas.rtas_start = rtas_mem_space;
134: } else {
135: printf("instantiate-rtas failed\n");
136: return -1;
137: }
138: #if 0
139: printf("\ninstantiate-rtas at %x size %x entry %x\n",
140: _rtas.rtas_start, _rtas.rtas_size, _rtas.rtas_entry);
141: #endif
142: return 0;
143: }
144:
145: static int read_pci_config_token = 0;
146: static int write_pci_config_token = 0;
147: static int ibm_read_pci_config_token = 0;
148: static int ibm_write_pci_config_token = 0;
149: static int ibm_update_flash_64_and_reboot_token = 0;
150: static int ibm_update_flash_64_token = 0;
151: static int manage_flash_token = 0;
152: static int system_reboot_token = 0;
153: static int get_time_of_day_token = 0;
154: static int set_time_of_day_token = 0;
155: static int start_cpu_token = 0;
156: static int stop_self_token = 0;
157:
158: void
159: rtas_init()
160: {
161: int ret;
162: ret = instantiate_rtas();
163: if (ret)
164: return;
165: read_pci_config_token = rtas_token("read-pci-config");
166: ibm_read_pci_config_token = rtas_token("ibm,read-pci-config");
167: write_pci_config_token = rtas_token("write-pci-config");
168: ibm_write_pci_config_token = rtas_token("ibm,write-pci-config");
169: ibm_update_flash_64_and_reboot_token =
170: rtas_token("ibm,update-flash-64-and-reboot");
171: ibm_update_flash_64_token = rtas_token("ibm,update-flash-64");
172: manage_flash_token = rtas_token("ibm,manage-flash-image");
173: system_reboot_token = rtas_token("system-reboot");
174: get_time_of_day_token = rtas_token("get-time-of-day");
175: set_time_of_day_token = rtas_token("set-time-of-day");
176: start_cpu_token = rtas_token("start-cpu");
177: stop_self_token = rtas_token("stop-self");
178: }
179:
180:
181: int
182: rtas_pci_config_read(long long puid, int size, int bus, int devfn, int offset)
183: {
184: int value[2];
185:
186: if (ibm_read_pci_config_token && puid) {
187: rtas_call(ibm_read_pci_config_token, 4, 2, value,
188: bus << 16 | devfn << 8 | offset,
189: puid >> 32, puid & 0xffffffffULL, size);
190: } else if (read_pci_config_token) {
191: rtas_call(read_pci_config_token, 2, 2, value,
192: bus << 16 | devfn << 8 | offset, size);
193: }
194:
195: return value[1];
196: }
197:
198: int
199: rtas_pci_config_write(long long puid, int size, int bus, int devfn,
200: int offset, int value)
201: {
202: int rc;
203:
204: if (ibm_write_pci_config_token && puid) {
205: rtas_call(ibm_write_pci_config_token, 5, 1, &rc,
206: bus << 16 | devfn << 8 | offset,
207: puid >> 32, puid & 0xffffffffULL, size, value);
208: } else
209: rtas_call(write_pci_config_token, 3, 1, &rc,
210: bus << 16 | devfn << 8 | offset, size, value);
211:
212: return rc;
213: }
214:
215: /* a simple blocklist like this will us give no animation during flashing */
216:
217: struct block_list {
218: long long size; //size of blocklist in bytes
219: long long address; //address of memory area
220: long long length; //lenght of memory area
221: };
222:
223: int
224: rtas_ibm_update_flash_64_and_reboot(long long address, long long length)
225: {
226: int rc;
227: struct block_list block_list;
228: block_list.size = sizeof(block_list);
229: block_list.address = address;
230: block_list.length = length;
231: if (ibm_update_flash_64_and_reboot_token)
232: rtas_call(ibm_update_flash_64_and_reboot_token, 1, 1, &rc,
233: &block_list);
234:
235: return rc;
236: }
237:
238: int
239: rtas_ibm_manage_flash(int mode)
240: {
241: int rc;
242: if (manage_flash_token)
243: rtas_call(manage_flash_token, 1, 1, &rc, mode);
244: return rc;
245: }
246:
247: int
248: rtas_ibm_update_flash_64(long long address, long long length)
249: {
250: int rc;
251: struct block_list block_list;
252: block_list.size = sizeof(block_list);
253: block_list.address = address;
254: block_list.length = length;
255: if (ibm_update_flash_64_token)
256: rtas_call(ibm_update_flash_64_token, 1, 1, &rc, &block_list);
257:
258: return rc;
259: }
260:
261: int
262: rtas_system_reboot()
263: {
264: int rc;
265: if (system_reboot_token)
266: rtas_call(system_reboot_token, 0, 1, &rc);
267: return rc;
268: }
269:
270:
271: int
272: rtas_get_time_of_day(dtime * get)
273: {
274: int rc = -1;
275: unsigned int year;
276: unsigned int month;
277: unsigned int day;
278: unsigned int hour;
279: unsigned int minute;
280: unsigned int second;
281: unsigned int nano;
282:
283: if (get_time_of_day_token)
284: rtas_call(get_time_of_day_token, 0, 8, &rc, &year, &month, &day,
285: &hour, &minute, &second, &nano);
286:
287: get->year = year;
288: get->month = month;
289: get->day = day;
290: get->hour = hour;
291: get->minute = minute;
292: get->second = second;
293: get->nano = nano;
294:
295: return rc;
296: }
297:
298: int
299: rtas_set_time_of_day(dtime * set)
300: {
301: int rc = -1;
302: if (set_time_of_day_token)
303: rtas_call(set_time_of_day_token, 7, 1, &rc, set->year,
304: set->month, set->day, set->hour, set->minute,
305: set->second, set->nano);
306: return rc;
307: }
308:
309:
310: int
311: rtas_start_cpu(int pid, thread_t func_ptr, int r3)
312: {
313: int rc;
314: if (start_cpu_token)
315: rtas_call(start_cpu_token, 3, 1, &rc, pid,
316: (int) (long) func_ptr, (int) r3);
317: printk("start-cpu called %d %x %x %x\n", rc, start_cpu_token, pid,
318: (long) func_ptr);
319: return rc;
320: }
321:
322: int
323: rtas_stop_self()
324: {
325: int rc;
326: // fixme
327: stop_self_token = 0x20;
328:
329: if (stop_self_token) {
330: rtas_call(stop_self_token, 0, 1, &rc);
331: printk("TOK\n");
332: }
333: return rc;
334: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.