|
|
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 <string.h> ! 14: #include <stdio.h> ! 15: #include <stdlib.h> ! 16: #include <of.h> ! 17: #include <pci.h> ! 18: #include <cpu.h> ! 19: #include <takeover.h> ! 20: ! 21: extern void call_client_interface(of_arg_t *); ! 22: ! 23: #define boot_rom_bin_start _binary_______boot_rom_bin_start ! 24: #define boot_rom_bin_end _binary_______boot_rom_bin_end ! 25: ! 26: extern char boot_rom_bin_start; ! 27: extern char boot_rom_bin_end; ! 28: ! 29: #if defined(__GNUC__) ! 30: # define UNUSED __attribute__((unused)) ! 31: #else ! 32: # define UNUSED ! 33: #endif ! 34: ! 35: ! 36: /* ! 37: * These functions are just dummy implemented to resolve symbols for linking to other objects ! 38: */ ! 39: ! 40: int ! 41: open(const char *name UNUSED, int flags UNUSED) ! 42: { ! 43: return 0; ! 44: } ! 45: ! 46: int ! 47: close(int fd UNUSED) ! 48: { ! 49: return 0; ! 50: } ! 51: ! 52: ssize_t ! 53: read(int fd UNUSED, void *buf UNUSED, size_t count UNUSED) ! 54: { ! 55: return 0; ! 56: } ! 57: ! 58: int ! 59: ioctl(int fd UNUSED, int req UNUSED, void *data UNUSED) ! 60: { ! 61: return 0; ! 62: } ! 63: ! 64: /* ! 65: * These functions are required for using libc.a ! 66: */ ! 67: ssize_t ! 68: write(int fd, const void *buf, size_t len) ! 69: { ! 70: char dst_buf[512]; ! 71: char *dst_buf_ptr; ! 72: char *src_buf_ptr; ! 73: int i; ! 74: ! 75: src_buf_ptr = (char *) buf; ! 76: if (fd == 1 || fd == 2) ! 77: { ! 78: dst_buf_ptr = &dst_buf[0]; ! 79: for (i = 0; i < len && i < 256; i++) ! 80: { ! 81: *dst_buf_ptr++ = *src_buf_ptr++; ! 82: if (src_buf_ptr[-1] == '\n') ! 83: *dst_buf_ptr++ = '\r'; ! 84: } ! 85: len = dst_buf_ptr - &dst_buf[0]; ! 86: src_buf_ptr = &dst_buf[0]; ! 87: } ! 88: ! 89: if(fd < 0 || fd >= FILEIO_MAX ! 90: || fd_array[fd].type == FILEIO_TYPE_EMPTY ! 91: || fd_array[fd].write == 0) ! 92: return -1; ! 93: ! 94: return fd_array[fd].write(&fd_array[fd], src_buf_ptr, len); ! 95: } ! 96: ! 97: void * ! 98: sbrk(int incr) ! 99: { ! 100: return (void *) -1; ! 101: } ! 102: ! 103: void ! 104: doWait(void) ! 105: { ! 106: static const char *wheel = "|/-\\"; ! 107: static int i = 0; ! 108: volatile int dly = 0xf0000; ! 109: while (dly--); ! 110: printf("\b%c", wheel[i++]); ! 111: i &= 0x3; ! 112: } ! 113: ! 114: void ! 115: quiesce(void) ! 116: { ! 117: of_arg_t arg = { ! 118: p32cast "quiesce", ! 119: 0, 0, ! 120: }; ! 121: call_client_interface(&arg); ! 122: } ! 123: ! 124: int ! 125: startCpu(int num, int addr, int reg) ! 126: { ! 127: of_arg_t arg = { ! 128: p32cast "start-cpu", ! 129: 3, 0, ! 130: {num, addr, reg} ! 131: }; ! 132: call_client_interface(&arg); ! 133: return arg.args[3]; ! 134: } ! 135: ! 136: volatile unsigned long slaveQuitt; ! 137: int takeoverFlag; ! 138: ! 139: void ! 140: main(int argc, char *argv[]) ! 141: { ! 142: phandle_t cpus; ! 143: phandle_t cpu; ! 144: unsigned long slaveMask; ! 145: extern int slaveLoop[]; ! 146: extern int slaveLoopNoTakeover[]; ! 147: int rcode; ! 148: int index = 0; ! 149: int delay = 100; ! 150: unsigned long reg; ! 151: unsigned long msr; ! 152: asm volatile ("mfmsr %0":"=r" (msr)); ! 153: if (msr & 0x1000000000000000) ! 154: takeoverFlag = 0; ! 155: else ! 156: takeoverFlag = 1; ! 157: ! 158: cpus = of_finddevice("/cpus"); ! 159: cpu = of_child(cpus); ! 160: slaveMask = 0; ! 161: while (cpu) { ! 162: char devType[100]; ! 163: *devType = '\0'; ! 164: of_getprop(cpu, "device_type", devType, sizeof(devType)); ! 165: if (strcmp(devType, "cpu") == 0) { ! 166: of_getprop(cpu, "reg", ®, sizeof(reg)); ! 167: if (index) { ! 168: printf("\r\n takeover on cpu%d (%x, %lx) ", index, ! 169: cpu, reg); ! 170: slaveQuitt = -1; ! 171: if (takeoverFlag) ! 172: startCpu(cpu, (int)(unsigned long)slaveLoop, index); ! 173: else ! 174: startCpu(cpu, (int)(unsigned long)slaveLoopNoTakeover, ! 175: index); ! 176: slaveMask |= 0x1 << index; ! 177: delay = 100; ! 178: while (delay-- && slaveQuitt) ! 179: doWait(); ! 180: } ! 181: index++; ! 182: } ! 183: cpu = of_peer(cpu); ! 184: } ! 185: ! 186: ! 187: printf("\r\n takeover on master cpu "); ! 188: quiesce(); ! 189: ! 190: delay = 5; ! 191: while (delay--) ! 192: doWait(); ! 193: if (takeoverFlag) ! 194: rcode = takeover(); ! 195: ! 196: memcpy((void*)TAKEOVERBASEADDRESS, &boot_rom_bin_start, &boot_rom_bin_end - &boot_rom_bin_start); ! 197: flush_cache((void *)TAKEOVERBASEADDRESS, &boot_rom_bin_end - &boot_rom_bin_start); ! 198: index = 0; ! 199: ! 200: while (slaveMask) { ! 201: unsigned long shifter = 0x1 << index; ! 202: if (shifter & slaveMask) { ! 203: slaveQuitt = index; ! 204: while (slaveQuitt); ! 205: slaveMask &= ~shifter; ! 206: } ! 207: index++; ! 208: } ! 209: ! 210: asm volatile(" mtctr %0 ; bctr " : : "r" (TAKEOVERBASEADDRESS+0x180) ); ! 211: } ! 212: ! 213: int ! 214: callback(int argc, char *argv[]) ! 215: { ! 216: /* Dummy, only for takeover */ ! 217: return (0); ! 218: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.