DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦a69697fee⟧ TextFile

    Length: 19543 (0x4c57)
    Types: TextFile
    Notes: R1k Text-file segment

Derivation

└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000
    └─ ⟦cfc2e13cd⟧ »Space Info Vol 2« 
        └─⟦82fcddd9a⟧ 
            └─⟦this⟧ 

TextFile

-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
--   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