Path: utzoo!utgpu!water!watmath!clyde!rutgers!husc6!hao!boulder!forys From: forys@sigi.Colorado.EDU (Jeff Forys) Newsgroups: comp.unix.wizards Subject: Re: BSD internals/ether/software intrs Summary: Emulate it with software! Message-ID: <4103@sigi.Colorado.EDU> Date: 1 Feb 88 22:37:51 GMT References: <3522@megaron.arizona.edu> <402@sering.cwi.nl> <13676@oliveb.olivetti.com> <10346@mimsy.UUCP> <454@cosmo.UUCP> Reply-To: forys@boulder.Colorado.EDU (Jeff Forys) Organization: University of Colorado, Boulder Lines: 57 In article <454@cosmo.UUCP> jum@cosmo.UUCP (Jens-Uwe Mager) writes: > In article <10346@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: > > on the Vax and the Tahoe, using the Software Interrupt Request > > Register, SIRR. There is a macro called `setsoftnet', defined as > > > > #define setsoftnet() mtpr(SIRR, 12) > > > > which asks the machine to generate an interrupt at IPL 12 as soon > > as it may. There is another macro called `schednetisr', which sets > > gee, how do they do that on a 680xx ? setting flags ? What do you usually do when the hardware doesnt provide something? Why, you emulate it with software, of course! BSD kernels I've seen provide software triggering of interrupt service routines to simulate things like a Software Interrupt Request Register. Basically, you need a routine to add interrupts to a linked list of functions, and another routine to process these functions later when the time is right. So, with much abbreviated, setsoftnet() might become: struct { func_t sw_func; /* function to call on trigger */ caddr_t sw_arg; /* arguments */ char priority; /* level of interrupt */ struct sw_trig *sw_next; /* next... */ } *sw_trigger; add_interrupt(func, args, priority) { s = spl6(); /* insert func into prioritized linked list of soft calls */ splx(s); } process_interrupts() { while (1) { s = spl6(); /* pull next function off queue */ splx(s); if (queue empty) return; (*func)(args); } } netintr() { /* To raw protocol input routines */ } setsoftnet() { /* finally! */ add_interrupt(netintr, (char *)0, 1); } No two ways are identical, but you should get the general idea. Oh, for completeness, the call to process_interrupts() would come out of locore. --- Jeff Forys @ UC/Boulder Engineering Research Comp Cntr (303-492-4991) forys@boulder.Colorado.EDU -or- ..!{hao|nbires}!boulder!forys