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