1 /**
2 * \file sigma0/lib/src/mem.c
3 * \brief map memory-mapped I/O memory using sigma0 protocol
4 *
5 * \date 02/2006
6 * \author Frank Mehnert <fm3@os.inf.tu-dresden.de> */
7
8 /*
9 * (c) 2006-2009 Author(s)
10 * economic rights: Technische Universität Dresden (Germany)
11 * This file is part of TUD:OS and distributed under the terms of the
12 * GNU Lesser General Public License 2.1.
13 * Please see the COPYING-LGPL-2.1 file for details.
14 */
15
16 #include <l4/sys/ipc.h>
17 #include <l4/sigma0/sigma0.h>
18
19 static int
map_mem(l4_cap_idx_t sigma0,l4_addr_t phys,l4_addr_t virt,l4_addr_t size,l4_umword_t type)20 map_mem(l4_cap_idx_t sigma0, l4_addr_t phys, l4_addr_t virt, l4_addr_t size,
21 l4_umword_t type)
22 {
23 l4_addr_t d = L4_SUPERPAGESIZE;
24 unsigned l = L4_LOG2_SUPERPAGESIZE;
25 l4_msgtag_t tag;
26 int error;
27 l4_utcb_t *utcb = l4_utcb();
28
29 if ((phys & (d-1)) || (size & (d-1)) || (virt & (d-1)))
30 {
31 l = L4_LOG2_PAGESIZE;
32 d = L4_PAGESIZE;
33 }
34
35 if ((phys & (d-1)) || (size & (d-1)) || (virt & (d-1)))
36 return -L4SIGMA0_NOTALIGNED;
37
38 for (; size>0; phys+=d, size-=d, virt+=d)
39 {
40 do
41 {
42 l4_msg_regs_t *m = l4_utcb_mr_u(utcb);
43 l4_buf_regs_t *b = l4_utcb_br_u(utcb);
44 tag = l4_msgtag(L4_PROTO_SIGMA0, 2, 0, 0);
45 m->mr[0] = type;
46 m->mr[1] = l4_fpage(phys, l, L4_FPAGE_RWX).raw;
47
48 b->bdr = 0;
49 b->br[0] = L4_ITEM_MAP;
50 b->br[1] = l4_fpage(virt, l, L4_FPAGE_RWX).raw;
51 tag = l4_ipc_call(sigma0, utcb, tag, L4_IPC_NEVER);
52 if (l4_msgtag_has_error(tag))
53 error = l4_utcb_tcr_u(utcb)->error;
54 else
55 error = 0;
56 }
57 while (error == L4_IPC_SECANCELED || error == L4_IPC_SEABORTED);
58
59 if (error)
60 return -L4SIGMA0_IPCERROR;
61
62 if (l4_msgtag_items(tag) < 1)
63 return -L4SIGMA0_NOFPAGE;
64 }
65
66 return 0;
67 }
68
69 L4_CV int
l4sigma0_map_mem(l4_cap_idx_t sigma0,l4_addr_t phys,l4_addr_t virt,l4_addr_t size)70 l4sigma0_map_mem(l4_cap_idx_t sigma0, l4_addr_t phys, l4_addr_t virt,
71 l4_addr_t size)
72 {
73 return map_mem(sigma0, phys, virt, size, SIGMA0_REQ_FPAGE_RAM);
74 }
75
76 L4_CV int
l4sigma0_map_iomem(l4_cap_idx_t sigma0,l4_addr_t phys,l4_addr_t virt,l4_addr_t size,int cached)77 l4sigma0_map_iomem(l4_cap_idx_t sigma0, l4_addr_t phys, l4_addr_t virt,
78 l4_addr_t size, int cached)
79 {
80 l4_umword_t type = cached ? SIGMA0_REQ_FPAGE_IOMEM_CACHED
81 : SIGMA0_REQ_FPAGE_IOMEM;
82 return map_mem(sigma0, phys, virt, size, type);
83 }
84