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