Overview   API Reference  

devices.hpp

00001 #if !defined(__DEVICES_HPP__)
00002 #define __DEVICES_HPP__
00003 
00004 //
00005 // local includes
00006 //
00007 #include "core/common.hpp"
00008 
00009 //
00010 // forward declarations
00011 //
00012 struct config_node;
00013 struct machine_base;
00014 
00020 template <typename DeviceT=void>
00021 struct device_descriptors
00022 {
00023     typedef DeviceT device_type;
00024     typedef device_type *(*create_func_ptr)(machine_base &, config_node &);
00025     typedef int (*multi_create_func_ptr)(vector<device_type *> &, machine_base &, config_node &);
00026 
00031     enum flags_constants
00032     {
00034         SINGLETON = 0x01,
00036         ALL_MASK  = SINGLETON
00037     };
00038 
00039     typedef bitmask<typename uint_value_t<ALL_MASK | L4VMM_ALL_MASK>::least> flags;
00040 
00041     static_assert(integer_traits<typename flags::word_type>::const_max >= (ALL_MASK | L4VMM_ALL_MASK),
00042                   "flags's max value is too small");
00043 
00047     struct descriptor
00048     {
00053         create_func_ptr create_func;
00054 
00060         multi_create_func_ptr multi_create_func;
00061 
00065         flags device_flags,
00066 
00070               l4vmm_flags;
00071 
00072         inline descriptor(void)
00073             : create_func(nullptr), multi_create_func(nullptr),
00074               device_flags(0), l4vmm_flags(0)
00075         {}
00076 
00077         inline descriptor(const create_func_ptr create_func,
00078                           const multi_create_func_ptr multi_create_func,
00079                           const flags device_flags, const flags l4vmm_flags)
00080             : create_func(create_func), multi_create_func(multi_create_func),
00081               device_flags(device_flags), l4vmm_flags(l4vmm_flags)
00082         {}
00083 
00084         int update(const descriptor &other);
00085     };
00086 
00087     typedef map<string, descriptor> collection_type;
00088 
00089   protected:
00093     static device_descriptors &instance;
00094 
00098     collection_type descriptors;
00099 
00100   public:
00101     static inline const descriptor *get(const string &name)
00102     {
00103         typename collection_type::const_iterator it=instance.descriptors.find(name);
00104         return (it != endof(instance.descriptors)) ? &it->second : nullptr;
00105     }
00106 
00107     static int register_device(const string &name, const descriptor &descriptor);
00108     static void print(const char *header=nullptr);
00109 };
00110 
00111 //
00112 // extern template declarations to prevent implicit instantiations
00113 //
00114 extern template struct device_descriptors<>;
00115 extern template struct device_descriptors<struct device>;
00116 extern template struct device_descriptors<struct pci_device>;
00117 
00118 //
00119 // dummy struct to execute code to register devices (if linked at all)
00120 //     during library initialization. used with the appropriate init priority.
00121 //
00122 template <typename DeviceT>
00123 struct register_device
00124 {
00125     typedef device_descriptors<DeviceT> descriptors_type;
00126     typedef typename descriptors_type::descriptor descriptor_type;
00127 
00128     inline register_device(const char *name,
00129                            const typename descriptors_type::create_func_ptr create_func,
00130                            const typename descriptors_type::flags device_flags=0,
00131                            const typename descriptors_type::flags l4vmm_flags=0)
00132     {
00133         descriptors_type::register_device(name, descriptor_type(create_func, nullptr,
00134                                                                 device_flags, l4vmm_flags));
00135     }
00136 
00137     inline register_device(const char *name,
00138                            const typename descriptors_type::multi_create_func_ptr multi_create_func,
00139                            const typename descriptors_type::flags device_flags=0,
00140                            const typename descriptors_type::flags l4vmm_flags=0)
00141     {
00142         descriptors_type::register_device(name, descriptor_type(nullptr, multi_create_func,
00143                                                                 device_flags, l4vmm_flags));
00144     }
00145 };
00146 
00147 //
00148 // register macros to be used in device implementations
00149 //
00150 #if (__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ <= 3)
00151     //
00152     // FIXME: GCC3
00153     // special version for GCC 3.3, which cannot handle attributes before
00154     //     variable declaration ...
00155     //
00156     #define __REGISTER_DEVICE(device_type, name, args...)               \
00157         static const register_device<device_type>                       \
00158             register_ ## name ## _device(L4_stringify(name), args)      \
00159                 __attribute__((__used__, __init_priority__(2000)));
00160 #elif defined(__GNUC__)
00161     //
00162     // ... while newer versions really need it there. hmm.
00163     //
00164     #define __REGISTER_DEVICE(device_type, name, args...)               \
00165         static const register_device<device_type>                       \
00166             __attribute__((__used__, __init_priority__(2000)))          \
00167                 register_ ## name ## _device(L4_stringify(name), args);
00168 #else
00169     #error define __REGISTER_DEVICE for your compiler first
00170 #endif
00171 
00172 #define REGISTER_DEVICE(name, args...)      __REGISTER_DEVICE(device, name, args)
00173 #define REGISTER_PCI_DEVICE(name, args...)  __REGISTER_DEVICE(pci_device, name, args)
00174 
00175 #endif
00176 
00177 // ***** end of source ***** //
00178 

L4vmm Reference Manual, written by Mario Schwalbe  © 2006-2008