summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2014-10-09 13:58:40 +0000
committermpi <mpi@openbsd.org>2014-10-09 13:58:40 +0000
commitdb9a4012d1808d837c00966b0c886f51cb478902 (patch)
tree1a264979837aefe9a8178d7a6a1d597b764d2f78
parentAdd POLLHUP to expected revents for POLLIN on writer EOF. (diff)
downloadwireguard-openbsd-db9a4012d1808d837c00966b0c886f51cb478902.tar.xz
wireguard-openbsd-db9a4012d1808d837c00966b0c886f51cb478902.zip
Properly initialize secondary CPUs on 64bit machines.
Due to a bug in our Openfirmware client interface on G5, the call to OF_finddevice() in cpu_spinup() will never return if the given argument is on the stack. Use a workaround for the moment and put it in the bss. Yes, this is ugly, but it makes GENERIC.MP ``usable'' on Powermac7,2 and 7,3 and does not freeze your machine during the first boot. Issue also reported by "The Mouse" on ppc@, tested by landry@
-rw-r--r--sys/arch/macppc/macppc/cpu.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/sys/arch/macppc/macppc/cpu.c b/sys/arch/macppc/macppc/cpu.c
index 09464da5cfd..10566a2e31f 100644
--- a/sys/arch/macppc/macppc/cpu.c
+++ b/sys/arch/macppc/macppc/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.78 2014/10/08 10:12:41 mpi Exp $ */
+/* $OpenBSD: cpu.c,v 1.79 2014/10/09 13:58:40 mpi Exp $ */
/*
* Copyright (c) 1997 Per Fogelstrom
@@ -572,15 +572,25 @@ void cpu_spinup_trampoline(void);
struct cpu_hatch_data {
uint64_t tb;
struct cpu_info *ci;
- int running;
- int hid0;
+ uint32_t hid0;
+ uint64_t hid1;
+ uint64_t hid4;
+ uint64_t hid5;
int l2cr;
int sdr1;
+ int running;
};
volatile struct cpu_hatch_data *cpu_hatch_data;
volatile void *cpu_hatch_stack;
+/*
+ * XXX Due to a bug in our OpenFirmware interface/memory mapping,
+ * machines with 64bit CPUs hang in the OF_finddevice() call below
+ * if this array is stored on the stack.
+ */
+char cpuname[64];
+
int
cpu_spinup(struct device *self, struct cpu_info *ci)
{
@@ -592,7 +602,6 @@ cpu_spinup(struct device *self, struct cpu_info *ci)
int size = 0;
char *cp;
u_char *reset_cpu;
- char cpuname[64];
u_int node;
/*
@@ -620,8 +629,14 @@ cpu_spinup(struct device *self, struct cpu_info *ci)
h->ci = ci;
h->running = 0;
h->hid0 = ppc_mfhid0();
- h->l2cr = ppc_mfl2cr();
h->sdr1 = ppc_mfsdr1();
+ if (ppc_proc_is_64b) {
+ h->hid1 = ppc64_mfhid1();
+ h->hid4 = ppc64_mfhid4();
+ h->hid5 = ppc64_mfhid5();
+ } else {
+ h->l2cr = ppc_mfl2cr();
+ }
cpu_hatch_data = h;
__asm volatile ("sync; isync");
@@ -747,9 +762,22 @@ cpu_hatch(void)
for (i = 0; i < 16; i++)
ppc_mtsrin(PPC_KERNEL_SEG0 + i, i << ADDR_SR_SHIFT);
- ppc_mthid0(h->hid0);
- if (h->l2cr != 0) {
+ if (ppc_proc_is_64b) {
+ /*
+ * The Hardware Interrupt Offset Register should be
+ * cleared after initialization.
+ */
+ ppc_mthior(0);
+ __asm volatile ("sync");
+
+ ppc_mthid0(h->hid0);
+ ppc64_mthid1(h->hid1);
+ ppc64_mthid4(h->hid4);
+ ppc64_mthid5(h->hid5);
+ } else if (h->l2cr != 0) {
u_int x;
+
+ ppc_mthid0(h->hid0);
ppc_mtl2cr(h->l2cr & ~L2CR_L2E);
/* Wait for L2 clock to be stable (640 L2 clocks). */
@@ -760,7 +788,7 @@ cpu_hatch(void)
do {
x = ppc_mfl2cr();
} while (x & L2CR_L2IP);
-
+
ppc_mtl2cr(h->l2cr);
}
ppc_mtsdr1(h->sdr1);