embox
102 строки · 2.0 Кб
1/**
2* @file memory.c
3* @brief
4* @author Denis Deryugin <deryugin.denis@gmail.com>
5* @version
6* @date 2016-08-11
7*/
8
9#include <errno.h>10#include <stdlib.h>11#include <sys/mman.h>12
13#include <mem/vmem.h>14#include <mem/sysmalloc.h>15#include <module/embox/arch/mmu.h>16
17#ifndef NOMMU18
19#include <drivers/common/memory.h>20#include <hal/mmu.h>21#include <kernel/task/kernel_task.h>22#include <kernel/task/resource/mmap.h>23#include <mem/misc/pool.h>24#include <mem/mmap.h>25#include <embox/unit.h>26#include <lib/libds/array.h>27
28ARRAY_SPREAD_DEF(struct periph_memory_desc *, __periph_mem_registry);29
30EMBOX_UNIT_INIT(periph_memory_init);31
32struct _segment {33uintptr_t start;34uintptr_t end;35};36static struct _segment _segments[PERIPH_MAX_SEGMENTS];37
38static int _seg_cmp(const void *fst, const void *snd) {39return ((struct _segment *) fst)->start -40((struct _segment *) snd)->start;41}
42
43/**
44* @brief Group peripheral memory into mmap-s
45*/
46static int periph_memory_init(void) {47struct periph_memory_desc *desc;48int seg_cnt = 0;49
50array_spread_foreach(desc, __periph_mem_registry) {51_segments[seg_cnt++] = (struct _segment) {52.start = desc->start / MMU_PAGE_SIZE,53.end = (desc->start + desc->len + MMU_PAGE_MASK) / MMU_PAGE_SIZE,54};55}56
57qsort(&_segments, seg_cnt, sizeof(struct _segment), _seg_cmp);58
59int l = 0, r = 1;60
61while (l < seg_cnt) {62uintptr_t addr_start;63uintptr_t addr_end;64
65addr_start = _segments[l].start;66addr_end = _segments[r - 1].end;67
68while (r < seg_cnt &&69(_segments[r].start <= addr_end)) {70if (_segments[r].end > addr_end)71addr_end = _segments[r].end;72r++;73}74
75addr_start *= MMU_PAGE_SIZE;76addr_end *= MMU_PAGE_SIZE;77
78if (mmap_place(task_resource_mmap(task_kernel_task()), addr_start,79addr_end - addr_start,80PROT_READ | PROT_WRITE | PROT_NOCACHE)) {81return -ENOMEM;82}83
84l = r;85r = l + 1;86}87
88return 0;89}
90
91int periph_desc(struct periph_memory_desc **buff) {92struct periph_memory_desc *elem;93
94int i = 0;95array_spread_foreach(elem, __periph_mem_registry) {96buff[i++] = elem;97}98
99return i;100}
101
102#endif /* NOMMU */103