diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/Makefile.inc | 16 | ||||
-rw-r--r-- | src/lib/bootblock.c | 17 | ||||
-rw-r--r-- | src/lib/decompressor.c | 70 | ||||
-rw-r--r-- | src/lib/program.ld | 6 |
4 files changed, 107 insertions, 2 deletions
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index a902e0cd6a..08ad9b2e4e 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -19,6 +19,19 @@ ramstage-y += ubsan.c CFLAGS_ramstage += -fsanitize=undefined endif +decompressor-y += decompressor.c +$(call src-to-obj,decompressor,$(dir)/decompressor.c): $(objcbfs)/bootblock.lz4 +$(call src-to-obj,decompressor,$(dir)/decompressor.c): CCACHE_EXTRAFILES=$(objcbfs)/bootblock.lz4 +# Must reset CCACHE_EXTRAFILES or make applies it transitively to dependencies. +$(objcbfs)/bootblock.lz4: CCACHE_EXTRAFILES= + +decompressor-y += delay.c +decompressor-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c +decompressor-y += memchr.c +decompressor-y += memcmp.c +decompressor-y += prog_ops.c +decompressor-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c + ifneq ($(CONFIG_BOOTBLOCK_CUSTOM),y) bootblock-y += bootblock.c endif @@ -216,11 +229,13 @@ romstage-y += bootmode.c ramstage-y += bootmode.c verstage-y += bootmode.c +decompressor-y += halt.c bootblock-y += halt.c romstage-y += halt.c ramstage-y += halt.c smm-y += halt.c +decompressor-y += reset.c bootblock-y += reset.c verstage-y += reset.c romstage-y += reset.c @@ -248,6 +263,7 @@ postcar-$(CONFIG_GENERIC_UDELAY) += timer.c # Use program.ld for all the platforms which use C fo the bootblock. bootblock-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += program.ld +decompressor-y += program.ld postcar-y += program.ld romstage-y += program.ld ramstage-y += program.ld diff --git a/src/lib/bootblock.c b/src/lib/bootblock.c index 867f1b16e6..d74bebfe83 100644 --- a/src/lib/bootblock.c +++ b/src/lib/bootblock.c @@ -70,3 +70,20 @@ void main(void) bootblock_main_with_timestamp(base_timestamp, NULL, 0); } + +#if IS_ENABLED(CONFIG_COMPRESS_BOOTBLOCK) +/* + * This is the bootblock entry point when it is run after a decompressor stage. + * For non-decompressor builds, _start is generally defined in architecture- + * specific assembly code. In decompressor builds that architecture + * initialization code already ran in the decompressor, so the bootblock can + * start straight into common code with a C environment. + */ +void _start(struct bootblock_arg *arg); +void _start(struct bootblock_arg *arg) +{ + bootblock_main_with_timestamp(arg->base_timestamp, arg->timestamps, + arg->num_timestamps); +} + +#endif diff --git a/src/lib/decompressor.c b/src/lib/decompressor.c new file mode 100644 index 0000000000..7a5bf3b289 --- /dev/null +++ b/src/lib/decompressor.c @@ -0,0 +1,70 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2018 Google Inc. + * + * This program 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; version 2 of + * the License. + * + * This program 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. + */ + +#include <bootblock_common.h> +#include <commonlib/compression.h> +#include <delay.h> +#include <program_loading.h> +#include <symbols.h> + +extern u8 compressed_bootblock[]; +asm ( + ".pushsection .data.compressed_bootblock,\"a\",@progbits\n\t" + ".type compressed_bootblock, %object\n\t" + ".balign 8\n" + "compressed_bootblock:\n\t" + ".incbin \"" __BUILD_DIR__ "/cbfs/" CONFIG_CBFS_PREFIX "/bootblock.lz4\"\n\t" + ".size compressed_bootblock, . - compressed_bootblock\n\t" + ".popsection\n\t" +); + +struct bootblock_arg arg = { + .base_timestamp = 0, + .num_timestamps = 2, + .timestamps = { + { .entry_id = TS_START_ULZ4F }, + { .entry_id = TS_END_ULZ4F }, + }, +}; + +struct prog prog_bootblock = { + .type = PROG_BOOTBLOCK, + .entry = (void *)_bootblock, + .arg = &arg, +}; + +__weak void decompressor_soc_init(void) { /* no-op */ } + +void main(void) +{ + init_timer(); + + if (IS_ENABLED(CONFIG_COLLECT_TIMESTAMPS)) + arg.base_timestamp = timestamp_get(); + + decompressor_soc_init(); + + if (IS_ENABLED(CONFIG_COLLECT_TIMESTAMPS)) + arg.timestamps[0].entry_stamp = timestamp_get(); + + size_t out_size = ulz4f(compressed_bootblock, _bootblock); + prog_segment_loaded((uintptr_t)_bootblock, out_size, SEG_FINAL); + + if (IS_ENABLED(CONFIG_COLLECT_TIMESTAMPS)) + arg.timestamps[1].entry_stamp = timestamp_get(); + + prog_run(&prog_bootblock); +} diff --git a/src/lib/program.ld b/src/lib/program.ld index 668b29b18e..156b86255c 100644 --- a/src/lib/program.ld +++ b/src/lib/program.ld @@ -34,8 +34,10 @@ *(.rom.data); *(.text._start); *(.text.stage_entry); -#if ENV_BOOTBLOCK && !(IS_ENABLED(CONFIG_ARCH_BOOTBLOCK_X86_32) || \ - IS_ENABLED(CONFIG_ARCH_BOOTBLOCK_X86_64)) +#if (ENV_DECOMPRESSOR || ENV_BOOTBLOCK && \ + !IS_ENABLED(CONFIG_COMPRESS_BOOTBLOCK)) && \ + !(IS_ENABLED(CONFIG_ARCH_BOOTBLOCK_X86_32) || \ + IS_ENABLED(CONFIG_ARCH_BOOTBLOCK_X86_64)) KEEP(*(.id)); #endif *(.text); |