IDT does not load correctly
IDT does not load correctly
Hi.
I'm working on the Bootstrap and have already enabled Pmode, the A20, and loaded a kernel. The start of the kernel is in ASM and then is jumps to the C kernel. While in ASM, I want to setup Interrupts and Exceptions. So, I know that this file is real long, but it is very redundant. I'm very sure I will get some 'you could do it better this way'. So, how would I do it better and make it shorter? And actually make it work? It is just not working at all. Yes, the PIC is remapped after the C code is loaded, but even after that the interrupts aren't called? I can call the int's and exceptions from the code, but the computer is not loading the adresses correctly, I think. Well, look it over and tell me what you think it up.
Brett
I'm working on the Bootstrap and have already enabled Pmode, the A20, and loaded a kernel. The start of the kernel is in ASM and then is jumps to the C kernel. While in ASM, I want to setup Interrupts and Exceptions. So, I know that this file is real long, but it is very redundant. I'm very sure I will get some 'you could do it better this way'. So, how would I do it better and make it shorter? And actually make it work? It is just not working at all. Yes, the PIC is remapped after the C code is loaded, but even after that the interrupts aren't called? I can call the int's and exceptions from the code, but the computer is not loading the adresses correctly, I think. Well, look it over and tell me what you think it up.
Brett
Re:IDT does not load correctly
You could start with remapping the PIC before setting the IDT.
Re:IDT does not load correctly
strictly speaking not, but it's customary to do so. You must disable interrupts before doing either of them until after doing both of them. Then, do you acknowledge interrupts, do you receive 0, 1, 2 or more interrupts? Do you have a bochs trace (in debugger trace-on) of the code that is probably flawed? Did you print out the CPU state, PIC debug info and IDT once, when they should've worked?vbbrett wrote: Do you have to remap the PIC before loading the IDT?
Re:IDT does not load correctly
I got a problem with interrupts too, IDT is loaded correct i think...
exception routines work, but irq's don't look to work and every time i enable interrupts a int 08 is fired but with no error code pushed (found this out with bochs)
so it should be the timer that is causing this even if i remapped the pic, i wrote my own remap code and even tried some example code from the net without any luck... but its called only once, if its the timer thats doing this then its normal because the pic needs a EOI
don't known why i can't remap it, are there any steps i should follow? and why does the pic remap code you find on the net all use 010 (2) as slave ID?
exception routines work, but irq's don't look to work and every time i enable interrupts a int 08 is fired but with no error code pushed (found this out with bochs)
so it should be the timer that is causing this even if i remapped the pic, i wrote my own remap code and even tried some example code from the net without any luck... but its called only once, if its the timer thats doing this then its normal because the pic needs a EOI
don't known why i can't remap it, are there any steps i should follow? and why does the pic remap code you find on the net all use 010 (2) as slave ID?
- Pype.Clicker
- Member
- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:IDT does not load correctly
http://www.osdev.org/osfaq2/index.php/C ... e%20PIC%3F is our reference ...
i don't see pic-remapping code of yours so i barely can help ...
i don't see pic-remapping code of yours so i barely can help ...
Re:IDT does not load correctly
Because in all existing X86 compatibles, the slave PIC is connected to the masters PIC on line 2.Kim wrote: and why does the pic remap code you find on the net all use 010 (2) as slave ID?
Note that this also usually means that irq 8-15 are a higher priority than irq 3-7.
Re:IDT does not load correctly
This is my PIC unit, but remapping now works. I forgot to add stdcall to the io functions like koutportb, freepascal else uses register passing and doesn't load the registers correct then.
Now i still got a prob, same as vbbert my interrupt is called only once even when i send an End of interrupt cmd to the pic at the end of the handler code.
Iam testing using the keyb irq1. The interrupts are defined in the
idt as interrupt gates.
Code: Select all
unit pic;
interface
uses
io;
procedure kenable_irq(idx: Integer);
procedure kdisable_irq(idx: Integer);
procedure kdisable_irqs();
procedure kremap_irqs();
const
PIC_MASTER_CMD = $20; //Command Register
PIC_SLAVE_CMD = $A0; //Command Register
PIC_MASTER_DATA = $21; //Interrupt enable and initialization register
PIC_SLAVE_DATA = $A1; //Interrupt enable and initialization register
PIC_NEED_ICW4 = $01;
PIC_ICW1_FLAG = $01 shl 4;
//Start initialization and say we are going to send ICW4
PIC_ICW1 = PIC_NEED_ICW4 or PIC_ICW1_FLAG;
PIC_ICW2_MASTER = $20; //Starting irqs from interrup 32
PIC_ICW2_SLAVE = $28; //Starting irqs from interrup 40
PIC_ICW3_MASTER = $01 shl 2; //Slave is connected to irq2
PIC_ICW3_SLAVE = $01 shl 1; //Slave ID is 2
PIC_ICW4 = $01; //8086/8080 Mode
PIC_EOI = $20; //End of interrupt command
implementation
procedure kenable_irq(idx: Integer); [public, alias: 'kenable_irq'];
var
port: Word;
begin
if (idx > 7) then
begin
idx -= 7;
port := PIC_SLAVE_DATA;
end
else
port := PIC_MASTER_DATA;
koutportb(port, kinportb(port) and not (1 shl idx));
end;
procedure kdisable_irq(idx: Integer); [public, alias: 'kdisable_irq'];
var
port: Word;
begin
if (idx > 7) then
begin
idx -= 7;
port := PIC_SLAVE_DATA;
end
else
port := PIC_MASTER_DATA;
koutportb(port, kinportb(port) or (1 shl idx));
end;
procedure kdisable_irqs(); [public, alias: 'kdisable_irqs'];
begin
koutportb(PIC_MASTER_DATA, $FF);
koutportb(PIC_SLAVE_DATA, $FF);
end;
procedure kremap_irqs(); [public, alias: 'kremap_irqs'];
begin
koutportb(PIC_MASTER_CMD, PIC_ICW1);
koutportb(PIC_SLAVE_CMD, PIC_ICW1);
koutportb(PIC_MASTER_DATA, PIC_ICW2_MASTER);
koutportb(PIC_SLAVE_DATA, PIC_ICW2_SLAVE);
koutportb(PIC_MASTER_DATA, PIC_ICW3_MASTER);
koutportb(PIC_SLAVE_DATA, PIC_ICW3_SLAVE);
koutportb(PIC_MASTER_DATA, PIC_ICW4);
koutportb(PIC_SLAVE_DATA, PIC_ICW4);
end;
end.
Iam testing using the keyb irq1. The interrupts are defined in the
idt as interrupt gates.
Code: Select all
//done before loading new idt
kremap_irqs();
kdisable_irqs();
kisr_irq_handle1 := @kisr_irq_handletest;
kenable_irq(1);
//handler code
procedure kisr_irq_handletest(regs: Pisr_irq_regs); stdcall; [public, alias: 'kisr_irq_handletest'];
begin
xpos := 0;
ypos += 1;
kwritestr('BEEP');
koutportb(PIC_MASTER_CMD, PIC_EOI);
end;
Re:IDT does not load correctly
that was the prob, the keyb chip was waiting for the readout.