Page 2 of 2

Re:Unmapping IRQs causes panic.

Posted: Sun Aug 24, 2003 11:03 am
by TheChuckster
timer.c

Code: Select all

extern timer_counter;

#define byte unsigned char
#define dword unsigned int

#define bool byte
#define true 1
#define false 0

#define NULL 0x0

#define SUCCESS 1
#define FAIL 0

#define PIC1 0x20
#define PIC2 0xA0

#define ICW1 0x11
#define ICW4 0x01

#define ALL       0xFF
#define TIMER     0
#define KEYBOARD  1
#define CASCADE   2
#define COM2_4    3
#define COM1_3    4
#define LPT       5
#define FLOPPY    6
#define FREE7     7
#define CLOCK     8
#define FREE9     9
#define FREE10    10
#define FREE11    11
#define PS2MOUSE  12
#define COPROC    13
#define IDE_1     14
#define IDE_2     15

#define MASTER          0x20
#define MASTERDATA      0x21
#define SLAVE           0xA0
#define SLAVEDATA       0xA1
#define EOI             0x20

#define ICW1_INIT    0x10               // required for PIC initialisation
#define ICW1_EDGE    0x08               // edge triggered IRQs
#define ICW1_SINGLE  0x02               // only MASTER (not cascaded)
#define   ICW1_ICW4    0x01               // there IS an ICW4 control word

#define ICW4_SFNM    0x10               // Special Fully Nested Mode
#define ICW4_BUFFER  0x08               // Buffered Mode
#define ICW4_MASTER  0x04               // this is the Master PIC
#define ICW4_AEOI    0x02               // Auto EOI
#define ICW4_8086    0x01               // 80/86 Mode

void changeISR(unsigned int, void *);
void int_irq1(void);

/* init_pics()
 * init the PICs and remap them
 */
void init_pics(int pic1, int pic2)
{
   byte md,sd;

   md=inportb(MASTERDATA);                     // save state of MASTER DATA
   sd=inportb(SLAVEDATA);                      // save state of SLAVE DATA

   outportb(MASTER, EOI);                      // Send EOI | resets the chip

   outportb(MASTER, ICW1_INIT+ICW1_ICW4);      // ICW1 control word setup | just basic PIC stuff
   outportb(SLAVE, ICW1_INIT+ICW1_ICW4);       // see pic.h for more details about the values

   outportb(MASTERDATA, pic1);                 // ICW2 maps IRQs 0-7 to whatever kernel passes
   outportb(SLAVEDATA, pic2);                  // and same here except with IRQs 8-15 

   outportb(MASTERDATA, 0x04);                 // ICW3 
   outportb(SLAVEDATA, 0x02);

   outportb(MASTERDATA, ICW4_8086);            // ICW4 control word setup
   outportb(SLAVEDATA, ICW4_8086);

   outportb(MASTERDATA,md);                    // restore both MASTER DATA
   outportb(SLAVEDATA,sd);                     // restore SLAVE DATA
}

/* makes IRQ unavailable so it can't fire an interrupt */
void maskIRQ(byte irq)
{
   if(irq==ALL)
   {
      outportb(MASTERDATA,0xFF);
      outportb(SLAVEDATA,0xFF);
   }
   else
   {
      irq = irq | (1<<irq);
      if(irq < 8)
         outportb(MASTERDATA, irq&0xFF);
      else
         outportb(SLAVEDATA, irq>>8);
   }
}

/* opposite of above */
void unmaskIRQ(byte irq)
{
  byte picirq_m, picirq_s;
  if(irq > 7){
      picirq_m = 1 << 2;    //Cascade
      irq -= 8;
      picirq_s = 1 << irq;
  }else{
      picirq_m = 1 << irq;
  }

  picirq_m = ~picirq_m;
  picirq_s = ~picirq_s;

  outportb(MASTERDATA, picirq_m & inportb(MASTERDATA));
  outportb(SLAVEDATA, picirq_s & inportb(SLAVEDATA));
}

 /* enables/disables software interrupts */
void INTS(bool on)
{
   if(on)
   {
      asm("sti");
   }
   else
   {
      asm("cli");
   }
}
kernel_start.asm (the important part):

Code: Select all

[extern _testint]
[global _int32]

_int32:
        push    ds
        push    es                      ; saving segment registers and
        pushad                          ; other regs because it's an ISR
        mov     bx, 10h
        mov     ds, bx
        mov     es, bx                  ; load ds and es with valid selector
        call    _testint          ; call actual ISR code
        popad                           ; restoring the regs
        pop     es
        pop     ds
        iretd

Re:Unmapping IRQs causes panic.

Posted: Sun Aug 24, 2003 1:45 pm
by TheChuckster
Wow... no one knows what's wrong? :o Maybe I'll have to do another complete rewrite.

Re:Unmapping IRQs causes panic.

Posted: Sun Aug 24, 2003 2:18 pm
by Therx
No you don't need to do a complete rewrite!!!

The problem is probally in the assembly stub. Maybe you need to do a:-

mov ss, bx

as well as the other selector moves.

Don't lose heart everyone makes mistakes ;)

Pete

Re:Unmapping IRQs causes panic.

Posted: Sun Aug 24, 2003 2:40 pm
by TheChuckster
Nope that's not the problem. :(

Re:Unmapping IRQs causes panic.

Posted: Sun Aug 24, 2003 3:13 pm
by Therx
If it is a problem with the data/stack segments then this code for the C ISR will tell. If this works then that's your problem if it doesn't then...

Code: Select all


unsigned char *vidmem = 0xB8000;

void testint(void)
{
   (*vidmem)++;
   inportb(0x60);      //Acknoledge keyboard
   outportb(0x20, 0x20);
}
This doesn't use the stack (your kprintf probally does) so won't err if there's a problem with the data or stack selectors.

Pete

Re:Unmapping IRQs causes panic.

Posted: Sun Aug 24, 2003 3:20 pm
by TheChuckster
Still panics. :-[ FFS!!! All I want is an ISR......

Have you tried looking at my code in the previous posts?

Re:Unmapping IRQs causes panic.

Posted: Tue Aug 26, 2003 2:38 am
by Therx
What happens if you don't unmask IRQs and do asm("int 0x20"); if that works then try changing your init_pics function. I think you've got more code than you need in that function. Try the following (masks all IRQs)

Code: Select all

void init_pics(int pic1, int pic2)
{
   outportb(MASTER, ICW1_INIT+ICW1_ICW4);      // ICW1 control word setup | just basic PIC stuff
   outportb(SLAVE, ICW1_INIT+ICW1_ICW4);      // see pic.h for more details about the values

   outportb(MASTERDATA, pic1);                // ICW2 maps IRQs 0-7 to whatever kernel passes
   outportb(SLAVEDATA, pic2);                  // and same here except with IRQs 8-15 

   outportb(MASTERDATA, 0x04);                // ICW3 
   outportb(SLAVEDATA, 0x02);

   outportb(MASTERDATA, ICW4_8086);            // ICW4 control word setup
   outportb(SLAVEDATA, ICW4_8086);

   outportb(MASTERDATA,0xFF);                    // mask everything
   outportb(SLAVEDATA,0xFF);              
}
Pete

Re:Unmapping IRQs causes panic.

Posted: Tue Aug 26, 2003 2:57 am
by Pype.Clicker
if i were you, i would program a EXC13 handler which will be able to catch your error and give you more detailed info on what's wrong rather than letting BOCHS panic ...

Another thing you might find useful is to run BOCHS with the internal debugger and show register states after the panic (or even tracing the execution flow) ... See "Bochs survival kit" post in .:QuickLinkz:. for details ...

Re:Unmapping IRQs causes panic.

Posted: Tue Aug 26, 2003 7:54 am
by HOS
Another thing i noticed:

Code: Select all

IDTR.limit  = 256*(sizeof(x86_interrupt)-1);
this is multiplying 256 by one less than the size of x86_interrupt - you might want to do

Code: Select all

IDTR.limit  = 256*(sizeof(x86_interrupt))-1;
instead to have the correct limit. however, i dont think that this is what is causing a panic...

Re:Unmapping IRQs causes panic.

Posted: Tue Aug 26, 2003 5:12 pm
by TheChuckster
I tried your suggestion Pete and I got the following error when I called the interrupt by using asm("int $20");

Event type: PANIC
Device: [CPU ]
Message: prefecth: running in bogus memory

This is weird...

Re:Unmapping IRQs causes panic.

Posted: Tue Aug 26, 2003 9:06 pm
by Curufir

Code: Select all

    IDT[number].low_offset  = (offset & 0xFFFF);
    IDT[number].selector    = selector;
    IDT[number].settings    = settings;
    IDT[number].high_offset  = (offset >> 16);
Shot in the dark because I'm bad at C, but does C automatically cast those offsets from a 32-bit unsigned integer into an unsigned short when you fill the structure (Assuming I read your dword and word definitions properly)?

Re:Unmapping IRQs causes panic.

Posted: Wed Aug 27, 2003 1:32 am
by Pype.Clicker
TheChuckster wrote: Message: prefecth: running in bogus memory
This is typical from an eip value that is invalid (i.e. sent to WasteLands of Uninitialized Memory :p ) ... I suggest you check the effective IDTR content...

also

Code: Select all

   /* load IDTR with lidt */
    asm volatile("LIDT (%0) ": :"p" (IDTRptr));
looks strange to me ... try a "dump_cpu" from bochs debugger and check IDTR base and limits are what you expect. Then go for idtr.base and check it has the expected descriptor at the expected place ...