blob: a38e48bd5056410d9be0b7cdc319f3a730c05e6a (
plain) (
blame)
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
// MIT License, Copyright (c) 2021 Marvin Borner
// Memory map generator
#include <log.h>
#include <memory.h>
#include <panic.h>
#include <real.h>
/**
* Memory map using e820 BIOS call
*/
#define E820_MAX_ENTRIES 256 // Spec
enum e820_entry_type {
E820_MEMORY_NONE,
E820_MEMORY_USABLE,
E820_MEMORY_RESERVED,
E820_MEMORY_RECLAIMABLE,
E820_MEMORY_ACPI_NVS,
E820_MEMORY_UNUSABLE,
};
struct e820_entry {
u32 base_low;
u32 base_high;
u32 length_low;
u32 length_high;
enum e820_entry_type type;
u32 unused;
} PACKED;
u16 e820_count = 0;
struct e820_entry e820_map[E820_MAX_ENTRIES] = { 0 };
static u8 memory_e820(void)
{
struct real_regs r = { 0 };
for (u32 i = 0; i < E820_MAX_ENTRIES; i++) {
struct e820_entry entry = { 0 };
r.eax = 0xe820;
r.ecx = 24;
r.edx = 0x534d4150;
r.edi = (u32)&entry;
real_int(0x15, &r, &r);
if (r.eflags & EFLAGS_CF) {
e820_count = i;
return 1;
}
e820_map[i] = entry;
if (!r.ebx) {
e820_count = i++;
return 1;
}
}
return 0;
}
/**
* Configure memory map
*/
#define MAP_MAX_ENTRIES 256
static struct memory_entry mem[MAP_MAX_ENTRIES] = { 0 };
static struct memory_map map = { .entry = mem, .count = 0 };
static void memory_map_e820(void)
{
u32 i;
for (i = 0; i < COUNT(e820_map); i++) {
struct e820_entry *e820_entry = &e820_map[i];
struct memory_entry *map_entry = &mem[i];
map_entry->base = e820_entry->base_low;
map_entry->length = e820_entry->length_low;
// Set type accordingly
switch (e820_entry->type) {
case E820_MEMORY_NONE:
map_entry->type = MEMORY_USABLE;
continue;
case E820_MEMORY_USABLE:
map_entry->type = MEMORY_USABLE;
break;
case E820_MEMORY_RESERVED:
map_entry->type = MEMORY_RESERVED;
break;
case E820_MEMORY_RECLAIMABLE:
map_entry->type = MEMORY_RECLAIMABLE;
break;
case E820_MEMORY_ACPI_NVS:
map_entry->type = MEMORY_ACPI_NVS;
break;
case E820_MEMORY_UNUSABLE:
map_entry->type = MEMORY_UNUSABLE;
break;
default:
panic("Unknown e820 type\n");
}
}
map.count = i;
}
struct memory_map *memory_map_get(void)
{
return ↦
}
void memory_map(void)
{
if (memory_e820()) {
memory_map_e820();
return;
}
panic("Couldn't find memory map\n");
}
|