diff options
Diffstat (limited to 'contrib/syslinux/syslinux-4.03/com32/lib/syslinux/shuffle.c')
-rw-r--r-- | contrib/syslinux/syslinux-4.03/com32/lib/syslinux/shuffle.c | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/contrib/syslinux/syslinux-4.03/com32/lib/syslinux/shuffle.c b/contrib/syslinux/syslinux-4.03/com32/lib/syslinux/shuffle.c deleted file mode 100644 index 6b5a601..0000000 --- a/contrib/syslinux/syslinux-4.03/com32/lib/syslinux/shuffle.c +++ /dev/null @@ -1,275 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved - * Copyright 2009 Intel Corporation; author: H. Peter Anvin - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -/* - * shuffle.c - * - * Common code for "shuffle and boot" operation; generates a shuffle list - * and puts it in the bounce buffer. Returns the number of shuffle - * descriptors. - */ - -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> -#include <com32.h> -#include <minmax.h> -#include <syslinux/movebits.h> -#include <klibc/compiler.h> - -#ifndef DEBUG -# define DEBUG 0 -#endif - -#define dprintf(f, ...) ((void)0) -#define dprintf2(f, ...) ((void)0) - -#if DEBUG -# include <stdio.h> -# undef dprintf -# define dprintf printf -# if DEBUG > 1 -# undef dprintf2 -# define dprintf2 printf -# endif -#endif - -struct shuffle_descriptor { - uint32_t dst, src, len; -}; - -static int shuffler_size; - -static void __constructor __syslinux_get_shuffer_size(void) -{ - static com32sys_t reg; - - reg.eax.w[0] = 0x0023; - __intcall(0x22, ®, ®); - - shuffler_size = (reg.eflags.l & EFLAGS_CF) ? 2048 : reg.ecx.w[0]; -} - -/* - * Allocate descriptor memory in these chunks; if this is large we may - * waste memory, if it is small we may get slow convergence. - */ -#define DESC_BLOCK_SIZE 256 - -int syslinux_do_shuffle(struct syslinux_movelist *fraglist, - struct syslinux_memmap *memmap, - addr_t entry_point, addr_t entry_type, - uint16_t bootflags) -{ - int rv = -1; - struct syslinux_movelist *moves = NULL, *mp; - struct syslinux_memmap *rxmap = NULL, *ml; - struct shuffle_descriptor *dp, *dbuf; - int np; - int desc_blocks, need_blocks; - int need_ptrs; - addr_t desczone, descfree, descaddr, descoffs; - int nmoves, nzero; - com32sys_t ireg; - - descaddr = 0; - dp = dbuf = NULL; - - /* Count the number of zero operations */ - nzero = 0; - for (ml = memmap; ml->type != SMT_END; ml = ml->next) { - if (ml->type == SMT_ZERO) - nzero++; - } - - /* Find the largest contiguous region unused by input *and* output; - this is where we put the move descriptor list and safe area */ - - rxmap = syslinux_dup_memmap(memmap); - if (!rxmap) - goto bail; - /* Avoid using the low 1 MB for the shuffle area -- this avoids - possible interference with the real mode code or stack */ - if (syslinux_add_memmap(&rxmap, 0, 1024 * 1024, SMT_RESERVED)) - goto bail; - for (mp = fraglist; mp; mp = mp->next) { - if (syslinux_add_memmap(&rxmap, mp->src, mp->len, SMT_ALLOC) || - syslinux_add_memmap(&rxmap, mp->dst, mp->len, SMT_ALLOC)) - goto bail; - } - if (syslinux_memmap_largest(rxmap, SMT_FREE, &desczone, &descfree)) - goto bail; - - syslinux_free_memmap(rxmap); - - dprintf("desczone = 0x%08x, descfree = 0x%08x\n", desczone, descfree); - - rxmap = syslinux_dup_memmap(memmap); - if (!rxmap) - goto bail; - - desc_blocks = (nzero + DESC_BLOCK_SIZE - 1) / DESC_BLOCK_SIZE; - for (;;) { - /* We want (desc_blocks) allocation blocks, plus the terminating - descriptor, plus the shuffler safe area. */ - addr_t descmem = desc_blocks * - sizeof(struct shuffle_descriptor) * DESC_BLOCK_SIZE - + sizeof(struct shuffle_descriptor) + shuffler_size; - - descaddr = (desczone + descfree - descmem) & ~3; - - if (descaddr < desczone) - goto bail; /* No memory block large enough */ - - /* Mark memory used by shuffle descriptors as reserved */ - if (syslinux_add_memmap(&rxmap, descaddr, descmem, SMT_RESERVED)) - goto bail; - -#if DEBUG > 1 - syslinux_dump_movelist(stdout, fraglist); -#endif - - if (syslinux_compute_movelist(&moves, fraglist, rxmap)) - goto bail; - - nmoves = 0; - for (mp = moves; mp; mp = mp->next) - nmoves++; - - need_blocks = (nmoves + nzero + DESC_BLOCK_SIZE - 1) / DESC_BLOCK_SIZE; - - if (desc_blocks >= need_blocks) - break; /* Sufficient memory, yay */ - - desc_blocks = need_blocks; /* Try again... */ - } - -#if DEBUG > 1 - dprintf("Final movelist:\n"); - syslinux_dump_movelist(stdout, moves); -#endif - - syslinux_free_memmap(rxmap); - rxmap = NULL; - - need_ptrs = nmoves + nzero + 1; - dbuf = malloc(need_ptrs * sizeof(struct shuffle_descriptor)); - if (!dbuf) - goto bail; - - descoffs = descaddr - (addr_t) dbuf; - -#if DEBUG - dprintf("nmoves = %d, nzero = %d, dbuf = %p, offs = 0x%08x\n", - nmoves, nzero, dbuf, descoffs); -#endif - - /* Copy the move sequence into the descriptor buffer */ - np = 0; - dp = dbuf; - for (mp = moves; mp; mp = mp->next) { - dp->dst = mp->dst; - dp->src = mp->src; - dp->len = mp->len; - dprintf2("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len); - dp++; - np++; - } - - /* Copy bzero operations into the descriptor buffer */ - for (ml = memmap; ml->type != SMT_END; ml = ml->next) { - if (ml->type == SMT_ZERO) { - dp->dst = ml->start; - dp->src = (addr_t) - 1; /* bzero region */ - dp->len = ml->next->start - ml->start; - dprintf2("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len); - dp++; - np++; - } - } - - /* Finally, record the termination entry */ - dp->dst = entry_point; - dp->src = entry_type; - dp->len = 0; - dp++; - np++; - - if (np != need_ptrs) { - dprintf("!!! np = %d : nmoves = %d, nzero = %d, desc_blocks = %d\n", - np, nmoves, nzero, desc_blocks); - } - - rv = 0; - -bail: - /* This is safe only because free() doesn't use the bounce buffer!!!! */ - if (moves) - syslinux_free_movelist(moves); - if (rxmap) - syslinux_free_memmap(rxmap); - - if (rv) - return rv; - - /* Actually do it... */ - memset(&ireg, 0, sizeof ireg); - ireg.edi.l = descaddr; - ireg.esi.l = (addr_t) dbuf; - ireg.ecx.l = (addr_t) dp - (addr_t) dbuf; - ireg.edx.w[0] = bootflags; - ireg.eax.w[0] = 0x0024; - __intcall(0x22, &ireg, NULL); - - return -1; /* Shouldn't have returned! */ -} - -/* - * Common helper routine: takes a memory map and blots out the - * zones which are used in the destination of a fraglist - */ -struct syslinux_memmap *syslinux_target_memmap(struct syslinux_movelist - *fraglist, - struct syslinux_memmap *memmap) -{ - struct syslinux_memmap *tmap; - struct syslinux_movelist *mp; - - tmap = syslinux_dup_memmap(memmap); - if (!tmap) - return NULL; - - for (mp = fraglist; mp; mp = mp->next) { - if (syslinux_add_memmap(&tmap, mp->dst, mp->len, SMT_ALLOC)) { - syslinux_free_memmap(tmap); - return NULL; - } - } - - return tmap; -} |