Page 1 of 2

Need help remapping PICs

Posted: Mon Mar 28, 2005 8:36 pm
by Crazed123
I've got my code for remapping the PICs at boot time just before I enable interrupts. By this time an IDT is already set up and defined for the basic 16 exceptions. The PIC code is:

Code: Select all

//Need to remap the PICs before IRQs can be enabled safely.
OutByteToPort($20,$11);
IOWait();
OutByteToPort($A0,$11);
IOWait();
OutByteToPort($21,$20);
IOWait();
OutByteToPort($A1,$28);
IOWait();
OutByteToPort($21,$04);
IOWait();
OutByteToPort($A1,$02);
IOWait();
OutByteToPort($21,$01);
IOWait();
OutByteToPort($A1,$01);
IOWait();
OutByteToPort($21,$00);
IOWait();
OutByteToPort($A1,$00);
IOWait();
OutByteToPort($21,$FF);
IOWait();
However, when I test it in Bochs it still always triggers a Double Fault Exception because of IRQ0 firing. I can tell it's not a genuine double fault because no exception gets handled before it.

Does anyone know how to make this work? I learned this stuff from this site and BonaFide.

Re:Need help remapping PICs

Posted: Mon Mar 28, 2005 10:38 pm
by AR
I would assume the double fault is caused by the IRQ occuring without a valid handler. Unfortunately I don't have the docs I downloaded about the PIC (or my own source code) on hand to check the initalization process.

Re:Need help remapping PICs

Posted: Mon Mar 28, 2005 11:06 pm
by B.E
Would disabling interrupt help

Re:Need help remapping PICs

Posted: Tue Mar 29, 2005 1:27 pm
by mystran
Crazed123 wrote: However, when I test it in Bochs it still always triggers a Double Fault Exception because of IRQ0 firing. I can tell it's not a genuine double fault because no exception gets handled before it.
Have you enabled CPU debugging in Bochs, so that you indeed get a message for each interrupt that fires of? If you did, it should also give you some idea of what is wrong with the IDT descriptor (in case that is an issue). If you've enabled paging, also check if a page fault has fired of.

Re:Need help remapping PICs

Posted: Tue Mar 29, 2005 7:28 pm
by Crazed123
I haven't enabled paging yet, and have enabled debugging on Bochs, so that I can trace and breakpoint and that sort of thing. Is that what you mean by CPU debugging?

[edit]No, I actually haven't it would seem. Do you have to recompile bochs to get that?[/edit]

Re:Need help remapping PICs

Posted: Thu Mar 31, 2005 2:46 am
by Pype.Clicker
until your sequence is completed, any IRQ0 will be interpreted as EXC8 (double fault). To avoid any troubles, make sure you have interrupts disabled before you enter pmode and reenable them *only* after this sequence.

Re:Need help remapping PICs

Posted: Thu Mar 31, 2005 6:59 am
by mystran
Crazed123 wrote: I haven't enabled paging yet, and have enabled debugging on Bochs, so that I can trace and breakpoint and that sort of thing. Is that what you mean by CPU debugging?
Not really. What I mean is that from Bochs options you can edit "logging options for individual devices" from which you can change "debug" from "ignore" to "report". You can only do this for ALL devices in config file, so do it in Bochs menus instead, for only the devices you need (all devices output a LOT of unnecessary stuff).

Re:Need help remapping PICs

Posted: Thu Mar 31, 2005 2:27 pm
by Crazed123
When I set CPU to report and run the kernel, nothing happens. It doesn't even report the Double Fault.

Re:Need help remapping PICs

Posted: Fri Apr 01, 2005 11:15 am
by Guest
I had a prob to with interrupts, prob was that my outport function didn't do his job right (stupid coding error :p )...

Make sure if you use asm that you define a known calling convention...

Code: Select all

procedure koutportb(port: Word; data: Byte); stdcall; assembler; [public, alias: 'koutportb'];
asm
   mov al, data
   mov dx, port
   out dx, al
end ['EAX', 'EDX'];

Re:Need help remapping PICs

Posted: Fri Apr 01, 2005 1:51 pm
by Crazed123
Why use stdcall?

Re:Need help remapping PICs

Posted: Sat Apr 02, 2005 1:54 am
by Guest
Pascal uses register passing when theres only two param...
And i was to lazy to look up what regs freepascal uses :)

cdecl should be fine too or get the compiler docs to find out what regs it uses to pass params...

Re:Need help remapping PICs

Posted: Sat Apr 02, 2005 9:12 am
by Crazed123
Won't it clean up its own parameters?

And can anyone tell me why the PIC setting won't work?

Re:Need help remapping PICs

Posted: Sat Apr 02, 2005 9:33 am
by AR
Some old archived code I used to initalise the PIC:

Code: Select all

#define PIC_ICW1              0x10
#define PIC_ICW1_ICW4USED     0x1
#define PIC_ICW1_ICW4NOTUSED  0x0
#define PIC_ICW1_MASTERSLAVE  0x2
#define PIC_ICW1_MASTERONLY   0x0
#define PIC_ICW1_LEVELTRIGGER 0x8
#define PIC_ICW1_EDGETRIGGER  0x0

//ICW2 is the interrupt numbers to use(bits 0,1,2 are ignored so must be divisible by 8)
//ICW3(Master) set 1 on the bit representing the IRQ connected to the Slave PIC
//ICW3(Slave) set first 3 bits(0-2) to make number(int) of IRQ used on Master PIC. ie. 2 [IRQ 2]

#define PIC_ICW4_8086MODE     0x1
#define PIC_ICW4_MCSMODE      0x0
#define PIC_ICW4_AUTOAEOI     0x2
#define PIC_ICW4_MANUALAEOI   0x0
#define PIC_ICW4_ISMASTER     0x4
#define PIC_ICW4_ISSLAVE      0x0
#define PIC_ICW4_BUFFERED     0x8
#define PIC_ICW4_UNBUFFERED   0x0
#define PIC_ICW4_NESTEDMODE   0x10
#define PIC_ICW4_UNNESTEDMODE 0x0

void SetPICInts(unsigned char FromInt)
{
   OutB(0x20, PIC_ICW1 | PIC_ICW1_ICW4USED);   //Write PIC1_COMMAND - INIT (ICW4 will be used)
   OutB(0xA0, PIC_ICW1 | PIC_ICW1_ICW4USED);   //Write PIC2_COMMAND - INIT ^^

   OutB(0x21, FromInt);   //Write PIC1_DATA, Interrupts start At for PIC1
   OutB(0xA1, FromInt+8);   //Write PIC2_DATA, Interrupts start At for PIC2 (Bits 0-2 are
            //unused)

   OutB(0x21, 4);      //ICW3 - Writes IRQ 2 is attached to Slave PIC
   OutB(0xA1, 2);      //ICW3(Slave) - Only bits 0-2 used. Slave is on IRQ 2 on Master

   OutB(0x21, PIC_ICW4_8086MODE | PIC_ICW4_ISMASTER);   //ICW4 - 8086 PIC Master
   OutB(0xA1, PIC_ICW4_8086MODE);   //8086 PIC Slave
   
   OutB(0x21, 0xFF);
   OutB(0xA1, 0xFF);
}
This code would seem to match, the only things I can think of are that you've caused a double fault in the handler, the reprogram code is not called or you've got a logic-syntactic error with the numbers.

Re:Need help remapping PICs

Posted: Sat Apr 02, 2005 11:25 am
by Crazed123
My procedure to output a byte to a port is:

Code: Select all

procedure OutByteToPort(wPort: Word; btValue: Byte); assembler;
asm
mov dx,wPort
mov al,btValue
out dx,al
end ['DX','AL'];
I don't see what's wrong. Also, I don't know what interrupt is being called (CPU debugging won't seem to report anything), so I can't check my handler. How might I alleviate that?

Re:Need help remapping PICs

Posted: Sat Apr 02, 2005 1:15 pm
by Guest
Did you try using the function i posted?
I tried yours and didn't work for me...

It could be that the compiler allocates the DL reg as register to pass btValue... so you get if AX is the register used to pass wPort

mov dx, ax <- btValue changed!!!!
mov al, dl <- rong data!!!!
out dx, al

if you call the function then as OutByteToPort($000A, $10);
if will output like this out $0A, $0A

So uses stdcall to force the compiler to use the stack! And make your inline asm functions easy to write. It would be slower but you can always look up the compiler docs and find a faster a solution after you realy need speed in your os...

Tip when using boch :)

Writing to bochs console:

procedure bwritestr(s: PChar); [public, alias: 'bwritestr'];
var
   i: Integer;
begin
   koutportb(BOCHS_DEBUG_PORT, $0D);
   koutportb(BOCHS_DEBUG_PORT, $0A);

   i := 0;

   while (s <> Char($0)) do
   begin
      koutportb(BOCHS_DEBUG_PORT, Byte(s));
      i += 1;
   end;
end;