From e5c73177bf31ed98d3dc9887eaa5836cd0a6148a Mon Sep 17 00:00:00 2001 From: Arnaud Charlet Date: Tue, 9 Sep 2008 15:01:51 +0200 Subject: [PATCH] Makefile.in: Switch VxWorks to s-interr-hwint.adb. * gcc-interface/Makefile.in: Switch VxWorks to s-interr-hwint.adb. * s-interr-vxworks.adb: Renamed to s-interr-hwint.adb * s-interr-hwint.adb: New file. * s-osinte-vxworks.ads, s-osinte-vxworks.adb: Add new functions needed by s-interr-hwint.adb. * s-osinte-vxworks-kernel.adb: New file. From-SVN: r140147 --- gcc/ada/ChangeLog | 18 +- gcc/ada/gcc-interface/Makefile.in | 24 +- ...-interr-vxworks.adb => s-interr-hwint.adb} | 69 +++-- gcc/ada/s-osinte-vxworks-kernel.adb | 251 ++++++++++++++++++ gcc/ada/s-osinte-vxworks.adb | 71 ++++- gcc/ada/s-osinte-vxworks.ads | 44 +++ 6 files changed, 425 insertions(+), 52 deletions(-) rename gcc/ada/{s-interr-vxworks.adb => s-interr-hwint.adb} (95%) create mode 100644 gcc/ada/s-osinte-vxworks-kernel.adb diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 0ce56a66a97..8453c2eb964 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,17 @@ +2008-09-09 Arnaud Charlet + Joel Sherrill + + * gcc-interface/Makefile.in: Switch VxWorks to s-interr-hwint.adb. + + * s-interr-vxworks.adb: Renamed to s-interr-hwint.adb + + * s-interr-hwint.adb: New file. + + * s-osinte-vxworks.ads, s-osinte-vxworks.adb: Add new functions + needed by s-interr-hwint.adb. + + * s-osinte-vxworks-kernel.adb: New file. + 2008-09-05 Joel Sherrill * s-stchop-rtems.adb: Add file missed in early commit. Already @@ -28,8 +42,8 @@ * checks.adb (Determine_Range): Deal with values that might be invalid - * opt.adb, opt.ads (Assume_No_Invalid_Values[_Config]): New configuration - switches. + * opt.adb, opt.ads (Assume_No_Invalid_Values[_Config]): New + configuration switches. * par-prag.adb: Dummy entry for pragma Assume_No_Invalid_Values diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in index 28763d7872f..5a35c07c4d8 100644 --- a/gcc/ada/gcc-interface/Makefile.in +++ b/gcc/ada/gcc-interface/Makefile.in @@ -391,10 +391,10 @@ ifeq ($(strip $(filter-out m68k% wrs vx%,$(targ))),) a-intnam.ads 0); + of Binary_Semaphore_Id := (others => 0); -- Array of binary semaphores associated with vectored interrupts -- Note that the last bound should be Max_HW_Interrupt, but this will raise -- Storage_Error if Num_HW_Interrupts is null, so use an extra 4 bytes @@ -213,11 +213,12 @@ package body System.Interrupts is -- Always consider a null handler as registered. procedure Notify_Interrupt (Param : System.Address); + pragma Convention (C, Notify_Interrupt); -- Umbrella handler for vectored interrupts (not signals) procedure Install_Umbrella_Handler (Interrupt : HW_Interrupt; - Handler : Interfaces.VxWorks.VOIDFUNCPTR); + Handler : System.OS_Interface.Interrupt_Handler); -- Install the runtime umbrella handler for a vectored hardware -- interrupt @@ -490,16 +491,12 @@ package body System.Interrupts is procedure Install_Umbrella_Handler (Interrupt : HW_Interrupt; - Handler : Interfaces.VxWorks.VOIDFUNCPTR) + Handler : System.OS_Interface.Interrupt_Handler) is - use Interfaces.VxWorks; - Vec : constant Interrupt_Vector := - INUM_TO_IVEC (Interfaces.VxWorks.int (Interrupt)); + Interrupt_Number_To_Vector (int (Interrupt)); - Stat : Interfaces.VxWorks.STATUS; - pragma Unreferenced (Stat); - -- ??? shouldn't we test Stat at least in a pragma Assert? + Status : int; begin -- Only install umbrella handler when no Ada handler has already been @@ -508,7 +505,10 @@ package body System.Interrupts is -- wrapper generated by intConnect for each interrupt number. if not Handler_Installed (Interrupt) then - Stat := intConnect (Vec, Handler, System.Address (Interrupt)); + Status := + Interrupt_Connect (Vec, Handler, System.Address (Interrupt)); + pragma Assert (Status = 0); + Handler_Installed (Interrupt) := True; end if; end Install_Umbrella_Handler; @@ -618,20 +618,20 @@ package body System.Interrupts is -- on which it pends once it's been started. This routine determines -- The appropriate semaphore and issues a semGive call, waking -- the server task. When a handler is unbound, - -- System.Interrupts.Unbind_Handler issues a semFlush, and the - -- server task deletes its semaphore and terminates. + -- System.Interrupts.Unbind_Handler issues a Binary_Semaphore_Flush, + -- and the server task deletes its semaphore and terminates. procedure Notify_Interrupt (Param : System.Address) is Interrupt : constant Interrupt_ID := Interrupt_ID (Param); - Id : constant SEM_ID := Semaphore_ID_Map (Interrupt); + Id : constant Binary_Semaphore_Id := Semaphore_ID_Map (Interrupt); - Discard_Result : STATUS; - pragma Unreferenced (Discard_Result); + Status : int; begin if Id /= 0 then - Discard_Result := semGive (Id); + Status := Binary_Semaphore_Release (Id); + pragma Assert (Status = 0); end if; end Notify_Interrupt; @@ -764,15 +764,13 @@ package body System.Interrupts is -------------------- procedure Unbind_Handler (Interrupt : Interrupt_ID) is - S : STATUS; - use type STATUS; - + Status : int; begin -- Flush server task off semaphore, allowing it to terminate - S := semFlush (Semaphore_ID_Map (Interrupt)); - pragma Assert (S = 0); + Status := Binary_Semaphore_Flush (Semaphore_ID_Map (Interrupt)); + pragma Assert (Status = 0); end Unbind_Handler; -------------------------------- @@ -890,8 +888,7 @@ package body System.Interrupts is (To_Ada (Server_ID (Interrupt)))) then Interrupt_Access_Hold := - new Interrupt_Server_Task - (Interrupt, semBCreate (SEM_Q_FIFO, SEM_EMPTY)); + new Interrupt_Server_Task (Interrupt, Binary_Semaphore_Create); Server_ID (Interrupt) := To_System (Interrupt_Access_Hold.all'Identity); end if; @@ -988,7 +985,7 @@ package body System.Interrupts is (To_Ada (Server_ID (Interrupt))) then Interrupt_Access_Hold := new Interrupt_Server_Task - (Interrupt, semBCreate (SEM_Q_FIFO, SEM_EMPTY)); + (Interrupt, Binary_Semaphore_Create); Server_ID (Interrupt) := To_System (Interrupt_Access_Hold.all'Identity); end if; @@ -1046,9 +1043,7 @@ package body System.Interrupts is Tmp_Handler : Parameterless_Handler; Tmp_ID : Task_Id; Tmp_Entry_Index : Task_Entry_Index; - S : STATUS; - - use type STATUS; + Status : int; begin System.Tasking.Utilities.Make_Independent; @@ -1058,8 +1053,8 @@ package body System.Interrupts is -- Pend on semaphore that will be triggered by the -- umbrella handler when the associated interrupt comes in - S := semTake (Int_Sema, WAIT_FOREVER); - pragma Assert (S = 0); + Status := Binary_Semaphore_Obtain (Int_Sema); + pragma Assert (Status = 0); if User_Handler (Interrupt).H /= null then @@ -1091,9 +1086,9 @@ package body System.Interrupts is -- Delete the associated semaphore - S := semDelete (Int_Sema); + Status := Binary_Semaphore_Delete (Int_Sema); - pragma Assert (S = 0); + pragma Assert (Status = 0); -- Set status for the Interrupt_Manager diff --git a/gcc/ada/s-osinte-vxworks-kernel.adb b/gcc/ada/s-osinte-vxworks-kernel.adb new file mode 100644 index 00000000000..ed62f802953 --- /dev/null +++ b/gcc/ada/s-osinte-vxworks-kernel.adb @@ -0,0 +1,251 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS -- +-- -- +-- S Y S T E M . O S _ I N T E R F A C E -- +-- -- +-- B o d y -- +-- -- +-- Copyright (C) 1997-2008, Free Software Foundation, Inc. -- +-- -- +-- GNARL is free software; you can redistribute it and/or modify it under -- +-- terms of the GNU General Public License as published by the Free Soft- -- +-- ware Foundation; either version 2, or (at your option) any later ver- -- +-- sion. GNARL is distributed in the hope that it will be useful, but WITH- -- +-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- +-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- +-- for more details. You should have received a copy of the GNU General -- +-- Public License distributed with GNARL; see file COPYING. If not, write -- +-- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, -- +-- Boston, MA 02110-1301, USA. -- +-- -- +-- As a special exception, if other files instantiate generics from this -- +-- unit, or you link this unit with other files to produce an executable, -- +-- this unit does not by itself cause the resulting executable to be -- +-- covered by the GNU General Public License. This exception does not -- +-- however invalidate any other reasons why the executable file might be -- +-- covered by the GNU Public License. -- +-- -- +-- GNARL was developed by the GNARL team at Florida State University. -- +-- Extensive contributions were provided by Ada Core Technologies, Inc. -- +-- -- +------------------------------------------------------------------------------ + +-- This is the VxWorks version + +-- This package encapsulates all direct interfaces to OS services that are +-- needed by children of System. + +pragma Polling (Off); +-- Turn off polling, we do not want ATC polling to take place during tasking +-- operations. It causes infinite loops and other problems. + +package body System.OS_Interface is + + use type Interfaces.C.int; + + Low_Priority : constant := 255; + -- VxWorks native (default) lowest scheduling priority + + ---------- + -- kill -- + ---------- + + function kill (pid : t_id; sig : Signal) return int is + begin + return System.VxWorks.Ext.kill (pid, int (sig)); + end kill; + + ------------- + -- sigwait -- + ------------- + + function sigwait + (set : access sigset_t; + sig : access Signal) return int + is + Result : int; + + function sigwaitinfo + (set : access sigset_t; sigvalue : System.Address) return int; + pragma Import (C, sigwaitinfo, "sigwaitinfo"); + + begin + Result := sigwaitinfo (set, System.Null_Address); + + if Result /= -1 then + sig.all := Signal (Result); + return 0; + else + sig.all := 0; + return errno; + end if; + end sigwait; + + ----------------- + -- To_Duration -- + ----------------- + + function To_Duration (TS : timespec) return Duration is + begin + return Duration (TS.ts_sec) + Duration (TS.ts_nsec) / 10#1#E9; + end To_Duration; + + ----------------- + -- To_Timespec -- + ----------------- + + function To_Timespec (D : Duration) return timespec is + S : time_t; + F : Duration; + + begin + S := time_t (Long_Long_Integer (D)); + F := D - Duration (S); + + -- If F is negative due to a round-up, adjust for positive F value + + if F < 0.0 then + S := S - 1; + F := F + 1.0; + end if; + + return timespec'(ts_sec => S, + ts_nsec => long (Long_Long_Integer (F * 10#1#E9))); + end To_Timespec; + + ------------------------- + -- To_VxWorks_Priority -- + ------------------------- + + function To_VxWorks_Priority (Priority : int) return int is + begin + return Low_Priority - Priority; + end To_VxWorks_Priority; + + -------------------- + -- To_Clock_Ticks -- + -------------------- + + -- ??? - For now, we'll always get the system clock rate since it is + -- allowed to be changed during run-time in VxWorks. A better method would + -- be to provide an operation to set it that so we can always know its + -- value. + + -- Another thing we should probably allow for is a resultant tick count + -- greater than int'Last. This should probably be a procedure with two + -- output parameters, one in the range 0 .. int'Last, and another + -- representing the overflow count. + + function To_Clock_Ticks (D : Duration) return int is + Ticks : Long_Long_Integer; + Rate_Duration : Duration; + Ticks_Duration : Duration; + + begin + if D < 0.0 then + return -1; + end if; + + -- Ensure that the duration can be converted to ticks + -- at the current clock tick rate without overflowing. + + Rate_Duration := Duration (sysClkRateGet); + + if D > (Duration'Last / Rate_Duration) then + Ticks := Long_Long_Integer (int'Last); + else + Ticks_Duration := D * Rate_Duration; + Ticks := Long_Long_Integer (Ticks_Duration); + + if Ticks_Duration > Duration (Ticks) then + Ticks := Ticks + 1; + end if; + + if Ticks > Long_Long_Integer (int'Last) then + Ticks := Long_Long_Integer (int'Last); + end if; + end if; + + return int (Ticks); + end To_Clock_Ticks; + + ----------------------------- + -- Binary_Semaphore_Create -- + ----------------------------- + + function Binary_Semaphore_Create return Binary_Semaphore_Id is + begin + return Binary_Semaphore_Id (semBCreate (SEM_Q_FIFO, SEM_EMPTY)); + end Binary_Semaphore_Create; + + ----------------------------- + -- Binary_Semaphore_Delete -- + ----------------------------- + + function Binary_Semaphore_Delete (ID : Binary_Semaphore_Id) return int is + begin + return semDelete (SEM_ID (ID)); + end Binary_Semaphore_Delete; + + ----------------------------- + -- Binary_Semaphore_Obtain -- + ----------------------------- + + function Binary_Semaphore_Obtain (ID : Binary_Semaphore_Id) return int is + begin + return semTake (SEM_ID (ID), WAIT_FOREVER); + end Binary_Semaphore_Obtain; + + ------------------------------ + -- Binary_Semaphore_Release -- + ------------------------------ + + function Binary_Semaphore_Release (ID : Binary_Semaphore_Id) return int is + begin + return semGive (SEM_ID (ID)); + end Binary_Semaphore_Release; + + ---------------------------- + -- Binary_Semaphore_Flush -- + ---------------------------- + + function Binary_Semaphore_Flush (ID : Binary_Semaphore_Id) return int is + begin + return semFlush (SEM_ID (ID)); + end Binary_Semaphore_Flush; + + ----------------------- + -- Interrupt_Connect -- + ----------------------- + + function Interrupt_Connect + (Vector : Interrupt_Vector; + Handler : Interrupt_Handler; + Parameter : System.Address := System.Null_Address) return int + is + function intConnect + (vector : Interrupt_Vector; + handler : Interrupt_Handler; + parameter : System.Address) return int; + pragma Import (C, intConnect, "intConnect"); + + begin + return intConnect (Vector, Handler, Parameter); + end Interrupt_Connect; + + -------------------------------- + -- Interrupt_Number_To_Vector -- + -------------------------------- + + function Interrupt_Number_To_Vector + (intNum : int) return Interrupt_Vector + is + function INUM_TO_IVEC (intNum : int) return Interrupt_Vector; + pragma Import (C, INUM_TO_IVEC, "__gnat_inum_to_ivec"); + + begin + return INUM_TO_IVEC (intNum); + end Interrupt_Number_To_Vector; + +end System.OS_Interface; diff --git a/gcc/ada/s-osinte-vxworks.adb b/gcc/ada/s-osinte-vxworks.adb index 312fabaaeb6..b0fd06b10ef 100644 --- a/gcc/ada/s-osinte-vxworks.adb +++ b/gcc/ada/s-osinte-vxworks.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1997-2007, Free Software Foundation, Inc. -- +-- Copyright (C) 1997-2008, Free Software Foundation, Inc. -- -- -- -- GNARL is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -170,4 +170,73 @@ package body System.OS_Interface is return int (Ticks); end To_Clock_Ticks; + ----------------------------- + -- Binary_Semaphore_Create -- + ----------------------------- + + function Binary_Semaphore_Create return Binary_Semaphore_Id is + begin + return Binary_Semaphore_Id (semBCreate (SEM_Q_FIFO, SEM_EMPTY)); + end Binary_Semaphore_Create; + + ----------------------------- + -- Binary_Semaphore_Delete -- + ----------------------------- + + function Binary_Semaphore_Delete (ID : Binary_Semaphore_Id) return int is + begin + return semDelete (SEM_ID (ID)); + end Binary_Semaphore_Delete; + + ----------------------------- + -- Binary_Semaphore_Obtain -- + ----------------------------- + + function Binary_Semaphore_Obtain (ID : Binary_Semaphore_Id) return int is + begin + return semTake (SEM_ID (ID), WAIT_FOREVER); + end Binary_Semaphore_Obtain; + + ------------------------------ + -- Binary_Semaphore_Release -- + ------------------------------ + + function Binary_Semaphore_Release (ID : Binary_Semaphore_Id) return int is + begin + return semGive (SEM_ID (ID)); + end Binary_Semaphore_Release; + + ---------------------------- + -- Binary_Semaphore_Flush -- + ---------------------------- + + function Binary_Semaphore_Flush (ID : Binary_Semaphore_Id) return int is + begin + return semFlush (SEM_ID (ID)); + end Binary_Semaphore_Flush; + + ----------------------- + -- Interrupt_Connect -- + ----------------------- + + function Interrupt_Connect + (Vector : Interrupt_Vector; + Handler : Interrupt_Handler; + Parameter : System.Address := System.Null_Address) return int + is + pragma Unreferenced (Vector, Handler, Parameter); + begin + return 0; + end Interrupt_Connect; + + -------------------------------- + -- Interrupt_Number_To_Vector -- + -------------------------------- + + function Interrupt_Number_To_Vector + (intNum : int) return Interrupt_Vector is + begin + return Interrupt_Vector (intNum); + end Interrupt_Number_To_Vector; + end System.OS_Interface; diff --git a/gcc/ada/s-osinte-vxworks.ads b/gcc/ada/s-osinte-vxworks.ads index 35baabb6924..532bded849d 100644 --- a/gcc/ada/s-osinte-vxworks.ads +++ b/gcc/ada/s-osinte-vxworks.ads @@ -432,6 +432,50 @@ package System.OS_Interface is pragma Import (C, semFlush, "semFlush"); -- Release all threads blocked on the semaphore + ------------------------------------------------------------ + -- Binary Semaphore Wrapper to Support Interrupt Tasks -- + ------------------------------------------------------------ + + type Binary_Semaphore_Id is new Long_Integer; + + function Binary_Semaphore_Create return Binary_Semaphore_Id; + pragma Inline (Binary_Semaphore_Create); + + function Binary_Semaphore_Delete (ID : Binary_Semaphore_Id) return int; + pragma Inline (Binary_Semaphore_Delete); + + function Binary_Semaphore_Obtain (ID : Binary_Semaphore_Id) return int; + pragma Inline (Binary_Semaphore_Obtain); + + function Binary_Semaphore_Release (ID : Binary_Semaphore_Id) return int; + pragma Inline (Binary_Semaphore_Release); + + function Binary_Semaphore_Flush (ID : Binary_Semaphore_Id) return int; + pragma Inline (Binary_Semaphore_Flush); + + ------------------------------------------------------------ + -- Hardware Interrupt Wrappers to Support Interrupt Tasks -- + ------------------------------------------------------------ + + type Interrupt_Handler is access procedure (parameter : System.Address); + pragma Convention (C, Interrupt_Handler); + + type Interrupt_Vector is new System.Address; + + function Interrupt_Connect + (Vector : Interrupt_Vector; + Handler : Interrupt_Handler; + Parameter : System.Address := System.Null_Address) return int; + pragma Inline (Interrupt_Connect); + -- Use this to set up an user handler. The routine installs a + -- a user handler which is invoked after RTEMS has saved enough + -- context for a high-level language routine to be safely invoked. + + function Interrupt_Number_To_Vector (intNum : int) return Interrupt_Vector; + pragma Inline (Interrupt_Number_To_Vector); + -- Convert a logical interrupt number to the hardware interrupt vector + -- number used to connect the interrupt. + private type sigset_t is new unsigned_long_long;