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