To clear up stuff about RDTSC, he's what I just hacked up in zealos, it's
based on the .18 patch to do the same thing... My question is, how
would/should plex handle this?

I get loopsPerMs equal to 27 on this K5 box, whereas using the conventinal
method, I would get a value of about 99 million cycles per-second.

The way I think plex should handle this is work out the ammount of time in
between RDTSC calls, and then multiply that by the speed of the current
box or whatever...

-- 

Mark Zealey (aka JALH on irc.openprojects.net: #zealos and many more)
[EMAIL PROTECTED]
[EMAIL PROTECTED]
[EMAIL PROTECTED]

UL++++$ (GCM/GCS/GS/GM)GUG! dpu? s-:-@ a15! C+++>$ P++$>+++@ L+++>+++++$
!E---? W+++>$ N++@>+ o->+ w--- !M--? !V--? PS- PE--@ !PGP----? r++
!t---?@ !X---? !R- b+ !DI---? e->+++++ h+++*! y-

(www.geekcode.com)
// delay.c
/*
 * Copyright (C) 02/08/2000 Mark Zealey ([EMAIL PROTECTED])
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place - Suite 330, Boston, MA 02111-1307,
 *
 * This file was added to the ZealOS project on 02/08/2000 at 12:01:12 by Mark
 * Zealey
 */

/* Notes/Changes:
 * OK, the way we caliberate the delay loop is like this:
 * 1) Find a rough value
 * 2) go back down that xor'ing a mask to get the presice value
 * Simple eh?
 * This is quite like how linux does it except it's a bit shorter and a bit
 * quicker.
 *
 * Step 1:
 *      We set an initial delay (of 1) to caliberate with. This then
 *      gets shifted up each time, till the loop is slower than 1000 Hz. It then
 *      shifts it back one.
 * Step 2:
 *      A mask is applied (1 bit) and is rippled up till it's faster than 1000Hz
 *      as before, it's then shifted right by 1 and perminantly applied.
 *      
 */

#include <common.h>
#include <delay.h>
#include <desc.h>
#include <8259.h>
#include <printk.h>
#include <stdio.h>
#include <pit.h>
#include <asm_commands.h>

static volatile uchar tick = 0;
/* If we're on a 586 or greater (w/ RDTSC), the following value is in cycles per
 * second. Otherwise, we just caliberate to the milisecond */
ulong loopsPerMs = 1;

/* Ugly kludge for a Us delay on non-RDTSC processors */
#if !(defined(__i386__) && (PROCESSOR >= 5))
ulong loopsPerUs;
#endif

handleInt(delayISR)
{
        tick++;
}

// Calaberates the delay. This is a bogomips value :)
__uint8 delayInit()
{
        ulong mask;
#if !(defined(__i386__) && (PROCESSOR >= 5))
        __uint8 count = 32;
#endif

        DPRINT("Caliberating delay loop: ");

        // Set the PIT to 1000 interrupts a second.
        pitSet(1000, 0);
        // We add a handler to IRQ 0 (PIT).
        addHandler(0, delayISR, 1);

        do {
#if !(defined(__i386__) && (PROCESSOR >= 5))
                if(!--count)                    // If we're about to overflow
                        break;
#endif
                loopsPerMs <<= 1;               // * 2
                tick = 0;
                while(!tick) /* Wait */;        // Wait for the next tick
                sleep(1);                       // (tick==1)
        } while(tick == 1);

#if !(defined(__i386__) && (PROCESSOR >= 5))
        if(!count) {
                printk("Your processor is just too fast (and too old) :/\n");
                return FALSE;
        }
#endif
        loopsPerMs >>= 1;                       // back 1
        mask = loopsPerMs;                      // set the mask to us

        while(mask) {                           // do fine calaberation
                mask >>= 1;                     // move the mask bit
                loopsPerMs |= mask;             // Apply the mask
                tick = 0;
                while(!tick) /* Wait */;
                sleep(1);                       // (tick now = 1)
                if(tick != 1)                   // If a tick has passed
                        loopsPerMs ^= mask;     // remove it
        }
#if !(defined(__i386__) && (PROCESSOR >= 5))
        loopsPerUs = loopsPerMs / 1000;         // Ugly hack :/
#endif
        delHandler(0, delayISR);
        pitSet(Hz, 0);                          // Reset the Pic

        printk("Done! :)\n");
        DPRINT("Now delaying 10 seconds to varify that the value is correct\n");
        sleep(10000);
        DPRINT("10 Secs is up. Let's get on wit it! :)\n");     // Test :)
        return TRUE;
}

#if defined(__i386__) && (PROCESSOR >= 5)
// delays for about 1Us
void __1sleepRdtsc()
{
        __uint32 a, b, c;               // a is not actually used
        rdtsc(a,b);
        do {
                rdtsc(a,c);
        } while((c-b) < loopsPerMs);    // Really Us
}

void usleep(ulong us)
{
        for(;us;us--)
                __1sleepRdtsc();
}

void sleep(ulong ms)
{
        for(;ms;ms--)
                usleep(1000);
}
#else
// delays for x ms
void sleep(ulong ms)
{
        ulong t;
        for(;ms;ms--)
                for(t=loopsPerMs;t;t--)
                        /* Wait */;
}

// delays for x us
void usleep(ulong us)
{
        ulong t;
        for(;us;us--)
                for(t=loopsPerUs;t;t--)
                        /* Wait */;
}
#endif
// END

Reply via email to