Subversion Repositories HelenOS-historic

Rev

Rev 1429 | Rev 1588 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1429 Rev 1494
Line 45... Line 45...
45
#include <syscall/copy.h>
45
#include <syscall/copy.h>
46
#include <arch.h>
46
#include <arch.h>
47
#include <align.h>
47
#include <align.h>
48
#include <errno.h>
48
#include <errno.h>
49
 
49
 
50
/** Map piece of physical memory into virtual address space of specified task.
50
/** Map piece of physical memory into virtual address space of current task.
51
 *
51
 *
52
 * @param id Task ID of the destination task.
-
 
53
 * @param pf Physical frame address of the starting frame.
52
 * @param pf Physical frame address of the starting frame.
54
 * @param vp Virtual page address of the starting page.
53
 * @param vp Virtual page address of the starting page.
55
 * @param pages Number of pages to map.
54
 * @param pages Number of pages to map.
56
 * @param flags Address space area flags for the mapping.
55
 * @param flags Address space area flags for the mapping.
57
 *
56
 *
58
 * @return 0 on success, EPERM if the caller lacks capabilities to use this syscall,
57
 * @return 0 on success, EPERM if the caller lacks capabilities to use this syscall,
59
 *     ENOENT if there is no task matching the specified ID and ENOMEM if
58
 *     ENOENT if there is no task matching the specified ID and ENOMEM if
60
 *     there was a problem in creating address space area.
59
 *     there was a problem in creating address space area.
61
 */
60
 */
62
static int ddi_physmem_map(task_id_t id, __address pf, __address vp, count_t pages, int flags)
61
static int ddi_physmem_map(__address pf, __address vp, count_t pages, int flags)
63
{
62
{
64
    ipl_t ipl;
63
    ipl_t ipl;
65
    cap_t caps;
64
    cap_t caps;
66
    task_t *t;
-
 
67
    mem_backend_data_t backend_data;
65
    mem_backend_data_t backend_data;
68
 
66
 
69
    backend_data.base = pf;
67
    backend_data.base = pf;
70
    backend_data.frames = pages;
68
    backend_data.frames = pages;
71
   
69
   
Line 73... Line 71...
73
     * Make sure the caller is authorised to make this syscall.
71
     * Make sure the caller is authorised to make this syscall.
74
     */
72
     */
75
    caps = cap_get(TASK);
73
    caps = cap_get(TASK);
76
    if (!(caps & CAP_MEM_MANAGER))
74
    if (!(caps & CAP_MEM_MANAGER))
77
        return EPERM;
75
        return EPERM;
78
   
-
 
79
    ipl = interrupts_disable();
-
 
80
    spinlock_lock(&tasks_lock);
-
 
81
   
-
 
82
    t = task_find_by_id(id);
-
 
83
   
-
 
84
    if (!t) {
-
 
85
        /*
-
 
86
         * There is no task with the specified ID.
-
 
87
         */
-
 
88
        spinlock_unlock(&tasks_lock);
-
 
89
        interrupts_restore(ipl);
-
 
90
        return ENOENT;
-
 
91
    }
-
 
92
 
76
 
93
    /*
-
 
94
     * TODO: We are currently lacking support for task destroying.
-
 
95
     * Once it is added to the kernel, we must take care to
77
    ipl = interrupts_disable();
96
     * synchronize in a way that prevents race conditions here.
-
 
97
     */
-
 
98
   
-
 
99
    /* Lock the task and release the lock protecting tasks_btree. */
78
    /* Lock the task and release the lock protecting tasks_btree. */
100
    spinlock_lock(&t->lock);
79
    spinlock_lock(&TASK->lock);
101
    spinlock_unlock(&tasks_lock);
-
 
102
   
80
   
103
    if (!as_area_create(t->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE,
81
    if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE,
104
        &phys_backend, &backend_data)) {
82
        &phys_backend, &backend_data)) {
105
        /*
83
        /*
106
         * The address space area could not have been created.
84
         * The address space area could not have been created.
107
         * We report it using ENOMEM.
85
         * We report it using ENOMEM.
108
         */
86
         */
109
        spinlock_unlock(&t->lock);
87
        spinlock_unlock(&TASK->lock);
110
        interrupts_restore(ipl);
88
        interrupts_restore(ipl);
111
        return ENOMEM;
89
        return ENOMEM;
112
    }
90
    }
113
   
91
   
114
    /*
92
    /*
115
     * Mapping is created on-demand during page fault.
93
     * Mapping is created on-demand during page fault.
116
     */
94
     */
117
   
95
   
118
    spinlock_unlock(&t->lock);
96
    spinlock_unlock(&TASK->lock);
119
    interrupts_restore(ipl);
97
    interrupts_restore(ipl);
120
    return 0;
98
    return 0;
121
}
99
}
122
 
100
 
123
/** Enable range of I/O space for task.
101
/** Enable range of I/O space for task.
Line 174... Line 152...
174
    return rc;
152
    return rc;
175
}
153
}
176
 
154
 
177
/** Wrapper for SYS_MAP_PHYSMEM syscall.
155
/** Wrapper for SYS_MAP_PHYSMEM syscall.
178
 *
156
 *
-
 
157
 * @param phys_base Physical base address to map
-
 
158
 * @param virt_base Destination virtual address
-
 
159
 * @param pages Number of pages
179
 * @param User space address of memory DDI argument structure.
160
 * @param flags Flags of newly mapped pages
180
 *
161
 *
181
 * @return 0 on success, otherwise it returns error code found in errno.h
162
 * @return 0 on success, otherwise it returns error code found in errno.h
182
 */
163
 */
183
__native sys_physmem_map(ddi_memarg_t *uspace_mem_arg)
164
__native sys_physmem_map(__native phys_base, __native virt_base, __native pages,
-
 
165
             __native flags)
184
{
166
{
185
    ddi_memarg_t arg;
-
 
186
    int rc;
-
 
187
   
-
 
188
    rc = copy_from_uspace(&arg, uspace_mem_arg, sizeof(ddi_memarg_t));
-
 
189
    if (rc != 0)
-
 
190
        return (__native) rc;
-
 
191
       
-
 
192
    return (__native) ddi_physmem_map((task_id_t) arg.task_id, ALIGN_DOWN((__address) arg.phys_base, FRAME_SIZE),
167
    return (__native) ddi_physmem_map(ALIGN_DOWN((__address) phys_base, FRAME_SIZE),
193
                      ALIGN_DOWN((__address) arg.virt_base, PAGE_SIZE), (count_t) arg.pages,
168
                      ALIGN_DOWN((__address) virt_base, PAGE_SIZE), (count_t) pages,
194
                      (int) arg.flags);
169
                      (int) flags);
195
}
170
}
196
 
171
 
197
/** Wrapper for SYS_ENABLE_IOSPACE syscall.
172
/** Wrapper for SYS_ENABLE_IOSPACE syscall.
198
 *
173
 *
199
 * @param User space address of DDI argument structure.
174
 * @param User space address of DDI argument structure.