Trailing-Edge
-
PDP-10 Archives
-
QT020_T20_4.1_6.1_SWSKIT_851021
-
swskit-documentation/monitor-address-space.memos
There are 5 other files named monitor-address-space.memos in the archive. Click here to see a list.
MEMOS IN THIS FILE:
o More Address Space for the TOPS-20 Monitor (v4)
o Monitor PSECTs and BOOT Procedure (v4)
o Overlapping BGSTR to Build Monitors (v5)
o Write-Protecting the Resident Monitor (v5)
o Release 6 Address Space Project (v6, several parts)
o Hints on Moving Code to Extended Sections (XCDSEC) (6.1)
o Moving DECnet-36 Code to Extended Sections (6.1)
-------------------
---------------
|d|i|g|i|t|a|l| INTEROFFICE MEMORANDUM
---------------
TO: TOPS-20 Monitor Memo List DATE: 20-Aug-79
FROM: Mike Gilbert/David Bell
DEPT: Marlboro Support Group,
EXT: 231-5058 Software Services
LOC/MAIL STOP: MR1-2/S43
FILE: [DOC-SPECS]HIDSYM.RNO
PDM: JNG-78-001-01-S
SUBJ: More Address Space for the TOPS-20 Monitor
This spec was reviewed at the TOPS-20 monitor meeting of
11-Dec-78. This is the final version of the spec.
1.0 SUMMARY
This memo describes some changes to be made to the TOPS-20
monitor, BOOT, and DDT in order to reclaim about 80 (120 octal)
pages of virtual address space that is now used to hold the
monitor's symbol table. The strategy is to put the symbols into
an address space owned by the SPT, and then modify DDT and the
SNOOP% JSYS to be able to find them there.
2.0 MOTIVATION FOR CHANGE
THe TOPS-20 monitor is completely out of address space. This
means that release 4 in its current state cannot be built if all
of the committed functionality is installed. Extended addressing
cannot be used to solve the problem, since the 2020 does not
support extended addressing.
Given that something must be moved out of the monitor's
address space, the symbol table is the obvious (and perhaps the
only) choice. It is large (120604 octal words in 2102's monitor),
and references to it are isolated to DDT and the SNOOP% JSYS. It
is also not normally referenced when the system is running, so
making it harder to access will not degrade system performance at
customer sites.
More Address Space for the TOPS-20 Monitor Page 2
3.0 THE WAY IT WORKS NOW
In order to make the changes below easier to understand, the
following short description of the current address space layout
and build procedure has been included for contrast.
3.1 The Current Address Space Layout
After loading by LINK, the monitor's address space is laid
out as follows:
<----------RSCOD----------> INCOD<---------RSVAR----------><----
*********************************0000000000000000000000000000000
<1>
--------------(free)--------------> 2<NRVAR><-------------------
00000000000000000000000000000000000000000000********************
-----------------------NRCOD------------------------><----------
*****************************************************00000000000
<-3->4<----
----NPVAR----><----(free)---><-----------JSVAR----------><PSVAR>
0000000000000000000000000000000000000000000000000000000000000000
-----------Symbol Table----------->
*: Non-zero code or data 0: Zero space (allocated only)
1. POSTLD 2. PPVAR 3. BGSTR 4. BGPTR
where areas above the line indicate code or data loaded into its
final resting place, and areas below the line have just been
temporarily loaded overlapping zeros while awaiting processing by
POSTLD.
After loading, the monitor is started at POSTLD, which takes
the following actions:
1. Moves the symbol table to after the RSVAR area.
2. Writes BUGSTRINGS.TXT, then appends the BGSTR and BGPTR areas
to the NRCOD area.
3. Deletes itself.
More Address Space for the TOPS-20 Monitor Page 3
After POSTLD is finished, the final layout as seen by the
running monitor is as follows:
<----------RSCOD----------> INCOD<---------RSVAR----------><----
*********************************00000000000000000000000000*****
-----------Symbol Table-----------> 1<NRVAR><-------------------
***********************************000000000********************
-----------------------NRCOD------------------------><----------
*****************************************************00000000000
----NPVAR----><----(free)---><-----------JSVAR----------><PSVAR>
0000000000000000000000000000000000000000000000000000000000000000
<--------BOOT Area------->
*: Non-zero code or data 0: Zero space (allocated only)
1. PPVAR
3.2 BOOT
When BOOT is initially run, it only reads in the first 340
pages of the above address space (through the end of the symbol
table plus some number of zero pages). That portion of the
monitor then starts up job 0, which calls BOOT back to read in the
rest of the monitor a piece at a time, swapping it out as it goes
to make room for the next piece.
Since BOOT must stay around in the monitor's virtual address
space until after all of the non-zero parts of the monitor have
been read in and job 0 has been running for a while, it must
overlap a zero area of the monitor that will not be used while all
this is happening. The only areas that meet this criterion are
the NRVAR area, the latter part of the NPVAR area (the first part
is the resident free pool and is used when PS: is mounted), and
any unused areas.
More Address Space for the TOPS-20 Monitor Page 4
BOOT has a hard-wired in origin, so the address chosen for
BOOT must always lie in one of the above areas in all monitors
built, no matter how much the PSECT origins are moved around by
developers desperate for address space. In practice, BOOT is
built to lie in the middle of the space formed by the end of the
NPVAR area and the unused region beyond it (marked "BOOT area" in
the above diagram), and the system works because the PSECT origins
are not generally moved far enough to make BOOT fall outside this
area, though it may move around inside it.
This system started failing when the directory was moved out
of the JSB for 2060 monitors, because the JSB shrunk significantly
and everything moved up a lot. The current state of the world is
that there are two versions of BOOT, a model A and a model B
version, which are identical except that they have different
origins to try and stay within the BOOT area.
Another constraint to worry about is that the NRCOD area must
start above 340000 or MTBOOT will not work. The problem is that
if the first part of the NRCOD area is read in initially by BOOT,
then the tape will already be positioned past the start of the
area, so that Job 0's attempt to read in the entire swappable
monitor will fail. This is frequently broken by accident, since
there are no ill effects to anything except MTBOOT.
3.3 Small Systems
For the system to be sucessfully booted on a 128K machine,
the symbol table must end by about 350000 in order for BOOT to be
able to read it in with the resident monitor, and still leave room
for BOOT itself and an area to read the swappable monitor into a
piece at a time. This is generally not a problem, because the
RSVAR area (which contains the CSTs, the SPT, etc.) is smaller on
a small system.
More Address Space for the TOPS-20 Monitor Page 5
4.0 THE PROPOSED CHANGES
This section describes in detail all of the changes proposed
to move the symbol table out of the monitor's address space, along
with an explanation where appropriate of why plausible alternate
implementations were rejected.
4.1 The New Address Space Layout
In order for the symbols to be available from monitor startup
time, they must reside in the MONITR.EXE file and be read in by
BOOT. Any scheme to put them into a different file would mean
that they would not be around until after all of the monitor's
disk mounting and other startup code had been executed, which
means that EDDT would have no symbols to debug that startup code
with. Having two files also promotes version skew.
To put the symbols into the EXE file without overwriting code
or data, an all-zero area big enough to hold them must be found or
created. This area must also be right after the RSVAR area, so
the symbols will be read in by BOOT with the resident monitor.
The RSVAR area itself cannot be used, because it is used by the
monitor very early in system startup.
Given this, the only way to generate a zero area big enough
to hold the symbols is to concatenate the NPVAR area with the JSB,
and move them both to somewhere below 340000. These are the two
largest zero areas, and the symbol table is so large that the only
way to get enough room is to use both of them.
More Address Space for the TOPS-20 Monitor Page 6
The new address space layout looks like this:
<----------RSCOD----------> INCOD<---------RSVAR----------> 1<--
*********************************0000000000000000000000000000000
<--
-2-><----------JSVAR-----------><---------NPVAR---------><------
000000000000000000000000000000000000000000000000000000000*******
----------Symbol Table--------------->
----------------------------NRCOD-------------------------------
****************************************************************
-><-3->4<-------------------(free)----------------------><NRVAR>
********00000000000000000000000000000000000000000000000000000000
< BOOT>
*: Non-zero code or data 0: Zero space (allocated only)
1. PPVAR 2. PSVAR 3. BGSTR 4. BGPTR
Note that this is the layout after LINK is finished loading and
also what the monitor will see; POSTLD will no longer do any
reorganizing after loading. The area marked "(free)" is that
freed up by getting rid of the symbol table, and can be parceled
out as needed to the other PSECTs by adjusting the LINK command
file.
4.2 BOOT
Since most of the zero space in the monitor is now used to
hold the symbols in the EXE file, the monitor can no longer afford
to allocate a large zero area for BOOT and hope that it will
overlap properly. However, overlapping BOOT with a smaller zero
area means that the monitor and BOOT must agree exactly where BOOT
will fit, and no shuffling of the adjacent PSECT boundaries can be
allowed.
The solution to this problem is to move BOOT to the very end
of the monitor's virtual address space, and overlap it with the
NRVAR area, which is just about the same size as BOOT. Putting
BOOT and the NRVAR area at the end of memory means that the only
PSECT boundary moving that will ever be needed will be moving the
start of the NRVAR area down if it grows larger, which will not
hurt BOOT. It also means that the model A and model B versions of
BOOT can be recombined.
More Address Space for the TOPS-20 Monitor Page 7
The other change to BOOT is to move its default highest
address to read in from 340000 to the last address in the symbol
table, as calculated by looking at .JBSYM. This will allow the
growth of the CSTs etc. on large systems to push the end of the
symbol table above 340000 without harm, and will also allow the
bottom of the NRCOD area to drop below 340000 if needed without
breaking MTBOOT.
4.3 EDDT
When the monitor has been loaded by BOOT but not started, the
symbols will be in the monitor's virtual address space and EDDT
can access them as it does now. However, once the monitor has set
up MMAP and turned on paging, the symbols will vanish from the
virtual address space (although they will still be in physical
memory), so EDDT must know how to find them in physical memory.
In order to tell EDDT where the symbols are, the monitor will
set up an alternate MMAP that describes an alternate address space
containing only page 0, EDDT, the symbols, and the hardware paging
tables (SPT etc.). When EDDT wants to search the symbol table, it
will first change KIEPT to switch to the alternate address space.
When it wants to do almost anything else, it will first change
KIEPT to return to the monitor's address space.
The changing KIEPT was selected rather than a
"length,,address" or list of pages scheme because it is simple to
implement inside EDDT. This mechanism is also fairly independent
of the type of paging enabled, so TOPS-10 7.01 can use the same
EDDT to get more address space in their monitor.
In order to pass the necessary parameters to EDDT, we are
going to define location .JBEDV=112 ("Exec Data Vector") to point
to a block of data for communication with the monitor. This is
one of only three locations left that are still unused in page 0
of both the TOPS-10 and TOPS-20 monitors, and using a common
location cuts back somewhat on the wild proliferation of
conditionals inside DDT. For the format of the block itself, see
its definition in MONSYM and STG.
More Address Space for the TOPS-20 Monitor Page 8
4.4 MDDT
When MDDT wants to access the symbol table, we propose to
have it map a few pages of the symbol table at a time through a
window in the JSB. Doing this will also have the pleasant side
effect of forcing a centralization and cleanup of DDT's internal
symbol processing code.
Instead of having MDDT call MSETMP directly or inventing a
new MRPAC-style JSYS, we are going to define a new monitor
subroutine called .IMOPR (Internal Monitor OPeRation) that MDDT
can call whenever it needs the monitor to do something. We chose
a well-defined monitor subroutine because it is much faster than a
JSYS (symbol searching is already slow enough!), and the standard
interface keeps MDDT from breaking every time the calling sequence
to an internal subroutine like MSETMP changes. We also want the
interface to be standard enough so that an MDDT on TOPS-10 could
perform the same functions by calling an .IMOPR entry point
defined inside the TOPS-10 monitor.
The format of a call to .IMOPR is fairly simple, so it is not
explicitly described here. The eventual intent is to have MRPAC,
SWPMWE/SWPMWP, and anything else that MDDT may need from the
monitor available as functions to .IMOPR, but the only functions
currently planned are allocate JSB window and map symbols. The
interested reader is referred to the listings for more
information.
4.5 The SNOOP% JSYS
The SNOOP% JSYS will be made to do symbol windowing through
the JSB just like MDDT, using the .IMOPR functions mentioned
above.
4.6 LCKINI/ULKINI
These subroutines are called from the monitor and by WHEELs
from MDDT to lock or unlock EDDT (the INCOD PSECT) and the symbol
table. They will be made smart enough to lock and unlock the
symbol table.
4.7 JSB/PSB Assumptions
If the JSB and PSB are moved from the end of memory, some
assumptions in the monitor will no longer be valid and will have
to be fixed. So far, we have only been able to find four such
assumptions (all in PAGEM), but there may be more.
More Address Space for the TOPS-20 Monitor Page 9
4.8 POSTLD
After this project is finished, all that will be left for
POSTLD to do will be to write the BUGSTRINGS.TXT file. A possible
future one plus would be to write a utility that would read a
MONITR.EXE and produce a BUGSTRINGS.TXT. POSTLD could then be
deleted entirely, which would simplify the monitor build process
and control files.
4.9 PSECT Boundary Symbols
While working on this project, we frequently found it
necessary to range check addresses or page numbers against PSECT
boundaries. This is currently difficult, because PSECT boundary
symbol names are inconsistent or missing. We would like to define
a consistent set of symbols as follows (assume xxxxx is the name
of a PSECT):
xxxxxP The first page of the PSECT
xxxxx The first address of the PSECT (xxxxxP*1000)
xxxxxL The last page of the PSECT
xxxxxZ The last address of the PSECT (xxxxxL*1000+777)
5.0 GENERAL INFORMATION
5.1 Feature Tests
This project will define a feature test called HIDSYM in
PARAMS. If the feature test is on, then the hidden symbol
processing described in section 4 will occur. If it is turned
off, then the symbols will live in the monitor's virtual address
space between the PPVAR and PSVAR areas, and EDDT, MDDT and SNOOP%
will all access the symbols directly, as they always have.
Another feature test called BUGSTF will be cleaned up and
moved from POSTLD to PARAMS. This feature test controls whether
or not the bug strings are kept in the monitor address space, so
they will be available for typeout when BUGCHKs or BUGINFs occur.
The feature test will be turned on because it provides a useful
facility and only takes 10 pages of monitor virtual address space,
but it can be turned back off in the future if those 10 pages are
needed.
More Address Space for the TOPS-20 Monitor Page 10
5.2 Monitor Data Locations
The following locations are of interest to monitor
programmers:
HIDSYF Non-zero if HIDSYM was turned on; the monitor
has or intends to hide the symbols.
HSYPAG Less than zero if the symbols are in the
monitor's virtual address space (they have not
yet been hidden or are not going to be). If
positive, .JBSYM points into an alternate
address space, not the monitor's. This is the
word that EDDT looks at.
SYMBAS The SPT index of the alternate MMAP that
describes the symbol address space.
DDTPRS Non-zero if EDDT and the symbols are locked in
memory. If zero, they are swappable, so EDDT
cannot be used until LCKINI is called to lock
them.
BUGTP Non-zero if the bug strings are present (in
which case it points to them).
6.0 IMPLEMENTATION
This project will be implemented in the following discrete
steps. The completion of each step should result in a runnable
monitor, which can be brought up and checked out before
proceeding.
1. Put up the new MDDT for general use by the monitor group.
2. Put up the new EDDT for general use by the monitor group.
3. Put in the feature tests (turned off), and the monitor code.
4. Re-arrange the PSECTs, and fix POSTLD and BOOT. Note that
this BOOT will not bring up an old monitor, nor will an old
BOOT bring up this monitor.
5. Turn on the feature tests. The extra address space should
appear at this point.
The actual implementation schedule will depend on how the review
of this spec and the merging of code go.
[End of Monitor Address Space Spec]
---------------
|d|i|g|i|t|a|l| INTEROFFICE MEMORANDUM
---------------
TO: Folklore DATE: 20-Aug-79
FROM: Mike Gilbert
DEPT: Marlboro Support Group,
EXT: 231-5058 Software Services
LOC/MAIL STOP: MR1-2/S43
SUBJ: Monitor Psects and Boot Procedure
This memo collects in one place a bunch of random facts about
the TOPS-20 monitor address space layout, which Psects are where
and why, and how this all relates to the monitor's boot procedure.
For some additional information on this topic, see
[DOC-SPECS]HIDSYM.MEM. Be warned that parts of that file are
obsolete.
1.0 LIST OF PSECTS
The following is a list of all of the TOPS-20 monitor's
psects, along with a description of each one. Note that each
psect whose name ends in VAR is all zero, and is not filled in
until the monitor starts running.
1. Page 0 (and 1 on 2020s) - Not really a psect, these pages are
loaded with LOC statements, and are full of miscellaneous
communication areas, flags, etc.
2. RSCOD (Resident code) - This psect contains the code and data
that can never be swapped out. This psect is hard-wired into
the monitor as the first one, and the location MONCOR contains
the last page number in it.
3. INCOD (Initialization code) - This psect contains some
routines used only during monitor initialization (including
the 143$G dialog). It also contains Exec DDT. This psect is
locked when the monitor is started, but gets unlocked at
GETSWM unless EDDT is needed.
4. PPVAR (Per-processor variables) - This psect doesn't contain
anything. It is used to reserve a few slots in MMAP for use
in setting up temporary mappings to memory pages. APRSRV uses
Page 2
these map slots to recover from parity errors, for example.
5. RSVAR (Resident variables) - This psect contains the monitor's
variables that must always remain resident, including the EPT,
MMAP, and the CSTs.
6. SYVAR (Symbol variables) - This psect contains everything that
(like the symbols) should appear only in EDDT's alternate
address space, and not in the monitor's normal address space.
The symbols get appended to this psect early in the monitor's
initialization, and then both the symbols and the psect get
"hidden". This psect is of zero size if the HIDSYM
conditional is not set.
7. PSVAR (PSB variables) - This psect contains the PSB.
8. JSVAR (JSB variables) - This psect contains the JSB.
9. NRVAR (Non-resident variables) - This psect contains monitor
data locations that can be swapped.
10. NRCOD (Non-resident code) - This psect contains the monitor
code that can be swapped, including the processing routines
for all the JSYSes. This psect is usually write-locked.
11. BGSTR (Bugstrings) - This psect contains ASCIZ strings that
describe each BUGINF, BUGCHK, and BUGHLT. Like NRCOD, this
psect is swappable and write-locked.
12. BGPTR (Bugpointers) - This psect contains a few words for each
BUGxxx, including the addtional arguments and pointer to the
corresponding Bugstring. This psect is also swappable and
write-locked.
13. NPVAR (Non-resident page variables) - This psect contains
monitor variables that are allocated a page at a time and that
can be swapped. One of the main things in this psect is the
resident free pool (RESFRP), whose pages get locked in memory
one at a time as they are allocated.
2.0 BOOT
BOOT is read in by the front end at some random physical
address (currently on top of the RSCOD psect) and started. The
first thing it does is find the highest 20 pages in section 0 of
physical memory, and move itself there. It then sets up a mapping
that is straight physical to virtual, except that it always maps
itself at the end of virtual memory (pages 760000 and beyond).
After the above initialization, BOOT reads the monitor in
around itself in virtual memory. Since BOOT needs to remain
mapped and functioning until the swappable monitor has been read
Page 3
in and started, it must not lie in any part of the monitor's
virtual address space that will be used by the monitor's
initialization code, including the memory mapping code, the device
mounting and checkout code, the scheduler, etc.
The only three areas that satisfy the requirements are a gap
between psects, the NRVAR psect, or the last part of the NPVAR
psect (the first part of the NPVAR psect contains the resident
free pool, which is used by the disk mounting code and by the
swapper). BOOT currently overlaps the end of the NPVAR psect,
which is the last psect in the monitor.
3.0 WHY THE PSECTS ARE WHERE THEY ARE
In addition to the problem with BOOT mentioned above, there
are several rules that must be followed when re-arranging the
psects, as follows:
1. RSCOD must be first. Checks to see if an address lies in
RSCOD are just CAMLE MONCOR, which won't work if any psect
falls below RSCOD.
2. All of the psects in the part of the monitor that is started
first and that reads in the swappable monitor must be first.
In addition, the last thing in that part of the monitor must
be the symbol table. This includes the RSCOD, INCOD, PPVAR,
RSVAR, and SYVAR psects. The code in these psects must work
before any swapping or paging is going on, so they must all be
low enough to fit in physical memory on the smallest
configuration supported. In addition, BOOT stops reading in
the resident monitor when it hits the end of the symbol table,
so the symbol table must be the last thing in this group of
psects.
3. The group of non-zero psects that swap are treated as a unit
by certain parts of the monitor, and should therefore be
together. These psects are NRCOD, BGSTR, and BGPTR.
4. PSVAR, JSVAR, POSTCD, NRVAR, and NPVAR can generally be put
anywhere. They have been moved in the past with good success.
4.0 WHAT PSECTS CAN OVERLAP
The POSTCD psect can overlap any xxVAR psect, since it will
be gone by the time MONITR.EXE is generated. The psect is
currently allocated its own three pages to avoid psect overlap
warnings from LINK (a cosmetic precaution only).
Page 4
If HIDSYF is set and hidden symbol processing is being done,
then the SYVAR psect and the symbol table can overlap any other
xxVAR psects. The SYVAR psect is currently allocated its own page
to avoid psect overlap warning messages from LINK.
If BUGSTF is not set and the bugstrings and bugpointers are
not present in the running monitor, then the BGSTR and BGPTR
psects can overlap any xxVAR psect. In the current monitor, they
would probably be overlapped with the NPVAR psect, which
immediately follows them.
No other psect overlaps can be allowed without breaking the
monitor.
5.0 HOW TO CONTROL THE SYMBOL TABLE ORIGIN
The psect origins of all the real psects are controlled by
/SET switches in the LINK .CCL file. The symbol table, however,
must be controlled in a more indirect way, via the LINK switches
/SYMSEG and /UPTO.
The /SYMSEG:PSECT:name switch directs LINK to append the
symbol table to the named psect. If symbols are hidden, then then
symbols should be appended to INCOD. If not, then they should be
appended to SYVAR. The symbols will not normally start until 200
words after the end of the preceeding psect. The extra 200 words
are the PAT.. area.
The /UPTO:address switch tells LINK the highest legal address
for the symbol table. If there are enough symbols to make the
symbol table attempt to exceed the specified address, then LINK
will output a warning message and truncate the symbol table. The
resulting monitor should still run if this occurs. The address
should be set to one less than the base of the first psect that
the symbol table cannot overlap.
6.0 THE MONITOR BOOT PROCEDURE
The following is a step by step description of the memory
management going on when the monitor first comes up. Those steps
marked with an asterisk (*) are not applicable unless hidden
symbol processing is going on.
1. BOOT reads in the portion of the monitor up through the end of
the symbol table, then starts the monitor.
2. * STG moves the symbol table up to immediately following the
SYVAR psect in physical memory. It does this to free up the
RSVAR and PPVAR psects so that MMAP and the CSTs can be set up
to turn on paging. After the symbol table is moved, it lives
in physical memory overlapping part of where the non-resident
Page 5
code (NRCOD) will go in virtual memory.
3. PGRINI in PAGEM sets up KIEPT, MMAP, the CSTs, and the
replacable queue.
4. * PGRINI sets up SYMMAP to point to an alternate address space
containing EDDT, the symbols, and parts of the monitor. EDDT
and the symbols live at the same addresses in this virtual
address space as they do in physical memory. The symbols will
not appear in the monitor's main address space at all.
5. PGRINI turns on paging. If the symbols are being hidden, the
symbols become inaccessible to the monitor at that point.
6. The resident monitor (MEXEC) calls BOOT with a JSP repeatedly
to read in the swappable monitor a piece at a time. The
pieces are mapped at their correct home in virtual memory as
they are read in, but they are put in any free physical pages
available, including gaps between resident psects. If there
are not enough free physical pages to hold the swappable
monitor, then some of it is paged out to make room for
incoming new parts being read in by BOOT.
7. BOOT is deleted, and the monitor unlocks INCOD, then starts
SYSJOB and PTYCON, and finishes coming up.
A possible memory map at various stages of monitor
initialization is as follows (assume a 128K system and hidden
symbol processing):
Physical Monitor VAS Symbol VAS
Just before the monitor is started:
RSCOD RSCOD
INCOD INCOD
Symbols Symbols
... ...
128K BOOT ...
...
256K BOOT
Just after paging is turned on:
RSCOD RSCOD RSCOD
INCOD INCOD INCOD
PPVAR PPVAR
RSVAR RSVAR RSVAR
SYVAR SYVAR
Symbols PSVAR Symbols
| JSVAR |
128K v NRVAR v
...
...
Page 6
256K BOOT
After the swappable monitor has been read in:
RSCOD RSCOD RSCOD
INCOD INCOD INCOD
PPVAR PPVAR
RSVAR RSVAR RSVAR
SYVAR SYVAR
Symbols PSVAR Symbols
| JSVAR |
| NRVAR |
| NRCOD |
v NRCOD v
NRCOD (pieces, NRCOD
NRCOD mostly NRCOD
NRCOD swapped) NRCOD
128K BOOT NRCOD
...
NRCOD
NRCOD
256K BOOT
[End of MONPSC.MEM]
+---------------+
! d i g i t a l ! I N T E R O F F I C E M E M O R A N D U M
+---------------+
TO: S. Hemphill
P. Mierswa DATE: 21-Aug-79
B. Teegarden
B. Tomczak FROM: Clair Grant
G. Zima
DEPT: LCG Software
Engineering
LOC: MR1-2/E37
EXT: 6036
SUBJ: Overlapping BGSTR to Build Monitors
Some TOPS-20 systems are encountering problems when
attempting to build their monitor because they are running
out of address space. Sites that add monitor code of their
own and sites that simply increase configuration parameters
have both been faced with this situation.
The following discussion refers to the monitor at Ford
Motor but the solution may be applied to any situation in
which there is a need to redefine the PSECT boundaries and
acquire a few more pages of address space. This is by no
means the first time this has been done but the need to know
how to do it seems to be increasing rapidly.
Ford simply wanted to increase their swapping space to
10,000 pages. They made the appropriate change in PARAM0
and submitted TOPS20.CTL. The build failed because LINK
couldn't fit everything in 256K; also, they got some PSECT
overlaps.
The cause of their problem was that in order to
accommodate the larger swapping size the RSVAR PSECT
requires considerably more space and a couple other PSECTs
need a page or two more. Unfortunately, there is not enough
spare address space to simply redefine the PSECT boundaries
and have everything fit. Something must be eliminated
(actually, intentionally overlapped). The BGSTR and BGPTR
PSECTs were seen as candidates for elimination. So, making
believe BGSTR and BGPTR were still to be included, the
entire set of PSECT boundaries were redefined to so that the
ones which required more space were satisfied. Then the
very last PSECT in the address space NRVAR was given the
same boundary as BGSTR. You end up with something which
looks like:
Page 2
BGSTR 732000
BGPTR 743000
POSTCD 745000
NRVAR 732000 ;NPVAR if you already have Gilbert's
rearrangement
You must also set the contents of BUGSTF to 0 in STG.
This still causes LINK to find 3 PSECT overlap errors
but they are to be expected. The consequence of BGSTR being
eliminated is that when the system gets a BUGxxx the
descriptive string will not be available. Note, however,
that BUGSTRINGS.TXT still gets written.
+---------------+
! d i g i t a l ! I N T E R O F F I C E M E M O R A N D U M
+---------------+
TO: TOPS-20 Group
TOPS-20 Support Group
DATE: July 30, 1980
FROM: Judy Hall
DEPT: DEC-20 S. E. Dept.
LOC: MR 1-2/E37
EXT: 6421
SUBJ: Write-protecting the Resident Monitor
Recently I changed the monitor so that resident code could be
write-protected. This document provides some information on
what I did and some folklore that I picked up in the process.
NOTE: The intended audience for this document is monitor
programmers and supporters. My work does not affect users or
user documentation. Extensive knowledge of the monitor is
assumed.
1.0 THE OBJECTIVE
The purpose of this project was to allow the monitor to run in
a mode in which all resident code was write-protected. The
swappable code has long been write-protected, and we have from
time to time detected bugs because of it. We have also tracked
very obscure crashes to resident code that had been modified
unintentionally.
2.0 THE PIECES
2.1. Allowing writable, permanent resident data
The resident monitor consists of several PSECT's, including
RSVAR (resident variables) and RSCOD (resident code).
Locations are created in RSVAR through the RS macro. However,
in the past people have sometimes defined resident data via the
BLOCK pseudo-op, causing the locations to appear in RSCOD. One
of the reasons for this is that the RSVAR area is zeroed by the
monitor when it is coming up. Therefore, if a location was to
be given an initial value before monitor startup, and if it had
to be resident, the location was added to the resident code.
Lots of other locations were created this way simply out of
habit.
I have created a new PSECT, RSDAT. It is resident and
Page 2
write-enabled, and it is not zeroed as the monitor comes up.
Locations are placed in this PSECT via the RSI macro, which is
invoked as follows:
RSI NAME,LIST,TOTAL
where
NAME is the symbol associated with the first (or only) location
to be reserved
LIST is one or more values, to be placed in successive words
beginning with the first
TOTAL is the number of words to be reserved. If it is not
specified, the number of words included in the list is
allocated.
If more values are provided in LIST than are accounted for in
TOTAL, an assembly error is generated.
I have also begun the process of converting definitions of
resident data (including FFF) to use this macro. There are
many statements of the form
A: BLOCK n
and
B: C
within the RSCOD PSECT. As long as the monitor never stores
into these locations, it is not necessary to change the
definitions. However, in the future, all resident data that is
write-enabled should be placed either in the RSVAR PSECT via
the RS macro (if the location should be zeroed at system
startup) or in the RSDAT PSECT via the RSI macro (if the
location should not be zeroed).
Another common offender was JSR's. The typical sequence
occurred in APRSRV:
BUGMON: 0
code
.
.
.
Code to enter this routine would contain
JSR BUGMON
which stored into this resident location. Such locations are
now two-word blocks defined in STG to be in the RSDAT PSECT.
The second word transfers control to the original code. Thus
for BUGMON, we see
BUGMON: 0
JRST BUGM0
Page 3
and in APRSRV, the code that was executed now has the label
BUGM0.
2.2 Write-protecting the code
Write-protecting the resident monitor occurs in two stages. In
PGRINI, when the monitor's map is being established, RSCOD is
write-protected if DBUGSW is 0 or 1. Later, when the swappable
monitor has been read in, MEXEC calls SWPMWP if DBUGSW is 0 or
1.
SWPMWP/SWPMWE has been enhanced to write-protect or
write-enable the resident monitor in addition to the swappable
monitor. It seemed natural for the two pieces of code to be in
the same state. The name of the routine is unchanged purely
because of history. Everyone knows the names, and we often
call these routines by hand while the monitor is running.
2.3. Dealing with DDT
Originally I changed the BUGHLT code to avoid executing HLTADR
(where EDDT's breakpoint 12 is normally defined) if the monitor
was write-protected. I did this for two reasons: 1) I assumed
that the JSR would try to store into the resident monitor, and
2) I assumed that EDDT's attempt to replace all resident
instructions on which there were breakpoints would fail.
I found that the first assumption is incorrect; EDDT is in the
INCOD PSECT, which is write-enabled. Therefore executing
HLTADR will indeed get the monitor into EDDT. However, any
attempt to proceed the breakpoint seems to cause it to be
reexecuted. Obviously DDT can't replace the JSR at HLTADR, but
I had assumed it would simulate the original instruction.
This led me to try the same thing with the swappable monitor,
since that has been write-protected for years. I
write-enabled, set an EDDT breakpoint, write-protected, and hit
the breakpoint. Again I could not proceed until I
write-enabled and replaced the JSR with the original
instruction.
The particular problem of BUGHLT's was solved as follows: the
location on which the breakpoint is placed looks like this:
HLTAD0::XCT HLTADR
HLTADR is a location in RSDAT containing a NOP instruction.
Thus DDT can proceed the breakpoint by restoring the NOP.
BUGCHK's and BUGINF's are handled similarly.
Note, however, that breakpoints in write-protected code will
still exhibit the behavior I described.
2.4. Teletype data base changes
Page 4
As part of the reorganization of the teletype data base in
Release 3, transfer vectors were created for each line type.
An offset (TT1LIN) in each vector contained data, which was
initialized during system startup. I have changed this so that
a resident table, called TT1LIN, is indexed by line type. It
resides in the RSDAT PSECT and contains the data formerly
stored into the transfer vector.
2.5 Expanding FFF
I moved the definition of FFF into POSTLD and increased it to
400 words. Moving it to POSTLD should cause it to be the last
location in RSDAT. Thus the patch space will be even larger
than 400 words if there is room left on the page in which RSDAT
ends. (Currently RSDAT is only one page long.) The increase to
400 words was requested by Doug Ruby so that customers can have
room to apply all the patches that we send them.
2.6 Cleaning up System Startup
The code in STG near SYSGO1 contains a BLT that zeroes all of
the RSVAR PSECT. It then assigns initial values to those
locations in RSVAR whose initial values are non-zero. I have
moved most of these locations into RSDAT, assigning the initial
values at assembly time. Thus STG no longer initializes them.
3.0 FOLKLORE LEARNED THE HARD WAY
3.1. Adding a PSECT
Adding a PSECT proved to be non-trivial at best. I came upon a
lot of "unwritten rules". This section is an attempt to record
some of them.
3.1.1. Guiding LINK
The LINK control file (LNKMON.CCL, for example) had to contain
the new PSECT. Its placement was guided by the following
considerations:
1. RSCOD must be first. The monitor assumes this, and
it assumes that MONCOR contains the highest location in
the RSCOD PSECT.
2. PSECTS ending in "VAR" are assumed to be zeroed at
system startup, and the symbol table is linked on top
of them. Thus RSDAT had to precede the first zeroed
PSECT (PPVAR).
Since RSDAT preceded the symbol table, the /SYMSEG switch had
to point to the end of this PSECT. And since the patch space
precedes the symbol table, the /PATCHSIZE switch was added to
the same line. Of course, the starting locations of the PSECTS
also had to be changed to accommodate RSDAT.
Page 5
3.1.2. Creating a PSECT name
Each PSECT has associated with it several names
(XXXXX,XXXXXP,XXXXXL, XXXXXZ). The first two are generated by
the addition of the PSECT name to LDINIT (the PBEGIN macro).
The last two are generated by the addition of the PSECT name to
POSTLD (the PEND macro). And of course these names all have to
go into GLOBS.
3.1.3. Getting the PSECT saved
It's not enough to persuade LINK to link a new PSECT; you must
also convince POSTLD to save it when it creates the monitor
file (MONITR.EXE). This is done via the SSEG macro.
3.1.4. Getting the PSECT reported
When you "RUN MON", POSTLD generates a table describing the
monitor map. A series of invocations of the PRPSC provides the
necessary data. For each PSECT, the arguments are that PSECT
and the one that follows. Therefore, adding a PSECT requires
both the addition of an invocation of the macro and changes to
existing invocations.
3.1.5. Fixing monitor startup
This varies from case to case, and getting it wrong can have
confusing effects. For RSDAT there were three parts:
1. Getting it into MMAP - This required a call to
PGRIGR, which causes the pages to be added to MMAP and
write-enabled. A new entry point, PGRIGP, would cause
them to be write-protected.
2. Getting it locked in memory - This required a call
to BSMGP, providing the starting and ending addresses
of the PSECT. By convention, PSECTS for which this is
done have a cell defined in PAGEM that contains these
values.
3. Getting it into DDT's map - MDDT and EDDT use an
alternate map, which is pointed to by SYMBAS. Because
DDT uses locations in RSDAT, this PSECT had to be added
to DDT's map. This required storing some additional
indirect pointers in DDT's map (in PGRINI).
3.2. Patch space
PAT.., the default patch space when you type $< to DDT, is
placed by LINK in the last n locations before the symbol table.
For years, PAT.. coincided with SWPF, but the reorganization
of the monitor's address space in Release 4 caused it to be
part of the INCOD PSECT. In fact, it could wind up anywhere,
depending on the placement of the symbol table during LINK
time. (This is controlled by the /SYMSEG switch in the LINK
Page 6
control file.)
Since we have both FFF and SWPF, I thought there was no need
for PAT.. at all. The /PATCHSIZE switch in LINK establishes
the size of this space. I set it to 1. That's when I
discovered that DDT uses this space if you define a new symbol.
So we're back to a patchsize of 100.
3.3. The meaning of DBUGSW
In the course of this project I found myself trying to recall
the distinction among the three possible values of DBUGSW.
Following is a list of the modules, a label or routine name,
and a brief description of each reference to DBUGSW.
DBUGSW -
APRSRV
BUGH0 - IF DBUGSW IS 0, DON'T EXECUTE HLTADR, WHERE THE
BP IS. EVEN IF DBUGSW IS NON-ZERO, DON'T
EXECUTE HLTADR IF DDTPRS IS 0 (DDT ISN'T
LOCKED).
DSKALC
FSIINI - IF DBUGSW IS 2, ALLOW USER TO CHOOSE TO
REWRITE THE HOME BLOCKS
DTESRV
TAKACK - IF DBUGSW IS 2, WAKE UP FORK 0 TO ACK ALL
DEVICES (?)
DTEPOL - IF DBUGSW IS 2, DON'T SET THE SYSTEM DATE AND
TIME (?)
IMPPHY
AN2CMD - IF DBUGSW IS NON-ZERO, SAVE HISTORY OF
COMMANDS IN A RING BUFFER
MEXEC
SYSINP - BEFORE STARTING THE EXEC, PRINT [CAUTION
--SYSTEM IS STAND-ALONE] IF DBUGSW IS 2
RUNDD - IF DBUGSW IS 0 OR 1, PRINT "SYSTEM RESTARTING,
WAIT". IF DBUGSW IS 2, SKIP RUNNING CHECKD.
IF DBUGSW IS 2, PRINT [SYSTEM IS STAND-ALONE]
ON ALL TERMINALS.
LOKSM3 - IF DBUGSW IS 0 OR 1, CALL SWPMWP TO
WRITE-PROTECT THE MONITOR
Page 7
NETWRK
NETINI - IF DBUGSW IS 2, DON'T TURN ON THE NETWORK
SCHED
SWHLT - IF DBUGSW IS NON-ZERO OR DCHKSW IS NON-ZERO,
EXECUTE CHKADR IN ORDER TO HIT A BREAKPOINT
(BUT DON'T DO THIS IF DDTPRS IS 0)
PAGEM
PGRINI - IF DBUGSW IS 0 OR 1, INITIALIZE RESIDENT CODE
TO BE WRITE-PROTECTED. IF 2, WRITE-ENABLE IT.
In addition, SYSJOB decides what command file to read according
to DBUGSW. It treats 0 and 1 as representing normal
time-sharing.
It seems to come down to the following:
A. 0 is the standard value for running a time-sharing system.
With it, the monitor is write-protected, and a BUGHLT causes
the monitor to halt and be reloaded.
B. 1 is just like 0, with one exception. When a BUGHLT
occurs, the monitor executes HLTADR, on which there is a
breakpoint. This allows a monitor wizard to look at the
problem, gather information, and possibly get around the
problem, avoiding a reload. (Note that EDDT must be in memory;
thus if DBUGSW is 1, EDDTF should be 1 also.)
C. 2 is the standard value for debugging. The monitor is
write-enabled, and BUGHLT's execute the HLTADR breakpoint.
4.0 CONCLUSIONS
When adding resident data, you now have a choice of three
PSECT's:
RSVAR -- Write-enabled
Zeroed at system startup
RSDAT -- Write-enabled
Not zeroed at system startup
RSCOD -- Write-protected
Not zeroed at system startup
[End of WRITE-PROTECT.MEM]
+---------------+
! d i g i t a l ! I N T E R O F F I C E M E M O R A N D U M
+---------------+
TO:
DATE: 16-Oct-83
FROM: Clair Grant
DEPT: LCG Software
Engineering
LOC: MRO1-2/L10
EXT: 6877
SUBJ: Movement of CST and DECnet Node Counters in Release 6.0
1.0 CST MOVE
In TOPS-20 Release 6.0 the Core Status Tables (CSTs), except for CST5,
are no longer assembled in the section 0/1 address space. Also, the
symbol CSTS no longer exists.
The CSTs are built for MAXCOR and are temporarily located just beyond
the symbols (in the physical address space) during system startup.
Their pages are locked in memory at this time. A temporary mapping in
the virtual address space is also made for code which references the
CSTs. The variable CSTVA is the location of the temporary virtual
mapping and is computed early durirng startup.
After paging is on and the monitor sections initialized, the CSTs are
moved to TABSEC by BLTing the appropriate piece of the section 0/1
page map to the section 7 page map; the CSTs are located in the
virtual address space just beyond the DSTs. Also, MAXCOR is compared
to NHIPG and if there is less physical memory than the monitor was
built to support, the pages of the CSTs which will never be used are
released from physical memory. The location CSTLOC contains the
beginning of CST0.
For the MONMAX monitor the CSTs used to occupy 44 pages in the virtual
address space. Those pages are now available for other purposes.
2.0 DECNET NODE COUNTERS
For R6.0 the DECnet Phase III node counters were changed from
PC-section variables to extended section variables; some are resident
and some are non-resident. The code in NSPSRV and NTMAN was modified
Page 2
to use the new EP. macro and the storage is now defined with the new
NRE and RSE macros.
NRE NSSSLZ,BIGNOD+1 ;NSP - "SECONDS SINCE LAST ZEROED"
RSE NSBYTR,BIGNOD+1 ;NSP - "BYTES RECEIVED"
RSE NSBYTS,BIGNOD+1 ;NSP - "BYTES SENT"
RSE NSMSGR,BIGNOD+1 ;NSP - "MESSAGES RECEIVED"
RSE NSMSGS,BIGNOD+1 ;NSP - "MESSAGES SENT"
NRE NSCONR,BIGNOD+1 ;NSP - "CONNECTS RECEIVED"
NRE NSCONS,BIGNOD+1 ;NSP - "CONNECTS SENT"
NRE NSTIMO,BIGNOD+1 ;NSP - "TIMEOUTS"
NRE NSRCNE,BIGNOD+1 ;NSP - "CONNECT RESOURCE ERRORS"
RSE NSALNK,BIGNOD+1 ;NSP - "ACTIVE LINKS"
There were no changes in the code logic; only changes to use EP.
were required.
+---------------+
! d i g i t a l ! I N T E R O F F I C E M E M O R A N D U M
+---------------+
TO:
CC:
DATE: October 16, 1983
FROM: Judy Hall
DEPT: DEC-20 S. E. Dept.
LOC: MR 1-2/L10
DTN: 231-6421
SUBJ: The Address Space Project for Release 6
1.0 INTRODUCTION
This document describes the work being performed in Release 6
in order to make the monitor "fit" into its available virtual
address space. Unlike the CI projects, this project does not
provide new facilities to the user, nor does it involve the
creation of new modules. Rather, it consists primarily of
changes to existing code.
Because of this, the documentation is unusual. There is no
separate functional spec; where changes affect users (as in
the building of monitors), they are noted here. Also, where
existing algorithms or data structures have been modified,
emphasis is placed on describing the changes rather than the
entire module or data structure.
This is not a project plan. Other memos have described the
shortage of address space, the goals of the effort,
alternatives considered, etc. This is also not a status
report. The current state of the monitor can be determined by
building a maximum ARPA monitor with DECnet. This is strictly
a technical description of the changes made in an effort to
obtain enough address space to ship the required functions of
R6. If changes in the release necessitate more movement of
data, that movement will be done.
2.0 STRATEGY
When the monitor conversion to extended addressing was begun,
sections 0 and 1 (both code and data) were mapped together.
Little by little, code has been changed, and new code has been
written, to obey the rules for running in extended sections.
Such code was therefore able to reference data in any section,
and some data (the DST, directories, etc.) had been moved
before Release 6. All code continued to run in sections 0 or
To: Page 2
Subj: The Address Space Project for Release 6
1.
The following sections provide a brief description of the
changes made in R6. Because many people have contributed to
the coding effort, the details of each subproject are provided
in memos written by each programmer. The sections below point
to the relevant memos.
2.1. Movement of Data to Extended Sections
2.1.1 Static Data
Three new macros (RSE, NRE, and NRPE) allow the assignment of
extended addresses to resident and swappable data locations.
The related new PSECTs (ERVAR, ENVAR, and EPVAR) are assigned
to an extended section by statements in STG (or PARAMS).
EDEFST and EMSKST provide the extended equivalent of DEFSTR and
MSKSTR. [DLM]
The following list contains each data structure changed and a
reference to the memo describing it:
Fork tables [JH]
ARPA map page [DLM]
Program tables [DLM]
Class scheduler data [DLM]
RESBTB [DLM]
NSP network management counters [CG]
2.1.2 Dynamic Data
A new routine, ASGVAS, provides for dynamic allocation of space
in an extended section. This is used for creating a section
map for SCA. [DLM]
CST0, CST1, CST2, and CST3 have been moved to an extended
section. Space for these tables is allocated at system
startup. [CG]
Resident free space can be allocated from an extended section
if the caller requests it. [JH] The following list contains
each new user of extended free space and the memo describing
it:
Terminal data [JH]
Timer data [JH]
NSP data [CG]
In addition, new code written for SCA and CFS uses extended
section free space.
Swappable free space can also be allocated from an extended
section. ENQ/DEQ and IPCF use this. [GL]
To: Page 3
Subj: The Address Space Project for Release 6
2.1.3 Other Data
DDT's symbol table no longer lives in a separate map, but is
allocated in an extended section. [DLM]
The descriptions of BUGINFs, BUGCHKs, and BUGHLTs are moved
into an extended section at system startup. [DLM]
2.2 Movement of Code
We have taken a first step toward allowing code in sections
other than 0 and 1. More work is required, and may be delayed
behond the end of release 6.0.
DDT runs in its own section. [DLM]
2.3 Isolation of Section 0 Code
As more data has been moved out of the code sections, more code
has been converted to run in section 1. The style of some code
makes such conversion difficult, however.
Since code running in section 0 cannot reference data in
extended sections, we have needed to protect ourselves against
accidentally running in section 0. And since this case is not
readily detected, we have decided to remove code from the
section 0 map wherever possible. Thus R6 is the first release
in which sections 0 and 1 are mapped separately.
Resident code that can run in section 1 is allocated to the
RSCOD PSECT. It and all swappable code exist only in section
1. Resident code that must run in section 0 is allocated to
the SZCOD PSECT and mapped to both sections. This allows us to
call it from section 1, and to convert it gradually to run in
section 1.
Code running in section 0 calls code in section 1 via the XCALL
macro. This enters section 1 before making the call.
Therefore, code running in section 1 no longer requires an
EA.ENT. XJSP provides the extended equivalent of JSP.
[DLM] describes the new PSECTs and the separation of maps.
[JH] describes XCALL and XJSP.
3.0 EFFECTS
3.1 Configurations
Many data structures whose size varied according to the
configuration have now been moved to extended sections. Thus
we will no longer be able to squeeze some extra space by
reducing configurations. Each time we need more space, we will
have to move new data or code, and test the effects.
To: Page 4
Subj: The Address Space Project for Release 6
3.2 Performance
At a minimum, referencing data outside of the code section
requires an indexed or indirect reference. Worse, some changes
have led us to the use of OWGBPs. It seems likely, too, that
we have increased the frequency of pager conflicts. All of
these will have a negative effect on performance.
3.3 Changes to Monitor Build Procedures
Because of the limitations of LINK, the PSECTS that exist in
extended sections are created in a nonstandard way. This has
caused changes to the procedures for building monitors. [DLM]
4.0 EXTENSIBILITY
The facilities for moving data can be used in future releases
as tools both for creating new data and for moving existing
data. As code is converted to run in section 1, the separation
of the maps will make debugging easier.
5.0 REFERENCES
[DLM] Dan Murphy, Design Specification -- Release 6 Monitor
Address Space Work, September 9, 1983.
[JH] Judy Hall, My Part in the Address Space Project,
October 10, 1983.
[GL] Gene Leache, Movement of Swappable Free Space out of
Section Zero, September, 1983.
[CG] Clair Grant, Movement of CST and DECnet Node Counters
in Release 6.0, October 1983.
+---------------+
! d i g i t a l ! I N T E R O F F I C E M E M O R A N D U M
+---------------+
DATE: 9-Sept-1983
TO: TOPS20 Group
FROM: Dan Murphy
DEPT: LCG S.E.
DTN: 231-6DLM
LOC: MRO1-2/L10
FILE: ADR-SPC-DLM
SUBJ: DESIGN SPECIFICATION - RELEASE 6 MONITOR ADDRESS SPACE WORK
This document describes a portion of the work done in
Release 6 to increase the virtual address space available to
the monitor. For an overview of all such work and
references to other particular work, see [1].
Included herein are the following specific areas of
work:
1. New storage PSECTS (NRE, RSE, NRPE).
2. Conventions and facilities for extended data
structures (EDEFST, EMSKST).
3. Automatic computation of PSECT boundaries.
4. Static and dynamic assignment of monitor sections
(MSECN, ASGVAS).
5. Symbol table moved to extended section and
elimination of "hidden symbol table".
6. Move DDT (KDDT and MDDT) to extended section.
7. Move bugstrings and bugpointers to extended
section.
8. Separate maps for sections 0 and 1; allow code to
be in section 1 only or in both.
9. Provide for code in additional section(s).
10. Move existing data to extended section: Class
scheduler data; program name tables; map pages.
The functional objective of all of this work is to
accomodate the large amount of additional code and data
added to the monitor in this and future releases without
reducing the size or types of supported configurations. The
Page 2
work should not be visible to customers or users of the
system with the possible exception of performance
differences cause by greater use of inter-section
references, one-word global byte pointers, etc. This impact
could be significant in some cases, but testing and
measurement is necessary to determine what areas are
impacted and by how much. This testing is planned as part
of the overall performance testing to be done during during
load and field test.
This document particularly describes changes from
previous releases in the areas of storage assignment and
address space structure, and its intended audience includes
those who will work on the internals of the monitor or teach
them, and are familiar with the internals of Release 5/5.1.
1.0 NEW STORAGE PSECTS.
Heretofore, most static data areas have been declared
with the macros RS, NR, and NRP which create resident,
non-resident (swappable), and non-resident page-unit storage
respectively. To facilitate placing new or existing data
areas in extended sections, a parallel set of macros is
defined, and new PSECTS are created to contain the storage.
MACRO PSECT Equivalent to
RSE ERVAR RS
NRE ENVAR NR
NRPE EPVAR NRP
Storage defined by these macros will be in an extended
section (not 0 or 1) and the symbol will be a global symbol
with a 36-bit value. The actual section used will vary
depending on the monitor configuration. At present, the
three new psects are in the same extended section (RESSEC),
but this is not necessary and will not be true if the total
of such storage grows to more than a section.
Ordinary MACRO assembler constructs are sufficient to
reference these data areas provided the symbol is placed in
a 36-bit field. Hence, if DATLOC is defined with one of the
above,
MOVE T1,@[DATLOC]
will generate a reference to it, but
MOVE T1,DATLOC
will be flagged as an error at link time indicating that a 36-bit
symbol is being truncated to 18 bits.
Page 3
The most desirable implementation of the above would be
to declare PSECTS to MACRO and LINK in the same way as
existing PSECTS are declared. However, the present version
of LINK is not capable of handling a load in which some
psects are in section 0 and some are not. There is no known
way to work around this limitation, so the "psects" above
are not in fact actual psects known to MACRO or LINK.
Instead, the above three macros assemble as symbol
assignment statements (DATLOC=nnnn), with an assembly-time
counter being incremented by the size of the area being
defined. The main consequence of this is that all such
storage MUST be defined in STG.MAC since the assignments are
in fact made at assembly time rather than link time. This
has not been a problem since most storage areas are already
defined in STG, and no problem is created by moving a
declaration from some other module. Another consequence is
that the initial values of these "psects" are set by MACRO
statements in PARxxx.MAC rather than by LINK switches in
LNKxxx.CCL.
Another consequence of this is that LINK does not check
whether these PSECTS overlap with any others. POSTLD
performs this check as it does for all other PSECTS. This
is desirable in some cases as it allows us to intentionally
overlap storage areas with code or data which is moved as
the monitor starts up. If actual psects are used,
superfluous error messages are generated by LINK. For this
reason, the NPVAR psect (used by NRP) is also generated in
the STG.MAC assembly and is not a real psect. The four
storage assignment macros (NRP, RSE, NRE, NRPE) are
generated and defined only in STG.MAC.
2.0 REFERENCING EXTENDED DATA STRUCTURES
Generally, the straightforward way to reference tables
or data blocks in other sections is with an Extended Format
Indirect Word (EFIW). In particular, for references like:
MOVE T1,TABL(Q1)
an equivalent reference can be constructed using an
EFIW assuming only that the index has no junk in the left
half. With an EFIW, the indirect word will contain the
entire 30-bit address and the index register specification
in bits 2-5 per the Hardware Reference Manual.
In order to facilitate the assembly of EFIWs, the macro
EP. is now defined in MACSYM. The string following may
specify the 'address', 'index', and 'indirect' fields in the
same syntax as for ordinary instructions. That is,
EP. DATLOC(X)
Page 4
will assemble a word with DATLOC in bits 6-35, and X in
bits 2-5. If an "@" is present, bit 1 will be set. Bit 0
will always be off. This is appropriate for storage
declared as 30-bit addresses as is done by the above storage
macros. A typical reference is:
MOVE T1,@[EP. DATLOC(Q2)]
In some cases, moving a storage area to an extended
section requires only a systematic changing of instructions
of the form:
MOVE T1,DATLOC(Q2)
to the above form.
For data structures defined with DEFSTR and MSKSTR,
provision must be made to generate extended indirect
references. The macros EDEFST and EMSKST are defined in
MACSYM to handle such cases. For data structures so
defined, each reference generated by LOAD, STOR, etc. will
generate an EFIW. Note that this requires no change to the
in-line code. A statement like
LOAD T1,DATSTR,(Q2)
remains valid and will generate an extended reference
if DATSTR is defined with EDEFST or EMSKST.
In some cases, moving a storage area to an extended
sections requires only that the definition of the data
structures within it be changed from DEFSTR/MSKSTR to
EDEFST/EMSKST with no changes to in-line code.
3.0 AUTOMATIC COMPUTATION OF PSECT BOUNDARIES.
With the addition of several new PSECTS and the
increased complexity of rules for PSECT overlaps, the
process of juggling psect boundaries to make a valid load of
the monitor became increasingly painful. It has long been
assumed that the "relocatable psect" feature in LINK would
solve this problem, but that still appears a long way off.
Therefore, POSTLD is modified to compute new PSECT
boundaries as part of its process of checking and reporting
the results of a load. If the load is unsuccessful because
of one or more psect overlaps, the new set of boundaries can
be used for the next attempt. The standard batch control
files which build monitors are modified so that if an error
is reported by POSTLD (implying psect overlaps), the link
will be repeated with the new psect origins generated by
POSTLD.
Page 5
Typical POSTLD output is:
-----------------------------------------
SYSTEM 2102, TOPS-20 Monitor 6(5667)
Monitor address space:
Psect Start End Length Free Limit
RSCOD 1000 131033 130034 3744
SZCOD 135000 142377 5400 400
INCOD 143000 164214 21215 563
RSDAT 165000 166275 1276 502
PPVAR 167000 172777 4000 0
RSVAR 173000 322335 127336 442
SYVAR 323000 323777 1000 0
NRVAR 324000 354443 30444 334
PSVAR 355000 372777 16000 0
JSVAR 373000 450777 56000 0
NRCOD 451000 703720 232721 57
NPVAR 704000 752777 47000 25000 777777
POSTCD 774000 776303 2304 1474 777777
ERVAR 12001000 12006110 5111 171667
ENVAR 12200000 12232215 32216 145562
EPVAR 12400000 12435777 36000 342000 End of section
Loaded symbols 166442 400273 211632 31504 BGSTR
Runtime symbols 324000 535631 211632 146146 NPVAR
The symbols will be moved to their runtime area right after
the SYVAR psect by STG early in the monitor's initialization.
BGSTR 435000 446547 11550 230
BGPTR 447000 450217 1220 560 NRCOD
There are 30 (octal) free pages in section 0, not counting symbols.
A potential set of new PSECT origins will be written into LNKNEW.CCL
and PARNEW.MAC.
Writing sorted bug list to file BUGSTRINGS.TXT.267
Saving monitor as MONITR.EXE.21
-----------------------------------------
Note the comment regarding new PSECT origins. The
origins in LNKNEW.CCL replace the ones in LNKxxx.CCL for
"real" psects, and the ones in PARNEW.MAC replace the ones
in PARxxx.MAC for pseudo-psects. If the recomputed origins
are used, they must all be used since an adjustment of one
psect origin may require adustment of all higher ones.
Page 6
4.0 ASSIGNMENT OF MONITOR SECTIONS
Heretofore, monitor sections were defined by a
parameter in STG.MAC and some particular code scattered
around PAGUTL. As sections were grabbed for various
purposes, about half of the maximum 32 available on the KL10
were used in some configurations. The need to use a whole
section for some particular purpose is partially alleviated
by the RSE, NRE, and NRPE macros above. Beyond that, large
storage areas can be dynamically assigned with ASGVAS
described below.
To simplify the declaration of monitor sections at
assembly time, the macro MSECN is defined in STG. This
replaces the ad-hoc definitions previously used for the
sections above the bit table and index table sections. The
format is:
MSECN symbol
This declares the next available section to be in use
and assigns the section number to 'symbol'. The actual
section number will vary depending on the monitor
configuration. Sections defined this way include those used
for CSTs, DSTs, DECNET buffers, ARPANET buffers, CFS
buffers, extended static storage, and swappable free space.
To support this, code in PAGUTL around PGRINI and FTPA
was made general and capable of handling any section defined
with MSECN.
When storage requirements are large, or vary greatly at
runtime, it is more efficient to assign storage at runtime
than to declare the largest possible area at assembly or
link time. The routine ASGVAS provides this capability. It
assignes address space in units of one page up to an entire
section.
The interface is:
;ASSIGN MONITOR VIRTUAL ADDRESS SPACE
; BLCAL. ASGVAS,<AVFLG,AVSIZ>
; AVFLG - Flags
; AVSIZ - Size of desired space in words, rounded up to page multiple.
;Returns +1: failure
; +2: success, T1/ address of space (guaranteed on page boundary)
;FLAGS
AV%NCS==:1B0 ;Don't create section (i.e., just assign map slot)
AV%LOK==:1B1 ;Lock pages in memory
ASGVAS::BLSUB. <AVFLG,AVSIZ>
Page 7
Virtual address space assigned by ASGVAS will never
overlay a section boundary. Hence, one section is the
largest block that can be assigned. If less than a section
is requested, ASGVAS will see if there is room in the
current section.
The flag AV%LOK allows for the assignment of locked
storage with no further effort by the caller.
The flag AV%NCS may be used if the whole section is to
be used as a window. It is ignored if AVSIZ is less than
one section.
To assign a section, ASGVAS looks for a free section
above those declared at assembly time. The page table and
MSECTB entries are created. To assign pages within a
section, ASGVAS maintains a variable indicating the next
free page in the section currently being used if any. If
there is none, or if there is insufficient room, a new
section is assigned.
5.0 SYMBOL TABLE MOVED TO EXTENDED SECTION
In previous releases, the symbol table from the monitor
build has been either in section 0/1 or has been "hidden" in
a separate section 0 map. In fact, all recent monitors have
been built with the symbol table hidden since even a small
configuration did not have sufficient room for the symbol
table in section 0. There was quite a bit of code to
support the hidden symbol table. This included code to
build the alternate section 0 map, to map the symbol table
page-by-page when looking up symbols in SNOOP%, and to
switch maps when entering and leaving DDT. Some of this
incurred a time penalty, and the map switching sometimes led
to obscure bugs if the machine stopped with the wrong map in
place.
Further, the reorganization of the address space to
accomplish some of the other parts of the address space
project resulted in too many constraints involving the
physical address space, section 0 virtual address space, and
the symbol address space. That is, it became impossible to
layout psects such that all necessary areas were represented
in those address spaces with no overlap.
The solution to this is to move the symbol table to an
extended section which is always present. This eliminates
the map switching when entering and leaving DDT, and removes
constraints having to do with the layout of the symbol table
section.
Page 8
This is implemented as follows:
1. The map which was constructed for the hidden symbol
table section is used instead as an extended
section map. Areas other than the symbol table are
not mapped into it however. This is done in PGRINI
such that when paging is turned on, the extended
sections immediately exist and the symbol table
appears in SYMSEC.
2. The block MONEDV (monitor extended data vector) in
STG.MAC is increased by one word which contains the
section number of the symbol table section. The
hidden table pointers in this block are left 0.
EDDT looks at this block to figure out how to
reference the symbol table.
3. Code in SNOOP% is modified to reference the symbol
table via EFIWs and not to do page-by-page mapping.
4. DDT is modified to construct the symbol table
address from the section number in MONEDV and the
symbol table pointer. MDDT is modified to not
required the routine .IMOPR for symbol table
mapping.
5. The routine .IMOPR is removed from MEXEC.
Clearly, paging must be on for the symbol table or
anything else in extended sections to be referenced. In
fact, it has been true for some time that there is no place
in the monitor which turns off paging, and that the monitor
can not survive having paging off. Therefore, the PGROFF
routine has been placed within a REPEAT 0.
Also, code must be running in a non-0 section to
reference extended data. The code in PGRINI now enters
section 1 immediately upon enabling paging, and stays in
section 1 through the remainder of the initialization in
SYSGO except where S0.ENTs are present. If a breakpoint is
hit in section 0, DDT jumps into section 1 (unless a fully
extended DDT is in use -- see below) so that it can
reference the symbol table and any other locations requested
by the user.
6.0 MOVE DDT TO EXTENDED SECTIONS
Among particular candidates for moving out of section
0/1, DDT in the form of KDDT (10 pages) and MDDT (8 pages)
are among the largest. DDT is already capable of running in
extended sections and referencing locations in other
sections. The primary reason for having it in section 0/1
Page 9
has been that the breakpoint facility did not work between
sections.
This problem was studied, and a means of handling
inter-section breakpoints adequate for monitor DDTs was
designed and implemented. This uses "JSR @" for breakpoints
from non-0 sections, and "JSR" plus a small jump block for
breakpoints from section 0. See [2] for a functional
specification of all DDT changes.
Since the DDTs cannot be linked into a non-0 section
because of LINK limitations, they are linked into section 0
overlaying swappable storage areas that are not referenced
until well after paging is on. During PGRINI, the DDTs are
mapped to an extended section (SYMSEC) and unmapped from
section 0/1. Once paging is on, they appear only in the
extended section.
7.0 MOVE BUGSTRINGS AND BUGPOINTERS TO EXTENDED SECTION
The table of BUGHLT, BUGCHK, and BUGINF messages is
retained in the monitor so that they can be included in CTY
printouts. They take up approximately 12 pages however, and
have sometimes been deleted if there has been insufficient
address space with the result that the messages simply do
not appear in the CTY printouts.
At PGRINI time, the area holding the strings and
pointers is mapped to an extended section (SYMSEC) and
unmapped from section 0/1. The pointer BUGTP, formerly an
AOBJN pointer, is now a double word having 36-bit count and
address. The code in LOGBUG is modified to deal with this
pointer.
8.0 SEPARATE MAPS FOR SECTIONS 0 AND 1
Heretofore, identical section pointers to MMAP have
been used for both sections 0 and 1 with the result that the
two sections were completely equivalent. All code and
storage in 0 appeared in 1 also, and any map operations
affecting one also affected the other.
To reference storage areas in extended sections, the
code must be running in a non-0 section. Much of the
monitor already runs in section 1 most of time time. It has
not been clear however, whether a particular piece of code
might sometimes be entered in section 0 unless an EA.ENT
were placed at the top of it. As storage areas were moved
to extended sections, bugs resulting from attempted
references while in section 0 had to be found and fixed by
the addition of EA.ENTs. A great many EA.ENTs came to
Page 10
populate the code, most of them unnecessary most of the time
because the code was already running in section 1. The
scheduler was particularly bad in this respect because it
has many entry points which are used all over the monitor,
some rather infrequently.
The ultimate objective is that all monitor code run in
a non-0 section, and there is no hardware reason to prevent
this. The only hardware constraint on the monitor address
space is that DTE buffers must be in section 0 because they
are referenced with byte pointers in the comm region. In
fact, only the code in PHYSIO is presently known to be
incapable of running in non-0 sections. We have long felt
the need to have a way to immediately detect and prevent
code from running in section 0 as a debugging aid.
Therefore, this project is to generate separate maps
for monitor sections 0 and 1. All swappable code and most
resident code will appear only in section 1. Resident code
which cannot immediately be modified to run in section 1
will continue to appear in both sections and will be run in
section 0.
To identify code which must run in section 0, a new
psect (SZCOD) is defined. Code may be declared in this
psect with:
RESCD (SEC0)
Otherwise, the usual RESCD and SWAPCD declarations will
use the psects which appear in section 1 only.
Other than the code sections, all storage remains in
both sections. This is accomplished as follows:
1. A section 0 map is created and filled as usual
prior to enabling paging.
2. A section 1 map is created and filled with indirect
pointers to section 0. The identifier for the
section 1 map is in M1SPTN; the identifier for the
section 0 map remains MMSPTN. The section 0 map is
defined at assembly time as MMAP; the section 1
map has no pre-defined address.
3. For the code sections, each page pointer is moved
from the section 0 map to the section 1 map
(replacing the indirect pointer).
Having been setup this way, BOOT runs in section 1
while loading the swappable monitor and the swappable
monitor is loaded into section 1.
Page 11
As one might expect, and as was verified emperically,
the monitor would not run with all RSCOD code in section 1
only because of many unintentional transfers into section 0.
Hence, a debug switch is defined which allows this facility
to be used only when desired. The switch works as follows:
MSEC1F::0
;Debug facility -
; 0 = sections 0 and 1 the same;
; 1 = different maps but RSCOD and INCOD in section 0 with indirect ptrs
; 2 = different, RSCOD and NRCOD removed from section 0.
For debugging particular pieces of code, the monitor
should be started with MSEC1F set to 1. This keeps the code
in both sections initially, but allows particular pages to
be removed from section by calling MM0CLR as follows:
;Clear PSECT from section 0 map after pointers moved to section 1 map
;and PC jumped to 1 if necessary.
; T1/ First page number
; T2/ Last page number, inclusive
; CALL MM0CLR
;Returns +1 always
MM0CLR:
This routine merely zeros entries in MMAP, and this may
be done with DDT equally well.
The effect of an unintentional reference to section 0
will most likely be a "PCIN0" bugchk in the page fault
handler. The additional data words are the PC and memory
address of the failing reference. If the failure resulted
from a transfer, the PC from which the jump was made should
be on the stack or possibly in CX in the case of certain
scheduler entry points. To reduce the pain of debugging, if
the PCIN0 is continued, it will remap the offending page
back into section 0 and continue. Hence, this case should
never be fatal.
On the other hand, if the reference to section 0 occurs
in the scheduler or at interrupt level, a SKDPF1 or PITRAP
bughlt will result. There is no automatic recovery from
this, but with sufficiently nimble fingers in EDDT, you may
be able to back out manually.
At this writing, the monitor runs to a first
approximation with the entire swappable monitor in section 1
only. That is, it finds no failures through startup
including running all of the PTYCON jobs. Two cases of
unintentional section 0 references were found prior to this.
In neither case was the PC going to 0; rather a local
reference was badly constructed and referenced section 0.
In one case, a local assembled-in table was referenced, and
Page 12
in the other, a subroutine argument was referenced.
With respect to resident code, portions of PHYSIO were
put into the SZCOD psect, but no comprehensive effort was
made to identify and move all of the relevant PHYSIO code
including some things in STG. See [3] for further comments
regarding use of this facility.
9.0 PROVIDE FOR CODE IN ADDITIONAL SECTIONS
With the other parts of this project, we will have
ensured that future development will never run into a
shortage of address space for storage. All new code should
be written to support inter-section references to major data
areas, and such areas should be assigned in extended
sections. Hence, the section 0/1 storage areas should only
shrink in the future.
To completely eliminate constraints on future
development, we must also provide for code in sections other
than 0 and 1. As noted above, LINK is not presently capable
of loading code in multiple sections. Hence, for the
present, we must link all code into section 0 and remap
those psects which may run in other sections. Such code may
overlay storage areas at link time, but a limit of 256K for
the total of all code, symbol table, DDTs, and bugstrings
will exist until LINK is enhanced. At present, the builds
are about 50K short of this limit.
This project includes the following:
1. Create new psects for extended swappable and
extended resident code (ENCOD, ERCOD). Add macros
to allow specification of extended code as ESWPCD
and ERESCD.
2. Modify POSTLD for new psects.
3. In PGRINI, map extended code into SYMSEC and remove
it from section 0/1.
Beyond that, this project will investigate moving
certain self-contained pieces of code into the new psects.
The likely candidates are FLIN, FLOUT, DATIME, etc. which
use none of the monitor data base and few external
subroutine calls.
A requirement for effective multiple-section code is
that inter- and intra-section calls to the same routine can
be handled efficiently. An inter-section call must be
assembled as, e.g.:
Page 13
CALL @[SUBR]
whereas an intra-section call to the same routine could be:
CALL SUBR
Ideally, the linker would determine at link time
whether a call (or other reference) is inter- or
intra-section, and build the right thing. Since that is not
likely in the forseeable future, some other mechanism is
necessary. This problem is still to be investigated. In
the meantime, code moved to the extended section will call
to section 0/1 code with an explicit indirect. Such code
cannot readily be called from section 0/1 code except via
JSYS entry.
When LINK is enhanced to support the loading of code
into both 0 and non-0 sections, some additional work will be
necessary in POSTLD, PGRINI, and possibly elsewhere to
handle the generation and startup of a multi-section EXE
file. That work is beyond the scope of this project.
10.0 EXISTING DATA MOVED TO EXTENDED SECTIONS.
The following storage has been moved to extended
sections:
RSE(RESBTB,PGSIZ) ;RESIDENT FREE SPACE BITTABLE
RSE RSELST,1 ;LAST WORD IN RSE
RSE CLSUTL,MAXCLS ;CLASS UTILIZATION
RSE JOBCLS,NJOBS ;CLASS PER JOB
RSE JOBUTL,NJOBS ;JOB UTILIZATION
RSE JOBIRT,NJOBS ;JOB INCREMENTAL RUN-TIME
RSE JOBDST,NJOBS ;JOB "DISTANCE"
RSE CLSSHR,MAXCLS
RSE CLSSWA,MAXCLS ;WINDFALL ALLOCATION (OR -1)
RSE CLSSHI,MAXCLS ;SHARE PER MEMBER
RSE CLSCNT,MAXCLS
RSE CLSDST,MAXCLS ;CLASS DISTANCE
RSE CLSSUM,MAXCLS ;INTEGRAL OF NRUN FOR CLASSES
RSE CLSIRT,MAXCLS ;CLASS INCREMENTAL RUN TIME
RSE SNAMES,NNAMES ;SIXBIT NAME OF SUBSYSTEM
RSE STIMES,NNAMES ;ACCUMULATED RUNTIME OF SUBSYSTEM
RSE SPFLTS,NNAMES ;ACCUMULATED PAGE FAULTS OF SUBSYSTEM
RSE SSIZE,NNAMES ;WORKING SET SIZE INTEGRAL
RSE SNBLKS,NNAMES ;NUMBER OF BLOCKS
RSE SCOUNT,NNAMES ;NUMBER OF SETSN CALLS
RSE CLSRJA,<MAXCLS*NRJAVS> ;RUN AVGS FOR CLASSES
NRPE EPGMAP,PGSIZ ;Map for extended free memory for SCA
Most of the job and class-scheduler tables are
referenced as full words with no structure definition
imposed. In one case, the following definition was made:
Page 14
EDEFST (CLGLC,CLSCNT,17,18) ;COUNT OF PROCESSES ON GOLST FOR THIS CLASS
Otherwise, references were mechanically changed to
indirect via an EFIW using the "EP." construct.
11.0 REFERENCES
1. "The Address Space Project for Release 6" - J.
Hall, ?-Sep-83
2. "Proposed Enhancements to DDT for TOPS20 Release 6"
- D. Murphy, (in progress)
3. "My Part in the Address Space Project" - J. Hall,
7-Sep-83
1.0 MOVEMENT OF SWAPPABLE FREESPACE OUT OF SECTION ZERO
This section describes the project to reclaim PC-section monitor address space
by moving swappable freespace out of section zero. Because of project size,
only some of the necessary work will be performed in Release 6.0, with the
remainder to be performed in the post Release 6 timeframe.
This project should free up approximately 15 pages of section zero address
space.
The salient points of the project are as follows:
1. Recode the existing algorithm to use 30-bit addressing and make the
following extensions:
o Allow infinitely expandable headers and trailers. Previously, only
a fixed size header was used; no trailer was used. The size of
the header and trailer may be modified on a per-pool basis: the
header has a minimum size of 2 words, while the trailer is entirely
optional and has no minimum size.
o Change algorithm from "best fit" to "first fit" - see FSPFIT
conditional in FREE.MAC.
o During allocation, use randomized entry into free list to reduce
fragmentation. If a randomized entry fails to allocate a block,
then a second pass, starting from the beginning of the list, will
be performed.
o Allow separate pools for each major user of freespace; in the
current scheme, there is 1 global swappable freespace pool.
o Use appropriate minimum block sizes for each pool to reduce
fragmentation. Some operational data will be required to establish
these sizes; in the interim, the minimum block size has been set
to 4.
2. Streamline and unify the existing implementation such that, eventually,
only 1 freespace manager will be necessary for all freespace (Job,
resident, swappable). This is in contrast to the current scheme in
which a separate manager is required for resident and swappable space,
respectively.
o Eliminate redundant jacket routines
o Eliminate multiple zeroing of the same block
3. Modify the callers of swappable freespace to allow data in a non-PC
section
Page 2
o For V6.0, modify callers in the following modules: IPCF.MAC,
ENQ.MAC, NSPSRV.MAC.
o For Post V6, modify the remaining callers: TAPE, LOGNAM, USAGE%,
JSB.
4. Testing
o The freespace manager itself was initially written and tested in
user mode, and only then was it run in monitor mode.
o A home-grown IPCF tester was used to verify the IPCF changes. A
major weakness in the testing concerned the fact that the monitor
was not tested with accounting enabled, and several bugs were not
found until an attempt was made to use the monitor in a real
timesharing environment (with accounting enabled). Certain
archiving-specific IPCF code remains to be tested.
o The COBOL test library was used to test the ENQ/DEQ changes.
o DECnet changes were tested with the DTRDTS utility.
1.1 Freespace Data Structures
There are 3 major types of data structures used to implement swappable
freespace:
1. Freespace descriptor index table (1)
2. Freespace descriptors (1 per pool)
3. Freespace pool (1 per major user)
These structures are described below:
Page 3
1.1.1 Freespace Descriptor Index Table -
This is simply a table of pointers to the descriptors which define and control
each freespace pool. The index to this table constitutes a unique identifier
for a given freespace pool. The table appears as follows:
Freespace-descriptor index table
FSPTAB: *-------------------------------------------------------------*
* Address of freespace descriptor *
*-------------------------------------------------------------*
* Address of freespace descriptor *
*-------------------------------------------------------------*
.
.
.
*-------------------------------------------------------------*
* Address of freespace descriptor *
*-------------------------------------------------------------*
FSPTBL = Size of freespace descriptor index table in words
Page 4
1.1.2 Freespace Descriptor -
This defines certain attributes of the freespace pool, and is used to control
the allocation and deallocation of space from the pool. The descriptor has the
following format:
Freespace descriptor
*-------------------------------------------------------------*
FSPPFL: 0 * Flags *
*-------------------------------------------------------------*
FSPLOK: 1 * Pool lock *
*-------------------------------------------------------------*
FSPFFB: 2 * Address of first free block *
*-------------------------------------------------------------*
FSPRFB: 3 * Randomized Address of first free block *
*-------------------------------------------------------------*
FSPCNT: 4 * Count of space remaining in pool *
*-------------------------------------------------------------*
FSPHDS: 5 * Block header size *
*-------------------------------------------------------------*
FSPTRS: 6 * Block trailer size *
*-------------------------------------------------------------*
FSPHTS: 7 * Combined header and trailer size *
*-------------------------------------------------------------*
FSPMTB: 10 * Minimum total block size *
* (FSPHDS + FSPTRS + minimum user block size) *
*-------------------------------------------------------------*
FSPORG: 11 * Origin address of freespace pool *
*-------------------------------------------------------------*
FSPEND: 12 * Ending address of freespace pool *
*-------------------------------------------------------------*
FSPSML: 13 * Smallest balance of free space achieved *
*-------------------------------------------------------------*
FSPBAP: 14 * Address of block-accounting area *
*-------------------------------------------------------------*
FSPDSS = descriptor size in words
Offset FSPFFB contains the address of the block having the lowest address of any
free block in the pool. Offset FSPRFB contains the address of a
randomly-selected free block (ala Knuth); using this pointer to begin an
allocation-traverse tends to reduce list fragmentation.
Offset FSPSML contains the smallest balance of freespace available in the pool
since system-startup. This value indicates the relationship between the pool's
allocation of space and the demand for that space. If this value is
consistently large, then the pool allocation may be reduced. Conversely, the
pool allocation may need to be increased if the balance is too small. Some
research will be required to determine the acceptable minimum balance for a
given pool.
Page 5
The descriptor may optionally contain a pointer at offset FSPBAP to an area that
is used for block accounting. This area records (1) allocation requests (2)
allocation grants, and (3) depth of traversal. Each of these counts is kept on
a per blocksize basis and is used to measure freespace utilization and
fragmentation. The block-accounting area has the following format:
Block accounting area
*-------------------------------------------------------------*
n+0 * *
*-------------------------------------------------------------*
n+1 * Count for blocksize 1 *
*-------------------------------------------------------------*
n+2 * Count for blocksize 2 *
*-------------------------------------------------------------*
.
.
.
*-------------------------------------------------------------*
n+end-1 * Count for blocksize "end"-1 *
*-------------------------------------------------------------*
n+end * Count for all blocks of size "end" or greater *
*-------------------------------------------------------------*
Where "end" is the last offset in the accounting block.
FSPBSC = accounting-block size in words
There are three of the blocks shown above in the accounting area, one for each
of the following: (1) allocation requests, (2) allocation grants, and (3) depth
of traversal.
Page 6
1.1.3 Freespace Pool - The pool is simply a large block of storage statically
allocated at compile time and converted into a linked list of 1 large block at
run time initialization.
1.2 Freespace Definition Macro
The freespace pools and descriptors are defined by the FSPPL. macro, which is
invoked as follows:
;;The following specify the freepool characteristics:
;; Pol| Adrs| Pool| Hdr | Trl |Minim | Block| Cur |
;; Nam| Sect| Size| Size| Size |Size | Acctn| Pool| Flags
;;General section zero pool
FSPPL.(GEN,.ZERO., 5000,FSPBHS,FSPBTS, 4,.ACCN.,.NONE.,FS.CNT)
;;DECnet pool
FSPPL.(DCN,.ZERO.,DCNFSZ,FSPBHS,FSPBTS, 4,.ACCN.,.NONE.,.NONE.)
;;ENQ/DEQ pool
FSPPL.(ENQ,.XTND.,ENQFSZ,FSPBHS,FSPBTS, 4,.ACCN.,.NONE.,.NONE.)
;;IPCF pool
FSPPL.(IPC,.XTND.,IPCFSZ,FSPBHS,FSPBTS, 4,.ACCN.,.NONE.,.NONE.)
;;JSB (descriptor only)
FSPPL.(JSB,.NONE.,JSBFSZ,JSBBHS,JSBBTS, 4,.NONE.,JSBFSP,FS.CNT)
The macro arguments specify the following:
1. 3-character mnemonic upon which to base freespace symbols. E.g., "IPC"
will generate "IPCFSP" (the freespace pool for IPCF) and "IPCDES" (the
freespace descriptor for IPCF).
2. The address space in which to generate the pool ".XTND" for a pool in a
non-zero section, ".ZERO." for a pool in section zero, and ".NONE." to
suppress the generation of a pool (the latter assumes the pool has
already been defined elsewhere). Pool space is generated with the NR
or NRE macros, as appropriate.
3. Length of the freespace pool in words
4. Length of the block-header in words (minimum = 2, no maximum)
5. Length of the block-trailer in words (minimum = 0 , no maximum)
6. Minimum block size (minimum size given to user)
7. Flag to indicate if a block accounting area should be allocated
8. Address of pool if pool was defined elsewhere
9. Pool flags:
FS.CNT==1B0 Indicates that the users of this pool expect the
block pointer to be pointing to the count word of the header block
(this is a temporary bit, that will be removed once all users of
freespace have been modified to stop expecting to see the
Page 7
block-count word)
Note that JSB freespace is somewhat anomalous with respect to the other pools:
(1) its pool is not allocated by the FSPPL. macro (the area is already defined
in STG). (2) The JSB freespace descriptor generated by the macro (JSBDES) is
used as a template at job-startup and BLTed into the JSB at offset JSBDSC. (3)
There is a separate JSB pool and descriptor for each job on the system. (4) The
JSB pool is not initialized with the other pools at system-startup, but at
job-startup for each job. (5) The JSB pool is initialized with only a small
amount of space (currently 64 words) and is grown 1 page at a time on demand
until the maximum page allocation is reached.
1.3 Operational Description
INITIALIZATION
Swappable freespace is initialized at system startup (specifically, the last
activity performed before GOTSWM). JSB freespace is initialized at job startup.
OPERATION
The freespace manager is organized into a pair of central allocator/deallocator
routines (ASGFSP, RELFSP). These routines are normally entered only through a
pair of jacket routines that are specific to a particular freepool. For
example, IPCF freespace is acquired by calling the jacket routine ASGIPC:
Call: CALL ASGIPC
Args: T1/ Desired block size
Returns: +1 T1/ MONX05 - Insufficient space to honor
request
+2 T1/ address of block
and released by calling the jacket routine RELIPC:
Call: CALL RELIPC
Args: T1/ address of block
Returns: +1 Always
Page 8
1.4 Error-checking
The existing error-checking facilities of swappable freespace have been
maintained:
1. ASGFR0 BUGHLT - Attempt to assign block of zero words
2. ASGINT BUGCHK - Attempt to assign freespace while not NOINT
3. RELINT BUGCHK - Attempt to deassign freespace while not NOINT
4. RELRNG BUGCHK - Attempt to deassign a block whose address does not fall
within pool boundaries
5. RELBAD BUGCHK - Attempt to deassign a block which would overlap its
predecessor and/or successor in the freespace pool.
1.5 Design Issues
The freespace manager is designed such that major users of freespace will each
have their own pool. The advantage of this is that if a user of freespace is
misbehaving, any damage caused will tend to be limited to the particular pool
belonging to that user; knowing which pool has been damaged will usually give a
ready (though general) identification of who caused the damage. Another
advantage is that users who tend to hold blocks for long periods of time (and
tend to suffer greater fragmentation) can be isolated from users who hold blocks
for only a short period of time.
The tradeoff for the above feature is that load-balancing is not performed.
Thus, if the DECnet pool is out of space, space cannot be allocated from the
IPCF pool, even though that pool may be grossly underbooked. This implies the
following:
1. As each pool's allocation is a compile-time constant, that allocation
must be large enough to cover peak demand and allow for some growth of
consumption (as when more users are added to the system, and
job-sensitive pools are subject to heavier demand).
2. It will be prudent for an installation to periodically monitor pool
demand in order to anticipate when the pool size must increase (or
perhaps even decrease).
3. It will be incumbent upon DEC to ship monitors with pool sizes
sufficiently large to satisfy most customers (implying that some sites
may opt to raise or lower pool sizes).
Page 9
If the previous is found unacceptable, then it is possible to treat all of the
freespace pools (at least those non-zero-section pools) as 1 large pool and to
modify the freespace jacket routines to use that pool. However there is no
limit-logic in the manager to prevent a notorious user such as DECnet from
depleting the entire pool. (Previously, NSPSRV contained logic that prevented
DECnet from acquiring more than N% of the global swappable freespace pool.)
1.6 Conditional Features
Assembly switch FSPFIT (in FREE.MAC) can be used to convert the algorithm back
to "best" fit from "first" fit.
Assembly switch FSPDBG (under the control of the DEBUG conditional) is used to
assemble the code in the freespace manager that handles headers of length
greater than 2 and trailers of any length. If this code is not assembled, then
all headers are treated as having a length of 2 (the minimum) and trailers are
assumed not to exist, even if this contradicts the header/trailer size specified
in the pool descriptor.
Assembly switch FSPBAC (under the control of the DEBUG conditional) is used to
assemble the code that implements block accounting.
1.7 Related Projects
After all major monitor work is finished, statistics should be accumulated on
in-house systems (running the new freespace manager) for pool allocation and
demand, and most common block sizes. These statistics should aid in choosing
the final pool allocations and minimum blocksizes to be used in the monitors
shipped to customers.
The SYSDPY resources display will have to be changed to reflect the new pools
and new information available (such as minimum balance).
+---------------+
! d i g i t a l ! I N T E R O F F I C E M E M O R A N D U M
+---------------+
TO:
CC:
DATE: October 10, 1983
FROM: Judy Hall
DEPT: DEC-20 S. E. Dept.
LOC: MR 1-2/L10
DTN: 231-6421
SUBJ: My Part in the Address Space Project
NOTE: This document was reviewed by the TOPS-20 group
on September x, 1983. The group felt that it was
desirable to remove the structure definitions that
contain the index register FX. If time permits, this
will be done in Release 6.0 However, the spec does not
yet reflect that change.
1.0 INTRODUCTION
This document describes the pieces of the address space project
that I have coded in Release 6. In addition to the coding
work, I analyzed the effort required to change all users of
swappable free space in order to move all swappable free space
out of the code section. Some of that work was done by Gene
Leache in Release 6 and is described in his memo. The notes
regarding the rest of the effort are available but are not
reproduced here.
The following projects are described:
Changes to the resident free space handler to allow
extended free space
Changes to allow terminal data blocks to come from
extended free space
Changes to allow timer blocks to come from extended
free space
Movement of the fork tables to an extended section
Isolation of section 0 code via XCALL macro
2.0 RESIDENT FREE SPACE
In Release 5.1 and earlier, all resident free space came from a
single contiguous area of virtual address space (hereafter
referred to as a "chunk"). Although a bit, RS%SE0, was
provided to allow the caller to request free space from section
0, it (or rather the absence of it) had no effect, and thus it
To: Page 2
Subj: My Part in the Address Space Project
was not consistently used. In fact, all free space came from
the PC section (0 or 1, depending on the caller's point of
view).
In Release 6, there are two chunks of free space, and there
could be a larger number if that were desired. I believe it is
appropriate to refer to them as "PC section free space" and
"extended section free space". If the caller sets RS%SE0, free
space comes from the original chunk, and can be addressed via
18-bit addresses from code running in either section 0 or
section 1. If the caller does not set RS%SE0, free space comes
from an unknown (to the caller) section, and must be addressed
with a 30-bit address.
2.1 External Changes
Callers of ASGRES and RELRES pass the same arguments as in
previous releases. The selection between the two chunks is
made based on the setting of RS%SE0 in AC 2, when ASGRES is
called. The caller of RELRES continues to pass only the
address of the block; the routine determines which chunk was
allocated based on the section number in the address.
This decision was made for reasons of expediency: it meant
that no new ACs need be used by existing code in order to
select the chunk. In the future, we could have each caller
provide a more specific indication of what chunk it wants, and
extend the number of chunks indefinitely.
At first, all callers were changed to set RS%SE0. Gradually,
as callers have been changed to run in section 1, the setting
of the bit has been removed.
2.2 Internal Changes
2.2.1 Data Structure
In previous releases, resident free space was described by a
set of values and locations that were defined primarily in STG.
Some of the code made immediate references to determine, for
example, the total size of free space.
Now that there can be more than one chunk of free space, these
locations have been combined into a "descriptor block"
consisting of 11 (decimal) words. For the PC section free
space, RES0TB points to this block; for the extended section
free space, RESNTB points to it. The following table
identifies and describes the offsets (this table exists as a
comment in FREE.MAC and STG.MAC):
Offset Old Meaning
Name
.REBAS RESBAS Starting address of free space
To: Page 3
Subj: My Part in the Address Space Project
.REEND RESFRZ Address of last word of free space
.RETOT NRESFB Total size of free space in blocks
.REPR1 RESMIN If remaining space less than this, allocate only priority 1
.REGRO RESAVE If remaining space less than this, grow free space (larger than .REPR1)
.REBTB RESBTB Address of start of bit table
.REBTL RESBTL Length of bit table (words)
.RETFR RESFRE Total remaining unallocated blocks
.REFFB RESFFB Number of block just past end of free space
.REPMX RESQTL Number of pools
.REQTA RESQTB Address of block containing quota for each pool
.REPFR RESUTB Address of block containing count of unallocated blocks per pool
Initialization of these locations is the same as for their
Release 5.1 equivalents. That is, a location that previously
was defined with == is now defined with the RSI macro.
As before, the PC section free space is allocated with the NRP
macro. The extended section free space is allocated with the
NRPE macro.
2.2.2 Changes to ASGRES and Friends
Within the routines that assign free space, the chunk is
identified by the address of its descriptor block. The one
exception is the first part of ASGRES. Since it is called with
RS%SE0 either set or cleared in AC 2, it chooses the correct
descriptor. That is, if RS%SE0 is set, it establishes RES0TB
as the descriptor; if RS%SE0 is not set, it chooses RESNTB.
From then on, the internals of the free space manager base all
decisions on the descriptor block.
This provides a compromise of sorts. The callers of ASGRES are
ignorant of the descriptors, and the routines that ASGRES calls
are ignorant of the fact that there are really only two chunks
of free space. Thus in the future we could allow any number of
chunks of free space merely by changing a few lines of code in
ASGRES.
Under a debugging conditional, ASGRES BUGHLTs (SEC0FS) if the
caller requests extended section free space and is running in
section 0.
If the call is made before paging has been turned on, ASGRES
hands out PC section free space automatically.
The major effort in ASGRES and the routines it calls went into
converting from references to absolute values and locations to
references to offets within the descriptor blocks. No changes
were required to the lowest-level routines that manipulate the
bit table, since they accept the address of the bit table as an
argument.
2.2.3 Changes to RELRES and Friends
To: Page 4
Subj: My Part in the Address Space Project
Like ASGRES, RELRES provides its subroutines with the
descriptor block of a chunk. It determines this based on the
section number in the address passed by the caller. If it is 0
or 1, RELRES assumes the PC section free space; if it is
anything else, RELRES assumes the extended section free space.
Under a debugging conditional, RELRES BUGHLTs (SEC0RL) if the
caller provides an address in extended section free space and
is running in section 0. Such code has probably already
incorrectly tried to reference the data from section 0.
RELRES allows the caller to provide an address of the form
(1,,n) even though ASGRES always describes PC section free
space as (0,,n). Apparently NSP, and maybe others, generates
the (1,,n) form, which in fact is a legal address since the two
sections are mapped together.
2.2.4 Changes to Initialization
RESFPI, which always initialized the locations describing free
space, is now a jacket routine. It calls RESFPX twice, once
for each chunk. RESFPX is somewhat simpler than the old
RESFPI, since RSI macros are used to initialize most of the
data. It merely initializes the bit table to show all blocks
to be in use.
2.2.5 Changes to Job 0 Code
RESLCK, which always locked or unlocked pages as needed, is now
a jacket routine. It calls RESLCX twice, once for each chunk.
RESLCX performs the same function as the old RESLCK; the only
changes were to use the descriptor block rather than absolute
locations.
2.2.6 CHKRFS
In Release 5.1, NSPSRV kept track of its use of resident free
space, and avoided calling ASGRES if there were insufficient
free space in its pool. Thus NSPSRV was directly referencing
part of the data structure for resident free space. This
function is now performed by a routine in FREE called CHKRFS,
who arguments are as follows:
T1/ Number of words required
T2/ Flags,,pool number
CHKRFS returns +1 if the amount of space remaining in the
desired pool is less than the number of words provided in AC1,
and it returns success if the amount is greater than or equal
to that required.
NSPSRV was changed to call this routine instead of making its
own check. While it could be used by other callers (the flags
in AC 2 consist of RS%SE0 as with ASGRES), it is not in Releaes
To: Page 5
Subj: My Part in the Address Space Project
6.
2.3 Testing
Before this code was put up on our systems, I attempted a
thorough verification of the changes to the code. Since all
callers of free space exercise the changes (regardless of their
choice of type of free space), several months of load test have
probably proven its readiness for shipment. We did turn up one
occurrence of a MOVEI that should have been converted to a MOVE
in order to reference the descriptor block properly.
Terminal service has been using extended free space for several
months as well. Therefore I am reasonably confident that we
have exercised this code as well as the customers will.
However, like the rest of the monitor, this code has not been
tested with the debug switches turned off.
3.0 TERMINAL SERVICE
Terminal data blocks have been allocated from resident free
space since Release 3. Several changes were required in order
to allow these blocks to reside in a non-PC section.
3.1 Running in Section 1
A large portion of terminal service was already capable of
running in section 1, since it was called from JSYS code.
However, code that ran at interrupt level was typically called
from DTESRV in section 0. The following routines now have
EA.ENTs:
TTDTRM
TTYINT
TTSPST
TTYDON
TTYDLU
TTYHGU
TTYSLA
IDCTY
DTESTO
DFNDL1
TTEMES
No code change was required to make these execute successfully
in section 1.
Also, the secondary protocol code now runs in section 1. The
XPCW block for the interrupt now points to (1,,DTESV0).
3.2 Requesting Extended Section Free Space
Most calls to ASGRES were changed to clear RS%SE0. Since
sendall buffers are passed directly to the DTE, they still come
To: Page 6
Subj: My Part in the Address Space Project
from section 0. Likewise the data block for the CTY comes from
section 0 because paging is not turned on when this block is
allocated.
3.3 Using One-Word Global Byte Pointers
The terminal data blocks contain byte pointers to the input and
output buffers as well as the sendall buffers. Since these
buffers must remain in section 0 (an abortive attempt at
tricking the microcode into finding them elsewhere confirmed
this), and since the byte pointers now come from some extended
section, local byte pointers are no longer useful.
Code that initializes byte pointers was changed to generate
9-bit one-word global byte pointers. When terminal service
calls DTEQ to send a buffer over the DTE, it converts the byte
pointer back to a one-word local in section 0. This is done
via a table lookup that assumes 9-bit bytes.
3.4 Managing Input and Output Buffers
Terminal Service has long had the habit of chaining together
some number (usually two) of blocks of words to make a set of
input or output buffers. The first word of each buffer
contains the address of the next buffer, and the code
determines that it has reached the end of a buffer by examining
the current byte pointer. By controlling the allocation of
these buffers so that they were on the desired word boundary,
it could check for both the last word in the block, and the
last byte in the word with a single instruction. The following
typical piece of code comes from GTTCI:
TDNN 3,WRPMSK ;AT END OF CURRENT BUFFER?
HRR 3,1-TTSIZ(4) ;YES. GO TO NEXT IN CHAIN
where WRPMSK includes both the check for 0 in the P field, and
the test on the address.
WRPMSK: XWD 770000,TTSIZ-1 ;MASK FOR WRAPAROUND OF CHAR POINTER
Now, because of the need to check for a one-word global byte
pointer, this code is as follows:
TDNN 3,WRPMSK ;AT END OF CURRENT BUFFER?
JRST [ LDB 1,[POINT 6,3,5] ;GET BYTE POSITION AND SIZE
CAIN 1,73 ;POINTING TO LAST BYTE?
HRR 3,1-TTSIZ(4) ;YES. GET ADDRESS OF NEXT BUFFER
JRST .+1]
where WRPMSK now checks only the address.
WRPMSK: TTSIZ-1 ;MASK FOR WRAPAROUND OF CHAR POINTER
3.5 Testing
To: Page 7
Subj: My Part in the Address Space Project
This code has been running inhouse for several months now. I
believe it has been tested thoroughly. However, the potential
for bugs in the implementation of one-word global byte pointers
is great. Running the benchmarks using the emulator, as well
as inhouse use of the system, should provide an adequate test,
however.
4.0 TIMER
The timer data blocks now come from extended free space. The
only code change required was clearing the RS%SE0 bit before
the call to ASGRES. The code already ran properly in section
1.
5.0 FORK TABLES
In Release 5.1 there were 18 tables, indexed by system-wide
fork index, and allocated in the PC section. Since the MONMAX
configuration allows 512 forks, these tables occupied 18 pages
of address space.
The actual number of tables to be moved in Release 6 will
probably be dictated by our need for space and the amount of
available time. Dan Cobb did the preliminary work for moving
all but FKPT. On the assumption that this work will be
completed in Release 6, this memo describes the tables (except
FKPT) as if they had already been moved.
5.1 Allocation
The tables are allocated in STG using the RSE macro. As
before, their length is dictated by the size of NFKS, which is
defined in STG (or PARAMS).
5.2 Structures
All fields of the tables are defined using EDEFST, and
referenced via the appropriate LOADs and STORs. Where fields
were previously defined using DEFSTRs, the names have been
preserved.
5.2.1 Indexing
Exiting DEFSTRs had FX built into the name, as in
DEFSTR FKPSB,FKPGS(FX),35,18
and code referenced them using
LOAD T1,FKPSB
However, some code indexed with another AC, and did not use the
DEFSTR, as in
To: Page 8
Subj: My Part in the Address Space Project
HRRZ T1,FKPGS(T2).
To accommodate this code, an alternate definition exists:
EDEFST FKPS%,FKPGS,35,18
allowing
LOAD T1,FKPS%,(T2).
5.2.2 Overlapping Fields
In previous releases, some of the fork tables have been treated
in inconsistent ways. That is, the scheduler sometimes handles
individual fields within a word, and it sometimes handles the
whole word. FKPGST provides an example; sometimes it is
treated as two halfwords, and sometimes it is treated as a
fullword.
This project did not attempt to change that, but rather allowed
for it by defining overlapping fields. The following field
definitions exist for FKPGST:
EDEFST FKPTX,FKPGST,35,36
EDEFST FKPTR,FKPGST,35,18 ;TEST ROUTINE
EDEFST FKPTD,FKPGST,17,18 ;TEST DATA
Code that previously did fullword operations now uses the field
FKPTX. Code that previously did halfword operations now uses
the fields FKPTR and FKPTD.
5.2.3 The New Definitions
The complete set of structure definitions follows:
EDEFST FKPGX,FKPGS,35,36
EDEFST FKPSB,FKPGS(FX),35,18
EDEFST FKPS%,FKPGS,35,18
EDEFST FKUPT,FKPGS(FX),17,18
EDEFST FKUP%,FKPGS,17,18
EDEFST FKPTX,FKPGST,35,36
EDEFST FKPTR,FKPGST,35,18 ;TEST ROUTINE
EDEFST FKPTD,FKPGST,17,18 ;TEST DATA
EDEFST FKQTM,FKQ1(FX),35,36
EDEFST FKQ2X,FKQ2,35,36 ;ALL BITS
EDEFST FKNTC,FKQ2,0,1 ;NET TOPOLOGY CHANGE INT ENABLED
EDEFST PIBMP,FKQ2(FX),1,1 ;PI BOOST FLAG
EDEFST FKFLG,FKQ2(FX),5,4 ;FORK FLAGS
EDEFST FKMNQ,FKQ2(FX),11,6 ;MIN Q FOR FORK
EDEFST FKQN,FKQ2(FX),17,6 ;QUEUE LEVEL NUMBER
EDEFST FKWTL,FKQ2(FX),35,18 ;WAITLIST ADR FOR BLOCKED FORK
To: Page 9
Subj: My Part in the Address Space Project
EDEFST FKBET,FKPT(FX),17,17 ;BALSET ENTRY TIME
FKBETH==:1B<^L<.RTJST(FKBET,FKBET)>> ;HIGH BIT OF RIGHT JUSTIFIED FKBET
EDEFST FKSWX,FKSWP,35,36 ;ALL BITS
EDEFST FKWSL,FKSWP(FX),0,1 ;WORKING SET IS LOADED
EDEFST FKWS%,FKSWP,0,1 ;WORKING SET IS LOADED
EDEFST FKBLK,FKSWP(FX),1,1 ;FORK BLOCKED
EDEFST FKBL%,FKSWP,1,1 ;FORK BLOCKED
EDEFST FKIBS,FKSWP(FX),2,1 ;FORK IN BALSET
EDEFST FKIB%,FKSWP,2,1 ;FORK IN BALSET
EDEFST BSWTB,FKSWP(FX),3,1 ;IN BALSET WAIT
EDEFST BSWT%,FKSWP,3,1 ;IN BALSET WAIT
EDEFST BSNSK,FKSWP(FX),4,1 ;NOSKED
EDEFST BSNS%,FKSWP,4,1 ;NOSKED
EDEFST BSCRSK,FKSWP(FX),5,1 ;IN CRITICAL SECTION
EDEFST BSCR%,FKSWP,5,1 ;IN CRITICAL SECTION
EDEFST FKIBH,FKSWP(FX),6,1 ;IBS HOLD, SET ON BALSET ENTRY
EDEFST FKIH%,FKSWP,6,1 ;IBS HOLD, SET ON BALSET ENTRY
EDEFST FKBSHF,FKSWP(FX),7,1 ;IN BALSET HOLD (IN AJBALS ONLY)
EDEFST FKBS%,FKSWP,7,1 ;IN BALSET HOLD (IN AJBALS ONLY)
EDEFST BSSPQ,FKSWP(FX),8,1 ;SPECIAL QUEUE (SYSTEM FORK)
EDEFST BSSP%,FKSWP,8,1 ;SPECIAL QUEUE (SYSTEM FORK)
EDEFST BSOVRD,FKSWP(FX),9,1 ;OVERRIDE HIGH PRIORITY
EDEFST BSOV%,FKSWP,9,1 ;OVERRIDE HIGH PRIORITY
EDEFST BSNST,FKSWP(FX),10,1 ;LAST BLOCK WAS LONG
EDEFST BSNT%,FKSWP,10,1 ;LAST BLOCK WAS LONG
EDEFST SCWAK%,FKSWP,11,1 ;SCJSYS IS WAKING
EDEFST SCBLK%,FKSWP,12,1 ;SCJSYS IS BLOCKED
;B13-17 AVAILABLE
EDEFST FKHST,FKSWP(FX),35,18 ;HISTORY
EDEFST FKGOLN,FKBSPW(FX),17,18 ;GOLST POSITION
FHV1==:1 ;BLOCK PRIORITY VALUES IN FKGOLN
FHV2==:2
FHV3==:3
FHV4==:4
FHV5==:5
FHV6==:6
FHV7==:7
EDEFST FKBLP,FKBSPW(FX),35,18 ;LIST OF FORKS IN BALSET HOLD
EDEFST FKJOX,FKJOB,35,36 ;WHOLE WORD
EDEFST FKJSB,FKJOB(FX),35,18 ;JSB PAGE (WITH FX)
EDEFST FKJS%,FKJOB,35,18 ; W/O
EDEFST FKJOBN,FKJOB(FX),17,18 ;JOB NUMBER
EDEFST FKJO%,FKJOB,17,18 ; W/O FX
EDEFST FKNRX,FKNR,35,36 ;WHOLE WORD
EDEFST FKXAGE,FKNR(FX),8,9 ;AGE AT LAST XGC
EDEFST FKAGE,FKNR(FX),17,9 ;CURRENT AGE
EDEFST FKWSS,FKNR(FX),35,18 ;WORKING SET SIZE
To: Page 10
Subj: My Part in the Address Space Project
EDEFST FKWSX,FKWSP,35,36 ;WHOLE WORD
EDEFST FKCSIZ,FKWSP(FX),35,18 ;CURRENT SIZE (NUMBER ASSIGNED PAGES)
EDEFST FKNWCE,FKWSP(FX),17,18 ;NUMBER ENTRIES IN WS CACHE
EDEFST FKCNX,FKCNO,35,36 ;WHOLE WORD
EDEFST FKPS2,FKCNO(FX),17,18 ;SECOND PSB PAGE
EDEFST FKCNN,FKCNO(FX),35,18 ;CORE NUMBER
EDEFST FKIBX,FKINTB,35,36 ;WORD
;FIELDS IN FKINT
EDEFST FKINX,FKINT,35,36 ;ALL BITS
EDEFST FKPS0,FKINT, 0,1 ;FKPSI0
EDEFST FKPS1,FKINT, 1,1 ;FKPSI1
EDEFST FKNWF,FKINT, 2,1 ;NEWFK%
EDEFST FKNWJ,FKINT, 3,1 ;NEWJB%
EDEFST FKIIF,FKINT, 4,1 ;PSIIF%
EDEFST FKIT1,FKINT, 5,1 ;PSIT1%
EDEFST FKIT2,FKINT, 6,1 ;PSIT2%
EDEFST FKSUS,FKINT, 7,1 ;SUSFK%
EDEFST FKIWT,FKINT, 8,1 ;PSIWT%
EDEFST FKILO,FKINT, 9,1 ;PSILO%
EDEFST FKFR1,FKINT,10,1 ;FRZB1%
EDEFST FKFR2,FKINT,11,1 ;FRZB2%
EDEFST FKFRJ,FKINT,12,1 ;JTFRZ%
EDEFST FKFRA,FKINT,13,1 ;ABFRZ%
EDEFST FKEFR,FKINT,11,2 ;FRZBB%
EDEFST FKFRZ,FKINT,13,4 ;FRZBA%
EDEFST FKICO,FKINT,14,1 ;PSICO%
EDEFST FKITL,FKINT,15,1 ;PSITL%
EDEFST FKIJT,FKINT,16,1 ;PSIJT%
EDEFST FKABK,FKINT,17,1 ;ADRBK%
EDEFST FKPRI,FKINT,18,1 ;PSIPRI
EDEFST FKISC,FKINT,20,1 ;PSISC%
EDEFST TRMCD,FKINT,35,9 ;TERM CODE BITS
FKPSI0==:1B0 ;INTERRUPT ATTENTION
FKPSI1==:1B1 ;IN PSI HANDLER OR INT DEFERRED
NEWFK%==:1B2 ;INITIATE NEW FORK - PI FLAG
NEWJB%==:1B3 ;INITIATE NEW JOB - PI FLAG
PSIIF%==:1B4 ;CHANNEL INTERRUPT REQUESTED IN FKINTB
PSIT1%==:1B5 ;TERMINAL CODE INTERRUPT, PHASE 1
PSIT2%==:1B6 ;TERMINAL CODE INTERRUPT, PHASE 2
SUSFK%==:1B7 ;SUSPEND FORK REQUEST
PSIWT%==:1B8 ;JOB WAS IN WAIT STATUS
PSILO%==:1B9 ;LOGOUT JOB REQUEST
FRZB1%==:1B10 ;DIRECT FREEZE HAS BEEN DONE
FRZB2%==:1B11 ;INDIRECT FREEZE HAS BEEN DONE
FRZBB%==:FRZB1%+FRZB2% ;BOTH BITS FOR EXTERNAL REFS
JTFRZ%==:1B12 ;CARRIER OFF ACTION REQUEST
ABFRZ%==:1B13 ;TIME LIMIT EXCEEDED INTERRUPT
FRZBA%==:ABFRZ%+JTFRZ%+FRZBB% ;ALL TYPES OF FREEZES
PSICO%==:1B14 ;CARRIER OFF ACTION REQUEST
To: Page 11
Subj: My Part in the Address Space Project
PSITL%==:1B15 ;TIME LIMIT EXCEEDED INTERRUPT
PSIJT%==:1B16 ;JSYS TRAP REQUEST
ADRBK%==:1B17 ;ADDRESS BREAK REQUEST
DEFSTR (TRMCOD,,35,9) ; FIELD IN FKINT OR PIMSK FOR TERM
;DEFS IN RH OF WORD
PSIPRI==:1B18 ;PRIORITY WORD SET.
PSISC%==:1B20 ;SCS% JSYS work queue enries for this fork
UNUSED==MASKB(21,26) ;UNUSED FKINT BITS
EDEFST FKSTX,FKSTAT,35,36 ;FULL WORD MASK
EDEFST FKSTR,FKSTAT,35,18 ;TEST ROUTINE
EDEFST FKSTD,FKSTAT,17,18 ;ADDITIONAL DATA
EDEFST FKST2,FKSTA2,35,36 ;EXTRA ADDITIONAL DATA WORD FOR SCHED TEST
EDEFST FK2DT,@FKSTA2(FX),35,36 ;TEST WORD CONTENTS (CFS)
EDEFST FKNB%,FKNBW,35,36 ;BALANCE SET WAIT
EDEFST FKJTN,FKJTQ,35,18 ;"NEXT-ENTRY" POINTERS FOR JSYS TRAP QUEUE
EDEFST FKJTP,FKJTQ,17,18 ;"PREVIOUS-ENTRY" POINTERS....
EDEFST FKTIM,FKTIME,35,36 ;WAIT TIME ON QUEUE (SCHED)
5.3 Interpretation of Fields
5.3.1 JSYS Trap Queue (FKJTQ)
In Release 5.1, the list of forks waiting for a JSYS trap lock
is doubly-linked through FKJTQ. Each entry contains the
address of another entry, and the head is linked in like any
other entry. Thus,
JTLST/ 0,,FKJTQ+i ;Pointer to first entry
FKJTQ+i/ JTLST,,FKJTQ+m
FKJTQ+m/ FKJTQ+i,,0
JTLSTL/ 0,,FKJTQ+m ;Pointer to last entry
An empty list looks like this:
JTLST/ 0
JTLSTL/ 0,,JTLST
Moving FKJTQ to an extended section would have required
doubling the size of the table. Instead, the entries now
contain only the fork index, as follows:
JTLST/ 0,,i
To: Page 12
Subj: My Part in the Address Space Project
FKJTQ+i/ NFKS,,m
FKJTQ+m/ i,,NFKS
JTLSTL/ m
The end of the list is now indicated by the value NFKS, which
is one greater than the largest legal value, and an empty list
looks like this:
JTLST/ 0,,NFKS
JTLSTL/ 0,,NFKS
This required a change in the argument to JTDEQ; it now
accepts a fork handle rather than the location of the fork's
link pointer.
The initialization code was changed to store NFKS into both the
head and tail words for an empty list. Both the enqueue
routine (JTENQ) and the dequeue routine (JTDEQ) were changed to
reflect the fact that the head is no longer linked into the
chain. Also, JTLST was renamed to JTRAPH, and JTLSTL was
renamed to JTRAPT.
5.3.2 Balance Set List
[Similar change to be made for FKBLP, details not complete]
5.4 Code Changes
5.4.1 Running in Section 1
Since the scheduler may be entered from any part of the
monitor, this project pushed us into isolating section-0-only
code. That work is described elsewhere in this document. Code
that touches the fork tables must run in section 1; it assumes
that the caller has already entered section 1, and does not
explicitly enter section 1 to protect itself.
[This work has not yet been done, so details are not
available.]
5.4.2 LOAD, STOR, etc.
All references to the fork tables must be made via the fields.
In many cases, these tables had been referenced directly in the
past, so massive edits have been made. In general, however,
the changes are transparent.
In an effort to simply the project, few changes were made in
interpretation of data, calling of subroutines, etc. This has
resulted in some operatons that we would have avoided if we
were designing from scratch. For example, if the old code had
To: Page 13
Subj: My Part in the Address Space Project
a set of (unknown) bits set in AC1, and did
IORM T1,FKSWP(FX)
the new code does
OPSTRM <IORM T1,>,FKSWX,(FX).
5.4.3 Indexing
According to the rules of extended addressing, an index
register in an EFIW is interpreted in global format. Thus the
(-m,,n) form can no longer be used when stepping through fork
tables. This required changes to several routines in SCHED.
6.0 XCALL and XJSP
The following macros allow code running in section 0 to enter
section 1 before calling routines that must run in section 1:
;Macro to be used by code in section 0 that is calling code in section 1.
;Will also work correctly if code is already in section 1. The caller enters
;section 1 before making the call, and returns to its original section after
;the call.
DEFINE XCALL (SEC,OFFSET)<
XMOVEI CX,.+3 ;GET WHERE TO RETURN TO
PUSH P,CX ;FIX UP THE STACK
XJRST [SEC,,OFFSET]> ;GO TO NEW ROUTINE
;Macro to be used by code in section 0 that is calling code in section 1
;via JSP AC,OFFSET. Will also work correctly if code is already in section 1.
;Called routine is expected to use JRST 0(AC) to return.
DEFINE XJSP (AC,SEC,OFFSET)<
XMOVEI AC,.+3 ;GET WHERE TO RETURN TO
PUSH P,AC
XJRST [SEC,,OFFSET] ;GO TO NEW ROUTINE
RET
>
[End of Address space project memos]
+---------------------------+
! ! ! ! ! ! ! ! i n t e r o f f i c e
! d ! i ! g ! i ! t ! a ! l !
! ! ! ! ! ! ! ! m e m o r a n d u m
+---------------------------+
Date: 10-Nov-84
From: Kevin W. Paetzold
Dept: TOPS-20 Monitor Group
DTN: 231-7430
LOC/MAIL STOP: MRO1-2/L10
Subject: Hints on Moving Code to XCDSEC
The following is a collection of some notes and hints that I came upon
while moving the ARPANET code to XCDSEC. Instead of moving this code a
piece at a time I moved all of it at once. This code was ideal for
moving into XCDSEC because it allready ran in MSEC1, most of its
storage is in INTSEC, and the interfaces to the code are pretty well
defined (eg. TTYSRV, DTB offsets, Hardware interrupts, etc...). Items
are in no special order (other than the order I thought about them).
Beware Indirect page map pointers during interrupt instructions. A
little known and often forgotten fact is that interrupt instructions
must be mapped through immediate pointers. XCDSEC pages are quite often
mapped through indirect pointers. Make sure you know which ones you
have. Since most interrupt instructions are XPCWs to other places this
is not a very bad restriction. The symptom is IO Page Fails somewhat
randomly.
IFIWs may no longer be your friends. Many symbols pointing to code in
XCDSEC get resolved by link to be XCDSEC,,SYMBOL (eg. 6,,ANXRSS). This
is a great feature when you are in DDT. However the code IFIW!ANXRSS
will now generate something like 400006,,ANXRSS. This is probably not
what you want since the above IFIW will index of AC 6 if referenced
using an indirect (which is quite often the case with dispatch tables).
(You would be surprised how often AC 6 was zero in the ARPANET code).
Some code in FORK does really "bad" things with the stack. It stores
stuff in the left half of the stack and then fixes it up before
returning. If the code is called from other than section one (ie.
XCDSEC) it tries to return to section one. The biggest culprit is
SKIIFA. Your code probably does not call this stuff but mine did.
I have almost all the ARPANET JSYS code running in XCDSEC. All the DTB
offsets for the TCP: device dispatch immediattely into XCDSEC via
XNENTs. MRETN (and all its friends) have been changed to allow
execution in XCDSEC. Due to a microcode bug/feature MRETN must run in
section one. It forces the PC into MSEC1 before restoring the ACs. I
did not encounter any PXCT problems but most of my PXCTs were word move
instructions. The really good PXCT stuff was done by IO.MAC and friends
in MSEC1.
I added a macro called "CALLX" which makes the calling of subroutines
in section one (or any other section) easier when the caller is in a
section like XCDSEC.
The most common problem is of course referencing XCDSEC stuff from
MSEC1 stuff and vice versa. The failures are usually pretty interesting
because the right half of the symbols are almost always in NRCOD or
XNCOD/NRCOD. The monitor quite often runs for a while after getting
into the wrong section. The dumps are pretty interesting but not very
hard if you are looking for this case. Very often you seem to end up in
either COMND or into a random MDISMS and into the scheduler.
While debuging the code in XCDSEC is quite often not paged in. This is
a real pain because EDDT does not deal with it very well. Patching in a
"CALL SWPMLK" at GOTSWM helps a lot.
Do not forget to look at Gunnar's R61SPC:EXTENDED-CODE.MEM.
[End of EXTENDED-HINTS.MEM]
1.0 MOVING DECNET-36 CODE TO EXTENDED SECTIONS
There are now two psects that put code in an extended (non-0 and -1)
section. The section is defined by the symbol XCDSEC, and is in the
current monitor equal to 6. They are XRCOD for resident code, and XNCOD
for swappable.
All of the resident parts of section 0/1 are mapped into XCDSEC, which
means that extended code can make local references to resident data,
e.g.
MOVE T1,TODCLK
is perfectly legal although TODCLK is defined in section 0/1.
Similarly, since resident code is also mapped into XCDSEC, it is legal
to
RETSKP
or to use any AC save or STKVAR/TRVAR functions.
The JSB, PSB and section-0/1 free space are also mapped into XCDSEC, as
well as swappable data. However, swappable code (NRCOD psect) is NOT
mapped into XCDSEC. Hence, if
CALL RUNJB0
is put into one of the extended psects (and RUNJB0 is in the swappable
monitor), then you are in for trouble! MACRO/LINK will cooperate to
decide that this is a legal reference, but you will end up jumping to
the location in XCDSEC that corresponds to RUNJB0 in section 0/1.
The layout of section 0/1 and XCDSEC are:
Section 0/1 XCDSEC
Resident code Resident code
Resident data Resident data
Swappable data Swappable data
JSB JSB
PSB PSB
Swappable code Extended resident/swappable code
Free space Free space
2.0 ASSEMBLING CODE INTO EXTENDED SECTIONS
When you want to assemble code into extended code, you use
XRESCD
for extended resident code, and
XSWAPCD
for extended swappable code.
3.0 EXTENDED ENTRY POINTS
If you have an entry point that is called from section-0/1, but that you
are putting into extended code, you should change the current
DNADSP: whatever
to
Page 2
XRENT DNADSP
whatever
The XRENT macro will define a label DNADSP in section-0/1 resident code,
which means that the sectio-0/1 code that calls DNADSP do not have to be
changed just because DNADSP is moved to an extended section. At DNADSP
a transfer into extended code is done, and a label XDNADSP in extended
code is defined. Upon return to the caller transfer back to section 1
will be automatic.
I.e. XRENT DNADSP will expand to
RESCD
DNADSP: XJRST [XCDSEC,,XDNADSP]
XRESCD
XDNADSP:
For swappable extended entry points, there is a similar macro XNENT that
works in the same way.
4.0 CALLING ROUTINES IN OTHER SECTIONS
If you are putting code in an extended section, and you need to call a
subroutine that has to run in section 1, (perhaps in the swappable
monitor), you can use
XCALL (MSEC1,RUNJB0)
XJSP (CX,MSEC1,ZZYXX)
XCALLRET (MSEC1,RUNJB0)
The same macros could of course be used to call an extended routine from
section 1 (in case the routine is not defined with an XRENT or XNENT).
However, these macros assume that you are not running in section 0. If
you are, perhaps in DTESRV, you have to transfer to section 1 before
using any of there macros.
If you want to switch between two psects in a code stream without
bothering to defined labels, you can use
XRESCD
MOVE T1,T2
TORESCD
CALL ASGRES
TOXRESCD
TORESCD will insert a jump to a location in RESCD, and move assembly to
RESCD. TOXRESCD will transfer back to extended resident code. There
are also macros TOSWAPCD and TOXSWAPCD.
5.0 SYMBOLS IN EXTENDED CODE
LINK will link the extended code psects into XCDSEC at link time. This
means that all extended symbols will be 30-bit values. Example:
XRESCD
ZZZ: MOVE T1,T2
and you get into EDDT, then
Page 3
ZZZ=6,,477312
which means that you can
ZZZ/ MOVE T1,T2
without having to include the section number.
6.0 EDDT
In general, EDDT will behave as for section-0/1 symbols. If you want to
patch an extended code psect, you can still use FFF. However, if you
get into EDDT right after BOOT you cannot set breakpoints in the
extended resident code immediately, since XRESCD is not yet mapped. You
have to set a breakpoint at GOTXCD, and when you get there, set the
breakpoints you want. GOTXCD is executed long before GOTSWM, so you
might want to set the initial breakpoint at GOTSWM instead: then the
section-0/1 swappable monitor is available as well.
7.0 DEFINING DATA
There is no provision for any extended data storage in addition to the
ones already existing. You either use RS/NR/RSI or whatever to put data
into section-0/1 (and therefore also in section 6), or you use RSE/NRE
to put data in an extended section. If you use the latter method, you
have to use global references. I.e.
NRE XMTCNT,1 ;Define 1 extended swappable word
then
MOVE T1,@[XMTCNT]
is the right way to get the data.
8.0 THINGS TO THINK ABOUT
Since all of the resident code is mapped into XCDSEC, it is perfectly
legal to make local calls (JRST or CALL) to subroutines in it. However,
if you call major parts in section-0/1 code, like the scheduler, or code
that may transfer into section 0, you are advised to either XCALL
(MSEC1,...) or transfer into section 1 (TORESCD) before calling.
[End of EXTENDED-CODE.MEM]