]> git.buserror.net Git - polintos/scott/priv.git/blob - kernel/arch/x64/multiboot.cc
b06651ee7ce3f69b5c0be43a12a096896c899069
[polintos/scott/priv.git] / kernel / arch / x64 / multiboot.cc
1 // arch/x64/multiboot.cc -- Code to interpret multiboot data and initialize
2 //                          free memory regions based thereupon.
3 //
4 // This software is copyright (c) 2006 Scott Wood <scott@buserror.net>.
5 // 
6 // Permission is hereby granted, free of charge, to any person obtaining a copy of
7 // this software and associated documentation files (the "Software"), to deal with
8 // the Software without restriction, including without limitation the rights to
9 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10 // of the Software, and to permit persons to whom the Software is furnished to do
11 // so, subject to the following conditions:
12 // 
13 //     * Redistributions of source code must retain the above copyright notice,
14 //       this list of conditions and the following disclaimers.
15 // 
16 //     * Redistributions in binary form must reproduce the above copyright notice,
17 //       this list of conditions and the following disclaimers in the
18 //       documentation and/or other materials provided with the distribution.
19 // 
20 //     * The names of the Software's authors and/or contributors
21 //       may not be used to endorse or promote products derived from
22 //       this Software without specific prior written permission.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
26 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
27 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
30 // SOFTWARE.
31
32 #include <kern/libc.h>
33 #include <kern/pagealloc.h>
34
35 #include <arch/multiboot.h>
36 #include <arch/addrs.h>
37 #include <arch/paging.h>
38 #include <arch/mem.h>
39
40 #include <limits.h>
41
42 u32 x64_boot_info_phys;
43
44 namespace Arch {
45 namespace Priv {
46 namespace MultiBoot {
47         BootInfo *boot_info;
48
49         void parse_mmap()
50         {
51         }
52         
53         void make_mem_avail(uintptr_t page_start, uintptr_t page_end)
54         {
55                 using Mem::pages;
56                         
57                 if (page_start < dma32zonestart) {
58                         size_t len;
59                         
60                         if (page_end <= dma32zonestart)
61                                 len = page_end - page_start;
62                         else
63                                 len = dma32zonestart - page_start;
64                         
65                         isadmazone.free(&pages[page_start], len);
66                         page_start = dma32zonestart;
67                 }
68
69                 if (page_start < highzonestart && page_end > dma32zonestart) {
70                         size_t len;
71                         
72                         if (page_end <= highzonestart)
73                                 len = page_end - page_start;
74                         else
75                                 len = highzonestart - page_start;
76                         
77                         dma32zone.free(&pages[page_start], len);
78                         page_start = highzonestart;
79                 }
80
81                 if (page_end > highzonestart)
82                         dma32zone.free(&pages[page_start], page_end - highzonestart);
83         }
84
85         void process_info()
86         {
87                 if (x64_boot_info_phys > max_ktext_map) {
88                         printf("Cannot access boot info at %#.8x\n", x64_boot_info_phys);
89                         for(;;);
90                 }
91                 
92                 boot_info = (BootInfo *)phys_to_ktext(x64_boot_info_phys);
93                 mem_end = 0;
94
95                 if (!(boot_info->flags & (1 << BootInfo::flag_mmap))) {
96                         // FIXME: use mem_lower and mem_upper in this case.
97                         printf("MultiBoot info does not contain a memory map.\n");
98                         for(;;);
99                 }
100
101                 printf("BIOS Memory Map:\n");
102
103                 uint off = 0;
104                 while (off < boot_info->mmap_length) {
105                         u32 phys = boot_info->mmap_addr + off;
106                 
107                         if (phys > max_ktext_map) {
108                                 printf("Cannot access BIOS memory map entry at %#.8x\n", phys);
109                                 for(;;);
110                         }
111                         
112                         MemMap *mmap = (MemMap *)phys_to_ktext(phys);
113                         
114                         printf("0x%016llx - 0x%016llx, type %d\n",
115                                mmap->base, mmap->base + mmap->len - 1, mmap->type);
116                 
117                         off += mmap->size + 4;
118                         
119                         if (mmap->type == MemMap::Available) {
120                                 size_t page_end = (mmap->base + mmap->len) / page_size;
121                                 
122                                 if (page_end > mem_end)
123                                         mem_end = page_end;
124                         }
125                 }
126                 
127                 map_physmem();
128                 
129                 off = 0;
130                 while (off < boot_info->mmap_length) {
131                         u32 phys = boot_info->mmap_addr + off;
132                         MemMap *mmap = (MemMap *)phys_to_ktext(phys);
133                         off += mmap->size + 4;
134                         
135                         if (mmap->type == MemMap::Available) {
136                                 // Don't use any page that isn't fully in this entry.
137
138                                 size_t page_start = (mmap->base + page_size - 1) / page_size;
139                                 size_t page_end = (mmap->base + mmap->len) / page_size;
140                                 
141
142                                 // Don't make available any pages that overlap the
143                                 // kernel text/data or bootmem allocations.
144                                 
145                                 uintptr_t kernelendpage = 
146                                         (kvirt_to_phys((void *)next_free_bootmem) + page_size - 1) /
147                                         page_size;
148                                 
149                                 // Don't overwrite page 1; the BIOS will need it for later calls in
150                                 // emulation, and at least the BIOS I'm testing on doesn't mark
151                                 // it as reserved.
152                 
153                                 if (page_start == 0)
154                                         page_start = 1;
155                                 if (page_start >= page_end)
156                                         continue;
157                                 
158                                 if (page_start <= kernelendpage && page_end >= 512) {
159                                         if (page_start < 512)
160                                                 make_mem_avail(page_start, 512);
161                                         
162                                         if (page_end > kernelendpage)
163                                                 make_mem_avail(kernelendpage + 1, page_end);
164                                 } else {
165                                         make_mem_avail(page_start, page_end);
166                                 }
167                         }
168                 }
169         }
170 }
171 }
172 }