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