romutil.py revision 5911
13005Sstever@eecs.umich.edu# Copyright (c) 2008 The Regents of The University of Michigan 23005Sstever@eecs.umich.edu# All rights reserved. 33005Sstever@eecs.umich.edu# 43005Sstever@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 53005Sstever@eecs.umich.edu# modification, are permitted provided that the following conditions are 63005Sstever@eecs.umich.edu# met: redistributions of source code must retain the above copyright 73005Sstever@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 83005Sstever@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 93005Sstever@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 103005Sstever@eecs.umich.edu# documentation and/or other materials provided with the distribution; 113005Sstever@eecs.umich.edu# neither the name of the copyright holders nor the names of its 123005Sstever@eecs.umich.edu# contributors may be used to endorse or promote products derived from 133005Sstever@eecs.umich.edu# this software without specific prior written permission. 143005Sstever@eecs.umich.edu# 153005Sstever@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 163005Sstever@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 173005Sstever@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 183005Sstever@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 193005Sstever@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 203005Sstever@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 213005Sstever@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 223005Sstever@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 233005Sstever@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 243005Sstever@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 253005Sstever@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 263005Sstever@eecs.umich.edu# 273005Sstever@eecs.umich.edu# Authors: Gabe Black 283005Sstever@eecs.umich.edu 292889SN/AintCodeTemplate = ''' 302889SN/Adef rom 312710SN/A{ 322710SN/A # This vectors the CPU into an interrupt handler in long mode. 332934SN/A # On entry, t1 is set to the vector of the interrupt and t7 is the current 342934SN/A # ip. We need that because rdip returns the next ip. 352549SN/A extern %(startLabel)s: 362995SN/A 373395Shsul@eecs.umich.edu # 383448Shsul@eecs.umich.edu # Get the 64 bit interrupt or trap gate descriptor from the IDT 392549SN/A # 403088Sstever@eecs.umich.edu 413088Sstever@eecs.umich.edu # Load the gate descriptor from the IDT 423088Sstever@eecs.umich.edu slli t4, t1, 4, dataSize=8 433444Sktlim@umich.edu ld t2, idtr, [1, t0, t4], 8, dataSize=8, addressSize=8 443444Sktlim@umich.edu ld t4, idtr, [1, t0, t4], dataSize=8, addressSize=8 453444Sktlim@umich.edu 463444Sktlim@umich.edu # Make sure the descriptor is a legal gate. 472889SN/A chks t1, t4, %(gateCheckType)s 482710SN/A 493322Shsul@eecs.umich.edu # 503668Srdreslin@umich.edu # Get the target CS descriptor using the selector in the gate 512995SN/A # descriptor. 522995SN/A # 532995SN/A srli t10, t4, 16, dataSize=8 542995SN/A andi t5, t10, 0xF8, dataSize=8 552995SN/A andi t0, t10, 0x4, flags=(EZF,), dataSize=2 563143Shsul@eecs.umich.edu br rom_local_label("%(startLabel)s_globalDescriptor"), flags=(CEZF,) 573322Shsul@eecs.umich.edu ld t3, tsl, [1, t0, t5], dataSize=8, addressSize=8 583322Shsul@eecs.umich.edu br rom_local_label("%(startLabel)s_processDescriptor") 593025Ssaidi@eecs.umich.edu%(startLabel)s_globalDescriptor: 603143Shsul@eecs.umich.edu ld t3, tsg, [1, t0, t5], dataSize=8, addressSize=8 613143Shsul@eecs.umich.edu%(startLabel)s_processDescriptor: 623322Shsul@eecs.umich.edu chks t10, t3, IntCSCheck, dataSize=8 633444Sktlim@umich.edu wrdl hs, t3, t10, dataSize=8 643322Shsul@eecs.umich.edu 652710SN/A # Stick the target offset in t9. 662710SN/A wrdh t9, t4, t2, dataSize=8 672710SN/A 682710SN/A 692710SN/A # 702710SN/A # Figure out where the stack should be 713322Shsul@eecs.umich.edu # 723304Sstever@eecs.umich.edu 733322Shsul@eecs.umich.edu # Record what we might set the stack selector to. 743322Shsul@eecs.umich.edu rdsel t11, ss 753304Sstever@eecs.umich.edu 763481Shsul@eecs.umich.edu # Check if we're changing privelege level. At this point we can assume 773481Shsul@eecs.umich.edu # we're going to a DPL that's less than or equal to the CPL. 782566SN/A rdattr t10, hs, dataSize=8 793322Shsul@eecs.umich.edu srli t10, t10, 3, dataSize=8 803322Shsul@eecs.umich.edu andi t10, t10, 3, dataSize=8 812995SN/A rdattr t5, cs, dataSize=8 822995SN/A srli t5, t5, 3, dataSize=8 833304Sstever@eecs.umich.edu andi t5, t5, 0x3, dataSize=8 843304Sstever@eecs.umich.edu sub t0, t5, t10, flags=(EZF,), dataSize=8 853304Sstever@eecs.umich.edu # We're going to change priviledge, so zero out the stack selector. We 862995SN/A # need to let the IST have priority so we don't branch yet. 872995SN/A wrsel t11, t0, flags=(nCEZF,) 882995SN/A 892917SN/A # Check the IST field of the gate descriptor 902995SN/A srli t12, t4, 32, dataSize=8 913304Sstever@eecs.umich.edu andi t12, t12, 0x7, dataSize=8 922995SN/A subi t0, t12, 1, flags=(ECF,), dataSize=8 933304Sstever@eecs.umich.edu br rom_local_label("%(startLabel)s_istStackSwitch"), flags=(nCECF,) 943304Sstever@eecs.umich.edu br rom_local_label("%(startLabel)s_cplStackSwitch"), flags=(nCEZF,) 953819Shsul@eecs.umich.edu 963819Shsul@eecs.umich.edu # If we're here, it's because the stack isn't being switched. 973819Shsul@eecs.umich.edu # Set t6 to the new aligned rsp. 983819Shsul@eecs.umich.edu mov t6, t6, rsp, dataSize=8 993819Shsul@eecs.umich.edu br rom_local_label("%(startLabel)s_stackSwitched") 1003819Shsul@eecs.umich.edu 1013819Shsul@eecs.umich.edu%(startLabel)s_istStackSwitch: 1023312Sstever@eecs.umich.edu panic "IST based stack switching isn't implemented" 1033668Srdreslin@umich.edu br rom_local_label("%(startLabel)s_stackSwitched") 1043668Srdreslin@umich.edu 1053668Srdreslin@umich.edu%(startLabel)s_cplStackSwitch: 1063668Srdreslin@umich.edu # Get the new rsp from the TSS 1073668Srdreslin@umich.edu ld t6, tr, [8, t10, t0], 4, dataSize=8, addressSize=8 1083668Srdreslin@umich.edu 1093668Srdreslin@umich.edu%(startLabel)s_stackSwitched: 1103322Shsul@eecs.umich.edu 1113312Sstever@eecs.umich.edu andi t6, t6, 0xF0, dataSize=1 1123514Sktlim@umich.edu subi t6, t6, 40 + %(errorCodeSize)d, dataSize=8 1133395Shsul@eecs.umich.edu 1143448Shsul@eecs.umich.edu # Check that we can access everything we need to on the stack 1153668Srdreslin@umich.edu ldst t0, hs, [1, t0, t6], dataSize=8, addressSize=8 1163668Srdreslin@umich.edu ldst t0, hs, [1, t0, t6], \ 1173668Srdreslin@umich.edu 32 + %(errorCodeSize)d, dataSize=8, addressSize=8 1183668Srdreslin@umich.edu 1193668Srdreslin@umich.edu ## 1203005Sstever@eecs.umich.edu ## Point of no return. 1213005Sstever@eecs.umich.edu ## We're now going to irrevocably modify visible state. 1223819Shsul@eecs.umich.edu ## Anything bad that's going to happen should have happened by now or will 1233819Shsul@eecs.umich.edu ## happen right now. 1243819Shsul@eecs.umich.edu ## 1253819Shsul@eecs.umich.edu wrip t0, t9, dataSize=8 1263322Shsul@eecs.umich.edu 1273322Shsul@eecs.umich.edu # 1283322Shsul@eecs.umich.edu # Set up the target code segment. Do this now so we have the right 1293005Sstever@eecs.umich.edu # permissions when setting up the stack frame. 1303322Shsul@eecs.umich.edu # 1313005Sstever@eecs.umich.edu srli t5, t4, 16, dataSize=8 1323005Sstever@eecs.umich.edu andi t5, t5, 0xFF, dataSize=8 1333005Sstever@eecs.umich.edu wrdl cs, t3, t5, dataSize=8 1342566SN/A # Tuck away the old CS for use below 1353481Shsul@eecs.umich.edu limm t10, 0, dataSize=8 136 rdsel t10, cs, dataSize=2 137 wrsel cs, t5, dataSize=2 138 139 140 # 141 # Build up the interrupt stack frame 142 # 143 144 145 # Write out the contents of memory 146 %(errorCodeCode)s 147 st t7, hs, [1, t0, t6], %(errorCodeSize)d, dataSize=8, addressSize=8 148 st t10, hs, [1, t0, t6], 8 + %(errorCodeSize)d, dataSize=8, addressSize=8 149 rflags t10, dataSize=8 150 st t10, hs, [1, t0, t6], 16 + %(errorCodeSize)d, dataSize=8, addressSize=8 151 st rsp, hs, [1, t0, t6], 24 + %(errorCodeSize)d, dataSize=8, addressSize=8 152 rdsel t5, ss, dataSize=2 153 st t5, hs, [1, t0, t6], 32 + %(errorCodeSize)d, dataSize=8, addressSize=8 154 155 # Set the stack segment 156 mov rsp, rsp, t6, dataSize=8 157 wrsel ss, t11, dataSize=2 158 159 # 160 # Adjust rflags which is still in t10 from above 161 # 162 163 # Set IF to the lowest bit of the original gate type. 164 # The type field of the original gate starts at bit 40. 165 166 # Set the TF, NT, and RF bits. We'll flip them at the end. 167 limm t6, (1 << 8) | (1 << 14) | (1 << 16) 168 or t10, t10, t6 169 srli t5, t4, 40, dataSize=8 170 srli t7, t10, 9, dataSize=8 171 xor t5, t7, t5, dataSize=8 172 andi t5, t5, 1, dataSize=8 173 slli t5, t5, 9, dataSize=8 174 or t6, t5, t6, dataSize=8 175 176 # Put the results into rflags 177 wrflags t6, t10 178 179 eret 180}; 181''' 182 183microcode = \ 184intCodeTemplate % {\ 185 "startLabel" : "longModeInterrupt", 186 "gateCheckType" : "IntGateCheck", 187 "errorCodeSize" : 0, 188 "errorCodeCode" : "" 189} + \ 190intCodeTemplate % {\ 191 "startLabel" : "longModeSoftInterrupt", 192 "gateCheckType" : "SoftIntGateCheck", 193 "errorCodeSize" : 0, 194 "errorCodeCode" : "" 195} + \ 196intCodeTemplate % {\ 197 "startLabel" : "longModeInterruptWithError", 198 "gateCheckType" : "IntGateCheck", 199 "errorCodeSize" : 8, 200 "errorCodeCode" : ''' 201 st t15, hs, [1, t0, t6], dataSize=8, addressSize=8 202 ''' 203} + \ 204''' 205def rom 206{ 207 # This vectors the CPU into an interrupt handler in legacy mode. 208 extern legacyModeInterrupt: 209 panic "Legacy mode interrupts not implemented (in microcode)" 210 eret 211}; 212''' 213