2 * Copyright (C) 2015 Kernkonzept GmbH.
3 * Author(s): Sarah Hoffmann <sarah.hoffmann@kernkonzept.com>
5 * This file is distributed under the terms of the GNU General Public
6 * License, version 2. Please see the COPYING-GPL-2 file for details.
10 #include <l4/re/error_helper>
11 #include <l4/l4re_vfs/backend>
18 Ram_ds::Ram_ds(L4::Cap<L4Re::Dataspace> ram, l4_addr_t vm_base)
20 _dma(L4Re::chkcap(L4Re::Util::cap_alloc.alloc<L4Re::Dma_space>()))
27 auto *env = L4Re::Env::env();
29 int err = l4_error(env->user_factory()->create(_dma.get()));
32 err = _dma->associate(L4::Ipc::Cap<L4::Task>(L4::Cap<void>::Invalid),
33 L4Re::Dma_space::Phys_space);
36 _dma = L4::Cap<L4Re::Dma_space>::Invalid;
38 l4_size_t phys_size = _size;
39 L4Re::Dma_space::Dma_addr phys_ram = 0;
42 err = _dma->map(L4::Ipc::make_cap(ram, L4_CAP_FPAGE_RW),
44 L4Re::Dma_space::Attributes::None,
45 L4Re::Dma_space::Bidirectional, &phys_ram);
49 if (err < 0 || phys_size < _size)
51 info.printf("RAM dataspace not contiguous, should not use DMA w/o IOMMU\n");
52 if (err >= 0 && _vm_start == ~0UL)
61 if (_vm_start == ~0UL)
68 info.printf("RAM: @ %lx size=%x (%c%c)\n",
69 _vm_start, (unsigned) _size, _cont ? 'c' : '-', _ident ? 'i' : '-');
72 L4Re::chksys(env->rm()->attach(&_local_start, _size,
73 L4Re::Rm::Search_addr | L4Re::Rm::Eager_map,
74 L4::Ipc::make_cap_rw(ram), 0,
76 _local_end = _local_start + _size;
77 info.printf("RAM: VMM mapping @ %lx size=%x\n", _local_start, (unsigned)_size);
78 if (_vm_start != ~0UL)
80 _offset = _local_start - _vm_start;
81 info.printf("RAM: VM offset=%lx\n", _offset);
87 Ram_ds::load_file(char const *name, l4_addr_t offset, l4_size_t *_size)
89 Dbg info(Dbg::Info, "file");
91 info.printf("load: %s -> %lx\n", name, offset);
92 int fd = open(name, O_RDONLY);
95 Err().printf("could not open file: %s:", name);
96 L4Re::chksys(-L4_EINVAL);
99 cxx::Ref_ptr<L4Re::Vfs::File> file = L4Re::Vfs::vfs_ops->get_file(fd);
102 Err().printf("bad file descriptor: %s\n", name);
104 L4Re::chksys(-L4_EINVAL);
107 L4::Cap<L4Re::Dataspace> f = file->data_space();
110 Err().printf("could not get data space for %s\n", name);
112 L4Re::chksys(-L4_EINVAL);
115 l4_size_t size = f->size();
116 info.printf("copy in: %s -> %lx-%lx\n", name, offset, offset + size);
118 L4Re::chksys(_ram->copy_in(offset, f, 0, size), "copy in");
123 return L4virtio::Ptr<void>(offset + vm_start());