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