summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeal H. Walfield <neal@gnu.org>2009-03-01 20:05:02 +0100
committerNeal H. Walfield <neal@gnu.org>2009-03-01 21:03:14 +0100
commit7679645a02e563cc617c57aeb4c208d9a1d442ed (patch)
treee310dc6181c0a19a81c628a1469d8bf6c0696621
parent9f7c4845c850d86e5e813d309422812ec372eb4b (diff)
Fix multiboot.h for 64-bit machines. Remove some workarounds for Grub.
-rw-r--r--viengoos/memory.c12
-rw-r--r--viengoos/sysdeps/generic/multiboot.h2
-rw-r--r--viengoos/sysdeps/x86_64/boot64.c83
-rw-r--r--viengoos/sysdeps/x86_64/vm.c14
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 = &regions[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 = &regions[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 = &regions[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 = &regions[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);
}
}