Second part of p2v support
This commit is contained in:
parent
368c17f85d
commit
4b2ec20b41
15 changed files with 361 additions and 212 deletions
|
@ -84,12 +84,6 @@ grub_size_t grub_relocator_jumper_size = 12;
|
|||
grub_size_t grub_relocator_jumper_size = 7;
|
||||
#endif
|
||||
|
||||
static inline void *
|
||||
ptov (grub_addr_t a)
|
||||
{
|
||||
return (void *) a;
|
||||
}
|
||||
|
||||
void
|
||||
grub_cpu_relocator_init (void)
|
||||
{
|
||||
|
@ -154,12 +148,11 @@ grub_err_t
|
|||
grub_relocator32_boot (struct grub_relocator *rel,
|
||||
struct grub_relocator32_state state)
|
||||
{
|
||||
grub_phys_addr_t target;
|
||||
void *src;
|
||||
grub_err_t err;
|
||||
void *relst;
|
||||
grub_relocator_chunk_t ch;
|
||||
|
||||
err = grub_relocator_alloc_chunk_align (rel, &src, &target, 0,
|
||||
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
|
||||
(0xffffffff - RELOCATOR_SIZEOF (32))
|
||||
+ 1, RELOCATOR_SIZEOF (32), 16,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||
|
@ -174,9 +167,11 @@ grub_relocator32_boot (struct grub_relocator *rel,
|
|||
grub_relocator32_esp = state.esp;
|
||||
grub_relocator32_esi = state.esi;
|
||||
|
||||
grub_memmove (src, &grub_relocator32_start, RELOCATOR_SIZEOF (32));
|
||||
grub_memmove (get_virtual_current_address (ch), &grub_relocator32_start,
|
||||
RELOCATOR_SIZEOF (32));
|
||||
|
||||
err = grub_relocator_prepare_relocs (rel, ptov (target), &relst, NULL);
|
||||
err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
|
||||
&relst, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -191,12 +186,11 @@ grub_err_t
|
|||
grub_relocator16_boot (struct grub_relocator *rel,
|
||||
struct grub_relocator16_state state)
|
||||
{
|
||||
grub_phys_addr_t target;
|
||||
void *src;
|
||||
grub_err_t err;
|
||||
void *relst;
|
||||
grub_relocator_chunk_t ch;
|
||||
|
||||
err = grub_relocator_alloc_chunk_align (rel, &src, &target, 0,
|
||||
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
|
||||
0xa0000 - RELOCATOR_SIZEOF (16),
|
||||
RELOCATOR_SIZEOF (16), 16,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||
|
@ -216,12 +210,16 @@ grub_relocator16_boot (struct grub_relocator *rel,
|
|||
|
||||
grub_relocator16_edx = state.edx;
|
||||
|
||||
grub_memmove (src, &grub_relocator16_start, RELOCATOR_SIZEOF (16));
|
||||
grub_memmove (get_virtual_current_address (ch), &grub_relocator16_start,
|
||||
RELOCATOR_SIZEOF (16));
|
||||
|
||||
err = grub_relocator_prepare_relocs (rel, ptov (target), &relst, NULL);
|
||||
err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
|
||||
&relst, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
grub_printf ("%p\n", relst);
|
||||
|
||||
asm volatile ("cli");
|
||||
((void (*) (void)) relst) ();
|
||||
|
||||
|
@ -234,12 +232,11 @@ grub_relocator64_boot (struct grub_relocator *rel,
|
|||
struct grub_relocator64_state state,
|
||||
grub_addr_t min_addr, grub_addr_t max_addr)
|
||||
{
|
||||
grub_phys_addr_t target;
|
||||
void *src;
|
||||
grub_err_t err;
|
||||
void *relst;
|
||||
grub_relocator_chunk_t ch;
|
||||
|
||||
err = grub_relocator_alloc_chunk_align (rel, &src, &target, min_addr,
|
||||
err = grub_relocator_alloc_chunk_align (rel, &ch, min_addr,
|
||||
max_addr - RELOCATOR_SIZEOF (64),
|
||||
RELOCATOR_SIZEOF (64), 16,
|
||||
GRUB_RELOCATOR_PREFERENCE_NONE);
|
||||
|
@ -255,9 +252,11 @@ grub_relocator64_boot (struct grub_relocator *rel,
|
|||
grub_relocator64_rsi = state.rsi;
|
||||
grub_relocator64_cr3 = state.cr3;
|
||||
|
||||
grub_memmove (src, &grub_relocator64_start, RELOCATOR_SIZEOF (64));
|
||||
grub_memmove (get_virtual_current_address (ch), &grub_relocator64_start,
|
||||
RELOCATOR_SIZEOF (64));
|
||||
|
||||
err = grub_relocator_prepare_relocs (rel, ptov (target), &relst, NULL);
|
||||
err = grub_relocator_prepare_relocs (rel, get_physical_target_address (ch),
|
||||
&relst, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -81,6 +81,18 @@ struct grub_relocator_fw_leftover *leftovers;
|
|||
|
||||
struct grub_relocator_extra_block *extra_blocks;
|
||||
|
||||
void *
|
||||
get_virtual_current_address (grub_relocator_chunk_t in)
|
||||
{
|
||||
return in->srcv;
|
||||
}
|
||||
|
||||
grub_phys_addr_t
|
||||
get_physical_target_address (grub_relocator_chunk_t in)
|
||||
{
|
||||
return in->target;
|
||||
}
|
||||
|
||||
struct grub_relocator *
|
||||
grub_relocator_new (void)
|
||||
{
|
||||
|
@ -1126,7 +1138,8 @@ adjust_limits (struct grub_relocator *rel,
|
|||
}
|
||||
|
||||
grub_err_t
|
||||
grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, void **src,
|
||||
grub_relocator_alloc_chunk_addr (struct grub_relocator *rel,
|
||||
grub_relocator_chunk_t *out,
|
||||
grub_phys_addr_t target, grub_size_t size)
|
||||
{
|
||||
struct grub_relocator_chunk *chunk;
|
||||
|
@ -1221,13 +1234,14 @@ grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, void **src,
|
|||
grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks,
|
||||
rel->chunks->next);
|
||||
|
||||
*src = chunk->srcv = grub_map_memory (chunk->src, chunk->size);
|
||||
chunk->srcv = grub_map_memory (chunk->src, chunk->size);
|
||||
*out = chunk;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
|
||||
grub_phys_addr_t *target,
|
||||
grub_relocator_alloc_chunk_align (struct grub_relocator *rel,
|
||||
grub_relocator_chunk_t *out,
|
||||
grub_phys_addr_t min_addr,
|
||||
grub_phys_addr_t max_addr,
|
||||
grub_size_t size, grub_size_t align,
|
||||
|
@ -1262,8 +1276,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
|
|||
chunk->size = size;
|
||||
chunk->next = rel->chunks;
|
||||
rel->chunks = chunk;
|
||||
*src = (void *) chunk->src;
|
||||
*target = chunk->target;
|
||||
chunk->srcv = grub_map_memory (chunk->src, chunk->size);
|
||||
*out = chunk;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
|
@ -1300,12 +1314,12 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
|
|||
return 0;
|
||||
candidate = ALIGN_UP (addr, align);
|
||||
if (candidate < min_addr)
|
||||
candidate = min_addr;
|
||||
if (candidate + size >= addr + sz
|
||||
candidate = ALIGN_UP (min_addr, align);
|
||||
if (candidate + size > addr + sz
|
||||
|| candidate > ALIGN_DOWN (max_addr, align))
|
||||
return 0;
|
||||
if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH)
|
||||
candidate = ALIGN_DOWN (addr + sz - size, align);
|
||||
candidate = ALIGN_DOWN (min (addr + sz - size, max_addr), align);
|
||||
if (!found || (preference == GRUB_RELOCATOR_PREFERENCE_HIGH
|
||||
&& candidate > chunk->target))
|
||||
chunk->target = candidate;
|
||||
|
@ -1353,8 +1367,8 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
|
|||
rel->chunks = chunk;
|
||||
grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks,
|
||||
rel->chunks->next);
|
||||
*src = chunk->srcv = grub_map_memory (chunk->src, chunk->size);
|
||||
*target = chunk->target;
|
||||
chunk->srcv = grub_map_memory (chunk->src, chunk->size);
|
||||
*out = chunk;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
|
@ -1378,7 +1392,7 @@ grub_relocator_unload (struct grub_relocator *rel)
|
|||
}
|
||||
|
||||
grub_err_t
|
||||
grub_relocator_prepare_relocs (struct grub_relocator *rel, void *addr,
|
||||
grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr,
|
||||
void **relstart, grub_size_t *relsize)
|
||||
{
|
||||
grub_uint8_t *rels;
|
||||
|
@ -1395,12 +1409,12 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, void *addr,
|
|||
grub_relocator_align,
|
||||
rel->relocators_size, &movers_chunk, 1, 1))
|
||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
rels = rels0 = movers_chunk.srcv;
|
||||
rels = rels0 = grub_map_memory (movers_chunk.src, movers_chunk.size);
|
||||
|
||||
if (relsize)
|
||||
*relsize = rel->relocators_size;
|
||||
|
||||
grub_dprintf ("relocator", "Relocs allocated\n");
|
||||
grub_dprintf ("relocator", "Relocs allocated at %p\n", movers_chunk.srcv);
|
||||
|
||||
{
|
||||
unsigned i;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue