Bochs or me?

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.
Ryu

Re:Bochs or me?

Post by Ryu »

Brendan:
The image: http://69.194.132.218/2khz.rar

Because it does not output anything other then when it generates an exception, you would just see a blue line when its running good.
Brendan wrote: I've been trying your last boot images (PIT100hz.img and PIT200hz.img) but I haven't been able to get them to crash - I just get a sea of scrolling "tock!!tick"...
Hmm.. well on my bochs it crashs for the 200hz image. After then I started chipping away the source and ended up with the code in the previous post, then it needed to be at a higher timer frequency to cause a GPF.
Brendan wrote: Also, which version of Bochs are you using? I'm using the CVS version from about a month ago...
.....
It might also help to know how you've compiled Bochs - which optimizations were enabled (and possibly if SMP was enabled, as SMP disables some of the optimizations).
I don't use the CVS ones but the released one which is the bochs-2.2.6-win32msvc-src.zip still up in thier website. The only modifcation done was to support your 64KB ISA BIOS. (I've haven't managed to figure out why I can't get the 128KB BIOS working yet, nor can I understand why when I tried to compile Bochs with SMP enabled it hangs after any BIOS post.)
Brendan wrote: Bochs does have bugs but they are extremely rare for common things (like the CPU itself, PIC, PIT, etc).
Wether its me or bochs, I hope its me actually so then I can say I learn something out of this whole deal, but if it is bochs then I'm afraid I've just went through that for nothing.
Brendan wrote: I haven't been able to reproduce the problem and it's still not precise enough to tell exactly where a bug might be in Bochs....
Just wondering.. do you have that show IPS for bochout.txt enabled and using the option clock: sync=realtime, time0=local? It was an important factor for the two images because I've that the 100hz won't GPF but 200hz GPF on realtime setting, I'm not sure why your not getting GPFs...
Brendan wrote: I'm also not sure which instruction/s trigger the GPF or what is on the stack after the GPF (the error code pushed on the stack by the CPU, etc). Also, are all other IRQs masked?
I've now made a more friendly unhandled exception handler which hopefully will answer all those questions. This is what it outputs on GPF:


Dumping register and stack information..

CS=0008h DS=0010h ES=0010h SS=0018h GS=0010h FS=0010h
EAX=80000002h ESI=00094000h EIP=0009016Fh CR0=00000011h
EDX=00000254h EDI=00084000h ESP=00000F4Ch CR2=00000000h
ECX=00000000h EBX=00000000h EBP=00009000h CR3=00000000h

EFLAG=00210286h Reserved checksum (00000002)

IOPL=0 CF=0 PF=1 AF=0 ZF=0 SF=1 OF=0
ID=1 TF=0 IF=0 DF=0 NT=0 RF=1 VM=0 AC=0 VIF=0 VIP=0

ErrorCode=0000013Bh EXT=1 IDT=1 TI=0 Selector: 39 (27h)
ESP [00h]=00000000h
ESP [04h]=00000000h
ESP [08h]=00000000h
ESP [0Ch]=00000000h


Now I know you notice that this is a external error code that is specifying selector 39 (mapped to IRQ 7). At first I did not mask any IRQs, however I always had a #NP handler and confirm it works properly. The only ISR that was installed is IRQ 0, and only IDT was made was 20h for IRQ 0. This would at least what I think would case a #NP if some other IRQ was servicing (Yes the entire area was zero'd before installing ISRs). But no #NP was generated, so I assume its has nothing to do with that nature. However after you metioned it, I did mask all IRQs but the timer. Why the error code is pointed to IRQ 7 (parallel printer interrupt)? I am clueless.

edit: I forgot to mention that it still does generate the same GPF as shown here after masking IRQs.
Ryu

Re:Bochs or me?

Post by Ryu »

mystran wrote: Here's a suggestion:

Run Bochs with the-setting-that-shows-current-ips.
Then set that value as your IPS, and try without realtime sync.

If that will reproduce it, then I'd almost guess that you are getting too many nested interrupts or something..
I think this is what you mean, when bochout outputs the IPS:

00000141389i[VBIOS] VBE Bios $Id: vbe.c,v 1.48 2005/12/26 19:50:26 vruppert Exp $
00000170000i[WGUI ] dimension update x=720 y=400 fontheight=16 fontwidth=9 bpp=8
00000380000i[WGUI ] dimension update x=640 y=480 fontheight=0 fontwidth=0 bpp=8
00000423493i[FDD ] controller reset in software
00000424030i[FDD ] io_write: config control register: 0x00
00005210000i[WGUI ] dimension update x=720 y=400 fontheight=16 fontwidth=9 bpp=8


All what was mentioned above was using this setting. I'm not even sure how to enable/disable it. About nesting interrupts.. correct me if I'm wrong if only one ISR can be servicing at a time, once entered to an ISR the processor will disable interrupts, EFLAGS get pushed into stack, and wether interrupts was enable or not it is restored apon return. So, there can't be nested interrupts, unless for unmaskable interrupts which I'm not familiar with yet.


I'm going to also post the PIC remapping code I used that for now is hard coded masking everything but IRQ 0.. Its actually very much the same as the one in the FAQ, however I'm not entirely sure this is the way to mask IRQs.

Code: Select all

;==========================================================================
___PIC_RemapIRQ@4   PROC SYSCALL      index:DWORD
;==========================================================================
;+++++++++++++++STACK+++++++++++++++++++10h+++++++++++++++++++++++++++++++++
   @index               equ      esp+0Ch
   @RIP               equ      esp+08h ; <-- Return Address (CS:EIP)
   push   eax            ;      esp+04h
   push   ebx            ;      esp+00h
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

   in      al, 021h
   mov      bl, al         ; read master mask
   in      al, 0A1h
   mov      bh, al         ; read slave mask

   mov      al, ICW1_INITIALIZE OR ICW1_ICW4      ; initialize master channel
   out      020h, al
   mov      al, ICW1_INITIALIZE OR ICW1_ICW4      ; initialize slave channel
   out      0A0h, al

   mov      eax, [@index]   ; set both channels vector index
   out      021h, al
   add      al, 8h
   out      0A1h, al

   mov      al, 04h   
   out      021h, al      ; master data port, continue intialization sequence
   add      al, 02h
   out      0A1h, al      ; slave data port, continue intialization sequence

   mov      al, ICW4_8086   ; set both channels to operate in 8086 mode
   out      021h, al
   out      0A1h, al

;   mov      al, bl         ; restore masks on both channels
;   out      021h, al
;   mov      al, bh
;   out      0A1h, al

   mov      al, 0FEh      ; mask all but IRQ-0
   out      021h, al
   mov      al, 0FEh      ; mask all but IRQ-0 (not sure if this does anything for slave)
   out      0A1h, al

   pop      ebx
   pop      eax
   ret      4h

___PIC_RemapIRQ@4 ENDP
Thankye both.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:Bochs or me?

Post by Brendan »

Hi,
Ryu wrote:I'm going to also post the PIC remapping code I used that for now is hard coded masking everything but IRQ 0.. Its actually very much the same as the one in the FAQ, however I'm not entirely sure this is the way to mask IRQs.

Code: Select all

[SNIP]
   mov      al, 0FEh      ; mask all but IRQ-0
   out      021h, al
   mov      al, 0FEh      ; mask all but IRQ-0 (not sure if this does anything for slave)
   out      0A1h, al
This isn't quite right - you're enabling IRQ0 and IRQ8, but disabling the "cascade" line (the "IRQ2" line, which isn't IRQ2).

What you'd want is:

Code: Select all

[SNIP]
   mov      al, 0FAh      ; mask all but IRQ-0 and the cascade line
   out      021h, al
   mov      al, 0FFh      ; mask all
   out      0A1h, al
Out of curiousity, what would happen if your OS got an IRQ7?

It's a pain in the neck, but the PIC chips can generate a "spurious interrupt", which is normally IRQ7 for PIC1 and IRQ15 for PIC2 (and can't be masked).

The idea is that if the PIC chip's "INTR" line is high then the CPU is meant to wait for the interrupt number to come from a PIC chip. If the PIC chip doesn't know why the INTR line is high then it'll send a spurious interrupt so that the CPU does receive an interrupt number and doesn't get all messed up (i.e. wait forever).

Bochs does emulate this spurious interrupt - see "iodev/pic.cc" around line 807.

Looking at Bochs' code, it looks like the spurious interrupt is sent if the INTR line was high and there's nothing in the PIC's IRR. This includes when PIC2 raises the INTR line but PIC1 has nothing in it's IRR, which should never happen unless the cascade isn't enabled in PIC1 properly.

Adding all of this up for your OS, if anything generates an IRQ8 then you should get a spurious IRQ7 from the master PIC, which would trigger a general protection fault if you haven't got an IRQ handler for IRQ7. It's possible that this is the problem (although I can't think of any reason why you'd be getting an IRQ8).

Anyway, change your PIC chip initialization code, and let us know if it fixes your GPF trouble... :)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply