devices.hpp
00001 #if !defined(__DEVICES_HPP__)
00002 #define __DEVICES_HPP__
00003
00004
00005
00006
00007 #include "core/common.hpp"
00008
00009
00010
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
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
00120
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
00149
00150 #if (__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ <= 3)
00151
00152
00153
00154
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
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
00178