00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00042 #include <ddi/ddi.h>
00043 #include <ddi/ddi_arg.h>
00044 #include <proc/task.h>
00045 #include <security/cap.h>
00046 #include <mm/frame.h>
00047 #include <mm/as.h>
00048 #include <synch/spinlock.h>
00049 #include <syscall/copy.h>
00050 #include <arch.h>
00051 #include <align.h>
00052 #include <errno.h>
00053
00065 static int ddi_physmem_map(__address pf, __address vp, count_t pages, int flags)
00066 {
00067 ipl_t ipl;
00068 cap_t caps;
00069 mem_backend_data_t backend_data;
00070
00071 backend_data.base = pf;
00072 backend_data.frames = pages;
00073
00074
00075
00076
00077 caps = cap_get(TASK);
00078 if (!(caps & CAP_MEM_MANAGER))
00079 return EPERM;
00080
00081 ipl = interrupts_disable();
00082 spinlock_lock(&TASK->lock);
00083
00084 if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE,
00085 &phys_backend, &backend_data)) {
00086
00087
00088
00089
00090 spinlock_unlock(&TASK->lock);
00091 interrupts_restore(ipl);
00092 return ENOMEM;
00093 }
00094
00095
00096
00097
00098
00099 spinlock_unlock(&TASK->lock);
00100 interrupts_restore(ipl);
00101 return 0;
00102 }
00103
00113 static int ddi_iospace_enable(task_id_t id, __address ioaddr, size_t size)
00114 {
00115 ipl_t ipl;
00116 cap_t caps;
00117 task_t *t;
00118 int rc;
00119
00120
00121
00122
00123 caps = cap_get(TASK);
00124 if (!(caps & CAP_IO_MANAGER))
00125 return EPERM;
00126
00127 ipl = interrupts_disable();
00128 spinlock_lock(&tasks_lock);
00129
00130 t = task_find_by_id(id);
00131
00132 if (!t) {
00133
00134
00135
00136 spinlock_unlock(&tasks_lock);
00137 interrupts_restore(ipl);
00138 return ENOENT;
00139 }
00140
00141
00142 spinlock_lock(&t->lock);
00143 spinlock_unlock(&tasks_lock);
00144
00145 rc = ddi_iospace_enable_arch(t, ioaddr, size);
00146
00147 spinlock_unlock(&t->lock);
00148 interrupts_restore(ipl);
00149 return rc;
00150 }
00151
00161 __native sys_physmem_map(__native phys_base, __native virt_base, __native pages,
00162 __native flags)
00163 {
00164 return (__native) ddi_physmem_map(ALIGN_DOWN((__address) phys_base, FRAME_SIZE),
00165 ALIGN_DOWN((__address) virt_base, PAGE_SIZE), (count_t) pages,
00166 (int) flags);
00167 }
00168
00175 __native sys_iospace_enable(ddi_ioarg_t *uspace_io_arg)
00176 {
00177 ddi_ioarg_t arg;
00178 int rc;
00179
00180 rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t));
00181 if (rc != 0)
00182 return (__native) rc;
00183
00184 return (__native) ddi_iospace_enable((task_id_t) arg.task_id, (__address) arg.ioaddr, (size_t) arg.size);
00185 }
00186
00195 __native sys_preempt_control(int enable)
00196 {
00197 if (! cap_get(TASK) & CAP_PREEMPT_CONTROL)
00198 return EPERM;
00199 if (enable)
00200 preemption_enable();
00201 else
00202 preemption_disable();
00203 return 0;
00204 }
00205