]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
add memory routines
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 7 Dec 2009 15:16:10 +0000 (16:16 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 7 Dec 2009 15:16:10 +0000 (16:16 +0100)
conf/mips-yeeloong.rmk
include/grub/mips/yeeloong/memory.h
kern/mips/yeeloong/init.c
loader/mips/linux.c
mmap/mips/yeeloong/uppermem.c [new file with mode: 0644]
mmap/mmap.c

index 16909487d06c8abe50789d804dd5d24e065497c9..a06b3fa5eb77b8f742b98d16435e5821e42de25c 100644 (file)
@@ -40,3 +40,10 @@ pkglib_MODULES += ata_pthru.mod
 ata_pthru_mod_SOURCES = disk/ata_pthru.c
 ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS)
 ata_pthru_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For mmap.mod.
+pkglib_MODULES += mmap.mod
+mmap_mod_SOURCES = mmap/mmap.c mmap/mips/yeeloong/uppermem.c
+mmap_mod_CFLAGS = $(COMMON_CFLAGS)
+mmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
+mmap_mod_ASFLAGS = $(COMMON_ASFLAGS)
index bc8f47b12a6362c217949918aabb428b4cb18fb2..c85db712a720c2a43e93cb743e0209b4813e78cc 100644 (file)
 #endif
 
 #define GRUB_MACHINE_MEMORY_STACK_HIGH       0x801ffff0
-#define GRUB_MACHINE_MEMORY_USABLE           0x81000000
+#define GRUB_ARCH_LOWMEMVSTART 0x80000000
+#define GRUB_ARCH_LOWMEMPSTART 0x00000000
+#define GRUB_ARCH_LOWMEMMAXSIZE 0x10000000
+#define GRUB_ARCH_HIGHMEMPSTART 0x10000000
+
 
 #define GRUB_MACHINE_MEMORY_AVAILABLE        1
+#define GRUB_MACHINE_MEMORY_MAX_TYPE         1
+  /* This one is special: it's used internally but is never reported
+     by firmware. */
+#define GRUB_MACHINE_MEMORY_HOLE       2
+#define GRUB_MACHINE_MEMORY_RESERVED GRUB_MACHINE_MEMORY_HOLE
 
 #ifndef ASM_FILE
 grub_err_t EXPORT_FUNC (grub_machine_mmap_iterate)
 (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
-grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
-     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
 
 static inline grub_err_t
 grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
@@ -49,6 +56,15 @@ grub_machine_mmap_unregister (int handle  __attribute__ ((unused)))
 {
   return GRUB_ERR_NONE;
 }
+
+grub_uint64_t grub_mmap_get_lower (void);
+grub_uint64_t grub_mmap_get_upper (void);
+
+extern grub_uint32_t EXPORT_VAR (grub_arch_memsize);
+extern grub_uint32_t EXPORT_VAR (grub_arch_highmemsize);
+extern grub_uint32_t EXPORT_VAR (grub_arch_busclock);
+extern grub_uint32_t EXPORT_VAR (grub_arch_cpuclock);
+
 #endif
 
 #endif
index 01acd4f1cb153b462fe8071fe3f4a27fab9f89f2..1bd9d2ed9c6bf19ef796d93ee7f0643116744918 100644 (file)
@@ -28,8 +28,6 @@
 #include <grub/machine/memory.h>
 #include <grub/cpu/kernel.h>
 
-#define RAMSIZE (64 << 20)
-
 grub_uint32_t
 grub_get_rtc (void)
 {
@@ -38,11 +36,48 @@ grub_get_rtc (void)
   return (calln++) >> 8;
 }
 
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+                                                        grub_uint64_t,
+                                                        grub_uint32_t))
+{
+  hook (GRUB_ARCH_LOWMEMPSTART, grub_arch_memsize << 20,
+       GRUB_MACHINE_MEMORY_AVAILABLE);
+  hook (GRUB_ARCH_HIGHMEMPSTART, grub_arch_highmemsize << 20,
+       GRUB_MACHINE_MEMORY_AVAILABLE);
+  return GRUB_ERR_NONE;
+}
+
+
+static void *
+get_modules_end (void)
+{
+  struct grub_module_info *modinfo;
+  struct grub_module_header *header;
+  grub_addr_t modbase;
+
+  modbase = grub_arch_modules_addr ();
+  modinfo = (struct grub_module_info *) modbase;
+
+  /* Check if there are any modules.  */
+  if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC)
+    return modinfo;
+
+  for (header = (struct grub_module_header *) (modbase + modinfo->offset);
+       header < (struct grub_module_header *) (modbase + modinfo->size);
+       header = (struct grub_module_header *) ((char *) header + header->size));
+
+  return header;
+}
+
 void
 grub_machine_init (void)
 {
-  grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_USABLE,
-                      RAMSIZE - (GRUB_MACHINE_MEMORY_USABLE & 0x7fffffff));
+  void *modend;
+  modend = get_modules_end ();
+  grub_mm_init_region (modend, (grub_arch_memsize << 20)
+                      - (((grub_addr_t) modend) - GRUB_ARCH_LOWMEMVSTART));
+  /* FIXME: use upper memory as well.  */
   grub_install_get_time_ms (grub_rtc_get_time_ms);
 }
 
@@ -69,11 +104,3 @@ grub_reboot (void)
   while (1);
 }
 
-grub_err_t 
-grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, 
-                                                        grub_uint64_t, 
-                                                        grub_uint32_t))
-{
-  hook (0, RAMSIZE, GRUB_MACHINE_MEMORY_AVAILABLE);
-  return GRUB_ERR_NONE;
-}
index 4d9045a65ac553659bddab25c9c6d12ec097fd89..635f84a28d67c15e80320a0ac94c6e2146144de9 100644 (file)
 #include <grub/machine/loader.h>
 #include <grub/command.h>
 #include <grub/mips/relocator.h>
+#include <grub/machine/memory.h>
+
+/* For frequencies.  */
+#include <grub/pci.h>
 
 #define ELF32_LOADMASK (0x00000000UL)
 #define ELF64_LOADMASK (0x0000000000000000ULL)
@@ -176,7 +180,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   int size;
   void *extra = NULL;
   grub_uint32_t *linux_argv, *linux_envp;
-  char *linux_args;
+  char *linux_args, *linux_envs;
   grub_err_t err;
 
   if (argc == 0)
@@ -218,7 +222,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4);
 
   /* For the environment.  */
-  size += sizeof (grub_uint32_t); 
+  size += sizeof (grub_uint32_t);
+  size += 4 * sizeof (grub_uint32_t);
+  size += ALIGN_UP (sizeof ("memsize=XXXXXXXXXXXXXXXXXXXX"), 4)
+    + ALIGN_UP (sizeof ("highmemsize=XXXXXXXXXXXXXXXXXXXX"), 4)
+    + ALIGN_UP (sizeof ("busclock=XXXXXXXXXX"), 4)
+    + ALIGN_UP (sizeof ("cpuclock=XXXXXXXXXX"), 4);
 
   if (grub_elf_is_elf32 (elf))
     err = grub_linux_load32 (elf, &extra, size);
@@ -276,7 +285,27 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
 
   linux_envp = extra;
   envp_off = (grub_uint8_t *) linux_envp - (grub_uint8_t *) playground;
-  linux_envp[0] = 0;
+  linux_envs = (char *) (linux_envp + 5);
+  grub_sprintf (linux_envs, "memsize=%lld", (unsigned long long) grub_mmap_get_lower () >> 20);
+  linux_envp[0] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
+    + target_addr;
+  linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
+  grub_sprintf (linux_envs, "highmemsize=%lld", (unsigned long long) grub_mmap_get_upper () >> 20);
+  linux_envp[1] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
+    + target_addr;
+  linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
+
+  grub_sprintf (linux_envs, "busclock=%d", grub_arch_busclock);
+  linux_envp[2] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
+    + target_addr;
+  linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
+  grub_sprintf (linux_envs, "cpuclock=%d", grub_arch_cpuclock);
+  linux_envp[3] = (grub_uint8_t *) linux_envs - (grub_uint8_t *) playground
+    + target_addr;
+  linux_envs += ALIGN_UP (grub_strlen (linux_envs) + 1, 4);
+
+
+  linux_envp[4] = 0;
 
   grub_loader_set (grub_linux_boot, grub_linux_unload, 1);
   initrd_loaded = 0;
diff --git a/mmap/mips/yeeloong/uppermem.c b/mmap/mips/yeeloong/uppermem.c
new file mode 100644 (file)
index 0000000..3c5f814
--- /dev/null
@@ -0,0 +1,66 @@
+/* Compute amount of lower and upper memory till the first hole. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/memory.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/machine/memory.h>
+
+grub_uint64_t
+grub_mmap_get_lower (void)
+{
+  grub_uint64_t lower = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+                            grub_uint32_t type)
+    {
+      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+       return 0;
+      if (addr == 0)
+       lower = size;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+  if (lower > GRUB_ARCH_LOWMEMMAXSIZE)
+    lower = GRUB_ARCH_LOWMEMMAXSIZE;
+  return lower;
+}
+
+grub_uint64_t
+grub_mmap_get_upper (void)
+{
+  grub_uint64_t upper = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+                            grub_uint32_t type)
+    {
+      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+       return 0;
+      if (addr <= GRUB_ARCH_HIGHMEMPSTART && addr + size
+         > GRUB_ARCH_HIGHMEMPSTART)
+       upper = addr + size - GRUB_ARCH_HIGHMEMPSTART;
+      return 0;
+    }
+
+  grub_mmap_iterate (hook);
+  return upper;
+}
index 7598cf50163b54ac9b621ca8b89f22435401109e..d379a99f9cabccc5c0d07be81c5b931a965780d6 100644 (file)
@@ -52,7 +52,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
 #ifdef GRUB_MACHINE_MEMORY_AVAILABLE
       [GRUB_MACHINE_MEMORY_AVAILABLE] = 1,
 #endif
-#ifdef GRUB_MACHINE_MEMORY_RESERVED
+#if defined (GRUB_MACHINE_MEMORY_RESERVED) && GRUB_MACHINE_MEMORY_RESERVED != GRUB_MACHINE_MEMORY_HOLE
       [GRUB_MACHINE_MEMORY_RESERVED] = 3,
 #endif
 #ifdef GRUB_MACHINE_MEMORY_ACPI