struct grub_net_buff * grub_netbuff_alloc (grub_size_t len) { struct grub_net_buff *nb; void *data; COMPILE_TIME_ASSERT (NETBUFF_ALIGN % sizeof (grub_properly_aligned_t) == 0); if (len < NETBUFFMINLEN) len = NETBUFFMINLEN; len = ALIGN_UP (len, NETBUFF_ALIGN); #ifdef GRUB_MACHINE_EMU data = grub_malloc (len + sizeof (*nb)); #else data = grub_memalign (NETBUFF_ALIGN, len + sizeof (*nb)); #endif if (!data) return NULL; nb = (struct grub_net_buff *) ((grub_properly_aligned_t *) data + len / sizeof (grub_properly_aligned_t)); nb->head = nb->data = nb->tail = data; nb->end = (grub_uint8_t *) nb; return nb; }
U32 smp_init(void) { int handle; if (!global_working_memory) { global_working_memory = grub_memalign(SMP_WORKING_MEMORY_ALIGN, SMP_WORKING_MEMORY_SIZE); if (!global_working_memory) { dprintf("smp", "Failed to allocate working memory\n"); return 0; } grub_memset(global_working_memory, 0, SMP_WORKING_MEMORY_SIZE); } if (!global_page_below_1M) { global_page_below_1M = grub_mmap_malign_and_register(SMP_LOW_MEMORY_ALIGN, SMP_LOW_MEMORY_SIZE, &handle, GRUB_MEMORY_AVAILABLE, GRUB_MMAP_MALLOC_LOW); if (!global_page_below_1M) { dprintf("smp", "Failed to allocate a page below 1M\n"); return 0; } else if ((grub_addr_t)global_page_below_1M >= 1048576) { dprintf("smp", "Attempted to allocate a page below 1M, but got %p\n", global_page_below_1M); return 0; } } if (!global_reserved_mwait_memory) { global_reserved_mwait_memory = grub_mmap_malign_and_register(SMP_RESERVED_MEMORY_ALIGN, SMP_RESERVED_MEMORY_SIZE, &handle, GRUB_MEMORY_RESERVED, 0); if (!global_reserved_mwait_memory) { dprintf("smp", "Failed to allocate reserved MWAIT memory\n"); return 0; } } return smp_init_with_memory(global_working_memory, global_page_below_1M, global_reserved_mwait_memory); }
void * grub_mmap_malign_and_register (grub_uint64_t align, grub_uint64_t size, int *handle, int type, int flags) { void *ret; if (flags & (GRUB_MMAP_MALLOC_LOW | GRUB_MMAP_MALLOC_HIGH)) { struct grub_mmap_malign_and_register_closure c; c.align = align; c.size = size; c.highestlow = 0; if (flags & GRUB_MMAP_MALLOC_LOW) { c.min = 0; c.max = 0x100000; } else { c.min = grub_mmap_high; c.max = 0x100000000ll; } /* FIXME: use low-memory mm allocation once it's available. */ grub_mmap_iterate (find_hook, &c); ret = UINT_TO_PTR (c.highestlow); } else ret = grub_memalign (align, size); if (! ret) { *handle = 0; return 0; } *handle = grub_mmap_register (PTR_TO_UINT64 (ret), size, type); if (! *handle) { grub_free (ret); return 0; } return ret; }
/* Really allocate the memory */ static grub_err_t efiemu_alloc_requests (void) { grub_size_t align_overhead = 0; grub_uint8_t *curptr, *typestart; struct grub_efiemu_memrequest *cur; grub_size_t total_alloc = 0; unsigned i; /* Order of memory regions */ grub_efi_memory_type_t reqorder[] = { /* First come regions usable by OS*/ GRUB_EFI_LOADER_CODE, GRUB_EFI_LOADER_DATA, GRUB_EFI_BOOT_SERVICES_CODE, GRUB_EFI_BOOT_SERVICES_DATA, GRUB_EFI_CONVENTIONAL_MEMORY, GRUB_EFI_ACPI_RECLAIM_MEMORY, /* Then memory used by runtime */ /* This way all our regions are in a single block */ GRUB_EFI_RUNTIME_SERVICES_CODE, GRUB_EFI_RUNTIME_SERVICES_DATA, GRUB_EFI_ACPI_MEMORY_NVS, /* And then unavailable memory types. This is more for a completeness. You should double think before allocating memory of any of these types */ GRUB_EFI_UNUSABLE_MEMORY, GRUB_EFI_MEMORY_MAPPED_IO, GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE, GRUB_EFI_PAL_CODE }; /* Compute total memory needed */ for (i = 0; i < sizeof (reqorder) / sizeof (reqorder[0]); i++) { align_overhead = GRUB_EFIEMU_PAGESIZE - (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE); if (align_overhead == GRUB_EFIEMU_PAGESIZE) align_overhead = 0; total_alloc += requested_memory[reqorder[i]] + align_overhead; } /* Allocate the whole memory in one block */ resident_memory = grub_memalign (GRUB_EFIEMU_PAGESIZE, total_alloc); if (!resident_memory) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate resident memory"); /* Split the memory into blocks by type */ curptr = resident_memory; for (i = 0; i < sizeof (reqorder) / sizeof (reqorder[0]); i++) { if (!requested_memory[reqorder[i]]) continue; typestart = curptr; /* Write pointers to requests */ for (cur = memrequests; cur; cur = cur->next) if (cur->type == reqorder[i]) { curptr = ((grub_uint8_t *)curptr) + cur->align_overhead; cur->val = curptr; curptr = ((grub_uint8_t *)curptr) + cur->size; } /* Ensure that the regions are page-aligned */ align_overhead = GRUB_EFIEMU_PAGESIZE - (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE); if (align_overhead == GRUB_EFIEMU_PAGESIZE) align_overhead = 0; curptr = ((grub_uint8_t *)curptr) + align_overhead; /* Add the region to memory map */ grub_efiemu_add_to_mmap (PTR_TO_UINT64 (typestart), curptr - typestart, reqorder[i]); } return GRUB_ERR_NONE; }