32-bit TSS in long mode?
Posted: Sun Dec 28, 2014 10:23 pm
Hi,
I have a few issues going on at the moment, but I am trying to focus on getting my 64-bit TSS flags right since I believe that is the root of at least some of my issues. Please forgive the long post as I lay out the background.
I am getting a spurious IRQ when enabling interrupts for which I did not have a handler written yet. So I wrote very simple one (mostly ignoring LPT1 for now):
Bochs confirms that I am getting a spurious interrupter (0x27) followed by a page fault on exit:
At any rate, I investigate my GDT and I see the following:
I have read the Intel manual vol 3A sections 3.5 and 7.2.3 several times and I've convinced myself (probably wrongly) I have my bits setup correctly:
In particular, I am expecting "0xff808bf0" to tell me that I have a 64-bit TSS in GDT[0x05] ('busy' in fact). However, as above, Bochs is reporting a 32-bit TSS.
Bochs reports that I am using long mode, which is what I understand the distinguishing factor to be:
Thanks in advance!!
I have a few issues going on at the moment, but I am trying to focus on getting my 64-bit TSS flags right since I believe that is the root of at least some of my issues. Please forgive the long post as I lay out the background.
I am getting a spurious IRQ when enabling interrupts for which I did not have a handler written yet. So I wrote very simple one (mostly ignoring LPT1 for now):
Code: Select all
;----------------------------------------------------------------------------------------------
; SpurHandler -- This is the Interrupt handler for IRQ7. It will be called with each spurious
; interrupt. It will also be called for any LPT1 interrupt, so we will need
; to be careful with this.
;
; Keep in mind that this 'function' does not have a normal entry process or exit process. We
; need to be particularly careful about saving and restoring EVERYTHING we will touch.
;----------------------------------------------------------------------------------------------
SpurHandler:
push rbp ; save the interrupted process's frame
mov.q rbp,rsp ; we want our own frame
push rax ; yes, we even save rax
;----------------------------------------------------------------------------------------------
; check if it is a spurious interrupt
;----------------------------------------------------------------------------------------------
mov.q rax,pic ; get the pic interface structure
mov.q rax,[rax+PIC.readISR] ; get the ReadISR fucntion address
call rax ; do we have an interrupt
test.q rax,0x80 ; test bit 7
jz .eoi ; we have a real interrupt; ack it
mov.q rax,spurCount ; get the counter address
inc qword [rax] ; increment the count
%ifndef DISABLE_DBG_CONSOLE
mov.q rax,spurIntRcvd ; get the text address
push rax ; put it on the stack
call DbgConsolePutString ; write it to the console
add.q rsp,8 ; clean up the stack
%endif
jmp .out ; go exit
.eoi: mov.q rax,pic ; get the pic interface structure
mov.q rax,[rax+PIC.eoi] ; get the EOI fucntion address
push 0x07 ; we need to ack IRQ7
call rax ; do we have an interrupt
.out: pop rax ; restore rax
pop rbp ; restore rbp
iretq
;==============================================================================================
One thing I find odd is that DbgConsolePutString() is not writing any string to the serial port....00169419906d[CPU0 ] inhibit interrupts mask = 1
00169419908d[CPU0 ] interrupt(): vector = 27, TYPE = 0, EXT = 1
00169419908d[CPU0 ] page walk for address 0xffffa000000b8340
00169419908d[CPU0 ] interrupt(long mode): INTERRUPT TO SAME PRIVILEGE
00169419908d[CPU0 ] interrupt(long mode): trap to IST, vector = 2
00169419908d[CPU0 ] page walk for address 0xfffff00200017ff8
00169419908d[CPU0 ] page walk for address 0xffffa000000b806d
00169419949d[CPU0 ] LONG MODE IRET
00169419949d[CPU0 ] page walk for address 0x0000000000003e40
00169419949d[CPU0 ] PAE PTE: entry not present
00169419949d[CPU0 ] page fault for address 0000000000003e40 @ ffff800000104f59
00169419949d[CPU0 ] exception(0x0e): error_code=0000
00169419949d[CPU0 ] interrupt(): vector = 0e, TYPE = 3, EXT = 1
00169419949d[CPU0 ] interrupt(long mode): INTERRUPT TO SAME PRIVILEGE
00169419949d[CPU0 ] interrupt(long mode): trap to IST, vector = 5
00169419949d[CPU0 ] page walk for address 0xfffff00200023ff8
00169420038d[CPU0 ] page walk for address 0x00000000000b8000
00169466708i[CPU0 ] WARNING: HLT instruction with IF=0!
At any rate, I investigate my GDT and I see the following:
Code: Select all
Global Descriptor Table (base=0xffffa000000b8060, limit=55):
GDT[0x00]=??? descriptor hi=0x00000000, lo=0x00000000
GDT[0x01]=Code segment, base=0x00000000, limit=0x00000fff, Execute/Read, Non-Conforming, Accessed, 64-bit
GDT[0x02]=Data segment, base=0x00000000, limit=0x00000fff, Read/Write, Accessed
GDT[0x03]=Code segment, base=0x00000000, limit=0x00000fff, Execute/Read, Non-Conforming, 64-bit
GDT[0x04]=Data segment, base=0x00000000, limit=0x00000fff, Read/Write
GDT[0x05]=32-Bit TSS (Busy) at 0xfff00000, length 0x00067
GDT[0x06]=??? descriptor hi=0x00000000, lo=0xffffff7f
Code: Select all
0xffffa000000b8060 <bogus+ 0>: 0x00000000 0x00000000 0x00000000 0x00a09b00
0xffffa000000b8070 <bogus+ 16>: 0x00000000 0x00809300 0x00000000 0x00a0fa00
0xffffa000000b8080 <bogus+ 32>: 0x00000000 0x0080f200 0x00000067 0xff808bf0
0xffffa000000b8090 <bogus+ 48>: 0xffffff7f 0x00000000
Bochs reports that I am using long mode, which is what I understand the distinguishing factor to be:
I'm sure I'm missing something rather obvious with the GDT flags somewhere. Can someone please help me out or point me in the right direction?00820800009i[CPU0 ] CPU is in long mode (halted)
00820800009i[CPU0 ] CS.mode = 64 bit
00820800009i[CPU0 ] SS.mode = 64 bit
00820800009i[CPU0 ] EFER = 0x00000500
00820800009i[CPU0 ] | RAX=ffff800000101d0e RBX=ffff800000105a28
00820800009i[CPU0 ] | RCX=00000000e0000011 RDX=0000000000000020
00820800009i[CPU0 ] | RSP=fffff00200023ef8 RBP=fffff00200023f00
00820800009i[CPU0 ] | RSI=0000000000000000 RDI=00000000000b800c
00820800009i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00820800009i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00820800009i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00820800009i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00820800009i[CPU0 ] | IOPL=0 ID vip vif ac vm rf nt of df if tf sf zf af pf cf
00820800009i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00820800009i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 00000fff 1 0
00820800009i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 00000fff 1 0
00820800009i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 00000fff 1 0
00820800009i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 00000fff 1 0
00820800009i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 00000fff 1 0
00820800009i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 00000fff 1 0
00820800009i[CPU0 ] | MSR_FS_BASE:0000000000000000
00820800009i[CPU0 ] | MSR_GS_BASE:0000000000000000
00820800009i[CPU0 ] | RIP=ffff800000101d10 (ffff800000101d10)
00820800009i[CPU0 ] | CR0=0xe0000011 CR2=0x0000000000003e40
00820800009i[CPU0 ] | CR3=0x00400000 CR4=0x00000020
Thanks in advance!!