1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  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 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 
  28 /
  29 / Inline functions specific to the i86pc kernel running on bare metal.
  30 /
  31 
  32 /
  33 / return value of cr3 register
  34 /
  35         .inline getcr3,0
  36         movq    %cr3, %rax
  37         .end
  38 
  39 /
  40 / reload cr3 register with its current value
  41 /
  42         .inline reload_cr3,0
  43         movq    %cr3, %rdi
  44         movq    %rdi, %cr3
  45         .end
  46 
  47 /
  48 / set cr3 register with new value
  49 /
  50         .inline setcr3,0
  51         movq    %rdi, %cr3
  52         .end
  53 
  54 /
  55 / return value of cr8 register
  56 /
  57         .inline getcr8,0
  58         movq    %cr8, %rax
  59         .end
  60 
  61 /
  62 / set cr8 register
  63 /
  64         .inline setcr8,0
  65         movq    %rdi, %cr8
  66         .end
  67 
  68 /
  69 / enable interrupts
  70 /
  71         .inline sti,0
  72         sti
  73         .end
  74 
  75 /
  76 / disable interrupts
  77 /
  78         .inline cli,0
  79         cli
  80         .end
  81 
  82 /
  83 / disable interrupts and return value describing if interrupts were enabled
  84 /
  85         .inline clear_int_flag,0
  86         pushfq
  87         cli
  88         popq    %rax
  89         .end
  90 
  91         .inline intr_clear,0
  92         pushfq
  93         cli
  94         popq    %rax
  95         .end
  96 
  97 /
  98 / return the value of the flags register
  99 /
 100         .inline getflags,0
 101         pushfq
 102         popq    %rax
 103         .end
 104 
 105 /
 106 / restore interrupt enable flag to value returned from 'clear_int_flag' above
 107 /
 108         .inline restore_int_flag,4
 109         testq   $0x200, %rdi
 110         jz      1f
 111         sti
 112 1:
 113         .end
 114 
 115         .inline intr_restore,4
 116         testq   $0x200, %rdi
 117         jz      1f
 118         sti
 119 1:
 120         .end
 121 
 122 /
 123 / in and out
 124 /
 125         .inline inb,4
 126         movq    %rdi, %rdx
 127         xorq    %rax, %rax
 128         inb     (%dx)
 129         .end
 130 
 131         .inline inw,4
 132         movq    %rdi, %rdx
 133         xorq    %rax, %rax
 134         inw     (%dx)
 135         .end
 136 
 137         .inline inl,4
 138         movq    %rdi, %rdx
 139         xorq    %rax, %rax
 140         inl     (%dx)
 141         .end
 142 
 143         .inline outb,8
 144         movq    %rdi, %rdx
 145         movq    %rsi, %rax
 146         outb    (%dx)
 147         .end
 148 
 149         .inline outw,8
 150         movq    %rdi, %rdx
 151         movq    %rsi, %rax
 152         outw    (%dx)
 153         .end
 154 
 155         .inline outl,8
 156         movq    %rdi, %rdx
 157         movq    %rsi, %rax
 158         outl    (%dx)
 159         .end
 160 
 161 /*
 162  * Call the halt instruction. This will put the CPU to sleep until
 163  * it is again awoken via an interrupt.
 164  * This function should be called with interrupts already disabled
 165  * for the CPU.
 166  * Note that "sti" will only enable interrupts at the end of the
 167  * subsequent instruction...in this case: "hlt".
 168  */
 169         .inline i86_halt,0
 170         sti
 171         hlt
 172         .end
 173 /
 174 / execute the bsrw instruction
 175 /
 176         .inline bsrw_insn,4
 177         xorl    %eax, %eax
 178         bsrw    %di, %ax
 179         .end