Need help remapping PICs

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Crazed123

Need help remapping PICs

Post 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.
AR

Re:Need help remapping PICs

Post 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.
B.E

Re:Need help remapping PICs

Post by B.E »

Would disabling interrupt help
mystran

Re:Need help remapping PICs

Post 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.
Crazed123

Re:Need help remapping PICs

Post 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]
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Need help remapping PICs

Post 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.
mystran

Re:Need help remapping PICs

Post 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).
Crazed123

Re:Need help remapping PICs

Post by Crazed123 »

When I set CPU to report and run the kernel, nothing happens. It doesn't even report the Double Fault.
Guest

Re:Need help remapping PICs

Post 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'];
Crazed123

Re:Need help remapping PICs

Post by Crazed123 »

Why use stdcall?
Guest

Re:Need help remapping PICs

Post 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...
Crazed123

Re:Need help remapping PICs

Post by Crazed123 »

Won't it clean up its own parameters?

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

Re:Need help remapping PICs

Post 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.
Crazed123

Re:Need help remapping PICs

Post 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?
Guest

Re:Need help remapping PICs

Post 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;
Post Reply