00001 #if !defined(__PCI_IOREGION_HPP__)
00002 #define __PCI_IOREGION_HPP__
00003
00004
00005
00006
00007 #include "core/machine/generic/resource_region.hpp"
00008 #include "pci_config_header64.hpp"
00009
00017 struct pci_ioregion : public resource_region<l4_gpa_t>
00018 {
00019 typedef resource_region<l4_gpa_t> super_type;
00020
00024 enum type
00025 {
00027 UNUSED = 0x00,
00029 IOSPACE = 0x01,
00031 MEM = 0x02,
00033 MEM_PREFETCH = 0x04,
00035 ROM = 0x08,
00036
00038 IOMEMORY = MEM | MEM_PREFETCH | ROM,
00040 ALL_MASK = UNUSED | IOSPACE | MEM | MEM_PREFETCH | ROM | IOMEMORY
00041 } type;
00042
00048 l4_hva_t virtual_base;
00049
00050
00051
00052
00053 inline pci_ioregion(void)
00054 : type(UNUSED), virtual_base(0)
00055 {}
00056
00057 inline pci_ioregion(const enum type type, const l4_gpa_t base, const l4_gpa_t size,
00058 const l4_hva_t virtual_base=0)
00059 : super_type(base, size), type(type), virtual_base(virtual_base)
00060 {}
00061
00062 inline pci_ioregion(const union pci_config_header64::base_address ®,
00063 const l4_gpa_t size, const l4_hva_t virtual_base=0)
00064 : super_type(reg.region_base(), size),
00065 type(reg.iospace.indicator ? IOSPACE : reg.memory.prefetchable ? MEM_PREFETCH : MEM),
00066 virtual_base(virtual_base)
00067 {}
00068
00069 inline pci_ioregion(const union pci_config_header64::expansion_ROM_address ®,
00070 const l4_gpa_t size, const l4_hva_t virtual_base)
00071 : super_type(reg.region_base(), size), type(ROM), virtual_base(virtual_base)
00072 {}
00073
00074
00075
00076
00077 inline pci_ioregion &operator ()(const enum type type, const l4_gpa_t base,
00078 const l4_gpa_t size, const l4_hva_t virtual_base=0)
00079 {
00080 this->type=type;
00081 this->base=base;
00082 this->size=size;
00083 this->virtual_base=virtual_base;
00084 return *this;
00085 }
00086
00087 inline pci_ioregion &operator ()(const union pci_config_header64::base_address ®,
00088 const l4_gpa_t size, const l4_hva_t virtual_base=0)
00089 {
00090 return (*this)(reg.iospace.indicator ? IOSPACE : reg.memory.prefetchable ? MEM_PREFETCH : MEM,
00091 reg.region_base(), size, virtual_base);
00092 }
00093
00094 inline pci_ioregion &operator ()(const union pci_config_header64::expansion_ROM_address ®,
00095 const l4_gpa_t size, const l4_hva_t virtual_base)
00096 {
00097 return (*this)(ROM, reg.region_base(), size, virtual_base);
00098 }
00099
00103 inline pci_ioregion &reset(void)
00104 {
00105 base=0;
00106 return *this;
00107 }
00108
00109
00110
00111
00115 inline bool is(const enum type type) const
00116 {
00117 return (this->type & type) != 0;
00118 }
00119
00123 inline bool is_iospace(void) const
00124 {
00125 return is(IOSPACE);
00126 }
00127
00131 inline bool is_iomemory(void) const
00132 {
00133 return is(IOMEMORY);
00134 }
00135
00139 inline bool is_located(void) const
00140 {
00141 return base != 0;
00142 }
00143
00147 inline bool is_used(void) const
00148 {
00149 return (type != UNUSED) && (size != 0);
00150 }
00151
00156 inline l4_gpa_t size_mask(void) const
00157 {
00158 return ~(static_cast<l4_gpa_t>(size) - 1);
00159 }
00160
00161
00162
00163
00168 template <typename WordT>
00169 static inline WordT register_value(const enum type type, const WordT value)
00170 {
00171 static_assert(is_integer<WordT>::conforms, "WordT must be an integer");
00172 return (type == IOSPACE) ? (value & ~0x03) | 0x01 :
00173 (type == MEM) ? (value & ~0x0f) | 0x00 :
00174 (type == MEM_PREFETCH) ? (value & ~0x0f) | 0x08 :
00175 (type == ROM) ? (value & ~0x07ff) | 0x01 :
00176 0x00;
00177 }
00178
00183 template <typename WordT>
00184 inline WordT base2bar(void) const
00185 {
00186 return register_value<WordT>(type, base);
00187 }
00188
00193 template <typename WordT>
00194 inline WordT size2bar(void) const
00195 {
00196 return register_value<WordT>(type, size_mask());
00197 }
00198
00203 inline operator l4_umword_t(void) const
00204 {
00205
00206
00207
00208
00209 return base2bar<l4_umword_t>();
00210 }
00211
00212
00213
00214
00218 static inline const char *type2string(const enum type type)
00219 {
00220 return (type == UNUSED) ? "unused" :
00221 (type == IOSPACE) ? "ports" :
00222 (type == MEM) ? "memory" :
00223 (type == MEM_PREFETCH) ? "pref. memory" :
00224 (type == ROM) ? "ROM" :
00225 (type == IOMEMORY) ? "any memory type" :
00226 (type == ALL_MASK) ? "any region type" : "unknown";
00227 }
00228
00232 inline const char *type2string(void) const
00233 {
00234 return type2string(type);
00235 }
00236
00240 inline int print(const char *prefix="", const char *suffix="") const
00241 {
00242 return is_iospace() ?
00243 log::print("%s"l4_port_fmt"-"l4_port_fmt" ["l4_port_fmt"] type: %s%s",
00244 prefix,
00245 static_cast<l4_port_t>(base),
00246 static_cast<l4_port_t>(base + size - 1),
00247 static_cast<l4_port_t>(size),
00248 type2string(), suffix) :
00249 log::print("%s"l4_gpa_fmt"-"l4_gpa_fmt" ["l4_gpa_fmt"] type: %s%s",
00250 prefix, base, base + size -1, size, type2string(), suffix);
00251 }
00252
00256 inline int print_short(const char *prefix="", const char *suffix="") const
00257 {
00258 return is_iospace() ?
00259 log::print("%s"l4_port_fmt" ["l4_port_fmt"] type: %s%s",
00260 prefix,
00261 static_cast<l4_port_t>(base),
00262 static_cast<l4_port_t>(size),
00263 type2string(), suffix) :
00264 log::print("%s"l4_gpa_fmt" ["l4_gpa_fmt"] type: %s%s",
00265 prefix, base, size, type2string(), suffix);
00266 }
00267 };
00268
00269 #endif
00270
00271
00272