Changeset 8da51ad in mainline
- Timestamp:
- 2006-06-02T00:28:19Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f8d069e8
- Parents:
- 3f31742
- Location:
- generic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/include/ddi/ddi.h
r3f31742 r8da51ad 34 34 #include <typedefs.h> 35 35 36 extern __native sys_physmem_map(ddi_memarg_t *uspace_mem_arg); 36 __native sys_physmem_map(__native phys_base, __native virt_base, __native pages, 37 __native flags); 37 38 extern __native sys_iospace_enable(ddi_ioarg_t *uspace_io_arg); 38 39 extern __native sys_preempt_control(int enable); -
generic/src/ddi/ddi.c
r3f31742 r8da51ad 48 48 #include <errno.h> 49 49 50 /** Map piece of physical memory into virtual address space of specified task. 51 * 52 * @param id Task ID of the destination task. 50 /** Map piece of physical memory into virtual address space of current task. 51 * 53 52 * @param pf Physical frame address of the starting frame. 54 53 * @param vp Virtual page address of the starting page. … … 60 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) 62 { 63 ipl_t ipl; 64 cap_t caps; 65 mem_backend_data_t backend_data; 66 67 backend_data.base = pf; 68 backend_data.frames = pages; 69 70 /* 71 * Make sure the caller is authorised to make this syscall. 72 */ 73 caps = cap_get(TASK); 74 if (!(caps & CAP_MEM_MANAGER)) 75 return EPERM; 76 77 ipl = interrupts_disable(); 78 /* Lock the task and release the lock protecting tasks_btree. */ 79 spinlock_lock(&TASK->lock); 80 81 if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE, 82 &phys_backend, &backend_data)) { 83 /* 84 * The address space area could not have been created. 85 * We report it using ENOMEM. 86 */ 87 spinlock_unlock(&TASK->lock); 88 interrupts_restore(ipl); 89 return ENOMEM; 90 } 91 92 /* 93 * Mapping is created on-demand during page fault. 94 */ 95 96 spinlock_unlock(&TASK->lock); 97 interrupts_restore(ipl); 98 return 0; 99 } 100 101 /** Enable range of I/O space for task. 102 * 103 * @param id Task ID of the destination task. 104 * @param ioaddr Starting I/O address. 105 * @param size Size of the enabled I/O space.. 106 * 107 * @return 0 on success, EPERM if the caller lacks capabilities to use this syscall, 108 * ENOENT if there is no task matching the specified ID. 109 */ 110 static int ddi_iospace_enable(task_id_t id, __address ioaddr, size_t size) 63 111 { 64 112 ipl_t ipl; 65 113 cap_t caps; 66 114 task_t *t; 67 mem_backend_data_t backend_data; 68 69 backend_data.base = pf; 70 backend_data.frames = pages; 115 int rc; 71 116 72 117 /* … … 74 119 */ 75 120 caps = cap_get(TASK); 76 if (!(caps & CAP_ MEM_MANAGER))121 if (!(caps & CAP_IO_MANAGER)) 77 122 return EPERM; 78 123 … … 100 145 spinlock_lock(&t->lock); 101 146 spinlock_unlock(&tasks_lock); 102 103 if (!as_area_create(t->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE,104 &phys_backend, &backend_data)) {105 /*106 * The address space area could not have been created.107 * We report it using ENOMEM.108 */109 spinlock_unlock(&t->lock);110 interrupts_restore(ipl);111 return ENOMEM;112 }113 114 /*115 * Mapping is created on-demand during page fault.116 */117 118 spinlock_unlock(&t->lock);119 interrupts_restore(ipl);120 return 0;121 }122 123 /** Enable range of I/O space for task.124 *125 * @param id Task ID of the destination task.126 * @param ioaddr Starting I/O address.127 * @param size Size of the enabled I/O space..128 *129 * @return 0 on success, EPERM if the caller lacks capabilities to use this syscall,130 * ENOENT if there is no task matching the specified ID.131 */132 static int ddi_iospace_enable(task_id_t id, __address ioaddr, size_t size)133 {134 ipl_t ipl;135 cap_t caps;136 task_t *t;137 int rc;138 139 /*140 * Make sure the caller is authorised to make this syscall.141 */142 caps = cap_get(TASK);143 if (!(caps & CAP_IO_MANAGER))144 return EPERM;145 146 ipl = interrupts_disable();147 spinlock_lock(&tasks_lock);148 149 t = task_find_by_id(id);150 151 if (!t) {152 /*153 * There is no task with the specified ID.154 */155 spinlock_unlock(&tasks_lock);156 interrupts_restore(ipl);157 return ENOENT;158 }159 160 /*161 * TODO: We are currently lacking support for task destroying.162 * Once it is added to the kernel, we must take care to163 * synchronize in a way that prevents race conditions here.164 */165 166 /* Lock the task and release the lock protecting tasks_btree. */167 spinlock_lock(&t->lock);168 spinlock_unlock(&tasks_lock);169 147 170 148 rc = ddi_iospace_enable_arch(t, ioaddr, size); … … 177 155 /** Wrapper for SYS_MAP_PHYSMEM syscall. 178 156 * 179 * @param User space address of memory DDI argument structure. 157 * @param phys_base Physical base address to map 158 * @param virt_base Destination virtual address 159 * @param pages Number of pages 160 * @param flags Flags of newly mapped pages 180 161 * 181 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) 184 { 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), 193 ALIGN_DOWN((__address) arg.virt_base, PAGE_SIZE), (count_t) arg.pages, 194 (int) arg.flags); 164 __native sys_physmem_map(__native phys_base, __native virt_base, __native pages, 165 __native flags) 166 { 167 return (__native) ddi_physmem_map(ALIGN_DOWN((__address) phys_base, FRAME_SIZE), 168 ALIGN_DOWN((__address) virt_base, PAGE_SIZE), (count_t) pages, 169 (int) flags); 195 170 } 196 171
Note:
See TracChangeset
for help on using the changeset viewer.