svn commit: r225290 - in projects/armv6/sys/arm: arm include
Grzegorz Bernacki
gber at FreeBSD.org
Wed Aug 31 09:29:46 UTC 2011
Author: gber
Date: Wed Aug 31 09:29:46 2011
New Revision: 225290
URL: http://svn.freebsd.org/changeset/base/225290
Log:
Update SMP framework on ARM based on MIPS implementation.
Obtained from: Marvell, Semihalf
Modified:
projects/armv6/sys/arm/arm/mp_machdep.c
projects/armv6/sys/arm/include/smp.h
Modified: projects/armv6/sys/arm/arm/mp_machdep.c
==============================================================================
--- projects/armv6/sys/arm/arm/mp_machdep.c Wed Aug 31 09:15:52 2011 (r225289)
+++ projects/armv6/sys/arm/arm/mp_machdep.c Wed Aug 31 09:29:46 2011 (r225290)
@@ -23,7 +23,6 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
@@ -31,29 +30,81 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
-
+#include <sys/proc.h>
+#include <sys/pcpu.h>
+#include <sys/sched.h>
#include <sys/smp.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+
#include <machine/smp.h>
+extern struct pcpu __pcpu[];
+
/* used to hold the AP's until we are ready to release them */
static struct mtx ap_boot_mtx;
+/* # of Applications processors */
+int mp_naps;
+
+/* Set to 1 once we're ready to let the APs out of the pen. */
+static volatile int aps_ready = 0;
+
+/* Temporary variables for init_secondary() */
+void *dpcpu;
+
+
/* Determine if we running MP machine */
int
cpu_mp_probe(void)
{
CPU_SETOF(0, &all_cpus);
- return (mp_ncpus > 1);
+ return (platform_mp_probe());
}
+/* Start Application Processor via platform specific function */
+static int
+start_ap(int cpu)
+{
+ int cpus, ms;
+
+ cpus = mp_naps;
+
+ if (platform_mp_start_ap(cpu) != 0)
+ return (-1); /* could not start AP */
+
+ for (ms = 0; ms < 5000; ++ms) {
+ if (mp_naps > cpus)
+ return (0); /* success */
+ else
+ DELAY(1000);
+ }
+
+ return (-2);
+}
+
+
/* Initialize and fire up non-boot processors */
void
cpu_mp_start(void)
{
+ int error, i;
+
mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
+ for (i = 1; i < mp_maxid; i++) {
+ error = start_ap(i);
+ if (error) {
+ printf("AP #%d failed to start\n", i);
+ continue;
+ }
+ CPU_SET(i, &all_cpus);
+ }
+
+
return;
}
@@ -64,6 +115,61 @@ cpu_mp_announce(void)
return;
}
+void
+init_secondary(int cpu)
+{
+ struct pcpu *pc;
+ void *dpcpu;
+
+ /* Per-cpu initialization */
+ pc = &__pcpu[cpu];
+ pcpu_init(pc, cpu, sizeof(struct pcpu));
+
+ dpcpu = (void *)kmem_alloc(kernel_map, DPCPU_SIZE);
+ dpcpu_init(dpcpu, cpu);
+
+ /* Signal our startup to BSP */
+ mp_naps++;
+
+ /* Spin until the BSP releases the APs */
+ while (!aps_ready)
+ ;
+
+ /* Initialize curthread */
+ KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread"));
+ PCPU_SET(curthread, PCPU_GET(idlethread));
+
+
+ mtx_lock_spin(&ap_boot_mtx);
+
+ printf("SMP: AP CPU #%d Launched!\n", cpu);
+
+ smp_cpus++;
+
+ if (smp_cpus == mp_ncpus) {
+ /* enable IPI's, tlb shootdown, freezes etc */
+ atomic_store_rel_int(&smp_started, 1);
+ /*
+ * XXX do we really need it
+ * smp_active = 1;
+ */
+ }
+
+ mtx_unlock_spin(&ap_boot_mtx);
+
+ while (smp_started == 0)
+ ;
+
+ /* Start per-CPU event timers. */
+ cpu_initclocks_ap();
+
+ /* Enter the scheduler */
+ sched_throw(NULL);
+
+ panic("scheduler returned us to %s", __func__);
+ /* NOTREACHED */
+}
+
struct cpu_group *
cpu_topo(void)
{
@@ -73,26 +179,29 @@ cpu_topo(void)
void
cpu_mp_setmaxid(void)
{
- mp_ncpus = 4;
- mp_maxid = 3;
+
+ platform_mp_setmaxid();
}
/* Sending IPI */
void
ipi_all_but_self(u_int ipi)
{
+
return;
}
void
ipi_cpu(int cpu, u_int ipi)
{
+
return;
}
void
ipi_selected(cpuset_t cpus, u_int ipi)
{
+
return;
}
Modified: projects/armv6/sys/arm/include/smp.h
==============================================================================
--- projects/armv6/sys/arm/include/smp.h Wed Aug 31 09:15:52 2011 (r225289)
+++ projects/armv6/sys/arm/include/smp.h Wed Aug 31 09:29:46 2011 (r225290)
@@ -12,8 +12,16 @@
#define IPI_STOP_HARD 5
#define IPI_HARDCLOCK 6
+void init_secondary(int cpu);
+
void ipi_all_but_self(u_int ipi);
void ipi_cpu(int cpu, u_int ipi);
void ipi_selected(cpuset_t cpus, u_int ipi);
+/* Platform interface */
+void platform_mp_setmaxid(void);
+int platform_mp_probe(void);
+int platform_mp_start_ap(int cpuid);
+
+
#endif /* !_MACHINE_SMP_H_ */
More information about the svn-src-projects
mailing list