1 :Info: page_control_check.gi: pcc.gi:
2 2023-04-21 Multics Storage System consistency checker
3
4 Multics Storage System -- composed of
5 Segments
6 Tree-structured Data Base -- composed of
7 Directory Segments -- each tree node containing
8 Directory header
9 Directory entries -- each describing a segment in the tree.
10
11
12 Purpose of the storage system:
13 The Multics Storage System, and its Segment Control, Page Control,
14 Directory Control, and Disk Control subsystems manage the services
15 which:
16 - store data permanently or temporarily in segments; and
17 - allow a user program to directly access contents of non-directory
18 segments.
19
20
21 A variety of data structures participate in providing these services.
22 The azm page_control_check pcc request reports inconsistencies in
23 the relationships between the Segment Control and Page Control data
24 structures.
25
26 A user trying to interpret pcc output needs to understand how the
27 memory workspace of a process is tied to segments in the Multics
28 Storage System; and how Segment Control, Page Control, and Disk Control
29 cooperate to load a page from disk into hardware memory when the
30 corresponding page of a segment is referenced: a service called
31 "Demand Paging".
32
33
34 The next few sections introduce the Multics Storage System as viewed by
35 the pcc request. The checking and inconsistency reports produced in
36 the pcc output stem from this specialized viewpoint.
37
38
39 Multics storage system:
40 The basic unit of storage in the Multics Storage System is the segment.
41 Segments form a tree-structured data base that is organized by a
42 hierarchy of directories.
43
44 The azm page_control_check pcc request views each "segment" as an
45 individual memory region directly accessible to a program running in a
46 process.
47
48
49 Each segment holds a different type of data. Data types include:
50 - an executing user program;
51 - a stack containing subroutine call history and automatic variables
52 used by each called subroutine in a particular ring-of-execution;
53 - program input or output data;
54 - library subroutines;
55 - a gate to supervisor subroutines in an inner ring;
56 - the actual supervisor subroutines;
57 - supervisor data;
58 - a directory which catalogs attributes of other segments and their
59 location within the tree-structured directory hierarchy.
60
61
62 For details about the Storage System, refer to the Multics
63 Programmer's Reference Manual order AG91-04A. Section 2 introduces
64 the Storage System segments and directories, and describes using an
65 absolute pathname to identify segments, directories and links.
66
67
68 Storage system terms:
69 A "directory segment" is a special type of segment accessible only by
70 programs executing in ring-0. It contains:
71 - a header >ldd>incl>dir_header.incl.pl1 describing location of
72 the directory within the tree, and various attributes of the
73 directory segment;
74 - a list of "directory entries" >ldd>incl>dir_entry.incl.pl1.
75 Each describes attributes of a tree item located just below the
76 containing directory's position within the hierarchy. Each tree
77 item is either:
78 - a "non-directory segment": a leaf of the tree holding data;
79 - a "child directory": a directory describing tree elements at an
80 immediately inferior level of the tree; or
81 - a "link": a character-string pathname locating another item of
82 the tree.
83
84
85 The term "segment" usually refers only to a non-directory segment; but
86 in some contexts, it may include both non-directory and directory
87 segments.
88
89 The term "directory" refers only to a "directory segment". Actual
90 contents of a directory may be referenced or changed only by programs
91 of the Directory Control subsystem which execute in the ring-0
92 supervisor.
93
94
95 Any segment or directory can be located by one of the "names" attached
96 to its entry. The entry is stored within the directory immediately
97 superior to the segment in the Storage System hierarchy: its "parent
98 directory". That directory is located in the same manner by a name on
99 its entry in a superior directory and so on, up to the "root" or
100 top-most directory of the inverted tree.
101
102 The concatenation of all these names separated by ">" symbols forms
103 an "absolute pathname" that identifies a specific "item" non-directory
104 segment directory segment or link within the Storage System
105 hierarchy.
106
107
108 Programs executing outside of ring-0 may call Directory Control
109 services subroutines to:
110 - use an "absolute pathname" to identify a particular item in the
111 Storage System hierarchy.
112 - list items entries in a particular directory.
113 - create, delete, or rename a specific item in a directory.
114 - get or set other attributes of an entry access length etc..
115
116
117 Segment Control provides additional services for non-directory segments
118 including:
119 - "initiating a segment": making it known as a segment in the virtual
120 memory workspace of a process so contents of the segment can be
121 referenced or changed by instructions of a user program executing in
122 that process.
123 - truncating, setting bit-count and maximum length in words of the
124 segment.
125 - "terminating the segment": removing knowledge of that segment from
126 the process workspace.
127
128
129 The following azm general information topics introduce aspects of the
130 Multics Storage System, and provide details about data structures used
131 by its subsystems. Relationships between several of these structures
132 are checked by the pcc request.
133
134 Process Virtual Memory virtual_segment.gi.info
135 Permanent Storage on Disk for a Segment disk_segment.gi.info
136
137
138 Connect a Segment to a Process
139 A) Make Segment Known to the Process initiate_seg.gi.info
140 - Find segment information using the
141 directory hierarchy.
142 - Verify process has some access rights to segment.
143 - If segment is on a private LV: verify LV is mounted and
144 attached by the user process.
145 - Get KSTE and SDW for segment.
146 - Re-use existing KSTE/SDW if segment already in-use by
147 process, or has been used earlier in the login session.
148 - Extend seg access if ACL/RBs now grant write access.
149 OR
150 - Describe Segment to Hardware and Supervisor
151 - Fill-in faulted Segment Descriptor Word SDW
152 - Fill-in Known Segment Table Entry KSTE
153
154
155 B) Segment Fault When Accessed by the Process seg_fault.gi.info
156 - Find segment in, or add a segment to, the
157 List of Active Segments in-use by the system.
158 - Fill-in process access rights in SDW and KSTE.
159 - If process rights change encacheability of the segment,
160 change encacheability setting in SDWs of ALL referencing
161 processes.
162 - Add SDW Trailer Record STR to ASTE tracking this process as
163 referencing the active segment.
164
165
166 Demand Paging demand_paging.gi.info
167 Consistency Checks by page_control_check pcc_checks.gi.info
168
169
170 To learn about all of the data structures examined by the pcc request,
171 use the azm help h request to display the .gi segments in the order
172 suggested above. Begin with: help virtual_segment.gi
173
174 For details on the specific checks made by the pcc request, type:
175 help pcc_checks.gi
176
177
178 Use the azm list_help lh request to list all general information
179 topics provided by the analyze_multics subsystem: list_help .gi
180
181
182 :Info: process.gi: process_workspace.gi: virtual_segment.gi: virtual_segment: dseg.gi: sdw.gi: page_table.gi: ptw.gi: kst.gi: kste.gi:
183 2023-04-28 Components of a Process
184
185 User Process
186 - authorized by a Person_ID.Project_ID combination
187 - comprised of a
188 Running Program an execution point
189 Process Memory Workspace
190 Starting Directory the home directory
191 Starting Ring of Execution
192
193
194 Process Virtual Memory Workspace -- setup by the supervisor software
195
196 -- using HARDWARE REGISTERS
197
198 Descriptor Base Register DBR
199 - register describing the location and length of the
200 process' Descriptor Segment dseg.
201 - dseg defines memory workspace of the process using an array
202 of registers describing each virtual segment known to the
203 process.
204
205 Descriptor Segment dseg
206 - an array of SDW registers.
207 - a "segment number" or "segno" is the index used to select
208 elements from this array.
209
210
211 Segment Descriptor Word SDW register
212 - describes length and access attributes of a virtual segment.
213 - points to location of that segment in hardware memory.
214 - A "paged segment" locates hardware memory using a Page
215 Table.
216
217
218 Page Table
219 - an array of PTW registers - each locating a page section of
220 the data contained in the segment.
221 - a "page number" is the index used to select elements from
222 this PTW array. This page number specifies the order in
223 which the located section of data appears within the virtual
224 segment contents.
225
226 Page Table Word PTW register
227 - tells hardware whether contents of page has been loaded into
228 a hardware memory frame.
229 If loaded, PTW points to memory frame holding the data.
230 If ^loaded, PTW reference generates a "page fault" a type
231 of directed fault.
232
233
234 -- using SOFTWARE ANNOTATION
235
236 Known Segment Table kst
237 - a header summarizing virtual segments both directory and
238 non-directory segments in-use by a process.
239 - an array of KSTEs describing segments referenced outside of
240 the ring-0 supervisor of the process. A "segment number"
241 is the index used to select a KSTE in the array.
242
243 Known Segment Table Entry KSTE
244 - gives details to the supervisor about a particular virtual
245 segment in-use by the process information that won't fit
246 into the segment's SDW.
247 - a KSTE is tied by its segment number to the SDW which
248 describes the hardware characteristics of the segment.
249
250
251 Process owners give access to resources:
252 A process is usually created by a login pre-access request; or by an
253 enter_abs_request ear queue entry. This request or entry specifies
254 the "owners" of the created process: a Person_ID and Project_ID
255 combination that authorize access to computer resources cpu time
256 memory space data stored on disk etc. The Project_ID owner is
257 billed for resources used by the executing process.
258
259
260 PROCESS EXECUTION POINT:
261 When a new process is created, its project and person registrations
262 perhaps overridden by login arguments specify:
263 - a starting program process overseer; and
264 - a starting ring of execution usually ring-4 or ring-5.
265 - a "home directory" which starts as the working directory for the
266 process.
267
268
269 The process overseer program running in that starting ring "calls"
270 selects for execution a "listener program" that: prompts an
271 interactive user for command lines; or reads such lines from an
272 absentee input script .absin segment. For each command line, it
273 calls the command programs specified in that line, passing other
274 values on the line as argument strings.
275
276
277 A "program" is a non-directory segment containing instruction words.
278 The Central Processing Unit CPU reads instruction words sequentially
279 from the called program, beginning with the instruction located at a
280 "named program entry point" or just "entry point". Rather than
281 executing the next instruction in sequence, the program may use a
282 transfer instruction to jump to an instruction at a named location
283 within the program; or may use the CALL6 instruction to "invoke another
284 subroutine": switch to a named program entry point in another segment.
285
286
287 Procedure pointer register:
288 The Procedure Pointer Register PPR is a CPU register that tracks the
289 "execution point" for that process: the instruction being executed,
290 specified by:
291 - its offset within a given program segment, and
292 - its current ring of execution.
293
294 For user programs, this "ring of execution" is the starting ring
295 selected when the process was created usually ring-4 or ring-5.
296
297
298 An executing program can use the CALL6 instruction to invoke another
299 subroutine in the same segment, or in a different segment. CALL6
300 adjusts PPR contents to move the execution point to a named program
301 entry point holding instructions of the target subroutine. In this
302 fashion, the computer software and hardware cooperate to maintain a
303 single "execution point" for the process.
304
305
306 If the executing program needs a privileged service, it can use CALL6
307 to invoke a "gate entry point" which transfers to a specific supervisor
308 subroutine entry point running in an inner lower-numbered more
309 privileged ring of execution such as ring-0. After the requested
310 service has been provided, the supervisor subroutine returns to its
311 caller; and the ring-of-execution reverts back to that of its calling
312 program.
313
314 Using this method, the PPR tracks the execution point as it flows
315 between rings of execution: shifting from user code... into the
316 supervisor... and then back to user code.
317
318
319 For information about the Multics Ring Mechanism, see the Multics
320 Programmer's Manual Reference Guide Order No. AG91, page 6-22 and
321 following pages.
322
323
324 PROCESS MEMORY WORKSPACE:
325 The "memory workspace" of a process includes all of the user programs,
326 library subroutines, and data segments needed to run programs in the
327 process.
328
329 Each process workspace includes the entire ring-0 supervisor, enabling
330 the process to call gates into inner rings to obtain supervisor
331 services; and permitting the supervisor to:
332 - monitor I/O operations initiated by the process;
333 - handle fault events triggered by that process; and
334 - respond to interrupts generated by actions of that or other
335 processes.
336
337
338 Virtual segment:
339 The "process memory workspace" is divided into virtual segments. Each
340 "virtual segment" is an individual memory region directly accessible
341 to the program running in the process.
342
343 Each virtual segment holds a different type of data. Data types
344 of a "non-directory segment" include:
345 - an executing user program;
346 - a stack containing subroutine call history and automatic variables
347 used by each called subroutine in a particular ring-of-execution;
348 - program input or output data;
349 - library subroutines;
350 - a gate to supervisor subroutines in an inner ring;
351 - the actual supervisor subroutines;
352 - supervisor data.
353
354
355 Data in a "directory segment" organizes the Storage System segments
356 into an inverted tree structure in which each segment may be identified
357 by its location within the tree. The Directory Control subsystem
358 maintains directory segments in ring-0, and provides services for
359 finding or listing segments by their tree location an "absolute
360 pathname" character string.
361
362
363 Descriptor segment:
364 The workspace of each process is described by two ring-0 segments:
365 - a special "descriptor segment" pd>dseg used by the
366 hardware;
367 - with supporting information for each non-ring-0 virtual segment
368 known to the process held in its "known segment table" pd>kst.
369
370 The "descriptor segment" holds only an array of hardware registers:
371 usually 1024 Segment Descriptor Words. The Initializer.SysDaemon
372 process 0 uses an 8-page dseg, and therefore supports up to 4096
373 SDWs the maximum number of segments supported by the Packed Pointer
374 Register format which has a 12-bit segment number field.
375
376
377 Each process has its own dseg and kst segment stored in its process
378 directory: a directory inferior to the >process_dir_dir >pdd
379 directory. The absolute pathname of that process directory is
380 returned by the pd active function.
381
382
383 Segment descriptor word:
384 Segment Control software defines each "virtual segment" of a process
385 to the hardware the "Appending Unit APU" of the processor using a
386 "Segment Descriptor Word SDW" register.
387
388 Segment Control uses the SDW to tell the appending unit SW -> HW:
389 - the location and length of the virtual segment contents in hardware
390 memory sdw.add sdw.bound;
391 - which instruction kinds can access data in the virtual segment:
392 - those that load data from the segment sdw.read;
393 - those that process data words as instructions sdw.execute;
394 - those that store data into the segment sdw.write.
395 - which ring of execution hardware-protected level of service a
396 program must be running in to have access to the virtual segment
397 ring bracket values sdw.r1 sdw.r2 and sdw.r3.
398
399
400 Contents of each SDW register is stored in an even-word-aligned pair
401 of words in the dseg virtual segment. For purposes of this info
402 topic, the main elements of the SDW structure >ldd>incl>sdw.incl.pl1
403 are as follows:
404
405 dcl 1 sdw based sdwp aligned, /* Segment Descriptor Word */
406
407 2 add bit 24 /* absolute address in hardware memory*/
408 2 r1 r2 r3 bit 3 /* ring brackets for the segment */
409 2 df bit 1 /* "0"b = seg ^valid directed fault */
410 /* "1"b = seg valid no fault occurs*/
411 2 df_no bit 2 /* "00"b = fault treated as seg fault */
412 /* END OF WORD 1 */
413 ...
414
415
416 2 bound bit 14 /* segment length in 16 word blocks */
417
418 2 access /* access bits: */
419 /* a running program can... */
420 3 read bit 1 /* "1"b = read seg's bits/chars/words */
421 3 execute bit 1 /* "1"b = execute or transfer to seg */
422 /* words as instructions */
423 3 write bit 1 /* "1"b = write seg's bits/chars/words*/
424
425 3 privileged bit 1 /* "1"b = seg holding running program */
426 /* can include "privileged */
427 /* instructions" only allowed*/
428 /* in ring-0 supervisor code.*/
429
430
431 2 unpaged bit 1 /* "0"b = segment is paged */
432 /* "1"b = segment is unpaged */
433 ...
434 unaligned;
435
436
437 Unpaged virtual segment:
438 An unpaged segment is the simplest type of segment supported by
439 Multics memory access hardware. It designates a contiguous region of
440 hardware memory. As supported by the Multics operating system, an
441 unpaged segment may only be defined and used as part of the ring-0
442 supervisor. By definition, its content is not split into pages, so
443 segment content cannot be loaded as-needed by Demand Paging
444 mechanisms. It must be loaded during bootload of the operating
445 system, and permanently wired in hardware memory.
446
447
448 SDW settings for an unpaged virtual segment include...
449 sdw.unpaged = "1"b.
450 sdw.df = "1"b no segment fault occurs.
451 sdw.add = the absolute address hardware memory address of
452 first 16-word block in hardware memory at which the
453 virtual segment begins.
454 sdw.bound = count of contiguous 16-word blocks containing data
455 of the unpaged segment.
456 sdw.r1 = "0"b3 \
457 sdw.r2 = "0"b3 a ring-0 supervisor program or data seg
458 sdw.r3 = "0"b3 /
459 sdw.access set according to the type of data in the unpaged seg.
460
461
462 Every process includes three unpaged segments defined at the beginning
463 of hardware memory. Note the "U" flag shows value of the sdw.unpaged
464 bit in the following output from the azm sdw request.
465
466 azm: sdw 3 11
467 ADDRESS RNGS CA-MAX REWPUGCDF EBOUND SEGNO SEGMENT-NAME
468 3400 000 2777 R W UG DF 0 3 dn355_mailbox
469 0 000 577 R W UG DF 0 4 fault_vector
470 ...
471 1200 000 2177 R W UG DF 0 11 iom_mailbox
472
473
474 Paged virtual segment:
475 Most virtual segments of a process are subdivided into pages, each
476 page containing 1024 36-bit words of data. This permits segment
477 contents to reside in non-consecutive pages of hardware memory; and
478 allows access to data in mid-segment or near the end of the segment
479 without having to load the entire segment contents into hardware
480 memory enables "Demand Paging" for the segment.
481
482
483 SDW settings for a paged virtual segment may describe a segment from
484 1 to 256 pages in length. Each page is stored in a hardware "memory
485 frame" which: begins on a 1024-word boundary in hardware memory; and
486 holds 1024 words of data, each word being 36 bits long.
487 sdw.unpaged = "0"b.
488 sdw.df = "1"b no segment fault occurs.
489 sdw.add = absolute address of an even-word aligned Page Table.
490 sdw.bound = count of 16-word blocks in the virtual segment. The
491 paging hardware divides this count by 64 to determine
492 the count of non-contiguous pages comprising the
493 paged segment count of PTWs in its Page Table.
494
495
496 Note that most virtual segments are limited to a maximum length of 255
497 pages. For an introduction to 256 page segments, use the external help
498 command to display:
499 .. help 256K_segments.gi
500
501
502 Page table:
503 Each "Page Table" used to define a paged virtual segment is an
504 even-word-aligned array of hardware registers: Page Table Words
505 PTWs. Use of a Page Table enables the "Demand Paging" mechanism of
506 Multics Page Control: loading page content from disk into memory only
507 when a program first references the page. However, demand paging is
508 disabled for pages that are wired in hardware memory ptw.wired="1"b.
509
510
511 For purposes of this info topic, the Page Table's array of PTWs can be
512 described as follows:
513
514 dcl 1 ptwa 0:255 based ptp aligned like ptw; /* Page Table */
515
516
517 Index of a PTW in the page table array tells the paging hardware the
518 sequence of that page content within the virtual segment. Thus
519 ptwa0 locates the memory frame containing the first page of the
520 virtual segment; ptwa1 locates the memory frame containing its second
521 page; etc.
522
523
524 Page table word:
525 Each "Page Table Word PTW" exchanges information between Page
526 Control software and the Demand Paging hardware appending unit of the
527 processor. This exchange is bi-directional: SW <---> HW
528
529
530 By setting elements of the PTW, Page Control tells the paging hardware
531 SW --> HW:
532 - that page contents is now loaded into a hardware "memory frame":
533 a 1024-word aligned chunk of hardware memory ptw.df="1"b;
534 - absolute address of that memory frame in hardware memory ptw.add.
535
536 The paging hardware sets bits in the PTW telling Page Control
537 SW <-- HW that some program instruction has:
538 - used loaded data from that page ptw.phu="1"b;
539 - modified stored data into that page ptw.phm="1"b.
540
541
542 Page Control also uses bits in the PTW to remember that ...
543 - an I/O operation is in-progress into/from that page ptw.os="1"b;
544 - page content is wired unmoveable in hardware memory
545 ptw.wired="1"b, and cannot be evicted from hardware memory by
546 Page Control.
547
548
549 Contents of each PTW register is stored as a single word element of a
550 virtual segment's Page Table. For purposes of this info topic, the
551 main elements of the ptw structure >ldd>incl>ptw.incl.pl1 are:
552
553 dcl 1 ptw based ptwp aligned, /* Page Table Word */
554
555 2 add bit 18 /* page address add_type tells addr kind */
556 2 add_type bit 4 /* "1000"b = memory frame absolute address */
557 /* when page is valid in-memory*/
558 /* "0100"b = disk address */
559 /* "0000"b = null address page holds only */
560 /* zero bits: 36864"0"b */
561 ...
562 2 phu bit 1 /* "1"b = page has been used referenced */
563 ...
564
565
566 2 phm bit 1 /* "1"b = page has been modified */
567 ...
568 2 wired bit 1 /* "1"b = page is to remain in-memory */
569 2 os bit 1 /* "1"b = page I/O in progress */
570 2 df bit 1 /* "0"b = page ^valid directed fault */
571 /* "1"b = page valid no fault occurs */
572 2 df_no bit 2 /* "01"b = fault treated as a "page fault" */
573 unaligned;
574
575
576 A page of a virtual segment is valid accessible to a process if
577 its content has been read loaded into hardware memory. Page Control
578 sets the PTW elements to:
579 ptw.df = "1"b valid no page fault occurs.
580 ptw.add_type = "1000"b ptw.add contains an absolute memory address.
581 ptw.add = leftmost 18 bits of a 24-bit absolute address of the
582 memory frame in hardware memory holding page contents.
583 A page address is always aligned on a 1024-word
584 boundary. ptw.add = absadr_frame/64;
585
586
587 A page of a virtual segment is ^valid cannot be accessed by the
588 appending unit if its content is not loaded into hardware memory.
589 Page Control sets the PTW elements to:
590 ptw.df = "0"b ^valid fault occurs if program references
591 the page.
592 ptw.df_no = "01"b upon reference a "page fault" will occur
593
594
595 ptw.add_type = "0100"b "device address"
596 ptw.add contains record number of a disk
597 address holding page contents
598 = "0000"b "null address"
599 page contains only zero bits: 36864"0"b
600 so no disk record is assigned. Page
601 Control fabricates a page of zeros when
602 the page is referenced.
603 ptw.add = address record_no of a disk record on a physical
604 disk volume holding disk segment contents meaningful
605 only when add_type="0100"b.
606
607
608 Notes on disk device record numbers...
609 range of record_no values: 0:262143
610 where 262143 = 2**18 - 1.
611
612 The record_no = 0 value corresponds to a "null address". No disk
613 record is allocated for such record address.
614
615
616 Known segment table:
617 Segment Control maintains detailed information about each virtual
618 segment known to a process. Segment attributes and location in
619 hardware memory are held in hardware registers the SDW and a Page
620 Table holding PTWs accessible to the APU hardware. Those hardware
621 registers provide insufficient space to hold all details about the
622 virtual segment. These extra details tell Segment Control how to
623 re-connect records of a segment stored on disk with pages of a
624 virtual segment known to the process. The details are stored in a
625 software data segment called the Known Segment Table for the process.
626
627
628 The "Known Segment Table KST" pd>kst header specifies the range
629 of the process' workspace: how many segments the process is using.
630
631 Each "Known Segment Table Entry KSTE" describes a virtual segment
632 in-use by the process. Each KSTE is an element of the kst_entry array,
633 which is indexed by segment_number also known as: segno. No KSTE is
634 included for ring-0 segments which always remain "connected" to each
635 process: their SDWs are always valid sdw.df = "1"b.
636
637
638 The main structure elements >ldd>incl>kst.incl.pl1 are...
639
640 dcl 1 kst aligned based kstp, /* KST header */
641
642 2 lowseg fixed bin 17, /* lowest segment number */
643 /* outside range of the */
644 /* always connected segnos*/
645 /* seg 230o = stack_0 */
646 2 highseg fixed bin 17, /* highest segment number */
647 /* in process' dseg array.*/
648 2 highest_used_segno fixed bin 17,/* highest segment no used */
649 ...
650 2 free_list bit 18 unaligned, /* relp to 1st free kste */
651 /* Offset in kst seg */
652
653
654 ...
655 2 uid_hash_bucket 0 : 127 bit 18 unaligned,
656 /* hash buckets */
657 2 kst_entry 0 refer kst.lowseg:0 refer kst.highseg
658 aligned like kste, /* array of kst entries */
659 ...
660
661
662 dcl 1 kste based kstep aligned, /* KST entry */
663 2 fp bit 18 unaligned, /* forward relp to thread of */
664 /* KSTEs in a uid hash bucket*/
665 /* list or free KSTE list. */
666 2 segno fixed bin 17 unaligned, /* segment number */
667 ...
668 2 entryp ptr unaligned, /* branch pointer */
669 ...
670 2 uid bit 36 aligned, /* unique identifier */
671 2 access_information unaligned,
672 ...
673 3 extended_access bit 33, /* extended access from entry */
674 3 access bit 3, /* rew */
675 3 ex_rb 3 bit 3, /* extended ring brackets */
676
677
678 This completes the brief introduction to components of a process. To
679 display the next topic related to output of the azm page_control_check
680 pcc request, type: help disk_segment.gi
681
682
683 :Info: disk_segment.gi: disk_segment: disk_seg.gi: disk_seg: dir_entry.gi: entry.gi: vtoce.gi:
684 2023-04-06 Permanent Storage on Disk for a Segment
685
686 Disk segment -- permanent storage for a segment is comprised of
687 Directory Entry
688 - Logical attributes of the segment
689 Volume Table of Contents Entry VTOCE
690 - Physical attributes of the segment
691 - File map - an array of record_numbers record_no for the
692 segment in their order of appearance within the
693 data stream.
694
695
696 Physical disk volume -- comprised of
697 Physical disk label -- includes
698 - Physical Volume Name
699 - Physical Volume ID PVID
700 - Logical Volume Name
701 - Logical Volume ID LVID
702 Volume Table of Contents VTOC -- Array of VTOCEs
703 Disk records
704
705
706 Logical segment:
707 The Multics Storage System defines a "logical segment" as a
708 collection of related data stored as a stream of bits. The data
709 stream is maintained as:
710 - a sequence of fixed-length "records" each holding 36864 bits of
711 data 1024 36-bit words;
712 - a "bit count" which is the total segment length in bits.
713
714 Notice that each record of a logical segment contains the same number
715 of bits as a page of a virtual segment.
716
717
718 Each logical segment is stored permanently on disk as a non-directory
719 segment composed of --
720 - 1 to 256 records;
721 - a non-directory switch entry.dirsw="0"b;
722 - a bit count entry.bc.
723
724 Each directory segment is stored permanently as a disk segment
725 composed of --
726 - 1 to 255 records;
727 - a directory switch entry.dirsw="1"b;
728 - a zero bit count entry.bc = 0;
729 - ring brackets allowing access only by the ring-0 supervisor
730 entry.ring_brackets* = 0.
731
732
733 Permanent storage for a logical segment larger than 256 records is
734 also provided by the Storage System, but such a large segment cannot
735 be accessed directly as a virtual segment. Segments larger than 256
736 records won't be discussed further in any of these info blocks.
737
738
739 Segment's directory entry:
740 Each segment is identified to the Storage System by information
741 stored in its "directory entry" which includes ...
742 - A unique bit string identifying this segment entry.uid.
743 - One or more entry names attached to this directory entry
744 entry.nnames entry.name_frp and entry.name_brp.
745 - A unique bit string identifying the parent directory that contains
746 the entry describing this segment entry.owner.
747
748 Each "unique bit string" is unique on the Multics system among all
749 segments, directories, links, physical and logical volume IDs, etc.
750
751
752 A unique character string can be constructed to identify any segment
753 the segment's "absolute pathname" by concatenating a name from
754 segment's entry with a name from each superior directory, using a ">"
755 character to separate names from one another. The concatenation
756 continues until the name of the root directory is reached the ">"
757 directory. For example:
758 >udd>Project_ID>Person_ID>data_directory>my_seg.text
759
760 The directory entry describing the segment also includes:
761 - an identifier for the physical disk volume that contains segment
762 records entry.pvid;
763 - index of a VTOCE on that physical disk entry.vtocx;
764 - access control attributes read/write/execute modes for person
765 and/or project IDs; ring brackets; access class specification.
766
767
768 The entry structure >ldd>incl>dir_entry.incl.pl1 is word-aligned and
769 occupies 38 words in its "parent directory" segment. For purposes of
770 this info topic, the main elements of the entry declaration are:
771
772 dcl 1 entry based ep aligned, /* Directory Entry */
773 ...
774 2 uid bit 36, /* unique id of entry */
775 ...
776 2 dtem bit 36, /* date-time entry modified */
777 ...
778 2 nnames fixed bin 17, /* number of names for this entry */
779 2 name_frp bit 18, /* relp start of name list */
780 2 name_brp bit 18, /* relp end of name list */
781 /* Both are offsets in dir seg */
782 ...
783
784
785 2 primary_name bit 504, /* bits for 1st name structure */
786 /* see dir_name.incl.pl1 */
787 ...
788 2 pvid bit 36, /* physical volume id */
789 2 vtocx fixed bin 17, /* vtoc entry index */
790 ...
791 2 dirsw bit 1, /* "1"b - entry is a directory seg */
792 /* "0"b - entry is a non-dir seg */
793
794
795 ...
796 2 access_class bit 72, /* security attributes: */
797 /* level and category */
798 2 ring_brackets 3 bit 3, /* ring brackets on segment */
799 2 ex_ring_brackets 3 bit 3,
800 /* extended ring brackets */
801 2 acle_count fixed bin 17, /* number of entries on ACL */
802 2 acl_frp bit 18, /* relp to start of ACL */
803 2 acl_brp bit 18, /* relp to end of ACL */
804 /* Both are offsets in dir seg */
805 ...
806 2 bc fixed bin 24, /* bit count */
807 ...
808 2 owner bit 36; /* uid of parent directory which */
809 /* stores this entry. */
810
811
812 Segment's vtoce:
813 The physical attributes of the segment are stored in its "Volume Table
814 Of Contents Entry vtoce". They include:
815 - current segment length in records vtoce.csl;
816 - count of disk records in use by the segment vtoce.records;
817 - array of "disk addresses" each locating storage for a record of the
818 data stream vtoce.fm - its file map.
819
820
821 The "file map" describes the entire contents of the segment's data
822 stream using an array of disk addresses with dimension 0:255.
823 Each disk address is an 18-bit locator of a 1024-word record
824 on disk; or a "null disk address" = "000000"b3 which is
825 treated as a page of zero bits = 1024"000000000000"b3 for a
826 segment page that has never been written to disk.
827
828 Notice that the order of disk addresses in the file map corresponds
829 exactly with the order of pages presented in a virtual segment.
830
831
832 For a segment with null disk addresses within its entry.bc length of
833 its data stream, vtoce.csl will be larger than vtoce.records because
834 file map elements with a null disk address do not occupy record
835 locations on disk "000000"b3 does not designate any valid record on
836 the disk device.
837
838
839 The vtoce structure >ldd>incl>vtoce.incl.pl1 is word-aligned and
840 occupies 192 words in memory. For purposes of this info topic, the
841 main elements of the vtoce declaration are:
842
843 dcl 1 vtoce based vtocep aligned, /* VTOCE Entry */
844
845 2 uid bit 36, /* segment uid - "0"b if vtoce free */
846 2 msl bit 9, /* max seg length - 1024-word units */
847 2 csl bit 9, /* current seg length - */
848 /* 1024-word units */
849 2 records bit 9, /* count of disk records in-use */
850 ...
851 2 dtu bit 36, /* date/time segment was last used */
852 2 dtm bit 36, /* date/time segment last modified */
853 ...
854
855
856 2 dirsw bit 1, /* "1"b - entry is a directory seg */
857 /* "0"b - entry is a non-dir seg */
858 2 master_dir bit 1, /* master directory - */
859 /* root dir for logical disk vol */
860 ...
861 2 fm 0:255 bit 18, /* file map - each value is */
862 /* index of a 1024-word record in */
863 /* disk record array on that */
864 /* physical disk volume; or */
865 /* "000000"b - null disk address */
866 /* record holds only "0"b bits */
867 ...
868 2 master_dir_uid bit 36, /* superior master directory uid */
869 2 uid_path 0:15 bit 36, /* uid pathname of all parent dirs */
870 /* starting after the root */
871
872
873 2 primary_name char 32, /* primary name of the segment */
874 ...
875 2 par_pvid bit 36, /* physical volume id of the parent */
876 2 par_vtocx fixed bin 17, /* vtoc entry index of the parent */
877 ...
878 2 access_class bit 72, /* access class of segment */
879
880
881 This completes the topic on disk segments. To display the next topic
882 related to output of the azm page_control_check pcc request,
883 type: help initiate_seg.gi
884
885
886 :Info: initiate_seg.gi: initiate_seg: make_known.gi: make_known:
887 2023-04-21 Connect a Segment to a Process
888
889 Segment -- permanent storage on disk for a segment is comprised of
890 Directory Entry entry
891 - Logical attributes of the segment
892 Volume Table of Contents Entry vtoce
893 - Physical attributes of the segment
894 - File map locating records of the segment
895
896 Virtual Segment of a Process -- described by a
897 Segment Descriptor Word sdw
898 Known Segment Table Entry kste
899
900
901 A program running in a user process can ask the Multics supervisor to
902 connect a particular segment to one of the process' virtual segments
903 region in the process workspace directly accessible to a program.
904 This supervisor service is called "initiating a segment" or "making a
905 segment known to the process".
906
907
908 Make-known request:
909 A request for the make-known service begins when the program running in
910 a process calls the initiate_file_ subroutine or calls one of the
911 supervisor gate entry points: hcs_$initiate or hcs_$initiate_count.
912 These routines all invoke one of the supervisor entry points in
913 initiate_.pl1 with directory and entry arguments giving a target
914 pathname identifying a non-directory segment. initiate_ is part of the
915 Segment Control subsystem.
916
917 The supervisor must complete the following tasks to connect the target
918 segment to one of the virtual segments in the process workspace. These
919 include the make-known request plus a service to resolve a segment
920 fault when the virtual segment is referenced with an invalid SDW.
921
922
923 Connect a Segment to a Process
924 A) Make Segment Known to the Process initiate_seg.gi.info
925 - Find segment information using the
926 directory hierarchy.
927 - Verify process has some access rights to segment.
928 - If segment is on a private LV: verify LV is mounted and
929 attached by the user process.
930 - Get KSTE and SDW structures to describe the segment.
931 - Re-use existing KSTE/SDW if segment already in-use by
932 process, or has been used earlier in the session.
933 - Extend seg access if ACL/RBs now grant write access
934 OR
935 - Describe Segment to Hardware and Supervisor
936 - Fill-in Known Segment Table Entry KSTE
937 - Fill-in faulted Segment Descriptor Word SDW
938
939
940 B) Segment Fault When Accessed by the Process seg_fault.gi.info
941 - Find segment in, or add a segment to, the
942 List of Active Segments in-use by the system.
943 - Fill-in process access rights in SDW and KSTE.
944 - If process rights change encacheability of the segment,
945 change encacheability setting in SDWs of ALL referencing
946 processes.
947 - Add SDW Trailer Record STR to ASTE tracking this process as
948 referencing the active segment.
949
950
951 The next sections of this information block describe steps taken to
952 perform Task A. Task B will described in a subsequent info block
953 seg_fault.gi.info.
954
955
956 Find directory entry describing target segment:
957 Each of the entry points in the initiate_ supervisor subroutine must
958 get information about the target segment from its directory entry.
959 Arguments to initiate_ give an absolute pathname for the target segment
960 dname and ename arguments.
961
962
963 initiate_ starts by calling the Directory Control dc_find$obj_initiate
964 subroutine to locate the target segment's directory entry.
965
966 call dc_find$obj_initiate dname ename entryp code;
967
968 dc_find recursively calls makeknown_ to add to the process each
969 directory given in the absolute pathname beginning with the root
970 directory >. This enables the process to look in each directory to
971 find the named subdirectory, and finally the entry for the target
972 segment.
973
974 Searches for a directory employ a 30-element associative memory
975 pathname_am.incl.pl1 which is stored in pd>pds$pathname_am to avoid
976 repeated searches for directories already known to the process.
977
978
979 For purposes of this info topic, the main elements of the directory
980 entry declaration >ldd>incl>dir_entry.incl.pl1 located by dc_find
981 are:
982
983 dcl 1 entry based entryp aligned, /* Directory Entry */
984 ...
985 2 uid bit 36, /* unique id of entry */
986 ...
987 2 nnames fixed bin 17, /* number of names for this entry */
988 2 name_frp bit 18, /* relp start of name list */
989 2 name_brp bit 18, /* relp end of name list */
990 /* Both are offsets in dir seg */
991 ...
992 2 pvid bit 36, /* physical volume id */
993 2 vtocx fixed bin 17, /* vtoc entry index */
994
995
996 ...
997 2 dirsw bit 1, /* "1"b - entry is a directory seg */
998 /* "0"b - entry is a non-dir seg */
999 ...
1000 2 access_class bit 72, /* security attributes: */
1001 /* level and category */
1002 2 ring_brackets 3 bit 3, /* ring brackets on segment */
1003 2 ex_ring_brackets 3 bit 3,
1004 /* extended ring brackets */
1005 2 acle_count fixed bin 17, /* number of entries on ACL */
1006 2 acl_frp bit 18, /* relp to start of ACL */
1007 2 acl_brp bit 18, /* relp to end of ACL */
1008 /* Both are offsets in dir seg */
1009 ...
1010 2 bc fixed bin 24, /* bit count */
1011
1012
1013 dc_find verifies that the process and the ring-of-execution for the
1014 program calling initiate_file_ or one of the supervisor gate entry
1015 points like hcs_$initiate_count have at least read access to the
1016 segment. The level$get subroutine returns the ring-of-execution for
1017 the program which called into the inner ring.
1018
1019 dc_find then returns to initiate_ with a pointer to the directory entry
1020 for the target segment. The parent directory of that segment is also
1021 locked at this point.
1022
1023
1024 initiate_ gathers information about this target segment into a
1025 makeknown_info data structure >ldd>incl>makeknown_info.incl.pl1:
1026
1027 dcl 1 makeknown_info aligned /* Data for makeknown_ */
1028 based makeknown_infop,
1029 2 uid bit 36 aligned, /* segment unique identifier */
1030 2 entryp ptr unaligned, /* pointer to directory entry */
1031 2 flags unaligned,
1032 3 dirsw bit 1, /* seg is a directory segment */
1033 3 rsw bit 1, /* caller wants to re-use a segno */
1034 /* used before for this seg. */
1035 3 allow_write bit 1, /* supervisor wants to initiate */
1036 /* seg with write permission if */
1037 /* ACL/RBs grant such access. */
1038 ...
1039
1040
1041 The initiate_ subroutine gathers the following information about the
1042 target segment.
1043 entryp ---> makeknown_info.entryp
1044 entryp->entry.uid ---> makeknown_info.uid
1045 entryp->entry.dirsw ---> makeknown_info.dirsw
1046 "1"b ---> makeknown_info.allow_write
1047
1048
1049 Check if segment is stored on a private logical volume:
1050 initiate_ then checks whether the target segment is stored on a
1051 "private logical volume": a volume accessible only to specific users,
1052 and not necessarily mounted at all times. If so, initiate_ must verify
1053 that the logical volume has been mounted on a disk drive and has been
1054 attached by that process. The physical volume ID entry.pvid is used
1055 for that purpose.
1056
1057
1058 Make target segment known to the process:
1059 The initiate_ subroutine then calls the makeknown_ subroutine.
1060
1061 call makeknown_ addrmakeknown_info segno use_count code ;
1062
1063 This subroutine is responsible for making both directory and
1064 non-directory segments known to the process.
1065
1066
1067 makeknown_ first calls the kstsrch subroutine to check if the target
1068 segment is already known to the process.
1069
1070 call kstsrch makeknown_info.uid hash_bucket kstep;
1071
1072
1073 kstsrch searches for a kste.uid matching the makeknown_info.uid the
1074 target segment's uid, using the kst.uid_hash_buckets array to speed
1075 searching.
1076 - If the segment is already known to the process, a pointer to the
1077 Known Segment Table Entry kste describing that segment is
1078 returned to makeknown_.
1079 - Otherwise, a null kstep value is returned along with a hash_bucket
1080 onto which any new kste which might be assigned by makeknown_
1081 should be threaded.
1082
1083
1084 makeknown_ continues:
1085 At this point, makeknown_ begins its changes to the KSTE structure and
1086 SDW register using information returned by kstsrch.
1087
1088
1089 - If the segment is already known, makeknown_ checks if
1090 kste.allow_write="0"b the segment was previously made known without
1091 requesting that write access be granted. If so, the existing SDW
1092 is disconnected to cause access granted to be recalculated in case
1093 write access has been added to segment's ACLs, or ring bracket
1094 values.
1095 "0"b ---> sdw.valid
1096 "0"b ---> sdw.add
1097 36"1"b ---> kste.dtbm
1098
1099
1100 makeknown_ then updates its segno output argument, and the kste with
1101 data from the current makeknown_ request.
1102
1103 kste.segno ---> segno
1104 makeknown_info.allow_write ---> kste.allow_write
1105 makeknown_info.entryp ---> kste.entryp
1106 level$get ---> ring
1107 kste.usage_countring + 1 ---> kste.usage_countring
1108
1109 Notice that segment initiations are counted separately for each ring
1110 in which the caller has initiated the segment.
1111
1112
1113 makeknown_ finally returns its segno to the caller.
1114
1115
1116 - If the segment is not known to the process, makeknown_ selects an
1117 unused kste in the process, threads it onto the hash list selected
1118 by hash_bucket returned by kstsrch, and initializes that kste and
1119 sdw. No Page Table address or access data are recorded in the sdw
1120 at this time. The segno from the chosen kste is copied to
1121 makeknown_'s segno return argument.
1122
1123 kst.uid_hash_buckethash_bucket ---> kste.fp
1124 wordnokstep ---> kst.uid_hash_buckethash_bucket
1125
1126 kste.segno ---> segno
1127
1128
1129 makeknown_info.uid ---> kste.uid
1130 makeknown_info.dirsw ---> kste.dirsw
1131 makeknown_info.allow_write ---> kste.allow_write
1132 makeknown_info.entryp ---> kste.entryp
1133 level$get ---> ring
1134 kste.usage_countring + 1 ---> kste.usage_countring
1135 36"1"b ---> kste.dtbm
1136
1137 "0"b ---> sdw.add
1138 "0"b ---> sdw.r1, sdw.r2, sdw.r3
1139 "0"b ---> string sdw.access
1140 "0"b ---> sdw.valid
1141
1142
1143 Setting kste.dtbm to 36"1"b tells the segment fault handler in Task
1144 B that it must re-evaluate the process's access to the segment.
1145
1146 For a description of the PL/I wordno builtin function, type:
1147 .. help pl1_new_features
1148
1149
1150 Information in the "Known Segment Table KST header" describes the
1151 range of the process' workspace. The array of "Known Segment Table
1152 Entries KSTEs" describes each virtual segment in-use by the process
1153 outside of the ring-0 supervisor segments.
1154
1155
1156 Main elements of the kst and kste structures >ldd>incl>kst.incl.pl1
1157 are declared as follows:
1158
1159 dcl 1 kst aligned based kstp, /* KST header */
1160
1161 2 lowseg fixed bin 17, /* lowest segment number */
1162 /* seg 230 = stack_0 */
1163 2 highseg fixed bin 17, /* highest segment number */
1164 2 highest_used_segno fixed bin 17,/* highest segment no used */
1165 ...
1166 2 free_list bit 18 unaligned, /* relp to 1st free kste */
1167 /* Offset in kst seg */
1168
1169
1170 ...
1171 2 uid_hash_bucket 0 : 127 bit 18 unaligned,
1172 /* hash buckets */
1173 2 kst_entry 0 refer kst.lowseg:0 refer kst.highseg
1174 aligned like kste, /* kst entries */
1175 ...
1176
1177
1178 dcl 1 kste based kstep aligned, /* KST entry */
1179 2 fp bit 18 unaligned, /* forward relp to thread of */
1180 /* KSTEs in a uid hash bucket*/
1181 /* list or free KSTE list. */
1182 2 segno fixed bin 17 unaligned, /* segment number */
1183 2 usage_count 0:7 fixed bin 8 /* outstanding initiates/ring */
1184 unaligned,
1185 2 entryp ptr unaligned, /* branch pointer */
1186 ...
1187 2 uid bit 36 aligned, /* unique identifier */
1188 2 access_information unaligned,
1189 3 dtbm bit 36, /* date time branch modified */
1190 3 extended_access bit 33, /* extended access from entry */
1191 3 access bit 3, /* rew */
1192 3 ex_rb 3 bit 3, /* extended ring brackets */
1193
1194
1195 ...
1196 2 flags unaligned,
1197 3 dirsw bit 1, /* directory switch */
1198 3 allow_write bit 1, /* initiated w/ write mode */
1199
1200
1201 The main elements of the SDW structure >ldd>incl>sdw.incl.pl1 for
1202 this topic are:
1203
1204 dcl 1 sdw based sdwp aligned, /* Segment Descriptor Word */
1205
1206 2 add bit 24 /* absolute address in hardware memory*/
1207 2 r1 r2 r3 bit 3 /* ring brackets for the segment */
1208 2 df bit 1 /* "0"b = seg ^valid directed fault */
1209 /* "1"b = seg valid no fault occurs*/
1210 2 df_no bit 2 /* "00"b = fault treated as seg fault */
1211 /* END OF WORD 1 */
1212 ...
1213
1214
1215 2 access /* access bits: */
1216 /* a running program can... */
1217 3 read bit 1 /* "1"b = read seg's bits/chars/words */
1218 3 execute bit 1 /* "1"b = execute or transfer to seg */
1219 /* words as instructions */
1220 3 write bit 1 /* "1"b = write seg's bits/chars/words*/
1221 3 privileged bit 1 /* "1"b = seg holding running program */
1222 /* can include "privileged */
1223 /* instructions" only allowed*/
1224 /* in ring-0 supervisor code.*/
1225 ...
1226 unaligned;
1227
1228
1229 Connecting the SDW:
1230 When initiate_ returns to its caller, the process has initiated the
1231 target segment. The segment's SDW has some data but may not be valid
1232 for use by the hardware unless the segment was previously known to the
1233 process, and write access had been granted earlier. If the SDW is not
1234 valid, the first time any program in the process tries to reference
1235 that SDW, a segment fault will occur.
1236
1237
1238 The next topic explains steps taken to complete Task B outlined above
1239 which resolve the segment fault by connecting the SDW to an ASTE and
1240 Page Table describing the "activated" target segment. To display that
1241 info block, type: help seg_fault.gi
1242
1243
1244 :Info: seg_fault.gi: seg_fault: activate_seg.gi: activate_seg: sst.gi: aste.gi: page_tables.gi:
1245 2023-04-28 Segment Fault When SDW Accessed by the Process
1246
1247 Segment -- permanent storage on disk for a segment is comprised of
1248 Directory Entry entry
1249 - Logical attributes of the segment
1250 Volume Table of Contents Entry vtoce
1251 - Physical attributes of the segment
1252 - File map locating records of the segment
1253
1254
1255 System Segment Table sst -- contains
1256 - Segment Control locks, counts, pointers, meters
1257 - Active Segments List -- a threaded list of
1258 - Active Segment Table Entries aste -- each links to
1259 - ASTE SDW Trailer Records str
1260 - Page Tables
1261 - Page Control locks, counts, pointers, meters
1262
1263 Core Map - contains
1264 - an array of Core Map Entries cme -- each structure
1265 describes contents of a hardware memory frame.
1266 - a threaded list of CMEs managed by Page Control.
1267
1268
1269 Virtual Segment of a Process - described by a
1270 Segment Descriptor Word sdw
1271 Known Segment Table Entry kste
1272
1273
1274 After a process has initiated a segment, that segment is known as one
1275 of the process's virtual segments: a program running in that process
1276 can directly access words, characters or bits of that segment. Steps
1277 taken to initiate the segment are outlined below as Task A. Task A was
1278 explained in the azm help segment: initiate_seg.gi.info
1279
1280
1281 Connect a Segment to a Process
1282 A) Make Segment Known to the Process initiate_seg.gi.info
1283 - Find segment information using the
1284 directory hierarchy.
1285 - Verify process has some access rights to segment.
1286 - If segment is on a private LV: verify LV is mounted and
1287 attached by the user process.
1288 - Get KSTE and SDW for segment.
1289 - Re-use existing KSTE/SDW if segment already in-use by
1290 process, or has been used earlier in the session.
1291 - Extend seg access if ACL/RBs now grant write access
1292 OR
1293 - Describe new Virtual Segment to Hardware and Supervisor
1294 - Fill-in faulted Segment Descriptor Word SDW
1295 - Fill-in Known Segment Table Entry KSTE
1296
1297
1298 However, the SDW for that virtual segment may not be valid when a
1299 program tries to reference the segment. In that case, the reference
1300 will cause a segment fault. The supervisor fault handler must perform
1301 the steps outlined below in Task B to connect the SDW and KSTE to an
1302 ASTE and Page Table describing the segment to Segment Control and
1303 Page Control.
1304
1305
1306 B) Segment Fault When Accessed by the Process seg_fault.gi.info
1307 - Find segment in, or add the segment to, the
1308 List of Active Segments in-use by the system.
1309 - Fill-in process access rights in SDW and KSTE.
1310 - If process rights change encacheability of the segment,
1311 change encacheability setting in SDWs of ALL referencing
1312 processes.
1313 - Add SDW Trailer Record STR to ASTE tracking this process as
1314 referencing the active segment.
1315
1316
1317 The "segment fault" mechanism ties together the structures that
1318 describe the segment from several different viewpoints.
1319 - View as a data stream of bits permanently stored on disk.
1320 - View as an "active segment": added to system's working set of
1321 in-use segments.
1322 - View as a virtual segment directly accessible by a program
1323 running in a process.
1324
1325
1326 The next few sections of this info block present the relevant elements
1327 of structures introduced earlier describing a segment as it is stored
1328 on disk and as a virtual segment of a process; and then introduce
1329 structures describing segments as they are activated for use by the
1330 system. Further sections summarize the segment fault resolution
1331 mechanism.
1332
1333
1334 VIEW OF A SEGMENT -- as a data stream stored on disk:
1335
1336 Structures for describing a segment stored permanently on disk were
1337 introduced by the azm help segment: disk_segment.gi.info.
1338
1339 These include the Directory Entry entry describing logical attributes
1340 of the segment, and the Volume Table of Contents Entry vtoce
1341 describing physical attributes of the segment.
1342
1343
1344 For purposes of this info topic, the main elements of the entry
1345 declaration >ldd>incl>dir_entry.incl.pl1 are:
1346
1347 dcl 1 entry based ep aligned, /* Directory Entry */
1348 ...
1349 2 uid bit 36, /* unique id of entry */
1350 2 dtem bit 36, /* date-time entry modified */
1351 ...
1352 2 pvid bit 36, /* physical volume id */
1353 2 vtocx fixed bin 17, /* vtoc entry index */
1354 ...
1355 2 dirsw bit 1, /* "1"b - entry is a directory seg */
1356 /* "0"b - entry is a non-dir seg */
1357
1358 ...
1359 2 multiple_class bit 1, /* seg has several security classes*/
1360 ...
1361 2 entrypt_sw bit 1, /* "1"b - call limiter enabled */
1362 ...
1363 2 entrypt_bound bit 14, /* call limiter for gate segments */
1364 2 access_class bit 72, /* security attributes: */
1365 /* level and category */
1366 2 ring_brackets 3 bit 3, /* ring brackets on segment */
1367 2 ex_ring_brackets 3 bit 3,
1368 /* extended ring brackets */
1369 2 acle_count fixed bin 17, /* number of entries on ACL */
1370 2 acl_frp bit 18, /* relp to start of ACL */
1371 2 acl_brp bit 18, /* relp to end of ACL */
1372 /* Both are offsets in dir seg */
1373
1374
1375 ...
1376 2 bc fixed bin 24, /* bit count */
1377
1378
1379 For purposes of this info topic, the main elements of the vtoce
1380 declaration >ldd>incl>vtoce.incl.pl1 are:
1381
1382 dcl 1 vtoce based vtocep aligned, /* VTOCE Entry */
1383
1384 2 uid bit 36, /* segment uid - "0"b if vtoce free */
1385
1386 2 msl bit 9, /* max seg length */
1387 2 csl bit 9, /* current seg length */
1388 2 records bit 9, /* number of records used on disk */
1389 ... /* above 3 items in 1024-word units*/
1390 2 dtu bit 36, /* date/time segment last used */
1391 2 dtm bit 36, /* date/time segment last modified */
1392
1393
1394 ...
1395 2 fm 0:255 bit 18, /* file map - each positive value is*/
1396 /* index of a 1024-word record in */
1397 /* disk record array on that */
1398 /* physical disk volume; or */
1399 /* "000000"b - null disk address */
1400 /* record holds only "0"b bits */
1401
1402
1403 VIEW OF A SEGMENT -- as a virtual segment of a process:
1404
1405 Structures describing a segment as a virtual segment of a process were
1406 introduced by the azm help segment: virtual_segment.gi.info.
1407
1408 These include: the hardware-software register: SDW; and software's
1409 extra information about the segment: KSTE.
1410
1411
1412 The next few sections add a few more details about how the virtual
1413 segments of a process are described to the hardware; and present
1414 portions of the SDW and KSTE structures that are significant to the
1415 segment fault resolution mechanism.
1416
1417
1418 Hardware view of a process workspace:
1419 As each process is scheduled to run on a hardware processor CPU, its
1420 memory workspace is defined to that CPU by loading the CPU's
1421 Descriptor Base Register DBR with information about the process's
1422 Descriptor Segment pd>dseg.
1423
1424 The DBR contains some of the same information as an SDW for the dseg:
1425 - a flag specifying that the dseg is a paged segment is ^unpaged;
1426 - address and length of the dseg Page Table.
1427
1428
1429 Examining a descriptor base register:
1430 Whenever the azm select_process slp request selects a process for
1431 display, its DBR address dbr.add element is listed as an octal
1432 address as shown in the following slp output:
1433
1434 Proc 9 DBR 16630134 running on cpu a GDixon.Multics.a
1435
1436
1437 However, the complete DBR register contents for each process is saved
1438 in its Active Process Table Entry apte.dbr. APTE structures
1439 >ldd>incl>apte.incl.pl1 are displayed by the azm apte request.
1440 For example:
1441
1442 azm: apte -run
1443
1444 APTE #12 at ADDR 4100:
1445 Processid: 004100247203 GDixon.Multics.a; DBR: 16630134
1446 State: running at 2/18/* 17:49:25.522731
1447
1448
1449 APTE structures are stored in Traffic Control's tc_data segment.
1450
1451 azm: d tc_data|4100 -as apte.dbr
1452 dbr = 1091842560835687055379
1453
1454
1455 Seeing the dbr contents as a long decimal number isn't very helpful.
1456 The offset within the APTE for the 2-word apte.dbr element can be
1457 obtained using the azm search request to look for the first 12 digits
1458 of the DBR's octal value in the apte structure.
1459
1460 azm: octal 1091842560835687055379
1461 166301340004001775100023o
1462
1463 azm: search tc_data|4100 100 166301340004
1464 Segment 112 tc_data
1465 from 4100 to 4200
1466 112|4144 = 166301340004
1467
1468
1469 Knowing the location of the apte.dbr element allows the full DBR
1470 structure to be displayed.
1471
1472 azm: d tc_data|4144 -as l68_dbr
1473 l68_dbr at 112|4144
1474 add = "16630134"b3, bound = "00000001111111"b, stack_base_segno = 19
1475 OFF: unpaged
1476
1477
1478 Its dbr.bound value defines the number of SDWs stored in the pages of
1479 the dseg.
1480
1481 azm: calc "1111111b+1*16"
1482 = 2048
1483
1484 The normal dseg is 2048 words 2 pages long; and each SDW occupies 2
1485 words. So the dseg contains SDWs describing 1024 segments.
1486
1487
1488 Its dbr.stack_base_segno gives the first two digits of stack segment
1489 numbers. 19 decimal is 23 octal; concatenated with the octal
1490 ring-of-execution number gives the octal segment number of the stack
1491 segment in each ring-of-execution: 230 is the segment number for
1492 pd>stack_0, 231 for pd>stack_1, ..., 234 for pd>stack_4, etc.
1493 The CALL6 instruction uses this value to select the stack segment when
1494 crossing into a lower more privileged ring-of-execution.
1495
1496 See the Multics Processor Manual AL39-01C description of the CALL6
1497 instruction for a discussion of this stack segno identification
1498 mechanism.
1499
1500 See Figure 5-3 in that same manual for a diagram showing how loading
1501 the DBR register defines a process workspace to the CPU hardware.
1502
1503
1504 Supervisor view of another process's workspace:
1505 For any active process, the supervisor can examine the workspace of
1506 that process using an abs_seg: a ring-0 temporary virtual segment
1507 which can overlay any active segment using information in its ASTE and
1508 associated page table.
1509
1510 Segment Control holds in the sst prevents from being deactivated the
1511 ASTE describing the Descriptor Segment dseg of each active process.
1512 An abs_seg can overlay another process's dseg using the apte.dbr
1513 values as described above to access any SDW of that process. This is
1514 an important capability, because the SDWs for all processes referencing
1515 a given segment must be updated when the segment changes length, or
1516 access attributes, or is deactivated, etc.
1517
1518
1519 For the process running on a CPU, the supervisor can use a variable
1520 to locate that process' dseg ASTE:
1521
1522 dcl pds$dstep bit 18 aligned external;
1523 /* offset in sst_seg of ASTE for process' dseg */
1524
1525 The Process Data Segment pd>pds is an object segment describing
1526 properties of a process. Each process has its own copy of the pds
1527 segment.
1528
1529
1530 However, the supervisor can access any SDW in the running process
1531 directly by referencing that sdw in its dseg array of SDWs:
1532
1533 sdwap = addrdseg$;
1534 sdwp = addrsdwasegno;
1535
1536
1537 Virtual segment:
1538 Each virtual segment of a process is defined to the hardware by a
1539 Segment Descriptor Word SDW; and defined to the supervisor by its
1540 SDW plus the Known Segment Table Entry KSTE for that segment.
1541
1542
1543 Segment descriptor word:
1544 For purposes of this info topic, the process' array of SDWs can be
1545 described as follows:
1546
1547 dcl 1 sdwa 0:1023 based sdwap aligned like sdw; /* SDW array */
1548
1549 The sole content of the process' Descriptor Segment pd>dseg is
1550 this array of SDWs.
1551
1552
1553 The complete SDW structure is declared below. Data elements of the
1554 SDW and its page table tell the hardware exactly what access was
1555 granted to the process by the disk segment's ACL ring brackets and
1556 AIM access controls in each possible ring of execution.
1557
1558 dcl 1 sdw based sdwp aligned, /* Segment Descriptor Word */
1559
1560 2 add bit 24 /* absolute address in hardware memory*/
1561 /* of virtual seg's page table */
1562 2 r1 r2 r3 bit 3 /* ring brackets for the segment */
1563 2 df bit 1 /* "0"b = seg ^valid directed fault */
1564 /* "1"b = seg valid no fault occurs*/
1565 2 df_no bit 2 /* "00"b = fault treated as seg fault */
1566
1567
1568 2 pad1 bit 1
1569 2 bound bit 14 /* segment length in 16 word blocks */
1570
1571 2 access /* access bits: */
1572 /* a running program can... */
1573 3 read bit 1 /* "1"b = read seg's bits/chars/words */
1574 3 execute bit 1 /* "1"b = execute or transfer to seg */
1575 /* words as instructions */
1576 3 write bit 1 /* "1"b = write seg's bits/chars/words*/
1577
1578 3 privileged bit 1 /* "1"b = seg holding running program */
1579 /* can include "privileged */
1580 /* instructions" only allowed*/
1581 /* in ring-0 supervisor code.*/
1582
1583
1584 2 unpaged bit 1 /* "0"b = segment is paged. Only */
1585 /* ring-0 segs can be unpaged. */
1586 2 entry_bound_sw bit 1 /* "0"b = entry to seg via CALL6 only */
1587 /* to certain words at start */
1588 /* of a gate segment. */
1589 /* "1"b = segment is NOT a gate. */
1590 2 cache bit 1 /* "1"b = segment data loaded through */
1591 /* cache memory. */
1592 2 entry_bound bit 14 /* entry bound - CALL6 ADDR limit */
1593 /* ADDR <= seg|entry_bound */
1594 ) unaligned;
1595
1596
1597 Known segment table entry:
1598 Information in the "Known Segment Table kst header" includes:
1599 - the array of Known Segment Table Entries KSTEs describing
1600 non-supervisor segments;
1601 - the hash table mapping entry.uid onto a set of possible KSTEs
1602 sharing similar UID values.
1603
1604
1605 For purposes of this info topic, the main elements of the kst and kste
1606 declarations are:
1607
1608 dcl 1 kst aligned based kstp, /* KST header */
1609 ...
1610 2 uid_hash_bucket 0 : 127 bit 18 unaligned,
1611 /* hash buckets */
1612 2 kst_entry 0 refer kst.lowseg:0 refer kst.highseg
1613 aligned like kste, /* kst entries */
1614 ...
1615
1616
1617 The KSTE for a given segment number can be located in the kst
1618 segment of the process.
1619
1620 kstep = addr kst.kst_entryseg_fault_referenced_segno ;
1621
1622
1623 Each "Known Segment Table Entry kste structure holds information
1624 which must be supplied from the ASTE or the directory entry describing
1625 the active segment. These include the following elements:
1626
1627 dcl 1 kste based kstep aligned, /* KST entry */
1628 2 fp bit 18 unaligned, /* forward relp to thread of */
1629 /* KSTEs in a uid hash bucket*/
1630 /* list or free KSTE list. */
1631 2 segno fixed bin 17 unaligned, /* segment number */
1632 2 usage_count 0:7 /* count of initiates in each */
1633 fixed bin 8 unaligned, /* ring-of-execution */
1634 2 entryp ptr unaligned, /* branch pointer */
1635 2 uid bit 36 aligned, /* unique identifier */
1636
1637
1638 2 access_information unaligned,
1639 3 dtbm bit 36, /* date time branch modified */
1640 3 extended_access bit 33, /* extended access from entry */
1641 3 access bit 3, /* rew */
1642 3 ex_rb 3 bit 3, /* extended ring brackets */
1643 ...
1644 2 flags unaligned,
1645 3 dirsw bit 1, /* directory switch */
1646 ...
1647
1648
1649 VIEW OF A SEGMENT -- activated for use on the system:
1650
1651 Segment Control provides the glue that connects the two preceding views
1652 of a segment. It assigns an ASTE and Page Table structure when
1653 "activating the segment": adding it to the list of segments currently
1654 in-use on the system. And it records which processes have "initiated
1655 the segment": threading to the segment's ASTE an SDW Trailer Record
1656 str structure for each process accessing the segment.
1657
1658 The next few sections introduce these data structures and the segments
1659 that contain them.
1660
1661
1662 Segment Control maintains the "List of Active Segments". Page Control
1663 maintains a related "Core Map List" describing current contents of
1664 each page of hardware memory. Both lists begin in the SST header.
1665
1666
1667 System segment table:
1668 The "System Segment Table SST" ...
1669 - holds pointers to Segment Control data and resources;
1670 - provides storage for most of the system's Page Tables;
1671 - holds the list of active segments: the ASTEs;
1672 - holds meters for Segment Control and Page Control operations; and
1673 - defines locks used by Segment Control and Page Control to protect
1674 critical sections of code that update these data items.
1675
1676 Earlier versions of sst_seg also held the array of structures that
1677 describe how each frame in hardware memory is used: Core Map Entries
1678 CMEs. This array has been moved to a separate segment: the
1679 core_map segment. However, header information for the Core Map List
1680 remains in the SST. Thus, the SST is shared by both Segment Control
1681 and Page Control subsystems.
1682
1683
1684 The sst structure >ldd>incl>sst.incl.pl1 resides at the base of the
1685 sst_seg supervisor segment; that segment has a second name: sst. Since
1686 this segment holds page tables, the sst pages must be wired in memory
1687 frames. Page Control cannot take a page fault while referencing an
1688 ASTE or Page Table.
1689
1690
1691 Demand Paging hardware requires pages of sst_seg to be in consecutive
1692 hardware memory frames because the hardware requires all PTWs of a
1693 Page Table array to reside in contiguous words of hardware memory.
1694 If a Page Table crosses a page boundary, the two halves of the table
1695 must reside in contiguous hardware memory frames. For this reason, all
1696 SST pages are in contiguous memory frames.
1697
1698 Page Control software also requires these pages to be in consecutive
1699 order within hardware memory. It depends on this feature to convert
1700 the absolute address of a page table given by sdw.add to a relative
1701 offset of that Page Table within the sst_seg referenced by cme.ptwp
1702 values: pt_offset_in_sst = sdw.add - sst.ptwbase;
1703
1704
1705 For purposes of this info topic, the main elements of the sst
1706 declaration are:
1707
1708 dcl sst_seg$ external; /* sst seg location as PL/1 variable */
1709
1710 dcl 1 sst based sstp aligned, /* System Segment Table */
1711
1712 2 space 8 fixed bin, /* empty space to watch for bugs */
1713
1714 /* SST HEADER */
1715 /* locks for ... */
1716 2 ptl bit 36, /* - global page table a loop lock */
1717 2 astl bit 36, /* - global ast allocs a block lock */
1718 2 astl_event bit 36, /* - wait_event for waits on AST lock */
1719 ...
1720
1721
1722 2 nused fixed bin, /* count of page control memory frames */
1723 2 ptwbase fixed bin 24, /* absolute address of sst_seg */
1724 2 tfreep ptr, /* pointer to 1st free STR in str_seg */
1725 2 astap ptr, /* pointer to 1st ASTE in sst_seg */
1726 ...
1727 2 root_astep ptr, /* pointer to AST for root ">" dir */
1728
1729 2 pts 0: 3 fixed bin, /* array of page table sizes in pages*/
1730 2 level 0:3, /* pool of ASTE's by page table size */
1731 3 ausedp /* relp to 1st ASTE in this pool */
1732 no_aste /* count of ASTEs in this pool */
1733 bit 18 unaligned,
1734 ...
1735
1736
1737 /* CORE MAP HEADER */
1738 2 cmp ptr, /* pointer to start of CME array in */
1739 /* core_map seg. */
1740 2 usedp bit 18, /* relp to threaded list of CMEs */
1741 /* managed by Page Control. */
1742 ...
1743 /* OTHER AST ELEMENTS */
1744 2 ast_ht_ptr ptr, /* ASTE hash table pointer */
1745 /* hashed by aste.uid = entry.uid */
1746 2 ast_ht_n_buckets fixed bin,
1747 /* no. of buckets in ASTE hash table */
1748 ...
1749 2 n_trailers fixed bin, /* length of ASTE SDW Trailer Record */
1750 /* array STR structs in str_seg$ */
1751 ...
1752
1753
1754 2 wusedp bit 18, /* relp to next CME to be examined by */
1755 /* claim_mod_core for write to disk */
1756 ...
1757
1758
1759 Active segment table entry:
1760 An "Active Segment Table Entry ASTE" precedes each Page Table in the
1761 SST. The ASTE holds information about the disk storage for the
1762 segment being accessed by that Page Table. This information includes:
1763 - segment unique id aste.uid;
1764 - segment maximum length, in pages aste.msl;
1765 - segment current length, in pages aste.csl;
1766 - segment record count on disk aste.records;
1767 - segment type aste.dirsw;
1768 - segment location on disk aste.pvtx aste.vtocx.
1769 - segment count of pages in hardware memory aste.np.
1770
1771 The group of ASTEs form the system's "List of Active Segments".
1772
1773
1774 Segment Control limits the number of segments in its active segments
1775 list by pre-allocating storage for a fixed count of Page Tables in
1776 four popular lengths: 4-, 16-, 64- and 256-PTWs long. ASTEs
1777 associated with Page Tables of the same size are pooled threaded
1778 together in the SST segment sst.levelN substructure where N ranges
1779 from 0 and 3 to choose from the 4 page table lengths above.
1780
1781
1782 Each aste structure >ldd>incl>aste.incl.pl1 is even-word-aligned and
1783 occupies 12 words in memory. For purposes of this info topic, the
1784 main elements of the aste declaration are:
1785
1786 dcl 1 aste based astep aligned, /* Active Segment Table Entry */
1787
1788 2 fp bit 18 /* forward ausedp thread relp */
1789 2 bp bit 18 /* backward ausedp thread relp */
1790 /* Both are offsets within sst_seg. */
1791 ...
1792 2 strp bit 18 /* relp to ASTE SDW Trailer Record STR */
1793 /* in str_seg. */
1794 2 par_astep bit 18 /* relp to parent dir's ASTE in sst_seg */
1795
1796
1797 2 uid bit 36 /* segment unique id */
1798 2 msl bit 9 /* maximum seg length in 1024-word units */
1799 2 pvtx fixed bin 8 /* seg physical disk volume table index */
1800 2 vtocx fixed bin 17 /* seg vtoc entry index */
1801 2 usedf bit 1 /* ASTE is being used if non-zero */
1802 ...
1803 2 dirsw bit 1 /* ="1"b ASTE is for a directory */
1804 2 master_dir bit 1 /* ="1"b master dir - root of log. vol.*/
1805 2 volmap_seg bit 1 /* ="1"b phys vol bit map: for pvtx */
1806 /* ASTE does not describe a real seg */
1807 ...
1808
1809
1810 2 dtu bit 36 /* date and time segment last used */
1811 2 dtm bit 36 /* date and time segment last modified */
1812 ...
1813 2 csl bit 9 /* current seg length in 1024-word units */
1814 ...
1815 2 records bit 9 /* count of records used on disk for seg */
1816 2 np bit 9 /* count of seg pages currently in memory*/
1817 ...
1818 2 ptsi bit 2 /* page table size index */
1819 /* ="00"b 4-word page table follows */
1820 /* ="01"b 16-word page table follows */
1821 /* ="10"b 64-word page table follows */
1822 /* ="11"b 256-word page table follows */
1823 2 marker bit 6 /* marker to indicate last word of ASTE */
1824 unaligned;
1825
1826
1827 For purposes of this info topic, the Page Table which follows a given
1828 ASTE can be located from its associated ASTE's location.
1829
1830 For an ASTE located by astep pointer...
1831
1832 ptp = addwordno astep sizeaste ;
1833 pt_size = sst.pts fixedaste.ptsi - 1;
1834
1835 dcl 1 ptwa 0:pt_size based ptp aligned like ptw; /* Page Table */
1836
1837
1838 For a description of the PL/I addwordno and wordno builtin functions,
1839 type:
1840 .. help pl1_new_features
1841
1842
1843 SDW trailer record:
1844 Each SDW Trailer Record str tracks use by a process of an ASTE and
1845 its associated Page Table. These STR records are threaded onto the
1846 ASTE aste.strp.
1847
1848
1849 The str >ldd>incl>str.incl.pl1 is a word aligned structure stored in
1850 two words of the str_seg segment. Its full declaration is:
1851
1852 dcl 1 str based strp aligned, /* SDW Trailer Record STR */
1853
1854 2 fp bit 18 /* forward STR thread relp */
1855 2 bp bit 18 /* backward STR thread relp */
1856 /* Both are offsets in str_seg. */
1857
1858 2 segno bit 18 /* segment number of referencing */
1859 /* SDW in other process's dseg. */
1860 2 dstep bit 18 /* offset w/in sst_seg of ASTE for */
1861 unaligned; /* that process's dseg segment. */
1862
1863
1864 The str.dstep provides a third way of locating another process's dseg
1865 ASTE and Page Table so an abs_seg can be setup to reference that
1866 process's SDWs.
1867
1868
1869 The next section describes how the segment fault handler of the
1870 supervisor "activates a segment" by either:
1871 - finding an existing ASTE and Page Table which describe the
1872 faulted segment;
1873 or
1874 - assigning an unused ASTE and Page Table to describe the faulted
1875 segment, and initializing those structures with information about
1876 the segment obtained from the segment's KSTE and directory entry.
1877
1878
1879 SEGMENT FAULT HANDLER:
1880
1881 When an instruction in the executing program references a segment whose
1882 SDW is invalid sdw.df="0"b and sdw.df_no="00"b, a "segment fault"
1883 event occurs.
1884
1885
1886 To handle the fault, the processor shifts the process execution point
1887 into the fault_vector segment: a ring-0 supervisor segment containing
1888 an array of instruction pairs, one pair for each fault type.
1889
1890 The pair for a segment fault directed fault 0 does the following:
1891 - The first instruction an SCU stores state of the processor's
1892 Control Unit into a machine conditions structure designated for
1893 that fault type.
1894 - The second instruction transfers to a Fault Interceptor Module
1895 fim.alm entry point which stores contents of all registers into
1896 the machine conditions structure, masks receipt of other interrupts,
1897 then transfers to the seg_fault.pl1 supervisor subroutine which
1898 handles the "segment fault" type.
1899
1900
1901 The seg_fault entry point receives one input argument, a pointer to
1902 the stored machine conditions >ldd>incl>mc.incl.pl1. For a segment
1903 fault, fim pushes its own stack frame on the ring-0 stack stack_0;
1904 and stores the machine conditions data at: pds$fim_data
1905
1906 addrpds$fim_data ---> mcp
1907
1908 call seg_fault mcp ;
1909
1910
1911 seg_fault checks the machine conditions to determine whether the fault
1912 occurred:
1913 1. when transferring execution into a different procedure segment
1914 calling the procedure or snapping a dynamic link to a procedure
1915 entrypoint; or
1916 2. when the executing instruction was referencing some other segment.
1917
1918 Processor state data in the machine conditions tells the code which of
1919 these two possibilities caused the segment fault. seg_fault then
1920 obtains a segment number segno from either:
1921 1. the Procedure Segment Register PSR; or
1922 2. the Temporary Segment Register TSR value saved in the machine
1923 conditions.
1924
1925
1926 Missing stack segment:
1927 seg_fault first checks whether the segment reference was to a stack
1928 segment which is unknown to the process. A stack segment provides
1929 automatic storage and subroutine call history for a ring-of-execution.
1930
1931
1932 Notice that the CALL6 instruction generates a reference to the
1933 inner-ring stack when crossing into a lower, more privileged ring. The
1934 Multics supervisor must create the stack segment when the first call to
1935 a ring other than ring-0 occurs.
1936
1937 - seg_fault calls the makestack.pl1 subroutine which:
1938 - creates the segment for the referenced ring N pd>stack_N;
1939 then
1940 - calls initiate to make the new stack known to the process
1941 update the SDW and KSTE for that stack's segno. For details
1942 on initiate, type: help initiate_seg.gi
1943
1944
1945 - When makestack returns, seg_fault returns to its caller to cause
1946 restart from the seg_fault. The SDW and KSTE are now in a
1947 different state, but the SDW will still be faulted. Another
1948 seg_fault will occur to resolve that fault using the updated SDW
1949 and KSTE describing the just-created stack segment.
1950
1951
1952 The next sections of this info block describe steps taken by seg_fault
1953 to locate and update contents of the SDW and KSTE for the segment being
1954 referenced when the segment fault occurred.
1955
1956
1957 Find kste and directory entry describing the segment:
1958
1959 The mechanism for "Connecting a segment to a process" assigned a
1960 segment number by which that segment was known in the process. That
1961 segment number identifies an SDW and KSTE in the process. For details
1962 of this connection mechanism, type: help initiate_seg.gi
1963
1964
1965 Using the faulted SDW's segment number from the machine conditions,
1966 seg_fault then:
1967
1968 - Gets a pointer to the faulting process' KSTE kstep for the faulted
1969 segment.
1970
1971
1972 - Calls sum$getbranch_root_my to get the directory entry describing
1973 the faulted segment. This call validates contents of kste.entryp
1974 that points to the directory entry as it is known to that process.
1975
1976 call sum$getbranch_root_my segptr "0"b ep code;
1977
1978
1979 Note that every directory named in a pathname passed to the
1980 supervisor must be known in the calling process to permit the
1981 supervisor running in that process to search in that directory.
1982 Thus, the call to sum$getbranch_root_my may cause recursive
1983 seg_fault events as sum accesses directories superior to the parent
1984 directory of the faulted segment.
1985
1986
1987 sum returns to seg_fault with a pointer ep to the directory entry
1988 describing the faulted segment, and with the containing parent
1989 directory locked. The entry structure is based on the ep pointer.
1990
1991
1992 Determine what access the process has to the faulted segment:
1993
1994 After initiating a segment not previously known to the process, the
1995 KSTE and SDW contain no information about mode of access the process
1996 is authorized to have for that segment. To obtain access mode
1997 information, seg_fault must do the following.
1998
1999 - Call dc_find$seg_fault to set access elements of the KSTE based
2000 upon rights granted to the Person_ID.Project_ID of the process by
2001 the directory entry ACL, its ring brackets and AIM access class.
2002
2003 call dc_find$seg_fault kstep ep code;
2004
2005 - dc_find calls the update_kste_access.pl1 subroutine to store
2006 access elements in the KSTE for a segment.
2007
2008
2009 - update_kste_access calls access_mode$authorization to
2010 map two forms of access control authorizations into mode
2011 and ex_mode values:
2012 - authorization granted by the matching ACL entry selected
2013 by the owning Person_ID.Project_ID of the process;
2014 - AIM access class of the segment compared with AIM
2015 authorization of the faulting process.
2016 - update_kste_access returns the mode and ex_mode to dc_find.
2017
2018
2019 - dc_find$seg_fault uses the mode, ex_mode and data from the
2020 directory entry ring bracket values to set access fields in
2021 SDW and KSTE.
2022
2023 - ring_brackets entry.ring_brackets1 ---> sdw.r1
2024 entry.ring_brackets2 ---> sdw.r2
2025 entry.ring_brackets3 ---> sdw.r3
2026 - mode mode ---> stringsdw.access
2027 mode ---> kste.mode
2028 - ex_mode ex_mode ---> kste.ex_mode
2029 - date/time entry modified entry.dtem ---> kste.dtbm
2030
2031 The entry.dtem is copied into the KSTE to record the most recent
2032 date/time stamp at which process' access to the segment was last
2033 determined.
2034
2035
2036 Get other information about the faulted segment:
2037
2038 seg_fault continues to resolve the segment fault.
2039
2040 - Copy gate-related information entry.entrypt_sw
2041 entry.entrypt_bound from the directory entry while the directory
2042 is locked. This will be used later when updating the SDW.
2043
2044 - If the faulted segment is stored on a private Logical Volume LV,
2045 seg_fault checks that this LV has been mounted and that the LV was
2046 attached by the process.
2047
2048
2049 Activate the segment to get a page table:
2050
2051 seg_fault calls activate$activate_long in activate.pl1 to obtain an
2052 ASTE and associated Page Table for the faulted segment. A pointer to
2053 the ASTE is returned, and the Active Segment Table AST remains
2054 locked. The page table size aste.ptsi is already set in this ASTE.
2055
2056 astep = call activate$activate_long ep activated_sw code ;
2057 ptp = addwordno astep sizeaste ;
2058
2059
2060 - If the segment was already activated activated_sw="0"b, the
2061 astep pointer locates the existing ASTE and its Page Table.
2062
2063
2064 - OR, a free ASTE in the pool with Page Table size >= vtoce.csl is
2065 selected; and that ASTE and Page Table are initialized.
2066
2067 - physical volume ID entry.pvid --~> aste.pvtx
2068 - vtoce index on PV entry.vtocx ---> aste.vtocx
2069 - branch type entry.dirsw ---> aste.dirsw
2070 - maximum length vtoce.msl ---> aste.msl
2071 - current length vtoce.csl ---> aste.csl
2072 - no of records on disk vtoce.records ---> aste.records
2073 - count of pages in memory "0"b ---> aste.np
2074 - date last used vtoce.dtu ---> aste.dtu
2075 - date last modified vtoce.dtm ---> aste.dtm
2076 - multi_class entry.multiple_class ---> aste.multi_class
2077
2078
2079 - Page Table do i = 0 to vtoce.csl-1;
2080 vtoce.fmi ---> ptwi.add
2081 end;
2082
2083 - ASTE & Page Table in-use "1"b ---> aste.usedf
2084 - unique ID entry.uid ---> aste.uid
2085
2086
2087 The physical volume ID in the directory entry entry.pvid is
2088 changed to a physical volume index aste.pvtx of the equivalent
2089 disk in the Storage System's "Physical Volume Table PVT".
2090
2091
2092 - If sdw.add = "0"b, this is first time this process has initiated
2093 the segment. activate attaches an SDW Trailer Record for the
2094 process to the aste.strp thread.
2095
2096 - dstep pds$dstep ---> str.dstep
2097 - segno segno ---> str.segno
2098 - fp aste.strp ---> str.fp
2099 - bp "0"b ---> str.bp
2100
2101 The STR is then threaded onto the ASTE.
2102
2103 wordnostrp ---> pointer str_seg$ aste.strp -> str.bp
2104 wordnostrp ---> aste.strp
2105
2106
2107 This STR threaded list allows Segment Control to adjust all SDWs
2108 referencing a segment if:
2109 - the allowed length of the segment grows or shrinks maximum
2110 length is changed or contents grows to a larger Page Table
2111 size or is truncated to a smaller Page Table size;
2112 - access granted changes in the segment's directory entry: access
2113 for every process in the list would have to be recalculated; or
2114 - the process now activating an already-active segment has write
2115 access while other processes were accessing the segment in read
2116 mode: the encacheability state for the segment would have to be
2117 set to ^encacheable sdw.cache="0"b in all SDWs.
2118
2119
2120 Update the sdw to connect segment to the process:
2121
2122 seg_fault is finally ready to resolve the segment fault by updating
2123 final information in the SDW for the faulted segment.
2124
2125 - Update the SDW for the segment with latest effective access and
2126 encacheability settings.
2127
2128 For a directory segment:
2129 - ring brackets "0"b ---> sdw.r1 r2 r3
2130 - "rw" access mode "1010"b ---> stringsdw.access
2131 - encacheability "0"b ---> sdw.cache
2132
2133
2134 Note that seg_fault gives all processes read-write access to all
2135 directories to permit searches of directories for a specific entry
2136 name even if the process does not have status mode on that
2137 directory. Directory Control software recalculates the process'
2138 effective access to the directory if the process tries to list
2139 the directory or modify its contents.
2140
2141
2142 For a non-directory segment, the call to dc_find$seg_fault
2143 described above sets the sdw.access and sdw.r1 r2 r3 fields.
2144
2145 If only one process is accessing the segment, or none of the
2146 accessing processes have write access, then the SDW is marked as
2147 encacheable:
2148 - encacheability "1"b ---> sdw.cache
2149 Otherwise, it is marked as not encacheable:
2150 - encacheability "0"b ---> sdw.cache
2151
2152
2153 For a gate segment, additional SDW updates are needed.
2154
2155 - entry_bound_sw ^entry.entrypt_sw ---> sdw.entry_bound_sw
2156 - gate_entry_bound entry.entrypt_bound ---> sdw.entry_bound
2157
2158
2159 For all segments, a bound in 16-word blocks is placed on the length
2160 to which the segment can be extended using the calculation shown
2161 below. Then the SDW is marked as valid.
2162
2163 page_table_size = sst$pts aste.ptsi ;
2164 seg_words = min page_table_size aste.msl * 1024;
2165 seg_16_word_blocks = seg_words + 15 / 16;
2166
2167 - bound seg_16_word_blocks - 1 ---> sdw.bound
2168 - page table wordnoptp + sst.ptwbase ---> sdw.add
2169 - valid SDW "1"b ---> sdw.df
2170
2171
2172 seg_fault ends by unlocking the AST and the parent directory. When
2173 seg_fault returns, the fim code issues an RCU instruction to restart
2174 the faulting instruction with the SDW now valid for use in the
2175 segment-fault-interrupted instruction reference.
2176
2177
2178 Reading in segment pages:
2179
2180 When seg_fault returns, the process has connected an SDW for a segment
2181 with a supporting Page Table describing pages of the virtual segment.
2182 However, if the process is the first process to initiate the segment,
2183 none of its pages will be in hardware memory. Reference to any page
2184 will cause a "page fault" event.
2185
2186 The next info block explains steps taken by the Page Control subsystem
2187 to read a segment's permanent record from disk into a hardware memory
2188 frame whenever the corresponding page of the virtual segment is
2189 referenced. To display that info block, type: help demand_paging.gi
2190
2191
2192 :Info: demand_paging.gi: demand_paging:
2193 2023-04-27 Demand Paging
2194
2195 System Segment Table sst -- contains
2196 - Segment Control locks, counts, pointers, meters
2197 - Active Segments List -- a threaded list of
2198 - Active Segment Table Entries aste -- each links to
2199 - ASTE SDW Trailer Records str
2200 - Page Tables
2201 - Page Control locks, counts, pointers, meters
2202
2203 Core Map - contains
2204 - an array of Core Map Entries cme -- each structure
2205 describes contents of a hardware memory frame.
2206 - a threaded list of CMEs managed by Page Control.
2207
2208
2209 When a process first initiates a segment, some of its disk records may
2210 have been read into hardware memory frames by other processes that know
2211 about the same segment. But the first time Segment Control activates a
2212 segment, none of its pages are in memory. And if the segment is being
2213 created by initiate_file_ or hcs_$append_branch followed by
2214 hcs_$initiate_count, none of its pages even exist. Demand Paging must
2215 handle all of these cases.
2216
2217
2218 When an existing segment is first activated, the following occurs.
2219 - Each of the ptw.add values in the segment's Page Table contains:
2220 - a "device address" of the disk record that should be loaded into
2221 that page position within the segment ptw.add=record_no;
2222 ptw.add_type="0100"b; or
2223 - a "null address" indicating that page position has never been
2224 written to disk ptw.add="377020"b3 ptw.add_type="0000"b.
2225
2226 These addresses come from the vtoc.fm file map array of disk
2227 record numbers. Order of addresses in the file map array is
2228 maintained when copying those addresses into the Page Table array.
2229
2230 - Each of the ptw.df bits are set to "0"b, with ptw.df_no set to "01",
2231 meaning a "page fault" event occurs when this page is referenced.
2232
2233
2234 - Page Control has not assigned a memory frame location into which any
2235 page of the segment will be read.
2236
2237
2238 When a new segment is first created, it is assigned a 4-page Page
2239 Table.
2240 - Each of the ptw.add values in the segment's Page Table contains a
2241 "null address" indicating that page position has never be written
2242 to disk ptw.add="377020"b3 ptw.add_type="0000"b.
2243
2244 - Each of the ptw.df bits are set to "0"b, with ptw.df_no set to "01",
2245 meaning a "page fault" event occurs when this page is referenced.
2246
2247 - Page Control has not assigned a memory frame location to any of its
2248 page positions.
2249
2250
2251 Page Control defers loading any page of an active segment until that
2252 page is referenced by one of the processes sharing that segment's Page
2253 Table. If an instruction references such invalid page, a "page fault"
2254 event interrupts execution of that instruction.
2255
2256
2257 The steps taken to resolve a page fault are the topic of this info
2258 block. These page fault resolution tasks are the main method of
2259 implementing the Demand Paging service on Multics. They may be
2260 summarized as follows.
2261
2262
2263 TASK A) From the machine conditions describing the page fault, get
2264 location of the faulted PTW being referenced. Get the
2265 location of the ASTE describing the active segment being
2266 referenced from the PTW location; and the offset into the
2267 segment made by that reference.
2268 TASK B) Find a vacant hardware memory frame into which a disk record
2269 may be read. Assign that memory frame to hold contents of the
2270 disk record whose device address is placed initially in the
2271 faulted PTW.
2272 TASK C) If device address is a "null address" ptw.add_type="0000"b,
2273 then fill contents of assigned memory frame with a page of
2274 zero bits 32768"0"b bits, and mark the PTW as valid. Resume
2275 execution of the faulting instruction, which now succeeds in
2276 referencing the page of zeros.
2277
2278
2279 TASK D) If device address is a "disk address" ptw.add_type="0100"b,
2280 then update the PTW and CME, and issue a hardware request to
2281 read that record from disk into the assigned memory frame.
2282 Block further execution of the faulting process, telling the
2283 scheduler to wait for completion of the page read operation
2284 before resuming execution of that process.
2285 TASK E) When the read operation completes, a hardware interrupt is
2286 sent to one of the processors. The interrupt handler must
2287 update the PTW to indicate that I/O has completed and mark the
2288 PTW as valid. Then it must notify the scheduler to resume
2289 execution of any processes waiting on that page read
2290 completion.
2291 TASK F) When the faulting process resumes execution of the faulting
2292 instruction, that instruction now succeeds in referencing the
2293 segment page.
2294
2295
2296 The next few sections of this info block introduce the data structures
2297 that implement the Demand Paging service of Page Control. Later
2298 sections give details about each of the steps taken to resolve a page
2299 fault.
2300
2301
2302 System segment table:
2303 The "System Segment Table SST" ...
2304 - holds pointers to Segment Control data and resources;
2305 - holds the list of active segments: the ASTEs;
2306 - provides storage for most of the system's Page Tables;
2307 - holds meters for Segment Control and Page Control operations; and
2308 - defines locks used by Segment Control and Page Control to protect
2309 critical sections of code that update these data items.
2310
2311 Earlier versions of sst_seg also held the array of structures that
2312 describe how each frame in hardware memory is used: Core Map Entries
2313 CMEs. This array has been moved to a separate segment, the
2314 "core_map segment". However, header information for the core map
2315 remains in the SST.
2316
2317
2318 The sst structure >ldd>incl>sst.incl.pl1 is stored in the sst_seg
2319 supervisor segment; that segment has a second name: sst. For purposes
2320 of this info topic, the main elements of the sst declaration are:
2321
2322 dcl 1 sst based sstp aligned, /* System Segment Table */
2323 ...
2324 /* SST HEADER */
2325 /* locks for ... */
2326 2 ptl bit 36, /* - global page table a loop lock */
2327 2 astl bit 36, /* - global ast allocs a block lock */
2328 2 astl_event bit 36, /* - wait_event for waits on AST lock */
2329 ...
2330
2331
2332 2 nused fixed bin, /* count of page control memory frames */
2333 2 ptwbase fixed bin 24,/* absolute address of sst_seg */
2334 ...
2335
2336 /* CORE MAP HEADER */
2337 2 cmp ptr, /* pointer to start of CME array in */
2338 /* core_map seg. */
2339 2 usedp bit 18, /* relp to threaded list of CMEs */
2340 /* managed by Page Control. */
2341 ...
2342 2 wusedp bit 18, /* relp to next CME for writing to disk*/
2343 ...
2344
2345
2346 Active segment table entry:
2347 Each aste structure >ldd>incl>aste.incl.pl1 is even-word-aligned and
2348 occupies 12 words in memory. For purposes of this info topic, the
2349 main elements of the aste declaration are:
2350
2351 dcl 1 aste based astep aligned, /* Active Segment Table Entry */
2352
2353 ...
2354 2 uid bit 36 /* segment unique id */
2355 ...
2356 2 pvtx fixed bin 8 /* seg physical disk volume table index */
2357 2 vtocx fixed bin 17 /* seg vtoc entry index */
2358 2 usedf bit 1 /* ASTE is being used if non-zero */
2359 ...
2360
2361
2362 2 hc bit 1 /* hard core segment */
2363 2 hc_sdw bit 1 /* aste with sdw for hardcore seg */
2364 ...
2365 2 hc_part bit 1 /* set if pages are in hardcore partition*/
2366 ...
2367 2 ehs bit 1 /* entry hold switch */
2368 ...
2369 2 dirsw bit 1 /* ="1"b ASTE is for a directory */
2370 ...
2371 2 dtu bit 36 /* date and time segment last used */
2372 2 dtm bit 36 /* date and time segment last modified */
2373 ...
2374 2 csl bit 9 /* current seg length in 1024-word units */
2375 ...
2376
2377
2378 2 fmchanged bit 1 /* turned on if vtoce must be updated */
2379 ...
2380 2 records bit 9 /* count of records used on disk for seg */
2381 2 np bit 9 /* count of seg pages currently in memory*/
2382 ...
2383 2 ptsi bit 2 /* page table size index */
2384 /* ="00"b 4-word page table follows */
2385 /* ="01"b 16-word page table follows */
2386 /* ="10"b 64-word page table follows */
2387 /* ="11"b 256-word page table follows */
2388 2 marker bit 6 /* marker to indicate last word of ASTE */
2389 unaligned;
2390
2391
2392 Page table:
2393
2394 For purposes of this info topic, location of the Page Table which
2395 follows a given ASTE can be calculated from the location of its
2396 associated ASTE. Page Tables come in one of 4 supported dimensions.
2397 The ASTE preceding each Page Table gives its dimension aste.ptsi.
2398
2399 For an ASTE located by astep pointer...
2400
2401 ptp = addwordno astep sizeaste ;
2402 pt_size = sst.pts fixedaste.ptsi - 1;
2403
2404 dcl 1 ptwa 0:pt_size based ptp aligned like ptw; /* Page Table */
2405
2406
2407 In some parts of Demand Paging, the Page Table is located first by the
2408 software often from the sdw.add address. The associated ASTE can be
2409 located from the Page Table pointer. For a Page Table located by ptp
2410 pointer...
2411
2412 astep = addwordno ptp -sizeaste ;
2413
2414
2415 For a description of the PL/I addwordno and wordno builtin functions,
2416 type:
2417 .. help pl1_new_features
2418
2419
2420 Each "Page Table" defines content of a paged segment using an
2421 even-word-aligned array of hardware registers: Page Table Words
2422 PTWs. Use of a Page Table enables the Demand Paging service of
2423 Page Control for that segment: loading page content from disk into
2424 memory only when a program first references the page. However, demand
2425 paging is disabled for pages that are wired in hardware memory
2426 ptw.wired="1"b.
2427
2428 Index of a PTW in the page table array tells the paging hardware the
2429 sequence of that page content within the virtual segment. Thus
2430 ptwa0 locates the first page of the virtual segment; ptwa1 locates
2431 its second page; etc.
2432
2433
2434 See the Multics Processor Manual AL39-01C, Figure 5-3 for a diagram
2435 showing how pages of a segment are referenced by an instruction
2436 referencing a segno and offset which: identify a a virtual segment's
2437 SDW; and an offset within a page of that segment.
2438
2439
2440 Page table word:
2441 Each "Page Table Word ptw" exchanges information between Page
2442 Control software and the Demand Paging hardware appending unit of the
2443 processor. This exchange is bi-directional: SW <---> HW
2444
2445 By setting elements of the PTW, Page Control tells the paging hardware
2446 SW --> HW:
2447 - that page contents is loaded into a hardware "memory frame":
2448 a 1024-word aligned chunk of hardware memory which is 1024 words
2449 long ptw.df="1"b;
2450 - gives the absolute address of that memory frame in hardware memory
2451 ptw.add.
2452
2453
2454 The paging hardware sets bits in the PTW telling Page Control
2455 SW <-- HW that some program instruction has:
2456 - used loaded data from that page ptw.phu="1"b;
2457 - modified stored data into that page ptw.phm="1"b.
2458
2459
2460 Page Control also uses bits in the PTW to remember that ...
2461 - the address in the PTW ptw.add is either:
2462 - absolute address of a memory frame holding contents of the
2463 page ptw.add_type = "1000"b; or
2464 - device address of disk record holding contents of the page
2465 ptw.addr_type = "0100"b; or
2466 - a "null address" ="337020"b3 indicating a page holding
2467 only zero bits =36864"0"b which is fabricated by Page
2468 Control if the page is referenced ptw.addr_type = "0000"b.
2469 - an I/O operation is in-progress between memory frame and disk
2470 record ptw.os="1"b;
2471 - page content is wired unmoveable in hardware memory, and cannot
2472 be evicted from hardware memory by Page Control ptw.wired="1"b.
2473
2474
2475 If ptw.os="1"b, the direction of the I/O either read from disk into
2476 memory frame or write from memory into disk record is recorded in
2477 the CME describing that memory frame cme.io. The CME is introduced
2478 below.
2479
2480
2481 Contents of each PTW register is stored as a single word element of a
2482 segment's Page Table array. For purposes of this info topic, the
2483 main elements of the ptw structure >ldd>incl>ptw.incl.pl1 are:
2484
2485 dcl 1 ptw based ptwp aligned, /* Page Table Word */
2486
2487 2 add bit 18 /* page address add_type tells addr kind */
2488 2 add_type bit 4 /* "1000"b = memory frame absolute address */
2489 /* when page is valid in-memory*/
2490 /* "0100"b = disk address */
2491 /* "0000"b = null address page holds only */
2492 /* zero bits: 36864"0"b */
2493 2 first bit 1 /* page has not yet been written to disk */
2494 ...
2495 2 phu bit 1 /* "1"b = page has been used referenced */
2496
2497
2498 ...
2499 2 phm bit 1 /* "1"b = page has been modified */
2500 ...
2501 2 wired bit 1 /* "1"b = page is to remain in-memory */
2502 2 os bit 1 /* "1"b = page I/O in progress to frame */
2503 /* absadr in ptw.add element */
2504 /* "0"b = no I/O in progress to frame. */
2505 2 df bit 1 /* "0"b = page ^valid directed fault */
2506 /* "1"b = page valid no fault occurs */
2507 2 df_no bit 2 /* "01"b = fault treated as a "page fault" */
2508 unaligned;
2509
2510
2511 Core map:
2512 The Core Map supervisor segment core_map holds an array of Core Map
2513 Entry CME structures. These structures contain the main data used by
2514 Page Control to organize the work of Demand Paging. The array has
2515 enough elements to represent memory frames in the largest supported
2516 memory configuration: 4 System Control Units SCUs, each holding 4096
2517 memory frames, each frame of length 1024 words. This limit of 2**14
2518 memory frames is imposed by the length of the sdw.add element 24
2519 bits, which can address a maximum of 2**24 words of memory.
2520
2521 dcl 1 cma 0:16383 aligned like cme /* Core map array */
2522 basedsst.cmp;
2523
2524
2525 Absolute address of the memory frame described by a given CME can be
2526 determined from its index in the cma array:
2527
2528 absadr_memory_frame = cme_index * 1024;
2529
2530 It can also be determined from the offset of its CME within the
2531 core_map segment:
2532
2533 absadr_memory_frame = cme_offset - wordnosst.cmp * 256;
2534
2535
2536 Core map entry:
2537 Each "Core Map Entry" structure describes the current contents of one
2538 hardware memory frame.
2539
2540 Each CME is an even-word-aligned structure 4 words long. For purposes
2541 of this topic, the main elements of the cme >ldd>incl>cmp.incl.pl1
2542 structure are declared below.
2543
2544
2545 dcl 1 cme based cmep aligned, /* Core Map Entry */
2546
2547 2 fp bit 18 /* relp of next CME entry */
2548 2 bp bit 18 /* relp of previous CME entry */
2549 /* both offsets w/in core_map*/
2550
2551
2552 2 devadd bit 22 /* device addr of disk page */
2553 /* record_no || add_type */
2554 /* see mcme structure below */
2555 ...
2556 2 io bit 1 /* i/o direction 1=output 0=input*/
2557 /* meaningful if ptw.os="1"b */
2558 ...
2559 2 abs_w bit 1 /* absolute address must not be */
2560 /* be changed for this page */
2561 2 abs_usable bit 1 /* page may be assigned w/ fixed */
2562 /* wired absolute address */
2563 2 notify_requested bit 1 /* notify PC when I/O completes */
2564 ...
2565 2 contr bit 3 /* SCU controller for memory frame*/
2566
2567
2568 2 ptwp bit 18 /* relp to PTW for the page */
2569 2 astep bit 18 /* relp to ASTE describing */
2570 /* segment containing page */
2571 /* both offsets w/in sst_seg */
2572 ...
2573 unaligned;
2574
2575 dcl 1 mcme based cmep aligned, /* Core Map Entry for dev addr */
2576 2 pad bit 36
2577 2 record_no bit 18 /* record number on device */
2578 2 add_type bit 4 /* address type of record/page */
2579 /* see add_type.incl.pl1 */
2580 ...
2581 unaligned;
2582
2583
2584 Grouping of core map entries:
2585 Four main groups of CMEs are defined within the core_map array.
2586
2587
2588 - CMEs that are managed by Page Control and that participate in
2589 Demand Paging. These CMEs are threaded in a circular list using
2590 forward/back thread values in cme.fp and cme.bp. The sst.usedp and
2591 sst.wusedp header values identify CMEs in this circular list being
2592 focused on by various Page Control routines.
2593
2594 CMEs managed by Page Control are:
2595 - vacant if cme.astep, cme.ptwp = "000000"b3
2596 - in-use if cme.astep, cme.ptwp ^= "000000"b3 &
2597 cme.fp, cme.bp ^= "000000"b3
2598 - non I/O if cme.ptwp points to PTW with ptw.os = "0"b
2599
2600
2601 The in-use cme.ptwp value gives the relp relative pointer or
2602 wordnoptwp of the one PTW that addresses the memory frame
2603 described by that CME. The cme.astep value gives the relp of the
2604 ASTE associated with the Page Table containing that PTW. Actual
2605 pointers can be constructed from these relp offsets; both ASTE and
2606 Page Table managed by Page Control must be located in the SST
2607 segment.
2608 ptwp = pointer addrsst_seg$ cme.ptwp ;
2609 astep = pointer addrsst_seg$ cme.astep ;
2610
2611
2612 - CMEs that are usually managed by Page Control may be temporarily
2613 assigned to Device Control while an I/O operation is underway into
2614 or from that memory frame. Such CMEs are designated as:
2615 - in-use cme.astep, cme.ptwp ^= "000000"b3
2616 - I/O ongoing cme.fp, cme.bp = "000000"b3 &
2617 cme.ptwp points to PTW with ptw.os = "1"b
2618 - I/O direction cme.io = "0"b; disk rec. being input into frame
2619 cme.io = "1"b; frame being output to disk rec.
2620
2621
2622 The CME is unthreaded just before device_control is called to start
2623 an I/O operation to/from the memory frame. cme.fp and cme.bp remain
2624 zero while I/O is in progress.
2625
2626
2627 When that I/O completes, the interrupt handler returns the CME to
2628 Page Control by:
2629 - turning off the associated ptw.os flag ptw.os = "0"b; and
2630 - turning on the valid flag ptw.df = "1"b if a disk record
2631 was being read into the memory frame; and
2632 - threading the CME back onto the circular threaded list of CMEs
2633 managed by Page Control:
2634 - at the sst.usedp position: for frames just written to disk
2635 which are now potentially "evictable" from memory; or
2636 - just before the sst.wusedp position: for frames just read
2637 from a disk record which have a PTW which is now valid to
2638 reference.
2639
2640
2641 - CMEs describing memory frames containing supervisor segments whose
2642 content is loaded during the system bootload operations form a third
2643 group. Content of these segments is read from the Multics System
2644 Tape MST at bootload time.
2645
2646 While most of the segments have page tables, some of them are wired
2647 in memory ptw.wired="1"b while others are demand-paged by Page
2648 Control.
2649
2650
2651 Many have entries created in the fabricated >system_library_1 >sl1
2652 directory so they can be made known to a process and called as
2653 subroutines or referenced as data segments. These segments may be
2654 referenced using dynamic links as the user programs need these
2655 service libraries. They remain active at all times aste.hc="1"b
2656 aste.hc_sdw="1"b and aste.ehs="1"b so they are accessible during
2657 dynamic linking.
2658
2659
2660 Another segment variety is loaded only while the supervisor is
2661 initializing itself; then is deleted before Multics starts normal
2662 operation.
2663
2664
2665 Those supervisor segments that are managed by Page Control must obey
2666 the rules imposed by Page Control. They must have an ASTE and Page
2667 Table residing in the SST. Those whose pages are not wired in
2668 memory ptw.wired="0"b have semi-permanent storage for page
2669 contents in the hardcore partition on the root Physical Volume.
2670 This permits their pages to be evicted from memory until referenced
2671 by the ring-0 supervisor programs of a process.
2672
2673 For further details about hardcore segment varieties, see the azm
2674 help topic: help hardcore_segs.gi
2675
2676
2677 - CMEs describing memory frames residing in SCUs that are not
2678 configured on the system. Either:
2679 - SCU does not exist in the hardware configuration; or
2680 - SCUs have been cabled into the hardware configuration, but have
2681 not been added in the supervisor's config deck for the system.
2682
2683 Such CMEs are designated by:
2684 - cme.fp, cme.bp = "000000"b3
2685 - cme.astep, cme.ptwp = "000000"b3
2686 - cme.abs_w = "0"b
2687
2688 Note that cabled SCUs may be dynamically added to/removed from the
2689 system while Multics is in operation.
2690
2691
2692 This info block describes only the CMEs managed by Page Control the
2693 first of the four CME groups listed above; and those temporarily
2694 assigned to Disk Control while an I/O operation is in-progress. The
2695 next six sections give more details about the steps taken by the Demand
2696 Paging service to resolve a page fault.
2697
2698
2699 PAGE FAULT HANDLER:
2700
2701 When an instruction in the executing program references a page whose
2702 PTW is invalid ptw.df="0"b and ptw.df_no="01"b, a "page fault" event
2703 occurs.
2704
2705
2706 To handle the fault, the processor shifts the process execution point
2707 into the fault_vector segment: a ring-0 supervisor segment containing
2708 an array of instruction pairs, one pair for each fault type.
2709
2710 The pair for a page fault directed fault 1 does the following:
2711 - The first instruction an SCU stores state of the processor's
2712 Control Unit into a machine conditions structure designated for
2713 that fault type.
2714 - The second instruction transfers to the page_fault$fault subroutine
2715 which stores contents of all registers into the machine conditions
2716 structure and begins resolving the page fault. It masks receipt of
2717 interrupts.
2718
2719
2720 page_fault$fault pushes its own stack frame onto the beginning of the
2721 Processor Data Segment prds$. Each running processor has its own
2722 copy of this segment, so page faults can occur on more than one
2723 processor at a time. The page fault handler must acquire the global
2724 page table lock sst.ptl - a spin-lock to begin resolving a page fault
2725 event. Other processors encountering a page fault will loop at this
2726 point while trying to acquire this lock.
2727
2728 The SCU instruction in the fault vector and page_fault$fault subroutine
2729 both use the machine conditions structure >ldd>incl>mc.incl.pl1 to
2730 access data stored for a page fault at: pds$page_fault_data.
2731
2732 The next six sections describe the tasks performed to handle the page
2733 fault. These tasks were briefly summarized at the start of this info
2734 block. The tasks are now described in more detail.
2735
2736
2737 TASK A) Locate PTW experiencing the page fault:
2738
2739 page_fault$fault checks the machine conditions to determine which PTW
2740 was being referenced when the page fault occurred. Three or more
2741 PTWs are referenced by the Control Unit to execute an instruction, as
2742 numbered below.
2743 1. Fetching an SDW describing some virtual segment of the process.
2744 The page fault is for a PTW in the Page Table of the dseg.
2745 2. Fetching the next instruction to execute. The page fault is for a
2746 PTW in the Page Table for the executing program's segment.
2747 3. Fetching data referenced by the executing instruction. The page
2748 fault is for a PTW in the Page Table for that data segment.
2749
2750
2751 See the Multics Processor Manual AL39-01C, Figure 5-3 for a diagram
2752 showing these three possible PTW cases. For case:
2753 1. The PTW described above is the rightmost PTW in the diagram
2754 labeled PTWx1.
2755 2. The PTW is the leftmost PTW labeled PTWx2 in the diagram
2756 if the target segment is the executing program.
2757 3. The PTW is the leftmost PTW if the target segment contains data
2758 referenced by the current instruction word the instruction
2759 operand or an indirect word through which the instruction
2760 references its operand. There may be more than one indirection to
2761 access the operand.
2762
2763 Processor state data stored in the machine conditions tells which of
2764 these three possibilities caused the page fault.
2765
2766
2767 page_fault$fault then obtains a segment number segno involved in the
2768 reference. The choice differs for each case.
2769 1. If the SDW being referenced occurred while loading an instruction
2770 segment then the segment number comes from the Procedure Segment
2771 Register PSR; otherwise it comes from the Temporary Segment
2772 Register TSR.
2773 2. Segment number of the executing program obtained from the
2774 Procedure Segment Register PSR.
2775 3. Segment number of the data segment being referenced obtained from
2776 the Temporary Segment Register TSR.
2777
2778
2779 page_fault$fault determines the index into the Page Table for the
2780 faulted PTW. Again the choice differs for each case.
2781 1. The segno of SDW being referenced gives its offset in the dseg.
2782 Since an SDW is 2 words long segno*2-1/1024 gives index within
2783 dseg's Page Table of the PTW for that dseg page.
2784 2. From the PSR computed address or mc.scu.ca_word offset of the
2785 current instruction offset/1024 gives PTW index within Page Table
2786 for the executing segment.
2787 3. From the TSR computed address or mc.scu.ca_word offset of the
2788 referenced data segment location offset/1024 gives PTW index
2789 within Page Table of the referenced data segment.
2790
2791
2792 page_fault$fault uses the known location of the faulted PTW and the
2793 array index of that PTW within its Page Table to get a pointer to the
2794 start of that Page Table. Using that Page Table location it then gets
2795 a pointer to the ASTE preceding that Page Table that describes the
2796 segment referenced by the faulted PTW. Given ptwp and ptw_index and
2797 sizeptw structure being 1 word:
2798
2799 - pointer to Page Table ptp = addwordno ptwp -ptw_index ;
2800 - pointer to ASTE astep = addwordno ptp -sizeaste ;
2801
2802
2803 page_fault$fault calls read_page an internal procedure of page_fault
2804 to orchestrate the next tasks for resolving the page fault event.
2805
2806
2807 read_page begins to resolve the fault:
2808 Note that a PTW marked as invalid has no memory frame assigned to hold
2809 contents of the corresponding segment page. So the next task of
2810 resolving the page fault is to walk down the threaded list of CMEs
2811 managed by Page Control looking for a frame that is either unused
2812 vacant or has not been referenced recently.
2813
2814 read_page calls find_core another internal procedure of page_fault to
2815 select a vacant CME.
2816
2817
2818 TASK B Find a memory frame for the page:
2819
2820 find_core: implements the "clock algorithm" documented in the Multics
2821 Storage System Program Logic Manual AN61A Revision 0, Chapter 5, page
2822 5-9 and following. Figure 5-1 of that manual shows a diagram of the
2823 circular CME list. The text of that chapter describes the algorithm in
2824 great detail. The following is a summary of the algorithm obtained by
2825 reading the page_fault.alm code.
2826
2827 The clock algorithm approximates a search for the Least Recently Used
2828 LRU page which should be evicted from memory to make a vacant frame
2829 into which the faulted PTW's disk record can be read.
2830
2831
2832 The sst.usedp relp identifies the CME examined most recently when
2833 resolving the previous page fault. So the CME just forward in the
2834 threaded list cme.fp is the candidate CME that was least recently
2835 examined by the Demand Paging software. find_core begins its search by
2836 re-examining the CME pointed to by sst.usedp. CMEs for pages written
2837 to disk are rethreaded to that point, and are excellent candidates for
2838 being evictable.
2839
2840 - If that CME is vacant not associated with any PTW and therefore has
2841 cme.ptwp="0"b, then it can be assigned to resolve the page fault.
2842
2843 - Otherwise for a CME that is in-use, the paging hardware has marked
2844 its associated PTW if any instruction:
2845 - loaded data from the page "1"b ---> ptw.phu
2846 - stored data into the page "1"b ---> ptw.phm
2847
2848
2849 An in-use CME is "evictable" if its page has all of the following
2850 attributes:
2851 ptw.phu = "0"b & ptw.phm = "0"b &
2852 ptw.first = "0"b & ptw.wired = "0"b
2853
2854 which means:
2855 - the page contents in the memory frame is identical to the
2856 corresponding disk record; no disk I/O is needed to preserve page
2857 contents on disk, so the page can be evicted immediately; and
2858 - the page is not wired in memory.
2859
2860
2861 An in-use CME is skipped by the clock algorithm if it is not evictable.
2862 To skip a CME:
2863
2864 - advance to next CME in list cme.fp ---> sst.usedp
2865
2866
2867 To actually "evict" the page from memory, its PTW is invalidated, and
2868 its device address is moved from the CME back into its PTW:
2869
2870 - invalidate PTW "0"b ---> ptw.df
2871 - update PTW from CME mcme.add_type ---> ptw.add_type
2872 mcme.add ---> ptw.add
2873
2874
2875 Once the page is evicted from the memory frame, frame contents is
2876 zeroed, and the CME is "vacated" by zeroing all elements except its
2877 threads and SCU controller:
2878
2879 - save controller cme.contr ---> saved_controller
2880 - mark CME as vacant "0"b ---> substrstringcme37
2881 - restore controller saved_controller ---> cme.contr
2882
2883
2884 If 15 CMEs are examined without obtaining a vacant CME, then find_core
2885 interrupts its search to write some of the modified pages just skipped
2886 to disk. When such output operations complete, those CMEs will become
2887 evictable unless the page is modified after being queued for output to
2888 disk. find_core calls claim_mod_core an internal procedure of
2889 page_fault to start these write operations. When claim_mod_core ends
2890 its work, find_core then continues its search for a vacant CME.
2891
2892
2893 The clock algorithm continues until a vacant CME is found/created to
2894 designate a memory frame that can hold the page referenced by the
2895 faulted PTW. find_core returns to read_page with the relp offset of
2896 this vacant CME cme_offset.
2897
2898
2899 read_page continues:
2900 Using the Page Table and ASTE pointers obtained earlier, read_page
2901 also constructs a CME pointer using the cme_offset. At this point,
2902 read_page has the following pointers:
2903
2904 - pointer to faulted PTW ptwp
2905 - pointer to Page Table ptp = addwordno ptwp -ptw_index ;
2906 - pointer to ASTE astep = addwordno ptp -sizeaste ;
2907 - pointer to CME cmep = pointer sst.cmp cme_offset ;
2908
2909
2910 TASK C) Faulting PTW has a null address:
2911
2912 read_page checks the faulted PTW to determine the type of address it
2913 references. If it is a "null address" ptw.add_type="0000"b, Task C
2914 begins. Otherwise, read_page jumps to Task D.
2915
2916 For a null address, the PTW references a page of the segment that has
2917 never been modified from its starting value of all zero bits. No disk
2918 read is required for such page because content of a null address page
2919 has never been written to disk.
2920
2921
2922 read_page just assigns the vacated frame which already holds zeroed
2923 bits. But since the faulted page is now being referenced, it will
2924 likely be modified by the faulting instruction or by a future
2925 instruction. read_page first ensures that quota controls permit
2926 assigning a new disk record to the segment. If so, one page is
2927 withdrawn from that quota. If not, a record_quota_overflow condition
2928 is signalled in the ring-of-execution interrupted by the page fault
2929 event.
2930
2931 read_page also checks whether there is a free disk record on the
2932 physical volume containing the segment. If not, a segment fault is
2933 triggered physical volume is full.
2934
2935
2936 read_page then obtains a free disk record number from the physical
2937 volume map of the disk record_no. It uses this record_no and its
2938 astep, cmep and ptwp pointers to update the ASTE, CME, and PTW in that
2939 order per constraints imposed by pc_recover_sst and pc_check_tables_.
2940
2941 - update ASTE aste.records+1 ---> aste.records
2942 "1"b ---> aste.fmchanged
2943 - if J records were added aste.csl+J ---> aste.csl
2944 beyond current length
2945
2946 - store disk record in CME record_no ---> mcme.record_no
2947 "0100"b ---> mcme.add_type
2948 - store ASTE relp in CME wordnoastep ---> cme.astep
2949 - store PTW relp in CME wordnoptwp ---> cme.ptwp
2950
2951
2952 - calc absadr of memory frame
2953 described by vacant CME
2954 cme_offset-wordnosst.cmp/sizecme ---> cme_index
2955 cme_index*1024 ---> absadr_from_cme
2956
2957 - update PTW absadr_from_cme/64 ---> ptw.add
2958 "1000"b ---> ptw.add_type
2959 - not written to disk yet "1"b ---> ptw.first
2960 - no i/o in progress "0"b ---> ptw.os
2961 - ready to reference through "1"b ---> ptw.df
2962
2963
2964 When referencing a PTW with a "null address" in ptw.add, assigning a
2965 disk record_no to hold a possibly-modified page contents converts that
2966 to a "nulled address": a page that must be written to disk when the
2967 segment is deactivated even if ptw.phm="0"b. This change in
2968 designation is recorded by setting ptw.first="1"b.
2969
2970
2971 Note that PTWs from aste.csl+1 to end of Page Table are filled with
2972 null addresses when the segment is activated. So a reference to
2973 the Jth page beyond the current segment length adds J pages to that
2974 current segment length aste.csl, even though only the last of those
2975 pages is assigned a disk record at this time. The intervening pages
2976 keep their "null address". aste.records is increased by 1 for
2977 conversion of Jth page to a "nulled address" which now has a disk
2978 record assigned.
2979
2980
2981 read_page updates aste.dtu when the first page fault is processed for
2982 the segment, and updates aste.dtm if the faulting process has write
2983 access in SDW for the segment.
2984
2985 Note that date updates for multi-class segments and inner ring objects
2986 mailboxes message segments etc have different methods for updating
2987 their user-visible dates. Those are done on a per-object-type basis.
2988 Check the code for these object types.
2989
2990
2991 read_page then returns to page_fault$fault.
2992
2993
2994 page_fault$fault resolves the page fault for task C:
2995
2996 page_fault$fault sees ptw.os="0"b and ptw.df="1"b which indicate
2997 that no I/O is in-progress to the page, and the PTW is now valid to
2998 reference. So it ends handling of the page fault by:
2999 - unlocking the global page table lock sst.ptl;
3000 - unmasking interrupts;
3001 - restoring register contents; and
3002 - issuing an RCU instruction to restart execution of the instruction
3003 interrupted by the page fault event.
3004
3005
3006 TASK D) Faulting PTW has a disk address:
3007
3008 Since the test to enter Task C failed, read_page then checks if the
3009 faulted PTW contains a "disk address" ptw.add_type="0100"b. If that
3010 is true, then ptw.add is the index of the disk record which permanently
3011 stores contents of that segment page.
3012
3013
3014 read_page moves the disk record_no from the PTW into the just-assigned
3015 CME; and records the assignment of that memory frame in the PTW.
3016 Location of PTW and ASTE are captured in the CME. The PTW remains
3017 invalid ptw.df="0"b. The CME and PTW are marked with an "input"
3018 operation in-progress.
3019
3020 - store disk record in CME ptw.add ---> mcme.record_no
3021 ptw.add_type ---> mcme.add_type
3022 - store ASTE in CME wordnoastep ---> cme.astep
3023 - store PTW in CME wordnoptwp ---> cme.ptwp
3024
3025
3026 - calc absadr of memory frame
3027 described by vacant CME
3028 cme_offset-wordnosst.cmp/sizecme ---> cme_index
3029 cme_index*1024 ---> absadr_of_frame
3030
3031 - update PTW absadr_of_frame/64 ---> ptw.add
3032 "1000"b ---> ptw.add_type
3033
3034 - store "input" op in CME "0"b ---> cme.io
3035 - store i/o in progress in PTW "1"b ---> ptw.os
3036
3037
3038 read_page then unthreads the CME from the circular list of CMEs managed
3039 by Page Control by unhooking its partner CMEs, and setting the chosen
3040 CME's threads to zero.
3041
3042 - unthread CME while i/o in progress "0"b ---> cme.fp, cme.bp
3043
3044
3045 Once unthreaded, the CME is no longer protected by the global page
3046 table lock. It can therefore be updated by an I/O interrupt handler
3047 when the read operation completes.
3048
3049
3050 read_page then calls Device Control to invoke a disk Device Interface
3051 Module DIM to read the segment record into the memory frame.
3052
3053 interrupt_when_read_completes = "1"b;
3054 call device_control$dev_read aste.pvtx absadr_of_frame
3055 mcme.record_no
3056 interrupt_when_read_completes ;
3057
3058 When the page read request has been sent through a System Control Unit
3059 SCU to the appropriate I/O Module IOM, then read_page then returns
3060 to page_fault$fault.
3061
3062
3063 page_fault$fault usually must wait to resolve page fault for Task D:
3064
3065 Seeing that an I/O operation is in progress ptw.os="1"b and the PTW
3066 is still not valid ptw.df="0"b, page_fault$fault then calls
3067 claim_mod_core internal procedure of page_fault so that CMEs
3068 describing modified pages located by the find_core internal procedure
3069 can be scheduled to have their modified frame contents written out to
3070 disk. These write operations will overlap the disk read operation
3071 needed to resolve the current page fault event.
3072
3073
3074 When claim_mod_core returns, page_fault$fault then checks whether the
3075 read I/O operation is still in progress.
3076
3077 - If no I/O is in-progress to the page ptw.os="0"b, then the PTW is
3078 now valid to reference ptw.df="1"b.
3079
3080
3081 On a multi-CPU system, the read completed while claim_mod_core was
3082 executing, and an interrupt handler for the read running on another
3083 CPU changed the PTW state to valid ptw.df="1"b with no I/O in
3084 progress ptw.os="0"b. This was permitted because the unthreaded
3085 CME and its PTW were not protected by the global page table lock.
3086
3087 Early completion allows page_fault$fault to unlock the global page
3088 lock, unmask interrupts, restore register contents, and issue an RCU
3089 instruction to restart execution of the instruction interrupted by
3090 the page fault event.
3091
3092
3093 - If the disk read operation is still in progress ptw.os="1"b, then
3094 page_fault$fault must block execution of the faulting process until
3095 the read completes.
3096
3097 - get APTE for process pds$apt_ptr ---> aptep
3098 - set wait_event in APTE cme.ptwp ---> apte.wait_event
3099
3100 - tell interrupt handler
3101 to notify when I/O done "1"b ---> cme.notify_requested
3102 - unlock global page lock call unlock_ptl;
3103 - tell scheduler to wait call pxss$page_wait;
3104
3105
3106 page_fault$fault abandons its stack frame at the beginning of the
3107 prds$ stack segment when it calls pxss$page_wait and gives up the
3108 processor. The machine conditions describing the page fault remain
3109 in pds$page_fault_data.
3110
3111
3112 Note that most interrupt handlers also push their stack frame onto the
3113 beginning of the prds$ stack. The stack history on that segment is
3114 transient only valid while the interrupt or fault is being handled.
3115 - Interrupt handlers are always required to restore the interrupted
3116 instruction to resume execution of the usually unrelated process
3117 that was running on the CPU when the interrupt was received.
3118 - Fault handlers like page_fault$fault are processing a fault caused
3119 by the process running on the CPU. They can therefore block
3120 execution of that process to wait for an event completion. The call
3121 to pxss$page_wait abandons the stack frame on the prds, unmasks the
3122 interrupt cell, then switches to execution of another ready process
3123 on that CPU.
3124
3125
3126 TASK E) Page read I/O completion:
3127
3128 When the page read operation completes, the IOM ends the I/O operation
3129 and the System Control Unit SCU updates the assigned interrupt cell
3130 for that IOM, and then reports that it has an interrupt pending to all
3131 connected CPUs.
3132
3133 When a processor completes execution of its current instruction, it
3134 samples the interrupt present lines from all eight memory interface
3135 ports. If any interrupt is present, it accepts the interrupt from the
3136 highest-priority port.
3137
3138
3139 To handle the interrupt, that processor shifts the process execution
3140 point into the interrupt vector the leading part of the fault_vector
3141 segment a ring-0 supervisor segment. The interrupt vector contains
3142 an array of instruction pairs; several pairs are assigned to each
3143 system controller. The processor sends an XEC system controller
3144 command to the SCU whose line interrupt was accepted.
3145
3146
3147 The controller responds by clearing its highest priority interrupt cell
3148 and returning the interrupt trap pair address to the processor.
3149
3150 The CPU reads the instruction pair for the interrupt cell and does the
3151 following:
3152 - The first instruction a Store Control Unit or SCU instruction
3153 stores state of the processor's Control Unit into a machine
3154 conditions structure designated for that controller's interrupt
3155 cell.
3156 - The second instruction transfers to the interrupt handler, the
3157 iom_interrupt$interrupt_entry subroutine, which stores contents of
3158 all registers into the machine conditions structure and begins
3159 handling the interrupt. It masks receipt of other interrupts.
3160
3161
3162 For details about initial handling of interrupts, see the Multics
3163 Processor Manual AL39-01C, Section 7, "Interrupts and External
3164 Faults".
3165
3166
3167 iom_interrupt$interrupt_entry pushes its own stack frame onto the
3168 beginning of the Processor Data Segment prds$. Each running
3169 processor has its own copy of this segment, so interrupts can be
3170 handled on more than one processor at a time.
3171
3172 The SCU instruction in the interrupt vector and the iom_interrupt
3173 subroutine both use the machine conditions structure
3174 >ldd>incl>mc.incl.pl1 to access data stored for a page fault at:
3175 prds$interrupt_data.
3176
3177
3178 Each Device Interface Module DIM managing a particular external
3179 device type registers with the supervisor for use of a particular
3180 interrupt cell on each IOM configured with the device type it supports.
3181 When an interrupt is reported for a given interrupt cell, that cell
3182 selection is mapped by data in the iom_data supervisor segment onto a
3183 specific interrupt handler for the DIM, and a saved core_addr for the
3184 memory frame location holding the read/written segment page. For disk
3185 I/O operations on Multics Storage System disk volumes, the assigned
3186 interrupt handler is page$done.
3187
3188
3189 iom_interrupt invokes this ring-0 interrupt handler to complete
3190 processing of the page read operation.
3191
3192 - call handler call page$done core_addr code ;
3193
3194
3195 page$done is actually an entry in page_fault.alm. page_fault$done uses
3196 the core_addr absolute address into which the disk record was read to
3197 locate the CME describing that memory frame.
3198
3199 - get CME pointer core_addr/1024 ---> cme_index
3200 addr sst.cmp -> cmacme_index ---> cmep
3201
3202 - get PTW pointer pointer sst_seg$ cme.ptwp ---> ptwp
3203
3204
3205 page_fault$done then checks cme.io to determine whether the completed
3206 operation was for a page-read or page-write.
3207
3208 For a page-read input operation, page_fault$done rethreads the CME
3209 for the just-read page to the CME that precedes the sst.wusedp pointer.
3210 This can be done safely without holding the global page table lock
3211 because Page Control doesn't reference CMEs preceding the sst.wusedp
3212 relp hand in the clock algorithm until the next pass around the CME
3213 threads.
3214
3215
3216 page_fault$done then updates the PTW which points to that memory frame.
3217
3218 - no I/O in progress "0"b ---> ptw.os
3219 - PTW valid "1"b ---> ptw.df
3220
3221 Any process that now references that PTW will find it valid.
3222
3223
3224 If the CME says some process is waiting for the I/O to complete
3225 cme.notify_requested="1"b, then page_fault$done tells the scheduler
3226 to notify all processes already waiting on that page read that they may
3227 resume execution. The offset of the PTW is again used as the wait
3228 event to notify.
3229
3230 - notify I/O completion call pxss$page_notify cme.ptwp ;
3231
3232
3233 pxss$page_notify marks processes waiting on the wait event as "ready to
3234 run", updating their restart location to page_fault$wait_return because
3235 they no longer have a stack frame on the prds$ segment that records
3236 their execution point. That frame was abandoned at the end of the
3237 Task D steps described above.
3238
3239
3240 The I/O completion handler then returns to iom_interrupt, which unmasks
3241 interrupts, and restarts the interrupted process using an RCU
3242 instruction for the machine conditions at prds$interrupt_data. The
3243 stack frame at the beginning of the prds is abandoned by iom_interrupt.
3244
3245
3246 TASK F) Restarting page fault after i/o completion:
3247
3248 When the scheduler finds resources to run a process waiting for a page
3249 fault resolution, execution resumes at page_fault$wait_return. That
3250 entry has no stack frame of its own. Luckily, it has very little to do
3251 in restarting the page faulting instruction. Its main data comes from
3252 the saved page fault machine conditions at: pds$page_fault_data
3253
3254 page_fault$wait_return:
3255 - updates metering data in the SST;
3256 - restores register contents to values saved in the original machine
3257 conditions; and
3258 - executes an RCU instruction to restart execution of the instruction
3259 interrupted by the page fault event.
3260
3261
3262 Since the interrupt handler has updated the PTW, page_fault$wait_return
3263 has no need to reference the specific PTW or CME itself. Location of
3264 the once-faulted PTW is restored from the saved machine conditions.
3265
3266 The interrupted instruction resumes execution and its reference though
3267 the PTW now succeeds.
3268
3269
3270 This completes the introduction to Demand Paging. Other azm general
3271 information topics have introduced aspects of the Multics Storage
3272 System, and provided details about data structures checked by the azm
3273 page_control_check pcc request.
3274
3275 Process Virtual Memory virtual_segment.gi.info
3276 Permanent Storage on Disk for a Segment disk_segment.gi.info
3277
3278 Connect a Segment to a Process
3279 A) Make Segment Known to the Process initiate_seg.gi.info
3280 B) Segment Fault When Accessed by the Process seg_fault.gi.info
3281
3282
3283 Demand Paging demand_paging.gi.info
3284 Consistency Checks by page_control_check pcc_checks.gi.info
3285
3286 To display the final information block, type: help pcc_checks.gi
3287
3288
3289 :Info: pcc_checks.gi: pcc_checks:
3290 2023-03-11 Consistency Checks by page_control_check
3291
3292 System Segment Table sst -- holds
3293 - Active Segments List -- a threaded list of item pairs
3294 - Active Segment Table Entry aste
3295 - Page Table ptwa
3296
3297 Core Map - contains
3298 - a threaded list of CMEs managed by Page Control cme
3299
3300
3301 Other azm general info blocks have introduced Segment Control and Page
3302 Control subsystems and their data bases in the following topics.
3303
3304 Process Virtual Memory virtual_segment.gi.info
3305 Permanent Storage on Disk for a Segment disk_segment.gi.info
3306
3307 Connect a Segment to a Process
3308 A) Make Segment Known to the Process initiate_seg.gi.info
3309 B) Segment Fault When Accessed by the Process seg_fault.gi.info
3310
3311 Demand Paging demand_paging.gi.info
3312
3313
3314 The threaded list of CMEs managed by Page Control are the central
3315 database for Demand Paging. The ASTE and PTW referenced by each CME,
3316 and the CME itself, are the main data structures checked by the azm
3317 page_control_check request.
3318
3319
3320 Core map entry:
3321 Each CME describes the current contents of one frame 1024-word block
3322 of hardware memory. The description ties together two representations
3323 of a segment:
3324
3325 attributes and records of a segment stored permanently on disk
3326
3327 attributes and pages of the segment known to one or more processes
3328
3329
3330 CME relationships established by page control:
3331 Elements of the CME data structure link contents of a particular
3332 memory frame to descriptions of a segment as stored on disk.
3333
3334 Notice that a CME is associated with the ASTE and PTW of an active
3335 segment only when a record of that segment is loaded into the memory
3336 frame described by that CME.
3337
3338
3339 The relationships are as follows.
3340 - The overall attributes of a segment as described by an Active
3341 Segment Table Entry ASTE are referenced by the CME cme.astep.
3342 The ASTE includes:
3343 - a physical disk identifier aste.pvtx of the disk providing
3344 permanent storage for the segment.
3345 - index of a Volume Table of Contents Entry aste.vtocx
3346 describing physical attributes of the segment which are stored
3347 permanently on that disk.
3348
3349
3350 - The location record_no holding the Ith record of that segment on
3351 disk comes from its file map array vtoce.fmI. That record is
3352 or will be stored in the memory frame described by the CME. The
3353 record_no is stored in the CME cme.add.
3354
3355 - the Ith PTW in the Page Table associated with that ASTE contains
3356 the absolute address of the memory frame described by the CME.
3357 The CME references the offset of that Ith PTW cme.ptwp in the
3358 sst_seg.
3359
3360
3361 Page control rules:
3362 This method by which a disk segment in the Multics Storage System is
3363 accessed as a virtual segment memory region in a process workspace
3364 imposes several rules on Segment Control and Page Control.
3365
3366 1) Only one activation ASTE for a particular disk segment can
3367 appear in the system's Active Segments List at any point in time.
3368
3369 a) Each user process that wants to reference contents of this
3370 disk segment must do so by sharing access to that active
3371 segment ASTE and its associated Page Table.
3372
3373
3374 b) Each of its disk records can be loaded into only one memory
3375 frame at a time, and can therefore appear in only one active
3376 segment at a time.
3377
3378 c) The Ith record of the segment's file map on disk
3379 vtoce.fmI must be referenced by the Ith PTW of the active
3380 segment's Page Table ptwaI. This maintains the same
3381 logical sequence of bits found in the segment on disk and in
3382 the virtual segment accessed by each process.
3383
3384
3385 Consistency checks performed by pcc:
3386 The azm page_control_check pcc request performs the same consistency
3387 checks which are done by Multics shutdown. The pc_check_tables_
3388 subroutine performs these checks during a normal shutdown, and during a
3389 Multics system interruption system crash. It checks for, reports on,
3390 and tries to remove inconsistencies from the Multics Storage System's
3391 permanent data.
3392
3393 During a system crash, the dump image is first saved, then Emergency
3394 Shutdown ESD runs pc_check_tables_. So the dump image does not
3395 include any corrections that pc_check_tables_ makes.
3396
3397
3398 The azm pcc request runs pc_check_tables_ in a mode that locates and
3399 reports inconsistencies, but does not make any changes to remove such
3400 inconsistencies. Thus, the request may be run several times against
3401 the same dump image, and will report the same inconsistencies each time
3402 it runs.
3403
3404
3405 The pc_check_tables_ subroutine checks contents of ASTEs, Page Tables,
3406 and CMEs and reports any variance from the rules stated above.
3407
3408 - Each non-vacant CME should have a cme.ptwp value that gives the
3409 offset of the one-and-only PTW having a ptw.add value which is the
3410 absolute address of the memory frame described by that CME.
3411
3412 - Each non-vacant CME should have a cme.astep value that gives the
3413 offset of the ASTE preceding the Page Table which contains the PTW
3414 referenced by the cme.ptwp offset.
3415
3416 - Each in-use ASTE should have the correct count of disk records
3417 loaded into the the active segment's memory pages aste.np, as
3418 indicated by the count of PTWs in the associated Page Table having
3419 ptw.df = "1"b.
3420
3421
3422 The checks can generate the following inconsistency reports.
3423
3424 - A CME that has a non-zero cme.astep with a zero cme.ptep value.
3425
3426 - A CME that has a non-zero cme.ptwp with a zero cme.astep value.
3427
3428 - A PTW that has a ptw.add value referencing a memory frame whose CME
3429 does not have a cme.ptwp offset referencing that PTW.
3430
3431 - An ASTE that has:
3432 aste.np ^= countPTWs in its associated Page Table w/ ptw.df="1"b
3433
3434 - An ASTE that has:
3435 aste.csl ^= countPTWs w/ legitimate record_no or frame absadr
3436
3437
3438 Examples of these inconsistency reports are shown in the info block
3439 describing the pcc request. Type: help pcc -scn Examples
3440
3441
3442 Structures referenced:
3443 For this info topic, the main elements of the Active Segment Table
3444 Entry aste, page table ptwa and ptw, and Core Map Entry cme
3445 structures are shown below. These are the only structures wired
3446 in-memory at all times, and therefore available for checking in every
3447 complete dump image by the pcc request.
3448
3449
3450 dcl 1 cme based cmep aligned, /* Core Map Entry */
3451
3452 2 fp bit 18 /* relp of next CME entry */
3453 2 bp bit 18 /* relp of previous CME entry */
3454 /* both offsets w/in core_map */
3455
3456
3457 2 devadd bit 22 /* device addr of disk page */
3458 /* record_no || add_type */
3459 /* see mcme structure below */
3460 ...
3461
3462
3463 2 ptwp bit 18 /* relp to PTW for the page */
3464 2 astep bit 18 /* relp to ASTE describing segment*/
3465 /* segment containing page */
3466 /* both offsets w/in sst_seg */
3467 ...
3468 unaligned;
3469
3470 dcl 1 mcme based cmep aligned, /* Core Map Entry for dev ID */
3471 2 pad bit 36
3472 2 record_no bit 18 /* record number on device */
3473 2 add_type bit 4 /* address type of record/page */
3474 /* see ptw.add_type below */
3475 ...
3476 unaligned;
3477
3478
3479 dcl 1 aste based astep aligned, /* Active Segment Table Entry */
3480 ...
3481 2 pvtx fixed bin 8 /* seg physical disk volume table index */
3482 2 vtocx fixed bin 17 /* seg vtoc entry index */
3483 2 usedf bit 1 /* ASTE is being used if non-zero */
3484 ...
3485 2 csl bit 9 /* current seg length in 1024-word units */
3486 ...
3487 2 records bit 9 /* count of records used on disk for seg */
3488 2 np bit 9 /* count of seg pages currently in memory*/
3489 ...
3490
3491
3492 2 ptsi bit 2 /* page table size index */
3493 /* ="00"b 4-word page table follows */
3494 /* ="01"b 16-word page table follows */
3495 /* ="10"b 64-word page table follows */
3496 /* ="11"b 256-word page table follows */
3497 ...
3498 unaligned;
3499
3500
3501 For an ASTE located by astep pointer...
3502
3503 ptp = addwordno astep sizeaste ;
3504 pt_size = sst.pts fixedaste.ptsi - 1;
3505
3506 dcl 1 ptwa 0:pt_size based ptp aligned like ptw; /* Page Table */
3507
3508
3509 dcl 1 ptw based ptwp aligned, /* Page Table Word */
3510
3511 2 add bit 18 /* page address add_type tells addr kind */
3512 2 add_type bit 4 /* "1000"b = memory frame absolute address */
3513 /* when page is valid in-memory*/
3514 /* "0100"b = disk address */
3515 /* "0000"b = null address page holds only */
3516 /* zero bits: 36864"0"b */
3517 ...
3518 2 df bit 1 /* "0"b = page ^valid directed fault */
3519 /* "1"b = page valid no fault occurs */
3520 2 df_no bit 2 /* "01"b = fault treated as a "page fault" */
3521 unaligned;
3522
3523
3524 :Info: seg_initiate_code_path.gi:
3525 2023-02-06 Ring-0 Subroutines involved in Initiating a Segment
3526
3527 This info block provides a partial list of the subroutines called to
3528 perform tasks A and B shown below.
3529
3530
3531 Connect a Segment to a Process
3532 A) Make Segment Known to the Process initiate_seg.gi.info
3533 - Find segment information using the
3534 directory hierarchy.
3535 - Verify process has some access rights to segment.
3536 - If segment is on a private LV: verify LV is mounted and
3537 attached by the user process.
3538 - Get KSTE and SDW for segment.
3539 - Re-use existing KSTE/SDW if segment already in-use by
3540 process, or has been used earlier in the session.
3541 - Extend seg access if ACL/RBs now grant write access
3542 OR
3543 - Describe Segment to Hardware and Supervisor
3544 - Fill-in faulted Segment Descriptor Word SDW
3545 - Fill-in Known Segment Table Entry KSTE
3546
3547
3548 B) Segment Fault When Accessed by the Process seg_fault.gi.info
3549 - Find segment in, or add a segment to, the
3550 List of Active Segments in-use by the system.
3551 - Fill-in process access rights in SDW and KSTE.
3552 - If process rights change encacheability of the segment,
3553 change encacheability setting in SDWs of ALL referencing
3554 processes.
3555 - Add SDW Trailer Record STR to ASTE tracking this process as
3556 referencing the active segment.
3557
3558
3559 Task A above is requested by a call to initiate_file_ or
3560 hcs_$initiate_count or other hcs_ makeknown routine. Each of these
3561 subroutines ends up in the initiate_.pl1 ring-0 subroutine.
3562
3563
3564 initiate_.pl1
3565 Call dc_find$obj_initiate
3566 - Find/lock parent directory of segment
3567 - Find directory entry in parent directory
3568 - Check access rights: if none, returns nonzero error code
3569 Call mountedp -- Check if private LV containing segment is now
3570 mounted, and has been lv_attached by the process.
3571
3572
3573 Call makeknown_
3574 Call kstsrch -- Search for a KSTE and SDW for the segment
3575 - If found: if access modes need to be extended, disconnect
3576 seg_fault its SDW
3577 - If ^found: assign a segno from the process KST
3578 - fill-in KSTE values
3579 - change SDW for force seg_fault access violation fault
3580 records process access rights to segment contents in SDW
3581 Call unlock_dir_ -- unlock parent directory
3582
3583 initiate_ code then...
3584 - inserts any ref_name into RNT
3585 - initializes LOT entry for seg if first use of seg used in caller's
3586 ring of execution
3587 - returns to caller
3588
3589
3590 Task B above is performed automatically as a second supervisor service
3591 when the process actually references the SDW for the first time. This
3592 reference causes a hardware seg_fault directed fault 0. Process
3593 effective access and segment encacheability is computed at that time.
3594
3595
3596 seg_fault.pl1
3597 - Get segno of faulting SDW from MC
3598 - Check for fault on never-created stack segment. If so
3599 - Call makestack -- create missing stack segment
3600 - Return to caller, where seg_fault will be repeated on
3601 now-existing stack seg
3602 - Get KSTE and SDW
3603 - Get directory entry, fill-in KSTE and SDW elements
3604 - Use kste.entryp to find directory entry.
3605 - Call sum$getbranch_root_my -- verify kste.entryp still valid,
3606 and lock containing directory.
3607 - Call dc_find$seg_fault -- set SDW access from:
3608 kste.access
3609 OR
3610 entry.ring_brackets, entry.access_class, entry.acle_count
3611
3612
3613 - Call activate$activate_long to get ASTE and Page Table
3614 - Look for existing ASTE.
3615 - If found, return that ASTE and its Page Table.
3616 - If not found, assign unused ASTE and Page Table to activate
3617 the segment.
3618 - Create STR to track segment use by the current process
3619
3620
3621 :Info: hardcore_segs.gi: hardcore_segs:
3622 2023-04-22 Types of Hardcore Supervisor Segments
3623
3624 Multics hardcore supervisor segments are loaded from the Multics System
3625 Tape MST during system bootload operations. They include a wide
3626 variety of segment characteristics. Some segments are present only
3627 during early bootload operations. Others remain to form the Multics
3628 supervisor and essential libraries needed when Multics begins normal
3629 operations.
3630
3631 The next section describes segments which form the ring-0 supervisor
3632 present in the memory workspace of all processes.
3633
3634
3635 Common supervisor segment numbers used in every process:
3636
3637 segno range
3638 --------------
3639 Common supervisor segnos 0 thru 227
3640 Common stack segnos 230 thru 237
3641 Per-process segnos 230 and higher
3642
3643
3644 All ring-0 supervisor segments appear in every process, using a segment
3645 number assigned by the Segment Loader Table Entry SLTE for that
3646 segment.
3647
3648 PL/I pointers reference data by segment number and offset within a
3649 segment. Because every process references each ring-0 segment using
3650 the same assigned segment number, these supervisor segments can contain
3651 PL/I pointers to data in other ring-0 supervisor segments. The
3652 pointers reference the correct data no matter which process is running
3653 code in the supervisor.
3654
3655
3656 For example, the sst_seg segno 102 begins with the sst structure
3657 whose sst.cmp element points to the location in the core_map segno 47
3658 at which the Core Map array begins. This allows declarations in ring-0
3659 code such as:
3660
3661 dcl 1 cma 0:16383 aligned like cme /* Core map array */
3662 basedsst.cmp;
3663
3664 to declare ring-0 supervisor variables with pointers that identify the
3665 same segments in every process.
3666
3667
3668 The shared supervisor code can continue a scheduling operation on its
3669 assigned CPU while switching from one process address space to a
3670 different process address space. This works correctly because all
3671 ring-0 code uses the same segment numbers in every process to identify
3672 each supervisor segment.
3673
3674
3675 Most of these common supervisor segments are described by identical
3676 SDWs in every process's Descriptor Segment dseg: the same underlying
3677 segment is referenced by every process. Known Segment Table Entries
3678 KSTEs are not required for these identical supervisor segments
3679 because they are never deactivated.
3680
3681
3682 From the two common segno ranges in the above table, eleven 11
3683 reference a per-process segment: each per-process segment is tied to
3684 its own segment instance which is stored in the process directory on
3685 disk.
3686
3687 One segno from the common supervisor segno range references a
3688 per-processor segment: that virtual segment is tied to a different
3689 segment instance tailored for each running CPU. These per-CPU segment
3690 instances are stored in the >system_library_1 directory.
3691
3692
3693 These twelve segment numbers referencing different instances of the
3694 same named segment are described in the next three sections of this
3695 info block.
3696
3697
3698 SEG TYPE -- Per-process common ring-0 supervisor segments:
3699
3700 Three of the ring-0 supervisor segments have contents tailored to
3701 needs of the process. Each of these segments is known by the same
3702 segment number in every process; but segment contents differs for each
3703 process. This supports process-specific data content maintained by
3704 the ring-0 supervisor.
3705
3706
3707 Each of these process-specific segments has the Segment Loader Table
3708 SLT attribute: per_process. Those segments are:
3709
3710 - Descriptor Segment dseg -- holding an array of SDWs defining the
3711 process's virtual memory workspace.
3712
3713 - Known Segment Table kst_seg -- holding
3714 - a header describing the process's virtual memory workspace
3715 e.g. its range of segment numbers; followed by
3716 - an array of Known Segment Table Entries KSTEs giving details
3717 about each non-ring-0-supervisor segment known to the process.
3718 This information is needed to re-activate segments made known by
3719 the process.
3720
3721
3722 - Process Data Segment pds -- a common ring-0 supervisor segment
3723 giving details about the current process. It has the same set of
3724 named entry points, with the same data items stored at each entry
3725 point. But those items have distinct values describing
3726 characteristics or values associated only with the current process.
3727
3728
3729 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
3730 The SLTE entry for all three per-process segments is shown below.
3731
3732 azm: slte -attr per_process
3733
3734 dseg 0 0 0 0 read write wired
3735 per_process
3736 wired length: 1 pages; max length: 8 pages;
3737
3738 kst_seg 67 0 0 0 read write encacheable
3739 per_process
3740 total length: 64 pages;
3741 path: >process_dir_dir>!zzzzzzzbBBBBBB>kst_seg
3742
3743
3744 pds 71 0 0 0 read write encacheable wired
3745 per_process
3746 wired length: 1 pages; total length: 2 pages;
3747 max length: 4 pages;
3748 path: >process_dir_dir>!zzzzzzzbBBBBBB>pds
3749
3750
3751 SEG TYPE -- Per-processor common ring-0 supervisor segment:
3752
3753 A fourth ring-0 supervisor segment is identified by a segno assigned by
3754 its SLTE, but each segment instance has contents tailored to the
3755 particular processor CPU on which the scheduled process is running.
3756
3757 - Processor Data Segment prds: a segment with structure elements
3758 for:
3759 - processor-specific details needed by the ring-0 supervisor; and
3760 - automatic variables used by the idle process which runs on that
3761 CPU; followed by
3762 - a ring-0 interrupt-oriented stack call history and automatic
3763 variable storage used by all interrupt handlers and some fault
3764 handlers e.g. page fault -- aka directed fault 1.
3765
3766
3767 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
3768 Traffic Control pre-withdraws an ASTE and Page Table for the prds
3769 instance for each CPU in the config deck. The offset within the
3770 sst_seg of each per-CPU ASTE is stored in the APTE entry for the
3771 Idle.SysDaemon process that runs on that CPU. apte.prds is normally
3772 "000000"b3 for most processes; but in an Idle.SysDaemon process, it
3773 holds the offset within the SST of the ASTE describing the prds segment
3774 for that processor.
3775
3776 When Traffic Control selects a process to run on a given CPU, it
3777 updates the prds SDW segno 72 for that process to have the address
3778 and length of the prds segment instance tailored for that CPU.
3779 Contents of the stack stored on the end of the prds is invalidated each
3780 time another process is scheduled to run on the CPU.
3781
3782
3783 While these prds segments have the same structure overlaying the
3784 segment, each element can hold a different value on each CPU. In
3785 particular, each prds stack has a different stack history and automatic
3786 variables pushed onto the stack at any given point in time.
3787
3788
3789 Note that stack history is abandoned each time an interrupt or fault
3790 handler completes work on that CPU; no prds stack history survives
3791 process switching. History is valid for an interrupt or fault being
3792 handled on that CPU when the system crash occurs. If PR6 of machine
3793 conditions points to the prds segno 72, then that stack history is
3794 valid.
3795
3796
3797 While processing an interrupt or fault on that stack, the scheduler's
3798 timer interrupts are masked thereby preventing timer-based process
3799 switching interrupts while another interrupt/fault is being handled on
3800 that stack.
3801
3802
3803 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
3804 The SLTE for the prds segment is shown below.
3805
3806 azm: slte prds
3807
3808 prds 72 0 0 0 read execute write privileged encacheable wired
3809 breakpointable
3810 wired length: 10 pages;
3811 path: >system_library_1>prds
3812
3813
3814 On a running system, the actual pathname of the prds instances has the
3815 form:
3816 >system_library_1>cpu_A.prds
3817
3818 where A is replaced by the CPU letter of the particular CPU.
3819
3820
3821 SEG TYPE -- Per-process common stack segments:
3822
3823 Segnos 230 through 237 are reserved for stack segments in ring-0
3824 through ring-7. The segment number range for stacks is set by the
3825 dbr.stack_base_segno value loaded in the Descriptor Base Register.
3826 For example:
3827
3828 azm: d tc_data|4144 -as l68_dbr
3829 l68_dbr at 112|4144
3830 add = "16630134"b3, bound = "00000001111111"b, stack_base_segno = 19
3831 OFF: unpaged
3832
3833
3834 The CALL6 instruction uses the dbr.stack_base_segno value to select the
3835 stack segment when crossing into a lower more privileged
3836 ring-of-execution.
3837
3838
3839 See the Multics Processor Manual AL39-01C description of the CALL6
3840 instruction for a discussion of this stack segno identification
3841 mechanism.
3842
3843
3844 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
3845 While these stack segment number assignments are the same in every
3846 process, only the stack_0 segno: 230 is a segment in the ring-0
3847 supervisor. The other stacks describe running programs in the outer
3848 ring subsystems, and user programs.
3849
3850
3851 All of these stack segments have separate instances for each process;
3852 process A's stack_I is a different segment from process B's stack_I.
3853 Therefore, these stack_I segments must have entries in the process's
3854 Known Segment Table KST tracking their existence and location in the
3855 storage system hierarchy. They are each stored in the process
3856 directory of their process pd>stack_I where I varies from 0 to 7.
3857 These stack segments have no SLT entries.
3858
3859
3860 SEG TYPE -- Common ring-0 supervisor segments with no page table:
3861
3862 Three supervisor segments are defined without using a Page Table.
3863 These segments span the first three memory frames, but only the
3864 fault_vector begins on a 1024-word boundary has an absolute address
3865 ending in octal 0000 2000 4000 or 6000.
3866
3867 azm: sdw 3 11
3868 ADDRESS RNGS CA-MAX REWPUGCDF EBOUND SEGNO SEGMENT-NAME
3869 3400 000 2777 R W UG DF 0 3 dn355_mailbox
3870 0 000 577 R W UG DF 0 4 fault_vector
3871 ...
3872 1200 000 2177 R W UG DF 0 11 iom_mailbox
3873
3874
3875 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
3876 CMEs describing the first three frames of hardware memory have "0" relp
3877 values in all of their CME relp elements cme.fp cme.bp cme.astep and
3878 cme.ptwp elements - displayed below as labels: FWD BACK ASTEP PTWP.
3879 The "U" flag under the REWPUGCDF label above and the DFWU label
3880 below both indicate that the segment is "unpaged": defined without
3881 using a page table.
3882
3883 azm: cme -ix 0 1 2
3884
3885 CME_INDX FWD BACK ASTEP PTWP DFWU --- FRAME CONTENT ------ FLAGS ---
3886 0 0 0 0 0 WU Seg 4|0 fault_vector abs_wired
3887 1 0 0 0 0 WU Seg 11|600 iom_mailbox abs_wired
3888 2 0 0 0 0 WU Seg 3|400 dn355_mailbox abs_wired
3889
3890
3891 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
3892 The SLT entries for these segments are shown below.
3893
3894 azm: slte 4 11 3
3895
3896 fault_vector 4 0 0 0 read write wired ^paged
3897 wired length: 384 words;
3898
3899 iom_mailbox 11 0 0 0 read write wired ^paged
3900 wired length: 1152 words;
3901
3902 dn355_mailbox 3 0 0 0 read write wired ^paged
3903 wired length: 1536 words;
3904
3905
3906 SEG TYPE -- breakpoint page appearing in many supervisor segments:
3907
3908 The breakpoint_page segment is a special supervisor segment containing
3909 only one page. This "breakpoint page" is designed to appear at the end
3910 of many different code-bearing supervisor segments. It is used by the
3911 bce_probe command to track breakpoints created in hardcore supervisor
3912 segments. The bce_probe command is available only in the Bootload
3913 Command Environment BCE.
3914
3915
3916 The regular probe command tracks breakpoints created in any program by
3917 storing data about that breakpoint in the user's PERSON_ID.probe
3918 segment kept in the user's home directory. When a breakpoint is
3919 reached, the probe command looks in this shared .probe segment to find
3920 details about the breakpoint, actions to be taken when reached, etc.
3921
3922
3923 However, the BCE environment does not support Demand Paging. So a
3924 PERSON_ID.probe cannot be defined as a separate segment that is brought
3925 into memory when a supervisor breakpoint is reached.
3926
3927 Instead, the shared bce_probe breakpoint information is stored in the
3928 single-page wired breakpoint_page segment. The bootloader appends a
3929 PTW pointing to this page as the last PTW in the Page Table of any
3930 supervisor segment in which bce_probe might set a breakpoint. Thus,
3931 the shared breakpoint_page appears as a final page in many different
3932 wired supervisor segments.
3933
3934 When a breakpoint is reached, bce_probe can look in the final page of
3935 the breaking segment to access details about the breakpoint.
3936
3937
3938 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
3939 The following SLTE shows the properties of the breakpoint_page segment.
3940
3941 azm: slte 14
3942
3943 breakpoint_page 14 0 0 0 read write wired ^paged
3944 wired length: 1 pages;
3945
3946
3947 Note that its Page Table is stored in the unpaged_page_tables segment
3948 rather than in the SST. The breakpoint_page segment is only used
3949 while running in the wired Bootload Command Environment.
3950
3951 azm: aste 14
3952
3953 Segment without ASTE: breakpoint_page Seg 14 in Proc 0,
3954 with Page Table at unpaged_page_tables|36.
3955
3956 PAGE PTW DEVADD at unpaged_page_tables|36
3957
3958 0 000560420025 null wired breakpoint_page
3959
3960
3961 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
3962 Early in collection 1 operation, the breakpoint_page is appended to the
3963 Page Table of each wired supervisor segment having the SLTE
3964 breakpointable attribute. It must be setup in this early bootload
3965 collection because a memory image of the wired BCE execution workspace
3966 is captured in the separate BCE partition of the Root physical volume.
3967 bce_probe is only available when the Bootload Command Environment has
3968 been called and is running on this separate memory workspace.
3969
3970
3971 The following SLTE output shows start of the list of supervisor
3972 programs to which a breakpoint page is appended.
3973
3974 azm: slte -pri -attr breakpointable ^abs_seg
3975
3976 as_linkage 16 0 0 0 read execute write
3977 breakpointable
3978 total length: 3 pages;
3979 max length: 17 pages;
3980
3981 ws_linkage 17 0 0 0 read execute write wired ^paged
3982 breakpointable
3983 wired length: 4 pages;
3984
3985
3986 bound_active_1 31 0 0 0 read execute encacheable
3987 breakpointable
3988 total length: 6 pages;
3989
3990 bound_disk_util_1 32 0 0 0 read execute encacheable
3991 breakpointable
3992 total length: 3 pages;
3993
3994 bound_error_active_1 33 0 0 0 read execute encacheable
3995 breakpointable
3996 total length: 4 pages;
3997
3998
3999 bound_interceptors 34 0 0 0 read execute privileged
4000 encacheable wired ^paged
4001 breakpointable
4002 wired length: 4 pages;
4003 ...
4004
4005
4006 The Page Table for one of these segments shows a final SDW referencing
4007 the same memory frame address ptw.add = "000560"b3 for the
4008 breakpoint_page.
4009
4010 azm: aste 34
4011
4012 Segment without ASTE: bound_interceptors Seg 34 in Proc 0
4013 with Page Table at unpaged_page_tables|60.
4014
4015 PAGE PTW DEVADD at unpaged_page_tables|60
4016
4017 0 001240421125 null phu phm wired
4018 1 001260421125 null phu phm wired
4019 2 001300421125 null phu phm wired
4020 3 000560420025 null wired breakpoint_page
4021
4022
4023 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4024 A cme request for the breakpoint_page segment shows the offset of its
4025 single page within the core_map segment.
4026
4027 azm: cme -seg breakpoint_page
4028
4029 CMEs for Segment without ASTE: breakpoint_page Seg 14 in Proc 0
4030 with Page Table at unpaged_page_tables|36.
4031
4032 CME_OFS FWD BACK ASTEP PTWP DFWU --- FRAME CONTENT ------------------
4033 144 0 0 0 0 W Seg 14|0 breakpoint_page
4034 CA-MAX 1777
4035
4036
4037 Using that same offset the cme search option shows all the other
4038 segments which end with a breakpoint_page when Multics is in normal
4039 operation.
4040
4041 azm: cme -search 144
4042
4043 21 PTWs reference memory frame described by core_map|144:
4044
4045 CME_OFS FWD BACK ASTEP PTWP DFWU --- FRAME CONTENT ------------------
4046 144 0 0 0 0 W Seg 14|0 breakpoint_page
4047 144 0 0 0 0 W Seg 17|6000 ws_linkage
4048 144 0 0 0 0 W Seg 34|6000 bound_interceptors
4049 144 0 0 0 0 W Seg 35|12000 bound_io_wired
4050 144 0 0 0 0 W Seg 37|4000 bound_iom_support
4051
4052
4053 144 0 0 0 0 W Seg 42|50000 bound_page_control
4054 144 0 0 0 0 W Seg 43|6000 bound_priv_1
4055 144 0 0 0 0 W Seg 44|10000 bound_tc_priv
4056 144 0 0 0 0 W Seg 45|2000 bound_unencacheable
4057 144 0 0 0 0 W Seg 46|30000 bound_wired_1
4058 144 0 0 0 0 W Seg 55|2000 emergency_shutdown
4059 144 0 0 0 0 W Seg 61|2000 init_processor
4060 144 0 0 0 0 W Seg 75|2000 restart_fault
4061 144 0 0 0 0 W Seg 76|2000 return_to_ring_0_
4062 144 0 0 0 0 W Seg 100|2000 signaller
4063 144 0 0 0 0 W Seg 127|2000 bound_error_wired_2
4064 144 0 0 0 0 W Seg 146|2000 bound_tc_wired
4065 144 0 0 0 0 W Seg 72|22000 prds
4066 144 0 0 0 0 W Seg 314|114000 bound_library_wired_
4067
4068
4069 144 0 0 0 0 W Seg 122|54000 bound_355_wired
4070 144 0 0 0 0 W Seg 332|42000 error_table_
4071
4072
4073 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4074 Once Multics bootload completes many of these segments in the BCE
4075 wired environment have been made pageable with Page Table moving into
4076 the SST. As part of this move the breakpoint_page is removed from
4077 their Page Table since it is not used in the normal paged ring-0
4078 supervisor environment.
4079
4080
4081 For example the slte request during collection 1 shows
4082 bound_disk_util_1 as ending with a breakpoint_page PTW.
4083
4084 azm: sld >old_dumps>21
4085 Could not find apte for process_idx 0
4086 dbr = 54012
4087 This is an early dump.
4088
4089 ERF 21 in directory >old_dumps dumped at 09/19/21 0638.4 pst Sun.
4090 Proc 0 DBR 54012 empty last on cpu Initializer.SysDaemon.z
4091
4092
4093 The breakpoint_page is the final page of this segment.
4094
4095 azm: aste 32
4096
4097 Segment without ASTE: bound_disk_util_1 Seg 32 in Proc 0
4098 with Page Table at int_unpaged_page_tables|654.
4099
4100 PAGE PTW DEVADD PD COPY at int_unpaged_page_tables|654
4101
4102 0 775400401005 null phu
4103 1 775420401005 null phu
4104 2 000560420025 null wired breakpoint_page
4105
4106
4107 After the BCE memory workspace has been captured in the BCE partition
4108 the once-wired segment 32 is made pageable with an ASTE and Page Table
4109 in the SST segment. The breakpoint_page no longer appears in that Page
4110 Table.
4111
4112 azm: sld >old_dumps>22
4113 Could not find apte for process_idx 0
4114 dbr = 17543650
4115 This is an early dump.
4116
4117 ERF 22 in directory >old_dumps dumped at 09/19/21 0652.3 pst Sun.
4118 Proc 0 DBR 17543650 empty last on cpu Initializer.SysDaemon.z
4119
4120 azm: aste 32
4121
4122
4123 ASTE for bound_disk_util_1 Seg 32 in Proc 0 at SST|1360.
4124
4125 1360 0 000000000000 000000000000 000032000000 000000000000
4126 1364 4 000001777777 430100300000 000000000000 000000000000
4127 1370 10 000000000003 000000000000 003424003003 000000000002
4128
4129 uid = 000000000000 vtocx -1 on pvtx 1 dska device 0
4130 max len 0 3 recs used 3 in core cur len 3
4131 Not updated as used.
4132 Not updated as modified.
4133 Hardcore segno = 32
4134 Quota S D = 0 3
4135
4136 Flags: usedf hc hc_sdw hc_part ehs nqsw fmch dnzp ddnp
4137
4138
4139 PAGE PTW DEVADD PD COPY at SST|1374
4140
4141 0 775600400045 17130 phu1
4142 1 775560400045 17131 phu1
4143 2 775540400045 17126 phu1
4144 3 377012000001 null
4145
4146
4147 SEG TYPE -- Supervisor segments loaded only during initialization:
4148
4149 "Initializing segments" may be loaded into hardware memory frames only
4150 during the bootload process and are visible only in so-called "early
4151 dumps" taken before the Multics supervisor has been initialized and is
4152 ready for normal operation.
4153
4154
4155 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4156 In this sample dump bootload has loaded/run collection 0 loaded
4157 collection 1 software and is just starting initialization by running
4158 the collection 1 software.
4159
4160 azm: sld >old_dumps>21
4161 Could not find apte for process_idx 0
4162 dbr = 54012
4163 This is an early dump. <---= "early dump" indicator
4164
4165 ERF 21 in directory >old_dumps dumped at 09/19/21 0638.4 pst Sun.
4166 Proc 0 DBR 54012 empty last on cpu Initializer.SysDaemon.z
4167
4168
4169 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4170 "Initializing segments" are read from the Multics System Tape MST and
4171 loaded into hardware memory in consecutive memory frames. The slte
4172 request shows Segment Loader Table information for segment 430. These
4173 initializing segments are always referenced by segments numbered 400
4174 and above. Each includes the "init_seg" slte attribute. The -header
4175 -he control argument displays current segno ranges loaded when the
4176 dump was taken: shared supervisor segments from 0 through 115; and
4177 initializing segments from 400 through 465.
4178
4179 azm: slte -he -primary 430
4180
4181
4182 Supervisor Segments Initializing Segments
4183 First: 0 First: 400
4184 Last: 115 Last: 465
4185
4186 bound_bce_wired 430 0 0 0 read execute privileged
4187 init_seg breakpointable
4188 wired length: 8 pages;
4189
4190
4191 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4192 The SDW and Page Table for segment 430 are shown below.
4193
4194 azm: sdw 430
4195 ADDRESS RNGS CA-MAX REWPUGCDF EBOUND SEGNO SEGMENT-NAME
4196 54642 000 17777 RE P G DF 0 430 bound_bce_wired
4197
4198
4199 Segment 430 is 8 pages long including the breakpoint_page. Note that
4200 its Page Table is stored in the int_unpaged_page_tables segment:
4201 visible only in early dumps since it holds Page Tables for initializing
4202 segments.
4203
4204 azm: aste 430
4205
4206 Segment without ASTE: bound_bce_wired Seg 430 in Proc 0
4207 with Page Table at int_unpaged_page_tables|642.
4208
4209
4210 PAGE PTW DEVADD at int_unpaged_page_tables|40
4211
4212 0 775440400005 null
4213 1 775460400005 null
4214 2 775500400005 null
4215 3 775520400005 null
4216 4 775540400005 null
4217 5 775560400005 null
4218 6 775600400005 null
4219 7 000560420025 null wired breakpoint_page
4220
4221
4222 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4223 This early in collection 1 the core_map segment is just being setup.
4224 Most CME entries have FWD and BACK threads set to "777777"b3 with zero
4225 relp values for ASTEP and PTWP.
4226
4227 azm: cme -seg 430
4228
4229 CMEs for Segment without ASTE: bound_bce_wired Seg 430 in Proc 0
4230 with Page Table at int_unpaged_page_tables|642.
4231
4232
4233 CME_OFS FWD BACK ASTEP PTWP DFWU --- FRAME CONTENT --------------
4234 177320 777777 777777 0 0 Segment could not be identified.
4235 series of 7 vacant frames
4236 177350 777777 777777 0 0 Segment could not be identified.
4237 144 777777 777777 0 0 Segment could not be identified.
4238 CA-MAX 35777
4239
4240
4241 CMEs describing memory frames containing supervisor segments whose
4242 content is loaded during the system bootload operations are
4243 designated by:
4244 - cme.fp cme.bp = "000000"b3
4245 - cme.abs_w = "1"b
4246 These memory frames are part of the entire supervisor and are not
4247 managed by Page Control.
4248
4249
4250 The Core Map Entry CME entries in such early dumps often have 777777
4251 as their cme.fp and cme.bp FWD and BACK values to indicate pages
4252 occupied by such initializing segments in early dumps. These are not
4253 thread offsets of related CMEs just identifiable values signifying CME
4254 contents setup for use while initializing the supervisor. A later
4255 bootload step changes these thread values to "000000"b3 for permanently
4256 wired supervisor segments; or threads them into the CME list describing
4257 memory frames managed by Page Control.
4258
4259
4260 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4261 By the middle of collection 1 an ASTE and Page Table have been
4262 constructed for segment 430 in the SST. Its SDW has been updated
4263 accordingly.
4264
4265 azm: sld >old_dumps>22
4266 This is an early dump.
4267
4268 ERF 22 in directory >old_dumps dumped at 09/19/21 0652.3 pst Sun.
4269 Proc 0 DBR 17543650 empty last on cpu Initializer.SysDaemon.z
4270
4271 azm: sdw 430
4272 ADDRESS RNGS CA-MAX REWPUGCDF EBOUND SEGNO SEGMENT-NAME
4273 17544030 000 17777 RE P G DF 0 430 bound_bce_wired
4274
4275
4276 The ASTE and Page Table indicate the segment has been upgraded to a
4277 hardcore segment with pages that are no longer wired and with backing
4278 store in the hardcore partition. The breakpoint_page is no longer
4279 associated with the segment because this segment is only used by BCE's
4280 probe command and the BCE non-paged memory image has already been
4281 saved to the BCE partition on the root PV.
4282
4283 azm: aste 430
4284
4285 ASTE for bound_bce_wired Seg 430 in Proc 0 at SST|16014.
4286
4287 16014 0 016050001260 000000000000 000430000000 000000000000
4288 16020 4 000001777777 410100300000 000000000000 000000000000
4289 16024 10 000000000010 000000000000 010424010010 000000000102
4290
4291
4292 uid = 000000000000 vtocx -1 on pvtx 1 dska device 0
4293 max len 0 8 recs used 8 in core cur len 8
4294 Not updated as used.
4295 Not updated as modified.
4296 Hardcore segno = 430
4297 Quota S D = 0 8
4298
4299 Flags: usedf hc_sdw hc_part ehs nqsw fmch dnzp ddnp
4300
4301
4302 PAGE PTW DEVADD at SST|16030
4303
4304 0 775720400045 17140 phu1
4305 1 775700400045 17141 phu1
4306 2 775660400045 17136 phu1
4307 3 775640400045 17137 phu1
4308 4 775620400045 17134 phu1
4309 5 776060400045 17135 phu1
4310 6 776040400045 17132 phu1
4311 7 777360400045 17133 phu1
4312 10 377012000001 null
4313 ====
4314 17 377012000001 null
4315
4316
4317 The CMEs describing memory frames holding this segment have been
4318 assigned to Page Control. When bound_bce_wired is terminated by the
4319 Initializer this initializing segment's pages are evicted from memory
4320 by Page Control for lack of use; and the segment becomes deactivated
4321 by Segment Control because no process references the segment.
4322
4323 azm: cme -seg 430
4324
4325
4326 CMEs for ASTE for bound_bce_wired Seg 430 in Proc 0 at SST|16014.
4327
4328 CME_OFS FWD BACK ASTEP PTWP DFWU --- FRAME CONTENT ------------
4329 177374 177370 177330 16014 16030 Seg 430|0 bound_bce_wired
4330 177370 177364 177374 16014 16031 Seg 430|2000 bound_bce_wired
4331 177364 177360 177370 16014 16032 Seg 430|4000 bound_bce_wired
4332 177360 177354 177364 16014 16033 Seg 430|6000 bound_bce_wired
4333 177354 177424 177360 16014 16034 Seg 430|10000 bound_bce_wired
4334 177424 177420 177354 16014 16035 Seg 430|12000 bound_bce_wired
4335 177420 177704 177424 16014 16036 Seg 430|14000 bound_bce_wired
4336 177704 177270 177420 16014 16037 Seg 430|16000 bound_bce_wired
4337 CA-MAX 17777
4338
4339
4340 SEG TYPE -- Wired common ring-0 supervisor segments:
4341
4342 Many of the common ring-0 supervisor segments are wired in memory
4343 frames so they can hold Segment Control Page Control Traffic Control
4344 and I/O-related code and data which must be referenced without
4345 possibility of a page fault or of segment disconnection etc.
4346
4347 These segments do not have an entry in the >system_library_1 >sl1
4348 directory and therefore are not accessible as supervisor services
4349 callable from an outer ring program. They may be used only by other
4350 programs running in the ring-0 supervisor.
4351
4352
4353 An important example is the System Segment Table SST segment.
4354
4355 The "System Segment Table SST" ...
4356 - holds pointers to Segment Control data and resources;
4357 - holds the list of active segments: the ASTEs;
4358 - provides storage for most of the system's Page Tables;
4359 - holds meters for Segment Control and Page Control operations; and
4360 - defines locks used by Segment Control and Page Control to protect
4361 critical sections of code that update these data items.
4362
4363
4364 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4365 The SDW and ASTE for the SST are shown below. There is no need for the
4366 PTWs to be designated as wired ptw.wired="0"b because the Core Map
4367 Entries CMEs for the SST pages are not managed by Page Control.
4368
4369 azm: sdw 102
4370 ADDRESS RNGS CA-MAX REWPUGCDF EBOUND SEGNO SEGMENT-NAME
4371 52410 000 505777 R W G DF 0 102 sst_seg
4372
4373 azm: aste 102
4374
4375 Segment without ASTE: sst_seg Seg 102 in Proc 0
4376 with Page Table at unpaged_page_tables|410.
4377
4378
4379 PAGE PTW DEVADD at unpaged_page_tables|410
4380
4381 0 170700401105 null phu phm
4382 1 170720401105 null phu phm
4383 ...
4384
4385
4386 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4387 CMEs describing memory frames containing supervisor segments whose
4388 content is loaded during the system bootload operations are
4389 designated by:
4390 - cme.fp cme.bp = "000000"b3
4391 - cme.abs_w = "1"b
4392 These memory frames are part of the entire supervisor and are not
4393 managed by Page Control.
4394
4395
4396 The CMEs for the SST shows its wired pages in consecutive memory frames
4397 each CME describes one memory frame and its 4 words long.
4398
4399 azm: cme -seg 102
4400
4401 CMEs for Segment without ASTE: sst_seg Seg 102 in Proc 0
4402 with Page Table at unpaged_page_tables|410.
4403
4404 CME_OFS FWD BACK ASTEP PTWP DFWU --- FRAME CONTENT ----- --- FLAGS
4405 36170 0 0 0 0 W Seg 102|0 sst_seg abs_wired
4406 36174 0 0 0 0 W Seg 102|2000 sst_seg abs_wired
4407 ...
4408
4409
4410 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4411 The SLTE for the SST gives some of its key attributes.
4412
4413 azm: slte 102
4414
4415 sst_seg 102 0 0 0 read write wired ^paged
4416 sst wired length: 20 pages;
4417
4418
4419 SEG TYPE -- Paged common ring-0 supervisor segments:
4420
4421 Many of the common ring-0 supervisor segments contain code or data and
4422 are Demand Paged by Page Control. Such segments must have an ASTE and
4423 Page Table in the SST aste.hc_sdw = "1"b.
4424
4425 These segments do not have an entry in the >system_library_1 >sl1
4426 directory and therefore are not accessible as supervisor services
4427 callable from an outer ring program. They may be used only by other
4428 programs running in the ring-0 supervisor.
4429
4430 Because these segments are read from the Multics System Tape MST at
4431 bootload time their page content is preserved using records from the
4432 hardcore partition aste.hc_part="1"b on the Root Physical Volume
4433 RPV. ASTE Flags are set to prevent deactivation aste.ehs = "1"b.
4434
4435
4436 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4437 The SDW ASTE and Page Table for a typical paged common ring-0
4438 supervisor segment are shown below.
4439
4440 azm: sdw 31
4441 ADDRESS RNGS CA-MAX REWPUGCDF EBOUND SEGNO SEGMENT-NAME
4442 17171574 000 13777 RE GCDF 0 31 bound_active_1
4443
4444 azm: aste 31
4445
4446 ASTE for bound_active_1 Seg 31 in Proc 0 at SST|101560.
4447
4448
4449 101560 0 000000000000 000000000000 000031000000 000000000000
4450 101564 4 000001777777 430100300000 000000000000 000000000000
4451 101570 10 000000000006 000000000000 006424006006 000000000102
4452
4453 uid = 000000000000 vtocx -1 on pvtx 1 dska device 0
4454 max len 0 6 recs used 6 in core cur len 6
4455 Not updated as used.
4456 Not updated as modified.
4457 Hardcore segno = 31
4458 Quota S D = 0 6
4459
4460 Flags: usedf hc hc_sdw hc_part ehs nqsw fmch dnzp ddnp
4461
4462
4463 PAGE PTW DEVADD at SST|101574
4464
4465 0 775740401045 17146 phu phu1
4466 1 776200401045 17147 phu phu1
4467 2 776160401045 17144 phu phu1
4468 3 776140401045 17145 phu phu1
4469 4 776120401045 17142 phu phu1
4470 5 776100400045 17143 phu1
4471 6 377012000001 null
4472 ====
4473 17 377012000001 null
4474
4475
4476 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4477 The CME for bound_active_1 shows all of its relp offsets populated.
4478
4479 azm: cme -seg 31
4480
4481
4482 CMEs for ASTE for bound_active_1 Seg 31 in Proc 0
4483 at SST|101560.
4484
4485 CME_OFS FWD BACK ASTEP PTWP DFWU --- FRAME CONTENT ----------
4486 177400 177450 174224 101560 101574 Seg 31|0 bound_active_1
4487 177450 177444 177400 101560 101575 Seg 31|2000 bound_active_1
4488 177444 177440 177450 101560 101576 Seg 31|4000 bound_active_1
4489 177440 177434 177444 101560 101577 Seg 31|6000 bound_active_1
4490 177434 177430 177440 101560 101600 Seg 31|10000 bound_active_1
4491 177430 177350 177434 101560 101601 Seg 31|12000 bound_active_1
4492 CA-MAX 13777
4493
4494
4495 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4496 The SLTE for bound_active_1 gives some of its key attributes.
4497
4498 azm: slte 31
4499
4500 bound_active_1 31 0 0 0 read execute encacheable
4501 initializer breakpointable
4502 call_bce total length: 6 pages;
4503 delete_segs
4504 freecore prds_init fast_connect_init wire_proc
4505 get_main rsw_util mask_instruction init_scu
4506 flagbox_mgr ptw_util_ sdw_util_ dbr_util_
4507
4508
4509 SEG TYPE -- Wired ring-0 supervisor service segments:
4510
4511 Many ring-0 supervisor segments provide services to programs running
4512 in outer rings. These supervisor segments have:
4513 - a directory entry usually in the >system_library_1 sl1 directory
4514 allowing their segment names to be found by the dynamic linker
4515 according to linker search paths; and
4516 - ring brackets e. g. 055 allowing them to be read in outer rings
4517 so program entry points may be located and allowing the executing
4518 program to transfer to a named entry point using the CALL6
4519 instruction or to a PL/1 operator using a TSPn instruction without
4520 changing their ring-of-execution.
4521
4522
4523 Some of these supervisor service programs are wired in memory frames so
4524 they are instantly available for use by the executing program. The
4525 pl1_operators_ segment in >sl1>bound_library_wired_ is an important
4526 example of a wired supervisor service program.
4527
4528
4529 ls >sl1>pl1_operators_
4530
4531 Segments = 1 Lengths = 38.
4532
4533 re 38 bound_library_wired_
4534 clock_
4535 ...
4536 ioa_
4537 alloc_
4538 ...
4539 pl1_operators_
4540 any_to_any_
4541 dec_ops_
4542 ...
4543
4544
4545 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4546 The SLT entry for pl1_operators_ is shown below.
4547
4548 azm: slte pl1_operators_ -primary
4549
4550 bound_library_wired_ 41 0 5 5 read execute encacheable wired
4551 breakpointable
4552 wired length: 15 pages;
4553 total length: 39 pages;
4554 path: >sl1>bound_library_wired_
4555
4556
4557 While most of the wired supervisor service segments are entirely wired
4558 in memory frames a few specific segments are only partially wired.
4559 The non-wired pages participate in the Demand Paging algorithms.
4560
4561 For example only the first 14 pages of bound_library_wired_ are
4562 actually wired in memory. This covers all code through the end of the
4563 pl1_operators_ object component of that bound segment.
4564
4565
4566 The make_sdw.pl1 program of the ring-0 supervisor controls partial
4567 wiring for the following segments:
4568
4569 dseg only first page is wired
4570 error_table_ only first page is wired
4571 pds only first page is wired
4572 pl1_operators_ first 14 pages are wired + final breakpoint_page
4573
4574 Most processes seldom use more than 512 SDWs which fit in the first
4575 page of their dseg segment; so only that 1 page is wired. All of the
4576 fixed bin35 error code values are stored in the first page of
4577 error_table_. Several machine condition structures are stored in the
4578 first page of the pds segment. And much-used program support
4579 subroutines and operators are kept in the first 14 pages of
4580 bound_library_wired_ which includes pl1_operators_.
4581
4582
4583 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4584 The SDW ASTE and Page Table for bound_library_wired_ are shown below.
4585 The non-wired pages ptw.wired=0"b are controlled by Demand Paging
4586 software.
4587
4588 azm: sdw 41
4589 ADDRESS RNGS CA-MAX REWPUGCDF EBOUND SEGNO SEGMENT-NAME
4590 17260634 000 115777 RE GCDF 0 41 bound_library_wired_
4591
4592 azm: aste 41
4593
4594
4595 ASTE for bound_library_wired_ Seg 41 in Proc 0 at SST|170620.
4596
4597 170620 0 000000000000 170504000000 037644103630 544045573063
4598 170624 4 047001000045 414100300000 000000000000 000000000000
4599 170630 10 000000000046 000000000000 046424046046 000000000202
4600
4601
4602 uid = 544045573063 vtocx 45 on pvtx 1 dska device 0
4603 max len 39 38 recs used 38 in core cur len 38
4604 Not updated as used.
4605 Not updated as modified.
4606 Par astep = 103630 Son = 0 brother = 170504
4607 Trailer thread = 37644
4608 Quota S D = 0 38
4609
4610 Flags: usedf hc_sdw hc_part ehs aaccon nqsw fmch dnzp ddnp
4611
4612
4613 PAGE PTW DEVADD at SST|170634
4614
4615 0 774720401025 17276 phu wired
4616 1 774700401025 17273 phu wired
4617 2 774660401025 17274 phu wired
4618 3 774640401025 17271 phu wired
4619 4 774620401025 17272 phu wired
4620 5 774600401025 17267 phu wired
4621 6 774560401025 17270 phu wired
4622 7 774540401025 17265 phu wired
4623 10 774520401025 17266 phu wired
4624 11 774500401025 17263 phu wired
4625 12 774460401025 17264 phu wired
4626 13 774440401025 17261 phu wired
4627
4628
4629 14 774420401025 17262 phu wired
4630 15 774400401025 17257 phu wired
4631 16 774360400045 17260 phu1
4632 17 774340400045 17255 phu1
4633 20 774320400045 17256 phu1
4634 21 774300400045 17253 phu1
4635 22 774260401045 17254 phu phu1
4636 23 774240401045 17251 phu phu1
4637 24 774220401045 17252 phu phu1
4638 25 774200401045 17247 phu phu1
4639 26 774160401045 17250 phu phu1
4640 27 774140401045 17245 phu phu1
4641 30 774120400045 17246 phu1
4642 31 774100400045 17243 phu1
4643 32 774060400045 17244 phu1
4644
4645
4646 33 774040400045 17241 phu1
4647 34 774020401045 17242 phu phu1
4648 35 774000401045 17237 phu phu1
4649 36 773760401045 17240 phu phu1
4650 37 773740401045 17235 phu phu1
4651 40 773720401045 17323 phu phu1
4652 41 776360400045 17236 phu1
4653 42 776340400045 17233 phu1
4654 43 776320400045 17234 phu1
4655 44 776300400045 17231 phu1
4656 45 776260401045 17232 phu phu1
4657 46 000560401125 null phu phm wired breakpoint_page
4658 47 377012000001 null
4659 ====
4660 77 377012000001 null
4661
4662
4663 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4664 The Core Map Entry CME for bound_library_wired_ shows all memory
4665 frames in the circular list of Demand Paging CMEs having non-zero relp
4666 values in the FWD BACK ASTEP and PTWP columns except for page 46
4667 octal of the segment which is a special abs_wired breakpoint_page
4668 used by the BCE probe command. However Demand Paging software ignores
4669 wired pages ptw.wired="1"b of the segment.
4670
4671 azm: cme -seg 41
4672
4673 CMEs for ASTE for bound_library_wired_ Seg 41 in Proc 0
4674 at SST|170620.
4675
4676
4677 CME_OFS FWD BACK ASTEP PTWP DFWU -- FRAME CONTENT -------------
4678 177174 177170 176774 170620 170634 41|0 bound_library_wired_
4679 177170 177164 177174 170620 170635 41|2000 bound_library_wired_
4680 ...
4681 177464 177754 177470 170620 170701 41|112000 bound_library_wired_
4682 144 0 0 0 0 W 41|114000 bound_library_wired_
4683 CA-MAX 115777
4684
4685
4686 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4687 The wired supervisor service segments can be listed using the following
4688 slte request: slte -pri -attr wired branch
4689
4690
4691 :hcom:
4692 /****^ HISTORY COMMENTS:
4693 1 change2023-04-28GDixon, approve2023-03-07MCR10129a,
4694 audit2023-04-29Swenson, install2023-04-29MR12.8-1055:
4695 A) Initial version of this info segment.
4696 B) Add new hardcore_segs.gi.info block.
4697 END HISTORY COMMENTS */