Added memory detection using multiboot_info
authorKevin Klues <klueska@cs.berkeley.edu>
Wed, 15 Apr 2009 20:21:04 +0000 (13:21 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Wed, 15 Apr 2009 20:30:30 +0000 (13:30 -0700)
Changed to using multiboot_info structure to extract the available RAM on the system. Also changed the ghetto
timeouts from smp.c to be contained in a #define in smp.h so that they can be customized to the specific
machine you are running on. Right now we just have values for the default architecture and the __BOCHS__
architecture. To define the architecture in use, simply add ARCH=__BOCHS__ or similar on the command line when
you compile

.gitignore
GNUmakefile
inc/x86.h
kern/init.c
kern/pmap.c
kern/pmap.h
kern/smp.c
kern/smp.h
kern/testing.c

index 69ee436..e6797f1 100644 (file)
@@ -3,3 +3,4 @@ bochs.log
 .bochsrc
 mnt/
 obj/
+*.*~
index 76cc457..95f2e88 100644 (file)
@@ -61,6 +61,7 @@ LD    := $(GCCPREFIX)ld
 OBJCOPY        := $(GCCPREFIX)objcopy
 OBJDUMP        := $(GCCPREFIX)objdump
 NM     := $(GCCPREFIX)nm
+ARCH ?= NONE
 
 # Native commands
 NCC    := gcc $(CC_VER) -pipe
@@ -70,7 +71,7 @@ PERL  := perl
 # Compiler flags
 # -fno-builtin is required to avoid refs to undefined functions in the kernel.
 # Only optimize to -O1 to discourage inlining, which complicates backtraces.
-CFLAGS := $(CFLAGS) $(DEFS) $(LABDEFS) -O -fno-builtin -fno-stack-protector -I$(TOP) -MD -Wall -Wno-format -Wno-unused -gstabs
+CFLAGS := $(CFLAGS) $(DEFS) $(LABDEFS) -D$(ARCH) -O -fno-builtin -fno-stack-protector -I$(TOP) -MD -Wall -Wno-format -Wno-unused -gstabs
 
 # Linker flags for JOS user programs
 ULDFLAGS := -T user/user.ld
index 2a9363c..f7ae09e 100644 (file)
--- a/inc/x86.h
+++ b/inc/x86.h
@@ -4,6 +4,8 @@
 #include <inc/types.h>
 #include <inc/mmu.h>
 
+#define CHECK_FLAG(flags,bit)   ((flags) & (1 << (bit)))
+
 /* Model Specific Registers */
 #define IA32_APIC_BASE                         0x1b
 #define IA32_MTRR_DEF_TYPE                     0x2ff
index 50ff35d..b8abd67 100644 (file)
@@ -40,7 +40,8 @@ void kernel_init(multiboot_info_t *mboot_info)
 
        print_cpuinfo();
 
-       i386_detect_memory();
+       i386_detect_memory((multiboot_info_t*)((uint32_t)mboot_info + KERNBASE));
+       i386_print_memory_map((multiboot_info_t*)((uint32_t)mboot_info + KERNBASE));
        i386_vm_init();
        page_init();
        page_check();
index 6ea71da..5eb2506 100644 (file)
@@ -68,17 +68,33 @@ nvram_read(int r)
        return mc146818_read(r) | (mc146818_read(r + 1) << 8);
 }
 
-void
-i386_detect_memory(void)
-{
-       /* For shit BIOS reasons, this isn't seeing any more than 64MB,
-        * explained a little here: 
-        * http://exec.h1.ru/docs/os-devel-faq/os-faq-memory.html
-        */
+void i386_print_memory_map(multiboot_info_t *mbi) {
+       const char* memory_type[] = {"", "FREE", "RESERVED", "UNDEFINED"};
+
+
+       if(CHECK_FLAG(mbi->flags, 6)) {
+               cprintf ("mmap_addr = 0x%x, mmap_length = 0x%x\n", (unsigned long)mbi->mmap_addr,
+                                                                  (unsigned long)mbi->mmap_length);
+               
+               memory_map_t* mmap = (memory_map_t*) ((uint32_t)mbi->mmap_addr + KERNBASE);
+               while((uint32_t)mmap < ((uint32_t)mbi->mmap_addr + KERNBASE) + mbi->mmap_length) {                      
+                       cprintf (" size = 0x%x, base_addr = 0x%08x%08x," " length = 0x%08x%08x, type = %s\n",
+                               (unsigned) mmap->size,
+                               (unsigned) mmap->base_addr_high,
+                               (unsigned) mmap->base_addr_low,
+                               (unsigned) mmap->length_high,
+                               (unsigned) mmap->length_low,
+                               (unsigned) memory_type[mmap->type]);
+                       mmap = (memory_map_t*) ((uint32_t) mmap + mmap->size + sizeof (mmap->size));
+               }
+       }
+}
 
-       // CMOS tells us how many kilobytes there are
-       basemem = ROUNDDOWN(nvram_read(NVRAM_BASELO)*1024, PGSIZE);
-       extmem = ROUNDDOWN(nvram_read(NVRAM_EXTLO)*1024, PGSIZE);
+void i386_detect_memory(multiboot_info_t *mbi)
+{
+       // Tells us how many kilobytes there are
+       basemem = ROUNDDOWN(mbi->mem_lower*1024, PGSIZE);
+       extmem = ROUNDDOWN(mbi->mem_upper*1024, PGSIZE);
 
        // Calculate the maximum physical address based on whether
        // or not there is any extended memory.  See comment in <inc/memlayout.h>
index 37c61e3..f98be20 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <inc/memlayout.h>
 #include <inc/assert.h>
-
+#include <inc/multiboot.h>
 #include <kern/atomic.h>
 
 struct Env;
@@ -51,7 +51,8 @@ extern pde_t *boot_pgdir;
 extern struct Segdesc (COUNT(SEG_COUNT) gdt)[];
 extern struct Pseudodesc gdt_pd;
 
-void   i386_detect_memory(void);
+void   i386_detect_memory(multiboot_info_t *mbi);
+void   i386_print_memory_map(multiboot_info_t *mbi);
 bool   enable_pse(void);
 void   i386_vm_init(void);
 
index 5ebd604..3f53e65 100644 (file)
@@ -63,7 +63,7 @@ void smp_boot(void)
        // first SIPI
        waiting = 1;
        send_startup_ipi(0x01);
-       lapic_set_timer(0x002fffff, 0xf0, 0); // TODO - fix timing
+       lapic_set_timer(SMP_BOOT_TIMEOUT, 0xf0, 0); // TODO - fix timing
        while(waiting) // wait for the first SIPI to take effect
                cpu_relax();
        /* //BOCHS does not like this second SIPI.
@@ -194,7 +194,7 @@ uint32_t smp_main(void)
 static void smp_call_function(uint8_t type, uint8_t dest, isr_t handler, uint8_t vector)
 {
        extern isr_t interrupt_handlers[];
-       uint32_t i, amount = 0x7ffffff0; // should calibrate this!!  just remove it!
+       uint32_t i, amount = SMP_CALL_FUNCTION_TIMEOUT; // should calibrate this!!  just remove it!
        int8_t state = 0;
 
        if (!vector)
index 53b33d2..ac70f35 100644 (file)
@@ -7,6 +7,14 @@
 
 #include <kern/trap.h>
 
+#ifdef __BOCHS__
+#define SMP_CALL_FUNCTION_TIMEOUT    0x00ffffff
+#define SMP_BOOT_TIMEOUT             0x0000ffff
+#else
+#define SMP_CALL_FUNCTION_TIMEOUT    0x7ffffff0
+#define SMP_BOOT_TIMEOUT             0x002fffff
+#endif
+
 void smp_boot(void);
 
 void smp_call_function_self(isr_t handler, uint8_t vector);
index f0b4be9..537bf25 100644 (file)
@@ -17,7 +17,7 @@
 void test_ipi_sending(void)
 {
        extern isr_t interrupt_handlers[];
-       uint32_t i, amount = 0x7ffffff0; // should calibrate this
+       uint32_t i, amount = SMP_CALL_FUNCTION_TIMEOUT; // should calibrate this
        int8_t state = 0;
        register_interrupt_handler(interrupt_handlers, 0xf1, test_hello_world_handler);
        enable_irqsave(&state);