00001 #if !defined(__IOSPACE_MANAGER_HPP__)
00002 #define __IOSPACE_MANAGER_HPP__
00003
00004
00005
00006
00007 #include "core/machine/generic/resource_manager.hpp"
00008 #include "iospace_default_handler.hpp"
00009
00010
00011
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
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
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
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
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
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
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
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
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
00166