Changeset c6ae4c2 in mainline
- Timestamp:
- 2011-12-16T21:12:52Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c8751452
- Parents:
- e2718e1
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
abi/include/ddi/arg.h
re2718e1 rc6ae4c2 36 36 #define ABI_DDI_ARG_H_ 37 37 38 #define DMAMEM_FLAGS_ANONYMOUS 0x01 39 38 40 /** Structure encapsulating arguments for SYS_PHYSMEM_MAP syscall. */ 39 41 typedef struct { -
abi/include/syscall.h
re2718e1 rc6ae4c2 85 85 SYS_DEVICE_ASSIGN_DEVNO, 86 86 SYS_PHYSMEM_MAP, 87 SYS_DMAMEM_MAP, 88 SYS_DMAMEM_UNMAP, 87 89 SYS_IOSPACE_ENABLE, 88 90 SYS_REGISTER_IRQ, -
kernel/generic/include/ddi/ddi.h
re2718e1 rc6ae4c2 55 55 extern void ddi_parea_register(parea_t *); 56 56 57 extern sysarg_t sys_physmem_map(sysarg_t, sysarg_t, sysarg_t, sysarg_t); 57 extern sysarg_t sys_physmem_map(uintptr_t, uintptr_t, size_t, unsigned int); 58 59 extern sysarg_t sys_dmamem_map(uintptr_t, size_t, unsigned int, unsigned int, 60 void *); 61 extern sysarg_t sys_dmamem_unmap(uintptr_t, size_t, unsigned int); 62 58 63 extern sysarg_t sys_iospace_enable(ddi_ioarg_t *); 59 64 -
kernel/generic/include/mm/page.h
re2718e1 rc6ae4c2 66 66 extern uintptr_t hw_map(uintptr_t, size_t); 67 67 68 extern sysarg_t sys_page_find_mapping(uintptr_t, uintptr_t *); 68 extern int page_find_mapping(uintptr_t, void **); 69 extern sysarg_t sys_page_find_mapping(uintptr_t, void *); 69 70 70 71 #endif -
kernel/generic/src/ddi/ddi.c
re2718e1 rc6ae4c2 45 45 #include <mm/frame.h> 46 46 #include <mm/as.h> 47 #include <mm/page.h> 47 48 #include <synch/mutex.h> 48 49 #include <syscall/copy.h> … … 52 53 #include <errno.h> 53 54 #include <trace.h> 55 #include <bitops.h> 54 56 55 57 /** This lock protects the parea_btree. */ … … 87 89 /** Map piece of physical memory into virtual address space of current task. 88 90 * 89 * @param p fPhysical address of the starting frame.90 * @param v pVirtual address of the starting page.91 * @param phys Physical address of the starting frame. 92 * @param virt Virtual address of the starting page. 91 93 * @param pages Number of pages to map. 92 94 * @param flags Address space area flags for the mapping. 93 95 * 94 * @return 0 on success, EPERM if the caller lacks capabilities to use this 95 * syscall, EBADMEM if pf or vf is not page aligned, ENOENT if there 96 * is no task matching the specified ID or the physical address space 97 * is not enabled for mapping and ENOMEM if there was a problem in 98 * creating address space area. 99 * 100 */ 101 NO_TRACE static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, size_t pages, 96 * @return EOK on success. 97 * @return EPERM if the caller lacks capabilities to use this syscall. 98 * @return EBADMEM if phys or virt is not page aligned. 99 * @return ENOENT if there is no task matching the specified ID or 100 * the physical address space is not enabled for mapping. 101 * @return ENOMEM if there was a problem in creating address space area. 102 * 103 */ 104 NO_TRACE static int ddi_physmem_map(uintptr_t phys, uintptr_t virt, size_t pages, 102 105 unsigned int flags) 103 106 { 104 107 ASSERT(TASK); 105 108 106 if ((p f% FRAME_SIZE) != 0)109 if ((phys % FRAME_SIZE) != 0) 107 110 return EBADMEM; 108 111 109 if ((v p% PAGE_SIZE) != 0)112 if ((virt % PAGE_SIZE) != 0) 110 113 return EBADMEM; 111 114 … … 118 121 119 122 mem_backend_data_t backend_data; 120 backend_data.base = p f;123 backend_data.base = phys; 121 124 backend_data.frames = pages; 122 125 … … 129 132 btree_node_t *nodep; 130 133 parea_t *parea = (parea_t *) btree_search(&parea_btree, 131 (btree_key_t) p f, &nodep);134 (btree_key_t) phys, &nodep); 132 135 133 136 if ((parea != NULL) && (parea->frames >= pages)) { … … 149 152 150 153 irq_spinlock_lock(&zones.lock, true); 151 size_t znum = find_zone(ADDR2PFN(p f), pages, 0);154 size_t znum = find_zone(ADDR2PFN(phys), pages, 0); 152 155 153 156 if (znum == (size_t) -1) { … … 182 185 183 186 map: 184 if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp,187 if (!as_area_create(TASK->as, flags, FRAMES2SIZE(pages), virt, 185 188 AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) { 186 189 /* … … 253 256 /** Wrapper for SYS_PHYSMEM_MAP syscall. 254 257 * 255 * @param phys _basePhysical base address to map256 * @param virt _baseDestination virtual address258 * @param phys Physical base address to map 259 * @param virt Destination virtual address 257 260 * @param pages Number of pages 258 261 * @param flags Flags of newly mapped pages … … 261 264 * 262 265 */ 263 sysarg_t sys_physmem_map( sysarg_t phys_base, sysarg_t virt_base,264 s ysarg_t pages, sysarg_t flags)265 { 266 return (sysarg_t) ddi_physmem_map(ALIGN_DOWN((uintptr_t) phys_base,267 FRAME_SIZE), ALIGN_DOWN((uintptr_t) virt_base, PAGE_SIZE),268 (size_t) pages, (int)flags);266 sysarg_t sys_physmem_map(uintptr_t phys, uintptr_t virt, 267 size_t pages, unsigned int flags) 268 { 269 return (sysarg_t) 270 ddi_physmem_map(ALIGN_DOWN(phys, FRAME_SIZE), 271 ALIGN_DOWN(virt, PAGE_SIZE), pages, flags); 269 272 } 270 273 … … 287 290 } 288 291 292 NO_TRACE static int dmamem_map(uintptr_t virt, size_t size, 293 unsigned int map_flags, unsigned int flags, void **phys) 294 { 295 ASSERT(TASK); 296 297 if ((flags & DMAMEM_FLAGS_ANONYMOUS) == 0) { 298 // TODO: implement locking of non-anonymous mapping 299 return page_find_mapping(virt, phys); 300 } else { 301 // TODO: implement locking 302 303 if ((virt % PAGE_SIZE) != 0) 304 return EBADMEM; 305 306 size_t pages = SIZE2FRAMES(size); 307 uint8_t order; 308 309 /* We need the 2^order >= pages */ 310 if (pages == 1) 311 order = 0; 312 else 313 order = fnzb(pages - 1) + 1; 314 315 *phys = frame_alloc_noreserve(order, 0); 316 if (*phys == NULL) 317 return ENOMEM; 318 319 mem_backend_data_t backend_data; 320 backend_data.base = (uintptr_t) *phys; 321 backend_data.frames = pages; 322 323 if (!as_area_create(TASK->as, map_flags, size, virt, 324 AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) { 325 frame_free_noreserve((uintptr_t) *phys); 326 return ENOMEM; 327 } 328 329 return EOK; 330 } 331 } 332 333 NO_TRACE static int dmamem_unmap(uintptr_t virt, size_t size, 334 unsigned int flags) 335 { 336 // TODO: implement unlocking & unmap 337 return EOK; 338 } 339 340 sysarg_t sys_dmamem_map(uintptr_t virt, size_t size, unsigned int map_flags, 341 unsigned int flags, void *phys_ptr) 342 { 343 void *phys; 344 int rc = dmamem_map(virt, size, map_flags, flags, &phys); 345 if (rc != EOK) 346 return rc; 347 348 rc = copy_to_uspace(phys_ptr, &phys, sizeof(phys)); 349 if (rc != EOK) { 350 dmamem_unmap(virt, size, flags); 351 return rc; 352 } 353 354 return EOK; 355 } 356 357 sysarg_t sys_dmamem_unmap(uintptr_t virt, size_t size, unsigned int flags) 358 { 359 return dmamem_unmap(virt, size, flags); 360 } 361 289 362 /** @} 290 363 */ -
kernel/generic/src/syscall/syscall.c
re2718e1 rc6ae4c2 176 176 (syshandler_t) sys_device_assign_devno, 177 177 (syshandler_t) sys_physmem_map, 178 (syshandler_t) sys_dmamem_map, 179 (syshandler_t) sys_dmamem_unmap, 178 180 (syshandler_t) sys_iospace_enable, 179 181 (syshandler_t) sys_register_irq, -
uspace/lib/c/generic/as.c
re2718e1 rc6ae4c2 117 117 /** Find mapping to physical address. 118 118 * 119 * @param address Virtual address in question (virtual). 120 * @param[out] frame Frame address (physical). 121 * @return Error code. 122 * @retval EOK No error, @p frame holds the translation. 123 * @retval ENOENT Mapping not found. 119 * @param virt Virtual address to find mapping for. 120 * @param[out] phys Physical adress. 121 * 122 * @return EOK on no error. 123 * @retval ENOENT if no mapping was found. 124 * 124 125 */ 125 int as_get_physical_mapping(const void * address, uintptr_t *frame)126 int as_get_physical_mapping(const void *virt, uintptr_t *phys) 126 127 { 127 uintptr_t tmp_frame; 128 uintptr_t virt = (uintptr_t) address; 129 130 int rc = (int) __SYSCALL2(SYS_PAGE_FIND_MAPPING, 131 (sysarg_t) virt, (sysarg_t) &tmp_frame); 132 if (rc != EOK) { 133 return rc; 134 } 135 136 if (frame != NULL) { 137 *frame = tmp_frame; 138 } 139 140 return EOK; 128 return (int) __SYSCALL2(SYS_PAGE_FIND_MAPPING, (sysarg_t) virt, 129 (sysarg_t) phys); 141 130 } 142 131 -
uspace/lib/c/generic/ddi.c
re2718e1 rc6ae4c2 33 33 */ 34 34 35 #include <assert.h> 36 #include <unistd.h> 37 #include <errno.h> 35 38 #include <sys/types.h> 36 39 #include <abi/ddi/arg.h> … … 57 60 * Caller of this function must have the CAP_MEM_MANAGER capability. 58 61 * 59 * @param p fPhysical address of the starting frame.60 * @param v pVirtual address of the starting page.62 * @param phys Physical address of the starting frame. 63 * @param virt Virtual address of the starting page. 61 64 * @param pages Number of pages to map. 62 65 * @param flags Flags for the new address space area. … … 69 72 * 70 73 */ 71 int physmem_map(void *p f, void *vp, size_t pages, unsigned int flags)74 int physmem_map(void *phys, void *virt, size_t pages, unsigned int flags) 72 75 { 73 return __SYSCALL4(SYS_PHYSMEM_MAP, (sysarg_t) p f, (sysarg_t) vp,74 pages, flags);76 return __SYSCALL4(SYS_PHYSMEM_MAP, (sysarg_t) phys, 77 (sysarg_t) virt, pages, flags); 75 78 } 76 79 77 int dmamem_map( dmamem_t *dmamem, size_t pages, unsigned int map_flags,78 unsigned int dma_flags)80 int dmamem_map(void *virt, size_t size, unsigned int map_flags, 81 unsigned int flags, void **phys) 79 82 { 80 // FIXME TODO 81 return -1; 83 return (int) __SYSCALL5(SYS_DMAMEM_MAP, (sysarg_t) virt, 84 (sysarg_t) size, (sysarg_t) map_flags, (sysarg_t) flags, 85 (sysarg_t) phys); 82 86 } 83 87 84 int dmamem_unmap(dmamem_t *dmamem) 88 int dmamem_map_anonymous(size_t size, unsigned int map_flags, 89 unsigned int flags, void **phys, void **virt) 85 90 { 86 // FIXME TODO 87 return -1; 91 *virt = as_get_mappable_page(size); 92 if (*virt == NULL) 93 return ENOMEM; 94 95 return dmamem_map(*virt, size, map_flags, 96 flags | DMAMEM_FLAGS_ANONYMOUS, phys); 88 97 } 89 98 90 int dmamem_ lock(void *virt, void **phys, size_t pages)99 int dmamem_unmap(void *virt, size_t size, unsigned int flags) 91 100 { 92 // FIXME TODO93 return -1;101 return __SYSCALL3(SYS_DMAMEM_UNMAP, (sysarg_t) virt, (sysarg_t) size, 102 (sysarg_t) flags); 94 103 } 95 104 96 int dmamem_un lock(void *virt, size_t pages)105 int dmamem_unmap_anonymous(void *virt) 97 106 { 98 // FIXME TODO99 return -1;107 return __SYSCALL3(SYS_DMAMEM_UNMAP, (sysarg_t) virt, 0, 108 DMAMEM_FLAGS_ANONYMOUS); 100 109 } 101 110 -
uspace/lib/c/include/ddi.h
re2718e1 rc6ae4c2 40 40 #include <task.h> 41 41 42 typedef struct { 43 /** Physical memory */ 44 void *phys; 45 46 /** Virtual memory */ 47 void *virt; 48 49 /** Size in pages */ 50 size_t size; 51 52 /** Mapping flags */ 53 unsigned int flags; 54 } dmamem_t; 42 extern int device_assign_devno(void); 55 43 56 extern int device_assign_devno(void);57 44 extern int physmem_map(void *, void *, size_t, unsigned int); 58 extern int dmamem_map(dmamem_t *, size_t, unsigned int, unsigned int); 59 extern int dmamem_unmap(dmamem_t *); 60 extern int dmamem_lock(void *, void **, size_t); 61 extern int dmamem_unlock(void *, size_t); 45 46 extern int dmamem_map(void *, size_t, unsigned int, unsigned int, void **); 47 extern int dmamem_map_anonymous(size_t, unsigned int, unsigned int, void **, 48 void **); 49 extern int dmamem_unmap(void *, size_t, unsigned int); 50 extern int dmamem_unmap_anonymous(void *); 51 62 52 extern int iospace_enable(task_id_t, void *, unsigned long); 63 53 extern int pio_enable(void *, size_t, void **); 54 64 55 extern int register_irq(int, int, int, irq_code_t *); 65 56 extern int unregister_irq(int, int); -
uspace/lib/nic/include/nic.h
re2718e1 rc6ae4c2 275 275 276 276 /* Packet DMA lock */ 277 extern void *nic_dma_lock_packet(packet_t*);278 extern int nic_dma_unlock_packet(packet_t * );277 extern int nic_dma_lock_packet(packet_t *, size_t, void **); 278 extern int nic_dma_unlock_packet(packet_t *, size_t); 279 279 280 280 #endif // __NIC_H__ -
uspace/lib/nic/src/nic_driver.c
re2718e1 rc6ae4c2 46 46 #include <ipc/irc.h> 47 47 #include <sysinfo.h> 48 48 #include <as.h> 49 49 #include <devman.h> 50 50 #include <ddf/interrupt.h> … … 1334 1334 * @return physical address of packet 1335 1335 */ 1336 void *nic_dma_lock_packet(packet_t *packet) 1337 { 1338 void *phys_addr; 1339 int rc = dmamem_lock(packet, &phys_addr, 1); 1340 if (rc != EOK) 1341 return NULL; 1342 1343 return phys_addr; 1336 int nic_dma_lock_packet(packet_t *packet, size_t size, void **phys) 1337 { 1338 return dmamem_map(packet, SIZE2PAGES(size), 0, 0, phys); 1344 1339 } 1345 1340 … … 1348 1343 * @param packet 1349 1344 */ 1350 int nic_dma_unlock_packet(packet_t *packet )1351 { 1352 return dmamem_un lock(packet, 1);1345 int nic_dma_unlock_packet(packet_t *packet, size_t size) 1346 { 1347 return dmamem_unmap(packet, size, 0); 1353 1348 } 1354 1349
Note:
See TracChangeset
for help on using the changeset viewer.