From: MERC::"uunet!CRVAX.SRI.COM!RELAY-INFO-VAX" 16-MAR-1993 00:01:26.52 To: Info-VAX@KL.SRI.COM CC: Subj: Re: kernel routines in C (solved) In article <1993Mar3.152100.76@tachyon.lonestar.org>, wayne@tachyon.lonestar.org (Wayne Sewell) writes: > Is anyone writing kernel mode code in C? If so, how do you prevent the > change-mode dispatcher from destroying registers? > > I have been writing kernel code for a long time, and have no problem with the > mechanics of change-mode dipatchers or the cmkrnl system service. Due to the > coming of Alpha, I have decided not to write any more macro code, and have > started implementing privileged code in C instead. > > As long as you are careful what you do, there is no reason you can't have > kernel code in C. I have been using C for FDT-stealing routines, user-written > system services, and other things. > > The problem is that I have to fight the system a little to do so. > > When you call a user written system service, the change-mode dispatcher puts > the address of the PCB into register 4. Same thing with the $CMKRNL system > service. In both cases the routine being called must specify register 4 in its > save mask. Otherwise the calling program will suddenly find the PCB in > register 4. > > When calling a system service, user or otherwise, the registers are saved > according to the save mask of the transfer vector, which is itself derived from > the save mask of the actual procedure. Thus only the registers specified by > the called procedure are saved. > > This is no problem in macro, but in C you have no control over the register > save mask of a function, as far as I know. C keeps track of its own register > usage and saves only the registers it has personally destroyed within the > procedure. It doesn't know that the dispatcher clobbered register 4 before > calling the function. > > I tried to force C to save register 4 by calling the builtin function > _WRITE_GPR (write general purpose register). I thought if I deliberately > destroyed register 4 myself within the procedure, that would force C to save > it. No effect, much to my surprise (that makes me wonder about the viability > of those builtin functions). > > I finally solved the problem by dorking around with the transfer vectors. In > my transfer vectors for kernel C routines, the .transfer statement points to > the actual routine the way it's supposed to, but the .mask statement points to > a dummy mask that saves all registers. Kludgy, I know, but it works. Now my > system services written in C operate normally and register 4 isn't destroyed > any more. > > I do something similar for cmkrnl by calling a macro jacket routine. > > These methods work okay. I was just wondering if there was a better way. > > Wayne > > -- > Wayne Sewell |INET: wayne@tachyon.lonestar.org The problem has been solved over in vmsnet.internals. > You can do: > .MASK foo,^m > > (I just digested a V4 MACRO manual last night :-) > Kenn Humborg > elehumborg@orbsen.ucg.ie This is the solution to the problem. It turns out you *can* OR an arbitrary value into the mask. I have been programming in macro for over ten years, but I didn't know that .mask could do that. I wonder if it was a recent addition, or the capability has been there all along (obviously it was in V4, according to the above). This technique can be used for *all* user written system services, not just those written in C. If you do this, you don't have to remember to add R4 to the save mask of a macro routine. Wayne -- ============================================================================== Wayne Sewell |INET: wayne@tachyon.lonestar.org Tachyon Software Consulting |UUCP: ...!{letni,mic}!tachyon!wayne P. O. Box 550937, Dallas TX 75355-0937 |Voice: (214)-553-9760, Fax: -553-0077 ============================================================================== Curly: "I keep tryin' to think, but nuthin' happens!"