embox

Форк
0
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 NOMMU
18

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

28
ARRAY_SPREAD_DEF(struct periph_memory_desc *, __periph_mem_registry);
29

30
EMBOX_UNIT_INIT(periph_memory_init);
31

32
struct _segment {
33
	uintptr_t start;
34
	uintptr_t end;
35
};
36
static struct _segment _segments[PERIPH_MAX_SEGMENTS];
37

38
static int _seg_cmp(const void *fst, const void *snd) {
39
	return ((struct _segment *) fst)->start -
40
		((struct _segment *) snd)->start;
41
}
42

43
/**
44
 * @brief Group peripheral memory into mmap-s
45
 */
46
static int periph_memory_init(void) {
47
	struct periph_memory_desc *desc;
48
	int seg_cnt = 0;
49

50
	array_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

57
	qsort(&_segments, seg_cnt, sizeof(struct _segment), _seg_cmp);
58

59
	int l = 0, r = 1;
60

61
	while (l < seg_cnt) {
62
		uintptr_t addr_start;
63
		uintptr_t addr_end;
64

65
		addr_start = _segments[l].start;
66
		addr_end = _segments[r - 1].end;
67

68
		while (r < seg_cnt &&
69
			(_segments[r].start <= addr_end)) {
70
			if (_segments[r].end > addr_end)
71
				addr_end = _segments[r].end;
72
			r++;
73
		}
74

75
		addr_start *= MMU_PAGE_SIZE;
76
		addr_end   *= MMU_PAGE_SIZE;
77

78
		if (mmap_place(task_resource_mmap(task_kernel_task()), addr_start,
79
					addr_end - addr_start,
80
					PROT_READ | PROT_WRITE | PROT_NOCACHE)) {
81
			return -ENOMEM;
82
		}
83

84
		l = r;
85
		r = l + 1;
86
	}
87

88
	return 0;
89
}
90

91
int periph_desc(struct periph_memory_desc **buff) {
92
	struct periph_memory_desc *elem;
93

94
	int i = 0;
95
	array_spread_foreach(elem, __periph_mem_registry) {
96
		buff[i++] = elem;
97
	}
98

99
	return i;
100
}
101

102
#endif /* NOMMU */
103

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.