Page 1 of 1

Interrupt procedure modifier - Can I get the saved register

Posted: Wed Apr 06, 2005 9:12 pm
by Crazed123
I'm using FreePascal with an interrupt "calling convention" to write ISRs. This works fine except that the saved register values, which are normally accesible to the ISR, are simply pushed on the stack frame in a format unknown to me. I've looked in the compiler source and found the format, but I'm worried about this making me dependent upon the particular version and compiler that I'm writing for. I really only want to know the eip and general registers at the time it happened in order to display some general exception information in my handler so far, maybe some more useful things later. Any ideas what I could do?

Re:Interrupt procedure modifier - Can I get the saved regist

Posted: Thu Apr 07, 2005 4:30 am
by Kim
Don't use freepascals interrupt option...
Just use nasm or as, and write the stub code in asm and then let the asm routine jmp to your pascal code...

Example:

Code: Select all

[bits 32]

[extern kisr_exception] ;pascal code

[global kisr_exp0] ;export this one so you can set the pointers in the idt table in your pascal code

kisr_exp0:
   push 0
   push 0
   jmp kisr_exception_stub

kisr_exception_stub:
   pusha
   push ds
       push es
       push fs
       push gs
       mov ax, ss
       mov ds, ax
       mov es, ax
       mov fs, ax
       mov gs, ax
       push esp
       call kisr_exception
       pop gs
       pop fs
       pop es
       pop ds
   popa
   add esp, 8
   iret

procedure kisr_exception(regs: Pisr_exp_regs); stdcall; [public, alias: 'kisr_exception'];

type
   Pisr_exp_regs = ^isr_exp_regs_t;
   isr_exp_regs_t = packed record
     ds, es, fs, gs: DWORD;
     edi, esi, ebp, esp, ebx, edx, ecx, eax: DWORD;
     intr_idx, error_code: DWORD;
     syseip, syscs, syseflags, sysesp, sysss: DWORD;
   end;

Re:Interrupt procedure modifier - Can I get the saved regist

Posted: Thu Apr 07, 2005 1:02 pm
by Crazed123
Is there a place I could save the error code before pushing a regs structure so that if it was present I could proceed to add the error code to the top of the stack after that?

Re:Interrupt procedure modifier - Can I get the saved regist

Posted: Thu Apr 07, 2005 3:28 pm
by Crazed123
Whatever. Gonna go with your method and ask the FPC guys if they could fix all this.

Wait a minute, how do I link FreePascal's RTL without invoking FPC itself to link?

Re:Interrupt procedure modifier - Can I get the saved regist

Posted: Fri Apr 08, 2005 5:59 am
by Kim
I build my small kernel like this:

Code: Select all

cd .\kernel
..\bin\nasm -f elf stub.asm -o ..\output\obj\stub.o
..\bin\nasm -f elf _isr.asm -o ..\output\obj\_isr.o
..\bin\ppc386 -Aelf -FE..\output\obj -Fi.\include -Fu.\support -n -OG3p3 -Si -Sc -Sg -Xd -Rintel -Tlinux kernel.pas
..\bin\ld -T kernel.ld -o ..\output\kernel\kernel.elf ..\output\obj\stub.o ..\output\obj\console.o ..\output\obj\gdt.o ..\output\obj\idt.o ..\output\obj\isr.o ..\output\obj\_isr.o ..\output\obj\pic.o ..\output\obj\io.o ..\output\obj\timer.o ..\output\obj\keyb.o ..\output\obj\keymaps.o ..\output\obj\memory.o ..\output\obj\paging.o ..\output\obj\bochs_debug.o ..\output\obj\kernel.o
cd ..
.\bin\strip .\output\kernel\kernel.elf
pause
Only thing freepascal needs is a system unit with the standard type defines... but then you shouldn't use pascal's string type, pchar will do just fine :)

Re:Interrupt procedure modifier - Can I get the saved regist

Posted: Fri Apr 08, 2005 1:34 pm
by Crazed123
Why not use FPC's string type? I've hooked the RTL into my own heap routines.

Also, shouldn't there be some sort of Black Magic to access the stack and get the values from an interrupt procedure? As I've tried to implement your method I've found it excessively redundant. Is there any other method that C kernels use?

I added that bit on the "nostackframe" modifier myself, and will use it.

Re:Interrupt procedure modifier - Can I get the saved regist

Posted: Mon Apr 11, 2005 10:20 am
by Kim

Code: Select all

+ 4 = old ebx
+ 8 = old eax
+ 12 = ret addr
+ 16 = first stack item

procedure test; stdcall; assembler;
asm
mov eax, esp
push eax
push ebx
mov ebx, [eax + 16]
mov firstitem, ebx
mov ebx, [eax + 20]
mov secitem, ebx
...
pop ebx
pop eax
end;