This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

update constructor priorities


This is the start of updating the constructor priorities, as
originally discussed on ecos-devel last 18 Nov in the context of the
flashv2 merge. This patch updates cyg/infra/cyg_type.h in various
ways:

1) CYG_INIT_KERNEL and CYG_INIT_MEMALLOC are moved earlier, since they
should not depend on any peripherals and we want drivers to be able to
e.g. call malloc().

2) a bunch of new priorities are defined for buses and device classes.

3) CYG_INIT_DRIVERS is left for backwards compatibility but now
happens after the bus/device priorities.

4) then come CYG_INIT_IO and CYG_INIT_IO_FS, in pretty much their
current positions. This may change in future when/if these become more
precisely defined.

5) I have added a bit of a gap after CYG_INIT_IO_FS to allow for
future expansion/rearranging. Subsequent priorities remain in the same
order.

I think this is the best compromise possible right now between
backwards compatibility and where we want to head in the future. There
may be some breakage, especially related to CYG_INIT_DRIVERS. I'll be
going through the various anoncvs drivers and I/O subsystems to sort
things out.

I have also added macros to allow C code to define prioritized static
constructors, allowing you to write code like:

    void CYGBLD_ATTRIB_C_INIT_PRI(CYG_INIT_mypri)
    tom(void)
    {
        diag_printf("world");
    }

    void CYGBLD_ATTRIB_C_INIT_BEFORE(CYG_INIT_mypri)
    dick(void) 
    {
        diag_printf("Hello ");
    }

    void CYGBLD_ATTRIB_C_INIT_AFTER(CYG_INIT_mypri)
    harry(void)
    {
        diag_printf("!\n");
    }

This should allow us to eliminate various dummy C++ source files that
exist solely to create a prioritized static constructor. However,
there is a big caveat. The functionality was only added to gcc in
version 4.3, so the macros won't be defined if you are using an older
compiler. Obviously this is a big pain, and in retrospect we should
have got this sorted out back in the Cygnus days. For CortexM we
should be able to use these macros without problems. Arguably the same
is true for ARM targets that have been switched to arm-eabi. Things
are less clear-cut for i386, mips, m68k, powerpc and sh where people
may or may not start using the latest toolchain builds. Synth is
problematical since people may still be using older distributions.
For the other architectures, where we are not supplying new
toolchains, the C macros should probably be avoided for the time
being.

The __GNUC_VERSION__ macro had to be moved higher up the file for
things to work.

Bart

2009-02-04  Bart Veer  <bartv@ecoscentric.com>

	* include/cyg_type.h: add new static initialization priorities.
	Add macros to support static initialization from C as well as C++.

Index: cyg_type.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/infra/current/include/cyg_type.h,v
retrieving revision 1.26
diff -u -p -r1.26 cyg_type.h
--- cyg_type.h	29 Jan 2009 17:49:44 -0000	1.26
+++ cyg_type.h	4 Feb 2009 16:50:22 -0000
@@ -11,7 +11,7 @@
 // ####ECOSGPLCOPYRIGHTBEGIN####                                            
 // -------------------------------------------                              
 // This file is part of eCos, the Embedded Configurable Operating System.   
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
 //
 // eCos is free software; you can redistribute it and/or modify it under    
 // the terms of the GNU General Public License as published by the Free     
@@ -70,6 +70,18 @@
 // Also define externC for now - but it is deprecated
 #define externC __externC
 
+// Compiler version.
+#ifdef __GNUC__
+# if defined(__GNU_PATCHLEVEL__)
+#  define __GNUC_VERSION__ (__GNUC__ * 10000 \
+                             + __GNUC_MINOR__ * 100 \
+                             + __GNUC_PATCHLEVEL__)
+# else
+#  define __GNUC_VERSION__ (__GNUC__ * 10000 \
+                             + __GNUC_MINOR__ * 100)
+# endif
+#endif
+
 // -------------------------------------------------------------------------
 // The header <basetype.h> defines the base types used here. It is
 // supplied either by the target architecture HAL, or by the host
@@ -274,19 +286,71 @@ typedef cyg_haladdrword CYG_ADDRWORD;
 #define CYGBLD_ATTRIB_INIT_BEFORE( _pri_ ) CYGBLD_ATTRIB_INIT_PRI(_pri_-100)
 #define CYGBLD_ATTRIB_INIT_AFTER( _pri_ )  CYGBLD_ATTRIB_INIT_PRI(_pri_+100)
 
+#if defined(__GNUC__) && !defined(__cplusplus) && (__GNUC_VERSION__ >= 40300)
+// Equivalents of the above for C functions, available from gcc 4.3 onwards.
+# define CYGBLD_ATTRIB_C_INIT_PRI( _pri_)       __attribute__((constructor (_pri_)))
+# define CYGBLD_ATTRIB_C_INIT_BEFORE( _pri_ )   __attribute__((constructor (_pri_-100)))
+# define CYGBLD_ATTRIB_C_INIT_AFTER( _pri_ )    __attribute__((constructor (_pri_+100)))
+#endif
+
+// Start with initializing everything inside the cpu and the main memory.
 #define CYG_INIT_HAL                    10000
 #define CYG_INIT_SCHEDULER              11000
+#define CYG_INIT_IDLE_THREAD            11100
 #define CYG_INIT_INTERRUPTS             12000
-#define CYG_INIT_DRIVERS                13000
 #define CYG_INIT_CLOCK                  14000
-#define CYG_INIT_IDLE_THREAD            15000
 #define CYG_INIT_THREADS                16000
-#define CYG_INIT_KERNEL                 40000
-#define CYG_INIT_MEMALLOC               47000
+#define CYG_INIT_KERNEL                 19000
+#define CYG_INIT_MEMALLOC               20000
+// Now move on to I/O subsystems and device drivers. These can make use of
+// kernel and HAL functionality, and can dynamically allocate memory if
+// absolutely needed. For now they can also assume that diag_printf()
+// functionality is available, but that may change in future.
+//
+// Primary buses are ones very closely tied to the processor, e.g. PCI.
+#define CYG_INIT_BUS_PRIMARY            30000
+// Not yet: on some targets cyg_pci_init() has to be called very early
+// on for HAL diagnostics to work.
+// #define CYG_INIT_BUS_PCI                CYG_INIT_BUS_PRIMARY
+//
+// Secondary buses may hang off primary buses, e.g. USB host.
+#define CYG_INIT_BUS_SECONDARY          31000
+// Tertiary buses are everything else.
+#define CYG_INIT_BUS_TERTIARY           32000
+#define CYG_INIT_BUS_I2C                CYG_INIT_BUS_TERTIARY
+#define CYG_INIT_BUS_SPI                CYG_INIT_BUS_TERTIARY
+//
+// In future HAL diag initialization may happen at this point.
+//
+// Watchdogs and wallclocks often hang off a tertiary bus but
+// have no dependencies
+#define CYG_INIT_DEV_WATCHDOG           35000
+#define CYG_INIT_DEV_WALLCLOCK          36000
+// A primary block configuration can be initialized with no need
+// for per-unit configuration information.
+#define CYG_INIT_DEV_BLOCK_PRIMARY      37000
+#define CYG_INIT_DEV_FLASH              CYG_INIT_DEV_BLOCK_PRIMARY
+// Per-unit configuration data extracted from primary storage.
+// NOTE: for future use, not implemented yet.
+#define CYG_INIT_CONFIG                 38000
+// Secondary block devices may use per-unit configuration data
+// for e.g. interpreting partition layout. Few devices are expected
+// to fall into this category. Note that these devices, as well as
+// some char devices, may not actually be usable until interrupts
+// are enabled.
+#define CYG_INIT_DEV_BLOCK_SECONDARY    40000
+// Char devices are everything else: serial, ethernet, CAN, ...
+#define CYG_INIT_DEV_CHAR               41000
+// For backwards compatibility. Subject to change in future so
+// a CYG_INIT_DEV_ priority should be used instead.
+#define CYG_INIT_DRIVERS                48000
+// CYG_INIT_IO and CYG_INIT_IO_FS are poorly defined at present,
+// and may get reorganized in future.
 #define CYG_INIT_IO                     49000
 #define CYG_INIT_IO_FS                  50000
-#define CYG_INIT_LIBC                   52000
-#define CYG_INIT_COMPAT                 55000
+// The I/O subsystems and device drivers have been initialized.
+#define CYG_INIT_LIBC                   56000
+#define CYG_INIT_COMPAT                 58000
 #define CYG_INIT_APPLICATION            60000
 #define CYG_INIT_PREDEFAULT             65534
 #define CYG_INIT_DEFAULT                65535
@@ -317,15 +381,6 @@ typedef cyg_haladdrword CYG_ADDRWORD;
 // COMPILER-SPECIFIC STUFF
 
 #ifdef __GNUC__
-#if defined(__GNUC_PATCHLEVEL__)
-# define __GNUC_VERSION__ (__GNUC__ * 10000 \
-                            + __GNUC_MINOR__ * 100 \
-                            + __GNUC_PATCHLEVEL__)
-#else
-# define __GNUC_VERSION__ (__GNUC__ * 10000 \
-                            + __GNUC_MINOR__ * 100)
-#endif
-
 // Force a 'C' routine to be called like a 'C++' contructor
 # if !defined(CYGBLD_ATTRIB_CONSTRUCTOR)
 #  define CYGBLD_ATTRIB_CONSTRUCTOR __attribute__((constructor))


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]