Changeset f8ddd17 in mainline for kernel/generic/src/ddi/ddi.c
- Timestamp:
- 2006-12-09T20:20:50Z (18 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- b82a13c
- Parents:
- 9ab9c2ec
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ddi/ddi.c
r9ab9c2ec rf8ddd17 48 48 #include <synch/spinlock.h> 49 49 #include <syscall/copy.h> 50 #include <adt/btree.h> 50 51 #include <arch.h> 51 52 #include <align.h> 52 53 #include <errno.h> 53 54 55 /** This lock protects the parea_btree. */ 56 SPINLOCK_INITIALIZE(parea_lock); 57 58 /** B+tree with enabled physical memory areas. */ 59 static btree_t parea_btree; 60 61 /** Initialize DDI. */ 62 void ddi_init(void) 63 { 64 btree_create(&parea_btree); 65 } 66 67 /** Enable piece of physical memory for mapping by physmem_map(). 68 * 69 * @param parea Pointer to physical area structure. 70 * 71 * @todo This function doesn't check for overlaps. It depends on the kernel to 72 * create disjunct physical memory areas. 73 */ 74 void ddi_parea_register(parea_t *parea) 75 { 76 ipl_t ipl; 77 78 ipl = interrupts_disable(); 79 spinlock_lock(&parea_lock); 80 81 /* 82 * TODO: we should really check for overlaps here. 83 * However, we should be safe because the kernel is pretty sane and 84 * memory of different devices doesn't overlap. 85 */ 86 btree_insert(&parea_btree, (btree_key_t) parea->pbase, parea, NULL); 87 88 spinlock_unlock(&parea_lock); 89 interrupts_restore(ipl); 90 } 91 54 92 /** Map piece of physical memory into virtual address space of current task. 55 93 * 56 * @param pf Physical frameaddress of the starting frame.57 * @param vp Virtual pageaddress of the starting page.94 * @param pf Physical address of the starting frame. 95 * @param vp Virtual address of the starting page. 58 96 * @param pages Number of pages to map. 59 97 * @param flags Address space area flags for the mapping. 60 98 * 61 * @return 0 on success, EPERM if the caller lacks capabilities to use this syscall, 62 * ENOENT if there is no task matching the specified ID and ENOMEM if 63 * there was a problem in creating address space area. 99 * @return 0 on success, EPERM if the caller lacks capabilities to use this 100 * syscall, ENOENT if there is no task matching the specified ID or the 101 * physical address space is not enabled for mapping and ENOMEM if there 102 * was a problem in creating address space area. ENOTSUP is returned when 103 * an attempt to create an illegal address alias is detected. 64 104 */ 65 105 static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, count_t pages, int flags) … … 80 120 81 121 ipl = interrupts_disable(); 122 123 /* 124 * Check if the physical memory area is enabled for mapping. 125 * If the architecture supports virtually indexed caches, intercept 126 * attempts to create an illegal address alias. 127 */ 128 spinlock_lock(&parea_lock); 129 parea_t *parea; 130 btree_node_t *nodep; 131 parea = btree_search(&parea_btree, (btree_key_t) pf, &nodep); 132 if (!parea || parea->frames < pages || ((flags & AS_AREA_CACHEABLE) && 133 !parea->cacheable) || (!(flags & AS_AREA_CACHEABLE) && 134 parea->cacheable)) { 135 /* 136 * This physical memory area cannot be mapped. 137 */ 138 spinlock_unlock(&parea_lock); 139 interrupts_restore(ipl); 140 return ENOENT; 141 } 142 143 #ifdef CONFIG_VIRT_IDX_DCACHE 144 if (PAGE_COLOR(parea->vbase) != PAGE_COLOR(vp)) { 145 /* 146 * Refuse to create an illegal address alias. 147 */ 148 spinlock_unlock(&parea_lock); 149 interrupts_restore(ipl); 150 return ENOTSUP; 151 } 152 #endif /* CONFIG_VIRT_IDX_DCACHE */ 153 154 spinlock_unlock(&parea_lock); 155 82 156 spinlock_lock(&TASK->lock); 83 157 … … 108 182 * @param size Size of the enabled I/O space.. 109 183 * 110 * @return 0 on success, EPERM if the caller lacks capabilities to use this syscall,111 * 184 * @return 0 on success, EPERM if the caller lacks capabilities to use this 185 * syscall, ENOENT if there is no task matching the specified ID. 112 186 */ 113 187 static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size) … … 161 235 * @return 0 on success, otherwise it returns error code found in errno.h 162 236 */ 163 unative_t sys_physmem_map(unative_t phys_base, unative_t virt_base, unative_t pages,164 165 { 166 return (unative_t) ddi_physmem_map(ALIGN_DOWN((uintptr_t) phys_base, FRAME_SIZE),167 ALIGN_DOWN((uintptr_t) virt_base, PAGE_SIZE), (count_t) pages,168 237 unative_t sys_physmem_map(unative_t phys_base, unative_t virt_base, unative_t 238 pages, unative_t flags) 239 { 240 return (unative_t) ddi_physmem_map(ALIGN_DOWN((uintptr_t) phys_base, 241 FRAME_SIZE), ALIGN_DOWN((uintptr_t) virt_base, PAGE_SIZE), 242 (count_t) pages, (int) flags); 169 243 } 170 244 … … 184 258 return (unative_t) rc; 185 259 186 return (unative_t) ddi_iospace_enable((task_id_t) arg.task_id, (uintptr_t) arg.ioaddr, (size_t) arg.size); 260 return (unative_t) ddi_iospace_enable((task_id_t) arg.task_id, 261 (uintptr_t) arg.ioaddr, (size_t) arg.size); 187 262 } 188 263 189 264 /** Disable or enable preemption. 190 265 * 191 * @param enable If non-zero, the preemption counter will be decremented, leading to potential192 * enabling of preemption. Otherwise the preemption counter will be incremented,193 * 266 * @param enable If non-zero, the preemption counter will be decremented, 267 * leading to potential enabling of preemption. Otherwise the preemption 268 * counter will be incremented, preventing preemption from occurring. 194 269 * 195 270 * @return Zero on success or EPERM if callers capabilities are not sufficient.
Note:
See TracChangeset
for help on using the changeset viewer.