OSDev.org
https://forum.osdev.org/

[Solved] RTC timer fails after reboot only in Bochs
https://forum.osdev.org/viewtopic.php?f=1&t=30091
Page 1 of 1

Author:  sleephacker [ Sun Feb 14, 2016 12:59 pm ]
Post subject:  [Solved] RTC timer fails after reboot only in Bochs

My OS is currently in Protected Mode and I have a basic CLI, and a reboot command that supports these methods:
1. Sending 0xfe to the PS/2 controller
2. Sending 0x02 and then 0x04 to port 0xcf9
3. Tripple fault

I tested rebooting using these methods as well as with the reset button both on bochs and my real machine.
But in Bochs it seems the RTC timer stops working after rebooting using either the PS/2 or the port 0xcf9 method but not after rebooting using any other method.
Also when the RTC stops working it won't work anymore even after I reboot using either the tripple fault method or the reset button.
I have also tested this on VirtualBox and my real machine, but the problem seems to be specific to Bochs so far.

This is the most important bit of the reboot code:

Code:
   .ps2:
      mov esi, .ps2msg
      call boot_print_default
      mov byte [PS2.command], 0xfe      ;pulse reset line
      call PS2_cscw
      jmp .fail
   .pci:               ;TODO: according to linux source code I should check for the right PCI type to know if this is safe.
      mov esi, .pcimsg
      call boot_print_default
      mov dx, 0cf9h
      mov al, 02h
      out dx, al
      call .wait
      mov al, 04h
      out dx, al
      jmp .fail
   .tripple_fault:
      mov esi, .triflt
      call boot_print_default
      lidt [.BAD_IDTR]
      int 3   ;debug interrupt
      jmp .fail
      .BAD_IDTR dw 0, 0, 0


Even though the PCI part needs some work I don't think that's the problem since PS/2 has the exact same issue.
Here is the part responsible for setting up the PIC and RTC:

Code:
   ;intialize PIC
   ;ICW1
   mov al, 00010001b
   out 0020h, al
   out 00a0h, al
   ;ICW 2
   mov al, 20h   ;after reserved interrupts
   out 0021h, al
   mov al, 28h
   out 00a1h, al
   ;ICW 3
   mov al, 4
   out 0021h, al
   mov al, 2
   out 00a1h, al
   ;ICW 4
   mov al, 1
   out 0021h, al
   out 00a1h, al
   
   ;enable IRQ 8
   in al, 0xa1
   and al, 11111110b
   out 0xa1, al
   ;enable RTC
   mov al, 8bh
   out 70h, al
   in al, 71h
   or al, 01000000b
   and al, 11001111b
   xchg bl, al
   mov al, 8bh
   out 70h, al
   xchg bl, al
   out 71h, al
   ;set RTC frequency
   mov al, 8ah
   out 70h, al
   in al, 71h
   and al, 0xf0
   or al, 08h   ;256Hz
   xchg al, bl
   mov al, 8ah
   out 70h, al
   xchg al, bl
   out 71h, al


Could this be a bug in Bochs?

Author:  Combuster [ Mon Feb 15, 2016 9:28 am ]
Post subject:  Re: RTC timer fails after reboot only in Bochs

The master PIC doesn't have the slave unmasked.

Author:  sleephacker [ Mon Feb 15, 2016 12:32 pm ]
Post subject:  Re: RTC timer fails after reboot only in Bochs

I sort of figured it out.
I saved Bochs state before and after rebooting a couple of times, and noticed that in the PIC file slave.IRQ_in was always set to 0x01 after rebooting, which leads me to believe the IRQ 8 line got stuck high.
So I added an
Code:
int 28h
after the PIC initialization which translates to IRQ 8, hoping that this would reset the IRQ 8 line, and it just worked!

I still don't know what caused this issue in the first place though...

Author:  sleephacker [ Fri Apr 28, 2017 1:27 pm ]
Post subject:  [Solved] RTC timer fails after reboot only in Bochs

More than a year later, the problem has been solved (credits to Octocontrabass who provided the solution in another thread).

It turns out the reason why doing 'int 28h' fixed it was because within the int 28h handler the status register C is read because that's needed to acknowledge pending RTC interrupts, which were apparently the cause of this bug. The problem was solved by removing the 'int 28h' and replacing it with the following code, at the end of the RTC initialisation:
Code:
;read status register C to acknowledge pending RTC interrupts
mov al, 0ch
out 70h, al
in al, 71h
After coming back to this I've noticed an additional problem with my original RTC init code: NMIs were never enabled again. Instead normal interrupts were enabled, soon after which an IRQ 8 arrived causing NMIs to be enabled again while reading status register C, which is probably why I've never noticed this bug, even on real hardware. This problem has now also been fixed by sending 0x0C (select RTC status reg C, and enable NMIs) to port 0x70 instead of sending 0x8C (which would have left NMIs disabled).

I've added the solution to the original problem to the part about status reg C on the wiki:
On the wiki, I wrote:
[...] If you're using Bochs, it is also recommended to read Status Register C after initialising the RTC, to make sure any RTC interrupts that were pending before/while the RTC was initialised are acknowledged (not doing this has lead to the RTC timer not sending any interrupts after rebooting in at least one case, observed on Bochs 2.6.6, see this thread)
But I'm not sure if I've worded it correctly, should it really just be a recommendation for bochs only (because it's only a problem on bochs, if that's even true) or is it actually a must (which seems unlikely because by default RTC interrupts are disabled, so there's no way there can be any interrupts pending before/while the RTC is initialised)? Or should this not be added to the wiki at all?

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/