diff --git a/payloads/Kconfig b/payloads/Kconfig index 627bb95c9c1..f29e02279e1 100644 --- a/payloads/Kconfig +++ b/payloads/Kconfig @@ -30,7 +30,7 @@ config PAYLOAD_ELF config PAYLOAD_FIT bool "A FIT payload" - depends on ARCH_ARM64 || ARCH_RISCV || ARCH_ARM + depends on ARCH_ARM64 || ARCH_RISCV || ARCH_ARM || ARCH_PPC64 select PAYLOAD_FIT_SUPPORT help Select this option if you have a payload image (a FIT file) which @@ -96,8 +96,8 @@ config PAYLOAD_IS_FLAT_BINARY config PAYLOAD_FIT_SUPPORT bool "FIT support" default n - default y if PAYLOAD_LINUX && (ARCH_ARM || ARCH_ARM64 || ARCH_RISCV) - depends on ARCH_ARM64 || ARCH_RISCV || ARCH_ARM + default y if PAYLOAD_LINUX && (ARCH_ARM || ARCH_ARM64 || ARCH_RISCV || ARCH_PPC64) + depends on ARCH_ARM64 || ARCH_RISCV || ARCH_ARM || ARCH_PPC64 select FLATTENED_DEVICE_TREE help Select this option if your payload is of type FIT. diff --git a/payloads/Makefile.inc b/payloads/Makefile.inc index d89b5ba5037..c784951bf67 100644 --- a/payloads/Makefile.inc +++ b/payloads/Makefile.inc @@ -28,6 +28,7 @@ payloads/external/tianocore \ payloads/external/GRUB2 \ payloads/external/LinuxBoot \ payloads/external/Yabits \ +payloads/external/skiboot force-payload: diff --git a/payloads/external/Makefile.inc b/payloads/external/Makefile.inc index e30f57052d0..4b95de86b80 100644 --- a/payloads/external/Makefile.inc +++ b/payloads/external/Makefile.inc @@ -324,3 +324,8 @@ payloads/external/Yabits/uefi/build/uefi.elf yabits: payloads/external/BOOTBOOT/bootboot/dist/bootbootcb.elf: $(MAKE) -C payloads/external/BOOTBOOT all + +# skiboot + +payloads/external/skiboot/talos-skiboot/skiboot.lid: + $(MAKE) -C payloads/external/skiboot all diff --git a/payloads/external/skiboot/Kconfig b/payloads/external/skiboot/Kconfig new file mode 100644 index 00000000000..009c3ea573c --- /dev/null +++ b/payloads/external/skiboot/Kconfig @@ -0,0 +1,16 @@ +## SPDX-License-Identifier: GPL-2.0-only + +if PAYLOAD_SKIBOOT + +config PAYLOAD_FILE + default "payloads/external/skiboot/talos-skiboot/skiboot.lid" + +config PAYLOAD_SPECIFIC_OPTIONS + def_bool y + select PAYLOAD_IS_FLAT_BINARY + select PAYLOAD_FIT_SUPPORT + +config PAYLOAD_OPTIONS + default "-l 0x100000 -e 0x100010" + +endif #PAYLOAD_SKIBOOT diff --git a/payloads/external/skiboot/Kconfig.name b/payloads/external/skiboot/Kconfig.name new file mode 100644 index 00000000000..92d47e17826 --- /dev/null +++ b/payloads/external/skiboot/Kconfig.name @@ -0,0 +1,8 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config PAYLOAD_SKIBOOT + bool "skiboot" + depends on ARCH_PPC64 + help + Select this option if you want to build a coreboot image + with a skiboot payload. diff --git a/payloads/external/skiboot/Makefile b/payloads/external/skiboot/Makefile new file mode 100644 index 00000000000..c657b7c30bb --- /dev/null +++ b/payloads/external/skiboot/Makefile @@ -0,0 +1,26 @@ +## SPDX-License-Identifier: GPL-2.0-only + +skiboot_dir=$(CURDIR)/talos-skiboot +skiboot_git_repo=https://git.raptorcs.com/git/talos-skiboot +skiboot_revision=9858186353f2203fe477f316964e03609d12fd1d + +unexport $(COREBOOT_EXPORTS) + +all: $(skiboot_dir) + cd $(skiboot_dir) && $(MAKE) -j`nproc` CROSS=powerpc64-linux-gnu- DEBUG=1 +# $(error BUILDING SKIBOOT) + +clean: + rm -rf $(skiboot_dir) + #$(MAKE) -C $(skiboot_dir) CROSS=powerpc64-linux-gnu- distclean + +distclean: + rm -rf $(skiboot_dir) + +$(skiboot_dir): + echo " Cloning $(project_name) from Git" + git clone $(skiboot_git_repo) $(skiboot_dir) + echo " Checking out $(skiboot_revision)" + cd $(skiboot_dir) && git checkout $(skiboot_revision) + + diff --git a/payloads/external/skiboot/config.its b/payloads/external/skiboot/config.its new file mode 100644 index 00000000000..168baadd130 --- /dev/null +++ b/payloads/external/skiboot/config.its @@ -0,0 +1,40 @@ +/dts-v1/; +/ { + description = "Simple image with skiboot and FDT blob"; + #address-cells = <1>; + + images { + kernel { + description = "skiboot"; + data = /incbin/("skiboot.lid"); + type = "kernel"; + arch = "powerpc"; + compression = "none"; + load = <0x00000>; + entry = <0x10>; + hash-1 { + algo = "crc32"; + }; + }; + fdt-1 { + description = "Flattened Device Tree blob"; + data = /incbin/("fdt.bin"); + type = "flat_dt"; + arch = "powerpc"; + compression = "none"; + load = <0x1000000>; + hash-1 { + algo = "crc32"; + }; + }; + }; + + configurations { + default = "conf-1"; + conf-1 { + description = "Boot skiboot with FDT blob"; + kernel = "kernel"; + fdt = "fdt-1"; + }; + }; +}; diff --git a/src/arch/ppc64/boot.c b/src/arch/ppc64/boot.c index dc4bb422a3c..3ada906ba8f 100644 --- a/src/arch/ppc64/boot.c +++ b/src/arch/ppc64/boot.c @@ -2,9 +2,185 @@ #include +#if ENV_PAYLOAD_LOADER + +#include +#include +#include + +/* Empty FDT */ +static uint32_t fdt_buf[100*1024] = +{ + FDT_HEADER_MAGIC, /* uint32_t magic; */ + sizeof(struct fdt_header), /* uint32_t totalsize; */ + sizeof(struct fdt_header), /* uint32_t structure_offset; */ + sizeof(struct fdt_header), /* uint32_t strings_offset; */ + sizeof(struct fdt_header), /* uint32_t reserve_map_offset; */ + + FDT_SUPPORTED_VERSION, /* uint32_t version; */ + 16, /* uint32_t last_comp_version; */ + + 4, /* uint32_t boot_cpuid_phys; */ + + 0, /* uint32_t strings_size; */ + 0, /* uint32_t structure_size; */ +}; + +static uint8_t xscom_compat[] = "ibm,xscom\0ibm,power9-xscom\0"; +static uint64_t xscom_addrs[] = { 0x000603fc00000000 }; +static uint64_t xscom_sizes[] = { 0x0000000800000000 }; +static uint8_t chiptod_compat[] = "ibm,power9-chiptod\0ibm,power-chiptod\0"; +static uint64_t chiptod_addrs[] = { 0x40000 }; +static uint64_t chiptod_sizes[] = { 0x34 }; +static uint64_t cpu_addrs[] = { 0x4, 0xc, 0x10, 0x1c }; +static uint8_t lpcm_compat[] = "ibm,power9-lpcm-opb\0simple-bus\0"; +static uint64_t lpcm_addrs[] = { 0x0006030000000000 }; +static uint64_t lpcm_sizes[] = { 0x0000000100000000 }; +static uint32_t lpcm_ranges[] = { 0x00, 0x60300, 0x00, 0x80000000, 0x80000000, + 0x60300, 0x80000000, 0x80000000 }; +static uint8_t lpc_compat[] = "ibm,power9-lpc\0ibm,power8-lpc\0"; +static uint64_t serial_addrs[] = { 0x00000001000003f8 }; +static uint64_t serial_sizes[] = { 1 }; + +static void *fdt_prepare(void) +{ + struct device_tree *dt = fdt_unflatten(&fdt_buf[0]); + struct device_tree_node *node, *subnode, *subsubnode; + + fit_update_memory(dt); + + dt_add_u32_prop(dt->root, "#address-cells", 2); + dt_add_u32_prop(dt->root, "#size-cells", 2); + + + node = xzalloc(sizeof(*node)); + node->name = "xscom"; /* FIXME: shall include the unit address */ + dt_add_bin_prop(node, "primary", NULL, 0); + dt_add_reg_prop(node, xscom_addrs, xscom_sizes, 1, 2, 2); + dt_add_u32_prop(node, "#address-cells", 1); + dt_add_u32_prop(node, "#size-cells", 1); + //~ dt_add_u32_prop(node, "primary", 0); + dt_add_u32_prop(node, "ibm,chip-id", 0 /* FIXME for second CPU */); + dt_add_bin_prop(node, "compatible", xscom_compat, sizeof(xscom_compat)); + list_insert_after(&node->list_node, &dt->root->children); + + subnode = xzalloc(sizeof(*subnode)); + subnode->name = "chiptod"; + dt_add_bin_prop(subnode, "primary", NULL, 0); + dt_add_reg_prop(subnode, chiptod_addrs, chiptod_sizes, 1, 1, 1); + dt_add_bin_prop(subnode, "compatible", chiptod_compat, sizeof(chiptod_compat)); + list_insert_after(&subnode->list_node, &node->children); + + + node = xzalloc(sizeof(*node)); + node->name = "cpus"; + dt_add_u32_prop(node, "#address-cells", 1); + dt_add_u32_prop(node, "#size-cells", 0); + list_insert_after(&node->list_node, &dt->root->children); + + subnode = xzalloc(sizeof(*subnode)); + subnode->name = "PowerPC,POWER9@4"; + dt_add_reg_prop(subnode, &cpu_addrs[0], NULL, 1, 1, 0); + dt_add_string_prop(subnode, "device_type", (char *)"cpu"); + dt_add_string_prop(subnode, "status", (char *)"okay"); + dt_add_u32_prop(subnode, "ibm,chip-id", 0 /* FIXME for second CPU */); + dt_add_u32_prop(subnode, "clock-frequency", 0xa0eebb00); /* 512MHz */ + dt_add_u32_prop(subnode, "timebase-frequency", 0x1e848000); /* 2.7GHz */ + list_insert_after(&subnode->list_node, &node->children); + + subnode = xzalloc(sizeof(*subnode)); + subnode->name = "PowerPC,POWER9@c"; + dt_add_reg_prop(subnode, &cpu_addrs[1], NULL, 1, 1, 0); + dt_add_string_prop(subnode, "device_type", (char *)"cpu"); + dt_add_string_prop(subnode, "status", (char *)"disabled"); + dt_add_u32_prop(subnode, "ibm,chip-id", 0 /* FIXME for second CPU */); + dt_add_u32_prop(subnode, "clock-frequency", 0xa0eebb00); /* 512MHz */ + dt_add_u32_prop(subnode, "timebase-frequency", 0x1e848000); /* 2.7GHz */ + list_insert_after(&subnode->list_node, &node->children); + + subnode = xzalloc(sizeof(*subnode)); + subnode->name = "PowerPC,POWER9@10"; + dt_add_reg_prop(subnode, &cpu_addrs[2], NULL, 1, 1, 0); + dt_add_string_prop(subnode, "device_type", (char *)"cpu"); + dt_add_string_prop(subnode, "status", (char *)"disabled"); + dt_add_u32_prop(subnode, "ibm,chip-id", 0 /* FIXME for second CPU */); + dt_add_u32_prop(subnode, "clock-frequency", 0xa0eebb00); /* 512MHz */ + dt_add_u32_prop(subnode, "timebase-frequency", 0x1e848000); /* 2.7GHz */ + list_insert_after(&subnode->list_node, &node->children); + + subnode = xzalloc(sizeof(*subnode)); + subnode->name = "PowerPC,POWER9@1c"; + dt_add_reg_prop(subnode, &cpu_addrs[3], NULL, 1, 1, 0); + dt_add_string_prop(subnode, "device_type", (char *)"cpu"); + dt_add_string_prop(subnode, "status", (char *)"disabled"); + dt_add_u32_prop(subnode, "ibm,chip-id", 0 /* FIXME for second CPU */); + dt_add_u32_prop(subnode, "clock-frequency", 0xa0eebb00); /* 512MHz */ + dt_add_u32_prop(subnode, "timebase-frequency", 0x1e848000); /* 2.7GHz */ + list_insert_after(&subnode->list_node, &node->children); + + + node = xzalloc(sizeof(*node)); + node->name = "lpcm-opb"; + dt_add_reg_prop(node, lpcm_addrs, lpcm_sizes, 1, 2, 2); + dt_add_u32_prop(node, "#address-cells", 1); + dt_add_u32_prop(node, "#size-cells", 1); + dt_add_bin_prop(node, "compatible", lpcm_compat, sizeof(lpcm_compat)); + dt_add_bin_prop(node, "ranges", lpcm_ranges, sizeof(lpcm_ranges)); + dt_add_u32_prop(node, "ibm,chip-id", 0 /* FIXME for second CPU */); + list_insert_after(&node->list_node, &dt->root->children); + + subnode = xzalloc(sizeof(*subnode)); + subnode->name = "lpc"; + dt_add_u32_prop(subnode, "#address-cells", 2); + dt_add_u32_prop(subnode, "#size-cells", 1); + dt_add_bin_prop(subnode, "compatible", lpc_compat, sizeof(lpc_compat)); + list_insert_after(&subnode->list_node, &node->children); + + subsubnode = xzalloc(sizeof(*subnode)); + subsubnode->name = "serial"; + dt_add_reg_prop(subsubnode, serial_addrs, serial_sizes, 1, 2, 1); + dt_add_string_prop(subsubnode, "device_type", (char *)"serial"); + dt_add_string_prop(subsubnode, "compatible", (char *)"ns16550"); + dt_add_u32_prop(subsubnode, "clock-frequency", 0x1c2000); /* 512MHz */ + dt_add_u32_prop(subsubnode, "current-speed", 0x1c200); /* 2.7GHz */ + list_insert_after(&subsubnode->list_node, &subnode->children); + + + /* Adding 'bmc' node significantly changes skiboot's flow */ + node = xzalloc(sizeof(*node)); + node->name = "bmc"; + dt_add_string_prop(subsubnode, "compatible", (char *)"ibm,ast2500,openbmc"); + list_insert_after(&node->list_node, &dt->root->children); + + + dt_apply_fixups(dt); + + /* Repack FDT for handoff to kernel */ + dt_flatten(dt, &fdt_buf[0]); + + return &fdt_buf[0]; +} + +/* + * Payload's entry point is an offset to the real entry point, not to OPD + * (Official Procedure Descriptor) for entry point. + */ +void arch_prog_run(struct prog *prog) +{ + asm volatile( + "mtctr %1\n" + "mr 3, %0\n" + "bctr\n" + :: "r"(fdt_prepare()), "r"(prog_entry(prog)) : "memory"); +} + +#else + void arch_prog_run(struct prog *prog) { void (*doit)(void *) = prog_entry(prog); doit(prog_entry_arg(prog)); } + +#endif diff --git a/src/arch/ppc64/stages.c b/src/arch/ppc64/stages.c index 3138670ed06..3108bd10572 100644 --- a/src/arch/ppc64/stages.c +++ b/src/arch/ppc64/stages.c @@ -59,7 +59,7 @@ bool fit_payload_arch(struct prog *payload, struct fit_config_node *config, /* Place FDT */ /* TODO: remove hardcoded size */ - fdt->offset = 0xf0000000; + fdt->offset = 0xfe000000; fdt->size = 318539; /* Mark as reserved for future allocations. */ @@ -68,7 +68,7 @@ bool fit_payload_arch(struct prog *payload, struct fit_config_node *config, /* Kernel expects FDT as argument */ arg = (void *)fdt->offset; - prog_set_entry(payload, (void *)0x10 /* kernel->offset + 0x10 ? */, arg); + prog_set_entry(payload, (void *)(kernel->offset + 0x10), arg); bootmem_dump_ranges(); diff --git a/src/lib/fit_payload.c b/src/lib/fit_payload.c index 9613418b950..126470866b1 100644 --- a/src/lib/fit_payload.c +++ b/src/lib/fit_payload.c @@ -205,7 +205,7 @@ void fit_payload(struct prog *payload, void *data) #if defined(CONFIG_LINUX_COMMAND_LINE) fit_update_chosen(dt, (char *)CONFIG_LINUX_COMMAND_LINE); #endif - fit_update_memory(dt); + //~ fit_update_memory(dt); /* Collect infos for fit_payload_arch */ kernel.size = config->kernel->size; diff --git a/src/mainboard/raptor-cs/talos-2/mainboard.c b/src/mainboard/raptor-cs/talos-2/mainboard.c index aa608ea6119..5f7e97ddb0f 100644 --- a/src/mainboard/raptor-cs/talos-2/mainboard.c +++ b/src/mainboard/raptor-cs/talos-2/mainboard.c @@ -4,6 +4,31 @@ #include #include +#include +#include + +static int dt_platform_fixup(struct device_tree_fixup *fixup, + struct device_tree *tree) +{ + struct device_tree_node *node; + //~ uint32_t i = 0x44; + + printk(BIOS_ERR, "dt_platform_fixup called **************************\n"); + + /* Memory devices are always direct children of root */ + list_for_each(node, tree->root->children, list_node) { + const char *devtype = dt_find_string_prop(node, "device_type"); + if (devtype && !strcmp(devtype, "memory")) { + dt_add_u32_prop(node, "ibm,chip-id", 0 /* FIXME for second CPU */); + } + } + + dt_print_node(tree->root); + + printk(BIOS_ERR, "dt_platform_fixup exiting **************************\n"); + return 0; +} + static void mainboard_enable(struct device *dev) { @@ -19,8 +44,19 @@ static void mainboard_enable(struct device *dev) * * TODO: implement this properly for all RAM */ - ram_resource(dev, 0, 0, 4 * 1024 * 1024 - 128 * 1024); - reserved_ram_resource(dev, 1, 4 * 1024 * 1024 - 128 * 1024, 128 * 1024); + ram_resource(dev, 0, 0, 4 * 1024 * 1024 - 256 * 1024); + reserved_ram_resource(dev, 1, 4 * 1024 * 1024 - 256 * 1024, 256 * 1024); + + if (CONFIG(PAYLOAD_FIT_SUPPORT)) { + struct device_tree_fixup *dt_fixup; + + dt_fixup = malloc(sizeof(*dt_fixup)); + if (dt_fixup) { + dt_fixup->fixup = dt_platform_fixup; + list_insert_after(&dt_fixup->list_node, + &device_tree_fixups); + } + } } struct chip_operations mainboard_ops = { diff --git a/src/mainboard/raptor-cs/talos-2/memlayout.ld b/src/mainboard/raptor-cs/talos-2/memlayout.ld index 5f83385bb3d..c8a9ca9bb8c 100644 --- a/src/mainboard/raptor-cs/talos-2/memlayout.ld +++ b/src/mainboard/raptor-cs/talos-2/memlayout.ld @@ -16,13 +16,13 @@ SECTIONS #if !ENV_RAMSTAGE STACK(0x8000, 32K) -#endif - PRERAM_CBMEM_CONSOLE(0x10000, 128K) FMAP_CACHE(0x30000, 4K) CBFS_MCACHE(0x31000, 8K) TIMESTAMP(0x33000, 4K) CBFS_CACHE(0x34000, 512K) +#endif + ROMSTAGE(0x100000, 1M) #if CONFIG(BOOTBLOCK_IN_SEEPROM) @@ -32,7 +32,14 @@ SECTIONS #if !ENV_RAMSTAGE RAMSTAGE(0x300000, 5M) #else + STACK(0xf8008000, 32K) + + PRERAM_CBMEM_CONSOLE(0xf8010000, 128K) + FMAP_CACHE(0xf8030000, 4K) + CBFS_MCACHE(0xf8031000, 8K) + TIMESTAMP(0xf8033000, 4K) RAMSTAGE(0xf8300000, 5M) + CBFS_CACHE(0xf9000000, 20M) #endif } diff --git a/src/soc/ibm/power9/rom_media.c b/src/soc/ibm/power9/rom_media.c index 9b83b38f834..94c5d8eee6f 100644 --- a/src/soc/ibm/power9/rom_media.c +++ b/src/soc/ibm/power9/rom_media.c @@ -14,7 +14,7 @@ #define LPC_FLASH_TOP (LPC_FLASH_MIN + FW_SPACE_SIZE) /* TODO: at some point we may have to change it to a bigger partition (HBI?) */ -#define CBFS_PARTITION_NAME "HBB" +#define CBFS_PARTITION_NAME "HBI" #define MEMD_PARTITION_NAME "MEMD"