jeffrey@masscomp.UUCP (Jeff Jones) (10/15/87)
I am working with a driver that must wait for a specified period of time (usually less than one second) after issuing a command before assuming that a device is not present. This must happend during device initialization time. There are no real time clock interrupts during the device initialization phase of our kernel. The system time counter (lbolt in our case) does not get incremented HZ times per second until after all devices are initialized. So, How do you determine how much time has expired when you have no real time clock interrupt? One would suppose the answer would be to set up a loop with a specific number of instructions and then have some macro that tells you how many of these loops occur per second. But that would entail changing the macro everytime you change the clock rate of the processor (or changing the contents of the loop). This is also somewhat non-deterministic due the fact that the loop may or may not be in an instruction cache. I am curious to find our how others have dealt with this problem. Thanx, jeff jones
chris@mimsy.UUCP (Chris Torek) (10/16/87)
In article <2414@masscomp.UUCP> jeffrey@masscomp.UUCP (Jeff Jones) writes: >I am working with a driver that must wait ... after issuing a command >before assuming that a device is not present. This must happend during >device initialization time. ... There are no real time clock interrupts >during the device initialization phase of our kernel. > How do you determine how much time has expired > when you have no real time clock interrupt? My UDA50 driver has the same problem. On Vaxen, there is a CPU register called TODR (Time Of Day Register) that is incremented once every millisecond, so to wait for one second, one could use register int timo = mfpr(TODR) + 1000; while ((device->status & READY) == 0) if (mfpr(TODR) >= timo) return (0); /* device never went ready */ Alas, not *all* Vaxen have a TODR---in particular, the Microvax series and (I believe) the 8800. For now, I changed mfpr(TODR) to a call to todr(): register int timo = todr() + 1000; while ((device->status & READY) == 0) if (todr() >= timo) return (0); The routine todr() then reads (approximately) todr() { switch (cpu) { case VAX_8600: case VAX_8200: case VAX_780: case VAX_750: case VAX_730: return (mfpr(TODR)); case VAX_630: /* hack */ { static int t; DELAY(10000); return (++t); } } It is sort of a hack, but it works. Since it is used only at boot time, it need not be very accurate---and it is better than having the machine hang if a device gets stuck. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
boykin@custom.UUCP (Joseph Boykin) (10/16/87)
In article <2414@masscomp.UUCP>, jeffrey@masscomp.UUCP (Jeff Jones) writes: > I am working with a driver that must wait for a specified period of > time (usually less than one second) after issuing a command before > assuming that a device is not present. This must happend during > device initialization time. > > There are no real time clock interrupts during the device initialization > phase of our kernel. The system time counter (lbolt in our case) does > not get incremented HZ times per second until after all devices > are initialized. So, > > How do you determine how much time has expired > when you have no real time clock interrupt? There are two solutions which I've used. One has the advantage that you don't have to do anything, the other means you might have to do a little patching after the kernel is built. 1) Since you're doing this at initialization time and hence not overly concerned about real-time performance, and since the timeout is relatively short, I would just wait long enough for your 'best' CPU performance. If you're running a 10MHz 68000 vs. a 25MHz 68020 with cache the same code for the 68K will timeout in, say, 3 seconds instead of 0.5. Not great, but not a disaster either. 2) Just as you patch the kernel once to change the 'uname' structure to whatever name you want your system to have, add another location (or struction) which has whatever other info you might find useful. I've including things such as clock rate, CPU type, Kernel virtual offset, plus any other tunable parameters I thought would be of use. -- Joe Boykin Custom Software Systems ...necntc!custom!boykin
rneitzel@udenva.cair.du.edu (RICHARD NEITZEL ) (10/27/87)
In article <2414@masscomp.UUCP> jeffrey@masscomp.UUCP (Jeff Jones) writes: >I am working with a driver that must wait for a specified period of >time (usually less than one second) after issuing a command before >assuming that a device is not present. This must happend during >device initialization time. > >There are no real time clock interrupts during the device initialization >phase of our kernel. The system time counter (lbolt in our case) does >not get incremented HZ times per second until after all devices >are initialized. So, > > How do you determine how much time has expired > when you have no real time clock interrupt? > Well, if you have a clock board in the system that you can use to count down times you can load the desired time into the clock board and then loop on its done bit. This assumes that the board has a done bit of course. I have used this for DEC's KWV11-C and I am sure that similar boards are available for other buses. The nice thing about this method is that you need only one clock board, since you can use the board under interrupt control later. Rich Neitzel "Any job not worth doing is not worth doing well." "Make people think they think and they will love you; make them think and they will hate you."