Print this page
de-linting of .s files
m


  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2019 Joyent, Inc.
  24  */
  25 
  26 #include <sys/asm_linkage.h>
  27 #include <sys/asm_misc.h>
  28 #include <sys/regset.h>
  29 #include <sys/privregs.h>
  30 #include <sys/x86_archext.h>
  31 #include <sys/cpr_wakecode.h>
  32 
  33 #if !defined(__lint)
  34 #include <sys/segments.h>
  35 #include "assym.h"
  36 #endif
  37 
  38 #ifdef  DEBUG
  39 #define LED     1
  40 #define SERIAL  1
  41 #endif  /*      DEBUG   */
  42 
  43 #ifdef  DEBUG
  44 #define COM1    0x3f8
  45 #define COM2    0x2f8
  46 #define WC_COM  COM2    /* either COM1 or COM2                  */
  47 #define WC_LED  0x80    /* diagnostic led port ON motherboard   */
  48 
  49 /*
  50  * defined as offsets from the data register
  51  */
  52 #define DLL     0       /* divisor latch (lsb) */
  53 #define DLH     1       /* divisor latch (msb) */
  54 #define LCR     3       /* line control register                */
  55 #define MCR     4       /* modem control register               */
  56 


  59 #define B9600L  0X0c    /* lsb bit pattern for 9600 baud        */
  60 #define B9600H  0X0     /* hsb bit pattern for 9600 baud        */
  61 #define DTR     0x01    /* Data Terminal Ready                  */
  62 #define RTS     0x02    /* Request To Send                      */
  63 #define STOP1   0x00    /* 1 stop bit                           */
  64 #define BITS8   0x03    /* 8 bits per char                      */
  65 
  66 #endif  /*      DEBUG   */
  67 
  68 /*
  69  *      This file contains the low level routines involved in getting
  70  *      into and out of ACPI S3, including those needed for restarting
  71  *      the non-boot cpus.
  72  *
  73  *      Our assumptions:
  74  *
  75  *      Our actions:
  76  *
  77  */
  78 
  79 #if defined(lint) || defined(__lint)
  80 
  81 /*ARGSUSED*/
  82 int
  83 wc_save_context(wc_cpu_t *pcpu)
  84 { return 0; }
  85 
  86 #else   /* lint */
  87 
  88 #if defined(__amd64)
  89 
  90         ENTRY_NP(wc_save_context)
  91 
  92         movq    (%rsp), %rdx            / return address
  93         movq    %rdx, WC_RETADDR(%rdi)
  94         pushq   %rbp
  95         movq    %rsp,%rbp
  96 
  97         movq    %rdi, WC_VIRTADDR(%rdi)
  98         movq    %rdi, WC_RDI(%rdi)
  99 
 100         movq    %rdx, WC_RDX(%rdi)
 101 
 102 / stash everything else we need
 103         sgdt    WC_GDT(%rdi)
 104         sidt    WC_IDT(%rdi)
 105         sldt    WC_LDT(%rdi)
 106         str     WC_TR(%rdi)
 107 
 108         movq    %cr0, %rdx
 109         movq    %rdx, WC_CR0(%rdi)


 157         movl    %eax, WC_KGSBASE(%rdi)
 158         movl    %edx, WC_KGSBASE+4(%rdi)
 159 
 160         movq    %gs:CPU_ID, %rax        / save current cpu id
 161         movq    %rax, WC_CPU_ID(%rdi)
 162 
 163         pushfq
 164         popq    WC_EFLAGS(%rdi)
 165 
 166         wbinvd                          / flush the cache
 167         mfence
 168 
 169         movq    $1, %rax                / at suspend return 1
 170 
 171         leave
 172 
 173         ret
 174 
 175         SET_SIZE(wc_save_context)
 176 
 177 #elif defined(__i386)
 178 
 179         ENTRY_NP(wc_save_context)
 180 
 181         movl    4(%esp), %eax           / wc_cpu_t *
 182         movl    %eax, WC_VIRTADDR(%eax)
 183 
 184         movl    (%esp), %edx            / return address
 185         movl    %edx, WC_RETADDR(%eax)
 186 
 187         str     WC_TR(%eax)             / stash everything else we need
 188         sgdt    WC_GDT(%eax)
 189         sldt    WC_LDT(%eax)
 190         sidt    WC_IDT(%eax)
 191 
 192         movl    %cr0, %edx
 193         movl    %edx, WC_CR0(%eax)
 194         movl    %cr3, %edx
 195         movl    %edx, WC_CR3(%eax)
 196         movl    %cr4, %edx
 197         movl    %edx, WC_CR4(%eax)
 198 
 199         movl    %ebx, WC_EBX(%eax)
 200         movl    %edi, WC_EDI(%eax)
 201         movl    %esi, WC_ESI(%eax)
 202         movl    %ebp, WC_EBP(%eax)
 203         movl    %esp, WC_ESP(%eax)
 204 
 205         movw    %ss, WC_SS(%eax)
 206         movw    %cs, WC_CS(%eax)
 207         movw    %ds, WC_DS(%eax)
 208         movw    %es, WC_ES(%eax)
 209         movw    %fs, WC_FS(%eax)
 210         movw    %gs, WC_GS(%eax)
 211 
 212         pushfl
 213         popl    WC_EFLAGS(%eax)
 214 
 215         pushl   %gs:CPU_ID              / save current cpu id
 216         popl    WC_CPU_ID(%eax)
 217 
 218         wbinvd                          / flush the cache
 219         mfence
 220 
 221         movl    $1, %eax                / at suspend return 1
 222         ret
 223 
 224         SET_SIZE(wc_save_context)
 225 
 226 #endif  /* __amd64 */
 227 
 228 #endif /* lint */
 229 
 230 
 231 /*
 232  *      Our assumptions:
 233  *              - We are running in real mode.
 234  *              - Interrupts are disabled.
 235  *
 236  *      Our actions:
 237  *              - We start using our GDT by loading correct values in the
 238  *                selector registers (cs=KCS_SEL, ds=es=ss=KDS_SEL, fs=KFS_SEL,
 239  *                gs=KGS_SEL).
 240  *              - We change over to using our IDT.
 241  *              - We load the default LDT into the hardware LDT register.
 242  *              - We load the default TSS into the hardware task register.
 243  *              - We restore registers
 244  *              - We return to original caller (a la setjmp)
 245  */
 246 
 247 #if defined(lint) || defined(__lint)
 248 
 249 void
 250 wc_rm_start(void)
 251 {}
 252 
 253 void
 254 wc_rm_end(void)
 255 {}
 256 
 257 #else   /* lint */
 258 
 259 #if defined(__amd64)
 260 
 261         ENTRY_NP(wc_rm_start)
 262 
 263         /*
 264          * For the Sun Studio 10 assembler we needed to do a .code32 and
 265          * mentally invert the meaning of the addr16 and data16 prefixes to
 266          * get 32-bit access when generating code to be executed in 16-bit
 267          * mode (sigh...)
 268          *
 269          * This code, despite always being built with GNU as, has inherited
 270          * the conceptual damage.
 271          */
 272 
 273         .code32
 274 
 275         cli
 276         movw            %cs, %ax
 277         movw            %ax, %ds                / establish ds ...
 278         movw            %ax, %ss                / ... and ss:esp
 279         D16 movl        $WC_STKSTART, %esp
 280 / using the following value blows up machines! - DO NOT USE


 854         movq    WC_RETADDR(%rax), %rax
 855         movq    %rax, (%rsp)            / return to caller of wc_save_context
 856 
 857         xorl    %eax, %eax                      / at wakeup return 0
 858         ret
 859 
 860 
 861         SET_SIZE(wc_rm_start)
 862 
 863         ENTRY_NP(asmspin)
 864 
 865         movl    %edi, %ecx
 866 A1:
 867         loop    A1
 868 
 869         SET_SIZE(asmspin)
 870 
 871         .globl wc_rm_end
 872 wc_rm_end:
 873         nop
 874 
 875 #elif defined(__i386)
 876 
 877         ENTRY_NP(wc_rm_start)
 878 
 879 /entry: jmp             entry                   / stop here for HDT
 880 
 881         cli
 882         movw            %cs, %ax
 883         movw            %ax, %ds                / establish ds ...
 884         movw            %ax, %ss                / ... and ss:esp
 885         D16 movl        $WC_STKSTART, %esp
 886 
 887 #if     LED
 888         D16 movl        $WC_LED, %edx
 889         D16 movb        $0xd1, %al
 890         outb    (%dx)
 891 #endif
 892 
 893 #if     SERIAL
 894         D16 movl        $WC_COM, %edx
 895         D16 movb        $0x61, %al
 896         outb    (%dx)
 897 #endif
 898 
 899 
 900         D16 call        vgainit
 901         D16 call        kbdinit
 902         D16 call        cominit
 903 
 904 #if     LED
 905         D16 movl        $WC_LED, %edx
 906         D16 movb        $0xd2, %al
 907         outb    (%dx)
 908 #endif
 909 
 910 #if     SERIAL
 911         D16 movl        $WC_COM, %edx
 912         D16 movb        $0x62, %al
 913         outb    (%dx)
 914 #endif
 915 
 916         D16 A16 movl    $WC_CPU, %ebx           / base add of wc_cpu_t
 917 
 918 #if     LED
 919         D16 movb        $0xd3, %al
 920         outb    $WC_LED
 921 #endif
 922 
 923 #if     SERIAL
 924         D16 movl        $WC_COM, %edx
 925         D16 movb        $0x63, %al
 926         outb    (%dx)
 927 #endif
 928 
 929         D16 A16 movl    %cs:WC_DS(%ebx), %edx   / %ds post prot/paging transit
 930 
 931 #if     LED
 932         D16 movb        $0xd4, %al
 933         outb    $WC_LED
 934 #endif
 935 
 936         D16 A16 lgdt    %cs:WC_GDT(%ebx)        / restore gdt and idtr
 937         D16 A16 lidt    %cs:WC_IDT(%ebx)
 938 
 939 #if     LED
 940         D16 movb        $0xd5, %al
 941         outb    $WC_LED
 942 #endif
 943 
 944         D16 A16 movl    %cs:WC_CR4(%ebx), %eax  / restore cr4
 945         D16 andl        $_BITNOT(CR4_PGE), %eax / don't set Global Enable yet
 946         movl            %eax, %cr4
 947 
 948 #if     LED
 949         D16 movb        $0xd6, %al
 950         outb    $WC_LED
 951 #endif
 952 
 953         D16 A16 movl    %cs:WC_CR3(%ebx), %eax  / set PDPT
 954         movl            %eax, %cr3
 955 
 956 #if     LED
 957         D16 movb        $0xd7, %al
 958         outb    $WC_LED
 959 #endif
 960 
 961         D16 A16 movl    %cs:WC_CR0(%ebx), %eax  / enable prot/paging, etc.
 962         movl            %eax, %cr0
 963 
 964 #if     LED
 965         D16 movb        $0xd8, %al
 966         outb    $WC_LED
 967 #endif
 968 
 969         D16 A16 movl    %cs:WC_VIRTADDR(%ebx), %ebx     / virtaddr of wc_cpu_t
 970 
 971 #if     LED
 972         D16 movb        $0xd9, %al
 973         outb    $WC_LED
 974 #endif
 975 
 976 #if     LED
 977         D16 movb        $0xda, %al
 978         outb    $WC_LED
 979 #endif
 980 
 981         jmp             flush                   / flush prefetch queue
 982 flush:
 983         D16 pushl       $KCS_SEL
 984         D16 pushl       $kernel_wc_code
 985         D16 lret                                / re-appear at kernel_wc_code
 986 
 987 
 988 /*
 989  * Support routine to re-initialize VGA subsystem
 990  */
 991 vgainit:
 992         D16 ret
 993 
 994 /*
 995  * Support routine to re-initialize keyboard (which is USB - help!)
 996  */
 997 kbdinit:
 998         D16 ret
 999 
1000 /*
1001  * Support routine to re-initialize COM ports to something sane for debug output
1002  */
1003 cominit:
1004 #if     DEBUG
1005 /*
1006  * on debug kernels we need to initialize COM1 & COM2 here, so that
1007  * we can get debug output before the asy driver has resumed
1008  */
1009 
1010 / select COM1
1011         D16 movl        $_CONST(COM1+LCR), %edx
1012         D16 movb        $DLAB, %al              / divisor latch
1013         outb    (%dx)
1014 
1015         D16 movl        $_CONST(COM1+DLL), %edx / divisor latch lsb
1016         D16 movb        $B9600L, %al            / divisor latch
1017         outb    (%dx)
1018 
1019         D16 movl        $_CONST(COM1+DLH), %edx / divisor latch hsb
1020         D16 movb        $B9600H, %al            / divisor latch
1021         outb    (%dx)
1022 
1023         D16 movl        $_CONST(COM1+LCR), %edx / select COM1
1024         D16 movb        $_CONST(STOP1|BITS8), %al       / 1 stop bit, 8bit word len
1025         outb    (%dx)
1026 
1027         D16 movl        $_CONST(COM1+MCR), %edx / select COM1
1028         D16 movb        $_CONST(RTS|DTR), %al           / 1 stop bit, 8bit word len
1029         outb    (%dx)
1030 
1031 / select COM2
1032         D16 movl        $_CONST(COM2+LCR), %edx
1033         D16 movb        $DLAB, %al              / divisor latch
1034         outb    (%dx)
1035 
1036         D16 movl        $_CONST(COM2+DLL), %edx / divisor latch lsb
1037         D16 movb        $B9600L, %al            / divisor latch
1038         outb    (%dx)
1039 
1040         D16 movl        $_CONST(COM2+DLH), %edx / divisor latch hsb
1041         D16 movb        $B9600H, %al            / divisor latch
1042         outb    (%dx)
1043 
1044         D16 movl        $_CONST(COM2+LCR), %edx / select COM1
1045         D16 movb        $_CONST(STOP1|BITS8), %al       / 1 stop bit, 8bit word len
1046         outb    (%dx)
1047 
1048         D16 movl        $_CONST(COM2+MCR), %edx / select COM1
1049         D16 movb        $_CONST(RTS|DTR), %al           / 1 stop bit, 8bit word len
1050         outb    (%dx)
1051 #endif  /*      DEBUG   */
1052 
1053         D16 ret
1054 
1055         .globl wc_rm_end
1056 wc_rm_end:
1057         nop
1058 
1059         .globl  kernel_wc_code
1060 kernel_wc_code:
1061         / At this point we are with kernel's cs and proper eip.
1062         / We will be executing not from the copy in real mode platter,
1063         / but from the original code where boot loaded us.
1064         / By this time GDT and IDT are loaded as is cr0, cr3 and cr4.
1065         / %ebx is wc_cpu
1066         / %dx is our ds
1067 
1068 #if     LED
1069         D16 movb        $0xdb, %al
1070         outb    $WC_LED
1071 #endif
1072 
1073 / got here OK
1074 
1075         movw    %dx, %ds                / $KDS_SEL
1076 
1077 #if     LED
1078         movb    $0xdc, %al
1079         outb    $WC_LED
1080 #endif
1081 
1082         /*
1083          * Before proceeding, enable usage of the page table NX bit if
1084          * that's how the page tables are set up.
1085          */
1086         bt      $X86FSET_NX, x86_featureset
1087         jnc     1f
1088         movl    $MSR_AMD_EFER, %ecx
1089         rdmsr
1090         orl     $AMD_EFER_NXE, %eax
1091         wrmsr
1092 1:
1093 
1094         movl    WC_CR4(%ebx), %eax      / restore full cr4 (with Global Enable)
1095         movl    %eax, %cr4
1096 
1097 
1098         lldt    WC_LDT(%ebx)            / $LDT_SEL
1099 
1100         movzwl  WC_TR(%ebx), %eax       / clear TSS busy bit
1101         addl    WC_GDT+2(%ebx), %eax
1102         andl    $_BITNOT(0x200), 4(%eax)
1103         ltr     WC_TR(%ebx)             / $UTSS_SEL
1104 
1105         movw    WC_SS(%ebx), %ss        / restore segment registers
1106         movw    WC_ES(%ebx), %es
1107         movw    WC_FS(%ebx), %fs
1108         movw    WC_GS(%ebx), %gs
1109 
1110         /*
1111          * set the stack pointer to point into the identity mapped page
1112          * temporarily, so we can make function calls
1113          */
1114         .globl  rm_platter_va
1115         movl    rm_platter_va, %eax
1116         movl    $WC_STKSTART, %esp
1117         addl    %eax, %esp
1118         movl    %esp, %ebp
1119 
1120         /*
1121          * if we are not running on the boot CPU restore stack contents by
1122          * calling i_cpr_restore_stack(curthread, save_stack);
1123          */
1124         call    i_cpr_bootcpuid
1125         cmpl    %eax, WC_CPU_ID(%ebx)
1126         je      2f
1127 
1128         pushl   WC_SAVED_STACK(%ebx)
1129         pushl   %gs:CPU_THREAD
1130         call    i_cpr_restore_stack
1131         addl    $0x10, %esp
1132 2:
1133 
1134         movl    WC_ESP(%ebx), %esp
1135         movl    %esp, %ebp
1136 
1137         movl    WC_RETADDR(%ebx), %eax  / return to caller of wc_save_context
1138         movl    %eax, (%esp)
1139 
1140         /*
1141          * APIC initialization, skip iff function pointer is NULL
1142          */
1143         cmpl    $0, ap_mlsetup
1144         je      3f
1145         call    *ap_mlsetup
1146 3:
1147 
1148         call    *cpr_start_cpu_func
1149 
1150         pushl   WC_EFLAGS(%ebx)         / restore flags
1151         popfl
1152 
1153         movl    WC_EDI(%ebx), %edi      / restore general registers
1154         movl    WC_ESI(%ebx), %esi
1155         movl    WC_EBP(%ebx), %ebp
1156         movl    WC_EBX(%ebx), %ebx
1157 
1158 /exit:  jmp     exit                    / stop here for HDT
1159 
1160         xorl    %eax, %eax              / at wakeup return 0
1161         ret
1162 
1163         SET_SIZE(wc_rm_start)
1164 
1165 
1166 #endif  /* defined(__amd64) */
1167 
1168 #endif /* lint */
1169 


  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2019 Joyent, Inc.
  24  */
  25 
  26 #include <sys/asm_linkage.h>
  27 #include <sys/asm_misc.h>
  28 #include <sys/regset.h>
  29 #include <sys/privregs.h>
  30 #include <sys/x86_archext.h>
  31 #include <sys/cpr_wakecode.h>
  32 

  33 #include <sys/segments.h>
  34 #include "assym.h"

  35 
  36 #ifdef  DEBUG
  37 #define LED     1
  38 #define SERIAL  1
  39 #endif  /*      DEBUG   */
  40 
  41 #ifdef  DEBUG
  42 #define COM1    0x3f8
  43 #define COM2    0x2f8
  44 #define WC_COM  COM2    /* either COM1 or COM2                  */
  45 #define WC_LED  0x80    /* diagnostic led port ON motherboard   */
  46 
  47 /*
  48  * defined as offsets from the data register
  49  */
  50 #define DLL     0       /* divisor latch (lsb) */
  51 #define DLH     1       /* divisor latch (msb) */
  52 #define LCR     3       /* line control register                */
  53 #define MCR     4       /* modem control register               */
  54 


  57 #define B9600L  0X0c    /* lsb bit pattern for 9600 baud        */
  58 #define B9600H  0X0     /* hsb bit pattern for 9600 baud        */
  59 #define DTR     0x01    /* Data Terminal Ready                  */
  60 #define RTS     0x02    /* Request To Send                      */
  61 #define STOP1   0x00    /* 1 stop bit                           */
  62 #define BITS8   0x03    /* 8 bits per char                      */
  63 
  64 #endif  /*      DEBUG   */
  65 
  66 /*
  67  *      This file contains the low level routines involved in getting
  68  *      into and out of ACPI S3, including those needed for restarting
  69  *      the non-boot cpus.
  70  *
  71  *      Our assumptions:
  72  *
  73  *      Our actions:
  74  *
  75  */
  76 











  77         ENTRY_NP(wc_save_context)
  78 
  79         movq    (%rsp), %rdx            / return address
  80         movq    %rdx, WC_RETADDR(%rdi)
  81         pushq   %rbp
  82         movq    %rsp,%rbp
  83 
  84         movq    %rdi, WC_VIRTADDR(%rdi)
  85         movq    %rdi, WC_RDI(%rdi)
  86 
  87         movq    %rdx, WC_RDX(%rdi)
  88 
  89 / stash everything else we need
  90         sgdt    WC_GDT(%rdi)
  91         sidt    WC_IDT(%rdi)
  92         sldt    WC_LDT(%rdi)
  93         str     WC_TR(%rdi)
  94 
  95         movq    %cr0, %rdx
  96         movq    %rdx, WC_CR0(%rdi)


 144         movl    %eax, WC_KGSBASE(%rdi)
 145         movl    %edx, WC_KGSBASE+4(%rdi)
 146 
 147         movq    %gs:CPU_ID, %rax        / save current cpu id
 148         movq    %rax, WC_CPU_ID(%rdi)
 149 
 150         pushfq
 151         popq    WC_EFLAGS(%rdi)
 152 
 153         wbinvd                          / flush the cache
 154         mfence
 155 
 156         movq    $1, %rax                / at suspend return 1
 157 
 158         leave
 159 
 160         ret
 161 
 162         SET_SIZE(wc_save_context)
 163 

 164 




















































 165 /*
 166  *      Our assumptions:
 167  *              - We are running in real mode.
 168  *              - Interrupts are disabled.
 169  *
 170  *      Our actions:
 171  *              - We start using our GDT by loading correct values in the
 172  *                selector registers (cs=KCS_SEL, ds=es=ss=KDS_SEL, fs=KFS_SEL,
 173  *                gs=KGS_SEL).
 174  *              - We change over to using our IDT.
 175  *              - We load the default LDT into the hardware LDT register.
 176  *              - We load the default TSS into the hardware task register.
 177  *              - We restore registers
 178  *              - We return to original caller (a la setjmp)
 179  */
 180 














 181         ENTRY_NP(wc_rm_start)
 182 
 183         /*
 184          * For the Sun Studio 10 assembler we needed to do a .code32 and
 185          * mentally invert the meaning of the addr16 and data16 prefixes to
 186          * get 32-bit access when generating code to be executed in 16-bit
 187          * mode (sigh...)
 188          *
 189          * This code, despite always being built with GNU as, has inherited
 190          * the conceptual damage.
 191          */
 192 
 193         .code32
 194 
 195         cli
 196         movw            %cs, %ax
 197         movw            %ax, %ds                / establish ds ...
 198         movw            %ax, %ss                / ... and ss:esp
 199         D16 movl        $WC_STKSTART, %esp
 200 / using the following value blows up machines! - DO NOT USE


 774         movq    WC_RETADDR(%rax), %rax
 775         movq    %rax, (%rsp)            / return to caller of wc_save_context
 776 
 777         xorl    %eax, %eax                      / at wakeup return 0
 778         ret
 779 
 780 
 781         SET_SIZE(wc_rm_start)
 782 
 783         ENTRY_NP(asmspin)
 784 
 785         movl    %edi, %ecx
 786 A1:
 787         loop    A1
 788 
 789         SET_SIZE(asmspin)
 790 
 791         .globl wc_rm_end
 792 wc_rm_end:
 793         nop







































































































































































































































































































 794