| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| # Supermicro X11SSH-TF | ||
|
|
||
| This section details how to run coreboot on the [Supermicro X11SSH-TF]. | ||
|
|
||
| ## Required proprietary blobs | ||
|
|
||
| * [Intel FSP2.0] | ||
| * Intel ME | ||
|
|
||
| ## Flashing coreboot | ||
|
|
||
| The board can be flashed externally using *some* programmers. | ||
| The CH341 was found working, while Dediprog won't detect the chip. | ||
|
|
||
| For more details have a look at the [flashing tutorial]. | ||
|
|
||
| The flash IC can be found between the two PCIe slots near the southbridge: | ||
|  | ||
|
|
||
| ## BMC (IPMI) | ||
|
|
||
| This board has an ASPEED [AST2400], which has BMC functionality. The | ||
| BMC firmware resides in a 32 MiB SOIC-16 chip in the corner of the | ||
| mainboard near the [AST2400]. This chip is an [MX25L25635F]. | ||
|
|
||
| ## Known issues | ||
|
|
||
| - Intel SGX causes secondary APs to crash (disabled for now). | ||
| - Tianocore doesn't work with Aspeed NGI, as it's text mode only. | ||
| - After S5 resume coreboot detects more DIMMs than installed, causing FSP-M | ||
| to fail. | ||
|
|
||
| ## Tested and working | ||
|
|
||
| - USB ports | ||
| - M.2 2280 NVMe slot | ||
| - 2x 10GB Ethernet | ||
| - SATA | ||
| - RS232 | ||
| - VGA on Aspeed | ||
| - Super I/O initialisation | ||
| - ECC DRAM detection | ||
| - PCIe slots | ||
| - TPM on TPM expansion header | ||
| - BMC (IPMI) | ||
|
|
||
| ## Technology | ||
|
|
||
| ```eval_rst | ||
| +------------------+--------------------------------------------------+ | ||
| | CPU | Intel Kaby Lake | | ||
| +------------------+--------------------------------------------------+ | ||
| | PCH | Intel C236 | | ||
| +------------------+--------------------------------------------------+ | ||
| | Super I/O | ASPEED AST2400 | | ||
| +------------------+--------------------------------------------------+ | ||
| | Coprocessor | Intel SPS (server version of the ME) | | ||
| +------------------+--------------------------------------------------+ | ||
| | Coprocessor | ASPEED AST2400 | | ||
| +------------------+--------------------------------------------------+ | ||
| ``` | ||
|
|
||
| ## Extra links | ||
|
|
||
| - [Board manual] | ||
|
|
||
| [AST2400]: https://www.aspeedtech.com/products.php?fPath=20&rId=376 | ||
| [Board manual]: https://www.supermicro.com/manuals/motherboard/C236/MNL-1783.pdf | ||
| [flashrom]: https://flashrom.org/Flashrom | ||
| [MX25L25635F]: https://media.digikey.com/pdf/Data%20Sheets/Macronix/MX25L25635F.pdf | ||
| [N25Q128A]: https://www.micron.com/~/media/Documents/Products/Data%20Sheet/NOR%20Flash/Serial%20NOR/N25Q/n25q_128mb_3v_65nm.pdf | ||
| [flashing tutorial]: ../../flash_tutorial/ext_power.md | ||
| [Intel FSP2.0]: ../../soc/intel/fsp/index.md | ||
| [Supermicro X11SSH-TF]: https://www.supermicro.com/en/products/motherboard/X11SSH-TF |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| # SuperIO SSTD generator | ||
|
|
||
| This page describes the common SSDT ACPI generator for SuperIO chips that can | ||
| be found in coreboot. | ||
|
|
||
| ## Functional description | ||
|
|
||
| In order to automatically generate ACPI functions you need to add | ||
| a new `chip superio/common` and `device pnp xx.0 on` to your devicetree. | ||
|
|
||
| The xx denotes the hexadecimal address of the SuperIO. | ||
|
|
||
| Place the regular LDN pnp devices behind those two entries. | ||
|
|
||
| The code will automatically guess the function based on the decoded | ||
| I/O range and ISA IRQ number. | ||
|
|
||
| ## Example devicetree.cb | ||
|
|
||
| This example is based on AST2400. | ||
|
|
||
| ```code | ||
| # Add a "container" for proper ACPI code generation | ||
| chip superio/common | ||
| device pnp 2e.0 on # just for the base device, not for the LDNs | ||
| chip superio/aspeed/ast2400 | ||
| device pnp 2e.0 off end | ||
| device pnp 2e.2 on # SUART1 | ||
| io 0x60 = 0x3f8 | ||
| irq 0x70 = 4 | ||
| end | ||
| device pnp 2e.3 on # SUART2 | ||
| io 0x60 = 0x2f8 | ||
| irq 0x70 = 3 | ||
| end | ||
| device pnp 2e.4 on # SWC | ||
| io 0x60 = 0xa00 | ||
| io 0x62 = 0xa10 | ||
| io 0x64 = 0xa20 | ||
| io 0x66 = 0xa30 | ||
| irq 0x70 = 0 | ||
| end | ||
| end | ||
| end | ||
| end | ||
| ``` | ||
|
|
||
| ## TODO | ||
|
|
||
| 1) Add ACPI HIDs to every SuperIO driver | ||
| 2) Don't guess ACPI HID of LDNs if it's known | ||
| 3) Add "enter config" and "exit config" bytes | ||
| 4) Generate support methods that allow | ||
| * Setting resource settings at runtime | ||
| * Getting resource settings at runtime | ||
| * Disabling LDNs at runtime |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,15 @@ | ||
| config ARCH_BOOTBLOCK_ARMV4 | ||
| bool | ||
| select ARCH_BOOTBLOCK_ARM | ||
|
|
||
| config ARCH_VERSTAGE_ARMV4 | ||
| bool | ||
| select ARCH_VERSTAGE_ARM | ||
|
|
||
| config ARCH_ROMSTAGE_ARMV4 | ||
| bool | ||
| select ARCH_ROMSTAGE_ARM | ||
|
|
||
| config ARCH_RAMSTAGE_ARMV4 | ||
| bool | ||
| select ARCH_RAMSTAGE_ARM |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,37 +1,39 @@ | ||
| config ARCH_BOOTBLOCK_ARMV7 | ||
| bool | ||
| select ARCH_BOOTBLOCK_ARM | ||
|
|
||
| config ARCH_VERSTAGE_ARMV7 | ||
| bool | ||
| select ARCH_VERSTAGE_ARM | ||
|
|
||
| config ARCH_ROMSTAGE_ARMV7 | ||
| bool | ||
| select ARCH_ROMSTAGE_ARM | ||
|
|
||
| config ARCH_RAMSTAGE_ARMV7 | ||
| bool | ||
| select ARCH_RAMSTAGE_ARM | ||
|
|
||
| config ARCH_BOOTBLOCK_ARMV7_M | ||
| bool | ||
| select ARCH_BOOTBLOCK_ARM | ||
|
|
||
| config ARCH_VERSTAGE_ARMV7_M | ||
| bool | ||
| select ARCH_VERSTAGE_ARM | ||
|
|
||
| config ARCH_BOOTBLOCK_ARMV7_R | ||
| bool | ||
| select ARCH_BOOTBLOCK_ARM | ||
|
|
||
| config ARCH_VERSTAGE_ARMV7_R | ||
| bool | ||
| select ARCH_VERSTAGE_ARM | ||
|
|
||
| config ARCH_ROMSTAGE_ARMV7_R | ||
| bool | ||
| select ARCH_ROMSTAGE_ARM | ||
|
|
||
| config ARCH_RAMSTAGE_ARMV7_R | ||
| bool | ||
| select ARCH_RAMSTAGE_ARM |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| /* | ||
| * This file is part of the coreboot project. | ||
| * | ||
| * Copyright 2013 Google Inc. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| /* | ||
| * This file is part of the coreboot project. | ||
| * | ||
| * Copyright 2013 Google Inc. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| /* | ||
| * This file is part of the coreboot project. | ||
| * | ||
| * Copyright 2013 Google Inc. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| /* | ||
| * This file is part of the coreboot project. | ||
| * | ||
| * Copyright 2013 Google Inc. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,6 @@ | ||
| /* | ||
| * This file is part of the coreboot project. | ||
| * | ||
| * Copyright 2010, Google Inc. | ||
| * All rights reserved. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| /* | ||
| * This file is part of the coreboot project. | ||
| * | ||
| * Copyright 2013 Google Inc. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| /* | ||
| * This file is part of the coreboot project. | ||
| * | ||
| * Copyright 2013 Google Inc. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| /* | ||
| * This file is part of the coreboot project. | ||
| * | ||
| * SPDX-License-Identifier: GPL-2.0-or-later | ||
| */ | ||
|
|
||
| #include <types.h> | ||
| #include <device/mmio.h> | ||
| #include <ramdetect.h> | ||
| #include <arch/exception.h> | ||
| #include <arch/transition.h> | ||
|
|
||
| static enum { | ||
| ABORT_CHECKER_NOT_TRIGGERED, | ||
| ABORT_CHECKER_TRIGGERED, | ||
| } abort_state = ABORT_CHECKER_NOT_TRIGGERED; | ||
|
|
||
| static int abort_checker(struct exc_state *state, uint64_t vector_id) | ||
| { | ||
| if (raw_read_esr_el3() >> 26 != 0x25) | ||
| return EXC_RET_IGNORED; /* Not a data abort. */ | ||
|
|
||
| abort_state = ABORT_CHECKER_TRIGGERED; | ||
| state->elx.elr += sizeof(uint32_t); /* Jump over faulting instruction. */ | ||
| raw_write_elr_el3(state->elx.elr); | ||
| return EXC_RET_HANDLED; | ||
| } | ||
|
|
||
| static struct exception_handler sync_el0 = {.handler = &abort_checker}; | ||
|
|
||
| int probe_mb(const uintptr_t dram_start, const uintptr_t size) | ||
| { | ||
| uintptr_t addr = dram_start + (size * MiB) - sizeof(uint32_t); | ||
| void *ptr = (void *)addr; | ||
|
|
||
| abort_state = ABORT_CHECKER_NOT_TRIGGERED; | ||
| exception_handler_register(EXC_VID_CUR_SP_EL0_SYNC, &sync_el0); | ||
| read32(ptr); | ||
| exception_handler_unregister(EXC_VID_CUR_SP_EL0_SYNC, &sync_el0); | ||
| return abort_state == ABORT_CHECKER_NOT_TRIGGERED; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| /* | ||
| * Copyright 2013 Google Inc. | ||
| * Copyright 2018 Facebook, Inc. | ||
| * Copyright 2019 9elements Agency GmbH <patrick.rudolph@9elements.com> | ||
| * | ||
| * 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; either version 2 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * 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 <console/console.h> | ||
| #include <bootmem.h> | ||
| #include <stdlib.h> | ||
| #include <program_loading.h> | ||
| #include <string.h> | ||
| #include <commonlib/compression.h> | ||
| #include <commonlib/cbfs_serialized.h> | ||
| #include <lib.h> | ||
| #include <fit.h> | ||
| #include <endian.h> | ||
|
|
||
| /* Implements a Berkley Boot Loader (BBL) compatible payload loading */ | ||
|
|
||
| #define MAX_KERNEL_SIZE (64*MiB) | ||
|
|
||
| #if CONFIG(ARCH_RISCV_RV32) | ||
| #define SECTION_ALIGN (4 * MiB) | ||
| #endif | ||
| #if CONFIG(ARCH_RISCV_RV64) | ||
| #define SECTION_ALIGN (2 * MiB) | ||
| #endif | ||
|
|
||
| static size_t get_kernel_size(const struct fit_image_node *node) | ||
| { | ||
| /* | ||
| * Since we don't have a way to determine the uncompressed size of the | ||
| * kernel, we have to keep as much memory as possible free for use by | ||
| * the kernel immediately after the end of the kernel image. The amount | ||
| * of space required will vary depending on selected features, and is | ||
| * effectively unbound. | ||
| */ | ||
|
|
||
| printk(BIOS_INFO, | ||
| "FIT: Leaving additional %u MiB of free space after kernel.\n", | ||
| MAX_KERNEL_SIZE >> 20); | ||
|
|
||
| return node->size + MAX_KERNEL_SIZE; | ||
| } | ||
|
|
||
| /** | ||
| * Place the region in free memory range. | ||
| * | ||
| * The caller has to set region->offset to the minimum allowed address. | ||
| */ | ||
| static bool fit_place_mem(const struct range_entry *r, void *arg) | ||
| { | ||
| struct region *region = arg; | ||
| resource_t start; | ||
|
|
||
| if (range_entry_tag(r) != BM_MEM_RAM) | ||
| return true; | ||
|
|
||
| /* Section must be aligned at page boundary */ | ||
| start = ALIGN_UP(MAX(region->offset, range_entry_base(r)), SECTION_ALIGN); | ||
|
|
||
| if (start + region->size < range_entry_end(r)) { | ||
| region->offset = (size_t)start; | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| bool fit_payload_arch(struct prog *payload, struct fit_config_node *config, | ||
| struct region *kernel, | ||
| struct region *fdt, | ||
| struct region *initrd) | ||
| { | ||
| void *arg = NULL; | ||
|
|
||
| if (!config->fdt || !fdt) { | ||
| printk(BIOS_CRIT, "CRIT: Providing a valid FDT is mandatory to " | ||
| "boot a RISC-V kernel!\n"); | ||
| return false; | ||
| /* TODO: Fall back to the ROM FDT? */ | ||
| } | ||
|
|
||
| /* Update kernel size from image header, if possible */ | ||
| kernel->size = get_kernel_size(config->kernel); | ||
| printk(BIOS_DEBUG, "FIT: Using kernel size of 0x%zx bytes\n", | ||
| kernel->size); | ||
|
|
||
| /* | ||
| * The code assumes that bootmem_walk provides a sorted list of memory | ||
| * regions, starting from the lowest address. | ||
| * The order of the calls here doesn't matter, as the placement is | ||
| * enforced in the called functions. | ||
| * For details check code on top. | ||
| */ | ||
| kernel->offset = 0; | ||
| if (!bootmem_walk(fit_place_mem, kernel)) | ||
| return false; | ||
|
|
||
| /* Mark as reserved for future allocations. */ | ||
| bootmem_add_range(kernel->offset, kernel->size, BM_MEM_PAYLOAD); | ||
|
|
||
| /* Place FDT and INITRD after kernel. */ | ||
|
|
||
| /* Place INITRD */ | ||
| if (config->ramdisk) { | ||
| initrd->offset = kernel->offset + kernel->size; | ||
|
|
||
| if (!bootmem_walk(fit_place_mem, initrd)) | ||
| return false; | ||
| /* Mark as reserved for future allocations. */ | ||
| bootmem_add_range(initrd->offset, initrd->size, BM_MEM_PAYLOAD); | ||
| } | ||
|
|
||
| /* Place FDT */ | ||
| fdt->offset = kernel->offset + kernel->size; | ||
|
|
||
| if (!bootmem_walk(fit_place_mem, fdt)) | ||
| return false; | ||
| /* Mark as reserved for future allocations. */ | ||
| bootmem_add_range(fdt->offset, fdt->size, BM_MEM_PAYLOAD); | ||
|
|
||
| /* Kernel expects FDT as argument */ | ||
| arg = (void *)fdt->offset; | ||
|
|
||
| prog_set_entry(payload, (void *)kernel->offset, arg); | ||
|
|
||
| bootmem_dump_ranges(); | ||
|
|
||
| return true; | ||
| } |