This diff has been circulating around and I think amd64 is in pretty good
shape. I need testers for i386 - this diff includes both.

On some machines, during suspend/resume and other times, the BIOS/SMM
code corrupts low pages of memory. We presently use those pages for
various trampolines and hibernate scratch area. This diff moves those
users up so they start at 64kb physical. Linux and Windows have been
doing this for some time now.

If you have an i386 machine, please verify:

1. That 'zzz' and resume work, provided they worked before the diff.

2. That 'ZZZ' and resume work, provided they worked before the diff.

3. That all CPUs properly spin up during boot (if using SMP).

I have another set of trampoline diffs queued up behind this
diff, so I'd like to get this in ASAP. Thanks to those who have already
helped testing amd64.

-ml


Index: arch/amd64/amd64/acpi_wakecode.S
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/acpi_wakecode.S,v
retrieving revision 1.22
diff -a -u -r1.22 acpi_wakecode.S
--- arch/amd64/amd64/acpi_wakecode.S    26 Dec 2013 18:52:09 -0000      1.22
+++ arch/amd64/amd64/acpi_wakecode.S    27 Dec 2013 16:36:15 -0000
@@ -67,7 +67,7 @@
  *
  * We wakeup in real mode, at some phys addr based on the ACPI
  * specification (cs = phys>>8, ip = phys & 0xF). For example,
- * if our phys addr is 0x4000, we'd have cs=0x0400,ip=0
+ * if our phys addr is 0x11000, we'd have cs=0x1100,ip=0
  *
  * The wakeup code needs to do the following:
  *     1. Reenable the video display
@@ -410,7 +410,7 @@
        movl    %eax, %cr0
 
        /* Set up real mode segment selectors */
-       movw    $0x0400, %ax
+       movw    $0x1100, %ax
        movw    %ax, %ds
        movw    %ax, %es
        movw    %ax, %fs
@@ -419,7 +419,7 @@
        lidtl   clean_idt
 
        /* Jump to the S3 resume vector */
-       ljmp    $0x0400, $acpi_s3_vector_real
+       ljmp    $0x1100, $acpi_s3_vector_real
 
 NENTRY(hibernate_drop_to_real_mode)
        .code64
@@ -448,7 +448,7 @@
        movl    %eax, %cr0
 
        /* Set up real mode segment selectors */
-       movw    $0x0400, %ax
+       movw    $0x1100, %ax
        movw    %ax, %ds
        movw    %ax, %es
        movw    %ax, %fs
@@ -456,11 +456,11 @@
        movl    $0x0FFE, %esp
        lidtl   clean_idt
 
-       ljmp    $0x0400, $hib_hlt_real
+       ljmp    $0x1100, $hib_hlt_real
 
 _ACPI_TRMP_OFFSET(hib_hlt_real)
        hlt
-       ljmp    $0x0400, $hib_hlt_real
+       ljmp    $0x1100, $hib_hlt_real
 
        .code64
        /* Switch to hibernate resume pagetable */
Index: arch/amd64/amd64/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/machdep.c,v
retrieving revision 1.172
diff -a -u -r1.172 machdep.c
--- arch/amd64/amd64/machdep.c  23 Dec 2013 23:23:22 -0000      1.172
+++ arch/amd64/amd64/machdep.c  26 Dec 2013 17:42:41 -0000
@@ -1228,7 +1228,6 @@
            VM_PROT_ALL);               /* protection */
 #endif /* MULTIPROCESSOR */
 
-
        pmap_kenter_pa((vaddr_t)ACPI_TRAMPOLINE, /* virtual */
            (paddr_t)ACPI_TRAMPOLINE,   /* physical */
            VM_PROT_ALL);               /* protection */
@@ -1309,10 +1308,12 @@
  *
  * first_avail - This is the first available physical page after the
  *               kernel, page tables, etc.
+ *
+ * We skip the first few pages for trampolines, hibernate, and to avoid
+ * buggy SMI implementations that could corrupt the first 64KB.
  */
+       avail_start = 16*PAGE_SIZE;
 
-       avail_start = PAGE_SIZE; /* BIOS leaves data in low memory */
-                                /* and VM system doesn't work with phys 0 */
 #ifdef MULTIPROCESSOR
        if (avail_start < MP_TRAMPOLINE + PAGE_SIZE)
                avail_start = MP_TRAMPOLINE + PAGE_SIZE;
@@ -1360,7 +1361,7 @@
                        continue;
 
                /* Check and adjust our segment(s) */
-               /* Nuke page zero */
+               /* Nuke low pages */
                if (s1 < avail_start) {
                        s1 = avail_start;
                        if (s1 > e1)
Index: arch/amd64/amd64/mptramp.S
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/mptramp.S,v
retrieving revision 1.7
diff -a -u -r1.7 mptramp.S
--- arch/amd64/amd64/mptramp.S  13 Nov 2010 04:16:42 -0000      1.7
+++ arch/amd64/amd64/mptramp.S  3 Jan 2014 05:19:23 -0000
@@ -88,6 +88,7 @@
 #define RELOC(x)        _RELOC(_C_LABEL(x))
 
 #define _TRMP_LABEL(a)  a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE
+#define _TRMP_OFFSET(a)  a = . - _C_LABEL(cpu_spinup_trampoline)
 
        .globl  _C_LABEL(mpidle)
        .global _C_LABEL(cpu_spinup_trampoline)
@@ -105,7 +106,7 @@
        .code16
 _C_LABEL(cpu_spinup_trampoline):
        cli
-       xorw    %ax,%ax
+       movw    %cs, %ax
        movw    %ax, %ds
        movw    %ax, %es
        movw    %ax, %ss
@@ -182,7 +183,7 @@
        .quad 0x0000000000000000
        .quad 0x00cf9f000000ffff
        .quad 0x00cf93000000ffff
-_TRMP_LABEL(mptramp_gdt32_desc)
+_TRMP_OFFSET(mptramp_gdt32_desc)
        .word 0x17
        .long mptramp_gdt32
 
Index: arch/amd64/include/hibernate_var.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/hibernate_var.h,v
retrieving revision 1.6
diff -a -u -r1.6 hibernate_var.h
--- arch/amd64/include/hibernate_var.h  4 Jun 2013 16:21:23 -0000       1.6
+++ arch/amd64/include/hibernate_var.h  26 Dec 2013 17:36:18 -0000
@@ -27,41 +27,41 @@
 /*
  * PML4 table for resume
  */
-#define HIBERNATE_PML4T                (PAGE_SIZE * 5)
+#define HIBERNATE_PML4T                (PAGE_SIZE * 18)
 
 /*
  * amd64 uses a PDPT to map the first 512GB phys mem plus one more
  * to map any ranges of phys mem past 512GB (if needed)
  */
-#define HIBERNATE_PDPT_LOW     (PAGE_SIZE * 6)
-#define HIBERNATE_PDPT_HI      (PAGE_SIZE * 7)
+#define HIBERNATE_PDPT_LOW     (PAGE_SIZE * 19)
+#define HIBERNATE_PDPT_HI      (PAGE_SIZE * 20)
 
 /*
  * amd64 uses one PD to map the first 1GB phys mem plus one more to map any
  * other 1GB ranges within the first 512GB phys, plus one more to map any
  * 1GB range in any subsequent 512GB range
  */
-#define HIBERNATE_PD_LOW       (PAGE_SIZE * 8)
-#define HIBERNATE_PD_LOW2      (PAGE_SIZE * 9)
-#define HIBERNATE_PD_HI                (PAGE_SIZE * 10)
+#define HIBERNATE_PD_LOW       (PAGE_SIZE * 21)
+#define HIBERNATE_PD_LOW2      (PAGE_SIZE * 22)
+#define HIBERNATE_PD_HI                (PAGE_SIZE * 23)
 
 /*
  * amd64 uses one PT to map the first 2MB phys mem plus one more to map any
  * other 2MB range within the first 1GB, plus one more to map any 2MB range
  * in any subsequent 512GB range.
  */
-#define HIBERNATE_PT_LOW       (PAGE_SIZE * 11)
-#define HIBERNATE_PT_LOW2      (PAGE_SIZE * 12)
-#define HIBERNATE_PT_HI                (PAGE_SIZE * 13)
+#define HIBERNATE_PT_LOW       (PAGE_SIZE * 24)
+#define HIBERNATE_PT_LOW2      (PAGE_SIZE * 25)
+#define HIBERNATE_PT_HI                (PAGE_SIZE * 26)
 
-#define HIBERNATE_SELTABLE     (PAGE_SIZE * 14)
+#define HIBERNATE_SELTABLE     (PAGE_SIZE * 27)
 
 /* 3 pages for stack */
-#define HIBERNATE_STACK_PAGE   (PAGE_SIZE * 17)
+#define HIBERNATE_STACK_PAGE   (PAGE_SIZE * 30)
 
-#define HIBERNATE_INFLATE_PAGE (PAGE_SIZE * 18)
+#define HIBERNATE_INFLATE_PAGE (PAGE_SIZE * 31)
 /* HIBERNATE_HIBALLOC_PAGE must be the last stolen page (see machdep.c) */
-#define HIBERNATE_HIBALLOC_PAGE (PAGE_SIZE * 19)
+#define HIBERNATE_HIBALLOC_PAGE (PAGE_SIZE * 32)
 
 /* Use 4MB hibernation chunks */
 #define HIBERNATE_CHUNK_SIZE           0x400000
Index: arch/amd64/include/mpbiosvar.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/mpbiosvar.h,v
retrieving revision 1.4
diff -a -u -r1.4 mpbiosvar.h
--- arch/amd64/include/mpbiosvar.h      23 Mar 2011 16:54:34 -0000      1.4
+++ arch/amd64/include/mpbiosvar.h      26 Dec 2013 17:26:16 -0000
@@ -36,7 +36,7 @@
 #ifndef _MACHINE_MPBIOSVAR_H_
 #define _MACHINE_MPBIOSVAR_H_
 
-#define MP_TRAMPOLINE  (2 * PAGE_SIZE)
+#define MP_TRAMPOLINE  (16 * PAGE_SIZE)
 
 #if !defined(_LOCORE)
 
Index: arch/i386/i386/acpi_wakecode.S
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/acpi_wakecode.S,v
retrieving revision 1.19
diff -a -u -r1.19 acpi_wakecode.S
--- arch/i386/i386/acpi_wakecode.S      18 Oct 2013 15:07:59 -0000      1.19
+++ arch/i386/i386/acpi_wakecode.S      4 Jan 2014 18:56:42 -0000
@@ -70,7 +70,7 @@
  *
  * We wakeup in real mode, at some phys addr based on the ACPI
  * specification (cs = phys>>8, ip = phys & 0xF). For example,
- * if our phys addr is 0x4000, we'd have cs=0x0400,ip=0
+ * if our phys addr is 0x11000, we'd have cs=0x1100,ip=0
  *
  * The wakeup code needs to do the following:
  *     1. Reenable the video display
@@ -356,7 +356,7 @@
        movl    %eax, %cr3
 
        /* Set up real mode segment selectors */
-       movw    $0x0400, %ax
+       movw    $0x1100, %ax
        movw    %ax, %ds
        movw    %ax, %es
        movw    %ax, %fs
@@ -365,7 +365,7 @@
        lidtl   clean_idt
 
        /* Jump to the S3 resume vector */
-       ljmp    $0x0400, $acpi_s3_vector_real
+       ljmp    $0x1100, $acpi_s3_vector_real
 
        .code32
        /* Switch to hibernate resume pagetable */
Index: arch/i386/i386/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.530
diff -a -u -r1.530 machdep.c
--- arch/i386/i386/machdep.c    27 Dec 2013 21:40:57 -0000      1.530
+++ arch/i386/i386/machdep.c    4 Jan 2014 19:26:22 -0000
@@ -165,6 +165,11 @@
 #include <dev/ic/comvar.h>
 #endif /* NCOM > 0 */
 
+#ifdef HIBERNATE
+#include <machine/hibernate_var.h>
+#endif /* HIBERNATE */
+
+
 void   replacesmap(void);
 int     intr_handler(struct intrframe *, struct intrhand *);
 
@@ -3223,6 +3228,24 @@
                        /* skip first 16 pages due to SMI corruption */
                        if (a < 16 * NBPG)
                                a = 16 * NBPG;
+
+#ifdef MULTIPROCESSOR
+                       /* skip MP trampoline code page */
+                       if (a < MP_TRAMPOLINE + NBPG)
+                               a = MP_TRAMPOLINE + NBPG;
+#endif /* MULTIPROCESSOR */
+
+#if NACPI > 0 && !defined(SMALL_KERNEL)
+                       /* skip ACPI resume trampoline code page */
+                       if (a < ACPI_TRAMPOLINE + NBPG)
+                               a = ACPI_TRAMPOLINE + NBPG;
+#endif /* ACPI */
+
+#ifdef HIBERNATE
+                       /* skip hibernate reserved pages */
+                       if (a < HIBERNATE_HIBALLOC_PAGE + PAGE_SIZE)
+                               a = HIBERNATE_HIBALLOC_PAGE + PAGE_SIZE;
+#endif /* HIBERNATE */
 
                        /* skip shorter than page regions */
                        if (a >= e || (e - a) < NBPG) {
Index: arch/i386/i386/mptramp.s
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/mptramp.s,v
retrieving revision 1.13
diff -a -u -r1.13 mptramp.s
--- arch/i386/i386/mptramp.s    1 Apr 2010 19:48:50 -0000       1.13
+++ arch/i386/i386/mptramp.s    4 Jan 2014 19:31:43 -0000
@@ -89,6 +89,7 @@
 #define RELOC(x)       _RELOC(_C_LABEL(x))
 
 #define _TRMP_LABEL(a)  a = . - _C_LABEL(cpu_spinup_trampoline) + MP_TRAMPOLINE
+#define _TRMP_OFFSET(a)  a = . - _C_LABEL(cpu_spinup_trampoline)
 
 /*
  * Debug code to stop aux. processors in various stages based on the
@@ -122,7 +123,7 @@
        .code16
 _C_LABEL(cpu_spinup_trampoline):
        cli
-       xorw    %ax, %ax
+       movw    %cs, %ax
        movw    %ax, %ds
        movw    %ax, %es
        movw    %ax, %ss
@@ -130,7 +131,7 @@
        movl    %cr0, %eax      # get cr0
        orl     $0x1, %eax      # enable protected mode
        movl    %eax, %cr0      # doit
-       ljmp    $0x8, $mp_startup
+       ljmpl   $0x8, $mp_startup
 
 _TRMP_LABEL(mp_startup)
        .code32
@@ -213,7 +214,7 @@
        .word   0x0,0x0,0x0,0x0                 # null GDTE
         GDTE(0x9f,0xcf)                        # Kernel text
         GDTE(0x93,0xcf)                        # Kernel data
-_TRMP_LABEL(gdt_desc)
+_TRMP_OFFSET(gdt_desc)
        .word   0x17                            # limit 3 entries
        .long   gdt_table                       # where is gdt
 
Index: arch/i386/include/hibernate_var.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/hibernate_var.h,v
retrieving revision 1.8
diff -a -u -r1.8 hibernate_var.h
--- arch/i386/include/hibernate_var.h   4 Jun 2013 16:21:24 -0000       1.8
+++ arch/i386/include/hibernate_var.h   4 Jan 2014 19:51:24 -0000
@@ -24,11 +24,13 @@
 
 #define PIGLET_PAGE_MASK ~((paddr_t)PAGE_MASK_4M)
 
-#define HIBERNATE_PD_PAGE      (PAGE_SIZE * 5)
-#define HIBERNATE_PT_PAGE      (PAGE_SIZE * 6)
-#define HIBERNATE_STACK_PAGE   (PAGE_SIZE * 8)
-#define HIBERNATE_INFLATE_PAGE (PAGE_SIZE * 9)
-#define HIBERNATE_HIBALLOC_PAGE (PAGE_SIZE * 10)
+#define HIBERNATE_PD_PAGE      (PAGE_SIZE * 18)
+#define HIBERNATE_PT_PAGE      (PAGE_SIZE * 19)
+/* 2 pages for stack */
+#define HIBERNATE_STACK_PAGE   (PAGE_SIZE * 21)
+#define HIBERNATE_INFLATE_PAGE (PAGE_SIZE * 22)
+/* HIBERNATE_HIBALLOC_PAGE must be the last stolen page (see machdep.c) */
+#define HIBERNATE_HIBALLOC_PAGE (PAGE_SIZE * 23)
 
 /* Use 4MB hibernation chunks */
 #define HIBERNATE_CHUNK_SIZE           0x400000
Index: arch/i386/include/mpbiosvar.h
===================================================================
RCS file: /cvs/src/sys/arch/i386/include/mpbiosvar.h,v
retrieving revision 1.10
diff -a -u -r1.10 mpbiosvar.h
--- arch/i386/include/mpbiosvar.h       21 Oct 2011 18:16:13 -0000      1.10
+++ arch/i386/include/mpbiosvar.h       4 Jan 2014 19:21:29 -0000
@@ -36,7 +36,7 @@
 #ifndef _MACHINE_MPBIOSVAR_H_
 #define _MACHINE_MPBIOSVAR_H_
 
-#define MP_TRAMPOLINE  (7 * PAGE_SIZE)
+#define MP_TRAMPOLINE  (16 * PAGE_SIZE)
 
 #if !defined(_LOCORE)
 
Index: dev/acpi/acpivar.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.76
diff -a -u -r1.76 acpivar.h
--- dev/acpi/acpivar.h  6 Nov 2013 10:40:36 -0000       1.76
+++ dev/acpi/acpivar.h  26 Dec 2013 17:33:26 -0000
@@ -18,7 +18,7 @@
 #ifndef _DEV_ACPI_ACPIVAR_H_
 #define _DEV_ACPI_ACPIVAR_H_
 
-#define ACPI_TRAMPOLINE                (NBPG*4)
+#define ACPI_TRAMPOLINE                (17 * NBPG)
 
 #ifndef _ACPI_WAKECODE
 

Reply via email to