MErge mainline into intwrap
This commit is contained in:
commit
afba9f98ec
719 changed files with 55744 additions and 25714 deletions
265
grub-core/kern/i386/pc/init.c
Normal file
265
grub-core/kern/i386/pc/init.c
Normal file
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/kernel.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/machine/boot.h>
|
||||
#include <grub/machine/init.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/machine/console.h>
|
||||
#include <grub/machine/kernel.h>
|
||||
#include <grub/machine/int.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/loader.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/cache.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/cpu/tsc.h>
|
||||
|
||||
struct mem_region
|
||||
{
|
||||
grub_addr_t addr;
|
||||
grub_size_t size;
|
||||
};
|
||||
|
||||
#define MAX_REGIONS 32
|
||||
|
||||
static struct mem_region mem_regions[MAX_REGIONS];
|
||||
static int num_regions;
|
||||
|
||||
grub_addr_t grub_os_area_addr;
|
||||
grub_size_t grub_os_area_size;
|
||||
|
||||
static char *
|
||||
make_install_device (void)
|
||||
{
|
||||
/* XXX: This should be enough. */
|
||||
char dev[100], *ptr = dev;
|
||||
|
||||
if (grub_prefix[0] != '(')
|
||||
{
|
||||
/* No hardcoded root partition - make it from the boot drive and the
|
||||
partition number encoded at the install time. */
|
||||
if (grub_boot_drive == GRUB_BOOT_MACHINE_PXE_DL)
|
||||
{
|
||||
grub_strcpy (dev, "(pxe");
|
||||
ptr += sizeof ("(pxe") - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_snprintf (dev, sizeof (dev),
|
||||
"(%cd%u", (grub_boot_drive & 0x80) ? 'h' : 'f',
|
||||
grub_boot_drive & 0x7f);
|
||||
ptr += grub_strlen (ptr);
|
||||
|
||||
if (grub_install_dos_part >= 0)
|
||||
grub_snprintf (ptr, sizeof (dev) - (ptr - dev),
|
||||
",%u", grub_install_dos_part + 1);
|
||||
ptr += grub_strlen (ptr);
|
||||
|
||||
if (grub_install_bsd_part >= 0)
|
||||
grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%u",
|
||||
grub_install_bsd_part + 1);
|
||||
ptr += grub_strlen (ptr);
|
||||
}
|
||||
|
||||
grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ")%s", grub_prefix);
|
||||
grub_strcpy (grub_prefix, dev);
|
||||
}
|
||||
else if (grub_prefix[1] == ',' || grub_prefix[1] == ')')
|
||||
{
|
||||
/* We have a prefix, but still need to fill in the boot drive. */
|
||||
grub_snprintf (dev, sizeof (dev),
|
||||
"(%cd%u%s", (grub_boot_drive & 0x80) ? 'h' : 'f',
|
||||
grub_boot_drive & 0x7f, grub_prefix + 1);
|
||||
grub_strcpy (grub_prefix, dev);
|
||||
}
|
||||
|
||||
return grub_prefix;
|
||||
}
|
||||
|
||||
/* Add a memory region. */
|
||||
static void
|
||||
add_mem_region (grub_addr_t addr, grub_size_t size)
|
||||
{
|
||||
if (num_regions == MAX_REGIONS)
|
||||
/* Ignore. */
|
||||
return;
|
||||
|
||||
mem_regions[num_regions].addr = addr;
|
||||
mem_regions[num_regions].size = size;
|
||||
num_regions++;
|
||||
}
|
||||
|
||||
/* Compact memory regions. */
|
||||
static void
|
||||
compact_mem_regions (void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/* Sort them. */
|
||||
for (i = 0; i < num_regions - 1; i++)
|
||||
for (j = i + 1; j < num_regions; j++)
|
||||
if (mem_regions[i].addr > mem_regions[j].addr)
|
||||
{
|
||||
struct mem_region tmp = mem_regions[i];
|
||||
mem_regions[i] = mem_regions[j];
|
||||
mem_regions[j] = tmp;
|
||||
}
|
||||
|
||||
/* Merge overlaps. */
|
||||
for (i = 0; i < num_regions - 1; i++)
|
||||
if (mem_regions[i].addr + mem_regions[i].size >= mem_regions[i + 1].addr)
|
||||
{
|
||||
j = i + 1;
|
||||
|
||||
if (mem_regions[i].addr + mem_regions[i].size
|
||||
< mem_regions[j].addr + mem_regions[j].size)
|
||||
mem_regions[i].size = (mem_regions[j].addr + mem_regions[j].size
|
||||
- mem_regions[i].addr);
|
||||
|
||||
grub_memmove (mem_regions + j, mem_regions + j + 1,
|
||||
(num_regions - j - 1) * sizeof (struct mem_region));
|
||||
i--;
|
||||
num_regions--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* grub_get_conv_memsize(i) : return the conventional memory size in KB.
|
||||
* BIOS call "INT 12H" to get conventional memory size
|
||||
* The return value in AX.
|
||||
*/
|
||||
static inline grub_uint16_t
|
||||
grub_get_conv_memsize (void)
|
||||
{
|
||||
struct grub_bios_int_registers regs;
|
||||
|
||||
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||
grub_bios_interrupt (0x12, ®s);
|
||||
return regs.eax & 0xffff;
|
||||
}
|
||||
|
||||
void
|
||||
grub_machine_init (void)
|
||||
{
|
||||
int i;
|
||||
int grub_lower_mem;
|
||||
|
||||
/* Initialize the console as early as possible. */
|
||||
grub_console_init ();
|
||||
|
||||
grub_lower_mem = grub_get_conv_memsize () << 10;
|
||||
|
||||
/* Sanity check. */
|
||||
if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END)
|
||||
grub_fatal ("too small memory");
|
||||
|
||||
#if 0
|
||||
/* Turn on Gate A20 to access >1MB. */
|
||||
grub_gate_a20 (1);
|
||||
#endif
|
||||
|
||||
/* FIXME: This prevents loader/i386/linux.c from using low memory. When our
|
||||
heap implements support for requesting a chunk in low memory, this should
|
||||
no longer be a problem. */
|
||||
#if 0
|
||||
/* Add the lower memory into free memory. */
|
||||
if (grub_lower_mem >= GRUB_MEMORY_MACHINE_RESERVED_END)
|
||||
add_mem_region (GRUB_MEMORY_MACHINE_RESERVED_END,
|
||||
grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END);
|
||||
#endif
|
||||
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
|
||||
{
|
||||
/* Avoid the lower memory. */
|
||||
if (addr < 0x100000)
|
||||
{
|
||||
if (size <= 0x100000 - addr)
|
||||
return 0;
|
||||
|
||||
size -= 0x100000 - addr;
|
||||
addr = 0x100000;
|
||||
}
|
||||
|
||||
/* Ignore >4GB. */
|
||||
if (addr <= 0xFFFFFFFF && type == GRUB_MACHINE_MEMORY_AVAILABLE)
|
||||
{
|
||||
grub_size_t len;
|
||||
|
||||
len = (grub_size_t) ((addr + size > 0xFFFFFFFF)
|
||||
? 0xFFFFFFFF - addr
|
||||
: size);
|
||||
add_mem_region (addr, len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_machine_mmap_iterate (hook);
|
||||
|
||||
compact_mem_regions ();
|
||||
|
||||
/* Add the memory regions to free memory, except for the region starting
|
||||
from 1MB. This region is partially used for loading OS images.
|
||||
For now, 1/4 of this is added to free memory. */
|
||||
for (i = 0; i < num_regions; i++)
|
||||
if (mem_regions[i].addr == 0x100000)
|
||||
{
|
||||
grub_size_t quarter = mem_regions[i].size >> 2;
|
||||
|
||||
grub_os_area_addr = mem_regions[i].addr;
|
||||
grub_os_area_size = mem_regions[i].size - quarter;
|
||||
grub_mm_init_region ((void *) (grub_os_area_addr + grub_os_area_size),
|
||||
quarter);
|
||||
}
|
||||
else
|
||||
grub_mm_init_region ((void *) mem_regions[i].addr, mem_regions[i].size);
|
||||
|
||||
if (! grub_os_area_addr)
|
||||
grub_fatal ("no upper memory");
|
||||
|
||||
grub_tsc_init ();
|
||||
}
|
||||
|
||||
void
|
||||
grub_machine_set_prefix (void)
|
||||
{
|
||||
/* Initialize the prefix. */
|
||||
grub_env_set ("prefix", make_install_device ());
|
||||
}
|
||||
|
||||
void
|
||||
grub_machine_fini (void)
|
||||
{
|
||||
grub_console_fini ();
|
||||
grub_stop_floppy ();
|
||||
}
|
||||
|
||||
/* Return the end of the core image. */
|
||||
grub_addr_t
|
||||
grub_arch_modules_addr (void)
|
||||
{
|
||||
return GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR
|
||||
+ (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE);
|
||||
}
|
677
grub-core/kern/i386/pc/lzma_decode.S
Normal file
677
grub-core/kern/i386/pc/lzma_decode.S
Normal file
|
@ -0,0 +1,677 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define FIXED_PROPS
|
||||
|
||||
#define LZMA_BASE_SIZE 1846
|
||||
#define LZMA_LIT_SIZE 768
|
||||
|
||||
#define LZMA_PROPERTIES_SIZE 5
|
||||
|
||||
#define kNumTopBits 24
|
||||
#define kTopValue (1 << kNumTopBits)
|
||||
|
||||
#define kNumBitModelTotalBits 11
|
||||
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
||||
#define kNumMoveBits 5
|
||||
|
||||
|
||||
#define kNumPosBitsMax 4
|
||||
#define kNumPosStatesMax (1 << kNumPosBitsMax)
|
||||
|
||||
#define kLenNumLowBits 3
|
||||
#define kLenNumLowSymbols (1 << kLenNumLowBits)
|
||||
#define kLenNumMidBits 3
|
||||
#define kLenNumMidSymbols (1 << kLenNumMidBits)
|
||||
#define kLenNumHighBits 8
|
||||
#define kLenNumHighSymbols (1 << kLenNumHighBits)
|
||||
|
||||
#define LenChoice 0
|
||||
#define LenChoice2 (LenChoice + 1)
|
||||
#define LenLow (LenChoice2 + 1)
|
||||
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
|
||||
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
|
||||
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
|
||||
|
||||
|
||||
#define kNumStates 12
|
||||
#define kNumLitStates 7
|
||||
|
||||
#define kStartPosModelIndex 4
|
||||
#define kEndPosModelIndex 14
|
||||
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
|
||||
|
||||
#define kNumPosSlotBits 6
|
||||
#define kNumLenToPosStates 4
|
||||
|
||||
#define kNumAlignBits 4
|
||||
#define kAlignTableSize (1 << kNumAlignBits)
|
||||
|
||||
#define kMatchMinLen 2
|
||||
|
||||
#define IsMatch 0
|
||||
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
|
||||
#define IsRepG0 (IsRep + kNumStates)
|
||||
#define IsRepG1 (IsRepG0 + kNumStates)
|
||||
#define IsRepG2 (IsRepG1 + kNumStates)
|
||||
#define IsRep0Long (IsRepG2 + kNumStates)
|
||||
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
|
||||
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
|
||||
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
|
||||
#define LenCoder (Align + kAlignTableSize)
|
||||
#define RepLenCoder (LenCoder + kNumLenProbs)
|
||||
#define Literal (RepLenCoder + kNumLenProbs)
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
DbgOut:
|
||||
pushf
|
||||
pushl %ebp
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %edx
|
||||
pushl %ecx
|
||||
pushl %ebx
|
||||
pushl %eax
|
||||
|
||||
call _DebugPrint
|
||||
|
||||
popl %eax
|
||||
popl %ebx
|
||||
popl %ecx
|
||||
popl %edx
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ebp
|
||||
popf
|
||||
|
||||
ret
|
||||
|
||||
|
||||
/*
|
||||
* int LzmaDecodeProperties(CLzmaProperties *propsRes,
|
||||
* const unsigned char *propsData,
|
||||
* int size);
|
||||
*/
|
||||
|
||||
_LzmaDecodePropertiesA:
|
||||
movb (%edx), %dl
|
||||
|
||||
xorl %ecx, %ecx
|
||||
1:
|
||||
cmpb $45, %dl
|
||||
jb 2f
|
||||
incl %ecx
|
||||
subb $45, %dl
|
||||
jmp 1b
|
||||
2:
|
||||
movl %ecx, 8(%eax) /* pb */
|
||||
xorl %ecx, %ecx
|
||||
1:
|
||||
cmpb $9, %dl
|
||||
jb 2f
|
||||
incl %ecx
|
||||
subb $9, %dl
|
||||
2:
|
||||
movl %ecx, 4(%eax) /* lp */
|
||||
movb %dl, %cl
|
||||
movl %ecx, (%eax) /* lc */
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef ASM_FILE
|
||||
xorl %eax, %eax
|
||||
#endif
|
||||
ret
|
||||
|
||||
#define out_size 8(%ebp)
|
||||
|
||||
#define now_pos -4(%ebp)
|
||||
#define prev_byte -8(%ebp)
|
||||
#define range -12(%ebp)
|
||||
#define code -16(%ebp)
|
||||
#define state -20(%ebp)
|
||||
#define rep0 -24(%ebp)
|
||||
#define rep1 -28(%ebp)
|
||||
#define rep2 -32(%ebp)
|
||||
#define rep3 -36(%ebp)
|
||||
|
||||
#ifdef FIXED_PROPS
|
||||
|
||||
#define FIXED_LC 3
|
||||
#define FIXED_LP 0
|
||||
#define FIXED_PB 2
|
||||
|
||||
#define POS_STATE_MASK ((1 << (FIXED_PB)) - 1)
|
||||
#define LIT_POS_MASK ((1 << (FIXED_LP)) - 1)
|
||||
|
||||
#define LOCAL_SIZE 36
|
||||
|
||||
#else
|
||||
|
||||
#define lc (%ebx)
|
||||
#define lp 4(%ebx)
|
||||
#define pb 8(%ebx)
|
||||
#define probs 12(%ebx)
|
||||
|
||||
#define pos_state_mask -40(%ebp)
|
||||
#define lit_pos_mask -44(%ebp)
|
||||
|
||||
#define LOCAL_SIZE 44
|
||||
|
||||
#endif
|
||||
|
||||
RangeDecoderBitDecode:
|
||||
#ifdef FIXED_PROPS
|
||||
leal (%ebx, %eax, 4), %eax
|
||||
#else
|
||||
shll $2, %eax
|
||||
addl probs, %eax
|
||||
#endif
|
||||
|
||||
movl %eax, %ecx
|
||||
movl (%ecx), %eax
|
||||
|
||||
movl range, %edx
|
||||
shrl $kNumBitModelTotalBits, %edx
|
||||
mull %edx
|
||||
|
||||
cmpl code, %eax
|
||||
jbe 1f
|
||||
|
||||
movl %eax, range
|
||||
movl $kBitModelTotal, %edx
|
||||
subl (%ecx), %edx
|
||||
shrl $kNumMoveBits, %edx
|
||||
addl %edx, (%ecx)
|
||||
clc
|
||||
3:
|
||||
pushf
|
||||
cmpl $kTopValue, range
|
||||
jnc 2f
|
||||
shll $8, code
|
||||
lodsb
|
||||
movb %al, code
|
||||
shll $8, range
|
||||
2:
|
||||
popf
|
||||
ret
|
||||
1:
|
||||
subl %eax, range
|
||||
subl %eax, code
|
||||
movl (%ecx), %edx
|
||||
shrl $kNumMoveBits, %edx
|
||||
subl %edx, (%ecx)
|
||||
stc
|
||||
jmp 3b
|
||||
|
||||
RangeDecoderBitTreeDecode:
|
||||
RangeDecoderReverseBitTreeDecode:
|
||||
movzbl %cl, %ecx
|
||||
xorl %edx, %edx
|
||||
pushl %edx
|
||||
incl %edx
|
||||
pushl %edx
|
||||
|
||||
1:
|
||||
pushl %eax
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
|
||||
addl %edx, %eax
|
||||
call RangeDecoderBitDecode
|
||||
|
||||
popl %edx
|
||||
popl %ecx
|
||||
|
||||
jnc 2f
|
||||
movl 4(%esp), %eax
|
||||
orl %eax, 8(%esp)
|
||||
stc
|
||||
|
||||
2:
|
||||
adcl %edx, %edx
|
||||
popl %eax
|
||||
|
||||
shll $1, (%esp)
|
||||
loop 1b
|
||||
|
||||
popl %ecx
|
||||
subl %ecx, %edx /* RangeDecoderBitTreeDecode */
|
||||
popl %ecx /* RangeDecoderReverseBitTreeDecode */
|
||||
ret
|
||||
|
||||
LzmaLenDecode:
|
||||
pushl %eax
|
||||
addl $LenChoice, %eax
|
||||
call RangeDecoderBitDecode
|
||||
popl %eax
|
||||
jc 1f
|
||||
pushl $0
|
||||
movb $kLenNumLowBits, %cl
|
||||
addl $LenLow, %eax
|
||||
2:
|
||||
movl 12(%esp), %edx
|
||||
shll %cl, %edx
|
||||
addl %edx, %eax
|
||||
3:
|
||||
|
||||
call RangeDecoderBitTreeDecode
|
||||
popl %eax
|
||||
addl %eax, %edx
|
||||
ret
|
||||
|
||||
1:
|
||||
pushl %eax
|
||||
addl $LenChoice2, %eax
|
||||
call RangeDecoderBitDecode
|
||||
popl %eax
|
||||
jc 1f
|
||||
pushl $kLenNumLowSymbols
|
||||
movb $kLenNumMidBits, %cl
|
||||
addl $LenMid, %eax
|
||||
jmp 2b
|
||||
|
||||
1:
|
||||
pushl $(kLenNumLowSymbols + kLenNumMidSymbols)
|
||||
addl $LenHigh, %eax
|
||||
movb $kLenNumHighBits, %cl
|
||||
jmp 3b
|
||||
|
||||
WriteByte:
|
||||
movb %al, prev_byte
|
||||
stosb
|
||||
incl now_pos
|
||||
ret
|
||||
|
||||
/*
|
||||
* int LzmaDecode(CLzmaDecoderState *vs,
|
||||
* const unsigned char *inStream,
|
||||
* unsigned char *outStream,
|
||||
* SizeT outSize);
|
||||
*/
|
||||
|
||||
_LzmaDecodeA:
|
||||
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
subl $LOCAL_SIZE, %esp
|
||||
|
||||
#ifndef ASM_FILE
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
pushl %ebx
|
||||
|
||||
movl %eax, %ebx
|
||||
movl %edx, %esi
|
||||
pushl %ecx
|
||||
#else
|
||||
pushl %edi
|
||||
#endif
|
||||
|
||||
cld
|
||||
|
||||
#ifdef FIXED_PROPS
|
||||
movl %ebx, %edi
|
||||
movl $(Literal + (LZMA_LIT_SIZE << (FIXED_LC + FIXED_LP))), %ecx
|
||||
#else
|
||||
movl $LZMA_LIT_SIZE, %eax
|
||||
movb lc, %cl
|
||||
addb lp, %cl
|
||||
shll %cl, %eax
|
||||
addl $Literal, %eax
|
||||
movl %eax, %ecx
|
||||
movl probs, %edi
|
||||
#endif
|
||||
|
||||
movl $(kBitModelTotal >> 1), %eax
|
||||
|
||||
rep
|
||||
stosl
|
||||
|
||||
popl %edi
|
||||
|
||||
xorl %eax, %eax
|
||||
movl %eax, now_pos
|
||||
movl %eax, prev_byte
|
||||
movl %eax, state
|
||||
|
||||
incl %eax
|
||||
movl %eax, rep0
|
||||
movl %eax, rep1
|
||||
movl %eax, rep2
|
||||
movl %eax, rep3
|
||||
|
||||
#ifndef FIXED_PROPS
|
||||
movl %eax, %edx
|
||||
movb pb, %cl
|
||||
shll %cl, %edx
|
||||
decl %edx
|
||||
movl %edx, pos_state_mask
|
||||
|
||||
movl %eax, %edx
|
||||
movb lp, %cl
|
||||
shll %cl, %edx
|
||||
decl %edx
|
||||
movl %edx, lit_pos_mask;
|
||||
#endif
|
||||
|
||||
/* RangeDecoderInit */
|
||||
negl %eax
|
||||
movl %eax, range
|
||||
|
||||
incl %eax
|
||||
movb $5, %cl
|
||||
|
||||
1:
|
||||
shll $8, %eax
|
||||
lodsb
|
||||
loop 1b
|
||||
|
||||
movl %eax, code
|
||||
|
||||
lzma_decode_loop:
|
||||
movl now_pos, %eax
|
||||
cmpl out_size, %eax
|
||||
|
||||
jb 1f
|
||||
|
||||
#ifndef ASM_FILE
|
||||
xorl %eax, %eax
|
||||
|
||||
popl %ebx
|
||||
popl %edi
|
||||
popl %esi
|
||||
#endif
|
||||
|
||||
movl %ebp, %esp
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
1:
|
||||
#ifdef FIXED_PROPS
|
||||
andl $POS_STATE_MASK, %eax
|
||||
#else
|
||||
andl pos_state_mask, %eax
|
||||
#endif
|
||||
pushl %eax /* posState */
|
||||
movl state, %edx
|
||||
shll $kNumPosBitsMax, %edx
|
||||
addl %edx, %eax
|
||||
pushl %eax /* (state << kNumPosBitsMax) + posState */
|
||||
|
||||
call RangeDecoderBitDecode
|
||||
jc 1f
|
||||
|
||||
movl now_pos, %eax
|
||||
|
||||
#ifdef FIXED_PROPS
|
||||
andl $LIT_POS_MASK, %eax
|
||||
shll $FIXED_LC, %eax
|
||||
movl prev_byte, %edx
|
||||
shrl $(8 - FIXED_LC), %edx
|
||||
#else
|
||||
andl lit_pos_mask, %eax
|
||||
movb lc, %cl
|
||||
shll %cl, %eax
|
||||
negb %cl
|
||||
addb $8, %cl
|
||||
movl prev_byte, %edx
|
||||
shrl %cl, %edx
|
||||
#endif
|
||||
|
||||
addl %edx, %eax
|
||||
movl $LZMA_LIT_SIZE, %edx
|
||||
mull %edx
|
||||
addl $Literal, %eax
|
||||
pushl %eax
|
||||
|
||||
incl %edx /* edx = 1 */
|
||||
|
||||
movl rep0, %eax
|
||||
negl %eax
|
||||
pushl (%edi, %eax) /* matchByte */
|
||||
|
||||
cmpb $kNumLitStates, state
|
||||
jb 5f
|
||||
|
||||
/* LzmaLiteralDecodeMatch */
|
||||
|
||||
3:
|
||||
cmpl $0x100, %edx
|
||||
jae 4f
|
||||
|
||||
xorl %eax, %eax
|
||||
shlb $1, (%esp)
|
||||
adcl %eax, %eax
|
||||
|
||||
pushl %eax
|
||||
pushl %edx
|
||||
|
||||
shll $8, %eax
|
||||
leal 0x100(%edx, %eax), %eax
|
||||
addl 12(%esp), %eax
|
||||
call RangeDecoderBitDecode
|
||||
|
||||
setc %al
|
||||
popl %edx
|
||||
adcl %edx, %edx
|
||||
|
||||
popl %ecx
|
||||
cmpb %cl, %al
|
||||
jz 3b
|
||||
|
||||
5:
|
||||
|
||||
/* LzmaLiteralDecode */
|
||||
|
||||
cmpl $0x100, %edx
|
||||
jae 4f
|
||||
|
||||
pushl %edx
|
||||
movl %edx, %eax
|
||||
addl 8(%esp), %eax
|
||||
call RangeDecoderBitDecode
|
||||
popl %edx
|
||||
adcl %edx, %edx
|
||||
jmp 5b
|
||||
|
||||
4:
|
||||
addl $16, %esp
|
||||
|
||||
movb %dl, %al
|
||||
call WriteByte
|
||||
|
||||
movb state, %al
|
||||
cmpb $4, %al
|
||||
jae 2f
|
||||
xorb %al, %al
|
||||
jmp 3f
|
||||
2:
|
||||
subb $3, %al
|
||||
cmpb $7, %al
|
||||
jb 3f
|
||||
subb $3, %al
|
||||
3:
|
||||
movb %al, state
|
||||
jmp lzma_decode_loop
|
||||
|
||||
1:
|
||||
movl state, %eax
|
||||
addl $IsRep, %eax
|
||||
call RangeDecoderBitDecode
|
||||
jnc 1f
|
||||
|
||||
movl state, %eax
|
||||
addl $IsRepG0, %eax
|
||||
call RangeDecoderBitDecode
|
||||
jc 10f
|
||||
|
||||
movl (%esp), %eax
|
||||
addl $IsRep0Long, %eax
|
||||
call RangeDecoderBitDecode
|
||||
jc 20f
|
||||
|
||||
cmpb $7, state
|
||||
movb $9, state
|
||||
jb 100f
|
||||
addb $2, state
|
||||
100:
|
||||
|
||||
movl $1, %ecx
|
||||
|
||||
3:
|
||||
movl rep0, %edx
|
||||
negl %edx
|
||||
|
||||
4:
|
||||
movb (%edi, %edx), %al
|
||||
call WriteByte
|
||||
loop 4b
|
||||
|
||||
popl %eax
|
||||
popl %eax
|
||||
jmp lzma_decode_loop
|
||||
|
||||
10:
|
||||
movl state, %eax
|
||||
addl $IsRepG1, %eax
|
||||
call RangeDecoderBitDecode
|
||||
movl rep1, %edx
|
||||
jnc 100f
|
||||
|
||||
movl state, %eax
|
||||
addl $IsRepG2, %eax
|
||||
call RangeDecoderBitDecode
|
||||
movl rep2, %edx
|
||||
jnc 1000f
|
||||
movl rep2, %edx
|
||||
xchgl rep3, %edx
|
||||
1000:
|
||||
pushl rep1
|
||||
popl rep2
|
||||
100:
|
||||
xchg rep0, %edx
|
||||
movl %edx, rep1
|
||||
20:
|
||||
|
||||
movl $RepLenCoder, %eax
|
||||
call LzmaLenDecode
|
||||
|
||||
cmpb $7, state
|
||||
movb $8, state
|
||||
jb 100f
|
||||
addb $3, state
|
||||
100:
|
||||
jmp 2f
|
||||
|
||||
1:
|
||||
movl rep0, %eax
|
||||
xchgl rep1, %eax
|
||||
xchgl rep2, %eax
|
||||
movl %eax, rep3
|
||||
|
||||
cmpb $7, state
|
||||
movb $7, state
|
||||
jb 10f
|
||||
addb $3, state
|
||||
10:
|
||||
|
||||
movl $LenCoder, %eax
|
||||
call LzmaLenDecode
|
||||
pushl %edx
|
||||
|
||||
movl $(kNumLenToPosStates - 1), %eax
|
||||
cmpl %eax, %edx
|
||||
jbe 100f
|
||||
movl %eax, %edx
|
||||
100:
|
||||
movb $kNumPosSlotBits, %cl
|
||||
shll %cl, %edx
|
||||
leal PosSlot(%edx), %eax
|
||||
call RangeDecoderBitTreeDecode
|
||||
|
||||
movl %edx, rep0
|
||||
cmpl $kStartPosModelIndex, %edx
|
||||
jb 100f
|
||||
|
||||
movl %edx, %ecx
|
||||
shrl $1, %ecx
|
||||
decl %ecx
|
||||
|
||||
movzbl %dl, %eax
|
||||
andb $1, %al
|
||||
orb $2, %al
|
||||
shll %cl, %eax
|
||||
movl %eax, rep0
|
||||
|
||||
cmpl $kEndPosModelIndex, %edx
|
||||
jae 200f
|
||||
movl rep0, %eax
|
||||
addl $(SpecPos - 1), %eax
|
||||
subl %edx, %eax
|
||||
jmp 300f
|
||||
200:
|
||||
|
||||
subb $kNumAlignBits, %cl
|
||||
|
||||
/* RangeDecoderDecodeDirectBits */
|
||||
xorl %edx, %edx
|
||||
|
||||
1000:
|
||||
shrl $1, range
|
||||
shll $1, %edx
|
||||
|
||||
movl range, %eax
|
||||
cmpl %eax, code
|
||||
jb 2000f
|
||||
subl %eax, code
|
||||
orb $1, %dl
|
||||
2000:
|
||||
|
||||
cmpl $kTopValue, %eax
|
||||
jae 3000f
|
||||
shll $8, range
|
||||
shll $8, code
|
||||
lodsb
|
||||
movb %al, code
|
||||
|
||||
3000:
|
||||
loop 1000b
|
||||
|
||||
movb $kNumAlignBits, %cl
|
||||
shll %cl, %edx
|
||||
addl %edx, rep0
|
||||
|
||||
movl $Align, %eax
|
||||
|
||||
300:
|
||||
call RangeDecoderReverseBitTreeDecode
|
||||
addl %ecx, rep0
|
||||
|
||||
100:
|
||||
incl rep0
|
||||
popl %edx
|
||||
|
||||
2:
|
||||
|
||||
addl $kMatchMinLen, %edx
|
||||
movl %edx, %ecx
|
||||
|
||||
jmp 3b
|
155
grub-core/kern/i386/pc/mmap.c
Normal file
155
grub-core/kern/i386/pc/mmap.c
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/machine/init.h>
|
||||
#include <grub/machine/int.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/misc.h>
|
||||
|
||||
/*
|
||||
* grub_get_ext_memsize() : return the extended memory size in KB.
|
||||
* BIOS call "INT 15H, AH=88H" to get extended memory size
|
||||
* The return value in AX.
|
||||
*
|
||||
*/
|
||||
static inline grub_uint16_t
|
||||
grub_get_ext_memsize (void)
|
||||
{
|
||||
struct grub_bios_int_registers regs;
|
||||
|
||||
regs.eax = 0x8800;
|
||||
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||
grub_bios_interrupt (0x15, ®s);
|
||||
return regs.eax & 0xffff;
|
||||
}
|
||||
|
||||
/* Get a packed EISA memory map. Lower 16 bits are between 1MB and 16MB
|
||||
in 1KB parts, and upper 16 bits are above 16MB in 64KB parts. If error, return zero.
|
||||
BIOS call "INT 15H, AH=E801H" to get EISA memory map,
|
||||
AX = memory between 1M and 16M in 1K parts.
|
||||
BX = memory above 16M in 64K parts.
|
||||
*/
|
||||
|
||||
static inline grub_uint32_t
|
||||
grub_get_eisa_mmap (void)
|
||||
{
|
||||
struct grub_bios_int_registers regs;
|
||||
|
||||
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||
regs.eax = 0xe801;
|
||||
grub_bios_interrupt (0x15, ®s);
|
||||
|
||||
if ((regs.eax & 0xff00) == 0x8600)
|
||||
return 0;
|
||||
|
||||
return (regs.eax & 0xffff) | (regs.ebx << 16);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* grub_get_mmap_entry(addr, cont) : address and old continuation value (zero to
|
||||
* start), for the Query System Address Map BIOS call.
|
||||
*
|
||||
* Sets the first 4-byte int value of "addr" to the size returned by
|
||||
* the call. If the call fails, sets it to zero.
|
||||
*
|
||||
* Returns: new (non-zero) continuation value, 0 if done.
|
||||
*/
|
||||
/* Get a memory map entry. Return next continuation value. Zero means
|
||||
the end. */
|
||||
static grub_uint32_t
|
||||
grub_get_mmap_entry (struct grub_machine_mmap_entry *entry,
|
||||
grub_uint32_t cont)
|
||||
{
|
||||
struct grub_bios_int_registers regs;
|
||||
|
||||
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||
|
||||
/* place address (+4) in ES:DI */
|
||||
regs.es = ((grub_addr_t) &entry->addr) >> 4;
|
||||
regs.edi = ((grub_addr_t) &entry->addr) & 0xf;
|
||||
|
||||
/* set continuation value */
|
||||
regs.ebx = cont;
|
||||
|
||||
/* set default maximum buffer size */
|
||||
regs.ecx = sizeof (*entry) - sizeof (entry->size);
|
||||
|
||||
/* set EDX to 'SMAP' */
|
||||
regs.edx = 0x534d4150;
|
||||
|
||||
regs.eax = 0xe820;
|
||||
grub_bios_interrupt (0x15, ®s);
|
||||
|
||||
/* write length of buffer (zero if error) into ADDR */
|
||||
if ((regs.flags & GRUB_CPU_INT_FLAGS_CARRY) || regs.eax != 0x534d4150
|
||||
|| regs.ecx < 0x14 || regs.ecx > 0x400)
|
||||
entry->size = 0;
|
||||
else
|
||||
entry->size = regs.ecx;
|
||||
|
||||
/* return the continuation value */
|
||||
return regs.ebx;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
|
||||
{
|
||||
grub_uint32_t cont;
|
||||
struct grub_machine_mmap_entry *entry
|
||||
= (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
|
||||
|
||||
grub_memset (entry, 0, sizeof (entry));
|
||||
|
||||
/* Check if grub_get_mmap_entry works. */
|
||||
cont = grub_get_mmap_entry (entry, 0);
|
||||
|
||||
if (entry->size)
|
||||
do
|
||||
{
|
||||
if (hook (entry->addr, entry->len,
|
||||
/* Multiboot mmaps have been defined to match with the E820 definition.
|
||||
Therefore, we can just pass type through. */
|
||||
entry->type))
|
||||
break;
|
||||
|
||||
if (! cont)
|
||||
break;
|
||||
|
||||
grub_memset (entry, 0, sizeof (entry));
|
||||
|
||||
cont = grub_get_mmap_entry (entry, cont);
|
||||
}
|
||||
while (entry->size);
|
||||
else
|
||||
{
|
||||
grub_uint32_t eisa_mmap = grub_get_eisa_mmap ();
|
||||
|
||||
if (eisa_mmap)
|
||||
{
|
||||
if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, GRUB_MACHINE_MEMORY_AVAILABLE) == 0)
|
||||
hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MACHINE_MEMORY_AVAILABLE);
|
||||
}
|
||||
else
|
||||
hook (0x100000, grub_get_ext_memsize () << 10, GRUB_MACHINE_MEMORY_AVAILABLE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
1042
grub-core/kern/i386/pc/startup.S
Normal file
1042
grub-core/kern/i386/pc/startup.S
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue