[comp.sys.att] Those LEDs in the UNIXpc, one last time;

jbm@uncle.UUCP (John B. Milton) (10/11/88)

This is the first in a series of interesting hardware notes.

Yes, there are LEDs in the UNIXpc. They located on the left side of the system
near the front. There are four of them, and this is what they really do while
unix is running:

(left to right)

0 RED:    This is the "user LED". It can be turned on and off with the
          syslocal(2) call. It is not used by any existing applications.
1 GREEN:  This is the one most people get wrong. This LED toggles everytime
          there is a process context change, and is cleared on the whole second
2 YELLOW: This is the idle LED. When it is on, there are no processes in the
          ready to run state.
3 RED:    Heart beat LED. This is toggled on the whole second.

In the I/O scheme of things, they are the low 4 bits of the Micellaneous
Control Register (MCR), at address $4A0000, word access. See the file
/usr/include/sys/hardware.h for more detail.

The user LED comes in handy when goofing around with drivers and when eprintf
would be too expensive. The problem comes with the other bits of the MCR.
Since the MCR is write only, you can't read it to get the current state. The
kernel takes care of this by having a "last written value" variable, in this
case called mcr_save:
/*	mcr_save must be written to whenever the real MCR is written to. */
extern ushort	mcr_save;
#define led_on(x)	*MCR_ADDR = (mcr_save &= ~(ushort)(x))
#define led_off(x)	*MCR_ADDR = (mcr_save |= (ushort)(x))
#define led_toggle(x)	*MCR_ADDR = (mcr_save ^= (ushort)(x))

As as an example, "led_on(LED0)" produces the code:
	and.w	&65279,mcr_save
	mov.w	mcr_save,4849664
Note that since there is no locking here, an interrupt routine that uses the
MCR could run between these two instructions. Knowing which interrupt routines
use the MCR would provide the right kind of information to use the spl stuff
<sys/spl.h> correctly to avoid trouble.

Stay tuned.

John
--
-- 
John Bly Milton IV, jbm@uncle.UUCP, n8emr!uncle!jbm@osu-cis.cis.ohio-state.edu
home (614) 294-4823, work (614) 764-4272;  Send vi tricks, I'm making a manual

ditto@cbmvax.UUCP (Michael "Ford" Ditto) (10/12/88)

In article <357@uncle.UUCP> jbm@uncle.UUCP (John B. Milton) writes:
>As as an example, "led_on(LED0)" produces the code:
>	and.w	&65279,mcr_save
>	mov.w	mcr_save,4849664
>Note that since there is no locking here, an interrupt routine that uses the
>MCR could run between these two instructions.

But also note that this is not a problem if the interrupt routines only
*write* to the mcr and mcr_save (which should be the case) because
mcr_save is updated first.  The only potential problem is if an interrupt
routine *reads* mcr_save assuming that the hardware is in the same
state.  I don't know of any need to read mcr_save, so I doubt that this
is ever done.
-- 
					-=] Ford [=-

"The number of Unix installations	(In Real Life:  Mike Ditto)
has grown to 10, with more expected."	ford@kenobi.cts.com
- The Unix Programmer's Manual,		...!sdcsvax!crash!elgar!ford
  2nd Edition, June, 1972.		ditto@cbmvax.commodore.com

jbm@uncle.UUCP (John B. Milton) (10/15/88)

In article <4975@cbmvax.UUCP> ditto@cbmvax.UUCP (Michael "Ford" Ditto) writes:
>In article <357@uncle.UUCP> jbm@uncle.UUCP (John B. Milton) writes:
[ mcr_save update code ]
>But also note that this is not a problem if the interrupt routines only
>*write* ...  but is if *read*




I stand corrected

John
-- 
John Bly Milton IV, jbm@uncle.UUCP, n8emr!uncle!jbm@osu-cis.cis.ohio-state.edu
home (614) 294-4823, work (614) 764-4272;  Send vi tricks, I'm making a manual