From: "bibo,mao" <bibo.mao@intel.com>
To: grub-devel@gnu.org
Subject: [PATCH 1/3] grub efi memory map patch
Date: Tue, 24 Oct 2006 14:58:43 +0800 [thread overview]
Message-ID: <453DB9A3.8070809@intel.com> (raw)
This patch moves find_mmap_size from i386/efi/linux.c to
kern/efi/mm.c, and renamed as grub_efi_find_mmap_size, so that
other arch on EFI platform can use this function.
Also this function solves memory map too small problem,
on some EFI platform MEMORY_MAP_SIZE(0x1000) is a little smaller
than EFI memory map table.
any suggestion is welcome.
thanks
bibo,mao
diff -Nruap grub2.org/include/grub/efi/api.h grub2/include/grub/efi/api.h
--- grub2.org/include/grub/efi/api.h 2006-10-24 13:05:48.000000000 +0800
+++ grub2/include/grub/efi/api.h 2006-10-23 14:35:12.000000000 +0800
@@ -206,6 +206,13 @@ typedef grub_efi_intn_t grub_efi_status_
#define GRUB_EFI_WARN_WRITE_FAILURE GRUB_EFI_WARNING_CODE (3)
#define GRUB_EFI_WARN_BUFFER_TOO_SMALL GRUB_EFI_WARNING_CODE (4)
+#define GRUB_EFI_PAGE_SHIFT 12
+#define GRUB_EFI_PAGE_SIZE (0x1UL << GRUB_EFI_PAGE_SHIFT)
+#define GRUB_EFI_PAGES(addr) (addr >> GRUB_EFI_PAGE_SHIFT)
+#define GRUB_EFI_PAGES_UP(addr) ((addr + GRUB_EFI_PAGE_SIZE - 1) >> GRUB_EFI_PAGE_SHIFT)
+#define PAGE_DOWN(addr) ((addr) & (~(GRUB_EFI_PAGE_SIZE - 1)))
+#define PAGE_UP(addr) PAGE_DOWN(addr + GRUB_EFI_PAGE_SIZE - 1)
+
typedef void *grub_efi_handle_t;
typedef void *grub_efi_event_t;
typedef grub_efi_uint64_t grub_efi_lba_t;
diff -Nruap grub2.org/include/grub/efi/efi.h grub2/include/grub/efi/efi.h
--- grub2.org/include/grub/efi/efi.h 2006-10-24 13:05:48.000000000 +0800
+++ grub2/include/grub/efi/efi.h 2006-10-23 14:42:48.000000000 +0800
@@ -55,6 +55,7 @@ char *EXPORT_FUNC(grub_efi_get_filename)
grub_efi_device_path_t *
EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle);
int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key);
+grub_efi_uintn_t EXPORT_FUNC(grub_efi_find_mmap_size) (void);
void grub_efi_mm_init (void);
void grub_efi_mm_fini (void);
diff -Nruap grub2.org/kern/efi/mm.c grub2/kern/efi/mm.c
--- grub2.org/kern/efi/mm.c 2006-10-24 13:05:48.000000000 +0800
+++ grub2/kern/efi/mm.c 2006-10-24 13:18:48.000000000 +0800
@@ -30,10 +30,6 @@
#define BYTES_TO_PAGES(bytes) ((bytes) >> 12)
#define PAGES_TO_BYTES(pages) ((pages) << 12)
-/* The size of a memory map obtained from the firmware. This must be
- a multiplier of 4KB. */
-#define MEMORY_MAP_SIZE 0x1000
-
/* Maintain the list of allocated pages. */
struct allocated_page
{
@@ -335,6 +331,45 @@ print_memory_map (grub_efi_memory_descri
}
#endif
+/* Find the optimal number of pages for the memory map. */
+grub_efi_uintn_t
+grub_efi_find_mmap_size (void)
+{
+ static grub_efi_uintn_t mmap_size = 0;
+
+ if (mmap_size != 0)
+ return mmap_size;
+
+ mmap_size = GRUB_EFI_PAGE_SIZE;
+ while (1)
+ {
+ int ret;
+ grub_efi_memory_descriptor_t *mmap;
+ grub_efi_uintn_t desc_size;
+
+ mmap = grub_efi_allocate_pages ( 0, GRUB_EFI_PAGES_UP(mmap_size));
+ if (! mmap)
+ return 0;
+
+ ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
+ grub_efi_free_pages ((grub_addr_t) mmap, GRUB_EFI_PAGES_UP(mmap_size));
+
+ if (ret < 0)
+ grub_fatal ("cannot get memory map");
+ else if (ret > 0)
+ break;
+
+ mmap_size += GRUB_EFI_PAGE_SIZE;
+ }
+
+ /* Increase the size a bit for safety, because GRUB allocates more on
+ later, and EFI itself may allocate more. */
+ mmap_size += GRUB_EFI_PAGE_SIZE;
+ mmap_size = PAGE_UP(mmap_size);
+
+ return mmap_size;
+}
+
void
grub_efi_mm_init (void)
{
@@ -346,6 +381,8 @@ grub_efi_mm_init (void)
grub_efi_uintn_t desc_size;
grub_efi_uint64_t total_pages;
grub_efi_uint64_t required_pages;
+ grub_efi_uintn_t memory_map_size;
+ int res;
/* First of all, allocate pages to maintain allocations. */
allocated_pages
@@ -355,16 +392,20 @@ grub_efi_mm_init (void)
grub_memset (allocated_pages, 0, ALLOCATED_PAGES_SIZE);
- /* Prepare a memory region to store two memory maps. */
- memory_map = grub_efi_allocate_pages (0,
- 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+ /* Prepare a memory region to store two memory maps. Obtain size of
+ memory map by passing a NULL buffer and a buffer size of
+ zero. */
+ memory_map_size = grub_efi_find_mmap_size( );
+ memory_map = grub_efi_allocate_pages(0, 2 * PAGE_UP(memory_map_size));
+
if (! memory_map)
grub_fatal ("cannot allocate memory");
- filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map, MEMORY_MAP_SIZE);
+ filtered_memory_map = NEXT_MEMORY_DESCRIPTOR (memory_map,
+ PAGE_UP(memory_map_size));
/* Obtain descriptors for available memory. */
- map_size = MEMORY_MAP_SIZE;
+ map_size = memory_map_size;
if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0)
grub_fatal ("cannot get memory map");
@@ -405,8 +446,7 @@ grub_efi_mm_init (void)
#endif
/* Release the memory maps. */
- grub_efi_free_pages ((grub_addr_t) memory_map,
- 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
+ grub_efi_free_pages ((grub_addr_t) memory_map, 2 * PAGE_UP(memory_map_size));
}
void
diff -Nruap grub2.org/loader/i386/efi/linux.c grub2/loader/i386/efi/linux.c
--- grub2.org/loader/i386/efi/linux.c 2006-10-24 13:06:56.000000000 +0800
+++ grub2/loader/i386/efi/linux.c 2006-10-23 14:42:48.000000000 +0800
@@ -93,45 +93,6 @@ page_align (grub_size_t size)
return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
}
-/* Find the optimal number of pages for the memory map. Is it better to
- move this code to efi/mm.c? */
-static grub_efi_uintn_t
-find_mmap_size (void)
-{
- static grub_efi_uintn_t mmap_size = 0;
-
- if (mmap_size != 0)
- return mmap_size;
-
- mmap_size = (1 << 12);
- while (1)
- {
- int ret;
- grub_efi_memory_descriptor_t *mmap;
- grub_efi_uintn_t desc_size;
-
- mmap = grub_malloc (mmap_size);
- if (! mmap)
- return 0;
-
- ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
- grub_free (mmap);
-
- if (ret < 0)
- grub_fatal ("cannot get memory map");
- else if (ret > 0)
- break;
-
- mmap_size += (1 << 12);
- }
-
- /* Increase the size a bit for safety, because GRUB allocates more on
- later, and EFI itself may allocate more. */
- mmap_size += (1 << 12);
-
- return page_align (mmap_size);
-}
-
static void
free_pages (void)
{
@@ -167,7 +128,7 @@ allocate_pages (grub_size_t real_size, g
/* Make sure that each size is aligned to a page boundary. */
real_size = page_align (real_size + GRUB_DISK_SECTOR_SIZE);
prot_size = page_align (prot_size);
- mmap_size = find_mmap_size ();
+ mmap_size = grub_efi_find_mmap_size ();
grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
real_size, prot_size, mmap_size);
@@ -275,7 +236,7 @@ grub_linux_boot (void)
grub_dprintf ("linux", "idt = %x:%x, gdt = %x:%x\n",
(unsigned) idt_desc.limit, (unsigned) idt_desc.base,
(unsigned) gdt_desc.limit, (unsigned) gdt_desc.base);
- mmap_size = find_mmap_size ();
+ mmap_size = grub_efi_find_mmap_size ();
if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
&desc_size, &desc_version) <= 0)
grub_fatal ("cannot get memory map");
@@ -616,7 +577,7 @@ grub_rescue_cmd_initrd (int argc, char *
addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12);
/* Find the highest address to put the initrd. */
- mmap_size = find_mmap_size ();
+ mmap_size = grub_efi_find_mmap_size ();
if (grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0) <= 0)
grub_fatal ("cannot get memory map");
next reply other threads:[~2006-10-24 6:58 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-10-24 6:58 bibo,mao [this message]
2006-10-24 13:26 ` [PATCH 1/3] grub efi memory map patch Johan Rydberg
2006-10-25 5:38 ` bibo,mao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=453DB9A3.8070809@intel.com \
--to=bibo.mao@intel.com \
--cc=grub-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.