diff options
author | Neal H. Walfield <neal@gnu.org> | 2009-03-01 20:05:02 +0100 |
---|---|---|
committer | Neal H. Walfield <neal@gnu.org> | 2009-03-01 21:03:14 +0100 |
commit | 7679645a02e563cc617c57aeb4c208d9a1d442ed (patch) | |
tree | e310dc6181c0a19a81c628a1469d8bf6c0696621 | |
parent | 9f7c4845c850d86e5e813d309422812ec372eb4b (diff) |
Fix multiboot.h for 64-bit machines. Remove some workarounds for Grub.
-rw-r--r-- | viengoos/memory.c | 12 | ||||
-rw-r--r-- | viengoos/sysdeps/generic/multiboot.h | 2 | ||||
-rw-r--r-- | viengoos/sysdeps/x86_64/boot64.c | 83 | ||||
-rw-r--r-- | viengoos/sysdeps/x86_64/vm.c | 14 |
4 files changed, 69 insertions, 42 deletions
diff --git a/viengoos/memory.c b/viengoos/memory.c index 57e82a6..3ff4ca8 100644 --- a/viengoos/memory.c +++ b/viengoos/memory.c @@ -252,17 +252,7 @@ memory_add (uintptr_t start, uintptr_t end) if (first || start < first_frame) first_frame = start; if (first || end - (PAGESIZE - 1) > last_frame) - { - debug (0, "Extending last frame from %p to %p", - last_frame, end - (PAGESIZE - 1)); - /* XXX: Grub2 reports the wrong ranges. This is another - workaround when memory is freed later (e.g., when freeing the - multboot info record). */ - if (! object_descs) - last_frame = end - (PAGESIZE - 1); - else - end = last_frame; - } + last_frame = end - (PAGESIZE - 1); uintptr_t start_reservation; uintptr_t end_reservation; diff --git a/viengoos/sysdeps/generic/multiboot.h b/viengoos/sysdeps/generic/multiboot.h index 59d7995..063c649 100644 --- a/viengoos/sysdeps/generic/multiboot.h +++ b/viengoos/sysdeps/generic/multiboot.h @@ -116,6 +116,6 @@ typedef struct memory_map uint64_t base_addr; uint64_t length; uint32_t type; -} memory_map_t; +} __attribute__ ((packed)) memory_map_t; #endif /* ! ASM */ diff --git a/viengoos/sysdeps/x86_64/boot64.c b/viengoos/sysdeps/x86_64/boot64.c index 11ae0d5..e398a6d 100644 --- a/viengoos/sysdeps/x86_64/boot64.c +++ b/viengoos/sysdeps/x86_64/boot64.c @@ -87,15 +87,17 @@ debug_dump (void) if (CHECK_FLAG (mbi->flags, 6)) { - memory_map_t *mmap; - int nr = 1; + memory_map_t *mmap = (memory_map_t *) (uintptr_t) mbi->mmap_addr; + debug (5, "mmap at %p, %"PRId32" bytes\n", mmap, mbi->mmap_length); - for (mmap = (memory_map_t *) (uintptr_t) mbi->mmap_addr; + int nr; + for (mmap = (memory_map_t *) (uintptr_t) mbi->mmap_addr, nr = 1; (uint64_t) mmap < mbi->mmap_addr + mbi->mmap_length; mmap = (memory_map_t *) ((uint64_t) mmap - + mmap->size + sizeof (mmap->size))) + + mmap->size + sizeof (mmap->size)), + nr ++) debug (1, "Memory Map %i: Type %i, Base 0x%lx, Length 0x%lx", - nr++, mmap->type, mmap->base_addr, mmap->length); + nr, mmap->type, mmap->base_addr, mmap->length); } } @@ -247,16 +249,72 @@ memory_configure (void) do_debug (3) memory_reserve_dump (); - if (CHECK_FLAG (mbi->flags, 0)) +#define GB (UINT64_C(1) << 30) + if (CHECK_FLAG (mbi->flags, 6)) { /* phys_to_kv assumes that first_frame and last_frame are set up correctly. memory_add changes these. To avoid triggering an assert in phys_to_kv, we collect all the regions we will add and then call memory_add. */ + + memory_map_t *mmap = (memory_map_t *) (uintptr_t) mbi->mmap_addr; + int count = 0; + for (mmap = (memory_map_t *) (uintptr_t) mbi->mmap_addr; + (uint64_t) mmap < mbi->mmap_addr + mbi->mmap_length; + mmap = (memory_map_t *) ((uint64_t) mmap + + mmap->size + sizeof (mmap->size))) + if (mmap->type == 1) + { + count ++; + + /* We need to do some acrobatics: physical memory is not + mapped to kernel virtual memory contiguously: the first + 2GB of physical memory are mapped to the top 2 GB of + virtual memory and the next 62 GB of physical are mapped + to the first 62 GB of the top 64GB. We need to do this + because we compile with -mcmodel=kernel. */ + if (mmap->base_addr < 2 * GB + && mmap->base_addr + mmap->length > 2 * GB) + count ++; + } + struct { - uintptr_t start; - uintptr_t end; + void *start; + void *end; + } regions[count], *region = ®ions[0], *r; + + int nr; + for (mmap = (memory_map_t *) (uintptr_t) mbi->mmap_addr; + (uint64_t) mmap < mbi->mmap_addr + mbi->mmap_length; + mmap = (memory_map_t *) ((uint64_t) mmap + + mmap->size + sizeof (mmap->size))) + if (mmap->type == 1) + { + region->start = phys_to_kv (mmap->base_addr); + if (mmap->base_addr < 2 * GB + && mmap->base_addr + mmap->length > 2 * GB) + { + region->end = phys_to_kv (2 * GB - 1); + region ++; + region->start = phys_to_kv (2 * GB); + } + region->end = phys_to_kv (mmap->base_addr + mmap->length - 1); + + region ++; + } + + for (r = ®ions[0]; r != region; r ++) + memory_add ((uintptr_t) r->start, (uintptr_t) r->end); + } + else if (CHECK_FLAG (mbi->flags, 0)) + { + /* Refer to the comments above to understand what is going on + here. */ + struct + { + void *start; + void *end; } regions[3], *region = ®ions[0], *r; #define LOWER_MEMORY_START 0 @@ -275,13 +333,6 @@ memory_configure (void) uintptr_t mem = mbi->mem_upper * 1024; mem &= ~(PAGESIZE - 1); - /* We need to do some acrobatics: physical memory is not - mapped to kernel virtual memory contiguously: the first - 2GB of physical memory are mapped to the top 2 GB of - virtual memory and the next 62 GB of physical are mapped - to the first 62 GB of the top 64GB. We need to do this - because we compile with -mcmodel=kernel. */ -#define GB (UINT64_C(1) << 30) if (UPPER_MEMORY_START + mem > 2 * GB) { region->start = phys_to_kv (UPPER_MEMORY_START); @@ -300,7 +351,7 @@ memory_configure (void) } for (r = ®ions[0]; r != region; r ++) - memory_add (r->start, r->end); + memory_add ((uintptr_t) r->start, (uintptr_t) r->end); } } diff --git a/viengoos/sysdeps/x86_64/vm.c b/viengoos/sysdeps/x86_64/vm.c index 6e584b1..754f02f 100644 --- a/viengoos/sysdeps/x86_64/vm.c +++ b/viengoos/sysdeps/x86_64/vm.c @@ -645,18 +645,6 @@ vm_init (void) false, false)); pdp.allocated ++; - /* XXX: Grub doesn't report all the memory in the system. - This wouldn't be too bad except that it stores some of - its data structures in that memory! Here we "round up" - to the next gig. This gets all the memory. */ - uintptr_t last_frame_temp = last_frame; - if ((uintptr_t) phys_to_kv ((uintptr_t) base) + gb - 1 > last_frame) - { - last_frame = (uintptr_t) phys_to_kv ((uintptr_t) base) + gb - 1; - debug (0, "Setting last frame to %"PRIxPTR" -> %"PRIxPTR, - last_frame_temp, last_frame); - } - int i; for (i = 0; i < PTES && base <= kv_to_phys ((void *) last_frame); @@ -686,8 +674,6 @@ vm_init (void) debug (0, "i: %d, base: %"PRIxPTR", last_frame_phys: %"PRIxPTR, i, base, kv_to_phys ((void *) last_frame)); - last_frame = last_frame_temp; - page_table_check (&pdir[j], false); } } |