From owner-svn-src-all@FreeBSD.ORG Tue Aug 31 15:27:47 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 40C2C1065672; Tue, 31 Aug 2010 15:27:47 +0000 (UTC) (envelope-from nwhitehorn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 2D37F8FC0C; Tue, 31 Aug 2010 15:27:47 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o7VFRlTW034076; Tue, 31 Aug 2010 15:27:47 GMT (envelope-from nwhitehorn@svn.freebsd.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o7VFRlCZ034062; Tue, 31 Aug 2010 15:27:47 GMT (envelope-from nwhitehorn@svn.freebsd.org) Message-Id: <201008311527.o7VFRlCZ034062@svn.freebsd.org> From: Nathan Whitehorn Date: Tue, 31 Aug 2010 15:27:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r212054 - in head/sys: conf powerpc/aim powerpc/booke powerpc/include powerpc/mpc85xx powerpc/powermac powerpc/powerpc X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 31 Aug 2010 15:27:47 -0000 Author: nwhitehorn Date: Tue Aug 31 15:27:46 2010 New Revision: 212054 URL: http://svn.freebsd.org/changeset/base/212054 Log: Restructure how reset and poweroff are handled on PowerPC systems, since the existing code was very platform specific, and broken for SMP systems trying to reboot from KDB. - Add a new PLATFORM_RESET() method to the platform KOBJ interface, and migrate existing reset functions into platform modules. - Modify the OF_reboot() routine to submit the request by hand to avoid the IPIs involved in the regular openfirmware() routine. This fixes reboot from KDB on SMP machines. - Move non-KDB reset and poweroff functions on the Powermac platform into the relevant power control drivers (cuda, pmu, smu), instead of using them through the Open Firmware backdoor. - Rename platform_chrp to platform_powermac since it has become increasingly Powermac specific. When we gain support for IBM systems, we will grow a new platform_chrp. Added: head/sys/powerpc/powermac/platform_powermac.c - copied, changed from r212043, head/sys/powerpc/aim/platform_chrp.c Deleted: head/sys/powerpc/aim/platform_chrp.c Modified: head/sys/conf/files.powerpc head/sys/powerpc/aim/machdep.c head/sys/powerpc/aim/ofw_machdep.c head/sys/powerpc/aim/vm_machdep.c head/sys/powerpc/booke/platform_bare.c head/sys/powerpc/include/ofw_machdep.h head/sys/powerpc/mpc85xx/mpc85xx.c head/sys/powerpc/powermac/cuda.c head/sys/powerpc/powermac/pmu.c head/sys/powerpc/powermac/smu.c head/sys/powerpc/powerpc/platform.c head/sys/powerpc/powerpc/platform_if.m Modified: head/sys/conf/files.powerpc ============================================================================== --- head/sys/conf/files.powerpc Tue Aug 31 15:22:09 2010 (r212053) +++ head/sys/conf/files.powerpc Tue Aug 31 15:27:46 2010 (r212054) @@ -82,7 +82,6 @@ powerpc/aim/mp_cpudep.c optional aim sm powerpc/aim/nexus.c optional aim powerpc/aim/ofw_machdep.c optional aim powerpc/aim/ofwmagic.S optional aim -powerpc/aim/platform_chrp.c optional aim powerpc/aim/slb.c optional aim powerpc64 powerpc/aim/swtch32.S optional aim powerpc powerpc/aim/swtch64.S optional aim powerpc64 @@ -143,6 +142,7 @@ powerpc/powermac/kiic.c optional powerm powerpc/powermac/macgpio.c optional powermac pci powerpc/powermac/macio.c optional powermac pci powerpc/powermac/openpic_macio.c optional powermac pci +powerpc/powermac/platform_powermac.c optional powermac powerpc/powermac/pswitch.c optional powermac pswitch powerpc/powermac/pmu.c optional powermac pmu powerpc/powermac/smu.c optional powermac smu Modified: head/sys/powerpc/aim/machdep.c ============================================================================== --- head/sys/powerpc/aim/machdep.c Tue Aug 31 15:22:09 2010 (r212053) +++ head/sys/powerpc/aim/machdep.c Tue Aug 31 15:27:46 2010 (r212054) @@ -168,15 +168,6 @@ struct bat battable[16]; struct kva_md_info kmi; static void -powerpc_ofw_shutdown(void *junk, int howto) -{ - if (howto & RB_HALT) { - OF_halt(); - } - OF_reboot(); -} - -static void cpu_startup(void *dummy) { @@ -233,9 +224,6 @@ cpu_startup(void *dummy) */ bufinit(); vm_pager_bufferinit(); - - EVENTHANDLER_REGISTER(shutdown_final, powerpc_ofw_shutdown, 0, - SHUTDOWN_PRI_LAST); } extern char kernel_text[], _end[]; Modified: head/sys/powerpc/aim/ofw_machdep.c ============================================================================== --- head/sys/powerpc/aim/ofw_machdep.c Tue Aug 31 15:22:09 2010 (r212053) +++ head/sys/powerpc/aim/ofw_machdep.c Tue Aug 31 15:27:46 2010 (r212054) @@ -527,20 +527,21 @@ openfirmware(void *args) } void -OF_halt() -{ - int retval; /* dummy, this may not be needed */ - - OF_interpret("shut-down", 1, &retval); - for (;;); /* just in case */ -} - -void OF_reboot() { - int retval; /* dummy, this may not be needed */ + struct { + cell_t name; + cell_t nargs; + cell_t nreturns; + cell_t arg; + } args; + + args.name = (cell_t)(uintptr_t)"interpret"; + args.nargs = 1; + args.nreturns = 0; + args.arg = (cell_t)(uintptr_t)"reset-all"; + openfirmware_core(&args); /* Don't do rendezvous! */ - OF_interpret("reset-all", 1, &retval); for (;;); /* just in case */ } Modified: head/sys/powerpc/aim/vm_machdep.c ============================================================================== --- head/sys/powerpc/aim/vm_machdep.c Tue Aug 31 15:22:09 2010 (r212053) +++ head/sys/powerpc/aim/vm_machdep.c Tue Aug 31 15:27:46 2010 (r212054) @@ -238,15 +238,6 @@ cpu_exit(td) } /* - * Reset back to firmware. - */ -void -cpu_reset() -{ - OF_reboot(); -} - -/* * Allocate a pool of sf_bufs (sendfile(2) or "super-fast" if you prefer. :-)) */ static void Modified: head/sys/powerpc/booke/platform_bare.c ============================================================================== --- head/sys/powerpc/booke/platform_bare.c Tue Aug 31 15:22:09 2010 (r212053) +++ head/sys/powerpc/booke/platform_bare.c Tue Aug 31 15:27:46 2010 (r212054) @@ -70,6 +70,8 @@ static int bare_smp_next_cpu(platform_t, static int bare_smp_get_bsp(platform_t, struct cpuref *cpuref); static int bare_smp_start_cpu(platform_t, struct pcpu *cpu); +static void e500_reset(platform_t); + static platform_method_t bare_methods[] = { PLATFORMMETHOD(platform_probe, bare_probe), PLATFORMMETHOD(platform_mem_regions, bare_mem_regions), @@ -80,6 +82,8 @@ static platform_method_t bare_methods[] PLATFORMMETHOD(platform_smp_get_bsp, bare_smp_get_bsp), PLATFORMMETHOD(platform_smp_start_cpu, bare_smp_start_cpu), + PLATFORMMETHOD(platform_reset, e500_reset); + { 0, 0 } }; @@ -260,3 +264,30 @@ bare_smp_start_cpu(platform_t plat, stru return (ENXIO); #endif } + +static void +e500_reset(platform_t plat) +{ + uint32_t ver = SVR_VER(mfspr(SPR_SVR)); + + if (ver == SVR_MPC8572E || ver == SVR_MPC8572 || + ver == SVR_MPC8548E || ver == SVR_MPC8548) + /* Systems with dedicated reset register */ + ccsr_write4(OCP85XX_RSTCR, 2); + else { + /* Clear DBCR0, disables debug interrupts and events. */ + mtspr(SPR_DBCR0, 0); + __asm __volatile("isync"); + + /* Enable Debug Interrupts in MSR. */ + mtmsr(mfmsr() | PSL_DE); + + /* Enable debug interrupts and issue reset. */ + mtspr(SPR_DBCR0, mfspr(SPR_DBCR0) | DBCR0_IDM | + DBCR0_RST_SYSTEM); + } + + printf("Reset failed...\n"); + while (1); +} + Modified: head/sys/powerpc/include/ofw_machdep.h ============================================================================== --- head/sys/powerpc/include/ofw_machdep.h Tue Aug 31 15:22:09 2010 (r212053) +++ head/sys/powerpc/include/ofw_machdep.h Tue Aug 31 15:27:46 2010 (r212054) @@ -43,7 +43,6 @@ void OF_getetheraddr(device_t dev, u_cha void OF_initial_setup(void *fdt_ptr, void *junk, int (*openfirm)(void *)); boolean_t OF_bootstrap(void); -void OF_halt(void); void OF_reboot(void); void ofw_mem_regions(struct mem_region **, int *, struct mem_region **, int *); Modified: head/sys/powerpc/mpc85xx/mpc85xx.c ============================================================================== --- head/sys/powerpc/mpc85xx/mpc85xx.c Tue Aug 31 15:22:09 2010 (r212053) +++ head/sys/powerpc/mpc85xx/mpc85xx.c Tue Aug 31 15:27:46 2010 (r212054) @@ -164,28 +164,3 @@ law_pci_target(struct resource *res, int return (rv); } -void -cpu_reset(void) -{ - uint32_t ver = SVR_VER(mfspr(SPR_SVR)); - - if (ver == SVR_MPC8572E || ver == SVR_MPC8572 || - ver == SVR_MPC8548E || ver == SVR_MPC8548) - /* Systems with dedicated reset register */ - ccsr_write4(OCP85XX_RSTCR, 2); - else { - /* Clear DBCR0, disables debug interrupts and events. */ - mtspr(SPR_DBCR0, 0); - __asm __volatile("isync"); - - /* Enable Debug Interrupts in MSR. */ - mtmsr(mfmsr() | PSL_DE); - - /* Enable debug interrupts and issue reset. */ - mtspr(SPR_DBCR0, mfspr(SPR_DBCR0) | DBCR0_IDM | - DBCR0_RST_SYSTEM); - } - - printf("Reset failed...\n"); - while (1); -} Modified: head/sys/powerpc/powermac/cuda.c ============================================================================== --- head/sys/powerpc/powermac/cuda.c Tue Aug 31 15:22:09 2010 (r212053) +++ head/sys/powerpc/powermac/cuda.c Tue Aug 31 15:27:46 2010 (r212054) @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -72,6 +73,7 @@ static u_int cuda_adb_autopoll(device_t static u_int cuda_poll(device_t dev); static void cuda_send_inbound(struct cuda_softc *sc); static void cuda_send_outbound(struct cuda_softc *sc); +static void cuda_shutdown(void *xsc, int howto); /* * Clock interface @@ -249,6 +251,8 @@ cuda_attach(device_t dev) } clock_register(dev, 1000); + EVENTHANDLER_REGISTER(shutdown_final, cuda_shutdown, sc, + SHUTDOWN_PRI_LAST); return (bus_generic_attach(dev)); } @@ -739,6 +743,20 @@ cuda_adb_autopoll(device_t dev, uint16_t return (0); } +static void +cuda_shutdown(void *xsc, int howto) +{ + struct cuda_softc *sc = xsc; + uint8_t cmd[] = {CUDA_PSEUDO, 0}; + + cmd[1] = (howto & RB_HALT) ? CMD_POWEROFF : CMD_RESET; + cuda_poll(sc->sc_dev); + cuda_send(sc, 1, 2, cmd); + + while (1) + cuda_poll(sc->sc_dev); +} + #define DIFF19041970 2082844800 static int Copied and modified: head/sys/powerpc/powermac/platform_powermac.c (from r212043, head/sys/powerpc/aim/platform_chrp.c) ============================================================================== --- head/sys/powerpc/aim/platform_chrp.c Tue Aug 31 01:16:45 2010 (r212043, copy source) +++ head/sys/powerpc/powermac/platform_powermac.c Tue Aug 31 15:27:46 2010 (r212054) @@ -55,38 +55,41 @@ __FBSDID("$FreeBSD$"); extern void *ap_pcpu; #endif -static int chrp_probe(platform_t); -void chrp_mem_regions(platform_t, struct mem_region **phys, int *physsz, +static int powermac_probe(platform_t); +void powermac_mem_regions(platform_t, struct mem_region **phys, int *physsz, struct mem_region **avail, int *availsz); -static u_long chrp_timebase_freq(platform_t, struct cpuref *cpuref); -static int chrp_smp_first_cpu(platform_t, struct cpuref *cpuref); -static int chrp_smp_next_cpu(platform_t, struct cpuref *cpuref); -static int chrp_smp_get_bsp(platform_t, struct cpuref *cpuref); -static int chrp_smp_start_cpu(platform_t, struct pcpu *cpu); - -static platform_method_t chrp_methods[] = { - PLATFORMMETHOD(platform_probe, chrp_probe), - PLATFORMMETHOD(platform_mem_regions, chrp_mem_regions), - PLATFORMMETHOD(platform_timebase_freq, chrp_timebase_freq), +static u_long powermac_timebase_freq(platform_t, struct cpuref *cpuref); +static int powermac_smp_first_cpu(platform_t, struct cpuref *cpuref); +static int powermac_smp_next_cpu(platform_t, struct cpuref *cpuref); +static int powermac_smp_get_bsp(platform_t, struct cpuref *cpuref); +static int powermac_smp_start_cpu(platform_t, struct pcpu *cpu); +static void powermac_reset(platform_t); + +static platform_method_t powermac_methods[] = { + PLATFORMMETHOD(platform_probe, powermac_probe), + PLATFORMMETHOD(platform_mem_regions, powermac_mem_regions), + PLATFORMMETHOD(platform_timebase_freq, powermac_timebase_freq), - PLATFORMMETHOD(platform_smp_first_cpu, chrp_smp_first_cpu), - PLATFORMMETHOD(platform_smp_next_cpu, chrp_smp_next_cpu), - PLATFORMMETHOD(platform_smp_get_bsp, chrp_smp_get_bsp), - PLATFORMMETHOD(platform_smp_start_cpu, chrp_smp_start_cpu), + PLATFORMMETHOD(platform_smp_first_cpu, powermac_smp_first_cpu), + PLATFORMMETHOD(platform_smp_next_cpu, powermac_smp_next_cpu), + PLATFORMMETHOD(platform_smp_get_bsp, powermac_smp_get_bsp), + PLATFORMMETHOD(platform_smp_start_cpu, powermac_smp_start_cpu), + + PLATFORMMETHOD(platform_reset, powermac_reset), { 0, 0 } }; -static platform_def_t chrp_platform = { - "chrp", - chrp_methods, +static platform_def_t powermac_platform = { + "powermac", + powermac_methods, 0 }; -PLATFORM_DEF(chrp_platform); +PLATFORM_DEF(powermac_platform); static int -chrp_probe(platform_t plat) +powermac_probe(platform_t plat) { if (OF_finddevice("/memory") != -1 || OF_finddevice("/memory@0") != -1) return (BUS_PROBE_GENERIC); @@ -95,14 +98,14 @@ chrp_probe(platform_t plat) } void -chrp_mem_regions(platform_t plat, struct mem_region **phys, int *physsz, +powermac_mem_regions(platform_t plat, struct mem_region **phys, int *physsz, struct mem_region **avail, int *availsz) { ofw_mem_regions(phys,physsz,avail,availsz); } static u_long -chrp_timebase_freq(platform_t plat, struct cpuref *cpuref) +powermac_timebase_freq(platform_t plat, struct cpuref *cpuref) { phandle_t phandle; int32_t ticks = -1; @@ -119,7 +122,7 @@ chrp_timebase_freq(platform_t plat, stru static int -chrp_smp_fill_cpuref(struct cpuref *cpuref, phandle_t cpu) +powermac_smp_fill_cpuref(struct cpuref *cpuref, phandle_t cpu) { cell_t cpuid, res; @@ -139,7 +142,7 @@ chrp_smp_fill_cpuref(struct cpuref *cpur } static int -chrp_smp_first_cpu(platform_t plat, struct cpuref *cpuref) +powermac_smp_first_cpu(platform_t plat, struct cpuref *cpuref) { char buf[8]; phandle_t cpu, dev, root; @@ -175,11 +178,11 @@ chrp_smp_first_cpu(platform_t plat, stru if (cpu == 0) return (ENOENT); - return (chrp_smp_fill_cpuref(cpuref, cpu)); + return (powermac_smp_fill_cpuref(cpuref, cpu)); } static int -chrp_smp_next_cpu(platform_t plat, struct cpuref *cpuref) +powermac_smp_next_cpu(platform_t plat, struct cpuref *cpuref) { char buf[8]; phandle_t cpu; @@ -195,11 +198,11 @@ chrp_smp_next_cpu(platform_t plat, struc if (cpu == 0) return (ENOENT); - return (chrp_smp_fill_cpuref(cpuref, cpu)); + return (powermac_smp_fill_cpuref(cpuref, cpu)); } static int -chrp_smp_get_bsp(platform_t plat, struct cpuref *cpuref) +powermac_smp_get_bsp(platform_t plat, struct cpuref *cpuref) { ihandle_t inst; phandle_t bsp, chosen; @@ -214,11 +217,11 @@ chrp_smp_get_bsp(platform_t plat, struct return (ENXIO); bsp = OF_instance_to_package(inst); - return (chrp_smp_fill_cpuref(cpuref, bsp)); + return (powermac_smp_fill_cpuref(cpuref, bsp)); } static int -chrp_smp_start_cpu(platform_t plat, struct pcpu *pc) +powermac_smp_start_cpu(platform_t plat, struct pcpu *pc) { #ifdef SMP phandle_t cpu; @@ -277,3 +280,9 @@ chrp_smp_start_cpu(platform_t plat, stru #endif } +static void +powermac_reset(platform_t platform) +{ + OF_reboot(); +} + Modified: head/sys/powerpc/powermac/pmu.c ============================================================================== --- head/sys/powerpc/powermac/pmu.c Tue Aug 31 15:22:09 2010 (r212053) +++ head/sys/powerpc/powermac/pmu.c Tue Aug 31 15:27:46 2010 (r212054) @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -81,6 +82,11 @@ static u_int pmu_adb_send(device_t dev, static u_int pmu_adb_autopoll(device_t dev, uint16_t mask); static u_int pmu_poll(device_t dev); +/* + * Power interface + */ + +static void pmu_shutdown(void *xsc, int howto); static void pmu_set_sleepled(void *xsc, int onoff); static int pmu_server_mode(SYSCTL_HANDLER_ARGS); static int pmu_acline_state(SYSCTL_HANDLER_ARGS); @@ -474,6 +480,12 @@ pmu_attach(device_t dev) clock_register(dev, 1000); + /* + * Register power control handler + */ + EVENTHANDLER_REGISTER(shutdown_final, pmu_shutdown, sc, + SHUTDOWN_PRI_LAST); + return (bus_generic_attach(dev)); } @@ -751,6 +763,20 @@ pmu_adb_autopoll(device_t dev, uint16_t } static void +pmu_shutdown(void *xsc, int howto) +{ + struct pmu_softc *sc = xsc; + uint8_t cmd[] = {'M', 'A', 'T', 'T'}; + + if (howto & RB_HALT) + pmu_send(sc, PMU_POWER_OFF, 4, cmd, 0, NULL); + else + pmu_send(sc, PMU_RESET_CPU, 0, NULL, 0, NULL); + + for (;;); +} + +static void pmu_set_sleepled(void *xsc, int onoff) { struct pmu_softc *sc = xsc; Modified: head/sys/powerpc/powermac/smu.c ============================================================================== --- head/sys/powerpc/powermac/smu.c Tue Aug 31 15:22:09 2010 (r212053) +++ head/sys/powerpc/powermac/smu.c Tue Aug 31 15:27:46 2010 (r212054) @@ -165,6 +165,7 @@ static void smu_manage_fans(device_t smu static void smu_set_sleepled(void *xdev, int onoff); static int smu_server_mode(SYSCTL_HANDLER_ARGS); static void smu_doorbell_intr(void *xdev); +static void smu_shutdown(void *xdev, int howto); /* where to find the doorbell GPIO */ @@ -391,6 +392,12 @@ smu_attach(device_t dev) */ clock_register(dev, 1000); + /* + * Learn about shutdown events + */ + EVENTHANDLER_REGISTER(shutdown_final, smu_shutdown, dev, + SHUTDOWN_PRI_LAST); + return (bus_generic_attach(dev)); } @@ -1115,6 +1122,25 @@ smu_server_mode(SYSCTL_HANDLER_ARGS) return (smu_run_cmd(smu, &cmd, 1)); } +static void +smu_shutdown(void *xdev, int howto) +{ + device_t smu = xdev; + struct smu_cmd cmd; + + cmd.cmd = SMU_POWER; + if (howto & RB_HALT) + strcpy(cmd.data, "SHUTDOWN"); + else + strcpy(cmd.data, "RESTART"); + + cmd.len = strlen(cmd.data); + + smu_run_cmd(smu, &cmd, 1); + + for (;;); +} + static int smu_gettime(device_t dev, struct timespec *ts) { Modified: head/sys/powerpc/powerpc/platform.c ============================================================================== --- head/sys/powerpc/powerpc/platform.c Tue Aug 31 15:22:09 2010 (r212053) +++ head/sys/powerpc/powerpc/platform.c Tue Aug 31 15:27:46 2010 (r212054) @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -105,6 +106,15 @@ platform_smp_start_cpu(struct pcpu *cpu) } /* + * Reset back to firmware. + */ +void +cpu_reset() +{ + PLATFORM_RESET(plat_obj); +} + +/* * Platform install routines. Highest priority wins, using the same * algorithm as bus attachment. */ Modified: head/sys/powerpc/powerpc/platform_if.m ============================================================================== --- head/sys/powerpc/powerpc/platform_if.m Tue Aug 31 15:22:09 2010 (r212053) +++ head/sys/powerpc/powerpc/platform_if.m Tue Aug 31 15:27:46 2010 (r212054) @@ -161,3 +161,10 @@ METHOD int smp_start_cpu { struct pcpu *_cpu; }; +/** + * @brief Reset system + */ +METHOD void reset { + platform_t _plat; +}; +