Files
NANOKVM-LicheeRV-Nano-Build…/fsbl/lib/utils/decompress.c
916BGAI dbbad1938a fsbl: sync sg200x-dev through 5a80c12
Update the vendored FSBL from Sophgo sg200x-dev commit
426d1e7eccce84b34169e5f21de7d6e7da1804a1 to
5a80c127cf614dea7f534d5b5352886a1c720d37, incorporating 24 upstream
commits. Keep the local plat/sg200x symlink to cv181x.

Import the upstream DDR, clock, storage and boot-image changes together
with their platform support, prebuilt firmware and licensing files.
All 935 upstream files match the target revision.

Validation on LicheeRV Nano (SG2002/C906, SD, DDR3-1866 x16):
- Cross-build BL2 with the existing Xuantie GCC 10.2.0 toolchain.
- Repack FIP while preserving the installed OpenSBI and U-Boot byte
  for byte; verify headers, payload checksums, entry addresses and LZMA.
- Software reboot and power-cycle boot succeed; memtester 16M 1 passes
  all 18 checks.

Validation covers the FSBL update with existing later boot stages.
Full firmware builds, A53 and video/HID acceptance are not covered.
2026-11-06 18:34:01 +08:00

151 lines
2.8 KiB
C

#include <debug.h>
#include <errno.h>
#include <string.h>
#include <decompress.h>
#include <LzmaDec.h>
#include <lz4frame.h>
static uintptr_t comp_alloc_buf;
static size_t comp_alloc_size;
static void SzInit(void)
{
comp_alloc_buf = DECOMP_ALLOC_ADDR;
comp_alloc_size = DECOMP_ALLOC_SIZE;
}
static void *SzAlloc(ISzAllocPtr p, size_t size)
{
void *x;
x = (void *)comp_alloc_buf;
comp_alloc_buf += size;
if (comp_alloc_buf >= (comp_alloc_buf + comp_alloc_size)) {
ERROR("%s can't alloc %lu bytes\n", __func__, size);
return NULL;
}
return x;
}
static void SzFree(ISzAllocPtr p, void *address)
{
}
int decompress_lzma(void *dst, size_t *dst_size, const void *src, size_t src_size)
{
size_t uncomp_size = 0;
uint32_t tmp;
int ret;
ISzAlloc alloc = { SzAlloc, SzFree };
ELzmaStatus status = 0;
const uint8_t *prop;
if (!dst_size) {
ERROR("%s: dst_size is NULL.\n", __func__);
return -EINVAL;
}
SzInit();
INFO("LZMA1/%p/%p.\n", dst, src);
prop = src;
src += LZMA_PROPS_SIZE;
src_size -= LZMA_PROPS_SIZE;
// Copy 4 bytes to uncomp_size
memcpy(&tmp, src, sizeof(tmp));
uncomp_size = tmp;
src += 8;
src_size -= 8;
INFO("LZMA2/uncomp_size=0x%lx\n", uncomp_size);
ret = LzmaDecode(dst, &uncomp_size, src, &src_size, prop, LZMA_PROPS_SIZE, LZMA_FINISH_END, &status, &alloc);
if (ret != SZ_OK) {
ERROR("LzmaDecode ERROR: %d (status=%d)\n", ret, status);
return -EFAULT;
}
*dst_size = uncomp_size;
INFO("LZMA9/0x%lx\n", *dst_size);
return 0;
}
void *LZ4_malloc(size_t s)
{
return SzAlloc(NULL, s);
}
void *LZ4_calloc(size_t n, size_t s)
{
void *p = LZ4_malloc(n * s);
if (p)
memset(p, 0, n * s);
return p;
}
void LZ4_free(void *p)
{
}
int decompress_lz4(void *dst, size_t *dst_size, const void *src, size_t src_size)
{
LZ4F_dctx *dctx;
size_t ret;
size_t dctxStatus;
SzInit();
INFO("LZ4/%p/%p.\n", dst, src);
dctxStatus = LZ4F_createDecompressionContext(&dctx, LZ4F_VERSION);
if (LZ4F_isError(dctxStatus)) {
ERROR("dctxStatus=%lu\n", dctxStatus);
return -1;
}
ret = LZ4F_decompress(dctx, dst, dst_size, src, &src_size, NULL);
INFO("dst_size=%lu src_size=%lu ret=%zd\n", *dst_size, src_size, ret);
if (LZ4F_isError(dctxStatus)) {
ERROR("LZ4F_decompress=%lu\n", ret);
return -1;
}
#ifdef FSBL_FASTBOOT
(void)(ret);
#endif
// No need to free.
// LZ4F_freeDecompressionContext(dctx);
return 0;
}
int decompress(void *dst, size_t *dst_size, const void *src, size_t src_size, enum COMPRESS_TYPE type)
{
int ret = -EINVAL;
NOTICE("DCP/%p/0x%lx/%p/0x%lx/%d.\n", dst, *dst_size, src, src_size, type);
switch (type) {
case COMP_LZ4:
ret = decompress_lz4(dst, dst_size, src, src_size);
break;
case COMP_LZMA:
ret = decompress_lzma(dst, dst_size, src, src_size);
break;
default:
ret = -EINVAL;
break;
}
NOTICE("DCP/0x%lx/%d.\n", *dst_size, ret);
return ret;
}