-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplatform.c
More file actions
103 lines (85 loc) · 2.82 KB
/
Copy pathplatform.c
File metadata and controls
103 lines (85 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/* SPDX-License-Identifier: MIT */
#include <pmm.h>
#include <stdlib.h>
#include <multiboot2.h>
#include <init.h>
#include <platform.h>
#ifndef MEMBASE
#define MEMBASE 0x0
#endif
#define DEFAULT_MEMEND (16 * 1024 * 1024)
#define HIGHMEM_PADDR 0x100000
multiboot2_info_t *mbt_info __section(".data");
mmu_initial_mapping_t mmu_initial_mappings[] = {
{.phys = MEMBASE,
.virt = KERNEL_ASPACE_BASE,
.size = 64ULL * 1024 * 1024 * 1024, /* 64 GiB */
.name = "memory"},
{.phys = MEMBASE,
.virt = KERNEL_VMA_BASE,
.size = 1ULL * 1024 * 1024 * 1024, /* 1 GiB */
.name = "kernel"},
{0}
};
typedef struct phys_zone {
paddr_t base;
size_t size;
} phys_zone_t;
typedef struct boot_state {
uint32_t mem_lower;
phys_zone_t mem_high_zones[10];
size_t num_high_zones;
} boot_state_t;
boot_state_t bst;
static pmm_zone_t phy_zones[10];
void __init_func init_boot_state(void)
{
mbt_info = (multiboot2_info_t *)((uintptr_t)mbt_info + KERNEL_VMA_BASE);
multiboot2_tag_t const *tag = mbt_info->tags;
multiboot2_tag_t const *end_tag =
(multiboot2_tag_t *)((uintptr_t)mbt_info + mbt_info->total_size);
while (tag < end_tag && tag->type != MULTIBOOT2_TAG_TYPE_END) {
switch (tag->type) {
case MULTIBOOT2_TAG_TYPE_MMAP:;
multiboot2_mmap_entry_t *s =
((multiboot2_tag_mmap_t *)tag)->entries;
multiboot2_mmap_entry_t *e =
(multiboot2_mmap_entry_t *)((uintptr_t)tag + tag->size);
uint32_t count = 0;
for (multiboot2_mmap_entry_t const *mmap = s; mmap < e; mmap++) {
/* save the low memory */
if (!mmap->addr) {
bst.mem_lower = mmap->len;
}
/* add the high memory region to available physical zones */
if (mmap->type == MULTIBOOT2_MMAP_MEMORY_AVAILABLE &&
mmap->addr >= HIGHMEM_PADDR) {
bst.mem_high_zones[count++] = (phys_zone_t){
.base = mmap->addr,
.size = mmap->len,
};
bst.num_high_zones++;
}
}
break;
}
/* point to the next tag */
tag =
(multiboot2_tag_t const *)((uintptr_t)tag + ROUND_UP(tag->size, 8));
}
}
static void pmm_zone_init(void)
{
for (uint32_t i = 0; i < bst.num_high_zones; ++i) {
phy_zones[i].base = ROUND_UP(bst.mem_high_zones[i].base, PAGE_SIZE);
phy_zones[i].size = ROUND_DOWN(bst.mem_high_zones[i].size, PAGE_SIZE);
pmm_add_zone(&phy_zones[i]);
}
}
void platform_init(void)
{
platform_init_debug(); /* setup serial debugging */
platform_init_console(); /* setup the text console */
init_boot_state();
pmm_zone_init();
}