STI doesn't work [SOLVED]

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.
User avatar
inflater
Member
Member
Posts: 1309
Joined: Thu Sep 28, 2006 10:32 am
Location: Slovakia
Contact:

Re: STI doesn't work

Post by inflater »

This is what I would do in the following order:

1. Check the IDT and ISR handlers, check for any unwanted PUSH or POP (may affect the return address)
2. Setup a bigger stack, 12kB should be enough -> set it somewhere where BIOS/your kernel or its parts do not reside to avoid mem overwriting
3. Didn't you forget to send EOI to every PIC using ISR? e.g. IRQ0, mouse irq, floppy etc
4. Check your timer settings
5. If all else fails, open bochs debugger and execute DIV AX with AX=0 and see what happens, if it jumps to your ISR, or gives some error, or just skips the instruction. :shock:

I agree with JamesM, PEBKAC...
My web site: http://inflater.wz.cz (Slovak)
Derrick operating system: http://derrick.xf.cz (Slovak and English :P)
rdos
Member
Member
Posts: 3330
Joined: Wed Oct 01, 2008 1:55 pm

Re: STI doesn't work

Post by rdos »

A typical problem of non-working ISRs. Could be many things, from non-existant IRQ-handllers, errors in interrupt descriptors, errors in ISR code, error in the iret (wrong type), and so on.

I would build a simple panic that lists segment registers and general purpose registers, and link it to GPF, TSS fault, stack fault, page fault.
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: STI doesn't work

Post by System123 »

Bochs jumps to the correct ISR exception code but it gets stuck in an infinite loop there. One question: fro my IRQ_common_stub I noticed that there iis no sti before iret, I put one there but it didn't solve the problem. I was just wondering if this sti must be there
Gizmic OS
Currently - Busy with FAT12 driver and VFS
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: STI doesn't work

Post by JamesM »

STI affects EFLAGS. IRET pops the new value of EFLAGS off the stack. Therefore your STI must be before you PUSHFD (race condition ahoy!) or you must pushfd, pop, OR in the IF flag, then PUSH again, in order to affect the post-IRET state.
rdos
Member
Member
Posts: 3330
Joined: Wed Oct 01, 2008 1:55 pm

Re: STI doesn't work

Post by rdos »

A possible problem might be the use of an incorrect gate in the IDT. It must be an interrupt gate, otherwise interrupts will not be disabled in the ISR code, and reentry will occur, and an infinite loop.
rdos
Member
Member
Posts: 3330
Joined: Wed Oct 01, 2008 1:55 pm

Re: STI doesn't work

Post by rdos »

JamesM wrote:STI affects EFLAGS. IRET pops the new value of EFLAGS off the stack. Therefore your STI must be before you PUSHFD (race condition ahoy!) or you must pushfd, pop, OR in the IF flag, then PUSH again, in order to affect the post-IRET state.
An sti before the iret in an ISR will not have any other affect than the possibility for accepting another interrupt. The original EFLAGS will overwrite the state of the interrupt enable bit. To modify the state one needs to modify the state on the stack since EFLAGS is not at the top (EIP is).
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: STI doesn't work

Post by System123 »

I send an EOI at the end of my irq_handler. So every function will get one after it has been handled
Gizmic OS
Currently - Busy with FAT12 driver and VFS
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: STI doesn't work

Post by JamesM »

rdos wrote:
JamesM wrote:STI affects EFLAGS. IRET pops the new value of EFLAGS off the stack. Therefore your STI must be before you PUSHFD (race condition ahoy!) or you must pushfd, pop, OR in the IF flag, then PUSH again, in order to affect the post-IRET state.
An sti before the iret in an ISR will not have any other affect than the possibility for accepting another interrupt. The original EFLAGS will overwrite the state of the interrupt enable bit. To modify the state one needs to modify the state on the stack since EFLAGS is not at the top (EIP is).
You've just repeated what I said...
geppy
Member
Member
Posts: 27
Joined: Wed Jun 11, 2008 5:30 pm

Re: STI doesn't work

Post by geppy »

System123 wrote:Yes I know I said that before hand it was working but that is because I didn't have any code after sti.
I didn't look your code but if you don't have any code after an instruction that doesn't transfer control (jump) anywhere then your PC suppose to hang and even reboot if exception handlers are absent. Description of your problem is incomplete.
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: STI doesn't work

Post by System123 »

Read all the posts!!

And it has other code to set up gdt and idt and isr... Etc

sti only executes after all those are set up else the cpu would triple fault.

By other code i meant like writting to the screen thats y my kernel appeared to work. Until i added a floppy driver which never gets initialised because nothin after sti is run. This is because the interrupts are not returning properly!
Gizmic OS
Currently - Busy with FAT12 driver and VFS
rdos
Member
Member
Posts: 3330
Joined: Wed Oct 01, 2008 1:55 pm

Re: STI doesn't work

Post by rdos »

Do you remove the cause of the floppy interrupt before you return from ISR? If not, the handler will simply reenter in an infinite loop. Have you isolated the problem to the floppy ISR (disable all other ISRs in the PIC/APIC)?
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: STI doesn't work

Post by System123 »

No it has nothing to do with the floppy the keyboard or the timer. I only noticed the problem because I added a floppy driver which initialises after sti. Even if I put a printstring command there it never executes. If I do not install and IRQ's it still doesn't get passed sti even though the PIC and ISR's are set up correctly. Look at the code in kernel.pas and you will see what I mean. Any code after sti never executes, thats why I say the interupts aren't returning.
Gizmic OS
Currently - Busy with FAT12 driver and VFS
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: STI doesn't work

Post by JamesM »

We're going in circles. Post your code.
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: STI doesn't work

Post by System123 »

Ok here is my IRQ, ISR, IDT, and KERNEL code as well as the Assembler stubs

ISR and IRQ asm stub

Code: Select all

[BITS 32]
  
%macro ISR_NOERRCODE 2  ; define a macro, taking one parameter
GLOBAL %1        ; %1 accesses the first parameter.
  %1:
    cli
    push byte 0
    push byte %2
    jmp isr_common_stub
%endmacro

%macro ISR_ERRCODE 2
GLOBAL %1
  %1:
    cli
    push byte %2
    jmp isr_common_stub
%endmacro 

ISR_NOERRCODE isr0,0
ISR_NOERRCODE isr1,1
ISR_NOERRCODE isr2,2
ISR_NOERRCODE isr3,3
ISR_NOERRCODE isr4,4
ISR_NOERRCODE isr5,5
ISR_NOERRCODE isr6,6
ISR_NOERRCODE isr7,7
ISR_ERRCODE isr8,8
ISR_NOERRCODE isr9,9
ISR_ERRCODE isr10,10
ISR_ERRCODE isr11,11
ISR_ERRCODE isr12,12
ISR_ERRCODE isr13,13
ISR_ERRCODE isr14,14
ISR_NOERRCODE isr15,15
ISR_NOERRCODE isr16,16
ISR_NOERRCODE isr17,17
ISR_NOERRCODE isr18,18
ISR_NOERRCODE isr19,19
ISR_NOERRCODE isr20,20
ISR_NOERRCODE isr21,21
ISR_NOERRCODE isr22,22
ISR_NOERRCODE isr23,23
ISR_NOERRCODE isr24,24
ISR_NOERRCODE isr25,25
ISR_NOERRCODE isr26,26
ISR_NOERRCODE isr27,27
ISR_NOERRCODE isr28,28
ISR_NOERRCODE isr29,29
ISR_NOERRCODE isr30,30
ISR_NOERRCODE isr31,31
ISR_NOERRCODE isr32,32  
 
[EXTERN isr_handler]

; This is our common ISR stub. It saves the processor state, sets
; up for kernel mode segments, calls the C-level fault handler,
; and finally restores the stack frame.
isr_common_stub:
   pusha                    ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax

   mov ax, ds               ; Lower 16-bits of eax = ds.
   push eax                 ; save the data segment descriptor

   mov ax, 0x10  ; load the kernel data segment descriptor
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   call isr_handler

   pop eax        ; reload the original data segment descriptor
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   popa                     ; Pops edi,esi,ebp...
   add esp, 8     ; Cleans up the pushed error code and pushed ISR number
   sti
   iret           ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP 
   
%macro irqmacro 2
global %1
%1:
  cli
  push byte 0
  push byte %2
  jmp  irq_common_stub
%endmacro

irqmacro irq0,32  ; 32: Timer
irqmacro irq1,33  ; 33: Keyboard
irqmacro irq2,34  ; 34: ???
irqmacro irq3,35  ; 35: ???
irqmacro irq4,36  ; 36: ???
irqmacro irq5,37  ; 37: ???
irqmacro irq6,38  ; 38: ???
irqmacro irq7,39  ; 39: ???
irqmacro irq8,40  ; 40: ???
irqmacro irq9,41  ; 41: ???
irqmacro irq10,42 ; 42: ???
irqmacro irq11,43 ; 43: ???
irqmacro irq12,44 ; 44: ???
irqmacro irq13,45 ; 45: ???
irqmacro irq14,46 ; 46: ???
irqmacro irq15,47 ; 47: ???

extern irq_handler

irq_common_stub:
  pusha

  push ds
  push es
  push fs
  push gs

  mov  ax,0x10
  mov  ds,ax
  mov  es,ax
  mov  fs,ax
  mov  gs,ax
  mov  eax,esp
  push eax

  mov  eax,irq_handler
  call eax

  pop  eax
  pop  gs
  pop  fs
  pop  es
  pop  ds

  popa
  add  esp,8
  iret
IRQ code

Code: Select all

unit irq;

interface

type
  TIRQHandler = procedure (var r : TRegisters);

const
 IRQRoutines : array[0..15] of TIRQHandler = (
    nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil,nil
    );

procedure InitIRQ;stdcall;
procedure InstallIRQHandler(const IRQNo : byte; Handler : TIRQHandler);
procedure UninstallIRQHandler(const IRQNo : byte);
procedure IRQWait(IRQNo : byte);

var
  IRQWaiting : boolean = false;
  IRQWaiter : byte;

implementation

uses IDT, console;

procedure irq0; external name 'irq0';
procedure irq1; external name 'irq1';
procedure irq2; external name 'irq2';
procedure irq3; external name 'irq3';
procedure irq4; external name 'irq4';
procedure irq5; external name 'irq5';
procedure irq6; external name 'irq6';
procedure irq7; external name 'irq7';
procedure irq8; external name 'irq8';
procedure irq9; external name 'irq9';
procedure irq10; external name 'irq10';
procedure irq11; external name 'irq11';
procedure irq12; external name 'irq12';
procedure irq13; external name 'irq13';
procedure irq14; external name 'irq14';
procedure irq15; external name 'irq15';

procedure InstallIRQHandler(const IRQNo : byte; Handler : TIRQHandler);
begin
IRQRoutines[IRQNo] := Handler;
end;

procedure UninstallIRQHandler(const IRQNo : byte);
begin
IRQRoutines[IRQNo] := nil;
end;

procedure RemapIRQ;
begin
  WritePort($20,$11);
  WritePort($A0,$11);
  WritePort($21,$20);
  WritePort($A1,$28);
  WritePort($21,$04);
  WritePort($A1,$02);
  WritePort($21,$01);
  WritePort($A1,$01);
  WritePort($21,$0);
  WritePort($A1,$0);
end;

procedure InitIRQ;stdcall;[public, alias : 'initIRQ'];
begin
PrintString(#10'Remapping the Interupt Requests (IRQ)');
RemapIRQ;
PrintString(#10'Done'#10'Initialising IRQs 0 - 15');
SetIDTGate(32,PtrUInt(@irq0),$08,$8E,false); //timer
SetIDTGate(33,PtrUInt(@irq1),$08,$8E,false); //keyboard
SetIDTGate(34,PtrUInt(@irq2),$08,$8E,false);
SetIDTGate(35,PtrUInt(@irq3),$08,$8E,false);
SetIDTGate(36,PtrUInt(@irq4),$08,$8E,false);
SetIDTGate(37,PtrUInt(@irq5),$08,$8E,false);
SetIDTGate(38,PtrUInt(@irq6),$08,$8E,false);
SetIDTGate(39,PtrUInt(@irq7),$08,$8E,false);
SetIDTGate(40,PtrUInt(@irq8),$08,$8E,false);
SetIDTGate(41,PtrUInt(@irq9),$08,$8E,false);
SetIDTGate(42,PtrUInt(@irq10),$08,$8E,false);
SetIDTGate(43,PtrUInt(@irq11),$08,$8E,false);
SetIDTGate(44,PtrUInt(@irq12),$08,$8E,false);
SetIDTGate(45,PtrUInt(@irq13),$08,$8E,false);
SetIDTGate(46,PtrUInt(@irq14),$08,$8E,false);
SetIDTGate(47,PtrUInt(@irq15),$08,$8E,false);
PrintString(#10'Done');
end;

procedure IRQWait(IRQNo : byte);
begin
IRQWaiter := IRQNo;
IRQWaiting := true;
while IRQWaiting = true do;
end;

procedure IrqHandler(var r : TRegisters); cdecl; [public, alias: 'irq_handler'];
var
  Handler : TIrqHandler = nil;
begin
Handler := IrqRoutines[r.InterruptNumber-32];

if (IRQWaiting = true) and (IRQWaiter = (r.InterruptNumber-32)) then
    IRQWaiting := false;  
    
if Assigned(Handler) then
  Handler(r);

if r.InterruptNumber >= 40 then
  WritePort($A0,$20);

  WritePort($20,$20); 
end;

end.
ISR code:

Code: Select all

unit isr;

interface

procedure InitISR;stdcall;

implementation

uses idt, console;

const
  ExceptionMessages: array [0..31] of String = (
    'Division By Zero',
    'Debug',
    'Non Maskable Interrupt',
    'Breakpoint',
    'Into Detected Overflow',
    'Out of Bounds',
    'Invalid Opcode',
    'No Coprocessor',
    'Double Fault',
    'Coprocessor Segment Overrun',
    'Bad TSS',
    'Segment Not Present',
    'Stack Fault',
    'General Protection Fault',
    'Page Fault',
    'Unknown Interrupt',
    'Coprocessor Fault',
    'Alignment Check',
    'Machine Check',
    'Reserved',
    'Reserved',
    'Reserved',
    'Reserved',
    'Reserved',
    'Reserved',
    'Reserved',
    'Reserved',
    'Reserved',
    'Reserved',
    'Reserved',
    'Reserved',
    'Reserved'
  );

procedure isr0; external name 'isr0';
procedure isr1; external name 'isr1';
procedure isr2; external name 'isr2';
procedure isr3; external name 'isr3';
procedure isr4; external name 'isr4';
procedure isr5; external name 'isr5';
procedure isr6; external name 'isr6';
procedure isr7; external name 'isr7';
procedure isr8; external name 'isr8';
procedure isr9; external name 'isr9';
procedure isr10; external name 'isr10';
procedure isr11; external name 'isr11';
procedure isr12; external name 'isr12';
procedure isr13; external name 'isr13';
procedure isr14; external name 'isr14';
procedure isr15; external name 'isr15';
procedure isr16; external name 'isr16';
procedure isr17; external name 'isr17';
procedure isr18; external name 'isr18';
procedure isr19; external name 'isr19';
procedure isr20; external name 'isr20';
procedure isr21; external name 'isr21';
procedure isr22; external name 'isr22';
procedure isr23; external name 'isr23';
procedure isr24; external name 'isr24';
procedure isr25; external name 'isr25';
procedure isr26; external name 'isr26';
procedure isr27; external name 'isr27';
procedure isr28; external name 'isr28';
procedure isr29; external name 'isr29';
procedure isr30; external name 'isr30';
procedure isr31; external name 'isr31';

procedure InitISR; stdcall;[public, alias: 'initISR'];
begin
 // PrintString(#10'Initalising Interupt Service Requests (ISR)');
  SetIDTGate(0,PtrUInt(@isr0),$08,$8E,false);
  SetIDTGate(1,PtrUInt(@isr1),$08,$8E,false);
  SetIDTGate(2,PtrUInt(@isr2),$08,$8E,false);
  SetIDTGate(3,PtrUInt(@isr3),$08,$8E,false);
  SetIDTGate(4,PtrUInt(@isr4),$08,$8E,false);
  SetIDTGate(5,PtrUInt(@isr5),$08,$8E,false);
  SetIDTGate(6,PtrUInt(@isr6),$08,$8E,false);
  SetIDTGate(7,PtrUInt(@isr7),$08,$8E,false);
  SetIDTGate(8,PtrUInt(@isr8),$08,$8E,false);
  SetIDTGate(9,PtrUInt(@isr9),$08,$8E,false);
  SetIDTGate(10,PtrUInt(@isr10),$08,$8E,false);
  SetIDTGate(11,PtrUInt(@isr11),$08,$8E,false);
  SetIDTGate(12,PtrUInt(@isr12),$08,$8E,false);
  SetIDTGate(13,PtrUInt(@isr13),$08,$8E,false);
  SetIDTGate(14,PtrUInt(@isr14),$08,$8E,false);
  SetIDTGate(15,PtrUInt(@isr15),$08,$8E,false);
  SetIDTGate(16,PtrUInt(@isr16),$08,$8E,false);
  SetIDTGate(17,PtrUInt(@isr17),$08,$8E,false);
  SetIDTGate(18,PtrUInt(@isr18),$08,$8E,false);
  SetIDTGate(19,PtrUInt(@isr19),$08,$8E,false);
  SetIDTGate(20,PtrUInt(@isr20),$08,$8E,false);
  SetIDTGate(21,PtrUInt(@isr21),$08,$8E,false);
  SetIDTGate(22,PtrUInt(@isr22),$08,$8E,false);
  SetIDTGate(23,PtrUInt(@isr23),$08,$8E,false);
  SetIDTGate(24,PtrUInt(@isr24),$08,$8E,false);
  SetIDTGate(25,PtrUInt(@isr25),$08,$8E,false);
  SetIDTGate(26,PtrUInt(@isr26),$08,$8E,false);
  SetIDTGate(27,PtrUInt(@isr27),$08,$8E,false);
  SetIDTGate(28,PtrUInt(@isr28),$08,$8E,false);
  SetIDTGate(29,PtrUInt(@isr29),$08,$8E,false);
  SetIDTGate(30,PtrUInt(@isr30),$08,$8E,false);
  SetIDTGate(31,PtrUInt(@isr31),$08,$8E,false);
 // PrintString(#10'Done');
end;

procedure ISR_Handler(var r: TRegisters); cdecl; [public, alias: 'isr_handler'];
var
s : string;
begin
  if r.InterruptNumber < 32 then begin
    SetTextColor(clBlack,clRed);
    PrintChar(#10);
    PrintString(ExceptionMessages[r.InterruptNumber]);
    PrintString(' Exception');

    with r do begin
      Str(ErrorCode, s);
      PrintString(#10'Error code = ');PrintString(s);
      PrintString(#10'EAX'#9'= $');PrintString(HexStr(eax,8));
      PrintString(#10'EBX'#9'= $');PrintString(HexStr(ebx,8));
      PrintString(#10'ECX'#9'= $');PrintString(HexStr(ecx,8));
      PrintString(#10'EDX'#9'= $');PrintString(HexStr(edx,8));
      PrintString(#10'ESI'#9'= $');PrintString(HexStr(esi,8));
      PrintString(#10'EDI'#9'= $');PrintString(HexStr(edi,8));
      PrintString(#10'ESP'#9'= $');PrintString(HexStr(esp,8));
      PrintString(#10'EBP'#9'= $');PrintString(HexStr(ebp,8));
      PrintString(#10'CS'#9'= $');PrintString(HexStr(cs,8));
      PrintString(#10'DS'#9'= $');PrintString(HexStr(ds,8));
      PrintString(#10'ES'#9'= $');PrintString(HexStr(es,8));
      PrintString(#10'FS'#9'= $');PrintString(HexStr(fs,8));
      PrintString(#10'GS'#9'= $');PrintString(HexStr(gs,8));
      PrintString(#10'SS'#9'= $');PrintString(HexStr(ss,8));
      PrintString(#10'EIP'#9'= $');PrintString(HexStr(eip,8));
      PrintString(#10'EFLAGS'#9'= $');PrintString(HexStr(eflags,8));
      PrintString(#10'User ESP'#9'= $');PrintString(HexStr(UserESP,8));
    end;
    SetTextColor(clBlack,clWhite);
    PrintChar(#10);
    while true do ;
  end;   
end;

end.
IDT code

Code: Select all

unit idt;

interface

type
  TIDTEntry = packed record
  BaseLow : word;
  SegSel : word;
  Always0 : byte;
  Flags : byte;
  BaseHigh : word;
  end;

  TIDTPtr = packed record
  limit : word;
  base : LongWord;
  end;

var
IDTPtr : TIDTPtr;
IDTTables : array[0..255] of TIDTEntry;

procedure SetIDTGate(idx: Byte; base: LongWord; SSelect: Word; flg: Byte; UserMode : boolean);
procedure initIDT;stdcall;

implementation

uses console;

procedure FlushIDT; assembler; nostackframe;
asm
  lidt IDTPtr
end;

procedure SetIDTGate(idx: Byte; base: LongWord; SSelect: Word; flg: Byte; UserMode : boolean);
begin
with IDTTables[idx] do
  begin
  BaseLow := base and $FFFF;
  BaseHigh := (base shr 16) and $FFFF;

  SegSel := SSelect;
  Always0 := 0;

  if UserMode = true then
    Flags := flg or $60
  else
    Flags := flg;
  end;
end;

procedure initIDT;stdcall;[public, alias: 'initIDT'];
begin
//PrintString(#10'Initialising the Interupt Descriptor Table (IDT)');
IDTPtr.limit := SizeOf(IDTTables)-1;
IDTPtr.base := PtrUInt(@IDTTables);

FillByte(IDTTables,SizeOf(IDTTables),0);
FlushIDT;
//PrintString(#10'Done');
end;

end.
Kernel Code

Code: Select all

unit kernel;

interface

procedure kmain; stdcall;

implementation

uses console, idt, gdt, isr, irq, pit, keyboard, paging{, heap, DMA, Sound}, Floppy {,ConsoleEXP};

Const
  kHeader = 'GIZMIC OS v0.01';
  kHeaderBg = clBlue;
  kHeaderFg = clWhite;

procedure kmain; stdcall;[public, alias: 'kmain'];
var
sTemp : string;
i, x : byte;
begin

initScreen;
SetTextColor(clBlack,clLightGreen);
initGDT;
initIDT;
initISR;
initIRQ;
initTimer(100);
initKeyboard;
initPaging(1000000);
PrintString('STI - Start');
asm
sti
end;
PrintString(#10'STI - done');

//dmainit;
//initFloppy;

SetTextColor(clBlack,clWhite);
ClearScreen;
GoToXY(0,0); 
SetTextColor(clBlue,clWhite);
PrintString(kHeader + #10);
SetTextColor(clBlack,clWhite);
SetHeader(true);  

{i := 0;
x := 122323 div i; }

while true do ;  
end;

end.
I hope this can help.
Gizmic OS
Currently - Busy with FAT12 driver and VFS
ru2aqare
Member
Member
Posts: 342
Joined: Fri Jul 11, 2008 5:15 am
Location: Hungary

Re: STI doesn't work

Post by ru2aqare »

Code: Select all

  
%macro ISR_NOERRCODE 2  ; define a macro, taking one parameter
GLOBAL %1        ; %1 accesses the first parameter.
  %1:
    cli
    push byte 0
    push byte %2
    jmp isr_common_stub
%endmacro
I don't think that cli is necessary - as far as I know, the CPU automatically clears IF when an interrupt is executed.

Code: Select all

; This is our common ISR stub. It saves the processor state, sets
; up for kernel mode segments, calls the C-level fault handler,
; and finally restores the stack frame.
isr_common_stub:
   pusha                    ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
I'm not familiar with the nasm syntax, but shouldn't that be pushad?

Code: Select all

   popa                     ; Pops edi,esi,ebp...
   add esp, 8     ; Cleans up the pushed error code and pushed ISR number
   sti
   iret           ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP 
Shouldn't that be iretd? Also the sti is not required - executing an iretd restores the IF to its previous state.
Post Reply