romutil.py revision 5852
111308Santhony.gutierrez@amd.com# Copyright (c) 2008 The Regents of The University of Michigan
211308Santhony.gutierrez@amd.com# All rights reserved.
311308Santhony.gutierrez@amd.com#
411308Santhony.gutierrez@amd.com# Redistribution and use in source and binary forms, with or without
511308Santhony.gutierrez@amd.com# modification, are permitted provided that the following conditions are
611308Santhony.gutierrez@amd.com# met: redistributions of source code must retain the above copyright
711308Santhony.gutierrez@amd.com# notice, this list of conditions and the following disclaimer;
811308Santhony.gutierrez@amd.com# redistributions in binary form must reproduce the above copyright
911308Santhony.gutierrez@amd.com# notice, this list of conditions and the following disclaimer in the
1011308Santhony.gutierrez@amd.com# documentation and/or other materials provided with the distribution;
1111308Santhony.gutierrez@amd.com# neither the name of the copyright holders nor the names of its
1211308Santhony.gutierrez@amd.com# contributors may be used to endorse or promote products derived from
1311308Santhony.gutierrez@amd.com# this software without specific prior written permission.
1411308Santhony.gutierrez@amd.com#
1511308Santhony.gutierrez@amd.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1611308Santhony.gutierrez@amd.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1711308Santhony.gutierrez@amd.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1811308Santhony.gutierrez@amd.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1911308Santhony.gutierrez@amd.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2011308Santhony.gutierrez@amd.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2111308Santhony.gutierrez@amd.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2211308Santhony.gutierrez@amd.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2311308Santhony.gutierrez@amd.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2411308Santhony.gutierrez@amd.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2511308Santhony.gutierrez@amd.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2611308Santhony.gutierrez@amd.com#
2711308Santhony.gutierrez@amd.com# Authors: Gabe Black
2811308Santhony.gutierrez@amd.com
2911308Santhony.gutierrez@amd.commicrocode = '''
3011308Santhony.gutierrez@amd.comdef rom
3111308Santhony.gutierrez@amd.com{
3211308Santhony.gutierrez@amd.com    # This vectors the CPU into an interrupt handler in long mode.
3311308Santhony.gutierrez@amd.com    # On entry, t1 is set to the vector of the interrupt and t7 is the current
3411308Santhony.gutierrez@amd.com    # ip. We need that because rdip returns the next ip.
3511308Santhony.gutierrez@amd.com    extern longModeInterrupt:
3611308Santhony.gutierrez@amd.com
3711308Santhony.gutierrez@amd.com    #
3811308Santhony.gutierrez@amd.com    # Get the 64 bit interrupt or trap gate descriptor from the IDT
3911308Santhony.gutierrez@amd.com    #
4011308Santhony.gutierrez@amd.com
4111308Santhony.gutierrez@amd.com    # Load the gate descriptor from the IDT
4211308Santhony.gutierrez@amd.com    slli t4, t1, 4, dataSize=8
4311308Santhony.gutierrez@amd.com    ld t2, idtr, [1, t0, t4], 8, dataSize=8, addressSize=8
4411308Santhony.gutierrez@amd.com    ld t4, idtr, [1, t0, t4], dataSize=8, addressSize=8
4511308Santhony.gutierrez@amd.com
4611308Santhony.gutierrez@amd.com    # Check permissions
4711308Santhony.gutierrez@amd.com    chks t1, t4, IntGateCheck
4811308Santhony.gutierrez@amd.com
4911308Santhony.gutierrez@amd.com    mov t1, t1, t4, dataSize=8
5011308Santhony.gutierrez@amd.com
5111308Santhony.gutierrez@amd.com    # Check that it's the right type
5211308Santhony.gutierrez@amd.com    srli t4, t1, 40, dataSize=8
5311308Santhony.gutierrez@amd.com    andi t4, t4, 0xe, dataSize=8
5411308Santhony.gutierrez@amd.com    xori t4, t4, 0xe, flags=(EZF,), dataSize=8
5511308Santhony.gutierrez@amd.com    fault "new GeneralProtection(0)", flags=(nCEZF,)
5611308Santhony.gutierrez@amd.com
5711308Santhony.gutierrez@amd.com
5811308Santhony.gutierrez@amd.com    #
5911308Santhony.gutierrez@amd.com    # Get the target CS descriptor using the selector in the gate
6011308Santhony.gutierrez@amd.com    # descriptor.
6111308Santhony.gutierrez@amd.com    #
6211308Santhony.gutierrez@amd.com    srli t10, t4, 16, dataSize=8
6311308Santhony.gutierrez@amd.com    andi t5, t10, 0xF8, dataSize=8
6411308Santhony.gutierrez@amd.com    andi t0, t10, 0x4, flags=(EZF,), dataSize=2
6511308Santhony.gutierrez@amd.com    br rom_local_label("globalDescriptor"), flags=(CEZF,)
6611308Santhony.gutierrez@amd.com    ld t3, tsl, [1, t0, t5], dataSize=8, addressSize=8
6711308Santhony.gutierrez@amd.com    br rom_local_label("processDescriptor")
6811308Santhony.gutierrez@amd.comglobalDescriptor:
6911308Santhony.gutierrez@amd.com    ld t3, tsg, [1, t0, t5], dataSize=8, addressSize=8
7011308Santhony.gutierrez@amd.comprocessDescriptor:
7111308Santhony.gutierrez@amd.com    chks t10, t3, IntCSCheck, dataSize=8
7211308Santhony.gutierrez@amd.com    wrdl hs, t3, t10, dataSize=8
7311308Santhony.gutierrez@amd.com
7411308Santhony.gutierrez@amd.com    # Stick the target offset in t9.
7511308Santhony.gutierrez@amd.com    wrdh t9, t4, t2, dataSize=8
7611308Santhony.gutierrez@amd.com
7711308Santhony.gutierrez@amd.com
7811308Santhony.gutierrez@amd.com    #
7911308Santhony.gutierrez@amd.com    # Figure out where the stack should be
8011308Santhony.gutierrez@amd.com    #
8111308Santhony.gutierrez@amd.com
8211308Santhony.gutierrez@amd.com    # Record what we might set the stack selector to.
8311308Santhony.gutierrez@amd.com    rdsel t11, ss
8411308Santhony.gutierrez@amd.com
8511308Santhony.gutierrez@amd.com    # Check if we're changing privelege level. At this point we can assume
8611308Santhony.gutierrez@amd.com    # we're going to a DPL that's less than or equal to the CPL.
8711308Santhony.gutierrez@amd.com    rdattr t10, hs, dataSize=8
8811308Santhony.gutierrez@amd.com    srli t10, t10, 3, dataSize=8
8911308Santhony.gutierrez@amd.com    andi t10, t10, 3, dataSize=8
9011308Santhony.gutierrez@amd.com    rdattr t5, cs, dataSize=8
9111308Santhony.gutierrez@amd.com    srli t5, t5, 3, dataSize=8
9211308Santhony.gutierrez@amd.com    sub t5, t5, t10, dataSize=8
9311308Santhony.gutierrez@amd.com    andi t0, t5, 0x3, flags=(EZF,), dataSize=8
9411308Santhony.gutierrez@amd.com    # We're going to change priviledge, so zero out the stack selector. We
9511308Santhony.gutierrez@amd.com    # need to let the IST have priority so we don't branch yet.
9611308Santhony.gutierrez@amd.com    wrsel t11, t0, flags=(nCEZF,)
9711308Santhony.gutierrez@amd.com
9811308Santhony.gutierrez@amd.com    # Check the IST field of the gate descriptor
9911308Santhony.gutierrez@amd.com    srli t10, t4, 32, dataSize=8
10011308Santhony.gutierrez@amd.com    andi t10, t10, 0x7, dataSize=8
10111308Santhony.gutierrez@amd.com    subi t0, t10, 1, flags=(ECF,), dataSize=8
10211308Santhony.gutierrez@amd.com    br rom_local_label("istStackSwitch"), flags=(nCECF,)
10311308Santhony.gutierrez@amd.com    br rom_local_label("cplStackSwitch"), flags=(nCEZF,)
10411308Santhony.gutierrez@amd.com
10511308Santhony.gutierrez@amd.com    # If we're here, it's because the stack isn't being switched.
10611308Santhony.gutierrez@amd.com    # Set t6 to the new rsp.
10711308Santhony.gutierrez@amd.com    subi t6, rsp, 40, dataSize=8
10811308Santhony.gutierrez@amd.com
10911308Santhony.gutierrez@amd.com    # Align the stack
11011308Santhony.gutierrez@amd.com    andi t6, t6, 0xF0, dataSize=1
11111308Santhony.gutierrez@amd.com
11211308Santhony.gutierrez@amd.com    # Check that we can access everything we need to on the stack
11311308Santhony.gutierrez@amd.com    ldst t0, hs, [1, t0, t6], dataSize=8, addressSize=8
11411308Santhony.gutierrez@amd.com    ldst t0, hs, [1, t0, t6], 32, dataSize=8, addressSize=8
11511308Santhony.gutierrez@amd.com    br rom_local_label("stackSwitched")
11611308Santhony.gutierrez@amd.com
11711308Santhony.gutierrez@amd.comistStackSwitch:
11811308Santhony.gutierrez@amd.com    panic "IST based stack switching isn't implemented"
11911308Santhony.gutierrez@amd.com    br rom_local_label("stackSwitched")
12011308Santhony.gutierrez@amd.com
12111308Santhony.gutierrez@amd.comcplStackSwitch:
12211308Santhony.gutierrez@amd.com    panic "CPL change initiated stack switching isn't implemented"
12311308Santhony.gutierrez@amd.com
12411308Santhony.gutierrez@amd.comstackSwitched:
12511308Santhony.gutierrez@amd.com
12611308Santhony.gutierrez@amd.com
12711308Santhony.gutierrez@amd.com    ##
12811308Santhony.gutierrez@amd.com    ## Point of no return.
12911308Santhony.gutierrez@amd.com    ## We're now going to irrevocably modify visible state.
13011308Santhony.gutierrez@amd.com    ## Anything bad that's going to happen should have happened by now or will
13111308Santhony.gutierrez@amd.com    ## happen right now.
13211308Santhony.gutierrez@amd.com    ##
13311308Santhony.gutierrez@amd.com    wrip t0, t9, dataSize=8
13411308Santhony.gutierrez@amd.com
13511308Santhony.gutierrez@amd.com
13611308Santhony.gutierrez@amd.com    #
13711308Santhony.gutierrez@amd.com    # Build up the interrupt stack frame
13811308Santhony.gutierrez@amd.com    #
13911308Santhony.gutierrez@amd.com
14011308Santhony.gutierrez@amd.com
14111308Santhony.gutierrez@amd.com    # Write out the contents of memory
14211308Santhony.gutierrez@amd.com    st t7, hs, [1, t0, t6], dataSize=8
14311308Santhony.gutierrez@amd.com    limm t5, 0, dataSize=8
14411308Santhony.gutierrez@amd.com    rdsel t5, cs, dataSize=2
14511308Santhony.gutierrez@amd.com    st t5, hs, [1, t0, t6], 8, dataSize=8
14611308Santhony.gutierrez@amd.com    rflags t10, dataSize=8
14711308Santhony.gutierrez@amd.com    st t10, hs, [1, t0, t6], 16, dataSize=8
14811308Santhony.gutierrez@amd.com    st rsp, hs, [1, t0, t6], 24, dataSize=8
14911308Santhony.gutierrez@amd.com    rdsel t5, ss, dataSize=2
15011308Santhony.gutierrez@amd.com    st t5, hs, [1, t0, t6], 32, dataSize=8
15111308Santhony.gutierrez@amd.com
15211308Santhony.gutierrez@amd.com    # Set the stack segment
15311308Santhony.gutierrez@amd.com    mov rsp, rsp, t6, dataSize=8
15411308Santhony.gutierrez@amd.com    wrsel ss, t11, dataSize=2
15511308Santhony.gutierrez@amd.com
15611308Santhony.gutierrez@amd.com    #
15711308Santhony.gutierrez@amd.com    # Set up the target code segment
15811308Santhony.gutierrez@amd.com    #
15911308Santhony.gutierrez@amd.com    srli t5, t4, 16, dataSize=8
16011308Santhony.gutierrez@amd.com    andi t5, t5, 0xFF, dataSize=8
16111308Santhony.gutierrez@amd.com    wrdl cs, t3, t5, dataSize=8
16211308Santhony.gutierrez@amd.com    wrsel cs, t5, dataSize=2
16311308Santhony.gutierrez@amd.com
16411308Santhony.gutierrez@amd.com    #
16511308Santhony.gutierrez@amd.com    # Adjust rflags which is still in t10 from above
16611308Santhony.gutierrez@amd.com    #
16711308Santhony.gutierrez@amd.com
16811308Santhony.gutierrez@amd.com    # Set IF to the lowest bit of the original gate type.
16911308Santhony.gutierrez@amd.com    # The type field of the original gate starts at bit 40.
17011308Santhony.gutierrez@amd.com
17111308Santhony.gutierrez@amd.com    # Set the TF, NT, and RF bits. We'll flip them at the end.
17211308Santhony.gutierrez@amd.com    limm t6, (1 << 8) | (1 << 14) | (1 << 16)
17311308Santhony.gutierrez@amd.com    or t10, t10, t6
17411308Santhony.gutierrez@amd.com    srli t5, t4, 40, dataSize=8
17511308Santhony.gutierrez@amd.com    srli t7, t10, 9, dataSize=8
17611308Santhony.gutierrez@amd.com    xor t5, t7, t5, dataSize=8
17711308Santhony.gutierrez@amd.com    andi t5, t5, 1, dataSize=8
17811308Santhony.gutierrez@amd.com    slli t5, t5, 9, dataSize=8
17911308Santhony.gutierrez@amd.com    or t6, t5, t6, dataSize=8
18011308Santhony.gutierrez@amd.com
18111308Santhony.gutierrez@amd.com    # Put the results into rflags
18211308Santhony.gutierrez@amd.com    wrflags t6, t10
18311308Santhony.gutierrez@amd.com
18411308Santhony.gutierrez@amd.com    eret
18511308Santhony.gutierrez@amd.com};
18611308Santhony.gutierrez@amd.com
18711308Santhony.gutierrez@amd.comdef rom
18811308Santhony.gutierrez@amd.com{
18911308Santhony.gutierrez@amd.com    # This vectors the CPU into an interrupt handler in legacy mode.
19011308Santhony.gutierrez@amd.com    extern legacyModeInterrupt:
19111308Santhony.gutierrez@amd.com    panic "Legacy mode interrupts not implemented (in microcode)"
19211308Santhony.gutierrez@amd.com    eret
19311308Santhony.gutierrez@amd.com};
19411308Santhony.gutierrez@amd.com'''
19511308Santhony.gutierrez@amd.com