Page 1 of 1

IDT Loading in C

Posted: Tue Aug 12, 2003 3:06 am
by Therx
In my previous OSes I've always loaded the IDT from assembly and routed all the ints through one global handler which sorted them out but this time I'd like to use the IDT through C and my code doesn't work. I think I've loaded my IDT right because the code doesn't reboot when I leave my IRQ0 handler blank. I know you have to push everything and then pop it and my old assembly code did this fine but whenever I try and transfer it into inline it doesn't work. I think this is down to my lack of experience with AT&T. With the -masm=intel option described in another post I could leave the operands the "right" way round and leave off the % on the registers couldn't I. I'll try that now. Any other ideas or example code?

Thanks

Pete

Re:IDT Loading in C

Posted: Tue Aug 12, 2003 3:54 am
by Pype.Clicker
to be honest, i never dared to move my IDT setup code to C because of the kind of reasons you're evoking.

Having inline assembly for ISR prolog & epilog is not (imho) a good idea at all, because you cannot prevent the compiler to add its *own* prolog/epilog and you cannot (afaik) control what's put in it...

this means if you do something like

Code: Select all

isr_timer() {
     asm("pushad;push %%ds; push %%es");
     kprint("*clock*\n");
     outb(0x20,0x20);
     asm("pop %%es; pop %%ds; popad");
     asm("iretd");
}
the compiler may be issuing

Code: Select all

isr_timer:
     push ebp
     mov ebp,esp
     pushad
     ....
     popad
     iretd
     mov esp,ebp
     pop ebp
     ret
which is obviously wrong :-p

note that according to "info gcc, optimize options", you could do
-fomit-frame-pointer'
Don't keep the frame pointer in a register for functions that
don't need one. This avoids the instructions to save, set up and
restore frame pointers; it also makes an extra register available
in many functions. *It also makes debugging impossible on some
machines.*
and hope it will solve your problem. Your ISR may not have any argument or local variable if you want that trick to work (imho -- never tried) and it sounds *very* hackish to my limited senses ... but if you really want to give it a try ...

Re:IDT Loading in C

Posted: Tue Aug 12, 2003 4:04 am
by Therx
The reason I've switched is that I need to have the task scheduler as the real ISR. Before I had a NASM macro which I used to make all the stubs which did all the pushing, poping,etc and then pushed the INT number onto the stack and called a generic C function int_hand(int intno);. But now with the Page Fault Handler, Task Scheduler etc. I need to go direct.

Re:IDT Loading in C

Posted: Tue Aug 12, 2003 4:11 am
by Pype.Clicker
why so ?? the "page fault" can be processed like any other interrupt (i do it) and the task switching (even software stack-switch) can be handled by a "stack_switc()" function called from the C-based ISR handler rather than relying on some dark magic performed by the stub (like expecting the handler to return the new ESP value or something like this ...)

Re:IDT Loading in C

Posted: Tue Aug 12, 2003 4:17 am
by Therx
The way I want to do task switching is quicker because it doesn't store everything. Just the ESP. On entering the ISR it will push everything to the stack and then store the ESP value. Then it will restore the ESP value for a different task and pop everything off the stack.

For more info read my OS Plans thread.

Pete

Re:IDT Loading in C

Posted: Tue Aug 12, 2003 7:48 am
by Therx
Ok I've transfered it back to assembly but as I don't want them all going through the same function (3 different handlers - exceptions, irqs and scheduler) I've had to change it a bit. And it doesn't work yet doesn't crash. I think I've got the entries a bit out of place by one but I'm not sure. I have attached the assembly file (NASM). Please could someone check my numbers. AFAIK there are 32 exceptions 0->31, 16 IRQs which I want mapped straight after the exceptions 32->48, but the task switcher takes IRQ0 (32). All numbers in decimal

Any help would be much appreciated.

Thanks

Pete

[attachment deleted by admin]

Re:IDT Loading in C

Posted: Tue Aug 12, 2003 11:08 am
by nullify
You can use a macro to automatically set up the stub and wrap your C handler.

Code: Select all

/* eg. for a non-errorcode exception handler */
#define END_EXC(func) \
   void excstub_##func(void); \
   asm(".text\n" \
      ".globl excstub_" #func "\n" \
      "excstub_" #func ":\n" \
      "   pusha\n" \
      "   call " #func "\n" \
      "   popa\n" \
      "   iret")

/* then when define your ISR... */

void exception0(void)
{
    kprintf("Divide by zero.");
} END_EXC(exception0);

/* when you set the IDT entry, every handler's stub name is prefixed by 'excstub_' */

set_idt_entry(0, excstub_exception0);

Re:IDT Loading in C

Posted: Tue Aug 12, 2003 11:44 am
by Candy
To be very honest, as far as I have seen (GCC 2.95.3 and 3.1/3.2) they all use push ebp; mov ebp, esp ....... leave; ret to start/leave a function. If you could replace the leave/ret with a leave/iret you would be all set. Because dead code is no real concern, just add the leave/iret before the leave/ret.

In result, before compilation:

Code: Select all

int bla() {
    // something
    i++;
    asm ("leave; iret");
}
and after compilation:

Code: Select all

bla:
  push %ebp
  mov %esp, %ebp
  ; do the i++ thing

  leave
  iret

  leave
  ret
which, at least in my case, has worked each time I tried it.

Re:IDT Loading in C

Posted: Tue Aug 12, 2003 12:16 pm
by Therx
Ok it was no bug with the IDT but with my test code.

Why doesn't:-

Code: Select all

while(1)
   *vidmem++;
work for making the top left character rotate, when

Code: Select all

char temp;
while(1){
   temp++;
   *vidmem = temp;
}
works perfectly?

Pete

Re:IDT Loading in C

Posted: Tue Aug 12, 2003 12:41 pm
by Candy
try using (*vidmem)++. The ++ operator has precedence over the * operator

Re:IDT Loading in C

Posted: Tue Aug 12, 2003 1:23 pm
by Solar
...that's why you should always use parantheses in compound statements, even if you (think you) are sure about operator precedence. Helps with reading, too. ;-)