From owner-svn-src-all@freebsd.org Mon Apr 2 13:45:24 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4FB2CF63C5E; Mon, 2 Apr 2018 13:45:24 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id E76637F55A; Mon, 2 Apr 2018 13:45:23 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id DE3D21670F; Mon, 2 Apr 2018 13:45:23 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w32DjNQG072553; Mon, 2 Apr 2018 13:45:23 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w32DjND9072550; Mon, 2 Apr 2018 13:45:23 GMT (envelope-from avg@FreeBSD.org) Message-Id: <201804021345.w32DjND9072550@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Mon, 2 Apr 2018 13:45:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r331878 - in head/sys: amd64/amd64 i386/i386 x86/x86 X-SVN-Group: head X-SVN-Commit-Author: avg X-SVN-Commit-Paths: in head/sys: amd64/amd64 i386/i386 x86/x86 X-SVN-Commit-Revision: 331878 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 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: Mon, 02 Apr 2018 13:45:24 -0000 Author: avg Date: Mon Apr 2 13:45:23 2018 New Revision: 331878 URL: https://svnweb.freebsd.org/changeset/base/331878 Log: unify amd64 and i386 cpu_reset() in x86/cpu_machdep.c Because I didn't see any reason not too. I've been making some changes to the code and couldn't help but notice that the i386 and am64 code was nearly identical. MFC after: 17 days Modified: head/sys/amd64/amd64/vm_machdep.c head/sys/i386/i386/vm_machdep.c head/sys/x86/x86/cpu_machdep.c Modified: head/sys/amd64/amd64/vm_machdep.c ============================================================================== --- head/sys/amd64/amd64/vm_machdep.c Mon Apr 2 13:36:48 2018 (r331877) +++ head/sys/amd64/amd64/vm_machdep.c Mon Apr 2 13:45:23 2018 (r331878) @@ -84,13 +84,6 @@ __FBSDID("$FreeBSD$"); #include -static void cpu_reset_real(void); -#ifdef SMP -static void cpu_reset_proxy(void); -static u_int cpu_reset_proxyid; -static volatile u_int cpu_reset_proxy_active; -#endif - _Static_assert(OFFSETOF_CURTHREAD == offsetof(struct pcpu, pc_curthread), "OFFSETOF_CURTHREAD does not correspond with offset of pc_curthread."); _Static_assert(OFFSETOF_CURPCB == offsetof(struct pcpu, pc_curpcb), @@ -563,129 +556,6 @@ cpu_set_user_tls(struct thread *td, void *tls_base) #endif pcb->pcb_fsbase = (register_t)tls_base; return (0); -} - -#ifdef SMP -static void -cpu_reset_proxy() -{ - - cpu_reset_proxy_active = 1; - while (cpu_reset_proxy_active == 1) - ia32_pause(); /* Wait for other cpu to see that we've started */ - - printf("cpu_reset_proxy: Stopped CPU %d\n", cpu_reset_proxyid); - DELAY(1000000); - cpu_reset_real(); -} -#endif - -void -cpu_reset() -{ -#ifdef SMP - cpuset_t map; - u_int cnt; - - if (smp_started) { - map = all_cpus; - CPU_CLR(PCPU_GET(cpuid), &map); - CPU_NAND(&map, &stopped_cpus); - if (!CPU_EMPTY(&map)) { - printf("cpu_reset: Stopping other CPUs\n"); - stop_cpus(map); - } - - if (PCPU_GET(cpuid) != 0) { - cpu_reset_proxyid = PCPU_GET(cpuid); - cpustop_restartfunc = cpu_reset_proxy; - cpu_reset_proxy_active = 0; - printf("cpu_reset: Restarting BSP\n"); - - /* Restart CPU #0. */ - CPU_SETOF(0, &started_cpus); - wmb(); - - cnt = 0; - while (cpu_reset_proxy_active == 0 && cnt < 10000000) { - ia32_pause(); - cnt++; /* Wait for BSP to announce restart */ - } - if (cpu_reset_proxy_active == 0) { - printf("cpu_reset: Failed to restart BSP\n"); - } else { - cpu_reset_proxy_active = 2; - while (1) - ia32_pause(); - /* NOTREACHED */ - } - } - - DELAY(1000000); - } -#endif - cpu_reset_real(); - /* NOTREACHED */ -} - -static void -cpu_reset_real() -{ - struct region_descriptor null_idt; - int b; - - disable_intr(); - - /* - * Attempt to do a CPU reset via the keyboard controller, - * do not turn off GateA20, as any machine that fails - * to do the reset here would then end up in no man's land. - */ - outb(IO_KBD + 4, 0xFE); - DELAY(500000); /* wait 0.5 sec to see if that did it */ - - /* - * Attempt to force a reset via the Reset Control register at - * I/O port 0xcf9. Bit 2 forces a system reset when it - * transitions from 0 to 1. Bit 1 selects the type of reset - * to attempt: 0 selects a "soft" reset, and 1 selects a - * "hard" reset. We try a "hard" reset. The first write sets - * bit 1 to select a "hard" reset and clears bit 2. The - * second write forces a 0 -> 1 transition in bit 2 to trigger - * a reset. - */ - outb(0xcf9, 0x2); - outb(0xcf9, 0x6); - DELAY(500000); /* wait 0.5 sec to see if that did it */ - - /* - * Attempt to force a reset via the Fast A20 and Init register - * at I/O port 0x92. Bit 1 serves as an alternate A20 gate. - * Bit 0 asserts INIT# when set to 1. We are careful to only - * preserve bit 1 while setting bit 0. We also must clear bit - * 0 before setting it if it isn't already clear. - */ - b = inb(0x92); - if (b != 0xff) { - if ((b & 0x1) != 0) - outb(0x92, b & 0xfe); - outb(0x92, b | 0x1); - DELAY(500000); /* wait 0.5 sec to see if that did it */ - } - - printf("No known reset method worked, attempting CPU shutdown\n"); - DELAY(1000000); /* wait 1 sec for printf to complete */ - - /* Wipe the IDT. */ - null_idt.rd_limit = 0; - null_idt.rd_base = 0; - lidt(&null_idt); - - /* "good night, sweet prince .... " */ - breakpoint(); - - /* NOTREACHED */ - while(1); } /* Modified: head/sys/i386/i386/vm_machdep.c ============================================================================== --- head/sys/i386/i386/vm_machdep.c Mon Apr 2 13:36:48 2018 (r331877) +++ head/sys/i386/i386/vm_machdep.c Mon Apr 2 13:45:23 2018 (r331878) @@ -103,13 +103,6 @@ _Static_assert(OFFSETOF_CURPCB == offsetof(struct pcpu _Static_assert(__OFFSETOF_MONITORBUF == offsetof(struct pcpu, pc_monitorbuf), "__OFFSETOF_MONINORBUF does not correspond with offset of pc_monitorbuf."); -static void cpu_reset_real(void); -#ifdef SMP -static void cpu_reset_proxy(void); -static u_int cpu_reset_proxyid; -static volatile u_int cpu_reset_proxy_active; -#endif - union savefpu * get_pcb_user_save_td(struct thread *td) { @@ -575,141 +568,6 @@ kvtop(void *addr) if (pa == 0) panic("kvtop: zero page frame"); return (pa); -} - -#ifdef SMP -static void -cpu_reset_proxy() -{ - - cpu_reset_proxy_active = 1; - while (cpu_reset_proxy_active == 1) - ia32_pause(); /* Wait for other cpu to see that we've started */ - - printf("cpu_reset_proxy: Stopped CPU %d\n", cpu_reset_proxyid); - DELAY(1000000); - cpu_reset_real(); -} -#endif - -void -cpu_reset() -{ -#ifdef SMP - cpuset_t map; - u_int cnt; - - if (smp_started) { - map = all_cpus; - CPU_CLR(PCPU_GET(cpuid), &map); - CPU_NAND(&map, &stopped_cpus); - if (!CPU_EMPTY(&map)) { - printf("cpu_reset: Stopping other CPUs\n"); - stop_cpus(map); - } - - if (PCPU_GET(cpuid) != 0) { - cpu_reset_proxyid = PCPU_GET(cpuid); - cpustop_restartfunc = cpu_reset_proxy; - cpu_reset_proxy_active = 0; - printf("cpu_reset: Restarting BSP\n"); - - /* Restart CPU #0. */ - CPU_SETOF(0, &started_cpus); - wmb(); - - cnt = 0; - while (cpu_reset_proxy_active == 0 && cnt < 10000000) { - ia32_pause(); - cnt++; /* Wait for BSP to announce restart */ - } - if (cpu_reset_proxy_active == 0) { - printf("cpu_reset: Failed to restart BSP\n"); - } else { - cpu_reset_proxy_active = 2; - while (1) - ia32_pause(); - /* NOTREACHED */ - } - } - - DELAY(1000000); - } -#endif - cpu_reset_real(); - /* NOTREACHED */ -} - -static void -cpu_reset_real() -{ - struct region_descriptor null_idt; - int b; - - disable_intr(); -#ifdef CPU_ELAN - if (elan_mmcr != NULL) - elan_mmcr->RESCFG = 1; -#endif - - if (cpu == CPU_GEODE1100) { - /* Attempt Geode's own reset */ - outl(0xcf8, 0x80009044ul); - outl(0xcfc, 0xf); - } - -#if !defined(BROKEN_KEYBOARD_RESET) - /* - * Attempt to do a CPU reset via the keyboard controller, - * do not turn off GateA20, as any machine that fails - * to do the reset here would then end up in no man's land. - */ - outb(IO_KBD + 4, 0xFE); - DELAY(500000); /* wait 0.5 sec to see if that did it */ -#endif - - /* - * Attempt to force a reset via the Reset Control register at - * I/O port 0xcf9. Bit 2 forces a system reset when it - * transitions from 0 to 1. Bit 1 selects the type of reset - * to attempt: 0 selects a "soft" reset, and 1 selects a - * "hard" reset. We try a "hard" reset. The first write sets - * bit 1 to select a "hard" reset and clears bit 2. The - * second write forces a 0 -> 1 transition in bit 2 to trigger - * a reset. - */ - outb(0xcf9, 0x2); - outb(0xcf9, 0x6); - DELAY(500000); /* wait 0.5 sec to see if that did it */ - - /* - * Attempt to force a reset via the Fast A20 and Init register - * at I/O port 0x92. Bit 1 serves as an alternate A20 gate. - * Bit 0 asserts INIT# when set to 1. We are careful to only - * preserve bit 1 while setting bit 0. We also must clear bit - * 0 before setting it if it isn't already clear. - */ - b = inb(0x92); - if (b != 0xff) { - if ((b & 0x1) != 0) - outb(0x92, b & 0xfe); - outb(0x92, b | 0x1); - DELAY(500000); /* wait 0.5 sec to see if that did it */ - } - - printf("No known reset method worked, attempting CPU shutdown\n"); - DELAY(1000000); /* wait 1 sec for printf to complete */ - - /* Wipe the IDT. */ - null_idt.rd_limit = 0; - null_idt.rd_base = 0; - lidt(&null_idt); - - /* "good night, sweet prince .... " */ - breakpoint(); - - /* NOTREACHED */ - while(1); } /* Modified: head/sys/x86/x86/cpu_machdep.c ============================================================================== --- head/sys/x86/x86/cpu_machdep.c Mon Apr 2 13:36:48 2018 (r331877) +++ head/sys/x86/x86/cpu_machdep.c Mon Apr 2 13:45:23 2018 (r331878) @@ -96,10 +96,18 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #define STATE_RUNNING 0x0 #define STATE_MWAIT 0x1 #define STATE_SLEEPING 0x2 +#ifdef SMP +static u_int cpu_reset_proxyid; +static volatile u_int cpu_reset_proxy_active; +#endif + + /* * Machine dependent boot() routine * @@ -240,6 +248,141 @@ cpu_halt(void) { for (;;) halt(); +} + +static void +cpu_reset_real() +{ + struct region_descriptor null_idt; + int b; + + disable_intr(); +#ifdef CPU_ELAN + if (elan_mmcr != NULL) + elan_mmcr->RESCFG = 1; +#endif +#ifdef __i386__ + if (cpu == CPU_GEODE1100) { + /* Attempt Geode's own reset */ + outl(0xcf8, 0x80009044ul); + outl(0xcfc, 0xf); + } +#endif +#if !defined(BROKEN_KEYBOARD_RESET) + /* + * Attempt to do a CPU reset via the keyboard controller, + * do not turn off GateA20, as any machine that fails + * to do the reset here would then end up in no man's land. + */ + outb(IO_KBD + 4, 0xFE); + DELAY(500000); /* wait 0.5 sec to see if that did it */ +#endif + + /* + * Attempt to force a reset via the Reset Control register at + * I/O port 0xcf9. Bit 2 forces a system reset when it + * transitions from 0 to 1. Bit 1 selects the type of reset + * to attempt: 0 selects a "soft" reset, and 1 selects a + * "hard" reset. We try a "hard" reset. The first write sets + * bit 1 to select a "hard" reset and clears bit 2. The + * second write forces a 0 -> 1 transition in bit 2 to trigger + * a reset. + */ + outb(0xcf9, 0x2); + outb(0xcf9, 0x6); + DELAY(500000); /* wait 0.5 sec to see if that did it */ + + /* + * Attempt to force a reset via the Fast A20 and Init register + * at I/O port 0x92. Bit 1 serves as an alternate A20 gate. + * Bit 0 asserts INIT# when set to 1. We are careful to only + * preserve bit 1 while setting bit 0. We also must clear bit + * 0 before setting it if it isn't already clear. + */ + b = inb(0x92); + if (b != 0xff) { + if ((b & 0x1) != 0) + outb(0x92, b & 0xfe); + outb(0x92, b | 0x1); + DELAY(500000); /* wait 0.5 sec to see if that did it */ + } + + printf("No known reset method worked, attempting CPU shutdown\n"); + DELAY(1000000); /* wait 1 sec for printf to complete */ + + /* Wipe the IDT. */ + null_idt.rd_limit = 0; + null_idt.rd_base = 0; + lidt(&null_idt); + + /* "good night, sweet prince .... " */ + breakpoint(); + + /* NOTREACHED */ + while(1); +} + +#ifdef SMP +static void +cpu_reset_proxy() +{ + + cpu_reset_proxy_active = 1; + while (cpu_reset_proxy_active == 1) + ia32_pause(); /* Wait for other cpu to see that we've started */ + + printf("cpu_reset_proxy: Stopped CPU %d\n", cpu_reset_proxyid); + DELAY(1000000); + cpu_reset_real(); +} +#endif + +void +cpu_reset() +{ +#ifdef SMP + cpuset_t map; + u_int cnt; + + if (smp_started) { + map = all_cpus; + CPU_CLR(PCPU_GET(cpuid), &map); + CPU_NAND(&map, &stopped_cpus); + if (!CPU_EMPTY(&map)) { + printf("cpu_reset: Stopping other CPUs\n"); + stop_cpus(map); + } + + if (PCPU_GET(cpuid) != 0) { + cpu_reset_proxyid = PCPU_GET(cpuid); + cpustop_restartfunc = cpu_reset_proxy; + cpu_reset_proxy_active = 0; + printf("cpu_reset: Restarting BSP\n"); + + /* Restart CPU #0. */ + CPU_SETOF(0, &started_cpus); + wmb(); + + cnt = 0; + while (cpu_reset_proxy_active == 0 && cnt < 10000000) { + ia32_pause(); + cnt++; /* Wait for BSP to announce restart */ + } + if (cpu_reset_proxy_active == 0) { + printf("cpu_reset: Failed to restart BSP\n"); + } else { + cpu_reset_proxy_active = 2; + while (1) + ia32_pause(); + /* NOTREACHED */ + } + } + + DELAY(1000000); + } +#endif + cpu_reset_real(); + /* NOTREACHED */ } bool