From owner-p4-projects@FreeBSD.ORG Sun Feb 10 22:07:43 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B6AE816A46B; Sun, 10 Feb 2008 22:07:43 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 63AFB16A41A for ; Sun, 10 Feb 2008 22:07:43 +0000 (UTC) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 6C8EF13C45E for ; Sun, 10 Feb 2008 22:07:42 +0000 (UTC) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m1AM7eks088597 for ; Sun, 10 Feb 2008 22:07:40 GMT (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m1AM7d2c088594 for perforce@freebsd.org; Sun, 10 Feb 2008 22:07:39 GMT (envelope-from marcel@freebsd.org) Date: Sun, 10 Feb 2008 22:07:39 GMT Message-Id: <200802102207.m1AM7d2c088594@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Cc: Subject: PERFORCE change 135174 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Feb 2008 22:07:44 -0000 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 -__FBSDID("$FreeBSD: src/sys/powerpc/powerpc/mp_machdep.c,v 1.13 2006/05/16 14:32:17 phk Exp $"); +__FBSDID("$FreeBSD$"); #include #include #include #include +#include #include #include @@ -39,9 +40,6 @@ #include #include -#include -#include - #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++; }