OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Apr 25, 2024 2:39 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: 64-bit IDT
PostPosted: Mon Jun 23, 2008 1:49 pm 
Offline
Member
Member
User avatar

Joined: Mon Mar 31, 2008 1:00 pm
Posts: 47
Location: Louisville, KY, USA
I am using James' tutorial but doing it in 64-bit instead of 32-bit. I am having trouble with the IDT, by looking at the Intel and AMD manuals i think I got the struct correct, but bochs is giving me a wierd error.

Error:
Code:
00009347191p[CPU0 ] >>PANIC<< failed assertion "BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64" at access32.cc:352

00009347191p[CPU0 ] >>PANIC<< failed assertion "BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64" at access32.cc:352

========================================================================
Bochs is exiting with the following message:
[CPU0 ] failed assertion "BX_CPU_THIS_PTR cpu_mode != BX_MODE_LONG_64" at access32.cc:352

========================================================================
00009347191i[CPU0 ] CPU is in long mode (active)
00009347191i[CPU0 ] CS.d_b = 16 bit
00009347191i[CPU0 ] SS.d_b = 16 bitasm
00009347191i[CPU0 ] EFER   = 0x00000500


I think the error is saying that the cpu isn't in long mode, then just below it says it is and the EFER register has the LMA = 1.

Here is my idt.c:
Code:
/*
* Interrupt Descriptor Structure
*/
typedef struct {
   u16bit   baseLow;
   u16bit   selector;
   u08bit   reservedIst;
   u08bit   flags;
   u16bit   baseMid;
   u32bit   baseHigh;
   u32bit   reserved;
} __attribute__((packed)) idtEntry;

/*
* Interrupt Descriptor Pointer
*/
typedef struct {
   u16bit   limit;
   u64bit   base;
} __attribute__((packed)) idtPointer;

/*
* Pushed Registers for ISR's
*/
typedef struct {
    u64bit ds;
    u64bit rdi, rsi, rbp, rsp, rbx, rdx, rcx, rax;
    u64bit intNo, errCode;
    u64bit rip, cs, eflags, useresp, ss;
} registers;

/*
* Prototypes
*/
void idtStart(void);
void idtSet(u08bit, u64bit, u16bit, u08bit);
void isrHandler(registers);
extern void idtInit();
extern void isr0();
extern void isr1();
extern void isr2();
extern void isr3();
extern void isr4();
extern void isr5();
extern void isr6();
extern void isr7();
extern void isr8();
extern void isr9();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();


/* Setup Table and Pointer */
idtEntry idt[256];
idtPointer idtP;

void idtStart(void) {
   /* Set IDT Pointer */
   idtP.limit = (sizeof(idtEntry) * 256) - 1;
   idtP.base = (u64bit)&idt;
   
   /* Clear Memory for IDT's */
   memorySet((u08bit *)&idt, 0, sizeof(idtEntry) * 256);
   
   /* Set IDT Gates */
   idtSet(0, (u64bit)isr0, 0x08, 0x8E);
   idtSet(1, (u64bit)isr1, 0x08, 0x8E);
   idtSet(2, (u64bit)isr2, 0x08, 0x8E);
   idtSet(3, (u64bit)isr3, 0x08, 0x8E);
   idtSet(4, (u64bit)isr4, 0x08, 0x8E);
   idtSet(5, (u64bit)isr5, 0x08, 0x8E);
   idtSet(6, (u64bit)isr6, 0x08, 0x8E);
   idtSet(7, (u64bit)isr7, 0x08, 0x8E);
   idtSet(8, (u64bit)isr8, 0x08, 0x8E);
   idtSet(9, (u64bit)isr9, 0x08, 0x8E);
   idtSet(10, (u64bit)isr10, 0x08, 0x8E);
   idtSet(11, (u64bit)isr11, 0x08, 0x8E);
   idtSet(12, (u64bit)isr12, 0x08, 0x8E);
   idtSet(13, (u64bit)isr13, 0x08, 0x8E);
   idtSet(14, (u64bit)isr14, 0x08, 0x8E);
   idtSet(15, (u64bit)isr15, 0x08, 0x8E);
   idtSet(16, (u64bit)isr16, 0x08, 0x8E);
   idtSet(17, (u64bit)isr17, 0x08, 0x8E);
   idtSet(18, (u64bit)isr18, 0x08, 0x8E);
   idtSet(19, (u64bit)isr19, 0x08, 0x8E);
   idtSet(20, (u64bit)isr20, 0x08, 0x8E);
   idtSet(21, (u64bit)isr21, 0x08, 0x8E);
   idtSet(22, (u64bit)isr22, 0x08, 0x8E);
   idtSet(23, (u64bit)isr23, 0x08, 0x8E);
   idtSet(24, (u64bit)isr24, 0x08, 0x8E);
   idtSet(25, (u64bit)isr25, 0x08, 0x8E);
   idtSet(26, (u64bit)isr26, 0x08, 0x8E);
   idtSet(27, (u64bit)isr27, 0x08, 0x8E);
   idtSet(28, (u64bit)isr28, 0x08, 0x8E);
   idtSet(29, (u64bit)isr29, 0x08, 0x8E);
   idtSet(30, (u64bit)isr30, 0x08, 0x8E);
   idtSet(21, (u64bit)isr31, 0x08, 0x8E);
   
   /* Load IDT Table */
   idtInit();
}

void idtSet(u08bit number, u64bit base, u16bit selector, u08bit flags) {
   /* Set Base Address */
   idt[number].baseLow = base & 0xFFFF;
   idt[number].baseMid = (base >> 16) & 0xFFFF;
   idt[number].baseHigh = (base >> 32) & 0xFFFFFFFF;
   
   /* Set Selector */
   idt[number].selector = selector;
   idt[number].flags = flags;
   
   /* Set Reserved Areas to Zero */
   idt[number].reservedIst = 0;
   idt[number].reserved = 0;
}

void isrHandler(registers regs) {
   write("interrupt: ");
   writeInt(regs.intNo);
   write("\n");
}


Here is my external asm functions:
Code:
%macro pushAll 0
      push   rax
      push   rcx
      push   rdx
      push   rbx
      push   rbp
      push   rsi
      push   rdi
%endmacro

%macro popAll 0
      pop      rdi
      pop      rsi
      pop      rbp
      pop      rbx
      pop      rdx
      pop      rcx
      pop      rax
%endmacro

[GLOBAL idtInit]
[EXTERN idtP]
idtInit:
   lidt    [idtP]
   ret

;/*
; * Interrupt Handler
; */
[EXTERN isrHandler]

isrCommon:
    pushAll

    mov      ax, ds
    push   rax

    mov      ax, 0x10
    mov      ds, ax
    mov      es, ax
    mov      fs, ax
    mov      gs, ax

    call   isrHandler

    pop      rbx
    mov      ds, bx
    mov      es, bx
    mov      fs, bx
    mov      gs, bx

    popAll
    add      rsp, 8
    sti
    iret

%macro ISR_NOERRCODE 1
  global isr%1
  isr%1:
    cli
    push byte 0
    push byte %1
    jmp isrCommon
%endmacro

%macro ISR_ERRCODE 1
  global isr%1
  isr%1:
    cli
    push byte %1
    jmp isrCommon
%endmacro

ISR_NOERRCODE 0
ISR_NOERRCODE 1
ISR_NOERRCODE 2
ISR_NOERRCODE 3
ISR_NOERRCODE 4
ISR_NOERRCODE 5
ISR_NOERRCODE 6
ISR_NOERRCODE 7
ISR_ERRCODE   8
ISR_NOERRCODE 9
ISR_ERRCODE   10
ISR_ERRCODE   11
ISR_ERRCODE   12
ISR_ERRCODE   13
ISR_ERRCODE   14
ISR_NOERRCODE 15
ISR_NOERRCODE 16
ISR_NOERRCODE 17
ISR_NOERRCODE 18
ISR_NOERRCODE 19
ISR_NOERRCODE 20
ISR_NOERRCODE 21
ISR_NOERRCODE 22
ISR_NOERRCODE 23
ISR_NOERRCODE 24
ISR_NOERRCODE 25
ISR_NOERRCODE 26
ISR_NOERRCODE 27
ISR_NOERRCODE 28
ISR_NOERRCODE 29
ISR_NOERRCODE 30
ISR_NOERRCODE 31

_________________
Currently Working On:
Bootloader (Stage 1) (Complete)
Bootloader (Stage 2) (Inprogress)


Top
 Profile  
 
 Post subject: Re: 64-bit IDT
PostPosted: Mon Jun 23, 2008 2:18 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9301
Location: On the balcony, where I can actually keep 1½m distance
start with looking up the error message in bochs' source - it tells you exactly what's going on.

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: 64-bit IDT
PostPosted: Mon Jun 23, 2008 2:36 pm 
Offline
Member
Member
User avatar

Joined: Mon Mar 31, 2008 1:00 pm
Posts: 47
Location: Louisville, KY, USA
I looked at the error message in bochs source and it seems like, bochs cannot handle a 64bit idt. I do not know if this is correct but when it asked it cpu mode it says that it the cpu isn't in 64bit mode. Has anyone else had this problem, or is bochs not really broken just my code. I am going to say its my code, but you know you can hope :D .

_________________
Currently Working On:
Bootloader (Stage 1) (Complete)
Bootloader (Stage 2) (Inprogress)


Top
 Profile  
 
 Post subject: Re: 64-bit IDT
PostPosted: Mon Jun 23, 2008 2:46 pm 
Offline
Member
Member

Joined: Wed Jun 11, 2008 5:30 pm
Posts: 27
deleted


Last edited by geppy on Mon Jun 23, 2008 2:53 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: 64-bit IDT
PostPosted: Mon Jun 23, 2008 2:51 pm 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 3:45 am
Posts: 9301
Location: On the balcony, where I can actually keep 1½m distance
2.3.7 is recommended. There were several long-mode related glitches in 2.3.6

_________________
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]


Top
 Profile  
 
 Post subject: Re: 64-bit IDT
PostPosted: Mon Jun 23, 2008 2:53 pm 
Offline
Member
Member
User avatar

Joined: Mon Mar 31, 2008 1:00 pm
Posts: 47
Location: Louisville, KY, USA
I have that version, maybe my code is wrong, I just can't find what is wrong with it. Everything is according to the manuals.

Anything you recommend to try?

_________________
Currently Working On:
Bootloader (Stage 1) (Complete)
Bootloader (Stage 2) (Inprogress)


Top
 Profile  
 
 Post subject: Re: 64-bit IDT
PostPosted: Mon Jun 23, 2008 4:47 pm 
Offline
Member
Member
User avatar

Joined: Mon Mar 31, 2008 1:00 pm
Posts: 47
Location: Louisville, KY, USA
I had a 2.3.7.svn version so i down graded to just the 2.3.7 stable version.

The idt pointer is being loaded right but, I continually get a #GP and bochs show the error code below:
Code:
iret64: return CS selector null


what would make my code selector become null?

Code:
[GLOBAL idtInit]
[EXTERN idtP]
idtInit:
   lidt    [idtP]
   sti   <-------------------- #GP starts here
   ret


This is also in bochs source showing the #GP, but just don't understand why the CS is null.
Code:
// return CS selector must be non-null, else #GP(0)
if ((raw_cs_selector & 0xfffc) == 0) {
     BX_ERROR(("iret64: return CS selector null"));
     exception(BX_GP_EXCEPTION, 0, 0);
}


After looking at some information from bochs I see this, it apears that bochs thinks I am using a 32-bit idt I do not know why, so every other one is wrong here is the output:

Code:
<bochs:14> info idt 1
Interrupt Descriptor Table (base=0x0000000000013000, limit=4095):
IDT[0x01]=??? descriptor hi=0x00000000, lo=0x00000000
<bochs:15> info idt 2
Interrupt Descriptor Table (base=0x0000000000013000, limit=4095):
IDT[0x02]=32-Bit Interrupt Gate target=0x0008:0x0001004f, DPL=0
<bochs:16> info idt 3
Interrupt Descriptor Table (base=0x0000000000013000, limit=4095):
IDT[0x03]=??? descriptor hi=0x00000000, lo=0x00000000
<bochs:17> info idt 4
Interrupt Descriptor Table (base=0x0000000000013000, limit=4095):
IDT[0x04]=32-Bit Interrupt Gate target=0x0008:0x00010056, DPL=0
<bochs:18> info idt 5
Interrupt Descriptor Table (base=0x0000000000013000, limit=4095):
IDT[0x05]=??? descriptor hi=0x00000000, lo=0x00000000

_________________
Currently Working On:
Bootloader (Stage 1) (Complete)
Bootloader (Stage 2) (Inprogress)


Top
 Profile  
 
 Post subject: Re: 64-bit IDT
PostPosted: Sun Jun 29, 2008 8:59 am 
Offline
Member
Member
User avatar

Joined: Tue Apr 10, 2007 4:42 pm
Posts: 224
Use iretq instead of iret.

I had this a problem a long time ago and it pissed me off so much... As a final act of desperation, I added the 'q' suffix and it actually worked because assemblers just don't do that automatically for you when compiling 64-bit code... (this applies to NASM, FASM and AS)

Hope this helps!

_________________
"Sufficiently advanced stupidity is indistinguishable from malice."


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: 0xY, Bing [Bot], DotBot [Bot], Majestic-12 [Bot] and 267 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group