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 / Inline functions specific to the i86pc kernel running on bare metal.
  29 /
  30 
  31 /
  32 / return value of cr3 register
  33 /
  34         .inline getcr3,0
  35         movl    %cr3, %eax
  36         .end
  37 
  38 /
  39 / reload cr3 register with its current value
  40 /
  41         .inline reload_cr3,0
  42         movl    %cr3, %eax
  43         movl    %eax, %cr3
  44         .end
  45 
  46 /*
  47  * Put a new value into cr3 (page table base register
  48  *      void setcr3(void *value)
  49  */
  50         .inline setcr3,4
  51         movl    (%esp), %eax
  52         movl    %eax, %cr3
  53         .end
  54 
  55 /
  56 / enable interrupts
  57 /
  58         .inline sti,0
  59         sti
  60         .end
  61 
  62 /
  63 / disable interrupts
  64 /
  65         .inline cli,0
  66         cli
  67         .end
  68 
  69 /
  70 / disable interrupts and return value describing if interrupts were enabled
  71 /
  72         .inline clear_int_flag,0
  73         pushfl
  74         cli
  75         popl    %eax
  76         .end
  77 
  78         .inline intr_clear,0
  79         pushfl
  80         cli
  81         popl    %eax
  82         .end
  83 
  84 /
  85 / return the flags register
  86 /
  87         .inline getflags,0
  88         pushfl
  89         popl    %eax
  90         .end
  91 
  92 /
  93 / restore interrupt enable flag to value returned from 'clear_int_flag' above
  94 /
  95         .inline restore_int_flag,4
  96         testl   $0x200, (%esp)
  97         jz      1f
  98         sti
  99 1:
 100         .end
 101 
 102         .inline intr_restore,4
 103         testl   $0x200, (%esp)
 104         jz      1f
 105         sti
 106 1:
 107         .end
 108 
 109 /
 110 / in and out
 111 /
 112         .inline inb,4
 113         movl    (%esp), %edx
 114         xorl    %eax, %eax
 115         inb     (%dx)
 116         .end
 117 
 118         .inline inw,4
 119         movl    (%esp), %edx
 120         xorl    %eax, %eax
 121         inw     (%dx)
 122         .end
 123 
 124         .inline inl,4
 125         movl    (%esp), %edx
 126         xorl    %eax, %eax
 127         inl     (%dx)
 128         .end
 129 
 130         .inline outb,8
 131         movl    (%esp), %edx
 132         movl    4(%esp), %eax
 133         outb    (%dx)
 134         .end
 135 
 136         .inline outw,8
 137         movl    (%esp), %edx
 138         movl    4(%esp), %eax
 139         outw    (%dx)
 140         .end
 141 
 142         .inline outl,8
 143         movl    (%esp), %edx
 144         movl    4(%esp), %eax
 145         outl    (%dx)
 146         .end
 147 
 148 /*
 149  * Invalidate TLB translation to 1 page.
 150  *      void mmu_tlbflush_entry(void *addr)
 151  */
 152         .inline mmu_tlbflush_entry,4
 153         movl    (%esp), %eax
 154         invlpg  (%eax)
 155         .end
 156 
 157 /*
 158  * Call the halt instruction. This will put the CPU to sleep until
 159  * it is again awoken via an interrupt.
 160  * This function should be called with interrupts already disabled
 161  * for the CPU.
 162  * Note that "sti" will only enable interrupts at the end of the
 163  * subsequent instruction...in this case: "hlt".
 164  */
 165         .inline i86_halt,0
 166         sti
 167         hlt
 168         .end
 169 
 170 /*
 171  * execute the bsrw instruction
 172  *      int bsrw_insn(uint16_t)
 173  */
 174         .inline bsrw_insn,4
 175         xorl    %eax, %eax
 176         movw    (%esp), %cx
 177         bsrw    %cx, %ax
 178         .end