]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4sys/include/ARCH-arm/mem_op.h
update
[l4.git] / l4 / pkg / l4sys / include / ARCH-arm / mem_op.h
1 /**
2  * \file
3  * \brief  Memory access functions (ARM specific)
4  *
5  * \date   2010-10
6  * \author Adam Lackorzynski <adam@os.inf.tu-dresden.de>
7  *
8  */
9 /*
10  * (c) 2010 Author(s)
11  *     economic rights: Technische Universität Dresden (Germany)
12  *
13  * This file is part of TUD:OS and distributed under the terms of the
14  * GNU General Public License 2.
15  * Please see the COPYING-GPL-2 file for details.
16  *
17  * As a special exception, you may use this file as part of a free software
18  * library without restriction.  Specifically, if other files instantiate
19  * templates or use macros or inline functions from this file, or you compile
20  * this file and link it with other files to produce an executable, this
21  * file does not by itself cause the resulting executable to be covered by
22  * the GNU General Public License.  This exception does not however
23  * invalidate any other reasons why the executable file might be covered by
24  * the GNU General Public License.
25  */
26 #ifndef __L4SYS__INCLUDE__ARCH_ARM__MEM_OP_H__
27 #define __L4SYS__INCLUDE__ARCH_ARM__MEM_OP_H__
28
29 #include <l4/sys/compiler.h>
30 #include <l4/sys/syscall_defs.h>
31
32 EXTERN_C_BEGIN
33
34 /**
35  * \defgroup l4_mem_op_api Memory operations.
36  * \ingroup l4_api
37  * \brief Operations for memory access.
38  *
39  * This modules provides functionality to access user task memory from the
40  * kernel. This is needed for some devices that are only accessible from
41  * privileged processor mode. Only use this when absolutely required. This
42  * functionality is only available on the ARM architecture.
43  *
44  * <c>\#include <l4/sys/mem_op.h></c>
45  */
46
47 /**
48  * \brief Memory access width definitions.
49  * \ingroup l4_mem_op_api
50  */
51 enum L4_mem_op_widths
52 {
53   L4_MEM_WIDTH_1BYTE = 0, ///< Access one byte (8-bit width)
54   L4_MEM_WIDTH_2BYTE = 1, ///< Access two bytes (16-bit width)
55   L4_MEM_WIDTH_4BYTE = 2, ///< Access four bytes (32-bit width)
56 };
57
58 /**
59  * \brief Read memory from kernel privilege level.
60  * \ingroup l4_mem_op_api
61  *
62  * \param virtaddress  Virtual address in the calling task.
63  * \param width        Width of access in bytes in log2,
64  *                       \see L4_mem_op_widths
65  * \return Read value.
66  *
67  * Upon an given invalid address or invalid width value the function does
68  * nothing.
69  */
70 L4_INLINE unsigned long
71 l4_mem_read(unsigned long virtaddress, unsigned width);
72
73 /**
74  * \brief Write memory from kernel privilege level.
75  * \ingroup l4_mem_op_api
76  *
77  * \param virtaddress  Virtual address in the calling task.
78  * \param width        Width of access in bytes in log2
79  *                       (i.e. allowed values: 0, 1, 2)
80  * \param value        Value to write.
81  *
82  * Upon an given invalid address or invalid width value the function does
83  * nothing.
84  */
85 L4_INLINE void
86 l4_mem_write(unsigned long virtaddress, unsigned width,
87              unsigned long value);
88
89 enum L4_mem_ops
90 {
91   L4_MEM_OP_MEM_READ  = 0x10,
92   L4_MEM_OP_MEM_WRITE = 0x11,
93 };
94
95 /**
96  * \internal
97  */
98 L4_INLINE unsigned long
99 l4_mem_arm_op_call(unsigned long op,
100                    unsigned long va,
101                    unsigned long width,
102                    unsigned long value);
103
104 /** Implementations */
105
106 L4_INLINE unsigned long
107 l4_mem_arm_op_call(unsigned long op,
108                    unsigned long va,
109                    unsigned long width,
110                    unsigned long value)
111 {
112   register unsigned long _op    asm ("r0") = op;
113   register unsigned long _va    asm ("r1") = va;
114   register unsigned long _width asm ("r2") = width;
115   register unsigned long _value asm ("r3") = value;
116
117   __asm__ __volatile__
118     ("@ l4_cache_op_arm_call(start) \n\t"
119      "mov     lr, pc                \n\t"
120      "mov     pc, %[sc]             \n\t"
121      "@ l4_cache_op_arm_call(end)   \n\t"
122        :
123         "=r" (_op),
124         "=r" (_va),
125         "=r" (_width),
126         "=r" (_value)
127        :
128        [sc] "i" (L4_SYSCALL_MEM_OP),
129         "0" (_op),
130         "1" (_va),
131         "2" (_width),
132         "3" (_value)
133        :
134         "cc", "memory", "lr"
135        );
136
137   return _value;
138 }
139
140 L4_INLINE unsigned long
141 l4_mem_read(unsigned long virtaddress, unsigned width)
142 {
143   return l4_mem_arm_op_call(L4_MEM_OP_MEM_READ, virtaddress, width, 0);
144 }
145
146 L4_INLINE void
147 l4_mem_write(unsigned long virtaddress, unsigned width,
148              unsigned long value)
149 {
150   l4_mem_arm_op_call(L4_MEM_OP_MEM_WRITE, virtaddress, width, value);
151 }
152
153 EXTERN_C_END
154
155 #endif /* ! __L4SYS__INCLUDE__ARCH_ARM__MEM_OP_H__ */