mp_cpudep.c (cadd87749dc74a8e56ad741188d6740e121db7a4) mp_cpudep.c (c139f23d171c1a032ae57608f8dd72c47cda701e)
1/*-
2 * Copyright (c) 2008 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *

--- 125 unchanged lines hidden (view full) ---

134 if (res < 0)
135 return (ENXIO);
136
137 bsp = OF_instance_to_package(inst);
138 return (powerpc_smp_fill_cpuref(cpuref, bsp));
139}
140
141uint32_t
1/*-
2 * Copyright (c) 2008 Marcel Moolenaar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *

--- 125 unchanged lines hidden (view full) ---

134 if (res < 0)
135 return (ENXIO);
136
137 bsp = OF_instance_to_package(inst);
138 return (powerpc_smp_fill_cpuref(cpuref, bsp));
139}
140
141uint32_t
142cpudep_ap_bootstrap(volatile uint32_t *trcp)
142cpudep_ap_bootstrap(void)
143{
144 uint32_t hid, msr, sp;
145
143{
144 uint32_t hid, msr, sp;
145
146 trcp[0] = 0x2000;
147 trcp[1] = (uint32_t)&cpudep_ap_bootstrap;
148
149 __asm __volatile("mtsprg 0, %0" :: "r"(ap_pcpu));
150 __asm __volatile("sync");
151
146 __asm __volatile("mtsprg 0, %0" :: "r"(ap_pcpu));
147 __asm __volatile("sync");
148
152 trcp[0] = 0x2001;
153 trcp[1] = (uint32_t)pcpup;
154
155 hid = mfspr(SPR_HID0);
156 hid &= ~(HID0_ICE | HID0_DCE);
157 hid &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
158 mtspr(SPR_HID0, hid);
159 isync();
160
149 hid = mfspr(SPR_HID0);
150 hid &= ~(HID0_ICE | HID0_DCE);
151 hid &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
152 mtspr(SPR_HID0, hid);
153 isync();
154
161 trcp[0] = 0x2002;
162 trcp[1] = hid;
163
164 hid |= HID0_ICFI | HID0_DCFI;
165 hid |= HID0_ICE | HID0_DCE;
166 mtspr(SPR_HID0, hid);
167 isync();
168
155 hid |= HID0_ICFI | HID0_DCFI;
156 hid |= HID0_ICE | HID0_DCE;
157 mtspr(SPR_HID0, hid);
158 isync();
159
169 trcp[0] = 0x2003;
170 trcp[1] = hid;
171
172 msr = PSL_IR | PSL_DR | PSL_ME | PSL_RI;
173 mtmsr(msr);
174 isync();
175
160 msr = PSL_IR | PSL_DR | PSL_ME | PSL_RI;
161 mtmsr(msr);
162 isync();
163
176 trcp[0] = 0x2004;
177 trcp[1] = msr;
178
179 hid |= HID0_NAP | HID0_DPM;
180 mtspr(SPR_HID0, hid);
181 isync();
182
164 hid |= HID0_NAP | HID0_DPM;
165 mtspr(SPR_HID0, hid);
166 isync();
167
183 trcp[0] = 0x2005;
184 trcp[1] = hid;
185
186 pcpup->pc_curthread = pcpup->pc_idlethread;
187 pcpup->pc_curpcb = pcpup->pc_curthread->td_pcb;
188 sp = pcpup->pc_curpcb->pcb_sp;
189
168 pcpup->pc_curthread = pcpup->pc_idlethread;
169 pcpup->pc_curpcb = pcpup->pc_curthread->td_pcb;
170 sp = pcpup->pc_curpcb->pcb_sp;
171
190 trcp[0] = 0x2006;
191 trcp[1] = sp;
192
193 return (sp);
194}
195
196int
197powerpc_smp_start_cpu(struct pcpu *pc)
198{
199 phandle_t cpu;
172 return (sp);
173}
174
175int
176powerpc_smp_start_cpu(struct pcpu *pc)
177{
178 phandle_t cpu;
200 volatile uint32_t *trcp;
201 volatile uint8_t *rstvec;
179 volatile uint8_t *rstvec;
202 uint32_t trace;
203 int res, reset, timeout;
204
205 cpu = pc->pc_hwref;
206 res = OF_getprop(cpu, "soft-reset", &reset, sizeof(reset));
207 if (res < 0)
208 return (ENXIO);
209
180 int res, reset, timeout;
181
182 cpu = pc->pc_hwref;
183 res = OF_getprop(cpu, "soft-reset", &reset, sizeof(reset));
184 if (res < 0)
185 return (ENXIO);
186
210 trcp = (uint32_t *)(EXC_RST + 4);
211 trace = *trcp;
212
213 ap_pcpu = pc;
214
215 rstvec = (uint8_t *)(0x80000000 + reset);
216
217 *rstvec = 4;
218 __asm __volatile("sync");
219 DELAY(1);
220 *rstvec = 0;
221 __asm __volatile("sync");
222
223 timeout = 1000;
224 while (!pc->pc_awake && timeout--)
225 DELAY(100);
226
187 ap_pcpu = pc;
188
189 rstvec = (uint8_t *)(0x80000000 + reset);
190
191 *rstvec = 4;
192 __asm __volatile("sync");
193 DELAY(1);
194 *rstvec = 0;
195 __asm __volatile("sync");
196
197 timeout = 1000;
198 while (!pc->pc_awake && timeout--)
199 DELAY(100);
200
227 if (!pc->pc_awake)
228 printf("XXX: timeout (trace=%x; data=%x)\n", trcp[0], trcp[1]);
229
230 return (0);
201 return ((pc->pc_awake) ? 0 : EBUSY);
231}
202}