interrupts_and_exceptions.py revision 6645:c248b0348d85
12292SN/A# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
22292SN/A# All rights reserved.
32292SN/A#
42292SN/A# Redistribution and use of this software in source and binary forms,
52292SN/A# with or without modification, are permitted provided that the
62292SN/A# following conditions are met:
72292SN/A#
82292SN/A# The software must be used only for Non-Commercial Use which means any
92292SN/A# use which is NOT directed to receiving any direct monetary
102292SN/A# compensation for, or commercial advantage from such use.  Illustrative
112292SN/A# examples of non-commercial use are academic research, personal study,
122292SN/A# teaching, education and corporate research & development.
132292SN/A# Illustrative examples of commercial use are distributing products for
142292SN/A# commercial advantage and providing services using the software for
152292SN/A# commercial advantage.
162292SN/A#
172292SN/A# If you wish to use this software or functionality therein that may be
182292SN/A# covered by patents for commercial use, please contact:
192292SN/A#     Director of Intellectual Property Licensing
202292SN/A#     Office of Strategy and Technology
212292SN/A#     Hewlett-Packard Company
222292SN/A#     1501 Page Mill Road
232292SN/A#     Palo Alto, California  94304
242292SN/A#
252292SN/A# Redistributions of source code must retain the above copyright notice,
262292SN/A# this list of conditions and the following disclaimer.  Redistributions
272689Sktlim@umich.edu# in binary form must reproduce the above copyright notice, this list of
282689Sktlim@umich.edu# conditions and the following disclaimer in the documentation and/or
292689Sktlim@umich.edu# other materials provided with the distribution.  Neither the name of
302292SN/A# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
312292SN/A# contributors may be used to endorse or promote products derived from
322733Sktlim@umich.edu# this software without specific prior written permission.  No right of
332733Sktlim@umich.edu# sublicense is granted herewith.  Derivatives of the software and
342907Sktlim@umich.edu# output created using the software may be prepared, but only for
352292SN/A# Non-Commercial Uses.  Derivatives of the software may be shared with
362292SN/A# others provided: (i) the others agree to abide by the list of
372722Sktlim@umich.edu# conditions herein which includes the Non-Commercial Use restrictions;
382669Sktlim@umich.edu# and (ii) such Derivatives of the software include the above copyright
392292SN/A# notice to acknowledge the contribution from this software where
402790Sktlim@umich.edu# applicable, this list of conditions and the disclaimer below.
412790Sktlim@umich.edu#
422790Sktlim@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
432790Sktlim@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
442669Sktlim@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
452678Sktlim@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
462678Sktlim@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
472678Sktlim@umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
482292SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
492678Sktlim@umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
502292SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
512292SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
522669Sktlim@umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
532292SN/A#
542678Sktlim@umich.edu# Authors: Gabe Black
552292SN/A
562678Sktlim@umich.edumicrocode = '''
572678Sktlim@umich.edudef macroop IRET_REAL {
582678Sktlim@umich.edu    panic "Real mode iret isn't implemented!"
592678Sktlim@umich.edu};
602678Sktlim@umich.edu
612292SN/Adef macroop IRET_PROT {
622678Sktlim@umich.edu    .adjust_env oszIn64Override
632678Sktlim@umich.edu
642678Sktlim@umich.edu    # Check for a nested task. This isn't supported at the moment.
652678Sktlim@umich.edu    rflag t1, 14; #NT bit
662678Sktlim@umich.edu    panic "Task switching with iret is unimplemented!", flags=(nCEZF,)
672678Sktlim@umich.edu
682292SN/A    #t1 = temp_RIP
692678Sktlim@umich.edu    #t2 = temp_CS
702678Sktlim@umich.edu    #t3 = temp_RFLAGS
712678Sktlim@umich.edu    #t4 = handy m5 register
722678Sktlim@umich.edu
732678Sktlim@umich.edu    # Pop temp_RIP, temp_CS, and temp_RFLAGS
742678Sktlim@umich.edu    ld t1, ss, [1, t0, rsp], "0 * env.stackSize", dataSize=ssz
752678Sktlim@umich.edu    ld t2, ss, [1, t0, rsp], "1 * env.stackSize", dataSize=ssz
762698Sktlim@umich.edu    ld t3, ss, [1, t0, rsp], "2 * env.stackSize", dataSize=ssz
772344SN/A
782678Sktlim@umich.edu    # Read the handy m5 register for use later
792678Sktlim@umich.edu    rdm5reg t4
802678Sktlim@umich.edu
812820Sktlim@umich.edu
822678Sktlim@umich.edu###
832678Sktlim@umich.edu### Handle if we're returning to virtual 8086 mode.
842307SN/A###
852678Sktlim@umich.edu
862678Sktlim@umich.edu    #IF ((temp_RFLAGS.VM=1) && (CPL=0) && (LEGACY_MODE))
872678Sktlim@umich.edu    #    IRET_FROM_PROTECTED_TO_VIRTUAL
882678Sktlim@umich.edu
892678Sktlim@umich.edu    #temp_RFLAGS.VM != 1
902678Sktlim@umich.edu    rcri t0, t3, 18, flags=(ECF,)
912678Sktlim@umich.edu    br label("protToVirtFallThrough"), flags=(nCECF,)
922678Sktlim@umich.edu
932344SN/A    #CPL=0
942307SN/A    andi t0, t4, 0x30, flags=(EZF,)
952678Sktlim@umich.edu    br label("protToVirtFallThrough"), flags=(nCEZF,)
962678Sktlim@umich.edu
972292SN/A    #(LEGACY_MODE)
982292SN/A    rcri t0, t4, 1, flags=(ECF,)
992292SN/A    br label("protToVirtFallThrough"), flags=(nCECF,)
1002292SN/A
1012678Sktlim@umich.edu    panic "iret to virtual mode not supported"
1022678Sktlim@umich.edu
1032292SN/AprotToVirtFallThrough:
1042292SN/A
1052292SN/A
1062292SN/A
1072292SN/A    #temp_CPL = temp_CS.rpl
1082292SN/A    andi t5, t2, 0x3
1092907Sktlim@umich.edu
1102292SN/A
1112292SN/A###
1122292SN/A### Read in the info for the new CS segment.
1132292SN/A###
1142307SN/A
1152307SN/A    #CS = READ_DESCRIPTOR (temp_CS, iret_chk)
1162907Sktlim@umich.edu    andi t0, t2, 0xFC, flags=(EZF,), dataSize=2
1172907Sktlim@umich.edu    br label("processCSDescriptor"), flags=(CEZF,)
1182292SN/A    andi t6, t2, 0xF8, dataSize=8
1192292SN/A    andi t0, t2, 0x4, flags=(EZF,), dataSize=2
1202329SN/A    br label("globalCSDescriptor"), flags=(CEZF,)
1212329SN/A    ld t8, tsl, [1, t0, t6], dataSize=8
1222329SN/A    br label("processCSDescriptor")
1232292SN/AglobalCSDescriptor:
1242292SN/A    ld t8, tsg, [1, t0, t6], dataSize=8
1252292SN/AprocessCSDescriptor:
1262292SN/A    chks t2, t6, dataSize=8
1272292SN/A
1282292SN/A
1292292SN/A###
1302292SN/A### Get the new stack pointer and stack segment off the old stack if necessary,
1312292SN/A### and piggyback on the logic to check the new RIP value.
1322292SN/A###
1332292SN/A    #IF ((64BIT_MODE) || (temp_CPL!=CPL))
1342329SN/A    #{
1352292SN/A
1362292SN/A    #(64BIT_MODE)
1372292SN/A    andi t0, t4, 0xE, flags=(EZF,)
1382292SN/A    # Since we just found out we're in 64 bit mode, take advantage and
1392292SN/A    # do the appropriate RIP checks.
1402669Sktlim@umich.edu    br label("doPopStackStuffAndCheckRIP"), flags=(CEZF,)
1412733Sktlim@umich.edu
1422669Sktlim@umich.edu    # Here, we know we're -not- in 64 bit mode, so we should do the
1432669Sktlim@umich.edu    # appropriate/other RIP checks.
1442678Sktlim@umich.edu    # if temp_RIP > CS.limit throw #GP(0)
1452733Sktlim@umich.edu    rdlimit t6, cs, dataSize=8
1462679Sktlim@umich.edu    sub t0, t1, t6, flags=(ECF,)
1472679Sktlim@umich.edu    fault "new GeneralProtection(0)", flags=(CECF,)
1482679Sktlim@umich.edu
1492733Sktlim@umich.edu    #(temp_CPL!=CPL)
1502669Sktlim@umich.edu    srli t7, t4, 4
1512669Sktlim@umich.edu    xor t7, t7, t5
1522669Sktlim@umich.edu    andi t0, t7, 0x3, flags=(EZF,)
1532292SN/A    br label("doPopStackStuff"), flags=(nCEZF,)
1542292SN/A    # We can modify user visible state here because we're know
1552292SN/A    # we're done with things that can fault.
1562292SN/A    addi rsp, rsp, "3 * env.stackSize"
1572292SN/A    br label("fallThroughPopStackStuff")
1582292SN/A
1592292SN/AdoPopStackStuffAndCheckRIP:
1602292SN/A    # Check if the RIP is canonical.
1612292SN/A    srai t7, t1, 47, flags=(EZF,), dataSize=ssz
1622292SN/A    # if t7 isn't 0 or -1, it wasn't canonical.
1632292SN/A    br label("doPopStackStuff"), flags=(CEZF,)
1642292SN/A    addi t0, t7, 1, flags=(EZF,), dataSize=ssz
1652727Sktlim@umich.edu    fault "new GeneralProtection(0)", flags=(nCEZF,)
1662727Sktlim@umich.edu
1672727Sktlim@umich.edudoPopStackStuff:
1682727Sktlim@umich.edu    #    POP.v temp_RSP
1692727Sktlim@umich.edu    ld t6, ss, [1, t0, rsp], "3 * env.dataSize", dataSize=ssz
1702727Sktlim@umich.edu    #    POP.v temp_SS
1712727Sktlim@umich.edu    ld t9, ss, [1, t0, rsp], "4 * env.dataSize", dataSize=ssz
1722727Sktlim@umich.edu    #    SS = READ_DESCRIPTOR (temp_SS, ss_chk)
1732727Sktlim@umich.edu    andi t0, t9, 0xFC, flags=(EZF,), dataSize=2
1742727Sktlim@umich.edu    br label("processSSDescriptor"), flags=(CEZF,)
1752727Sktlim@umich.edu    andi t7, t9, 0xF8, dataSize=8
1762727Sktlim@umich.edu    andi t0, t9, 0x4, flags=(EZF,), dataSize=2
1772727Sktlim@umich.edu    br label("globalSSDescriptor"), flags=(CEZF,)
1782727Sktlim@umich.edu    ld t7, tsl, [1, t0, t7], dataSize=8
1792727Sktlim@umich.edu    br label("processSSDescriptor")
1802727Sktlim@umich.eduglobalSSDescriptor:
1812727Sktlim@umich.edu    ld t7, tsg, [1, t0, t7], dataSize=8
1822727Sktlim@umich.eduprocessSSDescriptor:
1832727Sktlim@umich.edu    chks t9, t7, dataSize=8
1842727Sktlim@umich.edu
1852727Sktlim@umich.edu    # This actually updates state which is wrong. It should wait until we know
1862727Sktlim@umich.edu    # we're not going to fault. Unfortunately, that's hard to do.
1872727Sktlim@umich.edu    wrdl ss, t7, t9
1882727Sktlim@umich.edu    wrsel ss, t9
1892727Sktlim@umich.edu
1902727Sktlim@umich.edu###
1912727Sktlim@umich.edu### From this point downwards, we can't fault. We can update user visible state.
1922727Sktlim@umich.edu###
1932727Sktlim@umich.edu    #    RSP.s = temp_RSP
1942727Sktlim@umich.edu    mov rsp, rsp, t6, dataSize=ssz
1952727Sktlim@umich.edu
1962727Sktlim@umich.edu    #}
1972727Sktlim@umich.edu
1982727Sktlim@umich.edufallThroughPopStackStuff:
1992727Sktlim@umich.edu
2002727Sktlim@umich.edu    # Update CS
2012727Sktlim@umich.edu    wrdl cs, t8, t2
2022727Sktlim@umich.edu    wrsel cs, t2
2032727Sktlim@umich.edu
2042727Sktlim@umich.edu    #CPL = temp_CPL
2052727Sktlim@umich.edu
2062292SN/A    #IF (changing CPL)
2072292SN/A    #{
2082292SN/A    srli t7, t4, 4
2092292SN/A    xor t7, t7, t5
2102292SN/A    andi t0, t7, 0x3, flags=(EZF,)
2112292SN/A    br label("skipSegmentSquashing"), flags=(CEZF,)
2122292SN/A
2132292SN/A    # The attribute register needs to keep track of more info before this will
2142292SN/A    # work the way it needs to.
2152292SN/A    #    FOR (seg = ES, DS, FS, GS)
2162292SN/A    #        IF ((seg.attr.dpl < cpl && ((seg.attr.type = 'data')
2172292SN/A    #            || (seg.attr.type = 'non-conforming-code')))
2182292SN/A    #        {
2192292SN/A    #            seg = NULL
2202307SN/A    #        }
2212307SN/A    #}
2222307SN/A
2232307SN/AskipSegmentSquashing:
2242307SN/A
2252307SN/A    # Ignore this for now.
2262329SN/A    #RFLAGS.v = temp_RFLAGS
2272307SN/A    wrflags t0, t3
2282307SN/A    #  VIF,VIP,IOPL only changed if (old_CPL = 0)
2292307SN/A    #  IF only changed if (old_CPL <= old_RFLAGS.IOPL)
2302307SN/A    #  VM unchanged
2312307SN/A    #  RF cleared
2322307SN/A
2332307SN/A    #RIP = temp_RIP
2342307SN/A    wrip t0, t1, dataSize=ssz
2352307SN/A};
2362307SN/A
2372307SN/Adef macroop IRET_VIRT {
2382307SN/A    panic "Virtual mode iret isn't implemented!"
2392307SN/A};
2402307SN/A'''
2412307SN/A#let {{
2422329SN/A#    class INT(Inst):
2432307SN/A#       "GenFault ${new UnimpInstFault}"
2442307SN/A#    class INTO(Inst):
2452307SN/A#       "GenFault ${new UnimpInstFault}"
2462307SN/A#}};
2472307SN/A