Overview   API Reference  

iospace_manager.hpp

00001 #if !defined(__IOSPACE_MANAGER_HPP__)
00002 #define __IOSPACE_MANAGER_HPP__
00003 
00004 //
00005 // local includes
00006 //
00007 #include "core/machine/generic/resource_manager.hpp"
00008 #include "iospace_default_handler.hpp"
00009 
00010 //
00011 // forward declarations
00012 //
00013 struct machine_config;
00014 
00018 struct iospace_manager : public resource_manager, private noncopyable
00019 {
00020     static const bool VERBOSE_ALLOCATION = false;
00021     static const int  NUM_IOPORTS        = L4_IOPORT_MAX;
00022 
00023     //
00024     //     l4_port_t must be unsigned. ports below 0 don't exist.
00025     //
00026     static_assert(is_unsigned<l4_port_t>::conforms, "l4_port_t must be an unsigned integer");
00027     static_assert(static_cast<uint32_t>(integer_traits<l4_port_t>::const_max) >= NUM_IOPORTS - 1,
00028                   "l4_port_t's max value is too small");
00029 
00030     typedef resource_flags ioport_flags;
00031 
00035     struct ioport_state : public ioport_flags
00036     {
00040         iospace_handler *handler;
00041 
00042         inline ioport_state(void)
00043             : ioport_flags(0), handler(nullptr)
00044         {}
00045 
00046         friend inline bool operator ==(const ioport_state &s1, const ioport_state &s2)
00047         {
00048             return (s1.bits == s2.bits) && (s1.handler == s2.handler);
00049         }
00050     };
00051 
00052   protected:
00056     const machine_config &config;
00057 
00061     lock iospace_lock;
00062 
00066     ioport_state iospace_state[NUM_IOPORTS];
00067 
00071     iospace_default_handler default_handler;
00072 
00073   public:
00074     //
00075     // constructors & destructors
00076     //
00077     iospace_manager(const machine_config &config);
00078     virtual ~iospace_manager(void);
00079 
00080     virtual int check_iospace_request(const iospace_handler *handler, l4_port_t base,
00081                                       l4_port_t size=1, bool verbose=VERBOSE_ALLOCATION) const;
00082 
00083     //
00084     // virtual I/O space management functions
00085     //
00086     virtual int register_iospace_handler(iospace_handler *handler, l4_port_t base,
00087                                          l4_port_t size=1, bool verbose=VERBOSE_ALLOCATION);
00088     virtual int unregister_iospace_handler(const iospace_handler *handler, l4_port_t base,
00089                                            l4_port_t size=1, bool verbose=VERBOSE_ALLOCATION);
00090 
00091     inline bool is_ioport_virtual(const l4_port_t port) const
00092     {
00093         assert_logd(L4VMM_DEBUG_IOSPACE, is_valid_ioport(port), "port: "l4_port_fmt"\n", port);
00094         return iospace_state[port].is_virtual();
00095     }
00096 
00097     //
00098     // virtual I/O port access proxy functions
00099     //
00100     template <typename WordT>
00101     inline WordT read_virtual_ioport(const l4_port_t port)
00102     {
00103         static_assert((is_integer<WordT, 1, 4>::conforms), "WordT must be an integer of at most (un)signed int");
00104         assert_logd(L4VMM_DEBUG_IOSPACE, is_valid_ioport(port), "port: "l4_port_fmt"\n", port);
00105         assert_logd(L4VMM_DEBUG_IOSPACE, iospace_state[port].handler != nullptr, "port: "l4_port_fmt"\n", port);
00106         return iospace_state[port].handler->read_ioport(port, sizeof(WordT));
00107     }
00108 
00109     template <typename WordT>
00110     inline int write_virtual_ioport(const l4_port_t port, const WordT data)
00111     {
00112         static_assert((is_integer<WordT, 1, 4>::conforms), "WordT must be an integer of at most (un)signed int");
00113         assert_logd(L4VMM_DEBUG_IOSPACE, is_valid_ioport(port), "port: "l4_port_fmt"\n", port);
00114         assert_logd(L4VMM_DEBUG_IOSPACE, iospace_state[port].handler != nullptr, "port: "l4_port_fmt"\n", port);
00115         return iospace_state[port].handler->write_ioport(port, data, sizeof(WordT));
00116     }
00117 
00118     //
00119     // physical I/O space management functions
00120     //
00121     virtual int request_iospace_region(iospace_handler *handler, l4_port_t base,
00122                                        l4_port_t size=1, bool verbose=VERBOSE_ALLOCATION);
00123     virtual int release_iospace_region(const iospace_handler *handler, l4_port_t base,
00124                                        l4_port_t size=1, bool verbose=VERBOSE_ALLOCATION);
00125     virtual int release_iospace_regions(const iospace_handler *handler=nullptr,
00126                                         bool verbose=VERBOSE_ALLOCATION);
00127 
00128     inline bool is_ioport_physical(const l4_port_t port) const
00129     {
00130         assert_logd(L4VMM_DEBUG_IOSPACE, is_valid_ioport(port), "port: "l4_port_fmt"\n", port);
00131         return iospace_state[port].is_physical();
00132     }
00133 
00134     //
00135     // other functions
00136     //
00137     virtual int check_iospace_use(ioport_flags use, l4_port_t base, l4_port_t size=1);
00138     virtual int change_iospace_region(iospace_handler *handler, ioport_flags use, l4_port_t base,
00139                                       l4_port_t size=1, bool verbose=VERBOSE_ALLOCATION);
00140 
00141     // TODO: should be removed
00142     inline iospace_handler *get_ioport_handler(const l4_port_t port) const
00143     {
00144         assert_logd(L4VMM_DEBUG_IOSPACE, is_valid_ioport(port), "port: "l4_port_fmt"\n", port);
00145         return iospace_state[port].handler;
00146     }
00147 
00148     //
00149     // debug stuff
00150     //
00151     virtual void print_iospace_state(const char *header=nullptr);
00152 
00153   protected:
00154     virtual int init_iospace(void);
00155 
00156   public:
00157     static inline bool is_valid_ioport(const l4_port_t port)
00158     {
00159         return range_traits<l4_port_t, NUM_IOPORTS>::is_valid(port);
00160     }
00161 };
00162 
00163 #endif
00164 
00165 // ***** end of source ***** //
00166 

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