00001 #if !defined(__DEVICE_BASE_HPP__)
00002 #define __DEVICE_BASE_HPP__
00003
00004
00005
00006
00007 #include "core/machine/machine_base.hpp"
00008 #include "device.hpp"
00009
00014 struct device_base : public iospace_handler, public mmio_handler, public irq_source,
00015 public device, private noncopyable
00016 {
00017 static const bool VERBOSE_ALLOCATION = false;
00018
00019 protected:
00023 const string device_name;
00024
00029 machine_base &machine;
00030
00034 l4_irq_t irq;
00035
00036 public:
00037 inline device_base(machine_base &machine, const string &device_name)
00038 : device_name(device_name), machine(machine), irq(irq_manager::NO_IRQ)
00039 {}
00040
00041
00042
00043
00049 virtual inline uint32_t read_ioport(l4_port_t port, access_size access_size)
00050 {
00051 log::debug("%s:\n device_base::%s called. override?\n"
00052 " read %s at "l4_port_fmt"\n",
00053 name(), __func__, access_size.string(), port);
00054 return iospace_handler::INVALID;
00055 }
00056
00062 virtual inline int write_ioport(l4_port_t port, uint32_t data, access_size access_size)
00063 {
00064 log::debug("%s:\n device_base::%s called. override?\n"
00065 " write %s %s at "l4_port_fmt"\n",
00066 name(), __func__,
00067 access_size.string(), format_hex<uint32_t>(data, access_size*2).c_str(), port);
00068 return -L4_ENOTSUPP;
00069 }
00070
00071
00072
00073
00079 virtual inline l4_umword_t read_mmio(l4_gpa_t address, access_size access_size)
00080 {
00081 log::debug("%s:\n device_base::%s called. override?\n"
00082 " read %s at "l4_gpa_fmt"\n",
00083 name(), __func__, access_size.string(), address);
00084 return mmio_handler::INVALID;
00085 }
00086
00092 virtual inline int write_mmio(l4_gpa_t address, l4_umword_t data, access_size access_size)
00093 {
00094 log::debug("%s:\n device_base::%s called. override?\n"
00095 " write %s %s at "l4_gpa_fmt"\n",
00096 name(), __func__,
00097 access_size.string(), format_hex<l4_umword_t>(data, access_size*2).c_str(), address);
00098 return -L4_ENOTSUPP;
00099 }
00100
00106 virtual l4_hva_t map_mmio_region(int flags, l4_gpa_t base, l4_gpa_t size=1)
00107 {
00108 log::debug("%s:\n device_base::%s called. override?\n"
00109 " "l4_gpa_fmt"-"l4_gpa_fmt" ["l4_gpa_fmt"]\n",
00110 name(), __func__, base, base + size - 1, size);
00111 return 0;
00112 }
00113
00119 virtual int unmap_mmio_region(l4_gpa_t base, l4_gpa_t size=1)
00120 {
00121 log::debug("%s:\n device_base::%s called. override?\n"
00122 " "l4_gpa_fmt"-"l4_gpa_fmt" ["l4_gpa_fmt"]\n",
00123 name(), __func__, base, base + size - 1, size);
00124 return -L4_ENOTSUPP;
00125 }
00126
00127
00128
00129
00134 virtual inline void irq_moved(l4_irq_t from, l4_irq_t to)
00135 {
00136 irq=to;
00137 }
00138
00139
00140
00141
00142 virtual inline const char *name(void) const
00143 {
00144 return device_name.c_str();
00145 }
00146
00147 virtual int reset(void)
00148 {
00149 return 0;
00150 }
00151
00152 protected:
00153
00154
00155
00160 virtual inline int use_iospace(l4_port_t base, l4_port_t size=1, bool verbose=VERBOSE_ALLOCATION)
00161 {
00162 return machine.register_iospace_handler(this, base, size, verbose);
00163 }
00164
00168 virtual inline int change_iospace(iospace_manager::ioport_flags use, l4_port_t base,
00169 l4_port_t size=1, bool verbose=VERBOSE_ALLOCATION)
00170 {
00171 return machine.change_iospace_region(this, use, base, size, verbose);
00172 }
00173
00177 virtual inline int free_iospace(l4_port_t base, l4_port_t size=1, bool verbose=VERBOSE_ALLOCATION)
00178 {
00179 return machine.unregister_iospace_handler(this, base, size, verbose);
00180 }
00181
00186 virtual inline int use_iomemory(l4_gpa_t base, l4_gpa_t size=1, bool verbose=VERBOSE_ALLOCATION)
00187 {
00188 return machine.register_mmio_handler(this, base, size, verbose);
00189 }
00190
00194 virtual inline int free_iomemory(l4_gpa_t base, l4_gpa_t size=1, bool verbose=VERBOSE_ALLOCATION)
00195 {
00196 return machine.unregister_mmio_handler(this, base, size, verbose);
00197 }
00198
00204 virtual inline int use_irq(irq_manager::irq_flags use=irq_manager::VIRTUAL,
00205 l4_irq_t requested_irq=irq_manager::NO_IRQ,
00206 l4_irq_t physical_irq=irq_manager::NO_IRQ,
00207 bool verbose=VERBOSE_ALLOCATION)
00208 {
00209 const int ret=machine.register_irq(this, use, requested_irq, physical_irq, verbose);
00210 this->irq=(ret >= 0) ? ret : irq_manager::NO_IRQ;
00211 return ret;
00212 }
00213
00218 inline void assert_irq(void) const
00219 {
00220 machine.assert_irq(irq);
00221 }
00222
00226 virtual inline int free_irq(bool verbose=VERBOSE_ALLOCATION)
00227 {
00228 const int ret=machine.unregister_irq(this, irq, verbose);
00229 irq=irq_manager::NO_IRQ;
00230 return ret;
00231 }
00232 };
00233
00234 #endif
00235
00236
00237