| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| # System76 Lemur Pro (lemp9) | ||
|
|
||
| ## Specs | ||
|
|
||
| - CPU | ||
| - Intel i7-10510U | ||
| - Intel i5-10210U | ||
| - EC | ||
| - ITE IT5570E running https://github.com/system76/ec | ||
| - Backlit Keyboard, with standard PS/2 keycodes and SCI hotkeys | ||
| - Battery | ||
| - Charger, using AC adapter or USB-C PD | ||
| - Suspend/resume | ||
| - Touchpad | ||
| - GPU | ||
| - Intel UHD Graphics 620 | ||
| - GOP driver is recommended, VBT is provided | ||
| - eDP 14-inch 1920x1080 LCD | ||
| - HDMI video | ||
| - USB-C DisplayPort video | ||
| - Memory | ||
| - Channel 0: 8-GB on-board DDR4 Samsung K4AAG165WA-BCTD | ||
| - Channel 1: 8-GB/16-GB/32-GB DDR4 SO-DIMM | ||
| - Networking | ||
| - M.2 PCIe/CNVi WiFi/Bluetooth | ||
| - Sound | ||
| - Realtek ALC293D | ||
| - Internal speaker | ||
| - Internal microphone | ||
| - Combined headphone/microphone 3.5-mm jack | ||
| - HDMI audio | ||
| - USB-C DisplayPort audio | ||
| - Storage | ||
| - M.2 PCIe/SATA SSD-1 | ||
| - M.2 PCIe/SATA SSD-2 | ||
| - RTS5227S MicroSD card reader | ||
| - USB | ||
| - 1280x720 CCD camera | ||
| - USB 3.1 Gen 2 Type-C (left) | ||
| - USB 3.1 Gen 2 Type-A (left) | ||
| - USB 3.1 Gen 1 Type-A (right) | ||
|
|
||
| ## Building coreboot | ||
|
|
||
| The following commands will build a working image: | ||
|
|
||
| ```bash | ||
| make distclean | ||
| make defconfig KBUILD_DEFCONFIG=configs/config.system76_lemp9 | ||
| make | ||
| ``` | ||
|
|
||
| ## Flashing coreboot | ||
|
|
||
| ```eval_rst | ||
| +---------------------+------------+ | ||
| | Type | Value | | ||
| +=====================+============+ | ||
| | Socketed flash | no | | ||
| +---------------------+------------+ | ||
| | Vendor | GigaDevice | | ||
| +---------------------+------------+ | ||
| | Model | GD25Q128C | | ||
| +---------------------+------------+ | ||
| | Size | 16 MiB | | ||
| +---------------------+------------+ | ||
| | Package | SOIC-8 | | ||
| +---------------------+------------+ | ||
| | Internal flashing | yes | | ||
| +---------------------+------------+ | ||
| | External flashing | yes | | ||
| +---------------------+------------+ | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| # PNP devices | ||
|
|
||
| Typical PNP devices are Super I/Os, LPC-connected TPMs and board | ||
| management controllers. | ||
|
|
||
| PNP devices are usually connected to the LPC or eSPI bus of a system | ||
| and shouldn't be confused with PCI(e) devices that use a completely | ||
| different plug and play mechanism. PNP originates in the ISA plug and | ||
| play specification. Since the original ISA bus is more or less extinct, | ||
| the auto-detection part of ISA PNP is mostly irrelevant nowadays. For | ||
| the register offsets for different functionality, appendix A of that | ||
| specification is still the main reference though. | ||
|
|
||
| ## Configuration access and config mode | ||
|
|
||
| Super I/O chips connected via LPC to the southbridge usually have their | ||
| I/O-mapped configuration interface with a size of two bytes at the base | ||
| address 0x2e or 0x4e. Other PNP devices have their configuration | ||
| interface at other addresses. | ||
|
|
||
| The two byte registers allow access to an indirect 256 bytes big | ||
| register space that contains the configuration. By writing the index | ||
| to the lower byte (e.g. 0x2e), you can access the register contents at | ||
| that index by reading/writing the higher byte (e.g. 0x2f). | ||
|
|
||
| To prevent accidental changes of the Super I/O (SIO) configuration, | ||
| the SIOs need a configuration mode unlock sequence. After changing the | ||
| configuration, the configuration mode should be left again, by sending | ||
| the configuration mode lock sequence. | ||
|
|
||
| ## Logical device numbers (LDN) | ||
|
|
||
| Each PNP device can contain multiple logical devices. The bytes from | ||
| 0x00 to 0x2f in the indirect configuration register space are common | ||
| for all LDNs, but some SIO chips require a certain LDN to be selected | ||
| in order to write certain registers in there. An LDN gets selected by | ||
| writing the LDN number to the LDN select register 0x07. Registers 0x30 | ||
| to 0xFF are specific to each LDN number. | ||
|
|
||
| coreboot encodes the physical LDN number in the lower byte of the LDN | ||
| number. | ||
|
|
||
| ### Virtual logical device numbers | ||
|
|
||
| Register 0x30 is the LDN enable register and since it is an 8 bit | ||
| register, it can contain up to 8 enable bits for different parts of | ||
| the functionality of that logical device. To set a certain enable bit | ||
| in one physical LDN, the concept of virtual LDNs was introduced. | ||
| Virtual LDNs share the registers of their base LDN, but allow to | ||
| specify which part of a LDN should be enabled. | ||
|
|
||
| coreboot encodes the enable bit number and by that the virtual LDN | ||
| part in the lower 3 bits of the higher byte of the LDN number. | ||
|
|
||
| ## I/O resources | ||
|
|
||
| Starting at register address 0x60, each LDN has 2 byte wide I/O base | ||
| address registers. The size of an I/O resource is always a power of | ||
| two. | ||
|
|
||
| ### I/O resource masks | ||
|
|
||
| The I/O resource masks encode both the size and the maximum base | ||
| address of the corresponding IO resource. The number of zeros counted | ||
| from the least significant bit encode the resource size. If N is the | ||
| number of LSBs being zero, which can also be zero if the LSB is a one, | ||
| the resource has N address bits and a size of 2\*\*N bytes. The mask | ||
| address is also the highest possible address to map the I/O region. | ||
|
|
||
| A typical example for an I/O resource mask is 0x07f8 which is | ||
| 0b0000011111111000 in binary notation. The three LSBs are zeros here, | ||
| so it's an eight byte I/O resource with three address offset bits | ||
| inside the resource. The highest base address it can be mapped to is | ||
| 0x07f8, so the region will end at 0x07ff. | ||
|
|
||
| The Super I/O datasheets typically contain the information about the | ||
| I/O resource masks. On most Super I/O chips the mask can also be found | ||
| out by writing 0xffff to the corresponding I/O base address register | ||
| and reading back the value; since the lowest and highest bits are | ||
| hard-wired to zero according to the I/O resource size and maximal | ||
| possible I/O address, this gives the mask. | ||
|
|
||
| ## IRQ resources | ||
|
|
||
| Each physical LDN has up to two configurable interrupt request | ||
| register pairs 0x70, 0x71 and 0x72, 0x73. Each pair can be configured | ||
| to use a certain IRQ number. Writing 1 to 15 into the first register | ||
| selects the IRQ number generated by the corresponding IRQ source and | ||
| enables IRQ generation; writing 0 to it disables the generation of | ||
| IRQs for the source. The second register selects the IRQ type (level | ||
| or edge) and IRQ level (high or low). For LPC SIOs the IRQ type is | ||
| hard-wired to edge. | ||
|
|
||
| On the LPC bus a shared SERIRQ line is used to signal IRQs to the | ||
| host; the IRQ number gets encoded by the number of LPC clock cycles | ||
| after the start frame before the device pulls the open drain | ||
| connection low. | ||
|
|
||
| SERIRQ can be used in two different modes: In the continuous SERIRQ | ||
| mode the host continuously sends IRQ frame starts and the devices | ||
| signal their IRQ request by pulling low the SERIRQ line at the right | ||
| time. In quiet SERIRQ mode the host doesn't send IRQ frame starts, so | ||
| the devices have to send both the IRQ frame start and the encoded IRQ | ||
| number. The quiet mode is often broken. | ||
|
|
||
| ## DRQ resources | ||
|
|
||
| Each physical LDN has two legacy ISA-style DMA request channel | ||
| registers at 0x74 and 0x75. Those are only used for legacy devices | ||
| like parallel printer ports or floppy disk controllers. | ||
|
|
||
| Each device using LPC legacy DMA needs its own LDMA line to the host. | ||
| Some newer chipsets have dropped the LDMA line and with that the | ||
| legacy DMA capability on LPC. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| CONFIG_VENDOR_ASUS=y | ||
| CONFIG_BOARD_ASUS_P2B=y | ||
| CONFIG_DEBUG_RAM_SETUP=y |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| CONFIG_VENDOR_SYSTEM76=y | ||
| CONFIG_BOARD_SYSTEM76_LEMP9=y | ||
| CONFIG_PAYLOAD_TIANOCORE=y | ||
| CONFIG_RUN_FSP_GOP=y | ||
| CONFIG_SMMSTORE=y |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,3 @@ | ||
| CONFIG_VENDOR_UP=y | ||
| CONFIG_VBOOT=y | ||
| CONFIG_CONSOLE_SPI_FLASH=y |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| if SORTBOOTORDER_SECONDARY_PAYLOAD | ||
|
|
||
| choice | ||
| prompt "sortbootorder version" | ||
| default SORTBOOTORDER_STABLE | ||
|
|
||
| config SORTBOOTORDER_STABLE | ||
| bool "v4.6.17" | ||
| help | ||
| Stable sortbootorder version | ||
|
|
||
| config SORTBOOTORDER_MASTER | ||
| bool "master" | ||
| help | ||
| Newest sortbootorder version | ||
|
|
||
| config SORTBOOTORDER_REVISION | ||
| bool "git revision" | ||
| help | ||
| Select this option if you have a specific commit or branch | ||
| that you want to use as the revision from which to | ||
| build sortbootorder. | ||
|
|
||
| You will be able to specify the name of a branch or a commit id | ||
| later. | ||
|
|
||
| endchoice | ||
|
|
||
| config SORTBOOTORDER_REVISION_ID | ||
| string "Insert sortbootorder commit's SHA-1 or a branch name" | ||
| depends on SORTBOOTORDER_REVISION | ||
| default "origin/master" | ||
| help | ||
| The commit's SHA-1 or branch name of the revision to use. | ||
|
|
||
| endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,4 @@ | ||
| # SPDX-License-Identifier: GPL-2.0-only | ||
| # This file is part of the coreboot project. | ||
|
|
||
| ramstage-$(CONFIG_ACPI_SATA_GENERATOR) += sata.c |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,15 +1,5 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| /* This file is part of the coreboot project. */ | ||
|
|
||
| #include "sata.h" | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,7 +15,6 @@ | |
|
|
||
| #include <mcall.h> | ||
| #include <stdint.h> | ||
| #include <arch/exception.h> | ||
| #include <sbi.h> | ||
| #include <vm.h> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -99,6 +99,7 @@ all-y += boot.c | |
| all-y += memcpy.c | ||
| all-y += memset.c | ||
| all-y += cpu_common.c | ||
| all-y += post.c | ||
|
|
||
| endif | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later */ | ||
|
|
||
| #ifndef _COMMONLIB_BSD_CB_ERR_H_ | ||
| #define _COMMONLIB_BSD_CB_ERR_H_ | ||
|
|
||
| #include <stdint.h> | ||
|
|
||
| /** | ||
| * coreboot error codes | ||
| * | ||
| * Common error definitions that can be used for any function. All error values | ||
| * should be negative -- when useful, positive values can also be used to denote | ||
| * success. Allocate a new group or errors every 100 values. | ||
| */ | ||
| enum cb_err { | ||
| CB_SUCCESS = 0, /**< Call completed successfully */ | ||
| CB_ERR = -1, /**< Generic error code */ | ||
| CB_ERR_ARG = -2, /**< Invalid argument */ | ||
|
|
||
| /* NVRAM/CMOS errors */ | ||
| CB_CMOS_OTABLE_DISABLED = -100, /**< Option table disabled */ | ||
| CB_CMOS_LAYOUT_NOT_FOUND = -101, /**< Layout file not found */ | ||
| CB_CMOS_OPTION_NOT_FOUND = -102, /**< Option string not found */ | ||
| CB_CMOS_ACCESS_ERROR = -103, /**< CMOS access error */ | ||
| CB_CMOS_CHECKSUM_INVALID = -104, /**< CMOS checksum is invalid */ | ||
|
|
||
| /* Keyboard test failures */ | ||
| CB_KBD_CONTROLLER_FAILURE = -200, | ||
| CB_KBD_INTERFACE_FAILURE = -201, | ||
|
|
||
| /* I2C controller failures */ | ||
| CB_I2C_NO_DEVICE = -300, /**< Device is not responding */ | ||
| CB_I2C_BUSY = -301, /**< Device tells it's busy */ | ||
| CB_I2C_PROTOCOL_ERROR = -302, /**< Data lost or spurious slave | ||
| device response, try again? */ | ||
| CB_I2C_TIMEOUT = -303, /**< Transmission timed out */ | ||
| }; | ||
|
|
||
| /* Don't typedef the enum directly, so the size is unambiguous for serialization. */ | ||
| typedef int32_t cb_err_t; | ||
|
|
||
| #endif /* _COMMONLIB_BSD_CB_ERR_H_ */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ | ||
|
|
||
| #ifndef FLASHMAP_SERIALIZED_H__ | ||
| #define FLASHMAP_SERIALIZED_H__ | ||
|
|
||
| #include <stdint.h> | ||
|
|
||
| #define FMAP_SIGNATURE "__FMAP__" | ||
| #define FMAP_VER_MAJOR 1 /* this header's FMAP minor version */ | ||
| #define FMAP_VER_MINOR 1 /* this header's FMAP minor version */ | ||
| #define FMAP_STRLEN 32 /* maximum length for strings, */ | ||
| /* including null-terminator */ | ||
|
|
||
| enum fmap_flags { | ||
| FMAP_AREA_STATIC = 1 << 0, | ||
| FMAP_AREA_COMPRESSED = 1 << 1, | ||
| FMAP_AREA_RO = 1 << 2, | ||
| FMAP_AREA_PRESERVE = 1 << 3, | ||
| }; | ||
|
|
||
| /* Mapping of volatile and static regions in firmware binary */ | ||
| struct fmap_area { | ||
| uint32_t offset; /* offset relative to base */ | ||
| uint32_t size; /* size in bytes */ | ||
| uint8_t name[FMAP_STRLEN]; /* descriptive name */ | ||
| uint16_t flags; /* flags for this area */ | ||
| } __packed; | ||
|
|
||
| struct fmap { | ||
| uint8_t signature[8]; /* "__FMAP__" (0x5F5F464D41505F5F) */ | ||
| uint8_t ver_major; /* major version */ | ||
| uint8_t ver_minor; /* minor version */ | ||
| uint64_t base; /* address of the firmware binary */ | ||
| uint32_t size; /* size of firmware binary in bytes */ | ||
| uint8_t name[FMAP_STRLEN]; /* name of this firmware binary */ | ||
| uint16_t nareas; /* number of areas described by | ||
| fmap_areas[] below */ | ||
| struct fmap_area areas[]; | ||
| } __packed; | ||
|
|
||
| #endif /* FLASHMAP_SERIALIZED_H__ */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ | ||
|
|
||
| #ifndef COMMONLIB_BSD_HELPERS_H | ||
| #define COMMONLIB_BSD_HELPERS_H | ||
|
|
||
| #ifndef __ASSEMBLER__ | ||
| #include <commonlib/bsd/compiler.h> | ||
| #include <stddef.h> | ||
| #endif | ||
|
|
||
| #ifndef ARRAY_SIZE | ||
| #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) | ||
| #endif | ||
|
|
||
| #define ALIGN(x, a) __ALIGN_MASK(x, (__typeof__(x))(a)-1UL) | ||
| #define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) | ||
| #define ALIGN_UP(x, a) ALIGN((x), (a)) | ||
| #define ALIGN_DOWN(x, a) ((x) & ~((__typeof__(x))(a)-1UL)) | ||
| #define IS_ALIGNED(x, a) (((x) & ((__typeof__(x))(a)-1UL)) == 0) | ||
|
|
||
| /* Double-evaluation unsafe min/max, for bitfields and outside of functions */ | ||
| #define __CMP_UNSAFE(a, b, op) ((a) op (b) ? (a) : (b)) | ||
| #define MIN_UNSAFE(a, b) __CMP_UNSAFE(a, b, <) | ||
| #define MAX_UNSAFE(a, b) __CMP_UNSAFE(a, b, >) | ||
|
|
||
| #define __CMP_SAFE(a, b, op, var_a, var_b) ({ \ | ||
| __TYPEOF_UNLESS_CONST(a, b) var_a = (a); \ | ||
| __TYPEOF_UNLESS_CONST(b, a) var_b = (b); \ | ||
| var_a op var_b ? var_a : var_b; \ | ||
| }) | ||
|
|
||
| #define __CMP(a, b, op) __builtin_choose_expr( \ | ||
| __builtin_constant_p(a) && __builtin_constant_p(b), \ | ||
| __CMP_UNSAFE(a, b, op), __CMP_SAFE(a, b, op, __TMPNAME, __TMPNAME)) | ||
|
|
||
| #ifndef MIN | ||
| #define MIN(a, b) __CMP(a, b, <) | ||
| #endif | ||
| #ifndef MAX | ||
| #define MAX(a, b) __CMP(a, b, >) | ||
| #endif | ||
|
|
||
| #ifndef ABS | ||
| #define ABS(a) ({ \ | ||
| __typeof__(a) _abs_local_a = (a); \ | ||
| (_abs_local_a < 0) ? (-_abs_local_a) : _abs_local_a; \ | ||
| }) | ||
| #endif | ||
|
|
||
| #define IS_POWER_OF_2(x) ({ \ | ||
| __typeof__(x) _power_local_x = (x); \ | ||
| (_power_local_x & (_power_local_x - 1)) == 0; \ | ||
| }) | ||
|
|
||
| #define DIV_ROUND_UP(x, y) ({ \ | ||
| __typeof__(x) _div_local_x = (x); \ | ||
| __typeof__(y) _div_local_y = (y); \ | ||
| (_div_local_x + _div_local_y - 1) / _div_local_y; \ | ||
| }) | ||
|
|
||
| #define SWAP(a, b) do { \ | ||
| __typeof__(&(a)) _swap_local_a = &(a); \ | ||
| __typeof__(&(b)) _swap_local_b = &(b); \ | ||
| __typeof__(a) _swap_local_tmp = *_swap_local_a; \ | ||
| *_swap_local_a = *_swap_local_b; \ | ||
| *_swap_local_b = _swap_local_tmp; \ | ||
| } while (0) | ||
|
|
||
| /* Standard units. */ | ||
| #define KiB (1<<10) | ||
| #define MiB (1<<20) | ||
| #define GiB (1<<30) | ||
|
|
||
| #define KHz (1000) | ||
| #define MHz (1000 * KHz) | ||
| #define GHz (1000 * MHz) | ||
|
|
||
| #ifndef offsetof | ||
| #define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER) | ||
| #endif | ||
|
|
||
| #define check_member(structure, member, offset) _Static_assert( \ | ||
| offsetof(struct structure, member) == offset, \ | ||
| "`struct " #structure "` offset for `" #member "` is not " #offset) | ||
|
|
||
| /* Calculate size of structure member. */ | ||
| #define member_size(type, member) (sizeof(((type *)0)->member)) | ||
|
|
||
| #endif /* COMMONLIB_BSD_HELPERS_H */ |