i386/113540: decrease i8254 calibration precision to make it work
with Xbox, remove warnings
Ed Schouten
ed at fxq.nl
Sun Jun 10 20:20:03 UTC 2007
>Number: 113540
>Category: i386
>Synopsis: decrease i8254 calibration precision to make it work with Xbox, remove warnings
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-i386
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun Jun 10 20:20:02 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator: Ed Schouten
>Release: FreeBSD 6.2-STABLE i386
>Organization:
>Environment:
System: FreeBSD palm.hoeg.nl 6.2-STABLE FreeBSD 6.2-STABLE #0: Fri Apr 20 13:44:49 CEST 2007 root at palm.hoeg.nl:/usr/obj/usr/src/sys/PALM i386
>Description:
For some reason, the timers in the Microsoft Xbox aren't as sane as on
PC's; it has two issues:
- The frequency of the i8254 timer is 1125000 Hz instead of 1193182 Hz.
The Microsoft Xbox port currently solves this by hardcoding TIMER_FREQ
in the config file.
- The diagnostic and status registers of the RTC contain invalid data,
which causes FreeBSD to assume the RTC is broken. This causes a lot of
spurious messages in the dmesg.
>How-To-Repeat:
>Fix:
I've been using the following patch on my Xbox for a long time now; it
essentially does the following things:
- It changes the rtcin() routine to return fake values for the diagnose
and status registers, which forces FreeBSD to properly use theh RTC.
- It decreases the precision of the timer (by default disabled) timer
calibration code from 1% to 10%; this is needed because the Xbox clock
is 6% off.
- It removes the hardcoded Xbox timer value from the Xbox configuration
file and enables timer calibration.
The reason why we want to do such a thing is because we could then
compile kernels that run on Xbox'es and PC's without a clock drift on
one of those systems.
--- src/sys/i386/isa/clock.c Tue Jan 23 19:18:32 2007
+++ src/sys/i386/isa/clock.c Thu Feb 8 18:07:28 2007
@@ -94,6 +94,10 @@
#include <i386/bios/mca_machdep.h>
#endif
+#ifdef XBOX
+#include <machine/xbox.h>
+#endif
+
#define TIMER_DIV(x) ((timer_freq + (x) / 2) / (x))
int clkintr_pending;
@@ -421,6 +425,23 @@
{
u_char val;
+#ifdef XBOX
+ /*
+ * The RTC in the Microsoft Xbox always reports errors,
+ * including power problems, though it's functioning correctly.
+ * We want to use the RTC to calibrate the timer, because its
+ * frequency isn't the same as a regular PC.
+ */
+ if (arch_i386_is_xbox) {
+ switch (reg) {
+ case RTC_DIAG:
+ return (0);
+ case RTC_STATUSD:
+ return (RTCSD_PWR);
+ }
+ }
+#endif
+
RTC_LOCK;
if (rtc_reg != reg) {
inb(0x84);
@@ -631,7 +652,7 @@
* frequency.
*/
delta = freq > timer_freq ? freq - timer_freq : timer_freq - freq;
- if (delta < timer_freq / 100) {
+ if (delta < timer_freq / 10) {
#ifndef CLK_USE_I8254_CALIBRATION
if (bootverbose)
printf(
@@ -642,7 +663,7 @@
} else {
if (bootverbose)
printf(
- "%d Hz differs from default of %d Hz by more than 1%%\n",
+ "%d Hz differs from default of %d Hz by more than 10%%\n",
freq, timer_freq);
}
--- src/sys/i386/conf/XBOX Mon Feb 5 16:50:16 2007
+++ src/sys/i386/conf/XBOX Mon Feb 5 17:36:12 2007
@@ -42,8 +42,7 @@
#options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
#options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options ADAPTIVE_GIANT # Giant mutex is adaptive.
-# Xbox has a non-standard default timer frequency
-options TIMER_FREQ=1125000 # Gives ~733.34MHz CPU
+options CLK_USE_I8254_CALIBRATION # Timer has non-standard frequency
#device apic # I/O APIC
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-i386
mailing list