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 program(s) 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 ptwa(0) locates the memory frame containing the first page of the
 520 virtual segment; ptwa(1) 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_ ( addr(makeknown_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_count(ring) + 1 ---> kste.usage_count(ring)
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_bucket(hash_bucket) ---> kste.fp
1124                     wordno(kstep) ---> kst.uid_hash_bucket(hash_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_count(ring) + 1 ---> kste.usage_count(ring)
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 = addr(dseg$);
1534    sdwp  = addr(sdwa(segno));
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_entry(seg_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.level(N) 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, size(aste) );
1833          pt_size = sst.pts( fixed(aste.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       addr(pds$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_brackets(1)) ---> (sdw.r1)
2024                        (entry.ring_brackets(2)) ---> (sdw.r2)
2025                        (entry.ring_brackets(3)) ---> (sdw.r3)
2026        - mode                            (mode) ---> string(sdw.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, size(aste) );
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.fm(i)) ---> (ptw(i).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              wordno(strp) ---> pointer( str_seg$, aste.strp ) -> str.bp
2104              wordno(strp) ---> 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 ---> string(sdw.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     wordno(ptp) + 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 process(es) 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, size(aste) );
2402          pt_size = sst.pts( fixed(aste.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, -size(aste) );
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 ptwa(0) locates the first page of the virtual segment; ptwa(1) 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           based(sst.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 - wordno(sst.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    wordno(ptwp)) 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( addr(sst_seg$), cme.ptwp  );
2609       astep = pointer( addr(sst_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 PTW(x1)).
2755  2. The PTW is the leftmost PTW (labeled PTW(x2) 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 size(ptw) structure being 1 word:
2798 
2799  - pointer to Page Table     ptp = addwordno( ptwp, -ptw_index );
2800  - pointer to ASTE         astep = addwordno( ptp,  -size(aste) );
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 ---> substr(string(cme),37)
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,    -size(aste) );
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     wordno(astep) ---> cme.astep
2949  - store PTW  relp in CME      wordno(ptwp) ---> cme.ptwp
2950 
2951 
2952  - calc absadr of memory frame
2953    described by vacant CME
2954      (cme_offset-wordno(sst.cmp))/size(cme) ---> 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          wordno(astep) ---> cme.astep
3023  - store PTW  in CME           wordno(ptwp) ---> cme.ptwp
3024 
3025 
3026  - calc absadr of memory frame
3027    described by vacant CME
3028      (cme_offset-wordno(sst.cmp))/size(cme) ---> 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 -> cma(cme_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.fm(I)).  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.fm(I)) must be referenced by the Ith PTW of the active
3380          segment's Page Table (ptwa(I)).  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 ^= count(PTWs in its associated Page Table w/ ptw.df="1"b)
3433 
3434   - An ASTE that has:
3435      aste.csl ^= count(PTWs 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, size(aste) );
3504          pt_size = sst.pts( fixed(aste.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           based(sst.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., 0,5,5) 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 bin(35) 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) change(2023-04-28,GDixon), approve(2023-03-07,MCR10129a),
4694      audit(2023-04-29,Swenson), install(2023-04-29,MR12.8-1055):
4695       A) Initial version of this info segment.
4696       B) Add new hardcore_segs.gi.info block.
4697                                                    END HISTORY COMMENTS */