1 /* 2 * (c) 2014 Alexander Warg <alexander.warg@kernkonzept.com> 3 * 4 * This file is part of TUD:OS and distributed under the terms of the 5 * GNU General Public License 2. 6 * Please see the COPYING-GPL-2 file for details. 7 */ 8 #pragma once 9 10 #include <cstddef> 11 #include <l4/sys/types.h> 12 #include <l4/re/dma_space> 13 #include <l4/sys/cxx/ipc_epiface> 14 #include <l4/cxx/hlist> 15 #include <l4/cxx/avl_tree> 16 #include <l4/cxx/ref_ptr> 17 18 #include "quota.h" 19 #include "server_obj.h" 20 #include "globals.h" 21 22 namespace Moe { 23 24 class Dma_space; 25 26 namespace Dma { 27 28 struct Mapping; 29 30 class Mapper : public cxx::Ref_obj 31 { 32 public: 33 Mapper(Mapper const &) = delete; 34 Mapper() = default; 35 Mapper &operator = (Mapper const &) = delete; 36 37 typedef L4Re::Dma_space::Attributes Attributes; 38 typedef L4Re::Dma_space::Direction Direction; 39 typedef L4Re::Dma_space::Dma_addr Dma_addr; 40 41 virtual Mapping *map(Dataspace *ds, Q_alloc *, 42 l4_addr_t offset, l4_size_t *size, 43 Attributes attrs, Direction dir, 44 Dma_addr *dma_addr) = 0; 45 46 virtual int unmap(Dma_addr dma_addr, l4_size_t size, 47 Attributes attrs, Direction dir) = 0; 48 49 virtual void remove(Mapping *m) = 0; 50 51 virtual ~Mapper() = default; 52 }; 53 54 struct Region 55 { 56 l4_addr_t start; 57 l4_addr_t end; 58 bool operator < (Region const &r) const 59 { return end < r.start; } 60 61 Region() = default; RegionRegion62 Region(l4_addr_t s) : start(s), end(s) {} RegionRegion63 Region(l4_addr_t s, l4_addr_t e) : start(s), end(e) {} 64 }; 65 66 struct Mapping : cxx::H_list_item_t<Mapping>, cxx::Avl_tree_node 67 { 68 typedef Region Key_type; 69 typedef cxx::Avl_tree<Mapping, Mapping, cxx::Lt_functor<Region>> Map; 70 typedef cxx::H_list_t<Dma::Mapping> List; 71 typedef L4Re::Dma_space::Direction Direction; 72 typedef L4Re::Dma_space::Attributes Attributes; 73 74 Region key; 75 Mapper *mapper = 0; 76 Attributes attrs = Attributes::None; 77 Direction dir = Direction::None; 78 key_ofMapping79 static Key_type key_of(Mapping const *m) { return m->key; } 80 81 Mapping(Mapping const &) = delete; 82 Mapping &operator = (Mapping const &) = delete; 83 Mapping() = default; 84 ~MappingMapping85 ~Mapping() 86 { 87 if (mapper) 88 mapper->remove(this); 89 90 if (0) 91 printf("DMA: del mapping: map=%p %lx %lx\n", mapper, key.start, key.end); 92 } 93 }; 94 95 } 96 97 class Dma_space : 98 public L4::Epiface_t<Dma_space, L4Re::Dma_space, Server_object>, 99 public Q_object 100 { 101 public: 102 typedef L4Re::Dma_space::Dma_addr Dma_addr; 103 typedef L4Re::Dma_space::Direction Direction; 104 typedef L4Re::Dma_space::Attributes Attributes; 105 typedef L4Re::Dma_space::Space_attribs Space_attribs; 106 107 long op_map(L4Re::Dma_space::Rights rights, 108 L4::Ipc::Snd_fpage src_ds, l4_addr_t offset, 109 l4_size_t &size, Attributes attrs, Direction dir, 110 Dma_addr &dma_addr); 111 112 long op_unmap(L4Re::Dma_space::Rights rights, 113 Dma_addr dma_addr, 114 l4_size_t size, Attributes attrs, Direction dir); 115 116 long op_associate(L4Re::Dma_space::Rights rights, 117 L4::Ipc::Snd_fpage dma_task, 118 Space_attribs attr); 119 120 long op_disassociate(L4Re::Dma_space::Rights rights); 121 122 void delete_all_mappings(); 123 ~Dma_space()124 ~Dma_space() { delete_all_mappings(); } 125 126 private: 127 Space_attribs _attr = Space_attribs::None; 128 cxx::Ref_ptr<Dma::Mapper> _mapper; 129 Dma::Mapping::List _mappings; 130 }; 131 132 } 133