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