Page 1 of 2

sti! ... and nothing happens

Posted: Thu Oct 10, 2002 3:04 pm
by dronkit
Hello,

There's something strange about this.

First I load a good ldt (i know it's good because i tried an
'int' instruction by hand).

Then, I program the 8259 to remap irq's to ints 0x20-0x2F
and unmask all 16 irq's.

Then I "sti"... but get no interrupts at all. Not even the
system clock.

Obviously I must be doing something wrong because the same
happens in both vmware and bochs ;)

I also tried to "sti" right after going into pmode (before
loading my ldt, thus using the default one at 0x0) just to see
things crashing... but again, NOTHING HAPPENED!

is it possible to "sti" and still get no interrupts at all?
The answer to me is "yes" if you mess with the pic and
not enable the interrupts later... but i tried both things

(to "sti" after programming the pic and *before* doing anything with idt and the pic).

I'm kinda lost on this one ;)

Thanks in advance!

Re:sti! ... and nothing happens

Posted: Thu Oct 10, 2002 3:30 pm
by .bdjames
Try it on a real machine, it will crash. Bochs is liberal in this
area.

Re:sti! ... and nothing happens

Posted: Thu Oct 10, 2002 3:44 pm
by Tom
you can't use BIOS int's with just a IDT, you need [glow=red][shadow]V86 MODE[/shadow][/glow]

Re:sti! ... and nothing happens

Posted: Thu Oct 10, 2002 3:53 pm
by dronkit
who said anything about the bios?

I'm taling about **hardware** interrupts, here...

Re:sti! ... and nothing happens

Posted: Fri Oct 11, 2002 12:22 am
by Whatever5k
Did you setup Interrupt Service Routines (ISR) for the IRQs you want to get? For example for the system clock. What does the interrupt handler do?
Show us the code for the setup and the interrupt handler itself, please...
best regards,
A. Blessing

Re:sti! ... and nothing happens

Posted: Fri Oct 11, 2002 10:11 am
by dronkit
I first setup all 256 interrupts to a generic handler that only "iret" to the caller.

Code: Select all

/*
 * This is for unhandled interrupts.
 */ 
.p2align 4, 0x90
int_unhandled:
???iret
Then i setup interrupts from 0-19h with exception handlers and then interrupts 20h-2Fh with my irq handlers (the pic is programmed so i redirect irq 0 to int 20h, etc).

Code: Select all

/*
 * Generic code for every irq handler.
 */
#define???IRQ_ENTRY(N) \
???.p2align 4, 0x90; \
???cli; \
???pushl %ebp; \
???movl %esp, %ebp; \
???pushl $N; \
???call irq_handler; \
???addl $4, %esp; \
???sti; \
???leave; \
???iret

irq_00: IRQ_ENTRY(0x0)
irq_01: IRQ_ENTRY(0x1)
irq_02: IRQ_ENTRY(0x2)
irq_03: IRQ_ENTRY(0x3)
irq_04: IRQ_ENTRY(0x4)
irq_05: IRQ_ENTRY(0x5)
irq_06: IRQ_ENTRY(0x6)
irq_07: IRQ_ENTRY(0x7)
irq_08: IRQ_ENTRY(0x8)
irq_09: IRQ_ENTRY(0x9)
irq_0a: IRQ_ENTRY(0xa)
irq_0b: IRQ_ENTRY(0xb)
irq_0c: IRQ_ENTRY(0xc)
irq_0d: IRQ_ENTRY(0xd)
irq_0e: IRQ_ENTRY(0xe)
irq_0f: IRQ_ENTRY(0xf)


/*
 * After basic setup, each irq handler calls this code which then
 * calls the real irq handler in C.
 */
.p2align 4, 0x90
irq_handler:
???pushl %ebp
???movl %esp, %ebp
???pusha
???movl 8(%ebp), %eax
???pushl %eax
???sti
???call interrupt_handler
???cli
???addl $4, %esp
???popa
???leave
???ret

void
interrupt_handler(exception_num e)
{
???kprintf("Interrupt #%d: called\n", e);
???intr_eoi(e);
???return;
}

/*
 * sends a EOI to the PICs involved in the IRQ operation
 */
void
intr_eoi(int irq)
{
   if (irq > 7)
      outb(I8259_SLV_CTRL, 0x20);
   outb(I8259_MSTR_CTRL, 0x20);
}
Anyway... it should work or crash for every system clock interrupt once I "sti".... but nothing happens! ;)

The idt setup is fine. I setup my sys trap gate at 0x80, then do by hand an "int $0x80". the call is successfully made.
Thanks.

P.S: .bdjames: What do you mean "bochs is liberal"?

Re:sti! ... and nothing happens

Posted: Fri Oct 11, 2002 11:01 am
by Whatever5k
You should push all registers in the ISR (you do that, fine) - and you should load the segments with a good value, i.e. the data selector. Something like this:

Code: Select all

pushad
mov eax, DS_SELECTOR
mov ds, eax
mov fs, eax
mov gs, eax
mov es, eax
Also, I cannot quite understand why you do:

Code: Select all

sti
call interrupt_handler
cli
This isn't very wise because then another IRQ could occur and it would mess...better remove it...
Try this and tell us what happens...
btw, do you try your kernel with Bochs or on real hardware?

Re:sti! ... and nothing happens

Posted: Fri Oct 11, 2002 11:35 am
by dronkit
you're right, but i'm not worrying about ds and ss yet because it's all in ring 0, at kernel level, and without any tasks yet. it's still a very young kernel, so i'm doing things as i need them ;)

anyway, i tried the code in both vmware and bochs. they should *at least* crash.. but it seems that there's something else wrong... I don't get *any* interrupts at all....

Re:sti! ... and nothing happens

Posted: Fri Oct 11, 2002 11:39 am
by Whatever5k
Well, Bochs is not perfect. It often sucks with my kernel (it works three times, fourth times, it sucks)...but my kernel always works on real hardware...
So did you try your code in real hardware?

And anyway, I would worry about the DS_SELECTOR stuff...implement it *now*, so you have it done and don't forget it...it's really not difficult to write 4-5 lines ;)

Re:sti! ... and nothing happens

Posted: Fri Oct 11, 2002 11:54 am
by dronkit
uh oh.... ok ;)

i'll try it on real hardware and get back to you.

Anyway, can vmware and bochs behave the same way and not be a bug in my code?

Re:sti! ... and nothing happens

Posted: Fri Oct 11, 2002 5:58 pm
by dronkit
Well, i tried it on real hardware. If I "sti" right before "call"ing my kernel, it triple faults, like it should be.

On the other hand, if I "sti" from my C kernel code, nothing
happens... mm what should i look for?

here's my enable_intr() routine, the one i call from C code:

Code: Select all

#define   ALIGN_TEXT               .p2align 4, 0x90
#define   CNAME(x)                  x
#define   SECTION_CODE            .text

#define   MY_ASM_FUNCTION(x)      SECTION_CODE; ALIGN_TEXT; \
                                 .globl CNAME(x); \
                                 .type CNAME(x),@function; CNAME(x): \
                                 pushl %ebp; \
                                 movl %esp, %ebp
MY_ASM_FUNCTION(enable_intr)
   sti
   leave
   ret

Re:sti! ... and nothing happens

Posted: Sat Oct 12, 2002 2:50 am
by Whatever5k
Hm, I think I'll have to see the entire code...
could you zip or tar it (depends on which OS you are using) and upload it on a server so that I can download it?

Re:sti! ... and nothing happens

Posted: Wed Oct 16, 2002 11:18 am
by dronkit
Well, I guess I found the bug.

I have a file called exception.S which has the asm stub code for every
interrupt/trap gate/exception in the kernel. This is linked along with the kernel.

In this file I declare all functions (irq_xx and ex_xx) to be .globl and
then declare them "extern void irq_xx(void) and extern void ex_xx(void)"

Apparently, when I do this:

Code: Select all

/* Finally, these will be our handlers for all ints & exceptions. */
isr_t *isr[ISR_TOTAL] = {
   /* exception handlers. */
   ex_00, ex_01, ex_02, ex_03, ex_04, ex_05, ex_06, ex_07,
   ex_08, ex_09, ex_0a, ex_0b, ex_0c, ex_0d, ex_0e, ex_0f,
   ex_10, ex_11, ex_12, ex_13, ex_14, ex_15, ex_16, ex_17,
   ex_18, ex_19, ex_1a, ex_1b, ex_1c, ex_1d, ex_1e, ex_1f,
   /* irq handlers. */
   irq_00, irq_01, irq_02, irq_03, irq_04, irq_05, irq_06, irq_07,
   irq_08, irq_09, irq_0a, irq_0b, irq_0c, irq_0d, irq_0e, irq_0f
};
and then

Code: Select all

for(i = 0; i < ISR_TOTAL; i++)
    (void)idt_set(i, isr[i], 0x8f);
All irq_xx and ex_xx functions have an address of "0"...

I'm using other asm functions from other files with no problems...so i don't know what could be the error, but I'm sure it has something to do with the linking stage or my function definitions ... :P

I get no errors at linking time and I defined my functions .globl....

what else do i need to check? ;)

Re:sti! ... and nothing happens

Posted: Wed Oct 16, 2002 11:23 am
by Whatever5k
What is isr_t for a type? void*?
Try this here:

Code: Select all

for (...)
  set_idt(i, *isr[i], ..);

Re:sti! ... and nothing happens

Posted: Wed Oct 16, 2002 11:48 am
by dronkit
just a function that does not return anything

Code: Select all

typedef void (isr_t)(void);