|
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: 11646 (0x2d7e) 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« └─⟦29ed5d28b⟧ └─⟦this⟧
------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- -- VERDIX CORPORATION (C) COPYRIGHT 1988 -- 14130-A Sullyfield Circle Proprietary Information -- Chantilly, Virginia 22021 Not to be Disclosed -- -- FILE: V_INTR_B.A -- -- UNITS: VADS/EXEC Interrupts Package Body. This version is for -- the M68000 Processor Family Cross Targets. -- -- PURPOSE: This file contains the body for the interrupt services supporting -- user-defined interrupt service routines (ISR's) and the -- getting/setting of interrupt status. -- -- Refer to V_INTERRUPTS package specification in V_VADS_EXEC.A for -- a detailed description of each service. -- -- Do not modify or recompile this package body. -- ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- -- Revision History: -- -- 880306:1430 B01 -- ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -- TARGET IS MC68020 with Machine_Code; with V_Cpu_Conf; with Link_Block; with V_I_Types; with Ada_Krn_I; with Ada_Krn_Defs; with System; use System; package body V_Interrupts is pragma Suppress (All_Checks); Stack_Limit : Address; pragma Interface_Name (Stack_Limit, "STACK_LIMIT"); -- Current task's bottom of stack limit. Debug_Block : Link_Block.Debug_Block_T; pragma Interface_Name (Debug_Block, "DEBUG_BLOCK"); -- Contains addresses of variables and ISR services in the kernel -- program. procedure Isr is pragma Implicit_Code (Off); use Machine_Code; begin -- Save scratch registers Code_2'(Movem_L, A0 / A1 / D0 / D1 / D2 / D3, Decr (Sp)); -- -- Enter ISR. -- -- The ENTER_ISR service -- 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 -- the ENTER_ISR service. -- -- Upon return, the address of the previous -- stack is pushed on the new stack. This address is also pushed -- for nested interrupts. The address points to the last entry -- pushed on the stack before the call. -- -- Get address of ENTER_ISR service in the kernel program Code_2'(Movea_L, Debug_Block.Intr_Enter'Ref, A0); Code_1'(Jsr, Indr (A0)); -- 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 -- Switch stack limit to bottom of interrupt stack. Code_2'(Move_L, Stack_Limit'Ref, Decr (Sp)); Code_2'(Movea_L, Debug_Block.Intr_Stack_Limit'Ref, A0); Code_2'(Move_L, Indr (A0), Stack_Limit'Ref); -- Process interrupt Call_0'(Subp => Interrupt_Handler'Ref); -- Restore stack limit Code_2'(Move_L, Incr (Sp), Stack_Limit'Ref); -- Restore frame pointer Code_2'(Movea_L, Incr (Sp), A6); -- Complete ISR -- -- complete_isr expects stack to look as follows -- 0 - return pc back to ISR -- 4 - pointer to previous stack (see below) (normally, the -- address pushed on the new stack by ENTER_ISR) -- -- where previous stack looks as follows: -- 0 - a0/a1/d0/d1/d2/d3 (saved scratch registers) -- 24 - ISR's exception stack frame -- -- Note: enter_isr must have been previosuly called for this ISR. -- -- Get address of COMPLETE_ISR service in kernel program Code_2'(Movea_L, Debug_Block.Intr_Complete'Ref, A0); Code_1'(Jsr, Indr (A0)); -- No return back here end Isr; procedure Fast_Isr is pragma Implicit_Code (Off); use Machine_Code; -- Fast version of ISR wrapper. -- -- This version is made faster by eliminating the call to the -- kernel service, ENTER_ISR, which switches to the the interrupt -- stack and increments the interrupt depth. Also the logic for -- saving, setting and restoring the current stack limit has been -- omitted. -- -- Restriction: -- The INTERRUPT_HANDLER procedure and the subprograms it calls -- must be compiled with "pragma suppress(ALL_CHECKS)" to suppress -- stack limit checking. -- -- If the kernel is configured to use the m68k's master state, then, -- FAST_ISR can not be used for software traps. It can still -- be used for external interrupts. begin -- Save scratch registers Code_2'(Movem_L, A0 / A1 / D0 / D1 / D2 / D3, Decr (Sp)); -- Emulate the omitted ENTER_ISR kernel service call by incrementing -- the kernel's interrupt depth count and pushing the current sp -- as the address of the previous stack. Code_2'(Movea_L, Debug_Block.Intr_Depth'Ref, A0); Code_2'(Addq_L, +1, Indr (A0)); Code_2'(Move_L, Sp, Decr (Sp)); -- 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 -- Process interrupt Call_0'(Subp => Interrupt_Handler'Ref); -- Restore frame pointer Code_2'(Movea_L, Incr (Sp), A6); -- Complete ISR -- -- complete_isr expects stack to look as follows -- 0 - return pc back to ISR -- 4 - pointer to previous stack (see below) (normally, the -- address pushed on the new stack by ENTER_ISR) -- -- where previous stack looks as follows: -- 0 - a0/a1/d0/d1/d2/d3 (saved scratch registers) -- 24 - ISR's exception stack frame -- -- Note: intr_depth must have been previosuly incremented for this ISR. -- -- Get address of COMPLETE_ISR service in kernel program Code_2'(Movea_L, Debug_Block.Intr_Complete'Ref, A0); Code_1'(Jsr, Indr (A0)); -- No return back here end Fast_Isr; procedure Float_Wrapper is pragma Implicit_Code (Off); use Machine_Code; begin -- No floating-point state save or restore for this target -- Process interrupt Call_0'(Subp => Float_Handler'Ref); Code_0'(Op => Rts); end Float_Wrapper; function Attach_Isr (Vector : in Vector_Id; Isr : in System.Address) return System.Address is use System; Prev_Vector : Address; begin Prev_Vector := Ada_Krn_I.Isr_Attach (Ada_Krn_Defs.Intr_Vector_Id_T (Vector), Isr); if Prev_Vector = Ada_Krn_Defs.Bad_Intr_Vector then raise Invalid_Interrupt_Vector; end if; return Prev_Vector; end Attach_Isr; procedure Attach_Isr (Vector : in Vector_Id; Isr : in System.Address) is use System; Prev_Vector : Address; begin Prev_Vector := Attach_Isr (Vector, Isr); end Attach_Isr; function Detach_Isr (Vector : in Vector_Id) return System.Address is use System; Prev_Vector : Address; begin Prev_Vector := Ada_Krn_I.Isr_Detach (Ada_Krn_Defs.Intr_Vector_Id_T (Vector)); if Prev_Vector = Ada_Krn_Defs.Bad_Intr_Vector then raise Invalid_Interrupt_Vector; end if; return Prev_Vector; end Detach_Isr; procedure Detach_Isr (Vector : in Vector_Id) is use System; Prev_Vector : Address; begin Prev_Vector := Detach_Isr (Vector); end Detach_Isr; function Get_Isr (Vector : in Vector_Id) return System.Address is use System; Isr : Address; begin Isr := Ada_Krn_I.Isr_Get (Ada_Krn_Defs.Intr_Vector_Id_T (Vector)); if Isr = Ada_Krn_Defs.Bad_Intr_Vector then raise Invalid_Interrupt_Vector; end if; return Isr; end Get_Isr; function Get_Ivt return System.Address is begin return Ada_Krn_I.Isr_Get_Ivt; end Get_Ivt; function Current_Interrupt_Status return Interrupt_Status_T is Status : Ada_Krn_Defs.Intr_Status_T; begin Ada_Krn_I.Interrupts_Get_Status (Status); return Interrupt_Status_T (Status); end Current_Interrupt_Status; function Set_Interrupt_Status (New_Status : in Interrupt_Status_T) return Interrupt_Status_T is Old_Status : Ada_Krn_Defs.Intr_Status_T; begin Ada_Krn_I.Interrupts_Set_Status (Old_Status, Ada_Krn_Defs.Intr_Status_T (New_Status)); return Interrupt_Status_T (Old_Status); end Set_Interrupt_Status; function Current_Supervisor_State return Boolean is begin return Ada_Krn_I.Task_Get_Supervisor_State; end Current_Supervisor_State; procedure Enter_Supervisor_State is begin Ada_Krn_I.Task_Enter_Supervisor_State; end Enter_Supervisor_State; procedure Leave_Supervisor_State is begin Ada_Krn_I.Task_Leave_Supervisor_State; end Leave_Supervisor_State; function Set_Supervisor_State (New_State : in Boolean) return Boolean is Old_State : Boolean := Ada_Krn_I.Task_Get_Supervisor_State; begin if New_State /= Old_State then if New_State then Ada_Krn_I.Task_Enter_Supervisor_State; else Ada_Krn_I.Task_Leave_Supervisor_State; end if; end if; return Old_State; end Set_Supervisor_State; end V_Interrupts;