Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 10 Feb 2008 22:07:39 GMT
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 135174 for review
Message-ID:  <200802102207.m1AM7d2c088594@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=135174

Change 135174 by marcel@marcel_xcllnt on 2008/02/10 22:07:04

	Refactor the SMP code to take into account the future
	integration of the BookE support. Abstract access to
	OFW, behind CPU-specific functions. This makes
	powerpc/powerpc/mp_machdep.c CPU-independent. Put the
	CPU-specific functions in powerpc/aim/mp_cpudep.c
	Introduce struct cpuref for the handshake between
	these two.
	
	Apple hardware doesn't implement the start-cpu OF
	call, so remove it again and instead copy the logic
	from NetBSD.

Affected files ...

.. //depot/projects/powerpc/sys/conf/files.powerpc#14 edit
.. //depot/projects/powerpc/sys/powerpc/aim/locore.S#3 edit
.. //depot/projects/powerpc/sys/powerpc/aim/mp_cpudep.c#1 add
.. //depot/projects/powerpc/sys/powerpc/aim/ofw_machdep.c#4 edit
.. //depot/projects/powerpc/sys/powerpc/include/ofw_machdep.h#3 edit
.. //depot/projects/powerpc/sys/powerpc/include/pcpu.h#9 edit
.. //depot/projects/powerpc/sys/powerpc/include/smp.h#5 edit
.. //depot/projects/powerpc/sys/powerpc/powerpc/mp_machdep.c#14 edit

Differences ...

==== //depot/projects/powerpc/sys/conf/files.powerpc#14 (text+ko) ====

@@ -63,6 +63,7 @@
 powerpc/aim/locore.S		optional	aim no-obj
 powerpc/aim/machdep.c		optional	aim
 powerpc/aim/mmu_oea.c		optional	aim
+powerpc/aim/mp_cpudep.c		optional	smp
 powerpc/aim/nexus.c		optional	aim
 powerpc/aim/ofw_machdep.c	optional	aim
 powerpc/aim/ofwmagic.S		optional	aim

==== //depot/projects/powerpc/sys/powerpc/aim/locore.S#3 (text+ko) ====

@@ -188,19 +188,14 @@
  */
 	.globl  __start_ap
 __start_ap:
-	li	8,0
-	li	9,0x100
-	mtctr	9
-1:
-	dcbf	0,8
-	icbi	0,8
-	addi	8,8,0x20
-	bdnz	1b
+#if 0
+	li	0,0
+	mtmsr	0
 
-	sync
 	isync
 
-	bl	mi_startup
+	bl	powerpc_smp_ap_init
+#endif
 9:
 	b       9b
 

==== //depot/projects/powerpc/sys/powerpc/aim/ofw_machdep.c#4 (text+ko) ====

@@ -278,33 +278,6 @@
 }
 
 void
-OF_start_cpu(phandle_t cpu, void (*entry)(void *), void *arg)
-{
-	static struct {
-		cell_t	name;
-		cell_t	nargs;
-		cell_t	nreturns;
-		cell_t	cpu;
-		cell_t	entry;
-		cell_t	arg;
-	} args = {
-		(cell_t)"start-cpu",
-		3,
-		0
-	};
-
-	printf("XXX: %s: cpu=%x, entry=%p, arg=%p...", __func__, cpu,
-	    entry, arg);
-
-	args.cpu = (cell_t)cpu;
-	args.entry = (cell_t)entry;
-	args.arg = (cell_t)arg;
-	openfirmware(&args);
-
-	printf(" ok\n");
-}
-
-void
 OF_getetheraddr(device_t dev, u_char *addr)
 {
 	phandle_t	node;

==== //depot/projects/powerpc/sys/powerpc/include/ofw_machdep.h#3 (text+ko) ====

@@ -32,6 +32,5 @@
 
 int  OF_decode_addr(phandle_t, int, bus_space_tag_t *, bus_space_handle_t *);
 void OF_getetheraddr(device_t dev, u_char *addr);
-void OF_start_cpu(phandle_t, void (*)(void *), void *);
 
 #endif /* _MACHINE_OFW_MACHDEP_H_ */

==== //depot/projects/powerpc/sys/powerpc/include/pcpu.h#9 (text+ko) ====

@@ -40,6 +40,7 @@
 	int		pc_inside_intr;					\
 	struct pmap	*pc_curpmap;		/* current pmap */	\
 	struct thread   *pc_fputhread;          /* current fpu user */  \
+	uintptr_t	pc_hwref;					\
 	int		pc_bsp:1;					\
 	int		pc_awake:1;					\
 	uint32_t	pc_ipimask;					\

==== //depot/projects/powerpc/sys/powerpc/include/smp.h#5 (text+ko) ====

@@ -45,6 +45,16 @@
 void	ipi_selected(cpumask_t cpus, int ipi);
 void	ipi_self(int ipi);
 
+struct cpuref {
+	uintptr_t	cr_hwref;
+	u_int		cr_cpuid;
+};
+
+int	powerpc_smp_first_cpu(struct cpuref *);
+int	powerpc_smp_get_bsp(struct cpuref *);
+int	powerpc_smp_next_cpu(struct cpuref *);
+int	powerpc_smp_start_cpu(struct pcpu *);
+
 #endif /* !LOCORE */
 #endif /* _KERNEL */
 #endif /* !_MACHINE_SMP_H */

==== //depot/projects/powerpc/sys/powerpc/powerpc/mp_machdep.c#14 (text+ko) ====

@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2006 Marcel Moolenaar
+ * Copyright (c) 2006-2008 Marcel Moolenaar
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -25,12 +25,13 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/powerpc/powerpc/mp_machdep.c,v 1.13 2006/05/16 14:32:17 phk Exp $");
+__FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/bus.h>
+#include <sys/malloc.h>
 #include <sys/pcpu.h>
 #include <sys/smp.h>
 
@@ -39,9 +40,6 @@
 #include <machine/intr_machdep.h>
 #include <machine/smp.h>
 
-#include <dev/ofw/openfirm.h>
-#include <machine/ofw_machdep.h>
-
 #include "pic_if.h"
 
 extern void __start_ap(void *);
@@ -56,29 +54,14 @@
 void
 cpu_mp_setmaxid(void)
 {
-	char buf[8];
-	phandle_t dev, root;
-	int res;
+	struct cpuref cpuref;
+	int error;
 
 	mp_ncpus = 0;
-
-	/*
-	 * Count the actual number of processors listed in the OFW
-	 * device tree.
-	 */
-	root = OF_peer(0);
-	dev = OF_child(root);
-	while (dev != 0) {
-		res = OF_getprop(dev, "name", buf, sizeof(buf));
-		if (res < 0 || strcmp(buf, "cpus") != 0) {
-			dev = OF_peer(dev);
-			continue;
-		}
-		for (dev = OF_child(dev); dev != 0; dev = OF_peer(dev)) {
-			res = OF_getprop(dev, "device_type", buf, sizeof(buf));
-			if (res > 0 && strcmp(buf, "cpu") == 0)
-				mp_ncpus++;
-		}
+	error = powerpc_smp_first_cpu(&cpuref);
+	while (!error) {
+		mp_ncpus++;
+		error = powerpc_smp_next_cpu(&cpuref);
 	}
 	/* Sanity. */
 	if (mp_ncpus == 0)
@@ -86,7 +69,7 @@
 
 	/*
 	 * Set the largest cpuid we're going to use. This is necessary
-	 * for * VM initialization.
+	 * for VM initialization.
 	 */
 	mp_maxid = min(mp_ncpus, MAXCPU) - 1;
 }
@@ -104,58 +87,39 @@
 void
 cpu_mp_start(void)
 {
-	char buf[8];
+	struct cpuref bsp, cpu;
 	struct pcpu *pc;
-	ihandle_t inst;
-	phandle_t bsp, chosen, dev, root;
-	int cpuid, res;
+	int error;
 
-	/* Get the p-handle of the BSP. */
-	chosen = OF_finddevice("/chosen");
-	res = OF_getprop(chosen, "cpu", &inst, sizeof(inst));
-	bsp = (res > 0) ? OF_instance_to_package(inst) : -1;
+	error = powerpc_smp_get_bsp(&bsp);
+	KASSERT(error == 0, ("Don't know BSP"));
+	KASSERT(bsp.cr_cpuid == 0, ("%s: cpuid != 0", __func__));
 
-	root = OF_peer(0);
-	dev = OF_child(root);
-	while (dev != 0) {
-		res = OF_getprop(dev, "name", buf, sizeof(buf));
-		if (res > 0 && !strcmp(buf, "cpus"))
-			break;
-		dev = OF_peer(dev);
-	}
-	KASSERT(dev != 0, ("%s: dev == 0", __func__));
-	for (dev = OF_child(dev); dev != 0; dev = OF_peer(dev)) {
-		res = OF_getprop(dev, "device_type", buf, sizeof(buf));
-		if (res < 0 || strcmp(buf, "cpu") != 0)
-			continue;
-		res = OF_getprop(dev, "reg", &cpuid, sizeof(cpuid));
-		if (res < 0)
-			continue;
-		cpuid &= 0xff;
-		if (cpuid >= MAXCPU) {
+	error = powerpc_smp_first_cpu(&cpu);
+	while (!error) {
+		if (cpu.cr_cpuid >= MAXCPU) {
 			printf("SMP: cpu%d: skipped -- ID out of range\n",
-			    cpuid);
-			continue;
+			    cpu.cr_cpuid);
+			goto next;
 		}
-		if (all_cpus & (1 << cpuid)) {
-			printf("SMP: cpu%d: skipped - duplicate ID\n", cpuid);
-			continue;
+		if (all_cpus & (1 << cpu.cr_cpuid)) {
+			printf("SMP: cpu%d: skipped - duplicate ID\n",
+			    cpu.cr_cpuid);
+			goto next;
 		}
-		if (dev != bsp) {
+		if (cpu.cr_cpuid != bsp.cr_cpuid) {
 			pc = (struct pcpu *)malloc(sizeof(*pc), M_SMP,
 			    M_WAITOK);
-			pcpu_init(pc, cpuid, sizeof(*pc));
+			pcpu_init(pc, cpu.cr_cpuid, sizeof(*pc));
 		} else {
-			KASSERT(cpuid == 0, ("%s: cpuid != 0", __func__));
 			pc = pcpup;
 			pc->pc_bsp = 1;
 		}
-		all_cpus |= 1 << cpuid;
-		if (pc->pc_bsp)
-			continue;
+		pc->pc_hwref = cpu.cr_hwref;
+		all_cpus |= 1 << cpu.cr_cpuid;
 
-		/* Start AP */
-		OF_start_cpu(dev, __start_ap, pc);
+ next:
+		error = powerpc_smp_next_cpu(&cpu);
 	}
 }
 
@@ -185,13 +149,22 @@
 	if (mp_ncpus <= 1)
 		return;
 
-	if (mp_ipi_test != 1)
-		printf("SMP: WARNING: sending of a test IPI failed\n");
+	if (mp_ipi_test != 1) {
+		printf("SMP: ERROR: sending of a test IPI failed\n");
+		return;
+	}
 
 	cpus = 0;
 	smp_cpus = 0;
 	SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
 		cpus++;
+		if (!pc->pc_bsp) {
+			printf("Waking up CPU %d (dev=%u)\n", pc->pc_cpuid,
+			    pc->pc_hwref);
+			powerpc_smp_start_cpu(pc);
+		} else
+			pc->pc_awake = 1;
+
 		if (pc->pc_awake)
 			smp_cpus++;
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200802102207.m1AM7d2c088594>