Reorganise memory map handling

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-09-04 17:10:10 +02:00
parent dda060dd0f
commit df3df23d5c
51 changed files with 301 additions and 443 deletions

View file

@ -17,8 +17,8 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/machine/memory.h>
#include <grub/memory.h>
#include <grub/machine/memory.h>
#include <grub/err.h>
#include <grub/misc.h>
#include <grub/mm.h>
@ -34,8 +34,7 @@ static int curhandle = 1;
#endif
grub_err_t
grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
grub_uint64_t, grub_uint32_t))
grub_mmap_iterate (grub_memory_hook_t hook)
{
/* This function resolves overlapping regions and sorts the memory map.
@ -48,27 +47,17 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
3 - unusable memory
4 - a range deliberately empty
*/
int priority[GRUB_MACHINE_MEMORY_MAX_TYPE + 2] =
int priority[] =
{
#ifdef GRUB_MACHINE_MEMORY_AVAILABLE
[GRUB_MACHINE_MEMORY_AVAILABLE] = 1,
#endif
#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
[GRUB_MACHINE_MEMORY_ACPI] = 2,
#endif
#ifdef GRUB_MACHINE_MEMORY_CODE
[GRUB_MACHINE_MEMORY_CODE] = 3,
#endif
#ifdef GRUB_MACHINE_MEMORY_NVS
[GRUB_MACHINE_MEMORY_NVS] = 3,
#endif
[GRUB_MACHINE_MEMORY_HOLE] = 4,
[GRUB_MEMORY_AVAILABLE] = 1,
[GRUB_MEMORY_RESERVED] = 3,
[GRUB_MEMORY_ACPI] = 2,
[GRUB_MEMORY_CODE] = 3,
[GRUB_MEMORY_NVS] = 3,
[GRUB_MEMORY_HOLE] = 4,
};
int i, k, done;
int i, done;
/* Scanline events. */
struct grub_mmap_scan
@ -89,7 +78,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
/* Current scanline event. */
int curtype;
/* How many regions of given type overlap at current location? */
int present[GRUB_MACHINE_MEMORY_MAX_TYPE + 2];
int present[ARRAY_SIZE (priority)];
/* Number of mmap chunks. */
int mmap_num;
@ -101,7 +90,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
grub_uint32_t);
int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
grub_uint64_t size __attribute__ ((unused)),
grub_uint32_t type __attribute__ ((unused)))
grub_memory_type_t type __attribute__ ((unused)))
{
mmap_num++;
return 0;
@ -111,17 +100,17 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
grub_uint32_t);
int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr,
grub_uint64_t size,
grub_uint32_t type)
grub_memory_type_t type)
{
scanline_events[i].pos = addr;
scanline_events[i].type = 0;
if (type <= GRUB_MACHINE_MEMORY_MAX_TYPE && priority[type])
if (type < ARRAY_SIZE (priority) && priority[type])
scanline_events[i].memtype = type;
else
{
grub_dprintf ("mmap", "Unknown memory type %d. Assuming unusable\n",
type);
scanline_events[i].memtype = GRUB_MACHINE_MEMORY_RESERVED;
scanline_events[i].memtype = GRUB_MEMORY_RESERVED;
}
i++;
@ -160,12 +149,10 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
{
scanline_events[i].pos = cur->start;
scanline_events[i].type = 0;
if (cur->type == GRUB_MACHINE_MEMORY_HOLE
|| (cur->type >= 0 && cur->type <= GRUB_MACHINE_MEMORY_MAX_TYPE
&& priority[cur->type]))
if (cur->type < ARRAY_SIZE (priority) && priority[cur->type])
scanline_events[i].memtype = cur->type;
else
scanline_events[i].memtype = GRUB_MACHINE_MEMORY_RESERVED;
scanline_events[i].memtype = GRUB_MEMORY_RESERVED;
i++;
scanline_events[i].pos = cur->end;
@ -201,6 +188,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
lasttype = scanline_events[0].memtype;
for (i = 0; i < 2 * mmap_num; i++)
{
unsigned k;
/* Process event. */
if (scanline_events[i].type)
present[scanline_events[i].memtype]--;
@ -209,7 +197,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
/* Determine current region type. */
curtype = -1;
for (k = 0; k <= GRUB_MACHINE_MEMORY_MAX_TYPE + 1; k++)
for (k = 0; k < ARRAY_SIZE (priority); k++)
if (present[k] && (curtype == -1 || priority[k] > priority[curtype]))
curtype = k;
@ -217,7 +205,7 @@ grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
if ((curtype == -1 || curtype != lasttype)
&& lastaddr != scanline_events[i].pos
&& lasttype != -1
&& lasttype != GRUB_MACHINE_MEMORY_HOLE
&& lasttype != GRUB_MEMORY_HOLE
&& hook (lastaddr, scanline_events[i].pos - lastaddr, lasttype))
{
grub_free (scanline_events);
@ -324,10 +312,11 @@ grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)),
char * str;
grub_uint64_t badaddr, badmask;
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
grub_memory_type_t);
int NESTED_FUNC_ATTR hook (grub_uint64_t addr,
grub_uint64_t size,
grub_uint32_t type __attribute__ ((unused)))
grub_memory_type_t type __attribute__ ((unused)))
{
grub_uint64_t iterator, low, high, cur;
int tail, var;
@ -370,7 +359,7 @@ grub_cmd_badram (grub_command_t cmd __attribute__ ((unused)),
{
grub_dprintf ("badram", "%llx (size %llx) is a badram range\n",
(unsigned long long) cur, (1ULL << tail));
grub_mmap_register (cur, (1ULL << tail), GRUB_MACHINE_MEMORY_HOLE);
grub_mmap_register (cur, (1ULL << tail), GRUB_MEMORY_HOLE);
}
return 0;
}