|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 19543 (0x4c57)
Types: TextFile
Notes: R1k Text-file segment
└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000
└─⟦cfc2e13cd⟧ »Space Info Vol 2«
└─⟦82fcddd9a⟧
└─⟦this⟧
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- VERDIX CORPORATION (C) COPYRIGHT 1988
-- 14130-A Sullyfield Circle Proprietary Information
-- Chantilly, Virginia 22021 Not to be Disclosed
--
-- FILE: V_KRN_CONF_I.A
--
-- UNIT: VADS Interface for Configuring the Tasking (or No
-- Tasking) Kernel Program for the M68000 Processor Family Cross
-- Targets.
--
-- PURPOSE: This package provides the interface to the VADS kernel used by
-- the package V_KRN_CONF. It contains types, objects,
-- and subprograms used to convey configuration information to and
-- from the kernel. It also contains a generic for an
-- interrupt handler linked into the kernel program and the kernel
-- subprograms that can be called from interrupt handler packages
-- linked into the kernel program.
--
-- This package consists of the following type definitions,
-- constants, generics and kernel subprogram interfaces:
-- 1. Startup table
-- 2. Interrupt vector table
-- 3. Configuration table
-- 4. Misc kernel program variables
-- 5. VADS supplied kernel ISRs
-- 6. Boot subprogram
-- 7. Execute subprogram
-- 8. Interrupt handler generic
-- 9 . Kernel service subprograms
--
-- NOTES: Do not modify this package.
--
-- This package may only be included in the kernel program.
-- It MAY NOT be included in the user or TDM programs.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Revision History:
--
-- 870706:2132 A00 Initial version.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
with SYSTEM; use SYSTEM;
with KRN_DEFS;
with V_I_TYPES;
with LINK_BLOCK;
with UNCHECKED_CONVERSION;
package V_KRN_CONF_I is
pragma suppress(ALL_CHECKS);
pragma suppress(EXCEPTION_TABLES);
--------------------------- #i1: Startup Table ---------------------------------
type startup_table_t is record
startup_stack_base : address;
-- specifies the address at which the
-- stack used during system
-- startup should begin. The stack
-- will grow from this address towards
-- lower memory.
--
-- Normally set to top of the heap/stack
-- area.
--
-- This stack is only used during startup.
startup_stack_size : integer;
-- is the size in BYTES of the startup
-- stack.
end record;
----------------------- #i2: Interrupt Vector Table ----------------------------
type interrupt_vector_table_t is array(natural range <>) of address;
untouchable_vector : constant address :=
system.MEMORY_ADDRESS(16#FFFF_FFFF#);
-------------------------- #i3: Configuration Table ----------------------------
subtype floating_point_control_t is v_i_types.floating_point_control_t;
type configuration_table_t is record
heap_stack_bottom : address;
heap_stack_top : address;
-- Bottom and top of memory where heaps
-- and stacks are allocated from.
-- Normally, HEAP_STACK_BOTTOM will be
-- set to first ram address following
-- end of kernel/TDM/user programs and
-- HEAP_STACK_TOP set to highest ram
-- location.
-- If HEAP_STACK_BOTTOM is set to the
-- constant,
-- v_krn_conf_i.END_OF_USER_PROGRAM,
-- then, this value is computed
-- dynamically by reading the user
-- program's group tables.
krn_stack_size : integer;
-- Size of kernel's stack.
intr_stack_size : integer;
-- Size of interrupt stack.
-- Stack size excludes room at bottom for
-- exception handling.
krn_exception_stack_size : natural;
-- Space below the bottom of the
-- interrupt handlers' stack or the
-- kernel task stacks for exception
-- unwinding.
task_supervisor_stack_size: integer;
-- Size of supervisor stack needed for
-- tasks executing in user state. The
-- task's supervisor stack is used for
-- kernel traps, numeric exception
-- handling and external interrupt
-- handling (before switching to interrupt
-- stack). Not used if
-- SUPERVISOR_TASKS_ENABLED parameter
-- is TRUE.
zero_stacks_enabled : boolean;
-- When true, at task create its
-- stack area is zeroed. Since the
-- stack area for all tasks is zeroed
-- at startup, normally only set to true
-- when using the debugger's "lt use"
-- command for dynamically terminated and
-- re-created tasks.
supervisor_tasks_enabled : boolean;
-- Set to TRUE to enable execution
-- of all user tasks in supervisor state.
master_state_enabled : boolean;
-- When TRUE, the kernel and
-- supervisor tasks use the master
-- stack instead of the interrupt stack.
-- Not applicable to mc68000 or mc68010
-- processors.
user_status : short_integer;
-- Setting of status register when user
-- program is started at completion of
-- kernel startup. If above
-- SUPERVISOR_TASKS_ENABLED parameter
-- is TRUE, then, user program is
-- started in supervisor state
-- irregardless of the S bit value for
-- this parameter. The above
-- MASTER_STATE_ENABLED parameter
-- is used to determine the setting
-- of the M bit.
disable_intr_priority : short_integer;
-- Setting of interrupt priority mask
-- within status register when interrupts
-- are disabled within kernel.
--
-- Note only bits 8 .. 10 are used.
vector_base_register : address;
-- starting location of the interrupt
-- vector table.
interrupt_vector_size : integer;
-- indicates the number of interrupt
-- vectors associated with this processor.
interrupt_vector_image : address;
-- starting location of the user's image
-- of the vector table.
floating_point_control : floating_point_control_t;
-- is the initial value for the fpcr
-- register on the MC68881.
time_slicing_enabled : boolean;
-- Set to TRUE to enable time slicing.
time_slice_interval : duration;
-- Task's initial time slice value.
time_slice_priority : priority;
-- If time slicing is enabled, then, it
-- is only applicable to tasks whose
-- priority is less than or equal to
-- this threshold priority.
idle_stack_size : integer;
-- specifies the size in BYTES of the
-- internal Idle Task's stack.
task_storage_size : integer;
-- specifies the size in BYTES of the
-- area allocated in the task control
-- block for user storage
pending_count : integer;
-- specifies the maximum number of kernel
-- service requests from an ISR (or
-- nested ISR) held pending until the
-- outer-most ISR completes. When
-- the outer-most ISR completes,
-- the kernel processes the queue of
-- pending requests.
end record;
type a_configuration_table_t is access configuration_table_t;
function to_a_configuration_table_t is new
unchecked_conversion(address, a_configuration_table_t);
untouchable_vbr : constant address :=
system.MEMORY_ADDRESS(16#FFFF_FFFF#);
no_vbr : constant address :=
system.MEMORY_ADDRESS(16#FFFF_FFFE#);
untouchable_table : constant address :=
system.MEMORY_ADDRESS(16#FFFF_FFFF#);
end_of_user_program : constant address :=
system.MEMORY_ADDRESS(16#FFFF_FFFF#);
--------------------- #i4: Misc Kernel Program Variables -----------------------
stack_limit: address;
pragma interface_name(stack_limit, "STACK_LIMIT");
-- Bottom of kernel/interrupt stack
user_link_block: link_block.link_block_t;
pragma interface_name(user_link_block, "USER_LINK_BLOCK");
-- Link block in user's program.
group_table: array (1..1) of character;
pragma interface_name(group_table, "GROUP_TABLE");
-- Table generated by the cross linker that defines the
-- memory locations of the different program groups (text, constant,
-- data, bss and void). Compiler defined dope vector information
-- precedes the group records.
------------------------- #i5: VADS Supplied ISRs ------------------------------
procedure bus_error_handler;
pragma interface(ADA, bus_error_handler);
pragma interface_name(bus_error_handler, "KRN_BUS_ERROR_HANDLER");
-- #2
procedure address_error_handler;
pragma interface(ADA, address_error_handler);
pragma interface_name(address_error_handler, "KRN_ADDRESS_ERROR_HANDLER");
-- #3
procedure zero_divide_handler;
pragma interface(ADA, zero_divide_handler);
pragma interface_name(zero_divide_handler, "KRN_ZERO_DIVIDE_HANDLER");
-- #5
procedure chk_instr_handler;
pragma interface(ADA, chk_instr_handler);
pragma interface_name(chk_instr_handler, "KRN_CHK_INSTR_HANDLER");
-- #6
procedure trapv_cc_instr_handler;
pragma interface(ADA, trapv_cc_instr_handler);
pragma interface_name(trapv_cc_instr_handler, "KRN_TRAPV_CC_INSTR_HANDLER");
-- #7
procedure float_error_handler;
pragma interface(ADA, float_error_handler);
pragma interface_name(float_error_handler, "KRN_FLOAT_ERROR_HANDLER");
-- #50, 52, 53, 54
procedure enter_from_user;
pragma interface(ADA, enter_from_user);
pragma interface_name(enter_from_user, "__KRN_ENTER_FROM_USER");
-- Kernel service trap
-- #32 - trap 0 (default)
------------------------- #i6: Boot Subprogram ---------------------------------
procedure v_boot(configuration_table_a: address);
-- specifies the user's configuration table
-- declared in the configuration package.
pragma interface(ADA, v_boot);
pragma interface_name(v_boot, "V_BOOT");
-- V_BOOT is called from the kernel startup program to
-- boot/initialize the kernel's tasking data structures.
------------------------ #i7: Execute Subprogram -------------------------------
procedure v_execute;
pragma interface(ADA, v_execute);
pragma interface_name(v_execute, "V_EXECUTE");
-- V_EXECUTE is called at the end of the kernel startup program to
-- start execution of the user program
---------------------- #i8: Interrupt Handler Generic --------------------------
generic
with procedure process_interrupt;
procedure interrupt_handler;
pragma share_body(interrupt_handler, FALSE);
-- Interrupt handler wrapper
--
-- Instantiate your handler by:
-- my_interrupt_handler is new
-- V_KRN_CONF_I.interrupt_handler(my_process_interrupt);
--
-- See generic body below for details.
----------------------- #i9: Kernel Service Subprograms ------------------------
subtype intr_status_t is krn_defs.intr_status_t;
procedure interrupts_disable(old_status: out intr_status_t);
pragma interface(ADA, interrupts_disable);
pragma interface_name(interrupts_disable, "__KRN_INTERRUPTS_DISABLE");
-- Disables interrupts by setting the Status Register's Interrupt
-- Priority Level (IPL) according to the DISABLE_INTR_PRIORITY
-- configuration parameter. The IPL is read before it is modified.
procedure interrupts_restore(restore_status: intr_status_t);
pragma interface(ADA, interrupts_restore);
pragma interface_name(interrupts_restore, "__KRN_INTERRUPTS_RESTORE");
-- Restores IPL using status returned by previous
-- DISABLE_INTERRUPTS invocation.
function replace_vector(iv: krn_defs.intr_vector_id_t;
isr: address) return address;
pragma interface(ADA, replace_vector);
pragma interface_name(replace_vector, "__KRN_REPLACE_VECTOR");
-- Replace interrupt vector
--
-- intr_num - interrupt vector number
-- handler_address - the address of the handler to be placed
-- in the interrupt vector table, NO_ADDR
-- implies replace with RTS kernel's null handler
--
-- Returns the address of the previously installed handler.
procedure isr_enter;
pragma interface(ADA, isr_enter);
pragma interface_name(isr_enter, "__KRN_ISR_ENTER");
-- Enter ISR handler
--
-- Increments the interrupt depth and switches to the interrupt stack
-- if the depth was incremented from 0 to 1.
--
-- Note: if MASTER_STATE is enabled for mc68020, the CPU already did
-- a switch from master to interrupt stack for an external interrupt.
--
-- The scratch registers (d0/d1/d2/d3/a0/a1) must be saved before calling
-- ISR_ENTER.
--
-- The address of the previous
-- stack is pushed on the new stack. This address is also pushed
-- for nested interrupts. The address points to last entry
-- pushed on the stack before the call.
--
--
procedure isr_complete;
pragma interface(ADA, isr_complete);
pragma interface_name(isr_complete, "__KRN_ISR_COMPLETE");
-- Complete ISR handler
--
-- ISR_COMPLETE expects stack to look as follows
-- 0 - return pc back to handler
-- 4 - pointer to previous stack (see below) (normally, the
-- address pushed on the new stack by ISR_ENTER)
--
-- where previous stack looks as follows:
-- 0 - d0/d1/d2/d3/a0/a1 (saved scratch registers)
-- 24 - handler's exception stack frame
--
-- ISR_ENTER must have been previously called for this interrupt.
--
--
-- Note: no return back to interrupt handler.
procedure post_alarm;
pragma interface(ADA, post_alarm);
pragma interface_name(post_alarm, "__KRN_POST_ALARM");
-- Post alarm
--
-- This procedure is called by the timer interrupt handler
-- (in V_KRN_CONF.V_TIMER_SUPPORT package) to notify the
-- RTS that the scheduled alarm has been reached.
end V_KRN_CONF_I;
with SYSTEM;
with MACHINE_CODE;
package body V_KRN_CONF_I is
pragma suppress(ALL_CHECKS);
pragma suppress(EXCEPTION_TABLES);
---------------------- #i8: Interrupt Handler Generic --------------------------
procedure interrupt_handler is
-- Interrupt handler wrapper
pragma implicit_code(off);
use machine_code;
begin
-- Save scratch registers
code_2'(movem_l, d0/d1/d2/d3/a0/a1, decr(sp));
call_0'(subp => V_KRN_CONF_I.isr_enter'ref);
-- Set up the frame pointer register (a6) so that the debugger and
-- exception unwinding can deduce this is the top of the stack
-- for an ISR.
--
-- By convention a6 = 0, => top of user program stack,
-- a6 = odd address => top of ISR stack
--
-- Furthermore, a6 = sp + 1. This allows the debugger to find the
-- saved value for a6 and the ISR's exception frame.
code_2'(move_l, a6, decr(sp));
code_2'(movea_l, sp, a6);
code_2'(addq_l, +1, a6);
-- The stack looks as follows:
-- 0 - saved a6 <-- a6 - 1
-- 4 - pointer to previous stack
--
-- Where previous stack is as follows:
-- 0 - d0/d1/d2/d3/a0/a1 (saved scratch registers)
-- 24 - ISR's exception stack frame
-- Note: for interrupt handlers linked into the kernel program,
-- its STACK_LIMIT already points to the bottom of the interrupt
-- stack. Therefore, don't need to switch as is necessary for handlers
-- linked into user program.
-- Process interrupt
call_0'(subp => process_interrupt'ref);
-- Restore frame pointer
code_2'(movea_l, incr(sp), a6);
-- Complete interrupt which also does a register restore
call_0'(subp => V_KRN_CONF_I.isr_complete'ref);
-- No return back here
end;
end V_KRN_CONF_I