summaryrefslogtreecommitdiff
path: root/src/boot/mod_mem_map.c
blob: aee2cc9eb3a4afbe050dafc2728730f6aaa7f438 (plain)
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
#include "mod_mem_map.h"

#include "../output/vga_character.h"

__asm__(".code16gcc\n");

struct bios_address_descriptor {
  uint32_t base_addr_low;
  uint32_t base_addr_high;
  uint32_t length_low;
  uint32_t length_high;
  uint32_t type;
};

uint32_t bios_mem_map_range(uint32_t continuation);
void show_bios_mem_descriptor(struct bios_address_descriptor descriptor);

static struct bios_address_descriptor curr_address_descriptor;

void populate_memory_map(void) {
  vga_graphics_newln();
  vga_graphics_return();
  vga_graphics_write_str("system_memory_map = ");
  vga_graphics_newln();
  vga_graphics_return();
  uint32_t cont = 0;
  do {
    cont = bios_mem_map_range(cont);
    //vga_graphics_int_hex(cont);
    show_bios_mem_descriptor(curr_address_descriptor);
  } while (cont != 0);
}


void show_bios_mem_descriptor(struct bios_address_descriptor descriptor) {
  vga_graphics_write_str("descriptor: ");
  vga_graphics_write_str(" base: 0x");
  vga_graphics_int_hex(descriptor.base_addr_high);
  vga_graphics_int_hex(descriptor.base_addr_low);
  vga_graphics_write_str(" length: 0x");
  vga_graphics_int_hex(descriptor.length_high);
  vga_graphics_int_hex(descriptor.length_low);
  vga_graphics_write_str(" ");
  vga_graphics_int_hex(descriptor.type);
  vga_graphics_return();
  vga_graphics_newln();
}

uint32_t bios_mem_map_range(uint32_t continuation) {
// I know I really want the bottom 16 bits of this address. So no warning, thanks.
#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
  uint16_t address_descriptor = (uint16_t)(&curr_address_descriptor);
#pragma GCC diagnostic pop
  __asm__(
    "push %%es                    \n"
    "mov %0, %%ebx                \n"
    "mov $0xE820, %%eax           \n"
    "mov %1, %%di                 \n"
    "mov $0, %%cx                 \n"
    "mov %%cx, %%es               \n"
    "mov $0x14, %%ecx             \n"
    "mov $0x534d4150, %%edx       \n"
    "int $0x15                    \n"
    "mov %%ebx, %0                \n"
    "pop %%es                     \n"
    :"+r"(continuation)
    :"r"(address_descriptor)
    : "%eax", "%ebx", "%ecx", "%edx", "cc"
  );
  return continuation;
}