INT not working in 64bit

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
johnsa
Member
Member
Posts: 296
Joined: Mon Oct 15, 2007 3:04 pm

INT not working in 64bit

Post by johnsa »

Hey,

I've had my long mode IDT setup for a while now, and I've been using IRQs quite extensively and they all work perfectly. The second I try to use an INT instruction .. triple fault.
I've double checked the idt entries and descriptor format and it seems fine to me, just can't figure why a direct INT won't work.

Here is what I've got setup as an entry in the IDT say for INT 80h:

Code: Select all

struct interrupt_gate
	ofs15_0  dw ?
	selector dw ?
	flags    dw ?
	ofs31_16 dw ?
	ofs63_32 dd ?	
	rsrvd    dd ?
ends

;the flags are set to 0x8e00 ... which in 64bit mode should be correct for int gate / using modified legacy stack / ring 0 (so no tss or switch) ...
;The IDT is initially setup with dummy handlers for all 256 ints, then various things replace them as needed.. like the base IRQ manager / setup using the install_int64 function:

macro INSTALL_INT_HANDLER int_num,handler_addr,int_type
{
	mov ecx,int_num
	mov rax,handler_addr
	mov dx,int_type
	call install_int64
}

idt_init64:
	mov rsi,offset kernel_idt
	mov ecx,256
fillidt:
	mov ax,8e00h
	mov [rsi+interrupt_gate.flags],ax
	mov rax,offset dummy_handler
	mov rbx,rax
	shr rbx,32
	mov [rsi+interrupt_gate.ofs15_0],ax
	shr rax,16
	mov [rsi+interrupt_gate.ofs31_16],ax
	mov [rsi+interrupt_gate.ofs63_32],ebx
	mov ax,8
	mov [rsi+interrupt_gate.selector],ax
	xor eax,eax
	mov [rsi+interrupt_gate.rsrvd],eax
	add rsi,16
	dec ecx
	jnz short fillidt
	lea rax,[kernel_idt]
	lea rsi,[IDTReg]
	lea rdi,[IDTBase]
	mov [rdi],rax
	lidt [rsi]
	ret

; ECX = interrupt vector number.
; RAX = address of new handler.
;  DX = (8e00h=int/8f00h=trap).
install_int64:
	mov rsi,offset kernel_idt
	xor rbx,rbx	
	mov ebx,ecx
	shl ebx,4
	add rsi,rbx
	mov [rsi+interrupt_gate.flags],dx
	mov rbx,rax
	shr rbx,32
	mov [rsi+interrupt_gate.ofs15_0],ax
	shr rax,16
	mov [rsi+interrupt_gate.ofs31_16],ax
	mov [rsi+interrupt_gate.ofs63_32],ebx
	mov ax,8
	mov [rsi+interrupt_gate.selector],ax
	xor eax,eax
	mov [rsi+interrupt_gate.rsrvd],eax
	ret

align 4
dummy_handler:
	iretq
	
align 16
kernel_idt:
	entries dq 512 DUP (0)
	
align 16
IDTReg: 
	dw 4095
IDTBase:
	dq 0

; so in the kernel somewhere i setup an int...
INSTALL_INT_HANDLER 80h,offset int_handler,0x8e00
; and call it..
int 80h..

it never makes it into the handler code at all.
anyone have any ideas as it seems the IDT is fine to me as it works from the IRQ handlers, just when trying to call one via INT it dies.
John
User avatar
54616E6E6572
Member
Member
Posts: 47
Joined: Tue Aug 18, 2009 12:52 pm
Location: Kansas City

Re: INT not working in 64bit

Post by 54616E6E6572 »

Not sure if this is the problem or not, just wanted to point out some things.

1. Your IST is 0, which means that the cpu uses a modified version of the legacy task switching mechanism when called by SOFTWARE(See page 245 of AMD System Programming Manual)
2. a #GP(0) occurs if SOFTWARE references a descriptor with an offset not in canonical form.

and if neither one of these is helpful, AMD's SimNow Simulator (linux and windows) should allow you to see exactly where and why the problem occurred.
It will allow you to see exactly how your Descriptor tables and registers are changing as you step through the code,
and will also allow you to step through your interrupts when they occur, so you can see where they failed, whether that be during Vector look-up, vector execution, or for some other strange reason
The 2nd Doctor: "I have no doubt that you could augment an earwig to the point where it could understand nuclear physics, but it would still be a very stupid thing to do!"
Post Reply