|
|
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.