coreboot-kgpe-d16/src/stream/rom_stream.c

147 lines
4.0 KiB
C
Raw Normal View History

#include <console/console.h>
#include <stdlib.h>
#include <stddef.h>
#include <stream/read_bytes.h>
#include <string.h>
/* if they set the precompressed rom stream, they better have set a type */
#if CONFIG_PRECOMPRESSED_PAYLOAD && ((!CONFIG_COMPRESSED_PAYLOAD_NRV2B) && (!CONFIG_COMPRESSED_PAYLOAD_LZMA))
#error "You set CONFIG_PRECOMPRESSED_PAYLOAD but need to set CONFIG_COMPRESSED_PAYLOAD_NRV2B or CONFIG_COMPRESSED_PAYLOAD_LZMA"
#endif
/* If they set ANY of these, then we're compressed */
#if ((CONFIG_COMPRESSED_PAYLOAD_NRV2B) || (CONFIG_COMPRESSED_PAYLOAD_LZMA))
#define UNCOMPRESSER 1
extern unsigned char _heap, _eheap;
#endif
#if (CONFIG_COMPRESSED_PAYLOAD_NRV2B)
#define HAVE_UNCOMPRESSER 1
// include generic nrv2b
#include "../lib/nrv2b.c"
#endif
#if (CONFIG_COMPRESSED_PAYLOAD_LZMA)
#if HAVE_UNCOMPRESSER
#error "You're defining more than one compression type, which is not allowed (of course)"
#endif
#define HAVE_UNCOMPRESSER 1
If you have option CONFIG_COMPRESSED_PAYLOAD_LZMA=1 option CONFIG_PRECOMPRESSED_PAYLOAD=1 set in Config.lb but accidentally use an uncompressed payload, coreboot (v2) bombs out like this: elfboot: Attempting to load payload. rom_stream: 0xfffc0000 - 0xfffdefff Uncompressing to RAM 0x01000000 Decoder scratchpad too small! Decoding error = 1 Unexpected Exception: 6 @ 10:04000408 - Halting Code: 0 eflags: 00010057 eax: 00000101 ebx: 04000400 ecx: 000003d4 edx: fffc0000 edi: 04000400 esi: 04000401 ebp: 04000400 esp: 0013dfb4 The attached patch modifies v2's lzma code so that it assumes an uncompressed payload if it fails to find a properly compressed payload. Compare with the fatal error above: elfboot: Attempting to load payload. rom_stream: 0xfffc0000 - 0xfffdefff Uncompressing to RAM 0x01000000 Decoder scratchpad too small! olen = 0x00000000 done. Decompression failed. Assuming payload is uncompressed... Found ELF candidate at offset 0 header_offset is 0 Try to load at offset 0x0 If you don't have CONFIG_COMPRESSED_PAYLOAD_LZMA and CONFIG_PRECOMPRESSED_PAYLOAD set and use an uncompressed payload, things are as before: elfboot: Attempting to load payload. rom_stream: 0xfffc0000 - 0xfffdefff Found ELF candidate at offset 0 header_offset is 0 Try to load at offset 0x0 One can argue that this is a case of 'builder beware', but my counter argument is that anything that causes unexpected runtime breakage is really, really, really bad, and should be avoided where possible. This patch also fixes one erroneous comment. Signed-off-by: Ward Vandewege <ward@gnu.org> Acked-by: Myles Watson <mylesgw@gmail.com> Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3542 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2008-08-27 23:53:11 +02:00
// include generic lzma
#include "../lib/lzma.c"
#endif
#ifndef CONFIG_ROM_PAYLOAD_START
#define CONFIG_ROM_PAYLOAD_START 0xffff0000UL
#endif
/* well, this is a mess, and it will get fixed, but not right away.
* until we stop using 'ld' for building the rom image, that is.
* problem is, that on the sc520, ROM_PAYLOAD_START has to be at 0x2000000.
* but if you set CONFIG_ROM_PAYLOAD_START to that, then ld will try to
* build a giant image: 0x0-0x2000000, i.e. almost 4 GB.
* so make this non-static, non-const for now.
*/
/*XXXXXXXXXXXXXX */
/*static const */unsigned char *rom_start = (unsigned char *)CONFIG_ROM_PAYLOAD_START;
/*static const */unsigned char *rom_end = (unsigned char *)(CONFIG_ROM_PAYLOAD_START + PAYLOAD_SIZE - 1);
/*XXXXXXXXXXXXXX */
static const unsigned char *rom;
#if UNCOMPRESSER
unsigned long
uncompress(uint8_t * rom_start, uint8_t *dest )
{
#if (CONFIG_COMPRESSED_PAYLOAD_NRV2B)
unsigned long ilen; // used compressed stream length
return unrv2b(rom_start, dest, &ilen);
#endif
#if (CONFIG_COMPRESSED_PAYLOAD_LZMA)
return ulzma(rom_start, dest);
#endif
}
#endif
int stream_init(void)
{
#if (UNCOMPRESSER)
unsigned char *dest;
unsigned long olen;
#endif
printk_debug("rom_stream: 0x%08lx - 0x%08lx\n",
(unsigned long)rom_start,
(unsigned long)rom_end);
#if (UNCOMPRESSER)
dest = &_eheap; /* need a good address on RAM */
#if _RAMBASE<0x00100000
olen = *(unsigned int *)dest;
#if (CONFIG_CONSOLE_VGA==1) || (CONFIG_PCI_ROM_RUN == 1)
if((dest < (unsigned char *)0xa0000) && ((dest+olen)>(unsigned char *)0xa0000)) {
dest = (unsigned char *)(CONFIG_LB_MEM_TOPK<<10);
}
#endif
if((dest < (unsigned char *) 0xf0000) && ((dest+olen)> (unsigned char *)0xf0000)) { // coreboot tables etc
dest = (unsigned char *) (CONFIG_LB_MEM_TOPK<<10);
}
#endif
/* ALL of those settings are too smart and also unsafe. Set the dest to 16 MB:
* known to be safe for LB for now, and mostly safe for all elf images we have tried.
* long term, this has got to be fixed.
*/
dest = (unsigned char *) (16 * 1024 * 1024);
printk_debug("Uncompressing to RAM %p ", dest);
olen = uncompress((uint8_t *) rom_start, (uint8_t *)dest );
printk_debug(" olen = 0x%08lx done.\n", olen);
If you have option CONFIG_COMPRESSED_PAYLOAD_LZMA=1 option CONFIG_PRECOMPRESSED_PAYLOAD=1 set in Config.lb but accidentally use an uncompressed payload, coreboot (v2) bombs out like this: elfboot: Attempting to load payload. rom_stream: 0xfffc0000 - 0xfffdefff Uncompressing to RAM 0x01000000 Decoder scratchpad too small! Decoding error = 1 Unexpected Exception: 6 @ 10:04000408 - Halting Code: 0 eflags: 00010057 eax: 00000101 ebx: 04000400 ecx: 000003d4 edx: fffc0000 edi: 04000400 esi: 04000401 ebp: 04000400 esp: 0013dfb4 The attached patch modifies v2's lzma code so that it assumes an uncompressed payload if it fails to find a properly compressed payload. Compare with the fatal error above: elfboot: Attempting to load payload. rom_stream: 0xfffc0000 - 0xfffdefff Uncompressing to RAM 0x01000000 Decoder scratchpad too small! olen = 0x00000000 done. Decompression failed. Assuming payload is uncompressed... Found ELF candidate at offset 0 header_offset is 0 Try to load at offset 0x0 If you don't have CONFIG_COMPRESSED_PAYLOAD_LZMA and CONFIG_PRECOMPRESSED_PAYLOAD set and use an uncompressed payload, things are as before: elfboot: Attempting to load payload. rom_stream: 0xfffc0000 - 0xfffdefff Found ELF candidate at offset 0 header_offset is 0 Try to load at offset 0x0 One can argue that this is a case of 'builder beware', but my counter argument is that anything that causes unexpected runtime breakage is really, really, really bad, and should be avoided where possible. This patch also fixes one erroneous comment. Signed-off-by: Ward Vandewege <ward@gnu.org> Acked-by: Myles Watson <mylesgw@gmail.com> Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3542 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
2008-08-27 23:53:11 +02:00
if (olen != 0) {
rom_end = dest + olen - 1;
rom = dest;
} else {
/* Decompression failed, assume payload is uncompressed */
printk_debug("Decompression failed. Assuming payload is uncompressed...\n");
rom = rom_start;
}
#else
rom = rom_start;
#endif
return 0;
}
void stream_fini(void)
{
return;
}
byte_offset_t stream_skip(byte_offset_t count)
{
byte_offset_t bytes;
bytes = count;
if ((rom + bytes - 1) > rom_end) {
printk_warning("%6d:%s() - overflowed source buffer\n",
__LINE__, __func__);
bytes = 0;
if (rom <= rom_end) {
bytes = (rom_end - rom) + 1;
}
}
rom += bytes;
return bytes;
}
byte_offset_t stream_read(void *vdest, byte_offset_t count)
{
unsigned char *dest = vdest;
const unsigned char *src = rom;
byte_offset_t bytes;
bytes = stream_skip(count);
memcpy(dest, src, bytes);
return bytes;
}