Thu Mar 8 11:33:15 2018 UTC ()
Pull up following revision(s) (requested by maxv in ticket #611):
	sys/arch/x86/x86/cpu.c: revision 1.134 (patch)
	sys/arch/x86/include/cpu.h: revision 1.78 (patch)
	sys/arch/i386/i386/machdep.c: revision 1.792 (patch)

style, and move some i386-specific code into i386/


(martin)
diff -r1.782.6.2 -r1.782.6.3 src/sys/arch/i386/i386/machdep.c
diff -r1.71 -r1.71.2.1 src/sys/arch/x86/include/cpu.h
diff -r1.130.2.2 -r1.130.2.3 src/sys/arch/x86/x86/cpu.c

cvs diff -r1.782.6.2 -r1.782.6.3 src/sys/arch/i386/i386/machdep.c (expand / switch to unified diff)

--- src/sys/arch/i386/i386/machdep.c 2018/01/01 19:09:03 1.782.6.2
+++ src/sys/arch/i386/i386/machdep.c 2018/03/08 11:33:15 1.782.6.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: machdep.c,v 1.782.6.2 2018/01/01 19:09:03 snj Exp $ */ 1/* $NetBSD: machdep.c,v 1.782.6.3 2018/03/08 11:33:15 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009 4 * Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009
5 * The NetBSD Foundation, Inc. 5 * The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Charles M. Hannum, by Jason R. Thorpe of the Numerical Aerospace 9 * by Charles M. Hannum, by Jason R. Thorpe of the Numerical Aerospace
10 * Simulation Facility NASA Ames Research Center, by Julio M. Merino Vidal, 10 * Simulation Facility NASA Ames Research Center, by Julio M. Merino Vidal,
11 * and by Andrew Doran. 11 * and by Andrew Doran.
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions 14 * modification, are permitted provided that the following conditions
@@ -57,27 +57,27 @@ @@ -57,27 +57,27 @@
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE. 64 * SUCH DAMAGE.
65 * 65 *
66 * @(#)machdep.c 7.4 (Berkeley) 6/3/91 66 * @(#)machdep.c 7.4 (Berkeley) 6/3/91
67 */ 67 */
68 68
69#include <sys/cdefs.h> 69#include <sys/cdefs.h>
70__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.782.6.2 2018/01/01 19:09:03 snj Exp $"); 70__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.782.6.3 2018/03/08 11:33:15 martin Exp $");
71 71
72#include "opt_beep.h" 72#include "opt_beep.h"
73#include "opt_compat_ibcs2.h" 73#include "opt_compat_ibcs2.h"
74#include "opt_compat_freebsd.h" 74#include "opt_compat_freebsd.h"
75#include "opt_compat_netbsd.h" 75#include "opt_compat_netbsd.h"
76#include "opt_compat_svr4.h" 76#include "opt_compat_svr4.h"
77#include "opt_cpureset_delay.h" 77#include "opt_cpureset_delay.h"
78#include "opt_ddb.h" 78#include "opt_ddb.h"
79#include "opt_ipkdb.h" 79#include "opt_ipkdb.h"
80#include "opt_kgdb.h" 80#include "opt_kgdb.h"
81#include "opt_mtrr.h" 81#include "opt_mtrr.h"
82#include "opt_modular.h" 82#include "opt_modular.h"
83#include "opt_multiboot.h" 83#include "opt_multiboot.h"
@@ -568,27 +568,98 @@ i386_tls_switch(lwp_t *l) @@ -568,27 +568,98 @@ i386_tls_switch(lwp_t *l)
568 if (l != ci->ci_fpcurlwp) { 568 if (l != ci->ci_fpcurlwp) {
569 HYPERVISOR_fpu_taskswitch(1); 569 HYPERVISOR_fpu_taskswitch(1);
570 } 570 }
571 571
572 /* Update TLS segment pointers */ 572 /* Update TLS segment pointers */
573 update_descriptor(&ci->ci_gdt[GUFS_SEL], 573 update_descriptor(&ci->ci_gdt[GUFS_SEL],
574 (union descriptor *) &pcb->pcb_fsd); 574 (union descriptor *) &pcb->pcb_fsd);
575 update_descriptor(&ci->ci_gdt[GUGS_SEL],  575 update_descriptor(&ci->ci_gdt[GUGS_SEL],
576 (union descriptor *) &pcb->pcb_gsd); 576 (union descriptor *) &pcb->pcb_gsd);
577 577
578} 578}
579#endif /* XEN */ 579#endif /* XEN */
580 580
 581/* XXX */
 582#define IDTVEC(name) __CONCAT(X, name)
 583typedef void (vector)(void);
 584
581#ifndef XEN 585#ifndef XEN
 586static void tss_init(struct i386tss *, void *, void *);
 587
 588static void
 589tss_init(struct i386tss *tss, void *stack, void *func)
 590{
 591 KASSERT(curcpu()->ci_pmap == pmap_kernel());
 592
 593 memset(tss, 0, sizeof *tss);
 594 tss->tss_esp0 = tss->tss_esp = (int)((char *)stack + USPACE - 16);
 595 tss->tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
 596 tss->__tss_cs = GSEL(GCODE_SEL, SEL_KPL);
 597 tss->tss_fs = GSEL(GCPU_SEL, SEL_KPL);
 598 tss->tss_gs = tss->__tss_es = tss->__tss_ds =
 599 tss->__tss_ss = GSEL(GDATA_SEL, SEL_KPL);
 600 /* %cr3 contains the value associated to pmap_kernel */
 601 tss->tss_cr3 = rcr3();
 602 tss->tss_esp = (int)((char *)stack + USPACE - 16);
 603 tss->tss_ldt = GSEL(GLDT_SEL, SEL_KPL);
 604 tss->__tss_eflags = PSL_MBO | PSL_NT; /* XXX not needed? */
 605 tss->__tss_eip = (int)func;
 606}
 607
 608extern vector IDTVEC(tss_trap08);
 609#if defined(DDB) && defined(MULTIPROCESSOR)
 610extern vector Xintrddbipi, Xx2apic_intrddbipi;
 611extern int ddb_vec;
 612#endif
 613
 614void
 615cpu_set_tss_gates(struct cpu_info *ci)
 616{
 617 struct segment_descriptor sd;
 618
 619 ci->ci_doubleflt_stack = (char *)uvm_km_alloc(kernel_map, USPACE, 0,
 620 UVM_KMF_WIRED);
 621
 622 tss_init(&ci->ci_doubleflt_tss, ci->ci_doubleflt_stack,
 623 IDTVEC(tss_trap08));
 624 setsegment(&sd, &ci->ci_doubleflt_tss, sizeof(struct i386tss) - 1,
 625 SDT_SYS386TSS, SEL_KPL, 0, 0);
 626 ci->ci_gdt[GTRAPTSS_SEL].sd = sd;
 627
 628 setgate(&idt[8], NULL, 0, SDT_SYSTASKGT, SEL_KPL,
 629 GSEL(GTRAPTSS_SEL, SEL_KPL));
 630
 631#if defined(DDB) && defined(MULTIPROCESSOR)
 632 /*
 633 * Set up separate handler for the DDB IPI, so that it doesn't
 634 * stomp on a possibly corrupted stack.
 635 *
 636 * XXX overwriting the gate set in db_machine_init.
 637 * Should rearrange the code so that it's set only once.
 638 */
 639 ci->ci_ddbipi_stack = (char *)uvm_km_alloc(kernel_map, USPACE, 0,
 640 UVM_KMF_WIRED);
 641 tss_init(&ci->ci_ddbipi_tss, ci->ci_ddbipi_stack,
 642 x2apic_mode ? Xx2apic_intrddbipi : Xintrddbipi);
 643
 644 setsegment(&sd, &ci->ci_ddbipi_tss, sizeof(struct i386tss) - 1,
 645 SDT_SYS386TSS, SEL_KPL, 0, 0);
 646 ci->ci_gdt[GIPITSS_SEL].sd = sd;
 647
 648 setgate(&idt[ddb_vec], NULL, 0, SDT_SYSTASKGT, SEL_KPL,
 649 GSEL(GIPITSS_SEL, SEL_KPL));
 650#endif
 651}
 652
582/* 653/*
583 * Set up TSS and I/O bitmap. 654 * Set up TSS and I/O bitmap.
584 */ 655 */
585void 656void
586cpu_init_tss(struct cpu_info *ci) 657cpu_init_tss(struct cpu_info *ci)
587{ 658{
588 struct i386tss *tss = &ci->ci_tss; 659 struct i386tss *tss = &ci->ci_tss;
589 660
590 tss->tss_iobase = IOMAP_INVALOFF << 16; 661 tss->tss_iobase = IOMAP_INVALOFF << 16;
591 tss->tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); 662 tss->tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
592 tss->tss_ldt = GSEL(GLDT_SEL, SEL_KPL); 663 tss->tss_ldt = GSEL(GLDT_SEL, SEL_KPL);
593 tss->tss_cr3 = rcr3(); 664 tss->tss_cr3 = rcr3();
594 ci->ci_tss_sel = tss_alloc(tss); 665 ci->ci_tss_sel = tss_alloc(tss);
@@ -920,28 +991,27 @@ setsegment(struct segment_descriptor *sd @@ -920,28 +991,27 @@ setsegment(struct segment_descriptor *sd
920 991
921 sd->sd_lolimit = (int)limit; 992 sd->sd_lolimit = (int)limit;
922 sd->sd_lobase = (int)base; 993 sd->sd_lobase = (int)base;
923 sd->sd_type = type; 994 sd->sd_type = type;
924 sd->sd_dpl = dpl; 995 sd->sd_dpl = dpl;
925 sd->sd_p = 1; 996 sd->sd_p = 1;
926 sd->sd_hilimit = (int)limit >> 16; 997 sd->sd_hilimit = (int)limit >> 16;
927 sd->sd_xx = 0; 998 sd->sd_xx = 0;
928 sd->sd_def32 = def32; 999 sd->sd_def32 = def32;
929 sd->sd_gran = gran; 1000 sd->sd_gran = gran;
930 sd->sd_hibase = (int)base >> 24; 1001 sd->sd_hibase = (int)base >> 24;
931} 1002}
932 1003
933#define IDTVEC(name) __CONCAT(X, name) 1004/* XXX */
934typedef void (vector)(void); 
935extern vector IDTVEC(syscall); 1005extern vector IDTVEC(syscall);
936extern vector *IDTVEC(exceptions)[]; 1006extern vector *IDTVEC(exceptions)[];
937extern vector IDTVEC(svr4_fasttrap); 1007extern vector IDTVEC(svr4_fasttrap);
938void (*svr4_fasttrap_vec)(void) = (void (*)(void))nullop; 1008void (*svr4_fasttrap_vec)(void) = (void (*)(void))nullop;
939krwlock_t svr4_fasttrap_lock; 1009krwlock_t svr4_fasttrap_lock;
940#ifdef XEN 1010#ifdef XEN
941#define MAX_XEN_IDT 128 1011#define MAX_XEN_IDT 128
942trap_info_t xen_idt[MAX_XEN_IDT]; 1012trap_info_t xen_idt[MAX_XEN_IDT];
943int xen_idt_idx; 1013int xen_idt_idx;
944extern union descriptor tmpgdt[]; 1014extern union descriptor tmpgdt[];
945#endif 1015#endif
946 1016
947void  1017void

cvs diff -r1.71 -r1.71.2.1 src/sys/arch/x86/include/cpu.h (expand / switch to unified diff)

--- src/sys/arch/x86/include/cpu.h 2017/05/23 08:48:34 1.71
+++ src/sys/arch/x86/include/cpu.h 2018/03/08 11:33:15 1.71.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cpu.h,v 1.71 2017/05/23 08:48:34 nonaka Exp $ */ 1/* $NetBSD: cpu.h,v 1.71.2.1 2018/03/08 11:33:15 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1990 The Regents of the University of California. 4 * Copyright (c) 1990 The Regents of the University of California.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * William Jolitz. 8 * William Jolitz.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -396,26 +396,29 @@ extern int i386_has_sse2; @@ -396,26 +396,29 @@ extern int i386_has_sse2;
396 396
397extern int x86_fpu_save; 397extern int x86_fpu_save;
398#define FPU_SAVE_FSAVE 0 398#define FPU_SAVE_FSAVE 0
399#define FPU_SAVE_FXSAVE 1 399#define FPU_SAVE_FXSAVE 1
400#define FPU_SAVE_XSAVE 2 400#define FPU_SAVE_XSAVE 2
401#define FPU_SAVE_XSAVEOPT 3 401#define FPU_SAVE_XSAVEOPT 3
402extern unsigned int x86_fpu_save_size; 402extern unsigned int x86_fpu_save_size;
403extern uint64_t x86_xsave_features; 403extern uint64_t x86_xsave_features;
404 404
405extern void (*x86_cpu_idle)(void); 405extern void (*x86_cpu_idle)(void);
406#define cpu_idle() (*x86_cpu_idle)() 406#define cpu_idle() (*x86_cpu_idle)()
407 407
408/* machdep.c */ 408/* machdep.c */
 409#ifdef i386
 410void cpu_set_tss_gates(struct cpu_info *);
 411#endif
409void dumpconf(void); 412void dumpconf(void);
410void cpu_reset(void); 413void cpu_reset(void);
411void i386_proc0_tss_ldt_init(void); 414void i386_proc0_tss_ldt_init(void);
412void dumpconf(void); 415void dumpconf(void);
413void cpu_reset(void); 416void cpu_reset(void);
414void x86_64_proc0_tss_ldt_init(void); 417void x86_64_proc0_tss_ldt_init(void);
415void x86_64_init_pcb_tss_ldt(struct cpu_info *); 418void x86_64_init_pcb_tss_ldt(struct cpu_info *);
416 419
417/* longrun.c */ 420/* longrun.c */
418u_int tmx86_get_longrun_mode(void); 421u_int tmx86_get_longrun_mode(void);
419void tmx86_get_longrun_status(u_int *, u_int *, u_int *); 422void tmx86_get_longrun_status(u_int *, u_int *, u_int *);
420void tmx86_init_longrun(void); 423void tmx86_init_longrun(void);
421 424
@@ -428,59 +431,56 @@ typedef enum vm_guest { @@ -428,59 +431,56 @@ typedef enum vm_guest {
428 VM_GUEST_NO = 0, 431 VM_GUEST_NO = 0,
429 VM_GUEST_VM, 432 VM_GUEST_VM,
430 VM_GUEST_XEN, 433 VM_GUEST_XEN,
431 VM_GUEST_HV, 434 VM_GUEST_HV,
432 VM_GUEST_VMWARE, 435 VM_GUEST_VMWARE,
433 VM_GUEST_KVM, 436 VM_GUEST_KVM,
434 VM_LAST 437 VM_LAST
435} vm_guest_t; 438} vm_guest_t;
436extern vm_guest_t vm_guest; 439extern vm_guest_t vm_guest;
437 440
438/* cpu_topology.c */ 441/* cpu_topology.c */
439void x86_cpu_topology(struct cpu_info *); 442void x86_cpu_topology(struct cpu_info *);
440 443
441/* vm_machdep.c */ 
442void cpu_proc_fork(struct proc *, struct proc *); 
443 
444/* locore.s */ 444/* locore.s */
445struct region_descriptor; 445struct region_descriptor;
446void lgdt(struct region_descriptor *); 446void lgdt(struct region_descriptor *);
447#ifdef XEN 447#ifdef XEN
448void lgdt_finish(void); 448void lgdt_finish(void);
449#endif 449#endif
450 450
451struct pcb; 451struct pcb;
452void savectx(struct pcb *); 452void savectx(struct pcb *);
453void lwp_trampoline(void); 453void lwp_trampoline(void);
454#ifdef XEN 454#ifdef XEN
455void startrtclock(void); 455void startrtclock(void);
456void xen_delay(unsigned int); 456void xen_delay(unsigned int);
457void xen_initclocks(void); 457void xen_initclocks(void);
458void xen_suspendclocks(struct cpu_info *); 458void xen_suspendclocks(struct cpu_info *);
459void xen_resumeclocks(struct cpu_info *); 459void xen_resumeclocks(struct cpu_info *);
460#else 460#else
461/* clock.c */ 461/* clock.c */
462void initrtclock(u_long); 462void initrtclock(u_long);
463void startrtclock(void); 463void startrtclock(void);
464void i8254_delay(unsigned int); 464void i8254_delay(unsigned int);
465void i8254_microtime(struct timeval *); 465void i8254_microtime(struct timeval *);
466void i8254_initclocks(void); 466void i8254_initclocks(void);
467#endif 467#endif
468 468
469/* cpu.c */ 469/* cpu.c */
470 
471void cpu_probe_features(struct cpu_info *); 470void cpu_probe_features(struct cpu_info *);
472 471
473/* vm_machdep.c */ 472/* vm_machdep.c */
 473void cpu_proc_fork(struct proc *, struct proc *);
474paddr_t kvtop(void *); 474paddr_t kvtop(void *);
475 475
476#ifdef USER_LDT 476#ifdef USER_LDT
477/* sys_machdep.h */ 477/* sys_machdep.h */
478int x86_get_ldt(struct lwp *, void *, register_t *); 478int x86_get_ldt(struct lwp *, void *, register_t *);
479int x86_set_ldt(struct lwp *, void *, register_t *); 479int x86_set_ldt(struct lwp *, void *, register_t *);
480#endif 480#endif
481 481
482/* isa_machdep.c */ 482/* isa_machdep.c */
483void isa_defaultirq(void); 483void isa_defaultirq(void);
484int isa_nmi(void); 484int isa_nmi(void);
485 485
486#ifdef VM86 486#ifdef VM86

cvs diff -r1.130.2.2 -r1.130.2.3 src/sys/arch/x86/x86/cpu.c (expand / switch to unified diff)

--- src/sys/arch/x86/x86/cpu.c 2018/03/07 14:50:57 1.130.2.2
+++ src/sys/arch/x86/x86/cpu.c 2018/03/08 11:33:15 1.130.2.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cpu.c,v 1.130.2.2 2018/03/07 14:50:57 martin Exp $ */ 1/* $NetBSD: cpu.c,v 1.130.2.3 2018/03/08 11:33:15 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2000-2012 NetBSD Foundation, Inc. 4 * Copyright (c) 2000-2012 NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Bill Sommerfeld of RedBack Networks Inc, and by Andrew Doran. 8 * by Bill Sommerfeld of RedBack Networks Inc, and by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -52,27 +52,27 @@ @@ -52,27 +52,27 @@
52 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE 54 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * SUCH DAMAGE. 61 * SUCH DAMAGE.
62 */ 62 */
63 63
64#include <sys/cdefs.h> 64#include <sys/cdefs.h>
65__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.130.2.2 2018/03/07 14:50:57 martin Exp $"); 65__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.130.2.3 2018/03/08 11:33:15 martin Exp $");
66 66
67#include "opt_ddb.h" 67#include "opt_ddb.h"
68#include "opt_mpbios.h" /* for MPDEBUG */ 68#include "opt_mpbios.h" /* for MPDEBUG */
69#include "opt_mtrr.h" 69#include "opt_mtrr.h"
70#include "opt_multiprocessor.h" 70#include "opt_multiprocessor.h"
71 71
72#include "lapic.h" 72#include "lapic.h"
73#include "ioapic.h" 73#include "ioapic.h"
74 74
75#include <sys/param.h> 75#include <sys/param.h>
76#include <sys/proc.h> 76#include <sys/proc.h>
77#include <sys/systm.h> 77#include <sys/systm.h>
78#include <sys/device.h> 78#include <sys/device.h>
@@ -154,51 +154,47 @@ CFATTACH_DECL2_NEW(cpu, sizeof(struct cp @@ -154,51 +154,47 @@ CFATTACH_DECL2_NEW(cpu, sizeof(struct cp
154 * point at it. 154 * point at it.
155 */ 155 */
156#ifdef TRAPLOG 156#ifdef TRAPLOG
157struct tlog tlog_primary; 157struct tlog tlog_primary;
158#endif 158#endif
159struct cpu_info cpu_info_primary __aligned(CACHE_LINE_SIZE) = { 159struct cpu_info cpu_info_primary __aligned(CACHE_LINE_SIZE) = {
160 .ci_dev = 0, 160 .ci_dev = 0,
161 .ci_self = &cpu_info_primary, 161 .ci_self = &cpu_info_primary,
162 .ci_idepth = -1, 162 .ci_idepth = -1,
163 .ci_curlwp = &lwp0, 163 .ci_curlwp = &lwp0,
164 .ci_curldt = -1, 164 .ci_curldt = -1,
165#ifdef TRAPLOG 165#ifdef TRAPLOG
166 .ci_tlog_base = &tlog_primary, 166 .ci_tlog_base = &tlog_primary,
167#endif /* !TRAPLOG */ 167#endif
168}; 168};
169 169
170struct cpu_info *cpu_info_list = &cpu_info_primary; 170struct cpu_info *cpu_info_list = &cpu_info_primary;
171 171
172static void cpu_set_tss_gates(struct cpu_info *); 
173 
174#ifdef i386 172#ifdef i386
175static void tss_init(struct i386tss *, void *, void *); 173void cpu_set_tss_gates(struct cpu_info *);
176#endif 174#endif
177 175
178static void cpu_init_idle_lwp(struct cpu_info *); 176static void cpu_init_idle_lwp(struct cpu_info *);
179 177
180uint32_t cpu_feature[7] __read_mostly; /* X86 CPUID feature bits */ 178uint32_t cpu_feature[7] __read_mostly; /* X86 CPUID feature bits */
181 /* [0] basic features cpuid.1:%edx 179 /* [0] basic features cpuid.1:%edx
182 * [1] basic features cpuid.1:%ecx (CPUID2_xxx bits) 180 * [1] basic features cpuid.1:%ecx (CPUID2_xxx bits)
183 * [2] extended features cpuid:80000001:%edx 181 * [2] extended features cpuid:80000001:%edx
184 * [3] extended features cpuid:80000001:%ecx 182 * [3] extended features cpuid:80000001:%ecx
185 * [4] VIA padlock features 183 * [4] VIA padlock features
186 * [5] structured extended features cpuid.7:%ebx 184 * [5] structured extended features cpuid.7:%ebx
187 * [6] structured extended features cpuid.7:%ecx 185 * [6] structured extended features cpuid.7:%ecx
188 */ 186 */
189 187
190extern char x86_64_doubleflt_stack[]; 
191 
192#ifdef MULTIPROCESSOR 188#ifdef MULTIPROCESSOR
193bool x86_mp_online; 189bool x86_mp_online;
194paddr_t mp_trampoline_paddr = MP_TRAMPOLINE; 190paddr_t mp_trampoline_paddr = MP_TRAMPOLINE;
195#endif 191#endif
196#if NLAPIC > 0 192#if NLAPIC > 0
197static vaddr_t cmos_data_mapping; 193static vaddr_t cmos_data_mapping;
198#endif 194#endif
199struct cpu_info *cpu_starting; 195struct cpu_info *cpu_starting;
200 196
201#ifdef MULTIPROCESSOR 197#ifdef MULTIPROCESSOR
202void cpu_hatch(void *); 198void cpu_hatch(void *);
203static void cpu_boot_secondary(struct cpu_info *ci); 199static void cpu_boot_secondary(struct cpu_info *ci);
204static void cpu_start_secondary(struct cpu_info *ci); 200static void cpu_start_secondary(struct cpu_info *ci);
@@ -385,27 +381,29 @@ cpu_attach(device_t parent, device_t sel @@ -385,27 +381,29 @@ cpu_attach(device_t parent, device_t sel
385 ci->ci_pmap = pmap_kernel(); 381 ci->ci_pmap = pmap_kernel();
386 ci->ci_tlbstate = TLBSTATE_STALE; 382 ci->ci_tlbstate = TLBSTATE_STALE;
387 383
388 /* 384 /*
389 * Boot processor may not be attached first, but the below 385 * Boot processor may not be attached first, but the below
390 * must be done to allow booting other processors. 386 * must be done to allow booting other processors.
391 */ 387 */
392 if (!again) { 388 if (!again) {
393 atomic_or_32(&ci->ci_flags, CPUF_PRESENT | CPUF_PRIMARY); 389 atomic_or_32(&ci->ci_flags, CPUF_PRESENT | CPUF_PRIMARY);
394 /* Basic init. */ 390 /* Basic init. */
395 cpu_intr_init(ci); 391 cpu_intr_init(ci);
396 cpu_get_tsc_freq(ci); 392 cpu_get_tsc_freq(ci);
397 cpu_init(ci); 393 cpu_init(ci);
 394#ifdef i386
398 cpu_set_tss_gates(ci); 395 cpu_set_tss_gates(ci);
 396#endif
399 pmap_cpu_init_late(ci); 397 pmap_cpu_init_late(ci);
400#if NLAPIC > 0 398#if NLAPIC > 0
401 if (caa->cpu_role != CPU_ROLE_SP) { 399 if (caa->cpu_role != CPU_ROLE_SP) {
402 /* Enable lapic. */ 400 /* Enable lapic. */
403 lapic_enable(); 401 lapic_enable();
404 lapic_set_lvt(); 402 lapic_set_lvt();
405 lapic_calibrate_timer(ci); 403 lapic_calibrate_timer(ci);
406 } 404 }
407#endif 405#endif
408 /* Make sure DELAY() is initialized. */ 406 /* Make sure DELAY() is initialized. */
409 DELAY(1); 407 DELAY(1);
410 again = true; 408 again = true;
411 } 409 }
@@ -424,27 +422,29 @@ cpu_attach(device_t parent, device_t sel @@ -424,27 +422,29 @@ cpu_attach(device_t parent, device_t sel
424 atomic_or_32(&ci->ci_flags, CPUF_BSP); 422 atomic_or_32(&ci->ci_flags, CPUF_BSP);
425 cpu_identify(ci); 423 cpu_identify(ci);
426 x86_errata(); 424 x86_errata();
427 x86_cpu_idle_init(); 425 x86_cpu_idle_init();
428 break; 426 break;
429 427
430#ifdef MULTIPROCESSOR 428#ifdef MULTIPROCESSOR
431 case CPU_ROLE_AP: 429 case CPU_ROLE_AP:
432 /* 430 /*
433 * report on an AP 431 * report on an AP
434 */ 432 */
435 cpu_intr_init(ci); 433 cpu_intr_init(ci);
436 gdt_alloc_cpu(ci); 434 gdt_alloc_cpu(ci);
 435#ifdef i386
437 cpu_set_tss_gates(ci); 436 cpu_set_tss_gates(ci);
 437#endif
438 pmap_cpu_init_late(ci); 438 pmap_cpu_init_late(ci);
439 cpu_start_secondary(ci); 439 cpu_start_secondary(ci);
440 if (ci->ci_flags & CPUF_PRESENT) { 440 if (ci->ci_flags & CPUF_PRESENT) {
441 struct cpu_info *tmp; 441 struct cpu_info *tmp;
442 442
443 cpu_identify(ci); 443 cpu_identify(ci);
444 tmp = cpu_info_list; 444 tmp = cpu_info_list;
445 while (tmp->ci_next) 445 while (tmp->ci_next)
446 tmp = tmp->ci_next; 446 tmp = tmp->ci_next;
447 447
448 tmp->ci_next = ci; 448 tmp->ci_next = ci;
449 } 449 }
450 break; 450 break;
@@ -491,27 +491,26 @@ cpu_defer(device_t self) @@ -491,27 +491,26 @@ cpu_defer(device_t self)
491} 491}
492 492
493static int 493static int
494cpu_rescan(device_t self, const char *ifattr, const int *locators) 494cpu_rescan(device_t self, const char *ifattr, const int *locators)
495{ 495{
496 struct cpu_softc *sc = device_private(self); 496 struct cpu_softc *sc = device_private(self);
497 struct cpufeature_attach_args cfaa; 497 struct cpufeature_attach_args cfaa;
498 struct cpu_info *ci = sc->sc_info; 498 struct cpu_info *ci = sc->sc_info;
499 499
500 memset(&cfaa, 0, sizeof(cfaa)); 500 memset(&cfaa, 0, sizeof(cfaa));
501 cfaa.ci = ci; 501 cfaa.ci = ci;
502 502
503 if (ifattr_match(ifattr, "cpufeaturebus")) { 503 if (ifattr_match(ifattr, "cpufeaturebus")) {
504 
505 if (ci->ci_frequency == NULL) { 504 if (ci->ci_frequency == NULL) {
506 cfaa.name = "frequency"; 505 cfaa.name = "frequency";
507 ci->ci_frequency = config_found_ia(self, 506 ci->ci_frequency = config_found_ia(self,
508 "cpufeaturebus", &cfaa, NULL); 507 "cpufeaturebus", &cfaa, NULL);
509 } 508 }
510 509
511 if (ci->ci_padlock == NULL) { 510 if (ci->ci_padlock == NULL) {
512 cfaa.name = "padlock"; 511 cfaa.name = "padlock";
513 ci->ci_padlock = config_found_ia(self, 512 ci->ci_padlock = config_found_ia(self,
514 "cpufeaturebus", &cfaa, NULL); 513 "cpufeaturebus", &cfaa, NULL);
515 } 514 }
516 515
517 if (ci->ci_temperature == NULL) { 516 if (ci->ci_temperature == NULL) {
@@ -798,43 +797,43 @@ cpu_boot_secondary(struct cpu_info *ci) @@ -798,43 +797,43 @@ cpu_boot_secondary(struct cpu_info *ci)
798 * this processor will enter the idle loop and start looking for work. 797 * this processor will enter the idle loop and start looking for work.
799 */ 798 */
800void 799void
801cpu_hatch(void *v) 800cpu_hatch(void *v)
802{ 801{
803 struct cpu_info *ci = (struct cpu_info *)v; 802 struct cpu_info *ci = (struct cpu_info *)v;
804 struct pcb *pcb; 803 struct pcb *pcb;
805 int s, i; 804 int s, i;
806 805
807 cpu_init_msrs(ci, true); 806 cpu_init_msrs(ci, true);
808 cpu_probe(ci); 807 cpu_probe(ci);
809 808
810 ci->ci_data.cpu_cc_freq = cpu_info_primary.ci_data.cpu_cc_freq; 809 ci->ci_data.cpu_cc_freq = cpu_info_primary.ci_data.cpu_cc_freq;
811 /* cpu_get_tsc_freq(ci); */  810 /* cpu_get_tsc_freq(ci); */
812 811
813 KDASSERT((ci->ci_flags & CPUF_PRESENT) == 0); 812 KDASSERT((ci->ci_flags & CPUF_PRESENT) == 0);
814 813
815 /* 814 /*
816 * Synchronize time stamp counters. Invalidate cache and do twice 815 * Synchronize time stamp counters. Invalidate cache and do twice
817 * to try and minimize possible cache effects. Note that interrupts 816 * to try and minimize possible cache effects. Note that interrupts
818 * are off at this point. 817 * are off at this point.
819 */ 818 */
820 wbinvd(); 819 wbinvd();
821 atomic_or_32(&ci->ci_flags, CPUF_PRESENT); 820 atomic_or_32(&ci->ci_flags, CPUF_PRESENT);
822 tsc_sync_ap(ci); 821 tsc_sync_ap(ci);
823 822
824 /* 823 /*
825 * Wait to be brought online. Use 'monitor/mwait' if available, 824 * Wait to be brought online. Use 'monitor/mwait' if available,
826 * in order to make the TSC drift as much as possible. so that 825 * in order to make the TSC drift as much as possible. so that
827 * we can detect it later. If not available, try 'pause'.  826 * we can detect it later. If not available, try 'pause'.
828 * We'd like to use 'hlt', but we have interrupts off. 827 * We'd like to use 'hlt', but we have interrupts off.
829 */ 828 */
830 while ((ci->ci_flags & CPUF_GO) == 0) { 829 while ((ci->ci_flags & CPUF_GO) == 0) {
831 if ((cpu_feature[1] & CPUID2_MONITOR) != 0) { 830 if ((cpu_feature[1] & CPUID2_MONITOR) != 0) {
832 x86_monitor(&ci->ci_flags, 0, 0); 831 x86_monitor(&ci->ci_flags, 0, 0);
833 if ((ci->ci_flags & CPUF_GO) != 0) { 832 if ((ci->ci_flags & CPUF_GO) != 0) {
834 continue; 833 continue;
835 } 834 }
836 x86_mwait(0, 0); 835 x86_mwait(0, 0);
837 } else { 836 } else {
838 /* 837 /*
839 * XXX The loop repetition count could be a lot higher, but 838 * XXX The loop repetition count could be a lot higher, but
840 * XXX currently qemu emulator takes a _very_long_time_ to 839 * XXX currently qemu emulator takes a _very_long_time_ to
@@ -923,119 +922,45 @@ cpu_debug_dump(void) @@ -923,119 +922,45 @@ cpu_debug_dump(void)
923 } 922 }
924} 923}
925#endif 924#endif
926 925
927#if NLAPIC > 0 926#if NLAPIC > 0
928static void 927static void
929cpu_copy_trampoline(void) 928cpu_copy_trampoline(void)
930{ 929{
931 /* 930 /*
932 * Copy boot code. 931 * Copy boot code.
933 */ 932 */
934 extern u_char cpu_spinup_trampoline[]; 933 extern u_char cpu_spinup_trampoline[];
935 extern u_char cpu_spinup_trampoline_end[]; 934 extern u_char cpu_spinup_trampoline_end[];
936  935
937 vaddr_t mp_trampoline_vaddr; 936 vaddr_t mp_trampoline_vaddr;
938 937
939 mp_trampoline_vaddr = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, 938 mp_trampoline_vaddr = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
940 UVM_KMF_VAONLY); 939 UVM_KMF_VAONLY);
941 940
942 pmap_kenter_pa(mp_trampoline_vaddr, mp_trampoline_paddr, 941 pmap_kenter_pa(mp_trampoline_vaddr, mp_trampoline_paddr,
943 VM_PROT_READ | VM_PROT_WRITE, 0); 942 VM_PROT_READ | VM_PROT_WRITE, 0);
944 pmap_update(pmap_kernel()); 943 pmap_update(pmap_kernel());
945 memcpy((void *)mp_trampoline_vaddr, 944 memcpy((void *)mp_trampoline_vaddr,
946 cpu_spinup_trampoline, 945 cpu_spinup_trampoline,
947 cpu_spinup_trampoline_end - cpu_spinup_trampoline); 946 cpu_spinup_trampoline_end - cpu_spinup_trampoline);
948 947
949 pmap_kremove(mp_trampoline_vaddr, PAGE_SIZE); 948 pmap_kremove(mp_trampoline_vaddr, PAGE_SIZE);
950 pmap_update(pmap_kernel()); 949 pmap_update(pmap_kernel());
951 uvm_km_free(kernel_map, mp_trampoline_vaddr, PAGE_SIZE, UVM_KMF_VAONLY); 950 uvm_km_free(kernel_map, mp_trampoline_vaddr, PAGE_SIZE, UVM_KMF_VAONLY);
952} 951}
953#endif 952#endif
954 953
955#ifdef i386 
956static void 
957tss_init(struct i386tss *tss, void *stack, void *func) 
958{ 
959 KASSERT(curcpu()->ci_pmap == pmap_kernel()); 
960 
961 memset(tss, 0, sizeof *tss); 
962 tss->tss_esp0 = tss->tss_esp = (int)((char *)stack + USPACE - 16); 
963 tss->tss_ss0 = GSEL(GDATA_SEL, SEL_KPL); 
964 tss->__tss_cs = GSEL(GCODE_SEL, SEL_KPL); 
965 tss->tss_fs = GSEL(GCPU_SEL, SEL_KPL); 
966 tss->tss_gs = tss->__tss_es = tss->__tss_ds = 
967 tss->__tss_ss = GSEL(GDATA_SEL, SEL_KPL); 
968 /* %cr3 contains the value associated to pmap_kernel */ 
969 tss->tss_cr3 = rcr3(); 
970 tss->tss_esp = (int)((char *)stack + USPACE - 16); 
971 tss->tss_ldt = GSEL(GLDT_SEL, SEL_KPL); 
972 tss->__tss_eflags = PSL_MBO | PSL_NT; /* XXX not needed? */ 
973 tss->__tss_eip = (int)func; 
974} 
975 
976/* XXX */ 
977#define IDTVEC(name) __CONCAT(X, name) 
978typedef void (vector)(void); 
979extern vector IDTVEC(tss_trap08); 
980#if defined(DDB) && defined(MULTIPROCESSOR) 
981extern vector Xintrddbipi, Xx2apic_intrddbipi; 
982extern int ddb_vec; 
983#endif 
984 
985static void 
986cpu_set_tss_gates(struct cpu_info *ci) 
987{ 
988 struct segment_descriptor sd; 
989 
990 ci->ci_doubleflt_stack = (char *)uvm_km_alloc(kernel_map, USPACE, 0, 
991 UVM_KMF_WIRED); 
992 tss_init(&ci->ci_doubleflt_tss, ci->ci_doubleflt_stack, 
993 IDTVEC(tss_trap08)); 
994 setsegment(&sd, &ci->ci_doubleflt_tss, sizeof(struct i386tss) - 1, 
995 SDT_SYS386TSS, SEL_KPL, 0, 0); 
996 ci->ci_gdt[GTRAPTSS_SEL].sd = sd; 
997 setgate(&idt[8], NULL, 0, SDT_SYSTASKGT, SEL_KPL, 
998 GSEL(GTRAPTSS_SEL, SEL_KPL)); 
999 
1000#if defined(DDB) && defined(MULTIPROCESSOR) 
1001 /* 
1002 * Set up separate handler for the DDB IPI, so that it doesn't 
1003 * stomp on a possibly corrupted stack. 
1004 * 
1005 * XXX overwriting the gate set in db_machine_init. 
1006 * Should rearrange the code so that it's set only once. 
1007 */ 
1008 ci->ci_ddbipi_stack = (char *)uvm_km_alloc(kernel_map, USPACE, 0, 
1009 UVM_KMF_WIRED); 
1010 tss_init(&ci->ci_ddbipi_tss, ci->ci_ddbipi_stack, 
1011 x2apic_mode ? Xx2apic_intrddbipi : Xintrddbipi); 
1012 
1013 setsegment(&sd, &ci->ci_ddbipi_tss, sizeof(struct i386tss) - 1, 
1014 SDT_SYS386TSS, SEL_KPL, 0, 0); 
1015 ci->ci_gdt[GIPITSS_SEL].sd = sd; 
1016 
1017 setgate(&idt[ddb_vec], NULL, 0, SDT_SYSTASKGT, SEL_KPL, 
1018 GSEL(GIPITSS_SEL, SEL_KPL)); 
1019#endif 
1020} 
1021#else 
1022static void 
1023cpu_set_tss_gates(struct cpu_info *ci) 
1024{ 
1025 
1026} 
1027#endif /* i386 */ 
1028 
1029#ifdef MULTIPROCESSOR 954#ifdef MULTIPROCESSOR
1030int 955int
1031mp_cpu_start(struct cpu_info *ci, paddr_t target) 956mp_cpu_start(struct cpu_info *ci, paddr_t target)
1032{ 957{
1033 unsigned short dwordptr[2]; 958 unsigned short dwordptr[2];
1034 int error; 959 int error;
1035 960
1036 /* 961 /*
1037 * Bootstrap code must be addressable in real mode 962 * Bootstrap code must be addressable in real mode
1038 * and it must be page aligned. 963 * and it must be page aligned.
1039 */ 964 */
1040 KASSERT(target < 0x10000 && target % PAGE_SIZE == 0); 965 KASSERT(target < 0x10000 && target % PAGE_SIZE == 0);
1041 966
@@ -1295,27 +1220,27 @@ cpu_load_pmap(struct pmap *pmap, struct  @@ -1295,27 +1220,27 @@ cpu_load_pmap(struct pmap *pmap, struct
1295 1220
1296 /* 1221 /*
1297 * disable interrupts to block TLB shootdowns, which can reload cr3. 1222 * disable interrupts to block TLB shootdowns, which can reload cr3.
1298 * while this doesn't block NMIs, it's probably ok as NMIs unlikely 1223 * while this doesn't block NMIs, it's probably ok as NMIs unlikely
1299 * reload cr3. 1224 * reload cr3.
1300 */ 1225 */
1301 interrupts_enabled = (x86_read_flags() & PSL_I) != 0; 1226 interrupts_enabled = (x86_read_flags() & PSL_I) != 0;
1302 if (interrupts_enabled) 1227 if (interrupts_enabled)
1303 x86_disable_intr(); 1228 x86_disable_intr();
1304 1229
1305 for (i = 0 ; i < PDP_SIZE; i++) { 1230 for (i = 0 ; i < PDP_SIZE; i++) {
1306 l3_pd[i] = pmap->pm_pdirpa[i] | PG_V; 1231 l3_pd[i] = pmap->pm_pdirpa[i] | PG_V;
1307 } 1232 }
1308  1233
1309 if (interrupts_enabled) 1234 if (interrupts_enabled)
1310 x86_enable_intr(); 1235 x86_enable_intr();
1311 tlbflush(); 1236 tlbflush();
1312#else /* PAE */ 1237#else /* PAE */
1313 lcr3(pmap_pdirpa(pmap, 0)); 1238 lcr3(pmap_pdirpa(pmap, 0));
1314#endif /* PAE */ 1239#endif /* PAE */
1315} 1240}
1316 1241
1317/* 1242/*
1318 * Notify all other cpus to halt. 1243 * Notify all other cpus to halt.
1319 */ 1244 */
1320 1245
1321void 1246void