|
|
1.1 root 1: .de EX
2: .DS
3: .ft CW
4: ..
5: .de EE
6: .ft
7: .DE
8: ..
9: .de CW
10: \&\\$3\f(CW\\$1\\fP\\$2
11: ..
12: .de CP
13: .IP "\&\\$3\f(CW\\$1\\fP\\$2" .7i
14: ..
15: .de Bh
16: .NH
17: ..
18: .de Sh
19: .SH
20: ..
21: .Bh
22: What
23: .CW mkconf
24: gets
25: .PP
26: There are three interesting files read:
27: one describing the devices and drivers
28: that may be configured,
29: one describing the system control block,
30: and one listing the pieces to be configured
31: into the particular system being built.
32: .PP
33: General rules:
34: all the files contain
35: lines of text,
36: which are broken into fields
37: separated by white space.
38: .CW #
39: introduces a comment;
40: the remainder of the line is ignored.
41: When a field contains a number,
42: it is interpreted as hexadecimal
43: if introduced by
44: .CW 0x ,
45: octal if by
46: .CW 0 ,
47: decimal otherwise.
48: .Sh
49: .CW devs
50: .PP
51: The master list of devices and drivers
52: lives in a file called
53: .CW devs .
54: This contains one line
55: for each device, driver, or driver-like entity
56: that may be added to the system.
57: Each line is of the form
58: .EX
59: name tag things
60: .EE
61: .PP
62: .CW Name
63: is the name of the thing described.
64: It need have nothing to do with
65: filenames,
66: driver entry points,
67: or anything else;
68: it is used only by
69: .CW mkconf .
70: .PP
71: .CW Tag
72: is a string known by the driver,
73: prepended to entry points in
74: (e.g.)
75: .CW conf.c .
76: .PP
77: .CW Things
78: are various bits of information:
79: which table the driver should be entered in,
80: what sort of addressing this device requires,
81: and some miscellaneous hacks.
82: They are encoded as words,
83: sometimes followed by other words.
84: .PP
85: Tables are encoded by
86: .CP bdev
87: Block device driver;
88: enter in
89: .CW bdevsw .
90: .CP cdev
91: Character device driver;
92: enter in
93: .CW cdevsw .
94: .CP fs
95: File system driver;
96: enter in
97: .CW fstypsw .
98: .CP ld
99: Stream line discipline;
100: enter in
101: .CW streamtab .
102: .LP
103: Each of these should be followed by a number,
104: which is used as the index in the table;
105: e.g.
106: .CW "bdev 3"
107: means the block device
108: with major number 3.
109: It's perfectly acceptable
110: to enter a driver
111: in several tables
112: (e.g. block and character device)
113: or in no table at all;
114: device addresses and the like are declared anyway if appropriate.
115: .PP
116: Address type words are
117: .CP sbi
118: This is an old-fashioned (SBI or CMI) nexus device.
119: .CP vaxbi
120: This is a VAXBI device.
121: .CP mb
122: This is a MASSBUS device.
123: .CP ub
124: This is a UNIBUS device.
125: .CP sub
126: This is a subdevice
127: (like a disk drive connected to a controller).
128: .CP count
129: This device has no address,
130: but needs to know its count anyway.
131: (Perhaps there are data structures.)
132: .LP
133: Again,
134: it's permissable
135: not to specify any address type at all;
136: this simply means
137: .CW mkconf
138: won't bother to print an address.
139: .PP
140: Some words indicate that the device
141: is an adapter into which other devices
142: (with one of the address types above)
143: are plugged:
144: .CP sbia
145: SBI adapter.
146: .CP bia
147: VAXBI adapter
148: .CP mba
149: MASSBUS adapter.
150: .CP uba
151: UNIBUS adapter.
152: .LP
153: By preference,
154: new adapter types
155: should be named by appending
156: .CW a
157: to the corresponding address name.
158: .PP
159: Other hacks:
160: .CP vec " n"
161: Vector size.
162: Devices are generally assumed to have
163: one interrupt vector
164: (if any, depending on address type).
165: .CW "vec 3"
166: means the device
167: really has three vectors,
168: presumably contiguous.
169: .CP rep " n"
170: Repeat count.
171: .CW "rep 8"
172: means there are really 8 devices
173: per device controller;
174: .CW mkconf
175: should scale counts by 8.
176: .PP
177: The magic word
178: .CW strs
179: introduces a list of data structures
180: associated with this device,
181: named by the remaining words on the line.
182: Obviously,
183: this flag must be last.
184: .Sh
185: scb
186: .PP
187: Annoyingly,
188: different VAXes have different low-level traps
189: in the system control block.
190: Hence,
191: for each kind of VAX
192: (or at least each variant kind of SCB)
193: there is an SCB template file.
194: .PP
195: The file contains lines like
196: .EX
197: offset type name label
198: .EE
199: meaning that traps to the given byte
200: .CW offset
201: are to be vectored to
202: .CW name .
203: The name is just a label in some assembly language routine
204: to which control should be transferred on the trap
205: with some arbitrary trap-dependent stuff on the stack.
206: It should be longword-aligned, as the low-order bits of the vector
207: are meaningful to the VAX.
208: .CW Type
209: is
210: .CW t
211: for traps that should be taken
212: on the kernel stack,
213: .CW i
214: for those that should be
215: on the interrupt stack.
216: .PP
217: It would be nice to eliminate this file entirely,
218: or at least cause there to be only one.
219: There must be something somewhere
220: as most of the system control block
221: consists of I/O vectors,
222: which
223: .CW mkconf
224: must generate,
225: or placeholders for stray interrupts,
226: which are best generated by a program.
227: .Sh
228: conf
229: .PP
230: This is the file
231: that describes what's to be configured
232: into a particular copy of the system.
233: Each real device
234: (individual object with an address)
235: takes up one line.
236: Each driver-like thing
237: (such as a line discipline)
238: takes up a line too.
239: .PP
240: Lines look like
241: .EX
242: name id addr ...
243: .EE
244: .CW Name
245: is one of the ones
246: in the
247: .CW devs
248: file.
249: .CW Id
250: is a sequence number.
251: It is used as an index
252: into data structures
253: (like the address)
254: generated by
255: .CW mkconf .
256: For honest devices
257: (that have entries in
258: .CW /dev )
259: the
260: .CW id
261: is probably related in some simple way
262: to the minor device number;
263: for devices that exist only as places to plug in other devices
264: (such as MASSBUS adapters
265: and UNIBUS disk controllers),
266: the
267: .CW id
268: is part of the address
269: for devices so plugged.
270: .CW Mkconf
271: uses the
272: .CW id
273: to connect devices to their adapters,
274: to build tables of addresses,
275: and to decide how many devices there are
276: (the highest
277: .CW id
278: plus one,
279: multiplied by the
280: repeat count).
281: .PP
282: Syntactically,
283: the address stuff
284: is just a handful of blank-separated numbers
285: whose interpretation
286: depends on the address type of the device:
287: .IP
288: SBI devices take an adapter number,
289: a nexus (TR) number,
290: and perhaps a vector base.
291: The adapter number
292: is useful when there's more than one bus,
293: is 0 otherwise.
294: The vector base is used for things like
295: UNIBUS adapters.
296: .IP
297: VAXBI devices
298: take an adapter number,
299: a node (TR) number,
300: a vector,
301: and perhaps a vector base.
302: .IP
303: MASSBUS devices
304: take an adapter number
305: (the
306: .CW id
307: of the corresponding
308: RH device)
309: and a unit number
310: (the controller number on the MASSBUS).
311: .IP
312: UNIBUS devices
313: take an adapter number
314: (the
315: .CW id
316: of the UNIBUS adapter),
317: a UNIBUS address,
318: and a vector.
319: Both the address and the vector
320: are relative to that UNIBUS.
321: .IP
322: Subdevices
323: take a controller number
324: and a unit number.
325: .PP
326: Devices that take only a count
327: are a special case:
328: the
329: .CW id
330: is really the count,
331: and there is no address
332: (or more exactly,
333: the address is ignored).
334: .Bh
335: What
336: .CW mkconf
337: puts out
338: .PP
339: .CW Mkconf
340: writes two files:
341: one with interrupt vectors,
342: one with tables and address stuff.
343: .Sh
344: scb.s
345: .PP
346: .CW Mkconf
347: writes one assembly language file
348: containing the SCB,
349: stray interrupt catching hooks,
350: and interface routines to call
351: interrupt handlers written in C.
352: .PP
353: Traps described in the SCB template file
354: are put out as entered.
355: Other interrupts are placed as described by the vectors
356: in the configuration file.
357: .CW Mkconf
358: doesn't know anything about,
359: say,
360: the peculiarities of comet UNIBUS adapters;
361: it's up to the person writing the
362: .CW conf
363: file to get it right
364: (in this case
365: by saying that the UNIBUS adapters have vector bases
366: at 0x200 and 0x400).
367: All I/O interrupts
368: are placed on the interrupt stack.
369: .PP
370: SCB slots with nothing assigned
371: are filled in with stray catchers.
372: In fact,
373: they are vectored into tables of
374: code of the form
375: .EX
376: straycatch:
377: .align 2; bsbw stray # here on stray interrupt from offset 0
378: .align 2; bsbw stray # offset 4
379: .align 2; bsbw stray # and so on
380: .
381: .
382: .
383: .EE
384: thus doubling the size of the SCB
385: (each page of vectors requires a page of stray catchers),
386: but making it possible
387: to see where strays come from.
388: .PP
389: .CW mkconf
390: only writes the tables;
391: .CW stray
392: is expected to be provided elsewhere in the system.
393: A plausible implementation might look like
394: .EX
395: stray:
396: pushr $0x3f # save some registers
397: subl3 $straycatch,7*4(sp),-(sp) # get offset of stray
398: calls $1,_strayintr
399: popr $0x3f
400: tstl (sp)+
401: rei
402: .EE
403: .PP
404: After the SCB,
405: .CW mkconf
406: writes a handful of interface routines of the form
407: .EX
408: Xdz31:
409: pushr $0x3f
410: pushl $3 # dz3
411: calls $1,_dz1int # call second interrupt
412: popr $3
413: rei
414: .EE
415: Device interrupt routines should be named
416: .CW xx0int ,
417: .CW xx1int ,
418: and so on for successive vectors,
419: where
420: .CW xx
421: is the tag for that device driver.
422: Even if there's only one interrupt vector,
423: the interrupt routine is named
424: .CW xx0int .
425: .Sh
426: conf.c
427: .PP
428: There are tables,
429: and per-device data structures.
430: .PP
431: The tables may be summarized as follows:
432: .EX
433: struct bdevsw *bdevsw[]; /* block devices */
434: struct cdevsw *cdevsw[]; /* character devices */
435: struct fstypsw *fstypsw[]; /* file systems */
436: struct streamtab *streamtab[]; /* line disciplines */
437:
438: int nblkdev, nchrdev, nfstyp, nstreamtab; /* number of entries */
439: .EE
440: The names need to be slightly straightened out
441: for consistency.
442: .PP
443: Note that the tables contain pointers
444: to entry point tables,
445: not the entry points themselves.
446: Empty slots in the tables
447: contain
448: .CW NULL
449: pointers.
450: .PP
451: A device driver is expected to define
452: an appropriate table entry
453: for each table it is entered in.
454: The table entry should be named
455: .CW xxbdev ,
456: .CW xxcdev ,
457: .CW xxfs ,
458: or
459: .CW xxstream
460: for the driver with tag
461: .CW xx .
462: .PP
463: Most drivers will expect
464: .CW conf.c
465: to define some data for them
466: as well.
467: A count of configured devices
468: will be defined:
469: .EX
470: int xxcnt;
471: .EE
472: The count is scaled by the repeat count,
473: if any;
474: e.g. declaring three DZ11s will probably cause
475: .CW dzcnt
476: to contain 24.
477: .PP
478: If the driver expects some address information,
479: it will be defined
480: with the name
481: .CW xxaddr .
482: The type of the data
483: and the meaning of its contents
484: depends on the kind of device;
485: see the section on addresses.
486: .PP
487: If the driver requested any structure definitions,
488: they will be there as well:
489: .EX
490: struct gumby xxgumby[N];
491: .EE
492: where
493: .CW N
494: is the same number as in
495: .CW xxcnt .
496: .PP
497: Things to think about:
498: it would be nice to declare,
499: e.g.,
500: inode table.
501: inode device with empty tag
502: (never mind the syntax),
503: but how do you get the count out?
504: .Bh
505: How devices are addressed
506: .Sh
507: The hardware model
508: .PP
509: There are buses,
510: to which adapters are attached.
511: Older VAXes have only one bus apiece
512: (the 780's SBI,
513: the 750's CMI);
514: newer ones can have several
515: (two SBIs on the 8600,
516: up to four VAXBIs on 8800-like machines).
517: .PP
518: Each bus contains some number of nexus
519: and some number of address windows.
520: A nexus is a space of 0x2000 bytes,
521: some of which are registers for the device at that nexus.
522: Sometimes the `device' is really a peripheral
523: (especially VAXBI devices,
524: but things like the DR780 as well),
525: but on older machines it is usually an adapter to some other kind of bus
526: (UNIBUS or MASSBUS).
527: UNIBUS adapters (and perhaps other adapters too)
528: need to allow the VAX to get at the address space they control;
529: hence the address windows.
530: .PP
531: The first few registers
532: in a nexus are usually well-defined,
533: but only for devices in the same bus
534: (e.g. SBI and VAXBI differ noticeably).
535: The low-order part of the first longword
536: is generally supposed to contain some sort of
537: nexus type code,
538: but even this is sometimes violated.
539: In general,
540: within a nexus,
541: all rules are off.
542: For example,
543: MASSBUS adapters
544: use part of their nexus space
545: for an array of eight sets of device registers
546: for each of eight possible multiplexed devices;
547: UNIBUS adapters
548: have registers controlling data paths;
549: memory controllers just have error flags.
550: .PP
551: Interrupt vectors are more poorly defined.
552: In some buses
553: (CMI, SBI),
554: nexus interrupts
555: are vectored to well-known places in the system control block,
556: determined by the interrupt priority and the nexus address.
557: In others
558: (VAXBI),
559: the vector is partly or wholly up to the software.
560: UNIBUS adapters
561: steal a whole page somewhere
562: for UNIBUS interrupts;
563: sometimes (CMI)
564: this is in a hard-wired place,
565: sometimes (VAXBI)
566: it must be set by software.
567: .Sh
568: The software model
569: .PP
570: The fundamental address unit is the nexus.
571: There is an array of nexus defined
572: in the system virtual address space.
573: It would be nice if the array could be at a fixed address,
574: but it's too hard to do.
575: Hence there's just a pointer to its base
576: which is initialized at boot time:
577: .EX
578: struct nexus {
579: char nx[0x2000];
580: char wind[0x40000];
581: } *nexus;
582:
583: /* who needs counts? */
584: int nexus_cnt = N;
585: .EE
586: .PP
587: The array bears no necessary resemblance to the
588: layout of nexus spaces in physical I/O space;
589: indices into
590: .CW nexus
591: are dreamt up by
592: .CW mkconf .
593: The appropriate mappings are set up
594: by machine-dependent startup code,
595: according to tables
596: generated by
597: .CW mkconf :
598: .EX
599: /*
600: * example: a typical 780
601: */
602:
603: struct nextab {
604: char bus;
605: char nex;
606: };
607:
608: struct nextab nextab[] = {
609: {0, 1}, /* ms780 */
610: {0, 8}, /* first rh780 */
611: {0, 3}, /* unibus adapter */
612: -1 /* end */
613: };
614: .EE
615: Bus numbers are defined in a machine-dependent,
616: presumably straightforward way;
617: nexus numbers are within the relevant bus.
618: It is assumed
619: that the mapping between
620: the bus and nexus numbers
621: and the corresponding address window
622: can be doped out by the machine-dependent startup code.
623: This is utterly straightforward in the VAXBI world.
624: Elsewhere it's a couple of simple special cases
625: (UNIBUS adapters have a known mapping,
626: other devices just don't get windows).
627: .PP
628: Why the configuration-dependent mapping
629: between real nexus numbers
630: and positions in the
631: .CW nexus
632: array?
633: Implementation horrors:
634: each nexus takes up 8kb of address space
635: for its registers,
636: and 256Kb for its window.
637: Address space isn't in short supply on the VAX,
638: but huge amounts of address space in the system
639: take up large quantities of physical memory
640: for system page table entries.
641: Hence it's nicer only to map
642: the nexus that matter.
643: The address windows are the bulk of the issue,
644: which is particularly annoying
645: because relatively few devices use them.
646: In practice,
647: older machines have relatively few nexus
648: (with or without windows),
649: and newer (VAXBI) systems
650: have a little more memory to waste,
651: so always mapping a (perhaps nonexistent) address window
652: isn't that great a burden (yet).
653: .PP
654: Interrupt vectors are harder to understand.
655: In older VAXes,
656: nexus interrupts go through vectors
657: in the second half of the first page of the system control block.
658: UNIBUS interrupts are handled in software (780)
659: or put into specific higher-numbered SCB pages.
660: In the 8600,
661: this is further complicated
662: by having two SBIs,
663: hence two pages of nexus interrupts.
664: In the VAXBI machines,
665: things are looser;
666: the vectors are really set in software,
667: though there are prefixes
668: (to point UNIBUS interrupts
669: or interrupts from a specific BI bus
670: to a particular page)
671: and arcane rules about the prefixes.
672: .PP
673: .CW mkconf
674: knows nothing about this mess.
675: In general,
676: it's necessary to specify the interrupt vector in the configuration file.
677: The fixed relationship between nexus number and vector
678: for SBI devices
679: is understood;
680: for VAXBI devices,
681: the vector must always be explicit.
682: In either case,
683: devices like UNIBUS adapters
684: and NMI-BI adapters
685: that have associated pages of
686: interrupts from the buses they control
687: require that the pages be named explicitly.
688: .Sh
689: What drivers are told
690: .PP
691: Device drivers
692: need to know the address
693: of the I/O registers interesting to them,
694: perhaps their interrupt vector and priority
695: (the latter is set in software on the VAXBI!),
696: and perhaps a cookie identifying the bus or adapter
697: to which their device is connected.
698: Different data structures are used
699: to pass this information
700: for different kinds of bus.
701: .PP
702: Unfortunately,
703: it's hard to specify the address exactly at compile time;
704: in practice it is given as a nexus index
705: and perhaps some kind of offset.
706: I/O adapters like the UNIBUS adapter
707: are expected
708: to provide routines
709: that map address structures
710: into virtual addresses in I/O space;
711: details are elsewhere.
712: .PP
713: SBI devices get
714: .EX
715: struct nxaddr {
716: short nexus; /* nexus number */
717: short adno; /* adapter number */
718: };
719: .EE
720: `Devices' here includes I/O adapters.
721: Interrupt vectors are assumed to be those
722: implied by the nexus number;
723: interrupts for all four BR levels
724: are sent to the same single interrupt routine.
725: If
726: .CW nexus
727: is \-1,
728: the device doesn't exist
729: (e.g. device 1 is configured
730: but device 0 isn't).
731: .PP
732: MASSBUS devices get
733: .EX
734: struct mbaddr {
735: char unit; /* MASSBUS unit number */
736: char mbno; /* adapter number */
737: };
738: .EE
739: .PP
740: The device doesn't exist
741: if
742: .CW unit
743: is \-1.
744: The MASSBUS adapter driver
745: will probably want to supply entry points
746: yielding both the address of the device registers proper
747: (determined by the unit number)
748: and just the MASSBUS registers
749: (to check for errors after a transfer).
750: .PP
751: What do we do about interrupt vectors?
752: A MASSBUS can only have one transfer going at a time,
753: but when that transfer completes
754: there can be several devices needing attention.
755: Pretty clearly the vectors in the SCB
756: need to point to the MASSBUS adapter code,
757: not that for the device on the MASSBUS;
758: the mba driver
759: has to have some way to forward the interrupts on
760: to the correct driver,
761: though.
762: Maybe some dynamic registry is appropriate;
763: consider it to be like mapping.
764: .PP
765: UNIBUS devices get
766: .EX
767: struct ubaddr {
768: long uboff; /* UNIBUS space address */
769: short vec; /* unibus vector, not scb */
770: short ubno; /* UNIBUS adapter number; implies nexus */
771: };
772: .EE
773: .PP
774: If
775: .CW uboff
776: is zero,
777: the device doesn't exist.
778: There are already devices that need the vector
779: (UDA50);
780: there will doubtless be more.
781: .PP
782: VAXBI devices probably need
783: .EX
784: struct biaddr {
785: short nexus; /* BI device nexus */
786: short vec; /* error interrupt */
787: short ovec; /* controlled devices */
788: short adno; /* adapter, e.g. NBI */
789: };
790: .EE
791: If
792: .CW nexus
793: is \-1,
794: the device doesn't exist.
795: .CW Vec
796: is the vector for the BI device itself;
797: .CW ovec
798: is the base of the page of interrupts
799: belonging to the device,
800: if it's a bus adapter
801: like the DWBUA.
802: .CW Vec
803: is always the vector
804: used for BIIC-generated errors.
805: If the device wants to have a separate interrupt
806: for I/O completion
807: (using, say, the UIR),
808: it should be described as having
809: multiple vectors,
810: which will have consecutive addresses.
811: The interrupt priority level is set in software
812: for some VAXBI devices,
813: but this might as well be a manifest in the driver
814: as it's rather inconvenient for it not to be a known constant
815: (e.g. for
816: .CW spl
817: calls).
818: .PP
819: There are also funny `subdevices',
820: which are addressed merely as sub-pieces of some controller.
821: The usual example is disk drives on a UNIBUS controller;
822: one needs to know about the controllers as entities,
823: but also about the individual drives.
824: These get
825: .EX
826: struct subaddr {
827: short ctl; /* controller number */
828: short unit; /* unit number within the controller */
829: };
830: .EE
831: where ctl and unit are in a language known only to the driver.
832: If
833: .CW ctl
834: is \-1,
835: the device doesn't exist.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.