Overview   API Reference  

device_base.hpp

00001 #if !defined(__DEVICE_BASE_HPP__)
00002 #define __DEVICE_BASE_HPP__
00003 
00004 //
00005 // local includes
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     // iospace_handler: override read_ioport & write_ioport
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     // mmio_handler: override read_mmio/write_mmio & I/O memory (un)map functions
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     // irq_source: override irq_moved
00129     //
00134     virtual inline void irq_moved(l4_irq_t from, l4_irq_t to)
00135     {
00136         irq=to;
00137     }
00138 
00139     //
00140     // device: override name & reset
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     // device helper functions
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 // ***** end of source ***** //
00237 

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