Updates multiboot code for amd64
[akaros.git] / kern / src / multiboot.c
1 /* Copyright (c) 2009,13 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * Kevin Klues <klueska@cs.berkeley.edu>
4  * See LICENSE for details. 
5  *
6  * Multiboot parsing. */
7
8 #include <multiboot.h>
9 #include <ros/common.h>
10 #include <arch/mmu.h>
11 #include <arch/arch.h>
12 #include <ros/memlayout.h>
13 #include <stdio.h>
14
15 #ifdef CONFIG_X86
16 #include <arch/apic.h>
17 #endif
18
19 physaddr_t maxpa;               /* Maximum physical address in the system */
20 physaddr_t maxaddrpa;   /* Maximum addressable physical address */
21 size_t npages;                  /* Total number of physical memory pages */
22 size_t naddrpages;              /* num of addressable physical memory pages */
23
24 static size_t basemem;  /* Amount of base memory (in bytes) */
25 static size_t extmem;   /* Amount of extended memory (in bytes) */
26
27 /* This only notices bios detectable memory - there's a lot more in the higher
28  * paddrs. */
29 void mboot_detect_memory(multiboot_info_t *mbi)
30 {
31         if (!(mbi->flags & MULTIBOOT_INFO_MEMORY)) {
32                 printk("No BIOS memory info from multiboot, crash impending!\n");
33                 return;
34         }
35         /* mem_lower and upper are measured in KB.  They are 32 bit values, so we're
36          * limited to 4TB total. */
37         size_t basemem = ROUNDDOWN((size_t)mbi->mem_lower * 1024, PGSIZE);
38         size_t extmem = ROUNDDOWN((size_t)mbi->mem_upper * 1024, PGSIZE);
39         /* Calculate the maximum physical address based on whether or not there is
40          * any extended memory. */
41         if (extmem)
42                 maxpa = EXTPHYSMEM + extmem;
43         else
44                 maxpa = basemem;
45         npages = maxpa / PGSIZE;
46         /* KERN_VMAP_TOP - KERNBASE is the max amount of virtual addresses we can
47          * use for the physical memory mapping (aka - the KERNBASE mapping) */
48         maxaddrpa = MIN(maxpa, KERN_VMAP_TOP - KERNBASE);
49         naddrpages = maxaddrpa / PGSIZE;
50         printk("Physical memory: %luK available, ", maxpa / 1024);
51         printk("base = %luK, extended = %luK\n", basemem / 1024, extmem / 1024);
52         printk("Maximum directly addressable physical memory: %luK\n",
53                maxaddrpa / 1024);
54 }
55
56 /* TODO: Use the info from this for our free pages, instead of just using
57  * the extended memory */
58 void mboot_print_mmap(multiboot_info_t *mbi)
59 {
60         multiboot_memory_map_t *mmap_b, *mmap_e, *mmap_i;
61         if (!(mbi->flags & MULTIBOOT_INFO_ELF_SHDR)) {
62                 printk("No memory mapping info from multiboot\n");
63                 return;
64         }
65         mmap_b = (multiboot_memory_map_t*)((size_t)mbi->mmap_addr + KERNBASE);
66         mmap_e = (multiboot_memory_map_t*)((size_t)mbi->mmap_addr + KERNBASE
67                                            + mbi->mmap_length);
68         printd("mmap_addr = %p, mmap_length = %p\n", mbi->mmap_addr,
69                mbi->mmap_length);
70         printd("mmap_b %p, mmap_e %p\n", mmap_b, mmap_e);
71         /* Note when we incremement mmap_i, we add in the value of size... */
72         for (mmap_i = mmap_b;
73              mmap_i < mmap_e;
74              mmap_i = (multiboot_memory_map_t*)((void*)mmap_i + mmap_i->size
75                                                 + sizeof(mmap_i->size))) {
76                 printk("base = 0x%016llx, length = 0x%016llx : %s\n",
77                        mmap_i->addr, mmap_i->len,
78                        mmap_i->type == MULTIBOOT_MEMORY_AVAILABLE ? "FREE" :
79                                                                     "RESERVED");
80         }
81 }
82