diff --git a/.gitmodules b/.gitmodules index 4fa82999dc8..7a8d6186193 100644 --- a/.gitmodules +++ b/.gitmodules @@ -70,3 +70,7 @@ [submodule "3rdparty/open-power-signing-utils"] path = 3rdparty/open-power-signing-utils url = https://review.coreboot.org/open-power-signing-utils.git +[submodule "src/vendorcode/amd/opensil/turin_poc/opensil"] + path = src/vendorcode/amd/opensil/turin_poc/opensil + url = https://github.com/openSIL/openSIL.git + branch = turin_poc diff --git a/3rdparty/fsp b/3rdparty/fsp index 9623d524500..a5b3d0e056a 160000 --- a/3rdparty/fsp +++ b/3rdparty/fsp @@ -1 +1 @@ -Subproject commit 9623d524500c140a6b11d2c727cb282b54962f09 +Subproject commit a5b3d0e056ad713f0055334427bc424f91aa6602 diff --git a/3rdparty/libgfxinit b/3rdparty/libgfxinit index 17cfc92f402..3c3828add50 160000 --- a/3rdparty/libgfxinit +++ b/3rdparty/libgfxinit @@ -1 +1 @@ -Subproject commit 17cfc92f402493979783585b6581efbd98c0cf07 +Subproject commit 3c3828add50024e90e57d6fbe0e660d1b66302d9 diff --git a/Documentation/POSTCODES b/Documentation/POSTCODES index 0e67dd173cc..8240375e117 100644 --- a/Documentation/POSTCODES +++ b/Documentation/POSTCODES @@ -5,7 +5,7 @@ coreboot POST Codes This is an (incomplete) list of POST codes emitted by coreboot v4. 0x10 Entry into protected mode -0x01 Entry into 'crt0.s' reset code jumps to here +0x01 Entry into 'entry16.S' reset code jumps to here 0x11 Start copying coreboot to RAM with decompression if compressed 0x12 Copy/decompression finished jumping to RAM 0x80 Entry into coreboot in RAM diff --git a/Documentation/acronyms.md b/Documentation/acronyms.md index 199a7da78cf..a52d206636a 100644 --- a/Documentation/acronyms.md +++ b/Documentation/acronyms.md @@ -204,7 +204,6 @@ Spec](https://uefi.org/specifications) for details, or run the tool * CRLF - Carriage Return, Line Feed - \\r\\n - The standard window EOL (End-of-Line) marker. * crt0 - [**C Run Time 0**](https://en.wikipedia.org/wiki/Crt0) -* crt0s - crt0 Source code * CRT - [**Cathode Ray Tube**](https://en.wikipedia.org/wiki/Cathode-ray_tube) * CSE - Intel: Converged Security Engine * CSI - MIPI: [**Camera Serial diff --git a/Documentation/getting_started/architecture.md b/Documentation/getting_started/architecture.md index 8910d775f79..1f360d04869 100644 --- a/Documentation/getting_started/architecture.md +++ b/Documentation/getting_started/architecture.md @@ -41,7 +41,7 @@ The bootblock loads the romstage or the verstage if verified boot is enabled. ### Cache-As-Ram The *Cache-As-Ram*, also called Non-Eviction mode, or *CAR* allows to use the -CPU cache like regular SRAM. This is particullary useful for high level +CPU cache like regular SRAM. This is particularly useful for high level languages like `C`, which need RAM for heap and stack. The CAR needs to be activated using vendor specific CPU instructions. diff --git a/Documentation/mainboard/index.md b/Documentation/mainboard/index.md index bbfe831fc9f..a90e3f2396e 100644 --- a/Documentation/mainboard/index.md +++ b/Documentation/mainboard/index.md @@ -358,8 +358,10 @@ StarBook Mk V StarBook Mk VI StarBook Mk VII (N200) StarBook Mk VII (165H) -Byte Mk II +StarBook Horizon +Byte Mk II StarFighter Mk I +StarFighter Mk II Building coreboot Flashing devices diff --git a/Documentation/mainboard/lenovo/skylake.md b/Documentation/mainboard/lenovo/skylake.md index 64e075e2cd1..352d91b3efc 100644 --- a/Documentation/mainboard/lenovo/skylake.md +++ b/Documentation/mainboard/lenovo/skylake.md @@ -193,8 +193,6 @@ binaries if only flashing the `bios` region. ## Known Issues -- Alpine Ridge Thunderbolt 3 controller does not work - - Lower (right) USB-C port only works for charging/DP alt mode, not USB/PCIe data - Some Fn+F{1-12} keys aren't handled correctly - Nvidia dGPU is finicky - Needs option ROM @@ -206,6 +204,7 @@ binaries if only flashing the `bios` region. ## Verified Working +- Alpine Ridge Thunderbolt 3 controller - Integrated graphics init with libgfxinit - video output: internal (eDP), miniDP - ACPI support diff --git a/Documentation/mainboard/protectli/fw6.md b/Documentation/mainboard/protectli/fw6.md index df61ee364ba..2f55d8566e4 100644 --- a/Documentation/mainboard/protectli/fw6.md +++ b/Documentation/mainboard/protectli/fw6.md @@ -57,8 +57,13 @@ This chip is located on the bottom side of the case (the radiator side). One has to remove all screws (in order): 4 top cover screws, 4 side cover screws (one side is enough), 4 mainboard screws, 4 CPU screws (under DIMMs). Lift up the mainboard and turn around it. The flash chip is near the SoC on the DIMM -slots side. Use a clip (or solder the wires) to program the chip. Specifically, -it's a Macronix MX25L6406E (3.3V) -[datasheet][MX25L6406E]. +slots side. Desolder and reprogram the chip, or use a clip (or solder the +wires) to program the chip. Specifically, it's a Macronix MX25L6406E (3.3V) +-[datasheet][MX25L6406E], while on some other boards it's a Macronix MX25L6436F. + +At least on some revisions of the motherboard, it's not possible to reprogram +the chip with a clip, while the board is powered off, because there's no diode +to prevent backfeeding power to other components on the board. ## Known issues @@ -99,8 +104,26 @@ the cables or not being populated on the board case. ## Technology -There are 3 variants of FW6 boards: FW6A, FW6B and FW6C. They differ only in -used SoC. +There are 5 variants of FW6 boards: FW6A, FW6B, FW6C, FW6D and FW6E. They differ +in used SoC. + +There are two revisions of the motherboard, hereby called Old Revision +(using IT8772E Super I/O chip), and New Revision (using IT8613E Super I/O chip). +Besides the different Super I/O chip, they also differ in component placement, +and available internal motherboard headers. The Old Revision motherboards are +marked with silkscreen "YL-SK1L6-V1", while the New Revision motherboards are +marked with silkscreen "KBR6LAV20". + +WARNING: The current code base only supports the Old Revision motherboards. + +To compare the two motherboard +revisions one may compare the [New Revision FW6A Datasheet] to the +[Old Revision FW6 Series Hardware Overview]. + +The FW6A/FW6B/FW6C variants are known to have been produced with both +motherboard revisions. + +The FW6D/FW6E variants are only known to exist with the new motherboard revision. - FW6A: @@ -110,10 +133,12 @@ used SoC. +------------------+--------------------------------------------------+ | PCH | Kaby Lake U w/ iHDCP2.2 Base | +------------------+--------------------------------------------------+ -| Super I/O, EC | ITE IT8772E | +| Super I/O, EC | Old revision: ITE IT8772E, New rev.: ITE IT8613E | +------------------+--------------------------------------------------+ | Coprocessor | Intel Management Engine | +------------------+--------------------------------------------------+ +| Support | Currently only the Old Revision is supported | ++------------------+--------------------------------------------------+ ``` - FW6B: @@ -124,10 +149,12 @@ used SoC. +------------------+--------------------------------------------------+ | PCH | Kaby Lake U w/ iHDCP2.2 Premium | +------------------+--------------------------------------------------+ -| Super I/O, EC | ITE IT8772E | +| Super I/O, EC | Old revision: ITE IT8772E, New rev.: ITE IT8613E | +------------------+--------------------------------------------------+ | Coprocessor | Intel Management Engine | +------------------+--------------------------------------------------+ +| Support | Currently only the Old Revision is supported | ++------------------+--------------------------------------------------+ ``` - FW6C: @@ -138,21 +165,58 @@ used SoC. +------------------+--------------------------------------------------+ | PCH | Kaby Lake U w/ iHDCP2.2 Premium | +------------------+--------------------------------------------------+ -| Super I/O, EC | ITE IT8772E | +| Super I/O, EC | Old revision: ITE IT8772E, New rev.: ITE IT8613E | +------------------+--------------------------------------------------+ | Coprocessor | Intel Management Engine | +------------------+--------------------------------------------------+ +| Support | Currently only the Old Revision is supported | ++------------------+--------------------------------------------------+ +``` + +- FW6D: + +```{eval-rst} ++------------------+--------------------------------------------------+ +| CPU | Intel Core i5-8250U | ++------------------+--------------------------------------------------+ +| PCH | Kaby Lake U w/ iHDCP2.2 Premium | ++------------------+--------------------------------------------------+ +| Super I/O, EC | ITE IT8613E | ++------------------+--------------------------------------------------+ +| Coprocessor | Intel Management Engine | ++------------------+--------------------------------------------------+ +| Support | Currently not supported | ++------------------+--------------------------------------------------+ +``` + +- FW6E: + +```{eval-rst} ++------------------+--------------------------------------------------+ +| CPU | Intel Core i7-8550U | ++------------------+--------------------------------------------------+ +| PCH | Kaby Lake U w/ iHDCP2.2 Premium | ++------------------+--------------------------------------------------+ +| Super I/O, EC | ITE IT8613E | ++------------------+--------------------------------------------------+ +| Coprocessor | Intel Management Engine | ++------------------+--------------------------------------------------+ +| Support | Currently not supported | ++------------------+--------------------------------------------------+ ``` ## Other compatible boards As Protectli licenses and uses [Yanling] appliances with no modifications to the actual hardware, any compatible [Yanling] appliances would work. -Specifically, look for hardware with the same CPU and NIC and coreboot -should be able to compile and boot with no modifications required. +Specifically, look for hardware with the same CPU, NIC, and Super I/O chip +and coreboot should be able to compile and boot with no modifications +required. [Protectli FW6]: https://protectli.com/vault-6-port/ [website]: https://protectli.com/kb/coreboot-on-the-vault/ [MX25L6406E]: https://www.macronix.com/Lists/Datasheet/Attachments/7370/MX25L6406E,%203V,%2064Mb,%20v1.9.pdf [flashrom]: https://flashrom.org/ [Yanling]: http://www.ylgkdn.cn/ +[New Revision FW6A Datasheet]: https://kb.protectli.com/wp-content/uploads/sites/9/2025/04/FW6A-Datasheet-20250204.pdf +[Old Revision FW6 Series Hardware Overview]: https://kb.protectli.com/kb/fw6-hardware-overview/ diff --git a/Documentation/mainboard/starlabs/adl_horizon.md b/Documentation/mainboard/starlabs/adl_horizon.md new file mode 100644 index 00000000000..4d81b7f9fc3 --- /dev/null +++ b/Documentation/mainboard/starlabs/adl_horizon.md @@ -0,0 +1,86 @@ +# StarBook Mk V + +## Specs + +- CPU (full processor specs available at ) + - Intel N305 (Alder Lake) +- EC + - ITE IT5570E + - Backlit keyboard, with standard PS/2 keycodes and SCI hotkeys + - Battery + - USB-C PD Charger + - Suspend / resume +- GPU + - Intel® Iris® Xe Graphics + - GOP driver is recommended, VBT is provided + - eDP 13.4-inch 2520x1680 LCD + - HDMI video + - USB-C DisplayPort video +- Memory + - 32GB LPDD% on-board memory +- Networking + - AX210 2230 WiFi / Bluetooth +- Sound + - Realtek ALC269-VB6 + - Internal speakers + - Internal microphone + - Combined headphone / microphone 3.5-mm jack + - HDMI audio + - USB-C DisplayPort audio +- Storage + - M.2 PCIe SSD +- USB + - 1920x1080 CCD camera + - USB 3.1 Gen 2 (left) + - USB 3.1 Gen 2 (right) + - USB 3.1 Gen 2 Type-A (right) + +## Building coreboot + +Please follow the [Star Labs build instructions](common/building.md) to build coreboot, using `config.starlabs_adl_horizon` as config file. + +### Preliminaries + +Prior to building coreboot the following files are required: +* Intel Flash Descriptor file (descriptor.bin) +* Intel Management Engine firmware (me.bin) +* ITE Embedded Controller firmware (ec.bin) + +The files listed below are optional: +- Splash screen image in Windows 3.1 BMP format (Logo.bmp) + +These files exist in the correct location in the StarLabsLtd/blobs repo on GitHub which is used in place of the standard 3rdparty/blobs repo. + +### Build + +The following commands will build a working image: + +```bash +make distclean +make defconfig KBUILD_DEFCONFIG=configs/config.starlabs_adl_horizon_n +make +``` + +## Flashing coreboot + +```{eval-rst} ++---------------------+------------+ +| Type | Value | ++=====================+============+ +| Socketed flash | no | ++---------------------+------------+ +| Vendor | Winbond | ++---------------------+------------+ +| Model | W25Q256.V | ++---------------------+------------+ +| Size | 32 MiB | ++---------------------+------------+ +| Package | WSON-8 | ++---------------------+------------+ +| Internal flashing | yes | ++---------------------+------------+ +| External flashing | yes | ++---------------------+------------+ +``` + +Please see [here](common/flashing.md) for instructions on how to flash with fwupd. diff --git a/Documentation/mainboard/starlabs/byte_adl.md b/Documentation/mainboard/starlabs/byte.md similarity index 86% rename from Documentation/mainboard/starlabs/byte_adl.md rename to Documentation/mainboard/starlabs/byte.md index 7805bb57376..4c9a86cb1a5 100644 --- a/Documentation/mainboard/starlabs/byte_adl.md +++ b/Documentation/mainboard/starlabs/byte.md @@ -34,7 +34,7 @@ ## Building coreboot -Please follow the [Star Labs build instructions](common/building.md) to build coreboot, using `config.starlabs_byte_adl` as config file. +Please follow the [Star Labs build instructions](common/building.md) to build coreboot, using `config.starlabs_byte_adl` (Byte Mk II) or `config.starlabs_byte_twl` (Byte Mk III) as config file. ### Preliminaries @@ -46,6 +46,10 @@ Prior to building coreboot the following files are required: The files listed below are optional: - Splash screen image in Windows 3.1 BMP format (Logo.bmp) +coreboot expects these binaries under +`3rdparty/blobs/mainboard/starlabs/adl//`, where `` +matches `CONFIG_VARIANT_DIR` (default: `y2`). + These files exist in the correct location in the StarLabsLtd/blobs repo on GitHub which is used in place of the standard 3rdparty/blobs repo. ### Build @@ -55,6 +59,8 @@ The following commands will build a working image: ```bash make distclean make defconfig KBUILD_DEFCONFIG=configs/config.starlabs_byte_adl +# or +make defconfig KBUILD_DEFCONFIG=configs/config.starlabs_byte_twl make ``` diff --git a/Documentation/mainboard/starlabs/lite_adl.md b/Documentation/mainboard/starlabs/lite_adl.md index b6e7cb37e7a..f914652b5a6 100644 --- a/Documentation/mainboard/starlabs/lite_adl.md +++ b/Documentation/mainboard/starlabs/lite_adl.md @@ -1,4 +1,4 @@ -# StarBook Mk V +# StarLite Mk V ## Specs @@ -33,7 +33,8 @@ ## Building coreboot -Please follow the [Star Labs build instructions](common/building.md) to build coreboot, using `config.starlabs_starbook_adl` as config file. +Please follow the [Star Labs build instructions](common/building.md) to build +coreboot, using `config.starlabs_lite_adl` as config file. ### Preliminaries @@ -45,6 +46,10 @@ Prior to building coreboot the following files are required: The files listed below are optional: - Splash screen image in Windows 3.1 BMP format (Logo.bmp) +coreboot expects these binaries under +`3rdparty/blobs/mainboard/starlabs/adl//`, where `` +matches `CONFIG_VARIANT_DIR` (default: `i5`). + These files exist in the correct location in the StarLabsLtd/blobs repo on GitHub which is used in place of the standard 3rdparty/blobs repo. ### Build @@ -53,7 +58,7 @@ The following commands will build a working image: ```bash make distclean -make defconfig KBUILD_DEFCONFIG=configs/config.starlabs_byte_adl +make defconfig KBUILD_DEFCONFIG=configs/config.starlabs_lite_adl make ``` diff --git a/Documentation/mainboard/starlabs/starfighter_mtl.md b/Documentation/mainboard/starlabs/starfighter_mtl.md new file mode 100644 index 00000000000..2164b698c59 --- /dev/null +++ b/Documentation/mainboard/starlabs/starfighter_mtl.md @@ -0,0 +1,92 @@ +# StarFighter Mk I + +## Specs + +- CPU (full processor specs available at ) + - Intel 125H (Meteor Lake) + - Intel 285H (Arrow Lake) +- EC + - ITE IT5570E + - Backlit keyboard, with standard PS/2 keycodes and SCI hotkeys + - Battery + - USB-C PD Charger + - Suspend / resume +- GPU + - Intel® Iris® Xe Graphics + - GOP driver is recommended, VBT is provided + - eDP 16-inch 3840x2400 or 2560x1600 LCD + - HDMI video + - USB-C DisplayPort video +- Memory + - 32 or 64GB LPDDR5 on-board memory +- Networking + - AX210 2230 WiFi / Bluetooth +- Sound + - Realtek ALC235 + - Internal speakers + - Removable microphone + - Combined headphone / microphone 3.5-mm jack + - HDMI audio + - USB-C DisplayPort audio +- Storage + - 2 x M.2 PCIe SSD + - RTS5129 MicroSD card reader +- USB + - 1920x1080 removable CCD camera + - 2 x Thunderbolt 4.0 (left) + - USB 3.1 Gen 2 Type-A (left) + - USB 3.1 Gen 2 Type-A (right) + - USB 3.1 Gen 1 Type-A (right) + +## Building coreboot + +Please follow the [Star Labs build instructions](common/building.md) to build +coreboot, using `config.starlabs_starfighter_mtl` as config file. + +### Preliminaries + +Prior to building coreboot the following files are required: +* Intel Flash Descriptor file (descriptor.bin) +* Intel Management Engine firmware (me.bin) +* ITE Embedded Controller firmware (ec.bin) + +The files listed below are optional: +- Splash screen image in Windows 3.1 BMP format (Logo.bmp) + +These files exist in the correct location in the StarLabsLtd/blobs repo on +GitHub which is used in place of the standard 3rdparty/blobs repo. + +### Build + +The following commands will build a working image: + + +```bash +make distclean +make defconfig KBUILD_DEFCONFIG=configs/config.starlabs_starfighter_mtl +make +``` + +## Flashing coreboot + +```{eval-rst} ++---------------------+------------+ +| Type | Value | ++=====================+============+ +| Socketed flash | no | ++---------------------+------------+ +| Vendor | Winbond | ++---------------------+------------+ +| Model | W25Q256.V | ++---------------------+------------+ +| Size | 32 MiB | ++---------------------+------------+ +| Package | SOIC-8 | ++---------------------+------------+ +| Internal flashing | yes | ++---------------------+------------+ +| External flashing | yes | ++---------------------+------------+ +``` + +Please see [here](common/flashing.md) for instructions on how to flash with fwupd. diff --git a/Documentation/payloads.md b/Documentation/payloads.md index 76ff2cd7e72..4c494ab5a97 100644 --- a/Documentation/payloads.md +++ b/Documentation/payloads.md @@ -23,6 +23,12 @@ When chainloaded from GRUB2, the following menuentry could be used: module /vgaroms/seavgabios.bin } +GRUB2 loading seabios from drive via command prompt is also possible: + + multiboot (usb0,msdos1)/seabios/bios.bin.elf + module (usb0,msdos1)/seabios/vgabios.bin name=vgaroms/seavgabios.bin + boot + ## edk2 [edk2](https://github.com/tianocore/tianocore.github.io/wiki/Getting-Started-with-EDK-II) is an open-source modern, feature-rich, diff --git a/Documentation/releases/coreboot-25.12-relnotes.md b/Documentation/releases/coreboot-25.12-relnotes.md index 894d8f9da73..d49c9dbce3b 100644 --- a/Documentation/releases/coreboot-25.12-relnotes.md +++ b/Documentation/releases/coreboot-25.12-relnotes.md @@ -1,9 +1,9 @@ -Upcoming release - coreboot 25.12 +coreboot 25.12 release ======================================================================== The coreboot project is pleased to announce the release of coreboot 25.12, continuing our commitment to advancing open-source firmware -development. This release incorporates over 680 commits from more than +development. This release incorporates over 750 commits from more than 110 contributors, including numerous first-time authors. Key improvements include: @@ -84,6 +84,14 @@ configuration (30b43839448) and VCM type and address settings configuration under modern operating systems, particularly Windows, as proper SSDB and PLD configuration is required for full functionality. +DSM (Device Specific Method) generation has been refactored into +per-UUID functions (ea099e8b8c9, c8f89e00e4c), with new support for +CVF (Computer Vision Framework) DSM and I2C V2 DSM functions +(a64b93562d0, 1532eb60ee7). The driver now supports ACPI device type +selection (ae0d2324021) and ROM type/address configuration for camera +sensors (6459a2007a5), improving compatibility with various camera +implementations. + ### soc/qualcomm/x1p42100: Expanded platform support and debug capabilities @@ -103,6 +111,15 @@ layout refinements (c3afc13a0a5) optimize BL31 region placement and TZ Application memory alignment, improving overall platform memory utilization and security boundaries. +The platform now includes CMD-DB (Command Database) driver support +(01bc527afa2), enabling resource address and configuration data +lookup for hardware accelerators. The CMD-DB region is properly mapped +as non-cacheable in MMU (a4cc1784860, 2277edff88b), ensuring correct +access patterns for shared resource management. ARM64 architecture +improvements include distinct PRERAM and POSTRAM stack regions +(641f7ac677b, 1b599a88449), with PRERAM stack relocated to BSRAM +memory (4d53aa77042) for improved memory utilization. + ### soc/intel: LPCAMM (Low Power Compression Attached Memory Module) support @@ -135,6 +152,23 @@ Measurement) initialization support has been added (33fc33c132c), improving security and system reliability. +### include/acpi: Comprehensive APEI (Advanced Platform Error Interface) infrastructure + +Extensive APEI struct definitions have been added to support advanced +error reporting capabilities (679ea61d4de, b689671e79d, 7a41dc416be, +5251284e392). The implementation includes structs for Machine Check +Exception (MCE), Non-Maskable Interrupt (NMI), and PCIe AER (Advanced +Error Reporting) error sources, providing a foundation for BERT (Boot +Error Record Table), HEST (Hardware Error Source Table), and EINJ +(Error Injection Table) implementations. + +These additions enable platforms to properly report hardware errors +to operating systems, supporting firmware-first error handling models +and improving system reliability diagnostics. The struct definitions +follow ACPI specification standards and include proper validation +(847d91b82e5, b70309350f8). + + ### commonlib: Code consolidation and endian handling improvements The `` header implementations from both coreboot and @@ -191,8 +225,19 @@ Additional coreboot changes * Intel FSP UPD header typedef additions (2ce4e094690) * Azalia verb table implementation rework for improved maintainability (31fc5b06a6b) across multiple platforms +* Azalia driver timing fixes including proper 521us delay after RESET# + de-assertion (ecf202b8e4a) and link-reset improvements + (6e074550a5c, 152914272c1) * Intel touch driver enhancements for new devices with improved I2C speed handling (f1708cf21a2, fce489e9e5c, 1af54d9784b) +* Generic graphics driver support extended to non-VGA devices + (0f1ae4ae5f1), expanding compatibility beyond traditional VGA + displays +* MediaTek ARMv9 MTE (Memory Tagging Extension) tag memory support + added to bootmem (3d5135fdd07, 9203cc827f9), enabling proper memory + tagging for security-enhanced platforms +* Parallel charging infrastructure and support for Google Bluey platforms + (de87ea0efad, 896984e800a), enabling faster charging capabilities * Qualcomm USB Type-C support with PHY configuration and repeater support (8ffa58723a2, 45cedbb9922, 155041ad4cf, b18dfde22a7) * SoundWire drivers for Cirrus Logic CS35L56 and CS42L43 codecs @@ -264,15 +309,15 @@ Platform Updates Statistics from the 25.09 to the 25.12 release -------------------------------------------- -* Total Commits: 687 -* Average Commits per day: 8.79 -* Total lines added: 57757 -* Average lines added per commit: 84.07 -* Number of patches adding more than 100 lines: 69 -* Average lines added per small commit: 42.00 -* Total lines removed: 9190 -* Average lines removed per commit: 13.38 -* Total difference between added and removed: 48567 +* Total Commits: 757 +* Average Commits per day: 8.94 +* Total lines added: 62219 +* Average lines added per commit: 82.19 +* Number of patches adding more than 100 lines: 77 +* Average lines added per small commit: 42.02 +* Total lines removed: 9669 +* Average lines removed per commit: 12.77 +* Total difference between added and removed: 52550 * Total authors: 106 * New authors: 21 diff --git a/Documentation/soc/intel/code_development_model/code_development_model.md b/Documentation/soc/intel/code_development_model/code_development_model.md index ad27bd498a5..11674e8bdc1 100644 --- a/Documentation/soc/intel/code_development_model/code_development_model.md +++ b/Documentation/soc/intel/code_development_model/code_development_model.md @@ -87,9 +87,13 @@ Code design after common code in coreboot will look as follows: [coreboot_common_code_design]: coreboot_common_code_design.png -There will be still some duplicated files left in each SOC folder and we may -copy across a SOC as a base but these files are subject to change as -development continues. +There will be still some duplicated files left in each SOC folder and we +may copy across a SOC as a base but these files are subject to change as +development continues. Some of those files, presenting strong similarities +from generation to generation, can be consolidated into the common feature +directory to reduce code duplication and improve +maintenance. Platform-specific differences are handled through +configuration options or platform-specific macros. ## Benefits diff --git a/Documentation/soc/intel/index.md b/Documentation/soc/intel/index.md index ef032f5ecec..96a23a55721 100644 --- a/Documentation/soc/intel/index.md +++ b/Documentation/soc/intel/index.md @@ -17,4 +17,5 @@ Apollolake CSE FW Update Xeon Scalable processor Skylake/Kaby Lake BootGuard bypass +Intel Top Swap based A/B redundancy ``` diff --git a/Documentation/soc/intel/redundancy.md b/Documentation/soc/intel/redundancy.md new file mode 100644 index 00000000000..bd3a92aaa53 --- /dev/null +++ b/Documentation/soc/intel/redundancy.md @@ -0,0 +1,174 @@ +# Intel Top Swap based A and B redundancy + +This document describes a simple firmware A and B redundancy scheme based on +Intel PCH Top Swap. The scheme maintains two firmware slots and uses the Top +Swap control bit to choose which bootblock runs on boot. Each bootblock then +continues booting from a matching CBFS region, so switching the Top Swap state +switches the active slot. + +The Intel Top Swap feature allows the PCH to take two physically topmost chunks +of the BIOS flash chip, and decide in which order to map them - effectively +allowing to swap the two chunks, and deciding which of them lands at the reset +vector. + +For background on the hardware mechanism, consult the Intel documentation +for your PCH and platform and search for sections named similarly to "Top +Swap", "Top Swap Block Size (TSBS)", or "Boot Block Update Scheme". The exact +document title and section naming varies between generations. The Alder Lake +implementation for example has been developed basing mainly on ADL-P EDS Vol +1&2, sections: + +* `3.2.1 Boot Block Update Scheme`, +* `9.70 PCH Descriptor Record 69 (Flash Descriptor Records)`, +* `31.3.2 Backed Up Control (BUC)`, +* `2.1.17 BIOS Control (ESPI_BC)` + +## Flash layout and CBFS regions + +The implementation assumes four FMAP regions that are CBFS formatted and that +use the following names. + +The bootblocks live in `BOOTBLOCK` and `TOPSWAP`. Each of these is a relatively +small CBFS region that contains a bootblock image and any additional files that +must reside next to it for early boot on a given platform. These regions must +exist in the board's `.fmd` file and must be sized with headroom for growth +- keeping in mind the FIT table and Boot Guard ACM's must reside in the same +region as the bootblock. + +The main firmware CBFS regions are `COREBOOT` and `COREBOOT_TS`. `COREBOOT` is +typically the base slot and is often placed under write protection, along with +`BOOTBLOCK`. `COREBOOT_TS` is the alternate slot and is typically left writable +so it can be replaced by an update mechanism, along with `TOPSWAP`. + +The `BOOTBLOCK` and `TOPSWAP` regions are expected to be placed in the +flash area covered by the Top Swap configuration. The sizes of the regions +must match and be equal to the corresponding field in the IFD. coreboot +can adjust the The Top Swap size (also called Top Swap Block Size in +Intel's documentation) field in the descriptor during the build. This +is controlled by `CONFIG_INTEL_IFD_SET_TOP_SWAP_BOOTBLOCK_SIZE` and uses +`CONFIG_INTEL_TOP_SWAP_BOOTBLOCK_SIZE` as the requested size. + +## Kconfig options + +The option `CONFIG_INTEL_ADD_TOP_SWAP_BOOTBLOCK` creates two copies of the +bootblock. + +The option `CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS` changes where the bootblocks +are stored. When it is disabled, both are stored in the primary CBFS region as +on existing platforms. When it is enabled, they are placed in the `BOOTBLOCK` +`TOPSWAP` FMAP regions. It also places copies of the following stages and +required files from the `COREBOOT` region in the `COREBOOT_TS` region. + +If CBFS verification is enabled, the image build checks verification status for +all main CBFS regions that are part of the redundancy configuration, not only +for `COREBOOT`. + +The option `CONFIG_INTEL_TOP_SWAP_OPTION_CONTROL` enables runtime control of the +Top Swap control bit based on a CMOS option. In tree, this option is constrained +to specific Intel SoCs. For a board to use it, the SoC bootblock must apply the +setting early enough for writes to the Top Swap control bit to take effect. + +To reduce per board configuration burden, `CONFIG_TOP_SWAP_REDUNDANCY` exists +as a convenience option that selects the relevant pieces for Top Swap based +redundancy. Even with this convenience option enabled, a board still must +provide an appropriate `.fmd` layout and a `cmos.layout` entry as described +below. + +Boards that use Top Swap based redundancy must enable CMOS option support +and ensure the option backend can read options at boot time. The symbol +`MAINBOARD_NEEDS_CMOS_OPTIONS` exists to indicate this dependency. Please +note that not every SoC supports this functionality. + +## CMOS option and when it is applied + +Runtime Top Swap selection is controlled by a CMOS option named +`attempt_slot_b`. The name is defined as `TOP_SWAP_ENABLE_CMOS_OPTION` in +`src/soc/intel/common/block/include/intelblocks/rtc.h`. A board enabling +`CONFIG_INTEL_TOP_SWAP_OPTION_CONTROL` must provide a CMOS entry with this exact +name in its `cmos.layout` file. + +The function `sync_rtc_buc_top_swap()` in `src/soc/intel/common/block/rtc/rtc.c` +implements the synchronization logic. It reads the CMOS option via +`get_uint_option()`, reads the current Top Swap state from the RTC BUC register, +compares the two, and if they differ it programs the new state and resets the +platform. The reset is intentional and ensures the new Top Swap state is in +effect from the beginning of the subsequent boot. + +The SoC bootblock must call `sync_rtc_buc_top_swap()` early in +`bootblock_soc_init()` when `CONFIG_INTEL_TOP_SWAP_OPTION_CONTROL` is enabled. +This must happen before the platform locks down the relevant interfaces such +that Top Swap state changes no longer take effect. + +Because the CMOS option is applied in bootblock, a mismatch between the requested +slot and the current Top Swap state causes a very early reset. The next boot +then starts directly from the selected slot. + +## CBFS region selection + +The choice of the main CBFS region is made in `cbfs_get_boot_device()` in +`src/lib/cbfs.c`. Instead of always locating `COREBOOT`, the code calls +`cbfs_fmap_region_hint()` to obtain the FMAP region name and then locates that +region. + +The default `cbfs_fmap_region_hint()` implementation is a weak symbol that +returns `COREBOOT`, so platforms that do not override it retain the existing +behavior. + +Intel Top Swap platforms provide a strong definition of +`cbfs_fmap_region_hint()` in `src/soc/intel/common/block/rtc/rtc.c`. When +`CONFIG_INTEL_TOP_SWAP_OPTION_CONTROL` is enabled and the Top Swap control +bit is set, it returns `COREBOOT_TS`. Otherwise it returns `COREBOOT`. +`cbfs_get_boot_device()` logs the selected region and stops with an error if the +region cannot be found in FMAP. + +This is deliberately based on the actual hardware Top Swap state rather than on +reading CMOS again. At the point where `cbfs_fmap_region_hint()` is used, the +option table is not reliably available, because the `cmos_layout.bin` backing +the option table is itself stored in CBFS. + +For the override to apply in a given stage, the RTC block code must be linked +into that stage. The common RTC block is built into multiple stages and is +also built into postcar to ensure the hint function is available when CBFS is +accessed there. + +## Boot flow summary + +A typical update and rollback sequence is as follows. + +The platform starts in slot A with Top Swap disabled. The hardware boots from +the `BOOTBLOCK` and coreboot continues from the `COREBOOT` CBFS region. + +An update writes into the `TOPSWAP` and `COREBOOT_TS` regions, then sets the +`attempt_slot_b` CMOS option. + +On the next boot, `sync_rtc_buc_top_swap()` observes that the CMOS request +differs from the current hardware Top Swap state, programs the new Top Swap +state, and resets the platform. + +After the reset, the hardware starts from the bootblock corresponding to +the new Top Swap state. When coreboot later initializes its boot device, +`cbfs_fmap_region_hint()` sees the Top Swap state and selects `COREBOOT_TS`, so +the remainder of the boot uses the updated slot. + +Clearing CMOS or resetting `attempt_slot_b` triggers the same sequence in the +opposite direction, returning the platform to `COREBOOT` without requiring +external flashing. + +## Troubleshooting notes + +If the platform does not switch slots as expected, confirm that the +`attempt_slot_b` entry exists in `cmos.layout` and that the option table backend +is in use so `get_uint_option()` can read it in bootblock. + +If the platform resets but still boots from `COREBOOT`, confirm that the RTC +block implementation providing `cbfs_fmap_region_hint()` is linked into the +stage that performs CBFS initialization on your platform. + +If the build fails to boot after enabling separate regions, confirm that the +`.fmd` file defines `BOOTBLOCK`, `TOPSWAP`, `COREBOOT`, and `COREBOOT_TS` as +CBFS regions and that the platform Top Swap configuration matches the reserved +bootblock and Top Swap region placement and sizing. + +Serial logs should show the CMOS request and the RTC BUC control bit values +during bootblock, followed by a log line indicating which CBFS region is being +used. diff --git a/MAINTAINERS b/MAINTAINERS index 083f91e9e63..bd26cac7f4b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -435,6 +435,11 @@ M: Vanessa Eusebio S: Maintained F: src/mainboard/intel/harcuvar/ +INTEL PANTHERLAKE_CRB MAINBOARD +M: Alicja Michalska +S: Supported +F: src/mainboard/intel/pantherlake_crb/ + INVENTEC MAINBOARDS @@ -927,12 +932,14 @@ M: Pranava Y N M: Jayvik Desai M: Avi Uday M: Dinesh Gehlot +M: Alicja Michalska S: Maintained F: src/soc/intel/pantherlake/ INTEL TIGERLAKE SOC M: Subrata Banik M: Nick Vaccaro +M: Alicja Michalska S: Maintained F: src/soc/intel/tigerlake/ @@ -1033,6 +1040,11 @@ M: Martin Roth S: Supported F: util/abuild/ +AUTOPORT +M: Nicholas Chin +S: Maintained +F: util/autoport/ + BOARD STATUS F: util/board_status/ diff --git a/Makefile.mk b/Makefile.mk index 75787b32d49..5fccb4a52db 100644 --- a/Makefile.mk +++ b/Makefile.mk @@ -455,6 +455,8 @@ cbfs-files-handler= \ CBFS_COMPRESS_FLAG:=none ifeq ($(CONFIG_COMPRESS_RAMSTAGE_LZMA),y) CBFS_COMPRESS_FLAG:=LZMA +else ifeq ($(CONFIG_COMPRESS_RAMSTAGE_ZSTD),y) +CBFS_COMPRESS_FLAG:=ZSTD endif ifeq ($(CONFIG_COMPRESS_RAMSTAGE_LZ4),y) CBFS_COMPRESS_FLAG:=LZ4 @@ -463,9 +465,10 @@ endif CBFS_PAYLOAD_COMPRESS_FLAG:=none ifeq ($(CONFIG_COMPRESSED_PAYLOAD_LZMA),y) CBFS_PAYLOAD_COMPRESS_FLAG:=LZMA -endif -ifeq ($(CONFIG_COMPRESSED_PAYLOAD_LZ4),y) +else ifeq ($(CONFIG_COMPRESSED_PAYLOAD_LZ4),y) CBFS_PAYLOAD_COMPRESS_FLAG:=LZ4 +else ifeq ($(CONFIG_COMPRESSED_PAYLOAD_ZSTD),y) +CBFS_PAYLOAD_COMPRESS_FLAG:=ZSTD endif CBFS_SECONDARY_PAYLOAD_COMPRESS_FLAG:=none @@ -611,12 +614,7 @@ LDFLAGS_common += -nostdlib LDFLAGS_common += --nmagic LDFLAGS_common += -static LDFLAGS_common += -z noexecstack - -# Workaround for RISC-V linker bug, merge back into above line when fixed. -# https://sourceware.org/bugzilla/show_bug.cgi?id=27180 -ifneq ($(CONFIG_ARCH_RISCV),y) LDFLAGS_common += --emit-relocs -endif ifeq ($(CONFIG_WARNINGS_ARE_ERRORS),y) CFLAGS_common += -Werror @@ -824,13 +822,6 @@ clean-abuild: ####################################################################### # Development utilities -printcrt0s: - @echo crt0s=$(crt0s) - @echo ldscripts=$(ldscripts) - -update: - dongle.py -c /dev/term/1 $(obj)/coreboot.rom EOF - check-style: grep "^# DESCR:" util/lint/check-style | sed "s,.*DESCR: *,," echo "========" @@ -971,22 +962,26 @@ $(objcbfs)/%.elf: $(objcbfs)/%.debug $(objcbfs)/%.map # 4) replace all '*' characters with spaces extract_nth=$(subst *,$(spc),$(patsubst -%-,%,$(word $(1), $(subst |,- -,-$(2)-)))) -# regions-for-file - Returns a cbfstool regions parameter -# $(call regions-for-file,$(filename)) -# returns "REGION1,REGION2,..." -# -# This is the default implementation. When using a boot strategy employing -# multiple CBFSes in fmap regions, override it. -regions-for-file ?= $(if $(value regions-for-file-$(1)), $(regions-for-file-$(1)), COREBOOT) +CBFS_REGIONS := COREBOOT ifeq ($(CONFIG_INTEL_ADD_TOP_SWAP_BOOTBLOCK),y) ifneq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) TS_OPTIONS := -j $(CONFIG_INTEL_TOP_SWAP_BOOTBLOCK_SIZE) else -regions-for-file = $(if $(value regions-for-file-$(1)), $(regions-for-file-$(1)), COREBOOT,COREBOOT_TS) +CBFS_REGIONS := COREBOOT,COREBOOT_TS endif endif +CBFS_REGION_COUNT := $(words $(subst $(comma),$(spc),$(CBFS_REGIONS))) + +# regions-for-file - Returns a cbfstool regions parameter +# $(call regions-for-file,$(filename)) +# returns "REGION1,REGION2,..." +# +# This is the default implementation. When using a boot strategy employing +# multiple CBFSes in fmap regions, override it. +regions-for-file ?= $(if $(value regions-for-file-$(1)), $(regions-for-file-$(1)), $(CBFS_REGIONS)) + ifeq ($(CONFIG_CBFS_AUTOGEN_ATTRIBUTES),y) cbfs-autogen-attributes=-g endif @@ -1090,6 +1085,8 @@ prebuild-files = $(foreach region,$(all-regions), \ # If no FMD file (Flashmap) is supplied by mainboard, fall back to a default ifeq ($(CONFIG_FMDFILE),) +FMAP_FLASH_SIZE := $(CONFIG_ROM_SIZE) + ifeq ($(CONFIG_ARCH_X86),y) DEFAULT_FLASHMAP:=$(top)/util/cbfstool/default-x86.fmd @@ -1103,8 +1100,6 @@ $(DEFAULT_FLASHMAP): $(call strip_quotes,$(CONFIG_IFD_BIN_PATH)) $(IFDTOOL) endif # ifeq($(CONFIG_HAVE_IFD_BIN),y) endif # ifneq($(CONFIG_IFD_CHIPSET),) -# entire flash -FMAP_ROM_SIZE := $(CONFIG_ROM_SIZE) # entire "BIOS" region (everything directly of concern to the host system) FMAP_BIOS_BASE := $(call int-align, $(call int-subtract, $(CONFIG_ROM_SIZE) $(CONFIG_CBFS_SIZE)), 0x10000) FMAP_BIOS_SIZE := $(call int-align-down, $(shell echo $(CONFIG_CBFS_SIZE) | tr A-F a-f), 0x10000) @@ -1191,7 +1186,6 @@ else # ifeq ($(CONFIG_ARCH_X86),y) DEFAULT_FLASHMAP:=$(top)/util/cbfstool/default.fmd # entire flash -FMAP_ROM_SIZE := $(CONFIG_ROM_SIZE) # entire "BIOS" region (everything directly of concern to the host system) FMAP_BIOS_BASE := 0 FMAP_BIOS_SIZE := $(CONFIG_CBFS_SIZE) @@ -1237,7 +1231,7 @@ FMAP_CBFS_SIZE := $(call int-subtract,$(FMAP_BIOS_SIZE) $(FMAP_CBFS_BASE)) endif # ifeq ($(CONFIG_ARCH_X86),y) $(obj)/fmap.fmd: $(top)/Makefile.mk $(DEFAULT_FLASHMAP) $(obj)/config.h - sed -e "s,##ROM_SIZE##,$(call _tohex,$(FMAP_ROM_SIZE))," \ + sed -e "s,##FLASH_SIZE##,$(call _tohex,$(FMAP_FLASH_SIZE))," \ -e "s,##BIOS_BASE##,$(call _tohex,$(FMAP_BIOS_BASE))," \ -e "s,##BIOS_SIZE##,$(call _tohex,$(FMAP_BIOS_SIZE))," \ -e "s,##FMAP_BASE##,$(call _tohex,$(FMAP_FMAP_BASE))," \ @@ -1291,9 +1285,16 @@ $(shell rm -f $(obj)/coreboot.pre) ifneq ($(CONFIG_UPDATE_IMAGE),y) $(obj)/coreboot.pre: $$(prebuilt-files) $(CBFSTOOL) $(obj)/fmap.fmap $(obj)/fmap.desc $(objcbfs)/bootblock.bin $(CBFSTOOL) $@.tmp create -M $(obj)/fmap.fmap -r $(shell cat $(obj)/fmap.desc) +# The bootblock must exist in the image before we call `prebuild-files`, +# otherwise their hashes won't be added into the CBFS header and CBFS +# verification will fail. printf " BOOTBLOCK\n" ifneq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) $(call add_bootblock,$@.tmp,$(objcbfs)/bootblock.bin) +else + @printf " PREP place bootblocks in $(BB_FIT_REGION) and $(TS_FIT_REGION)\n" + @printf " $(BB_FIT_REGION),$(TS_FIT_REGION)\n" + $(CBFSTOOL) $@.tmp add -r $(BB_FIT_REGION),$(TS_FIT_REGION) $(bootblock_add_params) endif # ifneq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) $(prebuild-files) true mv $@.tmp $@ @@ -1324,15 +1325,6 @@ add_intermediate = \ $(1): $(obj)/coreboot.pre $(2) | $(INTERMEDIATE) \ $(eval INTERMEDIATE+=$(1)) $(eval PHONY+=$(1)) -ifeq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) -$(call add_intermediate, prep_bb_regions, $(CBFSTOOL)) - @printf " PREP place bootblocks in BOOTBLOCK and TOPSWAP\n" - @printf " BOOTBLOCK\n" - $(CBFSTOOL) $< add -r $(BB_FIT_REGION) $(bootblock_add_params) - @printf " TOPSWAP\n" - $(CBFSTOOL) $< add -r $(TS_FIT_REGION) $(bootblock_add_params) -endif - $(obj)/coreboot.rom: $(obj)/coreboot.pre $(CBFSTOOL) $(IFITTOOL) $$(INTERMEDIATE) @printf " CBFS $(subst $(obj)/,,$(@))\n" # The full ROM may be larger than the CBFS part, so create an empty @@ -1353,8 +1345,8 @@ endif # CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE $(CBFSTOOL) $@ layout @printf " CBFSPRINT $(subst $(obj)/,,$(@))\n\n" ifeq ($(CONFIG_CBFS_VERIFICATION),y) - line=$$($(CBFSTOOL) $@ print -kv 2>/dev/null | grep -F '[CBFS VERIFICATION (COREBOOT)]') ;\ - if ! printf "$$line" | grep -q 'fully valid'; then \ + line=$$($(CBFSTOOL) $@ print -kv -r $(CBFS_REGIONS) 2>/dev/null | grep -F '[CBFS VERIFICATION') ;\ + if [ "$$(printf "$$line" | grep -c 'fully valid')" -ne $(CBFS_REGION_COUNT) ]; then \ echo "CBFS verification error: $$line" ;\ exit 1 ;\ fi @@ -1455,11 +1447,6 @@ bootsplash$(BOOTSPLASH_SUFFIX)-file := $(call strip_quotes,$(CONFIG_BOOTSPLASH_F bootsplash$(BOOTSPLASH_SUFFIX)-type := bootsplash endif -# Ensure that no payload segment overlaps with memory regions used by ramstage -# (not for x86 since it can relocate itself in that case) -ifneq ($(CONFIG_ARCH_X86),y) -check-ramstage-overlap-regions := ramstage -check-ramstage-overlap-files := ifneq ($(CONFIG_PAYLOAD_NONE),y) check-ramstage-overlap-files += $(CONFIG_CBFS_PREFIX)/payload endif @@ -1472,6 +1459,15 @@ ramstage-symbol-addr-cmd = $(OBJDUMP_ramstage) -t $(objcbfs)/ramstage.elf | \ sed -n '/ $(1)$$/s/^\([0-9a-fA-F]*\) .*/0x\1/p' | \ uniq +# Ensures that no segments from files in check-ramstage-overlap-files overlap memory regions +# used by ramstage. By default the segments of the payload are checked against the ramstage +# segments, but there may be other executables in RAM (e.g. BL31, OPENSBI). So Architecture +# Makefiles may add relevant executables to `check-ramstage-overlap-files`. Architecture +# Makefiles need to initialize `check-ramstage-overlap-regions` to use this check. +# For example: +# Common regions to add are `ramstage`, `stack` or `postram_cbfs_cache`. Which means that the +# ramstage segments `ramstage`, `stack`, `postram_cbfs_cache` are checked to make sure they +# don't overlap with the segments of check-ramstage-overlap-files (e.g. payload). $(call add_intermediate, check-ramstage-overlaps) programs=$$($(foreach file,$(check-ramstage-overlap-files), \ $(call cbfs-get-segments-cmd,$(file)) ; )) ; \ @@ -1497,5 +1493,3 @@ $(call add_intermediate, check-ramstage-overlaps) done ; \ pstart= ; pend= ; \ done - -endif diff --git a/configs/config.emulation_qemu_aarch64_zstd b/configs/config.emulation_qemu_aarch64_zstd new file mode 100644 index 00000000000..c1cf7c02c5b --- /dev/null +++ b/configs/config.emulation_qemu_aarch64_zstd @@ -0,0 +1,3 @@ +CONFIG_VENDOR_EMULATION=y +CONFIG_BOARD_EMULATION_QEMU_AARCH64=y +CONFIG_COMPRESS_RAMSTAGE_ZSTD=y diff --git a/configs/config.emulation_qemu_zstd b/configs/config.emulation_qemu_zstd new file mode 100644 index 00000000000..4b0a6feea99 --- /dev/null +++ b/configs/config.emulation_qemu_zstd @@ -0,0 +1,3 @@ +CONFIG_VENDOR_EMULATION=y +CONFIG_BOARD_EMULATION_QEMU_X86_Q35=y +CONFIG_COMPRESS_RAMSTAGE_ZSTD=y diff --git a/configs/config.qotom_qdnv01 b/configs/config.qotom_qdnv01 new file mode 100644 index 00000000000..1042ec6de44 --- /dev/null +++ b/configs/config.qotom_qdnv01 @@ -0,0 +1,5 @@ +CONFIG_VENDOR_QOTOM=y +CONFIG_MAINBOARD_PART_NUMBER="Qotom QDNV01" +CONFIG_ENABLE_HSUART=y +CONFIG_USE_DENVERTON_NS_FSP_CAR=y +# CONFIG_SMMSTORE is not set diff --git a/configs/config.starlabs_starbook_adl_option_table b/configs/config.starlabs_starbook_adl_option_table deleted file mode 100644 index 56211266a15..00000000000 --- a/configs/config.starlabs_starbook_adl_option_table +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG_VENDOR_STARLABS=y -CONFIG_BOARD_STARLABS_STARBOOK_ADL=y -CONFIG_MAINBOARD_SERIAL_NUMBER="B6I0000" -CONFIG_USE_OPTION_TABLE=y -CONFIG_LOCALVERSION="8.42" -CONFIG_MAINBOARD_USE_LIBGFXINIT=n -CONFIG_SMMSTORE=y -CONFIG_SMMSTORE_V2=y diff --git a/payloads/Kconfig b/payloads/Kconfig index be902a1b4bd..e30b1ec76c5 100644 --- a/payloads/Kconfig +++ b/payloads/Kconfig @@ -86,6 +86,12 @@ config COMPRESSED_PAYLOAD_LZMA In order to reduce the size payloads take up in the ROM chip coreboot can compress them using the LZMA algorithm. +config COMPRESSED_PAYLOAD_ZSTD + bool "Use ZSTD compression for payloads" + help + In order to reduce the size payloads take up in the ROM chip + coreboot can compress them using the ZSTD algorithm. + config COMPRESSED_PAYLOAD_LZ4 bool "Use LZ4 compression for payloads" help diff --git a/payloads/external/Makefile.mk b/payloads/external/Makefile.mk index 1a494486dbf..429c0b2a85c 100644 --- a/payloads/external/Makefile.mk +++ b/payloads/external/Makefile.mk @@ -152,7 +152,8 @@ payloads/external/depthcharge/depthcharge/build/depthcharge.elf depthcharge: $(D DEPTHCHARGE_STABLE=$(CONFIG_DEPTHCHARGE_STABLE) \ DEPTHCHARGE_REVISION=$(CONFIG_DEPTHCHARGE_REVISION) \ DEPTHCHARGE_REVISION_ID=$(CONFIG_DEPTHCHARGE_REVISION_ID) \ - OVERRIDE_DEFCONFIG=$(CONFIG_LP_DEFCONFIG_OVERRIDE) + OVERRIDE_DEFCONFIG=$(CONFIG_LP_DEFCONFIG_OVERRIDE) \ + OVERRIDE_DEFCONFIG_64=$(CONFIG_LP_DEFCONFIG_OVERRIDE_X64) # edk2 @@ -160,6 +161,21 @@ ifeq ($(CONFIG_EDK2_ENABLE_IPXE),y) IPXE_EFI := payloads/external/iPXE/ipxe/ipxe.rom endif +ifeq ($(CONFIG_PAYLOAD_EDK2)$(CONFIG_SMMSTORE_V2)$(CONFIG_DRIVERS_OPTION_CFR),yyy) +ifeq ($(CONFIG_DRIVERS_EFI_VARIABLE_STORE),) +show_notices:: warn_no_option_cfr_enabled + +PHONY+=warn_no_option_cfr_enabled +warn_no_option_cfr_enabled: + printf "\n\t** WARNING **\n" + printf "edk2 has been configured to store non-volatile variables in the 'SMMSTORE'\n" + printf "flash area, and to show coreboot's setup option menu, but coreboot is not\n" + printf "configured to use variables stored by edk2 in the 'SMMSTORE' flash area.\n" + printf "coreboot-related changes made in edk2's setup menu will have no effect.\n" + printf "To fix this, select CONFIG_DRIVERS_EFI_VARIABLE_STORE.\n\n" +endif +endif + $(obj)/UEFIPAYLOAD.fd: $(DOTCONFIG) $(IPXE_EFI) $(MAKE) -C payloads/external/edk2 UefiPayloadPkg \ HOSTCC="$(HOSTCC)" \ diff --git a/payloads/external/depthcharge/Kconfig b/payloads/external/depthcharge/Kconfig index 86b20abcaf8..7a9c7d75967 100644 --- a/payloads/external/depthcharge/Kconfig +++ b/payloads/external/depthcharge/Kconfig @@ -62,4 +62,15 @@ config LP_DEFCONFIG_OVERRIDE instead. This is can be a convenience for development purposes, or if the defaults in defconfig are sufficient for your system. +config LP_DEFCONFIG_OVERRIDE_X64 + bool "Use default 64-bit libpayload config" + depends on !LP_DEFCONFIG_OVERRIDE + help + The Depthcharge makefile looks for a file config. in the + libpayload/configs directory. Say Y here to use the file defconfig + for 64-bit format instead. This can be convenient for development for + a new board, or if the defaults in 64-bit defconfig file (i.e. + defconfig_64) are sufficient for your system without creating + board.[name] file. + endif diff --git a/payloads/external/depthcharge/Makefile b/payloads/external/depthcharge/Makefile index af303da872f..2328d6d2c65 100644 --- a/payloads/external/depthcharge/Makefile +++ b/payloads/external/depthcharge/Makefile @@ -30,6 +30,9 @@ BOARD:=$(notdir $(CONFIG_MAINBOARD_DIR)) ifeq ($(OVERRIDE_DEFCONFIG),y) libpayload_config=$(libpayload_dir)/configs/defconfig DEPTHCHARGE_LIBPAYLOAD_MSG="Depthcharge: Using default defconfig for libpayload" +else ifeq ($(OVERRIDE_DEFCONFIG_64),y) +libpayload_config=$(libpayload_dir)/configs/defconfig_64 +DEPTHCHARGE_LIBPAYLOAD_MSG="Depthcharge: Using default defconfig for 64-bit libpayload" else libpayload_config=$(libpayload_dir)/configs/config.$(BOARD) DEPTHCHARGE_LIBPAYLOAD_MSG="Depthcharge: Using $(libpayload_dir)/configs/config.$(BOARD)" diff --git a/payloads/external/edk2/Kconfig b/payloads/external/edk2/Kconfig index 7bfd486f7aa..2f4cab5efea 100644 --- a/payloads/external/edk2/Kconfig +++ b/payloads/external/edk2/Kconfig @@ -86,7 +86,7 @@ config EDK2_REPOSITORY config EDK2_TAG_OR_REV string "Insert a commit's SHA-1 or a branch name" - default "origin/uefipayload_2508" if EDK2_REPO_MRCHROMEBOX + default "origin/uefipayload_2511" if EDK2_REPO_MRCHROMEBOX default "origin/universalpayload" if EDK2_UNIVERSAL_PAYLOAD default "origin/master" if EDK2_REPO_OFFICIAL default "" if EDK2_REPO_CUSTOM @@ -128,8 +128,9 @@ choice config EDK2_DEBUG bool "Generate edk2 debug build" + select CONSOLE_SERIAL help - Generate a debug build. + Generate a debug build. Select this if you want to enable serial debugging output. config EDK2_RELEASE bool "Generate edk2 release build" @@ -190,11 +191,12 @@ config EDK2_BOOT_TIMEOUT config EDK2_CBMEM_LOGGING bool "Enable edk2 logging to CBMEM" + depends on EDK2_RELEASE help Select this option if you want to enable edk2 logging to CBMEM. - You may want to increase the default cbmem buffer size when selecting - this option, especially if using a debug (vs release) build. - Selecting this option will increase the payload size in CBFS by 0x10000. + You will want to increase the default cbmem buffer size when selecting + this option, as it will increase logging output significantly. + Selecting this option will increase the payload size in CBFS by ~1MB. config EDK2_CPU_TIMER_LIB bool @@ -262,12 +264,14 @@ config EDK2_SD_MMC_TIMEOUT Most only require 10ms, but certain readers can take 1s. config EDK2_SERIAL_SUPPORT - bool "Support serial output" + bool "Enable serial console" default y if EDK2_DEBUG default n + depends on !EDK2_CBMEM_LOGGING + select CONSOLE_SERIAL help - Enable serial port output in edk2. Serial output limits the performance of edk2's - FrontPage. + Enable serial consule support in edk2. Serial output limits the performance of edk2's + FrontPage. This option does not enable debugging output over serial. For that, use EDK2_DEBUG. config EDK2_SECURE_BOOT_SUPPORT bool "Enable UEFI Secure Boot support" diff --git a/payloads/external/iPXE/Kconfig b/payloads/external/iPXE/Kconfig index 14f8898f4e2..31686c89162 100644 --- a/payloads/external/iPXE/Kconfig +++ b/payloads/external/iPXE/Kconfig @@ -53,15 +53,15 @@ if BUILD_IPXE choice prompt "iPXE version" - default IPXE_MASTER + default IPXE_STABLE config IPXE_STABLE - bool "2022.1" + bool "2025.12" help iPXE uses a rolling release with no stable version, for reproducibility, use the last commit of a given month as the 'stable' version. - This is iPXE from the end of January, 2022. + This is iPXE from the end of December, 2025. config IPXE_MASTER bool "master" diff --git a/payloads/external/iPXE/Makefile b/payloads/external/iPXE/Makefile index a58d5f79ce3..a9fb43f8466 100644 --- a/payloads/external/iPXE/Makefile +++ b/payloads/external/iPXE/Makefile @@ -2,7 +2,7 @@ # 2022.1 - Last commit of January 2022 # When updating, change the name both here and in payloads/external/iPXE/Kconfig -STABLE_COMMIT_ID=6ba671acd922ee046b257c5119b8a0f64d275473 +STABLE_COMMIT_ID=7c39c04a537ce29dccc6f2bae9749d1d371429c1 TAG-$(CONFIG_IPXE_MASTER)=origin/master TAG-$(CONFIG_IPXE_STABLE)=$(STABLE_COMMIT_ID) @@ -42,15 +42,10 @@ checkout: fetch config: checkout ifeq ($(CONSOLE_SERIAL),yy) - cp "$(project_dir)/src/config/console.h" "$(project_dir)/src/config/console.h.cb" - cp "$(project_dir)/src/config/serial.h" "$(project_dir)/src/config/serial.h.cb" sed -i'' 's|//#define\s*CONSOLE_SERIAL.*|#define CONSOLE_SERIAL|' "$(project_dir)/src/config/console.h" sed -i'' 's|#define\s*COMCONSOLE.*|#define COMCONSOLE $(IPXE_UART)|' "$(project_dir)/src/config/serial.h" sed -i'' 's|#define\s*COMSPEED.*|#define COMSPEED $(CONFIG_TTYS0_BAUD)|' "$(project_dir)/src/config/serial.h" endif -ifneq ($(filter y,$(CONFIG_HAS_SCRIPT) $(CONFIG_IPXE_NO_PROMPT)),) - cp "$(project_dir)/src/config/general.h" "$(project_dir)/src/config/general.h.cb" -endif ifeq ($(CONFIG_HAS_SCRIPT),y) sed -i'' 's|//#define\s*IMAGE_SCRIPT.*|#define IMAGE_SCRIPT|' "$(project_dir)/src/config/general.h" endif @@ -73,13 +68,7 @@ else $(MAKE) -C $(project_dir)/src $(IPXE_BUILD_TARGET) $(PXE_MAKE_OPTS) endif cp $(project_dir)/src/$(IPXE_BUILD_TARGET) $(project_dir)/ipxe.rom -ifeq ($(CONSOLE_SERIAL),yy) - cp "$(project_dir)/src/config/console.h.cb" "$(project_dir)/src/config/console.h" - cp "$(project_dir)/src/config/serial.h.cb" "$(project_dir)/src/config/serial.h" -endif -ifneq ($(filter y,$(CONFIG_HAS_SCRIPT) $(CONFIG_IPXE_NO_PROMPT)),) - cp "$(project_dir)/src/config/general.h.cb" "$(project_dir)/src/config/general.h" -endif + cd $(project_dir) && git restore src/config/console.h src/config/serial.h src/config/general.h clean: test -d $(project_dir) && $(MAKE) -C $(project_dir)/src veryclean || exit 0 diff --git a/payloads/libpayload/Kconfig b/payloads/libpayload/Kconfig index 44d656bcacb..9ad454181fa 100644 --- a/payloads/libpayload/Kconfig +++ b/payloads/libpayload/Kconfig @@ -127,6 +127,15 @@ config ARCH_ARM64 help Support the ARM64 architecture +config ARCH_RISCV_RV64 + bool "RISCV64" + depends on GPL + depends on EXPERIMENTAL + help + Support the RISC-V 64-bit architecture + Please note that support for riscv64 payload is experimental at this time, may have + fundamental change in the future. + config ARCH_MOCK bool "Mock architecture (for unit tests)" help @@ -523,3 +532,4 @@ source "arch/arm/Kconfig" source "arch/arm64/Kconfig" source "arch/x86/Kconfig" source "arch/mock/Kconfig" +source "arch/riscv/Kconfig" diff --git a/payloads/libpayload/Makefile b/payloads/libpayload/Makefile index a8c2641dc66..6ac1e90d266 100644 --- a/payloads/libpayload/Makefile +++ b/payloads/libpayload/Makefile @@ -111,6 +111,7 @@ ARCHDIR-$(CONFIG_LP_ARCH_ARM) := arm ARCHDIR-$(CONFIG_LP_ARCH_ARM64) := arm64 ARCHDIR-$(CONFIG_LP_ARCH_X86) := x86 ARCHDIR-$(CONFIG_LP_ARCH_MOCK) := mock +ARCHDIR-$(CONFIG_LP_ARCH_RISCV_RV64) := riscv ARCH-y := $(ARCHDIR-y) @@ -121,6 +122,7 @@ ARCH-$(CONFIG_LP_ARCH_ARM64) := arm64 ARCH-$(CONFIG_LP_ARCH_X86_32) := x86_32 ARCH-$(CONFIG_LP_ARCH_X86_64) := x86_64 ARCH-$(CONFIG_LP_ARCH_MOCK) := mock +ARCH-$(CONFIG_LP_ARCH_RISCV_RV64) := riscv # Five cases where we don't need fully populated $(obj) lists: # 1. when no .config exists diff --git a/payloads/libpayload/Makefile.mk b/payloads/libpayload/Makefile.mk index 08249c26488..f7c2c8bda0e 100644 --- a/payloads/libpayload/Makefile.mk +++ b/payloads/libpayload/Makefile.mk @@ -41,6 +41,7 @@ ARCHDIR-$(CONFIG_LP_ARCH_ARM) := arm ARCHDIR-$(CONFIG_LP_ARCH_ARM64) := arm64 ARCHDIR-$(CONFIG_LP_ARCH_X86) := x86 ARCHDIR-$(CONFIG_LP_ARCH_MOCK) := mock +ARCHDIR-$(CONFIG_LP_ARCH_RISCV_RV64) := riscv DESTDIR ?= install real-target: lib diff --git a/payloads/libpayload/arch/arm64/mmu.c b/payloads/libpayload/arch/arm64/mmu.c index e99fa37c5d3..0b7d206a589 100644 --- a/payloads/libpayload/arch/arm64/mmu.c +++ b/payloads/libpayload/arch/arm64/mmu.c @@ -611,6 +611,7 @@ static void mmu_extract_ranges(struct memrange *cb_ranges, switch (cb_ranges[i].type) { case CB_MEM_TABLE: + case CB_MEM_TAG: /* Mark this memrange as used memory */ if (mmu_add_memrange(&usedmem_ranges, base, size, TYPE_NORMAL_MEM) == NULL) diff --git a/payloads/libpayload/arch/riscv/Kconfig b/payloads/libpayload/arch/riscv/Kconfig new file mode 100644 index 00000000000..03960ab1dad --- /dev/null +++ b/payloads/libpayload/arch/riscv/Kconfig @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config ARCH_RISCV_RV64 + select LITTLE_ENDIAN diff --git a/payloads/libpayload/arch/riscv/Makefile.mk b/payloads/libpayload/arch/riscv/Makefile.mk new file mode 100644 index 00000000000..cb835bbfcb1 --- /dev/null +++ b/payloads/libpayload/arch/riscv/Makefile.mk @@ -0,0 +1,7 @@ +## SPDX-License-Identifier: GPL-2.0-only + +libc-y += head.S +libc-y += main.c sysinfo.c +libc-y += timer.c coreboot.c cache.c util.S virtual.c + +CFLAGS += -mcmodel=medany diff --git a/payloads/libpayload/arch/riscv/cache.c b/payloads/libpayload/arch/riscv/cache.c new file mode 100644 index 00000000000..d5dcb5e2a25 --- /dev/null +++ b/payloads/libpayload/arch/riscv/cache.c @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +void tlb_invalidate_all(void) +{ + asm volatile ("sfence.vma" : : : "memory"); +} + +void dcache_clean_invalidate_all(void) +{ + +} diff --git a/payloads/libpayload/arch/riscv/coreboot.c b/payloads/libpayload/arch/riscv/coreboot.c new file mode 100644 index 00000000000..acd3e85fb16 --- /dev/null +++ b/payloads/libpayload/arch/riscv/coreboot.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +/* + * This pointer is no longer set in head.S by default like in other arch, payloads should have + * their own ways to init it from any source before using it. + * e.g. If run after OpenSBI, this could be retrieved from fdt node. + * If run directly after Ramstage, could be from arg0. + */ +void *cb_header_ptr; + +/* == Architecture specific == */ + +int cb_parse_arch_specific(struct cb_record *rec, struct sysinfo_t *info) +{ + switch (rec->tag) { + default: + return 0; + } + return 1; +} + +int get_coreboot_info(struct sysinfo_t *info) +{ + return cb_parse_header(cb_header_ptr, 1, info); +} + +void *get_cb_header_ptr(void) +{ + return cb_header_ptr; +} diff --git a/payloads/libpayload/arch/riscv/head.S b/payloads/libpayload/arch/riscv/head.S new file mode 100644 index 00000000000..aebbff979d3 --- /dev/null +++ b/payloads/libpayload/arch/riscv/head.S @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +/* + * Our entry point + */ +ENTRY(_entry) + + /* Setup new stack */ + lla t0, 1f + ld sp, 0(t0) + //mov sp, x1 + + /* Let's rock. */ + j start_main + + ret +ENDPROC(_entry) + +.section .entry, "ax", %progbits +.align 4 +1: +.quad _stack diff --git a/payloads/libpayload/arch/riscv/libpayload.ldscript b/payloads/libpayload/arch/riscv/libpayload.ldscript new file mode 100644 index 00000000000..168f61397a3 --- /dev/null +++ b/payloads/libpayload/arch/riscv/libpayload.ldscript @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +OUTPUT_ARCH(riscv) + +ENTRY(_entry) + +SECTIONS +{ + . = CONFIG_LP_BASE_ADDRESS; + + . = ALIGN(16); + _start = .; + + .text : { + _text = .; + *(.text._entry) + *(.text) + *(.text.*) + _etext = .; + } + + .rodata : { + _rodata = .; + *(.rodata) + *(.rodata.*) + _erodata = .; + } + + .data : { + _data = .; + *(.data) + *(.data.*) + _edata = .; + } + + .bss : { + _bss = .; + *(.sbss) + *(.sbss.*) + *(.bss) + *(.bss.*) + *(COMMON) + _ebss = .; + + /* Stack and heap */ + + . = ALIGN(16); + _heap = .; + . += CONFIG_LP_HEAP_SIZE; + . = ALIGN(16); + _eheap = .; + + _estack = .; + . += CONFIG_LP_STACK_SIZE; + . = ALIGN(16); + _stack = .; + } + + _end = .; + + /DISCARD/ : { + *(.comment) + *(.note*) + } +} diff --git a/payloads/libpayload/arch/riscv/main.c b/payloads/libpayload/arch/riscv/main.c new file mode 100644 index 00000000000..d0b400c8f2b --- /dev/null +++ b/payloads/libpayload/arch/riscv/main.c @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +uint64_t boot_hartid; +/** + * This is our C entry function - set up the system and jump into the payload entry point. + * Unlike other archs, we do not save a0~a2 from previous stage as global variables in head.S, + * but pass them to start_main directly as arg0, arg1, arg2 instead. + * + * arg0 is the preferred boot hart id. + * arg1 is a pointer to the DTB. + * This interface is static no matter whether previous stage is OpenSBI or coreboot Ramstage. + * + * arg2 is reserved for possible future usage. + */ +void start_main(uint64_t arg0, uint64_t arg1, uint64_t arg2); +void start_main(uint64_t arg0, uint64_t arg1, uint64_t arg2) +{ + extern int main(int argc, char **argv); + extern void *cb_header_ptr; + + /* cbtable pointer is stored in the dtb passed by previous stage */ + boot_hartid = arg0; + const void *dtb = (const void *)arg1; + if (dtb && fdt_is_valid(dtb)) { + /* Look for the "coreboot-table" node in the DTB */ + u32 node_offset = fdt_find_node_by_path(dtb, "/chosen", NULL, NULL); + if (node_offset) { + struct fdt_property prop; + if (fdt_read_prop(dtb, node_offset, "coreboot-table", &prop)) { + /* Extract the coreboot table pointer from the property */ + cb_header_ptr = (void *)be64dec(prop.data); + } + } + } + + /* Gather system information. */ + lib_get_sysinfo(); + +#if !CONFIG(LP_SKIP_CONSOLE_INIT) + console_init(); +#endif + + /* + * Go to the entry point. + * In the future we may care about the return value. + */ + main(0, NULL); + printf("Unexpected return from payload\n"); +} diff --git a/payloads/libpayload/arch/riscv/sysinfo.c b/payloads/libpayload/arch/riscv/sysinfo.c new file mode 100644 index 00000000000..353ede174e8 --- /dev/null +++ b/payloads/libpayload/arch/riscv/sysinfo.c @@ -0,0 +1,70 @@ +/* + * + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +/** + * This is a global structure that is used through the library - we set it + * up initially with some dummy values - hopefully they will be overridden. + */ +struct sysinfo_t lib_sysinfo = { + .cpu_khz = 200, +}; + +int lib_get_sysinfo(void) +{ + int ret; + + /* Get the CPU speed (for delays). */ + lib_sysinfo.cpu_khz = get_cpu_speed(); + + /* Get information from the coreboot tables, + * if they exist */ + + ret = get_coreboot_info(&lib_sysinfo); + + if (!lib_sysinfo.n_memranges) { + /* If we can't get a good memory range, use the default. */ + lib_sysinfo.n_memranges = 1; + + lib_sysinfo.memrange[0].base = 0; + lib_sysinfo.memrange[0].size = 1024 * 1024; + lib_sysinfo.memrange[0].type = CB_MEM_RAM; + } + + return ret; +} + +void lib_sysinfo_get_memranges(struct memrange **ranges, + uint64_t *nranges) +{ + *ranges = &lib_sysinfo.memrange[0]; + *nranges = lib_sysinfo.n_memranges; +} diff --git a/payloads/libpayload/arch/riscv/timer.c b/payloads/libpayload/arch/riscv/timer.c new file mode 100644 index 00000000000..1177e098024 --- /dev/null +++ b/payloads/libpayload/arch/riscv/timer.c @@ -0,0 +1,53 @@ +/* + * + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/** + * @file riscv64/timer.c + * RISCV64 specific timer routines + */ + +#include + +/** + * @ingroup arch + * Global variable containing the speed of the processor in KHz. + */ +u32 cpu_khz; + +/** + * Calculate the speed of the processor for use in delays. + * + * @return The CPU speed in kHz. + */ +unsigned int get_cpu_speed(void) +{ + /* FIXME */ + cpu_khz = 1000000U; + + return cpu_khz; +} diff --git a/payloads/libpayload/arch/riscv/util.S b/payloads/libpayload/arch/riscv/util.S new file mode 100644 index 00000000000..3b15abc21d7 --- /dev/null +++ b/payloads/libpayload/arch/riscv/util.S @@ -0,0 +1,34 @@ +/* + * + * Copyright (C) 2012 Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +/* This function puts the system into a halt. */ +ENTRY(halt) + j halt +ENDPROC(halt) diff --git a/payloads/libpayload/arch/riscv/virtual.c b/payloads/libpayload/arch/riscv/virtual.c new file mode 100644 index 00000000000..9450ac0d860 --- /dev/null +++ b/payloads/libpayload/arch/riscv/virtual.c @@ -0,0 +1,36 @@ +/* + * + * Copyright (C) 2008 coresystems GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +unsigned long virtual_offset = 0; + +int getpagesize(void) +{ + return 4096; +} diff --git a/payloads/libpayload/configs/defconfig_64 b/payloads/libpayload/configs/defconfig_64 new file mode 100644 index 00000000000..9db83c0635c --- /dev/null +++ b/payloads/libpayload/configs/defconfig_64 @@ -0,0 +1,9 @@ +CONFIG_LP_ARCH_X86_64=y +# CONFIG_LP_MULTIBOOT is not set +CONFIG_LP_COREBOOT_VIDEO_CONSOLE=y +CONFIG_LP_USB=y +CONFIG_LP_USB_UHCI=y +CONFIG_LP_USB_OHCI=y +CONFIG_LP_USB_EHCI=y +CONFIG_LP_USB_XHCI=y +CONFIG_LP_HEAP_SIZE=1048576 diff --git a/payloads/libpayload/curses/Makefile.mk b/payloads/libpayload/curses/Makefile.mk index 99f8d70e05b..8c8c401c65d 100644 --- a/payloads/libpayload/curses/Makefile.mk +++ b/payloads/libpayload/curses/Makefile.mk @@ -38,7 +38,10 @@ includes-$(CONFIG_LP_TINYCURSES) += curses.h ifeq ($(CONFIG_LP_PDCURSES),y) PDCURSES := PDCurses -INCLUDES += -D_LP64=0 -Icurses/$(PDCURSES) -Icurses/pdcurses-backend -Icurses/menu -Icurses/form +ifneq ($(CONFIG_LP_ARCH_X86_64),y) +INCLUDES += -D_LP64=0 +endif +INCLUDES += -Icurses/$(PDCURSES) -Icurses/pdcurses-backend -Icurses/menu -Icurses/form endif libcurses-$(CONFIG_LP_PDCURSES) += pdcurses-backend/pdcdisp.c diff --git a/payloads/libpayload/drivers/Makefile.mk b/payloads/libpayload/drivers/Makefile.mk index 23471b83c45..63daf67cdbf 100644 --- a/payloads/libpayload/drivers/Makefile.mk +++ b/payloads/libpayload/drivers/Makefile.mk @@ -64,6 +64,7 @@ libc-y += timer/generic.c endif libc-$(CONFIG_LP_TIMER_RDTSC) += timer/rdtsc.c libc-$(CONFIG_LP_TIMER_ARM64_ARCH) += timer/arm64_arch_timer.c +libc-$(CONFIG_LP_TIMER_RISCV64_ARCH) += timer/riscv64_arch_timer.c # Video console drivers libc-$(CONFIG_LP_VIDEO_CONSOLE) += video/video.c diff --git a/payloads/libpayload/drivers/timer/Kconfig b/payloads/libpayload/drivers/timer/Kconfig index 406457af8e0..1932a136dae 100644 --- a/payloads/libpayload/drivers/timer/Kconfig +++ b/payloads/libpayload/drivers/timer/Kconfig @@ -36,6 +36,12 @@ config TIMER_ARM64_ARCH help The cntfrq register needs to have been pre-initialized. +config TIMER_RISCV64_ARCH + bool "Architecture Timer for RISCV64 platforms" + depends on ARCH_RISCV_RV64 + help + Payloads usually run in S-Mode, which has a time CSR for timer implementation. + config TIMER_RK3288 bool "Timer for Rockchip RK3288" diff --git a/payloads/libpayload/drivers/timer/riscv64_arch_timer.c b/payloads/libpayload/drivers/timer/riscv64_arch_timer.c new file mode 100644 index 00000000000..515ae476584 --- /dev/null +++ b/payloads/libpayload/drivers/timer/riscv64_arch_timer.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +uint64_t timer_hz(void) +{ + /* FIXME */ + return 1000000; +} + +uint64_t timer_raw_value(void) +{ + uint64_t value; + asm volatile ("csrr %0, time" : "=r" (value)); + return value; +} diff --git a/payloads/libpayload/drivers/usb/dwc2.c b/payloads/libpayload/drivers/usb/dwc2.c index e0b290f58cf..5d9bd4cb593 100644 --- a/payloads/libpayload/drivers/usb/dwc2.c +++ b/payloads/libpayload/drivers/usb/dwc2.c @@ -152,13 +152,13 @@ static int dwc2_disconnected(hci_t *controller) * or an error code if the transfer failed */ static int -wait_for_complete(endpoint_t *ep, uint32_t ch_num) +wait_for_complete(endpoint_t *ep, uint32_t ch_num, int timeout_us) { hcint_t hcint; hcchar_t hcchar; hctsiz_t hctsiz; dwc2_reg_t *reg = DWC2_REG(ep->dev->controller); - int timeout = USB_MAX_PROCESSING_TIME_US / DWC2_SLEEP_TIME_US; + int timeout = timeout_us / DWC2_SLEEP_TIME_US; /* * TODO: We should take care of up to three times of transfer error @@ -211,12 +211,12 @@ wait_for_complete(endpoint_t *ep, uint32_t ch_num) hcint.d32 = ~0; writel(hcint.d32, ®->host.hchn[ch_num].hcintn); - return -HCSTAT_TIMEOUT; + return USB_TIMEOUT; } static int dwc2_do_xfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, - uint32_t ch_num, u8 *data_buf, int *short_pkt) + uint32_t ch_num, u8 *data_buf, int *short_pkt, int timeout_us) { uint32_t do_copy; int ret; @@ -279,7 +279,7 @@ dwc2_do_xfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, ®->host.hchn[ch_num].hcdman); writel(hcchar.d32, ®->host.hchn[ch_num].hccharn); - ret = wait_for_complete(ep, ch_num); + ret = wait_for_complete(ep, ch_num, timeout_us); if (ret >= 0) { /* Calculate actual transferred length */ @@ -307,7 +307,7 @@ dwc2_do_xfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, static int dwc2_split_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, uint32_t ch_num, u8 *data_buf, split_info_t *split, - int *short_pkt) + int *short_pkt, int timeout_us) { dwc2_reg_t *reg = DWC2_REG(ep->dev->controller); hfnum_t hfnum; @@ -331,7 +331,7 @@ dwc2_split_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, /* Handle Start-Split */ ret = dwc2_do_xfer(ep, dir == EPDIR_IN ? 0 : size, pid, dir, ch_num, - data_buf, NULL); + data_buf, NULL, timeout_us); if (ret < 0) goto out; @@ -346,7 +346,7 @@ dwc2_split_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, /* Handle Complete-Split */ do { ret = dwc2_do_xfer(ep, dir == EPDIR_OUT ? 0 : size, ep->toggle, - dir, ch_num, data_buf, short_pkt); + dir, ch_num, data_buf, short_pkt, timeout_us); } while (ret == -HCSTAT_NYET); if (dir == EPDIR_IN) @@ -379,11 +379,11 @@ static int dwc2_need_split(usbdev_t *dev, split_info_t *split) static int dwc2_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, uint32_t ch_num, - u8 *src, uint8_t skip_nak) + u8 *src, uint8_t skip_nak, int timeout_us) { split_info_t split; int ret, short_pkt, transferred = 0; - int timeout = USB_MAX_PROCESSING_TIME_US / USB_FULL_LOW_SPEED_FRAME_US; + int timeout = timeout_us / USB_FULL_LOW_SPEED_FRAME_US; ep->toggle = pid; @@ -393,7 +393,7 @@ dwc2_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, uint32_t ch_num, nak_retry: ret = dwc2_split_transfer(ep, MIN(ep->maxpacketsize, size), ep->toggle, dir, 0, src, &split, - &short_pkt); + &short_pkt, timeout_us); /* * dwc2_split_transfer() waits for the next FullSpeed @@ -403,10 +403,12 @@ dwc2_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, uint32_t ch_num, if (ret == -HCSTAT_NAK && !skip_nak && --timeout) { udelay(USB_FULL_LOW_SPEED_FRAME_US / 2); goto nak_retry; + } else if (timeout <= 0 && ret < 0) { + return USB_TIMEOUT; } } else { ret = dwc2_do_xfer(ep, MIN(DMA_SIZE, size), pid, dir, 0, - src, &short_pkt); + src, &short_pkt, timeout_us); } if (ret < 0) @@ -422,7 +424,7 @@ dwc2_transfer(endpoint_t *ep, int size, int pid, ep_dir_t dir, uint32_t ch_num, } static int -dwc2_bulk(endpoint_t *ep, int size, u8 *src, int finalize) +dwc2_bulk_timeout(endpoint_t *ep, int size, u8 *src, int timeout_us) { ep_dir_t data_dir; @@ -433,7 +435,13 @@ dwc2_bulk(endpoint_t *ep, int size, u8 *src, int finalize) else return -1; - return dwc2_transfer(ep, size, ep->toggle, data_dir, 0, src, 0); + return dwc2_transfer(ep, size, ep->toggle, data_dir, 0, src, 0, timeout_us); +} + +static int +dwc2_bulk(endpoint_t *ep, int size, u8 *src, int finalize) +{ + return dwc2_bulk_timeout(ep, size, src, USB_MAX_PROCESSING_TIME_US); } static int @@ -452,19 +460,22 @@ dwc2_control(usbdev_t *dev, direction_t dir, int drlen, void *setup, return -1; /* Setup Phase */ - if (dwc2_transfer(ep, drlen, PID_SETUP, EPDIR_OUT, 0, setup, 0) < 0) + if (dwc2_transfer(ep, drlen, PID_SETUP, EPDIR_OUT, 0, setup, 0, + USB_MAX_PROCESSING_TIME_US) < 0) return -1; /* Data Phase */ ep->toggle = PID_DATA1; if (dalen > 0) { - ret = dwc2_transfer(ep, dalen, ep->toggle, data_dir, 0, src, 0); + ret = dwc2_transfer(ep, dalen, ep->toggle, data_dir, 0, src, 0, + USB_MAX_PROCESSING_TIME_US); if (ret < 0) return -1; } /* Status Phase */ - if (dwc2_transfer(ep, 0, PID_DATA1, !data_dir, 0, NULL, 0) < 0) + if (dwc2_transfer(ep, 0, PID_DATA1, !data_dir, 0, NULL, 0, + USB_MAX_PROCESSING_TIME_US) < 0) return -1; return ret; @@ -482,7 +493,8 @@ dwc2_intr(endpoint_t *ep, int size, u8 *src) else return -1; - return dwc2_transfer(ep, size, ep->toggle, data_dir, 0, src, 1); + return dwc2_transfer(ep, size, ep->toggle, data_dir, 0, src, 1, + USB_MAX_PROCESSING_TIME_US); } static u32 dwc2_intr_get_timestamp(intr_queue_t *q) @@ -583,6 +595,7 @@ hci_t *dwc2_init(void *bar) controller->init = dwc2_reinit; controller->shutdown = dwc2_shutdown; controller->bulk = dwc2_bulk; + controller->bulk_timeout = dwc2_bulk_timeout; controller->control = dwc2_control; controller->set_address = generic_set_address; controller->finish_device_config = NULL; diff --git a/payloads/libpayload/drivers/usb/dwc2_private.h b/payloads/libpayload/drivers/usb/dwc2_private.h index 3616ff3d10d..86c9da2fa83 100644 --- a/payloads/libpayload/drivers/usb/dwc2_private.h +++ b/payloads/libpayload/drivers/usb/dwc2_private.h @@ -48,7 +48,6 @@ typedef enum { HCSTAT_NAK, HCSTAT_NYET, HCSTAT_UNKNOW, - HCSTAT_TIMEOUT, HCSTAT_DISCONNECTED, } hcstat_t; #endif diff --git a/payloads/libpayload/drivers/usb/ehci.c b/payloads/libpayload/drivers/usb/ehci.c index 822fdb19a9e..fe3186d5ca6 100644 --- a/payloads/libpayload/drivers/usb/ehci.c +++ b/payloads/libpayload/drivers/usb/ehci.c @@ -249,23 +249,25 @@ static void free_qh_and_tds(ehci_qh_t *qh, qtd_t *cur) #define EHCI_SLEEP_TIME_US 50 -static int wait_for_tds(qtd_t *head) +static int wait_for_tds(qtd_t *head, int timeout_us) { - /* returns the amount of bytes *not* transmitted, or -1 for error */ + /* returns the amount of bytes *not* transmitted, USB_TIMEOUT on timeout, + * or -1 for error + */ int result = 0; qtd_t *cur = head; while (1) { if (0) dump_td(virt_to_phys(cur)); /* wait for results */ - int timeout = USB_MAX_PROCESSING_TIME_US / EHCI_SLEEP_TIME_US; + int timeout = timeout_us / EHCI_SLEEP_TIME_US; while ((cur->token & QTD_ACTIVE) && !(cur->token & QTD_HALTED) && timeout--) udelay(EHCI_SLEEP_TIME_US); if (timeout < 0) { usb_debug("Error: ehci: queue transfer " "processing timed out.\n"); - return -1; + return USB_TIMEOUT; } if (cur->token & QTD_HALTED) { usb_debug("ERROR with packet\n"); @@ -319,7 +321,7 @@ static int ehci_set_async_schedule(ehci_t *ehcic, int enable) } static int ehci_process_async_schedule( - ehci_t *ehcic, ehci_qh_t *qhead, qtd_t *head) + ehci_t *ehcic, ehci_qh_t *qhead, qtd_t *head, int timeout_us) { int result; @@ -333,7 +335,7 @@ static int ehci_process_async_schedule( if (ehci_set_async_schedule(ehcic, 1)) return -1; /* wait for result */ - result = wait_for_tds(head); + result = wait_for_tds(head, timeout_us); /* disable async schedule */ ehci_set_async_schedule(ehcic, 0); @@ -341,7 +343,7 @@ static int ehci_process_async_schedule( return result; } -static int ehci_bulk(endpoint_t *ep, int size, u8 *src, int finalize) +static int ehci_bulk_timeout(endpoint_t *ep, int size, u8 *src, int timeout_us) { int result = 0; u8 *end = src + size; @@ -410,7 +412,7 @@ static int ehci_bulk(endpoint_t *ep, int size, u8 *src, int finalize) head->token |= (ep->toggle?QTD_TOGGLE_DATA1:0); result = ehci_process_async_schedule( - EHCI_INST(ep->dev->controller), qh, head); + EHCI_INST(ep->dev->controller), qh, head, timeout_us); if (result >= 0) { result = size - result; if (pid == EHCI_IN && end != src + size) @@ -429,6 +431,11 @@ static int ehci_bulk(endpoint_t *ep, int size, u8 *src, int finalize) return -1; } +static int ehci_bulk(endpoint_t *ep, int size, u8 *src, int finalize) +{ + return ehci_bulk_timeout(ep, size, src, USB_MAX_PROCESSING_TIME_US); +} + /* FIXME: Handle control transfers as 3 QHs, so the 2nd stage can be >0x4000 bytes */ static int ehci_control(usbdev_t *dev, direction_t dir, int drlen, void *setup, int dalen, u8 *src) @@ -530,7 +537,7 @@ static int ehci_control(usbdev_t *dev, direction_t dir, int drlen, void *setup, qh->td.next_qtd = virt_to_phys(head); result = ehci_process_async_schedule( - EHCI_INST(dev->controller), qh, head); + EHCI_INST(dev->controller), qh, head, USB_MAX_PROCESSING_TIME_US); if (result >= 0) { result = dalen - result; if (dir == IN && data != src) @@ -784,6 +791,7 @@ ehci_init(unsigned long physical_bar) controller->init = ehci_reinit; controller->shutdown = ehci_shutdown; controller->bulk = ehci_bulk; + controller->bulk_timeout = ehci_bulk_timeout; controller->control = ehci_control; controller->set_address = generic_set_address; controller->finish_device_config = NULL; diff --git a/payloads/libpayload/drivers/usb/ohci.c b/payloads/libpayload/drivers/usb/ohci.c index 79add33fe73..55bdf668262 100644 --- a/payloads/libpayload/drivers/usb/ohci.c +++ b/payloads/libpayload/drivers/usb/ohci.c @@ -39,6 +39,7 @@ static void ohci_stop(hci_t *controller); static void ohci_reset(hci_t *controller); static void ohci_shutdown(hci_t *controller); static int ohci_bulk(endpoint_t *ep, int size, u8 *data, int finalize); +static int ohci_bulk_timeout(endpoint_t *ep, int size, u8 *data, int timeout_us); static int ohci_control(usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen, u8 *data); static void* ohci_create_intr_queue(endpoint_t *ep, int reqsize, int reqcount, int reqtiming); @@ -181,6 +182,7 @@ ohci_init(unsigned long physical_bar) controller->init = ohci_reinit; controller->shutdown = ohci_shutdown; controller->bulk = ohci_bulk; + controller->bulk_timeout = ohci_bulk_timeout; controller->control = ohci_control; controller->set_address = generic_set_address; controller->finish_device_config = NULL; @@ -295,10 +297,10 @@ ohci_stop(hci_t *controller) #define OHCI_SLEEP_TIME_US 1000 static int -wait_for_ed(usbdev_t *dev, ed_t *head, int pages) +wait_for_ed(usbdev_t *dev, ed_t *head, int pages, int timeout_us) { /* wait for results */ - int timeout = USB_MAX_PROCESSING_TIME_US / OHCI_SLEEP_TIME_US; + int timeout = timeout_us / OHCI_SLEEP_TIME_US; while (((head->head_pointer & ~3) != head->tail_pointer) && !(head->head_pointer & 1) && ((((td_t*)phys_to_virt(head->head_pointer & ~3))->config @@ -326,7 +328,7 @@ wait_for_ed(usbdev_t *dev, ed_t *head, int pages) usb_debug("HALTED!\n"); return -1; } - return result; + return timeout <= 0 ? USB_TIMEOUT : result; } static void @@ -481,7 +483,8 @@ ohci_control(usbdev_t *dev, direction_t dir, int drlen, void *setup, int dalen, OHCI_INST(dev->controller)->opreg->HcCommandStatus = ControlListFilled; int result = wait_for_ed(dev, head, - (dalen == 0)?0:(last_page - first_page + 1)); + (dalen == 0)?0:(last_page - first_page + 1), + USB_MAX_PROCESSING_TIME_US); /* Wait some frames before and one after disabling list access. */ mdelay(4); OHCI_INST(dev->controller)->opreg->HcControl &= ~ControlListEnable; @@ -501,7 +504,7 @@ ohci_control(usbdev_t *dev, direction_t dir, int drlen, void *setup, int dalen, /* finalize == 1: if data is of packet aligned size, add a zero length packet */ static int -ohci_bulk(endpoint_t *ep, int dalen, u8 *src, int finalize) +ohci_bulk_finalize_timeout(endpoint_t *ep, int dalen, u8 *src, int finalize, int timeout_us) { int i; td_t *cur, *next; @@ -608,7 +611,7 @@ ohci_bulk(endpoint_t *ep, int dalen, u8 *src, int finalize) OHCI_INST(ep->dev->controller)->opreg->HcCommandStatus = BulkListFilled; int result = wait_for_ed(ep->dev, head, - (dalen == 0)?0:(last_page - first_page + 1)); + (dalen == 0)?0:(last_page - first_page + 1), timeout_us); /* Wait some frames before and one after disabling list access. */ mdelay(4); OHCI_INST(ep->dev->controller)->opreg->HcControl &= ~BulkListEnable; @@ -628,6 +631,19 @@ ohci_bulk(endpoint_t *ep, int dalen, u8 *src, int finalize) return result; } +static int +ohci_bulk_timeout(endpoint_t *ep, int dalen, u8 *src, int timeout_us) +{ + /* usbdev_hc bulk_timeout API doesn't have finalize argument. Assume it should be 0. */ + return ohci_bulk_finalize_timeout(ep, dalen, src, 0, timeout_us); +} + +static int +ohci_bulk(endpoint_t *ep, int dalen, u8 *src, int finalize) +{ + return ohci_bulk_finalize_timeout(ep, dalen, src, finalize, USB_MAX_PROCESSING_TIME_US); +} + struct _intr_queue; struct _intrq_td { diff --git a/payloads/libpayload/drivers/usb/uhci.c b/payloads/libpayload/drivers/usb/uhci.c index 7590ab3c850..53fb123c8c5 100644 --- a/payloads/libpayload/drivers/usb/uhci.c +++ b/payloads/libpayload/drivers/usb/uhci.c @@ -39,6 +39,7 @@ static void uhci_stop(hci_t *controller); static void uhci_reset(hci_t *controller); static void uhci_shutdown(hci_t *controller); static int uhci_bulk(endpoint_t *ep, int size, u8 *data, int finalize); +static int uhci_bulk_timeout(endpoint_t *ep, int size, u8 *data, int timeout_us); static int uhci_control(usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen, u8 *data); static void* uhci_create_intr_queue(endpoint_t *ep, int reqsize, int reqcount, int reqtiming); @@ -162,6 +163,7 @@ uhci_pci_init(pcidev_t addr) controller->init = uhci_reinit; controller->shutdown = uhci_shutdown; controller->bulk = uhci_bulk; + controller->bulk_timeout = uhci_bulk_timeout; controller->control = uhci_control; controller->set_address = generic_set_address; controller->finish_device_config = NULL; @@ -273,23 +275,23 @@ uhci_stop(hci_t *controller) } #define UHCI_SLEEP_TIME_US 30 -#define UHCI_TIMEOUT (USB_MAX_PROCESSING_TIME_US / UHCI_SLEEP_TIME_US) #define GET_TD(x) ((void *)(((unsigned long)(x))&~0xf)) static td_t * -wait_for_completed_qh(hci_t *controller, qh_t *qh) +wait_for_completed_qh(hci_t *controller, qh_t *qh, int *timeout_us) { - int timeout = UHCI_TIMEOUT; + int timeout = *timeout_us / UHCI_SLEEP_TIME_US; void *current = GET_TD(qh->elementlinkptr); while (((qh->elementlinkptr & FLISTP_TERMINATE) == 0) && (timeout-- > 0)) { if (current != GET_TD(qh->elementlinkptr)) { current = GET_TD(qh->elementlinkptr); - timeout = UHCI_TIMEOUT; + timeout = *timeout_us / UHCI_SLEEP_TIME_US; } uhci_reg_write16(controller, USBSTS, uhci_reg_read16(controller, USBSTS) | 0); // clear resettable registers udelay(UHCI_SLEEP_TIME_US); } + *timeout_us = timeout * UHCI_SLEEP_TIME_US; return (GET_TD(qh->elementlinkptr) == 0) ? 0 : GET_TD(phys_to_virt(qh->elementlinkptr)); } @@ -370,9 +372,10 @@ uhci_control(usbdev_t *dev, direction_t dir, int drlen, void *devreq, const int TD_STATUS_ACTIVE; UHCI_INST(dev->controller)->qh_data->elementlinkptr = virt_to_phys(tds) & ~(FLISTP_QH | FLISTP_TERMINATE); + int timeout_us = USB_MAX_PROCESSING_TIME_US; td_t *td = wait_for_completed_qh(dev->controller, UHCI_INST(dev->controller)-> - qh_data); + qh_data, &timeout_us); int result; if (td == 0) { result = dalen; /* TODO: We should return the actually transferred length. */ @@ -423,23 +426,24 @@ fill_schedule(td_t *td, endpoint_t *ep, int length, unsigned char *data, } static int -run_schedule(usbdev_t *dev, td_t *td) +run_schedule(usbdev_t *dev, td_t *td, int timeout_us) { UHCI_INST(dev->controller)->qh_data->elementlinkptr = virt_to_phys(td) & ~(FLISTP_QH | FLISTP_TERMINATE); td = wait_for_completed_qh(dev->controller, - UHCI_INST(dev->controller)->qh_data); + UHCI_INST(dev->controller)->qh_data, &timeout_us); if (td == 0) { return 0; } else { td_dump(td); - return 1; + return timeout_us <= 0 ? USB_TIMEOUT : -2; } } /* finalize == 1: if data is of packet aligned size, add a zero length packet */ static int -uhci_bulk(endpoint_t *ep, const int dalen, u8 *data, int finalize) +uhci_bulk_finalize_timeout(endpoint_t *ep, const int dalen, u8 *data, int finalize, + int timeout_us) { int maxpsize = ep->maxpacketsize; if (maxpsize == 0) @@ -460,15 +464,29 @@ uhci_bulk(endpoint_t *ep, const int dalen, u8 *data, int finalize) data += maxpsize; len_left -= maxpsize; } - if (run_schedule(ep->dev, tds) == 1) { + int ret = run_schedule(ep->dev, tds, timeout_us); + if (ret) { free(tds); - return -1; + return ret; } ep->toggle = toggle; free(tds); return dalen; /* TODO: We should return the actually transferred length. */ } +static int +uhci_bulk_timeout(endpoint_t *ep, int dalen, u8 *src, int timeout_us) +{ + /* usbdev_hc bulk_timeout API doesn't have finalize argument. Assume it should be 0. */ + return uhci_bulk_finalize_timeout(ep, dalen, src, 0, timeout_us); +} + +static int +uhci_bulk(endpoint_t *ep, const int dalen, u8 *data, int finalize) +{ + return uhci_bulk_finalize_timeout(ep, dalen, data, finalize, USB_MAX_PROCESSING_TIME_US); +} + typedef struct { qh_t *qh; td_t *tds; diff --git a/payloads/libpayload/drivers/usb/xhci.c b/payloads/libpayload/drivers/usb/xhci.c index e9a7ead18b1..2f9206efd5f 100644 --- a/payloads/libpayload/drivers/usb/xhci.c +++ b/payloads/libpayload/drivers/usb/xhci.c @@ -40,6 +40,7 @@ static void xhci_reset(hci_t *controller); static void xhci_reinit(hci_t *controller); static void xhci_shutdown(hci_t *controller); static int xhci_bulk(endpoint_t *ep, int size, u8 *data, int finalize); +static int xhci_bulk_timeout(endpoint_t *ep, int size, u8 *data, int timeout_us); static int xhci_control(usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen, u8 *data); static void* xhci_create_intr_queue(endpoint_t *ep, int reqsize, int reqcount, int reqtiming); @@ -168,6 +169,7 @@ xhci_init(unsigned long physical_bar) controller->init = xhci_reinit; controller->shutdown = xhci_shutdown; controller->bulk = xhci_bulk; + controller->bulk_timeout = xhci_bulk_timeout; controller->control = xhci_control; controller->set_address = xhci_set_address; controller->finish_device_config = xhci_finish_device_config; @@ -705,10 +707,11 @@ xhci_control(usbdev_t *const dev, const direction_t dir, int i, transferred = 0; const int n_stages = 2 + !!dalen; for (i = 0; i < n_stages; ++i) { - const int ret = xhci_wait_for_transfer(xhci, dev->address, 1); + const int ret = xhci_wait_for_transfer(xhci, dev->address, 1, + USB_MAX_PROCESSING_TIME_US); transferred += ret; if (ret < 0) { - if (ret == TIMEOUT) { + if (ret == USB_TIMEOUT) { xhci_debug("Stopping ID %d EP 1\n", dev->address); xhci_cmd_stop_endpoint(xhci, dev->address, 1); @@ -732,14 +735,10 @@ xhci_control(usbdev_t *const dev, const direction_t dir, return transferred; } -/* finalize == 1: if data is of packet aligned size, add a zero length packet */ static int -xhci_bulk(endpoint_t *const ep, const int size, u8 *const src, - const int finalize) +xhci_bulk_timeout(endpoint_t *const ep, const int size, u8 *const src, + int timeout_us) { - /* finalize: Hopefully the xHCI controller always does this. - We have no control over the packets. */ - u8 *data = src; xhci_t *const xhci = XHCI_INST(ep->dev->controller); const int slot_id = ep->dev->address; @@ -777,9 +776,9 @@ xhci_bulk(endpoint_t *const ep, const int size, u8 *const src, xhci_ring_doorbell(ep); /* Wait for transfer event */ - const int ret = xhci_wait_for_transfer(xhci, ep->dev->address, ep_id); + const int ret = xhci_wait_for_transfer(xhci, ep->dev->address, ep_id, timeout_us); if (ret < 0) { - if (ret == TIMEOUT) { + if (ret == USB_TIMEOUT) { xhci_debug("Stopping ID %d EP %d\n", ep->dev->address, ep_id); xhci_cmd_stop_endpoint(xhci, ep->dev->address, ep_id); @@ -798,6 +797,11 @@ xhci_bulk(endpoint_t *const ep, const int size, u8 *const src, return ret; } +static int xhci_bulk(endpoint_t *ep, int size, u8 *data, int finalize) +{ + return xhci_bulk_timeout(ep, size, data, USB_MAX_PROCESSING_TIME_US); +} + static trb_t * xhci_next_trb(trb_t *cur, int *const pcs) { diff --git a/payloads/libpayload/drivers/usb/xhci_commands.c b/payloads/libpayload/drivers/usb/xhci_commands.c index a4078030c6f..1cebb5432ae 100644 --- a/payloads/libpayload/drivers/usb/xhci_commands.c +++ b/payloads/libpayload/drivers/usb/xhci_commands.c @@ -69,7 +69,7 @@ xhci_wait_for_command(xhci_t *const xhci, int cc; cc = xhci_wait_for_command_done(xhci, cmd_trb, clear_event); - if (cc != TIMEOUT) + if (cc != USB_TIMEOUT) return cc; /* Abort command on timeout */ diff --git a/payloads/libpayload/drivers/usb/xhci_events.c b/payloads/libpayload/drivers/usb/xhci_events.c index 139ea59619d..3c36a313558 100644 --- a/payloads/libpayload/drivers/usb/xhci_events.c +++ b/payloads/libpayload/drivers/usb/xhci_events.c @@ -232,7 +232,7 @@ xhci_wait_for_event_type(xhci_t *const xhci, * * Process events from xHCI Abort command. * - * Returns CC_COMMAND_RING_STOPPED on success and TIMEOUT on failure. + * Returns CC_COMMAND_RING_STOPPED on success and USB_TIMEOUT on failure. */ int @@ -244,7 +244,7 @@ xhci_wait_for_command_aborted(xhci_t *const xhci, const trb_t *const address) * what to do then. */ unsigned long timeout_us = USB_MAX_PROCESSING_TIME_US; /* 5s */ - int cc = TIMEOUT; + int cc = USB_TIMEOUT; /* * Expects two command completion events: * The first with CC == COMMAND_ABORTED should point to address @@ -292,7 +292,7 @@ xhci_wait_for_command_aborted(xhci_t *const xhci, const trb_t *const address) /* * returns cc of command in question (pointed to by `address`) - * caller should abort command if cc is TIMEOUT + * caller should abort command if cc is USB_TIMEOUT */ int xhci_wait_for_command_done(xhci_t *const xhci, @@ -300,7 +300,7 @@ xhci_wait_for_command_done(xhci_t *const xhci, const int clear_event) { unsigned long timeout_us = USB_MAX_PROCESSING_TIME_US; /* 5s */ - int cc = TIMEOUT; + int cc = USB_TIMEOUT; while (xhci_wait_for_event_type(xhci, TRB_EV_CMD_CMPL, &timeout_us)) { if ((xhci->er.cur->ptr_low == virt_to_phys(address)) && (xhci->er.cur->ptr_high == 0)) { @@ -321,12 +321,11 @@ xhci_wait_for_command_done(xhci_t *const xhci, /* returns amount of bytes transferred on success, negative CC on error */ int -xhci_wait_for_transfer(xhci_t *const xhci, const int slot_id, const int ep_id) +xhci_wait_for_transfer(xhci_t *const xhci, const int slot_id, const int ep_id, + unsigned long timeout_us) { xhci_spew("Waiting for transfer on ID %d EP %d\n", slot_id, ep_id); - /* 5s for all types of transfers */ - unsigned long timeout_us = USB_MAX_PROCESSING_TIME_US; - int ret = TIMEOUT; + int ret = USB_TIMEOUT; while (xhci_wait_for_event_type(xhci, TRB_EV_TRANSFER, &timeout_us)) { if (TRB_GET(ID, xhci->er.cur) == slot_id && TRB_GET(EP, xhci->er.cur) == ep_id) { diff --git a/payloads/libpayload/drivers/usb/xhci_private.h b/payloads/libpayload/drivers/usb/xhci_private.h index 45c301391e3..c9464ce4236 100644 --- a/payloads/libpayload/drivers/usb/xhci_private.h +++ b/payloads/libpayload/drivers/usb/xhci_private.h @@ -45,8 +45,7 @@ #define MASK(startbit, lenbit) (((1<<(lenbit))-1)<<(startbit)) -/* Make these high enough to not collide with negative XHCI CCs */ -#define TIMEOUT -65 +/* Make these high enough to not collide with negative XHCI CCs and generic USB_TIMEOUT */ #define CONTROLLER_ERROR -66 #define COMMUNICATION_ERROR -67 #define OUT_OF_MEMORY -68 @@ -496,7 +495,8 @@ void xhci_update_event_dq(xhci_t *); void xhci_handle_events(xhci_t *); int xhci_wait_for_command_aborted(xhci_t *, const trb_t *); int xhci_wait_for_command_done(xhci_t *, const trb_t *, int clear_event); -int xhci_wait_for_transfer(xhci_t *, const int slot_id, const int ep_id); +int xhci_wait_for_transfer(xhci_t *, const int slot_id, const int ep_id, + unsigned long timeout_us); void xhci_clear_trb(trb_t *, int pcs); diff --git a/payloads/libpayload/include/coreboot_tables.h b/payloads/libpayload/include/coreboot_tables.h index 2f5b9be2287..9864c2b5d4d 100644 --- a/payloads/libpayload/include/coreboot_tables.h +++ b/payloads/libpayload/include/coreboot_tables.h @@ -85,6 +85,7 @@ enum { CB_TAG_TYPE_C_INFO = 0x0042, CB_TAG_ACPI_RSDP = 0x0043, CB_TAG_PCIE = 0x0044, + CB_TAG_PANEL_POWEROFF = 0x0049, CB_TAG_CMOS_OPTION_TABLE = 0x00c8, CB_TAG_OPTION = 0x00c9, CB_TAG_OPTION_ENUM = 0x00ca, @@ -122,6 +123,7 @@ struct cb_memory_range { #define CB_MEM_UNUSABLE 5 #define CB_MEM_VENDOR_RSVD 6 #define CB_MEM_TABLE 16 +#define CB_MEM_TAG 17 struct cb_memory { u32 tag; @@ -445,9 +447,22 @@ struct cb_acpi_rsdp { cb_uint64_t rsdp_pointer; /* Address of the ACPI RSDP */ }; +struct cb_panel_poweroff { + uint32_t tag; + uint32_t size; + + /* MIPI DSI poweroff commands from panel_serializable_data. */ + uint8_t cmd[]; +}; + enum boot_mode_t { + /* Regular boot scenarios */ CB_BOOT_MODE_NORMAL, + /* Device is booting in low-batter w/o charger attached */ CB_BOOT_MODE_LOW_BATTERY, + /* Device is booting in low-batter w/ charger attached */ + CB_BOOT_MODE_LOW_BATTERY_CHARGING, + /* Device is booting in due to charger insertion */ CB_BOOT_MODE_OFFMODE_CHARGING, }; diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h index 86429144ec6..6125fe0285e 100644 --- a/payloads/libpayload/include/libpayload.h +++ b/payloads/libpayload/include/libpayload.h @@ -47,6 +47,7 @@ #include #if CONFIG(LP_GPL) #include +#include #else #include #endif diff --git a/payloads/libpayload/include/lz4.h b/payloads/libpayload/include/lz4.h index 249afb3a41a..3879f47ab97 100644 --- a/payloads/libpayload/include/lz4.h +++ b/payloads/libpayload/include/lz4.h @@ -34,6 +34,9 @@ #include +#define LZ4F_MAGICNUMBER 0x184D2204 +#define LZ4_LEGACY_MAGICNUMBER 0x184C2102 + /* Decompresses an LZ4F image (multiple LZ4 blocks with frame header) from src * to dst, ensuring that it doesn't read more than srcn bytes and doesn't write * more than dstn. Buffer sizes must stay below 2GB. Can decompress files loaded diff --git a/payloads/libpayload/include/riscv/arch/asm.h b/payloads/libpayload/include/riscv/arch/asm.h new file mode 100644 index 00000000000..5d8eae20e27 --- /dev/null +++ b/payloads/libpayload/include/riscv/arch/asm.h @@ -0,0 +1,23 @@ +/* + * + * Copyright 2013 Google Inc. + * + */ + +#ifndef __RISCV64_ASM_H +#define __RISCV64_ASM_H + +#define ENDPROC(name) \ + .type name, %function; \ + END(name) + +#define ENTRY(name) \ + .section .text.name, "ax", %progbits; \ + .global name; \ + .align 2; \ + name: + +#define END(name) \ + .size name, .-name + +#endif /* __RISCV64_ASM_H */ diff --git a/payloads/libpayload/include/riscv/arch/cache.h b/payloads/libpayload/include/riscv/arch/cache.h new file mode 100644 index 00000000000..d47b05dd410 --- /dev/null +++ b/payloads/libpayload/include/riscv/arch/cache.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef RISCV64_CACHE_H +#define RISCV64_CACHE_H + +#include +#include + +/* tlb invalidate all */ +void tlb_invalidate_all(void); + +void dcache_clean_invalidate_all(void); + +/* Invalidate all of the instruction cache for PE to PoU. */ +static inline void icache_invalidate_all(void) +{ + __asm__ __volatile__("fence.i\n\t"); +} + + +#endif /* RISCV64_CACHE_H */ diff --git a/payloads/libpayload/include/riscv/arch/io.h b/payloads/libpayload/include/riscv/arch/io.h new file mode 100644 index 00000000000..b586204bfe5 --- /dev/null +++ b/payloads/libpayload/include/riscv/arch/io.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ARCH_IO_H +#define _ARCH_IO_H + +#include +#include + +#define fence_i_r() __asm__ __volatile__("fence i,r" : : : "memory") +#define fence_ow_ow() __asm__ __volatile__("fence ow,ow" : : : "memory") + +/* + * readb/w/l writeb/w/l are deprecated. use read8/16/32 and write8/16/32 + * instead for future development. + */ + +static inline uint8_t readb(volatile const void *_a) +{ + return *(volatile const uint8_t *)_a; + fence_i_r(); +} + +static inline uint16_t readw(volatile const void *_a) +{ + return *(volatile const uint16_t *)_a; + fence_i_r(); +} + +static inline uint32_t readl(volatile const void *_a) +{ + return *(volatile const uint32_t *)_a; + fence_i_r(); +} + +static inline void writeb(uint8_t _v, volatile void *_a) +{ + fence_ow_ow(); + *(volatile uint8_t *)_a = _v; +} + +static inline void writew(uint16_t _v, volatile void *_a) +{ + fence_ow_ow(); + *(volatile uint16_t *)_a = _v; +} + +static inline void writel(uint32_t _v, volatile void *_a) +{ + fence_ow_ow(); + *(volatile uint32_t *)_a = _v; +} + +/* + * TODO: make the existing code use read8/16/32 and write8/16/32 then remove + * readb/w/l and writeb/w/l. + */ + +static inline uint8_t read8(volatile const void *addr) +{ + return *(volatile uint8_t *)addr; + fence_i_r(); +} + +static inline uint16_t read16(volatile const void *addr) +{ + return *(volatile uint16_t *)addr; + fence_i_r(); +} + +static inline uint32_t read32(volatile const void *addr) +{ + return *(volatile uint32_t *)addr; + fence_i_r(); +} + +static inline uint64_t read64(volatile const void *addr) +{ + return *(volatile uint64_t *)addr; + fence_i_r(); +} + +static inline void write8(volatile void *addr, uint8_t val) +{ + fence_ow_ow(); + *(volatile uint8_t *)addr = val; +} + +static inline void write16(volatile void *addr, uint16_t val) +{ + fence_ow_ow(); + *(volatile uint16_t *)addr = val; +} + +static inline void write32(volatile void *addr, uint32_t val) +{ + fence_ow_ow(); + *(volatile uint32_t *)addr = val; +} + +static inline void write64(volatile void *addr, uint64_t val) +{ + fence_ow_ow(); + *(volatile uint64_t *)addr = val; +} + +#endif diff --git a/payloads/libpayload/include/riscv/arch/types.h b/payloads/libpayload/include/riscv/arch/types.h new file mode 100644 index 00000000000..044e047f37c --- /dev/null +++ b/payloads/libpayload/include/riscv/arch/types.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ARCH_TYPES_H +#define _ARCH_TYPES_H + +typedef unsigned char uint8_t; +typedef unsigned char u8; +typedef signed char int8_t; +typedef signed char s8; + +typedef unsigned short uint16_t; +typedef unsigned short u16; +typedef signed short int16_t; +typedef signed short s16; + +typedef unsigned int uint32_t; +typedef unsigned int u32; +typedef signed int int32_t; +typedef signed int s32; + +typedef unsigned long long uint64_t; +typedef unsigned long long u64; +typedef signed long long int64_t; +typedef signed long long s64; + +typedef long time_t; +typedef long suseconds_t; + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#endif diff --git a/payloads/libpayload/include/riscv/arch/virtual.h b/payloads/libpayload/include/riscv/arch/virtual.h new file mode 100644 index 00000000000..4b107787d23 --- /dev/null +++ b/payloads/libpayload/include/riscv/arch/virtual.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _ARCH_VIRTUAL_H +#define _ARCH_VIRTUAL_H + +extern unsigned long virtual_offset; + +#define virt_to_phys(virt) ((unsigned long) (virt) + virtual_offset) +#define phys_to_virt(phys) ((void *) ((unsigned long) (phys) - virtual_offset)) + +#define virt_to_bus(addr) virt_to_phys(addr) +#define bus_to_virt(addr) phys_to_virt(addr) + +#endif diff --git a/payloads/libpayload/include/stdio.h b/payloads/libpayload/include/stdio.h index ced4d19b99d..d19d3aa847b 100644 --- a/payloads/libpayload/include/stdio.h +++ b/payloads/libpayload/include/stdio.h @@ -41,14 +41,10 @@ extern FILE *stdout, *stdin, *stderr; * @defgroup printf Print functions * @{ */ -int snprintf(char *str, size_t size, const char *fmt, ...) - __attribute__((format (printf, 3, 4))); -int sprintf(char *str, const char *fmt, ...) - __attribute__((format (printf, 2, 3))); -int printf(const char *fmt, ...) - __attribute__((format (printf, 1, 2))); -int fprintf(FILE *file, const char *fmt, ...) - __attribute__((format (printf, 2, 3))); +int snprintf(char *str, size_t size, const char *fmt, ...) __printf(3, 4); +int sprintf(char *str, const char *fmt, ...) __printf(2, 3); +int printf(const char *fmt, ...) __printf(1, 2); +int fprintf(FILE *file, const char *fmt, ...) __printf(2, 3); /** @} */ void perror(const char *s); diff --git a/payloads/libpayload/include/sysinfo.h b/payloads/libpayload/include/sysinfo.h index f18ad62308d..324233170ee 100644 --- a/payloads/libpayload/include/sysinfo.h +++ b/payloads/libpayload/include/sysinfo.h @@ -34,8 +34,8 @@ /* Maximum number of memory range definitions. */ #define SYSINFO_MAX_MEM_RANGES 32 -/* Allow a maximum of 8 GPIOs */ -#define SYSINFO_MAX_GPIOS 8 +/* Allow a maximum of 10 GPIOs */ +#define SYSINFO_MAX_GPIOS 10 /* Up to 10 MAC addresses */ #define SYSINFO_MAX_MACS 10 @@ -180,6 +180,7 @@ struct sysinfo_t { enum boot_mode_t boot_mode; uintptr_t memory_info; + uintptr_t cb_panel_poweroff; }; extern struct sysinfo_t lib_sysinfo; diff --git a/payloads/libpayload/include/usb/usb.h b/payloads/libpayload/include/usb/usb.h index 43c7b4279d8..9e929e59c85 100644 --- a/payloads/libpayload/include/usb/usb.h +++ b/payloads/libpayload/include/usb/usb.h @@ -231,6 +231,12 @@ struct usbdev { typedef enum { OHCI = 0, UHCI = 1, EHCI = 2, XHCI = 3, DWC2 = 4} hc_type; +/* + * Use higher value so it is less likely to conflict with error codes that + * controller drivers may already use. + */ +#define USB_TIMEOUT -65 + struct usbdev_hc { hci_t *next; uintptr_t reg_base; @@ -255,6 +261,10 @@ struct usbdev_hc { void (*shutdown) (hci_t *controller); int (*bulk) (endpoint_t *ep, int size, u8 *data, int finalize); + /* bulk_timeout(): Perform bulk transfer, but timeout after + specified time in us. Returns + USB_TIMEOUT in that case. */ + int (*bulk_timeout) (endpoint_t *ep, int size, u8 *data, int timeout_us); int (*control) (usbdev_t *dev, direction_t pid, int dr_length, void *devreq, int data_length, u8 *data); void* (*create_intr_queue) (endpoint_t *ep, int reqsize, int reqcount, int reqtiming); @@ -334,7 +344,7 @@ int usb_interface_check(u16 vendor, u16 device); #define USB_QUIRK_TEST (1 << 31) #define USB_QUIRK_NONE 0 -static inline void __attribute__((format(printf, 1, 2))) usb_debug(const char *fmt, ...) +static inline void __printf(1, 2) usb_debug(const char *fmt, ...) { #ifdef USB_DEBUG va_list ap; diff --git a/payloads/libpayload/libc/Makefile.mk b/payloads/libpayload/libc/Makefile.mk index 063118a925c..45152f135c6 100644 --- a/payloads/libpayload/libc/Makefile.mk +++ b/payloads/libpayload/libc/Makefile.mk @@ -52,5 +52,6 @@ libc-srcs += $(coreboottop)/src/commonlib/bsd/string.c ifeq ($(CONFIG_LP_GPL),y) libc-srcs += $(coreboottop)/src/commonlib/device_tree.c libc-srcs += $(coreboottop)/src/commonlib/list.c +libc-srcs += $(coreboottop)/src/commonlib/mipi/cmd.c endif endif diff --git a/payloads/libpayload/libc/coreboot.c b/payloads/libpayload/libc/coreboot.c index b1be37c19e8..bd05d7c04a2 100644 --- a/payloads/libpayload/libc/coreboot.c +++ b/payloads/libpayload/libc/coreboot.c @@ -301,6 +301,11 @@ static void cb_parse_rsdp(void *ptr, struct sysinfo_t *info) info->acpi_rsdp = cb_acpi_rsdp->rsdp_pointer; } +static void cb_parse_panel_poweroff(unsigned char *ptr, struct sysinfo_t *info) +{ + info->cb_panel_poweroff = virt_to_phys(ptr); +} + int cb_parse_header(void *addr, int len, struct sysinfo_t *info) { struct cb_header *header; @@ -447,6 +452,9 @@ int cb_parse_header(void *addr, int len, struct sysinfo_t *info) case CB_TAG_PCIE: cb_parse_pcie(ptr, info); break; + case CB_TAG_PANEL_POWEROFF: + cb_parse_panel_poweroff(ptr, info); + break; case CB_TAG_BOOT_MODE: cb_parse_boot_mode(ptr, info); break; diff --git a/payloads/libpayload/liblz4/lz4_wrapper.c b/payloads/libpayload/liblz4/lz4_wrapper.c index 160d5dcb743..f80ccc7178b 100644 --- a/payloads/libpayload/liblz4/lz4_wrapper.c +++ b/payloads/libpayload/liblz4/lz4_wrapper.c @@ -73,9 +73,6 @@ typedef uint64_t U64; /* Unaltered (just removed unrelated code) from github.com/Cyan4973/lz4/dev. */ #include "lz4.c.inc" /* #include for inlining, do not link! */ -#define LZ4F_MAGICNUMBER 0x184D2204 -#define LEGACY_MAGICNUMBER 0x184C2102 - struct lz4_frame_header { uint32_t magic; union { @@ -198,7 +195,7 @@ size_t ulz4ln(const void *src, size_t srcn, void *dst, size_t dstn) void *out = dst; size_t out_size = 0; - if (le32toh(*((const uint32_t *)in)) != LEGACY_MAGICNUMBER) + if (le32toh(*((const uint32_t *)in)) != LZ4_LEGACY_MAGICNUMBER) return 0; in += sizeof(uint32_t); diff --git a/payloads/libpayload/tests/Makefile.mk b/payloads/libpayload/tests/Makefile.mk index a6cee5f480f..6b6c78d8353 100644 --- a/payloads/libpayload/tests/Makefile.mk +++ b/payloads/libpayload/tests/Makefile.mk @@ -274,7 +274,8 @@ clean-junit.xml-unit-tests: ifeq ($(COV),1) coverage-report: lcov -o $(testobj)/tests.info -c -d $(testobj) --exclude '$(testsrc)/*' - genhtml -q -o $(coverage-dir) -t "coreboot unit tests" -s $(testobj)/tests.info + # TODO: figure out issues with inconsistent and corrupt data + # genhtml -q -o $(coverage-dir) -t "coreboot unit tests" -s $(testobj)/tests.info clean-coverage-report: rm -Rf $(coverage-dir) diff --git a/spd/lp5/memory_parts.json b/spd/lp5/memory_parts.json index c012c2eb502..a38e0ac23f4 100644 --- a/spd/lp5/memory_parts.json +++ b/spd/lp5/memory_parts.json @@ -413,6 +413,60 @@ "ranksPerChannel": 1, "speedMbps": 6400 } + }, + { + "name": "MT62F2G32D4DS-031RF WT:C", + "attribs": { + "densityPerDieGb": 16, + "diesPerPackage": 4, + "bitWidthPerChannel": 16, + "ranksPerChannel": 2, + "speedMbps": 6400 + } + }, + { + "name": "RS1G32LO5D2FDB-23BT", + "attribs": { + "densityPerDieGb": 16, + "diesPerPackage": 2, + "bitWidthPerChannel": 16, + "ranksPerChannel": 1, + "speedMbps": 8533, + "lp5x": true + } + }, + { + "name": "BWMYAX32P8A-32G", + "attribs": { + "densityPerDieGb": 16, + "diesPerPackage": 2, + "bitWidthPerChannel": 16, + "ranksPerChannel": 1, + "speedMbps": 7500, + "lp5x": true + } + }, + { + "name": "MT62F2G32D4DS-020 WT:D", + "attribs": { + "densityPerDieGb": 16, + "diesPerPackage": 4, + "bitWidthPerChannel": 16, + "ranksPerChannel": 2, + "speedMbps": 8533, + "lp5x": true + } + }, + { + "name": "H58G56DK9BX068", + "attribs": { + "densityPerDieGb": 16, + "diesPerPackage": 2, + "bitWidthPerChannel": 16, + "ranksPerChannel": 1, + "speedMbps": 9600, + "lp5x": true + } } ] } diff --git a/spd/lp5/set-0/parts_spd_manifest.generated.txt b/spd/lp5/set-0/parts_spd_manifest.generated.txt index 9566fc27521..ac104fc0104 100644 --- a/spd/lp5/set-0/parts_spd_manifest.generated.txt +++ b/spd/lp5/set-0/parts_spd_manifest.generated.txt @@ -40,3 +40,8 @@ K3KLALA0EM-MGCU,spd-13.hex MT62F1G32D2DS-020 WT:D,spd-11.hex K3KL8L80EM-MGCV,spd-11.hex MT62F1G32D2DS-031RF WT:C,spd-3.hex +MT62F2G32D4DS-031RF WT:C,spd-6.hex +RS1G32LO5D2FDB-23BT,spd-11.hex +BWMYAX32P8A-32G,spd-7.hex +MT62F2G32D4DS-020 WT:D,spd-10.hex +H58G56DK9BX068,spd-14.hex diff --git a/spd/lp5/set-0/spd-14.hex b/spd/lp5/set-0/spd-14.hex index fb1b5a43c42..f9bb5a2eafd 100644 --- a/spd/lp5/set-0/spd-14.hex +++ b/spd/lp5/set-0/spd-14.hex @@ -1,11 +1,11 @@ -23 10 15 0E 16 22 91 08 00 00 00 00 0A 01 00 00 -00 00 08 00 00 00 00 00 AD 00 90 A8 90 C0 08 60 +23 10 15 0E 16 22 95 08 00 00 00 00 02 01 00 00 +00 00 07 00 00 00 00 00 AE 00 90 A8 90 C0 08 60 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 B6 00 C1 00 00 +00 00 00 00 00 00 00 00 00 00 00 A4 00 D6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/spd/lp5/set-1/parts_spd_manifest.generated.txt b/spd/lp5/set-1/parts_spd_manifest.generated.txt index 9566fc27521..ac104fc0104 100644 --- a/spd/lp5/set-1/parts_spd_manifest.generated.txt +++ b/spd/lp5/set-1/parts_spd_manifest.generated.txt @@ -40,3 +40,8 @@ K3KLALA0EM-MGCU,spd-13.hex MT62F1G32D2DS-020 WT:D,spd-11.hex K3KL8L80EM-MGCV,spd-11.hex MT62F1G32D2DS-031RF WT:C,spd-3.hex +MT62F2G32D4DS-031RF WT:C,spd-6.hex +RS1G32LO5D2FDB-23BT,spd-11.hex +BWMYAX32P8A-32G,spd-7.hex +MT62F2G32D4DS-020 WT:D,spd-10.hex +H58G56DK9BX068,spd-14.hex diff --git a/spd/lp5/set-1/spd-14.hex b/spd/lp5/set-1/spd-14.hex index 37203cc057b..8ecc7a190cb 100644 --- a/spd/lp5/set-1/spd-14.hex +++ b/spd/lp5/set-1/spd-14.hex @@ -1,11 +1,11 @@ -23 11 13 0E 86 21 91 18 00 40 00 00 0A 02 00 00 +23 11 13 0E 86 21 95 18 00 40 00 00 02 02 00 00 00 00 02 00 00 00 00 00 2C 00 90 A8 90 C0 08 60 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 8A 00 F0 00 00 +00 00 00 00 00 00 00 00 00 00 00 A4 00 D6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/Kconfig b/src/Kconfig index a7a34b26a53..dfd703630c6 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -151,7 +151,7 @@ choice prompt "Option backend to use" default USE_CBFS_FILE_OPTION_BACKEND if HAVE_CBFS_FILE_OPTION_BACKEND default USE_MAINBOARD_SPECIFIC_OPTION_BACKEND if HAVE_MAINBOARD_SPECIFIC_OPTION_BACKEND - default USE_OPTION_TABLE if NVRAMCUI_SECONDARY_PAYLOAD + default USE_OPTION_TABLE if NVRAMCUI_SECONDARY_PAYLOAD || MAINBOARD_NEEDS_CMOS_OPTIONS default USE_UEFI_VARIABLE_STORE if DRIVERS_EFI_VARIABLE_STORE && \ PAYLOAD_EDK2 && SMMSTORE_V2 @@ -202,10 +202,16 @@ config MB_COMPRESS_RAMSTAGE_LZ4 help Select this in a mainboard to use LZ4 compression by default +config MB_COMPRESS_RAMSTAGE_ZSTD + bool + help + Select this in a mainboard to use ZSTD compression by default + choice prompt "Ramstage compression" depends on HAVE_RAMSTAGE && !UNCOMPRESSED_RAMSTAGE default COMPRESS_RAMSTAGE_LZ4 if MB_COMPRESS_RAMSTAGE_LZ4 + default COMPRESS_RAMSTAGE_ZSTD if MB_COMPRESS_RAMSTAGE_ZSTD default COMPRESS_RAMSTAGE_LZMA config COMPRESS_RAMSTAGE_LZMA @@ -226,6 +232,13 @@ config COMPRESS_RAMSTAGE_LZ4 If you're not sure, stick with LZMA. +config COMPRESS_RAMSTAGE_ZSTD + bool "Compress ramstage with ZSTD" + help + Compress ramstage with ZSTD. + This is faster than LZMA but uses more BSS. + However it decompresses faster on slower CPUs and is suited for + platforms with high speed SPI interfaces, but limited computing power. endchoice config COMPRESS_PRERAM_STAGES @@ -347,6 +360,25 @@ config USE_QC_BLOBS mainboards cannot be built and will be hidden from the "Mainboards" section. +config QC_SECURE_BOOT_BLOBS + bool "Enable Qualcomm secure/signed blobs for fused SoCs" + depends on USE_QC_BLOBS + help + This option enables the inclusion of OEM-signed binaries and + secure-world components required for booting fused Qualcomm SoCs. + + When enabled, the build system will look for signed versions of + QcLib, QC-SEC, and secondary bootloader stages that match the + Root of Trust (RoT) fused into the SoC. + + Select this if you are building firmware for production hardware + or "fused" development units that enforce OEM signature + verification at the hardware level. + + Note: Using this option without the correct signing keys or + signed blobs will result in a bricked boot process on fused + hardware. + config COVERAGE bool "Code coverage support" depends on COMPILER_GCC @@ -891,6 +923,12 @@ config CMOS_LAYOUT_FILE default "src/mainboard/\$(MAINBOARDDIR)/cmos.layout" depends on HAVE_OPTION_TABLE +config MAINBOARD_NEEDS_CMOS_OPTIONS + bool + help + Select this option if a mainboard depends on storing options in CMOS + for the implementation of some feature. + config PCI_IO_CFG_EXT bool default n @@ -900,6 +938,13 @@ config IOAPIC default y if SMP default n +config IOAPIC_8BIT_ID + bool + default n + depends on IOAPIC + help + Select this option if the hardware support 8bit long IOAPIC IDs. + config USE_WATCHDOG_ON_BOOT bool default n @@ -986,6 +1031,13 @@ config SMBIOS_PROVIDED_BY_MOBO bool default n +config SMBIOS_TYPE4_SOCKETED_CPU + bool + default n + help + If enabled the CPU can be replaced and Type 4 advertises upgrade + support. + if GENERATE_SMBIOS_TABLES config BIOS_VENDOR diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index abdcf26160b..94b63092613 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -27,7 +27,11 @@ #include #include #include +#if CONFIG(AMD_CRB_FTPM) +#include +#else #include +#endif #include #include #include @@ -260,7 +264,7 @@ static void acpi_create_tpm2(acpi_header_t *header, void *unused) if (tlcl_get_family() != TPM_2) return; - if (CONFIG(CRB_TPM) && !(CONFIG(SPI_TPM) || CONFIG(I2C_TPM) || CONFIG(MEMORY_MAPPED_TPM))) + if ((CONFIG(CRB_TPM) || CONFIG(AMD_CRB_FTPM)) && !(CONFIG(SPI_TPM) || CONFIG(I2C_TPM) || CONFIG(MEMORY_MAPPED_TPM))) if (!crb_tpm_is_active()) return; @@ -281,14 +285,16 @@ static void acpi_create_tpm2(acpi_header_t *header, void *unused) /* Hard to detect for coreboot. Just set it to 0 */ tpm2->platform_class = 0; - if (CONFIG(CRB_TPM)) { - /* Must be set to 7 for CRB Support */ + + if (CONFIG(AMD_CRB_FTPM) && crb_tpm_is_active()) { + tpm2->control_area = crb_tpm_base_address() + 0x40; + tpm2->start_method = ACPI_TPM2_SM_ACPI_START; + } else if (CONFIG(CRB_TPM) && crb_tpm_is_active()) { tpm2->control_area = crb_tpm_base_address() + 0x40; - tpm2->start_method = 7; + tpm2->start_method = ACPI_TPM2_SM_CRB; } else { - /* Must be set to 0 for FIFO interface support */ tpm2->control_area = 0; - tpm2->start_method = 6; + tpm2->start_method = ACPI_TPM2_SM_MMIO_TIS; } memset(tpm2->msp, 0, sizeof(tpm2->msp)); diff --git a/src/acpi/acpigen_ps2_keybd.c b/src/acpi/acpigen_ps2_keybd.c index f8b58d739ba..38af89bfda8 100644 --- a/src/acpi/acpigen_ps2_keybd.c +++ b/src/acpi/acpigen_ps2_keybd.c @@ -179,6 +179,8 @@ static uint32_t rest_of_keymaps[] = { KEYMAP(0x3a, KEY_CAPSLOCK), /* Insert Key */ KEYMAP(0xd2, KEY_INSERT), + /* Screen Lock */ + KEYMAP(0xab, KEY_SCREENLOCK), }; static void ssdt_generate_physmap(struct acpi_dp *dp, uint8_t num_top_row_keys, diff --git a/src/acpi/dsdt_top.asl b/src/acpi/dsdt_top.asl index 7539f00e571..a99d80bbf49 100644 --- a/src/acpi/dsdt_top.asl +++ b/src/acpi/dsdt_top.asl @@ -57,22 +57,22 @@ Scope(\_SB) { Device (PERC) // PCI ECAM Resource Consumption { Name (_HID, EisaId("PNP0C02")) + Name (RBUF, ResourceTemplate () + { + QWordMemory (ResourceConsumer, PosDecode, MinFixed, MaxFixed, + NonCacheable, ReadWrite, + 0x0000000000000000, // Granularity + 0x0000000000000000, // _MIN + 0x0000000000000001, // _MAX + 0x0000000000000000, // Translation + 0x0000000000000002, // _Len + ,, _Y00, AddressRangeMemory, TypeStatic) + }) Method (_CRS, 0, Serialized) { - Name (RBUF, ResourceTemplate () - { - QWordMemory (ResourceConsumer, PosDecode, MinFixed, MaxFixed, - NonCacheable, ReadWrite, - 0x0000000000000000, // Granularity - 0x0000000000000000, // _MIN - 0x0000000000000001, // _MAX - 0x0000000000000000, // Translation - 0x0000000000000002, // _Len - ,, _Y00, AddressRangeMemory, TypeStatic) - }) - CreateQWordField (RBUF, \_SB.PERC._CRS._Y00._MIN, MIN1) - CreateQWordField (RBUF, \_SB.PERC._CRS._Y00._MAX, MAX1) - CreateQWordField (RBUF, \_SB.PERC._CRS._Y00._LEN, LEN1) + CreateQWordField (RBUF, \_SB.PERC._Y00._MIN, MIN1) + CreateQWordField (RBUF, \_SB.PERC._Y00._MAX, MAX1) + CreateQWordField (RBUF, \_SB.PERC._Y00._LEN, LEN1) MIN1 = CONFIG_ECAM_MMCONF_BASE_ADDRESS MAX1 = (MIN1 + CONFIG_ECAM_MMCONF_LENGTH -1) LEN1 = CONFIG_ECAM_MMCONF_LENGTH diff --git a/src/arch/arm/Makefile.mk b/src/arch/arm/Makefile.mk index ef87dcf14fa..89cca2b7931 100644 --- a/src/arch/arm/Makefile.mk +++ b/src/arch/arm/Makefile.mk @@ -4,10 +4,6 @@ # ARM specific options ############################################################################### -ifeq ($(CONFIG_ARCH_RAMSTAGE_ARM),y) -check-ramstage-overlap-regions += postram_cbfs_cache stack ttb -endif - ifeq ($(CONFIG_ARCH_ARM),y) subdirs-y += libgcc/ subdirs-y += armv4/ armv7/ @@ -99,6 +95,8 @@ endif # CONFIG_ARCH_ROMSTAGE_ARM ifeq ($(CONFIG_ARCH_RAMSTAGE_ARM),y) +check-ramstage-overlap-regions += postram_cbfs_cache stack ttb ramstage + ramstage-y += stages.c ramstage-y += div0.c ramstage-y += eabi_compat.c diff --git a/src/arch/arm64/Makefile.mk b/src/arch/arm64/Makefile.mk index 279d31fb470..efd628fee7d 100644 --- a/src/arch/arm64/Makefile.mk +++ b/src/arch/arm64/Makefile.mk @@ -6,14 +6,6 @@ subdirs-y += armv8/ -################################################################################ -# ARM specific options -################################################################################ - -ifeq ($(CONFIG_ARCH_RAMSTAGE_ARM64),y) -check-ramstage-overlap-regions += postram_cbfs_cache stack ttb -endif - ################################################################################ # bootblock ################################################################################ @@ -106,6 +98,8 @@ endif # CONFIG_ARCH_ROMSTAGE_ARM64 ifeq ($(CONFIG_ARCH_RAMSTAGE_ARM64),y) +check-ramstage-overlap-regions += postram_cbfs_cache stack ttb ramstage + ramstage-y += div0.c ramstage-y += eabi_compat.c ramstage-y += boot.c diff --git a/src/arch/ppc64/Makefile.mk b/src/arch/ppc64/Makefile.mk index 4a118b638af..9a4a2b01e7f 100644 --- a/src/arch/ppc64/Makefile.mk +++ b/src/arch/ppc64/Makefile.mk @@ -65,6 +65,8 @@ endif ################################################################################ ifeq ($(CONFIG_ARCH_RAMSTAGE_PPC64),y) +check-ramstage-overlap-regions += ramstage + ramstage-y += stages.c ramstage-y += arch_timer.c ramstage-y += boot.c diff --git a/src/arch/riscv/Makefile.mk b/src/arch/riscv/Makefile.mk index 95e439d5a92..cf393ba7007 100644 --- a/src/arch/riscv/Makefile.mk +++ b/src/arch/riscv/Makefile.mk @@ -5,10 +5,6 @@ ################################################################################ ifeq ($(CONFIG_ARCH_RISCV),y) -ifeq ($(CONFIG_ARCH_RAMSTAGE_RISCV),y) -check-ramstage-overlap-regions += stack -endif - riscv_flags = -I$(src)/arch/riscv/ ifeq ($(CONFIG_ARCH_RISCV_RV64),y) @@ -134,6 +130,8 @@ endif #CONFIG_ARCH_ROMSTAGE_RISCV ################################################################################ ifeq ($(CONFIG_ARCH_RAMSTAGE_RISCV),y) +check-ramstage-overlap-regions += stack ramstage + ramstage-y = ramstage-y += ramstage.S ramstage-y += tables.c diff --git a/src/arch/riscv/boot.c b/src/arch/riscv/boot.c index 6f744d32115..7d1cb3e92df 100644 --- a/src/arch/riscv/boot.c +++ b/src/arch/riscv/boot.c @@ -8,12 +8,58 @@ #include #include #include +#include +#include struct arch_prog_run_args { struct prog *prog; struct prog *opensbi; }; +/* + * At the moment devicetree is the default handoff format to the payload instead of + * coreboot tables (on RISC-V only). That may change in the future, but for now we will put a + * reference to the coreboot tables inside the FDT (similar to what we do in ACPI). + */ +static void *add_coreboot_table_to_fdt(void *fdt) +{ + if (!fdt || !fdt_is_valid(fdt)) { + printk(BIOS_ERR, "Invalid FDT provided\n"); + return fdt; + } + + void *coreboot_table = cbmem_find(CBMEM_ID_CBTABLE); + if (!coreboot_table) { + printk(BIOS_ERR, "coreboot table not found in CBMEM\n"); + return fdt; + } + + struct device_tree *tree = fdt_unflatten(fdt); + if (!tree) { + printk(BIOS_ERR, "Failed to unflatten FDT\n"); + return fdt; + } + + struct device_tree_node *chosen_node = dt_find_node_by_path(tree, "/chosen", NULL, NULL, 1); + if (!chosen_node) { + printk(BIOS_ERR, "Failed to find or create /chosen node\n"); + return fdt; + } + + printk(BIOS_INFO, "Adding cbtable@%p to fdt\n", coreboot_table); + dt_add_u64_prop(chosen_node, "coreboot-table", (uint64_t)(uintptr_t)coreboot_table); + + size_t next_size = dt_flat_size(tree); + void *next_fdt = malloc(next_size); + if (!next_fdt) { + printk(BIOS_ERR, "Failed to allocate memory for next-stage FDT\n"); + return fdt; + } + + dt_flatten(tree, next_fdt); + return next_fdt; +} + /* * A pointer to the Flattened Device Tree passed to coreboot by the boot ROM. * Presumably this FDT is also in ROM. @@ -51,14 +97,29 @@ void arch_prog_run(struct prog *prog) args.prog = prog; - /* In case of OpenSBI we have to load it before resuming all HARTs */ - if (ENV_RAMSTAGE && CONFIG(RISCV_OPENSBI)) { - struct prog sbi = PROG_INIT(PROG_OPENSBI, CONFIG_CBFS_PREFIX"/opensbi"); + if (ENV_RAMSTAGE) { + int hart_count = CONFIG_MAX_CPUS; + if (CONFIG(RISCV_GET_HART_COUNT_AT_RUNTIME)) + hart_count = smp_get_hart_count(); - if (!selfload_check(&sbi, BM_MEM_OPENSBI)) - die("OpenSBI load failed"); + /* Embed coreboot table pointer into fdt, so that payload can find it. */ + void *fdt = HLS()->fdt; + void *next_fdt = add_coreboot_table_to_fdt(fdt); - args.opensbi = &sbi; + /* Update per hart's fdt with "coreboot-table" node embedded */ + for (int i = 0; i < hart_count; i++) { + OTHER_HLS(i)->fdt = next_fdt; + } + + /* In case of OpenSBI we have to load it before resuming all HARTs */ + if (CONFIG(RISCV_OPENSBI)) { + struct prog sbi = PROG_INIT(PROG_OPENSBI, CONFIG_CBFS_PREFIX"/opensbi"); + + if (!selfload_check(&sbi, BM_MEM_OPENSBI)) + die("OpenSBI load failed"); + + args.opensbi = &sbi; + } } smp_resume((void (*)(void *))do_arch_prog_run, &args); diff --git a/src/arch/riscv/smp.c b/src/arch/riscv/smp.c index 67dc13b8fca..ab6e0add3a3 100644 --- a/src/arch/riscv/smp.c +++ b/src/arch/riscv/smp.c @@ -4,9 +4,25 @@ #include #include #include +#include #include #include +/* + * BSP + * --------------------------------- <--- + * AP | sync_b=HART_SLEEPING | | + * ---> --------------------------------- --------------------------------- | + * | | sync_a=HART_SLEEPING | ----> | Wait for sync_a=HART_SLEEPING | | + * | --------------------------------- --------------------------------- | + * | | Wait for Interrupt | <---- | set_msip() | | + * | --------------------------------- --------------------------------- | + * | | sync_a=HART_AWAKE | ----> | Wait for sync_a=HART_AWAKE | | + * | --------------------------------- --------------------------------- | + * | | Wait for sync_b=HART_AWAKE | <---- | sync_b=HART_AWAKE | | + * ---- --------------------------------- --------------------------------- ---- + */ + // made up value to sync hart state #define HART_SLEEPING 0x1 #define HART_AWAKE 0x2 @@ -29,6 +45,11 @@ void smp_pause(int working_hartid) } while ((read_csr(mip) & MIP_MSIP) == 0); atomic_set(&HLS()->entry.sync_a, HART_AWAKE); // mark the hart as awake + + // wait for working_hart to notice that this hart is awake + while (atomic_read(&HLS()->entry.sync_b) != HART_AWAKE) + ; + HLS()->entry.fn(HLS()->entry.arg); } } @@ -47,6 +68,8 @@ void smp_resume(void (*fn)(void *), void *arg) if (CONFIG(RISCV_GET_HART_COUNT_AT_RUNTIME)) hart_count = smp_get_hart_count(); + assert(hart_count <= CONFIG_MAX_CPUS); + // check that all harts are present u32 count_awake_harts = 0; @@ -55,6 +78,8 @@ void smp_resume(void (*fn)(void *), void *arg) if (i == working_hartid) continue; + atomic_set(&OTHER_HLS(i)->entry.sync_b, HART_SLEEPING); + if (atomic_read(&OTHER_HLS(i)->entry.sync_a) != HART_SLEEPING) { /* * we assmue here that the time between smp_pause and smp_resume @@ -83,6 +108,9 @@ void smp_resume(void (*fn)(void *), void *arg) // wait for hart to publish its waking state while (atomic_read(&OTHER_HLS(i)->entry.sync_a) != HART_AWAKE) ; + + // signal to hart that we noticed it woke up + atomic_set(&OTHER_HLS(i)->entry.sync_b, HART_AWAKE); count_awake_harts++; } printk(BIOS_DEBUG, "all harts up and running...\n"); diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig index d78aa8fa309..8e6babceb38 100644 --- a/src/arch/x86/Kconfig +++ b/src/arch/x86/Kconfig @@ -185,7 +185,7 @@ config BOOTBLOCK_DEBUG_SPINLOOP bool default n help - Add a spin (JMP .) in bootblock_crt0.S during early bootblock to wait + Add a spin (JMP .) in entry32.S during early bootblock to wait for a JTAG debugger to break into the execution sequence. config HAVE_CMOS_DEFAULT @@ -459,4 +459,11 @@ config SOC_FILL_CPU_CACHE_INFO default n help SoC selects this if it implements soc_fill_cpu_cache_info. + +config SOC_BERT_SIZEOF_ERROR_SECTION + bool + default n + help + SoC selects this if it implements soc_bert_sizeof_error_section. + endif diff --git a/src/arch/x86/Makefile.mk b/src/arch/x86/Makefile.mk index 0aaa962cfab..785d35c0aa6 100644 --- a/src/arch/x86/Makefile.mk +++ b/src/arch/x86/Makefile.mk @@ -224,6 +224,10 @@ $(CONFIG_CBFS_PREFIX)/postcar-compression := none ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32)$(CONFIG_ARCH_RAMSTAGE_X86_64),y) +# not adding a check-ramstage-overlap-regions here because x86 ramstage can automatically +# relocate itself to a free area (its build as a rmodule). Therefore no ramstage segments can +# overlap with other executables in RAM. + ramstage-y += acpi.c ramstage-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.c ramstage-$(CONFIG_ACPI_BERT) += acpi_bert_storage.c diff --git a/src/arch/x86/acpi_bert_storage.c b/src/arch/x86/acpi_bert_storage.c index 8b19403a5d1..efa1d078498 100644 --- a/src/arch/x86/acpi_bert_storage.c +++ b/src/arch/x86/acpi_bert_storage.c @@ -192,6 +192,11 @@ static size_t sizeof_error_section(guid_t *guid) else if (!guidcmp(guid, &CPER_SEC_FW_ERR_REC_REF_GUID)) return sizeof(cper_fw_err_rec_section_t); /* else if ... sizeof(structures not yet defined) */ + else if (CONFIG(SOC_BERT_SIZEOF_ERROR_SECTION)) { + size_t size = soc_bert_sizeof_error_section(guid); + if (size) + return size; + } printk(BIOS_ERR, "Requested size of unrecognized CPER GUID\n"); return 0; @@ -324,14 +329,14 @@ acpi_hest_generic_data_v300_t *bert_append_genproc( * CPER_IA32X64_CTX_32BIT_DBG * CPER_IA32X64_CTX_64BIT_DBG * CPER_IA32X64_CTX_MEMMAPPED - * num is the number of bytes eventually used to fill the context's register + * array_size_bytes is the size (in bytes) eventually used to fill the context's register * array, e.g. 4 MSRs * sizeof(msr_t) * * status and entry data_length values are updated. */ cper_ia32x64_context_t *new_cper_ia32x64_ctx( acpi_generic_error_status_t *status, - cper_ia32x64_proc_error_section_t *x86err, int type, int num) + cper_ia32x64_proc_error_section_t *x86err, int type, int array_size_bytes) { size_t size; cper_ia32x64_context_t *ctx; @@ -355,7 +360,7 @@ cper_ia32x64_context_t *new_cper_ia32x64_ctx( return NULL; } - size = cper_ia32x64_ctx_sz_bytype(type, num); + size = cper_ia32x64_ctx_sz_bytype(type, array_size_bytes); ctx = bert_allocate_storage(size); if (!ctx) { printk(BIOS_ERR, "New IA32X64 %s context entry would exceed available region\n", @@ -366,7 +371,7 @@ cper_ia32x64_context_t *new_cper_ia32x64_ctx( revise_error_sizes(status, size); ctx->type = type; - ctx->array_size = num; + ctx->array_size = array_size_bytes; cper_bump_ia32x64_ctx_count(x86err); return ctx; @@ -386,7 +391,7 @@ cper_ia32x64_proc_error_info_t *new_cper_ia32x64_check( cper_ia32x64_proc_error_section_t *x86err, enum cper_x86_check_type type) { - cper_ia32x64_proc_error_info_t *check; + cper_ia32x64_proc_error_info_t *proc_err_info; static const char * const check_names[] = { "cache", "TLB", @@ -409,19 +414,19 @@ cper_ia32x64_proc_error_info_t *new_cper_ia32x64_check( return NULL; } - check = bert_allocate_storage(sizeof(*check)); - if (!check) { + proc_err_info = bert_allocate_storage(sizeof(*proc_err_info)); + if (!proc_err_info) { printk(BIOS_ERR, "New IA32X64 %s check entry would exceed available region\n", check_names[type]); return NULL; } - revise_error_sizes(status, sizeof(*check)); + revise_error_sizes(status, sizeof(*proc_err_info)); - guidcpy(&check->type, &check_guids[type]); + guidcpy(&proc_err_info->type, &check_guids[type]); cper_bump_ia32x64_chk_count(x86err); - return check; + return proc_err_info; } /* Helper to append an ACPI Generic Error Data Entry plus a CPER IA32/X64 @@ -513,10 +518,10 @@ acpi_generic_error_status_t *bert_new_event(guid_t *guid) { size_t size; acpi_generic_error_status_t *status; - acpi_hest_generic_data_v300_t *entry, *r; + acpi_hest_generic_data_v300_t *r; size = sizeof(*status); - size += sizeof(*entry); + size += sizeof(*r); size += sizeof_error_section(guid); if (size > bert_storage_remaining()) { @@ -535,9 +540,8 @@ acpi_generic_error_status_t *bert_new_event(guid_t *guid) r = bert_append_ia32x64(status); else if (!guidcmp(guid, &CPER_SEC_FW_ERR_REC_REF_GUID)) r = bert_append_fw_err(status); - /* else if other types not implemented */ else - r = NULL; + r = bert_append_error_datasection(status, guid); if (r) return status; @@ -550,20 +554,21 @@ cper_ia32x64_context_t *cper_new_ia32x64_context_msr( cper_ia32x64_proc_error_section_t *x86err, u32 addr, int num) { cper_ia32x64_context_t *ctx; - int i; - msr_t *dest; - ctx = new_cper_ia32x64_ctx(status, x86err, CPER_IA32X64_CTX_MSR, num); + ctx = new_cper_ia32x64_ctx(status, x86err, CPER_IA32X64_CTX_MSR, num * sizeof(msr_t)); if (!ctx) return NULL; - /* already filled ctx->type = CPER_IA32X64_CTX_MSR; */ + /* + * already filled: + * - ctx->type = CPER_IA32X64_CTX_MSR + * - ctx->array_size = num * sizeof(msr_t) + */ ctx->msr_addr = addr; - ctx->array_size = num * sizeof(msr_t); - dest = (msr_t *)((u8 *)(ctx + 1)); /* point to the Register Array */ + msr_t *dest = (msr_t *)(ctx->register_array); /* point to the Register Array */ - for (i = 0 ; i < num ; i++) + for (int i = 0 ; i < num ; i++) *(dest + i) = rdmsr(addr + i); return ctx; } diff --git a/src/arch/x86/include/arch/bert_storage.h b/src/arch/x86/include/arch/bert_storage.h index d979d64000e..41c4f1c6e5d 100644 --- a/src/arch/x86/include/arch/bert_storage.h +++ b/src/arch/x86/include/arch/bert_storage.h @@ -50,6 +50,9 @@ */ void bert_errors_region(void **start, size_t *size); +/* Returns the size for SoC specific GUIDs */ +size_t soc_bert_sizeof_error_section(guid_t *guid); + /* Get amount of available storage left for error info */ size_t bert_storage_remaining(void); /* Find if errors were added, a BERT region is present, and ACPI table needed */ @@ -91,7 +94,7 @@ static inline acpi_hest_generic_data_v300_t *acpi_hest_generic_data3( /* Add a context to an existing IA32/X64-type error entry */ cper_ia32x64_context_t *new_cper_ia32x64_ctx( acpi_generic_error_status_t *status, - cper_ia32x64_proc_error_section_t *x86err, int type, int num); + cper_ia32x64_proc_error_section_t *x86err, int type, int array_size); /* Helper to add an MSR context to an existing IA32/X64-type error entry */ cper_ia32x64_context_t *cper_new_ia32x64_context_msr( diff --git a/src/arch/x86/include/arch/romstage.h b/src/arch/x86/include/arch/romstage.h index 063d4edd6b4..e0e82fd96ef 100644 --- a/src/arch/x86/include/arch/romstage.h +++ b/src/arch/x86/include/arch/romstage.h @@ -7,6 +7,19 @@ #include #include +/* + * Platform-specific hooks for logic surrounding memory initialization. + * + * platform_romstage_pre_mem() is invoked before memory training. + * + * platform_romstage_post_mem() is invoked after DRAM is initialized but + * before the transition to the RAM-based stack (Post-CAR). + * + * Default: No-op. These are weak symbols to be overridden by SoC or mainboard. + */ +void platform_romstage_pre_mem(void); +void platform_romstage_post_mem(void); + void mainboard_romstage_entry(void); /* diff --git a/src/arch/x86/ioapic.c b/src/arch/x86/ioapic.c index 4cde7c7f51f..792ba3e65e6 100644 --- a/src/arch/x86/ioapic.c +++ b/src/arch/x86/ioapic.c @@ -129,13 +129,21 @@ static void route_i8259_irq0(uintptr_t ioapic_base) static void set_ioapic_id(uintptr_t ioapic_base, u8 ioapic_id) { int i; + u32 reg; printk(BIOS_DEBUG, "IOAPIC: Initializing IOAPIC at %" PRIxPTR "\n", ioapic_base); printk(BIOS_DEBUG, "IOAPIC: ID = 0x%02x\n", ioapic_id); - io_apic_write(ioapic_base, 0x00, - (io_apic_read(ioapic_base, 0x00) & 0xf0ffffff) | (ioapic_id << 24)); + reg = io_apic_read(ioapic_base, 0x00); + + if (CONFIG(IOAPIC_8BIT_ID)) + reg &= 0x00ffffff; + else + reg &= 0xf0ffffff; + + reg |= (ioapic_id << 24); + io_apic_write(ioapic_base, 0x00, reg); printk(BIOS_SPEW, "IOAPIC: Dumping registers\n"); for (i = 0; i < 3; i++) diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c index 922340a886e..f0fa6a4bf63 100644 --- a/src/arch/x86/smbios.c +++ b/src/arch/x86/smbios.c @@ -64,6 +64,8 @@ static int get_socket_type(void) return PROCESSOR_UPGRADE_SOCKET_LGA3647_1; if (CONFIG(CPU_INTEL_SOCKET_OTHER)) return PROCESSOR_UPGRADE_OTHER; + if (CONFIG(SMBIOS_TYPE4_SOCKETED_CPU)) + return PROCESSOR_UPGRADE_OTHER; return PROCESSOR_UPGRADE_UNKNOWN; } diff --git a/src/commonlib/Makefile.mk b/src/commonlib/Makefile.mk index 91648c5170c..f71fff48921 100644 --- a/src/commonlib/Makefile.mk +++ b/src/commonlib/Makefile.mk @@ -1,6 +1,8 @@ ## SPDX-License-Identifier: GPL-2.0-only +subdirs-y += mipi subdirs-y += storage +subdirs-y += bsd/zstd bootblock-y += mem_pool.c verstage-y += mem_pool.c @@ -58,6 +60,7 @@ ramstage-y += bsd/lz4_wrapper.c postcar-y += bsd/lz4_wrapper.c all-y += list.c +all-y += bsd/zstd_wrapper.c ramstage-y += sort.c @@ -73,3 +76,5 @@ all-y += bsd/ipchksum.c decompressor-y += bsd/string.c smm-y += bsd/string.c all-y += bsd/string.c + +all-y += bsd/xxhash.c diff --git a/src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h b/src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h index b6a7baa20e3..7a0fb277555 100644 --- a/src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h +++ b/src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h @@ -10,6 +10,7 @@ enum cbfs_compression { CBFS_COMPRESS_NONE = 0, CBFS_COMPRESS_LZMA = 1, CBFS_COMPRESS_LZ4 = 2, + CBFS_COMPRESS_ZSTD = 3, }; enum cbfs_type { diff --git a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h index 20a1099f0a4..0431626f2ce 100644 --- a/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h +++ b/src/commonlib/bsd/include/commonlib/bsd/cbmem_id.h @@ -67,6 +67,7 @@ #define CBMEM_ID_TIMESTAMP 0x54494d45 #define CBMEM_ID_TPM2_TCG_LOG 0x54504d32 /* TPM log per TPM 2.0 specification */ #define CBMEM_ID_TPM_PPI 0x54505049 +#define CBMEM_ID_TPM2_CRB 0x43524220 #define CBMEM_ID_VBOOT_HANDOFF 0x780074f0 /* deprecated */ #define CBMEM_ID_VBOOT_SEL_REG 0x780074f1 /* deprecated */ #define CBMEM_ID_VBOOT_WORKBUF 0x78007343 @@ -92,6 +93,7 @@ #define CBMEM_ID_AMD_OPENSIL 0x4153494C #define CBMEM_ID_PVMFW 0x666d7670 #define CBMEM_ID_BOOT_MODE 0x444D5442 +#define CBMEM_ID_RB_INFO 0x50524249 #define CBMEM_ID_TO_NAME_TABLE \ { CBMEM_ID_ACPI, "ACPI " }, \ @@ -152,6 +154,7 @@ { CBMEM_ID_TIMESTAMP, "TIME STAMP " }, \ { CBMEM_ID_TPM2_TCG_LOG, "TPM2 TCGLOG" }, \ { CBMEM_ID_TPM_PPI, "TPM PPI " }, \ + { CBMEM_ID_TPM2_CRB, "TPM CRB " }, \ { CBMEM_ID_VBOOT_HANDOFF, "VBOOT " }, \ { CBMEM_ID_VBOOT_SEL_REG, "VBOOT SEL " }, \ { CBMEM_ID_VBOOT_WORKBUF, "VBOOT WORK " }, \ @@ -176,5 +179,6 @@ { CBMEM_ID_CSE_BP_INFO, "CSE BP INFO"}, \ { CBMEM_ID_AMD_OPENSIL, "OPENSIL DATA"}, \ { CBMEM_ID_PVMFW, "PVMFW "}, \ - { CBMEM_ID_BOOT_MODE, "BOOT MODE "} + { CBMEM_ID_BOOT_MODE, "BOOT MODE "}, \ + { CBMEM_ID_RB_INFO, "PCI RB INFO"} #endif /* _CBMEM_ID_H_ */ diff --git a/src/commonlib/bsd/include/commonlib/bsd/compression.h b/src/commonlib/bsd/include/commonlib/bsd/compression.h index 873e7e4e151..b13bc4c8b62 100644 --- a/src/commonlib/bsd/include/commonlib/bsd/compression.h +++ b/src/commonlib/bsd/include/commonlib/bsd/compression.h @@ -18,4 +18,7 @@ size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn); /* Same as ulz4fn() but does not perform any bounds checks. */ size_t ulz4f(const void *src, void *dst); +/* Decompresses ZSTD image */ +size_t uzstdn(const void *src, size_t srcn, void *dst, size_t dstn); + #endif /* _COMMONLIB_COMPRESSION_H_ */ diff --git a/src/include/xxhash.h b/src/commonlib/bsd/include/commonlib/bsd/xxhash.h similarity index 99% rename from src/include/xxhash.h rename to src/commonlib/bsd/include/commonlib/bsd/xxhash.h index f6340cb7914..a859b67d8a4 100644 --- a/src/include/xxhash.h +++ b/src/commonlib/bsd/include/commonlib/bsd/xxhash.h @@ -46,7 +46,8 @@ #ifndef XXHASH_H #define XXHASH_H -#include +#include +#include /*-**************************** * Simple Hash Functions diff --git a/src/lib/xxhash.c b/src/commonlib/bsd/xxhash.c similarity index 99% rename from src/lib/xxhash.c rename to src/commonlib/bsd/xxhash.c index c14fb968155..e6c9d2edb7e 100644 --- a/src/lib/xxhash.c +++ b/src/commonlib/bsd/xxhash.c @@ -9,10 +9,9 @@ * - xxHash source repository: https://github.com/Cyan4973/xxHash */ -#include +#include #include #include -#include /*-************************************* * Macros diff --git a/src/commonlib/bsd/zstd/Makefile.mk b/src/commonlib/bsd/zstd/Makefile.mk new file mode 100644 index 00000000000..d04ad31e98f --- /dev/null +++ b/src/commonlib/bsd/zstd/Makefile.mk @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +zstd_support=n +ifeq ($(CONFIG_COMPRESS_RAMSTAGE_ZSTD),y) +zstd_support=y +endif +ifeq ($(CONFIG_COMPRESSED_PAYLOAD_ZSTD),y) +zstd_support=y +endif + +ifeq ($(zstd_support),y) +all-y += decompress/huf_decompress.c +all-y += decompress/zstd_ddict.c +all-y += decompress/zstd_decompress_block.c +all-y += decompress/zstd_decompress.c + +all-y += common/entropy_common.c +all-y += common/fse_decompress.c + +CPPFLAGS_common += -DZSTD_DISABLE_ASM=1 +# Measured on Intel Sandy Bridge i5-2540M at 800Mhz: +# Setting code size reduction time loss +# -DHUF_FORCE_DECOMPRESS_X1=1 6.4 KiB 6% +# -DHUF_FORCE_DECOMPRESS_X2=1 5.4 KiB 7% +# -DZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT=1 8.1 KiB 19% +# -DZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG=1 7.8 KiB 15% + +CPPFLAGS_common += -DHUF_FORCE_DECOMPRESS_X1=1 +CPPFLAGS_common += -DZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT=1 +CPPFLAGS_common += -DZSTD_STRIP_ERROR_STRINGS=1 + +# Huffman fast decode needs 64bit and LE +CPPFLAGS_x86_32 += -DHUF_DISABLE_FAST_DECODE=1 +# Measured on Intel Sandy Bridge i5-2540M at 800Mhz (x86_64 only): +# Setting code size reduction time loss +# -DHUF_DISABLE_FAST_DECODE=1 2.3 KiB 5% + +CPPFLAGS_common += -DDYNAMIC_BMI2=0 -DSTATIC_BMI2=0 -DZSTD_DECODER_INTERNAL_BUFFER=2048 +endif + +CPPFLAGS_common += -I$(src)/commonlib/bsd/zstd +CPPFLAGS_common += -I$(src)/commonlib/bsd/zstd/common +CPPFLAGS_common += -I$(src)/commonlib/bsd/zstd/decompress diff --git a/src/commonlib/bsd/zstd/common/allocations.h b/src/commonlib/bsd/zstd/common/allocations.h new file mode 100644 index 00000000000..1bfa3db9e94 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/allocations.h @@ -0,0 +1,57 @@ + +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* This file provides custom allocation primitives + */ + +#define ZSTD_DEPS_NEED_MALLOC +#include "zstd_deps.h" /* ZSTD_malloc, ZSTD_calloc, ZSTD_free, ZSTD_memset */ + +#include "zstd_compiler.h" /* MEM_STATIC */ +#define ZSTD_STATIC_LINKING_ONLY +#include "../zstd.h" /* ZSTD_customMem */ + +#ifndef ZSTD_ALLOCATIONS_H +#define ZSTD_ALLOCATIONS_H + +/* custom memory allocation functions */ + +MEM_STATIC void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem) +{ + if (customMem.customAlloc) + return customMem.customAlloc(customMem.opaque, size); + return ZSTD_malloc(size); +} + +MEM_STATIC void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem) +{ + if (customMem.customAlloc) { + /* calloc implemented as malloc+memset; + * not as efficient as calloc, but next best guess for custom malloc */ + void* const ptr = customMem.customAlloc(customMem.opaque, size); + ZSTD_memset(ptr, 0, size); + return ptr; + } + return ZSTD_calloc(1, size); +} + +MEM_STATIC void ZSTD_customFree(void* ptr, ZSTD_customMem customMem) +{ + if (ptr!=NULL) { + if (customMem.customFree) + customMem.customFree(customMem.opaque, ptr); + else + ZSTD_free(ptr); + } +} + +#endif /* ZSTD_ALLOCATIONS_H */ diff --git a/src/commonlib/bsd/zstd/common/bitstream.h b/src/commonlib/bsd/zstd/common/bitstream.h new file mode 100644 index 00000000000..b0d433ff6fa --- /dev/null +++ b/src/commonlib/bsd/zstd/common/bitstream.h @@ -0,0 +1,456 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * bitstream + * Part of FSE library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ +#ifndef BITSTREAM_H_MODULE +#define BITSTREAM_H_MODULE + +/* +* This API consists of small unitary functions, which must be inlined for best performance. +* Since link-time-optimization is not available for all compilers, +* these functions are defined into a .h to be included. +*/ + +/*-**************************************** +* Dependencies +******************************************/ +#include "mem.h" /* unaligned access routines */ +#include "zstd_compiler.h" /* UNLIKELY() */ +#include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */ +#include "error_private.h" /* error codes and messages */ +#include "zstd_bits.h" /* ZSTD_highbit32 */ + +/*========================================= +* Target specific +=========================================*/ +#ifndef ZSTD_NO_INTRINSICS +# if (defined(__BMI__) || defined(__BMI2__)) && defined(__GNUC__) +# include /* support for bextr (experimental)/bzhi */ +# elif defined(__ICCARM__) +# include +# endif +#endif + +#define STREAM_ACCUMULATOR_MIN_32 25 +#define STREAM_ACCUMULATOR_MIN_64 57 +#define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64)) + + +/*-****************************************** +* bitStream encoding API (write forward) +********************************************/ +typedef size_t BitContainerType; +/* bitStream can mix input from multiple sources. + * A critical property of these streams is that they encode and decode in **reverse** direction. + * So the first bit sequence you add will be the last to be read, like a LIFO stack. + */ +typedef struct { + BitContainerType bitContainer; + unsigned bitPos; + char* startPtr; + char* ptr; + char* endPtr; +} BIT_CStream_t; + +MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity); +MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, BitContainerType value, unsigned nbBits); +MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC); +MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC); + +/* Start with initCStream, providing the size of buffer to write into. +* bitStream will never write outside of this buffer. +* `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code. +* +* bits are first added to a local register. +* Local register is BitContainerType, 64-bits on 64-bits systems, or 32-bits on 32-bits systems. +* Writing data into memory is an explicit operation, performed by the flushBits function. +* Hence keep track how many bits are potentially stored into local register to avoid register overflow. +* After a flushBits, a maximum of 7 bits might still be stored into local register. +* +* Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers. +* +* Last operation is to close the bitStream. +* The function returns the final size of CStream in bytes. +* If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable) +*/ + + +/*-******************************************** +* bitStream decoding API (read backward) +**********************************************/ +typedef struct { + BitContainerType bitContainer; + unsigned bitsConsumed; + const char* ptr; + const char* start; + const char* limitPtr; +} BIT_DStream_t; + +typedef enum { BIT_DStream_unfinished = 0, /* fully refilled */ + BIT_DStream_endOfBuffer = 1, /* still some bits left in bitstream */ + BIT_DStream_completed = 2, /* bitstream entirely consumed, bit-exact */ + BIT_DStream_overflow = 3 /* user requested more bits than present in bitstream */ + } BIT_DStream_status; /* result of BIT_reloadDStream() */ + +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize); +MEM_STATIC BitContainerType BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits); +MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD); +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD); + + +/* Start by invoking BIT_initDStream(). +* A chunk of the bitStream is then stored into a local register. +* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (BitContainerType). +* You can then retrieve bitFields stored into the local register, **in reverse order**. +* Local register is explicitly reloaded from memory by the BIT_reloadDStream() method. +* A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished. +* Otherwise, it can be less than that, so proceed accordingly. +* Checking if DStream has reached its end can be performed with BIT_endOfDStream(). +*/ + + +/*-**************************************** +* unsafe API +******************************************/ +MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, BitContainerType value, unsigned nbBits); +/* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */ + +MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC); +/* unsafe version; does not check buffer overflow */ + +MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits); +/* faster, but works only if nbBits >= 1 */ + +/*===== Local Constants =====*/ +static const unsigned BIT_mask[] = { + 0, 1, 3, 7, 0xF, 0x1F, + 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, + 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, + 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, + 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF, + 0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */ +#define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0])) + +/*-************************************************************** +* bitStream encoding +****************************************************************/ +/*! BIT_initCStream() : + * `dstCapacity` must be > sizeof(size_t) + * @return : 0 if success, + * otherwise an error code (can be tested using ERR_isError()) */ +MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, + void* startPtr, size_t dstCapacity) +{ + bitC->bitContainer = 0; + bitC->bitPos = 0; + bitC->startPtr = (char*)startPtr; + bitC->ptr = bitC->startPtr; + bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer); + if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall); + return 0; +} + +FORCE_INLINE_TEMPLATE BitContainerType BIT_getLowerBits(BitContainerType bitContainer, U32 const nbBits) +{ +#if STATIC_BMI2 && !defined(ZSTD_NO_INTRINSICS) +# if (defined(__x86_64__) || defined(_M_X64)) && !defined(__ILP32__) + return _bzhi_u64(bitContainer, nbBits); +# else + DEBUG_STATIC_ASSERT(sizeof(bitContainer) == sizeof(U32)); + return _bzhi_u32(bitContainer, nbBits); +# endif +#else + assert(nbBits < BIT_MASK_SIZE); + return bitContainer & BIT_mask[nbBits]; +#endif +} + +/*! BIT_addBits() : + * can add up to 31 bits into `bitC`. + * Note : does not check for register overflow ! */ +MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, + BitContainerType value, unsigned nbBits) +{ + DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32); + assert(nbBits < BIT_MASK_SIZE); + assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); + bitC->bitContainer |= BIT_getLowerBits(value, nbBits) << bitC->bitPos; + bitC->bitPos += nbBits; +} + +/*! BIT_addBitsFast() : + * works only if `value` is _clean_, + * meaning all high bits above nbBits are 0 */ +MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, + BitContainerType value, unsigned nbBits) +{ + assert((value>>nbBits) == 0); + assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8); + bitC->bitContainer |= value << bitC->bitPos; + bitC->bitPos += nbBits; +} + +/*! BIT_flushBitsFast() : + * assumption : bitContainer has not overflowed + * unsafe version; does not check buffer overflow */ +MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC) +{ + size_t const nbBytes = bitC->bitPos >> 3; + assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); + assert(bitC->ptr <= bitC->endPtr); + MEM_writeLEST(bitC->ptr, bitC->bitContainer); + bitC->ptr += nbBytes; + bitC->bitPos &= 7; + bitC->bitContainer >>= nbBytes*8; +} + +/*! BIT_flushBits() : + * assumption : bitContainer has not overflowed + * safe version; check for buffer overflow, and prevents it. + * note : does not signal buffer overflow. + * overflow will be revealed later on using BIT_closeCStream() */ +MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC) +{ + size_t const nbBytes = bitC->bitPos >> 3; + assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8); + assert(bitC->ptr <= bitC->endPtr); + MEM_writeLEST(bitC->ptr, bitC->bitContainer); + bitC->ptr += nbBytes; + if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr; + bitC->bitPos &= 7; + bitC->bitContainer >>= nbBytes*8; +} + +/*! BIT_closeCStream() : + * @return : size of CStream, in bytes, + * or 0 if it could not fit into dstBuffer */ +MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC) +{ + BIT_addBitsFast(bitC, 1, 1); /* endMark */ + BIT_flushBits(bitC); + if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */ + return (size_t)(bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0); +} + + +/*-******************************************************** +* bitStream decoding +**********************************************************/ +/*! BIT_initDStream() : + * Initialize a BIT_DStream_t. + * `bitD` : a pointer to an already allocated BIT_DStream_t structure. + * `srcSize` must be the *exact* size of the bitStream, in bytes. + * @return : size of stream (== srcSize), or an errorCode if a problem is detected + */ +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize) +{ + if (srcSize < 1) { ZSTD_memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } + + bitD->start = (const char*)srcBuffer; + bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer); + + if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */ + bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer); + bitD->bitContainer = MEM_readLEST(bitD->ptr); + { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; + bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */ + if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ } + } else { + bitD->ptr = bitD->start; + bitD->bitContainer = *(const BYTE*)(bitD->start); + switch(srcSize) + { + case 7: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16); + ZSTD_FALLTHROUGH; + + case 6: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24); + ZSTD_FALLTHROUGH; + + case 5: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32); + ZSTD_FALLTHROUGH; + + case 4: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[3]) << 24; + ZSTD_FALLTHROUGH; + + case 3: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[2]) << 16; + ZSTD_FALLTHROUGH; + + case 2: bitD->bitContainer += (BitContainerType)(((const BYTE*)(srcBuffer))[1]) << 8; + ZSTD_FALLTHROUGH; + + default: break; + } + { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1]; + bitD->bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; + if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */ + } + bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8; + } + + return srcSize; +} + +FORCE_INLINE_TEMPLATE BitContainerType BIT_getUpperBits(BitContainerType bitContainer, U32 const start) +{ + return bitContainer >> start; +} + +FORCE_INLINE_TEMPLATE BitContainerType BIT_getMiddleBits(BitContainerType bitContainer, U32 const start, U32 const nbBits) +{ + U32 const regMask = sizeof(bitContainer)*8 - 1; + /* if start > regMask, bitstream is corrupted, and result is undefined */ + assert(nbBits < BIT_MASK_SIZE); + /* x86 transform & ((1 << nbBits) - 1) to bzhi instruction, it is better + * than accessing memory. When bmi2 instruction is not present, we consider + * such cpus old (pre-Haswell, 2013) and their performance is not of that + * importance. + */ +#if defined(__x86_64__) || defined(_M_X64) + return (bitContainer >> (start & regMask)) & ((((U64)1) << nbBits) - 1); +#else + return (bitContainer >> (start & regMask)) & BIT_mask[nbBits]; +#endif +} + +/*! BIT_lookBits() : + * Provides next n bits from local register. + * local register is not modified. + * On 32-bits, maxNbBits==24. + * On 64-bits, maxNbBits==56. + * @return : value extracted */ +FORCE_INLINE_TEMPLATE BitContainerType BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) +{ + /* arbitrate between double-shift and shift+mask */ +#if 1 + /* if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8, + * bitstream is likely corrupted, and result is undefined */ + return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits); +#else + /* this code path is slower on my os-x laptop */ + U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; + return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask); +#endif +} + +/*! BIT_lookBitsFast() : + * unsafe version; only works if nbBits >= 1 */ +MEM_STATIC BitContainerType BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits) +{ + U32 const regMask = sizeof(bitD->bitContainer)*8 - 1; + assert(nbBits >= 1); + return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask); +} + +FORCE_INLINE_TEMPLATE void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits) +{ + bitD->bitsConsumed += nbBits; +} + +/*! BIT_readBits() : + * Read (consume) next n bits from local register and update. + * Pay attention to not read more than nbBits contained into local register. + * @return : extracted value. */ +FORCE_INLINE_TEMPLATE BitContainerType BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits) +{ + BitContainerType const value = BIT_lookBits(bitD, nbBits); + BIT_skipBits(bitD, nbBits); + return value; +} + +/*! BIT_readBitsFast() : + * unsafe version; only works if nbBits >= 1 */ +MEM_STATIC BitContainerType BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits) +{ + BitContainerType const value = BIT_lookBitsFast(bitD, nbBits); + assert(nbBits >= 1); + BIT_skipBits(bitD, nbBits); + return value; +} + +/*! BIT_reloadDStream_internal() : + * Simple variant of BIT_reloadDStream(), with two conditions: + * 1. bitstream is valid : bitsConsumed <= sizeof(bitD->bitContainer)*8 + * 2. look window is valid after shifted down : bitD->ptr >= bitD->start + */ +MEM_STATIC BIT_DStream_status BIT_reloadDStream_internal(BIT_DStream_t* bitD) +{ + assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8); + bitD->ptr -= bitD->bitsConsumed >> 3; + assert(bitD->ptr >= bitD->start); + bitD->bitsConsumed &= 7; + bitD->bitContainer = MEM_readLEST(bitD->ptr); + return BIT_DStream_unfinished; +} + +/*! BIT_reloadDStreamFast() : + * Similar to BIT_reloadDStream(), but with two differences: + * 1. bitsConsumed <= sizeof(bitD->bitContainer)*8 must hold! + * 2. Returns BIT_DStream_overflow when bitD->ptr < bitD->limitPtr, at this + * point you must use BIT_reloadDStream() to reload. + */ +MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD) +{ + if (UNLIKELY(bitD->ptr < bitD->limitPtr)) + return BIT_DStream_overflow; + return BIT_reloadDStream_internal(bitD); +} + +/*! BIT_reloadDStream() : + * Refill `bitD` from buffer previously set in BIT_initDStream() . + * This function is safe, it guarantees it will not never beyond src buffer. + * @return : status of `BIT_DStream_t` internal register. + * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */ +FORCE_INLINE_TEMPLATE BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD) +{ + /* note : once in overflow mode, a bitstream remains in this mode until it's reset */ + if (UNLIKELY(bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))) { + static const BitContainerType zeroFilled = 0; + bitD->ptr = (const char*)&zeroFilled; /* aliasing is allowed for char */ + /* overflow detected, erroneous scenario or end of stream: no update */ + return BIT_DStream_overflow; + } + + assert(bitD->ptr >= bitD->start); + + if (bitD->ptr >= bitD->limitPtr) { + return BIT_reloadDStream_internal(bitD); + } + if (bitD->ptr == bitD->start) { + /* reached end of bitStream => no update */ + if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer; + return BIT_DStream_completed; + } + /* start < ptr < limitPtr => cautious update */ + { U32 nbBytes = bitD->bitsConsumed >> 3; + BIT_DStream_status result = BIT_DStream_unfinished; + if (bitD->ptr - nbBytes < bitD->start) { + nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */ + result = BIT_DStream_endOfBuffer; + } + bitD->ptr -= nbBytes; + bitD->bitsConsumed -= nbBytes*8; + bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */ + return result; + } +} + +/*! BIT_endOfDStream() : + * @return : 1 if DStream has _exactly_ reached its end (all bits consumed). + */ +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream) +{ + return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); +} + +#endif /* BITSTREAM_H_MODULE */ diff --git a/src/commonlib/bsd/zstd/common/cpu.h b/src/commonlib/bsd/zstd/common/cpu.h new file mode 100644 index 00000000000..7f841fea6c3 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/cpu.h @@ -0,0 +1,251 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMMON_CPU_H +#define ZSTD_COMMON_CPU_H + +/** + * Implementation taken from folly/CpuId.h + * https://github.com/facebook/folly/blob/master/folly/CpuId.h + */ + +#include "mem.h" + +#ifdef _MSC_VER +#include +#endif + +typedef struct { + U32 f1c; + U32 f1d; + U32 f7b; + U32 f7c; +} ZSTD_cpuid_t; + +MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) { + U32 f1c = 0; + U32 f1d = 0; + U32 f7b = 0; + U32 f7c = 0; +#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) +#if !defined(_M_X64) || !defined(__clang__) || __clang_major__ >= 16 + int reg[4]; + __cpuid((int*)reg, 0); + { + int const n = reg[0]; + if (n >= 1) { + __cpuid((int*)reg, 1); + f1c = (U32)reg[2]; + f1d = (U32)reg[3]; + } + if (n >= 7) { + __cpuidex((int*)reg, 7, 0); + f7b = (U32)reg[1]; + f7c = (U32)reg[2]; + } + } +#else + /* Clang compiler has a bug (fixed in https://reviews.llvm.org/D101338) in + * which the `__cpuid` intrinsic does not save and restore `rbx` as it needs + * to due to being a reserved register. So in that case, do the `cpuid` + * ourselves. Clang supports inline assembly anyway. + */ + U32 n; + __asm__( + "pushq %%rbx\n\t" + "cpuid\n\t" + "popq %%rbx\n\t" + : "=a"(n) + : "a"(0) + : "rcx", "rdx"); + if (n >= 1) { + U32 f1a; + __asm__( + "pushq %%rbx\n\t" + "cpuid\n\t" + "popq %%rbx\n\t" + : "=a"(f1a), "=c"(f1c), "=d"(f1d) + : "a"(1) + :); + } + if (n >= 7) { + __asm__( + "pushq %%rbx\n\t" + "cpuid\n\t" + "movq %%rbx, %%rax\n\t" + "popq %%rbx" + : "=a"(f7b), "=c"(f7c) + : "a"(7), "c"(0) + : "rdx"); + } +#endif +#elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__) + /* The following block like the normal cpuid branch below, but gcc + * reserves ebx for use of its pic register so we must specially + * handle the save and restore to avoid clobbering the register + */ + U32 n; + __asm__( + "pushl %%ebx\n\t" + "cpuid\n\t" + "popl %%ebx\n\t" + : "=a"(n) + : "a"(0) + : "ecx", "edx"); + if (n >= 1) { + U32 f1a; + __asm__( + "pushl %%ebx\n\t" + "cpuid\n\t" + "popl %%ebx\n\t" + : "=a"(f1a), "=c"(f1c), "=d"(f1d) + : "a"(1)); + } + if (n >= 7) { + __asm__( + "pushl %%ebx\n\t" + "cpuid\n\t" + "movl %%ebx, %%eax\n\t" + "popl %%ebx" + : "=a"(f7b), "=c"(f7c) + : "a"(7), "c"(0) + : "edx"); + } +#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386__) + U32 n; + __asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "ecx", "edx"); + if (n >= 1) { + U32 f1a; + __asm__("cpuid" : "=a"(f1a), "=c"(f1c), "=d"(f1d) : "a"(1) : "ebx"); + } + if (n >= 7) { + U32 f7a; + __asm__("cpuid" + : "=a"(f7a), "=b"(f7b), "=c"(f7c) + : "a"(7), "c"(0) + : "edx"); + } +#endif + { + ZSTD_cpuid_t cpuid; + cpuid.f1c = f1c; + cpuid.f1d = f1d; + cpuid.f7b = f7b; + cpuid.f7c = f7c; + return cpuid; + } +} + +#define X(name, r, bit) \ + MEM_STATIC int ZSTD_cpuid_##name(ZSTD_cpuid_t const cpuid) { \ + return ((cpuid.r) & (1U << bit)) != 0; \ + } + +/* cpuid(1): Processor Info and Feature Bits. */ +#define C(name, bit) X(name, f1c, bit) + C(sse3, 0) + C(pclmuldq, 1) + C(dtes64, 2) + C(monitor, 3) + C(dscpl, 4) + C(vmx, 5) + C(smx, 6) + C(eist, 7) + C(tm2, 8) + C(ssse3, 9) + C(cnxtid, 10) + C(fma, 12) + C(cx16, 13) + C(xtpr, 14) + C(pdcm, 15) + C(pcid, 17) + C(dca, 18) + C(sse41, 19) + C(sse42, 20) + C(x2apic, 21) + C(movbe, 22) + C(popcnt, 23) + C(tscdeadline, 24) + C(aes, 25) + C(xsave, 26) + C(osxsave, 27) + C(avx, 28) + C(f16c, 29) + C(rdrand, 30) +#undef C +#define D(name, bit) X(name, f1d, bit) + D(fpu, 0) + D(vme, 1) + D(de, 2) + D(pse, 3) + D(tsc, 4) + D(msr, 5) + D(pae, 6) + D(mce, 7) + D(cx8, 8) + D(apic, 9) + D(sep, 11) + D(mtrr, 12) + D(pge, 13) + D(mca, 14) + D(cmov, 15) + D(pat, 16) + D(pse36, 17) + D(psn, 18) + D(clfsh, 19) + D(ds, 21) + D(acpi, 22) + D(mmx, 23) + D(fxsr, 24) + D(sse, 25) + D(sse2, 26) + D(ss, 27) + D(htt, 28) + D(tm, 29) + D(pbe, 31) +#undef D + +/* cpuid(7): Extended Features. */ +#define B(name, bit) X(name, f7b, bit) + B(bmi1, 3) + B(hle, 4) + B(avx2, 5) + B(smep, 7) + B(bmi2, 8) + B(erms, 9) + B(invpcid, 10) + B(rtm, 11) + B(mpx, 14) + B(avx512f, 16) + B(avx512dq, 17) + B(rdseed, 18) + B(adx, 19) + B(smap, 20) + B(avx512ifma, 21) + B(pcommit, 22) + B(clflushopt, 23) + B(clwb, 24) + B(avx512pf, 26) + B(avx512er, 27) + B(avx512cd, 28) + B(sha, 29) + B(avx512bw, 30) + B(avx512vl, 31) +#undef B +#define C(name, bit) X(name, f7c, bit) + C(prefetchwt1, 0) + C(avx512vbmi, 1) +#undef C + +#undef X + +#endif /* ZSTD_COMMON_CPU_H */ diff --git a/src/commonlib/bsd/zstd/common/debug.c b/src/commonlib/bsd/zstd/common/debug.c new file mode 100644 index 00000000000..c42634e21db --- /dev/null +++ b/src/commonlib/bsd/zstd/common/debug.c @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * debug + * Part of FSE library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + + +/* + * This module only hosts one global variable + * which can be used to dynamically influence the verbosity of traces, + * such as DEBUGLOG and RAWLOG + */ + +#include "debug.h" + +#if !defined(ZSTD_LINUX_KERNEL) || (DEBUGLEVEL>=2) +/* We only use this when DEBUGLEVEL>=2, but we get -Werror=pedantic errors if a + * translation unit is empty. So remove this from Linux kernel builds, but + * otherwise just leave it in. + */ +int g_debuglevel = DEBUGLEVEL; +#endif diff --git a/src/commonlib/bsd/zstd/common/debug.h b/src/commonlib/bsd/zstd/common/debug.h new file mode 100644 index 00000000000..2634d9d70e0 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/debug.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * debug + * Part of FSE library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + + +/* + * The purpose of this header is to enable debug functions. + * They regroup assert(), DEBUGLOG() and RAWLOG() for run-time, + * and DEBUG_STATIC_ASSERT() for compile-time. + * + * By default, DEBUGLEVEL==0, which means run-time debug is disabled. + * + * Level 1 enables assert() only. + * Starting level 2, traces can be generated and pushed to stderr. + * The higher the level, the more verbose the traces. + * + * It's possible to dynamically adjust level using variable g_debug_level, + * which is only declared if DEBUGLEVEL>=2, + * and is a global variable, not multi-thread protected (use with care) + */ + +#ifndef DEBUG_H_12987983217 +#define DEBUG_H_12987983217 + + +/* static assert is triggered at compile time, leaving no runtime artefact. + * static assert only works with compile-time constants. + * Also, this variant can only be used inside a function. */ +#define DEBUG_STATIC_ASSERT(c) (void)sizeof(char[(c) ? 1 : -1]) + + +/* DEBUGLEVEL is expected to be defined externally, + * typically through compiler command line. + * Value must be a number. */ +#ifndef DEBUGLEVEL +# define DEBUGLEVEL 0 +#endif + + +/* recommended values for DEBUGLEVEL : + * 0 : release mode, no debug, all run-time checks disabled + * 1 : enables assert() only, no display + * 2 : reserved, for currently active debug path + * 3 : events once per object lifetime (CCtx, CDict, etc.) + * 4 : events once per frame + * 5 : events once per block + * 6 : events once per sequence (verbose) + * 7+: events at every position (*very* verbose) + * + * It's generally inconvenient to output traces > 5. + * In which case, it's possible to selectively trigger high verbosity levels + * by modifying g_debug_level. + */ + +#if (DEBUGLEVEL>=1) +# define ZSTD_DEPS_NEED_ASSERT +# include "zstd_deps.h" +#else +# ifndef assert /* assert may be already defined, due to prior #include */ +# define assert(condition) ((void)0) /* disable assert (default) */ +# endif +#endif + +#if (DEBUGLEVEL>=2) +# define ZSTD_DEPS_NEED_IO +# include "zstd_deps.h" +extern int g_debuglevel; /* the variable is only declared, + it actually lives in debug.c, + and is shared by the whole process. + It's not thread-safe. + It's useful when enabling very verbose levels + on selective conditions (such as position in src) */ + +# define RAWLOG(l, ...) \ + do { \ + if (l<=g_debuglevel) { \ + ZSTD_DEBUG_PRINT(__VA_ARGS__); \ + } \ + } while (0) + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) +#define LINE_AS_STRING TOSTRING(__LINE__) + +# define DEBUGLOG(l, ...) \ + do { \ + if (l<=g_debuglevel) { \ + ZSTD_DEBUG_PRINT(__FILE__ ":" LINE_AS_STRING ": " __VA_ARGS__); \ + ZSTD_DEBUG_PRINT(" \n"); \ + } \ + } while (0) +#else +# define RAWLOG(l, ...) do { } while (0) /* disabled */ +# define DEBUGLOG(l, ...) do { } while (0) /* disabled */ +#endif + +#endif /* DEBUG_H_12987983217 */ diff --git a/src/commonlib/bsd/zstd/common/entropy_common.c b/src/commonlib/bsd/zstd/common/entropy_common.c new file mode 100644 index 00000000000..0b2a60a0ddc --- /dev/null +++ b/src/commonlib/bsd/zstd/common/entropy_common.c @@ -0,0 +1,342 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * Common functions of New Generation Entropy library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* ************************************* +* Dependencies +***************************************/ +#include "mem.h" +#include "error_private.h" /* ERR_*, ERROR */ +#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */ +#include "fse.h" +#include "huf.h" +#include "zstd_bits.h" /* ZSDT_highbit32, ZSTD_countTrailingZeros32 */ + + +/*=== Version ===*/ +unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; } + + +/*=== Error Management ===*/ +unsigned FSE_isError(size_t code) { return ERR_isError(code); } +const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); } + +unsigned HUF_isError(size_t code) { return ERR_isError(code); } +const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); } + + +/*-************************************************************** +* FSE NCount encoding-decoding +****************************************************************/ +FORCE_INLINE_TEMPLATE +size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + const BYTE* const istart = (const BYTE*) headerBuffer; + const BYTE* const iend = istart + hbSize; + const BYTE* ip = istart; + int nbBits; + int remaining; + int threshold; + U32 bitStream; + int bitCount; + unsigned charnum = 0; + unsigned const maxSV1 = *maxSVPtr + 1; + int previous0 = 0; + + if (hbSize < 8) { + /* This function only works when hbSize >= 8 */ + char buffer[8] = {0}; + ZSTD_memcpy(buffer, headerBuffer, hbSize); + { size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr, + buffer, sizeof(buffer)); + if (FSE_isError(countSize)) return countSize; + if (countSize > hbSize) return ERROR(corruption_detected); + return countSize; + } } + assert(hbSize >= 8); + + /* init */ + ZSTD_memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0])); /* all symbols not present in NCount have a frequency of 0 */ + bitStream = MEM_readLE32(ip); + nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */ + if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); + bitStream >>= 4; + bitCount = 4; + *tableLogPtr = nbBits; + remaining = (1<> 1; + while (repeats >= 12) { + charnum += 3 * 12; + if (LIKELY(ip <= iend-7)) { + ip += 3; + } else { + bitCount -= (int)(8 * (iend - 7 - ip)); + bitCount &= 31; + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> bitCount; + repeats = ZSTD_countTrailingZeros32(~bitStream | 0x80000000) >> 1; + } + charnum += 3 * repeats; + bitStream >>= 2 * repeats; + bitCount += 2 * repeats; + + /* Add the final repeat which isn't 0b11. */ + assert((bitStream & 3) < 3); + charnum += bitStream & 3; + bitCount += 2; + + /* This is an error, but break and return an error + * at the end, because returning out of a loop makes + * it harder for the compiler to optimize. + */ + if (charnum >= maxSV1) break; + + /* We don't need to set the normalized count to 0 + * because we already memset the whole buffer to 0. + */ + + if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { + assert((bitCount >> 3) <= 3); /* For first condition to work */ + ip += bitCount>>3; + bitCount &= 7; + } else { + bitCount -= (int)(8 * (iend - 4 - ip)); + bitCount &= 31; + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> bitCount; + } + { + int const max = (2*threshold-1) - remaining; + int count; + + if ((bitStream & (threshold-1)) < (U32)max) { + count = bitStream & (threshold-1); + bitCount += nbBits-1; + } else { + count = bitStream & (2*threshold-1); + if (count >= threshold) count -= max; + bitCount += nbBits; + } + + count--; /* extra accuracy */ + /* When it matters (small blocks), this is a + * predictable branch, because we don't use -1. + */ + if (count >= 0) { + remaining -= count; + } else { + assert(count == -1); + remaining += count; + } + normalizedCounter[charnum++] = (short)count; + previous0 = !count; + + assert(threshold > 1); + if (remaining < threshold) { + /* This branch can be folded into the + * threshold update condition because we + * know that threshold > 1. + */ + if (remaining <= 1) break; + nbBits = ZSTD_highbit32(remaining) + 1; + threshold = 1 << (nbBits - 1); + } + if (charnum >= maxSV1) break; + + if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { + ip += bitCount>>3; + bitCount &= 7; + } else { + bitCount -= (int)(8 * (iend - 4 - ip)); + bitCount &= 31; + ip = iend - 4; + } + bitStream = MEM_readLE32(ip) >> bitCount; + } } + if (remaining != 1) return ERROR(corruption_detected); + /* Only possible when there are too many zeros. */ + if (charnum > maxSV1) return ERROR(maxSymbolValue_tooSmall); + if (bitCount > 32) return ERROR(corruption_detected); + *maxSVPtr = charnum-1; + + ip += (bitCount+7)>>3; + return ip-istart; +} + +/* Avoids the FORCE_INLINE of the _body() function. */ +static size_t FSE_readNCount_body_default( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); +} + +#if DYNAMIC_BMI2 +BMI2_TARGET_ATTRIBUTE static size_t FSE_readNCount_body_bmi2( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); +} +#endif + +size_t FSE_readNCount_bmi2( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize, int bmi2) +{ +#if DYNAMIC_BMI2 + if (bmi2) { + return FSE_readNCount_body_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); + } +#endif + (void)bmi2; + return FSE_readNCount_body_default(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize); +} + +size_t FSE_readNCount( + short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, + const void* headerBuffer, size_t hbSize) +{ + return FSE_readNCount_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize, /* bmi2 */ 0); +} + + +/*! HUF_readStats() : + Read compact Huffman tree, saved by HUF_writeCTable(). + `huffWeight` is destination buffer. + `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32. + @return : size read from `src` , or an error Code . + Note : Needed by HUF_readCTable() and HUF_readDTableX?() . +*/ +size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize) +{ + U32 wksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; + return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* flags */ 0); +} + +FORCE_INLINE_TEMPLATE size_t +HUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize, + int bmi2) +{ + U32 weightTotal; + const BYTE* ip = (const BYTE*) src; + size_t iSize; + size_t oSize; + + if (!srcSize) return ERROR(srcSize_wrong); + iSize = ip[0]; + /* ZSTD_memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */ + + if (iSize >= 128) { /* special header */ + oSize = iSize - 127; + iSize = ((oSize+1)/2); + if (iSize+1 > srcSize) return ERROR(srcSize_wrong); + if (oSize >= hwSize) return ERROR(corruption_detected); + ip += 1; + { U32 n; + for (n=0; n> 4; + huffWeight[n+1] = ip[n/2] & 15; + } } } + else { /* header compressed with FSE (normal case) */ + if (iSize+1 > srcSize) return ERROR(srcSize_wrong); + /* max (hwSize-1) values decoded, as last one is implied */ + oSize = FSE_decompress_wksp_bmi2(huffWeight, hwSize-1, ip+1, iSize, 6, workSpace, wkspSize, bmi2); + if (FSE_isError(oSize)) return oSize; + } + + /* collect weight stats */ + ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32)); + weightTotal = 0; + { U32 n; for (n=0; n HUF_TABLELOG_MAX) return ERROR(corruption_detected); + rankStats[huffWeight[n]]++; + weightTotal += (1 << huffWeight[n]) >> 1; + } } + if (weightTotal == 0) return ERROR(corruption_detected); + + /* get last non-null symbol weight (implied, total must be 2^n) */ + { U32 const tableLog = ZSTD_highbit32(weightTotal) + 1; + if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected); + *tableLogPtr = tableLog; + /* determine last weight */ + { U32 const total = 1 << tableLog; + U32 const rest = total - weightTotal; + U32 const verif = 1 << ZSTD_highbit32(rest); + U32 const lastWeight = ZSTD_highbit32(rest) + 1; + if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ + huffWeight[oSize] = (BYTE)lastWeight; + rankStats[lastWeight]++; + } } + + /* check tree construction validity */ + if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ + + /* results */ + *nbSymbolsPtr = (U32)(oSize+1); + return iSize+1; +} + +/* Avoids the FORCE_INLINE of the _body() function. */ +static size_t HUF_readStats_body_default(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize) +{ + return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 0); +} + +#if DYNAMIC_BMI2 +static BMI2_TARGET_ATTRIBUTE size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize) +{ + return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 1); +} +#endif + +size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, U32* rankStats, + U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize, + int flags) +{ +#if DYNAMIC_BMI2 + if (flags & HUF_flags_bmi2) { + return HUF_readStats_body_bmi2(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize); + } +#endif + (void)flags; + return HUF_readStats_body_default(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize); +} diff --git a/src/commonlib/bsd/zstd/common/error_private.c b/src/commonlib/bsd/zstd/common/error_private.c new file mode 100644 index 00000000000..2d8e3bdd61c --- /dev/null +++ b/src/commonlib/bsd/zstd/common/error_private.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* The purpose of this file is to have a single list of error strings embedded in binary */ + +#include "error_private.h" + +const char* ERR_getErrorString(ERR_enum code) +{ +#ifdef ZSTD_STRIP_ERROR_STRINGS + (void)code; + return "Error strings stripped"; +#else + static const char* const notErrorCode = "Unspecified error code"; + switch( code ) + { + case PREFIX(no_error): return "No error detected"; + case PREFIX(GENERIC): return "Error (generic)"; + case PREFIX(prefix_unknown): return "Unknown frame descriptor"; + case PREFIX(version_unsupported): return "Version not supported"; + case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter"; + case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding"; + case PREFIX(corruption_detected): return "Data corruption detected"; + case PREFIX(checksum_wrong): return "Restored data doesn't match checksum"; + case PREFIX(literals_headerWrong): return "Header of Literals' block doesn't respect format specification"; + case PREFIX(parameter_unsupported): return "Unsupported parameter"; + case PREFIX(parameter_combination_unsupported): return "Unsupported combination of parameters"; + case PREFIX(parameter_outOfBound): return "Parameter is out of bound"; + case PREFIX(init_missing): return "Context should be init first"; + case PREFIX(memory_allocation): return "Allocation error : not enough memory"; + case PREFIX(workSpace_tooSmall): return "workSpace buffer is not large enough"; + case PREFIX(stage_wrong): return "Operation not authorized at current processing stage"; + case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported"; + case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large"; + case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small"; + case PREFIX(cannotProduce_uncompressedBlock): return "This mode cannot generate an uncompressed block"; + case PREFIX(stabilityCondition_notRespected): return "pledged buffer stability condition is not respected"; + case PREFIX(dictionary_corrupted): return "Dictionary is corrupted"; + case PREFIX(dictionary_wrong): return "Dictionary mismatch"; + case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples"; + case PREFIX(dstSize_tooSmall): return "Destination buffer is too small"; + case PREFIX(srcSize_wrong): return "Src size is incorrect"; + case PREFIX(dstBuffer_null): return "Operation on NULL destination buffer"; + case PREFIX(noForwardProgress_destFull): return "Operation made no progress over multiple calls, due to output buffer being full"; + case PREFIX(noForwardProgress_inputEmpty): return "Operation made no progress over multiple calls, due to input being empty"; + /* following error codes are not stable and may be removed or changed in a future version */ + case PREFIX(frameIndex_tooLarge): return "Frame index is too large"; + case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking"; + case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong"; + case PREFIX(srcBuffer_wrong): return "Source buffer is wrong"; + case PREFIX(sequenceProducer_failed): return "Block-level external sequence producer returned an error code"; + case PREFIX(externalSequences_invalid): return "External sequences are not valid"; + case PREFIX(maxCode): + default: return notErrorCode; + } +#endif +} diff --git a/src/commonlib/bsd/zstd/common/error_private.h b/src/commonlib/bsd/zstd/common/error_private.h new file mode 100644 index 00000000000..eeee67f52ee --- /dev/null +++ b/src/commonlib/bsd/zstd/common/error_private.h @@ -0,0 +1,160 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* Note : this module is expected to remain private, do not expose it */ + +#ifndef ERROR_H_MODULE +#define ERROR_H_MODULE + +/* **************************************** +* Dependencies +******************************************/ +#include "../zstd_errors.h" /* enum list */ +#include "zstd_compiler.h" +#include "debug.h" +#include "zstd_deps.h" /* size_t */ + +/* **************************************** +* Compiler-specific +******************************************/ +#if defined(__GNUC__) +# define ERR_STATIC static __attribute__((unused)) +#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define ERR_STATIC static inline +#elif defined(_MSC_VER) +# define ERR_STATIC static __inline +#else +# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ +#endif + + +/*-**************************************** +* Customization (error_public.h) +******************************************/ +typedef ZSTD_ErrorCode ERR_enum; +#define PREFIX(name) ZSTD_error_##name + + +/*-**************************************** +* Error codes handling +******************************************/ +#undef ERROR /* already defined on Visual Studio */ +#define ERROR(name) ZSTD_ERROR(name) +#define ZSTD_ERROR(name) ((size_t)-PREFIX(name)) + +ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); } + +ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); } + +/* check and forward error code */ +#define CHECK_V_F(e, f) \ + size_t const e = f; \ + do { \ + if (ERR_isError(e)) \ + return e; \ + } while (0) +#define CHECK_F(f) do { CHECK_V_F(_var_err__, f); } while (0) + + +/*-**************************************** +* Error Strings +******************************************/ + +const char* ERR_getErrorString(ERR_enum code); /* error_private.c */ + +ERR_STATIC const char* ERR_getErrorName(size_t code) +{ + return ERR_getErrorString(ERR_getErrorCode(code)); +} + +/** + * Ignore: this is an internal helper. + * + * This is a helper function to help force C99-correctness during compilation. + * Under strict compilation modes, variadic macro arguments can't be empty. + * However, variadic function arguments can be. Using a function therefore lets + * us statically check that at least one (string) argument was passed, + * independent of the compilation flags. + */ +static INLINE_KEYWORD UNUSED_ATTR +void _force_has_format_string(const char *format, ...) { + (void)format; +} + +/** + * Ignore: this is an internal helper. + * + * We want to force this function invocation to be syntactically correct, but + * we don't want to force runtime evaluation of its arguments. + */ +#define _FORCE_HAS_FORMAT_STRING(...) \ + do { \ + if (0) { \ + _force_has_format_string(__VA_ARGS__); \ + } \ + } while (0) + +#define ERR_QUOTE(str) #str + +/** + * Return the specified error if the condition evaluates to true. + * + * In debug modes, prints additional information. + * In order to do that (particularly, printing the conditional that failed), + * this can't just wrap RETURN_ERROR(). + */ +#define RETURN_ERROR_IF(cond, err, ...) \ + do { \ + if (cond) { \ + RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \ + __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return ERROR(err); \ + } \ + } while (0) + +/** + * Unconditionally return the specified error. + * + * In debug modes, prints additional information. + */ +#define RETURN_ERROR(err, ...) \ + do { \ + RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \ + __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return ERROR(err); \ + } while(0) + +/** + * If the provided expression evaluates to an error code, returns that error code. + * + * In debug modes, prints additional information. + */ +#define FORWARD_IF_ERROR(err, ...) \ + do { \ + size_t const err_code = (err); \ + if (ERR_isError(err_code)) { \ + RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \ + __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \ + _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \ + RAWLOG(3, ": " __VA_ARGS__); \ + RAWLOG(3, "\n"); \ + return err_code; \ + } \ + } while(0) + +#endif /* ERROR_H_MODULE */ diff --git a/src/commonlib/bsd/zstd/common/fse.h b/src/commonlib/bsd/zstd/common/fse.h new file mode 100644 index 00000000000..2b450b95795 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/fse.h @@ -0,0 +1,627 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * FSE : Finite State Entropy codec + * Public Prototypes declaration + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ +#ifndef FSE_H +#define FSE_H + + +/*-***************************************** +* Dependencies +******************************************/ +#include "zstd_deps.h" /* size_t, ptrdiff_t */ + +/*-***************************************** +* FSE_PUBLIC_API : control library symbols visibility +******************************************/ +#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4) +# define FSE_PUBLIC_API __attribute__ ((visibility ("default"))) +#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */ +# define FSE_PUBLIC_API __declspec(dllexport) +#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1) +# define FSE_PUBLIC_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define FSE_PUBLIC_API +#endif + +/*------ Version ------*/ +#define FSE_VERSION_MAJOR 0 +#define FSE_VERSION_MINOR 9 +#define FSE_VERSION_RELEASE 0 + +#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE +#define FSE_QUOTE(str) #str +#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str) +#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION) + +#define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE) +FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number; to be used when checking dll version */ + + +/*-***************************************** +* Tool functions +******************************************/ +FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */ + +/* Error Management */ +FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */ +FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */ + + +/*-***************************************** +* FSE detailed API +******************************************/ +/*! +FSE_compress() does the following: +1. count symbol occurrence from source[] into table count[] (see hist.h) +2. normalize counters so that sum(count[]) == Power_of_2 (2^tableLog) +3. save normalized counters to memory buffer using writeNCount() +4. build encoding table 'CTable' from normalized counters +5. encode the data stream using encoding table 'CTable' + +FSE_decompress() does the following: +1. read normalized counters with readNCount() +2. build decoding table 'DTable' from normalized counters +3. decode the data stream using decoding table 'DTable' + +The following API allows targeting specific sub-functions for advanced tasks. +For example, it's possible to compress several blocks using the same 'CTable', +or to save and provide normalized distribution using external method. +*/ + +/* *** COMPRESSION *** */ + +/*! FSE_optimalTableLog(): + dynamically downsize 'tableLog' when conditions are met. + It saves CPU time, by using smaller tables, while preserving or even improving compression ratio. + @return : recommended tableLog (necessarily <= 'maxTableLog') */ +FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); + +/*! FSE_normalizeCount(): + normalize counts so that sum(count[]) == Power_of_2 (2^tableLog) + 'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1). + useLowProbCount is a boolean parameter which trades off compressed size for + faster header decoding. When it is set to 1, the compressed data will be slightly + smaller. And when it is set to 0, FSE_readNCount() and FSE_buildDTable() will be + faster. If you are compressing a small amount of data (< 2 KB) then useLowProbCount=0 + is a good default, since header deserialization makes a big speed difference. + Otherwise, useLowProbCount=1 is a good default, since the speed difference is small. + @return : tableLog, + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, + const unsigned* count, size_t srcSize, unsigned maxSymbolValue, unsigned useLowProbCount); + +/*! FSE_NCountWriteBound(): + Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'. + Typically useful for allocation purpose. */ +FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog); + +/*! FSE_writeNCount(): + Compactly save 'normalizedCounter' into 'buffer'. + @return : size of the compressed table, + or an errorCode, which can be tested using FSE_isError(). */ +FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, + const short* normalizedCounter, + unsigned maxSymbolValue, unsigned tableLog); + +/*! Constructor and Destructor of FSE_CTable. + Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */ +typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */ + +/*! FSE_buildCTable(): + Builds `ct`, which must be already allocated, using FSE_createCTable(). + @return : 0, or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); + +/*! FSE_compress_usingCTable(): + Compress `src` using `ct` into `dst` which must be already allocated. + @return : size of compressed data (<= `dstCapacity`), + or 0 if compressed data could not fit into `dst`, + or an errorCode, which can be tested using FSE_isError() */ +FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct); + +/*! +Tutorial : +---------- +The first step is to count all symbols. FSE_count() does this job very fast. +Result will be saved into 'count', a table of unsigned int, which must be already allocated, and have 'maxSymbolValuePtr[0]+1' cells. +'src' is a table of bytes of size 'srcSize'. All values within 'src' MUST be <= maxSymbolValuePtr[0] +maxSymbolValuePtr[0] will be updated, with its real value (necessarily <= original value) +FSE_count() will return the number of occurrence of the most frequent symbol. +This can be used to know if there is a single symbol within 'src', and to quickly evaluate its compressibility. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). + +The next step is to normalize the frequencies. +FSE_normalizeCount() will ensure that sum of frequencies is == 2 ^'tableLog'. +It also guarantees a minimum of 1 to any Symbol with frequency >= 1. +You can use 'tableLog'==0 to mean "use default tableLog value". +If you are unsure of which tableLog value to use, you can ask FSE_optimalTableLog(), +which will provide the optimal valid tableLog given sourceSize, maxSymbolValue, and a user-defined maximum (0 means "default"). + +The result of FSE_normalizeCount() will be saved into a table, +called 'normalizedCounter', which is a table of signed short. +'normalizedCounter' must be already allocated, and have at least 'maxSymbolValue+1' cells. +The return value is tableLog if everything proceeded as expected. +It is 0 if there is a single symbol within distribution. +If there is an error (ex: invalid tableLog value), the function will return an ErrorCode (which can be tested using FSE_isError()). + +'normalizedCounter' can be saved in a compact manner to a memory area using FSE_writeNCount(). +'buffer' must be already allocated. +For guaranteed success, buffer size must be at least FSE_headerBound(). +The result of the function is the number of bytes written into 'buffer'. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError(); ex : buffer size too small). + +'normalizedCounter' can then be used to create the compression table 'CTable'. +The space required by 'CTable' must be already allocated, using FSE_createCTable(). +You can then use FSE_buildCTable() to fill 'CTable'. +If there is an error, both functions will return an ErrorCode (which can be tested using FSE_isError()). + +'CTable' can then be used to compress 'src', with FSE_compress_usingCTable(). +Similar to FSE_count(), the convention is that 'src' is assumed to be a table of char of size 'srcSize' +The function returns the size of compressed data (without header), necessarily <= `dstCapacity`. +If it returns '0', compressed data could not fit into 'dst'. +If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()). +*/ + + +/* *** DECOMPRESSION *** */ + +/*! FSE_readNCount(): + Read compactly saved 'normalizedCounter' from 'rBuffer'. + @return : size read from 'rBuffer', + or an errorCode, which can be tested using FSE_isError(). + maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */ +FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, + unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, + const void* rBuffer, size_t rBuffSize); + +/*! FSE_readNCount_bmi2(): + * Same as FSE_readNCount() but pass bmi2=1 when your CPU supports BMI2 and 0 otherwise. + */ +FSE_PUBLIC_API size_t FSE_readNCount_bmi2(short* normalizedCounter, + unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, + const void* rBuffer, size_t rBuffSize, int bmi2); + +typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */ + +/*! +Tutorial : +---------- +(Note : these functions only decompress FSE-compressed blocks. + If block is uncompressed, use memcpy() instead + If block is a single repeated byte, use memset() instead ) + +The first step is to obtain the normalized frequencies of symbols. +This can be performed by FSE_readNCount() if it was saved using FSE_writeNCount(). +'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short. +In practice, that means it's necessary to know 'maxSymbolValue' beforehand, +or size the table to handle worst case situations (typically 256). +FSE_readNCount() will provide 'tableLog' and 'maxSymbolValue'. +The result of FSE_readNCount() is the number of bytes read from 'rBuffer'. +Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that. +If there is an error, the function will return an error code, which can be tested using FSE_isError(). + +The next step is to build the decompression tables 'FSE_DTable' from 'normalizedCounter'. +This is performed by the function FSE_buildDTable(). +The space required by 'FSE_DTable' must be already allocated using FSE_createDTable(). +If there is an error, the function will return an error code, which can be tested using FSE_isError(). + +`FSE_DTable` can then be used to decompress `cSrc`, with FSE_decompress_usingDTable(). +`cSrcSize` must be strictly correct, otherwise decompression will fail. +FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`). +If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small) +*/ + +#endif /* FSE_H */ + + +#if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY) +#define FSE_H_FSE_STATIC_LINKING_ONLY +#include "bitstream.h" + +/* ***************************************** +* Static allocation +*******************************************/ +/* FSE buffer bounds */ +#define FSE_NCOUNTBOUND 512 +#define FSE_BLOCKBOUND(size) ((size) + ((size)>>7) + 4 /* fse states */ + sizeof(size_t) /* bitContainer */) +#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */ +#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<((maxTableLog)-1)) + (((maxSymbolValue)+1)*2)) +#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<(maxTableLog))) + +/* or use the size to malloc() space directly. Pay attention to alignment restrictions though */ +#define FSE_CTABLE_SIZE(maxTableLog, maxSymbolValue) (FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(FSE_CTable)) +#define FSE_DTABLE_SIZE(maxTableLog) (FSE_DTABLE_SIZE_U32(maxTableLog) * sizeof(FSE_DTable)) + + +/* ***************************************** + * FSE advanced API + ***************************************** */ + +unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus); +/**< same as FSE_optimalTableLog(), which used `minus==2` */ + +size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue); +/**< build a fake FSE_CTable, designed to compress always the same symbolValue */ + +/* FSE_buildCTable_wksp() : + * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). + * `wkspSize` must be >= `FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)` of `unsigned`. + * See FSE_buildCTable_wksp() for breakdown of workspace usage. + */ +#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (((maxSymbolValue + 2) + (1ull << (tableLog)))/2 + sizeof(U64)/sizeof(U32) /* additional 8 bytes for potential table overwrite */) +#define FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) (sizeof(unsigned) * FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)) +size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); + +#define FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) (sizeof(short) * (maxSymbolValue + 1) + (1ULL << maxTableLog) + 8) +#define FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) ((FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) + sizeof(unsigned) - 1) / sizeof(unsigned)) +FSE_PUBLIC_API size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); +/**< Same as FSE_buildDTable(), using an externally allocated `workspace` produced with `FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxSymbolValue)` */ + +#define FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) (FSE_DTABLE_SIZE_U32(maxTableLog) + 1 + FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) + (FSE_MAX_SYMBOL_VALUE + 1) / 2 + 1) +#define FSE_DECOMPRESS_WKSP_SIZE(maxTableLog, maxSymbolValue) (FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(unsigned)) +size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2); +/**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DECOMPRESS_WKSP_SIZE_U32(maxLog, maxSymbolValue)`. + * Set bmi2 to 1 if your CPU supports BMI2 or 0 if it doesn't */ + +typedef enum { + FSE_repeat_none, /**< Cannot use the previous table */ + FSE_repeat_check, /**< Can use the previous table but it must be checked */ + FSE_repeat_valid /**< Can use the previous table and it is assumed to be valid */ + } FSE_repeat; + +/* ***************************************** +* FSE symbol compression API +*******************************************/ +/*! + This API consists of small unitary functions, which highly benefit from being inlined. + Hence their body are included in next section. +*/ +typedef struct { + ptrdiff_t value; + const void* stateTable; + const void* symbolTT; + unsigned stateLog; +} FSE_CState_t; + +static void FSE_initCState(FSE_CState_t* CStatePtr, const FSE_CTable* ct); + +static void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* CStatePtr, unsigned symbol); + +static void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* CStatePtr); + +/**< +These functions are inner components of FSE_compress_usingCTable(). +They allow the creation of custom streams, mixing multiple tables and bit sources. + +A key property to keep in mind is that encoding and decoding are done **in reverse direction**. +So the first symbol you will encode is the last you will decode, like a LIFO stack. + +You will need a few variables to track your CStream. They are : + +FSE_CTable ct; // Provided by FSE_buildCTable() +BIT_CStream_t bitStream; // bitStream tracking structure +FSE_CState_t state; // State tracking structure (can have several) + + +The first thing to do is to init bitStream and state. + size_t errorCode = BIT_initCStream(&bitStream, dstBuffer, maxDstSize); + FSE_initCState(&state, ct); + +Note that BIT_initCStream() can produce an error code, so its result should be tested, using FSE_isError(); +You can then encode your input data, byte after byte. +FSE_encodeSymbol() outputs a maximum of 'tableLog' bits at a time. +Remember decoding will be done in reverse direction. + FSE_encodeByte(&bitStream, &state, symbol); + +At any time, you can also add any bit sequence. +Note : maximum allowed nbBits is 25, for compatibility with 32-bits decoders + BIT_addBits(&bitStream, bitField, nbBits); + +The above methods don't commit data to memory, they just store it into local register, for speed. +Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t). +Writing data to memory is a manual operation, performed by the flushBits function. + BIT_flushBits(&bitStream); + +Your last FSE encoding operation shall be to flush your last state value(s). + FSE_flushState(&bitStream, &state); + +Finally, you must close the bitStream. +The function returns the size of CStream in bytes. +If data couldn't fit into dstBuffer, it will return a 0 ( == not compressible) +If there is an error, it returns an errorCode (which can be tested using FSE_isError()). + size_t size = BIT_closeCStream(&bitStream); +*/ + + +/* ***************************************** +* FSE symbol decompression API +*******************************************/ +typedef struct { + size_t state; + const void* table; /* precise table may vary, depending on U16 */ +} FSE_DState_t; + + +static void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt); + +static unsigned char FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD); + +static unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr); + +/**< +Let's now decompose FSE_decompress_usingDTable() into its unitary components. +You will decode FSE-encoded symbols from the bitStream, +and also any other bitFields you put in, **in reverse order**. + +You will need a few variables to track your bitStream. They are : + +BIT_DStream_t DStream; // Stream context +FSE_DState_t DState; // State context. Multiple ones are possible +FSE_DTable* DTablePtr; // Decoding table, provided by FSE_buildDTable() + +The first thing to do is to init the bitStream. + errorCode = BIT_initDStream(&DStream, srcBuffer, srcSize); + +You should then retrieve your initial state(s) +(in reverse flushing order if you have several ones) : + errorCode = FSE_initDState(&DState, &DStream, DTablePtr); + +You can then decode your data, symbol after symbol. +For information the maximum number of bits read by FSE_decodeSymbol() is 'tableLog'. +Keep in mind that symbols are decoded in reverse order, like a LIFO stack (last in, first out). + unsigned char symbol = FSE_decodeSymbol(&DState, &DStream); + +You can retrieve any bitfield you eventually stored into the bitStream (in reverse order) +Note : maximum allowed nbBits is 25, for 32-bits compatibility + size_t bitField = BIT_readBits(&DStream, nbBits); + +All above operations only read from local register (which size depends on size_t). +Refueling the register from memory is manually performed by the reload method. + endSignal = FSE_reloadDStream(&DStream); + +BIT_reloadDStream() result tells if there is still some more data to read from DStream. +BIT_DStream_unfinished : there is still some data left into the DStream. +BIT_DStream_endOfBuffer : Dstream reached end of buffer. Its container may no longer be completely filled. +BIT_DStream_completed : Dstream reached its exact end, corresponding in general to decompression completed. +BIT_DStream_tooFar : Dstream went too far. Decompression result is corrupted. + +When reaching end of buffer (BIT_DStream_endOfBuffer), progress slowly, notably if you decode multiple symbols per loop, +to properly detect the exact end of stream. +After each decoded symbol, check if DStream is fully consumed using this simple test : + BIT_reloadDStream(&DStream) >= BIT_DStream_completed + +When it's done, verify decompression is fully completed, by checking both DStream and the relevant states. +Checking if DStream has reached its end is performed by : + BIT_endOfDStream(&DStream); +Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible. + FSE_endOfDState(&DState); +*/ + + +/* ***************************************** +* FSE unsafe API +*******************************************/ +static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD); +/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */ + + +/* ***************************************** +* Implementation of inlined functions +*******************************************/ +typedef struct { + int deltaFindState; + U32 deltaNbBits; +} FSE_symbolCompressionTransform; /* total 8 bytes */ + +MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct) +{ + const void* ptr = ct; + const U16* u16ptr = (const U16*) ptr; + const U32 tableLog = MEM_read16(ptr); + statePtr->value = (ptrdiff_t)1<stateTable = u16ptr+2; + statePtr->symbolTT = ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1); + statePtr->stateLog = tableLog; +} + + +/*! FSE_initCState2() : +* Same as FSE_initCState(), but the first symbol to include (which will be the last to be read) +* uses the smallest state value possible, saving the cost of this symbol */ +MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol) +{ + FSE_initCState(statePtr, ct); + { const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; + const U16* stateTable = (const U16*)(statePtr->stateTable); + U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16); + statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits; + statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; + } +} + +MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, unsigned symbol) +{ + FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol]; + const U16* const stateTable = (const U16*)(statePtr->stateTable); + U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16); + BIT_addBits(bitC, (BitContainerType)statePtr->value, nbBitsOut); + statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState]; +} + +MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr) +{ + BIT_addBits(bitC, (BitContainerType)statePtr->value, statePtr->stateLog); + BIT_flushBits(bitC); +} + + +/* FSE_getMaxNbBits() : + * Approximate maximum cost of a symbol, in bits. + * Fractional get rounded up (i.e. a symbol with a normalized frequency of 3 gives the same result as a frequency of 2) + * note 1 : assume symbolValue is valid (<= maxSymbolValue) + * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ +MEM_STATIC U32 FSE_getMaxNbBits(const void* symbolTTPtr, U32 symbolValue) +{ + const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; + return (symbolTT[symbolValue].deltaNbBits + ((1<<16)-1)) >> 16; +} + +/* FSE_bitCost() : + * Approximate symbol cost, as fractional value, using fixed-point format (accuracyLog fractional bits) + * note 1 : assume symbolValue is valid (<= maxSymbolValue) + * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */ +MEM_STATIC U32 FSE_bitCost(const void* symbolTTPtr, U32 tableLog, U32 symbolValue, U32 accuracyLog) +{ + const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr; + U32 const minNbBits = symbolTT[symbolValue].deltaNbBits >> 16; + U32 const threshold = (minNbBits+1) << 16; + assert(tableLog < 16); + assert(accuracyLog < 31-tableLog); /* ensure enough room for renormalization double shift */ + { U32 const tableSize = 1 << tableLog; + U32 const deltaFromThreshold = threshold - (symbolTT[symbolValue].deltaNbBits + tableSize); + U32 const normalizedDeltaFromThreshold = (deltaFromThreshold << accuracyLog) >> tableLog; /* linear interpolation (very approximate) */ + U32 const bitMultiplier = 1 << accuracyLog; + assert(symbolTT[symbolValue].deltaNbBits + tableSize <= threshold); + assert(normalizedDeltaFromThreshold <= bitMultiplier); + return (minNbBits+1)*bitMultiplier - normalizedDeltaFromThreshold; + } +} + + +/* ====== Decompression ====== */ + +typedef struct { + U16 tableLog; + U16 fastMode; +} FSE_DTableHeader; /* sizeof U32 */ + +typedef struct +{ + unsigned short newState; + unsigned char symbol; + unsigned char nbBits; +} FSE_decode_t; /* size == U32 */ + +MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt) +{ + const void* ptr = dt; + const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr; + DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); + BIT_reloadDStream(bitD); + DStatePtr->table = dt + 1; +} + +MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + return DInfo.symbol; +} + +MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + size_t const lowBits = BIT_readBits(bitD, nbBits); + DStatePtr->state = DInfo.newState + lowBits; +} + +MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + BYTE const symbol = DInfo.symbol; + size_t const lowBits = BIT_readBits(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +/*! FSE_decodeSymbolFast() : + unsafe, only works if no symbol has a probability > 50% */ +MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD) +{ + FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state]; + U32 const nbBits = DInfo.nbBits; + BYTE const symbol = DInfo.symbol; + size_t const lowBits = BIT_readBitsFast(bitD, nbBits); + + DStatePtr->state = DInfo.newState + lowBits; + return symbol; +} + +MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr) +{ + return DStatePtr->state == 0; +} + + + +#ifndef FSE_COMMONDEFS_ONLY + +/* ************************************************************** +* Tuning parameters +****************************************************************/ +/*!MEMORY_USAGE : +* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) +* Increasing memory usage improves compression ratio +* Reduced memory usage can improve speed, due to cache effect +* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ +#ifndef FSE_MAX_MEMORY_USAGE +# define FSE_MAX_MEMORY_USAGE 14 +#endif +#ifndef FSE_DEFAULT_MEMORY_USAGE +# define FSE_DEFAULT_MEMORY_USAGE 13 +#endif +#if (FSE_DEFAULT_MEMORY_USAGE > FSE_MAX_MEMORY_USAGE) +# error "FSE_DEFAULT_MEMORY_USAGE must be <= FSE_MAX_MEMORY_USAGE" +#endif + +/*!FSE_MAX_SYMBOL_VALUE : +* Maximum symbol value authorized. +* Required for proper stack allocation */ +#ifndef FSE_MAX_SYMBOL_VALUE +# define FSE_MAX_SYMBOL_VALUE 255 +#endif + +/* ************************************************************** +* template functions type & suffix +****************************************************************/ +#define FSE_FUNCTION_TYPE BYTE +#define FSE_FUNCTION_EXTENSION +#define FSE_DECODE_TYPE FSE_decode_t + + +#endif /* !FSE_COMMONDEFS_ONLY */ + + +/* *************************************************************** +* Constants +*****************************************************************/ +#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2) +#define FSE_MAX_TABLESIZE (1U< FSE_TABLELOG_ABSOLUTE_MAX +# error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported" +#endif + +#define FSE_TABLESTEP(tableSize) (((tableSize)>>1) + ((tableSize)>>3) + 3) + +#endif /* FSE_STATIC_LINKING_ONLY */ diff --git a/src/commonlib/bsd/zstd/common/fse_decompress.c b/src/commonlib/bsd/zstd/common/fse_decompress.c new file mode 100644 index 00000000000..6fbac2992a8 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/fse_decompress.c @@ -0,0 +1,317 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * FSE : Finite State Entropy decoder + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + + +/* ************************************************************** +* Includes +****************************************************************/ +#include "debug.h" /* assert */ +#include "bitstream.h" +#include "zstd_compiler.h" +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" +#include "error_private.h" +#include "zstd_deps.h" /* ZSTD_memcpy */ +#include "zstd_bits.h" /* ZSTD_highbit32 */ + + +/* ************************************************************** +* Error Management +****************************************************************/ +#define FSE_isError ERR_isError +#define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */ + + +/* ************************************************************** +* Templates +****************************************************************/ +/* + designed to be included + for type-specific functions (template emulation in C) + Objective is to write these functions only once, for improved maintenance +*/ + +/* safety checks */ +#ifndef FSE_FUNCTION_EXTENSION +# error "FSE_FUNCTION_EXTENSION must be defined" +#endif +#ifndef FSE_FUNCTION_TYPE +# error "FSE_FUNCTION_TYPE must be defined" +#endif + +/* Function names */ +#define FSE_CAT(X,Y) X##Y +#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) +#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) + +static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize) +{ + void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ + FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr); + U16* symbolNext = (U16*)workSpace; + BYTE* spread = (BYTE*)(symbolNext + maxSymbolValue + 1); + + U32 const maxSV1 = maxSymbolValue + 1; + U32 const tableSize = 1 << tableLog; + U32 highThreshold = tableSize-1; + + /* Sanity Checks */ + if (FSE_BUILD_DTABLE_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(maxSymbolValue_tooLarge); + if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge); + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); + + /* Init, lay down lowprob symbols */ + { FSE_DTableHeader DTableH; + DTableH.tableLog = (U16)tableLog; + DTableH.fastMode = 1; + { S16 const largeLimit= (S16)(1 << (tableLog-1)); + U32 s; + for (s=0; s= largeLimit) DTableH.fastMode=0; + symbolNext[s] = (U16)normalizedCounter[s]; + } } } + ZSTD_memcpy(dt, &DTableH, sizeof(DTableH)); + } + + /* Spread symbols */ + if (highThreshold == tableSize - 1) { + size_t const tableMask = tableSize-1; + size_t const step = FSE_TABLESTEP(tableSize); + /* First lay down the symbols in order. + * We use a uint64_t to lay down 8 bytes at a time. This reduces branch + * misses since small blocks generally have small table logs, so nearly + * all symbols have counts <= 8. We ensure we have 8 bytes at the end of + * our buffer to handle the over-write. + */ + { U64 const add = 0x0101010101010101ull; + size_t pos = 0; + U64 sv = 0; + U32 s; + for (s=0; s highThreshold) position = (position + step) & tableMask; /* lowprob area */ + } } + if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ + } + + /* Build Decoding table */ + { U32 u; + for (u=0; u sizeof(bitD.bitContainer)*8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[1] = FSE_GETSYMBOL(&state2); + + if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } } + + op[2] = FSE_GETSYMBOL(&state1); + + if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ + BIT_reloadDStream(&bitD); + + op[3] = FSE_GETSYMBOL(&state2); + } + + /* tail */ + /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */ + while (1) { + if (op>(omax-2)) return ERROR(dstSize_tooSmall); + *op++ = FSE_GETSYMBOL(&state1); + if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { + *op++ = FSE_GETSYMBOL(&state2); + break; + } + + if (op>(omax-2)) return ERROR(dstSize_tooSmall); + *op++ = FSE_GETSYMBOL(&state2); + if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) { + *op++ = FSE_GETSYMBOL(&state1); + break; + } } + + assert(op >= ostart); + return (size_t)(op-ostart); +} + +typedef struct { + short ncount[FSE_MAX_SYMBOL_VALUE + 1]; +} FSE_DecompressWksp; + + +FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body( + void* dst, size_t dstCapacity, + const void* cSrc, size_t cSrcSize, + unsigned maxLog, void* workSpace, size_t wkspSize, + int bmi2) +{ + const BYTE* const istart = (const BYTE*)cSrc; + const BYTE* ip = istart; + unsigned tableLog; + unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; + FSE_DecompressWksp* const wksp = (FSE_DecompressWksp*)workSpace; + size_t const dtablePos = sizeof(FSE_DecompressWksp) / sizeof(FSE_DTable); + FSE_DTable* const dtable = (FSE_DTable*)workSpace + dtablePos; + + FSE_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0); + if (wkspSize < sizeof(*wksp)) return ERROR(GENERIC); + + /* correct offset to dtable depends on this property */ + FSE_STATIC_ASSERT(sizeof(FSE_DecompressWksp) % sizeof(FSE_DTable) == 0); + + /* normal FSE decoding mode */ + { size_t const NCountLength = + FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2); + if (FSE_isError(NCountLength)) return NCountLength; + if (tableLog > maxLog) return ERROR(tableLog_tooLarge); + assert(NCountLength <= cSrcSize); + ip += NCountLength; + cSrcSize -= NCountLength; + } + + if (FSE_DECOMPRESS_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(tableLog_tooLarge); + assert(sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog) <= wkspSize); + workSpace = (BYTE*)workSpace + sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog); + wkspSize -= sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog); + + CHECK_F( FSE_buildDTable_internal(dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) ); + + { + const void* ptr = dtable; + const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr; + const U32 fastMode = DTableH->fastMode; + + /* select fast mode (static) */ + if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 1); + return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, dtable, 0); + } +} + +/* Avoids the FORCE_INLINE of the _body() function. */ +static size_t FSE_decompress_wksp_body_default(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize) +{ + return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 0); +} + +#if DYNAMIC_BMI2 +BMI2_TARGET_ATTRIBUTE static size_t FSE_decompress_wksp_body_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize) +{ + return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 1); +} +#endif + +size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2) +{ +#if DYNAMIC_BMI2 + if (bmi2) { + return FSE_decompress_wksp_body_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize); + } +#endif + (void)bmi2; + return FSE_decompress_wksp_body_default(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize); +} + +#endif /* FSE_COMMONDEFS_ONLY */ diff --git a/src/commonlib/bsd/zstd/common/huf.h b/src/commonlib/bsd/zstd/common/huf.h new file mode 100644 index 00000000000..c7c0f3fd43b --- /dev/null +++ b/src/commonlib/bsd/zstd/common/huf.h @@ -0,0 +1,279 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * huff0 huffman codec, + * part of Finite State Entropy library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +#ifndef HUF_H_298734234 +#define HUF_H_298734234 + +/* *** Dependencies *** */ +#include "zstd_deps.h" /* size_t */ +#include "mem.h" /* U32 */ +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" + +/* *** Tool functions *** */ +#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */ +size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */ + +/* Error Management */ +unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */ +const char* HUF_getErrorName(size_t code); /**< provides error code string (useful for debugging) */ + + +#define HUF_WORKSPACE_SIZE ((8 << 10) + 512 /* sorting scratch space */) +#define HUF_WORKSPACE_SIZE_U64 (HUF_WORKSPACE_SIZE / sizeof(U64)) + +/* *** Constants *** */ +#define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_TABLELOG_ABSOLUTEMAX */ +#define HUF_TABLELOG_DEFAULT 11 /* default tableLog value when none specified */ +#define HUF_SYMBOLVALUE_MAX 255 + +#define HUF_TABLELOG_ABSOLUTEMAX 12 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */ +#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX) +# error "HUF_TABLELOG_MAX is too large !" +#endif + + +/* **************************************** +* Static allocation +******************************************/ +/* HUF buffer bounds */ +#define HUF_CTABLEBOUND 129 +#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true when incompressible is pre-filtered with fast heuristic */ +#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */ + +/* static allocation of HUF's Compression Table */ +/* this is a private definition, just exposed for allocation and strict aliasing purpose. never EVER access its members directly */ +typedef size_t HUF_CElt; /* consider it an incomplete type */ +#define HUF_CTABLE_SIZE_ST(maxSymbolValue) ((maxSymbolValue)+2) /* Use tables of size_t, for proper alignment */ +#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_ST(maxSymbolValue) * sizeof(size_t)) +#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \ + HUF_CElt name[HUF_CTABLE_SIZE_ST(maxSymbolValue)] /* no final ; */ + +/* static allocation of HUF's DTable */ +typedef U32 HUF_DTable; +#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog))) +#define HUF_CREATE_STATIC_DTABLEX1(DTable, maxTableLog) \ + HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) } +#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \ + HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) } + + +/* **************************************** +* Advanced decompression functions +******************************************/ + +/** + * Huffman flags bitset. + * For all flags, 0 is the default value. + */ +typedef enum { + /** + * If compiled with DYNAMIC_BMI2: Set flag only if the CPU supports BMI2 at runtime. + * Otherwise: Ignored. + */ + HUF_flags_bmi2 = (1 << 0), + /** + * If set: Test possible table depths to find the one that produces the smallest header + encoded size. + * If unset: Use heuristic to find the table depth. + */ + HUF_flags_optimalDepth = (1 << 1), + /** + * If set: If the previous table can encode the input, always reuse the previous table. + * If unset: If the previous table can encode the input, reuse the previous table if it results in a smaller output. + */ + HUF_flags_preferRepeat = (1 << 2), + /** + * If set: Sample the input and check if the sample is uncompressible, if it is then don't attempt to compress. + * If unset: Always histogram the entire input. + */ + HUF_flags_suspectUncompressible = (1 << 3), + /** + * If set: Don't use assembly implementations + * If unset: Allow using assembly implementations + */ + HUF_flags_disableAsm = (1 << 4), + /** + * If set: Don't use the fast decoding loop, always use the fallback decoding loop. + * If unset: Use the fast decoding loop when possible. + */ + HUF_flags_disableFast = (1 << 5) +} HUF_flags_e; + + +/* **************************************** + * HUF detailed API + * ****************************************/ +#define HUF_OPTIMAL_DEPTH_THRESHOLD ZSTD_btultra + +/*! HUF_compress() does the following: + * 1. count symbol occurrence from source[] into table count[] using FSE_count() (exposed within "fse.h") + * 2. (optional) refine tableLog using HUF_optimalTableLog() + * 3. build Huffman table from count using HUF_buildCTable() + * 4. save Huffman table to memory buffer using HUF_writeCTable() + * 5. encode the data stream using HUF_compress4X_usingCTable() + * + * The following API allows targeting specific sub-functions for advanced tasks. + * For example, it's possible to compress several blocks using the same 'CTable', + * or to save and regenerate 'CTable' using external methods. + */ +unsigned HUF_minTableLog(unsigned symbolCardinality); +unsigned HUF_cardinality(const unsigned* count, unsigned maxSymbolValue); +unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, void* workSpace, + size_t wkspSize, HUF_CElt* table, const unsigned* count, int flags); /* table is used as scratch space for building and testing tables, not a return value */ +size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, void* workspace, size_t workspaceSize); +size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags); +size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue); +int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue); + +typedef enum { + HUF_repeat_none, /**< Cannot use the previous table */ + HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */ + HUF_repeat_valid /**< Can use the previous table and it is assumed to be valid */ + } HUF_repeat; + +/** HUF_compress4X_repeat() : + * Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. + * If it uses hufTable it does not modify hufTable or repeat. + * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. + * If preferRepeat then the old table will always be used if valid. + * If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */ +size_t HUF_compress4X_repeat(void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog, + void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ + HUF_CElt* hufTable, HUF_repeat* repeat, int flags); + +/** HUF_buildCTable_wksp() : + * Same as HUF_buildCTable(), but using externally allocated scratch buffer. + * `workSpace` must be aligned on 4-bytes boundaries, and its size must be >= HUF_CTABLE_WORKSPACE_SIZE. + */ +#define HUF_CTABLE_WORKSPACE_SIZE_U32 ((4 * (HUF_SYMBOLVALUE_MAX + 1)) + 192) +#define HUF_CTABLE_WORKSPACE_SIZE (HUF_CTABLE_WORKSPACE_SIZE_U32 * sizeof(unsigned)) +size_t HUF_buildCTable_wksp (HUF_CElt* tree, + const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, + void* workSpace, size_t wkspSize); + +/*! HUF_readStats() : + * Read compact Huffman tree, saved by HUF_writeCTable(). + * `huffWeight` is destination buffer. + * @return : size read from `src` , or an error Code . + * Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */ +size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, + U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize); + +/*! HUF_readStats_wksp() : + * Same as HUF_readStats() but takes an external workspace which must be + * 4-byte aligned and its size must be >= HUF_READ_STATS_WORKSPACE_SIZE. + * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0. + */ +#define HUF_READ_STATS_WORKSPACE_SIZE_U32 FSE_DECOMPRESS_WKSP_SIZE_U32(6, HUF_TABLELOG_MAX-1) +#define HUF_READ_STATS_WORKSPACE_SIZE (HUF_READ_STATS_WORKSPACE_SIZE_U32 * sizeof(unsigned)) +size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, + U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr, + const void* src, size_t srcSize, + void* workspace, size_t wkspSize, + int flags); + +/** HUF_readCTable() : + * Loading a CTable saved with HUF_writeCTable() */ +size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned *hasZeroWeights); + +/** HUF_getNbBitsFromCTable() : + * Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX + * Note 1 : If symbolValue > HUF_readCTableHeader(symbolTable).maxSymbolValue, returns 0 + * Note 2 : is not inlined, as HUF_CElt definition is private + */ +U32 HUF_getNbBitsFromCTable(const HUF_CElt* symbolTable, U32 symbolValue); + +typedef struct { + BYTE tableLog; + BYTE maxSymbolValue; + BYTE unused[sizeof(size_t) - 2]; +} HUF_CTableHeader; + +/** HUF_readCTableHeader() : + * @returns The header from the CTable specifying the tableLog and the maxSymbolValue. + */ +HUF_CTableHeader HUF_readCTableHeader(HUF_CElt const* ctable); + +/* + * HUF_decompress() does the following: + * 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics + * 2. build Huffman table from save, using HUF_readDTableX?() + * 3. decode 1 or 4 segments in parallel using HUF_decompress?X?_usingDTable() + */ + +/** HUF_selectDecoder() : + * Tells which decoder is likely to decode faster, + * based on a set of pre-computed metrics. + * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 . + * Assumption : 0 < dstSize <= 128 KB */ +U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize); + +/** + * The minimum workspace size for the `workSpace` used in + * HUF_readDTableX1_wksp() and HUF_readDTableX2_wksp(). + * + * The space used depends on HUF_TABLELOG_MAX, ranging from ~1500 bytes when + * HUF_TABLE_LOG_MAX=12 to ~1850 bytes when HUF_TABLE_LOG_MAX=15. + * Buffer overflow errors may potentially occur if code modifications result in + * a required workspace size greater than that specified in the following + * macro. + */ +#define HUF_DECOMPRESS_WORKSPACE_SIZE ((2 << 10) + (1 << 9)) +#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) + + +/* ====================== */ +/* single stream variants */ +/* ====================== */ + +size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags); +/** HUF_compress1X_repeat() : + * Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. + * If it uses hufTable it does not modify hufTable or repeat. + * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used. + * If preferRepeat then the old table will always be used if valid. + * If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */ +size_t HUF_compress1X_repeat(void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned tableLog, + void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */ + HUF_CElt* hufTable, HUF_repeat* repeat, int flags); + +size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags); +#ifndef HUF_FORCE_DECOMPRESS_X1 +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags); /**< double-symbols decoder */ +#endif + +/* BMI2 variants. + * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0. + */ +size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags); +#ifndef HUF_FORCE_DECOMPRESS_X2 +size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags); +#endif +size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags); +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags); +#ifndef HUF_FORCE_DECOMPRESS_X2 +size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags); +#endif +#ifndef HUF_FORCE_DECOMPRESS_X1 +size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags); +#endif + +#endif /* HUF_H_298734234 */ diff --git a/src/commonlib/bsd/zstd/common/mem.h b/src/commonlib/bsd/zstd/common/mem.h new file mode 100644 index 00000000000..4b2a4aebefe --- /dev/null +++ b/src/commonlib/bsd/zstd/common/mem.h @@ -0,0 +1,424 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef MEM_H_MODULE +#define MEM_H_MODULE + +/*-**************************************** +* Dependencies +******************************************/ +#include /* size_t, ptrdiff_t */ +#include "zstd_compiler.h" /* __has_builtin */ +#include "debug.h" /* DEBUG_STATIC_ASSERT */ +#include "zstd_deps.h" /* ZSTD_memcpy */ + + +/*-**************************************** +* Compiler specifics +******************************************/ +#if defined(_MSC_VER) /* Visual Studio */ +# include /* _byteswap_ulong */ +# include /* _byteswap_* */ +#elif defined(__ICCARM__) +# include +#endif + +/*-************************************************************** +* Basic Types +*****************************************************************/ +#if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) +# if defined(_AIX) +# include +# else +# include /* intptr_t */ +# endif + typedef uint8_t BYTE; + typedef uint8_t U8; + typedef int8_t S8; + typedef uint16_t U16; + typedef int16_t S16; + typedef uint32_t U32; + typedef int32_t S32; + typedef uint64_t U64; + typedef int64_t S64; +#else +# include +#if CHAR_BIT != 8 +# error "this implementation requires char to be exactly 8-bit type" +#endif + typedef unsigned char BYTE; + typedef unsigned char U8; + typedef signed char S8; +#if USHRT_MAX != 65535 +# error "this implementation requires short to be exactly 16-bit type" +#endif + typedef unsigned short U16; + typedef signed short S16; +#if UINT_MAX != 4294967295 +# error "this implementation requires int to be exactly 32-bit type" +#endif + typedef unsigned int U32; + typedef signed int S32; +/* note : there are no limits defined for long long type in C90. + * limits exist in C99, however, in such case, is preferred */ + typedef unsigned long long U64; + typedef signed long long S64; +#endif + +/*-************************************************************** +* Memory I/O API +*****************************************************************/ +/*=== Static platform detection ===*/ +MEM_STATIC unsigned MEM_32bits(void); +MEM_STATIC unsigned MEM_64bits(void); +MEM_STATIC unsigned MEM_isLittleEndian(void); + +/*=== Native unaligned read/write ===*/ +MEM_STATIC U16 MEM_read16(const void* memPtr); +MEM_STATIC U32 MEM_read32(const void* memPtr); +MEM_STATIC U64 MEM_read64(const void* memPtr); +MEM_STATIC size_t MEM_readST(const void* memPtr); + +MEM_STATIC void MEM_write16(void* memPtr, U16 value); +MEM_STATIC void MEM_write32(void* memPtr, U32 value); +MEM_STATIC void MEM_write64(void* memPtr, U64 value); + +/*=== Little endian unaligned read/write ===*/ +MEM_STATIC U16 MEM_readLE16(const void* memPtr); +MEM_STATIC U32 MEM_readLE24(const void* memPtr); +MEM_STATIC U32 MEM_readLE32(const void* memPtr); +MEM_STATIC U64 MEM_readLE64(const void* memPtr); +MEM_STATIC size_t MEM_readLEST(const void* memPtr); + +MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val); +MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val); +MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32); +MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64); +MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val); + +/*=== Big endian unaligned read/write ===*/ +MEM_STATIC U32 MEM_readBE32(const void* memPtr); +MEM_STATIC U64 MEM_readBE64(const void* memPtr); +MEM_STATIC size_t MEM_readBEST(const void* memPtr); + +MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32); +MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64); +MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val); + +/*=== Byteswap ===*/ +MEM_STATIC U32 MEM_swap32(U32 in); +MEM_STATIC U64 MEM_swap64(U64 in); +MEM_STATIC size_t MEM_swapST(size_t in); + + +/*-************************************************************** +* Memory I/O Implementation +*****************************************************************/ +/* MEM_FORCE_MEMORY_ACCESS : For accessing unaligned memory: + * Method 0 : always use `memcpy()`. Safe and portable. + * Method 1 : Use compiler extension to set unaligned access. + * Method 2 : direct access. This method is portable but violate C standard. + * It can generate buggy code on targets depending on alignment. + * Default : method 1 if supported, else method 0 + */ +#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ +# ifdef __GNUC__ +# define MEM_FORCE_MEMORY_ACCESS 1 +# endif +#endif + +MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; } +MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; } + +MEM_STATIC unsigned MEM_isLittleEndian(void) +{ +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + return 1; +#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + return 0; +#elif defined(__clang__) && __LITTLE_ENDIAN__ + return 1; +#elif defined(__clang__) && __BIG_ENDIAN__ + return 0; +#elif defined(_MSC_VER) && (_M_X64 || _M_IX86) + return 1; +#elif defined(__DMC__) && defined(_M_IX86) + return 1; +#elif defined(__IAR_SYSTEMS_ICC__) && __LITTLE_ENDIAN__ + return 1; +#else + const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ + return one.c[0]; +#endif +} + +#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) + +/* violates C standard, by lying on structure alignment. +Only use if no other choice to achieve best performance on target platform */ +MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } +MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } +MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } +MEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; } + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } +MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } +MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; } + +#elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) + +typedef __attribute__((aligned(1))) U16 unalign16; +typedef __attribute__((aligned(1))) U32 unalign32; +typedef __attribute__((aligned(1))) U64 unalign64; +typedef __attribute__((aligned(1))) size_t unalignArch; + +MEM_STATIC U16 MEM_read16(const void* ptr) { return *(const unalign16*)ptr; } +MEM_STATIC U32 MEM_read32(const void* ptr) { return *(const unalign32*)ptr; } +MEM_STATIC U64 MEM_read64(const void* ptr) { return *(const unalign64*)ptr; } +MEM_STATIC size_t MEM_readST(const void* ptr) { return *(const unalignArch*)ptr; } + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(unalign16*)memPtr = value; } +MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(unalign32*)memPtr = value; } +MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(unalign64*)memPtr = value; } + +#else + +/* default method, safe and standard. + can sometimes prove slower */ + +MEM_STATIC U16 MEM_read16(const void* memPtr) +{ + U16 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC U32 MEM_read32(const void* memPtr) +{ + U32 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC U64 MEM_read64(const void* memPtr) +{ + U64 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC size_t MEM_readST(const void* memPtr) +{ + size_t val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val; +} + +MEM_STATIC void MEM_write16(void* memPtr, U16 value) +{ + ZSTD_memcpy(memPtr, &value, sizeof(value)); +} + +MEM_STATIC void MEM_write32(void* memPtr, U32 value) +{ + ZSTD_memcpy(memPtr, &value, sizeof(value)); +} + +MEM_STATIC void MEM_write64(void* memPtr, U64 value) +{ + ZSTD_memcpy(memPtr, &value, sizeof(value)); +} + +#endif /* MEM_FORCE_MEMORY_ACCESS */ + +MEM_STATIC U32 MEM_swap32_fallback(U32 in) +{ + return ((in << 24) & 0xff000000 ) | + ((in << 8) & 0x00ff0000 ) | + ((in >> 8) & 0x0000ff00 ) | + ((in >> 24) & 0x000000ff ); +} + +MEM_STATIC U32 MEM_swap32(U32 in) +{ +#if defined(_MSC_VER) /* Visual Studio */ + return _byteswap_ulong(in); +#elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \ + || (defined(__clang__) && __has_builtin(__builtin_bswap32)) + return __builtin_bswap32(in); +#elif defined(__ICCARM__) + return __REV(in); +#else + return MEM_swap32_fallback(in); +#endif +} + +MEM_STATIC U64 MEM_swap64_fallback(U64 in) +{ + return ((in << 56) & 0xff00000000000000ULL) | + ((in << 40) & 0x00ff000000000000ULL) | + ((in << 24) & 0x0000ff0000000000ULL) | + ((in << 8) & 0x000000ff00000000ULL) | + ((in >> 8) & 0x00000000ff000000ULL) | + ((in >> 24) & 0x0000000000ff0000ULL) | + ((in >> 40) & 0x000000000000ff00ULL) | + ((in >> 56) & 0x00000000000000ffULL); +} + +MEM_STATIC U64 MEM_swap64(U64 in) +{ +#if defined(_MSC_VER) /* Visual Studio */ + return _byteswap_uint64(in); +#elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \ + || (defined(__clang__) && __has_builtin(__builtin_bswap64)) + return __builtin_bswap64(in); +#else + return MEM_swap64_fallback(in); +#endif +} + +MEM_STATIC size_t MEM_swapST(size_t in) +{ + if (MEM_32bits()) + return (size_t)MEM_swap32((U32)in); + else + return (size_t)MEM_swap64((U64)in); +} + +/*=== Little endian r/w ===*/ + +MEM_STATIC U16 MEM_readLE16(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read16(memPtr); + else { + const BYTE* p = (const BYTE*)memPtr; + return (U16)(p[0] + (p[1]<<8)); + } +} + +MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val) +{ + if (MEM_isLittleEndian()) { + MEM_write16(memPtr, val); + } else { + BYTE* p = (BYTE*)memPtr; + p[0] = (BYTE)val; + p[1] = (BYTE)(val>>8); + } +} + +MEM_STATIC U32 MEM_readLE24(const void* memPtr) +{ + return (U32)MEM_readLE16(memPtr) + ((U32)(((const BYTE*)memPtr)[2]) << 16); +} + +MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val) +{ + MEM_writeLE16(memPtr, (U16)val); + ((BYTE*)memPtr)[2] = (BYTE)(val>>16); +} + +MEM_STATIC U32 MEM_readLE32(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read32(memPtr); + else + return MEM_swap32(MEM_read32(memPtr)); +} + +MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32) +{ + if (MEM_isLittleEndian()) + MEM_write32(memPtr, val32); + else + MEM_write32(memPtr, MEM_swap32(val32)); +} + +MEM_STATIC U64 MEM_readLE64(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_read64(memPtr); + else + return MEM_swap64(MEM_read64(memPtr)); +} + +MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64) +{ + if (MEM_isLittleEndian()) + MEM_write64(memPtr, val64); + else + MEM_write64(memPtr, MEM_swap64(val64)); +} + +MEM_STATIC size_t MEM_readLEST(const void* memPtr) +{ + if (MEM_32bits()) + return (size_t)MEM_readLE32(memPtr); + else + return (size_t)MEM_readLE64(memPtr); +} + +MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val) +{ + if (MEM_32bits()) + MEM_writeLE32(memPtr, (U32)val); + else + MEM_writeLE64(memPtr, (U64)val); +} + +/*=== Big endian r/w ===*/ + +MEM_STATIC U32 MEM_readBE32(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_swap32(MEM_read32(memPtr)); + else + return MEM_read32(memPtr); +} + +MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32) +{ + if (MEM_isLittleEndian()) + MEM_write32(memPtr, MEM_swap32(val32)); + else + MEM_write32(memPtr, val32); +} + +MEM_STATIC U64 MEM_readBE64(const void* memPtr) +{ + if (MEM_isLittleEndian()) + return MEM_swap64(MEM_read64(memPtr)); + else + return MEM_read64(memPtr); +} + +MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64) +{ + if (MEM_isLittleEndian()) + MEM_write64(memPtr, MEM_swap64(val64)); + else + MEM_write64(memPtr, val64); +} + +MEM_STATIC size_t MEM_readBEST(const void* memPtr) +{ + if (MEM_32bits()) + return (size_t)MEM_readBE32(memPtr); + else + return (size_t)MEM_readBE64(memPtr); +} + +MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val) +{ + if (MEM_32bits()) + MEM_writeBE32(memPtr, (U32)val); + else + MEM_writeBE64(memPtr, (U64)val); +} + +/* code only tested on 32 and 64 bits systems */ +MEM_STATIC void MEM_check(void) { DEBUG_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); } + +#endif /* MEM_H_MODULE */ diff --git a/src/commonlib/bsd/zstd/common/portability_macros.h b/src/commonlib/bsd/zstd/common/portability_macros.h new file mode 100644 index 00000000000..e61f0784d34 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/portability_macros.h @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_PORTABILITY_MACROS_H +#define ZSTD_PORTABILITY_MACROS_H + +/** + * This header file contains macro definitions to support portability. + * This header is shared between C and ASM code, so it MUST only + * contain macro definitions. It MUST not contain any C code. + * + * This header ONLY defines macros to detect platforms/feature support. + * + */ + + +/* compat. with non-clang compilers */ +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif + +/* compat. with non-clang compilers */ +#ifndef __has_builtin +# define __has_builtin(x) 0 +#endif + +/* compat. with non-clang compilers */ +#ifndef __has_feature +# define __has_feature(x) 0 +#endif + +/* detects whether we are being compiled under msan */ +#ifndef ZSTD_MEMORY_SANITIZER +# if __has_feature(memory_sanitizer) +# define ZSTD_MEMORY_SANITIZER 1 +# else +# define ZSTD_MEMORY_SANITIZER 0 +# endif +#endif + +/* detects whether we are being compiled under asan */ +#ifndef ZSTD_ADDRESS_SANITIZER +# if __has_feature(address_sanitizer) +# define ZSTD_ADDRESS_SANITIZER 1 +# elif defined(__SANITIZE_ADDRESS__) +# define ZSTD_ADDRESS_SANITIZER 1 +# else +# define ZSTD_ADDRESS_SANITIZER 0 +# endif +#endif + +/* detects whether we are being compiled under dfsan */ +#ifndef ZSTD_DATAFLOW_SANITIZER +# if __has_feature(dataflow_sanitizer) +# define ZSTD_DATAFLOW_SANITIZER 1 +# else +# define ZSTD_DATAFLOW_SANITIZER 0 +# endif +#endif + +/* Mark the internal assembly functions as hidden */ +#ifdef __ELF__ +# define ZSTD_HIDE_ASM_FUNCTION(func) .hidden func +#elif defined(__APPLE__) +# define ZSTD_HIDE_ASM_FUNCTION(func) .private_extern func +#else +# define ZSTD_HIDE_ASM_FUNCTION(func) +#endif + +/* Compile time determination of BMI2 support */ +#ifndef STATIC_BMI2 +# if defined(__BMI2__) +# define STATIC_BMI2 1 +# elif defined(_MSC_VER) && defined(__AVX2__) +# define STATIC_BMI2 1 /* MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2 */ +# endif +#endif + +#ifndef STATIC_BMI2 +# define STATIC_BMI2 0 +#endif + +/* Enable runtime BMI2 dispatch based on the CPU. + * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default. + */ +#ifndef DYNAMIC_BMI2 +# if ((defined(__clang__) && __has_attribute(__target__)) \ + || (defined(__GNUC__) \ + && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \ + && (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)) \ + && !defined(__BMI2__) +# define DYNAMIC_BMI2 1 +# else +# define DYNAMIC_BMI2 0 +# endif +#endif + +/** + * Only enable assembly for GNU C compatible compilers, + * because other platforms may not support GAS assembly syntax. + * + * Only enable assembly for Linux / MacOS / Win32, other platforms may + * work, but they haven't been tested. This could likely be + * extended to BSD systems. + * + * Disable assembly when MSAN is enabled, because MSAN requires + * 100% of code to be instrumented to work. + */ +#if defined(__GNUC__) +# if defined(__linux__) || defined(__linux) || defined(__APPLE__) || defined(_WIN32) +# if ZSTD_MEMORY_SANITIZER +# define ZSTD_ASM_SUPPORTED 0 +# elif ZSTD_DATAFLOW_SANITIZER +# define ZSTD_ASM_SUPPORTED 0 +# else +# define ZSTD_ASM_SUPPORTED 1 +# endif +# else +# define ZSTD_ASM_SUPPORTED 0 +# endif +#else +# define ZSTD_ASM_SUPPORTED 0 +#endif + +/** + * Determines whether we should enable assembly for x86-64 + * with BMI2. + * + * Enable if all of the following conditions hold: + * - ASM hasn't been explicitly disabled by defining ZSTD_DISABLE_ASM + * - Assembly is supported + * - We are compiling for x86-64 and either: + * - DYNAMIC_BMI2 is enabled + * - BMI2 is supported at compile time + */ +#if !defined(ZSTD_DISABLE_ASM) && \ + ZSTD_ASM_SUPPORTED && \ + defined(__x86_64__) && \ + (DYNAMIC_BMI2 || defined(__BMI2__)) +# define ZSTD_ENABLE_ASM_X86_64_BMI2 1 +#else +# define ZSTD_ENABLE_ASM_X86_64_BMI2 0 +#endif + +/* + * For x86 ELF targets, add .note.gnu.property section for Intel CET in + * assembly sources when CET is enabled. + * + * Additionally, any function that may be called indirectly must begin + * with ZSTD_CET_ENDBRANCH. + */ +#if defined(__ELF__) && (defined(__x86_64__) || defined(__i386__)) \ + && defined(__has_include) +# if __has_include() +# include +# define ZSTD_CET_ENDBRANCH _CET_ENDBR +# endif +#endif + +#ifndef ZSTD_CET_ENDBRANCH +# define ZSTD_CET_ENDBRANCH +#endif + +#endif /* ZSTD_PORTABILITY_MACROS_H */ diff --git a/src/commonlib/bsd/zstd/common/zstd_bits.h b/src/commonlib/bsd/zstd/common/zstd_bits.h new file mode 100644 index 00000000000..5128d00ccfb --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_bits.h @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_BITS_H +#define ZSTD_BITS_H + +#include "mem.h" + +MEM_STATIC unsigned ZSTD_countTrailingZeros32_fallback(U32 val) +{ + assert(val != 0); + { + static const U32 DeBruijnBytePos[32] = {0, 1, 28, 2, 29, 14, 24, 3, + 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, + 26, 12, 18, 6, 11, 5, 10, 9}; + return DeBruijnBytePos[((U32) ((val & -(S32) val) * 0x077CB531U)) >> 27]; + } +} + +MEM_STATIC unsigned ZSTD_countTrailingZeros32(U32 val) +{ + assert(val != 0); +#if defined(_MSC_VER) +# if STATIC_BMI2 + return (unsigned)_tzcnt_u32(val); +# else + if (val != 0) { + unsigned long r; + _BitScanForward(&r, val); + return (unsigned)r; + } else { + __assume(0); /* Should not reach this code path */ + } +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) + return (unsigned)__builtin_ctz(val); +#elif defined(__ICCARM__) + return (unsigned)__builtin_ctz(val); +#else + return ZSTD_countTrailingZeros32_fallback(val); +#endif +} + +MEM_STATIC unsigned ZSTD_countLeadingZeros32_fallback(U32 val) +{ + assert(val != 0); + { + static const U32 DeBruijnClz[32] = {0, 9, 1, 10, 13, 21, 2, 29, + 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, + 19, 27, 23, 6, 26, 5, 4, 31}; + val |= val >> 1; + val |= val >> 2; + val |= val >> 4; + val |= val >> 8; + val |= val >> 16; + return 31 - DeBruijnClz[(val * 0x07C4ACDDU) >> 27]; + } +} + +MEM_STATIC unsigned ZSTD_countLeadingZeros32(U32 val) +{ + assert(val != 0); +#if defined(_MSC_VER) +# if STATIC_BMI2 + return (unsigned)_lzcnt_u32(val); +# else + if (val != 0) { + unsigned long r; + _BitScanReverse(&r, val); + return (unsigned)(31 - r); + } else { + __assume(0); /* Should not reach this code path */ + } +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) + return (unsigned)__builtin_clz(val); +#elif defined(__ICCARM__) + return (unsigned)__builtin_clz(val); +#else + return ZSTD_countLeadingZeros32_fallback(val); +#endif +} + +MEM_STATIC unsigned ZSTD_countTrailingZeros64(U64 val) +{ + assert(val != 0); +#if defined(_MSC_VER) && defined(_WIN64) +# if STATIC_BMI2 + return (unsigned)_tzcnt_u64(val); +# else + if (val != 0) { + unsigned long r; + _BitScanForward64(&r, val); + return (unsigned)r; + } else { + __assume(0); /* Should not reach this code path */ + } +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) && defined(__LP64__) + return (unsigned)__builtin_ctzll(val); +#elif defined(__ICCARM__) + return (unsigned)__builtin_ctzll(val); +#else + { + U32 mostSignificantWord = (U32)(val >> 32); + U32 leastSignificantWord = (U32)val; + if (leastSignificantWord == 0) { + return 32 + ZSTD_countTrailingZeros32(mostSignificantWord); + } else { + return ZSTD_countTrailingZeros32(leastSignificantWord); + } + } +#endif +} + +MEM_STATIC unsigned ZSTD_countLeadingZeros64(U64 val) +{ + assert(val != 0); +#if defined(_MSC_VER) && defined(_WIN64) +# if STATIC_BMI2 + return (unsigned)_lzcnt_u64(val); +# else + if (val != 0) { + unsigned long r; + _BitScanReverse64(&r, val); + return (unsigned)(63 - r); + } else { + __assume(0); /* Should not reach this code path */ + } +# endif +#elif defined(__GNUC__) && (__GNUC__ >= 4) + return (unsigned)(__builtin_clzll(val)); +#elif defined(__ICCARM__) + return (unsigned)(__builtin_clzll(val)); +#else + { + U32 mostSignificantWord = (U32)(val >> 32); + U32 leastSignificantWord = (U32)val; + if (mostSignificantWord == 0) { + return 32 + ZSTD_countLeadingZeros32(leastSignificantWord); + } else { + return ZSTD_countLeadingZeros32(mostSignificantWord); + } + } +#endif +} + +MEM_STATIC unsigned ZSTD_NbCommonBytes(size_t val) +{ + if (MEM_isLittleEndian()) { + if (MEM_64bits()) { + return ZSTD_countTrailingZeros64((U64)val) >> 3; + } else { + return ZSTD_countTrailingZeros32((U32)val) >> 3; + } + } else { /* Big Endian CPU */ + if (MEM_64bits()) { + return ZSTD_countLeadingZeros64((U64)val) >> 3; + } else { + return ZSTD_countLeadingZeros32((U32)val) >> 3; + } + } +} + +MEM_STATIC unsigned ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */ +{ + assert(val != 0); + return 31 - ZSTD_countLeadingZeros32(val); +} + +/* ZSTD_rotateRight_*(): + * Rotates a bitfield to the right by "count" bits. + * https://en.wikipedia.org/w/index.php?title=Circular_shift&oldid=991635599#Implementing_circular_shifts + */ +MEM_STATIC +U64 ZSTD_rotateRight_U64(U64 const value, U32 count) { + assert(count < 64); + count &= 0x3F; /* for fickle pattern recognition */ + return (value >> count) | (U64)(value << ((0U - count) & 0x3F)); +} + +MEM_STATIC +U32 ZSTD_rotateRight_U32(U32 const value, U32 count) { + assert(count < 32); + count &= 0x1F; /* for fickle pattern recognition */ + return (value >> count) | (U32)(value << ((0U - count) & 0x1F)); +} + +MEM_STATIC +U16 ZSTD_rotateRight_U16(U16 const value, U32 count) { + assert(count < 16); + count &= 0x0F; /* for fickle pattern recognition */ + return (value >> count) | (U16)(value << ((0U - count) & 0x0F)); +} + +#endif /* ZSTD_BITS_H */ diff --git a/src/commonlib/bsd/zstd/common/zstd_common.c b/src/commonlib/bsd/zstd/common/zstd_common.c new file mode 100644 index 00000000000..9b551ec8676 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_common.c @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + + +/*-************************************* +* Dependencies +***************************************/ +#define ZSTD_DEPS_NEED_MALLOC +#include "error_private.h" +#include "zstd_internal.h" + + +/*-**************************************** +* Version +******************************************/ +unsigned ZSTD_versionNumber(void) { return ZSTD_VERSION_NUMBER; } + +const char* ZSTD_versionString(void) { return ZSTD_VERSION_STRING; } + + +/*-**************************************** +* ZSTD Error Management +******************************************/ +#undef ZSTD_isError /* defined within zstd_internal.h */ +/*! ZSTD_isError() : + * tells if a return value is an error code + * symbol is required for external callers */ +unsigned ZSTD_isError(size_t code) { return ERR_isError(code); } + +/*! ZSTD_getErrorName() : + * provides error code string from function result (useful for debugging) */ +const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); } + +/*! ZSTD_getError() : + * convert a `size_t` function result into a proper ZSTD_errorCode enum */ +ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); } + +/*! ZSTD_getErrorString() : + * provides error code string from enum */ +const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString(code); } diff --git a/src/commonlib/bsd/zstd/common/zstd_compiler.h b/src/commonlib/bsd/zstd/common/zstd_compiler.h new file mode 100644 index 00000000000..80df87162e0 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_compiler.h @@ -0,0 +1,462 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPILER_H +#define ZSTD_COMPILER_H + +#include + +#include "portability_macros.h" + +/*-******************************************************* +* Compiler specifics +*********************************************************/ +/* force inlining */ + +#if !defined(ZSTD_NO_INLINE) +#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ +# define INLINE_KEYWORD inline +#else +# define INLINE_KEYWORD +#endif + +#if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) +# define FORCE_INLINE_ATTR __attribute__((always_inline)) +#elif defined(_MSC_VER) +# define FORCE_INLINE_ATTR __forceinline +#else +# define FORCE_INLINE_ATTR +#endif + +#else + +#define INLINE_KEYWORD +#define FORCE_INLINE_ATTR + +#endif + +/** + On MSVC qsort requires that functions passed into it use the __cdecl calling conversion(CC). + This explicitly marks such functions as __cdecl so that the code will still compile + if a CC other than __cdecl has been made the default. +*/ +#if defined(_MSC_VER) +# define WIN_CDECL __cdecl +#else +# define WIN_CDECL +#endif + +/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */ +#if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) +# define UNUSED_ATTR __attribute__((unused)) +#else +# define UNUSED_ATTR +#endif + +/** + * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant + * parameters. They must be inlined for the compiler to eliminate the constant + * branches. + */ +#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR UNUSED_ATTR +/** + * HINT_INLINE is used to help the compiler generate better code. It is *not* + * used for "templates", so it can be tweaked based on the compilers + * performance. + * + * gcc-4.8 and gcc-4.9 have been shown to benefit from leaving off the + * always_inline attribute. + * + * clang up to 5.0.0 (trunk) benefit tremendously from the always_inline + * attribute. + */ +#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5 +# define HINT_INLINE static INLINE_KEYWORD +#else +# define HINT_INLINE FORCE_INLINE_TEMPLATE +#endif + +/* "soft" inline : + * The compiler is free to select if it's a good idea to inline or not. + * The main objective is to silence compiler warnings + * when a defined function in included but not used. + * + * Note : this macro is prefixed `MEM_` because it used to be provided by `mem.h` unit. + * Updating the prefix is probably preferable, but requires a fairly large codemod, + * since this name is used everywhere. + */ +#ifndef MEM_STATIC /* already defined in Linux Kernel mem.h */ +#if defined(__GNUC__) +# define MEM_STATIC static __inline UNUSED_ATTR +#elif defined(__IAR_SYSTEMS_ICC__) +# define MEM_STATIC static inline UNUSED_ATTR +#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +# define MEM_STATIC static inline +#elif defined(_MSC_VER) +# define MEM_STATIC static __inline +#else +# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ +#endif +#endif + +/* force no inlining */ +#ifdef _MSC_VER +# define FORCE_NOINLINE static __declspec(noinline) +#else +# if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) +# define FORCE_NOINLINE static __attribute__((__noinline__)) +# else +# define FORCE_NOINLINE static +# endif +#endif + + +/* target attribute */ +#if defined(__GNUC__) || defined(__IAR_SYSTEMS_ICC__) +# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target))) +#else +# define TARGET_ATTRIBUTE(target) +#endif + +/* Target attribute for BMI2 dynamic dispatch. + * Enable lzcnt, bmi, and bmi2. + * We test for bmi1 & bmi2. lzcnt is included in bmi1. + */ +#define BMI2_TARGET_ATTRIBUTE TARGET_ATTRIBUTE("lzcnt,bmi,bmi2") + +/* prefetch + * can be disabled, by declaring NO_PREFETCH build macro */ +#if defined(NO_PREFETCH) +# define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */ +# define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */ +#else +# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) && !defined(_M_ARM64EC) /* _mm_prefetch() is not defined outside of x86/x64 */ +# include /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ +# define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) +# define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1) +# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) ) +# define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */) +# define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */) +# elif defined(__aarch64__) +# define PREFETCH_L1(ptr) do { __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))); } while (0) +# define PREFETCH_L2(ptr) do { __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))); } while (0) +# else +# define PREFETCH_L1(ptr) do { (void)(ptr); } while (0) /* disabled */ +# define PREFETCH_L2(ptr) do { (void)(ptr); } while (0) /* disabled */ +# endif +#endif /* NO_PREFETCH */ + +#define CACHELINE_SIZE 64 + +#define PREFETCH_AREA(p, s) \ + do { \ + const char* const _ptr = (const char*)(p); \ + size_t const _size = (size_t)(s); \ + size_t _pos; \ + for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \ + PREFETCH_L2(_ptr + _pos); \ + } \ + } while (0) + +/* vectorization + * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax, + * and some compilers, like Intel ICC and MCST LCC, do not support it at all. */ +#if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__) && !defined(__LCC__) +# if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5) +# define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize"))) +# else +# define DONT_VECTORIZE _Pragma("GCC optimize(\"no-tree-vectorize\")") +# endif +#else +# define DONT_VECTORIZE +#endif + +/* Tell the compiler that a branch is likely or unlikely. + * Only use these macros if it causes the compiler to generate better code. + * If you can remove a LIKELY/UNLIKELY annotation without speed changes in gcc + * and clang, please do. + */ +#if defined(__GNUC__) +#define LIKELY(x) (__builtin_expect((x), 1)) +#define UNLIKELY(x) (__builtin_expect((x), 0)) +#else +#define LIKELY(x) (x) +#define UNLIKELY(x) (x) +#endif + +#if __has_builtin(__builtin_unreachable) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))) +# define ZSTD_UNREACHABLE do { assert(0), __builtin_unreachable(); } while (0) +#else +# define ZSTD_UNREACHABLE do { assert(0); } while (0) +#endif + +/* disable warnings */ +#ifdef _MSC_VER /* Visual Studio */ +# include /* For Visual 2005 */ +# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */ +# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */ +# pragma warning(disable : 4324) /* disable: C4324: padded structure */ +#endif + +/* compile time determination of SIMD support */ +#if !defined(ZSTD_NO_INTRINSICS) +# if defined(__AVX2__) +# define ZSTD_ARCH_X86_AVX2 +# endif +# if defined(__SSE2__) || defined(_M_X64) || (defined (_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) +# define ZSTD_ARCH_X86_SSE2 +# endif +# +# if defined(ZSTD_ARCH_X86_AVX2) +# include +# endif +# if defined(ZSTD_ARCH_X86_SSE2) +# include +# elif defined(ZSTD_ARCH_ARM_NEON) +# include +# endif +#endif + +/* C-language Attributes are added in C23. */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute) +# define ZSTD_HAS_C_ATTRIBUTE(x) __has_c_attribute(x) +#else +# define ZSTD_HAS_C_ATTRIBUTE(x) 0 +#endif + +/* Only use C++ attributes in C++. Some compilers report support for C++ + * attributes when compiling with C. + */ +#if defined(__cplusplus) && defined(__has_cpp_attribute) +# define ZSTD_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +# define ZSTD_HAS_CPP_ATTRIBUTE(x) 0 +#endif + +/* Define ZSTD_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute. + * - C23: https://en.cppreference.com/w/c/language/attributes/fallthrough + * - CPP17: https://en.cppreference.com/w/cpp/language/attributes/fallthrough + * - Else: __attribute__((__fallthrough__)) + */ +#ifndef ZSTD_FALLTHROUGH +# if ZSTD_HAS_C_ATTRIBUTE(fallthrough) +# define ZSTD_FALLTHROUGH [[fallthrough]] +# elif ZSTD_HAS_CPP_ATTRIBUTE(fallthrough) +# define ZSTD_FALLTHROUGH [[fallthrough]] +# elif __has_attribute(__fallthrough__) +/* Leading semicolon is to satisfy gcc-11 with -pedantic. Without the semicolon + * gcc complains about: a label can only be part of a statement and a declaration is not a statement. + */ +# define ZSTD_FALLTHROUGH ; __attribute__((__fallthrough__)) +# else +# define ZSTD_FALLTHROUGH +# endif +#endif + +/*-************************************************************** +* Alignment +*****************************************************************/ + +/* @return 1 if @u is a 2^n value, 0 otherwise + * useful to check a value is valid for alignment restrictions */ +MEM_STATIC int ZSTD_isPower2(size_t u) { + return (u & (u-1)) == 0; +} + +/* this test was initially positioned in mem.h, + * but this file is removed (or replaced) for linux kernel + * so it's now hosted in compiler.h, + * which remains valid for both user & kernel spaces. + */ + +#ifndef ZSTD_ALIGNOF +# if defined(__GNUC__) || defined(_MSC_VER) +/* covers gcc, clang & MSVC */ +/* note : this section must come first, before C11, + * due to a limitation in the kernel source generator */ +# define ZSTD_ALIGNOF(T) __alignof(T) + +# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) +/* C11 support */ +# include +# define ZSTD_ALIGNOF(T) alignof(T) + +# else +/* No known support for alignof() - imperfect backup */ +# define ZSTD_ALIGNOF(T) (sizeof(void*) < sizeof(T) ? sizeof(void*) : sizeof(T)) + +# endif +#endif /* ZSTD_ALIGNOF */ + +#ifndef ZSTD_ALIGNED +/* C90-compatible alignment macro (GCC/Clang). Adjust for other compilers if needed. */ +# if defined(__GNUC__) || defined(__clang__) +# define ZSTD_ALIGNED(a) __attribute__((aligned(a))) +# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */ +# define ZSTD_ALIGNED(a) _Alignas(a) +#elif defined(_MSC_VER) +# define ZSTD_ALIGNED(n) __declspec(align(n)) +# else + /* this compiler will require its own alignment instruction */ +# define ZSTD_ALIGNED(...) +# endif +#endif /* ZSTD_ALIGNED */ + + +/*-************************************************************** +* Sanitizer +*****************************************************************/ + +/** + * Zstd relies on pointer overflow in its decompressor. + * We add this attribute to functions that rely on pointer overflow. + */ +#ifndef ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +# if __has_attribute(no_sanitize) +# if !defined(__clang__) && defined(__GNUC__) && __GNUC__ < 8 + /* gcc < 8 only has signed-integer-overlow which triggers on pointer overflow */ +# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("signed-integer-overflow"))) +# else + /* older versions of clang [3.7, 5.0) will warn that pointer-overflow is ignored. */ +# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR __attribute__((no_sanitize("pointer-overflow"))) +# endif +# else +# define ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +# endif +#endif + +/** + * Helper function to perform a wrapped pointer difference without triggering + * UBSAN. + * + * @returns lhs - rhs with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +ptrdiff_t ZSTD_wrappedPtrDiff(unsigned char const* lhs, unsigned char const* rhs) +{ + return lhs - rhs; +} + +/** + * Helper function to perform a wrapped pointer add without triggering UBSAN. + * + * @return ptr + add with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +unsigned char const* ZSTD_wrappedPtrAdd(unsigned char const* ptr, ptrdiff_t add) +{ + return ptr + add; +} + +/** + * Helper function to perform a wrapped pointer subtraction without triggering + * UBSAN. + * + * @return ptr - sub with wrapping + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +unsigned char const* ZSTD_wrappedPtrSub(unsigned char const* ptr, ptrdiff_t sub) +{ + return ptr - sub; +} + +/** + * Helper function to add to a pointer that works around C's undefined behavior + * of adding 0 to NULL. + * + * @returns `ptr + add` except it defines `NULL + 0 == NULL`. + */ +MEM_STATIC +unsigned char* ZSTD_maybeNullPtrAdd(unsigned char* ptr, ptrdiff_t add) +{ + return add > 0 ? ptr + add : ptr; +} + +/* Issue #3240 reports an ASAN failure on an llvm-mingw build. Out of an + * abundance of caution, disable our custom poisoning on mingw. */ +#ifdef __MINGW32__ +#ifndef ZSTD_ASAN_DONT_POISON_WORKSPACE +#define ZSTD_ASAN_DONT_POISON_WORKSPACE 1 +#endif +#ifndef ZSTD_MSAN_DONT_POISON_WORKSPACE +#define ZSTD_MSAN_DONT_POISON_WORKSPACE 1 +#endif +#endif + +#if ZSTD_MEMORY_SANITIZER && !defined(ZSTD_MSAN_DONT_POISON_WORKSPACE) +/* Not all platforms that support msan provide sanitizers/msan_interface.h. + * We therefore declare the functions we need ourselves, rather than trying to + * include the header file... */ +#include /* size_t */ +#define ZSTD_DEPS_NEED_STDINT +#include "zstd_deps.h" /* intptr_t */ + +/* Make memory region fully initialized (without changing its contents). */ +void __msan_unpoison(const volatile void *a, size_t size); + +/* Make memory region fully uninitialized (without changing its contents). + This is a legacy interface that does not update origin information. Use + __msan_allocated_memory() instead. */ +void __msan_poison(const volatile void *a, size_t size); + +/* Returns the offset of the first (at least partially) poisoned byte in the + memory range, or -1 if the whole range is good. */ +intptr_t __msan_test_shadow(const volatile void *x, size_t size); + +/* Print shadow and origin for the memory range to stderr in a human-readable + format. */ +void __msan_print_shadow(const volatile void *x, size_t size); +#endif + +#if ZSTD_ADDRESS_SANITIZER && !defined(ZSTD_ASAN_DONT_POISON_WORKSPACE) +/* Not all platforms that support asan provide sanitizers/asan_interface.h. + * We therefore declare the functions we need ourselves, rather than trying to + * include the header file... */ +#include /* size_t */ + +/** + * Marks a memory region ([addr, addr+size)) as unaddressable. + * + * This memory must be previously allocated by your program. Instrumented + * code is forbidden from accessing addresses in this region until it is + * unpoisoned. This function is not guaranteed to poison the entire region - + * it could poison only a subregion of [addr, addr+size) due to ASan + * alignment restrictions. + * + * \note This function is not thread-safe because no two threads can poison or + * unpoison memory in the same memory region simultaneously. + * + * \param addr Start of memory region. + * \param size Size of memory region. */ +void __asan_poison_memory_region(void const volatile *addr, size_t size); + +/** + * Marks a memory region ([addr, addr+size)) as addressable. + * + * This memory must be previously allocated by your program. Accessing + * addresses in this region is allowed until this region is poisoned again. + * This function could unpoison a super-region of [addr, addr+size) due + * to ASan alignment restrictions. + * + * \note This function is not thread-safe because no two threads can + * poison or unpoison memory in the same memory region simultaneously. + * + * \param addr Start of memory region. + * \param size Size of memory region. */ +void __asan_unpoison_memory_region(void const volatile *addr, size_t size); +#endif + +#endif /* ZSTD_COMPILER_H */ diff --git a/src/commonlib/bsd/zstd/common/zstd_deps.h b/src/commonlib/bsd/zstd/common/zstd_deps.h new file mode 100644 index 00000000000..7ad8df1a217 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_deps.h @@ -0,0 +1,125 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* This file provides common libc dependencies that zstd requires. + * The purpose is to allow replacing this file with a custom implementation + * to compile zstd without libc support. + */ + +/* Need: + * NULL + * INT_MAX + * UINT_MAX + * ZSTD_memcpy() + * ZSTD_memset() + * ZSTD_memmove() + */ +#ifndef ZSTD_DEPS_COMMON +#define ZSTD_DEPS_COMMON + +/* Even though we use qsort_r only for the dictionary builder, the macro + * _GNU_SOURCE has to be declared *before* the inclusion of any standard + * header and the script 'combine.sh' combines the whole zstd source code + * in a single file. + */ +#if defined(__linux) || defined(__linux__) || defined(linux) || defined(__gnu_linux__) || \ + defined(__CYGWIN__) || defined(__MSYS__) +#if !defined(_GNU_SOURCE) && !defined(__ANDROID__) /* NDK doesn't ship qsort_r(). */ +#define _GNU_SOURCE +#endif +#endif + +#include +#include +#include + +#if defined(__GNUC__) && __GNUC__ >= 4 +# define ZSTD_memcpy(d,s,l) __builtin_memcpy((d),(s),(l)) +# define ZSTD_memmove(d,s,l) __builtin_memmove((d),(s),(l)) +# define ZSTD_memset(p,v,l) __builtin_memset((p),(v),(l)) +#else +# define ZSTD_memcpy(d,s,l) memcpy((d),(s),(l)) +# define ZSTD_memmove(d,s,l) memmove((d),(s),(l)) +# define ZSTD_memset(p,v,l) memset((p),(v),(l)) +#endif + +#endif /* ZSTD_DEPS_COMMON */ + +/* Need: + * ZSTD_malloc() + * ZSTD_free() + * ZSTD_calloc() + */ +#ifdef ZSTD_DEPS_NEED_MALLOC +#ifndef ZSTD_DEPS_MALLOC +#define ZSTD_DEPS_MALLOC + +#include + +#define ZSTD_malloc(s) malloc(s) +#define ZSTD_calloc(n,s) calloc((n), (s)) +#define ZSTD_free(p) free((p)) + +#endif /* ZSTD_DEPS_MALLOC */ +#endif /* ZSTD_DEPS_NEED_MALLOC */ + +/* + * Provides 64-bit math support. + * Need: + * U64 ZSTD_div64(U64 dividend, U32 divisor) + */ +#ifdef ZSTD_DEPS_NEED_MATH64 +#ifndef ZSTD_DEPS_MATH64 +#define ZSTD_DEPS_MATH64 + +#define ZSTD_div64(dividend, divisor) ((dividend) / (divisor)) + +#endif /* ZSTD_DEPS_MATH64 */ +#endif /* ZSTD_DEPS_NEED_MATH64 */ + +/* Need: + * assert() + */ +#ifdef ZSTD_DEPS_NEED_ASSERT +#ifndef ZSTD_DEPS_ASSERT +#define ZSTD_DEPS_ASSERT + +#include + +#endif /* ZSTD_DEPS_ASSERT */ +#endif /* ZSTD_DEPS_NEED_ASSERT */ + +/* Need: + * ZSTD_DEBUG_PRINT() + */ +#ifdef ZSTD_DEPS_NEED_IO +#ifndef ZSTD_DEPS_IO +#define ZSTD_DEPS_IO + +#include +#define ZSTD_DEBUG_PRINT(...) fprintf(stderr, __VA_ARGS__) + +#endif /* ZSTD_DEPS_IO */ +#endif /* ZSTD_DEPS_NEED_IO */ + +/* Only requested when is known to be present. + * Need: + * intptr_t + */ +#ifdef ZSTD_DEPS_NEED_STDINT +#ifndef ZSTD_DEPS_STDINT +#define ZSTD_DEPS_STDINT + +#include + +#endif /* ZSTD_DEPS_STDINT */ +#endif /* ZSTD_DEPS_NEED_STDINT */ diff --git a/src/commonlib/bsd/zstd/common/zstd_internal.h b/src/commonlib/bsd/zstd/common/zstd_internal.h new file mode 100644 index 00000000000..eef669f9d89 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_internal.h @@ -0,0 +1,324 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_CCOMMON_H_MODULE +#define ZSTD_CCOMMON_H_MODULE + +/* this module contains definitions which must be identical + * across compression, decompression and dictBuilder. + * It also contains a few functions useful to at least 2 of them + * and which benefit from being inlined */ + +/*-************************************* +* Dependencies +***************************************/ +#include "zstd_compiler.h" +#include "cpu.h" +#include "mem.h" +#include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */ +#include "error_private.h" +#define ZSTD_STATIC_LINKING_ONLY +#include "../zstd.h" +#define FSE_STATIC_LINKING_ONLY +#include "fse.h" +#include "huf.h" +#include "zstd_xxhash.h" + +#ifndef ZSTD_NO_TRACE +# include "zstd_trace.h" +#else +# define ZSTD_TRACE 0 +#endif + +/* ---- static assert (debug) --- */ +#define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) +#define ZSTD_isError ERR_isError /* for inlining */ +#define FSE_isError ERR_isError +#define HUF_isError ERR_isError + + +/*-************************************* +* shared macros +***************************************/ +#undef MIN +#undef MAX +#define MIN(a,b) ((a)<(b) ? (a) : (b)) +#define MAX(a,b) ((a)>(b) ? (a) : (b)) +#define BOUNDED(min,val,max) (MAX(min,MIN(val,max))) + + +/*-************************************* +* Common constants +***************************************/ +#define ZSTD_OPT_NUM (1<<12) + +#define ZSTD_REP_NUM 3 /* number of repcodes */ +static UNUSED_ATTR const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 }; + +#define KB *(1 <<10) +#define MB *(1 <<20) +#define GB *(1U<<30) + +#define BIT7 128 +#define BIT6 64 +#define BIT5 32 +#define BIT4 16 +#define BIT1 2 +#define BIT0 1 + +#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10 +static UNUSED_ATTR const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 }; +static UNUSED_ATTR const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 }; + +#define ZSTD_FRAMEIDSIZE 4 /* magic number size */ + +#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */ +static UNUSED_ATTR const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE; +typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e; + +#define ZSTD_FRAMECHECKSUMSIZE 4 + +#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */ +#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */) /* for a non-null block */ +#define MIN_LITERALS_FOR_4_STREAMS 6 + +typedef enum { set_basic, set_rle, set_compressed, set_repeat } SymbolEncodingType_e; + +#define LONGNBSEQ 0x7F00 + +#define MINMATCH 3 + +#define Litbits 8 +#define LitHufLog 11 +#define MaxLit ((1<= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN); + /* Separate out the first COPY16() call because the copy length is + * almost certain to be short, so the branches have different + * probabilities. Since it is almost certain to be short, only do + * one COPY16() in the first call. Then, do two calls per loop since + * at that point it is more likely to have a high trip count. + */ + ZSTD_copy16(op, ip); + if (16 >= length) return; + op += 16; + ip += 16; + do { + COPY16(op, ip); + COPY16(op, ip); + } + while (op < oend); + } +} + +MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + size_t const length = MIN(dstCapacity, srcSize); + if (length > 0) { + ZSTD_memcpy(dst, src, length); + } + return length; +} + +/* define "workspace is too large" as this number of times larger than needed */ +#define ZSTD_WORKSPACETOOLARGE_FACTOR 3 + +/* when workspace is continuously too large + * during at least this number of times, + * context's memory usage is considered wasteful, + * because it's sized to handle a worst case scenario which rarely happens. + * In which case, resize it down to free some memory */ +#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128 + +/* Controls whether the input/output buffer is buffered or stable. */ +typedef enum { + ZSTD_bm_buffered = 0, /* Buffer the input/output */ + ZSTD_bm_stable = 1 /* ZSTD_inBuffer/ZSTD_outBuffer is stable */ +} ZSTD_bufferMode_e; + + +/*-******************************************* +* Private declarations +*********************************************/ + +/** + * Contains the compressed frame size and an upper-bound for the decompressed frame size. + * Note: before using `compressedSize`, check for errors using ZSTD_isError(). + * similarly, before using `decompressedBound`, check for errors using: + * `decompressedBound != ZSTD_CONTENTSIZE_ERROR` + */ +typedef struct { + size_t nbBlocks; + size_t compressedSize; + unsigned long long decompressedBound; +} ZSTD_frameSizeInfo; /* decompress & legacy */ + +/* ZSTD_invalidateRepCodes() : + * ensures next compression will not use repcodes from previous block. + * Note : only works with regular variant; + * do not use with extDict variant ! */ +void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */ + + +typedef struct { + blockType_e blockType; + U32 lastBlock; + U32 origSize; +} blockProperties_t; /* declared here for decompress and fullbench */ + +/*! ZSTD_getcBlockSize() : + * Provides the size of compressed block from block header `src` */ +/* Used by: decompress, fullbench */ +size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, + blockProperties_t* bpPtr); + +/*! ZSTD_decodeSeqHeaders() : + * decode sequence header from src */ +/* Used by: zstd_decompress_block, fullbench */ +size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, + const void* src, size_t srcSize); + +/** + * @returns true iff the CPU supports dynamic BMI2 dispatch. + */ +MEM_STATIC int ZSTD_cpuSupportsBmi2(void) +{ + ZSTD_cpuid_t cpuid = ZSTD_cpuid(); + return ZSTD_cpuid_bmi1(cpuid) && ZSTD_cpuid_bmi2(cpuid); +} + +#endif /* ZSTD_CCOMMON_H_MODULE */ diff --git a/src/commonlib/bsd/zstd/common/zstd_trace.h b/src/commonlib/bsd/zstd/common/zstd_trace.h new file mode 100644 index 00000000000..dc08bd4cb68 --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_trace.h @@ -0,0 +1,158 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_TRACE_H +#define ZSTD_TRACE_H + +#include + +/* weak symbol support + * For now, enable conservatively: + * - Only GNUC + * - Only ELF + * - Only x86-64, i386, aarch64 and risc-v. + * Also, explicitly disable on platforms known not to work so they aren't + * forgotten in the future. + */ +#if !defined(ZSTD_HAVE_WEAK_SYMBOLS) && \ + defined(__GNUC__) && defined(__ELF__) && \ + (defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \ + defined(_M_IX86) || defined(__aarch64__) || defined(__riscv)) && \ + !defined(__APPLE__) && !defined(_WIN32) && !defined(__MINGW32__) && \ + !defined(__CYGWIN__) && !defined(_AIX) +# define ZSTD_HAVE_WEAK_SYMBOLS 1 +#else +# define ZSTD_HAVE_WEAK_SYMBOLS 0 +#endif +#if ZSTD_HAVE_WEAK_SYMBOLS +# define ZSTD_WEAK_ATTR __attribute__((__weak__)) +#else +# define ZSTD_WEAK_ATTR +#endif + +/* Only enable tracing when weak symbols are available. */ +#ifndef ZSTD_TRACE +# define ZSTD_TRACE ZSTD_HAVE_WEAK_SYMBOLS +#endif + +#if ZSTD_TRACE + +struct ZSTD_CCtx_s; +struct ZSTD_DCtx_s; +struct ZSTD_CCtx_params_s; + +typedef struct { + /** + * ZSTD_VERSION_NUMBER + * + * This is guaranteed to be the first member of ZSTD_trace. + * Otherwise, this struct is not stable between versions. If + * the version number does not match your expectation, you + * should not interpret the rest of the struct. + */ + unsigned version; + /** + * Non-zero if streaming (de)compression is used. + */ + int streaming; + /** + * The dictionary ID. + */ + unsigned dictionaryID; + /** + * Is the dictionary cold? + * Only set on decompression. + */ + int dictionaryIsCold; + /** + * The dictionary size or zero if no dictionary. + */ + size_t dictionarySize; + /** + * The uncompressed size of the data. + */ + size_t uncompressedSize; + /** + * The compressed size of the data. + */ + size_t compressedSize; + /** + * The fully resolved CCtx parameters (NULL on decompression). + */ + struct ZSTD_CCtx_params_s const* params; + /** + * The ZSTD_CCtx pointer (NULL on decompression). + */ + struct ZSTD_CCtx_s const* cctx; + /** + * The ZSTD_DCtx pointer (NULL on compression). + */ + struct ZSTD_DCtx_s const* dctx; +} ZSTD_Trace; + +/** + * A tracing context. It must be 0 when tracing is disabled. + * Otherwise, any non-zero value returned by a tracing begin() + * function is presented to any subsequent calls to end(). + * + * Any non-zero value is treated as tracing is enabled and not + * interpreted by the library. + * + * Two possible uses are: + * * A timestamp for when the begin() function was called. + * * A unique key identifying the (de)compression, like the + * address of the [dc]ctx pointer if you need to track + * more information than just a timestamp. + */ +typedef unsigned long long ZSTD_TraceCtx; + +/** + * Trace the beginning of a compression call. + * @param cctx The dctx pointer for the compression. + * It can be used as a key to map begin() to end(). + * @returns Non-zero if tracing is enabled. The return value is + * passed to ZSTD_trace_compress_end(). + */ +ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_compress_begin( + struct ZSTD_CCtx_s const* cctx); + +/** + * Trace the end of a compression call. + * @param ctx The return value of ZSTD_trace_compress_begin(). + * @param trace The zstd tracing info. + */ +ZSTD_WEAK_ATTR void ZSTD_trace_compress_end( + ZSTD_TraceCtx ctx, + ZSTD_Trace const* trace); + +/** + * Trace the beginning of a decompression call. + * @param dctx The dctx pointer for the decompression. + * It can be used as a key to map begin() to end(). + * @returns Non-zero if tracing is enabled. The return value is + * passed to ZSTD_trace_compress_end(). + */ +ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_decompress_begin( + struct ZSTD_DCtx_s const* dctx); + +/** + * Trace the end of a decompression call. + * @param ctx The return value of ZSTD_trace_decompress_begin(). + * @param trace The zstd tracing info. + */ +ZSTD_WEAK_ATTR void ZSTD_trace_decompress_end( + ZSTD_TraceCtx ctx, + ZSTD_Trace const* trace); + +#endif /* ZSTD_TRACE */ + +#endif /* ZSTD_TRACE_H */ diff --git a/src/commonlib/bsd/zstd/common/zstd_xxhash.h b/src/commonlib/bsd/zstd/common/zstd_xxhash.h new file mode 100644 index 00000000000..4e3f2480d9e --- /dev/null +++ b/src/commonlib/bsd/zstd/common/zstd_xxhash.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +#ifndef ZSTD_XXHASH_COMMON +#define ZSTD_XXHASH_COMMON + +#include + +typedef struct xxh64_state XXH64_state_t; +#define XXH64_update xxh64_update +#define XXH64_reset xxh64_reset +#define XXH64_digest xxh64_digest +#define XXH64 xxh64 + +typedef struct xxh32_state XXH32_state_t; +#define XXH32_update xxh32_update +#define XXH32_reset xxh32_reset +#define XXH32_digest xxh32_digest +#define XXH32 xxh32 + +#endif /* ZSTD_XXHASH_COMMON */ diff --git a/src/commonlib/bsd/zstd/compress/clevels.h b/src/commonlib/bsd/zstd/compress/clevels.h new file mode 100644 index 00000000000..8ebf1be2829 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/clevels.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_CLEVELS_H +#define ZSTD_CLEVELS_H + +#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressionParameters */ +#include "../zstd.h" + +/*-===== Pre-defined compression levels =====-*/ + +#define ZSTD_MAX_CLEVEL 22 + +#ifdef __GNUC__ +__attribute__((__unused__)) +#endif + +static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = { +{ /* "default" - for any srcSize > 256 KB */ + /* W, C, H, S, L, TL, strat */ + { 19, 12, 13, 1, 6, 1, ZSTD_fast }, /* base for negative levels */ + { 19, 13, 14, 1, 7, 0, ZSTD_fast }, /* level 1 */ + { 20, 15, 16, 1, 6, 0, ZSTD_fast }, /* level 2 */ + { 21, 16, 17, 1, 5, 0, ZSTD_dfast }, /* level 3 */ + { 21, 18, 18, 1, 5, 0, ZSTD_dfast }, /* level 4 */ + { 21, 18, 19, 3, 5, 2, ZSTD_greedy }, /* level 5 */ + { 21, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6 */ + { 21, 19, 20, 4, 5, 8, ZSTD_lazy }, /* level 7 */ + { 21, 19, 20, 4, 5, 16, ZSTD_lazy2 }, /* level 8 */ + { 22, 20, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */ + { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 10 */ + { 22, 21, 22, 6, 5, 16, ZSTD_lazy2 }, /* level 11 */ + { 22, 22, 23, 6, 5, 32, ZSTD_lazy2 }, /* level 12 */ + { 22, 22, 22, 4, 5, 32, ZSTD_btlazy2 }, /* level 13 */ + { 22, 22, 23, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */ + { 22, 23, 23, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */ + { 22, 22, 22, 5, 5, 48, ZSTD_btopt }, /* level 16 */ + { 23, 23, 22, 5, 4, 64, ZSTD_btopt }, /* level 17 */ + { 23, 23, 22, 6, 3, 64, ZSTD_btultra }, /* level 18 */ + { 23, 24, 22, 7, 3,256, ZSTD_btultra2}, /* level 19 */ + { 25, 25, 23, 7, 3,256, ZSTD_btultra2}, /* level 20 */ + { 26, 26, 24, 7, 3,512, ZSTD_btultra2}, /* level 21 */ + { 27, 27, 25, 9, 3,999, ZSTD_btultra2}, /* level 22 */ +}, +{ /* for srcSize <= 256 KB */ + /* W, C, H, S, L, T, strat */ + { 18, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ + { 18, 13, 14, 1, 6, 0, ZSTD_fast }, /* level 1 */ + { 18, 14, 14, 1, 5, 0, ZSTD_dfast }, /* level 2 */ + { 18, 16, 16, 1, 4, 0, ZSTD_dfast }, /* level 3 */ + { 18, 16, 17, 3, 5, 2, ZSTD_greedy }, /* level 4.*/ + { 18, 17, 18, 5, 5, 2, ZSTD_greedy }, /* level 5.*/ + { 18, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6.*/ + { 18, 18, 19, 4, 4, 4, ZSTD_lazy }, /* level 7 */ + { 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ + { 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ + { 18, 18, 19, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ + { 18, 18, 19, 5, 4, 12, ZSTD_btlazy2 }, /* level 11.*/ + { 18, 19, 19, 7, 4, 12, ZSTD_btlazy2 }, /* level 12.*/ + { 18, 18, 19, 4, 4, 16, ZSTD_btopt }, /* level 13 */ + { 18, 18, 19, 4, 3, 32, ZSTD_btopt }, /* level 14.*/ + { 18, 18, 19, 6, 3,128, ZSTD_btopt }, /* level 15.*/ + { 18, 19, 19, 6, 3,128, ZSTD_btultra }, /* level 16.*/ + { 18, 19, 19, 8, 3,256, ZSTD_btultra }, /* level 17.*/ + { 18, 19, 19, 6, 3,128, ZSTD_btultra2}, /* level 18.*/ + { 18, 19, 19, 8, 3,256, ZSTD_btultra2}, /* level 19.*/ + { 18, 19, 19, 10, 3,512, ZSTD_btultra2}, /* level 20.*/ + { 18, 19, 19, 12, 3,512, ZSTD_btultra2}, /* level 21.*/ + { 18, 19, 19, 13, 3,999, ZSTD_btultra2}, /* level 22.*/ +}, +{ /* for srcSize <= 128 KB */ + /* W, C, H, S, L, T, strat */ + { 17, 12, 12, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ + { 17, 12, 13, 1, 6, 0, ZSTD_fast }, /* level 1 */ + { 17, 13, 15, 1, 5, 0, ZSTD_fast }, /* level 2 */ + { 17, 15, 16, 2, 5, 0, ZSTD_dfast }, /* level 3 */ + { 17, 17, 17, 2, 4, 0, ZSTD_dfast }, /* level 4 */ + { 17, 16, 17, 3, 4, 2, ZSTD_greedy }, /* level 5 */ + { 17, 16, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */ + { 17, 16, 17, 3, 4, 8, ZSTD_lazy2 }, /* level 7 */ + { 17, 16, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */ + { 17, 16, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */ + { 17, 16, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */ + { 17, 17, 17, 5, 4, 8, ZSTD_btlazy2 }, /* level 11 */ + { 17, 18, 17, 7, 4, 12, ZSTD_btlazy2 }, /* level 12 */ + { 17, 18, 17, 3, 4, 12, ZSTD_btopt }, /* level 13.*/ + { 17, 18, 17, 4, 3, 32, ZSTD_btopt }, /* level 14.*/ + { 17, 18, 17, 6, 3,256, ZSTD_btopt }, /* level 15.*/ + { 17, 18, 17, 6, 3,128, ZSTD_btultra }, /* level 16.*/ + { 17, 18, 17, 8, 3,256, ZSTD_btultra }, /* level 17.*/ + { 17, 18, 17, 10, 3,512, ZSTD_btultra }, /* level 18.*/ + { 17, 18, 17, 5, 3,256, ZSTD_btultra2}, /* level 19.*/ + { 17, 18, 17, 7, 3,512, ZSTD_btultra2}, /* level 20.*/ + { 17, 18, 17, 9, 3,512, ZSTD_btultra2}, /* level 21.*/ + { 17, 18, 17, 11, 3,999, ZSTD_btultra2}, /* level 22.*/ +}, +{ /* for srcSize <= 16 KB */ + /* W, C, H, S, L, T, strat */ + { 14, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */ + { 14, 14, 15, 1, 5, 0, ZSTD_fast }, /* level 1 */ + { 14, 14, 15, 1, 4, 0, ZSTD_fast }, /* level 2 */ + { 14, 14, 15, 2, 4, 0, ZSTD_dfast }, /* level 3 */ + { 14, 14, 14, 4, 4, 2, ZSTD_greedy }, /* level 4 */ + { 14, 14, 14, 3, 4, 4, ZSTD_lazy }, /* level 5.*/ + { 14, 14, 14, 4, 4, 8, ZSTD_lazy2 }, /* level 6 */ + { 14, 14, 14, 6, 4, 8, ZSTD_lazy2 }, /* level 7 */ + { 14, 14, 14, 8, 4, 8, ZSTD_lazy2 }, /* level 8.*/ + { 14, 15, 14, 5, 4, 8, ZSTD_btlazy2 }, /* level 9.*/ + { 14, 15, 14, 9, 4, 8, ZSTD_btlazy2 }, /* level 10.*/ + { 14, 15, 14, 3, 4, 12, ZSTD_btopt }, /* level 11.*/ + { 14, 15, 14, 4, 3, 24, ZSTD_btopt }, /* level 12.*/ + { 14, 15, 14, 5, 3, 32, ZSTD_btultra }, /* level 13.*/ + { 14, 15, 15, 6, 3, 64, ZSTD_btultra }, /* level 14.*/ + { 14, 15, 15, 7, 3,256, ZSTD_btultra }, /* level 15.*/ + { 14, 15, 15, 5, 3, 48, ZSTD_btultra2}, /* level 16.*/ + { 14, 15, 15, 6, 3,128, ZSTD_btultra2}, /* level 17.*/ + { 14, 15, 15, 7, 3,256, ZSTD_btultra2}, /* level 18.*/ + { 14, 15, 15, 8, 3,256, ZSTD_btultra2}, /* level 19.*/ + { 14, 15, 15, 8, 3,512, ZSTD_btultra2}, /* level 20.*/ + { 14, 15, 15, 9, 3,512, ZSTD_btultra2}, /* level 21.*/ + { 14, 15, 15, 10, 3,999, ZSTD_btultra2}, /* level 22.*/ +}, +}; + + + +#endif /* ZSTD_CLEVELS_H */ diff --git a/src/commonlib/bsd/zstd/compress/fse_compress.c b/src/commonlib/bsd/zstd/compress/fse_compress.c new file mode 100644 index 00000000000..7ef32108ef5 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/fse_compress.c @@ -0,0 +1,627 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * FSE : Finite State Entropy encoder + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* ************************************************************** +* Includes +****************************************************************/ +#include "../common/zstd_compiler.h" +#include "../common/mem.h" /* U32, U16, etc. */ +#include "../common/debug.h" /* assert, DEBUGLOG */ +#include "hist.h" /* HIST_count_wksp */ +#include "../common/bitstream.h" +#define FSE_STATIC_LINKING_ONLY +#include "../common/fse.h" +#include "../common/error_private.h" +#define ZSTD_DEPS_NEED_MALLOC +#define ZSTD_DEPS_NEED_MATH64 +#include "../common/zstd_deps.h" /* ZSTD_memset */ +#include "../common/zstd_bits.h" /* ZSTD_highbit32 */ + + +/* ************************************************************** +* Error Management +****************************************************************/ +#define FSE_isError ERR_isError + + +/* ************************************************************** +* Templates +****************************************************************/ +/* + designed to be included + for type-specific functions (template emulation in C) + Objective is to write these functions only once, for improved maintenance +*/ + +/* safety checks */ +#ifndef FSE_FUNCTION_EXTENSION +# error "FSE_FUNCTION_EXTENSION must be defined" +#endif +#ifndef FSE_FUNCTION_TYPE +# error "FSE_FUNCTION_TYPE must be defined" +#endif + +/* Function names */ +#define FSE_CAT(X,Y) X##Y +#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y) +#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y) + + +/* Function templates */ + +/* FSE_buildCTable_wksp() : + * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`). + * wkspSize should be sized to handle worst case situation, which is `1<>1 : 1) ; + FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT); + U32 const step = FSE_TABLESTEP(tableSize); + U32 const maxSV1 = maxSymbolValue+1; + + U16* cumul = (U16*)workSpace; /* size = maxSV1 */ + FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)(cumul + (maxSV1+1)); /* size = tableSize */ + + U32 highThreshold = tableSize-1; + + assert(((size_t)workSpace & 1) == 0); /* Must be 2 bytes-aligned */ + if (FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) > wkspSize) return ERROR(tableLog_tooLarge); + /* CTable header */ + tableU16[-2] = (U16) tableLog; + tableU16[-1] = (U16) maxSymbolValue; + assert(tableLog < 16); /* required for threshold strategy to work */ + + /* For explanations on how to distribute symbol values over the table : + * https://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */ + + #ifdef __clang_analyzer__ + ZSTD_memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize); /* useless initialization, just to keep scan-build happy */ + #endif + + /* symbol start positions */ + { U32 u; + cumul[0] = 0; + for (u=1; u <= maxSV1; u++) { + if (normalizedCounter[u-1]==-1) { /* Low proba symbol */ + cumul[u] = cumul[u-1] + 1; + tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1); + } else { + assert(normalizedCounter[u-1] >= 0); + cumul[u] = cumul[u-1] + (U16)normalizedCounter[u-1]; + assert(cumul[u] >= cumul[u-1]); /* no overflow */ + } } + cumul[maxSV1] = (U16)(tableSize+1); + } + + /* Spread symbols */ + if (highThreshold == tableSize - 1) { + /* Case for no low prob count symbols. Lay down 8 bytes at a time + * to reduce branch misses since we are operating on a small block + */ + BYTE* const spread = tableSymbol + tableSize; /* size = tableSize + 8 (may write beyond tableSize) */ + { U64 const add = 0x0101010101010101ull; + size_t pos = 0; + U64 sv = 0; + U32 s; + for (s=0; s=0); + pos += (size_t)n; + } + } + /* Spread symbols across the table. Lack of lowprob symbols means that + * we don't need variable sized inner loop, so we can unroll the loop and + * reduce branch misses. + */ + { size_t position = 0; + size_t s; + size_t const unroll = 2; /* Experimentally determined optimal unroll */ + assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */ + for (s = 0; s < (size_t)tableSize; s += unroll) { + size_t u; + for (u = 0; u < unroll; ++u) { + size_t const uPosition = (position + (u * step)) & tableMask; + tableSymbol[uPosition] = spread[s + u]; + } + position = (position + (unroll * step)) & tableMask; + } + assert(position == 0); /* Must have initialized all positions */ + } + } else { + U32 position = 0; + U32 symbol; + for (symbol=0; symbol highThreshold) + position = (position + step) & tableMask; /* Low proba area */ + } } + assert(position==0); /* Must have initialized all positions */ + } + + /* Build table */ + { U32 u; for (u=0; u 1); + { U32 const maxBitsOut = tableLog - ZSTD_highbit32 ((U32)normalizedCounter[s]-1); + U32 const minStatePlus = (U32)normalizedCounter[s] << maxBitsOut; + symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus; + symbolTT[s].deltaFindState = (int)(total - (unsigned)normalizedCounter[s]); + total += (unsigned)normalizedCounter[s]; + } } } } + +#if 0 /* debug : symbol costs */ + DEBUGLOG(5, "\n --- table statistics : "); + { U32 symbol; + for (symbol=0; symbol<=maxSymbolValue; symbol++) { + DEBUGLOG(5, "%3u: w=%3i, maxBits=%u, fracBits=%.2f", + symbol, normalizedCounter[symbol], + FSE_getMaxNbBits(symbolTT, symbol), + (double)FSE_bitCost(symbolTT, tableLog, symbol, 8) / 256); + } } +#endif + + return 0; +} + + + +#ifndef FSE_COMMONDEFS_ONLY + +/*-************************************************************** +* FSE NCount encoding +****************************************************************/ +size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog) +{ + size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog + + 4 /* bitCount initialized at 4 */ + + 2 /* first two symbols may use one additional bit each */) / 8) + + 1 /* round up to whole nb bytes */ + + 2 /* additional two bytes for bitstream flush */; + return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */ +} + +static size_t +FSE_writeNCount_generic (void* header, size_t headerBufferSize, + const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, + unsigned writeIsSafe) +{ + BYTE* const ostart = (BYTE*) header; + BYTE* out = ostart; + BYTE* const oend = ostart + headerBufferSize; + int nbBits; + const int tableSize = 1 << tableLog; + int remaining; + int threshold; + U32 bitStream = 0; + int bitCount = 0; + unsigned symbol = 0; + unsigned const alphabetSize = maxSymbolValue + 1; + int previousIs0 = 0; + + /* Table Size */ + bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount; + bitCount += 4; + + /* Init */ + remaining = tableSize+1; /* +1 for extra accuracy */ + threshold = tableSize; + nbBits = (int)tableLog+1; + + while ((symbol < alphabetSize) && (remaining>1)) { /* stops at 1 */ + if (previousIs0) { + unsigned start = symbol; + while ((symbol < alphabetSize) && !normalizedCounter[symbol]) symbol++; + if (symbol == alphabetSize) break; /* incorrect distribution */ + while (symbol >= start+24) { + start+=24; + bitStream += 0xFFFFU << bitCount; + if ((!writeIsSafe) && (out > oend-2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE) bitStream; + out[1] = (BYTE)(bitStream>>8); + out+=2; + bitStream>>=16; + } + while (symbol >= start+3) { + start+=3; + bitStream += 3U << bitCount; + bitCount += 2; + } + bitStream += (symbol-start) << bitCount; + bitCount += 2; + if (bitCount>16) { + if ((!writeIsSafe) && (out > oend - 2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream>>8); + out += 2; + bitStream >>= 16; + bitCount -= 16; + } } + { int count = normalizedCounter[symbol++]; + int const max = (2*threshold-1) - remaining; + remaining -= count < 0 ? -count : count; + count++; /* +1 for extra accuracy */ + if (count>=threshold) + count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */ + bitStream += (U32)count << bitCount; + bitCount += nbBits; + bitCount -= (count>=1; } + } + if (bitCount>16) { + if ((!writeIsSafe) && (out > oend - 2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream>>8); + out += 2; + bitStream >>= 16; + bitCount -= 16; + } } + + if (remaining != 1) + return ERROR(GENERIC); /* incorrect normalized distribution */ + assert(symbol <= alphabetSize); + + /* flush remaining bitStream */ + if ((!writeIsSafe) && (out > oend - 2)) + return ERROR(dstSize_tooSmall); /* Buffer overflow */ + out[0] = (BYTE)bitStream; + out[1] = (BYTE)(bitStream>>8); + out+= (bitCount+7) /8; + + assert(out >= ostart); + return (size_t)(out-ostart); +} + + +size_t FSE_writeNCount (void* buffer, size_t bufferSize, + const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) +{ + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported */ + if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported */ + + if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog)) + return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0); + + return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1 /* write in buffer is safe */); +} + + +/*-************************************************************** +* FSE Compression Code +****************************************************************/ + +/* provides the minimum logSize to safely represent a distribution */ +static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue) +{ + U32 minBitsSrc = ZSTD_highbit32((U32)(srcSize)) + 1; + U32 minBitsSymbols = ZSTD_highbit32(maxSymbolValue) + 2; + U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols; + assert(srcSize > 1); /* Not supported, RLE should be used instead */ + return minBits; +} + +unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus) +{ + U32 maxBitsSrc = ZSTD_highbit32((U32)(srcSize - 1)) - minus; + U32 tableLog = maxTableLog; + U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue); + assert(srcSize > 1); /* Not supported, RLE should be used instead */ + if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; + if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */ + if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */ + if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG; + if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG; + return tableLog; +} + +unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue) +{ + return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2); +} + +/* Secondary normalization method. + To be used when primary method fails. */ + +static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue, short lowProbCount) +{ + short const NOT_YET_ASSIGNED = -2; + U32 s; + U32 distributed = 0; + U32 ToDistribute; + + /* Init */ + U32 const lowThreshold = (U32)(total >> tableLog); + U32 lowOne = (U32)((total * 3) >> (tableLog + 1)); + + for (s=0; s<=maxSymbolValue; s++) { + if (count[s] == 0) { + norm[s]=0; + continue; + } + if (count[s] <= lowThreshold) { + norm[s] = lowProbCount; + distributed++; + total -= count[s]; + continue; + } + if (count[s] <= lowOne) { + norm[s] = 1; + distributed++; + total -= count[s]; + continue; + } + + norm[s]=NOT_YET_ASSIGNED; + } + ToDistribute = (1 << tableLog) - distributed; + + if (ToDistribute == 0) + return 0; + + if ((total / ToDistribute) > lowOne) { + /* risk of rounding to zero */ + lowOne = (U32)((total * 3) / (ToDistribute * 2)); + for (s=0; s<=maxSymbolValue; s++) { + if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) { + norm[s] = 1; + distributed++; + total -= count[s]; + continue; + } } + ToDistribute = (1 << tableLog) - distributed; + } + + if (distributed == maxSymbolValue+1) { + /* all values are pretty poor; + probably incompressible data (should have already been detected); + find max, then give all remaining points to max */ + U32 maxV = 0, maxC = 0; + for (s=0; s<=maxSymbolValue; s++) + if (count[s] > maxC) { maxV=s; maxC=count[s]; } + norm[maxV] += (short)ToDistribute; + return 0; + } + + if (total == 0) { + /* all of the symbols were low enough for the lowOne or lowThreshold */ + for (s=0; ToDistribute > 0; s = (s+1)%(maxSymbolValue+1)) + if (norm[s] > 0) { ToDistribute--; norm[s]++; } + return 0; + } + + { U64 const vStepLog = 62 - tableLog; + U64 const mid = (1ULL << (vStepLog-1)) - 1; + U64 const rStep = ZSTD_div64((((U64)1<> vStepLog); + U32 const sEnd = (U32)(end >> vStepLog); + U32 const weight = sEnd - sStart; + if (weight < 1) + return ERROR(GENERIC); + norm[s] = (short)weight; + tmpTotal = end; + } } } + + return 0; +} + +size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog, + const unsigned* count, size_t total, + unsigned maxSymbolValue, unsigned useLowProbCount) +{ + /* Sanity checks */ + if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; + if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported size */ + if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported size */ + if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */ + + { static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 }; + short const lowProbCount = useLowProbCount ? -1 : 1; + U64 const scale = 62 - tableLog; + U64 const step = ZSTD_div64((U64)1<<62, (U32)total); /* <== here, one division ! */ + U64 const vStep = 1ULL<<(scale-20); + int stillToDistribute = 1<> tableLog); + + for (s=0; s<=maxSymbolValue; s++) { + if (count[s] == total) return 0; /* rle special case */ + if (count[s] == 0) { normalizedCounter[s]=0; continue; } + if (count[s] <= lowThreshold) { + normalizedCounter[s] = lowProbCount; + stillToDistribute--; + } else { + short proba = (short)((count[s]*step) >> scale); + if (proba<8) { + U64 restToBeat = vStep * rtbTable[proba]; + proba += (count[s]*step) - ((U64)proba< restToBeat; + } + if (proba > largestP) { largestP=proba; largest=s; } + normalizedCounter[s] = proba; + stillToDistribute -= proba; + } } + if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) { + /* corner case, need another normalization method */ + size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue, lowProbCount); + if (FSE_isError(errorCode)) return errorCode; + } + else normalizedCounter[largest] += (short)stillToDistribute; + } + +#if 0 + { /* Print Table (debug) */ + U32 s; + U32 nTotal = 0; + for (s=0; s<=maxSymbolValue; s++) + RAWLOG(2, "%3i: %4i \n", s, normalizedCounter[s]); + for (s=0; s<=maxSymbolValue; s++) + nTotal += abs(normalizedCounter[s]); + if (nTotal != (1U< FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) { /* test bit 2 */ + FSE_encodeSymbol(&bitC, &CState2, *--ip); + FSE_encodeSymbol(&bitC, &CState1, *--ip); + FSE_FLUSHBITS(&bitC); + } + + /* 2 or 4 encoding per loop */ + while ( ip>istart ) { + + FSE_encodeSymbol(&bitC, &CState2, *--ip); + + if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 ) /* this test must be static */ + FSE_FLUSHBITS(&bitC); + + FSE_encodeSymbol(&bitC, &CState1, *--ip); + + if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) { /* this test must be static */ + FSE_encodeSymbol(&bitC, &CState2, *--ip); + FSE_encodeSymbol(&bitC, &CState1, *--ip); + } + + FSE_FLUSHBITS(&bitC); + } + + FSE_flushCState(&bitC, &CState2); + FSE_flushCState(&bitC, &CState1); + return BIT_closeCStream(&bitC); +} + +size_t FSE_compress_usingCTable (void* dst, size_t dstSize, + const void* src, size_t srcSize, + const FSE_CTable* ct) +{ + unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize)); + + if (fast) + return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1); + else + return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0); +} + + +size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } + +#endif /* FSE_COMMONDEFS_ONLY */ diff --git a/src/commonlib/bsd/zstd/compress/hist.c b/src/commonlib/bsd/zstd/compress/hist.c new file mode 100644 index 00000000000..f5c6ecbc5c1 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/hist.c @@ -0,0 +1,193 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * hist : Histogram functions + * part of Finite State Entropy project + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* --- dependencies --- */ +#include "../common/mem.h" /* U32, BYTE, etc. */ +#include "../common/debug.h" /* assert, DEBUGLOG */ +#include "../common/error_private.h" /* ERROR */ +#include "hist.h" + + +/* --- Error management --- */ +unsigned HIST_isError(size_t code) { return ERR_isError(code); } + +/*-************************************************************** + * Histogram functions + ****************************************************************/ +void HIST_add(unsigned* count, const void* src, size_t srcSize) +{ + const BYTE* ip = (const BYTE*)src; + const BYTE* const end = ip + srcSize; + + while (ip largestCount) largestCount = count[s]; + } + + return largestCount; +} + +typedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e; + +/* HIST_count_parallel_wksp() : + * store histogram into 4 intermediate tables, recombined at the end. + * this design makes better use of OoO cpus, + * and is noticeably faster when some values are heavily repeated. + * But it needs some additional workspace for intermediate tables. + * `workSpace` must be a U32 table of size >= HIST_WKSP_SIZE_U32. + * @return : largest histogram frequency, + * or an error code (notably when histogram's alphabet is larger than *maxSymbolValuePtr) */ +static size_t HIST_count_parallel_wksp( + unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, + HIST_checkInput_e check, + U32* const workSpace) +{ + const BYTE* ip = (const BYTE*)source; + const BYTE* const iend = ip+sourceSize; + size_t const countSize = (*maxSymbolValuePtr + 1) * sizeof(*count); + unsigned max=0; + U32* const Counting1 = workSpace; + U32* const Counting2 = Counting1 + 256; + U32* const Counting3 = Counting2 + 256; + U32* const Counting4 = Counting3 + 256; + + /* safety checks */ + assert(*maxSymbolValuePtr <= 255); + if (!sourceSize) { + ZSTD_memset(count, 0, countSize); + *maxSymbolValuePtr = 0; + return 0; + } + ZSTD_memset(workSpace, 0, 4*256*sizeof(unsigned)); + + /* by stripes of 16 bytes */ + { U32 cached = MEM_read32(ip); ip += 4; + while (ip < iend-15) { + U32 c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + c = cached; cached = MEM_read32(ip); ip += 4; + Counting1[(BYTE) c ]++; + Counting2[(BYTE)(c>>8) ]++; + Counting3[(BYTE)(c>>16)]++; + Counting4[ c>>24 ]++; + } + ip-=4; + } + + /* finish last symbols */ + while (ip max) max = Counting1[s]; + } } + + { unsigned maxSymbolValue = 255; + while (!Counting1[maxSymbolValue]) maxSymbolValue--; + if (check && maxSymbolValue > *maxSymbolValuePtr) return ERROR(maxSymbolValue_tooSmall); + *maxSymbolValuePtr = maxSymbolValue; + ZSTD_memmove(count, Counting1, countSize); /* in case count & Counting1 are overlapping */ + } + return (size_t)max; +} + +/* HIST_countFast_wksp() : + * Same as HIST_countFast(), but using an externally provided scratch buffer. + * `workSpace` is a writable buffer which must be 4-bytes aligned, + * `workSpaceSize` must be >= HIST_WKSP_SIZE + */ +size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, + void* workSpace, size_t workSpaceSize) +{ + if (sourceSize < 1500) /* heuristic threshold */ + return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize); + if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */ + if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall); + return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace); +} + +/* HIST_count_wksp() : + * Same as HIST_count(), but using an externally provided scratch buffer. + * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */ +size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize, + void* workSpace, size_t workSpaceSize) +{ + if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */ + if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall); + if (*maxSymbolValuePtr < 255) + return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, checkMaxSymbolValue, (U32*)workSpace); + *maxSymbolValuePtr = 255; + return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace, workSpaceSize); +} + +#ifndef ZSTD_NO_UNUSED_FUNCTIONS +/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */ +size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr, + const void* source, size_t sourceSize) +{ + unsigned tmpCounters[HIST_WKSP_SIZE_U32]; + return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters)); +} + +size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize) +{ + unsigned tmpCounters[HIST_WKSP_SIZE_U32]; + return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters, sizeof(tmpCounters)); +} +#endif diff --git a/src/commonlib/bsd/zstd/compress/hist.h b/src/commonlib/bsd/zstd/compress/hist.h new file mode 100644 index 00000000000..acb2aec6d51 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/hist.h @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * hist : Histogram functions + * part of Finite State Entropy project + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* --- dependencies --- */ +#include "../common/zstd_deps.h" /* size_t */ + + +/* --- simple histogram functions --- */ + +/*! HIST_count(): + * Provides the precise count of each byte within a table 'count'. + * 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1). + * Updates *maxSymbolValuePtr with actual largest symbol value detected. + * @return : count of the most frequent symbol (which isn't identified). + * or an error code, which can be tested using HIST_isError(). + * note : if return == srcSize, there is only one symbol. + */ +size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize); + +unsigned HIST_isError(size_t code); /**< tells if a return value is an error code */ + + +/* --- advanced histogram functions --- */ + +#define HIST_WKSP_SIZE_U32 1024 +#define HIST_WKSP_SIZE (HIST_WKSP_SIZE_U32 * sizeof(unsigned)) +/** HIST_count_wksp() : + * Same as HIST_count(), but using an externally provided scratch buffer. + * Benefit is this function will use very little stack space. + * `workSpace` is a writable buffer which must be 4-bytes aligned, + * `workSpaceSize` must be >= HIST_WKSP_SIZE + */ +size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize, + void* workSpace, size_t workSpaceSize); + +/** HIST_countFast() : + * same as HIST_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr. + * This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr` + */ +size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize); + +/** HIST_countFast_wksp() : + * Same as HIST_countFast(), but using an externally provided scratch buffer. + * `workSpace` is a writable buffer which must be 4-bytes aligned, + * `workSpaceSize` must be >= HIST_WKSP_SIZE + */ +size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize, + void* workSpace, size_t workSpaceSize); + +/*! HIST_count_simple() : + * Same as HIST_countFast(), this function is unsafe, + * and will segfault if any value within `src` is `> *maxSymbolValuePtr`. + * It is also a bit slower for large inputs. + * However, it does not need any additional memory (not even on stack). + * @return : count of the most frequent symbol. + * Note this function doesn't produce any error (i.e. it must succeed). + */ +unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, + const void* src, size_t srcSize); + +/*! HIST_add() : + * Lowest level: just add nb of occurrences of characters from @src into @count. + * @count is not reset. @count array is presumed large enough (i.e. 1 KB). + @ This function does not need any additional stack memory. + */ +void HIST_add(unsigned* count, const void* src, size_t srcSize); diff --git a/src/commonlib/bsd/zstd/compress/huf_compress.c b/src/commonlib/bsd/zstd/compress/huf_compress.c new file mode 100644 index 00000000000..add0c589fd6 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/huf_compress.c @@ -0,0 +1,1466 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * Huffman encoder, part of New Generation Entropy library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy + * - Public forum : https://groups.google.com/forum/#!forum/lz4c + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* ************************************************************** +* Compiler specifics +****************************************************************/ +#ifdef _MSC_VER /* Visual Studio */ +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ +#endif + + +/* ************************************************************** +* Includes +****************************************************************/ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */ +#include "../common/zstd_compiler.h" +#include "../common/bitstream.h" +#include "hist.h" +#define FSE_STATIC_LINKING_ONLY /* FSE_optimalTableLog_internal */ +#include "../common/fse.h" /* header compression */ +#include "../common/huf.h" +#include "../common/error_private.h" +#include "../common/zstd_bits.h" /* ZSTD_highbit32 */ + + +/* ************************************************************** +* Error Management +****************************************************************/ +#define HUF_isError ERR_isError +#define HUF_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */ + + +/* ************************************************************** +* Required declarations +****************************************************************/ +typedef struct nodeElt_s { + U32 count; + U16 parent; + BYTE byte; + BYTE nbBits; +} nodeElt; + + +/* ************************************************************** +* Debug Traces +****************************************************************/ + +#if DEBUGLEVEL >= 2 + +static size_t showU32(const U32* arr, size_t size) +{ + size_t u; + for (u=0; u= add) { + assert(add < align); + assert(((size_t)aligned & mask) == 0); + *workspaceSizePtr -= add; + return aligned; + } else { + *workspaceSizePtr = 0; + return NULL; + } +} + + +/* HUF_compressWeights() : + * Same as FSE_compress(), but dedicated to huff0's weights compression. + * The use case needs much less stack memory. + * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX. + */ +#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6 + +typedef struct { + FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)]; + U32 scratchBuffer[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(HUF_TABLELOG_MAX, MAX_FSE_TABLELOG_FOR_HUFF_HEADER)]; + unsigned count[HUF_TABLELOG_MAX+1]; + S16 norm[HUF_TABLELOG_MAX+1]; +} HUF_CompressWeightsWksp; + +static size_t +HUF_compressWeights(void* dst, size_t dstSize, + const void* weightTable, size_t wtSize, + void* workspace, size_t workspaceSize) +{ + BYTE* const ostart = (BYTE*) dst; + BYTE* op = ostart; + BYTE* const oend = ostart + dstSize; + + unsigned maxSymbolValue = HUF_TABLELOG_MAX; + U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER; + HUF_CompressWeightsWksp* wksp = (HUF_CompressWeightsWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, ZSTD_ALIGNOF(U32)); + + if (workspaceSize < sizeof(HUF_CompressWeightsWksp)) return ERROR(GENERIC); + + /* init conditions */ + if (wtSize <= 1) return 0; /* Not compressible */ + + /* Scan input and build symbol stats */ + { unsigned const maxCount = HIST_count_simple(wksp->count, &maxSymbolValue, weightTable, wtSize); /* never fails */ + if (maxCount == wtSize) return 1; /* only a single symbol in src : rle */ + if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */ + } + + tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue); + CHECK_F( FSE_normalizeCount(wksp->norm, tableLog, wksp->count, wtSize, maxSymbolValue, /* useLowProbCount */ 0) ); + + /* Write table description header */ + { CHECK_V_F(hSize, FSE_writeNCount(op, (size_t)(oend-op), wksp->norm, maxSymbolValue, tableLog) ); + op += hSize; + } + + /* Compress */ + CHECK_F( FSE_buildCTable_wksp(wksp->CTable, wksp->norm, maxSymbolValue, tableLog, wksp->scratchBuffer, sizeof(wksp->scratchBuffer)) ); + { CHECK_V_F(cSize, FSE_compress_usingCTable(op, (size_t)(oend - op), weightTable, wtSize, wksp->CTable) ); + if (cSize == 0) return 0; /* not enough space for compressed data */ + op += cSize; + } + + return (size_t)(op-ostart); +} + +static size_t HUF_getNbBits(HUF_CElt elt) +{ + return elt & 0xFF; +} + +static size_t HUF_getNbBitsFast(HUF_CElt elt) +{ + return elt; +} + +static size_t HUF_getValue(HUF_CElt elt) +{ + return elt & ~(size_t)0xFF; +} + +static size_t HUF_getValueFast(HUF_CElt elt) +{ + return elt; +} + +static void HUF_setNbBits(HUF_CElt* elt, size_t nbBits) +{ + assert(nbBits <= HUF_TABLELOG_ABSOLUTEMAX); + *elt = nbBits; +} + +static void HUF_setValue(HUF_CElt* elt, size_t value) +{ + size_t const nbBits = HUF_getNbBits(*elt); + if (nbBits > 0) { + assert((value >> nbBits) == 0); + *elt |= value << (sizeof(HUF_CElt) * 8 - nbBits); + } +} + +HUF_CTableHeader HUF_readCTableHeader(HUF_CElt const* ctable) +{ + HUF_CTableHeader header; + ZSTD_memcpy(&header, ctable, sizeof(header)); + return header; +} + +static void HUF_writeCTableHeader(HUF_CElt* ctable, U32 tableLog, U32 maxSymbolValue) +{ + HUF_CTableHeader header; + HUF_STATIC_ASSERT(sizeof(ctable[0]) == sizeof(header)); + ZSTD_memset(&header, 0, sizeof(header)); + assert(tableLog < 256); + header.tableLog = (BYTE)tableLog; + assert(maxSymbolValue < 256); + header.maxSymbolValue = (BYTE)maxSymbolValue; + ZSTD_memcpy(ctable, &header, sizeof(header)); +} + +typedef struct { + HUF_CompressWeightsWksp wksp; + BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */ + BYTE huffWeight[HUF_SYMBOLVALUE_MAX]; +} HUF_WriteCTableWksp; + +size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, + const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, + void* workspace, size_t workspaceSize) +{ + HUF_CElt const* const ct = CTable + 1; + BYTE* op = (BYTE*)dst; + U32 n; + HUF_WriteCTableWksp* wksp = (HUF_WriteCTableWksp*)HUF_alignUpWorkspace(workspace, &workspaceSize, ZSTD_ALIGNOF(U32)); + + HUF_STATIC_ASSERT(HUF_CTABLE_WORKSPACE_SIZE >= sizeof(HUF_WriteCTableWksp)); + + assert(HUF_readCTableHeader(CTable).maxSymbolValue == maxSymbolValue); + assert(HUF_readCTableHeader(CTable).tableLog == huffLog); + + /* check conditions */ + if (workspaceSize < sizeof(HUF_WriteCTableWksp)) return ERROR(GENERIC); + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge); + + /* convert to weight */ + wksp->bitsToWeight[0] = 0; + for (n=1; nbitsToWeight[n] = (BYTE)(huffLog + 1 - n); + for (n=0; nhuffWeight[n] = wksp->bitsToWeight[HUF_getNbBits(ct[n])]; + + /* attempt weights compression by FSE */ + if (maxDstSize < 1) return ERROR(dstSize_tooSmall); + { CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, wksp->huffWeight, maxSymbolValue, &wksp->wksp, sizeof(wksp->wksp)) ); + if ((hSize>1) & (hSize < maxSymbolValue/2)) { /* FSE compressed */ + op[0] = (BYTE)hSize; + return hSize+1; + } } + + /* write raw values as 4-bits (max : 15) */ + if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen : likely means source cannot be compressed */ + if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */ + op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1)); + wksp->huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause msan issue in final combination */ + for (n=0; nhuffWeight[n] << 4) + wksp->huffWeight[n+1]); + return ((maxSymbolValue+1)/2) + 1; +} + + +size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned* hasZeroWeights) +{ + BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; /* init not required, even though some static analyzer may complain */ + U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */ + U32 tableLog = 0; + U32 nbSymbols = 0; + HUF_CElt* const ct = CTable + 1; + + /* get symbol weights */ + CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize)); + *hasZeroWeights = (rankVal[0] > 0); + + /* check result */ + if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); + if (nbSymbols > *maxSymbolValuePtr+1) return ERROR(maxSymbolValue_tooSmall); + + *maxSymbolValuePtr = nbSymbols - 1; + + HUF_writeCTableHeader(CTable, tableLog, *maxSymbolValuePtr); + + /* Prepare base value per rank */ + { U32 n, nextRankStart = 0; + for (n=1; n<=tableLog; n++) { + U32 curr = nextRankStart; + nextRankStart += (rankVal[n] << (n-1)); + rankVal[n] = curr; + } } + + /* fill nbBits */ + { U32 n; for (n=0; nn=tableLog+1 */ + U16 valPerRank[HUF_TABLELOG_MAX+2] = {0}; + { U32 n; for (n=0; n0; n--) { /* start at n=tablelog <-> w=1 */ + valPerRank[n] = min; /* get starting value within each rank */ + min += nbPerRank[n]; + min >>= 1; + } } + /* assign value within rank, symbol order */ + { U32 n; for (n=0; n HUF_readCTableHeader(CTable).maxSymbolValue) + return 0; + return (U32)HUF_getNbBits(ct[symbolValue]); +} + + +/** + * HUF_setMaxHeight(): + * Try to enforce @targetNbBits on the Huffman tree described in @huffNode. + * + * It attempts to convert all nodes with nbBits > @targetNbBits + * to employ @targetNbBits instead. Then it adjusts the tree + * so that it remains a valid canonical Huffman tree. + * + * @pre The sum of the ranks of each symbol == 2^largestBits, + * where largestBits == huffNode[lastNonNull].nbBits. + * @post The sum of the ranks of each symbol == 2^largestBits, + * where largestBits is the return value (expected <= targetNbBits). + * + * @param huffNode The Huffman tree modified in place to enforce targetNbBits. + * It's presumed sorted, from most frequent to rarest symbol. + * @param lastNonNull The symbol with the lowest count in the Huffman tree. + * @param targetNbBits The allowed number of bits, which the Huffman tree + * may not respect. After this function the Huffman tree will + * respect targetNbBits. + * @return The maximum number of bits of the Huffman tree after adjustment. + */ +static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 targetNbBits) +{ + const U32 largestBits = huffNode[lastNonNull].nbBits; + /* early exit : no elt > targetNbBits, so the tree is already valid. */ + if (largestBits <= targetNbBits) return largestBits; + + DEBUGLOG(5, "HUF_setMaxHeight (targetNbBits = %u)", targetNbBits); + + /* there are several too large elements (at least >= 2) */ + { int totalCost = 0; + const U32 baseCost = 1 << (largestBits - targetNbBits); + int n = (int)lastNonNull; + + /* Adjust any ranks > targetNbBits to targetNbBits. + * Compute totalCost, which is how far the sum of the ranks is + * we are over 2^largestBits after adjust the offending ranks. + */ + while (huffNode[n].nbBits > targetNbBits) { + totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits)); + huffNode[n].nbBits = (BYTE)targetNbBits; + n--; + } + /* n stops at huffNode[n].nbBits <= targetNbBits */ + assert(huffNode[n].nbBits <= targetNbBits); + /* n end at index of smallest symbol using < targetNbBits */ + while (huffNode[n].nbBits == targetNbBits) --n; + + /* renorm totalCost from 2^largestBits to 2^targetNbBits + * note : totalCost is necessarily a multiple of baseCost */ + assert(((U32)totalCost & (baseCost - 1)) == 0); + totalCost >>= (largestBits - targetNbBits); + assert(totalCost > 0); + + /* repay normalized cost */ + { U32 const noSymbol = 0xF0F0F0F0; + U32 rankLast[HUF_TABLELOG_MAX+2]; + + /* Get pos of last (smallest = lowest cum. count) symbol per rank */ + ZSTD_memset(rankLast, 0xF0, sizeof(rankLast)); + { U32 currentNbBits = targetNbBits; + int pos; + for (pos=n ; pos >= 0; pos--) { + if (huffNode[pos].nbBits >= currentNbBits) continue; + currentNbBits = huffNode[pos].nbBits; /* < targetNbBits */ + rankLast[targetNbBits-currentNbBits] = (U32)pos; + } } + + while (totalCost > 0) { + /* Try to reduce the next power of 2 above totalCost because we + * gain back half the rank. + */ + U32 nBitsToDecrease = ZSTD_highbit32((U32)totalCost) + 1; + for ( ; nBitsToDecrease > 1; nBitsToDecrease--) { + U32 const highPos = rankLast[nBitsToDecrease]; + U32 const lowPos = rankLast[nBitsToDecrease-1]; + if (highPos == noSymbol) continue; + /* Decrease highPos if no symbols of lowPos or if it is + * not cheaper to remove 2 lowPos than highPos. + */ + if (lowPos == noSymbol) break; + { U32 const highTotal = huffNode[highPos].count; + U32 const lowTotal = 2 * huffNode[lowPos].count; + if (highTotal <= lowTotal) break; + } } + /* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */ + assert(rankLast[nBitsToDecrease] != noSymbol || nBitsToDecrease == 1); + /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */ + while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol)) + nBitsToDecrease++; + assert(rankLast[nBitsToDecrease] != noSymbol); + /* Increase the number of bits to gain back half the rank cost. */ + totalCost -= 1 << (nBitsToDecrease-1); + huffNode[rankLast[nBitsToDecrease]].nbBits++; + + /* Fix up the new rank. + * If the new rank was empty, this symbol is now its smallest. + * Otherwise, this symbol will be the largest in the new rank so no adjustment. + */ + if (rankLast[nBitsToDecrease-1] == noSymbol) + rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]; + /* Fix up the old rank. + * If the symbol was at position 0, meaning it was the highest weight symbol in the tree, + * it must be the only symbol in its rank, so the old rank now has no symbols. + * Otherwise, since the Huffman nodes are sorted by count, the previous position is now + * the smallest node in the rank. If the previous position belongs to a different rank, + * then the rank is now empty. + */ + if (rankLast[nBitsToDecrease] == 0) /* special case, reached largest symbol */ + rankLast[nBitsToDecrease] = noSymbol; + else { + rankLast[nBitsToDecrease]--; + if (huffNode[rankLast[nBitsToDecrease]].nbBits != targetNbBits-nBitsToDecrease) + rankLast[nBitsToDecrease] = noSymbol; /* this rank is now empty */ + } + } /* while (totalCost > 0) */ + + /* If we've removed too much weight, then we have to add it back. + * To avoid overshooting again, we only adjust the smallest rank. + * We take the largest nodes from the lowest rank 0 and move them + * to rank 1. There's guaranteed to be enough rank 0 symbols because + * TODO. + */ + while (totalCost < 0) { /* Sometimes, cost correction overshoot */ + /* special case : no rank 1 symbol (using targetNbBits-1); + * let's create one from largest rank 0 (using targetNbBits). + */ + if (rankLast[1] == noSymbol) { + while (huffNode[n].nbBits == targetNbBits) n--; + huffNode[n+1].nbBits--; + assert(n >= 0); + rankLast[1] = (U32)(n+1); + totalCost++; + continue; + } + huffNode[ rankLast[1] + 1 ].nbBits--; + rankLast[1]++; + totalCost ++; + } + } /* repay normalized cost */ + } /* there are several too large elements (at least >= 2) */ + + return targetNbBits; +} + +typedef struct { + U16 base; + U16 curr; +} rankPos; + +typedef nodeElt huffNodeTable[2 * (HUF_SYMBOLVALUE_MAX + 1)]; + +/* Number of buckets available for HUF_sort() */ +#define RANK_POSITION_TABLE_SIZE 192 + +typedef struct { + huffNodeTable huffNodeTbl; + rankPos rankPosition[RANK_POSITION_TABLE_SIZE]; +} HUF_buildCTable_wksp_tables; + +/* RANK_POSITION_DISTINCT_COUNT_CUTOFF == Cutoff point in HUF_sort() buckets for which we use log2 bucketing. + * Strategy is to use as many buckets as possible for representing distinct + * counts while using the remainder to represent all "large" counts. + * + * To satisfy this requirement for 192 buckets, we can do the following: + * Let buckets 0-166 represent distinct counts of [0, 166] + * Let buckets 166 to 192 represent all remaining counts up to RANK_POSITION_MAX_COUNT_LOG using log2 bucketing. + */ +#define RANK_POSITION_MAX_COUNT_LOG 32 +#define RANK_POSITION_LOG_BUCKETS_BEGIN ((RANK_POSITION_TABLE_SIZE - 1) - RANK_POSITION_MAX_COUNT_LOG - 1 /* == 158 */) +#define RANK_POSITION_DISTINCT_COUNT_CUTOFF (RANK_POSITION_LOG_BUCKETS_BEGIN + ZSTD_highbit32(RANK_POSITION_LOG_BUCKETS_BEGIN) /* == 166 */) + +/* Return the appropriate bucket index for a given count. See definition of + * RANK_POSITION_DISTINCT_COUNT_CUTOFF for explanation of bucketing strategy. + */ +static U32 HUF_getIndex(U32 const count) { + return (count < RANK_POSITION_DISTINCT_COUNT_CUTOFF) + ? count + : ZSTD_highbit32(count) + RANK_POSITION_LOG_BUCKETS_BEGIN; +} + +/* Helper swap function for HUF_quickSortPartition() */ +static void HUF_swapNodes(nodeElt* a, nodeElt* b) { + nodeElt tmp = *a; + *a = *b; + *b = tmp; +} + +/* Returns 0 if the huffNode array is not sorted by descending count */ +MEM_STATIC int HUF_isSorted(nodeElt huffNode[], U32 const maxSymbolValue1) { + U32 i; + for (i = 1; i < maxSymbolValue1; ++i) { + if (huffNode[i].count > huffNode[i-1].count) { + return 0; + } + } + return 1; +} + +/* Insertion sort by descending order */ +HINT_INLINE void HUF_insertionSort(nodeElt huffNode[], int const low, int const high) { + int i; + int const size = high-low+1; + huffNode += low; + for (i = 1; i < size; ++i) { + nodeElt const key = huffNode[i]; + int j = i - 1; + while (j >= 0 && huffNode[j].count < key.count) { + huffNode[j + 1] = huffNode[j]; + j--; + } + huffNode[j + 1] = key; + } +} + +/* Pivot helper function for quicksort. */ +static int HUF_quickSortPartition(nodeElt arr[], int const low, int const high) { + /* Simply select rightmost element as pivot. "Better" selectors like + * median-of-three don't experimentally appear to have any benefit. + */ + U32 const pivot = arr[high].count; + int i = low - 1; + int j = low; + for ( ; j < high; j++) { + if (arr[j].count > pivot) { + i++; + HUF_swapNodes(&arr[i], &arr[j]); + } + } + HUF_swapNodes(&arr[i + 1], &arr[high]); + return i + 1; +} + +/* Classic quicksort by descending with partially iterative calls + * to reduce worst case callstack size. + */ +static void HUF_simpleQuickSort(nodeElt arr[], int low, int high) { + int const kInsertionSortThreshold = 8; + if (high - low < kInsertionSortThreshold) { + HUF_insertionSort(arr, low, high); + return; + } + while (low < high) { + int const idx = HUF_quickSortPartition(arr, low, high); + if (idx - low < high - idx) { + HUF_simpleQuickSort(arr, low, idx - 1); + low = idx + 1; + } else { + HUF_simpleQuickSort(arr, idx + 1, high); + high = idx - 1; + } + } +} + +/** + * HUF_sort(): + * Sorts the symbols [0, maxSymbolValue] by count[symbol] in decreasing order. + * This is a typical bucket sorting strategy that uses either quicksort or insertion sort to sort each bucket. + * + * @param[out] huffNode Sorted symbols by decreasing count. Only members `.count` and `.byte` are filled. + * Must have (maxSymbolValue + 1) entries. + * @param[in] count Histogram of the symbols. + * @param[in] maxSymbolValue Maximum symbol value. + * @param rankPosition This is a scratch workspace. Must have RANK_POSITION_TABLE_SIZE entries. + */ +static void HUF_sort(nodeElt huffNode[], const unsigned count[], U32 const maxSymbolValue, rankPos rankPosition[]) { + U32 n; + U32 const maxSymbolValue1 = maxSymbolValue+1; + + /* Compute base and set curr to base. + * For symbol s let lowerRank = HUF_getIndex(count[n]) and rank = lowerRank + 1. + * See HUF_getIndex to see bucketing strategy. + * We attribute each symbol to lowerRank's base value, because we want to know where + * each rank begins in the output, so for rank R we want to count ranks R+1 and above. + */ + ZSTD_memset(rankPosition, 0, sizeof(*rankPosition) * RANK_POSITION_TABLE_SIZE); + for (n = 0; n < maxSymbolValue1; ++n) { + U32 lowerRank = HUF_getIndex(count[n]); + assert(lowerRank < RANK_POSITION_TABLE_SIZE - 1); + rankPosition[lowerRank].base++; + } + + assert(rankPosition[RANK_POSITION_TABLE_SIZE - 1].base == 0); + /* Set up the rankPosition table */ + for (n = RANK_POSITION_TABLE_SIZE - 1; n > 0; --n) { + rankPosition[n-1].base += rankPosition[n].base; + rankPosition[n-1].curr = rankPosition[n-1].base; + } + + /* Insert each symbol into their appropriate bucket, setting up rankPosition table. */ + for (n = 0; n < maxSymbolValue1; ++n) { + U32 const c = count[n]; + U32 const r = HUF_getIndex(c) + 1; + U32 const pos = rankPosition[r].curr++; + assert(pos < maxSymbolValue1); + huffNode[pos].count = c; + huffNode[pos].byte = (BYTE)n; + } + + /* Sort each bucket. */ + for (n = RANK_POSITION_DISTINCT_COUNT_CUTOFF; n < RANK_POSITION_TABLE_SIZE - 1; ++n) { + int const bucketSize = rankPosition[n].curr - rankPosition[n].base; + U32 const bucketStartIdx = rankPosition[n].base; + if (bucketSize > 1) { + assert(bucketStartIdx < maxSymbolValue1); + HUF_simpleQuickSort(huffNode + bucketStartIdx, 0, bucketSize-1); + } + } + + assert(HUF_isSorted(huffNode, maxSymbolValue1)); +} + + +/** HUF_buildCTable_wksp() : + * Same as HUF_buildCTable(), but using externally allocated scratch buffer. + * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as sizeof(HUF_buildCTable_wksp_tables). + */ +#define STARTNODE (HUF_SYMBOLVALUE_MAX+1) + +/* HUF_buildTree(): + * Takes the huffNode array sorted by HUF_sort() and builds an unlimited-depth Huffman tree. + * + * @param huffNode The array sorted by HUF_sort(). Builds the Huffman tree in this array. + * @param maxSymbolValue The maximum symbol value. + * @return The smallest node in the Huffman tree (by count). + */ +static int HUF_buildTree(nodeElt* huffNode, U32 maxSymbolValue) +{ + nodeElt* const huffNode0 = huffNode - 1; + int nonNullRank; + int lowS, lowN; + int nodeNb = STARTNODE; + int n, nodeRoot; + DEBUGLOG(5, "HUF_buildTree (alphabet size = %u)", maxSymbolValue + 1); + /* init for parents */ + nonNullRank = (int)maxSymbolValue; + while(huffNode[nonNullRank].count == 0) nonNullRank--; + lowS = nonNullRank; nodeRoot = nodeNb + lowS - 1; lowN = nodeNb; + huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS-1].count; + huffNode[lowS].parent = huffNode[lowS-1].parent = (U16)nodeNb; + nodeNb++; lowS-=2; + for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30); + huffNode0[0].count = (U32)(1U<<31); /* fake entry, strong barrier */ + + /* create parents */ + while (nodeNb <= nodeRoot) { + int const n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++; + int const n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++; + huffNode[nodeNb].count = huffNode[n1].count + huffNode[n2].count; + huffNode[n1].parent = huffNode[n2].parent = (U16)nodeNb; + nodeNb++; + } + + /* distribute weights (unlimited tree height) */ + huffNode[nodeRoot].nbBits = 0; + for (n=nodeRoot-1; n>=STARTNODE; n--) + huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1; + for (n=0; n<=nonNullRank; n++) + huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1; + + DEBUGLOG(6, "Initial distribution of bits completed (%zu sorted symbols)", showHNodeBits(huffNode, maxSymbolValue+1)); + + return nonNullRank; +} + +/** + * HUF_buildCTableFromTree(): + * Build the CTable given the Huffman tree in huffNode. + * + * @param[out] CTable The output Huffman CTable. + * @param huffNode The Huffman tree. + * @param nonNullRank The last and smallest node in the Huffman tree. + * @param maxSymbolValue The maximum symbol value. + * @param maxNbBits The exact maximum number of bits used in the Huffman tree. + */ +static void HUF_buildCTableFromTree(HUF_CElt* CTable, nodeElt const* huffNode, int nonNullRank, U32 maxSymbolValue, U32 maxNbBits) +{ + HUF_CElt* const ct = CTable + 1; + /* fill result into ctable (val, nbBits) */ + int n; + U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0}; + U16 valPerRank[HUF_TABLELOG_MAX+1] = {0}; + int const alphabetSize = (int)(maxSymbolValue + 1); + for (n=0; n<=nonNullRank; n++) + nbPerRank[huffNode[n].nbBits]++; + /* determine starting value per rank */ + { U16 min = 0; + for (n=(int)maxNbBits; n>0; n--) { + valPerRank[n] = min; /* get starting value within each rank */ + min += nbPerRank[n]; + min >>= 1; + } } + for (n=0; nhuffNodeTbl; + nodeElt* const huffNode = huffNode0+1; + int nonNullRank; + + HUF_STATIC_ASSERT(HUF_CTABLE_WORKSPACE_SIZE == sizeof(HUF_buildCTable_wksp_tables)); + + DEBUGLOG(5, "HUF_buildCTable_wksp (alphabet size = %u)", maxSymbolValue+1); + + /* safety checks */ + if (wkspSize < sizeof(HUF_buildCTable_wksp_tables)) + return ERROR(workSpace_tooSmall); + if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT; + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) + return ERROR(maxSymbolValue_tooLarge); + ZSTD_memset(huffNode0, 0, sizeof(huffNodeTable)); + + /* sort, decreasing order */ + HUF_sort(huffNode, count, maxSymbolValue, wksp_tables->rankPosition); + DEBUGLOG(6, "sorted symbols completed (%zu symbols)", showHNodeSymbols(huffNode, maxSymbolValue+1)); + + /* build tree */ + nonNullRank = HUF_buildTree(huffNode, maxSymbolValue); + + /* determine and enforce maxTableLog */ + maxNbBits = HUF_setMaxHeight(huffNode, (U32)nonNullRank, maxNbBits); + if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */ + + HUF_buildCTableFromTree(CTable, huffNode, nonNullRank, maxSymbolValue, maxNbBits); + + return maxNbBits; +} + +size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) +{ + HUF_CElt const* ct = CTable + 1; + size_t nbBits = 0; + int s; + for (s = 0; s <= (int)maxSymbolValue; ++s) { + nbBits += HUF_getNbBits(ct[s]) * count[s]; + } + return nbBits >> 3; +} + +int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) { + HUF_CTableHeader header = HUF_readCTableHeader(CTable); + HUF_CElt const* ct = CTable + 1; + int bad = 0; + int s; + + assert(header.tableLog <= HUF_TABLELOG_ABSOLUTEMAX); + + if (header.maxSymbolValue < maxSymbolValue) + return 0; + + for (s = 0; s <= (int)maxSymbolValue; ++s) { + bad |= (count[s] != 0) & (HUF_getNbBits(ct[s]) == 0); + } + return !bad; +} + +size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); } + +/** HUF_CStream_t: + * Huffman uses its own BIT_CStream_t implementation. + * There are three major differences from BIT_CStream_t: + * 1. HUF_addBits() takes a HUF_CElt (size_t) which is + * the pair (nbBits, value) in the format: + * format: + * - Bits [0, 4) = nbBits + * - Bits [4, 64 - nbBits) = 0 + * - Bits [64 - nbBits, 64) = value + * 2. The bitContainer is built from the upper bits and + * right shifted. E.g. to add a new value of N bits + * you right shift the bitContainer by N, then or in + * the new value into the N upper bits. + * 3. The bitstream has two bit containers. You can add + * bits to the second container and merge them into + * the first container. + */ + +#define HUF_BITS_IN_CONTAINER (sizeof(size_t) * 8) + +typedef struct { + size_t bitContainer[2]; + size_t bitPos[2]; + + BYTE* startPtr; + BYTE* ptr; + BYTE* endPtr; +} HUF_CStream_t; + +/**! HUF_initCStream(): + * Initializes the bitstream. + * @returns 0 or an error code. + */ +static size_t HUF_initCStream(HUF_CStream_t* bitC, + void* startPtr, size_t dstCapacity) +{ + ZSTD_memset(bitC, 0, sizeof(*bitC)); + bitC->startPtr = (BYTE*)startPtr; + bitC->ptr = bitC->startPtr; + bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer[0]); + if (dstCapacity <= sizeof(bitC->bitContainer[0])) return ERROR(dstSize_tooSmall); + return 0; +} + +/*! HUF_addBits(): + * Adds the symbol stored in HUF_CElt elt to the bitstream. + * + * @param elt The element we're adding. This is a (nbBits, value) pair. + * See the HUF_CStream_t docs for the format. + * @param idx Insert into the bitstream at this idx. + * @param kFast This is a template parameter. If the bitstream is guaranteed + * to have at least 4 unused bits after this call it may be 1, + * otherwise it must be 0. HUF_addBits() is faster when fast is set. + */ +FORCE_INLINE_TEMPLATE void HUF_addBits(HUF_CStream_t* bitC, HUF_CElt elt, int idx, int kFast) +{ + assert(idx <= 1); + assert(HUF_getNbBits(elt) <= HUF_TABLELOG_ABSOLUTEMAX); + /* This is efficient on x86-64 with BMI2 because shrx + * only reads the low 6 bits of the register. The compiler + * knows this and elides the mask. When fast is set, + * every operation can use the same value loaded from elt. + */ + bitC->bitContainer[idx] >>= HUF_getNbBits(elt); + bitC->bitContainer[idx] |= kFast ? HUF_getValueFast(elt) : HUF_getValue(elt); + /* We only read the low 8 bits of bitC->bitPos[idx] so it + * doesn't matter that the high bits have noise from the value. + */ + bitC->bitPos[idx] += HUF_getNbBitsFast(elt); + assert((bitC->bitPos[idx] & 0xFF) <= HUF_BITS_IN_CONTAINER); + /* The last 4-bits of elt are dirty if fast is set, + * so we must not be overwriting bits that have already been + * inserted into the bit container. + */ +#if DEBUGLEVEL >= 1 + { + size_t const nbBits = HUF_getNbBits(elt); + size_t const dirtyBits = nbBits == 0 ? 0 : ZSTD_highbit32((U32)nbBits) + 1; + (void)dirtyBits; + /* Middle bits are 0. */ + assert(((elt >> dirtyBits) << (dirtyBits + nbBits)) == 0); + /* We didn't overwrite any bits in the bit container. */ + assert(!kFast || (bitC->bitPos[idx] & 0xFF) <= HUF_BITS_IN_CONTAINER); + (void)dirtyBits; + } +#endif +} + +FORCE_INLINE_TEMPLATE void HUF_zeroIndex1(HUF_CStream_t* bitC) +{ + bitC->bitContainer[1] = 0; + bitC->bitPos[1] = 0; +} + +/*! HUF_mergeIndex1() : + * Merges the bit container @ index 1 into the bit container @ index 0 + * and zeros the bit container @ index 1. + */ +FORCE_INLINE_TEMPLATE void HUF_mergeIndex1(HUF_CStream_t* bitC) +{ + assert((bitC->bitPos[1] & 0xFF) < HUF_BITS_IN_CONTAINER); + bitC->bitContainer[0] >>= (bitC->bitPos[1] & 0xFF); + bitC->bitContainer[0] |= bitC->bitContainer[1]; + bitC->bitPos[0] += bitC->bitPos[1]; + assert((bitC->bitPos[0] & 0xFF) <= HUF_BITS_IN_CONTAINER); +} + +/*! HUF_flushBits() : +* Flushes the bits in the bit container @ index 0. +* +* @post bitPos will be < 8. +* @param kFast If kFast is set then we must know a-priori that +* the bit container will not overflow. +*/ +FORCE_INLINE_TEMPLATE void HUF_flushBits(HUF_CStream_t* bitC, int kFast) +{ + /* The upper bits of bitPos are noisy, so we must mask by 0xFF. */ + size_t const nbBits = bitC->bitPos[0] & 0xFF; + size_t const nbBytes = nbBits >> 3; + /* The top nbBits bits of bitContainer are the ones we need. */ + size_t const bitContainer = bitC->bitContainer[0] >> (HUF_BITS_IN_CONTAINER - nbBits); + /* Mask bitPos to account for the bytes we consumed. */ + bitC->bitPos[0] &= 7; + assert(nbBits > 0); + assert(nbBits <= sizeof(bitC->bitContainer[0]) * 8); + assert(bitC->ptr <= bitC->endPtr); + MEM_writeLEST(bitC->ptr, bitContainer); + bitC->ptr += nbBytes; + assert(!kFast || bitC->ptr <= bitC->endPtr); + if (!kFast && bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr; + /* bitContainer doesn't need to be modified because the leftover + * bits are already the top bitPos bits. And we don't care about + * noise in the lower values. + */ +} + +/*! HUF_endMark() + * @returns The Huffman stream end mark: A 1-bit value = 1. + */ +static HUF_CElt HUF_endMark(void) +{ + HUF_CElt endMark; + HUF_setNbBits(&endMark, 1); + HUF_setValue(&endMark, 1); + return endMark; +} + +/*! HUF_closeCStream() : + * @return Size of CStream, in bytes, + * or 0 if it could not fit into dstBuffer */ +static size_t HUF_closeCStream(HUF_CStream_t* bitC) +{ + HUF_addBits(bitC, HUF_endMark(), /* idx */ 0, /* kFast */ 0); + HUF_flushBits(bitC, /* kFast */ 0); + { + size_t const nbBits = bitC->bitPos[0] & 0xFF; + if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */ + return (size_t)(bitC->ptr - bitC->startPtr) + (nbBits > 0); + } +} + +FORCE_INLINE_TEMPLATE void +HUF_encodeSymbol(HUF_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable, int idx, int fast) +{ + HUF_addBits(bitCPtr, CTable[symbol], idx, fast); +} + +FORCE_INLINE_TEMPLATE void +HUF_compress1X_usingCTable_internal_body_loop(HUF_CStream_t* bitC, + const BYTE* ip, size_t srcSize, + const HUF_CElt* ct, + int kUnroll, int kFastFlush, int kLastFast) +{ + /* Join to kUnroll */ + int n = (int)srcSize; + int rem = n % kUnroll; + if (rem > 0) { + for (; rem > 0; --rem) { + HUF_encodeSymbol(bitC, ip[--n], ct, 0, /* fast */ 0); + } + HUF_flushBits(bitC, kFastFlush); + } + assert(n % kUnroll == 0); + + /* Join to 2 * kUnroll */ + if (n % (2 * kUnroll)) { + int u; + for (u = 1; u < kUnroll; ++u) { + HUF_encodeSymbol(bitC, ip[n - u], ct, 0, 1); + } + HUF_encodeSymbol(bitC, ip[n - kUnroll], ct, 0, kLastFast); + HUF_flushBits(bitC, kFastFlush); + n -= kUnroll; + } + assert(n % (2 * kUnroll) == 0); + + for (; n>0; n-= 2 * kUnroll) { + /* Encode kUnroll symbols into the bitstream @ index 0. */ + int u; + for (u = 1; u < kUnroll; ++u) { + HUF_encodeSymbol(bitC, ip[n - u], ct, /* idx */ 0, /* fast */ 1); + } + HUF_encodeSymbol(bitC, ip[n - kUnroll], ct, /* idx */ 0, /* fast */ kLastFast); + HUF_flushBits(bitC, kFastFlush); + /* Encode kUnroll symbols into the bitstream @ index 1. + * This allows us to start filling the bit container + * without any data dependencies. + */ + HUF_zeroIndex1(bitC); + for (u = 1; u < kUnroll; ++u) { + HUF_encodeSymbol(bitC, ip[n - kUnroll - u], ct, /* idx */ 1, /* fast */ 1); + } + HUF_encodeSymbol(bitC, ip[n - kUnroll - kUnroll], ct, /* idx */ 1, /* fast */ kLastFast); + /* Merge bitstream @ index 1 into the bitstream @ index 0 */ + HUF_mergeIndex1(bitC); + HUF_flushBits(bitC, kFastFlush); + } + assert(n == 0); + +} + +/** + * Returns a tight upper bound on the output space needed by Huffman + * with 8 bytes buffer to handle over-writes. If the output is at least + * this large we don't need to do bounds checks during Huffman encoding. + */ +static size_t HUF_tightCompressBound(size_t srcSize, size_t tableLog) +{ + return ((srcSize * tableLog) >> 3) + 8; +} + + +FORCE_INLINE_TEMPLATE size_t +HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable) +{ + U32 const tableLog = HUF_readCTableHeader(CTable).tableLog; + HUF_CElt const* ct = CTable + 1; + const BYTE* ip = (const BYTE*) src; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstSize; + HUF_CStream_t bitC; + + /* init */ + if (dstSize < 8) return 0; /* not enough space to compress */ + { BYTE* op = ostart; + size_t const initErr = HUF_initCStream(&bitC, op, (size_t)(oend-op)); + if (HUF_isError(initErr)) return 0; } + + if (dstSize < HUF_tightCompressBound(srcSize, (size_t)tableLog) || tableLog > 11) + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ MEM_32bits() ? 2 : 4, /* kFast */ 0, /* kLastFast */ 0); + else { + if (MEM_32bits()) { + switch (tableLog) { + case 11: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 10: ZSTD_FALLTHROUGH; + case 9: ZSTD_FALLTHROUGH; + case 8: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 2, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + case 7: ZSTD_FALLTHROUGH; + default: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 3, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + } + } else { + switch (tableLog) { + case 11: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 5, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 10: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 5, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + case 9: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 6, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 8: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 7, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 7: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 8, /* kFastFlush */ 1, /* kLastFast */ 0); + break; + case 6: ZSTD_FALLTHROUGH; + default: + HUF_compress1X_usingCTable_internal_body_loop(&bitC, ip, srcSize, ct, /* kUnroll */ 9, /* kFastFlush */ 1, /* kLastFast */ 1); + break; + } + } + } + assert(bitC.ptr <= bitC.endPtr); + + return HUF_closeCStream(&bitC); +} + +#if DYNAMIC_BMI2 + +static BMI2_TARGET_ATTRIBUTE size_t +HUF_compress1X_usingCTable_internal_bmi2(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable) +{ + return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable); +} + +static size_t +HUF_compress1X_usingCTable_internal_default(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable) +{ + return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable); +} + +static size_t +HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable, const int flags) +{ + if (flags & HUF_flags_bmi2) { + return HUF_compress1X_usingCTable_internal_bmi2(dst, dstSize, src, srcSize, CTable); + } + return HUF_compress1X_usingCTable_internal_default(dst, dstSize, src, srcSize, CTable); +} + +#else + +static size_t +HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable, const int flags) +{ + (void)flags; + return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable); +} + +#endif + +size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags) +{ + return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags); +} + +static size_t +HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize, + const void* src, size_t srcSize, + const HUF_CElt* CTable, int flags) +{ + size_t const segmentSize = (srcSize+3)/4; /* first 3 segments */ + const BYTE* ip = (const BYTE*) src; + const BYTE* const iend = ip + srcSize; + BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + BYTE* op = ostart; + + if (dstSize < 6 + 1 + 1 + 1 + 8) return 0; /* minimum space to compress successfully */ + if (srcSize < 12) return 0; /* no saving possible : too small input */ + op += 6; /* jumpTable */ + + assert(op <= oend); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) ); + if (cSize == 0 || cSize > 65535) return 0; + MEM_writeLE16(ostart, (U16)cSize); + op += cSize; + } + + ip += segmentSize; + assert(op <= oend); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) ); + if (cSize == 0 || cSize > 65535) return 0; + MEM_writeLE16(ostart+2, (U16)cSize); + op += cSize; + } + + ip += segmentSize; + assert(op <= oend); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, segmentSize, CTable, flags) ); + if (cSize == 0 || cSize > 65535) return 0; + MEM_writeLE16(ostart+4, (U16)cSize); + op += cSize; + } + + ip += segmentSize; + assert(op <= oend); + assert(ip <= iend); + { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, (size_t)(oend-op), ip, (size_t)(iend-ip), CTable, flags) ); + if (cSize == 0 || cSize > 65535) return 0; + op += cSize; + } + + return (size_t)(op-ostart); +} + +size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int flags) +{ + return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, flags); +} + +typedef enum { HUF_singleStream, HUF_fourStreams } HUF_nbStreams_e; + +static size_t HUF_compressCTable_internal( + BYTE* const ostart, BYTE* op, BYTE* const oend, + const void* src, size_t srcSize, + HUF_nbStreams_e nbStreams, const HUF_CElt* CTable, const int flags) +{ + size_t const cSize = (nbStreams==HUF_singleStream) ? + HUF_compress1X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, flags) : + HUF_compress4X_usingCTable_internal(op, (size_t)(oend - op), src, srcSize, CTable, flags); + if (HUF_isError(cSize)) { return cSize; } + if (cSize==0) { return 0; } /* uncompressible */ + op += cSize; + /* check compressibility */ + assert(op >= ostart); + if ((size_t)(op-ostart) >= srcSize-1) { return 0; } + return (size_t)(op-ostart); +} + +typedef struct { + unsigned count[HUF_SYMBOLVALUE_MAX + 1]; + HUF_CElt CTable[HUF_CTABLE_SIZE_ST(HUF_SYMBOLVALUE_MAX)]; + union { + HUF_buildCTable_wksp_tables buildCTable_wksp; + HUF_WriteCTableWksp writeCTable_wksp; + U32 hist_wksp[HIST_WKSP_SIZE_U32]; + } wksps; +} HUF_compress_tables_t; + +#define SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE 4096 +#define SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO 10 /* Must be >= 2 */ + +unsigned HUF_cardinality(const unsigned* count, unsigned maxSymbolValue) +{ + unsigned cardinality = 0; + unsigned i; + + for (i = 0; i < maxSymbolValue + 1; i++) { + if (count[i] != 0) cardinality += 1; + } + + return cardinality; +} + +unsigned HUF_minTableLog(unsigned symbolCardinality) +{ + U32 minBitsSymbols = ZSTD_highbit32(symbolCardinality) + 1; + return minBitsSymbols; +} + +unsigned HUF_optimalTableLog( + unsigned maxTableLog, + size_t srcSize, + unsigned maxSymbolValue, + void* workSpace, size_t wkspSize, + HUF_CElt* table, + const unsigned* count, + int flags) +{ + assert(srcSize > 1); /* Not supported, RLE should be used instead */ + assert(wkspSize >= sizeof(HUF_buildCTable_wksp_tables)); + + if (!(flags & HUF_flags_optimalDepth)) { + /* cheap evaluation, based on FSE */ + return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1); + } + + { BYTE* dst = (BYTE*)workSpace + sizeof(HUF_WriteCTableWksp); + size_t dstSize = wkspSize - sizeof(HUF_WriteCTableWksp); + size_t hSize, newSize; + const unsigned symbolCardinality = HUF_cardinality(count, maxSymbolValue); + const unsigned minTableLog = HUF_minTableLog(symbolCardinality); + size_t optSize = ((size_t) ~0) - 1; + unsigned optLog = maxTableLog, optLogGuess; + + DEBUGLOG(6, "HUF_optimalTableLog: probing huf depth (srcSize=%zu)", srcSize); + + /* Search until size increases */ + for (optLogGuess = minTableLog; optLogGuess <= maxTableLog; optLogGuess++) { + DEBUGLOG(7, "checking for huffLog=%u", optLogGuess); + + { size_t maxBits = HUF_buildCTable_wksp(table, count, maxSymbolValue, optLogGuess, workSpace, wkspSize); + if (ERR_isError(maxBits)) continue; + + if (maxBits < optLogGuess && optLogGuess > minTableLog) break; + + hSize = HUF_writeCTable_wksp(dst, dstSize, table, maxSymbolValue, (U32)maxBits, workSpace, wkspSize); + } + + if (ERR_isError(hSize)) continue; + + newSize = HUF_estimateCompressedSize(table, count, maxSymbolValue) + hSize; + + if (newSize > optSize + 1) { + break; + } + + if (newSize < optSize) { + optSize = newSize; + optLog = optLogGuess; + } + } + assert(optLog <= HUF_TABLELOG_MAX); + return optLog; + } +} + +/* HUF_compress_internal() : + * `workSpace_align4` must be aligned on 4-bytes boundaries, + * and occupies the same space as a table of HUF_WORKSPACE_SIZE_U64 unsigned */ +static size_t +HUF_compress_internal (void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned huffLog, + HUF_nbStreams_e nbStreams, + void* workSpace, size_t wkspSize, + HUF_CElt* oldHufTable, HUF_repeat* repeat, int flags) +{ + HUF_compress_tables_t* const table = (HUF_compress_tables_t*)HUF_alignUpWorkspace(workSpace, &wkspSize, ZSTD_ALIGNOF(size_t)); + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstSize; + BYTE* op = ostart; + + DEBUGLOG(5, "HUF_compress_internal (srcSize=%zu)", srcSize); + HUF_STATIC_ASSERT(sizeof(*table) + HUF_WORKSPACE_MAX_ALIGNMENT <= HUF_WORKSPACE_SIZE); + + /* checks & inits */ + if (wkspSize < sizeof(*table)) return ERROR(workSpace_tooSmall); + if (!srcSize) return 0; /* Uncompressed */ + if (!dstSize) return 0; /* cannot fit anything within dst budget */ + if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */ + if (huffLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge); + if (!maxSymbolValue) maxSymbolValue = HUF_SYMBOLVALUE_MAX; + if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT; + + /* Heuristic : If old table is valid, use it for small inputs */ + if ((flags & HUF_flags_preferRepeat) && repeat && *repeat == HUF_repeat_valid) { + return HUF_compressCTable_internal(ostart, op, oend, + src, srcSize, + nbStreams, oldHufTable, flags); + } + + /* If uncompressible data is suspected, do a smaller sampling first */ + DEBUG_STATIC_ASSERT(SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO >= 2); + if ((flags & HUF_flags_suspectUncompressible) && srcSize >= (SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE * SUSPECT_INCOMPRESSIBLE_SAMPLE_RATIO)) { + size_t largestTotal = 0; + DEBUGLOG(5, "input suspected incompressible : sampling to check"); + { unsigned maxSymbolValueBegin = maxSymbolValue; + CHECK_V_F(largestBegin, HIST_count_simple (table->count, &maxSymbolValueBegin, (const BYTE*)src, SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) ); + largestTotal += largestBegin; + } + { unsigned maxSymbolValueEnd = maxSymbolValue; + CHECK_V_F(largestEnd, HIST_count_simple (table->count, &maxSymbolValueEnd, (const BYTE*)src + srcSize - SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE, SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) ); + largestTotal += largestEnd; + } + if (largestTotal <= ((2 * SUSPECT_INCOMPRESSIBLE_SAMPLE_SIZE) >> 7)+4) return 0; /* heuristic : probably not compressible enough */ + } + + /* Scan input and build symbol stats */ + { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, table->wksps.hist_wksp, sizeof(table->wksps.hist_wksp)) ); + if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */ + if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */ + } + DEBUGLOG(6, "histogram detail completed (%zu symbols)", showU32(table->count, maxSymbolValue+1)); + + /* Check validity of previous table */ + if ( repeat + && *repeat == HUF_repeat_check + && !HUF_validateCTable(oldHufTable, table->count, maxSymbolValue)) { + *repeat = HUF_repeat_none; + } + /* Heuristic : use existing table for small inputs */ + if ((flags & HUF_flags_preferRepeat) && repeat && *repeat != HUF_repeat_none) { + return HUF_compressCTable_internal(ostart, op, oend, + src, srcSize, + nbStreams, oldHufTable, flags); + } + + /* Build Huffman Tree */ + huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue, &table->wksps, sizeof(table->wksps), table->CTable, table->count, flags); + { size_t const maxBits = HUF_buildCTable_wksp(table->CTable, table->count, + maxSymbolValue, huffLog, + &table->wksps.buildCTable_wksp, sizeof(table->wksps.buildCTable_wksp)); + CHECK_F(maxBits); + huffLog = (U32)maxBits; + DEBUGLOG(6, "bit distribution completed (%zu symbols)", showCTableBits(table->CTable + 1, maxSymbolValue+1)); + } + + /* Write table description header */ + { CHECK_V_F(hSize, HUF_writeCTable_wksp(op, dstSize, table->CTable, maxSymbolValue, huffLog, + &table->wksps.writeCTable_wksp, sizeof(table->wksps.writeCTable_wksp)) ); + /* Check if using previous huffman table is beneficial */ + if (repeat && *repeat != HUF_repeat_none) { + size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, table->count, maxSymbolValue); + size_t const newSize = HUF_estimateCompressedSize(table->CTable, table->count, maxSymbolValue); + if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) { + return HUF_compressCTable_internal(ostart, op, oend, + src, srcSize, + nbStreams, oldHufTable, flags); + } } + + /* Use the new huffman table */ + if (hSize + 12ul >= srcSize) { return 0; } + op += hSize; + if (repeat) { *repeat = HUF_repeat_none; } + if (oldHufTable) + ZSTD_memcpy(oldHufTable, table->CTable, sizeof(table->CTable)); /* Save new table */ + } + return HUF_compressCTable_internal(ostart, op, oend, + src, srcSize, + nbStreams, table->CTable, flags); +} + +size_t HUF_compress1X_repeat (void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned huffLog, + void* workSpace, size_t wkspSize, + HUF_CElt* hufTable, HUF_repeat* repeat, int flags) +{ + DEBUGLOG(5, "HUF_compress1X_repeat (srcSize = %zu)", srcSize); + return HUF_compress_internal(dst, dstSize, src, srcSize, + maxSymbolValue, huffLog, HUF_singleStream, + workSpace, wkspSize, hufTable, + repeat, flags); +} + +/* HUF_compress4X_repeat(): + * compress input using 4 streams. + * consider skipping quickly + * reuse an existing huffman compression table */ +size_t HUF_compress4X_repeat (void* dst, size_t dstSize, + const void* src, size_t srcSize, + unsigned maxSymbolValue, unsigned huffLog, + void* workSpace, size_t wkspSize, + HUF_CElt* hufTable, HUF_repeat* repeat, int flags) +{ + DEBUGLOG(5, "HUF_compress4X_repeat (srcSize = %zu)", srcSize); + return HUF_compress_internal(dst, dstSize, src, srcSize, + maxSymbolValue, huffLog, HUF_fourStreams, + workSpace, wkspSize, + hufTable, repeat, flags); +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress.c b/src/commonlib/bsd/zstd/compress/zstd_compress.c new file mode 100644 index 00000000000..7cf21cc5cbe --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress.c @@ -0,0 +1,6046 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/*-************************************* +* Dependencies +***************************************/ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */ +#include "../common/zstd_deps.h" /* INT_MAX, ZSTD_memset, ZSTD_memcpy */ +#include "../common/mem.h" +#include "../common/error_private.h" +#include "hist.h" /* HIST_countFast_wksp */ +#define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */ +#include "../common/fse.h" +#include "../common/huf.h" +#include "zstd_compress_internal.h" +#include "zstd_compress_sequences.h" +#include "zstd_compress_literals.h" +#include "zstd_fast.h" +#include "zstd_double_fast.h" +#include "zstd_lazy.h" +#include "zstd_opt.h" +#include "zstd_ldm.h" +#include "zstd_compress_superblock.h" +#include "../common/zstd_bits.h" /* ZSTD_highbit32, ZSTD_rotateRight_U64 */ + +/* *************************************************************** +* Tuning parameters +*****************************************************************/ +/*! + * COMPRESS_HEAPMODE : + * Select how default decompression function ZSTD_compress() allocates its context, + * on stack (0, default), or into heap (1). + * Note that functions with explicit context such as ZSTD_compressCCtx() are unaffected. + */ +#ifndef ZSTD_COMPRESS_HEAPMODE +# define ZSTD_COMPRESS_HEAPMODE 0 +#endif + +/*! + * ZSTD_HASHLOG3_MAX : + * Maximum size of the hash table dedicated to find 3-bytes matches, + * in log format, aka 17 => 1 << 17 == 128Ki positions. + * This structure is only used in zstd_opt. + * Since allocation is centralized for all strategies, it has to be known here. + * The actual (selected) size of the hash table is then stored in ZSTD_MatchState_t.hashLog3, + * so that zstd_opt.c doesn't need to know about this constant. + */ +#ifndef ZSTD_HASHLOG3_MAX +# define ZSTD_HASHLOG3_MAX 17 +#endif + +/*-************************************* +* Helper functions +***************************************/ +/* ZSTD_compressBound() + * Note that the result from this function is only valid for + * the one-pass compression functions. + * When employing the streaming mode, + * if flushes are frequently altering the size of blocks, + * the overhead from block headers can make the compressed data larger + * than the return value of ZSTD_compressBound(). + */ +size_t ZSTD_compressBound(size_t srcSize) { + size_t const r = ZSTD_COMPRESSBOUND(srcSize); + if (r==0) return ERROR(srcSize_wrong); + return r; +} + + +/*-************************************* +* Context memory management +***************************************/ +struct ZSTD_CDict_s { + const void* dictContent; + size_t dictContentSize; + ZSTD_dictContentType_e dictContentType; /* The dictContentType the CDict was created with */ + U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */ + ZSTD_cwksp workspace; + ZSTD_MatchState_t matchState; + ZSTD_compressedBlockState_t cBlockState; + ZSTD_customMem customMem; + U32 dictID; + int compressionLevel; /* 0 indicates that advanced API was used to select CDict params */ + ZSTD_ParamSwitch_e useRowMatchFinder; /* Indicates whether the CDict was created with params that would use + * row-based matchfinder. Unless the cdict is reloaded, we will use + * the same greedy/lazy matchfinder at compression time. + */ +}; /* typedef'd to ZSTD_CDict within "zstd.h" */ + +ZSTD_CCtx* ZSTD_createCCtx(void) +{ + return ZSTD_createCCtx_advanced(ZSTD_defaultCMem); +} + +static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager) +{ + assert(cctx != NULL); + ZSTD_memset(cctx, 0, sizeof(*cctx)); + cctx->customMem = memManager; + cctx->bmi2 = ZSTD_cpuSupportsBmi2(); + { size_t const err = ZSTD_CCtx_reset(cctx, ZSTD_reset_parameters); + assert(!ZSTD_isError(err)); + (void)err; + } +} + +ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem) +{ + ZSTD_STATIC_ASSERT(zcss_init==0); + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1)); + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + { ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_customMalloc(sizeof(ZSTD_CCtx), customMem); + if (!cctx) return NULL; + ZSTD_initCCtx(cctx, customMem); + return cctx; + } +} + +ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize) +{ + ZSTD_cwksp ws; + ZSTD_CCtx* cctx; + if (workspaceSize <= sizeof(ZSTD_CCtx)) return NULL; /* minimum size */ + if ((size_t)workspace & 7) return NULL; /* must be 8-aligned */ + ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc); + + cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CCtx)); + if (cctx == NULL) return NULL; + + ZSTD_memset(cctx, 0, sizeof(ZSTD_CCtx)); + ZSTD_cwksp_move(&cctx->workspace, &ws); + cctx->staticSize = workspaceSize; + + /* statically sized space. tmpWorkspace never moves (but prev/next block swap places) */ + if (!ZSTD_cwksp_check_available(&cctx->workspace, TMP_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL; + cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t)); + cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t)); + cctx->tmpWorkspace = ZSTD_cwksp_reserve_object(&cctx->workspace, TMP_WORKSPACE_SIZE); + cctx->tmpWkspSize = TMP_WORKSPACE_SIZE; + cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); + return cctx; +} + +/** + * Clears and frees all of the dictionaries in the CCtx. + */ +static void ZSTD_clearAllDicts(ZSTD_CCtx* cctx) +{ + ZSTD_customFree(cctx->localDict.dictBuffer, cctx->customMem); + ZSTD_freeCDict(cctx->localDict.cdict); + ZSTD_memset(&cctx->localDict, 0, sizeof(cctx->localDict)); + ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict)); + cctx->cdict = NULL; +} + +static size_t ZSTD_sizeof_localDict(ZSTD_localDict dict) +{ + size_t const bufferSize = dict.dictBuffer != NULL ? dict.dictSize : 0; + size_t const cdictSize = ZSTD_sizeof_CDict(dict.cdict); + return bufferSize + cdictSize; +} + +static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx) +{ + assert(cctx != NULL); + assert(cctx->staticSize == 0); + ZSTD_clearAllDicts(cctx); +#ifdef ZSTD_MULTITHREAD + ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL; +#endif + ZSTD_cwksp_free(&cctx->workspace, cctx->customMem); +} + +size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx) +{ + DEBUGLOG(3, "ZSTD_freeCCtx (address: %p)", (void*)cctx); + if (cctx==NULL) return 0; /* support free on NULL */ + RETURN_ERROR_IF(cctx->staticSize, memory_allocation, + "not compatible with static CCtx"); + { int cctxInWorkspace = ZSTD_cwksp_owns_buffer(&cctx->workspace, cctx); + ZSTD_freeCCtxContent(cctx); + if (!cctxInWorkspace) ZSTD_customFree(cctx, cctx->customMem); + } + return 0; +} + + +static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx) +{ +#ifdef ZSTD_MULTITHREAD + return ZSTDMT_sizeof_CCtx(cctx->mtctx); +#else + (void)cctx; + return 0; +#endif +} + + +size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx) +{ + if (cctx==NULL) return 0; /* support sizeof on NULL */ + /* cctx may be in the workspace */ + return (cctx->workspace.workspace == cctx ? 0 : sizeof(*cctx)) + + ZSTD_cwksp_sizeof(&cctx->workspace) + + ZSTD_sizeof_localDict(cctx->localDict) + + ZSTD_sizeof_mtctx(cctx); +} + +/* private API call, for dictBuilder only */ +const SeqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); } + +/* Returns true if the strategy supports using a row based matchfinder */ +static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy) { + return (strategy >= ZSTD_greedy && strategy <= ZSTD_lazy2); +} + +/* Returns true if the strategy and useRowMatchFinder mode indicate that we will use the row based matchfinder + * for this compression. + */ +static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_ParamSwitch_e mode) { + assert(mode != ZSTD_ps_auto); + return ZSTD_rowMatchFinderSupported(strategy) && (mode == ZSTD_ps_enable); +} + +/* Returns row matchfinder usage given an initial mode and cParams */ +static ZSTD_ParamSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_ParamSwitch_e mode, + const ZSTD_compressionParameters* const cParams) { + if (mode != ZSTD_ps_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */ + mode = ZSTD_ps_disable; + if (!ZSTD_rowMatchFinderSupported(cParams->strategy)) return mode; + if (cParams->windowLog > 14) mode = ZSTD_ps_enable; + return mode; +} + +/* Returns block splitter usage (generally speaking, when using slower/stronger compression modes) */ +static ZSTD_ParamSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_ParamSwitch_e mode, + const ZSTD_compressionParameters* const cParams) { + if (mode != ZSTD_ps_auto) return mode; + return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 17) ? ZSTD_ps_enable : ZSTD_ps_disable; +} + +/* Returns 1 if the arguments indicate that we should allocate a chainTable, 0 otherwise */ +static int ZSTD_allocateChainTable(const ZSTD_strategy strategy, + const ZSTD_ParamSwitch_e useRowMatchFinder, + const U32 forDDSDict) { + assert(useRowMatchFinder != ZSTD_ps_auto); + /* We always should allocate a chaintable if we are allocating a matchstate for a DDS dictionary matchstate. + * We do not allocate a chaintable if we are using ZSTD_fast, or are using the row-based matchfinder. + */ + return forDDSDict || ((strategy != ZSTD_fast) && !ZSTD_rowMatchFinderUsed(strategy, useRowMatchFinder)); +} + +/* Returns ZSTD_ps_enable if compression parameters are such that we should + * enable long distance matching (wlog >= 27, strategy >= btopt). + * Returns ZSTD_ps_disable otherwise. + */ +static ZSTD_ParamSwitch_e ZSTD_resolveEnableLdm(ZSTD_ParamSwitch_e mode, + const ZSTD_compressionParameters* const cParams) { + if (mode != ZSTD_ps_auto) return mode; + return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27) ? ZSTD_ps_enable : ZSTD_ps_disable; +} + +static int ZSTD_resolveExternalSequenceValidation(int mode) { + return mode; +} + +/* Resolves maxBlockSize to the default if no value is present. */ +static size_t ZSTD_resolveMaxBlockSize(size_t maxBlockSize) { + if (maxBlockSize == 0) { + return ZSTD_BLOCKSIZE_MAX; + } else { + return maxBlockSize; + } +} + +static ZSTD_ParamSwitch_e ZSTD_resolveExternalRepcodeSearch(ZSTD_ParamSwitch_e value, int cLevel) { + if (value != ZSTD_ps_auto) return value; + if (cLevel < 10) { + return ZSTD_ps_disable; + } else { + return ZSTD_ps_enable; + } +} + +/* Returns 1 if compression parameters are such that CDict hashtable and chaintable indices are tagged. + * If so, the tags need to be removed in ZSTD_resetCCtx_byCopyingCDict. */ +static int ZSTD_CDictIndicesAreTagged(const ZSTD_compressionParameters* const cParams) { + return cParams->strategy == ZSTD_fast || cParams->strategy == ZSTD_dfast; +} + +static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams( + ZSTD_compressionParameters cParams) +{ + ZSTD_CCtx_params cctxParams; + /* should not matter, as all cParams are presumed properly defined */ + ZSTD_CCtxParams_init(&cctxParams, ZSTD_CLEVEL_DEFAULT); + cctxParams.cParams = cParams; + + /* Adjust advanced params according to cParams */ + cctxParams.ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams.ldmParams.enableLdm, &cParams); + if (cctxParams.ldmParams.enableLdm == ZSTD_ps_enable) { + ZSTD_ldm_adjustParameters(&cctxParams.ldmParams, &cParams); + assert(cctxParams.ldmParams.hashLog >= cctxParams.ldmParams.bucketSizeLog); + assert(cctxParams.ldmParams.hashRateLog < 32); + } + cctxParams.postBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.postBlockSplitter, &cParams); + cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams); + cctxParams.validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams.validateSequences); + cctxParams.maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams.maxBlockSize); + cctxParams.searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(cctxParams.searchForExternalRepcodes, + cctxParams.compressionLevel); + assert(!ZSTD_checkCParams(cParams)); + return cctxParams; +} + +static ZSTD_CCtx_params* ZSTD_createCCtxParams_advanced( + ZSTD_customMem customMem) +{ + ZSTD_CCtx_params* params; + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + params = (ZSTD_CCtx_params*)ZSTD_customCalloc( + sizeof(ZSTD_CCtx_params), customMem); + if (!params) { return NULL; } + ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT); + params->customMem = customMem; + return params; +} + +ZSTD_CCtx_params* ZSTD_createCCtxParams(void) +{ + return ZSTD_createCCtxParams_advanced(ZSTD_defaultCMem); +} + +size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params) +{ + if (params == NULL) { return 0; } + ZSTD_customFree(params, params->customMem); + return 0; +} + +size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params) +{ + return ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT); +} + +size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) { + RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!"); + ZSTD_memset(cctxParams, 0, sizeof(*cctxParams)); + cctxParams->compressionLevel = compressionLevel; + cctxParams->fParams.contentSizeFlag = 1; + return 0; +} + +#define ZSTD_NO_CLEVEL 0 + +/** + * Initializes `cctxParams` from `params` and `compressionLevel`. + * @param compressionLevel If params are derived from a compression level then that compression level, otherwise ZSTD_NO_CLEVEL. + */ +static void +ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams, + const ZSTD_parameters* params, + int compressionLevel) +{ + assert(!ZSTD_checkCParams(params->cParams)); + ZSTD_memset(cctxParams, 0, sizeof(*cctxParams)); + cctxParams->cParams = params->cParams; + cctxParams->fParams = params->fParams; + /* Should not matter, as all cParams are presumed properly defined. + * But, set it for tracing anyway. + */ + cctxParams->compressionLevel = compressionLevel; + cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, ¶ms->cParams); + cctxParams->postBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams->postBlockSplitter, ¶ms->cParams); + cctxParams->ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams->ldmParams.enableLdm, ¶ms->cParams); + cctxParams->validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams->validateSequences); + cctxParams->maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams->maxBlockSize); + cctxParams->searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(cctxParams->searchForExternalRepcodes, compressionLevel); + DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d, useBlockSplitter=%d ldm=%d", + cctxParams->useRowMatchFinder, cctxParams->postBlockSplitter, cctxParams->ldmParams.enableLdm); +} + +size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params) +{ + RETURN_ERROR_IF(!cctxParams, GENERIC, "NULL pointer!"); + FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) , ""); + ZSTD_CCtxParams_init_internal(cctxParams, ¶ms, ZSTD_NO_CLEVEL); + return 0; +} + +ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param) +{ + ZSTD_bounds bounds = { 0, 0, 0 }; + + switch(param) + { + case ZSTD_c_compressionLevel: + bounds.lowerBound = ZSTD_minCLevel(); + bounds.upperBound = ZSTD_maxCLevel(); + return bounds; + + case ZSTD_c_windowLog: + bounds.lowerBound = ZSTD_WINDOWLOG_MIN; + bounds.upperBound = ZSTD_WINDOWLOG_MAX; + return bounds; + + case ZSTD_c_hashLog: + bounds.lowerBound = ZSTD_HASHLOG_MIN; + bounds.upperBound = ZSTD_HASHLOG_MAX; + return bounds; + + case ZSTD_c_chainLog: + bounds.lowerBound = ZSTD_CHAINLOG_MIN; + bounds.upperBound = ZSTD_CHAINLOG_MAX; + return bounds; + + case ZSTD_c_searchLog: + bounds.lowerBound = ZSTD_SEARCHLOG_MIN; + bounds.upperBound = ZSTD_SEARCHLOG_MAX; + return bounds; + + case ZSTD_c_minMatch: + bounds.lowerBound = ZSTD_MINMATCH_MIN; + bounds.upperBound = ZSTD_MINMATCH_MAX; + return bounds; + + case ZSTD_c_targetLength: + bounds.lowerBound = ZSTD_TARGETLENGTH_MIN; + bounds.upperBound = ZSTD_TARGETLENGTH_MAX; + return bounds; + + case ZSTD_c_strategy: + bounds.lowerBound = ZSTD_STRATEGY_MIN; + bounds.upperBound = ZSTD_STRATEGY_MAX; + return bounds; + + case ZSTD_c_contentSizeFlag: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_checksumFlag: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_dictIDFlag: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_nbWorkers: + bounds.lowerBound = 0; +#ifdef ZSTD_MULTITHREAD + bounds.upperBound = ZSTDMT_NBWORKERS_MAX; +#else + bounds.upperBound = 0; +#endif + return bounds; + + case ZSTD_c_jobSize: + bounds.lowerBound = 0; +#ifdef ZSTD_MULTITHREAD + bounds.upperBound = ZSTDMT_JOBSIZE_MAX; +#else + bounds.upperBound = 0; +#endif + return bounds; + + case ZSTD_c_overlapLog: +#ifdef ZSTD_MULTITHREAD + bounds.lowerBound = ZSTD_OVERLAPLOG_MIN; + bounds.upperBound = ZSTD_OVERLAPLOG_MAX; +#else + bounds.lowerBound = 0; + bounds.upperBound = 0; +#endif + return bounds; + + case ZSTD_c_enableDedicatedDictSearch: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_enableLongDistanceMatching: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_ldmHashLog: + bounds.lowerBound = ZSTD_LDM_HASHLOG_MIN; + bounds.upperBound = ZSTD_LDM_HASHLOG_MAX; + return bounds; + + case ZSTD_c_ldmMinMatch: + bounds.lowerBound = ZSTD_LDM_MINMATCH_MIN; + bounds.upperBound = ZSTD_LDM_MINMATCH_MAX; + return bounds; + + case ZSTD_c_ldmBucketSizeLog: + bounds.lowerBound = ZSTD_LDM_BUCKETSIZELOG_MIN; + bounds.upperBound = ZSTD_LDM_BUCKETSIZELOG_MAX; + return bounds; + + case ZSTD_c_ldmHashRateLog: + bounds.lowerBound = ZSTD_LDM_HASHRATELOG_MIN; + bounds.upperBound = ZSTD_LDM_HASHRATELOG_MAX; + return bounds; + + /* experimental parameters */ + case ZSTD_c_rsyncable: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_forceMaxWindow : + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_format: + ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless); + bounds.lowerBound = ZSTD_f_zstd1; + bounds.upperBound = ZSTD_f_zstd1_magicless; /* note : how to ensure at compile time that this is the highest value enum ? */ + return bounds; + + case ZSTD_c_forceAttachDict: + ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceLoad); + bounds.lowerBound = ZSTD_dictDefaultAttach; + bounds.upperBound = ZSTD_dictForceLoad; /* note : how to ensure at compile time that this is the highest value enum ? */ + return bounds; + + case ZSTD_c_literalCompressionMode: + ZSTD_STATIC_ASSERT(ZSTD_ps_auto < ZSTD_ps_enable && ZSTD_ps_enable < ZSTD_ps_disable); + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_targetCBlockSize: + bounds.lowerBound = ZSTD_TARGETCBLOCKSIZE_MIN; + bounds.upperBound = ZSTD_TARGETCBLOCKSIZE_MAX; + return bounds; + + case ZSTD_c_srcSizeHint: + bounds.lowerBound = ZSTD_SRCSIZEHINT_MIN; + bounds.upperBound = ZSTD_SRCSIZEHINT_MAX; + return bounds; + + case ZSTD_c_stableInBuffer: + case ZSTD_c_stableOutBuffer: + bounds.lowerBound = (int)ZSTD_bm_buffered; + bounds.upperBound = (int)ZSTD_bm_stable; + return bounds; + + case ZSTD_c_blockDelimiters: + bounds.lowerBound = (int)ZSTD_sf_noBlockDelimiters; + bounds.upperBound = (int)ZSTD_sf_explicitBlockDelimiters; + return bounds; + + case ZSTD_c_validateSequences: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_splitAfterSequences: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_blockSplitterLevel: + bounds.lowerBound = 0; + bounds.upperBound = ZSTD_BLOCKSPLITTER_LEVEL_MAX; + return bounds; + + case ZSTD_c_useRowMatchFinder: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_deterministicRefPrefix: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_prefetchCDictTables: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + case ZSTD_c_enableSeqProducerFallback: + bounds.lowerBound = 0; + bounds.upperBound = 1; + return bounds; + + case ZSTD_c_maxBlockSize: + bounds.lowerBound = ZSTD_BLOCKSIZE_MAX_MIN; + bounds.upperBound = ZSTD_BLOCKSIZE_MAX; + return bounds; + + case ZSTD_c_repcodeResolution: + bounds.lowerBound = (int)ZSTD_ps_auto; + bounds.upperBound = (int)ZSTD_ps_disable; + return bounds; + + default: + bounds.error = ERROR(parameter_unsupported); + return bounds; + } +} + +/* ZSTD_cParam_clampBounds: + * Clamps the value into the bounded range. + */ +static size_t ZSTD_cParam_clampBounds(ZSTD_cParameter cParam, int* value) +{ + ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam); + if (ZSTD_isError(bounds.error)) return bounds.error; + if (*value < bounds.lowerBound) *value = bounds.lowerBound; + if (*value > bounds.upperBound) *value = bounds.upperBound; + return 0; +} + +#define BOUNDCHECK(cParam, val) \ + do { \ + RETURN_ERROR_IF(!ZSTD_cParam_withinBounds(cParam,val), \ + parameter_outOfBound, "Param out of bounds"); \ + } while (0) + + +static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) +{ + switch(param) + { + case ZSTD_c_compressionLevel: + case ZSTD_c_hashLog: + case ZSTD_c_chainLog: + case ZSTD_c_searchLog: + case ZSTD_c_minMatch: + case ZSTD_c_targetLength: + case ZSTD_c_strategy: + case ZSTD_c_blockSplitterLevel: + return 1; + + case ZSTD_c_format: + case ZSTD_c_windowLog: + case ZSTD_c_contentSizeFlag: + case ZSTD_c_checksumFlag: + case ZSTD_c_dictIDFlag: + case ZSTD_c_forceMaxWindow : + case ZSTD_c_nbWorkers: + case ZSTD_c_jobSize: + case ZSTD_c_overlapLog: + case ZSTD_c_rsyncable: + case ZSTD_c_enableDedicatedDictSearch: + case ZSTD_c_enableLongDistanceMatching: + case ZSTD_c_ldmHashLog: + case ZSTD_c_ldmMinMatch: + case ZSTD_c_ldmBucketSizeLog: + case ZSTD_c_ldmHashRateLog: + case ZSTD_c_forceAttachDict: + case ZSTD_c_literalCompressionMode: + case ZSTD_c_targetCBlockSize: + case ZSTD_c_srcSizeHint: + case ZSTD_c_stableInBuffer: + case ZSTD_c_stableOutBuffer: + case ZSTD_c_blockDelimiters: + case ZSTD_c_validateSequences: + case ZSTD_c_splitAfterSequences: + case ZSTD_c_useRowMatchFinder: + case ZSTD_c_deterministicRefPrefix: + case ZSTD_c_prefetchCDictTables: + case ZSTD_c_enableSeqProducerFallback: + case ZSTD_c_maxBlockSize: + case ZSTD_c_repcodeResolution: + default: + return 0; + } +} + +size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value) +{ + DEBUGLOG(4, "ZSTD_CCtx_setParameter (%i, %i)", (int)param, value); + if (cctx->streamStage != zcss_init) { + if (ZSTD_isUpdateAuthorized(param)) { + cctx->cParamsChanged = 1; + } else { + RETURN_ERROR(stage_wrong, "can only set params in cctx init stage"); + } } + + switch(param) + { + case ZSTD_c_nbWorkers: + RETURN_ERROR_IF((value!=0) && cctx->staticSize, parameter_unsupported, + "MT not compatible with static alloc"); + break; + + case ZSTD_c_compressionLevel: + case ZSTD_c_windowLog: + case ZSTD_c_hashLog: + case ZSTD_c_chainLog: + case ZSTD_c_searchLog: + case ZSTD_c_minMatch: + case ZSTD_c_targetLength: + case ZSTD_c_strategy: + case ZSTD_c_ldmHashRateLog: + case ZSTD_c_format: + case ZSTD_c_contentSizeFlag: + case ZSTD_c_checksumFlag: + case ZSTD_c_dictIDFlag: + case ZSTD_c_forceMaxWindow: + case ZSTD_c_forceAttachDict: + case ZSTD_c_literalCompressionMode: + case ZSTD_c_jobSize: + case ZSTD_c_overlapLog: + case ZSTD_c_rsyncable: + case ZSTD_c_enableDedicatedDictSearch: + case ZSTD_c_enableLongDistanceMatching: + case ZSTD_c_ldmHashLog: + case ZSTD_c_ldmMinMatch: + case ZSTD_c_ldmBucketSizeLog: + case ZSTD_c_targetCBlockSize: + case ZSTD_c_srcSizeHint: + case ZSTD_c_stableInBuffer: + case ZSTD_c_stableOutBuffer: + case ZSTD_c_blockDelimiters: + case ZSTD_c_validateSequences: + case ZSTD_c_splitAfterSequences: + case ZSTD_c_blockSplitterLevel: + case ZSTD_c_useRowMatchFinder: + case ZSTD_c_deterministicRefPrefix: + case ZSTD_c_prefetchCDictTables: + case ZSTD_c_enableSeqProducerFallback: + case ZSTD_c_maxBlockSize: + case ZSTD_c_repcodeResolution: + break; + + default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); + } + return ZSTD_CCtxParams_setParameter(&cctx->requestedParams, param, value); +} + +size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams, + ZSTD_cParameter param, int value) +{ + DEBUGLOG(4, "ZSTD_CCtxParams_setParameter (%i, %i)", (int)param, value); + switch(param) + { + case ZSTD_c_format : + BOUNDCHECK(ZSTD_c_format, value); + CCtxParams->format = (ZSTD_format_e)value; + return (size_t)CCtxParams->format; + + case ZSTD_c_compressionLevel : { + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), ""); + if (value == 0) + CCtxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default */ + else + CCtxParams->compressionLevel = value; + if (CCtxParams->compressionLevel >= 0) return (size_t)CCtxParams->compressionLevel; + return 0; /* return type (size_t) cannot represent negative values */ + } + + case ZSTD_c_windowLog : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_windowLog, value); + CCtxParams->cParams.windowLog = (U32)value; + return CCtxParams->cParams.windowLog; + + case ZSTD_c_hashLog : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_hashLog, value); + CCtxParams->cParams.hashLog = (U32)value; + return CCtxParams->cParams.hashLog; + + case ZSTD_c_chainLog : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_chainLog, value); + CCtxParams->cParams.chainLog = (U32)value; + return CCtxParams->cParams.chainLog; + + case ZSTD_c_searchLog : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_searchLog, value); + CCtxParams->cParams.searchLog = (U32)value; + return (size_t)value; + + case ZSTD_c_minMatch : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_minMatch, value); + CCtxParams->cParams.minMatch = (U32)value; + return CCtxParams->cParams.minMatch; + + case ZSTD_c_targetLength : + BOUNDCHECK(ZSTD_c_targetLength, value); + CCtxParams->cParams.targetLength = (U32)value; + return CCtxParams->cParams.targetLength; + + case ZSTD_c_strategy : + if (value!=0) /* 0 => use default */ + BOUNDCHECK(ZSTD_c_strategy, value); + CCtxParams->cParams.strategy = (ZSTD_strategy)value; + return (size_t)CCtxParams->cParams.strategy; + + case ZSTD_c_contentSizeFlag : + /* Content size written in frame header _when known_ (default:1) */ + DEBUGLOG(4, "set content size flag = %u", (value!=0)); + CCtxParams->fParams.contentSizeFlag = value != 0; + return (size_t)CCtxParams->fParams.contentSizeFlag; + + case ZSTD_c_checksumFlag : + /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */ + CCtxParams->fParams.checksumFlag = value != 0; + return (size_t)CCtxParams->fParams.checksumFlag; + + case ZSTD_c_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */ + DEBUGLOG(4, "set dictIDFlag = %u", (value!=0)); + CCtxParams->fParams.noDictIDFlag = !value; + return !CCtxParams->fParams.noDictIDFlag; + + case ZSTD_c_forceMaxWindow : + CCtxParams->forceWindow = (value != 0); + return (size_t)CCtxParams->forceWindow; + + case ZSTD_c_forceAttachDict : { + const ZSTD_dictAttachPref_e pref = (ZSTD_dictAttachPref_e)value; + BOUNDCHECK(ZSTD_c_forceAttachDict, (int)pref); + CCtxParams->attachDictPref = pref; + return CCtxParams->attachDictPref; + } + + case ZSTD_c_literalCompressionMode : { + const ZSTD_ParamSwitch_e lcm = (ZSTD_ParamSwitch_e)value; + BOUNDCHECK(ZSTD_c_literalCompressionMode, (int)lcm); + CCtxParams->literalCompressionMode = lcm; + return CCtxParams->literalCompressionMode; + } + + case ZSTD_c_nbWorkers : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading"); + return 0; +#else + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), ""); + CCtxParams->nbWorkers = value; + return (size_t)(CCtxParams->nbWorkers); +#endif + + case ZSTD_c_jobSize : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading"); + return 0; +#else + /* Adjust to the minimum non-default value. */ + if (value != 0 && value < ZSTDMT_JOBSIZE_MIN) + value = ZSTDMT_JOBSIZE_MIN; + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), ""); + assert(value >= 0); + CCtxParams->jobSize = (size_t)value; + return CCtxParams->jobSize; +#endif + + case ZSTD_c_overlapLog : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading"); + return 0; +#else + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), ""); + CCtxParams->overlapLog = value; + return (size_t)CCtxParams->overlapLog; +#endif + + case ZSTD_c_rsyncable : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR_IF(value!=0, parameter_unsupported, "not compiled with multithreading"); + return 0; +#else + FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value), ""); + CCtxParams->rsyncable = value; + return (size_t)CCtxParams->rsyncable; +#endif + + case ZSTD_c_enableDedicatedDictSearch : + CCtxParams->enableDedicatedDictSearch = (value!=0); + return (size_t)CCtxParams->enableDedicatedDictSearch; + + case ZSTD_c_enableLongDistanceMatching : + BOUNDCHECK(ZSTD_c_enableLongDistanceMatching, value); + CCtxParams->ldmParams.enableLdm = (ZSTD_ParamSwitch_e)value; + return CCtxParams->ldmParams.enableLdm; + + case ZSTD_c_ldmHashLog : + if (value!=0) /* 0 ==> auto */ + BOUNDCHECK(ZSTD_c_ldmHashLog, value); + CCtxParams->ldmParams.hashLog = (U32)value; + return CCtxParams->ldmParams.hashLog; + + case ZSTD_c_ldmMinMatch : + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_ldmMinMatch, value); + CCtxParams->ldmParams.minMatchLength = (U32)value; + return CCtxParams->ldmParams.minMatchLength; + + case ZSTD_c_ldmBucketSizeLog : + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_ldmBucketSizeLog, value); + CCtxParams->ldmParams.bucketSizeLog = (U32)value; + return CCtxParams->ldmParams.bucketSizeLog; + + case ZSTD_c_ldmHashRateLog : + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_ldmHashRateLog, value); + CCtxParams->ldmParams.hashRateLog = (U32)value; + return CCtxParams->ldmParams.hashRateLog; + + case ZSTD_c_targetCBlockSize : + if (value!=0) { /* 0 ==> default */ + value = MAX(value, ZSTD_TARGETCBLOCKSIZE_MIN); + BOUNDCHECK(ZSTD_c_targetCBlockSize, value); + } + CCtxParams->targetCBlockSize = (U32)value; + return CCtxParams->targetCBlockSize; + + case ZSTD_c_srcSizeHint : + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_srcSizeHint, value); + CCtxParams->srcSizeHint = value; + return (size_t)CCtxParams->srcSizeHint; + + case ZSTD_c_stableInBuffer: + BOUNDCHECK(ZSTD_c_stableInBuffer, value); + CCtxParams->inBufferMode = (ZSTD_bufferMode_e)value; + return CCtxParams->inBufferMode; + + case ZSTD_c_stableOutBuffer: + BOUNDCHECK(ZSTD_c_stableOutBuffer, value); + CCtxParams->outBufferMode = (ZSTD_bufferMode_e)value; + return CCtxParams->outBufferMode; + + case ZSTD_c_blockDelimiters: + BOUNDCHECK(ZSTD_c_blockDelimiters, value); + CCtxParams->blockDelimiters = (ZSTD_SequenceFormat_e)value; + return CCtxParams->blockDelimiters; + + case ZSTD_c_validateSequences: + BOUNDCHECK(ZSTD_c_validateSequences, value); + CCtxParams->validateSequences = value; + return (size_t)CCtxParams->validateSequences; + + case ZSTD_c_splitAfterSequences: + BOUNDCHECK(ZSTD_c_splitAfterSequences, value); + CCtxParams->postBlockSplitter = (ZSTD_ParamSwitch_e)value; + return CCtxParams->postBlockSplitter; + + case ZSTD_c_blockSplitterLevel: + BOUNDCHECK(ZSTD_c_blockSplitterLevel, value); + CCtxParams->preBlockSplitter_level = value; + return (size_t)CCtxParams->preBlockSplitter_level; + + case ZSTD_c_useRowMatchFinder: + BOUNDCHECK(ZSTD_c_useRowMatchFinder, value); + CCtxParams->useRowMatchFinder = (ZSTD_ParamSwitch_e)value; + return CCtxParams->useRowMatchFinder; + + case ZSTD_c_deterministicRefPrefix: + BOUNDCHECK(ZSTD_c_deterministicRefPrefix, value); + CCtxParams->deterministicRefPrefix = !!value; + return (size_t)CCtxParams->deterministicRefPrefix; + + case ZSTD_c_prefetchCDictTables: + BOUNDCHECK(ZSTD_c_prefetchCDictTables, value); + CCtxParams->prefetchCDictTables = (ZSTD_ParamSwitch_e)value; + return CCtxParams->prefetchCDictTables; + + case ZSTD_c_enableSeqProducerFallback: + BOUNDCHECK(ZSTD_c_enableSeqProducerFallback, value); + CCtxParams->enableMatchFinderFallback = value; + return (size_t)CCtxParams->enableMatchFinderFallback; + + case ZSTD_c_maxBlockSize: + if (value!=0) /* 0 ==> default */ + BOUNDCHECK(ZSTD_c_maxBlockSize, value); + assert(value>=0); + CCtxParams->maxBlockSize = (size_t)value; + return CCtxParams->maxBlockSize; + + case ZSTD_c_repcodeResolution: + BOUNDCHECK(ZSTD_c_repcodeResolution, value); + CCtxParams->searchForExternalRepcodes = (ZSTD_ParamSwitch_e)value; + return CCtxParams->searchForExternalRepcodes; + + default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); + } +} + +size_t ZSTD_CCtx_getParameter(ZSTD_CCtx const* cctx, ZSTD_cParameter param, int* value) +{ + return ZSTD_CCtxParams_getParameter(&cctx->requestedParams, param, value); +} + +size_t ZSTD_CCtxParams_getParameter( + ZSTD_CCtx_params const* CCtxParams, ZSTD_cParameter param, int* value) +{ + switch(param) + { + case ZSTD_c_format : + *value = (int)CCtxParams->format; + break; + case ZSTD_c_compressionLevel : + *value = CCtxParams->compressionLevel; + break; + case ZSTD_c_windowLog : + *value = (int)CCtxParams->cParams.windowLog; + break; + case ZSTD_c_hashLog : + *value = (int)CCtxParams->cParams.hashLog; + break; + case ZSTD_c_chainLog : + *value = (int)CCtxParams->cParams.chainLog; + break; + case ZSTD_c_searchLog : + *value = (int)CCtxParams->cParams.searchLog; + break; + case ZSTD_c_minMatch : + *value = (int)CCtxParams->cParams.minMatch; + break; + case ZSTD_c_targetLength : + *value = (int)CCtxParams->cParams.targetLength; + break; + case ZSTD_c_strategy : + *value = (int)CCtxParams->cParams.strategy; + break; + case ZSTD_c_contentSizeFlag : + *value = CCtxParams->fParams.contentSizeFlag; + break; + case ZSTD_c_checksumFlag : + *value = CCtxParams->fParams.checksumFlag; + break; + case ZSTD_c_dictIDFlag : + *value = !CCtxParams->fParams.noDictIDFlag; + break; + case ZSTD_c_forceMaxWindow : + *value = CCtxParams->forceWindow; + break; + case ZSTD_c_forceAttachDict : + *value = (int)CCtxParams->attachDictPref; + break; + case ZSTD_c_literalCompressionMode : + *value = (int)CCtxParams->literalCompressionMode; + break; + case ZSTD_c_nbWorkers : +#ifndef ZSTD_MULTITHREAD + assert(CCtxParams->nbWorkers == 0); +#endif + *value = CCtxParams->nbWorkers; + break; + case ZSTD_c_jobSize : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR(parameter_unsupported, "not compiled with multithreading"); +#else + assert(CCtxParams->jobSize <= INT_MAX); + *value = (int)CCtxParams->jobSize; + break; +#endif + case ZSTD_c_overlapLog : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR(parameter_unsupported, "not compiled with multithreading"); +#else + *value = CCtxParams->overlapLog; + break; +#endif + case ZSTD_c_rsyncable : +#ifndef ZSTD_MULTITHREAD + RETURN_ERROR(parameter_unsupported, "not compiled with multithreading"); +#else + *value = CCtxParams->rsyncable; + break; +#endif + case ZSTD_c_enableDedicatedDictSearch : + *value = CCtxParams->enableDedicatedDictSearch; + break; + case ZSTD_c_enableLongDistanceMatching : + *value = (int)CCtxParams->ldmParams.enableLdm; + break; + case ZSTD_c_ldmHashLog : + *value = (int)CCtxParams->ldmParams.hashLog; + break; + case ZSTD_c_ldmMinMatch : + *value = (int)CCtxParams->ldmParams.minMatchLength; + break; + case ZSTD_c_ldmBucketSizeLog : + *value = (int)CCtxParams->ldmParams.bucketSizeLog; + break; + case ZSTD_c_ldmHashRateLog : + *value = (int)CCtxParams->ldmParams.hashRateLog; + break; + case ZSTD_c_targetCBlockSize : + *value = (int)CCtxParams->targetCBlockSize; + break; + case ZSTD_c_srcSizeHint : + *value = (int)CCtxParams->srcSizeHint; + break; + case ZSTD_c_stableInBuffer : + *value = (int)CCtxParams->inBufferMode; + break; + case ZSTD_c_stableOutBuffer : + *value = (int)CCtxParams->outBufferMode; + break; + case ZSTD_c_blockDelimiters : + *value = (int)CCtxParams->blockDelimiters; + break; + case ZSTD_c_validateSequences : + *value = (int)CCtxParams->validateSequences; + break; + case ZSTD_c_splitAfterSequences : + *value = (int)CCtxParams->postBlockSplitter; + break; + case ZSTD_c_blockSplitterLevel : + *value = CCtxParams->preBlockSplitter_level; + break; + case ZSTD_c_useRowMatchFinder : + *value = (int)CCtxParams->useRowMatchFinder; + break; + case ZSTD_c_deterministicRefPrefix: + *value = (int)CCtxParams->deterministicRefPrefix; + break; + case ZSTD_c_prefetchCDictTables: + *value = (int)CCtxParams->prefetchCDictTables; + break; + case ZSTD_c_enableSeqProducerFallback: + *value = CCtxParams->enableMatchFinderFallback; + break; + case ZSTD_c_maxBlockSize: + *value = (int)CCtxParams->maxBlockSize; + break; + case ZSTD_c_repcodeResolution: + *value = (int)CCtxParams->searchForExternalRepcodes; + break; + default: RETURN_ERROR(parameter_unsupported, "unknown parameter"); + } + return 0; +} + +/** ZSTD_CCtx_setParametersUsingCCtxParams() : + * just applies `params` into `cctx` + * no action is performed, parameters are merely stored. + * If ZSTDMT is enabled, parameters are pushed to cctx->mtctx. + * This is possible even if a compression is ongoing. + * In which case, new parameters will be applied on the fly, starting with next compression job. + */ +size_t ZSTD_CCtx_setParametersUsingCCtxParams( + ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params) +{ + DEBUGLOG(4, "ZSTD_CCtx_setParametersUsingCCtxParams"); + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "The context is in the wrong stage!"); + RETURN_ERROR_IF(cctx->cdict, stage_wrong, + "Can't override parameters with cdict attached (some must " + "be inherited from the cdict)."); + + cctx->requestedParams = *params; + return 0; +} + +size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams) +{ + ZSTD_STATIC_ASSERT(sizeof(cparams) == 7 * 4 /* all params are listed below */); + DEBUGLOG(4, "ZSTD_CCtx_setCParams"); + /* only update if all parameters are valid */ + FORWARD_IF_ERROR(ZSTD_checkCParams(cparams), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, (int)cparams.windowLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, (int)cparams.chainLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, (int)cparams.hashLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, (int)cparams.searchLog), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, (int)cparams.minMatch), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, (int)cparams.targetLength), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, (int)cparams.strategy), ""); + return 0; +} + +size_t ZSTD_CCtx_setFParams(ZSTD_CCtx* cctx, ZSTD_frameParameters fparams) +{ + ZSTD_STATIC_ASSERT(sizeof(fparams) == 3 * 4 /* all params are listed below */); + DEBUGLOG(4, "ZSTD_CCtx_setFParams"); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_contentSizeFlag, fparams.contentSizeFlag != 0), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, fparams.checksumFlag != 0), ""); + FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, fparams.noDictIDFlag == 0), ""); + return 0; +} + +size_t ZSTD_CCtx_setParams(ZSTD_CCtx* cctx, ZSTD_parameters params) +{ + DEBUGLOG(4, "ZSTD_CCtx_setParams"); + /* First check cParams, because we want to update all or none. */ + FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), ""); + /* Next set fParams, because this could fail if the cctx isn't in init stage. */ + FORWARD_IF_ERROR(ZSTD_CCtx_setFParams(cctx, params.fParams), ""); + /* Finally set cParams, which should succeed. */ + FORWARD_IF_ERROR(ZSTD_CCtx_setCParams(cctx, params.cParams), ""); + return 0; +} + +size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize) +{ + DEBUGLOG(4, "ZSTD_CCtx_setPledgedSrcSize to %llu bytes", pledgedSrcSize); + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't set pledgedSrcSize when not in init stage."); + cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1; + return 0; +} + +static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams( + int const compressionLevel, + size_t const dictSize); +static int ZSTD_dedicatedDictSearch_isSupported( + const ZSTD_compressionParameters* cParams); +static void ZSTD_dedicatedDictSearch_revertCParams( + ZSTD_compressionParameters* cParams); + +size_t ZSTD_CCtx_loadDictionary_advanced( + ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) +{ + DEBUGLOG(4, "ZSTD_CCtx_loadDictionary_advanced (size: %u)", (U32)dictSize); + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't load a dictionary when cctx is not in init stage."); + ZSTD_clearAllDicts(cctx); /* erase any previously set dictionary */ + if (dict == NULL || dictSize == 0) /* no dictionary */ + return 0; + if (dictLoadMethod == ZSTD_dlm_byRef) { + cctx->localDict.dict = dict; + } else { + /* copy dictionary content inside CCtx to own its lifetime */ + void* dictBuffer; + RETURN_ERROR_IF(cctx->staticSize, memory_allocation, + "static CCtx can't allocate for an internal copy of dictionary"); + dictBuffer = ZSTD_customMalloc(dictSize, cctx->customMem); + RETURN_ERROR_IF(dictBuffer==NULL, memory_allocation, + "allocation failed for dictionary content"); + ZSTD_memcpy(dictBuffer, dict, dictSize); + cctx->localDict.dictBuffer = dictBuffer; /* owned ptr to free */ + cctx->localDict.dict = dictBuffer; /* read-only reference */ + } + cctx->localDict.dictSize = dictSize; + cctx->localDict.dictContentType = dictContentType; + return 0; +} + +size_t ZSTD_CCtx_loadDictionary_byReference( + ZSTD_CCtx* cctx, const void* dict, size_t dictSize) +{ + return ZSTD_CCtx_loadDictionary_advanced( + cctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto); +} + +size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize) +{ + return ZSTD_CCtx_loadDictionary_advanced( + cctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto); +} + +size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) +{ + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't ref a dict when ctx not in init stage."); + /* Free the existing local cdict (if any) to save memory. */ + ZSTD_clearAllDicts(cctx); + cctx->cdict = cdict; + return 0; +} + +size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool) +{ + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't ref a pool when ctx not in init stage."); + cctx->pool = pool; + return 0; +} + +size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize) +{ + return ZSTD_CCtx_refPrefix_advanced(cctx, prefix, prefixSize, ZSTD_dct_rawContent); +} + +size_t ZSTD_CCtx_refPrefix_advanced( + ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType) +{ + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Can't ref a prefix when ctx not in init stage."); + ZSTD_clearAllDicts(cctx); + if (prefix != NULL && prefixSize > 0) { + cctx->prefixDict.dict = prefix; + cctx->prefixDict.dictSize = prefixSize; + cctx->prefixDict.dictContentType = dictContentType; + } + return 0; +} + +/*! ZSTD_CCtx_reset() : + * Also dumps dictionary */ +size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset) +{ + if ( (reset == ZSTD_reset_session_only) + || (reset == ZSTD_reset_session_and_parameters) ) { + cctx->streamStage = zcss_init; + cctx->pledgedSrcSizePlusOne = 0; + } + if ( (reset == ZSTD_reset_parameters) + || (reset == ZSTD_reset_session_and_parameters) ) { + RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong, + "Reset parameters is only possible during init stage."); + ZSTD_clearAllDicts(cctx); + return ZSTD_CCtxParams_reset(&cctx->requestedParams); + } + return 0; +} + + +/** ZSTD_checkCParams() : + control CParam values remain within authorized range. + @return : 0, or an error code if one value is beyond authorized range */ +size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) +{ + BOUNDCHECK(ZSTD_c_windowLog, (int)cParams.windowLog); + BOUNDCHECK(ZSTD_c_chainLog, (int)cParams.chainLog); + BOUNDCHECK(ZSTD_c_hashLog, (int)cParams.hashLog); + BOUNDCHECK(ZSTD_c_searchLog, (int)cParams.searchLog); + BOUNDCHECK(ZSTD_c_minMatch, (int)cParams.minMatch); + BOUNDCHECK(ZSTD_c_targetLength,(int)cParams.targetLength); + BOUNDCHECK(ZSTD_c_strategy, (int)cParams.strategy); + return 0; +} + +/** ZSTD_clampCParams() : + * make CParam values within valid range. + * @return : valid CParams */ +static ZSTD_compressionParameters +ZSTD_clampCParams(ZSTD_compressionParameters cParams) +{ +# define CLAMP_TYPE(cParam, val, type) \ + do { \ + ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam); \ + if ((int)valbounds.upperBound) val=(type)bounds.upperBound; \ + } while (0) +# define CLAMP(cParam, val) CLAMP_TYPE(cParam, val, unsigned) + CLAMP(ZSTD_c_windowLog, cParams.windowLog); + CLAMP(ZSTD_c_chainLog, cParams.chainLog); + CLAMP(ZSTD_c_hashLog, cParams.hashLog); + CLAMP(ZSTD_c_searchLog, cParams.searchLog); + CLAMP(ZSTD_c_minMatch, cParams.minMatch); + CLAMP(ZSTD_c_targetLength,cParams.targetLength); + CLAMP_TYPE(ZSTD_c_strategy,cParams.strategy, ZSTD_strategy); + return cParams; +} + +/** ZSTD_cycleLog() : + * condition for correct operation : hashLog > 1 */ +U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat) +{ + U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2); + return hashLog - btScale; +} + +/** ZSTD_dictAndWindowLog() : + * Returns an adjusted window log that is large enough to fit the source and the dictionary. + * The zstd format says that the entire dictionary is valid if one byte of the dictionary + * is within the window. So the hashLog and chainLog should be large enough to reference both + * the dictionary and the window. So we must use this adjusted dictAndWindowLog when downsizing + * the hashLog and windowLog. + * NOTE: srcSize must not be ZSTD_CONTENTSIZE_UNKNOWN. + */ +static U32 ZSTD_dictAndWindowLog(U32 windowLog, U64 srcSize, U64 dictSize) +{ + const U64 maxWindowSize = 1ULL << ZSTD_WINDOWLOG_MAX; + /* No dictionary ==> No change */ + if (dictSize == 0) { + return windowLog; + } + assert(windowLog <= ZSTD_WINDOWLOG_MAX); + assert(srcSize != ZSTD_CONTENTSIZE_UNKNOWN); /* Handled in ZSTD_adjustCParams_internal() */ + { + U64 const windowSize = 1ULL << windowLog; + U64 const dictAndWindowSize = dictSize + windowSize; + /* If the window size is already large enough to fit both the source and the dictionary + * then just use the window size. Otherwise adjust so that it fits the dictionary and + * the window. + */ + if (windowSize >= dictSize + srcSize) { + return windowLog; /* Window size large enough already */ + } else if (dictAndWindowSize >= maxWindowSize) { + return ZSTD_WINDOWLOG_MAX; /* Larger than max window log */ + } else { + return ZSTD_highbit32((U32)dictAndWindowSize - 1) + 1; + } + } +} + +/** ZSTD_adjustCParams_internal() : + * optimize `cPar` for a specified input (`srcSize` and `dictSize`). + * mostly downsize to reduce memory consumption and initialization latency. + * `srcSize` can be ZSTD_CONTENTSIZE_UNKNOWN when not known. + * `mode` is the mode for parameter adjustment. See docs for `ZSTD_CParamMode_e`. + * note : `srcSize==0` means 0! + * condition : cPar is presumed validated (can be checked using ZSTD_checkCParams()). */ +static ZSTD_compressionParameters +ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar, + unsigned long long srcSize, + size_t dictSize, + ZSTD_CParamMode_e mode, + ZSTD_ParamSwitch_e useRowMatchFinder) +{ + const U64 minSrcSize = 513; /* (1<<9) + 1 */ + const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1); + assert(ZSTD_checkCParams(cPar)==0); + + /* Cascade the selected strategy down to the next-highest one built into + * this binary. */ +#ifdef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_btultra2) { + cPar.strategy = ZSTD_btultra; + } + if (cPar.strategy == ZSTD_btultra) { + cPar.strategy = ZSTD_btopt; + } +#endif +#ifdef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_btopt) { + cPar.strategy = ZSTD_btlazy2; + } +#endif +#ifdef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_btlazy2) { + cPar.strategy = ZSTD_lazy2; + } +#endif +#ifdef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_lazy2) { + cPar.strategy = ZSTD_lazy; + } +#endif +#ifdef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_lazy) { + cPar.strategy = ZSTD_greedy; + } +#endif +#ifdef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_greedy) { + cPar.strategy = ZSTD_dfast; + } +#endif +#ifdef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + if (cPar.strategy == ZSTD_dfast) { + cPar.strategy = ZSTD_fast; + cPar.targetLength = 0; + } +#endif + + switch (mode) { + case ZSTD_cpm_unknown: + case ZSTD_cpm_noAttachDict: + /* If we don't know the source size, don't make any + * assumptions about it. We will already have selected + * smaller parameters if a dictionary is in use. + */ + break; + case ZSTD_cpm_createCDict: + /* Assume a small source size when creating a dictionary + * with an unknown source size. + */ + if (dictSize && srcSize == ZSTD_CONTENTSIZE_UNKNOWN) + srcSize = minSrcSize; + break; + case ZSTD_cpm_attachDict: + /* Dictionary has its own dedicated parameters which have + * already been selected. We are selecting parameters + * for only the source. + */ + dictSize = 0; + break; + default: + assert(0); + break; + } + + /* resize windowLog if input is small enough, to use less memory */ + if ( (srcSize <= maxWindowResize) + && (dictSize <= maxWindowResize) ) { + U32 const tSize = (U32)(srcSize + dictSize); + static U32 const hashSizeMin = 1 << ZSTD_HASHLOG_MIN; + U32 const srcLog = (tSize < hashSizeMin) ? ZSTD_HASHLOG_MIN : + ZSTD_highbit32(tSize-1) + 1; + if (cPar.windowLog > srcLog) cPar.windowLog = srcLog; + } + if (srcSize != ZSTD_CONTENTSIZE_UNKNOWN) { + U32 const dictAndWindowLog = ZSTD_dictAndWindowLog(cPar.windowLog, (U64)srcSize, (U64)dictSize); + U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy); + if (cPar.hashLog > dictAndWindowLog+1) cPar.hashLog = dictAndWindowLog+1; + if (cycleLog > dictAndWindowLog) + cPar.chainLog -= (cycleLog - dictAndWindowLog); + } + + if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) + cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* minimum wlog required for valid frame header */ + + /* We can't use more than 32 bits of hash in total, so that means that we require: + * (hashLog + 8) <= 32 && (chainLog + 8) <= 32 + */ + if (mode == ZSTD_cpm_createCDict && ZSTD_CDictIndicesAreTagged(&cPar)) { + U32 const maxShortCacheHashLog = 32 - ZSTD_SHORT_CACHE_TAG_BITS; + if (cPar.hashLog > maxShortCacheHashLog) { + cPar.hashLog = maxShortCacheHashLog; + } + if (cPar.chainLog > maxShortCacheHashLog) { + cPar.chainLog = maxShortCacheHashLog; + } + } + + + /* At this point, we aren't 100% sure if we are using the row match finder. + * Unless it is explicitly disabled, conservatively assume that it is enabled. + * In this case it will only be disabled for small sources, so shrinking the + * hash log a little bit shouldn't result in any ratio loss. + */ + if (useRowMatchFinder == ZSTD_ps_auto) + useRowMatchFinder = ZSTD_ps_enable; + + /* We can't hash more than 32-bits in total. So that means that we require: + * (hashLog - rowLog + 8) <= 32 + */ + if (ZSTD_rowMatchFinderUsed(cPar.strategy, useRowMatchFinder)) { + /* Switch to 32-entry rows if searchLog is 5 (or more) */ + U32 const rowLog = BOUNDED(4, cPar.searchLog, 6); + U32 const maxRowHashLog = 32 - ZSTD_ROW_HASH_TAG_BITS; + U32 const maxHashLog = maxRowHashLog + rowLog; + assert(cPar.hashLog >= rowLog); + if (cPar.hashLog > maxHashLog) { + cPar.hashLog = maxHashLog; + } + } + + return cPar; +} + +ZSTD_compressionParameters +ZSTD_adjustCParams(ZSTD_compressionParameters cPar, + unsigned long long srcSize, + size_t dictSize) +{ + cPar = ZSTD_clampCParams(cPar); /* resulting cPar is necessarily valid (all parameters within range) */ + if (srcSize == 0) srcSize = ZSTD_CONTENTSIZE_UNKNOWN; + return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize, ZSTD_cpm_unknown, ZSTD_ps_auto); +} + +static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode); +static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode); + +static void ZSTD_overrideCParams( + ZSTD_compressionParameters* cParams, + const ZSTD_compressionParameters* overrides) +{ + if (overrides->windowLog) cParams->windowLog = overrides->windowLog; + if (overrides->hashLog) cParams->hashLog = overrides->hashLog; + if (overrides->chainLog) cParams->chainLog = overrides->chainLog; + if (overrides->searchLog) cParams->searchLog = overrides->searchLog; + if (overrides->minMatch) cParams->minMatch = overrides->minMatch; + if (overrides->targetLength) cParams->targetLength = overrides->targetLength; + if (overrides->strategy) cParams->strategy = overrides->strategy; +} + +ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( + const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) +{ + ZSTD_compressionParameters cParams; + if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) { + assert(CCtxParams->srcSizeHint>=0); + srcSizeHint = (U64)CCtxParams->srcSizeHint; + } + cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize, mode); + if (CCtxParams->ldmParams.enableLdm == ZSTD_ps_enable) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG; + ZSTD_overrideCParams(&cParams, &CCtxParams->cParams); + assert(!ZSTD_checkCParams(cParams)); + /* srcSizeHint == 0 means 0 */ + return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize, mode, CCtxParams->useRowMatchFinder); +} + +static size_t +ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams, + const ZSTD_ParamSwitch_e useRowMatchFinder, + const int enableDedicatedDictSearch, + const U32 forCCtx) +{ + /* chain table size should be 0 for fast or row-hash strategies */ + size_t const chainSize = ZSTD_allocateChainTable(cParams->strategy, useRowMatchFinder, enableDedicatedDictSearch && !forCCtx) + ? ((size_t)1 << cParams->chainLog) + : 0; + size_t const hSize = ((size_t)1) << cParams->hashLog; + U32 const hashLog3 = (forCCtx && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0; + size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0; + /* We don't use ZSTD_cwksp_alloc_size() here because the tables aren't + * surrounded by redzones in ASAN. */ + size_t const tableSpace = chainSize * sizeof(U32) + + hSize * sizeof(U32) + + h3Size * sizeof(U32); + size_t const optPotentialSpace = + ZSTD_cwksp_aligned64_alloc_size((MaxML+1) * sizeof(U32)) + + ZSTD_cwksp_aligned64_alloc_size((MaxLL+1) * sizeof(U32)) + + ZSTD_cwksp_aligned64_alloc_size((MaxOff+1) * sizeof(U32)) + + ZSTD_cwksp_aligned64_alloc_size((1<strategy, useRowMatchFinder) + ? ZSTD_cwksp_aligned64_alloc_size(hSize) + : 0; + size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt)) + ? optPotentialSpace + : 0; + size_t const slackSpace = ZSTD_cwksp_slack_space_required(); + + /* tables are guaranteed to be sized in multiples of 64 bytes (or 16 uint32_t) */ + ZSTD_STATIC_ASSERT(ZSTD_HASHLOG_MIN >= 4 && ZSTD_WINDOWLOG_MIN >= 4 && ZSTD_CHAINLOG_MIN >= 4); + assert(useRowMatchFinder != ZSTD_ps_auto); + + DEBUGLOG(4, "chainSize: %u - hSize: %u - h3Size: %u", + (U32)chainSize, (U32)hSize, (U32)h3Size); + return tableSpace + optSpace + slackSpace + lazyAdditionalSpace; +} + +/* Helper function for calculating memory requirements. + * Gives a tighter bound than ZSTD_sequenceBound() by taking minMatch into account. */ +static size_t ZSTD_maxNbSeq(size_t blockSize, unsigned minMatch, int useSequenceProducer) { + U32 const divider = (minMatch==3 || useSequenceProducer) ? 3 : 4; + return blockSize / divider; +} + +static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( + const ZSTD_compressionParameters* cParams, + const ldmParams_t* ldmParams, + const int isStatic, + const ZSTD_ParamSwitch_e useRowMatchFinder, + const size_t buffInSize, + const size_t buffOutSize, + const U64 pledgedSrcSize, + int useSequenceProducer, + size_t maxBlockSize) +{ + size_t const windowSize = (size_t) BOUNDED(1ULL, 1ULL << cParams->windowLog, pledgedSrcSize); + size_t const blockSize = MIN(ZSTD_resolveMaxBlockSize(maxBlockSize), windowSize); + size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, cParams->minMatch, useSequenceProducer); + size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize) + + ZSTD_cwksp_aligned64_alloc_size(maxNbSeq * sizeof(SeqDef)) + + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE)); + size_t const tmpWorkSpace = ZSTD_cwksp_alloc_size(TMP_WORKSPACE_SIZE); + size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t)); + size_t const matchStateSize = ZSTD_sizeof_matchState(cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 0, /* forCCtx */ 1); + + size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams); + size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize); + size_t const ldmSeqSpace = ldmParams->enableLdm == ZSTD_ps_enable ? + ZSTD_cwksp_aligned64_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0; + + + size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize) + + ZSTD_cwksp_alloc_size(buffOutSize); + + size_t const cctxSpace = isStatic ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0; + + size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize); + size_t const externalSeqSpace = useSequenceProducer + ? ZSTD_cwksp_aligned64_alloc_size(maxNbExternalSeq * sizeof(ZSTD_Sequence)) + : 0; + + size_t const neededSpace = + cctxSpace + + tmpWorkSpace + + blockStateSpace + + ldmSpace + + ldmSeqSpace + + matchStateSize + + tokenSpace + + bufferSpace + + externalSeqSpace; + + DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace); + return neededSpace; +} + +size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params) +{ + ZSTD_compressionParameters const cParams = + ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict); + ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, + &cParams); + + RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only."); + /* estimateCCtxSize is for one-shot compression. So no buffers should + * be needed. However, we still allocate two 0-sized buffers, which can + * take space under ASAN. */ + return ZSTD_estimateCCtxSize_usingCCtxParams_internal( + &cParams, ¶ms->ldmParams, 1, useRowMatchFinder, 0, 0, ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_hasExtSeqProd(params), params->maxBlockSize); +} + +size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams) +{ + ZSTD_CCtx_params initialParams = ZSTD_makeCCtxParamsFromCParams(cParams); + if (ZSTD_rowMatchFinderSupported(cParams.strategy)) { + /* Pick bigger of not using and using row-based matchfinder for greedy and lazy strategies */ + size_t noRowCCtxSize; + size_t rowCCtxSize; + initialParams.useRowMatchFinder = ZSTD_ps_disable; + noRowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams); + initialParams.useRowMatchFinder = ZSTD_ps_enable; + rowCCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams); + return MAX(noRowCCtxSize, rowCCtxSize); + } else { + return ZSTD_estimateCCtxSize_usingCCtxParams(&initialParams); + } +} + +static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel) +{ + int tier = 0; + size_t largestSize = 0; + static const unsigned long long srcSizeTiers[4] = {16 KB, 128 KB, 256 KB, ZSTD_CONTENTSIZE_UNKNOWN}; + for (; tier < 4; ++tier) { + /* Choose the set of cParams for a given level across all srcSizes that give the largest cctxSize */ + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeTiers[tier], 0, ZSTD_cpm_noAttachDict); + largestSize = MAX(ZSTD_estimateCCtxSize_usingCParams(cParams), largestSize); + } + return largestSize; +} + +size_t ZSTD_estimateCCtxSize(int compressionLevel) +{ + int level; + size_t memBudget = 0; + for (level=MIN(compressionLevel, 1); level<=compressionLevel; level++) { + /* Ensure monotonically increasing memory usage as compression level increases */ + size_t const newMB = ZSTD_estimateCCtxSize_internal(level); + if (newMB > memBudget) memBudget = newMB; + } + return memBudget; +} + +static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1, + ZSTD_compressionParameters cParams2) +{ + (void)cParams1; + (void)cParams2; + assert(cParams1.windowLog == cParams2.windowLog); + assert(cParams1.chainLog == cParams2.chainLog); + assert(cParams1.hashLog == cParams2.hashLog); + assert(cParams1.searchLog == cParams2.searchLog); + assert(cParams1.minMatch == cParams2.minMatch); + assert(cParams1.targetLength == cParams2.targetLength); + assert(cParams1.strategy == cParams2.strategy); +} + +void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs) +{ + int i; + for (i = 0; i < ZSTD_REP_NUM; ++i) + bs->rep[i] = repStartValue[i]; + bs->entropy.huf.repeatMode = HUF_repeat_none; + bs->entropy.fse.offcode_repeatMode = FSE_repeat_none; + bs->entropy.fse.matchlength_repeatMode = FSE_repeat_none; + bs->entropy.fse.litlength_repeatMode = FSE_repeat_none; +} + +/*! ZSTD_invalidateMatchState() + * Invalidate all the matches in the match finder tables. + * Requires nextSrc and base to be set (can be NULL). + */ +static void ZSTD_invalidateMatchState(ZSTD_MatchState_t* ms) +{ + ZSTD_window_clear(&ms->window); + + ms->nextToUpdate = ms->window.dictLimit; + ms->loadedDictEnd = 0; + ms->opt.litLengthSum = 0; /* force reset of btopt stats */ + ms->dictMatchState = NULL; +} + +/** + * Controls, for this matchState reset, whether the tables need to be cleared / + * prepared for the coming compression (ZSTDcrp_makeClean), or whether the + * tables can be left unclean (ZSTDcrp_leaveDirty), because we know that a + * subsequent operation will overwrite the table space anyways (e.g., copying + * the matchState contents in from a CDict). + */ +typedef enum { + ZSTDcrp_makeClean, + ZSTDcrp_leaveDirty +} ZSTD_compResetPolicy_e; + +/** + * Controls, for this matchState reset, whether indexing can continue where it + * left off (ZSTDirp_continue), or whether it needs to be restarted from zero + * (ZSTDirp_reset). + */ +typedef enum { + ZSTDirp_continue, + ZSTDirp_reset +} ZSTD_indexResetPolicy_e; + +typedef enum { + ZSTD_resetTarget_CDict, + ZSTD_resetTarget_CCtx +} ZSTD_resetTarget_e; + +/* Mixes bits in a 64 bits in a value, based on XXH3_rrmxmx */ +static U64 ZSTD_bitmix(U64 val, U64 len) { + val ^= ZSTD_rotateRight_U64(val, 49) ^ ZSTD_rotateRight_U64(val, 24); + val *= 0x9FB21C651E98DF25ULL; + val ^= (val >> 35) + len ; + val *= 0x9FB21C651E98DF25ULL; + return val ^ (val >> 28); +} + +/* Mixes in the hashSalt and hashSaltEntropy to create a new hashSalt */ +static void ZSTD_advanceHashSalt(ZSTD_MatchState_t* ms) { + ms->hashSalt = ZSTD_bitmix(ms->hashSalt, 8) ^ ZSTD_bitmix((U64) ms->hashSaltEntropy, 4); +} + +static size_t +ZSTD_reset_matchState(ZSTD_MatchState_t* ms, + ZSTD_cwksp* ws, + const ZSTD_compressionParameters* cParams, + const ZSTD_ParamSwitch_e useRowMatchFinder, + const ZSTD_compResetPolicy_e crp, + const ZSTD_indexResetPolicy_e forceResetIndex, + const ZSTD_resetTarget_e forWho) +{ + /* disable chain table allocation for fast or row-based strategies */ + size_t const chainSize = ZSTD_allocateChainTable(cParams->strategy, useRowMatchFinder, + ms->dedicatedDictSearch && (forWho == ZSTD_resetTarget_CDict)) + ? ((size_t)1 << cParams->chainLog) + : 0; + size_t const hSize = ((size_t)1) << cParams->hashLog; + U32 const hashLog3 = ((forWho == ZSTD_resetTarget_CCtx) && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0; + size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0; + + DEBUGLOG(4, "reset indices : %u", forceResetIndex == ZSTDirp_reset); + assert(useRowMatchFinder != ZSTD_ps_auto); + if (forceResetIndex == ZSTDirp_reset) { + ZSTD_window_init(&ms->window); + ZSTD_cwksp_mark_tables_dirty(ws); + } + + ms->hashLog3 = hashLog3; + ms->lazySkipping = 0; + + ZSTD_invalidateMatchState(ms); + + assert(!ZSTD_cwksp_reserve_failed(ws)); /* check that allocation hasn't already failed */ + + ZSTD_cwksp_clear_tables(ws); + + DEBUGLOG(5, "reserving table space"); + /* table Space */ + ms->hashTable = (U32*)ZSTD_cwksp_reserve_table(ws, hSize * sizeof(U32)); + ms->chainTable = (U32*)ZSTD_cwksp_reserve_table(ws, chainSize * sizeof(U32)); + ms->hashTable3 = (U32*)ZSTD_cwksp_reserve_table(ws, h3Size * sizeof(U32)); + RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation, + "failed a workspace allocation in ZSTD_reset_matchState"); + + DEBUGLOG(4, "reset table : %u", crp!=ZSTDcrp_leaveDirty); + if (crp!=ZSTDcrp_leaveDirty) { + /* reset tables only */ + ZSTD_cwksp_clean_tables(ws); + } + + if (ZSTD_rowMatchFinderUsed(cParams->strategy, useRowMatchFinder)) { + /* Row match finder needs an additional table of hashes ("tags") */ + size_t const tagTableSize = hSize; + /* We want to generate a new salt in case we reset a Cctx, but we always want to use + * 0 when we reset a Cdict */ + if(forWho == ZSTD_resetTarget_CCtx) { + ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned_init_once(ws, tagTableSize); + ZSTD_advanceHashSalt(ms); + } else { + /* When we are not salting we want to always memset the memory */ + ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned64(ws, tagTableSize); + ZSTD_memset(ms->tagTable, 0, tagTableSize); + ms->hashSalt = 0; + } + { /* Switch to 32-entry rows if searchLog is 5 (or more) */ + U32 const rowLog = BOUNDED(4, cParams->searchLog, 6); + assert(cParams->hashLog >= rowLog); + ms->rowHashLog = cParams->hashLog - rowLog; + } + } + + /* opt parser space */ + if ((forWho == ZSTD_resetTarget_CCtx) && (cParams->strategy >= ZSTD_btopt)) { + DEBUGLOG(4, "reserving optimal parser space"); + ms->opt.litFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (1<opt.litLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxLL+1) * sizeof(unsigned)); + ms->opt.matchLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxML+1) * sizeof(unsigned)); + ms->opt.offCodeFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxOff+1) * sizeof(unsigned)); + ms->opt.matchTable = (ZSTD_match_t*)ZSTD_cwksp_reserve_aligned64(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_match_t)); + ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned64(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_optimal_t)); + } + + ms->cParams = *cParams; + + RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation, + "failed a workspace allocation in ZSTD_reset_matchState"); + return 0; +} + +/* ZSTD_indexTooCloseToMax() : + * minor optimization : prefer memset() rather than reduceIndex() + * which is measurably slow in some circumstances (reported for Visual Studio). + * Works when re-using a context for a lot of smallish inputs : + * if all inputs are smaller than ZSTD_INDEXOVERFLOW_MARGIN, + * memset() will be triggered before reduceIndex(). + */ +#define ZSTD_INDEXOVERFLOW_MARGIN (16 MB) +static int ZSTD_indexTooCloseToMax(ZSTD_window_t w) +{ + return (size_t)(w.nextSrc - w.base) > (ZSTD_CURRENT_MAX - ZSTD_INDEXOVERFLOW_MARGIN); +} + +/** ZSTD_dictTooBig(): + * When dictionaries are larger than ZSTD_CHUNKSIZE_MAX they can't be loaded in + * one go generically. So we ensure that in that case we reset the tables to zero, + * so that we can load as much of the dictionary as possible. + */ +static int ZSTD_dictTooBig(size_t const loadedDictSize) +{ + return loadedDictSize > ZSTD_CHUNKSIZE_MAX; +} + +/*! ZSTD_resetCCtx_internal() : + * @param loadedDictSize The size of the dictionary to be loaded + * into the context, if any. If no dictionary is used, or the + * dictionary is being attached / copied, then pass 0. + * note : `params` are assumed fully validated at this stage. + */ +static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, + ZSTD_CCtx_params const* params, + U64 const pledgedSrcSize, + size_t const loadedDictSize, + ZSTD_compResetPolicy_e const crp, + ZSTD_buffered_policy_e const zbuff) +{ + ZSTD_cwksp* const ws = &zc->workspace; + DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u, useRowMatchFinder=%d useBlockSplitter=%d", + (U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder, (int)params->postBlockSplitter); + assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams))); + + zc->isFirstBlock = 1; + + /* Set applied params early so we can modify them for LDM, + * and point params at the applied params. + */ + zc->appliedParams = *params; + params = &zc->appliedParams; + + assert(params->useRowMatchFinder != ZSTD_ps_auto); + assert(params->postBlockSplitter != ZSTD_ps_auto); + assert(params->ldmParams.enableLdm != ZSTD_ps_auto); + assert(params->maxBlockSize != 0); + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { + /* Adjust long distance matching parameters */ + ZSTD_ldm_adjustParameters(&zc->appliedParams.ldmParams, ¶ms->cParams); + assert(params->ldmParams.hashLog >= params->ldmParams.bucketSizeLog); + assert(params->ldmParams.hashRateLog < 32); + } + + { size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params->cParams.windowLog), pledgedSrcSize)); + size_t const blockSize = MIN(params->maxBlockSize, windowSize); + size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, params->cParams.minMatch, ZSTD_hasExtSeqProd(params)); + size_t const buffOutSize = (zbuff == ZSTDb_buffered && params->outBufferMode == ZSTD_bm_buffered) + ? ZSTD_compressBound(blockSize) + 1 + : 0; + size_t const buffInSize = (zbuff == ZSTDb_buffered && params->inBufferMode == ZSTD_bm_buffered) + ? windowSize + blockSize + : 0; + size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params->ldmParams, blockSize); + + int const indexTooClose = ZSTD_indexTooCloseToMax(zc->blockState.matchState.window); + int const dictTooBig = ZSTD_dictTooBig(loadedDictSize); + ZSTD_indexResetPolicy_e needsIndexReset = + (indexTooClose || dictTooBig || !zc->initialized) ? ZSTDirp_reset : ZSTDirp_continue; + + size_t const neededSpace = + ZSTD_estimateCCtxSize_usingCCtxParams_internal( + ¶ms->cParams, ¶ms->ldmParams, zc->staticSize != 0, params->useRowMatchFinder, + buffInSize, buffOutSize, pledgedSrcSize, ZSTD_hasExtSeqProd(params), params->maxBlockSize); + + FORWARD_IF_ERROR(neededSpace, "cctx size estimate failed!"); + + if (!zc->staticSize) ZSTD_cwksp_bump_oversized_duration(ws, 0); + + { /* Check if workspace is large enough, alloc a new one if needed */ + int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace; + int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace); + int resizeWorkspace = workspaceTooSmall || workspaceWasteful; + DEBUGLOG(4, "Need %zu B workspace", neededSpace); + DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize); + + if (resizeWorkspace) { + DEBUGLOG(4, "Resize workspaceSize from %zuKB to %zuKB", + ZSTD_cwksp_sizeof(ws) >> 10, + neededSpace >> 10); + + RETURN_ERROR_IF(zc->staticSize, memory_allocation, "static cctx : no resize"); + + needsIndexReset = ZSTDirp_reset; + + ZSTD_cwksp_free(ws, zc->customMem); + FORWARD_IF_ERROR(ZSTD_cwksp_create(ws, neededSpace, zc->customMem), ""); + + DEBUGLOG(5, "reserving object space"); + /* Statically sized space. + * tmpWorkspace never moves, + * though prev/next block swap places */ + assert(ZSTD_cwksp_check_available(ws, 2 * sizeof(ZSTD_compressedBlockState_t))); + zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t)); + RETURN_ERROR_IF(zc->blockState.prevCBlock == NULL, memory_allocation, "couldn't allocate prevCBlock"); + zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t)); + RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock"); + zc->tmpWorkspace = ZSTD_cwksp_reserve_object(ws, TMP_WORKSPACE_SIZE); + RETURN_ERROR_IF(zc->tmpWorkspace == NULL, memory_allocation, "couldn't allocate tmpWorkspace"); + zc->tmpWkspSize = TMP_WORKSPACE_SIZE; + } } + + ZSTD_cwksp_clear(ws); + + /* init params */ + zc->blockState.matchState.cParams = params->cParams; + zc->blockState.matchState.prefetchCDictTables = params->prefetchCDictTables == ZSTD_ps_enable; + zc->pledgedSrcSizePlusOne = pledgedSrcSize+1; + zc->consumedSrcSize = 0; + zc->producedCSize = 0; + if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN) + zc->appliedParams.fParams.contentSizeFlag = 0; + DEBUGLOG(4, "pledged content size : %u ; flag : %u", + (unsigned)pledgedSrcSize, zc->appliedParams.fParams.contentSizeFlag); + zc->blockSizeMax = blockSize; + + XXH64_reset(&zc->xxhState, 0); + zc->stage = ZSTDcs_init; + zc->dictID = 0; + zc->dictContentSize = 0; + + ZSTD_reset_compressedBlockState(zc->blockState.prevCBlock); + + FORWARD_IF_ERROR(ZSTD_reset_matchState( + &zc->blockState.matchState, + ws, + ¶ms->cParams, + params->useRowMatchFinder, + crp, + needsIndexReset, + ZSTD_resetTarget_CCtx), ""); + + zc->seqStore.sequencesStart = (SeqDef*)ZSTD_cwksp_reserve_aligned64(ws, maxNbSeq * sizeof(SeqDef)); + + /* ldm hash table */ + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { + /* TODO: avoid memset? */ + size_t const ldmHSize = ((size_t)1) << params->ldmParams.hashLog; + zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned64(ws, ldmHSize * sizeof(ldmEntry_t)); + ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t)); + zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned64(ws, maxNbLdmSeq * sizeof(rawSeq)); + zc->maxNbLdmSequences = maxNbLdmSeq; + + ZSTD_window_init(&zc->ldmState.window); + zc->ldmState.loadedDictEnd = 0; + } + + /* reserve space for block-level external sequences */ + if (ZSTD_hasExtSeqProd(params)) { + size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize); + zc->extSeqBufCapacity = maxNbExternalSeq; + zc->extSeqBuf = + (ZSTD_Sequence*)ZSTD_cwksp_reserve_aligned64(ws, maxNbExternalSeq * sizeof(ZSTD_Sequence)); + } + + /* buffers */ + + /* ZSTD_wildcopy() is used to copy into the literals buffer, + * so we have to oversize the buffer by WILDCOPY_OVERLENGTH bytes. + */ + zc->seqStore.litStart = ZSTD_cwksp_reserve_buffer(ws, blockSize + WILDCOPY_OVERLENGTH); + zc->seqStore.maxNbLit = blockSize; + + zc->bufferedPolicy = zbuff; + zc->inBuffSize = buffInSize; + zc->inBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffInSize); + zc->outBuffSize = buffOutSize; + zc->outBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffOutSize); + + /* ldm bucketOffsets table */ + if (params->ldmParams.enableLdm == ZSTD_ps_enable) { + /* TODO: avoid memset? */ + size_t const numBuckets = + ((size_t)1) << (params->ldmParams.hashLog - + params->ldmParams.bucketSizeLog); + zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, numBuckets); + ZSTD_memset(zc->ldmState.bucketOffsets, 0, numBuckets); + } + + /* sequences storage */ + ZSTD_referenceExternalSequences(zc, NULL, 0); + zc->seqStore.maxNbSeq = maxNbSeq; + zc->seqStore.llCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE)); + zc->seqStore.mlCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE)); + zc->seqStore.ofCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE)); + + DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws)); + assert(ZSTD_cwksp_estimated_space_within_bounds(ws, neededSpace)); + + zc->initialized = 1; + + return 0; + } +} + +/* ZSTD_invalidateRepCodes() : + * ensures next compression will not use repcodes from previous block. + * Note : only works with regular variant; + * do not use with extDict variant ! */ +void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) { + int i; + for (i=0; iblockState.prevCBlock->rep[i] = 0; + assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window)); +} + +/* These are the approximate sizes for each strategy past which copying the + * dictionary tables into the working context is faster than using them + * in-place. + */ +static const size_t attachDictSizeCutoffs[ZSTD_STRATEGY_MAX+1] = { + 8 KB, /* unused */ + 8 KB, /* ZSTD_fast */ + 16 KB, /* ZSTD_dfast */ + 32 KB, /* ZSTD_greedy */ + 32 KB, /* ZSTD_lazy */ + 32 KB, /* ZSTD_lazy2 */ + 32 KB, /* ZSTD_btlazy2 */ + 32 KB, /* ZSTD_btopt */ + 8 KB, /* ZSTD_btultra */ + 8 KB /* ZSTD_btultra2 */ +}; + +static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, + U64 pledgedSrcSize) +{ + size_t cutoff = attachDictSizeCutoffs[cdict->matchState.cParams.strategy]; + int const dedicatedDictSearch = cdict->matchState.dedicatedDictSearch; + return dedicatedDictSearch + || ( ( pledgedSrcSize <= cutoff + || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN + || params->attachDictPref == ZSTD_dictForceAttach ) + && params->attachDictPref != ZSTD_dictForceCopy + && !params->forceWindow ); /* dictMatchState isn't correctly + * handled in _enforceMaxDist */ +} + +static size_t +ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx, + const ZSTD_CDict* cdict, + ZSTD_CCtx_params params, + U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + DEBUGLOG(4, "ZSTD_resetCCtx_byAttachingCDict() pledgedSrcSize=%llu", + (unsigned long long)pledgedSrcSize); + { + ZSTD_compressionParameters adjusted_cdict_cParams = cdict->matchState.cParams; + unsigned const windowLog = params.cParams.windowLog; + assert(windowLog != 0); + /* Resize working context table params for input only, since the dict + * has its own tables. */ + /* pledgedSrcSize == 0 means 0! */ + + if (cdict->matchState.dedicatedDictSearch) { + ZSTD_dedicatedDictSearch_revertCParams(&adjusted_cdict_cParams); + } + + params.cParams = ZSTD_adjustCParams_internal(adjusted_cdict_cParams, pledgedSrcSize, + cdict->dictContentSize, ZSTD_cpm_attachDict, + params.useRowMatchFinder); + params.cParams.windowLog = windowLog; + params.useRowMatchFinder = cdict->useRowMatchFinder; /* cdict overrides */ + FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, ¶ms, pledgedSrcSize, + /* loadedDictSize */ 0, + ZSTDcrp_makeClean, zbuff), ""); + assert(cctx->appliedParams.cParams.strategy == adjusted_cdict_cParams.strategy); + } + + { const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc + - cdict->matchState.window.base); + const U32 cdictLen = cdictEnd - cdict->matchState.window.dictLimit; + if (cdictLen == 0) { + /* don't even attach dictionaries with no contents */ + DEBUGLOG(4, "skipping attaching empty dictionary"); + } else { + DEBUGLOG(4, "attaching dictionary into context"); + cctx->blockState.matchState.dictMatchState = &cdict->matchState; + + /* prep working match state so dict matches never have negative indices + * when they are translated to the working context's index space. */ + if (cctx->blockState.matchState.window.dictLimit < cdictEnd) { + cctx->blockState.matchState.window.nextSrc = + cctx->blockState.matchState.window.base + cdictEnd; + ZSTD_window_clear(&cctx->blockState.matchState.window); + } + /* loadedDictEnd is expressed within the referential of the active context */ + cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit; + } } + + cctx->dictID = cdict->dictID; + cctx->dictContentSize = cdict->dictContentSize; + + /* copy block state */ + ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState)); + + return 0; +} + +static void ZSTD_copyCDictTableIntoCCtx(U32* dst, U32 const* src, size_t tableSize, + ZSTD_compressionParameters const* cParams) { + if (ZSTD_CDictIndicesAreTagged(cParams)){ + /* Remove tags from the CDict table if they are present. + * See docs on "short cache" in zstd_compress_internal.h for context. */ + size_t i; + for (i = 0; i < tableSize; i++) { + U32 const taggedIndex = src[i]; + U32 const index = taggedIndex >> ZSTD_SHORT_CACHE_TAG_BITS; + dst[i] = index; + } + } else { + ZSTD_memcpy(dst, src, tableSize * sizeof(U32)); + } +} + +static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, + const ZSTD_CDict* cdict, + ZSTD_CCtx_params params, + U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams; + + assert(!cdict->matchState.dedicatedDictSearch); + DEBUGLOG(4, "ZSTD_resetCCtx_byCopyingCDict() pledgedSrcSize=%llu", + (unsigned long long)pledgedSrcSize); + + { unsigned const windowLog = params.cParams.windowLog; + assert(windowLog != 0); + /* Copy only compression parameters related to tables. */ + params.cParams = *cdict_cParams; + params.cParams.windowLog = windowLog; + params.useRowMatchFinder = cdict->useRowMatchFinder; + FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, ¶ms, pledgedSrcSize, + /* loadedDictSize */ 0, + ZSTDcrp_leaveDirty, zbuff), ""); + assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy); + assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog); + assert(cctx->appliedParams.cParams.chainLog == cdict_cParams->chainLog); + } + + ZSTD_cwksp_mark_tables_dirty(&cctx->workspace); + assert(params.useRowMatchFinder != ZSTD_ps_auto); + + /* copy tables */ + { size_t const chainSize = ZSTD_allocateChainTable(cdict_cParams->strategy, cdict->useRowMatchFinder, 0 /* DDS guaranteed disabled */) + ? ((size_t)1 << cdict_cParams->chainLog) + : 0; + size_t const hSize = (size_t)1 << cdict_cParams->hashLog; + + ZSTD_copyCDictTableIntoCCtx(cctx->blockState.matchState.hashTable, + cdict->matchState.hashTable, + hSize, cdict_cParams); + + /* Do not copy cdict's chainTable if cctx has parameters such that it would not use chainTable */ + if (ZSTD_allocateChainTable(cctx->appliedParams.cParams.strategy, cctx->appliedParams.useRowMatchFinder, 0 /* forDDSDict */)) { + ZSTD_copyCDictTableIntoCCtx(cctx->blockState.matchState.chainTable, + cdict->matchState.chainTable, + chainSize, cdict_cParams); + } + /* copy tag table */ + if (ZSTD_rowMatchFinderUsed(cdict_cParams->strategy, cdict->useRowMatchFinder)) { + size_t const tagTableSize = hSize; + ZSTD_memcpy(cctx->blockState.matchState.tagTable, + cdict->matchState.tagTable, + tagTableSize); + cctx->blockState.matchState.hashSalt = cdict->matchState.hashSalt; + } + } + + /* Zero the hashTable3, since the cdict never fills it */ + assert(cctx->blockState.matchState.hashLog3 <= 31); + { U32 const h3log = cctx->blockState.matchState.hashLog3; + size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0; + assert(cdict->matchState.hashLog3 == 0); + ZSTD_memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32)); + } + + ZSTD_cwksp_mark_tables_clean(&cctx->workspace); + + /* copy dictionary offsets */ + { ZSTD_MatchState_t const* srcMatchState = &cdict->matchState; + ZSTD_MatchState_t* dstMatchState = &cctx->blockState.matchState; + dstMatchState->window = srcMatchState->window; + dstMatchState->nextToUpdate = srcMatchState->nextToUpdate; + dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd; + } + + cctx->dictID = cdict->dictID; + cctx->dictContentSize = cdict->dictContentSize; + + /* copy block state */ + ZSTD_memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState)); + + return 0; +} + +/* We have a choice between copying the dictionary context into the working + * context, or referencing the dictionary context from the working context + * in-place. We decide here which strategy to use. */ +static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx, + const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, + U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + + DEBUGLOG(4, "ZSTD_resetCCtx_usingCDict (pledgedSrcSize=%u)", + (unsigned)pledgedSrcSize); + + if (ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) { + return ZSTD_resetCCtx_byAttachingCDict( + cctx, cdict, *params, pledgedSrcSize, zbuff); + } else { + return ZSTD_resetCCtx_byCopyingCDict( + cctx, cdict, *params, pledgedSrcSize, zbuff); + } +} + +/*! ZSTD_copyCCtx_internal() : + * Duplicate an existing context `srcCCtx` into another one `dstCCtx`. + * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()). + * The "context", in this case, refers to the hash and chain tables, + * entropy tables, and dictionary references. + * `windowLog` value is enforced if != 0, otherwise value is copied from srcCCtx. + * @return : 0, or an error code */ +static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, + const ZSTD_CCtx* srcCCtx, + ZSTD_frameParameters fParams, + U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong, + "Can't copy a ctx that's not in init stage."); + DEBUGLOG(5, "ZSTD_copyCCtx_internal"); + ZSTD_memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem)); + { ZSTD_CCtx_params params = dstCCtx->requestedParams; + /* Copy only compression parameters related to tables. */ + params.cParams = srcCCtx->appliedParams.cParams; + assert(srcCCtx->appliedParams.useRowMatchFinder != ZSTD_ps_auto); + assert(srcCCtx->appliedParams.postBlockSplitter != ZSTD_ps_auto); + assert(srcCCtx->appliedParams.ldmParams.enableLdm != ZSTD_ps_auto); + params.useRowMatchFinder = srcCCtx->appliedParams.useRowMatchFinder; + params.postBlockSplitter = srcCCtx->appliedParams.postBlockSplitter; + params.ldmParams = srcCCtx->appliedParams.ldmParams; + params.fParams = fParams; + params.maxBlockSize = srcCCtx->appliedParams.maxBlockSize; + ZSTD_resetCCtx_internal(dstCCtx, ¶ms, pledgedSrcSize, + /* loadedDictSize */ 0, + ZSTDcrp_leaveDirty, zbuff); + assert(dstCCtx->appliedParams.cParams.windowLog == srcCCtx->appliedParams.cParams.windowLog); + assert(dstCCtx->appliedParams.cParams.strategy == srcCCtx->appliedParams.cParams.strategy); + assert(dstCCtx->appliedParams.cParams.hashLog == srcCCtx->appliedParams.cParams.hashLog); + assert(dstCCtx->appliedParams.cParams.chainLog == srcCCtx->appliedParams.cParams.chainLog); + assert(dstCCtx->blockState.matchState.hashLog3 == srcCCtx->blockState.matchState.hashLog3); + } + + ZSTD_cwksp_mark_tables_dirty(&dstCCtx->workspace); + + /* copy tables */ + { size_t const chainSize = ZSTD_allocateChainTable(srcCCtx->appliedParams.cParams.strategy, + srcCCtx->appliedParams.useRowMatchFinder, + 0 /* forDDSDict */) + ? ((size_t)1 << srcCCtx->appliedParams.cParams.chainLog) + : 0; + size_t const hSize = (size_t)1 << srcCCtx->appliedParams.cParams.hashLog; + U32 const h3log = srcCCtx->blockState.matchState.hashLog3; + size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0; + + ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable, + srcCCtx->blockState.matchState.hashTable, + hSize * sizeof(U32)); + ZSTD_memcpy(dstCCtx->blockState.matchState.chainTable, + srcCCtx->blockState.matchState.chainTable, + chainSize * sizeof(U32)); + ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable3, + srcCCtx->blockState.matchState.hashTable3, + h3Size * sizeof(U32)); + } + + ZSTD_cwksp_mark_tables_clean(&dstCCtx->workspace); + + /* copy dictionary offsets */ + { + const ZSTD_MatchState_t* srcMatchState = &srcCCtx->blockState.matchState; + ZSTD_MatchState_t* dstMatchState = &dstCCtx->blockState.matchState; + dstMatchState->window = srcMatchState->window; + dstMatchState->nextToUpdate = srcMatchState->nextToUpdate; + dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd; + } + dstCCtx->dictID = srcCCtx->dictID; + dstCCtx->dictContentSize = srcCCtx->dictContentSize; + + /* copy block state */ + ZSTD_memcpy(dstCCtx->blockState.prevCBlock, srcCCtx->blockState.prevCBlock, sizeof(*srcCCtx->blockState.prevCBlock)); + + return 0; +} + +/*! ZSTD_copyCCtx() : + * Duplicate an existing context `srcCCtx` into another one `dstCCtx`. + * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()). + * pledgedSrcSize==0 means "unknown". +* @return : 0, or an error code */ +size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize) +{ + ZSTD_frameParameters fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; + ZSTD_buffered_policy_e const zbuff = srcCCtx->bufferedPolicy; + ZSTD_STATIC_ASSERT((U32)ZSTDb_buffered==1); + if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; + fParams.contentSizeFlag = (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN); + + return ZSTD_copyCCtx_internal(dstCCtx, srcCCtx, + fParams, pledgedSrcSize, + zbuff); +} + + +#define ZSTD_ROWSIZE 16 +/*! ZSTD_reduceTable() : + * reduce table indexes by `reducerValue`, or squash to zero. + * PreserveMark preserves "unsorted mark" for btlazy2 strategy. + * It must be set to a clear 0/1 value, to remove branch during inlining. + * Presume table size is a multiple of ZSTD_ROWSIZE + * to help auto-vectorization */ +FORCE_INLINE_TEMPLATE void +ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerValue, int const preserveMark) +{ + int const nbRows = (int)size / ZSTD_ROWSIZE; + int cellNb = 0; + int rowNb; + /* Protect special index values < ZSTD_WINDOW_START_INDEX. */ + U32 const reducerThreshold = reducerValue + ZSTD_WINDOW_START_INDEX; + assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */ + assert(size < (1U<<31)); /* can be cast to int */ + +#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) + /* To validate that the table reuse logic is sound, and that we don't + * access table space that we haven't cleaned, we re-"poison" the table + * space every time we mark it dirty. + * + * This function however is intended to operate on those dirty tables and + * re-clean them. So when this function is used correctly, we can unpoison + * the memory it operated on. This introduces a blind spot though, since + * if we now try to operate on __actually__ poisoned memory, we will not + * detect that. */ + __msan_unpoison(table, size * sizeof(U32)); +#endif + + for (rowNb=0 ; rowNb < nbRows ; rowNb++) { + int column; + for (column=0; columncParams.hashLog; + ZSTD_reduceTable(ms->hashTable, hSize, reducerValue); + } + + if (ZSTD_allocateChainTable(params->cParams.strategy, params->useRowMatchFinder, (U32)ms->dedicatedDictSearch)) { + U32 const chainSize = (U32)1 << params->cParams.chainLog; + if (params->cParams.strategy == ZSTD_btlazy2) + ZSTD_reduceTable_btlazy2(ms->chainTable, chainSize, reducerValue); + else + ZSTD_reduceTable(ms->chainTable, chainSize, reducerValue); + } + + if (ms->hashLog3) { + U32 const h3Size = (U32)1 << ms->hashLog3; + ZSTD_reduceTable(ms->hashTable3, h3Size, reducerValue); + } +} + + +/*-******************************************************* +* Block entropic compression +*********************************************************/ + +/* See doc/zstd_compression_format.md for detailed format description */ + +int ZSTD_seqToCodes(const SeqStore_t* seqStorePtr) +{ + const SeqDef* const sequences = seqStorePtr->sequencesStart; + BYTE* const llCodeTable = seqStorePtr->llCode; + BYTE* const ofCodeTable = seqStorePtr->ofCode; + BYTE* const mlCodeTable = seqStorePtr->mlCode; + U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + U32 u; + int longOffsets = 0; + assert(nbSeq <= seqStorePtr->maxNbSeq); + for (u=0; u= STREAM_ACCUMULATOR_MIN)); + if (MEM_32bits() && ofCode >= STREAM_ACCUMULATOR_MIN) + longOffsets = 1; + } + if (seqStorePtr->longLengthType==ZSTD_llt_literalLength) + llCodeTable[seqStorePtr->longLengthPos] = MaxLL; + if (seqStorePtr->longLengthType==ZSTD_llt_matchLength) + mlCodeTable[seqStorePtr->longLengthPos] = MaxML; + return longOffsets; +} + +/* ZSTD_useTargetCBlockSize(): + * Returns if target compressed block size param is being used. + * If used, compression will do best effort to make a compressed block size to be around targetCBlockSize. + * Returns 1 if true, 0 otherwise. */ +static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams) +{ + DEBUGLOG(5, "ZSTD_useTargetCBlockSize (targetCBlockSize=%zu)", cctxParams->targetCBlockSize); + return (cctxParams->targetCBlockSize != 0); +} + +/* ZSTD_blockSplitterEnabled(): + * Returns if block splitting param is being used + * If used, compression will do best effort to split a block in order to improve compression ratio. + * At the time this function is called, the parameter must be finalized. + * Returns 1 if true, 0 otherwise. */ +static int ZSTD_blockSplitterEnabled(ZSTD_CCtx_params* cctxParams) +{ + DEBUGLOG(5, "ZSTD_blockSplitterEnabled (postBlockSplitter=%d)", cctxParams->postBlockSplitter); + assert(cctxParams->postBlockSplitter != ZSTD_ps_auto); + return (cctxParams->postBlockSplitter == ZSTD_ps_enable); +} + +/* Type returned by ZSTD_buildSequencesStatistics containing finalized symbol encoding types + * and size of the sequences statistics + */ +typedef struct { + U32 LLtype; + U32 Offtype; + U32 MLtype; + size_t size; + size_t lastCountSize; /* Accounts for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */ + int longOffsets; +} ZSTD_symbolEncodingTypeStats_t; + +/* ZSTD_buildSequencesStatistics(): + * Returns a ZSTD_symbolEncodingTypeStats_t, or a zstd error code in the `size` field. + * Modifies `nextEntropy` to have the appropriate values as a side effect. + * nbSeq must be greater than 0. + * + * entropyWkspSize must be of size at least ENTROPY_WORKSPACE_SIZE - (MaxSeq + 1)*sizeof(U32) + */ +static ZSTD_symbolEncodingTypeStats_t +ZSTD_buildSequencesStatistics( + const SeqStore_t* seqStorePtr, size_t nbSeq, + const ZSTD_fseCTables_t* prevEntropy, ZSTD_fseCTables_t* nextEntropy, + BYTE* dst, const BYTE* const dstEnd, + ZSTD_strategy strategy, unsigned* countWorkspace, + void* entropyWorkspace, size_t entropyWkspSize) +{ + BYTE* const ostart = dst; + const BYTE* const oend = dstEnd; + BYTE* op = ostart; + FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable; + FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable; + FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable; + const BYTE* const ofCodeTable = seqStorePtr->ofCode; + const BYTE* const llCodeTable = seqStorePtr->llCode; + const BYTE* const mlCodeTable = seqStorePtr->mlCode; + ZSTD_symbolEncodingTypeStats_t stats; + + stats.lastCountSize = 0; + /* convert length/distances into codes */ + stats.longOffsets = ZSTD_seqToCodes(seqStorePtr); + assert(op <= oend); + assert(nbSeq != 0); /* ZSTD_selectEncodingType() divides by nbSeq */ + /* build CTable for Literal Lengths */ + { unsigned max = MaxLL; + size_t const mostFrequent = HIST_countFast_wksp(countWorkspace, &max, llCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */ + DEBUGLOG(5, "Building LL table"); + nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode; + stats.LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode, + countWorkspace, max, mostFrequent, nbSeq, + LLFSELog, prevEntropy->litlengthCTable, + LL_defaultNorm, LL_defaultNormLog, + ZSTD_defaultAllowed, strategy); + assert(set_basic < set_compressed && set_rle < set_compressed); + assert(!(stats.LLtype < set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */ + { size_t const countSize = ZSTD_buildCTable( + op, (size_t)(oend - op), + CTable_LitLength, LLFSELog, (SymbolEncodingType_e)stats.LLtype, + countWorkspace, max, llCodeTable, nbSeq, + LL_defaultNorm, LL_defaultNormLog, MaxLL, + prevEntropy->litlengthCTable, + sizeof(prevEntropy->litlengthCTable), + entropyWorkspace, entropyWkspSize); + if (ZSTD_isError(countSize)) { + DEBUGLOG(3, "ZSTD_buildCTable for LitLens failed"); + stats.size = countSize; + return stats; + } + if (stats.LLtype == set_compressed) + stats.lastCountSize = countSize; + op += countSize; + assert(op <= oend); + } } + /* build CTable for Offsets */ + { unsigned max = MaxOff; + size_t const mostFrequent = HIST_countFast_wksp( + countWorkspace, &max, ofCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */ + /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */ + ZSTD_DefaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed; + DEBUGLOG(5, "Building OF table"); + nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode; + stats.Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode, + countWorkspace, max, mostFrequent, nbSeq, + OffFSELog, prevEntropy->offcodeCTable, + OF_defaultNorm, OF_defaultNormLog, + defaultPolicy, strategy); + assert(!(stats.Offtype < set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */ + { size_t const countSize = ZSTD_buildCTable( + op, (size_t)(oend - op), + CTable_OffsetBits, OffFSELog, (SymbolEncodingType_e)stats.Offtype, + countWorkspace, max, ofCodeTable, nbSeq, + OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, + prevEntropy->offcodeCTable, + sizeof(prevEntropy->offcodeCTable), + entropyWorkspace, entropyWkspSize); + if (ZSTD_isError(countSize)) { + DEBUGLOG(3, "ZSTD_buildCTable for Offsets failed"); + stats.size = countSize; + return stats; + } + if (stats.Offtype == set_compressed) + stats.lastCountSize = countSize; + op += countSize; + assert(op <= oend); + } } + /* build CTable for MatchLengths */ + { unsigned max = MaxML; + size_t const mostFrequent = HIST_countFast_wksp( + countWorkspace, &max, mlCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */ + DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op)); + nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode; + stats.MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode, + countWorkspace, max, mostFrequent, nbSeq, + MLFSELog, prevEntropy->matchlengthCTable, + ML_defaultNorm, ML_defaultNormLog, + ZSTD_defaultAllowed, strategy); + assert(!(stats.MLtype < set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */ + { size_t const countSize = ZSTD_buildCTable( + op, (size_t)(oend - op), + CTable_MatchLength, MLFSELog, (SymbolEncodingType_e)stats.MLtype, + countWorkspace, max, mlCodeTable, nbSeq, + ML_defaultNorm, ML_defaultNormLog, MaxML, + prevEntropy->matchlengthCTable, + sizeof(prevEntropy->matchlengthCTable), + entropyWorkspace, entropyWkspSize); + if (ZSTD_isError(countSize)) { + DEBUGLOG(3, "ZSTD_buildCTable for MatchLengths failed"); + stats.size = countSize; + return stats; + } + if (stats.MLtype == set_compressed) + stats.lastCountSize = countSize; + op += countSize; + assert(op <= oend); + } } + stats.size = (size_t)(op-ostart); + return stats; +} + +/* ZSTD_entropyCompressSeqStore_internal(): + * compresses both literals and sequences + * Returns compressed size of block, or a zstd error. + */ +#define SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO 20 +MEM_STATIC size_t +ZSTD_entropyCompressSeqStore_internal( + void* dst, size_t dstCapacity, + const void* literals, size_t litSize, + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + void* entropyWorkspace, size_t entropyWkspSize, + const int bmi2) +{ + ZSTD_strategy const strategy = cctxParams->cParams.strategy; + unsigned* count = (unsigned*)entropyWorkspace; + FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable; + FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable; + FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable; + const SeqDef* const sequences = seqStorePtr->sequencesStart; + const size_t nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + const BYTE* const ofCodeTable = seqStorePtr->ofCode; + const BYTE* const llCodeTable = seqStorePtr->llCode; + const BYTE* const mlCodeTable = seqStorePtr->mlCode; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstCapacity; + BYTE* op = ostart; + size_t lastCountSize; + int longOffsets = 0; + + entropyWorkspace = count + (MaxSeq + 1); + entropyWkspSize -= (MaxSeq + 1) * sizeof(*count); + + DEBUGLOG(5, "ZSTD_entropyCompressSeqStore_internal (nbSeq=%zu, dstCapacity=%zu)", nbSeq, dstCapacity); + ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<= HUF_WORKSPACE_SIZE); + + /* Compress literals */ + { size_t const numSequences = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + /* Base suspicion of uncompressibility on ratio of literals to sequences */ + int const suspectUncompressible = (numSequences == 0) || (litSize / numSequences >= SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO); + + size_t const cSize = ZSTD_compressLiterals( + op, dstCapacity, + literals, litSize, + entropyWorkspace, entropyWkspSize, + &prevEntropy->huf, &nextEntropy->huf, + cctxParams->cParams.strategy, + ZSTD_literalsCompressionIsDisabled(cctxParams), + suspectUncompressible, bmi2); + FORWARD_IF_ERROR(cSize, "ZSTD_compressLiterals failed"); + assert(cSize <= dstCapacity); + op += cSize; + } + + /* Sequences Header */ + RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/, + dstSize_tooSmall, "Can't fit seq hdr in output buf!"); + if (nbSeq < 128) { + *op++ = (BYTE)nbSeq; + } else if (nbSeq < LONGNBSEQ) { + op[0] = (BYTE)((nbSeq>>8) + 0x80); + op[1] = (BYTE)nbSeq; + op+=2; + } else { + op[0]=0xFF; + MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)); + op+=3; + } + assert(op <= oend); + if (nbSeq==0) { + /* Copy the old tables over as if we repeated them */ + ZSTD_memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse)); + return (size_t)(op - ostart); + } + { BYTE* const seqHead = op++; + /* build stats for sequences */ + const ZSTD_symbolEncodingTypeStats_t stats = + ZSTD_buildSequencesStatistics(seqStorePtr, nbSeq, + &prevEntropy->fse, &nextEntropy->fse, + op, oend, + strategy, count, + entropyWorkspace, entropyWkspSize); + FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!"); + *seqHead = (BYTE)((stats.LLtype<<6) + (stats.Offtype<<4) + (stats.MLtype<<2)); + lastCountSize = stats.lastCountSize; + op += stats.size; + longOffsets = stats.longOffsets; + } + + { size_t const bitstreamSize = ZSTD_encodeSequences( + op, (size_t)(oend - op), + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, + longOffsets, bmi2); + FORWARD_IF_ERROR(bitstreamSize, "ZSTD_encodeSequences failed"); + op += bitstreamSize; + assert(op <= oend); + /* zstd versions <= 1.3.4 mistakenly report corruption when + * FSE_readNCount() receives a buffer < 4 bytes. + * Fixed by https://github.com/facebook/zstd/pull/1146. + * This can happen when the last set_compressed table present is 2 + * bytes and the bitstream is only one byte. + * In this exceedingly rare case, we will simply emit an uncompressed + * block, since it isn't worth optimizing. + */ + if (lastCountSize && (lastCountSize + bitstreamSize) < 4) { + /* lastCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */ + assert(lastCountSize + bitstreamSize == 3); + DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by " + "emitting an uncompressed block."); + return 0; + } + } + + DEBUGLOG(5, "compressed block size : %u", (unsigned)(op - ostart)); + return (size_t)(op - ostart); +} + +static size_t +ZSTD_entropyCompressSeqStore_wExtLitBuffer( + void* dst, size_t dstCapacity, + const void* literals, size_t litSize, + size_t blockSize, + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + void* entropyWorkspace, size_t entropyWkspSize, + int bmi2) +{ + size_t const cSize = ZSTD_entropyCompressSeqStore_internal( + dst, dstCapacity, + literals, litSize, + seqStorePtr, prevEntropy, nextEntropy, cctxParams, + entropyWorkspace, entropyWkspSize, bmi2); + if (cSize == 0) return 0; + /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block. + * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block. + */ + if ((cSize == ERROR(dstSize_tooSmall)) & (blockSize <= dstCapacity)) { + DEBUGLOG(4, "not enough dstCapacity (%zu) for ZSTD_entropyCompressSeqStore_internal()=> do not compress block", dstCapacity); + return 0; /* block not compressed */ + } + FORWARD_IF_ERROR(cSize, "ZSTD_entropyCompressSeqStore_internal failed"); + + /* Check compressibility */ + { size_t const maxCSize = blockSize - ZSTD_minGain(blockSize, cctxParams->cParams.strategy); + if (cSize >= maxCSize) return 0; /* block not compressed */ + } + DEBUGLOG(5, "ZSTD_entropyCompressSeqStore() cSize: %zu", cSize); + /* libzstd decoder before > v1.5.4 is not compatible with compressed blocks of size ZSTD_BLOCKSIZE_MAX exactly. + * This restriction is indirectly already fulfilled by respecting ZSTD_minGain() condition above. + */ + assert(cSize < ZSTD_BLOCKSIZE_MAX); + return cSize; +} + +static size_t +ZSTD_entropyCompressSeqStore( + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + void* dst, size_t dstCapacity, + size_t srcSize, + void* entropyWorkspace, size_t entropyWkspSize, + int bmi2) +{ + return ZSTD_entropyCompressSeqStore_wExtLitBuffer( + dst, dstCapacity, + seqStorePtr->litStart, (size_t)(seqStorePtr->lit - seqStorePtr->litStart), + srcSize, + seqStorePtr, + prevEntropy, nextEntropy, + cctxParams, + entropyWorkspace, entropyWkspSize, + bmi2); +} + +/* ZSTD_selectBlockCompressor() : + * Not static, but internal use only (used by long distance matcher) + * assumption : strat is a valid strategy */ +ZSTD_BlockCompressor_f ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_ParamSwitch_e useRowMatchFinder, ZSTD_dictMode_e dictMode) +{ + static const ZSTD_BlockCompressor_f blockCompressor[4][ZSTD_STRATEGY_MAX+1] = { + { ZSTD_compressBlock_fast /* default for 0 */, + ZSTD_compressBlock_fast, + ZSTD_COMPRESSBLOCK_DOUBLEFAST, + ZSTD_COMPRESSBLOCK_GREEDY, + ZSTD_COMPRESSBLOCK_LAZY, + ZSTD_COMPRESSBLOCK_LAZY2, + ZSTD_COMPRESSBLOCK_BTLAZY2, + ZSTD_COMPRESSBLOCK_BTOPT, + ZSTD_COMPRESSBLOCK_BTULTRA, + ZSTD_COMPRESSBLOCK_BTULTRA2 + }, + { ZSTD_compressBlock_fast_extDict /* default for 0 */, + ZSTD_compressBlock_fast_extDict, + ZSTD_COMPRESSBLOCK_DOUBLEFAST_EXTDICT, + ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT, + ZSTD_COMPRESSBLOCK_LAZY_EXTDICT, + ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT, + ZSTD_COMPRESSBLOCK_BTLAZY2_EXTDICT, + ZSTD_COMPRESSBLOCK_BTOPT_EXTDICT, + ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT, + ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT + }, + { ZSTD_compressBlock_fast_dictMatchState /* default for 0 */, + ZSTD_compressBlock_fast_dictMatchState, + ZSTD_COMPRESSBLOCK_DOUBLEFAST_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTLAZY2_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTOPT_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE, + ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE + }, + { NULL /* default for 0 */, + NULL, + NULL, + ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH, + ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH, + ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH, + NULL, + NULL, + NULL, + NULL } + }; + ZSTD_BlockCompressor_f selectedCompressor; + ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1); + + assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, (int)strat)); + DEBUGLOG(5, "Selected block compressor: dictMode=%d strat=%d rowMatchfinder=%d", (int)dictMode, (int)strat, (int)useRowMatchFinder); + if (ZSTD_rowMatchFinderUsed(strat, useRowMatchFinder)) { + static const ZSTD_BlockCompressor_f rowBasedBlockCompressors[4][3] = { + { + ZSTD_COMPRESSBLOCK_GREEDY_ROW, + ZSTD_COMPRESSBLOCK_LAZY_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_ROW + }, + { + ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW, + ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW + }, + { + ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW, + ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW + }, + { + ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW, + ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW, + ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW + } + }; + DEBUGLOG(5, "Selecting a row-based matchfinder"); + assert(useRowMatchFinder != ZSTD_ps_auto); + selectedCompressor = rowBasedBlockCompressors[(int)dictMode][(int)strat - (int)ZSTD_greedy]; + } else { + selectedCompressor = blockCompressor[(int)dictMode][(int)strat]; + } + assert(selectedCompressor != NULL); + return selectedCompressor; +} + +static void ZSTD_storeLastLiterals(SeqStore_t* seqStorePtr, + const BYTE* anchor, size_t lastLLSize) +{ + ZSTD_memcpy(seqStorePtr->lit, anchor, lastLLSize); + seqStorePtr->lit += lastLLSize; +} + +void ZSTD_resetSeqStore(SeqStore_t* ssPtr) +{ + ssPtr->lit = ssPtr->litStart; + ssPtr->sequences = ssPtr->sequencesStart; + ssPtr->longLengthType = ZSTD_llt_none; +} + +/* ZSTD_postProcessSequenceProducerResult() : + * Validates and post-processes sequences obtained through the external matchfinder API: + * - Checks whether nbExternalSeqs represents an error condition. + * - Appends a block delimiter to outSeqs if one is not already present. + * See zstd.h for context regarding block delimiters. + * Returns the number of sequences after post-processing, or an error code. */ +static size_t ZSTD_postProcessSequenceProducerResult( + ZSTD_Sequence* outSeqs, size_t nbExternalSeqs, size_t outSeqsCapacity, size_t srcSize +) { + RETURN_ERROR_IF( + nbExternalSeqs > outSeqsCapacity, + sequenceProducer_failed, + "External sequence producer returned error code %lu", + (unsigned long)nbExternalSeqs + ); + + RETURN_ERROR_IF( + nbExternalSeqs == 0 && srcSize > 0, + sequenceProducer_failed, + "Got zero sequences from external sequence producer for a non-empty src buffer!" + ); + + if (srcSize == 0) { + ZSTD_memset(&outSeqs[0], 0, sizeof(ZSTD_Sequence)); + return 1; + } + + { + ZSTD_Sequence const lastSeq = outSeqs[nbExternalSeqs - 1]; + + /* We can return early if lastSeq is already a block delimiter. */ + if (lastSeq.offset == 0 && lastSeq.matchLength == 0) { + return nbExternalSeqs; + } + + /* This error condition is only possible if the external matchfinder + * produced an invalid parse, by definition of ZSTD_sequenceBound(). */ + RETURN_ERROR_IF( + nbExternalSeqs == outSeqsCapacity, + sequenceProducer_failed, + "nbExternalSeqs == outSeqsCapacity but lastSeq is not a block delimiter!" + ); + + /* lastSeq is not a block delimiter, so we need to append one. */ + ZSTD_memset(&outSeqs[nbExternalSeqs], 0, sizeof(ZSTD_Sequence)); + return nbExternalSeqs + 1; + } +} + +/* ZSTD_fastSequenceLengthSum() : + * Returns sum(litLen) + sum(matchLen) + lastLits for *seqBuf*. + * Similar to another function in zstd_compress.c (determine_blockSize), + * except it doesn't check for a block delimiter to end summation. + * Removing the early exit allows the compiler to auto-vectorize (https://godbolt.org/z/cY1cajz9P). + * This function can be deleted and replaced by determine_blockSize after we resolve issue #3456. */ +static size_t ZSTD_fastSequenceLengthSum(ZSTD_Sequence const* seqBuf, size_t seqBufSize) { + size_t matchLenSum, litLenSum, i; + matchLenSum = 0; + litLenSum = 0; + for (i = 0; i < seqBufSize; i++) { + litLenSum += seqBuf[i].litLength; + matchLenSum += seqBuf[i].matchLength; + } + return litLenSum + matchLenSum; +} + +/** + * Function to validate sequences produced by a block compressor. + */ +static void ZSTD_validateSeqStore(const SeqStore_t* seqStore, const ZSTD_compressionParameters* cParams) +{ +#if DEBUGLEVEL >= 1 + const SeqDef* seq = seqStore->sequencesStart; + const SeqDef* const seqEnd = seqStore->sequences; + size_t const matchLenLowerBound = cParams->minMatch == 3 ? 3 : 4; + for (; seq < seqEnd; ++seq) { + const ZSTD_SequenceLength seqLength = ZSTD_getSequenceLength(seqStore, seq); + assert(seqLength.matchLength >= matchLenLowerBound); + (void)seqLength; + (void)matchLenLowerBound; + } +#else + (void)seqStore; + (void)cParams; +#endif +} + +static size_t +ZSTD_transferSequences_wBlockDelim(ZSTD_CCtx* cctx, + ZSTD_SequencePosition* seqPos, + const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, + const void* src, size_t blockSize, + ZSTD_ParamSwitch_e externalRepSearch); + +typedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_BuildSeqStore_e; + +static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize) +{ + ZSTD_MatchState_t* const ms = &zc->blockState.matchState; + DEBUGLOG(5, "ZSTD_buildSeqStore (srcSize=%zu)", srcSize); + assert(srcSize <= ZSTD_BLOCKSIZE_MAX); + /* Assert that we have correctly flushed the ctx params into the ms's copy */ + ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams); + /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding + * additional 1. We need to revisit and change this logic to be more consistent */ + if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1+1) { + if (zc->appliedParams.cParams.strategy >= ZSTD_btopt) { + ZSTD_ldm_skipRawSeqStoreBytes(&zc->externSeqStore, srcSize); + } else { + ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch); + } + return ZSTDbss_noCompress; /* don't even attempt compression below a certain srcSize */ + } + ZSTD_resetSeqStore(&(zc->seqStore)); + /* required for optimal parser to read stats from dictionary */ + ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy; + /* tell the optimal parser how we expect to compress literals */ + ms->opt.literalCompressionMode = zc->appliedParams.literalCompressionMode; + /* a gap between an attached dict and the current window is not safe, + * they must remain adjacent, + * and when that stops being the case, the dict must be unset */ + assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit); + + /* limited update after a very long match */ + { const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const U32 curr = (U32)(istart-base); + if (sizeof(ptrdiff_t)==8) assert(istart - base < (ptrdiff_t)(U32)(-1)); /* ensure no overflow */ + if (curr > ms->nextToUpdate + 384) + ms->nextToUpdate = curr - MIN(192, (U32)(curr - ms->nextToUpdate - 384)); + } + + /* select and store sequences */ + { ZSTD_dictMode_e const dictMode = ZSTD_matchState_dictMode(ms); + size_t lastLLSize; + { int i; + for (i = 0; i < ZSTD_REP_NUM; ++i) + zc->blockState.nextCBlock->rep[i] = zc->blockState.prevCBlock->rep[i]; + } + if (zc->externSeqStore.pos < zc->externSeqStore.size) { + assert(zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_disable); + + /* External matchfinder + LDM is technically possible, just not implemented yet. + * We need to revisit soon and implement it. */ + RETURN_ERROR_IF( + ZSTD_hasExtSeqProd(&zc->appliedParams), + parameter_combination_unsupported, + "Long-distance matching with external sequence producer enabled is not currently supported." + ); + + /* Updates ldmSeqStore.pos */ + lastLLSize = + ZSTD_ldm_blockCompress(&zc->externSeqStore, + ms, &zc->seqStore, + zc->blockState.nextCBlock->rep, + zc->appliedParams.useRowMatchFinder, + src, srcSize); + assert(zc->externSeqStore.pos <= zc->externSeqStore.size); + } else if (zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) { + RawSeqStore_t ldmSeqStore = kNullRawSeqStore; + + /* External matchfinder + LDM is technically possible, just not implemented yet. + * We need to revisit soon and implement it. */ + RETURN_ERROR_IF( + ZSTD_hasExtSeqProd(&zc->appliedParams), + parameter_combination_unsupported, + "Long-distance matching with external sequence producer enabled is not currently supported." + ); + + ldmSeqStore.seq = zc->ldmSequences; + ldmSeqStore.capacity = zc->maxNbLdmSequences; + /* Updates ldmSeqStore.size */ + FORWARD_IF_ERROR(ZSTD_ldm_generateSequences(&zc->ldmState, &ldmSeqStore, + &zc->appliedParams.ldmParams, + src, srcSize), ""); + /* Updates ldmSeqStore.pos */ + lastLLSize = + ZSTD_ldm_blockCompress(&ldmSeqStore, + ms, &zc->seqStore, + zc->blockState.nextCBlock->rep, + zc->appliedParams.useRowMatchFinder, + src, srcSize); + assert(ldmSeqStore.pos == ldmSeqStore.size); + } else if (ZSTD_hasExtSeqProd(&zc->appliedParams)) { + assert( + zc->extSeqBufCapacity >= ZSTD_sequenceBound(srcSize) + ); + assert(zc->appliedParams.extSeqProdFunc != NULL); + + { U32 const windowSize = (U32)1 << zc->appliedParams.cParams.windowLog; + + size_t const nbExternalSeqs = (zc->appliedParams.extSeqProdFunc)( + zc->appliedParams.extSeqProdState, + zc->extSeqBuf, + zc->extSeqBufCapacity, + src, srcSize, + NULL, 0, /* dict and dictSize, currently not supported */ + zc->appliedParams.compressionLevel, + windowSize + ); + + size_t const nbPostProcessedSeqs = ZSTD_postProcessSequenceProducerResult( + zc->extSeqBuf, + nbExternalSeqs, + zc->extSeqBufCapacity, + srcSize + ); + + /* Return early if there is no error, since we don't need to worry about last literals */ + if (!ZSTD_isError(nbPostProcessedSeqs)) { + ZSTD_SequencePosition seqPos = {0,0,0}; + size_t const seqLenSum = ZSTD_fastSequenceLengthSum(zc->extSeqBuf, nbPostProcessedSeqs); + RETURN_ERROR_IF(seqLenSum > srcSize, externalSequences_invalid, "External sequences imply too large a block!"); + FORWARD_IF_ERROR( + ZSTD_transferSequences_wBlockDelim( + zc, &seqPos, + zc->extSeqBuf, nbPostProcessedSeqs, + src, srcSize, + zc->appliedParams.searchForExternalRepcodes + ), + "Failed to copy external sequences to seqStore!" + ); + ms->ldmSeqStore = NULL; + DEBUGLOG(5, "Copied %lu sequences from external sequence producer to internal seqStore.", (unsigned long)nbExternalSeqs); + return ZSTDbss_compress; + } + + /* Propagate the error if fallback is disabled */ + if (!zc->appliedParams.enableMatchFinderFallback) { + return nbPostProcessedSeqs; + } + + /* Fallback to software matchfinder */ + { ZSTD_BlockCompressor_f const blockCompressor = + ZSTD_selectBlockCompressor( + zc->appliedParams.cParams.strategy, + zc->appliedParams.useRowMatchFinder, + dictMode); + ms->ldmSeqStore = NULL; + DEBUGLOG( + 5, + "External sequence producer returned error code %lu. Falling back to internal parser.", + (unsigned long)nbExternalSeqs + ); + lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize); + } } + } else { /* not long range mode and no external matchfinder */ + ZSTD_BlockCompressor_f const blockCompressor = ZSTD_selectBlockCompressor( + zc->appliedParams.cParams.strategy, + zc->appliedParams.useRowMatchFinder, + dictMode); + ms->ldmSeqStore = NULL; + lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize); + } + { const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize; + ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize); + } } + ZSTD_validateSeqStore(&zc->seqStore, &zc->appliedParams.cParams); + return ZSTDbss_compress; +} + +static size_t ZSTD_copyBlockSequences(SeqCollector* seqCollector, const SeqStore_t* seqStore, const U32 prevRepcodes[ZSTD_REP_NUM]) +{ + const SeqDef* inSeqs = seqStore->sequencesStart; + const size_t nbInSequences = (size_t)(seqStore->sequences - inSeqs); + const size_t nbInLiterals = (size_t)(seqStore->lit - seqStore->litStart); + + ZSTD_Sequence* outSeqs = seqCollector->seqIndex == 0 ? seqCollector->seqStart : seqCollector->seqStart + seqCollector->seqIndex; + const size_t nbOutSequences = nbInSequences + 1; + size_t nbOutLiterals = 0; + Repcodes_t repcodes; + size_t i; + + /* Bounds check that we have enough space for every input sequence + * and the block delimiter + */ + assert(seqCollector->seqIndex <= seqCollector->maxSequences); + RETURN_ERROR_IF( + nbOutSequences > (size_t)(seqCollector->maxSequences - seqCollector->seqIndex), + dstSize_tooSmall, + "Not enough space to copy sequences"); + + ZSTD_memcpy(&repcodes, prevRepcodes, sizeof(repcodes)); + for (i = 0; i < nbInSequences; ++i) { + U32 rawOffset; + outSeqs[i].litLength = inSeqs[i].litLength; + outSeqs[i].matchLength = inSeqs[i].mlBase + MINMATCH; + outSeqs[i].rep = 0; + + /* Handle the possible single length >= 64K + * There can only be one because we add MINMATCH to every match length, + * and blocks are at most 128K. + */ + if (i == seqStore->longLengthPos) { + if (seqStore->longLengthType == ZSTD_llt_literalLength) { + outSeqs[i].litLength += 0x10000; + } else if (seqStore->longLengthType == ZSTD_llt_matchLength) { + outSeqs[i].matchLength += 0x10000; + } + } + + /* Determine the raw offset given the offBase, which may be a repcode. */ + if (OFFBASE_IS_REPCODE(inSeqs[i].offBase)) { + const U32 repcode = OFFBASE_TO_REPCODE(inSeqs[i].offBase); + assert(repcode > 0); + outSeqs[i].rep = repcode; + if (outSeqs[i].litLength != 0) { + rawOffset = repcodes.rep[repcode - 1]; + } else { + if (repcode == 3) { + assert(repcodes.rep[0] > 1); + rawOffset = repcodes.rep[0] - 1; + } else { + rawOffset = repcodes.rep[repcode]; + } + } + } else { + rawOffset = OFFBASE_TO_OFFSET(inSeqs[i].offBase); + } + outSeqs[i].offset = rawOffset; + + /* Update repcode history for the sequence */ + ZSTD_updateRep(repcodes.rep, + inSeqs[i].offBase, + inSeqs[i].litLength == 0); + + nbOutLiterals += outSeqs[i].litLength; + } + /* Insert last literals (if any exist) in the block as a sequence with ml == off == 0. + * If there are no last literals, then we'll emit (of: 0, ml: 0, ll: 0), which is a marker + * for the block boundary, according to the API. + */ + assert(nbInLiterals >= nbOutLiterals); + { + const size_t lastLLSize = nbInLiterals - nbOutLiterals; + outSeqs[nbInSequences].litLength = (U32)lastLLSize; + outSeqs[nbInSequences].matchLength = 0; + outSeqs[nbInSequences].offset = 0; + assert(nbOutSequences == nbInSequences + 1); + } + seqCollector->seqIndex += nbOutSequences; + assert(seqCollector->seqIndex <= seqCollector->maxSequences); + + return 0; +} + +size_t ZSTD_sequenceBound(size_t srcSize) { + const size_t maxNbSeq = (srcSize / ZSTD_MINMATCH_MIN) + 1; + const size_t maxNbDelims = (srcSize / ZSTD_BLOCKSIZE_MAX_MIN) + 1; + return maxNbSeq + maxNbDelims; +} + +size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize) { + size_t in = 0; + size_t out = 0; + for (; in < seqsSize; ++in) { + if (sequences[in].offset == 0 && sequences[in].matchLength == 0) { + if (in != seqsSize - 1) { + sequences[in+1].litLength += sequences[in].litLength; + } + } else { + sequences[out] = sequences[in]; + ++out; + } + } + return out; +} + +/* Unrolled loop to read four size_ts of input at a time. Returns 1 if is RLE, 0 if not. */ +static int ZSTD_isRLE(const BYTE* src, size_t length) { + const BYTE* ip = src; + const BYTE value = ip[0]; + const size_t valueST = (size_t)((U64)value * 0x0101010101010101ULL); + const size_t unrollSize = sizeof(size_t) * 4; + const size_t unrollMask = unrollSize - 1; + const size_t prefixLength = length & unrollMask; + size_t i; + if (length == 1) return 1; + /* Check if prefix is RLE first before using unrolled loop */ + if (prefixLength && ZSTD_count(ip+1, ip, ip+prefixLength) != prefixLength-1) { + return 0; + } + for (i = prefixLength; i != length; i += unrollSize) { + size_t u; + for (u = 0; u < unrollSize; u += sizeof(size_t)) { + if (MEM_readST(ip + i + u) != valueST) { + return 0; + } } } + return 1; +} + +/* Returns true if the given block may be RLE. + * This is just a heuristic based on the compressibility. + * It may return both false positives and false negatives. + */ +static int ZSTD_maybeRLE(SeqStore_t const* seqStore) +{ + size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart); + size_t const nbLits = (size_t)(seqStore->lit - seqStore->litStart); + + return nbSeqs < 4 && nbLits < 10; +} + +static void +ZSTD_blockState_confirmRepcodesAndEntropyTables(ZSTD_blockState_t* const bs) +{ + ZSTD_compressedBlockState_t* const tmp = bs->prevCBlock; + bs->prevCBlock = bs->nextCBlock; + bs->nextCBlock = tmp; +} + +/* Writes the block header */ +static void +writeBlockHeader(void* op, size_t cSize, size_t blockSize, U32 lastBlock) +{ + U32 const cBlockHeader = cSize == 1 ? + lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) : + lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3); + MEM_writeLE24(op, cBlockHeader); + DEBUGLOG(5, "writeBlockHeader: cSize: %zu blockSize: %zu lastBlock: %u", cSize, blockSize, lastBlock); +} + +/** ZSTD_buildBlockEntropyStats_literals() : + * Builds entropy for the literals. + * Stores literals block type (raw, rle, compressed, repeat) and + * huffman description table to hufMetadata. + * Requires ENTROPY_WORKSPACE_SIZE workspace + * @return : size of huffman description table, or an error code + */ +static size_t +ZSTD_buildBlockEntropyStats_literals(void* const src, size_t srcSize, + const ZSTD_hufCTables_t* prevHuf, + ZSTD_hufCTables_t* nextHuf, + ZSTD_hufCTablesMetadata_t* hufMetadata, + const int literalsCompressionIsDisabled, + void* workspace, size_t wkspSize, + int hufFlags) +{ + BYTE* const wkspStart = (BYTE*)workspace; + BYTE* const wkspEnd = wkspStart + wkspSize; + BYTE* const countWkspStart = wkspStart; + unsigned* const countWksp = (unsigned*)workspace; + const size_t countWkspSize = (HUF_SYMBOLVALUE_MAX + 1) * sizeof(unsigned); + BYTE* const nodeWksp = countWkspStart + countWkspSize; + const size_t nodeWkspSize = (size_t)(wkspEnd - nodeWksp); + unsigned maxSymbolValue = HUF_SYMBOLVALUE_MAX; + unsigned huffLog = LitHufLog; + HUF_repeat repeat = prevHuf->repeatMode; + DEBUGLOG(5, "ZSTD_buildBlockEntropyStats_literals (srcSize=%zu)", srcSize); + + /* Prepare nextEntropy assuming reusing the existing table */ + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + + if (literalsCompressionIsDisabled) { + DEBUGLOG(5, "set_basic - disabled"); + hufMetadata->hType = set_basic; + return 0; + } + + /* small ? don't even attempt compression (speed opt) */ +#ifndef COMPRESS_LITERALS_SIZE_MIN +# define COMPRESS_LITERALS_SIZE_MIN 63 /* heuristic */ +#endif + { size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN; + if (srcSize <= minLitSize) { + DEBUGLOG(5, "set_basic - too small"); + hufMetadata->hType = set_basic; + return 0; + } } + + /* Scan input and build symbol stats */ + { size_t const largest = + HIST_count_wksp (countWksp, &maxSymbolValue, + (const BYTE*)src, srcSize, + workspace, wkspSize); + FORWARD_IF_ERROR(largest, "HIST_count_wksp failed"); + if (largest == srcSize) { + /* only one literal symbol */ + DEBUGLOG(5, "set_rle"); + hufMetadata->hType = set_rle; + return 0; + } + if (largest <= (srcSize >> 7)+4) { + /* heuristic: likely not compressible */ + DEBUGLOG(5, "set_basic - no gain"); + hufMetadata->hType = set_basic; + return 0; + } } + + /* Validate the previous Huffman table */ + if (repeat == HUF_repeat_check + && !HUF_validateCTable((HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue)) { + repeat = HUF_repeat_none; + } + + /* Build Huffman Tree */ + ZSTD_memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable)); + huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue, nodeWksp, nodeWkspSize, nextHuf->CTable, countWksp, hufFlags); + assert(huffLog <= LitHufLog); + { size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp, + maxSymbolValue, huffLog, + nodeWksp, nodeWkspSize); + FORWARD_IF_ERROR(maxBits, "HUF_buildCTable_wksp"); + huffLog = (U32)maxBits; + } + { /* Build and write the CTable */ + size_t const newCSize = HUF_estimateCompressedSize( + (HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue); + size_t const hSize = HUF_writeCTable_wksp( + hufMetadata->hufDesBuffer, sizeof(hufMetadata->hufDesBuffer), + (HUF_CElt*)nextHuf->CTable, maxSymbolValue, huffLog, + nodeWksp, nodeWkspSize); + /* Check against repeating the previous CTable */ + if (repeat != HUF_repeat_none) { + size_t const oldCSize = HUF_estimateCompressedSize( + (HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue); + if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) { + DEBUGLOG(5, "set_repeat - smaller"); + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + hufMetadata->hType = set_repeat; + return 0; + } } + if (newCSize + hSize >= srcSize) { + DEBUGLOG(5, "set_basic - no gains"); + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + hufMetadata->hType = set_basic; + return 0; + } + DEBUGLOG(5, "set_compressed (hSize=%u)", (U32)hSize); + hufMetadata->hType = set_compressed; + nextHuf->repeatMode = HUF_repeat_check; + return hSize; + } +} + + +/* ZSTD_buildDummySequencesStatistics(): + * Returns a ZSTD_symbolEncodingTypeStats_t with all encoding types as set_basic, + * and updates nextEntropy to the appropriate repeatMode. + */ +static ZSTD_symbolEncodingTypeStats_t +ZSTD_buildDummySequencesStatistics(ZSTD_fseCTables_t* nextEntropy) +{ + ZSTD_symbolEncodingTypeStats_t stats = {set_basic, set_basic, set_basic, 0, 0, 0}; + nextEntropy->litlength_repeatMode = FSE_repeat_none; + nextEntropy->offcode_repeatMode = FSE_repeat_none; + nextEntropy->matchlength_repeatMode = FSE_repeat_none; + return stats; +} + +/** ZSTD_buildBlockEntropyStats_sequences() : + * Builds entropy for the sequences. + * Stores symbol compression modes and fse table to fseMetadata. + * Requires ENTROPY_WORKSPACE_SIZE wksp. + * @return : size of fse tables or error code */ +static size_t +ZSTD_buildBlockEntropyStats_sequences( + const SeqStore_t* seqStorePtr, + const ZSTD_fseCTables_t* prevEntropy, + ZSTD_fseCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + ZSTD_fseCTablesMetadata_t* fseMetadata, + void* workspace, size_t wkspSize) +{ + ZSTD_strategy const strategy = cctxParams->cParams.strategy; + size_t const nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + BYTE* const ostart = fseMetadata->fseTablesBuffer; + BYTE* const oend = ostart + sizeof(fseMetadata->fseTablesBuffer); + BYTE* op = ostart; + unsigned* countWorkspace = (unsigned*)workspace; + unsigned* entropyWorkspace = countWorkspace + (MaxSeq + 1); + size_t entropyWorkspaceSize = wkspSize - (MaxSeq + 1) * sizeof(*countWorkspace); + ZSTD_symbolEncodingTypeStats_t stats; + + DEBUGLOG(5, "ZSTD_buildBlockEntropyStats_sequences (nbSeq=%zu)", nbSeq); + stats = nbSeq != 0 ? ZSTD_buildSequencesStatistics(seqStorePtr, nbSeq, + prevEntropy, nextEntropy, op, oend, + strategy, countWorkspace, + entropyWorkspace, entropyWorkspaceSize) + : ZSTD_buildDummySequencesStatistics(nextEntropy); + FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!"); + fseMetadata->llType = (SymbolEncodingType_e) stats.LLtype; + fseMetadata->ofType = (SymbolEncodingType_e) stats.Offtype; + fseMetadata->mlType = (SymbolEncodingType_e) stats.MLtype; + fseMetadata->lastCountSize = stats.lastCountSize; + return stats.size; +} + + +/** ZSTD_buildBlockEntropyStats() : + * Builds entropy for the block. + * Requires workspace size ENTROPY_WORKSPACE_SIZE + * @return : 0 on success, or an error code + * Note : also employed in superblock + */ +size_t ZSTD_buildBlockEntropyStats( + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + ZSTD_entropyCTablesMetadata_t* entropyMetadata, + void* workspace, size_t wkspSize) +{ + size_t const litSize = (size_t)(seqStorePtr->lit - seqStorePtr->litStart); + int const huf_useOptDepth = (cctxParams->cParams.strategy >= HUF_OPTIMAL_DEPTH_THRESHOLD); + int const hufFlags = huf_useOptDepth ? HUF_flags_optimalDepth : 0; + + entropyMetadata->hufMetadata.hufDesSize = + ZSTD_buildBlockEntropyStats_literals(seqStorePtr->litStart, litSize, + &prevEntropy->huf, &nextEntropy->huf, + &entropyMetadata->hufMetadata, + ZSTD_literalsCompressionIsDisabled(cctxParams), + workspace, wkspSize, hufFlags); + + FORWARD_IF_ERROR(entropyMetadata->hufMetadata.hufDesSize, "ZSTD_buildBlockEntropyStats_literals failed"); + entropyMetadata->fseMetadata.fseTablesSize = + ZSTD_buildBlockEntropyStats_sequences(seqStorePtr, + &prevEntropy->fse, &nextEntropy->fse, + cctxParams, + &entropyMetadata->fseMetadata, + workspace, wkspSize); + FORWARD_IF_ERROR(entropyMetadata->fseMetadata.fseTablesSize, "ZSTD_buildBlockEntropyStats_sequences failed"); + return 0; +} + +/* Returns the size estimate for the literals section (header + content) of a block */ +static size_t +ZSTD_estimateBlockSize_literal(const BYTE* literals, size_t litSize, + const ZSTD_hufCTables_t* huf, + const ZSTD_hufCTablesMetadata_t* hufMetadata, + void* workspace, size_t wkspSize, + int writeEntropy) +{ + unsigned* const countWksp = (unsigned*)workspace; + unsigned maxSymbolValue = HUF_SYMBOLVALUE_MAX; + size_t literalSectionHeaderSize = 3 + (litSize >= 1 KB) + (litSize >= 16 KB); + U32 singleStream = litSize < 256; + + if (hufMetadata->hType == set_basic) return litSize; + else if (hufMetadata->hType == set_rle) return 1; + else if (hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat) { + size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)literals, litSize, workspace, wkspSize); + if (ZSTD_isError(largest)) return litSize; + { size_t cLitSizeEstimate = HUF_estimateCompressedSize((const HUF_CElt*)huf->CTable, countWksp, maxSymbolValue); + if (writeEntropy) cLitSizeEstimate += hufMetadata->hufDesSize; + if (!singleStream) cLitSizeEstimate += 6; /* multi-stream huffman uses 6-byte jump table */ + return cLitSizeEstimate + literalSectionHeaderSize; + } } + assert(0); /* impossible */ + return 0; +} + +/* Returns the size estimate for the FSE-compressed symbols (of, ml, ll) of a block */ +static size_t +ZSTD_estimateBlockSize_symbolType(SymbolEncodingType_e type, + const BYTE* codeTable, size_t nbSeq, unsigned maxCode, + const FSE_CTable* fseCTable, + const U8* additionalBits, + short const* defaultNorm, U32 defaultNormLog, U32 defaultMax, + void* workspace, size_t wkspSize) +{ + unsigned* const countWksp = (unsigned*)workspace; + const BYTE* ctp = codeTable; + const BYTE* const ctStart = ctp; + const BYTE* const ctEnd = ctStart + nbSeq; + size_t cSymbolTypeSizeEstimateInBits = 0; + unsigned max = maxCode; + + HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */ + if (type == set_basic) { + /* We selected this encoding type, so it must be valid. */ + assert(max <= defaultMax); + (void)defaultMax; + cSymbolTypeSizeEstimateInBits = ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max); + } else if (type == set_rle) { + cSymbolTypeSizeEstimateInBits = 0; + } else if (type == set_compressed || type == set_repeat) { + cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max); + } + if (ZSTD_isError(cSymbolTypeSizeEstimateInBits)) { + return nbSeq * 10; + } + while (ctp < ctEnd) { + if (additionalBits) cSymbolTypeSizeEstimateInBits += additionalBits[*ctp]; + else cSymbolTypeSizeEstimateInBits += *ctp; /* for offset, offset code is also the number of additional bits */ + ctp++; + } + return cSymbolTypeSizeEstimateInBits >> 3; +} + +/* Returns the size estimate for the sequences section (header + content) of a block */ +static size_t +ZSTD_estimateBlockSize_sequences(const BYTE* ofCodeTable, + const BYTE* llCodeTable, + const BYTE* mlCodeTable, + size_t nbSeq, + const ZSTD_fseCTables_t* fseTables, + const ZSTD_fseCTablesMetadata_t* fseMetadata, + void* workspace, size_t wkspSize, + int writeEntropy) +{ + size_t sequencesSectionHeaderSize = 1 /* seqHead */ + 1 /* min seqSize size */ + (nbSeq >= 128) + (nbSeq >= LONGNBSEQ); + size_t cSeqSizeEstimate = 0; + cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, nbSeq, MaxOff, + fseTables->offcodeCTable, NULL, + OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, + workspace, wkspSize); + cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->llType, llCodeTable, nbSeq, MaxLL, + fseTables->litlengthCTable, LL_bits, + LL_defaultNorm, LL_defaultNormLog, MaxLL, + workspace, wkspSize); + cSeqSizeEstimate += ZSTD_estimateBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, nbSeq, MaxML, + fseTables->matchlengthCTable, ML_bits, + ML_defaultNorm, ML_defaultNormLog, MaxML, + workspace, wkspSize); + if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize; + return cSeqSizeEstimate + sequencesSectionHeaderSize; +} + +/* Returns the size estimate for a given stream of literals, of, ll, ml */ +static size_t +ZSTD_estimateBlockSize(const BYTE* literals, size_t litSize, + const BYTE* ofCodeTable, + const BYTE* llCodeTable, + const BYTE* mlCodeTable, + size_t nbSeq, + const ZSTD_entropyCTables_t* entropy, + const ZSTD_entropyCTablesMetadata_t* entropyMetadata, + void* workspace, size_t wkspSize, + int writeLitEntropy, int writeSeqEntropy) +{ + size_t const literalsSize = ZSTD_estimateBlockSize_literal(literals, litSize, + &entropy->huf, &entropyMetadata->hufMetadata, + workspace, wkspSize, writeLitEntropy); + size_t const seqSize = ZSTD_estimateBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable, + nbSeq, &entropy->fse, &entropyMetadata->fseMetadata, + workspace, wkspSize, writeSeqEntropy); + return seqSize + literalsSize + ZSTD_blockHeaderSize; +} + +/* Builds entropy statistics and uses them for blocksize estimation. + * + * @return: estimated compressed size of the seqStore, or a zstd error. + */ +static size_t +ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(SeqStore_t* seqStore, ZSTD_CCtx* zc) +{ + ZSTD_entropyCTablesMetadata_t* const entropyMetadata = &zc->blockSplitCtx.entropyMetadata; + DEBUGLOG(6, "ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize()"); + FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(seqStore, + &zc->blockState.prevCBlock->entropy, + &zc->blockState.nextCBlock->entropy, + &zc->appliedParams, + entropyMetadata, + zc->tmpWorkspace, zc->tmpWkspSize), ""); + return ZSTD_estimateBlockSize( + seqStore->litStart, (size_t)(seqStore->lit - seqStore->litStart), + seqStore->ofCode, seqStore->llCode, seqStore->mlCode, + (size_t)(seqStore->sequences - seqStore->sequencesStart), + &zc->blockState.nextCBlock->entropy, + entropyMetadata, + zc->tmpWorkspace, zc->tmpWkspSize, + (int)(entropyMetadata->hufMetadata.hType == set_compressed), 1); +} + +/* Returns literals bytes represented in a seqStore */ +static size_t ZSTD_countSeqStoreLiteralsBytes(const SeqStore_t* const seqStore) +{ + size_t literalsBytes = 0; + size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart); + size_t i; + for (i = 0; i < nbSeqs; ++i) { + SeqDef const seq = seqStore->sequencesStart[i]; + literalsBytes += seq.litLength; + if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_literalLength) { + literalsBytes += 0x10000; + } } + return literalsBytes; +} + +/* Returns match bytes represented in a seqStore */ +static size_t ZSTD_countSeqStoreMatchBytes(const SeqStore_t* const seqStore) +{ + size_t matchBytes = 0; + size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart); + size_t i; + for (i = 0; i < nbSeqs; ++i) { + SeqDef seq = seqStore->sequencesStart[i]; + matchBytes += seq.mlBase + MINMATCH; + if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_matchLength) { + matchBytes += 0x10000; + } } + return matchBytes; +} + +/* Derives the seqStore that is a chunk of the originalSeqStore from [startIdx, endIdx). + * Stores the result in resultSeqStore. + */ +static void ZSTD_deriveSeqStoreChunk(SeqStore_t* resultSeqStore, + const SeqStore_t* originalSeqStore, + size_t startIdx, size_t endIdx) +{ + *resultSeqStore = *originalSeqStore; + if (startIdx > 0) { + resultSeqStore->sequences = originalSeqStore->sequencesStart + startIdx; + resultSeqStore->litStart += ZSTD_countSeqStoreLiteralsBytes(resultSeqStore); + } + + /* Move longLengthPos into the correct position if necessary */ + if (originalSeqStore->longLengthType != ZSTD_llt_none) { + if (originalSeqStore->longLengthPos < startIdx || originalSeqStore->longLengthPos > endIdx) { + resultSeqStore->longLengthType = ZSTD_llt_none; + } else { + resultSeqStore->longLengthPos -= (U32)startIdx; + } + } + resultSeqStore->sequencesStart = originalSeqStore->sequencesStart + startIdx; + resultSeqStore->sequences = originalSeqStore->sequencesStart + endIdx; + if (endIdx == (size_t)(originalSeqStore->sequences - originalSeqStore->sequencesStart)) { + /* This accounts for possible last literals if the derived chunk reaches the end of the block */ + assert(resultSeqStore->lit == originalSeqStore->lit); + } else { + size_t const literalsBytes = ZSTD_countSeqStoreLiteralsBytes(resultSeqStore); + resultSeqStore->lit = resultSeqStore->litStart + literalsBytes; + } + resultSeqStore->llCode += startIdx; + resultSeqStore->mlCode += startIdx; + resultSeqStore->ofCode += startIdx; +} + +/** + * Returns the raw offset represented by the combination of offBase, ll0, and repcode history. + * offBase must represent a repcode in the numeric representation of ZSTD_storeSeq(). + */ +static U32 +ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32 offBase, const U32 ll0) +{ + U32 const adjustedRepCode = OFFBASE_TO_REPCODE(offBase) - 1 + ll0; /* [ 0 - 3 ] */ + assert(OFFBASE_IS_REPCODE(offBase)); + if (adjustedRepCode == ZSTD_REP_NUM) { + assert(ll0); + /* litlength == 0 and offCode == 2 implies selection of first repcode - 1 + * This is only valid if it results in a valid offset value, aka > 0. + * Note : it may happen that `rep[0]==1` in exceptional circumstances. + * In which case this function will return 0, which is an invalid offset. + * It's not an issue though, since this value will be + * compared and discarded within ZSTD_seqStore_resolveOffCodes(). + */ + return rep[0] - 1; + } + return rep[adjustedRepCode]; +} + +/** + * ZSTD_seqStore_resolveOffCodes() reconciles any possible divergences in offset history that may arise + * due to emission of RLE/raw blocks that disturb the offset history, + * and replaces any repcodes within the seqStore that may be invalid. + * + * dRepcodes are updated as would be on the decompression side. + * cRepcodes are updated exactly in accordance with the seqStore. + * + * Note : this function assumes seq->offBase respects the following numbering scheme : + * 0 : invalid + * 1-3 : repcode 1-3 + * 4+ : real_offset+3 + */ +static void +ZSTD_seqStore_resolveOffCodes(Repcodes_t* const dRepcodes, Repcodes_t* const cRepcodes, + const SeqStore_t* const seqStore, U32 const nbSeq) +{ + U32 idx = 0; + U32 const longLitLenIdx = seqStore->longLengthType == ZSTD_llt_literalLength ? seqStore->longLengthPos : nbSeq; + for (; idx < nbSeq; ++idx) { + SeqDef* const seq = seqStore->sequencesStart + idx; + U32 const ll0 = (seq->litLength == 0) && (idx != longLitLenIdx); + U32 const offBase = seq->offBase; + assert(offBase > 0); + if (OFFBASE_IS_REPCODE(offBase)) { + U32 const dRawOffset = ZSTD_resolveRepcodeToRawOffset(dRepcodes->rep, offBase, ll0); + U32 const cRawOffset = ZSTD_resolveRepcodeToRawOffset(cRepcodes->rep, offBase, ll0); + /* Adjust simulated decompression repcode history if we come across a mismatch. Replace + * the repcode with the offset it actually references, determined by the compression + * repcode history. + */ + if (dRawOffset != cRawOffset) { + seq->offBase = OFFSET_TO_OFFBASE(cRawOffset); + } + } + /* Compression repcode history is always updated with values directly from the unmodified seqStore. + * Decompression repcode history may use modified seq->offset value taken from compression repcode history. + */ + ZSTD_updateRep(dRepcodes->rep, seq->offBase, ll0); + ZSTD_updateRep(cRepcodes->rep, offBase, ll0); + } +} + +/* ZSTD_compressSeqStore_singleBlock(): + * Compresses a seqStore into a block with a block header, into the buffer dst. + * + * Returns the total size of that block (including header) or a ZSTD error code. + */ +static size_t +ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc, + const SeqStore_t* const seqStore, + Repcodes_t* const dRep, Repcodes_t* const cRep, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + U32 lastBlock, U32 isPartition) +{ + const U32 rleMaxLength = 25; + BYTE* op = (BYTE*)dst; + const BYTE* ip = (const BYTE*)src; + size_t cSize; + size_t cSeqsSize; + + /* In case of an RLE or raw block, the simulated decompression repcode history must be reset */ + Repcodes_t const dRepOriginal = *dRep; + DEBUGLOG(5, "ZSTD_compressSeqStore_singleBlock"); + if (isPartition) + ZSTD_seqStore_resolveOffCodes(dRep, cRep, seqStore, (U32)(seqStore->sequences - seqStore->sequencesStart)); + + RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall, "Block header doesn't fit"); + cSeqsSize = ZSTD_entropyCompressSeqStore(seqStore, + &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, + &zc->appliedParams, + op + ZSTD_blockHeaderSize, dstCapacity - ZSTD_blockHeaderSize, + srcSize, + zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */, + zc->bmi2); + FORWARD_IF_ERROR(cSeqsSize, "ZSTD_entropyCompressSeqStore failed!"); + + if (!zc->isFirstBlock && + cSeqsSize < rleMaxLength && + ZSTD_isRLE((BYTE const*)src, srcSize)) { + /* We don't want to emit our first block as a RLE even if it qualifies because + * doing so will cause the decoder (cli only) to throw a "should consume all input error." + * This is only an issue for zstd <= v1.4.3 + */ + cSeqsSize = 1; + } + + /* Sequence collection not supported when block splitting */ + if (zc->seqCollector.collectSequences) { + FORWARD_IF_ERROR(ZSTD_copyBlockSequences(&zc->seqCollector, seqStore, dRepOriginal.rep), "copyBlockSequences failed"); + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + return 0; + } + + if (cSeqsSize == 0) { + cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, srcSize, lastBlock); + FORWARD_IF_ERROR(cSize, "Nocompress block failed"); + DEBUGLOG(5, "Writing out nocompress block, size: %zu", cSize); + *dRep = dRepOriginal; /* reset simulated decompression repcode history */ + } else if (cSeqsSize == 1) { + cSize = ZSTD_rleCompressBlock(op, dstCapacity, *ip, srcSize, lastBlock); + FORWARD_IF_ERROR(cSize, "RLE compress block failed"); + DEBUGLOG(5, "Writing out RLE block, size: %zu", cSize); + *dRep = dRepOriginal; /* reset simulated decompression repcode history */ + } else { + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + writeBlockHeader(op, cSeqsSize, srcSize, lastBlock); + cSize = ZSTD_blockHeaderSize + cSeqsSize; + DEBUGLOG(5, "Writing out compressed block, size: %zu", cSize); + } + + if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + + return cSize; +} + +/* Struct to keep track of where we are in our recursive calls. */ +typedef struct { + U32* splitLocations; /* Array of split indices */ + size_t idx; /* The current index within splitLocations being worked on */ +} seqStoreSplits; + +#define MIN_SEQUENCES_BLOCK_SPLITTING 300 + +/* Helper function to perform the recursive search for block splits. + * Estimates the cost of seqStore prior to split, and estimates the cost of splitting the sequences in half. + * If advantageous to split, then we recurse down the two sub-blocks. + * If not, or if an error occurred in estimation, then we do not recurse. + * + * Note: The recursion depth is capped by a heuristic minimum number of sequences, + * defined by MIN_SEQUENCES_BLOCK_SPLITTING. + * In theory, this means the absolute largest recursion depth is 10 == log2(maxNbSeqInBlock/MIN_SEQUENCES_BLOCK_SPLITTING). + * In practice, recursion depth usually doesn't go beyond 4. + * + * Furthermore, the number of splits is capped by ZSTD_MAX_NB_BLOCK_SPLITS. + * At ZSTD_MAX_NB_BLOCK_SPLITS == 196 with the current existing blockSize + * maximum of 128 KB, this value is actually impossible to reach. + */ +static void +ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t endIdx, + ZSTD_CCtx* zc, const SeqStore_t* origSeqStore) +{ + SeqStore_t* const fullSeqStoreChunk = &zc->blockSplitCtx.fullSeqStoreChunk; + SeqStore_t* const firstHalfSeqStore = &zc->blockSplitCtx.firstHalfSeqStore; + SeqStore_t* const secondHalfSeqStore = &zc->blockSplitCtx.secondHalfSeqStore; + size_t estimatedOriginalSize; + size_t estimatedFirstHalfSize; + size_t estimatedSecondHalfSize; + size_t midIdx = (startIdx + endIdx)/2; + + DEBUGLOG(5, "ZSTD_deriveBlockSplitsHelper: startIdx=%zu endIdx=%zu", startIdx, endIdx); + assert(endIdx >= startIdx); + if (endIdx - startIdx < MIN_SEQUENCES_BLOCK_SPLITTING || splits->idx >= ZSTD_MAX_NB_BLOCK_SPLITS) { + DEBUGLOG(6, "ZSTD_deriveBlockSplitsHelper: Too few sequences (%zu)", endIdx - startIdx); + return; + } + ZSTD_deriveSeqStoreChunk(fullSeqStoreChunk, origSeqStore, startIdx, endIdx); + ZSTD_deriveSeqStoreChunk(firstHalfSeqStore, origSeqStore, startIdx, midIdx); + ZSTD_deriveSeqStoreChunk(secondHalfSeqStore, origSeqStore, midIdx, endIdx); + estimatedOriginalSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(fullSeqStoreChunk, zc); + estimatedFirstHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(firstHalfSeqStore, zc); + estimatedSecondHalfSize = ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(secondHalfSeqStore, zc); + DEBUGLOG(5, "Estimated original block size: %zu -- First half split: %zu -- Second half split: %zu", + estimatedOriginalSize, estimatedFirstHalfSize, estimatedSecondHalfSize); + if (ZSTD_isError(estimatedOriginalSize) || ZSTD_isError(estimatedFirstHalfSize) || ZSTD_isError(estimatedSecondHalfSize)) { + return; + } + if (estimatedFirstHalfSize + estimatedSecondHalfSize < estimatedOriginalSize) { + DEBUGLOG(5, "split decided at seqNb:%zu", midIdx); + ZSTD_deriveBlockSplitsHelper(splits, startIdx, midIdx, zc, origSeqStore); + splits->splitLocations[splits->idx] = (U32)midIdx; + splits->idx++; + ZSTD_deriveBlockSplitsHelper(splits, midIdx, endIdx, zc, origSeqStore); + } +} + +/* Base recursive function. + * Populates a table with intra-block partition indices that can improve compression ratio. + * + * @return: number of splits made (which equals the size of the partition table - 1). + */ +static size_t ZSTD_deriveBlockSplits(ZSTD_CCtx* zc, U32 partitions[], U32 nbSeq) +{ + seqStoreSplits splits; + splits.splitLocations = partitions; + splits.idx = 0; + if (nbSeq <= 4) { + DEBUGLOG(5, "ZSTD_deriveBlockSplits: Too few sequences to split (%u <= 4)", nbSeq); + /* Refuse to try and split anything with less than 4 sequences */ + return 0; + } + ZSTD_deriveBlockSplitsHelper(&splits, 0, nbSeq, zc, &zc->seqStore); + splits.splitLocations[splits.idx] = nbSeq; + DEBUGLOG(5, "ZSTD_deriveBlockSplits: final nb partitions: %zu", splits.idx+1); + return splits.idx; +} + +/* ZSTD_compressBlock_splitBlock(): + * Attempts to split a given block into multiple blocks to improve compression ratio. + * + * Returns combined size of all blocks (which includes headers), or a ZSTD error code. + */ +static size_t +ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t blockSize, + U32 lastBlock, U32 nbSeq) +{ + size_t cSize = 0; + const BYTE* ip = (const BYTE*)src; + BYTE* op = (BYTE*)dst; + size_t i = 0; + size_t srcBytesTotal = 0; + U32* const partitions = zc->blockSplitCtx.partitions; /* size == ZSTD_MAX_NB_BLOCK_SPLITS */ + SeqStore_t* const nextSeqStore = &zc->blockSplitCtx.nextSeqStore; + SeqStore_t* const currSeqStore = &zc->blockSplitCtx.currSeqStore; + size_t const numSplits = ZSTD_deriveBlockSplits(zc, partitions, nbSeq); + + /* If a block is split and some partitions are emitted as RLE/uncompressed, then repcode history + * may become invalid. In order to reconcile potentially invalid repcodes, we keep track of two + * separate repcode histories that simulate repcode history on compression and decompression side, + * and use the histories to determine whether we must replace a particular repcode with its raw offset. + * + * 1) cRep gets updated for each partition, regardless of whether the block was emitted as uncompressed + * or RLE. This allows us to retrieve the offset value that an invalid repcode references within + * a nocompress/RLE block. + * 2) dRep gets updated only for compressed partitions, and when a repcode gets replaced, will use + * the replacement offset value rather than the original repcode to update the repcode history. + * dRep also will be the final repcode history sent to the next block. + * + * See ZSTD_seqStore_resolveOffCodes() for more details. + */ + Repcodes_t dRep; + Repcodes_t cRep; + ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof(Repcodes_t)); + ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(Repcodes_t)); + ZSTD_memset(nextSeqStore, 0, sizeof(SeqStore_t)); + + DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)", + (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, + (unsigned)zc->blockState.matchState.nextToUpdate); + + if (numSplits == 0) { + size_t cSizeSingleBlock = + ZSTD_compressSeqStore_singleBlock(zc, &zc->seqStore, + &dRep, &cRep, + op, dstCapacity, + ip, blockSize, + lastBlock, 0 /* isPartition */); + FORWARD_IF_ERROR(cSizeSingleBlock, "Compressing single block from splitBlock_internal() failed!"); + DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal: No splits"); + assert(zc->blockSizeMax <= ZSTD_BLOCKSIZE_MAX); + assert(cSizeSingleBlock <= zc->blockSizeMax + ZSTD_blockHeaderSize); + return cSizeSingleBlock; + } + + ZSTD_deriveSeqStoreChunk(currSeqStore, &zc->seqStore, 0, partitions[0]); + for (i = 0; i <= numSplits; ++i) { + size_t cSizeChunk; + U32 const lastPartition = (i == numSplits); + U32 lastBlockEntireSrc = 0; + + size_t srcBytes = ZSTD_countSeqStoreLiteralsBytes(currSeqStore) + ZSTD_countSeqStoreMatchBytes(currSeqStore); + srcBytesTotal += srcBytes; + if (lastPartition) { + /* This is the final partition, need to account for possible last literals */ + srcBytes += blockSize - srcBytesTotal; + lastBlockEntireSrc = lastBlock; + } else { + ZSTD_deriveSeqStoreChunk(nextSeqStore, &zc->seqStore, partitions[i], partitions[i+1]); + } + + cSizeChunk = ZSTD_compressSeqStore_singleBlock(zc, currSeqStore, + &dRep, &cRep, + op, dstCapacity, + ip, srcBytes, + lastBlockEntireSrc, 1 /* isPartition */); + DEBUGLOG(5, "Estimated size: %zu vs %zu : actual size", + ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(currSeqStore, zc), cSizeChunk); + FORWARD_IF_ERROR(cSizeChunk, "Compressing chunk failed!"); + + ip += srcBytes; + op += cSizeChunk; + dstCapacity -= cSizeChunk; + cSize += cSizeChunk; + *currSeqStore = *nextSeqStore; + assert(cSizeChunk <= zc->blockSizeMax + ZSTD_blockHeaderSize); + } + /* cRep and dRep may have diverged during the compression. + * If so, we use the dRep repcodes for the next block. + */ + ZSTD_memcpy(zc->blockState.prevCBlock->rep, dRep.rep, sizeof(Repcodes_t)); + return cSize; +} + +static size_t +ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, U32 lastBlock) +{ + U32 nbSeq; + size_t cSize; + DEBUGLOG(5, "ZSTD_compressBlock_splitBlock"); + assert(zc->appliedParams.postBlockSplitter == ZSTD_ps_enable); + + { const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize); + FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed"); + if (bss == ZSTDbss_noCompress) { + if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + RETURN_ERROR_IF(zc->seqCollector.collectSequences, sequenceProducer_failed, "Uncompressible block"); + cSize = ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed"); + DEBUGLOG(5, "ZSTD_compressBlock_splitBlock: Nocompress block"); + return cSize; + } + nbSeq = (U32)(zc->seqStore.sequences - zc->seqStore.sequencesStart); + } + + cSize = ZSTD_compressBlock_splitBlock_internal(zc, dst, dstCapacity, src, srcSize, lastBlock, nbSeq); + FORWARD_IF_ERROR(cSize, "Splitting blocks failed!"); + return cSize; +} + +static size_t +ZSTD_compressBlock_internal(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, U32 frame) +{ + /* This is an estimated upper bound for the length of an rle block. + * This isn't the actual upper bound. + * Finding the real threshold needs further investigation. + */ + const U32 rleMaxLength = 25; + size_t cSize; + const BYTE* ip = (const BYTE*)src; + BYTE* op = (BYTE*)dst; + DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)", + (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, + (unsigned)zc->blockState.matchState.nextToUpdate); + + { const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize); + FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed"); + if (bss == ZSTDbss_noCompress) { + RETURN_ERROR_IF(zc->seqCollector.collectSequences, sequenceProducer_failed, "Uncompressible block"); + cSize = 0; + goto out; + } + } + + if (zc->seqCollector.collectSequences) { + FORWARD_IF_ERROR(ZSTD_copyBlockSequences(&zc->seqCollector, ZSTD_getSeqStore(zc), zc->blockState.prevCBlock->rep), "copyBlockSequences failed"); + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + return 0; + } + + /* encode sequences and literals */ + cSize = ZSTD_entropyCompressSeqStore(&zc->seqStore, + &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy, + &zc->appliedParams, + dst, dstCapacity, + srcSize, + zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */, + zc->bmi2); + + if (frame && + /* We don't want to emit our first block as a RLE even if it qualifies because + * doing so will cause the decoder (cli only) to throw a "should consume all input error." + * This is only an issue for zstd <= v1.4.3 + */ + !zc->isFirstBlock && + cSize < rleMaxLength && + ZSTD_isRLE(ip, srcSize)) + { + cSize = 1; + op[0] = ip[0]; + } + +out: + if (!ZSTD_isError(cSize) && cSize > 1) { + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + } + /* We check that dictionaries have offset codes available for the first + * block. After the first block, the offcode table might not have large + * enough codes to represent the offsets in the data. + */ + if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + + return cSize; +} + +static size_t ZSTD_compressBlock_targetCBlockSize_body(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const size_t bss, U32 lastBlock) +{ + DEBUGLOG(6, "Attempting ZSTD_compressSuperBlock()"); + if (bss == ZSTDbss_compress) { + if (/* We don't want to emit our first block as a RLE even if it qualifies because + * doing so will cause the decoder (cli only) to throw a "should consume all input error." + * This is only an issue for zstd <= v1.4.3 + */ + !zc->isFirstBlock && + ZSTD_maybeRLE(&zc->seqStore) && + ZSTD_isRLE((BYTE const*)src, srcSize)) + { + return ZSTD_rleCompressBlock(dst, dstCapacity, *(BYTE const*)src, srcSize, lastBlock); + } + /* Attempt superblock compression. + * + * Note that compressed size of ZSTD_compressSuperBlock() is not bound by the + * standard ZSTD_compressBound(). This is a problem, because even if we have + * space now, taking an extra byte now could cause us to run out of space later + * and violate ZSTD_compressBound(). + * + * Define blockBound(blockSize) = blockSize + ZSTD_blockHeaderSize. + * + * In order to respect ZSTD_compressBound() we must attempt to emit a raw + * uncompressed block in these cases: + * * cSize == 0: Return code for an uncompressed block. + * * cSize == dstSize_tooSmall: We may have expanded beyond blockBound(srcSize). + * ZSTD_noCompressBlock() will return dstSize_tooSmall if we are really out of + * output space. + * * cSize >= blockBound(srcSize): We have expanded the block too much so + * emit an uncompressed block. + */ + { size_t const cSize = + ZSTD_compressSuperBlock(zc, dst, dstCapacity, src, srcSize, lastBlock); + if (cSize != ERROR(dstSize_tooSmall)) { + size_t const maxCSize = + srcSize - ZSTD_minGain(srcSize, zc->appliedParams.cParams.strategy); + FORWARD_IF_ERROR(cSize, "ZSTD_compressSuperBlock failed"); + if (cSize != 0 && cSize < maxCSize + ZSTD_blockHeaderSize) { + ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState); + return cSize; + } + } + } + } /* if (bss == ZSTDbss_compress)*/ + + DEBUGLOG(6, "Resorting to ZSTD_noCompressBlock()"); + /* Superblock compression failed, attempt to emit a single no compress block. + * The decoder will be able to stream this block since it is uncompressed. + */ + return ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock); +} + +static size_t ZSTD_compressBlock_targetCBlockSize(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + U32 lastBlock) +{ + size_t cSize = 0; + const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize); + DEBUGLOG(5, "ZSTD_compressBlock_targetCBlockSize (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u, srcSize=%zu)", + (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit, (unsigned)zc->blockState.matchState.nextToUpdate, srcSize); + FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed"); + + cSize = ZSTD_compressBlock_targetCBlockSize_body(zc, dst, dstCapacity, src, srcSize, bss, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize_body failed"); + + if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid) + zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check; + + return cSize; +} + +static void ZSTD_overflowCorrectIfNeeded(ZSTD_MatchState_t* ms, + ZSTD_cwksp* ws, + ZSTD_CCtx_params const* params, + void const* ip, + void const* iend) +{ + U32 const cycleLog = ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy); + U32 const maxDist = (U32)1 << params->cParams.windowLog; + if (ZSTD_window_needOverflowCorrection(ms->window, cycleLog, maxDist, ms->loadedDictEnd, ip, iend)) { + U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip); + ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30); + ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30); + ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31); + ZSTD_cwksp_mark_tables_dirty(ws); + ZSTD_reduceIndex(ms, params, correction); + ZSTD_cwksp_mark_tables_clean(ws); + if (ms->nextToUpdate < correction) ms->nextToUpdate = 0; + else ms->nextToUpdate -= correction; + /* invalidate dictionaries on overflow correction */ + ms->loadedDictEnd = 0; + ms->dictMatchState = NULL; + } +} + +#include "zstd_preSplit.h" + +static size_t ZSTD_optimalBlockSize(ZSTD_CCtx* cctx, const void* src, size_t srcSize, size_t blockSizeMax, int splitLevel, ZSTD_strategy strat, S64 savings) +{ + /* split level based on compression strategy, from `fast` to `btultra2` */ + static const int splitLevels[] = { 0, 0, 1, 2, 2, 3, 3, 4, 4, 4 }; + /* note: conservatively only split full blocks (128 KB) currently. + * While it's possible to go lower, let's keep it simple for a first implementation. + * Besides, benefits of splitting are reduced when blocks are already small. + */ + if (srcSize < 128 KB || blockSizeMax < 128 KB) + return MIN(srcSize, blockSizeMax); + /* do not split incompressible data though: + * require verified savings to allow pre-splitting. + * Note: as a consequence, the first full block is not split. + */ + if (savings < 3) { + DEBUGLOG(6, "don't attempt splitting: savings (%i) too low", (int)savings); + return 128 KB; + } + /* apply @splitLevel, or use default value (which depends on @strat). + * note that splitting heuristic is still conditioned by @savings >= 3, + * so the first block will not reach this code path */ + if (splitLevel == 1) return 128 KB; + if (splitLevel == 0) { + assert(ZSTD_fast <= strat && strat <= ZSTD_btultra2); + splitLevel = splitLevels[strat]; + } else { + assert(2 <= splitLevel && splitLevel <= 6); + splitLevel -= 2; + } + return ZSTD_splitBlock(src, blockSizeMax, splitLevel, cctx->tmpWorkspace, cctx->tmpWkspSize); +} + +/*! ZSTD_compress_frameChunk() : +* Compress a chunk of data into one or multiple blocks. +* All blocks will be terminated, all input will be consumed. +* Function will issue an error if there is not enough `dstCapacity` to hold the compressed content. +* Frame is supposed already started (header already produced) +* @return : compressed size, or an error code +*/ +static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + U32 lastFrameChunk) +{ + size_t blockSizeMax = cctx->blockSizeMax; + size_t remaining = srcSize; + const BYTE* ip = (const BYTE*)src; + BYTE* const ostart = (BYTE*)dst; + BYTE* op = ostart; + U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog; + S64 savings = (S64)cctx->consumedSrcSize - (S64)cctx->producedCSize; + + assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX); + + DEBUGLOG(5, "ZSTD_compress_frameChunk (srcSize=%u, blockSizeMax=%u)", (unsigned)srcSize, (unsigned)blockSizeMax); + if (cctx->appliedParams.fParams.checksumFlag && srcSize) + XXH64_update(&cctx->xxhState, src, srcSize); + + while (remaining) { + ZSTD_MatchState_t* const ms = &cctx->blockState.matchState; + size_t const blockSize = ZSTD_optimalBlockSize(cctx, + ip, remaining, + blockSizeMax, + cctx->appliedParams.preBlockSplitter_level, + cctx->appliedParams.cParams.strategy, + savings); + U32 const lastBlock = lastFrameChunk & (blockSize == remaining); + assert(blockSize <= remaining); + + /* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding + * additional 1. We need to revisit and change this logic to be more consistent */ + RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE + 1, + dstSize_tooSmall, + "not enough space to store compressed block"); + + ZSTD_overflowCorrectIfNeeded( + ms, &cctx->workspace, &cctx->appliedParams, ip, ip + blockSize); + ZSTD_checkDictValidity(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState); + ZSTD_window_enforceMaxDist(&ms->window, ip, maxDist, &ms->loadedDictEnd, &ms->dictMatchState); + + /* Ensure hash/chain table insertion resumes no sooner than lowlimit */ + if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit; + + { size_t cSize; + if (ZSTD_useTargetCBlockSize(&cctx->appliedParams)) { + cSize = ZSTD_compressBlock_targetCBlockSize(cctx, op, dstCapacity, ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_targetCBlockSize failed"); + assert(cSize > 0); + assert(cSize <= blockSize + ZSTD_blockHeaderSize); + } else if (ZSTD_blockSplitterEnabled(&cctx->appliedParams)) { + cSize = ZSTD_compressBlock_splitBlock(cctx, op, dstCapacity, ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_splitBlock failed"); + assert(cSize > 0 || cctx->seqCollector.collectSequences == 1); + } else { + cSize = ZSTD_compressBlock_internal(cctx, + op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, + ip, blockSize, 1 /* frame */); + FORWARD_IF_ERROR(cSize, "ZSTD_compressBlock_internal failed"); + + if (cSize == 0) { /* block is not compressible */ + cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed"); + } else { + U32 const cBlockHeader = cSize == 1 ? + lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) : + lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3); + MEM_writeLE24(op, cBlockHeader); + cSize += ZSTD_blockHeaderSize; + } + } /* if (ZSTD_useTargetCBlockSize(&cctx->appliedParams))*/ + + /* @savings is employed to ensure that splitting doesn't worsen expansion of incompressible data. + * Without splitting, the maximum expansion is 3 bytes per full block. + * An adversarial input could attempt to fudge the split detector, + * and make it split incompressible data, resulting in more block headers. + * Note that, since ZSTD_COMPRESSBOUND() assumes a worst case scenario of 1KB per block, + * and the splitter never creates blocks that small (current lower limit is 8 KB), + * there is already no risk to expand beyond ZSTD_COMPRESSBOUND() limit. + * But if the goal is to not expand by more than 3-bytes per 128 KB full block, + * then yes, it becomes possible to make the block splitter oversplit incompressible data. + * Using @savings, we enforce an even more conservative condition, + * requiring the presence of enough savings (at least 3 bytes) to authorize splitting, + * otherwise only full blocks are used. + * But being conservative is fine, + * since splitting barely compressible blocks is not fruitful anyway */ + savings += (S64)blockSize - (S64)cSize; + + ip += blockSize; + assert(remaining >= blockSize); + remaining -= blockSize; + op += cSize; + assert(dstCapacity >= cSize); + dstCapacity -= cSize; + cctx->isFirstBlock = 0; + DEBUGLOG(5, "ZSTD_compress_frameChunk: adding a block of size %u", + (unsigned)cSize); + } } + + if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending; + return (size_t)(op-ostart); +} + + +static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity, + const ZSTD_CCtx_params* params, + U64 pledgedSrcSize, U32 dictID) +{ + BYTE* const op = (BYTE*)dst; + U32 const dictIDSizeCodeLength = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */ + U32 const dictIDSizeCode = params->fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength; /* 0-3 */ + U32 const checksumFlag = params->fParams.checksumFlag>0; + U32 const windowSize = (U32)1 << params->cParams.windowLog; + U32 const singleSegment = params->fParams.contentSizeFlag && (windowSize >= pledgedSrcSize); + BYTE const windowLogByte = (BYTE)((params->cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3); + U32 const fcsCode = params->fParams.contentSizeFlag ? + (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0; /* 0-3 */ + BYTE const frameHeaderDescriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) ); + size_t pos=0; + + assert(!(params->fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)); + RETURN_ERROR_IF(dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX, dstSize_tooSmall, + "dst buf is too small to fit worst-case frame header size."); + DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u", + !params->fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode); + if (params->format == ZSTD_f_zstd1) { + MEM_writeLE32(dst, ZSTD_MAGICNUMBER); + pos = 4; + } + op[pos++] = frameHeaderDescriptionByte; + if (!singleSegment) op[pos++] = windowLogByte; + switch(dictIDSizeCode) + { + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; + case 0 : break; + case 1 : op[pos] = (BYTE)(dictID); pos++; break; + case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break; + case 3 : MEM_writeLE32(op+pos, dictID); pos+=4; break; + } + switch(fcsCode) + { + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; + case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break; + case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break; + case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break; + case 3 : MEM_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break; + } + return pos; +} + +/* ZSTD_writeSkippableFrame_advanced() : + * Writes out a skippable frame with the specified magic number variant (16 are supported), + * from ZSTD_MAGIC_SKIPPABLE_START to ZSTD_MAGIC_SKIPPABLE_START+15, and the desired source data. + * + * Returns the total number of bytes written, or a ZSTD error code. + */ +size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity, + const void* src, size_t srcSize, unsigned magicVariant) { + BYTE* op = (BYTE*)dst; + RETURN_ERROR_IF(dstCapacity < srcSize + ZSTD_SKIPPABLEHEADERSIZE /* Skippable frame overhead */, + dstSize_tooSmall, "Not enough room for skippable frame"); + RETURN_ERROR_IF(srcSize > (unsigned)0xFFFFFFFF, srcSize_wrong, "Src size too large for skippable frame"); + RETURN_ERROR_IF(magicVariant > 15, parameter_outOfBound, "Skippable frame magic number variant not supported"); + + MEM_writeLE32(op, (U32)(ZSTD_MAGIC_SKIPPABLE_START + magicVariant)); + MEM_writeLE32(op+4, (U32)srcSize); + ZSTD_memcpy(op+8, src, srcSize); + return srcSize + ZSTD_SKIPPABLEHEADERSIZE; +} + +/* ZSTD_writeLastEmptyBlock() : + * output an empty Block with end-of-frame mark to complete a frame + * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h)) + * or an error code if `dstCapacity` is too small (stage == ZSTDcs_init); + assert(nbSeq == 0 || cctx->appliedParams.ldmParams.enableLdm != ZSTD_ps_enable); + cctx->externSeqStore.seq = seq; + cctx->externSeqStore.size = nbSeq; + cctx->externSeqStore.capacity = nbSeq; + cctx->externSeqStore.pos = 0; + cctx->externSeqStore.posInSequence = 0; +} + + +static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + U32 frame, U32 lastFrameChunk) +{ + ZSTD_MatchState_t* const ms = &cctx->blockState.matchState; + size_t fhSize = 0; + + DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u", + cctx->stage, (unsigned)srcSize); + RETURN_ERROR_IF(cctx->stage==ZSTDcs_created, stage_wrong, + "missing init (ZSTD_compressBegin)"); + + if (frame && (cctx->stage==ZSTDcs_init)) { + fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, + cctx->pledgedSrcSizePlusOne-1, cctx->dictID); + FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed"); + assert(fhSize <= dstCapacity); + dstCapacity -= fhSize; + dst = (char*)dst + fhSize; + cctx->stage = ZSTDcs_ongoing; + } + + if (!srcSize) return fhSize; /* do not generate an empty block if no input */ + + if (!ZSTD_window_update(&ms->window, src, srcSize, ms->forceNonContiguous)) { + ms->forceNonContiguous = 0; + ms->nextToUpdate = ms->window.dictLimit; + } + if (cctx->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) { + ZSTD_window_update(&cctx->ldmState.window, src, srcSize, /* forceNonContiguous */ 0); + } + + if (!frame) { + /* overflow check and correction for block mode */ + ZSTD_overflowCorrectIfNeeded( + ms, &cctx->workspace, &cctx->appliedParams, + src, (BYTE const*)src + srcSize); + } + + DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSizeMax); + { size_t const cSize = frame ? + ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) : + ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize, 0 /* frame */); + FORWARD_IF_ERROR(cSize, "%s", frame ? "ZSTD_compress_frameChunk failed" : "ZSTD_compressBlock_internal failed"); + cctx->consumedSrcSize += srcSize; + cctx->producedCSize += (cSize + fhSize); + assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0)); + if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */ + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1); + RETURN_ERROR_IF( + cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne, + srcSize_wrong, + "error : pledgedSrcSize = %u, while realSrcSize >= %u", + (unsigned)cctx->pledgedSrcSizePlusOne-1, + (unsigned)cctx->consumedSrcSize); + } + return cSize + fhSize; + } +} + +size_t ZSTD_compressContinue_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_compressContinue (srcSize=%u)", (unsigned)srcSize); + return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 0 /* last chunk */); +} + +/* NOTE: Must just wrap ZSTD_compressContinue_public() */ +size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + return ZSTD_compressContinue_public(cctx, dst, dstCapacity, src, srcSize); +} + +static size_t ZSTD_getBlockSize_deprecated(const ZSTD_CCtx* cctx) +{ + ZSTD_compressionParameters const cParams = cctx->appliedParams.cParams; + assert(!ZSTD_checkCParams(cParams)); + return MIN(cctx->appliedParams.maxBlockSize, (size_t)1 << cParams.windowLog); +} + +/* NOTE: Must just wrap ZSTD_getBlockSize_deprecated() */ +size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx) +{ + return ZSTD_getBlockSize_deprecated(cctx); +} + +/* NOTE: Must just wrap ZSTD_compressBlock_deprecated() */ +size_t ZSTD_compressBlock_deprecated(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_compressBlock: srcSize = %u", (unsigned)srcSize); + { size_t const blockSizeMax = ZSTD_getBlockSize_deprecated(cctx); + RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong, "input is larger than a block"); } + + return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */); +} + +/* NOTE: Must just wrap ZSTD_compressBlock_deprecated() */ +size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_deprecated(cctx, dst, dstCapacity, src, srcSize); +} + +/*! ZSTD_loadDictionaryContent() : + * @return : 0, or an error code + */ +static size_t +ZSTD_loadDictionaryContent(ZSTD_MatchState_t* ms, + ldmState_t* ls, + ZSTD_cwksp* ws, + ZSTD_CCtx_params const* params, + const void* src, size_t srcSize, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp) +{ + const BYTE* ip = (const BYTE*) src; + const BYTE* const iend = ip + srcSize; + int const loadLdmDict = params->ldmParams.enableLdm == ZSTD_ps_enable && ls != NULL; + + /* Assert that the ms params match the params we're being given */ + ZSTD_assertEqualCParams(params->cParams, ms->cParams); + + { /* Ensure large dictionaries can't cause index overflow */ + + /* Allow the dictionary to set indices up to exactly ZSTD_CURRENT_MAX. + * Dictionaries right at the edge will immediately trigger overflow + * correction, but I don't want to insert extra constraints here. + */ + U32 maxDictSize = ZSTD_CURRENT_MAX - ZSTD_WINDOW_START_INDEX; + + int const CDictTaggedIndices = ZSTD_CDictIndicesAreTagged(¶ms->cParams); + if (CDictTaggedIndices && tfp == ZSTD_tfp_forCDict) { + /* Some dictionary matchfinders in zstd use "short cache", + * which treats the lower ZSTD_SHORT_CACHE_TAG_BITS of each + * CDict hashtable entry as a tag rather than as part of an index. + * When short cache is used, we need to truncate the dictionary + * so that its indices don't overlap with the tag. */ + U32 const shortCacheMaxDictSize = (1u << (32 - ZSTD_SHORT_CACHE_TAG_BITS)) - ZSTD_WINDOW_START_INDEX; + maxDictSize = MIN(maxDictSize, shortCacheMaxDictSize); + assert(!loadLdmDict); + } + + /* If the dictionary is too large, only load the suffix of the dictionary. */ + if (srcSize > maxDictSize) { + ip = iend - maxDictSize; + src = ip; + srcSize = maxDictSize; + } + } + + if (srcSize > ZSTD_CHUNKSIZE_MAX) { + /* We must have cleared our windows when our source is this large. */ + assert(ZSTD_window_isEmpty(ms->window)); + if (loadLdmDict) assert(ZSTD_window_isEmpty(ls->window)); + } + ZSTD_window_update(&ms->window, src, srcSize, /* forceNonContiguous */ 0); + + DEBUGLOG(4, "ZSTD_loadDictionaryContent: useRowMatchFinder=%d", (int)params->useRowMatchFinder); + + if (loadLdmDict) { /* Load the entire dict into LDM matchfinders. */ + DEBUGLOG(4, "ZSTD_loadDictionaryContent: Trigger loadLdmDict"); + ZSTD_window_update(&ls->window, src, srcSize, /* forceNonContiguous */ 0); + ls->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ls->window.base); + ZSTD_ldm_fillHashTable(ls, ip, iend, ¶ms->ldmParams); + DEBUGLOG(4, "ZSTD_loadDictionaryContent: ZSTD_ldm_fillHashTable completes"); + } + + /* If the dict is larger than we can reasonably index in our tables, only load the suffix. */ + { U32 maxDictSize = 1U << MIN(MAX(params->cParams.hashLog + 3, params->cParams.chainLog + 1), 31); + if (srcSize > maxDictSize) { + ip = iend - maxDictSize; + src = ip; + srcSize = maxDictSize; + } + } + + ms->nextToUpdate = (U32)(ip - ms->window.base); + ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base); + ms->forceNonContiguous = params->deterministicRefPrefix; + + if (srcSize <= HASH_READ_SIZE) return 0; + + ZSTD_overflowCorrectIfNeeded(ms, ws, params, ip, iend); + + switch(params->cParams.strategy) + { + case ZSTD_fast: + ZSTD_fillHashTable(ms, iend, dtlm, tfp); + break; + case ZSTD_dfast: +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + ZSTD_fillDoubleHashTable(ms, iend, dtlm, tfp); +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif + break; + + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) + assert(srcSize >= HASH_READ_SIZE); + if (ms->dedicatedDictSearch) { + assert(ms->chainTable != NULL); + ZSTD_dedicatedDictSearch_lazy_loadDictionary(ms, iend-HASH_READ_SIZE); + } else { + assert(params->useRowMatchFinder != ZSTD_ps_auto); + if (params->useRowMatchFinder == ZSTD_ps_enable) { + size_t const tagTableSize = ((size_t)1 << params->cParams.hashLog); + ZSTD_memset(ms->tagTable, 0, tagTableSize); + ZSTD_row_update(ms, iend-HASH_READ_SIZE); + DEBUGLOG(4, "Using row-based hash table for lazy dict"); + } else { + ZSTD_insertAndFindFirstIndex(ms, iend-HASH_READ_SIZE); + DEBUGLOG(4, "Using chain-based hash table for lazy dict"); + } + } +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif + break; + + case ZSTD_btlazy2: /* we want the dictionary table fully sorted */ + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: +#if !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) + assert(srcSize >= HASH_READ_SIZE); + DEBUGLOG(4, "Fill %u bytes into the Binary Tree", (unsigned)srcSize); + ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend); +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif + break; + + default: + assert(0); /* not possible : not a valid strategy id */ + } + + ms->nextToUpdate = (U32)(iend - ms->window.base); + return 0; +} + + +/* Dictionaries that assign zero probability to symbols that show up causes problems + * when FSE encoding. Mark dictionaries with zero probability symbols as FSE_repeat_check + * and only dictionaries with 100% valid symbols can be assumed valid. + */ +static FSE_repeat ZSTD_dictNCountRepeat(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) +{ + U32 s; + if (dictMaxSymbolValue < maxSymbolValue) { + return FSE_repeat_check; + } + for (s = 0; s <= maxSymbolValue; ++s) { + if (normalizedCounter[s] == 0) { + return FSE_repeat_check; + } + } + return FSE_repeat_valid; +} + +size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, + const void* const dict, size_t dictSize) +{ + short offcodeNCount[MaxOff+1]; + unsigned offcodeMaxValue = MaxOff; + const BYTE* dictPtr = (const BYTE*)dict; /* skip magic num and dict ID */ + const BYTE* const dictEnd = dictPtr + dictSize; + dictPtr += 8; + bs->entropy.huf.repeatMode = HUF_repeat_check; + + { unsigned maxSymbolValue = 255; + unsigned hasZeroWeights = 1; + size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr, + (size_t)(dictEnd-dictPtr), &hasZeroWeights); + + /* We only set the loaded table as valid if it contains all non-zero + * weights. Otherwise, we set it to check */ + if (!hasZeroWeights && maxSymbolValue == 255) + bs->entropy.huf.repeatMode = HUF_repeat_valid; + + RETURN_ERROR_IF(HUF_isError(hufHeaderSize), dictionary_corrupted, ""); + dictPtr += hufHeaderSize; + } + + { unsigned offcodeLog; + size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, ""); + /* fill all offset symbols to avoid garbage at end of table */ + RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( + bs->entropy.fse.offcodeCTable, + offcodeNCount, MaxOff, offcodeLog, + workspace, HUF_WORKSPACE_SIZE)), + dictionary_corrupted, ""); + /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */ + dictPtr += offcodeHeaderSize; + } + + { short matchlengthNCount[MaxML+1]; + unsigned matchlengthMaxValue = MaxML, matchlengthLog; + size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, ""); + RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( + bs->entropy.fse.matchlengthCTable, + matchlengthNCount, matchlengthMaxValue, matchlengthLog, + workspace, HUF_WORKSPACE_SIZE)), + dictionary_corrupted, ""); + bs->entropy.fse.matchlength_repeatMode = ZSTD_dictNCountRepeat(matchlengthNCount, matchlengthMaxValue, MaxML); + dictPtr += matchlengthHeaderSize; + } + + { short litlengthNCount[MaxLL+1]; + unsigned litlengthMaxValue = MaxLL, litlengthLog; + size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, ""); + RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp( + bs->entropy.fse.litlengthCTable, + litlengthNCount, litlengthMaxValue, litlengthLog, + workspace, HUF_WORKSPACE_SIZE)), + dictionary_corrupted, ""); + bs->entropy.fse.litlength_repeatMode = ZSTD_dictNCountRepeat(litlengthNCount, litlengthMaxValue, MaxLL); + dictPtr += litlengthHeaderSize; + } + + RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted, ""); + bs->rep[0] = MEM_readLE32(dictPtr+0); + bs->rep[1] = MEM_readLE32(dictPtr+4); + bs->rep[2] = MEM_readLE32(dictPtr+8); + dictPtr += 12; + + { size_t const dictContentSize = (size_t)(dictEnd - dictPtr); + U32 offcodeMax = MaxOff; + if (dictContentSize <= ((U32)-1) - 128 KB) { + U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */ + offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */ + } + /* All offset values <= dictContentSize + 128 KB must be representable for a valid table */ + bs->entropy.fse.offcode_repeatMode = ZSTD_dictNCountRepeat(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)); + + /* All repCodes must be <= dictContentSize and != 0 */ + { U32 u; + for (u=0; u<3; u++) { + RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted, ""); + RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, ""); + } } } + + return (size_t)(dictPtr - (const BYTE*)dict); +} + +/* Dictionary format : + * See : + * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#dictionary-format + */ +/*! ZSTD_loadZstdDictionary() : + * @return : dictID, or an error code + * assumptions : magic number supposed already checked + * dictSize supposed >= 8 + */ +static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, + ZSTD_MatchState_t* ms, + ZSTD_cwksp* ws, + ZSTD_CCtx_params const* params, + const void* dict, size_t dictSize, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp, + void* workspace) +{ + const BYTE* dictPtr = (const BYTE*)dict; + const BYTE* const dictEnd = dictPtr + dictSize; + size_t dictID; + size_t eSize; + ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<= 8); + assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY); + + dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr + 4 /* skip magic number */ ); + eSize = ZSTD_loadCEntropy(bs, workspace, dict, dictSize); + FORWARD_IF_ERROR(eSize, "ZSTD_loadCEntropy failed"); + dictPtr += eSize; + + { + size_t const dictContentSize = (size_t)(dictEnd - dictPtr); + FORWARD_IF_ERROR(ZSTD_loadDictionaryContent( + ms, NULL, ws, params, dictPtr, dictContentSize, dtlm, tfp), ""); + } + return dictID; +} + +/** ZSTD_compress_insertDictionary() : +* @return : dictID, or an error code */ +static size_t +ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, + ZSTD_MatchState_t* ms, + ldmState_t* ls, + ZSTD_cwksp* ws, + const ZSTD_CCtx_params* params, + const void* dict, size_t dictSize, + ZSTD_dictContentType_e dictContentType, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp, + void* workspace) +{ + DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize); + if ((dict==NULL) || (dictSize<8)) { + RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong, ""); + return 0; + } + + ZSTD_reset_compressedBlockState(bs); + + /* dict restricted modes */ + if (dictContentType == ZSTD_dct_rawContent) + return ZSTD_loadDictionaryContent(ms, ls, ws, params, dict, dictSize, dtlm, tfp); + + if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) { + if (dictContentType == ZSTD_dct_auto) { + DEBUGLOG(4, "raw content dictionary detected"); + return ZSTD_loadDictionaryContent( + ms, ls, ws, params, dict, dictSize, dtlm, tfp); + } + RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong, ""); + assert(0); /* impossible */ + } + + /* dict as full zstd dictionary */ + return ZSTD_loadZstdDictionary( + bs, ms, ws, params, dict, dictSize, dtlm, tfp, workspace); +} + +#define ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF (128 KB) +#define ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER (6ULL) + +/*! ZSTD_compressBegin_internal() : + * Assumption : either @dict OR @cdict (or none) is non-NULL, never both + * @return : 0, or an error code */ +static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_dictContentType_e dictContentType, + ZSTD_dictTableLoadMethod_e dtlm, + const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) +{ + size_t const dictContentSize = cdict ? cdict->dictContentSize : dictSize; +#if ZSTD_TRACE + cctx->traceCtx = (ZSTD_trace_compress_begin != NULL) ? ZSTD_trace_compress_begin(cctx) : 0; +#endif + DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params->cParams.windowLog); + /* params are supposed to be fully validated at this point */ + assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams))); + assert(!((dict) && (cdict))); /* either dict or cdict, not both */ + if ( (cdict) + && (cdict->dictContentSize > 0) + && ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF + || pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER + || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN + || cdict->compressionLevel == 0) + && (params->attachDictPref != ZSTD_dictForceLoad) ) { + return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff); + } + + FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, + dictContentSize, + ZSTDcrp_makeClean, zbuff) , ""); + { size_t const dictID = cdict ? + ZSTD_compress_insertDictionary( + cctx->blockState.prevCBlock, &cctx->blockState.matchState, + &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, cdict->dictContent, + cdict->dictContentSize, cdict->dictContentType, dtlm, + ZSTD_tfp_forCCtx, cctx->tmpWorkspace) + : ZSTD_compress_insertDictionary( + cctx->blockState.prevCBlock, &cctx->blockState.matchState, + &cctx->ldmState, &cctx->workspace, &cctx->appliedParams, dict, dictSize, + dictContentType, dtlm, ZSTD_tfp_forCCtx, cctx->tmpWorkspace); + FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed"); + assert(dictID <= UINT_MAX); + cctx->dictID = (U32)dictID; + cctx->dictContentSize = dictContentSize; + } + return 0; +} + +size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_dictContentType_e dictContentType, + ZSTD_dictTableLoadMethod_e dtlm, + const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, + unsigned long long pledgedSrcSize) +{ + DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params->cParams.windowLog); + /* compression parameters verification and optimization */ + FORWARD_IF_ERROR( ZSTD_checkCParams(params->cParams) , ""); + return ZSTD_compressBegin_internal(cctx, + dict, dictSize, dictContentType, dtlm, + cdict, + params, pledgedSrcSize, + ZSTDb_not_buffered); +} + +/*! ZSTD_compressBegin_advanced() : +* @return : 0, or an error code */ +size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_parameters params, unsigned long long pledgedSrcSize) +{ + ZSTD_CCtx_params cctxParams; + ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, ZSTD_NO_CLEVEL); + return ZSTD_compressBegin_advanced_internal(cctx, + dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, + NULL /*cdict*/, + &cctxParams, pledgedSrcSize); +} + +static size_t +ZSTD_compressBegin_usingDict_deprecated(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) +{ + ZSTD_CCtx_params cctxParams; + { ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_noAttachDict); + ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel); + } + DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (unsigned)dictSize); + return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL, + &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered); +} + +size_t +ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) +{ + return ZSTD_compressBegin_usingDict_deprecated(cctx, dict, dictSize, compressionLevel); +} + +size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel) +{ + return ZSTD_compressBegin_usingDict_deprecated(cctx, NULL, 0, compressionLevel); +} + + +/*! ZSTD_writeEpilogue() : +* Ends a frame. +* @return : nb of bytes written into dst (or an error code) */ +static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity) +{ + BYTE* const ostart = (BYTE*)dst; + BYTE* op = ostart; + + DEBUGLOG(4, "ZSTD_writeEpilogue"); + RETURN_ERROR_IF(cctx->stage == ZSTDcs_created, stage_wrong, "init missing"); + + /* special case : empty frame */ + if (cctx->stage == ZSTDcs_init) { + size_t fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, 0, 0); + FORWARD_IF_ERROR(fhSize, "ZSTD_writeFrameHeader failed"); + dstCapacity -= fhSize; + op += fhSize; + cctx->stage = ZSTDcs_ongoing; + } + + if (cctx->stage != ZSTDcs_ending) { + /* write one last empty block, make it the "last" block */ + U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0; + ZSTD_STATIC_ASSERT(ZSTD_BLOCKHEADERSIZE == 3); + RETURN_ERROR_IF(dstCapacity<3, dstSize_tooSmall, "no room for epilogue"); + MEM_writeLE24(op, cBlockHeader24); + op += ZSTD_blockHeaderSize; + dstCapacity -= ZSTD_blockHeaderSize; + } + + if (cctx->appliedParams.fParams.checksumFlag) { + U32 const checksum = (U32) XXH64_digest(&cctx->xxhState); + RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum"); + DEBUGLOG(4, "ZSTD_writeEpilogue: write checksum : %08X", (unsigned)checksum); + MEM_writeLE32(op, checksum); + op += 4; + } + + cctx->stage = ZSTDcs_created; /* return to "created but no init" status */ + return (size_t)(op-ostart); +} + +void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize) +{ +#if ZSTD_TRACE + if (cctx->traceCtx && ZSTD_trace_compress_end != NULL) { + int const streaming = cctx->inBuffSize > 0 || cctx->outBuffSize > 0 || cctx->appliedParams.nbWorkers > 0; + ZSTD_Trace trace; + ZSTD_memset(&trace, 0, sizeof(trace)); + trace.version = ZSTD_VERSION_NUMBER; + trace.streaming = streaming; + trace.dictionaryID = cctx->dictID; + trace.dictionarySize = cctx->dictContentSize; + trace.uncompressedSize = cctx->consumedSrcSize; + trace.compressedSize = cctx->producedCSize + extraCSize; + trace.params = &cctx->appliedParams; + trace.cctx = cctx; + ZSTD_trace_compress_end(cctx->traceCtx, &trace); + } + cctx->traceCtx = 0; +#else + (void)cctx; + (void)extraCSize; +#endif +} + +size_t ZSTD_compressEnd_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + size_t endResult; + size_t const cSize = ZSTD_compressContinue_internal(cctx, + dst, dstCapacity, src, srcSize, + 1 /* frame mode */, 1 /* last chunk */); + FORWARD_IF_ERROR(cSize, "ZSTD_compressContinue_internal failed"); + endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize); + FORWARD_IF_ERROR(endResult, "ZSTD_writeEpilogue failed"); + assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0)); + if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */ + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1); + DEBUGLOG(4, "end of frame : controlling src size"); + RETURN_ERROR_IF( + cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1, + srcSize_wrong, + "error : pledgedSrcSize = %u, while realSrcSize = %u", + (unsigned)cctx->pledgedSrcSizePlusOne-1, + (unsigned)cctx->consumedSrcSize); + } + ZSTD_CCtx_trace(cctx, endResult); + return cSize + endResult; +} + +/* NOTE: Must just wrap ZSTD_compressEnd_public() */ +size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize); +} + +size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + ZSTD_parameters params) +{ + DEBUGLOG(4, "ZSTD_compress_advanced"); + FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), ""); + ZSTD_CCtxParams_init_internal(&cctx->simpleApiParams, ¶ms, ZSTD_NO_CLEVEL); + return ZSTD_compress_advanced_internal(cctx, + dst, dstCapacity, + src, srcSize, + dict, dictSize, + &cctx->simpleApiParams); +} + +/* Internal */ +size_t ZSTD_compress_advanced_internal( + ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + const ZSTD_CCtx_params* params) +{ + DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (unsigned)srcSize); + FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx, + dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL, + params, srcSize, ZSTDb_not_buffered) , ""); + return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize); +} + +size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize, + int compressionLevel) +{ + { + ZSTD_parameters const params = ZSTD_getParams_internal(compressionLevel, srcSize, dict ? dictSize : 0, ZSTD_cpm_noAttachDict); + assert(params.fParams.contentSizeFlag == 1); + ZSTD_CCtxParams_init_internal(&cctx->simpleApiParams, ¶ms, (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT: compressionLevel); + } + DEBUGLOG(4, "ZSTD_compress_usingDict (srcSize=%u)", (unsigned)srcSize); + return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, &cctx->simpleApiParams); +} + +size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + int compressionLevel) +{ + DEBUGLOG(4, "ZSTD_compressCCtx (srcSize=%u)", (unsigned)srcSize); + assert(cctx != NULL); + return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel); +} + +size_t ZSTD_compress(void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + int compressionLevel) +{ + size_t result; +#if ZSTD_COMPRESS_HEAPMODE + ZSTD_CCtx* cctx = ZSTD_createCCtx(); + RETURN_ERROR_IF(!cctx, memory_allocation, "ZSTD_createCCtx failed"); + result = ZSTD_compressCCtx(cctx, dst, dstCapacity, src, srcSize, compressionLevel); + ZSTD_freeCCtx(cctx); +#else + ZSTD_CCtx ctxBody; + ZSTD_initCCtx(&ctxBody, ZSTD_defaultCMem); + result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel); + ZSTD_freeCCtxContent(&ctxBody); /* can't free ctxBody itself, as it's on stack; free only heap content */ +#endif + return result; +} + + +/* ===== Dictionary API ===== */ + +/*! ZSTD_estimateCDictSize_advanced() : + * Estimate amount of memory that will be needed to create a dictionary with following arguments */ +size_t ZSTD_estimateCDictSize_advanced( + size_t dictSize, ZSTD_compressionParameters cParams, + ZSTD_dictLoadMethod_e dictLoadMethod) +{ + DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (unsigned)sizeof(ZSTD_CDict)); + return ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) + + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) + /* enableDedicatedDictSearch == 1 ensures that CDict estimation will not be too small + * in case we are using DDS with row-hash. */ + + ZSTD_sizeof_matchState(&cParams, ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams), + /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0) + + (dictLoadMethod == ZSTD_dlm_byRef ? 0 + : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void *)))); +} + +size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel) +{ + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + return ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy); +} + +size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict) +{ + if (cdict==NULL) return 0; /* support sizeof on NULL */ + DEBUGLOG(5, "sizeof(*cdict) : %u", (unsigned)sizeof(*cdict)); + /* cdict may be in the workspace */ + return (cdict->workspace.workspace == cdict ? 0 : sizeof(*cdict)) + + ZSTD_cwksp_sizeof(&cdict->workspace); +} + +static size_t ZSTD_initCDict_internal( + ZSTD_CDict* cdict, + const void* dictBuffer, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_CCtx_params params) +{ + DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (unsigned)dictContentType); + assert(!ZSTD_checkCParams(params.cParams)); + cdict->matchState.cParams = params.cParams; + cdict->matchState.dedicatedDictSearch = params.enableDedicatedDictSearch; + if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) { + cdict->dictContent = dictBuffer; + } else { + void *internalBuffer = ZSTD_cwksp_reserve_object(&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*))); + RETURN_ERROR_IF(!internalBuffer, memory_allocation, "NULL pointer!"); + cdict->dictContent = internalBuffer; + ZSTD_memcpy(internalBuffer, dictBuffer, dictSize); + } + cdict->dictContentSize = dictSize; + cdict->dictContentType = dictContentType; + + cdict->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cdict->workspace, HUF_WORKSPACE_SIZE); + + + /* Reset the state to no dictionary */ + ZSTD_reset_compressedBlockState(&cdict->cBlockState); + FORWARD_IF_ERROR(ZSTD_reset_matchState( + &cdict->matchState, + &cdict->workspace, + ¶ms.cParams, + params.useRowMatchFinder, + ZSTDcrp_makeClean, + ZSTDirp_reset, + ZSTD_resetTarget_CDict), ""); + /* (Maybe) load the dictionary + * Skips loading the dictionary if it is < 8 bytes. + */ + { params.compressionLevel = ZSTD_CLEVEL_DEFAULT; + params.fParams.contentSizeFlag = 1; + { size_t const dictID = ZSTD_compress_insertDictionary( + &cdict->cBlockState, &cdict->matchState, NULL, &cdict->workspace, + ¶ms, cdict->dictContent, cdict->dictContentSize, + dictContentType, ZSTD_dtlm_full, ZSTD_tfp_forCDict, cdict->entropyWorkspace); + FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed"); + assert(dictID <= (size_t)(U32)-1); + cdict->dictID = (U32)dictID; + } + } + + return 0; +} + +static ZSTD_CDict* +ZSTD_createCDict_advanced_internal(size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_compressionParameters cParams, + ZSTD_ParamSwitch_e useRowMatchFinder, + int enableDedicatedDictSearch, + ZSTD_customMem customMem) +{ + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + DEBUGLOG(3, "ZSTD_createCDict_advanced_internal (dictSize=%u)", (unsigned)dictSize); + + { size_t const workspaceSize = + ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) + + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) + + ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, enableDedicatedDictSearch, /* forCCtx */ 0) + + (dictLoadMethod == ZSTD_dlm_byRef ? 0 + : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*)))); + void* const workspace = ZSTD_customMalloc(workspaceSize, customMem); + ZSTD_cwksp ws; + ZSTD_CDict* cdict; + + if (!workspace) { + ZSTD_customFree(workspace, customMem); + return NULL; + } + + ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_dynamic_alloc); + + cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict)); + assert(cdict != NULL); + ZSTD_cwksp_move(&cdict->workspace, &ws); + cdict->customMem = customMem; + cdict->compressionLevel = ZSTD_NO_CLEVEL; /* signals advanced API usage */ + cdict->useRowMatchFinder = useRowMatchFinder; + return cdict; + } +} + +ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_compressionParameters cParams, + ZSTD_customMem customMem) +{ + ZSTD_CCtx_params cctxParams; + ZSTD_memset(&cctxParams, 0, sizeof(cctxParams)); + DEBUGLOG(3, "ZSTD_createCDict_advanced, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType); + ZSTD_CCtxParams_init(&cctxParams, 0); + cctxParams.cParams = cParams; + cctxParams.customMem = customMem; + return ZSTD_createCDict_advanced2( + dictBuffer, dictSize, + dictLoadMethod, dictContentType, + &cctxParams, customMem); +} + +ZSTD_CDict* ZSTD_createCDict_advanced2( + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + const ZSTD_CCtx_params* originalCctxParams, + ZSTD_customMem customMem) +{ + ZSTD_CCtx_params cctxParams = *originalCctxParams; + ZSTD_compressionParameters cParams; + ZSTD_CDict* cdict; + + DEBUGLOG(3, "ZSTD_createCDict_advanced2, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType); + if (!customMem.customAlloc ^ !customMem.customFree) return NULL; + + if (cctxParams.enableDedicatedDictSearch) { + cParams = ZSTD_dedicatedDictSearch_getCParams( + cctxParams.compressionLevel, dictSize); + ZSTD_overrideCParams(&cParams, &cctxParams.cParams); + } else { + cParams = ZSTD_getCParamsFromCCtxParams( + &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + } + + if (!ZSTD_dedicatedDictSearch_isSupported(&cParams)) { + /* Fall back to non-DDSS params */ + cctxParams.enableDedicatedDictSearch = 0; + cParams = ZSTD_getCParamsFromCCtxParams( + &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + } + + DEBUGLOG(3, "ZSTD_createCDict_advanced2: DedicatedDictSearch=%u", cctxParams.enableDedicatedDictSearch); + cctxParams.cParams = cParams; + cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams); + + cdict = ZSTD_createCDict_advanced_internal(dictSize, + dictLoadMethod, cctxParams.cParams, + cctxParams.useRowMatchFinder, cctxParams.enableDedicatedDictSearch, + customMem); + + if (!cdict || ZSTD_isError( ZSTD_initCDict_internal(cdict, + dict, dictSize, + dictLoadMethod, dictContentType, + cctxParams) )) { + ZSTD_freeCDict(cdict); + return NULL; + } + + return cdict; +} + +ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel) +{ + ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize, + ZSTD_dlm_byCopy, ZSTD_dct_auto, + cParams, ZSTD_defaultCMem); + if (cdict) + cdict->compressionLevel = (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel; + return cdict; +} + +ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel) +{ + ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dict, dictSize, + ZSTD_dlm_byRef, ZSTD_dct_auto, + cParams, ZSTD_defaultCMem); + if (cdict) + cdict->compressionLevel = (compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : compressionLevel; + return cdict; +} + +size_t ZSTD_freeCDict(ZSTD_CDict* cdict) +{ + if (cdict==NULL) return 0; /* support free on NULL */ + { ZSTD_customMem const cMem = cdict->customMem; + int cdictInWorkspace = ZSTD_cwksp_owns_buffer(&cdict->workspace, cdict); + ZSTD_cwksp_free(&cdict->workspace, cMem); + if (!cdictInWorkspace) { + ZSTD_customFree(cdict, cMem); + } + return 0; + } +} + +/*! ZSTD_initStaticCDict_advanced() : + * Generate a digested dictionary in provided memory area. + * workspace: The memory area to emplace the dictionary into. + * Provided pointer must 8-bytes aligned. + * It must outlive dictionary usage. + * workspaceSize: Use ZSTD_estimateCDictSize() + * to determine how large workspace must be. + * cParams : use ZSTD_getCParams() to transform a compression level + * into its relevant cParams. + * @return : pointer to ZSTD_CDict*, or NULL if error (size too small) + * Note : there is no corresponding "free" function. + * Since workspace was allocated externally, it must be freed externally. + */ +const ZSTD_CDict* ZSTD_initStaticCDict( + void* workspace, size_t workspaceSize, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_compressionParameters cParams) +{ + ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams); + /* enableDedicatedDictSearch == 1 ensures matchstate is not too small in case this CDict will be used for DDS + row hash */ + size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0); + size_t const neededSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) + + (dictLoadMethod == ZSTD_dlm_byRef ? 0 + : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*)))) + + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) + + matchStateSize; + ZSTD_CDict* cdict; + ZSTD_CCtx_params params; + + DEBUGLOG(4, "ZSTD_initStaticCDict (dictSize==%u)", (unsigned)dictSize); + if ((size_t)workspace & 7) return NULL; /* 8-aligned */ + + { + ZSTD_cwksp ws; + ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_static_alloc); + cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict)); + if (cdict == NULL) return NULL; + ZSTD_cwksp_move(&cdict->workspace, &ws); + } + + if (workspaceSize < neededSize) return NULL; + + ZSTD_CCtxParams_init(¶ms, 0); + params.cParams = cParams; + params.useRowMatchFinder = useRowMatchFinder; + cdict->useRowMatchFinder = useRowMatchFinder; + cdict->compressionLevel = ZSTD_NO_CLEVEL; + + if (ZSTD_isError( ZSTD_initCDict_internal(cdict, + dict, dictSize, + dictLoadMethod, dictContentType, + params) )) + return NULL; + + return cdict; +} + +ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict) +{ + assert(cdict != NULL); + return cdict->matchState.cParams; +} + +/*! ZSTD_getDictID_fromCDict() : + * Provides the dictID of the dictionary loaded into `cdict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict) +{ + if (cdict==NULL) return 0; + return cdict->dictID; +} + +/* ZSTD_compressBegin_usingCDict_internal() : + * Implementation of various ZSTD_compressBegin_usingCDict* functions. + */ +static size_t ZSTD_compressBegin_usingCDict_internal( + ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, + ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize) +{ + ZSTD_CCtx_params cctxParams; + DEBUGLOG(4, "ZSTD_compressBegin_usingCDict_internal"); + RETURN_ERROR_IF(cdict==NULL, dictionary_wrong, "NULL pointer!"); + /* Initialize the cctxParams from the cdict */ + { + ZSTD_parameters params; + params.fParams = fParams; + params.cParams = ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF + || pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER + || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN + || cdict->compressionLevel == 0 ) ? + ZSTD_getCParamsFromCDict(cdict) + : ZSTD_getCParams(cdict->compressionLevel, + pledgedSrcSize, + cdict->dictContentSize); + ZSTD_CCtxParams_init_internal(&cctxParams, ¶ms, cdict->compressionLevel); + } + /* Increase window log to fit the entire dictionary and source if the + * source size is known. Limit the increase to 19, which is the + * window log for compression level 1 with the largest source size. + */ + if (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN) { + U32 const limitedSrcSize = (U32)MIN(pledgedSrcSize, 1U << 19); + U32 const limitedSrcLog = limitedSrcSize > 1 ? ZSTD_highbit32(limitedSrcSize - 1) + 1 : 1; + cctxParams.cParams.windowLog = MAX(cctxParams.cParams.windowLog, limitedSrcLog); + } + return ZSTD_compressBegin_internal(cctx, + NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, + cdict, + &cctxParams, pledgedSrcSize, + ZSTDb_not_buffered); +} + + +/* ZSTD_compressBegin_usingCDict_advanced() : + * This function is DEPRECATED. + * cdict must be != NULL */ +size_t ZSTD_compressBegin_usingCDict_advanced( + ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, + ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize) +{ + return ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, pledgedSrcSize); +} + +/* ZSTD_compressBegin_usingCDict() : + * cdict must be != NULL */ +size_t ZSTD_compressBegin_usingCDict_deprecated(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) +{ + ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; + return ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN); +} + +size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) +{ + return ZSTD_compressBegin_usingCDict_deprecated(cctx, cdict); +} + +/*! ZSTD_compress_usingCDict_internal(): + * Implementation of various ZSTD_compress_usingCDict* functions. + */ +static size_t ZSTD_compress_usingCDict_internal(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict, ZSTD_frameParameters fParams) +{ + FORWARD_IF_ERROR(ZSTD_compressBegin_usingCDict_internal(cctx, cdict, fParams, srcSize), ""); /* will check if cdict != NULL */ + return ZSTD_compressEnd_public(cctx, dst, dstCapacity, src, srcSize); +} + +/*! ZSTD_compress_usingCDict_advanced(): + * This function is DEPRECATED. + */ +size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict, ZSTD_frameParameters fParams) +{ + return ZSTD_compress_usingCDict_internal(cctx, dst, dstCapacity, src, srcSize, cdict, fParams); +} + +/*! ZSTD_compress_usingCDict() : + * Compression using a digested Dictionary. + * Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times. + * Note that compression parameters are decided at CDict creation time + * while frame parameters are hardcoded */ +size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict) +{ + ZSTD_frameParameters const fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ }; + return ZSTD_compress_usingCDict_internal(cctx, dst, dstCapacity, src, srcSize, cdict, fParams); +} + +/*====== Compression ======*/ + +/* ZSTD_validateSequence() : + * @offBase : must use the format required by ZSTD_storeSeq() + * @returns a ZSTD error code if sequence is not valid + */ +static size_t +ZSTD_validateSequence(U32 offBase, U32 matchLength, U32 minMatch, + size_t posInSrc, U32 windowLog, size_t dictSize, int useSequenceProducer) +{ + U32 const windowSize = 1u << windowLog; + /* posInSrc represents the amount of data the decoder would decode up to this point. + * As long as the amount of data decoded is less than or equal to window size, offsets may be + * larger than the total length of output decoded in order to reference the dict, even larger than + * window size. After output surpasses windowSize, we're limited to windowSize offsets again. + */ + size_t const offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize; + size_t const matchLenLowerBound = (minMatch == 3 || useSequenceProducer) ? 3 : 4; + RETURN_ERROR_IF(offBase > OFFSET_TO_OFFBASE(offsetBound), externalSequences_invalid, "Offset too large!"); + /* Validate maxNbSeq is large enough for the given matchLength and minMatch */ + RETURN_ERROR_IF(matchLength < matchLenLowerBound, externalSequences_invalid, "Matchlength too small for the minMatch"); + return 0; +} + +/* Returns an offset code, given a sequence's raw offset, the ongoing repcode array, and whether litLength == 0 */ +static U32 ZSTD_finalizeOffBase(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32 ll0) +{ + U32 offBase = OFFSET_TO_OFFBASE(rawOffset); + + if (!ll0 && rawOffset == rep[0]) { + offBase = REPCODE1_TO_OFFBASE; + } else if (rawOffset == rep[1]) { + offBase = REPCODE_TO_OFFBASE(2 - ll0); + } else if (rawOffset == rep[2]) { + offBase = REPCODE_TO_OFFBASE(3 - ll0); + } else if (ll0 && rawOffset == rep[0] - 1) { + offBase = REPCODE3_TO_OFFBASE; + } + return offBase; +} + +/* This function scans through an array of ZSTD_Sequence, + * storing the sequences it reads, until it reaches a block delimiter. + * Note that the block delimiter includes the last literals of the block. + * @blockSize must be == sum(sequence_lengths). + * @returns @blockSize on success, and a ZSTD_error otherwise. + */ +static size_t +ZSTD_transferSequences_wBlockDelim(ZSTD_CCtx* cctx, + ZSTD_SequencePosition* seqPos, + const ZSTD_Sequence* const inSeqs, size_t inSeqsSize, + const void* src, size_t blockSize, + ZSTD_ParamSwitch_e externalRepSearch) +{ + U32 idx = seqPos->idx; + U32 const startIdx = idx; + BYTE const* ip = (BYTE const*)(src); + const BYTE* const iend = ip + blockSize; + Repcodes_t updatedRepcodes; + U32 dictSize; + + DEBUGLOG(5, "ZSTD_transferSequences_wBlockDelim (blockSize = %zu)", blockSize); + + if (cctx->cdict) { + dictSize = (U32)cctx->cdict->dictContentSize; + } else if (cctx->prefixDict.dict) { + dictSize = (U32)cctx->prefixDict.dictSize; + } else { + dictSize = 0; + } + ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t)); + for (; idx < inSeqsSize && (inSeqs[idx].matchLength != 0 || inSeqs[idx].offset != 0); ++idx) { + U32 const litLength = inSeqs[idx].litLength; + U32 const matchLength = inSeqs[idx].matchLength; + U32 offBase; + + if (externalRepSearch == ZSTD_ps_disable) { + offBase = OFFSET_TO_OFFBASE(inSeqs[idx].offset); + } else { + U32 const ll0 = (litLength == 0); + offBase = ZSTD_finalizeOffBase(inSeqs[idx].offset, updatedRepcodes.rep, ll0); + ZSTD_updateRep(updatedRepcodes.rep, offBase, ll0); + } + + DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength); + if (cctx->appliedParams.validateSequences) { + seqPos->posInSrc += litLength + matchLength; + FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch, + seqPos->posInSrc, + cctx->appliedParams.cParams.windowLog, dictSize, + ZSTD_hasExtSeqProd(&cctx->appliedParams)), + "Sequence validation failed"); + } + RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, externalSequences_invalid, + "Not enough memory allocated. Try adjusting ZSTD_c_minMatch."); + ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offBase, matchLength); + ip += matchLength + litLength; + } + RETURN_ERROR_IF(idx == inSeqsSize, externalSequences_invalid, "Block delimiter not found."); + + /* If we skipped repcode search while parsing, we need to update repcodes now */ + assert(externalRepSearch != ZSTD_ps_auto); + assert(idx >= startIdx); + if (externalRepSearch == ZSTD_ps_disable && idx != startIdx) { + U32* const rep = updatedRepcodes.rep; + U32 lastSeqIdx = idx - 1; /* index of last non-block-delimiter sequence */ + + if (lastSeqIdx >= startIdx + 2) { + rep[2] = inSeqs[lastSeqIdx - 2].offset; + rep[1] = inSeqs[lastSeqIdx - 1].offset; + rep[0] = inSeqs[lastSeqIdx].offset; + } else if (lastSeqIdx == startIdx + 1) { + rep[2] = rep[0]; + rep[1] = inSeqs[lastSeqIdx - 1].offset; + rep[0] = inSeqs[lastSeqIdx].offset; + } else { + assert(lastSeqIdx == startIdx); + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = inSeqs[lastSeqIdx].offset; + } + } + + ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t)); + + if (inSeqs[idx].litLength) { + DEBUGLOG(6, "Storing last literals of size: %u", inSeqs[idx].litLength); + ZSTD_storeLastLiterals(&cctx->seqStore, ip, inSeqs[idx].litLength); + ip += inSeqs[idx].litLength; + seqPos->posInSrc += inSeqs[idx].litLength; + } + RETURN_ERROR_IF(ip != iend, externalSequences_invalid, "Blocksize doesn't agree with block delimiter!"); + seqPos->idx = idx+1; + return blockSize; +} + +/*-===== Pre-defined compression levels =====-*/ +#include "clevels.h" + +int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; } +int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; } +int ZSTD_defaultCLevel(void) { return ZSTD_CLEVEL_DEFAULT; } + +static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(int const compressionLevel, size_t const dictSize) +{ + ZSTD_compressionParameters cParams = ZSTD_getCParams_internal(compressionLevel, 0, dictSize, ZSTD_cpm_createCDict); + switch (cParams.strategy) { + case ZSTD_fast: + case ZSTD_dfast: + break; + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: + cParams.hashLog += ZSTD_LAZY_DDSS_BUCKET_LOG; + break; + case ZSTD_btlazy2: + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: + break; + } + return cParams; +} + +static int ZSTD_dedicatedDictSearch_isSupported( + ZSTD_compressionParameters const* cParams) +{ + return (cParams->strategy >= ZSTD_greedy) + && (cParams->strategy <= ZSTD_lazy2) + && (cParams->hashLog > cParams->chainLog) + && (cParams->chainLog <= 24); +} + +/** + * Reverses the adjustment applied to cparams when enabling dedicated dict + * search. This is used to recover the params set to be used in the working + * context. (Otherwise, those tables would also grow.) + */ +static void ZSTD_dedicatedDictSearch_revertCParams( + ZSTD_compressionParameters* cParams) { + switch (cParams->strategy) { + case ZSTD_fast: + case ZSTD_dfast: + break; + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: + cParams->hashLog -= ZSTD_LAZY_DDSS_BUCKET_LOG; + if (cParams->hashLog < ZSTD_HASHLOG_MIN) { + cParams->hashLog = ZSTD_HASHLOG_MIN; + } + break; + case ZSTD_btlazy2: + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: + break; + } +} + +static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) +{ + switch (mode) { + case ZSTD_cpm_unknown: + case ZSTD_cpm_noAttachDict: + case ZSTD_cpm_createCDict: + break; + case ZSTD_cpm_attachDict: + dictSize = 0; + break; + default: + assert(0); + break; + } + { int const unknown = srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN; + size_t const addedSize = unknown && dictSize > 0 ? 500 : 0; + return unknown && dictSize == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : srcSizeHint+dictSize+addedSize; + } +} + +/*! ZSTD_getCParams_internal() : + * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize. + * Note: srcSizeHint 0 means 0, use ZSTD_CONTENTSIZE_UNKNOWN for unknown. + * Use dictSize == 0 for unknown or unused. + * Note: `mode` controls how we treat the `dictSize`. See docs for `ZSTD_CParamMode_e`. */ +static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) +{ + U64 const rSize = ZSTD_getCParamRowSize(srcSizeHint, dictSize, mode); + U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); + int row; + DEBUGLOG(5, "ZSTD_getCParams_internal (cLevel=%i)", compressionLevel); + + /* row */ + if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT; /* 0 == default */ + else if (compressionLevel < 0) row = 0; /* entry 0 is baseline for fast mode */ + else if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL; + else row = compressionLevel; + + { ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row]; + DEBUGLOG(5, "ZSTD_getCParams_internal selected tableID: %u row: %u strat: %u", tableID, row, (U32)cp.strategy); + /* acceleration factor */ + if (compressionLevel < 0) { + int const clampedCompressionLevel = MAX(ZSTD_minCLevel(), compressionLevel); + cp.targetLength = (unsigned)(-clampedCompressionLevel); + } + /* refine parameters based on srcSize & dictSize */ + return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize, mode, ZSTD_ps_auto); + } +} + +/*! ZSTD_getCParams() : + * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize. + * Size values are optional, provide 0 if not known or unused */ +ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) +{ + if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN; + return ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown); +} + +/*! ZSTD_getParams() : + * same idea as ZSTD_getCParams() + * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`). + * Fields of `ZSTD_frameParameters` are set to default values */ +static ZSTD_parameters +ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) +{ + ZSTD_parameters params; + ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, mode); + DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel); + ZSTD_memset(¶ms, 0, sizeof(params)); + params.cParams = cParams; + params.fParams.contentSizeFlag = 1; + return params; +} + +/*! ZSTD_getParams() : + * same idea as ZSTD_getCParams() + * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`). + * Fields of `ZSTD_frameParameters` are set to default values */ +ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) +{ + if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN; + return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown); +} + +void ZSTD_registerSequenceProducer( + ZSTD_CCtx* zc, + void* extSeqProdState, + ZSTD_sequenceProducer_F extSeqProdFunc) +{ + assert(zc != NULL); + ZSTD_CCtxParams_registerSequenceProducer( + &zc->requestedParams, extSeqProdState, extSeqProdFunc + ); +} + +void ZSTD_CCtxParams_registerSequenceProducer( + ZSTD_CCtx_params* params, + void* extSeqProdState, + ZSTD_sequenceProducer_F extSeqProdFunc) +{ + assert(params != NULL); + if (extSeqProdFunc != NULL) { + params->extSeqProdFunc = extSeqProdFunc; + params->extSeqProdState = extSeqProdState; + } else { + params->extSeqProdFunc = NULL; + params->extSeqProdState = NULL; + } +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_internal.h b/src/commonlib/bsd/zstd/compress/zstd_compress_internal.h new file mode 100644 index 00000000000..1d26c608675 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_internal.h @@ -0,0 +1,1625 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* This header contains definitions + * that shall **only** be used by modules within lib/compress. + */ + +#ifndef ZSTD_COMPRESS_H +#define ZSTD_COMPRESS_H + +/*-************************************* +* Dependencies +***************************************/ +#include "../common/zstd_internal.h" +#include "zstd_cwksp.h" +#include "../common/zstd_bits.h" /* ZSTD_highbit32, ZSTD_NbCommonBytes */ +#include "zstd_preSplit.h" /* ZSTD_SLIPBLOCK_WORKSPACESIZE */ + +/*-************************************* +* Constants +***************************************/ +#define kSearchStrength 8 +#define HASH_READ_SIZE 8 +#define ZSTD_DUBT_UNSORTED_MARK 1 /* For btlazy2 strategy, index ZSTD_DUBT_UNSORTED_MARK==1 means "unsorted". + It could be confused for a real successor at index "1", if sorted as larger than its predecessor. + It's not a big deal though : candidate will just be sorted again. + Additionally, candidate position 1 will be lost. + But candidate 1 cannot hide a large tree of candidates, so it's a minimal loss. + The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table reuse with a different strategy. + This constant is required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */ + + +/*-************************************* +* Context memory management +***************************************/ +typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e; +typedef enum { zcss_init=0, zcss_load, zcss_flush } ZSTD_cStreamStage; + +typedef struct ZSTD_prefixDict_s { + const void* dict; + size_t dictSize; + ZSTD_dictContentType_e dictContentType; +} ZSTD_prefixDict; + +typedef struct { + void* dictBuffer; + void const* dict; + size_t dictSize; + ZSTD_dictContentType_e dictContentType; + ZSTD_CDict* cdict; +} ZSTD_localDict; + +typedef struct { + HUF_CElt CTable[HUF_CTABLE_SIZE_ST(255)]; + HUF_repeat repeatMode; +} ZSTD_hufCTables_t; + +typedef struct { + FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)]; + FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)]; + FSE_CTable litlengthCTable[FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)]; + FSE_repeat offcode_repeatMode; + FSE_repeat matchlength_repeatMode; + FSE_repeat litlength_repeatMode; +} ZSTD_fseCTables_t; + +typedef struct { + ZSTD_hufCTables_t huf; + ZSTD_fseCTables_t fse; +} ZSTD_entropyCTables_t; + +/*********************************************** +* Sequences * +***********************************************/ +typedef struct SeqDef_s { + U32 offBase; /* offBase == Offset + ZSTD_REP_NUM, or repcode 1,2,3 */ + U16 litLength; + U16 mlBase; /* mlBase == matchLength - MINMATCH */ +} SeqDef; + +/* Controls whether seqStore has a single "long" litLength or matchLength. See SeqStore_t. */ +typedef enum { + ZSTD_llt_none = 0, /* no longLengthType */ + ZSTD_llt_literalLength = 1, /* represents a long literal */ + ZSTD_llt_matchLength = 2 /* represents a long match */ +} ZSTD_longLengthType_e; + +typedef struct { + SeqDef* sequencesStart; + SeqDef* sequences; /* ptr to end of sequences */ + BYTE* litStart; + BYTE* lit; /* ptr to end of literals */ + BYTE* llCode; + BYTE* mlCode; + BYTE* ofCode; + size_t maxNbSeq; + size_t maxNbLit; + + /* longLengthPos and longLengthType to allow us to represent either a single litLength or matchLength + * in the seqStore that has a value larger than U16 (if it exists). To do so, we increment + * the existing value of the litLength or matchLength by 0x10000. + */ + ZSTD_longLengthType_e longLengthType; + U32 longLengthPos; /* Index of the sequence to apply long length modification to */ +} SeqStore_t; + +typedef struct { + U32 litLength; + U32 matchLength; +} ZSTD_SequenceLength; + +/** + * Returns the ZSTD_SequenceLength for the given sequences. It handles the decoding of long sequences + * indicated by longLengthPos and longLengthType, and adds MINMATCH back to matchLength. + */ +MEM_STATIC ZSTD_SequenceLength ZSTD_getSequenceLength(SeqStore_t const* seqStore, SeqDef const* seq) +{ + ZSTD_SequenceLength seqLen; + seqLen.litLength = seq->litLength; + seqLen.matchLength = seq->mlBase + MINMATCH; + if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) { + if (seqStore->longLengthType == ZSTD_llt_literalLength) { + seqLen.litLength += 0x10000; + } + if (seqStore->longLengthType == ZSTD_llt_matchLength) { + seqLen.matchLength += 0x10000; + } + } + return seqLen; +} + +const SeqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */ +int ZSTD_seqToCodes(const SeqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */ + + +/*********************************************** +* Entropy buffer statistics structs and funcs * +***********************************************/ +/** ZSTD_hufCTablesMetadata_t : + * Stores Literals Block Type for a super-block in hType, and + * huffman tree description in hufDesBuffer. + * hufDesSize refers to the size of huffman tree description in bytes. + * This metadata is populated in ZSTD_buildBlockEntropyStats_literals() */ +typedef struct { + SymbolEncodingType_e hType; + BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE]; + size_t hufDesSize; +} ZSTD_hufCTablesMetadata_t; + +/** ZSTD_fseCTablesMetadata_t : + * Stores symbol compression modes for a super-block in {ll, ol, ml}Type, and + * fse tables in fseTablesBuffer. + * fseTablesSize refers to the size of fse tables in bytes. + * This metadata is populated in ZSTD_buildBlockEntropyStats_sequences() */ +typedef struct { + SymbolEncodingType_e llType; + SymbolEncodingType_e ofType; + SymbolEncodingType_e mlType; + BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE]; + size_t fseTablesSize; + size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */ +} ZSTD_fseCTablesMetadata_t; + +typedef struct { + ZSTD_hufCTablesMetadata_t hufMetadata; + ZSTD_fseCTablesMetadata_t fseMetadata; +} ZSTD_entropyCTablesMetadata_t; + +/** ZSTD_buildBlockEntropyStats() : + * Builds entropy for the block. + * @return : 0 on success or error code */ +size_t ZSTD_buildBlockEntropyStats( + const SeqStore_t* seqStorePtr, + const ZSTD_entropyCTables_t* prevEntropy, + ZSTD_entropyCTables_t* nextEntropy, + const ZSTD_CCtx_params* cctxParams, + ZSTD_entropyCTablesMetadata_t* entropyMetadata, + void* workspace, size_t wkspSize); + +/********************************* +* Compression internals structs * +*********************************/ + +typedef struct { + U32 off; /* Offset sumtype code for the match, using ZSTD_storeSeq() format */ + U32 len; /* Raw length of match */ +} ZSTD_match_t; + +typedef struct { + U32 offset; /* Offset of sequence */ + U32 litLength; /* Length of literals prior to match */ + U32 matchLength; /* Raw length of match */ +} rawSeq; + +typedef struct { + rawSeq* seq; /* The start of the sequences */ + size_t pos; /* The index in seq where reading stopped. pos <= size. */ + size_t posInSequence; /* The position within the sequence at seq[pos] where reading + stopped. posInSequence <= seq[pos].litLength + seq[pos].matchLength */ + size_t size; /* The number of sequences. <= capacity. */ + size_t capacity; /* The capacity starting from `seq` pointer */ +} RawSeqStore_t; + +UNUSED_ATTR static const RawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0}; + +typedef struct { + int price; /* price from beginning of segment to this position */ + U32 off; /* offset of previous match */ + U32 mlen; /* length of previous match */ + U32 litlen; /* nb of literals since previous match */ + U32 rep[ZSTD_REP_NUM]; /* offset history after previous match */ +} ZSTD_optimal_t; + +typedef enum { zop_dynamic=0, zop_predef } ZSTD_OptPrice_e; + +#define ZSTD_OPT_SIZE (ZSTD_OPT_NUM+3) +typedef struct { + /* All tables are allocated inside cctx->workspace by ZSTD_resetCCtx_internal() */ + unsigned* litFreq; /* table of literals statistics, of size 256 */ + unsigned* litLengthFreq; /* table of litLength statistics, of size (MaxLL+1) */ + unsigned* matchLengthFreq; /* table of matchLength statistics, of size (MaxML+1) */ + unsigned* offCodeFreq; /* table of offCode statistics, of size (MaxOff+1) */ + ZSTD_match_t* matchTable; /* list of found matches, of size ZSTD_OPT_SIZE */ + ZSTD_optimal_t* priceTable; /* All positions tracked by optimal parser, of size ZSTD_OPT_SIZE */ + + U32 litSum; /* nb of literals */ + U32 litLengthSum; /* nb of litLength codes */ + U32 matchLengthSum; /* nb of matchLength codes */ + U32 offCodeSum; /* nb of offset codes */ + U32 litSumBasePrice; /* to compare to log2(litfreq) */ + U32 litLengthSumBasePrice; /* to compare to log2(llfreq) */ + U32 matchLengthSumBasePrice;/* to compare to log2(mlfreq) */ + U32 offCodeSumBasePrice; /* to compare to log2(offreq) */ + ZSTD_OptPrice_e priceType; /* prices can be determined dynamically, or follow a pre-defined cost structure */ + const ZSTD_entropyCTables_t* symbolCosts; /* pre-calculated dictionary statistics */ + ZSTD_ParamSwitch_e literalCompressionMode; +} optState_t; + +typedef struct { + ZSTD_entropyCTables_t entropy; + U32 rep[ZSTD_REP_NUM]; +} ZSTD_compressedBlockState_t; + +typedef struct { + BYTE const* nextSrc; /* next block here to continue on current prefix */ + BYTE const* base; /* All regular indexes relative to this position */ + BYTE const* dictBase; /* extDict indexes relative to this position */ + U32 dictLimit; /* below that point, need extDict */ + U32 lowLimit; /* below that point, no more valid data */ + U32 nbOverflowCorrections; /* Number of times overflow correction has run since + * ZSTD_window_init(). Useful for debugging coredumps + * and for ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY. + */ +} ZSTD_window_t; + +#define ZSTD_WINDOW_START_INDEX 2 + +typedef struct ZSTD_MatchState_t ZSTD_MatchState_t; + +#define ZSTD_ROW_HASH_CACHE_SIZE 8 /* Size of prefetching hash cache for row-based matchfinder */ + +struct ZSTD_MatchState_t { + ZSTD_window_t window; /* State for window round buffer management */ + U32 loadedDictEnd; /* index of end of dictionary, within context's referential. + * When loadedDictEnd != 0, a dictionary is in use, and still valid. + * This relies on a mechanism to set loadedDictEnd=0 when dictionary is no longer within distance. + * Such mechanism is provided within ZSTD_window_enforceMaxDist() and ZSTD_checkDictValidity(). + * When dict referential is copied into active context (i.e. not attached), + * loadedDictEnd == dictSize, since referential starts from zero. + */ + U32 nextToUpdate; /* index from which to continue table update */ + U32 hashLog3; /* dispatch table for matches of len==3 : larger == faster, more memory */ + + U32 rowHashLog; /* For row-based matchfinder: Hashlog based on nb of rows in the hashTable.*/ + BYTE* tagTable; /* For row-based matchFinder: A row-based table containing the hashes and head index. */ + U32 hashCache[ZSTD_ROW_HASH_CACHE_SIZE]; /* For row-based matchFinder: a cache of hashes to improve speed */ + U64 hashSalt; /* For row-based matchFinder: salts the hash for reuse of tag table */ + U32 hashSaltEntropy; /* For row-based matchFinder: collects entropy for salt generation */ + + U32* hashTable; + U32* hashTable3; + U32* chainTable; + + int forceNonContiguous; /* Non-zero if we should force non-contiguous load for the next window update. */ + + int dedicatedDictSearch; /* Indicates whether this matchState is using the + * dedicated dictionary search structure. + */ + optState_t opt; /* optimal parser state */ + const ZSTD_MatchState_t* dictMatchState; + ZSTD_compressionParameters cParams; + const RawSeqStore_t* ldmSeqStore; + + /* Controls prefetching in some dictMatchState matchfinders. + * This behavior is controlled from the cctx ms. + * This parameter has no effect in the cdict ms. */ + int prefetchCDictTables; + + /* When == 0, lazy match finders insert every position. + * When != 0, lazy match finders only insert positions they search. + * This allows them to skip much faster over incompressible data, + * at a small cost to compression ratio. + */ + int lazySkipping; +}; + +typedef struct { + ZSTD_compressedBlockState_t* prevCBlock; + ZSTD_compressedBlockState_t* nextCBlock; + ZSTD_MatchState_t matchState; +} ZSTD_blockState_t; + +typedef struct { + U32 offset; + U32 checksum; +} ldmEntry_t; + +typedef struct { + BYTE const* split; + U32 hash; + U32 checksum; + ldmEntry_t* bucket; +} ldmMatchCandidate_t; + +#define LDM_BATCH_SIZE 64 + +typedef struct { + ZSTD_window_t window; /* State for the window round buffer management */ + ldmEntry_t* hashTable; + U32 loadedDictEnd; + BYTE* bucketOffsets; /* Next position in bucket to insert entry */ + size_t splitIndices[LDM_BATCH_SIZE]; + ldmMatchCandidate_t matchCandidates[LDM_BATCH_SIZE]; +} ldmState_t; + +typedef struct { + ZSTD_ParamSwitch_e enableLdm; /* ZSTD_ps_enable to enable LDM. ZSTD_ps_auto by default */ + U32 hashLog; /* Log size of hashTable */ + U32 bucketSizeLog; /* Log bucket size for collision resolution, at most 8 */ + U32 minMatchLength; /* Minimum match length */ + U32 hashRateLog; /* Log number of entries to skip */ + U32 windowLog; /* Window log for the LDM */ +} ldmParams_t; + +typedef struct { + int collectSequences; + ZSTD_Sequence* seqStart; + size_t seqIndex; + size_t maxSequences; +} SeqCollector; + +struct ZSTD_CCtx_params_s { + ZSTD_format_e format; + ZSTD_compressionParameters cParams; + ZSTD_frameParameters fParams; + + int compressionLevel; + int forceWindow; /* force back-references to respect limit of + * 1< 63) ? ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength]; +} + +/* ZSTD_MLcode() : + * note : mlBase = matchLength - MINMATCH; + * because it's the format it's stored in seqStore->sequences */ +MEM_STATIC U32 ZSTD_MLcode(U32 mlBase) +{ + static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, + 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 }; + static const U32 ML_deltaCode = 36; + return (mlBase > 127) ? ZSTD_highbit32(mlBase) + ML_deltaCode : ML_Code[mlBase]; +} + +/* ZSTD_cParam_withinBounds: + * @return 1 if value is within cParam bounds, + * 0 otherwise */ +MEM_STATIC int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value) +{ + ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam); + if (ZSTD_isError(bounds.error)) return 0; + if (value < bounds.lowerBound) return 0; + if (value > bounds.upperBound) return 0; + return 1; +} + +/* ZSTD_selectAddr: + * @return index >= lowLimit ? candidate : backup, + * tries to force branchless codegen. */ +MEM_STATIC const BYTE* +ZSTD_selectAddr(U32 index, U32 lowLimit, const BYTE* candidate, const BYTE* backup) +{ +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ( + "cmp %1, %2\n" + "cmova %3, %0\n" + : "+r"(candidate) + : "r"(index), "r"(lowLimit), "r"(backup) + ); + return candidate; +#else + return index >= lowLimit ? candidate : backup; +#endif +} + +/* ZSTD_noCompressBlock() : + * Writes uncompressed block to dst buffer from given src. + * Returns the size of the block */ +MEM_STATIC size_t +ZSTD_noCompressBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock) +{ + U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3); + DEBUGLOG(5, "ZSTD_noCompressBlock (srcSize=%zu, dstCapacity=%zu)", srcSize, dstCapacity); + RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity, + dstSize_tooSmall, "dst buf too small for uncompressed block"); + MEM_writeLE24(dst, cBlockHeader24); + ZSTD_memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize); + return ZSTD_blockHeaderSize + srcSize; +} + +MEM_STATIC size_t +ZSTD_rleCompressBlock(void* dst, size_t dstCapacity, BYTE src, size_t srcSize, U32 lastBlock) +{ + BYTE* const op = (BYTE*)dst; + U32 const cBlockHeader = lastBlock + (((U32)bt_rle)<<1) + (U32)(srcSize << 3); + RETURN_ERROR_IF(dstCapacity < 4, dstSize_tooSmall, ""); + MEM_writeLE24(op, cBlockHeader); + op[3] = src; + return 4; +} + + +/* ZSTD_minGain() : + * minimum compression required + * to generate a compress block or a compressed literals section. + * note : use same formula for both situations */ +MEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat) +{ + U32 const minlog = (strat>=ZSTD_btultra) ? (U32)(strat) - 1 : 6; + ZSTD_STATIC_ASSERT(ZSTD_btultra == 8); + assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, (int)strat)); + return (srcSize >> minlog) + 2; +} + +MEM_STATIC int ZSTD_literalsCompressionIsDisabled(const ZSTD_CCtx_params* cctxParams) +{ + switch (cctxParams->literalCompressionMode) { + case ZSTD_ps_enable: + return 0; + case ZSTD_ps_disable: + return 1; + default: + assert(0 /* impossible: pre-validated */); + ZSTD_FALLTHROUGH; + case ZSTD_ps_auto: + return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0); + } +} + +/*! ZSTD_safecopyLiterals() : + * memcpy() function that won't read beyond more than WILDCOPY_OVERLENGTH bytes past ilimit_w. + * Only called when the sequence ends past ilimit_w, so it only needs to be optimized for single + * large copies. + */ +static void +ZSTD_safecopyLiterals(BYTE* op, BYTE const* ip, BYTE const* const iend, BYTE const* ilimit_w) +{ + assert(iend > ilimit_w); + if (ip <= ilimit_w) { + ZSTD_wildcopy(op, ip, ilimit_w - ip, ZSTD_no_overlap); + op += ilimit_w - ip; + ip = ilimit_w; + } + while (ip < iend) *op++ = *ip++; +} + + +#define REPCODE1_TO_OFFBASE REPCODE_TO_OFFBASE(1) +#define REPCODE2_TO_OFFBASE REPCODE_TO_OFFBASE(2) +#define REPCODE3_TO_OFFBASE REPCODE_TO_OFFBASE(3) +#define REPCODE_TO_OFFBASE(r) (assert((r)>=1), assert((r)<=ZSTD_REP_NUM), (r)) /* accepts IDs 1,2,3 */ +#define OFFSET_TO_OFFBASE(o) (assert((o)>0), o + ZSTD_REP_NUM) +#define OFFBASE_IS_OFFSET(o) ((o) > ZSTD_REP_NUM) +#define OFFBASE_IS_REPCODE(o) ( 1 <= (o) && (o) <= ZSTD_REP_NUM) +#define OFFBASE_TO_OFFSET(o) (assert(OFFBASE_IS_OFFSET(o)), (o) - ZSTD_REP_NUM) +#define OFFBASE_TO_REPCODE(o) (assert(OFFBASE_IS_REPCODE(o)), (o)) /* returns ID 1,2,3 */ + +/*! ZSTD_storeSeqOnly() : + * Store a sequence (litlen, litPtr, offBase and matchLength) into SeqStore_t. + * Literals themselves are not copied, but @litPtr is updated. + * @offBase : Users should employ macros REPCODE_TO_OFFBASE() and OFFSET_TO_OFFBASE(). + * @matchLength : must be >= MINMATCH +*/ +HINT_INLINE UNUSED_ATTR void +ZSTD_storeSeqOnly(SeqStore_t* seqStorePtr, + size_t litLength, + U32 offBase, + size_t matchLength) +{ + assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq); + + /* literal Length */ + assert(litLength <= ZSTD_BLOCKSIZE_MAX); + if (UNLIKELY(litLength>0xFFFF)) { + assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */ + seqStorePtr->longLengthType = ZSTD_llt_literalLength; + seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + } + seqStorePtr->sequences[0].litLength = (U16)litLength; + + /* match offset */ + seqStorePtr->sequences[0].offBase = offBase; + + /* match Length */ + assert(matchLength <= ZSTD_BLOCKSIZE_MAX); + assert(matchLength >= MINMATCH); + { size_t const mlBase = matchLength - MINMATCH; + if (UNLIKELY(mlBase>0xFFFF)) { + assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */ + seqStorePtr->longLengthType = ZSTD_llt_matchLength; + seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); + } + seqStorePtr->sequences[0].mlBase = (U16)mlBase; + } + + seqStorePtr->sequences++; +} + +/*! ZSTD_storeSeq() : + * Store a sequence (litlen, litPtr, offBase and matchLength) into SeqStore_t. + * @offBase : Users should employ macros REPCODE_TO_OFFBASE() and OFFSET_TO_OFFBASE(). + * @matchLength : must be >= MINMATCH + * Allowed to over-read literals up to litLimit. +*/ +HINT_INLINE UNUSED_ATTR void +ZSTD_storeSeq(SeqStore_t* seqStorePtr, + size_t litLength, const BYTE* literals, const BYTE* litLimit, + U32 offBase, + size_t matchLength) +{ + BYTE const* const litLimit_w = litLimit - WILDCOPY_OVERLENGTH; + BYTE const* const litEnd = literals + litLength; +#if defined(DEBUGLEVEL) && (DEBUGLEVEL >= 6) + static const BYTE* g_start = NULL; + if (g_start==NULL) g_start = (const BYTE*)literals; /* note : index only works for compression within a single segment */ + { U32 const pos = (U32)((const BYTE*)literals - g_start); + DEBUGLOG(6, "Cpos%7u :%3u literals, match%4u bytes at offBase%7u", + pos, (U32)litLength, (U32)matchLength, (U32)offBase); + } +#endif + assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq); + /* copy Literals */ + assert(seqStorePtr->maxNbLit <= 128 KB); + assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + seqStorePtr->maxNbLit); + assert(literals + litLength <= litLimit); + if (litEnd <= litLimit_w) { + /* Common case we can use wildcopy. + * First copy 16 bytes, because literals are likely short. + */ + ZSTD_STATIC_ASSERT(WILDCOPY_OVERLENGTH >= 16); + ZSTD_copy16(seqStorePtr->lit, literals); + if (litLength > 16) { + ZSTD_wildcopy(seqStorePtr->lit+16, literals+16, (ptrdiff_t)litLength-16, ZSTD_no_overlap); + } + } else { + ZSTD_safecopyLiterals(seqStorePtr->lit, literals, litEnd, litLimit_w); + } + seqStorePtr->lit += litLength; + + ZSTD_storeSeqOnly(seqStorePtr, litLength, offBase, matchLength); +} + +/* ZSTD_updateRep() : + * updates in-place @rep (array of repeat offsets) + * @offBase : sum-type, using numeric representation of ZSTD_storeSeq() + */ +MEM_STATIC void +ZSTD_updateRep(U32 rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0) +{ + if (OFFBASE_IS_OFFSET(offBase)) { /* full offset */ + rep[2] = rep[1]; + rep[1] = rep[0]; + rep[0] = OFFBASE_TO_OFFSET(offBase); + } else { /* repcode */ + U32 const repCode = OFFBASE_TO_REPCODE(offBase) - 1 + ll0; + if (repCode > 0) { /* note : if repCode==0, no change */ + U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode]; + rep[2] = (repCode >= 2) ? rep[1] : rep[2]; + rep[1] = rep[0]; + rep[0] = currentOffset; + } else { /* repCode == 0 */ + /* nothing to do */ + } + } +} + +typedef struct repcodes_s { + U32 rep[3]; +} Repcodes_t; + +MEM_STATIC Repcodes_t +ZSTD_newRep(U32 const rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0) +{ + Repcodes_t newReps; + ZSTD_memcpy(&newReps, rep, sizeof(newReps)); + ZSTD_updateRep(newReps.rep, offBase, ll0); + return newReps; +} + + +/*-************************************* +* Match length counter +***************************************/ +MEM_STATIC size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit) +{ + const BYTE* const pStart = pIn; + const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1); + + if (pIn < pInLoopLimit) { + { size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn); + if (diff) return ZSTD_NbCommonBytes(diff); } + pIn+=sizeof(size_t); pMatch+=sizeof(size_t); + while (pIn < pInLoopLimit) { + size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn); + if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; } + pIn += ZSTD_NbCommonBytes(diff); + return (size_t)(pIn - pStart); + } } + if (MEM_64bits() && (pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; } + if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; } + if ((pIn> (32-h) ; } +MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h, 0); } /* only in zstd_opt.h */ +MEM_STATIC size_t ZSTD_hash3PtrS(const void* ptr, U32 h, U32 s) { return ZSTD_hash3(MEM_readLE32(ptr), h, s); } + +static const U32 prime4bytes = 2654435761U; +static U32 ZSTD_hash4(U32 u, U32 h, U32 s) { assert(h <= 32); return ((u * prime4bytes) ^ s) >> (32-h) ; } +static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_readLE32(ptr), h, 0); } +static size_t ZSTD_hash4PtrS(const void* ptr, U32 h, U32 s) { return ZSTD_hash4(MEM_readLE32(ptr), h, s); } + +static const U64 prime5bytes = 889523592379ULL; +static size_t ZSTD_hash5(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-40)) * prime5bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash5PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash5(MEM_readLE64(p), h, s); } + +static const U64 prime6bytes = 227718039650203ULL; +static size_t ZSTD_hash6(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-48)) * prime6bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash6PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash6(MEM_readLE64(p), h, s); } + +static const U64 prime7bytes = 58295818150454627ULL; +static size_t ZSTD_hash7(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-56)) * prime7bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash7PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash7(MEM_readLE64(p), h, s); } + +static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL; +static size_t ZSTD_hash8(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u) * prime8bytes) ^ s) >> (64-h)) ; } +static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h, 0); } +static size_t ZSTD_hash8PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash8(MEM_readLE64(p), h, s); } + + +MEM_STATIC FORCE_INLINE_ATTR +size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls) +{ + /* Although some of these hashes do support hBits up to 64, some do not. + * To be on the safe side, always avoid hBits > 32. */ + assert(hBits <= 32); + + switch(mls) + { + default: + case 4: return ZSTD_hash4Ptr(p, hBits); + case 5: return ZSTD_hash5Ptr(p, hBits); + case 6: return ZSTD_hash6Ptr(p, hBits); + case 7: return ZSTD_hash7Ptr(p, hBits); + case 8: return ZSTD_hash8Ptr(p, hBits); + } +} + +MEM_STATIC FORCE_INLINE_ATTR +size_t ZSTD_hashPtrSalted(const void* p, U32 hBits, U32 mls, const U64 hashSalt) { + /* Although some of these hashes do support hBits up to 64, some do not. + * To be on the safe side, always avoid hBits > 32. */ + assert(hBits <= 32); + + switch(mls) + { + default: + case 4: return ZSTD_hash4PtrS(p, hBits, (U32)hashSalt); + case 5: return ZSTD_hash5PtrS(p, hBits, hashSalt); + case 6: return ZSTD_hash6PtrS(p, hBits, hashSalt); + case 7: return ZSTD_hash7PtrS(p, hBits, hashSalt); + case 8: return ZSTD_hash8PtrS(p, hBits, hashSalt); + } +} + + +/** ZSTD_ipow() : + * Return base^exponent. + */ +static U64 ZSTD_ipow(U64 base, U64 exponent) +{ + U64 power = 1; + while (exponent) { + if (exponent & 1) power *= base; + exponent >>= 1; + base *= base; + } + return power; +} + +#define ZSTD_ROLL_HASH_CHAR_OFFSET 10 + +/** ZSTD_rollingHash_append() : + * Add the buffer to the hash value. + */ +static U64 ZSTD_rollingHash_append(U64 hash, void const* buf, size_t size) +{ + BYTE const* istart = (BYTE const*)buf; + size_t pos; + for (pos = 0; pos < size; ++pos) { + hash *= prime8bytes; + hash += istart[pos] + ZSTD_ROLL_HASH_CHAR_OFFSET; + } + return hash; +} + +/** ZSTD_rollingHash_compute() : + * Compute the rolling hash value of the buffer. + */ +MEM_STATIC U64 ZSTD_rollingHash_compute(void const* buf, size_t size) +{ + return ZSTD_rollingHash_append(0, buf, size); +} + +/** ZSTD_rollingHash_primePower() : + * Compute the primePower to be passed to ZSTD_rollingHash_rotate() for a hash + * over a window of length bytes. + */ +MEM_STATIC U64 ZSTD_rollingHash_primePower(U32 length) +{ + return ZSTD_ipow(prime8bytes, length - 1); +} + +/** ZSTD_rollingHash_rotate() : + * Rotate the rolling hash by one byte. + */ +MEM_STATIC U64 ZSTD_rollingHash_rotate(U64 hash, BYTE toRemove, BYTE toAdd, U64 primePower) +{ + hash -= (toRemove + ZSTD_ROLL_HASH_CHAR_OFFSET) * primePower; + hash *= prime8bytes; + hash += toAdd + ZSTD_ROLL_HASH_CHAR_OFFSET; + return hash; +} + +/*-************************************* +* Round buffer management +***************************************/ +/* Max @current value allowed: + * In 32-bit mode: we want to avoid crossing the 2 GB limit, + * reducing risks of side effects in case of signed operations on indexes. + * In 64-bit mode: we want to ensure that adding the maximum job size (512 MB) + * doesn't overflow U32 index capacity (4 GB) */ +#define ZSTD_CURRENT_MAX (MEM_64bits() ? 3500U MB : 2000U MB) +/* Maximum chunk size before overflow correction needs to be called again */ +#define ZSTD_CHUNKSIZE_MAX \ + ( ((U32)-1) /* Maximum ending current index */ \ + - ZSTD_CURRENT_MAX) /* Maximum beginning lowLimit */ + +/** + * ZSTD_window_clear(): + * Clears the window containing the history by simply setting it to empty. + */ +MEM_STATIC void ZSTD_window_clear(ZSTD_window_t* window) +{ + size_t const endT = (size_t)(window->nextSrc - window->base); + U32 const end = (U32)endT; + + window->lowLimit = end; + window->dictLimit = end; +} + +MEM_STATIC U32 ZSTD_window_isEmpty(ZSTD_window_t const window) +{ + return window.dictLimit == ZSTD_WINDOW_START_INDEX && + window.lowLimit == ZSTD_WINDOW_START_INDEX && + (window.nextSrc - window.base) == ZSTD_WINDOW_START_INDEX; +} + +/** + * ZSTD_window_hasExtDict(): + * Returns non-zero if the window has a non-empty extDict. + */ +MEM_STATIC U32 ZSTD_window_hasExtDict(ZSTD_window_t const window) +{ + return window.lowLimit < window.dictLimit; +} + +/** + * ZSTD_matchState_dictMode(): + * Inspects the provided matchState and figures out what dictMode should be + * passed to the compressor. + */ +MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_MatchState_t *ms) +{ + return ZSTD_window_hasExtDict(ms->window) ? + ZSTD_extDict : + ms->dictMatchState != NULL ? + (ms->dictMatchState->dedicatedDictSearch ? ZSTD_dedicatedDictSearch : ZSTD_dictMatchState) : + ZSTD_noDict; +} + +/* Defining this macro to non-zero tells zstd to run the overflow correction + * code much more frequently. This is very inefficient, and should only be + * used for tests and fuzzers. + */ +#ifndef ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY +# ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +# define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 1 +# else +# define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 0 +# endif +#endif + +/** + * ZSTD_window_canOverflowCorrect(): + * Returns non-zero if the indices are large enough for overflow correction + * to work correctly without impacting compression ratio. + */ +MEM_STATIC U32 ZSTD_window_canOverflowCorrect(ZSTD_window_t const window, + U32 cycleLog, + U32 maxDist, + U32 loadedDictEnd, + void const* src) +{ + U32 const cycleSize = 1u << cycleLog; + U32 const curr = (U32)((BYTE const*)src - window.base); + U32 const minIndexToOverflowCorrect = cycleSize + + MAX(maxDist, cycleSize) + + ZSTD_WINDOW_START_INDEX; + + /* Adjust the min index to backoff the overflow correction frequency, + * so we don't waste too much CPU in overflow correction. If this + * computation overflows we don't really care, we just need to make + * sure it is at least minIndexToOverflowCorrect. + */ + U32 const adjustment = window.nbOverflowCorrections + 1; + U32 const adjustedIndex = MAX(minIndexToOverflowCorrect * adjustment, + minIndexToOverflowCorrect); + U32 const indexLargeEnough = curr > adjustedIndex; + + /* Only overflow correct early if the dictionary is invalidated already, + * so we don't hurt compression ratio. + */ + U32 const dictionaryInvalidated = curr > maxDist + loadedDictEnd; + + return indexLargeEnough && dictionaryInvalidated; +} + +/** + * ZSTD_window_needOverflowCorrection(): + * Returns non-zero if the indices are getting too large and need overflow + * protection. + */ +MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window, + U32 cycleLog, + U32 maxDist, + U32 loadedDictEnd, + void const* src, + void const* srcEnd) +{ + U32 const curr = (U32)((BYTE const*)srcEnd - window.base); + if (ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY) { + if (ZSTD_window_canOverflowCorrect(window, cycleLog, maxDist, loadedDictEnd, src)) { + return 1; + } + } + return curr > ZSTD_CURRENT_MAX; +} + +/** + * ZSTD_window_correctOverflow(): + * Reduces the indices to protect from index overflow. + * Returns the correction made to the indices, which must be applied to every + * stored index. + * + * The least significant cycleLog bits of the indices must remain the same, + * which may be 0. Every index up to maxDist in the past must be valid. + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, + U32 maxDist, void const* src) +{ + /* preemptive overflow correction: + * 1. correction is large enough: + * lowLimit > (3<<29) ==> current > 3<<29 + 1< (3<<29 + 1< (3<<29) - (1< (3<<29) - (1<<30) (NOTE: chainLog <= 30) + * > 1<<29 + * + * 2. (ip+ZSTD_CHUNKSIZE_MAX - cctx->base) doesn't overflow: + * After correction, current is less than (1<base < 1<<32. + * 3. (cctx->lowLimit + 1< 3<<29 + 1<base); + U32 const currentCycle = curr & cycleMask; + /* Ensure newCurrent - maxDist >= ZSTD_WINDOW_START_INDEX. */ + U32 const currentCycleCorrection = currentCycle < ZSTD_WINDOW_START_INDEX + ? MAX(cycleSize, ZSTD_WINDOW_START_INDEX) + : 0; + U32 const newCurrent = currentCycle + + currentCycleCorrection + + MAX(maxDist, cycleSize); + U32 const correction = curr - newCurrent; + /* maxDist must be a power of two so that: + * (newCurrent & cycleMask) == (curr & cycleMask) + * This is required to not corrupt the chains / binary tree. + */ + assert((maxDist & (maxDist - 1)) == 0); + assert((curr & cycleMask) == (newCurrent & cycleMask)); + assert(curr > newCurrent); + if (!ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY) { + /* Loose bound, should be around 1<<29 (see above) */ + assert(correction > 1<<28); + } + + window->base += correction; + window->dictBase += correction; + if (window->lowLimit < correction + ZSTD_WINDOW_START_INDEX) { + window->lowLimit = ZSTD_WINDOW_START_INDEX; + } else { + window->lowLimit -= correction; + } + if (window->dictLimit < correction + ZSTD_WINDOW_START_INDEX) { + window->dictLimit = ZSTD_WINDOW_START_INDEX; + } else { + window->dictLimit -= correction; + } + + /* Ensure we can still reference the full window. */ + assert(newCurrent >= maxDist); + assert(newCurrent - maxDist >= ZSTD_WINDOW_START_INDEX); + /* Ensure that lowLimit and dictLimit didn't underflow. */ + assert(window->lowLimit <= newCurrent); + assert(window->dictLimit <= newCurrent); + + ++window->nbOverflowCorrections; + + DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction, + window->lowLimit); + return correction; +} + +/** + * ZSTD_window_enforceMaxDist(): + * Updates lowLimit so that: + * (srcEnd - base) - lowLimit == maxDist + loadedDictEnd + * + * It ensures index is valid as long as index >= lowLimit. + * This must be called before a block compression call. + * + * loadedDictEnd is only defined if a dictionary is in use for current compression. + * As the name implies, loadedDictEnd represents the index at end of dictionary. + * The value lies within context's referential, it can be directly compared to blockEndIdx. + * + * If loadedDictEndPtr is NULL, no dictionary is in use, and we use loadedDictEnd == 0. + * If loadedDictEndPtr is not NULL, we set it to zero after updating lowLimit. + * This is because dictionaries are allowed to be referenced fully + * as long as the last byte of the dictionary is in the window. + * Once input has progressed beyond window size, dictionary cannot be referenced anymore. + * + * In normal dict mode, the dictionary lies between lowLimit and dictLimit. + * In dictMatchState mode, lowLimit and dictLimit are the same, + * and the dictionary is below them. + * forceWindow and dictMatchState are therefore incompatible. + */ +MEM_STATIC void +ZSTD_window_enforceMaxDist(ZSTD_window_t* window, + const void* blockEnd, + U32 maxDist, + U32* loadedDictEndPtr, + const ZSTD_MatchState_t** dictMatchStatePtr) +{ + U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base); + U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0; + DEBUGLOG(5, "ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u", + (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd); + + /* - When there is no dictionary : loadedDictEnd == 0. + In which case, the test (blockEndIdx > maxDist) is merely to avoid + overflowing next operation `newLowLimit = blockEndIdx - maxDist`. + - When there is a standard dictionary : + Index referential is copied from the dictionary, + which means it starts from 0. + In which case, loadedDictEnd == dictSize, + and it makes sense to compare `blockEndIdx > maxDist + dictSize` + since `blockEndIdx` also starts from zero. + - When there is an attached dictionary : + loadedDictEnd is expressed within the referential of the context, + so it can be directly compared against blockEndIdx. + */ + if (blockEndIdx > maxDist + loadedDictEnd) { + U32 const newLowLimit = blockEndIdx - maxDist; + if (window->lowLimit < newLowLimit) window->lowLimit = newLowLimit; + if (window->dictLimit < window->lowLimit) { + DEBUGLOG(5, "Update dictLimit to match lowLimit, from %u to %u", + (unsigned)window->dictLimit, (unsigned)window->lowLimit); + window->dictLimit = window->lowLimit; + } + /* On reaching window size, dictionaries are invalidated */ + if (loadedDictEndPtr) *loadedDictEndPtr = 0; + if (dictMatchStatePtr) *dictMatchStatePtr = NULL; + } +} + +/* Similar to ZSTD_window_enforceMaxDist(), + * but only invalidates dictionary + * when input progresses beyond window size. + * assumption : loadedDictEndPtr and dictMatchStatePtr are valid (non NULL) + * loadedDictEnd uses same referential as window->base + * maxDist is the window size */ +MEM_STATIC void +ZSTD_checkDictValidity(const ZSTD_window_t* window, + const void* blockEnd, + U32 maxDist, + U32* loadedDictEndPtr, + const ZSTD_MatchState_t** dictMatchStatePtr) +{ + assert(loadedDictEndPtr != NULL); + assert(dictMatchStatePtr != NULL); + { U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base); + U32 const loadedDictEnd = *loadedDictEndPtr; + DEBUGLOG(5, "ZSTD_checkDictValidity: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u", + (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd); + assert(blockEndIdx >= loadedDictEnd); + + if (blockEndIdx > loadedDictEnd + maxDist || loadedDictEnd != window->dictLimit) { + /* On reaching window size, dictionaries are invalidated. + * For simplification, if window size is reached anywhere within next block, + * the dictionary is invalidated for the full block. + * + * We also have to invalidate the dictionary if ZSTD_window_update() has detected + * non-contiguous segments, which means that loadedDictEnd != window->dictLimit. + * loadedDictEnd may be 0, if forceWindow is true, but in that case we never use + * dictMatchState, so setting it to NULL is not a problem. + */ + DEBUGLOG(6, "invalidating dictionary for current block (distance > windowSize)"); + *loadedDictEndPtr = 0; + *dictMatchStatePtr = NULL; + } else { + if (*loadedDictEndPtr != 0) { + DEBUGLOG(6, "dictionary considered valid for current block"); + } } } +} + +MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) { + ZSTD_memset(window, 0, sizeof(*window)); + window->base = (BYTE const*)" "; + window->dictBase = (BYTE const*)" "; + ZSTD_STATIC_ASSERT(ZSTD_DUBT_UNSORTED_MARK < ZSTD_WINDOW_START_INDEX); /* Start above ZSTD_DUBT_UNSORTED_MARK */ + window->dictLimit = ZSTD_WINDOW_START_INDEX; /* start from >0, so that 1st position is valid */ + window->lowLimit = ZSTD_WINDOW_START_INDEX; /* it ensures first and later CCtx usages compress the same */ + window->nextSrc = window->base + ZSTD_WINDOW_START_INDEX; /* see issue #1241 */ + window->nbOverflowCorrections = 0; +} + +/** + * ZSTD_window_update(): + * Updates the window by appending [src, src + srcSize) to the window. + * If it is not contiguous, the current prefix becomes the extDict, and we + * forget about the extDict. Handles overlap of the prefix and extDict. + * Returns non-zero if the segment is contiguous. + */ +MEM_STATIC +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_window_update(ZSTD_window_t* window, + const void* src, size_t srcSize, + int forceNonContiguous) +{ + BYTE const* const ip = (BYTE const*)src; + U32 contiguous = 1; + DEBUGLOG(5, "ZSTD_window_update"); + if (srcSize == 0) + return contiguous; + assert(window->base != NULL); + assert(window->dictBase != NULL); + /* Check if blocks follow each other */ + if (src != window->nextSrc || forceNonContiguous) { + /* not contiguous */ + size_t const distanceFromBase = (size_t)(window->nextSrc - window->base); + DEBUGLOG(5, "Non contiguous blocks, new segment starts at %u", window->dictLimit); + window->lowLimit = window->dictLimit; + assert(distanceFromBase == (size_t)(U32)distanceFromBase); /* should never overflow */ + window->dictLimit = (U32)distanceFromBase; + window->dictBase = window->base; + window->base = ip - distanceFromBase; + /* ms->nextToUpdate = window->dictLimit; */ + if (window->dictLimit - window->lowLimit < HASH_READ_SIZE) window->lowLimit = window->dictLimit; /* too small extDict */ + contiguous = 0; + } + window->nextSrc = ip + srcSize; + /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */ + if ( (ip+srcSize > window->dictBase + window->lowLimit) + & (ip < window->dictBase + window->dictLimit)) { + size_t const highInputIdx = (size_t)((ip + srcSize) - window->dictBase); + U32 const lowLimitMax = (highInputIdx > (size_t)window->dictLimit) ? window->dictLimit : (U32)highInputIdx; + assert(highInputIdx < UINT_MAX); + window->lowLimit = lowLimitMax; + DEBUGLOG(5, "Overlapping extDict and input : new lowLimit = %u", window->lowLimit); + } + return contiguous; +} + +/** + * Returns the lowest allowed match index. It may either be in the ext-dict or the prefix. + */ +MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_MatchState_t* ms, U32 curr, unsigned windowLog) +{ + U32 const maxDistance = 1U << windowLog; + U32 const lowestValid = ms->window.lowLimit; + U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; + U32 const isDictionary = (ms->loadedDictEnd != 0); + /* When using a dictionary the entire dictionary is valid if a single byte of the dictionary + * is within the window. We invalidate the dictionary (and set loadedDictEnd to 0) when it isn't + * valid for the entire block. So this check is sufficient to find the lowest valid match index. + */ + U32 const matchLowest = isDictionary ? lowestValid : withinWindow; + return matchLowest; +} + +/** + * Returns the lowest allowed match index in the prefix. + */ +MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_MatchState_t* ms, U32 curr, unsigned windowLog) +{ + U32 const maxDistance = 1U << windowLog; + U32 const lowestValid = ms->window.dictLimit; + U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; + U32 const isDictionary = (ms->loadedDictEnd != 0); + /* When computing the lowest prefix index we need to take the dictionary into account to handle + * the edge case where the dictionary and the source are contiguous in memory. + */ + U32 const matchLowest = isDictionary ? lowestValid : withinWindow; + return matchLowest; +} + +/* index_safety_check: + * intentional underflow : ensure repIndex isn't overlapping dict + prefix + * @return 1 if values are not overlapping, + * 0 otherwise */ +MEM_STATIC int ZSTD_index_overlap_check(const U32 prefixLowestIndex, const U32 repIndex) { + return ((U32)((prefixLowestIndex-1) - repIndex) >= 3); +} + + +/* debug functions */ +#if (DEBUGLEVEL>=2) + +MEM_STATIC double ZSTD_fWeight(U32 rawStat) +{ + U32 const fp_accuracy = 8; + U32 const fp_multiplier = (1 << fp_accuracy); + U32 const newStat = rawStat + 1; + U32 const hb = ZSTD_highbit32(newStat); + U32 const BWeight = hb * fp_multiplier; + U32 const FWeight = (newStat << fp_accuracy) >> hb; + U32 const weight = BWeight + FWeight; + assert(hb + fp_accuracy < 31); + return (double)weight / fp_multiplier; +} + +/* display a table content, + * listing each element, its frequency, and its predicted bit cost */ +MEM_STATIC void ZSTD_debugTable(const U32* table, U32 max) +{ + unsigned u, sum; + for (u=0, sum=0; u<=max; u++) sum += table[u]; + DEBUGLOG(2, "total nb elts: %u", sum); + for (u=0; u<=max; u++) { + DEBUGLOG(2, "%2u: %5u (%.2f)", + u, table[u], ZSTD_fWeight(sum) - ZSTD_fWeight(table[u]) ); + } +} + +#endif + +/* Short Cache */ + +/* Normally, zstd matchfinders follow this flow: + * 1. Compute hash at ip + * 2. Load index from hashTable[hash] + * 3. Check if *ip == *(base + index) + * In dictionary compression, loading *(base + index) is often an L2 or even L3 miss. + * + * Short cache is an optimization which allows us to avoid step 3 most of the time + * when the data doesn't actually match. With short cache, the flow becomes: + * 1. Compute (hash, currentTag) at ip. currentTag is an 8-bit independent hash at ip. + * 2. Load (index, matchTag) from hashTable[hash]. See ZSTD_writeTaggedIndex to understand how this works. + * 3. Only if currentTag == matchTag, check *ip == *(base + index). Otherwise, continue. + * + * Currently, short cache is only implemented in CDict hashtables. Thus, its use is limited to + * dictMatchState matchfinders. + */ +#define ZSTD_SHORT_CACHE_TAG_BITS 8 +#define ZSTD_SHORT_CACHE_TAG_MASK ((1u << ZSTD_SHORT_CACHE_TAG_BITS) - 1) + +/* Helper function for ZSTD_fillHashTable and ZSTD_fillDoubleHashTable. + * Unpacks hashAndTag into (hash, tag), then packs (index, tag) into hashTable[hash]. */ +MEM_STATIC void ZSTD_writeTaggedIndex(U32* const hashTable, size_t hashAndTag, U32 index) { + size_t const hash = hashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS; + U32 const tag = (U32)(hashAndTag & ZSTD_SHORT_CACHE_TAG_MASK); + assert(index >> (32 - ZSTD_SHORT_CACHE_TAG_BITS) == 0); + hashTable[hash] = (index << ZSTD_SHORT_CACHE_TAG_BITS) | tag; +} + +/* Helper function for short cache matchfinders. + * Unpacks tag1 and tag2 from lower bits of packedTag1 and packedTag2, then checks if the tags match. */ +MEM_STATIC int ZSTD_comparePackedTags(size_t packedTag1, size_t packedTag2) { + U32 const tag1 = packedTag1 & ZSTD_SHORT_CACHE_TAG_MASK; + U32 const tag2 = packedTag2 & ZSTD_SHORT_CACHE_TAG_MASK; + return tag1 == tag2; +} + +/* =============================================================== + * Shared internal declarations + * These prototypes may be called from sources not in lib/compress + * =============================================================== */ + +/* ZSTD_loadCEntropy() : + * dict : must point at beginning of a valid zstd dictionary. + * return : size of dictionary header (size of magic number + dict ID + entropy tables) + * assumptions : magic number supposed already checked + * and dictSize >= 8 */ +size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace, + const void* const dict, size_t dictSize); + +void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs); + +typedef struct { + U32 idx; /* Index in array of ZSTD_Sequence */ + U32 posInSequence; /* Position within sequence at idx */ + size_t posInSrc; /* Number of bytes given by sequences provided so far */ +} ZSTD_SequencePosition; + +/* for benchmark */ +size_t ZSTD_convertBlockSequences(ZSTD_CCtx* cctx, + const ZSTD_Sequence* const inSeqs, size_t nbSequences, + int const repcodeResolution); + +typedef struct { + size_t nbSequences; + size_t blockSize; + size_t litSize; +} BlockSummary; + +BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs); + +/* ============================================================== + * Private declarations + * These prototypes shall only be called from within lib/compress + * ============================================================== */ + +/* ZSTD_getCParamsFromCCtxParams() : + * cParams are built depending on compressionLevel, src size hints, + * LDM and manually set compression parameters. + * Note: srcSizeHint == 0 means 0! + */ +ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( + const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode); + +void ZSTD_resetSeqStore(SeqStore_t* ssPtr); + +/*! ZSTD_getCParamsFromCDict() : + * as the name implies */ +ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict); + +/* ZSTD_compressBegin_advanced_internal() : + * Private use only. To be called from zstdmt_compress.c. */ +size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + ZSTD_dictContentType_e dictContentType, + ZSTD_dictTableLoadMethod_e dtlm, + const ZSTD_CDict* cdict, + const ZSTD_CCtx_params* params, + unsigned long long pledgedSrcSize); + +/* ZSTD_compress_advanced_internal() : + * Private use only. To be called from zstdmt_compress.c. */ +size_t ZSTD_compress_advanced_internal(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + const ZSTD_CCtx_params* params); + + +/* ZSTD_writeLastEmptyBlock() : + * output an empty Block with end-of-frame mark to complete a frame + * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h)) + * or an error code if `dstCapacity` is too small ( 1 */ +U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat); + +/** ZSTD_CCtx_trace() : + * Trace the end of a compression call. + */ +void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize); + +/* Returns 1 if an external sequence producer is registered, otherwise returns 0. */ +MEM_STATIC int ZSTD_hasExtSeqProd(const ZSTD_CCtx_params* params) { + return params->extSeqProdFunc != NULL; +} + +/* =============================================================== + * Deprecated definitions that are still used internally to avoid + * deprecation warnings. These functions are exactly equivalent to + * their public variants, but avoid the deprecation warnings. + * =============================================================== */ + +size_t ZSTD_compressBegin_usingCDict_deprecated(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); + +size_t ZSTD_compressContinue_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + +size_t ZSTD_compressEnd_public(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + +size_t ZSTD_compressBlock_deprecated(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); + + +#endif /* ZSTD_COMPRESS_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_literals.c b/src/commonlib/bsd/zstd/compress/zstd_compress_literals.c new file mode 100644 index 00000000000..7c4960e6d69 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_literals.c @@ -0,0 +1,237 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + /*-************************************* + * Dependencies + ***************************************/ +#include "zstd_compress_literals.h" + + +/* ************************************************************** +* Debug Traces +****************************************************************/ +#if DEBUGLEVEL >= 2 + +static size_t showHexa(const void* src, size_t srcSize) +{ + const BYTE* const ip = (const BYTE*)src; + size_t u; + for (u=0; u31) + (srcSize>4095); + + DEBUGLOG(5, "ZSTD_noCompressLiterals: srcSize=%zu, dstCapacity=%zu", srcSize, dstCapacity); + + RETURN_ERROR_IF(srcSize + flSize > dstCapacity, dstSize_tooSmall, ""); + + switch(flSize) + { + case 1: /* 2 - 1 - 5 */ + ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3)); + break; + case 2: /* 2 - 2 - 12 */ + MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4))); + break; + case 3: /* 2 - 2 - 20 */ + MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4))); + break; + default: /* not necessary : flSize is {1,2,3} */ + assert(0); + } + + ZSTD_memcpy(ostart + flSize, src, srcSize); + DEBUGLOG(5, "Raw (uncompressed) literals: %u -> %u", (U32)srcSize, (U32)(srcSize + flSize)); + return srcSize + flSize; +} + +static int allBytesIdentical(const void* src, size_t srcSize) +{ + assert(srcSize >= 1); + assert(src != NULL); + { const BYTE b = ((const BYTE*)src)[0]; + size_t p; + for (p=1; p31) + (srcSize>4095); + + assert(dstCapacity >= 4); (void)dstCapacity; + assert(allBytesIdentical(src, srcSize)); + + switch(flSize) + { + case 1: /* 2 - 1 - 5 */ + ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3)); + break; + case 2: /* 2 - 2 - 12 */ + MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4))); + break; + case 3: /* 2 - 2 - 20 */ + MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4))); + break; + default: /* not necessary : flSize is {1,2,3} */ + assert(0); + } + + ostart[flSize] = *(const BYTE*)src; + DEBUGLOG(5, "RLE : Repeated Literal (%02X: %u times) -> %u bytes encoded", ((const BYTE*)src)[0], (U32)srcSize, (U32)flSize + 1); + return flSize+1; +} + +/* ZSTD_minLiteralsToCompress() : + * returns minimal amount of literals + * for literal compression to even be attempted. + * Minimum is made tighter as compression strategy increases. + */ +static size_t +ZSTD_minLiteralsToCompress(ZSTD_strategy strategy, HUF_repeat huf_repeat) +{ + assert((int)strategy >= 0); + assert((int)strategy <= 9); + /* btultra2 : min 8 bytes; + * then 2x larger for each successive compression strategy + * max threshold 64 bytes */ + { int const shift = MIN(9-(int)strategy, 3); + size_t const mintc = (huf_repeat == HUF_repeat_valid) ? 6 : (size_t)8 << shift; + DEBUGLOG(7, "minLiteralsToCompress = %zu", mintc); + return mintc; + } +} + +size_t ZSTD_compressLiterals ( + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + void* entropyWorkspace, size_t entropyWorkspaceSize, + const ZSTD_hufCTables_t* prevHuf, + ZSTD_hufCTables_t* nextHuf, + ZSTD_strategy strategy, + int disableLiteralCompression, + int suspectUncompressible, + int bmi2) +{ + size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB); + BYTE* const ostart = (BYTE*)dst; + U32 singleStream = srcSize < 256; + SymbolEncodingType_e hType = set_compressed; + size_t cLitSize; + + DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i, srcSize=%u, dstCapacity=%zu)", + disableLiteralCompression, (U32)srcSize, dstCapacity); + + DEBUGLOG(6, "Completed literals listing (%zu bytes)", showHexa(src, srcSize)); + + /* Prepare nextEntropy assuming reusing the existing table */ + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + + if (disableLiteralCompression) + return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); + + /* if too small, don't even attempt compression (speed opt) */ + if (srcSize < ZSTD_minLiteralsToCompress(strategy, prevHuf->repeatMode)) + return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); + + RETURN_ERROR_IF(dstCapacity < lhSize+1, dstSize_tooSmall, "not enough space for compression"); + { HUF_repeat repeat = prevHuf->repeatMode; + int const flags = 0 + | (bmi2 ? HUF_flags_bmi2 : 0) + | (strategy < ZSTD_lazy && srcSize <= 1024 ? HUF_flags_preferRepeat : 0) + | (strategy >= HUF_OPTIMAL_DEPTH_THRESHOLD ? HUF_flags_optimalDepth : 0) + | (suspectUncompressible ? HUF_flags_suspectUncompressible : 0); + + typedef size_t (*huf_compress_f)(void*, size_t, const void*, size_t, unsigned, unsigned, void*, size_t, HUF_CElt*, HUF_repeat*, int); + huf_compress_f huf_compress; + if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1; + huf_compress = singleStream ? HUF_compress1X_repeat : HUF_compress4X_repeat; + cLitSize = huf_compress(ostart+lhSize, dstCapacity-lhSize, + src, srcSize, + HUF_SYMBOLVALUE_MAX, LitHufLog, + entropyWorkspace, entropyWorkspaceSize, + (HUF_CElt*)nextHuf->CTable, + &repeat, flags); + DEBUGLOG(5, "%zu literals compressed into %zu bytes (before header)", srcSize, cLitSize); + if (repeat != HUF_repeat_none) { + /* reused the existing table */ + DEBUGLOG(5, "reusing statistics from previous huffman block"); + hType = set_repeat; + } + } + + { size_t const minGain = ZSTD_minGain(srcSize, strategy); + if ((cLitSize==0) || (cLitSize >= srcSize - minGain) || ERR_isError(cLitSize)) { + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize); + } } + if (cLitSize==1) { + /* A return value of 1 signals that the alphabet consists of a single symbol. + * However, in some rare circumstances, it could be the compressed size (a single byte). + * For that outcome to have a chance to happen, it's necessary that `srcSize < 8`. + * (it's also necessary to not generate statistics). + * Therefore, in such a case, actively check that all bytes are identical. */ + if ((srcSize >= 8) || allBytesIdentical(src, srcSize)) { + ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf)); + return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize); + } } + + if (hType == set_compressed) { + /* using a newly constructed table */ + nextHuf->repeatMode = HUF_repeat_check; + } + + /* Build header */ + switch(lhSize) + { + case 3: /* 2 - 2 - 10 - 10 */ + if (!singleStream) assert(srcSize >= MIN_LITERALS_FOR_4_STREAMS); + { U32 const lhc = hType + ((U32)(!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14); + MEM_writeLE24(ostart, lhc); + break; + } + case 4: /* 2 - 2 - 14 - 14 */ + assert(srcSize >= MIN_LITERALS_FOR_4_STREAMS); + { U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18); + MEM_writeLE32(ostart, lhc); + break; + } + case 5: /* 2 - 2 - 18 - 18 */ + assert(srcSize >= MIN_LITERALS_FOR_4_STREAMS); + { U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22); + MEM_writeLE32(ostart, lhc); + ostart[4] = (BYTE)(cLitSize >> 10); + break; + } + default: /* not possible : lhSize is {3,4,5} */ + assert(0); + } + DEBUGLOG(5, "Compressed literals: %u -> %u", (U32)srcSize, (U32)(lhSize+cLitSize)); + return lhSize+cLitSize; +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_literals.h b/src/commonlib/bsd/zstd/compress/zstd_compress_literals.h new file mode 100644 index 00000000000..994ca02e4d2 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_literals.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPRESS_LITERALS_H +#define ZSTD_COMPRESS_LITERALS_H + +#include "zstd_compress_internal.h" /* ZSTD_hufCTables_t, ZSTD_minGain() */ + + +size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize); + +/* ZSTD_compressRleLiteralsBlock() : + * Conditions : + * - All bytes in @src are identical + * - dstCapacity >= 4 */ +size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize); + +/* ZSTD_compressLiterals(): + * @entropyWorkspace: must be aligned on 4-bytes boundaries + * @entropyWorkspaceSize : must be >= HUF_WORKSPACE_SIZE + * @suspectUncompressible: sampling checks, to potentially skip huffman coding + */ +size_t ZSTD_compressLiterals (void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + void* entropyWorkspace, size_t entropyWorkspaceSize, + const ZSTD_hufCTables_t* prevHuf, + ZSTD_hufCTables_t* nextHuf, + ZSTD_strategy strategy, int disableLiteralCompression, + int suspectUncompressible, + int bmi2); + +#endif /* ZSTD_COMPRESS_LITERALS_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_sequences.c b/src/commonlib/bsd/zstd/compress/zstd_compress_sequences.c new file mode 100644 index 00000000000..46b43b5bc9d --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_sequences.c @@ -0,0 +1,444 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + /*-************************************* + * Dependencies + ***************************************/ +#include "zstd_compress_sequences.h" + +/** + * -log2(x / 256) lookup table for x in [0, 256). + * If x == 0: Return 0 + * Else: Return floor(-log2(x / 256) * 256) + */ +static unsigned const kInverseProbabilityLog256[256] = { + 0, 2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162, + 1130, 1100, 1073, 1047, 1024, 1001, 980, 960, 941, 923, 906, 889, + 874, 859, 844, 830, 817, 804, 791, 779, 768, 756, 745, 734, + 724, 714, 704, 694, 685, 676, 667, 658, 650, 642, 633, 626, + 618, 610, 603, 595, 588, 581, 574, 567, 561, 554, 548, 542, + 535, 529, 523, 517, 512, 506, 500, 495, 489, 484, 478, 473, + 468, 463, 458, 453, 448, 443, 438, 434, 429, 424, 420, 415, + 411, 407, 402, 398, 394, 390, 386, 382, 377, 373, 370, 366, + 362, 358, 354, 350, 347, 343, 339, 336, 332, 329, 325, 322, + 318, 315, 311, 308, 305, 302, 298, 295, 292, 289, 286, 282, + 279, 276, 273, 270, 267, 264, 261, 258, 256, 253, 250, 247, + 244, 241, 239, 236, 233, 230, 228, 225, 222, 220, 217, 215, + 212, 209, 207, 204, 202, 199, 197, 194, 192, 190, 187, 185, + 182, 180, 178, 175, 173, 171, 168, 166, 164, 162, 159, 157, + 155, 153, 151, 149, 146, 144, 142, 140, 138, 136, 134, 132, + 130, 128, 126, 123, 121, 119, 117, 115, 114, 112, 110, 108, + 106, 104, 102, 100, 98, 96, 94, 93, 91, 89, 87, 85, + 83, 82, 80, 78, 76, 74, 73, 71, 69, 67, 66, 64, + 62, 61, 59, 57, 55, 54, 52, 50, 49, 47, 46, 44, + 42, 41, 39, 37, 36, 34, 33, 31, 30, 28, 26, 25, + 23, 22, 20, 19, 17, 16, 14, 13, 11, 10, 8, 7, + 5, 4, 2, 1, +}; + +static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) { + void const* ptr = ctable; + U16 const* u16ptr = (U16 const*)ptr; + U32 const maxSymbolValue = MEM_read16(u16ptr + 1); + return maxSymbolValue; +} + +/** + * Returns true if we should use ncount=-1 else we should + * use ncount=1 for low probability symbols instead. + */ +static unsigned ZSTD_useLowProbCount(size_t const nbSeq) +{ + /* Heuristic: This should cover most blocks <= 16K and + * start to fade out after 16K to about 32K depending on + * compressibility. + */ + return nbSeq >= 2048; +} + +/** + * Returns the cost in bytes of encoding the normalized count header. + * Returns an error if any of the helper functions return an error. + */ +static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max, + size_t const nbSeq, unsigned const FSELog) +{ + BYTE wksp[FSE_NCOUNTBOUND]; + S16 norm[MaxSeq + 1]; + const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max); + FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max, ZSTD_useLowProbCount(nbSeq)), ""); + return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog); +} + +/** + * Returns the cost in bits of encoding the distribution described by count + * using the entropy bound. + */ +static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total) +{ + unsigned cost = 0; + unsigned s; + + assert(total > 0); + for (s = 0; s <= max; ++s) { + unsigned norm = (unsigned)((256 * count[s]) / total); + if (count[s] != 0 && norm == 0) + norm = 1; + assert(count[s] < total); + cost += count[s] * kInverseProbabilityLog256[norm]; + } + return cost >> 8; +} + +/** + * Returns the cost in bits of encoding the distribution in count using ctable. + * Returns an error if ctable cannot represent all the symbols in count. + */ +size_t ZSTD_fseBitCost( + FSE_CTable const* ctable, + unsigned const* count, + unsigned const max) +{ + unsigned const kAccuracyLog = 8; + size_t cost = 0; + unsigned s; + FSE_CState_t cstate; + FSE_initCState(&cstate, ctable); + if (ZSTD_getFSEMaxSymbolValue(ctable) < max) { + DEBUGLOG(5, "Repeat FSE_CTable has maxSymbolValue %u < %u", + ZSTD_getFSEMaxSymbolValue(ctable), max); + return ERROR(GENERIC); + } + for (s = 0; s <= max; ++s) { + unsigned const tableLog = cstate.stateLog; + unsigned const badCost = (tableLog + 1) << kAccuracyLog; + unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog); + if (count[s] == 0) + continue; + if (bitCost >= badCost) { + DEBUGLOG(5, "Repeat FSE_CTable has Prob[%u] == 0", s); + return ERROR(GENERIC); + } + cost += (size_t)count[s] * bitCost; + } + return cost >> kAccuracyLog; +} + +/** + * Returns the cost in bits of encoding the distribution in count using the + * table described by norm. The max symbol support by norm is assumed >= max. + * norm must be valid for every symbol with non-zero probability in count. + */ +size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog, + unsigned const* count, unsigned const max) +{ + unsigned const shift = 8 - accuracyLog; + size_t cost = 0; + unsigned s; + assert(accuracyLog <= 8); + for (s = 0; s <= max; ++s) { + unsigned const normAcc = (norm[s] != -1) ? (unsigned)norm[s] : 1; + unsigned const norm256 = normAcc << shift; + assert(norm256 > 0); + assert(norm256 < 256); + cost += count[s] * kInverseProbabilityLog256[norm256]; + } + return cost >> 8; +} + +SymbolEncodingType_e +ZSTD_selectEncodingType( + FSE_repeat* repeatMode, unsigned const* count, unsigned const max, + size_t const mostFrequent, size_t nbSeq, unsigned const FSELog, + FSE_CTable const* prevCTable, + short const* defaultNorm, U32 defaultNormLog, + ZSTD_DefaultPolicy_e const isDefaultAllowed, + ZSTD_strategy const strategy) +{ + ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0); + if (mostFrequent == nbSeq) { + *repeatMode = FSE_repeat_none; + if (isDefaultAllowed && nbSeq <= 2) { + /* Prefer set_basic over set_rle when there are 2 or fewer symbols, + * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol. + * If basic encoding isn't possible, always choose RLE. + */ + DEBUGLOG(5, "Selected set_basic"); + return set_basic; + } + DEBUGLOG(5, "Selected set_rle"); + return set_rle; + } + if (strategy < ZSTD_lazy) { + if (isDefaultAllowed) { + size_t const staticFse_nbSeq_max = 1000; + size_t const mult = 10 - strategy; + size_t const baseLog = 3; + size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog; /* 28-36 for offset, 56-72 for lengths */ + assert(defaultNormLog >= 5 && defaultNormLog <= 6); /* xx_DEFAULTNORMLOG */ + assert(mult <= 9 && mult >= 7); + if ( (*repeatMode == FSE_repeat_valid) + && (nbSeq < staticFse_nbSeq_max) ) { + DEBUGLOG(5, "Selected set_repeat"); + return set_repeat; + } + if ( (nbSeq < dynamicFse_nbSeq_min) + || (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) { + DEBUGLOG(5, "Selected set_basic"); + /* The format allows default tables to be repeated, but it isn't useful. + * When using simple heuristics to select encoding type, we don't want + * to confuse these tables with dictionaries. When running more careful + * analysis, we don't need to waste time checking both repeating tables + * and default tables. + */ + *repeatMode = FSE_repeat_none; + return set_basic; + } + } + } else { + size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC); + size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC); + size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog); + size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq); + + if (isDefaultAllowed) { + assert(!ZSTD_isError(basicCost)); + assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost))); + } + assert(!ZSTD_isError(NCountCost)); + assert(compressedCost < ERROR(maxCode)); + DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u", + (unsigned)basicCost, (unsigned)repeatCost, (unsigned)compressedCost); + if (basicCost <= repeatCost && basicCost <= compressedCost) { + DEBUGLOG(5, "Selected set_basic"); + assert(isDefaultAllowed); + *repeatMode = FSE_repeat_none; + return set_basic; + } + if (repeatCost <= compressedCost) { + DEBUGLOG(5, "Selected set_repeat"); + assert(!ZSTD_isError(repeatCost)); + return set_repeat; + } + assert(compressedCost < basicCost && compressedCost < repeatCost); + } + DEBUGLOG(5, "Selected set_compressed"); + *repeatMode = FSE_repeat_check; + return set_compressed; +} + +typedef struct { + S16 norm[MaxSeq + 1]; + U32 wksp[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(MaxSeq, MaxFSELog)]; +} ZSTD_BuildCTableWksp; + +size_t +ZSTD_buildCTable(void* dst, size_t dstCapacity, + FSE_CTable* nextCTable, U32 FSELog, SymbolEncodingType_e type, + unsigned* count, U32 max, + const BYTE* codeTable, size_t nbSeq, + const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax, + const FSE_CTable* prevCTable, size_t prevCTableSize, + void* entropyWorkspace, size_t entropyWorkspaceSize) +{ + BYTE* op = (BYTE*)dst; + const BYTE* const oend = op + dstCapacity; + DEBUGLOG(6, "ZSTD_buildCTable (dstCapacity=%u)", (unsigned)dstCapacity); + + switch (type) { + case set_rle: + FORWARD_IF_ERROR(FSE_buildCTable_rle(nextCTable, (BYTE)max), ""); + RETURN_ERROR_IF(dstCapacity==0, dstSize_tooSmall, "not enough space"); + *op = codeTable[0]; + return 1; + case set_repeat: + ZSTD_memcpy(nextCTable, prevCTable, prevCTableSize); + return 0; + case set_basic: + FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize), ""); /* note : could be pre-calculated */ + return 0; + case set_compressed: { + ZSTD_BuildCTableWksp* wksp = (ZSTD_BuildCTableWksp*)entropyWorkspace; + size_t nbSeq_1 = nbSeq; + const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max); + if (count[codeTable[nbSeq-1]] > 1) { + count[codeTable[nbSeq-1]]--; + nbSeq_1--; + } + assert(nbSeq_1 > 1); + assert(entropyWorkspaceSize >= sizeof(ZSTD_BuildCTableWksp)); + (void)entropyWorkspaceSize; + FORWARD_IF_ERROR(FSE_normalizeCount(wksp->norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "FSE_normalizeCount failed"); + assert(oend >= op); + { size_t const NCountSize = FSE_writeNCount(op, (size_t)(oend - op), wksp->norm, max, tableLog); /* overflow protected */ + FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed"); + FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, wksp->norm, max, tableLog, wksp->wksp, sizeof(wksp->wksp)), "FSE_buildCTable_wksp failed"); + return NCountSize; + } + } + default: assert(0); RETURN_ERROR(GENERIC, "impossible to reach"); + } +} + +FORCE_INLINE_TEMPLATE size_t +ZSTD_encodeSequences_body( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets) +{ + BIT_CStream_t blockStream; + FSE_CState_t stateMatchLength; + FSE_CState_t stateOffsetBits; + FSE_CState_t stateLitLength; + + RETURN_ERROR_IF( + ERR_isError(BIT_initCStream(&blockStream, dst, dstCapacity)), + dstSize_tooSmall, "not enough space remaining"); + DEBUGLOG(6, "available space for bitstream : %i (dstCapacity=%u)", + (int)(blockStream.endPtr - blockStream.startPtr), + (unsigned)dstCapacity); + + /* first symbols */ + FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]); + FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq-1]); + FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq-1]); + BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]); + if (MEM_32bits()) BIT_flushBits(&blockStream); + BIT_addBits(&blockStream, sequences[nbSeq-1].mlBase, ML_bits[mlCodeTable[nbSeq-1]]); + if (MEM_32bits()) BIT_flushBits(&blockStream); + if (longOffsets) { + U32 const ofBits = ofCodeTable[nbSeq-1]; + unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1); + if (extraBits) { + BIT_addBits(&blockStream, sequences[nbSeq-1].offBase, extraBits); + BIT_flushBits(&blockStream); + } + BIT_addBits(&blockStream, sequences[nbSeq-1].offBase >> extraBits, + ofBits - extraBits); + } else { + BIT_addBits(&blockStream, sequences[nbSeq-1].offBase, ofCodeTable[nbSeq-1]); + } + BIT_flushBits(&blockStream); + + { size_t n; + for (n=nbSeq-2 ; n= 64-7-(LLFSELog+MLFSELog+OffFSELog))) + BIT_flushBits(&blockStream); /* (7)*/ + BIT_addBits(&blockStream, sequences[n].litLength, llBits); + if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream); + BIT_addBits(&blockStream, sequences[n].mlBase, mlBits); + if (MEM_32bits() || (ofBits+mlBits+llBits > 56)) BIT_flushBits(&blockStream); + if (longOffsets) { + unsigned const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1); + if (extraBits) { + BIT_addBits(&blockStream, sequences[n].offBase, extraBits); + BIT_flushBits(&blockStream); /* (7)*/ + } + BIT_addBits(&blockStream, sequences[n].offBase >> extraBits, + ofBits - extraBits); /* 31 */ + } else { + BIT_addBits(&blockStream, sequences[n].offBase, ofBits); /* 31 */ + } + BIT_flushBits(&blockStream); /* (7)*/ + DEBUGLOG(7, "remaining space : %i", (int)(blockStream.endPtr - blockStream.ptr)); + } } + + DEBUGLOG(6, "ZSTD_encodeSequences: flushing ML state with %u bits", stateMatchLength.stateLog); + FSE_flushCState(&blockStream, &stateMatchLength); + DEBUGLOG(6, "ZSTD_encodeSequences: flushing Off state with %u bits", stateOffsetBits.stateLog); + FSE_flushCState(&blockStream, &stateOffsetBits); + DEBUGLOG(6, "ZSTD_encodeSequences: flushing LL state with %u bits", stateLitLength.stateLog); + FSE_flushCState(&blockStream, &stateLitLength); + + { size_t const streamSize = BIT_closeCStream(&blockStream); + RETURN_ERROR_IF(streamSize==0, dstSize_tooSmall, "not enough space"); + return streamSize; + } +} + +static size_t +ZSTD_encodeSequences_default( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets) +{ + return ZSTD_encodeSequences_body(dst, dstCapacity, + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, longOffsets); +} + + +#if DYNAMIC_BMI2 + +static BMI2_TARGET_ATTRIBUTE size_t +ZSTD_encodeSequences_bmi2( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets) +{ + return ZSTD_encodeSequences_body(dst, dstCapacity, + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, longOffsets); +} + +#endif + +size_t ZSTD_encodeSequences( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2) +{ + DEBUGLOG(5, "ZSTD_encodeSequences: dstCapacity = %u", (unsigned)dstCapacity); +#if DYNAMIC_BMI2 + if (bmi2) { + return ZSTD_encodeSequences_bmi2(dst, dstCapacity, + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, longOffsets); + } +#endif + (void)bmi2; + return ZSTD_encodeSequences_default(dst, dstCapacity, + CTable_MatchLength, mlCodeTable, + CTable_OffsetBits, ofCodeTable, + CTable_LitLength, llCodeTable, + sequences, nbSeq, longOffsets); +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_sequences.h b/src/commonlib/bsd/zstd/compress/zstd_compress_sequences.h new file mode 100644 index 00000000000..bcc1da97e3b --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_sequences.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPRESS_SEQUENCES_H +#define ZSTD_COMPRESS_SEQUENCES_H + +#include "zstd_compress_internal.h" /* SeqDef */ +#include "../common/fse.h" /* FSE_repeat, FSE_CTable */ +#include "../common/zstd_internal.h" /* SymbolEncodingType_e, ZSTD_strategy */ + +typedef enum { + ZSTD_defaultDisallowed = 0, + ZSTD_defaultAllowed = 1 +} ZSTD_DefaultPolicy_e; + +SymbolEncodingType_e +ZSTD_selectEncodingType( + FSE_repeat* repeatMode, unsigned const* count, unsigned const max, + size_t const mostFrequent, size_t nbSeq, unsigned const FSELog, + FSE_CTable const* prevCTable, + short const* defaultNorm, U32 defaultNormLog, + ZSTD_DefaultPolicy_e const isDefaultAllowed, + ZSTD_strategy const strategy); + +size_t +ZSTD_buildCTable(void* dst, size_t dstCapacity, + FSE_CTable* nextCTable, U32 FSELog, SymbolEncodingType_e type, + unsigned* count, U32 max, + const BYTE* codeTable, size_t nbSeq, + const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax, + const FSE_CTable* prevCTable, size_t prevCTableSize, + void* entropyWorkspace, size_t entropyWorkspaceSize); + +size_t ZSTD_encodeSequences( + void* dst, size_t dstCapacity, + FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable, + FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable, + FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable, + SeqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2); + +size_t ZSTD_fseBitCost( + FSE_CTable const* ctable, + unsigned const* count, + unsigned const max); + +size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog, + unsigned const* count, unsigned const max); +#endif /* ZSTD_COMPRESS_SEQUENCES_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_superblock.c b/src/commonlib/bsd/zstd/compress/zstd_compress_superblock.c new file mode 100644 index 00000000000..85a2f1c2317 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_superblock.c @@ -0,0 +1,690 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + /*-************************************* + * Dependencies + ***************************************/ +#include "zstd_compress_superblock.h" + +#include "../common/zstd_internal.h" /* ZSTD_getSequenceLength */ +#include "hist.h" /* HIST_countFast_wksp */ +#include "zstd_compress_internal.h" /* ZSTD_[huf|fse|entropy]CTablesMetadata_t */ +#include "zstd_compress_sequences.h" +#include "zstd_compress_literals.h" + +/** ZSTD_compressSubBlock_literal() : + * Compresses literals section for a sub-block. + * When we have to write the Huffman table we will sometimes choose a header + * size larger than necessary. This is because we have to pick the header size + * before we know the table size + compressed size, so we have a bound on the + * table size. If we guessed incorrectly, we fall back to uncompressed literals. + * + * We write the header when writeEntropy=1 and set entropyWritten=1 when we succeeded + * in writing the header, otherwise it is set to 0. + * + * hufMetadata->hType has literals block type info. + * If it is set_basic, all sub-blocks literals section will be Raw_Literals_Block. + * If it is set_rle, all sub-blocks literals section will be RLE_Literals_Block. + * If it is set_compressed, first sub-block's literals section will be Compressed_Literals_Block + * If it is set_compressed, first sub-block's literals section will be Treeless_Literals_Block + * and the following sub-blocks' literals sections will be Treeless_Literals_Block. + * @return : compressed size of literals section of a sub-block + * Or 0 if unable to compress. + * Or error code */ +static size_t +ZSTD_compressSubBlock_literal(const HUF_CElt* hufTable, + const ZSTD_hufCTablesMetadata_t* hufMetadata, + const BYTE* literals, size_t litSize, + void* dst, size_t dstSize, + const int bmi2, int writeEntropy, int* entropyWritten) +{ + size_t const header = writeEntropy ? 200 : 0; + size_t const lhSize = 3 + (litSize >= (1 KB - header)) + (litSize >= (16 KB - header)); + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstSize; + BYTE* op = ostart + lhSize; + U32 const singleStream = lhSize == 3; + SymbolEncodingType_e hType = writeEntropy ? hufMetadata->hType : set_repeat; + size_t cLitSize = 0; + + DEBUGLOG(5, "ZSTD_compressSubBlock_literal (litSize=%zu, lhSize=%zu, writeEntropy=%d)", litSize, lhSize, writeEntropy); + + *entropyWritten = 0; + if (litSize == 0 || hufMetadata->hType == set_basic) { + DEBUGLOG(5, "ZSTD_compressSubBlock_literal using raw literal"); + return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize); + } else if (hufMetadata->hType == set_rle) { + DEBUGLOG(5, "ZSTD_compressSubBlock_literal using rle literal"); + return ZSTD_compressRleLiteralsBlock(dst, dstSize, literals, litSize); + } + + assert(litSize > 0); + assert(hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat); + + if (writeEntropy && hufMetadata->hType == set_compressed) { + ZSTD_memcpy(op, hufMetadata->hufDesBuffer, hufMetadata->hufDesSize); + op += hufMetadata->hufDesSize; + cLitSize += hufMetadata->hufDesSize; + DEBUGLOG(5, "ZSTD_compressSubBlock_literal (hSize=%zu)", hufMetadata->hufDesSize); + } + + { int const flags = bmi2 ? HUF_flags_bmi2 : 0; + const size_t cSize = singleStream ? HUF_compress1X_usingCTable(op, (size_t)(oend-op), literals, litSize, hufTable, flags) + : HUF_compress4X_usingCTable(op, (size_t)(oend-op), literals, litSize, hufTable, flags); + op += cSize; + cLitSize += cSize; + if (cSize == 0 || ERR_isError(cSize)) { + DEBUGLOG(5, "Failed to write entropy tables %s", ZSTD_getErrorName(cSize)); + return 0; + } + /* If we expand and we aren't writing a header then emit uncompressed */ + if (!writeEntropy && cLitSize >= litSize) { + DEBUGLOG(5, "ZSTD_compressSubBlock_literal using raw literal because uncompressible"); + return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize); + } + /* If we are writing headers then allow expansion that doesn't change our header size. */ + if (lhSize < (size_t)(3 + (cLitSize >= 1 KB) + (cLitSize >= 16 KB))) { + assert(cLitSize > litSize); + DEBUGLOG(5, "Literals expanded beyond allowed header size"); + return ZSTD_noCompressLiterals(dst, dstSize, literals, litSize); + } + DEBUGLOG(5, "ZSTD_compressSubBlock_literal (cSize=%zu)", cSize); + } + + /* Build header */ + switch(lhSize) + { + case 3: /* 2 - 2 - 10 - 10 */ + { U32 const lhc = hType + ((U32)(!singleStream) << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<14); + MEM_writeLE24(ostart, lhc); + break; + } + case 4: /* 2 - 2 - 14 - 14 */ + { U32 const lhc = hType + (2 << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<18); + MEM_writeLE32(ostart, lhc); + break; + } + case 5: /* 2 - 2 - 18 - 18 */ + { U32 const lhc = hType + (3 << 2) + ((U32)litSize<<4) + ((U32)cLitSize<<22); + MEM_writeLE32(ostart, lhc); + ostart[4] = (BYTE)(cLitSize >> 10); + break; + } + default: /* not possible : lhSize is {3,4,5} */ + assert(0); + } + *entropyWritten = 1; + DEBUGLOG(5, "Compressed literals: %u -> %u", (U32)litSize, (U32)(op-ostart)); + return (size_t)(op-ostart); +} + +static size_t +ZSTD_seqDecompressedSize(SeqStore_t const* seqStore, + const SeqDef* sequences, size_t nbSeqs, + size_t litSize, int lastSubBlock) +{ + size_t matchLengthSum = 0; + size_t litLengthSum = 0; + size_t n; + for (n=0; nllType, fseMetadata->ofType, and fseMetadata->mlType have + * symbol compression modes for the super-block. + * The first successfully compressed block will have these in its header. + * We set entropyWritten=1 when we succeed in compressing the sequences. + * The following sub-blocks will always have repeat mode. + * @return : compressed size of sequences section of a sub-block + * Or 0 if it is unable to compress + * Or error code. */ +static size_t +ZSTD_compressSubBlock_sequences(const ZSTD_fseCTables_t* fseTables, + const ZSTD_fseCTablesMetadata_t* fseMetadata, + const SeqDef* sequences, size_t nbSeq, + const BYTE* llCode, const BYTE* mlCode, const BYTE* ofCode, + const ZSTD_CCtx_params* cctxParams, + void* dst, size_t dstCapacity, + const int bmi2, int writeEntropy, int* entropyWritten) +{ + const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstCapacity; + BYTE* op = ostart; + BYTE* seqHead; + + DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (nbSeq=%zu, writeEntropy=%d, longOffsets=%d)", nbSeq, writeEntropy, longOffsets); + + *entropyWritten = 0; + /* Sequences Header */ + RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/, + dstSize_tooSmall, ""); + if (nbSeq < 128) + *op++ = (BYTE)nbSeq; + else if (nbSeq < LONGNBSEQ) + op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2; + else + op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3; + if (nbSeq==0) { + return (size_t)(op - ostart); + } + + /* seqHead : flags for FSE encoding type */ + seqHead = op++; + + DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (seqHeadSize=%u)", (unsigned)(op-ostart)); + + if (writeEntropy) { + const U32 LLtype = fseMetadata->llType; + const U32 Offtype = fseMetadata->ofType; + const U32 MLtype = fseMetadata->mlType; + DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (fseTablesSize=%zu)", fseMetadata->fseTablesSize); + *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2)); + ZSTD_memcpy(op, fseMetadata->fseTablesBuffer, fseMetadata->fseTablesSize); + op += fseMetadata->fseTablesSize; + } else { + const U32 repeat = set_repeat; + *seqHead = (BYTE)((repeat<<6) + (repeat<<4) + (repeat<<2)); + } + + { size_t const bitstreamSize = ZSTD_encodeSequences( + op, (size_t)(oend - op), + fseTables->matchlengthCTable, mlCode, + fseTables->offcodeCTable, ofCode, + fseTables->litlengthCTable, llCode, + sequences, nbSeq, + longOffsets, bmi2); + FORWARD_IF_ERROR(bitstreamSize, "ZSTD_encodeSequences failed"); + op += bitstreamSize; + /* zstd versions <= 1.3.4 mistakenly report corruption when + * FSE_readNCount() receives a buffer < 4 bytes. + * Fixed by https://github.com/facebook/zstd/pull/1146. + * This can happen when the last set_compressed table present is 2 + * bytes and the bitstream is only one byte. + * In this exceedingly rare case, we will simply emit an uncompressed + * block, since it isn't worth optimizing. + */ +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if (writeEntropy && fseMetadata->lastCountSize && fseMetadata->lastCountSize + bitstreamSize < 4) { + /* NCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */ + assert(fseMetadata->lastCountSize + bitstreamSize == 3); + DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by " + "emitting an uncompressed block."); + return 0; + } +#endif + DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (bitstreamSize=%zu)", bitstreamSize); + } + + /* zstd versions <= 1.4.0 mistakenly report error when + * sequences section body size is less than 3 bytes. + * Fixed by https://github.com/facebook/zstd/pull/1664. + * This can happen when the previous sequences section block is compressed + * with rle mode and the current block's sequences section is compressed + * with repeat mode where sequences section body size can be 1 byte. + */ +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if (op-seqHead < 4) { + DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.4.0 by emitting " + "an uncompressed block when sequences are < 4 bytes"); + return 0; + } +#endif + + *entropyWritten = 1; + return (size_t)(op - ostart); +} + +/** ZSTD_compressSubBlock() : + * Compresses a single sub-block. + * @return : compressed size of the sub-block + * Or 0 if it failed to compress. */ +static size_t ZSTD_compressSubBlock(const ZSTD_entropyCTables_t* entropy, + const ZSTD_entropyCTablesMetadata_t* entropyMetadata, + const SeqDef* sequences, size_t nbSeq, + const BYTE* literals, size_t litSize, + const BYTE* llCode, const BYTE* mlCode, const BYTE* ofCode, + const ZSTD_CCtx_params* cctxParams, + void* dst, size_t dstCapacity, + const int bmi2, + int writeLitEntropy, int writeSeqEntropy, + int* litEntropyWritten, int* seqEntropyWritten, + U32 lastBlock) +{ + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstCapacity; + BYTE* op = ostart + ZSTD_blockHeaderSize; + DEBUGLOG(5, "ZSTD_compressSubBlock (litSize=%zu, nbSeq=%zu, writeLitEntropy=%d, writeSeqEntropy=%d, lastBlock=%d)", + litSize, nbSeq, writeLitEntropy, writeSeqEntropy, lastBlock); + { size_t cLitSize = ZSTD_compressSubBlock_literal((const HUF_CElt*)entropy->huf.CTable, + &entropyMetadata->hufMetadata, literals, litSize, + op, (size_t)(oend-op), + bmi2, writeLitEntropy, litEntropyWritten); + FORWARD_IF_ERROR(cLitSize, "ZSTD_compressSubBlock_literal failed"); + if (cLitSize == 0) return 0; + op += cLitSize; + } + { size_t cSeqSize = ZSTD_compressSubBlock_sequences(&entropy->fse, + &entropyMetadata->fseMetadata, + sequences, nbSeq, + llCode, mlCode, ofCode, + cctxParams, + op, (size_t)(oend-op), + bmi2, writeSeqEntropy, seqEntropyWritten); + FORWARD_IF_ERROR(cSeqSize, "ZSTD_compressSubBlock_sequences failed"); + if (cSeqSize == 0) return 0; + op += cSeqSize; + } + /* Write block header */ + { size_t cSize = (size_t)(op-ostart) - ZSTD_blockHeaderSize; + U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3); + MEM_writeLE24(ostart, cBlockHeader24); + } + return (size_t)(op-ostart); +} + +static size_t ZSTD_estimateSubBlockSize_literal(const BYTE* literals, size_t litSize, + const ZSTD_hufCTables_t* huf, + const ZSTD_hufCTablesMetadata_t* hufMetadata, + void* workspace, size_t wkspSize, + int writeEntropy) +{ + unsigned* const countWksp = (unsigned*)workspace; + unsigned maxSymbolValue = 255; + size_t literalSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */ + + if (hufMetadata->hType == set_basic) return litSize; + else if (hufMetadata->hType == set_rle) return 1; + else if (hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat) { + size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)literals, litSize, workspace, wkspSize); + if (ZSTD_isError(largest)) return litSize; + { size_t cLitSizeEstimate = HUF_estimateCompressedSize((const HUF_CElt*)huf->CTable, countWksp, maxSymbolValue); + if (writeEntropy) cLitSizeEstimate += hufMetadata->hufDesSize; + return cLitSizeEstimate + literalSectionHeaderSize; + } } + assert(0); /* impossible */ + return 0; +} + +static size_t ZSTD_estimateSubBlockSize_symbolType(SymbolEncodingType_e type, + const BYTE* codeTable, unsigned maxCode, + size_t nbSeq, const FSE_CTable* fseCTable, + const U8* additionalBits, + short const* defaultNorm, U32 defaultNormLog, U32 defaultMax, + void* workspace, size_t wkspSize) +{ + unsigned* const countWksp = (unsigned*)workspace; + const BYTE* ctp = codeTable; + const BYTE* const ctStart = ctp; + const BYTE* const ctEnd = ctStart + nbSeq; + size_t cSymbolTypeSizeEstimateInBits = 0; + unsigned max = maxCode; + + HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */ + if (type == set_basic) { + /* We selected this encoding type, so it must be valid. */ + assert(max <= defaultMax); + cSymbolTypeSizeEstimateInBits = max <= defaultMax + ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max) + : ERROR(GENERIC); + } else if (type == set_rle) { + cSymbolTypeSizeEstimateInBits = 0; + } else if (type == set_compressed || type == set_repeat) { + cSymbolTypeSizeEstimateInBits = ZSTD_fseBitCost(fseCTable, countWksp, max); + } + if (ZSTD_isError(cSymbolTypeSizeEstimateInBits)) return nbSeq * 10; + while (ctp < ctEnd) { + if (additionalBits) cSymbolTypeSizeEstimateInBits += additionalBits[*ctp]; + else cSymbolTypeSizeEstimateInBits += *ctp; /* for offset, offset code is also the number of additional bits */ + ctp++; + } + return cSymbolTypeSizeEstimateInBits / 8; +} + +static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable, + const BYTE* llCodeTable, + const BYTE* mlCodeTable, + size_t nbSeq, + const ZSTD_fseCTables_t* fseTables, + const ZSTD_fseCTablesMetadata_t* fseMetadata, + void* workspace, size_t wkspSize, + int writeEntropy) +{ + size_t const sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */ + size_t cSeqSizeEstimate = 0; + if (nbSeq == 0) return sequencesSectionHeaderSize; + cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff, + nbSeq, fseTables->offcodeCTable, NULL, + OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff, + workspace, wkspSize); + cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->llType, llCodeTable, MaxLL, + nbSeq, fseTables->litlengthCTable, LL_bits, + LL_defaultNorm, LL_defaultNormLog, MaxLL, + workspace, wkspSize); + cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, MaxML, + nbSeq, fseTables->matchlengthCTable, ML_bits, + ML_defaultNorm, ML_defaultNormLog, MaxML, + workspace, wkspSize); + if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize; + return cSeqSizeEstimate + sequencesSectionHeaderSize; +} + +typedef struct { + size_t estLitSize; + size_t estBlockSize; +} EstimatedBlockSize; +static EstimatedBlockSize ZSTD_estimateSubBlockSize(const BYTE* literals, size_t litSize, + const BYTE* ofCodeTable, + const BYTE* llCodeTable, + const BYTE* mlCodeTable, + size_t nbSeq, + const ZSTD_entropyCTables_t* entropy, + const ZSTD_entropyCTablesMetadata_t* entropyMetadata, + void* workspace, size_t wkspSize, + int writeLitEntropy, int writeSeqEntropy) +{ + EstimatedBlockSize ebs; + ebs.estLitSize = ZSTD_estimateSubBlockSize_literal(literals, litSize, + &entropy->huf, &entropyMetadata->hufMetadata, + workspace, wkspSize, writeLitEntropy); + ebs.estBlockSize = ZSTD_estimateSubBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable, + nbSeq, &entropy->fse, &entropyMetadata->fseMetadata, + workspace, wkspSize, writeSeqEntropy); + ebs.estBlockSize += ebs.estLitSize + ZSTD_blockHeaderSize; + return ebs; +} + +static int ZSTD_needSequenceEntropyTables(ZSTD_fseCTablesMetadata_t const* fseMetadata) +{ + if (fseMetadata->llType == set_compressed || fseMetadata->llType == set_rle) + return 1; + if (fseMetadata->mlType == set_compressed || fseMetadata->mlType == set_rle) + return 1; + if (fseMetadata->ofType == set_compressed || fseMetadata->ofType == set_rle) + return 1; + return 0; +} + +static size_t countLiterals(SeqStore_t const* seqStore, const SeqDef* sp, size_t seqCount) +{ + size_t n, total = 0; + assert(sp != NULL); + for (n=0; n %zu bytes", seqCount, (const void*)sp, total); + return total; +} + +#define BYTESCALE 256 + +static size_t sizeBlockSequences(const SeqDef* sp, size_t nbSeqs, + size_t targetBudget, size_t avgLitCost, size_t avgSeqCost, + int firstSubBlock) +{ + size_t n, budget = 0, inSize=0; + /* entropy headers */ + size_t const headerSize = (size_t)firstSubBlock * 120 * BYTESCALE; /* generous estimate */ + assert(firstSubBlock==0 || firstSubBlock==1); + budget += headerSize; + + /* first sequence => at least one sequence*/ + budget += sp[0].litLength * avgLitCost + avgSeqCost; + if (budget > targetBudget) return 1; + inSize = sp[0].litLength + (sp[0].mlBase+MINMATCH); + + /* loop over sequences */ + for (n=1; n targetBudget) + /* though continue to expand until the sub-block is deemed compressible */ + && (budget < inSize * BYTESCALE) ) + break; + } + + return n; +} + +/** ZSTD_compressSubBlock_multi() : + * Breaks super-block into multiple sub-blocks and compresses them. + * Entropy will be written into the first block. + * The following blocks use repeat_mode to compress. + * Sub-blocks are all compressed, except the last one when beneficial. + * @return : compressed size of the super block (which features multiple ZSTD blocks) + * or 0 if it failed to compress. */ +static size_t ZSTD_compressSubBlock_multi(const SeqStore_t* seqStorePtr, + const ZSTD_compressedBlockState_t* prevCBlock, + ZSTD_compressedBlockState_t* nextCBlock, + const ZSTD_entropyCTablesMetadata_t* entropyMetadata, + const ZSTD_CCtx_params* cctxParams, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const int bmi2, U32 lastBlock, + void* workspace, size_t wkspSize) +{ + const SeqDef* const sstart = seqStorePtr->sequencesStart; + const SeqDef* const send = seqStorePtr->sequences; + const SeqDef* sp = sstart; /* tracks progresses within seqStorePtr->sequences */ + size_t const nbSeqs = (size_t)(send - sstart); + const BYTE* const lstart = seqStorePtr->litStart; + const BYTE* const lend = seqStorePtr->lit; + const BYTE* lp = lstart; + size_t const nbLiterals = (size_t)(lend - lstart); + BYTE const* ip = (BYTE const*)src; + BYTE const* const iend = ip + srcSize; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ostart + dstCapacity; + BYTE* op = ostart; + const BYTE* llCodePtr = seqStorePtr->llCode; + const BYTE* mlCodePtr = seqStorePtr->mlCode; + const BYTE* ofCodePtr = seqStorePtr->ofCode; + size_t const minTarget = ZSTD_TARGETCBLOCKSIZE_MIN; /* enforce minimum size, to reduce undesirable side effects */ + size_t const targetCBlockSize = MAX(minTarget, cctxParams->targetCBlockSize); + int writeLitEntropy = (entropyMetadata->hufMetadata.hType == set_compressed); + int writeSeqEntropy = 1; + + DEBUGLOG(5, "ZSTD_compressSubBlock_multi (srcSize=%u, litSize=%u, nbSeq=%u)", + (unsigned)srcSize, (unsigned)(lend-lstart), (unsigned)(send-sstart)); + + /* let's start by a general estimation for the full block */ + if (nbSeqs > 0) { + EstimatedBlockSize const ebs = + ZSTD_estimateSubBlockSize(lp, nbLiterals, + ofCodePtr, llCodePtr, mlCodePtr, nbSeqs, + &nextCBlock->entropy, entropyMetadata, + workspace, wkspSize, + writeLitEntropy, writeSeqEntropy); + /* quick estimation */ + size_t const avgLitCost = nbLiterals ? (ebs.estLitSize * BYTESCALE) / nbLiterals : BYTESCALE; + size_t const avgSeqCost = ((ebs.estBlockSize - ebs.estLitSize) * BYTESCALE) / nbSeqs; + const size_t nbSubBlocks = MAX((ebs.estBlockSize + (targetCBlockSize/2)) / targetCBlockSize, 1); + size_t n, avgBlockBudget, blockBudgetSupp=0; + avgBlockBudget = (ebs.estBlockSize * BYTESCALE) / nbSubBlocks; + DEBUGLOG(5, "estimated fullblock size=%u bytes ; avgLitCost=%.2f ; avgSeqCost=%.2f ; targetCBlockSize=%u, nbSubBlocks=%u ; avgBlockBudget=%.0f bytes", + (unsigned)ebs.estBlockSize, (double)avgLitCost/BYTESCALE, (double)avgSeqCost/BYTESCALE, + (unsigned)targetCBlockSize, (unsigned)nbSubBlocks, (double)avgBlockBudget/BYTESCALE); + /* simplification: if estimates states that the full superblock doesn't compress, just bail out immediately + * this will result in the production of a single uncompressed block covering @srcSize.*/ + if (ebs.estBlockSize > srcSize) return 0; + + /* compress and write sub-blocks */ + assert(nbSubBlocks>0); + for (n=0; n < nbSubBlocks-1; n++) { + /* determine nb of sequences for current sub-block + nbLiterals from next sequence */ + size_t const seqCount = sizeBlockSequences(sp, (size_t)(send-sp), + avgBlockBudget + blockBudgetSupp, avgLitCost, avgSeqCost, n==0); + /* if reached last sequence : break to last sub-block (simplification) */ + assert(seqCount <= (size_t)(send-sp)); + if (sp + seqCount == send) break; + assert(seqCount > 0); + /* compress sub-block */ + { int litEntropyWritten = 0; + int seqEntropyWritten = 0; + size_t litSize = countLiterals(seqStorePtr, sp, seqCount); + const size_t decompressedSize = + ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, 0); + size_t const cSize = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata, + sp, seqCount, + lp, litSize, + llCodePtr, mlCodePtr, ofCodePtr, + cctxParams, + op, (size_t)(oend-op), + bmi2, writeLitEntropy, writeSeqEntropy, + &litEntropyWritten, &seqEntropyWritten, + 0); + FORWARD_IF_ERROR(cSize, "ZSTD_compressSubBlock failed"); + + /* check compressibility, update state components */ + if (cSize > 0 && cSize < decompressedSize) { + DEBUGLOG(5, "Committed sub-block compressing %u bytes => %u bytes", + (unsigned)decompressedSize, (unsigned)cSize); + assert(ip + decompressedSize <= iend); + ip += decompressedSize; + lp += litSize; + op += cSize; + llCodePtr += seqCount; + mlCodePtr += seqCount; + ofCodePtr += seqCount; + /* Entropy only needs to be written once */ + if (litEntropyWritten) { + writeLitEntropy = 0; + } + if (seqEntropyWritten) { + writeSeqEntropy = 0; + } + sp += seqCount; + blockBudgetSupp = 0; + } } + /* otherwise : do not compress yet, coalesce current sub-block with following one */ + } + } /* if (nbSeqs > 0) */ + + /* write last block */ + DEBUGLOG(5, "Generate last sub-block: %u sequences remaining", (unsigned)(send - sp)); + { int litEntropyWritten = 0; + int seqEntropyWritten = 0; + size_t litSize = (size_t)(lend - lp); + size_t seqCount = (size_t)(send - sp); + const size_t decompressedSize = + ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, 1); + size_t const cSize = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata, + sp, seqCount, + lp, litSize, + llCodePtr, mlCodePtr, ofCodePtr, + cctxParams, + op, (size_t)(oend-op), + bmi2, writeLitEntropy, writeSeqEntropy, + &litEntropyWritten, &seqEntropyWritten, + lastBlock); + FORWARD_IF_ERROR(cSize, "ZSTD_compressSubBlock failed"); + + /* update pointers, the nb of literals borrowed from next sequence must be preserved */ + if (cSize > 0 && cSize < decompressedSize) { + DEBUGLOG(5, "Last sub-block compressed %u bytes => %u bytes", + (unsigned)decompressedSize, (unsigned)cSize); + assert(ip + decompressedSize <= iend); + ip += decompressedSize; + lp += litSize; + op += cSize; + llCodePtr += seqCount; + mlCodePtr += seqCount; + ofCodePtr += seqCount; + /* Entropy only needs to be written once */ + if (litEntropyWritten) { + writeLitEntropy = 0; + } + if (seqEntropyWritten) { + writeSeqEntropy = 0; + } + sp += seqCount; + } + } + + + if (writeLitEntropy) { + DEBUGLOG(5, "Literal entropy tables were never written"); + ZSTD_memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf)); + } + if (writeSeqEntropy && ZSTD_needSequenceEntropyTables(&entropyMetadata->fseMetadata)) { + /* If we haven't written our entropy tables, then we've violated our contract and + * must emit an uncompressed block. + */ + DEBUGLOG(5, "Sequence entropy tables were never written => cancel, emit an uncompressed block"); + return 0; + } + + if (ip < iend) { + /* some data left : last part of the block sent uncompressed */ + size_t const rSize = (size_t)((iend - ip)); + size_t const cSize = ZSTD_noCompressBlock(op, (size_t)(oend - op), ip, rSize, lastBlock); + DEBUGLOG(5, "Generate last uncompressed sub-block of %u bytes", (unsigned)(rSize)); + FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed"); + assert(cSize != 0); + op += cSize; + /* We have to regenerate the repcodes because we've skipped some sequences */ + if (sp < send) { + const SeqDef* seq; + Repcodes_t rep; + ZSTD_memcpy(&rep, prevCBlock->rep, sizeof(rep)); + for (seq = sstart; seq < sp; ++seq) { + ZSTD_updateRep(rep.rep, seq->offBase, ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0); + } + ZSTD_memcpy(nextCBlock->rep, &rep, sizeof(rep)); + } + } + + DEBUGLOG(5, "ZSTD_compressSubBlock_multi compressed all subBlocks: total compressed size = %u", + (unsigned)(op-ostart)); + return (size_t)(op-ostart); +} + +size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + unsigned lastBlock) +{ + ZSTD_entropyCTablesMetadata_t entropyMetadata; + + FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(&zc->seqStore, + &zc->blockState.prevCBlock->entropy, + &zc->blockState.nextCBlock->entropy, + &zc->appliedParams, + &entropyMetadata, + zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */), ""); + + return ZSTD_compressSubBlock_multi(&zc->seqStore, + zc->blockState.prevCBlock, + zc->blockState.nextCBlock, + &entropyMetadata, + &zc->appliedParams, + dst, dstCapacity, + src, srcSize, + zc->bmi2, lastBlock, + zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */); +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_compress_superblock.h b/src/commonlib/bsd/zstd/compress/zstd_compress_superblock.h new file mode 100644 index 00000000000..a8765694d9b --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_compress_superblock.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_COMPRESS_ADVANCED_H +#define ZSTD_COMPRESS_ADVANCED_H + +/*-************************************* +* Dependencies +***************************************/ + +#include "../zstd.h" /* ZSTD_CCtx */ + +/*-************************************* +* Target Compressed Block Size +***************************************/ + +/* ZSTD_compressSuperBlock() : + * Used to compress a super block when targetCBlockSize is being used. + * The given block will be compressed into multiple sub blocks that are around targetCBlockSize. */ +size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc, + void* dst, size_t dstCapacity, + void const* src, size_t srcSize, + unsigned lastBlock); + +#endif /* ZSTD_COMPRESS_ADVANCED_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_cwksp.h b/src/commonlib/bsd/zstd/compress/zstd_cwksp.h new file mode 100644 index 00000000000..bb5d283a224 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_cwksp.h @@ -0,0 +1,767 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_CWKSP_H +#define ZSTD_CWKSP_H + +/*-************************************* +* Dependencies +***************************************/ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customFree */ +#include "../common/zstd_internal.h" +#include "../common/portability_macros.h" +#include "../common/zstd_compiler.h" /* ZS2_isPower2 */ + +/*-************************************* +* Constants +***************************************/ + +/* Since the workspace is effectively its own little malloc implementation / + * arena, when we run under ASAN, we should similarly insert redzones between + * each internal element of the workspace, so ASAN will catch overruns that + * reach outside an object but that stay inside the workspace. + * + * This defines the size of that redzone. + */ +#ifndef ZSTD_CWKSP_ASAN_REDZONE_SIZE +#define ZSTD_CWKSP_ASAN_REDZONE_SIZE 128 +#endif + + +/* Set our tables and aligneds to align by 64 bytes */ +#define ZSTD_CWKSP_ALIGNMENT_BYTES 64 + +/*-************************************* +* Structures +***************************************/ +typedef enum { + ZSTD_cwksp_alloc_objects, + ZSTD_cwksp_alloc_aligned_init_once, + ZSTD_cwksp_alloc_aligned, + ZSTD_cwksp_alloc_buffers +} ZSTD_cwksp_alloc_phase_e; + +/** + * Used to describe whether the workspace is statically allocated (and will not + * necessarily ever be freed), or if it's dynamically allocated and we can + * expect a well-formed caller to free this. + */ +typedef enum { + ZSTD_cwksp_dynamic_alloc, + ZSTD_cwksp_static_alloc +} ZSTD_cwksp_static_alloc_e; + +/** + * Zstd fits all its internal datastructures into a single continuous buffer, + * so that it only needs to perform a single OS allocation (or so that a buffer + * can be provided to it and it can perform no allocations at all). This buffer + * is called the workspace. + * + * Several optimizations complicate that process of allocating memory ranges + * from this workspace for each internal datastructure: + * + * - These different internal datastructures have different setup requirements: + * + * - The static objects need to be cleared once and can then be trivially + * reused for each compression. + * + * - Various buffers don't need to be initialized at all--they are always + * written into before they're read. + * + * - The matchstate tables have a unique requirement that they don't need + * their memory to be totally cleared, but they do need the memory to have + * some bound, i.e., a guarantee that all values in the memory they've been + * allocated is less than some maximum value (which is the starting value + * for the indices that they will then use for compression). When this + * guarantee is provided to them, they can use the memory without any setup + * work. When it can't, they have to clear the area. + * + * - These buffers also have different alignment requirements. + * + * - We would like to reuse the objects in the workspace for multiple + * compressions without having to perform any expensive reallocation or + * reinitialization work. + * + * - We would like to be able to efficiently reuse the workspace across + * multiple compressions **even when the compression parameters change** and + * we need to resize some of the objects (where possible). + * + * To attempt to manage this buffer, given these constraints, the ZSTD_cwksp + * abstraction was created. It works as follows: + * + * Workspace Layout: + * + * [ ... workspace ... ] + * [objects][tables ->] free space [<- buffers][<- aligned][<- init once] + * + * The various objects that live in the workspace are divided into the + * following categories, and are allocated separately: + * + * - Static objects: this is optionally the enclosing ZSTD_CCtx or ZSTD_CDict, + * so that literally everything fits in a single buffer. Note: if present, + * this must be the first object in the workspace, since ZSTD_customFree{CCtx, + * CDict}() rely on a pointer comparison to see whether one or two frees are + * required. + * + * - Fixed size objects: these are fixed-size, fixed-count objects that are + * nonetheless "dynamically" allocated in the workspace so that we can + * control how they're initialized separately from the broader ZSTD_CCtx. + * Examples: + * - Entropy Workspace + * - 2 x ZSTD_compressedBlockState_t + * - CDict dictionary contents + * + * - Tables: these are any of several different datastructures (hash tables, + * chain tables, binary trees) that all respect a common format: they are + * uint32_t arrays, all of whose values are between 0 and (nextSrc - base). + * Their sizes depend on the cparams. These tables are 64-byte aligned. + * + * - Init once: these buffers require to be initialized at least once before + * use. They should be used when we want to skip memory initialization + * while not triggering memory checkers (like Valgrind) when reading from + * from this memory without writing to it first. + * These buffers should be used carefully as they might contain data + * from previous compressions. + * Buffers are aligned to 64 bytes. + * + * - Aligned: these buffers don't require any initialization before they're + * used. The user of the buffer should make sure they write into a buffer + * location before reading from it. + * Buffers are aligned to 64 bytes. + * + * - Buffers: these buffers are used for various purposes that don't require + * any alignment or initialization before they're used. This means they can + * be moved around at no cost for a new compression. + * + * Allocating Memory: + * + * The various types of objects must be allocated in order, so they can be + * correctly packed into the workspace buffer. That order is: + * + * 1. Objects + * 2. Init once / Tables + * 3. Aligned / Tables + * 4. Buffers / Tables + * + * Attempts to reserve objects of different types out of order will fail. + */ +typedef struct { + void* workspace; + void* workspaceEnd; + + void* objectEnd; + void* tableEnd; + void* tableValidEnd; + void* allocStart; + void* initOnceStart; + + BYTE allocFailed; + int workspaceOversizedDuration; + ZSTD_cwksp_alloc_phase_e phase; + ZSTD_cwksp_static_alloc_e isStatic; +} ZSTD_cwksp; + +/*-************************************* +* Functions +***************************************/ + +MEM_STATIC size_t ZSTD_cwksp_available_space(ZSTD_cwksp* ws); +MEM_STATIC void* ZSTD_cwksp_initialAllocStart(ZSTD_cwksp* ws); + +MEM_STATIC void ZSTD_cwksp_assert_internal_consistency(ZSTD_cwksp* ws) { + (void)ws; + assert(ws->workspace <= ws->objectEnd); + assert(ws->objectEnd <= ws->tableEnd); + assert(ws->objectEnd <= ws->tableValidEnd); + assert(ws->tableEnd <= ws->allocStart); + assert(ws->tableValidEnd <= ws->allocStart); + assert(ws->allocStart <= ws->workspaceEnd); + assert(ws->initOnceStart <= ZSTD_cwksp_initialAllocStart(ws)); + assert(ws->workspace <= ws->initOnceStart); +#if ZSTD_MEMORY_SANITIZER + { + intptr_t const offset = __msan_test_shadow(ws->initOnceStart, + (U8*)ZSTD_cwksp_initialAllocStart(ws) - (U8*)ws->initOnceStart); + (void)offset; +#if defined(ZSTD_MSAN_PRINT) + if(offset!=-1) { + __msan_print_shadow((U8*)ws->initOnceStart + offset - 8, 32); + } +#endif + assert(offset==-1); + }; +#endif +} + +/** + * Align must be a power of 2. + */ +MEM_STATIC size_t ZSTD_cwksp_align(size_t size, size_t align) { + size_t const mask = align - 1; + assert(ZSTD_isPower2(align)); + return (size + mask) & ~mask; +} + +/** + * Use this to determine how much space in the workspace we will consume to + * allocate this object. (Normally it should be exactly the size of the object, + * but under special conditions, like ASAN, where we pad each object, it might + * be larger.) + * + * Since tables aren't currently redzoned, you don't need to call through this + * to figure out how much space you need for the matchState tables. Everything + * else is though. + * + * Do not use for sizing aligned buffers. Instead, use ZSTD_cwksp_aligned64_alloc_size(). + */ +MEM_STATIC size_t ZSTD_cwksp_alloc_size(size_t size) { + if (size == 0) + return 0; +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + return size + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE; +#else + return size; +#endif +} + +MEM_STATIC size_t ZSTD_cwksp_aligned_alloc_size(size_t size, size_t alignment) { + return ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(size, alignment)); +} + +/** + * Returns an adjusted alloc size that is the nearest larger multiple of 64 bytes. + * Used to determine the number of bytes required for a given "aligned". + */ +MEM_STATIC size_t ZSTD_cwksp_aligned64_alloc_size(size_t size) { + return ZSTD_cwksp_aligned_alloc_size(size, ZSTD_CWKSP_ALIGNMENT_BYTES); +} + +/** + * Returns the amount of additional space the cwksp must allocate + * for internal purposes (currently only alignment). + */ +MEM_STATIC size_t ZSTD_cwksp_slack_space_required(void) { + /* For alignment, the wksp will always allocate an additional 2*ZSTD_CWKSP_ALIGNMENT_BYTES + * bytes to align the beginning of tables section and end of buffers; + */ + size_t const slackSpace = ZSTD_CWKSP_ALIGNMENT_BYTES * 2; + return slackSpace; +} + + +/** + * Return the number of additional bytes required to align a pointer to the given number of bytes. + * alignBytes must be a power of two. + */ +MEM_STATIC size_t ZSTD_cwksp_bytes_to_align_ptr(void* ptr, const size_t alignBytes) { + size_t const alignBytesMask = alignBytes - 1; + size_t const bytes = (alignBytes - ((size_t)ptr & (alignBytesMask))) & alignBytesMask; + assert(ZSTD_isPower2(alignBytes)); + assert(bytes < alignBytes); + return bytes; +} + +/** + * Returns the initial value for allocStart which is used to determine the position from + * which we can allocate from the end of the workspace. + */ +MEM_STATIC void* ZSTD_cwksp_initialAllocStart(ZSTD_cwksp* ws) +{ + char* endPtr = (char*)ws->workspaceEnd; + assert(ZSTD_isPower2(ZSTD_CWKSP_ALIGNMENT_BYTES)); + endPtr = endPtr - ((size_t)endPtr % ZSTD_CWKSP_ALIGNMENT_BYTES); + return (void*)endPtr; +} + +/** + * Internal function. Do not use directly. + * Reserves the given number of bytes within the aligned/buffer segment of the wksp, + * which counts from the end of the wksp (as opposed to the object/table segment). + * + * Returns a pointer to the beginning of that space. + */ +MEM_STATIC void* +ZSTD_cwksp_reserve_internal_buffer_space(ZSTD_cwksp* ws, size_t const bytes) +{ + void* const alloc = (BYTE*)ws->allocStart - bytes; + void* const bottom = ws->tableEnd; + DEBUGLOG(5, "cwksp: reserving [0x%p]:%zd bytes; %zd bytes remaining", + alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes); + ZSTD_cwksp_assert_internal_consistency(ws); + assert(alloc >= bottom); + if (alloc < bottom) { + DEBUGLOG(4, "cwksp: alloc failed!"); + ws->allocFailed = 1; + return NULL; + } + /* the area is reserved from the end of wksp. + * If it overlaps with tableValidEnd, it voids guarantees on values' range */ + if (alloc < ws->tableValidEnd) { + ws->tableValidEnd = alloc; + } + ws->allocStart = alloc; + return alloc; +} + +/** + * Moves the cwksp to the next phase, and does any necessary allocations. + * cwksp initialization must necessarily go through each phase in order. + * Returns a 0 on success, or zstd error + */ +MEM_STATIC size_t +ZSTD_cwksp_internal_advance_phase(ZSTD_cwksp* ws, ZSTD_cwksp_alloc_phase_e phase) +{ + assert(phase >= ws->phase); + if (phase > ws->phase) { + /* Going from allocating objects to allocating initOnce / tables */ + if (ws->phase < ZSTD_cwksp_alloc_aligned_init_once && + phase >= ZSTD_cwksp_alloc_aligned_init_once) { + ws->tableValidEnd = ws->objectEnd; + ws->initOnceStart = ZSTD_cwksp_initialAllocStart(ws); + + { /* Align the start of the tables to 64 bytes. Use [0, 63] bytes */ + void *const alloc = ws->objectEnd; + size_t const bytesToAlign = ZSTD_cwksp_bytes_to_align_ptr(alloc, ZSTD_CWKSP_ALIGNMENT_BYTES); + void *const objectEnd = (BYTE *) alloc + bytesToAlign; + DEBUGLOG(5, "reserving table alignment addtl space: %zu", bytesToAlign); + RETURN_ERROR_IF(objectEnd > ws->workspaceEnd, memory_allocation, + "table phase - alignment initial allocation failed!"); + ws->objectEnd = objectEnd; + ws->tableEnd = objectEnd; /* table area starts being empty */ + if (ws->tableValidEnd < ws->tableEnd) { + ws->tableValidEnd = ws->tableEnd; + } + } + } + ws->phase = phase; + ZSTD_cwksp_assert_internal_consistency(ws); + } + return 0; +} + +/** + * Returns whether this object/buffer/etc was allocated in this workspace. + */ +MEM_STATIC int ZSTD_cwksp_owns_buffer(const ZSTD_cwksp* ws, const void* ptr) +{ + return (ptr != NULL) && (ws->workspace <= ptr) && (ptr < ws->workspaceEnd); +} + +/** + * Internal function. Do not use directly. + */ +MEM_STATIC void* +ZSTD_cwksp_reserve_internal(ZSTD_cwksp* ws, size_t bytes, ZSTD_cwksp_alloc_phase_e phase) +{ + void* alloc; + if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase)) || bytes == 0) { + return NULL; + } + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* over-reserve space */ + bytes += 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE; +#endif + + alloc = ZSTD_cwksp_reserve_internal_buffer_space(ws, bytes); + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on + * either size. */ + if (alloc) { + alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE; + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + /* We need to keep the redzone poisoned while unpoisoning the bytes that + * are actually allocated. */ + __asan_unpoison_memory_region(alloc, bytes - 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE); + } + } +#endif + + return alloc; +} + +/** + * Reserves and returns unaligned memory. + */ +MEM_STATIC BYTE* ZSTD_cwksp_reserve_buffer(ZSTD_cwksp* ws, size_t bytes) +{ + return (BYTE*)ZSTD_cwksp_reserve_internal(ws, bytes, ZSTD_cwksp_alloc_buffers); +} + +/** + * Reserves and returns memory sized on and aligned on ZSTD_CWKSP_ALIGNMENT_BYTES (64 bytes). + * This memory has been initialized at least once in the past. + * This doesn't mean it has been initialized this time, and it might contain data from previous + * operations. + * The main usage is for algorithms that might need read access into uninitialized memory. + * The algorithm must maintain safety under these conditions and must make sure it doesn't + * leak any of the past data (directly or in side channels). + */ +MEM_STATIC void* ZSTD_cwksp_reserve_aligned_init_once(ZSTD_cwksp* ws, size_t bytes) +{ + size_t const alignedBytes = ZSTD_cwksp_align(bytes, ZSTD_CWKSP_ALIGNMENT_BYTES); + void* ptr = ZSTD_cwksp_reserve_internal(ws, alignedBytes, ZSTD_cwksp_alloc_aligned_init_once); + assert(((size_t)ptr & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0); + if(ptr && ptr < ws->initOnceStart) { + /* We assume the memory following the current allocation is either: + * 1. Not usable as initOnce memory (end of workspace) + * 2. Another initOnce buffer that has been allocated before (and so was previously memset) + * 3. An ASAN redzone, in which case we don't want to write on it + * For these reasons it should be fine to not explicitly zero every byte up to ws->initOnceStart. + * Note that we assume here that MSAN and ASAN cannot run in the same time. */ + ZSTD_memset(ptr, 0, MIN((size_t)((U8*)ws->initOnceStart - (U8*)ptr), alignedBytes)); + ws->initOnceStart = ptr; + } +#if ZSTD_MEMORY_SANITIZER + assert(__msan_test_shadow(ptr, bytes) == -1); +#endif + return ptr; +} + +/** + * Reserves and returns memory sized on and aligned on ZSTD_CWKSP_ALIGNMENT_BYTES (64 bytes). + */ +MEM_STATIC void* ZSTD_cwksp_reserve_aligned64(ZSTD_cwksp* ws, size_t bytes) +{ + void* const ptr = ZSTD_cwksp_reserve_internal(ws, + ZSTD_cwksp_align(bytes, ZSTD_CWKSP_ALIGNMENT_BYTES), + ZSTD_cwksp_alloc_aligned); + assert(((size_t)ptr & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0); + return ptr; +} + +/** + * Aligned on 64 bytes. These buffers have the special property that + * their values remain constrained, allowing us to reuse them without + * memset()-ing them. + */ +MEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) +{ + const ZSTD_cwksp_alloc_phase_e phase = ZSTD_cwksp_alloc_aligned_init_once; + void* alloc; + void* end; + void* top; + + /* We can only start allocating tables after we are done reserving space for objects at the + * start of the workspace */ + if(ws->phase < phase) { + if (ZSTD_isError(ZSTD_cwksp_internal_advance_phase(ws, phase))) { + return NULL; + } + } + alloc = ws->tableEnd; + end = (BYTE *)alloc + bytes; + top = ws->allocStart; + + DEBUGLOG(5, "cwksp: reserving %p table %zd bytes, %zd bytes remaining", + alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes); + assert((bytes & (sizeof(U32)-1)) == 0); + ZSTD_cwksp_assert_internal_consistency(ws); + assert(end <= top); + if (end > top) { + DEBUGLOG(4, "cwksp: table alloc failed!"); + ws->allocFailed = 1; + return NULL; + } + ws->tableEnd = end; + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + __asan_unpoison_memory_region(alloc, bytes); + } +#endif + + assert((bytes & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0); + assert(((size_t)alloc & (ZSTD_CWKSP_ALIGNMENT_BYTES-1)) == 0); + return alloc; +} + +/** + * Aligned on sizeof(void*). + * Note : should happen only once, at workspace first initialization + */ +MEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) +{ + size_t const roundedBytes = ZSTD_cwksp_align(bytes, sizeof(void*)); + void* alloc = ws->objectEnd; + void* end = (BYTE*)alloc + roundedBytes; + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* over-reserve space */ + end = (BYTE *)end + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE; +#endif + + DEBUGLOG(4, + "cwksp: reserving %p object %zd bytes (rounded to %zd), %zd bytes remaining", + alloc, bytes, roundedBytes, ZSTD_cwksp_available_space(ws) - roundedBytes); + assert((size_t)alloc % ZSTD_ALIGNOF(void*) == 0); + assert(bytes % ZSTD_ALIGNOF(void*) == 0); + ZSTD_cwksp_assert_internal_consistency(ws); + /* we must be in the first phase, no advance is possible */ + if (ws->phase != ZSTD_cwksp_alloc_objects || end > ws->workspaceEnd) { + DEBUGLOG(3, "cwksp: object alloc failed!"); + ws->allocFailed = 1; + return NULL; + } + ws->objectEnd = end; + ws->tableEnd = end; + ws->tableValidEnd = end; + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on + * either size. */ + alloc = (BYTE*)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE; + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + __asan_unpoison_memory_region(alloc, bytes); + } +#endif + + return alloc; +} +/** + * with alignment control + * Note : should happen only once, at workspace first initialization + */ +MEM_STATIC void* ZSTD_cwksp_reserve_object_aligned(ZSTD_cwksp* ws, size_t byteSize, size_t alignment) +{ + size_t const mask = alignment - 1; + size_t const surplus = (alignment > sizeof(void*)) ? alignment - sizeof(void*) : 0; + void* const start = ZSTD_cwksp_reserve_object(ws, byteSize + surplus); + if (start == NULL) return NULL; + if (surplus == 0) return start; + assert(ZSTD_isPower2(alignment)); + return (void*)(((size_t)start + surplus) & ~mask); +} + +MEM_STATIC void ZSTD_cwksp_mark_tables_dirty(ZSTD_cwksp* ws) +{ + DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_dirty"); + +#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) + /* To validate that the table reuse logic is sound, and that we don't + * access table space that we haven't cleaned, we re-"poison" the table + * space every time we mark it dirty. + * Since tableValidEnd space and initOnce space may overlap we don't poison + * the initOnce portion as it break its promise. This means that this poisoning + * check isn't always applied fully. */ + { + size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd; + assert(__msan_test_shadow(ws->objectEnd, size) == -1); + if((BYTE*)ws->tableValidEnd < (BYTE*)ws->initOnceStart) { + __msan_poison(ws->objectEnd, size); + } else { + assert(ws->initOnceStart >= ws->objectEnd); + __msan_poison(ws->objectEnd, (BYTE*)ws->initOnceStart - (BYTE*)ws->objectEnd); + } + } +#endif + + assert(ws->tableValidEnd >= ws->objectEnd); + assert(ws->tableValidEnd <= ws->allocStart); + ws->tableValidEnd = ws->objectEnd; + ZSTD_cwksp_assert_internal_consistency(ws); +} + +MEM_STATIC void ZSTD_cwksp_mark_tables_clean(ZSTD_cwksp* ws) { + DEBUGLOG(4, "cwksp: ZSTD_cwksp_mark_tables_clean"); + assert(ws->tableValidEnd >= ws->objectEnd); + assert(ws->tableValidEnd <= ws->allocStart); + if (ws->tableValidEnd < ws->tableEnd) { + ws->tableValidEnd = ws->tableEnd; + } + ZSTD_cwksp_assert_internal_consistency(ws); +} + +/** + * Zero the part of the allocated tables not already marked clean. + */ +MEM_STATIC void ZSTD_cwksp_clean_tables(ZSTD_cwksp* ws) { + DEBUGLOG(4, "cwksp: ZSTD_cwksp_clean_tables"); + assert(ws->tableValidEnd >= ws->objectEnd); + assert(ws->tableValidEnd <= ws->allocStart); + if (ws->tableValidEnd < ws->tableEnd) { + ZSTD_memset(ws->tableValidEnd, 0, (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->tableValidEnd)); + } + ZSTD_cwksp_mark_tables_clean(ws); +} + +/** + * Invalidates table allocations. + * All other allocations remain valid. + */ +MEM_STATIC void ZSTD_cwksp_clear_tables(ZSTD_cwksp* ws) +{ + DEBUGLOG(4, "cwksp: clearing tables!"); + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* We don't do this when the workspace is statically allocated, because + * when that is the case, we have no capability to hook into the end of the + * workspace's lifecycle to unpoison the memory. + */ + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd; + __asan_poison_memory_region(ws->objectEnd, size); + } +#endif + + ws->tableEnd = ws->objectEnd; + ZSTD_cwksp_assert_internal_consistency(ws); +} + +/** + * Invalidates all buffer, aligned, and table allocations. + * Object allocations remain valid. + */ +MEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) { + DEBUGLOG(4, "cwksp: clearing!"); + +#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE) + /* To validate that the context reuse logic is sound, and that we don't + * access stuff that this compression hasn't initialized, we re-"poison" + * the workspace except for the areas in which we expect memory reuse + * without initialization (objects, valid tables area and init once + * memory). */ + { + if((BYTE*)ws->tableValidEnd < (BYTE*)ws->initOnceStart) { + size_t size = (BYTE*)ws->initOnceStart - (BYTE*)ws->tableValidEnd; + __msan_poison(ws->tableValidEnd, size); + } + } +#endif + +#if ZSTD_ADDRESS_SANITIZER && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE) + /* We don't do this when the workspace is statically allocated, because + * when that is the case, we have no capability to hook into the end of the + * workspace's lifecycle to unpoison the memory. + */ + if (ws->isStatic == ZSTD_cwksp_dynamic_alloc) { + size_t size = (BYTE*)ws->workspaceEnd - (BYTE*)ws->objectEnd; + __asan_poison_memory_region(ws->objectEnd, size); + } +#endif + + ws->tableEnd = ws->objectEnd; + ws->allocStart = ZSTD_cwksp_initialAllocStart(ws); + ws->allocFailed = 0; + if (ws->phase > ZSTD_cwksp_alloc_aligned_init_once) { + ws->phase = ZSTD_cwksp_alloc_aligned_init_once; + } + ZSTD_cwksp_assert_internal_consistency(ws); +} + +MEM_STATIC size_t ZSTD_cwksp_sizeof(const ZSTD_cwksp* ws) { + return (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->workspace); +} + +MEM_STATIC size_t ZSTD_cwksp_used(const ZSTD_cwksp* ws) { + return (size_t)((BYTE*)ws->tableEnd - (BYTE*)ws->workspace) + + (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->allocStart); +} + +/** + * The provided workspace takes ownership of the buffer [start, start+size). + * Any existing values in the workspace are ignored (the previously managed + * buffer, if present, must be separately freed). + */ +MEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size, ZSTD_cwksp_static_alloc_e isStatic) { + DEBUGLOG(4, "cwksp: init'ing workspace with %zd bytes", size); + assert(((size_t)start & (sizeof(void*)-1)) == 0); /* ensure correct alignment */ + ws->workspace = start; + ws->workspaceEnd = (BYTE*)start + size; + ws->objectEnd = ws->workspace; + ws->tableValidEnd = ws->objectEnd; + ws->initOnceStart = ZSTD_cwksp_initialAllocStart(ws); + ws->phase = ZSTD_cwksp_alloc_objects; + ws->isStatic = isStatic; + ZSTD_cwksp_clear(ws); + ws->workspaceOversizedDuration = 0; + ZSTD_cwksp_assert_internal_consistency(ws); +} + +MEM_STATIC size_t ZSTD_cwksp_create(ZSTD_cwksp* ws, size_t size, ZSTD_customMem customMem) { + void* workspace = ZSTD_customMalloc(size, customMem); + DEBUGLOG(4, "cwksp: creating new workspace with %zd bytes", size); + RETURN_ERROR_IF(workspace == NULL, memory_allocation, "NULL pointer!"); + ZSTD_cwksp_init(ws, workspace, size, ZSTD_cwksp_dynamic_alloc); + return 0; +} + +MEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) { + void *ptr = ws->workspace; + DEBUGLOG(4, "cwksp: freeing workspace"); +#if ZSTD_MEMORY_SANITIZER && !defined(ZSTD_MSAN_DONT_POISON_WORKSPACE) + if (ptr != NULL && customMem.customFree != NULL) { + __msan_unpoison(ptr, ZSTD_cwksp_sizeof(ws)); + } +#endif + ZSTD_memset(ws, 0, sizeof(ZSTD_cwksp)); + ZSTD_customFree(ptr, customMem); +} + +/** + * Moves the management of a workspace from one cwksp to another. The src cwksp + * is left in an invalid state (src must be re-init()'ed before it's used again). + */ +MEM_STATIC void ZSTD_cwksp_move(ZSTD_cwksp* dst, ZSTD_cwksp* src) { + *dst = *src; + ZSTD_memset(src, 0, sizeof(ZSTD_cwksp)); +} + +MEM_STATIC int ZSTD_cwksp_reserve_failed(const ZSTD_cwksp* ws) { + return ws->allocFailed; +} + +/*-************************************* +* Functions Checking Free Space +***************************************/ + +/* ZSTD_alignmentSpaceWithinBounds() : + * Returns if the estimated space needed for a wksp is within an acceptable limit of the + * actual amount of space used. + */ +MEM_STATIC int ZSTD_cwksp_estimated_space_within_bounds(const ZSTD_cwksp *const ws, size_t const estimatedSpace) { + /* We have an alignment space between objects and tables between tables and buffers, so we can have up to twice + * the alignment bytes difference between estimation and actual usage */ + return (estimatedSpace - ZSTD_cwksp_slack_space_required()) <= ZSTD_cwksp_used(ws) && + ZSTD_cwksp_used(ws) <= estimatedSpace; +} + + +MEM_STATIC size_t ZSTD_cwksp_available_space(ZSTD_cwksp* ws) { + return (size_t)((BYTE*)ws->allocStart - (BYTE*)ws->tableEnd); +} + +MEM_STATIC int ZSTD_cwksp_check_available(ZSTD_cwksp* ws, size_t additionalNeededSpace) { + return ZSTD_cwksp_available_space(ws) >= additionalNeededSpace; +} + +MEM_STATIC int ZSTD_cwksp_check_too_large(ZSTD_cwksp* ws, size_t additionalNeededSpace) { + return ZSTD_cwksp_check_available( + ws, additionalNeededSpace * ZSTD_WORKSPACETOOLARGE_FACTOR); +} + +MEM_STATIC int ZSTD_cwksp_check_wasteful(ZSTD_cwksp* ws, size_t additionalNeededSpace) { + return ZSTD_cwksp_check_too_large(ws, additionalNeededSpace) + && ws->workspaceOversizedDuration > ZSTD_WORKSPACETOOLARGE_MAXDURATION; +} + +MEM_STATIC void ZSTD_cwksp_bump_oversized_duration( + ZSTD_cwksp* ws, size_t additionalNeededSpace) { + if (ZSTD_cwksp_check_too_large(ws, additionalNeededSpace)) { + ws->workspaceOversizedDuration++; + } else { + ws->workspaceOversizedDuration = 0; + } +} + +#endif /* ZSTD_CWKSP_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_double_fast.c b/src/commonlib/bsd/zstd/compress/zstd_double_fast.c new file mode 100644 index 00000000000..7a2a56b8234 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_double_fast.c @@ -0,0 +1,780 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_compress_internal.h" +#include "zstd_double_fast.h" + +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillDoubleHashTableForCDict(ZSTD_MatchState_t* ms, + void const* end, ZSTD_dictTableLoadMethod_e dtlm) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashLarge = ms->hashTable; + U32 const hBitsL = cParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS; + U32 const mls = cParams->minMatch; + U32* const hashSmall = ms->chainTable; + U32 const hBitsS = cParams->chainLog + ZSTD_SHORT_CACHE_TAG_BITS; + const BYTE* const base = ms->window.base; + const BYTE* ip = base + ms->nextToUpdate; + const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; + const U32 fastHashFillStep = 3; + + /* Always insert every fastHashFillStep position into the hash tables. + * Insert the other positions into the large hash table if their entry + * is empty. + */ + for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) { + U32 const curr = (U32)(ip - base); + U32 i; + for (i = 0; i < fastHashFillStep; ++i) { + size_t const smHashAndTag = ZSTD_hashPtr(ip + i, hBitsS, mls); + size_t const lgHashAndTag = ZSTD_hashPtr(ip + i, hBitsL, 8); + if (i == 0) { + ZSTD_writeTaggedIndex(hashSmall, smHashAndTag, curr + i); + } + if (i == 0 || hashLarge[lgHashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS] == 0) { + ZSTD_writeTaggedIndex(hashLarge, lgHashAndTag, curr + i); + } + /* Only load extra positions for ZSTD_dtlm_full */ + if (dtlm == ZSTD_dtlm_fast) + break; + } } +} + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillDoubleHashTableForCCtx(ZSTD_MatchState_t* ms, + void const* end, ZSTD_dictTableLoadMethod_e dtlm) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashLarge = ms->hashTable; + U32 const hBitsL = cParams->hashLog; + U32 const mls = cParams->minMatch; + U32* const hashSmall = ms->chainTable; + U32 const hBitsS = cParams->chainLog; + const BYTE* const base = ms->window.base; + const BYTE* ip = base + ms->nextToUpdate; + const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; + const U32 fastHashFillStep = 3; + + /* Always insert every fastHashFillStep position into the hash tables. + * Insert the other positions into the large hash table if their entry + * is empty. + */ + for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) { + U32 const curr = (U32)(ip - base); + U32 i; + for (i = 0; i < fastHashFillStep; ++i) { + size_t const smHash = ZSTD_hashPtr(ip + i, hBitsS, mls); + size_t const lgHash = ZSTD_hashPtr(ip + i, hBitsL, 8); + if (i == 0) + hashSmall[smHash] = curr + i; + if (i == 0 || hashLarge[lgHash] == 0) + hashLarge[lgHash] = curr + i; + /* Only load extra positions for ZSTD_dtlm_full */ + if (dtlm == ZSTD_dtlm_fast) + break; + } } +} + +void ZSTD_fillDoubleHashTable(ZSTD_MatchState_t* ms, + const void* const end, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp) +{ + if (tfp == ZSTD_tfp_forCDict) { + ZSTD_fillDoubleHashTableForCDict(ms, end, dtlm); + } else { + ZSTD_fillDoubleHashTableForCCtx(ms, end, dtlm); + } +} + + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_doubleFast_noDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, U32 const mls /* template */) +{ + ZSTD_compressionParameters const* cParams = &ms->cParams; + U32* const hashLong = ms->hashTable; + const U32 hBitsL = cParams->hashLog; + U32* const hashSmall = ms->chainTable; + const U32 hBitsS = cParams->chainLog; + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const BYTE* anchor = istart; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + /* presumes that, if there is a dictionary, it must be using Attach mode */ + const U32 prefixLowestIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); + const BYTE* const prefixLowest = base + prefixLowestIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + U32 offset_1=rep[0], offset_2=rep[1]; + U32 offsetSaved1 = 0, offsetSaved2 = 0; + + size_t mLength; + U32 offset; + U32 curr; + + /* how many positions to search before increasing step size */ + const size_t kStepIncr = 1 << kSearchStrength; + /* the position at which to increment the step size if no match is found */ + const BYTE* nextStep; + size_t step; /* the current step size */ + + size_t hl0; /* the long hash at ip */ + size_t hl1; /* the long hash at ip1 */ + + U32 idxl0; /* the long match index for ip */ + U32 idxl1; /* the long match index for ip1 */ + + const BYTE* matchl0; /* the long match for ip */ + const BYTE* matchs0; /* the short match for ip */ + const BYTE* matchl1; /* the long match for ip1 */ + const BYTE* matchs0_safe; /* matchs0 or safe address */ + + const BYTE* ip = istart; /* the current position */ + const BYTE* ip1; /* the next position */ + /* Array of ~random data, should have low probability of matching data + * we load from here instead of from tables, if matchl0/matchl1 are + * invalid indices. Used to avoid unpredictable branches. */ + const BYTE dummy[] = {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0xe2,0xb4}; + + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_noDict_generic"); + + /* init */ + ip += ((ip - prefixLowest) == 0); + { + U32 const current = (U32)(ip - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, cParams->windowLog); + U32 const maxRep = current - windowLow; + if (offset_2 > maxRep) offsetSaved2 = offset_2, offset_2 = 0; + if (offset_1 > maxRep) offsetSaved1 = offset_1, offset_1 = 0; + } + + /* Outer Loop: one iteration per match found and stored */ + while (1) { + step = 1; + nextStep = ip + kStepIncr; + ip1 = ip + step; + + if (ip1 > ilimit) { + goto _cleanup; + } + + hl0 = ZSTD_hashPtr(ip, hBitsL, 8); + idxl0 = hashLong[hl0]; + matchl0 = base + idxl0; + + /* Inner Loop: one iteration per search / position */ + do { + const size_t hs0 = ZSTD_hashPtr(ip, hBitsS, mls); + const U32 idxs0 = hashSmall[hs0]; + curr = (U32)(ip-base); + matchs0 = base + idxs0; + + hashLong[hl0] = hashSmall[hs0] = curr; /* update hash tables */ + + /* check noDict repcode */ + if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { + mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4; + ip++; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength); + goto _match_stored; + } + + hl1 = ZSTD_hashPtr(ip1, hBitsL, 8); + + /* idxl0 > prefixLowestIndex is a (somewhat) unpredictable branch. + * However expression below complies into conditional move. Since + * match is unlikely and we only *branch* on idxl0 > prefixLowestIndex + * if there is a match, all branches become predictable. */ + { const BYTE* const matchl0_safe = ZSTD_selectAddr(idxl0, prefixLowestIndex, matchl0, &dummy[0]); + + /* check prefix long match */ + if (MEM_read64(matchl0_safe) == MEM_read64(ip) && matchl0_safe == matchl0) { + mLength = ZSTD_count(ip+8, matchl0+8, iend) + 8; + offset = (U32)(ip-matchl0); + while (((ip>anchor) & (matchl0>prefixLowest)) && (ip[-1] == matchl0[-1])) { ip--; matchl0--; mLength++; } /* catch up */ + goto _match_found; + } } + + idxl1 = hashLong[hl1]; + matchl1 = base + idxl1; + + /* Same optimization as matchl0 above */ + matchs0_safe = ZSTD_selectAddr(idxs0, prefixLowestIndex, matchs0, &dummy[0]); + + /* check prefix short match */ + if(MEM_read32(matchs0_safe) == MEM_read32(ip) && matchs0_safe == matchs0) { + goto _search_next_long; + } + + if (ip1 >= nextStep) { + PREFETCH_L1(ip1 + 64); + PREFETCH_L1(ip1 + 128); + step++; + nextStep += kStepIncr; + } + ip = ip1; + ip1 += step; + + hl0 = hl1; + idxl0 = idxl1; + matchl0 = matchl1; + #if defined(__aarch64__) + PREFETCH_L1(ip+256); + #endif + } while (ip1 <= ilimit); + +_cleanup: + /* If offset_1 started invalid (offsetSaved1 != 0) and became valid (offset_1 != 0), + * rotate saved offsets. See comment in ZSTD_compressBlock_fast_noDict for more context. */ + offsetSaved2 = ((offsetSaved1 != 0) && (offset_1 != 0)) ? offsetSaved1 : offsetSaved2; + + /* save reps for next block */ + rep[0] = offset_1 ? offset_1 : offsetSaved1; + rep[1] = offset_2 ? offset_2 : offsetSaved2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); + +_search_next_long: + + /* short match found: let's check for a longer one */ + mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4; + offset = (U32)(ip - matchs0); + + /* check long match at +1 position */ + if ((idxl1 > prefixLowestIndex) && (MEM_read64(matchl1) == MEM_read64(ip1))) { + size_t const l1len = ZSTD_count(ip1+8, matchl1+8, iend) + 8; + if (l1len > mLength) { + /* use the long match instead */ + ip = ip1; + mLength = l1len; + offset = (U32)(ip-matchl1); + matchs0 = matchl1; + } + } + + while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* complete backward */ + + /* fall-through */ + +_match_found: /* requires ip, offset, mLength */ + offset_2 = offset_1; + offset_1 = offset; + + if (step < 4) { + /* It is unsafe to write this value back to the hashtable when ip1 is + * greater than or equal to the new ip we will have after we're done + * processing this match. Rather than perform that test directly + * (ip1 >= ip + mLength), which costs speed in practice, we do a simpler + * more predictable test. The minmatch even if we take a short match is + * 4 bytes, so as long as step, the distance between ip and ip1 + * (initially) is less than 4, we know ip1 < new ip. */ + hashLong[hl1] = (U32)(ip1 - base); + } + + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + +_match_stored: + /* match found */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Complementary insertion */ + /* done after iLimit test, as candidates could be > iend-8 */ + { U32 const indexToInsert = curr+2; + hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; + hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); + hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; + hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); + } + + /* check immediate repcode */ + while ( (ip <= ilimit) + && ( (offset_2>0) + & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) { + /* store sequence */ + size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4; + U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */ + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base); + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base); + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, rLength); + ip += rLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } + } + } +} + + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_doubleFast_dictMatchState_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, + U32 const mls /* template */) +{ + ZSTD_compressionParameters const* cParams = &ms->cParams; + U32* const hashLong = ms->hashTable; + const U32 hBitsL = cParams->hashLog; + U32* const hashSmall = ms->chainTable; + const U32 hBitsS = cParams->chainLog; + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + /* presumes that, if there is a dictionary, it must be using Attach mode */ + const U32 prefixLowestIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); + const BYTE* const prefixLowest = base + prefixLowestIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + U32 offset_1=rep[0], offset_2=rep[1]; + + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + const ZSTD_compressionParameters* const dictCParams = &dms->cParams; + const U32* const dictHashLong = dms->hashTable; + const U32* const dictHashSmall = dms->chainTable; + const U32 dictStartIndex = dms->window.dictLimit; + const BYTE* const dictBase = dms->window.base; + const BYTE* const dictStart = dictBase + dictStartIndex; + const BYTE* const dictEnd = dms->window.nextSrc; + const U32 dictIndexDelta = prefixLowestIndex - (U32)(dictEnd - dictBase); + const U32 dictHBitsL = dictCParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS; + const U32 dictHBitsS = dictCParams->chainLog + ZSTD_SHORT_CACHE_TAG_BITS; + const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictStart)); + + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_dictMatchState_generic"); + + /* if a dictionary is attached, it must be within window range */ + assert(ms->window.dictLimit + (1U << cParams->windowLog) >= endIndex); + + if (ms->prefetchCDictTables) { + size_t const hashTableBytes = (((size_t)1) << dictCParams->hashLog) * sizeof(U32); + size_t const chainTableBytes = (((size_t)1) << dictCParams->chainLog) * sizeof(U32); + PREFETCH_AREA(dictHashLong, hashTableBytes); + PREFETCH_AREA(dictHashSmall, chainTableBytes); + } + + /* init */ + ip += (dictAndPrefixLength == 0); + + /* dictMatchState repCode checks don't currently handle repCode == 0 + * disabling. */ + assert(offset_1 <= dictAndPrefixLength); + assert(offset_2 <= dictAndPrefixLength); + + /* Main Search Loop */ + while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */ + size_t mLength; + U32 offset; + size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8); + size_t const h = ZSTD_hashPtr(ip, hBitsS, mls); + size_t const dictHashAndTagL = ZSTD_hashPtr(ip, dictHBitsL, 8); + size_t const dictHashAndTagS = ZSTD_hashPtr(ip, dictHBitsS, mls); + U32 const dictMatchIndexAndTagL = dictHashLong[dictHashAndTagL >> ZSTD_SHORT_CACHE_TAG_BITS]; + U32 const dictMatchIndexAndTagS = dictHashSmall[dictHashAndTagS >> ZSTD_SHORT_CACHE_TAG_BITS]; + int const dictTagsMatchL = ZSTD_comparePackedTags(dictMatchIndexAndTagL, dictHashAndTagL); + int const dictTagsMatchS = ZSTD_comparePackedTags(dictMatchIndexAndTagS, dictHashAndTagS); + U32 const curr = (U32)(ip-base); + U32 const matchIndexL = hashLong[h2]; + U32 matchIndexS = hashSmall[h]; + const BYTE* matchLong = base + matchIndexL; + const BYTE* match = base + matchIndexS; + const U32 repIndex = curr + 1 - offset_1; + const BYTE* repMatch = (repIndex < prefixLowestIndex) ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + hashLong[h2] = hashSmall[h] = curr; /* update hash tables */ + + /* check repcode */ + if ((ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { + const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; + mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4; + ip++; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength); + goto _match_stored; + } + + if ((matchIndexL >= prefixLowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) { + /* check prefix long match */ + mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8; + offset = (U32)(ip-matchLong); + while (((ip>anchor) & (matchLong>prefixLowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */ + goto _match_found; + } else if (dictTagsMatchL) { + /* check dictMatchState long match */ + U32 const dictMatchIndexL = dictMatchIndexAndTagL >> ZSTD_SHORT_CACHE_TAG_BITS; + const BYTE* dictMatchL = dictBase + dictMatchIndexL; + assert(dictMatchL < dictEnd); + + if (dictMatchL > dictStart && MEM_read64(dictMatchL) == MEM_read64(ip)) { + mLength = ZSTD_count_2segments(ip+8, dictMatchL+8, iend, dictEnd, prefixLowest) + 8; + offset = (U32)(curr - dictMatchIndexL - dictIndexDelta); + while (((ip>anchor) & (dictMatchL>dictStart)) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } /* catch up */ + goto _match_found; + } } + + if (matchIndexS > prefixLowestIndex) { + /* short match candidate */ + if (MEM_read32(match) == MEM_read32(ip)) { + goto _search_next_long; + } + } else if (dictTagsMatchS) { + /* check dictMatchState short match */ + U32 const dictMatchIndexS = dictMatchIndexAndTagS >> ZSTD_SHORT_CACHE_TAG_BITS; + match = dictBase + dictMatchIndexS; + matchIndexS = dictMatchIndexS + dictIndexDelta; + + if (match > dictStart && MEM_read32(match) == MEM_read32(ip)) { + goto _search_next_long; + } } + + ip += ((ip-anchor) >> kSearchStrength) + 1; +#if defined(__aarch64__) + PREFETCH_L1(ip+256); +#endif + continue; + +_search_next_long: + { size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8); + size_t const dictHashAndTagL3 = ZSTD_hashPtr(ip+1, dictHBitsL, 8); + U32 const matchIndexL3 = hashLong[hl3]; + U32 const dictMatchIndexAndTagL3 = dictHashLong[dictHashAndTagL3 >> ZSTD_SHORT_CACHE_TAG_BITS]; + int const dictTagsMatchL3 = ZSTD_comparePackedTags(dictMatchIndexAndTagL3, dictHashAndTagL3); + const BYTE* matchL3 = base + matchIndexL3; + hashLong[hl3] = curr + 1; + + /* check prefix long +1 match */ + if ((matchIndexL3 >= prefixLowestIndex) && (MEM_read64(matchL3) == MEM_read64(ip+1))) { + mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8; + ip++; + offset = (U32)(ip-matchL3); + while (((ip>anchor) & (matchL3>prefixLowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */ + goto _match_found; + } else if (dictTagsMatchL3) { + /* check dict long +1 match */ + U32 const dictMatchIndexL3 = dictMatchIndexAndTagL3 >> ZSTD_SHORT_CACHE_TAG_BITS; + const BYTE* dictMatchL3 = dictBase + dictMatchIndexL3; + assert(dictMatchL3 < dictEnd); + if (dictMatchL3 > dictStart && MEM_read64(dictMatchL3) == MEM_read64(ip+1)) { + mLength = ZSTD_count_2segments(ip+1+8, dictMatchL3+8, iend, dictEnd, prefixLowest) + 8; + ip++; + offset = (U32)(curr + 1 - dictMatchIndexL3 - dictIndexDelta); + while (((ip>anchor) & (dictMatchL3>dictStart)) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } /* catch up */ + goto _match_found; + } } } + + /* if no long +1 match, explore the short match we found */ + if (matchIndexS < prefixLowestIndex) { + mLength = ZSTD_count_2segments(ip+4, match+4, iend, dictEnd, prefixLowest) + 4; + offset = (U32)(curr - matchIndexS); + while (((ip>anchor) & (match>dictStart)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ + } else { + mLength = ZSTD_count(ip+4, match+4, iend) + 4; + offset = (U32)(ip - match); + while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ + } + +_match_found: + offset_2 = offset_1; + offset_1 = offset; + + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + +_match_stored: + /* match found */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Complementary insertion */ + /* done after iLimit test, as candidates could be > iend-8 */ + { U32 const indexToInsert = curr+2; + hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; + hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); + hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; + hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); + } + + /* check immediate repcode */ + while (ip <= ilimit) { + U32 const current2 = (U32)(ip-base); + U32 const repIndex2 = current2 - offset_2; + const BYTE* repMatch2 = repIndex2 < prefixLowestIndex ? + dictBase + repIndex2 - dictIndexDelta : + base + repIndex2; + if ( (ZSTD_index_overlap_check(prefixLowestIndex, repIndex2)) + && (MEM_read32(repMatch2) == MEM_read32(ip)) ) { + const BYTE* const repEnd2 = repIndex2 < prefixLowestIndex ? dictEnd : iend; + size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixLowest) + 4; + U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2); + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2; + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2; + ip += repLength2; + anchor = ip; + continue; + } + break; + } + } + } /* while (ip < ilimit) */ + + /* save reps for next block */ + rep[0] = offset_1; + rep[1] = offset_2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} + +#define ZSTD_GEN_DFAST_FN(dictMode, mls) \ + static size_t ZSTD_compressBlock_doubleFast_##dictMode##_##mls( \ + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \ + void const* src, size_t srcSize) \ + { \ + return ZSTD_compressBlock_doubleFast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mls); \ + } + +ZSTD_GEN_DFAST_FN(noDict, 4) +ZSTD_GEN_DFAST_FN(noDict, 5) +ZSTD_GEN_DFAST_FN(noDict, 6) +ZSTD_GEN_DFAST_FN(noDict, 7) + +ZSTD_GEN_DFAST_FN(dictMatchState, 4) +ZSTD_GEN_DFAST_FN(dictMatchState, 5) +ZSTD_GEN_DFAST_FN(dictMatchState, 6) +ZSTD_GEN_DFAST_FN(dictMatchState, 7) + + +size_t ZSTD_compressBlock_doubleFast( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + const U32 mls = ms->cParams.minMatch; + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_doubleFast_noDict_4(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_doubleFast_noDict_5(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_doubleFast_noDict_6(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_doubleFast_noDict_7(ms, seqStore, rep, src, srcSize); + } +} + + +size_t ZSTD_compressBlock_doubleFast_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + const U32 mls = ms->cParams.minMatch; + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_doubleFast_dictMatchState_4(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_doubleFast_dictMatchState_5(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_doubleFast_dictMatchState_6(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_doubleFast_dictMatchState_7(ms, seqStore, rep, src, srcSize); + } +} + + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_doubleFast_extDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, + U32 const mls /* template */) +{ + ZSTD_compressionParameters const* cParams = &ms->cParams; + U32* const hashLong = ms->hashTable; + U32 const hBitsL = cParams->hashLog; + U32* const hashSmall = ms->chainTable; + U32 const hBitsS = cParams->chainLog; + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - 8; + const BYTE* const base = ms->window.base; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + const U32 lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog); + const U32 dictStartIndex = lowLimit; + const U32 dictLimit = ms->window.dictLimit; + const U32 prefixStartIndex = (dictLimit > lowLimit) ? dictLimit : lowLimit; + const BYTE* const prefixStart = base + prefixStartIndex; + const BYTE* const dictBase = ms->window.dictBase; + const BYTE* const dictStart = dictBase + dictStartIndex; + const BYTE* const dictEnd = dictBase + prefixStartIndex; + U32 offset_1=rep[0], offset_2=rep[1]; + + DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_extDict_generic (srcSize=%zu)", srcSize); + + /* if extDict is invalidated due to maxDistance, switch to "regular" variant */ + if (prefixStartIndex == dictStartIndex) + return ZSTD_compressBlock_doubleFast(ms, seqStore, rep, src, srcSize); + + /* Search Loop */ + while (ip < ilimit) { /* < instead of <=, because (ip+1) */ + const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls); + const U32 matchIndex = hashSmall[hSmall]; + const BYTE* const matchBase = matchIndex < prefixStartIndex ? dictBase : base; + const BYTE* match = matchBase + matchIndex; + + const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8); + const U32 matchLongIndex = hashLong[hLong]; + const BYTE* const matchLongBase = matchLongIndex < prefixStartIndex ? dictBase : base; + const BYTE* matchLong = matchLongBase + matchLongIndex; + + const U32 curr = (U32)(ip-base); + const U32 repIndex = curr + 1 - offset_1; /* offset_1 expected <= curr +1 */ + const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base; + const BYTE* const repMatch = repBase + repIndex; + size_t mLength; + hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */ + + if (((ZSTD_index_overlap_check(prefixStartIndex, repIndex)) + & (offset_1 <= curr+1 - dictStartIndex)) /* note: we are searching at curr+1 */ + && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { + const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend; + mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4; + ip++; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength); + } else { + if ((matchLongIndex > dictStartIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) { + const BYTE* const matchEnd = matchLongIndex < prefixStartIndex ? dictEnd : iend; + const BYTE* const lowMatchPtr = matchLongIndex < prefixStartIndex ? dictStart : prefixStart; + U32 offset; + mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, prefixStart) + 8; + offset = curr - matchLongIndex; + while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */ + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + + } else if ((matchIndex > dictStartIndex) && (MEM_read32(match) == MEM_read32(ip))) { + size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8); + U32 const matchIndex3 = hashLong[h3]; + const BYTE* const match3Base = matchIndex3 < prefixStartIndex ? dictBase : base; + const BYTE* match3 = match3Base + matchIndex3; + U32 offset; + hashLong[h3] = curr + 1; + if ( (matchIndex3 > dictStartIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) { + const BYTE* const matchEnd = matchIndex3 < prefixStartIndex ? dictEnd : iend; + const BYTE* const lowMatchPtr = matchIndex3 < prefixStartIndex ? dictStart : prefixStart; + mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, prefixStart) + 8; + ip++; + offset = curr+1 - matchIndex3; + while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */ + } else { + const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend; + const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart; + mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4; + offset = curr - matchIndex; + while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */ + } + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + + } else { + ip += ((ip-anchor) >> kSearchStrength) + 1; + continue; + } } + + /* move to next sequence start */ + ip += mLength; + anchor = ip; + + if (ip <= ilimit) { + /* Complementary insertion */ + /* done after iLimit test, as candidates could be > iend-8 */ + { U32 const indexToInsert = curr+2; + hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert; + hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base); + hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert; + hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base); + } + + /* check immediate repcode */ + while (ip <= ilimit) { + U32 const current2 = (U32)(ip-base); + U32 const repIndex2 = current2 - offset_2; + const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2; + if ( ((ZSTD_index_overlap_check(prefixStartIndex, repIndex2)) + & (offset_2 <= current2 - dictStartIndex)) + && (MEM_read32(repMatch2) == MEM_read32(ip)) ) { + const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; + size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4; + U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2); + hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2; + hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2; + ip += repLength2; + anchor = ip; + continue; + } + break; + } } } + + /* save reps for next block */ + rep[0] = offset_1; + rep[1] = offset_2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} + +ZSTD_GEN_DFAST_FN(extDict, 4) +ZSTD_GEN_DFAST_FN(extDict, 5) +ZSTD_GEN_DFAST_FN(extDict, 6) +ZSTD_GEN_DFAST_FN(extDict, 7) + +size_t ZSTD_compressBlock_doubleFast_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + U32 const mls = ms->cParams.minMatch; + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_doubleFast_extDict_4(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_doubleFast_extDict_5(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_doubleFast_extDict_6(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_doubleFast_extDict_7(ms, seqStore, rep, src, srcSize); + } +} + +#endif /* ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_double_fast.h b/src/commonlib/bsd/zstd/compress/zstd_double_fast.h new file mode 100644 index 00000000000..73c5e710c8a --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_double_fast.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_DOUBLE_FAST_H +#define ZSTD_DOUBLE_FAST_H + +#include "../common/mem.h" /* U32 */ +#include "zstd_compress_internal.h" /* ZSTD_CCtx, size_t */ + +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + +void ZSTD_fillDoubleHashTable(ZSTD_MatchState_t* ms, + void const* end, ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp); + +size_t ZSTD_compressBlock_doubleFast( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_doubleFast_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_doubleFast_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST ZSTD_compressBlock_doubleFast +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_DICTMATCHSTATE ZSTD_compressBlock_doubleFast_dictMatchState +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_EXTDICT ZSTD_compressBlock_doubleFast_extDict +#else +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST NULL +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_DOUBLEFAST_EXTDICT NULL +#endif /* ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR */ + +#endif /* ZSTD_DOUBLE_FAST_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_fast.c b/src/commonlib/bsd/zstd/compress/zstd_fast.c new file mode 100644 index 00000000000..1cc9de5dbd5 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_fast.c @@ -0,0 +1,987 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_compress_internal.h" /* ZSTD_hashPtr, ZSTD_count, ZSTD_storeSeq */ +#include "zstd_fast.h" + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillHashTableForCDict(ZSTD_MatchState_t* ms, + const void* const end, + ZSTD_dictTableLoadMethod_e dtlm) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hBits = cParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS; + U32 const mls = cParams->minMatch; + const BYTE* const base = ms->window.base; + const BYTE* ip = base + ms->nextToUpdate; + const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; + const U32 fastHashFillStep = 3; + + /* Currently, we always use ZSTD_dtlm_full for filling CDict tables. + * Feel free to remove this assert if there's a good reason! */ + assert(dtlm == ZSTD_dtlm_full); + + /* Always insert every fastHashFillStep position into the hash table. + * Insert the other positions if their hash entry is empty. + */ + for ( ; ip + fastHashFillStep < iend + 2; ip += fastHashFillStep) { + U32 const curr = (U32)(ip - base); + { size_t const hashAndTag = ZSTD_hashPtr(ip, hBits, mls); + ZSTD_writeTaggedIndex(hashTable, hashAndTag, curr); } + + if (dtlm == ZSTD_dtlm_fast) continue; + /* Only load extra positions for ZSTD_dtlm_full */ + { U32 p; + for (p = 1; p < fastHashFillStep; ++p) { + size_t const hashAndTag = ZSTD_hashPtr(ip + p, hBits, mls); + if (hashTable[hashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS] == 0) { /* not yet filled */ + ZSTD_writeTaggedIndex(hashTable, hashAndTag, curr + p); + } } } } +} + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_fillHashTableForCCtx(ZSTD_MatchState_t* ms, + const void* const end, + ZSTD_dictTableLoadMethod_e dtlm) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hBits = cParams->hashLog; + U32 const mls = cParams->minMatch; + const BYTE* const base = ms->window.base; + const BYTE* ip = base + ms->nextToUpdate; + const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; + const U32 fastHashFillStep = 3; + + /* Currently, we always use ZSTD_dtlm_fast for filling CCtx tables. + * Feel free to remove this assert if there's a good reason! */ + assert(dtlm == ZSTD_dtlm_fast); + + /* Always insert every fastHashFillStep position into the hash table. + * Insert the other positions if their hash entry is empty. + */ + for ( ; ip + fastHashFillStep < iend + 2; ip += fastHashFillStep) { + U32 const curr = (U32)(ip - base); + size_t const hash0 = ZSTD_hashPtr(ip, hBits, mls); + hashTable[hash0] = curr; + if (dtlm == ZSTD_dtlm_fast) continue; + /* Only load extra positions for ZSTD_dtlm_full */ + { U32 p; + for (p = 1; p < fastHashFillStep; ++p) { + size_t const hash = ZSTD_hashPtr(ip + p, hBits, mls); + if (hashTable[hash] == 0) { /* not yet filled */ + hashTable[hash] = curr + p; + } } } } +} + +void ZSTD_fillHashTable(ZSTD_MatchState_t* ms, + const void* const end, + ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp) +{ + if (tfp == ZSTD_tfp_forCDict) { + ZSTD_fillHashTableForCDict(ms, end, dtlm); + } else { + ZSTD_fillHashTableForCCtx(ms, end, dtlm); + } +} + + +typedef int (*ZSTD_match4Found) (const BYTE* currentPtr, const BYTE* matchAddress, U32 matchIdx, U32 idxLowLimit); + +static int +ZSTD_match4Found_cmov(const BYTE* currentPtr, const BYTE* matchAddress, U32 matchIdx, U32 idxLowLimit) +{ + /* Array of ~random data, should have low probability of matching data. + * Load from here if the index is invalid. + * Used to avoid unpredictable branches. */ + static const BYTE dummy[] = {0x12,0x34,0x56,0x78}; + + /* currentIdx >= lowLimit is a (somewhat) unpredictable branch. + * However expression below compiles into conditional move. + */ + const BYTE* mvalAddr = ZSTD_selectAddr(matchIdx, idxLowLimit, matchAddress, dummy); + /* Note: this used to be written as : return test1 && test2; + * Unfortunately, once inlined, these tests become branches, + * in which case it becomes critical that they are executed in the right order (test1 then test2). + * So we have to write these tests in a specific manner to ensure their ordering. + */ + if (MEM_read32(currentPtr) != MEM_read32(mvalAddr)) return 0; + /* force ordering of these tests, which matters once the function is inlined, as they become branches */ +#if defined(__GNUC__) + __asm__(""); +#endif + return matchIdx >= idxLowLimit; +} + +static int +ZSTD_match4Found_branch(const BYTE* currentPtr, const BYTE* matchAddress, U32 matchIdx, U32 idxLowLimit) +{ + /* using a branch instead of a cmov, + * because it's faster in scenarios where matchIdx >= idxLowLimit is generally true, + * aka almost all candidates are within range */ + U32 mval; + if (matchIdx >= idxLowLimit) { + mval = MEM_read32(matchAddress); + } else { + mval = MEM_read32(currentPtr) ^ 1; /* guaranteed to not match. */ + } + + return (MEM_read32(currentPtr) == mval); +} + + +/** + * If you squint hard enough (and ignore repcodes), the search operation at any + * given position is broken into 4 stages: + * + * 1. Hash (map position to hash value via input read) + * 2. Lookup (map hash val to index via hashtable read) + * 3. Load (map index to value at that position via input read) + * 4. Compare + * + * Each of these steps involves a memory read at an address which is computed + * from the previous step. This means these steps must be sequenced and their + * latencies are cumulative. + * + * Rather than do 1->2->3->4 sequentially for a single position before moving + * onto the next, this implementation interleaves these operations across the + * next few positions: + * + * R = Repcode Read & Compare + * H = Hash + * T = Table Lookup + * M = Match Read & Compare + * + * Pos | Time --> + * ----+------------------- + * N | ... M + * N+1 | ... TM + * N+2 | R H T M + * N+3 | H TM + * N+4 | R H T M + * N+5 | H ... + * N+6 | R ... + * + * This is very much analogous to the pipelining of execution in a CPU. And just + * like a CPU, we have to dump the pipeline when we find a match (i.e., take a + * branch). + * + * When this happens, we throw away our current state, and do the following prep + * to re-enter the loop: + * + * Pos | Time --> + * ----+------------------- + * N | H T + * N+1 | H + * + * This is also the work we do at the beginning to enter the loop initially. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_fast_noDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, + U32 const mls, int useCmov) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hlog = cParams->hashLog; + size_t const stepSize = cParams->targetLength + !(cParams->targetLength) + 1; /* min 2 */ + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + const U32 prefixStartIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog); + const BYTE* const prefixStart = base + prefixStartIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + + const BYTE* anchor = istart; + const BYTE* ip0 = istart; + const BYTE* ip1; + const BYTE* ip2; + const BYTE* ip3; + U32 current0; + + U32 rep_offset1 = rep[0]; + U32 rep_offset2 = rep[1]; + U32 offsetSaved1 = 0, offsetSaved2 = 0; + + size_t hash0; /* hash for ip0 */ + size_t hash1; /* hash for ip1 */ + U32 matchIdx; /* match idx for ip0 */ + + U32 offcode; + const BYTE* match0; + size_t mLength; + + /* ip0 and ip1 are always adjacent. The targetLength skipping and + * uncompressibility acceleration is applied to every other position, + * matching the behavior of #1562. step therefore represents the gap + * between pairs of positions, from ip0 to ip2 or ip1 to ip3. */ + size_t step; + const BYTE* nextStep; + const size_t kStepIncr = (1 << (kSearchStrength - 1)); + const ZSTD_match4Found matchFound = useCmov ? ZSTD_match4Found_cmov : ZSTD_match4Found_branch; + + DEBUGLOG(5, "ZSTD_compressBlock_fast_generic"); + ip0 += (ip0 == prefixStart); + { U32 const curr = (U32)(ip0 - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog); + U32 const maxRep = curr - windowLow; + if (rep_offset2 > maxRep) offsetSaved2 = rep_offset2, rep_offset2 = 0; + if (rep_offset1 > maxRep) offsetSaved1 = rep_offset1, rep_offset1 = 0; + } + + /* start each op */ +_start: /* Requires: ip0 */ + + step = stepSize; + nextStep = ip0 + kStepIncr; + + /* calculate positions, ip0 - anchor == 0, so we skip step calc */ + ip1 = ip0 + 1; + ip2 = ip0 + step; + ip3 = ip2 + 1; + + if (ip3 >= ilimit) { + goto _cleanup; + } + + hash0 = ZSTD_hashPtr(ip0, hlog, mls); + hash1 = ZSTD_hashPtr(ip1, hlog, mls); + + matchIdx = hashTable[hash0]; + + do { + /* load repcode match for ip[2]*/ + const U32 rval = MEM_read32(ip2 - rep_offset1); + + /* write back hash table entry */ + current0 = (U32)(ip0 - base); + hashTable[hash0] = current0; + + /* check repcode at ip[2] */ + if ((MEM_read32(ip2) == rval) & (rep_offset1 > 0)) { + ip0 = ip2; + match0 = ip0 - rep_offset1; + mLength = ip0[-1] == match0[-1]; + ip0 -= mLength; + match0 -= mLength; + offcode = REPCODE1_TO_OFFBASE; + mLength += 4; + + /* Write next hash table entry: it's already calculated. + * This write is known to be safe because ip1 is before the + * repcode (ip2). */ + hashTable[hash1] = (U32)(ip1 - base); + + goto _match; + } + + if (matchFound(ip0, base + matchIdx, matchIdx, prefixStartIndex)) { + /* Write next hash table entry (it's already calculated). + * This write is known to be safe because the ip1 == ip0 + 1, + * so searching will resume after ip1 */ + hashTable[hash1] = (U32)(ip1 - base); + + goto _offset; + } + + /* lookup ip[1] */ + matchIdx = hashTable[hash1]; + + /* hash ip[2] */ + hash0 = hash1; + hash1 = ZSTD_hashPtr(ip2, hlog, mls); + + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 = ip3; + + /* write back hash table entry */ + current0 = (U32)(ip0 - base); + hashTable[hash0] = current0; + + if (matchFound(ip0, base + matchIdx, matchIdx, prefixStartIndex)) { + /* Write next hash table entry, since it's already calculated */ + if (step <= 4) { + /* Avoid writing an index if it's >= position where search will resume. + * The minimum possible match has length 4, so search can resume at ip0 + 4. + */ + hashTable[hash1] = (U32)(ip1 - base); + } + goto _offset; + } + + /* lookup ip[1] */ + matchIdx = hashTable[hash1]; + + /* hash ip[2] */ + hash0 = hash1; + hash1 = ZSTD_hashPtr(ip2, hlog, mls); + + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 = ip0 + step; + ip3 = ip1 + step; + + /* calculate step */ + if (ip2 >= nextStep) { + step++; + PREFETCH_L1(ip1 + 64); + PREFETCH_L1(ip1 + 128); + nextStep += kStepIncr; + } + } while (ip3 < ilimit); + +_cleanup: + /* Note that there are probably still a couple positions one could search. + * However, it seems to be a meaningful performance hit to try to search + * them. So let's not. */ + + /* When the repcodes are outside of the prefix, we set them to zero before the loop. + * When the offsets are still zero, we need to restore them after the block to have a correct + * repcode history. If only one offset was invalid, it is easy. The tricky case is when both + * offsets were invalid. We need to figure out which offset to refill with. + * - If both offsets are zero they are in the same order. + * - If both offsets are non-zero, we won't restore the offsets from `offsetSaved[12]`. + * - If only one is zero, we need to decide which offset to restore. + * - If rep_offset1 is non-zero, then rep_offset2 must be offsetSaved1. + * - It is impossible for rep_offset2 to be non-zero. + * + * So if rep_offset1 started invalid (offsetSaved1 != 0) and became valid (rep_offset1 != 0), then + * set rep[0] = rep_offset1 and rep[1] = offsetSaved1. + */ + offsetSaved2 = ((offsetSaved1 != 0) && (rep_offset1 != 0)) ? offsetSaved1 : offsetSaved2; + + /* save reps for next block */ + rep[0] = rep_offset1 ? rep_offset1 : offsetSaved1; + rep[1] = rep_offset2 ? rep_offset2 : offsetSaved2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); + +_offset: /* Requires: ip0, idx */ + + /* Compute the offset code. */ + match0 = base + matchIdx; + rep_offset2 = rep_offset1; + rep_offset1 = (U32)(ip0-match0); + offcode = OFFSET_TO_OFFBASE(rep_offset1); + mLength = 4; + + /* Count the backwards match length. */ + while (((ip0>anchor) & (match0>prefixStart)) && (ip0[-1] == match0[-1])) { + ip0--; + match0--; + mLength++; + } + +_match: /* Requires: ip0, match0, offcode */ + + /* Count the forward length. */ + mLength += ZSTD_count(ip0 + mLength, match0 + mLength, iend); + + ZSTD_storeSeq(seqStore, (size_t)(ip0 - anchor), anchor, iend, offcode, mLength); + + ip0 += mLength; + anchor = ip0; + + /* Fill table and check for immediate repcode. */ + if (ip0 <= ilimit) { + /* Fill Table */ + assert(base+current0+2 > istart); /* check base overflow */ + hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */ + hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base); + + if (rep_offset2 > 0) { /* rep_offset2==0 means rep_offset2 is invalidated */ + while ( (ip0 <= ilimit) && (MEM_read32(ip0) == MEM_read32(ip0 - rep_offset2)) ) { + /* store sequence */ + size_t const rLength = ZSTD_count(ip0+4, ip0+4-rep_offset2, iend) + 4; + { U32 const tmpOff = rep_offset2; rep_offset2 = rep_offset1; rep_offset1 = tmpOff; } /* swap rep_offset2 <=> rep_offset1 */ + hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base); + ip0 += rLength; + ZSTD_storeSeq(seqStore, 0 /*litLen*/, anchor, iend, REPCODE1_TO_OFFBASE, rLength); + anchor = ip0; + continue; /* faster when present (confirmed on gcc-8) ... (?) */ + } } } + + goto _start; +} + +#define ZSTD_GEN_FAST_FN(dictMode, mml, cmov) \ + static size_t ZSTD_compressBlock_fast_##dictMode##_##mml##_##cmov( \ + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \ + void const* src, size_t srcSize) \ + { \ + return ZSTD_compressBlock_fast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mml, cmov); \ + } + +ZSTD_GEN_FAST_FN(noDict, 4, 1) +ZSTD_GEN_FAST_FN(noDict, 5, 1) +ZSTD_GEN_FAST_FN(noDict, 6, 1) +ZSTD_GEN_FAST_FN(noDict, 7, 1) + +ZSTD_GEN_FAST_FN(noDict, 4, 0) +ZSTD_GEN_FAST_FN(noDict, 5, 0) +ZSTD_GEN_FAST_FN(noDict, 6, 0) +ZSTD_GEN_FAST_FN(noDict, 7, 0) + +size_t ZSTD_compressBlock_fast( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + U32 const mml = ms->cParams.minMatch; + /* use cmov when "candidate in range" branch is likely unpredictable */ + int const useCmov = ms->cParams.windowLog < 19; + assert(ms->dictMatchState == NULL); + if (useCmov) { + switch(mml) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_noDict_4_1(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_noDict_5_1(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_noDict_6_1(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_noDict_7_1(ms, seqStore, rep, src, srcSize); + } + } else { + /* use a branch instead */ + switch(mml) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_noDict_4_0(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_noDict_5_0(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_noDict_6_0(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_noDict_7_0(ms, seqStore, rep, src, srcSize); + } + } +} + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_fast_dictMatchState_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, U32 const mls, U32 const hasStep) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hlog = cParams->hashLog; + /* support stepSize of 0 */ + U32 const stepSize = cParams->targetLength + !(cParams->targetLength); + const BYTE* const base = ms->window.base; + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip0 = istart; + const BYTE* ip1 = ip0 + stepSize; /* we assert below that stepSize >= 1 */ + const BYTE* anchor = istart; + const U32 prefixStartIndex = ms->window.dictLimit; + const BYTE* const prefixStart = base + prefixStartIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - HASH_READ_SIZE; + U32 offset_1=rep[0], offset_2=rep[1]; + + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + const ZSTD_compressionParameters* const dictCParams = &dms->cParams ; + const U32* const dictHashTable = dms->hashTable; + const U32 dictStartIndex = dms->window.dictLimit; + const BYTE* const dictBase = dms->window.base; + const BYTE* const dictStart = dictBase + dictStartIndex; + const BYTE* const dictEnd = dms->window.nextSrc; + const U32 dictIndexDelta = prefixStartIndex - (U32)(dictEnd - dictBase); + const U32 dictAndPrefixLength = (U32)(istart - prefixStart + dictEnd - dictStart); + const U32 dictHBits = dictCParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS; + + /* if a dictionary is still attached, it necessarily means that + * it is within window size. So we just check it. */ + const U32 maxDistance = 1U << cParams->windowLog; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + assert(endIndex - prefixStartIndex <= maxDistance); + (void)maxDistance; (void)endIndex; /* these variables are not used when assert() is disabled */ + + (void)hasStep; /* not currently specialized on whether it's accelerated */ + + /* ensure there will be no underflow + * when translating a dict index into a local index */ + assert(prefixStartIndex >= (U32)(dictEnd - dictBase)); + + if (ms->prefetchCDictTables) { + size_t const hashTableBytes = (((size_t)1) << dictCParams->hashLog) * sizeof(U32); + PREFETCH_AREA(dictHashTable, hashTableBytes); + } + + /* init */ + DEBUGLOG(5, "ZSTD_compressBlock_fast_dictMatchState_generic"); + ip0 += (dictAndPrefixLength == 0); + /* dictMatchState repCode checks don't currently handle repCode == 0 + * disabling. */ + assert(offset_1 <= dictAndPrefixLength); + assert(offset_2 <= dictAndPrefixLength); + + /* Outer search loop */ + assert(stepSize >= 1); + while (ip1 <= ilimit) { /* repcode check at (ip0 + 1) is safe because ip0 < ip1 */ + size_t mLength; + size_t hash0 = ZSTD_hashPtr(ip0, hlog, mls); + + size_t const dictHashAndTag0 = ZSTD_hashPtr(ip0, dictHBits, mls); + U32 dictMatchIndexAndTag = dictHashTable[dictHashAndTag0 >> ZSTD_SHORT_CACHE_TAG_BITS]; + int dictTagsMatch = ZSTD_comparePackedTags(dictMatchIndexAndTag, dictHashAndTag0); + + U32 matchIndex = hashTable[hash0]; + U32 curr = (U32)(ip0 - base); + size_t step = stepSize; + const size_t kStepIncr = 1 << kSearchStrength; + const BYTE* nextStep = ip0 + kStepIncr; + + /* Inner search loop */ + while (1) { + const BYTE* match = base + matchIndex; + const U32 repIndex = curr + 1 - offset_1; + const BYTE* repMatch = (repIndex < prefixStartIndex) ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + const size_t hash1 = ZSTD_hashPtr(ip1, hlog, mls); + size_t const dictHashAndTag1 = ZSTD_hashPtr(ip1, dictHBits, mls); + hashTable[hash0] = curr; /* update hash table */ + + if ((ZSTD_index_overlap_check(prefixStartIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip0 + 1))) { + const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend; + mLength = ZSTD_count_2segments(ip0 + 1 + 4, repMatch + 4, iend, repMatchEnd, prefixStart) + 4; + ip0++; + ZSTD_storeSeq(seqStore, (size_t) (ip0 - anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength); + break; + } + + if (dictTagsMatch) { + /* Found a possible dict match */ + const U32 dictMatchIndex = dictMatchIndexAndTag >> ZSTD_SHORT_CACHE_TAG_BITS; + const BYTE* dictMatch = dictBase + dictMatchIndex; + if (dictMatchIndex > dictStartIndex && + MEM_read32(dictMatch) == MEM_read32(ip0)) { + /* To replicate extDict parse behavior, we only use dict matches when the normal matchIndex is invalid */ + if (matchIndex <= prefixStartIndex) { + U32 const offset = (U32) (curr - dictMatchIndex - dictIndexDelta); + mLength = ZSTD_count_2segments(ip0 + 4, dictMatch + 4, iend, dictEnd, prefixStart) + 4; + while (((ip0 > anchor) & (dictMatch > dictStart)) + && (ip0[-1] == dictMatch[-1])) { + ip0--; + dictMatch--; + mLength++; + } /* catch up */ + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStore, (size_t) (ip0 - anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + break; + } + } + } + + if (ZSTD_match4Found_cmov(ip0, match, matchIndex, prefixStartIndex)) { + /* found a regular match of size >= 4 */ + U32 const offset = (U32) (ip0 - match); + mLength = ZSTD_count(ip0 + 4, match + 4, iend) + 4; + while (((ip0 > anchor) & (match > prefixStart)) + && (ip0[-1] == match[-1])) { + ip0--; + match--; + mLength++; + } /* catch up */ + offset_2 = offset_1; + offset_1 = offset; + ZSTD_storeSeq(seqStore, (size_t) (ip0 - anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength); + break; + } + + /* Prepare for next iteration */ + dictMatchIndexAndTag = dictHashTable[dictHashAndTag1 >> ZSTD_SHORT_CACHE_TAG_BITS]; + dictTagsMatch = ZSTD_comparePackedTags(dictMatchIndexAndTag, dictHashAndTag1); + matchIndex = hashTable[hash1]; + + if (ip1 >= nextStep) { + step++; + nextStep += kStepIncr; + } + ip0 = ip1; + ip1 = ip1 + step; + if (ip1 > ilimit) goto _cleanup; + + curr = (U32)(ip0 - base); + hash0 = hash1; + } /* end inner search loop */ + + /* match found */ + assert(mLength); + ip0 += mLength; + anchor = ip0; + + if (ip0 <= ilimit) { + /* Fill Table */ + assert(base+curr+2 > istart); /* check base overflow */ + hashTable[ZSTD_hashPtr(base+curr+2, hlog, mls)] = curr+2; /* here because curr+2 could be > iend-8 */ + hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base); + + /* check immediate repcode */ + while (ip0 <= ilimit) { + U32 const current2 = (U32)(ip0-base); + U32 const repIndex2 = current2 - offset_2; + const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? + dictBase - dictIndexDelta + repIndex2 : + base + repIndex2; + if ( (ZSTD_index_overlap_check(prefixStartIndex, repIndex2)) + && (MEM_read32(repMatch2) == MEM_read32(ip0))) { + const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; + size_t const repLength2 = ZSTD_count_2segments(ip0+4, repMatch2+4, iend, repEnd2, prefixStart) + 4; + U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2); + hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = current2; + ip0 += repLength2; + anchor = ip0; + continue; + } + break; + } + } + + /* Prepare for next iteration */ + assert(ip0 == anchor); + ip1 = ip0 + stepSize; + } + +_cleanup: + /* save reps for next block */ + rep[0] = offset_1; + rep[1] = offset_2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} + + +ZSTD_GEN_FAST_FN(dictMatchState, 4, 0) +ZSTD_GEN_FAST_FN(dictMatchState, 5, 0) +ZSTD_GEN_FAST_FN(dictMatchState, 6, 0) +ZSTD_GEN_FAST_FN(dictMatchState, 7, 0) + +size_t ZSTD_compressBlock_fast_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + U32 const mls = ms->cParams.minMatch; + assert(ms->dictMatchState != NULL); + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_dictMatchState_4_0(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_dictMatchState_5_0(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_dictMatchState_6_0(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_dictMatchState_7_0(ms, seqStore, rep, src, srcSize); + } +} + + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_fast_extDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize, U32 const mls, U32 const hasStep) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hlog = cParams->hashLog; + /* support stepSize of 0 */ + size_t const stepSize = cParams->targetLength + !(cParams->targetLength) + 1; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const BYTE* const istart = (const BYTE*)src; + const BYTE* anchor = istart; + const U32 endIndex = (U32)((size_t)(istart - base) + srcSize); + const U32 lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog); + const U32 dictStartIndex = lowLimit; + const BYTE* const dictStart = dictBase + dictStartIndex; + const U32 dictLimit = ms->window.dictLimit; + const U32 prefixStartIndex = dictLimit < lowLimit ? lowLimit : dictLimit; + const BYTE* const prefixStart = base + prefixStartIndex; + const BYTE* const dictEnd = dictBase + prefixStartIndex; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - 8; + U32 offset_1=rep[0], offset_2=rep[1]; + U32 offsetSaved1 = 0, offsetSaved2 = 0; + + const BYTE* ip0 = istart; + const BYTE* ip1; + const BYTE* ip2; + const BYTE* ip3; + U32 current0; + + + size_t hash0; /* hash for ip0 */ + size_t hash1; /* hash for ip1 */ + U32 idx; /* match idx for ip0 */ + const BYTE* idxBase; /* base pointer for idx */ + + U32 offcode; + const BYTE* match0; + size_t mLength; + const BYTE* matchEnd = 0; /* initialize to avoid warning, assert != 0 later */ + + size_t step; + const BYTE* nextStep; + const size_t kStepIncr = (1 << (kSearchStrength - 1)); + + (void)hasStep; /* not currently specialized on whether it's accelerated */ + + DEBUGLOG(5, "ZSTD_compressBlock_fast_extDict_generic (offset_1=%u)", offset_1); + + /* switch to "regular" variant if extDict is invalidated due to maxDistance */ + if (prefixStartIndex == dictStartIndex) + return ZSTD_compressBlock_fast(ms, seqStore, rep, src, srcSize); + + { U32 const curr = (U32)(ip0 - base); + U32 const maxRep = curr - dictStartIndex; + if (offset_2 >= maxRep) offsetSaved2 = offset_2, offset_2 = 0; + if (offset_1 >= maxRep) offsetSaved1 = offset_1, offset_1 = 0; + } + + /* start each op */ +_start: /* Requires: ip0 */ + + step = stepSize; + nextStep = ip0 + kStepIncr; + + /* calculate positions, ip0 - anchor == 0, so we skip step calc */ + ip1 = ip0 + 1; + ip2 = ip0 + step; + ip3 = ip2 + 1; + + if (ip3 >= ilimit) { + goto _cleanup; + } + + hash0 = ZSTD_hashPtr(ip0, hlog, mls); + hash1 = ZSTD_hashPtr(ip1, hlog, mls); + + idx = hashTable[hash0]; + idxBase = idx < prefixStartIndex ? dictBase : base; + + do { + { /* load repcode match for ip[2] */ + U32 const current2 = (U32)(ip2 - base); + U32 const repIndex = current2 - offset_1; + const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base; + U32 rval; + if ( ((U32)(prefixStartIndex - repIndex) >= 4) /* intentional underflow */ + & (offset_1 > 0) ) { + rval = MEM_read32(repBase + repIndex); + } else { + rval = MEM_read32(ip2) ^ 1; /* guaranteed to not match. */ + } + + /* write back hash table entry */ + current0 = (U32)(ip0 - base); + hashTable[hash0] = current0; + + /* check repcode at ip[2] */ + if (MEM_read32(ip2) == rval) { + ip0 = ip2; + match0 = repBase + repIndex; + matchEnd = repIndex < prefixStartIndex ? dictEnd : iend; + assert((match0 != prefixStart) & (match0 != dictStart)); + mLength = ip0[-1] == match0[-1]; + ip0 -= mLength; + match0 -= mLength; + offcode = REPCODE1_TO_OFFBASE; + mLength += 4; + goto _match; + } } + + { /* load match for ip[0] */ + U32 const mval = idx >= dictStartIndex ? + MEM_read32(idxBase + idx) : + MEM_read32(ip0) ^ 1; /* guaranteed not to match */ + + /* check match at ip[0] */ + if (MEM_read32(ip0) == mval) { + /* found a match! */ + goto _offset; + } } + + /* lookup ip[1] */ + idx = hashTable[hash1]; + idxBase = idx < prefixStartIndex ? dictBase : base; + + /* hash ip[2] */ + hash0 = hash1; + hash1 = ZSTD_hashPtr(ip2, hlog, mls); + + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 = ip3; + + /* write back hash table entry */ + current0 = (U32)(ip0 - base); + hashTable[hash0] = current0; + + { /* load match for ip[0] */ + U32 const mval = idx >= dictStartIndex ? + MEM_read32(idxBase + idx) : + MEM_read32(ip0) ^ 1; /* guaranteed not to match */ + + /* check match at ip[0] */ + if (MEM_read32(ip0) == mval) { + /* found a match! */ + goto _offset; + } } + + /* lookup ip[1] */ + idx = hashTable[hash1]; + idxBase = idx < prefixStartIndex ? dictBase : base; + + /* hash ip[2] */ + hash0 = hash1; + hash1 = ZSTD_hashPtr(ip2, hlog, mls); + + /* advance to next positions */ + ip0 = ip1; + ip1 = ip2; + ip2 = ip0 + step; + ip3 = ip1 + step; + + /* calculate step */ + if (ip2 >= nextStep) { + step++; + PREFETCH_L1(ip1 + 64); + PREFETCH_L1(ip1 + 128); + nextStep += kStepIncr; + } + } while (ip3 < ilimit); + +_cleanup: + /* Note that there are probably still a couple positions we could search. + * However, it seems to be a meaningful performance hit to try to search + * them. So let's not. */ + + /* If offset_1 started invalid (offsetSaved1 != 0) and became valid (offset_1 != 0), + * rotate saved offsets. See comment in ZSTD_compressBlock_fast_noDict for more context. */ + offsetSaved2 = ((offsetSaved1 != 0) && (offset_1 != 0)) ? offsetSaved1 : offsetSaved2; + + /* save reps for next block */ + rep[0] = offset_1 ? offset_1 : offsetSaved1; + rep[1] = offset_2 ? offset_2 : offsetSaved2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); + +_offset: /* Requires: ip0, idx, idxBase */ + + /* Compute the offset code. */ + { U32 const offset = current0 - idx; + const BYTE* const lowMatchPtr = idx < prefixStartIndex ? dictStart : prefixStart; + matchEnd = idx < prefixStartIndex ? dictEnd : iend; + match0 = idxBase + idx; + offset_2 = offset_1; + offset_1 = offset; + offcode = OFFSET_TO_OFFBASE(offset); + mLength = 4; + + /* Count the backwards match length. */ + while (((ip0>anchor) & (match0>lowMatchPtr)) && (ip0[-1] == match0[-1])) { + ip0--; + match0--; + mLength++; + } } + +_match: /* Requires: ip0, match0, offcode, matchEnd */ + + /* Count the forward length. */ + assert(matchEnd != 0); + mLength += ZSTD_count_2segments(ip0 + mLength, match0 + mLength, iend, matchEnd, prefixStart); + + ZSTD_storeSeq(seqStore, (size_t)(ip0 - anchor), anchor, iend, offcode, mLength); + + ip0 += mLength; + anchor = ip0; + + /* write next hash table entry */ + if (ip1 < ip0) { + hashTable[hash1] = (U32)(ip1 - base); + } + + /* Fill table and check for immediate repcode. */ + if (ip0 <= ilimit) { + /* Fill Table */ + assert(base+current0+2 > istart); /* check base overflow */ + hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */ + hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base); + + while (ip0 <= ilimit) { + U32 const repIndex2 = (U32)(ip0-base) - offset_2; + const BYTE* const repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2; + if ( ((ZSTD_index_overlap_check(prefixStartIndex, repIndex2)) & (offset_2 > 0)) + && (MEM_read32(repMatch2) == MEM_read32(ip0)) ) { + const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend; + size_t const repLength2 = ZSTD_count_2segments(ip0+4, repMatch2+4, iend, repEnd2, prefixStart) + 4; + { U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; } /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0 /*litlen*/, anchor, iend, REPCODE1_TO_OFFBASE, repLength2); + hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base); + ip0 += repLength2; + anchor = ip0; + continue; + } + break; + } } + + goto _start; +} + +ZSTD_GEN_FAST_FN(extDict, 4, 0) +ZSTD_GEN_FAST_FN(extDict, 5, 0) +ZSTD_GEN_FAST_FN(extDict, 6, 0) +ZSTD_GEN_FAST_FN(extDict, 7, 0) + +size_t ZSTD_compressBlock_fast_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + U32 const mls = ms->cParams.minMatch; + assert(ms->dictMatchState == NULL); + switch(mls) + { + default: /* includes case 3 */ + case 4 : + return ZSTD_compressBlock_fast_extDict_4_0(ms, seqStore, rep, src, srcSize); + case 5 : + return ZSTD_compressBlock_fast_extDict_5_0(ms, seqStore, rep, src, srcSize); + case 6 : + return ZSTD_compressBlock_fast_extDict_6_0(ms, seqStore, rep, src, srcSize); + case 7 : + return ZSTD_compressBlock_fast_extDict_7_0(ms, seqStore, rep, src, srcSize); + } +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_fast.h b/src/commonlib/bsd/zstd/compress/zstd_fast.h new file mode 100644 index 00000000000..4ba4217f870 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_fast.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_FAST_H +#define ZSTD_FAST_H + +#include "../common/mem.h" /* U32 */ +#include "zstd_compress_internal.h" + +void ZSTD_fillHashTable(ZSTD_MatchState_t* ms, + void const* end, ZSTD_dictTableLoadMethod_e dtlm, + ZSTD_tableFillPurpose_e tfp); +size_t ZSTD_compressBlock_fast( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_fast_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_fast_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#endif /* ZSTD_FAST_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_lazy.c b/src/commonlib/bsd/zstd/compress/zstd_lazy.c new file mode 100644 index 00000000000..ef1f2fe0151 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_lazy.c @@ -0,0 +1,2201 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_compress_internal.h" +#include "zstd_lazy.h" +#include "../common/zstd_bits.h" /* ZSTD_countTrailingZeros64 */ + +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) + +#define kLazySkippingStep 8 + + +/*-************************************* +* Binary Tree search +***************************************/ + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_updateDUBT(ZSTD_MatchState_t* ms, + const BYTE* ip, const BYTE* iend, + U32 mls) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hashLog = cParams->hashLog; + + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + + const BYTE* const base = ms->window.base; + U32 const target = (U32)(ip - base); + U32 idx = ms->nextToUpdate; + + if (idx != target) + DEBUGLOG(7, "ZSTD_updateDUBT, from %u to %u (dictLimit:%u)", + idx, target, ms->window.dictLimit); + assert(ip + 8 <= iend); /* condition for ZSTD_hashPtr */ + (void)iend; + + assert(idx >= ms->window.dictLimit); /* condition for valid base+idx */ + for ( ; idx < target ; idx++) { + size_t const h = ZSTD_hashPtr(base + idx, hashLog, mls); /* assumption : ip + 8 <= iend */ + U32 const matchIndex = hashTable[h]; + + U32* const nextCandidatePtr = bt + 2*(idx&btMask); + U32* const sortMarkPtr = nextCandidatePtr + 1; + + DEBUGLOG(8, "ZSTD_updateDUBT: insert %u", idx); + hashTable[h] = idx; /* Update Hash Table */ + *nextCandidatePtr = matchIndex; /* update BT like a chain */ + *sortMarkPtr = ZSTD_DUBT_UNSORTED_MARK; + } + ms->nextToUpdate = target; +} + + +/** ZSTD_insertDUBT1() : + * sort one already inserted but unsorted position + * assumption : curr >= btlow == (curr - btmask) + * doesn't fail */ +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_insertDUBT1(const ZSTD_MatchState_t* ms, + U32 curr, const BYTE* inputEnd, + U32 nbCompares, U32 btLow, + const ZSTD_dictMode_e dictMode) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + size_t commonLengthSmaller=0, commonLengthLarger=0; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const ip = (curr>=dictLimit) ? base + curr : dictBase + curr; + const BYTE* const iend = (curr>=dictLimit) ? inputEnd : dictBase + dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* match; + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = smallerPtr + 1; + U32 matchIndex = *smallerPtr; /* this candidate is unsorted : next sorted candidate is reached through *smallerPtr, while *largerPtr contains previous unsorted candidate (which is already saved and can be overwritten) */ + U32 dummy32; /* to be nullified at the end */ + U32 const windowValid = ms->window.lowLimit; + U32 const maxDistance = 1U << cParams->windowLog; + U32 const windowLow = (curr - windowValid > maxDistance) ? curr - maxDistance : windowValid; + + + DEBUGLOG(8, "ZSTD_insertDUBT1(%u) (dictLimit=%u, lowLimit=%u)", + curr, dictLimit, windowLow); + assert(curr >= btLow); + assert(ip < iend); /* condition for ZSTD_count */ + + for (; nbCompares && (matchIndex > windowLow); --nbCompares) { + U32* const nextPtr = bt + 2*(matchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + assert(matchIndex < curr); + /* note : all candidates are now supposed sorted, + * but it's still possible to have nextPtr[1] == ZSTD_DUBT_UNSORTED_MARK + * when a real index has the same value as ZSTD_DUBT_UNSORTED_MARK */ + + if ( (dictMode != ZSTD_extDict) + || (matchIndex+matchLength >= dictLimit) /* both in current segment*/ + || (curr < dictLimit) /* both in extDict */) { + const BYTE* const mBase = ( (dictMode != ZSTD_extDict) + || (matchIndex+matchLength >= dictLimit)) ? + base : dictBase; + assert( (matchIndex+matchLength >= dictLimit) /* might be wrong if extDict is incorrectly set to 0 */ + || (curr < dictLimit) ); + match = mBase + matchIndex; + matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend); + } else { + match = dictBase + matchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); + if (matchIndex+matchLength >= dictLimit) + match = base + matchIndex; /* preparation for next read of match[matchLength] */ + } + + DEBUGLOG(8, "ZSTD_insertDUBT1: comparing %u with %u : found %u common bytes ", + curr, matchIndex, (U32)matchLength); + + if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */ + break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */ + } + + if (match[matchLength] < ip[matchLength]) { /* necessarily within buffer */ + /* match is smaller than current */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop searching */ + DEBUGLOG(8, "ZSTD_insertDUBT1: %u (>btLow=%u) is smaller : next => %u", + matchIndex, btLow, nextPtr[1]); + smallerPtr = nextPtr+1; /* new "candidate" => larger than match, which was smaller than target */ + matchIndex = nextPtr[1]; /* new matchIndex, larger than previous and closer to current */ + } else { + /* match is larger than current */ + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop searching */ + DEBUGLOG(8, "ZSTD_insertDUBT1: %u (>btLow=%u) is larger => %u", + matchIndex, btLow, nextPtr[0]); + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } } + + *smallerPtr = *largerPtr = 0; +} + + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_DUBT_findBetterDictMatch ( + const ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + size_t* offsetPtr, + size_t bestLength, + U32 nbCompares, + U32 const mls, + const ZSTD_dictMode_e dictMode) +{ + const ZSTD_MatchState_t * const dms = ms->dictMatchState; + const ZSTD_compressionParameters* const dmsCParams = &dms->cParams; + const U32 * const dictHashTable = dms->hashTable; + U32 const hashLog = dmsCParams->hashLog; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32 dictMatchIndex = dictHashTable[h]; + + const BYTE* const base = ms->window.base; + const BYTE* const prefixStart = base + ms->window.dictLimit; + U32 const curr = (U32)(ip-base); + const BYTE* const dictBase = dms->window.base; + const BYTE* const dictEnd = dms->window.nextSrc; + U32 const dictHighLimit = (U32)(dms->window.nextSrc - dms->window.base); + U32 const dictLowLimit = dms->window.lowLimit; + U32 const dictIndexDelta = ms->window.lowLimit - dictHighLimit; + + U32* const dictBt = dms->chainTable; + U32 const btLog = dmsCParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + U32 const btLow = (btMask >= dictHighLimit - dictLowLimit) ? dictLowLimit : dictHighLimit - btMask; + + size_t commonLengthSmaller=0, commonLengthLarger=0; + + (void)dictMode; + assert(dictMode == ZSTD_dictMatchState); + + for (; nbCompares && (dictMatchIndex > dictLowLimit); --nbCompares) { + U32* const nextPtr = dictBt + 2*(dictMatchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + const BYTE* match = dictBase + dictMatchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); + if (dictMatchIndex+matchLength >= dictHighLimit) + match = base + dictMatchIndex + dictIndexDelta; /* to prepare for next usage of match[matchLength] */ + + if (matchLength > bestLength) { + U32 matchIndex = dictMatchIndex + dictIndexDelta; + if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) { + DEBUGLOG(9, "ZSTD_DUBT_findBetterDictMatch(%u) : found better match length %u -> %u and offsetCode %u -> %u (dictMatchIndex %u, matchIndex %u)", + curr, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, OFFSET_TO_OFFBASE(curr - matchIndex), dictMatchIndex, matchIndex); + bestLength = matchLength, *offsetPtr = OFFSET_TO_OFFBASE(curr - matchIndex); + } + if (ip+matchLength == iend) { /* reached end of input : ip[matchLength] is not valid, no way to know if it's larger or smaller than match */ + break; /* drop, to guarantee consistency (miss a little bit of compression) */ + } + } + + if (match[matchLength] < ip[matchLength]) { + if (dictMatchIndex <= btLow) { break; } /* beyond tree size, stop the search */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + dictMatchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + } else { + /* match is larger than current */ + if (dictMatchIndex <= btLow) { break; } /* beyond tree size, stop the search */ + commonLengthLarger = matchLength; + dictMatchIndex = nextPtr[0]; + } + } + + if (bestLength >= MINMATCH) { + U32 const mIndex = curr - (U32)OFFBASE_TO_OFFSET(*offsetPtr); (void)mIndex; + DEBUGLOG(8, "ZSTD_DUBT_findBetterDictMatch(%u) : found match of length %u and offsetCode %u (pos %u)", + curr, (U32)bestLength, (U32)*offsetPtr, mIndex); + } + return bestLength; + +} + + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_DUBT_findBestMatch(ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + size_t* offBasePtr, + U32 const mls, + const ZSTD_dictMode_e dictMode) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hashLog = cParams->hashLog; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32 matchIndex = hashTable[h]; + + const BYTE* const base = ms->window.base; + U32 const curr = (U32)(ip-base); + U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog); + + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + U32 const btLow = (btMask >= curr) ? 0 : curr - btMask; + U32 const unsortLimit = MAX(btLow, windowLow); + + U32* nextCandidate = bt + 2*(matchIndex&btMask); + U32* unsortedMark = bt + 2*(matchIndex&btMask) + 1; + U32 nbCompares = 1U << cParams->searchLog; + U32 nbCandidates = nbCompares; + U32 previousCandidate = 0; + + DEBUGLOG(7, "ZSTD_DUBT_findBestMatch (%u) ", curr); + assert(ip <= iend-8); /* required for h calculation */ + assert(dictMode != ZSTD_dedicatedDictSearch); + + /* reach end of unsorted candidates list */ + while ( (matchIndex > unsortLimit) + && (*unsortedMark == ZSTD_DUBT_UNSORTED_MARK) + && (nbCandidates > 1) ) { + DEBUGLOG(8, "ZSTD_DUBT_findBestMatch: candidate %u is unsorted", + matchIndex); + *unsortedMark = previousCandidate; /* the unsortedMark becomes a reversed chain, to move up back to original position */ + previousCandidate = matchIndex; + matchIndex = *nextCandidate; + nextCandidate = bt + 2*(matchIndex&btMask); + unsortedMark = bt + 2*(matchIndex&btMask) + 1; + nbCandidates --; + } + + /* nullify last candidate if it's still unsorted + * simplification, detrimental to compression ratio, beneficial for speed */ + if ( (matchIndex > unsortLimit) + && (*unsortedMark==ZSTD_DUBT_UNSORTED_MARK) ) { + DEBUGLOG(7, "ZSTD_DUBT_findBestMatch: nullify last unsorted candidate %u", + matchIndex); + *nextCandidate = *unsortedMark = 0; + } + + /* batch sort stacked candidates */ + matchIndex = previousCandidate; + while (matchIndex) { /* will end on matchIndex == 0 */ + U32* const nextCandidateIdxPtr = bt + 2*(matchIndex&btMask) + 1; + U32 const nextCandidateIdx = *nextCandidateIdxPtr; + ZSTD_insertDUBT1(ms, matchIndex, iend, + nbCandidates, unsortLimit, dictMode); + matchIndex = nextCandidateIdx; + nbCandidates++; + } + + /* find longest match */ + { size_t commonLengthSmaller = 0, commonLengthLarger = 0; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const prefixStart = base + dictLimit; + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = bt + 2*(curr&btMask) + 1; + U32 matchEndIdx = curr + 8 + 1; + U32 dummy32; /* to be nullified at the end */ + size_t bestLength = 0; + + matchIndex = hashTable[h]; + hashTable[h] = curr; /* Update Hash Table */ + + for (; nbCompares && (matchIndex > windowLow); --nbCompares) { + U32* const nextPtr = bt + 2*(matchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + const BYTE* match; + + if ((dictMode != ZSTD_extDict) || (matchIndex+matchLength >= dictLimit)) { + match = base + matchIndex; + matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend); + } else { + match = dictBase + matchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); + if (matchIndex+matchLength >= dictLimit) + match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ + } + + if (matchLength > bestLength) { + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr - matchIndex + 1) - ZSTD_highbit32((U32)*offBasePtr)) ) + bestLength = matchLength, *offBasePtr = OFFSET_TO_OFFBASE(curr - matchIndex); + if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */ + if (dictMode == ZSTD_dictMatchState) { + nbCompares = 0; /* in addition to avoiding checking any + * further in this loop, make sure we + * skip checking in the dictionary. */ + } + break; /* drop, to guarantee consistency (miss a little bit of compression) */ + } + } + + if (match[matchLength] < ip[matchLength]) { + /* match is smaller than current */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + smallerPtr = nextPtr+1; /* new "smaller" => larger of match */ + matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + } else { + /* match is larger than current */ + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } } + + *smallerPtr = *largerPtr = 0; + + assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ + if (dictMode == ZSTD_dictMatchState && nbCompares) { + bestLength = ZSTD_DUBT_findBetterDictMatch( + ms, ip, iend, + offBasePtr, bestLength, nbCompares, + mls, dictMode); + } + + assert(matchEndIdx > curr+8); /* ensure nextToUpdate is increased */ + ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */ + if (bestLength >= MINMATCH) { + U32 const mIndex = curr - (U32)OFFBASE_TO_OFFSET(*offBasePtr); (void)mIndex; + DEBUGLOG(8, "ZSTD_DUBT_findBestMatch(%u) : found match of length %u and offsetCode %u (pos %u)", + curr, (U32)bestLength, (U32)*offBasePtr, mIndex); + } + return bestLength; + } +} + + +/** ZSTD_BtFindBestMatch() : Tree updater, providing best match */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_BtFindBestMatch( ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iLimit, + size_t* offBasePtr, + const U32 mls /* template */, + const ZSTD_dictMode_e dictMode) +{ + DEBUGLOG(7, "ZSTD_BtFindBestMatch"); + if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */ + ZSTD_updateDUBT(ms, ip, iLimit, mls); + return ZSTD_DUBT_findBestMatch(ms, ip, iLimit, offBasePtr, mls, dictMode); +} + +/*********************************** +* Dedicated dict search +***********************************/ + +void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_MatchState_t* ms, const BYTE* const ip) +{ + const BYTE* const base = ms->window.base; + U32 const target = (U32)(ip - base); + U32* const hashTable = ms->hashTable; + U32* const chainTable = ms->chainTable; + U32 const chainSize = 1 << ms->cParams.chainLog; + U32 idx = ms->nextToUpdate; + U32 const minChain = chainSize < target - idx ? target - chainSize : idx; + U32 const bucketSize = 1 << ZSTD_LAZY_DDSS_BUCKET_LOG; + U32 const cacheSize = bucketSize - 1; + U32 const chainAttempts = (1 << ms->cParams.searchLog) - cacheSize; + U32 const chainLimit = chainAttempts > 255 ? 255 : chainAttempts; + + /* We know the hashtable is oversized by a factor of `bucketSize`. + * We are going to temporarily pretend `bucketSize == 1`, keeping only a + * single entry. We will use the rest of the space to construct a temporary + * chaintable. + */ + U32 const hashLog = ms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG; + U32* const tmpHashTable = hashTable; + U32* const tmpChainTable = hashTable + ((size_t)1 << hashLog); + U32 const tmpChainSize = (U32)((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog; + U32 const tmpMinChain = tmpChainSize < target ? target - tmpChainSize : idx; + U32 hashIdx; + + assert(ms->cParams.chainLog <= 24); + assert(ms->cParams.hashLog > ms->cParams.chainLog); + assert(idx != 0); + assert(tmpMinChain <= minChain); + + /* fill conventional hash table and conventional chain table */ + for ( ; idx < target; idx++) { + U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch); + if (idx >= tmpMinChain) { + tmpChainTable[idx - tmpMinChain] = hashTable[h]; + } + tmpHashTable[h] = idx; + } + + /* sort chains into ddss chain table */ + { + U32 chainPos = 0; + for (hashIdx = 0; hashIdx < (1U << hashLog); hashIdx++) { + U32 count; + U32 countBeyondMinChain = 0; + U32 i = tmpHashTable[hashIdx]; + for (count = 0; i >= tmpMinChain && count < cacheSize; count++) { + /* skip through the chain to the first position that won't be + * in the hash cache bucket */ + if (i < minChain) { + countBeyondMinChain++; + } + i = tmpChainTable[i - tmpMinChain]; + } + if (count == cacheSize) { + for (count = 0; count < chainLimit;) { + if (i < minChain) { + if (!i || ++countBeyondMinChain > cacheSize) { + /* only allow pulling `cacheSize` number of entries + * into the cache or chainTable beyond `minChain`, + * to replace the entries pulled out of the + * chainTable into the cache. This lets us reach + * back further without increasing the total number + * of entries in the chainTable, guaranteeing the + * DDSS chain table will fit into the space + * allocated for the regular one. */ + break; + } + } + chainTable[chainPos++] = i; + count++; + if (i < tmpMinChain) { + break; + } + i = tmpChainTable[i - tmpMinChain]; + } + } else { + count = 0; + } + if (count) { + tmpHashTable[hashIdx] = ((chainPos - count) << 8) + count; + } else { + tmpHashTable[hashIdx] = 0; + } + } + assert(chainPos <= chainSize); /* I believe this is guaranteed... */ + } + + /* move chain pointers into the last entry of each hash bucket */ + for (hashIdx = (1 << hashLog); hashIdx; ) { + U32 const bucketIdx = --hashIdx << ZSTD_LAZY_DDSS_BUCKET_LOG; + U32 const chainPackedPointer = tmpHashTable[hashIdx]; + U32 i; + for (i = 0; i < cacheSize; i++) { + hashTable[bucketIdx + i] = 0; + } + hashTable[bucketIdx + bucketSize - 1] = chainPackedPointer; + } + + /* fill the buckets of the hash table */ + for (idx = ms->nextToUpdate; idx < target; idx++) { + U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch) + << ZSTD_LAZY_DDSS_BUCKET_LOG; + U32 i; + /* Shift hash cache down 1. */ + for (i = cacheSize - 1; i; i--) + hashTable[h + i] = hashTable[h + i - 1]; + hashTable[h] = idx; + } + + ms->nextToUpdate = target; +} + +/* Returns the longest match length found in the dedicated dict search structure. + * If none are longer than the argument ml, then ml will be returned. + */ +FORCE_INLINE_TEMPLATE +size_t ZSTD_dedicatedDictSearch_lazy_search(size_t* offsetPtr, size_t ml, U32 nbAttempts, + const ZSTD_MatchState_t* const dms, + const BYTE* const ip, const BYTE* const iLimit, + const BYTE* const prefixStart, const U32 curr, + const U32 dictLimit, const size_t ddsIdx) { + const U32 ddsLowestIndex = dms->window.dictLimit; + const BYTE* const ddsBase = dms->window.base; + const BYTE* const ddsEnd = dms->window.nextSrc; + const U32 ddsSize = (U32)(ddsEnd - ddsBase); + const U32 ddsIndexDelta = dictLimit - ddsSize; + const U32 bucketSize = (1 << ZSTD_LAZY_DDSS_BUCKET_LOG); + const U32 bucketLimit = nbAttempts < bucketSize - 1 ? nbAttempts : bucketSize - 1; + U32 ddsAttempt; + U32 matchIndex; + + for (ddsAttempt = 0; ddsAttempt < bucketSize - 1; ddsAttempt++) { + PREFETCH_L1(ddsBase + dms->hashTable[ddsIdx + ddsAttempt]); + } + + { + U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1]; + U32 const chainIndex = chainPackedPointer >> 8; + + PREFETCH_L1(&dms->chainTable[chainIndex]); + } + + for (ddsAttempt = 0; ddsAttempt < bucketLimit; ddsAttempt++) { + size_t currentMl=0; + const BYTE* match; + matchIndex = dms->hashTable[ddsIdx + ddsAttempt]; + match = ddsBase + matchIndex; + + if (!matchIndex) { + return ml; + } + + /* guaranteed by table construction */ + (void)ddsLowestIndex; + assert(matchIndex >= ddsLowestIndex); + assert(match+4 <= ddsEnd); + if (MEM_read32(match) == MEM_read32(ip)) { + /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4; + } + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + ddsIndexDelta)); + if (ip+currentMl == iLimit) { + /* best possible, avoids read overflow on next attempt */ + return ml; + } + } + } + + { + U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1]; + U32 chainIndex = chainPackedPointer >> 8; + U32 const chainLength = chainPackedPointer & 0xFF; + U32 const chainAttempts = nbAttempts - ddsAttempt; + U32 const chainLimit = chainAttempts > chainLength ? chainLength : chainAttempts; + U32 chainAttempt; + + for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++) { + PREFETCH_L1(ddsBase + dms->chainTable[chainIndex + chainAttempt]); + } + + for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++, chainIndex++) { + size_t currentMl=0; + const BYTE* match; + matchIndex = dms->chainTable[chainIndex]; + match = ddsBase + matchIndex; + + /* guaranteed by table construction */ + assert(matchIndex >= ddsLowestIndex); + assert(match+4 <= ddsEnd); + if (MEM_read32(match) == MEM_read32(ip)) { + /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4; + } + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + ddsIndexDelta)); + if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ + } + } + } + return ml; +} + + +/* ********************************* +* Hash Chain +***********************************/ +#define NEXT_IN_CHAIN(d, mask) chainTable[(d) & (mask)] + +/* Update chains up to ip (excluded) + Assumption : always within prefix (i.e. not within extDict) */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_insertAndFindFirstIndex_internal( + ZSTD_MatchState_t* ms, + const ZSTD_compressionParameters* const cParams, + const BYTE* ip, U32 const mls, U32 const lazySkipping) +{ + U32* const hashTable = ms->hashTable; + const U32 hashLog = cParams->hashLog; + U32* const chainTable = ms->chainTable; + const U32 chainMask = (1 << cParams->chainLog) - 1; + const BYTE* const base = ms->window.base; + const U32 target = (U32)(ip - base); + U32 idx = ms->nextToUpdate; + + while(idx < target) { /* catch up */ + size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls); + NEXT_IN_CHAIN(idx, chainMask) = hashTable[h]; + hashTable[h] = idx; + idx++; + /* Stop inserting every position when in the lazy skipping mode. */ + if (lazySkipping) + break; + } + + ms->nextToUpdate = target; + return hashTable[ZSTD_hashPtr(ip, hashLog, mls)]; +} + +U32 ZSTD_insertAndFindFirstIndex(ZSTD_MatchState_t* ms, const BYTE* ip) { + const ZSTD_compressionParameters* const cParams = &ms->cParams; + return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch, /* lazySkipping*/ 0); +} + +/* inlining is important to hardwire a hot branch (template emulation) */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_HcFindBestMatch( + ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iLimit, + size_t* offsetPtr, + const U32 mls, const ZSTD_dictMode_e dictMode) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const chainTable = ms->chainTable; + const U32 chainSize = (1 << cParams->chainLog); + const U32 chainMask = chainSize-1; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const U32 curr = (U32)(ip-base); + const U32 maxDistance = 1U << cParams->windowLog; + const U32 lowestValid = ms->window.lowLimit; + const U32 withinMaxDistance = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; + const U32 isDictionary = (ms->loadedDictEnd != 0); + const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance; + const U32 minChain = curr > chainSize ? curr - chainSize : 0; + U32 nbAttempts = 1U << cParams->searchLog; + size_t ml=4-1; + + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + const U32 ddsHashLog = dictMode == ZSTD_dedicatedDictSearch + ? dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG : 0; + const size_t ddsIdx = dictMode == ZSTD_dedicatedDictSearch + ? ZSTD_hashPtr(ip, ddsHashLog, mls) << ZSTD_LAZY_DDSS_BUCKET_LOG : 0; + + U32 matchIndex; + + if (dictMode == ZSTD_dedicatedDictSearch) { + const U32* entry = &dms->hashTable[ddsIdx]; + PREFETCH_L1(entry); + } + + /* HC4 match finder */ + matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls, ms->lazySkipping); + + for ( ; (matchIndex>=lowLimit) & (nbAttempts>0) ; nbAttempts--) { + size_t currentMl=0; + if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) { + const BYTE* const match = base + matchIndex; + assert(matchIndex >= dictLimit); /* ensures this is true if dictMode != ZSTD_extDict */ + /* read 4B starting from (match + ml + 1 - sizeof(U32)) */ + if (MEM_read32(match + ml - 3) == MEM_read32(ip + ml - 3)) /* potentially better */ + currentMl = ZSTD_count(ip, match, iLimit); + } else { + const BYTE* const match = dictBase + matchIndex; + assert(match+4 <= dictEnd); + if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4; + } + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = OFFSET_TO_OFFBASE(curr - matchIndex); + if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ + } + + if (matchIndex <= minChain) break; + matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask); + } + + assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ + if (dictMode == ZSTD_dedicatedDictSearch) { + ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts, dms, + ip, iLimit, prefixStart, curr, dictLimit, ddsIdx); + } else if (dictMode == ZSTD_dictMatchState) { + const U32* const dmsChainTable = dms->chainTable; + const U32 dmsChainSize = (1 << dms->cParams.chainLog); + const U32 dmsChainMask = dmsChainSize - 1; + const U32 dmsLowestIndex = dms->window.dictLimit; + const BYTE* const dmsBase = dms->window.base; + const BYTE* const dmsEnd = dms->window.nextSrc; + const U32 dmsSize = (U32)(dmsEnd - dmsBase); + const U32 dmsIndexDelta = dictLimit - dmsSize; + const U32 dmsMinChain = dmsSize > dmsChainSize ? dmsSize - dmsChainSize : 0; + + matchIndex = dms->hashTable[ZSTD_hashPtr(ip, dms->cParams.hashLog, mls)]; + + for ( ; (matchIndex>=dmsLowestIndex) & (nbAttempts>0) ; nbAttempts--) { + size_t currentMl=0; + const BYTE* const match = dmsBase + matchIndex; + assert(match+4 <= dmsEnd); + if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dmsEnd, prefixStart) + 4; + + /* save best solution */ + if (currentMl > ml) { + ml = currentMl; + assert(curr > matchIndex + dmsIndexDelta); + *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + dmsIndexDelta)); + if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ + } + + if (matchIndex <= dmsMinChain) break; + + matchIndex = dmsChainTable[matchIndex & dmsChainMask]; + } + } + + return ml; +} + +/* ********************************* +* (SIMD) Row-based matchfinder +***********************************/ +/* Constants for row-based hash */ +#define ZSTD_ROW_HASH_TAG_MASK ((1u << ZSTD_ROW_HASH_TAG_BITS) - 1) +#define ZSTD_ROW_HASH_MAX_ENTRIES 64 /* absolute maximum number of entries per row, for all configurations */ + +#define ZSTD_ROW_HASH_CACHE_MASK (ZSTD_ROW_HASH_CACHE_SIZE - 1) + +typedef U64 ZSTD_VecMask; /* Clarifies when we are interacting with a U64 representing a mask of matches */ + +/* ZSTD_VecMask_next(): + * Starting from the LSB, returns the idx of the next non-zero bit. + * Basically counting the nb of trailing zeroes. + */ +MEM_STATIC U32 ZSTD_VecMask_next(ZSTD_VecMask val) { + return ZSTD_countTrailingZeros64(val); +} + +/* ZSTD_row_nextIndex(): + * Returns the next index to insert at within a tagTable row, and updates the "head" + * value to reflect the update. Essentially cycles backwards from [1, {entries per row}) + */ +FORCE_INLINE_TEMPLATE U32 ZSTD_row_nextIndex(BYTE* const tagRow, U32 const rowMask) { + U32 next = (*tagRow-1) & rowMask; + next += (next == 0) ? rowMask : 0; /* skip first position */ + *tagRow = (BYTE)next; + return next; +} + +/* ZSTD_isAligned(): + * Checks that a pointer is aligned to "align" bytes which must be a power of 2. + */ +MEM_STATIC int ZSTD_isAligned(void const* ptr, size_t align) { + assert((align & (align - 1)) == 0); + return (((size_t)ptr) & (align - 1)) == 0; +} + +/* ZSTD_row_prefetch(): + * Performs prefetching for the hashTable and tagTable at a given row. + */ +FORCE_INLINE_TEMPLATE void ZSTD_row_prefetch(U32 const* hashTable, BYTE const* tagTable, U32 const relRow, U32 const rowLog) { + PREFETCH_L1(hashTable + relRow); + if (rowLog >= 5) { + PREFETCH_L1(hashTable + relRow + 16); + /* Note: prefetching more of the hash table does not appear to be beneficial for 128-entry rows */ + } + PREFETCH_L1(tagTable + relRow); + if (rowLog == 6) { + PREFETCH_L1(tagTable + relRow + 32); + } + assert(rowLog == 4 || rowLog == 5 || rowLog == 6); + assert(ZSTD_isAligned(hashTable + relRow, 64)); /* prefetched hash row always 64-byte aligned */ + assert(ZSTD_isAligned(tagTable + relRow, (size_t)1 << rowLog)); /* prefetched tagRow sits on correct multiple of bytes (32,64,128) */ +} + +/* ZSTD_row_fillHashCache(): + * Fill up the hash cache starting at idx, prefetching up to ZSTD_ROW_HASH_CACHE_SIZE entries, + * but not beyond iLimit. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_row_fillHashCache(ZSTD_MatchState_t* ms, const BYTE* base, + U32 const rowLog, U32 const mls, + U32 idx, const BYTE* const iLimit) +{ + U32 const* const hashTable = ms->hashTable; + BYTE const* const tagTable = ms->tagTable; + U32 const hashLog = ms->rowHashLog; + U32 const maxElemsToPrefetch = (base + idx) > iLimit ? 0 : (U32)(iLimit - (base + idx) + 1); + U32 const lim = idx + MIN(ZSTD_ROW_HASH_CACHE_SIZE, maxElemsToPrefetch); + + for (; idx < lim; ++idx) { + U32 const hash = (U32)ZSTD_hashPtrSalted(base + idx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt); + U32 const row = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + ZSTD_row_prefetch(hashTable, tagTable, row, rowLog); + ms->hashCache[idx & ZSTD_ROW_HASH_CACHE_MASK] = hash; + } + + DEBUGLOG(6, "ZSTD_row_fillHashCache(): [%u %u %u %u %u %u %u %u]", ms->hashCache[0], ms->hashCache[1], + ms->hashCache[2], ms->hashCache[3], ms->hashCache[4], + ms->hashCache[5], ms->hashCache[6], ms->hashCache[7]); +} + +/* ZSTD_row_nextCachedHash(): + * Returns the hash of base + idx, and replaces the hash in the hash cache with the byte at + * base + idx + ZSTD_ROW_HASH_CACHE_SIZE. Also prefetches the appropriate rows from hashTable and tagTable. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_row_nextCachedHash(U32* cache, U32 const* hashTable, + BYTE const* tagTable, BYTE const* base, + U32 idx, U32 const hashLog, + U32 const rowLog, U32 const mls, + U64 const hashSalt) +{ + U32 const newHash = (U32)ZSTD_hashPtrSalted(base+idx+ZSTD_ROW_HASH_CACHE_SIZE, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, hashSalt); + U32 const row = (newHash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + ZSTD_row_prefetch(hashTable, tagTable, row, rowLog); + { U32 const hash = cache[idx & ZSTD_ROW_HASH_CACHE_MASK]; + cache[idx & ZSTD_ROW_HASH_CACHE_MASK] = newHash; + return hash; + } +} + +/* ZSTD_row_update_internalImpl(): + * Updates the hash table with positions starting from updateStartIdx until updateEndIdx. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_row_update_internalImpl(ZSTD_MatchState_t* ms, + U32 updateStartIdx, U32 const updateEndIdx, + U32 const mls, U32 const rowLog, + U32 const rowMask, U32 const useCache) +{ + U32* const hashTable = ms->hashTable; + BYTE* const tagTable = ms->tagTable; + U32 const hashLog = ms->rowHashLog; + const BYTE* const base = ms->window.base; + + DEBUGLOG(6, "ZSTD_row_update_internalImpl(): updateStartIdx=%u, updateEndIdx=%u", updateStartIdx, updateEndIdx); + for (; updateStartIdx < updateEndIdx; ++updateStartIdx) { + U32 const hash = useCache ? ZSTD_row_nextCachedHash(ms->hashCache, hashTable, tagTable, base, updateStartIdx, hashLog, rowLog, mls, ms->hashSalt) + : (U32)ZSTD_hashPtrSalted(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt); + U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + U32* const row = hashTable + relRow; + BYTE* tagRow = tagTable + relRow; + U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask); + + assert(hash == ZSTD_hashPtrSalted(base + updateStartIdx, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, ms->hashSalt)); + tagRow[pos] = hash & ZSTD_ROW_HASH_TAG_MASK; + row[pos] = updateStartIdx; + } +} + +/* ZSTD_row_update_internal(): + * Inserts the byte at ip into the appropriate position in the hash table, and updates ms->nextToUpdate. + * Skips sections of long matches as is necessary. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_row_update_internal(ZSTD_MatchState_t* ms, const BYTE* ip, + U32 const mls, U32 const rowLog, + U32 const rowMask, U32 const useCache) +{ + U32 idx = ms->nextToUpdate; + const BYTE* const base = ms->window.base; + const U32 target = (U32)(ip - base); + const U32 kSkipThreshold = 384; + const U32 kMaxMatchStartPositionsToUpdate = 96; + const U32 kMaxMatchEndPositionsToUpdate = 32; + + if (useCache) { + /* Only skip positions when using hash cache, i.e. + * if we are loading a dict, don't skip anything. + * If we decide to skip, then we only update a set number + * of positions at the beginning and end of the match. + */ + if (UNLIKELY(target - idx > kSkipThreshold)) { + U32 const bound = idx + kMaxMatchStartPositionsToUpdate; + ZSTD_row_update_internalImpl(ms, idx, bound, mls, rowLog, rowMask, useCache); + idx = target - kMaxMatchEndPositionsToUpdate; + ZSTD_row_fillHashCache(ms, base, rowLog, mls, idx, ip+1); + } + } + assert(target >= idx); + ZSTD_row_update_internalImpl(ms, idx, target, mls, rowLog, rowMask, useCache); + ms->nextToUpdate = target; +} + +/* ZSTD_row_update(): + * External wrapper for ZSTD_row_update_internal(). Used for filling the hashtable during dictionary + * processing. + */ +void ZSTD_row_update(ZSTD_MatchState_t* const ms, const BYTE* ip) { + const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6); + const U32 rowMask = (1u << rowLog) - 1; + const U32 mls = MIN(ms->cParams.minMatch, 6 /* mls caps out at 6 */); + + DEBUGLOG(5, "ZSTD_row_update(), rowLog=%u", rowLog); + ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 0 /* don't use cache */); +} + +/* Returns the mask width of bits group of which will be set to 1. Given not all + * architectures have easy movemask instruction, this helps to iterate over + * groups of bits easier and faster. + */ +FORCE_INLINE_TEMPLATE U32 +ZSTD_row_matchMaskGroupWidth(const U32 rowEntries) +{ + assert((rowEntries == 16) || (rowEntries == 32) || rowEntries == 64); + assert(rowEntries <= ZSTD_ROW_HASH_MAX_ENTRIES); + (void)rowEntries; +#if defined(ZSTD_ARCH_ARM_NEON) + /* NEON path only works for little endian */ + if (!MEM_isLittleEndian()) { + return 1; + } + if (rowEntries == 16) { + return 4; + } + if (rowEntries == 32) { + return 2; + } + if (rowEntries == 64) { + return 1; + } +#endif + return 1; +} + +#if defined(ZSTD_ARCH_X86_SSE2) +FORCE_INLINE_TEMPLATE ZSTD_VecMask +ZSTD_row_getSSEMask(int nbChunks, const BYTE* const src, const BYTE tag, const U32 head) +{ + const __m128i comparisonMask = _mm_set1_epi8((char)tag); + int matches[4] = {0}; + int i; + assert(nbChunks == 1 || nbChunks == 2 || nbChunks == 4); + for (i=0; i> chunkSize; + do { + size_t chunk = MEM_readST(&src[i]); + chunk ^= splatChar; + chunk = (((chunk | x80) - x01) | chunk) & x80; + matches <<= chunkSize; + matches |= (chunk * extractMagic) >> shiftAmount; + i -= chunkSize; + } while (i >= 0); + } else { /* big endian: reverse bits during extraction */ + const size_t msb = xFF ^ (xFF >> 1); + const size_t extractMagic = (msb / 0x1FF) | msb; + do { + size_t chunk = MEM_readST(&src[i]); + chunk ^= splatChar; + chunk = (((chunk | x80) - x01) | chunk) & x80; + matches <<= chunkSize; + matches |= ((chunk >> 7) * extractMagic) >> shiftAmount; + i -= chunkSize; + } while (i >= 0); + } + matches = ~matches; + if (rowEntries == 16) { + return ZSTD_rotateRight_U16((U16)matches, headGrouped); + } else if (rowEntries == 32) { + return ZSTD_rotateRight_U32((U32)matches, headGrouped); + } else { + return ZSTD_rotateRight_U64((U64)matches, headGrouped); + } + } +#endif +} + +/* The high-level approach of the SIMD row based match finder is as follows: + * - Figure out where to insert the new entry: + * - Generate a hash for current input position and split it into a one byte of tag and `rowHashLog` bits of index. + * - The hash is salted by a value that changes on every context reset, so when the same table is used + * we will avoid collisions that would otherwise slow us down by introducing phantom matches. + * - The hashTable is effectively split into groups or "rows" of 15 or 31 entries of U32, and the index determines + * which row to insert into. + * - Determine the correct position within the row to insert the entry into. Each row of 15 or 31 can + * be considered as a circular buffer with a "head" index that resides in the tagTable (overall 16 or 32 bytes + * per row). + * - Use SIMD to efficiently compare the tags in the tagTable to the 1-byte tag calculated for the position and + * generate a bitfield that we can cycle through to check the collisions in the hash table. + * - Pick the longest match. + * - Insert the tag into the equivalent row and position in the tagTable. + */ +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_RowFindBestMatch( + ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iLimit, + size_t* offsetPtr, + const U32 mls, const ZSTD_dictMode_e dictMode, + const U32 rowLog) +{ + U32* const hashTable = ms->hashTable; + BYTE* const tagTable = ms->tagTable; + U32* const hashCache = ms->hashCache; + const U32 hashLog = ms->rowHashLog; + const ZSTD_compressionParameters* const cParams = &ms->cParams; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const U32 curr = (U32)(ip-base); + const U32 maxDistance = 1U << cParams->windowLog; + const U32 lowestValid = ms->window.lowLimit; + const U32 withinMaxDistance = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid; + const U32 isDictionary = (ms->loadedDictEnd != 0); + const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance; + const U32 rowEntries = (1U << rowLog); + const U32 rowMask = rowEntries - 1; + const U32 cappedSearchLog = MIN(cParams->searchLog, rowLog); /* nb of searches is capped at nb entries per row */ + const U32 groupWidth = ZSTD_row_matchMaskGroupWidth(rowEntries); + const U64 hashSalt = ms->hashSalt; + U32 nbAttempts = 1U << cappedSearchLog; + size_t ml=4-1; + U32 hash; + + /* DMS/DDS variables that may be referenced laster */ + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + + /* Initialize the following variables to satisfy static analyzer */ + size_t ddsIdx = 0; + U32 ddsExtraAttempts = 0; /* cctx hash tables are limited in searches, but allow extra searches into DDS */ + U32 dmsTag = 0; + U32* dmsRow = NULL; + BYTE* dmsTagRow = NULL; + + if (dictMode == ZSTD_dedicatedDictSearch) { + const U32 ddsHashLog = dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG; + { /* Prefetch DDS hashtable entry */ + ddsIdx = ZSTD_hashPtr(ip, ddsHashLog, mls) << ZSTD_LAZY_DDSS_BUCKET_LOG; + PREFETCH_L1(&dms->hashTable[ddsIdx]); + } + ddsExtraAttempts = cParams->searchLog > rowLog ? 1U << (cParams->searchLog - rowLog) : 0; + } + + if (dictMode == ZSTD_dictMatchState) { + /* Prefetch DMS rows */ + U32* const dmsHashTable = dms->hashTable; + BYTE* const dmsTagTable = dms->tagTable; + U32 const dmsHash = (U32)ZSTD_hashPtr(ip, dms->rowHashLog + ZSTD_ROW_HASH_TAG_BITS, mls); + U32 const dmsRelRow = (dmsHash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + dmsTag = dmsHash & ZSTD_ROW_HASH_TAG_MASK; + dmsTagRow = (BYTE*)(dmsTagTable + dmsRelRow); + dmsRow = dmsHashTable + dmsRelRow; + ZSTD_row_prefetch(dmsHashTable, dmsTagTable, dmsRelRow, rowLog); + } + + /* Update the hashTable and tagTable up to (but not including) ip */ + if (!ms->lazySkipping) { + ZSTD_row_update_internal(ms, ip, mls, rowLog, rowMask, 1 /* useCache */); + hash = ZSTD_row_nextCachedHash(hashCache, hashTable, tagTable, base, curr, hashLog, rowLog, mls, hashSalt); + } else { + /* Stop inserting every position when in the lazy skipping mode. + * The hash cache is also not kept up to date in this mode. + */ + hash = (U32)ZSTD_hashPtrSalted(ip, hashLog + ZSTD_ROW_HASH_TAG_BITS, mls, hashSalt); + ms->nextToUpdate = curr; + } + ms->hashSaltEntropy += hash; /* collect salt entropy */ + + { /* Get the hash for ip, compute the appropriate row */ + U32 const relRow = (hash >> ZSTD_ROW_HASH_TAG_BITS) << rowLog; + U32 const tag = hash & ZSTD_ROW_HASH_TAG_MASK; + U32* const row = hashTable + relRow; + BYTE* tagRow = (BYTE*)(tagTable + relRow); + U32 const headGrouped = (*tagRow & rowMask) * groupWidth; + U32 matchBuffer[ZSTD_ROW_HASH_MAX_ENTRIES]; + size_t numMatches = 0; + size_t currMatch = 0; + ZSTD_VecMask matches = ZSTD_row_getMatchMask(tagRow, (BYTE)tag, headGrouped, rowEntries); + + /* Cycle through the matches and prefetch */ + for (; (matches > 0) && (nbAttempts > 0); matches &= (matches - 1)) { + U32 const matchPos = ((headGrouped + ZSTD_VecMask_next(matches)) / groupWidth) & rowMask; + U32 const matchIndex = row[matchPos]; + if(matchPos == 0) continue; + assert(numMatches < rowEntries); + if (matchIndex < lowLimit) + break; + if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) { + PREFETCH_L1(base + matchIndex); + } else { + PREFETCH_L1(dictBase + matchIndex); + } + matchBuffer[numMatches++] = matchIndex; + --nbAttempts; + } + + /* Speed opt: insert current byte into hashtable too. This allows us to avoid one iteration of the loop + in ZSTD_row_update_internal() at the next search. */ + { + U32 const pos = ZSTD_row_nextIndex(tagRow, rowMask); + tagRow[pos] = (BYTE)tag; + row[pos] = ms->nextToUpdate++; + } + + /* Return the longest match */ + for (; currMatch < numMatches; ++currMatch) { + U32 const matchIndex = matchBuffer[currMatch]; + size_t currentMl=0; + assert(matchIndex < curr); + assert(matchIndex >= lowLimit); + + if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) { + const BYTE* const match = base + matchIndex; + assert(matchIndex >= dictLimit); /* ensures this is true if dictMode != ZSTD_extDict */ + /* read 4B starting from (match + ml + 1 - sizeof(U32)) */ + if (MEM_read32(match + ml - 3) == MEM_read32(ip + ml - 3)) /* potentially better */ + currentMl = ZSTD_count(ip, match, iLimit); + } else { + const BYTE* const match = dictBase + matchIndex; + assert(match+4 <= dictEnd); + if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */ + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4; + } + + /* Save best solution */ + if (currentMl > ml) { + ml = currentMl; + *offsetPtr = OFFSET_TO_OFFBASE(curr - matchIndex); + if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */ + } + } + } + + assert(nbAttempts <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ + if (dictMode == ZSTD_dedicatedDictSearch) { + ml = ZSTD_dedicatedDictSearch_lazy_search(offsetPtr, ml, nbAttempts + ddsExtraAttempts, dms, + ip, iLimit, prefixStart, curr, dictLimit, ddsIdx); + } else if (dictMode == ZSTD_dictMatchState) { + /* TODO: Measure and potentially add prefetching to DMS */ + const U32 dmsLowestIndex = dms->window.dictLimit; + const BYTE* const dmsBase = dms->window.base; + const BYTE* const dmsEnd = dms->window.nextSrc; + const U32 dmsSize = (U32)(dmsEnd - dmsBase); + const U32 dmsIndexDelta = dictLimit - dmsSize; + + { U32 const headGrouped = (*dmsTagRow & rowMask) * groupWidth; + U32 matchBuffer[ZSTD_ROW_HASH_MAX_ENTRIES]; + size_t numMatches = 0; + size_t currMatch = 0; + ZSTD_VecMask matches = ZSTD_row_getMatchMask(dmsTagRow, (BYTE)dmsTag, headGrouped, rowEntries); + + for (; (matches > 0) && (nbAttempts > 0); matches &= (matches - 1)) { + U32 const matchPos = ((headGrouped + ZSTD_VecMask_next(matches)) / groupWidth) & rowMask; + U32 const matchIndex = dmsRow[matchPos]; + if(matchPos == 0) continue; + if (matchIndex < dmsLowestIndex) + break; + PREFETCH_L1(dmsBase + matchIndex); + matchBuffer[numMatches++] = matchIndex; + --nbAttempts; + } + + /* Return the longest match */ + for (; currMatch < numMatches; ++currMatch) { + U32 const matchIndex = matchBuffer[currMatch]; + size_t currentMl=0; + assert(matchIndex >= dmsLowestIndex); + assert(matchIndex < curr); + + { const BYTE* const match = dmsBase + matchIndex; + assert(match+4 <= dmsEnd); + if (MEM_read32(match) == MEM_read32(ip)) + currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dmsEnd, prefixStart) + 4; + } + + if (currentMl > ml) { + ml = currentMl; + assert(curr > matchIndex + dmsIndexDelta); + *offsetPtr = OFFSET_TO_OFFBASE(curr - (matchIndex + dmsIndexDelta)); + if (ip+currentMl == iLimit) break; + } + } + } + } + return ml; +} + + +/** + * Generate search functions templated on (dictMode, mls, rowLog). + * These functions are outlined for code size & compilation time. + * ZSTD_searchMax() dispatches to the correct implementation function. + * + * TODO: The start of the search function involves loading and calculating a + * bunch of constants from the ZSTD_MatchState_t. These computations could be + * done in an initialization function, and saved somewhere in the match state. + * Then we could pass a pointer to the saved state instead of the match state, + * and avoid duplicate computations. + * + * TODO: Move the match re-winding into searchMax. This improves compression + * ratio, and unlocks further simplifications with the next TODO. + * + * TODO: Try moving the repcode search into searchMax. After the re-winding + * and repcode search are in searchMax, there is no more logic in the match + * finder loop that requires knowledge about the dictMode. So we should be + * able to avoid force inlining it, and we can join the extDict loop with + * the single segment loop. It should go in searchMax instead of its own + * function to avoid having multiple virtual function calls per search. + */ + +#define ZSTD_BT_SEARCH_FN(dictMode, mls) ZSTD_BtFindBestMatch_##dictMode##_##mls +#define ZSTD_HC_SEARCH_FN(dictMode, mls) ZSTD_HcFindBestMatch_##dictMode##_##mls +#define ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog) ZSTD_RowFindBestMatch_##dictMode##_##mls##_##rowLog + +#define ZSTD_SEARCH_FN_ATTRS FORCE_NOINLINE + +#define GEN_ZSTD_BT_SEARCH_FN(dictMode, mls) \ + ZSTD_SEARCH_FN_ATTRS size_t ZSTD_BT_SEARCH_FN(dictMode, mls)( \ + ZSTD_MatchState_t* ms, \ + const BYTE* ip, const BYTE* const iLimit, \ + size_t* offBasePtr) \ + { \ + assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \ + return ZSTD_BtFindBestMatch(ms, ip, iLimit, offBasePtr, mls, ZSTD_##dictMode); \ + } \ + +#define GEN_ZSTD_HC_SEARCH_FN(dictMode, mls) \ + ZSTD_SEARCH_FN_ATTRS size_t ZSTD_HC_SEARCH_FN(dictMode, mls)( \ + ZSTD_MatchState_t* ms, \ + const BYTE* ip, const BYTE* const iLimit, \ + size_t* offsetPtr) \ + { \ + assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \ + return ZSTD_HcFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode); \ + } \ + +#define GEN_ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog) \ + ZSTD_SEARCH_FN_ATTRS size_t ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog)( \ + ZSTD_MatchState_t* ms, \ + const BYTE* ip, const BYTE* const iLimit, \ + size_t* offsetPtr) \ + { \ + assert(MAX(4, MIN(6, ms->cParams.minMatch)) == mls); \ + assert(MAX(4, MIN(6, ms->cParams.searchLog)) == rowLog); \ + return ZSTD_RowFindBestMatch(ms, ip, iLimit, offsetPtr, mls, ZSTD_##dictMode, rowLog); \ + } \ + +#define ZSTD_FOR_EACH_ROWLOG(X, dictMode, mls) \ + X(dictMode, mls, 4) \ + X(dictMode, mls, 5) \ + X(dictMode, mls, 6) + +#define ZSTD_FOR_EACH_MLS_ROWLOG(X, dictMode) \ + ZSTD_FOR_EACH_ROWLOG(X, dictMode, 4) \ + ZSTD_FOR_EACH_ROWLOG(X, dictMode, 5) \ + ZSTD_FOR_EACH_ROWLOG(X, dictMode, 6) + +#define ZSTD_FOR_EACH_MLS(X, dictMode) \ + X(dictMode, 4) \ + X(dictMode, 5) \ + X(dictMode, 6) + +#define ZSTD_FOR_EACH_DICT_MODE(X, ...) \ + X(__VA_ARGS__, noDict) \ + X(__VA_ARGS__, extDict) \ + X(__VA_ARGS__, dictMatchState) \ + X(__VA_ARGS__, dedicatedDictSearch) + +/* Generate row search fns for each combination of (dictMode, mls, rowLog) */ +ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS_ROWLOG, GEN_ZSTD_ROW_SEARCH_FN) +/* Generate binary Tree search fns for each combination of (dictMode, mls) */ +ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_BT_SEARCH_FN) +/* Generate hash chain search fns for each combination of (dictMode, mls) */ +ZSTD_FOR_EACH_DICT_MODE(ZSTD_FOR_EACH_MLS, GEN_ZSTD_HC_SEARCH_FN) + +typedef enum { search_hashChain=0, search_binaryTree=1, search_rowHash=2 } searchMethod_e; + +#define GEN_ZSTD_CALL_BT_SEARCH_FN(dictMode, mls) \ + case mls: \ + return ZSTD_BT_SEARCH_FN(dictMode, mls)(ms, ip, iend, offsetPtr); +#define GEN_ZSTD_CALL_HC_SEARCH_FN(dictMode, mls) \ + case mls: \ + return ZSTD_HC_SEARCH_FN(dictMode, mls)(ms, ip, iend, offsetPtr); +#define GEN_ZSTD_CALL_ROW_SEARCH_FN(dictMode, mls, rowLog) \ + case rowLog: \ + return ZSTD_ROW_SEARCH_FN(dictMode, mls, rowLog)(ms, ip, iend, offsetPtr); + +#define ZSTD_SWITCH_MLS(X, dictMode) \ + switch (mls) { \ + ZSTD_FOR_EACH_MLS(X, dictMode) \ + } + +#define ZSTD_SWITCH_ROWLOG(dictMode, mls) \ + case mls: \ + switch (rowLog) { \ + ZSTD_FOR_EACH_ROWLOG(GEN_ZSTD_CALL_ROW_SEARCH_FN, dictMode, mls) \ + } \ + ZSTD_UNREACHABLE; \ + break; + +#define ZSTD_SWITCH_SEARCH_METHOD(dictMode) \ + switch (searchMethod) { \ + case search_hashChain: \ + ZSTD_SWITCH_MLS(GEN_ZSTD_CALL_HC_SEARCH_FN, dictMode) \ + break; \ + case search_binaryTree: \ + ZSTD_SWITCH_MLS(GEN_ZSTD_CALL_BT_SEARCH_FN, dictMode) \ + break; \ + case search_rowHash: \ + ZSTD_SWITCH_MLS(ZSTD_SWITCH_ROWLOG, dictMode) \ + break; \ + } \ + ZSTD_UNREACHABLE; + +/** + * Searches for the longest match at @p ip. + * Dispatches to the correct implementation function based on the + * (searchMethod, dictMode, mls, rowLog). We use switch statements + * here instead of using an indirect function call through a function + * pointer because after Spectre and Meltdown mitigations, indirect + * function calls can be very costly, especially in the kernel. + * + * NOTE: dictMode and searchMethod should be templated, so those switch + * statements should be optimized out. Only the mls & rowLog switches + * should be left. + * + * @param ms The match state. + * @param ip The position to search at. + * @param iend The end of the input data. + * @param[out] offsetPtr Stores the match offset into this pointer. + * @param mls The minimum search length, in the range [4, 6]. + * @param rowLog The row log (if applicable), in the range [4, 6]. + * @param searchMethod The search method to use (templated). + * @param dictMode The dictMode (templated). + * + * @returns The length of the longest match found, or < mls if no match is found. + * If a match is found its offset is stored in @p offsetPtr. + */ +FORCE_INLINE_TEMPLATE size_t ZSTD_searchMax( + ZSTD_MatchState_t* ms, + const BYTE* ip, + const BYTE* iend, + size_t* offsetPtr, + U32 const mls, + U32 const rowLog, + searchMethod_e const searchMethod, + ZSTD_dictMode_e const dictMode) +{ + if (dictMode == ZSTD_noDict) { + ZSTD_SWITCH_SEARCH_METHOD(noDict) + } else if (dictMode == ZSTD_extDict) { + ZSTD_SWITCH_SEARCH_METHOD(extDict) + } else if (dictMode == ZSTD_dictMatchState) { + ZSTD_SWITCH_SEARCH_METHOD(dictMatchState) + } else if (dictMode == ZSTD_dedicatedDictSearch) { + ZSTD_SWITCH_SEARCH_METHOD(dedicatedDictSearch) + } + ZSTD_UNREACHABLE; + return 0; +} + +/* ******************************* +* Common parser - lazy strategy +*********************************/ + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_lazy_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, + U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, + const searchMethod_e searchMethod, const U32 depth, + ZSTD_dictMode_e const dictMode) +{ + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = (searchMethod == search_rowHash) ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8; + const BYTE* const base = ms->window.base; + const U32 prefixLowestIndex = ms->window.dictLimit; + const BYTE* const prefixLowest = base + prefixLowestIndex; + const U32 mls = BOUNDED(4, ms->cParams.minMatch, 6); + const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6); + + U32 offset_1 = rep[0], offset_2 = rep[1]; + U32 offsetSaved1 = 0, offsetSaved2 = 0; + + const int isDMS = dictMode == ZSTD_dictMatchState; + const int isDDS = dictMode == ZSTD_dedicatedDictSearch; + const int isDxS = isDMS || isDDS; + const ZSTD_MatchState_t* const dms = ms->dictMatchState; + const U32 dictLowestIndex = isDxS ? dms->window.dictLimit : 0; + const BYTE* const dictBase = isDxS ? dms->window.base : NULL; + const BYTE* const dictLowest = isDxS ? dictBase + dictLowestIndex : NULL; + const BYTE* const dictEnd = isDxS ? dms->window.nextSrc : NULL; + const U32 dictIndexDelta = isDxS ? + prefixLowestIndex - (U32)(dictEnd - dictBase) : + 0; + const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictLowest)); + + DEBUGLOG(5, "ZSTD_compressBlock_lazy_generic (dictMode=%u) (searchFunc=%u)", (U32)dictMode, (U32)searchMethod); + ip += (dictAndPrefixLength == 0); + if (dictMode == ZSTD_noDict) { + U32 const curr = (U32)(ip - base); + U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, ms->cParams.windowLog); + U32 const maxRep = curr - windowLow; + if (offset_2 > maxRep) offsetSaved2 = offset_2, offset_2 = 0; + if (offset_1 > maxRep) offsetSaved1 = offset_1, offset_1 = 0; + } + if (isDxS) { + /* dictMatchState repCode checks don't currently handle repCode == 0 + * disabling. */ + assert(offset_1 <= dictAndPrefixLength); + assert(offset_2 <= dictAndPrefixLength); + } + + /* Reset the lazy skipping state */ + ms->lazySkipping = 0; + + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + + /* Match Loop */ +#if defined(__GNUC__) && defined(__x86_64__) + /* I've measured random a 5% speed loss on levels 5 & 6 (greedy) when the + * code alignment is perturbed. To fix the instability align the loop on 32-bytes. + */ + __asm__(".p2align 5"); +#endif + while (ip < ilimit) { + size_t matchLength=0; + size_t offBase = REPCODE1_TO_OFFBASE; + const BYTE* start=ip+1; + DEBUGLOG(7, "search baseline (depth 0)"); + + /* check repCode */ + if (isDxS) { + const U32 repIndex = (U32)(ip - base) + 1 - offset_1; + const BYTE* repMatch = ((dictMode == ZSTD_dictMatchState || dictMode == ZSTD_dedicatedDictSearch) + && repIndex < prefixLowestIndex) ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + if ((ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) { + const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; + matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4; + if (depth==0) goto _storeSequence; + } + } + if ( dictMode == ZSTD_noDict + && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) { + matchLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4; + if (depth==0) goto _storeSequence; + } + + /* first search (depth 0) */ + { size_t offbaseFound = 999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &offbaseFound, mls, rowLog, searchMethod, dictMode); + if (ml2 > matchLength) + matchLength = ml2, start = ip, offBase = offbaseFound; + } + + if (matchLength < 4) { + size_t const step = ((size_t)(ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */; + ip += step; + /* Enter the lazy skipping mode once we are skipping more than 8 bytes at a time. + * In this mode we stop inserting every position into our tables, and only insert + * positions that we search, which is one in step positions. + * The exact cutoff is flexible, I've just chosen a number that is reasonably high, + * so we minimize the compression ratio loss in "normal" scenarios. This mode gets + * triggered once we've gone 2KB without finding any matches. + */ + ms->lazySkipping = step > kLazySkippingStep; + continue; + } + + /* let's try to find a better solution */ + if (depth>=1) + while (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) { + size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4; + int const gain2 = (int)(mlRep * 3); + int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offBase) + 1); + if ((mlRep >= 4) && (gain2 > gain1)) + matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip; + } + if (isDxS) { + const U32 repIndex = (U32)(ip - base) - offset_1; + const BYTE* repMatch = repIndex < prefixLowestIndex ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + if ((ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip)) ) { + const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; + size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4; + int const gain2 = (int)(mlRep * 3); + int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offBase) + 1); + if ((mlRep >= 4) && (gain2 > gain1)) + matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip; + } + } + { size_t ofbCandidate=999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, dictMode); + int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */ + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 4); + if ((ml2 >= 4) && (gain2 > gain1)) { + matchLength = ml2, offBase = ofbCandidate, start = ip; + continue; /* search a better one */ + } } + + /* let's find an even better one */ + if ((depth==2) && (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) { + size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4; + int const gain2 = (int)(mlRep * 4); + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 1); + if ((mlRep >= 4) && (gain2 > gain1)) + matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip; + } + if (isDxS) { + const U32 repIndex = (U32)(ip - base) - offset_1; + const BYTE* repMatch = repIndex < prefixLowestIndex ? + dictBase + (repIndex - dictIndexDelta) : + base + repIndex; + if ((ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip)) ) { + const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend; + size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4; + int const gain2 = (int)(mlRep * 4); + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 1); + if ((mlRep >= 4) && (gain2 > gain1)) + matchLength = mlRep, offBase = REPCODE1_TO_OFFBASE, start = ip; + } + } + { size_t ofbCandidate=999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, dictMode); + int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */ + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 7); + if ((ml2 >= 4) && (gain2 > gain1)) { + matchLength = ml2, offBase = ofbCandidate, start = ip; + continue; + } } } + break; /* nothing found : store previous solution */ + } + + /* NOTE: + * Pay attention that `start[-value]` can lead to strange undefined behavior + * notably if `value` is unsigned, resulting in a large positive `-value`. + */ + /* catch up */ + if (OFFBASE_IS_OFFSET(offBase)) { + if (dictMode == ZSTD_noDict) { + while ( ((start > anchor) & (start - OFFBASE_TO_OFFSET(offBase) > prefixLowest)) + && (start[-1] == (start-OFFBASE_TO_OFFSET(offBase))[-1]) ) /* only search for offset within prefix */ + { start--; matchLength++; } + } + if (isDxS) { + U32 const matchIndex = (U32)((size_t)(start-base) - OFFBASE_TO_OFFSET(offBase)); + const BYTE* match = (matchIndex < prefixLowestIndex) ? dictBase + matchIndex - dictIndexDelta : base + matchIndex; + const BYTE* const mStart = (matchIndex < prefixLowestIndex) ? dictLowest : prefixLowest; + while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */ + } + offset_2 = offset_1; offset_1 = (U32)OFFBASE_TO_OFFSET(offBase); + } + /* store sequence */ +_storeSequence: + { size_t const litLength = (size_t)(start - anchor); + ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offBase, matchLength); + anchor = ip = start + matchLength; + } + if (ms->lazySkipping) { + /* We've found a match, disable lazy skipping mode, and refill the hash cache. */ + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + ms->lazySkipping = 0; + } + + /* check immediate repcode */ + if (isDxS) { + while (ip <= ilimit) { + U32 const current2 = (U32)(ip-base); + U32 const repIndex = current2 - offset_2; + const BYTE* repMatch = repIndex < prefixLowestIndex ? + dictBase - dictIndexDelta + repIndex : + base + repIndex; + if ( (ZSTD_index_overlap_check(prefixLowestIndex, repIndex)) + && (MEM_read32(repMatch) == MEM_read32(ip)) ) { + const BYTE* const repEnd2 = repIndex < prefixLowestIndex ? dictEnd : iend; + matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd2, prefixLowest) + 4; + offBase = offset_2; offset_2 = offset_1; offset_1 = (U32)offBase; /* swap offset_2 <=> offset_1 */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, matchLength); + ip += matchLength; + anchor = ip; + continue; + } + break; + } + } + + if (dictMode == ZSTD_noDict) { + while ( ((ip <= ilimit) & (offset_2>0)) + && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) { + /* store sequence */ + matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4; + offBase = offset_2; offset_2 = offset_1; offset_1 = (U32)offBase; /* swap repcodes */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, matchLength); + ip += matchLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } } } + + /* If offset_1 started invalid (offsetSaved1 != 0) and became valid (offset_1 != 0), + * rotate saved offsets. See comment in ZSTD_compressBlock_fast_noDict for more context. */ + offsetSaved2 = ((offsetSaved1 != 0) && (offset_1 != 0)) ? offsetSaved1 : offsetSaved2; + + /* save reps for next block */ + rep[0] = offset_1 ? offset_1 : offsetSaved1; + rep[1] = offset_2 ? offset_2 : offsetSaved2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} +#endif /* build exclusions */ + + +#ifndef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_greedy( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_greedy_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dedicatedDictSearch); +} + +size_t ZSTD_compressBlock_greedy_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_greedy_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0, ZSTD_dedicatedDictSearch); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dedicatedDictSearch); +} + +size_t ZSTD_compressBlock_lazy_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1, ZSTD_dedicatedDictSearch); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy2_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dedicatedDictSearch); +} + +size_t ZSTD_compressBlock_lazy2_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_lazy2_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2, ZSTD_dedicatedDictSearch); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btlazy2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_btlazy2_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_dictMatchState); +} +#endif + +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_compressBlock_lazy_extDict_generic( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, + U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, + const searchMethod_e searchMethod, const U32 depth) +{ + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = searchMethod == search_rowHash ? iend - 8 - ZSTD_ROW_HASH_CACHE_SIZE : iend - 8; + const BYTE* const base = ms->window.base; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* const dictBase = ms->window.dictBase; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const dictStart = dictBase + ms->window.lowLimit; + const U32 windowLog = ms->cParams.windowLog; + const U32 mls = BOUNDED(4, ms->cParams.minMatch, 6); + const U32 rowLog = BOUNDED(4, ms->cParams.searchLog, 6); + + U32 offset_1 = rep[0], offset_2 = rep[1]; + + DEBUGLOG(5, "ZSTD_compressBlock_lazy_extDict_generic (searchFunc=%u)", (U32)searchMethod); + + /* Reset the lazy skipping state */ + ms->lazySkipping = 0; + + /* init */ + ip += (ip == prefixStart); + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + + /* Match Loop */ +#if defined(__GNUC__) && defined(__x86_64__) + /* I've measured random a 5% speed loss on levels 5 & 6 (greedy) when the + * code alignment is perturbed. To fix the instability align the loop on 32-bytes. + */ + __asm__(".p2align 5"); +#endif + while (ip < ilimit) { + size_t matchLength=0; + size_t offBase = REPCODE1_TO_OFFBASE; + const BYTE* start=ip+1; + U32 curr = (U32)(ip-base); + + /* check repCode */ + { const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr+1, windowLog); + const U32 repIndex = (U32)(curr+1 - offset_1); + const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; + const BYTE* const repMatch = repBase + repIndex; + if ( (ZSTD_index_overlap_check(dictLimit, repIndex)) + & (offset_1 <= curr+1 - windowLow) ) /* note: we are searching at curr+1 */ + if (MEM_read32(ip+1) == MEM_read32(repMatch)) { + /* repcode detected we should take it */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repEnd, prefixStart) + 4; + if (depth==0) goto _storeSequence; + } } + + /* first search (depth 0) */ + { size_t ofbCandidate = 999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, ZSTD_extDict); + if (ml2 > matchLength) + matchLength = ml2, start = ip, offBase = ofbCandidate; + } + + if (matchLength < 4) { + size_t const step = ((size_t)(ip-anchor) >> kSearchStrength); + ip += step + 1; /* jump faster over incompressible sections */ + /* Enter the lazy skipping mode once we are skipping more than 8 bytes at a time. + * In this mode we stop inserting every position into our tables, and only insert + * positions that we search, which is one in step positions. + * The exact cutoff is flexible, I've just chosen a number that is reasonably high, + * so we minimize the compression ratio loss in "normal" scenarios. This mode gets + * triggered once we've gone 2KB without finding any matches. + */ + ms->lazySkipping = step > kLazySkippingStep; + continue; + } + + /* let's try to find a better solution */ + if (depth>=1) + while (ip repIndex >= windowLow` */ + if (MEM_read32(ip) == MEM_read32(repMatch)) { + /* repcode detected */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4; + int const gain2 = (int)(repLength * 3); + int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offBase) + 1); + if ((repLength >= 4) && (gain2 > gain1)) + matchLength = repLength, offBase = REPCODE1_TO_OFFBASE, start = ip; + } } + + /* search match, depth 1 */ + { size_t ofbCandidate = 999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, ZSTD_extDict); + int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */ + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 4); + if ((ml2 >= 4) && (gain2 > gain1)) { + matchLength = ml2, offBase = ofbCandidate, start = ip; + continue; /* search a better one */ + } } + + /* let's find an even better one */ + if ((depth==2) && (ip repIndex >= windowLow` */ + if (MEM_read32(ip) == MEM_read32(repMatch)) { + /* repcode detected */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4; + int const gain2 = (int)(repLength * 4); + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 1); + if ((repLength >= 4) && (gain2 > gain1)) + matchLength = repLength, offBase = REPCODE1_TO_OFFBASE, start = ip; + } } + + /* search match, depth 2 */ + { size_t ofbCandidate = 999999999; + size_t const ml2 = ZSTD_searchMax(ms, ip, iend, &ofbCandidate, mls, rowLog, searchMethod, ZSTD_extDict); + int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)ofbCandidate)); /* raw approx */ + int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offBase) + 7); + if ((ml2 >= 4) && (gain2 > gain1)) { + matchLength = ml2, offBase = ofbCandidate, start = ip; + continue; + } } } + break; /* nothing found : store previous solution */ + } + + /* catch up */ + if (OFFBASE_IS_OFFSET(offBase)) { + U32 const matchIndex = (U32)((size_t)(start-base) - OFFBASE_TO_OFFSET(offBase)); + const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex; + const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart; + while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */ + offset_2 = offset_1; offset_1 = (U32)OFFBASE_TO_OFFSET(offBase); + } + + /* store sequence */ +_storeSequence: + { size_t const litLength = (size_t)(start - anchor); + ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offBase, matchLength); + anchor = ip = start + matchLength; + } + if (ms->lazySkipping) { + /* We've found a match, disable lazy skipping mode, and refill the hash cache. */ + if (searchMethod == search_rowHash) { + ZSTD_row_fillHashCache(ms, base, rowLog, mls, ms->nextToUpdate, ilimit); + } + ms->lazySkipping = 0; + } + + /* check immediate repcode */ + while (ip <= ilimit) { + const U32 repCurrent = (U32)(ip-base); + const U32 windowLow = ZSTD_getLowestMatchIndex(ms, repCurrent, windowLog); + const U32 repIndex = repCurrent - offset_2; + const BYTE* const repBase = repIndex < dictLimit ? dictBase : base; + const BYTE* const repMatch = repBase + repIndex; + if ( (ZSTD_index_overlap_check(dictLimit, repIndex)) + & (offset_2 <= repCurrent - windowLow) ) /* equivalent to `curr > repIndex >= windowLow` */ + if (MEM_read32(ip) == MEM_read32(repMatch)) { + /* repcode detected we should take it */ + const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend; + matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4; + offBase = offset_2; offset_2 = offset_1; offset_1 = (U32)offBase; /* swap offset history */ + ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, matchLength); + ip += matchLength; + anchor = ip; + continue; /* faster when present ... (?) */ + } + break; + } } + + /* Save reps for next block */ + rep[0] = offset_1; + rep[1] = offset_2; + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} +#endif /* build exclusions */ + +#ifndef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_greedy_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0); +} + +size_t ZSTD_compressBlock_greedy_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 0); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1); +} + +size_t ZSTD_compressBlock_lazy_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 1); +} +#endif + +#ifndef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy2_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2); +} + +size_t ZSTD_compressBlock_lazy2_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_rowHash, 2); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btlazy2_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize) + +{ + return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2); +} +#endif diff --git a/src/commonlib/bsd/zstd/compress/zstd_lazy.h b/src/commonlib/bsd/zstd/compress/zstd_lazy.h new file mode 100644 index 00000000000..f959a855f61 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_lazy.h @@ -0,0 +1,195 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_LAZY_H +#define ZSTD_LAZY_H + +#include "zstd_compress_internal.h" + +/** + * Dedicated Dictionary Search Structure bucket log. In the + * ZSTD_dedicatedDictSearch mode, the hashTable has + * 2 ** ZSTD_LAZY_DDSS_BUCKET_LOG entries in each bucket, rather than just + * one. + */ +#define ZSTD_LAZY_DDSS_BUCKET_LOG 2 + +#define ZSTD_ROW_HASH_TAG_BITS 8 /* nb bits to use for the tag */ + +#if !defined(ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) +U32 ZSTD_insertAndFindFirstIndex(ZSTD_MatchState_t* ms, const BYTE* ip); +void ZSTD_row_update(ZSTD_MatchState_t* const ms, const BYTE* ip); + +void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_MatchState_t* ms, const BYTE* const ip); + +void ZSTD_preserveUnsortedMark (U32* const table, U32 const size, U32 const reducerValue); /*! used in ZSTD_reduceIndex(). preemptively increase value of ZSTD_DUBT_UNSORTED_MARK */ +#endif + +#ifndef ZSTD_EXCLUDE_GREEDY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_greedy( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_greedy_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_GREEDY ZSTD_compressBlock_greedy +#define ZSTD_COMPRESSBLOCK_GREEDY_ROW ZSTD_compressBlock_greedy_row +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE ZSTD_compressBlock_greedy_dictMatchState +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW ZSTD_compressBlock_greedy_dictMatchState_row +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH ZSTD_compressBlock_greedy_dedicatedDictSearch +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW ZSTD_compressBlock_greedy_dedicatedDictSearch_row +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT ZSTD_compressBlock_greedy_extDict +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW ZSTD_compressBlock_greedy_extDict_row +#else +#define ZSTD_COMPRESSBLOCK_GREEDY NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_ROW NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DICTMATCHSTATE_ROW NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_DEDICATEDDICTSEARCH_ROW NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_GREEDY_EXTDICT_ROW NULL +#endif + +#ifndef ZSTD_EXCLUDE_LAZY_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_LAZY ZSTD_compressBlock_lazy +#define ZSTD_COMPRESSBLOCK_LAZY_ROW ZSTD_compressBlock_lazy_row +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE ZSTD_compressBlock_lazy_dictMatchState +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW ZSTD_compressBlock_lazy_dictMatchState_row +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH ZSTD_compressBlock_lazy_dedicatedDictSearch +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW ZSTD_compressBlock_lazy_dedicatedDictSearch_row +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT ZSTD_compressBlock_lazy_extDict +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW ZSTD_compressBlock_lazy_extDict_row +#else +#define ZSTD_COMPRESSBLOCK_LAZY NULL +#define ZSTD_COMPRESSBLOCK_LAZY_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DICTMATCHSTATE_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH NULL +#define ZSTD_COMPRESSBLOCK_LAZY_DEDICATEDDICTSEARCH_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_LAZY_EXTDICT_ROW NULL +#endif + +#ifndef ZSTD_EXCLUDE_LAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_lazy2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dictMatchState_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_lazy2_extDict_row( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_LAZY2 ZSTD_compressBlock_lazy2 +#define ZSTD_COMPRESSBLOCK_LAZY2_ROW ZSTD_compressBlock_lazy2_row +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE ZSTD_compressBlock_lazy2_dictMatchState +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW ZSTD_compressBlock_lazy2_dictMatchState_row +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH ZSTD_compressBlock_lazy2_dedicatedDictSearch +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW ZSTD_compressBlock_lazy2_dedicatedDictSearch_row +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT ZSTD_compressBlock_lazy2_extDict +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW ZSTD_compressBlock_lazy2_extDict_row +#else +#define ZSTD_COMPRESSBLOCK_LAZY2 NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DICTMATCHSTATE_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_LAZY2_EXTDICT_ROW NULL +#endif + +#ifndef ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btlazy2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btlazy2_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btlazy2_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_BTLAZY2 ZSTD_compressBlock_btlazy2 +#define ZSTD_COMPRESSBLOCK_BTLAZY2_DICTMATCHSTATE ZSTD_compressBlock_btlazy2_dictMatchState +#define ZSTD_COMPRESSBLOCK_BTLAZY2_EXTDICT ZSTD_compressBlock_btlazy2_extDict +#else +#define ZSTD_COMPRESSBLOCK_BTLAZY2 NULL +#define ZSTD_COMPRESSBLOCK_BTLAZY2_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_BTLAZY2_EXTDICT NULL +#endif + +#endif /* ZSTD_LAZY_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_ldm.c b/src/commonlib/bsd/zstd/compress/zstd_ldm.c new file mode 100644 index 00000000000..969b73152f1 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_ldm.c @@ -0,0 +1,747 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_ldm.h" + +#include "../common/debug.h" +#include +#include "zstd_fast.h" /* ZSTD_fillHashTable() */ +#include "zstd_double_fast.h" /* ZSTD_fillDoubleHashTable() */ +#include "zstd_ldm_geartab.h" + +#define LDM_BUCKET_SIZE_LOG 4 +#define LDM_MIN_MATCH_LENGTH 64 +#define LDM_HASH_RLOG 7 + +typedef struct { + U64 rolling; + U64 stopMask; +} ldmRollingHashState_t; + +/** ZSTD_ldm_gear_init(): + * + * Initializes the rolling hash state such that it will honor the + * settings in params. */ +static void ZSTD_ldm_gear_init(ldmRollingHashState_t* state, ldmParams_t const* params) +{ + unsigned maxBitsInMask = MIN(params->minMatchLength, 64); + unsigned hashRateLog = params->hashRateLog; + + state->rolling = ~(U32)0; + + /* The choice of the splitting criterion is subject to two conditions: + * 1. it has to trigger on average every 2^(hashRateLog) bytes; + * 2. ideally, it has to depend on a window of minMatchLength bytes. + * + * In the gear hash algorithm, bit n depends on the last n bytes; + * so in order to obtain a good quality splitting criterion it is + * preferable to use bits with high weight. + * + * To match condition 1 we use a mask with hashRateLog bits set + * and, because of the previous remark, we make sure these bits + * have the highest possible weight while still respecting + * condition 2. + */ + if (hashRateLog > 0 && hashRateLog <= maxBitsInMask) { + state->stopMask = (((U64)1 << hashRateLog) - 1) << (maxBitsInMask - hashRateLog); + } else { + /* In this degenerate case we simply honor the hash rate. */ + state->stopMask = ((U64)1 << hashRateLog) - 1; + } +} + +/** ZSTD_ldm_gear_reset() + * Feeds [data, data + minMatchLength) into the hash without registering any + * splits. This effectively resets the hash state. This is used when skipping + * over data, either at the beginning of a block, or skipping sections. + */ +static void ZSTD_ldm_gear_reset(ldmRollingHashState_t* state, + BYTE const* data, size_t minMatchLength) +{ + U64 hash = state->rolling; + size_t n = 0; + +#define GEAR_ITER_ONCE() do { \ + hash = (hash << 1) + ZSTD_ldm_gearTab[data[n] & 0xff]; \ + n += 1; \ + } while (0) + while (n + 3 < minMatchLength) { + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + } + while (n < minMatchLength) { + GEAR_ITER_ONCE(); + } +#undef GEAR_ITER_ONCE +} + +/** ZSTD_ldm_gear_feed(): + * + * Registers in the splits array all the split points found in the first + * size bytes following the data pointer. This function terminates when + * either all the data has been processed or LDM_BATCH_SIZE splits are + * present in the splits array. + * + * Precondition: The splits array must not be full. + * Returns: The number of bytes processed. */ +static size_t ZSTD_ldm_gear_feed(ldmRollingHashState_t* state, + BYTE const* data, size_t size, + size_t* splits, unsigned* numSplits) +{ + size_t n; + U64 hash, mask; + + hash = state->rolling; + mask = state->stopMask; + n = 0; + +#define GEAR_ITER_ONCE() do { \ + hash = (hash << 1) + ZSTD_ldm_gearTab[data[n] & 0xff]; \ + n += 1; \ + if (UNLIKELY((hash & mask) == 0)) { \ + splits[*numSplits] = n; \ + *numSplits += 1; \ + if (*numSplits == LDM_BATCH_SIZE) \ + goto done; \ + } \ + } while (0) + + while (n + 3 < size) { + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + GEAR_ITER_ONCE(); + } + while (n < size) { + GEAR_ITER_ONCE(); + } + +#undef GEAR_ITER_ONCE + +done: + state->rolling = hash; + return n; +} + +void ZSTD_ldm_adjustParameters(ldmParams_t* params, + const ZSTD_compressionParameters* cParams) +{ + params->windowLog = cParams->windowLog; + ZSTD_STATIC_ASSERT(LDM_BUCKET_SIZE_LOG <= ZSTD_LDM_BUCKETSIZELOG_MAX); + DEBUGLOG(4, "ZSTD_ldm_adjustParameters"); + if (params->hashRateLog == 0) { + if (params->hashLog > 0) { + /* if params->hashLog is set, derive hashRateLog from it */ + assert(params->hashLog <= ZSTD_HASHLOG_MAX); + if (params->windowLog > params->hashLog) { + params->hashRateLog = params->windowLog - params->hashLog; + } + } else { + assert(1 <= (int)cParams->strategy && (int)cParams->strategy <= 9); + /* mapping from [fast, rate7] to [btultra2, rate4] */ + params->hashRateLog = 7 - (cParams->strategy/3); + } + } + if (params->hashLog == 0) { + params->hashLog = BOUNDED(ZSTD_HASHLOG_MIN, params->windowLog - params->hashRateLog, ZSTD_HASHLOG_MAX); + } + if (params->minMatchLength == 0) { + params->minMatchLength = LDM_MIN_MATCH_LENGTH; + if (cParams->strategy >= ZSTD_btultra) + params->minMatchLength /= 2; + } + if (params->bucketSizeLog==0) { + assert(1 <= (int)cParams->strategy && (int)cParams->strategy <= 9); + params->bucketSizeLog = BOUNDED(LDM_BUCKET_SIZE_LOG, (U32)cParams->strategy, ZSTD_LDM_BUCKETSIZELOG_MAX); + } + params->bucketSizeLog = MIN(params->bucketSizeLog, params->hashLog); +} + +size_t ZSTD_ldm_getTableSize(ldmParams_t params) +{ + size_t const ldmHSize = ((size_t)1) << params.hashLog; + size_t const ldmBucketSizeLog = MIN(params.bucketSizeLog, params.hashLog); + size_t const ldmBucketSize = ((size_t)1) << (params.hashLog - ldmBucketSizeLog); + size_t const totalSize = ZSTD_cwksp_alloc_size(ldmBucketSize) + + ZSTD_cwksp_alloc_size(ldmHSize * sizeof(ldmEntry_t)); + return params.enableLdm == ZSTD_ps_enable ? totalSize : 0; +} + +size_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize) +{ + return params.enableLdm == ZSTD_ps_enable ? (maxChunkSize / params.minMatchLength) : 0; +} + +/** ZSTD_ldm_getBucket() : + * Returns a pointer to the start of the bucket associated with hash. */ +static ldmEntry_t* ZSTD_ldm_getBucket( + const ldmState_t* ldmState, size_t hash, U32 const bucketSizeLog) +{ + return ldmState->hashTable + (hash << bucketSizeLog); +} + +/** ZSTD_ldm_insertEntry() : + * Insert the entry with corresponding hash into the hash table */ +static void ZSTD_ldm_insertEntry(ldmState_t* ldmState, + size_t const hash, const ldmEntry_t entry, + U32 const bucketSizeLog) +{ + BYTE* const pOffset = ldmState->bucketOffsets + hash; + unsigned const offset = *pOffset; + + *(ZSTD_ldm_getBucket(ldmState, hash, bucketSizeLog) + offset) = entry; + *pOffset = (BYTE)((offset + 1) & ((1u << bucketSizeLog) - 1)); + +} + +/** ZSTD_ldm_countBackwardsMatch() : + * Returns the number of bytes that match backwards before pIn and pMatch. + * + * We count only bytes where pMatch >= pBase and pIn >= pAnchor. */ +static size_t ZSTD_ldm_countBackwardsMatch( + const BYTE* pIn, const BYTE* pAnchor, + const BYTE* pMatch, const BYTE* pMatchBase) +{ + size_t matchLength = 0; + while (pIn > pAnchor && pMatch > pMatchBase && pIn[-1] == pMatch[-1]) { + pIn--; + pMatch--; + matchLength++; + } + return matchLength; +} + +/** ZSTD_ldm_countBackwardsMatch_2segments() : + * Returns the number of bytes that match backwards from pMatch, + * even with the backwards match spanning 2 different segments. + * + * On reaching `pMatchBase`, start counting from mEnd */ +static size_t ZSTD_ldm_countBackwardsMatch_2segments( + const BYTE* pIn, const BYTE* pAnchor, + const BYTE* pMatch, const BYTE* pMatchBase, + const BYTE* pExtDictStart, const BYTE* pExtDictEnd) +{ + size_t matchLength = ZSTD_ldm_countBackwardsMatch(pIn, pAnchor, pMatch, pMatchBase); + if (pMatch - matchLength != pMatchBase || pMatchBase == pExtDictStart) { + /* If backwards match is entirely in the extDict or prefix, immediately return */ + return matchLength; + } + DEBUGLOG(7, "ZSTD_ldm_countBackwardsMatch_2segments: found 2-parts backwards match (length in prefix==%zu)", matchLength); + matchLength += ZSTD_ldm_countBackwardsMatch(pIn - matchLength, pAnchor, pExtDictEnd, pExtDictStart); + DEBUGLOG(7, "final backwards match length = %zu", matchLength); + return matchLength; +} + +/** ZSTD_ldm_fillFastTables() : + * + * Fills the relevant tables for the ZSTD_fast and ZSTD_dfast strategies. + * This is similar to ZSTD_loadDictionaryContent. + * + * The tables for the other strategies are filled within their + * block compressors. */ +static size_t ZSTD_ldm_fillFastTables(ZSTD_MatchState_t* ms, + void const* end) +{ + const BYTE* const iend = (const BYTE*)end; + + switch(ms->cParams.strategy) + { + case ZSTD_fast: + ZSTD_fillHashTable(ms, iend, ZSTD_dtlm_fast, ZSTD_tfp_forCCtx); + break; + + case ZSTD_dfast: +#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR + ZSTD_fillDoubleHashTable(ms, iend, ZSTD_dtlm_fast, ZSTD_tfp_forCCtx); +#else + assert(0); /* shouldn't be called: cparams should've been adjusted. */ +#endif + break; + + case ZSTD_greedy: + case ZSTD_lazy: + case ZSTD_lazy2: + case ZSTD_btlazy2: + case ZSTD_btopt: + case ZSTD_btultra: + case ZSTD_btultra2: + break; + default: + assert(0); /* not possible : not a valid strategy id */ + } + + return 0; +} + +void ZSTD_ldm_fillHashTable( + ldmState_t* ldmState, const BYTE* ip, + const BYTE* iend, ldmParams_t const* params) +{ + U32 const minMatchLength = params->minMatchLength; + U32 const bucketSizeLog = params->bucketSizeLog; + U32 const hBits = params->hashLog - bucketSizeLog; + BYTE const* const base = ldmState->window.base; + BYTE const* const istart = ip; + ldmRollingHashState_t hashState; + size_t* const splits = ldmState->splitIndices; + unsigned numSplits; + + DEBUGLOG(5, "ZSTD_ldm_fillHashTable"); + + ZSTD_ldm_gear_init(&hashState, params); + while (ip < iend) { + size_t hashed; + unsigned n; + + numSplits = 0; + hashed = ZSTD_ldm_gear_feed(&hashState, ip, (size_t)(iend - ip), splits, &numSplits); + + for (n = 0; n < numSplits; n++) { + if (ip + splits[n] >= istart + minMatchLength) { + BYTE const* const split = ip + splits[n] - minMatchLength; + U64 const xxhash = XXH64(split, minMatchLength, 0); + U32 const hash = (U32)(xxhash & (((U32)1 << hBits) - 1)); + ldmEntry_t entry; + + entry.offset = (U32)(split - base); + entry.checksum = (U32)(xxhash >> 32); + ZSTD_ldm_insertEntry(ldmState, hash, entry, params->bucketSizeLog); + } + } + + ip += hashed; + } +} + + +/** ZSTD_ldm_limitTableUpdate() : + * + * Sets cctx->nextToUpdate to a position corresponding closer to anchor + * if it is far way + * (after a long match, only update tables a limited amount). */ +static void ZSTD_ldm_limitTableUpdate(ZSTD_MatchState_t* ms, const BYTE* anchor) +{ + U32 const curr = (U32)(anchor - ms->window.base); + if (curr > ms->nextToUpdate + 1024) { + ms->nextToUpdate = + curr - MIN(512, curr - ms->nextToUpdate - 1024); + } +} + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_ldm_generateSequences_internal( + ldmState_t* ldmState, RawSeqStore_t* rawSeqStore, + ldmParams_t const* params, void const* src, size_t srcSize) +{ + /* LDM parameters */ + int const extDict = ZSTD_window_hasExtDict(ldmState->window); + U32 const minMatchLength = params->minMatchLength; + U32 const entsPerBucket = 1U << params->bucketSizeLog; + U32 const hBits = params->hashLog - params->bucketSizeLog; + /* Prefix and extDict parameters */ + U32 const dictLimit = ldmState->window.dictLimit; + U32 const lowestIndex = extDict ? ldmState->window.lowLimit : dictLimit; + BYTE const* const base = ldmState->window.base; + BYTE const* const dictBase = extDict ? ldmState->window.dictBase : NULL; + BYTE const* const dictStart = extDict ? dictBase + lowestIndex : NULL; + BYTE const* const dictEnd = extDict ? dictBase + dictLimit : NULL; + BYTE const* const lowPrefixPtr = base + dictLimit; + /* Input bounds */ + BYTE const* const istart = (BYTE const*)src; + BYTE const* const iend = istart + srcSize; + BYTE const* const ilimit = iend - HASH_READ_SIZE; + /* Input positions */ + BYTE const* anchor = istart; + BYTE const* ip = istart; + /* Rolling hash state */ + ldmRollingHashState_t hashState; + /* Arrays for staged-processing */ + size_t* const splits = ldmState->splitIndices; + ldmMatchCandidate_t* const candidates = ldmState->matchCandidates; + unsigned numSplits; + + if (srcSize < minMatchLength) + return iend - anchor; + + /* Initialize the rolling hash state with the first minMatchLength bytes */ + ZSTD_ldm_gear_init(&hashState, params); + ZSTD_ldm_gear_reset(&hashState, ip, minMatchLength); + ip += minMatchLength; + + while (ip < ilimit) { + size_t hashed; + unsigned n; + + numSplits = 0; + hashed = ZSTD_ldm_gear_feed(&hashState, ip, ilimit - ip, + splits, &numSplits); + + for (n = 0; n < numSplits; n++) { + BYTE const* const split = ip + splits[n] - minMatchLength; + U64 const xxhash = XXH64(split, minMatchLength, 0); + U32 const hash = (U32)(xxhash & (((U32)1 << hBits) - 1)); + + candidates[n].split = split; + candidates[n].hash = hash; + candidates[n].checksum = (U32)(xxhash >> 32); + candidates[n].bucket = ZSTD_ldm_getBucket(ldmState, hash, params->bucketSizeLog); + PREFETCH_L1(candidates[n].bucket); + } + + for (n = 0; n < numSplits; n++) { + size_t forwardMatchLength = 0, backwardMatchLength = 0, + bestMatchLength = 0, mLength; + U32 offset; + BYTE const* const split = candidates[n].split; + U32 const checksum = candidates[n].checksum; + U32 const hash = candidates[n].hash; + ldmEntry_t* const bucket = candidates[n].bucket; + ldmEntry_t const* cur; + ldmEntry_t const* bestEntry = NULL; + ldmEntry_t newEntry; + + newEntry.offset = (U32)(split - base); + newEntry.checksum = checksum; + + /* If a split point would generate a sequence overlapping with + * the previous one, we merely register it in the hash table and + * move on */ + if (split < anchor) { + ZSTD_ldm_insertEntry(ldmState, hash, newEntry, params->bucketSizeLog); + continue; + } + + for (cur = bucket; cur < bucket + entsPerBucket; cur++) { + size_t curForwardMatchLength, curBackwardMatchLength, + curTotalMatchLength; + if (cur->checksum != checksum || cur->offset <= lowestIndex) { + continue; + } + if (extDict) { + BYTE const* const curMatchBase = + cur->offset < dictLimit ? dictBase : base; + BYTE const* const pMatch = curMatchBase + cur->offset; + BYTE const* const matchEnd = + cur->offset < dictLimit ? dictEnd : iend; + BYTE const* const lowMatchPtr = + cur->offset < dictLimit ? dictStart : lowPrefixPtr; + curForwardMatchLength = + ZSTD_count_2segments(split, pMatch, iend, matchEnd, lowPrefixPtr); + if (curForwardMatchLength < minMatchLength) { + continue; + } + curBackwardMatchLength = ZSTD_ldm_countBackwardsMatch_2segments( + split, anchor, pMatch, lowMatchPtr, dictStart, dictEnd); + } else { /* !extDict */ + BYTE const* const pMatch = base + cur->offset; + curForwardMatchLength = ZSTD_count(split, pMatch, iend); + if (curForwardMatchLength < minMatchLength) { + continue; + } + curBackwardMatchLength = + ZSTD_ldm_countBackwardsMatch(split, anchor, pMatch, lowPrefixPtr); + } + curTotalMatchLength = curForwardMatchLength + curBackwardMatchLength; + + if (curTotalMatchLength > bestMatchLength) { + bestMatchLength = curTotalMatchLength; + forwardMatchLength = curForwardMatchLength; + backwardMatchLength = curBackwardMatchLength; + bestEntry = cur; + } + } + + /* No match found -- insert an entry into the hash table + * and process the next candidate match */ + if (bestEntry == NULL) { + ZSTD_ldm_insertEntry(ldmState, hash, newEntry, params->bucketSizeLog); + continue; + } + + /* Match found */ + offset = (U32)(split - base) - bestEntry->offset; + mLength = forwardMatchLength + backwardMatchLength; + { + rawSeq* const seq = rawSeqStore->seq + rawSeqStore->size; + + /* Out of sequence storage */ + if (rawSeqStore->size == rawSeqStore->capacity) + return ERROR(dstSize_tooSmall); + seq->litLength = (U32)(split - backwardMatchLength - anchor); + seq->matchLength = (U32)mLength; + seq->offset = offset; + rawSeqStore->size++; + } + + /* Insert the current entry into the hash table --- it must be + * done after the previous block to avoid clobbering bestEntry */ + ZSTD_ldm_insertEntry(ldmState, hash, newEntry, params->bucketSizeLog); + + anchor = split + forwardMatchLength; + + /* If we find a match that ends after the data that we've hashed + * then we have a repeating, overlapping, pattern. E.g. all zeros. + * If one repetition of the pattern matches our `stopMask` then all + * repetitions will. We don't need to insert them all into out table, + * only the first one. So skip over overlapping matches. + * This is a major speed boost (20x) for compressing a single byte + * repeated, when that byte ends up in the table. + */ + if (anchor > ip + hashed) { + ZSTD_ldm_gear_reset(&hashState, anchor - minMatchLength, minMatchLength); + /* Continue the outer loop at anchor (ip + hashed == anchor). */ + ip = anchor - hashed; + break; + } + } + + ip += hashed; + } + + return iend - anchor; +} + +/*! ZSTD_ldm_reduceTable() : + * reduce table indexes by `reducerValue` */ +static void ZSTD_ldm_reduceTable(ldmEntry_t* const table, U32 const size, + U32 const reducerValue) +{ + U32 u; + for (u = 0; u < size; u++) { + if (table[u].offset < reducerValue) table[u].offset = 0; + else table[u].offset -= reducerValue; + } +} + +size_t ZSTD_ldm_generateSequences( + ldmState_t* ldmState, RawSeqStore_t* sequences, + ldmParams_t const* params, void const* src, size_t srcSize) +{ + U32 const maxDist = 1U << params->windowLog; + BYTE const* const istart = (BYTE const*)src; + BYTE const* const iend = istart + srcSize; + size_t const kMaxChunkSize = 1 << 20; + size_t const nbChunks = (srcSize / kMaxChunkSize) + ((srcSize % kMaxChunkSize) != 0); + size_t chunk; + size_t leftoverSize = 0; + + assert(ZSTD_CHUNKSIZE_MAX >= kMaxChunkSize); + /* Check that ZSTD_window_update() has been called for this chunk prior + * to passing it to this function. + */ + assert(ldmState->window.nextSrc >= (BYTE const*)src + srcSize); + /* The input could be very large (in zstdmt), so it must be broken up into + * chunks to enforce the maximum distance and handle overflow correction. + */ + assert(sequences->pos <= sequences->size); + assert(sequences->size <= sequences->capacity); + for (chunk = 0; chunk < nbChunks && sequences->size < sequences->capacity; ++chunk) { + BYTE const* const chunkStart = istart + chunk * kMaxChunkSize; + size_t const remaining = (size_t)(iend - chunkStart); + BYTE const *const chunkEnd = + (remaining < kMaxChunkSize) ? iend : chunkStart + kMaxChunkSize; + size_t const chunkSize = chunkEnd - chunkStart; + size_t newLeftoverSize; + size_t const prevSize = sequences->size; + + assert(chunkStart < iend); + /* 1. Perform overflow correction if necessary. */ + if (ZSTD_window_needOverflowCorrection(ldmState->window, 0, maxDist, ldmState->loadedDictEnd, chunkStart, chunkEnd)) { + U32 const ldmHSize = 1U << params->hashLog; + U32 const correction = ZSTD_window_correctOverflow( + &ldmState->window, /* cycleLog */ 0, maxDist, chunkStart); + ZSTD_ldm_reduceTable(ldmState->hashTable, ldmHSize, correction); + /* invalidate dictionaries on overflow correction */ + ldmState->loadedDictEnd = 0; + } + /* 2. We enforce the maximum offset allowed. + * + * kMaxChunkSize should be small enough that we don't lose too much of + * the window through early invalidation. + * TODO: * Test the chunk size. + * * Try invalidation after the sequence generation and test the + * offset against maxDist directly. + * + * NOTE: Because of dictionaries + sequence splitting we MUST make sure + * that any offset used is valid at the END of the sequence, since it may + * be split into two sequences. This condition holds when using + * ZSTD_window_enforceMaxDist(), but if we move to checking offsets + * against maxDist directly, we'll have to carefully handle that case. + */ + ZSTD_window_enforceMaxDist(&ldmState->window, chunkEnd, maxDist, &ldmState->loadedDictEnd, NULL); + /* 3. Generate the sequences for the chunk, and get newLeftoverSize. */ + newLeftoverSize = ZSTD_ldm_generateSequences_internal( + ldmState, sequences, params, chunkStart, chunkSize); + if (ZSTD_isError(newLeftoverSize)) + return newLeftoverSize; + /* 4. We add the leftover literals from previous iterations to the first + * newly generated sequence, or add the `newLeftoverSize` if none are + * generated. + */ + /* Prepend the leftover literals from the last call */ + if (prevSize < sequences->size) { + sequences->seq[prevSize].litLength += (U32)leftoverSize; + leftoverSize = newLeftoverSize; + } else { + assert(newLeftoverSize == chunkSize); + leftoverSize += chunkSize; + } + } + return 0; +} + +void +ZSTD_ldm_skipSequences(RawSeqStore_t* rawSeqStore, size_t srcSize, U32 const minMatch) +{ + while (srcSize > 0 && rawSeqStore->pos < rawSeqStore->size) { + rawSeq* seq = rawSeqStore->seq + rawSeqStore->pos; + if (srcSize <= seq->litLength) { + /* Skip past srcSize literals */ + seq->litLength -= (U32)srcSize; + return; + } + srcSize -= seq->litLength; + seq->litLength = 0; + if (srcSize < seq->matchLength) { + /* Skip past the first srcSize of the match */ + seq->matchLength -= (U32)srcSize; + if (seq->matchLength < minMatch) { + /* The match is too short, omit it */ + if (rawSeqStore->pos + 1 < rawSeqStore->size) { + seq[1].litLength += seq[0].matchLength; + } + rawSeqStore->pos++; + } + return; + } + srcSize -= seq->matchLength; + seq->matchLength = 0; + rawSeqStore->pos++; + } +} + +/** + * If the sequence length is longer than remaining then the sequence is split + * between this block and the next. + * + * Returns the current sequence to handle, or if the rest of the block should + * be literals, it returns a sequence with offset == 0. + */ +static rawSeq maybeSplitSequence(RawSeqStore_t* rawSeqStore, + U32 const remaining, U32 const minMatch) +{ + rawSeq sequence = rawSeqStore->seq[rawSeqStore->pos]; + assert(sequence.offset > 0); + /* Likely: No partial sequence */ + if (remaining >= sequence.litLength + sequence.matchLength) { + rawSeqStore->pos++; + return sequence; + } + /* Cut the sequence short (offset == 0 ==> rest is literals). */ + if (remaining <= sequence.litLength) { + sequence.offset = 0; + } else if (remaining < sequence.litLength + sequence.matchLength) { + sequence.matchLength = remaining - sequence.litLength; + if (sequence.matchLength < minMatch) { + sequence.offset = 0; + } + } + /* Skip past `remaining` bytes for the future sequences. */ + ZSTD_ldm_skipSequences(rawSeqStore, remaining, minMatch); + return sequence; +} + +void ZSTD_ldm_skipRawSeqStoreBytes(RawSeqStore_t* rawSeqStore, size_t nbBytes) { + U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes); + while (currPos && rawSeqStore->pos < rawSeqStore->size) { + rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos]; + if (currPos >= currSeq.litLength + currSeq.matchLength) { + currPos -= currSeq.litLength + currSeq.matchLength; + rawSeqStore->pos++; + } else { + rawSeqStore->posInSequence = currPos; + break; + } + } + if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) { + rawSeqStore->posInSequence = 0; + } +} + +size_t ZSTD_ldm_blockCompress(RawSeqStore_t* rawSeqStore, + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + ZSTD_ParamSwitch_e useRowMatchFinder, + void const* src, size_t srcSize) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + unsigned const minMatch = cParams->minMatch; + ZSTD_BlockCompressor_f const blockCompressor = + ZSTD_selectBlockCompressor(cParams->strategy, useRowMatchFinder, ZSTD_matchState_dictMode(ms)); + /* Input bounds */ + BYTE const* const istart = (BYTE const*)src; + BYTE const* const iend = istart + srcSize; + /* Input positions */ + BYTE const* ip = istart; + + DEBUGLOG(5, "ZSTD_ldm_blockCompress: srcSize=%zu", srcSize); + /* If using opt parser, use LDMs only as candidates rather than always accepting them */ + if (cParams->strategy >= ZSTD_btopt) { + size_t lastLLSize; + ms->ldmSeqStore = rawSeqStore; + lastLLSize = blockCompressor(ms, seqStore, rep, src, srcSize); + ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore, srcSize); + return lastLLSize; + } + + assert(rawSeqStore->pos <= rawSeqStore->size); + assert(rawSeqStore->size <= rawSeqStore->capacity); + /* Loop through each sequence and apply the block compressor to the literals */ + while (rawSeqStore->pos < rawSeqStore->size && ip < iend) { + /* maybeSplitSequence updates rawSeqStore->pos */ + rawSeq const sequence = maybeSplitSequence(rawSeqStore, + (U32)(iend - ip), minMatch); + /* End signal */ + if (sequence.offset == 0) + break; + + assert(ip + sequence.litLength + sequence.matchLength <= iend); + + /* Fill tables for block compressor */ + ZSTD_ldm_limitTableUpdate(ms, ip); + ZSTD_ldm_fillFastTables(ms, ip); + /* Run the block compressor */ + DEBUGLOG(5, "pos %u : calling block compressor on segment of size %u", (unsigned)(ip-istart), sequence.litLength); + { + int i; + size_t const newLitLength = + blockCompressor(ms, seqStore, rep, ip, sequence.litLength); + ip += sequence.litLength; + /* Update the repcodes */ + for (i = ZSTD_REP_NUM - 1; i > 0; i--) + rep[i] = rep[i-1]; + rep[0] = sequence.offset; + /* Store the sequence */ + ZSTD_storeSeq(seqStore, newLitLength, ip - newLitLength, iend, + OFFSET_TO_OFFBASE(sequence.offset), + sequence.matchLength); + ip += sequence.matchLength; + } + } + /* Fill the tables for the block compressor */ + ZSTD_ldm_limitTableUpdate(ms, ip); + ZSTD_ldm_fillFastTables(ms, ip); + /* Compress the last literals */ + return blockCompressor(ms, seqStore, rep, ip, iend - ip); +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_ldm.h b/src/commonlib/bsd/zstd/compress/zstd_ldm.h new file mode 100644 index 00000000000..d69c3648ceb --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_ldm.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_LDM_H +#define ZSTD_LDM_H + +#include "zstd_compress_internal.h" /* ldmParams_t, U32 */ +#include "../zstd.h" /* ZSTD_CCtx, size_t */ + +/*-************************************* +* Long distance matching +***************************************/ + +#define ZSTD_LDM_DEFAULT_WINDOW_LOG ZSTD_WINDOWLOG_LIMIT_DEFAULT + +void ZSTD_ldm_fillHashTable( + ldmState_t* state, const BYTE* ip, + const BYTE* iend, ldmParams_t const* params); + +/** + * ZSTD_ldm_generateSequences(): + * + * Generates the sequences using the long distance match finder. + * Generates long range matching sequences in `sequences`, which parse a prefix + * of the source. `sequences` must be large enough to store every sequence, + * which can be checked with `ZSTD_ldm_getMaxNbSeq()`. + * @returns 0 or an error code. + * + * NOTE: The user must have called ZSTD_window_update() for all of the input + * they have, even if they pass it to ZSTD_ldm_generateSequences() in chunks. + * NOTE: This function returns an error if it runs out of space to store + * sequences. + */ +size_t ZSTD_ldm_generateSequences( + ldmState_t* ldms, RawSeqStore_t* sequences, + ldmParams_t const* params, void const* src, size_t srcSize); + +/** + * ZSTD_ldm_blockCompress(): + * + * Compresses a block using the predefined sequences, along with a secondary + * block compressor. The literals section of every sequence is passed to the + * secondary block compressor, and those sequences are interspersed with the + * predefined sequences. Returns the length of the last literals. + * Updates `rawSeqStore.pos` to indicate how many sequences have been consumed. + * `rawSeqStore.seq` may also be updated to split the last sequence between two + * blocks. + * @return The length of the last literals. + * + * NOTE: The source must be at most the maximum block size, but the predefined + * sequences can be any size, and may be longer than the block. In the case that + * they are longer than the block, the last sequences may need to be split into + * two. We handle that case correctly, and update `rawSeqStore` appropriately. + * NOTE: This function does not return any errors. + */ +size_t ZSTD_ldm_blockCompress(RawSeqStore_t* rawSeqStore, + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + ZSTD_ParamSwitch_e useRowMatchFinder, + void const* src, size_t srcSize); + +/** + * ZSTD_ldm_skipSequences(): + * + * Skip past `srcSize` bytes worth of sequences in `rawSeqStore`. + * Avoids emitting matches less than `minMatch` bytes. + * Must be called for data that is not passed to ZSTD_ldm_blockCompress(). + */ +void ZSTD_ldm_skipSequences(RawSeqStore_t* rawSeqStore, size_t srcSize, + U32 const minMatch); + +/* ZSTD_ldm_skipRawSeqStoreBytes(): + * Moves forward in rawSeqStore by nbBytes, updating fields 'pos' and 'posInSequence'. + * Not to be used in conjunction with ZSTD_ldm_skipSequences(). + * Must be called for data with is not passed to ZSTD_ldm_blockCompress(). + */ +void ZSTD_ldm_skipRawSeqStoreBytes(RawSeqStore_t* rawSeqStore, size_t nbBytes); + +/** ZSTD_ldm_getTableSize() : + * Estimate the space needed for long distance matching tables or 0 if LDM is + * disabled. + */ +size_t ZSTD_ldm_getTableSize(ldmParams_t params); + +/** ZSTD_ldm_getSeqSpace() : + * Return an upper bound on the number of sequences that can be produced by + * the long distance matcher, or 0 if LDM is disabled. + */ +size_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize); + +/** ZSTD_ldm_adjustParameters() : + * If the params->hashRateLog is not set, set it to its default value based on + * windowLog and params->hashLog. + * + * Ensures that params->bucketSizeLog is <= params->hashLog (setting it to + * params->hashLog if it is not). + * + * Ensures that the minMatchLength >= targetLength during optimal parsing. + */ +void ZSTD_ldm_adjustParameters(ldmParams_t* params, + ZSTD_compressionParameters const* cParams); + +#endif /* ZSTD_FAST_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_ldm_geartab.h b/src/commonlib/bsd/zstd/compress/zstd_ldm_geartab.h new file mode 100644 index 00000000000..be292bb256f --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_ldm_geartab.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_LDM_GEARTAB_H +#define ZSTD_LDM_GEARTAB_H + +#include "../common/zstd_compiler.h" /* UNUSED_ATTR */ +#include "../common/mem.h" /* U64 */ + +static UNUSED_ATTR const U64 ZSTD_ldm_gearTab[256] = { + 0xf5b8f72c5f77775c, 0x84935f266b7ac412, 0xb647ada9ca730ccc, + 0xb065bb4b114fb1de, 0x34584e7e8c3a9fd0, 0x4e97e17c6ae26b05, + 0x3a03d743bc99a604, 0xcecd042422c4044f, 0x76de76c58524259e, + 0x9c8528f65badeaca, 0x86563706e2097529, 0x2902475fa375d889, + 0xafb32a9739a5ebe6, 0xce2714da3883e639, 0x21eaf821722e69e, + 0x37b628620b628, 0x49a8d455d88caf5, 0x8556d711e6958140, + 0x4f7ae74fc605c1f, 0x829f0c3468bd3a20, 0x4ffdc885c625179e, + 0x8473de048a3daf1b, 0x51008822b05646b2, 0x69d75d12b2d1cc5f, + 0x8c9d4a19159154bc, 0xc3cc10f4abbd4003, 0xd06ddc1cecb97391, + 0xbe48e6e7ed80302e, 0x3481db31cee03547, 0xacc3f67cdaa1d210, + 0x65cb771d8c7f96cc, 0x8eb27177055723dd, 0xc789950d44cd94be, + 0x934feadc3700b12b, 0x5e485f11edbdf182, 0x1e2e2a46fd64767a, + 0x2969ca71d82efa7c, 0x9d46e9935ebbba2e, 0xe056b67e05e6822b, + 0x94d73f55739d03a0, 0xcd7010bdb69b5a03, 0x455ef9fcd79b82f4, + 0x869cb54a8749c161, 0x38d1a4fa6185d225, 0xb475166f94bbe9bb, + 0xa4143548720959f1, 0x7aed4780ba6b26ba, 0xd0ce264439e02312, + 0x84366d746078d508, 0xa8ce973c72ed17be, 0x21c323a29a430b01, + 0x9962d617e3af80ee, 0xab0ce91d9c8cf75b, 0x530e8ee6d19a4dbc, + 0x2ef68c0cf53f5d72, 0xc03a681640a85506, 0x496e4e9f9c310967, + 0x78580472b59b14a0, 0x273824c23b388577, 0x66bf923ad45cb553, + 0x47ae1a5a2492ba86, 0x35e304569e229659, 0x4765182a46870b6f, + 0x6cbab625e9099412, 0xddac9a2e598522c1, 0x7172086e666624f2, + 0xdf5003ca503b7837, 0x88c0c1db78563d09, 0x58d51865acfc289d, + 0x177671aec65224f1, 0xfb79d8a241e967d7, 0x2be1e101cad9a49a, + 0x6625682f6e29186b, 0x399553457ac06e50, 0x35dffb4c23abb74, + 0x429db2591f54aade, 0xc52802a8037d1009, 0x6acb27381f0b25f3, + 0xf45e2551ee4f823b, 0x8b0ea2d99580c2f7, 0x3bed519cbcb4e1e1, + 0xff452823dbb010a, 0x9d42ed614f3dd267, 0x5b9313c06257c57b, + 0xa114b8008b5e1442, 0xc1fe311c11c13d4b, 0x66e8763ea34c5568, + 0x8b982af1c262f05d, 0xee8876faaa75fbb7, 0x8a62a4d0d172bb2a, + 0xc13d94a3b7449a97, 0x6dbbba9dc15d037c, 0xc786101f1d92e0f1, + 0xd78681a907a0b79b, 0xf61aaf2962c9abb9, 0x2cfd16fcd3cb7ad9, + 0x868c5b6744624d21, 0x25e650899c74ddd7, 0xba042af4a7c37463, + 0x4eb1a539465a3eca, 0xbe09dbf03b05d5ca, 0x774e5a362b5472ba, + 0x47a1221229d183cd, 0x504b0ca18ef5a2df, 0xdffbdfbde2456eb9, + 0x46cd2b2fbee34634, 0xf2aef8fe819d98c3, 0x357f5276d4599d61, + 0x24a5483879c453e3, 0x88026889192b4b9, 0x28da96671782dbec, + 0x4ef37c40588e9aaa, 0x8837b90651bc9fb3, 0xc164f741d3f0e5d6, + 0xbc135a0a704b70ba, 0x69cd868f7622ada, 0xbc37ba89e0b9c0ab, + 0x47c14a01323552f6, 0x4f00794bacee98bb, 0x7107de7d637a69d5, + 0x88af793bb6f2255e, 0xf3c6466b8799b598, 0xc288c616aa7f3b59, + 0x81ca63cf42fca3fd, 0x88d85ace36a2674b, 0xd056bd3792389e7, + 0xe55c396c4e9dd32d, 0xbefb504571e6c0a6, 0x96ab32115e91e8cc, + 0xbf8acb18de8f38d1, 0x66dae58801672606, 0x833b6017872317fb, + 0xb87c16f2d1c92864, 0xdb766a74e58b669c, 0x89659f85c61417be, + 0xc8daad856011ea0c, 0x76a4b565b6fe7eae, 0xa469d085f6237312, + 0xaaf0365683a3e96c, 0x4dbb746f8424f7b8, 0x638755af4e4acc1, + 0x3d7807f5bde64486, 0x17be6d8f5bbb7639, 0x903f0cd44dc35dc, + 0x67b672eafdf1196c, 0xa676ff93ed4c82f1, 0x521d1004c5053d9d, + 0x37ba9ad09ccc9202, 0x84e54d297aacfb51, 0xa0b4b776a143445, + 0x820d471e20b348e, 0x1874383cb83d46dc, 0x97edeec7a1efe11c, + 0xb330e50b1bdc42aa, 0x1dd91955ce70e032, 0xa514cdb88f2939d5, + 0x2791233fd90db9d3, 0x7b670a4cc50f7a9b, 0x77c07d2a05c6dfa5, + 0xe3778b6646d0a6fa, 0xb39c8eda47b56749, 0x933ed448addbef28, + 0xaf846af6ab7d0bf4, 0xe5af208eb666e49, 0x5e6622f73534cd6a, + 0x297daeca42ef5b6e, 0x862daef3d35539a6, 0xe68722498f8e1ea9, + 0x981c53093dc0d572, 0xfa09b0bfbf86fbf5, 0x30b1e96166219f15, + 0x70e7d466bdc4fb83, 0x5a66736e35f2a8e9, 0xcddb59d2b7c1baef, + 0xd6c7d247d26d8996, 0xea4e39eac8de1ba3, 0x539c8bb19fa3aff2, + 0x9f90e4c5fd508d8, 0xa34e5956fbaf3385, 0x2e2f8e151d3ef375, + 0x173691e9b83faec1, 0xb85a8d56bf016379, 0x8382381267408ae3, + 0xb90f901bbdc0096d, 0x7c6ad32933bcec65, 0x76bb5e2f2c8ad595, + 0x390f851a6cf46d28, 0xc3e6064da1c2da72, 0xc52a0c101cfa5389, + 0xd78eaf84a3fbc530, 0x3781b9e2288b997e, 0x73c2f6dea83d05c4, + 0x4228e364c5b5ed7, 0x9d7a3edf0da43911, 0x8edcfeda24686756, + 0x5e7667a7b7a9b3a1, 0x4c4f389fa143791d, 0xb08bc1023da7cddc, + 0x7ab4be3ae529b1cc, 0x754e6132dbe74ff9, 0x71635442a839df45, + 0x2f6fb1643fbe52de, 0x961e0a42cf7a8177, 0xf3b45d83d89ef2ea, + 0xee3de4cf4a6e3e9b, 0xcd6848542c3295e7, 0xe4cee1664c78662f, + 0x9947548b474c68c4, 0x25d73777a5ed8b0b, 0xc915b1d636b7fc, + 0x21c2ba75d9b0d2da, 0x5f6b5dcf608a64a1, 0xdcf333255ff9570c, + 0x633b922418ced4ee, 0xc136dde0b004b34a, 0x58cc83b05d4b2f5a, + 0x5eb424dda28e42d2, 0x62df47369739cd98, 0xb4e0b42485e4ce17, + 0x16e1f0c1f9a8d1e7, 0x8ec3916707560ebf, 0x62ba6e2df2cc9db3, + 0xcbf9f4ff77d83a16, 0x78d9d7d07d2bbcc4, 0xef554ce1e02c41f4, + 0x8d7581127eccf94d, 0xa9b53336cb3c8a05, 0x38c42c0bf45c4f91, + 0x640893cdf4488863, 0x80ec34bc575ea568, 0x39f324f5b48eaa40, + 0xe9d9ed1f8eff527f, 0x9224fc058cc5a214, 0xbaba00b04cfe7741, + 0x309a9f120fcf52af, 0xa558f3ec65626212, 0x424bec8b7adabe2f, + 0x41622513a6aea433, 0xb88da2d5324ca798, 0xd287733b245528a4, + 0x9a44697e6d68aec3, 0x7b1093be2f49bb28, 0x50bbec632e3d8aad, + 0x6cd90723e1ea8283, 0x897b9e7431b02bf3, 0x219efdcb338a7047, + 0x3b0311f0a27c0656, 0xdb17bf91c0db96e7, 0x8cd4fd6b4e85a5b2, + 0xfab071054ba6409d, 0x40d6fe831fa9dfd9, 0xaf358debad7d791e, + 0xeb8d0e25a65e3e58, 0xbbcbd3df14e08580, 0xcf751f27ecdab2b, + 0x2b4da14f2613d8f4 +}; + +#endif /* ZSTD_LDM_GEARTAB_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_opt.c b/src/commonlib/bsd/zstd/compress/zstd_opt.c new file mode 100644 index 00000000000..519091b82dd --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_opt.c @@ -0,0 +1,1582 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "zstd_compress_internal.h" +#include "hist.h" +#include "zstd_opt.h" + +#if !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) + +#define ZSTD_LITFREQ_ADD 2 /* scaling factor for litFreq, so that frequencies adapt faster to new stats */ +#define ZSTD_MAX_PRICE (1<<30) + +#define ZSTD_PREDEF_THRESHOLD 8 /* if srcSize < ZSTD_PREDEF_THRESHOLD, symbols' cost is assumed static, directly determined by pre-defined distributions */ + + +/*-************************************* +* Price functions for optimal parser +***************************************/ + +#if 0 /* approximation at bit level (for tests) */ +# define BITCOST_ACCURACY 0 +# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) +# define WEIGHT(stat, opt) ((void)(opt), ZSTD_bitWeight(stat)) +#elif 0 /* fractional bit accuracy (for tests) */ +# define BITCOST_ACCURACY 8 +# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) +# define WEIGHT(stat,opt) ((void)(opt), ZSTD_fracWeight(stat)) +#else /* opt==approx, ultra==accurate */ +# define BITCOST_ACCURACY 8 +# define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY) +# define WEIGHT(stat,opt) ((opt) ? ZSTD_fracWeight(stat) : ZSTD_bitWeight(stat)) +#endif + +/* ZSTD_bitWeight() : + * provide estimated "cost" of a stat in full bits only */ +MEM_STATIC U32 ZSTD_bitWeight(U32 stat) +{ + return (ZSTD_highbit32(stat+1) * BITCOST_MULTIPLIER); +} + +/* ZSTD_fracWeight() : + * provide fractional-bit "cost" of a stat, + * using linear interpolation approximation */ +MEM_STATIC U32 ZSTD_fracWeight(U32 rawStat) +{ + U32 const stat = rawStat + 1; + U32 const hb = ZSTD_highbit32(stat); + U32 const BWeight = hb * BITCOST_MULTIPLIER; + /* Fweight was meant for "Fractional weight" + * but it's effectively a value between 1 and 2 + * using fixed point arithmetic */ + U32 const FWeight = (stat << BITCOST_ACCURACY) >> hb; + U32 const weight = BWeight + FWeight; + assert(hb + BITCOST_ACCURACY < 31); + return weight; +} + +#if (DEBUGLEVEL>=2) +/* debugging function, + * @return price in bytes as fractional value + * for debug messages only */ +MEM_STATIC double ZSTD_fCost(int price) +{ + return (double)price / (BITCOST_MULTIPLIER*8); +} +#endif + +static int ZSTD_compressedLiterals(optState_t const* const optPtr) +{ + return optPtr->literalCompressionMode != ZSTD_ps_disable; +} + +static void ZSTD_setBasePrices(optState_t* optPtr, int optLevel) +{ + if (ZSTD_compressedLiterals(optPtr)) + optPtr->litSumBasePrice = WEIGHT(optPtr->litSum, optLevel); + optPtr->litLengthSumBasePrice = WEIGHT(optPtr->litLengthSum, optLevel); + optPtr->matchLengthSumBasePrice = WEIGHT(optPtr->matchLengthSum, optLevel); + optPtr->offCodeSumBasePrice = WEIGHT(optPtr->offCodeSum, optLevel); +} + + +static U32 sum_u32(const unsigned table[], size_t nbElts) +{ + size_t n; + U32 total = 0; + for (n=0; n0); + unsigned const newStat = base + (table[s] >> shift); + sum += newStat; + table[s] = newStat; + } + return sum; +} + +/* ZSTD_scaleStats() : + * reduce all elt frequencies in table if sum too large + * return the resulting sum of elements */ +static U32 ZSTD_scaleStats(unsigned* table, U32 lastEltIndex, U32 logTarget) +{ + U32 const prevsum = sum_u32(table, lastEltIndex+1); + U32 const factor = prevsum >> logTarget; + DEBUGLOG(5, "ZSTD_scaleStats (nbElts=%u, target=%u)", (unsigned)lastEltIndex+1, (unsigned)logTarget); + assert(logTarget < 30); + if (factor <= 1) return prevsum; + return ZSTD_downscaleStats(table, lastEltIndex, ZSTD_highbit32(factor), base_1guaranteed); +} + +/* ZSTD_rescaleFreqs() : + * if first block (detected by optPtr->litLengthSum == 0) : init statistics + * take hints from dictionary if there is one + * and init from zero if there is none, + * using src for literals stats, and baseline stats for sequence symbols + * otherwise downscale existing stats, to be used as seed for next block. + */ +static void +ZSTD_rescaleFreqs(optState_t* const optPtr, + const BYTE* const src, size_t const srcSize, + int const optLevel) +{ + int const compressedLiterals = ZSTD_compressedLiterals(optPtr); + DEBUGLOG(5, "ZSTD_rescaleFreqs (srcSize=%u)", (unsigned)srcSize); + optPtr->priceType = zop_dynamic; + + if (optPtr->litLengthSum == 0) { /* no literals stats collected -> first block assumed -> init */ + + /* heuristic: use pre-defined stats for too small inputs */ + if (srcSize <= ZSTD_PREDEF_THRESHOLD) { + DEBUGLOG(5, "srcSize <= %i : use predefined stats", ZSTD_PREDEF_THRESHOLD); + optPtr->priceType = zop_predef; + } + + assert(optPtr->symbolCosts != NULL); + if (optPtr->symbolCosts->huf.repeatMode == HUF_repeat_valid) { + + /* huffman stats covering the full value set : table presumed generated by dictionary */ + optPtr->priceType = zop_dynamic; + + if (compressedLiterals) { + /* generate literals statistics from huffman table */ + unsigned lit; + assert(optPtr->litFreq != NULL); + optPtr->litSum = 0; + for (lit=0; lit<=MaxLit; lit++) { + U32 const scaleLog = 11; /* scale to 2K */ + U32 const bitCost = HUF_getNbBitsFromCTable(optPtr->symbolCosts->huf.CTable, lit); + assert(bitCost <= scaleLog); + optPtr->litFreq[lit] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/; + optPtr->litSum += optPtr->litFreq[lit]; + } } + + { unsigned ll; + FSE_CState_t llstate; + FSE_initCState(&llstate, optPtr->symbolCosts->fse.litlengthCTable); + optPtr->litLengthSum = 0; + for (ll=0; ll<=MaxLL; ll++) { + U32 const scaleLog = 10; /* scale to 1K */ + U32 const bitCost = FSE_getMaxNbBits(llstate.symbolTT, ll); + assert(bitCost < scaleLog); + optPtr->litLengthFreq[ll] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/; + optPtr->litLengthSum += optPtr->litLengthFreq[ll]; + } } + + { unsigned ml; + FSE_CState_t mlstate; + FSE_initCState(&mlstate, optPtr->symbolCosts->fse.matchlengthCTable); + optPtr->matchLengthSum = 0; + for (ml=0; ml<=MaxML; ml++) { + U32 const scaleLog = 10; + U32 const bitCost = FSE_getMaxNbBits(mlstate.symbolTT, ml); + assert(bitCost < scaleLog); + optPtr->matchLengthFreq[ml] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/; + optPtr->matchLengthSum += optPtr->matchLengthFreq[ml]; + } } + + { unsigned of; + FSE_CState_t ofstate; + FSE_initCState(&ofstate, optPtr->symbolCosts->fse.offcodeCTable); + optPtr->offCodeSum = 0; + for (of=0; of<=MaxOff; of++) { + U32 const scaleLog = 10; + U32 const bitCost = FSE_getMaxNbBits(ofstate.symbolTT, of); + assert(bitCost < scaleLog); + optPtr->offCodeFreq[of] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/; + optPtr->offCodeSum += optPtr->offCodeFreq[of]; + } } + + } else { /* first block, no dictionary */ + + assert(optPtr->litFreq != NULL); + if (compressedLiterals) { + /* base initial cost of literals on direct frequency within src */ + unsigned lit = MaxLit; + HIST_count_simple(optPtr->litFreq, &lit, src, srcSize); /* use raw first block to init statistics */ + optPtr->litSum = ZSTD_downscaleStats(optPtr->litFreq, MaxLit, 8, base_0possible); + } + + { unsigned const baseLLfreqs[MaxLL+1] = { + 4, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1 + }; + ZSTD_memcpy(optPtr->litLengthFreq, baseLLfreqs, sizeof(baseLLfreqs)); + optPtr->litLengthSum = sum_u32(baseLLfreqs, MaxLL+1); + } + + { unsigned ml; + for (ml=0; ml<=MaxML; ml++) + optPtr->matchLengthFreq[ml] = 1; + } + optPtr->matchLengthSum = MaxML+1; + + { unsigned const baseOFCfreqs[MaxOff+1] = { + 6, 2, 1, 1, 2, 3, 4, 4, + 4, 3, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 + }; + ZSTD_memcpy(optPtr->offCodeFreq, baseOFCfreqs, sizeof(baseOFCfreqs)); + optPtr->offCodeSum = sum_u32(baseOFCfreqs, MaxOff+1); + } + + } + + } else { /* new block : scale down accumulated statistics */ + + if (compressedLiterals) + optPtr->litSum = ZSTD_scaleStats(optPtr->litFreq, MaxLit, 12); + optPtr->litLengthSum = ZSTD_scaleStats(optPtr->litLengthFreq, MaxLL, 11); + optPtr->matchLengthSum = ZSTD_scaleStats(optPtr->matchLengthFreq, MaxML, 11); + optPtr->offCodeSum = ZSTD_scaleStats(optPtr->offCodeFreq, MaxOff, 11); + } + + ZSTD_setBasePrices(optPtr, optLevel); +} + +/* ZSTD_rawLiteralsCost() : + * price of literals (only) in specified segment (which length can be 0). + * does not include price of literalLength symbol */ +static U32 ZSTD_rawLiteralsCost(const BYTE* const literals, U32 const litLength, + const optState_t* const optPtr, + int optLevel) +{ + DEBUGLOG(8, "ZSTD_rawLiteralsCost (%u literals)", litLength); + if (litLength == 0) return 0; + + if (!ZSTD_compressedLiterals(optPtr)) + return (litLength << 3) * BITCOST_MULTIPLIER; /* Uncompressed - 8 bytes per literal. */ + + if (optPtr->priceType == zop_predef) + return (litLength*6) * BITCOST_MULTIPLIER; /* 6 bit per literal - no statistic used */ + + /* dynamic statistics */ + { U32 price = optPtr->litSumBasePrice * litLength; + U32 const litPriceMax = optPtr->litSumBasePrice - BITCOST_MULTIPLIER; + U32 u; + assert(optPtr->litSumBasePrice >= BITCOST_MULTIPLIER); + for (u=0; u < litLength; u++) { + U32 litPrice = WEIGHT(optPtr->litFreq[literals[u]], optLevel); + if (UNLIKELY(litPrice > litPriceMax)) litPrice = litPriceMax; + price -= litPrice; + } + return price; + } +} + +/* ZSTD_litLengthPrice() : + * cost of literalLength symbol */ +static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optPtr, int optLevel) +{ + assert(litLength <= ZSTD_BLOCKSIZE_MAX); + if (optPtr->priceType == zop_predef) + return WEIGHT(litLength, optLevel); + + /* ZSTD_LLcode() can't compute litLength price for sizes >= ZSTD_BLOCKSIZE_MAX + * because it isn't representable in the zstd format. + * So instead just pretend it would cost 1 bit more than ZSTD_BLOCKSIZE_MAX - 1. + * In such a case, the block would be all literals. + */ + if (litLength == ZSTD_BLOCKSIZE_MAX) + return BITCOST_MULTIPLIER + ZSTD_litLengthPrice(ZSTD_BLOCKSIZE_MAX - 1, optPtr, optLevel); + + /* dynamic statistics */ + { U32 const llCode = ZSTD_LLcode(litLength); + return (LL_bits[llCode] * BITCOST_MULTIPLIER) + + optPtr->litLengthSumBasePrice + - WEIGHT(optPtr->litLengthFreq[llCode], optLevel); + } +} + +/* ZSTD_getMatchPrice() : + * Provides the cost of the match part (offset + matchLength) of a sequence. + * Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence. + * @offBase : sumtype, representing an offset or a repcode, and using numeric representation of ZSTD_storeSeq() + * @optLevel: when <2, favors small offset for decompression speed (improved cache efficiency) + */ +FORCE_INLINE_TEMPLATE U32 +ZSTD_getMatchPrice(U32 const offBase, + U32 const matchLength, + const optState_t* const optPtr, + int const optLevel) +{ + U32 price; + U32 const offCode = ZSTD_highbit32(offBase); + U32 const mlBase = matchLength - MINMATCH; + assert(matchLength >= MINMATCH); + + if (optPtr->priceType == zop_predef) /* fixed scheme, does not use statistics */ + return WEIGHT(mlBase, optLevel) + + ((16 + offCode) * BITCOST_MULTIPLIER); /* emulated offset cost */ + + /* dynamic statistics */ + price = (offCode * BITCOST_MULTIPLIER) + (optPtr->offCodeSumBasePrice - WEIGHT(optPtr->offCodeFreq[offCode], optLevel)); + if ((optLevel<2) /*static*/ && offCode >= 20) + price += (offCode-19)*2 * BITCOST_MULTIPLIER; /* handicap for long distance offsets, favor decompression speed */ + + /* match Length */ + { U32 const mlCode = ZSTD_MLcode(mlBase); + price += (ML_bits[mlCode] * BITCOST_MULTIPLIER) + (optPtr->matchLengthSumBasePrice - WEIGHT(optPtr->matchLengthFreq[mlCode], optLevel)); + } + + price += BITCOST_MULTIPLIER / 5; /* heuristic : make matches a bit more costly to favor less sequences -> faster decompression speed */ + + DEBUGLOG(8, "ZSTD_getMatchPrice(ml:%u) = %u", matchLength, price); + return price; +} + +/* ZSTD_updateStats() : + * assumption : literals + litLength <= iend */ +static void ZSTD_updateStats(optState_t* const optPtr, + U32 litLength, const BYTE* literals, + U32 offBase, U32 matchLength) +{ + /* literals */ + if (ZSTD_compressedLiterals(optPtr)) { + U32 u; + for (u=0; u < litLength; u++) + optPtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD; + optPtr->litSum += litLength*ZSTD_LITFREQ_ADD; + } + + /* literal Length */ + { U32 const llCode = ZSTD_LLcode(litLength); + optPtr->litLengthFreq[llCode]++; + optPtr->litLengthSum++; + } + + /* offset code : follows storeSeq() numeric representation */ + { U32 const offCode = ZSTD_highbit32(offBase); + assert(offCode <= MaxOff); + optPtr->offCodeFreq[offCode]++; + optPtr->offCodeSum++; + } + + /* match Length */ + { U32 const mlBase = matchLength - MINMATCH; + U32 const mlCode = ZSTD_MLcode(mlBase); + optPtr->matchLengthFreq[mlCode]++; + optPtr->matchLengthSum++; + } +} + + +/* ZSTD_readMINMATCH() : + * function safe only for comparisons + * assumption : memPtr must be at least 4 bytes before end of buffer */ +MEM_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length) +{ + switch (length) + { + default : + case 4 : return MEM_read32(memPtr); + case 3 : if (MEM_isLittleEndian()) + return MEM_read32(memPtr)<<8; + else + return MEM_read32(memPtr)>>8; + } +} + + +/* Update hashTable3 up to ip (excluded) + Assumption : always within prefix (i.e. not within extDict) */ +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_insertAndFindFirstIndexHash3 (const ZSTD_MatchState_t* ms, + U32* nextToUpdate3, + const BYTE* const ip) +{ + U32* const hashTable3 = ms->hashTable3; + U32 const hashLog3 = ms->hashLog3; + const BYTE* const base = ms->window.base; + U32 idx = *nextToUpdate3; + U32 const target = (U32)(ip - base); + size_t const hash3 = ZSTD_hash3Ptr(ip, hashLog3); + assert(hashLog3 > 0); + + while(idx < target) { + hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx; + idx++; + } + + *nextToUpdate3 = target; + return hashTable3[hash3]; +} + + +/*-************************************* +* Binary Tree search +***************************************/ +/** ZSTD_insertBt1() : add one or multiple positions to tree. + * @param ip assumed <= iend-8 . + * @param target The target of ZSTD_updateTree_internal() - we are filling to this position + * @return : nb of positions added */ +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_insertBt1( + const ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + U32 const target, + U32 const mls, const int extDict) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32* const hashTable = ms->hashTable; + U32 const hashLog = cParams->hashLog; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask = (1 << btLog) - 1; + U32 matchIndex = hashTable[h]; + size_t commonLengthSmaller=0, commonLengthLarger=0; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const prefixStart = base + dictLimit; + const BYTE* match; + const U32 curr = (U32)(ip-base); + const U32 btLow = btMask >= curr ? 0 : curr - btMask; + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = smallerPtr + 1; + U32 dummy32; /* to be nullified at the end */ + /* windowLow is based on target because + * we only need positions that will be in the window at the end of the tree update. + */ + U32 const windowLow = ZSTD_getLowestMatchIndex(ms, target, cParams->windowLog); + U32 matchEndIdx = curr+8+1; + size_t bestLength = 8; + U32 nbCompares = 1U << cParams->searchLog; +#ifdef ZSTD_C_PREDICT + U32 predictedSmall = *(bt + 2*((curr-1)&btMask) + 0); + U32 predictedLarge = *(bt + 2*((curr-1)&btMask) + 1); + predictedSmall += (predictedSmall>0); + predictedLarge += (predictedLarge>0); +#endif /* ZSTD_C_PREDICT */ + + DEBUGLOG(8, "ZSTD_insertBt1 (%u)", curr); + + assert(curr <= target); + assert(ip <= iend-8); /* required for h calculation */ + hashTable[h] = curr; /* Update Hash Table */ + + assert(windowLow > 0); + for (; nbCompares && (matchIndex >= windowLow); --nbCompares) { + U32* const nextPtr = bt + 2*(matchIndex & btMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + assert(matchIndex < curr); + +#ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */ + const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */ + if (matchIndex == predictedSmall) { + /* no need to check length, result known */ + *smallerPtr = matchIndex; + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + smallerPtr = nextPtr+1; /* new "smaller" => larger of match */ + matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + predictedSmall = predictPtr[1] + (predictPtr[1]>0); + continue; + } + if (matchIndex == predictedLarge) { + *largerPtr = matchIndex; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + predictedLarge = predictPtr[0] + (predictPtr[0]>0); + continue; + } +#endif + + if (!extDict || (matchIndex+matchLength >= dictLimit)) { + assert(matchIndex+matchLength >= dictLimit); /* might be wrong if actually extDict */ + match = base + matchIndex; + matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend); + } else { + match = dictBase + matchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart); + if (matchIndex+matchLength >= dictLimit) + match = base + matchIndex; /* to prepare for next usage of match[matchLength] */ + } + + if (matchLength > bestLength) { + bestLength = matchLength; + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + } + + if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */ + break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */ + } + + if (match[matchLength] < ip[matchLength]) { /* necessarily within buffer */ + /* match is smaller than current */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop searching */ + smallerPtr = nextPtr+1; /* new "candidate" => larger than match, which was smaller than target */ + matchIndex = nextPtr[1]; /* new matchIndex, larger than previous and closer to current */ + } else { + /* match is larger than current */ + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop searching */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } } + + *smallerPtr = *largerPtr = 0; + { U32 positions = 0; + if (bestLength > 384) positions = MIN(192, (U32)(bestLength - 384)); /* speed optimization */ + assert(matchEndIdx > curr + 8); + return MAX(positions, matchEndIdx - (curr + 8)); + } +} + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_updateTree_internal( + ZSTD_MatchState_t* ms, + const BYTE* const ip, const BYTE* const iend, + const U32 mls, const ZSTD_dictMode_e dictMode) +{ + const BYTE* const base = ms->window.base; + U32 const target = (U32)(ip - base); + U32 idx = ms->nextToUpdate; + DEBUGLOG(7, "ZSTD_updateTree_internal, from %u to %u (dictMode:%u)", + idx, target, dictMode); + + while(idx < target) { + U32 const forward = ZSTD_insertBt1(ms, base+idx, iend, target, mls, dictMode == ZSTD_extDict); + assert(idx < (U32)(idx + forward)); + idx += forward; + } + assert((size_t)(ip - base) <= (size_t)(U32)(-1)); + assert((size_t)(iend - base) <= (size_t)(U32)(-1)); + ms->nextToUpdate = target; +} + +void ZSTD_updateTree(ZSTD_MatchState_t* ms, const BYTE* ip, const BYTE* iend) { + ZSTD_updateTree_internal(ms, ip, iend, ms->cParams.minMatch, ZSTD_noDict); +} + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 +ZSTD_insertBtAndGetAllMatches ( + ZSTD_match_t* matches, /* store result (found matches) in this table (presumed large enough) */ + ZSTD_MatchState_t* ms, + U32* nextToUpdate3, + const BYTE* const ip, const BYTE* const iLimit, + const ZSTD_dictMode_e dictMode, + const U32 rep[ZSTD_REP_NUM], + const U32 ll0, /* tells if associated literal length is 0 or not. This value must be 0 or 1 */ + const U32 lengthToBeat, + const U32 mls /* template */) +{ + const ZSTD_compressionParameters* const cParams = &ms->cParams; + U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1); + const BYTE* const base = ms->window.base; + U32 const curr = (U32)(ip-base); + U32 const hashLog = cParams->hashLog; + U32 const minMatch = (mls==3) ? 3 : 4; + U32* const hashTable = ms->hashTable; + size_t const h = ZSTD_hashPtr(ip, hashLog, mls); + U32 matchIndex = hashTable[h]; + U32* const bt = ms->chainTable; + U32 const btLog = cParams->chainLog - 1; + U32 const btMask= (1U << btLog) - 1; + size_t commonLengthSmaller=0, commonLengthLarger=0; + const BYTE* const dictBase = ms->window.dictBase; + U32 const dictLimit = ms->window.dictLimit; + const BYTE* const dictEnd = dictBase + dictLimit; + const BYTE* const prefixStart = base + dictLimit; + U32 const btLow = (btMask >= curr) ? 0 : curr - btMask; + U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog); + U32 const matchLow = windowLow ? windowLow : 1; + U32* smallerPtr = bt + 2*(curr&btMask); + U32* largerPtr = bt + 2*(curr&btMask) + 1; + U32 matchEndIdx = curr+8+1; /* farthest referenced position of any match => detects repetitive patterns */ + U32 dummy32; /* to be nullified at the end */ + U32 mnum = 0; + U32 nbCompares = 1U << cParams->searchLog; + + const ZSTD_MatchState_t* dms = dictMode == ZSTD_dictMatchState ? ms->dictMatchState : NULL; + const ZSTD_compressionParameters* const dmsCParams = + dictMode == ZSTD_dictMatchState ? &dms->cParams : NULL; + const BYTE* const dmsBase = dictMode == ZSTD_dictMatchState ? dms->window.base : NULL; + const BYTE* const dmsEnd = dictMode == ZSTD_dictMatchState ? dms->window.nextSrc : NULL; + U32 const dmsHighLimit = dictMode == ZSTD_dictMatchState ? (U32)(dmsEnd - dmsBase) : 0; + U32 const dmsLowLimit = dictMode == ZSTD_dictMatchState ? dms->window.lowLimit : 0; + U32 const dmsIndexDelta = dictMode == ZSTD_dictMatchState ? windowLow - dmsHighLimit : 0; + U32 const dmsHashLog = dictMode == ZSTD_dictMatchState ? dmsCParams->hashLog : hashLog; + U32 const dmsBtLog = dictMode == ZSTD_dictMatchState ? dmsCParams->chainLog - 1 : btLog; + U32 const dmsBtMask = dictMode == ZSTD_dictMatchState ? (1U << dmsBtLog) - 1 : 0; + U32 const dmsBtLow = dictMode == ZSTD_dictMatchState && dmsBtMask < dmsHighLimit - dmsLowLimit ? dmsHighLimit - dmsBtMask : dmsLowLimit; + + size_t bestLength = lengthToBeat-1; + DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", curr); + + /* check repCode */ + assert(ll0 <= 1); /* necessarily 1 or 0 */ + { U32 const lastR = ZSTD_REP_NUM + ll0; + U32 repCode; + for (repCode = ll0; repCode < lastR; repCode++) { + U32 const repOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode]; + U32 const repIndex = curr - repOffset; + U32 repLen = 0; + assert(curr >= dictLimit); + if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < curr-dictLimit) { /* equivalent to `curr > repIndex >= dictLimit` */ + /* We must validate the repcode offset because when we're using a dictionary the + * valid offset range shrinks when the dictionary goes out of bounds. + */ + if ((repIndex >= windowLow) & (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch))) { + repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch; + } + } else { /* repIndex < dictLimit || repIndex >= curr */ + const BYTE* const repMatch = dictMode == ZSTD_dictMatchState ? + dmsBase + repIndex - dmsIndexDelta : + dictBase + repIndex; + assert(curr >= windowLow); + if ( dictMode == ZSTD_extDict + && ( ((repOffset-1) /*intentional overflow*/ < curr - windowLow) /* equivalent to `curr > repIndex >= windowLow` */ + & (ZSTD_index_overlap_check(dictLimit, repIndex)) ) + && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) { + repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dictEnd, prefixStart) + minMatch; + } + if (dictMode == ZSTD_dictMatchState + && ( ((repOffset-1) /*intentional overflow*/ < curr - (dmsLowLimit + dmsIndexDelta)) /* equivalent to `curr > repIndex >= dmsLowLimit` */ + & (ZSTD_index_overlap_check(dictLimit, repIndex)) ) + && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) { + repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dmsEnd, prefixStart) + minMatch; + } } + /* save longer solution */ + if (repLen > bestLength) { + DEBUGLOG(8, "found repCode %u (ll0:%u, offset:%u) of length %u", + repCode, ll0, repOffset, repLen); + bestLength = repLen; + matches[mnum].off = REPCODE_TO_OFFBASE(repCode - ll0 + 1); /* expect value between 1 and 3 */ + matches[mnum].len = (U32)repLen; + mnum++; + if ( (repLen > sufficient_len) + | (ip+repLen == iLimit) ) { /* best possible */ + return mnum; + } } } } + + /* HC3 match finder */ + if ((mls == 3) /*static*/ && (bestLength < mls)) { + U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, nextToUpdate3, ip); + if ((matchIndex3 >= matchLow) + & (curr - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) { + size_t mlen; + if ((dictMode == ZSTD_noDict) /*static*/ || (dictMode == ZSTD_dictMatchState) /*static*/ || (matchIndex3 >= dictLimit)) { + const BYTE* const match = base + matchIndex3; + mlen = ZSTD_count(ip, match, iLimit); + } else { + const BYTE* const match = dictBase + matchIndex3; + mlen = ZSTD_count_2segments(ip, match, iLimit, dictEnd, prefixStart); + } + + /* save best solution */ + if (mlen >= mls /* == 3 > bestLength */) { + DEBUGLOG(8, "found small match with hlog3, of length %u", + (U32)mlen); + bestLength = mlen; + assert(curr > matchIndex3); + assert(mnum==0); /* no prior solution */ + matches[0].off = OFFSET_TO_OFFBASE(curr - matchIndex3); + matches[0].len = (U32)mlen; + mnum = 1; + if ( (mlen > sufficient_len) | + (ip+mlen == iLimit) ) { /* best possible length */ + ms->nextToUpdate = curr+1; /* skip insertion */ + return 1; + } } } + /* no dictMatchState lookup: dicts don't have a populated HC3 table */ + } /* if (mls == 3) */ + + hashTable[h] = curr; /* Update Hash Table */ + + for (; nbCompares && (matchIndex >= matchLow); --nbCompares) { + U32* const nextPtr = bt + 2*(matchIndex & btMask); + const BYTE* match; + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + assert(curr > matchIndex); + + if ((dictMode == ZSTD_noDict) || (dictMode == ZSTD_dictMatchState) || (matchIndex+matchLength >= dictLimit)) { + assert(matchIndex+matchLength >= dictLimit); /* ensure the condition is correct when !extDict */ + match = base + matchIndex; + if (matchIndex >= dictLimit) assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */ + matchLength += ZSTD_count(ip+matchLength, match+matchLength, iLimit); + } else { + match = dictBase + matchIndex; + assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */ + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart); + if (matchIndex+matchLength >= dictLimit) + match = base + matchIndex; /* prepare for match[matchLength] read */ + } + + if (matchLength > bestLength) { + DEBUGLOG(8, "found match of length %u at distance %u (offBase=%u)", + (U32)matchLength, curr - matchIndex, OFFSET_TO_OFFBASE(curr - matchIndex)); + assert(matchEndIdx > matchIndex); + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + bestLength = matchLength; + matches[mnum].off = OFFSET_TO_OFFBASE(curr - matchIndex); + matches[mnum].len = (U32)matchLength; + mnum++; + if ( (matchLength > ZSTD_OPT_NUM) + | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) { + if (dictMode == ZSTD_dictMatchState) nbCompares = 0; /* break should also skip searching dms */ + break; /* drop, to preserve bt consistency (miss a little bit of compression) */ + } } + + if (match[matchLength] < ip[matchLength]) { + /* match smaller than current */ + *smallerPtr = matchIndex; /* update smaller idx */ + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + smallerPtr = nextPtr+1; /* new candidate => larger than match, which was smaller than current */ + matchIndex = nextPtr[1]; /* new matchIndex, larger than previous, closer to current */ + } else { + *largerPtr = matchIndex; + commonLengthLarger = matchLength; + if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */ + largerPtr = nextPtr; + matchIndex = nextPtr[0]; + } } + + *smallerPtr = *largerPtr = 0; + + assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */ + if (dictMode == ZSTD_dictMatchState && nbCompares) { + size_t const dmsH = ZSTD_hashPtr(ip, dmsHashLog, mls); + U32 dictMatchIndex = dms->hashTable[dmsH]; + const U32* const dmsBt = dms->chainTable; + commonLengthSmaller = commonLengthLarger = 0; + for (; nbCompares && (dictMatchIndex > dmsLowLimit); --nbCompares) { + const U32* const nextPtr = dmsBt + 2*(dictMatchIndex & dmsBtMask); + size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */ + const BYTE* match = dmsBase + dictMatchIndex; + matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dmsEnd, prefixStart); + if (dictMatchIndex+matchLength >= dmsHighLimit) + match = base + dictMatchIndex + dmsIndexDelta; /* to prepare for next usage of match[matchLength] */ + + if (matchLength > bestLength) { + matchIndex = dictMatchIndex + dmsIndexDelta; + DEBUGLOG(8, "found dms match of length %u at distance %u (offBase=%u)", + (U32)matchLength, curr - matchIndex, OFFSET_TO_OFFBASE(curr - matchIndex)); + if (matchLength > matchEndIdx - matchIndex) + matchEndIdx = matchIndex + (U32)matchLength; + bestLength = matchLength; + matches[mnum].off = OFFSET_TO_OFFBASE(curr - matchIndex); + matches[mnum].len = (U32)matchLength; + mnum++; + if ( (matchLength > ZSTD_OPT_NUM) + | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) { + break; /* drop, to guarantee consistency (miss a little bit of compression) */ + } } + + if (dictMatchIndex <= dmsBtLow) { break; } /* beyond tree size, stop the search */ + if (match[matchLength] < ip[matchLength]) { + commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */ + dictMatchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */ + } else { + /* match is larger than current */ + commonLengthLarger = matchLength; + dictMatchIndex = nextPtr[0]; + } } } /* if (dictMode == ZSTD_dictMatchState) */ + + assert(matchEndIdx > curr+8); + ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */ + return mnum; +} + +typedef U32 (*ZSTD_getAllMatchesFn)( + ZSTD_match_t*, + ZSTD_MatchState_t*, + U32*, + const BYTE*, + const BYTE*, + const U32 rep[ZSTD_REP_NUM], + U32 const ll0, + U32 const lengthToBeat); + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +U32 ZSTD_btGetAllMatches_internal( + ZSTD_match_t* matches, + ZSTD_MatchState_t* ms, + U32* nextToUpdate3, + const BYTE* ip, + const BYTE* const iHighLimit, + const U32 rep[ZSTD_REP_NUM], + U32 const ll0, + U32 const lengthToBeat, + const ZSTD_dictMode_e dictMode, + const U32 mls) +{ + assert(BOUNDED(3, ms->cParams.minMatch, 6) == mls); + DEBUGLOG(8, "ZSTD_BtGetAllMatches(dictMode=%d, mls=%u)", (int)dictMode, mls); + if (ip < ms->window.base + ms->nextToUpdate) + return 0; /* skipped area */ + ZSTD_updateTree_internal(ms, ip, iHighLimit, mls, dictMode); + return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, mls); +} + +#define ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls) ZSTD_btGetAllMatches_##dictMode##_##mls + +#define GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, mls) \ + static U32 ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls)( \ + ZSTD_match_t* matches, \ + ZSTD_MatchState_t* ms, \ + U32* nextToUpdate3, \ + const BYTE* ip, \ + const BYTE* const iHighLimit, \ + const U32 rep[ZSTD_REP_NUM], \ + U32 const ll0, \ + U32 const lengthToBeat) \ + { \ + return ZSTD_btGetAllMatches_internal( \ + matches, ms, nextToUpdate3, ip, iHighLimit, \ + rep, ll0, lengthToBeat, ZSTD_##dictMode, mls); \ + } + +#define GEN_ZSTD_BT_GET_ALL_MATCHES(dictMode) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 3) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 4) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 5) \ + GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 6) + +GEN_ZSTD_BT_GET_ALL_MATCHES(noDict) +GEN_ZSTD_BT_GET_ALL_MATCHES(extDict) +GEN_ZSTD_BT_GET_ALL_MATCHES(dictMatchState) + +#define ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMode) \ + { \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 3), \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 4), \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 5), \ + ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 6) \ + } + +static ZSTD_getAllMatchesFn +ZSTD_selectBtGetAllMatches(ZSTD_MatchState_t const* ms, ZSTD_dictMode_e const dictMode) +{ + ZSTD_getAllMatchesFn const getAllMatchesFns[3][4] = { + ZSTD_BT_GET_ALL_MATCHES_ARRAY(noDict), + ZSTD_BT_GET_ALL_MATCHES_ARRAY(extDict), + ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMatchState) + }; + U32 const mls = BOUNDED(3, ms->cParams.minMatch, 6); + assert((U32)dictMode < 3); + assert(mls - 3 < 4); + return getAllMatchesFns[(int)dictMode][mls - 3]; +} + +/************************* +* LDM helper functions * +*************************/ + +/* Struct containing info needed to make decision about ldm inclusion */ +typedef struct { + RawSeqStore_t seqStore; /* External match candidates store for this block */ + U32 startPosInBlock; /* Start position of the current match candidate */ + U32 endPosInBlock; /* End position of the current match candidate */ + U32 offset; /* Offset of the match candidate */ +} ZSTD_optLdm_t; + +/* ZSTD_optLdm_skipRawSeqStoreBytes(): + * Moves forward in @rawSeqStore by @nbBytes, + * which will update the fields 'pos' and 'posInSequence'. + */ +static void ZSTD_optLdm_skipRawSeqStoreBytes(RawSeqStore_t* rawSeqStore, size_t nbBytes) +{ + U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes); + while (currPos && rawSeqStore->pos < rawSeqStore->size) { + rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos]; + if (currPos >= currSeq.litLength + currSeq.matchLength) { + currPos -= currSeq.litLength + currSeq.matchLength; + rawSeqStore->pos++; + } else { + rawSeqStore->posInSequence = currPos; + break; + } + } + if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) { + rawSeqStore->posInSequence = 0; + } +} + +/* ZSTD_opt_getNextMatchAndUpdateSeqStore(): + * Calculates the beginning and end of the next match in the current block. + * Updates 'pos' and 'posInSequence' of the ldmSeqStore. + */ +static void +ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 currPosInBlock, + U32 blockBytesRemaining) +{ + rawSeq currSeq; + U32 currBlockEndPos; + U32 literalsBytesRemaining; + U32 matchBytesRemaining; + + /* Setting match end position to MAX to ensure we never use an LDM during this block */ + if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) { + optLdm->startPosInBlock = UINT_MAX; + optLdm->endPosInBlock = UINT_MAX; + return; + } + /* Calculate appropriate bytes left in matchLength and litLength + * after adjusting based on ldmSeqStore->posInSequence */ + currSeq = optLdm->seqStore.seq[optLdm->seqStore.pos]; + assert(optLdm->seqStore.posInSequence <= currSeq.litLength + currSeq.matchLength); + currBlockEndPos = currPosInBlock + blockBytesRemaining; + literalsBytesRemaining = (optLdm->seqStore.posInSequence < currSeq.litLength) ? + currSeq.litLength - (U32)optLdm->seqStore.posInSequence : + 0; + matchBytesRemaining = (literalsBytesRemaining == 0) ? + currSeq.matchLength - ((U32)optLdm->seqStore.posInSequence - currSeq.litLength) : + currSeq.matchLength; + + /* If there are more literal bytes than bytes remaining in block, no ldm is possible */ + if (literalsBytesRemaining >= blockBytesRemaining) { + optLdm->startPosInBlock = UINT_MAX; + optLdm->endPosInBlock = UINT_MAX; + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, blockBytesRemaining); + return; + } + + /* Matches may be < minMatch by this process. In that case, we will reject them + when we are deciding whether or not to add the ldm */ + optLdm->startPosInBlock = currPosInBlock + literalsBytesRemaining; + optLdm->endPosInBlock = optLdm->startPosInBlock + matchBytesRemaining; + optLdm->offset = currSeq.offset; + + if (optLdm->endPosInBlock > currBlockEndPos) { + /* Match ends after the block ends, we can't use the whole match */ + optLdm->endPosInBlock = currBlockEndPos; + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, currBlockEndPos - currPosInBlock); + } else { + /* Consume nb of bytes equal to size of sequence left */ + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, literalsBytesRemaining + matchBytesRemaining); + } +} + +/* ZSTD_optLdm_maybeAddMatch(): + * Adds a match if it's long enough, + * based on it's 'matchStartPosInBlock' and 'matchEndPosInBlock', + * into 'matches'. Maintains the correct ordering of 'matches'. + */ +static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches, + const ZSTD_optLdm_t* optLdm, U32 currPosInBlock, + U32 minMatch) +{ + U32 const posDiff = currPosInBlock - optLdm->startPosInBlock; + /* Note: ZSTD_match_t actually contains offBase and matchLength (before subtracting MINMATCH) */ + U32 const candidateMatchLength = optLdm->endPosInBlock - optLdm->startPosInBlock - posDiff; + + /* Ensure that current block position is not outside of the match */ + if (currPosInBlock < optLdm->startPosInBlock + || currPosInBlock >= optLdm->endPosInBlock + || candidateMatchLength < minMatch) { + return; + } + + if (*nbMatches == 0 || ((candidateMatchLength > matches[*nbMatches-1].len) && *nbMatches < ZSTD_OPT_NUM)) { + U32 const candidateOffBase = OFFSET_TO_OFFBASE(optLdm->offset); + DEBUGLOG(6, "ZSTD_optLdm_maybeAddMatch(): Adding ldm candidate match (offBase: %u matchLength %u) at block position=%u", + candidateOffBase, candidateMatchLength, currPosInBlock); + matches[*nbMatches].len = candidateMatchLength; + matches[*nbMatches].off = candidateOffBase; + (*nbMatches)++; + } +} + +/* ZSTD_optLdm_processMatchCandidate(): + * Wrapper function to update ldm seq store and call ldm functions as necessary. + */ +static void +ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm, + ZSTD_match_t* matches, U32* nbMatches, + U32 currPosInBlock, U32 remainingBytes, + U32 minMatch) +{ + if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) { + return; + } + + if (currPosInBlock >= optLdm->endPosInBlock) { + if (currPosInBlock > optLdm->endPosInBlock) { + /* The position at which ZSTD_optLdm_processMatchCandidate() is called is not necessarily + * at the end of a match from the ldm seq store, and will often be some bytes + * over beyond matchEndPosInBlock. As such, we need to correct for these "overshoots" + */ + U32 const posOvershoot = currPosInBlock - optLdm->endPosInBlock; + ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, posOvershoot); + } + ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes); + } + ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock, minMatch); +} + + +/*-******************************* +* Optimal parser +*********************************/ + +#if 0 /* debug */ + +static void +listStats(const U32* table, int lastEltID) +{ + int const nbElts = lastEltID + 1; + int enb; + for (enb=0; enb < nbElts; enb++) { + (void)table; + /* RAWLOG(2, "%3i:%3i, ", enb, table[enb]); */ + RAWLOG(2, "%4i,", table[enb]); + } + RAWLOG(2, " \n"); +} + +#endif + +#define LIT_PRICE(_p) (int)ZSTD_rawLiteralsCost(_p, 1, optStatePtr, optLevel) +#define LL_PRICE(_l) (int)ZSTD_litLengthPrice(_l, optStatePtr, optLevel) +#define LL_INCPRICE(_l) (LL_PRICE(_l) - LL_PRICE(_l-1)) + +FORCE_INLINE_TEMPLATE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t +ZSTD_compressBlock_opt_generic(ZSTD_MatchState_t* ms, + SeqStore_t* seqStore, + U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, + const int optLevel, + const ZSTD_dictMode_e dictMode) +{ + optState_t* const optStatePtr = &ms->opt; + const BYTE* const istart = (const BYTE*)src; + const BYTE* ip = istart; + const BYTE* anchor = istart; + const BYTE* const iend = istart + srcSize; + const BYTE* const ilimit = iend - 8; + const BYTE* const base = ms->window.base; + const BYTE* const prefixStart = base + ms->window.dictLimit; + const ZSTD_compressionParameters* const cParams = &ms->cParams; + + ZSTD_getAllMatchesFn getAllMatches = ZSTD_selectBtGetAllMatches(ms, dictMode); + + U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1); + U32 const minMatch = (cParams->minMatch == 3) ? 3 : 4; + U32 nextToUpdate3 = ms->nextToUpdate; + + ZSTD_optimal_t* const opt = optStatePtr->priceTable; + ZSTD_match_t* const matches = optStatePtr->matchTable; + ZSTD_optimal_t lastStretch; + ZSTD_optLdm_t optLdm; + + ZSTD_memset(&lastStretch, 0, sizeof(ZSTD_optimal_t)); + + optLdm.seqStore = ms->ldmSeqStore ? *ms->ldmSeqStore : kNullRawSeqStore; + optLdm.endPosInBlock = optLdm.startPosInBlock = optLdm.offset = 0; + ZSTD_opt_getNextMatchAndUpdateSeqStore(&optLdm, (U32)(ip-istart), (U32)(iend-ip)); + + /* init */ + DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u", + (U32)(ip - base), ms->window.dictLimit, ms->nextToUpdate); + assert(optLevel <= 2); + ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize, optLevel); + ip += (ip==prefixStart); + + /* Match Loop */ + while (ip < ilimit) { + U32 cur, last_pos = 0; + + /* find first match */ + { U32 const litlen = (U32)(ip - anchor); + U32 const ll0 = !litlen; + U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, ip, iend, rep, ll0, minMatch); + ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches, + (U32)(ip-istart), (U32)(iend-ip), + minMatch); + if (!nbMatches) { + DEBUGLOG(8, "no match found at cPos %u", (unsigned)(ip-istart)); + ip++; + continue; + } + + /* Match found: let's store this solution, and eventually find more candidates. + * During this forward pass, @opt is used to store stretches, + * defined as "a match followed by N literals". + * Note how this is different from a Sequence, which is "N literals followed by a match". + * Storing stretches allows us to store different match predecessors + * for each literal position part of a literals run. */ + + /* initialize opt[0] */ + opt[0].mlen = 0; /* there are only literals so far */ + opt[0].litlen = litlen; + /* No need to include the actual price of the literals before the first match + * because it is static for the duration of the forward pass, and is included + * in every subsequent price. But, we include the literal length because + * the cost variation of litlen depends on the value of litlen. + */ + opt[0].price = LL_PRICE(litlen); + ZSTD_STATIC_ASSERT(sizeof(opt[0].rep[0]) == sizeof(rep[0])); + ZSTD_memcpy(&opt[0].rep, rep, sizeof(opt[0].rep)); + + /* large match -> immediate encoding */ + { U32 const maxML = matches[nbMatches-1].len; + U32 const maxOffBase = matches[nbMatches-1].off; + DEBUGLOG(6, "found %u matches of maxLength=%u and maxOffBase=%u at cPos=%u => start new series", + nbMatches, maxML, maxOffBase, (U32)(ip-prefixStart)); + + if (maxML > sufficient_len) { + lastStretch.litlen = 0; + lastStretch.mlen = maxML; + lastStretch.off = maxOffBase; + DEBUGLOG(6, "large match (%u>%u) => immediate encoding", + maxML, sufficient_len); + cur = 0; + last_pos = maxML; + goto _shortestPath; + } } + + /* set prices for first matches starting position == 0 */ + assert(opt[0].price >= 0); + { U32 pos; + U32 matchNb; + for (pos = 1; pos < minMatch; pos++) { + opt[pos].price = ZSTD_MAX_PRICE; + opt[pos].mlen = 0; + opt[pos].litlen = litlen + pos; + } + for (matchNb = 0; matchNb < nbMatches; matchNb++) { + U32 const offBase = matches[matchNb].off; + U32 const end = matches[matchNb].len; + for ( ; pos <= end ; pos++ ) { + int const matchPrice = (int)ZSTD_getMatchPrice(offBase, pos, optStatePtr, optLevel); + int const sequencePrice = opt[0].price + matchPrice; + DEBUGLOG(7, "rPos:%u => set initial price : %.2f", + pos, ZSTD_fCost(sequencePrice)); + opt[pos].mlen = pos; + opt[pos].off = offBase; + opt[pos].litlen = 0; /* end of match */ + opt[pos].price = sequencePrice + LL_PRICE(0); + } + } + last_pos = pos-1; + opt[pos].price = ZSTD_MAX_PRICE; + } + } + + /* check further positions */ + for (cur = 1; cur <= last_pos; cur++) { + const BYTE* const inr = ip + cur; + assert(cur <= ZSTD_OPT_NUM); + DEBUGLOG(7, "cPos:%i==rPos:%u", (int)(inr-istart), cur); + + /* Fix current position with one literal if cheaper */ + { U32 const litlen = opt[cur-1].litlen + 1; + int const price = opt[cur-1].price + + LIT_PRICE(ip+cur-1) + + LL_INCPRICE(litlen); + assert(price < 1000000000); /* overflow check */ + if (price <= opt[cur].price) { + ZSTD_optimal_t const prevMatch = opt[cur]; + DEBUGLOG(7, "cPos:%i==rPos:%u : better price (%.2f<=%.2f) using literal (ll==%u) (hist:%u,%u,%u)", + (int)(inr-istart), cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price), litlen, + opt[cur-1].rep[0], opt[cur-1].rep[1], opt[cur-1].rep[2]); + opt[cur] = opt[cur-1]; + opt[cur].litlen = litlen; + opt[cur].price = price; + if ( (optLevel >= 1) /* additional check only for higher modes */ + && (prevMatch.litlen == 0) /* replace a match */ + && (LL_INCPRICE(1) < 0) /* ll1 is cheaper than ll0 */ + && LIKELY(ip + cur < iend) + ) { + /* check next position, in case it would be cheaper */ + int with1literal = prevMatch.price + LIT_PRICE(ip+cur) + LL_INCPRICE(1); + int withMoreLiterals = price + LIT_PRICE(ip+cur) + LL_INCPRICE(litlen+1); + DEBUGLOG(7, "then at next rPos %u : match+1lit %.2f vs %ulits %.2f", + cur+1, ZSTD_fCost(with1literal), litlen+1, ZSTD_fCost(withMoreLiterals)); + if ( (with1literal < withMoreLiterals) + && (with1literal < opt[cur+1].price) ) { + /* update offset history - before it disappears */ + U32 const prev = cur - prevMatch.mlen; + Repcodes_t const newReps = ZSTD_newRep(opt[prev].rep, prevMatch.off, opt[prev].litlen==0); + assert(cur >= prevMatch.mlen); + DEBUGLOG(7, "==> match+1lit is cheaper (%.2f < %.2f) (hist:%u,%u,%u) !", + ZSTD_fCost(with1literal), ZSTD_fCost(withMoreLiterals), + newReps.rep[0], newReps.rep[1], newReps.rep[2] ); + opt[cur+1] = prevMatch; /* mlen & offbase */ + ZSTD_memcpy(opt[cur+1].rep, &newReps, sizeof(Repcodes_t)); + opt[cur+1].litlen = 1; + opt[cur+1].price = with1literal; + if (last_pos < cur+1) last_pos = cur+1; + } + } + } else { + DEBUGLOG(7, "cPos:%i==rPos:%u : literal would cost more (%.2f>%.2f)", + (int)(inr-istart), cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price)); + } + } + + /* Offset history is not updated during match comparison. + * Do it here, now that the match is selected and confirmed. + */ + ZSTD_STATIC_ASSERT(sizeof(opt[cur].rep) == sizeof(Repcodes_t)); + assert(cur >= opt[cur].mlen); + if (opt[cur].litlen == 0) { + /* just finished a match => alter offset history */ + U32 const prev = cur - opt[cur].mlen; + Repcodes_t const newReps = ZSTD_newRep(opt[prev].rep, opt[cur].off, opt[prev].litlen==0); + ZSTD_memcpy(opt[cur].rep, &newReps, sizeof(Repcodes_t)); + } + + /* last match must start at a minimum distance of 8 from oend */ + if (inr > ilimit) continue; + + if (cur == last_pos) break; + + if ( (optLevel==0) /*static_test*/ + && (opt[cur+1].price <= opt[cur].price + (BITCOST_MULTIPLIER/2)) ) { + DEBUGLOG(7, "skip current position : next rPos(%u) price is cheaper", cur+1); + continue; /* skip unpromising positions; about ~+6% speed, -0.01 ratio */ + } + + assert(opt[cur].price >= 0); + { U32 const ll0 = (opt[cur].litlen == 0); + int const previousPrice = opt[cur].price; + int const basePrice = previousPrice + LL_PRICE(0); + U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, inr, iend, opt[cur].rep, ll0, minMatch); + U32 matchNb; + + ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches, + (U32)(inr-istart), (U32)(iend-inr), + minMatch); + + if (!nbMatches) { + DEBUGLOG(7, "rPos:%u : no match found", cur); + continue; + } + + { U32 const longestML = matches[nbMatches-1].len; + DEBUGLOG(7, "cPos:%i==rPos:%u, found %u matches, of longest ML=%u", + (int)(inr-istart), cur, nbMatches, longestML); + + if ( (longestML > sufficient_len) + || (cur + longestML >= ZSTD_OPT_NUM) + || (ip + cur + longestML >= iend) ) { + lastStretch.mlen = longestML; + lastStretch.off = matches[nbMatches-1].off; + lastStretch.litlen = 0; + last_pos = cur + longestML; + goto _shortestPath; + } } + + /* set prices using matches found at position == cur */ + for (matchNb = 0; matchNb < nbMatches; matchNb++) { + U32 const offset = matches[matchNb].off; + U32 const lastML = matches[matchNb].len; + U32 const startML = (matchNb>0) ? matches[matchNb-1].len+1 : minMatch; + U32 mlen; + + DEBUGLOG(7, "testing match %u => offBase=%4u, mlen=%2u, llen=%2u", + matchNb, matches[matchNb].off, lastML, opt[cur].litlen); + + for (mlen = lastML; mlen >= startML; mlen--) { /* scan downward */ + U32 const pos = cur + mlen; + int const price = basePrice + (int)ZSTD_getMatchPrice(offset, mlen, optStatePtr, optLevel); + + if ((pos > last_pos) || (price < opt[pos].price)) { + DEBUGLOG(7, "rPos:%u (ml=%2u) => new better price (%.2f<%.2f)", + pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price)); + while (last_pos < pos) { + /* fill empty positions, for future comparisons */ + last_pos++; + opt[last_pos].price = ZSTD_MAX_PRICE; + opt[last_pos].litlen = !0; /* just needs to be != 0, to mean "not an end of match" */ + } + opt[pos].mlen = mlen; + opt[pos].off = offset; + opt[pos].litlen = 0; + opt[pos].price = price; + } else { + DEBUGLOG(7, "rPos:%u (ml=%2u) => new price is worse (%.2f>=%.2f)", + pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price)); + if (optLevel==0) break; /* early update abort; gets ~+10% speed for about -0.01 ratio loss */ + } + } } } + opt[last_pos+1].price = ZSTD_MAX_PRICE; + } /* for (cur = 1; cur <= last_pos; cur++) */ + + lastStretch = opt[last_pos]; + assert(cur >= lastStretch.mlen); + cur = last_pos - lastStretch.mlen; + +_shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */ + assert(opt[0].mlen == 0); + assert(last_pos >= lastStretch.mlen); + assert(cur == last_pos - lastStretch.mlen); + + if (lastStretch.mlen==0) { + /* no solution : all matches have been converted into literals */ + assert(lastStretch.litlen == (ip - anchor) + last_pos); + ip += last_pos; + continue; + } + assert(lastStretch.off > 0); + + /* Update offset history */ + if (lastStretch.litlen == 0) { + /* finishing on a match : update offset history */ + Repcodes_t const reps = ZSTD_newRep(opt[cur].rep, lastStretch.off, opt[cur].litlen==0); + ZSTD_memcpy(rep, &reps, sizeof(Repcodes_t)); + } else { + ZSTD_memcpy(rep, lastStretch.rep, sizeof(Repcodes_t)); + assert(cur >= lastStretch.litlen); + cur -= lastStretch.litlen; + } + + /* Let's write the shortest path solution. + * It is stored in @opt in reverse order, + * starting from @storeEnd (==cur+2), + * effectively partially @opt overwriting. + * Content is changed too: + * - So far, @opt stored stretches, aka a match followed by literals + * - Now, it will store sequences, aka literals followed by a match + */ + { U32 const storeEnd = cur + 2; + U32 storeStart = storeEnd; + U32 stretchPos = cur; + + DEBUGLOG(6, "start reverse traversal (last_pos:%u, cur:%u)", + last_pos, cur); (void)last_pos; + assert(storeEnd < ZSTD_OPT_SIZE); + DEBUGLOG(6, "last stretch copied into pos=%u (llen=%u,mlen=%u,ofc=%u)", + storeEnd, lastStretch.litlen, lastStretch.mlen, lastStretch.off); + if (lastStretch.litlen > 0) { + /* last "sequence" is unfinished: just a bunch of literals */ + opt[storeEnd].litlen = lastStretch.litlen; + opt[storeEnd].mlen = 0; + storeStart = storeEnd-1; + opt[storeStart] = lastStretch; + } { + opt[storeEnd] = lastStretch; /* note: litlen will be fixed */ + storeStart = storeEnd; + } + while (1) { + ZSTD_optimal_t nextStretch = opt[stretchPos]; + opt[storeStart].litlen = nextStretch.litlen; + DEBUGLOG(6, "selected sequence (llen=%u,mlen=%u,ofc=%u)", + opt[storeStart].litlen, opt[storeStart].mlen, opt[storeStart].off); + if (nextStretch.mlen == 0) { + /* reaching beginning of segment */ + break; + } + storeStart--; + opt[storeStart] = nextStretch; /* note: litlen will be fixed */ + assert(nextStretch.litlen + nextStretch.mlen <= stretchPos); + stretchPos -= nextStretch.litlen + nextStretch.mlen; + } + + /* save sequences */ + DEBUGLOG(6, "sending selected sequences into seqStore"); + { U32 storePos; + for (storePos=storeStart; storePos <= storeEnd; storePos++) { + U32 const llen = opt[storePos].litlen; + U32 const mlen = opt[storePos].mlen; + U32 const offBase = opt[storePos].off; + U32 const advance = llen + mlen; + DEBUGLOG(6, "considering seq starting at %i, llen=%u, mlen=%u", + (int)(anchor - istart), (unsigned)llen, (unsigned)mlen); + + if (mlen==0) { /* only literals => must be last "sequence", actually starting a new stream of sequences */ + assert(storePos == storeEnd); /* must be last sequence */ + ip = anchor + llen; /* last "sequence" is a bunch of literals => don't progress anchor */ + continue; /* will finish */ + } + + assert(anchor + llen <= iend); + ZSTD_updateStats(optStatePtr, llen, anchor, offBase, mlen); + ZSTD_storeSeq(seqStore, llen, anchor, iend, offBase, mlen); + anchor += advance; + ip = anchor; + } } + DEBUGLOG(7, "new offset history : %u, %u, %u", rep[0], rep[1], rep[2]); + + /* update all costs */ + ZSTD_setBasePrices(optStatePtr, optLevel); + } + } /* while (ip < ilimit) */ + + /* Return the last literals size */ + return (size_t)(iend - anchor); +} +#endif /* build exclusions */ + +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR +static size_t ZSTD_compressBlock_opt0( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode) +{ + return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /* optLevel */, dictMode); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +static size_t ZSTD_compressBlock_opt2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode) +{ + return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /* optLevel */, dictMode); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btopt( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_compressBlock_btopt"); + return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_noDict); +} +#endif + + + + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +/* ZSTD_initStats_ultra(): + * make a first compression pass, just to seed stats with more accurate starting values. + * only works on first block, with no dictionary and no ldm. + * this function cannot error out, its narrow contract must be respected. + */ +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_initStats_ultra(ZSTD_MatchState_t* ms, + SeqStore_t* seqStore, + U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + U32 tmpRep[ZSTD_REP_NUM]; /* updated rep codes will sink here */ + ZSTD_memcpy(tmpRep, rep, sizeof(tmpRep)); + + DEBUGLOG(4, "ZSTD_initStats_ultra (srcSize=%zu)", srcSize); + assert(ms->opt.litLengthSum == 0); /* first block */ + assert(seqStore->sequences == seqStore->sequencesStart); /* no ldm */ + assert(ms->window.dictLimit == ms->window.lowLimit); /* no dictionary */ + assert(ms->window.dictLimit - ms->nextToUpdate <= 1); /* no prefix (note: intentional overflow, defined as 2-complement) */ + + ZSTD_compressBlock_opt2(ms, seqStore, tmpRep, src, srcSize, ZSTD_noDict); /* generate stats into ms->opt*/ + + /* invalidate first scan from history, only keep entropy stats */ + ZSTD_resetSeqStore(seqStore); + ms->window.base -= srcSize; + ms->window.dictLimit += (U32)srcSize; + ms->window.lowLimit = ms->window.dictLimit; + ms->nextToUpdate = ms->window.dictLimit; + +} + +size_t ZSTD_compressBlock_btultra( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_compressBlock_btultra (srcSize=%zu)", srcSize); + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict); +} + +size_t ZSTD_compressBlock_btultra2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + U32 const curr = (U32)((const BYTE*)src - ms->window.base); + DEBUGLOG(5, "ZSTD_compressBlock_btultra2 (srcSize=%zu)", srcSize); + + /* 2-passes strategy: + * this strategy makes a first pass over first block to collect statistics + * in order to seed next round's statistics with it. + * After 1st pass, function forgets history, and starts a new block. + * Consequently, this can only work if no data has been previously loaded in tables, + * aka, no dictionary, no prefix, no ldm preprocessing. + * The compression ratio gain is generally small (~0.5% on first block), + * the cost is 2x cpu time on first block. */ + assert(srcSize <= ZSTD_BLOCKSIZE_MAX); + if ( (ms->opt.litLengthSum==0) /* first block */ + && (seqStore->sequences == seqStore->sequencesStart) /* no ldm */ + && (ms->window.dictLimit == ms->window.lowLimit) /* no dictionary */ + && (curr == ms->window.dictLimit) /* start of frame, nothing already loaded nor skipped */ + && (srcSize > ZSTD_PREDEF_THRESHOLD) /* input large enough to not employ default stats */ + ) { + ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize); + } + + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btopt_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_btopt_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_extDict); +} +#endif + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btultra_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState); +} + +size_t ZSTD_compressBlock_btultra_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + const void* src, size_t srcSize) +{ + return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_extDict); +} +#endif + +/* note : no btultra2 variant for extDict nor dictMatchState, + * because btultra2 is not meant to work with dictionaries + * and is only specific for the first block (no prefix) */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_opt.h b/src/commonlib/bsd/zstd/compress/zstd_opt.h new file mode 100644 index 00000000000..365c0a573ea --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_opt.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_OPT_H +#define ZSTD_OPT_H + +#include "zstd_compress_internal.h" + +#if !defined(ZSTD_EXCLUDE_BTLAZY2_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \ + || !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR) +/* used in ZSTD_loadDictionaryContent() */ +void ZSTD_updateTree(ZSTD_MatchState_t* ms, const BYTE* ip, const BYTE* iend); +#endif + +#ifndef ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btopt( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btopt_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btopt_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_BTOPT ZSTD_compressBlock_btopt +#define ZSTD_COMPRESSBLOCK_BTOPT_DICTMATCHSTATE ZSTD_compressBlock_btopt_dictMatchState +#define ZSTD_COMPRESSBLOCK_BTOPT_EXTDICT ZSTD_compressBlock_btopt_extDict +#else +#define ZSTD_COMPRESSBLOCK_BTOPT NULL +#define ZSTD_COMPRESSBLOCK_BTOPT_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_BTOPT_EXTDICT NULL +#endif + +#ifndef ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR +size_t ZSTD_compressBlock_btultra( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btultra_dictMatchState( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); +size_t ZSTD_compressBlock_btultra_extDict( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + + /* note : no btultra2 variant for extDict nor dictMatchState, + * because btultra2 is not meant to work with dictionaries + * and is only specific for the first block (no prefix) */ +size_t ZSTD_compressBlock_btultra2( + ZSTD_MatchState_t* ms, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], + void const* src, size_t srcSize); + +#define ZSTD_COMPRESSBLOCK_BTULTRA ZSTD_compressBlock_btultra +#define ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE ZSTD_compressBlock_btultra_dictMatchState +#define ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT ZSTD_compressBlock_btultra_extDict +#define ZSTD_COMPRESSBLOCK_BTULTRA2 ZSTD_compressBlock_btultra2 +#else +#define ZSTD_COMPRESSBLOCK_BTULTRA NULL +#define ZSTD_COMPRESSBLOCK_BTULTRA_DICTMATCHSTATE NULL +#define ZSTD_COMPRESSBLOCK_BTULTRA_EXTDICT NULL +#define ZSTD_COMPRESSBLOCK_BTULTRA2 NULL +#endif + +#endif /* ZSTD_OPT_H */ diff --git a/src/commonlib/bsd/zstd/compress/zstd_preSplit.c b/src/commonlib/bsd/zstd/compress/zstd_preSplit.c new file mode 100644 index 00000000000..b4a2a738e52 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_preSplit.c @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#include "../common/zstd_compiler.h" /* ZSTD_ALIGNOF */ +#include "../common/mem.h" /* S64 */ +#include "../common/zstd_deps.h" /* ZSTD_memset */ +#include "../common/zstd_internal.h" /* ZSTD_STATIC_ASSERT */ +#include "hist.h" /* HIST_add */ +#include "zstd_preSplit.h" + + +#define BLOCKSIZE_MIN 3500 +#define THRESHOLD_PENALTY_RATE 16 +#define THRESHOLD_BASE (THRESHOLD_PENALTY_RATE - 2) +#define THRESHOLD_PENALTY 3 + +#define HASHLENGTH 2 +#define HASHLOG_MAX 10 +#define HASHTABLESIZE (1 << HASHLOG_MAX) +#define HASHMASK (HASHTABLESIZE - 1) +#define KNUTH 0x9e3779b9 + +/* for hashLog > 8, hash 2 bytes. + * for hashLog == 8, just take the byte, no hashing. + * The speed of this method relies on compile-time constant propagation */ +FORCE_INLINE_TEMPLATE unsigned hash2(const void *p, unsigned hashLog) +{ + assert(hashLog >= 8); + if (hashLog == 8) return (U32)((const BYTE*)p)[0]; + assert(hashLog <= HASHLOG_MAX); + return (U32)(MEM_read16(p)) * KNUTH >> (32 - hashLog); +} + + +typedef struct { + unsigned events[HASHTABLESIZE]; + size_t nbEvents; +} Fingerprint; +typedef struct { + Fingerprint pastEvents; + Fingerprint newEvents; +} FPStats; + +static void initStats(FPStats* fpstats) +{ + ZSTD_memset(fpstats, 0, sizeof(FPStats)); +} + +FORCE_INLINE_TEMPLATE void +addEvents_generic(Fingerprint* fp, const void* src, size_t srcSize, size_t samplingRate, unsigned hashLog) +{ + const char* p = (const char*)src; + size_t limit = srcSize - HASHLENGTH + 1; + size_t n; + assert(srcSize >= HASHLENGTH); + for (n = 0; n < limit; n+=samplingRate) { + fp->events[hash2(p+n, hashLog)]++; + } + fp->nbEvents += limit/samplingRate; +} + +FORCE_INLINE_TEMPLATE void +recordFingerprint_generic(Fingerprint* fp, const void* src, size_t srcSize, size_t samplingRate, unsigned hashLog) +{ + ZSTD_memset(fp, 0, sizeof(unsigned) * ((size_t)1 << hashLog)); + fp->nbEvents = 0; + addEvents_generic(fp, src, srcSize, samplingRate, hashLog); +} + +typedef void (*RecordEvents_f)(Fingerprint* fp, const void* src, size_t srcSize); + +#define FP_RECORD(_rate) ZSTD_recordFingerprint_##_rate + +#define ZSTD_GEN_RECORD_FINGERPRINT(_rate, _hSize) \ + static void FP_RECORD(_rate)(Fingerprint* fp, const void* src, size_t srcSize) \ + { \ + recordFingerprint_generic(fp, src, srcSize, _rate, _hSize); \ + } + +ZSTD_GEN_RECORD_FINGERPRINT(1, 10) +ZSTD_GEN_RECORD_FINGERPRINT(5, 10) +ZSTD_GEN_RECORD_FINGERPRINT(11, 9) +ZSTD_GEN_RECORD_FINGERPRINT(43, 8) + + +static U64 abs64(S64 s64) { return (U64)((s64 < 0) ? -s64 : s64); } + +static U64 fpDistance(const Fingerprint* fp1, const Fingerprint* fp2, unsigned hashLog) +{ + U64 distance = 0; + size_t n; + assert(hashLog <= HASHLOG_MAX); + for (n = 0; n < ((size_t)1 << hashLog); n++) { + distance += + abs64((S64)fp1->events[n] * (S64)fp2->nbEvents - (S64)fp2->events[n] * (S64)fp1->nbEvents); + } + return distance; +} + +/* Compare newEvents with pastEvents + * return 1 when considered "too different" + */ +static int compareFingerprints(const Fingerprint* ref, + const Fingerprint* newfp, + int penalty, + unsigned hashLog) +{ + assert(ref->nbEvents > 0); + assert(newfp->nbEvents > 0); + { U64 p50 = (U64)ref->nbEvents * (U64)newfp->nbEvents; + U64 deviation = fpDistance(ref, newfp, hashLog); + U64 threshold = p50 * (U64)(THRESHOLD_BASE + penalty) / THRESHOLD_PENALTY_RATE; + return deviation >= threshold; + } +} + +static void mergeEvents(Fingerprint* acc, const Fingerprint* newfp) +{ + size_t n; + for (n = 0; n < HASHTABLESIZE; n++) { + acc->events[n] += newfp->events[n]; + } + acc->nbEvents += newfp->nbEvents; +} + +static void flushEvents(FPStats* fpstats) +{ + size_t n; + for (n = 0; n < HASHTABLESIZE; n++) { + fpstats->pastEvents.events[n] = fpstats->newEvents.events[n]; + } + fpstats->pastEvents.nbEvents = fpstats->newEvents.nbEvents; + ZSTD_memset(&fpstats->newEvents, 0, sizeof(fpstats->newEvents)); +} + +static void removeEvents(Fingerprint* acc, const Fingerprint* slice) +{ + size_t n; + for (n = 0; n < HASHTABLESIZE; n++) { + assert(acc->events[n] >= slice->events[n]); + acc->events[n] -= slice->events[n]; + } + acc->nbEvents -= slice->nbEvents; +} + +#define CHUNKSIZE (8 << 10) +static size_t ZSTD_splitBlock_byChunks(const void* blockStart, size_t blockSize, + int level, + void* workspace, size_t wkspSize) +{ + static const RecordEvents_f records_fs[] = { + FP_RECORD(43), FP_RECORD(11), FP_RECORD(5), FP_RECORD(1) + }; + static const unsigned hashParams[] = { 8, 9, 10, 10 }; + const RecordEvents_f record_f = (assert(0<=level && level<=3), records_fs[level]); + FPStats* const fpstats = (FPStats*)workspace; + const char* p = (const char*)blockStart; + int penalty = THRESHOLD_PENALTY; + size_t pos = 0; + assert(blockSize == (128 << 10)); + assert(workspace != NULL); + assert((size_t)workspace % ZSTD_ALIGNOF(FPStats) == 0); + ZSTD_STATIC_ASSERT(ZSTD_SLIPBLOCK_WORKSPACESIZE >= sizeof(FPStats)); + assert(wkspSize >= sizeof(FPStats)); (void)wkspSize; + + initStats(fpstats); + record_f(&fpstats->pastEvents, p, CHUNKSIZE); + for (pos = CHUNKSIZE; pos <= blockSize - CHUNKSIZE; pos += CHUNKSIZE) { + record_f(&fpstats->newEvents, p + pos, CHUNKSIZE); + if (compareFingerprints(&fpstats->pastEvents, &fpstats->newEvents, penalty, hashParams[level])) { + return pos; + } else { + mergeEvents(&fpstats->pastEvents, &fpstats->newEvents); + if (penalty > 0) penalty--; + } + } + assert(pos == blockSize); + return blockSize; + (void)flushEvents; (void)removeEvents; +} + +/* ZSTD_splitBlock_fromBorders(): very fast strategy : + * compare fingerprint from beginning and end of the block, + * derive from their difference if it's preferable to split in the middle, + * repeat the process a second time, for finer grained decision. + * 3 times did not brought improvements, so I stopped at 2. + * Benefits are good enough for a cheap heuristic. + * More accurate splitting saves more, but speed impact is also more perceptible. + * For better accuracy, use more elaborate variant *_byChunks. + */ +static size_t ZSTD_splitBlock_fromBorders(const void* blockStart, size_t blockSize, + void* workspace, size_t wkspSize) +{ +#define SEGMENT_SIZE 512 + FPStats* const fpstats = (FPStats*)workspace; + Fingerprint* middleEvents = (Fingerprint*)(void*)((char*)workspace + 512 * sizeof(unsigned)); + assert(blockSize == (128 << 10)); + assert(workspace != NULL); + assert((size_t)workspace % ZSTD_ALIGNOF(FPStats) == 0); + ZSTD_STATIC_ASSERT(ZSTD_SLIPBLOCK_WORKSPACESIZE >= sizeof(FPStats)); + assert(wkspSize >= sizeof(FPStats)); (void)wkspSize; + + initStats(fpstats); + HIST_add(fpstats->pastEvents.events, blockStart, SEGMENT_SIZE); + HIST_add(fpstats->newEvents.events, (const char*)blockStart + blockSize - SEGMENT_SIZE, SEGMENT_SIZE); + fpstats->pastEvents.nbEvents = fpstats->newEvents.nbEvents = SEGMENT_SIZE; + if (!compareFingerprints(&fpstats->pastEvents, &fpstats->newEvents, 0, 8)) + return blockSize; + + HIST_add(middleEvents->events, (const char*)blockStart + blockSize/2 - SEGMENT_SIZE/2, SEGMENT_SIZE); + middleEvents->nbEvents = SEGMENT_SIZE; + { U64 const distFromBegin = fpDistance(&fpstats->pastEvents, middleEvents, 8); + U64 const distFromEnd = fpDistance(&fpstats->newEvents, middleEvents, 8); + U64 const minDistance = SEGMENT_SIZE * SEGMENT_SIZE / 3; + if (abs64((S64)distFromBegin - (S64)distFromEnd) < minDistance) + return 64 KB; + return (distFromBegin > distFromEnd) ? 32 KB : 96 KB; + } +} + +size_t ZSTD_splitBlock(const void* blockStart, size_t blockSize, + int level, + void* workspace, size_t wkspSize) +{ + DEBUGLOG(6, "ZSTD_splitBlock (level=%i)", level); + assert(0<=level && level<=4); + if (level == 0) + return ZSTD_splitBlock_fromBorders(blockStart, blockSize, workspace, wkspSize); + /* level >= 1*/ + return ZSTD_splitBlock_byChunks(blockStart, blockSize, level-1, workspace, wkspSize); +} diff --git a/src/commonlib/bsd/zstd/compress/zstd_preSplit.h b/src/commonlib/bsd/zstd/compress/zstd_preSplit.h new file mode 100644 index 00000000000..3adda529fa6 --- /dev/null +++ b/src/commonlib/bsd/zstd/compress/zstd_preSplit.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_PRESPLIT_H +#define ZSTD_PRESPLIT_H + +#include /* size_t */ + +#define ZSTD_SLIPBLOCK_WORKSPACESIZE 8208 + +/* ZSTD_splitBlock(): + * @level must be a value between 0 and 4. + * higher levels spend more energy to detect block boundaries. + * @workspace must be aligned for size_t. + * @wkspSize must be at least >= ZSTD_SLIPBLOCK_WORKSPACESIZE + * note: + * For the time being, this function only accepts full 128 KB blocks. + * Therefore, @blockSize must be == 128 KB. + * While this could be extended to smaller sizes in the future, + * it is not yet clear if this would be useful. TBD. + */ +size_t ZSTD_splitBlock(const void* blockStart, size_t blockSize, + int level, + void* workspace, size_t wkspSize); + +#endif /* ZSTD_PRESPLIT_H */ diff --git a/src/commonlib/bsd/zstd/decompress/huf_decompress.c b/src/commonlib/bsd/zstd/decompress/huf_decompress.c new file mode 100644 index 00000000000..2248ba8deb6 --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/huf_decompress.c @@ -0,0 +1,1946 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* ****************************************************************** + * huff0 huffman decoder, + * part of Finite State Entropy library + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * You can contact the author at : + * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. +****************************************************************** */ + +/* ************************************************************** +* Dependencies +****************************************************************/ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */ +#include "../common/zstd_compiler.h" +#include "../common/bitstream.h" /* BIT_* */ +#include "../common/fse.h" /* to compress headers */ +#include "../common/huf.h" +#include "../common/error_private.h" +#include "../common/zstd_internal.h" +#include "../common/zstd_bits.h" /* ZSTD_highbit32, ZSTD_countTrailingZeros64 */ + +/* ************************************************************** +* Constants +****************************************************************/ + +#define HUF_DECODER_FAST_TABLELOG 11 + +/* ************************************************************** +* Macros +****************************************************************/ + +#ifdef HUF_DISABLE_FAST_DECODE +# define HUF_ENABLE_FAST_DECODE 0 +#else +# define HUF_ENABLE_FAST_DECODE 1 +#endif + +/* These two optional macros force the use one way or another of the two + * Huffman decompression implementations. You can't force in both directions + * at the same time. + */ +#if defined(HUF_FORCE_DECOMPRESS_X1) && \ + defined(HUF_FORCE_DECOMPRESS_X2) +#error "Cannot force the use of the X1 and X2 decoders at the same time!" +#endif + +/* When DYNAMIC_BMI2 is enabled, fast decoders are only called when bmi2 is + * supported at runtime, so we can add the BMI2 target attribute. + * When it is disabled, we will still get BMI2 if it is enabled statically. + */ +#if DYNAMIC_BMI2 +# define HUF_FAST_BMI2_ATTRS BMI2_TARGET_ATTRIBUTE +#else +# define HUF_FAST_BMI2_ATTRS +#endif + +#ifdef __cplusplus +# define HUF_EXTERN_C extern "C" +#else +# define HUF_EXTERN_C +#endif +#define HUF_ASM_DECL HUF_EXTERN_C + +#if DYNAMIC_BMI2 +# define HUF_NEED_BMI2_FUNCTION 1 +#else +# define HUF_NEED_BMI2_FUNCTION 0 +#endif + +/* ************************************************************** +* Error Management +****************************************************************/ +#define HUF_isError ERR_isError + + +/* ************************************************************** +* Byte alignment for workSpace management +****************************************************************/ +#define HUF_ALIGN(x, a) HUF_ALIGN_MASK((x), (a) - 1) +#define HUF_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) + + +/* ************************************************************** +* BMI2 Variant Wrappers +****************************************************************/ +typedef size_t (*HUF_DecompressUsingDTableFn)(void *dst, size_t dstSize, + const void *cSrc, + size_t cSrcSize, + const HUF_DTable *DTable); + +#if DYNAMIC_BMI2 + +#define HUF_DGEN(fn) \ + \ + static size_t fn##_default( \ + void* dst, size_t dstSize, \ + const void* cSrc, size_t cSrcSize, \ + const HUF_DTable* DTable) \ + { \ + return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ + } \ + \ + static BMI2_TARGET_ATTRIBUTE size_t fn##_bmi2( \ + void* dst, size_t dstSize, \ + const void* cSrc, size_t cSrcSize, \ + const HUF_DTable* DTable) \ + { \ + return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ + } \ + \ + static size_t fn(void* dst, size_t dstSize, void const* cSrc, \ + size_t cSrcSize, HUF_DTable const* DTable, int flags) \ + { \ + if (flags & HUF_flags_bmi2) { \ + return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable); \ + } \ + return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable); \ + } + +#else + +#define HUF_DGEN(fn) \ + static size_t fn(void* dst, size_t dstSize, void const* cSrc, \ + size_t cSrcSize, HUF_DTable const* DTable, int flags) \ + { \ + (void)flags; \ + return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \ + } + +#endif + + +/*-***************************/ +/* generic DTableDesc */ +/*-***************************/ +typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc; + +static DTableDesc HUF_getDTableDesc(const HUF_DTable* table) +{ + DTableDesc dtd; + ZSTD_memcpy(&dtd, table, sizeof(dtd)); + return dtd; +} + +static size_t HUF_initFastDStream(BYTE const* ip) { + BYTE const lastByte = ip[7]; + size_t const bitsConsumed = lastByte ? 8 - ZSTD_highbit32(lastByte) : 0; + size_t const value = MEM_readLEST(ip) | 1; + assert(bitsConsumed <= 8); + assert(sizeof(size_t) == 8); + return value << bitsConsumed; +} + + +/** + * The input/output arguments to the Huffman fast decoding loop: + * + * ip [in/out] - The input pointers, must be updated to reflect what is consumed. + * op [in/out] - The output pointers, must be updated to reflect what is written. + * bits [in/out] - The bitstream containers, must be updated to reflect the current state. + * dt [in] - The decoding table. + * ilowest [in] - The beginning of the valid range of the input. Decoders may read + * down to this pointer. It may be below iend[0]. + * oend [in] - The end of the output stream. op[3] must not cross oend. + * iend [in] - The end of each input stream. ip[i] may cross iend[i], + * as long as it is above ilowest, but that indicates corruption. + */ +typedef struct { + BYTE const* ip[4]; + BYTE* op[4]; + U64 bits[4]; + void const* dt; + BYTE const* ilowest; + BYTE* oend; + BYTE const* iend[4]; +} HUF_DecompressFastArgs; + +typedef void (*HUF_DecompressFastLoopFn)(HUF_DecompressFastArgs*); + +/** + * Initializes args for the fast decoding loop. + * @returns 1 on success + * 0 if the fallback implementation should be used. + * Or an error code on failure. + */ +static size_t HUF_DecompressFastArgs_init(HUF_DecompressFastArgs* args, void* dst, size_t dstSize, void const* src, size_t srcSize, const HUF_DTable* DTable) +{ + void const* dt = DTable + 1; + U32 const dtLog = HUF_getDTableDesc(DTable).tableLog; + + const BYTE* const istart = (const BYTE*)src; + + BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize); + + /* The fast decoding loop assumes 64-bit little-endian. + * This condition is false on x32. + */ + if (!MEM_isLittleEndian() || MEM_32bits()) + return 0; + + /* Avoid nullptr addition */ + if (dstSize == 0) + return 0; + assert(dst != NULL); + + /* strict minimum : jump table + 1 byte per stream */ + if (srcSize < 10) + return ERROR(corruption_detected); + + /* Must have at least 8 bytes per stream because we don't handle initializing smaller bit containers. + * If table log is not correct at this point, fallback to the old decoder. + * On small inputs we don't have enough data to trigger the fast loop, so use the old decoder. + */ + if (dtLog != HUF_DECODER_FAST_TABLELOG) + return 0; + + /* Read the jump table. */ + { + size_t const length1 = MEM_readLE16(istart); + size_t const length2 = MEM_readLE16(istart+2); + size_t const length3 = MEM_readLE16(istart+4); + size_t const length4 = srcSize - (length1 + length2 + length3 + 6); + args->iend[0] = istart + 6; /* jumpTable */ + args->iend[1] = args->iend[0] + length1; + args->iend[2] = args->iend[1] + length2; + args->iend[3] = args->iend[2] + length3; + + /* HUF_initFastDStream() requires this, and this small of an input + * won't benefit from the ASM loop anyways. + */ + if (length1 < 8 || length2 < 8 || length3 < 8 || length4 < 8) + return 0; + if (length4 > srcSize) return ERROR(corruption_detected); /* overflow */ + } + /* ip[] contains the position that is currently loaded into bits[]. */ + args->ip[0] = args->iend[1] - sizeof(U64); + args->ip[1] = args->iend[2] - sizeof(U64); + args->ip[2] = args->iend[3] - sizeof(U64); + args->ip[3] = (BYTE const*)src + srcSize - sizeof(U64); + + /* op[] contains the output pointers. */ + args->op[0] = (BYTE*)dst; + args->op[1] = args->op[0] + (dstSize+3)/4; + args->op[2] = args->op[1] + (dstSize+3)/4; + args->op[3] = args->op[2] + (dstSize+3)/4; + + /* No point to call the ASM loop for tiny outputs. */ + if (args->op[3] >= oend) + return 0; + + /* bits[] is the bit container. + * It is read from the MSB down to the LSB. + * It is shifted left as it is read, and zeros are + * shifted in. After the lowest valid bit a 1 is + * set, so that CountTrailingZeros(bits[]) can be used + * to count how many bits we've consumed. + */ + args->bits[0] = HUF_initFastDStream(args->ip[0]); + args->bits[1] = HUF_initFastDStream(args->ip[1]); + args->bits[2] = HUF_initFastDStream(args->ip[2]); + args->bits[3] = HUF_initFastDStream(args->ip[3]); + + /* The decoders must be sure to never read beyond ilowest. + * This is lower than iend[0], but allowing decoders to read + * down to ilowest can allow an extra iteration or two in the + * fast loop. + */ + args->ilowest = istart; + + args->oend = oend; + args->dt = dt; + + return 1; +} + +static size_t HUF_initRemainingDStream(BIT_DStream_t* bit, HUF_DecompressFastArgs const* args, int stream, BYTE* segmentEnd) +{ + /* Validate that we haven't overwritten. */ + if (args->op[stream] > segmentEnd) + return ERROR(corruption_detected); + /* Validate that we haven't read beyond iend[]. + * Note that ip[] may be < iend[] because the MSB is + * the next bit to read, and we may have consumed 100% + * of the stream, so down to iend[i] - 8 is valid. + */ + if (args->ip[stream] < args->iend[stream] - 8) + return ERROR(corruption_detected); + + /* Construct the BIT_DStream_t. */ + assert(sizeof(size_t) == 8); + bit->bitContainer = MEM_readLEST(args->ip[stream]); + bit->bitsConsumed = ZSTD_countTrailingZeros64(args->bits[stream]); + bit->start = (const char*)args->ilowest; + bit->limitPtr = bit->start + sizeof(size_t); + bit->ptr = (const char*)args->ip[stream]; + + return 0; +} + +/* Calls X(N) for each stream 0, 1, 2, 3. */ +#define HUF_4X_FOR_EACH_STREAM(X) \ + do { \ + X(0); \ + X(1); \ + X(2); \ + X(3); \ + } while (0) + +/* Calls X(N, var) for each stream 0, 1, 2, 3. */ +#define HUF_4X_FOR_EACH_STREAM_WITH_VAR(X, var) \ + do { \ + X(0, (var)); \ + X(1, (var)); \ + X(2, (var)); \ + X(3, (var)); \ + } while (0) + + +#ifndef HUF_FORCE_DECOMPRESS_X2 + +/*-***************************/ +/* single-symbol decoding */ +/*-***************************/ +typedef struct { BYTE nbBits; BYTE byte; } HUF_DEltX1; /* single-symbol decoding */ + +/** + * Packs 4 HUF_DEltX1 structs into a U64. This is used to lay down 4 entries at + * a time. + */ +static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) { + U64 D4; + if (MEM_isLittleEndian()) { + D4 = (U64)((symbol << 8) + nbBits); + } else { + D4 = (U64)(symbol + (nbBits << 8)); + } + assert(D4 < (1U << 16)); + D4 *= 0x0001000100010001ULL; + return D4; +} + +/** + * Increase the tableLog to targetTableLog and rescales the stats. + * If tableLog > targetTableLog this is a no-op. + * @returns New tableLog + */ +static U32 HUF_rescaleStats(BYTE* huffWeight, U32* rankVal, U32 nbSymbols, U32 tableLog, U32 targetTableLog) +{ + if (tableLog > targetTableLog) + return tableLog; + if (tableLog < targetTableLog) { + U32 const scale = targetTableLog - tableLog; + U32 s; + /* Increase the weight for all non-zero probability symbols by scale. */ + for (s = 0; s < nbSymbols; ++s) { + huffWeight[s] += (BYTE)((huffWeight[s] == 0) ? 0 : scale); + } + /* Update rankVal to reflect the new weights. + * All weights except 0 get moved to weight + scale. + * Weights [1, scale] are empty. + */ + for (s = targetTableLog; s > scale; --s) { + rankVal[s] = rankVal[s - scale]; + } + for (s = scale; s > 0; --s) { + rankVal[s] = 0; + } + } + return targetTableLog; +} + +typedef struct { + U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; + U32 rankStart[HUF_TABLELOG_ABSOLUTEMAX + 1]; + U32 statsWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; + BYTE symbols[HUF_SYMBOLVALUE_MAX + 1]; + BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; +} HUF_ReadDTableX1_Workspace; + +size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int flags) +{ + U32 tableLog = 0; + U32 nbSymbols = 0; + size_t iSize; + void* const dtPtr = DTable + 1; + HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr; + HUF_ReadDTableX1_Workspace* wksp = (HUF_ReadDTableX1_Workspace*)workSpace; + + DEBUG_STATIC_ASSERT(HUF_DECOMPRESS_WORKSPACE_SIZE >= sizeof(*wksp)); + if (sizeof(*wksp) > wkspSize) return ERROR(tableLog_tooLarge); + + DEBUG_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable)); + /* ZSTD_memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */ + + iSize = HUF_readStats_wksp(wksp->huffWeight, HUF_SYMBOLVALUE_MAX + 1, wksp->rankVal, &nbSymbols, &tableLog, src, srcSize, wksp->statsWksp, sizeof(wksp->statsWksp), flags); + if (HUF_isError(iSize)) return iSize; + + + /* Table header */ + { DTableDesc dtd = HUF_getDTableDesc(DTable); + U32 const maxTableLog = dtd.maxTableLog + 1; + U32 const targetTableLog = MIN(maxTableLog, HUF_DECODER_FAST_TABLELOG); + tableLog = HUF_rescaleStats(wksp->huffWeight, wksp->rankVal, nbSymbols, tableLog, targetTableLog); + if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */ + dtd.tableType = 0; + dtd.tableLog = (BYTE)tableLog; + ZSTD_memcpy(DTable, &dtd, sizeof(dtd)); + } + + /* Compute symbols and rankStart given rankVal: + * + * rankVal already contains the number of values of each weight. + * + * symbols contains the symbols ordered by weight. First are the rankVal[0] + * weight 0 symbols, followed by the rankVal[1] weight 1 symbols, and so on. + * symbols[0] is filled (but unused) to avoid a branch. + * + * rankStart contains the offset where each rank belongs in the DTable. + * rankStart[0] is not filled because there are no entries in the table for + * weight 0. + */ + { int n; + U32 nextRankStart = 0; + int const unroll = 4; + int const nLimit = (int)nbSymbols - unroll + 1; + for (n=0; n<(int)tableLog+1; n++) { + U32 const curr = nextRankStart; + nextRankStart += wksp->rankVal[n]; + wksp->rankStart[n] = curr; + } + for (n=0; n < nLimit; n += unroll) { + int u; + for (u=0; u < unroll; ++u) { + size_t const w = wksp->huffWeight[n+u]; + wksp->symbols[wksp->rankStart[w]++] = (BYTE)(n+u); + } + } + for (; n < (int)nbSymbols; ++n) { + size_t const w = wksp->huffWeight[n]; + wksp->symbols[wksp->rankStart[w]++] = (BYTE)n; + } + } + + /* fill DTable + * We fill all entries of each weight in order. + * That way length is a constant for each iteration of the outer loop. + * We can switch based on the length to a different inner loop which is + * optimized for that particular case. + */ + { U32 w; + int symbol = wksp->rankVal[0]; + int rankStart = 0; + for (w=1; wrankVal[w]; + int const length = (1 << w) >> 1; + int uStart = rankStart; + BYTE const nbBits = (BYTE)(tableLog + 1 - w); + int s; + int u; + switch (length) { + case 1: + for (s=0; ssymbols[symbol + s]; + D.nbBits = nbBits; + dt[uStart] = D; + uStart += 1; + } + break; + case 2: + for (s=0; ssymbols[symbol + s]; + D.nbBits = nbBits; + dt[uStart+0] = D; + dt[uStart+1] = D; + uStart += 2; + } + break; + case 4: + for (s=0; ssymbols[symbol + s], nbBits); + MEM_write64(dt + uStart, D4); + uStart += 4; + } + break; + case 8: + for (s=0; ssymbols[symbol + s], nbBits); + MEM_write64(dt + uStart, D4); + MEM_write64(dt + uStart + 4, D4); + uStart += 8; + } + break; + default: + for (s=0; ssymbols[symbol + s], nbBits); + for (u=0; u < length; u += 16) { + MEM_write64(dt + uStart + u + 0, D4); + MEM_write64(dt + uStart + u + 4, D4); + MEM_write64(dt + uStart + u + 8, D4); + MEM_write64(dt + uStart + u + 12, D4); + } + assert(u == length); + uStart += length; + } + break; + } + symbol += symbolCount; + rankStart += symbolCount * length; + } + } + return iSize; +} + +FORCE_INLINE_TEMPLATE BYTE +HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */ + BYTE const c = dt[val].byte; + BIT_skipBits(Dstream, dt[val].nbBits); + return c; +} + +#define HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) \ + do { *ptr++ = HUF_decodeSymbolX1(DStreamPtr, dt, dtLog); } while (0) + +#define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ + HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr); \ + } while (0) + +#define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits()) \ + HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr); \ + } while (0) + +HINT_INLINE size_t +HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX1* const dt, const U32 dtLog) +{ + BYTE* const pStart = p; + + /* up to 4 symbols at a time */ + if ((pEnd - p) > 3) { + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) { + HUF_DECODE_SYMBOLX1_2(p, bitDPtr); + HUF_DECODE_SYMBOLX1_1(p, bitDPtr); + HUF_DECODE_SYMBOLX1_2(p, bitDPtr); + HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + } + } else { + BIT_reloadDStream(bitDPtr); + } + + /* [0-3] symbols remaining */ + if (MEM_32bits()) + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd)) + HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + + /* no more data to retrieve from bitstream, no need to reload */ + while (p < pEnd) + HUF_DECODE_SYMBOLX1_0(p, bitDPtr); + + return (size_t)(pEnd-pStart); +} + +FORCE_INLINE_TEMPLATE size_t +HUF_decompress1X1_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + BYTE* op = (BYTE*)dst; + BYTE* const oend = ZSTD_maybeNullPtrAdd(op, dstSize); + const void* dtPtr = DTable + 1; + const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr; + BIT_DStream_t bitD; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + + CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) ); + + HUF_decodeStreamX1(op, &bitD, oend, dt, dtLog); + + if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected); + + return dstSize; +} + +/* HUF_decompress4X1_usingDTable_internal_body(): + * Conditions : + * @dstSize >= 6 + */ +FORCE_INLINE_TEMPLATE size_t +HUF_decompress4X1_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + /* Check */ + if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */ + + { const BYTE* const istart = (const BYTE*) cSrc; + BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + BYTE* const olimit = oend - 3; + const void* const dtPtr = DTable + 1; + const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr; + + /* Init */ + BIT_DStream_t bitD1; + BIT_DStream_t bitD2; + BIT_DStream_t bitD3; + BIT_DStream_t bitD4; + size_t const length1 = MEM_readLE16(istart); + size_t const length2 = MEM_readLE16(istart+2); + size_t const length3 = MEM_readLE16(istart+4); + size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6); + const BYTE* const istart1 = istart + 6; /* jumpTable */ + const BYTE* const istart2 = istart1 + length1; + const BYTE* const istart3 = istart2 + length2; + const BYTE* const istart4 = istart3 + length3; + const size_t segmentSize = (dstSize+3) / 4; + BYTE* const opStart2 = ostart + segmentSize; + BYTE* const opStart3 = opStart2 + segmentSize; + BYTE* const opStart4 = opStart3 + segmentSize; + BYTE* op1 = ostart; + BYTE* op2 = opStart2; + BYTE* op3 = opStart3; + BYTE* op4 = opStart4; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + U32 endSignal = 1; + + if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ + if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */ + assert(dstSize >= 6); /* validated above */ + CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); + CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); + CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); + CHECK_F( BIT_initDStream(&bitD4, istart4, length4) ); + + /* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */ + if ((size_t)(oend - op4) >= sizeof(size_t)) { + for ( ; (endSignal) & (op4 < olimit) ; ) { + HUF_DECODE_SYMBOLX1_2(op1, &bitD1); + HUF_DECODE_SYMBOLX1_2(op2, &bitD2); + HUF_DECODE_SYMBOLX1_2(op3, &bitD3); + HUF_DECODE_SYMBOLX1_2(op4, &bitD4); + HUF_DECODE_SYMBOLX1_1(op1, &bitD1); + HUF_DECODE_SYMBOLX1_1(op2, &bitD2); + HUF_DECODE_SYMBOLX1_1(op3, &bitD3); + HUF_DECODE_SYMBOLX1_1(op4, &bitD4); + HUF_DECODE_SYMBOLX1_2(op1, &bitD1); + HUF_DECODE_SYMBOLX1_2(op2, &bitD2); + HUF_DECODE_SYMBOLX1_2(op3, &bitD3); + HUF_DECODE_SYMBOLX1_2(op4, &bitD4); + HUF_DECODE_SYMBOLX1_0(op1, &bitD1); + HUF_DECODE_SYMBOLX1_0(op2, &bitD2); + HUF_DECODE_SYMBOLX1_0(op3, &bitD3); + HUF_DECODE_SYMBOLX1_0(op4, &bitD4); + endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished; + } + } + + /* check corruption */ + /* note : should not be necessary : op# advance in lock step, and we control op4. + * but curiously, binary generated by gcc 7.2 & 7.3 with -mbmi2 runs faster when >=1 test is present */ + if (op1 > opStart2) return ERROR(corruption_detected); + if (op2 > opStart3) return ERROR(corruption_detected); + if (op3 > opStart4) return ERROR(corruption_detected); + /* note : op4 supposed already verified within main loop */ + + /* finish bitStreams one by one */ + HUF_decodeStreamX1(op1, &bitD1, opStart2, dt, dtLog); + HUF_decodeStreamX1(op2, &bitD2, opStart3, dt, dtLog); + HUF_decodeStreamX1(op3, &bitD3, opStart4, dt, dtLog); + HUF_decodeStreamX1(op4, &bitD4, oend, dt, dtLog); + + /* check */ + { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); + if (!endCheck) return ERROR(corruption_detected); } + + /* decoded size */ + return dstSize; + } +} + +#if HUF_NEED_BMI2_FUNCTION +static BMI2_TARGET_ATTRIBUTE +size_t HUF_decompress4X1_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} +#endif + +static +size_t HUF_decompress4X1_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 + +HUF_ASM_DECL void HUF_decompress4X1_usingDTable_internal_fast_asm_loop(HUF_DecompressFastArgs* args) ZSTDLIB_HIDDEN; + +#endif + +static HUF_FAST_BMI2_ATTRS +void HUF_decompress4X1_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* args) +{ + U64 bits[4]; + BYTE const* ip[4]; + BYTE* op[4]; + U16 const* const dtable = (U16 const*)args->dt; + BYTE* const oend = args->oend; + BYTE const* const ilowest = args->ilowest; + + /* Copy the arguments to local variables */ + ZSTD_memcpy(&bits, &args->bits, sizeof(bits)); + ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip)); + ZSTD_memcpy(&op, &args->op, sizeof(op)); + + assert(MEM_isLittleEndian()); + assert(!MEM_32bits()); + + for (;;) { + BYTE* olimit; + int stream; + + /* Assert loop preconditions */ +#ifndef NDEBUG + for (stream = 0; stream < 4; ++stream) { + assert(op[stream] <= (stream == 3 ? oend : op[stream + 1])); + assert(ip[stream] >= ilowest); + } +#endif + /* Compute olimit */ + { + /* Each iteration produces 5 output symbols per stream */ + size_t const oiters = (size_t)(oend - op[3]) / 5; + /* Each iteration consumes up to 11 bits * 5 = 55 bits < 7 bytes + * per stream. + */ + size_t const iiters = (size_t)(ip[0] - ilowest) / 7; + /* We can safely run iters iterations before running bounds checks */ + size_t const iters = MIN(oiters, iiters); + size_t const symbols = iters * 5; + + /* We can simply check that op[3] < olimit, instead of checking all + * of our bounds, since we can't hit the other bounds until we've run + * iters iterations, which only happens when op[3] == olimit. + */ + olimit = op[3] + symbols; + + /* Exit fast decoding loop once we reach the end. */ + if (op[3] == olimit) + break; + + /* Exit the decoding loop if any input pointer has crossed the + * previous one. This indicates corruption, and a precondition + * to our loop is that ip[i] >= ip[0]. + */ + for (stream = 1; stream < 4; ++stream) { + if (ip[stream] < ip[stream - 1]) + goto _out; + } + } + +#ifndef NDEBUG + for (stream = 1; stream < 4; ++stream) { + assert(ip[stream] >= ip[stream - 1]); + } +#endif + +#define HUF_4X1_DECODE_SYMBOL(_stream, _symbol) \ + do { \ + int const index = (int)(bits[(_stream)] >> 53); \ + int const entry = (int)dtable[index]; \ + bits[(_stream)] <<= (entry & 0x3F); \ + op[(_stream)][(_symbol)] = (BYTE)((entry >> 8) & 0xFF); \ + } while (0) + +#define HUF_4X1_RELOAD_STREAM(_stream) \ + do { \ + int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \ + int const nbBits = ctz & 7; \ + int const nbBytes = ctz >> 3; \ + op[(_stream)] += 5; \ + ip[(_stream)] -= nbBytes; \ + bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \ + bits[(_stream)] <<= nbBits; \ + } while (0) + + /* Manually unroll the loop because compilers don't consistently + * unroll the inner loops, which destroys performance. + */ + do { + /* Decode 5 symbols in each of the 4 streams */ + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 1); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 2); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 3); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X1_DECODE_SYMBOL, 4); + + /* Reload each of the 4 the bitstreams */ + HUF_4X_FOR_EACH_STREAM(HUF_4X1_RELOAD_STREAM); + } while (op[3] < olimit); + +#undef HUF_4X1_DECODE_SYMBOL +#undef HUF_4X1_RELOAD_STREAM + } + +_out: + + /* Save the final values of each of the state variables back to args. */ + ZSTD_memcpy(&args->bits, &bits, sizeof(bits)); + ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip)); + ZSTD_memcpy(&args->op, &op, sizeof(op)); +} + +/** + * @returns @p dstSize on success (>= 6) + * 0 if the fallback implementation should be used + * An error if an error occurred + */ +static HUF_FAST_BMI2_ATTRS +size_t +HUF_decompress4X1_usingDTable_internal_fast( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable, + HUF_DecompressFastLoopFn loopFn) +{ + void const* dt = DTable + 1; + BYTE const* const ilowest = (BYTE const*)cSrc; + BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize); + HUF_DecompressFastArgs args; + { size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable); + FORWARD_IF_ERROR(ret, "Failed to init fast loop args"); + if (ret == 0) + return 0; + } + + assert(args.ip[0] >= args.ilowest); + loopFn(&args); + + /* Our loop guarantees that ip[] >= ilowest and that we haven't + * overwritten any op[]. + */ + assert(args.ip[0] >= ilowest); + assert(args.ip[0] >= ilowest); + assert(args.ip[1] >= ilowest); + assert(args.ip[2] >= ilowest); + assert(args.ip[3] >= ilowest); + assert(args.op[3] <= oend); + + assert(ilowest == args.ilowest); + assert(ilowest + 6 == args.iend[0]); + (void)ilowest; + + /* finish bit streams one by one. */ + { size_t const segmentSize = (dstSize+3) / 4; + BYTE* segmentEnd = (BYTE*)dst; + int i; + for (i = 0; i < 4; ++i) { + BIT_DStream_t bit; + if (segmentSize <= (size_t)(oend - segmentEnd)) + segmentEnd += segmentSize; + else + segmentEnd = oend; + FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption"); + /* Decompress and validate that we've produced exactly the expected length. */ + args.op[i] += HUF_decodeStreamX1(args.op[i], &bit, segmentEnd, (HUF_DEltX1 const*)dt, HUF_DECODER_FAST_TABLELOG); + if (args.op[i] != segmentEnd) return ERROR(corruption_detected); + } + } + + /* decoded size */ + assert(dstSize != 0); + return dstSize; +} + +HUF_DGEN(HUF_decompress1X1_usingDTable_internal) + +static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable, int flags) +{ + HUF_DecompressUsingDTableFn fallbackFn = HUF_decompress4X1_usingDTable_internal_default; + HUF_DecompressFastLoopFn loopFn = HUF_decompress4X1_usingDTable_internal_fast_c_loop; + +#if DYNAMIC_BMI2 + if (flags & HUF_flags_bmi2) { + fallbackFn = HUF_decompress4X1_usingDTable_internal_bmi2; +# if ZSTD_ENABLE_ASM_X86_64_BMI2 + if (!(flags & HUF_flags_disableAsm)) { + loopFn = HUF_decompress4X1_usingDTable_internal_fast_asm_loop; + } +# endif + } else { + return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable); + } +#endif + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__) + if (!(flags & HUF_flags_disableAsm)) { + loopFn = HUF_decompress4X1_usingDTable_internal_fast_asm_loop; + } +#endif + + if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) { + size_t const ret = HUF_decompress4X1_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn); + if (ret != 0) + return ret; + } + return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable); +} + +static size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int flags) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize, flags); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress4X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags); +} + +#endif /* HUF_FORCE_DECOMPRESS_X2 */ + + +#ifndef HUF_FORCE_DECOMPRESS_X1 + +/* *************************/ +/* double-symbols decoding */ +/* *************************/ + +typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX2; /* double-symbols decoding */ +typedef struct { BYTE symbol; } sortedSymbol_t; +typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1]; +typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX]; + +/** + * Constructs a HUF_DEltX2 in a U32. + */ +static U32 HUF_buildDEltX2U32(U32 symbol, U32 nbBits, U32 baseSeq, int level) +{ + U32 seq; + DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, sequence) == 0); + DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, nbBits) == 2); + DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, length) == 3); + DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(U32)); + if (MEM_isLittleEndian()) { + seq = level == 1 ? symbol : (baseSeq + (symbol << 8)); + return seq + (nbBits << 16) + ((U32)level << 24); + } else { + seq = level == 1 ? (symbol << 8) : ((baseSeq << 8) + symbol); + return (seq << 16) + (nbBits << 8) + (U32)level; + } +} + +/** + * Constructs a HUF_DEltX2. + */ +static HUF_DEltX2 HUF_buildDEltX2(U32 symbol, U32 nbBits, U32 baseSeq, int level) +{ + HUF_DEltX2 DElt; + U32 const val = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level); + DEBUG_STATIC_ASSERT(sizeof(DElt) == sizeof(val)); + ZSTD_memcpy(&DElt, &val, sizeof(val)); + return DElt; +} + +/** + * Constructs 2 HUF_DEltX2s and packs them into a U64. + */ +static U64 HUF_buildDEltX2U64(U32 symbol, U32 nbBits, U16 baseSeq, int level) +{ + U32 DElt = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level); + return (U64)DElt + ((U64)DElt << 32); +} + +/** + * Fills the DTable rank with all the symbols from [begin, end) that are each + * nbBits long. + * + * @param DTableRank The start of the rank in the DTable. + * @param begin The first symbol to fill (inclusive). + * @param end The last symbol to fill (exclusive). + * @param nbBits Each symbol is nbBits long. + * @param tableLog The table log. + * @param baseSeq If level == 1 { 0 } else { the first level symbol } + * @param level The level in the table. Must be 1 or 2. + */ +static void HUF_fillDTableX2ForWeight( + HUF_DEltX2* DTableRank, + sortedSymbol_t const* begin, sortedSymbol_t const* end, + U32 nbBits, U32 tableLog, + U16 baseSeq, int const level) +{ + U32 const length = 1U << ((tableLog - nbBits) & 0x1F /* quiet static-analyzer */); + const sortedSymbol_t* ptr; + assert(level >= 1 && level <= 2); + switch (length) { + case 1: + for (ptr = begin; ptr != end; ++ptr) { + HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level); + *DTableRank++ = DElt; + } + break; + case 2: + for (ptr = begin; ptr != end; ++ptr) { + HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level); + DTableRank[0] = DElt; + DTableRank[1] = DElt; + DTableRank += 2; + } + break; + case 4: + for (ptr = begin; ptr != end; ++ptr) { + U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level); + ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2)); + DTableRank += 4; + } + break; + case 8: + for (ptr = begin; ptr != end; ++ptr) { + U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level); + ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2)); + DTableRank += 8; + } + break; + default: + for (ptr = begin; ptr != end; ++ptr) { + U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level); + HUF_DEltX2* const DTableRankEnd = DTableRank + length; + for (; DTableRank != DTableRankEnd; DTableRank += 8) { + ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2)); + } + } + break; + } +} + +/* HUF_fillDTableX2Level2() : + * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */ +static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 targetLog, const U32 consumedBits, + const U32* rankVal, const int minWeight, const int maxWeight1, + const sortedSymbol_t* sortedSymbols, U32 const* rankStart, + U32 nbBitsBaseline, U16 baseSeq) +{ + /* Fill skipped values (all positions up to rankVal[minWeight]). + * These are positions only get a single symbol because the combined weight + * is too large. + */ + if (minWeight>1) { + U32 const length = 1U << ((targetLog - consumedBits) & 0x1F /* quiet static-analyzer */); + U64 const DEltX2 = HUF_buildDEltX2U64(baseSeq, consumedBits, /* baseSeq */ 0, /* level */ 1); + int const skipSize = rankVal[minWeight]; + assert(length > 1); + assert((U32)skipSize < length); + switch (length) { + case 2: + assert(skipSize == 1); + ZSTD_memcpy(DTable, &DEltX2, sizeof(DEltX2)); + break; + case 4: + assert(skipSize <= 4); + ZSTD_memcpy(DTable + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + 2, &DEltX2, sizeof(DEltX2)); + break; + default: + { + int i; + for (i = 0; i < skipSize; i += 8) { + ZSTD_memcpy(DTable + i + 0, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + i + 2, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + i + 4, &DEltX2, sizeof(DEltX2)); + ZSTD_memcpy(DTable + i + 6, &DEltX2, sizeof(DEltX2)); + } + } + } + } + + /* Fill each of the second level symbols by weight. */ + { + int w; + for (w = minWeight; w < maxWeight1; ++w) { + int const begin = rankStart[w]; + int const end = rankStart[w+1]; + U32 const nbBits = nbBitsBaseline - w; + U32 const totalBits = nbBits + consumedBits; + HUF_fillDTableX2ForWeight( + DTable + rankVal[w], + sortedSymbols + begin, sortedSymbols + end, + totalBits, targetLog, + baseSeq, /* level */ 2); + } + } +} + +static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog, + const sortedSymbol_t* sortedList, + const U32* rankStart, rankValCol_t* rankValOrigin, const U32 maxWeight, + const U32 nbBitsBaseline) +{ + U32* const rankVal = rankValOrigin[0]; + const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */ + const U32 minBits = nbBitsBaseline - maxWeight; + int w; + int const wEnd = (int)maxWeight + 1; + + /* Fill DTable in order of weight. */ + for (w = 1; w < wEnd; ++w) { + int const begin = (int)rankStart[w]; + int const end = (int)rankStart[w+1]; + U32 const nbBits = nbBitsBaseline - w; + + if (targetLog-nbBits >= minBits) { + /* Enough room for a second symbol. */ + int start = rankVal[w]; + U32 const length = 1U << ((targetLog - nbBits) & 0x1F /* quiet static-analyzer */); + int minWeight = nbBits + scaleLog; + int s; + if (minWeight < 1) minWeight = 1; + /* Fill the DTable for every symbol of weight w. + * These symbols get at least 1 second symbol. + */ + for (s = begin; s != end; ++s) { + HUF_fillDTableX2Level2( + DTable + start, targetLog, nbBits, + rankValOrigin[nbBits], minWeight, wEnd, + sortedList, rankStart, + nbBitsBaseline, sortedList[s].symbol); + start += length; + } + } else { + /* Only a single symbol. */ + HUF_fillDTableX2ForWeight( + DTable + rankVal[w], + sortedList + begin, sortedList + end, + nbBits, targetLog, + /* baseSeq */ 0, /* level */ 1); + } + } +} + +typedef struct { + rankValCol_t rankVal[HUF_TABLELOG_MAX]; + U32 rankStats[HUF_TABLELOG_MAX + 1]; + U32 rankStart0[HUF_TABLELOG_MAX + 3]; + sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1]; + BYTE weightList[HUF_SYMBOLVALUE_MAX + 1]; + U32 calleeWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32]; +} HUF_ReadDTableX2_Workspace; + +size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, + const void* src, size_t srcSize, + void* workSpace, size_t wkspSize, int flags) +{ + U32 tableLog, maxW, nbSymbols; + DTableDesc dtd = HUF_getDTableDesc(DTable); + U32 maxTableLog = dtd.maxTableLog; + size_t iSize; + void* dtPtr = DTable+1; /* force compiler to avoid strict-aliasing */ + HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr; + U32 *rankStart; + + HUF_ReadDTableX2_Workspace* const wksp = (HUF_ReadDTableX2_Workspace*)workSpace; + + if (sizeof(*wksp) > wkspSize) return ERROR(GENERIC); + + rankStart = wksp->rankStart0 + 1; + ZSTD_memset(wksp->rankStats, 0, sizeof(wksp->rankStats)); + ZSTD_memset(wksp->rankStart0, 0, sizeof(wksp->rankStart0)); + + DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */ + if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); + /* ZSTD_memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */ + + iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), flags); + if (HUF_isError(iSize)) return iSize; + + /* check result */ + if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */ + if (tableLog <= HUF_DECODER_FAST_TABLELOG && maxTableLog > HUF_DECODER_FAST_TABLELOG) maxTableLog = HUF_DECODER_FAST_TABLELOG; + + /* find maxWeight */ + for (maxW = tableLog; wksp->rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */ + + /* Get start index of each weight */ + { U32 w, nextRankStart = 0; + for (w=1; wrankStats[w]; + rankStart[w] = curr; + } + rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/ + rankStart[maxW+1] = nextRankStart; + } + + /* sort symbols by weight */ + { U32 s; + for (s=0; sweightList[s]; + U32 const r = rankStart[w]++; + wksp->sortedSymbol[r].symbol = (BYTE)s; + } + rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */ + } + + /* Build rankVal */ + { U32* const rankVal0 = wksp->rankVal[0]; + { int const rescale = (maxTableLog-tableLog) - 1; /* tableLog <= maxTableLog */ + U32 nextRankVal = 0; + U32 w; + for (w=1; wrankStats[w] << (w+rescale); + rankVal0[w] = curr; + } } + { U32 const minBits = tableLog+1 - maxW; + U32 consumed; + for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) { + U32* const rankValPtr = wksp->rankVal[consumed]; + U32 w; + for (w = 1; w < maxW+1; w++) { + rankValPtr[w] = rankVal0[w] >> consumed; + } } } } + + HUF_fillDTableX2(dt, maxTableLog, + wksp->sortedSymbol, + wksp->rankStart0, wksp->rankVal, maxW, + tableLog+1); + + dtd.tableLog = (BYTE)maxTableLog; + dtd.tableType = 1; + ZSTD_memcpy(DTable, &dtd, sizeof(dtd)); + return iSize; +} + + +FORCE_INLINE_TEMPLATE U32 +HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + ZSTD_memcpy(op, &dt[val].sequence, 2); + BIT_skipBits(DStream, dt[val].nbBits); + return dt[val].length; +} + +FORCE_INLINE_TEMPLATE U32 +HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog) +{ + size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + ZSTD_memcpy(op, &dt[val].sequence, 1); + if (dt[val].length==1) { + BIT_skipBits(DStream, dt[val].nbBits); + } else { + if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) { + BIT_skipBits(DStream, dt[val].nbBits); + if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8)) + /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */ + DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8); + } + } + return 1; +} + +#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \ + do { ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); } while (0) + +#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \ + ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); \ + } while (0) + +#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \ + do { \ + if (MEM_64bits()) \ + ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog); \ + } while (0) + +HINT_INLINE size_t +HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, + const HUF_DEltX2* const dt, const U32 dtLog) +{ + BYTE* const pStart = p; + + /* up to 8 symbols at a time */ + if ((size_t)(pEnd - p) >= sizeof(bitDPtr->bitContainer)) { + if (dtLog <= 11 && MEM_64bits()) { + /* up to 10 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-9)) { + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + } + } else { + /* up to 8 symbols at a time */ + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) { + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_1(p, bitDPtr); + HUF_DECODE_SYMBOLX2_2(p, bitDPtr); + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + } + } + } else { + BIT_reloadDStream(bitDPtr); + } + + /* closer to end : up to 2 symbols at a time */ + if ((size_t)(pEnd - p) >= 2) { + while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2)) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); + + while (p <= pEnd-2) + HUF_DECODE_SYMBOLX2_0(p, bitDPtr); /* no need to reload : reached the end of DStream */ + } + + if (p < pEnd) + p += HUF_decodeLastSymbolX2(p, bitDPtr, dt, dtLog); + + return p-pStart; +} + +FORCE_INLINE_TEMPLATE size_t +HUF_decompress1X2_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + BIT_DStream_t bitD; + + /* Init */ + CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) ); + + /* decode */ + { BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, dstSize); + const void* const dtPtr = DTable+1; /* force compiler to not use strict-aliasing */ + const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + HUF_decodeStreamX2(ostart, &bitD, oend, dt, dtd.tableLog); + } + + /* check */ + if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected); + + /* decoded size */ + return dstSize; +} + +/* HUF_decompress4X2_usingDTable_internal_body(): + * Conditions: + * @dstSize >= 6 + */ +FORCE_INLINE_TEMPLATE size_t +HUF_decompress4X2_usingDTable_internal_body( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable) +{ + if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + if (dstSize < 6) return ERROR(corruption_detected); /* stream 4-split doesn't work */ + + { const BYTE* const istart = (const BYTE*) cSrc; + BYTE* const ostart = (BYTE*) dst; + BYTE* const oend = ostart + dstSize; + BYTE* const olimit = oend - (sizeof(size_t)-1); + const void* const dtPtr = DTable+1; + const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr; + + /* Init */ + BIT_DStream_t bitD1; + BIT_DStream_t bitD2; + BIT_DStream_t bitD3; + BIT_DStream_t bitD4; + size_t const length1 = MEM_readLE16(istart); + size_t const length2 = MEM_readLE16(istart+2); + size_t const length3 = MEM_readLE16(istart+4); + size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6); + const BYTE* const istart1 = istart + 6; /* jumpTable */ + const BYTE* const istart2 = istart1 + length1; + const BYTE* const istart3 = istart2 + length2; + const BYTE* const istart4 = istart3 + length3; + size_t const segmentSize = (dstSize+3) / 4; + BYTE* const opStart2 = ostart + segmentSize; + BYTE* const opStart3 = opStart2 + segmentSize; + BYTE* const opStart4 = opStart3 + segmentSize; + BYTE* op1 = ostart; + BYTE* op2 = opStart2; + BYTE* op3 = opStart3; + BYTE* op4 = opStart4; + U32 endSignal = 1; + DTableDesc const dtd = HUF_getDTableDesc(DTable); + U32 const dtLog = dtd.tableLog; + + if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ + if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */ + assert(dstSize >= 6 /* validated above */); + CHECK_F( BIT_initDStream(&bitD1, istart1, length1) ); + CHECK_F( BIT_initDStream(&bitD2, istart2, length2) ); + CHECK_F( BIT_initDStream(&bitD3, istart3, length3) ); + CHECK_F( BIT_initDStream(&bitD4, istart4, length4) ); + + /* 16-32 symbols per loop (4-8 symbols per stream) */ + if ((size_t)(oend - op4) >= sizeof(size_t)) { + for ( ; (endSignal) & (op4 < olimit); ) { +#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_1(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_0(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_1(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_0(op2, &bitD2); + endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished; + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_1(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_0(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_1(op4, &bitD4); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_0(op4, &bitD4); + endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished; + endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished; +#else + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_1(op1, &bitD1); + HUF_DECODE_SYMBOLX2_1(op2, &bitD2); + HUF_DECODE_SYMBOLX2_1(op3, &bitD3); + HUF_DECODE_SYMBOLX2_1(op4, &bitD4); + HUF_DECODE_SYMBOLX2_2(op1, &bitD1); + HUF_DECODE_SYMBOLX2_2(op2, &bitD2); + HUF_DECODE_SYMBOLX2_2(op3, &bitD3); + HUF_DECODE_SYMBOLX2_2(op4, &bitD4); + HUF_DECODE_SYMBOLX2_0(op1, &bitD1); + HUF_DECODE_SYMBOLX2_0(op2, &bitD2); + HUF_DECODE_SYMBOLX2_0(op3, &bitD3); + HUF_DECODE_SYMBOLX2_0(op4, &bitD4); + endSignal = (U32)LIKELY((U32) + (BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished) + & (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished) + & (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished) + & (BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished)); +#endif + } + } + + /* check corruption */ + if (op1 > opStart2) return ERROR(corruption_detected); + if (op2 > opStart3) return ERROR(corruption_detected); + if (op3 > opStart4) return ERROR(corruption_detected); + /* note : op4 already verified within main loop */ + + /* finish bitStreams one by one */ + HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog); + HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog); + HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog); + HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog); + + /* check */ + { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4); + if (!endCheck) return ERROR(corruption_detected); } + + /* decoded size */ + return dstSize; + } +} + +#if HUF_NEED_BMI2_FUNCTION +static BMI2_TARGET_ATTRIBUTE +size_t HUF_decompress4X2_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} +#endif + +static +size_t HUF_decompress4X2_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable) { + return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable); +} + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 + +HUF_ASM_DECL void HUF_decompress4X2_usingDTable_internal_fast_asm_loop(HUF_DecompressFastArgs* args) ZSTDLIB_HIDDEN; + +#endif + +static HUF_FAST_BMI2_ATTRS +void HUF_decompress4X2_usingDTable_internal_fast_c_loop(HUF_DecompressFastArgs* args) +{ + U64 bits[4]; + BYTE const* ip[4]; + BYTE* op[4]; + BYTE* oend[4]; + HUF_DEltX2 const* const dtable = (HUF_DEltX2 const*)args->dt; + BYTE const* const ilowest = args->ilowest; + + /* Copy the arguments to local registers. */ + ZSTD_memcpy(&bits, &args->bits, sizeof(bits)); + ZSTD_memcpy((void*)(&ip), &args->ip, sizeof(ip)); + ZSTD_memcpy(&op, &args->op, sizeof(op)); + + oend[0] = op[1]; + oend[1] = op[2]; + oend[2] = op[3]; + oend[3] = args->oend; + + assert(MEM_isLittleEndian()); + assert(!MEM_32bits()); + + for (;;) { + BYTE* olimit; + int stream; + + /* Assert loop preconditions */ +#ifndef NDEBUG + for (stream = 0; stream < 4; ++stream) { + assert(op[stream] <= oend[stream]); + assert(ip[stream] >= ilowest); + } +#endif + /* Compute olimit */ + { + /* Each loop does 5 table lookups for each of the 4 streams. + * Each table lookup consumes up to 11 bits of input, and produces + * up to 2 bytes of output. + */ + /* We can consume up to 7 bytes of input per iteration per stream. + * We also know that each input pointer is >= ip[0]. So we can run + * iters loops before running out of input. + */ + size_t iters = (size_t)(ip[0] - ilowest) / 7; + /* Each iteration can produce up to 10 bytes of output per stream. + * Each output stream my advance at different rates. So take the + * minimum number of safe iterations among all the output streams. + */ + for (stream = 0; stream < 4; ++stream) { + size_t const oiters = (size_t)(oend[stream] - op[stream]) / 10; + iters = MIN(iters, oiters); + } + + /* Each iteration produces at least 5 output symbols. So until + * op[3] crosses olimit, we know we haven't executed iters + * iterations yet. This saves us maintaining an iters counter, + * at the expense of computing the remaining # of iterations + * more frequently. + */ + olimit = op[3] + (iters * 5); + + /* Exit the fast decoding loop once we reach the end. */ + if (op[3] == olimit) + break; + + /* Exit the decoding loop if any input pointer has crossed the + * previous one. This indicates corruption, and a precondition + * to our loop is that ip[i] >= ip[0]. + */ + for (stream = 1; stream < 4; ++stream) { + if (ip[stream] < ip[stream - 1]) + goto _out; + } + } + +#ifndef NDEBUG + for (stream = 1; stream < 4; ++stream) { + assert(ip[stream] >= ip[stream - 1]); + } +#endif + +#define HUF_4X2_DECODE_SYMBOL(_stream, _decode3) \ + do { \ + if ((_decode3) || (_stream) != 3) { \ + int const index = (int)(bits[(_stream)] >> 53); \ + HUF_DEltX2 const entry = dtable[index]; \ + MEM_write16(op[(_stream)], entry.sequence); \ + bits[(_stream)] <<= (entry.nbBits) & 0x3F; \ + op[(_stream)] += (entry.length); \ + } \ + } while (0) + +#define HUF_4X2_RELOAD_STREAM(_stream) \ + do { \ + HUF_4X2_DECODE_SYMBOL(3, 1); \ + { \ + int const ctz = ZSTD_countTrailingZeros64(bits[(_stream)]); \ + int const nbBits = ctz & 7; \ + int const nbBytes = ctz >> 3; \ + ip[(_stream)] -= nbBytes; \ + bits[(_stream)] = MEM_read64(ip[(_stream)]) | 1; \ + bits[(_stream)] <<= nbBits; \ + } \ + } while (0) + + /* Manually unroll the loop because compilers don't consistently + * unroll the inner loops, which destroys performance. + */ + do { + /* Decode 5 symbols from each of the first 3 streams. + * The final stream will be decoded during the reload phase + * to reduce register pressure. + */ + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + HUF_4X_FOR_EACH_STREAM_WITH_VAR(HUF_4X2_DECODE_SYMBOL, 0); + + /* Decode one symbol from the final stream */ + HUF_4X2_DECODE_SYMBOL(3, 1); + + /* Decode 4 symbols from the final stream & reload bitstreams. + * The final stream is reloaded last, meaning that all 5 symbols + * are decoded from the final stream before it is reloaded. + */ + HUF_4X_FOR_EACH_STREAM(HUF_4X2_RELOAD_STREAM); + } while (op[3] < olimit); + } + +#undef HUF_4X2_DECODE_SYMBOL +#undef HUF_4X2_RELOAD_STREAM + +_out: + + /* Save the final values of each of the state variables back to args. */ + ZSTD_memcpy(&args->bits, &bits, sizeof(bits)); + ZSTD_memcpy((void*)(&args->ip), &ip, sizeof(ip)); + ZSTD_memcpy(&args->op, &op, sizeof(op)); +} + + +static HUF_FAST_BMI2_ATTRS size_t +HUF_decompress4X2_usingDTable_internal_fast( + void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + const HUF_DTable* DTable, + HUF_DecompressFastLoopFn loopFn) { + void const* dt = DTable + 1; + const BYTE* const ilowest = (const BYTE*)cSrc; + BYTE* const oend = ZSTD_maybeNullPtrAdd((BYTE*)dst, dstSize); + HUF_DecompressFastArgs args; + { + size_t const ret = HUF_DecompressFastArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable); + FORWARD_IF_ERROR(ret, "Failed to init asm args"); + if (ret == 0) + return 0; + } + + assert(args.ip[0] >= args.ilowest); + loopFn(&args); + + /* note : op4 already verified within main loop */ + assert(args.ip[0] >= ilowest); + assert(args.ip[1] >= ilowest); + assert(args.ip[2] >= ilowest); + assert(args.ip[3] >= ilowest); + assert(args.op[3] <= oend); + + assert(ilowest == args.ilowest); + assert(ilowest + 6 == args.iend[0]); + (void)ilowest; + + /* finish bitStreams one by one */ + { + size_t const segmentSize = (dstSize+3) / 4; + BYTE* segmentEnd = (BYTE*)dst; + int i; + for (i = 0; i < 4; ++i) { + BIT_DStream_t bit; + if (segmentSize <= (size_t)(oend - segmentEnd)) + segmentEnd += segmentSize; + else + segmentEnd = oend; + FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption"); + args.op[i] += HUF_decodeStreamX2(args.op[i], &bit, segmentEnd, (HUF_DEltX2 const*)dt, HUF_DECODER_FAST_TABLELOG); + if (args.op[i] != segmentEnd) + return ERROR(corruption_detected); + } + } + + /* decoded size */ + return dstSize; +} + +static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc, + size_t cSrcSize, HUF_DTable const* DTable, int flags) +{ + HUF_DecompressUsingDTableFn fallbackFn = HUF_decompress4X2_usingDTable_internal_default; + HUF_DecompressFastLoopFn loopFn = HUF_decompress4X2_usingDTable_internal_fast_c_loop; + +#if DYNAMIC_BMI2 + if (flags & HUF_flags_bmi2) { + fallbackFn = HUF_decompress4X2_usingDTable_internal_bmi2; +# if ZSTD_ENABLE_ASM_X86_64_BMI2 + if (!(flags & HUF_flags_disableAsm)) { + loopFn = HUF_decompress4X2_usingDTable_internal_fast_asm_loop; + } +# endif + } else { + return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable); + } +#endif + +#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__) + if (!(flags & HUF_flags_disableAsm)) { + loopFn = HUF_decompress4X2_usingDTable_internal_fast_asm_loop; + } +#endif + + if (HUF_ENABLE_FAST_DECODE && !(flags & HUF_flags_disableFast)) { + size_t const ret = HUF_decompress4X2_usingDTable_internal_fast(dst, dstSize, cSrc, cSrcSize, DTable, loopFn); + if (ret != 0) + return ret; + } + return fallbackFn(dst, dstSize, cSrc, cSrcSize, DTable); +} + +HUF_DGEN(HUF_decompress1X2_usingDTable_internal) + +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int flags) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize, + workSpace, wkspSize, flags); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, flags); +} + +static size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int flags) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize, + workSpace, wkspSize, flags); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags); +} + +#endif /* HUF_FORCE_DECOMPRESS_X1 */ + + +/* ***********************************/ +/* Universal decompression selectors */ +/* ***********************************/ + + +#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2) +typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t; +static const algo_time_t algoTime[16 /* Quantization */][2 /* single, double */] = +{ + /* single, double, quad */ + {{0,0}, {1,1}}, /* Q==0 : impossible */ + {{0,0}, {1,1}}, /* Q==1 : impossible */ + {{ 150,216}, { 381,119}}, /* Q == 2 : 12-18% */ + {{ 170,205}, { 514,112}}, /* Q == 3 : 18-25% */ + {{ 177,199}, { 539,110}}, /* Q == 4 : 25-32% */ + {{ 197,194}, { 644,107}}, /* Q == 5 : 32-38% */ + {{ 221,192}, { 735,107}}, /* Q == 6 : 38-44% */ + {{ 256,189}, { 881,106}}, /* Q == 7 : 44-50% */ + {{ 359,188}, {1167,109}}, /* Q == 8 : 50-56% */ + {{ 582,187}, {1570,114}}, /* Q == 9 : 56-62% */ + {{ 688,187}, {1712,122}}, /* Q ==10 : 62-69% */ + {{ 825,186}, {1965,136}}, /* Q ==11 : 69-75% */ + {{ 976,185}, {2131,150}}, /* Q ==12 : 75-81% */ + {{1180,186}, {2070,175}}, /* Q ==13 : 81-87% */ + {{1377,185}, {1731,202}}, /* Q ==14 : 87-93% */ + {{1412,185}, {1695,202}}, /* Q ==15 : 93-99% */ +}; +#endif + +/** HUF_selectDecoder() : + * Tells which decoder is likely to decode faster, + * based on a set of pre-computed metrics. + * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 . + * Assumption : 0 < dstSize <= 128 KB */ +U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize) +{ + assert(dstSize > 0); + assert(dstSize <= 128*1024); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)dstSize; + (void)cSrcSize; + return 0; +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)dstSize; + (void)cSrcSize; + return 1; +#else + /* decoder timing evaluation */ + { U32 const Q = (cSrcSize >= dstSize) ? 15 : (U32)(cSrcSize * 16 / dstSize); /* Q < 16 */ + U32 const D256 = (U32)(dstSize >> 8); + U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256); + U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256); + DTime1 += DTime1 >> 5; /* small advantage to algorithm using less memory, to reduce cache eviction */ + return DTime1 < DTime0; + } +#endif +} + +size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize, int flags) +{ + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */ + if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */ + if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)algoNb; + assert(algoNb == 0); + return HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize, flags); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)algoNb; + assert(algoNb == 1); + return HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize, flags); +#else + return algoNb ? HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize, flags): + HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize, flags); +#endif + } +} + + +size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags) +{ + DTableDesc const dtd = HUF_getDTableDesc(DTable); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)dtd; + assert(dtd.tableType == 0); + return HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)dtd; + assert(dtd.tableType == 1); + return HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#else + return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags) : + HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#endif +} + +#ifndef HUF_FORCE_DECOMPRESS_X2 +size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags) +{ + const BYTE* ip = (const BYTE*) cSrc; + + size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize, flags); + if (HUF_isError(hSize)) return hSize; + if (hSize >= cSrcSize) return ERROR(srcSize_wrong); + ip += hSize; cSrcSize -= hSize; + + return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, flags); +} +#endif + +size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int flags) +{ + DTableDesc const dtd = HUF_getDTableDesc(DTable); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)dtd; + assert(dtd.tableType == 0); + return HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)dtd; + assert(dtd.tableType == 1); + return HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#else + return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags) : + HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, flags); +#endif +} + +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int flags) +{ + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if (cSrcSize == 0) return ERROR(corruption_detected); + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); +#if defined(HUF_FORCE_DECOMPRESS_X1) + (void)algoNb; + assert(algoNb == 0); + return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags); +#elif defined(HUF_FORCE_DECOMPRESS_X2) + (void)algoNb; + assert(algoNb == 1); + return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags); +#else + return algoNb ? HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags) : + HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, flags); +#endif + } +} diff --git a/src/commonlib/bsd/zstd/decompress/zstd_ddict.c b/src/commonlib/bsd/zstd/decompress/zstd_ddict.c new file mode 100644 index 00000000000..d1ec182f4ce --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/zstd_ddict.c @@ -0,0 +1,246 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* zstd_ddict.c : + * concentrates all logic that needs to know the internals of ZSTD_DDict object */ + +/*-******************************************************* +* Dependencies +*********************************************************/ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customFree */ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ +#include "../common/cpu.h" /* bmi2 */ +#include "../common/mem.h" /* low level memory routines */ +#define FSE_STATIC_LINKING_ONLY +#include "../common/fse.h" +#include "../common/huf.h" +#include "zstd_decompress_internal.h" +#include "zstd_ddict.h" + +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) +# include "../legacy/zstd_legacy.h" +#endif + + + +/*-******************************************************* +* Types +*********************************************************/ +struct ZSTD_DDict_s { + void* dictBuffer; + const void* dictContent; + size_t dictSize; + ZSTD_entropyDTables_t entropy; + U32 dictID; + U32 entropyPresent; + ZSTD_customMem cMem; +}; /* typedef'd to ZSTD_DDict within "zstd.h" */ + +const void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict) +{ + assert(ddict != NULL); + return ddict->dictContent; +} + +size_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict) +{ + assert(ddict != NULL); + return ddict->dictSize; +} + +void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) +{ + DEBUGLOG(4, "ZSTD_copyDDictParameters"); + assert(dctx != NULL); + assert(ddict != NULL); + dctx->dictID = ddict->dictID; + dctx->prefixStart = ddict->dictContent; + dctx->virtualStart = ddict->dictContent; + dctx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize; + dctx->previousDstEnd = dctx->dictEnd; +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + dctx->dictContentBeginForFuzzing = dctx->prefixStart; + dctx->dictContentEndForFuzzing = dctx->previousDstEnd; +#endif + if (ddict->entropyPresent) { + dctx->litEntropy = 1; + dctx->fseEntropy = 1; + dctx->LLTptr = ddict->entropy.LLTable; + dctx->MLTptr = ddict->entropy.MLTable; + dctx->OFTptr = ddict->entropy.OFTable; + dctx->HUFptr = ddict->entropy.hufTable; + dctx->entropy.rep[0] = ddict->entropy.rep[0]; + dctx->entropy.rep[1] = ddict->entropy.rep[1]; + dctx->entropy.rep[2] = ddict->entropy.rep[2]; + } else { + dctx->litEntropy = 0; + dctx->fseEntropy = 0; + } +} + + +static size_t +ZSTD_loadEntropy_intoDDict(ZSTD_DDict* ddict, + ZSTD_dictContentType_e dictContentType) +{ + ddict->dictID = 0; + ddict->entropyPresent = 0; + if (dictContentType == ZSTD_dct_rawContent) return 0; + + if (ddict->dictSize < 8) { + if (dictContentType == ZSTD_dct_fullDict) + return ERROR(dictionary_corrupted); /* only accept specified dictionaries */ + return 0; /* pure content mode */ + } + { U32 const magic = MEM_readLE32(ddict->dictContent); + if (magic != ZSTD_MAGIC_DICTIONARY) { + if (dictContentType == ZSTD_dct_fullDict) + return ERROR(dictionary_corrupted); /* only accept specified dictionaries */ + return 0; /* pure content mode */ + } + } + ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_FRAMEIDSIZE); + + /* load entropy tables */ + RETURN_ERROR_IF(ZSTD_isError(ZSTD_loadDEntropy( + &ddict->entropy, ddict->dictContent, ddict->dictSize)), + dictionary_corrupted, ""); + ddict->entropyPresent = 1; + return 0; +} + + +static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) +{ + if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) { + ddict->dictBuffer = NULL; + ddict->dictContent = dict; + if (!dict) dictSize = 0; + } else { + void* const internalBuffer = ZSTD_customMalloc(dictSize, ddict->cMem); + ddict->dictBuffer = internalBuffer; + ddict->dictContent = internalBuffer; + if (!internalBuffer) return ERROR(memory_allocation); + ZSTD_memcpy(internalBuffer, dict, dictSize); + } + ddict->dictSize = dictSize; + ddict->entropy.hufTable[0] = (HUF_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001); /* cover both little and big endian */ + + /* parse dictionary content */ + FORWARD_IF_ERROR( ZSTD_loadEntropy_intoDDict(ddict, dictContentType) , ""); + + return 0; +} + +ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_customMem customMem) +{ + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + + { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_customMalloc(sizeof(ZSTD_DDict), customMem); + if (ddict == NULL) return NULL; + ddict->cMem = customMem; + { size_t const initResult = ZSTD_initDDict_internal(ddict, + dict, dictSize, + dictLoadMethod, dictContentType); + if (ZSTD_isError(initResult)) { + ZSTD_freeDDict(ddict); + return NULL; + } } + return ddict; + } +} + +/*! ZSTD_createDDict() : +* Create a digested dictionary, to start decompression without startup delay. +* `dict` content is copied inside DDict. +* Consequently, `dict` can be released after `ZSTD_DDict` creation */ +ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize) +{ + ZSTD_customMem const allocator = { NULL, NULL, NULL }; + return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto, allocator); +} + +/*! ZSTD_createDDict_byReference() : + * Create a digested dictionary, to start decompression without startup delay. + * Dictionary content is simply referenced, it will be accessed during decompression. + * Warning : dictBuffer must outlive DDict (DDict must be freed before dictBuffer) */ +ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize) +{ + ZSTD_customMem const allocator = { NULL, NULL, NULL }; + return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto, allocator); +} + + +const ZSTD_DDict* ZSTD_initStaticDDict( + void* sBuffer, size_t sBufferSize, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType) +{ + size_t const neededSpace = sizeof(ZSTD_DDict) + + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize); + ZSTD_DDict* const ddict = (ZSTD_DDict*)sBuffer; + assert(sBuffer != NULL); + assert(dict != NULL); + if ((size_t)sBuffer & 7) return NULL; /* 8-aligned */ + if (sBufferSize < neededSpace) return NULL; + if (dictLoadMethod == ZSTD_dlm_byCopy) { + ZSTD_memcpy(ddict+1, dict, dictSize); /* local copy */ + dict = ddict+1; + } + if (ZSTD_isError( ZSTD_initDDict_internal(ddict, + dict, dictSize, + ZSTD_dlm_byRef, dictContentType) )) + return NULL; + return ddict; +} + + +size_t ZSTD_freeDDict(ZSTD_DDict* ddict) +{ + if (ddict==NULL) return 0; /* support free on NULL */ + { ZSTD_customMem const cMem = ddict->cMem; + ZSTD_customFree(ddict->dictBuffer, cMem); + ZSTD_customFree(ddict, cMem); + return 0; + } +} + +/*! ZSTD_estimateDDictSize() : + * Estimate amount of memory that will be needed to create a dictionary for decompression. + * Note : dictionary created by reference using ZSTD_dlm_byRef are smaller */ +size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod) +{ + return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize); +} + +size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict) +{ + if (ddict==NULL) return 0; /* support sizeof on NULL */ + return sizeof(*ddict) + (ddict->dictBuffer ? ddict->dictSize : 0) ; +} + +/*! ZSTD_getDictID_fromDDict() : + * Provides the dictID of the dictionary loaded into `ddict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict) +{ + if (ddict==NULL) return 0; + return ddict->dictID; +} diff --git a/src/commonlib/bsd/zstd/decompress/zstd_ddict.h b/src/commonlib/bsd/zstd/decompress/zstd_ddict.h new file mode 100644 index 00000000000..ef8000417a1 --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/zstd_ddict.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +#ifndef ZSTD_DDICT_H +#define ZSTD_DDICT_H + +/*-******************************************************* + * Dependencies + *********************************************************/ +#include "../common/zstd_deps.h" /* size_t */ +#include "../zstd.h" /* ZSTD_DDict, and several public functions */ + + +/*-******************************************************* + * Interface + *********************************************************/ + +/* note: several prototypes are already published in `zstd.h` : + * ZSTD_createDDict() + * ZSTD_createDDict_byReference() + * ZSTD_createDDict_advanced() + * ZSTD_freeDDict() + * ZSTD_initStaticDDict() + * ZSTD_sizeof_DDict() + * ZSTD_estimateDDictSize() + * ZSTD_getDictID_fromDict() + */ + +const void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict); +size_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict); + +void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); + + + +#endif /* ZSTD_DDICT_H */ diff --git a/src/commonlib/bsd/zstd/decompress/zstd_decompress.c b/src/commonlib/bsd/zstd/decompress/zstd_decompress.c new file mode 100644 index 00000000000..e87776a68c2 --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/zstd_decompress.c @@ -0,0 +1,922 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +/* *************************************************************** +* Tuning parameters +*****************************************************************/ + +/*! +* LEGACY_SUPPORT : +* if set to 1+, ZSTD_decompress() can decode older formats (v0.1+) +*/ +#ifndef ZSTD_LEGACY_SUPPORT +# define ZSTD_LEGACY_SUPPORT 0 +#endif + +/*! + * MAXWINDOWSIZE_DEFAULT : + * maximum window size accepted by DStream __by default__. + * Frames requiring more memory will be rejected. + * It's possible to set a different limit using ZSTD_DCtx_setMaxWindowSize(). + */ +#ifndef ZSTD_MAXWINDOWSIZE_DEFAULT +# define ZSTD_MAXWINDOWSIZE_DEFAULT (((U32)1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT) + 1) +#endif + +/*! + * NO_FORWARD_PROGRESS_MAX : + * maximum allowed nb of calls to ZSTD_decompressStream() + * without any forward progress + * (defined as: no byte read from input, and no byte flushed to output) + * before triggering an error. + */ +#ifndef ZSTD_NO_FORWARD_PROGRESS_MAX +# define ZSTD_NO_FORWARD_PROGRESS_MAX 16 +#endif + + +/*-******************************************************* +* Dependencies +*********************************************************/ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ +#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */ +#include "../common/error_private.h" +#include "../common/zstd_internal.h" /* blockProperties_t */ +#include "../common/mem.h" /* low level memory routines */ +#include "../common/zstd_bits.h" /* ZSTD_highbit32 */ +#define FSE_STATIC_LINKING_ONLY +#include "../common/fse.h" +#include "../common/huf.h" +#include +#include "zstd_decompress_internal.h" /* ZSTD_DCtx */ +#include "zstd_ddict.h" /* ZSTD_DDictDictContent */ +#include "zstd_decompress_block.h" /* ZSTD_decompressBlock_internal */ + +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) +# include "../legacy/zstd_legacy.h" +#endif + +/*-************************************************************* +* Context management +***************************************************************/ +size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) +{ + if (dctx==NULL) return 0; /* support sizeof NULL */ + return sizeof(*dctx) + + dctx->inBuffSize + dctx->outBuffSize; +} + +size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); } + +static size_t ZSTD_startingInputLength(ZSTD_format_e format) +{ + size_t const startingInputLength = ZSTD_FRAMEHEADERSIZE_PREFIX(format); + /* only supports formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless */ + assert( (format == ZSTD_f_zstd1) || (format == ZSTD_f_zstd1_magicless) ); + return startingInputLength; +} + +static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx) +{ + assert(dctx->streamStage == zdss_init); + dctx->format = ZSTD_f_zstd1; + dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; + dctx->outBufferMode = ZSTD_bm_buffered; + dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum; + dctx->refMultipleDDicts = ZSTD_rmd_refSingleDDict; + dctx->disableHufAsm = 0; + dctx->maxBlockSizeParam = 0; +} + +static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) +{ + dctx->staticSize = 0; + dctx->ddict = NULL; + dctx->dictEnd = NULL; + dctx->ddictIsCold = 0; + dctx->dictUses = ZSTD_dont_use; + dctx->inBuff = NULL; + dctx->inBuffSize = 0; + dctx->outBuffSize = 0; + dctx->streamStage = zdss_init; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) + dctx->legacyContext = NULL; + dctx->previousLegacyVersion = 0; +#endif + dctx->noForwardProgress = 0; + dctx->oversizedDuration = 0; + dctx->isFrameDecompression = 1; +#if DYNAMIC_BMI2 + dctx->bmi2 = ZSTD_cpuSupportsBmi2(); +#endif + ZSTD_DCtx_resetParameters(dctx); +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + dctx->dictContentEndForFuzzing = NULL; +#endif +} + +ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize) +{ + ZSTD_DCtx* const dctx = (ZSTD_DCtx*) workspace; + + if ((size_t)workspace & 7) return NULL; /* 8-aligned */ + if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL; /* minimum size */ + + ZSTD_initDCtx_internal(dctx); + dctx->staticSize = workspaceSize; + dctx->inBuff = (char*)(dctx+1); + return dctx; +} + +static ZSTD_DCtx* ZSTD_createDCtx_internal(ZSTD_customMem customMem) { + if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL; + + { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_customMalloc(sizeof(*dctx), customMem); + if (!dctx) return NULL; + dctx->customMem = customMem; + ZSTD_initDCtx_internal(dctx); + return dctx; + } +} + +ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) +{ + return ZSTD_createDCtx_internal(customMem); +} + +ZSTD_DCtx* ZSTD_createDCtx(void) +{ + DEBUGLOG(3, "ZSTD_createDCtx"); + return ZSTD_createDCtx_internal(ZSTD_defaultCMem); +} + +static void ZSTD_clearDict(ZSTD_DCtx* dctx) +{ + dctx->ddict = NULL; + dctx->dictUses = ZSTD_dont_use; +} + +size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx) +{ + if (dctx==NULL) return 0; /* support free on NULL */ + RETURN_ERROR_IF(dctx->staticSize, memory_allocation, "not compatible with static DCtx"); + { ZSTD_customMem const cMem = dctx->customMem; + ZSTD_clearDict(dctx); + ZSTD_customFree(dctx->inBuff, cMem); + dctx->inBuff = NULL; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (dctx->legacyContext) + ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion); +#endif + ZSTD_customFree(dctx, cMem); + return 0; + } +} + +/* no longer useful */ +void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) +{ + size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx); + ZSTD_memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */ +} + + +/*-************************************************************* + * Frame header decoding + ***************************************************************/ + +/*! ZSTD_isFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + * Note 3 : Skippable Frame Identifiers are considered valid. */ +unsigned ZSTD_isFrame(const void* buffer, size_t size) +{ + if (size < ZSTD_FRAMEIDSIZE) return 0; + { U32 const magic = MEM_readLE32(buffer); + if (magic == ZSTD_MAGICNUMBER) return 1; + if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1; + } +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (ZSTD_isLegacy(buffer, size)) return 1; +#endif + return 0; +} + +/*! ZSTD_isSkippableFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + */ +unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size) +{ + if (size < ZSTD_FRAMEIDSIZE) return 0; + { U32 const magic = MEM_readLE32(buffer); + if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1; + } + return 0; +} + +/** ZSTD_frameHeaderSize_internal() : + * srcSize must be large enough to reach header size fields. + * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless. + * @return : size of the Frame Header + * or an error code, which can be tested with ZSTD_isError() */ +static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format) +{ + size_t const minInputSize = ZSTD_startingInputLength(format); + RETURN_ERROR_IF(srcSize < minInputSize, srcSize_wrong, ""); + + { BYTE const fhd = ((const BYTE*)src)[minInputSize-1]; + U32 const dictID= fhd & 3; + U32 const singleSegment = (fhd >> 5) & 1; + U32 const fcsId = fhd >> 6; + return minInputSize + !singleSegment + + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId] + + (singleSegment && !fcsId); + } +} + +/** ZSTD_frameHeaderSize() : + * srcSize must be >= ZSTD_frameHeaderSize_prefix. + * @return : size of the Frame Header, + * or an error code (if srcSize is too small) */ +size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize) +{ + return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1); +} + +/** ZSTD_getFrameHeader_advanced() : + * decode Frame Header, or require larger `srcSize`. + * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless + * @return : 0, `zfhPtr` is correctly filled, + * >0, `srcSize` is too small, value is wanted `srcSize` amount, +** or an error code, which can be tested using ZSTD_isError() */ +size_t ZSTD_getFrameHeader_advanced(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format) +{ + const BYTE* ip = (const BYTE*)src; + size_t const minInputSize = ZSTD_startingInputLength(format); + + DEBUGLOG(5, "ZSTD_getFrameHeader_advanced: minInputSize = %zu, srcSize = %zu", minInputSize, srcSize); + + if (srcSize > 0) { + /* note : technically could be considered an assert(), since it's an invalid entry */ + RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter : src==NULL, but srcSize>0"); + } + if (srcSize < minInputSize) { + if (srcSize > 0 && format != ZSTD_f_zstd1_magicless) { + /* when receiving less than @minInputSize bytes, + * control these bytes at least correspond to a supported magic number + * in order to error out early if they don't. + **/ + size_t const toCopy = MIN(4, srcSize); + unsigned char hbuf[4]; MEM_writeLE32(hbuf, ZSTD_MAGICNUMBER); + assert(src != NULL); + ZSTD_memcpy(hbuf, src, toCopy); + if ( MEM_readLE32(hbuf) != ZSTD_MAGICNUMBER ) { + /* not a zstd frame : let's check if it's a skippable frame */ + MEM_writeLE32(hbuf, ZSTD_MAGIC_SKIPPABLE_START); + ZSTD_memcpy(hbuf, src, toCopy); + if ((MEM_readLE32(hbuf) & ZSTD_MAGIC_SKIPPABLE_MASK) != ZSTD_MAGIC_SKIPPABLE_START) { + RETURN_ERROR(prefix_unknown, + "first bytes don't correspond to any supported magic number"); + } } } + return minInputSize; + } + + ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzers may not understand that zfhPtr will be read only if return value is zero, since they are 2 different signals */ + if ( (format != ZSTD_f_zstd1_magicless) + && (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) { + if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { + /* skippable frame */ + if (srcSize < ZSTD_SKIPPABLEHEADERSIZE) + return ZSTD_SKIPPABLEHEADERSIZE; /* magic number + frame length */ + ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); + zfhPtr->frameType = ZSTD_skippableFrame; + zfhPtr->dictID = MEM_readLE32(src) - ZSTD_MAGIC_SKIPPABLE_START; + zfhPtr->headerSize = ZSTD_SKIPPABLEHEADERSIZE; + zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE); + return 0; + } + RETURN_ERROR(prefix_unknown, ""); + } + + /* ensure there is enough `srcSize` to fully read/decode frame header */ + { size_t const fhsize = ZSTD_frameHeaderSize_internal(src, srcSize, format); + if (srcSize < fhsize) return fhsize; + zfhPtr->headerSize = (U32)fhsize; + } + + { BYTE const fhdByte = ip[minInputSize-1]; + size_t pos = minInputSize; + U32 const dictIDSizeCode = fhdByte&3; + U32 const checksumFlag = (fhdByte>>2)&1; + U32 const singleSegment = (fhdByte>>5)&1; + U32 const fcsID = fhdByte>>6; + U64 windowSize = 0; + U32 dictID = 0; + U64 frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; + RETURN_ERROR_IF((fhdByte & 0x08) != 0, frameParameter_unsupported, + "reserved bits, must be zero"); + + if (!singleSegment) { + BYTE const wlByte = ip[pos++]; + U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN; + RETURN_ERROR_IF(windowLog > ZSTD_WINDOWLOG_MAX, frameParameter_windowTooLarge, ""); + windowSize = (1ULL << windowLog); + windowSize += (windowSize >> 3) * (wlByte&7); + } + switch(dictIDSizeCode) + { + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; + case 0 : break; + case 1 : dictID = ip[pos]; pos++; break; + case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break; + case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break; + } + switch(fcsID) + { + default: + assert(0); /* impossible */ + ZSTD_FALLTHROUGH; + case 0 : if (singleSegment) frameContentSize = ip[pos]; break; + case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break; + case 2 : frameContentSize = MEM_readLE32(ip+pos); break; + case 3 : frameContentSize = MEM_readLE64(ip+pos); break; + } + if (singleSegment) windowSize = frameContentSize; + + zfhPtr->frameType = ZSTD_frame; + zfhPtr->frameContentSize = frameContentSize; + zfhPtr->windowSize = windowSize; + zfhPtr->blockSizeMax = (unsigned) MIN(windowSize, ZSTD_BLOCKSIZE_MAX); + zfhPtr->dictID = dictID; + zfhPtr->checksumFlag = checksumFlag; + } + return 0; +} + +/** ZSTD_getFrameHeader() : + * decode Frame Header, or require larger `srcSize`. + * note : this function does not consume input, it only reads it. + * @return : 0, `zfhPtr` is correctly filled, + * >0, `srcSize` is too small, value is wanted `srcSize` amount, + * or an error code, which can be tested using ZSTD_isError() */ +size_t ZSTD_getFrameHeader(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize) +{ + return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1); +} + +static size_t readSkippableFrameSize(void const* src, size_t srcSize) +{ + size_t const skippableHeaderSize = ZSTD_SKIPPABLEHEADERSIZE; + U32 sizeU32; + + RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, ""); + + sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE); + RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32, + frameParameter_unsupported, ""); + { size_t const skippableSize = skippableHeaderSize + sizeU32; + RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong, ""); + return skippableSize; + } +} + +/** ZSTD_decodeFrameHeader() : + * `headerSize` must be the size provided by ZSTD_frameHeaderSize(). + * If multiple DDict references are enabled, also will choose the correct DDict to use. + * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */ +static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize) +{ + size_t const result = ZSTD_getFrameHeader_advanced(&(dctx->fParams), src, headerSize, dctx->format); + if (ZSTD_isError(result)) return result; /* invalid header */ + RETURN_ERROR_IF(result>0, srcSize_wrong, "headerSize too small"); + +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* Skip the dictID check in fuzzing mode, because it makes the search + * harder. + */ + RETURN_ERROR_IF(dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID), + dictionary_wrong, ""); +#endif + dctx->validateChecksum = (dctx->fParams.checksumFlag && !dctx->forceIgnoreChecksum) ? 1 : 0; + if (dctx->validateChecksum) XXH64_reset(&dctx->xxhState, 0); + dctx->processedCSize += headerSize; + return 0; +} + +static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, + const void* src, size_t srcSize) +{ + DEBUGLOG(5, "ZSTD_copyRawBlock"); + RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall, ""); + if (dst == NULL) { + if (srcSize == 0) return 0; + RETURN_ERROR(dstBuffer_null, ""); + } + ZSTD_memmove(dst, src, srcSize); + return srcSize; +} + +static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity, + BYTE b, + size_t regenSize) +{ + RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall, ""); + if (dst == NULL) { + if (regenSize == 0) return 0; + RETURN_ERROR(dstBuffer_null, ""); + } + ZSTD_memset(dst, b, regenSize); + return regenSize; +} + +static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 compressedSize, int streaming) +{ +#if ZSTD_TRACE + if (dctx->traceCtx && ZSTD_trace_decompress_end != NULL) { + ZSTD_Trace trace; + ZSTD_memset(&trace, 0, sizeof(trace)); + trace.version = ZSTD_VERSION_NUMBER; + trace.streaming = streaming; + if (dctx->ddict) { + trace.dictionaryID = ZSTD_getDictID_fromDDict(dctx->ddict); + trace.dictionarySize = ZSTD_DDict_dictSize(dctx->ddict); + trace.dictionaryIsCold = dctx->ddictIsCold; + } + trace.uncompressedSize = (size_t)uncompressedSize; + trace.compressedSize = (size_t)compressedSize; + trace.dctx = dctx; + ZSTD_trace_decompress_end(dctx->traceCtx, &trace); + } +#else + (void)dctx; + (void)uncompressedSize; + (void)compressedSize; + (void)streaming; +#endif +} + +/*! ZSTD_decompressFrame() : + * @dctx must be properly initialized + * will update *srcPtr and *srcSizePtr, + * to make *srcPtr progress by one frame. */ +static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void** srcPtr, size_t *srcSizePtr) +{ + const BYTE* const istart = (const BYTE*)(*srcPtr); + const BYTE* ip = istart; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = dstCapacity != 0 ? ostart + dstCapacity : ostart; + BYTE* op = ostart; + size_t remainingSrcSize = *srcSizePtr; + + DEBUGLOG(4, "ZSTD_decompressFrame (srcSize:%i)", (int)*srcSizePtr); + + /* check */ + RETURN_ERROR_IF( + remainingSrcSize < ZSTD_FRAMEHEADERSIZE_MIN(dctx->format)+ZSTD_blockHeaderSize, + srcSize_wrong, ""); + + /* Frame Header */ + { size_t const frameHeaderSize = ZSTD_frameHeaderSize_internal( + ip, ZSTD_FRAMEHEADERSIZE_PREFIX(dctx->format), dctx->format); + if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize; + RETURN_ERROR_IF(remainingSrcSize < frameHeaderSize+ZSTD_blockHeaderSize, + srcSize_wrong, ""); + FORWARD_IF_ERROR( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) , ""); + ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize; + } + + /* Shrink the blockSizeMax if enabled */ + if (dctx->maxBlockSizeParam != 0) + dctx->fParams.blockSizeMax = MIN(dctx->fParams.blockSizeMax, (unsigned)dctx->maxBlockSizeParam); + + /* Loop on each block */ + while (1) { + BYTE* oBlockEnd = oend; + size_t decodedSize; + blockProperties_t blockProperties; + size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSrcSize, &blockProperties); + if (ZSTD_isError(cBlockSize)) return cBlockSize; + + ip += ZSTD_blockHeaderSize; + remainingSrcSize -= ZSTD_blockHeaderSize; + RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong, ""); + + if (ip >= op && ip < oBlockEnd) { + /* We are decompressing in-place. Limit the output pointer so that we + * don't overwrite the block that we are currently reading. This will + * fail decompression if the input & output pointers aren't spaced + * far enough apart. + * + * This is important to set, even when the pointers are far enough + * apart, because ZSTD_decompressBlock_internal() can decide to store + * literals in the output buffer, after the block it is decompressing. + * Since we don't want anything to overwrite our input, we have to tell + * ZSTD_decompressBlock_internal to never write past ip. + * + * See ZSTD_allocateLiteralsBuffer() for reference. + */ + oBlockEnd = op + (ip - op); + } + + switch(blockProperties.blockType) + { + case bt_compressed: + assert(dctx->isFrameDecompression == 1); + decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, not_streaming); + break; + case bt_raw : + /* Use oend instead of oBlockEnd because this function is safe to overlap. It uses memmove. */ + decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize); + break; + case bt_rle : + decodedSize = ZSTD_setRleBlock(op, (size_t)(oBlockEnd-op), *ip, blockProperties.origSize); + break; + case bt_reserved : + default: + RETURN_ERROR(corruption_detected, "invalid block type"); + } + FORWARD_IF_ERROR(decodedSize, "Block decompression failure"); + DEBUGLOG(5, "Decompressed block of dSize = %u", (unsigned)decodedSize); + if (dctx->validateChecksum) { + XXH64_update(&dctx->xxhState, op, decodedSize); + } + if (decodedSize) /* support dst = NULL,0 */ { + op += decodedSize; + } + assert(ip != NULL); + ip += cBlockSize; + remainingSrcSize -= cBlockSize; + if (blockProperties.lastBlock) break; + } + + if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) { + RETURN_ERROR_IF((U64)(op-ostart) != dctx->fParams.frameContentSize, + corruption_detected, ""); + } + if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */ + RETURN_ERROR_IF(remainingSrcSize<4, checksum_wrong, ""); + if (!dctx->forceIgnoreChecksum) { + U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState); + U32 checkRead; + checkRead = MEM_readLE32(ip); + RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong, ""); + } + ip += 4; + remainingSrcSize -= 4; + } + ZSTD_DCtx_trace_end(dctx, (U64)(op-ostart), (U64)(ip-istart), /* streaming */ 0); + /* Allow caller to get size read */ + DEBUGLOG(4, "ZSTD_decompressFrame: decompressed frame of size %i, consuming %i bytes of input", (int)(op-ostart), (int)(ip - (const BYTE*)*srcPtr)); + *srcPtr = ip; + *srcSizePtr = remainingSrcSize; + return (size_t)(op-ostart); +} + +static +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize, + const ZSTD_DDict* ddict) +{ + void* const dststart = dst; + int moreThan1Frame = 0; + + DEBUGLOG(5, "ZSTD_decompressMultiFrame"); + assert(dict==NULL || ddict==NULL); /* either dict or ddict set, not both */ + + if (ddict) { + dict = ZSTD_DDict_dictContent(ddict); + dictSize = ZSTD_DDict_dictSize(ddict); + } + + while (srcSize >= ZSTD_startingInputLength(dctx->format)) { + +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) + if (dctx->format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize)) { + size_t decodedSize; + size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize); + if (ZSTD_isError(frameSize)) return frameSize; + RETURN_ERROR_IF(dctx->staticSize, memory_allocation, + "legacy support is not compatible with static dctx"); + + decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize); + if (ZSTD_isError(decodedSize)) return decodedSize; + + { + unsigned long long const expectedSize = ZSTD_getFrameContentSize(src, srcSize); + RETURN_ERROR_IF(expectedSize == ZSTD_CONTENTSIZE_ERROR, corruption_detected, "Corrupted frame header!"); + if (expectedSize != ZSTD_CONTENTSIZE_UNKNOWN) { + RETURN_ERROR_IF(expectedSize != decodedSize, corruption_detected, + "Frame header size does not match decoded size!"); + } + } + + assert(decodedSize <= dstCapacity); + dst = (BYTE*)dst + decodedSize; + dstCapacity -= decodedSize; + + src = (const BYTE*)src + frameSize; + srcSize -= frameSize; + + continue; + } +#endif + + if (dctx->format == ZSTD_f_zstd1 && srcSize >= 4) { + U32 const magicNumber = MEM_readLE32(src); + DEBUGLOG(5, "reading magic number %08X", (unsigned)magicNumber); + if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { + /* skippable frame detected : skip it */ + size_t const skippableSize = readSkippableFrameSize(src, srcSize); + FORWARD_IF_ERROR(skippableSize, "invalid skippable frame"); + assert(skippableSize <= srcSize); + + src = (const BYTE *)src + skippableSize; + srcSize -= skippableSize; + continue; /* check next frame */ + } } + + if (ddict) { + /* we were called from ZSTD_decompress_usingDDict */ + FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(dctx, ddict), ""); + } else { + /* this will initialize correctly with no dict if dict == NULL, so + * use this in all cases but ddict */ + FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize), ""); + } + ZSTD_checkContinuity(dctx, dst, dstCapacity); + + { const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity, + &src, &srcSize); + RETURN_ERROR_IF( + (ERR_getErrorCode(res) == ZSTD_error_prefix_unknown) + && (moreThan1Frame==1), + srcSize_wrong, + "At least one frame successfully completed, " + "but following bytes are garbage: " + "it's more likely to be a srcSize error, " + "specifying more input bytes than size of frame(s). " + "Note: one could be unlucky, it might be a corruption error instead, " + "happening right at the place where we expect zstd magic bytes. " + "But this is _much_ less likely than a srcSize field error."); + if (ZSTD_isError(res)) return res; + assert(res <= dstCapacity); + if (res != 0) + dst = (BYTE*)dst + res; + dstCapacity -= res; + } + moreThan1Frame = 1; + } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */ + + RETURN_ERROR_IF(srcSize, srcSize_wrong, "input not entirely consumed"); + + return (size_t)((BYTE*)dst - (BYTE*)dststart); +} + +size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize) +{ + return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL); +} + +static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx) +{ + switch (dctx->dictUses) { + default: + assert(0 /* Impossible */); + ZSTD_FALLTHROUGH; + case ZSTD_dont_use: + ZSTD_clearDict(dctx); + return NULL; + case ZSTD_use_indefinitely: + return dctx->ddict; + case ZSTD_use_once: + dctx->dictUses = ZSTD_dont_use; + return dctx->ddict; + } +} + +size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) +{ + return ZSTD_decompress_usingDDict(dctx, dst, dstCapacity, src, srcSize, ZSTD_getDDict(dctx)); +} + +static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + dctx->dictEnd = dctx->previousDstEnd; + dctx->virtualStart = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart)); + dctx->prefixStart = dict; + dctx->previousDstEnd = (const char*)dict + dictSize; +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + dctx->dictContentBeginForFuzzing = dctx->prefixStart; + dctx->dictContentEndForFuzzing = dctx->previousDstEnd; +#endif + return 0; +} + + +/*! ZSTD_loadDEntropy() : + * dict : must point at beginning of a valid zstd dictionary. + * @return : size of entropy tables read */ +size_t +ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy, + const void* const dict, size_t const dictSize) +{ + const BYTE* dictPtr = (const BYTE*)dict; + const BYTE* const dictEnd = dictPtr + dictSize; + + RETURN_ERROR_IF(dictSize <= 8, dictionary_corrupted, "dict is too small"); + assert(MEM_readLE32(dict) == ZSTD_MAGIC_DICTIONARY); /* dict must be valid */ + dictPtr += 8; /* skip header = magic + dictID */ + + ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, OFTable) == offsetof(ZSTD_entropyDTables_t, LLTable) + sizeof(entropy->LLTable)); + ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, MLTable) == offsetof(ZSTD_entropyDTables_t, OFTable) + sizeof(entropy->OFTable)); + ZSTD_STATIC_ASSERT(sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable) >= HUF_DECOMPRESS_WORKSPACE_SIZE); + { void* const workspace = &entropy->LLTable; /* use fse tables as temporary workspace; implies fse tables are grouped together */ + size_t const workspaceSize = sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable); +#ifdef HUF_FORCE_DECOMPRESS_X1 + /* in minimal huffman, we always use X1 variants */ + size_t const hSize = HUF_readDTableX1_wksp(entropy->hufTable, + dictPtr, dictEnd - dictPtr, + workspace, workspaceSize, /* flags */ 0); +#else + size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable, + dictPtr, (size_t)(dictEnd - dictPtr), + workspace, workspaceSize, /* flags */ 0); +#endif + RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted, ""); + dictPtr += hSize; + } + + { short offcodeNCount[MaxOff+1]; + unsigned offcodeMaxValue = MaxOff, offcodeLog; + size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(offcodeMaxValue > MaxOff, dictionary_corrupted, ""); + RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, ""); + ZSTD_buildFSETable( entropy->OFTable, + offcodeNCount, offcodeMaxValue, + OF_base, OF_bits, + offcodeLog, + entropy->workspace, sizeof(entropy->workspace), + /* bmi2 */0); + dictPtr += offcodeHeaderSize; + } + + { short matchlengthNCount[MaxML+1]; + unsigned matchlengthMaxValue = MaxML, matchlengthLog; + size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(matchlengthMaxValue > MaxML, dictionary_corrupted, ""); + RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, ""); + ZSTD_buildFSETable( entropy->MLTable, + matchlengthNCount, matchlengthMaxValue, + ML_base, ML_bits, + matchlengthLog, + entropy->workspace, sizeof(entropy->workspace), + /* bmi2 */ 0); + dictPtr += matchlengthHeaderSize; + } + + { short litlengthNCount[MaxLL+1]; + unsigned litlengthMaxValue = MaxLL, litlengthLog; + size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr)); + RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, ""); + RETURN_ERROR_IF(litlengthMaxValue > MaxLL, dictionary_corrupted, ""); + RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, ""); + ZSTD_buildFSETable( entropy->LLTable, + litlengthNCount, litlengthMaxValue, + LL_base, LL_bits, + litlengthLog, + entropy->workspace, sizeof(entropy->workspace), + /* bmi2 */ 0); + dictPtr += litlengthHeaderSize; + } + + RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted, ""); + { int i; + size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12)); + for (i=0; i<3; i++) { + U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4; + RETURN_ERROR_IF(rep==0 || rep > dictContentSize, + dictionary_corrupted, ""); + entropy->rep[i] = rep; + } } + + return (size_t)(dictPtr - (const BYTE*)dict); +} + +static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize); + { U32 const magic = MEM_readLE32(dict); + if (magic != ZSTD_MAGIC_DICTIONARY) { + return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */ + } } + dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE); + + /* load entropy tables */ + { size_t const eSize = ZSTD_loadDEntropy(&dctx->entropy, dict, dictSize); + RETURN_ERROR_IF(ZSTD_isError(eSize), dictionary_corrupted, ""); + dict = (const char*)dict + eSize; + dictSize -= eSize; + } + dctx->litEntropy = dctx->fseEntropy = 1; + + /* reference dictionary content */ + return ZSTD_refDictContent(dctx, dict, dictSize); +} + +size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) +{ + assert(dctx != NULL); +#if ZSTD_TRACE + dctx->traceCtx = (ZSTD_trace_decompress_begin != NULL) ? ZSTD_trace_decompress_begin(dctx) : 0; +#endif + dctx->expected = ZSTD_startingInputLength(dctx->format); /* dctx->format must be properly set */ + dctx->stage = ZSTDds_getFrameHeaderSize; + dctx->processedCSize = 0; + dctx->decodedSize = 0; + dctx->previousDstEnd = NULL; + dctx->prefixStart = NULL; + dctx->virtualStart = NULL; + dctx->dictEnd = NULL; + dctx->entropy.hufTable[0] = (HUF_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001); /* cover both little and big endian */ + dctx->litEntropy = dctx->fseEntropy = 0; + dctx->dictID = 0; + dctx->bType = bt_reserved; + dctx->isFrameDecompression = 1; + ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue)); + ZSTD_memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */ + dctx->LLTptr = dctx->entropy.LLTable; + dctx->MLTptr = dctx->entropy.MLTable; + dctx->OFTptr = dctx->entropy.OFTable; + dctx->HUFptr = dctx->entropy.hufTable; + return 0; +} + +size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) +{ + FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) , ""); + if (dict && dictSize) + RETURN_ERROR_IF( + ZSTD_isError(ZSTD_decompress_insertDictionary(dctx, dict, dictSize)), + dictionary_corrupted, ""); + return 0; +} + + +/* ====== ZSTD_DDict ====== */ + +size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) +{ + DEBUGLOG(4, "ZSTD_decompressBegin_usingDDict"); + assert(dctx != NULL); + if (ddict) { + const char* const dictStart = (const char*)ZSTD_DDict_dictContent(ddict); + size_t const dictSize = ZSTD_DDict_dictSize(ddict); + const void* const dictEnd = dictStart + dictSize; + dctx->ddictIsCold = (dctx->dictEnd != dictEnd); + DEBUGLOG(4, "DDict is %s", + dctx->ddictIsCold ? "~cold~" : "hot!"); + } + FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) , ""); + if (ddict) { /* NULL ddict is equivalent to no dictionary */ + ZSTD_copyDDictParameters(dctx, ddict); + } + return 0; +} + +/*! ZSTD_decompress_usingDDict() : +* Decompression using a pre-digested Dictionary +* Use dictionary without significant overhead. */ +size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_DDict* ddict) +{ + /* pass content and size in case legacy frames are encountered */ + return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, + NULL, 0, + ddict); +} diff --git a/src/commonlib/bsd/zstd/decompress/zstd_decompress_block.c b/src/commonlib/bsd/zstd/decompress/zstd_decompress_block.c new file mode 100644 index 00000000000..3a963792a4a --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/zstd_decompress_block.c @@ -0,0 +1,2188 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +/* zstd_decompress_block : + * this module takes care of decompressing _compressed_ block */ + +/*-******************************************************* +* Dependencies +*********************************************************/ +#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */ +#include "../common/zstd_compiler.h" /* prefetch */ +#include "../common/cpu.h" /* bmi2 */ +#include "../common/mem.h" /* low level memory routines */ +#define FSE_STATIC_LINKING_ONLY +#include "../common/fse.h" +#include "../common/huf.h" +#include "../common/zstd_internal.h" +#include "zstd_decompress_internal.h" /* ZSTD_DCtx */ +#include "zstd_ddict.h" /* ZSTD_DDictDictContent */ +#include "zstd_decompress_block.h" +#include "../common/zstd_bits.h" /* ZSTD_highbit32 */ + +/*_******************************************************* +* Macros +**********************************************************/ + +/* These two optional macros force the use one way or another of the two + * ZSTD_decompressSequences implementations. You can't force in both directions + * at the same time. + */ +#if defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \ + defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG) +#error "Cannot force the use of the short and the long ZSTD_decompressSequences variants!" +#endif + + +/*_******************************************************* +* Memory operations +**********************************************************/ +static void ZSTD_copy4(void* dst, const void* src) { ZSTD_memcpy(dst, src, 4); } + + +/*-************************************************************* + * Block decoding + ***************************************************************/ + +static size_t ZSTD_blockSizeMax(ZSTD_DCtx const* dctx) +{ + size_t const blockSizeMax = dctx->isFrameDecompression ? dctx->fParams.blockSizeMax : ZSTD_BLOCKSIZE_MAX; + assert(blockSizeMax <= ZSTD_BLOCKSIZE_MAX); + return blockSizeMax; +} + +/*! ZSTD_getcBlockSize() : + * Provides the size of compressed block from block header `src` */ +size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, + blockProperties_t* bpPtr) +{ + RETURN_ERROR_IF(srcSize < ZSTD_blockHeaderSize, srcSize_wrong, ""); + + { U32 const cBlockHeader = MEM_readLE24(src); + U32 const cSize = cBlockHeader >> 3; + bpPtr->lastBlock = cBlockHeader & 1; + bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3); + bpPtr->origSize = cSize; /* only useful for RLE */ + if (bpPtr->blockType == bt_rle) return 1; + RETURN_ERROR_IF(bpPtr->blockType == bt_reserved, corruption_detected, ""); + return cSize; + } +} + +/* Allocate buffer for literals, either overlapping current dst, or split between dst and litExtraBuffer, or stored entirely within litExtraBuffer */ +static void ZSTD_allocateLiteralsBuffer(ZSTD_DCtx* dctx, void* const dst, const size_t dstCapacity, const size_t litSize, + const streaming_operation streaming, const size_t expectedWriteSize, const unsigned splitImmediately) +{ + size_t const blockSizeMax = ZSTD_blockSizeMax(dctx); + assert(litSize <= blockSizeMax); + assert(dctx->isFrameDecompression || streaming == not_streaming); + assert(expectedWriteSize <= blockSizeMax); + if (streaming == not_streaming && dstCapacity > blockSizeMax + WILDCOPY_OVERLENGTH + litSize + WILDCOPY_OVERLENGTH) { + /* If we aren't streaming, we can just put the literals after the output + * of the current block. We don't need to worry about overwriting the + * extDict of our window, because it doesn't exist. + * So if we have space after the end of the block, just put it there. + */ + dctx->litBuffer = (BYTE*)dst + blockSizeMax + WILDCOPY_OVERLENGTH; + dctx->litBufferEnd = dctx->litBuffer + litSize; + dctx->litBufferLocation = ZSTD_in_dst; + } else if (litSize <= ZSTD_LITBUFFEREXTRASIZE) { + /* Literals fit entirely within the extra buffer, put them there to avoid + * having to split the literals. + */ + dctx->litBuffer = dctx->litExtraBuffer; + dctx->litBufferEnd = dctx->litBuffer + litSize; + dctx->litBufferLocation = ZSTD_not_in_dst; + } else { + assert(blockSizeMax > ZSTD_LITBUFFEREXTRASIZE); + /* Literals must be split between the output block and the extra lit + * buffer. We fill the extra lit buffer with the tail of the literals, + * and put the rest of the literals at the end of the block, with + * WILDCOPY_OVERLENGTH of buffer room to allow for overreads. + * This MUST not write more than our maxBlockSize beyond dst, because in + * streaming mode, that could overwrite part of our extDict window. + */ + if (splitImmediately) { + /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */ + dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH; + dctx->litBufferEnd = dctx->litBuffer + litSize - ZSTD_LITBUFFEREXTRASIZE; + } else { + /* initially this will be stored entirely in dst during huffman decoding, it will partially be shifted to litExtraBuffer after */ + dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize; + dctx->litBufferEnd = (BYTE*)dst + expectedWriteSize; + } + dctx->litBufferLocation = ZSTD_split; + assert(dctx->litBufferEnd <= (BYTE*)dst + expectedWriteSize); + } +} + +/*! ZSTD_decodeLiteralsBlock() : + * Where it is possible to do so without being stomped by the output during decompression, the literals block will be stored + * in the dstBuffer. If there is room to do so, it will be stored in full in the excess dst space after where the current + * block will be output. Otherwise it will be stored at the end of the current dst blockspace, with a small portion being + * stored in dctx->litExtraBuffer to help keep it "ahead" of the current output write. + * + * @return : nb of bytes read from src (< srcSize ) + * note : symbol not declared but exposed for fullbench */ +static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, + const void* src, size_t srcSize, /* note : srcSize < BLOCKSIZE */ + void* dst, size_t dstCapacity, const streaming_operation streaming) +{ + DEBUGLOG(5, "ZSTD_decodeLiteralsBlock"); + RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected, ""); + + { const BYTE* const istart = (const BYTE*) src; + SymbolEncodingType_e const litEncType = (SymbolEncodingType_e)(istart[0] & 3); + size_t const blockSizeMax = ZSTD_blockSizeMax(dctx); + + switch(litEncType) + { + case set_repeat: + DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block"); + RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, ""); + ZSTD_FALLTHROUGH; + + case set_compressed: + RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need up to 5 for case 3"); + { size_t lhSize, litSize, litCSize; + U32 singleStream=0; + U32 const lhlCode = (istart[0] >> 2) & 3; + U32 const lhc = MEM_readLE32(istart); + size_t hufSuccess; + size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity); + int const flags = 0 + | (ZSTD_DCtx_get_bmi2(dctx) ? HUF_flags_bmi2 : 0) + | (dctx->disableHufAsm ? HUF_flags_disableAsm : 0); + switch(lhlCode) + { + case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */ + /* 2 - 2 - 10 - 10 */ + singleStream = !lhlCode; + lhSize = 3; + litSize = (lhc >> 4) & 0x3FF; + litCSize = (lhc >> 14) & 0x3FF; + break; + case 2: + /* 2 - 2 - 14 - 14 */ + lhSize = 4; + litSize = (lhc >> 4) & 0x3FFF; + litCSize = lhc >> 18; + break; + case 3: + /* 2 - 2 - 18 - 18 */ + lhSize = 5; + litSize = (lhc >> 4) & 0x3FFFF; + litCSize = (lhc >> 22) + ((size_t)istart[4] << 10); + break; + } + RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, ""); + if (!singleStream) + RETURN_ERROR_IF(litSize < MIN_LITERALS_FOR_4_STREAMS, literals_headerWrong, + "Not enough literals (%zu) for the 4-streams mode (min %u)", + litSize, MIN_LITERALS_FOR_4_STREAMS); + RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, ""); + RETURN_ERROR_IF(expectedWriteSize < litSize , dstSize_tooSmall, ""); + ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 0); + + /* prefetch huffman table if cold */ + if (dctx->ddictIsCold && (litSize > 768 /* heuristic */)) { + PREFETCH_AREA(dctx->HUFptr, sizeof(dctx->entropy.hufTable)); + } + + if (litEncType==set_repeat) { + if (singleStream) { + hufSuccess = HUF_decompress1X_usingDTable( + dctx->litBuffer, litSize, istart+lhSize, litCSize, + dctx->HUFptr, flags); + } else { + assert(litSize >= MIN_LITERALS_FOR_4_STREAMS); + hufSuccess = HUF_decompress4X_usingDTable( + dctx->litBuffer, litSize, istart+lhSize, litCSize, + dctx->HUFptr, flags); + } + } else { + if (singleStream) { +#if defined(HUF_FORCE_DECOMPRESS_X2) + hufSuccess = HUF_decompress1X_DCtx_wksp( + dctx->entropy.hufTable, dctx->litBuffer, litSize, + istart+lhSize, litCSize, dctx->workspace, + sizeof(dctx->workspace), flags); +#else + hufSuccess = HUF_decompress1X1_DCtx_wksp( + dctx->entropy.hufTable, dctx->litBuffer, litSize, + istart+lhSize, litCSize, dctx->workspace, + sizeof(dctx->workspace), flags); +#endif + } else { + hufSuccess = HUF_decompress4X_hufOnly_wksp( + dctx->entropy.hufTable, dctx->litBuffer, litSize, + istart+lhSize, litCSize, dctx->workspace, + sizeof(dctx->workspace), flags); + } + } + if (dctx->litBufferLocation == ZSTD_split) + { + assert(litSize > ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memcpy(dctx->litExtraBuffer, dctx->litBufferEnd - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memmove(dctx->litBuffer + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH, dctx->litBuffer, litSize - ZSTD_LITBUFFEREXTRASIZE); + dctx->litBuffer += ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH; + dctx->litBufferEnd -= WILDCOPY_OVERLENGTH; + assert(dctx->litBufferEnd <= (BYTE*)dst + blockSizeMax); + } + + RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, ""); + + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + dctx->litEntropy = 1; + if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable; + return litCSize + lhSize; + } + + case set_basic: + { size_t litSize, lhSize; + U32 const lhlCode = ((istart[0]) >> 2) & 3; + size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity); + switch(lhlCode) + { + case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ + lhSize = 1; + litSize = istart[0] >> 3; + break; + case 1: + lhSize = 2; + litSize = MEM_readLE16(istart) >> 4; + break; + case 3: + lhSize = 3; + RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize = 3"); + litSize = MEM_readLE24(istart) >> 4; + break; + } + + RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, ""); + RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, ""); + ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1); + if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */ + RETURN_ERROR_IF(litSize+lhSize > srcSize, corruption_detected, ""); + if (dctx->litBufferLocation == ZSTD_split) + { + ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize - ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memcpy(dctx->litExtraBuffer, istart + lhSize + litSize - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE); + } + else + { + ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize); + } + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + return lhSize+litSize; + } + /* direct reference into compressed stream */ + dctx->litPtr = istart+lhSize; + dctx->litSize = litSize; + dctx->litBufferEnd = dctx->litPtr + litSize; + dctx->litBufferLocation = ZSTD_not_in_dst; + return lhSize+litSize; + } + + case set_rle: + { U32 const lhlCode = ((istart[0]) >> 2) & 3; + size_t litSize, lhSize; + size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity); + switch(lhlCode) + { + case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */ + lhSize = 1; + litSize = istart[0] >> 3; + break; + case 1: + lhSize = 2; + RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 3"); + litSize = MEM_readLE16(istart) >> 4; + break; + case 3: + lhSize = 3; + RETURN_ERROR_IF(srcSize<4, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 4"); + litSize = MEM_readLE24(istart) >> 4; + break; + } + RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, ""); + RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, ""); + ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1); + if (dctx->litBufferLocation == ZSTD_split) + { + ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize - ZSTD_LITBUFFEREXTRASIZE); + ZSTD_memset(dctx->litExtraBuffer, istart[lhSize], ZSTD_LITBUFFEREXTRASIZE); + } + else + { + ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize); + } + dctx->litPtr = dctx->litBuffer; + dctx->litSize = litSize; + return lhSize+1; + } + default: + RETURN_ERROR(corruption_detected, "impossible"); + } + } +} + +/* Hidden declaration for fullbench */ +size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx, + const void* src, size_t srcSize, + void* dst, size_t dstCapacity); +size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx, + const void* src, size_t srcSize, + void* dst, size_t dstCapacity) +{ + dctx->isFrameDecompression = 0; + return ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, not_streaming); +} + +/* Default FSE distribution tables. + * These are pre-calculated FSE decoding tables using default distributions as defined in specification : + * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions + * They were generated programmatically with following method : + * - start from default distributions, present in /lib/common/zstd_internal.h + * - generate tables normally, using ZSTD_buildFSETable() + * - printout the content of tables + * - prettify output, report below, test with fuzzer to ensure it's correct */ + +/* Default FSE distribution table for Literal Lengths */ +static const ZSTD_seqSymbol LL_defaultDTable[(1<tableLog = 0; + DTableH->fastMode = 0; + + cell->nbBits = 0; + cell->nextState = 0; + assert(nbAddBits < 255); + cell->nbAdditionalBits = nbAddBits; + cell->baseValue = baseValue; +} + + +/* ZSTD_buildFSETable() : + * generate FSE decoding table for one symbol (ll, ml or off) + * cannot fail if input is valid => + * all inputs are presumed validated at this stage */ +FORCE_INLINE_TEMPLATE +void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt, + const short* normalizedCounter, unsigned maxSymbolValue, + const U32* baseValue, const U8* nbAdditionalBits, + unsigned tableLog, void* wksp, size_t wkspSize) +{ + ZSTD_seqSymbol* const tableDecode = dt+1; + U32 const maxSV1 = maxSymbolValue + 1; + U32 const tableSize = 1 << tableLog; + + U16* symbolNext = (U16*)wksp; + BYTE* spread = (BYTE*)(symbolNext + MaxSeq + 1); + U32 highThreshold = tableSize - 1; + + + /* Sanity Checks */ + assert(maxSymbolValue <= MaxSeq); + assert(tableLog <= MaxFSELog); + assert(wkspSize >= ZSTD_BUILD_FSE_TABLE_WKSP_SIZE); + (void)wkspSize; + /* Init, lay down lowprob symbols */ + { ZSTD_seqSymbol_header DTableH; + DTableH.tableLog = tableLog; + DTableH.fastMode = 1; + { S16 const largeLimit= (S16)(1 << (tableLog-1)); + U32 s; + for (s=0; s= largeLimit) DTableH.fastMode=0; + assert(normalizedCounter[s]>=0); + symbolNext[s] = (U16)normalizedCounter[s]; + } } } + ZSTD_memcpy(dt, &DTableH, sizeof(DTableH)); + } + + /* Spread symbols */ + assert(tableSize <= 512); + /* Specialized symbol spreading for the case when there are + * no low probability (-1 count) symbols. When compressing + * small blocks we avoid low probability symbols to hit this + * case, since header decoding speed matters more. + */ + if (highThreshold == tableSize - 1) { + size_t const tableMask = tableSize-1; + size_t const step = FSE_TABLESTEP(tableSize); + /* First lay down the symbols in order. + * We use a uint64_t to lay down 8 bytes at a time. This reduces branch + * misses since small blocks generally have small table logs, so nearly + * all symbols have counts <= 8. We ensure we have 8 bytes at the end of + * our buffer to handle the over-write. + */ + { + U64 const add = 0x0101010101010101ull; + size_t pos = 0; + U64 sv = 0; + U32 s; + for (s=0; s=0); + pos += (size_t)n; + } + } + /* Now we spread those positions across the table. + * The benefit of doing it in two stages is that we avoid the + * variable size inner loop, which caused lots of branch misses. + * Now we can run through all the positions without any branch misses. + * We unroll the loop twice, since that is what empirically worked best. + */ + { + size_t position = 0; + size_t s; + size_t const unroll = 2; + assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */ + for (s = 0; s < (size_t)tableSize; s += unroll) { + size_t u; + for (u = 0; u < unroll; ++u) { + size_t const uPosition = (position + (u * step)) & tableMask; + tableDecode[uPosition].baseValue = spread[s + u]; + } + position = (position + (unroll * step)) & tableMask; + } + assert(position == 0); + } + } else { + U32 const tableMask = tableSize-1; + U32 const step = FSE_TABLESTEP(tableSize); + U32 s, position = 0; + for (s=0; s highThreshold)) position = (position + step) & tableMask; /* lowprob area */ + } } + assert(position == 0); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ + } + + /* Build Decoding table */ + { + U32 u; + for (u=0; u max, corruption_detected, ""); + { U32 const symbol = *(const BYTE*)src; + U32 const baseline = baseValue[symbol]; + U8 const nbBits = nbAdditionalBits[symbol]; + ZSTD_buildSeqTable_rle(DTableSpace, baseline, nbBits); + } + *DTablePtr = DTableSpace; + return 1; + case set_basic : + *DTablePtr = defaultTable; + return 0; + case set_repeat: + RETURN_ERROR_IF(!flagRepeatTable, corruption_detected, ""); + /* prefetch FSE table if used */ + if (ddictIsCold && (nbSeq > 24 /* heuristic */)) { + const void* const pStart = *DTablePtr; + size_t const pSize = sizeof(ZSTD_seqSymbol) * (SEQSYMBOL_TABLE_SIZE(maxLog)); + PREFETCH_AREA(pStart, pSize); + } + return 0; + case set_compressed : + { unsigned tableLog; + S16 norm[MaxSeq+1]; + size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); + RETURN_ERROR_IF(FSE_isError(headerSize), corruption_detected, ""); + RETURN_ERROR_IF(tableLog > maxLog, corruption_detected, ""); + ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog, wksp, wkspSize, bmi2); + *DTablePtr = DTableSpace; + return headerSize; + } + default : + assert(0); + RETURN_ERROR(GENERIC, "impossible"); + } +} + +size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, + const void* src, size_t srcSize) +{ + const BYTE* const istart = (const BYTE*)src; + const BYTE* const iend = istart + srcSize; + const BYTE* ip = istart; + int nbSeq; + DEBUGLOG(5, "ZSTD_decodeSeqHeaders"); + + /* check */ + RETURN_ERROR_IF(srcSize < MIN_SEQUENCES_SIZE, srcSize_wrong, ""); + + /* SeqHead */ + nbSeq = *ip++; + if (nbSeq > 0x7F) { + if (nbSeq == 0xFF) { + RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong, ""); + nbSeq = MEM_readLE16(ip) + LONGNBSEQ; + ip+=2; + } else { + RETURN_ERROR_IF(ip >= iend, srcSize_wrong, ""); + nbSeq = ((nbSeq-0x80)<<8) + *ip++; + } + } + *nbSeqPtr = nbSeq; + + if (nbSeq == 0) { + /* No sequence : section ends immediately */ + RETURN_ERROR_IF(ip != iend, corruption_detected, + "extraneous data present in the Sequences section"); + return (size_t)(ip - istart); + } + + /* FSE table descriptors */ + RETURN_ERROR_IF(ip+1 > iend, srcSize_wrong, ""); /* minimum possible size: 1 byte for symbol encoding types */ + RETURN_ERROR_IF(*ip & 3, corruption_detected, ""); /* The last field, Reserved, must be all-zeroes. */ + { SymbolEncodingType_e const LLtype = (SymbolEncodingType_e)(*ip >> 6); + SymbolEncodingType_e const OFtype = (SymbolEncodingType_e)((*ip >> 4) & 3); + SymbolEncodingType_e const MLtype = (SymbolEncodingType_e)((*ip >> 2) & 3); + ip++; + + /* Build DTables */ + { size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr, + LLtype, MaxLL, LLFSELog, + ip, iend-ip, + LL_base, LL_bits, + LL_defaultDTable, dctx->fseEntropy, + dctx->ddictIsCold, nbSeq, + dctx->workspace, sizeof(dctx->workspace), + ZSTD_DCtx_get_bmi2(dctx)); + RETURN_ERROR_IF(ZSTD_isError(llhSize), corruption_detected, "ZSTD_buildSeqTable failed"); + ip += llhSize; + } + + { size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr, + OFtype, MaxOff, OffFSELog, + ip, iend-ip, + OF_base, OF_bits, + OF_defaultDTable, dctx->fseEntropy, + dctx->ddictIsCold, nbSeq, + dctx->workspace, sizeof(dctx->workspace), + ZSTD_DCtx_get_bmi2(dctx)); + RETURN_ERROR_IF(ZSTD_isError(ofhSize), corruption_detected, "ZSTD_buildSeqTable failed"); + ip += ofhSize; + } + + { size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr, + MLtype, MaxML, MLFSELog, + ip, iend-ip, + ML_base, ML_bits, + ML_defaultDTable, dctx->fseEntropy, + dctx->ddictIsCold, nbSeq, + dctx->workspace, sizeof(dctx->workspace), + ZSTD_DCtx_get_bmi2(dctx)); + RETURN_ERROR_IF(ZSTD_isError(mlhSize), corruption_detected, "ZSTD_buildSeqTable failed"); + ip += mlhSize; + } + } + + return ip-istart; +} + + +typedef struct { + size_t litLength; + size_t matchLength; + size_t offset; +} seq_t; + +typedef struct { + size_t state; + const ZSTD_seqSymbol* table; +} ZSTD_fseState; + +typedef struct { + BIT_DStream_t DStream; + ZSTD_fseState stateLL; + ZSTD_fseState stateOffb; + ZSTD_fseState stateML; + size_t prevOffset[ZSTD_REP_NUM]; +} seqState_t; + +/*! ZSTD_overlapCopy8() : + * Copies 8 bytes from ip to op and updates op and ip where ip <= op. + * If the offset is < 8 then the offset is spread to at least 8 bytes. + * + * Precondition: *ip <= *op + * Postcondition: *op - *op >= 8 + */ +HINT_INLINE void ZSTD_overlapCopy8(BYTE** op, BYTE const** ip, size_t offset) { + assert(*ip <= *op); + if (offset < 8) { + /* close range match, overlap */ + static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ + static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */ + int const sub2 = dec64table[offset]; + (*op)[0] = (*ip)[0]; + (*op)[1] = (*ip)[1]; + (*op)[2] = (*ip)[2]; + (*op)[3] = (*ip)[3]; + *ip += dec32table[offset]; + ZSTD_copy4(*op+4, *ip); + *ip -= sub2; + } else { + ZSTD_copy8(*op, *ip); + } + *ip += 8; + *op += 8; + assert(*op - *ip >= 8); +} + +/*! ZSTD_safecopy() : + * Specialized version of memcpy() that is allowed to READ up to WILDCOPY_OVERLENGTH past the input buffer + * and write up to 16 bytes past oend_w (op >= oend_w is allowed). + * This function is only called in the uncommon case where the sequence is near the end of the block. It + * should be fast for a single long sequence, but can be slow for several short sequences. + * + * @param ovtype controls the overlap detection + * - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart. + * - ZSTD_overlap_src_before_dst: The src and dst may overlap and may be any distance apart. + * The src buffer must be before the dst buffer. + */ +static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, ptrdiff_t length, ZSTD_overlap_e ovtype) { + ptrdiff_t const diff = op - ip; + BYTE* const oend = op + length; + + assert((ovtype == ZSTD_no_overlap && (diff <= -8 || diff >= 8 || op >= oend_w)) || + (ovtype == ZSTD_overlap_src_before_dst && diff >= 0)); + + if (length < 8) { + /* Handle short lengths. */ + while (op < oend) *op++ = *ip++; + return; + } + if (ovtype == ZSTD_overlap_src_before_dst) { + /* Copy 8 bytes and ensure the offset >= 8 when there can be overlap. */ + assert(length >= 8); + ZSTD_overlapCopy8(&op, &ip, diff); + length -= 8; + assert(op - ip >= 8); + assert(op <= oend); + } + + if (oend <= oend_w) { + /* No risk of overwrite. */ + ZSTD_wildcopy(op, ip, length, ovtype); + return; + } + if (op <= oend_w) { + /* Wildcopy until we get close to the end. */ + assert(oend > oend_w); + ZSTD_wildcopy(op, ip, oend_w - op, ovtype); + ip += oend_w - op; + op += oend_w - op; + } + /* Handle the leftovers. */ + while (op < oend) *op++ = *ip++; +} + +/* ZSTD_safecopyDstBeforeSrc(): + * This version allows overlap with dst before src, or handles the non-overlap case with dst after src + * Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */ +static void ZSTD_safecopyDstBeforeSrc(BYTE* op, const BYTE* ip, ptrdiff_t length) { + ptrdiff_t const diff = op - ip; + BYTE* const oend = op + length; + + if (length < 8 || diff > -8) { + /* Handle short lengths, close overlaps, and dst not before src. */ + while (op < oend) *op++ = *ip++; + return; + } + + if (op <= oend - WILDCOPY_OVERLENGTH && diff < -WILDCOPY_VECLEN) { + ZSTD_wildcopy(op, ip, oend - WILDCOPY_OVERLENGTH - op, ZSTD_no_overlap); + ip += oend - WILDCOPY_OVERLENGTH - op; + op += oend - WILDCOPY_OVERLENGTH - op; + } + + /* Handle the leftovers. */ + while (op < oend) *op++ = *ip++; +} + +/* ZSTD_execSequenceEnd(): + * This version handles cases that are near the end of the output buffer. It requires + * more careful checks to make sure there is no overflow. By separating out these hard + * and unlikely cases, we can speed up the common cases. + * + * NOTE: This function needs to be fast for a single long sequence, but doesn't need + * to be optimized for many small sequences, since those fall into ZSTD_execSequence(). + */ +FORCE_NOINLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_execSequenceEnd(BYTE* op, + BYTE* const oend, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; + + /* bounds checks : careful of address space overflow in 32-bit mode */ + RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer"); + RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer"); + assert(op < op + sequenceLength); + assert(oLitEnd < op + sequenceLength); + + /* copy literals */ + ZSTD_safecopy(op, oend_w, *litPtr, sequence.litLength, ZSTD_no_overlap); + op = oLitEnd; + *litPtr = iLitEnd; + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix */ + RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, ""); + match = dictEnd - (prefixStart - match); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } + } + ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst); + return sequenceLength; +} + +/* ZSTD_execSequenceEndSplitLitBuffer(): + * This version is intended to be used during instances where the litBuffer is still split. It is kept separate to avoid performance impact for the good case. + */ +FORCE_NOINLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op, + BYTE* const oend, const BYTE* const oend_w, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + + + /* bounds checks : careful of address space overflow in 32-bit mode */ + RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer"); + RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer"); + assert(op < op + sequenceLength); + assert(oLitEnd < op + sequenceLength); + + /* copy literals */ + RETURN_ERROR_IF(op > *litPtr && op < *litPtr + sequence.litLength, dstSize_tooSmall, "output should not catch up to and overwrite literal buffer"); + ZSTD_safecopyDstBeforeSrc(op, *litPtr, sequence.litLength); + op = oLitEnd; + *litPtr = iLitEnd; + + /* copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix */ + RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, ""); + match = dictEnd - (prefixStart - match); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } + } + ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst); + return sequenceLength; +} + +HINT_INLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_execSequence(BYTE* op, + BYTE* const oend, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; /* risk : address space underflow on oend=NULL */ + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + + assert(op != NULL /* Precondition */); + assert(oend_w < oend /* No underflow */); + +#if defined(__aarch64__) + /* prefetch sequence starting from match that will be used for copy later */ + PREFETCH_L1(match); +#endif + /* Handle edge cases in a slow path: + * - Read beyond end of literals + * - Match end is within WILDCOPY_OVERLIMIT of oend + * - 32-bit mode and the match length overflows + */ + if (UNLIKELY( + iLitEnd > litLimit || + oMatchEnd > oend_w || + (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH))) + return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd); + + /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */ + assert(op <= oLitEnd /* No overflow */); + assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */); + assert(oMatchEnd <= oend /* No underflow */); + assert(iLitEnd <= litLimit /* Literal length is in bounds */); + assert(oLitEnd <= oend_w /* Can wildcopy literals */); + assert(oMatchEnd <= oend_w /* Can wildcopy matches */); + + /* Copy Literals: + * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9. + * We likely don't need the full 32-byte wildcopy. + */ + assert(WILDCOPY_OVERLENGTH >= 16); + ZSTD_copy16(op, (*litPtr)); + if (UNLIKELY(sequence.litLength > 16)) { + ZSTD_wildcopy(op + 16, (*litPtr) + 16, sequence.litLength - 16, ZSTD_no_overlap); + } + op = oLitEnd; + *litPtr = iLitEnd; /* update for next sequence */ + + /* Copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix -> go into extDict */ + RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, ""); + match = dictEnd + (match - prefixStart); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } + } + /* Match within prefix of 1 or more bytes */ + assert(op <= oMatchEnd); + assert(oMatchEnd <= oend_w); + assert(match >= prefixStart); + assert(sequence.matchLength >= 1); + + /* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy + * without overlap checking. + */ + if (LIKELY(sequence.offset >= WILDCOPY_VECLEN)) { + /* We bet on a full wildcopy for matches, since we expect matches to be + * longer than literals (in general). In silesia, ~10% of matches are longer + * than 16 bytes. + */ + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap); + return sequenceLength; + } + assert(sequence.offset < WILDCOPY_VECLEN); + + /* Copy 8 bytes and spread the offset to be >= 8. */ + ZSTD_overlapCopy8(&op, &match, sequence.offset); + + /* If the match length is > 8 bytes, then continue with the wildcopy. */ + if (sequence.matchLength > 8) { + assert(op < oMatchEnd); + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8, ZSTD_overlap_src_before_dst); + } + return sequenceLength; +} + +HINT_INLINE +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op, + BYTE* const oend, const BYTE* const oend_w, seq_t sequence, + const BYTE** litPtr, const BYTE* const litLimit, + const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd) +{ + BYTE* const oLitEnd = op + sequence.litLength; + size_t const sequenceLength = sequence.litLength + sequence.matchLength; + BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ + const BYTE* const iLitEnd = *litPtr + sequence.litLength; + const BYTE* match = oLitEnd - sequence.offset; + + assert(op != NULL /* Precondition */); + assert(oend_w < oend /* No underflow */); + /* Handle edge cases in a slow path: + * - Read beyond end of literals + * - Match end is within WILDCOPY_OVERLIMIT of oend + * - 32-bit mode and the match length overflows + */ + if (UNLIKELY( + iLitEnd > litLimit || + oMatchEnd > oend_w || + (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH))) + return ZSTD_execSequenceEndSplitLitBuffer(op, oend, oend_w, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd); + + /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */ + assert(op <= oLitEnd /* No overflow */); + assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */); + assert(oMatchEnd <= oend /* No underflow */); + assert(iLitEnd <= litLimit /* Literal length is in bounds */); + assert(oLitEnd <= oend_w /* Can wildcopy literals */); + assert(oMatchEnd <= oend_w /* Can wildcopy matches */); + + /* Copy Literals: + * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9. + * We likely don't need the full 32-byte wildcopy. + */ + assert(WILDCOPY_OVERLENGTH >= 16); + ZSTD_copy16(op, (*litPtr)); + if (UNLIKELY(sequence.litLength > 16)) { + ZSTD_wildcopy(op+16, (*litPtr)+16, sequence.litLength-16, ZSTD_no_overlap); + } + op = oLitEnd; + *litPtr = iLitEnd; /* update for next sequence */ + + /* Copy Match */ + if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { + /* offset beyond prefix -> go into extDict */ + RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, ""); + match = dictEnd + (match - prefixStart); + if (match + sequence.matchLength <= dictEnd) { + ZSTD_memmove(oLitEnd, match, sequence.matchLength); + return sequenceLength; + } + /* span extDict & currentPrefixSegment */ + { size_t const length1 = dictEnd - match; + ZSTD_memmove(oLitEnd, match, length1); + op = oLitEnd + length1; + sequence.matchLength -= length1; + match = prefixStart; + } } + /* Match within prefix of 1 or more bytes */ + assert(op <= oMatchEnd); + assert(oMatchEnd <= oend_w); + assert(match >= prefixStart); + assert(sequence.matchLength >= 1); + + /* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy + * without overlap checking. + */ + if (LIKELY(sequence.offset >= WILDCOPY_VECLEN)) { + /* We bet on a full wildcopy for matches, since we expect matches to be + * longer than literals (in general). In silesia, ~10% of matches are longer + * than 16 bytes. + */ + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap); + return sequenceLength; + } + assert(sequence.offset < WILDCOPY_VECLEN); + + /* Copy 8 bytes and spread the offset to be >= 8. */ + ZSTD_overlapCopy8(&op, &match, sequence.offset); + + /* If the match length is > 8 bytes, then continue with the wildcopy. */ + if (sequence.matchLength > 8) { + assert(op < oMatchEnd); + ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8, ZSTD_overlap_src_before_dst); + } + return sequenceLength; +} + + +static void +ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt) +{ + const void* ptr = dt; + const ZSTD_seqSymbol_header* const DTableH = (const ZSTD_seqSymbol_header*)ptr; + DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); + DEBUGLOG(6, "ZSTD_initFseState : val=%u using %u bits", + (U32)DStatePtr->state, DTableH->tableLog); + BIT_reloadDStream(bitD); + DStatePtr->table = dt + 1; +} + +FORCE_INLINE_TEMPLATE void +ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16 nextState, U32 nbBits) +{ + size_t const lowBits = BIT_readBits(bitD, nbBits); + DStatePtr->state = nextState + lowBits; +} + +/* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum + * offset bits. But we can only read at most STREAM_ACCUMULATOR_MIN_32 + * bits before reloading. This value is the maximum number of bytes we read + * after reloading when we are decoding long offsets. + */ +#define LONG_OFFSETS_MAX_EXTRA_BITS_32 \ + (ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32 \ + ? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32 \ + : 0) + +typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e; + +/** + * ZSTD_decodeSequence(): + * @p longOffsets : tells the decoder to reload more bit while decoding large offsets + * only used in 32-bit mode + * @return : Sequence (litL + matchL + offset) + */ +FORCE_INLINE_TEMPLATE seq_t +ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const int isLastSeq) +{ + seq_t seq; + /* + * ZSTD_seqSymbol is a 64 bits wide structure. + * It can be loaded in one operation + * and its fields extracted by simply shifting or bit-extracting on aarch64. + * GCC doesn't recognize this and generates more unnecessary ldr/ldrb/ldrh + * operations that cause performance drop. This can be avoided by using this + * ZSTD_memcpy hack. + */ +#if defined(__aarch64__) && (defined(__GNUC__) && !defined(__clang__)) + ZSTD_seqSymbol llDInfoS, mlDInfoS, ofDInfoS; + ZSTD_seqSymbol* const llDInfo = &llDInfoS; + ZSTD_seqSymbol* const mlDInfo = &mlDInfoS; + ZSTD_seqSymbol* const ofDInfo = &ofDInfoS; + ZSTD_memcpy(llDInfo, seqState->stateLL.table + seqState->stateLL.state, sizeof(ZSTD_seqSymbol)); + ZSTD_memcpy(mlDInfo, seqState->stateML.table + seqState->stateML.state, sizeof(ZSTD_seqSymbol)); + ZSTD_memcpy(ofDInfo, seqState->stateOffb.table + seqState->stateOffb.state, sizeof(ZSTD_seqSymbol)); +#else + const ZSTD_seqSymbol* const llDInfo = seqState->stateLL.table + seqState->stateLL.state; + const ZSTD_seqSymbol* const mlDInfo = seqState->stateML.table + seqState->stateML.state; + const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state; +#endif + seq.matchLength = mlDInfo->baseValue; + seq.litLength = llDInfo->baseValue; + { U32 const ofBase = ofDInfo->baseValue; + BYTE const llBits = llDInfo->nbAdditionalBits; + BYTE const mlBits = mlDInfo->nbAdditionalBits; + BYTE const ofBits = ofDInfo->nbAdditionalBits; + BYTE const totalBits = llBits+mlBits+ofBits; + + U16 const llNext = llDInfo->nextState; + U16 const mlNext = mlDInfo->nextState; + U16 const ofNext = ofDInfo->nextState; + U32 const llnbBits = llDInfo->nbBits; + U32 const mlnbBits = mlDInfo->nbBits; + U32 const ofnbBits = ofDInfo->nbBits; + + assert(llBits <= MaxLLBits); + assert(mlBits <= MaxMLBits); + assert(ofBits <= MaxOff); + /* + * As gcc has better branch and block analyzers, sometimes it is only + * valuable to mark likeliness for clang, it gives around 3-4% of + * performance. + */ + + /* sequence */ + { size_t offset; + if (ofBits > 1) { + ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1); + ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5); + ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 > LONG_OFFSETS_MAX_EXTRA_BITS_32); + ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 - LONG_OFFSETS_MAX_EXTRA_BITS_32 >= MaxMLBits); + if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) { + /* Always read extra bits, this keeps the logic simple, + * avoids branches, and avoids accidentally reading 0 bits. + */ + U32 const extraBits = LONG_OFFSETS_MAX_EXTRA_BITS_32; + offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits); + BIT_reloadDStream(&seqState->DStream); + offset += BIT_readBitsFast(&seqState->DStream, extraBits); + } else { + offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); + } + seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset; + } else { + U32 const ll0 = (llDInfo->baseValue == 0); + if (LIKELY((ofBits == 0))) { + offset = seqState->prevOffset[ll0]; + seqState->prevOffset[1] = seqState->prevOffset[!ll0]; + seqState->prevOffset[0] = offset; + } else { + offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1); + { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; + temp -= !temp; /* 0 is not valid: input corrupted => force offset to -1 => corruption detected at execSequence */ + if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; + seqState->prevOffset[1] = seqState->prevOffset[0]; + seqState->prevOffset[0] = offset = temp; + } } } + seq.offset = offset; + } + + if (mlBits > 0) + seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/); + + if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32)) + BIT_reloadDStream(&seqState->DStream); + if (MEM_64bits() && UNLIKELY(totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog))) + BIT_reloadDStream(&seqState->DStream); + /* Ensure there are enough bits to read the rest of data in 64-bit mode. */ + ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64); + + if (llBits > 0) + seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/); + + if (MEM_32bits()) + BIT_reloadDStream(&seqState->DStream); + + DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u", + (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); + + if (!isLastSeq) { + /* don't update FSE state for last Sequence */ + ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */ + ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */ + if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ + ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */ + BIT_reloadDStream(&seqState->DStream); + } + } + + return seq; +} + +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) +#if DEBUGLEVEL >= 1 +static int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd) +{ + size_t const windowSize = dctx->fParams.windowSize; + /* No dictionary used. */ + if (dctx->dictContentEndForFuzzing == NULL) return 0; + /* Dictionary is our prefix. */ + if (prefixStart == dctx->dictContentBeginForFuzzing) return 1; + /* Dictionary is not our ext-dict. */ + if (dctx->dictEnd != dctx->dictContentEndForFuzzing) return 0; + /* Dictionary is not within our window size. */ + if ((size_t)(oLitEnd - prefixStart) >= windowSize) return 0; + /* Dictionary is active. */ + return 1; +} +#endif + +static void ZSTD_assertValidSequence( + ZSTD_DCtx const* dctx, + BYTE const* op, BYTE const* oend, + seq_t const seq, + BYTE const* prefixStart, BYTE const* virtualStart) +{ +#if DEBUGLEVEL >= 1 + if (dctx->isFrameDecompression) { + size_t const windowSize = dctx->fParams.windowSize; + size_t const sequenceSize = seq.litLength + seq.matchLength; + BYTE const* const oLitEnd = op + seq.litLength; + DEBUGLOG(6, "Checking sequence: litL=%u matchL=%u offset=%u", + (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); + assert(op <= oend); + assert((size_t)(oend - op) >= sequenceSize); + assert(sequenceSize <= ZSTD_blockSizeMax(dctx)); + if (ZSTD_dictionaryIsActive(dctx, prefixStart, oLitEnd)) { + size_t const dictSize = (size_t)((char const*)dctx->dictContentEndForFuzzing - (char const*)dctx->dictContentBeginForFuzzing); + /* Offset must be within the dictionary. */ + assert(seq.offset <= (size_t)(oLitEnd - virtualStart)); + assert(seq.offset <= windowSize + dictSize); + } else { + /* Offset must be within our window. */ + assert(seq.offset <= windowSize); + } + } +#else + (void)dctx, (void)op, (void)oend, (void)seq, (void)prefixStart, (void)virtualStart; +#endif +} +#endif + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG + + +FORCE_INLINE_TEMPLATE size_t +DONT_VECTORIZE +ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, maxDstSize); + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* litBufferEnd = dctx->litBufferEnd; + const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); + const BYTE* const vBase = (const BYTE*) (dctx->virtualStart); + const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); + DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer (%i seqs)", nbSeq); + + /* Literals are split between internal buffer & output buffer */ + if (nbSeq) { + seqState_t seqState; + dctx->fseEntropy = 1; + { U32 i; for (i=0; ientropy.rep[i]; } + RETURN_ERROR_IF( + ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)), + corruption_detected, ""); + ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + assert(dst != NULL); + + ZSTD_STATIC_ASSERT( + BIT_DStream_unfinished < BIT_DStream_completed && + BIT_DStream_endOfBuffer < BIT_DStream_completed && + BIT_DStream_completed < BIT_DStream_overflow); + + /* decompress without overrunning litPtr begins */ + { seq_t sequence = {0,0,0}; /* some static analyzer believe that @sequence is not initialized (it necessarily is, since for(;;) loop as at least one iteration) */ + /* Align the decompression loop to 32 + 16 bytes. + * + * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression + * speed swings based on the alignment of the decompression loop. This + * performance swing is caused by parts of the decompression loop falling + * out of the DSB. The entire decompression loop should fit in the DSB, + * when it can't we get much worse performance. You can measure if you've + * hit the good case or the bad case with this perf command for some + * compressed file test.zst: + * + * perf stat -e cycles -e instructions -e idq.all_dsb_cycles_any_uops \ + * -e idq.all_mite_cycles_any_uops -- ./zstd -tq test.zst + * + * If you see most cycles served out of the MITE you've hit the bad case. + * If you see most cycles served out of the DSB you've hit the good case. + * If it is pretty even then you may be in an okay case. + * + * This issue has been reproduced on the following CPUs: + * - Kabylake: Macbook Pro (15-inch, 2019) 2.4 GHz Intel Core i9 + * Use Instruments->Counters to get DSB/MITE cycles. + * I never got performance swings, but I was able to + * go from the good case of mostly DSB to half of the + * cycles served from MITE. + * - Coffeelake: Intel i9-9900k + * - Coffeelake: Intel i7-9700k + * + * I haven't been able to reproduce the instability or DSB misses on any + * of the following CPUS: + * - Haswell + * - Broadwell: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GH + * - Skylake + * + * Alignment is done for each of the three major decompression loops: + * - ZSTD_decompressSequences_bodySplitLitBuffer - presplit section of the literal buffer + * - ZSTD_decompressSequences_bodySplitLitBuffer - postsplit section of the literal buffer + * - ZSTD_decompressSequences_body + * Alignment choices are made to minimize large swings on bad cases and influence on performance + * from changes external to this code, rather than to overoptimize on the current commit. + * + * If you are seeing performance stability this script can help test. + * It tests on 4 commits in zstd where I saw performance change. + * + * https://gist.github.com/terrelln/9889fc06a423fd5ca6e99351564473f4 + */ +#if defined(__GNUC__) && defined(__x86_64__) + __asm__(".p2align 6"); +# if __GNUC__ >= 7 + /* good for gcc-7, gcc-9, and gcc-11 */ + __asm__("nop"); + __asm__(".p2align 5"); + __asm__("nop"); + __asm__(".p2align 4"); +# if __GNUC__ == 8 || __GNUC__ == 10 + /* good for gcc-8 and gcc-10 */ + __asm__("nop"); + __asm__(".p2align 3"); +# endif +# endif +#endif + + /* Handle the initial state where litBuffer is currently split between dst and litExtraBuffer */ + for ( ; nbSeq; nbSeq--) { + sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1); + if (litPtr + sequence.litLength > dctx->litBufferEnd) break; + { size_t const oneSeqSize = ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence.litLength - WILDCOPY_OVERLENGTH, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + } } + DEBUGLOG(6, "reached: (litPtr + sequence.litLength > dctx->litBufferEnd)"); + + /* If there are more sequences, they will need to read literals from litExtraBuffer; copy over the remainder from dst and update litPtr and litEnd */ + if (nbSeq > 0) { + const size_t leftoverLit = dctx->litBufferEnd - litPtr; + DEBUGLOG(6, "There are %i sequences left, and %zu/%zu literals left in buffer", nbSeq, leftoverLit, sequence.litLength); + if (leftoverLit) { + RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); + ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); + sequence.litLength -= leftoverLit; + op += leftoverLit; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + { size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + } + nbSeq--; + } + } + + if (nbSeq > 0) { + /* there is remaining lit from extra buffer */ + +#if defined(__GNUC__) && defined(__x86_64__) + __asm__(".p2align 6"); + __asm__("nop"); +# if __GNUC__ != 7 + /* worse for gcc-7 better for gcc-8, gcc-9, and gcc-10 and clang */ + __asm__(".p2align 4"); + __asm__("nop"); + __asm__(".p2align 3"); +# elif __GNUC__ >= 11 + __asm__(".p2align 3"); +# else + __asm__(".p2align 5"); + __asm__("nop"); + __asm__(".p2align 3"); +# endif +#endif + + for ( ; nbSeq ; nbSeq--) { + seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1); + size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + } + } + + /* check if reached exact end */ + DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer: after decode loop, remaining nbSeq : %i", nbSeq); + RETURN_ERROR_IF(nbSeq, corruption_detected, ""); + DEBUGLOG(5, "bitStream : start=%p, ptr=%p, bitsConsumed=%u", seqState.DStream.start, seqState.DStream.ptr, seqState.DStream.bitsConsumed); + RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, ""); + /* save reps for next block */ + { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + if (dctx->litBufferLocation == ZSTD_split) { + /* split hasn't been reached yet, first get dst then copy litExtraBuffer */ + size_t const lastLLSize = (size_t)(litBufferEnd - litPtr); + DEBUGLOG(6, "copy last literals from segment : %u", (U32)lastLLSize); + RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memmove(op, litPtr, lastLLSize); + op += lastLLSize; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + } + /* copy last literals from internal buffer */ + { size_t const lastLLSize = (size_t)(litBufferEnd - litPtr); + DEBUGLOG(6, "copy last literals from internal buffer : %u", (U32)lastLLSize); + RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } } + + DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart)); + return (size_t)(op - ostart); +} + +FORCE_INLINE_TEMPLATE size_t +DONT_VECTORIZE +ZSTD_decompressSequences_body(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ZSTD_maybeNullPtrAdd(ostart, maxDstSize) : dctx->litBuffer; + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* const litEnd = litPtr + dctx->litSize; + const BYTE* const prefixStart = (const BYTE*)(dctx->prefixStart); + const BYTE* const vBase = (const BYTE*)(dctx->virtualStart); + const BYTE* const dictEnd = (const BYTE*)(dctx->dictEnd); + DEBUGLOG(5, "ZSTD_decompressSequences_body: nbSeq = %d", nbSeq); + + /* Regen sequences */ + if (nbSeq) { + seqState_t seqState; + dctx->fseEntropy = 1; + { U32 i; for (i = 0; i < ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; } + RETURN_ERROR_IF( + ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend - ip)), + corruption_detected, ""); + ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + assert(dst != NULL); + +#if defined(__GNUC__) && defined(__x86_64__) + __asm__(".p2align 6"); + __asm__("nop"); +# if __GNUC__ >= 7 + __asm__(".p2align 5"); + __asm__("nop"); + __asm__(".p2align 3"); +# else + __asm__(".p2align 4"); + __asm__("nop"); + __asm__(".p2align 3"); +# endif +#endif + + for ( ; nbSeq ; nbSeq--) { + seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1); + size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase); +#endif + if (UNLIKELY(ZSTD_isError(oneSeqSize))) + return oneSeqSize; + DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); + op += oneSeqSize; + } + + /* check if reached exact end */ + assert(nbSeq == 0); + RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, ""); + /* save reps for next block */ + { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + { size_t const lastLLSize = (size_t)(litEnd - litPtr); + DEBUGLOG(6, "copy last literals : %u", (U32)lastLLSize); + RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memcpy(op, litPtr, lastLLSize); + op += lastLLSize; + } } + + DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart)); + return (size_t)(op - ostart); +} + +static size_t +ZSTD_decompressSequences_default(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} + +static size_t +ZSTD_decompressSequencesSplitLitBuffer_default(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT + +FORCE_INLINE_TEMPLATE + +size_t ZSTD_prefetchMatch(size_t prefetchPos, seq_t const sequence, + const BYTE* const prefixStart, const BYTE* const dictEnd) +{ + prefetchPos += sequence.litLength; + { const BYTE* const matchBase = (sequence.offset > prefetchPos) ? dictEnd : prefixStart; + /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted. + * No consequence though : memory address is only used for prefetching, not for dereferencing */ + const BYTE* const match = ZSTD_wrappedPtrSub(ZSTD_wrappedPtrAdd(matchBase, prefetchPos), sequence.offset); + PREFETCH_L1(match); PREFETCH_L1(match+CACHELINE_SIZE); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */ + } + return prefetchPos + sequence.matchLength; +} + +/* This decoding function employs prefetching + * to reduce latency impact of cache misses. + * It's generally employed when block contains a significant portion of long-distance matches + * or when coupled with a "cold" dictionary */ +FORCE_INLINE_TEMPLATE size_t +ZSTD_decompressSequencesLong_body( + ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + const BYTE* ip = (const BYTE*)seqStart; + const BYTE* const iend = ip + seqSize; + BYTE* const ostart = (BYTE*)dst; + BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ZSTD_maybeNullPtrAdd(ostart, maxDstSize); + BYTE* op = ostart; + const BYTE* litPtr = dctx->litPtr; + const BYTE* litBufferEnd = dctx->litBufferEnd; + const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart); + const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart); + const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); + + /* Regen sequences */ + if (nbSeq) { +#define STORED_SEQS 8 +#define STORED_SEQS_MASK (STORED_SEQS-1) +#define ADVANCED_SEQS STORED_SEQS + seq_t sequences[STORED_SEQS]; + int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); + seqState_t seqState; + int seqNb; + size_t prefetchPos = (size_t)(op-prefixStart); /* track position relative to prefixStart */ + + dctx->fseEntropy = 1; + { int i; for (i=0; ientropy.rep[i]; } + assert(dst != NULL); + assert(iend >= ip); + RETURN_ERROR_IF( + ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)), + corruption_detected, ""); + ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); + ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); + ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); + + /* prepare in advance */ + for (seqNb=0; seqNblitBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd) { + /* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */ + const size_t leftoverLit = dctx->litBufferEnd - litPtr; + if (leftoverLit) + { + RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); + ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength -= leftoverLit; + op += leftoverLit; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + { size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + + prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd); + sequences[seqNb & STORED_SEQS_MASK] = sequence; + op += oneSeqSize; + } } + else + { + /* lit buffer is either wholly contained in first or second split, or not split at all*/ + size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ? + ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength - WILDCOPY_OVERLENGTH, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) : + ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + + prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd); + sequences[seqNb & STORED_SEQS_MASK] = sequence; + op += oneSeqSize; + } + } + RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, ""); + + /* finish queue */ + seqNb -= seqAdvance; + for ( ; seqNblitBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd) { + const size_t leftoverLit = dctx->litBufferEnd - litPtr; + if (leftoverLit) { + RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer"); + ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit); + sequence->litLength -= leftoverLit; + op += leftoverLit; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + dctx->litBufferLocation = ZSTD_not_in_dst; + { size_t const oneSeqSize = ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + op += oneSeqSize; + } + } + else + { + size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ? + ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence->litLength - WILDCOPY_OVERLENGTH, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) : + ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd); +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE) + assert(!ZSTD_isError(oneSeqSize)); + ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart); +#endif + if (ZSTD_isError(oneSeqSize)) return oneSeqSize; + op += oneSeqSize; + } + } + + /* save reps for next block */ + { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); } + } + + /* last literal segment */ + if (dctx->litBufferLocation == ZSTD_split) { /* first deplete literal buffer in dst, then copy litExtraBuffer */ + size_t const lastLLSize = litBufferEnd - litPtr; + RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memmove(op, litPtr, lastLLSize); + op += lastLLSize; + } + litPtr = dctx->litExtraBuffer; + litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE; + } + { size_t const lastLLSize = litBufferEnd - litPtr; + RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, ""); + if (op != NULL) { + ZSTD_memmove(op, litPtr, lastLLSize); + op += lastLLSize; + } + } + + return (size_t)(op - ostart); +} + +static size_t +ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ + + + +#if DYNAMIC_BMI2 + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG +static BMI2_TARGET_ATTRIBUTE size_t +DONT_VECTORIZE +ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +static BMI2_TARGET_ATTRIBUTE size_t +DONT_VECTORIZE +ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT +static BMI2_TARGET_ATTRIBUTE size_t +ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ + +#endif /* DYNAMIC_BMI2 */ + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG +static size_t +ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + DEBUGLOG(5, "ZSTD_decompressSequences"); +#if DYNAMIC_BMI2 + if (ZSTD_DCtx_get_bmi2(dctx)) { + return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); + } +#endif + return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +static size_t +ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + DEBUGLOG(5, "ZSTD_decompressSequencesSplitLitBuffer"); +#if DYNAMIC_BMI2 + if (ZSTD_DCtx_get_bmi2(dctx)) { + return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); + } +#endif + return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */ + + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT +/* ZSTD_decompressSequencesLong() : + * decompression function triggered when a minimum share of offsets is considered "long", + * aka out of cache. + * note : "long" definition seems overloaded here, sometimes meaning "wider than bitstream register", and sometimes meaning "farther than memory cache distance". + * This function will try to mitigate main memory latency through the use of prefetching */ +static size_t +ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx, + void* dst, size_t maxDstSize, + const void* seqStart, size_t seqSize, int nbSeq, + const ZSTD_longOffset_e isLongOffset) +{ + DEBUGLOG(5, "ZSTD_decompressSequencesLong"); +#if DYNAMIC_BMI2 + if (ZSTD_DCtx_get_bmi2(dctx)) { + return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); + } +#endif + return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); +} +#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */ + + +/** + * @returns The total size of the history referenceable by zstd, including + * both the prefix and the extDict. At @p op any offset larger than this + * is invalid. + */ +static size_t ZSTD_totalHistorySize(BYTE* op, BYTE const* virtualStart) +{ + return (size_t)(op - virtualStart); +} + +typedef struct { + unsigned longOffsetShare; + unsigned maxNbAdditionalBits; +} ZSTD_OffsetInfo; + +/* ZSTD_getOffsetInfo() : + * condition : offTable must be valid + * @return : "share" of long offsets (arbitrarily defined as > (1<<23)) + * compared to maximum possible of (1< 22) info.longOffsetShare += 1; + } + + assert(tableLog <= OffFSELog); + info.longOffsetShare <<= (OffFSELog - tableLog); /* scale to OffFSELog */ + } + + return info; +} + +/** + * @returns The maximum offset we can decode in one read of our bitstream, without + * reloading more bits in the middle of the offset bits read. Any offsets larger + * than this must use the long offset decoder. + */ +static size_t ZSTD_maxShortOffset(void) +{ + if (MEM_64bits()) { + /* We can decode any offset without reloading bits. + * This might change if the max window size grows. + */ + ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31); + return (size_t)-1; + } else { + /* The maximum offBase is (1 << (STREAM_ACCUMULATOR_MIN + 1)) - 1. + * This offBase would require STREAM_ACCUMULATOR_MIN extra bits. + * Then we have to subtract ZSTD_REP_NUM to get the maximum possible offset. + */ + size_t const maxOffbase = ((size_t)1 << (STREAM_ACCUMULATOR_MIN + 1)) - 1; + size_t const maxOffset = maxOffbase - ZSTD_REP_NUM; + assert(ZSTD_highbit32((U32)maxOffbase) == STREAM_ACCUMULATOR_MIN); + return maxOffset; + } +} + +size_t +ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, const streaming_operation streaming) +{ /* blockType == blockCompressed */ + const BYTE* ip = (const BYTE*)src; + DEBUGLOG(5, "ZSTD_decompressBlock_internal (cSize : %u)", (unsigned)srcSize); + + /* Note : the wording of the specification + * allows compressed block to be sized exactly ZSTD_blockSizeMax(dctx). + * This generally does not happen, as it makes little sense, + * since an uncompressed block would feature same size and have no decompression cost. + * Also, note that decoder from reference libzstd before < v1.5.4 + * would consider this edge case as an error. + * As a consequence, avoid generating compressed blocks of size ZSTD_blockSizeMax(dctx) + * for broader compatibility with the deployed ecosystem of zstd decoders */ + RETURN_ERROR_IF(srcSize > ZSTD_blockSizeMax(dctx), srcSize_wrong, ""); + + /* Decode literals section */ + { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming); + DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : cSize=%u, nbLiterals=%zu", (U32)litCSize, dctx->litSize); + if (ZSTD_isError(litCSize)) return litCSize; + ip += litCSize; + srcSize -= litCSize; + } + + /* Build Decoding Tables */ + { + /* Compute the maximum block size, which must also work when !frame and fParams are unset. + * Additionally, take the min with dstCapacity to ensure that the totalHistorySize fits in a size_t. + */ + size_t const blockSizeMax = MIN(dstCapacity, ZSTD_blockSizeMax(dctx)); + size_t const totalHistorySize = ZSTD_totalHistorySize(ZSTD_maybeNullPtrAdd((BYTE*)dst, blockSizeMax), (BYTE const*)dctx->virtualStart); + /* isLongOffset must be true if there are long offsets. + * Offsets are long if they are larger than ZSTD_maxShortOffset(). + * We don't expect that to be the case in 64-bit mode. + * + * We check here to see if our history is large enough to allow long offsets. + * If it isn't, then we can't possible have (valid) long offsets. If the offset + * is invalid, then it is okay to read it incorrectly. + * + * If isLongOffsets is true, then we will later check our decoding table to see + * if it is even possible to generate long offsets. + */ + ZSTD_longOffset_e isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (totalHistorySize > ZSTD_maxShortOffset())); + /* These macros control at build-time which decompressor implementation + * we use. If neither is defined, we do some inspection and dispatch at + * runtime. + */ +#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \ + !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG) + int usePrefetchDecoder = dctx->ddictIsCold; +#else + /* Set to 1 to avoid computing offset info if we don't need to. + * Otherwise this value is ignored. + */ + int usePrefetchDecoder = 1; +#endif + int nbSeq; + size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, srcSize); + if (ZSTD_isError(seqHSize)) return seqHSize; + ip += seqHSize; + srcSize -= seqHSize; + + RETURN_ERROR_IF((dst == NULL || dstCapacity == 0) && nbSeq > 0, dstSize_tooSmall, "NULL not handled"); + RETURN_ERROR_IF(MEM_64bits() && sizeof(size_t) == sizeof(void*) && (size_t)(-1) - (size_t)dst < (size_t)(1 << 20), dstSize_tooSmall, + "invalid dst"); + + /* If we could potentially have long offsets, or we might want to use the prefetch decoder, + * compute information about the share of long offsets, and the maximum nbAdditionalBits. + * NOTE: could probably use a larger nbSeq limit + */ + if (isLongOffset || (!usePrefetchDecoder && (totalHistorySize > (1u << 24)) && (nbSeq > 8))) { + ZSTD_OffsetInfo const info = ZSTD_getOffsetInfo(dctx->OFTptr, nbSeq); + if (isLongOffset && info.maxNbAdditionalBits <= STREAM_ACCUMULATOR_MIN) { + /* If isLongOffset, but the maximum number of additional bits that we see in our table is small + * enough, then we know it is impossible to have too long an offset in this block, so we can + * use the regular offset decoder. + */ + isLongOffset = ZSTD_lo_isRegularOffset; + } + if (!usePrefetchDecoder) { + U32 const minShare = MEM_64bits() ? 7 : 20; /* heuristic values, correspond to 2.73% and 7.81% */ + usePrefetchDecoder = (info.longOffsetShare >= minShare); + } + } + + dctx->ddictIsCold = 0; + +#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \ + !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG) + if (usePrefetchDecoder) { +#else + (void)usePrefetchDecoder; + { +#endif +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT + return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); +#endif + } + +#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG + /* else */ + if (dctx->litBufferLocation == ZSTD_split) + return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); + else + return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); +#endif + } +} + + +ZSTD_ALLOW_POINTER_OVERFLOW_ATTR +void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize) +{ + if (dst != dctx->previousDstEnd && dstSize > 0) { /* not contiguous */ + dctx->dictEnd = dctx->previousDstEnd; + dctx->virtualStart = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart)); + dctx->prefixStart = dst; + dctx->previousDstEnd = dst; + } +} diff --git a/src/commonlib/bsd/zstd/decompress/zstd_decompress_block.h b/src/commonlib/bsd/zstd/decompress/zstd_decompress_block.h new file mode 100644 index 00000000000..d8ece22cfbf --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/zstd_decompress_block.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +#ifndef ZSTD_DEC_BLOCK_H +#define ZSTD_DEC_BLOCK_H + +/*-******************************************************* + * Dependencies + *********************************************************/ +#include "../common/zstd_deps.h" /* size_t */ +#include "../zstd.h" /* DCtx, and some public functions */ +#include "../common/zstd_internal.h" /* blockProperties_t, and some public functions */ +#include "zstd_decompress_internal.h" /* ZSTD_seqSymbol */ + + +/* === Prototypes === */ + +/* note: prototypes already published within `zstd.h` : + * ZSTD_decompressBlock() + */ + +/* note: prototypes already published within `zstd_internal.h` : + * ZSTD_getcBlockSize() + * ZSTD_decodeSeqHeaders() + */ + + + /* Streaming state is used to inform allocation of the literal buffer */ +typedef enum { + not_streaming = 0, + is_streaming = 1 +} streaming_operation; + +/* ZSTD_decompressBlock_internal() : + * decompress block, starting at `src`, + * into destination buffer `dst`. + * @return : decompressed block size, + * or an error code (which can be tested using ZSTD_isError()) + */ +size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, const streaming_operation streaming); + +/* ZSTD_buildFSETable() : + * generate FSE decoding table for one symbol (ll, ml or off) + * this function must be called with valid parameters only + * (dt is large enough, normalizedCounter distribution total is a power of 2, max is within range, etc.) + * in which case it cannot fail. + * The workspace must be 4-byte aligned and at least ZSTD_BUILD_FSE_TABLE_WKSP_SIZE bytes, which is + * defined in zstd_decompress_internal.h. + * Internal use only. + */ +void ZSTD_buildFSETable(ZSTD_seqSymbol* dt, + const short* normalizedCounter, unsigned maxSymbolValue, + const U32* baseValue, const U8* nbAdditionalBits, + unsigned tableLog, void* wksp, size_t wkspSize, + int bmi2); + +#endif /* ZSTD_DEC_BLOCK_H */ diff --git a/src/commonlib/bsd/zstd/decompress/zstd_decompress_internal.h b/src/commonlib/bsd/zstd/decompress/zstd_decompress_internal.h new file mode 100644 index 00000000000..ae1d7503786 --- /dev/null +++ b/src/commonlib/bsd/zstd/decompress/zstd_decompress_internal.h @@ -0,0 +1,240 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + + +/* zstd_decompress_internal: + * objects and definitions shared within lib/decompress modules */ + + #ifndef ZSTD_DECOMPRESS_INTERNAL_H + #define ZSTD_DECOMPRESS_INTERNAL_H + + +/*-******************************************************* + * Dependencies + *********************************************************/ +#include "../common/mem.h" /* BYTE, U16, U32 */ +#include "../common/zstd_internal.h" /* constants : MaxLL, MaxML, MaxOff, LLFSELog, etc. */ + + + +/*-******************************************************* + * Constants + *********************************************************/ +static UNUSED_ATTR const U32 LL_base[MaxLL+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 18, 20, 22, 24, 28, 32, 40, + 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, + 0x2000, 0x4000, 0x8000, 0x10000 }; + +static UNUSED_ATTR const U32 OF_base[MaxOff+1] = { + 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, + 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, + 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, + 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD }; + +static UNUSED_ATTR const U8 OF_bits[MaxOff+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31 }; + +static UNUSED_ATTR const U32 ML_base[MaxML+1] = { + 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, + 35, 37, 39, 41, 43, 47, 51, 59, + 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, + 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; + + +/*-******************************************************* + * Decompression types + *********************************************************/ + typedef struct { + U32 fastMode; + U32 tableLog; + } ZSTD_seqSymbol_header; + + typedef struct { + U16 nextState; + BYTE nbAdditionalBits; + BYTE nbBits; + U32 baseValue; + } ZSTD_seqSymbol; + + #define SEQSYMBOL_TABLE_SIZE(log) (1 + (1 << (log))) + +#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE (sizeof(S16) * (MaxSeq + 1) + (1u << MaxFSELog) + sizeof(U64)) +#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32 ((ZSTD_BUILD_FSE_TABLE_WKSP_SIZE + sizeof(U32) - 1) / sizeof(U32)) +#define ZSTD_HUFFDTABLE_CAPACITY_LOG 12 + +typedef struct { + ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)]; /* Note : Space reserved for FSE Tables */ + ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)]; /* is also used as temporary workspace while building hufTable during DDict creation */ + ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)]; /* and therefore must be at least HUF_DECOMPRESS_WORKSPACE_SIZE large */ + HUF_DTable hufTable[HUF_DTABLE_SIZE(ZSTD_HUFFDTABLE_CAPACITY_LOG)]; /* can accommodate HUF_decompress4X */ + U32 rep[ZSTD_REP_NUM]; + U32 workspace[ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32]; +} ZSTD_entropyDTables_t; + +typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader, + ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock, + ZSTDds_decompressLastBlock, ZSTDds_checkChecksum, + ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage; + +typedef enum { zdss_init=0, zdss_loadHeader, + zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage; + +typedef enum { + ZSTD_use_indefinitely = -1, /* Use the dictionary indefinitely */ + ZSTD_dont_use = 0, /* Do not use the dictionary (if one exists free it) */ + ZSTD_use_once = 1 /* Use the dictionary once and set to ZSTD_dont_use */ +} ZSTD_dictUses_e; + +/* Hashset for storing references to multiple ZSTD_DDict within ZSTD_DCtx */ +typedef struct { + const ZSTD_DDict** ddictPtrTable; + size_t ddictPtrTableSize; + size_t ddictPtrCount; +} ZSTD_DDictHashSet; + +#ifndef ZSTD_DECODER_INTERNAL_BUFFER +# define ZSTD_DECODER_INTERNAL_BUFFER (1 << 16) +#endif + +#define ZSTD_LBMIN 64 +#define ZSTD_LBMAX (128 << 10) + +/* extra buffer, compensates when dst is not large enough to store litBuffer */ +#define ZSTD_LITBUFFEREXTRASIZE BOUNDED(ZSTD_LBMIN, ZSTD_DECODER_INTERNAL_BUFFER, ZSTD_LBMAX) + +typedef enum { + ZSTD_not_in_dst = 0, /* Stored entirely within litExtraBuffer */ + ZSTD_in_dst = 1, /* Stored entirely within dst (in memory after current output write) */ + ZSTD_split = 2 /* Split between litExtraBuffer and dst */ +} ZSTD_litLocation_e; + +struct ZSTD_DCtx_s +{ + const ZSTD_seqSymbol* LLTptr; + const ZSTD_seqSymbol* MLTptr; + const ZSTD_seqSymbol* OFTptr; + const HUF_DTable* HUFptr; + ZSTD_entropyDTables_t entropy; + U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; /* space needed when building huffman tables */ + const void* previousDstEnd; /* detect continuity */ + const void* prefixStart; /* start of current segment */ + const void* virtualStart; /* virtual start of previous segment if it was just before current one */ + const void* dictEnd; /* end of previous segment */ + size_t expected; + ZSTD_FrameHeader fParams; + U64 processedCSize; + U64 decodedSize; + blockType_e bType; /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */ + ZSTD_dStage stage; + U32 litEntropy; + U32 fseEntropy; + XXH64_state_t xxhState; + size_t headerSize; + ZSTD_format_e format; + ZSTD_forceIgnoreChecksum_e forceIgnoreChecksum; /* User specified: if == 1, will ignore checksums in compressed frame. Default == 0 */ + U32 validateChecksum; /* if == 1, will validate checksum. Is == 1 if (fParams.checksumFlag == 1) and (forceIgnoreChecksum == 0). */ + const BYTE* litPtr; + ZSTD_customMem customMem; + size_t litSize; + size_t rleSize; + size_t staticSize; + int isFrameDecompression; +#if DYNAMIC_BMI2 + int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */ +#endif + + /* dictionary */ + const ZSTD_DDict* ddict; /* set by ZSTD_initDStream_usingDDict(), or ZSTD_DCtx_refDDict() */ + U32 dictID; + int ddictIsCold; /* if == 1 : dictionary is "new" for working context, and presumed "cold" (not in cpu cache) */ + ZSTD_dictUses_e dictUses; + ZSTD_refMultipleDDicts_e refMultipleDDicts; /* User specified: if == 1, will allow references to multiple DDicts. Default == 0 (disabled) */ + int disableHufAsm; + int maxBlockSizeParam; + + /* streaming */ + ZSTD_dStreamStage streamStage; + char* inBuff; + size_t inBuffSize; + size_t inPos; + size_t maxWindowSize; + char* outBuff; + size_t outBuffSize; + size_t outStart; + size_t outEnd; + size_t lhSize; +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) + void* legacyContext; + U32 previousLegacyVersion; + U32 legacyVersion; +#endif + U32 hostageByte; + int noForwardProgress; + ZSTD_bufferMode_e outBufferMode; + ZSTD_outBuffer expectedOutBuffer; + + /* workspace */ + BYTE* litBuffer; + const BYTE* litBufferEnd; + ZSTD_litLocation_e litBufferLocation; + BYTE litExtraBuffer[ZSTD_LITBUFFEREXTRASIZE + WILDCOPY_OVERLENGTH]; /* literal buffer can be split between storage within dst and within this scratch buffer */ + BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; + + size_t oversizedDuration; + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + void const* dictContentBeginForFuzzing; + void const* dictContentEndForFuzzing; +#endif + + /* Tracing */ +#if ZSTD_TRACE + ZSTD_TraceCtx traceCtx; +#endif +}; /* typedef'd to ZSTD_DCtx within "zstd.h" */ + +MEM_STATIC int ZSTD_DCtx_get_bmi2(const struct ZSTD_DCtx_s *dctx) { +#if DYNAMIC_BMI2 + return dctx->bmi2; +#else + (void)dctx; + return 0; +#endif +} + +/*-******************************************************* + * Shared internal functions + *********************************************************/ + +/*! ZSTD_loadDEntropy() : + * dict : must point at beginning of a valid zstd dictionary. + * @return : size of dictionary header (size of magic number + dict ID + entropy tables) */ +size_t ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy, + const void* const dict, size_t const dictSize); + +/*! ZSTD_checkContinuity() : + * check if next `dst` follows previous position, where decompression ended. + * If yes, do nothing (continue on current segment). + * If not, classify previous segment as "external dictionary", and start a new segment. + * This function cannot fail. */ +void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize); + + +#endif /* ZSTD_DECOMPRESS_INTERNAL_H */ diff --git a/src/commonlib/bsd/zstd/zdict.h b/src/commonlib/bsd/zstd/zdict.h new file mode 100644 index 00000000000..9befe96c1a6 --- /dev/null +++ b/src/commonlib/bsd/zstd/zdict.h @@ -0,0 +1,483 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_ZDICT_H +#define ZSTD_ZDICT_H + + +/*====== Dependencies ======*/ +#include /* size_t */ + +#if defined (__cplusplus) +extern "C" { +#endif + +/* ===== ZDICTLIB_API : control library symbols visibility ===== */ +#ifndef ZDICTLIB_VISIBLE + /* Backwards compatibility with old macro name */ +# ifdef ZDICTLIB_VISIBILITY +# define ZDICTLIB_VISIBLE ZDICTLIB_VISIBILITY +# elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) +# define ZDICTLIB_VISIBLE __attribute__ ((visibility ("default"))) +# else +# define ZDICTLIB_VISIBLE +# endif +#endif + +#ifndef ZDICTLIB_HIDDEN +# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) +# define ZDICTLIB_HIDDEN __attribute__ ((visibility ("hidden"))) +# else +# define ZDICTLIB_HIDDEN +# endif +#endif + +#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +# define ZDICTLIB_API __declspec(dllexport) ZDICTLIB_VISIBLE +#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZDICTLIB_API __declspec(dllimport) ZDICTLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define ZDICTLIB_API ZDICTLIB_VISIBLE +#endif + +/******************************************************************************* + * Zstd dictionary builder + * + * FAQ + * === + * Why should I use a dictionary? + * ------------------------------ + * + * Zstd can use dictionaries to improve compression ratio of small data. + * Traditionally small files don't compress well because there is very little + * repetition in a single sample, since it is small. But, if you are compressing + * many similar files, like a bunch of JSON records that share the same + * structure, you can train a dictionary on ahead of time on some samples of + * these files. Then, zstd can use the dictionary to find repetitions that are + * present across samples. This can vastly improve compression ratio. + * + * When is a dictionary useful? + * ---------------------------- + * + * Dictionaries are useful when compressing many small files that are similar. + * The larger a file is, the less benefit a dictionary will have. Generally, + * we don't expect dictionary compression to be effective past 100KB. And the + * smaller a file is, the more we would expect the dictionary to help. + * + * How do I use a dictionary? + * -------------------------- + * + * Simply pass the dictionary to the zstd compressor with + * `ZSTD_CCtx_loadDictionary()`. The same dictionary must then be passed to + * the decompressor, using `ZSTD_DCtx_loadDictionary()`. There are other + * more advanced functions that allow selecting some options, see zstd.h for + * complete documentation. + * + * What is a zstd dictionary? + * -------------------------- + * + * A zstd dictionary has two pieces: Its header, and its content. The header + * contains a magic number, the dictionary ID, and entropy tables. These + * entropy tables allow zstd to save on header costs in the compressed file, + * which really matters for small data. The content is just bytes, which are + * repeated content that is common across many samples. + * + * What is a raw content dictionary? + * --------------------------------- + * + * A raw content dictionary is just bytes. It doesn't have a zstd dictionary + * header, a dictionary ID, or entropy tables. Any buffer is a valid raw + * content dictionary. + * + * How do I train a dictionary? + * ---------------------------- + * + * Gather samples from your use case. These samples should be similar to each + * other. If you have several use cases, you could try to train one dictionary + * per use case. + * + * Pass those samples to `ZDICT_trainFromBuffer()` and that will train your + * dictionary. There are a few advanced versions of this function, but this + * is a great starting point. If you want to further tune your dictionary + * you could try `ZDICT_optimizeTrainFromBuffer_cover()`. If that is too slow + * you can try `ZDICT_optimizeTrainFromBuffer_fastCover()`. + * + * If the dictionary training function fails, that is likely because you + * either passed too few samples, or a dictionary would not be effective + * for your data. Look at the messages that the dictionary trainer printed, + * if it doesn't say too few samples, then a dictionary would not be effective. + * + * How large should my dictionary be? + * ---------------------------------- + * + * A reasonable dictionary size, the `dictBufferCapacity`, is about 100KB. + * The zstd CLI defaults to a 110KB dictionary. You likely don't need a + * dictionary larger than that. But, most use cases can get away with a + * smaller dictionary. The advanced dictionary builders can automatically + * shrink the dictionary for you, and select the smallest size that doesn't + * hurt compression ratio too much. See the `shrinkDict` parameter. + * A smaller dictionary can save memory, and potentially speed up + * compression. + * + * How many samples should I provide to the dictionary builder? + * ------------------------------------------------------------ + * + * We generally recommend passing ~100x the size of the dictionary + * in samples. A few thousand should suffice. Having too few samples + * can hurt the dictionaries effectiveness. Having more samples will + * only improve the dictionaries effectiveness. But having too many + * samples can slow down the dictionary builder. + * + * How do I determine if a dictionary will be effective? + * ----------------------------------------------------- + * + * Simply train a dictionary and try it out. You can use zstd's built in + * benchmarking tool to test the dictionary effectiveness. + * + * # Benchmark levels 1-3 without a dictionary + * zstd -b1e3 -r /path/to/my/files + * # Benchmark levels 1-3 with a dictionary + * zstd -b1e3 -r /path/to/my/files -D /path/to/my/dictionary + * + * When should I retrain a dictionary? + * ----------------------------------- + * + * You should retrain a dictionary when its effectiveness drops. Dictionary + * effectiveness drops as the data you are compressing changes. Generally, we do + * expect dictionaries to "decay" over time, as your data changes, but the rate + * at which they decay depends on your use case. Internally, we regularly + * retrain dictionaries, and if the new dictionary performs significantly + * better than the old dictionary, we will ship the new dictionary. + * + * I have a raw content dictionary, how do I turn it into a zstd dictionary? + * ------------------------------------------------------------------------- + * + * If you have a raw content dictionary, e.g. by manually constructing it, or + * using a third-party dictionary builder, you can turn it into a zstd + * dictionary by using `ZDICT_finalizeDictionary()`. You'll also have to + * provide some samples of the data. It will add the zstd header to the + * raw content, which contains a dictionary ID and entropy tables, which + * will improve compression ratio, and allow zstd to write the dictionary ID + * into the frame, if you so choose. + * + * Do I have to use zstd's dictionary builder? + * ------------------------------------------- + * + * No! You can construct dictionary content however you please, it is just + * bytes. It will always be valid as a raw content dictionary. If you want + * a zstd dictionary, which can improve compression ratio, use + * `ZDICT_finalizeDictionary()`. + * + * What is the attack surface of a zstd dictionary? + * ------------------------------------------------ + * + * Zstd is heavily fuzz tested, including loading fuzzed dictionaries, so + * zstd should never crash, or access out-of-bounds memory no matter what + * the dictionary is. However, if an attacker can control the dictionary + * during decompression, they can cause zstd to generate arbitrary bytes, + * just like if they controlled the compressed data. + * + ******************************************************************************/ + + +/*! ZDICT_trainFromBuffer(): + * Train a dictionary from an array of samples. + * Redirect towards ZDICT_optimizeTrainFromBuffer_fastCover() single-threaded, with d=8, steps=4, + * f=20, and accel=1. + * Samples must be stored concatenated in a single flat buffer `samplesBuffer`, + * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order. + * The resulting dictionary will be saved into `dictBuffer`. + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`) + * or an error code, which can be tested with ZDICT_isError(). + * Note: Dictionary training will fail if there are not enough samples to construct a + * dictionary, or if most of the samples are too small (< 8 bytes being the lower limit). + * If dictionary training fails, you should use zstd without a dictionary, as the dictionary + * would've been ineffective anyways. If you believe your samples would benefit from a dictionary + * please open an issue with details, and we can look into it. + * Note: ZDICT_trainFromBuffer()'s memory usage is about 6 MB. + * Tips: In general, a reasonable dictionary has a size of ~ 100 KB. + * It's possible to select smaller or larger size, just by specifying `dictBufferCapacity`. + * In general, it's recommended to provide a few thousands samples, though this can vary a lot. + * It's recommended that total size of all samples be about ~x100 times the target size of dictionary. + */ +ZDICTLIB_API size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity, + const void* samplesBuffer, + const size_t* samplesSizes, unsigned nbSamples); + +typedef struct { + int compressionLevel; /**< optimize for a specific zstd compression level; 0 means default */ + unsigned notificationLevel; /**< Write log to stderr; 0 = none (default); 1 = errors; 2 = progression; 3 = details; 4 = debug; */ + unsigned dictID; /**< force dictID value; 0 means auto mode (32-bits random value) + * NOTE: The zstd format reserves some dictionary IDs for future use. + * You may use them in private settings, but be warned that they + * may be used by zstd in a public dictionary registry in the future. + * These dictionary IDs are: + * - low range : <= 32767 + * - high range : >= (2^31) + */ +} ZDICT_params_t; + +/*! ZDICT_finalizeDictionary(): + * Given a custom content as a basis for dictionary, and a set of samples, + * finalize dictionary by adding headers and statistics according to the zstd + * dictionary format. + * + * Samples must be stored concatenated in a flat buffer `samplesBuffer`, + * supplied with an array of sizes `samplesSizes`, providing the size of each + * sample in order. The samples are used to construct the statistics, so they + * should be representative of what you will compress with this dictionary. + * + * The compression level can be set in `parameters`. You should pass the + * compression level you expect to use in production. The statistics for each + * compression level differ, so tuning the dictionary for the compression level + * can help quite a bit. + * + * You can set an explicit dictionary ID in `parameters`, or allow us to pick + * a random dictionary ID for you, but we can't guarantee no collisions. + * + * The dstDictBuffer and the dictContent may overlap, and the content will be + * appended to the end of the header. If the header + the content doesn't fit in + * maxDictSize the beginning of the content is truncated to make room, since it + * is presumed that the most profitable content is at the end of the dictionary, + * since that is the cheapest to reference. + * + * `maxDictSize` must be >= max(dictContentSize, ZDICT_DICTSIZE_MIN). + * + * @return: size of dictionary stored into `dstDictBuffer` (<= `maxDictSize`), + * or an error code, which can be tested by ZDICT_isError(). + * Note: ZDICT_finalizeDictionary() will push notifications into stderr if + * instructed to, using notificationLevel>0. + * NOTE: This function currently may fail in several edge cases including: + * * Not enough samples + * * Samples are uncompressible + * * Samples are all exactly the same + */ +ZDICTLIB_API size_t ZDICT_finalizeDictionary(void* dstDictBuffer, size_t maxDictSize, + const void* dictContent, size_t dictContentSize, + const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples, + ZDICT_params_t parameters); + + +/*====== Helper functions ======*/ +ZDICTLIB_API unsigned ZDICT_getDictID(const void* dictBuffer, size_t dictSize); /**< extracts dictID; @return zero if error (not a valid dictionary) */ +ZDICTLIB_API size_t ZDICT_getDictHeaderSize(const void* dictBuffer, size_t dictSize); /* returns dict header size; returns a ZSTD error code on failure */ +ZDICTLIB_API unsigned ZDICT_isError(size_t errorCode); +ZDICTLIB_API const char* ZDICT_getErrorName(size_t errorCode); + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_ZDICT_H */ + +#if defined(ZDICT_STATIC_LINKING_ONLY) && !defined(ZSTD_ZDICT_H_STATIC) +#define ZSTD_ZDICT_H_STATIC + +#if defined (__cplusplus) +extern "C" { +#endif + +/* This can be overridden externally to hide static symbols. */ +#ifndef ZDICTLIB_STATIC_API +# if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +# define ZDICTLIB_STATIC_API __declspec(dllexport) ZDICTLIB_VISIBLE +# elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZDICTLIB_STATIC_API __declspec(dllimport) ZDICTLIB_VISIBLE +# else +# define ZDICTLIB_STATIC_API ZDICTLIB_VISIBLE +# endif +#endif + +/* ==================================================================================== + * The definitions in this section are considered experimental. + * They should never be used with a dynamic library, as they may change in the future. + * They are provided for advanced usages. + * Use them only in association with static linking. + * ==================================================================================== */ + +#define ZDICT_DICTSIZE_MIN 256 +/* Deprecated: Remove in v1.6.0 */ +#define ZDICT_CONTENTSIZE_MIN 128 + +/*! ZDICT_cover_params_t: + * k and d are the only required parameters. + * For others, value 0 means default. + */ +typedef struct { + unsigned k; /* Segment size : constraint: 0 < k : Reasonable range [16, 2048+] */ + unsigned d; /* dmer size : constraint: 0 < d <= k : Reasonable range [6, 16] */ + unsigned steps; /* Number of steps : Only used for optimization : 0 means default (40) : Higher means more parameters checked */ + unsigned nbThreads; /* Number of threads : constraint: 0 < nbThreads : 1 means single-threaded : Only used for optimization : Ignored if ZSTD_MULTITHREAD is not defined */ + double splitPoint; /* Percentage of samples used for training: Only used for optimization : the first nbSamples * splitPoint samples will be used to training, the last nbSamples * (1 - splitPoint) samples will be used for testing, 0 means default (1.0), 1.0 when all samples are used for both training and testing */ + unsigned shrinkDict; /* Train dictionaries to shrink in size starting from the minimum size and selects the smallest dictionary that is shrinkDictMaxRegression% worse than the largest dictionary. 0 means no shrinking and 1 means shrinking */ + unsigned shrinkDictMaxRegression; /* Sets shrinkDictMaxRegression so that a smaller dictionary can be at worse shrinkDictMaxRegression% worse than the max dict size dictionary. */ + ZDICT_params_t zParams; +} ZDICT_cover_params_t; + +typedef struct { + unsigned k; /* Segment size : constraint: 0 < k : Reasonable range [16, 2048+] */ + unsigned d; /* dmer size : constraint: 0 < d <= k : Reasonable range [6, 16] */ + unsigned f; /* log of size of frequency array : constraint: 0 < f <= 31 : 1 means default(20)*/ + unsigned steps; /* Number of steps : Only used for optimization : 0 means default (40) : Higher means more parameters checked */ + unsigned nbThreads; /* Number of threads : constraint: 0 < nbThreads : 1 means single-threaded : Only used for optimization : Ignored if ZSTD_MULTITHREAD is not defined */ + double splitPoint; /* Percentage of samples used for training: Only used for optimization : the first nbSamples * splitPoint samples will be used to training, the last nbSamples * (1 - splitPoint) samples will be used for testing, 0 means default (0.75), 1.0 when all samples are used for both training and testing */ + unsigned accel; /* Acceleration level: constraint: 0 < accel <= 10, higher means faster and less accurate, 0 means default(1) */ + unsigned shrinkDict; /* Train dictionaries to shrink in size starting from the minimum size and selects the smallest dictionary that is shrinkDictMaxRegression% worse than the largest dictionary. 0 means no shrinking and 1 means shrinking */ + unsigned shrinkDictMaxRegression; /* Sets shrinkDictMaxRegression so that a smaller dictionary can be at worse shrinkDictMaxRegression% worse than the max dict size dictionary. */ + + ZDICT_params_t zParams; +} ZDICT_fastCover_params_t; + +/*! ZDICT_trainFromBuffer_cover(): + * Train a dictionary from an array of samples using the COVER algorithm. + * Samples must be stored concatenated in a single flat buffer `samplesBuffer`, + * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order. + * The resulting dictionary will be saved into `dictBuffer`. + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`) + * or an error code, which can be tested with ZDICT_isError(). + * See ZDICT_trainFromBuffer() for details on failure modes. + * Note: ZDICT_trainFromBuffer_cover() requires about 9 bytes of memory for each input byte. + * Tips: In general, a reasonable dictionary has a size of ~ 100 KB. + * It's possible to select smaller or larger size, just by specifying `dictBufferCapacity`. + * In general, it's recommended to provide a few thousands samples, though this can vary a lot. + * It's recommended that total size of all samples be about ~x100 times the target size of dictionary. + */ +ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_cover( + void *dictBuffer, size_t dictBufferCapacity, + const void *samplesBuffer, const size_t *samplesSizes, unsigned nbSamples, + ZDICT_cover_params_t parameters); + +/*! ZDICT_optimizeTrainFromBuffer_cover(): + * The same requirements as above hold for all the parameters except `parameters`. + * This function tries many parameter combinations and picks the best parameters. + * `*parameters` is filled with the best parameters found, + * dictionary constructed with those parameters is stored in `dictBuffer`. + * + * All of the parameters d, k, steps are optional. + * If d is non-zero then we don't check multiple values of d, otherwise we check d = {6, 8}. + * if steps is zero it defaults to its default value. + * If k is non-zero then we don't check multiple values of k, otherwise we check steps values in [50, 2000]. + * + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`) + * or an error code, which can be tested with ZDICT_isError(). + * On success `*parameters` contains the parameters selected. + * See ZDICT_trainFromBuffer() for details on failure modes. + * Note: ZDICT_optimizeTrainFromBuffer_cover() requires about 8 bytes of memory for each input byte and additionally another 5 bytes of memory for each byte of memory for each thread. + */ +ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_cover( + void* dictBuffer, size_t dictBufferCapacity, + const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples, + ZDICT_cover_params_t* parameters); + +/*! ZDICT_trainFromBuffer_fastCover(): + * Train a dictionary from an array of samples using a modified version of COVER algorithm. + * Samples must be stored concatenated in a single flat buffer `samplesBuffer`, + * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order. + * d and k are required. + * All other parameters are optional, will use default values if not provided + * The resulting dictionary will be saved into `dictBuffer`. + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`) + * or an error code, which can be tested with ZDICT_isError(). + * See ZDICT_trainFromBuffer() for details on failure modes. + * Note: ZDICT_trainFromBuffer_fastCover() requires 6 * 2^f bytes of memory. + * Tips: In general, a reasonable dictionary has a size of ~ 100 KB. + * It's possible to select smaller or larger size, just by specifying `dictBufferCapacity`. + * In general, it's recommended to provide a few thousands samples, though this can vary a lot. + * It's recommended that total size of all samples be about ~x100 times the target size of dictionary. + */ +ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_fastCover(void *dictBuffer, + size_t dictBufferCapacity, const void *samplesBuffer, + const size_t *samplesSizes, unsigned nbSamples, + ZDICT_fastCover_params_t parameters); + +/*! ZDICT_optimizeTrainFromBuffer_fastCover(): + * The same requirements as above hold for all the parameters except `parameters`. + * This function tries many parameter combinations (specifically, k and d combinations) + * and picks the best parameters. `*parameters` is filled with the best parameters found, + * dictionary constructed with those parameters is stored in `dictBuffer`. + * All of the parameters d, k, steps, f, and accel are optional. + * If d is non-zero then we don't check multiple values of d, otherwise we check d = {6, 8}. + * if steps is zero it defaults to its default value. + * If k is non-zero then we don't check multiple values of k, otherwise we check steps values in [50, 2000]. + * If f is zero, default value of 20 is used. + * If accel is zero, default value of 1 is used. + * + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`) + * or an error code, which can be tested with ZDICT_isError(). + * On success `*parameters` contains the parameters selected. + * See ZDICT_trainFromBuffer() for details on failure modes. + * Note: ZDICT_optimizeTrainFromBuffer_fastCover() requires about 6 * 2^f bytes of memory for each thread. + */ +ZDICTLIB_STATIC_API size_t ZDICT_optimizeTrainFromBuffer_fastCover(void* dictBuffer, + size_t dictBufferCapacity, const void* samplesBuffer, + const size_t* samplesSizes, unsigned nbSamples, + ZDICT_fastCover_params_t* parameters); + +typedef struct { + unsigned selectivityLevel; /* 0 means default; larger => select more => larger dictionary */ + ZDICT_params_t zParams; +} ZDICT_legacy_params_t; + +/*! ZDICT_trainFromBuffer_legacy(): + * Train a dictionary from an array of samples. + * Samples must be stored concatenated in a single flat buffer `samplesBuffer`, + * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order. + * The resulting dictionary will be saved into `dictBuffer`. + * `parameters` is optional and can be provided with values set to 0 to mean "default". + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`) + * or an error code, which can be tested with ZDICT_isError(). + * See ZDICT_trainFromBuffer() for details on failure modes. + * Tips: In general, a reasonable dictionary has a size of ~ 100 KB. + * It's possible to select smaller or larger size, just by specifying `dictBufferCapacity`. + * In general, it's recommended to provide a few thousands samples, though this can vary a lot. + * It's recommended that total size of all samples be about ~x100 times the target size of dictionary. + * Note: ZDICT_trainFromBuffer_legacy() will send notifications into stderr if instructed to, using notificationLevel>0. + */ +ZDICTLIB_STATIC_API size_t ZDICT_trainFromBuffer_legacy( + void* dictBuffer, size_t dictBufferCapacity, + const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples, + ZDICT_legacy_params_t parameters); + + +/* Deprecation warnings */ +/* It is generally possible to disable deprecation warnings from compiler, + for example with -Wno-deprecated-declarations for gcc + or _CRT_SECURE_NO_WARNINGS in Visual. + Otherwise, it's also possible to manually define ZDICT_DISABLE_DEPRECATE_WARNINGS */ +#ifdef ZDICT_DISABLE_DEPRECATE_WARNINGS +# define ZDICT_DEPRECATED(message) /* disable deprecation warnings */ +#else +# define ZDICT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) +# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ +# define ZDICT_DEPRECATED(message) [[deprecated(message)]] +# elif defined(__clang__) || (ZDICT_GCC_VERSION >= 405) +# define ZDICT_DEPRECATED(message) __attribute__((deprecated(message))) +# elif (ZDICT_GCC_VERSION >= 301) +# define ZDICT_DEPRECATED(message) __attribute__((deprecated)) +# elif defined(_MSC_VER) +# define ZDICT_DEPRECATED(message) __declspec(deprecated(message)) +# else +# pragma message("WARNING: You need to implement ZDICT_DEPRECATED for this compiler") +# define ZDICT_DEPRECATED(message) +# endif +#endif /* ZDICT_DISABLE_DEPRECATE_WARNINGS */ + +ZDICT_DEPRECATED("use ZDICT_finalizeDictionary() instead") +ZDICTLIB_STATIC_API +size_t ZDICT_addEntropyTablesFromBuffer(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity, + const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples); + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_ZDICT_H_STATIC */ diff --git a/src/commonlib/bsd/zstd/zstd.h b/src/commonlib/bsd/zstd/zstd.h new file mode 100644 index 00000000000..d88412c8dc3 --- /dev/null +++ b/src/commonlib/bsd/zstd/zstd.h @@ -0,0 +1,2646 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_H_235446 +#define ZSTD_H_235446 + + +/* ====== Dependencies ======*/ +#include /* size_t */ + +#include "zstd_errors.h" /* list of errors */ +#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY) +#include /* INT_MAX */ +#endif /* ZSTD_STATIC_LINKING_ONLY */ + +#if defined (__cplusplus) +extern "C" { +#endif + +/* ===== ZSTDLIB_API : control library symbols visibility ===== */ +#ifndef ZSTDLIB_VISIBLE + /* Backwards compatibility with old macro name */ +# ifdef ZSTDLIB_VISIBILITY +# define ZSTDLIB_VISIBLE ZSTDLIB_VISIBILITY +# elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) +# define ZSTDLIB_VISIBLE __attribute__ ((visibility ("default"))) +# else +# define ZSTDLIB_VISIBLE +# endif +#endif + +#ifndef ZSTDLIB_HIDDEN +# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) +# define ZSTDLIB_HIDDEN __attribute__ ((visibility ("hidden"))) +# else +# define ZSTDLIB_HIDDEN +# endif +#endif + +#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +# define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBLE +#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZSTDLIB_API __declspec(dllimport) ZSTDLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define ZSTDLIB_API ZSTDLIB_VISIBLE +#endif + +/* Deprecation warnings : + * Should these warnings be a problem, it is generally possible to disable them, + * typically with -Wno-deprecated-declarations for gcc or _CRT_SECURE_NO_WARNINGS in Visual. + * Otherwise, it's also possible to define ZSTD_DISABLE_DEPRECATE_WARNINGS. + */ +#ifdef ZSTD_DISABLE_DEPRECATE_WARNINGS +# define ZSTD_DEPRECATED(message) /* disable deprecation warnings */ +#else +# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ +# define ZSTD_DEPRECATED(message) [[deprecated(message)]] +# elif (defined(GNUC) && (GNUC > 4 || (GNUC == 4 && GNUC_MINOR >= 5))) || defined(__clang__) || defined(__IAR_SYSTEMS_ICC__) +# define ZSTD_DEPRECATED(message) __attribute__((deprecated(message))) +# elif defined(__GNUC__) && (__GNUC__ >= 3) +# define ZSTD_DEPRECATED(message) __attribute__((deprecated)) +# elif defined(_MSC_VER) +# define ZSTD_DEPRECATED(message) __declspec(deprecated(message)) +# else +# pragma message("WARNING: You need to implement ZSTD_DEPRECATED for this compiler") +# define ZSTD_DEPRECATED(message) +# endif +#endif /* ZSTD_DISABLE_DEPRECATE_WARNINGS */ + + +/******************************************************************************* + Introduction + + zstd, short for Zstandard, is a fast lossless compression algorithm, targeting + real-time compression scenarios at zlib-level and better compression ratios. + The zstd compression library provides in-memory compression and decompression + functions. + + The library supports regular compression levels from 1 up to ZSTD_maxCLevel(), + which is currently 22. Levels >= 20, labeled `--ultra`, should be used with + caution, as they require more memory. The library also offers negative + compression levels, which extend the range of speed vs. ratio preferences. + The lower the level, the faster the speed (at the cost of compression). + + Compression can be done in: + - a single step (described as Simple API) + - a single step, reusing a context (described as Explicit context) + - unbounded multiple steps (described as Streaming compression) + + The compression ratio achievable on small data can be highly improved using + a dictionary. Dictionary compression can be performed in: + - a single step (described as Simple dictionary API) + - a single step, reusing a dictionary (described as Bulk-processing + dictionary API) + + Advanced experimental functions can be accessed using + `#define ZSTD_STATIC_LINKING_ONLY` before including zstd.h. + + Advanced experimental APIs should never be used with a dynamically-linked + library. They are not "stable"; their definitions or signatures may change in + the future. Only static linking is allowed. +*******************************************************************************/ + +/*------ Version ------*/ +#define ZSTD_VERSION_MAJOR 1 +#define ZSTD_VERSION_MINOR 5 +#define ZSTD_VERSION_RELEASE 7 +#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) + +/*! ZSTD_versionNumber() : + * Return runtime library version, the value is (MAJOR*100*100 + MINOR*100 + RELEASE). */ +ZSTDLIB_API unsigned ZSTD_versionNumber(void); + +#define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE +#define ZSTD_QUOTE(str) #str +#define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str) +#define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION) + +/*! ZSTD_versionString() : + * Return runtime library version, like "1.4.5". Requires v1.3.0+. */ +ZSTDLIB_API const char* ZSTD_versionString(void); + +/* ************************************* + * Default constant + ***************************************/ +#ifndef ZSTD_CLEVEL_DEFAULT +# define ZSTD_CLEVEL_DEFAULT 3 +#endif + +/* ************************************* + * Constants + ***************************************/ + +/* All magic numbers are supposed read/written to/from files/memory using little-endian convention */ +#define ZSTD_MAGICNUMBER 0xFD2FB528 /* valid since v0.8.0 */ +#define ZSTD_MAGIC_DICTIONARY 0xEC30A437 /* valid since v0.7.0 */ +#define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50 /* all 16 values, from 0x184D2A50 to 0x184D2A5F, signal the beginning of a skippable frame */ +#define ZSTD_MAGIC_SKIPPABLE_MASK 0xFFFFFFF0 + +#define ZSTD_BLOCKSIZELOG_MAX 17 +#define ZSTD_BLOCKSIZE_MAX (1<= ZSTD_compressBound(srcSize)` guarantees that zstd will have + * enough space to successfully compress the data. + * @return : compressed size written into `dst` (<= `dstCapacity), + * or an error code if it fails (which can be tested using ZSTD_isError()). */ +ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + int compressionLevel); + +/*====== Decompression helper functions ======*/ + +/*! ZSTD_getFrameContentSize() : requires v1.3.0+ + * `src` should point to the start of a ZSTD encoded frame. + * `srcSize` must be at least as large as the frame header. + * hint : any size >= `ZSTD_frameHeaderSize_max` is large enough. + * @return : - decompressed size of `src` frame content, if known + * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined + * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) + * note 1 : a 0 return value means the frame is valid but "empty". + * When invoking this method on a skippable frame, it will return 0. + * note 2 : decompressed size is an optional field, it may not be present (typically in streaming mode). + * When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size. + * In which case, it's necessary to use streaming mode to decompress data. + * Optionally, application can rely on some implicit limit, + * as ZSTD_decompress() only needs an upper bound of decompressed size. + * (For example, data could be necessarily cut into blocks <= 16 KB). + * note 3 : decompressed size is always present when compression is completed using single-pass functions, + * such as ZSTD_compress(), ZSTD_compressCCtx() ZSTD_compress_usingDict() or ZSTD_compress_usingCDict(). + * note 4 : decompressed size can be very large (64-bits value), + * potentially larger than what local system can handle as a single memory segment. + * In which case, it's necessary to use streaming mode to decompress data. + * note 5 : If source is untrusted, decompressed size could be wrong or intentionally modified. + * Always ensure return value fits within application's authorized limits. + * Each application can set its own limits. + * note 6 : This function replaces ZSTD_getDecompressedSize() */ +#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1) +#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2) +ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize); + +/*! ZSTD_getDecompressedSize() (obsolete): + * This function is now obsolete, in favor of ZSTD_getFrameContentSize(). + * Both functions work the same way, but ZSTD_getDecompressedSize() blends + * "empty", "unknown" and "error" results to the same return value (0), + * while ZSTD_getFrameContentSize() gives them separate return values. + * @return : decompressed size of `src` frame content _if known and not empty_, 0 otherwise. */ +ZSTD_DEPRECATED("Replaced by ZSTD_getFrameContentSize") +ZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize); + +/*! ZSTD_findFrameCompressedSize() : Requires v1.4.0+ + * `src` should point to the start of a ZSTD frame or skippable frame. + * `srcSize` must be >= first frame size + * @return : the compressed size of the first frame starting at `src`, + * suitable to pass as `srcSize` to `ZSTD_decompress` or similar, + * or an error code if input is invalid + * Note 1: this method is called _find*() because it's not enough to read the header, + * it may have to scan through the frame's content, to reach its end. + * Note 2: this method also works with Skippable Frames. In which case, + * it returns the size of the complete skippable frame, + * which is always equal to its content size + 8 bytes for headers. */ +ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize); + + +/*====== Compression helper functions ======*/ + +/*! ZSTD_compressBound() : + * maximum compressed size in worst case single-pass scenario. + * When invoking `ZSTD_compress()`, or any other one-pass compression function, + * it's recommended to provide @dstCapacity >= ZSTD_compressBound(srcSize) + * as it eliminates one potential failure scenario, + * aka not enough room in dst buffer to write the compressed frame. + * Note : ZSTD_compressBound() itself can fail, if @srcSize >= ZSTD_MAX_INPUT_SIZE . + * In which case, ZSTD_compressBound() will return an error code + * which can be tested using ZSTD_isError(). + * + * ZSTD_COMPRESSBOUND() : + * same as ZSTD_compressBound(), but as a macro. + * It can be used to produce constants, which can be useful for static allocation, + * for example to size a static array on stack. + * Will produce constant value 0 if srcSize is too large. + */ +#define ZSTD_MAX_INPUT_SIZE ((sizeof(size_t)==8) ? 0xFF00FF00FF00FF00ULL : 0xFF00FF00U) +#define ZSTD_COMPRESSBOUND(srcSize) (((size_t)(srcSize) >= ZSTD_MAX_INPUT_SIZE) ? 0 : (srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) /* margin, from 64 to 0 */ : 0)) /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */ +ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */ + + +/*====== Error helper functions ======*/ +/* ZSTD_isError() : + * Most ZSTD_* functions returning a size_t value can be tested for error, + * using ZSTD_isError(). + * @return 1 if error, 0 otherwise + */ +ZSTDLIB_API unsigned ZSTD_isError(size_t result); /*!< tells if a `size_t` function result is an error code */ +ZSTDLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult); /* convert a result into an error code, which can be compared to error enum list */ +ZSTDLIB_API const char* ZSTD_getErrorName(size_t result); /*!< provides readable string from a function result */ +ZSTDLIB_API int ZSTD_minCLevel(void); /*!< minimum negative compression level allowed, requires v1.4.0+ */ +ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compression level available */ +ZSTDLIB_API int ZSTD_defaultCLevel(void); /*!< default compression level, specified by ZSTD_CLEVEL_DEFAULT, requires v1.5.0+ */ + + +/*************************************** +* Explicit context +***************************************/ +/*= Compression context + * When compressing many times, + * it is recommended to allocate a compression context just once, + * and reuse it for each successive compression operation. + * This will make the workload easier for system's memory. + * Note : re-using context is just a speed / resource optimization. + * It doesn't change the compression ratio, which remains identical. + * Note 2: For parallel execution in multi-threaded environments, + * use one different context per thread . + */ +typedef struct ZSTD_CCtx_s ZSTD_CCtx; +ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void); +ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); /* compatible with NULL pointer */ + +/*! ZSTD_compressCCtx() : + * Same as ZSTD_compress(), using an explicit ZSTD_CCtx. + * Important : in order to mirror `ZSTD_compress()` behavior, + * this function compresses at the requested compression level, + * __ignoring any other advanced parameter__ . + * If any advanced parameter was set using the advanced API, + * they will all be reset. Only @compressionLevel remains. + */ +ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + int compressionLevel); + +/*= Decompression context + * When decompressing many times, + * it is recommended to allocate a context only once, + * and reuse it for each successive compression operation. + * This will make workload friendlier for system's memory. + * Use one context per thread for parallel execution. */ +typedef struct ZSTD_DCtx_s ZSTD_DCtx; +ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void); +ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /* accept NULL pointer */ + +/*! ZSTD_decompressDCtx() : + * Same as ZSTD_decompress(), + * requires an allocated ZSTD_DCtx. + * Compatible with sticky parameters (see below). + */ +ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize); + + +/********************************************* +* Advanced compression API (Requires v1.4.0+) +**********************************************/ + +/* API design : + * Parameters are pushed one by one into an existing context, + * using ZSTD_CCtx_set*() functions. + * Pushed parameters are sticky : they are valid for next compressed frame, and any subsequent frame. + * "sticky" parameters are applicable to `ZSTD_compress2()` and `ZSTD_compressStream*()` ! + * __They do not apply to one-shot variants such as ZSTD_compressCCtx()__ . + * + * It's possible to reset all parameters to "default" using ZSTD_CCtx_reset(). + * + * This API supersedes all other "advanced" API entry points in the experimental section. + * In the future, we expect to remove API entry points from experimental which are redundant with this API. + */ + + +/* Compression strategies, listed from fastest to strongest */ +typedef enum { ZSTD_fast=1, + ZSTD_dfast=2, + ZSTD_greedy=3, + ZSTD_lazy=4, + ZSTD_lazy2=5, + ZSTD_btlazy2=6, + ZSTD_btopt=7, + ZSTD_btultra=8, + ZSTD_btultra2=9 + /* note : new strategies _might_ be added in the future. + Only the order (from fast to strong) is guaranteed */ +} ZSTD_strategy; + +typedef enum { + + /* compression parameters + * Note: When compressing with a ZSTD_CDict these parameters are superseded + * by the parameters used to construct the ZSTD_CDict. + * See ZSTD_CCtx_refCDict() for more info (superseded-by-cdict). */ + ZSTD_c_compressionLevel=100, /* Set compression parameters according to pre-defined cLevel table. + * Note that exact compression parameters are dynamically determined, + * depending on both compression level and srcSize (when known). + * Default level is ZSTD_CLEVEL_DEFAULT==3. + * Special: value 0 means default, which is controlled by ZSTD_CLEVEL_DEFAULT. + * Note 1 : it's possible to pass a negative compression level. + * Note 2 : setting a level does not automatically set all other compression parameters + * to default. Setting this will however eventually dynamically impact the compression + * parameters which have not been manually set. The manually set + * ones will 'stick'. */ + /* Advanced compression parameters : + * It's possible to pin down compression parameters to some specific values. + * In which case, these values are no longer dynamically selected by the compressor */ + ZSTD_c_windowLog=101, /* Maximum allowed back-reference distance, expressed as power of 2. + * This will set a memory budget for streaming decompression, + * with larger values requiring more memory + * and typically compressing more. + * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX. + * Special: value 0 means "use default windowLog". + * Note: Using a windowLog greater than ZSTD_WINDOWLOG_LIMIT_DEFAULT + * requires explicitly allowing such size at streaming decompression stage. */ + ZSTD_c_hashLog=102, /* Size of the initial probe table, as a power of 2. + * Resulting memory usage is (1 << (hashLog+2)). + * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX. + * Larger tables improve compression ratio of strategies <= dFast, + * and improve speed of strategies > dFast. + * Special: value 0 means "use default hashLog". */ + ZSTD_c_chainLog=103, /* Size of the multi-probe search table, as a power of 2. + * Resulting memory usage is (1 << (chainLog+2)). + * Must be clamped between ZSTD_CHAINLOG_MIN and ZSTD_CHAINLOG_MAX. + * Larger tables result in better and slower compression. + * This parameter is useless for "fast" strategy. + * It's still useful when using "dfast" strategy, + * in which case it defines a secondary probe table. + * Special: value 0 means "use default chainLog". */ + ZSTD_c_searchLog=104, /* Number of search attempts, as a power of 2. + * More attempts result in better and slower compression. + * This parameter is useless for "fast" and "dFast" strategies. + * Special: value 0 means "use default searchLog". */ + ZSTD_c_minMatch=105, /* Minimum size of searched matches. + * Note that Zstandard can still find matches of smaller size, + * it just tweaks its search algorithm to look for this size and larger. + * Larger values increase compression and decompression speed, but decrease ratio. + * Must be clamped between ZSTD_MINMATCH_MIN and ZSTD_MINMATCH_MAX. + * Note that currently, for all strategies < btopt, effective minimum is 4. + * , for all strategies > fast, effective maximum is 6. + * Special: value 0 means "use default minMatchLength". */ + ZSTD_c_targetLength=106, /* Impact of this field depends on strategy. + * For strategies btopt, btultra & btultra2: + * Length of Match considered "good enough" to stop search. + * Larger values make compression stronger, and slower. + * For strategy fast: + * Distance between match sampling. + * Larger values make compression faster, and weaker. + * Special: value 0 means "use default targetLength". */ + ZSTD_c_strategy=107, /* See ZSTD_strategy enum definition. + * The higher the value of selected strategy, the more complex it is, + * resulting in stronger and slower compression. + * Special: value 0 means "use default strategy". */ + + ZSTD_c_targetCBlockSize=130, /* v1.5.6+ + * Attempts to fit compressed block size into approximately targetCBlockSize. + * Bound by ZSTD_TARGETCBLOCKSIZE_MIN and ZSTD_TARGETCBLOCKSIZE_MAX. + * Note that it's not a guarantee, just a convergence target (default:0). + * No target when targetCBlockSize == 0. + * This is helpful in low bandwidth streaming environments to improve end-to-end latency, + * when a client can make use of partial documents (a prominent example being Chrome). + * Note: this parameter is stable since v1.5.6. + * It was present as an experimental parameter in earlier versions, + * but it's not recommended using it with earlier library versions + * due to massive performance regressions. + */ + /* LDM mode parameters */ + ZSTD_c_enableLongDistanceMatching=160, /* Enable long distance matching. + * This parameter is designed to improve compression ratio + * for large inputs, by finding large matches at long distance. + * It increases memory usage and window size. + * Note: enabling this parameter increases default ZSTD_c_windowLog to 128 MB + * except when expressly set to a different value. + * Note: will be enabled by default if ZSTD_c_windowLog >= 128 MB and + * compression strategy >= ZSTD_btopt (== compression level 16+) */ + ZSTD_c_ldmHashLog=161, /* Size of the table for long distance matching, as a power of 2. + * Larger values increase memory usage and compression ratio, + * but decrease compression speed. + * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX + * default: windowlog - 7. + * Special: value 0 means "automatically determine hashlog". */ + ZSTD_c_ldmMinMatch=162, /* Minimum match size for long distance matcher. + * Larger/too small values usually decrease compression ratio. + * Must be clamped between ZSTD_LDM_MINMATCH_MIN and ZSTD_LDM_MINMATCH_MAX. + * Special: value 0 means "use default value" (default: 64). */ + ZSTD_c_ldmBucketSizeLog=163, /* Log size of each bucket in the LDM hash table for collision resolution. + * Larger values improve collision resolution but decrease compression speed. + * The maximum value is ZSTD_LDM_BUCKETSIZELOG_MAX. + * Special: value 0 means "use default value" (default: 3). */ + ZSTD_c_ldmHashRateLog=164, /* Frequency of inserting/looking up entries into the LDM hash table. + * Must be clamped between 0 and (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN). + * Default is MAX(0, (windowLog - ldmHashLog)), optimizing hash table usage. + * Larger values improve compression speed. + * Deviating far from default value will likely result in a compression ratio decrease. + * Special: value 0 means "automatically determine hashRateLog". */ + + /* frame parameters */ + ZSTD_c_contentSizeFlag=200, /* Content size will be written into frame header _whenever known_ (default:1) + * Content size must be known at the beginning of compression. + * This is automatically the case when using ZSTD_compress2(), + * For streaming scenarios, content size must be provided with ZSTD_CCtx_setPledgedSrcSize() */ + ZSTD_c_checksumFlag=201, /* A 32-bits checksum of content is written at end of frame (default:0) */ + ZSTD_c_dictIDFlag=202, /* When applicable, dictionary's ID is written into frame header (default:1) */ + + /* multi-threading parameters */ + /* These parameters are only active if multi-threading is enabled (compiled with build macro ZSTD_MULTITHREAD). + * Otherwise, trying to set any other value than default (0) will be a no-op and return an error. + * In a situation where it's unknown if the linked library supports multi-threading or not, + * setting ZSTD_c_nbWorkers to any value >= 1 and consulting the return value provides a quick way to check this property. + */ + ZSTD_c_nbWorkers=400, /* Select how many threads will be spawned to compress in parallel. + * When nbWorkers >= 1, triggers asynchronous mode when invoking ZSTD_compressStream*() : + * ZSTD_compressStream*() consumes input and flush output if possible, but immediately gives back control to caller, + * while compression is performed in parallel, within worker thread(s). + * (note : a strong exception to this rule is when first invocation of ZSTD_compressStream2() sets ZSTD_e_end : + * in which case, ZSTD_compressStream2() delegates to ZSTD_compress2(), which is always a blocking call). + * More workers improve speed, but also increase memory usage. + * Default value is `0`, aka "single-threaded mode" : no worker is spawned, + * compression is performed inside Caller's thread, and all invocations are blocking */ + ZSTD_c_jobSize=401, /* Size of a compression job. This value is enforced only when nbWorkers >= 1. + * Each compression job is completed in parallel, so this value can indirectly impact the nb of active threads. + * 0 means default, which is dynamically determined based on compression parameters. + * Job size must be a minimum of overlap size, or ZSTDMT_JOBSIZE_MIN (= 512 KB), whichever is largest. + * The minimum size is automatically and transparently enforced. */ + ZSTD_c_overlapLog=402, /* Control the overlap size, as a fraction of window size. + * The overlap size is an amount of data reloaded from previous job at the beginning of a new job. + * It helps preserve compression ratio, while each job is compressed in parallel. + * This value is enforced only when nbWorkers >= 1. + * Larger values increase compression ratio, but decrease speed. + * Possible values range from 0 to 9 : + * - 0 means "default" : value will be determined by the library, depending on strategy + * - 1 means "no overlap" + * - 9 means "full overlap", using a full window size. + * Each intermediate rank increases/decreases load size by a factor 2 : + * 9: full window; 8: w/2; 7: w/4; 6: w/8; 5:w/16; 4: w/32; 3:w/64; 2:w/128; 1:no overlap; 0:default + * default value varies between 6 and 9, depending on strategy */ + + /* note : additional experimental parameters are also available + * within the experimental section of the API. + * At the time of this writing, they include : + * ZSTD_c_rsyncable + * ZSTD_c_format + * ZSTD_c_forceMaxWindow + * ZSTD_c_forceAttachDict + * ZSTD_c_literalCompressionMode + * ZSTD_c_srcSizeHint + * ZSTD_c_enableDedicatedDictSearch + * ZSTD_c_stableInBuffer + * ZSTD_c_stableOutBuffer + * ZSTD_c_blockDelimiters + * ZSTD_c_validateSequences + * ZSTD_c_blockSplitterLevel + * ZSTD_c_splitAfterSequences + * ZSTD_c_useRowMatchFinder + * ZSTD_c_prefetchCDictTables + * ZSTD_c_enableSeqProducerFallback + * ZSTD_c_maxBlockSize + * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them. + * note : never ever use experimentalParam? names directly; + * also, the enums values themselves are unstable and can still change. + */ + ZSTD_c_experimentalParam1=500, + ZSTD_c_experimentalParam2=10, + ZSTD_c_experimentalParam3=1000, + ZSTD_c_experimentalParam4=1001, + ZSTD_c_experimentalParam5=1002, + /* was ZSTD_c_experimentalParam6=1003; is now ZSTD_c_targetCBlockSize */ + ZSTD_c_experimentalParam7=1004, + ZSTD_c_experimentalParam8=1005, + ZSTD_c_experimentalParam9=1006, + ZSTD_c_experimentalParam10=1007, + ZSTD_c_experimentalParam11=1008, + ZSTD_c_experimentalParam12=1009, + ZSTD_c_experimentalParam13=1010, + ZSTD_c_experimentalParam14=1011, + ZSTD_c_experimentalParam15=1012, + ZSTD_c_experimentalParam16=1013, + ZSTD_c_experimentalParam17=1014, + ZSTD_c_experimentalParam18=1015, + ZSTD_c_experimentalParam19=1016, + ZSTD_c_experimentalParam20=1017 +} ZSTD_cParameter; + +typedef struct { + size_t error; + int lowerBound; + int upperBound; +} ZSTD_bounds; + +/*! ZSTD_cParam_getBounds() : + * All parameters must belong to an interval with lower and upper bounds, + * otherwise they will either trigger an error or be automatically clamped. + * @return : a structure, ZSTD_bounds, which contains + * - an error status field, which must be tested using ZSTD_isError() + * - lower and upper bounds, both inclusive + */ +ZSTDLIB_API ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter cParam); + +/*! ZSTD_CCtx_setParameter() : + * Set one compression parameter, selected by enum ZSTD_cParameter. + * All parameters have valid bounds. Bounds can be queried using ZSTD_cParam_getBounds(). + * Providing a value beyond bound will either clamp it, or trigger an error (depending on parameter). + * Setting a parameter is generally only possible during frame initialization (before starting compression). + * Exception : when using multi-threading mode (nbWorkers >= 1), + * the following parameters can be updated _during_ compression (within same frame): + * => compressionLevel, hashLog, chainLog, searchLog, minMatch, targetLength and strategy. + * new parameters will be active for next job only (after a flush()). + * @return : an error code (which can be tested using ZSTD_isError()). + */ +ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value); + +/*! ZSTD_CCtx_setPledgedSrcSize() : + * Total input data size to be compressed as a single frame. + * Value will be written in frame header, unless if explicitly forbidden using ZSTD_c_contentSizeFlag. + * This value will also be controlled at end of frame, and trigger an error if not respected. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Note 1 : pledgedSrcSize==0 actually means zero, aka an empty frame. + * In order to mean "unknown content size", pass constant ZSTD_CONTENTSIZE_UNKNOWN. + * ZSTD_CONTENTSIZE_UNKNOWN is default value for any new frame. + * Note 2 : pledgedSrcSize is only valid once, for the next frame. + * It's discarded at the end of the frame, and replaced by ZSTD_CONTENTSIZE_UNKNOWN. + * Note 3 : Whenever all input data is provided and consumed in a single round, + * for example with ZSTD_compress2(), + * or invoking immediately ZSTD_compressStream2(,,,ZSTD_e_end), + * this value is automatically overridden by srcSize instead. + */ +ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize); + +typedef enum { + ZSTD_reset_session_only = 1, + ZSTD_reset_parameters = 2, + ZSTD_reset_session_and_parameters = 3 +} ZSTD_ResetDirective; + +/*! ZSTD_CCtx_reset() : + * There are 2 different things that can be reset, independently or jointly : + * - The session : will stop compressing current frame, and make CCtx ready to start a new one. + * Useful after an error, or to interrupt any ongoing compression. + * Any internal data not yet flushed is cancelled. + * Compression parameters and dictionary remain unchanged. + * They will be used to compress next frame. + * Resetting session never fails. + * - The parameters : changes all parameters back to "default". + * This also removes any reference to any dictionary or external sequence producer. + * Parameters can only be changed between 2 sessions (i.e. no compression is currently ongoing) + * otherwise the reset fails, and function returns an error value (which can be tested using ZSTD_isError()) + * - Both : similar to resetting the session, followed by resetting parameters. + */ +ZSTDLIB_API size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset); + + +/*********************************************** +* Advanced decompression API (Requires v1.4.0+) +************************************************/ + +/* The advanced API pushes parameters one by one into an existing DCtx context. + * Parameters are sticky, and remain valid for all following frames + * using the same DCtx context. + * It's possible to reset parameters to default values using ZSTD_DCtx_reset(). + * Note : This API is compatible with existing ZSTD_decompressDCtx() and ZSTD_decompressStream(). + * Therefore, no new decompression function is necessary. + */ + +typedef enum { + + ZSTD_d_windowLogMax=100, /* Select a size limit (in power of 2) beyond which + * the streaming API will refuse to allocate memory buffer + * in order to protect the host from unreasonable memory requirements. + * This parameter is only useful in streaming mode, since no internal buffer is allocated in single-pass mode. + * By default, a decompression context accepts window sizes <= (1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT). + * Special: value 0 means "use default maximum windowLog". */ + + /* note : additional experimental parameters are also available + * within the experimental section of the API. + * At the time of this writing, they include : + * ZSTD_d_format + * ZSTD_d_stableOutBuffer + * ZSTD_d_forceIgnoreChecksum + * ZSTD_d_refMultipleDDicts + * ZSTD_d_disableHuffmanAssembly + * ZSTD_d_maxBlockSize + * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them. + * note : never ever use experimentalParam? names directly + */ + ZSTD_d_experimentalParam1=1000, + ZSTD_d_experimentalParam2=1001, + ZSTD_d_experimentalParam3=1002, + ZSTD_d_experimentalParam4=1003, + ZSTD_d_experimentalParam5=1004, + ZSTD_d_experimentalParam6=1005 + +} ZSTD_dParameter; + +/*! ZSTD_dParam_getBounds() : + * All parameters must belong to an interval with lower and upper bounds, + * otherwise they will either trigger an error or be automatically clamped. + * @return : a structure, ZSTD_bounds, which contains + * - an error status field, which must be tested using ZSTD_isError() + * - both lower and upper bounds, inclusive + */ +ZSTDLIB_API ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam); + +/*! ZSTD_DCtx_setParameter() : + * Set one compression parameter, selected by enum ZSTD_dParameter. + * All parameters have valid bounds. Bounds can be queried using ZSTD_dParam_getBounds(). + * Providing a value beyond bound will either clamp it, or trigger an error (depending on parameter). + * Setting a parameter is only possible during frame initialization (before starting decompression). + * @return : 0, or an error code (which can be tested using ZSTD_isError()). + */ +ZSTDLIB_API size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int value); + +/*! ZSTD_DCtx_reset() : + * Return a DCtx to clean state. + * Session and parameters can be reset jointly or separately. + * Parameters can only be reset when no active frame is being decompressed. + * @return : 0, or an error code, which can be tested with ZSTD_isError() + */ +ZSTDLIB_API size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset); + + +/**************************** +* Streaming +****************************/ + +typedef struct ZSTD_inBuffer_s { + const void* src; /**< start of input buffer */ + size_t size; /**< size of input buffer */ + size_t pos; /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */ +} ZSTD_inBuffer; + +typedef struct ZSTD_outBuffer_s { + void* dst; /**< start of output buffer */ + size_t size; /**< size of output buffer */ + size_t pos; /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */ +} ZSTD_outBuffer; + +/************************** +* Simple dictionary API +***************************/ +/*! ZSTD_compress_usingDict() : + * Compression at an explicit compression level using a Dictionary. + * A dictionary can be any arbitrary data segment (also called a prefix), + * or a buffer with specified information (see zdict.h). + * Note : This function loads the dictionary, resulting in significant startup delay. + * It's intended for a dictionary used only once. + * Note 2 : When `dict == NULL || dictSize < 8` no dictionary is used. */ +ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + int compressionLevel); + +/*! ZSTD_decompress_usingDict() : + * Decompression using a known Dictionary. + * Dictionary must be identical to the one used during compression. + * Note : This function loads the dictionary, resulting in significant startup delay. + * It's intended for a dictionary used only once. + * Note : When `dict == NULL || dictSize < 8` no dictionary is used. */ +ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize); + + +/*********************************** + * Bulk processing dictionary API + **********************************/ +typedef struct ZSTD_CDict_s ZSTD_CDict; + +/*! ZSTD_createCDict() : + * When compressing multiple messages or blocks using the same dictionary, + * it's recommended to digest the dictionary only once, since it's a costly operation. + * ZSTD_createCDict() will create a state from digesting a dictionary. + * The resulting state can be used for future compression operations with very limited startup cost. + * ZSTD_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only. + * @dictBuffer can be released after ZSTD_CDict creation, because its content is copied within CDict. + * Note 1 : Consider experimental function `ZSTD_createCDict_byReference()` if you prefer to not duplicate @dictBuffer content. + * Note 2 : A ZSTD_CDict can be created from an empty @dictBuffer, + * in which case the only thing that it transports is the @compressionLevel. + * This can be useful in a pipeline featuring ZSTD_compress_usingCDict() exclusively, + * expecting a ZSTD_CDict parameter with any data, including those without a known dictionary. */ +ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize, + int compressionLevel); + +/*! ZSTD_freeCDict() : + * Function frees memory allocated by ZSTD_createCDict(). + * If a NULL pointer is passed, no operation is performed. */ +ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict); + +/*! ZSTD_compress_usingCDict() : + * Compression using a digested Dictionary. + * Recommended when same dictionary is used multiple times. + * Note : compression level is _decided at dictionary creation time_, + * and frame parameters are hardcoded (dictID=yes, contentSize=yes, checksum=no) */ +ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict); + + +typedef struct ZSTD_DDict_s ZSTD_DDict; + +/*! ZSTD_createDDict() : + * Create a digested dictionary, ready to start decompression operation without startup delay. + * dictBuffer can be released after DDict creation, as its content is copied inside DDict. */ +ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dictBuffer, size_t dictSize); + +/*! ZSTD_freeDDict() : + * Function frees memory allocated with ZSTD_createDDict() + * If a NULL pointer is passed, no operation is performed. */ +ZSTDLIB_API size_t ZSTD_freeDDict(ZSTD_DDict* ddict); + +/*! ZSTD_decompress_usingDDict() : + * Decompression using a digested Dictionary. + * Recommended when same dictionary is used multiple times. */ +ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_DDict* ddict); + + +/******************************** + * Dictionary helper functions + *******************************/ + +/*! ZSTD_getDictID_fromDict() : Requires v1.4.0+ + * Provides the dictID stored within dictionary. + * if @return == 0, the dictionary is not conformant with Zstandard specification. + * It can still be loaded, but as a content-only dictionary. */ +ZSTDLIB_API unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize); + +/*! ZSTD_getDictID_fromCDict() : Requires v1.5.0+ + * Provides the dictID of the dictionary loaded into `cdict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +ZSTDLIB_API unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict); + +/*! ZSTD_getDictID_fromDDict() : Requires v1.4.0+ + * Provides the dictID of the dictionary loaded into `ddict`. + * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. + * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */ +ZSTDLIB_API unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict); + +/*! ZSTD_getDictID_fromFrame() : Requires v1.4.0+ + * Provides the dictID required to decompressed the frame stored within `src`. + * If @return == 0, the dictID could not be decoded. + * This could for one of the following reasons : + * - The frame does not require a dictionary to be decoded (most common case). + * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden piece of information. + * Note : this use case also happens when using a non-conformant dictionary. + * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`). + * - This is not a Zstandard frame. + * When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code. */ +ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize); + + +/******************************************************************************* + * Advanced dictionary and prefix API (Requires v1.4.0+) + * + * This API allows dictionaries to be used with ZSTD_compress2(), + * ZSTD_compressStream2(), and ZSTD_decompressDCtx(). + * Dictionaries are sticky, they remain valid when same context is reused, + * they only reset when the context is reset + * with ZSTD_reset_parameters or ZSTD_reset_session_and_parameters. + * In contrast, Prefixes are single-use. + ******************************************************************************/ + + +/*! ZSTD_CCtx_loadDictionary() : Requires v1.4.0+ + * Create an internal CDict from `dict` buffer. + * Decompression will have to use same dictionary. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special: Loading a NULL (or 0-size) dictionary invalidates previous dictionary, + * meaning "return to no-dictionary mode". + * Note 1 : Dictionary is sticky, it will be used for all future compressed frames, + * until parameters are reset, a new dictionary is loaded, or the dictionary + * is explicitly invalidated by loading a NULL dictionary. + * Note 2 : Loading a dictionary involves building tables. + * It's also a CPU consuming operation, with non-negligible impact on latency. + * Tables are dependent on compression parameters, and for this reason, + * compression parameters can no longer be changed after loading a dictionary. + * Note 3 :`dict` content will be copied internally. + * Use experimental ZSTD_CCtx_loadDictionary_byReference() to reference content instead. + * In such a case, dictionary buffer must outlive its users. + * Note 4 : Use ZSTD_CCtx_loadDictionary_advanced() + * to precisely select how dictionary content must be interpreted. + * Note 5 : This method does not benefit from LDM (long distance mode). + * If you want to employ LDM on some large dictionary content, + * prefer employing ZSTD_CCtx_refPrefix() described below. + */ +ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); + +/*! ZSTD_CCtx_refCDict() : Requires v1.4.0+ + * Reference a prepared dictionary, to be used for all future compressed frames. + * Note that compression parameters are enforced from within CDict, + * and supersede any compression parameter previously set within CCtx. + * The parameters ignored are labelled as "superseded-by-cdict" in the ZSTD_cParameter enum docs. + * The ignored parameters will be used again if the CCtx is returned to no-dictionary mode. + * The dictionary will remain valid for future compressed frames using same CCtx. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special : Referencing a NULL CDict means "return to no-dictionary mode". + * Note 1 : Currently, only one dictionary can be managed. + * Referencing a new dictionary effectively "discards" any previous one. + * Note 2 : CDict is just referenced, its lifetime must outlive its usage within CCtx. */ +ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); + +/*! ZSTD_CCtx_refPrefix() : Requires v1.4.0+ + * Reference a prefix (single-usage dictionary) for next compressed frame. + * A prefix is **only used once**. Tables are discarded at end of frame (ZSTD_e_end). + * Decompression will need same prefix to properly regenerate data. + * Compressing with a prefix is similar in outcome as performing a diff and compressing it, + * but performs much faster, especially during decompression (compression speed is tunable with compression level). + * This method is compatible with LDM (long distance mode). + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special: Adding any prefix (including NULL) invalidates any previous prefix or dictionary + * Note 1 : Prefix buffer is referenced. It **must** outlive compression. + * Its content must remain unmodified during compression. + * Note 2 : If the intention is to diff some large src data blob with some prior version of itself, + * ensure that the window size is large enough to contain the entire source. + * See ZSTD_c_windowLog. + * Note 3 : Referencing a prefix involves building tables, which are dependent on compression parameters. + * It's a CPU consuming operation, with non-negligible impact on latency. + * If there is a need to use the same prefix multiple times, consider loadDictionary instead. + * Note 4 : By default, the prefix is interpreted as raw content (ZSTD_dct_rawContent). + * Use experimental ZSTD_CCtx_refPrefix_advanced() to alter dictionary interpretation. */ +ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, + const void* prefix, size_t prefixSize); + +/*! ZSTD_DCtx_loadDictionary() : Requires v1.4.0+ + * Create an internal DDict from dict buffer, to be used to decompress all future frames. + * The dictionary remains valid for all future frames, until explicitly invalidated, or + * a new dictionary is loaded. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary, + * meaning "return to no-dictionary mode". + * Note 1 : Loading a dictionary involves building tables, + * which has a non-negligible impact on CPU usage and latency. + * It's recommended to "load once, use many times", to amortize the cost + * Note 2 :`dict` content will be copied internally, so `dict` can be released after loading. + * Use ZSTD_DCtx_loadDictionary_byReference() to reference dictionary content instead. + * Note 3 : Use ZSTD_DCtx_loadDictionary_advanced() to take control of + * how dictionary content is loaded and interpreted. + */ +ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); + +/*! ZSTD_DCtx_refDDict() : Requires v1.4.0+ + * Reference a prepared dictionary, to be used to decompress next frames. + * The dictionary remains active for decompression of future frames using same DCtx. + * + * If called with ZSTD_d_refMultipleDDicts enabled, repeated calls of this function + * will store the DDict references in a table, and the DDict used for decompression + * will be determined at decompression time, as per the dict ID in the frame. + * The memory for the table is allocated on the first call to refDDict, and can be + * freed with ZSTD_freeDCtx(). + * + * If called with ZSTD_d_refMultipleDDicts disabled (the default), only one dictionary + * will be managed, and referencing a dictionary effectively "discards" any previous one. + * + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Special: referencing a NULL DDict means "return to no-dictionary mode". + * Note 2 : DDict is just referenced, its lifetime must outlive its usage from DCtx. + */ +ZSTDLIB_API size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); + +/*! ZSTD_DCtx_refPrefix() : Requires v1.4.0+ + * Reference a prefix (single-usage dictionary) to decompress next frame. + * This is the reverse operation of ZSTD_CCtx_refPrefix(), + * and must use the same prefix as the one used during compression. + * Prefix is **only used once**. Reference is discarded at end of frame. + * End of frame is reached when ZSTD_decompressStream() returns 0. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + * Note 1 : Adding any prefix (including NULL) invalidates any previously set prefix or dictionary + * Note 2 : Prefix buffer is referenced. It **must** outlive decompression. + * Prefix buffer must remain unmodified up to the end of frame, + * reached when ZSTD_decompressStream() returns 0. + * Note 3 : By default, the prefix is treated as raw content (ZSTD_dct_rawContent). + * Use ZSTD_CCtx_refPrefix_advanced() to alter dictMode (Experimental section) + * Note 4 : Referencing a raw content prefix has almost no cpu nor memory cost. + * A full dictionary is more costly, as it requires building tables. + */ +ZSTDLIB_API size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, + const void* prefix, size_t prefixSize); + +/* === Memory management === */ + +/*! ZSTD_sizeof_*() : Requires v1.4.0+ + * These functions give the _current_ memory usage of selected object. + * Note that object memory usage can evolve (increase or decrease) over time. */ +ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx); +ZSTDLIB_API size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx); +ZSTDLIB_API size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict); +ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_H_235446 */ + + +/* ************************************************************************************** + * ADVANCED AND EXPERIMENTAL FUNCTIONS + **************************************************************************************** + * The definitions in the following section are considered experimental. + * They are provided for advanced scenarios. + * They should never be used with a dynamic library, as prototypes may change in the future. + * Use them only in association with static linking. + * ***************************************************************************************/ + +#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY) +#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY + +#if defined (__cplusplus) +extern "C" { +#endif + +/* This can be overridden externally to hide static symbols. */ +#ifndef ZSTDLIB_STATIC_API +# if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +# define ZSTDLIB_STATIC_API __declspec(dllexport) ZSTDLIB_VISIBLE +# elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZSTDLIB_STATIC_API __declspec(dllimport) ZSTDLIB_VISIBLE +# else +# define ZSTDLIB_STATIC_API ZSTDLIB_VISIBLE +# endif +#endif + +/**************************************************************************************** + * experimental API (static linking only) + **************************************************************************************** + * The following symbols and constants + * are not planned to join "stable API" status in the near future. + * They can still change in future versions. + * Some of them are planned to remain in the static_only section indefinitely. + * Some of them might be removed in the future (especially when redundant with existing stable functions) + * ***************************************************************************************/ + +#define ZSTD_FRAMEHEADERSIZE_PREFIX(format) ((format) == ZSTD_f_zstd1 ? 5 : 1) /* minimum input size required to query frame header size */ +#define ZSTD_FRAMEHEADERSIZE_MIN(format) ((format) == ZSTD_f_zstd1 ? 6 : 2) +#define ZSTD_FRAMEHEADERSIZE_MAX 18 /* can be useful for static allocation */ +#define ZSTD_SKIPPABLEHEADERSIZE 8 + +/* compression parameter bounds */ +#define ZSTD_WINDOWLOG_MAX_32 30 +#define ZSTD_WINDOWLOG_MAX_64 31 +#define ZSTD_WINDOWLOG_MAX ((int)(sizeof(size_t) == 4 ? ZSTD_WINDOWLOG_MAX_32 : ZSTD_WINDOWLOG_MAX_64)) +#define ZSTD_WINDOWLOG_MIN 10 +#define ZSTD_HASHLOG_MAX ((ZSTD_WINDOWLOG_MAX < 30) ? ZSTD_WINDOWLOG_MAX : 30) +#define ZSTD_HASHLOG_MIN 6 +#define ZSTD_CHAINLOG_MAX_32 29 +#define ZSTD_CHAINLOG_MAX_64 30 +#define ZSTD_CHAINLOG_MAX ((int)(sizeof(size_t) == 4 ? ZSTD_CHAINLOG_MAX_32 : ZSTD_CHAINLOG_MAX_64)) +#define ZSTD_CHAINLOG_MIN ZSTD_HASHLOG_MIN +#define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1) +#define ZSTD_SEARCHLOG_MIN 1 +#define ZSTD_MINMATCH_MAX 7 /* only for ZSTD_fast, other strategies are limited to 6 */ +#define ZSTD_MINMATCH_MIN 3 /* only for ZSTD_btopt+, faster strategies are limited to 4 */ +#define ZSTD_TARGETLENGTH_MAX ZSTD_BLOCKSIZE_MAX +#define ZSTD_TARGETLENGTH_MIN 0 /* note : comparing this constant to an unsigned results in a tautological test */ +#define ZSTD_STRATEGY_MIN ZSTD_fast +#define ZSTD_STRATEGY_MAX ZSTD_btultra2 +#define ZSTD_BLOCKSIZE_MAX_MIN (1 << 10) /* The minimum valid max blocksize. Maximum blocksizes smaller than this make compressBound() inaccurate. */ + + +#define ZSTD_OVERLAPLOG_MIN 0 +#define ZSTD_OVERLAPLOG_MAX 9 + +#define ZSTD_WINDOWLOG_LIMIT_DEFAULT 27 /* by default, the streaming decoder will refuse any frame + * requiring larger than (1< 0: + * If litLength != 0: + * rep == 1 --> offset == repeat_offset_1 + * rep == 2 --> offset == repeat_offset_2 + * rep == 3 --> offset == repeat_offset_3 + * If litLength == 0: + * rep == 1 --> offset == repeat_offset_2 + * rep == 2 --> offset == repeat_offset_3 + * rep == 3 --> offset == repeat_offset_1 - 1 + * + * Note: This field is optional. ZSTD_generateSequences() will calculate the value of + * 'rep', but repeat offsets do not necessarily need to be calculated from an external + * sequence provider perspective. For example, ZSTD_compressSequences() does not + * use this 'rep' field at all (as of now). + */ +} ZSTD_Sequence; + +typedef struct { + unsigned windowLog; /**< largest match distance : larger == more compression, more memory needed during decompression */ + unsigned chainLog; /**< fully searched segment : larger == more compression, slower, more memory (useless for fast) */ + unsigned hashLog; /**< dispatch table : larger == faster, more memory */ + unsigned searchLog; /**< nb of searches : larger == more compression, slower */ + unsigned minMatch; /**< match length searched : larger == faster decompression, sometimes less compression */ + unsigned targetLength; /**< acceptable match size for optimal parser (only) : larger == more compression, slower */ + ZSTD_strategy strategy; /**< see ZSTD_strategy definition above */ +} ZSTD_compressionParameters; + +typedef struct { + int contentSizeFlag; /**< 1: content size will be in frame header (when known) */ + int checksumFlag; /**< 1: generate a 32-bits checksum using XXH64 algorithm at end of frame, for error detection */ + int noDictIDFlag; /**< 1: no dictID will be saved into frame header (dictID is only useful for dictionary compression) */ +} ZSTD_frameParameters; + +typedef struct { + ZSTD_compressionParameters cParams; + ZSTD_frameParameters fParams; +} ZSTD_parameters; + +typedef enum { + ZSTD_dct_auto = 0, /* dictionary is "full" when starting with ZSTD_MAGIC_DICTIONARY, otherwise it is "rawContent" */ + ZSTD_dct_rawContent = 1, /* ensures dictionary is always loaded as rawContent, even if it starts with ZSTD_MAGIC_DICTIONARY */ + ZSTD_dct_fullDict = 2 /* refuses to load a dictionary if it does not respect Zstandard's specification, starting with ZSTD_MAGIC_DICTIONARY */ +} ZSTD_dictContentType_e; + +typedef enum { + ZSTD_dlm_byCopy = 0, /**< Copy dictionary content internally */ + ZSTD_dlm_byRef = 1 /**< Reference dictionary content -- the dictionary buffer must outlive its users. */ +} ZSTD_dictLoadMethod_e; + +typedef enum { + ZSTD_f_zstd1 = 0, /* zstd frame format, specified in zstd_compression_format.md (default) */ + ZSTD_f_zstd1_magicless = 1 /* Variant of zstd frame format, without initial 4-bytes magic number. + * Useful to save 4 bytes per generated frame. + * Decoder cannot recognise automatically this format, requiring this instruction. */ +} ZSTD_format_e; + +typedef enum { + /* Note: this enum controls ZSTD_d_forceIgnoreChecksum */ + ZSTD_d_validateChecksum = 0, + ZSTD_d_ignoreChecksum = 1 +} ZSTD_forceIgnoreChecksum_e; + +typedef enum { + /* Note: this enum controls ZSTD_d_refMultipleDDicts */ + ZSTD_rmd_refSingleDDict = 0, + ZSTD_rmd_refMultipleDDicts = 1 +} ZSTD_refMultipleDDicts_e; + +typedef enum { + /* Note: this enum and the behavior it controls are effectively internal + * implementation details of the compressor. They are expected to continue + * to evolve and should be considered only in the context of extremely + * advanced performance tuning. + * + * Zstd currently supports the use of a CDict in three ways: + * + * - The contents of the CDict can be copied into the working context. This + * means that the compression can search both the dictionary and input + * while operating on a single set of internal tables. This makes + * the compression faster per-byte of input. However, the initial copy of + * the CDict's tables incurs a fixed cost at the beginning of the + * compression. For small compressions (< 8 KB), that copy can dominate + * the cost of the compression. + * + * - The CDict's tables can be used in-place. In this model, compression is + * slower per input byte, because the compressor has to search two sets of + * tables. However, this model incurs no start-up cost (as long as the + * working context's tables can be reused). For small inputs, this can be + * faster than copying the CDict's tables. + * + * - The CDict's tables are not used at all, and instead we use the working + * context alone to reload the dictionary and use params based on the source + * size. See ZSTD_compress_insertDictionary() and ZSTD_compress_usingDict(). + * This method is effective when the dictionary sizes are very small relative + * to the input size, and the input size is fairly large to begin with. + * + * Zstd has a simple internal heuristic that selects which strategy to use + * at the beginning of a compression. However, if experimentation shows that + * Zstd is making poor choices, it is possible to override that choice with + * this enum. + */ + ZSTD_dictDefaultAttach = 0, /* Use the default heuristic. */ + ZSTD_dictForceAttach = 1, /* Never copy the dictionary. */ + ZSTD_dictForceCopy = 2, /* Always copy the dictionary. */ + ZSTD_dictForceLoad = 3 /* Always reload the dictionary */ +} ZSTD_dictAttachPref_e; + +typedef enum { + ZSTD_lcm_auto = 0, /**< Automatically determine the compression mode based on the compression level. + * Negative compression levels will be uncompressed, and positive compression + * levels will be compressed. */ + ZSTD_lcm_huffman = 1, /**< Always attempt Huffman compression. Uncompressed literals will still be + * emitted if Huffman compression is not profitable. */ + ZSTD_lcm_uncompressed = 2 /**< Always emit uncompressed literals. */ +} ZSTD_literalCompressionMode_e; + +typedef enum { + /* Note: This enum controls features which are conditionally beneficial. + * Zstd can take a decision on whether or not to enable the feature (ZSTD_ps_auto), + * but setting the switch to ZSTD_ps_enable or ZSTD_ps_disable force enable/disable the feature. + */ + ZSTD_ps_auto = 0, /* Let the library automatically determine whether the feature shall be enabled */ + ZSTD_ps_enable = 1, /* Force-enable the feature */ + ZSTD_ps_disable = 2 /* Do not use the feature */ +} ZSTD_ParamSwitch_e; +#define ZSTD_paramSwitch_e ZSTD_ParamSwitch_e /* old name */ + +/*************************************** +* Frame header and size functions +***************************************/ + +/*! ZSTD_frameHeaderSize() : + * srcSize must be large enough, aka >= ZSTD_FRAMEHEADERSIZE_PREFIX. + * @return : size of the Frame Header, + * or an error code (if srcSize is too small) */ +ZSTDLIB_STATIC_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize); + +typedef enum { ZSTD_frame, ZSTD_skippableFrame } ZSTD_FrameType_e; +#define ZSTD_frameType_e ZSTD_FrameType_e /* old name */ +typedef struct { + unsigned long long frameContentSize; /* if == ZSTD_CONTENTSIZE_UNKNOWN, it means this field is not available. 0 means "empty" */ + unsigned long long windowSize; /* can be very large, up to <= frameContentSize */ + unsigned blockSizeMax; + ZSTD_FrameType_e frameType; /* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */ + unsigned headerSize; + unsigned dictID; /* for ZSTD_skippableFrame, contains the skippable magic variant [0-15] */ + unsigned checksumFlag; + unsigned _reserved1; + unsigned _reserved2; +} ZSTD_FrameHeader; +#define ZSTD_frameHeader ZSTD_FrameHeader /* old name */ + +/*! ZSTD_getFrameHeader() : + * decode Frame Header into `zfhPtr`, or requires larger `srcSize`. + * @return : 0 => header is complete, `zfhPtr` is correctly filled, + * >0 => `srcSize` is too small, @return value is the wanted `srcSize` amount, `zfhPtr` is not filled, + * or an error code, which can be tested using ZSTD_isError() */ +ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize); +/*! ZSTD_getFrameHeader_advanced() : + * same as ZSTD_getFrameHeader(), + * with added capability to select a format (like ZSTD_f_zstd1_magicless) */ +ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format); + +/*! ZSTD_DECOMPRESS_MARGIN() : + * Similar to ZSTD_decompressionMargin(), but instead of computing the margin from + * the compressed frame, compute it from the original size and the blockSizeLog. + * See ZSTD_decompressionMargin() for details. + * + * WARNING: This macro does not support multi-frame input, the input must be a single + * zstd frame. If you need that support use the function, or implement it yourself. + * + * @param originalSize The original uncompressed size of the data. + * @param blockSize The block size == MIN(windowSize, ZSTD_BLOCKSIZE_MAX). + * Unless you explicitly set the windowLog smaller than + * ZSTD_BLOCKSIZELOG_MAX you can just use ZSTD_BLOCKSIZE_MAX. + */ +#define ZSTD_DECOMPRESSION_MARGIN(originalSize, blockSize) ((size_t)( \ + ZSTD_FRAMEHEADERSIZE_MAX /* Frame header */ + \ + 4 /* checksum */ + \ + ((originalSize) == 0 ? 0 : 3 * (((originalSize) + (blockSize) - 1) / blockSize)) /* 3 bytes per block */ + \ + (blockSize) /* One block of margin */ \ + )) + +typedef enum { + ZSTD_sf_noBlockDelimiters = 0, /* ZSTD_Sequence[] has no block delimiters, just sequences */ + ZSTD_sf_explicitBlockDelimiters = 1 /* ZSTD_Sequence[] contains explicit block delimiters */ +} ZSTD_SequenceFormat_e; +#define ZSTD_sequenceFormat_e ZSTD_SequenceFormat_e /* old name */ + +/*! ZSTD_sequenceBound() : + * `srcSize` : size of the input buffer + * @return : upper-bound for the number of sequences that can be generated + * from a buffer of srcSize bytes + * + * note : returns number of sequences - to get bytes, multiply by sizeof(ZSTD_Sequence). + */ +ZSTDLIB_STATIC_API size_t ZSTD_sequenceBound(size_t srcSize); + +/*! ZSTD_generateSequences() : + * WARNING: This function is meant for debugging and informational purposes ONLY! + * Its implementation is flawed, and it will be deleted in a future version. + * It is not guaranteed to succeed, as there are several cases where it will give + * up and fail. You should NOT use this function in production code. + * + * This function is deprecated, and will be removed in a future version. + * + * Generate sequences using ZSTD_compress2(), given a source buffer. + * + * @param zc The compression context to be used for ZSTD_compress2(). Set any + * compression parameters you need on this context. + * @param outSeqs The output sequences buffer of size @p outSeqsSize + * @param outSeqsCapacity The size of the output sequences buffer. + * ZSTD_sequenceBound(srcSize) is an upper bound on the number + * of sequences that can be generated. + * @param src The source buffer to generate sequences from of size @p srcSize. + * @param srcSize The size of the source buffer. + * + * Each block will end with a dummy sequence + * with offset == 0, matchLength == 0, and litLength == length of last literals. + * litLength may be == 0, and if so, then the sequence of (of: 0 ml: 0 ll: 0) + * simply acts as a block delimiter. + * + * @returns The number of sequences generated, necessarily less than + * ZSTD_sequenceBound(srcSize), or an error code that can be checked + * with ZSTD_isError(). + */ +ZSTD_DEPRECATED("For debugging only, will be replaced by ZSTD_extractSequences()") +ZSTDLIB_STATIC_API size_t +ZSTD_generateSequences(ZSTD_CCtx* zc, + ZSTD_Sequence* outSeqs, size_t outSeqsCapacity, + const void* src, size_t srcSize); + +/*! ZSTD_mergeBlockDelimiters() : + * Given an array of ZSTD_Sequence, remove all sequences that represent block delimiters/last literals + * by merging them into the literals of the next sequence. + * + * As such, the final generated result has no explicit representation of block boundaries, + * and the final last literals segment is not represented in the sequences. + * + * The output of this function can be fed into ZSTD_compressSequences() with CCtx + * setting of ZSTD_c_blockDelimiters as ZSTD_sf_noBlockDelimiters + * @return : number of sequences left after merging + */ +ZSTDLIB_STATIC_API size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize); + +/*! ZSTD_compressSequences() : + * Compress an array of ZSTD_Sequence, associated with @src buffer, into dst. + * @src contains the entire input (not just the literals). + * If @srcSize > sum(sequence.length), the remaining bytes are considered all literals + * If a dictionary is included, then the cctx should reference the dict (see: ZSTD_CCtx_refCDict(), ZSTD_CCtx_loadDictionary(), etc.). + * The entire source is compressed into a single frame. + * + * The compression behavior changes based on cctx params. In particular: + * If ZSTD_c_blockDelimiters == ZSTD_sf_noBlockDelimiters, the array of ZSTD_Sequence is expected to contain + * no block delimiters (defined in ZSTD_Sequence). Block boundaries are roughly determined based on + * the block size derived from the cctx, and sequences may be split. This is the default setting. + * + * If ZSTD_c_blockDelimiters == ZSTD_sf_explicitBlockDelimiters, the array of ZSTD_Sequence is expected to contain + * valid block delimiters (defined in ZSTD_Sequence). Behavior is undefined if no block delimiters are provided. + * + * When ZSTD_c_blockDelimiters == ZSTD_sf_explicitBlockDelimiters, it's possible to decide generating repcodes + * using the advanced parameter ZSTD_c_repcodeResolution. Repcodes will improve compression ratio, though the benefit + * can vary greatly depending on Sequences. On the other hand, repcode resolution is an expensive operation. + * By default, it's disabled at low (<10) compression levels, and enabled above the threshold (>=10). + * ZSTD_c_repcodeResolution makes it possible to directly manage this processing in either direction. + * + * If ZSTD_c_validateSequences == 0, this function blindly accepts the Sequences provided. Invalid Sequences cause undefined + * behavior. If ZSTD_c_validateSequences == 1, then the function will detect invalid Sequences (see doc/zstd_compression_format.md for + * specifics regarding offset/matchlength requirements) and then bail out and return an error. + * + * In addition to the two adjustable experimental params, there are other important cctx params. + * - ZSTD_c_minMatch MUST be set as less than or equal to the smallest match generated by the match finder. It has a minimum value of ZSTD_MINMATCH_MIN. + * - ZSTD_c_compressionLevel accordingly adjusts the strength of the entropy coder, as it would in typical compression. + * - ZSTD_c_windowLog affects offset validation: this function will return an error at higher debug levels if a provided offset + * is larger than what the spec allows for a given window log and dictionary (if present). See: doc/zstd_compression_format.md + * + * Note: Repcodes are, as of now, always re-calculated within this function, ZSTD_Sequence.rep is effectively unused. + * Dev Note: Once ability to ingest repcodes become available, the explicit block delims mode must respect those repcodes exactly, + * and cannot emit an RLE block that disagrees with the repcode history. + * @return : final compressed size, or a ZSTD error code. + */ +ZSTDLIB_STATIC_API size_t +ZSTD_compressSequences(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const ZSTD_Sequence* inSeqs, size_t inSeqsSize, + const void* src, size_t srcSize); + + +/*! ZSTD_compressSequencesAndLiterals() : + * This is a variant of ZSTD_compressSequences() which, + * instead of receiving (src,srcSize) as input parameter, receives (literals,litSize), + * aka all the literals, already extracted and laid out into a single continuous buffer. + * This can be useful if the process generating the sequences also happens to generate the buffer of literals, + * thus skipping an extraction + caching stage. + * It's a speed optimization, useful when the right conditions are met, + * but it also features the following limitations: + * - Only supports explicit delimiter mode + * - Currently does not support Sequences validation (so input Sequences are trusted) + * - Not compatible with frame checksum, which must be disabled + * - If any block is incompressible, will fail and return an error + * - @litSize must be == sum of all @.litLength fields in @inSeqs. Any discrepancy will generate an error. + * - @litBufCapacity is the size of the underlying buffer into which literals are written, starting at address @literals. + * @litBufCapacity must be at least 8 bytes larger than @litSize. + * - @decompressedSize must be correct, and correspond to the sum of all Sequences. Any discrepancy will generate an error. + * @return : final compressed size, or a ZSTD error code. + */ +ZSTDLIB_STATIC_API size_t +ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const ZSTD_Sequence* inSeqs, size_t nbSequences, + const void* literals, size_t litSize, size_t litBufCapacity, + size_t decompressedSize); + + +/*! ZSTD_writeSkippableFrame() : + * Generates a zstd skippable frame containing data given by src, and writes it to dst buffer. + * + * Skippable frames begin with a 4-byte magic number. There are 16 possible choices of magic number, + * ranging from ZSTD_MAGIC_SKIPPABLE_START to ZSTD_MAGIC_SKIPPABLE_START+15. + * As such, the parameter magicVariant controls the exact skippable frame magic number variant used, + * so the magic number used will be ZSTD_MAGIC_SKIPPABLE_START + magicVariant. + * + * Returns an error if destination buffer is not large enough, if the source size is not representable + * with a 4-byte unsigned int, or if the parameter magicVariant is greater than 15 (and therefore invalid). + * + * @return : number of bytes written or a ZSTD error. + */ +ZSTDLIB_STATIC_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + unsigned magicVariant); + +/*! ZSTD_isSkippableFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame. + */ +ZSTDLIB_STATIC_API unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size); + + + +/*************************************** +* Memory management +***************************************/ + +/*! ZSTD_estimate*() : + * These functions make it possible to estimate memory usage + * of a future {D,C}Ctx, before its creation. + * This is useful in combination with ZSTD_initStatic(), + * which makes it possible to employ a static buffer for ZSTD_CCtx* state. + * + * ZSTD_estimateCCtxSize() will provide a memory budget large enough + * to compress data of any size using one-shot compression ZSTD_compressCCtx() or ZSTD_compress2() + * associated with any compression level up to max specified one. + * The estimate will assume the input may be arbitrarily large, + * which is the worst case. + * + * Note that the size estimation is specific for one-shot compression, + * it is not valid for streaming (see ZSTD_estimateCStreamSize*()) + * nor other potential ways of using a ZSTD_CCtx* state. + * + * When srcSize can be bound by a known and rather "small" value, + * this knowledge can be used to provide a tighter budget estimation + * because the ZSTD_CCtx* state will need less memory for small inputs. + * This tighter estimation can be provided by employing more advanced functions + * ZSTD_estimateCCtxSize_usingCParams(), which can be used in tandem with ZSTD_getCParams(), + * and ZSTD_estimateCCtxSize_usingCCtxParams(), which can be used in tandem with ZSTD_CCtxParams_setParameter(). + * Both can be used to estimate memory using custom compression parameters and arbitrary srcSize limits. + * + * Note : only single-threaded compression is supported. + * ZSTD_estimateCCtxSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1. + */ +ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize(int maxCompressionLevel); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params); +ZSTDLIB_STATIC_API size_t ZSTD_estimateDCtxSize(void); + +/*! ZSTD_estimate?DictSize() : + * ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict(). + * ZSTD_estimateCDictSize_advanced() makes it possible to control compression parameters precisely, like ZSTD_createCDict_advanced(). + * Note : dictionaries created by reference (`ZSTD_dlm_byRef`) are logically smaller. + */ +ZSTDLIB_STATIC_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel); +ZSTDLIB_STATIC_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod); +ZSTDLIB_STATIC_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod); + +/*! ZSTD_initStatic*() : + * Initialize an object using a pre-allocated fixed-size buffer. + * workspace: The memory area to emplace the object into. + * Provided pointer *must be 8-bytes aligned*. + * Buffer must outlive object. + * workspaceSize: Use ZSTD_estimate*Size() to determine + * how large workspace must be to support target scenario. + * @return : pointer to object (same address as workspace, just different type), + * or NULL if error (size too small, incorrect alignment, etc.) + * Note : zstd will never resize nor malloc() when using a static buffer. + * If the object requires more memory than available, + * zstd will just error out (typically ZSTD_error_memory_allocation). + * Note 2 : there is no corresponding "free" function. + * Since workspace is allocated externally, it must be freed externally too. + * Note 3 : cParams : use ZSTD_getCParams() to convert a compression level + * into its associated cParams. + * Limitation 1 : currently not compatible with internal dictionary creation, triggered by + * ZSTD_CCtx_loadDictionary(), ZSTD_initCStream_usingDict() or ZSTD_initDStream_usingDict(). + * Limitation 2 : static cctx currently not compatible with multi-threading. + * Limitation 3 : static dctx is incompatible with legacy support. + */ +ZSTDLIB_STATIC_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize); + +ZSTDLIB_STATIC_API ZSTD_DCtx* ZSTD_initStaticDCtx(void* workspace, size_t workspaceSize); + +ZSTDLIB_STATIC_API const ZSTD_CDict* ZSTD_initStaticCDict( + void* workspace, size_t workspaceSize, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_compressionParameters cParams); + +ZSTDLIB_STATIC_API const ZSTD_DDict* ZSTD_initStaticDDict( + void* workspace, size_t workspaceSize, + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType); + + +/*! Custom memory allocation : + * These prototypes make it possible to pass your own allocation/free functions. + * ZSTD_customMem is provided at creation time, using ZSTD_create*_advanced() variants listed below. + * All allocation/free operations will be completed using these custom variants instead of regular ones. + */ +typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size); +typedef void (*ZSTD_freeFunction) (void* opaque, void* address); +typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem; +static +#ifdef __GNUC__ +__attribute__((__unused__)) +#endif + +#if defined(__clang__) && __clang_major__ >= 5 +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" +#endif +ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */ +#if defined(__clang__) && __clang_major__ >= 5 +#pragma clang diagnostic pop +#endif + +ZSTDLIB_STATIC_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem); +ZSTDLIB_STATIC_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem); + +ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_compressionParameters cParams, + ZSTD_customMem customMem); + +/*! Thread pool : + * These prototypes make it possible to share a thread pool among multiple compression contexts. + * This can limit resources for applications with multiple threads where each one uses + * a threaded compression mode (via ZSTD_c_nbWorkers parameter). + * ZSTD_createThreadPool creates a new thread pool with a given number of threads. + * Note that the lifetime of such pool must exist while being used. + * ZSTD_CCtx_refThreadPool assigns a thread pool to a context (use NULL argument value + * to use an internal thread pool). + * ZSTD_freeThreadPool frees a thread pool, accepts NULL pointer. + */ +typedef struct POOL_ctx_s ZSTD_threadPool; +ZSTDLIB_STATIC_API ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads); +ZSTDLIB_STATIC_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool); /* accept NULL pointer */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool); + + +/* + * This API is temporary and is expected to change or disappear in the future! + */ +ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_advanced2( + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + const ZSTD_CCtx_params* cctxParams, + ZSTD_customMem customMem); + +ZSTDLIB_STATIC_API ZSTD_DDict* ZSTD_createDDict_advanced( + const void* dict, size_t dictSize, + ZSTD_dictLoadMethod_e dictLoadMethod, + ZSTD_dictContentType_e dictContentType, + ZSTD_customMem customMem); + + +/*************************************** +* Advanced compression functions +***************************************/ + +/*! ZSTD_createCDict_byReference() : + * Create a digested dictionary for compression + * Dictionary content is just referenced, not duplicated. + * As a consequence, `dictBuffer` **must** outlive CDict, + * and its content must remain unmodified throughout the lifetime of CDict. + * note: equivalent to ZSTD_createCDict_advanced(), with dictLoadMethod==ZSTD_dlm_byRef */ +ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel); + +/*! ZSTD_getCParams() : + * @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. + * `estimatedSrcSize` value is optional, select 0 if not known */ +ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); + +/*! ZSTD_getParams() : + * same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`. + * All fields of `ZSTD_frameParameters` are set to default : contentSize=1, checksum=0, noDictID=0 */ +ZSTDLIB_STATIC_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize); + +/*! ZSTD_checkCParams() : + * Ensure param values remain within authorized range. + * @return 0 on success, or an error code (can be checked with ZSTD_isError()) */ +ZSTDLIB_STATIC_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params); + +/*! ZSTD_adjustCParams() : + * optimize params for a given `srcSize` and `dictSize`. + * `srcSize` can be unknown, in which case use ZSTD_CONTENTSIZE_UNKNOWN. + * `dictSize` must be `0` when there is no dictionary. + * cPar can be invalid : all parameters will be clamped within valid range in the @return struct. + * This function never fails (wide contract) */ +ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize); + +/*! ZSTD_CCtx_setCParams() : + * Set all parameters provided within @p cparams into the working @p cctx. + * Note : if modifying parameters during compression (MT mode only), + * note that changes to the .windowLog parameter will be ignored. + * @return 0 on success, or an error code (can be checked with ZSTD_isError()). + * On failure, no parameters are updated. + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams); + +/*! ZSTD_CCtx_setFParams() : + * Set all parameters provided within @p fparams into the working @p cctx. + * @return 0 on success, or an error code (can be checked with ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setFParams(ZSTD_CCtx* cctx, ZSTD_frameParameters fparams); + +/*! ZSTD_CCtx_setParams() : + * Set all parameters provided within @p params into the working @p cctx. + * @return 0 on success, or an error code (can be checked with ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setParams(ZSTD_CCtx* cctx, ZSTD_parameters params); + +/*! ZSTD_compress_advanced() : + * Note : this function is now DEPRECATED. + * It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_setParameter() and other parameter setters. + * This prototype will generate compilation warnings. */ +ZSTD_DEPRECATED("use ZSTD_compress2") +ZSTDLIB_STATIC_API +size_t ZSTD_compress_advanced(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const void* dict,size_t dictSize, + ZSTD_parameters params); + +/*! ZSTD_compress_usingCDict_advanced() : + * Note : this function is now DEPRECATED. + * It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_loadDictionary() and other parameter setters. + * This prototype will generate compilation warnings. */ +ZSTD_DEPRECATED("use ZSTD_compress2 with ZSTD_CCtx_loadDictionary") +ZSTDLIB_STATIC_API +size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict, + ZSTD_frameParameters fParams); + + +/*! ZSTD_CCtx_loadDictionary_byReference() : + * Same as ZSTD_CCtx_loadDictionary(), but dictionary content is referenced, instead of being copied into CCtx. + * It saves some memory, but also requires that `dict` outlives its usage within `cctx` */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); + +/*! ZSTD_CCtx_loadDictionary_advanced() : + * Same as ZSTD_CCtx_loadDictionary(), but gives finer control over + * how to load the dictionary (by copy ? by reference ?) + * and how to interpret it (automatic ? force raw mode ? full mode only ?) */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType); + +/*! ZSTD_CCtx_refPrefix_advanced() : + * Same as ZSTD_CCtx_refPrefix(), but gives finer control over + * how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType); + +/* === experimental parameters === */ +/* these parameters can be used with ZSTD_setParameter() + * they are not guaranteed to remain supported in the future */ + + /* Enables rsyncable mode, + * which makes compressed files more rsync friendly + * by adding periodic synchronization points to the compressed data. + * The target average block size is ZSTD_c_jobSize / 2. + * It's possible to modify the job size to increase or decrease + * the granularity of the synchronization point. + * Once the jobSize is smaller than the window size, + * it will result in compression ratio degradation. + * NOTE 1: rsyncable mode only works when multithreading is enabled. + * NOTE 2: rsyncable performs poorly in combination with long range mode, + * since it will decrease the effectiveness of synchronization points, + * though mileage may vary. + * NOTE 3: Rsyncable mode limits maximum compression speed to ~400 MB/s. + * If the selected compression level is already running significantly slower, + * the overall speed won't be significantly impacted. + */ + #define ZSTD_c_rsyncable ZSTD_c_experimentalParam1 + +/* Select a compression format. + * The value must be of type ZSTD_format_e. + * See ZSTD_format_e enum definition for details */ +#define ZSTD_c_format ZSTD_c_experimentalParam2 + +/* Force back-reference distances to remain < windowSize, + * even when referencing into Dictionary content (default:0) */ +#define ZSTD_c_forceMaxWindow ZSTD_c_experimentalParam3 + +/* Controls whether the contents of a CDict + * are used in place, or copied into the working context. + * Accepts values from the ZSTD_dictAttachPref_e enum. + * See the comments on that enum for an explanation of the feature. */ +#define ZSTD_c_forceAttachDict ZSTD_c_experimentalParam4 + +/* Controlled with ZSTD_ParamSwitch_e enum. + * Default is ZSTD_ps_auto. + * Set to ZSTD_ps_disable to never compress literals. + * Set to ZSTD_ps_enable to always compress literals. (Note: uncompressed literals + * may still be emitted if huffman is not beneficial to use.) + * + * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use + * literals compression based on the compression parameters - specifically, + * negative compression levels do not use literal compression. + */ +#define ZSTD_c_literalCompressionMode ZSTD_c_experimentalParam5 + +/* User's best guess of source size. + * Hint is not valid when srcSizeHint == 0. + * There is no guarantee that hint is close to actual source size, + * but compression ratio may regress significantly if guess considerably underestimates */ +#define ZSTD_c_srcSizeHint ZSTD_c_experimentalParam7 + +/* Controls whether the new and experimental "dedicated dictionary search + * structure" can be used. This feature is still rough around the edges, be + * prepared for surprising behavior! + * + * How to use it: + * + * When using a CDict, whether to use this feature or not is controlled at + * CDict creation, and it must be set in a CCtxParams set passed into that + * construction (via ZSTD_createCDict_advanced2()). A compression will then + * use the feature or not based on how the CDict was constructed; the value of + * this param, set in the CCtx, will have no effect. + * + * However, when a dictionary buffer is passed into a CCtx, such as via + * ZSTD_CCtx_loadDictionary(), this param can be set on the CCtx to control + * whether the CDict that is created internally can use the feature or not. + * + * What it does: + * + * Normally, the internal data structures of the CDict are analogous to what + * would be stored in a CCtx after compressing the contents of a dictionary. + * To an approximation, a compression using a dictionary can then use those + * data structures to simply continue what is effectively a streaming + * compression where the simulated compression of the dictionary left off. + * Which is to say, the search structures in the CDict are normally the same + * format as in the CCtx. + * + * It is possible to do better, since the CDict is not like a CCtx: the search + * structures are written once during CDict creation, and then are only read + * after that, while the search structures in the CCtx are both read and + * written as the compression goes along. This means we can choose a search + * structure for the dictionary that is read-optimized. + * + * This feature enables the use of that different structure. + * + * Note that some of the members of the ZSTD_compressionParameters struct have + * different semantics and constraints in the dedicated search structure. It is + * highly recommended that you simply set a compression level in the CCtxParams + * you pass into the CDict creation call, and avoid messing with the cParams + * directly. + * + * Effects: + * + * This will only have any effect when the selected ZSTD_strategy + * implementation supports this feature. Currently, that's limited to + * ZSTD_greedy, ZSTD_lazy, and ZSTD_lazy2. + * + * Note that this means that the CDict tables can no longer be copied into the + * CCtx, so the dict attachment mode ZSTD_dictForceCopy will no longer be + * usable. The dictionary can only be attached or reloaded. + * + * In general, you should expect compression to be faster--sometimes very much + * so--and CDict creation to be slightly slower. Eventually, we will probably + * make this mode the default. + */ +#define ZSTD_c_enableDedicatedDictSearch ZSTD_c_experimentalParam8 + +/* ZSTD_c_stableInBuffer + * Experimental parameter. + * Default is 0 == disabled. Set to 1 to enable. + * + * Tells the compressor that input data presented with ZSTD_inBuffer + * will ALWAYS be the same between calls. + * Technically, the @src pointer must never be changed, + * and the @pos field can only be updated by zstd. + * However, it's possible to increase the @size field, + * allowing scenarios where more data can be appended after compressions starts. + * These conditions are checked by the compressor, + * and compression will fail if they are not respected. + * Also, data in the ZSTD_inBuffer within the range [src, src + pos) + * MUST not be modified during compression or it will result in data corruption. + * + * When this flag is enabled zstd won't allocate an input window buffer, + * because the user guarantees it can reference the ZSTD_inBuffer until + * the frame is complete. But, it will still allocate an output buffer + * large enough to fit a block (see ZSTD_c_stableOutBuffer). This will also + * avoid the memcpy() from the input buffer to the input window buffer. + * + * NOTE: So long as the ZSTD_inBuffer always points to valid memory, using + * this flag is ALWAYS memory safe, and will never access out-of-bounds + * memory. However, compression WILL fail if conditions are not respected. + * + * WARNING: The data in the ZSTD_inBuffer in the range [src, src + pos) MUST + * not be modified during compression or it will result in data corruption. + * This is because zstd needs to reference data in the ZSTD_inBuffer to find + * matches. Normally zstd maintains its own window buffer for this purpose, + * but passing this flag tells zstd to rely on user provided buffer instead. + */ +#define ZSTD_c_stableInBuffer ZSTD_c_experimentalParam9 + +/* ZSTD_c_stableOutBuffer + * Experimental parameter. + * Default is 0 == disabled. Set to 1 to enable. + * + * Tells he compressor that the ZSTD_outBuffer will not be resized between + * calls. Specifically: (out.size - out.pos) will never grow. This gives the + * compressor the freedom to say: If the compressed data doesn't fit in the + * output buffer then return ZSTD_error_dstSizeTooSmall. This allows us to + * always decompress directly into the output buffer, instead of decompressing + * into an internal buffer and copying to the output buffer. + * + * When this flag is enabled zstd won't allocate an output buffer, because + * it can write directly to the ZSTD_outBuffer. It will still allocate the + * input window buffer (see ZSTD_c_stableInBuffer). + * + * Zstd will check that (out.size - out.pos) never grows and return an error + * if it does. While not strictly necessary, this should prevent surprises. + */ +#define ZSTD_c_stableOutBuffer ZSTD_c_experimentalParam10 + +/* ZSTD_c_blockDelimiters + * Default is 0 == ZSTD_sf_noBlockDelimiters. + * + * For use with sequence compression API: ZSTD_compressSequences(). + * + * Designates whether or not the given array of ZSTD_Sequence contains block delimiters + * and last literals, which are defined as sequences with offset == 0 and matchLength == 0. + * See the definition of ZSTD_Sequence for more specifics. + */ +#define ZSTD_c_blockDelimiters ZSTD_c_experimentalParam11 + +/* ZSTD_c_validateSequences + * Default is 0 == disabled. Set to 1 to enable sequence validation. + * + * For use with sequence compression API: ZSTD_compressSequences*(). + * Designates whether or not provided sequences are validated within ZSTD_compressSequences*() + * during function execution. + * + * When Sequence validation is disabled (default), Sequences are compressed as-is, + * so they must correct, otherwise it would result in a corruption error. + * + * Sequence validation adds some protection, by ensuring that all values respect boundary conditions. + * If a Sequence is detected invalid (see doc/zstd_compression_format.md for + * specifics regarding offset/matchlength requirements) then the function will bail out and + * return an error. + */ +#define ZSTD_c_validateSequences ZSTD_c_experimentalParam12 + +/* ZSTD_c_blockSplitterLevel + * note: this parameter only influences the first splitter stage, + * which is active before producing the sequences. + * ZSTD_c_splitAfterSequences controls the next splitter stage, + * which is active after sequence production. + * Note that both can be combined. + * Allowed values are between 0 and ZSTD_BLOCKSPLITTER_LEVEL_MAX included. + * 0 means "auto", which will select a value depending on current ZSTD_c_strategy. + * 1 means no splitting. + * Then, values from 2 to 6 are sorted in increasing cpu load order. + * + * Note that currently the first block is never split, + * to ensure expansion guarantees in presence of incompressible data. + */ +#define ZSTD_BLOCKSPLITTER_LEVEL_MAX 6 +#define ZSTD_c_blockSplitterLevel ZSTD_c_experimentalParam20 + +/* ZSTD_c_splitAfterSequences + * This is a stronger splitter algorithm, + * based on actual sequences previously produced by the selected parser. + * It's also slower, and as a consequence, mostly used for high compression levels. + * While the post-splitter does overlap with the pre-splitter, + * both can nonetheless be combined, + * notably with ZSTD_c_blockSplitterLevel at ZSTD_BLOCKSPLITTER_LEVEL_MAX, + * resulting in higher compression ratio than just one of them. + * + * Default is ZSTD_ps_auto. + * Set to ZSTD_ps_disable to never use block splitter. + * Set to ZSTD_ps_enable to always use block splitter. + * + * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use + * block splitting based on the compression parameters. + */ +#define ZSTD_c_splitAfterSequences ZSTD_c_experimentalParam13 + +/* ZSTD_c_useRowMatchFinder + * Controlled with ZSTD_ParamSwitch_e enum. + * Default is ZSTD_ps_auto. + * Set to ZSTD_ps_disable to never use row-based matchfinder. + * Set to ZSTD_ps_enable to force usage of row-based matchfinder. + * + * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use + * the row-based matchfinder based on support for SIMD instructions and the window log. + * Note that this only pertains to compression strategies: greedy, lazy, and lazy2 + */ +#define ZSTD_c_useRowMatchFinder ZSTD_c_experimentalParam14 + +/* ZSTD_c_deterministicRefPrefix + * Default is 0 == disabled. Set to 1 to enable. + * + * Zstd produces different results for prefix compression when the prefix is + * directly adjacent to the data about to be compressed vs. when it isn't. + * This is because zstd detects that the two buffers are contiguous and it can + * use a more efficient match finding algorithm. However, this produces different + * results than when the two buffers are non-contiguous. This flag forces zstd + * to always load the prefix in non-contiguous mode, even if it happens to be + * adjacent to the data, to guarantee determinism. + * + * If you really care about determinism when using a dictionary or prefix, + * like when doing delta compression, you should select this option. It comes + * at a speed penalty of about ~2.5% if the dictionary and data happened to be + * contiguous, and is free if they weren't contiguous. We don't expect that + * intentionally making the dictionary and data contiguous will be worth the + * cost to memcpy() the data. + */ +#define ZSTD_c_deterministicRefPrefix ZSTD_c_experimentalParam15 + +/* ZSTD_c_prefetchCDictTables + * Controlled with ZSTD_ParamSwitch_e enum. Default is ZSTD_ps_auto. + * + * In some situations, zstd uses CDict tables in-place rather than copying them + * into the working context. (See docs on ZSTD_dictAttachPref_e above for details). + * In such situations, compression speed is seriously impacted when CDict tables are + * "cold" (outside CPU cache). This parameter instructs zstd to prefetch CDict tables + * when they are used in-place. + * + * For sufficiently small inputs, the cost of the prefetch will outweigh the benefit. + * For sufficiently large inputs, zstd will by default memcpy() CDict tables + * into the working context, so there is no need to prefetch. This parameter is + * targeted at a middle range of input sizes, where a prefetch is cheap enough to be + * useful but memcpy() is too expensive. The exact range of input sizes where this + * makes sense is best determined by careful experimentation. + * + * Note: for this parameter, ZSTD_ps_auto is currently equivalent to ZSTD_ps_disable, + * but in the future zstd may conditionally enable this feature via an auto-detection + * heuristic for cold CDicts. + * Use ZSTD_ps_disable to opt out of prefetching under any circumstances. + */ +#define ZSTD_c_prefetchCDictTables ZSTD_c_experimentalParam16 + +/* ZSTD_c_enableSeqProducerFallback + * Allowed values are 0 (disable) and 1 (enable). The default setting is 0. + * + * Controls whether zstd will fall back to an internal sequence producer if an + * external sequence producer is registered and returns an error code. This fallback + * is block-by-block: the internal sequence producer will only be called for blocks + * where the external sequence producer returns an error code. Fallback parsing will + * follow any other cParam settings, such as compression level, the same as in a + * normal (fully-internal) compression operation. + * + * The user is strongly encouraged to read the full Block-Level Sequence Producer API + * documentation (below) before setting this parameter. */ +#define ZSTD_c_enableSeqProducerFallback ZSTD_c_experimentalParam17 + +/* ZSTD_c_maxBlockSize + * Allowed values are between 1KB and ZSTD_BLOCKSIZE_MAX (128KB). + * The default is ZSTD_BLOCKSIZE_MAX, and setting to 0 will set to the default. + * + * This parameter can be used to set an upper bound on the blocksize + * that overrides the default ZSTD_BLOCKSIZE_MAX. It cannot be used to set upper + * bounds greater than ZSTD_BLOCKSIZE_MAX or bounds lower than 1KB (will make + * compressBound() inaccurate). Only currently meant to be used for testing. + */ +#define ZSTD_c_maxBlockSize ZSTD_c_experimentalParam18 + +/* ZSTD_c_repcodeResolution + * This parameter only has an effect if ZSTD_c_blockDelimiters is + * set to ZSTD_sf_explicitBlockDelimiters (may change in the future). + * + * This parameter affects how zstd parses external sequences, + * provided via the ZSTD_compressSequences*() API + * or from an external block-level sequence producer. + * + * If set to ZSTD_ps_enable, the library will check for repeated offsets within + * external sequences, even if those repcodes are not explicitly indicated in + * the "rep" field. Note that this is the only way to exploit repcode matches + * while using compressSequences*() or an external sequence producer, since zstd + * currently ignores the "rep" field of external sequences. + * + * If set to ZSTD_ps_disable, the library will not exploit repeated offsets in + * external sequences, regardless of whether the "rep" field has been set. This + * reduces sequence compression overhead by about 25% while sacrificing some + * compression ratio. + * + * The default value is ZSTD_ps_auto, for which the library will enable/disable + * based on compression level (currently: level<10 disables, level>=10 enables). + */ +#define ZSTD_c_repcodeResolution ZSTD_c_experimentalParam19 +#define ZSTD_c_searchForExternalRepcodes ZSTD_c_experimentalParam19 /* older name */ + + +/*! ZSTD_CCtx_getParameter() : + * Get the requested compression parameter value, selected by enum ZSTD_cParameter, + * and store it into int* value. + * @return : 0, or an error code (which can be tested with ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_getParameter(const ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value); + + +/*! ZSTD_CCtx_params : + * Quick howto : + * - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure + * - ZSTD_CCtxParams_setParameter() : Push parameters one by one into + * an existing ZSTD_CCtx_params structure. + * This is similar to + * ZSTD_CCtx_setParameter(). + * - ZSTD_CCtx_setParametersUsingCCtxParams() : Apply parameters to + * an existing CCtx. + * These parameters will be applied to + * all subsequent frames. + * - ZSTD_compressStream2() : Do compression using the CCtx. + * - ZSTD_freeCCtxParams() : Free the memory, accept NULL pointer. + * + * This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams() + * for static allocation of CCtx for single-threaded compression. + */ +ZSTDLIB_STATIC_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void); +ZSTDLIB_STATIC_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params); /* accept NULL pointer */ + +/*! ZSTD_CCtxParams_reset() : + * Reset params to default values. + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params); + +/*! ZSTD_CCtxParams_init() : + * Initializes the compression parameters of cctxParams according to + * compression level. All other parameters are reset to their default values. + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel); + +/*! ZSTD_CCtxParams_init_advanced() : + * Initializes the compression and frame parameters of cctxParams according to + * params. All other parameters are reset to their default values. + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params); + +/*! ZSTD_CCtxParams_setParameter() : Requires v1.4.0+ + * Similar to ZSTD_CCtx_setParameter. + * Set one compression parameter, selected by enum ZSTD_cParameter. + * Parameters must be applied to a ZSTD_CCtx using + * ZSTD_CCtx_setParametersUsingCCtxParams(). + * @result : a code representing success or failure (which can be tested with + * ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int value); + +/*! ZSTD_CCtxParams_getParameter() : + * Similar to ZSTD_CCtx_getParameter. + * Get the requested value of one compression parameter, selected by enum ZSTD_cParameter. + * @result : 0, or an error code (which can be tested with ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_getParameter(const ZSTD_CCtx_params* params, ZSTD_cParameter param, int* value); + +/*! ZSTD_CCtx_setParametersUsingCCtxParams() : + * Apply a set of ZSTD_CCtx_params to the compression context. + * This can be done even after compression is started, + * if nbWorkers==0, this will have no impact until a new compression is started. + * if nbWorkers>=1, new parameters will be picked up at next job, + * with a few restrictions (windowLog, pledgedSrcSize, nbWorkers, jobSize, and overlapLog are not updated). + */ +ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setParametersUsingCCtxParams( + ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params); + + +/*************************************** +* Advanced decompression functions +***************************************/ + +/*! ZSTD_isFrame() : + * Tells if the content of `buffer` starts with a valid Frame Identifier. + * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. + * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. + * Note 3 : Skippable Frame Identifiers are considered valid. */ +ZSTDLIB_STATIC_API unsigned ZSTD_isFrame(const void* buffer, size_t size); + +/*! ZSTD_createDDict_byReference() : + * Create a digested dictionary, ready to start decompression operation without startup delay. + * Dictionary content is referenced, and therefore stays in dictBuffer. + * It is important that dictBuffer outlives DDict, + * it must remain read accessible throughout the lifetime of DDict */ +ZSTDLIB_STATIC_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize); + +/*! ZSTD_DCtx_loadDictionary_byReference() : + * Same as ZSTD_DCtx_loadDictionary(), + * but references `dict` content instead of copying it into `dctx`. + * This saves memory if `dict` remains around., + * However, it's imperative that `dict` remains accessible (and unmodified) while being used, so it must outlive decompression. */ +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); + +/*! ZSTD_DCtx_loadDictionary_advanced() : + * Same as ZSTD_DCtx_loadDictionary(), + * but gives direct control over + * how to load the dictionary (by copy ? by reference ?) + * and how to interpret it (automatic ? force raw mode ? full mode only ?). */ +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType); + +/*! ZSTD_DCtx_refPrefix_advanced() : + * Same as ZSTD_DCtx_refPrefix(), but gives finer control over + * how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) */ +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType); + +/*! ZSTD_DCtx_setMaxWindowSize() : + * Refuses allocating internal buffers for frames requiring a window size larger than provided limit. + * This protects a decoder context from reserving too much memory for itself (potential attack scenario). + * This parameter is only useful in streaming mode, since no internal buffer is allocated in single-pass mode. + * By default, a decompression context accepts all window sizes <= (1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT) + * @return : 0, or an error code (which can be tested using ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize); + +/*! ZSTD_DCtx_getParameter() : + * Get the requested decompression parameter value, selected by enum ZSTD_dParameter, + * and store it into int* value. + * @return : 0, or an error code (which can be tested with ZSTD_isError()). + */ +ZSTDLIB_STATIC_API size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value); + +/* ZSTD_d_format + * experimental parameter, + * allowing selection between ZSTD_format_e input compression formats + */ +#define ZSTD_d_format ZSTD_d_experimentalParam1 +/* ZSTD_d_stableOutBuffer + * Experimental parameter. + * Default is 0 == disabled. Set to 1 to enable. + * + * Tells the decompressor that the ZSTD_outBuffer will ALWAYS be the same + * between calls, except for the modifications that zstd makes to pos (the + * caller must not modify pos). This is checked by the decompressor, and + * decompression will fail if it ever changes. Therefore the ZSTD_outBuffer + * MUST be large enough to fit the entire decompressed frame. This will be + * checked when the frame content size is known. The data in the ZSTD_outBuffer + * in the range [dst, dst + pos) MUST not be modified during decompression + * or you will get data corruption. + * + * When this flag is enabled zstd won't allocate an output buffer, because + * it can write directly to the ZSTD_outBuffer, but it will still allocate + * an input buffer large enough to fit any compressed block. This will also + * avoid the memcpy() from the internal output buffer to the ZSTD_outBuffer. + * If you need to avoid the input buffer allocation use the buffer-less + * streaming API. + * + * NOTE: So long as the ZSTD_outBuffer always points to valid memory, using + * this flag is ALWAYS memory safe, and will never access out-of-bounds + * memory. However, decompression WILL fail if you violate the preconditions. + * + * WARNING: The data in the ZSTD_outBuffer in the range [dst, dst + pos) MUST + * not be modified during decompression or you will get data corruption. This + * is because zstd needs to reference data in the ZSTD_outBuffer to regenerate + * matches. Normally zstd maintains its own buffer for this purpose, but passing + * this flag tells zstd to use the user provided buffer. + */ +#define ZSTD_d_stableOutBuffer ZSTD_d_experimentalParam2 + +/* ZSTD_d_forceIgnoreChecksum + * Experimental parameter. + * Default is 0 == disabled. Set to 1 to enable + * + * Tells the decompressor to skip checksum validation during decompression, regardless + * of whether checksumming was specified during compression. This offers some + * slight performance benefits, and may be useful for debugging. + * Param has values of type ZSTD_forceIgnoreChecksum_e + */ +#define ZSTD_d_forceIgnoreChecksum ZSTD_d_experimentalParam3 + +/* ZSTD_d_refMultipleDDicts + * Experimental parameter. + * Default is 0 == disabled. Set to 1 to enable + * + * If enabled and dctx is allocated on the heap, then additional memory will be allocated + * to store references to multiple ZSTD_DDict. That is, multiple calls of ZSTD_refDDict() + * using a given ZSTD_DCtx, rather than overwriting the previous DDict reference, will instead + * store all references. At decompression time, the appropriate dictID is selected + * from the set of DDicts based on the dictID in the frame. + * + * Usage is simply calling ZSTD_refDDict() on multiple dict buffers. + * + * Param has values of byte ZSTD_refMultipleDDicts_e + * + * WARNING: Enabling this parameter and calling ZSTD_DCtx_refDDict(), will trigger memory + * allocation for the hash table. ZSTD_freeDCtx() also frees this memory. + * Memory is allocated as per ZSTD_DCtx::customMem. + * + * Although this function allocates memory for the table, the user is still responsible for + * memory management of the underlying ZSTD_DDict* themselves. + */ +#define ZSTD_d_refMultipleDDicts ZSTD_d_experimentalParam4 + +/* ZSTD_d_disableHuffmanAssembly + * Set to 1 to disable the Huffman assembly implementation. + * The default value is 0, which allows zstd to use the Huffman assembly + * implementation if available. + * + * This parameter can be used to disable Huffman assembly at runtime. + * If you want to disable it at compile time you can define the macro + * ZSTD_DISABLE_ASM. + */ +#define ZSTD_d_disableHuffmanAssembly ZSTD_d_experimentalParam5 + +/* ZSTD_d_maxBlockSize + * Allowed values are between 1KB and ZSTD_BLOCKSIZE_MAX (128KB). + * The default is ZSTD_BLOCKSIZE_MAX, and setting to 0 will set to the default. + * + * Forces the decompressor to reject blocks whose content size is + * larger than the configured maxBlockSize. When maxBlockSize is + * larger than the windowSize, the windowSize is used instead. + * This saves memory on the decoder when you know all blocks are small. + * + * This option is typically used in conjunction with ZSTD_c_maxBlockSize. + * + * WARNING: This causes the decoder to reject otherwise valid frames + * that have block sizes larger than the configured maxBlockSize. + */ +#define ZSTD_d_maxBlockSize ZSTD_d_experimentalParam6 + + +/*! ZSTD_DCtx_setFormat() : + * This function is REDUNDANT. Prefer ZSTD_DCtx_setParameter(). + * Instruct the decoder context about what kind of data to decode next. + * This instruction is mandatory to decode data without a fully-formed header, + * such ZSTD_f_zstd1_magicless for example. + * @return : 0, or an error code (which can be tested using ZSTD_isError()). */ +ZSTD_DEPRECATED("use ZSTD_DCtx_setParameter() instead") +ZSTDLIB_STATIC_API +size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format); + + +/******************************************************************** +* Advanced streaming functions +* Warning : most of these functions are now redundant with the Advanced API. +* Once Advanced API reaches "stable" status, +* redundant functions will be deprecated, and then at some point removed. +********************************************************************/ + +typedef struct { + unsigned long long ingested; /* nb input bytes read and buffered */ + unsigned long long consumed; /* nb input bytes actually compressed */ + unsigned long long produced; /* nb of compressed bytes generated and buffered */ + unsigned long long flushed; /* nb of compressed bytes flushed : not provided; can be tracked from caller side */ + unsigned currentJobID; /* MT only : latest started job nb */ + unsigned nbActiveWorkers; /* MT only : nb of workers actively compressing at probe time */ +} ZSTD_frameProgression; + +/* ZSTD_getFrameProgression() : + * tells how much data has been ingested (read from input) + * consumed (input actually compressed) and produced (output) for current frame. + * Note : (ingested - consumed) is amount of input data buffered internally, not yet compressed. + * Aggregates progression inside active worker threads. + */ +ZSTDLIB_STATIC_API ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx); + +/*! ZSTD_toFlushNow() : + * Tell how many bytes are ready to be flushed immediately. + * Useful for multithreading scenarios (nbWorkers >= 1). + * Probe the oldest active job, defined as oldest job not yet entirely flushed, + * and check its output buffer. + * @return : amount of data stored in oldest job and ready to be flushed immediately. + * if @return == 0, it means either : + * + there is no active job (could be checked with ZSTD_frameProgression()), or + * + oldest job is still actively compressing data, + * but everything it has produced has also been flushed so far, + * therefore flush speed is limited by production speed of oldest job + * irrespective of the speed of concurrent (and newer) jobs. + */ +ZSTDLIB_STATIC_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx); + + +/* ********************* BLOCK-LEVEL SEQUENCE PRODUCER API ********************* + * + * *** OVERVIEW *** + * The Block-Level Sequence Producer API allows users to provide their own custom + * sequence producer which libzstd invokes to process each block. The produced list + * of sequences (literals and matches) is then post-processed by libzstd to produce + * valid compressed blocks. + * + * This block-level offload API is a more granular complement of the existing + * frame-level offload API compressSequences() (introduced in v1.5.1). It offers + * an easier migration story for applications already integrated with libzstd: the + * user application continues to invoke the same compression functions + * ZSTD_compress2() or ZSTD_compressStream2() as usual, and transparently benefits + * from the specific advantages of the external sequence producer. For example, + * the sequence producer could be tuned to take advantage of known characteristics + * of the input, to offer better speed / ratio, or could leverage hardware + * acceleration not available within libzstd itself. + * + * See contrib/externalSequenceProducer for an example program employing the + * Block-Level Sequence Producer API. + * + * *** USAGE *** + * The user is responsible for implementing a function of type + * ZSTD_sequenceProducer_F. For each block, zstd will pass the following + * arguments to the user-provided function: + * + * - sequenceProducerState: a pointer to a user-managed state for the sequence + * producer. + * + * - outSeqs, outSeqsCapacity: an output buffer for the sequence producer. + * outSeqsCapacity is guaranteed >= ZSTD_sequenceBound(srcSize). The memory + * backing outSeqs is managed by the CCtx. + * + * - src, srcSize: an input buffer for the sequence producer to parse. + * srcSize is guaranteed to be <= ZSTD_BLOCKSIZE_MAX. + * + * - dict, dictSize: a history buffer, which may be empty, which the sequence + * producer may reference as it parses the src buffer. Currently, zstd will + * always pass dictSize == 0 into external sequence producers, but this will + * change in the future. + * + * - compressionLevel: a signed integer representing the zstd compression level + * set by the user for the current operation. The sequence producer may choose + * to use this information to change its compression strategy and speed/ratio + * tradeoff. Note: the compression level does not reflect zstd parameters set + * through the advanced API. + * + * - windowSize: a size_t representing the maximum allowed offset for external + * sequences. Note that sequence offsets are sometimes allowed to exceed the + * windowSize if a dictionary is present, see doc/zstd_compression_format.md + * for details. + * + * The user-provided function shall return a size_t representing the number of + * sequences written to outSeqs. This return value will be treated as an error + * code if it is greater than outSeqsCapacity. The return value must be non-zero + * if srcSize is non-zero. The ZSTD_SEQUENCE_PRODUCER_ERROR macro is provided + * for convenience, but any value greater than outSeqsCapacity will be treated as + * an error code. + * + * If the user-provided function does not return an error code, the sequences + * written to outSeqs must be a valid parse of the src buffer. Data corruption may + * occur if the parse is not valid. A parse is defined to be valid if the + * following conditions hold: + * - The sum of matchLengths and literalLengths must equal srcSize. + * - All sequences in the parse, except for the final sequence, must have + * matchLength >= ZSTD_MINMATCH_MIN. The final sequence must have + * matchLength >= ZSTD_MINMATCH_MIN or matchLength == 0. + * - All offsets must respect the windowSize parameter as specified in + * doc/zstd_compression_format.md. + * - If the final sequence has matchLength == 0, it must also have offset == 0. + * + * zstd will only validate these conditions (and fail compression if they do not + * hold) if the ZSTD_c_validateSequences cParam is enabled. Note that sequence + * validation has a performance cost. + * + * If the user-provided function returns an error, zstd will either fall back + * to an internal sequence producer or fail the compression operation. The user can + * choose between the two behaviors by setting the ZSTD_c_enableSeqProducerFallback + * cParam. Fallback compression will follow any other cParam settings, such as + * compression level, the same as in a normal compression operation. + * + * The user shall instruct zstd to use a particular ZSTD_sequenceProducer_F + * function by calling + * ZSTD_registerSequenceProducer(cctx, + * sequenceProducerState, + * sequenceProducer) + * This setting will persist until the next parameter reset of the CCtx. + * + * The sequenceProducerState must be initialized by the user before calling + * ZSTD_registerSequenceProducer(). The user is responsible for destroying the + * sequenceProducerState. + * + * *** LIMITATIONS *** + * This API is compatible with all zstd compression APIs which respect advanced parameters. + * However, there are three limitations: + * + * First, the ZSTD_c_enableLongDistanceMatching cParam is not currently supported. + * COMPRESSION WILL FAIL if it is enabled and the user tries to compress with a block-level + * external sequence producer. + * - Note that ZSTD_c_enableLongDistanceMatching is auto-enabled by default in some + * cases (see its documentation for details). Users must explicitly set + * ZSTD_c_enableLongDistanceMatching to ZSTD_ps_disable in such cases if an external + * sequence producer is registered. + * - As of this writing, ZSTD_c_enableLongDistanceMatching is disabled by default + * whenever ZSTD_c_windowLog < 128MB, but that's subject to change. Users should + * check the docs on ZSTD_c_enableLongDistanceMatching whenever the Block-Level Sequence + * Producer API is used in conjunction with advanced settings (like ZSTD_c_windowLog). + * + * Second, history buffers are not currently supported. Concretely, zstd will always pass + * dictSize == 0 to the external sequence producer (for now). This has two implications: + * - Dictionaries are not currently supported. Compression will *not* fail if the user + * references a dictionary, but the dictionary won't have any effect. + * - Stream history is not currently supported. All advanced compression APIs, including + * streaming APIs, work with external sequence producers, but each block is treated as + * an independent chunk without history from previous blocks. + * + * Third, multi-threading within a single compression is not currently supported. In other words, + * COMPRESSION WILL FAIL if ZSTD_c_nbWorkers > 0 and an external sequence producer is registered. + * Multi-threading across compressions is fine: simply create one CCtx per thread. + * + * Long-term, we plan to overcome all three limitations. There is no technical blocker to + * overcoming them. It is purely a question of engineering effort. + */ + +#define ZSTD_SEQUENCE_PRODUCER_ERROR ((size_t)(-1)) + +typedef size_t (*ZSTD_sequenceProducer_F) ( + void* sequenceProducerState, + ZSTD_Sequence* outSeqs, size_t outSeqsCapacity, + const void* src, size_t srcSize, + const void* dict, size_t dictSize, + int compressionLevel, + size_t windowSize +); + +/*! ZSTD_registerSequenceProducer() : + * Instruct zstd to use a block-level external sequence producer function. + * + * The sequenceProducerState must be initialized by the caller, and the caller is + * responsible for managing its lifetime. This parameter is sticky across + * compressions. It will remain set until the user explicitly resets compression + * parameters. + * + * Sequence producer registration is considered to be an "advanced parameter", + * part of the "advanced API". This means it will only have an effect on compression + * APIs which respect advanced parameters, such as compress2() and compressStream2(). + * Older compression APIs such as compressCCtx(), which predate the introduction of + * "advanced parameters", will ignore any external sequence producer setting. + * + * The sequence producer can be "cleared" by registering a NULL function pointer. This + * removes all limitations described above in the "LIMITATIONS" section of the API docs. + * + * The user is strongly encouraged to read the full API documentation (above) before + * calling this function. */ +ZSTDLIB_STATIC_API void +ZSTD_registerSequenceProducer( + ZSTD_CCtx* cctx, + void* sequenceProducerState, + ZSTD_sequenceProducer_F sequenceProducer +); + +/*! ZSTD_CCtxParams_registerSequenceProducer() : + * Same as ZSTD_registerSequenceProducer(), but operates on ZSTD_CCtx_params. + * This is used for accurate size estimation with ZSTD_estimateCCtxSize_usingCCtxParams(), + * which is needed when creating a ZSTD_CCtx with ZSTD_initStaticCCtx(). + * + * If you are using the external sequence producer API in a scenario where ZSTD_initStaticCCtx() + * is required, then this function is for you. Otherwise, you probably don't need it. + * + * See tests/zstreamtest.c for example usage. */ +ZSTDLIB_STATIC_API void +ZSTD_CCtxParams_registerSequenceProducer( + ZSTD_CCtx_params* params, + void* sequenceProducerState, + ZSTD_sequenceProducer_F sequenceProducer +); + + +/********************************************************************* +* Buffer-less and synchronous inner streaming functions (DEPRECATED) +* +* This API is deprecated, and will be removed in a future version. +* It allows streaming (de)compression with user allocated buffers. +* However, it is hard to use, and not as well tested as the rest of +* our API. +* +* Please use the normal streaming API instead: ZSTD_compressStream2, +* and ZSTD_decompressStream. +* If there is functionality that you need, but it doesn't provide, +* please open an issue on our GitHub. +********************************************************************* */ + +/** + Buffer-less streaming compression (synchronous mode) + + A ZSTD_CCtx object is required to track streaming operations. + Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource. + ZSTD_CCtx object can be reused multiple times within successive compression operations. + + Start by initializing a context. + Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression. + + Then, consume your input using ZSTD_compressContinue(). + There are some important considerations to keep in mind when using this advanced function : + - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffers only. + - Interface is synchronous : input is consumed entirely and produces 1+ compressed blocks. + - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario. + Worst case evaluation is provided by ZSTD_compressBound(). + ZSTD_compressContinue() doesn't guarantee recover after a failed compression. + - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog). + It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks) + - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps. + In which case, it will "discard" the relevant memory section from its history. + + Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum. + It's possible to use srcSize==0, in which case, it will write a final empty block to end the frame. + Without last block mark, frames are considered unfinished (hence corrupted) by compliant decoders. + + `ZSTD_CCtx` object can be reused (ZSTD_compressBegin()) to compress again. +*/ + +/*===== Buffer-less streaming compression functions =====*/ +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel); +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel); +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */ + +ZSTD_DEPRECATED("This function will likely be removed in a future release. It is misleading and has very limited utility.") +ZSTDLIB_STATIC_API +size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */ + +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTD_DEPRECATED("The buffer-less API is deprecated in favor of the normal streaming API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); + +/* The ZSTD_compressBegin_advanced() and ZSTD_compressBegin_usingCDict_advanced() are now DEPRECATED and will generate a compiler warning */ +ZSTD_DEPRECATED("use advanced API to access custom parameters") +ZSTDLIB_STATIC_API +size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */ +ZSTD_DEPRECATED("use advanced API to access custom parameters") +ZSTDLIB_STATIC_API +size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); /* compression parameters are already set within cdict. pledgedSrcSize must be correct. If srcSize is not known, use macro ZSTD_CONTENTSIZE_UNKNOWN */ +/** + Buffer-less streaming decompression (synchronous mode) + + A ZSTD_DCtx object is required to track streaming operations. + Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it. + A ZSTD_DCtx object can be reused multiple times. + + First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader(). + Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough. + Data fragment must be large enough to ensure successful decoding. + `ZSTD_frameHeaderSize_max` bytes is guaranteed to always be large enough. + result : 0 : successful decoding, the `ZSTD_frameHeader` structure is correctly filled. + >0 : `srcSize` is too small, please provide at least result bytes on next attempt. + errorCode, which can be tested using ZSTD_isError(). + + It fills a ZSTD_FrameHeader structure with important information to correctly decode the frame, + such as the dictionary ID, content size, or maximum back-reference distance (`windowSize`). + Note that these values could be wrong, either because of data corruption, or because a 3rd party deliberately spoofs false information. + As a consequence, check that values remain within valid application range. + For example, do not allocate memory blindly, check that `windowSize` is within expectation. + Each application can set its own limits, depending on local restrictions. + For extended interoperability, it is recommended to support `windowSize` of at least 8 MB. + + ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize` bytes. + ZSTD_decompressContinue() is very sensitive to contiguity, + if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place, + or that previous contiguous segment is large enough to properly handle maximum back-reference distance. + There are multiple ways to guarantee this condition. + + The most memory efficient way is to use a round buffer of sufficient size. + Sufficient size is determined by invoking ZSTD_decodingBufferSize_min(), + which can return an error code if required value is too large for current system (in 32-bits mode). + In a round buffer methodology, ZSTD_decompressContinue() decompresses each block next to previous one, + up to the moment there is not enough room left in the buffer to guarantee decoding another full block, + which maximum size is provided in `ZSTD_frameHeader` structure, field `blockSizeMax`. + At which point, decoding can resume from the beginning of the buffer. + Note that already decoded data stored in the buffer should be flushed before being overwritten. + + There are alternatives possible, for example using two or more buffers of size `windowSize` each, though they consume more memory. + + Finally, if you control the compression process, you can also ignore all buffer size rules, + as long as the encoder and decoder progress in "lock-step", + aka use exactly the same buffer sizes, break contiguity at the same place, etc. + + Once buffers are setup, start decompression, with ZSTD_decompressBegin(). + If decompression requires a dictionary, use ZSTD_decompressBegin_usingDict() or ZSTD_decompressBegin_usingDDict(). + + Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively. + ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue(). + ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail. + + result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity). + It can be zero : it just means ZSTD_decompressContinue() has decoded some metadata item. + It can also be an error code, which can be tested with ZSTD_isError(). + + A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero. + Context can then be reset to start a new decompression. + + Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType(). + This information is not required to properly decode a frame. + + == Special case : skippable frames == + + Skippable frames allow integration of user-defined data into a flow of concatenated frames. + Skippable frames will be ignored (skipped) by decompressor. + The format of skippable frames is as follows : + a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F + b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits + c) Frame Content - any content (User Data) of length equal to Frame Size + For skippable frames ZSTD_getFrameHeader() returns zfhPtr->frameType==ZSTD_skippableFrame. + For skippable frames ZSTD_decompressContinue() always returns 0 : it only skips the content. +*/ + +/*===== Buffer-less streaming decompression functions =====*/ + +ZSTDLIB_STATIC_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize); /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */ + +ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx); +ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize); +ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict); + +/* misc */ +ZSTD_DEPRECATED("This function will likely be removed in the next minor release. It is misleading and has very limited utility.") +ZSTDLIB_STATIC_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx); +typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e; +ZSTDLIB_STATIC_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx); + + + + +/* ========================================= */ +/** Block level API (DEPRECATED) */ +/* ========================================= */ + +/*! + + This API is deprecated in favor of the regular compression API. + You can get the frame header down to 2 bytes by setting: + - ZSTD_c_format = ZSTD_f_zstd1_magicless + - ZSTD_c_contentSizeFlag = 0 + - ZSTD_c_checksumFlag = 0 + - ZSTD_c_dictIDFlag = 0 + + This API is not as well tested as our normal API, so we recommend not using it. + We will be removing it in a future version. If the normal API doesn't provide + the functionality you need, please open a GitHub issue. + + Block functions produce and decode raw zstd blocks, without frame metadata. + Frame metadata cost is typically ~12 bytes, which can be non-negligible for very small blocks (< 100 bytes). + But users will have to take in charge needed metadata to regenerate data, such as compressed and content sizes. + + A few rules to respect : + - Compressing and decompressing require a context structure + + Use ZSTD_createCCtx() and ZSTD_createDCtx() + - It is necessary to init context before starting + + compression : any ZSTD_compressBegin*() variant, including with dictionary + + decompression : any ZSTD_decompressBegin*() variant, including with dictionary + - Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB + + If input is larger than a block size, it's necessary to split input data into multiple blocks + + For inputs larger than a single block, consider using regular ZSTD_compress() instead. + Frame metadata is not that costly, and quickly becomes negligible as source size grows larger than a block. + - When a block is considered not compressible enough, ZSTD_compressBlock() result will be 0 (zero) ! + ===> In which case, nothing is produced into `dst` ! + + User __must__ test for such outcome and deal directly with uncompressed data + + A block cannot be declared incompressible if ZSTD_compressBlock() return value was != 0. + Doing so would mess up with statistics history, leading to potential data corruption. + + ZSTD_decompressBlock() _doesn't accept uncompressed data as input_ !! + + In case of multiple successive blocks, should some of them be uncompressed, + decoder must be informed of their existence in order to follow proper history. + Use ZSTD_insertBlock() for such a case. +*/ + +/*===== Raw zstd block functions =====*/ +ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_getBlockSize (const ZSTD_CCtx* cctx); +ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTD_DEPRECATED("The block API is deprecated in favor of the normal compression API. See docs.") +ZSTDLIB_STATIC_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */ + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */ diff --git a/src/commonlib/bsd/zstd/zstd_errors.h b/src/commonlib/bsd/zstd/zstd_errors.h new file mode 100644 index 00000000000..658c9ef4bdc --- /dev/null +++ b/src/commonlib/bsd/zstd/zstd_errors.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * All rights reserved. + * + * This source code is licensed under both the BSD-style license (found in the + * LICENSE file in the root directory of this source tree) and the GPLv2 (found + * in the COPYING file in the root directory of this source tree). + * You may select, at your option, one of the above-listed licenses. + */ + +#ifndef ZSTD_ERRORS_H_398273423 +#define ZSTD_ERRORS_H_398273423 + +#if defined (__cplusplus) +extern "C" { +#endif + +/* ===== ZSTDERRORLIB_API : control library symbols visibility ===== */ +#ifndef ZSTDERRORLIB_VISIBLE + /* Backwards compatibility with old macro name */ +# ifdef ZSTDERRORLIB_VISIBILITY +# define ZSTDERRORLIB_VISIBLE ZSTDERRORLIB_VISIBILITY +# elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) +# define ZSTDERRORLIB_VISIBLE __attribute__ ((visibility ("default"))) +# else +# define ZSTDERRORLIB_VISIBLE +# endif +#endif + +#ifndef ZSTDERRORLIB_HIDDEN +# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__) +# define ZSTDERRORLIB_HIDDEN __attribute__ ((visibility ("hidden"))) +# else +# define ZSTDERRORLIB_HIDDEN +# endif +#endif + +#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1) +# define ZSTDERRORLIB_API __declspec(dllexport) ZSTDERRORLIB_VISIBLE +#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1) +# define ZSTDERRORLIB_API __declspec(dllimport) ZSTDERRORLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ +#else +# define ZSTDERRORLIB_API ZSTDERRORLIB_VISIBLE +#endif + +/*-********************************************* + * Error codes list + *-********************************************* + * Error codes _values_ are pinned down since v1.3.1 only. + * Therefore, don't rely on values if you may link to any version < v1.3.1. + * + * Only values < 100 are considered stable. + * + * note 1 : this API shall be used with static linking only. + * dynamic linking is not yet officially supported. + * note 2 : Prefer relying on the enum than on its value whenever possible + * This is the only supported way to use the error list < v1.3.1 + * note 3 : ZSTD_isError() is always correct, whatever the library version. + **********************************************/ +typedef enum { + ZSTD_error_no_error = 0, + ZSTD_error_GENERIC = 1, + ZSTD_error_prefix_unknown = 10, + ZSTD_error_version_unsupported = 12, + ZSTD_error_frameParameter_unsupported = 14, + ZSTD_error_frameParameter_windowTooLarge = 16, + ZSTD_error_corruption_detected = 20, + ZSTD_error_checksum_wrong = 22, + ZSTD_error_literals_headerWrong = 24, + ZSTD_error_dictionary_corrupted = 30, + ZSTD_error_dictionary_wrong = 32, + ZSTD_error_dictionaryCreation_failed = 34, + ZSTD_error_parameter_unsupported = 40, + ZSTD_error_parameter_combination_unsupported = 41, + ZSTD_error_parameter_outOfBound = 42, + ZSTD_error_tableLog_tooLarge = 44, + ZSTD_error_maxSymbolValue_tooLarge = 46, + ZSTD_error_maxSymbolValue_tooSmall = 48, + ZSTD_error_cannotProduce_uncompressedBlock = 49, + ZSTD_error_stabilityCondition_notRespected = 50, + ZSTD_error_stage_wrong = 60, + ZSTD_error_init_missing = 62, + ZSTD_error_memory_allocation = 64, + ZSTD_error_workSpace_tooSmall= 66, + ZSTD_error_dstSize_tooSmall = 70, + ZSTD_error_srcSize_wrong = 72, + ZSTD_error_dstBuffer_null = 74, + ZSTD_error_noForwardProgress_destFull = 80, + ZSTD_error_noForwardProgress_inputEmpty = 82, + /* following error codes are __NOT STABLE__, they can be removed or changed in future versions */ + ZSTD_error_frameIndex_tooLarge = 100, + ZSTD_error_seekableIO = 102, + ZSTD_error_dstBuffer_wrong = 104, + ZSTD_error_srcBuffer_wrong = 105, + ZSTD_error_sequenceProducer_failed = 106, + ZSTD_error_externalSequences_invalid = 107, + ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */ +} ZSTD_ErrorCode; + +ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code); /**< Same as ZSTD_getErrorName, but using a `ZSTD_ErrorCode` enum argument */ + + +#if defined (__cplusplus) +} +#endif + +#endif /* ZSTD_ERRORS_H_398273423 */ diff --git a/src/commonlib/bsd/zstd_wrapper.c b/src/commonlib/bsd/zstd_wrapper.c new file mode 100644 index 00000000000..89051206351 --- /dev/null +++ b/src/commonlib/bsd/zstd_wrapper.c @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +#include +#include +#include +#include +#define ZSTD_STATIC_LINKING_ONLY 1 +#include +#undef ZSTD_STATIC_LINKING_ONLY +#include + +size_t uzstdn(const void *src, size_t srcn, void *dst, size_t dstn) +{ + static ZSTD_DCtx dctx __aligned(8); + if (!ZSTD_initStaticDCtx(&dctx, sizeof(dctx))) + return 0; + return ZSTD_decompressDCtx(&dctx, dst, dstn, src, srcn); +} diff --git a/src/commonlib/device_tree.c b/src/commonlib/device_tree.c index b51f9fc31d4..7d5161db23b 100644 --- a/src/commonlib/device_tree.c +++ b/src/commonlib/device_tree.c @@ -2166,3 +2166,32 @@ bool dt_is_overlay(struct device_tree *tree) return false; } + +struct device_tree_node *dt_add_reserved_memory_region(struct device_tree *tree, + const char *name, const char *compatible, uint64_t addr, uint64_t size, + bool nomap) +{ + uint32_t addr_cells, size_cells; + const char *path[] = { "reserved-memory", name, NULL }; + + /* Find or create the node. Using 1 for the 'create' argument. */ + struct device_tree_node *node = dt_find_node(tree->root, path, + &addr_cells, &size_cells, 1); + if (!node) { + printk(BIOS_ERR, "Failed to create reserved-memory node: %s\n", name); + return NULL; + } + + /* Add the compatible string if provided */ + if (compatible) + dt_add_string_prop(node, "compatible", compatible); + + /* Always add the reg property */ + dt_add_reg_prop(node, &addr, &size, 1, addr_cells, size_cells); + + /* Add no-map if requested */ + if (nomap) + dt_add_bin_prop(node, "no-map", NULL, 0); + + return node; +} diff --git a/src/commonlib/include/commonlib/console/post_codes.h b/src/commonlib/include/commonlib/console/post_codes.h index d581bc487f8..b0f9565e356 100644 --- a/src/commonlib/include/commonlib/console/post_codes.h +++ b/src/commonlib/include/commonlib/console/post_codes.h @@ -34,7 +34,7 @@ #define POSTCODE_CODE_CLEAR 0x00 /** - * \brief Entry into 'crt0.s'. reset code jumps to here + * \brief Entry into 'entry16.S'. reset code jumps to here * * First instruction that gets executed after the reset vector jumps. * This indicates that the reset vector points to the correct code segment. diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h index 251e2c44914..cb16e65c5cb 100644 --- a/src/commonlib/include/commonlib/coreboot_tables.h +++ b/src/commonlib/include/commonlib/coreboot_tables.h @@ -90,6 +90,8 @@ enum { LB_TAG_EFI_FW_INFO = 0x0045, LB_TAG_CAPSULE = 0x0046, LB_TAG_CFR_ROOT = 0x0047, + LB_TAG_ROOT_BRIDGE_INFO = 0x0048, + LB_TAG_PANEL_POWEROFF = 0x0049, /* The following options are CMOS-related */ LB_TAG_CMOS_OPTION_TABLE = 0x00c8, LB_TAG_OPTION = 0x00c9, @@ -143,8 +145,12 @@ struct lb_memory_range { #define LB_MEM_NVS 4 /* ACPI NVS Memory */ #define LB_MEM_UNUSABLE 5 /* Unusable address space */ #define LB_MEM_VENDOR_RSVD 6 /* Vendor Reserved */ -#define LB_MEM_TAG 7 /* Armv9 tag storage for MTE */ -#define LB_MEM_TABLE 16 /* Ram configuration tables are kept in */ +/* + * The memory type [1 ... 16) needs to match + * https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/15_System_Address_Map_Interfaces/Sys_Address_Map_Interfaces.html + */ +#define LB_MEM_TABLE 16 /* Ram configuration tables are kept in */ +#define LB_MEM_TAG 17 /* Armv9 tag storage for MTE */ #define LB_MEM_SOFT_RESERVED 0xefffffff /* Specific purpose memory */ }; @@ -624,9 +630,22 @@ struct lb_cfr { /* struct lb_cfr_option_form forms[] */ }; +struct lb_panel_poweroff { + uint32_t tag; + uint32_t size; + + /* MIPI DSI poweroff commands from panel_serializable_data. */ + uint8_t cmd[]; +}; + enum boot_mode_t { + /* Regular boot scenarios */ LB_BOOT_MODE_NORMAL, + /* Device is booting in low-batter w/o charger attached */ LB_BOOT_MODE_LOW_BATTERY, + /* Device is booting in low-batter w/ charger attached */ + LB_BOOT_MODE_LOW_BATTERY_CHARGING, + /* Device is booting in due to charger insertion */ LB_BOOT_MODE_OFFMODE_CHARGING, }; diff --git a/src/commonlib/include/commonlib/device_tree.h b/src/commonlib/include/commonlib/device_tree.h index b6004fe8c4a..ec4b4ffd299 100644 --- a/src/commonlib/include/commonlib/device_tree.h +++ b/src/commonlib/include/commonlib/device_tree.h @@ -237,4 +237,19 @@ struct device_tree_node *dt_init_reserved_memory_node(struct device_tree *tree); /* Check whether a devicetree is an overlay device tree */ bool dt_is_overlay(struct device_tree *tree); +/* + * dt_add_reserved_memory_region - Helper to add a node under `/reserved-memory` + * @tree: The device tree structure + * @name: Name of the child node (e.g., "ramoops", "pkvm-drng-seed") + * @compatible: Compatible string (optional, pass NULL if not needed) + * @addr: Physical start address + * @size: Size of the region + * @nomap: Boolean, if true adds the "no-map" property + * + * Returns the created node on success, NULL on failure. + */ +struct device_tree_node *dt_add_reserved_memory_region(struct device_tree *tree, + const char *name, const char *compatible, uint64_t addr, uint64_t size, + bool nomap); + #endif /* __COMMONLIB_DEVICE_TREE_H__ */ diff --git a/src/commonlib/include/commonlib/list.h b/src/commonlib/include/commonlib/list.h index 970d68ea492..a6c87ceee27 100644 --- a/src/commonlib/include/commonlib/list.h +++ b/src/commonlib/include/commonlib/list.h @@ -5,26 +5,90 @@ #define __COMMONLIB_LIST_H__ #include +#include #include struct list_node { - struct list_node *next; - struct list_node *prev; + struct _internal_do_not_access_list_node { + struct list_node *next; + struct list_node *prev; + } _internal_do_not_access; }; +// These macros do NOT belong to the public API. +#define NEXT(ptr) ((ptr)->_internal_do_not_access.next) +#define PREV(ptr) ((ptr)->_internal_do_not_access.prev) + +/* Initialize a circular list, with `head` being a placeholder head node. */ +void _list_init(struct list_node *head); + // Remove list_node node from the doubly linked list it's a part of. void list_remove(struct list_node *node); // Insert list_node node after list_node after in a doubly linked list. void list_insert_after(struct list_node *node, struct list_node *after); // Insert list_node node before list_node before in a doubly linked list. +// `before` must not be the placeholder head node. void list_insert_before(struct list_node *node, struct list_node *before); -// Appends the node to the end of the list. -void list_append(struct list_node *node, struct list_node *head); +// Append the node to the end of the list. +static inline void list_append(struct list_node *node, struct list_node *head) +{ + _list_init(head); + /* With a circular list, we just need to insert before the head. */ + list_insert_before(node, head); +} + +// Return if the list is empty. +static inline bool list_is_empty(const struct list_node *head) +{ + return !NEXT(head) || NEXT(head) == head; +} -#define list_for_each(ptr, head, member) \ - for ((ptr) = container_of((head).next, typeof(*(ptr)), member); \ - (uintptr_t)ptr + (uintptr_t)offsetof(typeof(*(ptr)), member); \ - (ptr) = container_of((ptr)->member.next, \ +// Get next node. +static inline struct list_node *list_next(const struct list_node *node, + const struct list_node *head) +{ + return NEXT(node) == head ? NULL : NEXT(node); +}; + +// Get prev node. +static inline struct list_node *list_prev(const struct list_node *node, + const struct list_node *head) +{ + return PREV(node) == head ? NULL : PREV(node); +}; + +// Get first node. +static inline struct list_node *list_first(const struct list_node *head) +{ + return list_next(head, head); +} + +// Get last node. +static inline struct list_node *list_last(const struct list_node *head) +{ + return list_prev(head, head); +} + +// Get the number of list elements. +size_t list_length(const struct list_node *head); + +/* + * Explanation of `ptr` initialization: + * 1. head.next != NULL: This means the list isn't empty. As the implementation ensures that + * _list_init() is called when the very first element is added, we can safely assume that + * the list is circular, and hence set `ptr` to the 1st element. + * 2. head.next == NULL: This means the list is empty, and _list_init() hasn't been called. + * As the `head` arg might be const, we cannot simply call _list_init() here. Instead, we set + * `ptr` to a special value such that `&(ptr->member) == &head`, causing the loop to + * terminate immediately. + */ +#define list_for_each(ptr, head, member) \ + for ((ptr) = container_of((head)._internal_do_not_access.next ?: &(head), typeof(*(ptr)), member); \ + &((ptr)->member) != &(head); \ + (ptr) = container_of((ptr)->member._internal_do_not_access.next, \ typeof(*(ptr)), member)) +#undef NEXT +#undef PREV + #endif /* __COMMONLIB_LIST_H__ */ diff --git a/src/commonlib/include/commonlib/mipi/cmd.h b/src/commonlib/include/commonlib/mipi/cmd.h new file mode 100644 index 00000000000..ad3c5a7fb4a --- /dev/null +++ b/src/commonlib/include/commonlib/mipi/cmd.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __COMMONLIB_MIPI_CMD_H__ +#define __COMMONLIB_MIPI_CMD_H__ + +#include +#include +#include +#include + +/* Definitions for cmd in panel_command */ +enum panel_cmd { + PANEL_CMD_END = 0, + PANEL_CMD_DELAY = 1, + PANEL_CMD_GENERIC = 2, + PANEL_CMD_DCS = 3, +}; + +struct panel_command { + u8 cmd; + u8 len; + u8 data[]; +}; + +#define PANEL_DELAY(delay) \ + PANEL_CMD_DELAY, \ + delay + +#define PANEL_GENERIC(...) \ + PANEL_CMD_GENERIC, \ + sizeof((u8[]){__VA_ARGS__}), \ + __VA_ARGS__ + +#define PANEL_DCS(...) \ + PANEL_CMD_DCS, \ + sizeof((u8[]){__VA_ARGS__}), \ + __VA_ARGS__ + +#define PANEL_END \ + PANEL_CMD_END + +/* + * Callback function type for mipi_panel_parse_commands(). + * @param type MIPI DSI transaction type. + * @param data panel_command data. + * @param len panel_command len. + * @param user_data Arbitrary user data passed from mipi_panel_parse_commands(). + */ +typedef enum cb_err (*mipi_cmd_func_t)(enum mipi_dsi_transaction type, const u8 *data, u8 len, + void *user_data); + +/* Parse a command array and call cmd_func() for each entry. Delays get handled internally. */ +enum cb_err mipi_panel_parse_commands(const void *buf, mipi_cmd_func_t cmd_func, + void *user_data); + +/* + * Parse a command array and calculate the array length, including the trailing + * PANEL_CMD_END. If the array begins with PANEL_CMD_END, 0 will be returned. + */ +size_t mipi_panel_get_commands_len(const void *buf); + +#endif /* __COMMONLIB_MIPI_CMD_H__ */ diff --git a/src/include/mipi/dsi.h b/src/commonlib/include/commonlib/mipi/dsi.h similarity index 97% rename from src/include/mipi/dsi.h rename to src/commonlib/include/commonlib/mipi/dsi.h index 9f11490f694..b55fd9dc702 100644 --- a/src/include/mipi/dsi.h +++ b/src/commonlib/include/commonlib/mipi/dsi.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef __MIPI_DSI_H__ -#define __MIPI_DSI_H__ +#ifndef __COMMONLIB_MIPI_DSI_H__ +#define __COMMONLIB_MIPI_DSI_H__ /* MIPI DSI Processor-to-Peripheral transaction types */ enum mipi_dsi_transaction { @@ -109,4 +109,4 @@ enum { MIPI_DCS_READ_DDB_CONTINUE = 0xA8, }; -#endif /* __MIPI_DSI_H__ */ +#endif /* __COMMONLIB_MIPI_DSI_H__ */ diff --git a/src/commonlib/include/commonlib/timestamp_serialized.h b/src/commonlib/include/commonlib/timestamp_serialized.h index 2a159f64b8c..3999b35069b 100644 --- a/src/commonlib/include/commonlib/timestamp_serialized.h +++ b/src/commonlib/include/commonlib/timestamp_serialized.h @@ -37,6 +37,8 @@ enum timestamp_id { TS_ULZMA_END = 16, TS_ULZ4F_START = 17, TS_ULZ4F_END = 18, + TS_UZSTDF_START = 19, + TS_UZSTDF_END = 20, TS_DEVICE_INIT_CHIPS = 30, TS_DEVICE_ENUMERATE = 31, TS_DEVICE_CONFIGURE = 40, @@ -236,6 +238,8 @@ static const struct timestamp_id_to_name { TS_NAME_DEF(TS_ULZMA_END, 0, "finished LZMA decompress (ignore for x86)"), TS_NAME_DEF(TS_ULZ4F_START, TS_ULZ4F_END, "starting LZ4 decompress (ignore for x86)"), TS_NAME_DEF(TS_ULZ4F_END, 0, "finished LZ4 decompress (ignore for x86)"), + TS_NAME_DEF(TS_UZSTDF_START, TS_UZSTDF_END, "starting ZSTD decompress (ignore for x86)"), + TS_NAME_DEF(TS_UZSTDF_END, 0, "finished ZSTD decompress (ignore for x86)"), TS_NAME_DEF(TS_DEVICE_INIT_CHIPS, TS_DEVICE_ENUMERATE, "early chipset initialization"), TS_NAME_DEF(TS_DEVICE_ENUMERATE, TS_DEVICE_CONFIGURE, "device enumeration"), TS_NAME_DEF(TS_DEVICE_CONFIGURE, TS_DEVICE_ENABLE, "device configuration"), diff --git a/src/commonlib/list.c b/src/commonlib/list.c index b1030c82637..93a9b12887e 100644 --- a/src/commonlib/list.c +++ b/src/commonlib/list.c @@ -1,38 +1,61 @@ /* Taken from depthcharge: src/base/list.c */ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include #include +#define NEXT(ptr) ((ptr)->_internal_do_not_access.next) +#define PREV(ptr) ((ptr)->_internal_do_not_access.prev) + +void _list_init(struct list_node *head) +{ + if (!NEXT(head)) { + assert(!PREV(head)); + PREV(head) = NEXT(head) = head; + } +} + void list_remove(struct list_node *node) { - if (node->prev) - node->prev->next = node->next; - if (node->next) - node->next->prev = node->prev; + /* Cannot remove the head node. */ + assert(PREV(node) && NEXT(node)); + NEXT(PREV(node)) = NEXT(node); + PREV(NEXT(node)) = PREV(node); } void list_insert_after(struct list_node *node, struct list_node *after) { - node->next = after->next; - node->prev = after; - after->next = node; - if (node->next) - node->next->prev = node; + /* Check uninitialized head node. */ + if (!PREV(after)) + _list_init(after); + NEXT(node) = NEXT(after); + PREV(node) = after; + NEXT(after) = node; + PREV(NEXT(node)) = node; } void list_insert_before(struct list_node *node, struct list_node *before) { - node->prev = before->prev; - node->next = before; - before->prev = node; - if (node->prev) - node->prev->next = node; + /* `before` cannot be an uninitialized head node. */ + assert(PREV(before)); + PREV(node) = PREV(before); + NEXT(node) = before; + PREV(before) = node; + NEXT(PREV(node)) = node; } -void list_append(struct list_node *node, struct list_node *head) +size_t list_length(const struct list_node *head) { - while (head->next) - head = head->next; + struct { + struct list_node node; + } const *ptr; + size_t len = 0; + + list_for_each(ptr, *head, node) + len++; - list_insert_after(node, head); + return len; } + +#undef NEXT +#undef PREV diff --git a/src/commonlib/mipi/Makefile.mk b/src/commonlib/mipi/Makefile.mk new file mode 100644 index 00000000000..e5df26b2c54 --- /dev/null +++ b/src/commonlib/mipi/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-y += cmd.c diff --git a/src/commonlib/mipi/cmd.c b/src/commonlib/mipi/cmd.c new file mode 100644 index 00000000000..8c59a83b6e4 --- /dev/null +++ b/src/commonlib/mipi/cmd.c @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +enum cb_err mipi_panel_parse_commands(const void *buf, mipi_cmd_func_t cmd_func, + void *user_data) +{ + const struct panel_command *command = buf; + enum mipi_dsi_transaction type; + + /* + * The given commands should be in a buffer containing a packed array of + * panel_command and each element may be in variable size so we have + * to parse and scan. + */ + + for (; command->cmd != PANEL_CMD_END; command = buf) { + /* + * For some commands like DELAY, the command->len should not be + * counted for buf. + */ + buf += sizeof(*command); + + u32 cmd = command->cmd, len = command->len; + + if (cmd == PANEL_CMD_DELAY) { + mdelay(len); + continue; + } + + switch (cmd) { + case PANEL_CMD_DCS: + switch (len) { + case 0: + printk(BIOS_ERR, "%s: DCS command length 0?\n", __func__); + return CB_ERR; + case 1: + type = MIPI_DSI_DCS_SHORT_WRITE; + break; + case 2: + type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; + break; + default: + type = MIPI_DSI_DCS_LONG_WRITE; + break; + } + break; + case PANEL_CMD_GENERIC: + switch (len) { + case 0: + type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM; + break; + case 1: + type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM; + break; + case 2: + type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM; + break; + default: + type = MIPI_DSI_GENERIC_LONG_WRITE; + break; + } + break; + default: + printk(BIOS_ERR, "%s: Unknown command code: %d, " + "abort panel initialization.\n", __func__, cmd); + return CB_ERR; + } + + enum cb_err ret = cmd_func(type, command->data, len, user_data); + if (ret != CB_SUCCESS) + return ret; + buf += len; + } + + return CB_SUCCESS; +} + +size_t mipi_panel_get_commands_len(const void *buf) +{ + const void *const buf_start = buf; + const struct panel_command *command = buf; + + if (command->cmd == PANEL_CMD_END) + return 0; + + for (; command->cmd != PANEL_CMD_END; command = buf) { + buf += sizeof(*command); + + switch (command->cmd) { + case PANEL_CMD_DELAY: + /* + * For PANEL_CMD_DELAY, the command->len should not be + * counted for buf. + */ + break; + case PANEL_CMD_GENERIC: + case PANEL_CMD_DCS: + buf += command->len; + break; + default: + printk(BIOS_ERR, "%s: Unknown command code: %d.\n", + __func__, command->cmd); + return 0; + } + } + + /* Add 1 byte for PANEL_CMD_END. */ + return buf - buf_start + 1; +} diff --git a/src/cpu/intel/car/romstage.c b/src/cpu/intel/car/romstage.c index 285c2f48b23..f0a55f14b3e 100644 --- a/src/cpu/intel/car/romstage.c +++ b/src/cpu/intel/car/romstage.c @@ -16,6 +16,19 @@ following as a guideline for acceptable stack usage. */ #define DCACHE_RAM_ROMSTAGE_STACK_SIZE 0x2000 +/* + * Platform-specific hooks for logic surrounding memory initialization. + * + * platform_romstage_pre_mem() is invoked before memory training. + * + * platform_romstage_post_mem() is invoked after DRAM is initialized but + * before the transition to the RAM-based stack (Post-CAR). + * + * Default: No-op. These are weak symbols to be overridden by SoC or mainboard. + */ +__weak void platform_romstage_pre_mem(void) { /* no-op */ } +__weak void platform_romstage_post_mem(void) { /* no-op */ } + void __noreturn romstage_main(void) { int i; @@ -71,7 +84,9 @@ void __noreturn romstage_main(void) */ romstage_adainit(); + platform_romstage_pre_mem(); mainboard_romstage_entry(); + platform_romstage_post_mem(); /* Check the stack. */ for (i = 0; i < num_guards; i++) { diff --git a/src/cpu/intel/fit/Makefile.mk b/src/cpu/intel/fit/Makefile.mk index 2729c0a6ae4..4a01449e4ea 100644 --- a/src/cpu/intel/fit/Makefile.mk +++ b/src/cpu/intel/fit/Makefile.mk @@ -16,6 +16,10 @@ intel_fit-align := 16 ifeq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) regions-for-file-intel_fit = BOOTBLOCK regions-for-file-intel_fit_ts = TOPSWAP + +TS_MCU_REGION = COREBOOT_TS +else +TS_MCU_REGION = COREBOOT endif $(call add_intermediate, set_fit_ptr, $(IFITTOOL)) @@ -45,7 +49,7 @@ $(call add_intermediate, add_ts_mcu_fit, set_ts_fit_ptr $(IFITTOOL)) ifneq ($(FIT_ENTRY),) $(IFITTOOL) -f $< -A -n $(FIT_ENTRY) -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) $(TS_OPTIONS) -r $(TS_FIT_REGION) endif # FIT_ENTRY - $(IFITTOOL) -f $< -a -n cpu_microcode_blob.bin -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) $(TS_OPTIONS) -r $(TS_FIT_REGION) -R COREBOOT + $(IFITTOOL) -f $< -a -n cpu_microcode_blob.bin -t 1 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) $(TS_OPTIONS) -r $(TS_FIT_REGION) -R $(TS_MCU_REGION) cbfs-files-y += intel_fit_ts intel_fit_ts-file := fit_table.c:struct @@ -65,10 +69,7 @@ pbp.bin-type := raw $(call add_intermediate, add_pbp_fit, set_fit_ptr $(IFITTOOL)) @printf " UPDATE-FIT Platform Boot Policy binary\n" - $(IFITTOOL) -f $< -a -n pbp.bin -t 4 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -r COREBOOT -ifeq ($(CONFIG_INTEL_TOP_SWAP_SEPARATE_REGIONS),y) - $(IFITTOOL) -f $< -a -n pbp.bin -t 4 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -r COREBOOT_TS -endif + $(IFITTOOL) -f $< -a -n pbp.bin -t 4 -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -r $(CBFS_REGIONS) endif # CONFIG_HAVE_PBP_BIN diff --git a/src/cpu/intel/haswell/haswell.h b/src/cpu/intel/haswell/haswell.h index f42199de0ae..d24cbe19758 100644 --- a/src/cpu/intel/haswell/haswell.h +++ b/src/cpu/intel/haswell/haswell.h @@ -103,10 +103,6 @@ #define SMBASE_MSR 0xc20 #define IEDBASE_MSR 0xc22 -/* MTRR_CAP_MSR bit definitions */ -#define SMRR_SUPPORTED (1 << 11) -#define PRMRR_SUPPORTED (1 << 12) - /* Intel suggested latency times in units of 1024ns. */ #define C_STATE_LATENCY_CONTROL_0_LIMIT 0x42 #define C_STATE_LATENCY_CONTROL_1_LIMIT 0x73 diff --git a/src/cpu/intel/haswell/haswell_init.c b/src/cpu/intel/haswell/haswell_init.c index a54a01ad8fa..c21f3c09f8a 100644 --- a/src/cpu/intel/haswell/haswell_init.c +++ b/src/cpu/intel/haswell/haswell_init.c @@ -502,8 +502,6 @@ static void cpu_core_init(struct device *cpu) } /* MP initialization support. */ -static const void *microcode_patch; - static void pre_mp_init(void) { /* Setup MTRRs based on physical address size. */ @@ -534,10 +532,13 @@ static int get_cpu_count(void) return num_threads; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - microcode_patch = intel_microcode_find(); - *microcode = microcode_patch; + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 1; } @@ -547,6 +548,7 @@ static void per_cpu_smm_trigger(void) smm_relocate(); /* After SMM relocation a 2nd microcode load is required. */ + const void *microcode_patch = intel_microcode_find(); intel_microcode_load_unlocked(microcode_patch); } @@ -604,6 +606,13 @@ static const struct cpu_device_id cpu_table[] = { CPU_TABLE_END }; +struct device_operations haswell_cpu_bus_ops = { + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, + .init = mp_cpu_bus_init, + .acpi_fill_ssdt = generate_cpu_entries, +}; + static const struct cpu_driver driver __cpu_driver = { .ops = &cpu_dev_ops, .id_table = cpu_table, diff --git a/src/cpu/intel/haswell/smmrelocate.c b/src/cpu/intel/haswell/smmrelocate.c index 47946e8401d..6ce41965d1a 100644 --- a/src/cpu/intel/haswell/smmrelocate.c +++ b/src/cpu/intel/haswell/smmrelocate.c @@ -124,10 +124,10 @@ void smm_relocation_handler(int cpu, uintptr_t curr_smbase, /* Write PRMRR and SMRR MSRs based on indicated support. */ mtrr_cap = rdmsr(MTRR_CAP_MSR); - if (mtrr_cap.lo & SMRR_SUPPORTED) + if (mtrr_cap.lo & MTRR_CAP_SMRR) write_smrr(relo_params); - if (mtrr_cap.lo & PRMRR_SUPPORTED) { + if (mtrr_cap.lo & MTRR_CAP_PRMRR) { write_prmrr(relo_params); /* UNCORE_PRMRR msrs are package level. Therefore, only * configure these MSRs on the BSP. */ diff --git a/src/cpu/intel/microcode/microcode.c b/src/cpu/intel/microcode/microcode.c index b22822641a2..7e1e1b06419 100644 --- a/src/cpu/intel/microcode/microcode.c +++ b/src/cpu/intel/microcode/microcode.c @@ -132,7 +132,12 @@ uint32_t get_microcode_rev(const void *microcode) uint32_t get_microcode_size(const void *microcode) { - return ((struct microcode *)microcode)->total_size; + u32 size = ((struct microcode *)microcode)->total_size; + + /* Newer microcode updates include a size field, whereas older + * containers set it at 0 and are exactly 2048 bytes long */ + + return size ? size : 2048; } uint32_t get_microcode_checksum(const void *microcode) diff --git a/src/cpu/intel/model_1067x/mp_init.c b/src/cpu/intel/model_1067x/mp_init.c index bc532143105..f2a702c2ca2 100644 --- a/src/cpu/intel/model_1067x/mp_init.c +++ b/src/cpu/intel/model_1067x/mp_init.c @@ -30,9 +30,13 @@ static int get_cpu_count(void) return cores; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } @@ -43,12 +47,10 @@ static void pre_mp_smm_init(void) smm_initialize(); } -#define SMRR_SUPPORTED (1 << 11) - static void per_cpu_smm_trigger(void) { msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR); - if (cpu_has_alternative_smrr() && mtrr_cap.lo & SMRR_SUPPORTED) { + if (mtrr_cap.lo & MTRR_CAP_SMRR) { set_feature_ctrl_vmx(); msr_t ia32_ft_ctrl = rdmsr(IA32_FEATURE_CONTROL); /* We don't care if the lock is already setting diff --git a/src/cpu/intel/model_2065x/model_2065x_init.c b/src/cpu/intel/model_2065x/model_2065x_init.c index 70a2d1ae806..f8fb5891599 100644 --- a/src/cpu/intel/model_2065x/model_2065x_init.c +++ b/src/cpu/intel/model_2065x/model_2065x_init.c @@ -106,6 +106,9 @@ static void model_2065x_init(struct device *cpu) /* MP initialization support. */ static void pre_mp_init(void) { + const void *microcode_patch = intel_microcode_find(); + intel_microcode_load_unlocked(microcode_patch); + /* Setup MTRRs based on physical address size. */ x86_setup_mtrrs_with_detect(); x86_mtrr_check(); @@ -126,9 +129,13 @@ static int get_cpu_count(void) return num_threads; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/cpu/intel/model_206ax/model_206ax_init.c b/src/cpu/intel/model_206ax/model_206ax_init.c index 21a13f3d114..0fdbacbe8d5 100644 --- a/src/cpu/intel/model_206ax/model_206ax_init.c +++ b/src/cpu/intel/model_206ax/model_206ax_init.c @@ -486,6 +486,9 @@ static void model_206ax_init(struct device *cpu) /* MP initialization support. */ static void pre_mp_init(void) { + const void *microcode_patch = intel_microcode_find(); + intel_microcode_load_unlocked(microcode_patch); + /* Setup MTRRs based on physical address size. */ x86_setup_mtrrs_with_detect(); x86_mtrr_check(); @@ -506,9 +509,13 @@ static int get_cpu_count(void) return num_threads; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/cpu/intel/model_f2x/mp_init.c b/src/cpu/intel/model_f2x/mp_init.c index c8d38c59ff1..010b1770c14 100644 --- a/src/cpu/intel/model_f2x/mp_init.c +++ b/src/cpu/intel/model_f2x/mp_init.c @@ -27,9 +27,13 @@ static int get_cpu_count(void) return CONFIG_MAX_CPUS; } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/cpu/intel/smm/gen1/smmrelocate.c b/src/cpu/intel/smm/gen1/smmrelocate.c index 8dffceb4fdc..1408a674690 100644 --- a/src/cpu/intel/smm/gen1/smmrelocate.c +++ b/src/cpu/intel/smm/gen1/smmrelocate.c @@ -17,8 +17,6 @@ #include #include -#define SMRR_SUPPORTED (1 << 11) - #define D_OPEN (1 << 6) #define D_CLS (1 << 5) #define D_LCK (1 << 4) @@ -28,20 +26,17 @@ /* On model_6fx, model_1067x and model_106cx SMRR functions slightly differently. The MSR are at different location from the rest and need to be explicitly enabled in IA32_FEATURE_CONTROL MSR. */ -bool cpu_has_alternative_smrr(void) +static inline bool cpu_has_alternative_smrr(void) { - struct cpuinfo_x86 c; - get_fms(&c, cpuid_eax(1)); - if (c.x86 != 6) - return false; - switch (c.x86_model) { - case 0xf: - case 0x17: /* core2 */ - case 0x1c: /* Bonnell */ + if (CONFIG(CPU_INTEL_MODEL_1067X) || + CONFIG(CPU_INTEL_MODEL_106CX)) return true; - default: + if (!CONFIG(CPU_INTEL_MODEL_6FX)) return false; - } + /* Runtime detection as model_6fx also supports Fam 6 Model 16h */ + struct cpuinfo_x86 c; + get_fms(&c, cpuid_eax(1)); + return c.x86 == 6 && c.x86_model == 0xf; } static void write_smrr_alt(struct smm_relocation_params *relo_params) @@ -145,10 +140,7 @@ void smm_initialize(void) /* Clear the SMM state in the southbridge. */ smm_southbridge_clear_state(); - /* - * Run the relocation handler for on the BSP to check and set up - * parallel SMM relocation. - */ + /* Run the relocation handler on the BSP. */ smm_initiate_relocation(); } @@ -186,7 +178,7 @@ void smm_relocation_handler(int cpu, uintptr_t curr_smbase, /* Write EMRR and SMRR MSRs based on indicated support. */ mtrr_cap = rdmsr(MTRR_CAP_MSR); - if (!(mtrr_cap.lo & SMRR_SUPPORTED)) + if (!(mtrr_cap.lo & MTRR_CAP_SMRR)) return; if (cpu_has_alternative_smrr()) @@ -195,20 +187,11 @@ void smm_relocation_handler(int cpu, uintptr_t curr_smbase, write_smrr(relo_params); } -/* - * The default SMM entry can happen in parallel or serially. If the - * default SMM entry is done in parallel the BSP has already setup - * the saving state to each CPU's MSRs. At least one save state size - * is required for the initial SMM entry for the BSP to determine if - * parallel SMM relocation is even feasible. - */ void smm_relocate(void) { /* - * If smm_save_state_in_msrs is non-zero then parallel SMM relocation - * shall take place. Run the relocation handler a second time on the - * BSP to do the final move. For APs, a relocation handler always - * needs to be run. + * The BSP had already run SMM relocation in smm_initialize(), + * so skip it for the BSP and only run it on the APs. */ if (!boot_cpu()) smm_initiate_relocation(); diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c index 23880c74c81..ed2005e91ef 100644 --- a/src/cpu/x86/mp_init.c +++ b/src/cpu/x86/mp_init.c @@ -77,6 +77,7 @@ struct mp_params { int num_cpus; /* Total cpus include BSP */ int parallel_microcode_load; const void *microcode_pointer; + size_t microcode_size; /* Flight plan for APs and BSP. */ struct mp_flight_record *flight_plan; int num_records; @@ -1145,9 +1146,11 @@ static enum cb_err do_mp_init_with_smm(struct bus *cpu_bus, const struct mp_ops printk(BIOS_INFO, "Will perform SMM setup.\n"); mp_params.num_cpus = mp_state.cpu_count; + /* Gather microcode information. */ if (mp_state.ops.get_microcode_info != NULL) mp_state.ops.get_microcode_info(&mp_params.microcode_pointer, + &mp_params.microcode_size, &mp_params.parallel_microcode_load); mp_params.flight_plan = &mp_steps[0]; mp_params.num_records = ARRAY_SIZE(mp_steps); diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c index 72727861dee..001f9b5a886 100644 --- a/src/cpu/x86/mtrr/mtrr.c +++ b/src/cpu/x86/mtrr/mtrr.c @@ -122,6 +122,16 @@ static int filter_vga_wrcomb(struct device *dev, struct resource *res) if (((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)) return 0; + /* + * Only mark 32-bit BARs as WC. Some platforms expose additional large + * prefetchable BARs above 4GiB for the iGPU, and tagging those as WC + * can fragment the address space enough to exhaust variable MTRRs. + * Keeping the below-4GiB framebuffer WC is the priority for payload UI + * performance. + */ + if (res->size != 0 && res->base >= 0x100000000ULL) + return 0; + /* Add resource as write-combining in the address space. */ return 1; } diff --git a/src/cpu/x86/smm/smm_module_handler.c b/src/cpu/x86/smm/smm_module_handler.c index d9f64204d6d..8bcda32b33d 100644 --- a/src/cpu/x86/smm/smm_module_handler.c +++ b/src/cpu/x86/smm/smm_module_handler.c @@ -226,6 +226,7 @@ void __weak southbridge_smi_handler(void) {} void __weak mainboard_smi_gpi(u32 gpi_sts) {} int __weak mainboard_smi_apmc(u8 data) { return 0; } void __weak mainboard_smi_sleep(u8 slp_typ) {} +void __weak mainboard_smi_sleep_finalize(u8 slp_typ) {} void __weak mainboard_smi_finalize(void) {} void __weak smm_soc_early_init(void) {} diff --git a/src/device/Kconfig b/src/device/Kconfig index f185ecb4c3f..39aa7dd1932 100644 --- a/src/device/Kconfig +++ b/src/device/Kconfig @@ -126,7 +126,7 @@ endchoice choice prompt "Early (romstage) graphics initialization" - default MAINBOARD_USE_EARLY_LIBGFXINIT if MAINBOARD_HAS_EARLY_LIBGFXINIT + default MAINBOARD_USE_EARLY_LIBGFXINIT if MAINBOARD_HAS_EARLY_LIBGFXINIT && CHROMEOS default NO_EARLY_GFX_INIT config NO_EARLY_GFX_INIT diff --git a/src/device/dram/ddr3.c b/src/device/dram/ddr3.c index c99255ba5a8..eb87289481f 100644 --- a/src/device/dram/ddr3.c +++ b/src/device/dram/ddr3.c @@ -542,6 +542,9 @@ enum cb_err spd_add_smbios17(const u8 channel, const u8 slot, const u16 selected if (info->size_mb) { dimm->ddr_type = MEMORY_TYPE_DDR3; dimm->ddr_frequency = selected_freq; + dimm->configured_speed_mts = 2 * selected_freq; + if (info->tCK > 0) + dimm->max_speed_mts = 2 * NS2MHZ_DIV256 / info->tCK; dimm->dimm_size = info->size_mb; dimm->channel_num = channel; dimm->rank_per_dimm = info->ranks; diff --git a/src/device/pci_device.c b/src/device/pci_device.c index 202e8b50559..a0a8df3d4d9 100644 --- a/src/device/pci_device.c +++ b/src/device/pci_device.c @@ -1438,11 +1438,11 @@ void pci_scan_bus(struct bus *bus, unsigned int min_devfn, } /* - * The device is only considered leftover if it is not hidden - * and it has a Vendor ID of 0 (the default for a device that + * The device is only considered leftover if it is enabled, not + * hidden, and has a Vendor ID of 0 (the default for a device that * could not be probed). */ - if (dev->vendor != 0 || dev->hidden) { + if (dev->vendor != 0 || dev->hidden || !dev->enabled) { prev = &dev->sibling; continue; } diff --git a/src/device/pciexp_device.c b/src/device/pciexp_device.c index a5f162e8ac5..3c2f06e013a 100644 --- a/src/device/pciexp_device.c +++ b/src/device/pciexp_device.c @@ -563,13 +563,49 @@ static int pciexp_aspm_latency(struct device *root, unsigned int root_cap, return (endp_lat > root_lat) ? endp_lat : root_lat; } +/* + * Enable ASPM on PCIe root port when no endpoint is connected. + * This programs ASPM based on the root port's own capabilities. + */ +static void pciexp_enable_aspm_root_port_only(struct device *root, unsigned int root_cap) +{ + static const char * const aspm_type_str[] = { "None", "L0s", "L1", "L0s and L1" }; + enum aspm_type apmc = PCIE_ASPM_NONE; + u16 lnkctl; + u32 lnkcap; + + /* Read root port's ASPM support from Link Capabilities */ + lnkcap = pci_read_config32(root, root_cap + PCI_EXP_LNKCAP); + + /* Extract ASPM support bits (11:10) */ + u32 aspm_support = (lnkcap & PCI_EXP_LNKCAP_ASPMS) >> 10; + + /* Map ASPM support to control value: + * 00 = No ASPM -> apmc = 0 (NONE) + * 01 = L0s supported -> apmc = 1 (L0S) + * 10 = L1 supported -> apmc = 2 (L1) + * 11 = L0s and L1 supported -> apmc = 3 (BOTH) + */ + apmc = (enum aspm_type)aspm_support; + + if (apmc != PCIE_ASPM_NONE) { + /* Set ASPM control in root port's Link Control register */ + lnkctl = pci_read_config16(root, root_cap + PCI_EXP_LNKCTL); + /* Clear existing ASPM bits (0:1) and set new value */ + lnkctl = (lnkctl & ~0x3) | apmc; + pci_write_config16(root, root_cap + PCI_EXP_LNKCTL, lnkctl); + printk(BIOS_INFO, "%s: ASPM enabled %s (no endpoint)\n", + dev_path(root), aspm_type_str[apmc]); + } +} + /* * Enable ASPM on PCIe root port and endpoint. */ static void pciexp_enable_aspm(struct device *root, unsigned int root_cap, struct device *endp, unsigned int endp_cap) { - const char *aspm_type_str[] = { "None", "L0s", "L1", "L0s and L1" }; + static const char * const aspm_type_str[] = { "None", "L0s", "L1", "L0s and L1" }; enum aspm_type apmc = PCIE_ASPM_NONE; int exit_latency, ok_latency; u16 lnkctl; @@ -692,7 +728,7 @@ static void clear_lane_error_status(struct device *dev) u32 reg32; u16 pos; - pos = pciexp_find_extended_cap(dev, PCI_EXP_SEC_CAP_ID, 0); + pos = pciexp_find_extended_cap(dev, PCI_CAP_ID_SEC_PCIE, 0); if (pos == 0) return; @@ -843,6 +879,8 @@ void pciexp_scan_bus(struct bus *bus, unsigned int min_devfn, { struct device *child; unsigned int max_payload; + bool has_children = false; + unsigned int root_cap; pciexp_enable_ltr(bus->dev); @@ -862,9 +900,20 @@ void pciexp_scan_bus(struct bus *bus, unsigned int min_devfn, (child->path.pci.devfn > max_devfn)) { continue; } + has_children = true; pciexp_tune_dev(child); } + /* + * If no endpoint is connected and this is a root port, program ASPM + * based on the root port's own capabilities. + */ + if (!has_children && pcie_is_root_port(bus->dev) && CONFIG(PCIEXP_ASPM)) { + root_cap = pci_find_capability(bus->dev, PCI_CAP_ID_PCIE); + if (root_cap) + pciexp_enable_aspm_root_port_only(bus->dev, root_cap); + } + /* * Now the root port's Max Payload Size should be set to the highest * possible value supported by all devices under a given root port. diff --git a/src/device/smbus_ops.c b/src/device/smbus_ops.c index d08965c7e0b..0bff636c624 100644 --- a/src/device/smbus_ops.c +++ b/src/device/smbus_ops.c @@ -35,3 +35,11 @@ int smbus_block_write(struct device *dev, u8 cmd, u8 bytes, const u8 *buffer) return ops_smbus_bus(get_pbus_smbus(dev))->block_write(dev, cmd, bytes, buffer); } + +int smbus_i2c_eeprom_read(struct device *dev, u8 cmd, u8 bytes, u8 *buffer) +{ + CHECK_PRESENCE(i2c_eeprom_read); + + return ops_smbus_bus(get_pbus_smbus(dev))->i2c_eeprom_read(dev, cmd, + bytes, buffer); +} diff --git a/src/drivers/amd/ftpm/Kconfig b/src/drivers/amd/ftpm/Kconfig new file mode 100644 index 00000000000..9e9c3825728 --- /dev/null +++ b/src/drivers/amd/ftpm/Kconfig @@ -0,0 +1,14 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config AMD_CRB_FTPM + bool + default n + depends on !CRB_TPM + depends on SOC_AMD_COMMON_BLOCK_PSP_GEN2 + # The fTPM needs to access the SPI flash when ROM Armor + # is not being used, thus select SOC_AMD_COMMON_BLOCK_PSP_SMI. + select SOC_AMD_COMMON_BLOCK_PSP_SMI + help + Mainboard has AMD fTPM with Command Response Buffer support. + The fTPM is based on the CRB interface as defined by TCG, + but with reduced set of registers being implemented. diff --git a/src/drivers/amd/ftpm/Makefile.mk b/src/drivers/amd/ftpm/Makefile.mk new file mode 100644 index 00000000000..87f649b67ca --- /dev/null +++ b/src/drivers/amd/ftpm/Makefile.mk @@ -0,0 +1,7 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ifeq ($(CONFIG_AMD_CRB_FTPM),y) +# Currently depends on SOC_AMD_COMMON_BLOCK_PSP_SMI, that means +# fTPM is only accepting commands after SMM has been set up. +ramstage-y += tis.c tpm.c +endif diff --git a/src/drivers/amd/ftpm/chip.h b/src/drivers/amd/ftpm/chip.h new file mode 100644 index 00000000000..7e695092699 --- /dev/null +++ b/src/drivers/amd/ftpm/chip.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef DRIVERS_AMD_FTPM_CHIP_H +#define DRIVERS_AMD_FTPM_CHIP_H + +struct drivers_amd_ftpm_config { +}; + +#endif /* DRIVERS_AMD_FTPM_CHIP_H */ diff --git a/src/drivers/amd/ftpm/tis.c b/src/drivers/amd/ftpm/tis.c new file mode 100644 index 00000000000..0f0dd5c899c --- /dev/null +++ b/src/drivers/amd/ftpm/tis.c @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tpm.h" +#include "chip.h" + +static const char *tis_get_dev_name(void) +{ + return "fTPM"; +} + +static tpm_result_t crb_tpm_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, uint8_t *recvbuf, + size_t *rbuf_len) +{ + int len = crb_tpm_process_command(sendbuf, sbuf_size, recvbuf, *rbuf_len); + + if (len <= 0) + return TPM_CB_FAIL; + + *rbuf_len = len; + + return TPM_SUCCESS; +} + +tis_sendrecv_fn crb_tis_probe(enum tpm_family *family) +{ + /* Wake TPM up (if necessary) */ + if (crb_tpm_init()) + return NULL; + + /* CRB interface exists only in TPM2 */ + if (family != NULL) + *family = TPM_2; + + printk(BIOS_INFO, "Initialized TPM device %s\n", tis_get_dev_name()); + + return &crb_tpm_sendrecv; +} + +static void tpm_start_func0_cb(void *arg) +{ + /* Function 1. */ + acpigen_write_return_singleton_buffer(0x3); +} +static void tpm_start_func1_cb(void *arg) +{ + /* Just return success. fTPM is already operational. */ + acpigen_write_return_byte(0); +} + +static void (*tpm_start_callbacks[])(void *) = { + tpm_start_func0_cb, + tpm_start_func1_cb, +}; + +#define TPM_START_UUID "6bbf6cab-5463-4714-b7cd-f0203c0368d4" + +static void crb_tpm_fill_ssdt(const struct device *dev) +{ + assert(dev->path.type == DEVICE_PATH_MMIO); + assert(dev->path.mmio.addr == crb_tpm_base_address()); + + /* Device */ + acpigen_write_scope("\\_SB"); + acpigen_write_device(acpi_device_name(dev)); + + acpigen_write_name_string("_HID", "MSFT0101"); + acpigen_write_name_string("_CID", "MSFT0101"); + + acpi_device_write_uid(dev); + + if (crb_tpm_is_active()) + acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON); + else + acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_OFF); + + /* Resources */ + acpigen_write_name("_CRS"); + acpigen_write_resourcetemplate_header(); + acpigen_write_mem32fixed(1, read32(CRB_REG(CRB_REG_CMD_ADDR)), + read32(CRB_REG(CRB_REG_CMD_SIZE))); + acpigen_write_mem32fixed(1, read32(CRB_REG(CRB_REG_RESP_ADDR)), + read32(CRB_REG(CRB_REG_RESP_SIZE))); + acpigen_write_resourcetemplate_footer(); + + /* + * _DSM method + */ + struct dsm_uuid ids[] = { + DSM_UUID(TPM_START_UUID, tpm_start_callbacks, + ARRAY_SIZE(tpm_start_callbacks), NULL), + }; + + acpigen_write_dsm_uuid_arr(ids, ARRAY_SIZE(ids)); + + acpigen_pop_len(); /* Device */ + acpigen_pop_len(); /* Scope */ +} + +static const char *crb_tpm_acpi_name(const struct device *dev) +{ + return "TPM2"; +} + +#if CONFIG(GENERATE_SMBIOS_TABLES) +static tpm_result_t tpm_get_cap(uint32_t property, uint32_t *value) +{ + TPMS_CAPABILITY_DATA cap_data; + int i; + tpm_result_t rc; + + if (!value) + return TPM_CB_INVALID_ARG; + + rc = tlcl2_get_capability(TPM_CAP_TPM_PROPERTIES, property, 1, &cap_data); + + if (rc) + return rc; + + for (i = 0; i < cap_data.data.tpmProperties.count; i++) { + if (cap_data.data.tpmProperties.tpmProperty[i].property == property) { + *value = cap_data.data.tpmProperties.tpmProperty[i].value; + return TPM_SUCCESS; + } + } + + return TPM_CB_FAIL; +} + +static int smbios_write_type43_tpm(struct device *dev, int *handle, unsigned long *current) +{ + uint32_t tpm_manuf, tpm_family; + uint32_t fw_ver1, fw_ver2; + uint8_t major_spec_ver, minor_spec_ver; + + /* Vendor ID is the value returned by TPM2_GetCapabiltiy TPM_PT_MANUFACTURER */ + if (tpm_get_cap(TPM_PT_MANUFACTURER, &tpm_manuf)) { + printk(BIOS_DEBUG, "TPM2_GetCap TPM_PT_MANUFACTURER failed\n"); + return 0; + } + + tpm_manuf = be32toh(tpm_manuf); + + if (tpm_get_cap(TPM_PT_FIRMWARE_VERSION_1, &fw_ver1)) { + printk(BIOS_DEBUG, "TPM2_GetCap TPM_PT_FIRMWARE_VERSION_1 failed\n"); + return 0; + } + + if (tpm_get_cap(TPM_PT_FIRMWARE_VERSION_2, &fw_ver2)) { + printk(BIOS_DEBUG, "TPM2_GetCap TPM_PT_FIRMWARE_VERSION_2 failed\n"); + return 0; + } + + if (tpm_get_cap(TPM_PT_FAMILY_INDICATOR, &tpm_family)) { + printk(BIOS_DEBUG, "TPM2_GetCap TPM_PT_FAMILY_INDICATOR failed\n"); + return 0; + } + + tpm_family = be32toh(tpm_family); + + if (!strncmp((char *)&tpm_family, "2.0", 4)) { + major_spec_ver = 2; + minor_spec_ver = 0; + } else { + printk(BIOS_ERR, "%s: Invalid TPM family\n", __func__); + return 0; + } + + return smbios_write_type43(current, handle, tpm_manuf, major_spec_ver, minor_spec_ver, + fw_ver1, fw_ver2, tis_get_dev_name(), + SMBIOS_TPM_DEVICE_CHARACTERISTICS_NOT_SUPPORTED, 0); +} +#endif + +static struct device_operations __maybe_unused amd_crb_ops = { + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_name = crb_tpm_acpi_name, + .acpi_fill_ssdt = crb_tpm_fill_ssdt, +#endif +#if CONFIG(GENERATE_SMBIOS_TABLES) + .get_smbios_data = smbios_write_type43_tpm, +#endif +}; + +static void enable_dev(struct device *dev) +{ +#if !DEVTREE_EARLY + dev->ops = &amd_crb_ops; +#endif +} + +struct chip_operations drivers_amd_ftpm_ops = { + .name = "AMD CRB fTPM", + .enable_dev = enable_dev +}; diff --git a/src/drivers/amd/ftpm/tpm.c b/src/drivers/amd/ftpm/tpm.c new file mode 100644 index 00000000000..e5ab0dea39a --- /dev/null +++ b/src/drivers/amd/ftpm/tpm.c @@ -0,0 +1,307 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* + * This is a driver for the AMD fTPM CRB Interface. + * + * The AMD fTPM uses the CRB interface, but doesn't implement all registers + * defined in the TCG specification. + * + * The reduced CRB MMIO register space has: + * - A START register to ring the doorbell + * - An error STATUS register with only one bit + * - DMA address and size register for the CRB + * - No other status or control registers + * - No way to read current locality (assumption is locality 0) + * - No interface ID register + * - No read only registers + * + * The TPM interface also assumes that the DRTM is always using locality 0. + * + * The fTPM needs to access the SPI flash and this is currently done using + * the PSP SMI handler. Thus the fTPM will only operate after SMM has been + * set up. + * + * The fTPM needs the PSP directory files type 0x04 and type 0x54. When + * the regions are missing or corrupted the fTPM won't be operational. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tpm.h" + +/* FMAP regions used */ +#define FMAP_NAME_PSP_NVRAM "PSP_NVRAM" +#define FMAP_NAME_PSP_RPMC_NVRAM "PSP_RPMC_NVRAM" + +/* Size of DMA buffer in DRAM */ +#define FTPM_CRB_SIZE (4 * 4096) + +/* Index of Count field in TPM response buffer */ +#define TPM_RSP_SIZE_BYTE 2 + +static struct control_area { + uint32_t start; + uint32_t command_size; + void *command_bfr; + uint32_t response_size; + void *response_bfr; +} control_area; + +/* Read Control Area Structure back */ +static void crb_read_control_area(void) +{ + control_area.command_size = read32(CRB_REG(CRB_REG_CMD_SIZE)); + control_area.command_bfr = + (void *)(uintptr_t)read64(CRB_REG(CRB_REG_CMD_ADDR)); + control_area.response_size = read32(CRB_REG(CRB_REG_RESP_SIZE)); + control_area.response_bfr = + (void *)(uintptr_t)read64(CRB_REG(CRB_REG_RESP_ADDR)); +} + +/* Wait for reg to be expected value */ +static tpm_result_t crb_wait_for_reg32(const void *addr, + uint32_t timeout_ms, + uint32_t mask, + uint32_t expected_value) +{ + uint32_t reg_value; + struct stopwatch sw; + + // Set up a timer which breaks the loop after timeout + stopwatch_init_msecs_expire(&sw, timeout_ms); + + while (1) { + // Now check if the TPM is in IDLE mode + reg_value = read32(addr); + + if ((reg_value & mask) == expected_value) + return TPM_SUCCESS; + + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, + "fTPM: Timed out with reg_value: %08x, mask: %08x, expected: %08x\n", + reg_value, mask, expected_value); + return TPM_CB_TIMEOUT; + } + } +} + +static int erase_region(const char *name) +{ + struct region_device store; + + if (fmap_locate_area_as_rdev_rw(name, &store)) { + printk(BIOS_ERR, "fTPM: Unable to find FMAP region %s\n", name); + return -1; + } + + if (rdev_eraseat(&store, 0, region_device_sz(&store)) + != region_device_sz(&store)) + return -1; + + printk(BIOS_NOTICE, "fTPM: Erased FMAP region %s\n", name); + + return 0; +} + +/* + * crb_tpm_init + * + * Even though the TPM does not need an initialization we check + * if the TPM responds and is in IDLE mode, which should be the + * normal bring up mode. + */ +tpm_result_t crb_tpm_init(void) +{ + bool psp_rpmc_nvram, psp_nvram, psp_dir; + + /* + * When recovery is required psp_ftpm_is_active() always returns false. + * Thus handle recovery before checking if fTPM is usable. + */ + psp_ftpm_needs_recovery(&psp_rpmc_nvram, &psp_nvram, &psp_dir); + + if (psp_rpmc_nvram) { + if (erase_region(FMAP_NAME_PSP_RPMC_NVRAM)) + psp_rpmc_nvram = false; /* Skip reset if erase failed */ + } + + if (psp_nvram) { + if (erase_region(FMAP_NAME_PSP_NVRAM)) + psp_nvram = false; /* Skip reset if erase failed */ + } + + if (psp_rpmc_nvram || psp_nvram) { + printk(BIOS_DEBUG, "fTPM: Reset to recover fTPM...\n"); + cold_reset(); + } + + if (psp_dir) { + printk(BIOS_ERR, "fTPM: fTPM driver corrupted. Need FW update.\n"); + return CB_ERR; + } + + if (!psp_ftpm_is_active()) + return CB_ERR_NOT_IMPLEMENTED; + + if (ENV_HAS_CBMEM) { + /* setting up fTPM communication buffers in cbmem */ + const struct cbmem_entry *entry; + void *buf; + uint32_t length = 2 * FTPM_CRB_SIZE; + + /* Only allocate once */ + entry = cbmem_entry_find(CBMEM_ID_TPM2_CRB); + if (entry) { + buf = cbmem_entry_start(entry); + length = cbmem_entry_size(entry); + } else { + buf = cbmem_add(CBMEM_ID_TPM2_CRB, length); + if (!buf) { + printk(BIOS_ERR, "fTPM: CBMEM CRB buffer allocation failed\n"); + return CB_ERR; + } + printk(BIOS_DEBUG, "fTPM: CRB buffer created at %p\n", buf); + memset(buf, 0, length); + } + + /* Set command/response buffers in control area */ + write32(CRB_REG(CRB_REG_CMD_SIZE), FTPM_CRB_SIZE); + write64(CRB_REG(CRB_REG_CMD_ADDR), (uintptr_t)buf); + write32(CRB_REG(CRB_REG_RESP_SIZE), FTPM_CRB_SIZE); + write64(CRB_REG(CRB_REG_RESP_ADDR), (uintptr_t)buf + FTPM_CRB_SIZE); + + /* + * The OS will read the CRB registers to find the communication + * buffers. No need to advertise it in ACPI. + */ + } + + /* Read back control area structure */ + crb_read_control_area(); + + /* Opt out when CRB hasn't been set up yet */ + if (!control_area.command_size || !control_area.response_size) + return CB_ERR_NOT_IMPLEMENTED; + + /* Good to go. */ + printk(BIOS_SPEW, "fTPM: CRB TPM initialized successfully\n"); + + return TPM_SUCCESS; +} + +/* + * crb_tpm_process_command + * + * Transfers data to and from the fTPM. + * + */ +size_t crb_tpm_process_command(const void *tpm2_command, size_t command_size, + void *tpm2_response, size_t max_response) +{ + uint32_t rsp_size; + tpm_result_t rc; + + if (!control_area.response_size || !control_area.command_size) { + printk(BIOS_ERR, "%s: Control area wasn't set up yet\n", __func__); + return -1; + } + if (command_size > control_area.command_size) { + printk(BIOS_ERR, "%s: Command size is too big: %zu > %u.\n", + __func__, command_size, control_area.command_size); + return -1; + } + + /* Check if CMD bit is cleared. */ + rc = crb_wait_for_reg32(CRB_REG(CRB_REG_START), 250, CRB_REG_START_START, 0x0); + if (rc) { + printk(BIOS_ERR, "%s: Cmd Bit didn't clear\n", __func__); + return -1; + } + + /* Write to Command Buffer */ + memcpy(control_area.command_bfr, tpm2_command, command_size); + + /* Clear Response buffer */ + memset(control_area.response_bfr, 0, control_area.response_size); + + /* Set Response size */ + write32(CRB_REG(CRB_REG_RESP_SIZE), control_area.response_size); + + /* Write Start Bit */ + write8(CRB_REG(CRB_REG_START), CRB_REG_START_START); + + /* Poll for Response */ + rc = crb_wait_for_reg32(CRB_REG(CRB_REG_START), 3500, CRB_REG_START_START, 0); + if (rc) { + printk(BIOS_DEBUG, "%s: Timeout waiting for CMD processing\n", __func__); + return -1; + } + + /* Check for errors */ + rc = read32(CRB_REG(CRB_REG_STATUS)); + if (rc & CRB_REG_STATUS_ERROR) { + printk(BIOS_DEBUG, "fTPM Error (%#x): Command errored.\n", rc); + return -1; + } + + /* Get Response Length. Seems to be static on some platforms. */ + uint32_t length = read32(CRB_REG(CRB_REG_RESP_SIZE)); + assert(length <= control_area.response_size); + + /* Response has to have at least 6 bytes */ + if (length < 6) { + printk(BIOS_DEBUG, "fTPM Error: Invalid response length: %u\n", length); + return -1; + } + + /* Get actual size from TPM packet */ + memcpy(&rsp_size, control_area.response_bfr + TPM_RSP_SIZE_BYTE, sizeof(rsp_size)); + rsp_size = be32_to_cpu(rsp_size); + if ((size_t)rsp_size > max_response) { + printk(BIOS_DEBUG, "fTPM Error: Response wouldn't fit into target buffer: %u > %zu\n", + rsp_size, max_response); + return -1; + } + + /* Copy Response */ + length = MIN(length, MIN(max_response, rsp_size)); + memcpy(tpm2_response, control_area.response_bfr, length); + + return length; +} + +/* + * crb_tpm_is_active + * + * Checks that CRB interface is available and active. + */ +bool crb_tpm_is_active(void) +{ + if (!psp_ftpm_is_active()) + return false; + + /* Read back control area structure */ + crb_read_control_area(); + + /* Validate fields */ + if (!control_area.command_size || !control_area.response_size || + !control_area.command_bfr || !control_area.response_bfr || + (control_area.command_bfr == (void *)-1) || + (control_area.response_bfr == (void *)-1)) + return false; + + return true; +} + +uintptr_t crb_tpm_base_address(void) +{ + return psp_ftpm_base_address(); +} diff --git a/src/drivers/amd/ftpm/tpm.h b/src/drivers/amd/ftpm/tpm.h new file mode 100644 index 00000000000..aaae99eb348 --- /dev/null +++ b/src/drivers/amd/ftpm/tpm.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* This is a driver for a Command Response Buffer Interface + * as found on AMD fTPMs. It only implements a small subset + * of the registers defined in the TCG specification. + */ + +#include +#include +#include + +/* CRB hardware registers */ +#define CRB_REG_STATUS 0x44 +#define CRB_REG_STATUS_ERROR 0x01 +#define CRB_REG_START 0x4C +#define CRB_REG_START_START 0x01 +#define CRB_REG_CMD_SIZE 0x58 +#define CRB_REG_CMD_ADDR 0x5C +#define CRB_REG_RESP_SIZE 0x64 +#define CRB_REG_RESP_ADDR 0x68 + +/* address of locality 0 (CRB) */ +#define CRB_REG(REG) ((void *)(uintptr_t)(psp_ftpm_base_address() + (REG))) + +tpm_result_t crb_tpm_init(void); +size_t crb_tpm_process_command(const void *tpm2_command, size_t command_size, + void *tpm2_response, size_t max_response); +bool crb_tpm_is_active(void); + +tis_sendrecv_fn crb_tis_probe(enum tpm_family *family); + +uintptr_t crb_tpm_base_address(void); diff --git a/src/drivers/amd/opensil/Makefile.mk b/src/drivers/amd/opensil/Makefile.mk index 6ed46d1f819..08918bc36d5 100644 --- a/src/drivers/amd/opensil/Makefile.mk +++ b/src/drivers/amd/opensil/Makefile.mk @@ -7,6 +7,7 @@ subdirs-y += mpio romstage-y += romstage.c ramstage-y += acpi.c +ramstage-y += dmi.c ramstage-y += ramstage.c ramstage-y += memmap.c diff --git a/src/drivers/amd/opensil/dmi.c b/src/drivers/amd/opensil/dmi.c new file mode 100644 index 00000000000..0cedb74c9be --- /dev/null +++ b/src/drivers/amd/opensil/dmi.c @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include "opensil.h" + +__weak void opensil_smbios_fill_cbmem_meminfo(void) { } + +static void prepare_dmi_17(void *unused) +{ + opensil_smbios_fill_cbmem_meminfo(); +} + +BOOT_STATE_INIT_ENTRY(BS_DEV_ENUMERATE, BS_ON_ENTRY, prepare_dmi_17, NULL); diff --git a/src/drivers/amd/opensil/opensil.h b/src/drivers/amd/opensil/opensil.h index e6efbdc80a9..7cc7ad80c9f 100644 --- a/src/drivers/amd/opensil/opensil.h +++ b/src/drivers/amd/opensil/opensil.h @@ -5,6 +5,7 @@ #include #include +#include /* Set up openSIL env and call TP1 */ void amd_opensil_silicon_init(void); @@ -14,5 +15,9 @@ void configure_mpio(void); void amd_opensil_add_memmap(struct device *dev, unsigned long *idx); /* Fill in FADT from openSIL */ void amd_opensil_fill_fadt_io_ports(acpi_fadt_t *fadt); +/* Marshalls dimm info from SIL_DMI_INFO into CBMEM_ID_MEMINFO */ +void opensil_smbios_fill_cbmem_meminfo(void); +/* Fill DIMM locators using OpenSIL DMI info, returns 0 on success */ +int opensil_smbios_fill_dimm_locator(const struct dimm_info *dimm, struct smbios_type17 *t); #endif /* OPENSIL_DRIVER_H */ diff --git a/src/drivers/generic/gpio_keys/gpio_keys.c b/src/drivers/generic/gpio_keys/gpio_keys.c index f5df0c45bce..e837e041585 100644 --- a/src/drivers/generic/gpio_keys/gpio_keys.c +++ b/src/drivers/generic/gpio_keys/gpio_keys.c @@ -86,7 +86,7 @@ static void gpio_keys_fill_ssdt_generator(const struct device *dev) acpi_dp_add_child(dsd, "button-0", child); acpi_dp_write(dsd); - acpigen_write_STA(acpi_device_status(dev)); + acpigen_write_STA(ACPI_STATUS_DEVICE_HIDDEN_ON); acpigen_pop_len(); /* Device */ acpigen_pop_len(); /* Scope */ diff --git a/src/drivers/genesyslogic/gl9763e/gl9763e.c b/src/drivers/genesyslogic/gl9763e/gl9763e.c index 98e69bb3f8d..a80a3d48db9 100644 --- a/src/drivers/genesyslogic/gl9763e/gl9763e.c +++ b/src/drivers/genesyslogic/gl9763e/gl9763e.c @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #include "gl9763e.h" static void gl9763e_init(struct device *dev) @@ -54,12 +57,59 @@ static void gl9763e_init(struct device *dev) pci_update_config32(dev, VHS, ~VHS_REV_MASK, VHS_REV_R); } +/* + * Generate ACPI device for on-board eMMC (SD Host Controller + fixed CARD) under the + * root port so the OS sees non-removable storage. Scope is the parent root port + * (e.g. \_SB.PCI0.RP09). + * + * Generated ASL: + * Scope (\_SB.PCI0.RPxx) { + * Device (EMMC) { + * Name (_ADR, 0x00000000) + * Device (CARD) { + * Name (_ADR, 0x00000008) + * Method (_RMV, 0, NotSerialized) { + * Return (0) // Fixed (not removable) + * } + * } + * } + * } + */ +static void gl9763e_fill_ssdt(const struct device *dev) +{ + const char *scope; + + if (!is_dev_enabled(dev)) + return; + + scope = acpi_device_scope(dev); + if (!scope) + return; + + /* Emit EMMC device under root port so OS sees fixed (non-removable) storage */ + acpigen_write_scope(scope); + acpigen_write_device("EMMC"); + acpigen_write_name_integer("_ADR", 0x0); + + /* CARD child: slot at address 0x08, not removable */ + acpigen_write_device("CARD"); + acpigen_write_name_integer("_ADR", 0x8); + acpigen_write_method_serialized("_RMV", 0); + acpigen_write_return_integer(0); /* Fixed (not removable) */ + acpigen_write_method_end(); + acpigen_write_device_end(); /* CARD */ + + acpigen_write_device_end(); /* EMMC */ + acpigen_write_scope_end(); +} + static struct device_operations gl9763e_ops = { .read_resources = pci_dev_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, .ops_pci = &pci_dev_ops_pci, .init = gl9763e_init, + .acpi_fill_ssdt = gl9763e_fill_ssdt, }; static const unsigned short pci_device_ids[] = { diff --git a/src/drivers/gfx/nvidia/Kconfig b/src/drivers/gfx/nvidia/Kconfig new file mode 100644 index 00000000000..eb2d60dff65 --- /dev/null +++ b/src/drivers/gfx/nvidia/Kconfig @@ -0,0 +1,39 @@ +config DRIVERS_GFX_NVIDIA + bool + default n + depends on HAVE_ACPI_TABLES + help + Support for NVIDIA Optimus graphics + +config DRIVERS_GFX_NVIDIA_BRIDGE + hex "PCI bridge for the GPU device" + default 0x01 + depends on DRIVERS_GFX_NVIDIA + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + depends on DRIVERS_GFX_NVIDIA + bool + default n + help + Support for NVIDIA Dynamic Boost + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP + int "Total processor power offset from default TGP in watts" + default 45 + depends on DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + help + This identifies the available power for the CPU or GPU boost + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MIN + int "Minimum TGP offset from default TGP in watts" + default 0 + depends on DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + help + This is used to transfer power from the GPU to the CPU + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX + int "Maximum TGP offset from default TGP in watts" + default 0 + depends on DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + help + This is used to transfer power from the CPU to the GPU diff --git a/src/drivers/gfx/nvidia/Makefile.mk b/src/drivers/gfx/nvidia/Makefile.mk new file mode 100644 index 00000000000..32ddf7e64e5 --- /dev/null +++ b/src/drivers/gfx/nvidia/Makefile.mk @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +romstage-$(CONFIG_DRIVERS_GFX_NVIDIA) += romstage.c + +ramstage-$(CONFIG_DRIVERS_GFX_NVIDIA) += nvidia.c diff --git a/src/drivers/gfx/nvidia/acpi/coffeelake.asl b/src/drivers/gfx/nvidia/acpi/coffeelake.asl new file mode 100644 index 00000000000..c515ec1cb29 --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/coffeelake.asl @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* NVIDIA GC6 on CFL and CML CPU PCIe ports */ + +// Memory mapped PCI express config space +OperationRegion (PCIC, SystemMemory, CONFIG_ECAM_MMCONF_BASE_ADDRESS + (CONFIG_DRIVERS_GFX_NVIDIA_BRIDGE << 15), 0x1000) + +Field (PCIC, ByteAcc, NoLock, Preserve) { + PVID, 16, + PDID, 16, + + Offset (0x248), + , 7, + L23E, 1, /* L23_Rdy Entry Request */ + L23R, 1, /* L23_Rdy to Detect Transition */ + + Offset (0xC20), + , 4, + P0AP, 2, /* Additional power savings */ + + Offset (0xC38), + , 3, + P0RM, 1, /* Robust squelch mechanism */ +} + +// Enter L23 +Method (DL23, 0, Serialized) { + Printf(" GPU PORT DL23 START") + + L23E = 1 + Sleep (16) + Local0 = 0 + While (L23E) { + If ((Local0 > 4)) { + Break + } + + Sleep (16) + Local0++ + } + + P0RM = 1 + P0AP = 3 + + Printf(" GPU PORT DL23 FINISH") +} + +// Exit L23 +Method (L23D, 0, Serialized) { + Printf(" GPU PORT L23D START") + + L23R = 1 + Sleep (16) + Local0 = 0 + While (L23R) { + If ((Local0 > 4)) { + Break + } + + Sleep (16) + Local0++ + } + + P0RM = 0 + P0AP = 0 + + Printf(" GPU PORT L23D FINISH") +} + +// Main power resource +PowerResource (PWRR, 0, 0) { + Name (_STA, 1) + + Method (_ON, 0, Serialized) { + Printf("GPU PORT PWRR._ON") + + ^^DEV0._ON() + + _STA = 1 + } + + Method (_OFF, 0, Serialized) { + Printf("GPU PORT PWRR._OFF") + + ^^DEV0._OFF() + + _STA = 0 + } +} + +// Power resources for entering D0 +Name (_PR0, Package () { PWRR }) + +// Power resources for entering D3 +Name (_PR3, Package () { PWRR }) + +#include "common/gpu.asl" diff --git a/src/drivers/gfx/nvidia/acpi/common/dsm.asl b/src/drivers/gfx/nvidia/acpi/common/dsm.asl new file mode 100644 index 00000000000..ad440b58b74 --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/dsm.asl @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define NV_ERROR_SUCCESS 0x0 +#define NV_ERROR_UNSPECIFIED 0x80000001 +#define NV_ERROR_UNSUPPORTED 0x80000002 + +#include "gps.asl" +#include "nvjt.asl" + +Method (_DSM, 4, Serialized) { + Printf("GPU _DSM") + If (Arg0 == ToUUID (JT_DSM_GUID)) { + If (ToInteger(Arg1) >= JT_REVISION_ID_MIN) { + Return (NVJT(Arg2, Arg3)) + } Else { + Printf(" Unsupported JT revision: %o", SFST(Arg1)) + Return (NV_ERROR_UNSUPPORTED) + } + } ElseIf (Arg0 == ToUUID (GPS_DSM_GUID)) { + If (ToInteger(Arg1) == GPS_REVISION_ID) { + Return (GPS(Arg2, Arg3)) + } Else { + Printf(" Unsupported GPS revision: %o", SFST(Arg1)) + Return (NV_ERROR_UNSUPPORTED) + } + } Else { + Printf(" Unsupported GUID: %o", IDST(Arg0)) + Return (NV_ERROR_UNSPECIFIED) + } +} diff --git a/src/drivers/gfx/nvidia/acpi/common/gps.asl b/src/drivers/gfx/nvidia/acpi/common/gps.asl new file mode 100644 index 00000000000..7d69b194066 --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/gps.asl @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define GPS_DSM_GUID "A3132D01-8CDA-49BA-A52E-BC9D46DF6B81" +#define GPS_REVISION_ID 0x00000200 +#define GPS_FUNC_SUPPORT 0x00000000 +#define GPS_FUNC_PSHARESTATUS 0x00000020 +#define GPS_FUNC_PSHAREPARAMS 0x0000002A + +Method(GPS, 2, Serialized) { + Printf(" GPU GPS") + Switch(ToInteger(Arg0)) { + Case(GPS_FUNC_SUPPORT) { + Printf(" Supported Functions") + Return(ITOB( + (1 << GPS_FUNC_SUPPORT) | + (1 << GPS_FUNC_PSHARESTATUS) | + (1 << GPS_FUNC_PSHAREPARAMS) + )) + } + Case(GPS_FUNC_PSHARESTATUS) { + Printf(" Power Share Status") + Return(ITOB(0)) + } + Case(GPS_FUNC_PSHAREPARAMS) { + Printf(" Power Share Parameters") + + CreateField(Arg1, 0, 4, QTYP) // Query type + + Name(GPSP, Buffer(36) { 0x00 }) + CreateDWordField(GPSP, 0, RSTS) // Response status + CreateDWordField(GPSP, 4, VERS) // Version + + // Set query type of response + RSTS = QTYP + // Set version of response + VERS = 0x00010000 + + Switch(ToInteger(QTYP)) { + Case(0) { + Printf(" Request Current Information") + // No required information + Return(GPSP) + } + Case(1) { + Printf(" Request Supported Fields") + // Support GPU temperature field + RSTS |= (1 << 8) + Return(GPSP) + } + Case(2) { + Printf(" Request Current Limits") + // No required limits + Return(GPSP) + } + Default { + Printf(" Unknown Query: %o", SFST(QTYP)) + Return(NV_ERROR_UNSUPPORTED) + } + } + } + Default { + Printf(" Unsupported function: %o", SFST(Arg0)) + Return(NV_ERROR_UNSUPPORTED) + } + } +} diff --git a/src/drivers/gfx/nvidia/acpi/common/gpu.asl b/src/drivers/gfx/nvidia/acpi/common/gpu.asl new file mode 100644 index 00000000000..49e5c47285b --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/gpu.asl @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Device (DEV0) { + Name(_ADR, 0x00000000) + + #include "utility.asl" + #include "dsm.asl" + #include "power.asl" +} + +#if CONFIG(DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST) +Scope (\_SB) { + Device(NPCF) { + #include "utility.asl" + #include "nvpcf.asl" + } +} +#endif diff --git a/src/drivers/gfx/nvidia/acpi/common/nvjt.asl b/src/drivers/gfx/nvidia/acpi/common/nvjt.asl new file mode 100644 index 00000000000..31eaed275e8 --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/nvjt.asl @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define JT_DSM_GUID "CBECA351-067B-4924-9CBD-B46B00B86F34" +#define JT_REVISION_ID_MIN 0x00000100 +#define JT_REVISION_ID_MAX 0x00000200 +#define JT_FUNC_SUPPORT 0x00000000 +#define JT_FUNC_CAPS 0x00000001 +#define JT_FUNC_POWERCONTROL 0x00000003 + +//TODO: SMI traps and EGIN/XCLM +#define JT_GPC_GSS 0 // Get current GPU GCx sleep status +#define JT_GPC_EGNS 1 // Enter GC6 without self-refresh +#define JT_GPC_EGIS 2 // Enter GC6 with self-refresh +#define JT_GPC_XGXS 3 // Exit GC6 and stop self-refresh +#define JT_GPC_XGIS 4 // Exit GC6 for self-refresh update + +#define JT_DFGC_NONE 0 // Handle request immediately +#define JT_DFGC_DEFER 1 // Defer GPC and GPCX +//TODO #define JT_DFGC_CLEAR 2 // Clear pending requests + +// Deferred GC6 enter/exit until D3-cold (saved DFGC) +Name(DFEN, 0) + +// Deferred GC6 enter control (saved GPC) +Name(DFCI, 0) + +// Deferred GC6 exit control (saved GPCX) +Name(DFCO, 0) + +Method (NVJT, 2, Serialized) { + Printf(" GPU NVJT") + Switch (ToInteger(Arg0)) { + Case (JT_FUNC_SUPPORT) { + Printf(" Supported Functions") + Return(ITOB( + (1 << JT_FUNC_SUPPORT) | + (1 << JT_FUNC_CAPS) | + (1 << JT_FUNC_POWERCONTROL) + )) + } + Case (JT_FUNC_CAPS) { + Printf(" Capabilities") + Return(ITOB( + (1 << 0) | // G-SYNC NSVR power-saving features are enabled + (1 << 1) | // NVSR disabled + (2 << 3) | // Panel power and backlight are on the suspend rail + (0 << 5) | // self-refresh controller remains powered while panel is powered + (0 << 6) | // FB is not on the suspend rail but is powered on in GC6 + (0 << 8) | // Combined power rail for all GPUs + (0 << 10) | // External SPI ROM + (1 << 11) | // No SMI handler for kernel panic exit while in GC6 + (0 << 12) | // Supports notify on GC6 state done + (1 << 13) | // Support deferred GC6 + (1 << 14) | // Support fine-grained root port control + (2 << 15) | // GC6 version is GC6-R + (0 << 17) | // GC6 exit ISR is not supported + (0 << 18) | // GC6 self wakeup not supported + (JT_REVISION_ID_MAX << 20) // Highest revision supported + )) + } + Case (JT_FUNC_POWERCONTROL) { + Printf(" Power Control: %o", SFST(Arg1)) + + CreateField (Arg1, 0, 3, GPC) // GPU power control + CreateField (Arg1, 4, 1, PPC) // Panel power control + CreateField (Arg1, 14, 2, DFGC) // Defer GC6 enter/exit until D3 cold + CreateField (Arg1, 16, 3, GPCX) // Deferred GC6 exit control + + // Save deferred GC6 request + If ((ToInteger(GPC) != 0) || (ToInteger(DFGC) != 0)) { + DFEN = DFGC + DFCI = GPC + DFCO = GPCX + } + + // Buffer to cache current state + Name (JTBF, Buffer (4) { 0, 0, 0, 0 }) + CreateField (JTBF, 0, 3, CGCS) // Current GC state + CreateField (JTBF, 3, 1, CGPS) // Current GPU power status + CreateField (JTBF, 7, 1, CPSS) // Current panel and SRC state (0 when on) + + // If doing deferred GC6 request, return now + If (ToInteger(DFGC) != 0) { + CGCS = 1 + CGPS = 1 + Return (JTBF) + } + + // Apply requested state + Switch (ToInteger(GPC)) { + Case (JT_GPC_GSS) { + Printf(" Get current GPU GCx sleep status") + //TODO: include transitions! + If (GTXS(DGPU_RST_N)) { + // GPU powered on + CGCS = 1 + CGPS = 1 + } ElseIf (GTXS(DGPU_PWR_EN)) { + // GPU powered off, GC6 + CGCS = 3 + CGPS = 0 + } Else { + // GPU powered off, D3 cold + CGCS = 2 + CGPS = 0 + } + } + Case (JT_GPC_EGNS) { + Printf(" Enter GC6 without self-refresh") + GC6I() + CPSS = 1 + } + Case (JT_GPC_EGIS) { + Printf(" Enter GC6 with self-refresh") + GC6I() + If (ToInteger(PPC) == 0) { + CPSS = 0 + } + } + Case (JT_GPC_XGXS) { + Printf(" Exit GC6 and stop self-refresh") + GC6O() + + CGCS = 1 + CGPS = 1 + If (ToInteger(PPC) != 0) { + CPSS = 0 + } + } + Case (JT_GPC_XGIS) { + Printf(" Exit GC6 for self-refresh update") + GC6O() + + CGCS = 1 + CGPS = 1 + If (ToInteger(PPC) != 0) { + CPSS = 0 + } + } + Default { + Printf(" Unsupported GPU power control: %o", SFST(GPC)) + } + } + + Return (JTBF) + } + Default { + Printf(" Unsupported function: %o", SFST(Arg0)) + Return (NV_ERROR_UNSUPPORTED) + } + } +} diff --git a/src/drivers/gfx/nvidia/acpi/common/nvpcf.asl b/src/drivers/gfx/nvidia/acpi/common/nvpcf.asl new file mode 100644 index 00000000000..6ecbd05191b --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/nvpcf.asl @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define NVPCF_DSM_GUID "36b49710-2483-11e7-9598-0800200c9a66" +#define NVPCF_REVISION_ID 0x200 + +#define NVPCF_ERROR_SUCCESS 0 +#define NVPCF_ERROR_GENERIC 0x80000001 +#define NVPCF_ERROR_UNSUPPORTED 0x80000002 + +#define NVPCF_FUNC_GET_SUPPORTED 0 // Required +#define NVPCF_FUNC_GET_STATIC_CONFIG_TABLES 1 // Required +#define NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS 2 // Required +#define NVPCF_FUNC_GET_WM2_TBAND_TABLES 3 +#define NVPCF_FUNC_GET_WM2_SL_MAP_TABLES 4 +#define NVPCF_FUNC_GET_WM2_DYNAMIC_PARAMS 5 +#define NVPCF_FUNC_CPU_CONTROL 6 +#define NVPCF_FUNC_GPU_INFO 7 +#define NVPCF_FUNC_GET_DC_SYSTEM_POWER_LIMITS_TABLE 8 +#define NVPCF_FUNC_CPU_TDP_CONTROL 9 +#define NVPCF_FUNC_GET_DC_TPP_LIMIT_PREFERENCE 10 +#define NVPCF_FUNC_GET_THERMAL_ZONE_STATUS 11 + +Name (DBAC, 0) // Disable GPU Boost on AC +Name (DBDC, 0) // Disable GPU Boost on DC (XXX: Proprietary default disables on DC) + +Name (_HID, "NVDA0820") +Name (_UID, "NPCF") + +Method (_STA, 0, NotSerialized) +{ + Return (0x0F) // ACPI_STATUS_DEVICE_ALL_ON +} + +Method (_DSM, 4, Serialized) +{ + If (Arg0 == ToUUID (NVPCF_DSM_GUID)) { + Printf ("NVPCF DSM") + If (ToInteger (Arg1) == NVPCF_REVISION_ID) { + Return (NPCF (Arg2, Arg3)) + } Else { + Printf (" NVPCF: Unsupported revision: %o", Arg1) + } + } + Else { + Printf (" NVPCF: Unsupported GUID: %o", IDST (Arg0)) + } + + Return (NVPCF_ERROR_GENERIC) +} + +Method (NPCF, 2, Serialized) +{ + Switch (ToInteger (Arg0)) { + Case (NVPCF_FUNC_GET_SUPPORTED) { + Printf (" NVPCF[0]: GET_SUPPORTED") + Return (ITOB ( + (1 << NVPCF_FUNC_GET_SUPPORTED) | + (1 << NVPCF_FUNC_GET_STATIC_CONFIG_TABLES) | + (1 << NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS) + )) + } + Case (NVPCF_FUNC_GET_STATIC_CONFIG_TABLES) { + Printf (" NVPCF[1]: GET_STATIC_CONFIG_TABLE") + Return (Buffer (14) { + // System Device Table Header (v2.0) + 0x20, 0x03, 0x01, + // System Device Table Entries + // [3:0] CPU Type (0=Intel, 1=AMD) + // [7:4] GPU Type (0=Nvidia) + 0x00, + // System Controller Table Header (v2.3) + 0x23, 0x04, 0x05, 0x01, + // System Controller Table Controller Entry + // Controller Flags + // [3:0] Controller Class Type + // 0=Disabled + // 1=Dynamic Boost Controller + // 2=Configurable TGP-only Controller + // [7:4] Reserved + 0x01, + // Controller Params + // [0:0] DC support (0=Not supported, 1=Supported) + // [31:1] Reserved + 0x01, 0x00, 0x00, 0x00, + // Single byte checksum value + 0xAD + }) + } + Case (NVPCF_FUNC_UPDATE_DYNAMIC_PARAMS) { + Printf (" NVPCF[2]: UPDATE_DYNAMIC_PARAMS") + + // Dynamic Params Common Status, Input + // 0=Get Controller Params + // 1=Set Controller Status + CreateField (Arg1, 0x28, 2, ICMD) + + // XXX: All input params unused? + // Controller Entry, Input + //CreateByteField (Arg1, 0x15, IIDX) // Controller index + //CreateField (Arg1, 0xB0, 0x01, PWCS) // Power control capability (0=Disabled, 1=Enabled) + //CreateField (Arg1, 0xB1, 0x01, PWTS) // Power transfer status (0=Disabled, 1=Enabled) + //CreateField (Arg1, 0xB2, 0x01, CGPS) // CTGP status (0=Disabled, 1=Enabled) + + Name (PBD2, Buffer(49) { + // Dynamic Params Table Header + 0x23, // Version 2.3 + 0x05, // Table header size in bytes + 0x10, // Size of Common Status in bytes + 0x1C, // Size of Controller Entry in bytes + 0x01, // Number of Controller Entries + }) + + // Dynamic Params Common Status, Output + // Baseline (configurable) TGP in AC for the intended TPP + // limit, expressed as a signed offset relative to the + // static TGP rates, AC, in 1/8-watt units. + CreateWordField (PBD2, 0x05, TGPA) + + // Controller Entry, Output - Dynamic Boost Controller + CreateByteField (PBD2, 0x15, OIDX) // Controller index + // Disable controller on AC/DC + // [0:0] Disable controller on AC (0=Enable, 1=Disable) + // [1:1] Disable controller on DC (0=Enable, 1=Disable) + CreateByteField (PBD2, 0x16, PC02) + CreateWordField (PBD2, 0x19, TPPA) // TPP target on AC + CreateWordField (PBD2, 0x1D, MAGA) // Max TGP on AC + CreateWordField (PBD2, 0x21, MIGA) // Min TGP on AC + CreateDWordField (PBD2, 0x25, DROP) // DC Rest of system reserved power + CreateDWordField (PBD2, 0x29, LTBC) // Long Timescale Battery Current Limit + CreateDWordField (PBD2, 0x2D, STBC) // Short Timescale Battery Current Limit + + Switch (ToInteger (ICMD)) { + Case (0) { + Printf (" Get Controller Params") + + TGPA = 0 + OIDX = 0 + PC02 = DBAC | (DBDC << 1) + TPPA = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP << 3) + MAGA = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX << 3) + MIGA = (CONFIG_DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MIN << 3) + + // TODO: Handle v2.3+ fields + + Printf ("PBD2: %o", SFST(PBD2)) + Return (PBD2) + } + Case (1) { + Printf (" Set Controller Status") + + // XXX: Match proprietary firmware behavior, + // which just explicitly sets fields to zero. + TGPA = 0 + OIDX = 0 + PC02 = 0 + TPPA = 0 + MAGA = 0 + MIGA = 0 + + Printf ("PBD2: %o", SFST(PBD2)) + Return (PBD2) + } + Default { + Printf (" Unknown Input Command: %o", SFST(ICMD)) + Return (NV_ERROR_UNSUPPORTED) + } + } + } + Case (NVPCF_FUNC_GET_WM2_TBAND_TABLES) { + Printf (" NVPCF[3]: GET_WM2_TBAND_TABLES") + } + Case (NVPCF_FUNC_GET_WM2_SL_MAP_TABLES) { + Printf (" NVPCF[4]: GET_WM2_SL_MAP_TABLES") + } + Case (NVPCF_FUNC_GET_WM2_DYNAMIC_PARAMS) { + Printf (" NVPCF[5]: GET_WM2_DYNAMIC_PARAMS") + } + Case (NVPCF_FUNC_CPU_CONTROL) { + Printf (" NVPCF[6]: CPU_CONTROL") + } + Case (NVPCF_FUNC_GPU_INFO) { + Printf (" NVPCF[7]: GPU_INFO") + } + Case (NVPCF_FUNC_GET_DC_SYSTEM_POWER_LIMITS_TABLE) { + Printf (" NVPCF[8]: GET_DC_SYSTEM_POWER_LIMITS_TABLE") + } + Case (NVPCF_FUNC_CPU_TDP_CONTROL) { + Printf (" NVPCF[9]: CPU_TDP_CONTROL") + } + Case (NVPCF_FUNC_GET_DC_TPP_LIMIT_PREFERENCE) { + Printf (" NVPCF[10]: GET_DC_TPP_LIMIT_PREFERENCE") + } + Case (NVPCF_FUNC_GET_THERMAL_ZONE_STATUS) { + Printf (" NVPCF[11]: GET_THERMAL_ZONE_STATUS") + } + Default { + Printf (" NVPCF: Unknown function: %o", Arg0) + } + } + + // XXX: DG says unsupported functions should return a + // buffer, but even the example immediately following + // this statement returns a DWORD, and this is what + // proprietary firmware also does. + Return (NVPCF_ERROR_UNSUPPORTED) +} diff --git a/src/drivers/gfx/nvidia/acpi/common/power.asl b/src/drivers/gfx/nvidia/acpi/common/power.asl new file mode 100644 index 00000000000..b285ba6af0e --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/power.asl @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +//TODO: evaluate sleeps + +OperationRegion (PCIC, PCI_Config, 0x00, 0xFF) +Field (PCIC, DwordAcc, NoLock, Preserve) { + Offset (0x40), + SSID, 32, // Subsystem vendor and product ID +} + +// Enter GC6 +Method(GC6I, 0, Serialized) { + Printf(" GPU GC6I START") + + // Enter L23 + ^^DL23() + Sleep(5) + + // Put GPU into reset + Printf(" Put GPU into reset") + CTXS(DGPU_RST_N) + Sleep(5) + + Printf(" GPU GC6I FINISH") +} + +// Exit GC6 +Method(GC6O, 0, Serialized) { + Printf(" GPU GC6O START") + + // Bring GPU out of reset + Printf(" Bring GPU out of reset") + STXS(DGPU_RST_N) + Sleep(5) + + // Exit L23 + ^^L23D() + Sleep(5) + + Printf(" GPU GC6O FINISH") +} + +Method (_ON, 0, Serialized) { + Printf(" GPU _ON START") + + If (DFEN == JT_DFGC_DEFER) { + Switch (ToInteger(DFCO)) { + Case (JT_GPC_XGXS) { + Printf(" Exit GC6 and stop self-refresh") + GC6O() + } + Default { + Printf(" Unsupported DFCO: %o", SFST(DFCO)) + } + } + DFEN = JT_DFGC_NONE + } Else { + Printf(" Standard RTD3 power on") + STXS(DGPU_PWR_EN) + Sleep(5) + GC6O() + } + + Printf(" GPU _ON FINISH") +} + +Method (_OFF, 0, Serialized) { + Printf(" GPU _OFF START") + + If (DFEN == JT_DFGC_DEFER) { + Switch (ToInteger(DFCI)) { + Case (JT_GPC_EGNS) { + Printf(" Enter GC6 without self-refresh") + GC6I() + } + Case (JT_GPC_EGIS) { + Printf(" Enter GC6 with self-refresh") + GC6I() + } + Default { + Printf(" Unsupported DFCI: %o", SFST(DFCI)) + } + } + DFEN = JT_DFGC_NONE + } Else { + Printf(" Standard RTD3 power off") + GC6I() + CTXS(DGPU_PWR_EN) + Sleep(5) + } + + Printf(" GPU _OFF FINISH") +} + +// Main power resource +PowerResource (PWRR, 0, 0) { + Name (_STA, 1) + + Method (_ON, 0, Serialized) { + Printf("GPU PWRR._ON") + + // Restore SSID + ^^SSID = DGPU_SSID + Printf(" Restore SSID: %o", SFST(^^SSID)) + + _STA = 1 + } + + Method (_OFF, 0, Serialized) { + Printf("GPU PWRR._OFF") + + _STA = 0 + } +} + +// Power resources for entering D0 +Name (_PR0, Package () { PWRR }) + +// Power resources for entering D3 +Name (_PR3, Package () { PWRR }) diff --git a/src/drivers/gfx/nvidia/acpi/common/utility.asl b/src/drivers/gfx/nvidia/acpi/common/utility.asl new file mode 100644 index 00000000000..edf42bd024b --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/common/utility.asl @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +// Convert a byte to a hex string, trimming extra parts +Method (BHEX, 1) { + Local0 = ToHexString(Arg0) + Return (Mid(Local0, SizeOf(Local0) - 2, 2)) +} + +// UUID to string +Method (IDST, 1) { + Local0 = "" + Fprintf( + Local0, + "%o%o%o%o-%o%o-%o%o-%o%o-%o%o%o%o%o%o", + BHEX(DerefOf(Arg0[3])), + BHEX(DerefOf(Arg0[2])), + BHEX(DerefOf(Arg0[1])), + BHEX(DerefOf(Arg0[0])), + BHEX(DerefOf(Arg0[5])), + BHEX(DerefOf(Arg0[4])), + BHEX(DerefOf(Arg0[7])), + BHEX(DerefOf(Arg0[6])), + BHEX(DerefOf(Arg0[8])), + BHEX(DerefOf(Arg0[9])), + BHEX(DerefOf(Arg0[10])), + BHEX(DerefOf(Arg0[11])), + BHEX(DerefOf(Arg0[12])), + BHEX(DerefOf(Arg0[13])), + BHEX(DerefOf(Arg0[14])), + BHEX(DerefOf(Arg0[15])) + ) + Return (Local0) +} + +// Safe hex conversion, checks type first +Method (SFST, 1) { + Local0 = ObjectType(Arg0) + If (Local0 == 1 || Local0 == 2 || Local0 == 3) { + Return (ToHexString(Arg0)) + } Else { + Return (Concatenate("Type: ", Arg0)) + } +} + +// Convert from 4-byte buffer to 32-bit integer +Method (BTOI, 1) { + Return( + DerefOf(Arg0[0]) | + (DerefOf(Arg0[1]) << 8) | + (DerefOf(Arg0[2]) << 16) | + (DerefOf(Arg0[3]) << 24) + ) +} + +// Convert from 32-bit integer to 4-byte buffer +Method (ITOB, 1) { + Local0 = Buffer(4) { 0, 0, 0, 0 } + Local0[0] = Arg0 & 0xFF + Local0[1] = (Arg0 >> 8) & 0xFF + Local0[2] = (Arg0 >> 16) & 0xFF + Local0[3] = (Arg0 >> 24) & 0xFF + Return (Local0) +} diff --git a/src/drivers/gfx/nvidia/acpi/tigerlake.asl b/src/drivers/gfx/nvidia/acpi/tigerlake.asl new file mode 100644 index 00000000000..a13e46a04f8 --- /dev/null +++ b/src/drivers/gfx/nvidia/acpi/tigerlake.asl @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* NVIDIA GC6 on (TGL and ADL) (CPU and PCH) PCIe ports */ + +// Port mapped PCI express config space +OperationRegion (PCIC, PCI_Config, 0x00, 0xFF) + +Field (PCIC, AnyAcc, NoLock, Preserve) { + Offset(0x52), /* LSTS - Link Status Register */ + , 13, + LASX, 1, /* 0, Link Active Status */ + + Offset(0x60), /* RSTS - Root Status Register */ + , 16, + PSPX, 1, /* 16, PME Status */ + + Offset(0xD8), /* 0xD8, MPC - Miscellaneous Port Configuration Register */ + , 30, + HPEX, 1, /* 30, Hot Plug SCI Enable */ + PMEX, 1, /* 31, Power Management SCI Enable */ + + Offset (0xE0), /* 0xE0, SPR - Scratch Pad Register */ + SCB0, 1, /* Scratch bit 0 */ + + Offset(0xE2), /* 0xE2, RPPGEN - Root Port Power Gating Enable */ + , 2, + L23E, 1, /* 2, L23_Rdy Entry Request (L23ER) */ + L23R, 1, /* 3, L23_Rdy to Detect Transition (L23R2DT) */ +} + +Field (PCIC, AnyAcc, NoLock, WriteAsZeros) { + Offset(0xDC), /* 0xDC, SMSCS - SMI/SCI Status Register */ + , 30, + HPSX, 1, /* 30, Hot Plug SCI Status */ + PMSX, 1 /* 31, Power Management SCI Status */ +} + +// Enter L23 +Method (DL23, 0, Serialized) { + Printf(" GPU PORT DL23 START") + + L23E = 1 + Sleep (16) + Local0 = 0 + While (L23E) { + If ((Local0 > 4)) { + Break + } + + Sleep (16) + Local0++ + } + SCB0 = 1 + + Printf(" GPU PORT DL23 FINISH") +} + +// Exit L23 +Method (L23D, 0, Serialized) { + Printf(" GPU PORT L23D START") + + If ((SCB0 == 1)) { + L23R = 1 + Local0 = 0 + While (L23R) { + If ((Local0 > 4)) { + Break + } + Sleep (16) + Local0++ + } + + SCB0 = 0 + Local0 = 0 + While ((LASX == 0)) { + If ((Local0 > 8)) { + Break + } + Sleep (16) + Local0++ + } + } + + Printf(" GPU PORT L23D FINISH") +} + +Method (HPME, 0, Serialized) { + Printf(" GPU PORT HPME START") + + If (PMSX == 1) { + Printf(" Notify GPU driver of PME SCI") + Notify(DEV0, 0x2) + Printf(" Clear PME SCI") + PMSX = 1 + Printf(" Consume PME notification") + PSPX = 1 + } + + Printf(" GPU PORT HPME FINISH") +} + +// Main power resource +PowerResource (PWRR, 0, 0) { + Name (_STA, 1) + + Method (_ON, 0, Serialized) { + Printf("GPU PORT PWRR._ON") + + HPME(); + If (PMEX == 1) { + Printf(" Disable power management SCI") + PMEX = 0 + } + + ^^DEV0._ON() + + _STA = 1 + } + + Method (_OFF, 0, Serialized) { + Printf("GPU PORT PWRR._OFF") + + ^^DEV0._OFF() + + If (PMEX == 0) { + Printf(" Enable power management SCI") + PMEX = 1 + HPME() + } + + _STA = 0 + } +} + +// Power resources for entering D0 +Name (_PR0, Package () { PWRR }) + +// Power resources for entering D3 +Name (_PR3, Package () { PWRR }) + +#include "common/gpu.asl" diff --git a/src/drivers/gfx/nvidia/chip.h b/src/drivers/gfx/nvidia/chip.h new file mode 100644 index 00000000000..b6d9c908ebc --- /dev/null +++ b/src/drivers/gfx/nvidia/chip.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _DRIVERS_GFX_NVIDIA_CHIP_H_ +#define _DRIVERS_GFX_NVIDIA_CHIP_H_ + +struct drivers_gfx_nvidia_config { + /* TODO: Set GPIOs in devicetree? */ +}; + +#endif /* _DRIVERS_GFX_NVIDIA_CHIP_H_ */ diff --git a/src/drivers/gfx/nvidia/gpu.h b/src/drivers/gfx/nvidia/gpu.h new file mode 100644 index 00000000000..68b6cd2d590 --- /dev/null +++ b/src/drivers/gfx/nvidia/gpu.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _DRIVERS_GFX_NVIDIA_GPU_H_ +#define _DRIVERS_GFX_NVIDIA_GPU_H_ + +#include + +struct nvidia_gpu_config { + /* GPIO for GPU_PWR_EN */ + unsigned int power_gpio; + /* GPIO for GPU_RST# */ + unsigned int reset_gpio; + /* Enable or disable GPU power */ + bool enable; +}; + +void nvidia_set_power(const struct nvidia_gpu_config *config); + +#endif /* _DRIVERS_NVIDIA_GPU_H_ */ diff --git a/src/drivers/gfx/nvidia/nvidia.c b/src/drivers/gfx/nvidia/nvidia.c new file mode 100644 index 00000000000..42d5db07f05 --- /dev/null +++ b/src/drivers/gfx/nvidia/nvidia.c @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "chip.h" +#include +#include +#include +#include + +#define NVIDIA_SUBSYSTEM_ID_OFFSET 0x40 + +static void nvidia_read_resources(struct device *dev) +{ + printk(BIOS_DEBUG, "%s: %s\n", __func__, dev_path(dev)); + + pci_dev_read_resources(dev); + + // Find all BARs on GPU, mark them above 4g if prefetchable + for (int bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar += 4) { + struct resource *res = probe_resource(dev, bar); + + if (res) { + if (res->flags & IORESOURCE_PREFETCH) { + printk(BIOS_INFO, " BAR at 0x%02x marked above 4g\n", bar); + res->flags |= IORESOURCE_ABOVE_4G; + } else { + printk(BIOS_DEBUG, " BAR at 0x%02x not prefetch\n", bar); + } + } else { + printk(BIOS_DEBUG, " BAR at 0x%02x not found\n", bar); + } + } +} + +static void nvidia_set_subsystem(struct device *dev, unsigned int vendor, unsigned int device) +{ + pci_write_config32(dev, NVIDIA_SUBSYSTEM_ID_OFFSET, + ((device & 0xffff) << 16) | (vendor & 0xffff)); +} + +static struct pci_operations nvidia_device_ops_pci = { + .set_subsystem = nvidia_set_subsystem, +}; + +static struct device_operations nvidia_device_ops = { + .read_resources = nvidia_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .write_acpi_tables = pci_rom_write_acpi_tables, + .acpi_fill_ssdt = pci_rom_ssdt, + .init = pci_dev_init, + .ops_pci = &nvidia_device_ops_pci, +}; + +static void nvidia_enable(struct device *dev) +{ + if (!is_dev_enabled(dev) || dev->path.type != DEVICE_PATH_PCI) + return; + + if (pci_read_config16(dev, PCI_VENDOR_ID) != PCI_VID_NVIDIA) + return; + + dev->ops = &nvidia_device_ops; +} + +struct chip_operations drivers_gfx_nvidia_ops = { + .name = "NVIDIA Optimus Graphics Device", + .enable_dev = nvidia_enable +}; diff --git a/src/drivers/gfx/nvidia/romstage.c b/src/drivers/gfx/nvidia/romstage.c new file mode 100644 index 00000000000..78fe5ddf503 --- /dev/null +++ b/src/drivers/gfx/nvidia/romstage.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include "chip.h" +#include "gpu.h" + +void nvidia_set_power(const struct nvidia_gpu_config *config) +{ + if (!config->power_gpio || !config->reset_gpio) { + printk(BIOS_ERR, "%s: GPU_PWR_EN and GPU_RST# must be set\n", __func__); + return; + } + + printk(BIOS_DEBUG, "%s: GPU_PWR_EN = %d\n", __func__, config->power_gpio); + printk(BIOS_DEBUG, "%s: GPU_RST# = %d\n", __func__, config->reset_gpio); + + gpio_set(config->reset_gpio, 0); + mdelay(10); + + if (config->enable) { + gpio_set(config->power_gpio, 1); + mdelay(25); + gpio_set(config->reset_gpio, 1); + } else { + gpio_set(config->power_gpio, 0); + } + + mdelay(10); +} diff --git a/src/drivers/i2c/at24rf08c/Kconfig b/src/drivers/i2c/at24rf08c/Kconfig index a930a46123e..219c091a922 100644 --- a/src/drivers/i2c/at24rf08c/Kconfig +++ b/src/drivers/i2c/at24rf08c/Kconfig @@ -3,3 +3,7 @@ config DRIVER_LENOVO_SERIALS bool select SMBIOS_PROVIDED_BY_MOBO + +config DRIVER_LENOVO_SERIALS_EARLY_LOCK + bool + depends on DRIVER_LENOVO_SERIALS diff --git a/src/drivers/i2c/at24rf08c/Makefile.mk b/src/drivers/i2c/at24rf08c/Makefile.mk index 4ef2bc595cd..223f6903a40 100644 --- a/src/drivers/i2c/at24rf08c/Makefile.mk +++ b/src/drivers/i2c/at24rf08c/Makefile.mk @@ -3,3 +3,4 @@ ramstage-$(CONFIG_DRIVER_LENOVO_SERIALS) += at24rf08c.c $(call src-to-obj,ramstage,$(dir)/lenovo_serials.c) : $(obj)/build.h ramstage-$(CONFIG_DRIVER_LENOVO_SERIALS) += lenovo_serials.c +romstage-$(CONFIG_DRIVER_LENOVO_SERIALS_EARLY_LOCK) += romstage.c diff --git a/src/drivers/i2c/at24rf08c/at24rf08c.c b/src/drivers/i2c/at24rf08c/at24rf08c.c index 99ea7a47f0e..6005f74c4c3 100644 --- a/src/drivers/i2c/at24rf08c/at24rf08c.c +++ b/src/drivers/i2c/at24rf08c/at24rf08c.c @@ -11,6 +11,9 @@ static void at24rf08c_init(struct device *dev) if (!dev->enabled) return; + if (CONFIG(DRIVER_LENOVO_SERIALS_EARLY_LOCK)) + return; + /* Ensure that EEPROM/RFID chip is not accessible through RFID. Need to do it only on 5c. */ if (dev->path.type != DEVICE_PATH_I2C || dev->path.i2c.device != 0x5c) diff --git a/src/drivers/i2c/at24rf08c/lenovo.h b/src/drivers/i2c/at24rf08c/lenovo.h index f94b9ee06df..628308d5dd7 100644 --- a/src/drivers/i2c/at24rf08c/lenovo.h +++ b/src/drivers/i2c/at24rf08c/lenovo.h @@ -1,3 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ const char *lenovo_mainboard_partnumber(void); + +void lenovo_mainboard_eeprom_lock(void); diff --git a/src/drivers/i2c/at24rf08c/lenovo_serials.c b/src/drivers/i2c/at24rf08c/lenovo_serials.c index dd09dda7fe7..34b98004c64 100644 --- a/src/drivers/i2c/at24rf08c/lenovo_serials.c +++ b/src/drivers/i2c/at24rf08c/lenovo_serials.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include @@ -38,18 +39,22 @@ static int at24rf08c_read_byte(struct device *dev, u8 addr) return t; } -static void at24rf08c_read_string_dev(struct device *dev, u8 start, - u8 len, char *result) +static void at24rf08c_read_string_dev(struct device *dev, const u8 start, + const u8 len, char *result) { - int i; - for (i = 0; i < len; i++) { - int t = at24rf08c_read_byte(dev, start + i); + assert(start + len <= 128); - if (t < 0x20 || t > 0x7f) { + int ret = smbus_i2c_eeprom_read(dev, start, len, (u8 *)result); + if (ret != len) { + for (int i = 0; i < len; i++) + result[i] = at24rf08c_read_byte(dev, start + i); + } + + for (int i = 0; i < len; i++) { + if (result[i] < 0x20) { memcpy(result, ERROR_STRING, sizeof(ERROR_STRING)); return; } - result[i] = t; } result[len] = '\0'; } @@ -106,7 +111,7 @@ const char *smbios_mainboard_product_name(void) void smbios_system_set_uuid(u8 *uuid) { static char result[16]; - unsigned int i; + u8 buf[16]; static int already_read; struct device *dev; const int remap[16] = { @@ -119,34 +124,30 @@ void smbios_system_set_uuid(u8 *uuid) return; } - memset(result, 0, sizeof(result)); + memset(uuid, 0, 16); dev = dev_find_slot_on_smbus(1, 0x56); if (dev == NULL) { printk(BIOS_WARNING, "EEPROM not found\n"); already_read = 1; - memset(uuid, 0, 16); return; } - for (i = 0; i < 16; i++) { - int t; - int j; - /* After a register write AT24RF08C (which we issued in init function) sometimes stops responding. - Retry several times in case of failure. - */ - for (j = 0; j < 100; j++) { - t = smbus_read_byte(dev, 0x12 + i); - if (t >= 0) - break; + int ret = smbus_i2c_eeprom_read(dev, 0x12, 16, buf); + if (ret != 16) { + for (int i = 0; i < 16; i++) { + int c = at24rf08c_read_byte(dev, 0x12 + i); + if (c < 0) { + already_read = 1; + return; + } + buf[i] = c; } - if (t < 0) { - memset(result, 0, sizeof(result)); - break; - } - result[remap[i]] = t; } + for (int i = 0; i < 16; i++) + result[remap[i]] = buf[i]; + already_read = 1; memcpy(uuid, result, 16); @@ -154,7 +155,7 @@ void smbios_system_set_uuid(u8 *uuid) const char *smbios_mainboard_version(void) { - static char result[100]; + static char result[90]; static int already_read; struct device *dev; int len; diff --git a/src/drivers/i2c/at24rf08c/romstage.c b/src/drivers/i2c/at24rf08c/romstage.c new file mode 100644 index 00000000000..00026b7f3f6 --- /dev/null +++ b/src/drivers/i2c/at24rf08c/romstage.c @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +void lenovo_mainboard_eeprom_lock(void) +{ + printk(BIOS_DEBUG, "Locking EEPROM RFID\n"); + + for (int i = 0; i < 8; i++) { + /* After a register write AT24RF08C sometimes stops responding. + Retry several times in case of failure. */ + for (int j = 0; j < 100; j++) + if (smbus_write_byte(0x5c, i, 0x0f) >= 0) + break; + } +} diff --git a/src/drivers/i2c/rv3028c7/rv3028c7.c b/src/drivers/i2c/rv3028c7/rv3028c7.c index 0a1e4b6872d..a8ac33b5a2a 100644 --- a/src/drivers/i2c/rv3028c7/rv3028c7.c +++ b/src/drivers/i2c/rv3028c7/rv3028c7.c @@ -86,29 +86,37 @@ static void rtc_set_time_date(struct device *dev) buf[6] = coreboot_build_date.year; printk(BIOS_DEBUG, "%s: Set to coreboot build date\n", dev->chip_ops->name); } - /* According to the datasheet, date and time should be transferred in "one go" - in order to avoid value corruption. */ - if (i2c_dev_write_at(dev, buf, sizeof(buf), 0) != sizeof(buf)) { - printk(BIOS_ERR, "%s: Not able to set date and time!\n", dev->chip_ops->name); + for (size_t i = 0; i < ARRAY_SIZE(buf); i++) { + if (i2c_dev_writeb_at(dev, i, buf[i]) < 0) { + printk(BIOS_ERR, "%s: Failed to write register 0x%02zx!\n", + dev->chip_ops->name, i); + return; + } } } static void rtc_final(struct device *dev) { uint8_t buf[7]; + int val; + /* Read back current RTC date and time byte by byte */ + printk(BIOS_DEBUG, "%s: Reading current date and time...\n", dev->chip_ops->name); - /* Read back current RTC date and time and print it to the console. - Date and time are read in "one go", the buffer contains seconds (byte 0) - through years (byte 6) after this read. */ - if (i2c_dev_read_at(dev, buf, sizeof(buf), 0) != sizeof(buf)) { - printk(BIOS_ERR, "%s: Not able to read current date and time!\n", - dev->chip_ops->name); - } else { - printk(BIOS_INFO, "%s: Current date %02d.%02d.%02d %02d:%02d:%02d\n", - dev->chip_ops->name, bcd2bin(buf[5]), bcd2bin(buf[4]), - bcd2bin(buf[6]), bcd2bin(buf[2]), bcd2bin(buf[1]), - bcd2bin(buf[0])); + for (size_t i = 0; i < ARRAY_SIZE(buf); i++) { + val = i2c_dev_readb_at(dev, i); + if (val < 0) { + printk(BIOS_ERR, "%s: Failed to read register 0x%02zx!\n", + dev->chip_ops->name, i); + return; + } + buf[i] = (uint8_t)val; } + + printk(BIOS_INFO, "%s: Current date %02d.%02d.%02d %02d:%02d:%02d\n", + dev->chip_ops->name, bcd2bin(buf[5]), bcd2bin(buf[4]), + bcd2bin(buf[6]), bcd2bin(buf[2]), bcd2bin(buf[1]), + bcd2bin(buf[0])); + /* Make sure the EEPROM automatic refresh is enabled. */ if (rtc_eep_auto_refresh(dev, EEP_REFRESH_EN) != CB_SUCCESS) { printk(BIOS_ERR, "%s: Not able to enable EEPROM auto refresh!\n", diff --git a/src/drivers/intel/dtbt/Kconfig b/src/drivers/intel/dtbt/Kconfig new file mode 100644 index 00000000000..c357288816e --- /dev/null +++ b/src/drivers/intel/dtbt/Kconfig @@ -0,0 +1,9 @@ +config DRIVERS_INTEL_DTBT + def_bool n + help + Enable support for discrete Thunderbolt controllers (Alpine Ridge, + Titan Ridge, and Maple Ridge). Provides device initialization and ACPI + _DSD/opregion for S3 sleep support. Mainboards must call \TBTS from + their MPTS so TBT is prepared before sleep. + + Note: Only a single TBT bridge device is currently supported. diff --git a/src/drivers/intel/dtbt/Makefile.mk b/src/drivers/intel/dtbt/Makefile.mk new file mode 100644 index 00000000000..1b5252dda09 --- /dev/null +++ b/src/drivers/intel/dtbt/Makefile.mk @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only + +ramstage-$(CONFIG_DRIVERS_INTEL_DTBT) += dtbt.c diff --git a/src/drivers/intel/dtbt/chip.h b/src/drivers/intel/dtbt/chip.h new file mode 100644 index 00000000000..2b1dfa70a52 --- /dev/null +++ b/src/drivers/intel/dtbt/chip.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _DRIVERS_INTEL_DTBT_CHIP_H_ +#define _DRIVERS_INTEL_DTBT_CHIP_H_ + +struct drivers_intel_dtbt_config {}; + +#endif /* _DRIVERS_INTEL_DTBT_CHIP_H_ */ diff --git a/src/drivers/intel/dtbt/dtbt.c b/src/drivers/intel/dtbt/dtbt.c new file mode 100644 index 00000000000..695f44105e6 --- /dev/null +++ b/src/drivers/intel/dtbt/dtbt.c @@ -0,0 +1,247 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "chip.h" +#include "dtbt.h" + + +/* Returns true on success, false on timeout or TBT2PCIE Error field non-zero */ +static bool dtbt_cmd(struct device *dev, u8 command, u32 data, u32 timeout) +{ + u32 reg = (data << 8) | (command << 1) | PCIE2TBT_VALID; + u32 status; + u8 error; + + printk(BIOS_SPEW, "dTBT send command 0x%x\n", command); + /* Send command */ + pci_write_config32(dev, PCIE2TBT, reg); + /* Wait for Done bit */ + if (!wait_ms(timeout, (status = pci_read_config32(dev, TBT2PCIE)) & TBT2PCIE_DONE)) { + printk(BIOS_ERR, "dTBT command 0x%x send timeout, status 0x%x\n", command, status); + return false; + } + /* Check Error field (bits 15:12) */ + error = (status & TBT2PCIE_ERROR_MASK) >> 12; + if (error != TBT2PCIE_ERROR_SUCCESS) { + printk(BIOS_ERR, "dTBT command 0x%x failed, TBT2PCIE Error 0x%x (status 0x%x)\n", + command, error, status); + pci_write_config32(dev, PCIE2TBT, 0); + return false; + } + /* Clear valid bit */ + pci_write_config32(dev, PCIE2TBT, 0); + /* Wait for done bit to be cleared */ + if (!wait_ms(timeout, (status = pci_read_config32(dev, TBT2PCIE)) & TBT2PCIE_DONE)) { + printk(BIOS_ERR, "dTBT command 0x%x clear valid bit timeout, status 0x%x\n", + command, status); + return false; + } + return true; +} + +static void dtbt_write_dsd(void) +{ + struct acpi_dp *dsd = acpi_dp_new_table("_DSD"); + + acpi_device_add_hotplug_support_in_d3(dsd); + acpi_device_add_external_facing_port(dsd); + acpi_dp_write(dsd); +} + +static void dtbt_write_opregion(void) +{ + const struct opregion opregion = OPREGION("PXCS", PCI_CONFIG, 0, 0x1000); + const struct fieldlist fieldlist[] = { + FIELDLIST_OFFSET(TBT2PCIE), + FIELDLIST_NAMESTR("TB2P", 32), + FIELDLIST_OFFSET(PCIE2TBT), + FIELDLIST_NAMESTR("P2TB", 32), + }; + + acpigen_write_opregion(&opregion); + acpigen_write_field("PXCS", fieldlist, ARRAY_SIZE(fieldlist), + FIELD_DWORDACC | FIELD_NOLOCK | FIELD_PRESERVE); +} + +/* + * Generated ASL: + * + * Scope (\_SB.PCI0.RPxx) + * { + * _DSD (Package () { ... hotplug support, external facing port ... }) + * Device (DTBT) + * { + * Name (_ADR, 0) + * OperationRegion (PXCS, PCI_Config, 0, 0x1000) + * Field (PXCS, DWordAcc, NoLock, Preserve) + * { + * Offset (0x2A40), + * TB2P, 32, + * Offset (0), + * P2TB, 32, + * } + * Method (PTS, 0, Serialized) + * { + * Debug = "dTBT prepare to sleep" + * Store (0x06, P2TB) + * Debug = TB2P + * Store (0, P2TB) + * Debug = TB2P + * } + * } + * } + * Scope (\) + * { + * Method (TBTS, 0) + * { + * \_SB.PCI0.RPxx.DTBT.PTS () + * } + * } + */ +static void dtbt_fill_ssdt(const struct device *dev) +{ + /* We only want to create a single ACPI device in the SSDT */ + static bool ssdt_done; + + struct bus *bus; + struct device *parent; + const char *parent_scope; + const char *dev_name = acpi_device_name(dev); + + if (ssdt_done) + return; + + bus = dev->upstream; + if (!bus) { + printk(BIOS_ERR, "dTBT bus invalid\n"); + return; + } + + parent = bus->dev; + if (!parent || !is_pci(parent)) { + printk(BIOS_ERR, "dTBT parent invalid\n"); + return; + } + + parent_scope = acpi_device_path(parent); + if (!parent_scope) { + printk(BIOS_ERR, "dTBT parent scope not valid\n"); + return; + } + + /* Scope */ + acpigen_write_scope(parent_scope); + dtbt_write_dsd(); + + /* Device */ + acpigen_write_device(dev_name); + acpigen_write_name_integer("_ADR", 0); + dtbt_write_opregion(); + + /* PTS Method */ + acpigen_write_method_serialized("PTS", 0); + + acpigen_write_debug_string("dTBT prepare to sleep"); + acpigen_write_store_int_to_namestr(PCIE2TBT_GO2SX_NO_WAKE << 1, "P2TB"); + acpigen_write_delay_until_namestr_int(GO2SX_TIMEOUT_MS, "TB2P", PCIE2TBT_GO2SX_NO_WAKE << 1); + + acpigen_write_debug_namestr("TB2P"); + acpigen_write_store_int_to_namestr(0, "P2TB"); + acpigen_write_delay_until_namestr_int(GO2SX_TIMEOUT_MS, "TB2P", 0); + acpigen_write_debug_namestr("TB2P"); + + acpigen_write_method_end(); + acpigen_write_device_end(); + acpigen_write_scope_end(); + + /* \.TBTS Method: mainboard must call this from MPTS/_PTS */ + acpigen_write_scope("\\"); + acpigen_write_method("TBTS", 0); + acpigen_emit_namestring(acpi_device_path_join(dev, "PTS")); + acpigen_write_method_end(); + acpigen_write_scope_end(); + + printk(BIOS_INFO, "%s.%s %s\n", parent_scope, dev_name, dev_path(dev)); + ssdt_done = true; +} + +static const char *dtbt_acpi_name(const struct device *dev) +{ + return "DTBT"; +} + +static void dtbt_enable(struct device *dev) +{ + /* Only enable the primary bridge device (device 0, function 0) */ + if (!is_dev_enabled(dev) || dev->path.pci.devfn != 0) + return; + + printk(BIOS_INFO, "dTBT controller found at %s\n", dev_path(dev)); + + /* Set security level (Table 37/428); failure aborts enable */ + // XXX: Recommendation is to set SL1 ("User Authorization") + printk(BIOS_DEBUG, "dTBT set security level SL0\n"); + if (!dtbt_cmd(dev, PCIE2TBT_SET_SECURITY_LEVEL, SEC_LEVEL_NONE, MBOX_TIMEOUT_MS)) { + printk(BIOS_ERR, "dTBT Set_Security_Level failed, aborting enable\n"); + return; + } + + if (acpi_is_wakeup_s3()) { + printk(BIOS_DEBUG, "dTBT SX exit\n"); + if (!dtbt_cmd(dev, PCIE2TBT_SX_EXIT_TBT_CONNECTED, 0, MBOX_TIMEOUT_MS)) + printk(BIOS_ERR, "dTBT Sx_Exit_TBT_Connected failed\n"); + if (pci_read_config32(dev, TBT2PCIE) == 0xffffffff) + printk(BIOS_ERR, "dTBT S3 resume failure.\n"); + } else { + printk(BIOS_DEBUG, "dTBT set boot on\n"); + if (dtbt_cmd(dev, PCIE2TBT_BOOT_ON, 0, MBOX_TIMEOUT_MS)) { + printk(BIOS_DEBUG, "dTBT set USB on\n"); + dtbt_cmd(dev, PCIE2TBT_USB_ON, 0, MBOX_TIMEOUT_MS); + } else { + printk(BIOS_ERR, "dTBT BOOT_ON failed, skipping USB_ON\n"); + } + } +} + +static struct device_operations dtbt_device_ops = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .acpi_fill_ssdt = dtbt_fill_ssdt, + .acpi_name = dtbt_acpi_name, + .scan_bus = pciexp_scan_bridge, + .reset_bus = pci_bus_reset, + .enable = dtbt_enable +}; + +/* We only want to match the bridge devices */ +static const unsigned short pci_device_ids[] = { + AR_2C_BRG, + AR_4C_BRG, + AR_LP_BRG, + AR_4C_C0_BRG, + AR_2C_C0_BRG, + TR_2C_BRG, + TR_4C_BRG, + TR_DD_BRG, + MR_2C_BRG, + MR_4C_BRG, + 0 +}; + +static const struct pci_driver intel_dtbt_driver __pci_driver = { + .ops = &dtbt_device_ops, + .vendor = PCI_VID_INTEL, + .devices = pci_device_ids, +}; + +struct chip_operations drivers_intel_dtbt_ops = { + .name = "Intel Discrete Thunderbolt", +}; diff --git a/src/drivers/intel/dtbt/dtbt.h b/src/drivers/intel/dtbt/dtbt.h new file mode 100644 index 00000000000..40c1938ceb4 --- /dev/null +++ b/src/drivers/intel/dtbt/dtbt.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _DRIVERS_INTEL_DTBT_H_ +#define _DRIVERS_INTEL_DTBT_H_ + +/* Alpine Ridge device IDs */ +#define AR_2C_NHI 0x1575 +#define AR_2C_BRG 0x1576 +#define AR_2C_USB 0x15B5 +#define AR_4C_NHI 0x1577 +#define AR_4C_BRG 0x1578 +#define AR_4C_USB 0x15B6 +#define AR_LP_NHI 0x15BF +#define AR_LP_BRG 0x15C0 +#define AR_LP_USB 0x15C1 +#define AR_4C_C0_NHI 0x15D2 +#define AR_4C_C0_BRG 0x15D3 +#define AR_4C_C0_USB 0x15D4 +#define AR_2C_C0_NHI 0x15D9 +#define AR_2C_C0_BRG 0x15DA +#define AR_2C_C0_USB 0x15DB + +/* Titan Ridge device IDs */ +#define TR_2C_BRG 0x15E7 +#define TR_2C_NHI 0x15E8 +#define TR_2C_USB 0x15E9 +#define TR_4C_BRG 0x15EA +#define TR_4C_NHI 0x15EB +#define TR_4C_USB 0x15EC +#define TR_DD_BRG 0x15EF +#define TR_DD_USB 0x15F0 + +/* Maple Ridge device IDs */ +#define MR_2C_BRG 0x1133 +#define MR_2C_NHI 0x1134 +#define MR_2C_USB 0x1135 +#define MR_4C_BRG 0x1136 +#define MR_4C_NHI 0x1137 +#define MR_4C_USB 0x1138 + +/* Security Levels */ +#define SEC_LEVEL_NONE 0 +#define SEC_LEVEL_USER 1 +#define SEC_LEVEL_AUTH 2 +#define SEC_LEVEL_DP_ONLY 3 + +#define PCIE2TBT 0x54C +#define PCIE2TBT_VALID BIT(0) +#define PCIE2TBT_GO2SX 2 +#define PCIE2TBT_GO2SX_NO_WAKE 3 +#define PCIE2TBT_SX_EXIT_TBT_CONNECTED 4 +#define PCIE2TBT_OS_UP 6 +#define PCIE2TBT_SET_SECURITY_LEVEL 8 +#define PCIE2TBT_GET_SECURITY_LEVEL 9 +#define PCIE2TBT_BOOT_ON 24 +#define PCIE2TBT_USB_ON 25 +#define PCIE2TBT_GET_ENUMERATION_METHOD 26 +#define PCIE2TBT_SET_ENUMERATION_METHOD 27 +#define PCIE2TBT_POWER_CYCLE 28 +#define PCIE2TBT_SX_START 29 +#define PCIE2TBT_ACL_BOOT 30 +#define PCIE2TBT_CONNECT_TOPOLOGY 31 + +#define TBT2PCIE 0x548 +#define TBT2PCIE_DONE BIT(0) +#define TBT2PCIE_ERROR_MASK (0xF << 12) /* bits 15:12, Table 38 */ +#define TBT2PCIE_ERROR_SUCCESS 0 +#define TBT2PCIE_ERROR_GENERAL 1 +#define TBT2PCIE_ERROR_ILLEGAL_DATA 2 +#define TBT2PCIE_ERROR_TIMEOUT 3 + +// Timeout for mailbox commands unless otherwise specified. +#define MBOX_TIMEOUT_MS 5000 + +// Timeout for controller to ack GO2SX/GO2SX_NO_WAKE mailbox command. +#define GO2SX_TIMEOUT_MS 600 + +#endif /* _DRIVERS_INTEL_DTBT_H_ */ diff --git a/src/drivers/intel/fsp2_0/fsp_timestamp.c b/src/drivers/intel/fsp2_0/fsp_timestamp.c index 872cf9149ee..65a6060f57d 100644 --- a/src/drivers/intel/fsp2_0/fsp_timestamp.c +++ b/src/drivers/intel/fsp2_0/fsp_timestamp.c @@ -51,7 +51,7 @@ static void print_guid_record(const struct generic_event_record *rec) static void print_string_record(const struct generic_event_record *rec) { size_t str_len = rec->header.length - offsetof(struct generic_event_record, string); - printk(BIOS_INFO, "%5x\t%16llu\t\t%*s/", + printk(BIOS_INFO, "%5x\t%16llu\t\t%.*s/", rec->progress_id, TIMESTAMP_TO_MICRO(rec->timestamp), (int)str_len, rec->string); fsp_print_guid(BIOS_INFO, rec->guid); printk(BIOS_INFO, "\n"); diff --git a/src/drivers/intel/fsp2_0/include/fsp/util.h b/src/drivers/intel/fsp2_0/include/fsp/util.h index ce6666a4539..88b0b6a22c7 100644 --- a/src/drivers/intel/fsp2_0/include/fsp/util.h +++ b/src/drivers/intel/fsp2_0/include/fsp/util.h @@ -166,7 +166,6 @@ void display_fsp_error_info_hob(const void *hob); void fsp_get_version(char *buf); /* fsp_verify_upd_header_signature calls die() on signature mismatch */ void fsp_verify_upd_header_signature(uint64_t upd_signature, uint64_t expected_signature); -void lb_string_platform_blob_version(struct lb_header *header); void report_fspt_output(void); void soc_validate_fspm_header(const struct fsp_header *hdr); /* diff --git a/src/drivers/intel/ish/ish.c b/src/drivers/intel/ish/ish.c index 9cf6b7c0e59..fc153fba3a3 100644 --- a/src/drivers/intel/ish/ish.c +++ b/src/drivers/intel/ish/ish.c @@ -85,6 +85,7 @@ static const struct device_operations pci_ish_device_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_ISHB, PCI_DID_INTEL_WCL_ISHB, PCI_DID_INTEL_PTL_H_ISHB, PCI_DID_INTEL_PTL_U_H_ISHB, diff --git a/src/drivers/intel/mipi_camera/camera.c b/src/drivers/intel/mipi_camera/camera.c index 1b2fc692d80..79c0616ccf4 100644 --- a/src/drivers/intel/mipi_camera/camera.c +++ b/src/drivers/intel/mipi_camera/camera.c @@ -1219,10 +1219,19 @@ static struct device_operations camera_ops = { static void camera_enable(struct device *dev) { - //Validate Camera Parameters + /* Validate Camera Parameters */ struct drivers_intel_mipi_camera_config *config = dev->chip_info; bool params_error = false; + /* + * Non-sensor devices (like an aggregator) don't need + * SSDB validation, just assign ops and return. + */ + if (config->device_type != INTEL_ACPI_CAMERA_SENSOR) { + dev->ops = &camera_ops; + return; + } + if (!config->ssdb.lanes_used) { printk(BIOS_ERR, "MIPI camera: SSDB lanes_used not set\n"); params_error = true; diff --git a/src/drivers/intel/touch/chip.h b/src/drivers/intel/touch/chip.h index 83b5cd7d378..6e2696ff3fe 100644 --- a/src/drivers/intel/touch/chip.h +++ b/src/drivers/intel/touch/chip.h @@ -178,8 +178,12 @@ struct intel_thc_hidspi_info { enum intel_touch_device { TH_SENSOR_NONE, TH_SENSOR_WACOM, /* BOM22 for SPI only */ + /* + * TH_SENSOR_ELAN: the ELAN device for Intel's RVPs (default for ELAN) + * TH_SENSOR_ELAN_REX: the devece used in Google Rex; requires a special cable for Intel's RVP + */ TH_SENSOR_ELAN, /* BOM36 for SPI and BOM37 for I2C */ - TH_SENSOR_GOOGLE, /* ELAN9006 for SPI and ELAN6918 for I2C */ + TH_SENSOR_ELAN_REX, /* ELAN9006 for SPI and ELAN6918 for I2C */ TH_SENSOR_HYNITRON, /* NYITRON for I2C only */ TH_SENSOR_GENERIC, /* for device properity thru devicetree */ }; diff --git a/src/drivers/intel/touch/elan.h b/src/drivers/intel/touch/elan.h index 4f7b2a1ee06..baaa56880ab 100644 --- a/src/drivers/intel/touch/elan.h +++ b/src/drivers/intel/touch/elan.h @@ -32,19 +32,20 @@ static const struct drivers_intel_touch_config elan_touch_config = { /* * ELAN9006 is used for HID-SPI interface, while ELAN6918 is used for HID-I2C - * interface. + * interface; This is Google Rex's touch device and requires a special cable + * in Intel's RVP and fatcat. */ -static const struct drivers_intel_touch_config google_touch_config = { +static const struct drivers_intel_touch_config elan_rex_touch_config = { .sensor_dev_name = "ELAN Touch Sensor Device", - .dev_hidi2c = { /* Google's I2C-based touch */ + .dev_hidi2c = { /* Google Rex's I2C-based touch */ .hid = "ELAN6918", .cid = "PNP0C50", .intf.hidi2c.addr = 0x10, .intf.hidi2c.descriptor_address = 0x1, .intf.hidi2c.connection_speed = I2C_SPEED_FAST, /* fast mode */ }, - .dev_hidspi = { /* Google's SPI-based touch */ + .dev_hidspi = { /* Google Rex's SPI-based touch */ .hid = "ELAN9006", .cid = "PNP0C51", .intf.hidspi.connection_speed = (32 * MHz), /* unit: Hz */ diff --git a/src/drivers/intel/touch/touch.c b/src/drivers/intel/touch/touch.c index 85dd7f91595..0d27ca39362 100644 --- a/src/drivers/intel/touch/touch.c +++ b/src/drivers/intel/touch/touch.c @@ -43,7 +43,7 @@ static const struct drivers_intel_touch_config *get_driver_config(const struct d switch (config->connected_device) { case TH_SENSOR_WACOM: return &wacom_touch_config; case TH_SENSOR_ELAN: return &elan_touch_config; - case TH_SENSOR_GOOGLE: return &google_touch_config; + case TH_SENSOR_ELAN_REX: return &elan_rex_touch_config; case TH_SENSOR_HYNITRON: return &hynitron_touch_config; case TH_SENSOR_GENERIC: return config; case TH_SENSOR_NONE: return NULL; @@ -626,6 +626,10 @@ static const struct device_operations pci_thc_device_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_THC0_1, + PCI_DID_INTEL_NVL_THC0_2, + PCI_DID_INTEL_NVL_THC1_1, + PCI_DID_INTEL_NVL_THC1_2, PCI_DID_INTEL_MTL_THC0_SPI, PCI_DID_INTEL_MTL_THC1_SPI, PCI_DID_INTEL_PTL_U_H_THC0_I2C, diff --git a/src/drivers/lenovo/hybrid_graphics/chip.h b/src/drivers/lenovo/hybrid_graphics/chip.h index 4a17138552d..81d3552e98a 100644 --- a/src/drivers/lenovo/hybrid_graphics/chip.h +++ b/src/drivers/lenovo/hybrid_graphics/chip.h @@ -3,10 +3,6 @@ #ifndef _LENOVO_HYBRID_GRAPHICS_CHIP_H_ #define _LENOVO_HYBRID_GRAPHICS_CHIP_H_ -#define HYBRID_GRAPHICS_PORT 0xff - -#define HYBRID_GRAPHICS_DEVICE 0xf - enum hybrid_graphics_req { HYBRID_GRAPHICS_INTEGRATED = 0, HYBRID_GRAPHICS_DISCRETE = 1, diff --git a/src/drivers/lenovo/hybrid_graphics/romstage.c b/src/drivers/lenovo/hybrid_graphics/romstage.c index 10f94439f85..6860c958f39 100644 --- a/src/drivers/lenovo/hybrid_graphics/romstage.c +++ b/src/drivers/lenovo/hybrid_graphics/romstage.c @@ -5,11 +5,14 @@ #include #include #include +#include #include #include "hybrid_graphics.h" #include "chip.h" +WEAK_DEV_PTR(hg_mux); + /* * Returns the hybrid graphics presence and user's card preferences. */ @@ -19,9 +22,7 @@ void early_hybrid_graphics(bool *enable_igd, bool *enable_peg) const struct device *dev; enum hybrid_graphics_req mode; - /* TODO: Use generic device instead of dummy PNP device */ - dev = dev_find_slot_pnp(HYBRID_GRAPHICS_PORT, HYBRID_GRAPHICS_DEVICE); - + dev = DEV_PTR(hg_mux); if (!dev || !dev->chip_info) { printk(BIOS_ERR, "Hybrid graphics: ERROR\n"); *enable_igd = true; diff --git a/src/drivers/mipi/Kconfig b/src/drivers/mipi/Kconfig index 10d46628b44..80533ffd279 100644 --- a/src/drivers/mipi/Kconfig +++ b/src/drivers/mipi/Kconfig @@ -75,6 +75,9 @@ config MIPI_PANEL_STA_HIMAX83102_J02 config MIPI_PANEL_STA_ILI9882T bool +config MIPI_PANEL_TG_XTI05101 + bool + config MIPI_PANEL_TM_TL121BVMS07_00C bool diff --git a/src/drivers/mipi/Makefile.mk b/src/drivers/mipi/Makefile.mk index 92d5ebe9872..4aa4d1217b6 100644 --- a/src/drivers/mipi/Makefile.mk +++ b/src/drivers/mipi/Makefile.mk @@ -1,7 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -ramstage-y += panel.c - panel-params-y := panel-params-$(CONFIG_MIPI_PANEL_AUO_B101UAN08_3) += panel-AUO_B101UAN08_3 @@ -37,6 +35,8 @@ panel-params-$(CONFIG_MIPI_PANEL_STA_ER88577) += panel-STA_ER88577 panel-params-$(CONFIG_MIPI_PANEL_STA_HIMAX83102_J02) += panel-STA_HIMAX83102_J02 panel-params-$(CONFIG_MIPI_PANEL_STA_ILI9882T) += panel-STA_ILI9882T +panel-params-$(CONFIG_MIPI_PANEL_TG_XTI05101) += panel-TG_XTI05101 + panel-params-$(CONFIG_MIPI_PANEL_TM_TL121BVMS07_00C) += panel-TM_TL121BVMS07_00C panel-params-$(CONFIG_MIPI_PANEL_VIS_RM69299) += panel-VIS_RM69299 diff --git a/src/drivers/mipi/panel-BOE_NS130069_M00.c b/src/drivers/mipi/panel-BOE_NS130069_M00.c index 2e2accebfae..cf36af86486 100644 --- a/src/drivers/mipi/panel-BOE_NS130069_M00.c +++ b/src/drivers/mipi/panel-BOE_NS130069_M00.c @@ -576,8 +576,6 @@ struct panel_serializable_data BOE_NS130069_M00 = { .convert_rgb = 1, .simple_422 = false, .bits_per_pixel = 8 << 4, - .pic_height = 2190, - .pic_width = 3504, .slice_height = 30, .slice_width = 876, .slice_chunk_size = 876, diff --git a/src/drivers/mipi/panel-TG_XTI05101.c b/src/drivers/mipi/panel-TG_XTI05101.c new file mode 100644 index 00000000000..71a1ad0d0f3 --- /dev/null +++ b/src/drivers/mipi/panel-TG_XTI05101.c @@ -0,0 +1,227 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +struct panel_serializable_data TG_XTI05101 = { + .edid = { + .ascii_string = "XTI05101", + .manufacturer_name = "TG", + .panel_bits_per_color = 8, + .panel_bits_per_pixel = 24, + .mode = { + .pixel_clock = 69167, + .lvds_dual_channel = 0, + .refresh = 60, + .ha = 800, .hbl = 72, .hso = 24, .hspw = 24, + .va = 1280, .vbl = 42, .vso = 30, .vspw = 4, + .phsync = '-', .pvsync = '-', + .x_mm = 135, .y_mm = 216, + }, + }, + .init = { + PANEL_DELAY(24), + PANEL_DCS(0xE0, 0x00), + PANEL_DCS(0xE1, 0x93), + PANEL_DCS(0xE2, 0x65), + PANEL_DCS(0xE3, 0xF8), + PANEL_DCS(0x80, 0x03), + PANEL_DCS(0xE0, 0x01), + PANEL_DCS(0x0C, 0x74), + PANEL_DCS(0x17, 0x00), + PANEL_DCS(0x18, 0xD7), + PANEL_DCS(0x19, 0x01), + PANEL_DCS(0x1A, 0x00), + PANEL_DCS(0x1B, 0xD7), + PANEL_DCS(0x1C, 0x01), + PANEL_DCS(0x24, 0xFE), + PANEL_DCS(0x37, 0x19), + PANEL_DCS(0x35, 0x28), + PANEL_DCS(0x38, 0x05), + PANEL_DCS(0x39, 0x08), + PANEL_DCS(0x3A, 0x12), + PANEL_DCS(0x3C, 0x78), + PANEL_DCS(0x3D, 0xFF), + PANEL_DCS(0x3E, 0xFF), + PANEL_DCS(0x3F, 0x7F), + PANEL_DCS(0x40, 0x06), + PANEL_DCS(0x41, 0xA0), + PANEL_DCS(0x43, 0x1E), + PANEL_DCS(0x44, 0x0B), + PANEL_DCS(0x55, 0x02), + PANEL_DCS(0x57, 0x6A), + PANEL_DCS(0x59, 0x0A), + PANEL_DCS(0x5A, 0x2E), + PANEL_DCS(0x5B, 0x1A), + PANEL_DCS(0x5C, 0x15), + + /* -------- Gamma -------- */ + PANEL_DCS(0x5D, 0x7F), + PANEL_DCS(0x5E, 0x58), + PANEL_DCS(0x5F, 0x46), + PANEL_DCS(0x60, 0x39), + PANEL_DCS(0x61, 0x35), + PANEL_DCS(0x62, 0x27), + PANEL_DCS(0x63, 0x2B), + PANEL_DCS(0x64, 0x16), + PANEL_DCS(0x65, 0x30), + PANEL_DCS(0x66, 0x2E), + PANEL_DCS(0x67, 0x2F), + PANEL_DCS(0x68, 0x4D), + PANEL_DCS(0x69, 0x3C), + PANEL_DCS(0x6A, 0x43), + PANEL_DCS(0x6B, 0x36), + PANEL_DCS(0x6C, 0x31), + PANEL_DCS(0x6D, 0x24), + PANEL_DCS(0x6E, 0x14), + PANEL_DCS(0x6F, 0x02), + PANEL_DCS(0x70, 0x7F), + PANEL_DCS(0x71, 0x58), + PANEL_DCS(0x72, 0x46), + PANEL_DCS(0x73, 0x39), + PANEL_DCS(0x74, 0x35), + PANEL_DCS(0x75, 0x27), + PANEL_DCS(0x76, 0x2B), + PANEL_DCS(0x77, 0x16), + PANEL_DCS(0x78, 0x30), + PANEL_DCS(0x79, 0x2E), + PANEL_DCS(0x7A, 0x2F), + PANEL_DCS(0x7B, 0x4D), + PANEL_DCS(0x7C, 0x3C), + PANEL_DCS(0x7D, 0x43), + PANEL_DCS(0x7E, 0x36), + PANEL_DCS(0x7F, 0x31), + PANEL_DCS(0x80, 0x24), + PANEL_DCS(0x81, 0x14), + PANEL_DCS(0x82, 0x02), + + /* -------- Page 2 -------- */ + PANEL_DCS(0xE0, 0x02), + PANEL_DCS(0x00, 0x52), + PANEL_DCS(0x01, 0x5F), + PANEL_DCS(0x02, 0x5F), + PANEL_DCS(0x03, 0x50), + PANEL_DCS(0x04, 0x77), + PANEL_DCS(0x05, 0x57), + PANEL_DCS(0x06, 0x5F), + PANEL_DCS(0x07, 0x4E), + PANEL_DCS(0x08, 0x4C), + PANEL_DCS(0x09, 0x5F), + PANEL_DCS(0x0A, 0x4A), + PANEL_DCS(0x0B, 0x48), + PANEL_DCS(0x0C, 0x5F), + PANEL_DCS(0x0D, 0x46), + PANEL_DCS(0x0E, 0x44), + PANEL_DCS(0x0F, 0x40), + PANEL_DCS(0x10, 0x5F), + PANEL_DCS(0x11, 0x5F), + PANEL_DCS(0x12, 0x5F), + PANEL_DCS(0x13, 0x5F), + PANEL_DCS(0x14, 0x5F), + PANEL_DCS(0x15, 0x5F), + PANEL_DCS(0x16, 0x53), + PANEL_DCS(0x17, 0x5F), + PANEL_DCS(0x18, 0x5F), + PANEL_DCS(0x19, 0x51), + PANEL_DCS(0x1A, 0x77), + PANEL_DCS(0x1B, 0x57), + PANEL_DCS(0x1C, 0x5F), + PANEL_DCS(0x1D, 0x4F), + PANEL_DCS(0x1E, 0x4D), + PANEL_DCS(0x1F, 0x5F), + PANEL_DCS(0x20, 0x4B), + PANEL_DCS(0x21, 0x49), + PANEL_DCS(0x22, 0x5F), + PANEL_DCS(0x23, 0x47), + PANEL_DCS(0x24, 0x45), + PANEL_DCS(0x25, 0x41), + PANEL_DCS(0x26, 0x5F), + PANEL_DCS(0x27, 0x5F), + PANEL_DCS(0x28, 0x5F), + PANEL_DCS(0x29, 0x5F), + PANEL_DCS(0x2A, 0x5F), + PANEL_DCS(0x2B, 0x5F), + PANEL_DCS(0x2C, 0x13), + PANEL_DCS(0x2D, 0x1F), + PANEL_DCS(0x2E, 0x1F), + PANEL_DCS(0x2F, 0x01), + PANEL_DCS(0x30, 0x17), + PANEL_DCS(0x31, 0x17), + PANEL_DCS(0x32, 0x1F), + PANEL_DCS(0x33, 0x0D), + PANEL_DCS(0x34, 0x0F), + PANEL_DCS(0x35, 0x1F), + PANEL_DCS(0x36, 0x05), + PANEL_DCS(0x37, 0x07), + PANEL_DCS(0x38, 0x1F), + PANEL_DCS(0x39, 0x09), + PANEL_DCS(0x3A, 0x0B), + PANEL_DCS(0x3B, 0x11), + PANEL_DCS(0x3C, 0x1F), + PANEL_DCS(0x3D, 0x1F), + PANEL_DCS(0x3E, 0x1F), + PANEL_DCS(0x3F, 0x1F), + PANEL_DCS(0x40, 0x1F), + PANEL_DCS(0x41, 0x1F), + PANEL_DCS(0x42, 0x12), + PANEL_DCS(0x43, 0x1F), + PANEL_DCS(0x44, 0x1F), + PANEL_DCS(0x45, 0x00), + PANEL_DCS(0x46, 0x17), + PANEL_DCS(0x47, 0x17), + PANEL_DCS(0x48, 0x1F), + PANEL_DCS(0x49, 0x0C), + PANEL_DCS(0x4A, 0x0E), + PANEL_DCS(0x4B, 0x1F), + PANEL_DCS(0x4C, 0x04), + PANEL_DCS(0x4D, 0x06), + PANEL_DCS(0x4E, 0x1F), + PANEL_DCS(0x4F, 0x08), + PANEL_DCS(0x50, 0x0A), + PANEL_DCS(0x51, 0x10), + PANEL_DCS(0x52, 0x1F), + PANEL_DCS(0x53, 0x1F), + PANEL_DCS(0x54, 0x1F), + PANEL_DCS(0x55, 0x1F), + PANEL_DCS(0x56, 0x1F), + PANEL_DCS(0x57, 0x1F), + PANEL_DCS(0x58, 0x40), + PANEL_DCS(0x5B, 0x10), + PANEL_DCS(0x5C, 0x06), + PANEL_DCS(0x5D, 0x40), + PANEL_DCS(0x5E, 0x00), + PANEL_DCS(0x5F, 0x00), + PANEL_DCS(0x60, 0x40), + PANEL_DCS(0x61, 0x03), + PANEL_DCS(0x62, 0x04), + PANEL_DCS(0x63, 0x6C), + PANEL_DCS(0x64, 0x6C), + PANEL_DCS(0x65, 0x75), + PANEL_DCS(0x66, 0x08), + PANEL_DCS(0x67, 0xB4), + PANEL_DCS(0x68, 0x08), + PANEL_DCS(0x69, 0x6C), + PANEL_DCS(0x6A, 0x6C), + PANEL_DCS(0x6B, 0x0C), + PANEL_DCS(0x6D, 0x00), + PANEL_DCS(0x6E, 0x00), + PANEL_DCS(0x6F, 0x88), + PANEL_DCS(0x75, 0xBB), + PANEL_DCS(0x76, 0x00), + PANEL_DCS(0x77, 0x05), + PANEL_DCS(0x78, 0x2A), + PANEL_DCS(0xE0, 0x04), + PANEL_DCS(0x00, 0x0E), + PANEL_DCS(0x02, 0xB3), + PANEL_DCS(0x09, 0x61), + PANEL_DCS(0x0E, 0x48), + PANEL_DCS(0x2B, 0x0F), + PANEL_DCS(0x37, 0x58), + PANEL_DCS(0xE0, 0x00), + PANEL_DCS(0x11), + PANEL_DELAY(120), + PANEL_DCS(0x29), + PANEL_DELAY(20), + + PANEL_END, + }, +}; diff --git a/src/drivers/mipi/panel-TM_TL121BVMS07_00C.c b/src/drivers/mipi/panel-TM_TL121BVMS07_00C.c index e69d8ebc541..52b3e1ff1f3 100644 --- a/src/drivers/mipi/panel-TM_TL121BVMS07_00C.c +++ b/src/drivers/mipi/panel-TM_TL121BVMS07_00C.c @@ -22,6 +22,14 @@ struct panel_serializable_data TM_TL121BVMS07_00C = { PANEL_DELAY(24), PANEL_DCS(0xFF, 0x5A, 0xA5, 0x06), PANEL_DCS(0x3E, 0x62), + PANEL_DCS(0x90, 0x55), + PANEL_DCS(0x8F, 0xF0), + PANEL_DCS(0xFF, 0x5A, 0xA5, 0x08), + PANEL_DCS(0x82, 0x13), + PANEL_DCS(0x7D, 0x84), + PANEL_DCS(0x7F, 0xDA), + PANEL_DCS(0xFF, 0x5A, 0xA5, 0x05), + PANEL_DCS(0x3F, 0x47), PANEL_DCS(0xFF, 0x5A, 0xA5, 0x02), PANEL_DCS(0x1B, 0x20), PANEL_DCS(0x5D, 0x00), @@ -29,11 +37,18 @@ struct panel_serializable_data TM_TL121BVMS07_00C = { PANEL_DCS(0xFF, 0x5A, 0xA5, 0x07), PANEL_DCS(0X29, 0x00), PANEL_DCS(0xFF, 0x5A, 0xA5, 0x00), - PANEL_DCS(0x11), + PANEL_DCS(MIPI_DCS_EXIT_SLEEP_MODE), PANEL_DELAY(120), - PANEL_DCS(0x29), + PANEL_DCS(MIPI_DCS_SET_DISPLAY_ON), PANEL_DELAY(20), PANEL_END, }, + .poweroff = { + PANEL_DCS(MIPI_DCS_SET_DISPLAY_OFF), + PANEL_DELAY(20), + PANEL_DCS(MIPI_DCS_ENTER_SLEEP_MODE), + PANEL_DELAY(120), + PANEL_END, + }, .flags = PANEL_FLAG_CPHY, }; diff --git a/src/drivers/mipi/panel.c b/src/drivers/mipi/panel.c deleted file mode 100644 index 0182a8594a9..00000000000 --- a/src/drivers/mipi/panel.c +++ /dev/null @@ -1,80 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -enum cb_err mipi_panel_parse_init_commands(const void *buf, mipi_cmd_func_t cmd_func, - void *user_data) -{ - const struct panel_init_command *init = buf; - enum mipi_dsi_transaction type; - - /* - * The given commands should be in a buffer containing a packed array of - * panel_init_command and each element may be in variable size so we have - * to parse and scan. - */ - - for (; init->cmd != PANEL_CMD_END; init = (const void *)buf) { - /* - * For some commands like DELAY, the init->len should not be - * counted for buf. - */ - buf += sizeof(*init); - - u32 cmd = init->cmd, len = init->len; - - if (cmd == PANEL_CMD_DELAY) { - mdelay(len); - continue; - } - - switch (cmd) { - case PANEL_CMD_DCS: - switch (len) { - case 0: - printk(BIOS_ERR, "%s: DCS command length 0?\n", __func__); - return CB_ERR; - case 1: - type = MIPI_DSI_DCS_SHORT_WRITE; - break; - case 2: - type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; - break; - default: - type = MIPI_DSI_DCS_LONG_WRITE; - break; - } - break; - case PANEL_CMD_GENERIC: - switch (len) { - case 0: - type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM; - break; - case 1: - type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM; - break; - case 2: - type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM; - break; - default: - type = MIPI_DSI_GENERIC_LONG_WRITE; - break; - } - break; - default: - printk(BIOS_ERR, "%s: Unknown command code: %d, " - "abort panel initialization.\n", __func__, cmd); - return CB_ERR; - } - - enum cb_err ret = cmd_func(type, init->data, len, user_data); - if (ret != CB_SUCCESS) - return ret; - buf += len; - } - - return CB_SUCCESS; -} diff --git a/src/drivers/mrc_cache/mrc_cache.c b/src/drivers/mrc_cache/mrc_cache.c index a066fa8f3a6..e6b1ed20a77 100644 --- a/src/drivers/mrc_cache/mrc_cache.c +++ b/src/drivers/mrc_cache/mrc_cache.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -14,7 +15,6 @@ #include #include #include -#include #include "mrc_cache.h" diff --git a/src/drivers/option/cfr.c b/src/drivers/option/cfr.c index d5390231d6b..1a5f1d67d71 100644 --- a/src/drivers/option/cfr.c +++ b/src/drivers/option/cfr.c @@ -123,6 +123,21 @@ static uint32_t sm_write_enum_value(char *current, const struct sm_enum_value *e return enum_val->size; } + +static bool override_matches_numeric_tag(enum sm_object_kind override_kind, uint32_t tag) +{ + switch (tag) { + case CFR_TAG_OPTION_ENUM: + return override_kind == SM_OBJ_ENUM; + case CFR_TAG_OPTION_NUMBER: + return override_kind == SM_OBJ_NUMBER; + case CFR_TAG_OPTION_BOOL: + return override_kind == SM_OBJ_BOOL; + default: + return false; + } +} + static uint32_t write_numeric_option(char *current, uint32_t tag, const uint64_t object_id, const char *opt_name, const char *ui_name, const char *ui_helptext, uint32_t flags, uint32_t default_value, uint32_t min, uint32_t max, uint32_t step, @@ -135,10 +150,8 @@ static uint32_t write_numeric_option(char *current, uint32_t tag, const uint64_t /* Check for mainboard override of default value */ const struct cfr_default_override *ovr = find_override(opt_name); if (ovr) { - if (ovr->kind != tag) + if (!override_matches_numeric_tag(ovr->kind, tag)) printk(BIOS_WARNING, "CFR: override for option '%s' has mismatched type; skipping.\n", opt_name); - else if (tag == CFR_TAG_OPTION_BOOL) - default_value = ovr->bool_value; else default_value = ovr->uint_value; } diff --git a/src/drivers/smmstore/store.c b/src/drivers/smmstore/store.c index 35887b3c7f6..fa4c1e1b511 100644 --- a/src/drivers/smmstore/store.c +++ b/src/drivers/smmstore/store.c @@ -134,7 +134,7 @@ int smmstore_lookup_region(struct region_device *rstore) if (!done) { done = 1; - if (fmap_locate_area_as_rdev_rw(SMMSTORE_REGION, &rdev)) { + if (lookup_store(&rdev)) { printk(BIOS_WARNING, "smm store: Unable to find SMM store FMAP region '%s'\n", SMMSTORE_REGION); diff --git a/src/drivers/spi/boot_device_rw_nommap.c b/src/drivers/spi/boot_device_rw_nommap.c index 58efc87fe9c..86581600d13 100644 --- a/src/drivers/spi/boot_device_rw_nommap.c +++ b/src/drivers/spi/boot_device_rw_nommap.c @@ -8,6 +8,11 @@ static struct spi_flash sfg; static bool sfg_init_done; +__weak int boot_device_spi_cs(void) +{ + return 0; /* Default to chip select 0 */ +} + static ssize_t spi_readat(const struct region_device *rd, void *b, size_t offset, size_t size) { @@ -47,7 +52,7 @@ static const struct region_device spi_rw = static void boot_device_rw_init(void) { const int bus = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS; - const int cs = 0; + const int cs = boot_device_spi_cs(); if (sfg_init_done == true) return; diff --git a/src/drivers/spi/cbfs_spi.c b/src/drivers/spi/cbfs_spi.c index 15a18b72e4e..5f3b5ca40a0 100644 --- a/src/drivers/spi/cbfs_spi.c +++ b/src/drivers/spi/cbfs_spi.c @@ -17,6 +17,11 @@ static struct spi_flash spi_flash_info; static bool spi_flash_init_done; +__weak int boot_device_spi_cs(void) +{ + return 0; /* Default to chip select 0 */ +} + /* * SPI speed logging for big transfers available with BIOS_DEBUG. The format is: * @@ -82,7 +87,7 @@ static struct mmap_helper_region_device mdev = void boot_device_init(void) { int bus = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS; - int cs = 0; + int cs = boot_device_spi_cs(); if (spi_flash_init_done == true) return; diff --git a/src/drivers/spi/flashconsole.c b/src/drivers/spi/flashconsole.c index 679c814dffa..878cef0ce3e 100644 --- a/src/drivers/spi/flashconsole.c +++ b/src/drivers/spi/flashconsole.c @@ -87,18 +87,20 @@ void flashconsole_tx_flush(void) { size_t len = line_offset; size_t region_size; - static int busy; /* Prevent any recursive loops in case the spi flash driver * calls printk (in case of transaction timeout or * any other error while writing) */ - if (busy) - return; + static bool busy; - if (!rdev_ptr) + /* In addition to being an obvious runtime optimization, checking for + * len = 0 also prevents false disabling of the driver, as rdev_writeat + * seems to return -1 if len is zero even though this should be a + * recoverable condition. */ + if (busy || !rdev_ptr || len == 0) return; - busy = 1; + busy = true; region_size = region_device_sz(rdev_ptr); if (offset + len >= region_size) len = region_size - offset; @@ -113,5 +115,5 @@ void flashconsole_tx_flush(void) offset += len; line_offset = 0; - busy = 0; + busy = false; } diff --git a/src/drivers/usb/acpi/intel_bluetooth.c b/src/drivers/usb/acpi/intel_bluetooth.c index 4c882cde9d7..151f2bb18c2 100644 --- a/src/drivers/usb/acpi/intel_bluetooth.c +++ b/src/drivers/usb/acpi/intel_bluetooth.c @@ -14,16 +14,20 @@ * * Arg2 == 1: Set the reset delay based on Arg3 * - * Arg2 == 3: Set the reset method based on Arg3 (Not supported by this driver) - * WDISABLE2 (BT_RF_KILL_N) - * VSEC (PCI Config Space) + * Arg2 == 2: Reserved + * + * Arg2 == 3: Set the reset method based on Arg3 (required by Linux driver) + * Arg3 is a 4-byte buffer: [0x01, 0x00, type, 0x00] + * type 0 = WDISABLE2 (BT_RF_KILL_N) - supported by this driver + * type 1 = VSEC (PCI Config Space) - not supported */ static void check_reset_delay(void *arg) { acpigen_write_if_lequal_op_int(ARG1_OP, 0); { - acpigen_write_return_singleton_buffer(0x03); + /* Bits 0, 1, 3: other funcs, reset timing, set reset method (Linux) */ + acpigen_write_return_singleton_buffer(0x0b); } acpigen_write_else(); { @@ -37,12 +41,26 @@ static void set_reset_delay(void *arg) acpigen_write_store_op_to_namestr(ARG3_OP, "RDLY"); } +static void set_reset_method(void *arg) +{ + /* + * coreboot only supports WDISABLE2 (GPIO). Linux sends type in Arg3[2]. + * Accept and return success - _RST already implements GPIO toggle. + */ + acpigen_write_return_singleton_buffer(0x01); +} + static void not_supported(void *arg) { acpigen_write_return_singleton_buffer(0x00); } -void (*reset_supported[])(void *) = { check_reset_delay, set_reset_delay }; +void (*reset_supported[])(void *) = { + check_reset_delay, /* 0: capability query */ + set_reset_delay, /* 1: set delay */ + not_supported, /* 2: reserved */ + set_reset_method, /* 3: set reset method (required by Linux) */ +}; void (*reset_unsupported[])(void *) = { not_supported }; void acpi_device_intel_bt(const struct acpi_gpio *enable_gpio, @@ -50,34 +68,14 @@ void acpi_device_intel_bt(const struct acpi_gpio *enable_gpio, bool audio_offload) { /* - * Name (_S0W, 3) - */ - if (get_uint_option("bluetooth_rtd3", 1)) - acpigen_write_name_integer("_S0W", ACPI_DEVICE_SLEEP_D3_HOT); - else - acpigen_write_name_integer("_S0W", ACPI_DEVICE_SLEEP_D0); - -/* - * Name (_DSD, Package (0x02) - * { - * ToUUID ("6211e2c0-58a3-4af3-90e1-927a4e0c55a4") - * Package (0x01) - * { - * Package (0x02) - * { - * "HotPlugSupportInD3", - * One - * } - * } - * }) - * + * Name (_S0W, 2) */ - acpi_device_add_hotplug_support_in_d3(NULL); + acpigen_write_name_integer("_S0W", ACPI_DEVICE_SLEEP_D2); /* - * Name (RDLY, 0x69) + * Name (RDLY, 160) // ms, matches Linux driver default */ - acpigen_write_name_integer("RDLY", 0x69); + acpigen_write_name_integer("RDLY", 160); /* * Method (_DSM, 4, Serialized) @@ -128,7 +126,7 @@ void acpi_device_intel_bt(const struct acpi_gpio *enable_gpio, acpigen_write_dsm_uuid_arr(uuid_callbacks, ARRAY_SIZE(uuid_callbacks)); /* - * PowerResource (BTRT, 0, 0) + * PowerResource (BTRT, 0x05, 0) * { * Method (_STA, 0, NotSerialized) * { @@ -159,7 +157,7 @@ void acpi_device_intel_bt(const struct acpi_gpio *enable_gpio, * } * } */ - acpigen_write_power_res("BTRT", 0, 0, NULL, 0); + acpigen_write_power_res("BTRT", 5, 0, NULL, 0); { acpigen_write_method("_STA", 0); { diff --git a/src/drivers/wwan/fm/acpi_fm350gl.c b/src/drivers/wwan/fm/acpi_fm350gl.c index 564ac03cfc2..07054e33cb5 100644 --- a/src/drivers/wwan/fm/acpi_fm350gl.c +++ b/src/drivers/wwan/fm/acpi_fm350gl.c @@ -285,18 +285,19 @@ wwan_fm350gl_acpi_event_method(const struct device *dev, if (CONFIG(GENERIC_GPIO_LIB)) pin = gpio_acpi_pin(pin); - if (pin > 0xff) { - printk(BIOS_ERR, "%s: pins above 0xFF are unsupported (pin %u)\n", - __func__, pin); - return; + if (pin <= 0xff) { + snprintf(name, sizeof(name), "_%c%02X", + wake_gpio->irq.mode == ACPI_IRQ_EDGE_TRIGGERED ? 'E' : 'L', pin); + acpigen_write_method_serialized(name, 0); + acpigen_notify(acpi_device_path(dev), 0x02); /* NOTIFY_DEVICE_WAKE */ + acpigen_write_method_end(); + } else { + acpigen_write_method_serialized("_EVT", 1); + acpigen_write_if_lequal_op_int(ARG0_OP, pin); + acpigen_notify(acpi_device_path(dev), 0x02); /* NOTIFY_DEVICE_WAKE */ + acpigen_pop_len(); + acpigen_write_method_end(); } - - snprintf(name, sizeof(name), "_%c%02X", - wake_gpio->irq.mode == ACPI_IRQ_EDGE_TRIGGERED ? 'E' : 'L', pin); - - acpigen_write_method_serialized(name, 0); - acpigen_notify(acpi_device_path(dev), 0x02); /* NOTIFY_DEVICE_WAKE */ - acpigen_write_method_end(); } static void wwan_fm350gl_acpi_gpio_events(const struct device *dev) diff --git a/src/ec/google/chromeec/Kconfig b/src/ec/google/chromeec/Kconfig index 9213e24302b..081f7cb754f 100644 --- a/src/ec/google/chromeec/Kconfig +++ b/src/ec/google/chromeec/Kconfig @@ -220,6 +220,17 @@ config EC_GOOGLE_CHROMEEC_READ_BATTERY_LONG_STRING If unsure, say N. +config EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND + bool + help + Enable the ACPI "full battery" workaround (BFWK) for remaining capacity. + When enabled, remaining charge near full is reported as full capacity to + hide 93-100% charge-discharge cycles and to handle batteries that don't report + full capacity timely. + Select this for older boards whose EC firmware lacks battery_compensate_params + logic. + If unsure, say N. + config EC_GOOGLE_CHROMEEC_LPC_GENERIC_MEMORY_RANGE def_bool n help @@ -234,6 +245,28 @@ config EC_GOOGLE_CHROMEEC_LPC_GENERIC_MEMORY_SIZE hex default 0x10000 +config EC_GOOGLE_CHROMEEC_BATTERY_SOC_DYNAMIC + bool + default n + help + Enable this option to calculate the battery State of Charge (SoC) + manually using remaining and full capacity metrics. + + On certain platforms, such as Qualcomm X1P42100 (Hamoa), the AP + cannot use the standard CHARGE_STATE_CMD_GET_STATE host command + while in the S0 power state due to hardware arbitration or + access restrictions to the battery fuel gauge. + + Selecting this option forces the use of ec_cmd_battery_get_dynamic(), + which retrieves cached telemetry from the EC rather than triggering + a synchronous bus transaction to the battery. + +config EC_GOOGLE_CHROMEEC_LED_CONTROL + bool + help + Enable manual AP control over ChromeEC LEDs/lightbars to ensure + visual continuity with AP-side boot animations. + endif # EC_GOOGLE_CHROMEEC source "src/ec/google/chromeec/*/Kconfig" diff --git a/src/ec/google/chromeec/acpi/battery.asl b/src/ec/google/chromeec/acpi/battery.asl index 41b77861a56..eb19c3c4225 100644 --- a/src/ec/google/chromeec/acpi/battery.asl +++ b/src/ec/google/chromeec/acpi/battery.asl @@ -414,8 +414,9 @@ Device (BAT0) }) Name (BSTP, 0) - // Workaround for full battery status, disabled by default - Name (BFWK, 0) + // Workaround for full battery status, disabled by default, + // enabled via Kconfig for older boards lacking EC compensation. + Name (BFWK, CONFIG(EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND)) // Method to enable full battery workaround Method (BFWE) @@ -504,8 +505,9 @@ Device (BAT1) }) Name (BSTP, 0) - // Workaround for full battery status, disabled by default - Name (BFWK, 0) + // Workaround for full battery status, disabled by default, + // enabled via Kconfig for older boards lacking EC compensation. + Name (BFWK, CONFIG(EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND)) // Method to enable full battery workaround Method (BFWE) diff --git a/src/ec/google/chromeec/acpi/ec.asl b/src/ec/google/chromeec/acpi/ec.asl index ebba0faffdb..93b04718ec8 100644 --- a/src/ec/google/chromeec/acpi/ec.asl +++ b/src/ec/google/chromeec/acpi/ec.asl @@ -589,7 +589,7 @@ Device (EC0) \_SB.DPTF.TEVT (Local0) #endif - /* Keep reaading sensor ID for event */ + /* Keep reading sensor ID for event */ Local0 = ^PATI } diff --git a/src/ec/google/chromeec/cfr.h b/src/ec/google/chromeec/cfr.h index 2972bd5424a..07ca0e9b68c 100644 --- a/src/ec/google/chromeec/cfr.h +++ b/src/ec/google/chromeec/cfr.h @@ -14,20 +14,15 @@ static void update_fan_control(struct sm_object *new) { if (!CONFIG(EC_GOOGLE_CHROMEEC_AUTO_FAN_CTRL) && !google_chromeec_has_fan()) { new->sm_bool.flags = CFR_OPTFLAG_SUPPRESS; - new->sm_bool.default_value = 0; + new->sm_bool.default_value = false; } } -static const struct sm_object auto_fan_control = SM_DECLARE_ENUM({ +static const struct sm_object auto_fan_control = SM_DECLARE_BOOL({ .opt_name = "auto_fan_control", .ui_name = "Automatic Fan Control", .ui_helptext = "Enable or disable automatic fan control.", .default_value = CONFIG(EC_GOOGLE_CHROMEEC_AUTO_FAN_CTRL), - .values = (struct sm_enum_value[]) { - { "Enabled", 1 }, - { "Disabled", 0 }, - SM_ENUM_VALUE_END, - }, }, WITH_CALLBACK(update_fan_control)); static const struct sm_enum_value ec_backlight_values[] = { diff --git a/src/ec/google/chromeec/ec.c b/src/ec/google/chromeec/ec.c index 03ae01c03d0..5b89dac265d 100644 --- a/src/ec/google/chromeec/ec.c +++ b/src/ec/google/chromeec/ec.c @@ -795,6 +795,15 @@ int rtc_get(struct rtc_time *time) } #endif +int google_chromeec_offmode_heartbeat(void) +{ + struct chromeec_command cmd = { + .cmd_code = EC_CMD_ENABLE_OFFMODE_HEARTBEAT, + }; + + return google_chromeec_command(&cmd); +} + int google_chromeec_reboot(enum ec_reboot_cmd type, uint8_t flags) { const struct ec_params_reboot_ec params = { @@ -841,7 +850,12 @@ static int cbi_read(void *buf, size_t bufsize, uint32_t tag, bool check_size) static int cbi_get_uint32(uint32_t *id, uint32_t tag) { - return cbi_read(id, sizeof(*id), tag, true); + uint32_t r = 0; + int rv = cbi_read(&r, sizeof(r), tag, true); + if (rv) + return rv; + *id = r; + return 0; } int google_chromeec_cbi_get_sku_id(uint32_t *id) @@ -1860,3 +1874,215 @@ void platform_do_early_poweroff(void) google_chromeec_reboot(EC_REBOOT_COLD_AP_OFF, 0); halt(); } + +/* + * Reads the current battery charge percentage using CHARGE_STATE_CMD_GET_STATE CMD. + * + * This function communicates with the Embedded Controller (EC) via a host + * command to retrieve the "State of Charge" (SoC) as calculated by the battery fuel gauge. + * + * Return: 0 on success, -1 on failure (communication error or EC rejection). + * Return Value (state): Pointer to a uint32_t where the battery state of charge + * (0-100) will be stored. + */ +static int google_chromeec_read_batt_state_of_charge_cmd(uint32_t *state) +{ + struct ec_params_charge_state params; + struct ec_response_charge_state resp; + + params.cmd = CHARGE_STATE_CMD_GET_STATE; + + if (ec_cmd_charge_state(PLAT_EC, ¶ms, &resp) < 0) + return -1; + + *state = resp.get_state.batt_state_of_charge; + return 0; +} + +/* + * Calculates SoC from dynamic battery data. + * + * This function fetches "dynamic" battery metrics (voltage, current, and capacity) + * and manually calculates the percentage. This is often used when the high-level + * "Get Charge State" command is unavailable. + * + * Return: 0 on success, -1 on communication failure or invalid battery data. + * Return Value (state): Pointer to store the calculated State of Charge (0-100%). + */ +static int google_chromeec_read_batt_state_of_charge_raw(uint32_t *state) +{ + struct ec_params_battery_dynamic_info params = { + .index = 0, + }; + struct ec_response_battery_dynamic_info resp; + + if (ec_cmd_battery_get_dynamic(PLAT_EC, ¶ms, &resp) != 0) + return -1; + + if (resp.full_capacity <= 0) + return -1; + + uint32_t soc = (uint32_t)resp.remaining_capacity * 100 / (uint32_t)resp.full_capacity; + + /* Clamp the value to 100% (some fuel gauges report slight overflows) */ + if (soc > 100) + soc = 100; + + *state = soc; + + return 0; +} + +/* + * Reads the current battery charge percentage. + * + * This function communicates with the Embedded Controller (EC) via a host + * command to retrieve the "State of Charge" (SoC) as calculated by the battery fuel gauge. + * + * Return: 0 on success, -1 on failure (communication error or EC rejection). + * Return Value (state): Pointer to a uint32_t where the battery state of charge + * (0-100) will be stored. + */ +int google_chromeec_read_batt_state_of_charge(uint32_t *state) +{ + int ret; + + if (CONFIG(EC_GOOGLE_CHROMEEC_BATTERY_SOC_DYNAMIC)) + ret = google_chromeec_read_batt_state_of_charge_raw(state); + else + ret = google_chromeec_read_batt_state_of_charge_cmd(state); + + return ret; +} + +/* + * Set the RGB color of a specific LED on the Lightbar. + * + * This function communicates with the Embedded Controller (EC) + * to update the color of an individual LED. + * + * led: The index of the LED to be updated. + * red: Red intensity value (0x00 - 0xff). + * green: Green intensity value (0x00 - 0xff). + * blue: Blue intensity value (0x00 - 0xff). + * Return: 0 on success, or a non-zero error code from the EC host command. + */ +int google_chromeec_set_lightbar_rgb(unsigned int led, int red, int green, + int blue) +{ + const struct ec_params_lightbar req = { + .cmd = LIGHTBAR_CMD_SET_RGB, + .set_rgb = { + .led = led, + .red = red, + .green = green, + .blue = blue + } + }; + + struct chromeec_command cmd = { + .cmd_code = EC_CMD_LIGHTBAR_CMD, + .cmd_size_out = 0, + .cmd_data_out = NULL, + .cmd_size_in = sizeof(req), + .cmd_data_in = &req, + }; + + return google_chromeec_command(&cmd); +} + +/* + * Sends a command to turn off the Chrome EC lightbar. + * + * This function packages a LIGHTBAR_CMD_OFF sub-command into a standard + * EC_CMD_LIGHTBAR_CMD packet. + * + * @return 0 on success, non-zero error code from the EC transport on failure. + */ +int google_chromeec_lightbar_off(void) +{ + const struct ec_params_lightbar req = { + .cmd = LIGHTBAR_CMD_OFF, + }; + + struct chromeec_command cmd = { + .cmd_code = EC_CMD_LIGHTBAR_CMD, + .cmd_size_out = 0, + .cmd_data_out = NULL, + .cmd_size_in = sizeof(req), + .cmd_data_in = &req, + }; + + return google_chromeec_command(&cmd); +} + +/* + * Sends a command to enable the Chrome EC lightbar. + * + * This function wraps the LIGHTBAR_CMD_ON sub-command into a standard + * EC_CMD_LIGHTBAR_CMD host command. + * + * @return 0 on success, or a non-zero EC transport error code on failure. + */ +int google_chromeec_lightbar_on(void) +{ + const struct ec_params_lightbar req = { + .cmd = LIGHTBAR_CMD_ON, + }; + + struct chromeec_command cmd = { + .cmd_code = EC_CMD_LIGHTBAR_CMD, + .cmd_size_out = 0, + .cmd_data_out = NULL, + .cmd_size_in = sizeof(req), + .cmd_data_in = &req, + }; + + return google_chromeec_command(&cmd); +} + + +/* + * Check if the battery is critically low and not currently charging. + * + * Return true if battery is below threshold and AC is not present. + */ +bool google_chromeec_is_critically_low_on_battery(void) +{ + return google_chromeec_is_below_critical_threshold() && + !google_chromeec_is_charger_present(); +} + +#if !CONFIG(EC_GOOGLE_CHROMEEC_LPC) +static int google_chromeec_read_memmap(uint8_t offset, uint8_t size, void *dest) +{ + struct ec_params_read_memmap params; + + params.offset = offset; + params.size = size; + + struct chromeec_command cmd = { + .cmd_code = EC_CMD_READ_MEMMAP, + .cmd_version = 0, + .cmd_data_in = ¶ms, + .cmd_data_out = dest, + .cmd_size_in = sizeof(params), + .cmd_size_out = size, + }; + + return google_chromeec_command(&cmd); +} + +/* + * Return the byte of EC switch states e.g. lid state + */ +uint8_t google_chromeec_get_switches(void) +{ + uint8_t flags; + + if (google_chromeec_read_memmap(EC_MEMMAP_SWITCHES, sizeof(flags), &flags)) + return 0; + + return flags; +} +#endif diff --git a/src/ec/google/chromeec/ec.h b/src/ec/google/chromeec/ec.h index 2f29b9d21c3..aadd51ff22f 100644 --- a/src/ec/google/chromeec/ec.h +++ b/src/ec/google/chromeec/ec.h @@ -110,6 +110,8 @@ int google_chromeec_reboot(enum ec_reboot_cmd type, uint8_t flags); void google_chromeec_ap_poweroff(void); +int google_chromeec_offmode_heartbeat(void); + /** * Get data from Cros Board Info * @@ -538,4 +540,55 @@ bool chipset_emi_write_bytes(u16 port, size_t length, u8 *msg, u8 *csum); */ void chipset_ioport_range(uint16_t *base, size_t *size); +/* + * Reads the current battery charge percentage. + * + * @param state Pointer to a uint32_t where the battery state of charge (0-100) will be + * stored. + */ +int google_chromeec_read_batt_state_of_charge(uint32_t *state); + +/* + * Set the RGB color of a specific LED on the Lightbar. + * + * This function communicates with the Embedded Controller (EC) + * to update the color of an individual LED. + * + * @param led: The index of the LED to be updated. + * @param red: Red intensity value (0x00 - 0xff). + * @param green: Green intensity value (0x00 - 0xff). + * @param blue: Blue intensity value (0x00 - 0xff). + * + * @return 0 on success, or a non-zero error code from the EC host command. + */ +int google_chromeec_set_lightbar_rgb(unsigned int led, int red, int green, + int blue); + +/* + * Sends a command to turn off the Chrome EC lightbar. + * + * This function packages a LIGHTBAR_CMD_OFF sub-command into a standard + * EC_CMD_LIGHTBAR_CMD packet. + * + * @return 0 on success, non-zero error code from the EC transport on failure. + */ +int google_chromeec_lightbar_off(void); + +/* + * Sends a command to enable the Chrome EC lightbar. + * + * This function wraps the LIGHTBAR_CMD_ON sub-command into a standard + * EC_CMD_LIGHTBAR_CMD host command. + * + * @return 0 on success, or a non-zero EC transport error code on failure. + */ +int google_chromeec_lightbar_on(void); + +/* + * Check if the battery is critically low and AC is not present. + * + * Return true if battery is below threshold and AC is not present. + */ +bool google_chromeec_is_critically_low_on_battery(void); + #endif /* _EC_GOOGLE_CHROMEEC_EC_H */ diff --git a/src/ec/google/chromeec/switches.c b/src/ec/google/chromeec/switches.c index e35e7722eaf..066a788f712 100644 --- a/src/ec/google/chromeec/switches.c +++ b/src/ec/google/chromeec/switches.c @@ -5,7 +5,6 @@ #include #include -#if CONFIG(EC_GOOGLE_CHROMEEC_LPC) /* * Retrieves the state of the lid switch. * @@ -32,7 +31,6 @@ int get_lid_switch(void) return !!(google_chromeec_get_switches() & EC_SWITCH_LID_OPEN); } -#endif int get_recovery_mode_switch(void) { diff --git a/src/ec/lenovo/h8/acpi/ec.asl b/src/ec/lenovo/h8/acpi/ec.asl index bc54d3b4221..fe39c197618 100644 --- a/src/ec/lenovo/h8/acpi/ec.asl +++ b/src/ec/lenovo/h8/acpi/ec.asl @@ -335,3 +335,52 @@ Device(EC) #include "systemstatus.asl" #include "thinkpad.asl" } + +#if CONFIG(EC_LENOVO_H8) +// EC SMM interface +Device(ECMM) +{ + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 10) + + Name (_CRS, ResourceTemplate() { + IO (Decode16, 0x1600, 0x1600, 1, 1) + IO (Decode16, 0x1604, 0x1604, 1, 1) + }) +} + +// EC Gravity sensor interface +Device(ECGS) +{ + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 11) + + Name (_CRS, ResourceTemplate() { + IO (Decode16, 0x1602, 0x1602, 1, 1) + IO (Decode16, 0x1606, 0x1606, 1, 1) + }) +} + +// Battery two wire interface +Device(TWRI) +{ + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 12) + + Name (_CRS, ResourceTemplate() { + IO (Decode16, 0x1610, 0x1610, 16, 16) + }) +} +#endif + +#if CONFIG(EC_LENOVO_PMH7) +Device(PMH7) +{ + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 13) + + Name (_CRS, ResourceTemplate() { + IO (Decode16, 0x15e0, 0x15e0, 16, 16) + }) +} +#endif diff --git a/src/ec/lenovo/h8/cfr.h b/src/ec/lenovo/h8/cfr.h index b410f2d449a..fbda80471a3 100644 --- a/src/ec/lenovo/h8/cfr.h +++ b/src/ec/lenovo/h8/cfr.h @@ -11,27 +11,19 @@ #include "h8.h" /* Bluetooth */ -static const struct sm_object bluetooth = SM_DECLARE_ENUM({ +static const struct sm_object bluetooth = SM_DECLARE_BOOL({ .opt_name = "bluetooth", .ui_name = "Bluetooth", .ui_helptext = "Enable or disable the bluetooth module", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* Keyboard Backlight */ -static const struct sm_object backlight = SM_DECLARE_ENUM({ +static const struct sm_object backlight = SM_DECLARE_BOOL({ .opt_name = "backlight", .ui_name = "Keyboard Backlight", .ui_helptext = "Enable or disable the keyboard backlight", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = false, }); /* USB Always-On */ @@ -48,15 +40,11 @@ static const struct sm_object usb_always_on = SM_DECLARE_ENUM({ }); /* Ultrawideband */ -static const struct sm_object uwb = SM_DECLARE_ENUM({ +static const struct sm_object uwb = SM_DECLARE_BOOL({ .opt_name = "uwb", .ui_name = "Ultrawideband", .ui_helptext = "TBD", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* Volume control */ @@ -72,87 +60,59 @@ static const struct sm_object volume = SM_DECLARE_ENUM({ }); /* WLAN */ -static const struct sm_object wlan = SM_DECLARE_ENUM({ +static const struct sm_object wlan = SM_DECLARE_BOOL({ .opt_name = "wlan", .ui_name = "WLAN", .ui_helptext = "Enable or disable the WLAN module", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* WWAN */ -static const struct sm_object wwan = SM_DECLARE_ENUM({ +static const struct sm_object wwan = SM_DECLARE_BOOL({ .opt_name = "wwan", .ui_name = "WWAN", .ui_helptext = "Enable or disable the WWAN module", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* Power Management Beeps */ -static const struct sm_object pm_beeps = SM_DECLARE_ENUM({ +static const struct sm_object pm_beeps = SM_DECLARE_BOOL({ .opt_name = "power_management_beeps", .ui_name = "Power Management Beeps", .ui_helptext = "Enable or disable power management beeps", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* Low Battery Beep */ -static const struct sm_object battery_beep = SM_DECLARE_ENUM({ +static const struct sm_object battery_beep = SM_DECLARE_BOOL({ .opt_name = "low_battery_beep", .ui_name = "Low Battery Beep", .ui_helptext = "Enable or disable low battery beep", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* Fn-CTRL Swap */ -static const struct sm_object fn_ctrl_swap = SM_DECLARE_ENUM({ +static const struct sm_object fn_ctrl_swap = SM_DECLARE_BOOL({ .opt_name = "fn_ctrl_swap", .ui_name = "Swap Fn and CTRL", .ui_helptext = "Swap the left Fn and CTRL keys", .default_value = CONFIG(H8_FN_CTRL_SWAP), - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, }); /* Fn Lock */ -static const struct sm_object sticky_fn = SM_DECLARE_ENUM({ +static const struct sm_object sticky_fn = SM_DECLARE_BOOL({ .opt_name = "sticky_fn", .ui_name = "Sticky Fn key", .ui_helptext = "Function key acts as a toggle", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = false, }); /* Function keys primary */ -static const struct sm_object f1_to_f12_as_primary = SM_DECLARE_ENUM({ +static const struct sm_object f1_to_f12_as_primary = SM_DECLARE_BOOL({ .opt_name = "f1_to_f12_as_primary", .ui_name = "Primary Function keys", .ui_helptext = "F1-F12 default act as function keys", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); #endif /* _LENOVO_H8_CFR_H_ */ diff --git a/src/ec/lenovo/h8/h8.c b/src/ec/lenovo/h8/h8.c index acf5ce54086..1ea3ccfa405 100644 --- a/src/ec/lenovo/h8/h8.c +++ b/src/ec/lenovo/h8/h8.c @@ -81,6 +81,34 @@ static void f1_to_f12_as_primary(int on) ec_clr_bit(0x3b, 3); } +static u8 h8_build_id_and_function_spec_version(char *buf, u8 buf_len) +{ + static char str[16 + 1]; /* 16 ASCII chars + \0 */ + u8 i, c; + + if (!str[0]) { + /* Build ID */ + for (i = 0; i < 8; i++) { + c = ec_read(H8_EC_BUILD_ID + i); + if (c < 0x20 || c > 0x7f) { + i = snprintf(str, sizeof(str), "*INVALID"); + break; + } + str[i] = c; + } + + /* Lenovo EC firmware function specification version */ + i += snprintf(str + i, sizeof(str) - i, "-%u.%u", + ec_read(H8_EC_FUNC_MAJOR_VER), ec_read(H8_EC_FUNC_MINOR_VER)); + } else + i = strlen(str); + + i = MIN(buf_len, i); + memcpy(buf, str, i); + + return i; +} + static void h8_log_ec_version(void) { char ecfw[17]; @@ -90,8 +118,8 @@ static void h8_log_ec_version(void) len = h8_build_id_and_function_spec_version(ecfw, sizeof(ecfw) - 1); ecfw[len] = 0; - fwvh = ec_read(0xe9); - fwvl = ec_read(0xe8); + fwvh = ec_read(H8_EC_FIRMWARE_MAJOR_VER); + fwvl = ec_read(H8_EC_FIRMWARE_MINOR_VER); printk(BIOS_INFO, "H8: EC Firmware ID %s, Version %d.%d%d%c\n", ecfw, fwvh >> 4, fwvh & 0x0f, fwvl >> 4, 0x41 + (fwvl & 0xf)); @@ -162,30 +190,6 @@ int h8_ultrabay_device_present(void) return ec_read(H8_STATUS1) & 0x5 ? 0 : 1; } -u8 h8_build_id_and_function_spec_version(char *buf, u8 buf_len) -{ - u8 i, c; - char str[16 + 1]; /* 16 ASCII chars + \0 */ - - /* Build ID */ - for (i = 0; i < 8; i++) { - c = ec_read(0xf0 + i); - if (c < 0x20 || c > 0x7f) { - i = snprintf(str, sizeof(str), "*INVALID"); - break; - } - str[i] = c; - } - - /* EC firmware function specification version */ - i += snprintf(str + i, sizeof(str) - i, "-%u.%u", ec_read(0xef), ec_read(0xeb)); - - i = MIN(buf_len, i); - memcpy(buf, str, i); - - return i; -} - #if CONFIG(GENERATE_SMBIOS_TABLES) static void h8_smbios_strings(struct device *dev, struct smbios_type11 *t) { @@ -209,6 +213,15 @@ static const char *h8_acpi_name(const struct device *dev) } #endif +static void h8_read_resources(struct device *dev) +{ + static const u16 ports[] = {0x60, 0x64, 0x62, 0x66, 0x1600, 0x1604, 0x1602, 0x1606}; + for (int i = 0; i < ARRAY_SIZE(ports); i++) + fixed_io_range_flags(dev, ports[i], ports[i], 1, IORESOURCE_ASSIGNED); + + fixed_io_range_flags(dev, 0x1610, 0x1610, 16, IORESOURCE_ASSIGNED); +} + struct device_operations h8_dev_ops = { #if CONFIG(GENERATE_SMBIOS_TABLES) .get_smbios_strings = h8_smbios_strings, @@ -217,6 +230,8 @@ struct device_operations h8_dev_ops = { .acpi_fill_ssdt = h8_ssdt_generator, .acpi_name = h8_acpi_name, #endif + .read_resources = h8_read_resources, + .set_resources = noop_set_resources, .init = h8_init, }; diff --git a/src/ec/lenovo/h8/h8.h b/src/ec/lenovo/h8/h8.h index 40816117b15..88d7b07136f 100644 --- a/src/ec/lenovo/h8/h8.h +++ b/src/ec/lenovo/h8/h8.h @@ -20,7 +20,6 @@ void h8_usb_power_enable(int on); void h8_enable_event(int event); void h8_disable_event(int event); int h8_ultrabay_device_present(void); -u8 h8_build_id_and_function_spec_version(char *buf, u8 buf_len); void h8_usb_always_on(void); int h8_get_fn_key(void); @@ -141,4 +140,12 @@ void h8_mb_init(void); #define H8_EVENT_FN_F5 0x64 #define H8_EVENT_FN_F6 0x65 +#define H8_EC_FIRMWARE_MINOR_VER 0xe8 +#define H8_EC_FIRMWARE_MAJOR_VER 0xe9 + +#define H8_EC_FUNC_MINOR_VER 0xeb +#define H8_EC_FUNC_MAJOR_VER 0xef + +#define H8_EC_BUILD_ID 0xf0 + #endif /* EC_LENOVO_H8_H */ diff --git a/src/ec/lenovo/pmh7/cfr.h b/src/ec/lenovo/pmh7/cfr.h index 329fb56a3ee..bda05edeea2 100644 --- a/src/ec/lenovo/pmh7/cfr.h +++ b/src/ec/lenovo/pmh7/cfr.h @@ -10,27 +10,19 @@ #include /* Touchpad */ -static const struct sm_object touchpad = SM_DECLARE_ENUM({ +static const struct sm_object touchpad = SM_DECLARE_BOOL({ .opt_name = "touchpad", .ui_name = "Touchpad", .ui_helptext = "Enable or disable the touchpad", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* Trackpoint */ -static const struct sm_object trackpoint = SM_DECLARE_ENUM({ +static const struct sm_object trackpoint = SM_DECLARE_BOOL({ .opt_name = "trackpoint", .ui_name = "Trackpoint", .ui_helptext = "Enable or disable the trackpoint", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); #endif /* _LENOVO_PMH7_CFR_H_ */ diff --git a/src/ec/lenovo/pmh7/pmh7.c b/src/ec/lenovo/pmh7/pmh7.c index 95502f3d889..00d34edb568 100644 --- a/src/ec/lenovo/pmh7/pmh7.c +++ b/src/ec/lenovo/pmh7/pmh7.c @@ -101,17 +101,23 @@ void pmh7_register_write(int reg, int val) outb(val, EC_LENOVO_PMH7_DATA); } +#if ENV_RAMSTAGE +static void pmh7_read_resources(struct device *dev) +{ + fixed_io_range_flags(dev, EC_LENOVO_PMH7_BASE, EC_LENOVO_PMH7_BASE, + 16, IORESOURCE_ASSIGNED); +} + +struct device_operations pmh7_dev_ops = { + .read_resources = pmh7_read_resources, + .set_resources = noop_set_resources, +}; + static void enable_dev(struct device *dev) { const struct ec_lenovo_pmh7_config *conf = dev->chip_info; - struct resource *resource; - resource = new_resource(dev, EC_LENOVO_PMH7_INDEX); - resource->base = EC_LENOVO_PMH7_BASE; - resource->size = 16; - resource->align = 5; - resource->gran = 5; - resource->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_ASSIGNED; + dev->ops = &pmh7_dev_ops; pmh7_backlight_enable(conf->backlight_enable); pmh7_dock_event_enable(conf->dock_event_enable); @@ -129,3 +135,4 @@ struct chip_operations ec_lenovo_pmh7_ops = { .name = "Lenovo Power Management Hardware Hub 7", .enable_dev = enable_dev, }; +#endif diff --git a/src/ec/lenovo/pmh7/pmh7.h b/src/ec/lenovo/pmh7/pmh7.h index 61dc1137d39..b06e79920d5 100644 --- a/src/ec/lenovo/pmh7/pmh7.h +++ b/src/ec/lenovo/pmh7/pmh7.h @@ -5,8 +5,6 @@ #include -#define EC_LENOVO_PMH7_INDEX 0x77 - #define EC_LENOVO_PMH7_BASE 0x15e0 #define EC_LENOVO_PMH7_ADDR_L (EC_LENOVO_PMH7_BASE + 0x0c) #define EC_LENOVO_PMH7_ADDR_H (EC_LENOVO_PMH7_BASE + 0x0d) diff --git a/src/ec/starlabs/merlin/Kconfig b/src/ec/starlabs/merlin/Kconfig index c21ac68a0a8..0d2c6378b83 100644 --- a/src/ec/starlabs/merlin/Kconfig +++ b/src/ec/starlabs/merlin/Kconfig @@ -1,5 +1,12 @@ ## SPDX-License-Identifier: GPL-2.0-only +config EC_STARLABS_MERLIN + bool + default n + help + Use open source embedded controller firmware. Both firmwares have the + same features but differ in licensing and compilers. + config EC_STARLABS_NUVOTON bool select EC_ACPI @@ -18,6 +25,8 @@ config EC_STARLABS_ITE KBL - 3.12 or later And open-source Merlin firmware version 1.00 or later +if EC_STARLABS_MERLIN || EC_STARLABS_ITE || EC_STARLABS_NUVOTON + config EC_STARLABS_ADD_ITE_BIN bool "Add Star Labs EC binary file" default n @@ -63,13 +72,6 @@ config EC_STARLABS_BATTERY_OEM string default "Unknown" -config EC_STARLABS_MERLIN - bool "Use open-source Merlin EC Firmware" - default n - help - Use open source embedded controller firmware. Both firmwares have the - same features but differ in licensing and compilers. - if EC_STARLABS_MERLIN config EC_STARLABS_MAX_CHARGE @@ -94,6 +96,14 @@ config EC_STARLABS_POWER_LED bool "Enable lowering the brightess of the Power LED" default y help - Select the in the mainboard supports reducing the LED brightness + Select if the mainboard supports reducing the power LED brightness + +config EC_STARLABS_CHARGE_LED + bool "Enable lowering the brightess of the Charge LED" + default y + help + Select if the mainboard supports reducing the charge LED brightness + +endif # EC_STARLABS_MERLIN -endif +endif # EC_STARLABS_MERLIN || EC_STARLABS_ITE || EC_STARLABS_NUVOTON diff --git a/src/ec/starlabs/merlin/acpi/cmos.asl b/src/ec/starlabs/merlin/acpi/cmos.asl deleted file mode 100644 index 7ff0102b376..00000000000 --- a/src/ec/starlabs/merlin/acpi/cmos.asl +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -OperationRegion (CMS2, SystemIO, 0x72, 0x2) -Field (CMS2, ByteAcc, NoLock, Preserve) -{ - IND2, 8, - DAT2, 8, -} - -IndexField (IND2, DAT2, ByteAcc, NoLock, Preserve) -{ - Offset (0x80), - FLKC, 8, // Function Lock State - TPLC, 8, // Trackpad State - KLBC, 8, // Keyboard Backlight Brightness - KLSC, 8, // Keyboard Backlight State -} diff --git a/src/ec/starlabs/merlin/acpi/ec.asl b/src/ec/starlabs/merlin/acpi/ec.asl index ae5092772f6..84113c343da 100644 --- a/src/ec/starlabs/merlin/acpi/ec.asl +++ b/src/ec/starlabs/merlin/acpi/ec.asl @@ -2,8 +2,6 @@ Scope (\_SB.PCI0.LPCB) { - #include "cmos.asl" - Device (EC) { Name (_HID, EisaId ("PNP0C09")) diff --git a/src/ec/starlabs/merlin/acpi/suspend.asl b/src/ec/starlabs/merlin/acpi/suspend.asl index 2039b34c470..9c280dba6fc 100644 --- a/src/ec/starlabs/merlin/acpi/suspend.asl +++ b/src/ec/starlabs/merlin/acpi/suspend.asl @@ -1,137 +1,138 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -Method (RPTS, 1, Serialized) +#if CONFIG(STARLABS_ACPI_EFI_OPTION_SMI) +Field (\DNVS, ByteAcc, NoLock, Preserve) { + EOCM, 32, // EFI option command + EOID, 32, // EFI option ID + EOVL, 32, // EFI option value + EORS, 32, // EFI option status +} + +Name (EOAP, 0xE2) // STARLABS_APMC_CMD_EFI_OPTION + +Name (EOFL, 0x1) // STARLABS_EFIOPT_ID_FN_LOCK_STATE +Name (EOTP, 0x2) // STARLABS_EFIOPT_ID_TRACKPAD_STATE +Name (EOKB, 0x3) // STARLABS_EFIOPT_ID_KBL_BRIGHTNESS +Name (EOKS, 0x4) // STARLABS_EFIOPT_ID_KBL_STATE - /* Store current EC settings in CMOS */ - Switch (ToInteger (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.TPLE)))) +Mutex (EOMX, 0x00) + +Method (EOGT, 1, Serialized) +{ + If (Acquire (EOMX, 1000)) { - // 0x00 == Enabled == 0x00 - // 0x11 == Re-enabled == 0x00 - // 0x22 == Disabled == 0x01 - Case (0x00) - { - \_SB.PCI0.LPCB.TPLC = 0x00 - } - Case (0x11) - { - \_SB.PCI0.LPCB.TPLC = 0x00 - } - Case (0x22) - { - \_SB.PCI0.LPCB.TPLC = 0x01 - } + Return (0xFFFFFFFF) } - \_SB.PCI0.LPCB.FLKC = - \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.FLKE)) + Store (0x01, EOCM) + Store (Arg0, EOID) + Store (0x00, EORS) + Store (EOAP, \_SB.PCI0.LPCB.EC.SMB2) - Switch (ToInteger (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLSE)))) + Store (EOVL, Local0) + Release (EOMX) + Return (Local0) +} + +Method (EOSV, 2, Serialized) +{ + If (Acquire (EOMX, 1000)) { - // 0x00 == Disabled == 0x00 - // 0xdd == Enabled == 0x01 - Case (0x00) - { - \_SB.PCI0.LPCB.KLSC = 0x00 - } - Case (0xdd) - { - \_SB.PCI0.LPCB.KLSC = 0x01 - } + Return (0x01) } - Switch (ToInteger (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLBE)))) + Store (0x02, EOCM) + Store (Arg0, EOID) + Store (Arg1, EOVL) + Store (0x00, EORS) + Store (EOAP, \_SB.PCI0.LPCB.EC.SMB2) + + Store (EORS, Local0) + Release (EOMX) + Return (Local0) +} +#endif + +Method (RPTS, 1, Serialized) +{ + +#if CONFIG(STARLABS_ACPI_EFI_OPTION_SMI) + /* Store current EC settings in UEFI variable store */ + Store (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.TPLE)), Local0) + If (Local0 == 0x11) { - // 0xdd == On == 0x00 - // 0xcc == Off == 0x01 - // 0xbb == Low == 0x02 - // 0xaa == High == 0x03 - Case (0xdd) - { - \_SB.PCI0.LPCB.KLBC = 0x00 - } - Case (0xcc) - { - \_SB.PCI0.LPCB.KLBC = 0x01 - } - Case (0xbb) - { - \_SB.PCI0.LPCB.KLBC = 0x02 - } - Case (0xaa) - { - \_SB.PCI0.LPCB.KLBC = 0x03 - } + Store (0x00, Local0) } + EOSV (EOTP, Local0) + + EOSV (EOFL, \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.FLKE))) + EOSV (EOKS, \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLSE))) + EOSV (EOKB, \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLBE))) +#endif /* * Disable ACPI support. - * This should always be the last action before entering S4 or S5. + * This should always be the last action before entering a sleep state. */ \_SB.PCI0.LPCB.EC.ECWR(0x00, RefOf(\_SB.PCI0.LPCB.EC.OSFG)) + + Return (Arg0) } Method (RWAK, 1, Serialized) { /* * Enable ACPI support. - * This should always be the first action when exiting S4 or S5. + * This should always be the first action when exiting a sleep state. */ \_SB.PCI0.LPCB.EC.ECWR(0x01, RefOf(\_SB.PCI0.LPCB.EC.OSFG)) - /* Restore EC settings from CMOS */ - Switch (ToInteger (\_SB.PCI0.LPCB.TPLC)) +#if CONFIG(STARLABS_ACPI_EFI_OPTION_SMI) + /* Restore EC settings from UEFI variable store */ + Store (EOGT (EOTP), Local0) + If (Local0 == 0x22) { - // 0x00 == Enabled == 0x00 - // 0x00 == Re-enabled == 0x11 - // 0x01 == Disabled == 0x22 - Case (0x00) - { - \_SB.PCI0.LPCB.EC.ECWR (0x00, RefOf(\_SB.PCI0.LPCB.EC.TPLE)) - } - Case (0x01) - { - \_SB.PCI0.LPCB.EC.ECWR (0x22, RefOf(\_SB.PCI0.LPCB.EC.TPLE)) - } + \_SB.PCI0.LPCB.EC.ECWR (0x22, RefOf(\_SB.PCI0.LPCB.EC.TPLE)) + } + Else + { + \_SB.PCI0.LPCB.EC.ECWR (0x00, RefOf(\_SB.PCI0.LPCB.EC.TPLE)) } - \_SB.PCI0.LPCB.EC.ECWR (\_SB.PCI0.LPCB.FLKC, RefOf(\_SB.PCI0.LPCB.EC.FLKE)) + \_SB.PCI0.LPCB.EC.ECWR (EOGT (EOFL), RefOf(\_SB.PCI0.LPCB.EC.FLKE)) - Switch (ToInteger (\_SB.PCI0.LPCB.KLSC)) + Store (EOGT (EOKS), Local0) + If (Local0 == 0xdd) { - // 0x00 == Disabled == 0x00 - // 0x01 == Enabled == 0xdd - Case (0x00) - { - \_SB.PCI0.LPCB.EC.ECWR (0x00, RefOf(\_SB.PCI0.LPCB.EC.KLSE)) - } - Case (0x01) - { - \_SB.PCI0.LPCB.EC.ECWR (0xdd, RefOf(\_SB.PCI0.LPCB.EC.KLSE)) - } + \_SB.PCI0.LPCB.EC.ECWR (0xdd, RefOf(\_SB.PCI0.LPCB.EC.KLSE)) + } + Else + { + \_SB.PCI0.LPCB.EC.ECWR (0x00, RefOf(\_SB.PCI0.LPCB.EC.KLSE)) } - Switch (ToInteger (\_SB.PCI0.LPCB.KLBC)) + Store (EOGT (EOKB), Local0) + Switch (ToInteger (Local0)) { - // 0x00 == On == 0xdd - // 0x01 == Off == 0xcc - // 0x02 == Low == 0xbb - // 0x03 == High == 0xaa - Case (0x00) + Case (0xdd) { - \_SB.PCI0.LPCB.EC.ECWR (0xdd, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) + \_SB.PCI0.LPCB.EC.ECWR (0xdd, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) } - Case (0x01) + Case (0xcc) { - \_SB.PCI0.LPCB.EC.ECWR (0xcc, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) + \_SB.PCI0.LPCB.EC.ECWR (0xcc, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) } - Case (0x02) + Case (0xbb) { - \_SB.PCI0.LPCB.EC.ECWR (0xbb, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) + \_SB.PCI0.LPCB.EC.ECWR (0xbb, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) } - Case (0x03) + Case (0xaa) { - \_SB.PCI0.LPCB.EC.ECWR (0xaa, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) + \_SB.PCI0.LPCB.EC.ECWR (0xaa, RefOf(\_SB.PCI0.LPCB.EC.KLBE)) } } +#endif + + Return (Arg0) } diff --git a/src/ec/starlabs/merlin/cfr.h b/src/ec/starlabs/merlin/cfr.h index 51b3adad1af..760c41afb67 100644 --- a/src/ec/starlabs/merlin/cfr.h +++ b/src/ec/starlabs/merlin/cfr.h @@ -75,7 +75,7 @@ static const struct sm_object charging_speed = SM_DECLARE_ENUM({ .ui_name = "Charging Speed", .ui_helptext = "Set the maximum speed to charge the battery. Charging faster" " will increase heat and battery wear.", - .default_value = SPEED_0_5C, + .default_value = SPEED_1_0C, .values = (const struct sm_enum_value[]) { { "1.0C", SPEED_1_0C }, { "0.5C", SPEED_0_5C }, @@ -98,6 +98,13 @@ static const struct sm_object lid_switch = SM_DECLARE_ENUM({ SM_ENUM_VALUE_END }, }); +const struct sm_enum_value led_brightness[] = { + { "Normal", LED_NORMAL }, + { "Reduced", LED_REDUCED }, + { "Off", LED_OFF }, + SM_ENUM_VALUE_END +}; + /* * Power LED Brightness */ @@ -106,9 +113,16 @@ static const struct sm_object power_led = SM_DECLARE_ENUM({ .ui_name = "Power LED Brightness", .ui_helptext = "Control the maximum brightness of the power LED", .default_value = LED_NORMAL, - .values = (const struct sm_enum_value[]) { - { "Normal", LED_NORMAL }, - { "Reduced", LED_REDUCED }, - { "Off", LED_OFF }, - SM_ENUM_VALUE_END }, + .values = led_brightness, +}); + +/* + * Charge LED Brightness + */ +static const struct sm_object charge_led = SM_DECLARE_ENUM({ + .opt_name = "charge_led", + .ui_name = "Charge LED Brightness", + .ui_helptext = "Control the maximum brightness of the charge LED", + .default_value = LED_NORMAL, + .values = led_brightness, }); diff --git a/src/ec/starlabs/merlin/ite.c b/src/ec/starlabs/merlin/ite.c index c239b061ad2..a3369700c3b 100644 --- a/src/ec/starlabs/merlin/ite.c +++ b/src/ec/starlabs/merlin/ite.c @@ -5,51 +5,26 @@ #include #include #include -#include #include #include "ecdefs.h" -#include "option_table.h" #include "ec.h" -#define ITE_IT5570 0x5570 -#define ITE_IT8987 0x8987 +#define ITE_IT5570 0x5570 +#define ITE_IT8987 0x8987 uint16_t ec_get_version(void) { return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION); } -static uint8_t get_cmos_value(uint32_t bit, uint32_t length) +static uint8_t get_ec_value_from_option(const char *name, uint8_t fallback, const uint8_t *lut, + size_t lut_size) { - uint32_t byte, byte_bit; - uint8_t uchar; - - byte = bit / 8; // find the byte where the data starts - byte_bit = bit % 8; // find the bit in the byte where the data starts - - uchar = cmos_read(byte); // load the byte - uchar >>= byte_bit; // shift the bits to byte align - // clear unspecified bits - return uchar & ((1U << length) - 1); -} - -static uint8_t get_ec_value_from_option(const char *name, - uint32_t fallback, - const uint8_t *lut, - size_t lut_size, - uint32_t cmos_start_bit, - uint32_t cmos_length) -{ - uint8_t value; - - if (cmos_start_bit != UINT_MAX) - value = get_cmos_value(cmos_start_bit, cmos_length); - else - value = get_uint_option(name, fallback); + const uint8_t value = get_uint_option(name, fallback); /* Check if the value exists in the LUT array */ - for (int i = 0; i < lut_size; i++) + for (size_t i = 0; i < lut_size; i++) if (lut[i] == value) return value; @@ -58,8 +33,7 @@ static uint8_t get_ec_value_from_option(const char *name, static uint16_t ec_get_chip_id(unsigned int port) { - return (pnp_read_index(port, ITE_CHIPID1) << 8) | - pnp_read_index(port, ITE_CHIPID2); + return (pnp_read_index(port, ITE_CHIPID1) << 8) | pnp_read_index(port, ITE_CHIPID2); } static void merlin_init(struct device *dev) @@ -87,7 +61,7 @@ static void merlin_init(struct device *dev) } /* - * Restore settings from CMOS into EC RAM: + * Restore settings from options into EC RAM: * * kbl_timeout * fn_ctrl_swap @@ -111,21 +85,11 @@ static void merlin_init(struct device *dev) * Default: 30 Seconds * */ - const uint8_t kbl_timeout[] = { - SEC_30, - MIN_1, - MIN_3, - MIN_5, - NEVER - }; + const uint8_t kbl_timeout[] = {SEC_30, MIN_1, MIN_3, MIN_5, NEVER}; ec_write(ECRAM_KBL_TIMEOUT, - get_ec_value_from_option("kbl_timeout", - SEC_30, - kbl_timeout, - ARRAY_SIZE(kbl_timeout), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("kbl_timeout", SEC_30, kbl_timeout, + ARRAY_SIZE(kbl_timeout))); /* * Fn Ctrl Reverse @@ -136,18 +100,11 @@ static void merlin_init(struct device *dev) * Default: Disabled * */ - const uint8_t fn_ctrl_swap[] = { - FN_CTRL, - CTRL_FN - }; + const uint8_t fn_ctrl_swap[] = {FN_CTRL, CTRL_FN}; ec_write(ECRAM_FN_CTRL_REVERSE, - get_ec_value_from_option("fn_ctrl_swap", - FN_CTRL, - fn_ctrl_swap, - ARRAY_SIZE(fn_ctrl_swap), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("fn_ctrl_swap", FN_CTRL, fn_ctrl_swap, + ARRAY_SIZE(fn_ctrl_swap))); /* * Maximum Charge Level @@ -158,20 +115,12 @@ static void merlin_init(struct device *dev) * Default: 100% * */ - const uint8_t max_charge[] = { - CHARGE_100, - CHARGE_80, - CHARGE_60 - }; + const uint8_t max_charge[] = {CHARGE_100, CHARGE_80, CHARGE_60}; if (CONFIG(EC_STARLABS_MAX_CHARGE)) ec_write(ECRAM_MAX_CHARGE, - get_ec_value_from_option("max_charge", - CHARGE_100, - max_charge, - ARRAY_SIZE(max_charge), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("max_charge", CHARGE_100, max_charge, + ARRAY_SIZE(max_charge))); /* * Fan Mode @@ -182,21 +131,12 @@ static void merlin_init(struct device *dev) * Default: Normal * */ - const uint8_t fan_mode[] = { - FAN_NORMAL, - FAN_AGGRESSIVE, - FAN_QUIET, - FAN_DISABLED - }; + const uint8_t fan_mode[] = {FAN_NORMAL, FAN_AGGRESSIVE, FAN_QUIET, FAN_DISABLED}; if (CONFIG(EC_STARLABS_FAN)) ec_write(ECRAM_FAN_MODE, - get_ec_value_from_option("fan_mode", - FAN_NORMAL, - fan_mode, - ARRAY_SIZE(fan_mode), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("fan_mode", FAN_NORMAL, fan_mode, + ARRAY_SIZE(fan_mode))); /* * Function Lock @@ -207,20 +147,11 @@ static void merlin_init(struct device *dev) * Default: Locked * */ -#ifdef CMOS_VLEN_fn_lock_state - const uint8_t fn_lock_state[] = { - UNLOCKED, - LOCKED - }; + const uint8_t fn_lock_state[] = {UNLOCKED, LOCKED}; ec_write(ECRAM_FN_LOCK_STATE, - get_ec_value_from_option("fn_lock_state", - UNLOCKED, - fn_lock_state, - ARRAY_SIZE(fn_lock_state), - CMOS_VSTART_fn_lock_state, - CMOS_VLEN_fn_lock_state)); -#endif + get_ec_value_from_option( + "fn_lock_state", UNLOCKED, fn_lock_state, ARRAY_SIZE(fn_lock_state))); /* * Trackpad State @@ -231,20 +162,12 @@ static void merlin_init(struct device *dev) * Default: Enabled * */ -#ifdef CMOS_VSTART_trackpad_state - const uint8_t trackpad_state[] = { - TRACKPAD_ENABLED, - TRACKPAD_DISABLED - }; + const uint8_t trackpad_state[] = {TRACKPAD_ENABLED, TRACKPAD_DISABLED}; ec_write(ECRAM_TRACKPAD_STATE, - get_ec_value_from_option("trackpad_state", - TRACKPAD_ENABLED, - trackpad_state, - ARRAY_SIZE(trackpad_state), - CMOS_VSTART_trackpad_state, - CMOS_VLEN_trackpad_state)); -#endif + get_ec_value_from_option( + "trackpad_state", TRACKPAD_ENABLED, trackpad_state, + ARRAY_SIZE(trackpad_state))); /* * Keyboard Backlight Brightness @@ -255,24 +178,16 @@ static void merlin_init(struct device *dev) * Default: Low * */ -#ifdef CMOS_VSTART_kbl_brightness - const uint8_t kbl_brightness[] = { - KBL_ON, - KBL_OFF, - KBL_LOW, - KBL_HIGH - }; - - ec_write(ECRAM_KBL_BRIGHTNESS, - get_ec_value_from_option("kbl_brightness", - CONFIG(EC_STARLABS_KBL_LEVELS) ? KBL_LOW : KBL_ON, - kbl_brightness, - ARRAY_SIZE(kbl_brightness), - CMOS_VSTART_kbl_brightness, - CMOS_VLEN_kbl_brightness)); + const uint8_t kbl_brightness[] = {KBL_ON, KBL_OFF, KBL_LOW, KBL_HIGH}; -#endif + const uint8_t kbl_brightness_fallback = + CONFIG(EC_STARLABS_KBL_LEVELS) ? KBL_LOW : KBL_ON; + ec_write(ECRAM_KBL_BRIGHTNESS, + get_ec_value_from_option( + "kbl_brightness", + kbl_brightness_fallback, + kbl_brightness, ARRAY_SIZE(kbl_brightness))); /* * Keyboard Backlight State @@ -297,20 +212,12 @@ static void merlin_init(struct device *dev) * Default: 0.5C * */ - const uint8_t charging_speed[] = { - SPEED_1_0C, - SPEED_0_5C, - SPEED_0_2C - }; + const uint8_t charging_speed[] = {SPEED_1_0C, SPEED_0_5C, SPEED_0_2C}; if (CONFIG(EC_STARLABS_CHARGING_SPEED)) ec_write(ECRAM_CHARGING_SPEED, - get_ec_value_from_option("charging_speed", - SPEED_0_5C, - charging_speed, - ARRAY_SIZE(charging_speed), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("charging_speed", SPEED_0_5C, charging_speed, + ARRAY_SIZE(charging_speed))); /* * Lid Switch @@ -321,20 +228,12 @@ static void merlin_init(struct device *dev) * Default: 0 * */ - const uint8_t lid_switch[] = { - SWITCH_NORMAL, - SWITCH_SLEEP_ONLY, - SWITCH_DISABLED - }; + const uint8_t lid_switch[] = {SWITCH_NORMAL, SWITCH_SLEEP_ONLY, SWITCH_DISABLED}; if (CONFIG(EC_STARLABS_LID_SWITCH)) ec_write(ECRAM_LID_SWITCH, - get_ec_value_from_option("lid_switch", - SWITCH_NORMAL, - lid_switch, - ARRAY_SIZE(lid_switch), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("lid_switch", SWITCH_NORMAL, lid_switch, + ARRAY_SIZE(lid_switch))); /* * Power LED Brightness @@ -345,26 +244,33 @@ static void merlin_init(struct device *dev) * Default: 0 * */ - const uint8_t power_led[] = { - LED_NORMAL, - LED_REDUCED, - LED_OFF - }; + const uint8_t led_brightness[] = {LED_NORMAL, LED_REDUCED, LED_OFF}; if (CONFIG(EC_STARLABS_POWER_LED)) ec_write(ECRAM_POWER_LED, - get_ec_value_from_option("power_led", - LED_NORMAL, - power_led, - ARRAY_SIZE(power_led), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("power_led", LED_NORMAL, led_brightness, + ARRAY_SIZE(led_brightness))); + + /* + * Charge LED Brightness + * + * Setting: charge_led + * + * Values: 0, 1, 2 + * Default: 0 + * + */ + + if (CONFIG(EC_STARLABS_CHARGE_LED)) + ec_write(ECRAM_CHARGE_LED, + get_ec_value_from_option("charge_led", LED_NORMAL, led_brightness, + ARRAY_SIZE(led_brightness))); } static struct device_operations ops = { - .init = merlin_init, - .read_resources = noop_read_resources, - .set_resources = noop_set_resources, + .init = merlin_init, + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, }; static struct pnp_info pnp_dev_info[] = { diff --git a/src/ec/starlabs/merlin/nuvoton.c b/src/ec/starlabs/merlin/nuvoton.c index 6b39fe0ebf2..398b12619bd 100644 --- a/src/ec/starlabs/merlin/nuvoton.c +++ b/src/ec/starlabs/merlin/nuvoton.c @@ -5,50 +5,27 @@ #include #include #include -#include #include #include "ecdefs.h" -#include "option_table.h" #include "ec.h" - uint16_t ec_get_version(void) { return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION); } -static uint8_t get_cmos_value(uint32_t bit, uint32_t length) +static uint8_t get_ec_value_from_option(const char *name, uint8_t fallback, const uint8_t *lut, + size_t lut_size) { - uint32_t byte, byte_bit; - uint8_t uchar; + const uint8_t value = get_uint_option(name, fallback); - byte = bit / 8; // find the byte where the data starts - byte_bit = bit % 8; // find the bit in the byte where the data starts + /* Check if the value exists in the LUT array */ + for (size_t i = 0; i < lut_size; i++) + if (lut[i] == value) + return value; - uchar = cmos_read(byte); // load the byte - uchar >>= byte_bit; // shift the bits to byte align - // clear unspecified bits - return uchar & ((1U << length) - 1); -} - -static uint8_t get_ec_value_from_option(const char *name, - uint32_t fallback, - const uint8_t *lut, - size_t lut_size, - uint32_t cmos_start_bit, - uint32_t cmos_length) -{ - unsigned int index; - - if (cmos_start_bit != UINT_MAX) - index = get_cmos_value(cmos_start_bit, cmos_length); - else - index = get_uint_option(name, fallback); - - if (index >= lut_size) - index = fallback; - return lut[index]; + return fallback; } static uint16_t ec_get_chip_id(unsigned int port) @@ -77,12 +54,12 @@ static void merlin_init(struct device *dev) if (chip_id != NUVOTON_CHIPID_VAL) { printk(BIOS_ERR, "NUVOTON: Expected chip ID 0x%04x, but got 0x%04x instead.\n", - NUVOTON_CHIPID_VAL, chip_id); + NUVOTON_CHIPID_VAL, chip_id); return; } /* - * Restore settings from CMOS into EC RAM: + * Restore settings from options into EC RAM: * * kbl_timeout * fn_ctrl_swap @@ -103,21 +80,11 @@ static void merlin_init(struct device *dev) * Default: 30 Seconds * */ - const uint8_t kbl_timeout[] = { - SEC_30, - MIN_1, - MIN_3, - MIN_5, - NEVER - }; + const uint8_t kbl_timeout[] = {SEC_30, MIN_1, MIN_3, MIN_5, NEVER}; ec_write(ECRAM_KBL_TIMEOUT, - get_ec_value_from_option("kbl_timeout", - 0, - kbl_timeout, - ARRAY_SIZE(kbl_timeout), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("kbl_timeout", 0, kbl_timeout, + ARRAY_SIZE(kbl_timeout))); /* * Fn Ctrl Reverse @@ -128,18 +95,11 @@ static void merlin_init(struct device *dev) * Default: Disabled * */ - const uint8_t fn_ctrl_swap[] = { - FN_CTRL, - CTRL_FN - }; + const uint8_t fn_ctrl_swap[] = {FN_CTRL, CTRL_FN}; ec_write(ECRAM_FN_CTRL_REVERSE, - get_ec_value_from_option("fn_ctrl_swap", - 0, - fn_ctrl_swap, - ARRAY_SIZE(fn_ctrl_swap), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("fn_ctrl_swap", 0, fn_ctrl_swap, + ARRAY_SIZE(fn_ctrl_swap))); /* * Maximum Charge Level @@ -150,20 +110,12 @@ static void merlin_init(struct device *dev) * Default: 100% * */ - const uint8_t max_charge[] = { - CHARGE_100, - CHARGE_80, - CHARGE_60 - }; + const uint8_t max_charge[] = {CHARGE_100, CHARGE_80, CHARGE_60}; if (CONFIG(EC_STARLABS_MAX_CHARGE)) ec_write(ECRAM_MAX_CHARGE, - get_ec_value_from_option("max_charge", - 0, - max_charge, - ARRAY_SIZE(max_charge), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("max_charge", 0, max_charge, + ARRAY_SIZE(max_charge))); /* * Fan Mode @@ -174,20 +126,11 @@ static void merlin_init(struct device *dev) * Default: Normal * */ - const uint8_t fan_mode[] = { - FAN_NORMAL, - FAN_AGGRESSIVE, - FAN_QUIET - }; + const uint8_t fan_mode[] = {FAN_NORMAL, FAN_AGGRESSIVE, FAN_QUIET}; if (CONFIG(EC_STARLABS_FAN)) ec_write(ECRAM_FAN_MODE, - get_ec_value_from_option("fan_mode", - 0, - fan_mode, - ARRAY_SIZE(fan_mode), - UINT_MAX, - UINT_MAX)); + get_ec_value_from_option("fan_mode", 0, fan_mode, ARRAY_SIZE(fan_mode))); /* * Function Lock @@ -198,20 +141,11 @@ static void merlin_init(struct device *dev) * Default: Locked * */ -#ifdef CMOS_VLEN_fn_lock_state - const uint8_t fn_lock_state[] = { - UNLOCKED, - LOCKED - }; + const uint8_t fn_lock_state[] = {UNLOCKED, LOCKED}; ec_write(ECRAM_FN_LOCK_STATE, - get_ec_value_from_option("fn_lock_state", - 1, - fn_lock_state, - ARRAY_SIZE(fn_lock_state), - CMOS_VSTART_fn_lock_state, - CMOS_VLEN_fn_lock_state)); -#endif + get_ec_value_from_option( + "fn_lock_state", 1, fn_lock_state, ARRAY_SIZE(fn_lock_state))); /* * Trackpad State @@ -222,20 +156,11 @@ static void merlin_init(struct device *dev) * Default: Enabled * */ -#ifdef CMOS_VSTART_trackpad_state - const uint8_t trackpad_state[] = { - TRACKPAD_ENABLED, - TRACKPAD_DISABLED - }; + const uint8_t trackpad_state[] = {TRACKPAD_ENABLED, TRACKPAD_DISABLED}; ec_write(ECRAM_TRACKPAD_STATE, - get_ec_value_from_option("trackpad_state", - 0, - trackpad_state, - ARRAY_SIZE(trackpad_state), - CMOS_VSTART_trackpad_state, - CMOS_VLEN_trackpad_state)); -#endif + get_ec_value_from_option( + "trackpad_state", 0, trackpad_state, ARRAY_SIZE(trackpad_state))); /* * Keyboard Backlight Brightness @@ -246,24 +171,16 @@ static void merlin_init(struct device *dev) * Default: Low * */ -#ifdef CMOS_VSTART_kbl_brightness - const uint8_t kbl_brightness[] = { - KBL_ON, - KBL_OFF, - KBL_LOW, - KBL_HIGH - }; - - ec_write(ECRAM_KBL_BRIGHTNESS, - get_ec_value_from_option("kbl_brightness", - CONFIG(EC_STARLABS_KBL_LEVELS) ? 2 : 0, - kbl_brightness, - ARRAY_SIZE(kbl_brightness), - CMOS_VSTART_kbl_brightness, - CMOS_VLEN_kbl_brightness)); + const uint8_t kbl_brightness[] = {KBL_ON, KBL_OFF, KBL_LOW, KBL_HIGH}; -#endif + const uint8_t kbl_brightness_fallback = + CONFIG(EC_STARLABS_KBL_LEVELS) ? KBL_LOW : KBL_ON; + ec_write(ECRAM_KBL_BRIGHTNESS, + get_ec_value_from_option( + "kbl_brightness", + kbl_brightness_fallback, + kbl_brightness, ARRAY_SIZE(kbl_brightness))); /* * Keyboard Backlight State @@ -281,9 +198,9 @@ static void merlin_init(struct device *dev) } static struct device_operations ops = { - .init = merlin_init, - .read_resources = noop_read_resources, - .set_resources = noop_set_resources, + .init = merlin_init, + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, }; static struct pnp_info pnp_dev_info[] = { @@ -299,7 +216,7 @@ static struct pnp_info pnp_dev_info[] = { { NULL, NUVOTON_PM1, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, }, /* Power Management I/F Channel 2 (PMC2) */ { NULL, NUVOTON_PM2, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IRQ0, 0x07fc, - 0x07fc, 0xfff0, }, + 0x07fc, 0xfff0, }, /* Power Management I/F Channel 3 (PMC3) */ { NULL, NUVOTON_PM3, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, }, /* Extended Shared Memory (ESHM) */ diff --git a/src/ec/starlabs/merlin/variants/glk/ecdefs.h b/src/ec/starlabs/merlin/variants/glk/ecdefs.h index ed518f400a2..d5bfc037d38 100644 --- a/src/ec/starlabs/merlin/variants/glk/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/glk/ecdefs.h @@ -19,6 +19,7 @@ #define ECRAM_KBL_TIMEOUT 0x1a #define ECRAM_FN_LOCK_STATE 0x2c #define ECRAM_FN_CTRL_REVERSE 0x2d +#define ECRAM_CHARGE_LED dead_code_t(uint8_t) #define ECRAM_MAX_CHARGE dead_code_t(uint8_t) #define ECRAM_FAN_MODE dead_code_t(uint8_t) #define ECRAM_CHARGING_SPEED dead_code_t(uint8_t) diff --git a/src/ec/starlabs/merlin/variants/glkr/ecdefs.h b/src/ec/starlabs/merlin/variants/glkr/ecdefs.h index 6d469b27856..38368208959 100644 --- a/src/ec/starlabs/merlin/variants/glkr/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/glkr/ecdefs.h @@ -22,6 +22,7 @@ #define ECRAM_KBL_TIMEOUT 0x12 #define ECRAM_FN_LOCK_STATE 0x15 #define ECRAM_FN_CTRL_REVERSE 0x13 +#define ECRAM_CHARGE_LED dead_code_t(uint8_t) #define ECRAM_MAX_CHARGE dead_code_t(uint8_t) #define ECRAM_FAN_MODE dead_code_t(uint8_t) #define ECRAM_CHARGING_SPEED dead_code_t(uint8_t) diff --git a/src/ec/starlabs/merlin/variants/kbl/ecdefs.h b/src/ec/starlabs/merlin/variants/kbl/ecdefs.h index b0f743f711f..206ccf27151 100644 --- a/src/ec/starlabs/merlin/variants/kbl/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/kbl/ecdefs.h @@ -20,6 +20,7 @@ #define ECRAM_FN_LOCK_STATE 0x2c #define ECRAM_FAN_MODE 0x42 #define ECRAM_FN_CTRL_REVERSE 0x43 +#define ECRAM_CHARGE_LED dead_code_t(uint8_t) #define ECRAM_MAX_CHARGE dead_code_t(uint8_t) #define ECRAM_CHARGING_SPEED dead_code_t(uint8_t) #define ECRAM_LID_SWITCH dead_code_t(uint8_t) diff --git a/src/ec/starlabs/merlin/variants/merlin/ecdefs.h b/src/ec/starlabs/merlin/variants/merlin/ecdefs.h index 4fab635f3d4..f924ad0fbf9 100644 --- a/src/ec/starlabs/merlin/variants/merlin/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/merlin/ecdefs.h @@ -19,6 +19,7 @@ #define ECRAM_TRACKPAD_STATE 0x0c #define ECRAM_FN_LOCK_STATE 0x0f #define ECRAM_FN_CTRL_REVERSE 0x17 +#define ECRAM_CHARGE_LED 0x18 #define ECRAM_MAX_CHARGE 0x1a #define ECRAM_FAN_MODE 0x1b #define ECRAM_CHARGING_SPEED 0x1d diff --git a/src/ec/system76/ec/Kconfig b/src/ec/system76/ec/Kconfig index f0702a76d17..14899dbce73 100644 --- a/src/ec/system76/ec/Kconfig +++ b/src/ec/system76/ec/Kconfig @@ -21,6 +21,11 @@ config EC_SYSTEM76_EC_DGPU select EC_SYSTEM76_EC_FAN2 depends on EC_SYSTEM76_EC +config EC_SYSTEM76_EC_LOCKDOWN + bool + default n + depends on EC_SYSTEM76_EC + config EC_SYSTEM76_EC_OLED bool default n diff --git a/src/ec/system76/ec/Makefile.mk b/src/ec/system76/ec/Makefile.mk index 9808e297d66..02fcda537ce 100644 --- a/src/ec/system76/ec/Makefile.mk +++ b/src/ec/system76/ec/Makefile.mk @@ -4,6 +4,7 @@ ifeq ($(CONFIG_EC_SYSTEM76_EC),y) all-y += system76_ec.c ramstage-y += smbios.c +ramstage-$(CONFIG_EC_SYSTEM76_EC_LOCKDOWN) += lockdown.c smm-$(CONFIG_DEBUG_SMI) += system76_ec.c diff --git a/src/ec/system76/ec/lockdown.c b/src/ec/system76/ec/lockdown.c new file mode 100644 index 00000000000..d6f52f41021 --- /dev/null +++ b/src/ec/system76/ec/lockdown.c @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "system76_ec.h" +#include +#include +#include +#include + +static int protect_region_by_name(const char *name) +{ + int res; + struct region region; + + res = fmap_locate_area(name, ®ion); + if (res < 0) { + printk(BIOS_ERR, "fmap_locate_area '%s' failed: %d\n", name, res); + return res; + } + + res = spi_flash_ctrlr_protect_region( + boot_device_spi_flash(), + ®ion, + WRITE_PROTECT + ); + if (res < 0) { + printk(BIOS_ERR, "spi_flash_ctrlr_protect_region '%s' failed: %d\n", name, res); + return res; + } + + printk(BIOS_INFO, "protected '%s'\n", name); + return 0; +} + +static void lock(void *unused) +{ + uint8_t state = SYSTEM76_EC_SECURITY_STATE_UNLOCK; + if (!system76_ec_security_get(&state)) { + printk(BIOS_INFO, "failed to get security state, assuming unlocked\n"); + state = SYSTEM76_EC_SECURITY_STATE_UNLOCK; + } + + printk(BIOS_INFO, "security state: %d\n", state); + if (state != SYSTEM76_EC_SECURITY_STATE_UNLOCK) { + // Protect WP_RO region, which should contain FMAP and COREBOOT + protect_region_by_name("WP_RO"); + // Protect RW_MRC_CACHE region, this must be done after it is written + protect_region_by_name("RW_MRC_CACHE"); + //TODO: protect entire flash except when in SMM? + } +} + +/* + * Keep in sync with mrc_cache.c + */ +#if CONFIG(MRC_WRITE_NV_LATE) +BOOT_STATE_INIT_ENTRY(BS_OS_RESUME_CHECK, BS_ON_EXIT, lock, NULL); +#else +BOOT_STATE_INIT_ENTRY(BS_DEV_RESOURCES, BS_ON_ENTRY, lock, NULL); +#endif diff --git a/src/ec/system76/ec/system76_ec.c b/src/ec/system76/ec/system76_ec.c index 828376d0e5c..ee41b1e8d72 100644 --- a/src/ec/system76/ec/system76_ec.c +++ b/src/ec/system76/ec/system76_ec.c @@ -26,6 +26,9 @@ #define CMD_PRINT_REG_LEN 3 #define CMD_PRINT_REG_DATA 4 +// Get security state command +#define CMD_SECURITY_GET 20 + static inline uint8_t system76_ec_read(uint8_t addr) { return inb(SYSTEM76_EC_BASE + (uint16_t)addr); @@ -110,3 +113,9 @@ bool system76_ec_cmd(uint8_t cmd, const uint8_t *request_data, return ret; } + +bool system76_ec_security_get(uint8_t *state) +{ + *state = SYSTEM76_EC_SECURITY_STATE_LOCK; + return system76_ec_cmd(CMD_SECURITY_GET, NULL, 0, state, sizeof(*state)); +} diff --git a/src/ec/system76/ec/system76_ec.h b/src/ec/system76/ec/system76_ec.h index 9675bd0cafc..6c91bb6aec6 100644 --- a/src/ec/system76/ec/system76_ec.h +++ b/src/ec/system76/ec/system76_ec.h @@ -6,6 +6,15 @@ #include #include +// Default value, flashing is prevented, cannot be set with CMD_SECURITY_SET +#define SYSTEM76_EC_SECURITY_STATE_LOCK 0 +// Flashing is allowed, cannot be set with CMD_SECURITY_SET +#define SYSTEM76_EC_SECURITY_STATE_UNLOCK 1 +// Flashing will be prevented on the next reboot +#define SYSTEM76_EC_SECURITY_STATE_PREPARE_LOCK 2 +// Flashing will be allowed on the next reboot +#define SYSTEM76_EC_SECURITY_STATE_PREPARE_UNLOCK 3 + /* * Send a command to the EC. request_data/request_size are the request payload, * request_data can be NULL if request_size is 0. reply_data/reply_size are @@ -14,4 +23,6 @@ bool system76_ec_cmd(uint8_t cmd, const uint8_t *request_data, uint8_t request_size, uint8_t *reply_data, uint8_t reply_size); +bool system76_ec_security_get(uint8_t *state); + #endif diff --git a/src/include/acpi/acpi.h b/src/include/acpi/acpi.h index 87c99a1eb3f..ac00050031b 100644 --- a/src/include/acpi/acpi.h +++ b/src/include/acpi/acpi.h @@ -243,6 +243,20 @@ typedef struct acpi_tcpa { u64 lasa; } __packed acpi_tcpa_t; +/* TCG ACPI Specification "Table 8: Start Method values for ACPI table for TPM 2.0" */ +enum acpi_tpm2_start_methods { + ACPI_TPM2_SM_NOT_ALLOWED = 0, + ACPI_TPM2_SM_LEGACY, + ACPI_TPM2_SM_ACPI_START, + ACPI_TPM2_SM_MMIO_TIS = 6, + ACPI_TPM2_SM_CRB, + ACPI_TPM2_SM_CRB_AND_ACPI_START, + ACPI_TPM2_SM_CRB_AND_ARM_SECURE_MONITOR = 11, + ACPI_TPM2_SM_FIFO_I2C, + ACPI_TPM2_SM_RESERVED_MMIO0, + ACPI_TPM2_SM_RESERVED_MMIO1, +}; + typedef struct acpi_tpm2 { acpi_header_t header; u16 platform_class; diff --git a/src/include/assert.h b/src/include/assert.h index 0e09eef3922..19d041010f3 100644 --- a/src/include/assert.h +++ b/src/include/assert.h @@ -22,7 +22,7 @@ #define __ASSERT_LINE__ __LINE__ #endif -#ifndef _PORTING_H_ /* TODO: Isolate AGESA properly. */ +#if !ENV_TEST && !defined(_PORTING_H_) /* TODO: Isolate AGESA properly. */ #define __build_time_assert(x) \ (__builtin_constant_p(x) ? ((x) ? 1 : dead_code_t(int)) : 0) #else @@ -34,11 +34,13 @@ void mock_assert(const int result, const char *const expression, const char *const file, const int line); #if ENV_TEST -#define MOCK_ASSERT(result, expression) \ +#define _ASSERT_MSG(...) +#define _MOCK_ASSERT(result, expression) \ mock_assert((result), (expression), __ASSERT_FILE__, __ASSERT_LINE__) -#else -#define MOCK_ASSERT(result, expression) -#endif +#else /* ENV_TEST */ +#define _ASSERT_MSG(...) printk(BIOS_EMERG, __VA_ARGS__) +#define _MOCK_ASSERT(result, expression) +#endif /* ENV_TEST */ /* * assert() should be used to test stuff that the programmer *knows* to be true. @@ -54,30 +56,30 @@ void mock_assert(const int result, const char *const expression, */ #define ASSERT(x) { \ if (!__build_time_assert(x) && !(x)) { \ - printk(BIOS_EMERG, \ + _ASSERT_MSG( \ "ASSERTION ERROR: file '%s', line %d\n", \ __ASSERT_FILE__, __ASSERT_LINE__); \ - MOCK_ASSERT(!!(x), #x); \ + _MOCK_ASSERT(!!(x), #x); \ if (CONFIG(FATAL_ASSERTS)) \ hlt(); \ } \ } #define ASSERT_MSG(x, msg) { \ if (!__build_time_assert(x) && !(x)) { \ - printk(BIOS_EMERG, \ + _ASSERT_MSG( \ "ASSERTION ERROR: file '%s', line %d\n", \ __ASSERT_FILE__, __ASSERT_LINE__); \ - printk(BIOS_EMERG, "%s", msg); \ - MOCK_ASSERT(!!(x), (msg)); \ + _ASSERT_MSG("%s", msg); \ + _MOCK_ASSERT(!!(x), (msg)); \ if (CONFIG(FATAL_ASSERTS)) \ hlt(); \ } \ } #define BUG() { \ - printk(BIOS_EMERG, \ + _ASSERT_MSG( \ "ERROR: BUG ENCOUNTERED at file '%s', line %d\n", \ __ASSERT_FILE__, __ASSERT_LINE__); \ - MOCK_ASSERT(0, "BUG ENCOUNTERED"); \ + _MOCK_ASSERT(0, "BUG ENCOUNTERED"); \ if (CONFIG(FATAL_ASSERTS)) \ hlt(); \ } diff --git a/src/include/boot/coreboot_tables.h b/src/include/boot/coreboot_tables.h index be737b0bb92..ec56c159233 100644 --- a/src/include/boot/coreboot_tables.h +++ b/src/include/boot/coreboot_tables.h @@ -24,6 +24,8 @@ void lb_add_console(uint16_t consoletype, void *data); enum cb_err fill_lb_pcie(struct lb_pcie *pcie); +void lb_string_platform_blob_version(struct lb_header *header); + /* Define this in mainboard.c to add board-specific table entries. */ void lb_board(struct lb_header *header); @@ -33,9 +35,9 @@ void lb_efi_fw_info(struct lb_header *header); /* Adds LB_TAG_CAPSULE table entries. */ void lb_efi_capsules(struct lb_header *header); -/* Define this function to fill in the frame buffer returning 0 on success and - < 0 on error. */ -int fill_lb_framebuffer(struct lb_framebuffer *framebuffer); +/* Define this function to get the frame buffer returning lb_framebuffer object + on success and NULL on error. */ +const struct lb_framebuffer *get_lb_framebuffer(void); /* Allow arch to add records. */ void lb_arch_add_records(struct lb_header *header); diff --git a/src/include/boot_device.h b/src/include/boot_device.h index 883f37c8c86..1a44aefc030 100644 --- a/src/include/boot_device.h +++ b/src/include/boot_device.h @@ -27,6 +27,9 @@ enum bootdev_prot_type { * most likely not to work so don't rely on such semantics. */ +/* Return the chip select index used for probing the SPI flash. */ +int boot_device_spi_cs(void); + /* Return the region_device for the read-only boot device. This is the root device for all CBFS boot devices. */ const struct region_device *boot_device_ro(void); diff --git a/src/include/bootsplash.h b/src/include/bootsplash.h index da51590345b..67b3a405a11 100644 --- a/src/include/bootsplash.h +++ b/src/include/bootsplash.h @@ -13,11 +13,23 @@ enum bootsplash_type { BOOTSPLASH_CENTER, /* Indicates an optional OEM defined bootsplash logo for footer of the splash screen. */ BOOTSPLASH_FOOTER, + /* Indicates a off-mode charging bootsplash logo. */ + BOOTSPLASH_OFF_MODE_CHARGING, /* It's used to determine the total number of bootsplash types. */ BOOTSPLASH_MAX_NUM, }; +enum bootsplash_text_type { + /* Indicates a bootsplash text message appear at the center of the screen. */ + BOOTSPLASH_TEXT_CENTER, + /* Indicates a bootsplash text message appear at the footer of the screen. */ + BOOTSPLASH_TEXT_FOOTER, + + /* It's used to determine the total number of bootsplash types. */ + BOOTSPLASH_TEXT_MAX_NUM, +}; + /** * Sets up the framebuffer with the bootsplash.jpg from cbfs. * Returns 0 on success @@ -139,6 +151,15 @@ struct logo_config { uint8_t logo_bottom_margin; }; +/* + * Calculates the destination coordinates for the logo based on both horizontal and + * vertical alignment settings. + */ +struct logo_coordinates calculate_logo_coordinates( + uint32_t horizontal_resolution, uint32_t vertical_resolution, + uint32_t logo_width, uint32_t logo_height, + enum fw_splash_horizontal_alignment halignment, + enum fw_splash_vertical_alignment valignment); void render_logo_to_framebuffer(struct logo_config *config); void load_and_convert_bmp_to_blt(uintptr_t *logo, size_t *logo_size, uintptr_t *blt, size_t *blt_size, uint32_t *pixel_height, uint32_t *pixel_width, @@ -146,7 +167,12 @@ void load_and_convert_bmp_to_blt(uintptr_t *logo, size_t *logo_size, void convert_bmp_to_blt(uintptr_t logo, size_t logo_size, uintptr_t *blt, size_t *blt_size, uint32_t *pixel_height, uint32_t *pixel_width, enum lb_fb_orientation orientation); +void render_text_to_framebuffer(struct logo_config *config, const char *str, + enum bootsplash_text_type type); +bool platform_get_splash_text(enum bootsplash_type logo_type, char *msg, size_t msg_max); +/* Mainboard-specific override for logo filenames */ +const char *mainboard_bmp_logo_filename(void); /* * Allow platform-specific BMP logo overrides via HAVE_CUSTOM_BMP_LOGO config. * For example: Introduce configurable BMP logo for customization on platforms like ChromeOS @@ -165,8 +191,38 @@ void bmp_release_logo(void); */ #if CONFIG(PLATFORM_HAS_LOW_BATTERY_INDICATOR) bool platform_is_low_battery_shutdown_needed(void); +/* + * Platform hooks for system shutdown due to critical battery levels. + * Provides visual feedback via the Lightbar/LEDs and logs the event + * to non-volatile storage before signaling to cut power. + */ +void platform_handle_emergency_low_battery(void); #else static inline bool platform_is_low_battery_shutdown_needed(void) { return false; } +static inline void platform_handle_emergency_low_battery(void) { /* nop */ } +#endif + +/* + * Platform specific callbacks for off-mode bootsplash handling. + * + * These callbacks allow the platform to determine if the device + * has booted in off-mode charging to render the appropriate user + * notification. + */ +#if CONFIG(PLATFORM_HAS_OFF_MODE_CHARGING_INDICATOR) +/* + * platform_is_off_mode_charging_active - Check if off-mode charging is required. + * + * Returns true if the system should stay in a "charging splash" state + * instead of performing a full OS boot or a complete power-off. + */ +bool platform_is_off_mode_charging_active(void); +#else +/* Inline fallback for platforms without off-mode charging support */ +static inline bool platform_is_off_mode_charging_active(void) +{ + return false; +} #endif /* diff --git a/src/include/cbfs.h b/src/include/cbfs.h index 27a285e51dd..f7067f9009f 100644 --- a/src/include/cbfs.h +++ b/src/include/cbfs.h @@ -201,7 +201,8 @@ void *_cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg, size_t *size_out, bool force_ro, enum cbfs_type *type); void *_cbfs_unverified_area_alloc(const char *area, const char *name, - cbfs_allocator_t allocator, void *arg, size_t *size_out); + cbfs_allocator_t allocator, void *arg, size_t *size_out, + enum cbfs_type *type); struct _cbfs_default_allocator_arg { void *buf; @@ -242,7 +243,14 @@ static inline void *cbfs_unverified_area_alloc(const char *area, const char *nam cbfs_allocator_t allocator, void *arg, size_t *size_out) { - return _cbfs_unverified_area_alloc(area, name, allocator, arg, size_out); + return _cbfs_unverified_area_alloc(area, name, allocator, arg, size_out, NULL); +} + +static inline void *cbfs_unverified_area_type_alloc(const char *area, const char *name, + cbfs_allocator_t allocator, void *arg, + size_t *size_out, enum cbfs_type *type) +{ + return _cbfs_unverified_area_alloc(area, name, allocator, arg, size_out, type); } static inline void *cbfs_map(const char *name, size_t *size_out) @@ -268,7 +276,7 @@ static inline void *cbfs_ro_type_map(const char *name, size_t *size_out, enum cb static inline void *cbfs_unverified_area_map(const char *area, const char *name, size_t *size_out) { - return _cbfs_unverified_area_alloc(area, name, NULL, NULL, size_out); + return _cbfs_unverified_area_alloc(area, name, NULL, NULL, size_out, NULL); } static inline size_t _cbfs_load(const char *name, void *buf, size_t size, bool force_ro, @@ -307,7 +315,7 @@ static inline size_t cbfs_unverified_area_load(const char *area, const char *nam void *buf, size_t size) { struct _cbfs_default_allocator_arg arg = { .buf = buf, .buf_size = size }; - if (_cbfs_unverified_area_alloc(area, name, _cbfs_default_allocator, &arg, &size)) + if (_cbfs_unverified_area_alloc(area, name, _cbfs_default_allocator, &arg, &size, NULL)) return size; else return 0; @@ -341,7 +349,7 @@ static inline void *cbfs_unverified_area_cbmem_alloc(const char *area, const cha uint32_t cbmem_id, size_t *size_out) { return _cbfs_unverified_area_alloc(area, name, _cbfs_cbmem_allocator, - (void *)(uintptr_t)cbmem_id, size_out); + (void *)(uintptr_t)cbmem_id, size_out, NULL); } static inline size_t cbfs_get_size(const char *name) diff --git a/src/include/console/console.h b/src/include/console/console.h index 8d1a5c5dde0..a24425935ca 100644 --- a/src/include/console/console.h +++ b/src/include/console/console.h @@ -45,14 +45,15 @@ static inline int get_console_loglevel(void) ((ENV_BOOTBLOCK && CONFIG(BOOTBLOCK_CONSOLE)) || \ (ENV_POSTCAR && CONFIG(POSTCAR_CONSOLE)) || \ ENV_SEPARATE_VERSTAGE || ENV_SEPARATE_ROMSTAGE || ENV_RAMSTAGE || \ - ENV_LIBAGESA || (ENV_SMM && CONFIG(DEBUG_SMI))) + ENV_LIBAGESA || (ENV_SMM && CONFIG(DEBUG_SMI)) || \ + ENV_TEST) #if __CONSOLE_ENABLE__ int get_log_level(void); void console_init(void); int console_log_level(int msg_level); -int printk(int msg_level, const char *fmt, ...) __attribute__((format(printf, 2, 3))); +int printk(int msg_level, const char *fmt, ...) __printf(2, 3); int vprintk(int msg_level, const char *fmt, va_list args); void do_putchar(unsigned char byte); @@ -79,9 +80,7 @@ enum { CONSOLE_LOG_NONE = 0, CONSOLE_LOG_FAST, CONSOLE_LOG_ALL }; static inline int get_log_level(void) { return -1; } static inline void console_init(void) {} static inline int console_log_level(int msg_level) { return 0; } -static inline int - __attribute__((format(printf, 2, 3))) - printk(int LEVEL, const char *fmt, ...) { return 0; } +static inline int __printf(2, 3) printk(int LEVEL, const char *fmt, ...) { return 0; } static inline int vprintk(int LEVEL, const char *fmt, va_list args) { return 0; } static inline void do_putchar(unsigned char byte) {} static inline long console_time_get_and_reset(void) { return 0; } diff --git a/src/include/cper.h b/src/include/cper.h index 50e858a2198..1bddaa78efb 100644 --- a/src/include/cper.h +++ b/src/include/cper.h @@ -172,16 +172,61 @@ typedef struct cper_ia32x64_proc_error_section { (I32X64SEC_VALID_CTXNUM_MAX \ << I32X64SEC_VALID_CTXNUM_SH) +#define I32X64_ERRTYPE_INTERNAL_UNCLASSIFIED 5 + +struct cper_ia32x64_check_ms { + uint64_t validation_bits:16; + uint64_t err_type:3; + uint64_t proc_context_corrupt:1; + uint64_t uncorrected:1; + uint64_t precise_ip:1; + uint64_t restartable_ip:1; + uint64_t overflow:1; + uint64_t :40; +}; + +struct cper_ia32x64_check_tlb { + uint64_t validation_bits:16; + uint64_t transaction_type:2; + uint64_t operation:4; + uint64_t level:3; + uint64_t proc_context_corrupt:1; + uint64_t uncorrected:1; + uint64_t precise_ip:1; + uint64_t restartable_ip:1; + uint64_t overflow:1; + uint64_t :34; +}; + +struct cper_ia32x64_check_cache { + uint64_t validation_bits:16; + uint64_t transaction_type:2; + uint64_t operation:4; + uint64_t level:3; + uint64_t proc_context_corrupt:1; + uint64_t uncorrected:1; + uint64_t precise_ip:1; + uint64_t restartable_ip:1; + uint64_t overflow:1; + uint64_t :34; +}; + /* IA32/X64 Processor Error Information Structure (Table N.8) */ typedef struct cper_ia32x64_proc_error_info { guid_t type; /* cache, tlb, bus, micro-architecture specific */ u64 validation; - u64 check_info; + union { + struct cper_ia32x64_check_ms ms; + struct cper_ia32x64_check_tlb tlb; + struct cper_ia32x64_check_cache cache; + uint64_t raw; + }; u64 target_id; u64 requestor_id; u64 responder_id; u64 instruction_ip; } __packed cper_ia32x64_proc_error_info_t; +_Static_assert(sizeof(struct cper_ia32x64_proc_error_info) == 64, "cper_ia32x64_proc_error_info size wrong"); /* IA32/X64 Processor Error Information Structs, Err Struct Types (Table N.8) */ #define X86_PROCESSOR_CACHE_CHK_ERROR_GUID \ @@ -289,7 +334,7 @@ typedef struct cper_ia32x64_context { u16 array_size; u32 msr_addr; u64 mmap_addr; - /* N bytes of register array */ + u8 register_array[]; /* N bytes of register array */ } __packed cper_ia32x64_context_t; /* IA32/X64 Processor Context Information, Types field (Table N.13) */ @@ -459,7 +504,7 @@ static inline cper_timestamp_t cper_timestamp(int precise) * CPER_IA32X64_CTX_MEMMAPPED * num is the number of items in the context's register array */ -static inline size_t cper_ia32x64_ctx_sz_bytype(int type, int arr_num) +static inline size_t cper_ia32x64_ctx_sz_bytype(int type, int array_size) { size_t sz = sizeof(cper_ia32x64_context_t); @@ -476,7 +521,7 @@ static inline size_t cper_ia32x64_ctx_sz_bytype(int type, int arr_num) case CPER_IA32X64_CTX_MEMMAPPED: default: /* Table N.13: "size ... is determined by (Array Size / 8)" */ - return ALIGN_UP(sz + arr_num * 8, 16); + return ALIGN_UP(sz + array_size, 16); } } diff --git a/src/include/cpu/intel/cpu_ids.h b/src/include/cpu/intel/cpu_ids.h index ada3bfd2168..f43287226ac 100644 --- a/src/include/cpu/intel/cpu_ids.h +++ b/src/include/cpu/intel/cpu_ids.h @@ -95,5 +95,6 @@ #define CPUID_SNOWRIDGE_B1 0x80665 #define CPUID_SNOWRIDGE_C0 0x80667 #define CPUID_WILDCATLAKE 0xd0650 +#define CPUID_NOVALAKE 0x300f30 #endif /* CPU_INTEL_CPU_IDS_H */ diff --git a/src/include/cpu/intel/smm_reloc.h b/src/include/cpu/intel/smm_reloc.h index 6b1a525d6c0..2b25c757054 100644 --- a/src/include/cpu/intel/smm_reloc.h +++ b/src/include/cpu/intel/smm_reloc.h @@ -51,8 +51,6 @@ void smm_initialize(void); void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, size_t *smm_save_state_size); void smm_relocation_handler(int cpu, uintptr_t curr_smbase, uintptr_t staggered_smbase); -bool cpu_has_alternative_smrr(void); - #define MSR_PRMRR_PHYS_BASE 0x1f4 #define MSR_PRMRR_PHYS_MASK 0x1f5 #define MSR_UNCORE_PRMRR_PHYS_BASE 0x2f4 diff --git a/src/include/cpu/x86/mp.h b/src/include/cpu/x86/mp.h index dd86dce2c54..ec4297e105c 100644 --- a/src/include/cpu/x86/mp.h +++ b/src/include/cpu/x86/mp.h @@ -47,7 +47,7 @@ struct mp_ops { * Optionally fill in pointer to microcode and indicate if the APs * can load the microcode in parallel. */ - void (*get_microcode_info)(const void **microcode, int *parallel); + void (*get_microcode_info)(const void **microcode, size_t *size, int *parallel); /* * Optionally provide a callback prior to the APs starting SMM * relocation or CPU driver initialization. However, note that diff --git a/src/include/cpu/x86/msr.h b/src/include/cpu/x86/msr.h index a5226fb0b69..f4f33b40f6d 100644 --- a/src/include/cpu/x86/msr.h +++ b/src/include/cpu/x86/msr.h @@ -40,9 +40,12 @@ #define IA32_SMM_MONITOR_CTL_MSR 0x9B #define SMBASE_RO_MSR 0x98 #define IA32_SMM_MONITOR_VALID (1 << 0) +#define IA32_SYSENTER_EIP 0x176 #define IA32_MCG_CAP 0x179 #define MCG_CTL_P (1 << 8) #define MCA_BANKS_MASK 0xff +#define IA32_MCG_STATUS 0x17A +#define MCG_STAT_EIPV (1 << 1) #define IA32_PERF_STATUS 0x198 #define IA32_PERF_CTL 0x199 #define IA32_THERM_INTERRUPT 0x19b @@ -74,6 +77,8 @@ #define MCA_STATUS_HI_ADDRV (1UL << (58 - 32)) #define MCA_STATUS_HI_PCC (1UL << (57 - 32)) #define MCA_STATUS_HI_COREID_VAL (1UL << (56 - 32)) +#define MCA_STATUS_HI_TCC (1UL << (55 - 32)) +#define MCA_STATUS_HI_SYNDV (1UL << (53 - 32)) #define MCA_STATUS_HI_CECC (1UL << (46 - 32)) #define MCA_STATUS_HI_UECC (1UL << (45 - 32)) #define MCA_STATUS_HI_DEFERRED (1UL << (44 - 32)) @@ -137,67 +142,77 @@ static inline void mca_clear_status(void) /* Helpers for interpreting MC[i]_STATUS */ -static inline int mca_valid(msr_t msr) +static inline bool mca_valid(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_VAL); } -static inline int mca_over(msr_t msr) +static inline bool mca_over(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_OVERFLOW); } -static inline int mca_uc(msr_t msr) +static inline bool mca_uc(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_UC); } -static inline int mca_en(msr_t msr) +static inline bool mca_en(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_EN); } -static inline int mca_miscv(msr_t msr) +static inline bool mca_miscv(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_MISCV); } -static inline int mca_addrv(msr_t msr) +static inline bool mca_addrv(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_ADDRV); } -static inline int mca_pcc(msr_t msr) +static inline bool mca_pcc(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_PCC); } -static inline int mca_idv(msr_t msr) +static inline bool mca_tcc(msr_t msr) +{ + return !!(msr.hi & MCA_STATUS_HI_TCC); +} + +static inline bool mca_syndv(msr_t msr) +{ + return !!(msr.hi & MCA_STATUS_HI_SYNDV); +} + +static inline bool mca_idv(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_COREID_VAL); } -static inline int mca_cecc(msr_t msr) +static inline bool mca_cecc(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_CECC); } -static inline int mca_uecc(msr_t msr) +static inline bool mca_uecc(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_UECC); } -static inline int mca_defd(msr_t msr) +static inline bool mca_defd(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_DEFERRED); } -static inline int mca_poison(msr_t msr) +static inline bool mca_poison(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_POISON); } -static inline int mca_sublink(msr_t msr) +static inline bool mca_sublink(msr_t msr) { return !!(msr.hi & MCA_STATUS_HI_SUBLINK); } diff --git a/src/include/cpu/x86/smm.h b/src/include/cpu/x86/smm.h index b552d33b5a2..8c416238174 100644 --- a/src/include/cpu/x86/smm.h +++ b/src/include/cpu/x86/smm.h @@ -61,6 +61,7 @@ void southbridge_smi_handler(void); void mainboard_smi_gpi(u32 gpi_sts); int mainboard_smi_apmc(u8 data); void mainboard_smi_sleep(u8 slp_typ); +void mainboard_smi_sleep_finalize(u8 slp_typ); void mainboard_smi_finalize(void); int mainboard_set_smm_log_level(void); diff --git a/src/include/device/dram/ddr5.h b/src/include/device/dram/ddr5.h index 78d18b24f8a..ba048f6cb3e 100644 --- a/src/include/device/dram/ddr5.h +++ b/src/include/device/dram/ddr5.h @@ -15,6 +15,15 @@ /** Maximum SPD size supported */ #define SPD_SIZE_MAX_DDR5 1024 +/* DDR5 SPD byte offsets */ +#define DDR5_SPD_DENSITY_PACKAGE 4 +#define DDR5_SPD_ADDRESSING 5 +#define DDR5_SPD_IO_WIDTH 6 +#define DDR5_SPD_BANKS 7 +#define DDR5_SPD_MODULE_ORG 234 +#define DDR5_SPD_CHANNEL_BUS_WIDTH 235 +#define DDR5_SPD_MIN_LEN 236 + enum spd_dimm_type_ddr5 { SPD_DDR5_DIMM_TYPE_RDIMM = 0x01, SPD_DDR5_DIMM_TYPE_UDIMM = 0x02, diff --git a/src/include/device/pci_def.h b/src/include/device/pci_def.h index 6748b356b73..08381280573 100644 --- a/src/include/device/pci_def.h +++ b/src/include/device/pci_def.h @@ -204,6 +204,7 @@ #define PCI_CAP_ID_SSVID 0x0D /* Bridge subsystem vendor/device ID */ #define PCI_CAP_ID_PCIE 0x10 /* PCI Express */ #define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ +#define PCI_CAP_ID_SEC_PCIE 0x19 /* Secondary PCI Express Extended Capability */ #define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ #define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ @@ -481,7 +482,6 @@ #define PCIE_EXT_CAP_SRIOV_ID 0x0010 /* Secondary PCI Express Extended Capability Structure */ -#define PCI_EXP_SEC_CAP_ID 0x19 #define PCI_EXP_SEC_LNK_CTL3 4 /* Link Control 3 */ #define PCI_EXP_SEC_LANE_ERR_STATUS 8 /* Lane Error Status */ diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h index a3c3e580565..d990b86a022 100644 --- a/src/include/device/pci_ids.h +++ b/src/include/device/pci_ids.h @@ -2190,6 +2190,7 @@ #define PCI_DID_INTEL_PTL_H_ISHB 0xe445 #define PCI_DID_INTEL_PTL_U_H_ISHB 0xe345 #define PCI_DID_INTEL_WCL_ISHB 0x4d45 +#define PCI_DID_INTEL_NVL_ISHB 0xd354 /* Intel 82371FB (PIIX) */ #define PCI_DID_INTEL_82371FB_ISA 0x122e @@ -3349,6 +3350,38 @@ #define PCI_DID_INTEL_WCL_ESPI_29 0x4d1d #define PCI_DID_INTEL_WCL_ESPI_30 0x4d1e #define PCI_DID_INTEL_WCL_ESPI_31 0x4d1f +#define PCI_DID_INTEL_NVL_ESPI_0 0xd300 +#define PCI_DID_INTEL_NVL_ESPI_1 0xd301 +#define PCI_DID_INTEL_NVL_ESPI_2 0xd302 +#define PCI_DID_INTEL_NVL_ESPI_3 0xd303 +#define PCI_DID_INTEL_NVL_ESPI_4 0xd304 +#define PCI_DID_INTEL_NVL_ESPI_5 0xd305 +#define PCI_DID_INTEL_NVL_ESPI_6 0xd306 +#define PCI_DID_INTEL_NVL_ESPI_7 0xd307 +#define PCI_DID_INTEL_NVL_ESPI_8 0xd308 +#define PCI_DID_INTEL_NVL_ESPI_9 0xd309 +#define PCI_DID_INTEL_NVL_ESPI_10 0xd30a +#define PCI_DID_INTEL_NVL_ESPI_11 0xd30b +#define PCI_DID_INTEL_NVL_ESPI_12 0xd30c +#define PCI_DID_INTEL_NVL_ESPI_13 0xd30d +#define PCI_DID_INTEL_NVL_ESPI_14 0xd30e +#define PCI_DID_INTEL_NVL_ESPI_15 0xd30f +#define PCI_DID_INTEL_NVL_ESPI_16 0xd310 +#define PCI_DID_INTEL_NVL_ESPI_17 0xd311 +#define PCI_DID_INTEL_NVL_ESPI_18 0xd312 +#define PCI_DID_INTEL_NVL_ESPI_19 0xd313 +#define PCI_DID_INTEL_NVL_ESPI_20 0xd314 +#define PCI_DID_INTEL_NVL_ESPI_21 0xd315 +#define PCI_DID_INTEL_NVL_ESPI_22 0xd316 +#define PCI_DID_INTEL_NVL_ESPI_23 0xd317 +#define PCI_DID_INTEL_NVL_ESPI_24 0xd318 +#define PCI_DID_INTEL_NVL_ESPI_25 0xd319 +#define PCI_DID_INTEL_NVL_ESPI_26 0xd31a +#define PCI_DID_INTEL_NVL_ESPI_27 0xd31b +#define PCI_DID_INTEL_NVL_ESPI_28 0xd31c +#define PCI_DID_INTEL_NVL_ESPI_29 0xd31d +#define PCI_DID_INTEL_NVL_ESPI_30 0xd31e +#define PCI_DID_INTEL_NVL_ESPI_31 0xd31f /* Intel PCIE device ids */ #define PCI_DID_INTEL_LPT_H_PCIE_RP1 0x8c10 @@ -3492,23 +3525,6 @@ #define PCI_DID_INTEL_CNL_LP_PCIE_RP15 0x9db6 #define PCI_DID_INTEL_CNL_LP_PCIE_RP16 0x9db7 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP1 0x34b8 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP2 0x34b9 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP3 0x34ba -#define PCI_DID_INTEL_ICP_LP_PCIE_RP4 0x34bb -#define PCI_DID_INTEL_ICP_LP_PCIE_RP5 0x34bc -#define PCI_DID_INTEL_ICP_LP_PCIE_RP6 0x34bd -#define PCI_DID_INTEL_ICP_LP_PCIE_RP7 0x34be -#define PCI_DID_INTEL_ICP_LP_PCIE_RP8 0x34bf -#define PCI_DID_INTEL_ICP_LP_PCIE_RP9 0x34b0 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP10 0x34b1 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP11 0x34b2 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP12 0x34b3 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP13 0x34b4 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP14 0x34b5 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP15 0x34b6 -#define PCI_DID_INTEL_ICP_LP_PCIE_RP16 0x34b7 - #define PCI_DID_INTEL_TGP_LP_PCIE_RP1 0xa0b8 #define PCI_DID_INTEL_TGP_LP_PCIE_RP2 0xa0b9 #define PCI_DID_INTEL_TGP_LP_PCIE_RP3 0xa0ba @@ -3829,6 +3845,21 @@ #define PCI_DID_INTEL_WCL_PCIE_RP5 0x4d61 #define PCI_DID_INTEL_WCL_PCIE_RP6 0x4d5c +#define PCI_DID_INTEL_NVL_PCIE_RP1 0xd338 +#define PCI_DID_INTEL_NVL_PCIE_RP2 0xd339 +#define PCI_DID_INTEL_NVL_PCIE_RP3 0xd33a +#define PCI_DID_INTEL_NVL_PCIE_RP4 0xd33b +#define PCI_DID_INTEL_NVL_PCIE_RP5 0xd33c +#define PCI_DID_INTEL_NVL_PCIE_RP6 0xd33d +#define PCI_DID_INTEL_NVL_PCIE_RP7 0xd33e +#define PCI_DID_INTEL_NVL_PCIE_RP8 0xd33f +#define PCI_DID_INTEL_NVL_PCIE_RP9 0xd361 +#define PCI_DID_INTEL_NVL_PCIE_RP10 0xd35c +#define PCI_DID_INTEL_NVL_PCIE_RP11 0xd365 +#define PCI_DID_INTEL_NVL_PCIE_RP12 0xd366 +#define PCI_DID_INTEL_NVL_PCIE_RP13 0xd367 +#define PCI_DID_INTEL_NVL_PCIE_RP14 0xd368 + /* Intel SATA device Ids */ #define PCI_DID_INTEL_LPT_H_DESKTOP_SATA_IDE 0x8c00 #define PCI_DID_INTEL_LPT_H_DESKTOP_SATA_AHCI 0x8c02 @@ -3882,7 +3913,6 @@ #define PCI_DID_INTEL_CNP_H_SATA 0xa352 #define PCI_DID_INTEL_CNP_H_HALO_SATA 0xa353 #define PCI_DID_INTEL_CNP_LP_SATA 0x9dd3 -#define PCI_DID_INTEL_ICP_U_SATA 0x34d3 #define PCI_DID_INTEL_CMP_SATA 0x02d5 #define PCI_DID_INTEL_CMP_PREMIUM_SATA 0x02d7 #define PCI_DID_INTEL_CMP_LP_SATA 0x02d3 @@ -3932,7 +3962,6 @@ #define PCI_DID_INTEL_GLK_PMC 0x3194 #define PCI_DID_INTEL_CNL_PMC 0x9da1 #define PCI_DID_INTEL_CNP_H_PMC 0xa321 -#define PCI_DID_INTEL_ICP_PMC 0x34a1 #define PCI_DID_INTEL_CMP_PMC 0x02a1 #define PCI_DID_INTEL_CMP_H_PMC 0x06a1 #define PCI_DID_INTEL_TGP_PMC 0xa0a1 @@ -3954,6 +3983,7 @@ #define PCI_DID_INTEL_PTL_H_PMC 0xe421 #define PCI_DID_INTEL_PTL_U_H_PMC 0xe321 #define PCI_DID_INTEL_WCL_PMC 0x4d21 +#define PCI_DID_INTEL_NVL_PMC 0xd321 /* Intel I2C device Ids */ #define PCI_DID_INTEL_LPT_LP_I2C0 0x9c61 @@ -3994,12 +4024,6 @@ #define PCI_DID_INTEL_CNP_H_I2C1 0xa369 #define PCI_DID_INTEL_CNP_H_I2C2 0xa36a #define PCI_DID_INTEL_CNP_H_I2C3 0xa36b -#define PCI_DID_INTEL_ICP_I2C0 0x34e8 -#define PCI_DID_INTEL_ICP_I2C1 0x34e9 -#define PCI_DID_INTEL_ICP_I2C2 0x34ea -#define PCI_DID_INTEL_ICP_I2C3 0x34eb -#define PCI_DID_INTEL_ICP_I2C4 0x34c5 -#define PCI_DID_INTEL_ICP_I2C5 0x34c6 #define PCI_DID_INTEL_CMP_I2C0 0x02e8 #define PCI_DID_INTEL_CMP_I2C1 0x02e9 #define PCI_DID_INTEL_CMP_I2C2 0x02ea @@ -4119,6 +4143,13 @@ #define PCI_DID_INTEL_WCL_I2C4 0x4d50 #define PCI_DID_INTEL_WCL_I2C5 0x4d51 +#define PCI_DID_INTEL_NVL_I2C0 0xd378 +#define PCI_DID_INTEL_NVL_I2C1 0xd379 +#define PCI_DID_INTEL_NVL_I2C2 0xd37a +#define PCI_DID_INTEL_NVL_I2C3 0xd37b +#define PCI_DID_INTEL_NVL_I2C4 0xd350 +#define PCI_DID_INTEL_NVL_I2C5 0xd351 + /* Intel UART device Ids */ #define PCI_DID_INTEL_LPT_LP_UART0 0x9c63 #define PCI_DID_INTEL_LPT_LP_UART1 0x9c64 @@ -4145,9 +4176,6 @@ #define PCI_DID_INTEL_CNP_H_UART0 0xa328 #define PCI_DID_INTEL_CNP_H_UART1 0xa329 #define PCI_DID_INTEL_CNP_H_UART2 0xa347 -#define PCI_DID_INTEL_ICP_UART0 0x34a8 -#define PCI_DID_INTEL_ICP_UART1 0x34a9 -#define PCI_DID_INTEL_ICP_UART2 0x34c7 #define PCI_DID_INTEL_CMP_UART0 0x02a8 #define PCI_DID_INTEL_CMP_UART1 0x02a9 #define PCI_DID_INTEL_CMP_UART2 0x02c7 @@ -4222,6 +4250,10 @@ #define PCI_DID_INTEL_WCL_UART1 0x4d26 #define PCI_DID_INTEL_WCL_UART2 0x4d52 +#define PCI_DID_INTEL_NVL_UART0 0xd325 +#define PCI_DID_INTEL_NVL_UART1 0xd326 +#define PCI_DID_INTEL_NVL_UART2 0xd352 + /* Intel SPI device Ids */ #define PCI_DID_INTEL_LPT_LP_GSPI0 0x9c65 #define PCI_DID_INTEL_LPT_LP_GSPI1 0x9c66 @@ -4246,10 +4278,6 @@ #define PCI_DID_INTEL_CNP_H_SPI1 0xa32b #define PCI_DID_INTEL_CNP_H_SPI2 0xa37b #define PCI_DID_INTEL_CNP_H_HWSEQ_SPI 0xa324 -#define PCI_DID_INTEL_ICP_SPI0 0x34aa -#define PCI_DID_INTEL_ICP_SPI1 0x34ab -#define PCI_DID_INTEL_ICP_SPI2 0x34fb -#define PCI_DID_INTEL_ICP_HWSEQ_SPI 0x34a4 #define PCI_DID_INTEL_CMP_SPI0 0x02aa #define PCI_DID_INTEL_CMP_SPI1 0x02ab #define PCI_DID_INTEL_CMP_SPI2 0x02fb @@ -4349,6 +4377,11 @@ #define PCI_DID_INTEL_WCL_SPI1 0x4d30 #define PCI_DID_INTEL_WCL_SPI2 0x4d46 +#define PCI_DID_INTEL_NVL_HWSEQ_SPI 0xd323 +#define PCI_DID_INTEL_NVL_SPI0 0xd327 +#define PCI_DID_INTEL_NVL_SPI1 0xd330 +#define PCI_DID_INTEL_NVL_SPI2 0xd347 + /* Intel IGD device Ids */ #define PCI_DID_INTEL_SKL_GT1F_DT2 0x1902 #define PCI_DID_INTEL_SKL_GT1_SULTM 0x1906 @@ -4522,6 +4555,11 @@ #define PCI_DID_INTEL_PTL_H_GT2_4 0xb08f #define PCI_DID_INTEL_WCL_GT2_1 0xfd80 #define PCI_DID_INTEL_WCL_GT2_2 0xfd81 +#define PCI_DID_INTEL_NVL_GT2_1 0xd741 +#define PCI_DID_INTEL_NVL_GT2_2 0xd742 +#define PCI_DID_INTEL_NVL_GT2_3 0xd743 +#define PCI_DID_INTEL_NVL_GT2_4 0xd744 +#define PCI_DID_INTEL_NVL_GT2_5 0xd745 /* Intel Northbridge Ids */ #define PCI_DID_INTEL_APL_NB 0x5af0 @@ -4691,6 +4729,11 @@ #define PCI_DID_INTEL_WCL_ID_3 0xfd02 #define PCI_DID_INTEL_WCL_ID_4 0xfd03 #define PCI_DID_INTEL_WCL_ID_5 0xfd04 +#define PCI_DID_INTEL_NVL_ID_1 0xd701 +#define PCI_DID_INTEL_NVL_ID_2 0xd702 +#define PCI_DID_INTEL_NVL_ID_3 0xd704 +#define PCI_DID_INTEL_NVL_ID_4 0xd705 +#define PCI_DID_INTEL_NVL_ID_5 0xd70e /* Intel SMBUS device Ids */ #define PCI_DID_INTEL_LPT_H_SMBUS 0x8c22 @@ -4706,7 +4749,6 @@ #define PCI_DID_INTEL_LWB_SMBUS_SUPER 0xa223 #define PCI_DID_INTEL_CNL_SMBUS 0x9da3 #define PCI_DID_INTEL_CNP_H_SMBUS 0xa323 -#define PCI_DID_INTEL_ICP_LP_SMBUS 0x34a3 #define PCI_DID_INTEL_CMP_SMBUS 0x02a3 #define PCI_DID_INTEL_CMP_H_SMBUS 0x06a3 #define PCI_DID_INTEL_TGP_LP_SMBUS 0xa0a3 @@ -4747,7 +4789,6 @@ #define PCI_DID_INTEL_UPT_H_XHCI 0xa2af #define PCI_DID_INTEL_CNL_LP_XHCI 0x9ded #define PCI_DID_INTEL_CNP_H_XHCI 0xa36d -#define PCI_DID_INTEL_ICP_LP_XHCI 0x34ed #define PCI_DID_INTEL_CMP_LP_XHCI 0x02ed #define PCI_DID_INTEL_CMP_H_XHCI 0x06ed #define PCI_DID_INTEL_TGP_LP_XHCI 0xa0ed @@ -4777,6 +4818,8 @@ #define PCI_DID_INTEL_SNR_XHCI 0x18d0 #define PCI_DID_INTEL_WCL_XHCI 0x4d7d #define PCI_DID_INTEL_WCL_TCSS_XHCI 0x4d31 +#define PCI_DID_INTEL_NVL_XHCI 0xd37d +#define PCI_DID_INTEL_NVL_TCSS_XHCI 0xd331 /* Intel P2SB device Ids */ #define PCI_DID_INTEL_APL_P2SB 0x5a92 @@ -4815,6 +4858,8 @@ #define PCI_DID_INTEL_SNR_P2SB 0x18dd #define PCI_DID_INTEL_WCL_P2SB 0x4d20 #define PCI_DID_INTEL_WCL_P2SB2 0x4d4c +#define PCI_DID_INTEL_NVL_P2SB 0xd320 +#define PCI_DID_INTEL_NVL_P2SB2 0xd34c /* Intel SRAM device Ids */ #define PCI_DID_INTEL_APL_SRAM 0x5aec @@ -4836,6 +4881,7 @@ #define PCI_DID_INTEL_PTL_H_SRAM 0xe47f #define PCI_DID_INTEL_PTL_U_H_SRAM 0xe37f #define PCI_DID_INTEL_WCL_SRAM 0x4d7f +#define PCI_DID_INTEL_NVL_SRAM 0xd37e /* Intel AUDIO device Ids */ #define PCI_DID_INTEL_LPT_H_AUDIO 0x8c20 @@ -4932,6 +4978,15 @@ #define PCI_DID_INTEL_WCL_AUDIO_7 0x4d2e #define PCI_DID_INTEL_WCL_AUDIO_8 0x4d2f +#define PCI_DID_INTEL_NVL_AUDIO_1 0xd328 +#define PCI_DID_INTEL_NVL_AUDIO_2 0xd329 +#define PCI_DID_INTEL_NVL_AUDIO_3 0xd32a +#define PCI_DID_INTEL_NVL_AUDIO_4 0xd32b +#define PCI_DID_INTEL_NVL_AUDIO_5 0xd32c +#define PCI_DID_INTEL_NVL_AUDIO_6 0xd32d +#define PCI_DID_INTEL_NVL_AUDIO_7 0xd32e +#define PCI_DID_INTEL_NVL_AUDIO_8 0xd32f + /* Intel HECI/ME device Ids */ #define PCI_DID_INTEL_LPT_H_MEI 0x8c3a #define PCI_DID_INTEL_LPT_H_MEI_9 0x8cba @@ -4989,6 +5044,7 @@ #define PCI_DID_INTEL_PTL_U_H_CSE0 0xe370 #define PCI_DID_INTEL_SNR_HECI1 0x18d3 #define PCI_DID_INTEL_WCL_CSE0 0x4d70 +#define PCI_DID_INTEL_NVL_CSE0 0xd370 /* Intel XDCI device Ids */ #define PCI_DID_INTEL_APL_XDCI 0x5aaa @@ -4996,7 +5052,6 @@ #define PCI_DID_INTEL_SPT_LP_XDCI 0x9d30 #define PCI_DID_INTEL_CNL_LP_XDCI 0x9dee #define PCI_DID_INTEL_CNP_H_XDCI 0xa36e -#define PCI_DID_INTEL_ICP_LP_XDCI 0x34ee #define PCI_DID_INTEL_CMP_LP_XDCI 0x02ee #define PCI_DID_INTEL_CMP_H_XDCI 0x06ee #define PCI_DID_INTEL_TGP_LP_XDCI 0xa0ee @@ -5017,6 +5072,7 @@ #define PCI_DID_INTEL_PTL_H_XDCI 0xe47e #define PCI_DID_INTEL_PTL_U_H_XDCI 0xe37e #define PCI_DID_INTEL_WCL_XDCI 0x4d7e +#define PCI_DID_INTEL_NVL_XDCI 0xd37f /* Intel SD device Ids */ #define PCI_DID_INTEL_LPT_LP_SD 0x9c35 @@ -5078,6 +5134,7 @@ #define PCI_DID_INTEL_PTL_TBT_DMA0 0xe433 #define PCI_DID_INTEL_PTL_TBT_DMA1 0xe434 #define PCI_DID_INTEL_WCL_TBT_DMA0 0x4d33 +#define PCI_DID_INTEL_NVL_TBT_DMA0 0xd333 /* Intel WIFI Ids */ #define PCI_DID_1000_SERIES_WIFI 0x0084 @@ -5120,6 +5177,7 @@ #define PCI_DID_INTEL_RPL_IPU 0xa75d #define PCI_DID_INTEL_LNL_IPU 0x645d #define PCI_DID_INTEL_PTL_IPU 0xb05d +#define PCI_DID_INTEL_NVL_IPU 0xd719 /* Intel Dynamic Tuning Technology Device */ #define PCI_DID_INTEL_CML_DTT 0x1903 @@ -5199,6 +5257,11 @@ #define PCI_DID_INTEL_WCL_CNVI_WIFI_2 0x4d42 #define PCI_DID_INTEL_WCL_CNVI_WIFI_3 0x4d43 #define PCI_DID_INTEL_WCL_CNVI_BT 0x4d76 +#define PCI_DID_INTEL_NVL_CNVI_WIFI_0 0xd340 +#define PCI_DID_INTEL_NVL_CNVI_WIFI_1 0xd341 +#define PCI_DID_INTEL_NVL_CNVI_WIFI_2 0xd342 +#define PCI_DID_INTEL_NVL_CNVI_WIFI_3 0xd343 +#define PCI_DID_INTEL_NVL_CNVI_BT 0xd346 /* Platform Security Engine */ #define PCI_DID_INTEL_LNL_PSE0 0xa862 @@ -5224,6 +5287,7 @@ #define PCI_DID_INTEL_RPP_S_PMC_CRASHLOG_SRAM 0x7a27 #define PCI_DID_INTEL_PTL_PUNIT_CRASHLOG_SRAM 0xb07d #define PCI_DID_INTEL_WCL_PUNIT_CRASHLOG_SRAM 0xfd7d +#define PCI_DID_INTEL_NVL_PUNIT_CRASHLOG_SRAM 0xd70d /* Intel Trace Hub */ #define PCI_DID_INTEL_MTL_TRACEHUB 0x7e24 @@ -5234,6 +5298,7 @@ #define PCI_DID_INTEL_PTL_H_TRACEHUB 0xe424 #define PCI_DID_INTEL_PTL_U_H_TRACEHUB 0xe324 #define PCI_DID_INTEL_WCL_TRACEHUB 0x4d24 +#define PCI_DID_INTEL_NVL_TRACEHUB 0xd324 /* Intel Ethernet Controller device Ids */ #define PCI_DID_INTEL_EHL_GBE_HOST 0x4B32 @@ -5265,6 +5330,10 @@ #define PCI_DID_INTEL_ARP_S_THC0_2 0x7f59 #define PCI_DID_INTEL_ARP_S_THC1_1 0x7f5a #define PCI_DID_INTEL_ARP_S_THC1_2 0x7f5b +#define PCI_DID_INTEL_NVL_THC0_1 0xd348 +#define PCI_DID_INTEL_NVL_THC0_2 0xd349 +#define PCI_DID_INTEL_NVL_THC1_1 0xd34a +#define PCI_DID_INTEL_NVL_THC1_2 0xd34b #define PCI_VID_COMPUTONE 0x8e0e #define PCI_DID_COMPUTONE_IP2EX 0x0291 diff --git a/src/include/device/smbus.h b/src/include/device/smbus.h index 171e3044727..02ddec661a4 100644 --- a/src/include/device/smbus.h +++ b/src/include/device/smbus.h @@ -16,6 +16,7 @@ struct smbus_bus_operations { int (*block_read)(struct device *dev, u8 cmd, u8 bytes, u8 *buffer); int (*block_write)(struct device *dev, u8 cmd, u8 bytes, const u8 *buffer); + int (*i2c_eeprom_read)(struct device *dev, u8 offset, u8 bytes, u8 *buffer); }; static inline const struct smbus_bus_operations *ops_smbus_bus(struct bus *bus) @@ -54,6 +55,7 @@ static inline int smbus_write_byte(struct device *const dev, u8 addr, u8 val) int smbus_block_read(struct device *dev, u8 cmd, u8 bytes, u8 *buffer); int smbus_block_write(struct device *dev, u8 cmd, u8 bytes, const u8 *buffer); +int smbus_i2c_eeprom_read(struct device *dev, u8 cmd, u8 bytes, u8 *buffer); #endif #endif /* DEVICE_SMBUS_H */ diff --git a/src/include/devtree_update.h b/src/include/devtree_update.h new file mode 100644 index 00000000000..b99b689b995 --- /dev/null +++ b/src/include/devtree_update.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __DEVTREE_UPDATE_H__ +#define __DEVTREE_UPDATE_H__ + +/* + * Optional mainboard hook to update devicetree runtime enable/disable state + * based on CMOS/NVRAM settings. + * + * This function is called early in ramstage at BS_PRE_DEVICE. + */ +void devtree_update(void); + +#endif /* __DEVTREE_UPDATE_H__ */ diff --git a/src/include/fmap.h b/src/include/fmap.h index 900bfff542f..1fadaef3c5f 100644 --- a/src/include/fmap.h +++ b/src/include/fmap.h @@ -13,6 +13,14 @@ #error "FMAP must always start flash address 0" #endif +/* This is usually the case. And it can to lead to confusion if one them is updated without the + * other. There is however no code that has a hard dependency on this check. So if there comes + * a platform at some point, which has a Flashmap which doesn't cover the whole flash, we can + * remove the check again. */ +#if FMAP_SECTION_FLASH_SIZE != CONFIG_ROM_SIZE + #error "ROM_SIZE must always be equal to FMAP flash size" +#endif + /* Return the name of the boot region. Falls back to COREBOOT, if not overridden * by any multi-slot mechanism (e.g Intel Top Swap, vboot). */ const char *cbfs_fmap_region_hint(void); diff --git a/src/include/mipi/panel.h b/src/include/mipi/panel.h index d306f06fb4c..432b43090be 100644 --- a/src/include/mipi/panel.h +++ b/src/include/mipi/panel.h @@ -3,29 +3,15 @@ #ifndef __MIPI_PANEL_H__ #define __MIPI_PANEL_H__ +#include #include -#include #include -/* Definitions for cmd in panel_init_command */ -enum panel_init_cmd { - PANEL_CMD_END = 0, - PANEL_CMD_DELAY = 1, - PANEL_CMD_GENERIC = 2, - PANEL_CMD_DCS = 3, -}; - /* Definitions for flags in panel_serializable_data */ enum panel_flag { PANEL_FLAG_CPHY = BIT(0), }; -struct panel_init_command { - u8 cmd; - u8 len; - u8 data[]; -}; - /* VESA Display Stream Compression DSC 1.2 constants */ #define DSC_NUM_BUF_RANGES 15 @@ -85,14 +71,6 @@ struct dsc_config { * @slice_height: Slice height in pixels */ u16 slice_height; - /* - * @pic_width: Width of the input display frame in pixels - */ - u16 pic_width; - /* - * @pic_height: Vertical height of the input display frame - */ - u16 pic_height; /* * @rc_tgt_offset_high: * Offset to bits/group used by RC to determine QP adjustment @@ -211,6 +189,8 @@ struct dsc_config { u8 dsc_version_major; }; +#define PANEL_POWEROFF_CMD_MAX_LEN 16 + /* * The data to be serialized and put into CBFS. * Note some fields, for example edid.mode.name, were actually pointers and @@ -220,38 +200,9 @@ struct panel_serializable_data { u32 flags; /* flags of panel_flag */ struct edid edid; /* edid info of this panel */ struct dsc_config dsc_config; /* dsc config of this panel */ - u8 init[]; /* A packed array of panel_init_command */ + /* Packed arrays of panel_command */ + u8 poweroff[PANEL_POWEROFF_CMD_MAX_LEN]; + u8 init[]; }; -/* - * Callback function type for mipi_panel_parse_init_commands(). - * @param type MIPI DSI transaction type. - * @param data panel_init_command data. - * @param len panel_init_command len. - * @param user_data Arbitrary user data passed from mipi_panel_parse_init_commands(). - */ -typedef enum cb_err (*mipi_cmd_func_t)(enum mipi_dsi_transaction type, const u8 *data, u8 len, - void *user_data); - -/* Parse a command array and call cmd_func() for each entry. Delays get handled internally. */ -enum cb_err mipi_panel_parse_init_commands(const void *buf, mipi_cmd_func_t cmd_func, - void *user_data); - -#define PANEL_DCS(...) \ - PANEL_CMD_DCS, \ - sizeof((u8[]){__VA_ARGS__}), \ - __VA_ARGS__ - -#define PANEL_GENERIC(...) \ - PANEL_CMD_GENERIC, \ - sizeof((u8[]){__VA_ARGS__}), \ - __VA_ARGS__ - -#define PANEL_DELAY(delay) \ - PANEL_CMD_DELAY, \ - delay - -#define PANEL_END \ - PANEL_CMD_END - #endif /* __MIPI_PANEL_H__ */ diff --git a/src/include/rules.h b/src/include/rules.h index 673138bfe6a..053cd6bc09c 100644 --- a/src/include/rules.h +++ b/src/include/rules.h @@ -267,6 +267,14 @@ #define ENV_PAYLOAD_LOADER ENV_RAMSTAGE #endif +#if CONFIG(POSTCAR_STAGE) +#define ENV_RAMSTAGE_LOADER ENV_POSTCAR +#elif CONFIG(SEPARATE_ROMSTAGE) +#define ENV_RAMSTAGE_LOADER ENV_SEPARATE_ROMSTAGE +#else +#define ENV_RAMSTAGE_LOADER ENV_BOOTBLOCK +#endif + #define ENV_ROMSTAGE_OR_BEFORE \ (ENV_DECOMPRESSOR || ENV_BOOTBLOCK || ENV_SEPARATE_ROMSTAGE || \ (ENV_SEPARATE_VERSTAGE && !CONFIG(VBOOT_STARTS_IN_ROMSTAGE))) diff --git a/src/include/smbios.h b/src/include/smbios.h index b9dbc0bdf63..103e85b9afd 100644 --- a/src/include/smbios.h +++ b/src/include/smbios.h @@ -123,6 +123,7 @@ int smbios_write_type8(unsigned long *current, int *handle, #define BIOS_EXT1_CHARACTERISTICS_ACPI (1 << 0) #define BIOS_EXT2_CHARACTERISTICS_TARGET (1 << 2) +#define BIOS_EXT2_CHARACTERISTICS_UEFI_SUPPORT (1 << 3) #define BIOS_MEMORY_ECC_SINGLE_BIT_CORRECTING (1 << 3) #define BIOS_MEMORY_ECC_DOUBLE_BIT_CORRECTING (1 << 4) diff --git a/src/lib/Kconfig b/src/lib/Kconfig index 6407c82cfa0..38cc4590867 100644 --- a/src/lib/Kconfig +++ b/src/lib/Kconfig @@ -229,16 +229,17 @@ config PLATFORM_HAS_LOW_BATTERY_INDICATOR This option requires that the system have a display and that the BMP_LOGO option is enabled. -if PLATFORM_HAS_LOW_BATTERY_INDICATOR - -config PLATFORM_LOW_BATTERY_SHUTDOWN_DELAY_SEC +config PLATFORM_POST_RENDER_DELAY_SEC int default 5 help - Delay, in seconds, before system shutdown due to low battery. - This delay allows the user to observe the low-battery indicator. - The default value of 5 seconds aligns with standard user experience (UX) practices. - Platforms may override this value based on specific product requirements. + Delay, in seconds, after rendering a splash screen element. + In low-battery mode, this ensures the warning is visible before shutdown. + In normal modes, this can be used to ensure the display has finished + teardown/synchronization after user notification before passing control + to the OS. + +if PLATFORM_HAS_LOW_BATTERY_INDICATOR config PLATFORM_HAS_EARLY_LOW_BATTERY_INDICATOR bool "Display low battery indicator in romstage" @@ -269,6 +270,63 @@ config SPLASH_SCREEN_FOOTER_LOGO_PATH depends on SPLASH_SCREEN_FOOTER default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/logo.bmp" +config PLATFORM_HAS_OFF_MODE_CHARGING_INDICATOR + bool "Display off-mode charging indicator" + default n + depends on BMP_LOGO + help + Enable an off-mode charging splash screen to notify the user that + the device is charging. This prevents user confusion when a + device autoboots into a charging state upon the + insertion of a power cable, rather than performing a full OS boot. + + This feature requires a functional display and depends on the + BMP_LOGO infrastructure to render the charging assets. + +config PLATFORM_OFF_MODE_CHARGING_INDICATOR_LOGO_PATH + string "Path to off-mode charging logo file" + default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/off_mode_charging.bmp" + +config FRAMEBUFFER_SPLASH_TEXT + bool "Enable splash screen text" + default n + help + Enable logic to render bitmapped text strings directly into + the linear framebuffer during the splash screen stage. This + method uses a bitmapped font table to display system + status messages, such as battery charging levels. + +if FRAMEBUFFER_SPLASH_TEXT + +choice + prompt "Font Selection" + default FONT_GOOGLE_SANS_FLEX_MEDIUM_24X32 + +config FONT_GOOGLE_SANS_FLEX_MEDIUM_24X32 + bool "Google Sans Flex Medium 24x32" + help + Use the Google Sans Medium font table generated from + GoogleSansFlex_24pt-Medium.ttf using `generate_font.py` script. + Dimensions: 24x32 pixels. + +endchoice + +config FONT_WIDTH + int + default 24 if FONT_GOOGLE_SANS_FLEX_MEDIUM_24X32 + default 16 + help + The width of the font canvas in pixels. + +config FONT_HEIGHT + int + default 32 if FONT_GOOGLE_SANS_FLEX_MEDIUM_24X32 + default 24 + help + The height of the font canvas in pixels. + +endif # FRAMEBUFFER_SPLASH_TEXT + endmenu config HAVE_EARLY_POWEROFF_SUPPORT diff --git a/src/lib/Makefile.mk b/src/lib/Makefile.mk index 073d9fbb68c..0dc41ce9212 100644 --- a/src/lib/Makefile.mk +++ b/src/lib/Makefile.mk @@ -149,13 +149,16 @@ ramstage-y += wrdd.c ramstage-$(CONFIG_CONSOLE_CBMEM) += cbmem_console.c ramstage-$(CONFIG_BMP_LOGO) += bmp_logo.c ramstage-$(CONFIG_BMP_LOGO) += render_bmp.c +ramstage-$(CONFIG_FRAMEBUFFER_SPLASH_TEXT) += render_text.c +ramstage-$(CONFIG_FONT_GOOGLE_SANS_FLEX_MEDIUM_24X32) += fonts/font_table_google_sans_flex_medium_24x32.c ramstage-$(CONFIG_BOOTSPLASH) += bootsplash.c ramstage-$(CONFIG_BOOTSPLASH) += jpeg.c ramstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c ramstage-$(CONFIG_COVERAGE) += libgcov.c +ramstage-y += devtree_update.c ramstage-y += dp_aux.c +ramstage-y += framebuffer_info.c ramstage-y += edid.c -ramstage-y += edid_fill_fb.c ramstage-y += memrange.c ramstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c ramstage-$(CONFIG_GENERIC_UDELAY) += timer.c @@ -275,9 +278,6 @@ postcar-y += crc_byte.c ramstage-y += crc_byte.c smm-y += crc_byte.c -romstage-y += xxhash.c -ramstage-y += xxhash.c - postcar-y += bootmode.c postcar-y += boot_device.c postcar-y += cbfs.c @@ -452,3 +452,5 @@ $(eval $(call add_bmp_logo_file_to_cbfs,CONFIG_PLATFORM_HAS_LOW_BATTERY_INDICATO low_battery.bmp,CONFIG_PLATFORM_LOW_BATTERY_INDICATOR_LOGO_PATH)) $(eval $(call add_bmp_logo_file_to_cbfs,CONFIG_SPLASH_SCREEN_FOOTER, \ footer_logo.bmp,CONFIG_SPLASH_SCREEN_FOOTER_LOGO_PATH)) +$(eval $(call add_bmp_logo_file_to_cbfs,CONFIG_PLATFORM_HAS_OFF_MODE_CHARGING_INDICATOR, \ + off_mode_charging.bmp,CONFIG_PLATFORM_OFF_MODE_CHARGING_INDICATOR_LOGO_PATH)) diff --git a/src/lib/bmp_logo.c b/src/lib/bmp_logo.c index 9dfe15a0856..7b0de547209 100644 --- a/src/lib/bmp_logo.c +++ b/src/lib/bmp_logo.c @@ -13,7 +13,8 @@ static const struct cbmem_entry *logo_entry; static const char *bootsplash_list[BOOTSPLASH_MAX_NUM] = { [BOOTSPLASH_LOW_BATTERY] = "low_battery.bmp", [BOOTSPLASH_CENTER] = "logo.bmp", - [BOOTSPLASH_FOOTER] = "footer_logo.bmp" + [BOOTSPLASH_FOOTER] = "footer_logo.bmp", + [BOOTSPLASH_OFF_MODE_CHARGING] = "off_mode_charging.bmp" }; /* @@ -60,6 +61,9 @@ void *bmp_load_logo(size_t *logo_size) if (platform_is_low_battery_shutdown_needed()) type = BOOTSPLASH_LOW_BATTERY; + if (platform_is_off_mode_charging_active()) + type = BOOTSPLASH_OFF_MODE_CHARGING; + return bmp_load_logo_by_type(type, logo_size); } diff --git a/src/lib/bootmem.c b/src/lib/bootmem.c index dbd8450f064..b6be5820d22 100644 --- a/src/lib/bootmem.c +++ b/src/lib/bootmem.c @@ -14,7 +14,38 @@ static int table_written; static struct memranges bootmem; static struct memranges bootmem_os; -static const char *bootmem_range_string(const enum bootmem_type tag); +struct range_strings { + enum bootmem_type tag; + const char *str; +}; + +static const struct range_strings type_strings[] = { + { BM_MEM_RAM, "RAM" }, + { BM_MEM_RESERVED, "RESERVED" }, + { BM_MEM_ACPI, "ACPI" }, + { BM_MEM_NVS, "NVS" }, + { BM_MEM_UNUSABLE, "UNUSABLE" }, + { BM_MEM_VENDOR_RSVD, "VENDOR RESERVED" }, + { BM_MEM_BL31, "BL31" }, + { BM_MEM_OPENSBI, "OPENSBI" }, + { BM_MEM_TABLE, "CONFIGURATION TABLES" }, + { BM_MEM_SOFT_RESERVED, "SOFT RESERVED" }, + { BM_MEM_RAMSTAGE, "RAMSTAGE" }, + { BM_MEM_PAYLOAD, "PAYLOAD" }, + { BM_MEM_TAG, "TAG STORAGE" }, +}; + +static const char *bootmem_range_string(const enum bootmem_type tag) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(type_strings); i++) { + if (type_strings[i].tag == tag) + return type_strings[i].str; + } + + return "UNKNOWN!"; +} static int bootmem_is_initialized(void) { @@ -113,8 +144,7 @@ void bootmem_add_range(uint64_t start, uint64_t size, int bootmem_add_range_from(uint64_t start, uint64_t size, const enum bootmem_type new_tag, const enum bootmem_type from_tag) { - if (new_tag == from_tag) - return -1; + assert(new_tag != from_tag); if (!bootmem_region_targets_type(start, size, from_tag)) { printk(BIOS_ERR, "%s: Failed to add the range [%#llx, %#llx)" @@ -150,39 +180,6 @@ void bootmem_write_memory_table(struct lb_memory *mem) table_written = 1; } -struct range_strings { - enum bootmem_type tag; - const char *str; -}; - -static const struct range_strings type_strings[] = { - { BM_MEM_RAM, "RAM" }, - { BM_MEM_RESERVED, "RESERVED" }, - { BM_MEM_ACPI, "ACPI" }, - { BM_MEM_NVS, "NVS" }, - { BM_MEM_UNUSABLE, "UNUSABLE" }, - { BM_MEM_VENDOR_RSVD, "VENDOR RESERVED" }, - { BM_MEM_BL31, "BL31" }, - { BM_MEM_OPENSBI, "OPENSBI" }, - { BM_MEM_TABLE, "CONFIGURATION TABLES" }, - { BM_MEM_SOFT_RESERVED, "SOFT RESERVED" }, - { BM_MEM_RAMSTAGE, "RAMSTAGE" }, - { BM_MEM_PAYLOAD, "PAYLOAD" }, - { BM_MEM_TAG, "TAG STORAGE" }, -}; - -static const char *bootmem_range_string(const enum bootmem_type tag) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(type_strings); i++) { - if (type_strings[i].tag == tag) - return type_strings[i].str; - } - - return "UNKNOWN!"; -} - void bootmem_dump_ranges(void) { int i; diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index 0c47359260b..25a29a28855 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -137,6 +137,9 @@ static inline bool cbfs_lz4_enabled(void) if (ENV_SMM) return false; + if (ENV_RAMSTAGE_LOADER && !CONFIG(COMPRESS_RAMSTAGE_LZ4)) + return false; + return true; } @@ -150,17 +153,18 @@ static inline bool cbfs_lzma_enabled(void) /* Payload loader (ramstage) always needs LZMA. */ if (ENV_PAYLOAD_LOADER) return true; - /* Only other use of LZMA is ramstage compression. */ - if (!CONFIG(COMPRESS_RAMSTAGE_LZMA)) - return false; - /* If there is a postcar, it loads the ramstage. */ - if (CONFIG(POSTCAR_STAGE)) - return ENV_POSTCAR; - /* If there is no postcar but a separate romstage, it loads the ramstage. */ - if (CONFIG(SEPARATE_ROMSTAGE)) - return ENV_SEPARATE_ROMSTAGE; - /* Otherwise, the combined bootblock+romstage loads the ramstage. */ - return ENV_BOOTBLOCK; + if (ENV_RAMSTAGE_LOADER && CONFIG(COMPRESS_RAMSTAGE_LZMA)) + return true; + return false; +} + +static inline bool cbfs_zstd_enabled(void) +{ + if (ENV_PAYLOAD_LOADER && CONFIG(COMPRESSED_PAYLOAD_ZSTD)) + return true; + if (ENV_RAMSTAGE_LOADER && CONFIG(COMPRESS_RAMSTAGE_ZSTD)) + return true; + return false; } static bool cbfs_file_hash_mismatch(const void *buffer, size_t size, @@ -172,7 +176,12 @@ static bool cbfs_file_hash_mismatch(const void *buffer, size_t size, const struct vb2_hash *hash = NULL; - if (CONFIG(CBFS_VERIFICATION) && !skip_verification) { + /* + * Skipping this block in SMM because vboot library isn't linked to SMM stage. This is + * an issue only if using a CMOS options backend, then SMM refers to an option and tries + * to verify cmos.layout here. + */ + if (CONFIG(CBFS_VERIFICATION) && !ENV_SMM && !skip_verification) { hash = cbfs_file_hash(mdata); if (!hash) { ERROR("'%s' does not have a file hash!\n", mdata->h.filename); @@ -275,6 +284,24 @@ static size_t cbfs_load_and_decompress(const struct region_device *rdev, void *b rdev_munmap(rdev, map); + return out_size; + case CBFS_COMPRESS_ZSTD: + if (!cbfs_zstd_enabled()) + return 0; + + map = rdev_mmap_full(rdev); + if (map == NULL) + return 0; + + if (!cbfs_file_hash_mismatch(map, in_size, mdata, skip_verification)) { + /* Note: timestamp not useful for memory-mapped media (x86) */ + timestamp_add_now(TS_UZSTDF_START); + out_size = uzstdn(map, in_size, buffer, buffer_size); + timestamp_add_now(TS_UZSTDF_END); + } + + rdev_munmap(rdev, map); + return out_size; default: @@ -527,7 +554,8 @@ void *_cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg, } void *_cbfs_unverified_area_alloc(const char *area, const char *name, - cbfs_allocator_t allocator, void *arg, size_t *size_out) + cbfs_allocator_t allocator, void *arg, size_t *size_out, + enum cbfs_type *type) { struct region_device area_rdev, file_rdev; union cbfs_mdata mdata; @@ -543,6 +571,17 @@ void *_cbfs_unverified_area_alloc(const char *area, const char *name, return NULL; } + if (type) { + const enum cbfs_type real_type = be32toh(mdata.h.type); + if (*type == CBFS_TYPE_QUERY) + *type = real_type; + else if (*type != real_type) { + ERROR("'%s' type mismatch (is %u, expected %u)\n", + mdata.h.filename, real_type, *type); + return NULL; + } + } + if (rdev_chain(&file_rdev, &area_rdev, data_offset, be32toh(mdata.h.len))) return NULL; diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c index d8ecdce868e..5aa0e92d155 100644 --- a/src/lib/coreboot_table.c +++ b/src/lib/coreboot_table.c @@ -29,11 +29,6 @@ #if CONFIG(USE_OPTION_TABLE) #include #endif -#if CONFIG(PLATFORM_USES_FSP2_0) -#include -#else -void lb_string_platform_blob_version(struct lb_header *header); -#endif __weak enum cb_err fill_lb_pcie(struct lb_pcie *pcie) { @@ -142,13 +137,13 @@ static void lb_pcie(struct lb_header *header) static void lb_framebuffer(struct lb_header *header) { struct lb_framebuffer *framebuffer; - struct lb_framebuffer fb = {0}; + const struct lb_framebuffer *fb; - if (!CONFIG(LINEAR_FRAMEBUFFER) || fill_lb_framebuffer(&fb)) + if (!CONFIG(LINEAR_FRAMEBUFFER) || !(fb = get_lb_framebuffer())) return; framebuffer = (struct lb_framebuffer *)lb_new_record(header); - memcpy(framebuffer, &fb, sizeof(*framebuffer)); + memcpy(framebuffer, fb, sizeof(*framebuffer)); framebuffer->tag = LB_TAG_FRAMEBUFFER; framebuffer->size = sizeof(*framebuffer); @@ -274,6 +269,7 @@ static void add_cbmem_pointers(struct lb_header *header) {CBMEM_ID_FMAP, LB_TAG_FMAP}, {CBMEM_ID_VBOOT_WORKBUF, LB_TAG_VBOOT_WORKBUF}, {CBMEM_ID_TYPE_C_INFO, LB_TAG_TYPE_C_INFO}, + {CBMEM_ID_RB_INFO, LB_TAG_ROOT_BRIDGE_INFO}, }; int i; diff --git a/src/lib/devtree_update.c b/src/lib/devtree_update.c new file mode 100644 index 00000000000..1b454a25809 --- /dev/null +++ b/src/lib/devtree_update.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +__weak void devtree_update(void) +{ +} + +static void run_devtree_update(void *unused) +{ + devtree_update(); +} + +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, run_devtree_update, NULL); diff --git a/src/lib/dimm_info_util.c b/src/lib/dimm_info_util.c index d16cb46d0a0..6ca707c5428 100644 --- a/src/lib/dimm_info_util.c +++ b/src/lib/dimm_info_util.c @@ -45,6 +45,13 @@ uint8_t smbios_bus_width_to_spd_width(uint8_t ddr_type, uint16_t total_width, else out |= SPD_ECC_8BIT; break; + case 16: + if (ddr_type == MEMORY_TYPE_DDR5 || ddr_type == MEMORY_TYPE_LPDDR5) + out |= SPD_ECC_8BIT_LP5_DDR5; + else + printk(BIOS_NOTICE, "Unknown number of extension bits %hu\n", + extension_bits); + break; case 0: /* No extension bits */ break; diff --git a/src/lib/fit.c b/src/lib/fit.c index 3bfca57aab0..1942cb30406 100644 --- a/src/lib/fit.c +++ b/src/lib/fit.c @@ -396,7 +396,7 @@ static int fit_update_compat(struct fit_config_node *config) } /* FDT overlays are not supported in legacy FIT images. */ - if (config->overlays.next) { + if (!list_is_empty(&config->overlays)) { printk(BIOS_ERR, "config %s has overlay but no compat!\n", config->name); return -1; diff --git a/src/lib/fonts/font_table_google_sans_flex_medium_24x32.c b/src/lib/fonts/font_table_google_sans_flex_medium_24x32.c new file mode 100644 index 00000000000..421292e171f --- /dev/null +++ b/src/lib/fonts/font_table_google_sans_flex_medium_24x32.c @@ -0,0 +1,9426 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + * Source: GoogleSansFlex_24pt-Medium.ttf + * Command: python generate_font.py GoogleSansFlex_24pt-Medium.ttf --width 24 --height 32 + */ + +#include + +#define FONT_WIDTH 24 +#define FONT_HEIGHT 32 +#define FONT_START_CHAR 32 +#define FONT_END_CHAR 126 +#define FONT_NUM_CHARS (FONT_END_CHAR - FONT_START_CHAR + 1) + +const uint8_t font_table[FONT_NUM_CHARS][FONT_HEIGHT * FONT_WIDTH] = { + [0x20 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* ' ' */ + [0x21 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0f, 0x30, 0x30, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4c, 0xff, 0xff, 0x57, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x46, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0xff, 0xff, 0x4a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x39, 0xff, 0xff, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x32, 0xff, 0xff, 0x3b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2d, 0xff, 0xff, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x26, 0xff, 0xff, 0x2e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0xff, 0xff, 0x26, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1a, 0xff, 0xff, 0x1f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xff, 0xff, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0xff, 0xff, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0xe0, 0xe0, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x13, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x57, 0xfb, 0xfc, 0x5f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb9, 0xff, 0xff, 0xc0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x69, 0xff, 0xff, 0x71, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2b, 0x2c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '!' */ + [0x22 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x21, 0x30, 0x1a, 0x00, 0x2c, 0x30, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xff, 0x88, 0x00, 0xe8, 0xff, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xff, 0x88, 0x00, 0xe8, 0xff, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xff, 0x88, 0x00, 0xe8, 0xff, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xff, 0x88, 0x00, 0xe8, 0xff, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xff, 0x88, 0x00, 0xe8, 0xff, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xff, 0x88, 0x00, 0xe8, 0xff, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x04, 0x02, 0x00, 0x04, 0x04, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '"' */ + [0x23 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x17, + 0x00, 0x00, 0x13, 0x30, 0x23, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0xff, 0x67, + 0x00, 0x00, 0x79, 0xff, 0xa6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xda, 0xff, 0x42, + 0x00, 0x00, 0x9e, 0xff, 0x82, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0xfb, 0xff, 0x1d, + 0x00, 0x00, 0xc2, 0xff, 0x5d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x23, 0xff, 0xf7, 0x02, + 0x00, 0x00, 0xe7, 0xff, 0x37, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x34, 0x34, 0x6d, 0xff, 0xe0, 0x34, + 0x34, 0x3d, 0xff, 0xff, 0x46, 0x34, 0x34, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6d, 0xd4, 0xd4, 0xf2, 0xff, 0xea, 0xd4, + 0xd4, 0xe8, 0xff, 0xf5, 0xd4, 0xd4, 0xac, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb7, 0xff, 0x65, 0x00, + 0x00, 0x79, 0xff, 0xa3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xdb, 0xff, 0x41, 0x00, + 0x00, 0x9e, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0xfc, 0xff, 0x1b, 0x00, + 0x00, 0xc2, 0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0xac, 0xac, 0xb7, 0xff, 0xff, 0xad, 0xac, + 0xac, 0xf6, 0xff, 0xc2, 0xac, 0xac, 0x2a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x5c, 0x5c, 0xaa, 0xff, 0xc9, 0x5c, 0x5c, + 0x81, 0xff, 0xf0, 0x5c, 0x5c, 0x5c, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x93, 0xff, 0x89, 0x00, 0x00, + 0x55, 0xff, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb9, 0xff, 0x64, 0x00, 0x00, + 0x79, 0xff, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xdd, 0xff, 0x3f, 0x00, 0x00, + 0x9d, 0xff, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0xfc, 0xff, 0x1a, 0x00, 0x00, + 0xc2, 0xff, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '#' */ + [0x24 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x2c, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xff, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa1, 0xff, + 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2c, 0xb2, 0xfa, 0xff, 0xff, + 0xff, 0xda, 0x67, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0xf6, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xa7, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0xe2, 0xff, 0xeb, 0x57, 0x9f, 0xff, + 0x6c, 0xbc, 0xff, 0xff, 0x6f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0xff, 0xff, 0x5b, 0x00, 0x90, 0xff, + 0x38, 0x04, 0xb5, 0x9c, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x4c, 0xff, 0xff, 0x47, 0x00, 0x90, 0xff, + 0x38, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x21, 0xff, 0xff, 0xbd, 0x08, 0x90, 0xff, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xab, 0xff, 0xff, 0xdf, 0xcd, 0xff, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xb7, 0xff, 0xff, 0xff, 0xff, + 0xc9, 0x62, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4f, 0xbf, 0xff, 0xff, + 0xff, 0xff, 0xde, 0x3d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0xff, + 0xe8, 0xff, 0xff, 0xf8, 0x35, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0xff, + 0x39, 0x65, 0xfc, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0x1c, 0x00, 0x00, 0x94, 0xff, + 0x38, 0x00, 0x9f, 0xff, 0xfd, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x79, 0xf2, 0xa5, 0x00, 0x00, 0x94, 0xff, + 0x38, 0x00, 0x81, 0xff, 0xff, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x9b, 0xff, 0xff, 0x57, 0x00, 0x94, 0xff, + 0x38, 0x08, 0xd3, 0xff, 0xdf, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1b, 0xec, 0xff, 0xfe, 0x9e, 0xbb, 0xff, + 0x88, 0xcb, 0xff, 0xff, 0x75, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x36, 0xea, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xa2, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x14, 0x85, 0xd3, 0xfc, 0xff, + 0xeb, 0xb2, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0xff, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0xfc, + 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '$' */ + [0x25 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x54, 0xcb, 0xf8, 0xe9, 0x9a, 0x16, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x66, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xff, 0xff, 0xf5, 0xfd, 0xff, 0xdc, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc8, 0xff, + 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1d, 0xfa, 0xfe, 0x60, 0x02, 0x18, 0xc5, 0xff, + 0x97, 0x00, 0x00, 0x00, 0x00, 0x75, 0xff, 0xdb, + 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x63, 0xff, 0xbb, 0x00, 0x00, 0x00, 0x39, 0xff, + 0xe2, 0x00, 0x00, 0x00, 0x28, 0xf8, 0xfe, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0xff, 0xa7, 0x00, 0x00, 0x00, 0x25, 0xff, + 0xee, 0x00, 0x00, 0x03, 0xc9, 0xff, 0x8e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3e, 0xff, 0xf0, 0x1d, 0x00, 0x00, 0x82, 0xff, + 0xbe, 0x00, 0x00, 0x7a, 0xff, 0xd8, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xbe, 0xff, 0xe7, 0x93, 0xaf, 0xff, 0xfd, + 0x42, 0x00, 0x2c, 0xf9, 0xfd, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x12, 0xb9, 0xff, 0xff, 0xff, 0xf1, 0x5a, + 0x00, 0x04, 0xcc, 0xff, 0x8b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x32, 0x60, 0x50, 0x10, 0x00, + 0x00, 0x7c, 0xff, 0xd6, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2e, 0xfa, 0xfc, 0x34, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, + 0xce, 0xff, 0x85, 0x00, 0x08, 0x81, 0xe0, 0xf8, + 0xd8, 0x71, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, + 0xff, 0xd3, 0x07, 0x04, 0xbc, 0xff, 0xff, 0xf2, + 0xff, 0xff, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xfb, + 0xfb, 0x33, 0x00, 0x68, 0xff, 0xe4, 0x2e, 0x00, + 0x3d, 0xf1, 0xff, 0x46, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xd1, 0xff, + 0x83, 0x00, 0x00, 0xb3, 0xff, 0x6b, 0x00, 0x00, + 0x00, 0x89, 0xff, 0x93, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xff, 0xd0, + 0x06, 0x00, 0x00, 0xc0, 0xff, 0x57, 0x00, 0x00, + 0x00, 0x75, 0xff, 0x9e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x33, 0xfb, 0xfa, 0x30, + 0x00, 0x00, 0x00, 0x8f, 0xff, 0xbb, 0x03, 0x00, + 0x06, 0xcb, 0xff, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xd3, 0xff, 0x7e, 0x00, + 0x00, 0x00, 0x00, 0x1e, 0xf0, 0xff, 0xc9, 0x8e, + 0xd2, 0xff, 0xe1, 0x0d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x36, 0xf4, 0xce, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0xe2, 0xff, 0xff, + 0xff, 0xd3, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x22, 0x28, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x48, 0x62, + 0x3e, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '%' */ + [0x26 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x7a, 0x8e, + 0x74, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x9e, 0xff, 0xff, 0xff, + 0xff, 0xfb, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x72, 0xff, 0xff, 0xec, 0xb6, + 0xeb, 0xff, 0xfd, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xcc, 0xff, 0xed, 0x14, 0x00, + 0x18, 0xeb, 0xf0, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xdc, 0xff, 0xc7, 0x00, 0x00, + 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa6, 0xff, 0xf8, 0x1c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2c, 0xfa, 0xff, 0xc4, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x21, 0xd8, 0xff, 0xff, 0x96, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x34, 0xed, 0xff, 0xff, 0xff, 0xff, + 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x11, 0xe7, 0xff, 0xf2, 0x5e, 0xd0, 0xff, + 0xf9, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xff, 0xff, 0x54, 0x00, 0x22, 0xee, + 0xff, 0xe5, 0x18, 0x00, 0x00, 0x2f, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xcc, 0xff, 0xe2, 0x01, 0x00, 0x00, 0x48, + 0xfd, 0xff, 0xc4, 0x06, 0x11, 0xf8, 0xd9, 0x2d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe6, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, + 0x79, 0xff, 0xff, 0x96, 0x7b, 0xff, 0xf3, 0x0d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0xff, 0xde, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xaf, 0xff, 0xff, 0xfb, 0xff, 0x8c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa3, 0xff, 0xff, 0x4d, 0x00, 0x00, 0x00, + 0x00, 0x0d, 0xd7, 0xff, 0xff, 0xeb, 0x13, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3b, 0xff, 0xff, 0xf3, 0x64, 0x0c, 0x00, + 0x08, 0x53, 0xdf, 0xff, 0xff, 0xe9, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x84, 0xff, 0xff, 0xff, 0xfe, 0xf0, + 0xfc, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xc4, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x62, 0xe4, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xbc, 0x2f, 0x87, 0xfc, 0x75, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x58, 0x61, + 0x4f, 0x1c, 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '&' */ + [0x27 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x21, 0x30, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb0, 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '\'' */ + [0x28 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0xe5, 0xbf, 0x27, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xff, 0x53, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3e, 0xff, 0xff, 0xac, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc5, 0xff, 0xf4, 0x1b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0xff, 0xff, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa6, 0xff, 0xf9, 0x16, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xf4, 0xff, 0xaf, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xff, 0xff, 0x61, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x74, 0xff, 0xff, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x94, 0xff, 0xfe, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa4, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa4, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x94, 0xff, 0xfe, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x71, 0xff, 0xff, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xff, 0xff, 0x62, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xf3, 0xff, 0xb0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa4, 0xff, 0xfb, 0x19, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0xff, 0xff, 0x8d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc4, 0xff, 0xf7, 0x1f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3a, 0xff, 0xff, 0xb0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0x56, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xe2, 0xb7, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '(' */ + [0x29 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x14, 0xa2, 0xf7, 0x2b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2c, 0xf9, 0xff, 0xcc, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0xff, 0xff, 0x6b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xdd, 0xff, 0xe8, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5c, 0xff, 0xff, 0x6c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xe0, 0xff, 0xd4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x83, 0xff, 0xff, 0x29, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x34, 0xff, 0xff, 0x6d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xf8, 0xff, 0x9f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd5, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc4, 0xff, 0xd0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc4, 0xff, 0xd0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd8, 0xff, 0xbf, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0xf9, 0xff, 0x9d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x37, 0xff, 0xff, 0x69, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x85, 0xff, 0xff, 0x26, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xe3, 0xff, 0xce, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0xff, 0xff, 0x66, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x09, 0xdf, 0xff, 0xe7, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x32, 0xfb, 0xff, 0xc8, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x9c, 0xf5, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* ')' */ + [0x2a - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7f, 0xb4, 0x31, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xae, 0xff, 0x42, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x69, 0x2f, 0x00, 0xa8, 0xff, 0x3d, 0x07, + 0x59, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x14, 0xfb, 0xff, 0xca, 0xd5, 0xff, 0xb2, 0xec, + 0xff, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x86, 0xd2, 0xff, 0xff, 0xff, 0xff, 0xf6, + 0xae, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x81, 0xff, 0xff, 0xf8, 0x23, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x36, 0xf9, 0xf5, 0xa4, 0xff, 0xc2, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x16, 0xe3, 0xff, 0x6a, 0x07, 0xd3, 0xff, + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x93, 0xb9, 0x01, 0x00, 0x2f, 0xe1, + 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '*' */ + [0x2b - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xf8, 0xf8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0x9c, 0x9c, 0x9c, 0xc1, 0xff, 0xff, + 0x9c, 0x9c, 0x9c, 0x9c, 0x25, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x90, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5f, 0xa8, 0xa8, 0xa8, 0xca, 0xff, 0xff, + 0xa8, 0xa8, 0xa8, 0xa8, 0x27, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '+' */ + [0x2c - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x46, 0x4a, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0xff, 0xff, 0x89, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbd, 0xff, 0xff, 0xc9, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x49, 0xf1, 0xff, 0x81, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1d, 0xef, 0xdb, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0xc0, 0xfd, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x56, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* ',' */ + [0x2d - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x94, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x94, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x15, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '-' */ + [0x2e - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x4a, 0x4e, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x81, 0xff, 0xff, 0x89, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc1, 0xff, 0xff, 0xc9, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xfb, 0xfd, 0x61, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '.' */ + [0x2f - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x26, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xff, 0x9e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x15, 0xfd, 0xff, 0x4e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x63, 0xff, 0xf5, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb2, 0xff, 0xae, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0b, 0xf7, 0xff, 0x5e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x52, 0xff, 0xfc, 0x12, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa3, 0xff, 0xbe, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xee, 0xff, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0xff, 0xff, 0x21, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x92, 0xff, 0xd2, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xe3, 0xff, 0x82, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x32, 0xff, 0xff, 0x32, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x83, 0xff, 0xe1, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd5, 0xff, 0x92, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x26, 0xff, 0xff, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x75, 0xff, 0xee, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc5, 0xff, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '/' */ + [0x30 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x6e, 0x8d, + 0x83, 0x52, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0x9b, 0xfe, 0xff, 0xff, + 0xff, 0xff, 0xe6, 0x4b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xb8, 0xff, 0xff, 0xff, 0xf3, + 0xfa, 0xff, 0xff, 0xfc, 0x4e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xff, 0xff, 0xc4, 0x2b, 0x00, + 0x07, 0x64, 0xf6, 0xff, 0xef, 0x17, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0b, 0xef, 0xff, 0xe0, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x5b, 0xff, 0xff, 0x8b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x59, 0xff, 0xff, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd2, 0xff, 0xe9, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x9b, 0xff, 0xff, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x2e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0xff, 0xe1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4d, 0xff, 0xff, 0x58, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xdd, 0xff, 0xc7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x34, 0xff, 0xff, 0x70, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe3, 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2d, 0xff, 0xff, 0x76, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd9, 0xff, 0xcb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x37, 0xff, 0xff, 0x6d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbf, 0xff, 0xe9, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x55, 0xff, 0xff, 0x52, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x8f, 0xff, 0xff, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x8d, 0xff, 0xff, 0x23, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x49, 0xff, 0xff, 0x79, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xe2, 0xff, 0xdb, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0xe0, 0xff, 0xef, 0x1e, 0x00, 0x00, + 0x00, 0x00, 0x7b, 0xff, 0xff, 0x76, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x57, 0xff, 0xff, 0xe2, 0x57, 0x1f, + 0x2d, 0x91, 0xff, 0xff, 0xdd, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x93, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf1, 0x32, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x6f, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xc2, 0x2a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x41, 0x61, + 0x57, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '0' */ + [0x31 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x30, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x6c, 0xf7, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x17, 0xb5, 0xff, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x4b, 0xe9, 0xff, 0xff, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0xfd, 0xff, 0xf6, 0xad, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x89, 0xce, 0x29, 0x54, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x07, 0x00, 0x54, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '1' */ + [0x32 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x4c, 0x80, 0x8e, 0x79, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2f, 0xd8, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb9, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1f, 0xed, 0xff, 0xff, 0xfa, 0xee, 0xff, + 0xff, 0xff, 0xcb, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa7, 0xff, 0xff, 0x88, 0x0b, 0x00, 0x26, + 0xce, 0xff, 0xff, 0x59, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x71, 0xe5, 0xa8, 0x00, 0x00, 0x00, 0x00, + 0x32, 0xff, 0xff, 0x9b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x0a, 0xff, 0xff, 0xa8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x31, 0xff, 0xff, 0x85, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa3, 0xff, 0xff, 0x31, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0xff, 0xff, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0xf7, + 0xff, 0xe5, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xf0, 0xff, + 0xf1, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x25, 0xe9, 0xff, 0xf5, + 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1d, 0xe1, 0xff, 0xf8, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x15, 0xd8, 0xff, 0xfb, 0x4c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0xcd, 0xff, 0xfd, 0x56, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbd, 0xff, 0xff, 0xbc, 0x64, 0x64, 0x64, + 0x64, 0x64, 0x64, 0x58, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '2' */ + [0x33 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x42, 0x7e, 0x8e, 0x7b, + 0x42, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0xc7, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xcd, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0xdb, 0xff, 0xff, 0xeb, 0xd2, 0xf8, + 0xff, 0xff, 0xd8, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x8e, 0xff, 0xff, 0x7e, 0x03, 0x00, 0x12, + 0xbe, 0xff, 0xff, 0x58, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x26, 0xa5, 0xaf, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0xff, 0xff, 0x88, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0xff, 0xff, 0x85, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x51, 0xff, 0xff, 0x52, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x14, 0x5c, + 0xed, 0xff, 0xcc, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x44, 0xff, 0xff, 0xff, + 0xff, 0xab, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x44, 0xff, 0xff, 0xff, + 0xff, 0xe9, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x20, 0x26, 0x55, + 0xd4, 0xff, 0xff, 0x4d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0xe5, 0xff, 0xd3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x95, 0xff, 0xff, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3a, 0xa0, 0x43, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x92, 0xff, 0xff, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0xf6, 0xff, 0xca, 0x05, 0x00, 0x00, 0x00, + 0x09, 0xdf, 0xff, 0xf3, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x8f, 0xff, 0xff, 0xb1, 0x21, 0x01, 0x29, + 0xba, 0xff, 0xff, 0x98, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xd0, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xd5, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0xa6, 0xfe, 0xff, 0xff, 0xff, + 0xfd, 0xa4, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1c, 0x53, 0x62, 0x4e, + 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '3' */ + [0x34 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x30, 0x30, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0xcc, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + 0xff, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0xf9, + 0xff, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xcd, 0xff, + 0xcd, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0xff, 0xf0, + 0x33, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2e, 0xfa, 0xff, 0x5f, + 0x18, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0xcf, 0xff, 0xb0, 0x00, + 0x18, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xff, 0xed, 0x18, 0x00, + 0x18, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x31, 0xfb, 0xff, 0x59, 0x00, 0x00, + 0x18, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0xd2, 0xff, 0xad, 0x00, 0x00, 0x00, + 0x18, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x83, 0xff, 0xeb, 0x17, 0x00, 0x00, 0x00, + 0x18, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0xfc, 0xff, 0xf6, 0xe4, 0xe4, 0xe4, 0xe4, + 0xea, 0xff, 0xff, 0xf6, 0xec, 0x51, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x58, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x8e, 0xff, 0xff, 0xac, 0x70, 0x27, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '4' */ + [0x35 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x90, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb0, 0xff, 0xb5, 0x34, 0x34, 0x34, + 0x34, 0x34, 0x34, 0x1d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd0, 0xff, 0x84, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0xff, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0xff, 0xff, 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0xff, 0xff, 0x43, 0x9a, 0xdc, 0xed, + 0xd3, 0x84, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xde, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0xf8, 0x8f, 0x5a, 0x69, + 0xc4, 0xff, 0xff, 0xcf, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x25, 0x8b, 0x3b, 0x00, 0x00, 0x00, + 0x02, 0xa6, 0xff, 0xff, 0x4f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1f, 0xff, 0xff, 0x92, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf5, 0xff, 0xa9, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x59, 0xbe, 0x82, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0xff, 0xff, 0x9b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd3, 0xff, 0xf2, 0x1f, 0x00, 0x00, 0x00, + 0x00, 0x79, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5a, 0xff, 0xff, 0xd8, 0x46, 0x0e, 0x1e, + 0x7f, 0xfd, 0xff, 0xe7, 0x0b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf8, 0x41, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x79, 0xf2, 0xff, 0xff, 0xff, + 0xff, 0xcf, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0b, 0x45, 0x61, 0x5a, + 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '5' */ + [0x36 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xda, + 0xff, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0xff, + 0xff, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0xff, 0xff, + 0xc1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x21, 0xf1, 0xff, 0xed, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0xc5, 0xff, 0xff, 0x4e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0xff, 0xff, 0x92, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2d, 0xfa, 0xff, 0xff, 0xd7, 0xec, + 0xdf, 0x9d, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf8, 0x52, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x4d, 0xff, 0xff, 0xfd, 0x99, 0x51, 0x52, + 0x9c, 0xfe, 0xff, 0xf8, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb5, 0xff, 0xff, 0x55, 0x00, 0x00, 0x00, + 0x00, 0x63, 0xff, 0xff, 0x9d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xff, 0xc5, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd7, 0xff, 0xde, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0xff, 0xff, 0x9a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xae, 0xff, 0xf2, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf3, 0xff, 0xb5, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc8, 0xff, 0xde, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xba, 0xff, 0xfb, 0x2f, 0x00, 0x00, 0x00, + 0x00, 0x3a, 0xff, 0xff, 0x9d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x46, 0xff, 0xff, 0xea, 0x5f, 0x18, 0x19, + 0x62, 0xee, 0xff, 0xfb, 0x2b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x8c, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x67, 0xe9, 0xff, 0xff, 0xff, + 0xff, 0xdb, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x3a, 0x5b, 0x59, + 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '6' */ + [0x37 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x1d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x98, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x98, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x15, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, + 0x7a, 0xff, 0xff, 0x75, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0xce, 0xff, 0xe9, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, + 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xde, + 0xff, 0xe2, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0xff, + 0xff, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xeb, 0xff, + 0xdb, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xff, 0xff, + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x17, 0xf4, 0xff, 0xd3, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x96, 0xff, 0xff, 0x4f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x25, 0xfb, 0xff, 0xc9, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa9, 0xff, 0xff, 0x44, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x35, 0xff, 0xff, 0xbf, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xbe, 0xff, 0xff, 0x3a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x47, 0xff, 0xff, 0xb4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3b, 0xcc, 0xff, 0x31, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '7' */ + [0x38 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x23, 0x6e, 0x8d, 0x83, + 0x52, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x8f, 0xfd, 0xff, 0xff, 0xff, + 0xff, 0xe2, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x8d, 0xff, 0xff, 0xf9, 0xcd, 0xdf, + 0xff, 0xff, 0xf4, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1a, 0xfc, 0xff, 0xd1, 0x1b, 0x00, 0x00, + 0x5e, 0xfe, 0xff, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x54, 0xff, 0xff, 0x43, 0x00, 0x00, 0x00, + 0x00, 0xb7, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5f, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x96, 0xff, 0xea, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, + 0x02, 0xd2, 0xff, 0xbb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb0, 0xff, 0xef, 0x56, 0x0d, 0x1f, + 0xa2, 0xff, 0xfd, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0b, 0xae, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf1, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0xd3, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfa, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x23, 0xf0, 0xff, 0xdd, 0x59, 0x24, 0x31, + 0x8f, 0xfe, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa7, 0xff, 0xf1, 0x1a, 0x00, 0x00, 0x00, + 0x00, 0x83, 0xff, 0xff, 0x32, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xec, 0xff, 0xa7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1e, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x12, 0xff, 0xff, 0x88, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xdb, 0xff, 0xe8, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x62, 0xff, 0xff, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x81, 0xff, 0xff, 0xc4, 0x2d, 0x00, 0x08, + 0x60, 0xf5, 0xff, 0xf6, 0x17, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x09, 0xc8, 0xff, 0xff, 0xff, 0xf6, 0xfd, + 0xff, 0xff, 0xff, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x95, 0xf9, 0xff, 0xff, 0xff, + 0xff, 0xdb, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x49, 0x61, 0x5a, + 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '8' */ + [0x39 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2d, 0x71, 0x8d, 0x83, + 0x55, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xaf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xed, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0d, 0xd3, 0xff, 0xff, 0xfe, 0xe6, 0xf5, + 0xff, 0xff, 0xff, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x90, 0xff, 0xff, 0xa6, 0x17, 0x00, 0x04, + 0x5b, 0xf4, 0xff, 0xf5, 0x19, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0xf5, 0xff, 0xc8, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0xff, 0xff, 0x73, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0xff, 0xff, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0xf6, 0xff, 0xa7, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xec, 0xff, 0xb1, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x27, 0xff, 0xff, 0x98, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0xff, 0xff, 0x95, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xdb, 0xff, 0xf9, 0x42, 0x00, 0x00, 0x00, + 0x0d, 0xc3, 0xff, 0xff, 0x51, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0xff, 0xff, 0xfc, 0xaa, 0x7a, 0x8e, + 0xe6, 0xff, 0xff, 0xe0, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x69, 0xfa, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x59, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x26, 0x8a, 0xb9, 0xb9, 0xd1, + 0xff, 0xff, 0xbb, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xed, + 0xff, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc1, 0xff, + 0xff, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, + 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfd, 0xff, 0xda, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x13, 0xe4, 0xff, 0xfa, 0x32, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0e, 0x9e, 0xff, 0x73, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '9' */ + [0x3a - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x46, 0x4a, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xff, 0xff, 0x88, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc1, 0xff, 0xff, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xfd, 0xfe, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x1a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x4a, 0x4e, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x82, 0xff, 0xff, 0x89, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc1, 0xff, 0xff, 0xc9, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0xfb, 0xfd, 0x61, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* ':' */ + [0x3b - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2f, 0x56, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xfd, 0xff, 0xc9, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7d, 0xff, 0xff, 0xff, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2a, 0xef, 0xff, 0xa7, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x46, 0x4a, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0xff, 0xff, 0x89, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbd, 0xff, 0xff, 0xc9, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x49, 0xf1, 0xff, 0x81, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1d, 0xef, 0xd9, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0xc0, 0xfc, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* ';' */ + [0x3c - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x39, 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, + 0x62, 0xcd, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x8d, 0xef, + 0xff, 0xff, 0xf9, 0xa7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x4c, 0xb7, 0xfe, 0xff, 0xff, + 0xd4, 0x71, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x49, 0xde, 0xff, 0xff, 0xf4, 0x9c, 0x3a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xb9, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x52, 0xea, 0xff, 0xff, 0xed, 0x90, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x5c, 0xc7, 0xff, 0xff, 0xff, + 0xcc, 0x6c, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x9e, 0xf6, + 0xff, 0xff, 0xf8, 0xa6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x73, 0xdc, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x49, 0xb0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '<' */ + [0x3d - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, + 0x9c, 0x9c, 0x9c, 0x9c, 0x25, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x90, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5f, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, + 0xa8, 0xa8, 0xa8, 0xa8, 0x27, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, + 0x9c, 0x9c, 0x9c, 0x9c, 0x25, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x90, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5f, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, + 0xa8, 0xa8, 0xa8, 0xa8, 0x27, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '=' */ + [0x3e - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3e, 0x81, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0xff, 0xfb, 0xaa, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2e, 0xd4, 0xff, 0xff, 0xff, 0xd4, 0x68, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x37, 0x99, 0xf2, 0xff, 0xff, + 0xf1, 0x93, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x5f, 0xc1, + 0xff, 0xff, 0xff, 0xbc, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3d, 0xe6, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x4c, 0xb0, + 0xfb, 0xff, 0xff, 0xcc, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x22, 0x84, 0xe5, 0xff, 0xff, + 0xf8, 0xa2, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x27, 0xbd, 0xff, 0xff, 0xff, 0xe1, 0x79, + 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0xff, 0xff, 0xbb, 0x4f, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x43, 0x91, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '>' */ + [0x3f - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0b, 0x5b, 0x8d, 0x93, 0x75, + 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4a, 0xeb, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0x92, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3b, 0xfa, 0xff, 0xff, 0xe3, 0xda, 0xfe, + 0xff, 0xff, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xd0, 0xff, 0xfc, 0x59, 0x00, 0x00, 0x31, + 0xf0, 0xff, 0xf4, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x68, 0xc2, 0x8a, 0x00, 0x00, 0x00, 0x00, + 0x95, 0xff, 0xff, 0x31, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8e, 0xff, 0xff, 0x2a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, + 0xe9, 0xff, 0xe5, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xd3, + 0xff, 0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0xdc, 0xff, + 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xc3, 0xff, 0xff, + 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2d, 0xff, 0xff, 0xa6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4b, 0xff, 0xff, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x35, 0xb4, 0xb4, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x97, 0xa6, 0x34, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xbc, 0xff, 0xff, 0xef, + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xdc, 0xff, 0xff, 0xff, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0xfd, 0xff, 0x9f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x26, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '?' */ + [0x40 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x57, 0x7f, 0x8d, 0x88, 0x6f, 0x3a, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xb6, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe8, 0x78, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0xfc, 0xff, 0xe5, + 0x8f, 0x59, 0x40, 0x44, 0x65, 0xa9, 0xf9, 0xff, + 0xd2, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7b, 0xff, 0xfa, 0x79, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xba, + 0xff, 0xdf, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0xfe, 0xf9, 0x48, 0x00, 0x00, + 0x00, 0x1f, 0x2c, 0x0a, 0x00, 0x00, 0x00, 0x03, + 0xa6, 0xff, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0xd7, 0xff, 0x6a, 0x00, 0x00, 0x47, + 0xd9, 0xff, 0xff, 0xf7, 0x8c, 0x85, 0xe4, 0x27, + 0x08, 0xd8, 0xff, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x42, 0xff, 0xd4, 0x02, 0x00, 0x47, 0xfc, + 0xff, 0xc8, 0x9f, 0xcd, 0xff, 0xf7, 0xff, 0x2c, + 0x00, 0x58, 0xff, 0x9e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x8b, 0xff, 0x76, 0x00, 0x02, 0xdd, 0xff, + 0x7a, 0x00, 0x00, 0x00, 0x82, 0xff, 0xff, 0x2c, + 0x00, 0x09, 0xfa, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb4, 0xff, 0x3d, 0x00, 0x31, 0xff, 0xe3, + 0x02, 0x00, 0x00, 0x00, 0x03, 0xe4, 0xff, 0x2c, + 0x00, 0x00, 0xd4, 0xff, 0x08, 0x00, 0x00, 0x00, + 0x00, 0xc5, 0xff, 0x27, 0x00, 0x51, 0xff, 0xb7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0xff, 0x2c, + 0x00, 0x00, 0xc3, 0xff, 0x14, 0x00, 0x00, 0x00, + 0x00, 0xbf, 0xff, 0x2f, 0x00, 0x46, 0xff, 0xc7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xff, 0x2c, + 0x00, 0x00, 0xcd, 0xff, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0xa2, 0xff, 0x53, 0x00, 0x12, 0xfa, 0xfd, + 0x2e, 0x00, 0x00, 0x00, 0x33, 0xfe, 0xff, 0x3f, + 0x00, 0x0d, 0xf8, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6b, 0xff, 0x9b, 0x00, 0x00, 0x90, 0xff, + 0xe5, 0x5c, 0x32, 0x63, 0xea, 0xf9, 0xff, 0xc2, + 0x46, 0xac, 0xff, 0x8a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1b, 0xfb, 0xf5, 0x1a, 0x00, 0x06, 0xac, + 0xff, 0xff, 0xff, 0xff, 0xf2, 0x46, 0xc2, 0xff, + 0xff, 0xff, 0xd7, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9c, 0xff, 0xb9, 0x04, 0x00, 0x00, + 0x42, 0x87, 0x94, 0x6d, 0x15, 0x00, 0x09, 0x6b, + 0x96, 0x6f, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0xe0, 0xff, 0xae, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x27, 0xe4, 0xff, 0xe1, 0x67, + 0x13, 0x00, 0x00, 0x00, 0x12, 0x51, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0xb0, 0xff, 0xff, + 0xfe, 0xe1, 0xd2, 0xe1, 0xff, 0xff, 0x3c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x8f, + 0xcc, 0xed, 0xf6, 0xea, 0xc4, 0x85, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '@' */ + [0x41 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x30, + 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xff, + 0xff, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, 0xff, + 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xff, 0xff, + 0xfe, 0xff, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0xff, 0xee, + 0xa0, 0xff, 0xeb, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0xeb, 0xff, 0x9e, + 0x4a, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x51, 0xff, 0xff, 0x45, + 0x06, 0xed, 0xff, 0xb4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb4, 0xff, 0xe6, 0x03, + 0x00, 0x97, 0xff, 0xfc, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0xfc, 0xff, 0x8c, 0x00, + 0x00, 0x3b, 0xff, 0xff, 0x75, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x78, 0xff, 0xff, 0x2e, 0x00, + 0x00, 0x01, 0xde, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xd8, 0xff, 0xd2, 0x00, 0x00, + 0x00, 0x00, 0x83, 0xff, 0xff, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0xff, 0xff, 0xc0, 0x74, 0x74, + 0x74, 0x74, 0x96, 0xff, 0xff, 0x98, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xf4, 0xff, 0xe5, 0xbc, 0xbc, 0xbc, + 0xbc, 0xbc, 0xbc, 0xd1, 0xff, 0xff, 0x5c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x61, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x16, 0xfc, 0xff, 0xbc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc4, 0xff, 0xf4, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb6, 0xff, 0xfe, 0x1e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x25, 0xff, 0xff, 0xa4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5a, 0xff, 0xff, 0x7f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x87, 0xff, 0xff, 0x46, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0a, 0xf4, 0xff, 0xde, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'A' */ + [0x42 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x2f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xcc, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0x5a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x8b, 0x24, 0x24, 0x24, + 0x2c, 0x75, 0xf9, 0xff, 0xf2, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x73, 0xff, 0xff, 0x55, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2b, 0xff, 0xff, 0x68, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x52, 0xff, 0xff, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x2e, 0xe2, 0xff, 0xcf, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xec, 0xd8, 0xd8, 0xd8, + 0xe0, 0xff, 0xff, 0xcb, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xa5, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xa4, 0x50, 0x50, 0x50, + 0x53, 0x7e, 0xee, 0xff, 0xe9, 0x21, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2a, 0xf9, 0xff, 0xad, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb5, 0xff, 0xf5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb6, 0xff, 0xfc, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2b, 0xfa, 0xff, 0xd0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xa0, 0x4c, 0x4c, 0x4c, + 0x4d, 0x76, 0xec, 0xff, 0xff, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x95, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf3, 0xc0, 0x54, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'B' */ + [0x43 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, + 0x75, 0x8c, 0x8a, 0x6a, 0x2d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x7c, 0xec, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xcd, 0x44, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1c, 0xd1, 0xff, 0xff, 0xff, + 0xff, 0xf6, 0xfa, 0xff, 0xff, 0xff, 0xff, 0x82, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xdd, 0xff, 0xff, 0xda, 0x61, + 0x16, 0x00, 0x01, 0x26, 0x82, 0xf4, 0xff, 0xf7, + 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xae, 0xff, 0xff, 0xaa, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xd4, 0x3e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x39, 0xff, 0xff, 0xc6, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x98, 0xff, 0xff, 0x37, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0xff, 0xde, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf9, 0xff, 0xb1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xff, 0xff, 0xa7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf3, 0xff, 0xb9, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xcb, 0xff, 0xed, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x85, 0xff, 0xff, 0x56, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x22, 0xfb, 0xff, 0xe3, 0x16, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x88, 0xff, 0xff, 0xd2, 0x24, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xed, 0xe1, + 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0xbb, 0xff, 0xff, 0xf6, 0x96, + 0x4b, 0x29, 0x2d, 0x5a, 0xb6, 0xff, 0xff, 0xff, + 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0xa8, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xc6, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf9, 0xab, 0x2e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, + 0x4a, 0x60, 0x5e, 0x41, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'C' */ + [0x44 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2e, + 0x1f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf6, 0xb9, 0x54, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xc3, 0x1a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x9e, 0x48, 0x48, 0x4a, + 0x61, 0x97, 0xef, 0xff, 0xff, 0xdf, 0x19, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x11, 0xac, 0xff, 0xff, 0xbd, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xb9, 0xff, 0xff, 0x48, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0xff, 0xff, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xff, 0xe4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0xff, 0xff, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9b, 0xff, 0xff, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0xff, 0xfc, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, 0xff, 0xd9, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0xff, 0xff, 0x97, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0a, 0xcf, 0xff, 0xff, 0x31, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x26, 0xc8, 0xff, 0xff, 0x9a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xb1, 0x6c, 0x6c, 0x6e, + 0x82, 0xbb, 0xfd, 0xff, 0xff, 0xbe, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfd, 0x92, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, + 0xef, 0xca, 0x88, 0x27, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'D' */ + [0x45 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x2b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x9b, 0x48, 0x48, 0x48, + 0x48, 0x48, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xdd, 0xc0, 0xc0, 0xc0, + 0xc0, 0xc0, 0xc0, 0x5d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xc5, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x46, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xb3, 0x74, 0x74, 0x74, + 0x74, 0x74, 0x74, 0x74, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'E' */ + [0x46 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xb0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xb0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xa1, 0x48, 0x48, 0x48, + 0x48, 0x48, 0x48, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xc3, 0x88, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x31, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xec, 0xd8, 0xd8, 0xd8, + 0xd8, 0xd8, 0xd8, 0x4e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'F' */ + [0x47 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x41, + 0x75, 0x8b, 0x8a, 0x71, 0x3c, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x72, 0xea, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe5, 0x6a, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x14, 0xc4, 0xff, 0xff, 0xff, + 0xff, 0xee, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xb3, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xd1, 0xff, 0xff, 0xd8, 0x5e, + 0x11, 0x00, 0x00, 0x16, 0x69, 0xe5, 0xff, 0xd5, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa2, 0xff, 0xff, 0xa7, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa5, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x32, 0xff, 0xff, 0xc3, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x95, 0xff, 0xff, 0x33, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0xff, 0xda, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf9, 0xff, 0xa9, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf2, 0xff, 0xb1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x19, 0xe4, 0xe4, 0xe4, 0xe4, 0xe4, 0xe9, + 0xff, 0xff, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc8, 0xff, 0xe6, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, + 0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7e, 0xff, 0xff, 0x4d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, + 0xff, 0xfe, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x19, 0xf7, 0xff, 0xdd, 0x11, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xef, + 0xff, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x77, 0xff, 0xff, 0xcb, 0x1b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xc9, 0xff, + 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0xa6, 0xff, 0xff, 0xf1, 0x86, + 0x36, 0x12, 0x12, 0x33, 0x7d, 0xec, 0xff, 0xff, + 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x8f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x85, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xb8, 0xfd, + 0xff, 0xff, 0xff, 0xff, 0xfd, 0xb9, 0x3a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, + 0x44, 0x5e, 0x5e, 0x43, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'G' */ + [0x48 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x30, 0x30, 0x17, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x30, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7b, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x57, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xb6, 0x74, 0x74, 0x74, + 0x74, 0x74, 0x74, 0x74, 0xa4, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0xff, 0xff, 0x4c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'H' */ + [0x49 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'I' */ + [0x4a - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0b, 0x30, 0x30, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3d, 0xff, 0xff, 0x5f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3a, 0x8f, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x52, 0xff, 0xff, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0xff, 0xff, 0x5d, 0x00, 0x00, 0x00, 0x00, + 0xa8, 0xff, 0xff, 0x23, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0xf0, 0xff, 0xf6, 0x66, 0x1c, 0x28, 0x92, + 0xff, 0xff, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x52, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf5, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4a, 0xe0, 0xff, 0xff, 0xff, 0xff, + 0xd1, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x3b, 0x5e, 0x5d, 0x32, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'J' */ + [0x4b - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x30, 0x30, 0x17, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x30, 0x30, 0x2f, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0xcf, 0xff, 0xff, 0x77, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x02, 0xb2, 0xff, 0xff, 0x9b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x8c, 0xff, 0xff, 0xb8, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x65, 0xff, 0xff, 0xd0, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x42, + 0xfb, 0xff, 0xe4, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x25, 0xee, + 0xff, 0xf3, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x11, 0xd9, 0xff, + 0xfc, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7d, 0xbd, 0xff, 0xff, + 0xe1, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, + 0xff, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xac, 0xd5, + 0xff, 0xff, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xc4, 0x08, 0x33, + 0xfb, 0xff, 0xe4, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xd9, 0x13, 0x00, 0x00, + 0x7d, 0xff, 0xff, 0xa6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x7a, 0x00, 0x00, 0x00, + 0x04, 0xc8, 0xff, 0xff, 0x5a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x25, 0xf5, 0xff, 0xee, 0x1b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0xff, 0xff, 0xbb, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xb8, 0xff, 0xff, 0x6e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1b, 0xed, 0xff, 0xf7, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'K' */ + [0x4c - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x30, 0x30, 0x17, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xb8, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x71, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'L' */ + [0x4d - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x30, 0x30, 0x30, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2d, 0x30, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0x9e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0xff, 0xff, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xf5, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, + 0xff, 0xff, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0x68, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xef, + 0xff, 0xff, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xfc, 0xff, 0xce, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0xff, + 0xff, 0xfc, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xae, 0xff, 0xff, 0x33, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xff, + 0xc6, 0xea, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x67, 0xe6, 0xff, 0x99, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xff, 0xff, + 0x60, 0xf2, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x6a, 0x84, 0xff, 0xf2, + 0x0c, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xff, 0xf0, + 0x0a, 0xfa, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x6c, 0x20, 0xfe, 0xff, + 0x63, 0x00, 0x00, 0x00, 0x06, 0xeb, 0xff, 0x93, + 0x00, 0xfc, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x6c, 0x00, 0xb7, 0xff, + 0xc9, 0x00, 0x00, 0x00, 0x56, 0xff, 0xff, 0x2d, + 0x00, 0xfc, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x6c, 0x00, 0x51, 0xff, + 0xff, 0x2d, 0x00, 0x00, 0xbb, 0xff, 0xc6, 0x00, + 0x00, 0xfc, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x6c, 0x00, 0x04, 0xe6, + 0xff, 0x93, 0x00, 0x22, 0xfe, 0xff, 0x60, 0x00, + 0x00, 0xfc, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x6c, 0x00, 0x00, 0x84, + 0xff, 0xf0, 0x0a, 0x85, 0xff, 0xef, 0x0a, 0x00, + 0x00, 0xfc, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x6c, 0x00, 0x00, 0x20, + 0xfe, 0xff, 0x62, 0xe6, 0xff, 0x93, 0x00, 0x00, + 0x00, 0xfc, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x6c, 0x00, 0x00, 0x00, + 0xb6, 0xff, 0xf0, 0xff, 0xff, 0x2c, 0x00, 0x00, + 0x00, 0xfc, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x6c, 0x00, 0x00, 0x00, + 0x50, 0xff, 0xff, 0xff, 0xc5, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x6c, 0x00, 0x00, 0x00, + 0x04, 0xe6, 0xff, 0xff, 0x5e, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x83, 0xff, 0xef, 0x08, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'M' */ + [0x4e - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x30, 0x30, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x30, 0x30, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xfe, 0x3a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2c, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xd4, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2c, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2c, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xf7, 0xff, 0xf9, 0x27, + 0x00, 0x00, 0x00, 0x00, 0x2c, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x82, 0xf7, 0xff, 0xc2, + 0x01, 0x00, 0x00, 0x00, 0x2c, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x66, 0x78, 0xff, 0xff, + 0x67, 0x00, 0x00, 0x00, 0x2c, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x6d, 0x05, 0xd0, 0xff, + 0xf0, 0x18, 0x00, 0x00, 0x2c, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x70, 0x00, 0x34, 0xfd, + 0xff, 0xac, 0x00, 0x00, 0x2c, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x70, 0x00, 0x00, 0x8f, + 0xff, 0xff, 0x4f, 0x00, 0x2c, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x70, 0x00, 0x00, 0x0b, + 0xe0, 0xff, 0xe3, 0x0e, 0x2b, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x47, 0xff, 0xff, 0x94, 0x25, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0xa4, 0xff, 0xfe, 0x58, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x14, 0xec, 0xff, 0xe6, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5c, 0xff, 0xff, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb8, 0xff, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0xf5, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x71, 0xff, 0xff, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'N' */ + [0x4f - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, + 0x78, 0x8c, 0x87, 0x69, 0x2d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x7c, 0xec, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x47, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1b, 0xcc, 0xff, 0xff, 0xff, + 0xff, 0xf4, 0xfa, 0xff, 0xff, 0xff, 0xff, 0x8f, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0xda, 0xff, 0xff, 0xda, 0x5f, + 0x14, 0x00, 0x01, 0x29, 0x84, 0xf5, 0xff, 0xff, + 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xac, 0xff, 0xff, 0xad, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0xe2, 0xff, + 0xff, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0xff, 0xff, 0xc9, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0xf8, + 0xff, 0xdc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x98, 0xff, 0xff, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, + 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd7, 0xff, 0xde, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, + 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf9, 0xff, 0xad, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0xff, 0xff, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xff, 0xff, 0xa3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfb, 0xff, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf3, 0xff, 0xb5, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, + 0xff, 0xff, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xcb, 0xff, 0xeb, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, + 0xff, 0xff, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x86, 0xff, 0xff, 0x52, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, + 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x22, 0xfb, 0xff, 0xe1, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xff, + 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x88, 0xff, 0xff, 0xd0, 0x1f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xf6, 0xff, + 0xfa, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xba, 0xff, 0xff, 0xf4, 0x8f, + 0x44, 0x24, 0x2b, 0x58, 0xb4, 0xff, 0xff, 0xff, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0xa5, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x5d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0xc7, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf7, 0xa1, 0x22, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, + 0x4b, 0x60, 0x5c, 0x3d, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'O' */ + [0x50 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x28, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf9, 0xa9, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xef, 0x31, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x98, 0x3c, 0x3c, 0x3c, + 0x52, 0xb2, 0xff, 0xff, 0xda, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xa7, 0xff, 0xff, 0x4c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x31, 0xff, 0xff, 0x86, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0xff, 0xff, 0x96, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x32, 0xff, 0xff, 0x83, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x04, 0xb5, 0xff, 0xff, 0x44, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xaa, 0x5c, 0x5c, 0x5d, + 0x73, 0xcf, 0xff, 0xff, 0xc6, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xd4, 0x1b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xfc, 0xf8, 0xf8, 0xf8, + 0xee, 0xc4, 0x6f, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'P' */ + [0x51 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, + 0x78, 0x8c, 0x87, 0x69, 0x2d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x7c, 0xec, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x47, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1b, 0xcc, 0xff, 0xff, 0xff, + 0xff, 0xf4, 0xfa, 0xff, 0xff, 0xff, 0xff, 0x8f, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0xda, 0xff, 0xff, 0xda, 0x5f, + 0x14, 0x00, 0x01, 0x29, 0x84, 0xf5, 0xff, 0xff, + 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xac, 0xff, 0xff, 0xad, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0xe2, 0xff, + 0xff, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0xff, 0xff, 0xc9, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0xf8, + 0xff, 0xdc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x98, 0xff, 0xff, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, + 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd7, 0xff, 0xde, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, + 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf9, 0xff, 0xad, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, + 0xff, 0xff, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xff, 0xff, 0xa3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfb, 0xff, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf3, 0xff, 0xb5, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, + 0xff, 0xff, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xcb, 0xff, 0xeb, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x46, + 0xff, 0xff, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x86, 0xff, 0xff, 0x52, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x16, 0xa3, 0xff, 0x50, 0x00, 0xac, + 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x22, 0xfb, 0xff, 0xe1, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x23, 0xf5, 0xff, 0xe8, 0x5f, 0xff, + 0xff, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x88, 0xff, 0xff, 0xd0, 0x1f, 0x00, + 0x00, 0x00, 0x00, 0x70, 0xff, 0xff, 0xff, 0xff, + 0xfa, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xba, 0xff, 0xff, 0xf4, 0x8f, + 0x44, 0x24, 0x2b, 0x5a, 0xf8, 0xff, 0xff, 0xff, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0xa5, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xeb, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0xc7, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf7, 0xc9, 0xff, 0xff, + 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, + 0x4b, 0x60, 0x5c, 0x3d, 0x0a, 0x03, 0xcc, 0xff, + 0xd5, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x78, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'Q' */ + [0x52 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x29, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf9, 0xa7, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xee, 0x34, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x96, 0x38, 0x38, 0x38, + 0x4b, 0xad, 0xff, 0xff, 0xde, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9f, 0xff, 0xff, 0x52, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2d, 0xff, 0xff, 0x82, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x23, 0xff, 0xff, 0x85, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0xff, 0xff, 0x5b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x03, 0x5c, 0xf7, 0xff, 0xec, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xee, 0xdc, 0xdc, 0xdc, + 0xf1, 0xff, 0xff, 0xfb, 0x4b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xca, 0x3b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0xa6, 0x54, 0x55, 0xe0, + 0xff, 0xf0, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x43, + 0xff, 0xff, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x9a, 0xff, 0xff, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x0e, 0xe3, 0xff, 0xf2, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x4b, 0xff, 0xff, 0xc0, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa5, 0xff, 0xff, 0x71, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0xff, 0xff, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xe9, 0xff, 0xf8, 0x29, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'R' */ + [0x53 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2d, 0x71, 0x8d, 0x86, + 0x5f, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xb1, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf6, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xce, 0xff, 0xff, 0xf1, 0xcb, 0xda, + 0xff, 0xff, 0xff, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x69, 0xff, 0xff, 0x93, 0x08, 0x00, 0x00, + 0x35, 0xe3, 0xff, 0xf9, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xaa, 0xff, 0xf4, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x3a, 0xc0, 0x56, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb1, 0xff, 0xf6, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7d, 0xff, 0xff, 0xa1, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x14, 0xe9, 0xff, 0xff, 0xea, 0x85, 0x27, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2c, 0xda, 0xff, 0xff, 0xff, 0xff, + 0xcc, 0x61, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x6b, 0xd6, 0xff, 0xff, + 0xff, 0xff, 0xcd, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x93, + 0xf4, 0xff, 0xff, 0xdb, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x17, 0xbb, 0xff, 0xff, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0xf3, 0xff, 0xb7, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1b, 0x98, 0xf3, 0x52, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd3, 0xff, 0xc5, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x15, 0xf8, 0xff, 0xd8, 0x0b, 0x00, 0x00, 0x00, + 0x00, 0x1c, 0xfa, 0xff, 0xa3, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x90, 0xff, 0xff, 0xc7, 0x37, 0x01, 0x02, + 0x3b, 0xd2, 0xff, 0xff, 0x4c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0xcd, 0xff, 0xff, 0xff, 0xf8, 0xfa, + 0xff, 0xff, 0xff, 0x9f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x94, 0xf8, 0xff, 0xff, 0xff, + 0xff, 0xea, 0x6f, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x46, 0x60, 0x5c, + 0x39, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'S' */ + [0x54 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x15, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x24, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x48, 0x48, 0x48, 0x48, 0xbf, 0xff, 0xfe, + 0x48, 0x48, 0x48, 0x48, 0x36, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'T' */ + [0x55 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1a, 0x30, 0x30, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x30, 0x30, 0x1b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x88, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0x90, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x88, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0x90, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x88, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0x90, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x88, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0x90, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x88, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0x90, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x88, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0x90, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x88, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0x90, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x88, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0x90, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x88, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0x90, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x88, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0xff, 0xff, 0x90, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x87, 0xff, 0xff, 0x19, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x09, 0xff, 0xff, 0x8f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7b, 0xff, 0xff, 0x29, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x19, 0xff, 0xff, 0x83, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x4f, 0xff, 0xff, 0x67, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x5a, 0xff, 0xff, 0x5a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xf2, 0xff, 0xdf, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0xd6, 0xff, 0xf9, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7a, 0xff, 0xff, 0xd7, 0x4f, 0x15, + 0x14, 0x4b, 0xd0, 0xff, 0xff, 0x8f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xaf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xc3, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x79, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xf4, 0x89, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x3d, 0x5e, + 0x5f, 0x41, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'U' */ + [0x56 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x30, 0x30, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x30, 0x30, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7d, 0xff, 0xff, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb2, 0xff, 0xfd, 0x1a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x21, 0xff, 0xff, 0xae, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x13, 0xfa, 0xff, 0xb8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc4, 0xff, 0xf8, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x67, 0xff, 0xff, 0x58, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x69, 0xff, 0xff, 0x5f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc1, 0xff, 0xf1, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x13, 0xf9, 0xff, 0xb8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1d, 0xfe, 0xff, 0x9c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb0, 0xff, 0xfc, 0x16, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xff, 0xff, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x54, 0xff, 0xff, 0x6a, 0x00, 0x00, + 0x00, 0x00, 0xd0, 0xff, 0xdb, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0xf0, 0xff, 0xc2, 0x00, 0x00, + 0x00, 0x2a, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9b, 0xff, 0xfe, 0x1d, 0x00, + 0x00, 0x85, 0xff, 0xff, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x74, 0x00, + 0x01, 0xde, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0xe2, 0xff, 0xce, 0x00, + 0x39, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x87, 0xff, 0xff, 0x26, + 0x93, 0xff, 0xf6, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2b, 0xff, 0xff, 0x7b, + 0xe7, 0xff, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcf, 0xff, 0xf0, + 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0xff, 0xff, + 0xff, 0xe2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xfd, 0xff, + 0xff, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xff, + 0xff, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'V' */ + [0x57 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x30, 0x30, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1b, 0x30, 0x2e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2f, 0x30, 0x26, 0x00, + 0x6d, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xbe, 0xff, 0xff, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0xff, 0xff, 0xa1, 0x00, + 0x29, 0xff, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x12, 0xfc, 0xff, 0xff, 0x6b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0x5c, 0x00, + 0x00, 0xe3, 0xff, 0xd4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0xff, 0xb4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9f, 0xff, 0xff, 0x18, 0x00, + 0x00, 0x9f, 0xff, 0xff, 0x15, 0x00, 0x00, 0x00, + 0x00, 0xaa, 0xff, 0xfb, 0xff, 0xf7, 0x09, 0x00, + 0x00, 0x00, 0x00, 0xdc, 0xff, 0xd2, 0x00, 0x00, + 0x00, 0x5b, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00, + 0x07, 0xf3, 0xff, 0x8c, 0xff, 0xff, 0x4c, 0x00, + 0x00, 0x00, 0x1c, 0xff, 0xff, 0x8d, 0x00, 0x00, + 0x00, 0x17, 0xff, 0xff, 0x94, 0x00, 0x00, 0x00, + 0x4a, 0xff, 0xff, 0x1b, 0xd9, 0xff, 0x97, 0x00, + 0x00, 0x00, 0x5c, 0xff, 0xff, 0x47, 0x00, 0x00, + 0x00, 0x00, 0xd1, 0xff, 0xd4, 0x00, 0x00, 0x00, + 0x9a, 0xff, 0xce, 0x00, 0x8c, 0xff, 0xe1, 0x00, + 0x00, 0x00, 0x9c, 0xff, 0xf9, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x8d, 0xff, 0xff, 0x15, 0x00, 0x01, + 0xe6, 0xff, 0x7e, 0x00, 0x3f, 0xff, 0xff, 0x2c, + 0x00, 0x00, 0xdc, 0xff, 0xbe, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x46, 0xff, 0xff, 0x54, 0x00, 0x36, + 0xff, 0xff, 0x30, 0x00, 0x04, 0xef, 0xff, 0x79, + 0x00, 0x19, 0xff, 0xff, 0x7a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0xf9, 0xff, 0x94, 0x00, 0x86, + 0xff, 0xe1, 0x00, 0x00, 0x00, 0xa6, 0xff, 0xc3, + 0x00, 0x59, 0xff, 0xff, 0x35, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xbe, 0xff, 0xd4, 0x00, 0xd6, + 0xff, 0x92, 0x00, 0x00, 0x00, 0x5a, 0xff, 0xfc, + 0x11, 0x99, 0xff, 0xed, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7a, 0xff, 0xff, 0x39, 0xff, + 0xff, 0x43, 0x00, 0x00, 0x00, 0x11, 0xfc, 0xff, + 0x59, 0xd7, 0xff, 0xab, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x35, 0xff, 0xff, 0xbf, 0xff, + 0xf0, 0x06, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xff, + 0xbd, 0xff, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xee, 0xff, 0xff, 0xff, + 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0xff, + 0xff, 0xff, 0xff, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xac, 0xff, 0xff, 0xff, + 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xff, + 0xff, 0xff, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0xff, 0xff, 0xfa, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xda, + 0xff, 0xff, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x22, 0xff, 0xff, 0xba, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, + 0xff, 0xff, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'W' */ + [0x58 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x30, 0x30, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x30, 0x30, 0x29, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xe5, 0xff, 0xf9, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x8b, 0xff, 0xff, 0x72, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x4b, 0xff, 0xff, 0xc4, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x34, 0xfc, 0xff, 0xc7, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0xff, 0xff, 0x6a, 0x00, 0x00, + 0x00, 0x05, 0xd2, 0xff, 0xf8, 0x27, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0xe5, 0xff, 0xf2, 0x1d, 0x00, + 0x00, 0x7e, 0xff, 0xff, 0x75, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4b, 0xff, 0xff, 0xb4, 0x00, + 0x2c, 0xf9, 0xff, 0xc8, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0xff, 0xff, 0x5c, + 0xc8, 0xff, 0xf8, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xe5, 0xff, 0xfd, + 0xff, 0xff, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xff, 0xff, + 0xff, 0xc8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0xfc, 0xff, + 0xff, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0xff, 0xff, + 0xff, 0xff, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6a, 0xff, 0xff, 0x9f, + 0xed, 0xff, 0xeb, 0x17, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0xf3, 0xff, 0xda, 0x09, + 0x5b, 0xff, 0xff, 0xae, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xbc, 0xff, 0xfe, 0x3d, 0x00, + 0x00, 0xb5, 0xff, 0xff, 0x5b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x67, 0xff, 0xff, 0x90, 0x00, 0x00, + 0x00, 0x1b, 0xf0, 0xff, 0xed, 0x1a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1e, 0xf2, 0xff, 0xdd, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x61, 0xff, 0xff, 0xb5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xba, 0xff, 0xfe, 0x3f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xba, 0xff, 0xff, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0xff, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1e, 0xf2, 0xff, 0xf0, 0x1e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'X' */ + [0x59 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x30, 0x30, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x12, 0x30, 0x30, 0x1c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x54, 0xff, 0xff, 0xb5, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xbd, 0xff, 0xfe, 0x39, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb5, 0xff, 0xff, 0x4e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x56, 0xff, 0xff, 0x98, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1f, 0xf5, 0xff, 0xde, 0x09, 0x00, 0x00, + 0x00, 0x0c, 0xe3, 0xff, 0xe8, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x71, 0xff, 0xff, 0x81, 0x00, 0x00, + 0x00, 0x88, 0xff, 0xff, 0x58, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xcd, 0xff, 0xf7, 0x22, 0x00, + 0x28, 0xfa, 0xff, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x33, 0xfd, 0xff, 0xb2, 0x00, + 0xbb, 0xff, 0xf7, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x90, 0xff, 0xff, 0x99, + 0xff, 0xff, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0xe1, 0xff, 0xff, + 0xff, 0xd6, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0xff, 0xff, + 0xff, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xff, + 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, + 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, + 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, + 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, + 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, + 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, + 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, + 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'Y' */ + [0x5a - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x26, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xcc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xcc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x36, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, + 0x48, 0xb5, 0xff, 0xff, 0xa5, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x39, 0xfc, 0xff, 0xe4, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, + 0xde, 0xff, 0xfe, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, + 0xff, 0xff, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0xff, + 0xff, 0xca, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xf2, 0xff, + 0xf3, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0xc7, 0xff, 0xff, + 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x83, 0xff, 0xff, 0xa6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0xfd, 0xff, 0xdf, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0xe3, 0xff, 0xfc, 0x3b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xac, 0xff, 0xff, 0x7f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x65, 0xff, 0xff, 0xc4, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xf5, 0xff, 0xff, 0x96, 0x78, 0x78, 0x78, + 0x78, 0x78, 0x78, 0x78, 0x6d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'Z' */ + [0x5b - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x04, 0x04, 0x04, 0x04, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xd8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xd8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xde, 0x24, 0x24, 0x1e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xdf, 0x2c, 0x2c, 0x25, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xd8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xf8, 0xf8, 0xf8, 0xf8, 0xd1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '[' */ + [0x5c - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x30, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb3, 0xff, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0xff, 0xf5, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0xfc, 0xff, 0x52, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbd, 0xff, 0xa6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6a, 0xff, 0xf1, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x19, 0xfe, 0xff, 0x4a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xff, 0x9d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x72, 0xff, 0xeb, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x22, 0xff, 0xff, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xce, 0xff, 0x94, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xff, 0xe5, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2a, 0xff, 0xff, 0x3a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd6, 0xff, 0x8d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x84, 0xff, 0xde, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0xff, 0xff, 0x32, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0x84, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0xff, 0xd6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '\\' */ + [0x5d - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0xff, 0xff, 0xff, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0xff, 0xff, 0xff, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x11, 0x24, 0x24, 0x92, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x15, 0x2c, 0x2c, 0x96, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0xff, 0xff, 0xff, 0xff, 0xdc, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x74, 0xf8, 0xf8, 0xf8, 0xf8, 0xd5, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* ']' */ + [0x5e - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x30, 0x25, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa2, 0xff, 0xf9, 0x27, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xbb, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xd4, 0xff, 0xa7, 0xf6, 0xff, + 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x75, 0xff, 0xeb, 0x0f, 0x82, 0xff, + 0xe8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1d, 0xf3, 0xff, 0x66, 0x00, 0x0a, 0xe3, + 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xab, 0xff, 0xd0, 0x03, 0x00, 0x00, 0x59, + 0xff, 0xfd, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x46, 0xff, 0xff, 0x42, 0x00, 0x00, 0x00, 0x01, + 0xc5, 0xff, 0xcc, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x19, 0x28, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x28, 0x28, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '^' */ + [0x5f - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, + 0xfc, 0xfc, 0xfc, 0xbd, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '_' */ + [0x60 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6b, 0xe0, 0xdc, 0x16, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xff, 0x7e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5b, 0xff, 0xe9, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x9a, 0xb4, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '`' */ + [0x61 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1e, 0x74, 0xa1, 0xaa, 0x97, + 0x61, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x84, 0xfb, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xea, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x8a, 0xff, 0xff, 0xc9, 0x80, 0x76, 0xaa, + 0xfc, 0xff, 0xf7, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x12, 0xc1, 0x6d, 0x00, 0x00, 0x00, 0x00, + 0x49, 0xfe, 0xff, 0x97, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc1, 0xff, 0xcf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x5f, 0xa6, 0xc3, 0xc1, 0xa3, + 0x66, 0xb2, 0xff, 0xdc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x22, 0xd7, 0xff, 0xff, 0xfc, 0xf0, 0xfe, + 0xff, 0xff, 0xff, 0xdc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xcd, 0xff, 0xec, 0x51, 0x05, 0x00, 0x09, + 0x4a, 0xdb, 0xff, 0xdc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x29, 0xff, 0xff, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbb, 0xff, 0xdc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xff, 0xff, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x1e, 0xf9, 0xff, 0xdc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x16, 0xfd, 0xff, 0xbb, 0x08, 0x00, 0x00, 0x19, + 0xcd, 0xff, 0xff, 0xdc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x9c, 0xff, 0xff, 0xe4, 0xa8, 0xb4, 0xf5, + 0xf7, 0xd0, 0xff, 0xdc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x9b, 0xfe, 0xff, 0xff, 0xff, 0xde, + 0x3e, 0xa0, 0xff, 0xdc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1c, 0x56, 0x61, 0x3e, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'a' */ + [0x62 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x19, 0x30, 0x30, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x09, 0x60, 0x9d, + 0xa8, 0x87, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x41, 0xdc, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xa2, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xea, 0xff, 0xd3, 0x9c, + 0xb0, 0xf7, 0xff, 0xff, 0xac, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xfe, 0x6b, 0x00, 0x00, + 0x00, 0x1e, 0xd3, 0xff, 0xff, 0x51, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x94, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, 0xfb, 0xff, 0xb8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x2b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb7, 0xff, 0xf1, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x91, 0xff, 0xff, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x99, 0xff, 0xff, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x46, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xff, 0xe0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xc5, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x4e, 0xff, 0xff, 0x97, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xff, 0xb3, 0x20, 0x00, + 0x04, 0x5e, 0xf5, 0xff, 0xf9, 0x26, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xfb, 0xc4, 0xff, 0xff, 0xe8, + 0xf6, 0xff, 0xff, 0xff, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xf8, 0x10, 0xa4, 0xfe, 0xff, + 0xff, 0xff, 0xe5, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x56, + 0x61, 0x3e, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'b' */ + [0x63 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2a, 0x7b, 0xa2, 0xa7, + 0x89, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x9a, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xbd, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0xb6, 0xff, 0xff, 0xee, 0xa9, 0xa1, + 0xd8, 0xff, 0xff, 0xca, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6a, 0xff, 0xff, 0xb4, 0x0e, 0x00, 0x00, + 0x01, 0x83, 0xff, 0xff, 0x62, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd9, 0xff, 0xe1, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x8c, 0x4d, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x16, 0xff, 0xff, 0x82, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x31, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0xff, 0xff, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0xfb, 0xff, 0x9d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb8, 0xff, 0xf9, 0x2b, 0x00, 0x00, 0x00, + 0x00, 0x09, 0xd4, 0xa9, 0x35, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x39, 0xfd, 0xff, 0xe5, 0x49, 0x02, 0x00, + 0x28, 0xbd, 0xff, 0xff, 0x4c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6f, 0xff, 0xff, 0xff, 0xf3, 0xed, + 0xff, 0xff, 0xff, 0x9b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0xdc, 0xff, 0xff, 0xff, + 0xff, 0xef, 0x76, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x33, 0x5b, 0x5f, + 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'c' */ + [0x64 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x30, 0x30, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3e, 0x88, 0xa4, 0x94, + 0x51, 0x03, 0x44, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0f, 0xb3, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xc8, 0x59, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0xc3, 0xff, 0xff, 0xf0, 0xb0, 0xa9, + 0xe5, 0xff, 0xeb, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x6f, 0xff, 0xff, 0xb7, 0x10, 0x00, 0x00, + 0x06, 0x94, 0xff, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd9, 0xff, 0xe2, 0x0b, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xc1, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x16, 0xff, 0xff, 0x85, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5a, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0xff, 0xff, 0x5d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x31, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2c, 0xff, 0xff, 0x64, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0d, 0xfe, 0xff, 0x9c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0xff, 0xf6, 0x25, 0x00, 0x00, 0x00, + 0x00, 0x10, 0xe2, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0xff, 0xff, 0xe0, 0x3f, 0x00, 0x00, + 0x2a, 0xcb, 0xff, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x98, 0xff, 0xff, 0xff, 0xec, 0xe5, + 0xff, 0xff, 0xc5, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x76, 0xf3, 0xff, 0xff, 0xff, + 0xf9, 0x8e, 0x2e, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x48, 0x61, 0x4f, + 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'd' */ + [0x65 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x33, 0x84, 0xa6, 0xa4, + 0x7f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0a, 0xa7, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xa2, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xb9, 0xff, 0xff, 0xd2, 0x91, 0x97, + 0xdd, 0xff, 0xff, 0xb2, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x69, 0xff, 0xff, 0x87, 0x01, 0x00, 0x00, + 0x04, 0x9f, 0xff, 0xff, 0x52, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd6, 0xff, 0xd0, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x09, 0xec, 0xff, 0xae, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x15, 0xff, 0xff, 0xb7, 0x64, 0x64, 0x64, 0x64, + 0x64, 0x64, 0xd6, 0xff, 0xd8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x31, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2c, 0xff, 0xff, 0x9f, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x51, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0xfd, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbd, 0xff, 0xf2, 0x1d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x60, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0xff, 0xff, 0xd7, 0x33, 0x00, 0x00, + 0x08, 0x7d, 0xff, 0xff, 0x5e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xff, 0xff, 0xff, 0xdc, 0xce, + 0xf1, 0xff, 0xff, 0xb7, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x59, 0xe4, 0xff, 0xff, 0xff, + 0xff, 0xf6, 0x89, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x38, 0x5d, 0x60, + 0x45, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'e' */ + [0x66 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x63, 0x8c, 0x84, + 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0xe7, 0xff, 0xff, 0xff, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0xd8, 0xff, 0xff, 0xce, 0xb6, + 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0xff, 0xff, 0x9d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x47, 0xff, 0xff, 0x57, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x48, 0x7c, 0xff, 0xff, 0x85, 0x48, 0x48, + 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x59, 0xe4, 0xed, 0xff, 0xff, 0xf0, 0xe4, 0xe4, + 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xff, 0xff, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xff, 0xff, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xff, 0xff, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xff, 0xff, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xff, 0xff, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xff, 0xff, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xff, 0xff, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xff, 0xff, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xff, 0xff, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xff, 0xff, 0x54, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'f' */ + [0x67 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x4a, 0x90, 0xa9, 0x96, + 0x52, 0x03, 0x13, 0x48, 0x48, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x19, 0xc4, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xcb, 0x5b, 0xff, 0xff, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0b, 0xd5, 0xff, 0xff, 0xe3, 0xa2, 0x9d, + 0xdc, 0xff, 0xf0, 0xff, 0xff, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x82, 0xff, 0xff, 0x9b, 0x06, 0x00, 0x00, + 0x03, 0x86, 0xff, 0xff, 0xff, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe5, 0xff, 0xd3, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc1, 0xff, 0xff, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1b, 0xff, 0xff, 0x79, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0xff, 0xff, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x32, 0xff, 0xff, 0x5b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x47, 0xff, 0xff, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0xff, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x55, 0xff, 0xff, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0xfc, 0xff, 0x9e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x92, 0xff, 0xff, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbb, 0xff, 0xf9, 0x2e, 0x00, 0x00, 0x00, + 0x00, 0x2a, 0xf6, 0xff, 0xff, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3f, 0xff, 0xff, 0xee, 0x6a, 0x23, 0x22, + 0x65, 0xeb, 0xff, 0xff, 0xff, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x77, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfd, 0xa8, 0xff, 0xff, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4e, 0xd0, 0xff, 0xff, 0xff, + 0xcc, 0x42, 0x5b, 0xff, 0xff, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x2a, 0x15, + 0x00, 0x00, 0x74, 0xff, 0xff, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x69, 0x98, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xff, 0xf0, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7b, 0xff, 0xff, 0x89, 0x04, 0x00, 0x00, + 0x02, 0x7e, 0xff, 0xff, 0x94, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0xd0, 0xff, 0xff, 0xe5, 0xab, 0xa9, + 0xe1, 0xff, 0xff, 0xde, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0xa4, 0xfe, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xb7, 0x1a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x21, 0x66, 0x86, 0x87, + 0x69, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'g' */ + [0x68 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x19, 0x30, 0x30, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x10, 0x09, 0x66, 0xa0, + 0xa5, 0x7c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x34, 0xdc, 0xff, 0xff, + 0xff, 0xff, 0xf5, 0x49, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xde, 0xfc, 0xb2, 0x9b, + 0xd8, 0xff, 0xff, 0xef, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xf5, 0x3a, 0x00, 0x00, + 0x03, 0xac, 0xff, 0xff, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x7a, 0x00, 0x00, 0x00, + 0x00, 0x2f, 0xff, 0xff, 0x89, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x2a, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'h' */ + [0x69 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x21, 0xb4, 0xac, 0x15, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x9e, 0xff, 0xff, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x79, 0xff, 0xff, 0x5b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x54, 0x4b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1a, 0x48, 0x48, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5c, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'i' */ + [0x6a - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1e, 0xb3, 0xaf, 0x19, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x96, 0xff, 0xff, 0x86, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x71, 0xff, 0xff, 0x63, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x50, 0x4f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x19, 0x48, 0x48, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5d, 0xff, 0xff, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xac, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xda, 0xff, 0xff, 0xd4, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xe4, 0x2b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x88, 0x5e, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'j' */ + [0x6b - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x19, 0x30, 0x30, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x37, 0x48, 0x48, 0x29, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x63, 0xff, 0xff, 0xd5, 0x17, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x5e, + 0xfe, 0xff, 0xd5, 0x17, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x59, 0xfd, + 0xff, 0xd5, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x53, 0xfc, 0xff, + 0xd5, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x66, 0xfb, 0xff, 0xff, + 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xff, 0xd6, 0xdb, 0xff, + 0xfc, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xd5, 0x17, 0x3b, 0xfe, + 0xff, 0xd4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x2a, 0x00, 0x00, 0x92, + 0xff, 0xff, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x0c, + 0xe0, 0xff, 0xfd, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x46, 0xff, 0xff, 0xdb, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x9f, 0xff, 0xff, 0x92, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'k' */ + [0x6c - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x19, 0x30, 0x30, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'l' */ + [0x6d - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x25, 0x48, 0x46, 0x00, 0x0e, 0x6d, 0xa4, + 0xa0, 0x64, 0x07, 0x00, 0x00, 0x1b, 0x78, 0xa5, + 0xa2, 0x70, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xf8, 0x33, 0xe7, 0xff, 0xff, + 0xff, 0xff, 0xcf, 0x12, 0x57, 0xf5, 0xff, 0xff, + 0xff, 0xff, 0xe4, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xfc, 0xe4, 0xf4, 0xa6, 0xa0, + 0xea, 0xff, 0xff, 0xbf, 0xfb, 0xf9, 0xac, 0x9d, + 0xe1, 0xff, 0xff, 0xb6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xec, 0x26, 0x00, 0x00, + 0x15, 0xe8, 0xff, 0xff, 0xf4, 0x31, 0x00, 0x00, + 0x0b, 0xd5, 0xff, 0xfe, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x6d, 0x00, 0x00, 0x00, + 0x00, 0x8f, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0x75, 0xff, 0xff, 0x35, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x27, 0x00, 0x00, 0x00, + 0x00, 0x73, 0xff, 0xff, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x5b, 0xff, 0xff, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'm' */ + [0x6e - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x25, 0x48, 0x46, 0x00, 0x0a, 0x64, 0xa0, + 0xa5, 0x7c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xf8, 0x2e, 0xe0, 0xff, 0xff, + 0xff, 0xff, 0xf5, 0x4a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xfc, 0xe3, 0xf9, 0xac, 0x9b, + 0xd5, 0xff, 0xff, 0xf0, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xf1, 0x2f, 0x00, 0x00, + 0x02, 0xa5, 0xff, 0xff, 0x61, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x72, 0x00, 0x00, 0x00, + 0x00, 0x2e, 0xff, 0xff, 0x89, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x27, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'n' */ + [0x6f - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x75, 0x9f, 0xa9, + 0x8e, 0x4d, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x8c, 0xfc, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xd5, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xa8, 0xff, 0xff, 0xf3, 0xb0, 0xa0, + 0xd2, 0xff, 0xff, 0xf2, 0x31, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0xff, 0xff, 0xbc, 0x14, 0x00, 0x00, + 0x00, 0x5c, 0xfa, 0xff, 0xd7, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd3, 0xff, 0xe5, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x15, 0xff, 0xff, 0x85, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0xfd, 0xff, 0x94, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0xff, 0xff, 0x5d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe1, 0xff, 0xb0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0xff, 0xff, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe9, 0xff, 0xaa, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0xfa, 0xff, 0x9d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, 0xff, 0xff, 0x83, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb4, 0xff, 0xf9, 0x2c, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xa9, 0xff, 0xff, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x32, 0xfb, 0xff, 0xe8, 0x4f, 0x03, 0x00, + 0x1c, 0xa6, 0xff, 0xff, 0xae, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x62, 0xfe, 0xff, 0xff, 0xf5, 0xe8, + 0xff, 0xff, 0xff, 0xd1, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x43, 0xd4, 0xff, 0xff, 0xff, + 0xff, 0xf8, 0x94, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x58, 0x61, + 0x47, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'o' */ + [0x70 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x25, 0x48, 0x46, 0x00, 0x0b, 0x64, 0x9e, + 0xa8, 0x87, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xf8, 0x36, 0xe4, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xa2, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xfe, 0xea, 0xff, 0xd3, 0x9c, + 0xb0, 0xf7, 0xff, 0xff, 0xac, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xfe, 0x69, 0x00, 0x00, + 0x00, 0x1e, 0xd3, 0xff, 0xff, 0x51, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x95, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x22, 0xfa, 0xff, 0xb8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb5, 0xff, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x8d, 0xff, 0xff, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x95, 0xff, 0xff, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x45, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xcd, 0xff, 0xe1, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xc4, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x4e, 0xff, 0xff, 0x97, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xff, 0xb3, 0x20, 0x00, + 0x04, 0x5f, 0xf5, 0xff, 0xf9, 0x26, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xd9, 0xff, 0xff, 0xe8, + 0xf6, 0xff, 0xff, 0xff, 0x66, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x2d, 0xb3, 0xff, 0xff, + 0xff, 0xff, 0xe5, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x21, 0x57, + 0x61, 0x3e, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x15, 0x28, 0x28, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'p' */ + [0x71 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x42, 0x8d, 0xa8, 0x98, + 0x56, 0x04, 0x0b, 0x48, 0x48, 0x17, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0xb7, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xd1, 0x46, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0xc9, 0xff, 0xff, 0xed, 0xa8, 0xa1, + 0xe0, 0xff, 0xeb, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x74, 0xff, 0xff, 0xb5, 0x0e, 0x00, 0x00, + 0x04, 0x8f, 0xff, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xde, 0xff, 0xe2, 0x0b, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xbc, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x19, 0xff, 0xff, 0x84, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x54, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x31, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2d, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2c, 0xff, 0xff, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x33, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0xfd, 0xff, 0x9d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x68, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc3, 0xff, 0xf7, 0x29, 0x00, 0x00, 0x00, + 0x00, 0x09, 0xd6, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x4c, 0xff, 0xff, 0xe4, 0x47, 0x01, 0x00, + 0x27, 0xbd, 0xff, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x91, 0xff, 0xff, 0xff, 0xf3, 0xec, + 0xff, 0xff, 0xd5, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x75, 0xf2, 0xff, 0xff, 0xff, + 0xfc, 0x95, 0x4b, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x48, 0x61, 0x51, + 0x18, 0x00, 0x44, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0xff, 0xff, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0b, 0x28, 0x28, 0x0d, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'q' */ + [0x72 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x25, 0x48, 0x46, 0x00, 0x1d, 0x83, 0xa6, + 0x8b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xf8, 0x40, 0xf3, 0xff, 0xff, + 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xfc, 0xdf, 0xff, 0xea, 0xd8, + 0xfb, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0xfc, 0x65, 0x02, 0x00, + 0x0b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x8b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x19, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x84, 0xff, 0xff, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'r' */ + [0x73 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0x89, 0xa6, 0xa2, 0x7d, + 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0xb5, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfe, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xff, 0xff, 0xb4, 0x76, 0x80, 0xcd, + 0xff, 0xff, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf2, 0xff, 0xaa, 0x00, 0x00, 0x00, 0x02, + 0x96, 0x90, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xeb, 0xff, 0xc5, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x91, 0xff, 0xff, 0xe0, 0x87, 0x44, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x9d, 0xff, 0xff, 0xff, 0xff, 0xf7, + 0xa9, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x29, 0x84, 0xc9, 0xfc, 0xff, + 0xff, 0xf7, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x65, + 0xf3, 0xff, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x49, 0xa1, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x97, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0xff, 0xff, 0xa0, 0x0d, 0x00, 0x00, 0x12, + 0xd2, 0xff, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa3, 0xff, 0xff, 0xf4, 0xc8, 0xc4, 0xf3, + 0xff, 0xff, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x7d, 0xf3, 0xff, 0xff, 0xff, 0xff, + 0xe6, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0b, 0x44, 0x60, 0x5d, 0x3a, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 's' */ + [0x74 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x46, 0xb4, 0xb4, 0x25, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0xff, 0xff, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0xff, 0xff, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1e, 0x48, 0x91, 0xff, 0xff, 0x6f, 0x48, 0x48, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0xe4, 0xf2, 0xff, 0xff, 0xeb, 0xe4, 0xe4, + 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0xff, 0xff, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0xff, 0xff, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0xff, 0xff, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0xff, 0xff, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0xff, 0xff, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0xff, 0xff, 0x34, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x63, 0xff, 0xff, 0x39, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x50, 0xff, 0xff, 0x86, 0x00, 0x04, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0xf4, 0xff, 0xff, 0xe4, 0xf2, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0xf4, 0xff, 0xff, 0xff, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x50, 0x60, 0x3b, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 't' */ + [0x75 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2d, 0x48, 0x46, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0b, 0x48, 0x48, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x29, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x9f, 0xff, 0xfd, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x42, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x90, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x58, 0xff, 0xff, 0xbd, 0x0f, 0x00, 0x03, + 0x74, 0xff, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0xdc, 0xff, 0xff, 0xf4, 0xcd, 0xe9, + 0xff, 0xc4, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x26, 0xd2, 0xff, 0xff, 0xff, 0xff, + 0xa8, 0x17, 0xff, 0xff, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x38, 0x5f, 0x58, 0x21, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'u' */ + [0x76 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3e, 0x48, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x48, 0x48, 0x2a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9b, 0xff, 0xfe, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x54, 0xff, 0xff, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb4, 0xff, 0xe6, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xcd, 0xff, 0xdb, 0x01, 0x00, 0x00, 0x00, + 0x19, 0xfc, 0xff, 0x82, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0xff, 0xff, 0x40, 0x00, 0x00, 0x00, + 0x78, 0xff, 0xfd, 0x1d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xf2, 0xff, 0xa0, 0x00, 0x00, 0x00, + 0xd8, 0xff, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x98, 0xff, 0xf4, 0x0c, 0x00, 0x38, + 0xff, 0xff, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0xff, 0xff, 0x61, 0x00, 0x99, + 0xff, 0xdf, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc9, 0xff, 0xc4, 0x0a, 0xf2, + 0xff, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x61, 0xff, 0xff, 0x7e, 0xff, + 0xfa, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0a, 0xf0, 0xff, 0xfc, 0xff, + 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x93, 0xff, 0xff, 0xff, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2d, 0xff, 0xff, 0xd7, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'v' */ + [0x77 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0x48, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x35, 0x48, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x48, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa2, 0xff, 0xf6, 0x08, 0x00, 0x00, 0x00, 0x03, + 0xeb, 0xff, 0xf3, 0x07, 0x00, 0x00, 0x00, 0x03, + 0xec, 0xff, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4e, 0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0x3e, + 0xff, 0xff, 0xff, 0x4a, 0x00, 0x00, 0x00, 0x3b, + 0xff, 0xff, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0xf5, 0xff, 0x93, 0x00, 0x00, 0x00, 0x8e, + 0xff, 0xf9, 0xff, 0x9a, 0x00, 0x00, 0x00, 0x87, + 0xff, 0xeb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xaa, 0xff, 0xde, 0x00, 0x00, 0x00, 0xdf, + 0xff, 0x87, 0xff, 0xe8, 0x02, 0x00, 0x00, 0xd2, + 0xff, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x5a, 0xff, 0xff, 0x28, 0x00, 0x2e, 0xff, + 0xe5, 0x0e, 0xf9, 0xff, 0x3a, 0x00, 0x1e, 0xff, + 0xff, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0xf9, 0xff, 0x71, 0x00, 0x7f, 0xff, + 0x96, 0x00, 0xb6, 0xff, 0x8a, 0x00, 0x69, 0xff, + 0xf1, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb6, 0xff, 0xbc, 0x00, 0xd2, 0xff, + 0x45, 0x00, 0x63, 0xff, 0xda, 0x00, 0xb4, 0xff, + 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x64, 0xff, 0xfa, 0x2e, 0xff, 0xf0, + 0x05, 0x00, 0x15, 0xfd, 0xff, 0x33, 0xf7, 0xff, + 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x15, 0xfd, 0xff, 0xc1, 0xff, 0xa6, + 0x00, 0x00, 0x00, 0xbe, 0xff, 0xc2, 0xff, 0xf6, + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc1, 0xff, 0xff, 0xff, 0x56, + 0x00, 0x00, 0x00, 0x6e, 0xff, 0xff, 0xff, 0xae, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6e, 0xff, 0xff, 0xf8, 0x0d, + 0x00, 0x00, 0x00, 0x1b, 0xff, 0xff, 0xff, 0x5a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1e, 0xff, 0xff, 0xb5, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc9, 0xff, 0xfa, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'w' */ + [0x78 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x48, 0x48, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x46, 0x48, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3b, 0xfc, 0xff, 0xb3, 0x00, 0x00, 0x00, 0x00, + 0x6f, 0xff, 0xff, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x81, 0xff, 0xff, 0x60, 0x00, 0x00, 0x25, + 0xf6, 0xff, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0xc8, 0xff, 0xf0, 0x1e, 0x03, 0xc5, + 0xff, 0xe3, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x23, 0xf4, 0xff, 0xba, 0x76, 0xff, + 0xfd, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x61, 0xff, 0xff, 0xff, 0xff, + 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb9, 0xff, 0xff, 0xd1, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1c, 0xee, 0xff, 0xff, 0xf2, + 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0xbd, 0xff, 0xe5, 0xe5, 0xff, + 0xc5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x72, 0xff, 0xff, 0x48, 0x4d, 0xff, + 0xff, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2d, 0xf9, 0xff, 0x9b, 0x00, 0x00, 0xa5, + 0xff, 0xfb, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xd3, 0xff, 0xe1, 0x0e, 0x00, 0x00, 0x13, + 0xe9, 0xff, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8e, 0xff, 0xff, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x54, 0xff, 0xff, 0x99, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'x' */ + [0x79 - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3e, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0b, 0x48, 0x48, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x94, 0xff, 0xff, 0x29, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x68, 0xff, 0xff, 0x46, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0xfe, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xce, 0xff, 0xd7, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xb2, 0xff, 0xf3, 0x0d, 0x00, 0x00, 0x00, + 0x34, 0xff, 0xff, 0x6a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3e, 0xff, 0xff, 0x6c, 0x00, 0x00, 0x00, + 0x9a, 0xff, 0xf1, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xce, 0xff, 0xd7, 0x01, 0x00, 0x0d, + 0xf4, 0xff, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5c, 0xff, 0xff, 0x43, 0x00, 0x66, + 0xff, 0xfe, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0xe5, 0xff, 0xaf, 0x00, 0xcd, + 0xff, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7a, 0xff, 0xfd, 0x4a, 0xff, + 0xff, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0xf5, 0xff, 0xe9, 0xff, + 0xd5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x96, 0xff, 0xff, 0xff, + 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x27, 0xfe, 0xff, 0xef, + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfa, 0xff, 0x8c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x77, 0xff, 0xfd, 0x21, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0xe5, 0xff, 0xb1, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0xff, 0xff, 0x42, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xd4, 0xff, 0xd4, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xff, 0xff, 0x66, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x2c, 0x2c, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'y' */ + [0x7a - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, + 0x48, 0x48, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0b, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xec, + 0xff, 0xff, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xcf, + 0xff, 0xf4, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xb4, 0xff, + 0xfc, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0xff, 0xff, + 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6f, 0xff, 0xff, 0x8c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4f, 0xfd, 0xff, 0xad, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x34, 0xf6, 0xff, 0xc9, 0x09, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1e, 0xe8, 0xff, 0xe0, 0x17, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0xd4, 0xff, 0xfb, 0x55, 0x2c, 0x2c, 0x2c, + 0x2c, 0x2c, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* 'z' */ + [0x7b - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x31, 0xbd, 0xfa, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x24, 0xf3, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x96, 0xff, 0xfa, 0x55, 0x0d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0xff, 0xa6, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xff, 0x89, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xff, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xff, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xff, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xde, 0xff, 0x81, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0d, 0x57, 0xff, 0xff, 0x4f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xff, 0xfa, 0x8f, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0xff, 0xfb, 0x97, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0b, 0x50, 0xff, 0xff, 0x53, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xdd, 0xff, 0x83, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xff, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xff, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xff, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0xff, 0x89, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0xff, 0xa6, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x98, 0xff, 0xfa, 0x55, 0x15, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x27, 0xf6, 0xff, 0xff, 0xfc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0xb9, 0xed, 0xf2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '{' */ + [0x7c - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0xd0, 0xd0, 0x4b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0xff, 0xff, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x28, 0x28, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '|' */ + [0x7d - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xfe, 0xe4, 0x8a, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xff, 0xff, 0xff, 0xa4, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x1b, 0xb4, 0xff, 0xff, 0x1d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x29, 0xff, 0xff, 0x4d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0xff, 0xff, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0xff, 0xff, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0xff, 0xff, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0xff, 0xff, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x62, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd3, 0xff, 0xc1, 0x26, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x35, 0xd8, 0xff, 0xff, + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x39, 0xde, 0xff, 0xff, + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd6, 0xff, 0xbb, 0x1a, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x61, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0xff, 0xff, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0xff, 0xff, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0xff, 0xff, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0xff, 0xff, 0x54, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2e, 0xff, 0xff, 0x4a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x09, 0x27, 0xc0, 0xff, 0xfd, 0x19, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xff, 0xff, 0xff, 0x92, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0xf7, 0xd9, 0x74, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '}' */ + [0x7e - FONT_START_CHAR] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x61, 0x77, 0x4d, 0x08, 0x00, + 0x00, 0x00, 0x1d, 0x28, 0x17, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x15, 0xdc, 0xff, 0xff, 0xff, 0xec, 0x84, + 0x1c, 0x0f, 0xe7, 0xff, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x91, 0xff, 0xfb, 0xcd, 0xf9, 0xff, 0xff, + 0xff, 0xfa, 0xff, 0xfe, 0x2b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd4, 0xf8, 0x80, 0x00, 0x14, 0x7a, 0xe1, + 0xff, 0xff, 0xfe, 0x79, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x30, 0x48, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, /* '~' */ +}; + +const uint8_t font_widths[FONT_NUM_CHARS] = { + [0x20 - FONT_START_CHAR] = 8, + [0x21 - FONT_START_CHAR] = 4, + [0x22 - FONT_START_CHAR] = 7, + [0x23 - FONT_START_CHAR] = 16, + [0x24 - FONT_START_CHAR] = 13, + [0x25 - FONT_START_CHAR] = 20, + [0x26 - FONT_START_CHAR] = 15, + [0x27 - FONT_START_CHAR] = 3, + [0x28 - FONT_START_CHAR] = 7, + [0x29 - FONT_START_CHAR] = 7, + [0x2a - FONT_START_CHAR] = 10, + [0x2b - FONT_START_CHAR] = 12, + [0x2c - FONT_START_CHAR] = 5, + [0x2d - FONT_START_CHAR] = 8, + [0x2e - FONT_START_CHAR] = 4, + [0x2f - FONT_START_CHAR] = 8, + [0x30 - FONT_START_CHAR] = 14, + [0x31 - FONT_START_CHAR] = 8, + [0x32 - FONT_START_CHAR] = 11, + [0x33 - FONT_START_CHAR] = 13, + [0x34 - FONT_START_CHAR] = 14, + [0x35 - FONT_START_CHAR] = 13, + [0x36 - FONT_START_CHAR] = 13, + [0x37 - FONT_START_CHAR] = 12, + [0x38 - FONT_START_CHAR] = 12, + [0x39 - FONT_START_CHAR] = 13, + [0x3a - FONT_START_CHAR] = 4, + [0x3b - FONT_START_CHAR] = 6, + [0x3c - FONT_START_CHAR] = 11, + [0x3d - FONT_START_CHAR] = 12, + [0x3e - FONT_START_CHAR] = 12, + [0x3f - FONT_START_CHAR] = 12, + [0x40 - FONT_START_CHAR] = 20, + [0x41 - FONT_START_CHAR] = 17, + [0x42 - FONT_START_CHAR] = 14, + [0x43 - FONT_START_CHAR] = 17, + [0x44 - FONT_START_CHAR] = 16, + [0x45 - FONT_START_CHAR] = 12, + [0x46 - FONT_START_CHAR] = 11, + [0x47 - FONT_START_CHAR] = 19, + [0x48 - FONT_START_CHAR] = 15, + [0x49 - FONT_START_CHAR] = 4, + [0x4a - FONT_START_CHAR] = 12, + [0x4b - FONT_START_CHAR] = 15, + [0x4c - FONT_START_CHAR] = 11, + [0x4d - FONT_START_CHAR] = 19, + [0x4e - FONT_START_CHAR] = 15, + [0x4f - FONT_START_CHAR] = 19, + [0x50 - FONT_START_CHAR] = 13, + [0x51 - FONT_START_CHAR] = 19, + [0x52 - FONT_START_CHAR] = 14, + [0x53 - FONT_START_CHAR] = 13, + [0x54 - FONT_START_CHAR] = 13, + [0x55 - FONT_START_CHAR] = 14, + [0x56 - FONT_START_CHAR] = 16, + [0x57 - FONT_START_CHAR] = 23, + [0x58 - FONT_START_CHAR] = 16, + [0x59 - FONT_START_CHAR] = 15, + [0x5a - FONT_START_CHAR] = 13, + [0x5b - FONT_START_CHAR] = 6, + [0x5c - FONT_START_CHAR] = 8, + [0x5d - FONT_START_CHAR] = 6, + [0x5e - FONT_START_CHAR] = 12, + [0x5f - FONT_START_CHAR] = 12, + [0x60 - FONT_START_CHAR] = 5, + [0x61 - FONT_START_CHAR] = 12, + [0x62 - FONT_START_CHAR] = 14, + [0x63 - FONT_START_CHAR] = 13, + [0x64 - FONT_START_CHAR] = 14, + [0x65 - FONT_START_CHAR] = 13, + [0x66 - FONT_START_CHAR] = 9, + [0x67 - FONT_START_CHAR] = 14, + [0x68 - FONT_START_CHAR] = 12, + [0x69 - FONT_START_CHAR] = 4, + [0x6a - FONT_START_CHAR] = 5, + [0x6b - FONT_START_CHAR] = 12, + [0x6c - FONT_START_CHAR] = 4, + [0x6d - FONT_START_CHAR] = 20, + [0x6e - FONT_START_CHAR] = 12, + [0x6f - FONT_START_CHAR] = 14, + [0x70 - FONT_START_CHAR] = 14, + [0x71 - FONT_START_CHAR] = 14, + [0x72 - FONT_START_CHAR] = 9, + [0x73 - FONT_START_CHAR] = 11, + [0x74 - FONT_START_CHAR] = 9, + [0x75 - FONT_START_CHAR] = 12, + [0x76 - FONT_START_CHAR] = 13, + [0x77 - FONT_START_CHAR] = 19, + [0x78 - FONT_START_CHAR] = 12, + [0x79 - FONT_START_CHAR] = 13, + [0x7a - FONT_START_CHAR] = 11, + [0x7b - FONT_START_CHAR] = 7, + [0x7c - FONT_START_CHAR] = 4, + [0x7d - FONT_START_CHAR] = 8, + [0x7e - FONT_START_CHAR] = 12, +}; diff --git a/src/lib/fonts/fonts.h b/src/lib/fonts/fonts.h new file mode 100644 index 00000000000..45371438c3d --- /dev/null +++ b/src/lib/fonts/fonts.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __FONTS_H__ +#define __FONTS_H__ + +#include + +/* Printable ASCII character range [32-126] */ +#define FONT_START_CHAR 32 /* ASCII Space */ +#define FONT_END_CHAR 126 /* ASCII ~ */ +#define FONT_NUM_CHARS (FONT_END_CHAR - FONT_START_CHAR + 1) + +extern const uint8_t font_table[FONT_NUM_CHARS][CONFIG_FONT_WIDTH * CONFIG_FONT_HEIGHT]; +extern const uint8_t font_widths[FONT_NUM_CHARS]; + +#endif // __FONTS_H__ diff --git a/src/lib/edid_fill_fb.c b/src/lib/framebuffer_info.c similarity index 97% rename from src/lib/edid_fill_fb.c rename to src/lib/framebuffer_info.c index a9ff31f5caf..f706377caab 100644 --- a/src/lib/edid_fill_fb.c +++ b/src/lib/framebuffer_info.c @@ -181,14 +181,13 @@ struct fb_info *fb_new_framebuffer_info_from_edid(const struct edid *edid, edid->bytes_per_line, edid->framebuffer_bits_per_pixel); } -int fill_lb_framebuffer(struct lb_framebuffer *framebuffer) +const struct lb_framebuffer *get_lb_framebuffer(void) { struct fb_info *i; list_for_each(i, list, node) { //TODO: Add support for advertising all framebuffers in this list - *framebuffer = i->fb; - return 0; + return &i->fb; } - return -1; + return NULL; } diff --git a/src/lib/render_bmp.c b/src/lib/render_bmp.c index 3a7e245ecaa..81b5876422c 100644 --- a/src/lib/render_bmp.c +++ b/src/lib/render_bmp.c @@ -10,6 +10,8 @@ #include "render_bmp.h" +#define MAX_SPLASH_TEXT_WIDTH 32 + static bool is_bmp_image_valid(struct bmp_image_header *header) { /* Check if the BMP Header Signature is valid */ @@ -487,7 +489,7 @@ void convert_bmp_to_blt(uintptr_t logo, size_t logo_size, * Returning `struct logo_coordinates` that contains the calculated x and y coordinates * for rendering the logo. */ -static struct logo_coordinates calculate_logo_coordinates( +struct logo_coordinates calculate_logo_coordinates( uint32_t horizontal_resolution, uint32_t vertical_resolution, uint32_t logo_width, uint32_t logo_height, enum fw_splash_horizontal_alignment halignment, @@ -576,7 +578,8 @@ static void get_logo_layout( if (!config || !logo_halignment || !logo_valignment || !logo_bottom_margin) return; - if (logo_type == BOOTSPLASH_LOW_BATTERY || logo_type == BOOTSPLASH_CENTER) { + if (logo_type == BOOTSPLASH_LOW_BATTERY || logo_type == BOOTSPLASH_CENTER || + logo_type == BOOTSPLASH_OFF_MODE_CHARGING) { *logo_halignment = config->halignment; *logo_valignment = config->valignment; /* Override logo alignment if the default screen orientation is not normal */ @@ -689,16 +692,14 @@ void render_logo_to_framebuffer(struct logo_config *config) if (config->framebuffer_base == 0) { /* Try to load from already populated framebuffer information */ - struct lb_framebuffer framebuffer; - memset(&framebuffer, 0, sizeof(struct lb_framebuffer)); - fill_lb_framebuffer(&framebuffer); + const struct lb_framebuffer *fb = get_lb_framebuffer(); /* Exit if framebuffer is still not available */ - if (framebuffer.physical_address == 0) + if (!fb) return; - config->framebuffer_base = framebuffer.physical_address; - config->horizontal_resolution = framebuffer.x_resolution; - config->vertical_resolution = framebuffer.y_resolution; - config->bytes_per_scanline = framebuffer.bytes_per_line; + config->framebuffer_base = fb->physical_address; + config->horizontal_resolution = fb->x_resolution; + config->vertical_resolution = fb->y_resolution; + config->bytes_per_scanline = fb->bytes_per_line; } /* @@ -709,6 +710,31 @@ void render_logo_to_framebuffer(struct logo_config *config) if (load_and_render_logo_to_framebuffer(BOOTSPLASH_LOW_BATTERY, config) != 0) { printk(BIOS_ERR, "%s: Failed to render low-battery logo.\n", __func__); } + + /* Display Text message at the footer of splash screen if supported */ + if (CONFIG(FRAMEBUFFER_SPLASH_TEXT)) { + char msg[MAX_SPLASH_TEXT_WIDTH]; + if (platform_get_splash_text(BOOTSPLASH_LOW_BATTERY, msg, MAX_SPLASH_TEXT_WIDTH)) + render_text_to_framebuffer(config, msg, BOOTSPLASH_TEXT_FOOTER); + } + return; + } + + /* + * If the device has booted due to cable power insertion aka off-mode then display + * off-mode charging user notification and bail out early. + */ + if (platform_is_off_mode_charging_active()) { + if (load_and_render_logo_to_framebuffer(BOOTSPLASH_OFF_MODE_CHARGING, config) != 0) + printk(BIOS_ERR, "%s: Failed to render off-mode charging logo.\n", __func__); + + /* Display Text message at the footer of splash screen if supported */ + if (CONFIG(FRAMEBUFFER_SPLASH_TEXT)) { + char msg[MAX_SPLASH_TEXT_WIDTH]; + if (platform_get_splash_text(BOOTSPLASH_OFF_MODE_CHARGING, msg, + MAX_SPLASH_TEXT_WIDTH)) + render_text_to_framebuffer(config, msg, BOOTSPLASH_TEXT_FOOTER); + } return; } diff --git a/src/lib/render_text.c b/src/lib/render_text.c new file mode 100644 index 00000000000..a87489a616b --- /dev/null +++ b/src/lib/render_text.c @@ -0,0 +1,251 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include + +#include "fonts/fonts.h" +#include "render_bmp.h" + +/* Major dimension for panel */ +#define PANEL_4K 3840 +#define PANEL_2K_QHD 2560 + +/* Determine scaling factor based on display resolution */ +static uint32_t get_resolution_scale(struct logo_config *config) +{ + uint32_t width = config->horizontal_resolution; + uint32_t height = config->vertical_resolution; + uint32_t major_dim = (width > height) ? width : height; + + if (major_dim >= PANEL_4K) + return 3; + else if (major_dim >= PANEL_2K_QHD) + return 2; + else /* HD / FHD Panels */ + return 1; +} + +/* Maps an unsigned character to the 8-bit alpha map (smoothing data) */ +static const uint8_t *get_glyph_data(unsigned char c) +{ + /* Range check using macros generated by Python */ + if (c < FONT_START_CHAR || c > FONT_END_CHAR) + return font_table[0]; /* Default to space character */ + + return font_table[c - FONT_START_CHAR]; +} + +/* Retrieves the pre-calculated width for a character */ +static uint8_t get_glyph_width(unsigned char c) +{ + if (c < FONT_START_CHAR || c > FONT_END_CHAR) + return font_widths[0]; + + return font_widths[c - FONT_START_CHAR]; +} + +/* + * Maps local glyph coordinates to physical framebuffer coordinates + * based on the panel's physical orientation. + */ +static inline void get_rotated_text_coords(struct logo_config *config, + uint32_t x, uint32_t y, int row, int col, uint32_t *fb_x, uint32_t *fb_y) +{ + switch (config->panel_orientation) { + case LB_FB_ORIENTATION_RIGHT_UP: + *fb_x = x + (CONFIG_FONT_HEIGHT - 1 - row); + *fb_y = y + col; + break; + case LB_FB_ORIENTATION_LEFT_UP: + *fb_x = x + row; + *fb_y = y + (CONFIG_FONT_WIDTH - 1 - col); + break; + case LB_FB_ORIENTATION_BOTTOM_UP: + *fb_x = x + (CONFIG_FONT_WIDTH - 1 - col); + *fb_y = y + (CONFIG_FONT_HEIGHT - 1 - row); + break; + default: /* LB_FB_ORIENTATION_NORMAL */ + *fb_x = x + col; + *fb_y = y + row; + break; + } +} + +/* + * Renders a single character to the framebuffer. + * @config: Framebuffer and orientation configuration. + * @c: Character to render. + * @x, @y: Starting coordinates in the virtual grid. + * @color: Primary text color. + */ +static void draw_char(struct logo_config *config, unsigned char c, uint32_t x, uint32_t y, + struct blt_pixel color, uint32_t scale) +{ + size_t pixel_size = sizeof(struct blt_pixel); + uint8_t *fb = (uint8_t *)config->framebuffer_base; + + const uint8_t *glyph = get_glyph_data(c); + uint8_t actual_width = get_glyph_width(c); + + for (int row = 0; row < CONFIG_FONT_HEIGHT; row++) { + for (int col = 0; col < actual_width; col++) { + /* Get the 8-bit alpha value (0-255) for this pixel */ + uint8_t alpha = glyph[row * CONFIG_FONT_WIDTH + col]; + + if (alpha == 0) + continue; + + /* Fill a scale x scale block for each font pixel */ + for (uint32_t sy = 0; sy < scale; sy++) { + for (uint32_t sx = 0; sx < scale; sx++) { + uint32_t fb_x, fb_y; + get_rotated_text_coords(config, x, y, + (row * scale) + sy, + (col * scale) + sx, + &fb_x, &fb_y); + + if (fb_x < config->horizontal_resolution && + fb_y < config->vertical_resolution) { + struct blt_pixel *bg = (struct blt_pixel *) + (fb + (fb_y * config->bytes_per_scanline) + (fb_x * pixel_size)); + + if (alpha == 255) { + *bg = color; + } else { + bg->Red = (uint8_t)((color.Red * alpha + bg->Red * + (255 - alpha)) / 255); + bg->Green = (uint8_t)((color.Green * alpha + bg->Green * + (255 - alpha)) / 255); + bg->Blue = (uint8_t)((color.Blue * alpha + bg->Blue * + (255 - alpha)) / 255); + } + } + } + } + } + } +} + +static bool setup_text_alignment(struct logo_config *config, + enum bootsplash_text_type type, enum fw_splash_horizontal_alignment *halign, + enum fw_splash_vertical_alignment *valign, uint32_t *margin) +{ + /* Default to center/center */ + *halign = FW_SPLASH_HALIGNMENT_CENTER; + *valign = FW_SPLASH_VALIGNMENT_CENTER; + *margin = 0; + + if (type == BOOTSPLASH_TEXT_CENTER) + return true; + + if (type != BOOTSPLASH_TEXT_FOOTER) { + printk(BIOS_ERR, "%s: Invalid text type %d\n", __func__, type); + return false; + } + + *margin = config->logo_bottom_margin; + + switch (config->panel_orientation) { + case LB_FB_ORIENTATION_RIGHT_UP: + *halign = FW_SPLASH_HALIGNMENT_LEFT; + *valign = FW_SPLASH_VALIGNMENT_CENTER; + break; + case LB_FB_ORIENTATION_LEFT_UP: + *halign = FW_SPLASH_HALIGNMENT_RIGHT; + *valign = FW_SPLASH_VALIGNMENT_CENTER; + break; + case LB_FB_ORIENTATION_BOTTOM_UP: + *halign = FW_SPLASH_HALIGNMENT_CENTER; + *valign = FW_SPLASH_VALIGNMENT_TOP; + break; + default: /* LB_FB_ORIENTATION_NORMAL */ + *halign = FW_SPLASH_HALIGNMENT_CENTER; + *valign = FW_SPLASH_VALIGNMENT_BOTTOM; + break; + } + + return true; +} + +/* + * Renders a string centered on the screen. + * @config: Framebuffer and logo configuration. + * @str: The null-terminated string to render. + * @type: Type of bootsplash text (i.e., enum bootsplash_text_type). + */ +void render_text_to_framebuffer(struct logo_config *config, const char *str, + enum bootsplash_text_type type) +{ + if (!config || !str || config->framebuffer_base == 0) + return; + + size_t len = strlen(str); + if (len == 0) + return; + + uint32_t scale = get_resolution_scale(config); + const uint32_t kerning = 1 * scale; + uint32_t total_width = 0; + + for (size_t i = 0; i < len; i++) + total_width += (get_glyph_width((unsigned char)str[i]) * scale) + kerning; + + uint32_t text_w, text_h; + enum fw_splash_horizontal_alignment halign; + enum fw_splash_vertical_alignment valign; + uint32_t margin; + + if (setup_text_alignment(config, type, &halign, &valign, &margin) == false) + return; + + if (config->panel_orientation == LB_FB_ORIENTATION_LEFT_UP || + config->panel_orientation == LB_FB_ORIENTATION_RIGHT_UP) { + text_w = CONFIG_FONT_HEIGHT * scale; + text_h = total_width; + } else { + text_w = total_width; + text_h = CONFIG_FONT_HEIGHT * scale; + } + + struct logo_coordinates coords = calculate_logo_coordinates(config->horizontal_resolution, + config->vertical_resolution, text_w, text_h, halign, valign); + + switch (config->panel_orientation) { + case LB_FB_ORIENTATION_RIGHT_UP: + coords.x += margin; + break; + case LB_FB_ORIENTATION_LEFT_UP: + coords.x -= margin; + coords.y += total_width; + break; + case LB_FB_ORIENTATION_BOTTOM_UP: + coords.x += total_width; + coords.y += margin; + break; + default: /* LB_FB_ORIENTATION_NORMAL (default) */ + coords.y -= margin; + } + + /* Text Color: White (Default) */ + struct blt_pixel text_color = { .Red = 0xff, .Green = 0xff, .Blue = 0xff }; + uint32_t cur_x = coords.x; + uint32_t cur_y = coords.y; + + /* Loop through characters and draw them */ + for (size_t i = 0; i < len; i++) { + unsigned char c = (unsigned char)str[i]; + draw_char(config, c, cur_x, cur_y, text_color, scale); + + uint32_t advance = (get_glyph_width(c) * scale) + kerning; + if (config->panel_orientation == LB_FB_ORIENTATION_RIGHT_UP) + cur_y += advance; + else if (config->panel_orientation == LB_FB_ORIENTATION_LEFT_UP) + cur_y -= advance; + else if (config->panel_orientation == LB_FB_ORIENTATION_BOTTOM_UP) + cur_x -= advance; + else + cur_x += advance; + } +} diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c index e21c4937016..5a2321815ea 100644 --- a/src/lib/selfboot.c +++ b/src/lib/selfboot.c @@ -87,6 +87,19 @@ static int load_one_segment(uint8_t *dest, return 0; break; } + case CBFS_COMPRESS_ZSTD: { + if (!CONFIG(COMPRESSED_PAYLOAD_ZSTD)) + return 0; + + printk(BIOS_DEBUG, "using ZSTD\n"); + timestamp_add_now(TS_UZSTDF_START); + len = uzstdn(src, len, dest, memsz); + timestamp_add_now(TS_UZSTDF_END); + if (!len) /* Decompression Error. */ + return 0; + break; + } + case CBFS_COMPRESS_NONE: { printk(BIOS_DEBUG, "it's not compressed!\n"); memcpy(dest, src, len); diff --git a/src/lib/smbios.c b/src/lib/smbios.c index 7da3e2ad15d..35b4d7765f3 100644 --- a/src/lib/smbios.c +++ b/src/lib/smbios.c @@ -412,6 +412,9 @@ static int smbios_write_type0(unsigned long *current, int handle) t->bios_characteristics_ext1 = BIOS_EXT1_CHARACTERISTICS_ACPI; t->bios_characteristics_ext2 = BIOS_EXT2_CHARACTERISTICS_TARGET; + if (CONFIG(PAYLOAD_EDK2)) + t->bios_characteristics_ext2 |= BIOS_EXT2_CHARACTERISTICS_UEFI_SUPPORT; + const int len = smbios_full_table_len(&t->header, t->eos); *current += len; return len; diff --git a/src/lib/spd_bin.c b/src/lib/spd_bin.c index e3108cbcfd0..2f387f38eab 100644 --- a/src/lib/spd_bin.c +++ b/src/lib/spd_bin.c @@ -4,11 +4,18 @@ #include #include #include +#include #include #include #include +#include #include +static bool is_ddr5(int dram_type) +{ + return dram_type == SPD_MEMORY_TYPE_DDR5_SDRAM; +} + void dump_spd_info(struct spd_block *blk) { u8 i; @@ -76,8 +83,14 @@ static int spd_get_banks(const uint8_t spd[], int dram_type) { static const int ddr3_banks[4] = { 8, 16, 32, 64 }; static const int ddr4_banks[10] = { 4, 8, -1, -1, 8, 16, -1, -1, 16, 32 }; - int index = (spd[SPD_DENSITY_BANKS] >> 4) & 0xf; + if (is_ddr5(dram_type)) { + /* DDR5 byte 7: BanksPerBG (bits 2:0) * BankGroups (bits 5:3) */ + int banks_per_bg = 1 << (spd[DDR5_SPD_BANKS] & 7); + int bank_groups = 1 << ((spd[DDR5_SPD_BANKS] >> 3) & 7); + return banks_per_bg * bank_groups; + } + int index = (spd[SPD_DENSITY_BANKS] >> 4) & 0xf; if (use_ddr4_params(dram_type)) { if (index >= ARRAY_SIZE(ddr4_banks)) return -1; @@ -89,8 +102,24 @@ static int spd_get_banks(const uint8_t spd[], int dram_type) } } -static int spd_get_capmb(const uint8_t spd[]) +static int spd_get_capmb(const uint8_t spd[], int dram_type) { + /* + * DDR5: byte 4 = Density (5 bits, Gb per die) + DiePerPkg (3 bits). + * Capacity in Mb per package. + */ + if (is_ddr5(dram_type)) { + static const uint8_t ddr5_density_gb[32] = { + 0, 4, 8, 12, 16, 24, 32, 48, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + static const uint8_t ddr5_die_per_pkg[8] = { 1, 0, 2, 4, 8, 16, 0, 0 }; + uint8_t density_gb = ddr5_density_gb[spd[DDR5_SPD_DENSITY_PACKAGE] & 0x1f]; + uint8_t dies = ddr5_die_per_pkg[(spd[DDR5_SPD_DENSITY_PACKAGE] >> 5) & 7]; + if (density_gb == 0 || dies == 0) + return -1; + return (int)density_gb * dies * 1024; /* Mb per package */ + } static const int spd_capmb[13] = { 1, 2, 4, 8, 16, 32, 64, 128, 48, 96, 12, 24, 72 }; int index = spd[SPD_DENSITY_BANKS] & 0xf; @@ -99,8 +128,12 @@ static int spd_get_capmb(const uint8_t spd[]) return spd_capmb[index] * 256; } -static int spd_get_rows(const uint8_t spd[]) +static int spd_get_rows(const uint8_t spd[], int dram_type) { + if (is_ddr5(dram_type)) { + /* DDR5 byte 5 bits 7:3 = row address count; rows = 16 + value */ + return 16 + ((spd[DDR5_SPD_ADDRESSING] >> 3) & 0x1f); + } static const int spd_rows[7] = { 12, 13, 14, 15, 16, 17, 18 }; int index = (spd[SPD_ADDRESSING] >> 3) & 7; if (index >= ARRAY_SIZE(spd_rows)) @@ -108,8 +141,12 @@ static int spd_get_rows(const uint8_t spd[]) return spd_rows[index]; } -static int spd_get_cols(const uint8_t spd[]) +static int spd_get_cols(const uint8_t spd[], int dram_type) { + if (is_ddr5(dram_type)) { + /* DDR5 byte 5 bits 2:0 = column address count; cols = 10 + value */ + return 10 + (spd[DDR5_SPD_ADDRESSING] & 7); + } static const int spd_cols[4] = { 9, 10, 11, 12 }; int index = spd[SPD_ADDRESSING] & 7; if (index >= ARRAY_SIZE(spd_cols)) @@ -119,6 +156,10 @@ static int spd_get_cols(const uint8_t spd[]) static int spd_get_ranks(const uint8_t spd[], int dram_type) { + if (is_ddr5(dram_type)) { + /* DDR5 byte 234 bits 5:3 = package ranks per channel; ranks = 1 + value */ + return 1 + ((spd[DDR5_SPD_MODULE_ORG] >> 3) & 7); + } static const int spd_ranks[8] = { 1, 2, 3, 4, 5, 6, 7, 8 }; int organ_offset = use_ddr4_params(dram_type) ? DDR4_ORGANIZATION : DDR3_ORGANIZATION; @@ -130,6 +171,10 @@ static int spd_get_ranks(const uint8_t spd[], int dram_type) static int spd_get_devw(const uint8_t spd[], int dram_type) { + if (is_ddr5(dram_type)) { + /* DDR5 byte 6 bits 2:0 = SDRAM I/O width; 4 << value */ + return 4 << (spd[DDR5_SPD_IO_WIDTH] & 7); + } static const int spd_devw[4] = { 4, 8, 16, 32 }; int organ_offset = use_ddr4_params(dram_type) ? DDR4_ORGANIZATION : DDR3_ORGANIZATION; @@ -141,6 +186,10 @@ static int spd_get_devw(const uint8_t spd[], int dram_type) static int spd_get_busw(const uint8_t spd[], int dram_type) { + if (is_ddr5(dram_type)) { + /* DDR5 byte 235 bits 2:0 = primary bus width; 8 << value */ + return 8 << (spd[DDR5_SPD_CHANNEL_BUS_WIDTH] & 7); + } static const int spd_busw[4] = { 8, 16, 32, 64 }; int busw_offset = use_ddr4_params(dram_type) ? DDR4_BUS_DEV_WIDTH : DDR3_BUS_DEV_WIDTH; @@ -188,12 +237,14 @@ void print_spd_info(uint8_t spd[]) size_t len; int type = spd[SPD_MEMORY_TYPE]; int banks = spd_get_banks(spd, type); - int capmb = spd_get_capmb(spd); - int rows = spd_get_rows(spd); - int cols = spd_get_cols(spd); + int capmb = spd_get_capmb(spd, type); + int rows = spd_get_rows(spd, type); + int cols = spd_get_cols(spd, type); int ranks = spd_get_ranks(spd, type); int devw = spd_get_devw(spd, type); int busw = spd_get_busw(spd, type); + int channels; + u32 size_mb; /* Module type */ printk(BIOS_INFO, "SPD: module type is %s\n", @@ -211,8 +262,16 @@ void print_spd_info(uint8_t spd[]) if (capmb > 0 && busw > 0 && devw > 0 && ranks > 0) { /* SIZE = DENSITY / 8 * BUS_WIDTH / SDRAM_WIDTH * RANKS */ - printk(BIOS_INFO, "SPD: module size is %u MB (per channel)\n", - capmb / 8 * busw / devw * ranks); + size_mb = (u32)capmb / 8 * busw / devw * ranks; + if (size_mb > 0) { + channels = 1 + (is_ddr5(type) ? ((spd[DDR5_SPD_CHANNEL_BUS_WIDTH] >> 5) & 3) : 0); + if (channels > 1) { + printk(BIOS_INFO, "SPD: module size is %u MB (%u MB per channel)\n", + size_mb, size_mb / channels); + return; + } + printk(BIOS_INFO, "SPD: module size is %u MB\n", size_mb); + } } } diff --git a/src/mainboard/amd/birman/board_glinda.fmd b/src/mainboard/amd/birman/board_glinda.fmd index 4f5598cd777..01340430cd5 100644 --- a/src/mainboard/amd/birman/board_glinda.fmd +++ b/src/mainboard/amd/birman/board_glinda.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - BIOS { +FLASH 32M { + BIOS 16M { EC_SIG 4K FMAP 4K COREBOOT(CBFS) diff --git a/src/mainboard/amd/birman/board_phoenix.fmd b/src/mainboard/amd/birman/board_phoenix.fmd index 4f5598cd777..01340430cd5 100644 --- a/src/mainboard/amd/birman/board_phoenix.fmd +++ b/src/mainboard/amd/birman/board_phoenix.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - BIOS { +FLASH 32M { + BIOS 16M { EC_SIG 4K FMAP 4K COREBOOT(CBFS) diff --git a/src/mainboard/amd/birman/chromeos_glinda.fmd b/src/mainboard/amd/birman/chromeos_glinda.fmd index 9cc4fbd0508..bf10c06c3b8 100644 --- a/src/mainboard/amd/birman/chromeos_glinda.fmd +++ b/src/mainboard/amd/birman/chromeos_glinda.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - SI_BIOS { +FLASH 32M { + SI_BIOS 16M { WP_RO 8M { EC_SIG 4K RO_VPD(PRESERVE) 16K diff --git a/src/mainboard/amd/birman/chromeos_phoenix.fmd b/src/mainboard/amd/birman/chromeos_phoenix.fmd index 9cc4fbd0508..bf10c06c3b8 100644 --- a/src/mainboard/amd/birman/chromeos_phoenix.fmd +++ b/src/mainboard/amd/birman/chromeos_phoenix.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - SI_BIOS { +FLASH 32M { + SI_BIOS 16M { WP_RO 8M { EC_SIG 4K RO_VPD(PRESERVE) 16K diff --git a/src/mainboard/amd/birman_plus/Kconfig b/src/mainboard/amd/birman_plus/Kconfig index a5291a495c9..21b8607b480 100644 --- a/src/mainboard/amd/birman_plus/Kconfig +++ b/src/mainboard/amd/birman_plus/Kconfig @@ -8,10 +8,6 @@ config BOARD_AMD_BIRMANPLUS_COMMON select DRIVERS_PCIE_RTD3_DEVICE select DRIVERS_I2C_GENERIC select MAINBOARD_HAS_CHROMEOS - select PCIEXP_ASPM - select PCIEXP_CLK_PM - select PCIEXP_COMMON_CLOCK - select PCIEXP_L1_SUB_STATE select SOC_AMD_COMMON_BLOCK_ESPI_RETAIN_PORT80_EN if !SOC_AMD_COMMON_BLOCK_SIMNOW_BUILD select SOC_AMD_COMMON_BLOCK_SIMNOW_SUPPORTED select SPI_FLASH_EXIT_4_BYTE_ADDR_MODE diff --git a/src/mainboard/amd/birman_plus/acpi/acp.asl b/src/mainboard/amd/birman_plus/acpi/acp.asl new file mode 100644 index 00000000000..6de8190112e --- /dev/null +++ b/src/mainboard/amd/birman_plus/acpi/acp.asl @@ -0,0 +1,243 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* ACP Audio Configuration */ +Scope (\_SB.PCI0.GP41.ACPD) { + + /* Global Configuration - _DSD properties for ACP device */ + Name (_DSD, Package (0x02) + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package (0x02) + { + Package (0x02) {"acp-audio-zsc-enable", 0x01}, + Package (0x02) {"acp-audio-config-flag", 0x10} + } + }) +} +Scope (\_SB.PCI0.GP41.ACPD.HDA0) { + Name (_DSD, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (2) {"acp-audio-device-interface-version",0x01}, + Package (2) {"acp-audio-device-type",0x01} + }, + + ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), + Package () + { + Package (0x02) {"acp-audio-device-eps", + Package () { "PE00","PE01"} + } + } + }) + Name (PE00, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02) {"acp-audio-ep-type", 0x0 }, + Package (0x02) {"acp-audio-ep-dsp-offload-supported",0x1}, + Package (0x02) {"acp-audio-ep-category", 0x1} + }, + + ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), + Package () + { + Package (0x02){"acp-audio-ep-format", "FMTS"}, + Package (0x02){"acp-audio-ep-apo-fx-type-ex", "EFXS"} + } + }) + Name (PE01, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02){"acp-audio-ep-type", 0x0}, + Package (0x02){"acp-audio-ep-dsp-offload-supported", 0x1}, + Package (0x02){"acp-audio-ep-category", 0x2} + }, + + ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), + Package () + { + Package (0x02){"acp-audio-ep-format", "FMTH"}, + Package (0x02){"acp-audio-ep-apo-fx-type-ex","EFXH"} + } + }) + Name (FMTS, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02){"acp-audio-ep-format-max-channels", 0x02}, + Package (0x02){"acp-audio-ep-format-sampling-frequency", + Package (){ 48000,96000} + }, + Package (0x02){"acp-audio-ep-format-bits-per-sample", + Package (){16,24} + } + } + }) + Name (FMTH, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02){"acp-audio-ep-format-max-channels", 0x02}, + Package (0x02){"acp-audio-ep-format-sampling-frequency", + Package (){ 48000,96000} + }, + Package (0x02){"acp-audio-ep-format-bits-per-sample", + Package (){16,24} + } + } + }) + Name (EFXS, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02){"{05714B44-A61C-40F0-9F72-3A2EFF40D74C}", "{00000000-0000-0000-0000-000000000000}"}, + Package (0x02){"{591689D6-7499-4444-BFDE-BA2BE1D9A5D6}", "{00000000-0000-0000-0000-000000000000}"}, + Package (0x02){"{E5E0FB95-F997-4EB4-9580-35A81438FE5B}", "{00000000-0000-0000-0000-000000000000}"} + } + }) + Name (EFXH, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02){"{591689D6-7499-4444-BFDE-BA2BE1D9A5D6}", "{00000000-0000-0000-0000-000000000000}"}, + Package (0x02){"{E5E0FB95-F997-4EB4-9580-35A81438FE5B}", "{00000000-0000-0000-0000-000000000000}"} + } + }) +} +Scope (\_SB.PCI0.GP41.ACPD.BTSC) { + Name (_DSD, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (2) {"acp-audio-device-interface-version",0x01}, + Package (2) {"acp-audio-device-type",0x04} + }, + + ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), + Package () + { + Package (0x02) {"acp-audio-device-eps", + Package () { "PE00","CE00"} + } + } + }) + Name (PE00, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02) {"acp-audio-ep-type", 0x0 }, + Package (0x02) {"acp-audio-ep-dsp-offload-supported",0x1}, + Package (0x02) {"acp-audio-ep-category", 0x1}, + Package (0x02) {"acp-audio-ep-port", 0x3}, + Package (0x02) {"acp-audio-ep-node", 0x2}, + Package (0x02) {"acp-audio-ep-capabilities", + Package (){ 0x1, 0x2, 0x4, 0x8}} + }, + + ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), + Package () + { + Package (0x02){"acp-audio-ep-format", "FMT0"}, + Package (0x02){"acp-audio-ep-apo-fx-type", "EFX0"}, + Package (0x02){"acp-audio-ep-apo-fx-type-ex","EFX1"} + } + }) + Name (FMT0, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02){"acp-audio-ep-format-max-channels", 0x02}, + Package (0x02){"acp-audio-ep-format-sampling-frequency", + Package (){ 8000,16000, 48000}}, + Package (0x02){"acp-audio-ep-format-bits-per-sample", + Package (){16}} + } + }) + Name (EFX0, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02){"acp-audio-ep-apo-efx-type", 0x0}, + Package (0x02){"acp-audio-ep-apo-mfx-type", 0x0}, + Package (0x02){"acp-audio-ep-apo-sfx-type", 0x0}, + Package (0x02){"acp-audio-ep-apo-efx-encoder-type", 0x100} + } + }) + Name (EFX1, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02){"{591689D6-7499-4444-BFDE-BA2BE1D9A5D6}", "{00000000-0000-0000-0000-000000000000}"}, + Package (0x02){"{E5E0FB95-F997-4EB4-9580-35A81438FE5B}", "{00000000-0000-0000-0000-000000000000}"}, + Package (0x02){"{09DF37AE-0217-4601-A842-DEC90EEBC68F}", "{66E5A40D-4559-4019-B0F1-5F842C7E461A}"}, + } + }) + Name (CE00, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02) {"acp-audio-ep-type", 0x1 }, + Package (0x02) {"acp-audio-ep-dsp-offload-supported",0x1}, + Package (0x02) {"acp-audio-ep-ai-noise-reduction-supported", 0x0}, + Package (0x02) {"acp-audio-ep-port", 0x3}, + Package (0x02) {"acp-audio-ep-node", 0x2} + }, + + ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), + Package () + { + Package (0x02){"acp-audio-ep-format", "FMT1"}, + Package (0x02){"acp-audio-ep-apo-fx-type", "EFX2"}, + Package (0x02){"acp-audio-ep-apo-fx-type-ex","EFX3"} + } + }) + Name (FMT1, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02){"acp-audio-ep-format-max-channels", 0x02}, + Package (0x02){"acp-audio-ep-format-sampling-frequency", + Package (){ 8000,16000}}, + Package (0x02){"acp-audio-ep-format-bits-per-sample", + Package (){16}} + } + }) + Name (EFX2, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02){"acp-audio-ep-apo-efx-type", 0x0}, + Package (0x02){"acp-audio-ep-apo-mfx-type", 0x0}, + Package (0x02){"acp-audio-ep-apo-sfx-type", 0x0}, + Package (0x02){"acp-audio-ep-apo-efx-encoder-type", 0x100} + } + }) + Name (EFX3, Package () + { + ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), + Package () + { + Package (0x02){"{65E94A28-DE71-4154-AD49-F67C7831EA4D}", "{00000000-0000-0000-0000-000000000000}"}, + Package (0x02){"{E5B78E46-DAA2-4827-8D84-F6C0C0306541}", "{00000000-0000-0000-0000-000000000000}"}, + Package (0x02){"{09DF37AE-0217-4601-A842-DEC90EEBC68F}", "{66E5A40D-4559-4019-B0F1-5F842C7E461A}"} + } + }) +} diff --git a/src/mainboard/amd/birman_plus/board_phoenix.fmd b/src/mainboard/amd/birman_plus/board_phoenix.fmd index 4f5598cd777..13354094184 100644 --- a/src/mainboard/amd/birman_plus/board_phoenix.fmd +++ b/src/mainboard/amd/birman_plus/board_phoenix.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - BIOS { +FLASH 64M { + BIOS 16M { EC_SIG 4K FMAP 4K COREBOOT(CBFS) diff --git a/src/mainboard/amd/birman_plus/chromeos_glinda.fmd b/src/mainboard/amd/birman_plus/chromeos_glinda.fmd index 9cc4fbd0508..de5bcc788fb 100644 --- a/src/mainboard/amd/birman_plus/chromeos_glinda.fmd +++ b/src/mainboard/amd/birman_plus/chromeos_glinda.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - SI_BIOS { +FLASH 64M { + SI_BIOS 16M { WP_RO 8M { EC_SIG 4K RO_VPD(PRESERVE) 16K diff --git a/src/mainboard/amd/birman_plus/chromeos_phoenix.fmd b/src/mainboard/amd/birman_plus/chromeos_phoenix.fmd index 9cc4fbd0508..de5bcc788fb 100644 --- a/src/mainboard/amd/birman_plus/chromeos_phoenix.fmd +++ b/src/mainboard/amd/birman_plus/chromeos_phoenix.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - SI_BIOS { +FLASH 64M { + SI_BIOS 16M { WP_RO 8M { EC_SIG 4K RO_VPD(PRESERVE) 16K diff --git a/src/mainboard/amd/birman_plus/devicetree_glinda.cb b/src/mainboard/amd/birman_plus/devicetree_glinda.cb index 9ec3c8fd713..2027d5b6c06 100644 --- a/src/mainboard/amd/birman_plus/devicetree_glinda.cb +++ b/src/mainboard/amd/birman_plus/devicetree_glinda.cb @@ -21,6 +21,11 @@ chip soc/amd/glinda .flash_ch_en = 0, }" + register "system_configuration" = "2" + + register "slow_ppt_limit_mW" = "45000" + register "fast_ppt_limit_mW" = "45000" + register "i2c_scl_reset" = "GPIO_I2C0_SCL | GPIO_I2C1_SCL | GPIO_I2C2_SCL | GPIO_I2C3_SCL" register "i2c[2].early_init" = "1" diff --git a/src/mainboard/amd/birman_plus/dsdt.asl b/src/mainboard/amd/birman_plus/dsdt.asl index 7b8982a645c..751b9fb9cae 100644 --- a/src/mainboard/amd/birman_plus/dsdt.asl +++ b/src/mainboard/amd/birman_plus/dsdt.asl @@ -13,4 +13,5 @@ DefinitionBlock ( #include #include + #include "acpi/acp.asl" } diff --git a/src/mainboard/amd/birman_plus/port_descriptors_glinda.c b/src/mainboard/amd/birman_plus/port_descriptors_glinda.c index b699ca8e168..a30179f4207 100644 --- a/src/mainboard/amd/birman_plus/port_descriptors_glinda.c +++ b/src/mainboard/amd/birman_plus/port_descriptors_glinda.c @@ -144,30 +144,32 @@ static uint8_t get_ddi1_type(void) const uint8_t eeprom_i2c_bus = 2; const uint8_t eeprom_i2c_address = 0x55; const uint16_t eeprom_connector_type_offset = 2; - uint8_t eeprom_connector_type_data[2]; - uint16_t connector_type; + uint16_t connector_type = 0; if (i2c_2ba_read_bytes(eeprom_i2c_bus, eeprom_i2c_address, - eeprom_connector_type_offset, eeprom_connector_type_data, - sizeof(eeprom_connector_type_data))) { + eeprom_connector_type_offset, (void *)&connector_type, + sizeof(connector_type))) { printk(BIOS_NOTICE, "Display connector type couldn't be determined. Disabling DDI1.\n"); return DDI_UNUSED_TYPE; } - connector_type = eeprom_connector_type_data[1] | eeprom_connector_type_data[0] << 8; - + /* On some NOVA cards it's LE, on some it's BE... */ switch (connector_type) { - case 0x0c: + case 0x0c00: + case 0x000c: printk(BIOS_DEBUG, "Configuring DDI1 as HDMI.\n"); return DDI_HDMI; - case 0x13: + case 0x1300: + case 0x0013: printk(BIOS_DEBUG, "Configuring DDI1 as DP.\n"); return DDI_DP; - case 0x14: + case 0x1400: + case 0x0014: printk(BIOS_DEBUG, "Configuring DDI1 as eDP.\n"); return DDI_EDP; - case 0x17: + case 0x1700: + case 0x0017: printk(BIOS_DEBUG, "Configuring DDI1 as USB-C.\n"); return DDI_DP_W_TYPEC; default: diff --git a/src/mainboard/amd/crater/Kconfig b/src/mainboard/amd/crater/Kconfig index b2fc3d63e0e..0861a216f73 100644 --- a/src/mainboard/amd/crater/Kconfig +++ b/src/mainboard/amd/crater/Kconfig @@ -2,7 +2,7 @@ config BOARD_AMD_CRATER_COMMON def_bool n - select BOARD_ROMSIZE_KB_32768 + select BOARD_ROMSIZE_KB_16384 select EC_ACPI select SOC_AMD_COMMON_BLOCK_USE_ESPI if !SOC_AMD_COMMON_BLOCK_SIMNOW_BUILD select DRIVERS_PCIE_RTD3_DEVICE diff --git a/src/mainboard/amd/mayan/board.fmd b/src/mainboard/amd/mayan/board.fmd index 2600ec75a26..6ba6b4d68fe 100644 --- a/src/mainboard/amd/mayan/board.fmd +++ b/src/mainboard/amd/mayan/board.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - BIOS { +FLASH 32M { + BIOS 16M { EC 4K FMAP 4K COREBOOT(CBFS) diff --git a/src/mainboard/amd/mayan/chromeos.fmd b/src/mainboard/amd/mayan/chromeos.fmd index b77203f5896..b819c9c3ccf 100644 --- a/src/mainboard/amd/mayan/chromeos.fmd +++ b/src/mainboard/amd/mayan/chromeos.fmd @@ -1,5 +1,5 @@ -FLASH 16M { - SI_BIOS { +FLASH 32M { + SI_BIOS 16M { WP_RO 8M { EC 4K RO_VPD(PRESERVE) 16K diff --git a/src/mainboard/asrock/Kconfig b/src/mainboard/asrock/Kconfig index 3fe439728dc..ddbe9f5b0e4 100644 --- a/src/mainboard/asrock/Kconfig +++ b/src/mainboard/asrock/Kconfig @@ -12,6 +12,6 @@ endchoice source "src/mainboard/asrock/*/Kconfig" config MAINBOARD_VENDOR - default "ASROCK" + default "ASRock" endif # VENDOR_ASROCK diff --git a/src/mainboard/asrock/Kconfig.name b/src/mainboard/asrock/Kconfig.name index a04cd2707bf..c19475ee000 100644 --- a/src/mainboard/asrock/Kconfig.name +++ b/src/mainboard/asrock/Kconfig.name @@ -1,4 +1,4 @@ ## SPDX-License-Identifier: GPL-2.0-only config VENDOR_ASROCK - bool "ASROCK" + bool "ASRock" diff --git a/src/mainboard/asrock/fatal1ty_z87_professional/mainboard.c b/src/mainboard/asrock/fatal1ty_z87_professional/mainboard.c index 1e62d65d2e8..8e30e3c61cc 100644 --- a/src/mainboard/asrock/fatal1ty_z87_professional/mainboard.c +++ b/src/mainboard/asrock/fatal1ty_z87_professional/mainboard.c @@ -10,24 +10,6 @@ #include #define GPIO1_DEV PNP_DEV(0x2e, NCT6776_WDT1_GPIO01A_V) -#define NUVOTON_ENTRY_KEY 0x87 -#define NUVOTON_EXIT_KEY 0xAA - -/* Enable configuration: pass entry key '0x87' into index port dev - * two times. */ -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_ENTRY_KEY, port); - outb(NUVOTON_ENTRY_KEY, port); -} - -/* Disable configuration: pass exit key '0xAA' into index port dev. */ -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_EXIT_KEY, port); -} static void turn_off_leds(void *unused) { diff --git a/src/mainboard/asrock/fatal1ty_z87_professional/smihandler.c b/src/mainboard/asrock/fatal1ty_z87_professional/smihandler.c index 6736c15bcd9..5ecf42409c6 100644 --- a/src/mainboard/asrock/fatal1ty_z87_professional/smihandler.c +++ b/src/mainboard/asrock/fatal1ty_z87_professional/smihandler.c @@ -7,24 +7,6 @@ #include #define GPIO1_DEV PNP_DEV(0x2e, NCT6776_WDT1_GPIO01A_V) -#define NUVOTON_ENTRY_KEY 0x87 -#define NUVOTON_EXIT_KEY 0xAA - -/* Enable configuration: pass entry key '0x87' into index port dev - * two times. */ -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_ENTRY_KEY, port); - outb(NUVOTON_ENTRY_KEY, port); -} - -/* Disable configuration: pass exit key '0xAA' into index port dev. */ -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_EXIT_KEY, port); -} void mainboard_smi_sleep(u8 slp_typ) { diff --git a/src/mainboard/asrock/z87_extreme4/mainboard.c b/src/mainboard/asrock/z87_extreme4/mainboard.c index 1e62d65d2e8..8e30e3c61cc 100644 --- a/src/mainboard/asrock/z87_extreme4/mainboard.c +++ b/src/mainboard/asrock/z87_extreme4/mainboard.c @@ -10,24 +10,6 @@ #include #define GPIO1_DEV PNP_DEV(0x2e, NCT6776_WDT1_GPIO01A_V) -#define NUVOTON_ENTRY_KEY 0x87 -#define NUVOTON_EXIT_KEY 0xAA - -/* Enable configuration: pass entry key '0x87' into index port dev - * two times. */ -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_ENTRY_KEY, port); - outb(NUVOTON_ENTRY_KEY, port); -} - -/* Disable configuration: pass exit key '0xAA' into index port dev. */ -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_EXIT_KEY, port); -} static void turn_off_leds(void *unused) { diff --git a/src/mainboard/asrock/z87_extreme4/smihandler.c b/src/mainboard/asrock/z87_extreme4/smihandler.c index d6ebcef9a0a..462316a692f 100644 --- a/src/mainboard/asrock/z87_extreme4/smihandler.c +++ b/src/mainboard/asrock/z87_extreme4/smihandler.c @@ -7,24 +7,6 @@ #include #define GPIO1_DEV PNP_DEV(0x2e, NCT6776_WDT1_GPIO01A_V) -#define NUVOTON_ENTRY_KEY 0x87 -#define NUVOTON_EXIT_KEY 0xAA - -/* Enable configuration: pass entry key '0x87' into index port dev - * two times. */ -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_ENTRY_KEY, port); - outb(NUVOTON_ENTRY_KEY, port); -} - -/* Disable configuration: pass exit key '0xAA' into index port dev. */ -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_EXIT_KEY, port); -} void mainboard_smi_sleep(u8 slp_typ) { diff --git a/src/mainboard/asus/p8x7x-series/Kconfig b/src/mainboard/asus/p8x7x-series/Kconfig index cfff67a0dc5..ee4ee3eeb27 100644 --- a/src/mainboard/asus/p8x7x-series/Kconfig +++ b/src/mainboard/asus/p8x7x-series/Kconfig @@ -106,8 +106,7 @@ config CMOS_DEFAULT_FILE config CMOS_LAYOUT_FILE default "src/mainboard/\$(MAINBOARDDIR)/variants/\$(CONFIG_VARIANT_DIR)/cmos.layout" -config SUPERIO_PNP_BASE - hex +config SUPERIO_NUVOTON_PNP_BASE default 0x2e endif diff --git a/src/mainboard/asus/p8x7x-series/acpi/platform.asl b/src/mainboard/asus/p8x7x-series/acpi/platform.asl index b5c3fc333a6..d7dcaeeec53 100644 --- a/src/mainboard/asus/p8x7x-series/acpi/platform.asl +++ b/src/mainboard/asus/p8x7x-series/acpi/platform.asl @@ -12,10 +12,12 @@ Method(_PTS, 1) { BLINK_POWER_LED = 1 } + \_SB.PCI0.LPCB.SIO0.SIOS(Arg0) } Method(_WAK, 1) { BLINK_POWER_LED = 0 + \_SB.PCI0.LPCB.SIO0.SIOW(Arg0) Return(Package(){0, 0}) } diff --git a/src/mainboard/asus/p8x7x-series/acpi/superio.asl b/src/mainboard/asus/p8x7x-series/acpi/superio.asl index 55b1db5b113..3fb0be5bef7 100644 --- a/src/mainboard/asus/p8x7x-series/acpi/superio.asl +++ b/src/mainboard/asus/p8x7x-series/acpi/superio.asl @@ -1,3 +1,31 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#define SUPERIO_DEV SIO0 +#define SUPERIO_PNP_BASE CONFIG_SUPERIO_NUVOTON_PNP_BASE -#include +/* Defines to have ASLs below make visible some devices */ +#if !CONFIG(NO_UART_ON_SUPERIO) +#define NCT677X_SHOW_SP1 +#endif + +/* TODO: Exclude next lines for variants without PS/2 port */ +#define NCT677X_SHOW_KBC +#define SUPERIO_KBC_PS2KID PS2K +#define SUPERIO_KBC_PS2MID PS2M + +/* + * This series uses one of four SIO chips: + * NCT6776 (p8c_ws) + * NCT6779D + * NCT5535D + * IT8771E (P8H77-I and P8H77-V LE, both not yet supported) + * + * Include the correct ASL file. + */ + +#if CONFIG(SUPERIO_NUVOTON_NCT6779D) +#include +#elif CONFIG(SUPERIO_NUVOTON_NCT5535D) +#include +#elif CONFIG(SUPERIO_NUVOTON_NCT6776) +#include +#endif diff --git a/src/mainboard/asus/p8x7x-series/variants/p8c_ws/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8c_ws/early_init.c index f192e22f3c4..ae3a3633f67 100644 --- a/src/mainboard/asus/p8x7x-series/variants/p8c_ws/early_init.c +++ b/src/mainboard/asus/p8x7x-series/variants/p8c_ws/early_init.c @@ -5,9 +5,9 @@ #include #include -#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, 0) -#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6776_SP1) -#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6776_ACPI) +#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, 0) +#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6776_SP1) +#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6776_ACPI) void bootblock_mainboard_early_init(void) { diff --git a/src/mainboard/asus/p8x7x-series/variants/p8h77-v/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8h77-v/early_init.c index a7f7e9f077f..69a2f4544c5 100644 --- a/src/mainboard/asus/p8x7x-series/variants/p8h77-v/early_init.c +++ b/src/mainboard/asus/p8x7x-series/variants/p8h77-v/early_init.c @@ -5,9 +5,9 @@ #include #include -#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, 0) -#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_SP1) -#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_ACPI) +#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, 0) +#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_SP1) +#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_ACPI) void bootblock_mainboard_early_init(void) { diff --git a/src/mainboard/asus/p8x7x-series/variants/p8z77-m/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8z77-m/early_init.c index 7e4647c6e21..3c6853eef4f 100644 --- a/src/mainboard/asus/p8x7x-series/variants/p8z77-m/early_init.c +++ b/src/mainboard/asus/p8x7x-series/variants/p8z77-m/early_init.c @@ -10,9 +10,9 @@ #include -#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_SP1) -#define GPIO0_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_WDT1_GPIO01_V) -#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_ACPI) +#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_SP1) +#define GPIO0_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_WDT1_GPIO01_V) +#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_ACPI) void bootblock_mainboard_early_init(void) { diff --git a/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/early_init.c index 81d9a3a9c84..c3ccf1bbde2 100644 --- a/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/early_init.c +++ b/src/mainboard/asus/p8x7x-series/variants/p8z77-m_pro/early_init.c @@ -11,7 +11,7 @@ #include #include -#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_SP1) +#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_SP1) void bootblock_mainboard_early_init(void) { diff --git a/src/mainboard/asus/p8x7x-series/variants/p8z77-v/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8z77-v/early_init.c index f693fbcb180..e2ab6e0d017 100644 --- a/src/mainboard/asus/p8x7x-series/variants/p8z77-v/early_init.c +++ b/src/mainboard/asus/p8x7x-series/variants/p8z77-v/early_init.c @@ -2,12 +2,28 @@ #include #include +#include #include #include -#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, 0) -#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_SP1) -#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_ACPI) +#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, 0) +#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_SP1) +#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_ACPI) + +void mainboard_late_rcba_config(void) +{ + RCBA32(D31IP) = (INTC << D31IP_TTIP) | (INTB << D31IP_SIP2) | + (INTC << D31IP_SMIP) | (INTB << D31IP_SIP); + RCBA32(D22IP) = (INTB << D22IP_KTIP) | (INTC << D22IP_IDERIP) | + (INTB << D22IP_MEI2IP) | (INTA << D22IP_MEI1IP); + + DIR_ROUTE(D31IR, PIRQA, PIRQC, PIRQD, PIRQA); + DIR_ROUTE(D29IR, PIRQH, PIRQD, PIRQA, PIRQC); + DIR_ROUTE(D27IR, PIRQG, PIRQB, PIRQC, PIRQD); + DIR_ROUTE(D26IR, PIRQA, PIRQF, PIRQC, PIRQD); + DIR_ROUTE(D25IR, PIRQE, PIRQF, PIRQG, PIRQH); + DIR_ROUTE(D22IR, PIRQA, PIRQD, PIRQC, PIRQB); +} void bootblock_mainboard_early_init(void) { diff --git a/src/mainboard/asus/p8x7x-series/variants/p8z77-v_lx2/early_init.c b/src/mainboard/asus/p8x7x-series/variants/p8z77-v_lx2/early_init.c index a7f7e9f077f..69a2f4544c5 100644 --- a/src/mainboard/asus/p8x7x-series/variants/p8z77-v_lx2/early_init.c +++ b/src/mainboard/asus/p8x7x-series/variants/p8z77-v_lx2/early_init.c @@ -5,9 +5,9 @@ #include #include -#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, 0) -#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_SP1) -#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_PNP_BASE, NCT6779D_ACPI) +#define GLOBAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, 0) +#define SERIAL_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_SP1) +#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT6779D_ACPI) void bootblock_mainboard_early_init(void) { diff --git a/src/mainboard/emulation/qemu-i440fx/dsdt.asl b/src/mainboard/emulation/qemu-i440fx/dsdt.asl index 749ecfe664c..89f9d5fad04 100644 --- a/src/mainboard/emulation/qemu-i440fx/dsdt.asl +++ b/src/mainboard/emulation/qemu-i440fx/dsdt.asl @@ -218,16 +218,17 @@ DefinitionBlock ( } Return (0x0B) } + Method(IQCR, 1, Serialized) { // _CRS method - get current settings - Name(PRR0, ResourceTemplate() { - Interrupt(, Level, ActiveHigh, Shared) { 0 } - }) - CreateDWordField(PRR0, 0x05, PRRI) + Local0 = ResourceTemplate() { + Interrupt(, Level, ActiveHigh, Shared,,, IRQ0) { 0 } + } + CreateDWordField(Local0, IRQ0._INT, IRQV) If (Arg0 < 0x80) { - PRRI = Arg0 + IRQV = Arg0 } - Return (PRR0) + Return (Local0) } #define define_link(link, uid, reg) \ diff --git a/src/mainboard/emulation/qemu-q35/dsdt.asl b/src/mainboard/emulation/qemu-q35/dsdt.asl index d65f2de0ec0..da809d6e611 100644 --- a/src/mainboard/emulation/qemu-q35/dsdt.asl +++ b/src/mainboard/emulation/qemu-q35/dsdt.asl @@ -291,14 +291,15 @@ DefinitionBlock ( } Return (0x0B) } + Method(IQCR, 1, Serialized) { // _CRS method - get current settings - Name(PRR0, ResourceTemplate() { - Interrupt(, Level, ActiveHigh, Shared) { 0 } - }) - CreateDWordField(PRR0, 0x05, PRRI) - PRRI = Arg0 & 0x0F - Return (PRR0) + Local0 = ResourceTemplate() { + Interrupt(, Level, ActiveHigh, Shared,,, IRQ0) { 0 } + } + CreateDWordField(Local0, IRQ0._INT, IRQV) + IRQV = Arg0 & 0x0F + Return (Local0) } #define define_link(link, uid, reg) \ @@ -350,6 +351,8 @@ DefinitionBlock ( }) \ Method(_SRS, 1, NotSerialized) { \ } \ + Method(_DIS, 0, NotSerialized) { \ + } \ } define_gsi_link(GSIA, 0, 0x10) diff --git a/src/mainboard/google/asurada/Kconfig.name b/src/mainboard/google/asurada/Kconfig.name index 278655180ee..159b11e3809 100644 --- a/src/mainboard/google/asurada/Kconfig.name +++ b/src/mainboard/google/asurada/Kconfig.name @@ -1,12 +1,12 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Asurada" +comment "Asurada (MediaTek Kompanio 820 (MT8192))" config BOARD_GOOGLE_ASURADA bool "-> Asurada" config BOARD_GOOGLE_HAYATO - bool "-> Hayato" + bool "-> Hayato (ASUS Chromebook Flip CM3 (CM3200))" config BOARD_GOOGLE_SPHERION bool "-> Spherion (Acer Chromebook 514 (CB514-2H, CB514-2HT))" diff --git a/src/mainboard/google/auron/Kconfig b/src/mainboard/google/auron/Kconfig index b84708f6571..10d9a35191c 100644 --- a/src/mainboard/google/auron/Kconfig +++ b/src/mainboard/google/auron/Kconfig @@ -9,6 +9,7 @@ config BOARD_GOOGLE_BASEBOARD_AURON select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_LPC + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_OPTION_TABLE @@ -70,6 +71,9 @@ config MAINBOARD_PART_NUMBER config OVERRIDE_DEVICETREE default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" +config CBFS_SIZE + default 0x600000 + config MAINBOARD_SMBIOS_MANUFACTURER string default "GOOGLE" diff --git a/src/mainboard/google/auron/Kconfig.name b/src/mainboard/google/auron/Kconfig.name index 1db2149b4cd..953228e73cb 100644 --- a/src/mainboard/google/auron/Kconfig.name +++ b/src/mainboard/google/auron/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Auron" +comment "Auron (Intel Broadwell (5th Gen))" config BOARD_GOOGLE_AURON_PAINE bool "-> Auron_Paine (Acer C740 Chromebook)" diff --git a/src/mainboard/google/auron/cfr.c b/src/mainboard/google/auron/cfr.c index 90106a5586d..dea0e812be9 100644 --- a/src/mainboard/google/auron/cfr.c +++ b/src/mainboard/google/auron/cfr.c @@ -5,15 +5,11 @@ #include #include -static const struct sm_object touchscreen = SM_DECLARE_ENUM({ +static const struct sm_object touchscreen = SM_DECLARE_BOOL({ .opt_name = "touchscreen", .ui_name = "Touchscreen", .ui_helptext = "Enable or disable the integrated touchscreen device", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, #if !CONFIG(BOARD_GOOGLE_LULU) .flags = CFR_OPTFLAG_SUPPRESS, #endif diff --git a/src/mainboard/google/auron/devicetree.cb b/src/mainboard/google/auron/devicetree.cb index 49db5187606..3534ac9ea25 100644 --- a/src/mainboard/google/auron/devicetree.cb +++ b/src/mainboard/google/auron/devicetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell # IGD Displays register "gfx" = "GMA_STATIC_DISPLAYS(0)" @@ -15,7 +15,7 @@ chip soc/intel/broadwell register "ec_present" = "true" chip cpu/intel/haswell - device cpu_cluster 0 on ops broadwell_cpu_bus_ops end + device cpu_cluster 0 on ops haswell_cpu_bus_ops end register "s0ix_enable" = "true" end @@ -26,7 +26,7 @@ chip soc/intel/broadwell device pci 02.0 on end # vga controller device pci 03.0 on end # mini-hd audio - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # EC range is 0x800-0x9ff register "gen1_dec" = "0x00fc0801" register "gen2_dec" = "0x00fc0901" diff --git a/src/mainboard/google/auron/dsdt.asl b/src/mainboard/google/auron/dsdt.asl index ba7f1e43242..eebeeeacee5 100644 --- a/src/mainboard/google/auron/dsdt.asl +++ b/src/mainboard/google/auron/dsdt.asl @@ -11,13 +11,13 @@ DefinitionBlock( ) { #include - #include + #include // Thermal handler #include "acpi/thermal.asl" // global NVS and variables - #include + #include // CPU #include @@ -26,7 +26,7 @@ DefinitionBlock( Device (PCI0) { #include - #include + #include #include } } diff --git a/src/mainboard/google/auron/variants/auron_paine/overridetree.cb b/src/mainboard/google/auron/variants/auron_paine/overridetree.cb index 62e42b17188..b18f1d77a31 100644 --- a/src/mainboard/google/auron/variants/auron_paine/overridetree.cb +++ b/src/mainboard/google/auron/variants/auron_paine/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell register "panel_cfg" = "{ .up_delay_ms = 40, @@ -10,7 +10,7 @@ chip soc/intel/broadwell }" device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # DTLE DATA / EDGE values register "sata_port0_gen3_dtle" = "0x5" register "sata_port1_gen3_dtle" = "0x5" diff --git a/src/mainboard/google/auron/variants/auron_yuna/overridetree.cb b/src/mainboard/google/auron/variants/auron_yuna/overridetree.cb index 174463d0b7d..d6586431300 100644 --- a/src/mainboard/google/auron/variants/auron_yuna/overridetree.cb +++ b/src/mainboard/google/auron/variants/auron_yuna/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell register "panel_cfg" = "{ .up_delay_ms = 40, @@ -10,7 +10,7 @@ chip soc/intel/broadwell }" device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # DTLE DATA / EDGE values register "sata_port0_gen3_dtle" = "0x7" register "sata_port1_gen3_dtle" = "0x5" diff --git a/src/mainboard/google/auron/variants/buddy/overridetree.cb b/src/mainboard/google/auron/variants/buddy/overridetree.cb index d1e217b8aaf..81fecac9c76 100644 --- a/src/mainboard/google/auron/variants/buddy/overridetree.cb +++ b/src/mainboard/google/auron/variants/buddy/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell register "panel_cfg" = "{ .up_delay_ms = 40, @@ -18,7 +18,7 @@ chip soc/intel/broadwell end device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint register "sata_devslp_disable" = "0x1" register "sio_i2c0_voltage" = "1" # 1.8V diff --git a/src/mainboard/google/auron/variants/gandof/overridetree.cb b/src/mainboard/google/auron/variants/gandof/overridetree.cb index ca5d6166590..c74f9f80b4e 100644 --- a/src/mainboard/google/auron/variants/gandof/overridetree.cb +++ b/src/mainboard/google/auron/variants/gandof/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell register "panel_cfg" = "{ .up_delay_ms = 40, @@ -10,7 +10,7 @@ chip soc/intel/broadwell }" device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # DTLE DATA / EDGE values register "sata_port0_gen3_dtle" = "0x5" register "sata_port1_gen3_dtle" = "0x5" diff --git a/src/mainboard/google/auron/variants/lulu/overridetree.cb b/src/mainboard/google/auron/variants/lulu/overridetree.cb index 62e42b17188..b18f1d77a31 100644 --- a/src/mainboard/google/auron/variants/lulu/overridetree.cb +++ b/src/mainboard/google/auron/variants/lulu/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell register "panel_cfg" = "{ .up_delay_ms = 40, @@ -10,7 +10,7 @@ chip soc/intel/broadwell }" device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # DTLE DATA / EDGE values register "sata_port0_gen3_dtle" = "0x5" register "sata_port1_gen3_dtle" = "0x5" diff --git a/src/mainboard/google/auron/variants/samus/overridetree.cb b/src/mainboard/google/auron/variants/samus/overridetree.cb index b0b8a603f61..013c3133eab 100644 --- a/src/mainboard/google/auron/variants/samus/overridetree.cb +++ b/src/mainboard/google/auron/variants/samus/overridetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell # Enable DDI2 Hotplug with 6ms pulse register "gpu_dp_c_hotplug" = "0x06" @@ -26,7 +26,7 @@ chip soc/intel/broadwell end device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint register "sata_port0_gen3_tx" = "0x72" # Set I2C0 to 1.8V diff --git a/src/mainboard/google/beltino/Kconfig b/src/mainboard/google/beltino/Kconfig index 9f061c2aaeb..0b5be0d5351 100644 --- a/src/mainboard/google/beltino/Kconfig +++ b/src/mainboard/google/beltino/Kconfig @@ -66,6 +66,9 @@ config MAINBOARD_FAMILY config INTEL_GMA_VBT_FILE default "src/mainboard/\$(MAINBOARDDIR)/data.vbt" if !BOARD_GOOGLE_MONROE +config CBFS_SIZE + default 0x600000 + config MAINBOARD_SMBIOS_MANUFACTURER string default "GOOGLE" diff --git a/src/mainboard/google/beltino/Kconfig.name b/src/mainboard/google/beltino/Kconfig.name index a794330c63b..fe9dc278141 100644 --- a/src/mainboard/google/beltino/Kconfig.name +++ b/src/mainboard/google/beltino/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Beltino" +comment "Beltino (Intel Haswell (4th Gen))" config BOARD_GOOGLE_MCCLOUD bool "-> Mccloud (Acer Chromebox CXI)" diff --git a/src/mainboard/google/bluey/Kconfig b/src/mainboard/google/bluey/Kconfig index 8c902026439..d5ecf88a263 100644 --- a/src/mainboard/google/bluey/Kconfig +++ b/src/mainboard/google/bluey/Kconfig @@ -31,6 +31,7 @@ config BOARD_GOOGLE_MODEL_QUENBI def_bool n select BOARD_GOOGLE_BASEBOARD_BLUEY select BOARD_ROMSIZE_KB_32768 + select EC_GOOGLE_CHROMEEC_BATTERY_SOC_DYNAMIC select MAINBOARD_HAS_CHROME_EC select MAINBOARD_HAS_FINGERPRINT_VIA_SPI select MAINBOARD_HAS_GOOGLE_TPM @@ -39,6 +40,7 @@ config BOARD_GOOGLE_MODEL_QUARTZ def_bool n select BOARD_GOOGLE_BASEBOARD_BLUEY select BOARD_ROMSIZE_KB_32768 + select EC_GOOGLE_CHROMEEC_BATTERY_SOC_DYNAMIC select MAINBOARD_HAS_CHROME_EC select MAINBOARD_HAS_FINGERPRINT_VIA_SPI select MAINBOARD_HAS_GOOGLE_TPM @@ -53,10 +55,25 @@ config BOARD_GOOGLE_QUENBIH config BOARD_GOOGLE_QUARTZ select BOARD_GOOGLE_MODEL_QUARTZ + select HAVE_CHARGING_DEBUG_ACCESS_PORT select SOC_QUALCOMM_HAMOA + select MAINBOARD_HAS_PS8820_RETIMER select MAINBOARD_NO_USB_A_PORT select MAINBOARD_SUPPORTS_PARALLEL_CHARGING +config BOARD_GOOGLE_MODEL_MICA + def_bool n + select BOARD_GOOGLE_BASEBOARD_BLUEY + select BOARD_ROMSIZE_KB_32768 + select EC_GOOGLE_CHROMEEC_BATTERY_SOC_DYNAMIC + select MAINBOARD_HAS_CHROME_EC + select MAINBOARD_HAS_FINGERPRINT_VIA_USB + select MAINBOARD_HAS_GOOGLE_TPM + +config BOARD_GOOGLE_MICA + select BOARD_GOOGLE_MODEL_MICA + select SOC_QUALCOMM_HAMOA + if BOARD_GOOGLE_BLUEY_COMMON config MAINBOARD_DIR @@ -89,6 +106,12 @@ config MAINBOARD_HAS_SD_CONTROLLER help Enable this option if your mainboard is equipped with SD card controller. +config MAINBOARD_HAS_PS8820_RETIMER + bool + default n + help + Enable this option if your mainboard is equipped with a PS8820 retimer. + config MAINBOARD_NO_USB_A_PORT bool default n @@ -101,6 +124,12 @@ config MAINBOARD_SUPPORTS_PARALLEL_CHARGING help Enable this option if your mainboard supports parallel charging. +config HAVE_CHARGING_DEBUG_ACCESS_PORT + bool + default n + help + Enable this option to allow charging on the debug access port. + config MAINBOARD_HAS_GOOGLE_TPM bool default n @@ -127,6 +156,7 @@ config MAINBOARD_VENDOR config VBOOT select VBOOT_ALWAYS_ENABLE_DISPLAY + select VBOOT_LID_SWITCH if MAINBOARD_HAS_CHROME_EC select VBOOT_NO_BOARD_SUPPORT if BOARD_GOOGLE_MODEL_BLUEY select VBOOT_VBNV_FLASH @@ -139,12 +169,14 @@ config MAINBOARD_PART_NUMBER default "Quenbi" if BOARD_GOOGLE_QUENBI default "QuenbiH" if BOARD_GOOGLE_QUENBIH default "Quartz" if BOARD_GOOGLE_MODEL_QUARTZ + default "Mica" if BOARD_GOOGLE_MODEL_MICA config DRIVER_TPM_I2C_BUS depends on I2C_TPM hex default 0xa if BOARD_GOOGLE_MODEL_QUENBI default 0xa if BOARD_GOOGLE_MODEL_QUARTZ + default 0xa if BOARD_GOOGLE_MODEL_MICA default 0x10 config DRIVER_TPM_I2C_ADDR @@ -155,6 +187,7 @@ config EC_GOOGLE_CHROMEEC_SPI_BUS hex default 0xd if BOARD_GOOGLE_MODEL_QUENBI default 0xd if BOARD_GOOGLE_MODEL_QUARTZ + default 0xd if BOARD_GOOGLE_MODEL_MICA default 0xb config MAINBOARD_GPIO_PIN_FOR_TOUCHPAD_POWER @@ -170,10 +203,15 @@ config MAINBOARD_GPIO_PIN_FOR_GSC_AP_INTERRUPT int default 91 if BOARD_GOOGLE_MODEL_QUENBI default 91 if BOARD_GOOGLE_MODEL_QUARTZ + default 91 if BOARD_GOOGLE_MODEL_MICA default 34 help This option specifies the GPIO pin number on the mainboard that is used for the interrupt line from the Google Security Chip (GSC) to the Application Processor (AP). +config FMDFILE + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/chromeos-nogsc.fmd" if BOARD_GOOGLE_MODEL_BLUEY + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/chromeos.fmd" + endif # BOARD_GOOGLE_BLUEY_COMMON diff --git a/src/mainboard/google/bluey/Kconfig.name b/src/mainboard/google/bluey/Kconfig.name index 3925717a655..25009d7be01 100644 --- a/src/mainboard/google/bluey/Kconfig.name +++ b/src/mainboard/google/bluey/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Bluey" +comment "Bluey (Qualcomm Snapdragon X Plus (X1P-42-100))" config BOARD_GOOGLE_BLUEY bool "-> Bluey" @@ -16,3 +16,6 @@ config BOARD_GOOGLE_QUENBIH config BOARD_GOOGLE_QUARTZ bool "-> Quartz" + +config BOARD_GOOGLE_MICA + bool "-> Mica" diff --git a/src/mainboard/google/bluey/board.h b/src/mainboard/google/bluey/board.h index 40e63791dc6..0544381e690 100644 --- a/src/mainboard/google/bluey/board.h +++ b/src/mainboard/google/bluey/board.h @@ -35,15 +35,31 @@ #define GPIO_PANEL_POWER_ON GPIO(70) #define GPIO_PANEL_HPD GPIO(119) +/* Charging GPIOs */ +#define GPIO_PARALLEL_CHARGING_CFG GPIO(71) + /* SD card specific GPIOs. Only for SD-enabled devices. */ #if CONFIG(MAINBOARD_HAS_SD_CONTROLLER) #define GPIO_SD_CD_L GPIO(71) #endif +/* USB Camera specific GPIOs */ +#define GPIO_USB_CAM_RESET_L GPIO(10) +#define GPIO_USB_CAM_ENABLE GPIO(206) + +/* USB-C1 port specific GPIOs */ +#define GPIO_USB_C1_EN_PP3300 GPIO(186) +#define GPIO_USB_C1_EN_PP1800 GPIO(175) +#define GPIO_USB_C1_EN_PP0900 GPIO(188) +#define GPIO_USB_C1_RETIMER_RESET_L GPIO(176) + void setup_chromeos_gpios(void); bool is_off_mode(void); void configure_parallel_charging(void); +void configure_parallel_charging_late(void); +void configure_charging_debug_access(void); void enable_slow_battery_charging(void); void disable_slow_battery_charging(void); +void launch_charger_applet(void); #endif /* MAINBOARD_GOOGLE_BLUEY_BOARD_H */ diff --git a/src/mainboard/google/bluey/charging.c b/src/mainboard/google/bluey/charging.c index 9d53372f9b2..f81d5b96502 100644 --- a/src/mainboard/google/bluey/charging.c +++ b/src/mainboard/google/bluey/charging.c @@ -1,8 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include "board.h" + +#include +#include +#include #include #include +#include #include #define SMB1_SLAVE_ID 0x07 @@ -11,15 +16,18 @@ #define SMB1_CHGR_MAX_FCC_CFG ((SMB1_SLAVE_ID << 16) | SCHG_CHGR_MAX_FAST_CHARGE_CURRENT_CFG) #define SMB2_CHGR_MAX_FCC_CFG ((SMB2_SLAVE_ID << 16) | SCHG_CHGR_MAX_FAST_CHARGE_CURRENT_CFG) #define SCHG_CHGR_CHARGING_ENABLE_CMD 0x2642 +#define SCHG_TYPE_C_TYPE_C_DEBUG_ACCESS_SNK_CFG 0x2B4A #define SMB1_CHGR_CHRG_EN_CMD ((SMB1_SLAVE_ID << 16) | SCHG_CHGR_CHARGING_ENABLE_CMD) #define SMB2_CHGR_CHRG_EN_CMD ((SMB2_SLAVE_ID << 16) | SCHG_CHGR_CHARGING_ENABLE_CMD) +#define SMB1_SCHG_TYPE_C_TYPE_C_DEBUG_ACCESS_SNK_CFG \ +((SMB1_SLAVE_ID << 16) | SCHG_TYPE_C_TYPE_C_DEBUG_ACCESS_SNK_CFG) +#define SCHG_CHGR_CHARGING_FCC 0x260A +#define SMB1_CHGR_CHARGING_FCC ((SMB1_SLAVE_ID << 16) | SCHG_CHGR_CHARGING_FCC) +#define SMB2_CHGR_CHARGING_FCC ((SMB2_SLAVE_ID << 16) | SCHG_CHGR_CHARGING_FCC) #define FCC_1A_STEP_50MA 0x14 - -enum charging_status { - CHRG_DISABLE, - CHRG_ENABLE, -}; +#define FCC_DISABLE 0x8c +#define EN_DEBUG_ACCESS_SNK 0x1B #define PMC8380F_SLAVE_ID 0x05 #define GPIO07_MODE_CTL 0x8E40 @@ -33,6 +41,103 @@ enum charging_status { #define OUTPUT_INVERT 0x80 #define PERPH_EN 0x80 +#define DELAY_CHARGING_APPLET_MS 2000 /* 2sec */ +#define CHARGING_RAIL_STABILIZATION_DELAY_MS 3000 /* 3sec */ + +enum charging_status { + CHRG_DISABLE, + CHRG_ENABLE, +}; + +static int get_battery_icurr_ma(void) +{ + /* Read battery i-current value */ + int icurr = spmi_read8(SMB1_CHGR_CHARGING_FCC); + if (icurr <= 0) + icurr = spmi_read8(SMB2_CHGR_CHARGING_FCC); + if (icurr < 0) + icurr = 0; + + icurr *= 50; + return icurr; +} + +static void clear_ec_manual_poweron_event(void) +{ + const uint64_t manual_pwron_event_mask = + (EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON) | + EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)); + google_chromeec_clear_events_b(manual_pwron_event_mask); +} + +static int detect_ec_manual_poweron_event(void) +{ + const uint64_t manual_pwron_event_mask = + (EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON) | + EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)); + uint64_t events = google_chromeec_get_events_b(); + + if (!!(events & manual_pwron_event_mask)) + return 1; + + return 0; +} + +void launch_charger_applet(void) +{ + if (!CONFIG(EC_GOOGLE_CHROMEEC)) + return; + + static const long charging_enable_timeout_ms = CHARGING_RAIL_STABILIZATION_DELAY_MS; + struct stopwatch sw; + + printk(BIOS_INFO, "Inside %s. Initiating charging\n", __func__); + + /* clear any pending power button press and lid open event */ + clear_ec_manual_poweron_event(); + + stopwatch_init_msecs_expire(&sw, charging_enable_timeout_ms); + while (!get_battery_icurr_ma()) { + if (stopwatch_expired(&sw)) { + printk(BIOS_WARNING, "Charging not enabled %ld ms. Abort.\n", + charging_enable_timeout_ms); + return; + } + mdelay(200); + } + printk(BIOS_INFO, "Charging ready after %lld ms\n", stopwatch_duration_msecs(&sw)); + + do { + /* Add static delay before reading the charging applet pre-requisites */ + mdelay(DELAY_CHARGING_APPLET_MS); + + /* + * Issue a shutdown if not charging. + */ + if (!get_battery_icurr_ma()) { + printk(BIOS_INFO, "Issuing power-off due to change in charging state.\n"); + google_chromeec_offmode_heartbeat(); + google_chromeec_ap_poweroff(); + } + + /* + * Exit the charging loop in the event of lid open or power + * button press. + * + * Reset the device to ensure a fresh boot to OS. + * This is required to avoid any kind of tear-down due to ADSP-lite + * being loaded and need some clean up before loading ADSP firmware by + * linux kernel. + */ + if (detect_ec_manual_poweron_event()) { + printk(BIOS_INFO, "Exiting charging applet to boot to OS\n"); + do_board_reset(); + } + + /* TODO: add Tsense support and issue a shutdown in the event of temperature trip */ + } while (true); +} + /* * Enable PMC8380F GPIO07 & GPIO09 for parallel charging. */ @@ -42,12 +147,35 @@ void configure_parallel_charging(void) return; printk(BIOS_INFO, "Configure parallel charging support\n"); - spmi_write8(SPMI_ADDR(PMC8380F_SLAVE_ID, GPIO07_MODE_CTL), MODE_OUTPUT); spmi_write8(SPMI_ADDR(PMC8380F_SLAVE_ID, GPIO07_DIG_OUT_SOURCE_CTL), OUTPUT_INVERT); spmi_write8(SPMI_ADDR(PMC8380F_SLAVE_ID, GPIO07_EN_CTL), PERPH_EN); - spmi_write8(SPMI_ADDR(PMC8380F_SLAVE_ID, GPIO09_MODE_CTL), MODE_OUTPUT); + spmi_write8(SPMI_ADDR(PMC8380F_SLAVE_ID, GPIO07_MODE_CTL), MODE_OUTPUT); spmi_write8(SPMI_ADDR(PMC8380F_SLAVE_ID, GPIO09_DIG_OUT_SOURCE_CTL), OUTPUT_INVERT); spmi_write8(SPMI_ADDR(PMC8380F_SLAVE_ID, GPIO09_EN_CTL), PERPH_EN); + spmi_write8(SPMI_ADDR(PMC8380F_SLAVE_ID, GPIO09_MODE_CTL), MODE_OUTPUT); +} + +/* + * Enable SMB1 charging debug access port. + */ +void configure_charging_debug_access(void) +{ + if (!CONFIG(HAVE_CHARGING_DEBUG_ACCESS_PORT)) + return; + + printk(BIOS_INFO, "Enable charging debug access port support\n"); + spmi_write8(SMB1_SCHG_TYPE_C_TYPE_C_DEBUG_ACCESS_SNK_CFG, EN_DEBUG_ACCESS_SNK); +} + +/* + * Late configuration for parallel charging. + */ +void configure_parallel_charging_late(void) +{ + if (!CONFIG(MAINBOARD_SUPPORTS_PARALLEL_CHARGING)) + return; + + gpio_output(GPIO_PARALLEL_CHARGING_CFG, 1); } /* @@ -71,4 +199,6 @@ void disable_slow_battery_charging(void) printk(BIOS_INFO, "Disable slow charge support\n"); spmi_write8(SMB1_CHGR_CHRG_EN_CMD, CHRG_DISABLE); spmi_write8(SMB2_CHGR_CHRG_EN_CMD, CHRG_DISABLE); + spmi_write8(SMB1_CHGR_MAX_FCC_CFG, FCC_DISABLE); + spmi_write8(SMB2_CHGR_MAX_FCC_CFG, FCC_DISABLE); } diff --git a/src/mainboard/google/bluey/chromeos-nogsc.fmd b/src/mainboard/google/bluey/chromeos-nogsc.fmd new file mode 100644 index 00000000000..cd3caa84f20 --- /dev/null +++ b/src/mainboard/google/bluey/chromeos-nogsc.fmd @@ -0,0 +1,45 @@ +## SPDX-License-Identifier: GPL-2.0-only + +FLASH@0x0 CONFIG_ROM_SIZE { + WP_RO 8M { + RO_SECTION { + BOOTBLOCK 512K + FMAP 4K + COREBOOT(CBFS) + GBB 0x2f00 + RO_FRID 0x100 + } + RO_VPD(PRESERVE) 16K + } + + RW_MISC 184K { + UNIFIED_MRC_CACHE(PRESERVE) 128K { + RECOVERY_MRC_CACHE 64K + RW_MRC_CACHE 64K + } + RW_ELOG(PRESERVE) 4K + RW_SHARED 4K { + SHARED_DATA + } + RW_VPD(PRESERVE) 32K + RW_NVRAM(PRESERVE) 16K + } + + RW_SECTION_A 8704K { + VBLOCK_A 8K + FW_MAIN_A(CBFS) + RW_FWID_A 256 + } + + RW_SECTION_B 8704K { + VBLOCK_B 8K + FW_MAIN_B(CBFS) + RW_FWID_B 256 + } + + RW_LEGACY(CBFS) + + RW_UNUSED 3840K + + RW_CDT 256K +} diff --git a/src/mainboard/google/bluey/chromeos.fmd b/src/mainboard/google/bluey/chromeos.fmd index 98f03b58517..b70b49811df 100644 --- a/src/mainboard/google/bluey/chromeos.fmd +++ b/src/mainboard/google/bluey/chromeos.fmd @@ -1,7 +1,7 @@ ## SPDX-License-Identifier: GPL-2.0-only FLASH@0x0 CONFIG_ROM_SIZE { - WP_RO 12M { + WP_RO 8M { RO_SECTION { BOOTBLOCK 512K FMAP 4K @@ -26,17 +26,19 @@ FLASH@0x0 CONFIG_ROM_SIZE { RW_NVRAM(PRESERVE) 16K } - RW_SECTION_A 4608K { + RW_SECTION_A 8704K { VBLOCK_A 8K FW_MAIN_A(CBFS) RW_FWID_A 256 } - RW_SECTION_B 4608K { + RW_SECTION_B 8704K { VBLOCK_B 8K FW_MAIN_B(CBFS) RW_FWID_B 256 } + RW_UNUSED 4M + RW_LEGACY(CBFS) } diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index 7b31a8cba63..ac80ceef80c 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -2,19 +2,50 @@ #include #include +#include +#include #include #include #include #include +#include #include +#include #include #include +#include #include #include +#include #include #include "board.h" +#include #include +#define C0_RETIMER_I2C_BUS 0x03 +#define C1_RETIMER_I2C_BUS 0x07 +#define PS8820_SLAVE_ADDR 0x08 + +#define PS8820_USB_PORT_CONN_STATUS_REG 0x00 +#define USB3_MODE_NORMAL_VAL 0x21 +#define USB3_MODE_FLIP_VAL 0x23 + +void mainboard_usb_typec_configure(uint8_t port_num, bool inverse_polarity) +{ + if (!CONFIG(MAINBOARD_HAS_PS8820_RETIMER)) + return; + + /* There are only two ports (0 and 1) */ + if (port_num > 1) { + printk(BIOS_WARNING, "Invalid USB Type-C port number (%d)!\n", port_num); + return; + } + + uint8_t bus = port_num ? C1_RETIMER_I2C_BUS : C0_RETIMER_I2C_BUS; + uint8_t mode_value = inverse_polarity ? USB3_MODE_FLIP_VAL : USB3_MODE_NORMAL_VAL; + i2c_writeb(bus, PS8820_SLAVE_ADDR, PS8820_USB_PORT_CONN_STATUS_REG, mode_value); +} + /* * This function calls the underlying PMIC/EC function only once during the * first execution and caches the result for all subsequent calls. @@ -33,20 +64,52 @@ static enum boot_mode_t get_boot_mode(void) return boot_mode; } -static bool is_low_power_boot(void) +static bool is_low_power_boot_with_charger(void) { + bool ret = false; enum boot_mode_t boot_mode = get_boot_mode(); - if ((boot_mode == LB_BOOT_MODE_LOW_BATTERY) || + if ((boot_mode == LB_BOOT_MODE_LOW_BATTERY_CHARGING) || (boot_mode == LB_BOOT_MODE_OFFMODE_CHARGING)) - return true; - return false; + ret = true; + + return ret; +} + +static void enable_usb_camera(void) +{ + gpio_output(GPIO_USB_CAM_RESET_L, 1); + gpio_output(GPIO_USB_CAM_ENABLE, 1); +} + +static void setup_usb_typec(void) +{ + gpio_output(GPIO_USB_C1_EN_PP3300, 1); + mdelay(1); + gpio_output(GPIO_USB_C1_EN_PP1800, 1); + mdelay(1); + gpio_output(GPIO_USB_C1_EN_PP0900, 1); + mdelay(1); + gpio_output(GPIO_USB_C1_RETIMER_RESET_L, 1); } static void setup_usb(void) { + setup_usb_typec(); + + enable_usb_camera(); +} + +static void setup_usb_late(void *unused) +{ + /* Skip USB initialization if boot mode is "low-battery" or "off-mode charging"*/ + if (is_low_power_boot_with_charger()) + return; + setup_usb_host0(); } +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, setup_usb_late, NULL); + void lb_add_boot_mode(struct lb_header *header) { if (!CONFIG(EC_GOOGLE_CHROMEEC)) @@ -58,16 +121,12 @@ void lb_add_boot_mode(struct lb_header *header) mode->tag = LB_TAG_BOOT_MODE; mode->size = sizeof(*mode); mode->boot_mode = get_boot_mode(); - - /* Enable charging only during off-mode or low-battery mode and charger present */ - if (is_low_power_boot() && google_chromeec_is_charger_present()) - enable_slow_battery_charging(); } bool mainboard_needs_pcie_init(void) { /* Skip PCIe initialization if boot mode is "low-battery" or "off-mode charging"*/ - if (is_low_power_boot()) + if (is_low_power_boot_with_charger()) return false; return true; @@ -75,21 +134,65 @@ bool mainboard_needs_pcie_init(void) static void display_startup(void) { - if (!display_init_required()) { + if (!display_init_required() || (CONFIG(VBOOT_LID_SWITCH) && !get_lid_switch())) { printk(BIOS_INFO, "Skipping display init.\n"); return; } - /* TODO: add logic for display init */ + /* Initialize RPMh subsystem and display power rails */ + if (display_rpmh_init() != CB_SUCCESS) + return; + + enable_mdss_clk(); +} + +static void trigger_critical_battery_shutdown(void) +{ + printk(BIOS_WARNING, "Critical battery level detected without charger! Shutting down.\n"); + + if (!CONFIG(EC_GOOGLE_CHROMEEC)) + return; + + platform_handle_emergency_low_battery(); + + google_chromeec_ap_poweroff(); } static void mainboard_init(struct device *dev) { configure_parallel_charging(); + configure_charging_debug_access(); + + display_startup(); + + /* + * Low-battery boot indicator is done. Therefore, power off if battery + * is critical and not charging + */ + if (get_boot_mode() == LB_BOOT_MODE_LOW_BATTERY) + trigger_critical_battery_shutdown(); + + /* ADSP I2C (Charger/Fuel gauge) */ + qupv3_se_fw_load_and_init(QUPV3_2_SE4, SE_PROTOCOL_I2C, MIXED); + + configure_parallel_charging_late(); + + /* Skip mainboard initialization if boot mode is "low-battery" or "off-mode charging" */ + if (is_low_power_boot_with_charger()) { + /* TODO: enable fast charging */ + enable_slow_battery_charging(); + + /* Disable the lightbar for Low-Battery or Off-Mode charging sequences. + * This maintains visual consistency between the built-in display + * indicators and the external lightbar. + */ + if (CONFIG(EC_GOOGLE_CHROMEEC_LED_CONTROL)) + google_chromeec_lightbar_off(); - /* Skip mainboard initialization if boot mode is "low-battery" or "off-mode charging"*/ - if (is_low_power_boot()) + /* Boot to charging applet */ + launch_charger_applet(); return; + } gpi_firmware_load(QUP_0_GSI_BASE); gpi_firmware_load(QUP_1_GSI_BASE); @@ -105,6 +208,15 @@ static void mainboard_init(struct device *dev) qupv3_se_fw_load_and_init(QUPV3_1_SE0, SE_PROTOCOL_I2C, MIXED); /* Touch I2C */ qupv3_se_fw_load_and_init(QUPV3_1_SE6, SE_PROTOCOL_UART, FIFO); /* BT UART */ qupv3_se_fw_load_and_init(QUPV3_0_SE0, SE_PROTOCOL_I2C, MIXED); /* Trackpad I2C */ + + if (CONFIG(MAINBOARD_HAS_PS8820_RETIMER)) { + i2c_init(QUPV3_0_SE3, I2C_SPEED_FAST); /* USB-C0 Re-Timer I2C */ + i2c_init(QUPV3_0_SE7, I2C_SPEED_FAST); /* USB-C1 Re-Timer I2C */ + } else { + qupv3_se_fw_load_and_init(QUPV3_0_SE3, SE_PROTOCOL_I2C, MIXED); /* USB-C0 Re-Timer I2C */ + qupv3_se_fw_load_and_init(QUPV3_0_SE7, SE_PROTOCOL_I2C, MIXED); /* USB-C1 Re-Timer I2C */ + } + if (!CONFIG(MAINBOARD_NO_USB_A_PORT)) qupv3_se_fw_load_and_init(QUPV3_0_SE1, SE_PROTOCOL_I2C, MIXED); /* USB-A retimer */ qupv3_se_fw_load_and_init(QUPV3_0_SE5, SE_PROTOCOL_I2C, MIXED); /* eUSB repeater */ @@ -124,8 +236,6 @@ static void mainboard_init(struct device *dev) /* Setup USB related initial config */ setup_usb(); - - display_startup(); } static void mainboard_enable(struct device *dev) diff --git a/src/mainboard/google/bluey/romstage.c b/src/mainboard/google/bluey/romstage.c index 3c5b307fd86..891809f0453 100644 --- a/src/mainboard/google/bluey/romstage.c +++ b/src/mainboard/google/bluey/romstage.c @@ -2,12 +2,15 @@ #include #include "board.h" +#include #include #include #include #include #include +#include #include +#include #include #include #include @@ -27,30 +30,64 @@ static enum boot_mode_t boot_mode = LB_BOOT_MODE_NORMAL; */ bool is_off_mode(void) { + return is_pon_on_ac(); +} + +static enum boot_mode_t set_boot_mode(void) +{ + if (!CONFIG(EC_GOOGLE_CHROMEEC)) + return boot_mode; + + enum boot_mode_t boot_mode_new; + + if (is_off_mode() && google_chromeec_is_battery_present()) { + boot_mode_new = LB_BOOT_MODE_OFFMODE_CHARGING; + } else if (google_chromeec_is_below_critical_threshold()) { + if (google_chromeec_is_charger_present()) + boot_mode_new = LB_BOOT_MODE_LOW_BATTERY_CHARGING; + else + boot_mode_new = LB_BOOT_MODE_LOW_BATTERY; + } else { + boot_mode_new = LB_BOOT_MODE_NORMAL; + } + + boot_mode = boot_mode_new; + return boot_mode_new; +} + +static bool is_pd_sync_required(void) +{ + if (!CONFIG(EC_GOOGLE_CHROMEEC)) + return false; + const uint64_t manual_pwron_event_mask = (EC_HOST_EVENT_MASK(EC_HOST_EVENT_POWER_BUTTON) | EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_OPEN)); uint64_t ec_events = google_chromeec_get_events_b(); - if (!(ec_events & manual_pwron_event_mask) && - (ec_events & EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_CONNECTED))) + if (!(ec_events & EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_CONNECTED))) + return false; + + if (!(ec_events & manual_pwron_event_mask) || + google_chromeec_is_below_critical_threshold() || !google_chromeec_is_battery_present()) return true; return false; } -static enum boot_mode_t set_boot_mode(void) +/* Check if it is okay to enable PD sync. */ +static bool vboot_can_enable_pd_sync(void) { - if (!CONFIG(EC_GOOGLE_CHROMEEC)) - return boot_mode; + if (!CONFIG(VBOOT)) + return false; - enum boot_mode_t boot_mode_new = LB_BOOT_MODE_NORMAL; - if (is_off_mode()) - boot_mode_new = LB_BOOT_MODE_OFFMODE_CHARGING; - else if (google_chromeec_is_below_critical_threshold()) - boot_mode_new = LB_BOOT_MODE_LOW_BATTERY; - boot_mode = boot_mode_new; - return boot_mode_new; + /* Always enable if in developer or recovery mode */ + if (vboot_developer_mode_enabled() || vboot_recovery_mode_enabled() || + vboot_check_recovery_request()) + return true; + + /* Otherwise disable */ + return false; } int qclib_mainboard_override(struct qclib_cb_if_table *table) @@ -58,23 +95,76 @@ int qclib_mainboard_override(struct qclib_cb_if_table *table) if (!CONFIG(EC_GOOGLE_CHROMEEC)) return 0; - if ((set_boot_mode() != LB_BOOT_MODE_NORMAL) || !google_chromeec_is_battery_present()) + if (is_pd_sync_required() || vboot_can_enable_pd_sync()) table->global_attributes |= QCLIB_GA_ENABLE_PD_NEGOTIATION; else table->global_attributes &= ~QCLIB_GA_ENABLE_PD_NEGOTIATION; return 0; } +static void platform_dump_battery_soc_information(void) +{ + uint32_t batt_pct; + if (google_chromeec_read_batt_state_of_charge(&batt_pct)) + printk(BIOS_WARNING, "Failed to get battery level\n"); + else + printk(BIOS_INFO, "Battery state-of-charge %d%%\n", batt_pct); +} + +static void early_setup_usb_typec(void) +{ + gpio_output(GPIO_USB_C1_RETIMER_RESET_L, 0); + gpio_output(GPIO_USB_C1_EN_PP3300, 0); + gpio_output(GPIO_USB_C1_EN_PP1800, 0); + gpio_output(GPIO_USB_C1_EN_PP0900, 0); +} + +static void early_setup_usb(void) +{ + early_setup_usb_typec(); +} + +static void platform_init_lightbar(void) +{ + if (!CONFIG(EC_GOOGLE_CHROMEEC_LED_CONTROL)) + return; + + /* + * Early initialization of the Chrome EC lightbar. + * Ensures visual continuity if the AP firmware disabled the lightbar + * in a previous boot without a subsequent EC reset. + */ + google_chromeec_lightbar_on(); + + /* + * Only alert the user (set LED to red in color) if the lid is closed and the battery + * is critically low without AC power. + */ + if (CONFIG(VBOOT_LID_SWITCH) && !get_lid_switch() && + google_chromeec_is_critically_low_on_battery()) + google_chromeec_set_lightbar_rgb(0xff, 0xff, 0x00, 0x00); +} + void platform_romstage_main(void) { + platform_init_lightbar(); + + /* Setup early USB related config */ + early_setup_usb(); + /* Watchdog must be checked first to avoid erasing watchdog info later. */ check_wdog(); - shrm_fw_load_reset(); + if (CONFIG(EC_GOOGLE_CHROMEEC) && CONFIG(CONSOLE_SERIAL)) + platform_dump_battery_soc_information(); + + if (!qclib_check_dload_mode()) + shrm_fw_load_reset(); /* QCLib: DDR init & train */ qclib_load_and_run(); + /* Underlying PMIC registers are accessible only at this point */ set_boot_mode(); aop_fw_load_reset(); diff --git a/src/mainboard/google/brox/Kconfig b/src/mainboard/google/brox/Kconfig index cec63f53be8..8847f33e72e 100644 --- a/src/mainboard/google/brox/Kconfig +++ b/src/mainboard/google/brox/Kconfig @@ -97,6 +97,14 @@ config BOARD_GOOGLE_JUBILANT select MAINBOARD_HAS_GOOGLE_STRAUSS_KEYBOARD select USE_UNIFIED_AP_FIRMWARE_FOR_UFS_AND_NON_UFS +config BOARD_GOOGLE_JUCHI + select BOARD_GOOGLE_BASEBOARD_BROX + select CHROMEOS_WIFI_SAR if CHROMEOS + select DRIVERS_GENERIC_ALC1015 + select DRIVERS_I2C_SX9324 + select MAINBOARD_HAS_GOOGLE_STRAUSS_KEYBOARD + select USE_UNIFIED_AP_FIRMWARE_FOR_UFS_AND_NON_UFS + config BOARD_GOOGLE_CABOC select BOARD_GOOGLE_BASEBOARD_BROX select CHROMEOS_WIFI_SAR if CHROMEOS @@ -140,6 +148,7 @@ config PL4_LIMIT_FOR_CRITICAL_BAT_BOOT default 9 if BOARD_GOOGLE_BROX_RTK_EC default 14 if BOARD_GOOGLE_CABOC default 14 if BOARD_GOOGLE_JUBILANT + default 14 if BOARD_GOOGLE_JUCHI default 40 if BOARD_GOOGLE_LOTSO help Select this if the variant has to boot even with low battery, critical battery @@ -180,6 +189,7 @@ config MAINBOARD_PART_NUMBER default "Caboc" if BOARD_GOOGLE_CABOC default "Greenbayupoc" if BOARD_GOOGLE_GREENBAYUPOC default "Jubilant" if BOARD_GOOGLE_JUBILANT + default "Juchi" if BOARD_GOOGLE_JUCHI default "Lotso" if BOARD_GOOGLE_LOTSO config VARIANT_DIR @@ -192,6 +202,7 @@ config VARIANT_DIR default "lotso" if BOARD_GOOGLE_LOTSO default "greenbayupoc" if BOARD_GOOGLE_GREENBAYUPOC default "jubilant" if BOARD_GOOGLE_JUBILANT + default "juchi" if BOARD_GOOGLE_JUCHI config VBOOT select VBOOT_LID_SWITCH @@ -212,6 +223,9 @@ config HAVE_WWAN_POWER_SEQUENCE config HAVE_PCIE_WWAN def_bool n +config CBFS_SIZE + default 0x1000000 + config USE_PM_ACPI_TIMER default n diff --git a/src/mainboard/google/brox/Kconfig.name b/src/mainboard/google/brox/Kconfig.name index ca231025fcf..ec754a68a7b 100644 --- a/src/mainboard/google/brox/Kconfig.name +++ b/src/mainboard/google/brox/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Brox" +comment "Brox (Intel RaptorLake (13th Gen))" config BOARD_GOOGLE_BROX bool "-> Brox" @@ -27,5 +27,8 @@ config BOARD_GOOGLE_JUBILANT - Acer Chromebook Plus 514 - Acer Chromebook Plus 516 (CB516-1H,CB516-1HT) +config BOARD_GOOGLE_JUCHI + bool "-> Juchi" + config BOARD_GOOGLE_LOTSO bool "-> Lotso (Lenovo Chromebook Plus 2-in-1)" diff --git a/src/mainboard/google/brox/variants/caboc/overridetree.cb b/src/mainboard/google/brox/variants/caboc/overridetree.cb index 9816c123c13..cded4fd8758 100644 --- a/src/mainboard/google/brox/variants/caboc/overridetree.cb +++ b/src/mainboard/google/brox/variants/caboc/overridetree.cb @@ -23,6 +23,7 @@ fw_config option TOUCH_UNKNOWN 0 option TOUCH_ELAN_HID_I2C 1 option TOUCH_G2TOUCH_HID_I2C 2 + option TOUCH_LGD_HID_I2C 3 end end @@ -419,6 +420,23 @@ chip soc/intel/alderlake probe PANEL TOUCH_G2TOUCH_HID_I2C end end + chip drivers/i2c/hid + register "generic.hid" = ""LXST2024"" + register "generic.desc" = ""LGD Touchscreen"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_F18_IRQ)" + register "generic.detect" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F17)" + register "generic.reset_delay_ms" = "150" + register "generic.reset_off_delay_ms" = "2" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F7)" + register "generic.enable_delay_ms" = "1" + register "generic.has_power_resource" = "1" + register "generic.use_gpio_for_status" = "true" + register "hid_desc_reg_offset" = "0x00" + device i2c 10 on + probe PANEL TOUCH_LGD_HID_I2C + end + end end device ref gspi1 on chip drivers/spi/acpi diff --git a/src/mainboard/google/brox/variants/juchi/Makefile.mk b/src/mainboard/google/brox/variants/juchi/Makefile.mk new file mode 100644 index 00000000000..bb7543b9685 --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/Makefile.mk @@ -0,0 +1,14 @@ +## SPDX-License-Identifier: GPL-2.0-only + +bootblock-y += gpio.c + +romstage-y += gpio.c +romstage-y += memory.c +romstage-$(CONFIG_FW_CONFIG) += variant.c + +ramstage-$(CONFIG_FW_CONFIG) += fw_config.c +ramstage-$(CONFIG_FW_CONFIG) += variant.c +ramstage-y += gpio.c +ramstage-y += ramstage.c + +smm-y += smihandler.c diff --git a/src/mainboard/google/brox/variants/juchi/data.vbt b/src/mainboard/google/brox/variants/juchi/data.vbt new file mode 100644 index 00000000000..716d09f557d Binary files /dev/null and b/src/mainboard/google/brox/variants/juchi/data.vbt differ diff --git a/src/mainboard/google/brox/variants/juchi/fw_config.c b/src/mainboard/google/brox/variants/juchi/fw_config.c new file mode 100644 index 00000000000..6d50ca24955 --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/fw_config.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +static const struct pad_config fp_disable_pads[] = { + /* D2 : ISH_GP2 ==> EN_FP_PWR (NC) */ + PAD_NC(GPP_D2, NONE), + /* GPP_D3 : IPCH_FP_BOOT0 (active high) (NC) */ + PAD_NC(GPP_D3, NONE), + /* GPP_D15 : FPMCU_RST_J_SUB_L (active low) (NC) */ + PAD_NC(GPP_D15, NONE), + /* GPP_D13 : FP GSPI INT (NC) */ + PAD_NC(GPP_D13, NONE), + /* GPP_F11 : FP GSPI CLK (NC) */ + PAD_NC(GPP_F11, NONE), + /* GPP_F12 : FP GSPI DO (NC) */ + PAD_NC(GPP_F12, NONE), + /* GPP_F13 : FP GSPI DI (NC) */ + PAD_NC(GPP_F13, NONE), + /* GPP_F16 : FP GSPI CS (NC) */ + PAD_NC(GPP_F16, NONE), +}; + +static const struct pad_config lte_disable_pads[] = { + /* GPP_E11 : WWAN_CFG0 */ + PAD_NC(GPP_E11, NONE), + /* GPP_E17 : WWAN_CFG02 */ + PAD_NC(GPP_E17, NONE), + /* GPP_D7 :WWAN_RF_DISABLE_ODL */ + PAD_NC(GPP_D7, NONE), + /* GPP_D5 : WWAN_SAR_ODL */ + PAD_NC(GPP_D5, NONE), + /* GPP_F21 : WWAN_FCPO_L */ + PAD_NC(GPP_F21, NONE), + /* GPP_S4 : WWAN_WLAN_COEX1 */ + PAD_NC(GPP_S4, NONE), + /* GPP_S5 : WWAN_WLAN_COEX2 */ + PAD_NC(GPP_S5, NONE), + /* GPP_F6 : WWAN_WLAN_COEX3 */ + PAD_NC(GPP_F6, NONE), + /* GPP_A12 : WWAN_PWR_EN */ + PAD_NC(GPP_A12, NONE), + /* GPP_H23 : WWAN_RST_L */ + PAD_NC(GPP_H23, NONE), + /* GPP_H19 : SRCCLKREQ4_L ==> SAR1_INT_L (NC) */ + PAD_NC(GPP_H19, NONE), +}; + +static const struct pad_config lte_sar_disable_pads[] = { + /* GPP_D5 : WWAN_SAR_ODL */ + PAD_NC(GPP_D5, NONE), + /* GPP_S4 : WWAN_WLAN_COEX1 */ + PAD_NC(GPP_S4, NONE), + /* GPP_S5 : WWAN_WLAN_COEX2 */ + PAD_NC(GPP_S5, NONE), + /* GPP_F6 : WWAN_WLAN_COEX3 */ + PAD_NC(GPP_F6, NONE), + /* GPP_H19 : SRCCLKREQ4_L ==> SAR1_INT_L (NC) */ + PAD_NC(GPP_H19, NONE), +}; + +static const struct pad_config nvme_disable_pads[] = { + /* GPP_F9 : SSD_PERST_L */ + PAD_NC(GPP_F9, NONE), + /* GPP_D11 : EN_PP3300_SSD (NC) */ + PAD_NC(GPP_D11, NONE), + /* GPP_D8 : SSD_CLKREQ_ODL */ + PAD_NC(GPP_D8, NONE), +}; + +static void fw_config_handle(void *unused) +{ + if (!fw_config_is_provisioned()) { + printk(BIOS_WARNING, "FW_CONFIG is unprovisioned. Skip disable device's pads.\n"); + return; + } + + if (fw_config_probe(FW_CONFIG(FPMCU, FPMCU_ABSENT))) { + printk(BIOS_INFO, "Disable Fingerprint GPIOs by fw_config.\n"); + gpio_configure_pads(fp_disable_pads, ARRAY_SIZE(fp_disable_pads)); + } + + if (fw_config_probe(FW_CONFIG(DB_USB, DB_1A))) { + printk(BIOS_INFO, "Disable LTE-related GPIO pins by fw_config.\n"); + gpio_configure_pads(lte_disable_pads, ARRAY_SIZE(lte_disable_pads)); + } + + if (fw_config_probe(FW_CONFIG(DB_USB, DB_1A_LTE))) { + printk(BIOS_INFO, "Disable LTE's Sar sensor related GPIO pins by fw_config.\n"); + gpio_configure_pads(lte_sar_disable_pads, ARRAY_SIZE(lte_sar_disable_pads)); + } + + if (!fw_config_probe(FW_CONFIG(STORAGE, STORAGE_NVME))) { + printk(BIOS_INFO, "Disable NVMe GPIO pins by fw_config.\n"); + gpio_configure_pads(nvme_disable_pads, ARRAY_SIZE(nvme_disable_pads)); + } +} +BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, fw_config_handle, NULL); diff --git a/src/mainboard/google/brox/variants/juchi/gpio.c b/src/mainboard/google/brox/variants/juchi/gpio.c new file mode 100644 index 00000000000..c633a9116c1 --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/gpio.c @@ -0,0 +1,242 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include + +/* Pad configuration in ramstage */ +static const struct pad_config override_gpio_table[] = { + /* GPP_E11 : [NF2: THC0_SPI1_CLK NF6: USB_C_GPP_E11 NF7: GSPI0_CLK] ==> WWAN_CFG0 */ + PAD_CFG_GPI(GPP_E11, NONE, PLTRST), + /* GPP_E17 : [NF2: THC0_SPI1_INT# NF6: USB_C_GPP_E17] ==> WWAN_CFG02 */ + PAD_CFG_GPI(GPP_E17, NONE, PLTRST), + /* GPP_D7 : SRCCLKREQ2_L ==> WWAN_RF_DISABLE (Reserved) */ + PAD_NC_LOCK(GPP_D7, NONE, LOCK_CONFIG), + /* GPP_D5 : SRCCLKREQ0_L ==> WWAN_SAR_ODL */ + PAD_CFG_GPO(GPP_D5, 1, DEEP), + /* GPP_S4 : SNDW2_CLK/DMIC_CLK_B0 ==> WWAN_WLAN_COEX1 */ + PAD_CFG_GPI(GPP_S4, NONE, DEEP), + /* GPP_S5 : SNDW2_DATA/DMIC_CLK_B1 ==> WWAN_WLAN_COEX2 */ + PAD_CFG_GPI(GPP_S5, NONE, DEEP), + /* GPP_F6 : [NF1: CNV_PA_BLANKING NF6: USB_C_GPP_F6] ==>WWAN_WLAN_COEX3 */ + PAD_CFG_GPI(GPP_F6, NONE, DEEP), + /* + * GPP_A12 : [NF1: SATAXPCIE1 NF2: SATAGP1 NF4: SRCCLKREQ9B# NF6: USB_C_GPP_A12] + * ==> WWAN_PWR_EN + */ + PAD_CFG_GPO_LOCK(GPP_A12, 1, LOCK_CONFIG), + /* GPP_H23 : SRCCLKREQ5_L ==> WWAN_RST_L */ + PAD_CFG_GPO_LOCK(GPP_H23, 0, LOCK_CONFIG), + /* GPP_F21 : [NF1: Reserved NF6: USB_C_GPP_F21] ==> WWAN_FCPO_L */ + PAD_CFG_GPO_LOCK(GPP_F21, 0, LOCK_CONFIG), + + /* GPP_H19 : SRCCLKREQ4_L ==> SAR1_INT_L */ + PAD_CFG_GPI_APIC_LOCK(GPP_H19, NONE, LEVEL, NONE, LOCK_CONFIG), + + /* GPP_D2 : [NF1: ISH_GP2 NF2: BK2 NF5: SBK2 NF6: USB_C_GPP_D2] ==> EN_FP_PWR (active high) */ + PAD_CFG_GPO_LOCK(GPP_D2, 0, LOCK_CONFIG), + /* GPP_D3 : [NF1: ISH_GP3 NF2: BK3 NF5: SBK3 NF6: USB_C_GPP_D3] ==> IPCH_FP_BOOT0 (active high) */ + PAD_CFG_GPO_LOCK(GPP_D3, 0, LOCK_CONFIG), + /* GPP_D15 : ISH_UART0_RTS_L/I2C7B_SDA ==> FPMCU_RST_J_SUB_L (active low) */ + PAD_CFG_GPO_LOCK(GPP_D15, 0, LOCK_CONFIG), + /* GPP_D13 : [NF1: ISH_UART0_RXD NF3: I2C6_SDA NF6: USB_C_GPP_D13] ==> FP GSPI INT */ + PAD_CFG_GPI_IRQ_WAKE(GPP_D13, NONE, PWROK, LEVEL, INVERT), + /* GPP_F11 : [NF3: THC1_SPI2_CLK NF4: GSPI1_CLK NF6: USB_C_GPP_F11] ==> FP GSPI CLK */ + PAD_CFG_NF_LOCK(GPP_F11, NONE, NF4, LOCK_CONFIG), + /* GPP_F12 : [NF1: GSXDOUT NF3: THC1_SPI2_IO0 NF4: GSPI1_MOSI NF5: I2C1A_SCL + NF6: USB_C_GPP_F12] ==> FP GSPI DO */ + PAD_CFG_NF_LOCK(GPP_F12, NONE, NF4, LOCK_CONFIG), + /* GPP_F13 : [NF1: GSXSLOAD NF3: THC1_SPI2_IO1 NF4: GSPI1_MISIO NF5: I2C1A_SDA + NF6: USB_C_GPP_F13] ==> SFP GSPI DI */ + PAD_CFG_NF_LOCK(GPP_F13, NONE, NF4, LOCK_CONFIG), + /* GPP_F16 : [NF1: GSXCLK NF3: THC1_SPI2_CS# NF4: GSPI1_CS0# NF6: USB_C_GPP_F16] ==> FP GSPI CS */ + PAD_CFG_NF_LOCK(GPP_F16, NONE, NF4, LOCK_CONFIG), + + /* GPP_F14 : [NF1: GSXDIN NF3: THC1_SPI2_IO2 NF6: USB_C_GPP_F14] ==> PCH_TCHSCR_REPORT_EN */ + PAD_CFG_GPO(GPP_F14, 0, DEEP), + + /* GPP_E7 : [NF1: PROC_GP1 NF6: USB_C_GPP_E7] ==> EN_UCAM_PWR */ + PAD_CFG_GPO(GPP_E7, 1, PLTRST), + + /* GPP_B5 : [NF1: ISH_I2C0_SDA NF2: I2C2_SDA NF6: USB_C_GPP_B5] ==> PCH_I2C_MISC_R_SDA (SAR, HP) */ + PAD_CFG_NF(GPP_B5, NONE, DEEP, NF2), + /* GPP_B6 : [NF1: ISH_I2C0_SCL NF2: I2C2_SCL NF6: USB_C_GPP_B6] ==> PCH_I2C_MISC_R_SCL (SAR, HP) */ + PAD_CFG_NF(GPP_B6, NONE, DEEP, NF2), + + /* GPP_S6 : SNDW3_CLK/DMIC_CLK_A1 ==> HP_INT_L (Headphone interrupt) */ + PAD_CFG_GPI_INT(GPP_S6, NONE, PLTRST, EDGE_BOTH), + /* GPP_D19 : [NF1: I2S_MCLK1_OUT NF6: USB_C_GPP_D19] ==> I2S_MCLK_R (headphone MCLK) */ + PAD_CFG_NF(GPP_D19, NONE, DEEP, NF1), + /* GPP_R0 : [NF1: HDA_BCLK NF2: I2S0_SCLK NF3: DMIC_CLK_B0 NF4: HDAPROC_BCLK] ==> I2S0_SCLK */ + PAD_CFG_NF(GPP_R0, NONE, PLTRST, NF2), + /* GPP_R1 : [NF1: HDA_SYNC NF3: DMIC_CLK_B1] ==> I2S0_SFRM */ + PAD_CFG_NF(GPP_R1, NONE, PLTRST, NF2), + /* GPP_R2 : [NF1: HDA_SDO NF2: I2S0_TXD NF4: HDAPROC_SDO] ==> I2S0_TXD */ + PAD_CFG_NF(GPP_R2, NONE, PLTRST, NF2), + /* GPP_R3 : [NF1: HDA_SDI0 NF2: I2S0_RXD NF4: HDAPROC_SDI] ==> I2S0_RXD */ + PAD_CFG_NF(GPP_R3, NONE, PLTRST, NF2), + + /* GPP_F20 : [NF1: Reserved NF6: USB_C_GPP_F20] ==> SPK enable (active high) */ + PAD_CFG_GPO(GPP_F20, 1, DEEP), + /* GPP_S0 : SNDW0_CLL/I2S1_SCLK ==> SPK I2S_CLK */ + PAD_CFG_NF(GPP_S0, NONE, PLTRST, NF4), + /* GPP_S1 : SNDW0_DATA/I2S1_SFRM ==> SPK I2S_FRAME */ + PAD_CFG_NF(GPP_S1, NONE, PLTRST, NF4), + /* GPP_S2 : [NF1: SNDW1_CLK NF2: DMIC_CKL_A0 NF4: I2S1_TXD] ==> SPK I2S_TX */ + PAD_CFG_NF(GPP_S2, NONE, PLTRST, NF4), + /* GPP_S3 : [NF1: SNDW1_DATA NF2: DMIC_DAGPP_D1TA0 NF4: I2S1_RXD] ==> SPK I2S_RX */ + PAD_CFG_NF(GPP_S3, NONE, PLTRST, NF4), + + /* GPP_R4 : HDA_RST_L/I2S2_SCLK/DMIC_CLK_A0 ==> DMIC_CLK_A0 */ + PAD_CFG_NF(GPP_R4, NONE, PLTRST, NF3), + /* GPP_R5 : HDA_SDI1/I2S2_SFRM/DMIC_DATA0 ==> SDMIC_DATA0 */ + PAD_CFG_NF(GPP_R5, NONE, PLTRST, NF3), + /* GPP_R6 : I2S2_TXD/DMIC_CLK_A1 ==> DMIC_CLK_A1 */ + PAD_CFG_NF(GPP_R6, NONE, PLTRST, NF3), + /* GPP_R7 : I2S2_RXD/DMIC_DATA1 ==> DMIC_DATA1 */ + PAD_CFG_NF(GPP_R7, NONE, PLTRST, NF3), + + /* GPP_E15 : SRCCLK_OE8_L ==> MEM_STRAP_0 */ + PAD_CFG_GPI(GPP_E15, NONE, PLTRST), + /* GPP_E12 : THC0_SPI1_IO1/I2C0A_SDA/GSPI0_MISO ==> MEM_STRAP_1 */ + PAD_CFG_GPI(GPP_E12, NONE, PLTRST), + /* GPP_E13 : THC0_SPI1_IO0/I2C0A_SCL/GSPI0_MOSI ==> MEM_STRAP_2 */ + PAD_CFG_GPI(GPP_E13, NONE, PLTRST), + /* GPP_E10 : THC0_SPI1_CS_L/GSPI0_CS0_L ==> MEM_STRAP_3 */ + PAD_CFG_GPI(GPP_E10, NONE, PLTRST), + /* GPP_S7 : SNDW3_DATA/DMIC_DATA1 ==> MEM_CH_SEL */ + PAD_CFG_GPI(GPP_S7, NONE, DEEP), +}; + +/* Early pad configuration in bootblock */ +static const struct pad_config early_gpio_table[] = { + + /* + * GPP_A12 : [NF1: SATAXPCIE1 NF2: SATAGP1 NF4: SRCCLKREQ9B# NF6: USB_C_GPP_A12] + * ==> WWAN_PWR_EN + */ + PAD_CFG_GPO_LOCK(GPP_A12, 1, LOCK_CONFIG), + /* GPP_H23 : SRCCLKREQ5_L ==> WWAN_RST_L */ + PAD_CFG_GPO_LOCK(GPP_H23, 0, LOCK_CONFIG), + /* GPP_F21 : [NF1: Reserved NF6: USB_C_GPP_F21] ==> WWAN_FCPO_L */ + PAD_CFG_GPO_LOCK(GPP_F21, 0, LOCK_CONFIG), + + /* + * FP_RST_ODL comes out of reset as hi-z and does not have an external pull-down. + * To ensure proper power sequencing for the FPMCU device, reset signal is driven low + * early on in bootblock, followed by enabling of power. Reset signal is deasserted + * later on in ramstage. Since reset signal is asserted in bootblock, it results in + * FPMCU not working after a S3 resume. This is a known issue. + */ + /* GPP_D15 : ISH_UART0_RTS_L/I2C7B_SDA ==> FPMCU_RST_J_SUB_L (active low) */ + PAD_CFG_GPO(GPP_D15, 0, DEEP), + /* D2 : ISH_GP2 ==> EN_FP_PWR */ + PAD_CFG_GPO(GPP_D2, 1, DEEP), + + /* GPP_F9 : [NF1: BOOTMPC NF6: USB_C_GPP_F9] ==> SSD_PERST_L */ + PAD_CFG_GPO(GPP_F9, 0, DEEP), + /* GPP_D11 : [] ==> EN_PP3300_SSD (NC) */ + PAD_NC(GPP_D11, NONE), + + /* GPP_E2 : THC0_SPI1_IO3 ==> GSC_PCH_INT_ODL */ + PAD_CFG_GPI_APIC_LOCK(GPP_E2, NONE, LEVEL, INVERT, LOCK_CONFIG), + /* GPP_E8 : GPP_E8 ==> PCH_WP_OD */ + PAD_CFG_GPI_LOCK(GPP_E8, NONE, LOCK_CONFIG), + /* GPP_H8 : [NF1: I2C4_SDA NF2: CNV_MFUART2_RXD NF6: USB_C_GPP_H8] ==> PCH_I2C_GSC_SDA */ + PAD_CFG_NF(GPP_H8, NONE, DEEP, NF1), + /* GPP_H9 : [NF1: I2C4_SCL NF2: CNV_MFUART2_TXD] ==> PCH_I2C_GSC_SCL */ + PAD_CFG_NF(GPP_H9, NONE, DEEP, NF1), + + /* H10 : UART0_RXD ==> UART_PCH_RX_DBG_TX */ + PAD_CFG_NF(GPP_H10, NONE, PLTRST, NF2), + /* H11 : UART0_TXD ==> UART_PCH_TX_DBG_RX */ + PAD_CFG_NF(GPP_H11, NONE, PLTRST, NF2), + + /* GPP_S7 : SNDW3_DATA/DMIC_DATA1 ==> MEM_CH_SEL */ + PAD_CFG_GPI(GPP_S7, NONE, DEEP), + + /* CPU PCIe VGPIO for PEG60 */ + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_48, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_49, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_50, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_51, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_52, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_53, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_54, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_55, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_56, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_57, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_58, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_59, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_60, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_61, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_62, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_63, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_76, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_77, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_78, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_79, NONE, PLTRST, NF1), +}; + +static const struct pad_config romstage_gpio_table[] = { + /* GPP_D15 : ISH_UART0_RTS_L/I2C7B_SDA ==> FPMCU_RST_J_SUB_L (active low) */ + PAD_CFG_GPO(GPP_D15, 0, DEEP), + /* D2 : ISH_GP2 ==> EN_FP_PWR */ + PAD_CFG_GPO(GPP_D2, 0, DEEP), + + /* + * GPP_A12 : [NF1: SATAXPCIE1 NF2: SATAGP1 NF4: SRCCLKREQ9B# NF6: USB_C_GPP_A12] + * ==> WWAN_PWR_EN + */ + PAD_CFG_GPO_LOCK(GPP_A12, 1, LOCK_CONFIG), + /* GPP_H23 : SRCCLKREQ5_L ==> WWAN_RST_L */ + PAD_CFG_GPO_LOCK(GPP_H23, 0, LOCK_CONFIG), + /* GPP_F21 : [NF1: Reserved NF6: USB_C_GPP_F21] ==> WWAN_FCPO_L */ + PAD_CFG_GPO_LOCK(GPP_F21, 0, LOCK_CONFIG), + + /* GPP_E15 : SRCCLK_OE8_L ==> MEM_STRAP_0 */ + PAD_CFG_GPI(GPP_E15, NONE, PLTRST), + /* GPP_E12 : THC0_SPI1_IO1/I2C0A_SDA/GSPI0_MISO ==> MEM_STRAP_1 */ + PAD_CFG_GPI(GPP_E12, NONE, PLTRST), + /* GPP_E13 : THC0_SPI1_IO0/I2C0A_SCL/GSPI0_MOSI ==> MEM_STRAP_2 */ + PAD_CFG_GPI(GPP_E13, NONE, PLTRST), + /* GPP_E10 : THC0_SPI1_CS_L/GSPI0_CS0_L ==> MEM_STRAP_3 */ + PAD_CFG_GPI(GPP_E10, NONE, PLTRST), + /* GPP_S7 : SNDW3_DATA/DMIC_DATA1 ==> MEM_CH_SEL */ + PAD_CFG_GPI(GPP_S7, NONE, DEEP), + + /* GPP_F7 : [NF6: USB_C_GPP_F7] ==> EN_PP3300_TCHSCR */ + PAD_CFG_GPO(GPP_F7, 1, PLTRST), + /* GPP_F17 : [NF3: THC1_SPI2_RST# NF6: USB_C_GPP_F17] ==> TCHSCR_RST_L */ + PAD_CFG_GPO(GPP_F17, 0, DEEP), + + /* GPP_F9 : [NF1: BOOTMPC NF6: USB_C_GPP_F9] ==> SSD_PERST_L */ + PAD_CFG_GPO(GPP_F9, 1, DEEP), +}; + +const struct pad_config *variant_gpio_override_table(size_t *num) +{ + *num = ARRAY_SIZE(override_gpio_table); + return override_gpio_table; +} + +const struct pad_config *variant_early_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(early_gpio_table); + return early_gpio_table; +} + +const struct pad_config *variant_romstage_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(romstage_gpio_table); + return romstage_gpio_table; +} + +static const struct cros_gpio cros_gpios[] = { + CROS_GPIO_REC_AL(CROS_GPIO_VIRTUAL, CROS_GPIO_DEVICE_NAME), + CROS_GPIO_WP_AH(GPIO_PCH_WP, CROS_GPIO_DEVICE_NAME), +}; + +DECLARE_WEAK_CROS_GPIOS(cros_gpios); diff --git a/src/mainboard/google/brox/variants/juchi/include/variant/ec.h b/src/mainboard/google/brox/variants/juchi/include/variant/ec.h new file mode 100644 index 00000000000..4fc0622f15a --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/include/variant/ec.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef MAINBOARD_EC_H +#define MAINBOARD_EC_H + +#include + +#endif /* MAINBOARD_GPIO_H */ diff --git a/src/mainboard/google/brox/variants/juchi/include/variant/gpio.h b/src/mainboard/google/brox/variants/juchi/include/variant/gpio.h new file mode 100644 index 00000000000..1d660cf5036 --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __MAINBOARD_GPIO_H__ +#define __MAINBOARD_GPIO_H__ + +#include + +#define T1_OFF_MS 16 +#define T2_OFF_MS 2 +#define WWAN_FCPO GPP_F21 +#define WWAN_RST GPP_H23 + +#endif /* __MAINBOARD_GPIO_H__ */ diff --git a/src/mainboard/google/brox/variants/juchi/include/variant/hda_verb.h b/src/mainboard/google/brox/variants/juchi/include/variant/hda_verb.h new file mode 100644 index 00000000000..c0b0eb0733a --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/include/variant/hda_verb.h @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef MAINBOARD_HDA_VERB_H +#define MAINBOARD_HDA_VERB_H + +#include + +const u32 cim_verb_data[] = { + /* coreboot specific header */ + 0x10ec0256, // Codec Vendor / Device ID: Realtek ALC256 + 0x10ec12ac, // Subsystem ID + 0x00000013, // Number of jacks (NID entries) + + AZALIA_RESET(0x1), + /* NID 0x01, HDA Codec Subsystem ID Verb table */ + AZALIA_SUBVENDOR(0, 0x10ec12ac), + + /* Pin Widget Verb Table */ + + /* + * DMIC + * Requirement is to use PCH DMIC. Hence, + * commented out codec's Internal DMIC. + * AZALIA_PIN_CFG(0, 0x12, 0x90A60130), + * AZALIA_PIN_CFG(0, 0x13, 0x40000000), + */ + + /* Pin widget 0x14 - Front (Port-D) */ + AZALIA_PIN_CFG(0, 0x14, 0x90170110), + /* Pin widget 0x18 - NPC */ + AZALIA_PIN_CFG(0, 0x18, 0x411111F0), + /* Pin widget 0x19 - MIC2 (Port-F) */ + AZALIA_PIN_CFG(0, 0x19, 0x04A11040), + /* Pin widget 0x1A - LINE1 (Port-C) */ + AZALIA_PIN_CFG(0, 0x1a, 0x411111F0), + /* Pin widget 0x1B - NPC */ + AZALIA_PIN_CFG(0, 0x1b, 0x411111F0), + /* Pin widget 0x1D - BEEP-IN */ + AZALIA_PIN_CFG(0, 0x1d, 0x40610041), + /* Pin widget 0x1E - NPC */ + AZALIA_PIN_CFG(0, 0x1e, 0x411111F0), + /* Pin widget 0x21 - HP1-OUT (Port-I) */ + AZALIA_PIN_CFG(0, 0x21, 0x04211020), + /* + * Widget node 0x20 - 1 + * Codec hidden reset and speaker power 2W/4ohm + */ + 0x0205001A, + 0x0204C003, + 0x02050038, + 0x02047901, + /* + * Widget node 0x20 - 2 + * Class D power on Reset + */ + 0x0205003C, + 0x02040354, + 0x0205003C, + 0x02040314, + /* + * Widget node 0x20 - 3 + * Disable AGC and set AGC limit to -1.5dB + */ + 0x02050016, + 0x02040C50, + 0x02050012, + 0x0204EBC1, + /* + * Widget node 0x20 - 4 + * Set AGC Post gain +1.5dB then Enable AGC + */ + 0x02050013, + 0x02044023, + 0x02050016, + 0x02040E50, + /* + * Widget node 0x20 - 5 + * Silence detector enabling + Set EAPD to verb control + */ + 0x02050037, + 0x0204FE15, + 0x02050010, + 0x02040020, + /* + * Widget node 0x20 - 6 + * Silence data mode Threshold (-90dB) + */ + 0x02050030, + 0x0204A000, + 0x0205001B, + 0x02040A4B, + /* + * Widget node 0x20 - 7 + * Default setting - 1 + */ + 0x05750003, + 0x05740DA3, + 0x02050046, + 0x02040004, + /* + * Widget node 0x20 - 8 + * support 1 pin detect two port + */ + 0x02050009, + 0x0204E003, + 0x0205000A, + 0x02047770, + /* + * Widget node 0x20 - 9 + * To set LDO1/LDO2 as default (used for headset) + */ + 0x02050008, + 0x02046A0C, + 0x02050008, + 0x02046A0C, +}; + +const u32 pc_beep_verbs[] = { + /* Dos beep path - 1 */ + 0x01470C00, + 0x02050036, + 0x02047151, + 0x01470740, + /* Dos beep path - 2 */ + 0x0143b000, + 0x01470C02, + 0x01470C02, + 0x01470C02, +}; + +AZALIA_ARRAY_SIZES; + +#endif diff --git a/src/mainboard/google/brox/variants/juchi/memory.c b/src/mainboard/google/brox/variants/juchi/memory.c new file mode 100644 index 00000000000..f7023ac56ff --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/memory.c @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include + +static const struct mb_cfg baseboard_memcfg = { + .type = MEM_TYPE_LP5X, + + .rcomp = { + /* Baseboard uses only 100ohm Rcomp resistors */ + .resistor = 100, + }, + + /* DQ byte map */ + .lpx_dq_map = { + .ddr0 = { + .dq0 = { 0, 3, 2, 1, 6, 4, 5, 7 }, + .dq1 = { 14, 12, 13, 15, 8, 11, 9, 10 }, + }, + .ddr1 = { + .dq0 = { 1, 0, 2, 3, 6, 4, 7, 5 }, + .dq1 = { 11, 8, 10, 9, 15, 14, 13, 12 }, + }, + .ddr2 = { + .dq0 = { 6, 4, 7, 5, 3, 1, 2, 0 }, + .dq1 = { 14, 12, 13, 15, 9, 10, 11, 8 }, + }, + .ddr3 = { + .dq0 = { 1, 2, 3, 0, 6, 4, 7, 5 }, + .dq1 = { 13, 15, 12, 14, 8, 11, 10, 9 }, + }, + .ddr4 = { + .dq0 = { 2, 3, 0, 1, 6, 5, 7, 4 }, + .dq1 = { 14, 15, 13, 12, 10, 8, 9, 11 }, + }, + .ddr5 = { + .dq0 = { 1, 2, 3, 0, 6, 4, 7, 5 }, + .dq1 = { 15, 13, 12, 14, 10, 9, 8, 11 }, + }, + .ddr6 = { + .dq0 = { 2, 1, 3, 0, 7, 5, 4, 6 }, + .dq1 = { 15, 13, 14, 12, 11, 9, 10, 8 }, + }, + .ddr7 = { + .dq0 = { 3, 1, 2, 0, 5, 4, 7, 6 }, + .dq1 = { 14, 15, 9, 11, 13, 8, 10, 12 }, + }, + }, + + /* DQS CPU<>DRAM map */ + .lpx_dqs_map = { + .ddr0 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr1 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr2 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr3 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr4 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr5 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr6 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr7 = { .dqs0 = 0, .dqs1 = 1 }, + }, + + .lp5x_config = { + .ccc_config = 0xff, + }, + + .LpDdrDqDqsReTraining = 1, + + .ect = 1, /* Early Command Training */ + + .UserBd = BOARD_TYPE_ULT_ULX, +}; + +const struct mb_cfg *variant_memory_params(void) +{ + return &baseboard_memcfg; +} + +int variant_memory_sku(void) +{ + /* + * Memory configuration board straps + * MEM_STRAP_0 GPP_E15 + * MEM_STRAP_1 GPP_E12 + * MEM_STRAP_2 GPP_E13 + * MEM_STRAP_3 GPP_E10 + */ + gpio_t spd_gpios[] = { + GPP_E15, + GPP_E12, + GPP_E13, + GPP_E10, + }; + + return gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios)); +} + +bool variant_is_half_populated(void) +{ + /* MEM_CH_SEL GPP_S7 */ + return gpio_get(GPP_S7); +} + +void variant_get_spd_info(struct mem_spd *spd_info) +{ + spd_info->topo = MEM_TOPO_MEMORY_DOWN; + spd_info->cbfs_index = variant_memory_sku(); +} diff --git a/src/mainboard/google/brox/variants/juchi/memory/Makefile.mk b/src/mainboard/google/brox/variants/juchi/memory/Makefile.mk new file mode 100644 index 00000000000..56f44e554b6 --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/memory/Makefile.mk @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# This is an auto-generated file. Do not edit!! +# Generated by: +# util/spd_tools/bin/part_id_gen adl lp5 src/mainboard/google/brox/variants/juchi/memory src/mainboard/google/brox/variants/juchi/memory/mem_parts_used.txt + +SPD_SOURCES = +SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 0(0b0000) Parts = MT62F512M32D2DR-031 WT:B, H9JCNNNBK3MLYR-N6E +SPD_SOURCES += spd/lp5/set-0/spd-2.hex # ID = 1(0b0001) Parts = MT62F1G32D4DR-031 WT:B +SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 2(0b0010) Parts = MT62F1G32D2DS-023 WT:B, H58G56BK8BX068, H58G56CK8BX146, MT62F1G32D2DS-023 WT:C, K3KL8L80DM-MGCU +SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = K3KL8L80CM-MGCT diff --git a/src/mainboard/google/brox/variants/juchi/memory/dram_id.generated.txt b/src/mainboard/google/brox/variants/juchi/memory/dram_id.generated.txt new file mode 100644 index 00000000000..0420329929a --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/memory/dram_id.generated.txt @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# This is an auto-generated file. Do not edit!! +# Generated by: +# util/spd_tools/bin/part_id_gen adl lp5 src/mainboard/google/brox/variants/juchi/memory src/mainboard/google/brox/variants/juchi/memory/mem_parts_used.txt + +DRAM Part Name ID to assign +MT62F512M32D2DR-031 WT:B 0 (0000) +H9JCNNNBK3MLYR-N6E 0 (0000) +MT62F1G32D4DR-031 WT:B 1 (0001) +MT62F1G32D2DS-023 WT:B 2 (0010) +H58G56BK8BX068 2 (0010) +K3KL8L80CM-MGCT 3 (0011) +H58G56CK8BX146 2 (0010) +MT62F1G32D2DS-023 WT:C 2 (0010) +K3KL8L80DM-MGCU 2 (0010) diff --git a/src/mainboard/google/brox/variants/juchi/memory/mem_parts_used.txt b/src/mainboard/google/brox/variants/juchi/memory/mem_parts_used.txt new file mode 100644 index 00000000000..23f29e450aa --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/memory/mem_parts_used.txt @@ -0,0 +1,9 @@ +MT62F512M32D2DR-031 WT:B +H9JCNNNBK3MLYR-N6E +MT62F1G32D4DR-031 WT:B +MT62F1G32D2DS-023 WT:B +H58G56BK8BX068 +K3KL8L80CM-MGCT +H58G56CK8BX146 +MT62F1G32D2DS-023 WT:C +K3KL8L80DM-MGCU diff --git a/src/mainboard/google/brox/variants/juchi/overridetree.cb b/src/mainboard/google/brox/variants/juchi/overridetree.cb new file mode 100644 index 00000000000..1d667507a8d --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/overridetree.cb @@ -0,0 +1,481 @@ +fw_config + field STORAGE 2 3 + option STORAGE_UFS 1 + option STORAGE_NVME 2 + end + field WIFI_BT 4 4 + option WIFI_BT_CNVI 0 + option WIFI_BT_PCIE 1 + end + field DB_USB 11 12 + option DB_1A 0 + option DB_1A_LTE 1 + option DB_1A_LTE_SAR 2 + end + field FPMCU 17 18 + option FPMCU_ABSENT 0 + option FPMCU_NUVOTON 1 + end + field PANEL_PWR 19 + option DISABLE 0 + option ENABLE 1 + end +end + +chip soc/intel/alderlake + register "platform_pmax" = "208" + + # As per Intel Advisory doc#723158, the change is required to prevent possible + # display flickering issue. + register "disable_dynamic_tccold_handshake" = "true" + + register "usb2_ports[0]" = "USB2_PORT_TYPE_C(OC_SKIP)" # USB2_C0 + register "usb2_ports[1]" = "USB2_PORT_EMPTY" # Disable USB2 Port + register "usb2_ports[2]" = "USB2_PORT_TYPE_C(OC_SKIP)" # USB2_C2 + register "usb2_ports[3]" = "USB2_PORT_MID(OC_SKIP)" # WWAN + register "usb2_ports[4]" = "USB2_PORT_EMPTY" # Disable USB2 Port + register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # Camera + register "usb2_ports[6]" = "USB2_PORT_MID(OC2)" # Type-A Port A0 + register "usb2_ports[7]" = "USB2_PORT_EMPTY" # Disable USB2 Port + register "usb2_ports[8]" = "USB2_PORT_MID(OC1)" # Type-A Port A1 + register "usb2_ports[9]" = "USB2_PORT_MID(OC_SKIP)" # M.2 Bluetooth + + register "usb3_ports[0]" = "USB3_PORT_DEFAULT(OC1)" # Type-A port A1(DB) + register "usb3_ports[1]" = "USB3_PORT_EMPTY" # Disable USB3 Port + register "usb3_ports[2]" = "USB3_PORT_DEFAULT(OC2)" # Type A port A0(DCI) + register "usb3_ports[3]" = "USB3_PORT_DEFAULT(OC_SKIP)" # WWAN + + # Intel Common SoC Config + #+-------------------+---------------------------+ + #| Field | Value | + #+-------------------+---------------------------+ + #| I2C0 | Trackpad | + #| I2C1 | Touchscreen | + #| I2C2 | Audio codec & Sar sensor | + #| I2C4 | cr50 TPM. Early init is | + #| | required to set up a BAR | + #| | for TPM communication | + #+-------------------+---------------------------+ + register "common_soc_config" = "{ + .i2c[0] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 650, + .fall_time_ns = 330, + .data_hold_time_ns = 50, + }, + .i2c[1] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 600, + .fall_time_ns = 350, + .data_hold_time_ns = 50, + }, + .i2c[2] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 600, + .fall_time_ns = 250, + .data_hold_time_ns = 50, + }, + .i2c[4] = { + .early_init = 1, + .speed = I2C_SPEED_FAST, + .rise_time_ns = 650, + .fall_time_ns = 400, + .data_hold_time_ns = 50, + }, + }" + + register "power_limits_config[RPL_P_282_242_142_15W_CORE]" = "{ + .tdp_pl1_override = 15, + .tdp_pl2_override = 41, + .tdp_pl4 = 87, + }" + + device domain 0 on + device ref dtt on + chip drivers/intel/dptf + ## sensor information + register "options.tsr[0].desc" = ""DRAM"" + register "options.tsr[1].desc" = ""Soc"" + register "options.tsr[2].desc" = ""Charger"" + + ## Passive Policy + register "policies.passive" = "{ + [0] = DPTF_PASSIVE(CPU, CPU, 97, 5000), + [1] = DPTF_PASSIVE(CPU, TEMP_SENSOR_0, 85, 5000), + [2] = DPTF_PASSIVE(CPU, TEMP_SENSOR_1, 85, 5000), + [3] = DPTF_PASSIVE(CHARGER, TEMP_SENSOR_2, 85, 5000), + }" + + ## Critical Policy + register "policies.critical" = "{ + [0] = DPTF_CRITICAL(CPU, 105, SHUTDOWN), + [1] = DPTF_CRITICAL(TEMP_SENSOR_0, 95, SHUTDOWN), + [2] = DPTF_CRITICAL(TEMP_SENSOR_1, 95, SHUTDOWN), + [3] = DPTF_CRITICAL(TEMP_SENSOR_2, 95, SHUTDOWN), + }" + + register "controls.power_limits" = "{ + .pl1 = { + .min_power = 15000, + .max_power = 18000, + .time_window_min = 28 * MSECS_PER_SEC, + .time_window_max = 32 * MSECS_PER_SEC, + .granularity = 200, + }, + .pl2 = { + .min_power = 41000, + .max_power = 41000, + .time_window_min = 28 * MSECS_PER_SEC, + .time_window_max = 32 * MSECS_PER_SEC, + .granularity = 1000, + } + }" + + ## Charger Performance Control (Control, mA) + register "controls.charger_perf" = "{ + [0] = { 255, 1700 }, + [1] = { 24, 1500 }, + [2] = { 16, 1000 }, + [3] = { 8, 500 } + }" + + device generic 0 alias dptf_policy on end + end + end # DTT + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "6" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + register "device[0].type" = "panel" + # DDIB for HDMI + # If HDMI is not enumerated in the kernel, then no GFX device should be added for DDIB + register "device[1].name" = ""DD01"" + # TCP0 (DP-1) for port C0 + register "device[2].name" = ""DD02"" + register "device[2].use_pld" = "true" + register "device[2].pld" = "ACPI_PLD_TYPE_C(LEFT, LEFT, ACPI_PLD_GROUP(1, 1))" + # TCP1 (DP-2) is unused for any ports but still enumerated in the kernel, so GFX device is added for TCP1 + register "device[3].name" = ""DD03"" + # TCP2 (DP-3) for port C2 + register "device[4].name" = ""DD04"" + register "device[4].use_pld" = "true" + register "device[4].pld" = "ACPI_PLD_TYPE_C(LEFT, RIGHT, ACPI_PLD_GROUP(2, 1))" + # TCP3 (DP-4) is unused for any ports but still enumerated in the kernel, so GFX device is added for TCP3 + register "device[5].name" = ""DD05"" + device generic 0 on end + end + end # Integrated Graphics Device + device ref pch_espi on + chip ec/google/chromeec + device pnp 0c09.0 on end + end + end + device ref pmc hidden + chip drivers/intel/pmc_mux + device generic 0 on + chip drivers/intel/pmc_mux/conn + use usb2_port1 as usb2_port + use tcss_usb3_port1 as usb3_port + device generic 0 on end + end + chip drivers/intel/pmc_mux/conn + use usb2_port3 as usb2_port + use tcss_usb3_port3 as usb3_port + device generic 1 on end + end + end + end + end + device ref tcss_xhci on + chip drivers/usb/acpi + device ref tcss_root_hub on + chip drivers/usb/acpi + register "desc" = ""USB3 Type-C Port C0 (MLB)"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(LEFT, LEFT, ACPI_PLD_GROUP(1, 1))" + device ref tcss_usb3_port1 on end + end + chip drivers/usb/acpi + register "desc" = ""USB3 Type-C Port C2 (MLB)"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(LEFT, RIGHT, ACPI_PLD_GROUP(2, 1))" + device ref tcss_usb3_port3 on end + end + end + end + end + device ref xhci on + chip drivers/usb/acpi + device ref xhci_root_hub on + chip drivers/usb/acpi + register "desc" = ""USB2 Type-C Port C0 (MLB)"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(LEFT, LEFT, ACPI_PLD_GROUP(1, 1))" + device ref usb2_port1 on end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Type-C Port C2 (MLB)"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(LEFT, RIGHT, ACPI_PLD_GROUP(2, 1))" + device ref usb2_port3 on end + end + chip drivers/usb/acpi + register "desc" = ""USB2 WWAN"" + register "type" = "UPC_TYPE_INTERNAL" + device ref usb2_port4 on + probe DB_USB DB_1A_LTE + probe DB_USB DB_1A_LTE_SAR + probe unprovisioned + end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Camera"" + register "type" = "UPC_TYPE_INTERNAL" + register "has_power_resource" = "true" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E7)" + device ref usb2_port6 on end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Type-A Port A0 (DCI)"" + register "type" = "UPC_TYPE_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(RIGHT, LEFT, ACPI_PLD_GROUP(3, 1))" + device ref usb2_port7 on end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Type-A Port A1 (DB)"" + register "type" = "UPC_TYPE_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(LEFT, LEFT, ACPI_PLD_GROUP(4, 1))" + device ref usb2_port9 on end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Bluetooth"" + register "type" = "UPC_TYPE_INTERNAL" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_A13)" + device ref usb2_port10 on end + end + chip drivers/usb/acpi + register "desc" = ""USB3 Type-A Port A1 (DB)"" + register "type" = "UPC_TYPE_USB3_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(LEFT, LEFT, ACPI_PLD_GROUP(4, 1))" + device ref usb3_port1 on end + end + chip drivers/usb/acpi + register "desc" = ""USB3 Type-A Port A0 (DCI)"" + register "type" = "UPC_TYPE_USB3_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(RIGHT, LEFT, ACPI_PLD_GROUP(3, 1))" + device ref usb3_port3 on end + end + chip drivers/usb/acpi + register "desc" = ""USB3 WWAN"" + register "type" = "UPC_TYPE_INTERNAL" + device ref usb3_port4 on + probe DB_USB DB_1A_LTE + probe DB_USB DB_1A_LTE_SAR + probe unprovisioned + end + end + end + end + end + device ref pcie4_0 on + # Enable CPU PCIE RP 1 using CLK 3 + register "cpu_pcie_rp[CPU_RP(1)]" = "{ + .clk_req = 3, + .clk_src = 3, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + .pcie_rp_aspm = ASPM_L1, + }" + probe STORAGE STORAGE_NVME + probe unprovisioned + end + device ref pcie_rp5 on + register "pch_pcie_rp[PCH_RP(5)]" = "{ + .clk_src = 1, + .clk_req = 1, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + .pcie_rp_pcie_speed = SPEED_GEN2, + }" + chip drivers/wifi/generic + register "wake" = "GPE0_DW0_03" + register "add_acpi_dma_property" = "true" + use usb2_port10 as bluetooth_companion + device pci 00.0 on + probe WIFI_BT WIFI_BT_PCIE + probe unprovisioned + end + end + chip soc/intel/common/block/pcie/rtd3 + # enable_gpio is controlled by the EC with EC_EN_PP3300_WLAN + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H2)" + register "srcclk_pin" = "1" + device generic 0 on end + end + probe WIFI_BT WIFI_BT_PCIE + probe unprovisioned + end + device ref cnvi_wifi on + chip drivers/wifi/generic + register "wake" = "GPE0_PME_B0" + register "add_acpi_dma_property" = "true" + register "enable_cnvi_ddr_rfim" = "true" + device generic 0 on end + end + probe WIFI_BT WIFI_BT_CNVI + probe unprovisioned + end + device ref ish on + chip drivers/intel/ish + register "add_acpi_dma_property" = "true" + device generic 0 alias ish_conf on end + end + probe STORAGE STORAGE_UFS + probe unprovisioned + end + device ref ufs on + probe STORAGE STORAGE_UFS + probe unprovisioned + end + device ref i2c0 on + chip drivers/i2c/generic + register "hid" = ""ELAN0000"" + register "desc" = ""ELAN Touchpad"" + register "irq" = "ACPI_IRQ_WAKE_LEVEL_LOW(GPP_E3_IRQ)" + register "wake" = "GPE0_DW2_03" + register "detect" = "1" + device i2c 0x15 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""SYNA0000"" + register "generic.cid" = ""ACPI0C50"" + register "generic.desc" = ""Synaptics Touchpad"" + register "generic.irq" = "ACPI_IRQ_WAKE_LEVEL_LOW(GPP_E3_IRQ)" + register "generic.wake" = "GPE0_DW2_03" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x20" + device i2c 0x2c on end + end + chip drivers/i2c/hid + register "generic.hid" = ""PIXA2303"" + register "generic.desc" = ""PIXA Touchpad"" + register "generic.irq" = "ACPI_IRQ_WAKE_LEVEL_LOW(GPP_E3_IRQ)" + register "generic.wake" = "GPE0_DW2_03" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x20" + device i2c 0x68 on end + end + end #I2C0 + device ref i2c1 on + chip drivers/i2c/hid + register "generic.hid" = ""ILTK0001"" + register "generic.desc" = ""ILITEK Touchscreen"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_F18_IRQ)" + register "generic.detect" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F17)" + register "generic.reset_delay_ms" = "200" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F7)" + register "generic.enable_delay_ms" = "12" + register "generic.has_power_resource" = "1" + register "generic.use_gpio_for_status" = "true" + register "hid_desc_reg_offset" = "0x01" + device i2c 41 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""ELAN9004"" + register "generic.desc" = ""ELAN Touchscreen"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_F18_IRQ)" + register "generic.detect" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F17)" + register "generic.reset_delay_ms" = "20" + register "generic.reset_off_delay_ms" = "2" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F7)" + register "generic.enable_delay_ms" = "1" + register "generic.stop_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F14)" + register "generic.stop_delay_ms" = "150" + register "generic.stop_off_delay_ms" = "2" + register "generic.has_power_resource" = "1" + register "generic.use_gpio_for_status" = "true" + register "hid_desc_reg_offset" = "0x01" + device i2c 10 on end + end + probe PANEL_PWR ENABLE + end + device ref i2c2 on + chip drivers/i2c/generic + register "hid" = ""RTL5682"" + register "name" = ""RT58"" + register "desc" = ""Headset Codec"" + register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_S6)" + # Set the jd_src to RT5668_JD1 for jack detection + register "property_count" = "1" + register "property_list[0].type" = "ACPI_DP_TYPE_INTEGER" + register "property_list[0].name" = ""realtek,jd-src"" + register "property_list[0].integer" = "1" + device i2c 1a on end + end + chip drivers/generic/alc1015 + register "hid" = ""RTL1019"" + register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F20)" + device generic 0 on end + end + chip drivers/i2c/sx9324 + register "desc" = ""SAR Proximity Sensor"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_H19_IRQ)" + register "speed" = "I2C_SPEED_FAST" + register "uid" = "1" + register "ph0_pin" = "{1, 2, 2}" + register "ph1_pin" = "{2, 1, 2}" + register "ph2_pin" = "{2, 2, 1}" + register "ph3_pin" = "{2, 1, 1}" + register "ph01_resolution" = "1024" + register "ph23_resolution" = "1024" + register "startup_sensor" = "1" + register "ph01_proxraw_strength" = "2" + register "ph23_proxraw_strength" = "2" + register "avg_pos_strength" = "256" + register "cs_idle_sleep" = ""hi-z"" + register "int_comp_resistor" = ""lowest"" + register "input_precharge_resistor_ohms" = "4000" + register "input_analog_gain" = "1" + device i2c 28 on + probe DB_USB DB_1A_LTE_SAR + probe unprovisioned + end + end + end + device ref gspi1 on + chip drivers/spi/acpi + register "name" = ""CRFP"" + register "hid" = "ACPI_DT_NAMESPACE_HID" + register "uid" = "1" + register "compat_string" = ""google,cros-ec-spi"" + register "irq" = "ACPI_IRQ_WAKE_LEVEL_LOW(GPP_D13_IRQ)" + register "wake" = "GPE0_DW1_13" + register "has_power_resource" = "true" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_D15)" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D2)" + register "enable_delay_ms" = "3" + device spi 0 on + probe FPMCU FPMCU_NUVOTON + probe unprovisioned + end + end # FPMCU + end + device ref hda on + chip drivers/sof + register "spkr_tplg" = "rt1019" + register "jack_tplg" = "rt5682" + register "mic_tplg" = "_2ch_pdm0" + device generic 0 on end + end + end + end +end diff --git a/src/mainboard/google/brox/variants/juchi/ramstage.c b/src/mainboard/google/brox/variants/juchi/ramstage.c new file mode 100644 index 00000000000..0f78e26bd06 --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/ramstage.c @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include + +/* + * SKU_ID, TDP (Watts), pl1_min (milliWatts), pl1_max (milliWatts), + * pl2_min (milliWatts), pl2_max (milliWatts), pl4 (milliWatts) + * Following values are for performance config as per document #640982 + */ + +const struct cpu_power_limits performance_efficient_limits[] = { + { + .mchid = PCI_DID_INTEL_RPL_P_ID_3, + .cpu_tdp = 15, + .pl1_min_power = 15000, + .pl1_max_power = 18000, + .pl2_min_power = 41000, + .pl2_max_power = 41000, + .pl4_power = 87000 + }, + { + .mchid = PCI_DID_INTEL_RPL_P_ID_4, + .cpu_tdp = 15, + .pl1_min_power = 15000, + .pl1_max_power = 18000, + .pl2_min_power = 41000, + .pl2_max_power = 41000, + .pl4_power = 87000 + }, +}; + +void __weak variant_devtree_update(void) +{ + printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__); + + const struct cpu_power_limits *limits = performance_efficient_limits; + size_t limits_size = ARRAY_SIZE(performance_efficient_limits); + + variant_update_power_limits(limits, limits_size); +} diff --git a/src/mainboard/google/brox/variants/juchi/smihandler.c b/src/mainboard/google/brox/variants/juchi/smihandler.c new file mode 100644 index 00000000000..9f848eae4f8 --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/smihandler.c @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +#include "gpio.h" + +#define WWAN_FCPO_L GPP_F21 +#define WWAN_RSL_L GPP_H23 +#define WWAN_TOFF 15 + +void variant_smi_sleep(u8 slp_typ) +{ + if (slp_typ == ACPI_S5) { + /* WWAN RW101R-GL power off sequence */ + gpio_set(WWAN_RSL_L, 0); + mdelay(WWAN_TOFF); + gpio_set(WWAN_FCPO_L, 0); + } +} diff --git a/src/mainboard/google/brox/variants/juchi/variant.c b/src/mainboard/google/brox/variants/juchi/variant.c new file mode 100644 index 00000000000..ed0f3de01e5 --- /dev/null +++ b/src/mainboard/google/brox/variants/juchi/variant.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include + +#include "gpio.h" + +#define WWAN_RSL_L GPP_H23 +#define WWAN_FCPO_L GPP_F21 + +void variant_update_soc_chip_config(struct soc_intel_alderlake_config *config) +{ + if (fw_config_probe(FW_CONFIG(WIFI_BT, WIFI_BT_CNVI)) || (!fw_config_is_provisioned())) { + printk(BIOS_INFO, "CNVi bluetooth enabled by fw_config\n"); + config->cnvi_bt_core = true; + config->cnvi_bt_audio_offload = true; + } else { + printk(BIOS_INFO, "CNVi bluetooth disabled by fw_config\n"); + config->cnvi_bt_core = false; + config->cnvi_bt_audio_offload = false; + } +} + +const char *get_wifi_sar_cbfs_filename(void) +{ + return get_wifi_sar_fw_config_filename(FW_CONFIG_FIELD(WIFI_BT)); +} + +const char *variant_get_auxfw_version_file(void) +{ + return "rts5453_retimer_bypass.hash"; +} + +static void wwan_out_of_reset(void *unused) +{ + if (fw_config_probe(FW_CONFIG(DB_USB, DB_1A_LTE)) || + fw_config_probe(FW_CONFIG(DB_USB, DB_1A_LTE_SAR))) { + gpio_set(WWAN_FCPO_L, 1); + gpio_set(WWAN_RSL_L, 1); + } +} +BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, wwan_out_of_reset, NULL); diff --git a/src/mainboard/google/brox/variants/lotso/memory/Makefile.mk b/src/mainboard/google/brox/variants/lotso/memory/Makefile.mk index 64f4e227ba2..e38115911fd 100644 --- a/src/mainboard/google/brox/variants/lotso/memory/Makefile.mk +++ b/src/mainboard/google/brox/variants/lotso/memory/Makefile.mk @@ -7,4 +7,4 @@ SPD_SOURCES = SPD_SOURCES += spd/lp5/set-0/spd-9.hex # ID = 0(0b0000) Parts = K3KL6L60GM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 1(0b0001) Parts = H9JCNNNBK3MLYR-N6E SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 2(0b0010) Parts = K3KL8L80DM-MGCU, MT62F1G32D2DS-023 WT:C, H58G56BK8BX068, H58G56CK8BX146, K3KL8L80EM-MGCU -SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = H58G56BK7BX068 +SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = H58G56BK7BX068, K3KL8L80CM-MGCT diff --git a/src/mainboard/google/brox/variants/lotso/memory/dram_id.generated.txt b/src/mainboard/google/brox/variants/lotso/memory/dram_id.generated.txt index a4824fd008e..c27f7926ca8 100644 --- a/src/mainboard/google/brox/variants/lotso/memory/dram_id.generated.txt +++ b/src/mainboard/google/brox/variants/lotso/memory/dram_id.generated.txt @@ -9,6 +9,7 @@ H9JCNNNBK3MLYR-N6E 1 (0001) K3KL8L80DM-MGCU 2 (0010) MT62F1G32D2DS-023 WT:C 2 (0010) H58G56BK8BX068 2 (0010) -H58G56BK7BX068 3 (0011) H58G56CK8BX146 2 (0010) K3KL8L80EM-MGCU 2 (0010) +H58G56BK7BX068 3 (0011) +K3KL8L80CM-MGCT 3 (0011) diff --git a/src/mainboard/google/brox/variants/lotso/memory/mem_parts_used.txt b/src/mainboard/google/brox/variants/lotso/memory/mem_parts_used.txt index dac8c9957c5..7df5ad3b41b 100644 --- a/src/mainboard/google/brox/variants/lotso/memory/mem_parts_used.txt +++ b/src/mainboard/google/brox/variants/lotso/memory/mem_parts_used.txt @@ -10,10 +10,11 @@ # Part Name K3KL6L60GM-MGCT +K3KL8L80CM-MGCT H9JCNNNBK3MLYR-N6E K3KL8L80DM-MGCU MT62F1G32D2DS-023 WT:C H58G56BK8BX068 -H58G56BK7BX068 H58G56CK8BX146 K3KL8L80EM-MGCU +H58G56BK7BX068 diff --git a/src/mainboard/google/brya/Kconfig b/src/mainboard/google/brya/Kconfig index b871d32fa6d..c7fad434f4d 100644 --- a/src/mainboard/google/brya/Kconfig +++ b/src/mainboard/google/brya/Kconfig @@ -96,6 +96,7 @@ config BOARD_GOOGLE_BASEBOARD_NISSA select DRIVERS_GFX_GENERIC select DRIVERS_INTEL_ISH select FSP_TYPE_IOT if !CHROMEOS + select HAVE_CHIPSETINIT_BINARY select MAINBOARD_DISABLE_STAGE_CACHE select MAINBOARD_HAS_EARLY_LIBGFXINIT select MEMORY_SOLDERDOWN @@ -115,6 +116,7 @@ config BOARD_GOOGLE_BASEBOARD_TRULO select DRIVERS_GFX_GENERIC select DRIVERS_INTEL_ISH select DRIVER_INTEL_ISH_HAS_MAIN_FW + select HAVE_CHIPSETINIT_BINARY select MAINBOARD_DISABLE_STAGE_CACHE select MAINBOARD_HAS_EARLY_LIBGFXINIT select MEMORY_SOLDERDOWN @@ -303,6 +305,7 @@ config BOARD_GOOGLE_GOTHRAX select DRIVERS_I2C_SX9324 select DRIVERS_I2C_SX9324_SUPPORT_LEGACY_LINUX_DRIVER select HAVE_WWAN_POWER_SEQUENCE + select CHROMEOS_WIFI_SAR if CHROMEOS config BOARD_GOOGLE_GUREN select BOARD_GOOGLE_BASEBOARD_NISSA @@ -356,6 +359,13 @@ config BOARD_GOOGLE_KULDAX select INTEL_GMA_HAVE_VBT select SOC_INTEL_RAPTORLAKE +config BOARD_GOOGLE_KULNEX + select BOARD_GOOGLE_BASEBOARD_BRASK + select DRIVERS_GENESYSLOGIC_GL9755 + select EC_GOOGLE_CHROMEEC_INCLUDE_SSFC_IN_FW_CONFIG + select INTEL_GMA_HAVE_VBT + select SOC_INTEL_RAPTORLAKE + config BOARD_GOOGLE_JOXER select BOARD_GOOGLE_BASEBOARD_NISSA select CHROMEOS_WIFI_SAR if CHROMEOS @@ -404,6 +414,13 @@ config BOARD_GOOGLE_MOXIE select INTEL_GMA_HAVE_VBT select SOC_INTEL_RAPTORLAKE +config BOARD_GOOGLE_MOXOE + select BOARD_GOOGLE_BASEBOARD_BRASK + select DRIVERS_GENESYSLOGIC_GL9755 + select EC_GOOGLE_CHROMEEC_INCLUDE_SSFC_IN_FW_CONFIG + select INTEL_GMA_HAVE_VBT + select SOC_INTEL_RAPTORLAKE + config BOARD_GOOGLE_NIVVIKS select BOARD_GOOGLE_BASEBOARD_NISSA select BOARD_ROMSIZE_KB_32768 @@ -592,6 +609,7 @@ config BOARD_GOOGLE_RIVEN select CHROMEOS_WIFI_SAR if CHROMEOS select DRIVERS_GENERIC_GPIO_KEYS select DRIVERS_INTEL_MIPI_CAMERA + select ENFORCE_MEM_CHANNEL_DISABLE select HAVE_WWAN_POWER_SEQUENCE select INTEL_GMA_HAVE_VBT select MAINBOARD_HAS_GOOGLE_STRAUSS_KEYBOARD @@ -604,6 +622,7 @@ config BOARD_GOOGLE_RULL select CHROMEOS_WIFI_SAR if CHROMEOS select DRIVERS_GENERIC_BAYHUB_LV2 select DRIVERS_GENERIC_GPIO_KEYS + select ENFORCE_MEM_CHANNEL_DISABLE select MAINBOARD_HAS_GOOGLE_STRAUSS_KEYBOARD select SOC_INTEL_TWINLAKE @@ -771,7 +790,7 @@ config BOARD_GOOGLE_YAVIKS select EC_GOOGLE_CHROMEEC_INCLUDE_SSFC_IN_FW_CONFIG select HAVE_WWAN_POWER_SEQUENCE select INTEL_GMA_HAVE_VBT - select USE_MTCL + select USE_MTCL if CHROMEOS config BOARD_GOOGLE_YAVILLA select BOARD_GOOGLE_BASEBOARD_NISSA @@ -862,11 +881,13 @@ config DRIVER_TPM_I2C_BUS default 0x0 if BOARD_GOOGLE_KALADIN default 0x1 if BOARD_GOOGLE_KINOX default 0x1 if BOARD_GOOGLE_KULDAX + default 0x1 if BOARD_GOOGLE_KULNEX default 0x1 if BOARD_GOOGLE_LISBON default 0x1 if BOARD_GOOGLE_MARASOV default 0x1 if BOARD_GOOGLE_MITHRAX default 0x1 if BOARD_GOOGLE_MOLI default 0x1 if BOARD_GOOGLE_MOXIE + default 0x1 if BOARD_GOOGLE_MOXOE default 0x0 if BOARD_GOOGLE_NEREID default 0x0 if BOARD_GOOGLE_NIVVIKS default 0x1 if BOARD_GOOGLE_NOVA @@ -950,11 +971,13 @@ config TPM_TIS_ACPI_INTERRUPT default 13 if BOARD_GOOGLE_KALADIN default 13 if BOARD_GOOGLE_KINOX default 13 if BOARD_GOOGLE_KULDAX + default 13 if BOARD_GOOGLE_KULNEX default 13 if BOARD_GOOGLE_LISBON default 13 if BOARD_GOOGLE_MARASOV default 13 if BOARD_GOOGLE_MITHRAX default 13 if BOARD_GOOGLE_MOLI default 13 if BOARD_GOOGLE_MOXIE + default 13 if BOARD_GOOGLE_MOXOE default 13 if BOARD_GOOGLE_NEREID default 13 if BOARD_GOOGLE_NIVVIKS default 13 if BOARD_GOOGLE_NOVA @@ -1042,11 +1065,13 @@ config MAINBOARD_PART_NUMBER default "Kaladin" if BOARD_GOOGLE_KALADIN default "Kinox" if BOARD_GOOGLE_KINOX default "Kuldax" if BOARD_GOOGLE_KULDAX + default "Kulnex" if BOARD_GOOGLE_KULNEX default "Lisbon" if BOARD_GOOGLE_LISBON default "Marasov" if BOARD_GOOGLE_MARASOV default "Mithrax" if BOARD_GOOGLE_MITHRAX default "Moli" if BOARD_GOOGLE_MOLI default "Moxie" if BOARD_GOOGLE_MOXIE + default "Moxoe" if BOARD_GOOGLE_MOXOE default "Nereid" if BOARD_GOOGLE_NEREID default "Nivviks" if BOARD_GOOGLE_NIVVIKS default "Nokris" if BOARD_GOOGLE_NOKRIS @@ -1123,11 +1148,13 @@ config VARIANT_DIR default "kaladin" if BOARD_GOOGLE_KALADIN default "kinox" if BOARD_GOOGLE_KINOX default "kuldax" if BOARD_GOOGLE_KULDAX + default "kulnex" if BOARD_GOOGLE_KULNEX default "lisbon" if BOARD_GOOGLE_LISBON default "marasov" if BOARD_GOOGLE_MARASOV default "mithrax" if BOARD_GOOGLE_MITHRAX default "moli" if BOARD_GOOGLE_MOLI default "moxie" if BOARD_GOOGLE_MOXIE + default "moxoe" if BOARD_GOOGLE_MOXOE default "nereid" if BOARD_GOOGLE_NEREID default "nereid" if BOARD_GOOGLE_TEREID default "nivviks" if BOARD_GOOGLE_NIVVIKS @@ -1174,14 +1201,18 @@ config VARIANT_DIR default "pujjolo" if BOARD_GOOGLE_PUJJOLO config VBOOT - select VBOOT_EARLY_EC_SYNC if !(BOARD_GOOGLE_BASEBOARD_NISSA || BOARD_GOOGLE_BASEBOARD_TRULO) || BOARD_GOOGLE_RULL - select VBOOT_EC_SYNC_ESOL if BOARD_GOOGLE_RULL + select VBOOT_EARLY_EC_SYNC if !(BOARD_GOOGLE_BASEBOARD_NISSA || BOARD_GOOGLE_BASEBOARD_TRULO) || BOARD_GOOGLE_RULL || BOARD_GOOGLE_GOTHRAX || BOARD_GOOGLE_EPIC + select VBOOT_EC_SYNC_ESOL if BOARD_GOOGLE_RULL || BOARD_GOOGLE_GOTHRAX || BOARD_GOOGLE_EPIC select VBOOT_LID_SWITCH config UART_FOR_CONSOLE int default 0 +config CBFS_SIZE + default 0xc60000 if BOARD_ROMSIZE_KB_16384 + default 0x1000000 if BOARD_ROMSIZE_KB_32768 + config HAVE_WWAN_POWER_SEQUENCE def_bool n help diff --git a/src/mainboard/google/brya/Kconfig.name b/src/mainboard/google/brya/Kconfig.name index 2565a426ef9..bce6d1c83f1 100644 --- a/src/mainboard/google/brya/Kconfig.name +++ b/src/mainboard/google/brya/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Brya" +comment "Brya (Intel AlderLake/RaptorLake/TwinLake (12 - 13th Gen))" config BOARD_GOOGLE_AGAH bool "-> Agah" @@ -95,6 +95,9 @@ config BOARD_GOOGLE_KINOX config BOARD_GOOGLE_KULDAX bool "-> Kuldax (ASUS Chromebox 5/5a (CN67))" +config BOARD_GOOGLE_KULNEX + bool "-> Kulnex" + config BOARD_GOOGLE_JOXER bool "-> Joxer (HP Chromebook x360 14b)" @@ -118,6 +121,9 @@ config BOARD_GOOGLE_MOLI config BOARD_GOOGLE_MOXIE bool "-> Moxie (Acer Chromebox CXI6)" +config BOARD_GOOGLE_MOXOE + bool "-> Moxoe" + config BOARD_GOOGLE_NIVVIKS bool "-> Nivviks" @@ -189,7 +195,7 @@ config BOARD_GOOGLE_TEREID bool "-> Tereid" config BOARD_GOOGLE_TIVVIKS - bool "-> Tivviks" + bool "-> Tivviks" config BOARD_GOOGLE_TRULO bool "-> Trulo" diff --git a/src/mainboard/google/brya/acpi/cnvi_bt_reset.asl b/src/mainboard/google/brya/acpi/cnvi_bt_reset.asl index 6e84522145d..4fd2ad74491 100644 --- a/src/mainboard/google/brya/acpi/cnvi_bt_reset.asl +++ b/src/mainboard/google/brya/acpi/cnvi_bt_reset.asl @@ -22,7 +22,7 @@ External (\_SB.PCI0.GTXS, MethodObj) Scope (\_SB.PCI0.XHCI.RHUB.HS10) { - PowerResource (CTTR, 0x00, 0x0000) + PowerResource (CTTR, 0x05, 0x0000) { Method (_STA, 0, NotSerialized) // _STA: Status { @@ -31,32 +31,30 @@ Scope (\_SB.PCI0.XHCI.RHUB.HS10) Method (_ON, 0, NotSerialized) // _ON_: Power On { - If (LEqual (\_SB.PCI0.GTXS(BT_RESET_GPIO), 0)) { - \_SB.PCI0.STXS(CNV_BTEN) - \_SB.PCI0.STXS(CNV_BT_IF_SELECT) - \_SB.PCI0.STXS(BT_RESET_GPIO) - } } Method (_OFF, 0, NotSerialized) // _OFF: Power Off { - If (LEqual (\_SB.PCI0.GTXS(BT_RESET_GPIO), 1)) { - \_SB.PCI0.CTXS(CNV_BTEN) - \_SB.PCI0.CTXS(CNV_BT_IF_SELECT) - \_SB.PCI0.CTXS(BT_RESET_GPIO) - Sleep (BT_RESET_DELAY_MS) - } } + Method (_RST, 0, NotSerialized) // _RST: Device Reset + { + \_SB.PCI0.CTXS(CNV_BTEN) + \_SB.PCI0.CTXS(CNV_BT_IF_SELECT) + \_SB.PCI0.CTXS(BT_RESET_GPIO) + Sleep (BT_RESET_DELAY_MS) + \_SB.PCI0.STXS(CNV_BTEN) + \_SB.PCI0.STXS(CNV_BT_IF_SELECT) + \_SB.PCI0.STXS(BT_RESET_GPIO) + Sleep (BT_RESET_DELAY_MS) + } } - Name (_PRR, Package (0x01) // _PRR: Power Resource for Reset - { - CTTR - }) - - Name (_PR0, Package (0x01) // _PR0: Power Resources for D0 + Method (_PRR, 0, NotSerialized) // _PRR: Power Resource for Reset { - CTTR - }) + Return (Package (0x01) + { + CTTR + }) + } } diff --git a/src/mainboard/google/brya/cfr.c b/src/mainboard/google/brya/cfr.c index 637e1b38d59..21281450425 100644 --- a/src/mainboard/google/brya/cfr.c +++ b/src/mainboard/google/brya/cfr.c @@ -1,4 +1,3 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ #include diff --git a/src/mainboard/google/brya/variants/anahera/overridetree.cb b/src/mainboard/google/brya/variants/anahera/overridetree.cb index 12566087db5..b0dfb815263 100644 --- a/src/mainboard/google/brya/variants/anahera/overridetree.cb +++ b/src/mainboard/google/brya/variants/anahera/overridetree.cb @@ -202,7 +202,7 @@ chip soc/intel/alderlake register "pch_pcie_rp[PCH_RP(7)]" = "{ .clk_src = 6, .clk_req = 6, - .flags = PCIE_RP_HOTPLUG | PCIE_RP_AER, + .flags = PCIE_RP_HOTPLUG | PCIE_RP_AER | PCIE_RP_BUILT_IN, }" end #PCIE7 EMMC device ref tcss_dma0 on diff --git a/src/mainboard/google/brya/variants/anahera4es/overridetree.cb b/src/mainboard/google/brya/variants/anahera4es/overridetree.cb index 33daa9962c0..41393781c75 100644 --- a/src/mainboard/google/brya/variants/anahera4es/overridetree.cb +++ b/src/mainboard/google/brya/variants/anahera4es/overridetree.cb @@ -184,7 +184,7 @@ chip soc/intel/alderlake register "pch_pcie_rp[PCH_RP(7)]" = "{ .clk_src = 6, .clk_req = 6, - .flags = PCIE_RP_HOTPLUG | PCIE_RP_AER, + .flags = PCIE_RP_HOTPLUG | PCIE_RP_AER | PCIE_RP_BUILT_IN, }" end #PCIE7 EMMC device ref tcss_dma0 on diff --git a/src/mainboard/google/brya/variants/anraggar/overridetree.cb b/src/mainboard/google/brya/variants/anraggar/overridetree.cb index 877eec4700c..c9500476e90 100644 --- a/src/mainboard/google/brya/variants/anraggar/overridetree.cb +++ b/src/mainboard/google/brya/variants/anraggar/overridetree.cb @@ -263,13 +263,15 @@ chip soc/intel/alderlake end device ref i2c2 on chip drivers/intel/mipi_camera - register "acpi_hid" = ""OVTIDB10"" + register "acpi_hid" = ""OVTI13B1"" register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 13b10 Camera"" + register "sensor_name" = ""09B13U"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "1" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/aurash/overridetree.cb b/src/mainboard/google/brya/variants/aurash/overridetree.cb index a18197627c8..0d2cd9974bf 100644 --- a/src/mainboard/google/brya/variants/aurash/overridetree.cb +++ b/src/mainboard/google/brya/variants/aurash/overridetree.cb @@ -193,7 +193,7 @@ chip soc/intel/alderlake register "pch_pcie_rp[PCH_RP(12)]" = "{ .clk_src = 1, .clk_req = 1, - .flags = PCIE_RP_LTR | PCIE_RP_AER, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_BUILT_IN, }" probe STORAGE STORAGE_EMMC probe STORAGE STORAGE_UNKNOWN diff --git a/src/mainboard/google/brya/variants/brya0/overridetree.cb b/src/mainboard/google/brya/variants/brya0/overridetree.cb index 3139af5218b..40f75629cfb 100644 --- a/src/mainboard/google/brya/variants/brya0/overridetree.cb +++ b/src/mainboard/google/brya/variants/brya0/overridetree.cb @@ -543,7 +543,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "0" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9808" register "vcm_address" = "0x0C" @@ -653,7 +653,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "0" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9808" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/craask/overridetree.cb b/src/mainboard/google/brya/variants/craask/overridetree.cb index 86a5cfc465c..71c56512623 100644 --- a/src/mainboard/google/brya/variants/craask/overridetree.cb +++ b/src/mainboard/google/brya/variants/craask/overridetree.cb @@ -477,6 +477,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 5675 Camera"" + register "sensor_name" = ""CJFLE39"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" @@ -524,6 +525,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" diff --git a/src/mainboard/google/brya/variants/crota/overridetree.cb b/src/mainboard/google/brya/variants/crota/overridetree.cb index a55c68c98e2..a7994127c14 100644 --- a/src/mainboard/google/brya/variants/crota/overridetree.cb +++ b/src/mainboard/google/brya/variants/crota/overridetree.cb @@ -203,7 +203,7 @@ chip soc/intel/alderlake register "pch_pcie_rp[PCH_RP(3)]" = "{ .clk_src = 1, .clk_req = 1, - .flags = PCIE_RP_LTR | PCIE_RP_AER, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_BUILT_IN, }" end #PCIE3 BH799BB device ref pcie_rp9 off end diff --git a/src/mainboard/google/brya/variants/gladios/overridetree.cb b/src/mainboard/google/brya/variants/gladios/overridetree.cb index 6c3eaf952aa..10b54c4f929 100644 --- a/src/mainboard/google/brya/variants/gladios/overridetree.cb +++ b/src/mainboard/google/brya/variants/gladios/overridetree.cb @@ -213,7 +213,7 @@ chip soc/intel/alderlake register "pch_pcie_rp[PCH_RP(12)]" = "{ .clk_src = 4, .clk_req = 4, - .flags = PCIE_RP_HOTPLUG | PCIE_RP_AER, + .flags = PCIE_RP_HOTPLUG | PCIE_RP_AER | PCIE_RP_BUILT_IN, }" probe STORAGE STORAGE_EMMC end #PCIE12 EMMC diff --git a/src/mainboard/google/brya/variants/gothrax/memory/Makefile.mk b/src/mainboard/google/brya/variants/gothrax/memory/Makefile.mk index c323ea6ae64..44065b51d07 100644 --- a/src/mainboard/google/brya/variants/gothrax/memory/Makefile.mk +++ b/src/mainboard/google/brya/variants/gothrax/memory/Makefile.mk @@ -9,3 +9,4 @@ SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 1(0b0001) Parts = H58G56AK6B SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 2(0b0010) Parts = K3LKBKB0BM-MGCP SPD_SOURCES += spd/lp5/set-0/spd-2.hex # ID = 3(0b0011) Parts = H9JCNNNCP3MLYR-N6E SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 4(0b0100) Parts = K3KL8L80CM-MGCT +SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 5(0b0101) Parts = RS1G32LO5D2FDB-23BT diff --git a/src/mainboard/google/brya/variants/gothrax/memory/dram_id.generated.txt b/src/mainboard/google/brya/variants/gothrax/memory/dram_id.generated.txt index 8892ad8cb6d..9848a35a359 100644 --- a/src/mainboard/google/brya/variants/gothrax/memory/dram_id.generated.txt +++ b/src/mainboard/google/brya/variants/gothrax/memory/dram_id.generated.txt @@ -10,3 +10,4 @@ K3LKBKB0BM-MGCP 2 (0010) H9JCNNNBK3MLYR-N6E 0 (0000) H9JCNNNCP3MLYR-N6E 3 (0011) K3KL8L80CM-MGCT 4 (0100) +RS1G32LO5D2FDB-23BT 5 (0101) diff --git a/src/mainboard/google/brya/variants/gothrax/memory/mem_parts_used.txt b/src/mainboard/google/brya/variants/gothrax/memory/mem_parts_used.txt index bb85c55f8ba..baf0ab19af4 100644 --- a/src/mainboard/google/brya/variants/gothrax/memory/mem_parts_used.txt +++ b/src/mainboard/google/brya/variants/gothrax/memory/mem_parts_used.txt @@ -16,3 +16,4 @@ K3LKBKB0BM-MGCP, H9JCNNNBK3MLYR-N6E, H9JCNNNCP3MLYR-N6E, K3KL8L80CM-MGCT, +RS1G32LO5D2FDB-23BT, diff --git a/src/mainboard/google/brya/variants/gothrax/variant.c b/src/mainboard/google/brya/variants/gothrax/variant.c index 8b8822bf4ff..ab134c2ba72 100644 --- a/src/mainboard/google/brya/variants/gothrax/variant.c +++ b/src/mainboard/google/brya/variants/gothrax/variant.c @@ -4,6 +4,7 @@ #include #include #include +#include void variant_update_soc_chip_config(struct soc_intel_alderlake_config *config) { @@ -40,3 +41,8 @@ void variant_update_soc_chip_config(struct soc_intel_alderlake_config *config) config->typec_aux_bias_pads[1].pad_auxn_dc = 0x00; } } + +const char *get_wifi_sar_cbfs_filename(void) +{ + return get_wifi_sar_fw_config_filename(FW_CONFIG_FIELD(WLAN)); +} diff --git a/src/mainboard/google/brya/variants/kaladin/overridetree.cb b/src/mainboard/google/brya/variants/kaladin/overridetree.cb index a31ed720c5c..8f7f8e2be52 100644 --- a/src/mainboard/google/brya/variants/kaladin/overridetree.cb +++ b/src/mainboard/google/brya/variants/kaladin/overridetree.cb @@ -552,7 +552,7 @@ chip soc/intel/alderlake register "generic.reset_delay_ms" = "70" register "generic.reset_off_delay_ms" = "2" register "generic.stop_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_C4)" - register "generic.stop_delay_ms" = "280" + register "generic.stop_delay_ms" = "150" register "generic.stop_off_delay_ms" = "2" register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_C0)" register "generic.enable_delay_ms" = "1" @@ -571,7 +571,7 @@ chip soc/intel/alderlake register "generic.reset_delay_ms" = "70" register "generic.reset_off_delay_ms" = "2" register "generic.stop_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_C4)" - register "generic.stop_delay_ms" = "280" + register "generic.stop_delay_ms" = "150" register "generic.stop_off_delay_ms" = "2" register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_C0)" register "generic.enable_delay_ms" = "1" diff --git a/src/mainboard/google/brya/variants/kano/overridetree.cb b/src/mainboard/google/brya/variants/kano/overridetree.cb index 73065130e65..89cb3317997 100644 --- a/src/mainboard/google/brya/variants/kano/overridetree.cb +++ b/src/mainboard/google/brya/variants/kano/overridetree.cb @@ -98,7 +98,7 @@ chip soc/intel/alderlake device domain 0 on device ref igpu on chip drivers/gfx/generic - register "device_count" = "6" + register "device_count" = "7" # DDIA for eDP register "device[0].name" = ""LCD0"" # Internal panel on the first port of the graphics chip @@ -117,6 +117,10 @@ chip soc/intel/alderlake register "device[4].pld" = "ACPI_PLD_TYPE_C(RIGHT, RIGHT, ACPI_PLD_GROUP(2, 1))" # TCP3 (DP-4) is unused for any ports but still enumerated in the kernel, so GFX device is added for TCP3 register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" device generic 0 on end end end # Integrated Graphics Device @@ -322,6 +326,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 2740 Camera"" + register "sensor_name" = ""CJFLE23"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" @@ -365,6 +370,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Hi-556 Camera"" + register "sensor_name" = ""CJFLE25"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" diff --git a/src/mainboard/google/brya/variants/kinox/overridetree.cb b/src/mainboard/google/brya/variants/kinox/overridetree.cb index d0740b339dc..5b708f08f7c 100644 --- a/src/mainboard/google/brya/variants/kinox/overridetree.cb +++ b/src/mainboard/google/brya/variants/kinox/overridetree.cb @@ -261,7 +261,7 @@ chip soc/intel/alderlake register "pch_pcie_rp[PCH_RP(6)]" = "{ .clk_src = 1, .clk_req = 1, - .flags = PCIE_RP_LTR | PCIE_RP_AER, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_BUILT_IN, }" chip soc/intel/common/block/pcie/rtd3 register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_H13)" diff --git a/src/mainboard/google/brya/variants/kulnex/Makefile.mk b/src/mainboard/google/brya/variants/kulnex/Makefile.mk new file mode 100644 index 00000000000..2b274c69e23 --- /dev/null +++ b/src/mainboard/google/brya/variants/kulnex/Makefile.mk @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0-only +bootblock-y += gpio.c + +romstage-y += memory.c +romstage-y += gpio.c + +ramstage-y += gpio.c +ramstage-y += ramstage.c +ramstage-$(CONFIG_FW_CONFIG) += fw_config.c +ramstage-$(CONFIG_FW_CONFIG) += variant.c diff --git a/src/mainboard/google/brya/variants/kulnex/data.vbt b/src/mainboard/google/brya/variants/kulnex/data.vbt new file mode 100644 index 00000000000..7d14588c613 Binary files /dev/null and b/src/mainboard/google/brya/variants/kulnex/data.vbt differ diff --git a/src/mainboard/google/brya/variants/kulnex/fw_config.c b/src/mainboard/google/brya/variants/kulnex/fw_config.c new file mode 100644 index 00000000000..42613af1631 --- /dev/null +++ b/src/mainboard/google/brya/variants/kulnex/fw_config.c @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +static const struct pad_config dmic_enable_pads[] = { + PAD_CFG_NF(GPP_R6, NONE, DEEP, NF3), /* DMIC_CLK1_R */ + PAD_CFG_NF(GPP_R7, NONE, DEEP, NF3), /* DMIC_DATA1_R */ +}; + +static const struct pad_config dmic_disable_pads[] = { + PAD_NC(GPP_R6, NONE), + PAD_NC(GPP_R7, NONE), +}; + +static const struct pad_config i2s_enable_pads[] = { + PAD_CFG_NF(GPP_R0, NONE, DEEP, NF2), /* I2S_HP_SCLK_R */ + PAD_CFG_NF(GPP_R1, NONE, DEEP, NF2), /* I2S_HP_SFRM_R */ + PAD_CFG_NF(GPP_R2, DN_20K, DEEP, NF2), /* I2S_PCH_TX_HP_RX_STRAP */ + PAD_CFG_NF(GPP_R3, NONE, DEEP, NF2), /* I2S_PCH_RX_HP_TX */ +}; + +static const struct pad_config i2s_disable_pads[] = { + PAD_NC(GPP_R0, NONE), + PAD_NC(GPP_R1, NONE), + PAD_NC(GPP_R2, NONE), + PAD_NC(GPP_R3, NONE), +}; + +static const struct pad_config bt_i2s_enable_pads[] = { + PAD_CFG_NF(GPP_VGPIO_30, NONE, DEEP, NF3), /* BT_I2S_BCLK */ + PAD_CFG_NF(GPP_VGPIO_31, NONE, DEEP, NF3), /* BT_I2S_SYNC */ + PAD_CFG_NF(GPP_VGPIO_32, NONE, DEEP, NF3), /* BT_I2S_SDO */ + PAD_CFG_NF(GPP_VGPIO_33, NONE, DEEP, NF3), /* BT_I2S_SDI */ + PAD_CFG_NF(GPP_VGPIO_34, NONE, DEEP, NF1), /* SSP2_SCLK */ + PAD_CFG_NF(GPP_VGPIO_35, NONE, DEEP, NF1), /* SSP2_SFRM */ + PAD_CFG_NF(GPP_VGPIO_36, NONE, DEEP, NF1), /* SSP_TXD */ + PAD_CFG_NF(GPP_VGPIO_37, NONE, DEEP, NF1), /* SSP_RXD */ +}; + +static const struct pad_config bt_i2s_disable_pads[] = { + PAD_NC(GPP_VGPIO_30, NONE), + PAD_NC(GPP_VGPIO_31, NONE), + PAD_NC(GPP_VGPIO_32, NONE), + PAD_NC(GPP_VGPIO_33, NONE), + PAD_NC(GPP_VGPIO_34, NONE), + PAD_NC(GPP_VGPIO_35, NONE), + PAD_NC(GPP_VGPIO_36, NONE), + PAD_NC(GPP_VGPIO_37, NONE), +}; + +static void fw_config_handle(void *unused) +{ + if (!fw_config_is_provisioned() || fw_config_probe(FW_CONFIG(AUDIO, AUDIO_UNKNOWN))) { + printk(BIOS_INFO, "Disable audio related GPIO pins.\n"); + gpio_configure_pads(i2s_disable_pads, ARRAY_SIZE(i2s_disable_pads)); + gpio_configure_pads(dmic_disable_pads, ARRAY_SIZE(dmic_disable_pads)); + gpio_configure_pads(bt_i2s_disable_pads, ARRAY_SIZE(bt_i2s_disable_pads)); + return; + } + + if (fw_config_probe(FW_CONFIG(AUDIO, NAU88L25B_I2S))) { + printk(BIOS_INFO, "Configure audio over I2S with NAU88L25B.\n"); + gpio_configure_pads(dmic_enable_pads, ARRAY_SIZE(dmic_enable_pads)); + gpio_configure_pads(i2s_enable_pads, ARRAY_SIZE(i2s_enable_pads)); + printk(BIOS_INFO, "BT offload enabled\n"); + gpio_configure_pads(bt_i2s_enable_pads, ARRAY_SIZE(bt_i2s_enable_pads)); + } else { + printk(BIOS_INFO, "BT offload disabled\n"); + gpio_configure_pads(bt_i2s_disable_pads, ARRAY_SIZE(bt_i2s_disable_pads)); + } +} +BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, fw_config_handle, NULL); diff --git a/src/mainboard/google/brya/variants/kulnex/gpio.c b/src/mainboard/google/brya/variants/kulnex/gpio.c new file mode 100644 index 00000000000..556e8b694c9 --- /dev/null +++ b/src/mainboard/google/brya/variants/kulnex/gpio.c @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include + +/* Pad configuration in ramstage */ +static const struct pad_config override_gpio_table[] = { + /* A14 : USB_OC1# ==> HDMIA_HPD */ + PAD_CFG_NF(GPP_A14, NONE, DEEP, NF2), + /* A15 : USB_OC2# ==> NC */ + PAD_NC(GPP_A15, NONE), + /* A19 : DDSP_HPD1 ==> NC */ + PAD_NC(GPP_A19, NONE), + /* A20 : DDSP_HPD2 ==> NC */ + PAD_NC(GPP_A20, NONE), + /* A21 : DDPC_CTRCLK ==> NC */ + PAD_NC(GPP_A21, NONE), + /* A22 : DDPC_CTRLDATA ==> NC */ + PAD_NC(GPP_A22, NONE), + + /* B7 : ISH_12C1_SDA ==> PCH_I2C_MISCB_SDA */ + PAD_CFG_NF_LOCK(GPP_B7, NONE, NF2, LOCK_CONFIG), + /* B8 : ISH_I2C1_SCL ==> PCH_I2C_MISCB_SCL */ + PAD_CFG_NF_LOCK(GPP_B8, NONE, NF2, LOCK_CONFIG), + + /* C3 : SML0CLK ==> USB_C0_AUX_DC_P */ + PAD_CFG_NF(GPP_C3, NONE, DEEP, NF6), + /* C4 : SML0DATA ==> USB_C0_AUX_DC_N */ + PAD_CFG_NF(GPP_C4, NONE, DEEP, NF6), + + /* D0 : ISH_GP0 ==> NC */ + PAD_NC_LOCK(GPP_D0, NONE, LOCK_CONFIG), + /* D1 : ISH_GP1 ==> NC */ + PAD_NC_LOCK(GPP_D1, NONE, LOCK_CONFIG), + /* D2 : ISH_GP2 ==> NC */ + PAD_NC_LOCK(GPP_D2, NONE, LOCK_CONFIG), + /* D3 : ISH_GP3 ==> NC */ + PAD_NC_LOCK(GPP_D3, NONE, LOCK_CONFIG), + /* D9 : ISH_SPI_CS# ==> NC */ + PAD_NC_LOCK(GPP_D9, NONE, LOCK_CONFIG), + + /* E20 : DDP2_CTRLCLK ==> HDMIA_CTRLCLK */ + PAD_CFG_NF(GPP_E20, NONE, DEEP, NF1), + /* E21 : DDP2_CTRLDATA ==> HDMIA_CTRLDATA_STRAP */ + PAD_CFG_NF(GPP_E21, NONE, DEEP, NF1), + + /* F11 : THC1_SPI2_CLK ==> NC */ + PAD_NC_LOCK(GPP_F11, NONE, LOCK_CONFIG), + /* F12 : GSXDOUT ==> NC */ + PAD_NC_LOCK(GPP_F12, NONE, LOCK_CONFIG), + /* F13 : GSXDOUT ==> NC */ + PAD_NC_LOCK(GPP_F13, NONE, LOCK_CONFIG), + /* F15 : GSXSRESET# ==> NC */ + PAD_NC_LOCK(GPP_F15, NONE, LOCK_CONFIG), + /* F16 : GSXCLK ==> NC */ + PAD_NC_LOCK(GPP_F16, NONE, LOCK_CONFIG), + + /* R4 : HDA_RST# ==> NC */ + PAD_NC(GPP_R4, NONE), + /* R5 : HDA_SDI1 ==> NC */ + PAD_NC(GPP_R5, NONE), +}; + +/* Early pad configuration in bootblock */ +static const struct pad_config early_gpio_table[] = { + /* A13 : PMC_I2C_SCL ==> GSC_PCH_INT_ODL */ + PAD_CFG_GPI_APIC(GPP_A13, NONE, PLTRST, LEVEL, INVERT), + /* B4 : PROC_GP3 ==> SSD_PERST_L */ + PAD_CFG_GPO(GPP_B4, 0, DEEP), + /* E15 : RSVD_TP ==> PCH_WP_OD */ + PAD_CFG_GPI_GPIO_DRIVER(GPP_E15, NONE, DEEP), + /* F14 : GSXDIN ==> EN_PP3300_SSD */ + PAD_CFG_GPO(GPP_F14, 1, DEEP), + /* F18 : THC1_SPI2_INT# ==> EC_IN_RW_OD */ + PAD_CFG_GPI(GPP_F18, NONE, DEEP), + /* H6 : I2C1_SDA ==> PCH_I2C_TPM_SDA */ + PAD_CFG_NF(GPP_H6, NONE, DEEP, NF1), + /* H7 : I2C1_SCL ==> PCH_I2C_TPM_SCL */ + PAD_CFG_NF(GPP_H7, NONE, DEEP, NF1), + /* H10 : UART0_RXD ==> UART_PCH_RX_DBG_TX */ + PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), + /* H11 : UART0_TXD ==> UART_PCH_TX_DBG_RX */ + PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), + /* H13 : I2C7_SCL ==> EN_PP3300_SD */ + PAD_CFG_GPO(GPP_H13, 1, DEEP), + + /* CPU PCIe VGPIO for PEG60 */ + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_48, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_49, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_50, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_51, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_52, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_53, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_54, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_55, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_56, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_57, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_58, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_59, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_60, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_61, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_62, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_63, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_76, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_77, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_78, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_79, NONE, PLTRST, NF1), +}; + +static const struct pad_config romstage_gpio_table[] = { + /* B4 : PROC_GP3 ==> SSD_PERST_L */ + PAD_CFG_GPO(GPP_B4, 1, DEEP), +}; + +const struct pad_config *variant_gpio_override_table(size_t *num) +{ + *num = ARRAY_SIZE(override_gpio_table); + return override_gpio_table; +} + +const struct pad_config *variant_early_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(early_gpio_table); + return early_gpio_table; +} + +const struct pad_config *variant_romstage_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(romstage_gpio_table); + return romstage_gpio_table; +} diff --git a/src/mainboard/google/brya/variants/kulnex/include/variant/ec.h b/src/mainboard/google/brya/variants/kulnex/include/variant/ec.h new file mode 100644 index 00000000000..7a2a6ff8b77 --- /dev/null +++ b/src/mainboard/google/brya/variants/kulnex/include/variant/ec.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __VARIANT_EC_H__ +#define __VARIANT_EC_H__ + +#include + +#endif diff --git a/src/mainboard/google/brya/variants/kulnex/include/variant/gpio.h b/src/mainboard/google/brya/variants/kulnex/include/variant/gpio.h new file mode 100644 index 00000000000..c4fe342621e --- /dev/null +++ b/src/mainboard/google/brya/variants/kulnex/include/variant/gpio.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#endif diff --git a/src/mainboard/google/brya/variants/kulnex/memory.c b/src/mainboard/google/brya/variants/kulnex/memory.c new file mode 100644 index 00000000000..742ce7fe3a7 --- /dev/null +++ b/src/mainboard/google/brya/variants/kulnex/memory.c @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include + +static const struct mb_cfg ddr5_mem_config = { + .type = MEM_TYPE_DDR5, + + .rcomp = { + /* Baseboard uses only 100ohm Rcomp resistors */ + .resistor = 100, + + /* Baseboard Rcomp target values */ + .targets = {50, 20, 25, 25, 25}, + }, + + .LpDdrDqDqsReTraining = 1, + + .ect = 1, /* Early Command Training */ + + .UserBd = BOARD_TYPE_MOBILE, + + .ddr_config = { + .dq_pins_interleaved = false, + }, +}; + +const struct mb_cfg *__weak variant_memory_params(void) +{ + return &ddr5_mem_config; +} + +bool __weak variant_is_half_populated(void) +{ + return false; +} + +void __weak variant_get_spd_info(struct mem_spd *spd_info) +{ + spd_info->topo = MEM_TOPO_DIMM_MODULE; + spd_info->smbus[0].addr_dimm[0] = 0x50; + spd_info->smbus[1].addr_dimm[0] = 0x52; +} diff --git a/src/mainboard/google/brya/variants/kulnex/overridetree.cb b/src/mainboard/google/brya/variants/kulnex/overridetree.cb new file mode 100644 index 00000000000..71268f88ac9 --- /dev/null +++ b/src/mainboard/google/brya/variants/kulnex/overridetree.cb @@ -0,0 +1,384 @@ +fw_config + field AUDIO 0 2 + option AUDIO_UNKNOWN 0 + option NAU88L25B_I2S 1 + end + field BJ_POWER 3 4 + option BJ_POWER_150W 0 + option BJ_POWER_230W 1 + option BJ_POWER_65W 2 + option BJ_POWER_135W 3 + end + field MB_USBC 6 7 + option TC_USB4 0 + option TC_USB3 1 + end + field WIFI_TYPE 10 + option WIFI_PCIE 0 + option WIFI_CNVI 1 + end + field USB_HUB 32 + option HUB_ABSENT 0 + option HUB_PRESENT 1 + end +end + +chip soc/intel/alderlake + register "domain_vr_config[VR_DOMAIN_IA]" = "{ + .enable_fast_vmode = 1, + }" + + register "sagv" = "SaGv_Enabled" + + register "usb2_ports[1]" = "USB2_PORT_EMPTY" # Disable USB2 Port 1 + register "usb2_ports[2]" = "USB2_PORT_EMPTY" # Disable USB2 Port 2 + register "usb2_ports[4]" = "USB2_PORT_EMPTY" # Disable USB2 Port 4 + + register "usb3_ports[0]" = "{ + .enable = 1, + .ocpin = OC_SKIP, + .tx_de_emp = 0x2B, + .tx_downscale_amp = 0x00, + }" # Type-A port A0 + register "usb3_ports[1]" = "{ + .enable = 1, + .ocpin = OC_SKIP, + .tx_de_emp = 0x2B, + .tx_downscale_amp = 0x00, + }" # Type-A port A1 + + register "serial_io_gspi_mode" = "{ + [PchSerialIoIndexGSPI0] = PchSerialIoDisabled, + [PchSerialIoIndexGSPI1] = PchSerialIoDisabled, + }" + + register "ddi_ports_config" = "{ + [DDI_PORT_A] = DDI_ENABLE_HPD, + [DDI_PORT_B] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + [DDI_PORT_1] = DDI_ENABLE_HPD, + [DDI_PORT_3] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + }" + + register "power_limits_config[RPL_P_282_242_142_15W_CORE]" = "{ + .tdp_pl1_override = 15, + .tdp_pl2_override = 55, + .tdp_pl4 = 100, + }" + + device domain 0 on + device ref dtt on + chip drivers/intel/dptf + ## sensor information + register "options.tsr[0].desc" = ""DRAM"" + register "options.tsr[1].desc" = ""Charger"" + + # TODO: below values are initial reference values only + ## Active Policy + register "policies.active" = "{ + [0] = { + .target = DPTF_CPU, + .thresholds = { + TEMP_PCT(85, 90), + TEMP_PCT(80, 80), + TEMP_PCT(75, 70), + } + } + }" + + ## Passive Policy + register "policies.passive" = "{ + [0] = DPTF_PASSIVE(CPU, CPU, 95, 5000), + [1] = DPTF_PASSIVE(CPU, TEMP_SENSOR_0, 75, 5000), + [2] = DPTF_PASSIVE(CHARGER, TEMP_SENSOR_1, 75, 5000), + }" + + ## Critical Policy + register "policies.critical" = "{ + [0] = DPTF_CRITICAL(CPU, 105, SHUTDOWN), + [1] = DPTF_CRITICAL(TEMP_SENSOR_0, 85, SHUTDOWN), + [2] = DPTF_CRITICAL(TEMP_SENSOR_1, 85, SHUTDOWN), + }" + + register "controls.power_limits" = "{ + .pl1 = { + .min_power = 3000, + .max_power = 15000, + .time_window_min = 28 * MSECS_PER_SEC, + .time_window_max = 32 * MSECS_PER_SEC, + .granularity = 200, + }, + .pl2 = { + .min_power = 55000, + .max_power = 55000, + .time_window_min = 28 * MSECS_PER_SEC, + .time_window_max = 32 * MSECS_PER_SEC, + .granularity = 1000, + } + }" + + ## Charger Performance Control (Control, mA) + register "controls.charger_perf" = "{ + [0] = { 255, 1700 }, + [1] = { 24, 1500 }, + [2] = { 16, 1000 }, + [3] = { 8, 500 } + }" + + ## Fan Performance Control (Percent, Speed, Noise, Power) + register "controls.fan_perf" = "{ + [0] = { 90, 6700, 220, 2200, }, + [1] = { 80, 5800, 180, 1800, }, + [2] = { 70, 5000, 145, 1450, }, + [3] = { 60, 4900, 115, 1150, }, + [4] = { 50, 3838, 90, 900, }, + [5] = { 40, 2904, 55, 550, }, + [6] = { 30, 2337, 30, 300, }, + [7] = { 20, 1608, 15, 150, }, + [8] = { 10, 800, 10, 100, }, + [9] = { 0, 0, 0, 50, } + }" + + ## Fan options + register "options.fan.fine_grained_control" = "true" + register "options.fan.step_size" = "2" + + device generic 0 alias dptf_policy on end + end + end + device ref pcie4_0 on + # Enable CPU PCIE RP 1 using CLK 0 + register "cpu_pcie_rp[CPU_RP(1)]" = "{ + .clk_req = 0, + .clk_src = 0, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + chip soc/intel/common/block/pcie/rtd3 + register "is_storage" = "true" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F14)" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_B4)" + register "srcclk_pin" = "0" + device generic 0 on end + end + end + device ref tbt_pcie_rp0 on + probe MB_USBC TC_USB4 + end + device ref tbt_pcie_rp1 on + probe MB_USBC TC_USB4 + end + device ref tbt_pcie_rp2 on + probe MB_USBC TC_USB4 + end + device ref tcss_dma0 on + probe MB_USBC TC_USB4 + chip drivers/intel/usb4/retimer + register "dfp[0].power_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E4)" + use tcss_usb3_port1 as dfp[0].typec_port + device generic 0 on end + end + end + device ref cnvi_wifi on + chip drivers/wifi/generic + register "wake" = "GPE0_PME_B0" + device generic 0 on + probe WIFI_TYPE WIFI_CNVI + end + end + end + device ref i2c0 on + chip drivers/i2c/nau8825 + register "irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_A23)" + register "jkdet_enable" = "1" + register "jkdet_pull_enable" = "0" + register "jkdet_pull_up" = "0" + register "jkdet_polarity" = "1" # ActiveLow + register "vref_impedance" = "2" # 125kOhm + register "micbias_voltage" = "6" # 2.754 + register "sar_threshold_num" = "4" + register "sar_threshold[0]" = "0x0C" + register "sar_threshold[1]" = "0x1C" + register "sar_threshold[2]" = "0x38" + register "sar_threshold[3]" = "0x60" + register "sar_hysteresis" = "1" + register "sar_voltage" = "0" # VDDA + register "sar_compare_time" = "0" # 500ns + register "sar_sampling_time" = "0" # 2us + register "short_key_debounce" = "2" # 100ms + register "jack_insert_debounce" = "7" # 512ms + register "jack_eject_debounce" = "7" # 512ms + device i2c 1a on + probe AUDIO NAU88L25B_I2S + end + end + end + device ref pcie_rp5 on + probe WIFI_TYPE WIFI_PCIE + # Enable wlan PCIe 5 using clk 2 + register "pch_pcie_rp[PCH_RP(5)]" = "{ + .clk_src = 2, + .clk_req = 2, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + chip drivers/wifi/generic + register "wake" = "GPE0_DW1_03" + register "add_acpi_dma_property" = "true" + device pci 00.0 on + probe WIFI_TYPE WIFI_PCIE + end + end + chip soc/intel/common/block/pcie/rtd3 + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_B11)" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H20)" + register "srcclk_pin" = "2" + device generic 0 on + probe WIFI_TYPE WIFI_PCIE + end + end + end #PCIE5 WLAN card + device ref pcie_rp7 on + chip drivers/net + register "wake" = "GPE0_DW0_07" + register "led_feature" = "0xe0" + register "customized_leds" = "0x05af" + register "customized_led0" = "0x23f" + register "customized_led2" = "0x028" + register "enable_aspm_l1_2" = "1" + register "add_acpi_dma_property" = "true" + device pci 00.0 on end + end + end # RTL8125 and RTL8111K Ethernet NIC + device ref pcie_rp8 on + chip soc/intel/common/block/pcie/rtd3 + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_H13)" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_D18)" + register "srcclk_pin" = "3" + device generic 0 on end + end + end #PCIE8 SD card + device ref gspi1 off end + device ref pch_espi on + chip ec/google/chromeec + use conn0 as mux_conn[0] + device pnp 0c09.0 on end + end + end + device ref pmc hidden + chip drivers/intel/pmc_mux + device generic 0 on + chip drivers/intel/pmc_mux/conn + use usb2_port1 as usb2_port + use tcss_usb3_port1 as usb3_port + device generic 0 alias conn0 on end + end + end + end + end + device ref tcss_xhci on + chip drivers/usb/acpi + device ref tcss_root_hub on + chip drivers/usb/acpi + register "desc" = ""USB3 Type-C Port C0 (MLB)"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(BACK, RIGHT, ACPI_PLD_GROUP(1, 1))" + device ref tcss_usb3_port1 on end + end + end + end + end + device ref xhci on + chip drivers/usb/acpi + device ref xhci_root_hub on + chip drivers/usb/acpi + register "desc" = ""USB2 Type-C Port C0 (MLB)"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(BACK, RIGHT, ACPI_PLD_GROUP(1, 1))" + device ref usb2_port1 on end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Type-A Port A3 (MLB)"" + register "type" = "UPC_TYPE_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(BACK, LEFT, ACPI_PLD_GROUP(5, 1))" + device ref usb2_port6 on end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Type-A Port A2 (MLB)"" + register "type" = "UPC_TYPE_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(BACK, CENTER, ACPI_PLD_GROUP(6, 1))" + device ref usb2_port7 on end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Type-A Port A1 (MLB)"" + register "type" = "UPC_TYPE_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(FRONT, LEFT, ACPI_PLD_GROUP(4, 1))" + device ref usb2_port8 on end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Type-A Port A0 (MLB)"" + register "type" = "UPC_TYPE_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(FRONT, RIGHT, ACPI_PLD_GROUP(1, 2))" + device ref usb2_port9 on + probe USB_HUB HUB_ABSENT + end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Hub for Type-A Port A0/A4/A5 (MLB)"" + register "type" = "UPC_TYPE_INTERNAL" + device ref usb2_port9 on + probe USB_HUB HUB_PRESENT + end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Bluetooth"" + register "type" = "UPC_TYPE_INTERNAL" + register "reset_gpio" = + "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_D4)" + device ref usb2_port10 on end + end + chip drivers/usb/acpi + register "desc" = ""USB3 Type-A Port A0 (MLB)"" + register "type" = "UPC_TYPE_USB3_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(FRONT, RIGHT, ACPI_PLD_GROUP(1, 2))" + device ref usb3_port1 on + probe USB_HUB HUB_ABSENT + end + end + chip drivers/usb/acpi + register "desc" = ""USB3 Hub for Type-A Port A0/A4/A5 (MLB)"" + register "type" = "UPC_TYPE_INTERNAL" + device ref usb3_port1 on + probe USB_HUB HUB_PRESENT + end + end + chip drivers/usb/acpi + register "desc" = ""USB3 Type-A Port A1 (MLB)"" + register "type" = "UPC_TYPE_USB3_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(FRONT, LEFT, ACPI_PLD_GROUP(4, 1))" + device ref usb3_port2 on end + end + chip drivers/usb/acpi + register "desc" = ""USB3 Type-A Port A2 (MLB)"" + register "type" = "UPC_TYPE_USB3_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(BACK, CENTER, ACPI_PLD_GROUP(6, 1))" + device ref usb3_port3 on end + end + chip drivers/usb/acpi + register "desc" = ""USB3 Type-A Port A3 (MLB)"" + register "type" = "UPC_TYPE_USB3_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(BACK, LEFT, ACPI_PLD_GROUP(5, 1))" + device ref usb3_port4 on end + end + end + end + end + end +end diff --git a/src/mainboard/google/brya/variants/kulnex/ramstage.c b/src/mainboard/google/brya/variants/kulnex/ramstage.c new file mode 100644 index 00000000000..a3cd9f3fc61 --- /dev/null +++ b/src/mainboard/google/brya/variants/kulnex/ramstage.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include +#include +#include + +const struct cpu_power_limits limits[] = { + /* SKU_ID, TDP (Watts), pl1_min, pl1_max, pl2_min, pl2_max, pl4 */ + { PCI_DID_INTEL_RPL_P_ID_5, 15, 15000, 15000, 55000, 55000, 100000 }, + { PCI_DID_INTEL_RPL_P_ID_4, 15, 15000, 15000, 55000, 55000, 100000 }, + { PCI_DID_INTEL_RPL_P_ID_3, 15, 15000, 15000, 55000, 55000, 100000 }, +}; + +const struct system_power_limits sys_limits[] = { + /* SKU_ID, TDP (Watts), psys_pl2 (Watts) */ + { PCI_DID_INTEL_RPL_P_ID_5, 15, 138 }, + { PCI_DID_INTEL_RPL_P_ID_4, 15, 138 }, + { PCI_DID_INTEL_RPL_P_ID_3, 15, 138 }, +}; + +/* + * Psys_pmax considerations. + * + * Given the hardware design in kulnex, the serial shunt resistor is 0.005ohm. + * The full scale of hardware PSYS signal 1.6v maps to system current 11.25A + * instead of real system power. The equation is shown below: + * PSYS = 1.6v = (0.005ohm x 11.25A) x 50 (INA213, gain 50V/V) x R501/(R501 + R510) + * R501/(R501 + R510) = 0.57 = 20K / (20K + 15K) + * + * The Psys_pmax is a SW setting which tells IMVP9.1 the mapping b/w system input + * current and the actual system power. Since there is no voltage information + * from PSYS, different voltage input would map to different Psys_pmax settings: + * For Type-C 15V, the Psys_pmax should be 15v x 11.25A = 168.75W + * For Type-C 20V, the Psys_pmax should be 20v x 11.25A = 225W + * For a barrel jack, the Psys_pmax should be 20v x 11.25A = 225W + * + * Imagine that there is a type-c 100W (20V/5A) connected to DUT w/ full loading, + * and the Psys_pmax setting is 225W. Then IMVP9.1 can calculate the current system + * power = 225W * 5A / 11.25A = 100W, which is the actual system power. + */ +const struct psys_config psys_config = { + .efficiency = 97, + .psys_imax_ma = 11250, + .bj_volts_mv = 20000 +}; + +void variant_devtree_update(void) +{ + size_t total_entries = ARRAY_SIZE(limits); + variant_update_psys_power_limits(limits, sys_limits, total_entries, &psys_config); + + variant_update_power_limits(limits, total_entries); +} diff --git a/src/mainboard/google/brya/variants/kulnex/variant.c b/src/mainboard/google/brya/variants/kulnex/variant.c new file mode 100644 index 00000000000..b7cba968a52 --- /dev/null +++ b/src/mainboard/google/brya/variants/kulnex/variant.c @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +const char *get_wifi_sar_cbfs_filename(void) +{ + return "wifi_sar_0.hex"; +} + +void variant_update_soc_chip_config(struct soc_intel_alderlake_config *config) +{ + config->cnvi_bt_audio_offload = fw_config_probe(FW_CONFIG(AUDIO, + NAU88L25B_I2S)); + + if (fw_config_probe(FW_CONFIG(MB_USBC, TC_USB3))) { + config->tcss_aux_ori = 1; + config->typec_aux_bias_pads[0].pad_auxp_dc = GPP_C3; + config->typec_aux_bias_pads[0].pad_auxn_dc = GPP_C4; + } +} diff --git a/src/mainboard/google/brya/variants/lisbon/overridetree.cb b/src/mainboard/google/brya/variants/lisbon/overridetree.cb index 6c3eaf952aa..10b54c4f929 100644 --- a/src/mainboard/google/brya/variants/lisbon/overridetree.cb +++ b/src/mainboard/google/brya/variants/lisbon/overridetree.cb @@ -213,7 +213,7 @@ chip soc/intel/alderlake register "pch_pcie_rp[PCH_RP(12)]" = "{ .clk_src = 4, .clk_req = 4, - .flags = PCIE_RP_HOTPLUG | PCIE_RP_AER, + .flags = PCIE_RP_HOTPLUG | PCIE_RP_AER | PCIE_RP_BUILT_IN, }" probe STORAGE STORAGE_EMMC end #PCIE12 EMMC diff --git a/src/mainboard/google/brya/variants/meliks/overridetree.cb b/src/mainboard/google/brya/variants/meliks/overridetree.cb index 26cc7752170..4b4947765e3 100644 --- a/src/mainboard/google/brya/variants/meliks/overridetree.cb +++ b/src/mainboard/google/brya/variants/meliks/overridetree.cb @@ -261,10 +261,11 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/moli/overridetree.cb b/src/mainboard/google/brya/variants/moli/overridetree.cb index 3397d0c2117..741d54d7488 100644 --- a/src/mainboard/google/brya/variants/moli/overridetree.cb +++ b/src/mainboard/google/brya/variants/moli/overridetree.cb @@ -201,7 +201,7 @@ chip soc/intel/alderlake register "pch_pcie_rp[PCH_RP(12)]" = "{ .clk_src = 1, .clk_req = 1, - .flags = PCIE_RP_LTR | PCIE_RP_AER, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_BUILT_IN, }" probe STORAGE STORAGE_EMMC probe STORAGE STORAGE_UNKNOWN diff --git a/src/mainboard/google/brya/variants/moxoe/Makefile.mk b/src/mainboard/google/brya/variants/moxoe/Makefile.mk new file mode 100644 index 00000000000..2b274c69e23 --- /dev/null +++ b/src/mainboard/google/brya/variants/moxoe/Makefile.mk @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0-only +bootblock-y += gpio.c + +romstage-y += memory.c +romstage-y += gpio.c + +ramstage-y += gpio.c +ramstage-y += ramstage.c +ramstage-$(CONFIG_FW_CONFIG) += fw_config.c +ramstage-$(CONFIG_FW_CONFIG) += variant.c diff --git a/src/mainboard/google/brya/variants/moxoe/data.vbt b/src/mainboard/google/brya/variants/moxoe/data.vbt new file mode 100644 index 00000000000..7d14588c613 Binary files /dev/null and b/src/mainboard/google/brya/variants/moxoe/data.vbt differ diff --git a/src/mainboard/google/brya/variants/moxoe/fw_config.c b/src/mainboard/google/brya/variants/moxoe/fw_config.c new file mode 100644 index 00000000000..42613af1631 --- /dev/null +++ b/src/mainboard/google/brya/variants/moxoe/fw_config.c @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +static const struct pad_config dmic_enable_pads[] = { + PAD_CFG_NF(GPP_R6, NONE, DEEP, NF3), /* DMIC_CLK1_R */ + PAD_CFG_NF(GPP_R7, NONE, DEEP, NF3), /* DMIC_DATA1_R */ +}; + +static const struct pad_config dmic_disable_pads[] = { + PAD_NC(GPP_R6, NONE), + PAD_NC(GPP_R7, NONE), +}; + +static const struct pad_config i2s_enable_pads[] = { + PAD_CFG_NF(GPP_R0, NONE, DEEP, NF2), /* I2S_HP_SCLK_R */ + PAD_CFG_NF(GPP_R1, NONE, DEEP, NF2), /* I2S_HP_SFRM_R */ + PAD_CFG_NF(GPP_R2, DN_20K, DEEP, NF2), /* I2S_PCH_TX_HP_RX_STRAP */ + PAD_CFG_NF(GPP_R3, NONE, DEEP, NF2), /* I2S_PCH_RX_HP_TX */ +}; + +static const struct pad_config i2s_disable_pads[] = { + PAD_NC(GPP_R0, NONE), + PAD_NC(GPP_R1, NONE), + PAD_NC(GPP_R2, NONE), + PAD_NC(GPP_R3, NONE), +}; + +static const struct pad_config bt_i2s_enable_pads[] = { + PAD_CFG_NF(GPP_VGPIO_30, NONE, DEEP, NF3), /* BT_I2S_BCLK */ + PAD_CFG_NF(GPP_VGPIO_31, NONE, DEEP, NF3), /* BT_I2S_SYNC */ + PAD_CFG_NF(GPP_VGPIO_32, NONE, DEEP, NF3), /* BT_I2S_SDO */ + PAD_CFG_NF(GPP_VGPIO_33, NONE, DEEP, NF3), /* BT_I2S_SDI */ + PAD_CFG_NF(GPP_VGPIO_34, NONE, DEEP, NF1), /* SSP2_SCLK */ + PAD_CFG_NF(GPP_VGPIO_35, NONE, DEEP, NF1), /* SSP2_SFRM */ + PAD_CFG_NF(GPP_VGPIO_36, NONE, DEEP, NF1), /* SSP_TXD */ + PAD_CFG_NF(GPP_VGPIO_37, NONE, DEEP, NF1), /* SSP_RXD */ +}; + +static const struct pad_config bt_i2s_disable_pads[] = { + PAD_NC(GPP_VGPIO_30, NONE), + PAD_NC(GPP_VGPIO_31, NONE), + PAD_NC(GPP_VGPIO_32, NONE), + PAD_NC(GPP_VGPIO_33, NONE), + PAD_NC(GPP_VGPIO_34, NONE), + PAD_NC(GPP_VGPIO_35, NONE), + PAD_NC(GPP_VGPIO_36, NONE), + PAD_NC(GPP_VGPIO_37, NONE), +}; + +static void fw_config_handle(void *unused) +{ + if (!fw_config_is_provisioned() || fw_config_probe(FW_CONFIG(AUDIO, AUDIO_UNKNOWN))) { + printk(BIOS_INFO, "Disable audio related GPIO pins.\n"); + gpio_configure_pads(i2s_disable_pads, ARRAY_SIZE(i2s_disable_pads)); + gpio_configure_pads(dmic_disable_pads, ARRAY_SIZE(dmic_disable_pads)); + gpio_configure_pads(bt_i2s_disable_pads, ARRAY_SIZE(bt_i2s_disable_pads)); + return; + } + + if (fw_config_probe(FW_CONFIG(AUDIO, NAU88L25B_I2S))) { + printk(BIOS_INFO, "Configure audio over I2S with NAU88L25B.\n"); + gpio_configure_pads(dmic_enable_pads, ARRAY_SIZE(dmic_enable_pads)); + gpio_configure_pads(i2s_enable_pads, ARRAY_SIZE(i2s_enable_pads)); + printk(BIOS_INFO, "BT offload enabled\n"); + gpio_configure_pads(bt_i2s_enable_pads, ARRAY_SIZE(bt_i2s_enable_pads)); + } else { + printk(BIOS_INFO, "BT offload disabled\n"); + gpio_configure_pads(bt_i2s_disable_pads, ARRAY_SIZE(bt_i2s_disable_pads)); + } +} +BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, fw_config_handle, NULL); diff --git a/src/mainboard/google/brya/variants/moxoe/gpio.c b/src/mainboard/google/brya/variants/moxoe/gpio.c new file mode 100644 index 00000000000..556e8b694c9 --- /dev/null +++ b/src/mainboard/google/brya/variants/moxoe/gpio.c @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include + +/* Pad configuration in ramstage */ +static const struct pad_config override_gpio_table[] = { + /* A14 : USB_OC1# ==> HDMIA_HPD */ + PAD_CFG_NF(GPP_A14, NONE, DEEP, NF2), + /* A15 : USB_OC2# ==> NC */ + PAD_NC(GPP_A15, NONE), + /* A19 : DDSP_HPD1 ==> NC */ + PAD_NC(GPP_A19, NONE), + /* A20 : DDSP_HPD2 ==> NC */ + PAD_NC(GPP_A20, NONE), + /* A21 : DDPC_CTRCLK ==> NC */ + PAD_NC(GPP_A21, NONE), + /* A22 : DDPC_CTRLDATA ==> NC */ + PAD_NC(GPP_A22, NONE), + + /* B7 : ISH_12C1_SDA ==> PCH_I2C_MISCB_SDA */ + PAD_CFG_NF_LOCK(GPP_B7, NONE, NF2, LOCK_CONFIG), + /* B8 : ISH_I2C1_SCL ==> PCH_I2C_MISCB_SCL */ + PAD_CFG_NF_LOCK(GPP_B8, NONE, NF2, LOCK_CONFIG), + + /* C3 : SML0CLK ==> USB_C0_AUX_DC_P */ + PAD_CFG_NF(GPP_C3, NONE, DEEP, NF6), + /* C4 : SML0DATA ==> USB_C0_AUX_DC_N */ + PAD_CFG_NF(GPP_C4, NONE, DEEP, NF6), + + /* D0 : ISH_GP0 ==> NC */ + PAD_NC_LOCK(GPP_D0, NONE, LOCK_CONFIG), + /* D1 : ISH_GP1 ==> NC */ + PAD_NC_LOCK(GPP_D1, NONE, LOCK_CONFIG), + /* D2 : ISH_GP2 ==> NC */ + PAD_NC_LOCK(GPP_D2, NONE, LOCK_CONFIG), + /* D3 : ISH_GP3 ==> NC */ + PAD_NC_LOCK(GPP_D3, NONE, LOCK_CONFIG), + /* D9 : ISH_SPI_CS# ==> NC */ + PAD_NC_LOCK(GPP_D9, NONE, LOCK_CONFIG), + + /* E20 : DDP2_CTRLCLK ==> HDMIA_CTRLCLK */ + PAD_CFG_NF(GPP_E20, NONE, DEEP, NF1), + /* E21 : DDP2_CTRLDATA ==> HDMIA_CTRLDATA_STRAP */ + PAD_CFG_NF(GPP_E21, NONE, DEEP, NF1), + + /* F11 : THC1_SPI2_CLK ==> NC */ + PAD_NC_LOCK(GPP_F11, NONE, LOCK_CONFIG), + /* F12 : GSXDOUT ==> NC */ + PAD_NC_LOCK(GPP_F12, NONE, LOCK_CONFIG), + /* F13 : GSXDOUT ==> NC */ + PAD_NC_LOCK(GPP_F13, NONE, LOCK_CONFIG), + /* F15 : GSXSRESET# ==> NC */ + PAD_NC_LOCK(GPP_F15, NONE, LOCK_CONFIG), + /* F16 : GSXCLK ==> NC */ + PAD_NC_LOCK(GPP_F16, NONE, LOCK_CONFIG), + + /* R4 : HDA_RST# ==> NC */ + PAD_NC(GPP_R4, NONE), + /* R5 : HDA_SDI1 ==> NC */ + PAD_NC(GPP_R5, NONE), +}; + +/* Early pad configuration in bootblock */ +static const struct pad_config early_gpio_table[] = { + /* A13 : PMC_I2C_SCL ==> GSC_PCH_INT_ODL */ + PAD_CFG_GPI_APIC(GPP_A13, NONE, PLTRST, LEVEL, INVERT), + /* B4 : PROC_GP3 ==> SSD_PERST_L */ + PAD_CFG_GPO(GPP_B4, 0, DEEP), + /* E15 : RSVD_TP ==> PCH_WP_OD */ + PAD_CFG_GPI_GPIO_DRIVER(GPP_E15, NONE, DEEP), + /* F14 : GSXDIN ==> EN_PP3300_SSD */ + PAD_CFG_GPO(GPP_F14, 1, DEEP), + /* F18 : THC1_SPI2_INT# ==> EC_IN_RW_OD */ + PAD_CFG_GPI(GPP_F18, NONE, DEEP), + /* H6 : I2C1_SDA ==> PCH_I2C_TPM_SDA */ + PAD_CFG_NF(GPP_H6, NONE, DEEP, NF1), + /* H7 : I2C1_SCL ==> PCH_I2C_TPM_SCL */ + PAD_CFG_NF(GPP_H7, NONE, DEEP, NF1), + /* H10 : UART0_RXD ==> UART_PCH_RX_DBG_TX */ + PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), + /* H11 : UART0_TXD ==> UART_PCH_TX_DBG_RX */ + PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), + /* H13 : I2C7_SCL ==> EN_PP3300_SD */ + PAD_CFG_GPO(GPP_H13, 1, DEEP), + + /* CPU PCIe VGPIO for PEG60 */ + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_48, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_49, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_50, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_51, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_52, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_53, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_54, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_55, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_56, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_57, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_58, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_59, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_60, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_61, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_62, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_63, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_76, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_77, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_78, NONE, PLTRST, NF1), + PAD_CFG_NF_VWEN(GPP_vGPIO_PCIE_79, NONE, PLTRST, NF1), +}; + +static const struct pad_config romstage_gpio_table[] = { + /* B4 : PROC_GP3 ==> SSD_PERST_L */ + PAD_CFG_GPO(GPP_B4, 1, DEEP), +}; + +const struct pad_config *variant_gpio_override_table(size_t *num) +{ + *num = ARRAY_SIZE(override_gpio_table); + return override_gpio_table; +} + +const struct pad_config *variant_early_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(early_gpio_table); + return early_gpio_table; +} + +const struct pad_config *variant_romstage_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(romstage_gpio_table); + return romstage_gpio_table; +} diff --git a/src/mainboard/google/brya/variants/moxoe/include/variant/ec.h b/src/mainboard/google/brya/variants/moxoe/include/variant/ec.h new file mode 100644 index 00000000000..7a2a6ff8b77 --- /dev/null +++ b/src/mainboard/google/brya/variants/moxoe/include/variant/ec.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __VARIANT_EC_H__ +#define __VARIANT_EC_H__ + +#include + +#endif diff --git a/src/mainboard/google/brya/variants/moxoe/include/variant/gpio.h b/src/mainboard/google/brya/variants/moxoe/include/variant/gpio.h new file mode 100644 index 00000000000..c4fe342621e --- /dev/null +++ b/src/mainboard/google/brya/variants/moxoe/include/variant/gpio.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#endif diff --git a/src/mainboard/google/brya/variants/moxoe/memory.c b/src/mainboard/google/brya/variants/moxoe/memory.c new file mode 100644 index 00000000000..742ce7fe3a7 --- /dev/null +++ b/src/mainboard/google/brya/variants/moxoe/memory.c @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include + +static const struct mb_cfg ddr5_mem_config = { + .type = MEM_TYPE_DDR5, + + .rcomp = { + /* Baseboard uses only 100ohm Rcomp resistors */ + .resistor = 100, + + /* Baseboard Rcomp target values */ + .targets = {50, 20, 25, 25, 25}, + }, + + .LpDdrDqDqsReTraining = 1, + + .ect = 1, /* Early Command Training */ + + .UserBd = BOARD_TYPE_MOBILE, + + .ddr_config = { + .dq_pins_interleaved = false, + }, +}; + +const struct mb_cfg *__weak variant_memory_params(void) +{ + return &ddr5_mem_config; +} + +bool __weak variant_is_half_populated(void) +{ + return false; +} + +void __weak variant_get_spd_info(struct mem_spd *spd_info) +{ + spd_info->topo = MEM_TOPO_DIMM_MODULE; + spd_info->smbus[0].addr_dimm[0] = 0x50; + spd_info->smbus[1].addr_dimm[0] = 0x52; +} diff --git a/src/mainboard/google/brya/variants/moxoe/overridetree.cb b/src/mainboard/google/brya/variants/moxoe/overridetree.cb new file mode 100644 index 00000000000..71268f88ac9 --- /dev/null +++ b/src/mainboard/google/brya/variants/moxoe/overridetree.cb @@ -0,0 +1,384 @@ +fw_config + field AUDIO 0 2 + option AUDIO_UNKNOWN 0 + option NAU88L25B_I2S 1 + end + field BJ_POWER 3 4 + option BJ_POWER_150W 0 + option BJ_POWER_230W 1 + option BJ_POWER_65W 2 + option BJ_POWER_135W 3 + end + field MB_USBC 6 7 + option TC_USB4 0 + option TC_USB3 1 + end + field WIFI_TYPE 10 + option WIFI_PCIE 0 + option WIFI_CNVI 1 + end + field USB_HUB 32 + option HUB_ABSENT 0 + option HUB_PRESENT 1 + end +end + +chip soc/intel/alderlake + register "domain_vr_config[VR_DOMAIN_IA]" = "{ + .enable_fast_vmode = 1, + }" + + register "sagv" = "SaGv_Enabled" + + register "usb2_ports[1]" = "USB2_PORT_EMPTY" # Disable USB2 Port 1 + register "usb2_ports[2]" = "USB2_PORT_EMPTY" # Disable USB2 Port 2 + register "usb2_ports[4]" = "USB2_PORT_EMPTY" # Disable USB2 Port 4 + + register "usb3_ports[0]" = "{ + .enable = 1, + .ocpin = OC_SKIP, + .tx_de_emp = 0x2B, + .tx_downscale_amp = 0x00, + }" # Type-A port A0 + register "usb3_ports[1]" = "{ + .enable = 1, + .ocpin = OC_SKIP, + .tx_de_emp = 0x2B, + .tx_downscale_amp = 0x00, + }" # Type-A port A1 + + register "serial_io_gspi_mode" = "{ + [PchSerialIoIndexGSPI0] = PchSerialIoDisabled, + [PchSerialIoIndexGSPI1] = PchSerialIoDisabled, + }" + + register "ddi_ports_config" = "{ + [DDI_PORT_A] = DDI_ENABLE_HPD, + [DDI_PORT_B] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + [DDI_PORT_1] = DDI_ENABLE_HPD, + [DDI_PORT_3] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + }" + + register "power_limits_config[RPL_P_282_242_142_15W_CORE]" = "{ + .tdp_pl1_override = 15, + .tdp_pl2_override = 55, + .tdp_pl4 = 100, + }" + + device domain 0 on + device ref dtt on + chip drivers/intel/dptf + ## sensor information + register "options.tsr[0].desc" = ""DRAM"" + register "options.tsr[1].desc" = ""Charger"" + + # TODO: below values are initial reference values only + ## Active Policy + register "policies.active" = "{ + [0] = { + .target = DPTF_CPU, + .thresholds = { + TEMP_PCT(85, 90), + TEMP_PCT(80, 80), + TEMP_PCT(75, 70), + } + } + }" + + ## Passive Policy + register "policies.passive" = "{ + [0] = DPTF_PASSIVE(CPU, CPU, 95, 5000), + [1] = DPTF_PASSIVE(CPU, TEMP_SENSOR_0, 75, 5000), + [2] = DPTF_PASSIVE(CHARGER, TEMP_SENSOR_1, 75, 5000), + }" + + ## Critical Policy + register "policies.critical" = "{ + [0] = DPTF_CRITICAL(CPU, 105, SHUTDOWN), + [1] = DPTF_CRITICAL(TEMP_SENSOR_0, 85, SHUTDOWN), + [2] = DPTF_CRITICAL(TEMP_SENSOR_1, 85, SHUTDOWN), + }" + + register "controls.power_limits" = "{ + .pl1 = { + .min_power = 3000, + .max_power = 15000, + .time_window_min = 28 * MSECS_PER_SEC, + .time_window_max = 32 * MSECS_PER_SEC, + .granularity = 200, + }, + .pl2 = { + .min_power = 55000, + .max_power = 55000, + .time_window_min = 28 * MSECS_PER_SEC, + .time_window_max = 32 * MSECS_PER_SEC, + .granularity = 1000, + } + }" + + ## Charger Performance Control (Control, mA) + register "controls.charger_perf" = "{ + [0] = { 255, 1700 }, + [1] = { 24, 1500 }, + [2] = { 16, 1000 }, + [3] = { 8, 500 } + }" + + ## Fan Performance Control (Percent, Speed, Noise, Power) + register "controls.fan_perf" = "{ + [0] = { 90, 6700, 220, 2200, }, + [1] = { 80, 5800, 180, 1800, }, + [2] = { 70, 5000, 145, 1450, }, + [3] = { 60, 4900, 115, 1150, }, + [4] = { 50, 3838, 90, 900, }, + [5] = { 40, 2904, 55, 550, }, + [6] = { 30, 2337, 30, 300, }, + [7] = { 20, 1608, 15, 150, }, + [8] = { 10, 800, 10, 100, }, + [9] = { 0, 0, 0, 50, } + }" + + ## Fan options + register "options.fan.fine_grained_control" = "true" + register "options.fan.step_size" = "2" + + device generic 0 alias dptf_policy on end + end + end + device ref pcie4_0 on + # Enable CPU PCIE RP 1 using CLK 0 + register "cpu_pcie_rp[CPU_RP(1)]" = "{ + .clk_req = 0, + .clk_src = 0, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + chip soc/intel/common/block/pcie/rtd3 + register "is_storage" = "true" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F14)" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_B4)" + register "srcclk_pin" = "0" + device generic 0 on end + end + end + device ref tbt_pcie_rp0 on + probe MB_USBC TC_USB4 + end + device ref tbt_pcie_rp1 on + probe MB_USBC TC_USB4 + end + device ref tbt_pcie_rp2 on + probe MB_USBC TC_USB4 + end + device ref tcss_dma0 on + probe MB_USBC TC_USB4 + chip drivers/intel/usb4/retimer + register "dfp[0].power_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E4)" + use tcss_usb3_port1 as dfp[0].typec_port + device generic 0 on end + end + end + device ref cnvi_wifi on + chip drivers/wifi/generic + register "wake" = "GPE0_PME_B0" + device generic 0 on + probe WIFI_TYPE WIFI_CNVI + end + end + end + device ref i2c0 on + chip drivers/i2c/nau8825 + register "irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_A23)" + register "jkdet_enable" = "1" + register "jkdet_pull_enable" = "0" + register "jkdet_pull_up" = "0" + register "jkdet_polarity" = "1" # ActiveLow + register "vref_impedance" = "2" # 125kOhm + register "micbias_voltage" = "6" # 2.754 + register "sar_threshold_num" = "4" + register "sar_threshold[0]" = "0x0C" + register "sar_threshold[1]" = "0x1C" + register "sar_threshold[2]" = "0x38" + register "sar_threshold[3]" = "0x60" + register "sar_hysteresis" = "1" + register "sar_voltage" = "0" # VDDA + register "sar_compare_time" = "0" # 500ns + register "sar_sampling_time" = "0" # 2us + register "short_key_debounce" = "2" # 100ms + register "jack_insert_debounce" = "7" # 512ms + register "jack_eject_debounce" = "7" # 512ms + device i2c 1a on + probe AUDIO NAU88L25B_I2S + end + end + end + device ref pcie_rp5 on + probe WIFI_TYPE WIFI_PCIE + # Enable wlan PCIe 5 using clk 2 + register "pch_pcie_rp[PCH_RP(5)]" = "{ + .clk_src = 2, + .clk_req = 2, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + chip drivers/wifi/generic + register "wake" = "GPE0_DW1_03" + register "add_acpi_dma_property" = "true" + device pci 00.0 on + probe WIFI_TYPE WIFI_PCIE + end + end + chip soc/intel/common/block/pcie/rtd3 + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_B11)" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H20)" + register "srcclk_pin" = "2" + device generic 0 on + probe WIFI_TYPE WIFI_PCIE + end + end + end #PCIE5 WLAN card + device ref pcie_rp7 on + chip drivers/net + register "wake" = "GPE0_DW0_07" + register "led_feature" = "0xe0" + register "customized_leds" = "0x05af" + register "customized_led0" = "0x23f" + register "customized_led2" = "0x028" + register "enable_aspm_l1_2" = "1" + register "add_acpi_dma_property" = "true" + device pci 00.0 on end + end + end # RTL8125 and RTL8111K Ethernet NIC + device ref pcie_rp8 on + chip soc/intel/common/block/pcie/rtd3 + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_H13)" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_D18)" + register "srcclk_pin" = "3" + device generic 0 on end + end + end #PCIE8 SD card + device ref gspi1 off end + device ref pch_espi on + chip ec/google/chromeec + use conn0 as mux_conn[0] + device pnp 0c09.0 on end + end + end + device ref pmc hidden + chip drivers/intel/pmc_mux + device generic 0 on + chip drivers/intel/pmc_mux/conn + use usb2_port1 as usb2_port + use tcss_usb3_port1 as usb3_port + device generic 0 alias conn0 on end + end + end + end + end + device ref tcss_xhci on + chip drivers/usb/acpi + device ref tcss_root_hub on + chip drivers/usb/acpi + register "desc" = ""USB3 Type-C Port C0 (MLB)"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(BACK, RIGHT, ACPI_PLD_GROUP(1, 1))" + device ref tcss_usb3_port1 on end + end + end + end + end + device ref xhci on + chip drivers/usb/acpi + device ref xhci_root_hub on + chip drivers/usb/acpi + register "desc" = ""USB2 Type-C Port C0 (MLB)"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(BACK, RIGHT, ACPI_PLD_GROUP(1, 1))" + device ref usb2_port1 on end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Type-A Port A3 (MLB)"" + register "type" = "UPC_TYPE_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(BACK, LEFT, ACPI_PLD_GROUP(5, 1))" + device ref usb2_port6 on end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Type-A Port A2 (MLB)"" + register "type" = "UPC_TYPE_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(BACK, CENTER, ACPI_PLD_GROUP(6, 1))" + device ref usb2_port7 on end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Type-A Port A1 (MLB)"" + register "type" = "UPC_TYPE_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(FRONT, LEFT, ACPI_PLD_GROUP(4, 1))" + device ref usb2_port8 on end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Type-A Port A0 (MLB)"" + register "type" = "UPC_TYPE_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(FRONT, RIGHT, ACPI_PLD_GROUP(1, 2))" + device ref usb2_port9 on + probe USB_HUB HUB_ABSENT + end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Hub for Type-A Port A0/A4/A5 (MLB)"" + register "type" = "UPC_TYPE_INTERNAL" + device ref usb2_port9 on + probe USB_HUB HUB_PRESENT + end + end + chip drivers/usb/acpi + register "desc" = ""USB2 Bluetooth"" + register "type" = "UPC_TYPE_INTERNAL" + register "reset_gpio" = + "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_D4)" + device ref usb2_port10 on end + end + chip drivers/usb/acpi + register "desc" = ""USB3 Type-A Port A0 (MLB)"" + register "type" = "UPC_TYPE_USB3_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(FRONT, RIGHT, ACPI_PLD_GROUP(1, 2))" + device ref usb3_port1 on + probe USB_HUB HUB_ABSENT + end + end + chip drivers/usb/acpi + register "desc" = ""USB3 Hub for Type-A Port A0/A4/A5 (MLB)"" + register "type" = "UPC_TYPE_INTERNAL" + device ref usb3_port1 on + probe USB_HUB HUB_PRESENT + end + end + chip drivers/usb/acpi + register "desc" = ""USB3 Type-A Port A1 (MLB)"" + register "type" = "UPC_TYPE_USB3_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(FRONT, LEFT, ACPI_PLD_GROUP(4, 1))" + device ref usb3_port2 on end + end + chip drivers/usb/acpi + register "desc" = ""USB3 Type-A Port A2 (MLB)"" + register "type" = "UPC_TYPE_USB3_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(BACK, CENTER, ACPI_PLD_GROUP(6, 1))" + device ref usb3_port3 on end + end + chip drivers/usb/acpi + register "desc" = ""USB3 Type-A Port A3 (MLB)"" + register "type" = "UPC_TYPE_USB3_A" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_A(BACK, LEFT, ACPI_PLD_GROUP(5, 1))" + device ref usb3_port4 on end + end + end + end + end + end +end diff --git a/src/mainboard/google/brya/variants/moxoe/ramstage.c b/src/mainboard/google/brya/variants/moxoe/ramstage.c new file mode 100644 index 00000000000..de5254337a7 --- /dev/null +++ b/src/mainboard/google/brya/variants/moxoe/ramstage.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include +#include +#include + +const struct cpu_power_limits limits[] = { + /* SKU_ID, TDP (Watts), pl1_min, pl1_max, pl2_min, pl2_max, pl4 */ + { PCI_DID_INTEL_RPL_P_ID_5, 15, 15000, 15000, 55000, 55000, 100000 }, + { PCI_DID_INTEL_RPL_P_ID_4, 15, 15000, 15000, 55000, 55000, 100000 }, + { PCI_DID_INTEL_RPL_P_ID_3, 15, 15000, 15000, 55000, 55000, 100000 }, +}; + +const struct system_power_limits sys_limits[] = { + /* SKU_ID, TDP (Watts), psys_pl2 (Watts) */ + { PCI_DID_INTEL_RPL_P_ID_5, 15, 138 }, + { PCI_DID_INTEL_RPL_P_ID_4, 15, 138 }, + { PCI_DID_INTEL_RPL_P_ID_3, 15, 138 }, +}; + +/* + * Psys_pmax considerations. + * + * Given the hardware design in moxoe, the serial shunt resistor is 0.005ohm. + * The full scale of hardware PSYS signal 1.6v maps to system current 11.25A + * instead of real system power. The equation is shown below: + * PSYS = 1.6v = (0.005ohm x 11.25A) x 50 (INA213, gain 50V/V) x R501/(R501 + R510) + * R501/(R501 + R510) = 0.57 = 20K / (20K + 15K) + * + * The Psys_pmax is a SW setting which tells IMVP9.1 the mapping b/w system input + * current and the actual system power. Since there is no voltage information + * from PSYS, different voltage input would map to different Psys_pmax settings: + * For Type-C 15V, the Psys_pmax should be 15v x 11.25A = 168.75W + * For Type-C 20V, the Psys_pmax should be 20v x 11.25A = 225W + * For a barrel jack, the Psys_pmax should be 20v x 11.25A = 225W + * + * Imagine that there is a type-c 100W (20V/5A) connected to DUT w/ full loading, + * and the Psys_pmax setting is 225W. Then IMVP9.1 can calculate the current system + * power = 225W * 5A / 11.25A = 100W, which is the actual system power. + */ +const struct psys_config psys_config = { + .efficiency = 97, + .psys_imax_ma = 11250, + .bj_volts_mv = 20000 +}; + +void variant_devtree_update(void) +{ + size_t total_entries = ARRAY_SIZE(limits); + variant_update_psys_power_limits(limits, sys_limits, total_entries, &psys_config); + + variant_update_power_limits(limits, total_entries); +} diff --git a/src/mainboard/google/brya/variants/moxoe/variant.c b/src/mainboard/google/brya/variants/moxoe/variant.c new file mode 100644 index 00000000000..b7cba968a52 --- /dev/null +++ b/src/mainboard/google/brya/variants/moxoe/variant.c @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +const char *get_wifi_sar_cbfs_filename(void) +{ + return "wifi_sar_0.hex"; +} + +void variant_update_soc_chip_config(struct soc_intel_alderlake_config *config) +{ + config->cnvi_bt_audio_offload = fw_config_probe(FW_CONFIG(AUDIO, + NAU88L25B_I2S)); + + if (fw_config_probe(FW_CONFIG(MB_USBC, TC_USB3))) { + config->tcss_aux_ori = 1; + config->typec_aux_bias_pads[0].pad_auxp_dc = GPP_C3; + config->typec_aux_bias_pads[0].pad_auxn_dc = GPP_C4; + } +} diff --git a/src/mainboard/google/brya/variants/nivviks/overridetree.cb b/src/mainboard/google/brya/variants/nivviks/overridetree.cb index b90cda17826..db860c434d9 100644 --- a/src/mainboard/google/brya/variants/nivviks/overridetree.cb +++ b/src/mainboard/google/brya/variants/nivviks/overridetree.cb @@ -386,6 +386,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 5675 Camera"" + register "sensor_name" = ""CJFLE39"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" diff --git a/src/mainboard/google/brya/variants/pirrha/overridetree.cb b/src/mainboard/google/brya/variants/pirrha/overridetree.cb index 48f317157d3..58f83b5b21b 100644 --- a/src/mainboard/google/brya/variants/pirrha/overridetree.cb +++ b/src/mainboard/google/brya/variants/pirrha/overridetree.cb @@ -300,10 +300,11 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/primus/overridetree.cb b/src/mainboard/google/brya/variants/primus/overridetree.cb index b2619ee67d3..f073184ed42 100644 --- a/src/mainboard/google/brya/variants/primus/overridetree.cb +++ b/src/mainboard/google/brya/variants/primus/overridetree.cb @@ -183,7 +183,7 @@ chip soc/intel/alderlake register "pch_pcie_rp[PCH_RP(3)]" = "{ .clk_src = 6, .clk_req = 6, - .flags = PCIE_RP_LTR | PCIE_RP_AER, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_BUILT_IN, }" end #PCIE3 BH799BB device ref tcss_dma0 on diff --git a/src/mainboard/google/brya/variants/pujjocento/memory/Makefile.mk b/src/mainboard/google/brya/variants/pujjocento/memory/Makefile.mk index c60f5439fed..5c2e43e1aa1 100644 --- a/src/mainboard/google/brya/variants/pujjocento/memory/Makefile.mk +++ b/src/mainboard/google/brya/variants/pujjocento/memory/Makefile.mk @@ -8,3 +8,5 @@ SPD_SOURCES += spd/lp5/set-0/spd-9.hex # ID = 0(0b0000) Parts = K3KL6L60GM SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 1(0b0001) Parts = H9JCNNNBK3MLYR-N6E SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 2(0b0010) Parts = H58G56CK8BX146 SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = K3KL8L80CM-MGCT +SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 4(0b0100) Parts = MT62F1G32D2DS-031RF WT:C +SPD_SOURCES += spd/lp5/set-0/spd-6.hex # ID = 5(0b0101) Parts = MT62F2G32D4DS-031RF WT:C diff --git a/src/mainboard/google/brya/variants/pujjocento/memory/dram_id.generated.txt b/src/mainboard/google/brya/variants/pujjocento/memory/dram_id.generated.txt index 94e605c7b26..d7e389d4513 100644 --- a/src/mainboard/google/brya/variants/pujjocento/memory/dram_id.generated.txt +++ b/src/mainboard/google/brya/variants/pujjocento/memory/dram_id.generated.txt @@ -8,3 +8,5 @@ K3KL6L60GM-MGCT 0 (0000) H9JCNNNBK3MLYR-N6E 1 (0001) H58G56CK8BX146 2 (0010) K3KL8L80CM-MGCT 3 (0011) +MT62F1G32D2DS-031RF WT:C 4 (0100) +MT62F2G32D4DS-031RF WT:C 5 (0101) diff --git a/src/mainboard/google/brya/variants/pujjocento/memory/mem_parts_used.txt b/src/mainboard/google/brya/variants/pujjocento/memory/mem_parts_used.txt index e38d99697dc..6d5723fdbf8 100644 --- a/src/mainboard/google/brya/variants/pujjocento/memory/mem_parts_used.txt +++ b/src/mainboard/google/brya/variants/pujjocento/memory/mem_parts_used.txt @@ -13,3 +13,5 @@ K3KL6L60GM-MGCT H9JCNNNBK3MLYR-N6E H58G56CK8BX146 K3KL8L80CM-MGCT +MT62F1G32D2DS-031RF WT:C +MT62F2G32D4DS-031RF WT:C diff --git a/src/mainboard/google/brya/variants/pujjolo/memory/Makefile.mk b/src/mainboard/google/brya/variants/pujjolo/memory/Makefile.mk index b4d593dccf2..b1092e41706 100644 --- a/src/mainboard/google/brya/variants/pujjolo/memory/Makefile.mk +++ b/src/mainboard/google/brya/variants/pujjolo/memory/Makefile.mk @@ -8,3 +8,4 @@ SPD_SOURCES += spd/lp5/set-0/spd-9.hex # ID = 0(0b0000) Parts = K3KL6L60GM SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 1(0b0001) Parts = K3KL8L80CM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 2(0b0010) Parts = H58G56CK8BX146 SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 3(0b0011) Parts = H9JCNNNBK3MLYR-N6E +SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 4(0b0100) Parts = MT62F1G32D2DS-031RF WT:C diff --git a/src/mainboard/google/brya/variants/pujjolo/memory/dram_id.generated.txt b/src/mainboard/google/brya/variants/pujjolo/memory/dram_id.generated.txt index 3d03fa66a3e..a29454e5b52 100644 --- a/src/mainboard/google/brya/variants/pujjolo/memory/dram_id.generated.txt +++ b/src/mainboard/google/brya/variants/pujjolo/memory/dram_id.generated.txt @@ -8,3 +8,4 @@ K3KL6L60GM-MGCT 0 (0000) K3KL8L80CM-MGCT 1 (0001) H58G56CK8BX146 2 (0010) H9JCNNNBK3MLYR-N6E 3 (0011) +MT62F1G32D2DS-031RF WT:C 4 (0100) diff --git a/src/mainboard/google/brya/variants/pujjolo/memory/mem_parts_used.txt b/src/mainboard/google/brya/variants/pujjolo/memory/mem_parts_used.txt index e1102d6c262..a1fac3fa945 100644 --- a/src/mainboard/google/brya/variants/pujjolo/memory/mem_parts_used.txt +++ b/src/mainboard/google/brya/variants/pujjolo/memory/mem_parts_used.txt @@ -13,3 +13,4 @@ K3KL6L60GM-MGCT K3KL8L80CM-MGCT H58G56CK8BX146 H9JCNNNBK3MLYR-N6E +MT62F1G32D2DS-031RF WT:C diff --git a/src/mainboard/google/brya/variants/pujjolo/overridetree.cb b/src/mainboard/google/brya/variants/pujjolo/overridetree.cb index 738f1cb31e1..57fbfaf7f9b 100644 --- a/src/mainboard/google/brya/variants/pujjolo/overridetree.cb +++ b/src/mainboard/google/brya/variants/pujjolo/overridetree.cb @@ -388,6 +388,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "1" register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" diff --git a/src/mainboard/google/brya/variants/quandiso/memory/Makefile.mk b/src/mainboard/google/brya/variants/quandiso/memory/Makefile.mk index 166769396f5..6c970ad89ee 100644 --- a/src/mainboard/google/brya/variants/quandiso/memory/Makefile.mk +++ b/src/mainboard/google/brya/variants/quandiso/memory/Makefile.mk @@ -7,7 +7,7 @@ SPD_SOURCES = SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 0(0b0000) Parts = MT62F512M32D2DR-031 WT:B, H9JCNNNBK3MLYR-N6E SPD_SOURCES += spd/lp5/set-0/spd-2.hex # ID = 1(0b0001) Parts = MT62F1G32D4DR-031 WT:B SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 2(0b0010) Parts = H58G56AK6BX069, K3LKBKB0BM-MGCP -SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = H58G56BK7BX068, MT62F1G32D2DS-026 WT:B, K3KL8L80CM-MGCT +SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = H58G56BK7BX068, MT62F1G32D2DS-026 WT:B, K3KL8L80CM-MGCT, BWMYAX32P8A-32G SPD_SOURCES += spd/lp5/set-0/spd-8.hex # ID = 4(0b0100) Parts = H58G66BK7BX067, MT62F2G32D4DS-026 WT:B, K3KL9L90CM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-6.hex # ID = 5(0b0101) Parts = H58G66AK6BX070 SPD_SOURCES += spd/lp5/set-0/spd-9.hex # ID = 6(0b0110) Parts = K3KL6L60GM-MGCT diff --git a/src/mainboard/google/brya/variants/quandiso/memory/dram_id.generated.txt b/src/mainboard/google/brya/variants/quandiso/memory/dram_id.generated.txt index 362ef9ea214..275125f0d28 100644 --- a/src/mainboard/google/brya/variants/quandiso/memory/dram_id.generated.txt +++ b/src/mainboard/google/brya/variants/quandiso/memory/dram_id.generated.txt @@ -21,3 +21,4 @@ MT62F1G32D2DS-023 WT:C 7 (0111) H58G56CK8BX146 7 (0111) K3KL8L80EM-MGCU 7 (0111) MT62F512M32D1DS-023 WT:E 7 (0111) +BWMYAX32P8A-32G 3 (0011) diff --git a/src/mainboard/google/brya/variants/quandiso/memory/mem_parts_used.txt b/src/mainboard/google/brya/variants/quandiso/memory/mem_parts_used.txt index 76c6d3f3166..1570fe89627 100644 --- a/src/mainboard/google/brya/variants/quandiso/memory/mem_parts_used.txt +++ b/src/mainboard/google/brya/variants/quandiso/memory/mem_parts_used.txt @@ -26,3 +26,4 @@ MT62F1G32D2DS-023 WT:C H58G56CK8BX146 K3KL8L80EM-MGCU MT62F512M32D1DS-023 WT:E +BWMYAX32P8A-32G diff --git a/src/mainboard/google/brya/variants/redrix/overridetree.cb b/src/mainboard/google/brya/variants/redrix/overridetree.cb index 9f79c6ab21b..4410e49f208 100644 --- a/src/mainboard/google/brya/variants/redrix/overridetree.cb +++ b/src/mainboard/google/brya/variants/redrix/overridetree.cb @@ -102,7 +102,7 @@ chip soc/intel/alderlake device domain 0 on device ref igpu on chip drivers/gfx/generic - register "device_count" = "6" + register "device_count" = "7" # DDIA for eDP register "device[0].name" = ""LCD0"" # Use ChromeOS privacy screen _HID @@ -125,12 +125,16 @@ chip soc/intel/alderlake register "device[4].pld" = "ACPI_PLD_TYPE_C(RIGHT, LEFT, ACPI_PLD_GROUP(2, 1))" # TCP3 (DP-4) is unused for any ports but still enumerated in the kernel, so GFX device is added for TCP3 register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" device generic 0 on probe EPS PRIVACY_SCREEN end end chip drivers/gfx/generic - register "device_count" = "6" + register "device_count" = "7" # DDIA for eDP register "device[0].name" = ""LCD0"" # Internal panel on the first port of the graphics chip @@ -149,6 +153,10 @@ chip soc/intel/alderlake register "device[4].pld" = "ACPI_PLD_TYPE_C(RIGHT, LEFT, ACPI_PLD_GROUP(2, 1))" # TCP3 (DP-4) is unused for any ports but still enumerated in the kernel, so GFX device is added for TCP3 register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" device generic 0 on probe EPS PRIVACY_SCREEN_ABSENT end @@ -417,10 +425,11 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 5675 Camera"" + register "sensor_name" = ""CJFLE39"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" @@ -459,11 +468,12 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Hi-556 Camera"" + register "sensor_name" = ""CJFLE25"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" diff --git a/src/mainboard/google/brya/variants/redrix4es/overridetree.cb b/src/mainboard/google/brya/variants/redrix4es/overridetree.cb index d36f91e4141..c10a37acbf9 100644 --- a/src/mainboard/google/brya/variants/redrix4es/overridetree.cb +++ b/src/mainboard/google/brya/variants/redrix4es/overridetree.cb @@ -347,10 +347,11 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 5675 Camera"" + register "sensor_name" = ""CJFLE39"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" @@ -396,7 +397,7 @@ chip soc/intel/alderlake register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" diff --git a/src/mainboard/google/brya/variants/riven/Makefile.mk b/src/mainboard/google/brya/variants/riven/Makefile.mk index 393ccfdf1c3..f8d4e8ffdd4 100644 --- a/src/mainboard/google/brya/variants/riven/Makefile.mk +++ b/src/mainboard/google/brya/variants/riven/Makefile.mk @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only bootblock-y += gpio.c +romstage-y += memory.c romstage-y += gpio.c ramstage-$(CONFIG_FW_CONFIG) += fw_config.c diff --git a/src/mainboard/google/brya/variants/riven/gpio.c b/src/mainboard/google/brya/variants/riven/gpio.c index 4d0a6fea79b..6d0098f7757 100644 --- a/src/mainboard/google/brya/variants/riven/gpio.c +++ b/src/mainboard/google/brya/variants/riven/gpio.c @@ -15,6 +15,8 @@ static const struct pad_config override_gpio_table[] = { PAD_CFG_GPO(GPP_D6, 1, DEEP), /* D8 : SRCCLKREQ3# ==> NC */ PAD_NC(GPP_D8, NONE), + /* E5 : NC ==> GPP_E5_STRAP */ + PAD_CFG_GPI_LOCK(GPP_E5, DN_20K, LOCK_CONFIG), /* F12 : WWAN_RST_L */ PAD_CFG_GPO_LOCK(GPP_F12, 1, LOCK_CONFIG), /* H12 : UART0_RTS# ==> NC */ @@ -71,6 +73,8 @@ static const struct pad_config early_gpio_table[] = { PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* H11 : UART0_TXD ==> UART_SOC_TX_DBG_RX */ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), + /* E5 : NC ==> GPP_E5_STRAP */ + PAD_CFG_GPI(GPP_E5, DN_20K, DEEP), }; static const struct pad_config romstage_gpio_table[] = { diff --git a/src/mainboard/google/brya/variants/riven/memory.c b/src/mainboard/google/brya/variants/riven/memory.c new file mode 100644 index 00000000000..f5de481ed03 --- /dev/null +++ b/src/mainboard/google/brya/variants/riven/memory.c @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include + +uint8_t mb_get_channel_disable_mask(void) +{ + /* + * GPP_E5 High -> One RAM Chip + * GPP_E5 Low -> Two RAM Chip + */ + if (gpio_get(GPP_E5)) { + /* Disable all other channels except first two on each controller */ + printk(BIOS_INFO, "Device only supports one DIMM. Disable all other memory" + "channels except first two on each memory controller.\n"); + return (BIT(2) | BIT(3)); + } + + return 0; +} diff --git a/src/mainboard/google/brya/variants/riven/overridetree.cb b/src/mainboard/google/brya/variants/riven/overridetree.cb index 60111e5af29..acaffef2262 100644 --- a/src/mainboard/google/brya/variants/riven/overridetree.cb +++ b/src/mainboard/google/brya/variants/riven/overridetree.cb @@ -342,6 +342,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 5675 Camera"" + register "sensor_name" = ""CJFLE39"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" @@ -391,6 +392,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" diff --git a/src/mainboard/google/brya/variants/rull/Makefile.mk b/src/mainboard/google/brya/variants/rull/Makefile.mk index f41cdfdb8a6..efe5002383a 100644 --- a/src/mainboard/google/brya/variants/rull/Makefile.mk +++ b/src/mainboard/google/brya/variants/rull/Makefile.mk @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only bootblock-y += gpio.c +romstage-y += memory.c romstage-y += gpio.c ramstage-y += gpio.c diff --git a/src/mainboard/google/brya/variants/rull/gpio.c b/src/mainboard/google/brya/variants/rull/gpio.c index 24096d73bc5..0c5c2d0552e 100644 --- a/src/mainboard/google/brya/variants/rull/gpio.c +++ b/src/mainboard/google/brya/variants/rull/gpio.c @@ -90,6 +90,9 @@ static const struct pad_config override_gpio_table[] = { /* R7 : DMIC_DATA_1A ==> DMIC_WCAM_DATA */ PAD_CFG_NF(GPP_R7, NONE, DEEP, NF3), + /* E19 : DDP1_CTRLDATA ==> GPP_E19_STRAP */ + PAD_CFG_GPI_LOCK(GPP_E19, DN_20K, LOCK_CONFIG), + /* Configure the virtual CNVi Bluetooth I2S GPIO pads */ /* BT_I2S_BCLK */ PAD_CFG_NF(GPP_VGPIO_30, NONE, DEEP, NF3), @@ -138,6 +141,8 @@ static const struct pad_config early_gpio_table[] = { PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* H20 : IMGCLKOUT1 ==> WLAN_PERST_L */ PAD_CFG_GPO(GPP_H20, 0, DEEP), + /* E19 : DDP1_CTRLDATA ==> GPP_E19_STRAP */ + PAD_CFG_GPI(GPP_E19, DN_20K, DEEP), }; static const struct pad_config romstage_gpio_table[] = { diff --git a/src/mainboard/google/brya/variants/rull/memory.c b/src/mainboard/google/brya/variants/rull/memory.c new file mode 100644 index 00000000000..0608ae7e0df --- /dev/null +++ b/src/mainboard/google/brya/variants/rull/memory.c @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include + +uint8_t mb_get_channel_disable_mask(void) +{ + /* + * GPP_E19 High -> One RAM Chip + * GPP_E19 Low -> Two RAM Chip + * Disable all other channels except first two on each controller + */ + if (gpio_get(GPP_E19)) + return (BIT(2) | BIT(3)); + + return 0; +} diff --git a/src/mainboard/google/brya/variants/rull/memory/Makefile.mk b/src/mainboard/google/brya/variants/rull/memory/Makefile.mk index ae7be6dcd1d..682003b9af5 100644 --- a/src/mainboard/google/brya/variants/rull/memory/Makefile.mk +++ b/src/mainboard/google/brya/variants/rull/memory/Makefile.mk @@ -9,3 +9,5 @@ SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 1(0b0001) Parts = K3KL8L80CM SPD_SOURCES += spd/lp5/set-0/spd-8.hex # ID = 2(0b0010) Parts = K3KL9L90CM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-10.hex # ID = 3(0b0011) Parts = H58G66BK8BX067 SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 4(0b0100) Parts = H58G56BK8BX068, MT62F1G32D2DS-023 WT:B, H58G56CK8BX146 +SPD_SOURCES += spd/lp5/set-0/spd-2.hex # ID = 5(0b0101) Parts = H9JCNNNCP3MLYR-N6E, MT62F1G32D4DR-031 WT:B +SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 6(0b0110) Parts = K3LKBKB0BM-MGCP diff --git a/src/mainboard/google/brya/variants/rull/memory/dram_id.generated.txt b/src/mainboard/google/brya/variants/rull/memory/dram_id.generated.txt index 6a8d4b9db20..3f8483a688a 100644 --- a/src/mainboard/google/brya/variants/rull/memory/dram_id.generated.txt +++ b/src/mainboard/google/brya/variants/rull/memory/dram_id.generated.txt @@ -13,3 +13,6 @@ H58G66BK8BX067 3 (0011) H58G56BK8BX068 4 (0100) MT62F1G32D2DS-023 WT:B 4 (0100) H58G56CK8BX146 4 (0100) +H9JCNNNCP3MLYR-N6E 5 (0101) +MT62F1G32D4DR-031 WT:B 5 (0101) +K3LKBKB0BM-MGCP 6 (0110) diff --git a/src/mainboard/google/brya/variants/rull/memory/mem_parts_used.txt b/src/mainboard/google/brya/variants/rull/memory/mem_parts_used.txt index 4946ff0ab96..4b0c83cb1d4 100644 --- a/src/mainboard/google/brya/variants/rull/memory/mem_parts_used.txt +++ b/src/mainboard/google/brya/variants/rull/memory/mem_parts_used.txt @@ -18,3 +18,6 @@ H58G66BK8BX067 H58G56BK8BX068 MT62F1G32D2DS-023 WT:B H58G56CK8BX146 +H9JCNNNCP3MLYR-N6E +MT62F1G32D4DR-031 WT:B +K3LKBKB0BM-MGCP diff --git a/src/mainboard/google/brya/variants/skolas/overridetree.cb b/src/mainboard/google/brya/variants/skolas/overridetree.cb index 0f5a6cf651e..ac0e5f51daf 100644 --- a/src/mainboard/google/brya/variants/skolas/overridetree.cb +++ b/src/mainboard/google/brya/variants/skolas/overridetree.cb @@ -542,7 +542,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "0" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9808" register "vcm_address" = "0x0C" @@ -652,7 +652,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "0" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9808" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/skolas4es/overridetree.cb b/src/mainboard/google/brya/variants/skolas4es/overridetree.cb index 95a27df342c..b4e505c3051 100644 --- a/src/mainboard/google/brya/variants/skolas4es/overridetree.cb +++ b/src/mainboard/google/brya/variants/skolas4es/overridetree.cb @@ -383,7 +383,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "0" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9808" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/taeko/overridetree.cb b/src/mainboard/google/brya/variants/taeko/overridetree.cb index ff25f7b638e..dfd88a6c16b 100644 --- a/src/mainboard/google/brya/variants/taeko/overridetree.cb +++ b/src/mainboard/google/brya/variants/taeko/overridetree.cb @@ -565,7 +565,7 @@ chip soc/intel/alderlake register "pch_pcie_rp[PCH_RP(9)]" = "{ .clk_src = 0, .clk_req = 0, - .flags = PCIE_RP_LTR | PCIE_RP_AER, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_BUILT_IN, .pcie_rp_aspm = ASPM_L1, }" probe BOOT_EMMC_MASK BOOT_EMMC_ENABLED diff --git a/src/mainboard/google/brya/variants/taeko4es/overridetree.cb b/src/mainboard/google/brya/variants/taeko4es/overridetree.cb index 2dc3287a056..3e978f1e00e 100644 --- a/src/mainboard/google/brya/variants/taeko4es/overridetree.cb +++ b/src/mainboard/google/brya/variants/taeko4es/overridetree.cb @@ -390,7 +390,7 @@ chip soc/intel/alderlake end end chip drivers/sof - register "spkr_tplg" = "max98357a" + register "spkr_tplg" = "max98357a_tdm" register "jack_tplg" = "rt5682" register "mic_tplg" = "_2ch_pdm0" device generic 0 on end diff --git a/src/mainboard/google/brya/variants/taniks/overridetree.cb b/src/mainboard/google/brya/variants/taniks/overridetree.cb index e11793ae4e7..09654293dcf 100644 --- a/src/mainboard/google/brya/variants/taniks/overridetree.cb +++ b/src/mainboard/google/brya/variants/taniks/overridetree.cb @@ -383,7 +383,7 @@ chip soc/intel/alderlake register "pch_pcie_rp[PCH_RP(9)]" = "{ .clk_src = 0, .clk_req = 0, - .flags = PCIE_RP_LTR | PCIE_RP_AER, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_BUILT_IN, }" probe BOOT_EMMC_MASK BOOT_EMMC_ENABLED end diff --git a/src/mainboard/google/brya/variants/teliks/overridetree.cb b/src/mainboard/google/brya/variants/teliks/overridetree.cb index 121f432af1c..b3b8eb500a1 100644 --- a/src/mainboard/google/brya/variants/teliks/overridetree.cb +++ b/src/mainboard/google/brya/variants/teliks/overridetree.cb @@ -280,13 +280,15 @@ chip soc/intel/alderlake end device ref i2c2 on chip drivers/intel/mipi_camera - register "acpi_hid" = ""OVTIDB10"" + register "acpi_hid" = ""OVTI13B1"" register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 13b10 Camera"" + register "sensor_name" = ""09B13U"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "1" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/telith/overridetree.cb b/src/mainboard/google/brya/variants/telith/overridetree.cb index 7b5ebee441f..a071a16df03 100644 --- a/src/mainboard/google/brya/variants/telith/overridetree.cb +++ b/src/mainboard/google/brya/variants/telith/overridetree.cb @@ -406,13 +406,15 @@ chip soc/intel/alderlake end device ref i2c2 on chip drivers/intel/mipi_camera - register "acpi_hid" = ""OVTIDB10"" + register "acpi_hid" = ""OVTI13B1"" register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 13b10 Camera"" + register "sensor_name" = ""09B13U"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "1" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/vell/overridetree.cb b/src/mainboard/google/brya/variants/vell/overridetree.cb index 7fa68933df5..6bf7c63328d 100644 --- a/src/mainboard/google/brya/variants/vell/overridetree.cb +++ b/src/mainboard/google/brya/variants/vell/overridetree.cb @@ -341,6 +341,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" diff --git a/src/mainboard/google/brya/variants/volmar/overridetree.cb b/src/mainboard/google/brya/variants/volmar/overridetree.cb index f57b7339318..2145204245c 100644 --- a/src/mainboard/google/brya/variants/volmar/overridetree.cb +++ b/src/mainboard/google/brya/variants/volmar/overridetree.cb @@ -331,7 +331,7 @@ chip soc/intel/alderlake register "pch_pcie_rp[PCH_RP(3)]" = "{ .clk_src = 4, .clk_req = 4, - .flags = PCIE_RP_LTR | PCIE_RP_AER, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_BUILT_IN, }" probe BOOT_EMMC_MASK BOOT_EMMC_ENABLED end #PCIE3 BH799BB diff --git a/src/mainboard/google/brya/variants/xivu/overridetree.cb b/src/mainboard/google/brya/variants/xivu/overridetree.cb index 5b1dc9fd3d8..a367761ddf0 100644 --- a/src/mainboard/google/brya/variants/xivu/overridetree.cb +++ b/src/mainboard/google/brya/variants/xivu/overridetree.cb @@ -250,10 +250,11 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" diff --git a/src/mainboard/google/brya/variants/yaviks/memory/Makefile.mk b/src/mainboard/google/brya/variants/yaviks/memory/Makefile.mk index 8f38bca9dea..ccd34e882df 100644 --- a/src/mainboard/google/brya/variants/yaviks/memory/Makefile.mk +++ b/src/mainboard/google/brya/variants/yaviks/memory/Makefile.mk @@ -6,9 +6,9 @@ SPD_SOURCES = SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 0(0b0000) Parts = MT62F512M32D2DR-031 WT:B, H9JCNNNBK3MLYR-N6E SPD_SOURCES += spd/lp5/set-0/spd-2.hex # ID = 1(0b0001) Parts = MT62F1G32D4DR-031 WT:B -SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 2(0b0010) Parts = H58G56AK6BX069, K3LKBKB0BM-MGCP +SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 2(0b0010) Parts = H58G56AK6BX069, K3LKBKB0BM-MGCP, MT62F1G32D2DS-031RF WT:C SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = H58G56BK7BX068, MT62F1G32D2DS-026 WT:B, K3KL8L80CM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-8.hex # ID = 4(0b0100) Parts = H58G66BK7BX067, MT62F2G32D4DS-026 WT:B, K3KL9L90CM-MGCT -SPD_SOURCES += spd/lp5/set-0/spd-6.hex # ID = 5(0b0101) Parts = H58G66AK6BX070 +SPD_SOURCES += spd/lp5/set-0/spd-6.hex # ID = 5(0b0101) Parts = H58G66AK6BX070, MT62F2G32D4DS-031RF WT:C SPD_SOURCES += spd/lp5/set-0/spd-9.hex # ID = 6(0b0110) Parts = K3KL6L60GM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 7(0b0111) Parts = H58G56CK8BX146 diff --git a/src/mainboard/google/brya/variants/yaviks/memory/dram_id.generated.txt b/src/mainboard/google/brya/variants/yaviks/memory/dram_id.generated.txt index d0e3dfe8de1..4dbb10bc33e 100644 --- a/src/mainboard/google/brya/variants/yaviks/memory/dram_id.generated.txt +++ b/src/mainboard/google/brya/variants/yaviks/memory/dram_id.generated.txt @@ -18,3 +18,5 @@ K3KL9L90CM-MGCT 4 (0100) H58G66AK6BX070 5 (0101) K3KL6L60GM-MGCT 6 (0110) H58G56CK8BX146 7 (0111) +MT62F1G32D2DS-031RF WT:C 2 (0010) +MT62F2G32D4DS-031RF WT:C 5 (0101) diff --git a/src/mainboard/google/brya/variants/yaviks/memory/mem_parts_used.txt b/src/mainboard/google/brya/variants/yaviks/memory/mem_parts_used.txt index d9e4129cbad..3a13bb4951b 100644 --- a/src/mainboard/google/brya/variants/yaviks/memory/mem_parts_used.txt +++ b/src/mainboard/google/brya/variants/yaviks/memory/mem_parts_used.txt @@ -23,3 +23,5 @@ K3KL9L90CM-MGCT H58G66AK6BX070 K3KL6L60GM-MGCT H58G56CK8BX146 +MT62F1G32D2DS-031RF WT:C +MT62F2G32D4DS-031RF WT:C diff --git a/src/mainboard/google/brya/variants/yaviks/overridetree.cb b/src/mainboard/google/brya/variants/yaviks/overridetree.cb index 334b2bc6199..31e89fa88c8 100644 --- a/src/mainboard/google/brya/variants/yaviks/overridetree.cb +++ b/src/mainboard/google/brya/variants/yaviks/overridetree.cb @@ -327,6 +327,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" diff --git a/src/mainboard/google/brya/variants/yavilla/memory/Makefile.mk b/src/mainboard/google/brya/variants/yavilla/memory/Makefile.mk index 26c31d4ef3b..99061e1d121 100644 --- a/src/mainboard/google/brya/variants/yavilla/memory/Makefile.mk +++ b/src/mainboard/google/brya/variants/yavilla/memory/Makefile.mk @@ -6,9 +6,9 @@ SPD_SOURCES = SPD_SOURCES += spd/lp5/set-0/spd-1.hex # ID = 0(0b0000) Parts = MT62F512M32D2DR-031 WT:B, H9JCNNNBK3MLYR-N6E SPD_SOURCES += spd/lp5/set-0/spd-10.hex # ID = 1(0b0001) Parts = H58G66CK8BX147 -SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 2(0b0010) Parts = H58G56AK6BX069, K3LKBKB0BM-MGCP +SPD_SOURCES += spd/lp5/set-0/spd-3.hex # ID = 2(0b0010) Parts = H58G56AK6BX069, K3LKBKB0BM-MGCP, MT62F1G32D2DS-031RF WT:C SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 3(0b0011) Parts = H58G56BK7BX068, MT62F1G32D2DS-026 WT:B, K3KL8L80CM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-8.hex # ID = 4(0b0100) Parts = H58G66BK7BX067, MT62F2G32D4DS-026 WT:B, K3KL9L90CM-MGCT -SPD_SOURCES += spd/lp5/set-0/spd-6.hex # ID = 5(0b0101) Parts = H58G66AK6BX070 +SPD_SOURCES += spd/lp5/set-0/spd-6.hex # ID = 5(0b0101) Parts = H58G66AK6BX070, MT62F2G32D4DS-031RF WT:C SPD_SOURCES += spd/lp5/set-0/spd-9.hex # ID = 6(0b0110) Parts = K3KL6L60GM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 7(0b0111) Parts = H58G56CK8BX146 diff --git a/src/mainboard/google/brya/variants/yavilla/memory/dram_id.generated.txt b/src/mainboard/google/brya/variants/yavilla/memory/dram_id.generated.txt index 1264f20e91f..6b938ba8dd9 100644 --- a/src/mainboard/google/brya/variants/yavilla/memory/dram_id.generated.txt +++ b/src/mainboard/google/brya/variants/yavilla/memory/dram_id.generated.txt @@ -18,3 +18,5 @@ K3KL9L90CM-MGCT 4 (0100) H58G66AK6BX070 5 (0101) K3KL6L60GM-MGCT 6 (0110) H58G56CK8BX146 7 (0111) +MT62F1G32D2DS-031RF WT:C 2 (0010) +MT62F2G32D4DS-031RF WT:C 5 (0101) diff --git a/src/mainboard/google/brya/variants/yavilla/memory/mem_parts_used.txt b/src/mainboard/google/brya/variants/yavilla/memory/mem_parts_used.txt index 76efa2cd440..d0add1f65a9 100644 --- a/src/mainboard/google/brya/variants/yavilla/memory/mem_parts_used.txt +++ b/src/mainboard/google/brya/variants/yavilla/memory/mem_parts_used.txt @@ -23,3 +23,5 @@ K3KL9L90CM-MGCT H58G66AK6BX070 K3KL6L60GM-MGCT H58G56CK8BX146 +MT62F1G32D2DS-031RF WT:C +MT62F2G32D4DS-031RF WT:C diff --git a/src/mainboard/google/brya/variants/yavilla/overridetree.cb b/src/mainboard/google/brya/variants/yavilla/overridetree.cb index 588919da549..3686de90e93 100644 --- a/src/mainboard/google/brya/variants/yavilla/overridetree.cb +++ b/src/mainboard/google/brya/variants/yavilla/overridetree.cb @@ -113,6 +113,12 @@ chip soc/intel/alderlake .configure_ext_fivr = 1, }" + register "power_limits_config[ADL_N_041_6W_CORE]" = "{ + .tdp_pl1_override = 7, + .tdp_pl2_override = 25, + .tdp_pl4 = 78, + }" + # Intel Common SoC Config #+-------------------+---------------------------+ #| Field | Value | @@ -202,7 +208,7 @@ chip soc/intel/alderlake register "controls.power_limits" = "{ .pl1 = { .min_power = 3000, - .max_power = 6000, + .max_power = 7000, .time_window_min = 28 * MSECS_PER_SEC, .time_window_max = 32 * MSECS_PER_SEC, .granularity = 200 @@ -323,6 +329,24 @@ chip soc/intel/alderlake probe TOUCH_PANEL TOUCH_G2_HID_I2c end end + chip drivers/i2c/hid + register "generic.hid" = ""LXST2024"" + register "generic.desc" = ""LGD Touchscreen"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_C7_IRQ)" + register "generic.detect" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_C1)" + register "generic.reset_delay_ms" = "20" + register "generic.reset_off_delay_ms" = "2" + register "generic.stop_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_C6)" + register "generic.stop_delay_ms" = "280" + register "generic.stop_off_delay_ms" = "2" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_C0)" + register "generic.enable_delay_ms" = "1" + register "generic.has_power_resource" = "1" + register "generic.use_gpio_for_status" = "true" + register "hid_desc_reg_offset" = "0x00" + device i2c 34 on end + end chip drivers/i2c/hid register "generic.hid" = ""GTCH7503"" register "generic.desc" = ""G2TOUCH Touchscreen"" @@ -361,6 +385,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" diff --git a/src/mainboard/google/brya/variants/zydron/overridetree.cb b/src/mainboard/google/brya/variants/zydron/overridetree.cb index a632d362948..f87f9f3f16e 100644 --- a/src/mainboard/google/brya/variants/zydron/overridetree.cb +++ b/src/mainboard/google/brya/variants/zydron/overridetree.cb @@ -298,6 +298,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 2740 Camera"" + register "sensor_name" = ""CJFLE23"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" @@ -341,6 +342,7 @@ chip soc/intel/alderlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Hi-556 Camera"" + register "sensor_name" = ""CJFLE25"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" diff --git a/src/mainboard/google/butterfly/Kconfig b/src/mainboard/google/butterfly/Kconfig index 432374bb972..09ef13511b0 100644 --- a/src/mainboard/google/butterfly/Kconfig +++ b/src/mainboard/google/butterfly/Kconfig @@ -35,6 +35,9 @@ config MAINBOARD_DIR config MAINBOARD_PART_NUMBER default "Butterfly" +config CBFS_SIZE + default 0x600000 + config MAINBOARD_VENDOR string default "Hewlett-Packard" diff --git a/src/mainboard/google/butterfly/Kconfig.name b/src/mainboard/google/butterfly/Kconfig.name index fdde138279f..e02eeb96094 100644 --- a/src/mainboard/google/butterfly/Kconfig.name +++ b/src/mainboard/google/butterfly/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Butterfly" +comment "Butterfly (Intel SandyBridge (2nd Gen))" config BOARD_GOOGLE_BUTTERFLY bool "-> Butterfly (HP Pavilion Chromebook 14)" diff --git a/src/mainboard/google/cherry/Kconfig.name b/src/mainboard/google/cherry/Kconfig.name index 666bce4bf0d..bef53bab402 100644 --- a/src/mainboard/google/cherry/Kconfig.name +++ b/src/mainboard/google/cherry/Kconfig.name @@ -1,12 +1,12 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Cherry" +comment "Cherry (MediaTek Kompanio 1200 (MT8195))" config BOARD_GOOGLE_CHERRY bool "-> Cherry" config BOARD_GOOGLE_DOJO - bool "-> Dojo" + bool "-> Dojo (HP Chromebook x360 (13b-ca0002sa))" config BOARD_GOOGLE_TOMATO - bool "-> Tomato" + bool "-> Tomato (Acer Chromebook Spin 513 (CP513-2H))" diff --git a/src/mainboard/google/corsola/Kconfig b/src/mainboard/google/corsola/Kconfig index 1f249ac1a18..b137588191a 100644 --- a/src/mainboard/google/corsola/Kconfig +++ b/src/mainboard/google/corsola/Kconfig @@ -77,6 +77,7 @@ config BOARD_SPECIFIC_OPTIONS select MIPI_PANEL_STA_ER88577 if BOARD_GOOGLE_WUGTRIO select MIPI_PANEL_STA_HIMAX83102_J02 if BOARD_GOOGLE_STARMIE select MIPI_PANEL_STA_ILI9882T if BOARD_GOOGLE_STARMIE + select MIPI_PANEL_TG_XTI05101 if BOARD_GOOGLE_WUGTRIO config VBOOT select EC_GOOGLE_CHROMEEC_SWITCHES diff --git a/src/mainboard/google/corsola/Kconfig.name b/src/mainboard/google/corsola/Kconfig.name index 5de50c3533b..774f07649e8 100644 --- a/src/mainboard/google/corsola/Kconfig.name +++ b/src/mainboard/google/corsola/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Kingler" +comment "Kingler (MediaTek Kompanio 520 (MT8186))" config BOARD_GOOGLE_KINGLER bool "-> Kingler" @@ -12,18 +12,27 @@ config BOARD_GOOGLE_PONYTA bool "-> Ponyta" config BOARD_GOOGLE_SQUIRTLE - bool "-> Squirtle" + bool "-> Squirtle (Acer Chromebook Spin 311 (R724T))" config BOARD_GOOGLE_STEELIX - bool "-> Steelix" + bool "-> Steelix/Magneton (see help text for details)" + help + The "Steelix" board supports the following devices: + - Lenovo 300e Yoga Chromebook Gen 4 (Steelix, convertible) + - Lenovo IdeaPad Slim 3 Chromebook (14M868) (Magneton, clamshell) config BOARD_GOOGLE_VOLTORB - bool "-> Voltorb" + bool "-> Voltorb (Acer Chromebook 311 (C723/C732T))" -comment "Krabby" +comment "Krabby (MediaTek Kompanio 520 (MT8186))" config BOARD_GOOGLE_CHINCHOU - bool "-> Chinchou" + bool "-> Chinchou/Chinochou360 (see help text for details)" + help + The "Chinochou" board supports the following devices: + - Asus Chromebook CZ1104CM2A/CZ1204CM2A + - Asus Chromebook CZ1104FM2A/CZ1204FM2A/CZ1104CM2A/CZ1204CM2A + - Asus Chromebook CZ1104FM2A/CZ1204FM2A Flip config BOARD_GOOGLE_KRABBY bool "-> Krabby" @@ -35,15 +44,19 @@ config BOARD_GOOGLE_SKITTY bool "-> Skitty" config BOARD_GOOGLE_TENTACRUEL - bool "-> Tentacruel" + bool "-> Tentacruel/Tentacool (see help text for details)" + help + The "Tentacruel" board supports the following devices: + - ASUS Chromebook CM14 Flip (CM1402F) (Tentacruel, convertible) + - ASUS Chromebook CM14 (CM1402C) (Tentacool, clamshell) config BOARD_GOOGLE_VELUZA bool "-> Veluza" -comment "Staryu" +comment "Staryu (MediaTek Kompanio 528 (MT8186T))" config BOARD_GOOGLE_STARMIE - bool "-> Starmie" + bool "-> Starmie (ASUS Chromebook Enterprise CM30 (CM3001))" config BOARD_GOOGLE_WUGTRIO bool "-> Wugtrio" diff --git a/src/mainboard/google/corsola/panel_wugtrio.c b/src/mainboard/google/corsola/panel_wugtrio.c index 0603ce05167..7a729b2724a 100644 --- a/src/mainboard/google/corsola/panel_wugtrio.c +++ b/src/mainboard/google/corsola/panel_wugtrio.c @@ -49,6 +49,14 @@ static struct panel_description wugtrio_panels[] = { .disp_path = DISP_PATH_MIPI, .orientation = LB_FB_ORIENTATION_RIGHT_UP, }, + /* TaiGuan Corporation panel with bias IC on it */ + [10] = { + .configure_backlight = backlight_control, + .power_on = mipi_panel_power_on, + .name = "TG_XTI05101", + .disp_path = DISP_PATH_MIPI, + .orientation = LB_FB_ORIENTATION_RIGHT_UP, + }, }; struct panel_description *get_panel_description(void) diff --git a/src/mainboard/google/cyan/Kconfig b/src/mainboard/google/cyan/Kconfig index eacc8ef87dc..bda04161721 100644 --- a/src/mainboard/google/cyan/Kconfig +++ b/src/mainboard/google/cyan/Kconfig @@ -8,6 +8,7 @@ config BOARD_GOOGLE_BASEBOARD_CYAN select EC_GOOGLE_CHROMEEC_BOARDID select EC_GOOGLE_CHROMEEC_LPC select EC_GOOGLE_CHROMEEC_MEC + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_OPTION_TABLE @@ -107,7 +108,7 @@ config OVERRIDE_DEVICETREE default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" config CBFS_SIZE - default 0x200000 + default 0x600000 config MAINBOARD_SMBIOS_MANUFACTURER string diff --git a/src/mainboard/google/cyan/Kconfig.name b/src/mainboard/google/cyan/Kconfig.name index 6edc464919d..7400aee7d6a 100644 --- a/src/mainboard/google/cyan/Kconfig.name +++ b/src/mainboard/google/cyan/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Cyan" +comment "Cyan (Intel Braswell)" config BOARD_GOOGLE_BANON bool "-> Banon (Acer Chromebook 15 (CB3-532))" diff --git a/src/mainboard/google/daisy/Kconfig.name b/src/mainboard/google/daisy/Kconfig.name index f5152a1ec12..cb16bceac02 100644 --- a/src/mainboard/google/daisy/Kconfig.name +++ b/src/mainboard/google/daisy/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Daisy" +comment "Daisy (Samsung Exynos 5250)" config BOARD_GOOGLE_DAISY bool "-> Daisy (Samsung Chromebook (2012))" diff --git a/src/mainboard/google/dedede/Kconfig b/src/mainboard/google/dedede/Kconfig index a17c7560466..7e470d6b87e 100644 --- a/src/mainboard/google/dedede/Kconfig +++ b/src/mainboard/google/dedede/Kconfig @@ -278,6 +278,7 @@ if BOARD_GOOGLE_BASEBOARD_DEDEDE config BASEBOARD_DEDEDE_LAPTOP def_bool n + select DRIVERS_GFX_GENERIC select SYSTEM_TYPE_LAPTOP config CHROMEOS @@ -309,6 +310,10 @@ config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/chromeos-dedede-16MiB.fmd" if CHROMEOS && BOARD_ROMSIZE_KB_16384 default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/chromeos-dedede-32MiB.fmd" if CHROMEOS && BOARD_ROMSIZE_KB_32768 +config CBFS_SIZE + default 0xc7f000 if BOARD_ROMSIZE_KB_16384 + default 0x1000000 if BOARD_ROMSIZE_KB_32768 + config MAINBOARD_DIR default "google/dedede" diff --git a/src/mainboard/google/dedede/Kconfig.name b/src/mainboard/google/dedede/Kconfig.name index fd130ecb8d4..1b1c4679506 100644 --- a/src/mainboard/google/dedede/Kconfig.name +++ b/src/mainboard/google/dedede/Kconfig.name @@ -1,9 +1,16 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Dedede" +comment "Dedede (Intel JasperLake)" config BOARD_GOOGLE_BEADRIX - bool "-> Beadrix" + bool "-> Beadrix (Multiple devices - See help text)" + help + The "Beadrix" board supports the following devces: + - DINATECH Gen1 Chromebook SG20JL1C + - Multilaser Chromebook M11C-PC919 + - Evolve III Chromebook 11 E1 + - Positivo Chromebook N2320 + - Allied Chromebook 11 N5100E config BOARD_GOOGLE_BLIPPER bool "-> Blipper (Lenovo 3i-15 Chromebook)" @@ -57,10 +64,26 @@ config BOARD_GOOGLE_GOOEY bool "-> Gooey" config BOARD_GOOGLE_HABOKI - bool "-> HABOKI" + bool "-> Haboki" config BOARD_GOOGLE_KRACKO - bool "-> Kracko" + bool "-> Kracko/Kracko360 (Multiple devices - See help text)" + help + The "Kracko" board is for "clamshell" form factor. + The "Kracko360" board is for "convertible" form factor. + They support the following devices: + - ADVAN Chromebook 116J + - Centerm Chromebook M610 + - CTL Chromebook NL72 + - CTL Chromebook NL72T + - Edxis Chromebook 11 + - LG Chromebook 11TC50Q/11TQ50Q + - Poin2 Chromebook 11B + - Poin2 Chromebook 11E + - Zyrex Chromebook M432-64 + - Multilaser Chromebook M11HC-PC916 + - Positivo Chromebook N2310 + - Positivo Chromebook N2312 config BOARD_GOOGLE_LALALA bool "-> Lalala" @@ -78,7 +101,14 @@ config BOARD_GOOGLE_METAKNIGHT bool "-> Metaknight (NEC Chromebook Y3)" config BOARD_GOOGLE_PIRIKA - bool "-> Pirika" + bool "-> Pirika (Multiple devices - See help text)" + help + The Drawcia board supports the following devices: + - Axioo Chromebook P14 + - CTL Chromebook Enterprise + - Gateway Chromebook 14 + - Arai Nimbus S1 Chromebook Enterprise + - Edxis E-Lite Chromebook 14 config BOARD_GOOGLE_SASUKE bool "-> Sasuke (Samsung Galaxy Chromebook Go)" diff --git a/src/mainboard/google/dedede/cfr.c b/src/mainboard/google/dedede/cfr.c index 63705fcd3df..50f85c90cba 100644 --- a/src/mainboard/google/dedede/cfr.c +++ b/src/mainboard/google/dedede/cfr.c @@ -24,21 +24,6 @@ static const struct sm_object touchscreen = SM_DECLARE_ENUM({ #endif }); -static const struct sm_object touchpad = SM_DECLARE_ENUM({ - .opt_name = "touchpad", - .ui_name = "Touchpad Type", - .ui_helptext = "Select the model of the integrated touchpad device", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Auto-select", 0 }, - { "ELAN0000", 1 }, - { "ELAN2702", 2 }, - SM_ENUM_VALUE_END }, -#if !CONFIG(BOARD_GOOGLE_GALTIC) - .flags = CFR_OPTFLAG_SUPPRESS, -#endif -}); - static struct sm_obj_form system = { .ui_name = "System", .obj_list = (const struct sm_object *[]) { @@ -69,7 +54,6 @@ static struct sm_obj_form devices = { .ui_name = "Devices", .obj_list = (const struct sm_object *[]) { &touchscreen, - &touchpad, NULL }, }; diff --git a/src/mainboard/google/dedede/variants/awasuki/overridetree.cb b/src/mainboard/google/dedede/variants/awasuki/overridetree.cb index 76b7033f54f..f179a773882 100644 --- a/src/mainboard/google/dedede/variants/awasuki/overridetree.cb +++ b/src/mainboard/google/dedede/variants/awasuki/overridetree.cb @@ -53,14 +53,9 @@ chip soc/intel/jasperlake }" # SerialIO device mode selection - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ @@ -89,7 +84,18 @@ chip soc/intel/jasperlake register "SdCardPowerEnableActiveHigh" = "0" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf ## sensor information register "options.tsr[0].desc" = ""Ambient"" @@ -139,48 +145,30 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on - chip drivers/usb/acpi - device usb 2.1 off end - end - chip drivers/usb/acpi - device usb 2.3 off end - end - chip drivers/usb/acpi - device usb 2.4 off end - end + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""User Facing Camera"" register "type" = "UPC_TYPE_INTERNAL" register "has_power_resource" = "true" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D15)" register "enable_delay_ms" = "20" - device usb 2.5 on end - end - chip drivers/usb/acpi - device usb 2.6 off end - end - chip drivers/usb/acpi - device usb 3.1 off end - end - chip drivers/usb/acpi - device usb 3.3 off end + device ref usb2_port6 on end end end end - end # USB xHCI - device pci 14.3 on + end + device ref cnvi_wifi on chip drivers/wifi/generic register "wake" = "GPE0_PME_B0" register "enable_cnvi_ddr_rfim" = "true" register "add_acpi_dma_property" = "true" device generic 0 on end end - end # CNVi wifi - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""PNP0C50"" register "generic.desc" = ""PIXART Touchpad"" @@ -190,9 +178,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 15 on end end - end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 on + end + device ref i2c2 on probe TOUCHSCREEN TOUCHSCREEN_PRESENT chip drivers/i2c/generic register "hid" = ""ELAN0001"" @@ -212,9 +199,8 @@ chip soc/intel/jasperlake register "has_power_resource" = "true" device i2c 10 on end end - end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/rt5645 register "hid" = ""10EC5650"" register "name" = ""RT58"" @@ -224,20 +210,20 @@ chip soc/intel/jasperlake register "jd_mode" = "2" device i2c 1a on end end - end # I2C 4 - device pci 1c.7 on + end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN - device pci 1f.3 on + end + device ref hda on chip drivers/sof register "spkr_tplg" = "rt5650_sp" register "jack_tplg" = "rt5650_hp" register "mic_tplg" = "_2ch_pdm0" device generic 0 on end end - end # Intel HDA/cAVS + end end end diff --git a/src/mainboard/google/dedede/variants/baseboard/devicetree.cb b/src/mainboard/google/dedede/variants/baseboard/devicetree.cb index be057ea57db..d7f91cda461 100644 --- a/src/mainboard/google/dedede/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/dedede/variants/baseboard/devicetree.cb @@ -80,11 +80,11 @@ chip soc/intel/jasperlake register "usb3_ports[3]" = "USB3_PORT_DEFAULT(OC_SKIP)" # USB3/1 Type-A Port A1 register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoPci, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoPci, - [PchSerialIoIndexI2C4] = PchSerialIoPci, + [PchSerialIoIndexI2C0] = PchSerialIoDisabled, + [PchSerialIoIndexI2C1] = PchSerialIoDisabled, + [PchSerialIoIndexI2C2] = PchSerialIoDisabled, + [PchSerialIoIndexI2C3] = PchSerialIoDisabled, + [PchSerialIoIndexI2C4] = PchSerialIoDisabled, [PchSerialIoIndexI2C5] = PchSerialIoDisabled, }" @@ -228,11 +228,8 @@ chip soc/intel/jasperlake register "xhci_lfps_sampling_offtime_ms" = "9" device domain 0 on - device pci 00.0 on end # Host Bridge - device pci 02.0 on - register "gfx" = "GMA_DEFAULT_PANEL(0)" - end # Integrated Graphics Device - device pci 04.0 on + device ref igpu on end + device ref dptf on # Default DPTF Policy for all Dedede boards if not overridden chip drivers/intel/dptf ## Passive Policy @@ -283,132 +280,96 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 05.0 off end # IPU - device pci 08.0 on end # GNA - device pci 09.0 off end # Intel Trace Hub - device pci 12.6 off end # GSPI 2 - device pci 14.0 on + end + device ref gna on end + device ref south_xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Left Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""Left Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.3 on end - end - chip drivers/usb/acpi - device usb 2.4 off end - end - chip drivers/usb/acpi - device usb 2.5 off end - end - chip drivers/usb/acpi - device usb 2.6 off end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H19)" - device usb 2.7 on end + device ref usb2_port8 on end end chip drivers/usb/acpi register "desc" = ""Left Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""Left Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on end + device ref usb3_port4 on end end end end - end # USB xHCI - device pci 14.1 off end # USB xDCI (OTG) - device pci 14.2 alias shared_ram on end # PMC SRAM - device pci 14.3 on + end + device ref shared_ram on end + device ref cnvi_wifi on chip drivers/wifi/generic register "wake" = "GPE0_PME_B0" device generic 0 on end end - end # CNVi wifi - device pci 14.5 on end # SDCard - device pci 15.0 on end # I2C 0 - device pci 15.1 on end # I2C 1 - device pci 15.2 on end # I2C 2 - device pci 15.3 on end # I2C 3 - device pci 16.0 on end # HECI 1 - device pci 16.1 off end # HECI 2 - device pci 16.4 off end # HECI 3 - device pci 16.5 off end # HECI 4 - device pci 17.0 off end # SATA - device pci 19.0 on end # I2C 4 - device pci 19.1 off end # I2C 5 - device pci 19.2 on end # UART 2 - device pci 1a.0 on end # eMMC - device pci 1c.0 off end # PCI Express Root Port 1 - device pci 1c.1 off end # PCI Express Root Port 2 - device pci 1c.2 off end # PCI Express Root Port 3 - device pci 1c.3 off end # PCI Express Root Port 4 - device pci 1c.4 off end # PCI Express Root Port 5 - device pci 1c.5 off end # PCI Express Root Port 6 - device pci 1c.6 off end # PCI Express Root Port 7 - # External PCIe port 4 is mapped to PCIe Root port 8 - device pci 1c.7 on end # PCI Express Root Port 8 - hosts M.2 E-key WLAN - device pci 1e.0 off end # UART 0 - device pci 1e.1 off end # UART 1 - device pci 1e.2 on + end + device ref sdxc on end + device ref heci1 on end + device ref i2c4 on end + device ref uart2 on end + device ref emmc on end + device ref gspi0 on chip drivers/spi/acpi register "hid" = "ACPI_DT_NAMESPACE_HID" register "compat_string" = ""google,cr50"" register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_B4_IRQ)" device spi 0 on end end - end # GSPI 0 - device pci 1e.3 off end # GSPI 1 - device pci 1f.0 on + end + device ref pch_espi on chip ec/google/chromeec device pnp 0c09.0 on end end - end # eSPI Interface - device pci 1f.1 on end # P2SB - device pci 1f.2 hidden end # Power Management Controller - device pci 1f.3 on + end + device ref hda on chip drivers/sof register "spkr_tplg" = "rt1015" register "jack_tplg" = "rt5682" @@ -427,9 +388,6 @@ chip soc/intel/jasperlake probe AUDIO_AMP MAX98360 end end - end # Intel HDA/cAVS - device pci 1f.4 off end # SMBus - device pci 1f.5 on end # PCH SPI - device pci 1f.7 off end # Intel Trace Hub + end end end diff --git a/src/mainboard/google/dedede/variants/beadrix/overridetree.cb b/src/mainboard/google/dedede/variants/beadrix/overridetree.cb index c4e550c1720..6693a6e9c3b 100644 --- a/src/mainboard/google/dedede/variants/beadrix/overridetree.cb +++ b/src/mainboard/google/dedede/variants/beadrix/overridetree.cb @@ -54,17 +54,24 @@ chip soc/intel/jasperlake }, }" - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C5]" = "PchSerialIoPci" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on # Default DPTF Policy for all Dedede boards if not overridden chip drivers/intel/dptf register "options.tsr[0].desc" = ""Memory"" @@ -104,10 +111,10 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 05.0 off end # IPU - MIPI Camera - device pci 14.0 on + device ref ipu off end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" @@ -121,7 +128,7 @@ chip soc/intel/jasperlake register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.1 on + device ref usb3_port2 on probe DB_PORTS DB_PORTS_1C_LTE probe DB_PORTS DB_PORTS_1C end @@ -139,15 +146,15 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "20" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 3.3 on + device ref usb3_port4 on probe DB_PORTS DB_PORTS_1C_LTE probe DB_PORTS DB_PORTS_LTE end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""PIXA2635"" register "generic.desc" = ""PIXA Touchpad"" @@ -157,8 +164,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 15 on end end - end # I2C 0 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -186,8 +193,8 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end # I2C 4 - device pci 19.1 on + end + device ref i2c5 on chip drivers/i2c/sx9324 register "desc" = ""SAR Proximity Sensor"" register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E11_IRQ)" @@ -243,13 +250,13 @@ chip soc/intel/jasperlake probe DB_PORTS DB_PORTS_LTE end end - end # I2C 5 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/blipper/overridetree.cb b/src/mainboard/google/dedede/variants/blipper/overridetree.cb index 4b42f0e3aae..1e510536a4a 100644 --- a/src/mainboard/google/dedede/variants/blipper/overridetree.cb +++ b/src/mainboard/google/dedede/variants/blipper/overridetree.cb @@ -50,14 +50,9 @@ chip soc/intel/jasperlake register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # UF Camera register "usb2_ports[6]" = "USB2_PORT_EMPTY" # Not Used - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" register "tcc_offset" = "10" # TCC of 95C @@ -68,7 +63,18 @@ chip soc/intel/jasperlake register "FastPkgCRampDisable" = "1" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -94,19 +100,19 @@ chip soc/intel/jasperlake .granularity = 1000,}" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""UFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -125,9 +131,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""GTCH7503"" register "generic.desc" = ""G2 Touchscreen"" @@ -163,9 +168,8 @@ chip soc/intel/jasperlake register "has_power_resource" = "true" device i2c 10 on end end - end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -193,12 +197,12 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end # I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/boten/overridetree.cb b/src/mainboard/google/dedede/variants/boten/overridetree.cb index 3e0e7b32fc9..aa54ba3059c 100644 --- a/src/mainboard/google/dedede/variants/boten/overridetree.cb +++ b/src/mainboard/google/dedede/variants/boten/overridetree.cb @@ -73,14 +73,11 @@ chip soc/intel/jasperlake register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # UF Camera register "usb2_ports[6]" = "USB2_PORT_MID(OC_SKIP)" # WF Camera - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoPci, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C5]" = "PchSerialIoPci" # Enable Acoustic noise mitigation and set slew rate to 1/8 # Rest of the parameters are 0 by default. @@ -92,7 +89,18 @@ chip soc/intel/jasperlake register "xhci_lfps_sampling_offtime_ms" = "0" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -139,17 +147,17 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""LTE"" @@ -159,33 +167,33 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "10" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 2.3 alias usb2_lte on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""UFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""WFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.3 on end + device ref usb3_port4 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -204,8 +212,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -257,9 +265,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 10 on end end - end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -305,8 +312,8 @@ chip soc/intel/jasperlake probe AUDIO_AMP UNPROVISIONED end end - end # I2C 4 - device pci 19.1 on + end + device ref i2c5 on chip drivers/i2c/sx9324 register "desc" = ""SAR Proximity Sensor"" register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E11_IRQ)" @@ -359,14 +366,14 @@ chip soc/intel/jasperlake register "reg_irq_cfg2" = "0x00" device i2c 28 on end end - end # I2C 5 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on probe AUDIO_AMP RT1015P_AUTO end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/boxy/overridetree.cb b/src/mainboard/google/dedede/variants/boxy/overridetree.cb index 36eadcbd1f2..f3fb01df4b2 100644 --- a/src/mainboard/google/dedede/variants/boxy/overridetree.cb +++ b/src/mainboard/google/dedede/variants/boxy/overridetree.cb @@ -33,6 +33,8 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 6, @@ -88,7 +90,7 @@ chip soc/intel/jasperlake USB_PORT_WAKE_ENABLE(4)" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -137,66 +139,62 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A0"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A1"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C1"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C1"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A0"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A1"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.3 on end + device ref usb3_port4 on end end end end - end # USB xHCI - device pci 15.0 off end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -223,8 +221,8 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end # I2C 4 - device pci 1c.2 on + end + device ref pcie_rp3 on chip drivers/net register "customized_leds" = "0x07af" register "wake" = "GPE0_DW0_03" # GPP_B3 @@ -232,14 +230,13 @@ chip soc/intel/jasperlake register "device_index" = "0" device pci 00.0 on end end - end # PCI Express Root Port 3 - RTL8111H LAN - device pci 1c.6 on + end + device ref pcie_rp7 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 7 - WLAN - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1f.3 on end # Intel HDA + end + device ref hda on end end end diff --git a/src/mainboard/google/dedede/variants/bugzzy/overridetree.cb b/src/mainboard/google/dedede/variants/bugzzy/overridetree.cb index 6c399f87689..64e3214567b 100644 --- a/src/mainboard/google/dedede/variants/bugzzy/overridetree.cb +++ b/src/mainboard/google/dedede/variants/bugzzy/overridetree.cb @@ -86,8 +86,30 @@ chip soc/intel/jasperlake .fall_time_ns = 8, }, }" + + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "2" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + # IPUA for IPUs + register "device[1].name" = ""IPUA"" + register "device[1].non_vga_device" = "true" + register "device[1].addr" = "0x3480" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf register "options.tsr[0].desc" = ""Memory"" register "options.tsr[1].desc" = ""CPU"" @@ -131,8 +153,8 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 05.0 on # IPU - MIPI Camera + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -146,16 +168,16 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""UFCamera"" register "type" = "UPC_TYPE_INTERNAL" register "has_power_resource" = "true" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D13)" register "enable_delay_ms" = "20" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""LTE"" @@ -165,14 +187,14 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "20" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 3.3 on + device ref usb3_port4 on probe DB_PORTS DB_PORTS_1C_1A_LTE end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -190,8 +212,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0xE" device i2c 40 on end end - end # I2C 0 - device pci 15.1 on + end + device ref i2c1 on chip drivers/i2c/hid register "generic.hid" = ""WCOM014B"" register "generic.desc" = ""WCOM Digitizer"" @@ -215,8 +237,8 @@ chip soc/intel/jasperlake probe DB_PORTS DB_PORTS_1C_1A_LTE end end - end # I2C #1 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""HX121A"" register "generic.desc" = ""HX Touchscreen"" @@ -229,23 +251,22 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x1" device i2c 0x4F on end end - end # I2C #2 - device pci 15.3 on + end + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI8856"" register "acpi_uid" = "0" register "acpi_name" = ""CAM1"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_JSL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" register "vcm_name" = ""VCM0"" - register "ssdb.rom_type" = "ROM_EEPROM_CAT24C08" - register "rom_address" = "0x50" register "num_freq_entries" = "2" register "link_freq[0]" = "360000000" register "link_freq[1]" = "180000000" @@ -303,9 +324,8 @@ chip soc/intel/jasperlake device i2c 50 on end end - end # I2C 3 - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/da7219 register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_D16)" register "btn_cfg" = "50" @@ -323,13 +343,13 @@ chip soc/intel/jasperlake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end #I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/cappy2/overridetree.cb b/src/mainboard/google/dedede/variants/cappy2/overridetree.cb index e4e39f331d5..372fe482e8b 100644 --- a/src/mainboard/google/dedede/variants/cappy2/overridetree.cb +++ b/src/mainboard/google/dedede/variants/cappy2/overridetree.cb @@ -41,6 +41,12 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "disable_external_bypass_vr" = "1" # Does not support external vnn power rail register "tcc_offset" = "10" # TCC of 95C @@ -71,7 +77,18 @@ chip soc/intel/jasperlake }" # Camera device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -106,22 +123,22 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""UFCamera"" register "type" = "UPC_TYPE_INTERNAL" register "has_power_resource" = "true" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D15)" register "enable_delay_ms" = "20" - device usb 2.5 on end + device ref usb2_port6 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""SYNA0A00"" register "generic.desc" = ""SYNA Touchpad"" @@ -166,8 +183,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -213,13 +230,13 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_CS42l42 end end - end #I2C 4 - device pci 1f.0 on + end + device ref pch_espi on chip drivers/pc80/tpm device pnp 0c31.0 on end # Discrete TPM - end # chip drivers/pc80/tpm - end # PCH eSPI - device pci 1f.3 on + end + end + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on @@ -233,6 +250,6 @@ chip soc/intel/jasperlake probe AUDIO_AMP MAX98360 end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/corori/overridetree.cb b/src/mainboard/google/dedede/variants/corori/overridetree.cb index ed4a0976a11..c1a3cb0f724 100644 --- a/src/mainboard/google/dedede/variants/corori/overridetree.cb +++ b/src/mainboard/google/dedede/variants/corori/overridetree.cb @@ -17,14 +17,7 @@ chip soc/intel/jasperlake register "usb3_ports[1]" = "USB3_PORT_EMPTY" # None register "usb3_ports[3]" = "USB3_PORT_EMPTY" # None - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoDisabled, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" # Intel Common SoC Config #+-------------------+---------------------------+ @@ -51,7 +44,18 @@ chip soc/intel/jasperlake register "SerialIoGSpiCsMode[PchSerialIoIndexGSPI0]" = "0" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -86,31 +90,19 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on - chip drivers/usb/acpi - device usb 2.1 off end - end - chip drivers/usb/acpi - device usb 2.3 off end - end + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Camera (UFC)"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end - end - chip drivers/usb/acpi - device usb 3.1 off end - end - chip drivers/usb/acpi - device usb 3.3 off end + device ref usb2_port6 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -119,11 +111,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -153,19 +142,18 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end #I2C 4 - device pci 1e.2 off end # GSPI 0 - device pci 1f.0 on + end + device ref pch_espi on chip drivers/pc80/tpm device pnp 0c31.0 on end # Discrete TPM end # chip drivers/pc80/tpm - end # PCH eSPI - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/cret/overridetree.cb b/src/mainboard/google/dedede/variants/cret/overridetree.cb index 1c834f411d7..726328c2ef4 100644 --- a/src/mainboard/google/dedede/variants/cret/overridetree.cb +++ b/src/mainboard/google/dedede/variants/cret/overridetree.cb @@ -18,14 +18,9 @@ chip soc/intel/jasperlake register "usb3_ports[1]" = "USB3_PORT_EMPTY" # None register "usb3_ports[3]" = "USB3_PORT_DEFAULT(OC_SKIP)" # LTE - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # Intel Common SoC Config #+-------------------+---------------------------+ @@ -57,7 +52,18 @@ chip soc/intel/jasperlake }, }" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -92,32 +98,26 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on - chip drivers/usb/acpi - device usb 2.1 off end - end + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.3 on + device ref usb2_port4 on probe LTE LTE_PRESENT end end chip drivers/usb/acpi register "desc" = ""Camera (UFC)"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""Camera (WFC)"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.6 on end - end - chip drivers/usb/acpi - device usb 3.1 off end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""LTE"" @@ -129,14 +129,14 @@ chip soc/intel/jasperlake register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 3.3 on + device ref usb3_port4 on probe LTE LTE_PRESENT end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -154,9 +154,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 2c on end end - end #I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""WDHT0002"" register "generic.desc" = ""WDT Touchscreen"" @@ -245,10 +244,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 1c.7 on end - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/da7219 register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_D16)" register "btn_cfg" = "50" @@ -287,13 +284,13 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_CS42l42 end end - end #I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/dexi/overridetree.cb b/src/mainboard/google/dedede/variants/dexi/overridetree.cb index f53a11a89e4..54910d5f4cf 100644 --- a/src/mainboard/google/dedede/variants/dexi/overridetree.cb +++ b/src/mainboard/google/dedede/variants/dexi/overridetree.cb @@ -25,6 +25,8 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 6, @@ -133,7 +135,7 @@ chip soc/intel/jasperlake USB_PORT_WAKE_ENABLE(6)" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -182,90 +184,86 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A0"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A1"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A2"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A3"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A4"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A4"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A0"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A1"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A3"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.4 on end + device ref usb3_port5 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A2"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 3.5 on end + device ref usb3_port6 on end end end end - end # USB xHCI - device pci 15.0 off end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""RTL5682"" register "name" = ""RT58"" @@ -277,8 +275,8 @@ chip soc/intel/jasperlake register "property_list[0].integer" = "1" device i2c 1a on end end - end # I2C 4 - device pci 1c.2 on + end + device ref pcie_rp3 on chip drivers/net register "customized_leds" = "0x05af" register "wake" = "GPE0_DW0_03" # GPP_B3 @@ -286,14 +284,13 @@ chip soc/intel/jasperlake register "device_index" = "0" device pci 00.0 on end end - end # PCI Express Root Port 3 - RTL8111H LAN - device pci 1c.6 on + end + device ref pcie_rp7 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 7 - WLAN - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1f.3 on end # Intel HDA + end + device ref hda on end end end diff --git a/src/mainboard/google/dedede/variants/dibbi/overridetree.cb b/src/mainboard/google/dedede/variants/dibbi/overridetree.cb index c7d6afb495a..1c6ee0706e1 100644 --- a/src/mainboard/google/dedede/variants/dibbi/overridetree.cb +++ b/src/mainboard/google/dedede/variants/dibbi/overridetree.cb @@ -25,6 +25,8 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 6, @@ -109,7 +111,7 @@ chip soc/intel/jasperlake register "usb3_ports[5]" = "USB3_PORT_DEFAULT(OC_SKIP)" # USB3/1 Type-A Port A3 device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -158,81 +160,74 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A0"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A1"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A2"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 4)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A3"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 5)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.0 on end - end - chip drivers/usb/acpi - device usb 3.1 off end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A0"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A1"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A3"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 5)" - device usb 3.4 on end + device ref usb3_port5 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A2"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 4)" - device usb 3.5 on end + device ref usb3_port6 on end end end end - end # USB xHCI - device pci 15.0 off end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""RTL5682"" register "name" = ""RT58"" @@ -244,8 +239,8 @@ chip soc/intel/jasperlake register "property_list[0].integer" = "1" device i2c 1a on end end - end # I2C 4 - device pci 1c.2 on + end + device ref pcie_rp3 on chip drivers/net register "customized_leds" = "0x05af" register "wake" = "GPE0_DW0_03" # GPP_B3 @@ -253,14 +248,13 @@ chip soc/intel/jasperlake register "device_index" = "0" device pci 00.0 on end end - end # PCI Express Root Port 3 - RTL8111H LAN - device pci 1c.6 on + end + device ref pcie_rp7 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 7 - WLAN - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1f.3 on end # Intel HDA + end + device ref hda on end end end diff --git a/src/mainboard/google/dedede/variants/dita/overridetree.cb b/src/mainboard/google/dedede/variants/dita/overridetree.cb index f53a11a89e4..54910d5f4cf 100644 --- a/src/mainboard/google/dedede/variants/dita/overridetree.cb +++ b/src/mainboard/google/dedede/variants/dita/overridetree.cb @@ -25,6 +25,8 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 6, @@ -133,7 +135,7 @@ chip soc/intel/jasperlake USB_PORT_WAKE_ENABLE(6)" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -182,90 +184,86 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A0"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A1"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A2"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A3"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A4"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A4"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A0"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A1"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A3"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.4 on end + device ref usb3_port5 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A2"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 3.5 on end + device ref usb3_port6 on end end end end - end # USB xHCI - device pci 15.0 off end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""RTL5682"" register "name" = ""RT58"" @@ -277,8 +275,8 @@ chip soc/intel/jasperlake register "property_list[0].integer" = "1" device i2c 1a on end end - end # I2C 4 - device pci 1c.2 on + end + device ref pcie_rp3 on chip drivers/net register "customized_leds" = "0x05af" register "wake" = "GPE0_DW0_03" # GPP_B3 @@ -286,14 +284,13 @@ chip soc/intel/jasperlake register "device_index" = "0" device pci 00.0 on end end - end # PCI Express Root Port 3 - RTL8111H LAN - device pci 1c.6 on + end + device ref pcie_rp7 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 7 - WLAN - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1f.3 on end # Intel HDA + end + device ref hda on end end end diff --git a/src/mainboard/google/dedede/variants/drawcia/overridetree.cb b/src/mainboard/google/dedede/variants/drawcia/overridetree.cb index c84f9487fe5..1900e7e4cbf 100644 --- a/src/mainboard/google/dedede/variants/drawcia/overridetree.cb +++ b/src/mainboard/google/dedede/variants/drawcia/overridetree.cb @@ -67,6 +67,12 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "tcc_offset" = "20" # TCC of 85C # Enable Acoustic noise mitigation and set slew rate to 1/4 @@ -76,7 +82,22 @@ chip soc/intel/jasperlake register "FastPkgCRampDisable" = "1" device domain 0 on - device pci 05.0 on # IPU - MIPI Camera + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "2" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + # IPUA for IPUs + register "device[1].name" = ""IPUA"" + register "device[1].non_vga_device" = "true" + register "device[1].addr" = "0x3480" + + device generic 0 on end + end + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -91,7 +112,7 @@ chip soc/intel/jasperlake end end - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf # Default DPTF Policy for all drawcia boards if not overridden register "options.tsr[0].desc" = ""Memory"" @@ -144,10 +165,10 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" @@ -157,7 +178,7 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "20" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 2.3 alias lte_usb2 on + device ref usb2_port4 on probe DB_PORTS DB_PORTS_1A_HDMI_LTE end end @@ -165,7 +186,7 @@ chip soc/intel/jasperlake register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.3 on + device ref usb2_port4 on probe DB_PORTS DB_PORTS_1A_HDMI probe DB_PORTS DB_PORTS_1C_1A end @@ -173,13 +194,13 @@ chip soc/intel/jasperlake chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on + device ref usb3_port4 on probe DB_PORTS DB_PORTS_1A_HDMI_LTE end end @@ -187,15 +208,15 @@ chip soc/intel/jasperlake register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on + device ref usb3_port4 on probe DB_PORTS DB_PORTS_1A_HDMI probe DB_PORTS DB_PORTS_1C_1A end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -214,8 +235,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end #I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -290,23 +311,22 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 2c alias wdht0002 on end end - end # I2C 2 - device pci 15.3 on + end + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI8856"" register "acpi_uid" = "0" register "acpi_name" = ""CAM1"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_JSL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" register "vcm_name" = ""VCM0"" - register "ssdb.rom_type" = "ROM_EEPROM_CAT24C08" - register "rom_address" = "0x50" register "num_freq_entries" = "2" register "link_freq[0]" = "360000000" register "link_freq[1]" = "180000000" @@ -389,8 +409,8 @@ chip soc/intel/jasperlake register "off_seq.ops[0]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" device i2c 50 on end end - end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -420,19 +440,19 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end #I2C 4 - device pci 1c.7 on + end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end end - device pci 1f.3 on + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/drawcia/ramstage.c b/src/mainboard/google/dedede/variants/drawcia/ramstage.c index be1b2532191..543d7457a8d 100644 --- a/src/mainboard/google/dedede/variants/drawcia/ramstage.c +++ b/src/mainboard/google/dedede/variants/drawcia/ramstage.c @@ -18,7 +18,7 @@ static void ext_vr_update(void) static void update_lte_device_drawcia(void) { - struct device *lte_usb2 = DEV_PTR(lte_usb2); + struct device *lte_usb2 = DEV_PTR(usb2_port4); struct drivers_usb_acpi_config *config; struct acpi_gpio lte_reset_gpio = ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H0); diff --git a/src/mainboard/google/dedede/variants/driblee/overridetree.cb b/src/mainboard/google/dedede/variants/driblee/overridetree.cb index 3c9c92c98e8..97614fa5b2a 100644 --- a/src/mainboard/google/dedede/variants/driblee/overridetree.cb +++ b/src/mainboard/google/dedede/variants/driblee/overridetree.cb @@ -9,14 +9,8 @@ chip soc/intel/jasperlake register "usb3_ports[1]" = "USB3_PORT_EMPTY" # None register "usb3_ports[3]" = "USB3_PORT_EMPTY" # None - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoDisabled, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # Intel Common SoC Config #+-------------------+---------------------------+ @@ -41,7 +35,18 @@ chip soc/intel/jasperlake register "SerialIoGSpiCsMode[PchSerialIoIndexGSPI0]" = "0" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -76,31 +81,19 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on - chip drivers/usb/acpi - device usb 2.1 off end - end - chip drivers/usb/acpi - device usb 2.3 off end - end + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Camera (UFC)"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end - end - chip drivers/usb/acpi - device usb 3.1 off end - end - chip drivers/usb/acpi - device usb 3.3 off end + device ref usb2_port6 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -118,11 +111,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 2c on end end - end #I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/cs42l42 register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_D16)" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_H16)" @@ -139,19 +129,18 @@ chip soc/intel/jasperlake register "hs_bias_sense_disable" = "true" device i2c 48 on end end - end #I2C 4 - device pci 1e.2 off end # GSPI 0 - device pci 1f.0 on + end + device ref pch_espi on chip drivers/pc80/tpm device pnp 0c31.0 on end # Discrete TPM - end # chip drivers/pc80/tpm - end # PCH eSPI - device pci 1f.3 on + end + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/galtic/overridetree.cb b/src/mainboard/google/dedede/variants/galtic/overridetree.cb index 0ef9cdb5da6..0ccfbfa5195 100644 --- a/src/mainboard/google/dedede/variants/galtic/overridetree.cb +++ b/src/mainboard/google/dedede/variants/galtic/overridetree.cb @@ -9,6 +9,11 @@ fw_config option AUDIO_CODEC_ALC5682 1 option AUDIO_CODEC_ALC5682I_VS 2 end + field TOUCHPAD_SOURCE 62 63 + option TOUCHPAD_UNPROVISIONED 0 + option TOUCHPAD_ELAN0000 1 + option TOUCHPAD_ELAN2702 2 + end end chip soc/intel/jasperlake @@ -59,13 +64,9 @@ chip soc/intel/jasperlake }, }" - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # USB Port Configuration register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # Camera @@ -73,7 +74,18 @@ chip soc/intel/jasperlake register "tcc_offset" = "8" # TCC of 97C device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on # Default DPTF Policy for all Dedede boards if not overridden chip drivers/intel/dptf ## Passive Policy @@ -124,37 +136,45 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end end end - end # USB xHCI + end - device pci 15.0 on + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" register "irq" = "ACPI_IRQ_WAKE_EDGE_LOW(GPP_B3_IRQ)" register "wake" = "GPE0_DW0_03" - device i2c 15 alias elan0000 on end + register "detect" = "1" + device i2c 15 on + probe TOUCHPAD_SOURCE TOUCHPAD_UNPROVISIONED + probe TOUCHPAD_SOURCE TOUCHPAD_ELAN0000 + end end chip drivers/i2c/hid register "generic.hid" = ""ELAN2702"" register "generic.desc" = ""ELAN Touchpad"" register "generic.irq" = "ACPI_IRQ_WAKE_LEVEL_LOW(GPP_B3_IRQ)" register "generic.wake" = "GPE0_DW0_03" + register "generic.detect" = "1" register "hid_desc_reg_offset" = "0x01" - device i2c 15 alias elan2702 on end + device i2c 15 on + probe TOUCHPAD_SOURCE TOUCHPAD_UNPROVISIONED + probe TOUCHPAD_SOURCE TOUCHPAD_ELAN2702 + end end end - device pci 15.2 on + device ref i2c2 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -187,8 +207,8 @@ chip soc/intel/jasperlake probe TOUCHSCREEN_SOURCE TOUCHSCREEN_ELAN9008 end end - end # I2C 2 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -235,13 +255,13 @@ chip soc/intel/jasperlake end end end - device pci 1f.3 on + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on probe AUDIO_AMP RT1015P_AUTO end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/galtic/variant.c b/src/mainboard/google/dedede/variants/galtic/variant.c index a3f91896c0a..1e62f0c1876 100644 --- a/src/mainboard/google/dedede/variants/galtic/variant.c +++ b/src/mainboard/google/dedede/variants/galtic/variant.c @@ -1,12 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include -#include #include #include -#include #include -#include enum { GALTIC_SKU_START = 0x120000, @@ -41,23 +37,3 @@ const char *get_wifi_sar_cbfs_filename(void) return WIFI_SAR_CBFS_DEFAULT_FILENAME; } - -#define TP_TYPE_AUTO_SELECT 0 -#define TP_TYPE_ELAN0000 1 -#define TP_TYPE_ELAN2702 2 - -void variant_devtree_update(void) -{ - struct device *tp_elan0000 = DEV_PTR(elan0000); - struct device *tp_elan2702 = DEV_PTR(elan2702); - - /* Update touchpad device */ - switch (get_uint_option("touchpad", TP_TYPE_AUTO_SELECT)) { - case TP_TYPE_ELAN0000: - tp_elan2702->enabled = 0; - break; - case TP_TYPE_ELAN2702: - tp_elan0000->enabled = 0; - break; - } -} diff --git a/src/mainboard/google/dedede/variants/gooey/overridetree.cb b/src/mainboard/google/dedede/variants/gooey/overridetree.cb index 728ab919e1c..05144d1ff4e 100644 --- a/src/mainboard/google/dedede/variants/gooey/overridetree.cb +++ b/src/mainboard/google/dedede/variants/gooey/overridetree.cb @@ -49,14 +49,11 @@ chip soc/intel/jasperlake register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # UF Camera register "usb2_ports[6]" = "USB2_PORT_MID(OC_SKIP)" # WF Camera - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoPci, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C5]" = "PchSerialIoPci" register "SerialIoGSpiMode[PchSerialIoIndexGSPI0]" = "PchSerialIoDisabled" # Disable GSPI0 register "SerialIoGSpiCsMode[PchSerialIoIndexGSPI0]" = "0" @@ -71,7 +68,18 @@ chip soc/intel/jasperlake register "xhci_lfps_sampling_offtime_ms" = "0" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -118,17 +126,17 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""LTE"" @@ -138,33 +146,33 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "10" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""UFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""WFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.3 on end + device ref usb3_port4 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -183,8 +191,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -236,9 +244,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 10 on end end - end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -284,8 +291,8 @@ chip soc/intel/jasperlake probe AUDIO_AMP UNPROVISIONED end end - end # I2C 4 - device pci 19.1 on + end + device ref i2c5 on chip drivers/i2c/sx9324 register "desc" = ""SAR Proximity Sensor"" register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E11_IRQ)" @@ -339,19 +346,18 @@ chip soc/intel/jasperlake device i2c 28 on end end end # I2C 5 - device pci 1f.0 on + device ref pch_espi on chip drivers/pc80/tpm device pnp 0c31.0 on end # Discrete TPM - end # chip drivers/pc80/tpm - end # PCH eSPI - device pci 1e.2 off end # GSPI 0 - device pci 1f.3 on + end + end + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on probe AUDIO_AMP RT1015P_AUTO end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/haboki/overridetree.cb b/src/mainboard/google/dedede/variants/haboki/overridetree.cb index 92b3bb2c480..7377f904c27 100644 --- a/src/mainboard/google/dedede/variants/haboki/overridetree.cb +++ b/src/mainboard/google/dedede/variants/haboki/overridetree.cb @@ -35,6 +35,12 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "tcc_offset" = "20" # TCC of 85C register "SerialIoGSpiMode[PchSerialIoIndexGSPI0]" = "PchSerialIoDisabled" # Disable GSPI0 @@ -47,7 +53,22 @@ chip soc/intel/jasperlake register "FastPkgCRampDisable" = "1" device domain 0 on - device pci 05.0 on # IPU - MIPI Camera + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "2" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + # IPUA for IPUs + register "device[1].name" = ""IPUA"" + register "device[1].non_vga_device" = "true" + register "device[1].addr" = "0x3480" + + device generic 0 on end + end + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -62,7 +83,7 @@ chip soc/intel/jasperlake end end - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf # Default DPTF Policy for all drawcia boards if not overridden register "options.tsr[0].desc" = ""Memory"" @@ -116,7 +137,7 @@ chip soc/intel/jasperlake device generic 0 on end end end # SA Thermal device - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi device usb 0.0 on chip drivers/usb/acpi @@ -126,8 +147,8 @@ chip soc/intel/jasperlake end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -136,8 +157,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -204,23 +225,22 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 15 on end end - end # I2C 2 - device pci 15.3 on + end + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI8856"" register "acpi_uid" = "0" register "acpi_name" = ""CAM1"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_JSL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" register "vcm_name" = ""VCM0"" - register "ssdb.rom_type" = "ROM_EEPROM_CAT24C08" - register "rom_address" = "0x50" register "num_freq_entries" = "2" register "link_freq[0]" = "360000000" register "link_freq[1]" = "180000000" @@ -278,8 +298,8 @@ chip soc/intel/jasperlake device i2c 50 on end end - end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -292,19 +312,18 @@ chip soc/intel/jasperlake register "property_list[0].integer" = "1" device i2c 1a on end end - end #I2C 4 - device pci 1f.0 on + end + device ref pch_espi on chip drivers/pc80/tpm device pnp 0c31.0 on end # Discrete TPM - end # chip drivers/pc80/tpm - end # PCH eSPI - device pci 1e.2 off end # GSPI 0 - device pci 1f.3 on + end + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/kracko/overridetree.cb b/src/mainboard/google/dedede/variants/kracko/overridetree.cb index e4d9ad966e0..89d3a7ea963 100644 --- a/src/mainboard/google/dedede/variants/kracko/overridetree.cb +++ b/src/mainboard/google/dedede/variants/kracko/overridetree.cb @@ -11,14 +11,11 @@ chip soc/intel/jasperlake register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # Camera register "usb2_ports[6]" = "USB2_PORT_MID(OC_SKIP)" # WF Camera - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoPci, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C5]" = "PchSerialIoPci" # Intel Common SoC Config #+-------------------+---------------------------+ @@ -68,7 +65,18 @@ chip soc/intel/jasperlake register "tcc_offset" = "20" # TCC of 85C device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf # Default DPTF Policy for all drawcia boards if not overridden register "options.tsr[0].desc" = ""Memory"" @@ -116,10 +124,10 @@ chip soc/intel/jasperlake }" device generic 0 alias dptf_policy on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" @@ -129,7 +137,7 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "20" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 2.3 on + device ref usb2_port4 on probe DB_PORTS DB_PORTS_1C_LTE probe DB_PORTS DB_PORTS_LTE end @@ -138,7 +146,7 @@ chip soc/intel/jasperlake register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.1 on + device ref usb2_port2 on probe DB_PORTS DB_PORTS_1C_1A probe DB_PORTS DB_PORTS_1C_LTE end @@ -147,25 +155,25 @@ chip soc/intel/jasperlake register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.3 on + device ref usb2_port4 on probe DB_PORTS DB_PORTS_1C_1A end end chip drivers/usb/acpi register "desc" = ""UFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""WFCamera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.1 on + device ref usb3_port2 on probe DB_PORTS DB_PORTS_1C_1A probe DB_PORTS DB_PORTS_1C_LTE end @@ -174,7 +182,7 @@ chip soc/intel/jasperlake register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on + device ref usb3_port4 on probe DB_PORTS DB_PORTS_1C_LTE probe DB_PORTS DB_PORTS_LTE end @@ -183,14 +191,14 @@ chip soc/intel/jasperlake register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on + device ref usb3_port4 on probe DB_PORTS DB_PORTS_1C_1A end end end end end # USB xHCI - device pci 15.0 on + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -199,8 +207,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -243,9 +251,8 @@ chip soc/intel/jasperlake device i2c 40 on end end - end # I2C 2 - device pci 15.3 off end #I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -274,8 +281,8 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end #I2C 4 - device pci 19.1 on + end + device ref i2c5 on chip drivers/i2c/sx9324 register "desc" = ""SAR Proximity Sensor"" register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E11_IRQ)" @@ -328,12 +335,12 @@ chip soc/intel/jasperlake device i2c 28 on end end end # I2C 5 - device pci 1f.3 on + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/lalala/overridetree.cb b/src/mainboard/google/dedede/variants/lalala/overridetree.cb index 9609011a0c6..e703d5e7992 100644 --- a/src/mainboard/google/dedede/variants/lalala/overridetree.cb +++ b/src/mainboard/google/dedede/variants/lalala/overridetree.cb @@ -56,6 +56,12 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 7, @@ -81,7 +87,22 @@ chip soc/intel/jasperlake register "FastPkgCRampDisable" = "1" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "2" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + # IPUA for IPUs + register "device[1].name" = ""IPUA"" + register "device[1].non_vga_device" = "true" + register "device[1].addr" = "0x3480" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf register "options.tsr[0].desc" = ""Memory"" register "options.tsr[1].desc" = ""Ambient"" @@ -115,8 +136,8 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 05.0 on # IPU - MIPI Camera + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -129,18 +150,18 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""SYNA0000"" register "generic.cid" = ""ACPI0C50"" @@ -159,8 +180,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end # I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""ELAN6915"" register "generic.desc" = ""ELAN Touchscreen"" @@ -203,22 +224,21 @@ chip soc/intel/jasperlake device i2c 39 on end end end # I2C 2 - device pci 15.3 on # I2C 3 + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI5675"" register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 5675 Camera"" + register "sensor_name" = ""CJFLE39"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_JSL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" register "vcm_name" = ""VCM0"" - register "ssdb.rom_type" = "ROM_EEPROM_CAT24C08" - register "rom_address" = "0x50" register "num_freq_entries" = "1" register "link_freq[0]" = "DEFAULT_LINK_FREQ" register "remote_name" = ""IPU0"" @@ -279,7 +299,7 @@ chip soc/intel/jasperlake device i2c 50 on end end end - device pci 19.0 on + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -304,14 +324,13 @@ chip soc/intel/jasperlake device i2c 29 on end end end - device pci 1f.0 on + device ref pch_espi on chip drivers/pc80/tpm device pnp 0c31.0 on end # Discrete TPM end # chip drivers/pc80/tpm - end # PCH eSPI - device pci 1e.2 off end # GSPI 0 - device pci 1f.3 on end # Intel HDA - device pci 1c.7 on + end + device ref hda on end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end diff --git a/src/mainboard/google/dedede/variants/lantis/overridetree.cb b/src/mainboard/google/dedede/variants/lantis/overridetree.cb index 5f6ed2368b9..91590869451 100644 --- a/src/mainboard/google/dedede/variants/lantis/overridetree.cb +++ b/src/mainboard/google/dedede/variants/lantis/overridetree.cb @@ -15,14 +15,9 @@ chip soc/intel/jasperlake # USB Port Configuration register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # Camera - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # Intel Common SoC Config #+-------------------+---------------------------+ @@ -95,7 +90,18 @@ chip soc/intel/jasperlake register "FastPkgCRampDisable" = "1" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf register "options.tsr[0].desc" = ""Memory"" register "options.tsr[1].desc" = ""Ambient"" @@ -146,31 +152,31 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Discrete Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H19)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""Integrated Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H19)" - device usb 2.7 on end + device ref usb2_port8 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -179,9 +185,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 15.1 off end #I2C 1 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -239,15 +244,14 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 0x5d on end end - end # I2C 2 - device pci 15.3 off end #I2C 3 - device pci 1c.7 on + end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -275,13 +279,13 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end #I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/madoo/overridetree.cb b/src/mainboard/google/dedede/variants/madoo/overridetree.cb index 437c60a5cd4..dea54bdc0ed 100644 --- a/src/mainboard/google/dedede/variants/madoo/overridetree.cb +++ b/src/mainboard/google/dedede/variants/madoo/overridetree.cb @@ -3,14 +3,9 @@ chip soc/intel/jasperlake # USB Port Configuration register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # Camera - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # Intel Common SoC Config #+-------------------+---------------------------+ @@ -62,7 +57,18 @@ chip soc/intel/jasperlake register "SlowSlewRate" = "2" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf register "policies.passive" = "{ [0] = DPTF_PASSIVE(CPU, CPU, 65, 1000), @@ -86,25 +92,19 @@ chip soc/intel/jasperlake .granularity = 1000,}" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on - chip drivers/usb/acpi - device usb 2.2 off end - end + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end - end - chip drivers/usb/acpi - device usb 3.2 off end + device ref usb2_port6 on end end end end end # USB xHCI - device pci 15.0 on + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -113,9 +113,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""GDIX0000"" register "generic.desc" = ""Goodix Touchscreen"" @@ -131,15 +130,14 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 0x5d on end end - end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 1c.7 on + end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -152,13 +150,13 @@ chip soc/intel/jasperlake register "property_list[0].integer" = "1" device i2c 1a on end end - end #I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/magolor/overridetree.cb b/src/mainboard/google/dedede/variants/magolor/overridetree.cb index a09adeeff27..baf24b9436d 100644 --- a/src/mainboard/google/dedede/variants/magolor/overridetree.cb +++ b/src/mainboard/google/dedede/variants/magolor/overridetree.cb @@ -95,6 +95,12 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 7, @@ -120,7 +126,22 @@ chip soc/intel/jasperlake register "FastPkgCRampDisable" = "1" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "2" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + # IPUA for IPUs + register "device[1].name" = ""IPUA"" + register "device[1].non_vga_device" = "true" + register "device[1].addr" = "0x3480" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf register "options.tsr[0].desc" = ""Memory"" register "options.tsr[1].desc" = ""Ambient"" @@ -154,8 +175,8 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 05.0 on # IPU - MIPI Camera + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -168,7 +189,7 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi device usb 0.0 on chip drivers/usb/acpi @@ -178,8 +199,8 @@ chip soc/intel/jasperlake end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""SYNA0000"" register "generic.cid" = ""ACPI0C50"" @@ -198,8 +219,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end # I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -336,17 +357,18 @@ chip soc/intel/jasperlake probe TS_SOURCE TS_RAYD_0001 end end - end # I2C 2 - device pci 15.3 on # I2C 3 + end + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI5675"" register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 5675 Camera"" + register "sensor_name" = ""CJFLE39"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_JSL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" @@ -389,16 +411,15 @@ chip soc/intel/jasperlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_JSL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" register "vcm_name" = ""VCM0"" - register "ssdb.rom_type" = "ROM_EEPROM_CAT24C08" - register "rom_address" = "0x50" register "num_freq_entries" = "2" register "link_freq[0]" = "720000000" register "link_freq[1]" = "360000000" @@ -464,7 +485,7 @@ chip soc/intel/jasperlake device i2c 50 on end end end - device pci 19.0 on + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -530,19 +551,19 @@ chip soc/intel/jasperlake end end end - device pci 1f.3 on + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on probe AUDIO_AMP RT1015P_AUTO end end - end # Intel HDA - device pci 1c.7 on + end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN + end end end diff --git a/src/mainboard/google/dedede/variants/metaknight/overridetree.cb b/src/mainboard/google/dedede/variants/metaknight/overridetree.cb index d50fb7c59de..cafdaa1ff15 100644 --- a/src/mainboard/google/dedede/variants/metaknight/overridetree.cb +++ b/src/mainboard/google/dedede/variants/metaknight/overridetree.cb @@ -62,14 +62,10 @@ chip soc/intel/jasperlake }, }" - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoPci, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoDisabled, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ @@ -88,7 +84,18 @@ chip soc/intel/jasperlake }" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf register "options.tsr[0].desc" = ""Memory"" register "options.tsr[1].desc" = ""CPU"" @@ -122,10 +129,10 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""LTE"" register "type" = "UPC_TYPE_INTERNAL" @@ -175,8 +182,8 @@ chip soc/intel/jasperlake end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""SYNA0000"" register "generic.cid" = ""ACPI0C50"" @@ -195,8 +202,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end # I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -242,9 +249,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 15 on end end - end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -290,13 +296,13 @@ chip soc/intel/jasperlake end end end - device pci 1f.3 on + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on probe AUDIO_AMP RT1015P_AUTO end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/pirika/overridetree.cb b/src/mainboard/google/dedede/variants/pirika/overridetree.cb index cf1f95e7226..831ef975a28 100644 --- a/src/mainboard/google/dedede/variants/pirika/overridetree.cb +++ b/src/mainboard/google/dedede/variants/pirika/overridetree.cb @@ -46,13 +46,9 @@ chip soc/intel/jasperlake }, }" - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" # USB Port Configuration register "usb2_ports[0]" = "{ @@ -82,7 +78,18 @@ chip soc/intel/jasperlake register "tcc_offset" = "8" # TCC of 97C device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on # Default DPTF Policy for all Dedede boards if not overridden chip drivers/intel/dptf ## Passive Policy @@ -123,20 +130,20 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end end end - end # USB xHCI + end - device pci 15.0 on + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -156,7 +163,7 @@ chip soc/intel/jasperlake device i2c 0x2c on end end end - device pci 15.2 on + device ref i2c2 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -169,8 +176,8 @@ chip soc/intel/jasperlake register "has_power_resource" = "true" device i2c 10 on end end - end # I2C 2 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -230,13 +237,13 @@ chip soc/intel/jasperlake end end end - device pci 1f.3 on + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on probe AUDIO_AMP RT1015P_AUTO end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/sasuke/overridetree.cb b/src/mainboard/google/dedede/variants/sasuke/overridetree.cb index 0da00caef24..ffef13129a0 100644 --- a/src/mainboard/google/dedede/variants/sasuke/overridetree.cb +++ b/src/mainboard/google/dedede/variants/sasuke/overridetree.cb @@ -77,8 +77,26 @@ chip soc/intel/jasperlake .fall_time_ns = 8, }, }" + + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf register "options.tsr[0].desc" = ""Charger"" register "options.tsr[1].desc" = ""Vcore"" @@ -116,8 +134,8 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi device usb 0.0 on chip drivers/usb/acpi @@ -126,7 +144,7 @@ chip soc/intel/jasperlake register "has_power_resource" = "true" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D13)" register "enable_delay_ms" = "20" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""LTE"" @@ -136,12 +154,12 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "20" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 3.3 on end + device ref usb3_port4 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -159,10 +177,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0xE" device i2c 40 on end end - end # I2C 0 - device pci 15.2 on end - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/da7219 register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_D16)" register "btn_cfg" = "50" @@ -180,13 +196,13 @@ chip soc/intel/jasperlake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end #I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/sasukette/overridetree.cb b/src/mainboard/google/dedede/variants/sasukette/overridetree.cb index ba262b62826..518a490246f 100644 --- a/src/mainboard/google/dedede/variants/sasukette/overridetree.cb +++ b/src/mainboard/google/dedede/variants/sasukette/overridetree.cb @@ -59,6 +59,12 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # USB Port Configuration register "usb2_ports[2]" = "{ .enable = 1, @@ -90,7 +96,18 @@ chip soc/intel/jasperlake register "xhci_lfps_sampling_offtime_ms" = "0" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -125,8 +142,8 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi device usb 0.0 on chip drivers/usb/acpi @@ -135,7 +152,7 @@ chip soc/intel/jasperlake register "has_power_resource" = "true" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D15)" register "enable_delay_ms" = "20" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""LTE"" @@ -145,12 +162,12 @@ chip soc/intel/jasperlake register "reset_off_delay_ms" = "20" register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A10)" register "enable_delay_ms" = "20" - device usb 3.3 on end + device ref usb3_port4 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""SYNA0A00"" register "generic.desc" = ""SYNA Touchpad"" @@ -195,8 +212,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -224,13 +241,12 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end #I2C 4 - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/shotzo/overridetree.cb b/src/mainboard/google/dedede/variants/shotzo/overridetree.cb index 0935457092b..b32e39b1c93 100644 --- a/src/mainboard/google/dedede/variants/shotzo/overridetree.cb +++ b/src/mainboard/google/dedede/variants/shotzo/overridetree.cb @@ -38,6 +38,10 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "disable_external_bypass_vr" = "1" # Does not support external vnn power rail # Power limit config @@ -63,7 +67,7 @@ chip soc/intel/jasperlake register "usb2_ports[6]" = "USB2_PORT_MID(OC_SKIP)" # Lan device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf # Default DPTF Policy for all drawcia boards if not overridden register "options.tsr[0].desc" = ""Ambient"" @@ -107,84 +111,83 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A2"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A0"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A1"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A3"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 4)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""LAN"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H19)" - device usb 2.7 on end + device ref usb2_port8 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""LAN"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A0"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A1"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on end + device ref usb3_port4 on end end end end end # USB xHCI - device pci 15.0 off end # I2C 0 - device pci 15.2 on + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""ILTK0001"" register "generic.desc" = ""ILITEK Touchscreen"" @@ -199,15 +202,14 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 41 on end end - end # I2C 2 - device pci 15.3 off end #I2C 3 - device pci 1c.7 on + end + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""RTL5682"" register "name" = ""RT58"" @@ -220,12 +222,12 @@ chip soc/intel/jasperlake device i2c 1a on end end end #I2C 4 - device pci 1f.3 on + device ref hda on chip drivers/generic/alc1015 register "hid" = ""RTL1019"" register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/dedede/variants/storo/overridetree.cb b/src/mainboard/google/dedede/variants/storo/overridetree.cb index c22c796f68d..5469ea4808a 100644 --- a/src/mainboard/google/dedede/variants/storo/overridetree.cb +++ b/src/mainboard/google/dedede/variants/storo/overridetree.cb @@ -73,14 +73,11 @@ chip soc/intel/jasperlake .pre_emp_bit = USB2_HALF_BIT_PRE_EMP, }" # WWAN - register "SerialIoI2cMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoDisabled, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoPci, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoPci, - }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C5]" = "PchSerialIoPci" # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ @@ -103,7 +100,22 @@ chip soc/intel/jasperlake register "xhci_lfps_sampling_offtime_ms" = "0" device domain 0 on - device pci 04.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "2" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + # IPUA for IPUs + register "device[1].name" = ""IPUA"" + register "device[1].non_vga_device" = "true" + register "device[1].addr" = "0x3480" + + device generic 0 on end + end + end + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -138,8 +150,8 @@ chip soc/intel/jasperlake }" device generic 0 on end end - end # SA Thermal device - device pci 05.0 on # IPU - MIPI Camera + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -153,9 +165,9 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""User Facing Camera"" register "type" = "UPC_TYPE_INTERNAL" @@ -182,8 +194,8 @@ chip soc/intel/jasperlake end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -192,8 +204,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/generic/gpio_keys register "name" = ""PENH"" register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPP_C12)" @@ -219,23 +231,22 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 10 on end end - end # I2C 2 - device pci 15.3 on + end + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI8856"" register "acpi_uid" = "0" register "acpi_name" = ""CAM1"" register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_JSL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" register "vcm_name" = ""VCM0"" - register "ssdb.rom_type" = "ROM_EEPROM_CAT24C08" - register "rom_address" = "0x50" register "num_freq_entries" = "2" register "link_freq[0]" = "360000000" register "link_freq[1]" = "180000000" @@ -293,8 +304,8 @@ chip soc/intel/jasperlake device i2c 50 on end end - end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -322,14 +333,14 @@ chip soc/intel/jasperlake probe AUDIO_CODEC_SOURCE AUDIO_CODEC_ALC5682I_VS end end - end # I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/alc1015 register "sdb" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA - device pci 19.1 on + end + device ref i2c5 on chip drivers/i2c/sx9324 register "desc" = ""SAR Proximity Sensor"" register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E11_IRQ)" @@ -382,7 +393,6 @@ chip soc/intel/jasperlake register "reg_irq_cfg2" = "0x01" device i2c 28 on end end - end # I2C 5 - device pci 1c.7 off end # PCI Express Root Port 8 + end end end diff --git a/src/mainboard/google/dedede/variants/taranza/overridetree.cb b/src/mainboard/google/dedede/variants/taranza/overridetree.cb index f53a11a89e4..54910d5f4cf 100644 --- a/src/mainboard/google/dedede/variants/taranza/overridetree.cb +++ b/src/mainboard/google/dedede/variants/taranza/overridetree.cb @@ -25,6 +25,8 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + # Power limit config register "power_limits_config[JSL_N4500_6W_CORE]" = "{ .tdp_pl1_override = 6, @@ -133,7 +135,7 @@ chip soc/intel/jasperlake USB_PORT_WAKE_ENABLE(6)" device domain 0 on - device pci 04.0 on + device ref dptf on chip drivers/intel/dptf ## Passive Policy register "policies.passive" = "{ @@ -182,90 +184,86 @@ chip soc/intel/jasperlake device generic 0 on end end - end # SA Thermal device - device pci 14.0 on + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB2 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A0"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A1"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A2"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A3"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""USB2 Type-A Port A4"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-C Port C0"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A4"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A0"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A1"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 3)" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A3"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.4 on end + device ref usb3_port5 on end end chip drivers/usb/acpi register "desc" = ""USB3 Type-A Port A2"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 3)" - device usb 3.5 on end + device ref usb3_port6 on end end end end - end # USB xHCI - device pci 15.0 off end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 off end # I2C 2 - device pci 15.3 off end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""RTL5682"" register "name" = ""RT58"" @@ -277,8 +275,8 @@ chip soc/intel/jasperlake register "property_list[0].integer" = "1" device i2c 1a on end end - end # I2C 4 - device pci 1c.2 on + end + device ref pcie_rp3 on chip drivers/net register "customized_leds" = "0x05af" register "wake" = "GPE0_DW0_03" # GPP_B3 @@ -286,14 +284,13 @@ chip soc/intel/jasperlake register "device_index" = "0" device pci 00.0 on end end - end # PCI Express Root Port 3 - RTL8111H LAN - device pci 1c.6 on + end + device ref pcie_rp7 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 7 - WLAN - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1f.3 on end # Intel HDA + end + device ref hda on end end end diff --git a/src/mainboard/google/dedede/variants/waddledee/overridetree.cb b/src/mainboard/google/dedede/variants/waddledee/overridetree.cb index c177a8b32e5..7fc1a8bcaad 100644 --- a/src/mainboard/google/dedede/variants/waddledee/overridetree.cb +++ b/src/mainboard/google/dedede/variants/waddledee/overridetree.cb @@ -54,27 +54,43 @@ chip soc/intel/jasperlake }, }" + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + device domain 0 on - device pci 05.0 on end # IPU - MIPI Camera - device pci 14.0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "1" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + + device generic 0 on end + end + end + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Discrete Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H19)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""Integrated Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H19)" - device usb 2.7 on end + device ref usb2_port8 on end end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""SYNA0000"" register "generic.cid" = ""ACPI0C50"" @@ -86,7 +102,7 @@ chip soc/intel/jasperlake device i2c 0x2c on end end end - device pci 15.2 on + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""SIS6496"" register "generic.desc" = ""SIS Touchscreen"" @@ -119,8 +135,8 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 0x5d on end end - end # I2C 2 - device pci 15.3 on + end + device ref i2c3 on chip drivers/i2c/gpiomux/mux register "mux_gpio_count" = "1" register "mux_gpio[0]" = "ACPI_GPIO_OUTPUT(GPP_E5)" @@ -133,8 +149,8 @@ chip soc/intel/jasperlake end end # I2C MUX end - end # I2C 3 - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -159,12 +175,12 @@ chip soc/intel/jasperlake device i2c 29 on end end end - device pci 1c.7 on + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN - device pci 1f.3 on end # Intel HDA + end + device ref hda on end end end diff --git a/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb b/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb index 228a1720a63..9c7379c2f09 100644 --- a/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb +++ b/src/mainboard/google/dedede/variants/waddledoo/overridetree.cb @@ -49,8 +49,30 @@ chip soc/intel/jasperlake } }, }" + + register "SerialIoI2cMode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C1]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C2]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C3]" = "PchSerialIoPci" + register "SerialIoI2cMode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + device domain 0 on - device pci 05.0 on # IPU - MIPI Camera + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "2" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + # IPUA for IPUs + register "device[1].name" = ""IPUA"" + register "device[1].non_vga_device" = "true" + register "device[1].addr" = "0x3480" + + device generic 0 on end + end + end + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -65,9 +87,9 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Discrete Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" @@ -87,8 +109,8 @@ chip soc/intel/jasperlake end end end - end # USB xHCI - device pci 15.0 on + end + device ref i2c0 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -97,8 +119,8 @@ chip soc/intel/jasperlake register "detect" = "1" device i2c 15 on end end - end #I2C 0 - device pci 15.2 on + end + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""SIS6496"" register "generic.desc" = ""SIS Touchscreen"" @@ -136,24 +158,22 @@ chip soc/intel/jasperlake register "hid_desc_reg_offset" = "0x01" device i2c 10 on end end - end # I2C 2 - device pci 15.3 on #I2C #3 CAM0 CAM1 and VCM0 + end + device ref i2c3 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI8856"" register "acpi_uid" = "0" register "acpi_name" = ""CAM1"" register "chip_name" = ""Ov 8856 Camera"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" + register "sensor_name" = ""CJAJ813"" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_JSL" register "ssdb.vcm_type" = "VCM_DW9808" register "vcm_address" = "0x0C" register "vcm_name" = ""VCM0"" - # placeholder; ROM type 24C1024 currently unsupported - # register "ssdb.rom_type" = "ROM_EEPROM_24C1024" - # register "rom_address" = "0x50" register "num_freq_entries" = "2" register "link_freq[0]" = "360000000" register "link_freq[1]" = "180000000" @@ -218,9 +238,11 @@ chip soc/intel/jasperlake register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 9734 Camera"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" + register "sensor_name" = ""CJAJ813"" register "has_power_resource" = "true" register "ssdb.lanes_used" = "1" + register "ssdb.link_used" = "0" register "num_freq_entries" = "1" register "link_freq[0]" = "180000000" register "remote_name" = ""IPU0"" @@ -251,13 +273,13 @@ chip soc/intel/jasperlake device i2c 36 on end end end - device pci 1c.7 on + device ref pcie_rp8 on chip drivers/wifi/generic register "wake" = "GPE0_DW2_03" device pci 00.0 on end end - end # PCI Express Root Port 8 - WLAN - device pci 19.0 on + end + device ref i2c4 on chip drivers/i2c/da7219 register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_D16)" register "btn_cfg" = "50" @@ -275,13 +297,13 @@ chip soc/intel/jasperlake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end #I2C 4 - device pci 1f.3 on + end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98360A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D17)" device generic 0 on end end - end # Intel HDA + end end end diff --git a/src/mainboard/google/drallion/Kconfig b/src/mainboard/google/drallion/Kconfig index 34c9da5a8e7..1353447ee20 100644 --- a/src/mainboard/google/drallion/Kconfig +++ b/src/mainboard/google/drallion/Kconfig @@ -98,4 +98,7 @@ config VBOOT config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/default.fmd" if !CHROMEOS +config CBFS_SIZE + default 0x1000000 + endif # BOARD_GOOGLE_BASEBOARD_DRALLION diff --git a/src/mainboard/google/drallion/Kconfig.name b/src/mainboard/google/drallion/Kconfig.name index eed2505bcfb..3b3f67041ed 100644 --- a/src/mainboard/google/drallion/Kconfig.name +++ b/src/mainboard/google/drallion/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Drallion" +comment "Drallion (Intel CometLake (10th Gen) with ISH)" config BOARD_GOOGLE_DRALLION - bool "-> Drallion" + bool "-> Drallion/Drallion360 (Dell Latitude 7410 Chromebook Enterprise)" diff --git a/src/mainboard/google/drallion/cfr.c b/src/mainboard/google/drallion/cfr.c index aa9265db7d8..805b2870a12 100644 --- a/src/mainboard/google/drallion/cfr.c +++ b/src/mainboard/google/drallion/cfr.c @@ -1,4 +1,3 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ #include diff --git a/src/mainboard/google/eve/Kconfig b/src/mainboard/google/eve/Kconfig index 40eebc5c50c..cd4c5ad5e60 100644 --- a/src/mainboard/google/eve/Kconfig +++ b/src/mainboard/google/eve/Kconfig @@ -15,6 +15,7 @@ config BOARD_SPECIFIC_OPTIONS select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_BOARDID select EC_GOOGLE_CHROMEEC_ESPI + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select I2C_TPM @@ -73,6 +74,9 @@ config UART_FOR_CONSOLE int default 2 +config CBFS_SIZE + default 0xe00000 + config USE_PM_ACPI_TIMER default n endif diff --git a/src/mainboard/google/eve/Kconfig.name b/src/mainboard/google/eve/Kconfig.name index 59d691c0457..62e50ff7935 100644 --- a/src/mainboard/google/eve/Kconfig.name +++ b/src/mainboard/google/eve/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Eve" +comment "Eve (Intel KabyLake (7th Gen))" config BOARD_GOOGLE_EVE bool "-> Eve (Google Pixelbook)" diff --git a/src/mainboard/google/fatcat/Kconfig b/src/mainboard/google/fatcat/Kconfig index b38a4e90b9b..8f9029b2fc4 100644 --- a/src/mainboard/google/fatcat/Kconfig +++ b/src/mainboard/google/fatcat/Kconfig @@ -143,6 +143,7 @@ config BOARD_GOOGLE_LAPIS select EC_GOOGLE_CHROMEEC_LPC_GENERIC_MEMORY_RANGE select HAVE_SLP_S0_GATE select MAINBOARD_HAS_GOOGLE_STRAUSS_KEYBOARD + select FSP_UGOP_EARLY_SIGN_OF_LIFE config BOARD_GOOGLE_MOONSTONE select BOARD_GOOGLE_BASEBOARD_FATCAT @@ -157,6 +158,7 @@ config BOARD_GOOGLE_MODEL_RUBY select BOARD_GOOGLE_BASEBOARD_FATCAT select DRIVERS_I2C_TAS2563 select EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC + select FSP_UGOP_EARLY_SIGN_OF_LIFE select HAVE_SLP_S0_GATE select MAINBOARD_HAS_GOOGLE_STRAUSS_KEYBOARD @@ -243,6 +245,9 @@ config UART_FOR_CONSOLE int default 0 +config CBFS_SIZE + default 0x1000000 + config USE_PM_ACPI_TIMER default n diff --git a/src/mainboard/google/fatcat/Kconfig.name b/src/mainboard/google/fatcat/Kconfig.name index 61582c51021..fbd244e25d6 100644 --- a/src/mainboard/google/fatcat/Kconfig.name +++ b/src/mainboard/google/fatcat/Kconfig.name @@ -1,48 +1,48 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Fatcat" +comment "Fatcat (Intel PantherLake (Ultra 3rd Gen))" config BOARD_GOOGLE_FATCAT - bool "-> Fatcat" + bool "-> Fatcat" config BOARD_GOOGLE_FATCAT4ES - bool "-> Fatcat4ES" + bool "-> Fatcat4ES" config BOARD_GOOGLE_FATCATISH - bool "-> Fatcat_ish" + bool "-> Fatcat_ish" config BOARD_GOOGLE_FATCATITE - bool "-> Fatcatite" + bool "-> Fatcatite" config BOARD_GOOGLE_FATCATITE4ES - bool "-> Fatcatite4ES" + bool "-> Fatcatite4ES" config BOARD_GOOGLE_FATCATNUVO - bool "-> Fatcatnuvo" + bool "-> Fatcatnuvo" config BOARD_GOOGLE_FATCATNUVO4ES - bool "-> Fatcatnuvo4ES" + bool "-> Fatcatnuvo4ES" config BOARD_GOOGLE_FELINO - bool "-> Felino" + bool "-> Felino" config BOARD_GOOGLE_FELINO4ES - bool "-> Felino4ES" + bool "-> Felino4ES" config BOARD_GOOGLE_FRANCKA - bool "-> Francka" + bool "-> Francka" config BOARD_GOOGLE_KINMEN4ES - bool "-> Kinmen4ES" + bool "-> Kinmen4ES" config BOARD_GOOGLE_KINMEN - bool "-> Kinmen" + bool "-> Kinmen" config BOARD_GOOGLE_LAPIS - bool "-> Lapis" + bool "-> Lapis" config BOARD_GOOGLE_MOONSTONE - bool "-> Moonstone" + bool "-> Moonstone" config BOARD_GOOGLE_RUBY - bool "-> Ruby" + bool "-> Ruby" diff --git a/src/mainboard/google/fatcat/mainboard.c b/src/mainboard/google/fatcat/mainboard.c index 1ea606a6f10..b731f1d4d51 100644 --- a/src/mainboard/google/fatcat/mainboard.c +++ b/src/mainboard/google/fatcat/mainboard.c @@ -62,6 +62,18 @@ static void mainboard_early(void *unused) BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_EXIT, mainboard_early, NULL); +void __weak fw_config_post_gpio_configure(void) +{ + /* default implementation does nothing */ +} + +static void mainboard_pre_dev_init_chips(void *unused) +{ + fw_config_post_gpio_configure(); +} + +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_ENTRY, mainboard_pre_dev_init_chips, NULL); + void __weak baseboard_devtree_update(void) { /* Override dev tree settings per baseboard */ diff --git a/src/mainboard/google/fatcat/romstage.c b/src/mainboard/google/fatcat/romstage.c index 8f0000c2ce8..04b39c58c48 100644 --- a/src/mainboard/google/fatcat/romstage.c +++ b/src/mainboard/google/fatcat/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include #include -#include +#include +#include #include #include #include @@ -43,3 +45,22 @@ void mainboard_memory_init_params(FSPM_UPD *memupd) /* Override FSP-M UPD per board if required. */ variant_update_soc_memory_init_params(memupd); } + +void platform_romstage_pre_mem(void) +{ + /* + * Early initialization of the Chrome EC lightbar. + * Ensures visual continuity if the AP firmware disabled the lightbar + * in a previous boot without a subsequent EC reset. + */ + if (CONFIG(EC_GOOGLE_CHROMEEC_LED_CONTROL)) + google_chromeec_lightbar_on(); + + /* + * Only alert the user (set LED to red in color) if the lid is closed and the battery + * is critically low without AC power. + */ + if (CONFIG(EC_GOOGLE_CHROMEEC) && CONFIG(VBOOT_LID_SWITCH) && !get_lid_switch() && + google_chromeec_is_critically_low_on_battery()) + google_chromeec_set_lightbar_rgb(0xff, 0xff, 0x00, 0x00); +} diff --git a/src/mainboard/google/fatcat/variants/baseboard/fatcat/devicetree.cb b/src/mainboard/google/fatcat/variants/baseboard/fatcat/devicetree.cb index 6ccd7c2e182..14dbd34db6f 100644 --- a/src/mainboard/google/fatcat/variants/baseboard/fatcat/devicetree.cb +++ b/src/mainboard/google/fatcat/variants/baseboard/fatcat/devicetree.cb @@ -48,9 +48,11 @@ chip soc/intel/pantherlake register "sagv_freq_mhz[2]" = "6400" register "sagv_gear[2]" = "GEAR_4" - register "sagv_freq_mhz[3]" = "6800" + register "sagv_freq_mhz[3]" = "7467" register "sagv_gear[3]" = "GEAR_4" + register "max_dram_speed_mts" = "7467" + # Enable s0ix register "s0ix_enable" = "true" @@ -60,11 +62,6 @@ chip soc/intel/pantherlake # Setting TCC of 100C = Tj max (110) - TCC_Offset (10) register "tcc_offset" = "10" - # Disable C1 C-state auto-demotion - register "disable_c1_state_auto_demotion" = "true" - # Disable PKGC-state auto-demotion - register "disable_package_c_state_demotion" = "true" - # Enable Energy Reporting register "pch_pm_energy_report_enable" = "true" @@ -85,22 +82,36 @@ chip soc/intel/pantherlake register "cep_enable[VR_DOMAIN_GT]" = "true" register "enable_fast_vmode[VR_DOMAIN_SA]" = "true" register "cep_enable[VR_DOMAIN_SA]" = "true" - register "fast_vmode_i_trip[PTL_CORE_1]" = "{ + register "fast_vmode_i_trip[PTL_SKU_1]" = "{ [VR_DOMAIN_IA] = 63 * 4, [VR_DOMAIN_GT] = 38 * 4, [VR_DOMAIN_SA] = 38 * 4 }" - register "fast_vmode_i_trip[PTL_CORE_2]" = "{ + register "fast_vmode_i_trip[PTL_SKU_2]" = "{ + [VR_DOMAIN_IA] = 75 * 4, + [VR_DOMAIN_GT] = 75 * 4, + [VR_DOMAIN_SA] = 38 * 4 + }" + register "fast_vmode_i_trip[PTL_SKU_3]" = "{ + [VR_DOMAIN_IA] = 75 * 4, + [VR_DOMAIN_GT] = 38 * 4, + [VR_DOMAIN_SA] = 38 * 4 + }" + register "fast_vmode_i_trip[PTL_SKU_5]" = "{ [VR_DOMAIN_IA] = 63 * 4, [VR_DOMAIN_GT] = 38 * 4, [VR_DOMAIN_SA] = 38 * 4 }" - register "fast_vmode_i_trip[PTL_CORE_3]" = "{ + register "fast_vmode_i_trip[PTL_SKU_6]" = "{ [VR_DOMAIN_IA] = 75 * 4, [VR_DOMAIN_GT] = 75 * 4, [VR_DOMAIN_SA] = 38 * 4 }" - + register "fast_vmode_i_trip[PTL_SKU_7]" = "{ + [VR_DOMAIN_IA] = 75 * 4, + [VR_DOMAIN_GT] = 38 * 4, + [VR_DOMAIN_SA] = 38 * 4 + }" # Set on-board graphics as primary display register "skip_ext_gfx_scan" = "true" @@ -125,6 +136,7 @@ chip soc/intel/pantherlake register "pch_hda_idisp_codec_enable" = "true" register "disable_progress_bar" = "true" + register "vga_cd_clk_freq_sel" = "CD_CLK_461MHZ" device domain 0 on device ref dtt on end diff --git a/src/mainboard/google/fatcat/variants/baseboard/include/baseboard/variants.h b/src/mainboard/google/fatcat/variants/baseboard/include/baseboard/variants.h index ad26ab8a671..e0f49965797 100644 --- a/src/mainboard/google/fatcat/variants/baseboard/include/baseboard/variants.h +++ b/src/mainboard/google/fatcat/variants/baseboard/include/baseboard/variants.h @@ -19,6 +19,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num); const struct pad_config *variant_romstage_gpio_table(size_t *num); void fw_config_configure_pre_mem_gpio(void); void fw_config_gpio_padbased_override(struct pad_config *padbased_table); +void fw_config_post_gpio_configure(void); const struct mb_cfg *variant_memory_params(void); void variant_get_spd_info(struct mem_spd *spd_info); diff --git a/src/mainboard/google/fatcat/variants/fatcat/fw_config.c b/src/mainboard/google/fatcat/variants/fatcat/fw_config.c index d1f40ec06dd..329df7e09ad 100644 --- a/src/mainboard/google/fatcat/variants/fatcat/fw_config.c +++ b/src/mainboard/google/fatcat/variants/fatcat/fw_config.c @@ -168,20 +168,70 @@ static const struct pad_config audio_disable_pads[] = { PAD_NC(GPP_D17, NONE), }; +/* + * NOTE: The PCIe slot power PADs are pulled high by default on Fatcat. Since + * these PADs default to GPI configuration, slot power is enabled during early + * boot. Also, PERST# PADs are logically ANDed with PLTRST#. This ensures that + * PLTRST# de-assertion at the slot occurs after PCIe slot power stabilization, + * maintaining proper PCIe power-on sequences. + * + * If slot power must be disabled at boot, PERST# de-assertion must occur after + * power restoration and satisfy PCIe link training timing requirements. + * Additionally, the slot power PADs are recommended to be reworked to pull low + * to avoid a power glitch. The suggested power sequence is: + * + * Step 1 (romstage): ClkReq PAD off; PERST# asserted; power off + * Step 2 (ramstage at BS_PRE_DEVICE exit): Power on; ClkReq PAD on (if used) + * Step 3 (ramstage at BS_DEV_INIT_CHIPS entry): PERST# de-asserted + */ + +/* x1 slot power sequence: 1. no clkreq; PERST=asserted; power=off */ +static const struct pad_config pre_mem_x1slot_pads[] = { + /* GPP_C11: CLKREQ2_X1_GEN4_DT_CEM_SLOT_N */ + PAD_CFG_GPI(GPP_C11, NONE, DEEP), + /* GPP_D19: X1_DT_PCIE_RST_N */ + PAD_CFG_GPO(GPP_D19, 0, PLTRST), + /* GPP_A08: X1_PCIE_SLOT_PWR_EN */ + PAD_CFG_GPO(GPP_A08, 0, PLTRST), +}; + +/* x1 slot CBI + x1 slot power sequence: 2. power=on */ static const struct pad_config x1slot_pads[] = { /* GPP_A08: X1_PCIE_SLOT_PWR_EN */ PAD_CFG_GPO(GPP_A08, 1, PLTRST), /* GPP_D19: X1_DT_PCIE_RST_N */ - PAD_CFG_GPO(GPP_D19, 1, PLTRST), + PAD_CFG_GPO(GPP_D19, 0, PLTRST), /* GPP_B25: X1_SLOT_WAKE_N */ PAD_CFG_GPI_SCI_LOW(GPP_B25, NONE, DEEP, LEVEL), }; +/* + * x1 slot power sequence: 3. PERST# = de-assert; + */ +static const struct pad_config post_x1slot_pads[] = { + /* GPP_D19: X1_DT_PCIE_RST_N */ + PAD_CFG_GPO(GPP_D19, 1, PLTRST), +}; + +static const struct pad_config x1slot_clkreq_pads[] = { + /* x1 slot power sequence: 3a. Clkreq = enable for AIC with clkreq support */ + /* GPP_C11: CLKREQ2_X1_GEN4_DT_CEM_SLOT_N */ + PAD_CFG_NF(GPP_C11, NONE, DEEP, NF1), +}; + +static const struct pad_config x1slot_prsnt_pads[] = { + /* x1 slot power sequence: 3b. clkreq = GPI or NC for AIC using PRSNT2# */ + /* GPP_C11: for PRSNT2_X1_GEN4_DT_CEM_SLOT_N */ + PAD_CFG_GPI(GPP_C11, NONE, DEEP), +}; + static const struct pad_config x1slot_disable_pads[] = { /* GPP_A08: X1_PCIE_SLOT_PWR_EN */ - PAD_CFG_GPO(GPP_A08, 0, PLTRST), + PAD_CFG_GPO(GPP_A08, 1, PLTRST), /* GPP_D19: X1_DT_PCIE_RST_N */ PAD_NC(GPP_D19, NONE), + /* GPP_C11: CLKREQ2_X1_GEN4_DT_CEM_SLOT_N */ + PAD_NC(GPP_C11, NONE), /* GPP_B25: X1_SLOT_WAKE_N */ PAD_NC(GPP_B25, NONE) }; @@ -237,12 +287,10 @@ static const struct pad_config wwan_disable_pads[] = { /* Gen4 NVME: at the top M.2 slot */ static const struct pad_config pre_mem_gen4_ssd_pwr_pads[] = { /* GPP_B10: GEN4_SSD_PWREN */ - PAD_CFG_GPO(GPP_B10, 0, PLTRST), + PAD_CFG_GPO(GPP_B10, 1, PLTRST), }; static const struct pad_config gen4_ssd_pads[] = { - /* GPP_B10: GEN4_SSD_PWREN */ - PAD_CFG_GPO(GPP_B10, 1, PLTRST), /* GPP_B09: M2_GEN4_SSD_RESET_N */ PAD_CFG_GPO(GPP_B09, 1, PLTRST), }; @@ -250,7 +298,7 @@ static const struct pad_config gen4_ssd_pads[] = { /* Gen5 NVME: at the bottom M.2 slot */ static const struct pad_config pre_mem_gen5_ssd_pwr_pads[] = { /* GPP_B16: GEN5_SSD_PWREN */ - PAD_CFG_GPO(GPP_B16, 0, PLTRST), + PAD_CFG_GPO(GPP_B16, 1, PLTRST), }; static const struct pad_config gen5_ssd_pads[] = { @@ -567,14 +615,8 @@ void fw_config_configure_pre_mem_gpio(void) if (!fw_config_probe(FW_CONFIG(CELLULAR, CELLULAR_ABSENT))) GPIO_CONFIGURE_PADS(pre_mem_wwan_pwr_seq1_pads); - if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_NVME_GEN4))) { - GPIO_CONFIGURE_PADS(pre_mem_gen4_ssd_pwr_pads); - } else if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_NVME_GEN5))) { - GPIO_CONFIGURE_PADS(pre_mem_gen5_ssd_pwr_pads); - } else if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_UNKNOWN))) { - GPIO_CONFIGURE_PADS(pre_mem_gen4_ssd_pwr_pads); - GPIO_CONFIGURE_PADS(pre_mem_gen5_ssd_pwr_pads); - } + if (!fw_config_probe(FW_CONFIG(SD, SD_NONE))) + GPIO_CONFIGURE_PADS(pre_mem_x1slot_pads); /* * NOTE: We place WWAN sequence 2 here. According to the WWAN FIBOCOM @@ -592,6 +634,14 @@ void fw_config_configure_pre_mem_gpio(void) if (fw_config_probe(FW_CONFIG(FP, FP_PRESENT))) GPIO_CONFIGURE_PADS(pre_mem_fp_enable_pads); + if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_NVME_GEN4))) { + GPIO_CONFIGURE_PADS(pre_mem_gen4_ssd_pwr_pads); + } else if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_NVME_GEN5))) { + GPIO_CONFIGURE_PADS(pre_mem_gen5_ssd_pwr_pads); + } else if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_UNKNOWN))) { + GPIO_CONFIGURE_PADS(pre_mem_gen4_ssd_pwr_pads); + GPIO_CONFIGURE_PADS(pre_mem_gen5_ssd_pwr_pads); + } } void fw_config_gpio_padbased_override(struct pad_config *padbased_table) @@ -654,10 +704,15 @@ void fw_config_gpio_padbased_override(struct pad_config *padbased_table) GPIO_PADBASED_OVERRIDE(padbased_table, wwan_disable_pads); } - if (fw_config_probe(FW_CONFIG(SD, SD_NONE))) - GPIO_PADBASED_OVERRIDE(padbased_table, x1slot_disable_pads); - else + if (fw_config_probe(FW_CONFIG(SD, SD_GENSYS))) { + GPIO_PADBASED_OVERRIDE(padbased_table, x1slot_pads); + GPIO_PADBASED_OVERRIDE(padbased_table, x1slot_prsnt_pads); + } else if (fw_config_probe(FW_CONFIG(SD, SD_BAYHUB))) { GPIO_PADBASED_OVERRIDE(padbased_table, x1slot_pads); + GPIO_PADBASED_OVERRIDE(padbased_table, x1slot_clkreq_pads); + } else { + GPIO_PADBASED_OVERRIDE(padbased_table, x1slot_disable_pads); + } if (fw_config_probe(FW_CONFIG(TOUCHPAD, TOUCHPAD_LPSS_I2C))) { GPIO_PADBASED_OVERRIDE(padbased_table, touchpad_lpss_i2c_enable_pads); @@ -669,15 +724,18 @@ void fw_config_gpio_padbased_override(struct pad_config *padbased_table) GPIO_PADBASED_OVERRIDE(padbased_table, touchpad_i2c_disable_pads); } - if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_LPSS_I2C))) { + if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_LPSS_I2C)) || + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_LPSS_I2C_ELAN_REX))) { GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_lpss_i2c_enable_pads); - } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C))) { + } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C)) || + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C_ELAN_REX))) { GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_thc_i2c_enable_pads); if (config->thc_wake_on_touch[0]) GPIO_PADBASED_OVERRIDE(padbased_table, thc0_enable_wake); } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_GSPI))) { GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_gspi_enable_pads); - } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI))) { + } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI)) || + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI_ELAN_REX))) { GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_thc_spi_enable_pads); if (config->thc_wake_on_touch[0]) GPIO_PADBASED_OVERRIDE(padbased_table, thc0_enable_wake); @@ -708,7 +766,8 @@ void fw_config_gpio_padbased_override(struct pad_config *padbased_table) * 2. CBI selecting TS THC-SPI or TS GSPI with FSP present is invalid case. */ if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_GSPI)) || - fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI))) { + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI)) || + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI_ELAN_REX))) { /* board has TS SPI rework and not FPS support */ } else if (fw_config_probe(FW_CONFIG(FP, FP_PRESENT))) { GPIO_PADBASED_OVERRIDE(padbased_table, fp_enable_pads); @@ -716,3 +775,9 @@ void fw_config_gpio_padbased_override(struct pad_config *padbased_table) GPIO_PADBASED_OVERRIDE(padbased_table, fp_disable_pads); } } + +void fw_config_post_gpio_configure(void) +{ + if (!fw_config_probe(FW_CONFIG(SD, SD_NONE))) + GPIO_CONFIGURE_PADS(post_x1slot_pads); +} diff --git a/src/mainboard/google/fatcat/variants/fatcat/gpio.c b/src/mainboard/google/fatcat/variants/fatcat/gpio.c index eb036412519..1d12f5629f3 100644 --- a/src/mainboard/google/fatcat/variants/fatcat/gpio.c +++ b/src/mainboard/google/fatcat/variants/fatcat/gpio.c @@ -28,6 +28,8 @@ static const struct pad_config gpio_table[] = { /* GPP_A06: ESPI_RST_EC_R_N */ /* GPP_A06 : GPP_A06 ==> ESPI_RST_HDR configured on reset, do not touch */ + /* GPP_A08: X1_PCIE_SLOT_PWR_EN */ + /* NOTE: x1 slot power will be updated according to SD fw_config */ /* GPP_A09: M.2_WWAN_FCP_OFF_N */ PAD_CFG_GPO(GPP_A09, 1, PLTRST), /* GPP_A10: M.2_WWAN_DISABLE_N */ @@ -83,7 +85,8 @@ static const struct pad_config gpio_table[] = { PAD_CFG_GPO(GPP_B21, 0, DEEP), /* GPP_B24: ESPI_ALERT0_EC_R_N */ PAD_NC(GPP_B24, NONE), - + /* GPP_B25: X1_SLOT_WAKE_N */ + /* NOTE: x1 slot wake will be overridden according to SD fw_config */ /* GPP_C00: GPP_C0_SMBCLK */ PAD_CFG_NF(GPP_C00, NONE, DEEP, NF1), /* GPP_C01: GPP_C1_SMBDATA */ @@ -103,7 +106,7 @@ static const struct pad_config gpio_table[] = { /* GPP_C10: CLKREQ1_X4_GEN5_M2_SSD_N */ PAD_CFG_NF(GPP_C10, NONE, DEEP, NF1), /* GPP_C11: CLKREQ2_X1_GEN4_DT_CEM_SLOT_N */ - PAD_CFG_NF(GPP_C11, NONE, DEEP, NF1), + /* NOTE: x1 slot clkreq will be overridden according to SD fw_config */ /* GPP_C12: CLKREQ3_X1_GEN1_GBE_LAN_N */ PAD_CFG_NF(GPP_C12, NONE, DEEP, NF1), /* GPP_C13: CLKREQ4_X1_GEN4_M2_WLAN_N */ @@ -161,6 +164,8 @@ static const struct pad_config gpio_table[] = { PAD_CFG_NF(GPP_D17, NONE, DEEP, NF1), /* GPP_D18: CLKREQ6_X4_GEN4_M2_SSD_N */ PAD_CFG_NF(GPP_D18, NONE, DEEP, NF1), + /* GPP_D19: X1_DT_PCIE_RST_N */ + /* NOTE: X1 PERST will follow power sequence according to SD fw_config */ /* GPP_D20: CSE_EARLY_SW */ PAD_CFG_GPI_SCI_HIGH(GPP_D20, NONE, DEEP, LEVEL), /* GPP_D21: NC */ @@ -361,12 +366,15 @@ static const struct pad_config early_gpio_table[] = { PAD_CFG_NF(GPP_H07, NONE, DEEP, NF1), /* GPP_D15: SPI_TPM_INT_N */ PAD_CFG_GPI_APIC(GPP_D15, NONE, PLTRST, LEVEL, INVERT), + + /* GPP_B10: GEN4_SSD_PWREN */ + PAD_CFG_GPO(GPP_B10, 0, PLTRST), + /* GPP_B16: GEN5_SSD_PWREN */ + PAD_CFG_GPO(GPP_B16, 0, PLTRST), }; /* Pad configuration in romstage */ static const struct pad_config romstage_gpio_table[] = { - /* GPP_A08: X1_PCIE_SLOT_PWR_EN */ - PAD_CFG_GPO(GPP_A08, 0, PLTRST), /* GPP_C00: GPP_C0_SMBCLK */ PAD_CFG_NF(GPP_C00, NONE, DEEP, NF1), /* GPP_C01: GPP_C1_SMBDATA */ diff --git a/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb b/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb index f5204108472..5ad0dc63c89 100644 --- a/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb @@ -24,6 +24,10 @@ fw_config option TOUCHSCREEN_GSPI 2 option TOUCHSCREEN_THC_SPI 3 option TOUCHSCREEN_THC_I2C 4 + # NOTE: conversion cables are required to connect with Google touch screen + option TOUCHSCREEN_LPSS_I2C_ELAN_REX 5 + option TOUCHSCREEN_THC_SPI_ELAN_REX 6 + option TOUCHSCREEN_THC_I2C_ELAN_REX 7 end field TOUCHPAD 11 12 option TOUCHPAD_NONE 0 @@ -32,8 +36,8 @@ fw_config end field SD 13 14 option SD_NONE 0 - option SD_GENSYS 1 - option SD_BAYHUB 2 + option SD_GENSYS 1 # use pin B17 as PRSNT2# + option SD_BAYHUB 2 # use pin B17 as ClkReq# end field STORAGE 15 16 option STORAGE_UNKNOWN 0 @@ -128,8 +132,8 @@ chip soc/intel/pantherlake #| I2C5 | Touchpad | #+-------------------+---------------------------+ register "common_soc_config" = "{ - /* Render OEM footer logo 100px above from the edge */ - .logo_bottom_margin = 100, + /* Render OEM footer logo 200px above from the edge */ + .logo_bottom_margin = 200, .chipset_lockdown = CHIPSET_LOCKDOWN_COREBOOT, .i2c[1] = { .speed = I2C_SPEED_FAST, @@ -326,6 +330,8 @@ chip soc/intel/pantherlake register "thc_wake_on_touch[0]" = "true" probe TOUCHSCREEN TOUCHSCREEN_THC_SPI probe TOUCHSCREEN TOUCHSCREEN_THC_I2C + probe TOUCHSCREEN TOUCHSCREEN_THC_SPI_ELAN_REX + probe TOUCHSCREEN TOUCHSCREEN_THC_I2C_ELAN_REX # THC0 is function 0; hence it needs to be enabled when THC1 is to be enabled. probe TOUCHPAD TOUCHPAD_THC_I2C chip drivers/intel/touch @@ -345,6 +351,23 @@ chip soc/intel/pantherlake probe TOUCHSCREEN TOUCHSCREEN_THC_I2C end end + chip drivers/intel/touch + register "name" = "INTEL_THC0_NAME" + register "mode" = "THC_HID_I2C_MODE" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F08)" + register "enable_delay_ms" = "2" + register "enable_off_delay_ms" = "2" + register "wake_on_touch" = "true" + # NOTE: Use GpioInt() in _CRS and does not use GPE. + register "wake_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW_WAKE(GPP_VGPIO3_THC0)" + register "active_ltr" = "1" + register "idle_ltr" = "0" + register "connected_device" = "TH_SENSOR_ELAN_REX" + register "add_acpi_dma_property" = "true" + device generic 0 alias touch_0_i2c_google on + probe TOUCHSCREEN TOUCHSCREEN_THC_I2C_ELAN_REX + end + end chip drivers/intel/touch register "name" = "INTEL_THC0_NAME" register "mode" = "THC_HID_SPI_MODE" @@ -367,6 +390,28 @@ chip soc/intel/pantherlake probe TOUCHSCREEN TOUCHSCREEN_THC_SPI end end + chip drivers/intel/touch + register "name" = "INTEL_THC0_NAME" + register "mode" = "THC_HID_SPI_MODE" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F08)" + register "enable_delay_ms" = "2" + register "enable_off_delay_ms" = "2" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E16)" + register "reset_delay_ms" = "10" + register "reset_off_delay_ms" = "2" + register "wake_on_touch" = "true" + # NOTE: Use GpioInt() in _CRS and does not use GPE. + register "wake_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW_WAKE(GPP_VGPIO3_THC0)" + register "active_ltr" = "1" + register "idle_ltr" = "0" + register "connected_device" = "TH_SENSOR_ELAN_REX" + register "soc_hidspi.write_mode" = "HIDSPI_WRITE_MODE_SINGLE" + register "soc_hidspi.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E16)" + register "add_acpi_dma_property" = "true" + device generic 0 alias touch_0_spi_google on + probe TOUCHSCREEN TOUCHSCREEN_THC_SPI_ELAN_REX + end + end end device ref thc1 on register "thc_wake_on_touch[1]" = "true" @@ -557,6 +602,10 @@ chip soc/intel/pantherlake register "pcie_rp[PCIE_RP(3)]" = "{ .clk_src = 2, .clk_req = 2, + /* + * NOTE: The clock usage flag is changed to + * PCIE_RP_CLK_REQ_UNUSED in variant.c when PRSNT#2 is used. + */ .flags = PCIE_RP_CLK_REQ_DETECT | PCIE_RP_LTR | PCIE_RP_AER, }" chip soc/intel/common/block/pcie/rtd3 @@ -665,6 +714,7 @@ chip soc/intel/pantherlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "0" register "ssdb.platform" = "PLAT_PTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560 * MHz" # 560 MHz @@ -770,6 +820,7 @@ chip soc/intel/pantherlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_PTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560 * MHz" # 560 MHz @@ -900,6 +951,24 @@ chip soc/intel/pantherlake probe TOUCHSCREEN TOUCHSCREEN_LPSS_I2C end end + chip drivers/i2c/hid + register "generic.hid" = ""ELAN9006"" + register "generic.desc" = ""ELAN Touchscreen"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E18_IRQ)" + # NOTE: pmc_gpe0_dw2 is GPP_E in baseboard devicetree.cb. + register "generic.wake" = "GPE0_DW2_18" + register "generic.probed" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E16)" + register "generic.reset_delay_ms" = "20" + register "generic.reset_off_delay_ms" = "2" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F08)" + register "generic.enable_delay_ms" = "1" + register "generic.has_power_resource" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 10 on + probe TOUCHSCREEN TOUCHSCREEN_LPSS_I2C_ELAN_REX + end + end end # I2C4 device ref i2c5 on chip drivers/i2c/hid diff --git a/src/mainboard/google/fatcat/variants/fatcat/variant.c b/src/mainboard/google/fatcat/variants/fatcat/variant.c index a3d7e79e654..cb42dfb3b0f 100644 --- a/src/mainboard/google/fatcat/variants/fatcat/variant.c +++ b/src/mainboard/google/fatcat/variants/fatcat/variant.c @@ -51,9 +51,11 @@ void variant_update_soc_chip_config(struct soc_intel_pantherlake_config *config) * | with WOT disabled | with WOT disabled| | | * +===================+==================+=================+============================+ */ - if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C))) { + if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C)) || + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_I2C_ELAN_REX))) { config->thc_mode[0] = THC_HID_I2C_MODE; - } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI))) { + } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI)) || + fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI_ELAN_REX))) { config->thc_mode[0] = THC_HID_SPI_MODE; } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_GSPI))) { config->serial_io_gspi_mode[PchSerialIoIndexGSPI0] = PchSerialIoPci; @@ -73,6 +75,14 @@ void variant_update_soc_chip_config(struct soc_intel_pantherlake_config *config) */ config->thc_mode[0] = THC_HID_I2C_MODE; } + + /* x1 Slot */ + if (fw_config_probe(FW_CONFIG(SD, SD_GENSYS))) { + uint8_t flags = config->pcie_rp[PCIE_RP(3)].flags; + flags &= ~(PCIE_RP_CLK_REQ_DETECT | PCIE_RP_CLK_REQ_UNUSED); + flags |= PCIE_RP_CLK_SRC_UNUSED; + config->pcie_rp[PCIE_RP(3)].flags = flags; + } } void variant_update_soc_memory_init_params(FSPM_UPD *memupd) diff --git a/src/mainboard/google/fatcat/variants/felino/overridetree.cb b/src/mainboard/google/fatcat/variants/felino/overridetree.cb index 0be19ae39cb..b70a1da7220 100644 --- a/src/mainboard/google/fatcat/variants/felino/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/felino/overridetree.cb @@ -102,8 +102,8 @@ chip soc/intel/pantherlake #| I2C4 | CLICK PAD | #+-------------------+---------------------------+ register "common_soc_config" = "{ - /* Render OEM footer logo 100px above from the edge */ - .logo_bottom_margin = 100, + /* Render OEM footer logo 200px above from the edge */ + .logo_bottom_margin = 200, .i2c[1] = { .early_init=1, .speed = I2C_SPEED_FAST, diff --git a/src/mainboard/google/fatcat/variants/francka/overridetree.cb b/src/mainboard/google/fatcat/variants/francka/overridetree.cb index 4b758ea2935..3f26fb48784 100644 --- a/src/mainboard/google/fatcat/variants/francka/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/francka/overridetree.cb @@ -79,8 +79,8 @@ chip soc/intel/pantherlake #| I2C4 | Touchscreen, Touchpad | #+-------------------+---------------------------+ register "common_soc_config" = "{ - /* Render OEM footer logo 100px above from the edge */ - .logo_bottom_margin = 100, + /* Render OEM footer logo 200px above from the edge */ + .logo_bottom_margin = 200, .chipset_lockdown = CHIPSET_LOCKDOWN_COREBOOT, .i2c[1] = { .early_init = 1, diff --git a/src/mainboard/google/fatcat/variants/kinmen/overridetree.cb b/src/mainboard/google/fatcat/variants/kinmen/overridetree.cb index 36a7c30d09c..1eb39299dd7 100644 --- a/src/mainboard/google/fatcat/variants/kinmen/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/kinmen/overridetree.cb @@ -86,8 +86,8 @@ chip soc/intel/pantherlake #| I2C5 | Touchscreen | #+-------------------+---------------------------+ register "common_soc_config" = "{ - /* Render OEM footer logo 100px above from the edge */ - .logo_bottom_margin = 100, + /* Render OEM footer logo 200px above from the edge */ + .logo_bottom_margin = 200, .chipset_lockdown = CHIPSET_LOCKDOWN_COREBOOT, .i2c[3] = { .early_init = 1, @@ -374,13 +374,6 @@ chip soc/intel/pantherlake .clk_req = 1, .flags = PCIE_RP_CLK_REQ_DETECT | PCIE_RP_LTR | PCIE_RP_AER, }" - chip soc/intel/common/block/pcie/rtd3 - register "is_storage" = "true" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_B16)" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E03)" - register "srcclk_pin" = "1" - device generic 0 on end - end end # Gen5 M.2 SSD device ref cnvi_wifi on chip drivers/wifi/generic diff --git a/src/mainboard/google/fatcat/variants/lapis/memory/Makefile.mk b/src/mainboard/google/fatcat/variants/lapis/memory/Makefile.mk index 3580f944f9c..05fac1eb69f 100644 --- a/src/mainboard/google/fatcat/variants/lapis/memory/Makefile.mk +++ b/src/mainboard/google/fatcat/variants/lapis/memory/Makefile.mk @@ -4,6 +4,6 @@ # util/spd_tools/bin/part_id_gen PTL lp5 src/mainboard/google/fatcat/variants/lapis/memory src/mainboard/google/fatcat/variants/lapis/memory/mem_parts_used.txt SPD_SOURCES = -SPD_SOURCES += spd/lp5/set-0/spd-10.hex # ID = 0(0b0000) Parts = H58G66CK8BX147, K3KL9L90EM-MGCU, MT62F2G32D4DS-023 WT:C -SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 1(0b0001) Parts = H58G56CK8BX146, K3KL8L80EM-MGCU, MT62F1G32D2DS-023 WT:C +SPD_SOURCES += spd/lp5/set-0/spd-10.hex # ID = 0(0b0000) Parts = H58G66CK8BX147, K3KL9L90EM-MGCU, MT62F2G32D4DS-023 WT:C, MT62F2G32D4DS-020 WT:D +SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 1(0b0001) Parts = H58G56CK8BX146, K3KL8L80EM-MGCU, MT62F1G32D2DS-023 WT:C, MT62F1G32D2DS-020 WT:D SPD_SOURCES += spd/lp5/set-0/spd-13.hex # ID = 2(0b0010) Parts = K3KLALA0EM-MGCU diff --git a/src/mainboard/google/fatcat/variants/lapis/memory/dram_id.generated.txt b/src/mainboard/google/fatcat/variants/lapis/memory/dram_id.generated.txt index 9d1f6955351..cbb2a992c8d 100644 --- a/src/mainboard/google/fatcat/variants/lapis/memory/dram_id.generated.txt +++ b/src/mainboard/google/fatcat/variants/lapis/memory/dram_id.generated.txt @@ -11,3 +11,5 @@ H58G56CK8BX146 1 (0001) K3KL8L80EM-MGCU 1 (0001) MT62F1G32D2DS-023 WT:C 1 (0001) K3KLALA0EM-MGCU 2 (0010) +MT62F1G32D2DS-020 WT:D 1 (0001) +MT62F2G32D4DS-020 WT:D 0 (0000) diff --git a/src/mainboard/google/fatcat/variants/lapis/memory/mem_parts_used.txt b/src/mainboard/google/fatcat/variants/lapis/memory/mem_parts_used.txt index 332be8dc202..87fdf46aa67 100644 --- a/src/mainboard/google/fatcat/variants/lapis/memory/mem_parts_used.txt +++ b/src/mainboard/google/fatcat/variants/lapis/memory/mem_parts_used.txt @@ -16,3 +16,5 @@ H58G56CK8BX146 K3KL8L80EM-MGCU MT62F1G32D2DS-023 WT:C K3KLALA0EM-MGCU +MT62F1G32D2DS-020 WT:D +MT62F2G32D4DS-020 WT:D diff --git a/src/mainboard/google/fatcat/variants/lapis/overridetree.cb b/src/mainboard/google/fatcat/variants/lapis/overridetree.cb index 3d7e53aba5f..6855616bb90 100644 --- a/src/mainboard/google/fatcat/variants/lapis/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/lapis/overridetree.cb @@ -22,6 +22,10 @@ fw_config option TOUCHSCREEN_SOC_INTERFACE_I2C_LPSS 1 option TOUCHSCREEN_SOC_INTERFACE_I2C_THC 2 end + field SENSOR_HUB 23 23 + option ISH_ABSENT 0 + option ISH_PRESENT 1 + end field FINGERPRINT_INTERFACE 24 25 option FINGERPRINT_INTERFACE_UNKNOWN 0 option FINGERPRINT_INTERFACE_SPI 1 @@ -40,7 +44,7 @@ fw_config option TRACKPAD_SOC_INTERFACE_I2C_LPSS 1 option TRACKPAD_SOC_INTERFACE_I2C_THC 2 end - field KB_BACKLIGHT_PRESENT 43 43 + field KB_BACKLIGHT 43 43 option KB_BACKLIGHT_ABSENT 0 option KB_BACKLIGHT_PRESENT 1 end @@ -48,6 +52,10 @@ fw_config option WIFI_SAR_ID0 0 option WIFI_SAR_ID1 1 end + field FINGERPRINT_MCU 63 63 + option FINGERPRINT_FT9001_FT9865 0 + option FINGERPRINT_FT9001C_FT9849 1 + end end chip soc/intel/pantherlake @@ -76,7 +84,7 @@ chip soc/intel/pantherlake register "usb2_ports[2]" = "USB2_PORT_MID(OC_SKIP)" # LED register "usb2_ports[3]" = "USB2_PORT_MID(OC_SKIP)" # Type-A Port A0 (MB) register "usb2_ports[4]" = "USB2_PORT_MID(OC_SKIP)" # Type-A Port A1 (DB) - register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" # USB HUB (USB2 Camera) + register "usb2_ports[5]" = "USB2_PORT_LONG(OC_SKIP)" # USB HUB (USB2 Camera) register "usb2_ports[6]" = "USB2_PORT_MID(OC_SKIP)" # Fingerprint register "usb2_ports[7]" = "USB2_PORT_MID(OC_SKIP)" # Discrete Bluetooth @@ -111,7 +119,9 @@ chip soc/intel/pantherlake #| I2C3 | cr50 TPM. | #+-------------------+---------------------------+ register "common_soc_config" = "{ - .logo_valignment = FW_SPLASH_VALIGNMENT_MIDDLE, + .chipset_lockdown = CHIPSET_LOCKDOWN_COREBOOT, + /* Render OEM footer logo 200px above from the edge */ + .logo_bottom_margin = 200, .i2c[3] = { .early_init=1, .speed = I2C_SPEED_FAST, @@ -280,7 +290,7 @@ chip soc/intel/pantherlake device generic 0 on end end end - device ref ipu on end + device ref ipu off end device ref iaa off end device ref tbt_pcie_rp0 on end device ref tbt_pcie_rp2 on end @@ -395,11 +405,6 @@ chip soc/intel/pantherlake .clk_req = 0, .flags = PCIE_RP_CLK_REQ_DETECT | PCIE_RP_LTR | PCIE_RP_AER, }" - chip soc/intel/common/block/pcie/rtd3 - register "is_storage" = "true" - register "srcclk_pin" = "0" - device generic 0 on end - end end # Gen4 SSD device ref cnvi_wifi on @@ -515,6 +520,7 @@ chip soc/intel/pantherlake end end end # SNDW + device ref smbus on end device ref i2c0 on end device ref i2c3 on chip drivers/i2c/tpm diff --git a/src/mainboard/google/fatcat/variants/moonstone/overridetree.cb b/src/mainboard/google/fatcat/variants/moonstone/overridetree.cb index 17d461248c2..28b2fec9846 100644 --- a/src/mainboard/google/fatcat/variants/moonstone/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/moonstone/overridetree.cb @@ -87,6 +87,8 @@ chip soc/intel/pantherlake register "cnvi_wifi_core" = "true" register "cnvi_bt_core" = "true" + register "vga_cd_clk_freq_sel" = "CD_CLK_442MHZ" + register "serial_io_i2c_mode" = "{ [PchSerialIoIndexI2C0] = PchSerialIoPci, [PchSerialIoIndexI2C1] = PchSerialIoDisabled, @@ -111,8 +113,8 @@ chip soc/intel/pantherlake #| I2C5 | Touchscreen | #+-------------------+---------------------------+ register "common_soc_config" = "{ - /* Render OEM footer logo 100px above from the edge */ - .logo_bottom_margin = 100, + /* Render OEM footer logo 200px above from the edge */ + .logo_bottom_margin = 200, .chipset_lockdown = CHIPSET_LOCKDOWN_COREBOOT, .i2c[3] = { .early_init = 1, @@ -390,13 +392,6 @@ chip soc/intel/pantherlake .clk_req = 1, .flags = PCIE_RP_CLK_REQ_DETECT | PCIE_RP_LTR | PCIE_RP_AER, }" - chip soc/intel/common/block/pcie/rtd3 - register "is_storage" = "true" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_B16)" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E03)" - register "srcclk_pin" = "1" - device generic 0 on end - end end # Gen5 M.2 SSD device ref cnvi_wifi on chip drivers/wifi/generic diff --git a/src/mainboard/google/fatcat/variants/ruby/Makefile.mk b/src/mainboard/google/fatcat/variants/ruby/Makefile.mk index 6c0a1ae6fb6..36616963a3c 100644 --- a/src/mainboard/google/fatcat/variants/ruby/Makefile.mk +++ b/src/mainboard/google/fatcat/variants/ruby/Makefile.mk @@ -1,8 +1,9 @@ -## SPDX-License-Identifier: GPL-2.0-only +/* SPDX-License-Identifier: GPL-2.0-only */ bootblock-y += gpio.c romstage-y += gpio.c romstage-y += memory.c romstage-$(CONFIG_FW_CONFIG) += fw_config.c ramstage-y += gpio.c +ramstage-$(CONFIG_FW_CONFIG) += variant.c ramstage-$(CONFIG_FW_CONFIG) += fw_config.c diff --git a/src/mainboard/google/fatcat/variants/ruby/gpio.c b/src/mainboard/google/fatcat/variants/ruby/gpio.c index 6324a5d9b8d..9c800742550 100644 --- a/src/mainboard/google/fatcat/variants/ruby/gpio.c +++ b/src/mainboard/google/fatcat/variants/ruby/gpio.c @@ -55,7 +55,8 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_B02, NONE), /* GPP_B03: NC */ PAD_NC(GPP_B03, NONE), - + /* GPP_B05: NONE */ + PAD_NC(GPP_B05, NONE), /* GPP_B06: NC */ PAD_NC(GPP_B06, NONE), /* GPP_B07: NC */ @@ -381,7 +382,7 @@ static const struct pad_config gpio_table[] = { /* GPP_V16: GPP_V16_VCCST_EN */ PAD_CFG_NF(GPP_V16, NONE, DEEP, NF1), /* GPP_V17: SLP_S0_GATE_R */ - PAD_CFG_GPO(GPP_V17, 1, PLTRST), + PAD_CFG_GPO(GPP_V17, 1, DEEP), }; /* Early pad configuration in bootblock */ diff --git a/src/mainboard/google/fatcat/variants/ruby/overridetree.cb b/src/mainboard/google/fatcat/variants/ruby/overridetree.cb index c85b2b13c57..6b37f24a0f2 100644 --- a/src/mainboard/google/fatcat/variants/ruby/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/ruby/overridetree.cb @@ -39,6 +39,10 @@ fw_config option KB_BACKLIGHT_ABSENT 0 option KB_BACKLIGHT_PRESENT 1 end + field AP_OEM_3BIT_FIELD0 56 58 + option WIFI_SAR_ID0 0 + option WIFI_SAR_ID1 1 + end end chip soc/intel/pantherlake @@ -58,17 +62,31 @@ chip soc/intel/pantherlake .tdp_pl4 = 150, }" - register "fast_vmode_i_trip[PTL_CORE_1]" = "{ + register "fast_vmode_i_trip[PTL_SKU_1]" = "{ [VR_DOMAIN_IA] = 74 * 4, [VR_DOMAIN_GT] = 38 * 4, [VR_DOMAIN_SA] = 38 * 4 }" - register "fast_vmode_i_trip[PTL_CORE_2]" = "{ + register "fast_vmode_i_trip[PTL_SKU_5]" = "{ [VR_DOMAIN_IA] = 74 * 4, [VR_DOMAIN_GT] = 38 * 4, [VR_DOMAIN_SA] = 38 * 4 }" + # Acoustic Noise settings and slew rate configuration: + register "enable_acoustic_noise_mitigation" = "true" + # Slew rate for IA Domain: Fast/4 + register "slow_slew_rate_config[VR_DOMAIN_IA]" = "SLEW_FAST_4" + # Slew rate for GT Domain: Fast/2 + register "slow_slew_rate_config[VR_DOMAIN_GT]" = "SLEW_FAST_2" + # Slew rate for ATOM Domain: Fast/4 + register "slow_slew_rate_config[VR_DOMAIN_ATOM]" = "SLEW_FAST_4" + register "disable_fast_pkgc_ramp[VR_DOMAIN_IA]" = "true" + register "disable_fast_pkgc_ramp[VR_DOMAIN_GT]" = "true" + register "disable_fast_pkgc_ramp[VR_DOMAIN_ATOM]" = "true" + register "pcore_hysteresis_window_ms" = "3" + register "ecore_hysteresis_window_ms" = "3" + register "usb2_ports[0]" = "USB2_PORT_TYPE_C(OC_SKIP)" # USB2_C0 register "usb2_ports[1]" = "USB2_PORT_TYPE_C(OC_SKIP)" # USB2_C1 register "usb2_ports[2]" = "USB2_PORT_MID(OC_SKIP)" # USB HUB (USB2 Camera) @@ -121,8 +139,8 @@ chip soc/intel/pantherlake #| I2C5 | Touchscreen | #+-------------------+---------------------------+ register "common_soc_config" = "{ - /* Render OEM footer logo 100px above from the edge */ - .logo_bottom_margin = 100, + /* Render OEM footer logo 200px above from the edge */ + .logo_bottom_margin = 200, .chipset_lockdown = CHIPSET_LOCKDOWN_COREBOOT, .i2c[0] = { .speed = I2C_SPEED_FAST, @@ -261,13 +279,6 @@ chip soc/intel/pantherlake .clk_req = 6, .flags = PCIE_RP_CLK_REQ_DETECT | PCIE_RP_LTR | PCIE_RP_AER, }" - chip soc/intel/common/block/pcie/rtd3 - register "is_storage" = "true" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_B16)" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_B09)" - register "srcclk_pin" = "6" - device generic 0 on end - end end # Gen4 M.2 SSD device ref cnvi_wifi on @@ -280,7 +291,12 @@ chip soc/intel/pantherlake end end # CNVi - device ref cnvi_bluetooth on end + device ref cnvi_bluetooth on + chip soc/intel/common/block/cnvi + register "wake" = "GPE0_PME_B0" + device generic 0 on end + end + end # NOTE: i2c0 is function 0; hence it needs to be enabled when any of i2c1-5 is enabled. # TPM device is under i2c3. Therefore, i2c0 needs to be enabled anyways. @@ -333,7 +349,7 @@ chip soc/intel/pantherlake end # I2C4 device ref i2c5 on chip drivers/i2c/hid - register "generic.hid" = ""GT7936L"" + register "generic.hid" = ""GT 7936"" register "generic.desc" = ""Goodix Touchscreen"" register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_F18_IRQ)" register "generic.detect" = "1" @@ -351,7 +367,7 @@ chip soc/intel/pantherlake device i2c 0x14 on end end chip drivers/i2c/hid - register "generic.hid" = ""GT7936L"" + register "generic.hid" = ""GT 7936"" register "generic.desc" = ""Goodix Touchscreen"" register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_F18_IRQ)" register "generic.detect" = "1" diff --git a/src/mainboard/google/fatcat/variants/ruby/variant.c b/src/mainboard/google/fatcat/variants/ruby/variant.c new file mode 100644 index 00000000000..8fdfd4b8128 --- /dev/null +++ b/src/mainboard/google/fatcat/variants/ruby/variant.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +const char *get_wifi_sar_cbfs_filename(void) +{ + return get_wifi_sar_fw_config_filename(FW_CONFIG_FIELD(AP_OEM_3BIT_FIELD0)); +} diff --git a/src/mainboard/google/fizz/Kconfig b/src/mainboard/google/fizz/Kconfig index d07ce2ff10b..daaf81410ac 100644 --- a/src/mainboard/google/fizz/Kconfig +++ b/src/mainboard/google/fizz/Kconfig @@ -102,6 +102,9 @@ config UART_FOR_CONSOLE int default 2 +config CBFS_SIZE + default 0xe00000 + config USE_PM_ACPI_TIMER default n diff --git a/src/mainboard/google/fizz/Kconfig.name b/src/mainboard/google/fizz/Kconfig.name index 928afd81222..15c82802c53 100644 --- a/src/mainboard/google/fizz/Kconfig.name +++ b/src/mainboard/google/fizz/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Fizz" +comment "Fizz (Intel KabyLake/Kabylake-R (7th/8th Gen))" config BOARD_GOOGLE_FIZZ bool "-> Fizz (Multiple devices - See help text)" diff --git a/src/mainboard/google/foster/Kconfig.name b/src/mainboard/google/foster/Kconfig.name index 6a22b74832a..12bc11bb370 100644 --- a/src/mainboard/google/foster/Kconfig.name +++ b/src/mainboard/google/foster/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Foster" +comment "Foster (Nvidia Tegra X1 (T210))" config BOARD_GOOGLE_FOSTER bool "-> Foster" diff --git a/src/mainboard/google/gale/Kconfig.name b/src/mainboard/google/gale/Kconfig.name index 56d3181fad8..a43fd963cd0 100644 --- a/src/mainboard/google/gale/Kconfig.name +++ b/src/mainboard/google/gale/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Gale" +comment "Gale (Qualcomm IPQ4019)" config BOARD_GOOGLE_GALE bool "-> Gale (Google WiFi)" diff --git a/src/mainboard/google/geralt/Kconfig.name b/src/mainboard/google/geralt/Kconfig.name index 4195d6f3fda..285fd637c69 100644 --- a/src/mainboard/google/geralt/Kconfig.name +++ b/src/mainboard/google/geralt/Kconfig.name @@ -1,9 +1,9 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Geralt" +comment "Geralt (MediaTek Kompanio 838 (MT8188))" config BOARD_GOOGLE_GERALT bool "-> Geralt" config BOARD_GOOGLE_CIRI - bool "-> Ciri" + bool "-> Ciri (Lenovo Chromebook Duet Gen9 (11M889))" diff --git a/src/mainboard/google/glados/Kconfig b/src/mainboard/google/glados/Kconfig index 811a03deac0..746e326c04a 100644 --- a/src/mainboard/google/glados/Kconfig +++ b/src/mainboard/google/glados/Kconfig @@ -10,6 +10,7 @@ config BOARD_GOOGLE_BASEBOARD_GLADOS select EC_GOOGLE_CHROMEEC_BOARDID select EC_GOOGLE_CHROMEEC_LPC select EC_GOOGLE_CHROMEEC_MEC + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select EC_GOOGLE_CHROMEEC_PD select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES @@ -127,6 +128,9 @@ config UART_FOR_CONSOLE int default 2 +config CBFS_SIZE + default 0xe00000 + config CONSOLE_SERIAL bool default n diff --git a/src/mainboard/google/glados/Kconfig.name b/src/mainboard/google/glados/Kconfig.name index 57711d40bec..50d5b0d9a5f 100644 --- a/src/mainboard/google/glados/Kconfig.name +++ b/src/mainboard/google/glados/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Glados" +comment "Glados (Intel Skylake (6th Gen))" config BOARD_GOOGLE_ASUKA bool "-> Asuka (Dell Chromebook 13 3380)" diff --git a/src/mainboard/google/gru/Kconfig.name b/src/mainboard/google/gru/Kconfig.name index f72a350816b..e6b55b7e1aa 100644 --- a/src/mainboard/google/gru/Kconfig.name +++ b/src/mainboard/google/gru/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Gru" +comment "Gru (Rockchip RK3399)" config BOARD_GOOGLE_KEVIN bool "-> Kevin (Samsung Chromebook Plus)" diff --git a/src/mainboard/google/guybrush/Kconfig.name b/src/mainboard/google/guybrush/Kconfig.name index fc1f8644750..b62ee3154a9 100644 --- a/src/mainboard/google/guybrush/Kconfig.name +++ b/src/mainboard/google/guybrush/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Guybrush" +comment "Guybrush (AMD Ryzen Mobile 5000 (Cezanne))" config BOARD_GOOGLE_DEWATT bool "-> Dewatt (Acer Chromebook Spin 514)" diff --git a/src/mainboard/google/hatch/Kconfig b/src/mainboard/google/hatch/Kconfig index 1336c65eedd..1f9a7d2eb05 100644 --- a/src/mainboard/google/hatch/Kconfig +++ b/src/mainboard/google/hatch/Kconfig @@ -125,6 +125,10 @@ config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/chromeos-16MiB.fmd" if BOARD_ROMSIZE_KB_16384 && CHROMEOS default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/chromeos-32MiB.fmd" if BOARD_ROMSIZE_KB_32768 && CHROMEOS +config CBFS_SIZE + default 0xc00000 if BOARD_ROMSIZE_KB_16384 + default 0x1000000 if BOARD_ROMSIZE_KB_32768 + config MAINBOARD_DIR default "google/hatch" diff --git a/src/mainboard/google/hatch/Kconfig.name b/src/mainboard/google/hatch/Kconfig.name index 57441dc8205..2dd8ef88a0b 100644 --- a/src/mainboard/google/hatch/Kconfig.name +++ b/src/mainboard/google/hatch/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Hatch" +comment "Hatch (Intel CometLake (10th Gen))" config BOARD_GOOGLE_AKEMI bool "-> Akemi (IdeaPad Flex 5/5i Chromebook)" diff --git a/src/mainboard/google/hatch/cfr.c b/src/mainboard/google/hatch/cfr.c index 76f12e232cc..3ddcdb1a194 100644 --- a/src/mainboard/google/hatch/cfr.c +++ b/src/mainboard/google/hatch/cfr.c @@ -1,4 +1,3 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ #include @@ -7,17 +6,13 @@ #include #include -static const struct sm_object touchpad_wake = SM_DECLARE_ENUM({ +static const struct sm_object touchpad_wake = SM_DECLARE_BOOL({ .opt_name = "touchpad_wake", .ui_name = "Touchpad Wake", .ui_helptext = "Enable or disable touchpad wake from sleep.\n" "Disabled by default to prevent random wakeups when\n" "the system is moved while sleeping.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = false, }); static struct sm_obj_form system = { diff --git a/src/mainboard/google/hatch/variants/kindred/Makefile.mk b/src/mainboard/google/hatch/variants/kindred/Makefile.mk index 767e119dbce..1676fd97988 100644 --- a/src/mainboard/google/hatch/variants/kindred/Makefile.mk +++ b/src/mainboard/google/hatch/variants/kindred/Makefile.mk @@ -12,5 +12,3 @@ SPD_SOURCES += 16G_3200 # 0b111 bootblock-y += gpio.c ramstage-y += gpio.c ramstage-y += variant.c - -$(call add_vbt_to_cbfs, vbt-kled.bin, kled-data.vbt) diff --git a/src/mainboard/google/hatch/variants/kindred/kled-data.vbt b/src/mainboard/google/hatch/variants/kindred/kled-data.vbt deleted file mode 100644 index f07cb69c062..00000000000 Binary files a/src/mainboard/google/hatch/variants/kindred/kled-data.vbt and /dev/null differ diff --git a/src/mainboard/google/hatch/variants/kindred/variant.c b/src/mainboard/google/hatch/variants/kindred/variant.c index cf23608f671..e379419c0f5 100644 --- a/src/mainboard/google/hatch/variants/kindred/variant.c +++ b/src/mainboard/google/hatch/variants/kindred/variant.c @@ -5,7 +5,6 @@ #include #include #include -#include #include void variant_devtree_update(void) @@ -45,13 +44,3 @@ const char *get_wifi_sar_cbfs_filename(void) return "wifi_sar-kled.hex"; return WIFI_SAR_CBFS_DEFAULT_FILENAME; } - -const char *mainboard_vbt_filename(void) -{ - uint32_t sku_id = google_chromeec_get_board_sku(); - - if (sku_id == 1 || sku_id == 2 || sku_id == 3 || sku_id == 4) - return "vbt-kled.bin"; - else - return "vbt.bin"; -} diff --git a/src/mainboard/google/hatch/variants/kohaku/overridetree.cb b/src/mainboard/google/hatch/variants/kohaku/overridetree.cb index 59704cafa11..d8c268d7061 100644 --- a/src/mainboard/google/hatch/variants/kohaku/overridetree.cb +++ b/src/mainboard/google/hatch/variants/kohaku/overridetree.cb @@ -164,7 +164,7 @@ chip soc/intel/cannonlake end # I2C #1 device ref i2c2 on chip drivers/i2c/hid - register "generic.hid" = ""WCOM50C1"" + register "generic.hid" = ""WCOM006C"" register "generic.desc" = ""WCOM Digitizer"" register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_C7_IRQ)" register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_C15)" diff --git a/src/mainboard/google/herobrine/Kconfig.name b/src/mainboard/google/herobrine/Kconfig.name index 71b93c2d35e..7e9ef66d62c 100644 --- a/src/mainboard/google/herobrine/Kconfig.name +++ b/src/mainboard/google/herobrine/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Herobrine" +comment "Herobrine (Qualcomm Snapdragon 7c+ Gen3 (SC7280))" config BOARD_GOOGLE_HEROBRINE bool "-> Herobrine" @@ -15,16 +15,16 @@ config BOARD_GOOGLE_PIGLIN bool "-> Piglin" config BOARD_GOOGLE_HOGLIN - bool "-> Hoglin" + bool "-> Hoglin" config BOARD_GOOGLE_VILLAGER - bool "-> Villager" + bool "-> Villager" config BOARD_GOOGLE_EVOKER - bool "-> Evoker" + bool "-> Evoker" config BOARD_GOOGLE_ZOGLIN - bool "-> Zoglin" + bool "-> Zoglin" config BOARD_GOOGLE_ZOMBIE bool "-> Zombie" diff --git a/src/mainboard/google/jecht/Kconfig b/src/mainboard/google/jecht/Kconfig index 0ced2cd61db..0edbf5ebab8 100644 --- a/src/mainboard/google/jecht/Kconfig +++ b/src/mainboard/google/jecht/Kconfig @@ -55,6 +55,9 @@ config MAINBOARD_PART_NUMBER config INTEL_GMA_VBT_FILE default "src/mainboard/\$(MAINBOARDDIR)/data.vbt" if !BOARD_GOOGLE_TIDUS +config CBFS_SIZE + default 0x600000 + config MAINBOARD_SMBIOS_MANUFACTURER string default "GOOGLE" diff --git a/src/mainboard/google/jecht/Kconfig.name b/src/mainboard/google/jecht/Kconfig.name index 2da82b422d4..8528d020ec6 100644 --- a/src/mainboard/google/jecht/Kconfig.name +++ b/src/mainboard/google/jecht/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Jecht" +comment "Jecht (Intel Broadwell (5th Gen))" config BOARD_GOOGLE_GUADO bool "-> Guado (ASUS Chromebox CN62)" diff --git a/src/mainboard/google/jecht/cfr.c b/src/mainboard/google/jecht/cfr.c index 9f4d19088e7..199f2e54d99 100644 --- a/src/mainboard/google/jecht/cfr.c +++ b/src/mainboard/google/jecht/cfr.c @@ -1,4 +1,3 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ #include diff --git a/src/mainboard/google/jecht/devicetree.cb b/src/mainboard/google/jecht/devicetree.cb index ba8167cda2a..8de489c0ee7 100644 --- a/src/mainboard/google/jecht/devicetree.cb +++ b/src/mainboard/google/jecht/devicetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell # Disable eDP Hotplug register "gpu_dp_d_hotplug" = "0x00" @@ -12,7 +12,7 @@ chip soc/intel/broadwell register "dq_pins_interleaved" = "true" chip cpu/intel/haswell - device cpu_cluster 0 on ops broadwell_cpu_bus_ops end + device cpu_cluster 0 on ops haswell_cpu_bus_ops end end device domain 0 on @@ -21,7 +21,7 @@ chip soc/intel/broadwell device pci 02.0 on end # vga controller device pci 03.0 on end # mini-hd audio - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # SuperIO range is 0x700-0x73f register "gen2_dec" = "0x003c0701" diff --git a/src/mainboard/google/jecht/dsdt.asl b/src/mainboard/google/jecht/dsdt.asl index 1aeb08cdced..62c8b58fe60 100644 --- a/src/mainboard/google/jecht/dsdt.asl +++ b/src/mainboard/google/jecht/dsdt.asl @@ -18,8 +18,8 @@ DefinitionBlock( #include // global NVS and variables - #include - #include + #include + #include // CPU #include @@ -28,7 +28,7 @@ DefinitionBlock( Device (PCI0) { #include - #include + #include } } diff --git a/src/mainboard/google/kahlee/Kconfig b/src/mainboard/google/kahlee/Kconfig index b3fb71a04e5..157c317a620 100644 --- a/src/mainboard/google/kahlee/Kconfig +++ b/src/mainboard/google/kahlee/Kconfig @@ -103,6 +103,9 @@ config FMDFILE but in some cases more complex setups are required. When an fmd is specified, it overrides the default format. +config CBFS_SIZE + default 0x1000000 + config MAX_CPUS int default 4 diff --git a/src/mainboard/google/kahlee/Kconfig.name b/src/mainboard/google/kahlee/Kconfig.name index b102307bd2f..46f1b763a8b 100644 --- a/src/mainboard/google/kahlee/Kconfig.name +++ b/src/mainboard/google/kahlee/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Kahlee" +comment "Kahlee (AMD StoneyRidge)" config BOARD_GOOGLE_ALEENA bool "-> Aleena/Kasumi (Acer Chromebook 315 (CB315-2H), 311 (C721) / Spin 311 (R721T))" diff --git a/src/mainboard/google/kukui/Kconfig.name b/src/mainboard/google/kukui/Kconfig.name index d7f54f6d50c..425429834a7 100644 --- a/src/mainboard/google/kukui/Kconfig.name +++ b/src/mainboard/google/kukui/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Kukui" +comment "Kukui (MediaTek Kompanio 500 (MT8183))" config BOARD_GOOGLE_KUKUI bool "-> Kukui" @@ -12,7 +12,7 @@ config BOARD_GOOGLE_KODAMA bool "-> Kodama (Lenovo 10e Chromebook Tablet)" config BOARD_GOOGLE_KAKADU - bool "-> Kakadu" + bool "-> Kakadu (ASUS Chromebook Detachable CM3)" config BOARD_GOOGLE_FLAPJACK bool "-> Flapjack" @@ -20,7 +20,7 @@ config BOARD_GOOGLE_FLAPJACK config BOARD_GOOGLE_KATSU bool "-> Katsu (ASUS Chromebook Detachable CZ1)" -comment "Jacuzzi" +comment "Jacuzzi (MediaTek Kompanio 500 (MT8183))" config BOARD_GOOGLE_JACUZZI bool "-> Jacuzzi" @@ -29,7 +29,7 @@ config BOARD_GOOGLE_JUNIPER bool "-> Juniper (Acer Chromebook Spin 311 (CP311-3H))" config BOARD_GOOGLE_KAPPA - bool "-> Kappa" + bool "-> Kappa (HP Chromebook 11a)" config BOARD_GOOGLE_DAMU bool "-> Damu (ASUS Chromebook Flip CM3 (CM3200))" @@ -41,7 +41,7 @@ config BOARD_GOOGLE_STERN bool "-> Stern" config BOARD_GOOGLE_WILLOW - bool "-> Willow" + bool "-> Willow (Acer Chromebook 311 (C722/C722T))" config BOARD_GOOGLE_ESCHE bool "-> Esche (HP Chromebook 11MK G9 EE)" @@ -50,16 +50,16 @@ config BOARD_GOOGLE_BURNET bool "-> Burnet (HP Chromebook x360 11MK G3 EE)" config BOARD_GOOGLE_FENNEL - bool "-> Fennel" + bool "-> Fennel (Lenovo IdeaPad 3 Chromebook)" config BOARD_GOOGLE_COZMO bool "-> Cozmo (Acer Chromebook 314 (CB314-2H/CB314-2HT))" config BOARD_GOOGLE_MAKOMO - bool "-> Makomo" + bool "-> Makomo (Lenovo 100e Chromebook (2nd Gen))" config BOARD_GOOGLE_MUNNA bool "-> Munna" config BOARD_GOOGLE_PICO - bool "-> Pico" + bool "-> Pico (Acer Chromebook Spin 311)" diff --git a/src/mainboard/google/link/Kconfig b/src/mainboard/google/link/Kconfig index 86dd014f2a6..ab889f1c24d 100644 --- a/src/mainboard/google/link/Kconfig +++ b/src/mainboard/google/link/Kconfig @@ -10,6 +10,7 @@ config BOARD_SPECIFIC_OPTIONS select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_AUTO_FAN_CTRL + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select EC_GOOGLE_CHROMEEC_LPC select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES @@ -37,6 +38,9 @@ config MAINBOARD_DIR config MAINBOARD_PART_NUMBER default "Link" +config CBFS_SIZE + default 0x600000 + config MAINBOARD_SMBIOS_MANUFACTURER string default "GOOGLE" diff --git a/src/mainboard/google/link/Kconfig.name b/src/mainboard/google/link/Kconfig.name index 87d548bd642..d53ffa10bb2 100644 --- a/src/mainboard/google/link/Kconfig.name +++ b/src/mainboard/google/link/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Link" +comment "Link (Intel IvyBridge (3rd Gen))" config BOARD_GOOGLE_LINK bool "-> Link (Google Chromebook Pixel (2013))" diff --git a/src/mainboard/google/link/hda_verb.c b/src/mainboard/google/link/hda_verb.c index d3309cd6d78..7199e5a6f1c 100644 --- a/src/mainboard/google/link/hda_verb.c +++ b/src/mainboard/google/link/hda_verb.c @@ -72,31 +72,66 @@ const u32 cim_verb_data[] = { AZALIA_SUBVENDOR(0, 0x10280550), /* Pin Complex (NID 0x0B) Port-G Analog Unknown Speaker at Int N/A */ - AZALIA_PIN_CFG(0, 0x0b, 0x901700f0), + AZALIA_PIN_CFG(0, 0x0b, AZALIA_PIN_DESC( + AZALIA_INTEGRATED, + AZALIA_INTERNAL, + AZALIA_SPEAKER, + AZALIA_OTHER_ANALOG, + AZALIA_COLOR_UNKNOWN, + AZALIA_NO_JACK_PRESENCE_DETECT, + 15, 0)), /* Pin Complex (NID 0x0C) N/C */ - AZALIA_PIN_CFG(0, 0x0c, 0x70f000f0), + AZALIA_PIN_CFG(0, 0x0c, AZALIA_PIN_CFG_NC(0)), /* Pin Complex (NID 0x0D) N/C */ - AZALIA_PIN_CFG(0, 0x0d, 0x70f000f0), + AZALIA_PIN_CFG(0, 0x0d, AZALIA_PIN_CFG_NC(0)), /* Pin Complex (NID 0x0E) N/C */ - AZALIA_PIN_CFG(0, 0x0e, 0x70f000f0), + AZALIA_PIN_CFG(0, 0x0e, AZALIA_PIN_CFG_NC(0)), /* Pin Complex (NID 0x0F) N/C */ - AZALIA_PIN_CFG(0, 0x0f, 0x70f000f0), + AZALIA_PIN_CFG(0, 0x0f, AZALIA_PIN_CFG_NC(0)), /* Pin Complex (NID 0x10) Port-D 1/8 Black HP Out at Ext Left */ - AZALIA_PIN_CFG(0, 0x10, 0x032110f0), + AZALIA_PIN_CFG(0, 0x10, AZALIA_PIN_DESC( + AZALIA_JACK, + AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_LEFT, + AZALIA_HP_OUT, + AZALIA_STEREO_MONO_1_8, + AZALIA_BLACK, + AZALIA_JACK_PRESENCE_DETECT, + 15, 0)), /* Pin Complex (NID 0x11) Port-B Click Mic */ - AZALIA_PIN_CFG(0, 0x11, 0x90a700f0), + AZALIA_PIN_CFG(0, 0x11, AZALIA_PIN_DESC( + AZALIA_INTEGRATED, + AZALIA_INTERNAL, + AZALIA_MIC_IN, + AZALIA_OTHER_ANALOG, + AZALIA_COLOR_UNKNOWN, + AZALIA_NO_JACK_PRESENCE_DETECT, + 15, 0)), /* Pin Complex (NID 0x12) Port-C Combo Jack Mic or D-Mic */ - AZALIA_PIN_CFG(0, 0x12, 0x03a110f0), + AZALIA_PIN_CFG(0, 0x12, AZALIA_PIN_DESC( + AZALIA_JACK, + AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_LEFT, + AZALIA_MIC_IN, + AZALIA_STEREO_MONO_1_8, + AZALIA_BLACK, + AZALIA_JACK_PRESENCE_DETECT, + 15, 0)), /* Pin Complex (NID 0x13) What you hear */ - AZALIA_PIN_CFG(0, 0x13, 0x90d600f0), + AZALIA_PIN_CFG(0, 0x13, AZALIA_PIN_DESC( + AZALIA_INTEGRATED, + AZALIA_INTERNAL, + AZALIA_DIGITAL_OTHER_IN, + AZALIA_OTHER_DIGITAL, + AZALIA_COLOR_UNKNOWN, + AZALIA_JACK_PRESENCE_DETECT, + 15, 0)), /* coreboot specific header */ 0x80862806, // Codec Vendor / Device ID: Intel CougarPoint HDMI diff --git a/src/mainboard/google/mistral/Kconfig.name b/src/mainboard/google/mistral/Kconfig.name index b8f6fa2d9fb..0c7517356a0 100644 --- a/src/mainboard/google/mistral/Kconfig.name +++ b/src/mainboard/google/mistral/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Mistral" +comment "Mistral (Qualcomm Dragonwing QCS405)" config BOARD_GOOGLE_MISTRAL bool "-> Mistral" diff --git a/src/mainboard/google/myst/Kconfig.name b/src/mainboard/google/myst/Kconfig.name index 56fcc1924f4..da8bb4b4e75 100644 --- a/src/mainboard/google/myst/Kconfig.name +++ b/src/mainboard/google/myst/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Myst" +comment "Myst (AMD Ryzen Mobile 7000 (Phoenix))" config BOARD_GOOGLE_MYST bool "-> Myst" diff --git a/src/mainboard/google/nyan/Kconfig.name b/src/mainboard/google/nyan/Kconfig.name index 8bd2621b5b2..db1dd422420 100644 --- a/src/mainboard/google/nyan/Kconfig.name +++ b/src/mainboard/google/nyan/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Nyan" +comment "Nyan (NVIDIA Tegra K1 (CD570M))" config BOARD_GOOGLE_NYAN bool "-> Nyan" diff --git a/src/mainboard/google/nyan_big/Kconfig.name b/src/mainboard/google/nyan_big/Kconfig.name index dc841b15a5c..bda75aa648c 100644 --- a/src/mainboard/google/nyan_big/Kconfig.name +++ b/src/mainboard/google/nyan_big/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Nyan Big" +comment "Nyan Big (Nvidia Tegra K1 (T124))" config BOARD_GOOGLE_NYAN_BIG bool "-> Nyan Big (Acer Chromebook 13 (CB5-311))" diff --git a/src/mainboard/google/nyan_blaze/Kconfig.name b/src/mainboard/google/nyan_blaze/Kconfig.name index aae2fb7b3da..a16805580ab 100644 --- a/src/mainboard/google/nyan_blaze/Kconfig.name +++ b/src/mainboard/google/nyan_blaze/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Nyan Blaze" +comment "Nyan Blaze (NVIDIA Tegra K1 (CD570M))" config BOARD_GOOGLE_NYAN_BLAZE bool "-> Nyan Blaze (HP Chromebook 14 G3)" diff --git a/src/mainboard/google/oak/Kconfig.name b/src/mainboard/google/oak/Kconfig.name index ceba0376558..9829b55c32d 100644 --- a/src/mainboard/google/oak/Kconfig.name +++ b/src/mainboard/google/oak/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Oak" +comment "Oak (MediaTek Kompanio 500 (MT8173))" config BOARD_GOOGLE_OAK bool "-> Oak" diff --git a/src/mainboard/google/ocelot/Kconfig b/src/mainboard/google/ocelot/Kconfig index 1576db36719..d5e37c742f0 100644 --- a/src/mainboard/google/ocelot/Kconfig +++ b/src/mainboard/google/ocelot/Kconfig @@ -98,8 +98,6 @@ config BOARD_GOOGLE_MODEL_OJAL config BOARD_GOOGLE_MODEL_OCICAT def_bool n select BOARD_GOOGLE_BASEBOARD_OCELOT - select DRIVERS_GENERIC_BAYHUB_LV2 - select DRIVERS_GENERIC_MAX98357A select DRIVERS_INTEL_TOUCH select FSP_UGOP_EARLY_SIGN_OF_LIFE select SPD_CACHE_ENABLE @@ -137,6 +135,7 @@ config BOARD_GOOGLE_OJAL config BOARD_GOOGLE_OCICAT select BOARD_GOOGLE_MODEL_OCICAT + select EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC if BOARD_GOOGLE_OCELOT_COMMON @@ -146,7 +145,7 @@ config BASEBOARD_DIR config CHROMEOS select EC_GOOGLE_CHROMEEC_SWITCHES - select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC + select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC if EC_GOOGLE_CHROMEEC_MEC select GBB_FLAG_FORCE_DEV_BOOT_USB select GBB_FLAG_FORCE_MANUAL_RECOVERY select HAS_RECOVERY_MRC_CACHE @@ -211,6 +210,9 @@ config UART_FOR_CONSOLE int default 0 +config CBFS_SIZE + default 0x1000000 + config USE_PM_ACPI_TIMER default n @@ -228,4 +230,13 @@ config OVERRIDE_DEVICETREE config VBOOT select VBOOT_LID_SWITCH +config OCELOT_VGA_MODE12_SUPPORT + bool "Enable VGA Mode 12 support for eSOL" + default n + depends on FSP_UGOP_EARLY_SIGN_OF_LIFE + select ROMSTAGE_VGA + select FSP_VGA_MODE12 + help + Select this if the FSP supports VGA mode 12 for eSOL. + endif # BOARD_GOOGLE_OCELOT_COMMON diff --git a/src/mainboard/google/ocelot/Kconfig.name b/src/mainboard/google/ocelot/Kconfig.name index a57bc43c45b..8e5badc67d9 100644 --- a/src/mainboard/google/ocelot/Kconfig.name +++ b/src/mainboard/google/ocelot/Kconfig.name @@ -1,33 +1,33 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Ocelot" +comment "Ocelot (Intel WildcatLake (Ultra 3rd Gen))" config BOARD_GOOGLE_KODKOD - bool "-> Kodkod" + bool "-> Kodkod" config BOARD_GOOGLE_MATSU - bool "-> Matsu" + bool "-> Matsu" config BOARD_GOOGLE_OCELOT - bool "-> Ocelot" + bool "-> Ocelot" config BOARD_GOOGLE_OCELOTITE - bool "-> Ocelotite" + bool "-> Ocelotite" config BOARD_GOOGLE_OCELOTMCHP - bool "-> Ocelotmchp" + bool "-> Ocelotmchp" config BOARD_GOOGLE_OJAL - bool "-> Ojal" + bool "-> Ojal" config BOARD_GOOGLE_OCELOT4ES - bool "-> Ocelot4ES" + bool "-> Ocelot4ES" config BOARD_GOOGLE_OCELOTITE4ES - bool "-> Ocelotite4ES" + bool "-> Ocelotite4ES" config BOARD_GOOGLE_OCELOTMCHP4ES - bool "-> Ocelotmchp4ES" + bool "-> Ocelotmchp4ES" config BOARD_GOOGLE_OCICAT - bool "-> Ocicat" + bool "-> Ocicat" diff --git a/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb b/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb index e2ea33173bb..299c770d5e3 100644 --- a/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb +++ b/src/mainboard/google/ocelot/variants/baseboard/ocelot/devicetree.cb @@ -29,19 +29,25 @@ chip soc/intel/pantherlake register "tcss_ports[0]" = "TCSS_PORT_EMPTY" # Disable USB-C Port 0 register "tcss_ports[1]" = "TCSS_PORT_EMPTY" # Disable USB-C Port 1 + # Acoustic Noise settings and slew rate configuration: + # Slew rate for GT Domain: Fast/4 + register "enable_acoustic_noise_mitigation" = "true" + register "disable_fast_pkgc_ramp[VR_DOMAIN_GT]" = "true" + register "slow_slew_rate_config[VR_DOMAIN_GT]" = "SLEW_FAST_4" + # Enable SAGv register "sagv" = "SAGV_ENABLED" register "sagv_freq_mhz[0]" = "2400" register "sagv_gear[0]" = "GEAR_4" - register "sagv_freq_mhz[1]" = "3200" + register "sagv_freq_mhz[1]" = "4800" register "sagv_gear[1]" = "GEAR_4" - register "sagv_freq_mhz[2]" = "6000" + register "sagv_freq_mhz[2]" = "6400" register "sagv_gear[2]" = "GEAR_4" - register "sagv_freq_mhz[3]" = "6400" + register "sagv_freq_mhz[3]" = "7467" register "sagv_gear[3]" = "GEAR_4" # Enable s0ix @@ -61,15 +67,14 @@ chip soc/intel/pantherlake # Enable Energy Reporting register "pch_pm_energy_report_enable" = "true" - # Reference: 858124 Power Delivery Guide Rev1p0, 830097 Powermap Rev1p1 + # Reference: 844458 MOW WW03 # fast_vmode_i_trip values are derived from ICCMax with a safety margin. # ITRIP_NOM is approximately 0.70 of ICCMax # TODO: Update with actual i_trip values. - - register "fast_vmode_i_trip[WCL_CORE]" = "{ - [VR_DOMAIN_IA] = 35 * 4, - [VR_DOMAIN_GT] = 35 * 4, - [VR_DOMAIN_SA] = 24 * 4 + register "enable_fast_vmode[VR_DOMAIN_GT]" = "true" + register "cep_enable[VR_DOMAIN_GT]" = "true" + register "fast_vmode_i_trip[WCL_SKU_1]" = "{ + [VR_DOMAIN_GT] = 25 * 4, }" register "serial_io_uart_mode" = "{ @@ -90,6 +95,7 @@ chip soc/intel/pantherlake register "pch_hda_idisp_codec_enable" = "true" register "disable_progress_bar" = "true" + register "vga_cd_clk_freq_sel" = "CD_CLK_461MHZ" device domain 0 on device ref dtt on end diff --git a/src/mainboard/google/ocelot/variants/baseboard/ocelot/ramstage.c b/src/mainboard/google/ocelot/variants/baseboard/ocelot/ramstage.c index 43a82d12c3c..e68010d3b72 100644 --- a/src/mainboard/google/ocelot/variants/baseboard/ocelot/ramstage.c +++ b/src/mainboard/google/ocelot/variants/baseboard/ocelot/ramstage.c @@ -3,6 +3,51 @@ #include #include +/* + * SKU_ID, TDP (Watts), pl1_min (milliWatts), pl1_max (milliWatts), + * pl2_min (milliWatts), pl2_max (milliWatts), pl4 (milliWatts) + */ +/* Define a macro for the common power limit values for WCL */ +#define COMMON_WCL_POWER_LIMITS \ + .pl1_min_power = 10000, \ + .pl1_max_power = 15000, \ + .pl2_min_power = 35000, \ + .pl2_max_power = 35000, \ + .pl4_power = 45000 + +const struct cpu_tdp_power_limits power_optimized_limits[] = { + { + .mch_id = PCI_DID_INTEL_WCL_ID_1, + .cpu_tdp = TDP_15W, + .power_limits_index = WCL_CORE, + COMMON_WCL_POWER_LIMITS + }, + { + .mch_id = PCI_DID_INTEL_WCL_ID_2, + .cpu_tdp = TDP_15W, + .power_limits_index = WCL_CORE, + COMMON_WCL_POWER_LIMITS + }, + { + .mch_id = PCI_DID_INTEL_WCL_ID_3, + .cpu_tdp = TDP_15W, + .power_limits_index = WCL_CORE, + COMMON_WCL_POWER_LIMITS + }, + { + .mch_id = PCI_DID_INTEL_WCL_ID_4, + .cpu_tdp = TDP_15W, + .power_limits_index = WCL_CORE, + COMMON_WCL_POWER_LIMITS + }, + { + .mch_id = PCI_DID_INTEL_WCL_ID_5, + .cpu_tdp = TDP_15W, + .power_limits_index = WCL_CORE, + COMMON_WCL_POWER_LIMITS + }, +}; + /* * Placeholder to check if variant has support for barrel jack for powering * on the device. @@ -21,7 +66,9 @@ void baseboard_devtree_update(void) if (variant_is_barrel_charger_present()) return; - /* TODO: Add power limit override code for Wildcat Lake */ - if (!google_chromeec_is_battery_present()) - printk(BIOS_DEBUG, "TODO: Add support for power optimized boot configuration limits\n"); + if (!google_chromeec_is_battery_present()) { + printk(BIOS_INFO, "Battery not connected, booting with reduced PL values\n"); + variant_update_cpu_power_limits(power_optimized_limits, + ARRAY_SIZE(power_optimized_limits)); + } } diff --git a/src/mainboard/google/ocelot/variants/kodkod/gpio.c b/src/mainboard/google/ocelot/variants/kodkod/gpio.c index e8884d9c433..2259bda8c7d 100644 --- a/src/mainboard/google/ocelot/variants/kodkod/gpio.c +++ b/src/mainboard/google/ocelot/variants/kodkod/gpio.c @@ -125,8 +125,8 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_C13, NONE), /* GPP_C14: NC */ PAD_NC(GPP_C14, NONE), - /* GPP_C15: SOC_FPS_RST# */ - PAD_CFG_GPO_LOCK(GPP_C15, 1, LOCK_CONFIG), + /* GPP_C15: NC */ + PAD_NC(GPP_C15, NONE), /* GPP_C16: NC */ PAD_NC(GPP_C16, NONE), /* GPP_C17: NC */ @@ -279,10 +279,10 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_H04, NONE), /* GPP_H05: NC */ PAD_NC(GPP_H05, NONE), - /* GPP_H06: SOC_I2C_3_SDA_iPCM */ - PAD_CFG_NF(GPP_H06, NONE, DEEP, NF1), - /* GPP_H07: SOC_I2C_3_SCL_iPCM */ - PAD_CFG_NF(GPP_H07, NONE, DEEP, NF1), + /* GPP_H06: NC */ + PAD_NC(GPP_H06, NONE), + /* GPP_H07: NC */ + PAD_NC(GPP_H07, NONE), /* GPP_H08: UART_0_CRXD_DTXD */ PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), /* GPP_H09: UART_0_CTXD_DRXD */ @@ -372,10 +372,6 @@ static const struct pad_config gpio_table[] = { static const struct pad_config early_gpio_table[] = { /* GPP_B17: SOC_SPI_TPM_INT# */ PAD_CFG_GPI_APIC_LOCK(GPP_B17, NONE, LEVEL, INVERT, LOCK_CONFIG), - /* GPP_H06: SOC_I2C_3_SDA_iPCM */ - PAD_CFG_NF(GPP_H06, NONE, DEEP, NF1), - /* GPP_H07: SOC_I2C_3_SCL_iPCM */ - PAD_CFG_NF(GPP_H07, NONE, DEEP, NF1), /* GPP_H08: UART_0_CRXD_DTXD */ PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), /* GPP_H09: UART_0_CTXD_DRXD */ @@ -392,8 +388,6 @@ static const struct pad_config romstage_gpio_table[] = { PAD_CFG_NF(GPP_C00, NONE, DEEP, NF1), /* GPP_C01: SPD_SOC_SMBDATA */ PAD_CFG_NF(GPP_C01, NONE, DEEP, NF1), - /* GPP_C15: FPS_RST_N */ - PAD_CFG_GPO(GPP_C15, 0, PLTRST), }; const struct pad_config *variant_gpio_table(size_t *num) diff --git a/src/mainboard/google/ocelot/variants/matsu/overridetree.cb b/src/mainboard/google/ocelot/variants/matsu/overridetree.cb index 59d6226735a..8da38fe1d89 100644 --- a/src/mainboard/google/ocelot/variants/matsu/overridetree.cb +++ b/src/mainboard/google/ocelot/variants/matsu/overridetree.cb @@ -337,13 +337,6 @@ chip soc/intel/pantherlake .clk_req = 3, .flags = PCIE_RP_CLK_REQ_DETECT | PCIE_RP_LTR | PCIE_RP_AER, }" - chip soc/intel/common/block/pcie/rtd3 - register "is_storage" = "true" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_H18)" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_A08)" - register "srcclk_pin" = "3" - device generic 0 on end - end end # Gen4 M.2 SSD device ref cnvi_wifi on diff --git a/src/mainboard/google/ocelot/variants/ocelot/fw_config.c b/src/mainboard/google/ocelot/variants/ocelot/fw_config.c index 818be9b9aa8..9984ef5e890 100644 --- a/src/mainboard/google/ocelot/variants/ocelot/fw_config.c +++ b/src/mainboard/google/ocelot/variants/ocelot/fw_config.c @@ -12,37 +12,36 @@ #define GPIO_CONFIGURE_PADS(t) gpio_configure_pads(t, ARRAY_SIZE(t)) static const struct pad_config i2s_enable_pads[] = { - /* I2S_MCLK1_OUT */ + /* GPP_D09: I2S_MCLK1_OUT */ PAD_CFG_NF(GPP_D09, NONE, DEEP, NF2), - /* I2S0_SCLK_HDR */ - PAD_CFG_NF(GPP_D10, NONE, DEEP, NF1), - /* I2S0_SFRM_HDR */ - PAD_CFG_NF(GPP_D11, NONE, DEEP, NF1), - /* I2S0_TXD_HDR */ - PAD_CFG_NF(GPP_D12, NONE, DEEP, NF1), - /* I2S0_RXD_HDR */ - PAD_CFG_NF(GPP_D13, NONE, DEEP, NF1), - /* I2S1_TXD_HDR */ - PAD_CFG_NF(GPP_S00, NONE, DEEP, NF1), - /* I2S1_RXD_HDR */ - PAD_CFG_NF(GPP_S01, NONE, DEEP, NF1), - /* I2S1_SCLK_HDR */ - PAD_CFG_NF(GPP_S02, NONE, DEEP, NF1), - /* I2S1_SFRM_HDR */ - PAD_CFG_NF(GPP_S03, NONE, DEEP, NF1), - /* I2S2_SCLK_HDR */ - PAD_CFG_NF(GPP_S04, NONE, DEEP, NF1), - /* I2S2_SFRM_HDR */ - PAD_CFG_NF(GPP_S05, NONE, DEEP, NF1), - /* I2S2_TXD_HDR */ - PAD_NC(GPP_S06, NONE), - /* I2S2_RXD_HDR */ - PAD_NC(GPP_S07, NONE), - - /* DMIC_CLK */ - PAD_NC(GPP_D16, NONE), - /* DMIC_DATA */ - PAD_NC(GPP_D17, NONE), + /* GPP_D10: I2S0_SCLK_HDR */ + PAD_CFG_NF(GPP_D10, NONE, DEEP, NF2), + /* GPP_D11: I2S0_SFRM_HDR */ + PAD_CFG_NF(GPP_D11, NONE, DEEP, NF2), + /* GPP_D12: I2S0_TXD_HDR */ + PAD_CFG_NF(GPP_D12, NONE, DEEP, NF2), + /* GPP_D13: I2S0_RXD_HDR */ + PAD_CFG_NF(GPP_D13, NONE, DEEP, NF2), + /* GPP_S00: I2S1_TXD_HDR */ + PAD_CFG_NF(GPP_S00, NONE, DEEP, NF6), + /* GPP_S01: I2S1_RXD_HDR */ + PAD_CFG_NF(GPP_S01, NONE, DEEP, NF6), + /* GPP_S02: I2S1_SCLK_HDR */ + PAD_CFG_NF(GPP_S02, NONE, DEEP, NF6), + /* GPP_S03: I2S1_SFRM_HDR */ + PAD_CFG_NF(GPP_S03, NONE, DEEP, NF6), + /* GPP_S04: I2S2_SCLK_HDR */ + PAD_CFG_NF(GPP_S04, NONE, DEEP, NF6), + /* GPP_S05: I2S2_SFRM_HDR */ + PAD_CFG_NF(GPP_S05, NONE, DEEP, NF6), + /* GPP_S06: DMIC1_CLK (HDR) */ + PAD_CFG_NF(GPP_S06, NONE, DEEP, NF5), + /* GPP_S07: DMIC1_DATA (HDR) */ + PAD_CFG_NF(GPP_S07, NONE, DEEP, NF5), + /* GPP_D16: DMIC_CLK */ + PAD_CFG_NF(GPP_D16, NONE, DEEP, NF3), + /* GPP_D17: DMIC_DATA */ + PAD_CFG_NF(GPP_D17, NONE, DEEP, NF3), }; static const struct pad_config hda_enable_pads[] = { @@ -93,6 +92,8 @@ static const struct pad_config sndw_alc721_enable_pads[] = { }; static const struct pad_config audio_disable_pads[] = { + /* GPP_D09: I2S_MCLK1_OUT */ + PAD_NC(GPP_D09, NONE), /* GPP_D10: HDA_BCLK (HDR) */ PAD_NC(GPP_D10, NONE), /* GPP_D11: HDA_SYNC (HDR) */ @@ -291,6 +292,27 @@ static const struct pad_config touchscreen_disable_pads[] = { PAD_NC(GPP_VGPIO3_THC0, NONE), }; +static const struct pad_config touchscreen_lpss_i2c_enable_pads[] = { + /* GPP_E11: THC0_SPI1_CLK_TCH_PNL1 */ + PAD_NC(GPP_E11, NONE), + /* GPP_E12: THC0_SPI1_IO_0_I2C4_SCL_TCH_PNL1 NF1: THC I2C0_SCL */ + PAD_CFG_NF(GPP_E12, NONE, DEEP, NF8), + /* GPP_E13: THC0_SPI1_IO_1_I2C4_SDA_TCH_PNL1 NF1: THC I2C0 SDA */ + PAD_CFG_NF(GPP_E13, NONE, DEEP, NF8), + /* GPP_E14: THC0_SPI1_IO_2_TCH_PNL1 */ + PAD_NC(GPP_E14, NONE), + /* GPP_E15: THC0_SPI1_IO_3_TCH_PNL1 */ + PAD_NC(GPP_E15, NONE), + /* GPP_E16: THC0_SPI1_RST_N_TCH_PNL1 */ + PAD_CFG_GPO(GPP_E16, 1, DEEP), + /* GPP_E17: THC0_SPI1_CS0_N_TCH_PNL1 */ + PAD_NC(GPP_E17, NONE), + /* GPP_E18: THC0_SPI1_INT_N_TCH_PNL1 */ + PAD_CFG_GPI_APIC(GPP_E18, NONE, PLTRST, LEVEL, NONE), + /* GPP_VGPIO3_THC0: THC0_WOT */ + PAD_NC(GPP_VGPIO3_THC0, NONE), +}; + static const struct pad_config touchscreen_thc_i2c_enable_pads[] = { /* GPP_E11: THC0_SPI1_CLK_TCH_PNL1 */ PAD_NC(GPP_E11, NONE), @@ -571,6 +593,8 @@ void fw_config_gpio_padbased_override(struct pad_config *padbased_table) GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_thc_spi_enable_pads); if (config->thc_wake_on_touch[0]) GPIO_PADBASED_OVERRIDE(padbased_table, thc0_enable_wake); + } else if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_LPSS_I2C_ELAN_REX))) { + GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_lpss_i2c_enable_pads); } else { GPIO_PADBASED_OVERRIDE(padbased_table, touchscreen_disable_pads); } @@ -581,7 +605,21 @@ void fw_config_gpio_padbased_override(struct pad_config *padbased_table) GPIO_PADBASED_OVERRIDE(padbased_table, ish_disable_pads); } - if (fw_config_probe(FW_CONFIG(FP, FP_PRESENT))) { + /* + * *=========================================================================* + * | Usage | GPP_E17 | + * *=========================================================================* + * | Touchscreen in THC-SPI (with rework) | NF3: THC HID-SPI CS0 | + * *---------------------------------------*---------------------------------* + * | FPS present (without rework) | NF5: GSPI0 CS0 | + * *---------------------------------------*---------------------------------* + * + * NOTE: 1. CBI selecting TS THC-SPI or implies TS rework is applied for the board. + * 2. CBI selecting TS THC-SPI with FPS present is invalid case. + */ + if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_THC_SPI))) { + /* Board has TS THC-SPI rework and does not support FPS*/ + } else if (fw_config_probe(FW_CONFIG(FP, FP_PRESENT))) { GPIO_PADBASED_OVERRIDE(padbased_table, fp_enable_pads); } else { GPIO_PADBASED_OVERRIDE(padbased_table, fp_disable_pads); diff --git a/src/mainboard/google/ocelot/variants/ocelot/overridetree.cb b/src/mainboard/google/ocelot/variants/ocelot/overridetree.cb index 117e7d86102..5a36e4bf0bc 100644 --- a/src/mainboard/google/ocelot/variants/ocelot/overridetree.cb +++ b/src/mainboard/google/ocelot/variants/ocelot/overridetree.cb @@ -21,6 +21,7 @@ fw_config option TOUCHSCREEN_NONE 0 option TOUCHSCREEN_THC_SPI 1 option TOUCHSCREEN_THC_I2C 2 + option TOUCHSCREEN_LPSS_I2C_ELAN_REX 3 end field TOUCHPAD 9 10 option TOUCHPAD_NONE 0 @@ -92,8 +93,8 @@ chip soc/intel/pantherlake [PchSerialIoIndexI2C0] = PchSerialIoPci, [PchSerialIoIndexI2C1] = PchSerialIoPci, [PchSerialIoIndexI2C2] = PchSerialIoDisabled, - [PchSerialIoIndexI2C3] = PchSerialIoDisabled, - [PchSerialIoIndexI2C4] = PchSerialIoDisabled, + [PchSerialIoIndexI2C3] = PchSerialIoPci, + [PchSerialIoIndexI2C4] = PchSerialIoPci, [PchSerialIoIndexI2C5] = PchSerialIoPci, }" @@ -108,6 +109,8 @@ chip soc/intel/pantherlake #| Field | Value | #+-------------------+---------------------------+ #| I2C1 | TPM(cr50) | + #| I2C3 | Audio | + #| I2C4 | Touchscreen (LPSS) | #| I2C5 | Touchpad | #+-------------------+---------------------------+ register "common_soc_config" = "{ @@ -118,6 +121,14 @@ chip soc/intel/pantherlake .speed = I2C_SPEED_FAST, .early_init = 1, }, + .i2c[3] = { + .speed = I2C_SPEED_FAST, + .early_init = 1, + }, + .i2c[4] = { + .speed = I2C_SPEED_FAST, + .early_init = 1, + }, .i2c[5] = { .speed = I2C_SPEED_FAST, }, @@ -532,6 +543,42 @@ chip soc/intel/pantherlake device i2c 50 on end end end + device ref i2c3 on + chip drivers/i2c/generic + register "hid" = ""RTL5682"" + register "name" = ""RT58"" + register "desc" = ""Headset Codec"" + register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_F17)" + # Set the jd_src to RT5668_JD1 for jack detection + register "property_count" = "1" + register "property_list[0].type" = "ACPI_DP_TYPE_INTEGER" + register "property_list[0].name" = ""realtek,jd-src"" + register "property_list[0].integer" = "1" + device i2c 1a on + probe AUDIO AUDIO_MAX98360_ALC5682I_I2S + end + end + end #I2C3 + device ref i2c4 on + chip drivers/i2c/hid + register "generic.hid" = ""ELAN9006"" + register "generic.desc" = ""ELAN Touchscreen"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E18_IRQ)" + # NOTE: pmc_gpe0_dw2 is GPP_E in baseboard devicetree.cb. + register "generic.wake" = "GPE0_DW2_18" + register "generic.probed" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E16)" + register "generic.reset_delay_ms" = "20" + register "generic.reset_off_delay_ms" = "2" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F08)" + register "generic.enable_delay_ms" = "1" + register "generic.has_power_resource" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 10 on + probe TOUCHSCREEN TOUCHSCREEN_LPSS_I2C_ELAN_REX + end + end + end # I2C4 device ref i2c5 on chip drivers/i2c/hid register "generic.hid" = ""HFW68H"" @@ -586,6 +633,14 @@ chip soc/intel/pantherlake end end end + chip drivers/generic/max98357a + register "hid" = ""MX98360A"" + register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_A15)" + register "sdmode_delay" = "5" + device generic 0 on + probe AUDIO AUDIO_MAX98360_ALC5682I_I2S + end + end end end end diff --git a/src/mainboard/google/ocelot/variants/ocicat/gpio.c b/src/mainboard/google/ocelot/variants/ocicat/gpio.c index 3a9a7b4ed21..3c2f44b1c9f 100644 --- a/src/mainboard/google/ocelot/variants/ocicat/gpio.c +++ b/src/mainboard/google/ocelot/variants/ocicat/gpio.c @@ -209,8 +209,8 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_E16, NONE), /* GPP_E17: NC */ PAD_NC(GPP_E17, NONE), - /* GPP_E18: THC0_SPI1_INT_N_TCH_PNL1 */ - PAD_CFG_NF(GPP_E18, NONE, DEEP, NF3), + /* GPP_E18: TCHPAD_INT_ODL */ + PAD_CFG_GPI_IRQ_WAKE(GPP_E18, NONE, PWROK, LEVEL, INVERT), /* GPP_E19: NC */ PAD_NC(GPP_E19, NONE), /* GPP_E20: NC */ @@ -242,7 +242,7 @@ static const struct pad_config gpio_table[] = { /* GPP_F09: M2_UFS_RST_N */ PAD_CFG_GPO(GPP_F09, 1, DEEP), /* GPP_F10: ISH_ACCEL_MB_INT_L */ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_F05, NONE, DEEP, NF8), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_F10, NONE, DEEP, NF8), /* GPP_F11: NC */ PAD_NC(GPP_F11, NONE), /* GPP_F12: THC_I2C1_SCL_TCH_PAD */ diff --git a/src/mainboard/google/ocelot/variants/ocicat/hda_verb.c b/src/mainboard/google/ocelot/variants/ocicat/hda_verb.c index 2f703b78eea..bb978b8120a 100644 --- a/src/mainboard/google/ocelot/variants/ocicat/hda_verb.c +++ b/src/mainboard/google/ocelot/variants/ocicat/hda_verb.c @@ -4,15 +4,16 @@ const u32 cim_verb_data[] = { /* coreboot specific header */ - 0x10ec0256, /* Codec Vendor / Device ID: Realtek ALC256 */ - 0x10ec12ac, /* Subsystem ID */ - 0x00000013, /* Number of jacks (NID entries) */ + 0x10ec0236, // Codec Vendor / Device ID: Realtek ALC236 + 0x103C8C60, // Subsystem ID + 0x00000016, // Number of jacks (NID entries) AZALIA_RESET(0x1), - /* NID 0x01, HDA Codec Subsystem ID Verb Table */ - AZALIA_SUBVENDOR(0, 0x10ec12ac), + /* NID 0x01, HDA Codec Subsystem ID Verb table */ + AZALIA_SUBVENDOR(0, 0x103C8C60), /* Pin Widget Verb Table */ + /* * DMIC * Requirement is to use PCH DMIC. Hence, @@ -20,105 +21,101 @@ const u32 cim_verb_data[] = { * AZALIA_PIN_CFG(0, 0x12, 0x90A60130), * AZALIA_PIN_CFG(0, 0x13, 0x40000000), */ + /* Pin widget 0x14 - Front (Port-D) */ AZALIA_PIN_CFG(0, 0x14, 0x90170110), /* Pin widget 0x18 - NPC */ AZALIA_PIN_CFG(0, 0x18, 0x411111F0), /* Pin widget 0x19 - MIC2 (Port-F) */ - AZALIA_PIN_CFG(0, 0x19, 0x04A11040), + AZALIA_PIN_CFG(0, 0x19, 0x03A11020), /* Pin widget 0x1A - LINE1 (Port-C) */ AZALIA_PIN_CFG(0, 0x1a, 0x411111F0), /* Pin widget 0x1B - NPC */ AZALIA_PIN_CFG(0, 0x1b, 0x411111F0), /* Pin widget 0x1D - BEEP-IN */ - AZALIA_PIN_CFG(0, 0x1d, 0x40610041), + AZALIA_PIN_CFG(0, 0x1d, 0x40600001), /* Pin widget 0x1E - NPC */ AZALIA_PIN_CFG(0, 0x1e, 0x411111F0), /* Pin widget 0x21 - HP1-OUT (Port-I) */ - AZALIA_PIN_CFG(0, 0x21, 0x04211020), + AZALIA_PIN_CFG(0, 0x21, 0x03211040), + /* * Widget node 0x20 - 1 - * Codec hidden reset and speaker power 2W/4ohm - */ - 0x0205001A, - 0x0204C003, - 0x02050038, - 0x02047901, - /* - * Widget node 0x20 - 2 - * Class D power on Reset */ 0x0205003C, 0x02040354, 0x0205003C, 0x02040314, /* - * Widget node 0x20 - 3 - * Disable AGC and set AGC limit to -1.5dB - */ - 0x02050016, - 0x02040C50, - 0x02050012, - 0x0204EBC1, - /* - * Widget node 0x20 - 4 - * Set AGC Post gain +1.5dB then Enable AGC - */ - 0x02050013, - 0x02044023, - 0x02050016, - 0x02040E50, - /* - * Widget node 0x20 - 5 - * Silence detector enabling + Set EAPD to verb control - */ - 0x02050037, - 0x0204FE15, - 0x02050010, - 0x02040020, - /* - * Widget node 0x20 - 6 - * Silence data mode Threshold (-90dB) + * Widget node 0x20 - 2 + * Set JD2 pull high */ - 0x02050030, - 0x0204A000, 0x0205001B, 0x02040A4B, + 0x0205000B, + 0x02047778, /* - * Widget node 0x20 - 7 - * Default setting-1 + * Widget node 0x20 - 3 */ - 0x05750003, - 0x05740DA3, 0x02050046, 0x02040004, - /* - * Widget node 0x20 - 8 - * support 1 pin detect two port - */ - 0x02050009, - 0x0204E003, - 0x0205000A, - 0x02047770, - /* - * Widget node 0x20 - 9 - * To set LDO1/LDO2 as default - */ - 0x02050008, - 0x02046A0C, - 0x02050008, - 0x02046A0C, + 0x05750003, + 0x057409A3, + /* disable EQ first */ + 0x05350000, + 0x0534201A, + /* Left Channel */ + 0x0535001d, + 0x05340800, + 0x0535001e, + 0x05340800, + 0x05350003, + 0x05341F7B, + 0x05350004, + 0x05340000, + /* Right Channel */ + 0x05450000, + 0x05442000, + 0x0545001d, + 0x05440800, + 0x0545001e, + 0x05440800, + 0x05450003, + 0x05441F7B, + 0x05450004, + 0x05440000, + /* enable EQ */ + 0x05350000, + 0x0534E01A, + /* 2.2W/4ohm */ + 0x02050038, + 0x02046901, + /* Disable AGC and set AGC limit to 0dB */ + 0x02050016, + 0x02044C50, + 0x02050012, + 0x0204EBC0, + /* Set AGC Front and Post gain 0dB then Enable AGC */ + 0x02050013, + 0x0204401F, + 0x02050016, + 0x02044E50, + /* Headphone Pop */ + 0x05750007, + 0x057412B2, + 0x05750007, /* Padding */ + 0x057412B2, /* Padding */ }; const u32 pc_beep_verbs[] = { /* Dos beep path - 1 */ - 0x01470C00, 0x02050036, 0x02047151, - 0x01470740, + 0x02050010, + 0x02040020, /* Dos beep path - 2 */ - 0x0143b000, - 0x01470C02, + 0x0143B000, + 0x01470740, 0x01470C02, 0x01470C02, }; diff --git a/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb b/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb index ba43e1589ed..8ed23a71480 100644 --- a/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb +++ b/src/mainboard/google/ocelot/variants/ocicat/overridetree.cb @@ -1,22 +1,32 @@ fw_config - field WIFI 2 4 - option WIFI_NONE 0 - option WIFI_CNVI_7 1 - option WIFI_PCIE_7 2 + field AUDIO_CODEC 0 2 + option AUDIO_CODEC_UNKNOWN 0 + option AUDIO_CODEC_ALC3247 1 end field STORAGE_TYPE 12 14 - option STORAGE_TYPE_UNKNOWN 0 - option STORAGE_TYPE_NVME_GEN4 1 - option STORAGE_UFS 2 + option STORAGE_TYPE_UNKNOWN 0 + option STORAGE_TYPE_NVME_GEN4 1 + option STORAGE_UFS 2 end field TOUCHSCREEN 17 18 option TOUCHSCREEN_UNKNOWN 0 - option TOUCH_ELAN_TOP 1 - option TOUCH_ELAN_DBTS 2 + option TOUCH_ELAN_TOP 1 + option TOUCH_ELAN_DBTS 2 + end + field SENSOR_HUB 23 23 + option ISH_ABSENT 0 + option ISH_PRESENT 1 + end + field WIFI_INTERFACE 26 27 + option WIFI_INTERFACE_UNKNOWN 0 + option WIFI_INTERFACE_CNVI_7 1 + option WIFI_INTERFACE_PCIE_7 2 end end chip soc/intel/pantherlake + # HD Audio + register "pch_hda_audio_link_hda_enable" = "true" register "usb2_ports[0]" = "USB2_PORT_TYPE_C(OC_SKIP)" # Type C port - various configurations - TCP0 register "usb2_ports[1]" = "USB2_PORT_TYPE_C(OC_SKIP)" # Type C port - various configurations - TCP1 @@ -236,6 +246,7 @@ chip soc/intel/pantherlake device ref thc0 on register "thc_wake_on_touch[0]" = "true" + register "thc_mode[0]" = "THC_HID_I2C_MODE" # THC0 is function 0; hence it needs to be enabled when THC1 is to be enabled. chip drivers/intel/touch register "name" = "INTEL_THC0_NAME" @@ -255,6 +266,7 @@ chip soc/intel/pantherlake end device ref thc1 on register "thc_wake_on_touch[1]" = "true" + register "thc_mode[1]" = "THC_HID_I2C_MODE" chip drivers/intel/touch register "name" = "INTEL_THC1_NAME" register "mode" = "THC_HID_I2C_MODE" @@ -263,7 +275,7 @@ chip soc/intel/pantherlake register "wake_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW_WAKE(GPP_VGPIO3_THC1)" register "active_ltr" = "1" register "idle_ltr" = "0" - register "connected_device" = "TH_SENSOR_HYNITRON" + register "connected_device" = "TH_SENSOR_ELAN" register "add_acpi_dma_property" = "true" device generic 0 alias touch_1_i2c_hynitron on end end @@ -326,7 +338,7 @@ chip soc/intel/pantherlake register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_B09)" device ref usb2_port8 on - probe WIFI WIFI_PCIE_7 + probe WIFI_INTERFACE WIFI_INTERFACE_PCIE_7 end end @@ -353,17 +365,10 @@ chip soc/intel/pantherlake .clk_req = 3, .flags = PCIE_RP_CLK_REQ_DETECT | PCIE_RP_LTR | PCIE_RP_AER, }" - chip soc/intel/common/block/pcie/rtd3 - register "is_storage" = "true" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_H18)" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_A08)" - register "srcclk_pin" = "3" - device generic 0 on end - end end # Gen4 M.2 SSD device ref pcie_rp5 on - probe WIFI WIFI_PCIE_7 + probe WIFI_INTERFACE WIFI_INTERFACE_PCIE_7 register "pcie_rp[PCIE_RP(5)]" = "{ .clk_src = 0, .clk_req = 0, @@ -382,7 +387,7 @@ chip soc/intel/pantherlake end # CNVi device ref cnvi_bluetooth on - probe WIFI WIFI_CNVI_7 + probe WIFI_INTERFACE WIFI_INTERFACE_CNVI_7 chip soc/intel/common/block/cnvi register "wake" = "GPE0_PME_B0" device generic 0 on end @@ -424,6 +429,8 @@ chip soc/intel/pantherlake register "generic.hid" = ""ELAN2513"" register "generic.desc" = ""ELAN Touchscreen"" register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_F18_IRQ)" + # NOTE: pmc_gpe0_dw0 will be overridden to GPP_F in variant.c. + register "generic.wake" = "GPE0_DW0_18" register "generic.detect" = "1" register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F16)" register "generic.reset_delay_ms" = "20" @@ -444,6 +451,8 @@ chip soc/intel/pantherlake register "generic.hid" = ""ELAN2513"" register "generic.desc" = ""ELAN Touchscreen"" register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_F18_IRQ)" + # NOTE: pmc_gpe0_dw0 will be overridden to GPP_F in variant.c. + register "generic.wake" = "GPE0_DW0_18" register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F16)" register "generic.reset_delay_ms" = "20" register "generic.reset_off_delay_ms" = "2" @@ -462,11 +471,14 @@ chip soc/intel/pantherlake device ref smbus on end device ref hda on + probe AUDIO_CODEC AUDIO_CODEC_ALC3247 chip drivers/sof register "spkr_tplg" = "max98360a" register "jack_tplg" = "rt5682" register "mic_tplg" = "_2ch_pdm0" - device generic 0 on end + device generic 0 on + probe AUDIO_CODEC AUDIO_CODEC_ALC3247 + end end end end diff --git a/src/mainboard/google/ocelot/variants/ocicat/variant.c b/src/mainboard/google/ocelot/variants/ocicat/variant.c index 0bfbdf05edf..935327f2559 100644 --- a/src/mainboard/google/ocelot/variants/ocicat/variant.c +++ b/src/mainboard/google/ocelot/variants/ocicat/variant.c @@ -10,10 +10,39 @@ #include #include +const char *get_wifi_sar_cbfs_filename(void) +{ + return get_wifi_sar_fw_config_filename(FW_CONFIG_FIELD(WIFI_INTERFACE)); +} + +void variant_update_soc_chip_config(struct soc_intel_pantherlake_config *config) +{ + /* Touchscreen and Touchpad WOT support: + * +===================+==================+=================+========================+ + * | Touchscreen | Touchpad | PMC_GPE0_DW0 | WOT | + * +===================+==================+=================+========================+ + * | THC-SPI/THC-I2C | THC-I2C | VGPIO | TS, TP | + * +===================+==================+=================+========================+ + * | THC-SPI/THC-I2C | LPSS-I2C | GPP_F18 | TP | + * +===================+==================+=================+========================+ + */ + + config->thc_mode[0] = THC_HID_I2C_MODE; + config->thc_mode[1] = THC_HID_I2C_MODE; + + /* touchscreen: GPP_F18: GPE0_DW0_18 */ + config->pmc_gpe0_dw0 = GPP_F; +} + void variant_update_soc_memory_init_params(FSPM_UPD *memupd) { FSP_M_CONFIG *m_cfg = &memupd->FspmConfig; + /* HDA Audio */ + printk(BIOS_INFO, "Overriding HDA SDI lanes.\n"); + m_cfg->PchHdaSdiEnable[0] = true; + m_cfg->PchHdaSdiEnable[1] = false; + /* Override FSP-M SaGv frequency and gear for DDR5 boards */ m_cfg->SaGvFreq[0] = 3200; m_cfg->SaGvGear[0] = GEAR_4; @@ -46,3 +75,19 @@ void variant_update_soc_memory_init_params(FSPM_UPD *memupd) memcpy(m_cfg->PhyClockToCkdDimm, phy_clock_to_ckd_dimm, sizeof(phy_clock_to_ckd_dimm)); } + +/* + * HDA verb table loading is supported based on the firmware configuration. + * + * This function determines if the current platform has an HDA codec enabled by + * examining the `FW_CONFIG` value. Specifically, it checks if the + * `FW_CONFIG` includes the `AUDIO_ALC256_HDA` value, which is used to identify + * Fatcat SKUs with HDA codec support. + * + * Return true if the `FW_CONFIG` indicates HDA support (i.e., contains + * `AUDIO_ALC256_HDA`), false otherwise. + */ +bool mainboard_is_hda_codec_enabled(void) +{ + return true; +} diff --git a/src/mainboard/google/octopus/Kconfig b/src/mainboard/google/octopus/Kconfig index 1ba172e6878..8723820f142 100644 --- a/src/mainboard/google/octopus/Kconfig +++ b/src/mainboard/google/octopus/Kconfig @@ -12,7 +12,6 @@ config BOARD_GOOGLE_BASEBOARD_OCTOPUS select DRIVERS_I2C_SX9310 select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select DRIVERS_SPI_ACPI - select DRIVERS_USB_ACPI select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_BOARDID select EC_GOOGLE_CHROMEEC_ESPI diff --git a/src/mainboard/google/octopus/Kconfig.name b/src/mainboard/google/octopus/Kconfig.name index 7519a2e7bfd..90bd4ab4492 100644 --- a/src/mainboard/google/octopus/Kconfig.name +++ b/src/mainboard/google/octopus/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Octopus" +comment "Octopus (Intel GeminiLake)" config BOARD_GOOGLE_AMPTON bool "-> Ampton (ASUS Chromebook Flip C214)" diff --git a/src/mainboard/google/octopus/variants/ampton/overridetree.cb b/src/mainboard/google/octopus/variants/ampton/overridetree.cb index ee607aa6f06..2647d518e6e 100644 --- a/src/mainboard/google/octopus/variants/ampton/overridetree.cb +++ b/src/mainboard/google/octopus/variants/ampton/overridetree.cb @@ -71,7 +71,7 @@ chip soc/intel/apollolake }, }" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -83,8 +83,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 0 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/generic register "hid" = ""10EC5682"" register "name" = ""RT58"" @@ -98,8 +98,8 @@ chip soc/intel/apollolake register "property_list[0].integer" = "1" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -108,8 +108,8 @@ chip soc/intel/apollolake register "detect" = "1" device i2c 15 on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -135,6 +135,6 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end end diff --git a/src/mainboard/google/octopus/variants/baseboard/devicetree.cb b/src/mainboard/google/octopus/variants/baseboard/devicetree.cb index 671150d6560..21c68bab82d 100644 --- a/src/mainboard/google/octopus/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/octopus/variants/baseboard/devicetree.cb @@ -106,168 +106,148 @@ chip soc/intel/apollolake register "pnp_settings" = "PNP_PERF_POWER" device domain 0 on - device pci 00.0 on end # - Host Bridge - device pci 00.1 on end # - DPTF - device pci 00.2 off end # - NPK - device pci 02.0 on # - Gen + device ref igd on register "gfx" = "GMA_DEFAULT_PANEL(0)" end - device pci 03.0 off end # - Gaussian Mixture Model (GMM) - device pci 0c.0 on + device ref cnvi on chip drivers/wifi/generic register "wake" = "GPE0A_CNVI_PME_STS" device generic 0 on end end - end # - CNVi - device pci 0d.0 on end # - P2SB - device pci 0d.1 on end # - PMC - device pci 0d.2 on end # - Fast SPI - device pci 0d.3 on end # - Shared SRAM - device pci 0e.0 on + end + device ref p2sb on end + device ref pmc on end + device ref fast_spi on end + device ref sram on end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98357A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_91)" register "sdmode_delay" = "5" device generic 0 on end end - end # - Audio - device pci 0f.0 on end # - Heci1 - device pci 0f.1 on end # - Heci2 - device pci 0f.2 on end # - Heci3 - device pci 11.0 off end # - ISH - device pci 12.0 off end # - SATA - device pci 13.0 on + end + device ref heci1 on end + device ref heci2 on end + device ref heci3 on end + device ref pcie_rp01 on chip drivers/wifi/generic register "wake" = "GPE0_DW3_11" device pci 00.0 on end end - end # - PCIe-A 0 Onboard M2 Slot(Wifi) - device pci 13.1 off end # - PCIe-A 1 - device pci 13.2 off end # - PCIe-A 2 - device pci 13.3 off end # - PCIe-A 3 - device pci 14.0 off end # - PCIe-B 0 - device pci 14.1 off end # - PCIe-B 1 - device pci 15.0 on + end + device ref xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Left Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""Left Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPIO_109)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""SDCard"" register "type" = "UPC_TYPE_EXPRESSCARD" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""User Facing Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""World Facing Camera"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.7 on end + device ref usb2_port8 on end end chip drivers/usb/acpi register "desc" = ""Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPIO_109)" - device usb 2.8 on end + device ref usb2_port9 on end end chip drivers/usb/acpi register "desc" = ""Left Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""Left Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.4 on end + device ref usb3_port5 on end end chip drivers/usb/acpi register "desc" = ""SDCard"" register "type" = "UPC_TYPE_EXPRESSCARD" - device usb 3.5 on end + device ref usb3_port6 on end end end end - end # - XHCI - device pci 15.1 off end # - XDCI - device pci 16.0 on end # - I2C 0 - device pci 16.1 off end # - I2C 1 - device pci 16.2 off end # - I2C 2 - device pci 16.3 off end # - I2C 3 - device pci 17.0 on end # - I2C 4 - device pci 17.1 on end # - I2C 5 - device pci 17.2 on end # - I2C 6 - device pci 17.3 off end # - I2C 7 - device pci 18.0 on end # - UART 0 - device pci 18.1 off end # - UART 1 - device pci 18.2 on end # - UART 2 - device pci 18.3 off end # - UART 3 - device pci 19.0 on + end + device ref i2c0 on end + device ref i2c4 on end + device ref i2c5 on end + device ref i2c6 on end + device ref uart0 on end + device ref uart2 on end + device ref spi0 on chip drivers/spi/acpi register "hid" = "ACPI_DT_NAMESPACE_HID" register "compat_string" = ""google,cr50"" register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_63_IRQ)" device spi 0 on end end - end # - GSPI 0 - device pci 19.1 off end # - SPI 1 - device pci 19.2 on end # - SPI 2 - device pci 1a.0 on end # - PWM - device pci 1c.0 on end # - eMMC - device pci 1d.0 on end # - UFS - device pci 1e.0 off end # - SDIO - device pci 1f.0 on + end + device ref spi2 on end + device ref pwm on end + device ref emmc on end + device ref ufs on end + device ref lpc_espi on chip ec/google/chromeec device pnp 0c09.0 on end end - end # - ESPI - device pci 1f.1 on end # - SMBUS + end + device ref smbus on end end # FSP provides UPD interface to execute IPC command. PMIC has diff --git a/src/mainboard/google/octopus/variants/bloog/overridetree.cb b/src/mainboard/google/octopus/variants/bloog/overridetree.cb index 32e17cbb1a4..5b3db19d907 100644 --- a/src/mainboard/google/octopus/variants/bloog/overridetree.cb +++ b/src/mainboard/google/octopus/variants/bloog/overridetree.cb @@ -81,8 +81,8 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 16.0 off end # - I2C 0 - device pci 17.1 on + device ref i2c0 off end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -113,8 +113,8 @@ chip soc/intel/apollolake register "property_list[0].integer" = "1" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -123,8 +123,8 @@ chip soc/intel/apollolake register "detect" = "1" device i2c 15 on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -164,7 +164,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/bobba/overridetree.cb b/src/mainboard/google/octopus/variants/bobba/overridetree.cb index a79d15e2f13..d466695eb35 100644 --- a/src/mainboard/google/octopus/variants/bobba/overridetree.cb +++ b/src/mainboard/google/octopus/variants/bobba/overridetree.cb @@ -92,7 +92,7 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -116,8 +116,8 @@ chip soc/intel/apollolake register "key.wakeup_event_action" = "EV_ACT_DEASSERTED" device generic 0 on end end - end # - I2C 0 - device pci 16.1 on + end + device ref i2c1 on chip drivers/i2c/sx9310 register "desc" = ""SAR Proximity Sensor"" register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_214_IRQ)" @@ -132,8 +132,8 @@ chip soc/intel/apollolake register "proxraw_strength" = "0" device i2c 28 on end end - end # - I2C 1 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -164,8 +164,8 @@ chip soc/intel/apollolake register "property_list[0].integer" = "1" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -184,8 +184,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -223,7 +223,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/casta/overridetree.cb b/src/mainboard/google/octopus/variants/casta/overridetree.cb index 8d3fafd9568..a6cac573a33 100644 --- a/src/mainboard/google/octopus/variants/casta/overridetree.cb +++ b/src/mainboard/google/octopus/variants/casta/overridetree.cb @@ -83,33 +83,33 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 15.0 on + device ref xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi - device usb 2.3 off end + device ref usb2_port4 off end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi - device usb 3.3 off end + device ref usb3_port4 off end end end end - end # - XHCI - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -127,8 +127,8 @@ chip soc/intel/apollolake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -146,7 +146,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0xE" device i2c 40 on end end - end # - I2C 6 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/dood/overridetree.cb b/src/mainboard/google/octopus/variants/dood/overridetree.cb index eb8490da76e..8e04bd30607 100644 --- a/src/mainboard/google/octopus/variants/dood/overridetree.cb +++ b/src/mainboard/google/octopus/variants/dood/overridetree.cb @@ -80,8 +80,8 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 16.0 off end # - I2C 0 - device pci 17.1 on + device ref i2c0 off end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -99,8 +99,8 @@ chip soc/intel/apollolake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -119,8 +119,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -158,7 +158,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/fleex/overridetree.cb b/src/mainboard/google/octopus/variants/fleex/overridetree.cb index 3a17abba452..4583787f886 100644 --- a/src/mainboard/google/octopus/variants/fleex/overridetree.cb +++ b/src/mainboard/google/octopus/variants/fleex/overridetree.cb @@ -89,7 +89,7 @@ chip soc/intel/apollolake register "disable_xhci_lfps_pm" = "0" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -102,9 +102,9 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 0 - device pci 16.1 off end # - I2C 1 - device pci 17.1 on + end + device ref i2c1 off end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -151,8 +151,8 @@ chip soc/intel/apollolake register "hs_bias_sense_disable" = "true" device i2c 48 on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -170,8 +170,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 2c on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -210,6 +210,6 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end end diff --git a/src/mainboard/google/octopus/variants/foob/overridetree.cb b/src/mainboard/google/octopus/variants/foob/overridetree.cb index 154345599c9..b7d70935f2c 100644 --- a/src/mainboard/google/octopus/variants/foob/overridetree.cb +++ b/src/mainboard/google/octopus/variants/foob/overridetree.cb @@ -83,7 +83,7 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -94,8 +94,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 0 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -113,8 +113,8 @@ chip soc/intel/apollolake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -133,8 +133,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/hid register "generic.hid" = ""ELAN90FC"" register "generic.desc" = ""ELAN Touchscreen"" @@ -159,7 +159,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 20 on end end - end # - I2C 7 + end end # Disable xHCI compliance mode diff --git a/src/mainboard/google/octopus/variants/garg/overridetree.cb b/src/mainboard/google/octopus/variants/garg/overridetree.cb index a653148d10b..4084297fe62 100644 --- a/src/mainboard/google/octopus/variants/garg/overridetree.cb +++ b/src/mainboard/google/octopus/variants/garg/overridetree.cb @@ -86,7 +86,7 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -109,8 +109,8 @@ chip soc/intel/apollolake register "key.wakeup_event_action" = "EV_ACT_DEASSERTED" device generic 0 on end end - end # - I2C 0 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -141,8 +141,8 @@ chip soc/intel/apollolake register "property_list[0].integer" = "1" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -161,8 +161,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -200,7 +200,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/lick/overridetree.cb b/src/mainboard/google/octopus/variants/lick/overridetree.cb index a89a506dae4..a534173a6bb 100644 --- a/src/mainboard/google/octopus/variants/lick/overridetree.cb +++ b/src/mainboard/google/octopus/variants/lick/overridetree.cb @@ -73,7 +73,7 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 17.1 on + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -91,8 +91,8 @@ chip soc/intel/apollolake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -111,7 +111,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # - I2C 6 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/meep/overridetree.cb b/src/mainboard/google/octopus/variants/meep/overridetree.cb index 9634cf13bb9..11038d7e0a8 100644 --- a/src/mainboard/google/octopus/variants/meep/overridetree.cb +++ b/src/mainboard/google/octopus/variants/meep/overridetree.cb @@ -83,63 +83,63 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 15.0 on + device ref xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""Left Type-A Port"" register "type" = "UPC_TYPE_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""Left Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""Right Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(2, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""Right Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(2, 2)" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""Left Type-A Port"" register "type" = "UPC_TYPE_USB3_A" register "group" = "ACPI_PLD_GROUP(1, 2)" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""Left Type-C Port"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(1, 1)" - device usb 3.4 on end + device ref usb3_port5 on end end end end - end # - XHCI - device pci 16.0 on + end + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -162,8 +162,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0xa on end end - end # - I2C 0 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -194,8 +194,8 @@ chip soc/intel/apollolake register "property_list[0].integer" = "1" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -204,8 +204,8 @@ chip soc/intel/apollolake register "detect" = "1" device i2c 15 on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -244,7 +244,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end # Disable compliance mode diff --git a/src/mainboard/google/octopus/variants/phaser/overridetree.cb b/src/mainboard/google/octopus/variants/phaser/overridetree.cb index 41b654c8715..468ae4cb902 100644 --- a/src/mainboard/google/octopus/variants/phaser/overridetree.cb +++ b/src/mainboard/google/octopus/variants/phaser/overridetree.cb @@ -83,7 +83,7 @@ chip soc/intel/apollolake }" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -95,8 +95,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 0 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -127,8 +127,8 @@ chip soc/intel/apollolake register "property_list[0].integer" = "1" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -147,8 +147,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x20" device i2c 0x2c on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -198,7 +198,7 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x01" device i2c 40 on end end - end # - I2C 7 + end end # Disable xHCI compliance mode diff --git a/src/mainboard/google/octopus/variants/yorp/overridetree.cb b/src/mainboard/google/octopus/variants/yorp/overridetree.cb index 82a0ee42637..85db9f2aae4 100644 --- a/src/mainboard/google/octopus/variants/yorp/overridetree.cb +++ b/src/mainboard/google/octopus/variants/yorp/overridetree.cb @@ -42,7 +42,7 @@ chip soc/intel/apollolake register "emmc_rx_strobe_cntl" = "0x0a0a" device domain 0 on - device pci 16.0 on + device ref i2c0 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -53,8 +53,8 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 0 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" register "btn_cfg" = "50" @@ -72,8 +72,8 @@ chip soc/intel/apollolake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end # - I2C 5 - device pci 17.2 on + end + device ref i2c6 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -82,8 +82,8 @@ chip soc/intel/apollolake register "detect" = "1" device i2c 15 on end end - end # - I2C 6 - device pci 17.3 on + end + device ref i2c7 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -96,6 +96,6 @@ chip soc/intel/apollolake register "has_power_resource" = "true" device i2c 10 on end end - end # - I2C 7 + end end end diff --git a/src/mainboard/google/parrot/Kconfig b/src/mainboard/google/parrot/Kconfig index dc0e8606fe5..2fa7420a147 100644 --- a/src/mainboard/google/parrot/Kconfig +++ b/src/mainboard/google/parrot/Kconfig @@ -36,6 +36,9 @@ config MAINBOARD_DIR config MAINBOARD_PART_NUMBER default "Parrot" +config CBFS_SIZE + default 0x600000 + config MAINBOARD_SMBIOS_MANUFACTURER string default "GOOGLE" diff --git a/src/mainboard/google/parrot/Kconfig.name b/src/mainboard/google/parrot/Kconfig.name index bbaa6cf8280..c8155e2679c 100644 --- a/src/mainboard/google/parrot/Kconfig.name +++ b/src/mainboard/google/parrot/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Parrot" +comment "Parrot (Intel SandyBridge (2nd Gen))" config BOARD_GOOGLE_PARROT bool "-> Parrot (Acer C7/C710 Chromebook)" diff --git a/src/mainboard/google/peach_pit/Kconfig.name b/src/mainboard/google/peach_pit/Kconfig.name index 29eddb55944..dc0ab311340 100644 --- a/src/mainboard/google/peach_pit/Kconfig.name +++ b/src/mainboard/google/peach_pit/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Peach Pit" +comment "Peach Pit (Samsung Exynos 5420)" config BOARD_GOOGLE_PEACH_PIT bool "-> Peach Pit (Samsung Chromebook 2 11\")" diff --git a/src/mainboard/google/poppy/Kconfig b/src/mainboard/google/poppy/Kconfig index a9b45920db3..cef94552f7d 100644 --- a/src/mainboard/google/poppy/Kconfig +++ b/src/mainboard/google/poppy/Kconfig @@ -73,6 +73,7 @@ config BOARD_GOOGLE_NOCTURNE select DRIVERS_I2C_SX9310 select DRIVERS_SPI_ACPI select DRIVERS_USB_ACPI + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select EXCLUDE_NATIVE_SD_INTERFACE select GEO_SAR_ENABLE if CHROMEOS_WIFI_SAR select INTEL_GMA_HAVE_VBT @@ -224,6 +225,9 @@ config UART_FOR_CONSOLE int default 2 +config CBFS_SIZE + default 0xe00000 + config USE_PM_ACPI_TIMER default n diff --git a/src/mainboard/google/poppy/Kconfig.name b/src/mainboard/google/poppy/Kconfig.name index 7999d77dc3d..3566de21ef7 100644 --- a/src/mainboard/google/poppy/Kconfig.name +++ b/src/mainboard/google/poppy/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Poppy" +comment "Poppy (Intel KabyLake/KabyLake-R (7th/8th Gen))" config BOARD_GOOGLE_ATLAS bool "-> Atlas (Google Pixelbook Go)" diff --git a/src/mainboard/google/poppy/cfr.c b/src/mainboard/google/poppy/cfr.c index 01793c080c6..40bc75656f6 100644 --- a/src/mainboard/google/poppy/cfr.c +++ b/src/mainboard/google/poppy/cfr.c @@ -6,15 +6,11 @@ #include #include -static const struct sm_object ipu_camera = SM_DECLARE_ENUM({ +static const struct sm_object ipu_camera = SM_DECLARE_BOOL({ .opt_name = "ipu_camera", .ui_name = "IPU Camera", .ui_helptext = "Enable or disable integrated camera devices", .default_value = true, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, #if !CONFIG(VARIANT_HAS_CAMERA_ACPI) .flags = CFR_OPTFLAG_SUPPRESS, #endif diff --git a/src/mainboard/google/puff/Kconfig b/src/mainboard/google/puff/Kconfig index 2ec9d996b97..ebf9ea523b0 100644 --- a/src/mainboard/google/puff/Kconfig +++ b/src/mainboard/google/puff/Kconfig @@ -120,6 +120,10 @@ config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/chromeos-16MiB.fmd" if BOARD_ROMSIZE_KB_16384 && CHROMEOS default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/chromeos-32MiB.fmd" if BOARD_ROMSIZE_KB_32768 && CHROMEOS +config CBFS_SIZE + default 0xd00000 if BOARD_ROMSIZE_KB_16384 + default 0x1000000 if BOARD_ROMSIZE_KB_32768 + config POWER_OFF_ON_CR50_UPDATE bool default n diff --git a/src/mainboard/google/puff/Kconfig.name b/src/mainboard/google/puff/Kconfig.name index d8a997e7fbd..947e91057df 100644 --- a/src/mainboard/google/puff/Kconfig.name +++ b/src/mainboard/google/puff/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Puff" +comment "Puff (Intel CometLake (10th Gen))" config BOARD_GOOGLE_AMBASSADOR bool "-> Ambassador (Meet Compute System [Intel 10th Gen])" diff --git a/src/mainboard/google/puff/cfr.c b/src/mainboard/google/puff/cfr.c index e50af539c88..10df17757cb 100644 --- a/src/mainboard/google/puff/cfr.c +++ b/src/mainboard/google/puff/cfr.c @@ -1,4 +1,3 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ #include diff --git a/src/mainboard/google/rambi/Kconfig b/src/mainboard/google/rambi/Kconfig index 750eba1e309..399872e230c 100644 --- a/src/mainboard/google/rambi/Kconfig +++ b/src/mainboard/google/rambi/Kconfig @@ -6,6 +6,7 @@ config BOARD_GOOGLE_BASEBOARD_RAMBI select BOARD_ROMSIZE_KB_8192 select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_LPC + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select ENABLE_BUILTIN_COM1 if CONSOLE_SERIAL select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES @@ -145,6 +146,9 @@ config MAINBOARD_PART_NUMBER config OVERRIDE_DEVICETREE default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" +config CBFS_SIZE + default 0x600000 + config MAINBOARD_SMBIOS_MANUFACTURER string default "GOOGLE" diff --git a/src/mainboard/google/rambi/Kconfig.name b/src/mainboard/google/rambi/Kconfig.name index cd63c425dcf..07324384bb2 100644 --- a/src/mainboard/google/rambi/Kconfig.name +++ b/src/mainboard/google/rambi/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Rambi" +comment "Rambi (Intel Baytrail)" config BOARD_GOOGLE_BANJO bool "-> Banjo (Acer Chromebook 15 (CB3-531))" diff --git a/src/mainboard/google/rauru/Kconfig b/src/mainboard/google/rauru/Kconfig index 486e2738749..dbbfcfb3605 100644 --- a/src/mainboard/google/rauru/Kconfig +++ b/src/mainboard/google/rauru/Kconfig @@ -26,7 +26,7 @@ config BOARD_SPECIFIC_OPTIONS select SPI_FLASH_INCLUDE_ALL_DRIVERS select MAINBOARD_HAS_NATIVE_VGA_INIT select HAVE_LINEAR_FRAMEBUFFER - select CHROMEOS_USE_EC_WATCHDOG_FLAG if CHROMEOS + select CHROMEOS_USE_EC_WATCHDOG_FLAG if CHROMEOS && !MEDIATEK_WDT_RESET_BY_SW select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_BOARDID select EC_GOOGLE_CHROMEEC_FW_CONFIG_FROM_UFSC if BOARD_GOOGLE_SAPPHIRE @@ -40,6 +40,7 @@ config BOARD_SPECIFIC_OPTIONS select FW_CONFIG_SOURCE_CHROMEEC_CBI select RTC select MIPI_PANEL_BOE_NS130069_M00 if BOARD_GOOGLE_SAPPHIRE + select MEDIATEK_WDT_RESET_BY_SW if BOARD_GOOGLE_SAPPHIRE config MAINBOARD_DIR string diff --git a/src/mainboard/google/rauru/Kconfig.name b/src/mainboard/google/rauru/Kconfig.name index f09ee43e151..cac699c5538 100644 --- a/src/mainboard/google/rauru/Kconfig.name +++ b/src/mainboard/google/rauru/Kconfig.name @@ -1,12 +1,12 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Rauru" +comment "Rauru (MediaTek Kompanio Ultra 910 (MT8196))" config BOARD_GOOGLE_HYLIA - bool "-> Hylia" + bool "-> Hylia (Acer Chromebook Plus Spin 514 (CP514-5HN/CPE594-2N))" config BOARD_GOOGLE_NAVI - bool "-> Navi" + bool "-> Navi (Lenovo Chromebook Plus (14M9610))" config BOARD_GOOGLE_RAURU bool "-> Rauru" diff --git a/src/mainboard/google/rauru/mainboard.c b/src/mainboard/google/rauru/mainboard.c index d0ed3ad7f7a..93489426b8c 100644 --- a/src/mainboard/google/rauru/mainboard.c +++ b/src/mainboard/google/rauru/mainboard.c @@ -7,13 +7,11 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include #include @@ -128,12 +126,6 @@ static void mainboard_init(struct device *dev) if (CONFIG(RAURU_SDCARD_INIT)) mtk_msdc_configure_sdcard(); - if (dpm_init()) - printk(BIOS_ERR, "dpm init failed, DVFS may not work\n"); - - if (spm_init()) - printk(BIOS_ERR, "spm init failed, Suspend may not work\n"); - if (CONFIG(ARM64_USE_ARM_TRUSTED_FIRMWARE)) register_reset_to_bl31(GPIO_AP_EC_WARM_RST_REQ.id, true); } diff --git a/src/mainboard/google/reef/Kconfig b/src/mainboard/google/reef/Kconfig index 899efeb4b85..1ce23534320 100644 --- a/src/mainboard/google/reef/Kconfig +++ b/src/mainboard/google/reef/Kconfig @@ -10,6 +10,7 @@ config BOARD_GOOGLE_BASEBOARD_REEF select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_BOARDID + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select EC_GOOGLE_CHROMEEC_LPC select GOOGLE_SMBIOS_MAINBOARD_VERSION select HAVE_ACPI_RESUME @@ -76,12 +77,11 @@ config VARIANT_DIR default "coral" if BOARD_GOOGLE_CORAL config DEVICETREE - default "variants/coral/devicetree.cb" if BOARD_GOOGLE_CORAL - default "variants/pyro/devicetree.cb" if BOARD_GOOGLE_PYRO - default "variants/sand/devicetree.cb" if BOARD_GOOGLE_SAND - default "variants/snappy/devicetree.cb" if BOARD_GOOGLE_SNAPPY default "variants/baseboard/devicetree.cb" +config OVERRIDE_DEVICETREE + default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" if !BOARD_GOOGLE_REEF + config MAINBOARD_PART_NUMBER default "Reef" if BOARD_GOOGLE_REEF default "Pyro" if BOARD_GOOGLE_PYRO diff --git a/src/mainboard/google/reef/Kconfig.name b/src/mainboard/google/reef/Kconfig.name index e392c926cc0..c8d176c2b8e 100644 --- a/src/mainboard/google/reef/Kconfig.name +++ b/src/mainboard/google/reef/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Reef" +comment "Reef (Intel ApolloLake)" config BOARD_GOOGLE_REEF bool "-> Reef/Electro (Acer Chromebook Spin 11 R751T)" diff --git a/src/mainboard/google/reef/variants/baseboard/devicetree.cb b/src/mainboard/google/reef/variants/baseboard/devicetree.cb index 5eee33e790d..6c3f3f5d1e6 100644 --- a/src/mainboard/google/reef/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/reef/variants/baseboard/devicetree.cb @@ -118,18 +118,14 @@ chip soc/intel/apollolake register "slp_s3_assertion_width_usecs" = "28000" device domain 0 on - device pci 00.0 on end # - Host Bridge - device pci 00.1 on end # - DPTF - device pci 00.2 off end # - NPK - device pci 02.0 on # - Gen + device ref igd on register "gfx" = "GMA_DEFAULT_PANEL(0)" end - device pci 03.0 off end # - Iunit - device pci 0d.0 on end # - P2SB - device pci 0d.1 on end # - PMC - device pci 0d.2 on end # - SPI - device pci 0d.3 on end # - Shared SRAM - device pci 0e.0 on # - Audio + device ref p2sb on end + device ref pmc on end + device ref fast_spi on end + device ref sram on end + device ref hda on chip drivers/generic/max98357a register "hid" = ""MX98357A"" register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" @@ -137,23 +133,17 @@ chip soc/intel/apollolake device generic 0 on end end end - device pci 0f.0 on end # - CSE - device pci 11.0 off end # - ISH - device pci 12.0 off end # - SATA - device pci 13.0 off end # - Root Port 2 - PCIe-A 0 - device pci 13.1 off end # - Root Port 3 - PCIe-A 1 - device pci 13.2 off end # - Root Port 4 - PCIe-A 2 - device pci 13.3 off end # - Root Port 5 - PCIe-A 3 - device pci 14.0 on + device ref heci1 on end + device ref heci2 on end + device ref heci3 on end + device ref pcie_rp05 on chip drivers/wifi/generic register "wake" = "GPE0_DW3_00" device pci 00.0 on end end - end # - Root Port 0 - PCIe-B 0 - Wifi - device pci 14.1 off end # - Root Port 1 - PCIe-B 1 - device pci 15.0 on end # - XHCI - device pci 15.1 off end # - XDCI - device pci 16.0 on # - I2C 0 + end + device ref xhci on end + device ref i2c0 on chip drivers/i2c/da7219 register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" register "btn_cfg" = "50" @@ -172,15 +162,15 @@ chip soc/intel/apollolake device i2c 1a on end end end - device pci 16.1 on end # - I2C 1 - device pci 16.2 on + device ref i2c1 on end + device ref i2c2 on chip drivers/i2c/tpm register "hid" = ""GOOG0005"" register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" device i2c 50 on end end - end # - I2C 2 - device pci 16.3 on + end + device ref i2c3 on chip drivers/i2c/generic register "hid" = ""ELAN0001"" register "desc" = ""ELAN Touchscreen"" @@ -193,8 +183,8 @@ chip soc/intel/apollolake register "has_power_resource" = "true" device i2c 10 on end end - end # - I2C 3 - device pci 17.0 on + end + device ref i2c4 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" register "desc" = ""ELAN Touchpad"" @@ -203,8 +193,8 @@ chip soc/intel/apollolake register "detect" = "1" device i2c 15 on end end - end # - I2C 4 - device pci 17.1 on + end + device ref i2c5 on chip drivers/i2c/hid register "generic.hid" = ""WCOM50C1"" register "generic.desc" = ""WCOM Digitizer"" @@ -212,25 +202,19 @@ chip soc/intel/apollolake register "hid_desc_reg_offset" = "0x1" device i2c 0x9 on end end - end # - I2C 5 - device pci 17.2 off end # - I2C 6 - device pci 17.3 off end # - I2C 7 - device pci 18.0 on end # - UART 0 - device pci 18.1 on end # - UART 1 - device pci 18.2 on end # - UART 2 - device pci 18.3 off end # - UART 3 - device pci 19.0 on end # - SPI 0 - device pci 19.1 off end # - SPI 1 - device pci 19.2 off end # - SPI 2 - device pci 1a.0 on end # - PWM - device pci 1b.0 on end # - SDCARD - device pci 1c.0 on end # - eMMC - device pci 1e.0 off end # - SDIO - device pci 1f.0 on # - LPC + end + device ref uart0 on end + device ref uart1 on end + device ref uart2 on end + device ref spi0 on end + device ref pwm on end + device ref sdcard on end + device ref emmc on end + device ref lpc_espi on chip ec/google/chromeec device pnp 0c09.0 on end end end - device pci 1f.1 on end # - SMBUS + device ref smbus on end end end diff --git a/src/mainboard/google/reef/variants/coral/devicetree.cb b/src/mainboard/google/reef/variants/coral/devicetree.cb deleted file mode 100644 index ecfd522560d..00000000000 --- a/src/mainboard/google/reef/variants/coral/devicetree.cb +++ /dev/null @@ -1,258 +0,0 @@ -chip soc/intel/apollolake - - register "pcie_rp_clkreq_pin[0]" = "0" # wifi/bt - # Disable unused clkreq of PCIe root ports - register "pcie_rp_clkreq_pin[1]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[2]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[3]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[4]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[5]" = "CLKREQ_DISABLED" - - # GPIO for PERST_0 - # If the Board has PERST_0 signal, assign the GPIO - # If the Board does not have PERST_0, assign GPIO_PRT0_UDEF - register "prt0_gpio" = "GPIO_122" - - # GPIO for SD card detect - register "sdcard_cd_gpio" = "GPIO_177" - - # EMMC TX DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [14:8] steps of delay for HS400, each 125ps. - # [6:0] steps of delay for SDR104/HS200, each 125ps. - register "emmc_tx_data_cntl1" = "0x0C16" - - # EMMC TX DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_tx_data_cntl2" = "0x28162828" - - # EMMC RX CMD/DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_rx_cmd_data_cntl1" = "0x00181717" - - # EMMC RX CMD/DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [17:16] stands for Rx Clock before Output Buffer - # [14:8] steps of delay for Auto Tuning Mode, each 125ps. - # [6:0] steps of delay for HS200, each 125ps. - register "emmc_rx_cmd_data_cntl2" = "0x10008" - - # Enable DPTF - register "dptf_enable" = "true" - - # PL1 override 12 W: the energy calculation is wrong with the - # current VR solution. Experiments show that SoC TDP max (6W) can - # be reached when RAPL PL1 is set to 12W. - # Set RAPL PL2 to 15W. - register "power_limits_config" = "{ - .tdp_pl1_override = 12, - .tdp_pl2_override = 15, - }" - - # Enable Audio Clock and Power gating - register "hdaudio_clk_gate_enable" = "1" - register "hdaudio_pwr_gate_enable" = "1" - register "hdaudio_bios_config_lockdown" = "1" - - # Enable lpss s0ix - register "lpss_s0ix_enable" = "true" - - # GPE configuration - # Note that GPE events called out in ASL code rely on this - # route, i.e., if this route changes then the affected GPE - # offset bits also need to be changed. This sets the PMC register - # GPE_CFG fields. - register "gpe0_dw1" = "PMC_GPE_N_31_0" - register "gpe0_dw2" = "PMC_GPE_N_63_32" - register "gpe0_dw3" = "PMC_GPE_SW_31_0" - - # Intel Common SoC Config - #+-------------------+---------------------------+ - #| Field | Value | - #+-------------------+---------------------------+ - #| I2C0 | Audio | - #| I2C2 | TPM | - #| I2C3 | Touchscreen | - #| I2C4 | Trackpad | - #| I2C5 | Digitizer | - #+-------------------+---------------------------+ - register "common_soc_config" = "{ - .i2c[0] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 104, - .fall_time_ns = 52, - }, - .i2c[2] = { - .early_init = 1, - .speed = I2C_SPEED_FAST, - .rise_time_ns = 57, - .fall_time_ns = 28, - }, - .i2c[3] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 76, - .fall_time_ns = 164, - }, - .i2c[4] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 114, - .fall_time_ns = 164, - .data_hold_time_ns = 350, - }, - .i2c[5] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 152, - .fall_time_ns = 30, - }, - }" - - # Minimum SLP S3 assertion width 28ms. - register "slp_s3_assertion_width_usecs" = "28000" - - device domain 0 on - device pci 00.0 on end # - Host Bridge - device pci 00.1 on end # - DPTF - device pci 00.2 off end # - NPK - device pci 02.0 on # - Gen - register "gfx" = "GMA_DEFAULT_PANEL(0)" - end - device pci 03.0 off end # - Iunit - device pci 0d.0 on end # - P2SB - device pci 0d.1 on end # - PMC - device pci 0d.2 on end # - SPI - device pci 0d.3 on end # - Shared SRAM - device pci 0e.0 on # - Audio - chip drivers/generic/max98357a - register "hid" = ""MX98357A"" - register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" - register "sdmode_delay" = "5" - device generic 0 on end - end - end - device pci 0f.0 on end # - CSE - device pci 11.0 off end # - ISH - device pci 12.0 off end # - SATA - device pci 13.0 off end # - Root Port 2 - PCIe-A 0 - device pci 13.1 off end # - Root Port 3 - PCIe-A 1 - device pci 13.2 off end # - Root Port 4 - PCIe-A 2 - device pci 13.3 off end # - Root Port 5 - PCIe-A 3 - device pci 14.0 on - chip drivers/wifi/generic - register "wake" = "GPE0_DW3_00" - device pci 00.0 on end - end - end # - Root Port 0 - PCIe-B 0 - Wifi - device pci 14.1 off end # - Root Port 1 - PCIe-B 1 - device pci 15.0 on end # - XHCI - device pci 15.1 off end # - XDCI - device pci 16.0 on # - I2C 0 - chip drivers/i2c/da7219 - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" - register "btn_cfg" = "50" - register "mic_det_thr" = "200" - register "jack_ins_deb" = "20" - register "jack_det_rate" = ""32ms_64ms"" - register "jack_rem_deb" = "1" - register "a_d_btn_thr" = "0xa" - register "d_b_btn_thr" = "0x16" - register "b_c_btn_thr" = "0x21" - register "c_mic_btn_thr" = "0x3e" - register "btn_avg" = "4" - register "adc_1bit_rpt" = "1" - register "micbias_lvl" = "2600" - register "mic_amp_in_sel" = ""diff"" - device i2c 1a on end - end - end - device pci 16.1 on end # - I2C 1 - device pci 16.2 on - chip drivers/i2c/tpm - register "hid" = ""GOOG0005"" - register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" - device i2c 50 on end - end - end # - I2C 2 - device pci 16.3 on - chip drivers/i2c/generic - register "hid" = ""ELAN0001"" - register "desc" = ""ELAN Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "20" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "1" - register "has_power_resource" = "true" - device i2c 10 on end - end - chip drivers/i2c/generic - register "hid" = ""RAYD0001"" - register "desc" = ""Raydium Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "1" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "50" - register "has_power_resource" = "true" - device i2c 39 on end - end - end # - I2C 3 - device pci 17.0 on - chip drivers/i2c/generic - register "hid" = ""ELAN0000"" - register "desc" = ""ELAN Touchpad"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" - register "wake" = "GPE0_DW1_15" - register "detect" = "1" - device i2c 15 on end - end - chip drivers/i2c/hid - register "generic.hid" = ""SYNA0000"" - register "generic.cid" = ""ACPI0C50"" - register "generic.desc" = ""Synaptics Touchpad"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" - register "generic.wake" = "GPE0_DW1_15" - register "generic.detect" = "1" - register "hid_desc_reg_offset" = "0x20" - device i2c 0x2c on end - end - end # - I2C 4 - device pci 17.1 on - chip drivers/i2c/hid - register "generic.hid" = ""WCOM50C1"" - register "generic.desc" = ""WCOM Digitizer"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_13_IRQ)" - register "hid_desc_reg_offset" = "0x1" - device i2c 0x9 on end - end - end # - I2C 5 - device pci 17.2 off end # - I2C 6 - device pci 17.3 off end # - I2C 7 - device pci 18.0 on end # - UART 0 - device pci 18.1 off end # - UART 1 - device pci 18.2 off end # - UART 2 - device pci 18.3 off end # - UART 3 - device pci 19.0 on end # - SPI 0 - device pci 19.1 off end # - SPI 1 - device pci 19.2 off end # - SPI 2 - device pci 1a.0 on end # - PWM - device pci 1b.0 on end # - SDCARD - device pci 1c.0 on end # - eMMC - device pci 1e.0 off end # - SDIO - device pci 1f.0 on # - LPC - chip ec/google/chromeec - device pnp 0c09.0 on end - end - end - device pci 1f.1 on end # - SMBUS - end -end diff --git a/src/mainboard/google/reef/variants/coral/overridetree.cb b/src/mainboard/google/reef/variants/coral/overridetree.cb new file mode 100644 index 00000000000..0df53c0f7ac --- /dev/null +++ b/src/mainboard/google/reef/variants/coral/overridetree.cb @@ -0,0 +1,52 @@ +chip soc/intel/apollolake + device domain 0 on + device ref i2c3 on + chip drivers/i2c/generic + register "hid" = ""ELAN0001"" + register "desc" = ""ELAN Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "20" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "1" + register "has_power_resource" = "true" + device i2c 10 on end + end + chip drivers/i2c/generic + register "hid" = ""RAYD0001"" + register "desc" = ""Raydium Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "1" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "50" + register "has_power_resource" = "true" + device i2c 39 on end + end + end + device ref i2c4 on + chip drivers/i2c/generic + register "hid" = ""ELAN0000"" + register "desc" = ""ELAN Touchpad"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" + register "wake" = "GPE0_DW1_15" + register "detect" = "1" + device i2c 15 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""SYNA0000"" + register "generic.cid" = ""ACPI0C50"" + register "generic.desc" = ""Synaptics Touchpad"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" + register "generic.wake" = "GPE0_DW1_15" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x20" + device i2c 0x2c on end + end + end + device ref uart1 off end + device ref uart2 off end + end +end diff --git a/src/mainboard/google/reef/variants/pyro/devicetree.cb b/src/mainboard/google/reef/variants/pyro/devicetree.cb deleted file mode 100644 index 5385aaaccf6..00000000000 --- a/src/mainboard/google/reef/variants/pyro/devicetree.cb +++ /dev/null @@ -1,250 +0,0 @@ -chip soc/intel/apollolake - - register "pcie_rp_clkreq_pin[0]" = "0" # wifi/bt - # Disable unused clkreq of PCIe root ports - register "pcie_rp_clkreq_pin[1]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[2]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[3]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[4]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[5]" = "CLKREQ_DISABLED" - - # GPIO for PERST_0 - # If the Board has PERST_0 signal, assign the GPIO - # If the Board does not have PERST_0, assign GPIO_PRT0_UDEF - register "prt0_gpio" = "GPIO_122" - - # GPIO for SD card detect - register "sdcard_cd_gpio" = "GPIO_177" - - # EMMC TX DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [14:8] steps of delay for HS400, each 125ps. - # [6:0] steps of delay for SDR104/HS200, each 125ps. - register "emmc_tx_data_cntl1" = "0x0C16" - - # EMMC TX DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_tx_data_cntl2" = "0x28162828" - - # EMMC RX CMD/DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_rx_cmd_data_cntl1" = "0x00181717" - - # EMMC RX CMD/DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [17:16] stands for Rx Clock before Output Buffer - # [14:8] steps of delay for Auto Tuning Mode, each 125ps. - # [6:0] steps of delay for HS200, each 125ps. - register "emmc_rx_cmd_data_cntl2" = "0x10008" - - # Enable DPTF - register "dptf_enable" = "true" - - # PL1 override 12 W: the energy calculation is wrong with the - # current VR solution. Experiments show that SoC TDP max (6W) can - # be reached when RAPL PL1 is set to 12W. - # Set RAPL PL2 to 15W. - register "power_limits_config" = "{ - .tdp_pl1_override = 12, - .tdp_pl2_override = 15, - }" - - # Enable Audio Clock and Power gating - register "hdaudio_clk_gate_enable" = "1" - register "hdaudio_pwr_gate_enable" = "1" - register "hdaudio_bios_config_lockdown" = "1" - - # Enable lpss s0ix - register "lpss_s0ix_enable" = "true" - - # GPE configuration - # Note that GPE events called out in ASL code rely on this - # route, i.e., if this route changes then the affected GPE - # offset bits also need to be changed. This sets the PMC register - # GPE_CFG fields. - register "gpe0_dw1" = "PMC_GPE_N_31_0" - register "gpe0_dw2" = "PMC_GPE_N_63_32" - register "gpe0_dw3" = "PMC_GPE_SW_31_0" - - # Intel Common SoC Config - #+-------------------+---------------------------+ - #| Field | Value | - #+-------------------+---------------------------+ - #| I2C0 | Audio | - #| I2C2 | TPM | - #| I2C3 | Touchscreen | - #| I2C4 | Trackpad | - #+-------------------+---------------------------+ - register "common_soc_config" = "{ - .i2c[0] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 104, - .fall_time_ns = 52, - }, - .i2c[2] = { - .early_init = 1, - .speed = I2C_SPEED_FAST, - .rise_time_ns = 50, - .fall_time_ns = 23, - }, - .i2c[3] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 76, - .fall_time_ns = 164, - }, - .i2c[4] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 90, - .fall_time_ns = 164, - }, - }" - - # Minimum SLP S3 assertion width 28ms. - register "slp_s3_assertion_width_usecs" = "28000" - - # Override USB2 PER PORT register (PORT 0) - register "usb2eye[0]" = "{ - .Usb20PerPortPeTxiSet = 7, - .Usb20PerPortTxiSet = 1, - .Usb20IUsbTxEmphasisEn = 3, - .Usb20PerPortTxPeHalf = 0, - }" - - # Override USB2 PER PORT register (PORT 1) - register "usb2eye[1]" = "{ - .Usb20PerPortPeTxiSet = 7, - .Usb20PerPortTxiSet = 2, - .Usb20IUsbTxEmphasisEn = 3, - .Usb20PerPortTxPeHalf = 0, - }" - - device domain 0 on - device pci 00.0 on end # - Host Bridge - device pci 00.1 on end # - DPTF - device pci 00.2 off end # - NPK - device pci 02.0 on # - Gen - register "gfx" = "GMA_DEFAULT_PANEL(0)" - end - device pci 03.0 off end # - Iunit - device pci 0d.0 on end # - P2SB - device pci 0d.1 on end # - PMC - device pci 0d.2 on end # - SPI - device pci 0d.3 on end # - Shared SRAM - device pci 0e.0 on # - Audio - chip drivers/generic/max98357a - register "hid" = ""MX98357A"" - register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" - register "sdmode_delay" = "5" - device generic 0 on end - end - end - device pci 0f.0 on end # - CSE - device pci 11.0 off end # - ISH - device pci 12.0 off end # - SATA - device pci 13.0 off end # - Root Port 2 - PCIe-A 0 - device pci 13.1 off end # - Root Port 3 - PCIe-A 1 - device pci 13.2 off end # - Root Port 4 - PCIe-A 2 - device pci 13.3 off end # - Root Port 5 - PCIe-A 3 - device pci 14.0 on - chip drivers/wifi/generic - register "wake" = "GPE0_DW3_00" - device pci 00.0 on end - end - end # - Root Port 0 - PCIe-B 0 - Wifi - device pci 14.1 off end # - Root Port 1 - PCIe-B 1 - device pci 15.0 on end # - XHCI - device pci 15.1 off end # - XDCI - device pci 16.0 on # - I2C 0 - chip drivers/i2c/da7219 - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" - register "btn_cfg" = "50" - register "mic_det_thr" = "200" - register "jack_ins_deb" = "20" - register "jack_det_rate" = ""32ms_64ms"" - register "jack_rem_deb" = "1" - register "a_d_btn_thr" = "0xa" - register "d_b_btn_thr" = "0x16" - register "b_c_btn_thr" = "0x21" - register "c_mic_btn_thr" = "0x3e" - register "btn_avg" = "4" - register "adc_1bit_rpt" = "1" - register "micbias_lvl" = "2600" - register "mic_amp_in_sel" = ""diff"" - device i2c 1a on end - end - end - device pci 16.1 on end # - I2C 1 - device pci 16.2 on - chip drivers/i2c/tpm - register "hid" = ""GOOG0005"" - register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" - device i2c 50 on end - end - end # - I2C 2 - device pci 16.3 on - chip drivers/i2c/hid - register "generic.hid" = ""WCOMNTN2"" - register "generic.desc" = ""WCOM Touchscreen"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "generic.detect" = "1" - register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "generic.reset_delay_ms" = "20" - register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "generic.enable_delay_ms" = "1" - register "generic.has_power_resource" = "1" - register "hid_desc_reg_offset" = "0x1" - device i2c 0xA on end - end - chip drivers/i2c/generic - register "hid" = ""ELAN0001"" - register "desc" = ""ELAN Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "20" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "1" - register "has_power_resource" = "true" - device i2c 10 on end - end - end # - I2C 3 - device pci 17.0 on - chip drivers/i2c/generic - register "hid" = ""ELAN0000"" - register "desc" = ""ELAN Touchpad"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" - register "wake" = "GPE0_DW1_15" - register "detect" = "1" - device i2c 15 on end - end - end # - I2C 4 - device pci 17.1 off end # - I2C 5 - device pci 17.2 off end # - I2C 6 - device pci 17.3 off end # - I2C 7 - device pci 18.0 on end # - UART 0 - device pci 18.1 on end # - UART 1 - device pci 18.2 on end # - UART 2 - device pci 18.3 off end # - UART 3 - device pci 19.0 on end # - SPI 0 - device pci 19.1 off end # - SPI 1 - device pci 19.2 off end # - SPI 2 - device pci 1a.0 on end # - PWM - device pci 1b.0 on end # - SDCARD - device pci 1c.0 on end # - eMMC - device pci 1e.0 off end # - SDIO - device pci 1f.0 on # - LPC - chip ec/google/chromeec - device pnp 0c09.0 on end - end - end - device pci 1f.1 on end # - SMBUS - end -end diff --git a/src/mainboard/google/reef/variants/pyro/overridetree.cb b/src/mainboard/google/reef/variants/pyro/overridetree.cb new file mode 100644 index 00000000000..f669639695a --- /dev/null +++ b/src/mainboard/google/reef/variants/pyro/overridetree.cb @@ -0,0 +1,74 @@ +chip soc/intel/apollolake + # Intel Common SoC Config (no i2c[5]) + register "common_soc_config" = "{ + .i2c[0] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 104, + .fall_time_ns = 52, + }, + .i2c[2] = { + .early_init = 1, + .speed = I2C_SPEED_FAST, + .rise_time_ns = 50, + .fall_time_ns = 23, + }, + .i2c[3] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 76, + .fall_time_ns = 164, + }, + .i2c[4] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 90, + .fall_time_ns = 164, + }, + }" + + # Override USB2 PER PORT register (PORT 0) + register "usb2eye[0]" = "{ + .Usb20PerPortPeTxiSet = 7, + .Usb20PerPortTxiSet = 1, + .Usb20IUsbTxEmphasisEn = 3, + .Usb20PerPortTxPeHalf = 0, + }" + + # Override USB2 PER PORT register (PORT 1) + register "usb2eye[1]" = "{ + .Usb20PerPortPeTxiSet = 7, + .Usb20PerPortTxiSet = 2, + .Usb20IUsbTxEmphasisEn = 3, + .Usb20PerPortTxPeHalf = 0, + }" + + device domain 0 on + device ref i2c3 on + chip drivers/i2c/hid + register "generic.hid" = ""WCOMNTN2"" + register "generic.desc" = ""WCOM Touchscreen"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "generic.detect" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "generic.reset_delay_ms" = "20" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "generic.enable_delay_ms" = "1" + register "generic.has_power_resource" = "1" + register "hid_desc_reg_offset" = "0x1" + device i2c 0xA on end + end + chip drivers/i2c/generic + register "hid" = ""ELAN0001"" + register "desc" = ""ELAN Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "20" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "1" + register "has_power_resource" = "true" + device i2c 10 on end + end + end + device ref i2c5 off end + device ref i2c6 off end + end +end diff --git a/src/mainboard/google/reef/variants/sand/devicetree.cb b/src/mainboard/google/reef/variants/sand/devicetree.cb deleted file mode 100644 index f27d26a5e42..00000000000 --- a/src/mainboard/google/reef/variants/sand/devicetree.cb +++ /dev/null @@ -1,232 +0,0 @@ -chip soc/intel/apollolake - - register "pcie_rp_clkreq_pin[0]" = "0" # wifi/bt - # Disable unused clkreq of PCIe root ports - register "pcie_rp_clkreq_pin[1]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[2]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[3]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[4]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[5]" = "CLKREQ_DISABLED" - - # GPIO for PERST_0 - # If the Board has PERST_0 signal, assign the GPIO - # If the Board does not have PERST_0, assign GPIO_PRT0_UDEF - register "prt0_gpio" = "GPIO_122" - - # EMMC TX DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [14:8] steps of delay for HS400, each 125ps. - # [6:0] steps of delay for SDR104/HS200, each 125ps. - register "emmc_tx_data_cntl1" = "0x0C16" - - # EMMC TX DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_tx_data_cntl2" = "0x28162828" - - # EMMC RX CMD/DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_rx_cmd_data_cntl1" = "0x00181717" - - # EMMC RX CMD/DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [17:16] stands for Rx Clock before Output Buffer - # [14:8] steps of delay for Auto Tuning Mode, each 125ps. - # [6:0] steps of delay for HS200, each 125ps. - register "emmc_rx_cmd_data_cntl2" = "0x10008" - - # Enable DPTF - register "dptf_enable" = "true" - - # PL1 override 12 W: the energy calculation is wrong with the - # current VR solution. Experiments show that SoC TDP max (6W) can - # be reached when RAPL PL1 is set to 12W. - # Set RAPL PL2 to 15W. - register "power_limits_config" = "{ - .tdp_pl1_override = 12, - .tdp_pl2_override = 15, - }" - - # Enable Audio Clock and Power gating - register "hdaudio_clk_gate_enable" = "1" - register "hdaudio_pwr_gate_enable" = "1" - register "hdaudio_bios_config_lockdown" = "1" - - # Enable lpss s0ix - register "lpss_s0ix_enable" = "true" - - # GPE configuration - # Note that GPE events called out in ASL code rely on this - # route, i.e., if this route changes then the affected GPE - # offset bits also need to be changed. This sets the PMC register - # GPE_CFG fields. - register "gpe0_dw1" = "PMC_GPE_N_31_0" - register "gpe0_dw2" = "PMC_GPE_N_63_32" - register "gpe0_dw3" = "PMC_GPE_SW_31_0" - - # Intel Common SoC Config - #+-------------------+---------------------------+ - #| Field | Value | - #+-------------------+---------------------------+ - #| I2C0 | Audio | - #| I2C2 | TPM | - #| I2C3 | Touchscreen | - #| I2C4 | Trackpad | - #| I2C5 | Digitizer | - #+-------------------+---------------------------+ - register "common_soc_config" = "{ - .i2c[0] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 104, - .fall_time_ns = 52, - }, - .i2c[2] = { - .early_init = 1, - .speed = I2C_SPEED_FAST, - .rise_time_ns = 57, - .fall_time_ns = 28, - }, - .i2c[3] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 76, - .fall_time_ns = 164, - }, - .i2c[4] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 114, - .fall_time_ns = 164, - }, - .i2c[5] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 152, - .fall_time_ns = 30, - }, - }" - - # Minimum SLP S3 assertion width 28ms. - register "slp_s3_assertion_width_usecs" = "28000" - - device domain 0 on - device pci 00.0 on end # - Host Bridge - device pci 00.1 on end # - DPTF - device pci 00.2 off end # - NPK - device pci 02.0 on # - Gen - register "gfx" = "GMA_DEFAULT_PANEL(0)" - end - device pci 03.0 off end # - Iunit - device pci 0d.0 on end # - P2SB - device pci 0d.1 on end # - PMC - device pci 0d.2 on end # - SPI - device pci 0d.3 on end # - Shared SRAM - device pci 0e.0 on # - Audio - chip drivers/generic/max98357a - register "hid" = ""MX98357A"" - register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" - register "sdmode_delay" = "5" - device generic 0 on end - end - end - device pci 0f.0 on end # - CSE - device pci 11.0 off end # - ISH - device pci 12.0 off end # - SATA - device pci 13.0 off end # - Root Port 2 - PCIe-A 0 - device pci 13.1 off end # - Root Port 3 - PCIe-A 1 - device pci 13.2 off end # - Root Port 4 - PCIe-A 2 - device pci 13.3 off end # - Root Port 5 - PCIe-A 3 - device pci 14.0 on - chip drivers/wifi/generic - register "wake" = "GPE0_DW3_00" - device pci 00.0 on end - end - end # - Root Port 0 - PCIe-B 0 - Wifi - device pci 14.1 off end # - Root Port 1 - PCIe-B 1 - device pci 15.0 on end # - XHCI - device pci 15.1 off end # - XDCI - device pci 16.0 on # - I2C 0 - chip drivers/i2c/da7219 - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" - register "btn_cfg" = "50" - register "mic_det_thr" = "200" - register "jack_ins_deb" = "20" - register "jack_det_rate" = ""32ms_64ms"" - register "jack_rem_deb" = "1" - register "a_d_btn_thr" = "0xa" - register "d_b_btn_thr" = "0x16" - register "b_c_btn_thr" = "0x21" - register "c_mic_btn_thr" = "0x3e" - register "btn_avg" = "4" - register "adc_1bit_rpt" = "1" - register "micbias_lvl" = "2600" - register "mic_amp_in_sel" = ""diff"" - device i2c 1a on end - end - end - device pci 16.1 on end # - I2C 1 - device pci 16.2 on - chip drivers/i2c/tpm - register "hid" = ""GOOG0005"" - register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" - device i2c 50 on end - end - end # - I2C 2 - device pci 16.3 on - chip drivers/i2c/generic - register "hid" = ""RAYD0001"" - register "desc" = ""Raydium Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "20" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "1" - register "has_power_resource" = "true" - device i2c 39 on end - end - end # - I2C 3 - device pci 17.0 on - chip drivers/i2c/generic - register "hid" = ""ELAN0000"" - register "desc" = ""ELAN Touchpad"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" - register "wake" = "GPE0_DW1_15" - register "detect" = "1" - device i2c 15 on end - end - end # - I2C 4 - device pci 17.1 on - chip drivers/i2c/hid - register "generic.hid" = ""WCOM50C1"" - register "generic.desc" = ""WCOM Digitizer"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_13_IRQ)" - register "hid_desc_reg_offset" = "0x1" - device i2c 0x9 on end - end - end # - I2C 5 - device pci 17.2 off end # - I2C 6 - device pci 17.3 off end # - I2C 7 - device pci 18.0 on end # - UART 0 - device pci 18.1 on end # - UART 1 - device pci 18.2 on end # - UART 2 - device pci 18.3 off end # - UART 3 - device pci 19.0 on end # - SPI 0 - device pci 19.1 off end # - SPI 1 - device pci 19.2 off end # - SPI 2 - device pci 1a.0 on end # - PWM - device pci 1b.0 on end # - SDCARD - device pci 1c.0 on end # - eMMC - device pci 1e.0 off end # - SDIO - device pci 1f.0 on # - LPC - chip ec/google/chromeec - device pnp 0c09.0 on end - end - end - device pci 1f.1 on end # - SMBUS - end -end diff --git a/src/mainboard/google/reef/variants/sand/overridetree.cb b/src/mainboard/google/reef/variants/sand/overridetree.cb new file mode 100644 index 00000000000..7571a772bc6 --- /dev/null +++ b/src/mainboard/google/reef/variants/sand/overridetree.cb @@ -0,0 +1,48 @@ +chip soc/intel/apollolake + # Intel Common SoC Config (i2c[4] without data_hold_time_ns) + register "common_soc_config" = "{ + .i2c[0] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 104, + .fall_time_ns = 52, + }, + .i2c[2] = { + .early_init = 1, + .speed = I2C_SPEED_FAST, + .rise_time_ns = 57, + .fall_time_ns = 28, + }, + .i2c[3] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 76, + .fall_time_ns = 164, + }, + .i2c[4] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 114, + .fall_time_ns = 164, + }, + .i2c[5] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 152, + .fall_time_ns = 30, + }, + }" + + device domain 0 on + device ref i2c3 on + chip drivers/i2c/generic + register "hid" = ""RAYD0001"" + register "desc" = ""Raydium Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "20" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "1" + register "has_power_resource" = "true" + device i2c 39 on end + end + end + end +end diff --git a/src/mainboard/google/reef/variants/snappy/devicetree.cb b/src/mainboard/google/reef/variants/snappy/devicetree.cb deleted file mode 100644 index e755776aae5..00000000000 --- a/src/mainboard/google/reef/variants/snappy/devicetree.cb +++ /dev/null @@ -1,300 +0,0 @@ -chip soc/intel/apollolake - - register "pcie_rp_clkreq_pin[0]" = "0" # wifi/bt - # Disable unused clkreq of PCIe root ports - register "pcie_rp_clkreq_pin[1]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[2]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[3]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[4]" = "CLKREQ_DISABLED" - register "pcie_rp_clkreq_pin[5]" = "CLKREQ_DISABLED" - - # GPIO for PERST_0 - # If the Board has PERST_0 signal, assign the GPIO - # If the Board does not have PERST_0, assign GPIO_PRT0_UDEF - register "prt0_gpio" = "GPIO_122" - - # GPIO for SD card detect - register "sdcard_cd_gpio" = "GPIO_177" - - # EMMC TX DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [14:8] steps of delay for HS400, each 125ps. - # [6:0] steps of delay for SDR104/HS200, each 125ps. - register "emmc_tx_data_cntl1" = "0x0C16" - - # EMMC TX DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_tx_data_cntl2" = "0x28162828" - - # EMMC RX CMD/DATA Delay 1 - # Refer to EDS-Vol2-22.3. - # [30:24] steps of delay for SDR50, each 125ps. - # [22:16] steps of delay for DDR50, each 125ps. - # [14:8] steps of delay for SDR25/HS50, each 125ps. - # [6:0] steps of delay for SDR12, each 125ps. - register "emmc_rx_cmd_data_cntl1" = "0x00181717" - - # EMMC RX CMD/DATA Delay 2 - # Refer to EDS-Vol2-22.3. - # [17:16] stands for Rx Clock before Output Buffer - # [14:8] steps of delay for Auto Tuning Mode, each 125ps. - # [6:0] steps of delay for HS200, each 125ps. - register "emmc_rx_cmd_data_cntl2" = "0x10008" - - # Enable DPTF - register "dptf_enable" = "true" - - # PL1 override 12 W: the energy calculation is wrong with the - # current VR solution. Experiments show that SoC TDP max (6W) can - # be reached when RAPL PL1 is set to 12W. - # Set RAPL PL2 to 15W. - register "power_limits_config" = "{ - .tdp_pl1_override = 12, - .tdp_pl2_override = 15, - }" - - # Enable Audio Clock and Power gating - register "hdaudio_clk_gate_enable" = "1" - register "hdaudio_pwr_gate_enable" = "1" - register "hdaudio_bios_config_lockdown" = "1" - - # Enable lpss s0ix - register "lpss_s0ix_enable" = "true" - - # GPE configuration - # Note that GPE events called out in ASL code rely on this - # route, i.e., if this route changes then the affected GPE - # offset bits also need to be changed. This sets the PMC register - # GPE_CFG fields. - register "gpe0_dw1" = "PMC_GPE_N_31_0" - register "gpe0_dw2" = "PMC_GPE_N_63_32" - register "gpe0_dw3" = "PMC_GPE_SW_31_0" - - # Intel Common SoC Config - #+-------------------+---------------------------+ - #| Field | Value | - #+-------------------+---------------------------+ - #| I2C0 | Audio | - #| I2C2 | TPM | - #| I2C3 | Touchscreen | - #| I2C4 | Trackpad | - #| I2C5 | Digitizer | - #+-------------------+---------------------------+ - register "common_soc_config" = "{ - .i2c[0] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 44, - .fall_time_ns = 22, - }, - .i2c[2] = { - .early_init = 1, - .speed = I2C_SPEED_FAST, - .rise_time_ns = 40, - .fall_time_ns = 20, - }, - .i2c[3] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 70, - .fall_time_ns = 164, - }, - .i2c[4] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 20, - .fall_time_ns = 164, - }, - .i2c[5] = { - .speed = I2C_SPEED_FAST, - .rise_time_ns = 152, - .fall_time_ns = 30, - }, - }" - - # Minimum SLP S3 assertion width 28ms. - register "slp_s3_assertion_width_usecs" = "28000" - - # Override USB2 PER PORT register (PORT 1) - register "usb2eye[1]" = "{ - .Usb20PerPortPeTxiSet = 7, - .Usb20PerPortTxiSet = 0, - }" - - device domain 0 on - device pci 00.0 on end # - Host Bridge - device pci 00.1 on end # - DPTF - device pci 00.2 off end # - NPK - device pci 02.0 on # - Gen - register "gfx" = "GMA_DEFAULT_PANEL(0)" - end - device pci 03.0 off end # - Iunit - device pci 0d.0 on end # - P2SB - device pci 0d.1 on end # - PMC - device pci 0d.2 on end # - SPI - device pci 0d.3 on end # - Shared SRAM - device pci 0e.0 on # - Audio - chip drivers/generic/max98357a - register "hid" = ""MX98357A"" - register "sdmode_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_76)" - register "sdmode_delay" = "5" - device generic 0 on end - end - end - device pci 0f.0 on end # - CSE - device pci 11.0 off end # - ISH - device pci 12.0 off end # - SATA - device pci 13.0 off end # - Root Port 2 - PCIe-A 0 - device pci 13.1 off end # - Root Port 3 - PCIe-A 1 - device pci 13.2 off end # - Root Port 4 - PCIe-A 2 - device pci 13.3 off end # - Root Port 5 - PCIe-A 3 - device pci 14.0 on - chip drivers/wifi/generic - register "wake" = "GPE0_DW3_00" - device pci 00.0 on end - end - end # - Root Port 0 - PCIe-B 0 - Wifi - device pci 14.1 off end # - Root Port 1 - PCIe-B 1 - device pci 15.0 on end # - XHCI - device pci 15.1 off end # - XDCI - device pci 16.0 on # - I2C 0 - chip drivers/i2c/da7219 - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_116_IRQ)" - register "btn_cfg" = "50" - register "mic_det_thr" = "200" - register "jack_ins_deb" = "20" - register "jack_det_rate" = ""32ms_64ms"" - register "jack_rem_deb" = "1" - register "a_d_btn_thr" = "0xa" - register "d_b_btn_thr" = "0x16" - register "b_c_btn_thr" = "0x21" - register "c_mic_btn_thr" = "0x3e" - register "btn_avg" = "4" - register "adc_1bit_rpt" = "1" - register "micbias_lvl" = "2600" - register "mic_amp_in_sel" = ""diff"" - device i2c 1a on end - end - end - device pci 16.1 on end # - I2C 1 - device pci 16.2 on - chip drivers/i2c/tpm - register "hid" = ""GOOG0005"" - register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_28_IRQ)" - device i2c 50 on end - end - end # - I2C 2 - device pci 16.3 on - chip drivers/i2c/generic - register "hid" = ""ELAN0001"" - register "desc" = ""ELAN Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "20" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "1" - register "has_power_resource" = "true" - device i2c 10 on end - end - chip drivers/i2c/generic - register "hid" = ""MLFS0000"" - register "desc" = ""Melfas Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - # Melfas TS IC doesn't have reset pin design, current FW also not - # declare "ce-gpios" in ACPI _DSD to let Melfas TS driver to know - # "enable gpio#152 (VTSP) but because of kernel bug & Melfas TS driver - # is unable to separate clear power sequence path for certain - # TS IC (ex: MIT-410) and kernel will still obstain GPIO from _CRS - # by index "0" since no matched "gpio" in ACPI _DSD. - # coreboot needs to have "dummy pin" as workaround in order to let - # kernel driver grab "useless" GPIO to prevent Melfas TS driver cut - # power by driver itself. - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "1" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "5" - register "has_power_resource" = "true" - device i2c 34 on end - end - chip drivers/i2c/generic - register "hid" = ""RAYD0001"" - register "desc" = ""Raydium Touchscreen"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "detect" = "1" - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "reset_delay_ms" = "1" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "enable_delay_ms" = "50" - register "has_power_resource" = "true" - device i2c 39 on end - end - chip drivers/i2c/hid - register "generic.hid" = ""WDHT0002"" - register "generic.desc" = ""WDT Touchscreen"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "generic.detect" = "1" - register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "generic.reset_delay_ms" = "130" - register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "generic.enable_delay_ms" = "1" - register "generic.has_power_resource" = "1" - register "hid_desc_reg_offset" = "0x20" - device i2c 2c on end - end - chip drivers/i2c/hid - register "generic.hid" = ""GTCH7503"" - register "generic.desc" = ""G2TOUCH Touchscreen"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" - register "generic.detect" = "1" - register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" - register "generic.reset_delay_ms" = "50" - register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" - register "generic.enable_delay_ms" = "1" - register "generic.has_power_resource" = "1" - register "hid_desc_reg_offset" = "0x01" - device i2c 40 on end - end - end # - I2C 3 - device pci 17.0 on - chip drivers/i2c/generic - register "hid" = ""ELAN0000"" - register "desc" = ""ELAN Touchpad"" - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_18_IRQ)" - register "wake" = "GPE0_DW1_15" - register "detect" = "1" - device i2c 15 on end - end - end # - I2C 4 - device pci 17.1 on - chip drivers/i2c/hid - register "generic.hid" = ""WCOM50C1"" - register "generic.desc" = ""WCOM Digitizer"" - register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_13_IRQ)" - register "hid_desc_reg_offset" = "0x1" - device i2c 0x9 on end - end - end # - I2C 5 - device pci 17.2 off end # - I2C 6 - device pci 17.3 off end # - I2C 7 - device pci 18.0 on end # - UART 0 - device pci 18.1 on end # - UART 1 - device pci 18.2 on end # - UART 2 - device pci 18.3 off end # - UART 3 - device pci 19.0 on end # - SPI 0 - device pci 19.1 off end # - SPI 1 - device pci 19.2 off end # - SPI 2 - device pci 1a.0 on end # - PWM - device pci 1b.0 on end # - SDCARD - device pci 1c.0 on end # - eMMC - device pci 1e.0 off end # - SDIO - device pci 1f.0 on # - LPC - chip ec/google/chromeec - device pnp 0c09.0 on end - end - end - device pci 1f.1 on end # - SMBUS - end -end diff --git a/src/mainboard/google/reef/variants/snappy/overridetree.cb b/src/mainboard/google/reef/variants/snappy/overridetree.cb new file mode 100644 index 00000000000..3c420d4ddb6 --- /dev/null +++ b/src/mainboard/google/reef/variants/snappy/overridetree.cb @@ -0,0 +1,113 @@ +chip soc/intel/apollolake + # Intel Common SoC Config + register "common_soc_config" = "{ + .i2c[0] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 44, + .fall_time_ns = 22, + }, + .i2c[2] = { + .early_init = 1, + .speed = I2C_SPEED_FAST, + .rise_time_ns = 40, + .fall_time_ns = 20, + }, + .i2c[3] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 70, + .fall_time_ns = 164, + }, + .i2c[4] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 20, + .fall_time_ns = 164, + }, + .i2c[5] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 152, + .fall_time_ns = 30, + }, + }" + + # Override USB2 PER PORT register (PORT 1) + register "usb2eye[1]" = "{ + .Usb20PerPortPeTxiSet = 7, + .Usb20PerPortTxiSet = 0, + }" + + device domain 0 on + device ref i2c3 on + chip drivers/i2c/generic + register "hid" = ""ELAN0001"" + register "desc" = ""ELAN Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "20" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "1" + register "has_power_resource" = "true" + device i2c 10 on end + end + chip drivers/i2c/generic + register "hid" = ""MLFS0000"" + register "desc" = ""Melfas Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + # Melfas TS IC doesn't have reset pin design, current FW also not + # declare "ce-gpios" in ACPI _DSD to let Melfas TS driver to know + # "enable gpio#152 (VTSP) but because of kernel bug & Melfas TS driver + # is unable to separate clear power sequence path for certain + # TS IC (ex: MIT-410) and kernel will still obstain GPIO from _CRS + # by index "0" since no matched "gpio" in ACPI _DSD. + # coreboot needs to have "dummy pin" as workaround in order to let + # kernel driver grab "useless" GPIO to prevent Melfas TS driver cut + # power by driver itself. + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "1" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "5" + register "has_power_resource" = "true" + device i2c 34 on end + end + chip drivers/i2c/generic + register "hid" = ""RAYD0001"" + register "desc" = ""Raydium Touchscreen"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "detect" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "reset_delay_ms" = "1" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "enable_delay_ms" = "50" + register "has_power_resource" = "true" + device i2c 39 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""WDHT0002"" + register "generic.desc" = ""WDT Touchscreen"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "generic.detect" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "generic.reset_delay_ms" = "130" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "generic.enable_delay_ms" = "1" + register "generic.has_power_resource" = "1" + register "hid_desc_reg_offset" = "0x20" + device i2c 2c on end + end + chip drivers/i2c/hid + register "generic.hid" = ""GTCH7503"" + register "generic.desc" = ""G2TOUCH Touchscreen"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_21_IRQ)" + register "generic.detect" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_36)" + register "generic.reset_delay_ms" = "50" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_152)" + register "generic.enable_delay_ms" = "1" + register "generic.has_power_resource" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 40 on end + end + end + end +end diff --git a/src/mainboard/google/rex/Kconfig b/src/mainboard/google/rex/Kconfig index f9afd381410..b5f8858033c 100644 --- a/src/mainboard/google/rex/Kconfig +++ b/src/mainboard/google/rex/Kconfig @@ -259,6 +259,9 @@ config UART_FOR_CONSOLE int default 0 +config CBFS_SIZE + default 0x1000000 + config OVERRIDE_DEVICETREE default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" diff --git a/src/mainboard/google/rex/Kconfig.name b/src/mainboard/google/rex/Kconfig.name index 96aa4c63f14..0d1da6f015f 100644 --- a/src/mainboard/google/rex/Kconfig.name +++ b/src/mainboard/google/rex/Kconfig.name @@ -1,12 +1,12 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Rex" +comment "Rex (Intel MeteorLake (Ultra 1st Gen))" config BOARD_GOOGLE_DEKU - bool "-> Deku" + bool "-> Deku" config BOARD_GOOGLE_DEKU4ES - bool "-> Deku4ES" + bool "-> Deku4ES" config BOARD_GOOGLE_KARIS bool "-> Karis (Acer Chromebook Plus Spin 714)" @@ -15,25 +15,25 @@ config BOARD_GOOGLE_KARIS4ES bool "-> Karis4ES" config BOARD_GOOGLE_OVIS - bool "-> Ovis" + bool "-> Ovis" config BOARD_GOOGLE_OVIS4ES - bool "-> Ovis4ES" + bool "-> Ovis4ES" config BOARD_GOOGLE_REX0 - bool "-> Rex 0" + bool "-> Rex 0" config BOARD_GOOGLE_REX_EC_ISH - bool "-> Rex EC ISH" + bool "-> Rex EC ISH" config BOARD_GOOGLE_REX4ES - bool "-> Rex4ES" + bool "-> Rex4ES" config BOARD_GOOGLE_REX4ES_EC_ISH - bool "-> Rex4ES EC ISH" + bool "-> Rex4ES EC ISH" config BOARD_GOOGLE_REX64 - bool "-> Rex 64" + bool "-> Rex 64" config BOARD_GOOGLE_SCREEBO bool "-> Screebo (ASUS ExpertBook CX54 Chromebook Plus (CX5403))" diff --git a/src/mainboard/google/rex/cfr.c b/src/mainboard/google/rex/cfr.c index a84d9aae4d1..d64bbc7b79a 100644 --- a/src/mainboard/google/rex/cfr.c +++ b/src/mainboard/google/rex/cfr.c @@ -1,4 +1,3 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ #include diff --git a/src/mainboard/google/rex/variants/kanix/overridetree.cb b/src/mainboard/google/rex/variants/kanix/overridetree.cb index a9feef6b16e..37f3d7ca0a9 100644 --- a/src/mainboard/google/rex/variants/kanix/overridetree.cb +++ b/src/mainboard/google/rex/variants/kanix/overridetree.cb @@ -152,7 +152,7 @@ chip soc/intel/meteorlake device domain 0 on device ref igpu on chip drivers/gfx/generic - register "device_count" = "6" + register "device_count" = "7" # DDIA for eDP register "device[0].name" = ""LCD0"" register "device[0].type" = "panel" @@ -170,6 +170,11 @@ chip soc/intel/meteorlake register "device[4].pld" = "ACPI_PLD_TYPE_C(LEFT, RIGHT, ACPI_PLD_GROUP(2, 1))" # TCP3 (DP-4) unused register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" + device generic 0 on end end end # Integrated Graphics Device @@ -505,11 +510,12 @@ chip soc/intel/meteorlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Hi-556 Camera"" + register "sensor_name" = ""CJFLE25"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "4" register "ssdb.platform" = "PLAT_MTL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" diff --git a/src/mainboard/google/rex/variants/karis/overridetree.cb b/src/mainboard/google/rex/variants/karis/overridetree.cb index 580bb9d0337..c24c7c7cd79 100644 --- a/src/mainboard/google/rex/variants/karis/overridetree.cb +++ b/src/mainboard/google/rex/variants/karis/overridetree.cb @@ -130,7 +130,7 @@ chip soc/intel/meteorlake device domain 0 on device ref igpu on chip drivers/gfx/generic - register "device_count" = "6" + register "device_count" = "7" # DDIA for eDP register "device[0].name" = ""LCD0"" register "device[0].type" = "panel" @@ -148,6 +148,10 @@ chip soc/intel/meteorlake register "device[4].pld" = "ACPI_PLD_TYPE_C(LEFT, RIGHT, ACPI_PLD_GROUP(2, 1))" # TCP3 (DP-4) unused register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" device generic 0 on end end end # Integrated Graphics Device @@ -460,11 +464,12 @@ chip soc/intel/meteorlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Hi-556 Camera"" + register "sensor_name" = ""CJFLE25"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "4" register "ssdb.platform" = "PLAT_MTL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" diff --git a/src/mainboard/google/rex/variants/rex0/overridetree.cb b/src/mainboard/google/rex/variants/rex0/overridetree.cb index c82d773ff00..d26dd567ee8 100644 --- a/src/mainboard/google/rex/variants/rex0/overridetree.cb +++ b/src/mainboard/google/rex/variants/rex0/overridetree.cb @@ -148,7 +148,7 @@ chip soc/intel/meteorlake device domain 0 on device ref igpu on chip drivers/gfx/generic - register "device_count" = "6" + register "device_count" = "7" # DDIA for eDP register "device[0].name" = ""LCD0"" register "device[0].type" = "panel" @@ -167,6 +167,11 @@ chip soc/intel/meteorlake register "device[4].pld" = "ACPI_PLD_TYPE_C(RIGHT, LEFT, ACPI_PLD_GROUP(2, 1))" # TCP3 (DP-4) is unused for any ports but still enumerated in the kernel, so GFX device is added for TCP3 register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" + device generic 0 on end end end # Integrated Graphics Device @@ -466,10 +471,11 @@ chip soc/intel/meteorlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 13b10 Camera"" + register "sensor_name" = ""09B13U"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "0" + register "ssdb.link_used" = "4" register "ssdb.platform" = "PLAT_MTL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" @@ -623,11 +629,12 @@ chip soc/intel/meteorlake register "acpi_uid" = "0" register "acpi_name" = ""CAM1"" register "chip_name" = ""Hi-556 Camera"" + register "sensor_name" = ""CJFLE25"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "has_power_resource" = "true" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "0" register "ssdb.platform" = "PLAT_MTL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" diff --git a/src/mainboard/google/rex/variants/screebo/overridetree.cb b/src/mainboard/google/rex/variants/screebo/overridetree.cb index b1e8ff7ce19..60d28bcaa53 100644 --- a/src/mainboard/google/rex/variants/screebo/overridetree.cb +++ b/src/mainboard/google/rex/variants/screebo/overridetree.cb @@ -152,6 +152,35 @@ chip soc/intel/meteorlake }" device domain 0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "7" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + # Internal panel on the first port of the graphics chip + register "device[0].type" = "panel" + # DDIB for HDMI + register "device[1].name" = ""DD01"" + # TCP0 (DP-1) for port C0 + register "device[2].name" = ""DD02"" + register "device[2].use_pld" = "true" + register "device[2].pld" = "ACPI_PLD_TYPE_C(LEFT, LEFT, ACPI_PLD_GROUP(1, 1))" + # TCP1 (DP-2) is unused for any ports but still enumerated in the kernel + register "device[3].name" = ""DD03"" + # TCP2 (DP-3) for port C1 + register "device[4].name" = ""DD04"" + register "device[4].use_pld" = "true" + register "device[4].pld" = "ACPI_PLD_TYPE_C(RIGHT, RIGHT, ACPI_PLD_GROUP(2, 1))" + # TCP3 (DP-4) is unused for any ports but still enumerated in the kernel + register "device[5].name" = ""DD05"" + # IPUA for IPUs + register "device[6].name" = ""IPUA"" + register "device[6].non_vga_device" = "true" + register "device[6].addr" = "0x3480" + + device generic 0 on end + end + end # Integrated Graphics Device device ref dtt on chip drivers/intel/dptf ## sensor information @@ -513,9 +542,10 @@ chip soc/intel/meteorlake register "acpi_uid" = "0" register "acpi_name" = ""CAM0"" register "chip_name" = ""Ov 08X40 Camera"" + register "sensor_name" = ""CJFME55"" register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "4" register "ssdb.platform" = "PLAT_MTL" register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" register "rom_address" = "0x50" diff --git a/src/mainboard/google/sarien/Kconfig b/src/mainboard/google/sarien/Kconfig index dcf94470ecf..d4f5171d611 100644 --- a/src/mainboard/google/sarien/Kconfig +++ b/src/mainboard/google/sarien/Kconfig @@ -110,4 +110,7 @@ config VBOOT config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/default.fmd" if !CHROMEOS +config CBFS_SIZE + default 0x1000000 + endif # BOARD_GOOGLE_BASEBOARD_SARIEN diff --git a/src/mainboard/google/sarien/Kconfig.name b/src/mainboard/google/sarien/Kconfig.name index ad31cb12858..817fd6d278a 100644 --- a/src/mainboard/google/sarien/Kconfig.name +++ b/src/mainboard/google/sarien/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Sarien" +comment "Sarien (Intel WhiskeyLake (8th Gen))" config BOARD_GOOGLE_ARCADA bool "-> Arcada (Latitude 5300 2-in-1 Chromebook Enterprise)" diff --git a/src/mainboard/google/sarien/cfr.c b/src/mainboard/google/sarien/cfr.c index aa9265db7d8..805b2870a12 100644 --- a/src/mainboard/google/sarien/cfr.c +++ b/src/mainboard/google/sarien/cfr.c @@ -1,4 +1,3 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ #include diff --git a/src/mainboard/google/skyrim/Kconfig.name b/src/mainboard/google/skyrim/Kconfig.name index 5a9668c5980..12d28eee978 100644 --- a/src/mainboard/google/skyrim/Kconfig.name +++ b/src/mainboard/google/skyrim/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Skyrim" +comment "Skyrim (AMD Ryzen Mobile 7000 (Mendocino))" config BOARD_GOOGLE_CRYSTALDRIFT bool "-> Crystaldrift (SPC Chromebook V1)" diff --git a/src/mainboard/google/skywalker/Kconfig b/src/mainboard/google/skywalker/Kconfig index 6e8848af94f..a61cb6d46f7 100644 --- a/src/mainboard/google/skywalker/Kconfig +++ b/src/mainboard/google/skywalker/Kconfig @@ -6,10 +6,13 @@ config BOARD_GOOGLE_SKYWALKER_COMMON BOARD_GOOGLE_BAZE || \ BOARD_GOOGLE_DOOKU || \ BOARD_GOOGLE_GROGU || \ + BOARD_GOOGLE_JAINA || \ + BOARD_GOOGLE_MACE || \ BOARD_GOOGLE_OBIWAN || \ BOARD_GOOGLE_PADME || \ BOARD_GOOGLE_SKYWALKER || \ BOARD_GOOGLE_TARKIN || \ + BOARD_GOOGLE_VADER || \ BOARD_GOOGLE_YODA if BOARD_GOOGLE_SKYWALKER_COMMON @@ -55,10 +58,13 @@ config MAINBOARD_PART_NUMBER default "Baze" if BOARD_GOOGLE_BAZE default "Dooku" if BOARD_GOOGLE_DOOKU default "Grogu" if BOARD_GOOGLE_GROGU + default "Jaina" if BOARD_GOOGLE_JAINA + default "Mace" if BOARD_GOOGLE_MACE default "Obiwan" if BOARD_GOOGLE_OBIWAN default "Padme" if BOARD_GOOGLE_PADME default "Skywalker" if BOARD_GOOGLE_SKYWALKER default "Tarkin" if BOARD_GOOGLE_TARKIN + default "Vader" if BOARD_GOOGLE_VADER default "Yoda" if BOARD_GOOGLE_YODA config BOOT_DEVICE_SPI_FLASH_BUS diff --git a/src/mainboard/google/skywalker/Kconfig.name b/src/mainboard/google/skywalker/Kconfig.name index 6c67574e945..ad04340621a 100644 --- a/src/mainboard/google/skywalker/Kconfig.name +++ b/src/mainboard/google/skywalker/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only OR MIT -comment "Skywalker" +comment "Skywalker (MediaTek Kompanio 540 (MT8189))" config BOARD_GOOGLE_ANAKIN bool "-> Anakin" @@ -14,11 +14,17 @@ config BOARD_GOOGLE_DOOKU config BOARD_GOOGLE_GROGU bool "-> Grogu" +config BOARD_GOOGLE_JAINA + bool "-> Jaina" + +config BOARD_GOOGLE_MACE + bool "-> Mace" + config BOARD_GOOGLE_OBIWAN bool "-> Obiwan" config BOARD_GOOGLE_PADME - bool "-> Padme" + bool "-> Padme" config BOARD_GOOGLE_SKYWALKER bool "-> Skywalker" @@ -26,5 +32,8 @@ config BOARD_GOOGLE_SKYWALKER config BOARD_GOOGLE_TARKIN bool "-> Tarkin" +config BOARD_GOOGLE_VADER + bool "-> Vader" + config BOARD_GOOGLE_YODA - bool "-> Yoda" + bool "-> Yoda" diff --git a/src/mainboard/google/skywalker/chromeos.c b/src/mainboard/google/skywalker/chromeos.c index eace485648a..bbb8fadcb5d 100644 --- a/src/mainboard/google/skywalker/chromeos.c +++ b/src/mainboard/google/skywalker/chromeos.c @@ -97,6 +97,16 @@ void fill_lb_gpios(struct lb_gpios *gpios) {GPIO_EDP_BL_EN_1V8.id, ACTIVE_HIGH, -1, "backlight enable"}, }; lb_add_gpios(gpios, edp_pwm_backlight_gpios, ARRAY_SIZE(edp_pwm_backlight_gpios)); + + if (CONFIG(BOARD_GOOGLE_PADME)) { + /* Panel power control GPIOs for Depthcharge power-off sequence */ + struct lb_gpio mipi_panel_gpios[] = { + {GPIO_EN_PP3300_EDP_X.id, ACTIVE_LOW, -1, "panel_resx"}, + {GPIO_EN_PP6000_MIPI_DISP.id, ACTIVE_HIGH, -1, "mipi_iovcc_en"}, + {GPIO_TCHSCR_RST_1V8_L.id, ACTIVE_LOW, -1, "mipi_tp_rstn"}, + }; + lb_add_gpios(gpios, mipi_panel_gpios, ARRAY_SIZE(mipi_panel_gpios)); + } } int cr50_plat_irq_status(void) diff --git a/src/mainboard/google/skywalker/mainboard.c b/src/mainboard/google/skywalker/mainboard.c index e219861b632..f7191e91400 100644 --- a/src/mainboard/google/skywalker/mainboard.c +++ b/src/mainboard/google/skywalker/mainboard.c @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +#include #include +#include +#include +#include #include #include #include @@ -15,6 +19,7 @@ #include #include #include +#include #include "gpio.h" #include "panel.h" @@ -103,6 +108,13 @@ static void power_on_fpmcu(void) gpio_output(GPIO_FP_RST_1V8_S3_L, 1); } +void mainboard_prepare_cr50_reset(void) +{ + printk(BIOS_INFO, "%s: Powering MIPI panel off\n", __func__); + if (mtk_mipi_panel_poweroff() < 0) + printk(BIOS_ERR, "%s: Failed to power off MIPI panel\n", __func__); +} + enum mtk_storage_type mainboard_get_storage_type(void) { uint32_t index = storage_id(); @@ -124,7 +136,9 @@ static void mainboard_init(struct device *dev) { mt6359p_init_pmif_arb(); - if (mainboard_get_storage_type() == STORAGE_EMMC) { + if (!fw_config_is_provisioned()) { + mtk_msdc_configure_emmc(true); + } else if (fw_config_probe(FW_CONFIG(STORAGE, STORAGE_EMMC))) { mtk_msdc_configure_emmc(true); mtcmos_ufs_power_off(); } @@ -164,3 +178,23 @@ struct chip_operations mainboard_ops = { .name = CONFIG_MAINBOARD_PART_NUMBER, .enable_dev = mainboard_enable, }; + +void lb_board(struct lb_header *header) +{ + const struct panel_serializable_data *mipi_data = mtk_get_mipi_panel_data(); + + if (!mipi_data) + return; + + size_t cmd_len = mipi_panel_get_commands_len(mipi_data->poweroff); + + if (!cmd_len) + return; + + struct lb_panel_poweroff *panel_poweroff = + (struct lb_panel_poweroff *)lb_new_record(header); + panel_poweroff->tag = LB_TAG_PANEL_POWEROFF; + panel_poweroff->size = ALIGN_UP(sizeof(*panel_poweroff) + cmd_len, + LB_ENTRY_ALIGN); + memcpy(panel_poweroff->cmd, mipi_data->poweroff, cmd_len); +} diff --git a/src/mainboard/google/skywalker/panel.c b/src/mainboard/google/skywalker/panel.c index 32d684217e3..5856cf40444 100644 --- a/src/mainboard/google/skywalker/panel.c +++ b/src/mainboard/google/skywalker/panel.c @@ -60,7 +60,7 @@ void mipi_panel_power_on(void) mdelay(10); } gpio_output(GPIO_EN_PP3300_EDP_X, 0); - mdelay(1); + mdelay(5); gpio_output(GPIO_EN_PP3300_EDP_X, 1); mdelay(1); gpio_output(GPIO_TCHSCR_RST_1V8_L, 0); diff --git a/src/mainboard/google/slippy/Kconfig b/src/mainboard/google/slippy/Kconfig index d9684d34b39..5420557d821 100644 --- a/src/mainboard/google/slippy/Kconfig +++ b/src/mainboard/google/slippy/Kconfig @@ -8,6 +8,7 @@ config BOARD_GOOGLE_BASEBOARD_SLIPPY select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select EC_GOOGLE_CHROMEEC select EC_GOOGLE_CHROMEEC_LPC + select EC_GOOGLE_CHROMEEC_NEEDS_BATTERY_WORKAROUND select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_OPTION_TABLE @@ -70,6 +71,9 @@ config OVERRIDE_DEVICETREE config INTEL_GMA_VBT_FILE default "src/mainboard/\$(MAINBOARDDIR)/data.vbt" +config CBFS_SIZE + default 0x600000 + config MAINBOARD_SMBIOS_MANUFACTURER string default "GOOGLE" diff --git a/src/mainboard/google/slippy/Kconfig.name b/src/mainboard/google/slippy/Kconfig.name index f258a2f9a45..fb07f75ed75 100644 --- a/src/mainboard/google/slippy/Kconfig.name +++ b/src/mainboard/google/slippy/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Slippy" +comment "Slippy (Intel Haswell (4th Gen))" config BOARD_GOOGLE_FALCO bool "-> Falco (HP Chromebook 14)" diff --git a/src/mainboard/google/smaug/Kconfig.name b/src/mainboard/google/smaug/Kconfig.name index 169a179aabd..5273f92f5a7 100644 --- a/src/mainboard/google/smaug/Kconfig.name +++ b/src/mainboard/google/smaug/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Smaug" +comment "Smaug (Nvidia Tegra X1 (T210))" config BOARD_GOOGLE_SMAUG bool "-> Smaug (Google Pixel C)" diff --git a/src/mainboard/google/storm/Kconfig.name b/src/mainboard/google/storm/Kconfig.name index d2f74da3e89..b252f99465f 100644 --- a/src/mainboard/google/storm/Kconfig.name +++ b/src/mainboard/google/storm/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Storm" +comment "Storm (Qualcomm IPQ8064)" config BOARD_GOOGLE_STORM bool "-> Storm (OnHub Router TGR1900)" diff --git a/src/mainboard/google/stout/Kconfig b/src/mainboard/google/stout/Kconfig index 2c354419d8d..25add1b3402 100644 --- a/src/mainboard/google/stout/Kconfig +++ b/src/mainboard/google/stout/Kconfig @@ -38,6 +38,9 @@ config VGA_BIOS_ID string default "8086,0156" +config CBFS_SIZE + default 0x600000 + config MAINBOARD_SMBIOS_MANUFACTURER string default "GOOGLE" diff --git a/src/mainboard/google/stout/Kconfig.name b/src/mainboard/google/stout/Kconfig.name index f3d61533cf1..a1fbee03ea0 100644 --- a/src/mainboard/google/stout/Kconfig.name +++ b/src/mainboard/google/stout/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Stout" +comment "Stout (Intel SandyBridge (2nd Gen))" config BOARD_GOOGLE_STOUT bool "-> Stout (Lenovo Thinkpad X131e Chromebook)" diff --git a/src/mainboard/google/trogdor/Kconfig.name b/src/mainboard/google/trogdor/Kconfig.name index c3a00ab2aad..a8d41ef0284 100644 --- a/src/mainboard/google/trogdor/Kconfig.name +++ b/src/mainboard/google/trogdor/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Trogdor" +comment "Trogdor (Qualcomm Snapdragon 7c (SC7180))" config BOARD_GOOGLE_BUBS bool "-> Bubs" @@ -12,10 +12,10 @@ config BOARD_GOOGLE_GELARSHIE bool "-> Gelarshie" config BOARD_GOOGLE_HOMESTAR - bool "-> Homestar" + bool "-> Homestar (Lenovo IdeaPad Duet 5 Chromebook)" config BOARD_GOOGLE_KINGOFTOWN - bool "-> Kingoftown" + bool "-> Kingoftown (HP Fortis 11 G9 Q Chromebook)" config BOARD_GOOGLE_LAZOR bool "-> Lazor (Acer Chromebook Spin 513, CP513-1H/1HL, R841T/LT)" @@ -27,16 +27,20 @@ config BOARD_GOOGLE_MRBLAND bool "-> Mrbland" config BOARD_GOOGLE_PAZQUEL - bool "-> Pazquel" + bool "-> Pazquel (see help text for details)" + help + The "Pazquel" board supports the following devices: + - Orbic Chromebook 4G + - Libera-Merdeka Chromebook C100/C110/C120/C150 config BOARD_GOOGLE_POMPOM - bool "-> Pompom" + bool "-> Pompom (Dynabook Chromebook C1)" config BOARD_GOOGLE_QUACKINGSTICK bool "-> Quackingstick (Acer Chromebook Tab 510 / Enterprise Tab 510)" config BOARD_GOOGLE_WORMDINGLER - bool "-> Wormdingler" + bool "-> Wormdingler (Lenovo IdeaPad Duet 3 Chromebook)" config BOARD_GOOGLE_TROGDOR bool "-> Trogdor" diff --git a/src/mainboard/google/veyron/Kconfig.name b/src/mainboard/google/veyron/Kconfig.name index 7e174a0931f..952e9a8047b 100644 --- a/src/mainboard/google/veyron/Kconfig.name +++ b/src/mainboard/google/veyron/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Veyron" +comment "Veyron (Rockchip RK3288)" config BOARD_GOOGLE_VEYRON_JAQ bool "-> Veyron_Jaq (Haier Chromebook 11)" diff --git a/src/mainboard/google/veyron_mickey/Kconfig.name b/src/mainboard/google/veyron_mickey/Kconfig.name index 207b447532c..ff62fd13892 100644 --- a/src/mainboard/google/veyron_mickey/Kconfig.name +++ b/src/mainboard/google/veyron_mickey/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Veyron Mickey" +comment "Veyron Mickey (Rockchip RK3288)" config BOARD_GOOGLE_VEYRON_MICKEY bool "-> Veyron_Mickey (Asus Chromebit CS10)" diff --git a/src/mainboard/google/veyron_rialto/Kconfig.name b/src/mainboard/google/veyron_rialto/Kconfig.name index 490752ea4dd..dd17d288717 100644 --- a/src/mainboard/google/veyron_rialto/Kconfig.name +++ b/src/mainboard/google/veyron_rialto/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Veyron Rialto" +comment "Veyron Rialto (Rockchip RK3288)" config BOARD_GOOGLE_VEYRON_RIALTO bool "-> Veyron_Rialto" diff --git a/src/mainboard/google/volteer/Kconfig b/src/mainboard/google/volteer/Kconfig index a7537c0fd28..dc586f1538a 100644 --- a/src/mainboard/google/volteer/Kconfig +++ b/src/mainboard/google/volteer/Kconfig @@ -105,8 +105,9 @@ config BOARD_GOOGLE_TRONDO config BOARD_GOOGLE_VOEMA select BOARD_GOOGLE_BASEBOARD_VOLTEER + select DRIVERS_GFX_GENERIC + select DRIVERS_INTEL_MIPI_CAMERA select INTEL_GMA_HAVE_VBT - select VARIANT_HAS_MIPI_CAMERA config BOARD_GOOGLE_VOLET select BOARD_GOOGLE_BASEBOARD_VOLTEER @@ -114,24 +115,27 @@ config BOARD_GOOGLE_VOLET config BOARD_GOOGLE_VOLTEER select BOARD_GOOGLE_BASEBOARD_VOLTEER + select DRIVERS_GFX_GENERIC + select DRIVERS_INTEL_MIPI_CAMERA select INTEL_CAR_NEM select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES - select VARIANT_HAS_MIPI_CAMERA config BOARD_GOOGLE_VOLTEER2 select BOARD_GOOGLE_BASEBOARD_VOLTEER select DRIVER_I2C_TPM_ACPI select DRIVERS_GENESYSLOGIC_GL9755 + select DRIVERS_GFX_GENERIC + select DRIVERS_INTEL_MIPI_CAMERA select INTEL_GMA_HAVE_VBT select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES - select VARIANT_HAS_MIPI_CAMERA config BOARD_GOOGLE_VOLTEER2_TI50 select BOARD_GOOGLE_BASEBOARD_VOLTEER select DRIVER_I2C_TPM_ACPI select DRIVERS_GENESYSLOGIC_GL9755 + select DRIVERS_GFX_GENERIC + select DRIVERS_INTEL_MIPI_CAMERA select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES - select VARIANT_HAS_MIPI_CAMERA config BOARD_GOOGLE_VOXEL select BOARD_GOOGLE_BASEBOARD_VOLTEER @@ -241,9 +245,8 @@ config VARIANT_DIR default "volteer2" if BOARD_GOOGLE_VOLTEER2_TI50 default "voxel" if BOARD_GOOGLE_VOXEL -config VARIANT_HAS_MIPI_CAMERA - bool - default n +config CBFS_SIZE + default 0x1000000 config USE_PM_ACPI_TIMER default n diff --git a/src/mainboard/google/volteer/Kconfig.name b/src/mainboard/google/volteer/Kconfig.name index c3a2401bc98..fcae344309a 100644 --- a/src/mainboard/google/volteer/Kconfig.name +++ b/src/mainboard/google/volteer/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Volteer" +comment "Volteer (Intel TigerLake (11th Gen))" config BOARD_GOOGLE_CHRONICLER bool "-> Chronicler (FMV Chromebook 14F)" diff --git a/src/mainboard/google/volteer/cfr.c b/src/mainboard/google/volteer/cfr.c index 76f12e232cc..3ddcdb1a194 100644 --- a/src/mainboard/google/volteer/cfr.c +++ b/src/mainboard/google/volteer/cfr.c @@ -1,4 +1,3 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ #include @@ -7,17 +6,13 @@ #include #include -static const struct sm_object touchpad_wake = SM_DECLARE_ENUM({ +static const struct sm_object touchpad_wake = SM_DECLARE_BOOL({ .opt_name = "touchpad_wake", .ui_name = "Touchpad Wake", .ui_helptext = "Enable or disable touchpad wake from sleep.\n" "Disabled by default to prevent random wakeups when\n" "the system is moved while sleeping.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = false, }); static struct sm_obj_form system = { diff --git a/src/mainboard/google/volteer/dsdt.asl b/src/mainboard/google/volteer/dsdt.asl index c200294e744..dbd36043aab 100644 --- a/src/mainboard/google/volteer/dsdt.asl +++ b/src/mainboard/google/volteer/dsdt.asl @@ -30,9 +30,6 @@ DefinitionBlock( #include #include #include -#if CONFIG(VARIANT_HAS_MIPI_CAMERA) - #include -#endif } /* Mainboard hooks */ #include "mainboard.asl" @@ -48,9 +45,4 @@ DefinitionBlock( } #include - -#if CONFIG(VARIANT_HAS_MIPI_CAMERA) - /* Camera */ - #include -#endif /* VARIANT_HAS_MIPI_CAMERA */ } diff --git a/src/mainboard/google/volteer/variants/baseboard/include/baseboard/acpi/mipi_camera.asl b/src/mainboard/google/volteer/variants/baseboard/include/baseboard/acpi/mipi_camera.asl deleted file mode 100644 index f22b4028653..00000000000 --- a/src/mainboard/google/volteer/variants/baseboard/include/baseboard/acpi/mipi_camera.asl +++ /dev/null @@ -1,650 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -Scope (\_SB.PCI0.IPU0) -{ - Name (_DSD, Package (0x02) /* _DSD: Device-Specific Data */ - { - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x02) - { - Package (0x02) - { - "port0", - "PRT0" - }, - Package (0x02) - { - "port1", - "PRT1" - } - } - }) - - Name (PRT0, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 5 - } - }, - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP00" - } - } - }) - - Name (PRT1, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 1 - } - }, - - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP10" - } - } - }) -} - -Scope (\_SB.PCI0.IPU0) -{ - Name (EP00, Package (0x02) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x04) - { - Package (0x02) - { - "endpoint", - 0 - }, - Package (0x02) - { - "clock-lanes", - 0 - }, - Package (0x02) - { - "data-lanes", - Package (0x04) - { - 1, - 0x02, - 0x03, - 0x04 - } - }, - Package (0x02) - { - "remote-endpoint", - Package (0x03) - { - ^I2C3.CAM0, - 0, - 0 - } - } - } - }) - Name (EP10, Package (0x02) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x04) - { - Package (0x02) - { - "endpoint", - 0 - }, - Package (0x02) - { - "clock-lanes", - 0 - }, - Package (0x02) - { - "data-lanes", - Package (0x02) - { - 1, - 0x02 - } - }, - Package (0x02) - { - "remote-endpoint", - Package (0x03) - { - ^I2C2.CAM1, - 0, - 0 - } - } - } - }) -} - -Scope (\_SB.PCI0.I2C3) -{ - /* Reference counter to track power control by RCAM and VCM */ - Name (REFC, 0) - PowerResource (RCPR, 0x00, 0x0000) - { - Name (STA, 0) - Method (_ON, 0, Serialized) /* Rear camera_ON_: Power On */ - { - /* Enable IMG_CLK */ - MCON(3,1) /* Clock 3, 19.2MHz */ - - /* Pull RST low */ - CTXS(GPP_F15) - - /* Pull SNRPWR_EN high */ - STXS(GPP_H14) - - If (REFC == 0) - { - /* Pull PWREN high */ - STXS(GPP_H20) - } - Sleep(2) /* reset pulse width */ - - REFC++ - - /* Pull RST high */ - STXS(GPP_F15) - - Sleep(1) /* t2 */ - - STA = 1 - } - Method (_OFF, 0, Serialized) /* Rear camera _OFF: Power Off */ - { - /* Disable IMG_CLK */ - Sleep(1) /* t0+t1 */ - MCOF(3) /* Clock 3 */ - - /* Pull RST low */ - CTXS(GPP_F15) - - If (REFC == 1) - { - /* Pull PWREN low */ - CTXS(GPP_H20) - } - REFC-- - - /* Pull SNRPWR_EN low */ - CTXS(GPP_H14) - - STA = 0 - } - Method (_STA, 0, NotSerialized) - { - Return (STA) - } - } - - Device (CAM0) - { - Name (_HID, "OVTI8856") - Name (_UID, 0) - Name (_DDN, "Ov 8856 Camera") /* _DDN: DOS Device Name */ - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - Name (_CRS, ResourceTemplate () /* _CRS: Current Resource Settings */ - { - I2cSerialBus (0x0010, ControllerInitiated, 0x00061A80, - AddressingMode7Bit, "\\_SB.PCI0.I2C3", - 0x00, ResourceConsumer, , - ) - }) - Name (_PR0, Package (0x01) /* _PR0: Power Resources for D0 */ - { - RCPR - }) - Name (_PR3, Package (0x01) /* _PR3: Power Resources for D3hot */ - { - RCPR - }) - Name (_DSD, Package (0x04) /* _DSD: Device-Specific Data */ - { - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "port0", - "PRT0" - } - }, - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x03) - { - Package (0x02) - { - "clock-frequency", - 0x0124F800 - }, - Package (0x02) - { - "lens-focus", - Package (0x01) - { - VCM0 - } - }, - Package (0x02) - { - "i2c-allow-low-power-probe", - 0x01 - } - } - }) - Name (PRT0, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 0 - } - }, - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP00" - } - } - }) - Name (EP00, Package (0x02) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x05) - { - Package (0x02) - { - "endpoint", - 0 - }, - Package (0x02) - { - "clock-lanes", - 0 - }, - Package (0x02) - { - "data-lanes", - Package (0x04) - { - 1, - 0x02, - 0x03, - 0x04 - } - }, - Package (0x02) - { - "link-frequencies", - Package (0x02) - { - 0x15752A00, - 0xABA9500 - } - }, - Package (0x02) - { - "remote-endpoint", - Package (0x03) - { - IPU0, - 0, - 0 - } - } - } - }) - } - - PowerResource (VCPR, 0x00, 0x0000) - { - Name (STA, 0) - Method (_ON, 0, Serialized) /* VCPR_ON_: VCM Power On */ - { - If (REFC == 0) - { - /* Pull PWREN high */ - STXS(GPP_H20) - } - REFC++ - STA = 1 - } - Method (_OFF, 0, Serialized) /* VCPR_OFF: VCM Power Off */ - { - If (REFC == 1) - { - /* Pull PWREN low */ - CTXS(GPP_H20) - } - REFC-- - STA = 0 - } - Method (_STA, 0, NotSerialized) - { - Return (STA) - } - } - - Device (VCM0) - { - Name (_HID, "PRP0001") - Name (_UID, 0x00) - Name (_DDN, "DW9768 VCM") /* _DDN: DOS Device Name */ - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - Name (_CRS, ResourceTemplate () /* _CRS: Current Resource Settings */ - { - I2cSerialBus (0x000C, ControllerInitiated, 0x00061A80, - AddressingMode7Bit, "\\_SB.PCI0.I2C3", - 0x00, ResourceConsumer, , - ) - }) - Name (_DEP, Package (0x01) /* _DEP: Dependencies */ - { - CAM0 - }) - Name (_PR0, Package (0x01) /* _PR0: Power Resources for D0 */ - { - VCPR - }) - Name (_PR3, Package (0x01) /* _PR3: Power Resources for D3hot */ - { - VCPR - }) - Name (_DSD, Package (0x02) /* _DSD: Device-Specific Data */ - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x02) - { - Package (0x02) - { - "compatible", - "dongwoon,dw9768" - }, - Package (0x02) - { - "i2c-allow-low-power-probe", - 0x01 - } - } - }) - } - Device (NVM0) - { - Name (_HID, "PRP0001") - Name (_UID, 0x01) - Name (_DDN, "AT24 EEPROM") // _DDN: DOS Device Name - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings - { - I2cSerialBusV2 (0x0058, ControllerInitiated, 0x00061A80, - AddressingMode7Bit, "\\_SB.PCI0.I2C3", - 0x00, ResourceConsumer, , Exclusive, - ) - }) - Name (_DEP, Package (0x01) // _DEP: Dependencies - { - CAM0 - }) - Name (_PR0, Package (0x01) // _PR0: Power Resources for D0 - { - RCPR - }) - Name (_PR3, Package (0x01) // _PR3: Power Resources for D3hot - { - RCPR - }) - Name (_DSD, Package (0x02) // _DSD: Device-Specific Data - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */, - Package (0x06) - { - Package (0x02) - { - "size", - 0x2800 - }, - Package (0x02) - { - "pagesize", - 1 - }, - Package (0x02) - { - "read-only", - 1 - }, - Package (0x02) - { - "address-width", - 0x10 - }, - Package (0x02) - { - "compatible", - "atmel,24c1024" - }, - Package (0x02) - { - "i2c-allow-low-power-probe", - 0x01 - } - } - }) - } -} - -Scope (\_SB.PCI0.I2C2) -{ - Name (STA, 0) - PowerResource (FCPR, 0x00, 0x0000) - { - Method (_ON, 0, Serialized) /* Front camera_ON_: Power On */ - { - If (STA == 0) - { - /* Enable IMG_CLK */ - MCON(2,1) /* Clock 2, 19.2MHz */ - - /* Pull RST low */ - CTXS(GPP_D4) - - /* Pull SNRPWR_EN high */ - STXS(GPP_D18) - - /* Pull PWREN high */ - STXS(GPP_D17) - Sleep(10) /* t9 */ - - /* Pull RST high */ - STXS(GPP_D4) - Sleep(1) /* t2 */ - - STA = 1 - } - } - Method (_OFF, 0, Serialized) /* Front camera_OFF_: Power Off */ - { - If (STA == 1) - { - /* Disable IMG_CLK */ - Sleep(1) /* t0+t1 */ - MCOF(2) /* Clock 2 */ - - /* Pull RST low */ - CTXS(GPP_D4) - - /* Pull PWREN low */ - CTXS(GPP_D17) - - /* Pull SNRPWR_EN low */ - CTXS(GPP_D18) - - STA = 0 - } - } - Method (_STA, 0, NotSerialized) - { - Return (STA) - } - } - - Device (CAM1) - { - Name (_HID, "INT3474") - Name (_UID, 0) - Name (_DDN, "Ov 2740 Camera") /* _DDN: DOS Device Name */ - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - Name (_CRS, ResourceTemplate () /* _CRS: Current Resource Settings */ - { - I2cSerialBus (0x0010, ControllerInitiated, 0x00061A80, - AddressingMode7Bit, "\\_SB.PCI0.I2C2", - 0x00, ResourceConsumer, , - ) - }) - Name (_PR0, Package (0x01) /* _PR0: Power Resources for D0 */ - { - FCPR - }) - Name (_PR3, Package (0x01) /* _PR3: Power Resources for D3hot */ - { - FCPR - }) - Name (_DSD, Package (0x04) /* _DSD: Device-Specific Data */ - { - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "port0", - "PRT0" - } - }, - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x02) - { - Package (0x02) - { - "clock-frequency", - 0x0124F800 - }, - Package (0x02) - { - "i2c-allow-low-power-probe", - 0x01 - } - } - }) - Name (PRT0, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 0 - } - }, - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP00" - } - } - }) - Name (EP00, Package (0x02) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x05) - { - Package (0x02) - { - "endpoint", - 0 - }, - Package (0x02) - { - "clock-lanes", - 0 - }, - Package (0x02) - { - "data-lanes", - Package (0x02) - { - 1, - 0x02 - } - }, - Package (0x02) - { - "link-frequencies", - Package (0x01) - { - 0x15752A00 - } - }, - Package (0x02) - { - "remote-endpoint", - Package (0x03) - { - IPU0, - 1, - 0 - } - } - } - }) - } -} diff --git a/src/mainboard/google/volteer/variants/chronicler/overridetree.cb b/src/mainboard/google/volteer/variants/chronicler/overridetree.cb index 180acca7b3c..483fd3df219 100644 --- a/src/mainboard/google/volteer/variants/chronicler/overridetree.cb +++ b/src/mainboard/google/volteer/variants/chronicler/overridetree.cb @@ -272,6 +272,7 @@ chip soc/intel/tigerlake register "PcieRpHotPlug[4]" = "1" register "PcieClkSrcUsage[5]" = "4" register "PcieClkSrcClkReq[5]" = "5" + register "PcieRpSlotImplemented[4]" = "false" end device ref pmc hidden # The pmc_mux chip driver is a placeholder for the diff --git a/src/mainboard/google/volteer/variants/elemi/overridetree.cb b/src/mainboard/google/volteer/variants/elemi/overridetree.cb index 8f220b8fcd4..c63dd738f2b 100644 --- a/src/mainboard/google/volteer/variants/elemi/overridetree.cb +++ b/src/mainboard/google/volteer/variants/elemi/overridetree.cb @@ -273,6 +273,7 @@ chip soc/intel/tigerlake register "PcieRpHotPlug[4]" = "1" register "PcieClkSrcUsage[5]" = "4" register "PcieClkSrcClkReq[5]" = "5" + register "PcieRpSlotImplemented[4]" = "false" end device ref pmc hidden # The pmc_mux chip driver is a placeholder for the diff --git a/src/mainboard/google/volteer/variants/elemi/ramstage.c b/src/mainboard/google/volteer/variants/elemi/ramstage.c index 16261b7d45d..adff524d06e 100644 --- a/src/mainboard/google/volteer/variants/elemi/ramstage.c +++ b/src/mainboard/google/volteer/variants/elemi/ramstage.c @@ -10,11 +10,26 @@ void variant_ramstage_init(void) uint32_t sku_id = google_chromeec_get_board_sku(); switch (sku_id) { - case 102: - case 104: - case 107: - case 109: - case 115: + case 0xB0012: + case 0xB0014: + case 0xB0015: + case 0xB0016: + case 0xB0021: + case 0xB0023: + case 0xB0027: + case 0xB0032: + case 0xB0036: + case 0xB0037: + case 0xB0038: + case 0xB0040: + case 0xB0041: + case 0xB0042: + case 0xB0043: + case 0xB0047: + case 0xB0048: + /* SKU does not have FP Sensor, do not enable FPMCU */ + break; + default: /* * Assert FPMCU reset and enable power to FPMCU, * wait for power rail to stabilize, @@ -26,8 +41,5 @@ void variant_ramstage_init(void) mdelay(1); gpio_output(GPP_C23, 1); break; - default: - /* SKU does not have FP Sensor, do not enable FPMCU */ - break; } } diff --git a/src/mainboard/google/volteer/variants/voema/include/variant/acpi/mipi_camera.asl b/src/mainboard/google/volteer/variants/voema/include/variant/acpi/mipi_camera.asl deleted file mode 100644 index e35c3bba8a3..00000000000 --- a/src/mainboard/google/volteer/variants/voema/include/variant/acpi/mipi_camera.asl +++ /dev/null @@ -1,340 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -Scope (\_SB.PCI0.IPU0) -{ - Name (_DSD, Package (0x02) /* _DSD: Device-Specific Data */ - { - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x02) - { - Package (0x02) - { - "port0", - "PRT0" - }, - Package (0x02) - { - "port1", - "PRT1" - } - } - }) - - Name (PRT0, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 5 - } - }, - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP00" - } - } - }) - - Name (PRT1, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 1 - } - }, - - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP10" - } - } - }) -} - -Scope (\_SB.PCI0.IPU0) -{ - Name (EP10, Package (0x02) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x04) - { - Package (0x02) - { - "endpoint", - 0 - }, - Package (0x02) - { - "clock-lanes", - 0 - }, - Package (0x02) - { - "data-lanes", - Package (0x02) - { - 1, - 0x02 - } - }, - Package (0x02) - { - "remote-endpoint", - Package (0x03) - { - ^I2C2.CAM1, - 0, - 0 - } - } - } - }) -} - -Scope (\_SB.PCI0.I2C2) -{ - Name (STA, 0) - PowerResource (FCPR, 0x00, 0x0000) - { - Method (_ON, 0, Serialized) /* Front camera_ON_: Power On */ - { - If (STA == 0) - { - /* Enable IMG_CLK */ - MCON(2,1) /* Clock 2, 19.2MHz */ - - /* Pull RST low */ - CTXS(GPP_D4) - - /* Pull PWREN high */ - STXS(GPP_D17) - Sleep(10) /* t9 */ - - /* Pull RST high */ - STXS(GPP_D4) - Sleep(1) /* t2 */ - - STA = 1 - } - } - Method (_OFF, 0, Serialized) /* Front camera_OFF_: Power Off */ - { - If (STA == 1) - { - /* Disable IMG_CLK */ - Sleep(1) /* t0+t1 */ - MCOF(2) /* Clock 2 */ - - /* Pull RST low */ - CTXS(GPP_D4) - - /* Pull PWREN low */ - CTXS(GPP_D17) - - STA = 0 - } - } - Method (_STA, 0, NotSerialized) - { - Return (STA) - } - } - - Device (CAM1) - { - Name (_HID, "INT3474") - Name (_UID, 0) - Name (_DDN, "Ov 2740 Camera") /* _DDN: DOS Device Name */ - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - Name (_CRS, ResourceTemplate () /* _CRS: Current Resource Settings */ - { - I2cSerialBus (0x0036, ControllerInitiated, 0x00061A80, - AddressingMode7Bit, "\\_SB.PCI0.I2C2", - 0x00, ResourceConsumer, , - ) - }) - Name (_PR0, Package (0x01) /* _PR0: Power Resources for D0 */ - { - FCPR - }) - Name (_PR3, Package (0x01) /* _PR3: Power Resources for D3hot */ - { - FCPR - }) - Name (_DSD, Package (0x04) /* _DSD: Device-Specific Data */ - { - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "port0", - "PRT0" - } - }, - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x02) - { - Package (0x02) - { - "clock-frequency", - 0x0124F800 - }, - Package (0x02) - { - "i2c-allow-low-power-probe", - 0x01 - } - } - }) - Name (PRT0, Package (0x04) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x01) - { - Package (0x02) - { - "port", - 0 - } - }, - ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), - Package (0x01) - { - Package (0x02) - { - "endpoint0", - "EP00" - } - } - }) - Name (EP00, Package (0x02) - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), - Package (0x05) - { - Package (0x02) - { - "endpoint", - 0 - }, - Package (0x02) - { - "clock-lanes", - 0 - }, - Package (0x02) - { - "data-lanes", - Package (0x02) - { - 1, - 0x02 - } - }, - Package (0x02) - { - "link-frequencies", - Package (0x01) - { - 0x15752A00 - } - }, - Package (0x02) - { - "remote-endpoint", - Package (0x03) - { - IPU0, - 1, - 0 - } - } - } - }) - } - Device (NVM0) - { - Name (_HID, "PRP0001") - Name (_UID, 0x01) - Name (_DDN, "AT24 EEPROM") // _DDN: DOS Device Name - Method (_STA, 0, NotSerialized) - { - Return (0x0F) - } - Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings - { - I2cSerialBusV2 (0x0050, ControllerInitiated, 0x00061A80, - AddressingMode7Bit, "\\_SB.PCI0.I2C2", - 0x00, ResourceConsumer, , Exclusive, - ) - }) - Name (_DEP, Package (0x01) // _DEP: Dependencies - { - CAM1 - }) - Name (_PR0, Package (0x01) // _PR0: Power Resources for D0 - { - FCPR - }) - Name (_PR3, Package (0x01) // _PR3: Power Resources for D3hot - { - FCPR - }) - Name (_DSD, Package (0x02) // _DSD: Device-Specific Data - { - ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */, - Package (0x06) - { - Package (0x02) - { - "size", - 0x2000 - }, - Package (0x02) - { - "pagesize", - 1 - }, - Package (0x02) - { - "read-only", - 1 - }, - Package (0x02) - { - "address-width", - 0x10 - }, - Package (0x02) - { - "compatible", - "atmel,24c64" - }, - Package (0x02) - { - "i2c-allow-low-power-probe", - 0x01 - } - } - }) - } -} diff --git a/src/mainboard/google/volteer/variants/voema/overridetree.cb b/src/mainboard/google/volteer/variants/voema/overridetree.cb index e4b26168077..6dce086fdc5 100644 --- a/src/mainboard/google/volteer/variants/voema/overridetree.cb +++ b/src/mainboard/google/volteer/variants/voema/overridetree.cb @@ -9,7 +9,33 @@ chip soc/intel/tigerlake register "typec_aux_bias_pads[0]" = "{.pad_auxp_dc = GPP_E10, .pad_auxn_dc = GPP_E13}" device domain 0 on - device ref ipu on end # IPU + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "2" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + register "device[0].type" = "panel" + # IPUA for IPU camera + register "device[1].name" = ""IPUA"" + register "device[1].non_vga_device" = "true" + register "device[1].addr" = "0x3480" + device generic 0 on end + end + end + + device ref ipu on + chip drivers/intel/mipi_camera + register "acpi_uid" = "0x50000" + register "acpi_name" = ""IPU0"" + register "device_type" = "INTEL_ACPI_CAMERA_CIO2" + + register "cio2_num_ports" = "1" + register "cio2_lanes_used" = "{2}" # 2 CSI Camera lanes are used + register "cio2_lane_endpoint[0]" = ""^I2C2.CAM1"" + register "cio2_prt[0]" = "1" + device generic 0 on end + end + end device ref i2c0 on chip drivers/i2c/generic register "hid" = ""10EC5682"" @@ -62,6 +88,67 @@ chip soc/intel/tigerlake device i2c 10 on end end end + device ref i2c2 on + chip drivers/intel/mipi_camera + register "acpi_hid" = ""INT3474"" + register "acpi_uid" = "0" + register "acpi_name" = ""CAM1"" + register "chip_name" = ""Ov 2740 Camera"" + register "sensor_name" = ""CJFLE23"" + register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" + register "has_power_resource" = "true" + + register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "1" + register "ssdb.platform" = "PLAT_TGL" + register "ssdb.rom_type" = "ROM_EEPROM_CAT24C64" + register "rom_address" = "0x50" + register "num_freq_entries" = "1" + register "link_freq[0]" = "360 * MHz" + register "remote_name" = ""IPU0"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" + + #Controls + register "clk_panel.clks[0].clknum" = "2" + register "clk_panel.clks[0].freq" = "FREQ_19_2_MHZ" + + register "gpio_panel.gpio[0].gpio_num" = "GPP_D4" #reset + register "gpio_panel.gpio[1].gpio_num" = "GPP_D17" #power enable + + #_ON + register "on_seq.ops_cnt" = "4" + register "on_seq.ops[0]" = "SEQ_OPS_CLK_ENABLE(0, 0)" + register "on_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "on_seq.ops[2]" = "SEQ_OPS_GPIO_ENABLE(1, 10)" # PWREN high, sleep 10ms + register "on_seq.ops[3]" = "SEQ_OPS_GPIO_ENABLE(0, 1)" # RST high, sleep 1ms + + #_OFF + register "off_seq.ops_cnt" = "3" + register "off_seq.ops[0]" = "SEQ_OPS_CLK_DISABLE(0, 1)" # Disable clock, delay 1ms + register "off_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "off_seq.ops[2]" = "SEQ_OPS_GPIO_DISABLE(1, 0)" # PWREN low + + device i2c 36 on end + end + chip drivers/intel/mipi_camera + register "acpi_hid" = "ACPI_DT_NAMESPACE_HID" + register "acpi_uid" = "1" + register "acpi_name" = ""NVM0"" + register "chip_name" = ""AT24 EEPROM"" + register "device_type" = "INTEL_ACPI_CAMERA_NVM" + register "pr0" = ""\\_SB.PCI0.I2C2.CAM1.PRIC"" + + register "nvm_size" = "0x2000" + register "nvm_pagesize" = "1" + register "nvm_readonly" = "1" + register "nvm_width" = "0x10" + register "nvm_compat" = ""atmel,24c64"" + + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D0" + + device i2c 50 on end + end + end device ref i2c5 on chip drivers/i2c/generic register "hid" = ""ELAN0000"" diff --git a/src/mainboard/google/volteer/variants/volteer/include/variant/acpi/mipi_camera.asl b/src/mainboard/google/volteer/variants/volteer/include/variant/acpi/mipi_camera.asl deleted file mode 100644 index 418f2e04ba5..00000000000 --- a/src/mainboard/google/volteer/variants/volteer/include/variant/acpi/mipi_camera.asl +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include diff --git a/src/mainboard/google/volteer/variants/volteer/overridetree.cb b/src/mainboard/google/volteer/variants/volteer/overridetree.cb index c489c2dc91c..9ffe08aa484 100644 --- a/src/mainboard/google/volteer/variants/volteer/overridetree.cb +++ b/src/mainboard/google/volteer/variants/volteer/overridetree.cb @@ -63,7 +63,35 @@ chip soc/intel/tigerlake probe DB_USB USB4_GEN3 end - device ref ipu on end + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "2" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + register "device[0].type" = "panel" + # IPUA for IPU cameras + register "device[1].name" = ""IPUA"" + register "device[1].non_vga_device" = "true" + register "device[1].addr" = "0x3480" + device generic 0 on end + end + end + + device ref ipu on + chip drivers/intel/mipi_camera + register "acpi_uid" = "0x50000" + register "acpi_name" = ""IPU0"" + register "device_type" = "INTEL_ACPI_CAMERA_CIO2" + + register "cio2_num_ports" = "2" + register "cio2_lanes_used" = "{4,2}" # 4 and 2 CSI Camera lanes are used + register "cio2_lane_endpoint[0]" = ""^I2C3.CAM0"" + register "cio2_lane_endpoint[1]" = ""^I2C2.CAM1"" + register "cio2_prt[0]" = "5" + register "cio2_prt[1]" = "1" + device generic 0 on end + end + end device ref i2c0 on chip drivers/i2c/generic register "hid" = ""10EC5682"" @@ -166,6 +194,131 @@ chip soc/intel/tigerlake register "proxraw_strength" = "0" device i2c 28 on end end + chip drivers/intel/mipi_camera + register "acpi_hid" = ""INT3474"" + register "acpi_uid" = "0" + register "acpi_name" = ""CAM1"" + register "chip_name" = ""Ov 2740 Camera"" + register "sensor_name" = ""CJFLE23"" + register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" + register "has_power_resource" = "true" + register "low_power_probe" = "1" + + register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "1" + register "ssdb.platform" = "PLAT_TGL" + register "num_freq_entries" = "1" + register "link_freq[0]" = "360 * MHz" + register "remote_name" = ""IPU0"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" + + #Controls + register "clk_panel.clks[0].clknum" = "2" + register "clk_panel.clks[0].freq" = "FREQ_19_2_MHZ" + + register "gpio_panel.gpio[0].gpio_num" = "GPP_D4" #reset + register "gpio_panel.gpio[1].gpio_num" = "GPP_D17" #power enable + register "gpio_panel.gpio[2].gpio_num" = "GPP_D18" #SNRPWR_EN + + #_ON + register "on_seq.ops_cnt" = "5" + register "on_seq.ops[0]" = "SEQ_OPS_CLK_ENABLE(0, 0)" + register "on_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "on_seq.ops[2]" = "SEQ_OPS_GPIO_ENABLE(2, 0)" # SNRPWR_EN high + register "on_seq.ops[3]" = "SEQ_OPS_GPIO_ENABLE(1, 10)" # PWREN high, sleep 10ms + register "on_seq.ops[4]" = "SEQ_OPS_GPIO_ENABLE(0, 1)" # RST high, sleep 1ms + + #_OFF + register "off_seq.ops_cnt" = "4" + register "off_seq.ops[0]" = "SEQ_OPS_CLK_DISABLE(0, 1)" # Disable clock, delay 1ms + register "off_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "off_seq.ops[2]" = "SEQ_OPS_GPIO_DISABLE(1, 0)" # PWREN low + register "off_seq.ops[3]" = "SEQ_OPS_GPIO_DISABLE(2, 0)" # SNRPWR_EN low + + device i2c 10 on end + end + end + device ref i2c3 on + chip drivers/intel/mipi_camera + register "acpi_hid" = ""OVTI8856"" + register "acpi_uid" = "0" + register "acpi_name" = ""CAM0"" + register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" + register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" + register "has_power_resource" = "true" + register "low_power_probe" = "1" + + register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "0" + register "ssdb.platform" = "PLAT_TGL" + register "ssdb.vcm_type" = "VCM_DW9808" + register "vcm_address" = "0x0C" + register "vcm_name" = ""VCM0"" + # placeholder; ROM type 24C1024 currently unsupported + # register "ssdb.rom_type" = "ROM_EEPROM_24C1024" + # register "rom_address" = "0x50" + register "num_freq_entries" = "2" + register "link_freq[0]" = "360 * MHz" # 360 MHz + register "link_freq[1]" = "180 * MHz" # 180 MHz + register "remote_name" = ""IPU0"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" + + #Controls + register "clk_panel.clks[0].clknum" = "3" + register "clk_panel.clks[0].freq" = "FREQ_19_2_MHZ" + + register "gpio_panel.gpio[0].gpio_num" = "GPP_F15" #reset + register "gpio_panel.gpio[1].gpio_num" = "GPP_H20" #power enable + register "gpio_panel.gpio[2].gpio_num" = "GPP_H14" #SNRPWR_EN + + #_ON + register "on_seq.ops_cnt" = "5" + register "on_seq.ops[0]" = "SEQ_OPS_CLK_ENABLE(0, 0)" + register "on_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "on_seq.ops[2]" = "SEQ_OPS_GPIO_ENABLE(2, 0)" # SNRPWR_EN high + register "on_seq.ops[3]" = "SEQ_OPS_GPIO_ENABLE(1, 2)" # PWREN high, sleep 2ms + register "on_seq.ops[4]" = "SEQ_OPS_GPIO_ENABLE(0, 1)" # RST high, sleep 1ms + + #_OFF + register "off_seq.ops_cnt" = "4" + register "off_seq.ops[0]" = "SEQ_OPS_CLK_DISABLE(0, 1)" # Disable clock, delay 1ms + register "off_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "off_seq.ops[2]" = "SEQ_OPS_GPIO_DISABLE(1, 0)" # PWREN low + register "off_seq.ops[3]" = "SEQ_OPS_GPIO_DISABLE(2, 0)" # SNRPWR_EN low + + device i2c 10 on end + end + chip drivers/intel/mipi_camera + register "acpi_uid" = "2" + register "acpi_name" = ""VCM0"" + register "chip_name" = ""DW9768 VCM"" + register "device_type" = "INTEL_ACPI_CAMERA_VCM" + + register "pr0" = ""\\_SB.PCI0.I2C3.CAM0.PRIC"" + register "vcm_compat" = ""dongwoon,dw9768"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D0" + + device i2c 0C on end + end + chip drivers/intel/mipi_camera + register "acpi_hid" = "ACPI_DT_NAMESPACE_HID" + register "acpi_uid" = "1" + register "acpi_name" = ""NVM0"" + register "chip_name" = ""AT24 EEPROM"" + register "device_type" = "INTEL_ACPI_CAMERA_NVM" + register "pr0" = ""\\_SB.PCI0.I2C3.CAM0.PRIC"" + + register "nvm_size" = "0x2800" + register "nvm_pagesize" = "1" + register "nvm_readonly" = "1" + register "nvm_width" = "0x10" + register "nvm_compat" = ""atmel,24c1024"" + + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D0" + + device i2c 58 on end + end end device ref i2c5 on chip drivers/i2c/generic diff --git a/src/mainboard/google/volteer/variants/volteer2/include/variant/acpi/mipi_camera.asl b/src/mainboard/google/volteer/variants/volteer2/include/variant/acpi/mipi_camera.asl deleted file mode 100644 index 418f2e04ba5..00000000000 --- a/src/mainboard/google/volteer/variants/volteer2/include/variant/acpi/mipi_camera.asl +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include diff --git a/src/mainboard/google/volteer/variants/volteer2/overridetree.cb b/src/mainboard/google/volteer/variants/volteer2/overridetree.cb index ee181c86e08..782ebcb4c11 100644 --- a/src/mainboard/google/volteer/variants/volteer2/overridetree.cb +++ b/src/mainboard/google/volteer/variants/volteer2/overridetree.cb @@ -117,7 +117,35 @@ chip soc/intel/tigerlake probe DB_USB USB4_GEN3 end - device ref ipu on end # IPU 0x9A19 + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "2" + # DDIA for eDP + register "device[0].name" = ""LCD0"" + register "device[0].type" = "panel" + # IPUA for IPU cameras + register "device[1].name" = ""IPUA"" + register "device[1].non_vga_device" = "true" + register "device[1].addr" = "0x3480" + device generic 0 on end + end + end + + device ref ipu on + chip drivers/intel/mipi_camera + register "acpi_uid" = "0x50000" + register "acpi_name" = ""IPU0"" + register "device_type" = "INTEL_ACPI_CAMERA_CIO2" + + register "cio2_num_ports" = "2" + register "cio2_lanes_used" = "{4,2}" # 4 and 2 CSI Camera lanes are used + register "cio2_lane_endpoint[0]" = ""^I2C3.CAM0"" + register "cio2_lane_endpoint[1]" = ""^I2C2.CAM1"" + register "cio2_prt[0]" = "5" + register "cio2_prt[1]" = "1" + device generic 0 on end + end + end device ref i2c0 on chip drivers/i2c/generic register "hid" = ""10EC5682"" @@ -225,6 +253,131 @@ chip soc/intel/tigerlake register "proxraw_strength" = "0" device i2c 28 on end end + chip drivers/intel/mipi_camera + register "acpi_hid" = ""INT3474"" + register "acpi_uid" = "0" + register "acpi_name" = ""CAM1"" + register "chip_name" = ""Ov 2740 Camera"" + register "sensor_name" = ""CJFLE23"" + register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" + register "has_power_resource" = "true" + register "low_power_probe" = "1" + + register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "1" + register "ssdb.platform" = "PLAT_TGL" + register "num_freq_entries" = "1" + register "link_freq[0]" = "360 * MHz" + register "remote_name" = ""IPU0"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" + + #Controls + register "clk_panel.clks[0].clknum" = "2" + register "clk_panel.clks[0].freq" = "FREQ_19_2_MHZ" + + register "gpio_panel.gpio[0].gpio_num" = "GPP_D4" #reset + register "gpio_panel.gpio[1].gpio_num" = "GPP_D17" #power enable + register "gpio_panel.gpio[2].gpio_num" = "GPP_D18" #SNRPWR_EN + + #_ON + register "on_seq.ops_cnt" = "5" + register "on_seq.ops[0]" = "SEQ_OPS_CLK_ENABLE(0, 0)" + register "on_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "on_seq.ops[2]" = "SEQ_OPS_GPIO_ENABLE(2, 0)" # SNRPWR_EN high + register "on_seq.ops[3]" = "SEQ_OPS_GPIO_ENABLE(1, 10)" # PWREN high, sleep 10ms + register "on_seq.ops[4]" = "SEQ_OPS_GPIO_ENABLE(0, 1)" # RST high, sleep 1ms + + #_OFF + register "off_seq.ops_cnt" = "4" + register "off_seq.ops[0]" = "SEQ_OPS_CLK_DISABLE(0, 1)" # Disable clock, delay 1ms + register "off_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "off_seq.ops[2]" = "SEQ_OPS_GPIO_DISABLE(1, 0)" # PWREN low + register "off_seq.ops[3]" = "SEQ_OPS_GPIO_DISABLE(2, 0)" # SNRPWR_EN low + + device i2c 10 on end + end + end + device ref i2c3 on + chip drivers/intel/mipi_camera + register "acpi_hid" = ""OVTI8856"" + register "acpi_uid" = "0" + register "acpi_name" = ""CAM0"" + register "chip_name" = ""Ov 8856 Camera"" + register "sensor_name" = ""CJAJ813"" + register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" + register "has_power_resource" = "true" + register "low_power_probe" = "1" + + register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "0" + register "ssdb.platform" = "PLAT_TGL" + register "ssdb.vcm_type" = "VCM_DW9808" + register "vcm_address" = "0x0C" + register "vcm_name" = ""VCM0"" + # placeholder; ROM type 24C1024 currently unsupported + # register "ssdb.rom_type" = "ROM_EEPROM_24C1024" + # register "rom_address" = "0x50" + register "num_freq_entries" = "2" + register "link_freq[0]" = "360 * MHz" # 360 MHz + register "link_freq[1]" = "180 * MHz" # 180 MHz + register "remote_name" = ""IPU0"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D3_COLD" + + #Controls + register "clk_panel.clks[0].clknum" = "3" + register "clk_panel.clks[0].freq" = "FREQ_19_2_MHZ" + + register "gpio_panel.gpio[0].gpio_num" = "GPP_F15" #reset + register "gpio_panel.gpio[1].gpio_num" = "GPP_H20" #power enable + register "gpio_panel.gpio[2].gpio_num" = "GPP_H14" #SNRPWR_EN + + #_ON + register "on_seq.ops_cnt" = "5" + register "on_seq.ops[0]" = "SEQ_OPS_CLK_ENABLE(0, 0)" + register "on_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "on_seq.ops[2]" = "SEQ_OPS_GPIO_ENABLE(2, 0)" # SNRPWR_EN high + register "on_seq.ops[3]" = "SEQ_OPS_GPIO_ENABLE(1, 2)" # PWREN high, sleep 2ms + register "on_seq.ops[4]" = "SEQ_OPS_GPIO_ENABLE(0, 1)" # RST high, sleep 1ms + + #_OFF + register "off_seq.ops_cnt" = "4" + register "off_seq.ops[0]" = "SEQ_OPS_CLK_DISABLE(0, 1)" # Disable clock, delay 1ms + register "off_seq.ops[1]" = "SEQ_OPS_GPIO_DISABLE(0, 0)" # RST low + register "off_seq.ops[2]" = "SEQ_OPS_GPIO_DISABLE(1, 0)" # PWREN low + register "off_seq.ops[3]" = "SEQ_OPS_GPIO_DISABLE(2, 0)" # SNRPWR_EN low + + device i2c 10 on end + end + chip drivers/intel/mipi_camera + register "acpi_uid" = "2" + register "acpi_name" = ""VCM0"" + register "chip_name" = ""DW9768 VCM"" + register "device_type" = "INTEL_ACPI_CAMERA_VCM" + + register "pr0" = ""\\_SB.PCI0.I2C3.CAM0.PRIC"" + register "vcm_compat" = ""dongwoon,dw9768"" + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D0" + + device i2c 0C on end + end + chip drivers/intel/mipi_camera + register "acpi_hid" = "ACPI_DT_NAMESPACE_HID" + register "acpi_uid" = "1" + register "acpi_name" = ""NVM0"" + register "chip_name" = ""AT24 EEPROM"" + register "device_type" = "INTEL_ACPI_CAMERA_NVM" + register "pr0" = ""\\_SB.PCI0.I2C3.CAM0.PRIC"" + + register "nvm_size" = "0x2800" + register "nvm_pagesize" = "1" + register "nvm_readonly" = "1" + register "nvm_width" = "0x10" + register "nvm_compat" = ""atmel,24c1024"" + + register "max_dstate_for_probe" = "ACPI_DEVICE_SLEEP_D0" + + device i2c 58 on end + end end device ref i2c5 on chip drivers/i2c/generic diff --git a/src/mainboard/google/zork/Kconfig.name b/src/mainboard/google/zork/Kconfig.name index 43e1232792b..035fd7380c5 100644 --- a/src/mainboard/google/zork/Kconfig.name +++ b/src/mainboard/google/zork/Kconfig.name @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -comment "Zork" +comment "Zork (AMD Ryzen Mobile 3000 (Picasso))" config BOARD_GOOGLE_BERKNIP bool "-> Berknip (HP Pro c645 Chromebook Enterprise)" diff --git a/src/mainboard/google/zork/cfr.c b/src/mainboard/google/zork/cfr.c index 5565d31cd85..dbf38c0dc7c 100644 --- a/src/mainboard/google/zork/cfr.c +++ b/src/mainboard/google/zork/cfr.c @@ -7,7 +7,7 @@ static struct sm_obj_form ec = { .ui_name = "ChromeEC Embedded Controller", .obj_list = (const struct sm_object *[]) { - &auto_fan_control + &auto_fan_control, &ec_kb_backlight, NULL }, diff --git a/src/mainboard/hp/elitebook_820_g2/devicetree.cb b/src/mainboard/hp/elitebook_820_g2/devicetree.cb index d6cb2ed0161..1641472522a 100644 --- a/src/mainboard/hp/elitebook_820_g2/devicetree.cb +++ b/src/mainboard/hp/elitebook_820_g2/devicetree.cb @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-or-later -chip soc/intel/broadwell +chip northbridge/intel/broadwell chip cpu/intel/haswell - device cpu_cluster 0 on ops broadwell_cpu_bus_ops end + device cpu_cluster 0 on ops haswell_cpu_bus_ops end end device domain 0 on ops broadwell_pci_domain_ops @@ -24,7 +24,7 @@ chip soc/intel/broadwell end device pci 03.0 on end # Mini-HD audio - chip soc/intel/broadwell/pch # Wildcat Point PCH + chip southbridge/intel/wildcatpoint # Wildcat Point PCH device pci 13.0 off end # Smart Sound Audio DSP device pci 14.0 on end # xHCI Controller device pci 15.0 off end # Serial I/O DMA diff --git a/src/mainboard/hp/elitebook_820_g2/dsdt.asl b/src/mainboard/hp/elitebook_820_g2/dsdt.asl index 6d7555d02ef..95012ce7086 100644 --- a/src/mainboard/hp/elitebook_820_g2/dsdt.asl +++ b/src/mainboard/hp/elitebook_820_g2/dsdt.asl @@ -17,15 +17,15 @@ DefinitionBlock( #include "acpi/platform.asl" #include - #include - #include + #include + #include #include #include Device (\_SB.PCI0) { #include - #include + #include #include } } diff --git a/src/mainboard/intel/adlrvp/devicetree.cb b/src/mainboard/intel/adlrvp/devicetree.cb index 5c12bb3b80a..5451156ad15 100644 --- a/src/mainboard/intel/adlrvp/devicetree.cb +++ b/src/mainboard/intel/adlrvp/devicetree.cb @@ -354,6 +354,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" @@ -409,6 +410,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "1" register "ssdb.platform" = "PLAT_ADL" register "num_freq_entries" = "1" register "link_freq[0]" = "450000000" diff --git a/src/mainboard/intel/adlrvp/devicetree_m.cb b/src/mainboard/intel/adlrvp/devicetree_m.cb index 7d197b0eca5..6886babeb2e 100644 --- a/src/mainboard/intel/adlrvp/devicetree_m.cb +++ b/src/mainboard/intel/adlrvp/devicetree_m.cb @@ -288,6 +288,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" @@ -343,6 +344,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "1" register "ssdb.platform" = "PLAT_ADL" register "num_freq_entries" = "1" register "link_freq[0]" = "450000000" diff --git a/src/mainboard/intel/adlrvp/devicetree_n.cb b/src/mainboard/intel/adlrvp/devicetree_n.cb index 73b6828a388..5207d553a91 100644 --- a/src/mainboard/intel/adlrvp/devicetree_n.cb +++ b/src/mainboard/intel/adlrvp/devicetree_n.cb @@ -296,6 +296,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_ADL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" @@ -351,6 +352,7 @@ chip soc/intel/alderlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "1" register "ssdb.platform" = "PLAT_ADL" register "num_freq_entries" = "1" register "link_freq[0]" = "450000000" diff --git a/src/mainboard/intel/jasperlake_rvp/variants/jslrvp/devicetree.cb b/src/mainboard/intel/jasperlake_rvp/variants/jslrvp/devicetree.cb index d1fe8401298..4b95f52b36b 100644 --- a/src/mainboard/intel/jasperlake_rvp/variants/jslrvp/devicetree.cb +++ b/src/mainboard/intel/jasperlake_rvp/variants/jslrvp/devicetree.cb @@ -195,9 +195,8 @@ chip soc/intel/jasperlake register "xhci_lfps_sampling_offtime_ms" = "9" device domain 0 on - device pci 00.0 on end # Host Bridge - device pci 02.0 on end # Integrated Graphics Device - device pci 04.0 on + device ref igpu on end + device ref dptf on chip drivers/intel/dptf register "policies.passive[0]" = "DPTF_PASSIVE(CPU, CPU, 95, 1000)" register "policies.critical[0]" = "DPTF_CRITICAL(CPU, 119, SHUTDOWN)" @@ -216,9 +215,9 @@ chip soc/intel/jasperlake .granularity = 1000,}" device generic 0 on end end - end # SA Thermal device + end - device pci 05.0 on + device ref ipu on chip drivers/intel/mipi_camera register "acpi_uid" = "0x50000" register "acpi_name" = ""IPU0"" @@ -233,97 +232,92 @@ chip soc/intel/jasperlake device generic 0 on end end end - device pci 12.0 off end # Thermal Subsystem - device pci 12.5 off end # UFS SCS - device pci 12.6 off end # GSPI #2 - device pci 14.0 on + device ref south_xhci on chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""USB3/2 Type-A Left Lower"" register "type" = "UPC_TYPE_A" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""WWAN"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""USB C Connector 1"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""USB C Connector 2"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" - device usb 2.4 on end + device ref usb2_port5 on end end chip drivers/usb/acpi register "desc" = ""USB C Connector 3"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""USB C Connector 4"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""USB3/2 Type-A Left Upper"" register "type" = "UPC_TYPE_A" - device usb 2.7 on end + device ref usb2_port8 on end end chip drivers/usb/acpi register "desc" = ""USB3/2 Type-A Left Lower"" register "type" = "UPC_TYPE_A" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""USB3/2 Type-A Left Upper"" register "type" = "UPC_TYPE_A" - device usb 3.1 on end + device ref usb3_port2 on end end chip drivers/usb/acpi register "desc" = ""WLAN"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.2 on end + device ref usb3_port3 on end end chip drivers/usb/acpi register "desc" = ""USB3 Port Unused1"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.3 on end + device ref usb3_port4 on end end chip drivers/usb/acpi register "desc" = ""USB3 Port Unused2"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.4 on end + device ref usb3_port5 on end end chip drivers/usb/acpi register "desc" = ""USB3 Port Unused3"" register "type" = "UPC_TYPE_INTERNAL" - device usb 3.5 on end + device ref usb3_port6 on end end end end - end # USB xHCI - device pci 14.1 off end # USB xDCI (OTG) - device pci 14.2 off end # PMC SRAM - device pci 14.3 on + end + device ref cnvi_wifi on chip drivers/wifi/generic register "wake" = "GPE0_PME_B0" device generic 0 on end end - end # CNVi wifi - device pci 14.5 on end # SDCard - device pci 15.0 on + end + device ref sdxc on end + device ref i2c0 on chip drivers/i2c/max98373 register "vmon_slot_no" = "4" register "imon_slot_no" = "5" @@ -357,18 +351,9 @@ chip soc/intel/jasperlake register "mic_amp_in_sel" = ""diff"" device i2c 1a on end end - end # I2C #0 Audio - device pci 15.1 off end # I2C #1 - device pci 15.2 off end # I2C #2 - device pci 15.3 off end # I2C #3 - device pci 16.0 on end # Management Engine Interface 1 - device pci 16.1 off end # Management Engine Interface 2 - device pci 16.2 off end # Management Engine IDE-R - device pci 16.3 off end # Management Engine KT Redirection - device pci 16.4 off end # Management Engine Interface 3 - device pci 16.5 off end # Management Engine Interface 4 - device pci 17.0 off end # SATA - device pci 19.0 on # I2C #4 Cam 0 + end + device ref heci1 on end + device ref i2c4 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI2740"" register "acpi_uid" = "0" @@ -378,6 +363,7 @@ chip soc/intel/jasperlake register "has_power_resource" = "true" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "0" register "ssdb.platform" = "PLAT_JSL" register "num_freq_entries" = "1" register "link_freq[0]" = "360000000" @@ -406,7 +392,7 @@ chip soc/intel/jasperlake device i2c 10 on end end end - device pci 19.1 on # I2C #5 Cam 1 and VCM + device ref i2c5 on chip drivers/intel/mipi_camera register "acpi_hid" = ""OVTI5675"" register "acpi_uid" = "0" @@ -415,7 +401,7 @@ chip soc/intel/jasperlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "2" - register "ssdb.link_used" = "1" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_JSL" register "ssdb.vcm_type" = "VCM_DW9714" register "vcm_address" = "0x0C" @@ -466,27 +452,20 @@ chip soc/intel/jasperlake end end - device pci 19.2 on end # UART #2 - device pci 1a.0 on end # eMMC - device pci 1c.1 on end # PCI Express Port 2 - M.2 E-key WLAN - device pci 1c.4 on end # PCI Express Port 5 - NVMe - device pci 1e.0 on end # UART #0 - device pci 1e.1 off end # UART #1 - device pci 1e.2 off end # GSPI #0 - device pci 1e.3 on + device ref uart2 on end + device ref emmc on end + device ref pcie_rp2 on end + device ref pcie_rp5 on end + device ref uart0 on end + device ref gspi1 on chip drivers/spi/acpi register "hid" = "ACPI_DT_NAMESPACE_HID" register "compat_string" = ""google,cr50"" register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_H13_IRQ)" device spi 0 on end end - end # GSPI #1 - device pci 1f.0 on end # eSPI Interface - device pci 1f.1 on end # P2SB - device pci 1f.2 hidden end # Power Management Controller - device pci 1f.3 on end # Intel HDA - device pci 1f.4 on end # SMBus - device pci 1f.5 on end # PCH SPI - device pci 1f.6 off end # GbE + end + device ref hda on end + device ref smbus on end end end diff --git a/src/mainboard/intel/mtlrvp/variants/baseboard/mtlrvp_p/devicetree.cb b/src/mainboard/intel/mtlrvp/variants/baseboard/mtlrvp_p/devicetree.cb index a01364dde1c..995e765fffe 100644 --- a/src/mainboard/intel/mtlrvp/variants/baseboard/mtlrvp_p/devicetree.cb +++ b/src/mainboard/intel/mtlrvp/variants/baseboard/mtlrvp_p/devicetree.cb @@ -441,6 +441,7 @@ chip soc/intel/meteorlake register "device_type" = "INTEL_ACPI_CAMERA_SENSOR" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "4" register "ssdb.platform" = "PLAT_MTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560000000" @@ -484,6 +485,7 @@ chip soc/intel/meteorlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "0" register "ssdb.platform" = "PLAT_MTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560000000" diff --git a/src/mainboard/intel/pantherlake_crb/Kconfig b/src/mainboard/intel/pantherlake_crb/Kconfig new file mode 100644 index 00000000000..bd1506ad361 --- /dev/null +++ b/src/mainboard/intel/pantherlake_crb/Kconfig @@ -0,0 +1,58 @@ +## SPDX-License-Identifier: GPL-2.0-only + +if BOARD_INTEL_PANTHERLAKE_CRB + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select BOARD_ROMSIZE_KB_32768 + select CPU_INTEL_SOCKET_OTHER + select CRB_TPM + select DRIVERS_INTEL_DPTF + select DRIVERS_INTEL_MIPI_CAMERA + select DRIVERS_INTEL_MIPI_SUPPORTS_PRE_PRODUCTION_SOC if SOC_INTEL_PANTHERLAKE_PRE_PRODUCTION_SILICON + select DRIVERS_INTEL_PMC + select DRIVERS_INTEL_USB4_RETIMER + select DRIVERS_INTEL_SOUNDWIRE + select DRIVERS_SOUNDWIRE_ALC_BASE_7XX + select DRIVERS_GFX_GENERIC + select DRIVERS_I2C_GENERIC + select DRIVERS_USB_ACPI + select DRIVERS_SPI_ACPI + select DUMP_SMBIOS_TYPE17 + select GENERATE_SMBIOS_TABLES + select HAVE_ACPI_RESUME + select HAVE_ACPI_TABLES + select HAVE_INTEL_PTT + select INTEL_GMA_HAVE_VBT + select DRIVERS_UART_8250IO + select MAINBOARD_USES_IFD_GBE_REGION + select MAINBOARD_USES_IFD_EC_REGION + select PMC_IPC_ACPI_INTERFACE + select SOC_INTEL_COMMON_BLOCK_HDA_VERB + select AZALIA_USE_LEGACY_VERB_TABLE + select SOC_INTEL_COMMON_BLOCK_MEMINIT + select SOC_INTEL_IOE_DIE_SUPPORT + select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES + select SOC_INTEL_PANTHERLAKE_H + select SOC_INTEL_TCSS_USE_PDC_PMC_USBC_MUX_CONFIGURATION + select SUPERIO_ITE_IT8659E + # To be removed when we receive production SKUs for testing + select SOC_INTEL_PANTHERLAKE_PRE_PRODUCTION_SILICON + select FSP_UGOP_EARLY_SIGN_OF_LIFE + +config MAINBOARD_SMBIOS_PRODUCT_NAME + default "PantherLake CRB" + +config MAINBOARD_DIR + default "intel/pantherlake_crb" + +config MAINBOARD_PART_NUMBER + default "PantherLake CRB" + +config CBFS_SIZE + default 0xA00000 + +config USE_PM_ACPI_TIMER + default n + +endif diff --git a/src/mainboard/intel/pantherlake_crb/Kconfig.name b/src/mainboard/intel/pantherlake_crb/Kconfig.name new file mode 100644 index 00000000000..788be0ebb4d --- /dev/null +++ b/src/mainboard/intel/pantherlake_crb/Kconfig.name @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config BOARD_INTEL_PANTHERLAKE_CRB + bool "Intel PantherLake CRB for Edge" diff --git a/src/mainboard/intel/pantherlake_crb/Makefile.mk b/src/mainboard/intel/pantherlake_crb/Makefile.mk new file mode 100644 index 00000000000..bc081ab530d --- /dev/null +++ b/src/mainboard/intel/pantherlake_crb/Makefile.mk @@ -0,0 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + +bootblock-y += bootblock.c +ramstage-y += ramstage.c +romstage-y += romstage.c diff --git a/src/mainboard/intel/pantherlake_crb/board.fmd b/src/mainboard/intel/pantherlake_crb/board.fmd new file mode 100644 index 00000000000..1e1a005c8cd --- /dev/null +++ b/src/mainboard/intel/pantherlake_crb/board.fmd @@ -0,0 +1,21 @@ +FLASH 32M { + SI_ALL 18M { + SI_DESC 16K + SI_EC 576K + SI_GBE 8K + SI_ME + SI_PDR 4K + } + + SI_BIOS 14M { + UNIFIED_MRC_CACHE(PRESERVE) 256K { + RECOVERY_MRC_CACHE 128K + RW_MRC_CACHE 128K + } + SMMSTORE(PRESERVE) 256K + CONSOLE 128K + RW_VPD(PRESERVE) 32K + FMAP 2K + COREBOOT(CBFS) + } +} diff --git a/src/mainboard/intel/pantherlake_crb/board_info.txt b/src/mainboard/intel/pantherlake_crb/board_info.txt new file mode 100644 index 00000000000..2c124320d6a --- /dev/null +++ b/src/mainboard/intel/pantherlake_crb/board_info.txt @@ -0,0 +1,6 @@ +Vendor name: Intel +Board name: PantherLake CRB +Category: eval +ROM protocol: SPI +ROM socketed: y +Flashrom support: y diff --git a/src/mainboard/intel/pantherlake_crb/bootblock.c b/src/mainboard/intel/pantherlake_crb/bootblock.c new file mode 100644 index 00000000000..97955b7c1b6 --- /dev/null +++ b/src/mainboard/intel/pantherlake_crb/bootblock.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include "gpio.h" + +#define UART_DEV PNP_DEV(0x4e, IT8659E_SP1) +#define GPIO_DEV PNP_DEV(0x4e, IT8659E_GPIO) + +void bootblock_mainboard_early_init(void) +{ + // Early eSPI and LPSS UART initialization + gpio_configure_pads(early_gpio_table, ARRAY_SIZE(early_gpio_table)); + + ite_reg_write(GPIO_DEV, 0x26, 0xc0); + ite_reg_write(GPIO_DEV, 0x29, 0x24); + ite_reg_write(GPIO_DEV, 0x2c, 0x88); + + // COM1 (CP2105 Port B) + ite_enable_serial(UART_DEV, CONFIG_TTYS0_BASE); +} diff --git a/src/mainboard/intel/pantherlake_crb/data.vbt b/src/mainboard/intel/pantherlake_crb/data.vbt new file mode 100644 index 00000000000..84ffc62bd45 Binary files /dev/null and b/src/mainboard/intel/pantherlake_crb/data.vbt differ diff --git a/src/mainboard/intel/pantherlake_crb/devicetree.cb b/src/mainboard/intel/pantherlake_crb/devicetree.cb new file mode 100644 index 00000000000..ac7516c89d5 --- /dev/null +++ b/src/mainboard/intel/pantherlake_crb/devicetree.cb @@ -0,0 +1,262 @@ +chip soc/intel/pantherlake + + register "pmc_gpe0_dw0" = "GPP_A" + register "pmc_gpe0_dw1" = "GPP_D" + register "pmc_gpe0_dw2" = "GPP_E" + + device domain 0 on + device ref igpu on + # DDI-A: DP, DDI-B: Unused, DDI-C: Unused + # DDI-1: TCP-0, DDI-2: TCP-1, DDI-3: TCP-2, DDI-4: TCP-4 + register "ddi_port_A_config" = "1" + register "ddi_ports_config" = "{ + [DDI_PORT_A] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + [DDI_PORT_1] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + [DDI_PORT_2] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + [DDI_PORT_3] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + [DDI_PORT_4] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + }" + end + + # TODO: IPU Cameras. Currently no modules available. + + # GbE LAN + device ref gbe on + register "pcie_rp[PCIE_RP(1)]" = "{ + .clk_src = 3, + .clk_req = 3, + .flags = PCIE_RP_LTR, + }" + register "pcie_clk_config_flag[3]" = "PCIE_CLK_LAN" + end + + # M.2 WWAN (untested) + device ref pcie_rp2 on + register "pcie_rp[PCIE_RP(2)]" = "{ + .clk_src = 5, + .clk_req = 5, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_CLK_REQ_DETECT, + }" + end + + # Gen4 x1 slot + device ref pcie_rp3 on + register "pcie_rp[PCIE_RP(3)]" = "{ + .clk_src = 2, + .clk_req = 2, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_CLK_REQ_DETECT, + }" + end + + # M.2 WiFi + device ref pcie_rp4 on + register "pcie_rp[PCH_RP(4)]" = "{ + .clk_src = 4, + .clk_req = 4, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_CLK_REQ_DETECT, + }" + chip soc/intel/common/block/pcie/rtd3 + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_A11)" + register "srcclk_pin" = "4" + device pci 00.0 on end + end + chip drivers/wifi/generic + register "add_acpi_dma_property" = "true" + register "wake" = "GPE0_DW0_12" # GPP_A12 + use usb2_port7 as bluetooth_companion + device pci 00.0 on end + end + end + + # M.2 SSD Gen4 + device ref pcie_rp5 on + register "pcie_rp[PCIE_RP(5)]" = "{ + .clk_src = 6, + .clk_req = 6, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_CLK_REQ_DETECT, + }" + chip soc/intel/common/block/pcie/rtd3 + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_B10)" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_B09)" + register "srcclk_pin" = "6" + device generic 0 on end + end + end + + # PEG Gen5 x4 slot (M.2 SSD Gen5 with rework) + device ref pcie_rp9 on + register "pcie_rp[PCIE_RP(9)]" = "{ + .clk_src = 1, + .clk_req = 1, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_CLK_REQ_DETECT, + }" + end + + # PEG Gen5 x8 slot (available only on PTL-H484) + device ref pcie_rp11 on + register "pcie_rp[PCIE_RP(11)]" = "{ + .clk_src = 0, + .clk_req = 0, + .flags = PCIE_RP_LTR | PCIE_RP_AER | PCIE_RP_CLK_REQ_DETECT, + }" + end + + # TODO: Thunderbolt. No AIC modules available at the moment. + device ref tbt_pcie_rp0 on end + device ref tbt_pcie_rp1 on end + device ref tcss_xhci on end + + # TODO: Type-C role switch + device ref xhci on + register "usb2_ports" = "{ + [0] = USB2_PORT_TYPE_C(OC3), // Type-C P0 + [1] = USB2_PORT_TYPE_C(OC3), // Type-C P1 + [2] = USB2_PORT_TYPE_C(OC6), // Type-C P2 + [3] = USB2_PORT_TYPE_C(OC7), // Type-C P3 + [4] = USB2_PORT_MID(OC0), // Type-A P1 + [5] = USB2_PORT_MID(OC0), // Type-A P2 + [6] = USB2_PORT_MID(OC_SKIP), // M.2 WWAN + [7] = USB2_PORT_MID(OC_SKIP), // M.2 NGFF (BT) + }" + + register "usb3_ports" = "{ + [0] = USB3_PORT_DEFAULT(OC0), // Type-C P1 + [1] = USB3_PORT_DEFAULT(OC0), // Type-C P2 + }" + end + + # CNVi (Untested: lack of hardware). + device ref cnvi_wifi on + chip drivers/wifi/generic + register "wake" = "GPE0_PME_B0" + register "add_acpi_dma_property" = "true" + register "enable_cnvi_ddr_rfim" = "true" + use cnvi_bluetooth as bluetooth_companion + device generic 0 on end + end + end + device ref cnvi_bluetooth on + chip soc/intel/common/block/cnvi + register "wake" = "GPE0_PME_B0" + device generic 0 on end + end + end + + device ref npu on end + + # Likely broken on pre-production silicon? + # Linux freaks out if it's enabled. + device ref iaa off end + + # I2C interfaces + device ref i2c0 on + # TODO: PD Controller + ## Port-A @ 0x20 + ## Port-B @ 0x24 + # TODO: TCSS1 + # TODO: TCSS2 + # TODO: TTK3 @ 0x70 + # TODO: POST_LED @ 0x38 + # TODO: 1x3 HDR + end + + device ref i2c1 on + # TODO: IPU CARD 1 + end + + device ref i2c2 on + # TODO: IPU CARD 2 + end + + device ref i2c3 on + # TODO: AUDIO HDR: 0x1a, 0x28, 0x19, 0x2a, 0x2b + end + + device ref i2c4 on + # TODO: DP Repeater @ (0x08, 0x17)? + # TODO: VBY1 HDR @ 0x48 + end + + device ref i2c5 on end + + # LPSS UART interfaces + device ref uart0 on end # USB-TTL Bridge (Port A). + device ref uart1 on end # J17 header. + device ref uart2 on end # J7 header. + + ## UART0 will fail to initialize on pre-production silicon if set to "Pci"! + register "serial_io_uart_mode" = "{ + [PchSerialIoIndexUART0] = PchSerialIoSkipInit, + [PchSerialIoIndexUART1] = PchSerialIoHidden, + [PchSerialIoIndexUART2] = PchSerialIoHidden, + }" + + register "serial_io_uart_dma_enable" = "{ + [PchSerialIoIndexUART0] = PchSerialDma, + [PchSerialIoIndexUART1] = PchSerialDma, + [PchSerialIoIndexUART2] = PchSerialDma, + }" + + # ITE IT8659E SuperIO + device ref soc_espi on + chip superio/ite/it8659e + device pnp 4e.1 on # COM1: USB-TTL bridge (Port B) + io 0x60 = 0x3f8 + irq 0x70 = 0x04 + irq 0xf0 = 0x01 + irq 0xf1 = 0x50 + irq 0xf2 = 0x00 + end + device pnp 4e.2 off # COM2 + io 0x60 = 0x2f8 + irq 0x70 = 0x03 + irq 0xf0 = 0x00 + irq 0xf1 = 0x50 + irq 0xf2 = 0x00 + end + + device pnp 4e.4 on # EC + io 0x60 = 0x290 + io 0x62 = 0x230 + irq 0x70 = 0x00 + irq 0xf0 = 0x80 + irq 0xf1 = 0x40 + irq 0xf6 = 0xf0 + end + + device pnp 4e.5 off end # PS/2 KB + device pnp 4e.6 off end # PS/2 MS + + device pnp 4e.7 on # GPIO + io 0x60 = 0x000 + io 0x62 = 0x000 + irq 0x26 = 0xc0 + irq 0x29 = 0x24 + irq 0x2c = 0x88 + irq 0x72 = 0x80 + irq 0xb8 = 0x00 + irq 0xbc = 0x20 + irq 0xcb = 0x00 + irq 0xe7 = 0x10 + irq 0xf0 = 0x10 + irq 0xf1 = 0x40 + irq 0xf4 = 0x2d + irq 0xf6 = 0x0e + end + + device pnp 4e.a off end # CIR + end + end + + # TODO: Realtek ALC722-CG Audio. DSP firmware not upstreamed into Linux yet. + device ref hda on + register "pch_hda_dsp_enable" = "true" + register "pch_hda_idisp_link_tmode" = "HDA_TMODE_8T" + register "pch_hda_idisp_link_frequency" = "HDA_LINKFREQ_96MHZ" + register "pch_hda_idisp_codec_enable" = "true" + end + + device ref pmc_shared_sram on end + device ref smbus on end + end +end diff --git a/src/mainboard/intel/pantherlake_crb/dsdt.asl b/src/mainboard/intel/pantherlake_crb/dsdt.asl new file mode 100644 index 00000000000..d5571d7a20f --- /dev/null +++ b/src/mainboard/intel/pantherlake_crb/dsdt.asl @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +// HACK: MISCCFG_GPIO_PM_CONFIG_BITS are missing +#include +#include + +DefinitionBlock( + "dsdt.aml", + "DSDT", + ACPI_DSDT_REV_2, + OEM_ID, + ACPI_TABLE_CREATOR, + 0x20240917 +) + +{ + #include + #include + #include + #include + + Device (\_SB.PCI0) { + #include + #include + #include + } + + #include +} diff --git a/src/mainboard/intel/pantherlake_crb/gpio.h b/src/mainboard/intel/pantherlake_crb/gpio.h new file mode 100644 index 00000000000..b8038005e37 --- /dev/null +++ b/src/mainboard/intel/pantherlake_crb/gpio.h @@ -0,0 +1,230 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include + +/* GPIOs configured in bootblock */ +static const struct pad_config early_gpio_table[] = { + // eSPI: IT8659E SuperIO + PAD_CFG_NF(GPP_A00, NONE, DEEP, NF1), // ESPI_IO0_SIO_R + PAD_CFG_NF(GPP_A01, NONE, DEEP, NF1), // ESPI_IO1_SIO_R + PAD_CFG_NF(GPP_A02, NONE, DEEP, NF1), // ESPI_IO2_SIO_R + PAD_CFG_NF(GPP_A03, NONE, DEEP, NF1), // ESPI_IO3_SIO_R + PAD_CFG_NF(GPP_A04, NONE, DEEP, NF1), // ESPI_CS0_SIO_R_N + PAD_CFG_NF(GPP_A05, NONE, DEEP, NF1), // ESPI_CLK_SIO + PAD_CFG_NF(GPP_A06, NONE, DEEP, NF1), // ESPI_RST_SIO_R_N + PAD_CFG_NF(GPP_B24, NONE, DEEP, NF1), // ESPI_ALERT_SIO_R_N + + // LPSS UART0: USB TTL bridge + PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), // RXD + PAD_CFG_NF(GPP_H09, NONE, DEEP, NF1), // TXD + PAD_CFG_NF(GPP_H10, NONE, DEEP, NF1), // RTS + PAD_CFG_NF(GPP_H11, NONE, DEEP, NF1), // CTS + + // LPSS UART1: J17 header + PAD_CFG_NF(GPP_H14, NONE, DEEP, NF2), // TXD + PAD_CFG_NF(GPP_H15, NONE, DEEP, NF2), // RXD + + // LPSS UART2: J7 header + PAD_CFG_NF(GPP_F00, NONE, DEEP, NF2), // RTS + PAD_CFG_NF(GPP_F01, NONE, DEEP, NF2), // RXD + PAD_CFG_NF(GPP_F02, NONE, DEEP, NF2), // TXD + PAD_CFG_NF(GPP_F03, NONE, DEEP, NF2), // CTS + +}; + +/* GPIOs configured in romstage */ +static const struct pad_config main_gpio_table[] = { + /* GPIO Community A */ + PAD_CFG_GPO(GPP_A08, 1, PLTRST), // X1_PCIE_SLOT_PWR_EN + PAD_CFG_GPO(GPP_A09, 0, DEEP), // M.2_WWAN_FCP_OFF_N + PAD_CFG_GPO(GPP_A10, 0, DEEP), // M.2_WWAN_DISABLE_N + PAD_CFG_GPO(GPP_A11, 1, PLTRST), // WLAN_RST_N + PAD_CFG_GPI_SCI_LOW(GPP_A12, NONE, DEEP, LEVEL), // WLAN_WAKE_N + PAD_CFG_NF(GPP_A13, NONE, PLTRST, NF1), // WWAN_DPR + PAD_CFG_NF(GPP_A15, NONE, DEEP, NF1), // DNX_FORCE_RELOAD + PAD_CFG_GPO(GPP_A16, 1, DEEP), // BT_RF_KILL_N + PAD_CFG_GPO(GPP_A17, 1, DEEP), // WIFI_RF_KILL_N + + /* GPIO Community B */ + PAD_CFG_NF(GPP_B00, NONE, DEEP, NF1), // USB-C SMLCLK + PAD_CFG_NF(GPP_B01, NONE, DEEP, NF1), // USB-C SMLDATA + PAD_CFG_NF(GPP_B02, NONE, DEEP, NF3), // CAM1_ISH_I2C_SDA + PAD_CFG_NF(GPP_B03, NONE, DEEP, NF3), // CAM1_ISH_I2C_SCL + PAD_CFG_GPO(GPP_B04, 0, DEEP), // VBY1_BKLTCTRL_3P3V + PAD_CFG_GPO(GPP_B05, 0, DEEP), // VBY1_GPIO2_3P3V + PAD_CFG_GPO(GPP_B06, 0, DEEP), // VBY1_GPIO1_3P3V + PAD_CFG_NF(GPP_B07, NONE, DEEP, NF4), // ALC722 PCBEEP + PAD_CFG_GPO(GPP_B08, 0, DEEP), // VBY1_GPIO0_3P3V + PAD_CFG_GPO(GPP_B09, 1, PLTRST), // M2_GEN4_SSD_RESET_N + PAD_CFG_GPO(GPP_B10, 0, PLTRST), // M2_GEN4_SSD_PWR_DIS + PAD_CFG_NF(GPP_B11, NONE, DEEP, NF2), // MOD_TCSS1_DISP_HPD3 + PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1), // PM_SLP_S0_N + PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), // PLT_RST_N + PAD_CFG_NF(GPP_B14, NONE, DEEP, NF2), // MOD_TCSS2_DISP_HPD4 + PAD_CFG_NF(GPP_B15, NONE, DEEP, NF1), // MOD_TCSS1_USB_TYP_A_OC3_N + PAD_CFG_GPO(GPP_B16, 0, PLTRST), // X4_PCIE_SLOT_PWR_EN_N + PAD_NC(GPP_B17, NONE), // N/C + PAD_CFG_NF(GPP_B18, NONE, DEEP, NF2), // DDIA_RDVR_I2C_DATA + PAD_CFG_NF(GPP_B19, NONE, DEEP, NF2), // DDIA_RDVR_I2C_CLK + PAD_CFG_GPO(GPP_B20, 1, PLTRST), // M.2_WWAN_RST_BUF_N + PAD_CFG_GPO(GPP_B21, 0, DEEP), // TCP_RETIMER_FORCE_PWR + PAD_CFG_GPO(GPP_B22, 0, PLTRST), // TIME_SYNC0 + PAD_CFG_GPO(GPP_B23, 0, PLTRST), // TIME_SYNC1 + // B24 configured in bootblock + PAD_CFG_GPI_SCI_LOW(GPP_B25, NONE, DEEP, LEVEL), // X1_SLOT_LAN_WAKE_N + + /* GPIO Community C */ + PAD_CFG_NF(GPP_C00, NONE, DEEP, NF1), // DRAM_HSCL_1P0 + PAD_CFG_NF(GPP_C01, NONE, DEEP, NF1), // DRAM_HSDA_1P0 + PAD_CFG_GPI_SCI_LOW(GPP_C02, NONE, DEEP, LEVEL), // PCA9555_0_INT_N + PAD_CFG_NF(GPP_C03, NONE, DEEP, NF1), // SML0_SCL_LAN_PCIE + PAD_CFG_NF(GPP_C04, NONE, DEEP, NF1), // SML0_SDA_LAN_PCIE + PAD_CFG_GPO(GPP_C05, 0, DEEP), // CRD1_PWREN + PAD_NC(GPP_C06, NONE), // N/C + PAD_NC(GPP_C07, NONE), // N/C + PAD_CFG_GPO(GPP_C08, 0, DEEP), // CRD2_PWREN + + /* Source Clock Requests */ + PAD_CFG_NF(GPP_C09, NONE, DEEP, NF1), // SRCCLKREQ0: X8_GEN5_DT_CEM_SLOT_FOR_DGFX + PAD_CFG_NF(GPP_C10, NONE, DEEP, NF1), // SRCCLKREQ1: X4_GEN5_DT_CEM_SLOT + PAD_CFG_NF(GPP_C11, NONE, DEEP, NF1), // SRCCLKREQ2: X1_GEN4_DT_CEM_SLOT + PAD_CFG_NF(GPP_C12, NONE, DEEP, NF1), // SRCCLKREQ3: I226_LAN + PAD_CFG_NF(GPP_C13, NONE, DEEP, NF1), // SRCCLKREQ4: M.2_WLAN_KEY-E + PAD_CFG_NF(GPP_C14, NONE, DEEP, NF1), // SRCCLKREQ5: M.2_WWAN_KEY-B + PAD_CFG_NF(GPP_D18, NONE, DEEP, NF1), // SRCCLKREQ6: X4_GEN4_M.2_SSD_KEY-M + PAD_CFG_NF(GPP_D20, NONE, DEEP, NF1), // SRCCLKREQ7: N/C, exposed on RFSH + PAD_CFG_NF(GPP_D21, NONE, DEEP, NF1), // SRCCLKREQ8: N/C, exposed on RFSH + + PAD_CFG_GPO(GPP_C15, 1, PLTRST), // CAM1_CLK_EN + + /* Thunderbolt/USB-C Display Data Channels */ + PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), // TBT_LSX0_TXD + PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), // TBT_LSX0_RXD + PAD_CFG_NF(GPP_C18, NONE, DEEP, NF1), // TBT_LSX1_TXD + PAD_CFG_NF(GPP_C19, NONE, DEEP, NF1), // TBT_LSX1_RXD + PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), // MOD_TCSS1_LS_TX_DDC_SCL + PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), // MOD_TCSS1_LS_RX_DDC_SDA + PAD_CFG_NF(GPP_C22, NONE, DEEP, NF2), // MOD_TCSS2_LS_TX_DDC_SCL + PAD_CFG_NF(GPP_C23, NONE, DEEP, NF2), // MOD_TCSS2_LS_RX_DDC_SDA + + /* GPIO Community D */ + PAD_CFG_NF(GPP_D00, NONE, DEEP, NF1), // IMGCLKOUT_1 + PAD_CFG_GPO(GPP_D01, 1, DEEP), // MOD_TCSS1_TYP_A_VBUS_EN + PAD_CFG_GPO(GPP_D02, 1, DEEP), // VBY1_BKLTEN_3P3V + PAD_CFG_GPO(GPP_D03, 1, PLTRST), // M.2_WWAN_PERST_GPIO_N + PAD_CFG_NF(GPP_D04, NONE, DEEP, NF1), // IMGCLKOUT_0 + PAD_NC(GPP_D05, NONE), // Unknown, exposed on RFSH + PAD_NC(GPP_D06, NONE), // Unknown, exposed on RFSH + PAD_NC(GPP_D07, NONE), // N/C + PAD_NC(GPP_D08, NONE), // N/C + PAD_CFG_GPO(GPP_D09, 1, PLTRST), // PEG_SLOT_RST_N + PAD_CFG_NF(GPP_D10, NONE, DEEP, NF1), // HDA_BCLK_I2S0_SCLK_HDR + PAD_CFG_NF(GPP_D11, NONE, DEEP, NF1), // HDA_SYNC_I2S0_SFRM_HDR + PAD_CFG_NF(GPP_D12, NONE, DEEP, NF1), // HDA_SDO_I2S0_TXD_HDR + PAD_CFG_NF(GPP_D13, NONE, DEEP, NF1), // HDA_SDI0_I2S0_RXD_HDR + PAD_CFG_GPI_TRIG_OWN(GPP_D14, NONE, PLTRST, LEVEL, ACPI), // COINLESS_MODE_SELECT + PAD_CFG_GPI_APIC_LOCK(GPP_D15, NONE, LEVEL, INVERT, LOCK_CONFIG), // SPI_TPM_INT_N + PAD_CFG_NF(GPP_D16, NONE, DEEP, NF1), // HDA_RST_N_HDR + PAD_CFG_NF(GPP_D17, NONE, DEEP, NF1), // HDA_SDI1_HDR + PAD_CFG_GPO(GPP_D19, 1, PLTRST), // X1_DT_PCIE_RST_N + PAD_CFG_NF(GPP_D22, NONE, DEEP, NF1), // PD_TCP1_DBG_I3C_SDA + PAD_CFG_NF(GPP_D23, NONE, DEEP, NF1), // PD_TCP1_DBG_I3C_SCL + PAD_CFG_GPI_SCI_LOW(GPP_D24, NONE, DEEP, LEVEL), // PEG_SLOT_WAKE_N + PAD_CFG_GPI_SCI_LOW(GPP_D25, NONE, DEEP, LEVEL), // X4_SLOT_WAKE_N + + /* GPIO Community E */ + PAD_CFG_GPO(GPP_E01, 0, PLTRST), // CRD2_RST_N + PAD_NC(GPP_E02, NONE), // N/C + PAD_CFG_GPO(GPP_E03, 1, PLTRST), // X4_DT_PCIE_RST_N + PAD_CFG_GPI_SCI_LOW(GPP_E05, NONE, DEEP, LEVEL), // VBY1_INT_3P3V_N + PAD_CFG_GPI_TRIG_OWN(GPP_E06, NONE, PLTRST, LEVEL, ACPI), // SECURE_CAM_SW + PAD_CFG_NF(GPP_E07, NONE, DEEP, NF1), // DDPA_DDIA_CTRLCLK_R + PAD_CFG_NF(GPP_E08, NONE, DEEP, NF1), // DDPA_DDIA_CTRLDATA_R + PAD_CFG_NF(GPP_E09, NONE, DEEP, NF1), // USB32_TYPEA_CONN1_OC0_N + PAD_CFG_GPO(GPP_E10, 0, PLTRST), // CAM1_RST_N + PAD_NC(GPP_E11, NONE), // GSPI0_CLK: N/C, exposed on RFSH + PAD_NC(GPP_E12, NONE), // GSPI0_MOSI: N/C, exposed on RFSH + PAD_NC(GPP_E13, NONE), // GSPI0_MISO: N/C, exposed on RFSH + PAD_CFG_NF(GPP_E14, NONE, DEEP, NF3), // PD_ALERT_N + PAD_NC(GPP_E15, NONE), // N/C + PAD_CFG_GPI_SCI_LOW(GPP_E16, NONE, DEEP, LEVEL), // DEV_MODE_ID + PAD_NC(GPP_E17, NONE), // GSPI0_CS0: N/C, exposed on RFSH + PAD_NC(GPP_E18, NONE), // N/C, TP1506 + PAD_NC(GPP_E19, NONE), // X8_PEG_SEL_PROCHOT_N + PAD_NC(GPP_E20, NONE), // X8_PEG_DGPU_PWR_OK_3P3 + PAD_CFG_NF(GPP_E21, NONE, DEEP, NF1), // PMC_ALERT_N + PAD_NC(GPP_E22, NONE), // N/C + + /* GPIO Community F */ + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_F04, NONE, DEEP, NF1), // CNV_RF_RESET_R_N + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_F05, NONE, DEEP, NF3), // CRF_CLKREQ_R + + PAD_NC(GPP_F06, NONE), // N/C + PAD_CFG_NF(GPP_F07, NONE, DEEP, NF2), // IMGCLKOUT_2 + PAD_CFG_GPO(GPP_F08, 0, PLTRST), // N/C, but exposed on FUSA and J25 + PAD_CFG_NF(GPP_F09, NONE, DEEP, NF4), // ISH_INT_GP11_CVS_+V12S_CRD1 + PAD_CFG_GPO(GPP_F10, 0, PLTRST), // PEG_SLOT_PWR_EN_N + PAD_CFG_GPO(GPP_F11, 1, DEEP), // MOD_TCSS2_TYP_A_VBUS_EN + PAD_CFG_GPI_TRIG_OWN(GPP_F12, NONE, PLTRST, LEVEL, ACPI), // MOD_TCSS2_DETECT + PAD_CFG_GPI_TRIG_OWN(GPP_F13, NONE, PLTRST, LEVEL, ACPI), // MOD_TCSS2_DETECT_R + PAD_NC(GPP_F14, NONE), // N/C + PAD_NC(GPP_F15, NONE), // N/C + PAD_NC(GPP_F16, NONE), // N/C + PAD_CFG_GPI(GPP_F17, NONE, DEEP), // CODEC_IRQ_HDR + PAD_NC(GPP_F18, NONE), // N/C + PAD_CFG_GPO(GPP_F19, 0, PLTRST), // PRIVACY_LED_CAM2 + PAD_CFG_GPO(GPP_F20, 0, PLTRST), // PRIVACY_LED_CAM1_CVS_HST_WAKE + PAD_CFG_GPO(GPP_F22, 1, PLTRST), // MOD_TCSS1/2_SX_CNTRL_R + PAD_CFG_GPI_SCI_LOW(GPP_F23, NONE, DEEP, LEVEL), // M.2_WWAN_WAKE + + /* GPIO Community H */ + PAD_CFG_GPO(GPP_H00, 0, PLTRST), // CAM2_CLK_EN + PAD_CFG_GPO(GPP_H01, 0, PLTRST), // CAM2_FLSH_STROBE + PAD_CFG_GPO(GPP_H02, 0, PLTRST), // DNX_IN_PROG_LED_R + PAD_CFG_NF(GPP_H03, NONE, DEEP, NF1), // MIC_MUTE + PAD_CFG_NF(GPP_H04, NONE, DEEP, NF1), // I2C2_SDA_CAM_FLSH + PAD_CFG_NF(GPP_H05, NONE, DEEP, NF1), // I2C2_SCL_CAM_FLSH + PAD_CFG_NF(GPP_H06, NONE, DEEP, NF1), // I2C3_SDA_AUDIO_HDR + PAD_CFG_NF(GPP_H07, NONE, DEEP, NF1), // I2C3_SCL_AUDIO_HDR + + /* GPP_H08, H09, H10 and H11 are configured in bootblock for early UART0 bringup + * GPP_H14 and H15 are configured in bootblock for early UART1 bringup */ + + PAD_CFG_NF(GPP_H13, NONE, DEEP, NF1), // CPU_C10_GATE_N + PAD_NC(GPP_H16, NONE), // N/C + PAD_CFG_NF(GPP_H17, NONE, DEEP, NF1), // MIC_MUTE_LED + PAD_CFG_NF(GPP_H19, NONE, DEEP, NF1), // I2C0_SDA_PORT80_DISP_R + PAD_CFG_NF(GPP_H20, NONE, DEEP, NF1), // I2C0_SCL_PORT80_DISP_R + PAD_NC(GPP_H21, NONE), // N/C + PAD_NC(GPP_H22, NONE), // N/C + + /* GPIO Community S (SoundWire) */ + PAD_CFG_NF(GPP_S00, NONE, DEEP, NF1), // SNDW3_CLK_CODEC + PAD_CFG_NF(GPP_S01, NONE, DEEP, NF1), // SNDW3_DATA0_CODEC + PAD_CFG_NF(GPP_S02, NONE, DEEP, NF1), // SNDW3_DATA1_CODEC + PAD_CFG_NF(GPP_S03, NONE, DEEP, NF1), // SNDW3_DATA2_CODEC + PAD_CFG_NF(GPP_S04, NONE, DEEP, NF2), // SNDW2_CLK_DMIC_CLK_A + PAD_CFG_NF(GPP_S05, NONE, DEEP, NF2), // SNDW2_DATA0 + PAD_CFG_NF(GPP_S06, NONE, DEEP, NF3), // SNDW1_CLK_DMIC1 + PAD_CFG_NF(GPP_S07, NONE, DEEP, NF3), // SNDW1_DATA0_DMIC1 + + /* GPIO Community V */ + PAD_CFG_NF(GPP_V00, NONE, DEEP, NF1), // BATLOW_N + PAD_CFG_NF(GPP_V01, NONE, DEEP, NF1), // AC_PRESENT + PAD_CFG_NF(GPP_V02, NONE, DEEP, NF1), // LANWAKE_N + PAD_CFG_NF(GPP_V03, NONE, DEEP, NF1), // PM_PWRBTN_N + PAD_CFG_NF(GPP_V04, NONE, DEEP, NF1), // PM_SLP_S3_N + PAD_CFG_NF(GPP_V05, NONE, DEEP, NF1), // PM_SLP_S4_N + PAD_CFG_NF(GPP_V06, NONE, DEEP, NF1), // PM_SLP_A_N + PAD_NC(GPP_V07, NONE), // N/C + PAD_CFG_NF(GPP_V08, NONE, DEEP, NF1), // SLP_WLAN_N + PAD_CFG_NF(GPP_V09, NONE, DEEP, NF1), // PM_SLP_S5_N + PAD_CFG_NF(GPP_V10, NONE, DEEP, NF1), // LAN_PHY_PC + PAD_CFG_NF(GPP_V11, NONE, DEEP, NF1), // LAN_SW_EN + PAD_CFG_NF(GPP_V12, NONE, DEEP, NF1), // WAKE_N + PAD_CFG_NF(GPP_V13, NONE, DEEP, NF1), // H_CATERR_N + PAD_CFG_NF(GPP_V14, NONE, DEEP, NF1), // FORCE_PROCHOT + PAD_CFG_NF(GPP_V15, NONE, DEEP, NF1), // THERMTRIP_N + PAD_CFG_NF(GPP_V16, NONE, DEEP, NF1), // VCCST_EN_R + PAD_CFG_GPO(GPP_V17, 1, DEEP), // MOD_TCSS1_RT_S0IX_ENTRY_EXIT_N +}; diff --git a/src/mainboard/intel/pantherlake_crb/hda_verb.c b/src/mainboard/intel/pantherlake_crb/hda_verb.c new file mode 100644 index 00000000000..ee90770400a --- /dev/null +++ b/src/mainboard/intel/pantherlake_crb/hda_verb.c @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +const u32 cim_verb_data[] = { + // TODO: Realtek ALC722-CG pins +}; + +const u32 pc_beep_verbs[] = { +}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/starlabs/byte_adl/mainboard.c b/src/mainboard/intel/pantherlake_crb/ramstage.c similarity index 51% rename from src/mainboard/starlabs/byte_adl/mainboard.c rename to src/mainboard/intel/pantherlake_crb/ramstage.c index 60e65ee8c41..ea5e3ab7810 100644 --- a/src/mainboard/starlabs/byte_adl/mainboard.c +++ b/src/mainboard/intel/pantherlake_crb/ramstage.c @@ -1,21 +1,20 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include -#include -#include +#include "gpio.h" static void init_mainboard(void *chip_info) { - const struct pad_config *pads; - size_t num; - - pads = variant_gpio_table(&num); - gpio_configure_pads(pads, num); - - devtree_update(); + gpio_configure_pads(main_gpio_table, ARRAY_SIZE(main_gpio_table)); } struct chip_operations mainboard_ops = { .init = init_mainboard, }; + +void mainboard_silicon_init_params(FSP_S_CONFIG *params) +{ + params->PchLegacyIoLowLatency = 1; +} diff --git a/src/mainboard/intel/pantherlake_crb/romstage.c b/src/mainboard/intel/pantherlake_crb/romstage.c new file mode 100644 index 00000000000..a3e88153703 --- /dev/null +++ b/src/mainboard/intel/pantherlake_crb/romstage.c @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct mb_cfg mem_config = { + .type = MEM_TYPE_DDR5, + .user_bd = BOARD_TYPE_ULT_ULX, + .ect = true, + + .rcomp = { + .resistor = 100, + }, + + .ddr_config = { + .dq_pins_interleaved = false, + } +}; + +static const struct mem_spd spd_info = { + .topo = MEM_TOPO_DIMM_MODULE, + .smbus = { + [0] = { + .addr_dimm[0] = 0x50, + .addr_dimm[1] = 0x0, + }, + + [1] = { + .addr_dimm[0] = 0x50, + .addr_dimm[1] = 0x0, + }, + + [2] = { + .addr_dimm[0] = 0x52, + .addr_dimm[1] = 0x0, + }, + + [3] = { + .addr_dimm[0] = 0x52, + .addr_dimm[1] = 0x0, + }, + }, +}; + +void mainboard_memory_init_params(FSPM_UPD *mupd) +{ + const uint8_t channel_to_ckd_qck[] = { 0, 0, 1, 0, 0, 0, 1, 0 }; + memcpy(mupd->FspmConfig.ChannelToCkdQckMapping, + channel_to_ckd_qck, sizeof(channel_to_ckd_qck)); + + const uint8_t phy_clock_to_ckd_dimm[] = { 0, 0, 0, 0, 8, 0, 8, 0 }; + memcpy(mupd->FspmConfig.PhyClockToCkdDimm, + phy_clock_to_ckd_dimm, sizeof(phy_clock_to_ckd_dimm)); + + + // Raise FSP loglevel for verbose debugging. Requires debug build (NDA). + // mupd->FspmConfig.PcdSerialDebugLevel = 4; + + // GpioOverride needs to be disabled, messes with PCIe CLKREQs + mupd->FspmConfig.GpioOverride = 0; + mupd->FspmConfig.EnableAbove4GBMmio = 1; + + memcfg_init(mupd, &mem_config, &spd_info, false); +} diff --git a/src/mainboard/intel/ptlrvp/intel.c b/src/mainboard/intel/ptlrvp/intel.c index 600d1b3bb73..5e0358ec864 100644 --- a/src/mainboard/intel/ptlrvp/intel.c +++ b/src/mainboard/intel/ptlrvp/intel.c @@ -23,13 +23,3 @@ int get_recovery_mode_switch(void) { return 0; } - -bool chromeos_device_branded_plus_hard(void) -{ - return false; -} - -bool chromeos_device_branded_plus_soft(void) -{ - return false; -} diff --git a/src/mainboard/intel/ptlrvp/romstage.c b/src/mainboard/intel/ptlrvp/romstage.c index 1172f006cb7..e228f3a5bde 100644 --- a/src/mainboard/intel/ptlrvp/romstage.c +++ b/src/mainboard/intel/ptlrvp/romstage.c @@ -2,7 +2,6 @@ #include #include -#include #include #include #include diff --git a/src/mainboard/intel/ptlrvp/variants/baseboard/ptlrvp/devicetree.cb b/src/mainboard/intel/ptlrvp/variants/baseboard/ptlrvp/devicetree.cb index 83e99fb682c..2f9ed9f8c63 100644 --- a/src/mainboard/intel/ptlrvp/variants/baseboard/ptlrvp/devicetree.cb +++ b/src/mainboard/intel/ptlrvp/variants/baseboard/ptlrvp/devicetree.cb @@ -83,6 +83,7 @@ chip soc/intel/pantherlake register "pch_hda_idisp_codec_enable" = "true" register "disable_progress_bar" = "true" + register "vga_cd_clk_freq_sel" = "CD_CLK_461MHZ" device domain 0 on device ref dtt on end diff --git a/src/mainboard/intel/ptlrvp/variants/ptlrvp/overridetree.cb b/src/mainboard/intel/ptlrvp/variants/ptlrvp/overridetree.cb index 73294ec6f1e..0ffdd6e629d 100644 --- a/src/mainboard/intel/ptlrvp/variants/ptlrvp/overridetree.cb +++ b/src/mainboard/intel/ptlrvp/variants/ptlrvp/overridetree.cb @@ -665,6 +665,7 @@ chip soc/intel/pantherlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "0" register "ssdb.platform" = "PLAT_PTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560 * MHz" # 560 MHz @@ -770,6 +771,7 @@ chip soc/intel/pantherlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_PTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560 * MHz" # 560 MHz diff --git a/src/mainboard/intel/ptlrvp/variants/ptlrvp_chromeec/overridetree.cb b/src/mainboard/intel/ptlrvp/variants/ptlrvp_chromeec/overridetree.cb index 2c7782f841c..d6ac1a333a2 100644 --- a/src/mainboard/intel/ptlrvp/variants/ptlrvp_chromeec/overridetree.cb +++ b/src/mainboard/intel/ptlrvp/variants/ptlrvp_chromeec/overridetree.cb @@ -665,6 +665,7 @@ chip soc/intel/pantherlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "4" + register "ssdb.link_used" = "0" register "ssdb.platform" = "PLAT_PTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560 * MHz" # 560 MHz @@ -770,6 +771,7 @@ chip soc/intel/pantherlake register "ssdb.rom_type" = "ROM_EEPROM_CAT24C16" register "rom_address" = "0x50" register "ssdb.lanes_used" = "2" + register "ssdb.link_used" = "2" register "ssdb.platform" = "PLAT_PTL" register "num_freq_entries" = "1" register "link_freq[0]" = "560 * MHz" # 560 MHz diff --git a/src/mainboard/intel/wtm2/devicetree.cb b/src/mainboard/intel/wtm2/devicetree.cb index 3b3a9750aaa..453a45a70a7 100644 --- a/src/mainboard/intel/wtm2/devicetree.cb +++ b/src/mainboard/intel/wtm2/devicetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell # Enable DisplayPort 1 Hotplug with 6ms pulse register "gpu_dp_d_hotplug" = "0x06" @@ -10,7 +10,7 @@ chip soc/intel/broadwell register "gpu_dp_b_hotplug" = "0x06" chip cpu/intel/haswell - device cpu_cluster 0 on ops broadwell_cpu_bus_ops end + device cpu_cluster 0 on ops haswell_cpu_bus_ops end end device domain 0 on ops broadwell_pci_domain_ops @@ -18,7 +18,7 @@ chip soc/intel/broadwell device pci 02.0 on end # vga controller device pci 03.0 on end # mini-hd audio - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint register "alt_gp_smi_en" = "0x0000" register "gpe0_en_1" = "0x00000400" register "gpe0_en_2" = "0x00000000" diff --git a/src/mainboard/intel/wtm2/dsdt.asl b/src/mainboard/intel/wtm2/dsdt.asl index 9e06eb72021..764d442d5fe 100644 --- a/src/mainboard/intel/wtm2/dsdt.asl +++ b/src/mainboard/intel/wtm2/dsdt.asl @@ -18,8 +18,8 @@ DefinitionBlock( #include "acpi/platform.asl" // global NVS and variables - #include - #include + #include + #include // CPU #include @@ -28,7 +28,7 @@ DefinitionBlock( Device (PCI0) { #include - #include + #include } } diff --git a/src/mainboard/lenovo/haswell/Kconfig b/src/mainboard/lenovo/haswell/Kconfig index 46da23cfd28..88037170247 100644 --- a/src/mainboard/lenovo/haswell/Kconfig +++ b/src/mainboard/lenovo/haswell/Kconfig @@ -51,6 +51,9 @@ config VARIANT_DIR config DEVICETREE default "variants/\$(CONFIG_VARIANT_DIR)/devicetree.cb" +config CBFS_SIZE + default 0x700000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT diff --git a/src/mainboard/lenovo/l520/Kconfig b/src/mainboard/lenovo/l520/Kconfig index 6f7c4338282..c3e318e328d 100644 --- a/src/mainboard/lenovo/l520/Kconfig +++ b/src/mainboard/lenovo/l520/Kconfig @@ -7,6 +7,7 @@ config BOARD_SPECIFIC_OPTIONS select AZALIA_USE_LEGACY_VERB_TABLE select BOARD_ROMSIZE_KB_4096 select DRIVER_LENOVO_SERIALS + select DRIVER_LENOVO_SERIALS_EARLY_LOCK select EC_LENOVO_H8 select EC_LENOVO_PMH7 select HAVE_ACPI_RESUME diff --git a/src/mainboard/lenovo/l520/Makefile.mk b/src/mainboard/lenovo/l520/Makefile.mk index 76111943390..2afc15156dd 100644 --- a/src/mainboard/lenovo/l520/Makefile.mk +++ b/src/mainboard/lenovo/l520/Makefile.mk @@ -2,5 +2,6 @@ bootblock-y += gpio.c romstage-y += gpio.c +romstage-y += early_init.c ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads diff --git a/src/mainboard/lenovo/l520/acpi/ec.asl b/src/mainboard/lenovo/l520/acpi/ec.asl index 0e576b13d19..7e96ed79a09 100644 --- a/src/mainboard/lenovo/l520/acpi/ec.asl +++ b/src/mainboard/lenovo/l520/acpi/ec.asl @@ -1,7 +1,3 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include - -Scope(\_SB.PCI0.LPCB.EC) -{ -} diff --git a/src/mainboard/lenovo/l520/early_init.c b/src/mainboard/lenovo/l520/early_init.c new file mode 100644 index 00000000000..7d36c4b990f --- /dev/null +++ b/src/mainboard/lenovo/l520/early_init.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +void mainboard_early_init(bool s3resume) +{ + lenovo_mainboard_eeprom_lock(); +} diff --git a/src/mainboard/lenovo/m920q/Kconfig b/src/mainboard/lenovo/m720q_m920q/Kconfig similarity index 68% rename from src/mainboard/lenovo/m920q/Kconfig rename to src/mainboard/lenovo/m720q_m920q/Kconfig index 53d74b821aa..40641c211fd 100644 --- a/src/mainboard/lenovo/m920q/Kconfig +++ b/src/mainboard/lenovo/m720q_m920q/Kconfig @@ -1,11 +1,12 @@ # SPDX-License-Identifier: GPL-2.0-only -if BOARD_LENOVO_M920Q +if BOARD_LENOVO_M920Q || BOARD_LENOVO_M720Q config BOARD_SPECIFIC_OPTIONS def_bool y select AZALIA_USE_LEGACY_VERB_TABLE - select BOARD_ROMSIZE_KB_24576 + select BOARD_ROMSIZE_KB_16384 if BOARD_LENOVO_M720Q + select BOARD_ROMSIZE_KB_24576 if BOARD_LENOVO_M920Q select DRIVERS_UART_8250IO select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES @@ -22,10 +23,11 @@ config BOARD_SPECIFIC_OPTIONS select SUPERIO_NUVOTON_NCT6687D config MAINBOARD_DIR - default "lenovo/m920q" + default "lenovo/m720q_m920q" config MAINBOARD_PART_NUMBER - default "ThinkCentre M920 Tiny" + default "ThinkCentre M720 Tiny" if BOARD_LENOVO_M720Q + default "ThinkCentre M920 Tiny" if BOARD_LENOVO_M920Q config CBFS_SIZE default 0x900000 diff --git a/src/mainboard/lenovo/m920q/Kconfig.name b/src/mainboard/lenovo/m720q_m920q/Kconfig.name similarity index 62% rename from src/mainboard/lenovo/m920q/Kconfig.name rename to src/mainboard/lenovo/m720q_m920q/Kconfig.name index ccdd21a2379..6f5110366af 100644 --- a/src/mainboard/lenovo/m920q/Kconfig.name +++ b/src/mainboard/lenovo/m720q_m920q/Kconfig.name @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only +config BOARD_LENOVO_M720Q + bool "ThinkCentre M720 Tiny" + config BOARD_LENOVO_M920Q bool "ThinkCentre M920 Tiny" diff --git a/src/mainboard/lenovo/m920q/Makefile.mk b/src/mainboard/lenovo/m720q_m920q/Makefile.mk similarity index 100% rename from src/mainboard/lenovo/m920q/Makefile.mk rename to src/mainboard/lenovo/m720q_m920q/Makefile.mk diff --git a/src/mainboard/lenovo/m920q/acpi/ec.asl b/src/mainboard/lenovo/m720q_m920q/acpi/ec.asl similarity index 100% rename from src/mainboard/lenovo/m920q/acpi/ec.asl rename to src/mainboard/lenovo/m720q_m920q/acpi/ec.asl diff --git a/src/mainboard/lenovo/m920q/acpi/mainboard.asl b/src/mainboard/lenovo/m720q_m920q/acpi/mainboard.asl similarity index 100% rename from src/mainboard/lenovo/m920q/acpi/mainboard.asl rename to src/mainboard/lenovo/m720q_m920q/acpi/mainboard.asl diff --git a/src/mainboard/lenovo/m920q/acpi/superio.asl b/src/mainboard/lenovo/m720q_m920q/acpi/superio.asl similarity index 100% rename from src/mainboard/lenovo/m920q/acpi/superio.asl rename to src/mainboard/lenovo/m720q_m920q/acpi/superio.asl diff --git a/src/mainboard/lenovo/m920q/board_info.txt b/src/mainboard/lenovo/m720q_m920q/board_info.txt similarity index 51% rename from src/mainboard/lenovo/m920q/board_info.txt rename to src/mainboard/lenovo/m720q_m920q/board_info.txt index 02e3e322eb3..8420ecc4489 100644 --- a/src/mainboard/lenovo/m920q/board_info.txt +++ b/src/mainboard/lenovo/m720q_m920q/board_info.txt @@ -1,7 +1,7 @@ Category: desktop -Board URL: https://psref.lenovo.com/Product/ThinkCentre_M920_Tiny +Board URL: ThinkCentre M720q/M920q ROM package: SOIC-8 ROM protocol: SPI ROM socketed: n Flashrom support: y -Release year: 2021 +Release year: 2018 diff --git a/src/mainboard/lenovo/m920q/bootblock.c b/src/mainboard/lenovo/m720q_m920q/bootblock.c similarity index 100% rename from src/mainboard/lenovo/m920q/bootblock.c rename to src/mainboard/lenovo/m720q_m920q/bootblock.c diff --git a/src/mainboard/lenovo/m920q/cmos.default b/src/mainboard/lenovo/m720q_m920q/cmos.default similarity index 100% rename from src/mainboard/lenovo/m920q/cmos.default rename to src/mainboard/lenovo/m720q_m920q/cmos.default diff --git a/src/mainboard/lenovo/m920q/cmos.layout b/src/mainboard/lenovo/m720q_m920q/cmos.layout similarity index 100% rename from src/mainboard/lenovo/m920q/cmos.layout rename to src/mainboard/lenovo/m720q_m920q/cmos.layout diff --git a/src/mainboard/lenovo/m920q/data.vbt b/src/mainboard/lenovo/m720q_m920q/data.vbt similarity index 100% rename from src/mainboard/lenovo/m920q/data.vbt rename to src/mainboard/lenovo/m720q_m920q/data.vbt diff --git a/src/mainboard/lenovo/m920q/devicetree.cb b/src/mainboard/lenovo/m720q_m920q/devicetree.cb similarity index 100% rename from src/mainboard/lenovo/m920q/devicetree.cb rename to src/mainboard/lenovo/m720q_m920q/devicetree.cb diff --git a/src/mainboard/lenovo/m920q/dsdt.asl b/src/mainboard/lenovo/m720q_m920q/dsdt.asl similarity index 100% rename from src/mainboard/lenovo/m920q/dsdt.asl rename to src/mainboard/lenovo/m720q_m920q/dsdt.asl diff --git a/src/mainboard/lenovo/m920q/gma-mainboard.ads b/src/mainboard/lenovo/m720q_m920q/gma-mainboard.ads similarity index 100% rename from src/mainboard/lenovo/m920q/gma-mainboard.ads rename to src/mainboard/lenovo/m720q_m920q/gma-mainboard.ads diff --git a/src/mainboard/lenovo/m920q/gpio.c b/src/mainboard/lenovo/m720q_m920q/gpio.c similarity index 100% rename from src/mainboard/lenovo/m920q/gpio.c rename to src/mainboard/lenovo/m720q_m920q/gpio.c diff --git a/src/mainboard/lenovo/m920q/hda_verb.c b/src/mainboard/lenovo/m720q_m920q/hda_verb.c similarity index 100% rename from src/mainboard/lenovo/m920q/hda_verb.c rename to src/mainboard/lenovo/m720q_m920q/hda_verb.c diff --git a/src/mainboard/lenovo/m920q/include/mainboard/gpio.h b/src/mainboard/lenovo/m720q_m920q/include/mainboard/gpio.h similarity index 100% rename from src/mainboard/lenovo/m920q/include/mainboard/gpio.h rename to src/mainboard/lenovo/m720q_m920q/include/mainboard/gpio.h diff --git a/src/mainboard/lenovo/m920q/ramstage.c b/src/mainboard/lenovo/m720q_m920q/ramstage.c similarity index 100% rename from src/mainboard/lenovo/m920q/ramstage.c rename to src/mainboard/lenovo/m720q_m920q/ramstage.c diff --git a/src/mainboard/lenovo/m920q/romstage.c b/src/mainboard/lenovo/m720q_m920q/romstage.c similarity index 100% rename from src/mainboard/lenovo/m920q/romstage.c rename to src/mainboard/lenovo/m720q_m920q/romstage.c diff --git a/src/mainboard/lenovo/s230u/Kconfig b/src/mainboard/lenovo/s230u/Kconfig index 5fc7570aa96..ca0a639eddc 100644 --- a/src/mainboard/lenovo/s230u/Kconfig +++ b/src/mainboard/lenovo/s230u/Kconfig @@ -7,6 +7,7 @@ config BOARD_SPECIFIC_OPTIONS select AZALIA_USE_LEGACY_VERB_TABLE select BOARD_ROMSIZE_KB_12288 select DRIVER_LENOVO_SERIALS + select DRIVER_LENOVO_SERIALS_EARLY_LOCK select EC_ACPI select EC_COMPAL_ENE932 select GFX_GMA_PANEL_1_ON_LVDS diff --git a/src/mainboard/lenovo/s230u/early_init.c b/src/mainboard/lenovo/s230u/early_init.c index ba52b7e7c91..1f250916206 100644 --- a/src/mainboard/lenovo/s230u/early_init.c +++ b/src/mainboard/lenovo/s230u/early_init.c @@ -2,8 +2,10 @@ #include #include +#include #include #include +#include #include #include "ec.h" @@ -56,3 +58,8 @@ void mb_get_spd_map(struct spd_info *spdi) spdi->addresses[0] = SPD_MEMORY_DOWN; spdi->spd_index = spd_index; } + +void mainboard_early_init(bool s3resume) +{ + lenovo_mainboard_eeprom_lock(); +} diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig index d69d94f6382..b7cc7056999 100644 --- a/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig +++ b/src/mainboard/lenovo/sklkbl_thinkpad/Kconfig @@ -32,6 +32,7 @@ config BOARD_LENOVO_T470S config BOARD_LENOVO_T480 bool select BOARD_LENOVO_SKLKBL_THINKPAD_COMMON + select DRIVERS_INTEL_DTBT select SOC_INTEL_KABYLAKE select MEC1653_HAS_DEBUG_UNLOCK select VARIANT_HAS_DGPU @@ -39,6 +40,7 @@ config BOARD_LENOVO_T480 config BOARD_LENOVO_T480S bool select BOARD_LENOVO_SKLKBL_THINKPAD_COMMON + select DRIVERS_INTEL_DTBT select SOC_INTEL_KABYLAKE select VARIANT_HAS_DGPU @@ -52,6 +54,7 @@ config BOARD_LENOVO_T580 config BOARD_LENOVO_X280 bool select BOARD_LENOVO_SKLKBL_THINKPAD_COMMON + select DRIVERS_INTEL_DTBT select SOC_INTEL_KABYLAKE select HAVE_SPD_IN_CBFS diff --git a/src/mainboard/starlabs/byte_adl/acpi/mainboard.asl b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/mainboard.asl similarity index 100% rename from src/mainboard/starlabs/byte_adl/acpi/mainboard.asl rename to src/mainboard/lenovo/sklkbl_thinkpad/acpi/mainboard.asl diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/acpi/sleep.asl b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/sleep.asl new file mode 100644 index 00000000000..7460baeabb3 --- /dev/null +++ b/src/mainboard/lenovo/sklkbl_thinkpad/acpi/sleep.asl @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* Prepare discrete TBT controller before sleep */ +Method(MPTS, 1, Serialized) { + If (CondRefOf(\TBTS)) { + \TBTS() + } +} diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/cfr.c b/src/mainboard/lenovo/sklkbl_thinkpad/cfr.c index 8f282facdd4..213c90a17d6 100644 --- a/src/mainboard/lenovo/sklkbl_thinkpad/cfr.c +++ b/src/mainboard/lenovo/sklkbl_thinkpad/cfr.c @@ -8,6 +8,8 @@ #include #include +WEAK_DEV_PTR(dgpu); + /* Hide the dGPU CFR entry if dGPU not present */ static void update_dgpu(struct sm_object *new) { @@ -22,11 +24,7 @@ static const struct sm_object dgpu = SM_DECLARE_ENUM({ .opt_name = "dgpu_enable", .ui_name = "dGPU", .ui_helptext = "Enable or disable the dGPU", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = false, }, WITH_CALLBACK(update_dgpu)); static struct sm_obj_form system = { diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb b/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb index 5ec7750025f..1ce50a0358e 100644 --- a/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb +++ b/src/mainboard/lenovo/sklkbl_thinkpad/devicetree.cb @@ -8,6 +8,8 @@ chip soc/intel/skylake register "PmConfigSlpSusMinAssert" = "3" # 500ms register "PmConfigSlpAMinAssert" = "3" # 2s + # Generate ACPI P-State table + register "eist_enable" = "true" device domain 0 on subsystemid 0x17aa 0x225d inherit device ref igpu on diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl b/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl index aa4d4de2a6f..1279665beef 100644 --- a/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl +++ b/src/mainboard/lenovo/sklkbl_thinkpad/dsdt.asl @@ -11,6 +11,7 @@ DefinitionBlock( ) { #include + #include #include #include diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/spd/spd.c b/src/mainboard/lenovo/sklkbl_thinkpad/spd/spd.c index 6ce18e51679..eaff251cc7d 100644 --- a/src/mainboard/lenovo/sklkbl_thinkpad/spd/spd.c +++ b/src/mainboard/lenovo/sklkbl_thinkpad/spd/spd.c @@ -28,8 +28,7 @@ uint8_t *mainboard_find_spd_data(uint8_t spd_index) die("Missing SPD data (spd.bin size %zu smaller than SPD size %u).", spd_file_len, SPD_SIZE_MAX_DDR4); /* Assume same memory in both channels */ - spd_index *= SPD_SIZE_MAX_DDR4; - spd_data = (uint8_t *)(spd_file + spd_index); + spd_data = (uint8_t *)(spd_file + spd_index * SPD_SIZE_MAX_DDR4); /* Make sure a valid SPD was found */ if (spd_data[0] == 0) diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c index f337843fd9b..ffd2841e497 100644 --- a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c +++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480/gpio.c @@ -86,7 +86,7 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_C18, NONE), PAD_NC(GPP_C19, NONE), PAD_CFG_GPO(GPP_C20, 0, DEEP), /* EPRIVACY_ON */ - PAD_CFG_GPO(GPP_C21, 0, DEEP), /* TBT_FORCE_PWR */ + PAD_CFG_GPO(GPP_C21, 1, PLTRST), /* TBT_FORCE_PWR */ PAD_CFG_GPI_SCI(GPP_C22, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_SCI */ PAD_CFG_GPI_SCI(GPP_C23, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_WAKE */ @@ -191,9 +191,9 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_G1, NONE), PAD_NC(GPP_G2, NONE), PAD_NC(GPP_G3, NONE), - PAD_CFG_GPO(GPP_G4, 0, DEEP), /* TBT_RTD3_PWR_EN */ - PAD_CFG_GPO(GPP_G5, 0, DEEP), /* TBT_FORCE_USB_PWR */ - PAD_CFG_GPO(GPP_G6, 0, DEEP), /* -TBT_PERST */ + PAD_CFG_GPO(GPP_G4, 1, PLTRST), /* TBT_RTD3_PWR_EN */ + PAD_CFG_GPO(GPP_G5, 1, PLTRST), /* TBT_FORCE_USB_PWR */ + PAD_CFG_GPO(GPP_G6, 1, PLTRST), /* -TBT_PERST */ PAD_CFG_GPI_SCI(GPP_G7, NONE, DEEP, LEVEL, INVERT), /* -TBT_PCIE_WAKE */ }; diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c index 4f1c57390dd..c24c1abb07d 100644 --- a/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c +++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/t480s/gpio.c @@ -82,7 +82,7 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_C18, NONE), PAD_NC(GPP_C19, NONE), PAD_CFG_GPO(GPP_C20, 0, DEEP), /* EPRIVACY_ON */ - PAD_CFG_GPO(GPP_C21, 0, DEEP), /* TBT_FORCE_PWR */ + PAD_CFG_GPO(GPP_C21, 1, PLTRST), /* TBT_FORCE_PWR */ PAD_CFG_GPI_SCI(GPP_C22, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_SCI */ PAD_CFG_GPI_SCI(GPP_C23, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_WAKE */ @@ -187,9 +187,9 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_G1, NONE), PAD_NC(GPP_G2, NONE), PAD_NC(GPP_G3, NONE), - PAD_CFG_GPO(GPP_G4, 0, DEEP), /* TBT_RTD3_PWR_EN */ - PAD_CFG_GPO(GPP_G5, 0, DEEP), /* TBT_FORCE_USB_PWR */ - PAD_CFG_GPO(GPP_G6, 0, DEEP), /* -TBT_PERST */ + PAD_CFG_GPO(GPP_G4, 1, PLTRST), /* TBT_RTD3_PWR_EN */ + PAD_CFG_GPO(GPP_G5, 1, PLTRST), /* TBT_FORCE_USB_PWR */ + PAD_CFG_GPO(GPP_G6, 1, PLTRST), /* -TBT_PERST */ PAD_CFG_GPI_SCI(GPP_G7, NONE, DEEP, LEVEL, INVERT), /* -TBT_PCIE_WAKE */ }; diff --git a/src/mainboard/lenovo/sklkbl_thinkpad/variants/x280/gpio.c b/src/mainboard/lenovo/sklkbl_thinkpad/variants/x280/gpio.c index f38734be852..13c4a5240b6 100644 --- a/src/mainboard/lenovo/sklkbl_thinkpad/variants/x280/gpio.c +++ b/src/mainboard/lenovo/sklkbl_thinkpad/variants/x280/gpio.c @@ -82,7 +82,7 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_C18, NONE), PAD_NC(GPP_C19, NONE), PAD_NC(GPP_C20, NONE), - PAD_CFG_GPO(GPP_C21, 0, DEEP), /* TBT_FORCE_PWR */ + PAD_CFG_GPO(GPP_C21, 1, PLTRST), /* TBT_FORCE_PWR */ PAD_CFG_GPI_SCI(GPP_C22, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_SCI */ PAD_CFG_GPI_SCI(GPP_C23, NONE, DEEP, EDGE_SINGLE, INVERT), /* -EC_WAKE */ @@ -187,10 +187,10 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_G1, NONE), PAD_NC(GPP_G2, NONE), PAD_NC(GPP_G3, NONE), - PAD_CFG_GPO(GPP_G4, 0, DEEP), /* TBT_RTD3_PWR_EN */ - PAD_CFG_GPO(GPP_G5, 0, DEEP), /* TBT_FORCE_USB_PWR */ - PAD_CFG_GPO(GPP_G6, 0, DEEP), /* -TBT_PERST */ - PAD_CFG_GPI_SCI(GPP_G7, NONE, DEEP, LEVEL, INVERT), /* -TBT_PCIE_WAKE */ + PAD_CFG_GPO(GPP_G4, 1, PLTRST), /* TBT_RTD3_PWR_EN */ + PAD_CFG_GPO(GPP_G5, 1, PLTRST), /* TBT_FORCE_USB_PWR */ + PAD_CFG_GPO(GPP_G6, 1, PLTRST), /* -TBT_PERST */ + PAD_CFG_GPI_SCI(GPP_G7, NONE, DEEP, LEVEL, INVERT), /* -TBT_PCIE_WAKE */ }; diff --git a/src/mainboard/lenovo/t400/variants/t400/overridetree.cb b/src/mainboard/lenovo/t400/variants/t400/overridetree.cb index c3c3b082a5d..1e0c3fe1004 100644 --- a/src/mainboard/lenovo/t400/variants/t400/overridetree.cb +++ b/src/mainboard/lenovo/t400/variants/t400/overridetree.cb @@ -4,7 +4,7 @@ chip northbridge/intel/gm45 device pci 1f.0 on # LPC bridge subsystemid 0x17aa 0x20f5 chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy + device generic 0 alias hg_mux on end # dummy register "detect_gpio" = "21" diff --git a/src/mainboard/lenovo/t410/devicetree.cb b/src/mainboard/lenovo/t410/devicetree.cb index 9ba70d79e85..d4af8253e63 100644 --- a/src/mainboard/lenovo/t410/devicetree.cb +++ b/src/mainboard/lenovo/t410/devicetree.cb @@ -134,7 +134,7 @@ chip northbridge/intel/ironlake register "evente_enable" = "0x2d" end chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy + device generic 0 alias hg_mux on end # dummy register "detect_gpio" = "21" diff --git a/src/mainboard/lenovo/t420/Kconfig b/src/mainboard/lenovo/t420/Kconfig index 1b9ddd6e4c6..b14885eb6a8 100644 --- a/src/mainboard/lenovo/t420/Kconfig +++ b/src/mainboard/lenovo/t420/Kconfig @@ -22,6 +22,7 @@ config BOARD_SPECIFIC_OPTIONS select INTEL_INT15 select DRIVERS_RICOH_RCE822 select DRIVER_LENOVO_SERIALS + select DRIVER_LENOVO_SERIALS_EARLY_LOCK select MEMORY_MAPPED_TPM select MAINBOARD_HAS_TPM1 select MAINBOARD_HAS_LIBGFXINIT @@ -44,6 +45,9 @@ config VBOOT config VBOOT_SLOTS_RW_A default y +config CBFS_SIZE + default 0x300000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT diff --git a/src/mainboard/lenovo/t420/acpi/ec.asl b/src/mainboard/lenovo/t420/acpi/ec.asl index 7971d027b24..987593e919a 100644 --- a/src/mainboard/lenovo/t420/acpi/ec.asl +++ b/src/mainboard/lenovo/t420/acpi/ec.asl @@ -1,9 +1,4 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include - -Scope(\_SB.PCI0.LPCB.EC) -{ -} - #include diff --git a/src/mainboard/lenovo/t420/devicetree.cb b/src/mainboard/lenovo/t420/devicetree.cb index 37ac884eb31..4e4d4a0d8e9 100644 --- a/src/mainboard/lenovo/t420/devicetree.cb +++ b/src/mainboard/lenovo/t420/devicetree.cb @@ -153,7 +153,7 @@ chip northbridge/intel/sandybridge register "bdc_gpio_lvl" = "0" end chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy + device generic 0 alias hg_mux on end # dummy register "detect_gpio" = "21" diff --git a/src/mainboard/lenovo/t420/early_init.c b/src/mainboard/lenovo/t420/early_init.c index b14fea93a68..89e3514316d 100644 --- a/src/mainboard/lenovo/t420/early_init.c +++ b/src/mainboard/lenovo/t420/early_init.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include @@ -33,4 +34,5 @@ static void hybrid_graphics_init(void) void mainboard_early_init(bool s3resume) { hybrid_graphics_init(); + lenovo_mainboard_eeprom_lock(); } diff --git a/src/mainboard/lenovo/t420s/Kconfig b/src/mainboard/lenovo/t420s/Kconfig index 21bbd874310..bf8a9cf0f3e 100644 --- a/src/mainboard/lenovo/t420s/Kconfig +++ b/src/mainboard/lenovo/t420s/Kconfig @@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_8192 select DRIVERS_LENOVO_HYBRID_GRAPHICS select DRIVER_LENOVO_SERIALS + select DRIVER_LENOVO_SERIALS_EARLY_LOCK select EC_LENOVO_H8 select EC_LENOVO_PMH7 select GFX_GMA_PANEL_1_ON_LVDS @@ -42,6 +43,9 @@ config VBOOT config VBOOT_SLOTS_RW_A default y +config CBFS_SIZE + default 0x300000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT diff --git a/src/mainboard/lenovo/t420s/acpi/ec.asl b/src/mainboard/lenovo/t420s/acpi/ec.asl index 7971d027b24..987593e919a 100644 --- a/src/mainboard/lenovo/t420s/acpi/ec.asl +++ b/src/mainboard/lenovo/t420s/acpi/ec.asl @@ -1,9 +1,4 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include - -Scope(\_SB.PCI0.LPCB.EC) -{ -} - #include diff --git a/src/mainboard/lenovo/t420s/devicetree.cb b/src/mainboard/lenovo/t420s/devicetree.cb index 335e025c725..4ae67ec3f84 100644 --- a/src/mainboard/lenovo/t420s/devicetree.cb +++ b/src/mainboard/lenovo/t420s/devicetree.cb @@ -145,7 +145,7 @@ chip northbridge/intel/sandybridge register "bdc_gpio_lvl" = "0" end chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy + device generic 0 alias hg_mux on end # dummy register "detect_gpio" = "21" diff --git a/src/mainboard/lenovo/t420s/early_init.c b/src/mainboard/lenovo/t420s/early_init.c index b14fea93a68..89e3514316d 100644 --- a/src/mainboard/lenovo/t420s/early_init.c +++ b/src/mainboard/lenovo/t420s/early_init.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include @@ -33,4 +34,5 @@ static void hybrid_graphics_init(void) void mainboard_early_init(bool s3resume) { hybrid_graphics_init(); + lenovo_mainboard_eeprom_lock(); } diff --git a/src/mainboard/lenovo/t430/Kconfig b/src/mainboard/lenovo/t430/Kconfig deleted file mode 100644 index 20726edb505..00000000000 --- a/src/mainboard/lenovo/t430/Kconfig +++ /dev/null @@ -1,76 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -if BOARD_LENOVO_THINKPAD_T430 - -config BOARD_SPECIFIC_OPTIONS - def_bool y - select AZALIA_USE_LEGACY_VERB_TABLE - select BOARD_ROMSIZE_KB_12288 - select DRIVERS_LENOVO_HYBRID_GRAPHICS - select DRIVER_LENOVO_SERIALS - select DRIVERS_RICOH_RCE822 - select EC_LENOVO_H8 - select EC_LENOVO_PMH7 - select GFX_GMA_PANEL_1_ON_LVDS - select H8_HAS_BAT_THRESHOLDS_IMPL - select H8_HAS_BDC_GPIO_DETECTION - select H8_HAS_WWAN_GPIO_DETECTION - select HAVE_ACPI_RESUME - select HAVE_ACPI_TABLES - select HAVE_CMOS_DEFAULT - select HAVE_OPTION_TABLE - select INTEL_GMA_HAVE_VBT - select INTEL_INT15 - select MAINBOARD_HAS_LIBGFXINIT - select MAINBOARD_HAS_TPM1 - select MAINBOARD_USES_IFD_GBE_REGION - select MEMORY_MAPPED_TPM - select NO_UART_ON_SUPERIO - select NORTHBRIDGE_INTEL_SANDYBRIDGE - select SERIRQ_CONTINUOUS_MODE - select SOUTHBRIDGE_INTEL_C216 - select SYSTEM_TYPE_LAPTOP - select USE_NATIVE_RAMINIT - -config VBOOT - select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC - select GBB_FLAG_DISABLE_FWMP - select GBB_FLAG_DISABLE_LID_SHUTDOWN - select GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC - select HAS_RECOVERY_MRC_CACHE - select VBOOT_VBNV_FLASH - -config VBOOT_SLOTS_RW_AB - default y - -config FMDFILE - default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT - -config MAINBOARD_DIR - default "lenovo/t430" - -config MAINBOARD_PART_NUMBER - default "ThinkPad T430" - -config VGA_BIOS_ID - string - default "8086,0166" - -config DRAM_RESET_GATE_GPIO - int - default 10 - -config USBDEBUG_HCD_INDEX - int - default 2 - -config PS2K_EISAID - default "PNP0303" - -config PS2M_EISAID - default "LEN0015" - -config THINKPADEC_HKEY_EISAID - default "LEN0068" - -endif diff --git a/src/mainboard/lenovo/t430/Kconfig.name b/src/mainboard/lenovo/t430/Kconfig.name deleted file mode 100644 index f14a1a2d786..00000000000 --- a/src/mainboard/lenovo/t430/Kconfig.name +++ /dev/null @@ -1,4 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -config BOARD_LENOVO_THINKPAD_T430 - bool "ThinkPad T430" diff --git a/src/mainboard/lenovo/t430/Makefile.mk b/src/mainboard/lenovo/t430/Makefile.mk deleted file mode 100644 index e4b6fbf0f0a..00000000000 --- a/src/mainboard/lenovo/t430/Makefile.mk +++ /dev/null @@ -1,8 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -bootblock-y += gpio.c -romstage-y += gpio.c - -ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads -bootblock-y += early_init.c -romstage-y += early_init.c diff --git a/src/mainboard/lenovo/t430/acpi/ec.asl b/src/mainboard/lenovo/t430/acpi/ec.asl deleted file mode 100644 index 987593e919a..00000000000 --- a/src/mainboard/lenovo/t430/acpi/ec.asl +++ /dev/null @@ -1,4 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include diff --git a/src/mainboard/lenovo/t430/acpi/superio.asl b/src/mainboard/lenovo/t430/acpi/superio.asl deleted file mode 100644 index ee2eabeb756..00000000000 --- a/src/mainboard/lenovo/t430/acpi/superio.asl +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include diff --git a/src/mainboard/lenovo/t430/acpi_tables.c b/src/mainboard/lenovo/t430/acpi_tables.c deleted file mode 100644 index 36d3e85c1ef..00000000000 --- a/src/mainboard/lenovo/t430/acpi_tables.c +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -void mainboard_fill_gnvs(struct global_nvs *gnvs) -{ - /* The lid is open by default */ - gnvs->lids = 1; - - /* Temperature at which OS will shutdown */ - gnvs->tcrt = 100; - /* Temperature at which OS will throttle CPU */ - gnvs->tpsv = 90; -} diff --git a/src/mainboard/lenovo/t430/board_info.txt b/src/mainboard/lenovo/t430/board_info.txt deleted file mode 100644 index 09ddde1f859..00000000000 --- a/src/mainboard/lenovo/t430/board_info.txt +++ /dev/null @@ -1,6 +0,0 @@ -Category: laptop -ROM package: SOIC-8 -ROM protocol: SPI -ROM socketed: n -Flashrom support: n -Release year: 2012 diff --git a/src/mainboard/lenovo/t430/cmos.default b/src/mainboard/lenovo/t430/cmos.default deleted file mode 100644 index c896eadec1e..00000000000 --- a/src/mainboard/lenovo/t430/cmos.default +++ /dev/null @@ -1,20 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -boot_option=Fallback -debug_level=Debug -power_on_after_fail=Disable -nmi=Enable -volume=0x3 -first_battery=Primary -bluetooth=Enable -wwan=Enable -wlan=Enable -touchpad=Enable -sata_mode=AHCI -fn_ctrl_swap=Disable -sticky_fn=Disable -trackpoint=Enable -backlight=Both -usb_always_on=Disable -hybrid_graphics_mode=Integrated Only -me_state=Normal diff --git a/src/mainboard/lenovo/t430/cmos.layout b/src/mainboard/lenovo/t430/cmos.layout deleted file mode 100644 index 3e48df5584d..00000000000 --- a/src/mainboard/lenovo/t430/cmos.layout +++ /dev/null @@ -1,107 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -# ----------------------------------------------------------------- -entries - -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory - -# ----------------------------------------------------------------- -# RTC_BOOT_BYTE (coreboot hardcoded) -384 1 e 4 boot_option -388 4 h 0 reboot_counter - -# ----------------------------------------------------------------- -# coreboot config options: console -395 4 e 6 debug_level - -#400 8 r 0 reserved for century byte - -# coreboot config options: southbridge -408 1 e 1 nmi -409 2 e 7 power_on_after_fail - -# coreboot config options: EC -411 1 e 8 first_battery -412 1 e 1 bluetooth -413 1 e 1 wwan -414 1 e 1 touchpad -415 1 e 1 wlan -416 1 e 1 trackpoint -417 1 e 1 fn_ctrl_swap -418 1 e 1 sticky_fn -419 2 e 13 usb_always_on -421 1 e 9 sata_mode -422 2 e 10 backlight - -# coreboot config options: ME -424 1 e 14 me_state -425 2 h 0 me_state_prev - -# coreboot config options: northbridge -432 3 e 11 gfx_uma_size -435 2 e 12 hybrid_graphics_mode -440 8 h 0 volume - -# VBOOT -448 128 r 0 vbnv - -# SandyBridge MRC Scrambler Seed values -896 32 r 0 mrc_scrambler_seed -928 32 r 0 mrc_scrambler_seed_s3 -960 16 r 0 mrc_scrambler_seed_chk - -# coreboot config options: check sums -984 16 h 0 check_sum - -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable -2 0 Enable -2 1 Disable -4 0 Fallback -4 1 Normal -6 0 Emergency -6 1 Alert -6 2 Critical -6 3 Error -6 4 Warning -6 5 Notice -6 6 Info -6 7 Debug -6 8 Spew -7 0 Disable -7 1 Enable -7 2 Keep -8 0 Secondary -8 1 Primary -9 0 AHCI -9 1 Compatible -10 0 Both -10 1 Keyboard only -10 2 Thinklight only -10 3 None -11 0 32M -11 1 64M -11 2 96M -11 3 128M -11 4 160M -11 5 192M -11 6 224M -12 0 Integrated Only -12 1 Discrete Only -12 2 Dual Graphics -13 0 Disable -13 1 AC and battery -13 2 AC only -14 0 Normal -14 1 Disabled - -# ----------------------------------------------------------------- -checksums - -checksum 392 447 984 diff --git a/src/mainboard/lenovo/t430/devicetree.cb b/src/mainboard/lenovo/t430/devicetree.cb deleted file mode 100644 index 02a4c853441..00000000000 --- a/src/mainboard/lenovo/t430/devicetree.cb +++ /dev/null @@ -1,166 +0,0 @@ -chip northbridge/intel/sandybridge - register "gfx" = "GMA_STATIC_DISPLAYS(1)" - - # Enable DisplayPort Hotplug with 6ms pulse - register "gpu_dp_d_hotplug" = "0x06" - - # Enable Panel as LVDS and configure power delays - register "gpu_panel_port_select" = "PANEL_PORT_LVDS" - register "gpu_panel_power_cycle_delay" = "6" # T7: 500ms - register "gpu_panel_power_up_delay" = "100" # T1+T2: 10ms - register "gpu_panel_power_down_delay" = "100" # T5+T6: 10ms - register "gpu_panel_power_backlight_on_delay" = "2100" # T3: 210ms - register "gpu_panel_power_backlight_off_delay" = "2100" # T4: 210ms - register "gpu_cpu_backlight" = "0x1155" - register "gpu_pch_backlight" = "0x11551155" - - register "spd_addresses" = "{0x50, 0, 0x51, 0}" - - device domain 0 on - subsystemid 0x17aa 0x21f3 inherit - - chip southbridge/intel/bd82x6x # Intel Series 6 Cougar Point PCH - register "docking_supported" = "true" - register "gen1_dec" = "0x000c15e1" - register "gen2_dec" = "0x007c1601" - register "gen3_dec" = "0x000c06a1" - register "gpi13_routing" = "2" - register "gpi1_routing" = "2" - register "pcie_hotplug_map" = "{ 0, 0, 1, 0, 0, 0, 0, 0 }" - register "pcie_port_coalesce" = "true" - register "sata_interface_speed_support" = "0x3" - register "sata_port_map" = "0x17" - - # Do not enable xHCI Port 4 since WWAN USB is EHCI-only - register "superspeed_capable_ports" = "0x7" - register "xhci_switchable_ports" = "0x7" - register "usb_port_config" = "{ - { 1, 1, 0 }, - { 1, 1, 1 }, - { 1, 2, 3 }, - { 1, 1, -1 }, - { 1, 1, 2 }, - { 1, 0, -1 }, - { 0, 0, -1 }, - { 1, 2, -1 }, - { 1, 0, -1 }, - { 1, 1, 5 }, - { 1, 0, -1 }, - { 1, 0, -1 }, - { 1, 3, -1 }, - { 1, 1, -1 } - }" - - # device specific SPI configuration - register "spi_uvscc" = "0x2005" - register "spi_lvscc" = "0x2005" - - device ref xhci on end # USB 3.0 Controller - device ref mei1 on end # Management Engine Interface 1 - device ref mei2 off end # Management Engine Interface 2 - device ref me_ide_r off end # Management Engine IDE-R - device ref me_kt off end # Management Engine KT - device ref gbe on end # Intel Gigabit Ethernet - device ref ehci2 on end # USB2 EHCI #2 - device ref hda on end # High Definition Audio controller - device ref pcie_rp1 on # PCIe Port #1 - chip drivers/ricoh/rce822 # Ricoh cardreader - register "disable_mask" = "0x87" - register "sdwppol" = "1" - device pci 00.0 on end # Ricoh SD card reader - end - end - device ref pcie_rp2 on end # PCIe Port #2 - device ref pcie_rp3 on # PCIe Port #3 - smbios_slot_desc "7" "3" "ExpressCard Slot" "8" - end - device ref pcie_rp4 off end # PCIe Port #4 - device ref pcie_rp5 off end # PCIe Port #5 - device ref pcie_rp6 off end # PCIe Port #6 - device ref pcie_rp7 off end # PCIe Port #7 - device ref pcie_rp8 off end # PCIe Port #8 - device ref ehci1 on end # USB2 EHCI #1 - device ref pci_bridge off end # PCI bridge - device ref lpc on # LPC bridge PCI-LPC bridge - chip ec/lenovo/pmh7 - register "backlight_enable" = "true" - register "dock_event_enable" = "true" - device pnp ff.1 on end # dummy - end - chip ec/lenovo/h8 - device pnp ff.2 on # dummy - io 0x60 = 0x62 - io 0x62 = 0x66 - io 0x64 = 0x1600 - io 0x66 = 0x1604 - end - register "config0" = "0xa7" - register "config1" = "0x01" - register "config2" = "0xa0" - register "config3" = "0xe2" - - register "has_keyboard_backlight" = "0" - - register "beepmask0" = "0x02" - register "beepmask1" = "0x86" - register "has_power_management_beeps" = "1" - register "event2_enable" = "0xff" - register "event3_enable" = "0xff" - register "event4_enable" = "0xf0" - register "event5_enable" = "0x3c" - register "event6_enable" = "0x00" - register "event7_enable" = "0xa1" - register "event8_enable" = "0x7b" - register "event9_enable" = "0xff" - register "eventa_enable" = "0x00" - register "eventb_enable" = "0x00" - register "eventc_enable" = "0xff" - register "eventd_enable" = "0xff" - register "evente_enable" = "0x0d" - - register "bdc_gpio_num" = "54" - register "bdc_gpio_lvl" = "0" - - register "wwan_gpio_num" = "70" - register "wwan_gpio_lvl" = "0" - end - chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy - - register "detect_gpio" = "21" - - register "has_panel_hybrid_gpio" = "true" - register "panel_hybrid_gpio" = "52" - register "panel_integrated_lvl" = "true" - - register "has_backlight_gpio" = "false" - register "has_dgpu_power_gpio" = "false" - - register "has_thinker1" = "true" - end - chip drivers/pc80/tpm - device pnp 0c31.0 on end - end - end - device ref sata1 on end # SATA Controller 1 - device ref smbus on # SMBus - chip drivers/i2c/at24rf08c # eeprom, 8 virtual devices, same chip - device i2c 54 on end - device i2c 55 on end - device i2c 56 on end - device i2c 57 on end - device i2c 5c on end - device i2c 5d on end - device i2c 5e on end - device i2c 5f on end - end - end - device ref sata2 off end # SATA Controller 2 - device ref thermal off end # Thermal - end - device ref host_bridge on end # Host bridge Host bridge - device ref peg10 on end # PCIe Bridge for discrete graphics - device ref igd on end # Internal graphics VGA controller - device ref dev4 off end # Signal processing controller - end -end diff --git a/src/mainboard/lenovo/t430/dsdt.asl b/src/mainboard/lenovo/t430/dsdt.asl deleted file mode 100644 index 795f9a1ee91..00000000000 --- a/src/mainboard/lenovo/t430/dsdt.asl +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#define THINKPAD_EC_GPE 17 -#define BRIGHTNESS_UP \_SB.PCI0.GFX0.INCB -#define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.DECB - -#include -DefinitionBlock( - "dsdt.aml", - "DSDT", - ACPI_DSDT_REV_2, - OEM_ID, - ACPI_TABLE_CREATOR, - 0x20141018 // OEM revision -) -{ - #include - #include "acpi/platform.asl" - #include - #include - /* global NVS and variables. */ - #include - #include - - Scope (\_SB) { - Device (PCI0) - { - #include - #include - #include - } - } - #include -} diff --git a/src/mainboard/lenovo/t430/early_init.c b/src/mainboard/lenovo/t430/early_init.c deleted file mode 100644 index 8306e0e7202..00000000000 --- a/src/mainboard/lenovo/t430/early_init.c +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include - -static void hybrid_graphics_init(void) -{ - bool peg, igd; - u32 reg32; - - early_hybrid_graphics(&igd, &peg); - - if (peg && igd) - return; - - /* Hide disabled devices */ - reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN); - reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD); - - if (peg) - reg32 |= DEVEN_PEG10; - - if (igd) - reg32 |= DEVEN_IGD; - else - /* Disable IGD VGA decode, no GTT or GFX stolen */ - pci_write_config16(PCI_DEV(0, 0, 0), GGC, 2); - - pci_write_config32(PCI_DEV(0, 0, 0), DEVEN, reg32); -} - -void mainboard_early_init(bool s3resume) -{ - hybrid_graphics_init(); -} diff --git a/src/mainboard/lenovo/t430/gma-mainboard.ads b/src/mainboard/lenovo/t430/gma-mainboard.ads deleted file mode 100644 index 3df1e37f3e5..00000000000 --- a/src/mainboard/lenovo/t430/gma-mainboard.ads +++ /dev/null @@ -1,22 +0,0 @@ --- SPDX-License-Identifier: GPL-2.0-or-later - -with HW.GFX.GMA; -with HW.GFX.GMA.Display_Probing; - -use HW.GFX.GMA; -use HW.GFX.GMA.Display_Probing; - -private package GMA.Mainboard is - - ports : constant Port_List := - (DP1, - DP2, - DP3, - HDMI1, - HDMI2, - HDMI3, - Analog, - LVDS, - others => Disabled); - -end GMA.Mainboard; diff --git a/src/mainboard/lenovo/t430/mainboard.c b/src/mainboard/lenovo/t430/mainboard.c deleted file mode 100644 index 50c944e341d..00000000000 --- a/src/mainboard/lenovo/t430/mainboard.c +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -static void mainboard_enable(struct device *dev) -{ - install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_INT_LVDS, - GMA_INT15_PANEL_FIT_DEFAULT, - GMA_INT15_BOOT_DISPLAY_DEFAULT, 0); -} - -struct chip_operations mainboard_ops = { - .enable_dev = mainboard_enable, -}; diff --git a/src/mainboard/lenovo/t430/smihandler.c b/src/mainboard/lenovo/t430/smihandler.c deleted file mode 100644 index 81cbc487f6a..00000000000 --- a/src/mainboard/lenovo/t430/smihandler.c +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include - -#define GPE_EC_SCI 1 -#define GPE_EC_WAKE 13 - -static void mainboard_smi_handle_ec_sci(void) -{ - u8 status = inb(EC_SC); - u8 event; - - if (!(status & EC_SCI_EVT)) - return; - - event = ec_query(); - printk(BIOS_DEBUG, "EC event %#02x\n", event); -} - -void mainboard_smi_gpi(u32 gpi_sts) -{ - if (gpi_sts & (1 << GPE_EC_SCI)) - mainboard_smi_handle_ec_sci(); -} - -int mainboard_smi_apmc(u8 data) -{ - switch (data) { - case APM_CNT_ACPI_ENABLE: - /* use 0x1600/0x1604 to prevent races with userspace */ - ec_set_ports(0x1604, 0x1600); - /* route EC_SCI to SCI */ - gpi_route_interrupt(GPE_EC_SCI, GPI_IS_SCI); - /* discard all events, and enable attention */ - ec_write(0x80, 0x01); - break; - case APM_CNT_ACPI_DISABLE: - /* we have to use port 0x62/0x66, as 0x1600/0x1604 doesn't - provide a EC query function */ - ec_set_ports(0x66, 0x62); - /* route EC_SCI to SMI */ - gpi_route_interrupt(GPE_EC_SCI, GPI_IS_SMI); - /* discard all events, and enable attention */ - ec_write(0x80, 0x01); - break; - default: - break; - } - return 0; -} - -void mainboard_smi_sleep(u8 slp_typ) -{ - if (slp_typ == 3) { - u8 ec_wake = ec_read(0x32); - /* If EC wake events are enabled, enable wake on EC WAKE GPE. */ - if (ec_wake & 0x14) { - /* Redirect EC WAKE GPE to SCI. */ - gpi_route_interrupt(GPE_EC_WAKE, GPI_IS_SCI); - } - } -} diff --git a/src/mainboard/lenovo/t430/vboot-ro-me_clean.fmd b/src/mainboard/lenovo/t430/vboot-ro-me_clean.fmd deleted file mode 100644 index 5101caa59ce..00000000000 --- a/src/mainboard/lenovo/t430/vboot-ro-me_clean.fmd +++ /dev/null @@ -1,21 +0,0 @@ -FLASH 0xc00000 { - SI_ALL 0x20000 { - SI_DESC 0x1000 - SI_GBE 0x2000 - SI_ME - } - SI_BIOS 0xbe0000 { - UNIFIED_MRC_CACHE 0x20000 { - RECOVERY_MRC_CACHE 0x10000 - RW_MRC_CACHE 0x10000 - } - - WP_RO { - FMAP 0x800 - RO_FRID 0x40 - RO_PADDING 0x7c0 - GBB 0x1e000 - COREBOOT(CBFS) - } - } -} diff --git a/src/mainboard/lenovo/t430/vboot-ro.fmd b/src/mainboard/lenovo/t430/vboot-ro.fmd deleted file mode 100644 index 027849bfe99..00000000000 --- a/src/mainboard/lenovo/t430/vboot-ro.fmd +++ /dev/null @@ -1,21 +0,0 @@ -FLASH 0xc00000 { - SI_ALL 0x500000 { - SI_DESC 0x1000 - SI_GBE 0x2000 - SI_ME - } - SI_BIOS 0x700000 { - UNIFIED_MRC_CACHE 0x20000 { - RECOVERY_MRC_CACHE 0x10000 - RW_MRC_CACHE 0x10000 - } - - WP_RO { - FMAP 0x800 - RO_FRID 0x40 - RO_PADDING 0x7c0 - GBB 0x1e000 - COREBOOT(CBFS) - } - } -} diff --git a/src/mainboard/lenovo/t430/vboot-rwab.fmd b/src/mainboard/lenovo/t430/vboot-rwab.fmd deleted file mode 100644 index 8819959dfea..00000000000 --- a/src/mainboard/lenovo/t430/vboot-rwab.fmd +++ /dev/null @@ -1,35 +0,0 @@ -FLASH 0xc00000 { - SI_ALL@0x0 0x500000 { - SI_DESC@0x0 0x1000 - SI_GBE@0x1000 0x2000 - SI_ME - } - SI_BIOS@0x500000 0x700000 { - RW_SECTION_A 0x280000 { - VBLOCK_A 0x10000 - FW_MAIN_A(CBFS) - RW_FWID_A 0x40 - } - RW_SECTION_B 0x280000 { - VBLOCK_B 0x10000 - FW_MAIN_B(CBFS) - RW_FWID_B 0x40 - } - UNIFIED_MRC_CACHE@0x500000 0x20000 { - RECOVERY_MRC_CACHE@0x0 0x10000 - RW_MRC_CACHE@0x10000 0x10000 - } - RW_VPD(PRESERVE) 0x1000 - SMMSTORE(PRESERVE)@0x521000 0x40000 - RW_NVRAM(PRESERVE)@0x561000 0x2000 - - WP_RO { - FMAP 0x800 - RO_FRID 0x40 - RO_PADDING 0x7c0 - RO_VPD(PRESERVE) 0x1000 - GBB 0x1e000 - COREBOOT(CBFS) - } - } -} diff --git a/src/mainboard/lenovo/t430s/Kconfig b/src/mainboard/lenovo/t430s/Kconfig index 10ce88c6f1b..c7c0ffb3476 100644 --- a/src/mainboard/lenovo/t430s/Kconfig +++ b/src/mainboard/lenovo/t430s/Kconfig @@ -29,6 +29,7 @@ config BOARD_SPECIFIC_OPTIONS select MAINBOARD_USES_IFD_GBE_REGION select DRIVERS_RICOH_RCE822 if BOARD_LENOVO_T431S select DRIVER_LENOVO_SERIALS + select DRIVER_LENOVO_SERIALS_EARLY_LOCK select HAVE_SPD_IN_CBFS if BOARD_LENOVO_T431S # Workaround for EC/KBC IRQ1. @@ -45,6 +46,9 @@ config VBOOT config VBOOT_SLOTS_RW_AB default y +config CBFS_SIZE + default 0xB00000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT diff --git a/src/mainboard/lenovo/t430s/acpi/ec.asl b/src/mainboard/lenovo/t430s/acpi/ec.asl index 7971d027b24..987593e919a 100644 --- a/src/mainboard/lenovo/t430s/acpi/ec.asl +++ b/src/mainboard/lenovo/t430s/acpi/ec.asl @@ -1,9 +1,4 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include - -Scope(\_SB.PCI0.LPCB.EC) -{ -} - #include diff --git a/src/mainboard/lenovo/t430s/variants/t430s/romstage.c b/src/mainboard/lenovo/t430s/variants/t430s/romstage.c index 211ec2d345f..c658a34a4dd 100644 --- a/src/mainboard/lenovo/t430s/variants/t430s/romstage.c +++ b/src/mainboard/lenovo/t430s/variants/t430s/romstage.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -20,4 +21,6 @@ void mainboard_early_init(bool s3resume) // Hide disabled dGPU device pci_and_config32(HOST_BRIDGE, DEVEN, ~DEVEN_PEG10); } + + lenovo_mainboard_eeprom_lock(); } diff --git a/src/mainboard/lenovo/t430s/variants/t431s/romstage.c b/src/mainboard/lenovo/t430s/variants/t431s/romstage.c index 9a78bac8139..e1e5029e7c4 100644 --- a/src/mainboard/lenovo/t430s/variants/t431s/romstage.c +++ b/src/mainboard/lenovo/t430s/variants/t431s/romstage.c @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include +#include void mb_get_spd_map(struct spd_info *spdi) { @@ -9,3 +11,8 @@ void mb_get_spd_map(struct spd_info *spdi) spdi->addresses[2] = 0x51; spdi->spd_index = 0; } + +void mainboard_early_init(bool s3resume) +{ + lenovo_mainboard_eeprom_lock(); +} diff --git a/src/mainboard/lenovo/t520/Kconfig b/src/mainboard/lenovo/t520/Kconfig index a93c8596156..cef7750a40a 100644 --- a/src/mainboard/lenovo/t520/Kconfig +++ b/src/mainboard/lenovo/t520/Kconfig @@ -27,6 +27,7 @@ config BOARD_LENOVO_BASEBOARD_T520 select INTEL_GMA_HAVE_VBT if BOARD_LENOVO_T520 select MAINBOARD_USES_IFD_GBE_REGION select DRIVER_LENOVO_SERIALS + select DRIVER_LENOVO_SERIALS_EARLY_LOCK # Workaround for EC/KBC IRQ1. select SERIRQ_CONTINUOUS_MODE @@ -60,6 +61,9 @@ config MAINBOARD_DIR config OVERRIDE_DEVICETREE default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" +config CBFS_SIZE + default 0x300000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT diff --git a/src/mainboard/lenovo/t520/acpi/ec.asl b/src/mainboard/lenovo/t520/acpi/ec.asl index 7971d027b24..987593e919a 100644 --- a/src/mainboard/lenovo/t520/acpi/ec.asl +++ b/src/mainboard/lenovo/t520/acpi/ec.asl @@ -1,9 +1,4 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include - -Scope(\_SB.PCI0.LPCB.EC) -{ -} - #include diff --git a/src/mainboard/lenovo/t520/devicetree.cb b/src/mainboard/lenovo/t520/devicetree.cb index 74605ca081e..9456f85bd4a 100644 --- a/src/mainboard/lenovo/t520/devicetree.cb +++ b/src/mainboard/lenovo/t520/devicetree.cb @@ -141,7 +141,7 @@ chip northbridge/intel/sandybridge register "bdc_gpio_lvl" = "0" end chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy + device generic 0 alias hg_mux on end # dummy register "detect_gpio" = "21" diff --git a/src/mainboard/lenovo/t520/early_init.c b/src/mainboard/lenovo/t520/early_init.c index ba98ec700f2..198d603ff75 100644 --- a/src/mainboard/lenovo/t520/early_init.c +++ b/src/mainboard/lenovo/t520/early_init.c @@ -1,12 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include +#include +#include #include #include -#include -#include static void hybrid_graphics_init(void) { @@ -37,4 +38,5 @@ static void hybrid_graphics_init(void) void mainboard_early_init(bool s3resume) { hybrid_graphics_init(); + lenovo_mainboard_eeprom_lock(); } diff --git a/src/mainboard/lenovo/t530/Kconfig b/src/mainboard/lenovo/t530/Kconfig index 801e931fbd5..4f0002f5364 100644 --- a/src/mainboard/lenovo/t530/Kconfig +++ b/src/mainboard/lenovo/t530/Kconfig @@ -6,6 +6,7 @@ config BOARD_LENOVO_BASEBOARD_T530 select BOARD_ROMSIZE_KB_12288 select DRIVERS_LENOVO_HYBRID_GRAPHICS select DRIVER_LENOVO_SERIALS + select DRIVER_LENOVO_SERIALS_EARLY_LOCK select EC_LENOVO_H8 select EC_LENOVO_PMH7 select GFX_GMA_PANEL_1_ON_LVDS @@ -37,6 +38,10 @@ config BOARD_LENOVO_W530 select BOARD_LENOVO_BASEBOARD_T530 select DRIVERS_RICOH_RCE822 +config BOARD_LENOVO_T430 + select BOARD_LENOVO_BASEBOARD_T530 + select DRIVERS_RICOH_RCE822 + if BOARD_LENOVO_BASEBOARD_T530 config VBOOT @@ -50,12 +55,16 @@ config VBOOT config VBOOT_SLOTS_RW_AB default y +config CBFS_SIZE + default 0x700000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT config VARIANT_DIR default "t530" if BOARD_LENOVO_T530 default "w530" if BOARD_LENOVO_W530 + default "t430" if BOARD_LENOVO_T430 config MAINBOARD_DIR default "lenovo/t530" @@ -66,6 +75,7 @@ config OVERRIDE_DEVICETREE config MAINBOARD_PART_NUMBER default "ThinkPad T530" if BOARD_LENOVO_T530 default "ThinkPad W530" if BOARD_LENOVO_W530 + default "ThinkPad T430" if BOARD_LENOVO_T430 config USBDEBUG_HCD_INDEX int @@ -80,6 +90,7 @@ config VGA_BIOS_ID default "8086,0166" config PS2K_EISAID + default "PNP0303" if BOARD_LENOVO_T430 default "LEN0071" config PS2M_EISAID diff --git a/src/mainboard/lenovo/t530/Kconfig.name b/src/mainboard/lenovo/t530/Kconfig.name index d8b1925f656..5b42bd2f89f 100644 --- a/src/mainboard/lenovo/t530/Kconfig.name +++ b/src/mainboard/lenovo/t530/Kconfig.name @@ -5,3 +5,6 @@ config BOARD_LENOVO_T530 config BOARD_LENOVO_W530 bool "ThinkPad W530" + +config BOARD_LENOVO_T430 + bool "ThinkPad T430" diff --git a/src/mainboard/lenovo/t530/Makefile.mk b/src/mainboard/lenovo/t530/Makefile.mk index 69ef08873b6..1c72bfe0459 100644 --- a/src/mainboard/lenovo/t530/Makefile.mk +++ b/src/mainboard/lenovo/t530/Makefile.mk @@ -5,3 +5,4 @@ romstage-y += variants/$(VARIANT_DIR)/gpio.c ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads bootblock-y += early_init.c romstage-y += early_init.c +ramstage-y += variants/$(VARIANT_DIR)/hda_verb.c diff --git a/src/mainboard/lenovo/t530/acpi/ec.asl b/src/mainboard/lenovo/t530/acpi/ec.asl index 7971d027b24..987593e919a 100644 --- a/src/mainboard/lenovo/t530/acpi/ec.asl +++ b/src/mainboard/lenovo/t530/acpi/ec.asl @@ -1,9 +1,4 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include - -Scope(\_SB.PCI0.LPCB.EC) -{ -} - #include diff --git a/src/mainboard/lenovo/t530/devicetree.cb b/src/mainboard/lenovo/t530/devicetree.cb index 13c40d91d43..3ca79999f17 100644 --- a/src/mainboard/lenovo/t530/devicetree.cb +++ b/src/mainboard/lenovo/t530/devicetree.cb @@ -35,9 +35,9 @@ chip northbridge/intel/sandybridge # Set max SATA speed to 6.0 Gb/s register "sata_interface_speed_support" = "0x3" - register "gen1_dec" = "0x7c1601" - register "gen2_dec" = "0x0c15e1" - register "gen4_dec" = "0x0c06a1" + register "gen1_dec" = "0x00c15e1" + register "gen2_dec" = "0x07c1601" + register "gen3_dec" = "0x00c06a1" # Enable zero-based linear PCIe root port functions register "pcie_port_coalesce" = "true" @@ -121,7 +121,7 @@ chip northbridge/intel/sandybridge register "bdc_gpio_lvl" = "0" end chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy + device generic 0 alias hg_mux on end # dummy register "detect_gpio" = "21" diff --git a/src/mainboard/lenovo/t530/early_init.c b/src/mainboard/lenovo/t530/early_init.c index 429ab2857a8..d9826608563 100644 --- a/src/mainboard/lenovo/t530/early_init.c +++ b/src/mainboard/lenovo/t530/early_init.c @@ -1,11 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include #include #include -#include +#include +#include #include -#include +#include static void hybrid_graphics_init(void) { @@ -36,4 +36,5 @@ static void hybrid_graphics_init(void) void mainboard_early_init(bool s3resume) { hybrid_graphics_init(); + lenovo_mainboard_eeprom_lock(); } diff --git a/src/mainboard/lenovo/t430/data.vbt b/src/mainboard/lenovo/t530/variants/t430/data.vbt similarity index 100% rename from src/mainboard/lenovo/t430/data.vbt rename to src/mainboard/lenovo/t530/variants/t430/data.vbt diff --git a/src/mainboard/lenovo/t430/gpio.c b/src/mainboard/lenovo/t530/variants/t430/gpio.c similarity index 100% rename from src/mainboard/lenovo/t430/gpio.c rename to src/mainboard/lenovo/t530/variants/t430/gpio.c diff --git a/src/mainboard/lenovo/t430/hda_verb.c b/src/mainboard/lenovo/t530/variants/t430/hda_verb.c similarity index 100% rename from src/mainboard/lenovo/t430/hda_verb.c rename to src/mainboard/lenovo/t530/variants/t430/hda_verb.c diff --git a/src/mainboard/lenovo/t530/variants/t430/overridetree.cb b/src/mainboard/lenovo/t530/variants/t430/overridetree.cb new file mode 100644 index 00000000000..72cc6b54e15 --- /dev/null +++ b/src/mainboard/lenovo/t530/variants/t430/overridetree.cb @@ -0,0 +1,58 @@ +chip northbridge/intel/sandybridge + register "gpu_panel_power_backlight_on_delay" = "2100" # T3: 210ms + register "gpu_panel_power_backlight_off_delay" = "2100" # T4: 210ms + + register "spd_addresses" = "{0x50, 0, 0x51, 0}" + device domain 0 on + subsystemid 0x17aa 0x21f3 inherit + chip southbridge/intel/bd82x6x # Intel Series 7 Panther Point PCH + register "sata_interface_speed_support" = "0x3" + register "sata_port_map" = "0x17" + + # Do not enable xHCI Port 4 since WWAN USB is EHCI-only + register "superspeed_capable_ports" = "0x7" + register "xhci_switchable_ports" = "0x7" + register "usb_port_config" = "{ + { 1, 1, 0 }, + { 1, 1, 1 }, + { 1, 2, 3 }, + { 1, 1, -1 }, + { 1, 1, 2 }, + { 1, 0, -1 }, + { 0, 0, -1 }, + { 1, 2, -1 }, + { 1, 0, -1 }, + { 1, 1, 5 }, + { 1, 0, -1 }, + { 1, 0, -1 }, + { 1, 3, -1 }, + { 1, 1, -1 } + }" + + device ref pcie_rp1 on # PCIe Port #1 + chip drivers/ricoh/rce822 # Ricoh cardreader + register "disable_mask" = "0x87" + register "sdwppol" = "1" + device pci 00.0 on end # Ricoh SD card reader + end + end + device ref lpc on + chip ec/lenovo/h8 + device pnp ff.2 on end # dummy + register "wwan_gpio_num" = "70" + register "wwan_gpio_lvl" = "0" + register "config1" = "0x01" + register "config3" = "0xe2" + register "has_keyboard_backlight" = "0" + register "beepmask0" = "0x02" + register "has_power_management_beeps" = "1" + register "event4_enable" = "0xf0" + register "event5_enable" = "0x3c" + register "event7_enable" = "0xa1" + register "eventa_enable" = "0x00" + end + end + device ref thermal off end # Thermal + end + end +end diff --git a/src/mainboard/lenovo/t530/hda_verb.c b/src/mainboard/lenovo/t530/variants/t530/hda_verb.c similarity index 100% rename from src/mainboard/lenovo/t530/hda_verb.c rename to src/mainboard/lenovo/t530/variants/t530/hda_verb.c diff --git a/src/mainboard/lenovo/t530/variants/w530/hda_verb.c b/src/mainboard/lenovo/t530/variants/w530/hda_verb.c new file mode 100644 index 00000000000..564aff2d778 --- /dev/null +++ b/src/mainboard/lenovo/t530/variants/w530/hda_verb.c @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* Bits 31:28 - Codec Address */ +/* Bits 27:20 - NID */ +/* Bits 19:8 - Verb ID */ +/* Bits 7:0 - Payload */ + +#include + +const u32 cim_verb_data[] = { + 0x10ec0269, /* Codec Vendor / Device ID: Realtek ALC269VC */ + 0x17aa21fa, /* Subsystem ID */ + 18, /* Number of 4 dword sets */ + AZALIA_SUBVENDOR(0, 0x17aa21fa), + + /* Ext. Microphone Connector: External,Right; MicIn,3.5mm; Black,JD; DA,Seq */ + AZALIA_PIN_CFG(0, 0x0a, 0x04a11020), + + /* Headphones Connector: External,Right; HP,3.5mm; Black,JD; DA,Seq */ + AZALIA_PIN_CFG(0, 0x0b, 0x0421101f), + + /* Not connected: N/A,N/A; Other,Unknown; Unknown,JD; DA,Seq */ + AZALIA_PIN_CFG(0, 0x0c, 0x40f000f0), + + /* Internal Speakers Fixed,Int; Speaker,Other Analog; Unknown,nJD; DA,Seq */ + AZALIA_PIN_CFG(0, 0x0d, 0x90170110), + + /* Not connected */ + AZALIA_PIN_CFG(0, 0x0f, 0x40f000f0), + + /* Internal Microphone: Fixed,Int,Top; Mic In,ATIPI; Unknown,nJD; DA,Seq */ + AZALIA_PIN_CFG(0, 0x11, 0xd5a30140), + AZALIA_PIN_CFG(0, 0x12, 0x90a60140), + AZALIA_PIN_CFG(0, 0x14, 0x90170110), + AZALIA_PIN_CFG(0, 0x15, 0x03211020), + AZALIA_PIN_CFG(0, 0x18, 0x03a11830), + AZALIA_PIN_CFG(0, 0x19, AZALIA_PIN_CFG_NC(0)), + + 0x01970804, + 0x01870803, + 0x01470740, + 0x00970600, + + AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x1d, 0x40138205), + AZALIA_PIN_CFG(0, 0x1e, AZALIA_PIN_CFG_NC(0)), + + /* Misc entries */ + 0x00370600, + 0x00270600, + 0x00b707C0, /* Enable PortB as Output with HP amp */ + 0x00d70740, /* Enable PortD as Output */ + 0x0017a200, /* Disable ClkEn of PortSenseTst */ + 0x0017c621, /* Slave Port - Port A used as microphone input for + combo Jack + Master Port - Port B used for Jack Presence Detect + Enable Combo Jack Detection */ + 0x0017a208, /* Enable ClkEn of PortSenseTst */ + 0x00170500, /* Set power state to D0 */ + + /* --- Codec #3 --- */ + 0x80862806, /* Codec Vendor / Device ID: Intel PantherPoint HDMI */ + 0x80860101, /* Subsystem ID */ + 4, /* Number of 4 dword sets */ + AZALIA_SUBVENDOR(3, 0x80860101), + AZALIA_PIN_CFG(3, 0x05, 0x18560010), + AZALIA_PIN_CFG(3, 0x06, 0x18560020), + AZALIA_PIN_CFG(3, 0x07, 0x18560030), +}; + +const u32 pc_beep_verbs[] = { + 0x02177a00, /* Digital PCBEEP Gain: 0h=-9db, 1h=-6db ... 4h=+3db, 5h=+6db */ +}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/lenovo/x131e/Kconfig b/src/mainboard/lenovo/x131e/Kconfig index df435e9cfb8..3c6d4531001 100644 --- a/src/mainboard/lenovo/x131e/Kconfig +++ b/src/mainboard/lenovo/x131e/Kconfig @@ -7,6 +7,7 @@ config BOARD_SPECIFIC_OPTIONS select AZALIA_USE_LEGACY_VERB_TABLE select BOARD_ROMSIZE_KB_12288 select DRIVER_LENOVO_SERIALS + select DRIVER_LENOVO_SERIALS_EARLY_LOCK select EC_LENOVO_H8 select GFX_GMA_PANEL_1_ON_LVDS select HAVE_ACPI_RESUME @@ -36,6 +37,9 @@ config VBOOT config VBOOT_SLOTS_RW_AB default y +config CBFS_SIZE + default 0x700000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT diff --git a/src/mainboard/lenovo/x131e/Makefile.mk b/src/mainboard/lenovo/x131e/Makefile.mk index 76111943390..2afc15156dd 100644 --- a/src/mainboard/lenovo/x131e/Makefile.mk +++ b/src/mainboard/lenovo/x131e/Makefile.mk @@ -2,5 +2,6 @@ bootblock-y += gpio.c romstage-y += gpio.c +romstage-y += early_init.c ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads diff --git a/src/mainboard/lenovo/x131e/early_init.c b/src/mainboard/lenovo/x131e/early_init.c new file mode 100644 index 00000000000..7d36c4b990f --- /dev/null +++ b/src/mainboard/lenovo/x131e/early_init.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +void mainboard_early_init(bool s3resume) +{ + lenovo_mainboard_eeprom_lock(); +} diff --git a/src/mainboard/lenovo/x1_carbon_gen1/Kconfig b/src/mainboard/lenovo/x1_carbon_gen1/Kconfig index 902b92d5d38..84b8fedaa42 100644 --- a/src/mainboard/lenovo/x1_carbon_gen1/Kconfig +++ b/src/mainboard/lenovo/x1_carbon_gen1/Kconfig @@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_12288 select DRIVERS_RICOH_RCE822 select DRIVER_LENOVO_SERIALS + select DRIVER_LENOVO_SERIALS_EARLY_LOCK select EC_LENOVO_H8 select EC_LENOVO_PMH7 select GFX_GMA_PANEL_1_ON_LVDS @@ -43,6 +44,9 @@ config VBOOT config VBOOT_SLOTS_RW_AB default y +config CBFS_SIZE + default 0x700000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT diff --git a/src/mainboard/lenovo/x1_carbon_gen1/acpi/ec.asl b/src/mainboard/lenovo/x1_carbon_gen1/acpi/ec.asl index 7971d027b24..987593e919a 100644 --- a/src/mainboard/lenovo/x1_carbon_gen1/acpi/ec.asl +++ b/src/mainboard/lenovo/x1_carbon_gen1/acpi/ec.asl @@ -1,9 +1,4 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include - -Scope(\_SB.PCI0.LPCB.EC) -{ -} - #include diff --git a/src/mainboard/lenovo/x1_carbon_gen1/early_init.c b/src/mainboard/lenovo/x1_carbon_gen1/early_init.c index 7cfc5d9a0e4..880635280e4 100644 --- a/src/mainboard/lenovo/x1_carbon_gen1/early_init.c +++ b/src/mainboard/lenovo/x1_carbon_gen1/early_init.c @@ -1,8 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include +#include static unsigned int get_spd_index(void) { @@ -40,3 +42,8 @@ void mb_get_spd_map(struct spd_info *spdi) spdi->addresses[2] = SPD_MEMORY_DOWN; spdi->spd_index = get_spd_index(); } + +void mainboard_early_init(bool s3resume) +{ + lenovo_mainboard_eeprom_lock(); +} diff --git a/src/mainboard/lenovo/x201/acpi/ec.asl b/src/mainboard/lenovo/x201/acpi/ec.asl index 1ce63054f87..6d2e71f8c00 100644 --- a/src/mainboard/lenovo/x201/acpi/ec.asl +++ b/src/mainboard/lenovo/x201/acpi/ec.asl @@ -5,10 +5,5 @@ Name(\TPSV, 90) Name(\FLVL, 0) #include - -Scope(\_SB.PCI0.LPCB.EC) -{ -} - #define H8_BAT_THRESHOLDS_BIT7 #include diff --git a/src/mainboard/lenovo/x220/Kconfig b/src/mainboard/lenovo/x220/Kconfig index 453afd4bef9..1fe5566ab43 100644 --- a/src/mainboard/lenovo/x220/Kconfig +++ b/src/mainboard/lenovo/x220/Kconfig @@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_8192 select DRIVERS_RICOH_RCE822 select DRIVER_LENOVO_SERIALS + select DRIVER_LENOVO_SERIALS_EARLY_LOCK select EC_LENOVO_H8 select EC_LENOVO_PMH7 select GFX_GMA_PANEL_1_ON_LVDS @@ -29,7 +30,7 @@ config BOARD_SPECIFIC_OPTIONS select SERIRQ_CONTINUOUS_MODE select SOUTHBRIDGE_INTEL_C216 select SYSTEM_TYPE_LAPTOP - + select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE config VBOOT select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC @@ -49,6 +50,9 @@ config VARIANT_DIR default "x220" if BOARD_LENOVO_X220 || BOARD_LENOVO_X220I default "x1" if BOARD_LENOVO_X1 +config CBFS_SIZE + default 0x300000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT diff --git a/src/mainboard/lenovo/x220/acpi/ec.asl b/src/mainboard/lenovo/x220/acpi/ec.asl index 7971d027b24..987593e919a 100644 --- a/src/mainboard/lenovo/x220/acpi/ec.asl +++ b/src/mainboard/lenovo/x220/acpi/ec.asl @@ -1,9 +1,4 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include - -Scope(\_SB.PCI0.LPCB.EC) -{ -} - #include diff --git a/src/mainboard/lenovo/x220/cfr.c b/src/mainboard/lenovo/x220/cfr.c index 6d43c178563..e37464a07af 100644 --- a/src/mainboard/lenovo/x220/cfr.c +++ b/src/mainboard/lenovo/x220/cfr.c @@ -1,4 +1,3 @@ - /* SPDX-License-Identifier: GPL-2.0-only */ #include @@ -8,6 +7,26 @@ #include #include +DEFINE_RP_ENABLE_OPTION(1, "Wi-Fi"); +#if CONFIG(BOARD_LENOVO_X220) +DEFINE_RP_ENABLE_OPTION(3, "ExpressCard"); +#endif +DEFINE_RP_ENABLE_OPTION(4, "SD Card Reader"); +DEFINE_RP_ENABLE_OPTION(6, "xHCI"); + +static struct sm_obj_form pcie = { + .ui_name = "PCH PCIe", + .obj_list = (const struct sm_object *[]) { + &pcie_rp1, +#if CONFIG(BOARD_LENOVO_X220) + &pcie_rp3, +#endif + &pcie_rp4, + &pcie_rp6, + NULL + }, +}; + static struct sm_obj_form ec = { .ui_name = "Embedded Controller", .obj_list = (const struct sm_object *[]) { @@ -49,6 +68,7 @@ static struct sm_obj_form *sm_root[] = { &system, &power, &ec, + &pcie, NULL }; diff --git a/src/mainboard/lenovo/x220/early_init.c b/src/mainboard/lenovo/x220/early_init.c index 826796eddff..492614bdd67 100644 --- a/src/mainboard/lenovo/x220/early_init.c +++ b/src/mainboard/lenovo/x220/early_init.c @@ -2,7 +2,14 @@ #include #include +#include +#include void mainboard_fill_pei_data(struct pei_data *pei_data) { } + +void mainboard_early_init(bool s3resume) +{ + lenovo_mainboard_eeprom_lock(); +} diff --git a/src/mainboard/lenovo/x220/mainboard.c b/src/mainboard/lenovo/x220/mainboard.c index 50c944e341d..92e4b8e12ea 100644 --- a/src/mainboard/lenovo/x220/mainboard.c +++ b/src/mainboard/lenovo/x220/mainboard.c @@ -1,7 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include +#include +#include +#include static void mainboard_enable(struct device *dev) { @@ -10,6 +14,34 @@ static void mainboard_enable(struct device *dev) GMA_INT15_BOOT_DISPLAY_DEFAULT, 0); } +static void mainboard_init(void *chip_info) +{ + char option[20]; + + /* Apply user config and disable ports if option exists and is 0 */ + for (struct device *dev = all_devices; dev; dev = dev->next) { + /* Only care about PCH PCIe root ports */ + if (PCI_SLOT(dev->path.pci.devfn) != + PCH_PCIE_DEV_SLOT) + continue; + /* + * Only care about ports enabled at this point. Ports that are + * disabled here are not implemented on this mainboard. + */ + if (!dev->enabled) + continue; + + const unsigned int idx = PCI_FUNC(dev->path.pci.devfn); + snprintf(option, sizeof(option), "pch_pcie_enable_rp%u", idx); + + /* When option is not found keep current configuration */ + dev->enabled = get_uint_option(option, dev->enabled); + printk(BIOS_DEBUG, "%s: %s %sabled\n", __func__, dev_path(dev), + dev->enabled ? "en" : "dis"); + } +} + struct chip_operations mainboard_ops = { + .init = mainboard_init, .enable_dev = mainboard_enable, }; diff --git a/src/mainboard/lenovo/x220/variants/x220/overridetree.cb b/src/mainboard/lenovo/x220/variants/x220/overridetree.cb index 626f7eb3a67..7aed10d4bf8 100644 --- a/src/mainboard/lenovo/x220/variants/x220/overridetree.cb +++ b/src/mainboard/lenovo/x220/variants/x220/overridetree.cb @@ -2,20 +2,20 @@ chip northbridge/intel/sandybridge device domain 0 on chip southbridge/intel/bd82x6x # Intel Series 6 Cougar Point PCH register "usb_port_config" = "{ - {1, 0, 0 }, - {1, 1, 1 }, - {1, 1, 3 }, - {1, 1, 3 }, - {1, 1, -1}, - {1, 1, -1}, - {1, 0, 2 }, - {1, 0, 2 }, - {1, 1, 6 }, - {1, 1, 5 }, - {1, 1, 6 }, - {1, 1, 6 }, - {1, 1, 7 }, - {1, 1, 6 }, + {1, 0, 0 }, /* P00: System Port (near VGA) */ + {1, 1, 1 }, /* P01: System Port (near ExpressCard) */ + {1, 1, -1 }, /* P02: WLAN */ + {1, 1, -1 }, /* P03: WWAN */ + {0, 0, -1}, /* P04: Reserved */ + {1, 1, -1}, /* P05: ExpressCard */ + {0, 0, -1}, /* P06: Reserved */ + {0, 0, -1 }, /* P07: Reserved */ + {1, 1, -1 }, /* P08: Docking */ + {1, 1, 5 }, /* P09: Always On System Port */ + {1, 1, -1 }, /* P10: FPR */ + {1, 1, -1 }, /* P11: BDC */ + {1, 1, 7 }, /* P12: Docking */ + {1, 1, -1 }, /* P13: Camera */ }" device ref lpc on diff --git a/src/mainboard/lenovo/x230/Kconfig b/src/mainboard/lenovo/x230/Kconfig index 81049412df1..9b35477c5bf 100644 --- a/src/mainboard/lenovo/x230/Kconfig +++ b/src/mainboard/lenovo/x230/Kconfig @@ -24,6 +24,7 @@ config BOARD_SPECIFIC_OPTIONS select INTEL_INT15 select DRIVERS_RICOH_RCE822 select DRIVER_LENOVO_SERIALS + select DRIVER_LENOVO_SERIALS_EARLY_LOCK select MEMORY_MAPPED_TPM select MAINBOARD_HAS_TPM1 if BOARD_LENOVO_X230 || BOARD_LENOVO_X230T || BOARD_LENOVO_X230_EDP select MAINBOARD_HAS_LIBGFXINIT @@ -45,6 +46,10 @@ config VBOOT config VBOOT_SLOTS_RW_AB default y +config CBFS_SIZE + default 0x700000 if BOARD_LENOVO_X230 || BOARD_LENOVO_X230T || BOARD_LENOVO_X230_EDP + default 0xB00000 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/vboot-rwab.fmd" if VBOOT diff --git a/src/mainboard/lenovo/x230/Makefile.mk b/src/mainboard/lenovo/x230/Makefile.mk index 5cbdb7dc1b5..5a4ec5c21ec 100644 --- a/src/mainboard/lenovo/x230/Makefile.mk +++ b/src/mainboard/lenovo/x230/Makefile.mk @@ -4,6 +4,8 @@ bootblock-y += variants/$(VARIANT_DIR)/gpio.c romstage-y += variants/$(VARIANT_DIR)/gpio.c ramstage-y += variants/$(VARIANT_DIR)/hda_verb.c +romstage-y += early_init.c + ifeq ($(CONFIG_BOARD_LENOVO_X230_EDP),y) ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += variants/x230_edp/gma-mainboard.ads else diff --git a/src/mainboard/lenovo/x230/acpi/ec.asl b/src/mainboard/lenovo/x230/acpi/ec.asl index 7971d027b24..987593e919a 100644 --- a/src/mainboard/lenovo/x230/acpi/ec.asl +++ b/src/mainboard/lenovo/x230/acpi/ec.asl @@ -1,9 +1,4 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include - -Scope(\_SB.PCI0.LPCB.EC) -{ -} - #include diff --git a/src/mainboard/lenovo/x230/early_init.c b/src/mainboard/lenovo/x230/early_init.c new file mode 100644 index 00000000000..7d36c4b990f --- /dev/null +++ b/src/mainboard/lenovo/x230/early_init.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +void mainboard_early_init(bool s3resume) +{ + lenovo_mainboard_eeprom_lock(); +} diff --git a/src/mainboard/purism/librem_bdw/devicetree.cb b/src/mainboard/purism/librem_bdw/devicetree.cb index 45350b6c131..86d2cc2bbde 100644 --- a/src/mainboard/purism/librem_bdw/devicetree.cb +++ b/src/mainboard/purism/librem_bdw/devicetree.cb @@ -1,4 +1,4 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell # IGD Displays register "gfx" = "GMA_STATIC_DISPLAYS(0)" @@ -21,7 +21,7 @@ chip soc/intel/broadwell }" chip cpu/intel/haswell - device cpu_cluster 0 on ops broadwell_cpu_bus_ops end + device cpu_cluster 0 on ops haswell_cpu_bus_ops end end device domain 0 on ops broadwell_pci_domain_ops @@ -29,7 +29,7 @@ chip soc/intel/broadwell device pci 02.0 on end # vga controller device pci 03.0 on end # mini-hd audio - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # EC host command ranges are in 0x380-0x383 & 0x80-0x8f register "gen1_dec" = "0x00000381" diff --git a/src/mainboard/purism/librem_bdw/dsdt.asl b/src/mainboard/purism/librem_bdw/dsdt.asl index a631e5a5a57..18719a8f1ee 100644 --- a/src/mainboard/purism/librem_bdw/dsdt.asl +++ b/src/mainboard/purism/librem_bdw/dsdt.asl @@ -11,15 +11,15 @@ DefinitionBlock( ) { #include - #include - #include + #include + #include #include Scope (\_SB) { Device (PCI0) { #include - #include + #include #include } } diff --git a/src/mainboard/purism/librem_bdw/variants/librem13v1/overridetree.cb b/src/mainboard/purism/librem_bdw/variants/librem13v1/overridetree.cb index 256077cbd9a..1a8a469ea46 100644 --- a/src/mainboard/purism/librem_bdw/variants/librem13v1/overridetree.cb +++ b/src/mainboard/purism/librem_bdw/variants/librem13v1/overridetree.cb @@ -1,7 +1,7 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # Port 0 is HDD # Port 3 is M.2 NGFF register "sata_port_map" = "0x9" diff --git a/src/mainboard/purism/librem_bdw/variants/librem15v2/overridetree.cb b/src/mainboard/purism/librem_bdw/variants/librem15v2/overridetree.cb index 76737cc5e29..e2a66d83571 100644 --- a/src/mainboard/purism/librem_bdw/variants/librem15v2/overridetree.cb +++ b/src/mainboard/purism/librem_bdw/variants/librem15v2/overridetree.cb @@ -1,9 +1,9 @@ -chip soc/intel/broadwell +chip northbridge/intel/broadwell register "dq_pins_interleaved" = "true" device domain 0 on - chip soc/intel/broadwell/pch + chip southbridge/intel/wildcatpoint # Port 0 is HDD # Port 1 is M.2 NGFF register "sata_port_map" = "0x3" diff --git a/src/mainboard/purism/librem_jsl/devicetree.cb b/src/mainboard/purism/librem_jsl/devicetree.cb index 82cac1239aa..a8528f3459d 100644 --- a/src/mainboard/purism/librem_jsl/devicetree.cb +++ b/src/mainboard/purism/librem_jsl/devicetree.cb @@ -43,13 +43,10 @@ chip soc/intel/jasperlake register "PchHdaAudioLinkHdaEnable" = "1" device domain 0 on - device pci 00.0 on end # Host Bridge - device pci 02.0 on end # Integrated Graphics Device - device pci 04.0 on end # SA Thermal device - device pci 05.0 on end # IPU - device pci 09.0 off end # Intel Trace Hub - device pci 12.6 off end # GSPI 2 - device pci 14.0 on # USB xHCI + device ref igpu on end + device ref dptf on end + device ref ipu on end + device ref south_xhci on register "usb2_ports[0]" = "USB2_PORT_MID(OC_SKIP)" # Fingerprint reader register "usb2_ports[1]" = "USB2_PORT_MID(OC_SKIP)" # microSD register "usb2_ports[2]" = "USB2_PORT_MID(OC_SKIP)" # Type-C 1 @@ -64,70 +61,66 @@ chip soc/intel/jasperlake chip drivers/usb/acpi register "desc" = ""Root Hub"" register "type" = "UPC_TYPE_HUB" - device usb 0.0 on + device ref xhci_root_hub on chip drivers/usb/acpi register "desc" = ""Fingerprint Reader"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.0 on end + device ref usb2_port1 on end end chip drivers/usb/acpi register "desc" = ""microSD Card Reader"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.1 on end + device ref usb2_port2 on end end chip drivers/usb/acpi register "desc" = ""Type-C Port 1"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(0, 0)" - device usb 2.2 on end + device ref usb2_port3 on end end chip drivers/usb/acpi register "desc" = ""Type-C Port 2"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(0, 1)" - device usb 2.3 on end + device ref usb2_port4 on end end chip drivers/usb/acpi register "desc" = ""Cameras"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.5 on end + device ref usb2_port6 on end end chip drivers/usb/acpi register "desc" = ""Keyboard Dock"" register "type" = "UPC_TYPE_PROPRIETARY" - device usb 2.6 on end + device ref usb2_port7 on end end chip drivers/usb/acpi register "desc" = ""Bluetooth"" register "type" = "UPC_TYPE_INTERNAL" - device usb 2.7 on end + device ref usb2_port8 on end end chip drivers/usb/acpi register "desc" = ""Type-C Port 2"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(0, 1)" - device usb 3.0 on end + device ref usb3_port1 on end end chip drivers/usb/acpi register "desc" = ""Type-C Port 1"" register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" register "group" = "ACPI_PLD_GROUP(0, 0)" - device usb 3.1 on end + device ref usb3_port2 on end end end end end - device pci 14.1 off end # USB xDCI (OTG) - device pci 14.2 on end # PMC SRAM - device pci 14.3 on # CNVi wifi + device ref shared_ram on end + device ref cnvi_wifi on chip drivers/wifi/generic device generic 0 on end end end - device pci 14.5 off end # SD card - device pci 15.0 off end # I2C 0 - device pci 15.1 off end # I2C 1 - device pci 15.2 on # I2C 2 + device ref i2c2 on chip drivers/i2c/hid register "generic.hid" = ""GXTP7380"" register "generic.cid" = ""PNP0C50"" @@ -138,7 +131,7 @@ chip soc/intel/jasperlake device i2c 5d on end end end - device pci 15.3 on # I2C 3 + device ref i2c3 on chip drivers/i2c/generic register "hid" = ""MXC6655"" register "cid" = ""MXC6655"" @@ -147,37 +140,12 @@ chip soc/intel/jasperlake device i2c 15 on end end end - device pci 16.0 off end # HECI 1 - device pci 16.1 off end # HECI 2 - device pci 16.4 off end # HECI 3 - device pci 16.5 off end # HECI 4 - device pci 17.0 off end # SATA - device pci 19.0 on end # I2C 4 - device pci 19.1 off end # I2C 5 - device pci 19.2 off end # UART 2 - device pci 1a.0 off end # eMMC - device pci 1c.0 off end # PCI Express Root Port 1 - device pci 1c.1 off end # PCI Express Root Port 2 - device pci 1c.2 on # PCI Express Root Port 3 - M.2 M-key, PCIe only + device ref i2c4 on end + device ref pcie_rp3 on register "PcieClkSrcUsage[0]" = "2" register "PcieClkSrcClkReq[0]" = "0" smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "M.2/M 2280" "SlotDataBusWidth2X" end - device pci 1c.3 off end # PCI Express Root Port 4 - device pci 1c.4 off end # PCI Express Root Port 5 - device pci 1c.5 off end # PCI Express Root Port 6 - device pci 1c.6 off end # PCI Express Root Port 7 - device pci 1c.7 off end # PCI Express Root Port 8 - device pci 1e.0 off end # UART 0 - device pci 1e.1 off end # UART 1 - device pci 1e.2 off end # GSPI 0 - device pci 1e.3 off end # GSPI 1 - device pci 1f.0 on end # eSPI Interface - device pci 1f.1 off end # P2SB - device pci 1f.2 hidden end # Power Management Controller - device pci 1f.3 on end # Intel HDA/cAVS - device pci 1f.4 off end # SMBus - device pci 1f.5 on end # PCH SPI - device pci 1f.7 off end # Intel Trace Hub + device ref hda on end end end diff --git a/src/mainboard/qotom/Kconfig b/src/mainboard/qotom/Kconfig new file mode 100644 index 00000000000..066df4af965 --- /dev/null +++ b/src/mainboard/qotom/Kconfig @@ -0,0 +1,17 @@ +## SPDX-License-Identifier: GPL-2.0-only + +if VENDOR_QOTOM + +choice + prompt "Mainboard model" + +source "src/mainboard/qotom/*/Kconfig.name" + +endchoice + +source "src/mainboard/qotom/*/Kconfig" + +config MAINBOARD_VENDOR + default "Qotom" + +endif # VENDOR_QOTOM diff --git a/src/mainboard/qotom/Kconfig.name b/src/mainboard/qotom/Kconfig.name new file mode 100644 index 00000000000..c20833d1390 --- /dev/null +++ b/src/mainboard/qotom/Kconfig.name @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config VENDOR_QOTOM + bool "Qotom" diff --git a/src/mainboard/qotom/qdnv01/Kconfig b/src/mainboard/qotom/qdnv01/Kconfig new file mode 100644 index 00000000000..269cee07d12 --- /dev/null +++ b/src/mainboard/qotom/qdnv01/Kconfig @@ -0,0 +1,23 @@ +## SPDX-License-Identifier: GPL-2.0-only + +if BOARD_QOTOM_QDNV01 + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select SOC_INTEL_DENVERTON_NS + select BOARD_ROMSIZE_KB_16384 + select HAVE_ACPI_TABLES + select DRIVERS_ASPEED_AST2050 + select MAINBOARD_USES_IFD_10GBE_0_REGION + select MAINBOARD_USES_IFD_10GBE_1_REGION + +config MAINBOARD_DIR + default "qotom/qdnv01" + +config MAINBOARD_PART_NUMBER + default "QDNV01" + +config CBFS_SIZE + default 0x800000 + +endif # BOARD_QOTOM_QDNV01 diff --git a/src/mainboard/qotom/qdnv01/Kconfig.name b/src/mainboard/qotom/qdnv01/Kconfig.name new file mode 100644 index 00000000000..a3a2270c3b4 --- /dev/null +++ b/src/mainboard/qotom/qdnv01/Kconfig.name @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config BOARD_QOTOM_QDNV01 + bool "QDNV01" diff --git a/src/mainboard/qotom/qdnv01/Makefile.mk b/src/mainboard/qotom/qdnv01/Makefile.mk new file mode 100644 index 00000000000..8917ff6f64a --- /dev/null +++ b/src/mainboard/qotom/qdnv01/Makefile.mk @@ -0,0 +1,10 @@ +## SPDX-License-Identifier: GPL-2.0-only + +bootblock-y += bootblock.c + +romstage-y += hsio.c + +ramstage-y += ramstage.c +ramstage-y += hsio.c + +CPPFLAGS_common += -Isrc/mainboard/$(MAINBOARDDIR)/ diff --git a/src/mainboard/qotom/qdnv01/acpi/mainboard.asl b/src/mainboard/qotom/qdnv01/acpi/mainboard.asl new file mode 100644 index 00000000000..16990d45f42 --- /dev/null +++ b/src/mainboard/qotom/qdnv01/acpi/mainboard.asl @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: CC-PDDC */ + +/* Please update the license if adding licensable material. */ diff --git a/src/mainboard/qotom/qdnv01/acpi/mainboard_pci_irqs.asl b/src/mainboard/qotom/qdnv01/acpi/mainboard_pci_irqs.asl new file mode 100644 index 00000000000..3482e23761e --- /dev/null +++ b/src/mainboard/qotom/qdnv01/acpi/mainboard_pci_irqs.asl @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* This is board specific information: IRQ routing */ + +// PCI Interrupt Routing +Method(_PRT) +{ + If (PICM) { + Return (Package() { + // [GREG]: Global Registers + Package() { 0x0004ffff, 0, 0, 16 }, + + // [RCEC]: Root Complex Event Collector + Package() { 0x0005ffff, 0, 0, 23 }, + + // [VRP2]: Virtual root port 2 + Package() { 0x0006ffff, 2, 0, 18 }, + + // [PEX0]: PCI Express Port 0 + Package() { 0x0009ffff, 0, 0, 16 }, + + // [PEX1]: PCI Express Port 1 + Package() { 0x000affff, 1, 0, 17 }, + + // [PEX2]: PCI Express Port 2 + Package() { 0x000bffff, 2, 0, 18 }, + + // [PEX3]: PCI Express Port 3 + Package() { 0x000cffff, 3, 0, 19 }, + + // [PEX4]: PCI Express Port 4 + Package() { 0x000effff, 0, 0, 20 }, + + // [PEX5]: PCI Express Port 5 + Package() { 0x000fffff, 1, 0, 21 }, + + // [PEX6]: PCI Express Port 6 + Package() { 0x0010ffff, 2, 0, 22 }, + + // [PEX7]: PCI Express Port 7 + Package() { 0x0011ffff, 3, 0, 23 }, + + // [SMB1]: SMBus controller + Package() { 0x0012ffff, 0, 0, 16 }, + + // [SAT0]: SATA controller 0 + Package() { 0x0013ffff, 0, 0, 20 }, + + // [SAT1]: SATA controller 1 + Package() { 0x0014ffff, 0, 0, 21 }, + + // [XHC0]: XHCI USB controller + Package() { 0x0015ffff, 0, 0, 19 }, + + // [VRP0]: Virtual root port 0 + Package() { 0x0016ffff, 0, 0, 16 }, + + // [VRP1]: Virtual root port 1 + Package() { 0x0017ffff, 1, 0, 17 }, + + // [HECI]: ME HECI + Package() { 0x0018ffff, 0, 0, 16 }, + + // [HEC2]: ME HECI2 + Package() { 0x0018ffff, 1, 0, 17 }, + + // [MEKT]: MEKT on PCH + Package() { 0x0018ffff, 2, 0, 18 }, + + // [HEC3]: ME HECI3 + Package() { 0x0018ffff, 3, 0, 19 }, + + // [UAR0]: UART 0 + Package() { 0x001affff, 0, 0, 16 }, + + // [UAR1]: UART 1 + Package() { 0x001affff, 1, 0, 17 }, + + // [UAR2]: UART 2 + Package() { 0x001affff, 2, 0, 18 }, + + // [EMMC]: eMMC + Package() { 0x001cffff, 0, 0, 16 }, + + // [P2SB]: Primary to sideband bridge + // [SMB0]: SMBus controller + // [NPK0]: Northpeak DFX + Package() { 0x001fffff, 0, 0, 23 }, + }) + } Else { + Return (Package() { + // [GREG]: Global Registers 0:4.0 + Package() { 0x0004ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + + // [RCEC]: Root Complex Event Collector 0:5.0 + Package() { 0x0005ffff, 0, \_SB.PCI0.LPCB.LNKH, 0 }, + + // [VRP2]: Virtual root port 2 0:6.0 + Package() { 0x0006ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 }, + + // [PEX0]: PCI Express Port 0 0:9.0 + Package() { 0x0009ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + + // [PEX1]: PCI Express Port 1 0:a.0 + Package() { 0x000affff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, + + // [PEX2]: PCI Express Port 2 0:b.0 + Package() { 0x000bffff, 2, \_SB.PCI0.LPCB.LNKC, 0 }, + + // [PEX3]: PCI Express Port 3 0:c.0 + Package() { 0x000cffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }, + + // [PEX4]: PCI Express Port 4 0:e.0 + Package() { 0x000effff, 0, \_SB.PCI0.LPCB.LNKE, 0 }, + + // [PEX5]: PCI Express Port 5 0:f.0 + Package() { 0x000fffff, 1, \_SB.PCI0.LPCB.LNKF, 0 }, + + // [PEX6]: PCI Express Port 6 0:10.0 + Package() { 0x0010ffff, 2, \_SB.PCI0.LPCB.LNKG, 0 }, + + // [PEX7]: PCI Express Port 7 0:11.0 + Package() { 0x0011ffff, 3, \_SB.PCI0.LPCB.LNKH, 0 }, + + // [SMB1]: SMBus controller 0:12.0 + Package() { 0x0012ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + + // [SAT0]: SATA controller 0 0:13.0 + Package() { 0x0013ffff, 0, \_SB.PCI0.LPCB.LNKE, 0 }, + + // [SAT1]: SATA controller 1 0:14.0 + Package() { 0x0014ffff, 0, \_SB.PCI0.LPCB.LNKF, 0 }, + + // [XHC0]: XHCI USB controller 0:15.0 + Package() { 0x0015ffff, 0, \_SB.PCI0.LPCB.LNKD, 0 }, + + // [VRP0]: Virtual root port 0 0:16.0 + Package() { 0x0016ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + + // [VRP1]: Virtual root port 1 0:17.0 + Package() { 0x0017ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, + + // [HECI]: ME HECI 0:18.0 + Package() { 0x0018ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + + // [HEC2]: ME HECI2 0:18.1 + Package() { 0x0018ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, + + // [MEKT]: MEKT on PCH 0:18.2 + Package() { 0x0018ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 }, + + // [HEC3]: ME HECI3 0:18.3 + Package() { 0x0018ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }, + + // [UAR0]: UART 0 0:1a.0 + Package() { 0x001affff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + + // [UAR1]: UART 1 0:1a.1 + Package() { 0x001affff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, + + // [UAR2]: UART 2 0:1a.2 + Package() { 0x001affff, 2, \_SB.PCI0.LPCB.LNKC, 0 }, + + // [EMMC]: eMMC 0:1c.0 + Package() { 0x001cffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + + // [P2SB]: Primary to sideband bridge + // [SMB0]: SMBus controller + // [NPK0]: Northpeak DFX + Package() { 0x001ffffF, 0, \_SB.PCI0.LPCB.LNKH, 0 }, + }) + } +} diff --git a/src/mainboard/lenovo/t430/acpi/platform.asl b/src/mainboard/qotom/qdnv01/acpi/platform.asl similarity index 62% rename from src/mainboard/lenovo/t430/acpi/platform.asl rename to src/mainboard/qotom/qdnv01/acpi/platform.asl index 9dee90edc3c..bbee0a2787f 100644 --- a/src/mainboard/lenovo/t430/acpi/platform.asl +++ b/src/mainboard/qotom/qdnv01/acpi/platform.asl @@ -6,18 +6,11 @@ Method(_PTS,1) { - \_SB.PCI0.LPCB.EC.MUTE(1) - \_SB.PCI0.LPCB.EC.USBP(0) - \_SB.PCI0.LPCB.EC.RADI(0) } /* The _WAK method is called on system wakeup */ Method(_WAK,1) { - /* Wake the HKEY to init BT/WWAN */ - \_SB.PCI0.LPCB.EC.HKEY.WAKE (Arg0) - - /* Not implemented. */ Return(Package(){0,0}) } diff --git a/src/mainboard/qotom/qdnv01/acpi_tables.c b/src/mainboard/qotom/qdnv01/acpi_tables.c new file mode 100644 index 00000000000..b6e3846f281 --- /dev/null +++ b/src/mainboard/qotom/qdnv01/acpi_tables.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +void mainboard_fill_fadt(acpi_fadt_t *fadt) +{ + fadt->preferred_pm_profile = PM_ENTERPRISE_SERVER; +} diff --git a/src/mainboard/qotom/qdnv01/board_info.txt b/src/mainboard/qotom/qdnv01/board_info.txt new file mode 100644 index 00000000000..88971b9bfdc --- /dev/null +++ b/src/mainboard/qotom/qdnv01/board_info.txt @@ -0,0 +1,6 @@ +Vendor name: Qotom +Board name: QDNV01 +Category: eval +ROM protocol: SPI +ROM socketed: n +Flashrom support: y diff --git a/src/mainboard/qotom/qdnv01/bootblock.c b/src/mainboard/qotom/qdnv01/bootblock.c new file mode 100644 index 00000000000..3b3fd229401 --- /dev/null +++ b/src/mainboard/qotom/qdnv01/bootblock.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + + +void bootblock_mainboard_early_init(void) +{ +} diff --git a/src/mainboard/qotom/qdnv01/devicetree.cb b/src/mainboard/qotom/qdnv01/devicetree.cb new file mode 100644 index 00000000000..b7ba01f1ac3 --- /dev/null +++ b/src/mainboard/qotom/qdnv01/devicetree.cb @@ -0,0 +1,78 @@ +## SPDX-License-Identifier: GPL-2.0-only + +chip soc/intel/denverton_ns + + # configure pirq routing + register "pirqa_routing" = "11" + register "pirqb_routing" = "10" + register "pirqc_routing" = "06" + register "pirqd_routing" = "07" + register "pirqe_routing" = "12" + register "pirqf_routing" = "14" + register "pirqg_routing" = "15" + register "pirqh_routing" = "15" + # configure device interrupt routing + register "ir00_routing" = "0x3217" # IR00, Dev31 + register "ir01_routing" = "0x3210" # IR01, Dev22 + register "ir02_routing" = "0x3211" # IR02, Dev23 + register "ir03_routing" = "0x3217" # IR03, Dev5 + register "ir04_routing" = "0x3212" # IR04, Dev6 + register "ir05_routing" = "0x3210" # IR05, Dev24 + register "ir06_routing" = "0x3214" # IR06, Dev19 + register "ir07_routing" = "0x3210" # IR07, Dev9/10/11/12 + register "ir08_routing" = "0x7654" # IR08, Dev14/15/16/17 + register "ir09_routing" = "0x3213" # IR09, Dev21 + register "ir10_routing" = "0x3210" # IR10, Dev26/18 + register "ir11_routing" = "0x3215" # IR11, Dev20 + register "ir12_routing" = "0x3210" # IR12, Dev27 + # configure interrupt polarity control + register "ipc0" = "0x00ff4000" # IPC0, PIRQA-H (IRQ16-23) should always be ActiveLow + register "ipc1" = "0x00000000" # IPC1 + register "ipc2" = "0x00000000" # IPC2 + register "ipc3" = "0x00000000" # IPC3 + + device cpu_cluster 0 on end + + device domain 0 on + device pci 00.0 on end # Host Bridge + device pci 04.0 on end # RAS + device pci 05.0 on end # RCEC (Root Complex Event Collector) + device pci 06.0 on end # Virtual root port 2 (QAT) + device pci 09.0 on end # PCI Express Port 0 + device pci 0a.0 on end # PCI Express Port 1 + device pci 0b.0 on # PCI Express Port 2 + device pci 00.0 on end # Intel Ethernet Controller I226-V + end + device pci 0c.0 on # PCI Express Port 3 + device pci 00.0 on end # Intel Ethernet Controller I226-V + end + device pci 0e.0 on # PCI Express Port 4 + device pci 00.0 on end # Intel Ethernet Controller I226-V + end + device pci 0f.0 on # PCI Express Port 5 + device pci 00.0 on end # Intel Ethernet Controller I226-V + end + device pci 10.0 on # PCI Express Port 6 + device pci 00.0 on end # Intel Ethernet Controller I226-V + end + device pci 11.0 on # PCI Express Port 7 + device pci 00.0 on # ASPEED PCI-to-PCI bridge 1a03:1150 + device pci 00.0 on end # ASPEED VGA controller 1a03:2000 + end + end + device pci 12.0 on end # SMBus Controller + device pci 13.0 on end # SATA Controller 0 + device pci 14.0 on end # SATA Controller 1 + device pci 15.0 on end # XHCI USB Controller + device pci 16.0 on end # Virtual root port 0 (10GBE0) + device pci 17.0 on end # Virtual root port 1 (10GBE1) + device pci 18.0 on end # CSME HECI 1 + device pci 1a.0 on end # UART 0 + device pci 1a.1 on end # UART 1 + device pci 1a.2 on end # UART 2 + device pci 1f.0 on end # LPC or eSPI + device pci 1f.2 on end # PMC/ACPI + device pci 1f.4 on end # SMBus Controller + device pci 1f.5 on end # SPI Controller + end +end diff --git a/src/mainboard/qotom/qdnv01/dsdt.asl b/src/mainboard/qotom/qdnv01/dsdt.asl new file mode 100644 index 00000000000..3fa7422c463 --- /dev/null +++ b/src/mainboard/qotom/qdnv01/dsdt.asl @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +DefinitionBlock( + "dsdt.aml", + "DSDT", + ACPI_DSDT_REV_2, + OEM_ID, + ACPI_TABLE_CREATOR, + 0x20110725 +) +{ + #include + #include + #include "acpi/platform.asl" + #include "acpi/mainboard.asl" + + // global NVS and variables + #include + + #include + + Scope (\_SB) { + Device (PCI0) + { + #include + #include + } + } + + #include +} diff --git a/src/mainboard/qotom/qdnv01/gpio.h b/src/mainboard/qotom/qdnv01/gpio.h new file mode 100644 index 00000000000..b0653699297 --- /dev/null +++ b/src/mainboard/qotom/qdnv01/gpio.h @@ -0,0 +1,622 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _MAINBOARD_GPIO_H +#define _MAINBOARD_GPIO_H + +#include + +#ifndef __ACPI__ +const struct dnv_pad_config qdnv01_gpio_table[] = { + // GBE0_SDP0 (GPIO_14) + {NORTH_ALL_GBE0_SDP0, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE1_SDP0 (GPIO_15) + {NORTH_ALL_GBE1_SDP0, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE2_I2C_CLK (GPIO_16) + {NORTH_ALL_GBE0_SDP1, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE2_I2C_DATA (GPIO_17) + {NORTH_ALL_GBE1_SDP1, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE2_SDP0 (GPIO_18) + {NORTH_ALL_GBE0_SDP2, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE3_SDP0 (GPIO_19) + {NORTH_ALL_GBE1_SDP2, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE3_I2C_CLK (GPIO_20) + {NORTH_ALL_GBE0_SDP3, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE3_I2C_DATA (GPIO_21) + {NORTH_ALL_GBE1_SDP3, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE2_LED0 (GPIO_22) + {NORTH_ALL_GBE2_LED0, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE2_LED1 (GPIO_23) + {NORTH_ALL_GBE2_LED1, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE0_I2C_CLK (GPIO_24) + {NORTH_ALL_GBE0_I2C_CLK, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE0_I2C_DATA (GPIO_25) + {NORTH_ALL_GBE0_I2C_DATA, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE1_I2C_CLK (GPIO_26) + {NORTH_ALL_GBE1_I2C_CLK, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE1_I2C_DATA (GPIO_27) + {NORTH_ALL_GBE1_I2C_DATA, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // NCSI_RXD0 (GPIO_28) + {NORTH_ALL_NCSI_RXD0, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // NCSI_CLK_IN (GPIO_29) + {NORTH_ALL_NCSI_CLK_IN, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // NCSI_RXD1 (GPIO_30) + {NORTH_ALL_NCSI_RXD1, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // NCSI_CRS_DV (GPIO_31) + {NORTH_ALL_NCSI_CRS_DV, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // NCSI_ARB_IN (GPIO_32) + {NORTH_ALL_NCSI_ARB_IN, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // NCSI_TX_EN (GPIO_33) + {NORTH_ALL_NCSI_TX_EN, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // NCSI_TXD0 (GPIO_34) + {NORTH_ALL_NCSI_TXD0, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // NCSI_TXD1 (GPIO_35) + {NORTH_ALL_NCSI_TXD1, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // NCSI_ARB_OUT (GPIO_36) + {NORTH_ALL_NCSI_ARB_OUT, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // GBE0_LED0 (GPIO_37) + {NORTH_ALL_GBE0_LED0, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // GBE0_LED1 (GPIO_38) + {NORTH_ALL_GBE0_LED1, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // GBE1_LED0 (GPIO_39) + {NORTH_ALL_GBE1_LED0, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // GBE1_LED1 (GPIO_40) + {NORTH_ALL_GBE1_LED1, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // ADR-COMPLETE (GPIO_0) + {NORTH_ALL_GPIO_0, + {GpioPadModeNative3, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // PCIE_CLKREQ0_N (GPIO_41) + {NORTH_ALL_PCIE_CLKREQ0_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // PCIE_CLKREQ1_N (GPIO_42) + {NORTH_ALL_PCIE_CLKREQ1_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // PCIE_CLKREQ2_N (GPIO_43) + {NORTH_ALL_PCIE_CLKREQ2_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // PCIE_CLKREQ3_N (GPIO_44) + {NORTH_ALL_PCIE_CLKREQ3_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // FORCE_POWER (GPIO_45) + {NORTH_ALL_PCIE_CLKREQ4_N, + {GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE_MDC (GPIO_1) + {NORTH_ALL_GPIO_1, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE_MDIO (GPIO_2) + {NORTH_ALL_GPIO_2, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SVID_ALERT_N (GPIO_47) + {NORTH_ALL_SVID_ALERT_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SVID_DATA (GPIO_48) + {NORTH_ALL_SVID_DATA, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SVID_CLK (GPIO_49) + {NORTH_ALL_SVID_CLK, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // THERMTRIP_N (GPIO_50) + {NORTH_ALL_THERMTRIP_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // PROCHOT_N (GPIO_51) + {NORTH_ALL_PROCHOT_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // MEMHOT_N (GPIO_52) + {NORTH_ALL_MEMHOT_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT_CLK0 (GPIO_53) + {SOUTH_DFX_DFX_PORT_CLK0, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT_CLK1 (GPIO_54) + {SOUTH_DFX_DFX_PORT_CLK1, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT0 (GPIO_55) + {SOUTH_DFX_DFX_PORT0, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT1 (GPIO_56) + {SOUTH_DFX_DFX_PORT1, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT2 (GPIO_57) + {SOUTH_DFX_DFX_PORT2, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT3 (GPIO_58) + {SOUTH_DFX_DFX_PORT3, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT4 (GPIO_59) + {SOUTH_DFX_DFX_PORT4, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT5 (GPIO_60) + {SOUTH_DFX_DFX_PORT5, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT6 (GPIO_61) + {SOUTH_DFX_DFX_PORT6, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT7 (GPIO_62) + {SOUTH_DFX_DFX_PORT7, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT8 (GPIO_63) + {SOUTH_DFX_DFX_PORT8, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT9 (GPIO_134) + {SOUTH_DFX_DFX_PORT9, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT10 (GPIO_135) + {SOUTH_DFX_DFX_PORT10, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT11 (GPIO_136) + {SOUTH_DFX_DFX_PORT11, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT12 (GPIO_137) + {SOUTH_DFX_DFX_PORT12, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT13 (GPIO_138) + {SOUTH_DFX_DFX_PORT13, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT14 (GPIO_139) + {SOUTH_DFX_DFX_PORT14, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // DFX_PORT15 (GPIO_140) + {SOUTH_DFX_DFX_PORT15, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SPI_TPM_CS_N (GPIO_12) + {SOUTH_GROUP0_GPIO_12, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB5_GBE_ALRT_N (GPIO_13) + {SOUTH_GROUP0_SMB5_GBE_ALRT_N, + {GpioPadModeNative3, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // SMI (GPIO_98) + {SOUTH_GROUP0_PCIE_CLKREQ5_N, + {GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntSmi, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // NMI (GPIO_99) + {SOUTH_GROUP0_PCIE_CLKREQ6_N, + {GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntNmi, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE3_LED0 (GPIO_100) + {SOUTH_GROUP0_PCIE_CLKREQ7_N, + {GpioPadModeNative3, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // UART0_RXD (GPIO_101) + {SOUTH_GROUP0_UART0_RXD, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // UART0_TXD (GPIO_102) + {SOUTH_GROUP0_UART0_TXD, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB5_GBE_CLK (GPIO_103) + {SOUTH_GROUP0_SMB5_GBE_CLK, + {GpioPadModeNative3, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // SMB_GBE_DATA (GPIO_104) + {SOUTH_GROUP0_SMB5_GBE_DATA, + {GpioPadModeNative3, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetPwrGood, GpioTermDefault, GpioLockDefault} }, + // ERROR2_N (GPIO_105) + {SOUTH_GROUP0_ERROR2_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // ERROR1_N (GPIO_106) + {SOUTH_GROUP0_ERROR1_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // ERROR0_N (GPIO_107) + {SOUTH_GROUP0_ERROR0_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // IERR_N (CATERR_N) (GPIO_108) + {SOUTH_GROUP0_IERR_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // MCERR_N (GPIO_109) + {SOUTH_GROUP0_MCERR_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB0_LEG_CLK (GPIO_110) + {SOUTH_GROUP0_SMB0_LEG_CLK, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB0_LEG_DATA (GPIO_111) + {SOUTH_GROUP0_SMB0_LEG_DATA, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB0_LEG_ALRT_N (GPIO_112) + {SOUTH_GROUP0_SMB0_LEG_ALRT_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB1_HOST_DATA (GPIO_113) + {SOUTH_GROUP0_SMB1_HOST_DATA, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB1_HOST_CLK (GPIO_114) + {SOUTH_GROUP0_SMB1_HOST_CLK, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB2_PECI_DATA (GPIO_115) + {SOUTH_GROUP0_SMB2_PECI_DATA, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB2_PECI_CLK (GPIO_116) + {SOUTH_GROUP0_SMB2_PECI_CLK, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB4_CSME0_DATA (GPIO_117) + {SOUTH_GROUP0_SMB4_CSME0_DATA, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB4_CSME0_CLK (GPIO_118) + {SOUTH_GROUP0_SMB4_CSME0_CLK, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB4_CSME0_ALRT_N (GPIO_119) + {SOUTH_GROUP0_SMB4_CSME0_ALRT_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // USB_OC0_N (GPIO_120) + {SOUTH_GROUP0_USB_OC0_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // FLEX_CLK_SE0 (GPIO_121) + {SOUTH_GROUP0_FLEX_CLK_SE0, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // FLEX_CLK_SE1 (GPIO_122) + {SOUTH_GROUP0_FLEX_CLK_SE1, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // GBE3_LED1 (GPIO_4) + {SOUTH_GROUP0_GPIO_4, + {GpioPadModeNative3, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB3_IE0_CLK (GPIO_5) + {SOUTH_GROUP0_GPIO_5, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB3_IE0_DATA (GPIO_6) + {SOUTH_GROUP0_GPIO_6, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB3_IE0_ALERT_N (GPIO_7) + {SOUTH_GROUP0_GPIO_7, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SATA0_LED (GPIO_90) + {SOUTH_GROUP0_SATA0_LED_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SATA1_LED (GPIO_91) + {SOUTH_GROUP0_SATA1_LED_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SATA_PDETECT0 (GPIO_92) + {SOUTH_GROUP0_SATA_PDETECT0, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SATA_PDETECT1 (GPIO_93) + {SOUTH_GROUP0_SATA_PDETECT1, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // UART1_RTS (GPIO_94) + {SOUTH_GROUP0_SATA0_SDOUT, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // UART1_CTS (GPIO_95) + {SOUTH_GROUP0_SATA1_SDOUT, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // UART1_RXD (GPIO_96) + {SOUTH_GROUP0_UART1_RXD, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // UART1_TXD (GPIO_97) + {SOUTH_GROUP0_UART1_TXD, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB6_CSME1_DATA (GPIO_8) + {SOUTH_GROUP0_GPIO_8, + {GpioPadModeNative3, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB6_CSME1_CLK (GPIO_9) + {SOUTH_GROUP0_GPIO_9, + {GpioPadModeNative3, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // TCK (GPIO_141) + {SOUTH_GROUP0_TCK, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // TRST_N (GPIO_142) + {SOUTH_GROUP0_TRST_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // TMS (GPIO_143) + {SOUTH_GROUP0_TMS, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // TDI (GPIO_144) + {SOUTH_GROUP0_TDI, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // TDO (GPIO_145) + {SOUTH_GROUP0_TDO, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // CX_PRDY_N (GPIO_146) + {SOUTH_GROUP0_CX_PRDY_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // CX-PREQ_N (GPIO_147) + {SOUTH_GROUP0_CX_PREQ_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // ME_RECVR_HDR (GPIO_148) + {SOUTH_GROUP0_CTBTRIGINOUT, + {GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermWpu20K /*GpioTermDefault*/, + GpioLockDefault} }, + // ADV_DBG_DFX_HDR (GPIO_149) + {SOUTH_GROUP0_CTBTRIGOUT, + {GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // LAD2_SPI_IRQ_N (GPIO_150) + {SOUTH_GROUP0_DFX_SPARE2, + {GpioPadModeGpio, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB_PECI_ALRT_N (GPIO_151) + {SOUTH_GROUP0_DFX_SPARE3, + {GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SMB_CSME1_ALRT_N (GPIO_152) + {SOUTH_GROUP0_DFX_SPARE4, + {GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SUSPWRDNACK (GPIO_79) + {SOUTH_GROUP1_SUSPWRDNACK, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // PMU_SUSCLK (GPIO_80) + {SOUTH_GROUP1_PMU_SUSCLK, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // ADR_TRIGGER_N (GPIO_81) + {SOUTH_GROUP1_ADR_TRIGGER, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // PMU_SLP_S45_N (GPIO_82) + {SOUTH_GROUP1_PMU_SLP_S45_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // PMU_SLP_S3_N (GPIO_83) + {SOUTH_GROUP1_PMU_SLP_S3_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // PMU_WAKE_N (GPIO_84) + {SOUTH_GROUP1_PMU_WAKE_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // PMU_PWRBTN_N (GPIO_85) + {SOUTH_GROUP1_PMU_PWRBTN_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // PMU_RESETBUTTON_N (GPIO_86) + {SOUTH_GROUP1_PMU_RESETBUTTON_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // PMU_PLTRST_N (GPIO_87) + {SOUTH_GROUP1_PMU_PLTRST_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // PMU_SUS_STAT_N (GPIO_88) + {SOUTH_GROUP1_SUS_STAT_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // TDB_CIO_PLUG_EVENT (GPIO_89) + {SOUTH_GROUP1_SLP_S0IX_N, + {GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SPI_CS0_N (GPIO_72) + {SOUTH_GROUP1_SPI_CS0_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SPI_CS1_N (GPIO_73) + {SOUTH_GROUP1_SPI_CS1_N, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SPI_MOSI_IO0 (GPIO_74) + {SOUTH_GROUP1_SPI_MOSI_IO0, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SPI_MISO_IO1 (GPIO_75) + {SOUTH_GROUP1_SPI_MISO_IO1, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SPI_IO2 (GPIO_76) + {SOUTH_GROUP1_SPI_IO2, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SPI_IO3 (GPIO_77) + {SOUTH_GROUP1_SPI_IO3, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // SPI_CLK (GPIO_78) + {SOUTH_GROUP1_SPI_CLK, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // LPC_AD0 (GPIO_64) + {SOUTH_GROUP1_ESPI_IO0, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // LPC_AD1 (GPIO_65) + {SOUTH_GROUP1_ESPI_IO1, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // LPC_AD2 (GPIO_66) + {SOUTH_GROUP1_ESPI_IO2, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // LPC_AD3 (GPIO_67) + {SOUTH_GROUP1_ESPI_IO3, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // LPC_FRAME_N (GPIO_68) + {SOUTH_GROUP1_ESPI_CS0_N, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // LPC_CLKOUT0 (GPIO_69) + {SOUTH_GROUP1_ESPI_CLK, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // LPC_CLKOUT1 (GPIO_70) + {SOUTH_GROUP1_ESPI_RST_N, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // LPC_CLKRUN_N (GPIO_71) + {SOUTH_GROUP1_ESPI_ALRT0_N, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // MFG_MODE_HDR (GPIO_10) + {SOUTH_GROUP1_GPIO_10, + {GpioPadModeGpio, GpioHostOwnGpio, GpioDirIn, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // LPC_SERIRQ (GPIO_11) + {SOUTH_GROUP1_GPIO_11, + {GpioPadModeNative2, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // EMMC-CMD (GPIO_123) + {SOUTH_GROUP1_EMMC_CMD, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermWpu20K, GpioLockDefault} }, + // EMMC-CSTROBE (GPIO_124) + {SOUTH_GROUP1_EMMC_STROBE, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, + // EMMC-CLK (GPIO_125) + {SOUTH_GROUP1_EMMC_CLK, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermWpd20K, GpioLockDefault} }, + // EMMC-D0 (GPIO_126) + {SOUTH_GROUP1_EMMC_D0, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermWpu20K, GpioLockDefault} }, + // EMMC-D1 (GPIO_127) + {SOUTH_GROUP1_EMMC_D1, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermWpu20K, GpioLockDefault} }, + // EMMC-D2 (GPIO_128) + {SOUTH_GROUP1_EMMC_D2, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermWpu20K, GpioLockDefault} }, + // EMMC-D3 (GPIO_129) + {SOUTH_GROUP1_EMMC_D3, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermWpu20K, GpioLockDefault} }, + // EMMC-D4 (GPIO_130) + {SOUTH_GROUP1_EMMC_D4, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermWpu20K, GpioLockDefault} }, + // EMMC-D5 (GPIO_131) + {SOUTH_GROUP1_EMMC_D5, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermWpu20K, GpioLockDefault} }, + // EMMC-D6 (GPIO_132) + {SOUTH_GROUP1_EMMC_D6, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermWpu20K, GpioLockDefault} }, + // EMMC-D7 (GPIO_133) + {SOUTH_GROUP1_EMMC_D7, + {GpioPadModeNative1, GpioHostOwnGpio, GpioDirInOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermWpu20K, GpioLockDefault} }, + // IE_ROM GPIO (GPIO_3) + {SOUTH_GROUP1_GPIO_3, + {GpioPadModeGpio, GpioHostOwnGpio, GpioDirOut, GpioOutDefault, + GpioIntDefault, GpioResetDefault, GpioTermDefault, GpioLockDefault} }, +}; +#endif + +#endif /* _MAINBOARD_GPIO_H */ diff --git a/src/mainboard/qotom/qdnv01/hsio.c b/src/mainboard/qotom/qdnv01/hsio.c new file mode 100644 index 00000000000..3b1beac3ffd --- /dev/null +++ b/src/mainboard/qotom/qdnv01/hsio.c @@ -0,0 +1,253 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const BL_HSIO_INFORMATION qdnv01_hsio_config[] = { + /* + * + * Bifurcation: + * PCIE cluster #0: x2x2x2x2 + * PCIE cluster #1: x2x2x2x2 + * + */ + {BL_SKU_HSIO_20, + {PCIE_BIF_CTRL_x2x2x2x2, PCIE_BIF_CTRL_x2x2x2x2}, + {/* ME_FIA_MUX_CONFIG */ + {BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE00) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE01) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE02) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE03) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE04) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE05) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE06) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE07) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE08) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE09) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE10) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE11) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE12) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE13) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE14) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE15) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_SATA, BL_FIA_LANE16) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_SATA, BL_FIA_LANE17) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_SATA, BL_FIA_LANE18) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_XHCI, BL_FIA_LANE19)}, + + /* ME_FIA_SATA_CONFIG */ + {BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE04) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE05) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE06) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE07) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE08) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE09) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE10) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE11) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE12) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE13) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE14) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE15) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_ASSIGNED, + BL_FIA_SATA_LANE16) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_ASSIGNED, + BL_FIA_SATA_LANE17) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_ASSIGNED, + BL_FIA_SATA_LANE18) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE19)}, + + /* ME_FIA_PCIE_ROOT_PORTS_CONFIG */ + {BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_0) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_1) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_2) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_3) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_4) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_5) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_6) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_7) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH_BICTRL, + BL_FIA_PCIE_ROOT_PORT_0) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH_BICTRL, + BL_FIA_PCIE_ROOT_PORT_1) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_X1, + BL_FIA_PCIE_ROOT_PORT_2) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_X1, + BL_FIA_PCIE_ROOT_PORT_3) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_X1, + BL_FIA_PCIE_ROOT_PORT_4) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_X1, + BL_FIA_PCIE_ROOT_PORT_5) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_X1, + BL_FIA_PCIE_ROOT_PORT_6) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_X1, + BL_FIA_PCIE_ROOT_PORT_7)} } }, + + /* SKU HSIO 12 */ + {BL_SKU_HSIO_12, + {PCIE_BIF_CTRL_x2x2x2x2, PCIE_BIF_CTRL_x2x2x2x2}, + {/*ME_FIA_MUX_CONFIG */ + {BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE00) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE01) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE02) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE03) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_DISCONNECTED, BL_FIA_LANE04) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_DISCONNECTED, BL_FIA_LANE05) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_DISCONNECTED, BL_FIA_LANE06) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_DISCONNECTED, BL_FIA_LANE07) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE08) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE09) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_DISCONNECTED, BL_FIA_LANE10) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_DISCONNECTED, BL_FIA_LANE11) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE12) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_PCIE, BL_FIA_LANE13) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_DISCONNECTED, BL_FIA_LANE14) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_DISCONNECTED, BL_FIA_LANE15) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_SATA, BL_FIA_LANE16) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_SATA, BL_FIA_LANE17) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_SATA, BL_FIA_LANE18) | + BL_FIA_LANE_CONFIG(BL_ME_FIA_MUX_LANE_XHCI, BL_FIA_LANE19)}, + + /* ME_FIA_SATA_CONFIG */ + {BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE04) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE05) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE06) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE07) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE08) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE09) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE10) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE11) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE12) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE13) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE14) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE15) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_ASSIGNED, + BL_FIA_SATA_LANE16) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_ASSIGNED, + BL_FIA_SATA_LANE17) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_ASSIGNED, + BL_FIA_SATA_LANE18) | + BL_FIA_SATA_LANE_CONFIG(BL_ME_FIA_SATA_CONTROLLER_LANE_NOT_ASSIGNED, + BL_FIA_SATA_LANE19)}, + + /* ME_FIA_PCIE_ROOT_PORTS_CONFIG */ + {BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_0) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_1) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_2) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_3) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_4) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_5) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_6) | + BL_FIA_PCIE_ROOT_PORT_CONFIG(BL_ME_FIA_PCIE_ROOT_PORT_STATE, + BL_ME_FIA_PCIE_ROOT_PORT_ENABLED, + BL_FIA_PCIE_ROOT_PORT_7) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH_BICTRL, + BL_FIA_PCIE_ROOT_PORT_0) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH_BICTRL, + BL_FIA_PCIE_ROOT_PORT_1) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_X1, + BL_FIA_PCIE_ROOT_PORT_2) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_X1, + BL_FIA_PCIE_ROOT_PORT_3) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_X1, + BL_FIA_PCIE_ROOT_PORT_4) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_X1, + BL_FIA_PCIE_ROOT_PORT_5) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_X1, + BL_FIA_PCIE_ROOT_PORT_6) | + BL_FIA_PCIE_ROOT_PORT_CONFIG( + BL_ME_FIA_PCIE_ROOT_PORT_LINK_WIDTH, + BL_ME_FIA_PCIE_ROOT_PORT_LINK_X1, + BL_FIA_PCIE_ROOT_PORT_7)} } } +}; + +size_t mainboard_get_hsio_config(BL_HSIO_INFORMATION **p_hsio_config) +{ + const size_t num = ARRAY_SIZE(qdnv01_hsio_config); + (*p_hsio_config) = (BL_HSIO_INFORMATION *)qdnv01_hsio_config; + return num; +} diff --git a/src/mainboard/qotom/qdnv01/ramstage.c b/src/mainboard/qotom/qdnv01/ramstage.c new file mode 100644 index 00000000000..b7e56c569df --- /dev/null +++ b/src/mainboard/qotom/qdnv01/ramstage.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +void mainboard_silicon_init_params(FSPS_UPD *params) +{ + /* Disable eMMC */ + params->FspsConfig.PcdEnableEmmc = 0; +} diff --git a/src/mainboard/qotom/qdnv01/romstage.c b/src/mainboard/qotom/qdnv01/romstage.c new file mode 100644 index 00000000000..4a2ea2c4e28 --- /dev/null +++ b/src/mainboard/qotom/qdnv01/romstage.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpio.h" +#include +#include +#include +#include + + +/* +* Configure GPIO depend on platform +*/ +void mainboard_config_gpios(void) +{ + const int num = ARRAY_SIZE(qdnv01_gpio_table); + const struct dnv_pad_config *table = qdnv01_gpio_table; + + printk(BIOS_INFO, "GPIO table: 0x%lx, entry num: %d!\n", + (uintptr_t)table, num); + gpio_configure_dnv_pads(table, num); +} + +void mainboard_memory_init_params(FSPM_UPD *mupd) +{ + /* Disable Memory Down function */ + mupd->FspmConfig.PcdMemoryDown = 0; + + mupd->FspmConfig.PcdMmioSize = 2; + + /* Enable memory preservation through warm resets and Fast Boot by default */ + mupd->FspmConfig.PcdMemoryPreservation = 1; + mupd->FspmConfig.PcdFastBoot = 1; + mupd->FspmConfig.PcdSkipMemoryTest = 1; + + /* FSP debug message level */ + mupd->FspmConfig.PcdFspDebugPrintErrorLevel = 1; +} diff --git a/src/mainboard/samsung/lumpy/hda_verb.c b/src/mainboard/samsung/lumpy/hda_verb.c index aedd7b6ce2e..e6ed443a958 100644 --- a/src/mainboard/samsung/lumpy/hda_verb.c +++ b/src/mainboard/samsung/lumpy/hda_verb.c @@ -56,7 +56,7 @@ const u32 cim_verb_data[] = { )), /* Pin Complex (NID 0x08) - Unused (NC) */ - AZALIA_PIN_CFG_NC(0), + AZALIA_PIN_CFG(0, 0x08, AZALIA_PIN_CFG_NC(0)), /* Pin Complex (NID 0x09) - Internal Digital Mic */ AZALIA_PIN_CFG(0, 0x09, AZALIA_PIN_DESC( diff --git a/src/mainboard/siemens/mc_ehl/Kconfig b/src/mainboard/siemens/mc_ehl/Kconfig index 5aff0be1b53..25715ad9f81 100644 --- a/src/mainboard/siemens/mc_ehl/Kconfig +++ b/src/mainboard/siemens/mc_ehl/Kconfig @@ -29,6 +29,12 @@ config BOARD_SIEMENS_MC_EHL5 config BOARD_SIEMENS_MC_EHL6 select BOARD_SIEMENS_BASEBOARD_MC_EHL +config BOARD_SIEMENS_MC_EHL7 + select BOARD_SIEMENS_BASEBOARD_MC_EHL + +config BOARD_SIEMENS_MC_EHL8 + select BOARD_SIEMENS_BASEBOARD_MC_EHL + source "src/mainboard/siemens/mc_ehl/variants/*/Kconfig" if BOARD_SIEMENS_BASEBOARD_MC_EHL @@ -43,6 +49,8 @@ config VARIANT_DIR default "mc_ehl4" if BOARD_SIEMENS_MC_EHL4 default "mc_ehl5" if BOARD_SIEMENS_MC_EHL5 default "mc_ehl6" if BOARD_SIEMENS_MC_EHL6 + default "mc_ehl7" if BOARD_SIEMENS_MC_EHL7 + default "mc_ehl8" if BOARD_SIEMENS_MC_EHL8 config MAINBOARD_PART_NUMBER default "MC EHL1" if BOARD_SIEMENS_MC_EHL1 @@ -51,6 +59,8 @@ config MAINBOARD_PART_NUMBER default "MC EHL4" if BOARD_SIEMENS_MC_EHL4 default "MC EHL5" if BOARD_SIEMENS_MC_EHL5 default "MC EHL6" if BOARD_SIEMENS_MC_EHL6 + default "MC EHL7" if BOARD_SIEMENS_MC_EHL7 + default "MC EHL8" if BOARD_SIEMENS_MC_EHL8 config DEVICETREE default "variants/\$(CONFIG_VARIANT_DIR)/devicetree.cb" diff --git a/src/mainboard/siemens/mc_ehl/Kconfig.name b/src/mainboard/siemens/mc_ehl/Kconfig.name index 50233cea9c8..57eba04f0aa 100644 --- a/src/mainboard/siemens/mc_ehl/Kconfig.name +++ b/src/mainboard/siemens/mc_ehl/Kconfig.name @@ -19,3 +19,9 @@ config BOARD_SIEMENS_MC_EHL5 config BOARD_SIEMENS_MC_EHL6 bool "-> MC EHL6" + +config BOARD_SIEMENS_MC_EHL7 + bool "-> MC EHL7" + +config BOARD_SIEMENS_MC_EHL8 + bool "-> MC EHL8" diff --git a/src/mainboard/siemens/mc_ehl/romstage_fsp_params.c b/src/mainboard/siemens/mc_ehl/romstage_fsp_params.c index d386d756a6b..1e818345ba7 100644 --- a/src/mainboard/siemens/mc_ehl/romstage_fsp_params.c +++ b/src/mainboard/siemens/mc_ehl/romstage_fsp_params.c @@ -38,8 +38,10 @@ void mainboard_memory_init_params(FSPM_UPD *memupd) /* Enable Row-Hammer prevention */ memupd->FspmConfig.RhPrevention = 1; - if (CONFIG(BOARD_SIEMENS_MC_EHL1)) { - /* Allow writes to EEPROM addresses 0x50..0x57. */ + if (CONFIG(BOARD_SIEMENS_MC_EHL1) || CONFIG(BOARD_SIEMENS_MC_EHL8)) { + /* Disable write protection for SMBus addresses 0x50-0x57. + * mc_ehl1: Writable SPD EEPROM + * mc_ehl8: RTC at address 0x52 */ memupd->FspmConfig.SmbusSpdWriteDisable = 0; } } diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl2/devicetree.cb b/src/mainboard/siemens/mc_ehl/variants/mc_ehl2/devicetree.cb index 4a7a9974466..c1ebf7b5be0 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl2/devicetree.cb +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl2/devicetree.cb @@ -62,6 +62,11 @@ chip soc/intel/elkhartlake register "PcieRpLtrDisable[1]" = "true" register "PcieRpLtrDisable[6]" = "true" + # Adjust TX Output De-Emphasis for PCIe RP7 to -0.137 dB + register "pcie_mp_cfg[6]" = "{ + .tx_gen1_de_emph = 0x3f, + }" + # Storage (SDCARD/EMMC) related UPDs register "ScsEmmcHs400Enabled" = "0" register "ScsEmmcDdr50Enabled" = "1" diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl5/devicetree.cb b/src/mainboard/siemens/mc_ehl/variants/mc_ehl5/devicetree.cb index bcd76cb9916..5fca41cd4be 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl5/devicetree.cb +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl5/devicetree.cb @@ -62,6 +62,11 @@ chip soc/intel/elkhartlake register "PcieRpLtrDisable[1]" = "true" register "PcieRpLtrDisable[6]" = "true" + # Adjust TX Output De-Emphasis for PCIe RP7 to -0.137 dB + register "pcie_mp_cfg[6]" = "{ + .tx_gen1_de_emph = 0x3f, + }" + # Storage (SDCARD/EMMC) related UPDs register "ScsEmmcHs400Enabled" = "0" register "ScsEmmcDdr50Enabled" = "1" diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/devicetree.cb b/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/devicetree.cb index 5180770908a..f47fde0cab1 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/devicetree.cb +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/devicetree.cb @@ -111,6 +111,12 @@ chip soc/intel/elkhartlake [PchSerialIoIndexI2C6] = 1, }" + register "common_soc_config" = "{ + .i2c[1] = { + .speed = I2C_SPEED_STANDARD, + }, + }" + register "SerialIoUartMode" = "{ [PchSerialIoIndexUART0] = PchSerialIoPci, [PchSerialIoIndexUART1] = PchSerialIoPci, diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/gpio.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/gpio.c index 49f737b8684..4ec42c02cf4 100644 --- a/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/gpio.c +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl6/gpio.c @@ -27,6 +27,7 @@ static const struct pad_config gpio_table[] = { PAD_CFG_NF(GPP_T13, NONE, DEEP, NF2), /* SIO_UART0_TXD */ /* Community 0 - GpioGroup GPP_G */ + PAD_CFG_NF(GPP_G5, UP_20K, DEEP, NF1), /* SD Card Detect */ PAD_NC(GPP_G8, NONE), /* Not connected */ PAD_NC(GPP_G9, NONE), /* Not connected */ PAD_CFG_GPI(GPP_G19, UP_20K, PLTRST), /* TPM_IRQ_N */ diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig new file mode 100644 index 00000000000..c1c3bb2a989 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Kconfig @@ -0,0 +1,37 @@ +## SPDX-License-Identifier: GPL-2.0-only + +if BOARD_SIEMENS_MC_EHL7 + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select DRIVER_INTEL_I210 + select MAINBOARD_HAS_TPM2 + select MEMORY_MAPPED_TPM + select NC_FPGA_POST_CODE + select SOC_INTEL_COMMON_BLOCK_LPC_COMB_ENABLE + select TPM_MEASURED_BOOT + select TPM_MEASURED_BOOT_INIT_BOOTBLOCK + +config FMDFILE + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/mc_ehl.fmd" + +config UART_FOR_CONSOLE + int + default 0 + +config EARLY_PCI_BRIDGE_DEVICE + hex + depends on NC_FPGA_POST_CODE + default 0x1c + +config EARLY_PCI_BRIDGE_FUNCTION + hex + depends on NC_FPGA_POST_CODE + default 0x0 + +config EARLY_PCI_MMIO_BASE + hex + depends on NC_FPGA_POST_CODE + default 0xfe800000 + +endif # BOARD_SIEMENS_MC_EHL7 diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Makefile.mk b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Makefile.mk new file mode 100644 index 00000000000..d9050f098da --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/Makefile.mk @@ -0,0 +1,8 @@ +## SPDX-License-Identifier: GPL-2.0-only + +bootblock-y += gpio.c +romstage-y += memory.c +ramstage-y += gpio.c +ramstage-y += mainboard.c + +all-$(CONFIG_NC_FPGA_POST_CODE) += post.c diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb new file mode 100644 index 00000000000..fcd6de54630 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/devicetree.cb @@ -0,0 +1,193 @@ +chip soc/intel/elkhartlake + + device cpu_cluster 0 on end + + # GPE configuration + # Note that GPE events called out in ASL code rely on this + # route. i.e. If this route changes then the affected GPE + # offset bits also need to be changed. + register "pmc_gpe0_dw0" = "GPP_B" + register "pmc_gpe0_dw1" = "GPP_F" + register "pmc_gpe0_dw2" = "GPP_E" + + # FSP configuration + register "SaGv" = "SaGv_Disabled" + + # Enable IBECC for the complete memory + register "ibecc" = "{ + .enable = 1, + .mode = IBECC_ALL + }" + + # USB related UPDs + register "usb2_ports[0]" = "USB2_PORT_MID(OC2)" # X125/X135 + register "usb2_ports[1]" = "USB2_PORT_MID(OC2)" # X125/X135 + register "usb2_ports[2]" = "USB2_PORT_MID(OC0)" # X145/X155 + register "usb2_ports[3]" = "USB2_PORT_MID(OC0)" # X145/X155 + register "usb2_ports[4]" = "USB2_PORT_MID(OC3)" # USB Panel + register "usb2_ports[5]" = "USB2_PORT_MID(OC3)" # USB Panel + register "usb2_ports[6]" = "USB2_PORT_EMPTY" + register "usb2_ports[7]" = "USB2_PORT_EMPTY" + register "usb2_ports[8]" = "USB2_PORT_EMPTY" + register "usb2_ports[9]" = "USB2_PORT_EMPTY" + + register "usb3_ports[0]" = "USB3_PORT_DEFAULT(OC_SKIP)" # USB3/2 Type A port1 + register "usb3_ports[1]" = "USB3_PORT_DEFAULT(OC_SKIP)" # USB3/2 Type A port2 + register "usb3_ports[2]" = "USB3_PORT_EMPTY" # UNUSED + register "usb3_ports[3]" = "USB3_PORT_EMPTY" # UNUSED + + # Skip the CPU replacement check + register "SkipCpuReplacementCheck" = "1" + + # PCIe root ports related UPDs + register "PcieClkSrcUsage[0]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[1]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[2]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[3]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcUsage[4]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[5]" = "PCIE_CLK_FREE" + + register "PcieClkSrcClkReq[0]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[1]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[2]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[3]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[4]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[5]" = "PCIE_CLK_NOTUSED" + + # Disable all L1 substates for PCIe root ports + register "PcieRpL1Substates[0]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[1]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[2]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[4]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[6]" = "L1_SS_DISABLED" + + # Disable LTR for all PCIe root ports + register "PcieRpLtrDisable[0]" = "true" + register "PcieRpLtrDisable[1]" = "true" + register "PcieRpLtrDisable[2]" = "true" + register "PcieRpLtrDisable[4]" = "true" + register "PcieRpLtrDisable[6]" = "true" + + # Enable PCIe PTM (Precision Time Measurement) for all PCIe root ports + register "PciePtm[0]" = "true" + register "PciePtm[1]" = "true" + register "PciePtm[2]" = "true" + register "PciePtm[4]" = "true" + register "PciePtm[6]" = "true" + + # Determine PCIe root port speed + register "PcieRpPcieSpeed[6]" = "2" + + # Storage (SDCARD/EMMC) related UPDs + register "ScsEmmcHs400Enabled" = "0" + register "ScsEmmcDdr50Enabled" = "1" + register "SdCardPowerEnableActiveHigh" = "1" + + # GPIO for SD card detect + register "sdcard_cd_gpio" = "GPP_G5" + + # LPSS Serial IO (I2C/UART/GSPI) related UPDs + register "SerialIoI2cMode" = "{ + [PchSerialIoIndexI2C0] = PchSerialIoDisabled, + [PchSerialIoIndexI2C1] = PchSerialIoDisabled, + [PchSerialIoIndexI2C2] = PchSerialIoPci, + [PchSerialIoIndexI2C3] = PchSerialIoDisabled, + [PchSerialIoIndexI2C4] = PchSerialIoPci, + [PchSerialIoIndexI2C5] = PchSerialIoDisabled, + [PchSerialIoIndexI2C6] = PchSerialIoPci, + [PchSerialIoIndexI2C7] = PchSerialIoDisabled, + }" + + register "SerialIoI2cPadsTermination" = "{ + [PchSerialIoIndexI2C2] = 1, + [PchSerialIoIndexI2C4] = 1, + [PchSerialIoIndexI2C6] = 1, + }" + + register "SerialIoUartMode" = "{ + [PchSerialIoIndexUART0] = PchSerialIoPci, + [PchSerialIoIndexUART1] = PchSerialIoPci, + [PchSerialIoIndexUART2] = PchSerialIoPci, + }" + + register "SerialIoUartDmaEnable" = "{ + [PchSerialIoIndexUART0] = 1, + [PchSerialIoIndexUART1] = 1, + [PchSerialIoIndexUART2] = 1, + }" + + # TSN GBE related UPDs + register "PchTsnGbeLinkSpeed" = "Tsn_1_Gbps" + register "PchTsnGbeSgmiiEnable" = "1" + register "PseDmaOwn[0]" = "Host_Owned" + + # FIVR related settings + register "fivr" = "{ + .fivr_config_en = true, + .vcc_low_high_us = 50, + }" + + # Disable L1 prefetcher for real-time demands + register "L1_prefetcher_disable" = "true" + + # Enable real-time tuning + register "realtime_tuning_enable" = "true" + + device domain 0 on + device pci 00.0 on end # Host Bridge + device pci 02.0 on end # Integrated Graphics Device + + device pci 10.0 on # I2C6 + # Add dummy I2C device to limit BUS speed to 100 kHz in OS + chip drivers/i2c/generic + register "hid" = ""PRP0001"" + register "speed" = "I2C_SPEED_STANDARD" + device i2c 0x7f on end + end + end + + device pci 14.0 on end # USB3.1 xHCI + + device pci 15.2 on # I2C2 + # Add dummy I2C device to limit BUS speed to 100 kHz in OS + chip drivers/i2c/generic + register "hid" = ""PRP0001"" + register "speed" = "I2C_SPEED_STANDARD" + device i2c 0x7f on end + end + end + + device pci 16.0 hidden end # Management Engine Interface 1 + + device pci 19.0 on # I2C4 + # Add dummy I2C device to limit BUS speed to 100 kHz in OS + chip drivers/i2c/generic + register "hid" = ""PRP0001"" + register "speed" = "I2C_SPEED_STANDARD" + device i2c 0x7f on end + end + end + device pci 19.2 on end # UART2 + + device pci 1a.0 on end # eMMC + device pci 1a.1 on end # SD + + device pci 1c.0 on end # RP1 (pcie0 single VC) + device pci 1c.1 on end # RP2 (pcie0 single VC) + device pci 1c.2 on end # RP3 (pcie0 single VC) + device pci 1c.4 on end # RP5 (pcie1 multi VC) + device pci 1c.6 on end # RP7 (pcie3 multi VC) + + device pci 1e.0 on end # UART0 + device pci 1e.1 on end # UART1 + + device pci 1f.0 on # eSPI Interface + chip drivers/pc80/tpm + device pnp 0c31.0 on end + end + end + device pci 1f.2 hidden end # Power Management Controller + device pci 1f.4 on end # SMBus + device pci 1f.5 on end # PCH SPI (flash & TPM) + end +end diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/gpio.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/gpio.c new file mode 100644 index 00000000000..18997f7c0f6 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/gpio.c @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +/* Pad configuration in ramstage */ +static const struct pad_config gpio_table[] = { + /* Community 0 - GpioGroup GPP_B */ + PAD_CFG_NF(GPP_B2, NONE, PLTRST, NF1), /* PMC_VRALERT_N */ + PAD_CFG_NF(GPP_B3, NONE, PLTRST, NF4), /* ESPI_ALERT0_N */ + PAD_NC(GPP_B4, NONE), /* Not connected */ + PAD_NC(GPP_B9, NONE), /* Not connected */ + PAD_NC(GPP_B10, NONE), /* Not connected */ + PAD_CFG_NF(GPP_B11, NONE, PLTRST, NF1), /* PMC_ALERT_N */ + PAD_NC(GPP_B14, NONE), /* Not connected */ + PAD_NC(GPP_B15, NONE), /* Not connected */ + PAD_NC(GPP_B18, NONE), /* Not connected */ + PAD_NC(GPP_B19, NONE), /* Not connected */ + PAD_CFG_NF(GPP_B23, NONE, PLTRST, NF2), /* PCHHOT_N */ + + /* Community 0 - GpioGroup GPP_T */ + PAD_CFG_NF(GPP_T4, NONE, DEEP, NF1), /* PSE_GBE0_INT */ + PAD_CFG_GPO(GPP_T5, 1, DEEP), /* PSE_GBE0_RST_N */ + PAD_CFG_NF(GPP_T6, NONE, DEEP, NF1), /* PSE_GBE0_AUXTS */ + PAD_CFG_NF(GPP_T7, NONE, DEEP, NF1), /* PSE_GBE0_PPS */ + PAD_CFG_NF(GPP_T12, NONE, DEEP, NF2), /* SIO_UART0_RXD */ + PAD_CFG_NF(GPP_T13, NONE, DEEP, NF2), /* SIO_UART0_TXD */ + + /* Community 0 - GpioGroup GPP_G */ + PAD_CFG_NF(GPP_G5, UP_20K, DEEP, NF1), /* SD Card Detect */ + PAD_NC(GPP_G8, NONE), /* Not connected */ + PAD_NC(GPP_G9, NONE), /* Not connected */ + PAD_CFG_GPI(GPP_G19, UP_20K, PLTRST), /* TPM_IRQ_N */ + + /* Community 1 - GpioGroup GPP_V */ + PAD_CFG_NF(GPP_V0, UP_20K, DEEP, NF1), /* EMMC_CMD */ + PAD_CFG_NF(GPP_V1, UP_20K, DEEP, NF1), /* EMMC_DATA0 */ + PAD_CFG_NF(GPP_V2, UP_20K, DEEP, NF1), /* EMMC_DATA1 */ + PAD_CFG_NF(GPP_V3, UP_20K, DEEP, NF1), /* EMMC_DATA2 */ + PAD_CFG_NF(GPP_V4, UP_20K, DEEP, NF1), /* EMMC_DATA3 */ + PAD_CFG_NF(GPP_V5, UP_20K, DEEP, NF1), /* EMMC_DATA4 */ + PAD_CFG_NF(GPP_V6, UP_20K, DEEP, NF1), /* EMMC_DATA5 */ + PAD_CFG_NF(GPP_V7, UP_20K, DEEP, NF1), /* EMMC_DATA6 */ + PAD_CFG_NF(GPP_V8, UP_20K, DEEP, NF1), /* EMMC_DATA7 */ + PAD_CFG_NF(GPP_V9, DN_20K, DEEP, NF1), /* EMMC_RCLK */ + PAD_CFG_NF(GPP_V10, DN_20K, DEEP, NF1), /* EMMC_CLK */ + PAD_CFG_NF(GPP_V11, NONE, DEEP, NF1), /* EMMC_RESET */ + + /* Community 1 - GpioGroup GPP_H */ + PAD_CFG_NF(GPP_H10, NONE, DEEP, NF1), /* PCIE_CLKREQ4_N */ + PAD_CFG_NF(GPP_H11, NONE, DEEP, NF1), /* PCIE_CLKREQ5_N */ + + /* Community 1 - GpioGroup GPP_D */ + PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* PCIE_CLKREQ0_N */ + PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* PCIE_CLKREQ1_N */ + PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* PCIE_CLKREQ2_N */ + PAD_CFG_NF(GPP_D8, NONE, DEEP, NF1), /* PCIE_CLKREQ3_N */ + + /* Community 1 - GpioGroup GPP_U */ + PAD_CFG_NF(GPP_U0, NONE, DEEP, NF1), /* GBE_INT */ + PAD_CFG_GPO(GPP_U1, 1, DEEP), /* GBE_RST_N */ + PAD_NC(GPP_U12, NONE), /* Not connected */ + PAD_NC(GPP_U13, NONE), /* Not connected */ + PAD_NC(GPP_U16, NONE), /* Not connected */ + PAD_NC(GPP_U17, NONE), /* Not connected */ + PAD_NC(GPP_U18, NONE), /* Not connected */ + + /* Community 2 - GpioGroup DSW */ + PAD_CFG_NF(GPD1, NONE, PLTRST, NF1), /* ACPRESENT */ + PAD_NC(GPD9, NONE), /* Not connected */ + PAD_NC(GPD11, NONE), /* Not connected */ + + /* Community 3 - GpioGroup GPP_S */ + PAD_NC(GPP_S0, NONE), /* Not connected */ + PAD_NC(GPP_S1, NONE), /* Not connected */ + + /* Community 3 - GpioGroup GPP_A */ + PAD_CFG_NF(GPP_A0, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD3 */ + PAD_CFG_NF(GPP_A1, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD2 */ + PAD_CFG_NF(GPP_A2, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD1 */ + PAD_CFG_NF(GPP_A3, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD0 */ + PAD_CFG_NF(GPP_A4, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXCLK */ + PAD_CFG_NF(GPP_A5, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXCTL */ + PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXCLK */ + PAD_CFG_NF(GPP_A7, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD3 */ + PAD_CFG_NF(GPP_A8, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD2 */ + PAD_CFG_NF(GPP_A9, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD1 */ + PAD_CFG_NF(GPP_A10, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD0 */ + PAD_CFG_NF(GPP_A23, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXCTL */ + + /* Community 4 - GpioGroup GPP_C */ + PAD_CFG_NF(GPP_C3, NONE, DEEP, NF1), /* PSE_GBE0_MDC */ + PAD_CFG_NF(GPP_C4, NONE, DEEP, NF1), /* PSE_GBE0_MDIO */ + PAD_NC(GPP_C8, NONE), /* Not connected */ + PAD_CFG_NF(GPP_C12, NONE, DEEP, NF4), /* SIO_UART1_RXD */ + PAD_CFG_NF(GPP_C13, NONE, DEEP, NF4), /* SIO_UART1_TXD */ + PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), /* GBE_MDIO */ + PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), /* GBE_MDC */ + + /* Community 4 - GpioGroup GPP_F */ + PAD_NC(GPP_F1, NONE), /* Not connected */ + PAD_NC(GPP_F3, NONE), /* Not connected */ + PAD_NC(GPP_F8, NONE), /* Not connected */ + PAD_NC(GPP_F11, NONE), /* Not connected */ + PAD_NC(GPP_F12, NONE), /* Not connected */ + PAD_NC(GPP_F13, NONE), /* Not connected */ + PAD_NC(GPP_F14, NONE), /* Not connected */ + PAD_NC(GPP_F15, NONE), /* Not connected */ + PAD_NC(GPP_F16, NONE), /* Not connected */ + PAD_NC(GPP_F17, NONE), /* Not connected */ + PAD_CFG_GPO(GPP_F20, 0, DEEP), /* LED_BIOS_DONE */ + + /* Community 4 - GpioGroup GPP_E */ + PAD_NC(GPP_E15, NONE), /* Not connected */ + PAD_NC(GPP_E16, NONE), /* Not connected */ + PAD_NC(GPP_E18, NONE), /* Not connected */ + PAD_NC(GPP_E19, NONE), /* Not connected */ + PAD_NC(GPP_E23, NONE), /* Not connected */ + + /* Community 5 - GpioGroup GPP_R */ + PAD_NC(GPP_R1, NONE), /* Not connected */ + PAD_NC(GPP_R3, NONE), /* Not connected */ +}; + +/* Early pad configuration in bootblock */ +static const struct pad_config early_gpio_table[] = {}; + +const struct pad_config *variant_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(gpio_table); + return gpio_table; +} + +const struct pad_config *variant_early_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(early_gpio_table); + return early_gpio_table; +} diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/mainboard.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/mainboard.c new file mode 100644 index 00000000000..b3846196fc9 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/mainboard.c @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include + +#define HOSTCTRL2 0x3E +#define HOSTCTRL2_PRESET (1 << 15) +#define MMC_CAP_BYP 0x810 +#define MMC_CAP_BYP_EN 0x5A +#define MMC_CAP_BYP_REG1 0x814 +#define MMC_CAP_BYP_SDR50 (1 << 13) +#define MMC_CAP_BYP_SDR104 (1 << 14) +#define MMC_CAP_BYP_DDR50 (1 << 15) + +/* Disable SDR104 and SDR50 mode while keeping DDR50 mode enabled. */ +static void disable_sdr_modes(struct resource *res) +{ + write32(res2mmio(res, MMC_CAP_BYP, 0), MMC_CAP_BYP_EN); + clrsetbits32(res2mmio(res, MMC_CAP_BYP_REG1, 0), + MMC_CAP_BYP_SDR104 | MMC_CAP_BYP_SDR50, + MMC_CAP_BYP_DDR50); +} + +void variant_mainboard_final(void) +{ + struct device *dev; + + /* PIR8 register mapping for PCIe root ports + INTA#->PIRQC#, INTB#->PIRQD#, INTC#->PIRQA#, INTD#-> PIRQB# */ + pcr_write16(PID_ITSS, 0x3150, 0x1032); + + /* Disable clock outputs 1-5 (CLKOUT) for XIO2001 PCIe to PCI Bridge. */ + dev = dev_find_device(PCI_VID_TI, PCI_DID_TI_XIO2001, 0); + if (dev) + pci_write_config8(dev, 0xd8, 0x3e); + + dev = pcidev_path_on_root(PCH_DEVFN_SDCARD); + if (dev) { + struct resource *res = probe_resource(dev, PCI_BASE_ADDRESS_0); + if (res) { + disable_sdr_modes(res); + + /* Use preset driver strength from preset value + registers. */ + clrsetbits16(res2mmio(res, HOSTCTRL2, 0), 0, + HOSTCTRL2_PRESET); + } + } + + dev = pcidev_path_on_root(PCH_DEVFN_EMMC); + if (dev) { + struct resource *res = probe_resource(dev, PCI_BASE_ADDRESS_0); + if (res) + disable_sdr_modes(res); + } +} + +static void finalize_boot(void *unused) +{ + /* Set coreboot ready LED. */ + gpio_output(GPP_F20, 1); +} + +BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, finalize_boot, NULL); diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/memory.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/memory.c new file mode 100644 index 00000000000..551583394b6 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/memory.c @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +static const struct mb_cfg mc_ehl_lpddr4x_memcfg_cfg = { + .dq_map[DDR_CH0] = { + {0xf, 0xf0}, {0xf, 0xf0}, {0xff, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0} + }, + + .dq_map[DDR_CH1] = { + {0xf, 0xf0}, {0xf, 0xf0}, {0xff, 0x0}, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0} + }, + + /* + * The dqs_map arrays map the ddr4 pins to the SoC pins + * for both channels. + * + * the index = pin number on ddr4 part + * the value = pin number on SoC + */ + .dqs_map[DDR_CH0] = {3, 0, 1, 2, 7, 4, 5, 6}, + .dqs_map[DDR_CH1] = {3, 0, 1, 2, 7, 4, 5, 6}, + + /* Baseboard uses 100, 100 and 100 rcomp resistors */ + .rcomp_resistor = {100, 100, 100}, + + .rcomp_targets = {60, 40, 30, 20, 30}, + + /* LPDDR4x does not allow interleaved memory */ + .dq_pins_interleaved = 0, + + /* Baseboard is using config 2 for vref_ca */ + .vref_ca_config = 2, + + /* Enable Early Command Training */ + .ect = 1, + + /* Set Board Type */ + .UserBd = BOARD_TYPE_MOBILE, +}; + +const struct mb_cfg *variant_memcfg_config(void) +{ + return &mc_ehl_lpddr4x_memcfg_cfg; +} diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/post.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/post.c new file mode 100644 index 00000000000..c34e2539bc2 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl7/post.c @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +void mainboard_post(uint8_t value) +{ + nc_fpga_post(value); +} diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig new file mode 100644 index 00000000000..4160e7bc227 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Kconfig @@ -0,0 +1,42 @@ +## SPDX-License-Identifier: GPL-2.0-only + +if BOARD_SIEMENS_MC_EHL8 + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select DRIVER_INTEL_I210 + select DRIVERS_I2C_PI608GP + select DRIVERS_I2C_RV3028C7 + select NC_FPGA_POST_CODE + select MAINBOARD_HAS_TPM2 + select MEMORY_MAPPED_TPM + select SOC_INTEL_COMMON_BLOCK_LPC_COMB_ENABLE + select TPM_MEASURED_BOOT + select TPM_MEASURED_BOOT_INIT_BOOTBLOCK + +config FMDFILE + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/mc_ehl.fmd" + +config UART_FOR_CONSOLE + int + default 0 + +config EARLY_PCI_BRIDGE_DEVICE + hex + depends on NC_FPGA_POST_CODE + default 0x1c + +config EARLY_PCI_BRIDGE_FUNCTION + hex + depends on NC_FPGA_POST_CODE + default 0x2 + +config EARLY_PCI_MMIO_BASE + hex + depends on NC_FPGA_POST_CODE + default 0xfe800000 + +config SOC_INTEL_ELKHARTLAKE_TCO_NO_REBOOT_EN + default y + +endif # BOARD_SIEMENS_MC_EHL8 diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Makefile.mk b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Makefile.mk new file mode 100644 index 00000000000..2b78a7a75fb --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/Makefile.mk @@ -0,0 +1,7 @@ +## SPDX-License-Identifier: GPL-2.0-only + +bootblock-y += gpio.c +romstage-y += memory.c +ramstage-y += gpio.c + +all-$(CONFIG_NC_FPGA_POST_CODE) += post.c diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb new file mode 100644 index 00000000000..34cf91baa2c --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/devicetree.cb @@ -0,0 +1,202 @@ +chip soc/intel/elkhartlake + + device cpu_cluster 0 on end + + # GPE configuration + # Note that GPE events called out in ASL code rely on this + # route. i.e. If this route changes then the affected GPE + # offset bits also need to be changed. + register "pmc_gpe0_dw0" = "GPP_B" + register "pmc_gpe0_dw1" = "GPP_F" + register "pmc_gpe0_dw2" = "GPP_E" + + # FSP configuration + register "SaGv" = "SaGv_Disabled" + + # Enable IBECC for the complete memory + register "ibecc" = "{ + .enable = 1, + .mode = IBECC_ALL + }" + + # USB related UPDs + register "usb2_ports[0]" = "USB2_PORT_SHORT(OC_SKIP)" # USB3/2 Type A port 1 + register "usb2_ports[1]" = "USB2_PORT_SHORT(OC_SKIP)" # USB3/2 Type A Port 2 + register "usb2_ports[2]" = "USB2_PORT_MID(OC_SKIP)" # Onboard USB + register "usb2_ports[3]" = "USB2_PORT_EMPTY" # Port is unused + register "usb2_ports[4]" = "USB2_PORT_EMPTY" # Port is unused + register "usb2_ports[5]" = "USB2_PORT_EMPTY" # Port is unused + register "usb2_ports[6]" = "USB2_PORT_EMPTY" # Port is unused + register "usb2_ports[7]" = "USB2_PORT_EMPTY" # Port is unused + register "usb2_ports[8]" = "USB2_PORT_EMPTY" # Port is unused + register "usb2_ports[9]" = "USB2_PORT_EMPTY" # Port is unused + + register "usb3_ports[0]" = "USB3_PORT_DEFAULT(OC_SKIP)" # USB3/2 Type A port1 + register "usb3_ports[1]" = "USB3_PORT_DEFAULT(OC_SKIP)" # USB3/2 Type A port2 + register "usb3_ports[2]" = "USB3_PORT_EMPTY" # Port is not used + register "usb3_ports[3]" = "USB3_PORT_EMPTY" # Port is not used + + # Skip the CPU replacement check + register "SkipCpuReplacementCheck" = "1" + + # PCIe root ports related UPDs + register "PcieClkSrcUsage[0]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[1]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[2]" = "PCIE_CLK_FREE" + register "PcieClkSrcUsage[3]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcUsage[4]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcUsage[5]" = "PCIE_CLK_NOTUSED" + + register "PcieClkSrcClkReq[0]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[1]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[2]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[3]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[4]" = "PCIE_CLK_NOTUSED" + register "PcieClkSrcClkReq[5]" = "PCIE_CLK_NOTUSED" + + # Disable all L1 substates for PCIe root ports + register "PcieRpL1Substates[2]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[3]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[4]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[5]" = "L1_SS_DISABLED" + register "PcieRpL1Substates[6]" = "L1_SS_DISABLED" + + # Disable LTR for all PCIe root ports + register "PcieRpLtrDisable[2]" = "true" + register "PcieRpLtrDisable[3]" = "true" + register "PcieRpLtrDisable[4]" = "true" + register "PcieRpLtrDisable[5]" = "true" + register "PcieRpLtrDisable[6]" = "true" + + # Enable PCIe PTM (Precision Time Measurement) for all PCIe root ports + register "PciePtm[2]" = "true" + register "PciePtm[3]" = "true" + register "PciePtm[4]" = "true" + register "PciePtm[5]" = "true" + register "PciePtm[6]" = "true" + + # Determine PCIe root port speed + register "PcieRpPcieSpeed[5]" = "2" + + # Storage (SATA/SDCARD/EMMC) related UPDs + register "SataSalpSupport" = "0" + register "SataPortsEnable[0]" = "1" + register "SataPortsEnable[1]" = "1" + register "SataPortsDevSlp[0]" = "0" + register "SataPortsDevSlp[1]" = "0" + register "SataPortsSSD[0]" = "1" + register "SataPortsSSD[1]" = "1" + register "SataSpeed" = "SATA_GEN2" + + register "ScsEmmcHs400Enabled" = "0" + register "ScsEmmcDdr50Enabled" = "1" + register "SdCardPowerEnableActiveHigh" = "1" + + # LPSS Serial IO (I2C/UART/GSPI) related UPDs + register "SerialIoI2cMode" = "{ + [PchSerialIoIndexI2C0] = PchSerialIoDisabled, + [PchSerialIoIndexI2C1] = PchSerialIoDisabled, + [PchSerialIoIndexI2C2] = PchSerialIoPci, + [PchSerialIoIndexI2C3] = PchSerialIoDisabled, + [PchSerialIoIndexI2C4] = PchSerialIoPci, + [PchSerialIoIndexI2C5] = PchSerialIoDisabled, + [PchSerialIoIndexI2C6] = PchSerialIoPci, + [PchSerialIoIndexI2C7] = PchSerialIoDisabled, + }" + + register "SerialIoI2cPadsTermination" = "{ + [PchSerialIoIndexI2C2] = 1, + [PchSerialIoIndexI2C4] = 1, + [PchSerialIoIndexI2C6] = 1, + }" + + register "SerialIoUartMode" = "{ + [PchSerialIoIndexUART0] = PchSerialIoPci, + [PchSerialIoIndexUART1] = PchSerialIoPci, + [PchSerialIoIndexUART2] = PchSerialIoSkipInit, + }" + + register "SerialIoUartDmaEnable" = "{ + [PchSerialIoIndexUART0] = 1, + [PchSerialIoIndexUART1] = 1, + [PchSerialIoIndexUART2] = 1, + }" + + # TSN GBE related UPDs + register "PchTsnGbeLinkSpeed" = "Tsn_2_5_Gbps" + register "PchTsnGbeSgmiiEnable" = "1" + + # FIVR related settings + register "fivr" = "{ + .fivr_config_en = true, + .vcc_low_high_us = 50, + }" + + # Disable L1 prefetcher + register "L1_prefetcher_disable" = "true" + + # Enable real-time tuning + register "realtime_tuning_enable" = "true" + + device domain 0 on + device pci 00.0 on end # Host Bridge + device pci 02.0 on end # Integrated Graphics Device + + device pci 10.0 on end # I2C6 + + device pci 14.0 on end # USB3.1 xHCI + + device pci 15.0 off end # I2C0 + device pci 15.2 on end # I2C2 + + device pci 16.0 hidden end # Management Engine Interface 1 + + device pci 17.0 on end # SATA + + device pci 19.0 on end # I2C4 + device pci 19.2 on end # UART2 + + device pci 1a.0 on end # eMMC + + device pci 1c.2 on end # RP3 (pcie0 single VC) + device pci 1c.3 on end # RP4 (pcie0 single VC) + device pci 1c.4 on end # RP5 (pcie1 multi VC) + device pci 1c.5 on end # RP6 (pcie2 multi VC) + device pci 1c.6 on end # RP7 (pcie3 multi VC) + + device pci 1e.0 on end # UART0 + device pci 1e.1 on end # UART1 + + + device pci 1f.0 on # eSPI Interface + chip drivers/pc80/tpm + device pnp 0c31.0 on end + end + end + device pci 1f.2 hidden end # Power Management Controller + device pci 1f.4 on # SMBus + # Enable external RTC chip + chip drivers/i2c/rv3028c7 + register "bus_speed" = "I2C_SPEED_STANDARD" + register "set_user_date" = "1" + register "user_year" = "04" + register "user_month" = "07" + register "user_day" = "01" + register "user_weekday" = "4" + register "bckup_sw_mode" = "BACKUP_SW_LEVEL" + register "cap_charge" = "CHARGE_OFF" + device i2c 0x52 on end # RTC RV3028-C7 + end + # PI7C9X2G608GP PCIe switch configuration + chip drivers/i2c/pi608gp + register "gen2_3p5_enable" = "true" + register "gen2_3p5_amp" = "AMP_LVL_MV(425)" + register "gen2_3p5_deemph" = "DEEMPH_LVL_MV(6, 0)" + device i2c 0x6f on + ops pi608gp_ops + end + end + end + device pci 1f.5 on end # PCH SPI (flash & TPM) + end +end diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/gpio.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/gpio.c new file mode 100644 index 00000000000..ea814a09ac1 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/gpio.c @@ -0,0 +1,178 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +/* Pad configuration in ramstage */ +static const struct pad_config gpio_table[] = { + /* Community 0 - GpioGroup GPP_B */ + PAD_CFG_NF(GPP_B2, NONE, PLTRST, NF1), /* PMC_VRALERT_N */ + PAD_CFG_NF(GPP_B3, NONE, PLTRST, NF4), /* ESPI_ALERT0_N */ + PAD_CFG_NF(GPP_B4, NONE, PLTRST, NF4), /* ESPI_ALERT1_N */ + PAD_NC(GPP_B9, NONE), /* Not connected */ + PAD_NC(GPP_B10, NONE), /* Not connected */ + PAD_CFG_NF(GPP_B11, NONE, PLTRST, NF1), /* PMC_ALERT_N */ + PAD_NC(GPP_B14, NONE), /* Not connected */ + PAD_CFG_NF(GPP_B15, NONE, PLTRST, NF5), /* ESPI_CS1_N */ + PAD_NC(GPP_B18, NONE), /* Not connected */ + PAD_NC(GPP_B19, NONE), /* Not connected */ + PAD_NC(GPP_B20, NONE), /* Not connected */ + PAD_NC(GPP_B21, NONE), /* Not connected */ + PAD_NC(GPP_B22, NONE), /* Not connected */ + PAD_NC(GPP_B23, NONE), /* Not connected */ + + /* Community 0 - GpioGroup GPP_T */ + PAD_CFG_NF(GPP_T4, UP_20K, DEEP, NF1), /* PSE_GBE0_INT */ + PAD_CFG_NF(GPP_T5, DN_20K, DEEP, NF1), /* PSE_GBE0_RST_N */ + PAD_CFG_NF(GPP_T6, NONE, DEEP, NF1), /* PSE_GBE0_AUXTS */ + PAD_CFG_NF(GPP_T7, NONE, DEEP, NF1), /* PSE_GBE0_PPS */ + PAD_CFG_NF(GPP_T12, NONE, DEEP, NF2), /* SIO_UART0_RXD */ + PAD_CFG_NF(GPP_T13, NONE, DEEP, NF2), /* SIO_UART0_TXD */ + + /* Community 0 - GpioGroup GPP_G */ + PAD_NC(GPP_G8, NONE), /* Not connected */ + PAD_NC(GPP_G9, NONE), /* Not connected */ + PAD_NC(GPP_G12, NONE), /* Not connected */ + PAD_CFG_NF(GPP_G15, NONE, DEEP, NF1), /* ESPI_IO_0 */ + PAD_CFG_NF(GPP_G16, NONE, DEEP, NF1), /* ESPI_IO_1 */ + PAD_CFG_NF(GPP_G17, NONE, DEEP, NF1), /* ESPI_IO_2 */ + PAD_CFG_NF(GPP_G18, NONE, DEEP, NF1), /* ESPI_IO_3 */ + PAD_CFG_GPI(GPP_G19, UP_20K, PLTRST), /* TPM_IRQ_N */ + PAD_CFG_NF(GPP_G20, NONE, DEEP, NF1), /* ESPI_CSO_N */ + PAD_CFG_NF(GPP_G21, NONE, DEEP, NF1), /* ESPI_CLK */ + PAD_CFG_NF(GPP_G22, NONE, DEEP, NF1), /* ESPI_RST0_N */ + + /* Community 1 - GpioGroup GPP_V */ + PAD_CFG_NF(GPP_V0, UP_20K, DEEP, NF1), /* EMMC_CMD */ + PAD_CFG_NF(GPP_V1, UP_20K, DEEP, NF1), /* EMMC_DATA0 */ + PAD_CFG_NF(GPP_V2, UP_20K, DEEP, NF1), /* EMMC_DATA1 */ + PAD_CFG_NF(GPP_V3, UP_20K, DEEP, NF1), /* EMMC_DATA2 */ + PAD_CFG_NF(GPP_V4, UP_20K, DEEP, NF1), /* EMMC_DATA3 */ + PAD_CFG_NF(GPP_V5, UP_20K, DEEP, NF1), /* EMMC_DATA4 */ + PAD_CFG_NF(GPP_V6, UP_20K, DEEP, NF1), /* EMMC_DATA5 */ + PAD_CFG_NF(GPP_V7, UP_20K, DEEP, NF1), /* EMMC_DATA6 */ + PAD_CFG_NF(GPP_V8, UP_20K, DEEP, NF1), /* EMMC_DATA7 */ + PAD_CFG_NF(GPP_V9, DN_20K, DEEP, NF1), /* EMMC_RCLK */ + PAD_CFG_NF(GPP_V10, DN_20K, DEEP, NF1), /* EMMC_CLK */ + PAD_CFG_NF(GPP_V11, NONE, DEEP, NF1), /* EMMC_RESET_N */ + + /* Community 1 - GpioGroup GPP_H */ + PAD_CFG_NF(GPP_H0, DN_20K, DEEP, NF1), /* PSE_GBE1_INT */ + PAD_CFG_NF(GPP_H1, DN_20K, DEEP, NF1), /* PSE_GBE1_RST_N */ + PAD_CFG_NF(GPP_H2, NONE, DEEP, NF1), /* PSE_GBE1_AUXTS */ + PAD_CFG_NF(GPP_H3, NONE, DEEP, NF1), /* PSE_GBE1_PPS */ + PAD_CFG_NF(GPP_H8, UP_20K, DEEP, NF1), /* SIO_I2C4_SDA */ + PAD_CFG_NF(GPP_H9, UP_20K, DEEP, NF1), /* SIO_I2C4_SCL */ + + /* Community 1 - GpioGroup GPP_D */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* EMMC_PWR_EN_N */ + + /* Community 1 - GpioGroup GPP_U */ + PAD_CFG_NF(GPP_U0, DN_20K, DEEP, NF1), /* GBE_INT */ + PAD_CFG_NF(GPP_U1, DN_20K, DEEP, NF1), /* GBE_RST_N */ + PAD_CFG_NF(GPP_U2, NONE, DEEP, NF1), /* GBE_PPS */ + PAD_CFG_NF(GPP_U3, NONE, DEEP, NF1), /* GBE_AUXTS */ + PAD_NC(GPP_U12, NONE), /* Not connected */ + PAD_NC(GPP_U13, NONE), /* Not connected */ + PAD_NC(GPP_U16, NONE), /* Not connected */ + PAD_NC(GPP_U17, NONE), /* Not connected */ + PAD_NC(GPP_U18, NONE), /* Not connected */ + PAD_CFG_GPO(GPP_U19, 1, DEEP), /* UPD_REQ_N */ + + /* Community 2 - GpioGroup DSW */ + PAD_CFG_NF(GPD4, NONE, PLTRST, NF1), /* SLP_S3 */ + PAD_CFG_NF(GPD5, NONE, PLTRST, NF1), /* SLP_S4 */ + PAD_NC(GPD7, NONE), /* Not connected */ + PAD_CFG_NF(GPD10, NONE, PLTRST, NF1), /* SLP_S5 */ + + /* Community 3 - GpioGroup GPP_S */ + PAD_NC(GPP_S0, NONE), /* Not connected */ + PAD_NC(GPP_S1, NONE), /* Not connected */ + + /* Community 3 - GpioGroup GPP_A */ + PAD_CFG_NF(GPP_A0, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD3 */ + PAD_CFG_NF(GPP_A1, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD2 */ + PAD_CFG_NF(GPP_A2, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD1 */ + PAD_CFG_NF(GPP_A3, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXD0 */ + PAD_CFG_NF(GPP_A4, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXCLK */ + PAD_CFG_NF(GPP_A5, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_TXCTL */ + PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXCLK */ + PAD_CFG_NF(GPP_A7, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD3 */ + PAD_CFG_NF(GPP_A8, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD2 */ + PAD_CFG_NF(GPP_A9, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD1 */ + PAD_CFG_NF(GPP_A10, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXD0 */ + PAD_CFG_NF(GPP_A23, NONE, DEEP, NF1), /* PSE_GBE0_RGMII_RXCTL */ + + /* Community 4 - GpioGroup GPP_C */ + PAD_CFG_NF(GPP_C3, NONE, DEEP, NF1), /* PSE_GBE0_MDC */ + PAD_CFG_NF(GPP_C4, NONE, DEEP, NF1), /* PSE_GBE0_MDIO */ + PAD_NC(GPP_C5, NONE), /* Not connected */ + PAD_CFG_NF(GPP_C6, NONE, DEEP, NF1), /* PSE_GBE1_MDC */ + PAD_CFG_NF(GPP_C7, NONE, DEEP, NF1), /* PSE_GBE1_MDIO */ + PAD_NC(GPP_C8, NONE), /* Not connected */ + PAD_CFG_NF(GPP_C12, NONE, DEEP, NF4), /* SIO_UART1_RXD */ + PAD_CFG_NF(GPP_C13, NONE, DEEP, NF4), /* SIO_UART1_TXD */ + PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), /* GBE_MDIO */ + PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), /* GBE_MDC */ + PAD_CFG_NF(GPP_C18, NONE, DEEP, NF4), /* SIO_I2C1_SDA */ + PAD_CFG_NF(GPP_C19, NONE, DEEP, NF4), /* SIO_I2C1_SCL */ + + /* Community 4 - GpioGroup GPP_F */ + PAD_NC(GPP_F0, NONE), /* Not connected */ + PAD_NC(GPP_F1, NONE), /* Not connected */ + PAD_NC(GPP_F2, NONE), /* Not connected */ + PAD_NC(GPP_F3, NONE), /* Not connected */ + PAD_NC(GPP_F4, NONE), /* Not connected */ + PAD_NC(GPP_F5, NONE), /* Not connected */ + PAD_NC(GPP_F7, NONE), /* Not connected */ + PAD_NC(GPP_F8, NONE), /* Not connected */ + PAD_NC(GPP_F10, NONE), /* Not connected */ + PAD_NC(GPP_F11, NONE), /* Not connected */ + PAD_NC(GPP_F12, NONE), /* Not connected */ + PAD_NC(GPP_F13, NONE), /* Not connected */ + PAD_NC(GPP_F14, NONE), /* Not connected */ + PAD_NC(GPP_F15, NONE), /* Not connected */ + PAD_NC(GPP_F16, NONE), /* Not connected */ + PAD_NC(GPP_F17, NONE), /* Not connected */ + PAD_NC(GPP_F20, NONE), /* Not connected */ + PAD_NC(GPP_F21, NONE), /* Not connected */ + + /* Community 4 - GpioGroup GPP_E */ + PAD_CFG_NF(GPP_E0, NONE, DEEP, NF1), /* SATA_LED_N */ + PAD_CFG_NF(GPP_E3, NONE, DEEP, NF1), /* DDI1_HPD */ + PAD_CFG_NF(GPP_E5, NONE, DEEP, NF1), /* DDI1_DDC_SDA */ + PAD_NC(GPP_E6, NONE), /* Not connected */ + PAD_CFG_NF(GPP_E7, NONE, DEEP, NF1), /* DDI1_DDC_SCL */ + PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), /* DDI0_HPD */ + PAD_NC(GPP_E15, NONE), /* Not connected */ + PAD_NC(GPP_E16, NONE), /* Not connected */ + PAD_CFG_NF(GPP_E18, NONE, DEEP, NF1), /* DDI0_DDC_SDA */ + PAD_CFG_NF(GPP_E19, NONE, DEEP, NF1), /* DDI0_DDC_SCL */ + PAD_NC(GPP_E23, NONE), /* Not connected */ + + /* Community 5 - GpioGroup GPP_R */ + PAD_NC(GPP_R1, NONE), /* Not connected */ + PAD_NC(GPP_R2, NONE), /* Not connected */ + PAD_NC(GPP_R3, NONE), /* Not connected */ +}; + +/* Early pad configuration in bootblock */ +static const struct pad_config early_gpio_table[] = { + PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* SMB_CLK */ + PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* SMB_DATA */ + PAD_CFG_NF(GPP_C2, NONE, DEEP, NF2), /* SMB_ALERT_N */ + PAD_CFG_NF(GPP_C20, NONE, DEEP, NF4), /* SIO_UART2_RXD */ + PAD_CFG_NF(GPP_C21, NONE, DEEP, NF4), /* SIO_UART2_TXD */ +}; + +const struct pad_config *variant_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(gpio_table); + return gpio_table; +} + +const struct pad_config *variant_early_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(early_gpio_table); + return early_gpio_table; +} diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/memory.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/memory.c new file mode 100644 index 00000000000..a800d30ef1a --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/memory.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +static const struct mb_cfg mc_ehl_lpddr4x_memcfg_cfg = { + .dq_map[DDR_CH0] = { + {0xf, 0xf0}, + {0xf, 0xf0}, + {0xff, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0} + }, + + .dq_map[DDR_CH1] = { + {0xf, 0xf0}, + {0xf, 0xf0}, + {0xff, 0x0}, + {0x0, 0x0}, + {0x0, 0x0}, + {0x0, 0x0} + }, + + /* + * The dqs_map arrays map the ddr4 pins to the SoC pins + * for both channels. + * + * the index = pin number on ddr4 part + * the value = pin number on SoC + */ + .dqs_map[DDR_CH0] = {3, 0, 1, 2, 7, 4, 5, 6}, + .dqs_map[DDR_CH1] = {3, 0, 1, 2, 7, 4, 5, 6}, + + /* Baseboard uses 100, 100 and 100 rcomp resistors */ + .rcomp_resistor = {100, 100, 100}, + + .rcomp_targets = {60, 40, 30, 20, 30}, + + /* LPDDR4x does not allow interleaved memory */ + .dq_pins_interleaved = 0, + + /* Baseboard is using config 2 for vref_ca */ + .vref_ca_config = 2, + + /* Enable Early Command Training */ + .ect = 1, + + /* Set Board Type */ + .UserBd = BOARD_TYPE_MOBILE, +}; + +const struct mb_cfg *variant_memcfg_config(void) +{ + return &mc_ehl_lpddr4x_memcfg_cfg; +} diff --git a/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/post.c b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/post.c new file mode 100644 index 00000000000..c34e2539bc2 --- /dev/null +++ b/src/mainboard/siemens/mc_ehl/variants/mc_ehl8/post.c @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +void mainboard_post(uint8_t value) +{ + nc_fpga_post(value); +} diff --git a/src/mainboard/starlabs/adl/Kconfig b/src/mainboard/starlabs/adl/Kconfig new file mode 100644 index 00000000000..479ec79165e --- /dev/null +++ b/src/mainboard/starlabs/adl/Kconfig @@ -0,0 +1,183 @@ +config BOARD_STARLABS_ADL_SERIES + def_bool n + select AZALIA_USE_LEGACY_VERB_TABLE + select BOARD_ROMSIZE_KB_16384 + select CSE_DEFAULT_CFR_OPTION_STATE_DISABLED + select DRIVERS_EFI_VARIABLE_STORE + select DRIVERS_INTEL_PMC + select DRIVERS_OPTION_CFR_ENABLED + select EC_STARLABS_MERLIN + select HAVE_ACPI_RESUME + select HAVE_ACPI_TABLES + select INTEL_GMA_HAVE_VBT + select INTEL_LPSS_UART_FOR_CONSOLE + select NO_UART_ON_SUPERIO + select PMC_IPC_ACPI_INTERFACE + select SOC_INTEL_ALDERLAKE + select SOC_INTEL_COMMON_BLOCK_HDA_VERB + select SOC_INTEL_COMMON_BLOCK_TCSS + select SOC_INTEL_CRASHLOG + select SPD_READ_BY_WORD + select SPI_FLASH_WINBOND + select STARLABS_NVME_POWER_SEQUENCE + select TPM2 + select VALIDATE_INTEL_DESCRIPTOR + +config BOARD_STARLABS_ADL_HORIZON + select BOARD_STARLABS_ADL_SERIES + select DRIVERS_GFX_GENERIC + select DRIVERS_I2C_HID + select HAVE_HDA_DMIC + select HAVE_SPD_IN_CBFS + select MAINBOARD_HAS_TPM2 + select MEMORY_MAPPED_TPM + select SOC_INTEL_ALDERLAKE_PCH_N + select SYSTEM_TYPE_LAPTOP + select TPM_MEASURED_BOOT + +config BOARD_STARLABS_LITE_ADL + select BOARD_STARLABS_ADL_SERIES + select CRB_TPM + select DRIVERS_GFX_GENERIC + select DRIVERS_I2C_HID + select HAVE_HDA_DMIC + select HAVE_INTEL_PTT + select HAVE_SPD_IN_CBFS + select SOC_INTEL_ALDERLAKE_PCH_N + select SYSTEM_TYPE_DETACHABLE + +config BOARD_STARLABS_BYTE_ADL + select BOARD_STARLABS_ADL_SERIES + select CRB_TPM + select DRIVERS_PCIE_GENERIC + select EC_STARLABS_FAN + select HAVE_INTEL_PTT + select SOC_INTEL_ALDERLAKE_PCH_N + select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES + select SYSTEM_TYPE_MINIPC + +config BOARD_STARLABS_BYTE_TWL + select BOARD_STARLABS_ADL_SERIES + select CRB_TPM + select DRIVERS_PCIE_GENERIC + select EC_STARLABS_FAN + select HAVE_INTEL_PTT + select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES + select SOC_INTEL_TWINLAKE + select SYSTEM_TYPE_MINIPC + +if BOARD_STARLABS_ADL_SERIES + +config CONSOLE_SERIAL + default n if !EDK2_DEBUG + +config D3COLD_SUPPORT + default n + +config DEVICETREE + default "variants/\$(CONFIG_VARIANT_DIR)/devicetree.cb" + +config DIMM_SPD_SIZE + default 512 + +config EDK2_BOOTSPLASH_FILE + string + default "3rdparty/blobs/mainboard/starlabs/Logo.bmp" + +config EC_STARLABS_ITE_BIN_PATH + string + default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/ec.bin" + +config FMDFILE + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/vboot.fmd" if VBOOT + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" + +config IFD_BIN_PATH + string + default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/flashdescriptor.bin" + +config MAINBOARD_DIR + default "starlabs/adl" + +config MAINBOARD_FAMILY + string + default "HZ" if BOARD_STARLABS_ADL_HORIZON + default "I5" if BOARD_STARLABS_LITE_ADL + default "Y3" if BOARD_STARLABS_BYTE_TWL + default "Y2" if BOARD_STARLABS_BYTE_ADL + +config MAINBOARD_PART_NUMBER + default "StarBook Horizon" if BOARD_STARLABS_ADL_HORIZON + default "StarLite Mk V" if BOARD_STARLABS_LITE_ADL + default "Byte Mk III" if BOARD_STARLABS_BYTE_TWL + default "Byte Mk II" if BOARD_STARLABS_BYTE_ADL + +config MAINBOARD_SMBIOS_PRODUCT_NAME + default "StarBook Horizon" if BOARD_STARLABS_ADL_HORIZON + default "StarLite" if BOARD_STARLABS_LITE_ADL + default "Byte" if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL + +config ME_BIN_PATH + string + default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/intel_me.bin" + +config POWER_STATE_DEFAULT_ON_AFTER_FAILURE + default n + +config SOC_INTEL_CSE_SEND_EOP_EARLY + default n + +config UART_FOR_CONSOLE + default 0 + +config USE_PM_ACPI_TIMER + default n + +config VARIANT_DIR + default "hz" if BOARD_STARLABS_ADL_HORIZON + default "i5" if BOARD_STARLABS_LITE_ADL + default "y2" if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL + +config CMOS_LAYOUT_FILE + default "src/mainboard/\$(MAINBOARDDIR)/variants/\$(CONFIG_VARIANT_DIR)/cmos.layout" + +if BOARD_STARLABS_ADL_HORIZON || BOARD_STARLABS_LITE_ADL + +config CCD_PORT + int + default 4 if BOARD_STARLABS_ADL_HORIZON + default 5 if BOARD_STARLABS_LITE_ADL + +config EC_STARLABS_BATTERY_MODEL + default "U5266122PV-2S1P" if BOARD_STARLABS_ADL_HORIZON + default "AEC3756153-2S1P-N" if BOARD_STARLABS_LITE_ADL + +config EC_STARLABS_BATTERY_TYPE + default "LION" + +config EC_STARLABS_BATTERY_OEM + default "Shenzhen Utility Energy Co., Ltd" if BOARD_STARLABS_ADL_HORIZON + default "Apower Electronics" if BOARD_STARLABS_LITE_ADL + +if MAINBOARD_HAS_TPM2 + +config TPM_PIRQ + default 0x28 if BOARD_STARLABS_ADL_HORIZON + +endif # MAINBOARD_HAS_TPM2 + +endif # BOARD_STARLABS_ADL_HORIZON || BOARD_STARLABS_LITE_ADL + +if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL || BOARD_STARLABS_LITE_ADL + +config MB_STARLABS_PL4_WATTS + int + default 65 if BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL + default 37 if BOARD_STARLABS_LITE_ADL + +config VBOOT + select VBOOT_VBNV_FLASH + +endif # BOARD_STARLABS_BYTE_ADL || BOARD_STARLABS_BYTE_TWL || BOARD_STARLABS_LITE_ADL + +endif # BOARD_STARLABS_ADL_SERIES diff --git a/src/mainboard/starlabs/adl/Kconfig.name b/src/mainboard/starlabs/adl/Kconfig.name new file mode 100644 index 00000000000..373ed84cea8 --- /dev/null +++ b/src/mainboard/starlabs/adl/Kconfig.name @@ -0,0 +1,13 @@ +comment "Star Labs ADL Series" + +config BOARD_STARLABS_ADL_HORIZON + bool "Star Labs StarBook Horizon (N305)" + +config BOARD_STARLABS_BYTE_ADL + bool "Star Labs Byte Mk II (N200)" + +config BOARD_STARLABS_BYTE_TWL + bool "Star Labs Byte Mk III (N355)" + +config BOARD_STARLABS_LITE_ADL + bool "Star Labs Lite Mk V (N200/N350)" diff --git a/src/mainboard/starlabs/starlite_adl/Makefile.mk b/src/mainboard/starlabs/adl/Makefile.mk similarity index 77% rename from src/mainboard/starlabs/starlite_adl/Makefile.mk rename to src/mainboard/starlabs/adl/Makefile.mk index 14842f76e41..f42ebef3ab5 100644 --- a/src/mainboard/starlabs/starlite_adl/Makefile.mk +++ b/src/mainboard/starlabs/adl/Makefile.mk @@ -6,9 +6,6 @@ subdirs-y += variants/$(VARIANT_DIR) bootblock-y += bootblock.c -verstage-$(CONFIG_VBOOT) += vboot.c - -romstage-$(CONFIG_VBOOT) += vboot.c - ramstage-$(CONFIG_DRIVERS_OPTION_CFR) += cfr.c +ramstage-$(CONFIG_DRIVERS_OPTION_CFR) += $(wildcard variants/$(VARIANT_DIR)/cfr.c) ramstage-y += mainboard.c diff --git a/src/mainboard/starlabs/byte_adl/acpi/ec.asl b/src/mainboard/starlabs/adl/acpi/ec.asl similarity index 100% rename from src/mainboard/starlabs/byte_adl/acpi/ec.asl rename to src/mainboard/starlabs/adl/acpi/ec.asl diff --git a/src/mainboard/starlabs/starlite_adl/acpi/mainboard.asl b/src/mainboard/starlabs/adl/acpi/mainboard.asl similarity index 80% rename from src/mainboard/starlabs/starlite_adl/acpi/mainboard.asl rename to src/mainboard/starlabs/adl/acpi/mainboard.asl index f9d095244a4..702d37f3533 100644 --- a/src/mainboard/starlabs/starlite_adl/acpi/mainboard.asl +++ b/src/mainboard/starlabs/adl/acpi/mainboard.asl @@ -4,6 +4,7 @@ Scope (\_SB) { #include "sleep.asl" } +#if CONFIG(BOARD_STARLABS_LITE_ADL) Scope (_GPE) { Method (_E0F, 0, NotSerialized) @@ -11,3 +12,4 @@ Scope (_GPE) \_SB.PCI0.LPCB.EC.VBTN.UPDK() } } +#endif diff --git a/src/mainboard/starlabs/byte_adl/acpi/sleep.asl b/src/mainboard/starlabs/adl/acpi/sleep.asl similarity index 100% rename from src/mainboard/starlabs/byte_adl/acpi/sleep.asl rename to src/mainboard/starlabs/adl/acpi/sleep.asl diff --git a/src/mainboard/starlabs/byte_adl/acpi/superio.asl b/src/mainboard/starlabs/adl/acpi/superio.asl similarity index 100% rename from src/mainboard/starlabs/byte_adl/acpi/superio.asl rename to src/mainboard/starlabs/adl/acpi/superio.asl diff --git a/src/mainboard/starlabs/starlite_adl/board_info.txt b/src/mainboard/starlabs/adl/board_info.txt similarity index 80% rename from src/mainboard/starlabs/starlite_adl/board_info.txt rename to src/mainboard/starlabs/adl/board_info.txt index 77f1b9b0d56..c3772dc3d5f 100644 --- a/src/mainboard/starlabs/starlite_adl/board_info.txt +++ b/src/mainboard/starlabs/adl/board_info.txt @@ -1,5 +1,5 @@ Vendor name: Star Labs -Board name: StarLite +Board name: ADL Series Category: laptop ROM protocol: SPI ROM socketed: n diff --git a/src/mainboard/starlabs/byte_adl/bootblock.c b/src/mainboard/starlabs/adl/bootblock.c similarity index 100% rename from src/mainboard/starlabs/byte_adl/bootblock.c rename to src/mainboard/starlabs/adl/bootblock.c diff --git a/src/mainboard/starlabs/adl/cfr.c b/src/mainboard/starlabs/adl/cfr.c new file mode 100644 index 00000000000..8c8f5f601fb --- /dev/null +++ b/src/mainboard/starlabs/adl/cfr.c @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include + +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) +static struct sm_obj_form audio_video_group = { + .ui_name = "Audio/Video", + .obj_list = (const struct sm_object *[]){ + µphone, + &webcam, + NULL, + }, +}; +#endif + +static struct sm_obj_form battery_group = { + .ui_name = "Battery", + .obj_list = + (const struct sm_object *[]){ +#if CONFIG(EC_STARLABS_CHARGING_SPEED) + &charging_speed, +#endif +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) + &max_charge, +#endif + &power_on_after_fail_bool, NULL}, +}; + +static struct sm_obj_form debug_group = { + .ui_name = "Debug", + .obj_list = (const struct sm_object *[]){&debug_level, NULL}, +}; + +#if CONFIG(EC_STARLABS_POWER_LED) || CONFIG(EC_STARLABS_CHARGE_LED) +static struct sm_obj_form leds_group = { + .ui_name = "LEDs", + .obj_list = + (const struct sm_object *[]){ +#if CONFIG(EC_STARLABS_CHARGE_LED) + &charge_led, +#endif +#if CONFIG(EC_STARLABS_POWER_LED) + &power_led, +#endif + NULL, }, +}; +#endif + +#if CONFIG(SYSTEM_TYPE_LAPTOP) +static struct sm_obj_form keyboard_group = { + .ui_name = "Keyboard", + .obj_list = (const struct sm_object *[]){&fn_ctrl_swap, &kbl_timeout, NULL}, +}; +#endif + +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) +static struct sm_obj_form display_group = { + .ui_name = "Display", + .obj_list = + (const struct sm_object *[]){ +#if CONFIG(BOARD_STARLABS_LITE_ADL) + &accelerometer, +#endif + &display_native_res, +#if CONFIG(BOARD_STARLABS_LITE_ADL) + &touchscreen, +#endif + NULL, }, +}; +#endif + +#if CONFIG(BOARD_STARLABS_LITE_ADL) +static struct sm_obj_form io_expansion_group = { + .ui_name = "I/O / Expansion", + .obj_list = + (const struct sm_object *[]){ + &card_reader, + NULL, }, +}; +#endif + +static struct sm_obj_form pcie_power_management_group = { + .ui_name = "PCIe Power Management", + .obj_list = + (const struct sm_object *[]){ + &pciexp_aspm, + &pciexp_clk_pm, + &pciexp_l1ss, + NULL, }, +}; + +static struct sm_obj_form performance_group = { + .ui_name = "Performance", + .obj_list = + (const struct sm_object *[]){ +#if CONFIG(EC_STARLABS_FAN) + &fan_mode, +#endif + &gna, +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) + &memory_speed, +#endif + &power_profile, NULL}, +}; + +static struct sm_obj_form security_group = { + .ui_name = "Security", + .obj_list = (const struct sm_object *[]){&bios_lock, &intel_tme, &me_state, + &me_state_counter, NULL}, +}; + +static struct sm_obj_form suspend_lid_group = { + .ui_name = "Suspend & Lid", + .obj_list = + (const struct sm_object *[]){ +#if CONFIG(EC_STARLABS_LID_SWITCH) + &lid_switch, +#endif + &s0ix_enable, NULL}, +}; + +static struct sm_obj_form virtualization_group = { + .ui_name = "Virtualization", + .obj_list = (const struct sm_object *[]){&vtd, NULL}, +}; + +static struct sm_obj_form wireless_group = { + .ui_name = "Wireless", + .obj_list = (const struct sm_object *[]){&bluetooth, &bluetooth_rtd3, &wifi, NULL}, +}; + +static struct sm_obj_form *sm_root[] = { +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) + &audio_video_group, +#endif + &battery_group, + &debug_group, +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) + &display_group, +#endif +#if CONFIG(BOARD_STARLABS_LITE_ADL) + &io_expansion_group, +#endif +#if CONFIG(SYSTEM_TYPE_LAPTOP) + &keyboard_group, +#endif +#if CONFIG(EC_STARLABS_POWER_LED) || CONFIG(EC_STARLABS_CHARGE_LED) + &leds_group, +#endif + &pcie_power_management_group, + &performance_group, + &security_group, + &suspend_lid_group, + &virtualization_group, + &wireless_group, + NULL}; + +void mb_cfr_setup_menu(struct lb_cfr *cfr_root) +{ + starlabs_cfr_register_overrides(); + cfr_write_setup_menu(cfr_root, sm_root); +} diff --git a/src/mainboard/starlabs/starlite_adl/dsdt.asl b/src/mainboard/starlabs/adl/dsdt.asl similarity index 93% rename from src/mainboard/starlabs/starlite_adl/dsdt.asl rename to src/mainboard/starlabs/adl/dsdt.asl index b7783eae63e..367d6af038f 100644 --- a/src/mainboard/starlabs/starlite_adl/dsdt.asl +++ b/src/mainboard/starlabs/adl/dsdt.asl @@ -21,12 +21,13 @@ DefinitionBlock( #include #include - #include - #include +#if CONFIG(SYSTEM_TYPE_LAPTOP) || CONFIG(SYSTEM_TYPE_DETACHABLE) + #include /* PS/2 Keyboard */ #include +#endif } #include diff --git a/src/mainboard/starlabs/starlite_adl/include/variants.h b/src/mainboard/starlabs/adl/include/variants.h similarity index 82% rename from src/mainboard/starlabs/starlite_adl/include/variants.h rename to src/mainboard/starlabs/adl/include/variants.h index c95d15bd721..536ac891ae6 100644 --- a/src/mainboard/starlabs/starlite_adl/include/variants.h +++ b/src/mainboard/starlabs/adl/include/variants.h @@ -3,6 +3,7 @@ #ifndef _BASEBOARD_VARIANTS_H_ #define _BASEBOARD_VARIANTS_H_ +#include #include /* @@ -14,4 +15,6 @@ const struct pad_config *variant_early_gpio_table(size_t *num); void devtree_update(void); +void starlabs_adl_mainboard_fill_ssdt(const struct device *dev); + #endif /* _BASEBOARD_VARIANTS_H_ */ diff --git a/src/mainboard/starlabs/adl/mainboard.c b/src/mainboard/starlabs/adl/mainboard.c new file mode 100644 index 00000000000..940584b151b --- /dev/null +++ b/src/mainboard/starlabs/adl/mainboard.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +static void starlabs_configure_mainboard(void *unused) +{ + const struct pad_config *pads; + size_t num; + + pads = variant_gpio_table(&num); + gpio_configure_pads(pads, num); + + devtree_update(); +} + +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, starlabs_configure_mainboard, NULL); + +void __weak starlabs_adl_mainboard_fill_ssdt(const struct device *dev) +{ + (void)dev; +} + +static void enable_mainboard(struct device *dev) +{ + dev->ops->acpi_fill_ssdt = starlabs_adl_mainboard_fill_ssdt; +} + +struct chip_operations mainboard_ops = { + .enable_dev = enable_mainboard, +}; diff --git a/src/mainboard/starlabs/adl/spd/Makefile.mk b/src/mainboard/starlabs/adl/spd/Makefile.mk new file mode 100644 index 00000000000..f02db920015 --- /dev/null +++ b/src/mainboard/starlabs/adl/spd/Makefile.mk @@ -0,0 +1,11 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ifeq ($(VARIANT_DIR),hz) +SPD_SOURCES = rs4g32l05d8fdb-5500 +SPD_SOURCES += rs4g32l05d8fdb-6400 +SPD_SOURCES += rs4g32l05d8fdb-7500 +else ifeq ($(VARIANT_DIR),i5) +SPD_SOURCES = mt62f2g64d8-5500 +SPD_SOURCES += mt62f2g64d8-6400 +SPD_SOURCES += mt62f2g64d8-7500 +endif diff --git a/src/mainboard/starlabs/starlite_adl/spd/mt62f2g64d8-5500.spd.hex b/src/mainboard/starlabs/adl/spd/mt62f2g64d8-5500.spd.hex similarity index 100% rename from src/mainboard/starlabs/starlite_adl/spd/mt62f2g64d8-5500.spd.hex rename to src/mainboard/starlabs/adl/spd/mt62f2g64d8-5500.spd.hex diff --git a/src/mainboard/starlabs/starlite_adl/spd/mt62f2g64d8-6400.spd.hex b/src/mainboard/starlabs/adl/spd/mt62f2g64d8-6400.spd.hex similarity index 100% rename from src/mainboard/starlabs/starlite_adl/spd/mt62f2g64d8-6400.spd.hex rename to src/mainboard/starlabs/adl/spd/mt62f2g64d8-6400.spd.hex diff --git a/src/mainboard/starlabs/starlite_adl/spd/mt62f2g64d8-7500.spd.hex b/src/mainboard/starlabs/adl/spd/mt62f2g64d8-7500.spd.hex similarity index 100% rename from src/mainboard/starlabs/starlite_adl/spd/mt62f2g64d8-7500.spd.hex rename to src/mainboard/starlabs/adl/spd/mt62f2g64d8-7500.spd.hex diff --git a/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-5500.spd.hex b/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-5500.spd.hex new file mode 100644 index 00000000000..a52441a71b7 --- /dev/null +++ b/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-5500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 2A 91 08 00 00 00 00 09 01 00 00 +00 00 0B 00 00 00 00 00 AE 00 90 A8 90 C0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 4B 00 50 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-6400.spd.hex b/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-6400.spd.hex new file mode 100644 index 00000000000..0969d01568a --- /dev/null +++ b/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-6400.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 2A 91 08 00 00 00 00 09 01 00 00 +00 00 0A 00 00 00 00 00 AA 00 90 A8 90 C0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-7500.spd.hex b/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-7500.spd.hex new file mode 100644 index 00000000000..c132efab8cc --- /dev/null +++ b/src/mainboard/starlabs/adl/spd/rs4g32l05d8fdb-7500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 2A 91 08 00 00 00 00 09 01 00 00 +00 00 08 00 00 00 00 00 AA 00 90 A8 90 C0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 46 00 42 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/Makefile.mk b/src/mainboard/starlabs/adl/variants/hz/Makefile.mk similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/Makefile.mk rename to src/mainboard/starlabs/adl/variants/hz/Makefile.mk diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/board.fmd b/src/mainboard/starlabs/adl/variants/hz/board.fmd similarity index 68% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/board.fmd rename to src/mainboard/starlabs/adl/variants/hz/board.fmd index 3c64b271346..21972622372 100644 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/board.fmd +++ b/src/mainboard/starlabs/adl/variants/hz/board.fmd @@ -6,9 +6,9 @@ FLASH 0x1000000 { SI_BIOS 0xa00000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/adl/variants/hz/data.vbt b/src/mainboard/starlabs/adl/variants/hz/data.vbt new file mode 100644 index 00000000000..8c22ab4f40c Binary files /dev/null and b/src/mainboard/starlabs/adl/variants/hz/data.vbt differ diff --git a/src/mainboard/starlabs/adl/variants/hz/data_native_res.vbt b/src/mainboard/starlabs/adl/variants/hz/data_native_res.vbt new file mode 100644 index 00000000000..a101af780b8 Binary files /dev/null and b/src/mainboard/starlabs/adl/variants/hz/data_native_res.vbt differ diff --git a/src/mainboard/starlabs/adl/variants/hz/devicetree.cb b/src/mainboard/starlabs/adl/variants/hz/devicetree.cb new file mode 100644 index 00000000000..c06ad29b9a1 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/hz/devicetree.cb @@ -0,0 +1,251 @@ +chip soc/intel/alderlake + # FSP UPDs + register "eist_enable" = "true" + register "enable_c6dram" = "true" + register "energy_efficient_turbo" = "true" + register "sagv" = "SaGv_Enabled" + + # Serial I/O + register "serial_io_i2c_mode" = "{ + [PchSerialIoIndexI2C0] = PchSerialIoSkipInit, + [PchSerialIoIndexI2C3] = PchSerialIoPci, + }" + + register "common_soc_config" = "{ + .i2c[3] = { + .speed = I2C_SPEED_FAST, + }, + }" + + register "serial_io_uart_mode" = "{ + [PchSerialIoIndexUART0] = PchSerialIoSkipInit, + }" + + # Power + register "pch_slp_s3_min_assertion_width" = "SLP_S3_ASSERTION_1_MS" + register "pch_slp_s4_min_assertion_width" = "SLP_S4_ASSERTION_3S" + register "pch_slp_sus_min_assertion_width" = "SLP_SUS_ASSERTION_1_S" + register "pch_slp_a_min_assertion_width" = "SLP_A_ASSERTION_98_MS" + + device domain 0 on + device ref igpu on + chip drivers/gfx/generic + register "device_count" = "6" + # [DDIA] eDP + register "device[0].name" = ""LCD0"" + register "device[0].type" = "panel" + # [DDIB] HDMI + register "device[1].name" = ""DD01"" + # [TCP0] Type-C + register "device[2].name" = ""DD02"" + register "device[2].use_pld" = "true" + register "device[2].pld" = "ACPI_PLD_TYPE_C(LEFT, CENTER, ACPI_PLD_GROUP(0, 0))" + # [TCP1] Type-C + register "device[3].name" = ""DD03"" + register "device[3].use_pld" = "true" + register "device[3].pld" = "ACPI_PLD_TYPE_C(LEFT, CENTER, ACPI_PLD_GROUP(0, 1))" + # [TCP2] N/A + register "device[4].name" = ""DD04"" + # [TCP3] N/A + register "device[5].name" = ""DD05"" + device generic 0 on end + end + + register "ddi_portA_config" = "1" + register "ddi_ports_config" = "{ + [DDI_PORT_A] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + [DDI_PORT_B] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + }" + end + device ref gna on end + device ref xhci on + # Left Rear USB 2.0 Type-C 3289 mil + register "usb2_ports[0]" = "USB2_PORT_SHORT(OC_SKIP)" + register "usb3_ports[1]" = "USB3_PORT_DEFAULT(OC_SKIP)" + + # Left Front USB 3.0 Type C + register "usb2_ports[1]" = "USB2_PORT_SHORT(OC_SKIP)" + register "usb3_ports[3]" = "USB3_PORT_DEFAULT(OC_SKIP)" + + # Right USB 3.0 Hub + register "usb2_ports[6]" = "USB2_PORT_SHORT(OC_SKIP)" + register "usb3_ports[0]" = "USB3_PORT_DEFAULT(OC_SKIP)" + + # Webcam 3249 mil + register "usb2_ports[CONFIG_CCD_PORT]" = "USB2_PORT_SHORT(OC_SKIP)" + + # Internal Bluetooth 1874 mil + register "usb2_ports[9]" = "USB2_PORT_SHORT(OC_SKIP)" + + chip drivers/usb/acpi + device ref xhci_root_hub on + chip drivers/usb/acpi + register "desc" = ""Left Back USB Type-C"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(LEFT, CENTER, ACPI_PLD_GROUP(0, 0))" + device ref usb2_port1 on end + end + chip drivers/usb/acpi + register "desc" = ""Left Back USB Type-C"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(LEFT, CENTER, ACPI_PLD_GROUP(0, 0))" + device ref usb3_port2 on end + end + + chip drivers/usb/acpi + register "desc" = ""Left Front USB Type-C"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(LEFT, CENTER, ACPI_PLD_GROUP(0, 1))" + device ref usb2_port2 on end + end + chip drivers/usb/acpi + register "desc" = ""Left Front USB Type-C"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(LEFT, CENTER, ACPI_PLD_GROUP(0, 1))" + device ref usb3_port4 on end + end + + chip drivers/usb/acpi + register "desc" = ""Right USB 3.0 Hub"" + register "type" = "UPC_TYPE_HUB" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(RIGHT, CENTER, ACPI_PLD_GROUP(0, 2))" + device ref usb2_port7 on end + end + chip drivers/usb/acpi + register "desc" = ""Right USB 3.0 Hub"" + register "type" = "UPC_TYPE_HUB" + register "use_custom_pld" = "true" + register "custom_pld" = "ACPI_PLD_TYPE_C(RIGHT, CENTER, ACPI_PLD_GROUP(0, 2))" + device ref usb3_port1 on end + end + + chip drivers/usb/acpi + register "desc" = ""Internal Webcam"" + register "type" = "UPC_TYPE_INTERNAL" + register "group" = "ACPI_PLD_GROUP(0, 3)" + device ref usb2_port5 on end + end + + chip drivers/usb/acpi + register "desc" = ""CNVi Bluetooth"" + register "type" = "UPC_TYPE_INTERNAL" + register "is_intel_bluetooth" = "1" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_VGPIO_0)" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_A13)" + register "group" = "ACPI_PLD_GROUP(0, 4)" + device ref usb2_port10 on end + end + end + end + end + device ref i2c0 on end + device ref i2c3 on + chip drivers/i2c/hid + register "generic.hid" = ""STAR0001"" + register "generic.desc" = ""Touchpad"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E12_IRQ)" + register "hid_desc_reg_offset" = "0x20" + device i2c 2c on end + end + end + device ref shared_sram on end + device ref cnvi_wifi on + chip drivers/wifi/generic + register "add_acpi_dma_property" = "true" + register "cnvi_enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E3)" + register "enable_cnvi_ddr_rfim" = "true" + device generic 0 on end + end + end + device ref pcie_rp9 on # SSD x4 + register "pch_pcie_rp[PCH_RP(9)]" = "{ + .clk_src = 0, + .clk_req = 0, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + .pcie_rp_aspm = ASPM_L0S_L1, + .PcieRpL1Substates = L1_SS_L1_2, + .pcie_rp_detect_timeout_ms = 50, + + }" + smbios_slot_desc "SlotTypeM2Socket3" + "SlotLengthLong" + "M.2/M 2280" + "SlotDataBusWidth4X" + chip soc/intel/common/block/pcie/rtd3 + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_D16)" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_H0)" + register "srcclk_pin" = "0" + register "is_storage" = "true" + register "add_acpi_dma_property" = "true" + register "skip_on_off_support" = "true" + register "ext_pm_support" = "ACPI_PCIE_RP_EMIT_ALL" + register "use_rp_mutex" = "true" + device generic 0 on end + end + end + device ref uart0 on end + device ref pch_espi on + register "gen1_dec" = "0x00040069" + register "gen2_dec" = "0x00fc0201" + register "gen3_dec" = "0x000c0081" + + chip drivers/pc80/tpm + device pnp 0c31.0 on end + end + + chip ec/starlabs/merlin + # Port pair 4Eh/4Fh + device pnp 4e.01 off end # Com 1 + device pnp 4e.02 off end # Com 2 + device pnp 4e.04 off end # System Wake-Up + device pnp 4e.05 off end # PS/2 Mouse + device pnp 4e.06 on # PS/2 Keyboard + io 0x60 = 0x0060 + io 0x62 = 0x0064 + irq 0x70 = 1 + end + device pnp 4e.0a off end # Consumer IR + device pnp 4e.0f off end # Shared Memory/Flash Interface + device pnp 4e.10 off end # RTC-like Timer + device pnp 4e.11 off end # Power Management Channel 1 + device pnp 4e.12 off end # Power Management Channel 2 + device pnp 4e.13 off end # Serial Peripheral Interface + device pnp 4e.14 off end # Platform EC Interface + device pnp 4e.17 off end # Power Management Channel 3 + device pnp 4e.18 off end # Power Management Channel 4 + device pnp 4e.19 off end # Power Management Channel 5 + end + end + device ref pmc hidden + chip drivers/intel/pmc_mux + device generic 0 on + chip drivers/intel/pmc_mux/conn + use usb2_port2 as usb2_port + use usb3_port4 as usb3_port + device generic 0 alias conn0 on end + end + chip drivers/intel/pmc_mux/conn + use usb2_port7 as usb2_port + use usb3_port1 as usb3_port + device generic 1 alias conn1 on end + end + end + end + end + device ref hda on + subsystemid 0x1e50 0x7038 + register "pch_hda_sdi_enable[0]" = "true" + register "pch_hda_dsp_enable" = "true" + register "pch_hda_audio_link_hda_enable" = "true" + register "pch_hda_idisp_codec_enable" = "true" + register "pch_hda_idisp_link_frequency" = "HDA_LINKFREQ_96MHZ" + register "pch_hda_idisp_link_tmode" = "HDA_TMODE_8T" + end + device ref smbus on end + end +end diff --git a/src/mainboard/starlabs/adl/variants/hz/devtree.c b/src/mainboard/starlabs/adl/variants/hz/devtree.c new file mode 100644 index 00000000000..3ae2d089566 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/hz/devtree.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void devtree_update(void) +{ + config_t *cfg = config_of_soc(); + update_power_limits(cfg); + + /* Enable/Disable WiFi based on CMOS settings */ + if (get_uint_option("wifi", 1) == 0) + DEV_PTR(cnvi_wifi)->enabled = 0; + + /* Enable/Disable Bluetooth based on CMOS settings */ + if (get_uint_option("bluetooth", 1) == 0) + cfg->usb2_ports[9].enable = 0; + + /* Enable/Disable Webcam based on CMOS settings */ + if (get_uint_option("webcam", 1) == 0) + cfg->usb2_ports[CONFIG_CCD_PORT].enable = 0; + + /* Enable/Disable GNA based on CMOS settings */ + if (get_uint_option("gna", 0) == 0) + DEV_PTR(gna)->enabled = 0; +} diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/gpio.c b/src/mainboard/starlabs/adl/variants/hz/gpio.c similarity index 83% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/gpio.c rename to src/mainboard/starlabs/adl/variants/hz/gpio.c index 8c1b7cf79f8..4cb0af527d0 100644 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/gpio.c +++ b/src/mainboard/starlabs/adl/variants/hz/gpio.c @@ -1,12 +1,42 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset deasserted */ +}; + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_D5, NONE, DEEP), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ }; const struct pad_config *variant_early_gpio_table(size_t *num) @@ -34,24 +64,15 @@ const struct pad_config gpio_table[] = { // PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A9, UP_20K, DEEP, NF1), /* eSPI Clk */ // PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A10, NONE, DEEP, NF1), /* eSPI Reset */ - /* Touchpanel */ - PAD_CFG_NF(GPP_B5, NONE, DEEP, NF2), /* Data */ - PAD_CFG_NF(GPP_B6, NONE, DEEP, NF2), /* Clock */ + /* Touchpad */ + PAD_CFG_NF(GPP_B7, NONE, DEEP, NF2), /* Data */ + PAD_CFG_NF(GPP_B8, NONE, DEEP, NF2), /* Clock */ PAD_CFG_GPI_APIC_LOW(GPP_E12, NONE, PLTRST), /* Interrupt */ - PAD_CFG_GPO(GPP_F17, 1, PLTRST), /* Reset */ - PAD_CFG_GPI_APIC(GPP_F18, NONE, PLTRST, LEVEL, INVERT), /* Interrupt */ - - /* Accelerometer */ - PAD_CFG_NF(GPP_H4, NONE, DEEP, NF1), /* Data */ - PAD_CFG_NF(GPP_H5, NONE, DEEP, NF1), /* Clock */ - - /* Keyboard */ - PAD_CFG_GPI_SMI_LOW(GPP_F15, NONE, DEEP, EDGE_BOTH), /* Detect */ /* SSD */ - PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ - PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_NC(GPP_D5, NONE), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ /* Wireless */ PAD_CFG_NF(GPP_F0, NONE, DEEP, NF1), /* BRI Data */ @@ -69,7 +90,7 @@ const struct pad_config gpio_table[] = { PAD_CFG_NF(GPP_H15, NONE, DEEP, NF1), /* HDMI Clock */ PAD_CFG_NF(GPP_H17, NONE, DEEP, NF1), /* HDMI Data */ PAD_CFG_NF(GPP_A19, NONE, DEEP, NF1), /* TCP0 Hot Plug */ - PAD_CFG_NF(GPP_A20, NONE, DEEP, NF1), /* TCP0 Hot Plug */ + PAD_CFG_NF(GPP_A20, NONE, DEEP, NF1), /* TCP1 Hot Plug */ /* High-Definition Audio */ PAD_CFG_NF(GPP_R0, NATIVE, DEEP, NF1), /* Clock */ @@ -85,12 +106,15 @@ const struct pad_config gpio_table[] = { PAD_CFG_NF(GPP_B1, NONE, DEEP, NF1), /* Vendor ID 1 */ PAD_CFG_GPI_SCI(GPP_B2, NONE, PLTRST, EDGE_SINGLE, INVERT), /* Processor Hot */ + /* TPM */ + PAD_CFG_GPI_APIC_LOW(GPP_E2, NONE, PLTRST), /* Interrupt */ + /* SMBus */ PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* Clock */ PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* Data */ PAD_CFG_GPO(GPP_E8, 1, DEEP), /* DRAM Sleep */ - /* Config Straps [ Low / High ] */ + /* Config Straps [ Low / High ] */ PAD_CFG_GPO(GPP_B14, 0, PLTRST), /* Top Swap [ Disabled / Enabled ] */ PAD_CFG_GPO(GPP_B18, 0, PLTRST), /* Reboot Support [ Enabled / Disabled ] */ PAD_CFG_GPO(GPP_C2, 1, PLTRST), /* TLS Confidentiality [ Disabled / Enabled ] */ @@ -126,8 +150,8 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_B3, NONE), PAD_NC(GPP_B4, NONE), - PAD_NC(GPP_B7, NONE), - PAD_NC(GPP_B8, NONE), + PAD_NC(GPP_B5, NONE), + PAD_NC(GPP_B6, NONE), PAD_NC(GPP_B9, NONE), PAD_NC(GPP_B10, NONE), PAD_NC(GPP_B11, NONE), @@ -183,19 +207,18 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_E0, NONE), PAD_NC(GPP_E1, NONE), - PAD_NC(GPP_E2, NONE), PAD_NC(GPP_E4, NONE), PAD_NC(GPP_E5, NONE), PAD_NC(GPP_E7, NONE), PAD_NC(GPP_E9, NONE), PAD_NC(GPP_E10, NONE), - PAD_NC(GPP_E11, NONE), PAD_NC(GPP_E13, NONE), PAD_NC(GPP_E15, NONE), PAD_NC(GPP_E16, NONE), PAD_NC(GPP_E17, NONE), PAD_NC(GPP_E18, NONE), PAD_NC(GPP_E20, NONE), + PAD_NC(GPP_E21, NONE), PAD_NC(GPP_E22, NONE), PAD_NC(GPP_E23, NONE), @@ -207,7 +230,10 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_F12, NONE), PAD_NC(GPP_F13, NONE), PAD_NC(GPP_F14, NONE), + PAD_NC(GPP_F15, NONE), PAD_NC(GPP_F16, NONE), + PAD_NC(GPP_F17, NONE), + PAD_NC(GPP_F18, NONE), PAD_NC(GPP_F19, NONE), PAD_NC(GPP_F20, NONE), PAD_NC(GPP_F21, NONE), @@ -216,6 +242,8 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_H2, NONE), PAD_NC(GPP_H3, NONE), + PAD_NC(GPP_H4, NONE), + PAD_NC(GPP_H5, NONE), PAD_NC(GPP_H6, NONE), PAD_NC(GPP_H7, NONE), PAD_NC(GPP_H8, NONE), diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/hda_verb.c b/src/mainboard/starlabs/adl/variants/hz/hda_verb.c similarity index 96% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/hda_verb.c rename to src/mainboard/starlabs/adl/variants/hz/hda_verb.c index 24d23ae55de..813c0f0458f 100644 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/hda_verb.c +++ b/src/mainboard/starlabs/adl/variants/hz/hda_verb.c @@ -7,7 +7,7 @@ const u32 cim_verb_data[] = { /* coreboot specific header */ 0x10ec0269, /* Codec Vendor / Device ID: Realtek ALC269 */ 0x1e507038, /* Subsystem ID */ - 18, /* Number of jacks (NID entries) */ + 18, /* Number of verb entries */ /* Reset Codec First */ AZALIA_RESET(0x1), @@ -18,7 +18,7 @@ const u32 cim_verb_data[] = { /* Pin Widget Verb-table */ AZALIA_PIN_CFG(0, ALC269_DMIC12, AZALIA_PIN_DESC( AZALIA_INTEGRATED, - AZALIA_INTERNAL | AZALIA_FRONT, + AZALIA_MOBILE_LID_INSIDE, AZALIA_MIC_IN, AZALIA_OTHER_DIGITAL, AZALIA_COLOR_UNKNOWN, @@ -26,7 +26,6 @@ const u32 cim_verb_data[] = { 3, 0 )), - AZALIA_PIN_CFG(0, ALC269_SPEAKERS, AZALIA_PIN_DESC( AZALIA_INTEGRATED, AZALIA_INTERNAL | AZALIA_FRONT, diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/ramstage.c b/src/mainboard/starlabs/adl/variants/hz/ramstage.c similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/ramstage.c rename to src/mainboard/starlabs/adl/variants/hz/ramstage.c diff --git a/src/mainboard/starlabs/adl/variants/hz/romstage.c b/src/mainboard/starlabs/adl/variants/hz/romstage.c new file mode 100644 index 00000000000..9162509387a --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/hz/romstage.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void mainboard_memory_init_params(FSPM_UPD *mupd) +{ + const struct mb_cfg mem_config = { + .type = MEM_TYPE_LP5X, + + .lpx_dq_map = { + .ddr0 = { + .dq0 = { 10, 14, 13, 12, 9, 11, 15, 8 }, + .dq1 = { 4, 1, 7, 3, 5, 0, 2, 6 }, + }, + .ddr1 = { + .dq0 = { 2, 7, 6, 0, 1, 3, 5, 4 }, + .dq1 = { 13, 11, 9, 8, 10, 14, 12, 15 }, + }, + .ddr2 = { + .dq0 = { 7, 0, 1, 6, 4, 5, 2, 3 }, + .dq1 = { 8, 10, 9, 11, 15, 13, 12, 14 }, + }, + .ddr3 = { + .dq0 = { 2, 0, 3, 1, 4, 5, 7, 6 }, + .dq1 = { 10, 9, 14, 11, 12, 13, 15, 8 }, + }, + .ddr4 = { + .dq0 = { 3, 2, 1, 0, 7, 4, 6, 5 }, + .dq1 = { 8, 10, 11, 9, 14, 13, 12, 15 }, + }, + .ddr5 = { + .dq0 = { 8, 9, 10, 11, 12, 13, 14, 15 }, + .dq1 = { 7, 6, 5, 4, 3, 2, 1, 0 }, + }, + .ddr6 = { + .dq0 = { 13, 12, 15, 14, 9, 8, 11, 10 }, + .dq1 = { 5, 4, 7, 6, 3, 1, 2, 0 }, + }, + .ddr7 = { + .dq0 = { 3, 1, 2, 0, 4, 6, 5, 7 }, + .dq1 = { 15, 12, 9, 8, 11, 10, 13, 14 }, + }, + }, + .lpx_dqs_map = { + .ddr0 = { + .dqs0 = 1, + .dqs1 = 0, + }, + .ddr1 = { + .dqs0 = 0, + .dqs1 = 1, + }, + .ddr2 = { + .dqs0 = 0, + .dqs1 = 1, + }, + .ddr3 = { + .dqs0 = 0, + .dqs1 = 1, + }, + .ddr4 = { + .dqs0 = 1, + .dqs1 = 0, + }, + .ddr5 = { + .dqs0 = 0, + .dqs1 = 1, + }, + .ddr6 = { + .dqs0 = 0, + .dqs1 = 1, + }, + .ddr7 = { + .dqs0 = 1, + .dqs1 = 0, + } + }, + + .ect = true, + .UserBd = BOARD_TYPE_ULT_ULX, + .LpDdrDqDqsReTraining = true, + + .lp5x_config = { + .ccc_config = 0x00, + } + }; + + const bool half_populated = true; + + const struct mem_spd lpddr5_spd_info = { + .topo = MEM_TOPO_MEMORY_DOWN, + .cbfs_index = get_uint_option("memory_speed", 1), + }; + + memcfg_init(mupd, &mem_config, &lpddr5_spd_info, half_populated); + + const uint8_t vtd = get_uint_option("vtd", 1); + mupd->FspmConfig.VtdDisable = !vtd; +}; diff --git a/src/mainboard/starlabs/adl/variants/i5/Makefile.mk b/src/mainboard/starlabs/adl/variants/i5/Makefile.mk new file mode 100644 index 00000000000..d6e2d5b29d4 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/i5/Makefile.mk @@ -0,0 +1,13 @@ +## SPDX-License-Identifier: GPL-2.0-only + +bootblock-y += gpio.c + +romstage-y += romstage.c + +ramstage-y += devtree.c +ramstage-y += gpio.c +ramstage-y += hda_verb.c +ramstage-y += mainboard_ssdt.c +ramstage-y += ramstage.c + +$(call add_vbt_to_cbfs, vbt_native_res.bin, data_native_res.vbt) diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd b/src/mainboard/starlabs/adl/variants/i5/board.fmd similarity index 61% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd rename to src/mainboard/starlabs/adl/variants/i5/board.fmd index bc72a6098d6..21972622372 100644 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/board.fmd +++ b/src/mainboard/starlabs/adl/variants/i5/board.fmd @@ -1,14 +1,14 @@ FLASH 0x1000000 { SI_ALL 0x600000 { SI_DESC 0x1000 - SI_ME 0x412000 + SI_ME 0x411000 } SI_BIOS 0xa00000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/adl/variants/i5/cfr.c b/src/mainboard/starlabs/adl/variants/i5/cfr.c new file mode 100644 index 00000000000..5593cb55316 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/i5/cfr.c @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +void cfr_card_reader_update(struct sm_object *new_obj) +{ + struct device *mxc_accel = DEV_PTR(mxc6655); + + if (!i2c_dev_detect(i2c_busdev(mxc_accel), mxc_accel->path.i2c.device)) + new_obj->sm_bool.flags |= CFR_OPTFLAG_SUPPRESS; +} + +void cfr_touchscreen_update(struct sm_object *new_obj) +{ + if (get_uint_option("accelerometer", 1) == 0) + new_obj->sm_bool.flags |= CFR_OPTFLAG_SUPPRESS; +} diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/data.vbt b/src/mainboard/starlabs/adl/variants/i5/data.vbt similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/data.vbt rename to src/mainboard/starlabs/adl/variants/i5/data.vbt diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/data_native_res.vbt b/src/mainboard/starlabs/adl/variants/i5/data_native_res.vbt similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/data_native_res.vbt rename to src/mainboard/starlabs/adl/variants/i5/data_native_res.vbt diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devicetree.cb b/src/mainboard/starlabs/adl/variants/i5/devicetree.cb similarity index 98% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/devicetree.cb rename to src/mainboard/starlabs/adl/variants/i5/devicetree.cb index 10680827c6f..155ed5c08e8 100644 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devicetree.cb +++ b/src/mainboard/starlabs/adl/variants/i5/devicetree.cb @@ -85,8 +85,8 @@ chip soc/intel/alderlake # Internal Bluetooth 1874 mil register "usb2_ports[9]" = "USB2_PORT_SHORT(OC_SKIP)" - # Card Reader - register "usb2_ports[3]" = "USB2_PORT_MID(OC_SKIP)" + # Card Reader 3926 mil + register "usb2_ports[3]" = "USB2_PORT_SHORT(OC_SKIP)" chip drivers/usb/acpi device ref xhci_root_hub on @@ -199,7 +199,6 @@ chip soc/intel/alderlake .flags = PCIE_RP_LTR | PCIE_RP_AER, .pcie_rp_aspm = ASPM_L0S_L1, .PcieRpL1Substates = L1_SS_L1_2, - .pcie_rp_detect_timeout_ms = 50, }" smbios_slot_desc "SlotTypeM2Socket3" diff --git a/src/mainboard/starlabs/adl/variants/i5/devtree.c b/src/mainboard/starlabs/adl/variants/i5/devtree.c new file mode 100644 index 00000000000..4a13543bf63 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/i5/devtree.c @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void devtree_update(void) +{ + config_t *cfg = config_of_soc(); + update_power_limits(cfg); + + /* Enable/Disable WiFi based on CMOS settings */ + if (get_uint_option("wifi", 1) == 0) + DEV_PTR(cnvi_wifi)->enabled = 0; + + /* Enable/Disable Bluetooth based on CMOS settings */ + if (get_uint_option("bluetooth", 1) == 0) + cfg->usb2_ports[9].enable = 0; + + /* Enable/Disable Webcam/Camera based on CMOS settings */ + if (get_uint_option("webcam", 1) == 0) + cfg->usb2_ports[CONFIG_CCD_PORT].enable = 0; + + /* Enable/Disable Touchscreen based on CMOS settings */ + if (get_uint_option("touchscreen", 1) == 0) + DEV_PTR(i2c2)->enabled = 0; + + /* Enable/Disable Accelerometer based on CMOS settings */ + if (get_uint_option("accelerometer", 1) == 0) + DEV_PTR(i2c0)->enabled = 0; + + /* Enable/Disable GNA based on CMOS settings */ + if (get_uint_option("gna", 0) == 0) + DEV_PTR(gna)->enabled = 0; + + /* Enable/Disable Card Reader based on CMOS Settings */ + if (get_uint_option("card_reader", 0) == 0) + cfg->usb2_ports[3].enable = 0; +} diff --git a/src/mainboard/starlabs/adl/variants/i5/gpio.c b/src/mainboard/starlabs/adl/variants/i5/gpio.c new file mode 100644 index 00000000000..12b61daf055 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/i5/gpio.c @@ -0,0 +1,299 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +#if ENV_RAMSTAGE +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset deasserted */ +}; + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif + +/* Early pad configuration in bootblock */ +const struct pad_config early_gpio_table[] = { + /* Debug Connector */ + PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ + PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_D5, NONE, DEEP), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ +}; + +const struct pad_config *variant_early_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(early_gpio_table); + return early_gpio_table; +} + +/* Pad configuration in ramstage. */ +const struct pad_config gpio_table[] = { + /* General Purpose I/O Deep */ + PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ + PAD_CFG_NF(GPD1, NONE, DEEP, NF1), /* Charger Connected */ + PAD_CFG_NF(GPD3, UP_20K, DEEP, NF1), /* Power Button */ + PAD_CFG_NF(GPD4, NONE, DEEP, NF1), /* Sleep S3 */ + PAD_CFG_NF(GPD5, NONE, DEEP, NF1), /* Sleep S4 */ + PAD_CFG_NF(GPD8, NONE, DEEP, NF1), /* Bluetooth Suspend */ + + /* eSPI - Configure automatically on reset */ + // PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A0, UP_20K, DEEP, NF1), /* eSPI IO 0 */ + // PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A1, UP_20K, DEEP, NF1), /* eSPI IO 1 */ + // PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A2, UP_20K, DEEP, NF1), /* eSPI IO 2 */ + // PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A3, UP_20K, DEEP, NF1), /* eSPI IO 3 */ + // PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A4, UP_20K, DEEP, NF1), /* eSPI CS 0 */ + // PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A9, UP_20K, DEEP, NF1), /* eSPI Clk */ + // PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A10, NONE, DEEP, NF1), /* eSPI Reset */ + + /* Touchpanel */ + PAD_CFG_NF(GPP_B5, NONE, DEEP, NF2), /* Data */ + PAD_CFG_NF(GPP_B6, NONE, DEEP, NF2), /* Clock */ + PAD_CFG_GPI_APIC_LOW(GPP_E12, NONE, PLTRST), /* Interrupt */ + PAD_CFG_GPO(GPP_F17, 1, PLTRST), /* Reset */ + PAD_CFG_GPI_APIC(GPP_F18, NONE, PLTRST, LEVEL, INVERT), /* Interrupt */ + + /* Accelerometer */ + PAD_CFG_NF(GPP_H4, NONE, DEEP, NF1), /* Data */ + PAD_CFG_NF(GPP_H5, NONE, DEEP, NF1), /* Clock */ + + /* Keyboard */ + PAD_CFG_GPI_SMI_LOW(GPP_F15, NONE, DEEP, EDGE_BOTH), /* Detect */ + + /* SSD */ + PAD_NC(GPP_D5, NONE), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ + + /* Wireless */ + PAD_CFG_NF(GPP_F0, NONE, DEEP, NF1), /* BRI Data */ + PAD_CFG_NF(GPP_F1, UP_20K, DEEP, NF1), /* BRI Response */ + PAD_CFG_NF(GPP_F2, NONE, DEEP, NF1), /* RGI Data */ + PAD_CFG_NF(GPP_F3, UP_20K, DEEP, NF1), /* RGI Response */ + PAD_CFG_NF(GPP_F4, NONE, DEEP, NF1), /* RF Reset */ + PAD_CFG_NF(GPP_F5, NONE, DEEP, NF2), /* Modem Clock Request */ + PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_CFG_GPO(GPP_A13, 1, DEEP), /* Bluetooth RF Kill */ + + /* Display */ + PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), /* eDP Hot Plug */ + PAD_CFG_NF(GPP_A18, NONE, DEEP, NF1), /* HDMI Hot Plug */ + PAD_CFG_NF(GPP_H15, NONE, DEEP, NF1), /* HDMI Clock */ + PAD_CFG_NF(GPP_H17, NONE, DEEP, NF1), /* HDMI Data */ + PAD_CFG_NF(GPP_A19, NONE, DEEP, NF1), /* TCP0 Hot Plug */ + PAD_CFG_NF(GPP_A20, NONE, DEEP, NF1), /* TCP0 Hot Plug */ + + /* High-Definition Audio */ + PAD_CFG_NF(GPP_R0, NATIVE, DEEP, NF1), /* Clock */ + PAD_CFG_NF(GPP_R1, NATIVE, DEEP, NF1), /* Sync */ + PAD_CFG_NF(GPP_R2, NATIVE, DEEP, NF1), /* Data Output */ + PAD_CFG_NF(GPP_R3, NATIVE, DEEP, NF1), /* Data Input */ + PAD_CFG_NF(GPP_R4, NATIVE, DEEP, NF1), /* Reset */ + + /* PCH */ + PAD_CFG_NF(GPP_H18, NONE, DEEP, NF1), /* C10 Gate */ + PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), /* Platform Reset */ + PAD_CFG_NF(GPP_B0, NONE, DEEP, NF1), /* Vendor ID 0 */ + PAD_CFG_NF(GPP_B1, NONE, DEEP, NF1), /* Vendor ID 1 */ + PAD_CFG_GPI_SCI(GPP_B2, NONE, PLTRST, EDGE_SINGLE, INVERT), /* Processor Hot */ + + /* SMBus */ + PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* Clock */ + PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* Data */ + PAD_CFG_GPO(GPP_E8, 1, DEEP), /* DRAM Sleep */ + + /* Config Straps [ Low / High ] */ + PAD_CFG_GPO(GPP_B14, 0, PLTRST), /* Top Swap [ Disabled / Enabled ] */ + PAD_CFG_GPO(GPP_B18, 0, PLTRST), /* Reboot Support [ Enabled / Disabled ] */ + PAD_CFG_GPO(GPP_C2, 1, PLTRST), /* TLS Confidentiality [ Disabled / Enabled ] */ + PAD_CFG_GPO(GPP_C5, 0, + PLTRST), /* eSPI [ Enabled / Disabled ] */ + PAD_CFG_GPO(GPP_E6, 0, PLTRST), /* JTAG ODT [ Disabled / Enabled ] */ + PAD_CFG_GPO(GPP_H1, 0, PLTRST), /* BFX Strap 2 Bit 3 [ Disabled / Enabled ] */ + PAD_CFG_GPO(GPP_E19, 0, PLTRST), /* TBT LSX #0 [ 1.8V / 3.3V ] */ + PAD_CFG_GPO(GPP_E21, 0, PLTRST), /* TBT LSX #1 [ 1.8V / 3.3V ] */ + PAD_CFG_GPO(GPP_D10, 0, PLTRST), /* TBT LSX #2 [ 1.8V / 3.3V ] */ + PAD_CFG_GPO(GPP_D12, 0, PLTRST), /* TBT LSX #3 [ 1.8V / 3.3V ] */ + PAD_CFG_GPO(GPP_F7, 0, PLTRST), /* MCRO LDO [ Disabled / Bypass ] */ + PAD_CFG_GPO(GPD7, 0, PLTRST), /* RTC Clock Delay [ Disabled / 95ms ] */ + + PAD_NC(GPD2, NONE), + PAD_NC(GPD6, NONE), + PAD_NC(GPD9, NONE), + PAD_NC(GPD10, NONE), + PAD_NC(GPD11, NONE), + + PAD_NC(GPP_A5, NONE), + PAD_NC(GPP_A6, NONE), + PAD_NC(GPP_A7, NONE), + PAD_NC(GPP_A8, NONE), + PAD_NC(GPP_A11, NONE), + PAD_NC(GPP_A12, NONE), + PAD_NC(GPP_A14, NONE), + PAD_NC(GPP_A15, NONE), + PAD_NC(GPP_A16, NONE), + PAD_NC(GPP_A17, NONE), + PAD_NC(GPP_A21, NONE), + PAD_NC(GPP_A22, NONE), + PAD_NC(GPP_A23, NONE), + + PAD_NC(GPP_B3, NONE), + PAD_NC(GPP_B4, NONE), + PAD_NC(GPP_B7, NONE), + PAD_NC(GPP_B8, NONE), + PAD_NC(GPP_B9, NONE), + PAD_NC(GPP_B10, NONE), + PAD_NC(GPP_B11, NONE), + PAD_NC(GPP_B12, NONE), + PAD_NC(GPP_B15, NONE), + PAD_NC(GPP_B16, NONE), + PAD_NC(GPP_B17, NONE), + PAD_NC(GPP_B19, NONE), + PAD_NC(GPP_B20, NONE), + PAD_NC(GPP_B21, NONE), + PAD_NC(GPP_B22, NONE), + PAD_NC(GPP_B23, NONE), + PAD_NC(GPP_B24, NONE), + PAD_NC(GPP_B25, NONE), + + PAD_NC(GPP_C3, NONE), + PAD_NC(GPP_C4, NONE), + PAD_NC(GPP_C6, NONE), + PAD_NC(GPP_C7, NONE), + PAD_NC(GPP_C8, NONE), + PAD_NC(GPP_C9, NONE), + PAD_NC(GPP_C10, NONE), + PAD_NC(GPP_C11, NONE), + PAD_NC(GPP_C12, NONE), + PAD_NC(GPP_C13, NONE), + PAD_NC(GPP_C14, NONE), + PAD_NC(GPP_C15, NONE), + PAD_NC(GPP_C16, NONE), + PAD_NC(GPP_C17, NONE), + PAD_NC(GPP_C18, NONE), + PAD_NC(GPP_C19, NONE), + PAD_NC(GPP_C20, NONE), + PAD_NC(GPP_C21, NONE), + PAD_NC(GPP_C22, NONE), + PAD_NC(GPP_C23, NONE), + + PAD_NC(GPP_D0, NONE), + PAD_NC(GPP_D1, NONE), + PAD_NC(GPP_D2, NONE), + PAD_NC(GPP_D3, NONE), + PAD_NC(GPP_D4, NONE), + PAD_NC(GPP_D6, NONE), + PAD_NC(GPP_D7, NONE), + PAD_NC(GPP_D8, NONE), + PAD_NC(GPP_D9, NONE), + PAD_NC(GPP_D11, NONE), + PAD_NC(GPP_D13, NONE), + PAD_NC(GPP_D14, NONE), + PAD_NC(GPP_D15, NONE), + PAD_NC(GPP_D17, NONE), + PAD_NC(GPP_D18, NONE), + PAD_NC(GPP_D19, NONE), + + PAD_NC(GPP_E0, NONE), + PAD_NC(GPP_E1, NONE), + PAD_NC(GPP_E2, NONE), + PAD_NC(GPP_E4, NONE), + PAD_NC(GPP_E5, NONE), + PAD_NC(GPP_E7, NONE), + PAD_NC(GPP_E9, NONE), + PAD_NC(GPP_E10, NONE), + PAD_NC(GPP_E11, NONE), + PAD_NC(GPP_E13, NONE), + PAD_NC(GPP_E15, NONE), + PAD_NC(GPP_E16, NONE), + PAD_NC(GPP_E17, NONE), + PAD_NC(GPP_E18, NONE), + PAD_NC(GPP_E20, NONE), + PAD_NC(GPP_E22, NONE), + PAD_NC(GPP_E23, NONE), + + PAD_NC(GPP_F6, NONE), + PAD_NC(GPP_F8, NONE), + PAD_NC(GPP_F9, NONE), + PAD_NC(GPP_F10, NONE), + PAD_NC(GPP_F11, NONE), + PAD_NC(GPP_F12, NONE), + PAD_NC(GPP_F13, NONE), + PAD_NC(GPP_F14, NONE), + PAD_NC(GPP_F16, NONE), + PAD_NC(GPP_F19, NONE), + PAD_NC(GPP_F20, NONE), + PAD_NC(GPP_F21, NONE), + PAD_NC(GPP_F22, NONE), + PAD_NC(GPP_F23, NONE), + + PAD_NC(GPP_H2, NONE), + PAD_NC(GPP_H3, NONE), + PAD_NC(GPP_H6, NONE), + PAD_NC(GPP_H7, NONE), + PAD_NC(GPP_H8, NONE), + PAD_NC(GPP_H9, NONE), + PAD_NC(GPP_H12, NONE), + PAD_NC(GPP_H13, NONE), + PAD_NC(GPP_H14, NONE), + PAD_NC(GPP_H16, NONE), + PAD_NC(GPP_H19, NONE), + PAD_NC(GPP_H20, NONE), + PAD_NC(GPP_H21, NONE), + PAD_NC(GPP_H22, NONE), + PAD_NC(GPP_H23, NONE), + + PAD_NC(GPP_S0, NONE), + PAD_NC(GPP_S1, NONE), + PAD_NC(GPP_S2, NONE), + PAD_NC(GPP_S3, NONE), + PAD_NC(GPP_S4, NONE), + PAD_NC(GPP_S5, NONE), + PAD_NC(GPP_S6, NONE), + PAD_NC(GPP_S7, NONE), + + PAD_NC(GPP_T0, NONE), + PAD_NC(GPP_T1, NONE), + PAD_NC(GPP_T2, NONE), + PAD_NC(GPP_T3, NONE), + PAD_NC(GPP_T4, NONE), + PAD_NC(GPP_T5, NONE), + PAD_NC(GPP_T6, NONE), + PAD_NC(GPP_T7, NONE), + PAD_NC(GPP_T8, NONE), + PAD_NC(GPP_T9, NONE), + PAD_NC(GPP_T10, NONE), + PAD_NC(GPP_T11, NONE), + PAD_NC(GPP_T12, NONE), + PAD_NC(GPP_T13, NONE), + PAD_NC(GPP_T14, NONE), + PAD_NC(GPP_T15, NONE), + + PAD_NC(GPP_R5, NONE), + PAD_NC(GPP_R6, NONE), + PAD_NC(GPP_R7, NONE), +}; + +const struct pad_config *variant_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(gpio_table); + return gpio_table; +} diff --git a/src/mainboard/starlabs/adl/variants/i5/hda_verb.c b/src/mainboard/starlabs/adl/variants/i5/hda_verb.c new file mode 100644 index 00000000000..f7529371d66 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/i5/hda_verb.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +const u32 cim_verb_data[] = { + /* coreboot specific header */ + 0x10ec0269, /* Codec Vendor / Device ID: Realtek ALC269 */ + 0x1e507038, /* Subsystem ID */ + 18, /* Number of jacks (NID entries) */ + + /* Reset Codec First */ + AZALIA_RESET(0x1), + + /* HDA Codec Subsystem ID */ + AZALIA_SUBVENDOR(0, 0x1e507038), + + /* Pin Widget Verb-table */ + AZALIA_PIN_CFG(0, ALC269_DMIC12, + AZALIA_PIN_DESC(AZALIA_INTEGRATED, AZALIA_INTERNAL | AZALIA_FRONT, + AZALIA_MIC_IN, AZALIA_OTHER_DIGITAL, + AZALIA_COLOR_UNKNOWN, AZALIA_NO_JACK_PRESENCE_DETECT, 3, + 0)), + + AZALIA_PIN_CFG(0, ALC269_SPEAKERS, + AZALIA_PIN_DESC(AZALIA_INTEGRATED, AZALIA_INTERNAL | AZALIA_FRONT, + AZALIA_SPEAKER, AZALIA_OTHER_ANALOG, + AZALIA_COLOR_UNKNOWN, AZALIA_NO_JACK_PRESENCE_DETECT, 1, + 0)), + AZALIA_PIN_CFG(0, ALC269_VC_HP_OUT, + AZALIA_PIN_DESC(AZALIA_JACK, + AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, + AZALIA_HP_OUT, AZALIA_STEREO_MONO_1_8, AZALIA_BLACK, + AZALIA_JACK_PRESENCE_DETECT, 2, 0)), + AZALIA_PIN_CFG(0, ALC269_MIC1, + AZALIA_PIN_DESC(AZALIA_JACK, + AZALIA_EXTERNAL_PRIMARY_CHASSIS | AZALIA_RIGHT, + AZALIA_MIC_IN, AZALIA_STEREO_MONO_1_8, AZALIA_BLACK, + AZALIA_JACK_PRESENCE_DETECT, 4, 0)), + AZALIA_PIN_CFG(0, ALC269_MONO, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, ALC269_MIC2, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, ALC269_LINE1, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, ALC269_LINE2, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, ALC269_PC_BEEP, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, ALC269_SPDIF_OUT, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, ALC269_VB_HP_OUT, AZALIA_PIN_CFG_NC(0)), + + /* ALC269 Default 1 */ + 0x02050018, + 0x02040184, + 0x0205001c, + 0x02044800, + /* ALC269 Default 2 */ + 0x02050024, + 0x02040000, + 0x02050004, + 0x02040080, + /* ALC269 Default 3 */ + 0x02050008, + 0x02040000, + 0x0205000c, + 0x02043f00, + /* ALC269 Default 4 */ + 0x02050015, + 0x02048002, + 0x02050015, + 0x02048002, + /* Widget 0x0c */ + 0x00c37080, + 0x00270610, + 0x00d37080, + 0x00370610, +}; + +const u32 pc_beep_verbs[] = {}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/starlabs/adl/variants/i5/mainboard_ssdt.c b/src/mainboard/starlabs/adl/variants/i5/mainboard_ssdt.c new file mode 100644 index 00000000000..a58becd7f6e --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/i5/mainboard_ssdt.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void starlabs_adl_mainboard_fill_ssdt(const struct device *dev) +{ + enum ps2_action_key ps2_action_keys[2] = { PS2_KEY_VOL_DOWN, PS2_KEY_VOL_UP }; + + (void)dev; + + acpigen_ps2_keyboard_dsd("_SB.PCI0.PS2K", ARRAY_SIZE(ps2_action_keys), ps2_action_keys, + false, false, false, false, false); +} diff --git a/src/mainboard/starlabs/adl/variants/i5/ramstage.c b/src/mainboard/starlabs/adl/variants/i5/ramstage.c new file mode 100644 index 00000000000..370f5c87696 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/i5/ramstage.c @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void mainboard_silicon_init_params(FSP_S_CONFIG *supd) +{ + configure_pin_mux(supd); +} + +const char *mainboard_vbt_filename(void) +{ + if (get_uint_option("display_native_res", 0) == 1) + return "vbt_native_res.bin"; + + return "vbt.bin"; +} diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/romstage.c b/src/mainboard/starlabs/adl/variants/i5/romstage.c similarity index 99% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/romstage.c rename to src/mainboard/starlabs/adl/variants/i5/romstage.c index 235a8b4565e..13c31ea8099 100644 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/romstage.c +++ b/src/mainboard/starlabs/adl/variants/i5/romstage.c @@ -31,7 +31,7 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) .dq0 = { 3, 2, 1, 0, 7, 4, 6, 5 }, .dq1 = { 8, 10, 11, 9, 14, 13, 12, 15 }, }, - .ddr6 = { + .ddr5 = { .dq0 = { 8, 9, 10, 11, 12, 13, 14, 15 }, .dq1 = { 7, 6, 5, 4, 3, 2, 1, 0 }, }, diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/vboot.fmd b/src/mainboard/starlabs/adl/variants/i5/vboot.fmd similarity index 100% rename from src/mainboard/starlabs/starlite_adl/variants/mk_v/vboot.fmd rename to src/mainboard/starlabs/adl/variants/i5/vboot.fmd diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/Makefile.mk b/src/mainboard/starlabs/adl/variants/y2/Makefile.mk similarity index 79% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/Makefile.mk rename to src/mainboard/starlabs/adl/variants/y2/Makefile.mk index 9abc069b388..05782dbcc6b 100644 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/Makefile.mk +++ b/src/mainboard/starlabs/adl/variants/y2/Makefile.mk @@ -2,6 +2,8 @@ bootblock-y += gpio.c +smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c + romstage-y += romstage.c ramstage-y += devtree.c diff --git a/src/mainboard/starlabs/adl/variants/y2/board.fmd b/src/mainboard/starlabs/adl/variants/y2/board.fmd new file mode 100644 index 00000000000..21972622372 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/y2/board.fmd @@ -0,0 +1,14 @@ +FLASH 0x1000000 { + SI_ALL 0x600000 { + SI_DESC 0x1000 + SI_ME 0x411000 + } + SI_BIOS 0xa00000 { + EC@0x0 0x20000 + RW_MRC_CACHE@0x20000 0x10000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 + COREBOOT(CBFS) + } +} diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/data.vbt b/src/mainboard/starlabs/adl/variants/y2/data.vbt similarity index 100% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/data.vbt rename to src/mainboard/starlabs/adl/variants/y2/data.vbt diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devicetree.cb b/src/mainboard/starlabs/adl/variants/y2/devicetree.cb similarity index 98% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/devicetree.cb rename to src/mainboard/starlabs/adl/variants/y2/devicetree.cb index 40635bde30a..c8d856cc03a 100644 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devicetree.cb +++ b/src/mainboard/starlabs/adl/variants/y2/devicetree.cb @@ -155,7 +155,8 @@ chip soc/intel/alderlake }" chip drivers/pcie/generic - register "wake_gpe" = "GPE0_PME_B0" + register "wake_gpe" = "GPE0_LAN_WAK" + register "wake_deepest" = "ACPI_S5" device generic 0 on end end smbios_slot_desc "SlotTypePciExpressGen4x1" @@ -172,7 +173,8 @@ chip soc/intel/alderlake .PcieRpL1Substates = L1_SS_L1_2, }" chip drivers/pcie/generic - register "wake_gpe" = "GPE0_PME_B0" + register "wake_gpe" = "GPE0_LAN_WAK" + register "wake_deepest" = "ACPI_S5" device generic 0 on end end smbios_slot_desc "SlotTypePciExpressGen3X4" @@ -187,7 +189,6 @@ chip soc/intel/alderlake .flags = PCIE_RP_LTR | PCIE_RP_AER, .pcie_rp_aspm = ASPM_L0S_L1, .PcieRpL1Substates = L1_SS_L1_2, - .pcie_rp_detect_timeout_ms = 50, }" smbios_slot_desc "SlotTypePciExpressGen3X4" "SlotLengthLong" diff --git a/src/mainboard/starlabs/adl/variants/y2/devtree.c b/src/mainboard/starlabs/adl/variants/y2/devtree.c new file mode 100644 index 00000000000..aaa5fdafae6 --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/y2/devtree.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void devtree_update(void) +{ + config_t *cfg = config_of_soc(); + update_power_limits(cfg); + + /* Enable/Disable WiFi based on CMOS settings */ + if (get_uint_option("wifi", 1) == 0) + DEV_PTR(cnvi_wifi)->enabled = 0; + + /* Enable/Disable Bluetooth based on CMOS settings */ + if (get_uint_option("bluetooth", 1) == 0) + cfg->usb2_ports[9].enable = 0; + + /* Enable/Disable GNA based on CMOS settings */ + if (get_uint_option("gna", 0) == 0) + DEV_PTR(gna)->enabled = 0; +} diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/gpio.c b/src/mainboard/starlabs/adl/variants/y2/gpio.c similarity index 87% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/gpio.c rename to src/mainboard/starlabs/adl/variants/y2/gpio.c index bddabb14dbe..849daadd571 100644 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/gpio.c +++ b/src/mainboard/starlabs/adl/variants/y2/gpio.c @@ -1,12 +1,42 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset deasserted */ +}; + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_D5, NONE, DEEP), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ }; const struct pad_config *variant_early_gpio_table(size_t *num) @@ -20,6 +50,7 @@ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ PAD_CFG_NF(GPD1, NONE, DEEP, NF1), /* Charger Connected */ + PAD_CFG_NF(GPD2, NATIVE, PWROK, NF1), /* LAN Wake */ PAD_CFG_NF(GPD3, UP_20K, DEEP, NF1), /* Power Button */ PAD_CFG_NF(GPD4, NONE, DEEP, NF1), /* Sleep S3 */ PAD_CFG_NF(GPD5, NONE, DEEP, NF1), /* Sleep S4 */ @@ -35,9 +66,9 @@ const struct pad_config gpio_table[] = { // PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A10, NONE, DEEP, NF1), /* eSPI Reset */ /* SSD */ - PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ - PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_NC(GPP_D5, NONE), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ PAD_CFG_NF(GPP_H13, NONE, DEEP, NF5), /* Device Sleep */ PAD_CFG_NF(GPP_A12, NONE, DEEP, NF1), /* PEDET */ @@ -85,7 +116,7 @@ const struct pad_config gpio_table[] = { PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), /* Data */ PAD_CFG_GPO(GPP_E8, 1, DEEP), /* DRAM Sleep */ - /* Config Straps [ Low / High ] */ + /* Config Straps [ Low / High ] */ PAD_CFG_GPO(GPP_B14, 0, PLTRST), /* Top Swap [ Disabled / Enabled ] */ PAD_CFG_GPO(GPP_B18, 0, PLTRST), /* Reboot Support [ Enabled / Disabled ] */ PAD_CFG_GPO(GPP_C2, 1, PLTRST), /* TLS Confidentiality [ Disabled / Enabled ] */ @@ -99,7 +130,6 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPO(GPP_F7, 0, PLTRST), /* MCRO LDO [ Disabled / Bypass ] */ PAD_CFG_GPO(GPD7, 0, PLTRST), /* RTC Clock Delay [ Disabled / 95ms ] */ - PAD_NC(GPD2, NONE), PAD_NC(GPD6, NONE), PAD_NC(GPD9, NONE), PAD_NC(GPD11, NONE), diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/hda_verb.c b/src/mainboard/starlabs/adl/variants/y2/hda_verb.c similarity index 97% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/hda_verb.c rename to src/mainboard/starlabs/adl/variants/y2/hda_verb.c index 9b87198c4ac..203d5c1961b 100644 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/hda_verb.c +++ b/src/mainboard/starlabs/adl/variants/y2/hda_verb.c @@ -59,7 +59,7 @@ const uint32_t cim_verb_data[] = { AZALIA_PIN_CFG(0, 0x16, 0x04214040), AZALIA_PIN_CFG(0, 0x18, 0x40f001f0), - AZALIA_PIN_CFG(0, 0x1a, 0x90a72150), + AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)), AZALIA_PIN_CFG(0, 0x19, 0x04a19020), AZALIA_PIN_CFG(0, 0x1d, 0x00000000), AZALIA_PIN_CFG(0, 0x1e, 0x00000000), diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/ramstage.c b/src/mainboard/starlabs/adl/variants/y2/ramstage.c similarity index 100% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/ramstage.c rename to src/mainboard/starlabs/adl/variants/y2/ramstage.c diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/romstage.c b/src/mainboard/starlabs/adl/variants/y2/romstage.c similarity index 100% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/romstage.c rename to src/mainboard/starlabs/adl/variants/y2/romstage.c diff --git a/src/mainboard/starlabs/adl/variants/y2/smihandler.c b/src/mainboard/starlabs/adl/variants/y2/smihandler.c new file mode 100644 index 00000000000..fa77eb0568e --- /dev/null +++ b/src/mainboard/starlabs/adl/variants/y2/smihandler.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include + +void mainboard_smi_sleep_finalize(u8 slp_typ) +{ + if (slp_typ != ACPI_S5) + return; + + /* + * Keep LAN_WAKE# armed in S5 for WOL. + * GPE0_LAN_WAK is GPE 112, which is bit 16 in the STD GPE block (127:96). + */ + const uint32_t lan_wake_mask = 1U << (GPE0_LAN_WAK - 96); + + /* Clear any pending LAN_WAKE event to avoid immediate wake. */ + outl(lan_wake_mask, ACPI_BASE_ADDRESS + GPE0_STS(GPE_STD)); + pmc_enable_std_gpe(lan_wake_mask); + outl(lan_wake_mask, ACPI_BASE_ADDRESS + GPE0_STS(GPE_STD)); +} diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/vboot.fmd b/src/mainboard/starlabs/adl/variants/y2/vboot.fmd similarity index 100% rename from src/mainboard/starlabs/byte_adl/variants/mk_ii/vboot.fmd rename to src/mainboard/starlabs/adl/variants/y2/vboot.fmd diff --git a/src/mainboard/starlabs/byte_adl/vboot.c b/src/mainboard/starlabs/adl/vboot.c similarity index 100% rename from src/mainboard/starlabs/byte_adl/vboot.c rename to src/mainboard/starlabs/adl/vboot.c diff --git a/src/mainboard/starlabs/byte_adl/Kconfig b/src/mainboard/starlabs/byte_adl/Kconfig deleted file mode 100644 index 04bdcc8ee28..00000000000 --- a/src/mainboard/starlabs/byte_adl/Kconfig +++ /dev/null @@ -1,113 +0,0 @@ -config BOARD_STARLABS_BYTE_SERIES - def_bool n - select AZALIA_USE_LEGACY_VERB_TABLE - select BOARD_ROMSIZE_KB_16384 - select CRB_TPM - select CSE_DEFAULT_CFR_OPTION_STATE_DISABLED - select DRIVERS_EFI_VARIABLE_STORE - select DRIVERS_INTEL_PMC - select DRIVERS_OPTION_CFR_ENABLED - select DRIVERS_PCIE_GENERIC - select EC_STARLABS_FAN - select EC_STARLABS_MERLIN - select HAVE_ACPI_RESUME - select HAVE_ACPI_TABLES - select HAVE_INTEL_PTT - select HAVE_OPTION_TABLE - select INTEL_GMA_HAVE_VBT - select INTEL_LPSS_UART_FOR_CONSOLE - select NO_UART_ON_SUPERIO - select PMC_IPC_ACPI_INTERFACE - select SOC_INTEL_COMMON_BLOCK_HDA_VERB - select SOC_INTEL_COMMON_BLOCK_TCSS - select SOC_INTEL_CRASHLOG - select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES - select SPD_READ_BY_WORD - select SPI_FLASH_WINBOND - select SYSTEM_TYPE_MINIPC - select TPM2 - select VALIDATE_INTEL_DESCRIPTOR - -config BOARD_STARLABS_BYTE_ADL - select BOARD_STARLABS_BYTE_SERIES - select SOC_INTEL_ALDERLAKE - select SOC_INTEL_ALDERLAKE_PCH_N - -config BOARD_STARLABS_BYTE_TWL - select BOARD_STARLABS_BYTE_SERIES - select SOC_INTEL_ALDERLAKE - select SOC_INTEL_TWINLAKE - -if BOARD_STARLABS_BYTE_SERIES - -config CONSOLE_SERIAL - default n if !EDK2_DEBUG - -config D3COLD_SUPPORT - default n - -config DEVICETREE - default "variants/\$(CONFIG_VARIANT_DIR)/devicetree.cb" - -config DIMM_SPD_SIZE - default 512 - -config EC_STARLABS_ITE_BIN_PATH - string - default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/ec.bin" - -config FMDFILE - default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/vboot.fmd" if VBOOT - default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" - -config IFD_BIN_PATH - string - default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/flashdescriptor.bin" - -config MAINBOARD_DIR - default "starlabs/byte_adl" - -config MAINBOARD_FAMILY - string - default "Y3" if BOARD_STARLABS_BYTE_TWL - default "Y2" - -config MAINBOARD_PART_NUMBER - default "Byte Mk III" if BOARD_STARLABS_BYTE_TWL - default "Byte Mk II" - -config MAINBOARD_SMBIOS_PRODUCT_NAME - default "Byte" - -config ME_BIN_PATH - string - default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/intel_me.bin" - -config PL4_WATTS - int - default 65 if BOARD_STARLABS_BYTE_TWL - default 36 - -config POWER_STATE_DEFAULT_ON_AFTER_FAILURE - default n - -config EDK2_BOOTSPLASH_FILE - string - default "3rdparty/blobs/mainboard/starlabs/Logo.bmp" - -config SOC_INTEL_CSE_SEND_EOP_EARLY - default n - -config UART_FOR_CONSOLE - default 0 - -config USE_PM_ACPI_TIMER - default n - -config VBOOT - select VBOOT_VBNV_FLASH - -config VARIANT_DIR - default "mk_ii" - -endif diff --git a/src/mainboard/starlabs/byte_adl/Kconfig.name b/src/mainboard/starlabs/byte_adl/Kconfig.name deleted file mode 100644 index bb393c0daa4..00000000000 --- a/src/mainboard/starlabs/byte_adl/Kconfig.name +++ /dev/null @@ -1,7 +0,0 @@ -comment "Star Labs Byte Series" - -config BOARD_STARLABS_BYTE_ADL - bool "Star Labs Byte Mk II (N200)" - -config BOARD_STARLABS_BYTE_TWL - bool "Star Labs Byte Mk III (N355)" diff --git a/src/mainboard/starlabs/byte_adl/Makefile.mk b/src/mainboard/starlabs/byte_adl/Makefile.mk deleted file mode 100644 index 678662b55df..00000000000 --- a/src/mainboard/starlabs/byte_adl/Makefile.mk +++ /dev/null @@ -1,13 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include -subdirs-y += variants/$(VARIANT_DIR) - -bootblock-y += bootblock.c - -verstage-$(CONFIG_VBOOT) += vboot.c - -romstage-$(CONFIG_VBOOT) += vboot.c - -ramstage-$(CONFIG_DRIVERS_OPTION_CFR) += cfr.c -ramstage-y += mainboard.c diff --git a/src/mainboard/starlabs/byte_adl/board_info.txt b/src/mainboard/starlabs/byte_adl/board_info.txt deleted file mode 100644 index 86a76f61262..00000000000 --- a/src/mainboard/starlabs/byte_adl/board_info.txt +++ /dev/null @@ -1,6 +0,0 @@ -Vendor name: Star Labs -Board name: Byte -Category: desktop -ROM protocol: SPI -ROM socketed: n -Flashrom support: y diff --git a/src/mainboard/starlabs/byte_adl/cfr.c b/src/mainboard/starlabs/byte_adl/cfr.c deleted file mode 100644 index 5a291707781..00000000000 --- a/src/mainboard/starlabs/byte_adl/cfr.c +++ /dev/null @@ -1,81 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include - -static struct sm_obj_form performance = { - .ui_name = "Performance", - .obj_list = (const struct sm_object *[]) { - &bluetooth_rtd3, - &fan_mode, - &power_profile, - NULL - }, -}; - -static struct sm_obj_form processor = { - .ui_name = "Processor", - .obj_list = (const struct sm_object *[]) { - &me_state, - &me_state_counter, - &s0ix_enable, - &vtd, - NULL - }, -}; - -static struct sm_obj_form power = { - .ui_name = "Power", - .obj_list = (const struct sm_object *[]) { - &power_on_after_fail_bool, - NULL - }, -}; - -static struct sm_obj_form devices = { - .ui_name = "Devices", - .obj_list = (const struct sm_object *[]) { - &bluetooth, - &gna, - &wifi, - NULL - }, -}; - -static struct sm_obj_form pci = { - .ui_name = "PCI", - .obj_list = (const struct sm_object *[]) { - &pciexp_clk_pm, - &pciexp_aspm, - &pciexp_l1ss, - NULL - }, -}; - -static struct sm_obj_form coreboot = { - .ui_name = "coreboot", - .obj_list = (const struct sm_object *[]) { - &debug_level, - NULL - }, -}; - -static struct sm_obj_form *sm_root[] = { - &performance, - &processor, - &power, - &devices, - &pci, - &coreboot, - NULL -}; - -void mb_cfr_setup_menu(struct lb_cfr *cfr_root) -{ - cfr_write_setup_menu(cfr_root, sm_root); -} diff --git a/src/mainboard/starlabs/byte_adl/cmos.layout b/src/mainboard/starlabs/byte_adl/cmos.layout deleted file mode 100644 index f78701f5d68..00000000000 --- a/src/mainboard/starlabs/byte_adl/cmos.layout +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -# ----------------------------------------------------------------- -entries - -# Bank: 1 -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory - -# ----------------------------------------------------------------- -# coreboot config options: ramtop -304 80 h 0 ramtop - -# RTC_BOOT_BYTE (coreboot hardcoded) -388 4 h 0 reboot_counter - -# coreboot config options: cpu -#400 8 r 0 reserved for century byte - -# coreboot config options: check sums -984 16 h 0 check_sum - -# Bank: 2 -# embedded controller settings (outside the checksummed area) -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable - -# ----------------------------------------------------------------- -checksums - -checksum 392 983 984 diff --git a/src/mainboard/starlabs/byte_adl/include/variants.h b/src/mainboard/starlabs/byte_adl/include/variants.h deleted file mode 100644 index c95d15bd721..00000000000 --- a/src/mainboard/starlabs/byte_adl/include/variants.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef _BASEBOARD_VARIANTS_H_ -#define _BASEBOARD_VARIANTS_H_ - -#include - -/* - * The next set of functions return the gpio table and fill in the number of - * entries for each table. - */ -const struct pad_config *variant_gpio_table(size_t *num); -const struct pad_config *variant_early_gpio_table(size_t *num); - -void devtree_update(void); - -#endif /* _BASEBOARD_VARIANTS_H_ */ diff --git a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devtree.c b/src/mainboard/starlabs/byte_adl/variants/mk_ii/devtree.c deleted file mode 100644 index b9746623fe8..00000000000 --- a/src/mainboard/starlabs/byte_adl/variants/mk_ii/devtree.c +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TJ_MAX 105 -#define TCC(temp) (TJ_MAX - temp) - -void devtree_update(void) -{ - config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_4core = - &cfg->power_limits_config[ADL_N_041_6W_CORE]; - struct soc_power_limits_config *soc_conf_8core = - &cfg->power_limits_config[ADL_N_041_15W_CORE]; - - struct device *wifi_dev = pcidev_on_root(0x14, 3); - struct device *gna_dev = pcidev_on_root(0x08, 0); - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_4core->tdp_pl4 = CONFIG_PL4_WATTS; - - /* Set PL1 to 50% of PL2 */ - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl2_override / 2) & ~1; - soc_conf_8core->tdp_pl1_override = (soc_conf_8core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(70); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(80); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(90); - break; - } - - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl1_override * performance_scale) / 100; - soc_conf_4core->tdp_pl2_override = (soc_conf_4core->tdp_pl2_override * performance_scale) / 100; - - soc_conf_8core->tdp_pl1_override = (soc_conf_8core->tdp_pl1_override * performance_scale) / 100; - soc_conf_8core->tdp_pl2_override = (soc_conf_8core->tdp_pl2_override * performance_scale) / 100; - - - /* Enable/Disable WiFi based on CMOS settings */ - if (get_uint_option("wifi", 1) == 0) - wifi_dev->enabled = 0; - - /* Enable/Disable Bluetooth based on CMOS settings */ - if (get_uint_option("bluetooth", 1) == 0) - cfg->usb2_ports[9].enable = 0; - - /* Enable/Disable GNA based on CMOS settings */ - if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; -} diff --git a/src/mainboard/starlabs/common/Kconfig b/src/mainboard/starlabs/common/Kconfig index 07239c89049..5501d43efe4 100644 --- a/src/mainboard/starlabs/common/Kconfig +++ b/src/mainboard/starlabs/common/Kconfig @@ -4,10 +4,50 @@ if VENDOR_STARLABS menu "Star Labs Settings" +config BOOTMEDIA_SMM_BWP + def_bool y + +config BOOTMEDIA_SMM_BWP_RUNTIME_OPTION + def_bool y + +config DRIVERS_EFI_FW_INFO + def_bool y + +config STARLABS_NVME_POWER_SEQUENCE + bool "Enable NVMe/M.2 slot power sequence" + depends on SOC_INTEL_COMMON_BLOCK_GPIO + default n + help + Enable Fatcat-style 3-stage NVMe/M.2 slot sequencing using PWREN, PERST# + and CLKREQ# pads. + + The sequencing is: + 1) pre-mem: PERST# asserted; PWREN=0; CLKREQ# disabled + 2) BS_PRE_DEVICE exit: PERST# still asserted; PWREN=1; CLKREQ# native + 3) BS_DEV_INIT_CHIPS entry: PERST# deasserted + + Boards selecting this option must provide their own pad configs and + implement stage 1 (pre-mem) in their early pad configuration. + + For stage 2 and stage 3, boards must either implement the + `variant_nvme_power_sequence_*()` helpers or provide pad tables via + `variant_nvme_power_sequence_pads()` and + `variant_nvme_power_sequence_post_pads()`. + config MB_COMMON_DIR string default "starlabs/common" +config STARLABS_ACPI_EFI_OPTION_SMI + bool "Expose coreboot options to ACPI via SMI (UEFI var store)" + depends on USE_UEFI_VARIABLE_STORE + depends on HAVE_ACPI_TABLES + default y + help + Provide ACPI methods that proxy a restricted set of coreboot options + (e.g. keyboard backlight and trackpad state) to the UEFI variable + store via an SMM APMC SMI handler. + source "src/mainboard/starlabs/common/hda/Kconfig" endmenu diff --git a/src/mainboard/starlabs/common/Makefile.mk b/src/mainboard/starlabs/common/Makefile.mk index 90c0d94d5a8..6887c47a7d7 100644 --- a/src/mainboard/starlabs/common/Makefile.mk +++ b/src/mainboard/starlabs/common/Makefile.mk @@ -6,4 +6,9 @@ subdirs-$(CONFIG_VENDOR_STARLABS) += powercap subdirs-$(CONFIG_VENDOR_STARLABS) += pin_mux subdirs-$(CONFIG_VENDOR_STARLABS) += smbios +ramstage-$(CONFIG_STARLABS_NVME_POWER_SEQUENCE) += nvme_seq.c + CPPFLAGS_common += -I$(src)/mainboard/starlabs/common/include + +ramstage-$(CONFIG_STARLABS_ACPI_EFI_OPTION_SMI) += gnvs.c +smm-$(CONFIG_STARLABS_ACPI_EFI_OPTION_SMI) += smihandler.c diff --git a/src/mainboard/starlabs/common/cfr/cfr.c b/src/mainboard/starlabs/common/cfr/cfr.c index 78a41814e5c..44ee68323ee 100644 --- a/src/mainboard/starlabs/common/cfr/cfr.c +++ b/src/mainboard/starlabs/common/cfr/cfr.c @@ -1,9 +1,27 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include void __weak cfr_card_reader_update(struct sm_object *new_obj) { (void)new_obj; } + +void __weak cfr_touchscreen_update(struct sm_object *new_obj) +{ + (void)new_obj; +} + +static const struct cfr_default_override starlabs_cfr_overrides[] = { + CFR_OVERRIDE_ENUM("pciexp_aspm", ASPM_L0S_L1), + CFR_OVERRIDE_END +}; + +void starlabs_cfr_register_overrides(void) +{ + if (!CONFIG(DRIVERS_OPTION_CFR)) + return; + cfr_register_overrides(starlabs_cfr_overrides); +} diff --git a/src/mainboard/starlabs/common/gnvs.c b/src/mainboard/starlabs/common/gnvs.c new file mode 100644 index 00000000000..7e119470ab5 --- /dev/null +++ b/src/mainboard/starlabs/common/gnvs.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +#include +#include + +size_t size_of_dnvs(void) +{ + return sizeof(struct starlabs_dnvs_efiopt); +} diff --git a/src/mainboard/starlabs/common/include/common/cfr.h b/src/mainboard/starlabs/common/include/common/cfr.h index 4a081c3c310..de4f1084046 100644 --- a/src/mainboard/starlabs/common/include/common/cfr.h +++ b/src/mainboard/starlabs/common/include/common/cfr.h @@ -4,9 +4,12 @@ #define _STARLABS_CMN_CFR_H_ #include +#include #include void cfr_card_reader_update(struct sm_object *new_obj); +void cfr_touchscreen_update(struct sm_object *new_obj); +void starlabs_cfr_register_overrides(void); static const struct sm_object accelerometer = SM_DECLARE_BOOL({ .opt_name = "accelerometer", @@ -27,14 +30,14 @@ static const struct sm_object bluetooth_rtd3 = SM_DECLARE_BOOL({ .ui_name = "Bluetooth Runtime-D3", .ui_helptext = "Enable or disable Bluetooth power optimization.\n" "Recommended to disable when booting Windows.", - .default_value = true, + .default_value = false, }); static const struct sm_object card_reader = SM_DECLARE_BOOL({ .opt_name = "card_reader", .ui_name = "Card Reader", .ui_helptext = "Enable or disable the built-in card reader", - .default_value = true, + .default_value = !CONFIG(BOARD_STARLABS_LITE_ADL), }, WITH_CALLBACK(cfr_card_reader_update)); static const struct sm_object display_native_res = SM_DECLARE_BOOL({ @@ -88,19 +91,11 @@ static const struct sm_object microphone = SM_DECLARE_BOOL({ .default_value = true, }); -static const struct sm_object pci_hot_plug = SM_DECLARE_BOOL({ - .opt_name = "pci_hot_plug", - .ui_name = "Third-Party SSD Support", - .ui_helptext = "Enables PCI Hot Plug, which slows down the SSD initialization. It" - " is required for certain third-party SSDs to be detected.", - .default_value = false, -}); - static const struct sm_object power_profile = SM_DECLARE_ENUM({ .opt_name = "power_profile", .ui_name = "Power Profile", .ui_helptext = "Select whether to maximize performance, battery life or both.", - .default_value = 1, + .default_value = PP_PERFORMANCE, .values = (const struct sm_enum_value[]) { { "Power Saver", PP_POWER_SAVER }, { "Balanced", PP_BALANCED }, @@ -129,7 +124,7 @@ static const struct sm_object touchscreen = SM_DECLARE_BOOL({ .ui_name = "Touchscreen", .ui_helptext = "Enable or disable the built-in touch-screen", .default_value = true, -}); +}, WITH_CALLBACK(cfr_touchscreen_update)); static const struct sm_object vpu = SM_DECLARE_BOOL({ .opt_name = "vpu", diff --git a/src/mainboard/starlabs/common/include/common/nvme_seq.h b/src/mainboard/starlabs/common/include/common/nvme_seq.h new file mode 100644 index 00000000000..fcd18380459 --- /dev/null +++ b/src/mainboard/starlabs/common/include/common/nvme_seq.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _STARLABS_CMN_NVME_SEQ_H_ +#define _STARLABS_CMN_NVME_SEQ_H_ + +#include +#include + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num); +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num); + +void variant_nvme_power_sequence_configure(void); +void variant_nvme_power_sequence_post_gpio_configure(void); + +#endif /* _STARLABS_CMN_NVME_SEQ_H_ */ diff --git a/src/mainboard/starlabs/common/include/common/powercap.h b/src/mainboard/starlabs/common/include/common/powercap.h index aa1d68f4185..2447ce9851e 100644 --- a/src/mainboard/starlabs/common/include/common/powercap.h +++ b/src/mainboard/starlabs/common/include/common/powercap.h @@ -3,6 +3,8 @@ #ifndef _STARLABS_CMN_POWERCAP_H_ #define _STARLABS_CMN_POWERCAP_H_ +#include + enum cmos_power_profile { PP_POWER_SAVER = 0, PP_BALANCED = 1, @@ -10,6 +12,6 @@ enum cmos_power_profile { }; #define NUM_POWER_PROFILES 3 -enum cmos_power_profile get_power_profile(enum cmos_power_profile fallback); +void update_power_limits(config_t *cfg); #endif diff --git a/src/mainboard/starlabs/common/include/starlabs/efi_option_smi.h b/src/mainboard/starlabs/common/include/starlabs/efi_option_smi.h new file mode 100644 index 00000000000..cdd6bf4a89e --- /dev/null +++ b/src/mainboard/starlabs/common/include/starlabs/efi_option_smi.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef STARLABS_EFI_OPTION_SMI_H +#define STARLABS_EFI_OPTION_SMI_H + +#include + +/* + * ACPI <-> SMM protocol for reading/writing a restricted set of coreboot + * options in the UEFI variable store. + * + * ACPI fills DNVS, then triggers an APMC SMI by writing STARLABS_APMC_CMD + * to the APM_CNT port (0xB2). SMM reads DNVS, performs the operation, and + * updates DNVS with status and (for reads) the returned value. + */ + +#define STARLABS_APMC_CMD_EFI_OPTION 0xE2 + +enum starlabs_efiopt_cmd { + STARLABS_EFIOPT_CMD_GET = 1, + STARLABS_EFIOPT_CMD_SET = 2, +}; + +enum starlabs_efiopt_id { + STARLABS_EFIOPT_ID_FN_LOCK_STATE = 1, + STARLABS_EFIOPT_ID_TRACKPAD_STATE = 2, + STARLABS_EFIOPT_ID_KBL_BRIGHTNESS = 3, + STARLABS_EFIOPT_ID_KBL_STATE = 4, +}; + +struct starlabs_dnvs_efiopt { + uint32_t cmd; + uint32_t id; + uint32_t value; + uint32_t status; +} __packed; + +#endif /* STARLABS_EFI_OPTION_SMI_H */ diff --git a/src/mainboard/starlabs/common/nvme_seq.c b/src/mainboard/starlabs/common/nvme_seq.c new file mode 100644 index 00000000000..5fef80865a4 --- /dev/null +++ b/src/mainboard/starlabs/common/nvme_seq.c @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +#if ENV_RAMSTAGE +const __weak struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = 0; + return NULL; +} + +const __weak struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = 0; + return NULL; +} + +__weak void variant_nvme_power_sequence_configure(void) +{ + size_t num; + const struct pad_config *pads = variant_nvme_power_sequence_pads(&num); + + if (pads && num) + gpio_configure_pads(pads, num); +} + +__weak void variant_nvme_power_sequence_post_gpio_configure(void) +{ + size_t num; + const struct pad_config *pads = variant_nvme_power_sequence_post_pads(&num); + + if (pads && num) + gpio_configure_pads(pads, num); +} +#endif + +/* + * Star Labs NVMe/M.2 slot power sequence glue. + * + * Boards/variants provide the actual pad configs (PWREN, PERST#, CLKREQ#). + * + * This file only owns the ramstage ordering so the staged overrides happen + * before PCIe enumeration/link training. + */ + +static void starlabs_nvme_power_sequence_step2(void *unused) +{ + /* Stage 2: power on + enable CLKREQ#, keep PERST# asserted. */ + variant_nvme_power_sequence_configure(); +} + +static void starlabs_nvme_power_sequence_step3(void *unused) +{ + /* Stage 3: deassert PERST# after GPIO configuration, before device init. */ + variant_nvme_power_sequence_post_gpio_configure(); +} + +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_EXIT, starlabs_nvme_power_sequence_step2, NULL); +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_ENTRY, starlabs_nvme_power_sequence_step3, NULL); diff --git a/src/mainboard/starlabs/common/powercap/powercap.c b/src/mainboard/starlabs/common/powercap/powercap.c index e19e6ec4035..21b879f5cfd 100644 --- a/src/mainboard/starlabs/common/powercap/powercap.c +++ b/src/mainboard/starlabs/common/powercap/powercap.c @@ -1,10 +1,60 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include +#include #include -enum cmos_power_profile get_power_profile(enum cmos_power_profile fallback) +static enum cmos_power_profile get_power_profile(enum cmos_power_profile fallback) { const unsigned int power_profile = get_uint_option("power_profile", fallback); return power_profile < NUM_POWER_PROFILES ? power_profile : fallback; } + +static uint16_t round_up_to_5(uint16_t value) +{ + return DIV_ROUND_UP(value, 5) * 5; +} + +void update_power_limits(config_t *cfg) +{ + uint8_t performance_scale = 100; + uint32_t performance_tcc_offset = CONFIG(EC_STARLABS_FAN) ? 10 : 20; + + /* Scale PL1 & PL2 based on CMOS settings */ + switch (get_power_profile(PP_POWER_SAVER)) { + case PP_POWER_SAVER: + performance_scale -= 50; + cfg->tcc_offset = performance_tcc_offset + 20; + break; + case PP_BALANCED: + performance_scale -= 25; + cfg->tcc_offset = performance_tcc_offset + 10; + break; + case PP_PERFORMANCE: + cfg->tcc_offset = performance_tcc_offset; + break; + } + + struct soc_power_limits_config *limits = + (struct soc_power_limits_config *)&cfg->power_limits_config; + size_t limit_count = + sizeof(cfg->power_limits_config) / sizeof(struct soc_power_limits_config); + + for (size_t i = 0; i < limit_count; i++) { + struct soc_power_limits_config *entry = &limits[i]; + uint16_t tdp, pl1, pl2; + + entry->tdp_pl4 = (uint16_t)CONFIG_MB_STARLABS_PL4_WATTS; + + tdp = entry->tdp_pl1_override; + if (!tdp) + continue; + + pl1 = (tdp * performance_scale) / 100; + pl2 = round_up_to_5(pl1 * 2); + + entry->tdp_pl1_override = pl1; + entry->tdp_pl2_override = pl2; + } +} diff --git a/src/mainboard/starlabs/common/smihandler.c b/src/mainboard/starlabs/common/smihandler.c new file mode 100644 index 00000000000..d74cce1008b --- /dev/null +++ b/src/mainboard/starlabs/common/smihandler.c @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#if CONFIG(SOC_INTEL_COMMON_BLOCK_FAST_SPI) +#include +#include +#include +#include +#endif +#include +#include +#include +#include + +#if CONFIG(SOC_INTEL_COMMON_BLOCK_FAST_SPI) +static void set_insmm_sts(const bool enable_writes) +{ + msr_t msr = { + .lo = read32p(0xfed30880), + .hi = 0, + }; + + if (enable_writes) + msr.lo |= 1; + else + msr.lo &= ~1; + + wrmsr(MSR_SPCL_CHIPSET_USAGE, msr); +} +#endif + +static bool chipset_disable_wp(void) +{ +#if CONFIG(SOC_INTEL_COMMON_BLOCK_FAST_SPI) + const bool wp_enabled = !fast_spi_wpd_status(); + + if (wp_enabled) { + set_insmm_sts(true); + /* + * As per BWG, clearing "SPI_BIOS_CONTROL_SYNC_SS" + * bit is a must prior setting SPI_BIOS_CONTROL_WPD" bit + * to avoid 3-strike error. + */ + fast_spi_clear_sync_smi_status(); + fast_spi_disable_wp(); + } + + return wp_enabled; +#endif + + return false; +} + +static void chipset_enable_wp(void) +{ +#if CONFIG(SOC_INTEL_COMMON_BLOCK_FAST_SPI) + fast_spi_enable_wp(); + set_insmm_sts(false); +#endif +} + +static struct starlabs_dnvs_efiopt *get_starlabs_dnvs_efiopt(void) +{ + if (!gnvs) + return NULL; + + const size_t gnvs_size = ALIGN_UP(sizeof(struct global_nvs), sizeof(uint64_t)); + + uint8_t *base = (uint8_t *)gnvs; + base += gnvs_size; + return (struct starlabs_dnvs_efiopt *)base; +} + +struct starlabs_efiopt_entry { + const char *name; + enum starlabs_efiopt_id id; + uint32_t fallback; +}; + +static const struct starlabs_efiopt_entry *find_efiopt(enum starlabs_efiopt_id id) +{ + static const struct starlabs_efiopt_entry opts[] = { + { + .name = "fn_lock_state", + .id = STARLABS_EFIOPT_ID_FN_LOCK_STATE, + .fallback = LOCKED, + }, + { + .name = "trackpad_state", + .id = STARLABS_EFIOPT_ID_TRACKPAD_STATE, + .fallback = TRACKPAD_ENABLED, + }, + { + .name = "kbl_brightness", + .id = STARLABS_EFIOPT_ID_KBL_BRIGHTNESS, + .fallback = CONFIG(EC_STARLABS_KBL_LEVELS) ? KBL_LOW : KBL_ON, + }, + { + .name = "kbl_state", + .id = STARLABS_EFIOPT_ID_KBL_STATE, + .fallback = KBL_ENABLED, + }, + }; + + for (size_t i = 0; i < ARRAY_SIZE(opts); i++) { + if (opts[i].id == id) + return &opts[i]; + } + + return NULL; +} + +static enum cb_err normalize_value(enum starlabs_efiopt_id id, uint32_t *value) +{ + if (!value) + return CB_ERR_ARG; + + switch (id) { + case STARLABS_EFIOPT_ID_FN_LOCK_STATE: + if (*value == UNLOCKED || *value == LOCKED) + return CB_SUCCESS; + return CB_ERR_ARG; + case STARLABS_EFIOPT_ID_TRACKPAD_STATE: + /* Normalize "re-enabled" to "enabled". */ + if (*value == 0x11) + *value = TRACKPAD_ENABLED; + if (*value == TRACKPAD_ENABLED || *value == TRACKPAD_DISABLED) + return CB_SUCCESS; + return CB_ERR_ARG; + case STARLABS_EFIOPT_ID_KBL_BRIGHTNESS: + if (*value == KBL_ON || *value == KBL_OFF || *value == KBL_LOW || + *value == KBL_HIGH) + return CB_SUCCESS; + return CB_ERR_ARG; + case STARLABS_EFIOPT_ID_KBL_STATE: + if (*value == KBL_DISABLED || *value == KBL_ENABLED) + return CB_SUCCESS; + return CB_ERR_ARG; + default: + return CB_ERR_ARG; + } +} + +int mainboard_smi_apmc(u8 data) +{ + if (data != STARLABS_APMC_CMD_EFI_OPTION) + return 0; + + struct starlabs_dnvs_efiopt *dnvs = get_starlabs_dnvs_efiopt(); + if (!dnvs) + return 0; + + const enum starlabs_efiopt_cmd cmd = dnvs->cmd; + const enum starlabs_efiopt_id id = dnvs->id; + const struct starlabs_efiopt_entry *opt = find_efiopt(id); + + if (!opt) { + dnvs->status = CB_ERR_ARG; + return 1; + } + + switch (cmd) { + case STARLABS_EFIOPT_CMD_GET: + dnvs->value = get_uint_option(opt->name, opt->fallback); + dnvs->status = CB_SUCCESS; + break; + case STARLABS_EFIOPT_CMD_SET: { + uint32_t value = dnvs->value; + dnvs->status = normalize_value(id, &value); + if (dnvs->status != CB_SUCCESS) + break; + + const bool wp_enabled = chipset_disable_wp(); + dnvs->status = set_uint_option(opt->name, value); + if (wp_enabled) + chipset_enable_wp(); + break; + } + default: + dnvs->status = CB_ERR_ARG; + break; + } + + return 1; +} diff --git a/src/mainboard/starlabs/lite/Kconfig b/src/mainboard/starlabs/lite/Kconfig index 8ea2101f695..a9fcd13ed7b 100644 --- a/src/mainboard/starlabs/lite/Kconfig +++ b/src/mainboard/starlabs/lite/Kconfig @@ -9,8 +9,6 @@ config BOARD_STARLABS_LITE_SERIES select DRIVERS_I2C_HID select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES - select HAVE_CMOS_DEFAULT - select HAVE_OPTION_TABLE select HAVE_INTEL_PTT select INTEL_GMA_HAVE_VBT select INTEL_LPSS_UART_FOR_CONSOLE @@ -83,6 +81,10 @@ config MAINBOARD_SMBIOS_PRODUCT_NAME config POWER_STATE_DEFAULT_ON_AFTER_FAILURE default n +config MB_STARLABS_PL4_WATTS + int + default 45 + config TRACKPAD_INTERRUPT hex default 0x1 if BOARD_STARLABS_LITE_GLK diff --git a/src/mainboard/starlabs/lite/board.fmd b/src/mainboard/starlabs/lite/board.fmd index 5e16badf5c1..065ea619bd4 100644 --- a/src/mainboard/starlabs/lite/board.fmd +++ b/src/mainboard/starlabs/lite/board.fmd @@ -44,7 +44,7 @@ # the header. FLASH 8M { OBBP@0x382000 { - OBB@0x0 0x2ae000 { + OBB@0x0 0x2ee000 { FMAP@0xe000 0x10000 COREBOOT(CBFS)@0x1e000 0x210000 FPF_STATUS@0x22e000 0x10000 @@ -53,7 +53,7 @@ FLASH 8M { RW_MRC_CACHE@0x10000 0x10000 RW_VAR_MRC_CACHE@0x20000 0x10000 } - SMMSTORE@0x26e000 0x40000 + SMMSTORE@0x26e000 0x80000 } } } diff --git a/src/mainboard/starlabs/lite/cfr.c b/src/mainboard/starlabs/lite/cfr.c index f9e42146cf5..4a91a46a066 100644 --- a/src/mainboard/starlabs/lite/cfr.c +++ b/src/mainboard/starlabs/lite/cfr.c @@ -8,84 +8,119 @@ #include #include -static struct sm_obj_form performance = { - .ui_name = "Performance", +static struct sm_obj_form audio_video_group = { + .ui_name = "Audio/Video", .obj_list = (const struct sm_object *[]) { - &power_profile, + µphone, + &webcam, NULL }, }; -static struct sm_obj_form processor = { - .ui_name = "Processor", +static struct sm_obj_form battery_group = { + .ui_name = "Battery", .obj_list = (const struct sm_object *[]) { - &s0ix_enable, - &vtd, + &power_on_after_fail_bool, NULL }, }; -static struct sm_obj_form power = { - .ui_name = "Power", +static struct sm_obj_form debug_group = { + .ui_name = "Debug", .obj_list = (const struct sm_object *[]) { - &power_on_after_fail_bool, + &debug_level, NULL }, }; -static struct sm_obj_form keyboard = { +static struct sm_obj_form io_expansion_group = { + .ui_name = "I/O / Expansion", + .obj_list = (const struct sm_object *[]) { + &card_reader, + NULL + }, +}; + +static struct sm_obj_form keyboard_group = { .ui_name = "Keyboard", .obj_list = (const struct sm_object *[]) { - &kbl_timeout, &fn_ctrl_swap, + &kbl_timeout, NULL }, }; -static struct sm_obj_form devices = { - .ui_name = "Devices", +static struct sm_obj_form security_group = { + .ui_name = "Security", .obj_list = (const struct sm_object *[]) { - &bluetooth, - &card_reader, - µphone, - &webcam, - &wifi, + &bios_lock, + &intel_tme, NULL }, }; -static struct sm_obj_form pci = { - .ui_name = "PCI", +static struct sm_obj_form pcie_power_management_group = { + .ui_name = "PCIe Power Management", .obj_list = (const struct sm_object *[]) { #if CONFIG(SOC_INTEL_ALDERLAKE) - &pciexp_clk_pm, &pciexp_aspm, + &pciexp_clk_pm, &pciexp_l1ss, #endif NULL }, }; -static struct sm_obj_form coreboot = { - .ui_name = "coreboot", +static struct sm_obj_form performance_group = { + .ui_name = "Performance", .obj_list = (const struct sm_object *[]) { - &debug_level, + &power_profile, + NULL + }, +}; + +static struct sm_obj_form suspend_lid_group = { + .ui_name = "Suspend & Lid", + .obj_list = (const struct sm_object *[]) { + &s0ix_enable, + NULL + }, +}; + +static struct sm_obj_form virtualization_group = { + .ui_name = "Virtualization", + .obj_list = (const struct sm_object *[]) { + &vtd, + NULL + }, +}; + +static struct sm_obj_form wireless_group = { + .ui_name = "Wireless", + .obj_list = (const struct sm_object *[]) { + &bluetooth, + &wifi, NULL }, }; static struct sm_obj_form *sm_root[] = { - &performance, - &processor, - &power, - &keyboard, - &devices, - &pci, - &coreboot, + &audio_video_group, + &battery_group, + &debug_group, + &io_expansion_group, + &keyboard_group, + &pcie_power_management_group, + &performance_group, + &security_group, + &suspend_lid_group, + &virtualization_group, + &wireless_group, NULL }; void mb_cfr_setup_menu(struct lb_cfr *cfr_root) { + starlabs_cfr_register_overrides(); cfr_write_setup_menu(cfr_root, sm_root); } diff --git a/src/mainboard/starlabs/lite/cmos.default b/src/mainboard/starlabs/lite/cmos.default deleted file mode 100644 index 49faae3e6a2..00000000000 --- a/src/mainboard/starlabs/lite/cmos.default +++ /dev/null @@ -1,6 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only -# Functions -fn_lock_state=0x1 -trackpad_state=0x1 -kbl_brightness=0x0 -kbl_state=0x1 diff --git a/src/mainboard/starlabs/lite/cmos.layout b/src/mainboard/starlabs/lite/cmos.layout deleted file mode 100644 index 3057effc83f..00000000000 --- a/src/mainboard/starlabs/lite/cmos.layout +++ /dev/null @@ -1,43 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -# ----------------------------------------------------------------- -entries - -# Bank: 1 -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory - -# ----------------------------------------------------------------- -# RTC_BOOT_BYTE (coreboot hardcoded) -388 4 h 0 reboot_counter - -# coreboot config options: cpu -#400 8 r 0 reserved for century byte - -# coreboot config options: check sums -984 16 h 0 check_sum - -# Bank: 2 -# embedded controller settings (outside the checksummed area) -1024 8 h 1 fn_lock_state -1032 8 h 1 trackpad_state -1040 8 h 2 kbl_brightness -1048 8 h 1 kbl_state - -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable - -2 0 Off -2 1 Low -2 2 High -2 3 On - -# ----------------------------------------------------------------- -checksums - -checksum 392 983 984 diff --git a/src/mainboard/starlabs/lite/devtree.c b/src/mainboard/starlabs/lite/devtree.c index b86c38b208f..afbd1bba113 100644 --- a/src/mainboard/starlabs/lite/devtree.c +++ b/src/mainboard/starlabs/lite/devtree.c @@ -15,38 +15,9 @@ void devtree_update(void) { config_t *cfg = config_of_soc(); - struct soc_power_limits_config *soc_conf = - &cfg->power_limits_config; - struct device *wifi_dev = pcidev_on_root(0x0c, 0); - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf->tdp_pl4 = 31; - - /* Set PL1 to 50% of PL2 */ - soc_conf->tdp_pl1_override = (soc_conf->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 25; - cfg->tcc_offset = 15; - break; - case PP_BALANCED: - /* Use the Intel defaults */ - cfg->tcc_offset = 10; - break; - case PP_PERFORMANCE: - performance_scale += 25; - cfg->tcc_offset = 5; - break; - } - - soc_conf->tdp_pl1_override = (soc_conf->tdp_pl1_override * performance_scale) / 100; - soc_conf->tdp_pl2_override = (soc_conf->tdp_pl2_override * performance_scale) / 100; - + update_power_limits(cfg); /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) diff --git a/src/mainboard/starlabs/lite/mainboard.c b/src/mainboard/starlabs/lite/mainboard.c index 04537094d0d..cd46529c0fb 100644 --- a/src/mainboard/starlabs/lite/mainboard.c +++ b/src/mainboard/starlabs/lite/mainboard.c @@ -11,8 +11,6 @@ static void init_mainboard(void *chip_info) pads = variant_gpio_table(&num); gpio_configure_pads(pads, num); - - devtree_update(); } struct chip_operations mainboard_ops = { diff --git a/src/mainboard/starlabs/starbook/Kconfig b/src/mainboard/starlabs/starbook/Kconfig index 7a7ac3919e1..bae92d02399 100644 --- a/src/mainboard/starlabs/starbook/Kconfig +++ b/src/mainboard/starlabs/starbook/Kconfig @@ -10,14 +10,13 @@ config BOARD_STARLABS_STARBOOK_SERIES select EC_STARLABS_FAN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES - select HAVE_CMOS_DEFAULT select HAVE_HDA_DMIC - select HAVE_OPTION_TABLE select INTEL_GMA_HAVE_VBT select INTEL_LPSS_UART_FOR_CONSOLE select NO_UART_ON_SUPERIO select SPD_READ_BY_WORD select SOC_INTEL_COMMON_BLOCK_HDA_VERB + select STARLABS_NVME_POWER_SEQUENCE select SYSTEM_TYPE_LAPTOP select VALIDATE_INTEL_DESCRIPTOR @@ -197,6 +196,11 @@ config POWER_STATE_DEFAULT_ON_AFTER_FAILURE config SOC_INTEL_CSE_SEND_EOP_EARLY default n +config MB_STARLABS_PL4_WATTS + int + default 45 if BOARD_STARLABS_LABTOP_KBL || BOARD_STARLABS_LABTOP_CML + default 65 + config TME_KEY_REGENERATION_ON_WARM_BOOT default n diff --git a/src/mainboard/starlabs/starbook/cfr.c b/src/mainboard/starlabs/starbook/cfr.c index cddc9af16fc..d2e8b7c9ae4 100644 --- a/src/mainboard/starlabs/starbook/cfr.c +++ b/src/mainboard/starlabs/starbook/cfr.c @@ -7,120 +7,172 @@ #include #include -static struct sm_obj_form performance = { - .ui_name = "Performance", +static struct sm_obj_form audio_video_group = { + .ui_name = "Audio/Video", .obj_list = (const struct sm_object *[]) { - &bluetooth_rtd3, - &fan_mode, - &power_profile, + µphone, + &webcam, NULL }, }; -static struct sm_obj_form processor = { - .ui_name = "Processor", +static struct sm_obj_form battery_group = { + .ui_name = "Battery", .obj_list = (const struct sm_object *[]) { - &me_state, - &me_state_counter, - #if CONFIG(BOARD_SUPPORTS_HT) - &hyper_threading, + #if CONFIG(EC_STARLABS_CHARGING_SPEED) + &charging_speed, #endif - &s0ix_enable, - &vtd, + &max_charge, + &power_on_after_fail_bool, NULL }, }; -static struct sm_obj_form power = { - .ui_name = "Power", +static struct sm_obj_form debug_group = { + .ui_name = "Debug", .obj_list = (const struct sm_object *[]) { - &max_charge, - #if CONFIG(EC_STARLABS_CHARGING_SPEED) - &charging_speed, + &debug_level, + NULL + }, +}; + +#if CONFIG(BOARD_USES_FIXED_MODE_VBT) +static struct sm_obj_form display_group = { + .ui_name = "Display", + .obj_list = (const struct sm_object *[]) { + &display_native_res, + NULL + }, +}; +#endif + +static struct sm_obj_form io_expansion_group = { + .ui_name = "I/O / Expansion", + .obj_list = (const struct sm_object *[]) { + &card_reader, + #if CONFIG(DRIVERS_INTEL_USB4_RETIMER) + &thunderbolt, #endif - &power_on_after_fail_bool, NULL }, }; -static struct sm_obj_form keyboard = { +static struct sm_obj_form keyboard_group = { .ui_name = "Keyboard", .obj_list = (const struct sm_object *[]) { - &kbl_timeout, &fn_ctrl_swap, + &kbl_timeout, NULL }, }; -static struct sm_obj_form devices = { - .ui_name = "Devices", +static struct sm_obj_form leds_group = { + .ui_name = "LEDs", .obj_list = (const struct sm_object *[]) { - &bluetooth, - &card_reader, - #if CONFIG(BOARD_USES_FIXED_MODE_VBT) - &display_native_res, + &charge_led, + &power_led, + NULL + }, +}; + +static struct sm_obj_form pcie_power_management_group = { + .ui_name = "PCIe Power Management", + .obj_list = (const struct sm_object *[]) { + #if CONFIG(SOC_INTEL_COMMON_BLOCK_ASPM) + #if CONFIG(BOARD_STARLABS_STARBOOK_RPL) + &pciexp_aspm_cpu, + #else + &pciexp_aspm, #endif - #if CONFIG(BOARD_HAS_FPR) - &fingerprint_reader, + &pciexp_clk_pm, + &pciexp_l1ss, #endif + NULL + }, +}; + +static struct sm_obj_form performance_group = { + .ui_name = "Performance", + .obj_list = (const struct sm_object *[]) { + &fan_mode, #if CONFIG(BOARD_HAS_GNA) &gna, #endif - #if CONFIG(EC_STARLABS_LID_SWITCH) - &lid_switch, - #endif - µphone, - #if CONFIG(DRIVERS_INTEL_USB4_RETIMER) - &thunderbolt, + #if CONFIG(BOARD_SUPPORTS_HT) + &hyper_threading, #endif + &power_profile, #if CONFIG(SOC_INTEL_METEORLAKE) &vpu, #endif - &webcam, - &wifi, NULL }, }; -static struct sm_obj_form pci = { - .ui_name = "PCI", +static struct sm_obj_form security_group = { + .ui_name = "Security", .obj_list = (const struct sm_object *[]) { - #if CONFIG(BOARD_STARLABS_STARBOOK_ADL) - &pci_hot_plug, - #endif - #if CONFIG(SOC_INTEL_COMMON_BLOCK_ASPM) - &pciexp_clk_pm, - #if CONFIG(BOARD_STARLABS_STARBOOK_RPL) - &pciexp_aspm_cpu, - #else - &pciexp_aspm, + &bios_lock, + #if CONFIG(BOARD_HAS_FPR) + &fingerprint_reader, #endif - &pciexp_l1ss, + &intel_tme, + &me_state, + &me_state_counter, + NULL + }, +}; + +static struct sm_obj_form suspend_lid_group = { + .ui_name = "Suspend & Lid", + .obj_list = (const struct sm_object *[]) { + #if CONFIG(EC_STARLABS_LID_SWITCH) + &lid_switch, #endif + &s0ix_enable, NULL }, }; -static struct sm_obj_form coreboot = { - .ui_name = "coreboot", +static struct sm_obj_form virtualization_group = { + .ui_name = "Virtualization", .obj_list = (const struct sm_object *[]) { - &debug_level, + &vtd, + NULL + }, +}; + +static struct sm_obj_form wireless_group = { + .ui_name = "Wireless", + .obj_list = (const struct sm_object *[]) { + &bluetooth, + &bluetooth_rtd3, + &wifi, NULL }, }; static struct sm_obj_form *sm_root[] = { - &performance, - &processor, - &power, - &keyboard, - &devices, - &pci, - &coreboot, + &audio_video_group, + &battery_group, + &debug_group, + #if CONFIG(BOARD_USES_FIXED_MODE_VBT) + &display_group, + #endif + &io_expansion_group, + &keyboard_group, + &leds_group, + &pcie_power_management_group, + &performance_group, + &security_group, + &suspend_lid_group, + &virtualization_group, + &wireless_group, NULL }; void mb_cfr_setup_menu(struct lb_cfr *cfr_root) { + starlabs_cfr_register_overrides(); cfr_write_setup_menu(cfr_root, sm_root); } diff --git a/src/mainboard/starlabs/starbook/cmos.default b/src/mainboard/starlabs/starbook/cmos.default deleted file mode 100644 index 49faae3e6a2..00000000000 --- a/src/mainboard/starlabs/starbook/cmos.default +++ /dev/null @@ -1,6 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only -# Functions -fn_lock_state=0x1 -trackpad_state=0x1 -kbl_brightness=0x0 -kbl_state=0x1 diff --git a/src/mainboard/starlabs/starbook/cmos.layout b/src/mainboard/starlabs/starbook/cmos.layout deleted file mode 100644 index ebba7fbd5dc..00000000000 --- a/src/mainboard/starlabs/starbook/cmos.layout +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -# ----------------------------------------------------------------- -entries - -# Bank: 1 -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory - -# ----------------------------------------------------------------- -# coreboot config options: ramtop -304 80 h 0 ramtop - -# RTC_BOOT_BYTE (coreboot hardcoded) -388 4 h 0 reboot_counter - -# coreboot config options: cpu -#400 8 r 0 reserved for century byte - -# coreboot config options: check sums -984 16 h 0 check_sum - -# Bank: 2 -# embedded controller settings (outside the checksummed area) -1024 8 h 1 fn_lock_state -1032 8 h 1 trackpad_state -1040 8 h 2 kbl_brightness -1048 8 h 1 kbl_state - -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable - -2 0 Off -2 1 Low -2 2 High -2 3 On - -# ----------------------------------------------------------------- -checksums - -checksum 392 983 984 diff --git a/src/mainboard/starlabs/starbook/mainboard.c b/src/mainboard/starlabs/starbook/mainboard.c index 772e32cc1c2..8916dda296a 100644 --- a/src/mainboard/starlabs/starbook/mainboard.c +++ b/src/mainboard/starlabs/starbook/mainboard.c @@ -1,25 +1,24 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include #include #include -static void init_mainboard(void *chip_info) +static void starlabs_configure_gpios(void *unused) { const struct pad_config *pads; size_t num; pads = variant_gpio_table(&num); gpio_configure_pads(pads, num); - - devtree_update(); } -struct chip_operations mainboard_ops = { - .init = init_mainboard, -}; +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, starlabs_configure_gpios, NULL); + +struct chip_operations mainboard_ops = {}; const char *mainboard_vbt_filename(void) { diff --git a/src/mainboard/starlabs/starbook/variants/adl/board.fmd b/src/mainboard/starlabs/starbook/variants/adl/board.fmd index b652a36fe69..b921fa1f2be 100644 --- a/src/mainboard/starlabs/starbook/variants/adl/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/adl/board.fmd @@ -1,14 +1,14 @@ FLASH 0x2000000 { SI_ALL 0x1000000 { SI_DESC 0x1000 - SI_ME 0x41c000 + SI_ME 0x4c0000 } SI_BIOS 0x1000000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starbook/variants/adl/devicetree.cb b/src/mainboard/starlabs/starbook/variants/adl/devicetree.cb index 675cc27d3b1..55cc2d5cb59 100644 --- a/src/mainboard/starlabs/starbook/variants/adl/devicetree.cb +++ b/src/mainboard/starlabs/starbook/variants/adl/devicetree.cb @@ -199,7 +199,6 @@ chip soc/intel/alderlake .flags = PCIE_RP_LTR | PCIE_RP_AER, .pcie_rp_aspm = ASPM_L0S_L1, .PcieRpL1Substates = L1_SS_L1_2, - .pcie_rp_detect_timeout_ms = 50, }" smbios_slot_desc "SlotTypeM2Socket3" diff --git a/src/mainboard/starlabs/starbook/variants/adl/devtree.c b/src/mainboard/starlabs/starbook/variants/adl/devtree.c index 22b66d0d9f1..3379e02dae5 100644 --- a/src/mainboard/starlabs/starbook/variants/adl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/adl/devtree.c @@ -10,52 +10,10 @@ #include #include -#define TJ_MAX 110 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_10core = - &cfg->power_limits_config[ADL_P_282_442_482_28W_CORE]; - - struct soc_power_limits_config *soc_conf_12core = - &cfg->power_limits_config[ADL_P_682_28W_CORE]; - - struct device *gna_dev = pcidev_on_root(0x08, 0); - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_10core->tdp_pl4 = 65; - soc_conf_12core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_10core->tdp_pl1_override = (soc_conf_10core->tdp_pl2_override / 2) & ~1; - soc_conf_12core->tdp_pl1_override = (soc_conf_12core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_10core->tdp_pl1_override = (soc_conf_10core->tdp_pl1_override * performance_scale) / 100; - soc_conf_10core->tdp_pl2_override = (soc_conf_10core->tdp_pl2_override * performance_scale) / 100; - - soc_conf_12core->tdp_pl1_override = (soc_conf_12core->tdp_pl1_override * performance_scale) / 100; - soc_conf_12core->tdp_pl2_override = (soc_conf_12core->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) @@ -75,5 +33,5 @@ void devtree_update(void) /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; } diff --git a/src/mainboard/starlabs/starbook/variants/adl/gpio.c b/src/mainboard/starlabs/starbook/variants/adl/gpio.c index f2d33b64587..2bad34dc52a 100644 --- a/src/mainboard/starlabs/starbook/variants/adl/gpio.c +++ b/src/mainboard/starlabs/starbook/variants/adl/gpio.c @@ -1,13 +1,57 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +/* clang-format off */ +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + + PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset deasserted */ + PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset deasserted */ +}; +/* clang-format on */ + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_D6, NONE, DEEP), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ + + /* Wireless */ + PAD_CFG_GPI(GPP_D7, NONE, DEEP), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -16,6 +60,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ @@ -40,16 +85,16 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC_LOW(GPP_E12, NONE, PLTRST), /* Interrupt */ /* SSD */ - PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* Clock Request 1 */ - PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_NC(GPP_D6, NONE), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ PAD_CFG_NF(GPP_H13, NONE, DEEP, NF5), /* Device Sleep */ PAD_CFG_NF(GPP_A12, NONE, DEEP, NF1), /* PEDET */ /* Wireless */ - PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* Clock Request 2 */ - PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D7, NONE), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_A13, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -261,6 +306,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_R6, NONE), PAD_NC(GPP_R7, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { diff --git a/src/mainboard/starlabs/starbook/variants/adl/ramstage.c b/src/mainboard/starlabs/starbook/variants/adl/ramstage.c index 1dbad4fc989..3e9cfb13c4f 100644 --- a/src/mainboard/starlabs/starbook/variants/adl/ramstage.c +++ b/src/mainboard/starlabs/starbook/variants/adl/ramstage.c @@ -1,17 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include #include #include void mainboard_silicon_init_params(FSP_S_CONFIG *supd) { configure_pin_mux(supd); - - /* - * Enable Hot Plug on RP5 to slow down coreboot so that - * third-party drives are detected. - */ - if (get_uint_option("pci_hot_plug", 0) == 1) - supd->PcieRpHotPlug[8] = 1; } diff --git a/src/mainboard/starlabs/starbook/variants/adl_n/board.fmd b/src/mainboard/starlabs/starbook/variants/adl_n/board.fmd index bc72a6098d6..9cf12adf815 100644 --- a/src/mainboard/starlabs/starbook/variants/adl_n/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/adl_n/board.fmd @@ -6,9 +6,9 @@ FLASH 0x1000000 { SI_BIOS 0xa00000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starbook/variants/adl_n/devicetree.cb b/src/mainboard/starlabs/starbook/variants/adl_n/devicetree.cb index f0f16c43371..ca436a0d401 100644 --- a/src/mainboard/starlabs/starbook/variants/adl_n/devicetree.cb +++ b/src/mainboard/starlabs/starbook/variants/adl_n/devicetree.cb @@ -184,7 +184,6 @@ chip soc/intel/alderlake .flags = PCIE_RP_LTR | PCIE_RP_AER, .pcie_rp_aspm = ASPM_L0S_L1, .PcieRpL1Substates = L1_SS_L1_2, - .pcie_rp_detect_timeout_ms = 50, }" smbios_slot_desc "SlotTypeM2Socket3" diff --git a/src/mainboard/starlabs/starbook/variants/adl_n/devtree.c b/src/mainboard/starlabs/starbook/variants/adl_n/devtree.c index 437a73c1bb1..1b01e25cb0a 100644 --- a/src/mainboard/starlabs/starbook/variants/adl_n/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/adl_n/devtree.c @@ -10,44 +10,10 @@ #include #include -#define TJ_MAX 105 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_4core = - &cfg->power_limits_config[ADL_N_041_6W_CORE]; - - struct device *gna_dev = pcidev_on_root(0x08, 0); - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_4core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl1_override * performance_scale) / 100; - soc_conf_4core->tdp_pl2_override = (soc_conf_4core->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) @@ -63,5 +29,5 @@ void devtree_update(void) /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; } diff --git a/src/mainboard/starlabs/starbook/variants/adl_n/gpio.c b/src/mainboard/starlabs/starbook/variants/adl_n/gpio.c index fc44208bace..3a8afd2b4db 100644 --- a/src/mainboard/starlabs/starbook/variants/adl_n/gpio.c +++ b/src/mainboard/starlabs/starbook/variants/adl_n/gpio.c @@ -1,13 +1,57 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +/* clang-format off */ +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + + PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset deasserted */ + PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset deasserted */ +}; +/* clang-format on */ + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_D5, NONE, DEEP), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ + + /* Wireless */ + PAD_CFG_GPI(GPP_D6, NONE, DEEP), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -16,6 +60,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ @@ -40,14 +85,14 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC_LOW(GPP_E12, NONE, PLTRST), /* Interrupt */ /* SSD */ - PAD_CFG_NF(GPP_D5, NONE, DEEP, NF1), /* Clock Request 0 */ - PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, DEEP), /* Enable */ + PAD_NC(GPP_D5, NONE), /* Clock Request 0 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, DEEP), /* Enable (PWREN off) */ /* Wireless */ - PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* Clock Request 1 */ - PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D6, NONE), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_A13, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -258,6 +303,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_R6, NONE), PAD_NC(GPP_R7, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { diff --git a/src/mainboard/starlabs/starbook/variants/cml/board.fmd b/src/mainboard/starlabs/starbook/variants/cml/board.fmd index 9018104edde..747141d1883 100644 --- a/src/mainboard/starlabs/starbook/variants/cml/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/cml/board.fmd @@ -6,9 +6,9 @@ FLASH 16M { BIOS@0x400000 0xC00000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x200 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x200 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starbook/variants/cml/devtree.c b/src/mainboard/starlabs/starbook/variants/cml/devtree.c index d9bafcabd5b..980a472abc2 100644 --- a/src/mainboard/starlabs/starbook/variants/cml/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/cml/devtree.c @@ -10,47 +10,14 @@ #include #include -#define TJ_MAX 100 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf = &cfg->power_limits_config; - - struct device *wifi_dev = pcidev_on_root(0x14, 3); - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf->tdp_pl4 = 45; - - /* Set PL1 to 50% of PL2 */ - soc_conf->tdp_pl1_override = (soc_conf->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf->tdp_pl1_override = (soc_conf->tdp_pl1_override * performance_scale) / 100; - soc_conf->tdp_pl2_override = (soc_conf->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) - wifi_dev->enabled = 0; + DEV_PTR(cnvi_wifi)->enabled = 0; /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) diff --git a/src/mainboard/starlabs/starbook/variants/kbl/board.fmd b/src/mainboard/starlabs/starbook/variants/kbl/board.fmd index ef634574603..c9eee557ca6 100644 --- a/src/mainboard/starlabs/starbook/variants/kbl/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/kbl/board.fmd @@ -1,9 +1,9 @@ FLASH 8M { BIOS@0x200000 0x600000 { RW_MRC_CACHE@0x0 0x10000 - SMMSTORE@0x10000 0x40000 - CONSOLE@0x50000 0x20000 - FMAP@0x70000 0x200 + SMMSTORE@0x10000 0x80000 + CONSOLE@0x90000 0x20000 + FMAP@0xB0000 0x200 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starbook/variants/kbl/devtree.c b/src/mainboard/starlabs/starbook/variants/kbl/devtree.c index c648be9da76..2dd0f995ab2 100644 --- a/src/mainboard/starlabs/starbook/variants/kbl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/kbl/devtree.c @@ -10,47 +10,14 @@ #include #include -#define TJ_MAX 100 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf = &cfg->power_limits_config; - - struct device *wifi_dev = pcidev_on_root(0x1c, 5); - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf->tdp_pl4 = 45; - - /* Set PL1 to 50% of PL2 */ - soc_conf->tdp_pl1_override = (soc_conf->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf->tdp_pl1_override = (soc_conf->tdp_pl1_override * performance_scale) / 100; - soc_conf->tdp_pl2_override = (soc_conf->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) - wifi_dev->enabled = 0; + DEV_PTR(pcie_rp5)->enabled = 0; /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) diff --git a/src/mainboard/starlabs/starbook/variants/mtl/board.fmd b/src/mainboard/starlabs/starbook/variants/mtl/board.fmd index cfa449253d6..c1691514ab4 100644 --- a/src/mainboard/starlabs/starbook/variants/mtl/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/mtl/board.fmd @@ -6,9 +6,9 @@ FLASH 0x2000000 { SI_BIOS 0xe00000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starbook/variants/mtl/devtree.c b/src/mainboard/starlabs/starbook/variants/mtl/devtree.c index 296027e9e85..0b2cd1b959a 100644 --- a/src/mainboard/starlabs/starbook/variants/mtl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/mtl/devtree.c @@ -10,45 +10,10 @@ #include #include -#define TJ_MAX 110 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_20core = - &cfg->power_limits_config[MTL_P_682_482_CORE]; - - struct device *gna_dev = pcidev_on_root(0x08, 0); - struct device *vpu_dev = pcidev_on_root(0x0b, 0); - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_20core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_20core->tdp_pl1_override = (soc_conf_20core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_20core->tdp_pl1_override = (soc_conf_20core->tdp_pl1_override * performance_scale) / 100; - soc_conf_20core->tdp_pl2_override = (soc_conf_20core->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) @@ -64,9 +29,9 @@ void devtree_update(void) /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; /* Enable/Disable VPU based on CMOS settings */ if (get_uint_option("vpu", 0) == 0) - vpu_dev->enabled = 0; + DEV_PTR(vpu)->enabled = 0; } diff --git a/src/mainboard/starlabs/starbook/variants/mtl/gpio.c b/src/mainboard/starlabs/starbook/variants/mtl/gpio.c index 944c1452f8c..72c5d637a33 100644 --- a/src/mainboard/starlabs/starbook/variants/mtl/gpio.c +++ b/src/mainboard/starlabs/starbook/variants/mtl/gpio.c @@ -1,8 +1,41 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +/* clang-format off */ +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_H07, 1, DEEP), /* Enable */ + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D20, NONE, PLTRST, NF1), /* Clock Request 8 */ + PAD_CFG_GPO(GPP_A20, 0, PLTRST), /* Reset asserted */ + + PAD_CFG_GPO(GPP_B19, 1, DEEP), /* WiFi RF Kill */ + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D21, NONE, PLTRST, NF2), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_H02, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_A20, 1, PLTRST), /* Reset deasserted */ + PAD_CFG_GPO(GPP_H02, 1, PLTRST), /* Reset deasserted */ +}; +/* clang-format on */ + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), /* RXD */ @@ -11,7 +44,18 @@ const struct pad_config early_gpio_table[] = { /* SMBus */ PAD_CFG_NF(GPP_C00, NONE, DEEP, NF1), /* Clock */ PAD_CFG_NF(GPP_C01, NONE, DEEP, NF1), /* Data */ + + /* SSD */ + PAD_CFG_GPI(GPP_D20, NONE, PLTRST), /* Clock Request 8 */ + PAD_CFG_GPO(GPP_A20, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_H07, 0, DEEP), /* Enable (PWREN off) */ + + /* Wireless */ + PAD_CFG_GPI(GPP_D21, NONE, PLTRST), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_H02, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_B19, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -20,6 +64,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_V00, NONE, DEEP, NF1), /* Battery Low */ @@ -44,14 +89,14 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC(GPP_B00, NONE, DEEP, LEVEL, INVERT), /* Interrupt */ /* SSD */ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D20, NONE, PLTRST, NF1), /* Clock Request 8 */ - PAD_CFG_GPO(GPP_A20, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_H07, 1, DEEP), /* Enable */ + PAD_NC(GPP_D20, NONE), /* Clock Request 8 */ + PAD_CFG_GPO(GPP_A20, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_H07, 0, DEEP), /* Enable (PWREN off) */ /* Wireless */ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D21, NONE, PLTRST, NF2), /* Clock Request 5 */ - PAD_CFG_GPO(GPP_H02, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_B19, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D21, NONE), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_H02, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_B19, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_B18, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -246,6 +291,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_D22, NONE), PAD_NC(GPP_D23, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { diff --git a/src/mainboard/starlabs/starbook/variants/rpl/board.fmd b/src/mainboard/starlabs/starbook/variants/rpl/board.fmd index 6dcecabde79..b921fa1f2be 100644 --- a/src/mainboard/starlabs/starbook/variants/rpl/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/rpl/board.fmd @@ -6,9 +6,9 @@ FLASH 0x2000000 { SI_BIOS 0x1000000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starbook/variants/rpl/devtree.c b/src/mainboard/starlabs/starbook/variants/rpl/devtree.c index 32ba845ba8c..fe9ec1b3e2d 100644 --- a/src/mainboard/starlabs/starbook/variants/rpl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/rpl/devtree.c @@ -10,54 +10,10 @@ #include #include -#define TJ_MAX 110 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_6core = - &cfg->power_limits_config[RPL_P_282_242_142_15W_CORE]; - - struct soc_power_limits_config *soc_conf_12core = - &cfg->power_limits_config[RPL_P_682_482_282_28W_CORE]; - - struct device *tbt_pci_dev = pcidev_on_root(0x07, 0); - struct device *tbt_dma_dev = pcidev_on_root(0x0d, 2); - struct device *gna_dev = pcidev_on_root(0x08, 0); - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_6core->tdp_pl4 = 65; - soc_conf_12core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_6core->tdp_pl1_override = (soc_conf_6core->tdp_pl2_override / 2) & ~1; - soc_conf_12core->tdp_pl1_override = (soc_conf_12core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_6core->tdp_pl1_override = (soc_conf_6core->tdp_pl1_override * performance_scale) / 100; - soc_conf_6core->tdp_pl2_override = (soc_conf_6core->tdp_pl2_override * performance_scale) / 100; - - soc_conf_12core->tdp_pl1_override = (soc_conf_12core->tdp_pl1_override * performance_scale) / 100; - soc_conf_12core->tdp_pl2_override = (soc_conf_12core->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) @@ -77,11 +33,11 @@ void devtree_update(void) /* Enable/Disable Thunderbolt based on CMOS settings */ if (get_uint_option("thunderbolt", 1) == 0) { - tbt_pci_dev->enabled = 0; - tbt_dma_dev->enabled = 0; + DEV_PTR(tbt_pcie_rp0)->enabled = 0; + DEV_PTR(tcss_dma0)->enabled = 0; } /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; } diff --git a/src/mainboard/starlabs/starbook/variants/rpl/gpio.c b/src/mainboard/starlabs/starbook/variants/rpl/gpio.c index 0625675f10b..339e771544f 100644 --- a/src/mainboard/starlabs/starbook/variants/rpl/gpio.c +++ b/src/mainboard/starlabs/starbook/variants/rpl/gpio.c @@ -1,13 +1,57 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +/* clang-format off */ +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D14, 1, DEEP), /* Enable */ + PAD_CFG_NF(GPP_H19, NONE, DEEP, NF1), /* Clock Request 4 */ + PAD_CFG_GPO(GPP_F20, 0, PLTRST), /* Reset asserted */ + + PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_F20, 1, PLTRST), /* Reset deasserted */ + PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset deasserted */ +}; +/* clang-format on */ + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ PAD_CFG_NF(GPP_H11, NONE, DEEP, NF2), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_H19, NONE, DEEP), /* Clock Request 4 */ + PAD_CFG_GPO(GPP_F20, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D14, 0, DEEP), /* Enable (PWREN off) */ + + /* Wireless */ + PAD_CFG_GPI(GPP_D7, NONE, DEEP), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -16,6 +60,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ @@ -40,14 +85,14 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC_LOW(GPP_E12, NONE, PLTRST), /* Interrupt */ /* SSD */ - PAD_CFG_NF(GPP_H19, NONE, DEEP, NF1), /* Clock Request 4 */ - PAD_CFG_GPO(GPP_F20, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D14, 1, DEEP), /* Enable */ + PAD_NC(GPP_H19, NONE), /* Clock Request 4 */ + PAD_CFG_GPO(GPP_F20, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D14, 0, DEEP), /* Enable (PWREN off) */ /* Wireless */ - PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* Clock Request 2 */ - PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D7, NONE), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_A13, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -260,6 +305,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_R6, NONE), PAD_NC(GPP_R7, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { diff --git a/src/mainboard/starlabs/starbook/variants/tgl/board.fmd b/src/mainboard/starlabs/starbook/variants/tgl/board.fmd index e7405bee774..26e341f50bb 100644 --- a/src/mainboard/starlabs/starbook/variants/tgl/board.fmd +++ b/src/mainboard/starlabs/starbook/variants/tgl/board.fmd @@ -6,9 +6,9 @@ FLASH 0x1000000 { SI_BIOS 0xb00000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starbook/variants/tgl/devtree.c b/src/mainboard/starlabs/starbook/variants/tgl/devtree.c index d83c2b55a7d..796624e1c62 100644 --- a/src/mainboard/starlabs/starbook/variants/tgl/devtree.c +++ b/src/mainboard/starlabs/starbook/variants/tgl/devtree.c @@ -10,59 +10,14 @@ #include #include -#define TJ_MAX 100 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_2core = - &cfg->power_limits_config[POWER_LIMITS_U_2_CORE]; - - struct soc_power_limits_config *soc_conf_4core = - &cfg->power_limits_config[POWER_LIMITS_U_4_CORE]; - - struct device *wifi_dev = pcidev_on_root(0x14, 3); - struct device *tbt_pci_dev = pcidev_on_root(0x07, 0); - struct device *tbt_dma_dev = pcidev_on_root(0x0d, 2); - struct device *gna_dev = pcidev_on_root(0x08, 0); - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_2core->tdp_pl4 = 65; - soc_conf_4core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_2core->tdp_pl1_override = (soc_conf_2core->tdp_pl2_override / 2) & ~1; - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_2core->tdp_pl1_override = (soc_conf_2core->tdp_pl1_override * performance_scale) / 100; - soc_conf_2core->tdp_pl2_override = (soc_conf_2core->tdp_pl2_override * performance_scale) / 100; - - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl1_override * performance_scale) / 100; - soc_conf_4core->tdp_pl2_override = (soc_conf_4core->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable WiFi based on CMOS settings */ if (get_uint_option("wifi", 1) == 0) - wifi_dev->enabled = 0; + DEV_PTR(cnvi_wifi)->enabled = 0; /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) @@ -79,11 +34,11 @@ void devtree_update(void) if (get_uint_option("thunderbolt", 1) == 0) { cfg->UsbTcPortEn = 0; cfg->TcssXhciEn = 0; - tbt_pci_dev->enabled = 0; - tbt_dma_dev->enabled = 0; + DEV_PTR(tbt_pcie_rp0)->enabled = 0; + DEV_PTR(tbt_dma0)->enabled = 0; } /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; } diff --git a/src/mainboard/starlabs/starbook/variants/tgl/gpio.c b/src/mainboard/starlabs/starbook/variants/tgl/gpio.c index 448683ce28a..58fc4b46640 100644 --- a/src/mainboard/starlabs/starbook/variants/tgl/gpio.c +++ b/src/mainboard/starlabs/starbook/variants/tgl/gpio.c @@ -1,13 +1,47 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +/* clang-format off */ +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D16, 1, PLTRST), /* Enable */ + PAD_CFG_NF(GPP_D8, NONE, DEEP, NF1), /* Clock Request 3 */ + PAD_CFG_GPO(GPP_A11, 0, PLTRST), /* Reset asserted */ +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_A11, 1, PLTRST), /* Reset deasserted */ +}; +/* clang-format on */ + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* RXD */ PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), /* TXD */ + + /* SSD */ + PAD_CFG_GPI(GPP_D8, NONE, DEEP), /* Clock Request 3 */ + PAD_CFG_GPO(GPP_A11, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, PLTRST), /* Enable (PWREN off) */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -16,6 +50,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ @@ -40,9 +75,9 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC(GPP_C8, NONE, DEEP, LEVEL, INVERT), /* Interrupt */ /* SSD */ - PAD_CFG_NF(GPP_D8, NONE, DEEP, NF1), /* Clock Request 3 */ - PAD_CFG_GPO(GPP_A11, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, PLTRST), /* Enable */ + PAD_NC(GPP_D8, NONE), /* Clock Request 3 */ + PAD_CFG_GPO(GPP_A11, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_D16, 0, PLTRST), /* Enable (PWREN off) */ /* SATA */ PAD_CFG_NF(GPP_A12, UP_20K, DEEP, NF1), /* PEDET */ @@ -61,8 +96,8 @@ const struct pad_config gpio_table[] = { PAD_CFG_NF(GPP_H16, NONE, DEEP, NF1), /* HDMI Clock */ PAD_CFG_NF(GPP_H17, NONE, DEEP, NF1), /* HDMI Data */ PAD_CFG_NF(GPP_B11, NONE, DEEP, NF1), /* PMC Interrupt */ - PAD_CFG_NF(GPP_C6, NONE, PWROK, NF1), /* SML Clock */ - PAD_CFG_NF(GPP_C7, NONE, PWROK, NF1), /* SML Data */ + PAD_CFG_NF(GPP_C6, NONE, DEEP, NF1), /* SML Clock */ + PAD_CFG_NF(GPP_C7, NONE, DEEP, NF1), /* SML Data */ /* Webcam */ PAD_CFG_TERM_GPO(GPP_D19, 1, UP_20K, DEEP), /* Power */ @@ -250,6 +285,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_U4, NONE), PAD_NC(GPP_U5, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { diff --git a/src/mainboard/starlabs/starfighter/Kconfig b/src/mainboard/starlabs/starfighter/Kconfig index 1e12366501e..b7795cc6aa1 100644 --- a/src/mainboard/starlabs/starfighter/Kconfig +++ b/src/mainboard/starlabs/starfighter/Kconfig @@ -15,9 +15,7 @@ config BOARD_STARLABS_STARFIGHTER_SERIES select EC_STARLABS_MERLIN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES - select HAVE_CMOS_DEFAULT select HAVE_HDA_DMIC - select HAVE_OPTION_TABLE select HAVE_SPD_IN_CBFS select INTEL_GMA_HAVE_VBT select INTEL_LPSS_UART_FOR_CONSOLE @@ -34,6 +32,7 @@ config BOARD_STARLABS_STARFIGHTER_SERIES select SYSTEM_TYPE_LAPTOP select TPM_MEASURED_BOOT select VALIDATE_INTEL_DESCRIPTOR + select STARLABS_NVME_POWER_SEQUENCE config BOARD_STARLABS_STARFIGHTER_RPL select BOARD_STARLABS_STARFIGHTER_SERIES @@ -122,6 +121,10 @@ config SOC_INTEL_CSE_SEND_EOP_EARLY config TME_KEY_REGENERATION_ON_WARM_BOOT default n +config MB_STARLABS_PL4_WATTS + int + default 80 + config TPM_PIRQ depends on MAINBOARD_HAS_TPM2 default 0x3d if BOARD_STARLABS_STARFIGHTER_MTL diff --git a/src/mainboard/starlabs/starfighter/cfr.c b/src/mainboard/starlabs/starfighter/cfr.c index 166a9dbb818..6cdd98b1897 100644 --- a/src/mainboard/starlabs/starfighter/cfr.c +++ b/src/mainboard/starlabs/starfighter/cfr.c @@ -8,104 +8,153 @@ #include #include -static struct sm_obj_form performance = { - .ui_name = "Performance", +static struct sm_obj_form battery_group = { + .ui_name = "Battery", .obj_list = (const struct sm_object *[]) { - &bluetooth_rtd3, - &fan_mode, - &power_profile, + #if CONFIG(EC_STARLABS_CHARGING_SPEED) + &charging_speed, + #endif + &max_charge, + &power_on_after_fail_bool, NULL }, }; -static struct sm_obj_form processor = { - .ui_name = "Processor", +static struct sm_obj_form debug_group = { + .ui_name = "Debug", .obj_list = (const struct sm_object *[]) { - &me_state, - &me_state_counter, - &hyper_threading, - &s0ix_enable, - &vtd, + &debug_level, NULL }, }; -static struct sm_obj_form power = { - .ui_name = "Power", +static struct sm_obj_form display_group = { + .ui_name = "Display", .obj_list = (const struct sm_object *[]) { - &max_charge, - #if CONFIG(EC_STARLABS_CHARGING_SPEED) - &charging_speed, - #endif - &power_on_after_fail_bool, + &display_native_res, NULL }, }; -static struct sm_obj_form keyboard = { +#if CONFIG(DRIVERS_INTEL_USB4_RETIMER) +static struct sm_obj_form io_expansion_group = { + .ui_name = "I/O / Expansion", + .obj_list = (const struct sm_object *[]) { + &card_reader, + &thunderbolt, + NULL + }, +}; +#endif + +static struct sm_obj_form keyboard_group = { .ui_name = "Keyboard", .obj_list = (const struct sm_object *[]) { - &kbl_timeout, &fn_ctrl_swap, + &kbl_timeout, NULL }, }; -static struct sm_obj_form devices = { - .ui_name = "Devices", +static struct sm_obj_form leds_group = { + .ui_name = "LEDs", .obj_list = (const struct sm_object *[]) { - #if CONFIG(SOC_INTEL_TIGERLAKE) || CONFIG(SOC_INTEL_ALDERLAKE) || CONFIG(SOC_INTEL_RAPTORLAKE) - &gna, - #endif - &display_native_res, - #if CONFIG(EC_STARLABS_LID_SWITCH) - &lid_switch, - #endif - #if CONFIG(DRIVERS_INTEL_USB4_RETIMER) - &thunderbolt, - #endif - #if CONFIG(SOC_INTEL_METEORLAKE) - &vpu, - #endif + &charge_led, + &power_led, NULL }, }; -static struct sm_obj_form pci = { - .ui_name = "PCI", +static struct sm_obj_form pcie_power_management_group = { + .ui_name = "PCIe Power Management", .obj_list = (const struct sm_object *[]) { #if CONFIG(SOC_INTEL_COMMON_BLOCK_ASPM) - &pciexp_clk_pm, &pciexp_aspm, #if CONFIG(HAS_INTEL_CPU_ROOT_PORTS) &pciexp_aspm_cpu, #endif + &pciexp_clk_pm, &pciexp_l1ss, #endif NULL }, }; -static struct sm_obj_form coreboot = { - .ui_name = "coreboot", +static struct sm_obj_form performance_group = { + .ui_name = "Performance", .obj_list = (const struct sm_object *[]) { - &debug_level, + &fan_mode, + #if CONFIG(SOC_INTEL_TIGERLAKE) || CONFIG(SOC_INTEL_ALDERLAKE) || CONFIG(SOC_INTEL_RAPTORLAKE) + &gna, + #endif + &hyper_threading, + &memory_speed, + &power_profile, + #if CONFIG(SOC_INTEL_METEORLAKE) + &vpu, + #endif + NULL + }, +}; + +static struct sm_obj_form security_group = { + .ui_name = "Security", + .obj_list = (const struct sm_object *[]) { + &bios_lock, + &intel_tme, + &me_state, + &me_state_counter, + NULL + }, +}; + +static struct sm_obj_form suspend_lid_group = { + .ui_name = "Suspend & Lid", + .obj_list = (const struct sm_object *[]) { + #if CONFIG(EC_STARLABS_LID_SWITCH) + &lid_switch, + #endif + &s0ix_enable, + NULL + }, +}; + +static struct sm_obj_form virtualization_group = { + .ui_name = "Virtualization", + .obj_list = (const struct sm_object *[]) { + &vtd, + NULL + }, +}; + +static struct sm_obj_form wireless_group = { + .ui_name = "Wireless", + .obj_list = (const struct sm_object *[]) { + &bluetooth_rtd3, NULL }, }; static struct sm_obj_form *sm_root[] = { - &performance, - &processor, - &power, - &keyboard, - &devices, - &pci, - &coreboot, + &battery_group, + &debug_group, + &display_group, + #if CONFIG(DRIVERS_INTEL_USB4_RETIMER) + &io_expansion_group, + #endif + &keyboard_group, + &leds_group, + &pcie_power_management_group, + &performance_group, + &security_group, + &suspend_lid_group, + &virtualization_group, + &wireless_group, NULL }; void mb_cfr_setup_menu(struct lb_cfr *cfr_root) { + starlabs_cfr_register_overrides(); cfr_write_setup_menu(cfr_root, sm_root); } diff --git a/src/mainboard/starlabs/starfighter/cmos.default b/src/mainboard/starlabs/starfighter/cmos.default deleted file mode 100644 index 49faae3e6a2..00000000000 --- a/src/mainboard/starlabs/starfighter/cmos.default +++ /dev/null @@ -1,6 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only -# Functions -fn_lock_state=0x1 -trackpad_state=0x1 -kbl_brightness=0x0 -kbl_state=0x1 diff --git a/src/mainboard/starlabs/starfighter/cmos.layout b/src/mainboard/starlabs/starfighter/cmos.layout deleted file mode 100644 index ebba7fbd5dc..00000000000 --- a/src/mainboard/starlabs/starfighter/cmos.layout +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -# ----------------------------------------------------------------- -entries - -# Bank: 1 -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory - -# ----------------------------------------------------------------- -# coreboot config options: ramtop -304 80 h 0 ramtop - -# RTC_BOOT_BYTE (coreboot hardcoded) -388 4 h 0 reboot_counter - -# coreboot config options: cpu -#400 8 r 0 reserved for century byte - -# coreboot config options: check sums -984 16 h 0 check_sum - -# Bank: 2 -# embedded controller settings (outside the checksummed area) -1024 8 h 1 fn_lock_state -1032 8 h 1 trackpad_state -1040 8 h 2 kbl_brightness -1048 8 h 1 kbl_state - -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable - -2 0 Off -2 1 Low -2 2 High -2 3 On - -# ----------------------------------------------------------------- -checksums - -checksum 392 983 984 diff --git a/src/mainboard/starlabs/starfighter/mainboard.c b/src/mainboard/starlabs/starfighter/mainboard.c index 60e65ee8c41..e0b6ffae490 100644 --- a/src/mainboard/starlabs/starfighter/mainboard.c +++ b/src/mainboard/starlabs/starfighter/mainboard.c @@ -1,21 +1,19 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include -#include #include -static void init_mainboard(void *chip_info) +static void starlabs_configure_gpios(void *unused) { const struct pad_config *pads; size_t num; pads = variant_gpio_table(&num); gpio_configure_pads(pads, num); - - devtree_update(); } -struct chip_operations mainboard_ops = { - .init = init_mainboard, -}; +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, starlabs_configure_gpios, NULL); + +struct chip_operations mainboard_ops = {}; diff --git a/src/mainboard/starlabs/starfighter/spd/16gb-5500.spd.hex b/src/mainboard/starlabs/starfighter/spd/16gb-5500.spd.hex new file mode 100644 index 00000000000..77a62517e3c --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/16gb-5500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 15 1A B5 08 00 40 00 00 0A 01 00 00 +48 00 0B FF 92 55 05 00 AE 00 90 A8 90 90 06 C0 +03 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 16 36 16 36 +16 36 16 36 00 00 16 36 16 36 16 36 16 36 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 9C 00 00 00 00 4B 7F 50 69 9A +11 01 40 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 53 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +80 2C 25 20 02 F0 E6 A8 9B 38 41 54 46 31 47 36 +34 41 5A 2D 33 47 32 45 31 20 20 20 20 31 80 2C +45 48 4D 30 30 30 30 33 37 30 33 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/16gb.spd.hex b/src/mainboard/starlabs/starfighter/spd/16gb-6400.spd.hex similarity index 100% rename from src/mainboard/starlabs/starfighter/spd/16gb.spd.hex rename to src/mainboard/starlabs/starfighter/spd/16gb-6400.spd.hex diff --git a/src/mainboard/starlabs/starfighter/spd/16gb-7500.spd.hex b/src/mainboard/starlabs/starfighter/spd/16gb-7500.spd.hex new file mode 100644 index 00000000000..110d974afae --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/16gb-7500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 15 1A B5 08 00 40 00 00 0A 01 00 00 +48 00 08 FF 92 55 05 00 AA 00 90 A8 90 90 06 C0 +03 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 16 36 16 36 +16 36 16 36 00 00 16 36 16 36 16 36 16 36 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 9C 00 00 00 00 46 7F 42 69 9A +11 01 40 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 53 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +80 2C 25 20 02 F0 E6 A8 9B 38 41 54 46 31 47 36 +34 41 5A 2D 33 47 32 45 31 20 20 20 20 31 80 2C +45 48 4D 30 30 30 30 33 37 30 33 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/32gb-5500.spd.hex b/src/mainboard/starlabs/starfighter/spd/32gb-5500.spd.hex new file mode 100644 index 00000000000..09f6a034649 --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/32gb-5500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 22 B5 08 00 40 00 00 0A 01 00 00 +48 00 0B FF 92 55 05 00 AE 00 90 A8 90 C0 08 60 +04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 16 36 16 36 +16 36 16 36 00 00 16 36 16 36 16 36 16 36 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 9C 00 00 00 00 4B 7F 50 69 9A +11 01 40 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 53 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +80 2C 25 20 02 F0 E6 A8 9B 38 41 54 46 31 47 36 +34 41 5A 2D 33 47 32 45 31 20 20 20 20 31 80 2C +45 48 4D 30 30 30 30 33 37 30 33 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/32gb.spd.hex b/src/mainboard/starlabs/starfighter/spd/32gb-6400.spd.hex similarity index 100% rename from src/mainboard/starlabs/starfighter/spd/32gb.spd.hex rename to src/mainboard/starlabs/starfighter/spd/32gb-6400.spd.hex diff --git a/src/mainboard/starlabs/starfighter/spd/32gb-7500.spd.hex b/src/mainboard/starlabs/starfighter/spd/32gb-7500.spd.hex new file mode 100644 index 00000000000..c946476aa61 --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/32gb-7500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 22 B5 08 00 40 00 00 0A 01 00 00 +48 00 08 FF 92 55 05 00 AA 00 90 A8 90 C0 08 60 +04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 16 36 16 36 +16 36 16 36 00 00 16 36 16 36 16 36 16 36 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 9C 00 00 00 00 46 7F 42 69 9A +11 01 40 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 53 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +80 2C 25 20 02 F0 E6 A8 9B 38 41 54 46 31 47 36 +34 41 5A 2D 33 47 32 45 31 20 20 20 20 31 80 2C +45 48 4D 30 30 30 30 33 37 30 33 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/32gb-mtl-5500.spd.hex b/src/mainboard/starlabs/starfighter/spd/32gb-mtl-5500.spd.hex new file mode 100644 index 00000000000..de89ca1b806 --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/32gb-mtl-5500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 22 B5 08 00 40 00 00 0A 01 00 00 +48 00 0B FF 92 55 05 00 AE 00 90 A8 90 C0 08 60 +04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 4B 7F 50 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 20 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/32gb-mtl.spd.hex b/src/mainboard/starlabs/starfighter/spd/32gb-mtl-6400.spd.hex similarity index 100% rename from src/mainboard/starlabs/starfighter/spd/32gb-mtl.spd.hex rename to src/mainboard/starlabs/starfighter/spd/32gb-mtl-6400.spd.hex diff --git a/src/mainboard/starlabs/starfighter/spd/32gb-mtl-7500.spd.hex b/src/mainboard/starlabs/starfighter/spd/32gb-mtl-7500.spd.hex new file mode 100644 index 00000000000..8f4c71530af --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/32gb-mtl-7500.spd.hex @@ -0,0 +1,32 @@ +23 10 13 0E 16 22 B5 08 00 40 00 00 0A 01 00 00 +48 00 08 FF 92 55 05 00 AA 00 90 A8 90 C0 08 60 +04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 46 7F 42 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 20 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/64gb-5500.spd.hex b/src/mainboard/starlabs/starfighter/spd/64gb-5500.spd.hex new file mode 100644 index 00000000000..c0ecc150771 --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/64gb-5500.spd.hex @@ -0,0 +1,32 @@ +23 10 15 0E 16 2A F9 08 00 40 00 00 09 01 00 00 +48 00 0B FF 92 55 05 00 AE 00 90 A8 90 C0 08 60 +04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 16 36 16 36 +16 36 16 36 00 00 16 36 16 36 16 36 16 36 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 9C 00 00 00 00 4B 7F 50 69 9A +11 01 40 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 53 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +80 2C 25 20 02 F0 E6 A8 9B 38 41 54 46 31 47 36 +34 41 5A 2D 33 47 32 45 31 20 20 20 20 31 80 2C +45 48 4D 30 30 30 30 33 37 30 33 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/64gb-6400.spd.hex b/src/mainboard/starlabs/starfighter/spd/64gb-6400.spd.hex new file mode 100644 index 00000000000..bdeb4c2501d --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/64gb-6400.spd.hex @@ -0,0 +1,32 @@ +23 10 15 0E 16 2A F9 08 00 40 00 00 09 01 00 00 +48 00 0A FF 92 55 05 00 AA 00 90 A8 90 C0 08 60 +04 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 16 36 16 36 +16 36 16 36 00 00 16 36 16 36 16 36 16 36 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 9C 00 00 00 00 00 7F 00 69 9A +11 01 40 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 D8 53 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +80 2C 25 20 02 F0 E6 A8 9B 38 41 54 46 31 47 36 +34 41 5A 2D 33 47 32 45 31 20 20 20 20 31 80 2C +45 48 4D 30 30 30 30 33 37 30 33 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/64gb.spd.hex b/src/mainboard/starlabs/starfighter/spd/64gb-7500.spd.hex similarity index 100% rename from src/mainboard/starlabs/starfighter/spd/64gb.spd.hex rename to src/mainboard/starlabs/starfighter/spd/64gb-7500.spd.hex diff --git a/src/mainboard/starlabs/starfighter/spd/64gb-mtl-5500.spd.hex b/src/mainboard/starlabs/starfighter/spd/64gb-mtl-5500.spd.hex new file mode 100644 index 00000000000..c2934a2c6e3 --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/64gb-mtl-5500.spd.hex @@ -0,0 +1,32 @@ +23 10 15 0E 16 2A F9 08 00 40 00 00 09 01 00 00 +48 00 0B FF 92 55 05 00 AE 00 90 A8 90 C0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 4B 00 50 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 7F 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 20 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/64gb-mtl-6400.spd.hex b/src/mainboard/starlabs/starfighter/spd/64gb-mtl-6400.spd.hex new file mode 100644 index 00000000000..a3ca8d3afd5 --- /dev/null +++ b/src/mainboard/starlabs/starfighter/spd/64gb-mtl-6400.spd.hex @@ -0,0 +1,32 @@ +23 10 15 0E 16 2A F9 08 00 40 00 00 09 01 00 00 +48 00 0A FF 92 55 05 00 AA 00 90 A8 90 C0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 7F 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 20 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/64gb-mtl.spd.hex b/src/mainboard/starlabs/starfighter/spd/64gb-mtl-7500.spd.hex similarity index 62% rename from src/mainboard/starlabs/starfighter/spd/64gb-mtl.spd.hex rename to src/mainboard/starlabs/starfighter/spd/64gb-mtl-7500.spd.hex index d8a75d2182d..ee280c8ca26 100644 --- a/src/mainboard/starlabs/starfighter/spd/64gb-mtl.spd.hex +++ b/src/mainboard/starlabs/starfighter/spd/64gb-mtl-7500.spd.hex @@ -9,15 +9,24 @@ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00 -20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 -20 20 20 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 20 00 00 00 20 20 20 20 20 20 20 +20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/starlabs/starfighter/spd/Makefile.mk b/src/mainboard/starlabs/starfighter/spd/Makefile.mk index ee9a117ed20..4bce4845b9f 100644 --- a/src/mainboard/starlabs/starfighter/spd/Makefile.mk +++ b/src/mainboard/starlabs/starfighter/spd/Makefile.mk @@ -1,10 +1,24 @@ ## SPDX-License-Identifier: GPL-2.0-only ifeq ($(CONFIG_BOARD_STARLABS_STARFIGHTER_RPL),y) -SPD_SOURCES = 16gb # 13 -SPD_SOURCES += 32gb # 0 -SPD_SOURCES += 64gb # 8 +# RPL memory configs (selected by straps) with runtime speed selection. +# CBFS index order is (per config): 5500, 6400, 7500. +SPD_SOURCES = 16gb-5500 +SPD_SOURCES += 16gb-6400 +SPD_SOURCES += 16gb-7500 +SPD_SOURCES += 32gb-5500 +SPD_SOURCES += 32gb-6400 +SPD_SOURCES += 32gb-7500 +SPD_SOURCES += 64gb-5500 +SPD_SOURCES += 64gb-6400 +SPD_SOURCES += 64gb-7500 else -SPD_SOURCES = 32gb-mtl # 13 -SPD_SOURCES += 64gb-mtl # 0 +# MTL memory configs (selected by straps) with runtime speed selection. +# CBFS index order is (per config): 5500, 6400, 7500. +SPD_SOURCES = 32gb-mtl-5500 +SPD_SOURCES += 32gb-mtl-6400 +SPD_SOURCES += 32gb-mtl-7500 +SPD_SOURCES += 64gb-mtl-5500 +SPD_SOURCES += 64gb-mtl-6400 +SPD_SOURCES += 64gb-mtl-7500 endif diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/board.fmd b/src/mainboard/starlabs/starfighter/variants/mtl/board.fmd index 1c11c433a2d..e88eaf2d0ea 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/board.fmd +++ b/src/mainboard/starlabs/starfighter/variants/mtl/board.fmd @@ -1,14 +1,14 @@ FLASH 0x2000000 { SI_ALL 0x1000000 { SI_DESC 0x4000 - SI_ME 0x80f000 + SI_ME 0xbb1000 } SI_BIOS 0x1000000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb b/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb index f83df3e27a9..11384b8f138 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb +++ b/src/mainboard/starlabs/starfighter/variants/mtl/devicetree.cb @@ -160,6 +160,9 @@ chip soc/intel/meteorlake register "usb2_ports[6]" = "USB2_PORT_SHORT(OC_SKIP)" register "usb3_ports[1]" = "USB3_PORT_DEFAULT(OC_SKIP)" + # Card Reader + register "usb2_ports[3]" = "USB2_PORT_SHORT(OC_SKIP)" + # Internal Webcam 9070 mil register "usb2_ports[CONFIG_CCD_PORT]" = "USB2_PORT_MID(OC_SKIP)" @@ -207,9 +210,15 @@ chip soc/intel/meteorlake device ref usb3_port2 on end end chip drivers/usb/acpi - register "desc" = ""Internal Webcam"" + register "desc" = ""Card Reader"" register "type" = "UPC_TYPE_INTERNAL" register "group" = "ACPI_PLD_GROUP(0, 4)" + device ref usb2_port4 on end + end + chip drivers/usb/acpi + register "desc" = ""Internal Webcam"" + register "type" = "UPC_TYPE_INTERNAL" + register "group" = "ACPI_PLD_GROUP(0, 5)" device ref usb2_port5 on end end chip drivers/usb/acpi diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/devtree.c b/src/mainboard/starlabs/starfighter/variants/mtl/devtree.c index a983bba7471..5ac632b4b78 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/devtree.c +++ b/src/mainboard/starlabs/starfighter/variants/mtl/devtree.c @@ -10,42 +10,14 @@ #include #include -#define TJ_MAX 110 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); + update_power_limits(cfg); - struct soc_power_limits_config *soc_conf_20core = - &cfg->power_limits_config[MTL_P_682_482_CORE]; - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_20core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_20core->tdp_pl1_override = (soc_conf_20core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_20core->tdp_pl1_override = (soc_conf_20core->tdp_pl1_override * performance_scale) / 100; - soc_conf_20core->tdp_pl2_override = (soc_conf_20core->tdp_pl2_override * performance_scale) / 100; + /* Enable/Disable Bluetooth based on CMOS settings */ + if (get_uint_option("bluetooth", 1) == 0) + cfg->usb2_ports[9].enable = 0; /* Enable/Disable Webcam based on CMOS settings */ if (get_uint_option("webcam", 1) == 0) diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/gpio.c b/src/mainboard/starlabs/starfighter/variants/mtl/gpio.c index 63d8218f802..32e7a5f6bc0 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/gpio.c +++ b/src/mainboard/starlabs/starfighter/variants/mtl/gpio.c @@ -1,8 +1,42 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_H07, 1, DEEP), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D20, NONE, PLTRST, NF1), + PAD_CFG_GPO(GPP_A20, 0, PLTRST), + PAD_CFG_GPO(GPP_D22, 1, DEEP), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C10, NONE, PLTRST, NF1), + PAD_CFG_GPO(GPP_H00, 0, PLTRST), + PAD_CFG_GPO(GPP_B19, 1, DEEP), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D21, NONE, PLTRST, NF2), + PAD_CFG_GPO(GPP_H02, 0, PLTRST), +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_A20, 1, PLTRST), + PAD_CFG_GPO(GPP_H00, 1, PLTRST), + PAD_CFG_GPO(GPP_H02, 1, PLTRST), +}; + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), /* RXD */ @@ -17,7 +51,18 @@ const struct pad_config early_gpio_table[] = { PAD_CFG_GPI_LOCK(GPP_B06, NONE, LOCK_CONFIG), PAD_CFG_GPI_LOCK(GPP_B07, NONE, LOCK_CONFIG), PAD_CFG_GPI_LOCK(GPP_B08, NONE, LOCK_CONFIG), + + PAD_CFG_GPI(GPP_D20, NONE, PLTRST), /* Clock Request 8 */ + PAD_CFG_GPO(GPP_A20, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_H07, 0, DEEP), /* Enable (PWREN off) */ + PAD_CFG_GPI(GPP_C10, NONE, PLTRST), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H00, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D22, 0, DEEP), /* Enable (PWREN off) */ + PAD_CFG_GPI(GPP_D21, NONE, PLTRST), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_H02, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_B19, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -26,6 +71,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_V00, NONE, DEEP, NF1), /* Battery Low */ @@ -50,19 +96,19 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC(GPP_B00, NONE, DEEP, LEVEL, INVERT), /* Interrupt */ /* SSD (CPU)*/ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D20, NONE, PLTRST, NF1), /* Clock Request 8 */ - PAD_CFG_GPO(GPP_A20, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_H07, 1, DEEP), /* Enable */ + PAD_NC(GPP_D20, NONE), /* Clock Request 8 */ + PAD_CFG_GPO(GPP_A20, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_H07, 0, DEEP), /* Enable (PWREN off) */ /* SSD (PCH) */ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C10, NONE, PLTRST, NF1), /* Clock Request 1 */ - PAD_CFG_GPO(GPP_H00, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D22, 1, DEEP), /* Enable */ + PAD_NC(GPP_C10, NONE), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H00, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D22, 0, DEEP), /* Enable (PWREN off) */ /* Wireless */ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D21, NONE, PLTRST, NF2), /* Clock Request 5 */ - PAD_CFG_GPO(GPP_H02, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_B19, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D21, NONE), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_H02, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_B19, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_B18, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -252,6 +298,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_D19, NONE), PAD_NC(GPP_D23, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/romstage.c b/src/mainboard/starlabs/starfighter/variants/mtl/romstage.c index 8281dd0ebbf..4a50059cd52 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/romstage.c +++ b/src/mainboard/starlabs/starfighter/variants/mtl/romstage.c @@ -6,16 +6,23 @@ #include #include -static uint8_t strap_to_cbfs_index(uint8_t strap) +static uint8_t strap_to_memcfg_index(uint8_t strap) { switch (strap) { - case 13: // 32GB + case 13: /* 32GB */ return 0; - default: // 64GB + default: /* 64GB */ return 1; } } +static uint8_t memcfg_and_speed_to_cbfs_index(uint8_t memcfg, unsigned int speed) +{ + if (speed > 2) + speed = 2; + return (uint8_t)(memcfg * 3 + speed); +} + void mainboard_memory_init_params(FSPM_UPD *mupd) { const struct mb_cfg mem_config = { @@ -82,7 +89,9 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) const struct mem_spd lpddr5_spd_info = { .topo = MEM_TOPO_MEMORY_DOWN, - .cbfs_index = strap_to_cbfs_index(get_memory_config_straps()), + .cbfs_index = memcfg_and_speed_to_cbfs_index( + strap_to_memcfg_index(get_memory_config_straps()), + get_uint_option("memory_speed", 1)), }; memcfg_init(mupd, &mem_config, &lpddr5_spd_info, half_populated); @@ -91,7 +100,7 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) mupd->FspmConfig.VtdDisable = !vtd; /* Enable/Disable Wireless (RP09) based on CMOS settings */ - if (get_uint_option("wireless", 1) == 0) + if (get_uint_option("wifi", 1) == 0) mupd->FspmConfig.PcieRpEnableMask &= ~(1 << 8); /* Enable/Disable Thunderbolt based on CMOS settings */ diff --git a/src/mainboard/starlabs/starfighter/variants/rpl/board.fmd b/src/mainboard/starlabs/starfighter/variants/rpl/board.fmd index 7f89c336cab..1990e9f88d1 100644 --- a/src/mainboard/starlabs/starfighter/variants/rpl/board.fmd +++ b/src/mainboard/starlabs/starfighter/variants/rpl/board.fmd @@ -6,9 +6,9 @@ FLASH 0x2000000 { SI_BIOS 0x1000000 { EC@0x0 0x20000 RW_MRC_CACHE@0x20000 0x10000 - SMMSTORE@0x30000 0x40000 - CONSOLE@0x70000 0x20000 - FMAP@0x90000 0x1000 + SMMSTORE@0x30000 0x80000 + CONSOLE@0xB0000 0x20000 + FMAP@0xD0000 0x1000 COREBOOT(CBFS) } } diff --git a/src/mainboard/starlabs/starfighter/variants/rpl/devicetree.cb b/src/mainboard/starlabs/starfighter/variants/rpl/devicetree.cb index c911b05a4bc..20d2e3ba672 100644 --- a/src/mainboard/starlabs/starfighter/variants/rpl/devicetree.cb +++ b/src/mainboard/starlabs/starfighter/variants/rpl/devicetree.cb @@ -139,6 +139,9 @@ chip soc/intel/alderlake register "usb2_ports[6]" = "USB2_PORT_MID(OC_SKIP)" register "usb3_ports[1]" = "USB3_PORT_DEFAULT(OC_SKIP)" + # Card Reader + register "usb2_ports[3]" = "USB2_PORT_SHORT(OC_SKIP)" + # Internal Bluetooth register "usb2_ports[9]" = "USB2_PORT_MID(OC_SKIP)" @@ -182,6 +185,12 @@ chip soc/intel/alderlake register "group" = "ACPI_PLD_GROUP(0, 3)" device ref usb3_port2 on end end + chip drivers/usb/acpi + register "desc" = ""Card Reader"" + register "type" = "UPC_TYPE_INTERNAL" + register "group" = "ACPI_PLD_GROUP(0, 4)" + device ref usb2_port4 on end + end chip drivers/usb/acpi register "desc" = ""Internal Webcam"" register "group" = "ACPI_PLD_GROUP(0, 4)" @@ -244,7 +253,6 @@ chip soc/intel/alderlake .flags = PCIE_RP_LTR | PCIE_RP_AER, .pcie_rp_aspm = ASPM_L0S_L1, .PcieRpL1Substates = L1_SS_L1_2, - .pcie_rp_detect_timeout_ms = 50, }" smbios_slot_desc "SlotTypeM2Socket3" diff --git a/src/mainboard/starlabs/starfighter/variants/rpl/devtree.c b/src/mainboard/starlabs/starfighter/variants/rpl/devtree.c index fe9d9117dca..aea5d89b40b 100644 --- a/src/mainboard/starlabs/starfighter/variants/rpl/devtree.c +++ b/src/mainboard/starlabs/starfighter/variants/rpl/devtree.c @@ -10,55 +10,10 @@ #include #include -#define TJ_MAX 110 -#define TCC(temp) (TJ_MAX - temp) - void devtree_update(void) { config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_6core = - &cfg->power_limits_config[RPL_P_282_242_142_15W_CORE]; - - struct soc_power_limits_config *soc_conf_14core = - &cfg->power_limits_config[RPL_P_682_642_482_45W_CORE]; - - struct device *tbt_pci_dev_0 = pcidev_on_root(0x07, 0); - struct device *tbt_pci_dev_1 = pcidev_on_root(0x07, 1); - struct device *tbt_dma_dev = pcidev_on_root(0x0d, 2); - struct device *gna_dev = pcidev_on_root(0x08, 0); - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_6core->tdp_pl4 = 65; - soc_conf_14core->tdp_pl4 = 65; - - /* Set PL1 to 50% of PL2 */ - soc_conf_6core->tdp_pl1_override = (soc_conf_6core->tdp_pl2_override / 2) & ~1; - soc_conf_14core->tdp_pl1_override = (soc_conf_14core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(80); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(90); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(100); - break; - } - - soc_conf_6core->tdp_pl1_override = (soc_conf_6core->tdp_pl1_override * performance_scale) / 100; - soc_conf_6core->tdp_pl2_override = (soc_conf_6core->tdp_pl2_override * performance_scale) / 100; - - soc_conf_14core->tdp_pl1_override = (soc_conf_14core->tdp_pl1_override * performance_scale) / 100; - soc_conf_14core->tdp_pl2_override = (soc_conf_14core->tdp_pl2_override * performance_scale) / 100; + update_power_limits(cfg); /* Enable/Disable Bluetooth based on CMOS settings */ if (get_uint_option("bluetooth", 1) == 0) @@ -70,12 +25,12 @@ void devtree_update(void) /* Enable/Disable Thunderbolt based on CMOS settings */ if (get_uint_option("thunderbolt", 1) == 0) { - tbt_pci_dev_0->enabled = 0; - tbt_pci_dev_1->enabled = 0; - tbt_dma_dev->enabled = 0; + DEV_PTR(tbt_pcie_rp0)->enabled = 0; + DEV_PTR(tbt_pcie_rp1)->enabled = 0; + DEV_PTR(tcss_dma0)->enabled = 0; } /* Enable/Disable GNA based on CMOS settings */ if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; + DEV_PTR(gna)->enabled = 0; } diff --git a/src/mainboard/starlabs/starfighter/variants/rpl/gpio.c b/src/mainboard/starlabs/starfighter/variants/rpl/gpio.c index d58121e83a4..d1b7f60df68 100644 --- a/src/mainboard/starlabs/starfighter/variants/rpl/gpio.c +++ b/src/mainboard/starlabs/starfighter/variants/rpl/gpio.c @@ -1,8 +1,44 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +/* clang-format off */ +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D14, 1, DEEP), + PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_F20, 0, PLTRST), + PAD_CFG_GPO(GPP_D16, 1, PLTRST), + PAD_CFG_NF(GPP_H19, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_H0, 0, PLTRST), + PAD_CFG_GPO(GPP_E3, 1, DEEP), + PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_H2, 0, PLTRST), +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_F20, 1, PLTRST), + PAD_CFG_GPO(GPP_H0, 1, PLTRST), + PAD_CFG_GPO(GPP_H2, 1, PLTRST), +}; +/* clang-format on */ + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ @@ -13,7 +49,18 @@ const struct pad_config early_gpio_table[] = { PAD_CFG_GPI_LOCK(GPP_F13, NONE, LOCK_CONFIG), PAD_CFG_GPI_LOCK(GPP_F14, NONE, LOCK_CONFIG), PAD_CFG_GPI_LOCK(GPP_F15, NONE, LOCK_CONFIG), + + PAD_CFG_GPI(GPP_D6, NONE, DEEP), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_F20, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D14, 0, DEEP), /* Enable (PWREN off) */ + PAD_CFG_GPI(GPP_H19, NONE, DEEP), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D16, 0, PLTRST), /* Enable (PWREN off) */ + PAD_CFG_GPI(GPP_D7, NONE, DEEP), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -22,6 +69,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ @@ -46,19 +94,19 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC_LOW(GPP_D11, NONE, PLTRST), /* Interrupt */ /* SSD */ - PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* Clock Request 5 */ - PAD_CFG_GPO(GPP_F20, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D14, 1, DEEP), /* Enable */ + PAD_NC(GPP_D6, NONE), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_F20, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D14, 0, DEEP), /* Enable (PWREN off) */ /* SSD 2 */ - PAD_CFG_NF(GPP_H19, NONE, DEEP, NF1), /* Clock Request 2 */ - PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, PLTRST), /* Enable */ + PAD_NC(GPP_H19, NONE), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D16, 0, PLTRST), /* Enable (PWREN off) */ /* Wireless */ - PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* Clock Request 1 */ - PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D7, NONE), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_A13, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -265,6 +313,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_R6, NONE), PAD_NC(GPP_R7, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { diff --git a/src/mainboard/starlabs/starfighter/variants/rpl/romstage.c b/src/mainboard/starlabs/starfighter/variants/rpl/romstage.c index 34e61728c41..42425606881 100644 --- a/src/mainboard/starlabs/starfighter/variants/rpl/romstage.c +++ b/src/mainboard/starlabs/starfighter/variants/rpl/romstage.c @@ -40,18 +40,25 @@ static uint8_t get_memory_config_straps(void) return (uint8_t)gpio_base2_value(spd_id, ARRAY_SIZE(spd_id)); } -static uint8_t strap_to_cbfs_index(uint8_t strap) +static uint8_t strap_to_memcfg_index(uint8_t strap) { switch (strap) { - case 0: // 32GB + case 0: /* 32GB */ return 1; - case 8: // 64GB + case 8: /* 64GB */ return 2; - default:// 16GB + default: /* 16GB */ return 0; } } +static uint8_t memcfg_and_speed_to_cbfs_index(uint8_t memcfg, unsigned int speed) +{ + if (speed > 2) + speed = 2; + return (uint8_t)(memcfg * 3 + speed); +} + void mainboard_memory_init_params(FSPM_UPD *mupd) { const struct mb_cfg mem_config = { @@ -118,7 +125,9 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) const struct mem_spd lpddr5_spd_info = { .topo = MEM_TOPO_MEMORY_DOWN, - .cbfs_index = strap_to_cbfs_index(get_memory_config_straps()), + .cbfs_index = memcfg_and_speed_to_cbfs_index( + strap_to_memcfg_index(get_memory_config_straps()), + get_uint_option("memory_speed", 1)), }; memcfg_init(mupd, &mem_config, &lpddr5_spd_info, half_populated); diff --git a/src/mainboard/starlabs/starlite_adl/Kconfig b/src/mainboard/starlabs/starlite_adl/Kconfig deleted file mode 100644 index 6e66d653b0c..00000000000 --- a/src/mainboard/starlabs/starlite_adl/Kconfig +++ /dev/null @@ -1,115 +0,0 @@ -config BOARD_STARLABS_STARLITE_SERIES - def_bool n - select AZALIA_USE_LEGACY_VERB_TABLE - select BOARD_ROMSIZE_KB_16384 - select CRB_TPM - select CSE_DEFAULT_CFR_OPTION_STATE_DISABLED - select DRIVERS_EFI_VARIABLE_STORE - select DRIVERS_GFX_GENERIC - select DRIVERS_I2C_HID - select DRIVERS_INTEL_PMC - select DRIVERS_OPTION_CFR_ENABLED - select EC_STARLABS_MERLIN - select HAVE_ACPI_RESUME - select HAVE_ACPI_TABLES - select HAVE_HDA_DMIC - select HAVE_INTEL_PTT - select HAVE_OPTION_TABLE - select HAVE_SPD_IN_CBFS - select INTEL_GMA_HAVE_VBT - select INTEL_LPSS_UART_FOR_CONSOLE - select NO_UART_ON_SUPERIO - select PMC_IPC_ACPI_INTERFACE - select SOC_INTEL_ALDERLAKE - select SOC_INTEL_ALDERLAKE_PCH_N - select SOC_INTEL_COMMON_BLOCK_HDA_VERB - select SOC_INTEL_COMMON_BLOCK_TCSS - select SOC_INTEL_CRASHLOG - select SPD_READ_BY_WORD - select SPI_FLASH_WINBOND - select SYSTEM_TYPE_DETACHABLE - select TPM2 - select VALIDATE_INTEL_DESCRIPTOR - -config BOARD_STARLABS_LITE_ADL - select BOARD_STARLABS_STARLITE_SERIES - -if BOARD_STARLABS_STARLITE_SERIES - -config CCD_PORT - int - default 5 - -config CONSOLE_SERIAL - default n if !EDK2_DEBUG - -config D3COLD_SUPPORT - default n - -config DEVICETREE - default "variants/\$(CONFIG_VARIANT_DIR)/devicetree.cb" - -config DIMM_SPD_SIZE - default 512 - -config EC_STARLABS_BATTERY_MODEL - default "AEC3756153-2S1P-N" - -config EC_STARLABS_BATTERY_TYPE - default "LION" - -config EC_STARLABS_BATTERY_OEM - default "Apower Electronics" - -config EC_STARLABS_ITE_BIN_PATH - string - default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/ec.bin" - -config FMDFILE - default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/vboot.fmd" if VBOOT - default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" - -config IFD_BIN_PATH - string - default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/flashdescriptor.bin" - -config MAINBOARD_DIR - default "starlabs/starlite_adl" - -config MAINBOARD_FAMILY - string - default "I5" - -config MAINBOARD_PART_NUMBER - default "StarLite Mk V" - -config MAINBOARD_SMBIOS_PRODUCT_NAME - default "StarLite" - -config ME_BIN_PATH - string - default "3rdparty/blobs/mainboard/\$(MAINBOARDDIR)/\$(CONFIG_VARIANT_DIR)/intel_me.bin" - -config POWER_STATE_DEFAULT_ON_AFTER_FAILURE - default n - -config EDK2_BOOTSPLASH_FILE - string - default "3rdparty/blobs/mainboard/starlabs/Logo.bmp" - -config SOC_INTEL_CSE_SEND_EOP_EARLY - default n - -config UART_FOR_CONSOLE - default 0 - -config USE_PM_ACPI_TIMER - default n - -config VBOOT - select VBOOT_VBNV_FLASH - -config VARIANT_DIR - default "mk_v" - -endif diff --git a/src/mainboard/starlabs/starlite_adl/Kconfig.name b/src/mainboard/starlabs/starlite_adl/Kconfig.name deleted file mode 100644 index 071490084b8..00000000000 --- a/src/mainboard/starlabs/starlite_adl/Kconfig.name +++ /dev/null @@ -1,4 +0,0 @@ -comment "Star Labs StarLite Series" - -config BOARD_STARLABS_LITE_ADL - bool "Star Labs Lite Mk V (N200/N355)" diff --git a/src/mainboard/starlabs/starlite_adl/acpi/ec.asl b/src/mainboard/starlabs/starlite_adl/acpi/ec.asl deleted file mode 100644 index 853b0877b33..00000000000 --- a/src/mainboard/starlabs/starlite_adl/acpi/ec.asl +++ /dev/null @@ -1 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ diff --git a/src/mainboard/starlabs/starlite_adl/acpi/sleep.asl b/src/mainboard/starlabs/starlite_adl/acpi/sleep.asl deleted file mode 100644 index 7ed74e3514b..00000000000 --- a/src/mainboard/starlabs/starlite_adl/acpi/sleep.asl +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -Method (MPTS, 1, NotSerialized) -{ - RPTS (Arg0) -} - -Method (MWAK, 1, NotSerialized) -{ - RWAK (Arg0) -} diff --git a/src/mainboard/starlabs/starlite_adl/acpi/superio.asl b/src/mainboard/starlabs/starlite_adl/acpi/superio.asl deleted file mode 100644 index 853b0877b33..00000000000 --- a/src/mainboard/starlabs/starlite_adl/acpi/superio.asl +++ /dev/null @@ -1 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ diff --git a/src/mainboard/starlabs/starlite_adl/bootblock.c b/src/mainboard/starlabs/starlite_adl/bootblock.c deleted file mode 100644 index ca48bb1ab22..00000000000 --- a/src/mainboard/starlabs/starlite_adl/bootblock.c +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -void bootblock_mainboard_init(void) -{ - const struct pad_config *pads; - size_t num; - - pads = variant_early_gpio_table(&num); - gpio_configure_pads(pads, num); -} diff --git a/src/mainboard/starlabs/starlite_adl/cfr.c b/src/mainboard/starlabs/starlite_adl/cfr.c deleted file mode 100644 index 2ed505a17f0..00000000000 --- a/src/mainboard/starlabs/starlite_adl/cfr.c +++ /dev/null @@ -1,110 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void cfr_card_reader_update(struct sm_object *new_obj) -{ - struct device *mxc_accel = DEV_PTR(mxc6655); - - if (!i2c_dev_detect(i2c_busdev(mxc_accel), mxc_accel->path.i2c.device)) - new_obj->sm_bool.flags = CFR_OPTFLAG_SUPPRESS; -} - -static struct sm_obj_form performance = { - .ui_name = "Performance", - .obj_list = (const struct sm_object *[]) { - &bluetooth_rtd3, - &memory_speed, - &power_profile, - NULL - }, -}; - -static struct sm_obj_form processor = { - .ui_name = "Processor", - .obj_list = (const struct sm_object *[]) { - &me_state, - &me_state_counter, - &s0ix_enable, - &vtd, - NULL - }, -}; - -static struct sm_obj_form power = { - .ui_name = "Power", - .obj_list = (const struct sm_object *[]) { - &max_charge, - #if CONFIG(EC_STARLABS_CHARGING_SPEED) - &charging_speed, - #endif - &power_led, - &power_on_after_fail_bool, - NULL - }, -}; - -static struct sm_obj_form devices = { - .ui_name = "Devices", - .obj_list = (const struct sm_object *[]) { - &accelerometer, - &bluetooth, - &card_reader, - &display_native_res, - #if CONFIG(SOC_INTEL_TIGERLAKE) || CONFIG(SOC_INTEL_ALDERLAKE) || CONFIG(SOC_INTEL_RAPTORLAKE) - &gna, - #endif - #if CONFIG(EC_STARLABS_LID_SWITCH) - &lid_switch, - #endif - µphone, - &touchscreen, - &webcam, - &wifi, - NULL - }, -}; - -static struct sm_obj_form pci = { - .ui_name = "PCI", - .obj_list = (const struct sm_object *[]) { - #if CONFIG(SOC_INTEL_COMMON_BLOCK_ASPM) - &pciexp_clk_pm, - &pciexp_aspm, - &pciexp_l1ss, - #endif - NULL - }, -}; - -static struct sm_obj_form coreboot = { - .ui_name = "coreboot", - .obj_list = (const struct sm_object *[]) { - &debug_level, - NULL - }, -}; - -static struct sm_obj_form *sm_root[] = { - &performance, - &processor, - &power, - &devices, - &pci, - &coreboot, - NULL -}; - -void mb_cfr_setup_menu(struct lb_cfr *cfr_root) -{ - cfr_write_setup_menu(cfr_root, sm_root); -} diff --git a/src/mainboard/starlabs/starlite_adl/cmos.layout b/src/mainboard/starlabs/starlite_adl/cmos.layout deleted file mode 100644 index f78701f5d68..00000000000 --- a/src/mainboard/starlabs/starlite_adl/cmos.layout +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -# ----------------------------------------------------------------- -entries - -# Bank: 1 -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory - -# ----------------------------------------------------------------- -# coreboot config options: ramtop -304 80 h 0 ramtop - -# RTC_BOOT_BYTE (coreboot hardcoded) -388 4 h 0 reboot_counter - -# coreboot config options: cpu -#400 8 r 0 reserved for century byte - -# coreboot config options: check sums -984 16 h 0 check_sum - -# Bank: 2 -# embedded controller settings (outside the checksummed area) -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable - -# ----------------------------------------------------------------- -checksums - -checksum 392 983 984 diff --git a/src/mainboard/starlabs/starlite_adl/mainboard.c b/src/mainboard/starlabs/starlite_adl/mainboard.c deleted file mode 100644 index b82e2c0eba2..00000000000 --- a/src/mainboard/starlabs/starlite_adl/mainboard.c +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include - -static void init_mainboard(void *chip_info) -{ - const struct pad_config *pads; - size_t num; - - pads = variant_gpio_table(&num); - gpio_configure_pads(pads, num); - - devtree_update(); -} - -static void mainboard_fill_ssdt(const struct device *dev) -{ - enum ps2_action_key ps2_action_keys[2] = { - PS2_KEY_VOL_DOWN, - PS2_KEY_VOL_UP - }; - acpigen_ps2_keyboard_dsd("_SB.PCI0.PS2K", ARRAY_SIZE(ps2_action_keys), - ps2_action_keys, false, false, false, false, false); -} - -static void enable_mainboard(struct device *dev) -{ - dev->ops->acpi_fill_ssdt = mainboard_fill_ssdt; -} - -struct chip_operations mainboard_ops = { - .init = init_mainboard, - .enable_dev = enable_mainboard, -}; diff --git a/src/mainboard/starlabs/starlite_adl/spd/Makefile.mk b/src/mainboard/starlabs/starlite_adl/spd/Makefile.mk deleted file mode 100644 index 7c50cd736ac..00000000000 --- a/src/mainboard/starlabs/starlite_adl/spd/Makefile.mk +++ /dev/null @@ -1,5 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -SPD_SOURCES = mt62f2g64d8-5500 -SPD_SOURCES += mt62f2g64d8-6400 -SPD_SOURCES += mt62f2g64d8-7500 diff --git a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c b/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c deleted file mode 100644 index 35d289c7ad9..00000000000 --- a/src/mainboard/starlabs/starlite_adl/variants/mk_v/devtree.c +++ /dev/null @@ -1,83 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TJ_MAX 105 -#define TCC(temp) (TJ_MAX - temp) - -void devtree_update(void) -{ - config_t *cfg = config_of_soc(); - - struct soc_power_limits_config *soc_conf_4core = - &cfg->power_limits_config[ADL_N_041_6W_CORE]; - - struct device *wifi_dev = pcidev_on_root(0x14, 3); - struct device *touchscreen_dev = pcidev_on_root(0x15, 2); - struct device *accelerometer_dev = pcidev_on_root(0x15, 0); - struct device *gna_dev = pcidev_on_root(0x08, 0); - - uint8_t performance_scale = 100; - - /* Set PL4 to 1.0C */ - soc_conf_4core->tdp_pl4 = 37; - - /* Set PL1 to 50% of PL2 */ - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl2_override / 2) & ~1; - - /* Scale PL1 & PL2 based on CMOS settings */ - switch (get_power_profile(PP_POWER_SAVER)) { - case PP_POWER_SAVER: - performance_scale -= 50; - cfg->tcc_offset = TCC(70); - break; - case PP_BALANCED: - performance_scale -= 25; - cfg->tcc_offset = TCC(80); - break; - case PP_PERFORMANCE: - /* Use the Intel defaults */ - cfg->tcc_offset = TCC(90); - break; - } - - soc_conf_4core->tdp_pl1_override = (soc_conf_4core->tdp_pl1_override * performance_scale) / 100; - soc_conf_4core->tdp_pl2_override = (soc_conf_4core->tdp_pl2_override * performance_scale) / 100; - - - /* Enable/Disable WiFi based on CMOS settings */ - if (get_uint_option("wifi", 1) == 0) - wifi_dev->enabled = 0; - - /* Enable/Disable Bluetooth based on CMOS settings */ - if (get_uint_option("bluetooth", 1) == 0) - cfg->usb2_ports[9].enable = 0; - - /* Enable/Disable Webcam/Camera based on CMOS settings */ - if (get_uint_option("webcam", 1) == 0) - cfg->usb2_ports[CONFIG_CCD_PORT].enable = 0; - - /* Enable/Disable Touchscreen based on CMOS settings */ - if (get_uint_option("touchscreen", 1) == 0) - touchscreen_dev->enabled = 0; - - /* Enable/Disable Accelerometer based on CMOS settings */ - if (get_uint_option("accelerometer", 1) == 0) - accelerometer_dev->enabled = 0; - - /* Enable/Disable GNA based on CMOS settings */ - if (get_uint_option("gna", 0) == 0) - gna_dev->enabled = 0; - - /* Enable/Disable Card Reader based on CMOS Settings */ - if (get_uint_option("card_reader", 1) == 0) - cfg->usb2_ports[3].enable = 0; -} diff --git a/src/mainboard/starlabs/starlite_adl/vboot.c b/src/mainboard/starlabs/starlite_adl/vboot.c deleted file mode 100644 index 85118250046..00000000000 --- a/src/mainboard/starlabs/starlite_adl/vboot.c +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include - -int get_recovery_mode_switch(void) -{ - return 0; -} diff --git a/src/mainboard/system76/addw1/Kconfig b/src/mainboard/system76/addw1/Kconfig index a444da0441e..4905ec8e557 100644 --- a/src/mainboard/system76/addw1/Kconfig +++ b/src/mainboard/system76/addw1/Kconfig @@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_16384 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA select DRIVERS_I2C_HID select DRIVERS_I2C_TAS5825M select EC_SYSTEM76_EC diff --git a/src/mainboard/system76/addw1/Makefile.mk b/src/mainboard/system76/addw1/Makefile.mk index 09424595d72..1447b6a87f5 100644 --- a/src/mainboard/system76/addw1/Makefile.mk +++ b/src/mainboard/system76/addw1/Makefile.mk @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include bootblock-y += bootblock.c bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c diff --git a/src/mainboard/system76/addw1/acpi/mainboard.asl b/src/mainboard/system76/addw1/acpi/mainboard.asl index 4e67439c569..2f01acc0bc4 100644 --- a/src/mainboard/system76/addw1/acpi/mainboard.asl +++ b/src/mainboard/system76/addw1/acpi/mainboard.asl @@ -1,11 +1,19 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include + #define EC_GPE_SCI 0x03 /* GPP_K3 */ #define EC_GPE_SWI 0x06 /* GPP_K6 */ #include Scope (\_SB) { #include "sleep.asl" + Scope (PCI0) { + Device (PEGP) { + Name (_ADR, CONFIG_DRIVERS_GFX_NVIDIA_BRIDGE << 16) + #include + } + } } Scope (\_GPE) { diff --git a/src/mainboard/system76/addw1/devicetree.cb b/src/mainboard/system76/addw1/devicetree.cb index cd93ddcc148..f9a85fb2fe8 100644 --- a/src/mainboard/system76/addw1/devicetree.cb +++ b/src/mainboard/system76/addw1/devicetree.cb @@ -55,6 +55,12 @@ chip soc/intel/cannonlake # PCI Express Graphics #0 x16, Clock 8 (NVIDIA GPU) register "PcieClkSrcUsage[8]" = "0x40" register "PcieClkSrcClkReq[8]" = "8" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller + end end device ref igpu on end device ref dptf on end diff --git a/src/mainboard/system76/addw1/romstage.c b/src/mainboard/system76/addw1/romstage.c index 02634ba2ad2..fdb208b88db 100644 --- a/src/mainboard/system76/addw1/romstage.c +++ b/src/mainboard/system76/addw1/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include static const struct cnl_mb_cfg memcfg = { .spd[0] = { @@ -20,5 +22,17 @@ static const struct cnl_mb_cfg memcfg = { void mainboard_memory_init_params(FSPM_UPD *memupd) { + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + memupd->FspmConfig.PrimaryDisplay = 0; + cannonlake_memcfg_init(&memupd->FspmConfig, &memcfg); } diff --git a/src/mainboard/system76/oryp6/include/variant/gpio.h b/src/mainboard/system76/addw1/variants/addw1/include/variant/gpio.h similarity index 53% rename from src/mainboard/system76/oryp6/include/variant/gpio.h rename to src/mainboard/system76/addw1/variants/addw1/include/variant/gpio.h index 95d576294f6..c78f11b4cd0 100644 --- a/src/mainboard/system76/oryp6/include/variant/gpio.h +++ b/src/mainboard/system76/addw1/variants/addw1/include/variant/gpio.h @@ -3,7 +3,16 @@ #ifndef VARIANT_GPIO_H #define VARIANT_GPIO_H +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_C12 +#define DGPU_SSID 0x65d11558 + +#ifndef __ACPI__ void variant_configure_early_gpios(void); void variant_configure_gpios(void); +#endif #endif diff --git a/src/mainboard/system76/addw1/variants/addw2/include/variant/gpio.h b/src/mainboard/system76/addw1/variants/addw2/include/variant/gpio.h new file mode 100644 index 00000000000..321cd435271 --- /dev/null +++ b/src/mainboard/system76/addw1/variants/addw2/include/variant/gpio.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_C12 +#define DGPU_SSID 0x65e11558 + +#ifndef __ACPI__ +void variant_configure_early_gpios(void); +void variant_configure_gpios(void); +#endif + +#endif diff --git a/src/mainboard/system76/adl/Kconfig b/src/mainboard/system76/adl/Kconfig index 18c5e9b2d19..ac0b704408f 100644 --- a/src/mainboard/system76/adl/Kconfig +++ b/src/mainboard/system76/adl/Kconfig @@ -11,6 +11,7 @@ config BOARD_SYSTEM76_ADL_COMMON select DRIVERS_INTEL_PMC select DRIVERS_INTEL_USB4_RETIMER select EC_SYSTEM76_EC + select EC_SYSTEM76_EC_LOCKDOWN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_CMOS_DEFAULT @@ -35,10 +36,12 @@ config BOARD_SYSTEM76_GALP6 config BOARD_SYSTEM76_GAZE17_3050 select BOARD_SYSTEM76_ADL_COMMON + select DRIVERS_GFX_NVIDIA select EC_SYSTEM76_EC_DGPU config BOARD_SYSTEM76_GAZE17_3060_B select BOARD_SYSTEM76_ADL_COMMON + select DRIVERS_GFX_NVIDIA select EC_SYSTEM76_EC_DGPU select MAINBOARD_USES_IFD_GBE_REGION @@ -48,11 +51,15 @@ config BOARD_SYSTEM76_LEMP11 config BOARD_SYSTEM76_ORYP9 select BOARD_SYSTEM76_ADL_COMMON + select DRIVERS_GFX_NVIDIA + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select DRIVERS_I2C_TAS5825M select EC_SYSTEM76_EC_DGPU config BOARD_SYSTEM76_ORYP10 select BOARD_SYSTEM76_ADL_COMMON + select DRIVERS_GFX_NVIDIA + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU if BOARD_SYSTEM76_ADL_COMMON @@ -97,12 +104,22 @@ config MAINBOARD_VERSION default "oryp9" if BOARD_SYSTEM76_ORYP9 default "oryp10" if BOARD_SYSTEM76_ORYP10 +config CMOS_DEFAULT_FILE + default "src/mainboard/\$(MAINBOARDDIR)/cmos-csme.default" if BOARD_SYSTEM76_DARP8 + default "src/mainboard/\$(MAINBOARDDIR)/cmos.default" + config CONSOLE_POST default y config D3COLD_SUPPORT default n +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP + default 45 if BOARD_SYSTEM76_ORYP9 || BOARD_SYSTEM76_ORYP10 + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX + default 25 if BOARD_SYSTEM76_ORYP9 || BOARD_SYSTEM76_ORYP10 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/board.fmd" diff --git a/src/mainboard/system76/adl/Makefile.mk b/src/mainboard/system76/adl/Makefile.mk index c5334f1f0cf..727ce27218c 100644 --- a/src/mainboard/system76/adl/Makefile.mk +++ b/src/mainboard/system76/adl/Makefile.mk @@ -2,6 +2,10 @@ CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include +ifeq ($(CONFIG_DRIVERS_GFX_NVIDIA),y) +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include +endif + bootblock-y += bootblock.c bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c diff --git a/src/mainboard/system76/adl/acpi/mainboard.asl b/src/mainboard/system76/adl/acpi/mainboard.asl index c982a9ee4cb..f7453fc339e 100644 --- a/src/mainboard/system76/adl/acpi/mainboard.asl +++ b/src/mainboard/system76/adl/acpi/mainboard.asl @@ -1,5 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#if CONFIG(DRIVERS_GFX_NVIDIA) +#include +#endif + #define EC_GPE_SCI 0x6E #define EC_GPE_SWI 0x6B #include @@ -8,5 +12,11 @@ Scope (\_SB) { #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" + +#if CONFIG(DRIVERS_GFX_NVIDIA) + Scope (PEG2) { + #include + } +#endif } } diff --git a/src/mainboard/system76/adl/cmos-csme.default b/src/mainboard/system76/adl/cmos-csme.default new file mode 100644 index 00000000000..d61046df6b0 --- /dev/null +++ b/src/mainboard/system76/adl/cmos-csme.default @@ -0,0 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + +boot_option=Fallback +debug_level=Debug +me_state=Enable diff --git a/src/mainboard/system76/adl/variants/darp8/overridetree.cb b/src/mainboard/system76/adl/variants/darp8/overridetree.cb index 3af580229b8..d9c1a713ccc 100644 --- a/src/mainboard/system76/adl/variants/darp8/overridetree.cb +++ b/src/mainboard/system76/adl/variants/darp8/overridetree.cb @@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only chip soc/intel/alderlake + register "s0ix_enable" = "1" + register "power_limits_config[ADL_P_282_442_482_28W_CORE]" = "{ .tdp_pl1_override = 20, .tdp_pl2_override = 56, diff --git a/src/mainboard/system76/adl/variants/gaze17-3050/include/variant/gpio.h b/src/mainboard/system76/adl/variants/gaze17-3050/include/variant/gpio.h new file mode 100644 index 00000000000..5c2c0635fad --- /dev/null +++ b/src/mainboard/system76/adl/variants/gaze17-3050/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_F13 +#define DGPU_SSID 0x866d1558 + +#endif diff --git a/src/mainboard/system76/adl/variants/gaze17-3050/overridetree.cb b/src/mainboard/system76/adl/variants/gaze17-3050/overridetree.cb index 511e0535b77..876576f7c9d 100644 --- a/src/mainboard/system76/adl/variants/gaze17-3050/overridetree.cb +++ b/src/mainboard/system76/adl/variants/gaze17-3050/overridetree.cb @@ -40,6 +40,10 @@ chip soc/intel/alderlake .clk_req = 3, .flags = PCIE_RP_LTR, }" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + end end device ref pcie4_0 on # PCIe PEG0 x4, Clock 0 (SSD2) diff --git a/src/mainboard/system76/adl/variants/gaze17-3050/romstage.c b/src/mainboard/system76/adl/variants/gaze17-3050/romstage.c index 5e6cf7dd52a..cea4ff51551 100644 --- a/src/mainboard/system76/adl/variants/gaze17-3050/romstage.c +++ b/src/mainboard/system76/adl/variants/gaze17-3050/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -17,6 +19,14 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/adl/variants/gaze17-3060-b/include/variant/gpio.h b/src/mainboard/system76/adl/variants/gaze17-3060-b/include/variant/gpio.h new file mode 100644 index 00000000000..6bf3550d25f --- /dev/null +++ b/src/mainboard/system76/adl/variants/gaze17-3060-b/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_F13 +#define DGPU_SSID 0x867c1558 + +#endif diff --git a/src/mainboard/system76/adl/variants/gaze17-3060-b/overridetree.cb b/src/mainboard/system76/adl/variants/gaze17-3060-b/overridetree.cb index de679352932..a81796db0fd 100644 --- a/src/mainboard/system76/adl/variants/gaze17-3060-b/overridetree.cb +++ b/src/mainboard/system76/adl/variants/gaze17-3060-b/overridetree.cb @@ -40,6 +40,10 @@ chip soc/intel/alderlake .clk_req = 3, .flags = PCIE_RP_LTR, }" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + end end device ref igpu on # DDIA is eDP diff --git a/src/mainboard/system76/adl/variants/gaze17-3060-b/romstage.c b/src/mainboard/system76/adl/variants/gaze17-3060-b/romstage.c index 5e6cf7dd52a..cea4ff51551 100644 --- a/src/mainboard/system76/adl/variants/gaze17-3060-b/romstage.c +++ b/src/mainboard/system76/adl/variants/gaze17-3060-b/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -17,6 +19,14 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/adl/variants/oryp10/include/variant/gpio.h b/src/mainboard/system76/adl/variants/oryp10/include/variant/gpio.h new file mode 100644 index 00000000000..489487ba7b1 --- /dev/null +++ b/src/mainboard/system76/adl/variants/oryp10/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_A7 +#define DGPU_SSID 0x65f51558 + +#endif diff --git a/src/mainboard/system76/adl/variants/oryp10/overridetree.cb b/src/mainboard/system76/adl/variants/oryp10/overridetree.cb index b213892232b..94b10599608 100644 --- a/src/mainboard/system76/adl/variants/oryp10/overridetree.cb +++ b/src/mainboard/system76/adl/variants/oryp10/overridetree.cb @@ -25,6 +25,10 @@ chip soc/intel/alderlake .clk_req = 3, .flags = PCIE_RP_LTR, }" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + end end device ref igpu on register "ddi_portA_config" = "1" diff --git a/src/mainboard/system76/adl/variants/oryp10/romstage.c b/src/mainboard/system76/adl/variants/oryp10/romstage.c index 86ecf32826c..dfd826a759c 100644 --- a/src/mainboard/system76/adl/variants/oryp10/romstage.c +++ b/src/mainboard/system76/adl/variants/oryp10/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -20,6 +22,14 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/adl/variants/oryp9/include/variant/gpio.h b/src/mainboard/system76/adl/variants/oryp9/include/variant/gpio.h new file mode 100644 index 00000000000..489487ba7b1 --- /dev/null +++ b/src/mainboard/system76/adl/variants/oryp9/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_A7 +#define DGPU_SSID 0x65f51558 + +#endif diff --git a/src/mainboard/system76/adl/variants/oryp9/overridetree.cb b/src/mainboard/system76/adl/variants/oryp9/overridetree.cb index e41c0a278a4..3cbf1b984f3 100644 --- a/src/mainboard/system76/adl/variants/oryp9/overridetree.cb +++ b/src/mainboard/system76/adl/variants/oryp9/overridetree.cb @@ -25,6 +25,10 @@ chip soc/intel/alderlake .clk_req = 3, .flags = PCIE_RP_LTR, }" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + end end device ref igpu on register "ddi_portA_config" = "1" diff --git a/src/mainboard/system76/adl/variants/oryp9/romstage.c b/src/mainboard/system76/adl/variants/oryp9/romstage.c index 5e6cf7dd52a..cea4ff51551 100644 --- a/src/mainboard/system76/adl/variants/oryp9/romstage.c +++ b/src/mainboard/system76/adl/variants/oryp9/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -17,6 +19,14 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/bonw14/Kconfig b/src/mainboard/system76/bonw14/Kconfig index 7c7e42e10be..77842e493ea 100644 --- a/src/mainboard/system76/bonw14/Kconfig +++ b/src/mainboard/system76/bonw14/Kconfig @@ -8,7 +8,9 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_16384 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA select DRIVERS_I2C_HID + select DRIVERS_I2C_TAS5825M select EC_SYSTEM76_EC select EC_SYSTEM76_EC_DGPU select HAVE_ACPI_RESUME diff --git a/src/mainboard/system76/bonw14/Makefile.mk b/src/mainboard/system76/bonw14/Makefile.mk index 2efcac5f428..89b8816938e 100644 --- a/src/mainboard/system76/bonw14/Makefile.mk +++ b/src/mainboard/system76/bonw14/Makefile.mk @@ -10,3 +10,4 @@ romstage-y += romstage.c ramstage-y += ramstage.c ramstage-y += gpio.c ramstage-y += hda_verb.c +ramstage-y += tas5825m.c diff --git a/src/mainboard/system76/bonw14/devicetree.cb b/src/mainboard/system76/bonw14/devicetree.cb index 4064c00b556..d4d9c6d3182 100644 --- a/src/mainboard/system76/bonw14/devicetree.cb +++ b/src/mainboard/system76/bonw14/devicetree.cb @@ -58,11 +58,12 @@ chip soc/intel/cannonlake # PCI Express Graphics #0 x16, Clock 7 (NVIDIA GPU) register "PcieClkSrcUsage[7]" = "0x40" register "PcieClkSrcClkReq[7]" = "7" - - device pci 00.0 on end # VGA controller - device pci 00.1 on end # Audio device - device pci 00.2 on end # USB xHCI Host controller - device pci 00.3 on end # USB Type-C UCSI controller + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller + end end device ref dptf on end device ref thermal on end @@ -175,6 +176,15 @@ chip soc/intel/cannonlake device ref hda on register "PchHdaAudioLinkHda" = "1" end - device ref smbus on end + device ref smbus on + chip drivers/i2c/tas5825m + register "id" = "0" + device i2c 4e on end # (8bit address: 0x9c) + end + chip drivers/i2c/tas5825m + register "id" = "1" + device i2c 4f on end # (8bit address: 0x9e) + end + end end end diff --git a/src/mainboard/system76/bonw14/tas5825m-normal.c b/src/mainboard/system76/bonw14/tas5825m-normal.c new file mode 100644 index 00000000000..81695effd80 --- /dev/null +++ b/src/mainboard/system76/bonw14/tas5825m-normal.c @@ -0,0 +1,1240 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +static int tas5825m_setup_normal(struct device *dev) +{ + int res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x01, 0x11); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x46, 0x11); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x02, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x53, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x54, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x29, 0x7C); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x29, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x12); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x48, 0x0C); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x64); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0xFE, 0x00, 0x40, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x50, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x93, 0x00, 0xFC, 0x00, 0x00, + 0x8F, 0x00, 0xFF, 0xEF, 0x84, 0x49, 0x03, 0x27, + 0x84, 0x02, 0x04, 0x06, 0x02, 0x60, 0x00, 0x01, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0x70, 0x00, 0x06, 0x02, 0x78, 0x00, 0x05, + 0x02, 0x68, 0x00, 0x02, 0x02, 0x28, 0x03, 0x4D, + 0x84, 0x2A, 0x04, 0x00, 0xE2, 0x57, 0x91, 0x9F, + 0x84, 0x82, 0x20, 0xE0, 0x84, 0x82, 0x04, 0x01, + 0xF0, 0x1C, 0x31, 0xA0, 0xF0, 0x1C, 0x31, 0xA1, + 0xF0, 0x1C, 0x31, 0xA2, 0xF0, 0x1F, 0x31, 0xA3, + 0xE4, 0x00, 0x11, 0xA6, 0x80, 0x27, 0x80, 0xE1, + 0xF4, 0x00, 0x11, 0xA4, 0xF4, 0x1D, 0x31, 0xA5, + 0xF4, 0x1C, 0x31, 0xA7, 0xF4, 0x1F, 0x31, 0xA8, + 0x02, 0x78, 0x00, 0x03, 0xE2, 0x68, 0xF1, 0xC3, + 0x80, 0x67, 0x80, 0xE9, 0x84, 0x4B, 0x03, 0x27, + 0x02, 0x70, 0x00, 0x04, 0x84, 0x41, 0x03, 0x37, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x00, 0x11, 0xA9, + 0x84, 0x82, 0x00, 0xE0, 0x8E, 0xFC, 0x04, 0x10, + 0xF0, 0x1C, 0x11, 0xAA, 0xF0, 0x1C, 0x11, 0xAB, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x03); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xF0, 0x1C, 0x11, 0xAC, 0xF0, 0x1F, 0x11, 0xAD, + 0x86, 0xA1, 0x01, 0xC2, 0x80, 0x27, 0x80, 0xE8, + 0x60, 0x00, 0x00, 0x00, 0x84, 0x43, 0x03, 0x37, + 0x80, 0x00, 0x00, 0x81, 0x0D, 0x00, 0x10, 0x20, + 0x84, 0x51, 0x03, 0x3E, 0x08, 0x44, 0x26, 0x30, + 0x84, 0xC3, 0x03, 0x47, 0x84, 0xC2, 0x40, 0xE0, + 0x8C, 0xFF, 0x03, 0x23, 0xE0, 0x10, 0x11, 0xB3, + 0xF0, 0x1C, 0x51, 0xB4, 0xF0, 0x1C, 0x51, 0xB5, + 0xF0, 0x1C, 0x51, 0xB6, 0xF0, 0x1F, 0x51, 0xB7, + 0x86, 0xA1, 0x01, 0xC6, 0x80, 0x27, 0x80, 0xEA, + 0x84, 0x53, 0x03, 0x3E, 0x84, 0x82, 0x04, 0x05, + 0x84, 0x51, 0x03, 0x75, 0xE2, 0x6B, 0xC0, 0x00, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x80, 0x31, 0xB8, + 0x84, 0x82, 0x40, 0xE0, 0xF0, 0x1C, 0x51, 0xB9, + 0xF0, 0x1C, 0x51, 0xBA, 0xF0, 0x1C, 0x51, 0xBB, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x04); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xF0, 0x1F, 0x51, 0xBC, 0x86, 0xA1, 0x01, 0xC5, + 0x80, 0x27, 0x80, 0xEA, 0x60, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x81, 0x84, 0xA1, 0x03, 0x4F, + 0xE0, 0x80, 0xA0, 0x00, 0x01, 0x07, 0x11, 0x20, + 0x08, 0x44, 0x26, 0x30, 0x08, 0x00, 0x98, 0x4A, + 0x84, 0x53, 0x03, 0x75, 0x08, 0x00, 0x30, 0x48, + 0x02, 0xCA, 0x00, 0x01, 0x08, 0x60, 0x26, 0x32, + 0x84, 0x51, 0x03, 0x45, 0xE4, 0x10, 0x40, 0x00, + 0x80, 0x40, 0xC0, 0x82, 0x84, 0xC2, 0x40, 0xE0, + 0x84, 0xC3, 0x03, 0x5E, 0x08, 0x00, 0x50, 0x48, + 0xE0, 0x10, 0x11, 0xBD, 0x02, 0xC2, 0x00, 0x02, + 0x08, 0x60, 0x06, 0x12, 0x84, 0xD3, 0x03, 0x4F, + 0xF0, 0x1C, 0x51, 0xBE, 0xF0, 0x1C, 0x51, 0xBF, + 0xF0, 0x1C, 0x51, 0xC0, 0xF0, 0x1F, 0x51, 0xC1, + 0x84, 0xA1, 0x03, 0x65, 0x80, 0x27, 0x80, 0xEA, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x05); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x83, + 0x08, 0x00, 0x98, 0x6B, 0x08, 0x00, 0x30, 0x68, + 0x84, 0x53, 0x03, 0x45, 0x08, 0x60, 0x26, 0x33, + 0x84, 0x51, 0x03, 0x25, 0xE4, 0x10, 0x60, 0x00, + 0x80, 0x40, 0xC0, 0x81, 0x02, 0x70, 0x00, 0x7F, + 0x08, 0x00, 0x50, 0x28, 0x08, 0x60, 0x06, 0x11, + 0x84, 0xCB, 0x03, 0x65, 0xE0, 0x10, 0x51, 0xC4, + 0x84, 0x80, 0x41, 0x00, 0x02, 0xA3, 0x00, 0x10, + 0xE4, 0x00, 0x00, 0x00, 0x84, 0xD0, 0x04, 0x01, + 0x84, 0xA2, 0x04, 0x03, 0x84, 0xD2, 0x50, 0x01, + 0x84, 0x53, 0x03, 0x25, 0x80, 0x00, 0xC4, 0x04, + 0x8F, 0x30, 0x00, 0x00, 0x88, 0x67, 0x03, 0x00, + 0xE4, 0x00, 0x11, 0x9B, 0xEE, 0x64, 0x60, 0x00, + 0x02, 0xD3, 0x00, 0x10, 0x88, 0x47, 0x00, 0x80, + 0x10, 0x00, 0x18, 0x02, 0x86, 0xC1, 0x01, 0x9D, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x06); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x10, 0x31, 0xC7, 0x86, 0xC9, 0x01, 0x9E, + 0x80, 0x00, 0xC4, 0x02, 0x02, 0x50, 0x01, 0x9C, + 0x00, 0xFF, 0x21, 0x65, 0x00, 0xFC, 0x00, 0x00, + 0x02, 0x60, 0x00, 0x01, 0x02, 0x70, 0x00, 0x04, + 0x84, 0xC8, 0x04, 0x10, 0x84, 0x41, 0x03, 0x67, + 0x84, 0x51, 0x03, 0x6D, 0x84, 0xC0, 0x04, 0x02, + 0x04, 0x80, 0x91, 0x20, 0x08, 0x60, 0x26, 0x30, + 0x02, 0x78, 0x00, 0x03, 0x02, 0x68, 0x00, 0x02, + 0x0D, 0x00, 0x10, 0x10, 0x08, 0x60, 0x06, 0x12, + 0x84, 0x49, 0x03, 0x2F, 0xE0, 0x80, 0x71, 0xA9, + 0x02, 0x28, 0x03, 0x55, 0x84, 0x82, 0x00, 0xE0, + 0x84, 0x2A, 0x04, 0x00, 0xF0, 0x1C, 0x11, 0xAA, + 0xF0, 0x1C, 0x11, 0xAB, 0xF0, 0x1C, 0x11, 0xAC, + 0xF0, 0x1F, 0x11, 0xAD, 0x86, 0xA1, 0x01, 0xAE, + 0x80, 0x27, 0x80, 0xE8, 0x84, 0x82, 0x04, 0x07, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x07); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x80, 0x60, 0x00, 0x84, 0x82, 0x40, 0xE0, + 0x84, 0x43, 0x03, 0x67, 0xF0, 0x1C, 0x51, 0xAF, + 0xF0, 0x1C, 0x51, 0xB0, 0xF0, 0x1C, 0x51, 0xB1, + 0xF0, 0x1F, 0x51, 0xB2, 0x02, 0x78, 0x00, 0x05, + 0x80, 0x27, 0x80, 0xEA, 0x84, 0x82, 0x04, 0x08, + 0x02, 0x70, 0x00, 0x06, 0x84, 0x53, 0x03, 0x6D, + 0x84, 0x80, 0x04, 0x07, 0xE0, 0x00, 0x00, 0x82, + 0xF0, 0x81, 0x00, 0x80, 0x80, 0x07, 0x12, 0xBC, + 0x86, 0xA1, 0x01, 0x9F, 0xE2, 0x57, 0xA0, 0x00, + 0x84, 0x82, 0x04, 0x09, 0x84, 0x82, 0x20, 0xE0, + 0xF0, 0x1C, 0x31, 0xA0, 0xF0, 0x1C, 0x31, 0xA1, + 0xF0, 0x1C, 0x31, 0xA2, 0xF0, 0x1F, 0x31, 0xA3, + 0xE4, 0x00, 0x11, 0xA6, 0x80, 0x27, 0x80, 0xE1, + 0xF4, 0x00, 0x11, 0xA4, 0xF4, 0x1D, 0x31, 0xA5, + 0xF4, 0x1C, 0x31, 0xA7, 0xF4, 0x1F, 0x31, 0xA8, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x08); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0x78, 0x00, 0x03, 0xE2, 0x6A, 0xF1, 0xC3, + 0x80, 0x67, 0x80, 0xE9, 0x84, 0x4B, 0x03, 0x2F, + 0x02, 0x70, 0x00, 0x04, 0x84, 0x59, 0x03, 0x3D, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x00, 0x11, 0xA9, + 0x84, 0x82, 0x60, 0xE0, 0x8E, 0xFC, 0x04, 0x10, + 0xF0, 0x1C, 0x71, 0xAA, 0xF0, 0x1C, 0x71, 0xAB, + 0xF0, 0x1C, 0x71, 0xAC, 0xF0, 0x1F, 0x71, 0xAD, + 0x86, 0xA1, 0x01, 0xC2, 0x80, 0x27, 0x80, 0xEB, + 0x60, 0x00, 0x00, 0x00, 0x84, 0x5B, 0x03, 0x3D, + 0x80, 0x00, 0x00, 0x81, 0x0D, 0x00, 0x10, 0x20, + 0x84, 0x59, 0x03, 0x3F, 0x08, 0x44, 0x26, 0x30, + 0x84, 0xC3, 0x03, 0x57, 0x84, 0xC2, 0x60, 0xE0, + 0xE0, 0x10, 0x11, 0xB3, 0xF0, 0x1C, 0x71, 0xB4, + 0xF0, 0x1C, 0x71, 0xB5, 0xF0, 0x1C, 0x71, 0xB6, + 0xF0, 0x1F, 0x71, 0xB7, 0x86, 0xA1, 0x01, 0xC6, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x09); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x80, 0x27, 0x80, 0xEB, 0x84, 0x5B, 0x03, 0x3F, + 0x84, 0x82, 0x04, 0x0D, 0x84, 0x41, 0x03, 0x76, + 0xE2, 0x6B, 0xE0, 0x00, 0x80, 0x07, 0x00, 0x80, + 0xE0, 0x81, 0x31, 0xB8, 0x84, 0x82, 0x00, 0xE0, + 0xF0, 0x1C, 0x11, 0xB9, 0xF0, 0x1C, 0x11, 0xBA, + 0xF0, 0x1C, 0x11, 0xBB, 0xF0, 0x1F, 0x11, 0xBC, + 0x86, 0xA1, 0x01, 0xC5, 0x80, 0x27, 0x80, 0xE8, + 0x60, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x81, + 0x84, 0xA1, 0x03, 0x5D, 0xE0, 0x81, 0xA0, 0x00, + 0x01, 0x07, 0x11, 0x20, 0x08, 0x44, 0x26, 0x30, + 0x08, 0x00, 0x98, 0x4A, 0x84, 0x43, 0x03, 0x76, + 0x08, 0x00, 0x30, 0x48, 0x02, 0xCA, 0x00, 0x01, + 0x08, 0x60, 0x26, 0x32, 0x84, 0x41, 0x03, 0x46, + 0xE4, 0x10, 0x40, 0x00, 0x80, 0x40, 0xC0, 0x82, + 0x84, 0xC2, 0x00, 0xE0, 0x84, 0xC3, 0x03, 0x5F, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0A); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x50, 0x48, 0xE0, 0x10, 0x11, 0xBD, + 0x02, 0xC2, 0x00, 0x02, 0x08, 0x60, 0x06, 0x12, + 0x84, 0xD3, 0x03, 0x5D, 0xF0, 0x1C, 0x11, 0xBE, + 0xF0, 0x1C, 0x11, 0xBF, 0xF0, 0x1C, 0x11, 0xC0, + 0xF0, 0x1F, 0x11, 0xC1, 0x84, 0xA1, 0x03, 0x66, + 0x80, 0x27, 0x80, 0xE8, 0xE0, 0x00, 0x00, 0x00, + 0x80, 0x07, 0x00, 0x83, 0x08, 0x00, 0x98, 0x6B, + 0x08, 0x00, 0x30, 0x68, 0x84, 0x43, 0x03, 0x46, + 0x08, 0x60, 0x26, 0x33, 0x84, 0x51, 0x03, 0x26, + 0xE4, 0x10, 0x60, 0x00, 0x80, 0x40, 0xC0, 0x81, + 0x02, 0x70, 0x00, 0x7F, 0x08, 0x00, 0x50, 0x28, + 0x08, 0x60, 0x06, 0x11, 0x8C, 0xFF, 0x03, 0x24, + 0x84, 0xCB, 0x03, 0x66, 0xE0, 0x10, 0x51, 0xC4, + 0x84, 0x80, 0x41, 0x00, 0x02, 0xA3, 0x00, 0x10, + 0xE4, 0x00, 0x00, 0x00, 0x84, 0xD0, 0x04, 0x09, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x84, 0xA2, 0x04, 0x0B, 0x84, 0xD2, 0x50, 0x01, + 0x84, 0x53, 0x03, 0x26, 0x80, 0x00, 0xC4, 0x0C, + 0x8F, 0x30, 0x00, 0x00, 0x88, 0x67, 0x03, 0x00, + 0xE4, 0x00, 0x11, 0x9B, 0xEE, 0x64, 0x80, 0x00, + 0x02, 0xD3, 0x00, 0x10, 0x88, 0x47, 0x00, 0x80, + 0x10, 0x00, 0x18, 0x02, 0x86, 0xC1, 0x01, 0x9D, + 0xE0, 0x10, 0x31, 0xC7, 0x86, 0xC9, 0x01, 0x9E, + 0x80, 0x00, 0xC4, 0x0A, 0x02, 0x50, 0x01, 0x9C, + 0x00, 0xFF, 0x21, 0x65, 0x00, 0xFC, 0x00, 0x00, + 0x02, 0x70, 0x00, 0x04, 0x02, 0x68, 0x00, 0x01, + 0x02, 0x60, 0x00, 0x03, 0x02, 0x78, 0x00, 0x02, + 0x84, 0x49, 0x03, 0x6E, 0x84, 0x41, 0x03, 0x6F, + 0x84, 0xC8, 0x04, 0x10, 0x84, 0xC0, 0x04, 0x0A, + 0x04, 0x81, 0x91, 0x20, 0x08, 0x60, 0x26, 0x30, + 0x0D, 0x00, 0x10, 0x10, 0x08, 0x60, 0x06, 0x12, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x84, 0x00, 0x04, 0x06, 0xE0, 0x81, 0x71, 0xA9, + 0x84, 0x82, 0x20, 0xE8, 0xF0, 0x1D, 0x31, 0xAA, + 0xF0, 0x1D, 0x31, 0xAB, 0xF0, 0x1D, 0x31, 0xAC, + 0xF0, 0x1C, 0x31, 0xAD, 0x86, 0xA1, 0x01, 0xAE, + 0x80, 0x27, 0x80, 0xF9, 0x84, 0x82, 0x04, 0x0E, + 0xE0, 0x81, 0x60, 0x00, 0x84, 0x82, 0x00, 0xE8, + 0x84, 0x4B, 0x03, 0x6E, 0xF0, 0x1D, 0x11, 0xAF, + 0xF0, 0x1D, 0x11, 0xB0, 0xF0, 0x1D, 0x11, 0xB1, + 0xF0, 0x1C, 0x11, 0xB2, 0x02, 0xA3, 0x00, 0x1A, + 0x80, 0x27, 0x80, 0xF8, 0x84, 0x82, 0x04, 0x0F, + 0xE0, 0x81, 0xC0, 0x00, 0xF0, 0x81, 0xE0, 0x80, + 0x84, 0x43, 0x03, 0x6F, 0x80, 0x07, 0x12, 0xBD, + 0x02, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0x50, 0x00, + 0x8F, 0x00, 0x00, 0x11, 0x8F, 0x00, 0xFF, 0xFF, + 0x84, 0x58, 0x04, 0x01, 0x84, 0xC2, 0x04, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0xC2, 0x60, 0x00, 0x84, 0xA0, 0x61, 0x00, + 0xE0, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x40, 0x40, 0xA0, 0x00, 0x80, 0x00, 0xC0, 0x82, + 0x08, 0xFC, 0x48, 0x3A, 0x08, 0xFC, 0x18, 0x50, + 0x00, 0xFC, 0x00, 0x00, 0xE0, 0x10, 0x00, 0x00, + 0x86, 0xA0, 0x41, 0x00, 0x40, 0x47, 0x20, 0x00, + 0x80, 0x00, 0xC0, 0x83, 0x04, 0xE0, 0x3D, 0x1E, + 0x04, 0x80, 0x11, 0xE0, 0x08, 0x44, 0x26, 0x33, + 0x02, 0xCB, 0x00, 0x10, 0xE0, 0x10, 0x40, 0x83, + 0x08, 0x00, 0x28, 0x21, 0x84, 0xCA, 0x61, 0x00, + 0x80, 0x07, 0x00, 0x81, 0x0C, 0xE0, 0x2C, 0x09, + 0x84, 0xCA, 0x21, 0x00, 0x00, 0xFC, 0x50, 0x00, + 0x8F, 0x00, 0x00, 0x01 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x18); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x30, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x03, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x1C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x3C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x40, 0x00, 0x00, 0x03, 0x48, + 0x00, 0x00, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x54, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x58, 0x00, 0x00, 0x03, 0x60, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x74, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x1C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x3C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x0C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x70, 0x00, 0x00, 0x03, 0x78, + 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x24, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x04, 0x88, 0x00, 0x00, 0x04, 0x90, + }; + res = tas5825m_write_block_at(dev, 0x44, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x8C); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0xA7, 0x26, 0x4A, 0x7F, 0xFF, 0xFF, 0xFF, + 0x00, 0x20, 0xC4, 0x9C, 0x00, 0x20, 0xC4, 0x9C, + 0x00, 0x00, 0x68, 0xDB, 0x00, 0x00, 0xD1, 0xB7, + 0x00, 0x00, 0x68, 0xDB, 0x0F, 0xA4, 0xA8, 0xC1, + 0xF8, 0x59, 0x7F, 0x63 + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xB7, 0xE9, + 0x00, 0x5F, 0x6F, 0xD2, 0x00, 0x2F, 0xB7, 0xE9, + 0x0B, 0x1E, 0x4F, 0x76, 0xFC, 0x23, 0x05, 0x54, + 0xFA, 0x41, 0x20, 0x5C, 0x0B, 0x7D, 0xBF, 0x48, + 0xFA, 0x41, 0x20, 0x5C, 0x0B, 0x1E, 0x4F, 0x76, + 0xFC, 0x23, 0x05, 0x54, 0x00, 0x04, 0x81, 0x6F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x3F, 0xE5, 0xC9, 0xF8, 0xBB, 0x98, 0xC8, + 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x81, 0x6F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x3F, 0xE5, 0xC9, 0xF8, 0xBB, 0x98, 0xC8, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x10); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x89, 0xA0, 0x27, 0x7F, 0xEC, 0x56, 0xD5, + 0x7F, 0xFC, 0xB9, 0x23, 0x00, 0x89, 0xA0, 0x27, + 0x7F, 0xEC, 0x56, 0xD5, 0x7F, 0xFC, 0xB9, 0x23, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x40, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x11, 0xFF + }; + res = tas5825m_write_block_at(dev, 0x7D, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x51, 0x05); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x19, 0xDF); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x8C); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x71, 0x94, 0x9A + }; + res = tas5825m_write_block_at(dev, 0x2C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0A); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x64, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00, 0x00, 0x0C, 0xCC, 0xCD, + 0x00, 0x0C, 0xCC, 0xCD, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x57, 0x62, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x28, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x03, 0x69, 0xC5, 0x00, 0xA9, 0x15, 0xB8, + 0x00, 0x22, 0x1D, 0x95, 0x00, 0x03, 0x69, 0xC5, + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x7F, 0xF9, 0x2C, 0x60, 0x01, 0x33, 0x51, 0x50, + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x07); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x64, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0xAA); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xD1, 0x27, 0x3E, 0xF0, 0x5D, 0xB1, 0x85, + 0x07, 0xD1, 0x27, 0x3E, 0x0F, 0xA1, 0x3C, 0x1E, + 0xF8, 0x5C, 0x9F, 0x28, 0x07, 0xD1, 0x27, 0x3E, + 0xF0, 0x5D, 0xB1, 0x85, 0x07, 0xD1, 0x27, 0x3E, + 0x0F, 0xA1, 0x3C, 0x1E, 0xF8, 0x5C, 0x9F, 0x28, + 0x08, 0x00, 0x00, 0x00, 0xF0, 0x71, 0x4C, 0x87, + 0x07, 0x91, 0xC6, 0x22, 0x0F, 0x8E, 0xB3, 0x79, + 0xF8, 0x6E, 0x39, 0xDE, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x30, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x21, 0xA6, 0xC8, 0xF0, 0xA9, 0xF7, 0x0B, + 0x07, 0x3B, 0x34, 0x61, 0x0F, 0x56, 0x08, 0xF5, + 0xF8, 0xA3, 0x24, 0xD7, 0x08, 0x58, 0xFE, 0x57, + 0xF8, 0xB7, 0x23, 0xC8, 0x01, 0xF4, 0x51, 0x2E, + 0x07, 0x48, 0xDC, 0x38, 0xFD, 0xB2, 0xB0, 0x7B, + 0x0A, 0x8B, 0x89, 0x0F, 0xFA, 0xBE, 0x92, 0xE5, + 0xFE, 0xEA, 0x2A, 0xF4, 0x05, 0x41, 0x6D, 0x1B, + 0xFE, 0x8A, 0x4B, 0xFE, 0x09, 0x6F, 0x71, 0xB3, + 0xF4, 0xC9, 0x2E, 0xBA, 0x02, 0xE0, 0x4E, 0xFB, + 0x0B, 0x36, 0xD1, 0x46, 0xFB, 0xB0, 0x3F, 0x52, + 0x07, 0x86, 0xC1, 0xF0, 0xF3, 0x50, 0x29, 0xD7, + 0x05, 0x3A, 0xF8, 0x0F, 0x0C, 0xAF, 0xD6, 0x29, + 0xFB, 0x3E, 0x46, 0x00, 0x08, 0x17, 0x5D, 0x4C, + 0xF0, 0xBC, 0xDB, 0x13, 0x07, 0x34, 0x29, 0xCB, + 0x0F, 0x43, 0x24, 0xED, 0xF8, 0xB4, 0x78, 0xEA, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x03); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xFC, 0xDB, 0x0F, 0xF0, 0x3A, 0xC4, 0xBE, + 0x07, 0xC9, 0x51, 0x50, 0x0F, 0xC5, 0x3B, 0x42, + 0xF8, 0x39, 0xD3, 0xA1, 0x07, 0xFC, 0x38, 0xBF, + 0xF0, 0x47, 0x14, 0xF2, 0x07, 0xBE, 0x4A, 0x80, + 0x0F, 0xB8, 0xEB, 0x0E, 0xF8, 0x45, 0x7C, 0xC1, + 0x07, 0xEB, 0xF6, 0xEF, 0xF1, 0x08, 0x7E, 0x56, + 0x07, 0x17, 0x63, 0xC3, 0x0E, 0xF7, 0x81, 0xAA, + 0xF8, 0xFC, 0xA5, 0x4E, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xD1, 0x27, 0x3E, + 0xF0, 0x5D, 0xB1, 0x85, 0x07, 0xD1, 0x27, 0x3E, + 0x0F, 0xA1, 0x3C, 0x1E, 0xF8, 0x5C, 0x9F, 0x28, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x04); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xD1, 0x27, 0x3E, 0xF0, 0x5D, 0xB1, 0x85, + 0x07, 0xD1, 0x27, 0x3E, 0x0F, 0xA1, 0x3C, 0x1E, + 0xF8, 0x5C, 0x9F, 0x28, 0x08, 0x00, 0x00, 0x00, + 0xF0, 0x71, 0x4C, 0x87, 0x07, 0x91, 0xC6, 0x22, + 0x0F, 0x8E, 0xB3, 0x79, 0xF8, 0x6E, 0x39, 0xDE, + 0x08, 0x21, 0xA6, 0xC8, 0xF0, 0xA9, 0xF7, 0x0B, + 0x07, 0x3B, 0x34, 0x61, 0x0F, 0x56, 0x08, 0xF5, + 0xF8, 0xA3, 0x24, 0xD7, 0x08, 0x58, 0xFE, 0x57, + 0xF8, 0xB7, 0x23, 0xC8, 0x01, 0xF4, 0x51, 0x2E, + 0x07, 0x48, 0xDC, 0x38, 0xFD, 0xB2, 0xB0, 0x7B, + 0x0A, 0x8B, 0x89, 0x0F, 0xFA, 0xBE, 0x92, 0xE5, + 0xFE, 0xEA, 0x2A, 0xF4, 0x05, 0x41, 0x6D, 0x1B, + 0xFE, 0x8A, 0x4B, 0xFE, 0x09, 0x6F, 0x71, 0xB3, + 0xF4, 0xC9, 0x2E, 0xBA, 0x02, 0xE0, 0x4E, 0xFB, + 0x0B, 0x36, 0xD1, 0x46, 0xFB, 0xB0, 0x3F, 0x52, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x05); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0x86, 0xC1, 0xF0, 0xF3, 0x50, 0x29, 0xD7, + 0x05, 0x3A, 0xF8, 0x0F, 0x0C, 0xAF, 0xD6, 0x29, + 0xFB, 0x3E, 0x46, 0x00, 0x08, 0x17, 0x5D, 0x4C, + 0xF0, 0xBC, 0xDB, 0x13, 0x07, 0x34, 0x29, 0xCB, + 0x0F, 0x43, 0x24, 0xED, 0xF8, 0xB4, 0x78, 0xEA, + 0x07, 0xFB, 0x25, 0x84, 0xF0, 0x49, 0xA3, 0xCE, + 0x07, 0xC7, 0xA6, 0xCB, 0x0F, 0xB6, 0x5C, 0x32, + 0xF8, 0x3D, 0x33, 0xB1, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x06); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x86, 0x43, 0x99, 0xFF, 0x02, 0xE6, 0x50, + 0x00, 0x77, 0xAC, 0xFD, 0x0F, 0xD7, 0xE6, 0xBF, + 0xF8, 0x27, 0x42, 0x5B + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF4, 0x49, 0x81, + 0xFF, 0xE8, 0x93, 0x02, 0xFF, 0xF4, 0x49, 0x81, + 0x0D, 0x94, 0x7A, 0x64, 0xFA, 0x3C, 0xAB, 0xA1, + 0x06, 0xD5, 0xF3, 0xB1, 0xF2, 0x54, 0x18, 0x9F, + 0x06, 0xD5, 0xF3, 0xB1, 0x0D, 0x94, 0x7A, 0x64, + 0xFA, 0x3C, 0xAB, 0xA1, 0x00, 0x00, 0x38, 0xE4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xD5, 0x55, 0x55, 0xF8, 0x2A, 0x71, 0xC7, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x30, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x60, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x62, 0x09); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4C, 0x30); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x03); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x78, 0x80); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x60, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x64, 0x02); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4E, 0xBB); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4F, 0xB0); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x03); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x78, 0x80); + if (res < 0) + return res; + + return 0; +} diff --git a/src/mainboard/system76/bonw14/tas5825m-sub.c b/src/mainboard/system76/bonw14/tas5825m-sub.c new file mode 100644 index 00000000000..28987d9be20 --- /dev/null +++ b/src/mainboard/system76/bonw14/tas5825m-sub.c @@ -0,0 +1,1240 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +static int tas5825m_setup_sub(struct device *dev) +{ + int res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x01, 0x11); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x46, 0x11); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x02, 0x04); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x53, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x54, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x29, 0x7C); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x29, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x12); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x48, 0x0C); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x64); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0xFE, 0x00, 0x40, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x50, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x93, 0x00, 0xFC, 0x00, 0x00, + 0x8F, 0x00, 0xFF, 0xEF, 0x84, 0x49, 0x03, 0x27, + 0x84, 0x02, 0x04, 0x06, 0x02, 0x60, 0x00, 0x01, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0x70, 0x00, 0x06, 0x02, 0x78, 0x00, 0x05, + 0x02, 0x68, 0x00, 0x02, 0x02, 0x28, 0x03, 0x4D, + 0x84, 0x2A, 0x04, 0x00, 0xE2, 0x57, 0x91, 0x9F, + 0x84, 0x82, 0x20, 0xE0, 0x84, 0x82, 0x04, 0x01, + 0xF0, 0x1C, 0x31, 0xA0, 0xF0, 0x1C, 0x31, 0xA1, + 0xF0, 0x1C, 0x31, 0xA2, 0xF0, 0x1F, 0x31, 0xA3, + 0xE4, 0x00, 0x11, 0xA6, 0x80, 0x27, 0x80, 0xE1, + 0xF4, 0x00, 0x11, 0xA4, 0xF4, 0x1D, 0x31, 0xA5, + 0xF4, 0x1C, 0x31, 0xA7, 0xF4, 0x1F, 0x31, 0xA8, + 0x02, 0x78, 0x00, 0x03, 0xE2, 0x68, 0xF1, 0xC3, + 0x80, 0x67, 0x80, 0xE9, 0x84, 0x4B, 0x03, 0x27, + 0x02, 0x70, 0x00, 0x04, 0x84, 0x41, 0x03, 0x37, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x00, 0x11, 0xA9, + 0x84, 0x82, 0x00, 0xE0, 0x8E, 0xFC, 0x04, 0x10, + 0xF0, 0x1C, 0x11, 0xAA, 0xF0, 0x1C, 0x11, 0xAB, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x03); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xF0, 0x1C, 0x11, 0xAC, 0xF0, 0x1F, 0x11, 0xAD, + 0x86, 0xA1, 0x01, 0xC2, 0x80, 0x27, 0x80, 0xE8, + 0x60, 0x00, 0x00, 0x00, 0x84, 0x43, 0x03, 0x37, + 0x80, 0x00, 0x00, 0x81, 0x0D, 0x00, 0x10, 0x20, + 0x84, 0x51, 0x03, 0x3E, 0x08, 0x44, 0x26, 0x30, + 0x84, 0xC3, 0x03, 0x47, 0x84, 0xC2, 0x40, 0xE0, + 0x8C, 0xFF, 0x03, 0x23, 0xE0, 0x10, 0x11, 0xB3, + 0xF0, 0x1C, 0x51, 0xB4, 0xF0, 0x1C, 0x51, 0xB5, + 0xF0, 0x1C, 0x51, 0xB6, 0xF0, 0x1F, 0x51, 0xB7, + 0x86, 0xA1, 0x01, 0xC6, 0x80, 0x27, 0x80, 0xEA, + 0x84, 0x53, 0x03, 0x3E, 0x84, 0x82, 0x04, 0x05, + 0x84, 0x51, 0x03, 0x75, 0xE2, 0x6B, 0xC0, 0x00, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x80, 0x31, 0xB8, + 0x84, 0x82, 0x40, 0xE0, 0xF0, 0x1C, 0x51, 0xB9, + 0xF0, 0x1C, 0x51, 0xBA, 0xF0, 0x1C, 0x51, 0xBB, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x04); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xF0, 0x1F, 0x51, 0xBC, 0x86, 0xA1, 0x01, 0xC5, + 0x80, 0x27, 0x80, 0xEA, 0x60, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x81, 0x84, 0xA1, 0x03, 0x4F, + 0xE0, 0x80, 0xA0, 0x00, 0x01, 0x07, 0x11, 0x20, + 0x08, 0x44, 0x26, 0x30, 0x08, 0x00, 0x98, 0x4A, + 0x84, 0x53, 0x03, 0x75, 0x08, 0x00, 0x30, 0x48, + 0x02, 0xCA, 0x00, 0x01, 0x08, 0x60, 0x26, 0x32, + 0x84, 0x51, 0x03, 0x45, 0xE4, 0x10, 0x40, 0x00, + 0x80, 0x40, 0xC0, 0x82, 0x84, 0xC2, 0x40, 0xE0, + 0x84, 0xC3, 0x03, 0x5E, 0x08, 0x00, 0x50, 0x48, + 0xE0, 0x10, 0x11, 0xBD, 0x02, 0xC2, 0x00, 0x02, + 0x08, 0x60, 0x06, 0x12, 0x84, 0xD3, 0x03, 0x4F, + 0xF0, 0x1C, 0x51, 0xBE, 0xF0, 0x1C, 0x51, 0xBF, + 0xF0, 0x1C, 0x51, 0xC0, 0xF0, 0x1F, 0x51, 0xC1, + 0x84, 0xA1, 0x03, 0x65, 0x80, 0x27, 0x80, 0xEA, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x05); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x83, + 0x08, 0x00, 0x98, 0x6B, 0x08, 0x00, 0x30, 0x68, + 0x84, 0x53, 0x03, 0x45, 0x08, 0x60, 0x26, 0x33, + 0x84, 0x51, 0x03, 0x25, 0xE4, 0x10, 0x60, 0x00, + 0x80, 0x40, 0xC0, 0x81, 0x02, 0x70, 0x00, 0x7F, + 0x08, 0x00, 0x50, 0x28, 0x08, 0x60, 0x06, 0x11, + 0x84, 0xCB, 0x03, 0x65, 0xE0, 0x10, 0x51, 0xC4, + 0x84, 0x80, 0x41, 0x00, 0x02, 0xA3, 0x00, 0x10, + 0xE4, 0x00, 0x00, 0x00, 0x84, 0xD0, 0x04, 0x01, + 0x84, 0xA2, 0x04, 0x03, 0x84, 0xD2, 0x50, 0x01, + 0x84, 0x53, 0x03, 0x25, 0x80, 0x00, 0xC4, 0x04, + 0x8F, 0x30, 0x00, 0x00, 0x88, 0x67, 0x03, 0x00, + 0xE4, 0x00, 0x11, 0x9B, 0xEE, 0x64, 0x60, 0x00, + 0x02, 0xD3, 0x00, 0x10, 0x88, 0x47, 0x00, 0x80, + 0x10, 0x00, 0x18, 0x02, 0x86, 0xC1, 0x01, 0x9D, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x06); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x10, 0x31, 0xC7, 0x86, 0xC9, 0x01, 0x9E, + 0x80, 0x00, 0xC4, 0x02, 0x02, 0x50, 0x01, 0x9C, + 0x00, 0xFF, 0x21, 0x65, 0x00, 0xFC, 0x00, 0x00, + 0x02, 0x60, 0x00, 0x01, 0x02, 0x70, 0x00, 0x04, + 0x84, 0xC8, 0x04, 0x10, 0x84, 0x41, 0x03, 0x67, + 0x84, 0x51, 0x03, 0x6D, 0x84, 0xC0, 0x04, 0x02, + 0x04, 0x80, 0x91, 0x20, 0x08, 0x60, 0x26, 0x30, + 0x02, 0x78, 0x00, 0x03, 0x02, 0x68, 0x00, 0x02, + 0x0D, 0x00, 0x10, 0x10, 0x08, 0x60, 0x06, 0x12, + 0x84, 0x49, 0x03, 0x2F, 0xE0, 0x80, 0x71, 0xA9, + 0x02, 0x28, 0x03, 0x55, 0x84, 0x82, 0x00, 0xE0, + 0x84, 0x2A, 0x04, 0x00, 0xF0, 0x1C, 0x11, 0xAA, + 0xF0, 0x1C, 0x11, 0xAB, 0xF0, 0x1C, 0x11, 0xAC, + 0xF0, 0x1F, 0x11, 0xAD, 0x86, 0xA1, 0x01, 0xAE, + 0x80, 0x27, 0x80, 0xE8, 0x84, 0x82, 0x04, 0x07, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x07); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x80, 0x60, 0x00, 0x84, 0x82, 0x40, 0xE0, + 0x84, 0x43, 0x03, 0x67, 0xF0, 0x1C, 0x51, 0xAF, + 0xF0, 0x1C, 0x51, 0xB0, 0xF0, 0x1C, 0x51, 0xB1, + 0xF0, 0x1F, 0x51, 0xB2, 0x02, 0x78, 0x00, 0x05, + 0x80, 0x27, 0x80, 0xEA, 0x84, 0x82, 0x04, 0x08, + 0x02, 0x70, 0x00, 0x06, 0x84, 0x53, 0x03, 0x6D, + 0x84, 0x80, 0x04, 0x07, 0xE0, 0x00, 0x00, 0x82, + 0xF0, 0x81, 0x00, 0x80, 0x80, 0x07, 0x12, 0xBC, + 0x86, 0xA1, 0x01, 0x9F, 0xE2, 0x57, 0xA0, 0x00, + 0x84, 0x82, 0x04, 0x09, 0x84, 0x82, 0x20, 0xE0, + 0xF0, 0x1C, 0x31, 0xA0, 0xF0, 0x1C, 0x31, 0xA1, + 0xF0, 0x1C, 0x31, 0xA2, 0xF0, 0x1F, 0x31, 0xA3, + 0xE4, 0x00, 0x11, 0xA6, 0x80, 0x27, 0x80, 0xE1, + 0xF4, 0x00, 0x11, 0xA4, 0xF4, 0x1D, 0x31, 0xA5, + 0xF4, 0x1C, 0x31, 0xA7, 0xF4, 0x1F, 0x31, 0xA8, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x08); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0x78, 0x00, 0x03, 0xE2, 0x6A, 0xF1, 0xC3, + 0x80, 0x67, 0x80, 0xE9, 0x84, 0x4B, 0x03, 0x2F, + 0x02, 0x70, 0x00, 0x04, 0x84, 0x59, 0x03, 0x3D, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x00, 0x11, 0xA9, + 0x84, 0x82, 0x60, 0xE0, 0x8E, 0xFC, 0x04, 0x10, + 0xF0, 0x1C, 0x71, 0xAA, 0xF0, 0x1C, 0x71, 0xAB, + 0xF0, 0x1C, 0x71, 0xAC, 0xF0, 0x1F, 0x71, 0xAD, + 0x86, 0xA1, 0x01, 0xC2, 0x80, 0x27, 0x80, 0xEB, + 0x60, 0x00, 0x00, 0x00, 0x84, 0x5B, 0x03, 0x3D, + 0x80, 0x00, 0x00, 0x81, 0x0D, 0x00, 0x10, 0x20, + 0x84, 0x59, 0x03, 0x3F, 0x08, 0x44, 0x26, 0x30, + 0x84, 0xC3, 0x03, 0x57, 0x84, 0xC2, 0x60, 0xE0, + 0xE0, 0x10, 0x11, 0xB3, 0xF0, 0x1C, 0x71, 0xB4, + 0xF0, 0x1C, 0x71, 0xB5, 0xF0, 0x1C, 0x71, 0xB6, + 0xF0, 0x1F, 0x71, 0xB7, 0x86, 0xA1, 0x01, 0xC6, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x09); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x80, 0x27, 0x80, 0xEB, 0x84, 0x5B, 0x03, 0x3F, + 0x84, 0x82, 0x04, 0x0D, 0x84, 0x41, 0x03, 0x76, + 0xE2, 0x6B, 0xE0, 0x00, 0x80, 0x07, 0x00, 0x80, + 0xE0, 0x81, 0x31, 0xB8, 0x84, 0x82, 0x00, 0xE0, + 0xF0, 0x1C, 0x11, 0xB9, 0xF0, 0x1C, 0x11, 0xBA, + 0xF0, 0x1C, 0x11, 0xBB, 0xF0, 0x1F, 0x11, 0xBC, + 0x86, 0xA1, 0x01, 0xC5, 0x80, 0x27, 0x80, 0xE8, + 0x60, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x81, + 0x84, 0xA1, 0x03, 0x5D, 0xE0, 0x81, 0xA0, 0x00, + 0x01, 0x07, 0x11, 0x20, 0x08, 0x44, 0x26, 0x30, + 0x08, 0x00, 0x98, 0x4A, 0x84, 0x43, 0x03, 0x76, + 0x08, 0x00, 0x30, 0x48, 0x02, 0xCA, 0x00, 0x01, + 0x08, 0x60, 0x26, 0x32, 0x84, 0x41, 0x03, 0x46, + 0xE4, 0x10, 0x40, 0x00, 0x80, 0x40, 0xC0, 0x82, + 0x84, 0xC2, 0x00, 0xE0, 0x84, 0xC3, 0x03, 0x5F, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0A); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x50, 0x48, 0xE0, 0x10, 0x11, 0xBD, + 0x02, 0xC2, 0x00, 0x02, 0x08, 0x60, 0x06, 0x12, + 0x84, 0xD3, 0x03, 0x5D, 0xF0, 0x1C, 0x11, 0xBE, + 0xF0, 0x1C, 0x11, 0xBF, 0xF0, 0x1C, 0x11, 0xC0, + 0xF0, 0x1F, 0x11, 0xC1, 0x84, 0xA1, 0x03, 0x66, + 0x80, 0x27, 0x80, 0xE8, 0xE0, 0x00, 0x00, 0x00, + 0x80, 0x07, 0x00, 0x83, 0x08, 0x00, 0x98, 0x6B, + 0x08, 0x00, 0x30, 0x68, 0x84, 0x43, 0x03, 0x46, + 0x08, 0x60, 0x26, 0x33, 0x84, 0x51, 0x03, 0x26, + 0xE4, 0x10, 0x60, 0x00, 0x80, 0x40, 0xC0, 0x81, + 0x02, 0x70, 0x00, 0x7F, 0x08, 0x00, 0x50, 0x28, + 0x08, 0x60, 0x06, 0x11, 0x8C, 0xFF, 0x03, 0x24, + 0x84, 0xCB, 0x03, 0x66, 0xE0, 0x10, 0x51, 0xC4, + 0x84, 0x80, 0x41, 0x00, 0x02, 0xA3, 0x00, 0x10, + 0xE4, 0x00, 0x00, 0x00, 0x84, 0xD0, 0x04, 0x09, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x84, 0xA2, 0x04, 0x0B, 0x84, 0xD2, 0x50, 0x01, + 0x84, 0x53, 0x03, 0x26, 0x80, 0x00, 0xC4, 0x0C, + 0x8F, 0x30, 0x00, 0x00, 0x88, 0x67, 0x03, 0x00, + 0xE4, 0x00, 0x11, 0x9B, 0xEE, 0x64, 0x80, 0x00, + 0x02, 0xD3, 0x00, 0x10, 0x88, 0x47, 0x00, 0x80, + 0x10, 0x00, 0x18, 0x02, 0x86, 0xC1, 0x01, 0x9D, + 0xE0, 0x10, 0x31, 0xC7, 0x86, 0xC9, 0x01, 0x9E, + 0x80, 0x00, 0xC4, 0x0A, 0x02, 0x50, 0x01, 0x9C, + 0x00, 0xFF, 0x21, 0x65, 0x00, 0xFC, 0x00, 0x00, + 0x02, 0x70, 0x00, 0x04, 0x02, 0x68, 0x00, 0x01, + 0x02, 0x60, 0x00, 0x03, 0x02, 0x78, 0x00, 0x02, + 0x84, 0x49, 0x03, 0x6E, 0x84, 0x41, 0x03, 0x6F, + 0x84, 0xC8, 0x04, 0x10, 0x84, 0xC0, 0x04, 0x0A, + 0x04, 0x81, 0x91, 0x20, 0x08, 0x60, 0x26, 0x30, + 0x0D, 0x00, 0x10, 0x10, 0x08, 0x60, 0x06, 0x12, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x84, 0x00, 0x04, 0x06, 0xE0, 0x81, 0x71, 0xA9, + 0x84, 0x82, 0x20, 0xE8, 0xF0, 0x1D, 0x31, 0xAA, + 0xF0, 0x1D, 0x31, 0xAB, 0xF0, 0x1D, 0x31, 0xAC, + 0xF0, 0x1C, 0x31, 0xAD, 0x86, 0xA1, 0x01, 0xAE, + 0x80, 0x27, 0x80, 0xF9, 0x84, 0x82, 0x04, 0x0E, + 0xE0, 0x81, 0x60, 0x00, 0x84, 0x82, 0x00, 0xE8, + 0x84, 0x4B, 0x03, 0x6E, 0xF0, 0x1D, 0x11, 0xAF, + 0xF0, 0x1D, 0x11, 0xB0, 0xF0, 0x1D, 0x11, 0xB1, + 0xF0, 0x1C, 0x11, 0xB2, 0x02, 0xA3, 0x00, 0x1A, + 0x80, 0x27, 0x80, 0xF8, 0x84, 0x82, 0x04, 0x0F, + 0xE0, 0x81, 0xC0, 0x00, 0xF0, 0x81, 0xE0, 0x80, + 0x84, 0x43, 0x03, 0x6F, 0x80, 0x07, 0x12, 0xBD, + 0x02, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0x50, 0x00, + 0x8F, 0x00, 0x00, 0x11, 0x8F, 0x00, 0xFF, 0xFF, + 0x84, 0x58, 0x04, 0x01, 0x84, 0xC2, 0x04, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0xC2, 0x60, 0x00, 0x84, 0xA0, 0x61, 0x00, + 0xE0, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x40, 0x40, 0xA0, 0x00, 0x80, 0x00, 0xC0, 0x82, + 0x08, 0xFC, 0x48, 0x3A, 0x08, 0xFC, 0x18, 0x50, + 0x00, 0xFC, 0x00, 0x00, 0xE0, 0x10, 0x00, 0x00, + 0x86, 0xA0, 0x41, 0x00, 0x40, 0x47, 0x20, 0x00, + 0x80, 0x00, 0xC0, 0x83, 0x04, 0xE0, 0x3D, 0x1E, + 0x04, 0x80, 0x11, 0xE0, 0x08, 0x44, 0x26, 0x33, + 0x02, 0xCB, 0x00, 0x10, 0xE0, 0x10, 0x40, 0x83, + 0x08, 0x00, 0x28, 0x21, 0x84, 0xCA, 0x61, 0x00, + 0x80, 0x07, 0x00, 0x81, 0x0C, 0xE0, 0x2C, 0x09, + 0x84, 0xCA, 0x21, 0x00, 0x00, 0xFC, 0x50, 0x00, + 0x8F, 0x00, 0x00, 0x01 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x18); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x30, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x03, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x1C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x3C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x40, 0x00, 0x00, 0x03, 0x48, + 0x00, 0x00, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x54, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x58, 0x00, 0x00, 0x03, 0x60, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x74, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x1C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x3C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x0C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x70, 0x00, 0x00, 0x03, 0x78, + 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x24, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0xFD, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x04, 0x88, 0x00, 0x00, 0x04, 0x90, + }; + res = tas5825m_write_block_at(dev, 0x44, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x8C); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0xA7, 0x26, 0x4A, 0x7F, 0xFF, 0xFF, 0xFF, + 0x00, 0x20, 0xC4, 0x9C, 0x00, 0x20, 0xC4, 0x9C, + 0x00, 0x00, 0x68, 0xDB, 0x00, 0x00, 0xD1, 0xB7, + 0x00, 0x00, 0x68, 0xDB, 0x0F, 0xA4, 0xA8, 0xC1, + 0xF8, 0x59, 0x7F, 0x63 + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xB7, 0xE9, + 0x00, 0x5F, 0x6F, 0xD2, 0x00, 0x2F, 0xB7, 0xE9, + 0x0B, 0x1E, 0x4F, 0x76, 0xFC, 0x23, 0x05, 0x54, + 0xFA, 0x41, 0x20, 0x5C, 0x0B, 0x7D, 0xBF, 0x48, + 0xFA, 0x41, 0x20, 0x5C, 0x0B, 0x1E, 0x4F, 0x76, + 0xFC, 0x23, 0x05, 0x54, 0x00, 0x04, 0x81, 0x6F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x3F, 0xE5, 0xC9, 0xF8, 0xBB, 0x98, 0xC8, + 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x81, 0x6F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x3F, 0xE5, 0xC9, 0xF8, 0xBB, 0x98, 0xC8, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x10); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x89, 0xA0, 0x27, 0x7F, 0xEC, 0x56, 0xD5, + 0x7F, 0xFC, 0xB9, 0x23, 0x00, 0x89, 0xA0, 0x27, + 0x7F, 0xEC, 0x56, 0xD5, 0x7F, 0xFC, 0xB9, 0x23, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x40, 0x00); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x11, 0xFF + }; + res = tas5825m_write_block_at(dev, 0x7D, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x51, 0x05); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x19, 0xDF); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x8C); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x71, 0x94, 0x9A + }; + res = tas5825m_write_block_at(dev, 0x2C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0A); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x64, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x5A, 0x84, + 0x00, 0x1E, 0x5A, 0x84, 0x00, 0x40, 0x26, 0xE7, + 0x00, 0x40, 0x26, 0xE7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x57, 0x62, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x28, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x03, 0x69, 0xC5, 0x00, 0xEB, 0x8F, 0xA8, + 0x00, 0x22, 0x1D, 0x95, 0x00, 0x03, 0x69, 0xC5, + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x7F, 0xF9, 0x2C, 0x60, 0x01, 0xEB, 0x55, 0xAC, + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x07); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x64, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0xAA); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x01, 0x0A, 0x7A, 0x00, 0x02, 0x14, 0xF5, + 0x00, 0x01, 0x0A, 0x7A, 0x0F, 0x7B, 0xDB, 0x58, + 0xF8, 0x7F, 0xFA, 0xBE, 0x00, 0x01, 0x0A, 0x7A, + 0x00, 0x02, 0x14, 0xF5, 0x00, 0x01, 0x0A, 0x7A, + 0x0F, 0x7B, 0xDB, 0x58, 0xF8, 0x7F, 0xFA, 0xBE, + 0x07, 0xFD, 0xF9, 0x62, 0xF0, 0x25, 0x7A, 0x1B, + 0x07, 0xDC, 0xC4, 0xC6, 0x0F, 0xDA, 0x85, 0xE5, + 0xF8, 0x25, 0x41, 0xD8, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x30, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xF7, 0xFF, 0xB5, 0xF0, 0x4F, 0x8C, 0x33, + 0x07, 0xBA, 0x32, 0x37, 0x0F, 0xB0, 0x73, 0xCD, + 0xF8, 0x4D, 0xCE, 0x15, 0x07, 0xFA, 0x6B, 0x45, + 0xF0, 0x68, 0xC7, 0x1B, 0x07, 0x9E, 0xF0, 0xFB, + 0x0F, 0x97, 0x38, 0xE5, 0xF8, 0x66, 0xA3, 0xC0, + 0x07, 0xFE, 0x8C, 0x9C, 0xF0, 0x34, 0xCF, 0xDE, + 0x07, 0xCD, 0x94, 0xFF, 0x0F, 0xCB, 0x30, 0x22, + 0xF8, 0x33, 0xDE, 0x65, 0x07, 0xFE, 0x73, 0xDB, + 0xF0, 0x38, 0x93, 0x60, 0x07, 0xCA, 0x38, 0xAE, + 0x0F, 0xC7, 0x6C, 0xA0, 0xF8, 0x37, 0x53, 0x77, + 0x07, 0xF8, 0xC1, 0xBE, 0xF0, 0x88, 0xCB, 0x7D, + 0x07, 0x82, 0x08, 0xA9, 0x0F, 0x77, 0x34, 0x83, + 0xF8, 0x85, 0x35, 0x99, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x03); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xEE, 0xC6, 0xB4, + 0xF0, 0x22, 0x72, 0x97, 0x07, 0xEE, 0xC6, 0xB4, + 0x0F, 0xDD, 0x77, 0x9C, 0xF8, 0x22, 0x5C, 0xCB, + 0x07, 0xF4, 0x93, 0x76, 0xF0, 0x34, 0x67, 0xAD, + 0x07, 0xD7, 0xAE, 0x5A, 0x0F, 0xCB, 0x98, 0x53, + 0xF8, 0x33, 0xBE, 0x30, 0x08, 0x13, 0x15, 0xCB, + 0xF0, 0x0E, 0xB9, 0x1C, 0x07, 0xDE, 0xDC, 0x2A, + 0x0F, 0xF1, 0x86, 0x85, 0xF8, 0x0E, 0x4D, 0xAB, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x04); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x05); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xEE, 0xC6, 0xB4, 0xF0, 0x22, 0x72, 0x97, + 0x07, 0xEE, 0xC6, 0xB4, 0x0F, 0xDD, 0x77, 0x9C, + 0xF8, 0x22, 0x5C, 0xCB, 0x07, 0xF4, 0x93, 0x76, + 0xF0, 0x34, 0x67, 0xAD, 0x07, 0xD7, 0xAE, 0x5A, + 0x0F, 0xCB, 0x98, 0x53, 0xF8, 0x33, 0xBE, 0x30, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x06); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x13, 0x15, 0xCB, 0xF0, 0x0E, 0xB9, 0x1C, + 0x07, 0xDE, 0xDC, 0x2A, 0x0F, 0xF1, 0x86, 0x85, + 0xF8, 0x0E, 0x4D, 0xAB, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x85, 0xC0, 0x8D, 0xFF, 0x02, 0x2B, 0x75, + 0x00, 0x78, 0xBE, 0x6E, 0x0F, 0xE2, 0x46, 0xF6, + 0xF8, 0x1D, 0x0E, 0x9A + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0xAA, 0xC3, + 0xFF, 0xFD, 0x55, 0x85, 0xFF, 0xFE, 0xAA, 0xC3, + 0x0F, 0x2F, 0x01, 0x62, 0xF8, 0xCB, 0xA9, 0xA8, + 0x07, 0x98, 0xD5, 0xEF, 0xF0, 0xCE, 0x54, 0x23, + 0x07, 0x98, 0xD5, 0xEF, 0x0F, 0x2F, 0x01, 0x62, + 0xF8, 0xCB, 0xA9, 0xA8, 0x00, 0x00, 0x38, 0xE4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xD5, 0x55, 0x55, 0xF8, 0x2A, 0x71, 0xC7, + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x30, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x60, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x62, 0x09); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4C, 0x30); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x03); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x78, 0x80); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x60, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x64, 0x02); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4E, 0xBB); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4F, 0xB0); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x03); + if (res < 0) + return res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x78, 0x80); + if (res < 0) + return res; + + return 0; +} diff --git a/src/mainboard/system76/bonw14/tas5825m.c b/src/mainboard/system76/bonw14/tas5825m.c new file mode 100644 index 00000000000..95680fae92d --- /dev/null +++ b/src/mainboard/system76/bonw14/tas5825m.c @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +#include "tas5825m-normal.c" +#include "tas5825m-sub.c" + +int tas5825m_setup(struct device *dev, int id) +{ + if (id == 0) + return tas5825m_setup_normal(dev); + if (id == 1) + return tas5825m_setup_sub(dev); + return -1; +} diff --git a/src/mainboard/system76/gaze15/Kconfig b/src/mainboard/system76/gaze15/Kconfig index ea0ef2ded75..6a3cd7adc94 100644 --- a/src/mainboard/system76/gaze15/Kconfig +++ b/src/mainboard/system76/gaze15/Kconfig @@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_16384 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA select DRIVERS_I2C_HID select EC_SYSTEM76_EC select EC_SYSTEM76_EC_DGPU diff --git a/src/mainboard/system76/gaze15/Makefile.mk b/src/mainboard/system76/gaze15/Makefile.mk index 72f13667d31..ab7df6c275e 100644 --- a/src/mainboard/system76/gaze15/Makefile.mk +++ b/src/mainboard/system76/gaze15/Makefile.mk @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include bootblock-y += bootblock.c bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c diff --git a/src/mainboard/system76/gaze15/acpi/mainboard.asl b/src/mainboard/system76/gaze15/acpi/mainboard.asl index b235437c25d..610cdd12bad 100644 --- a/src/mainboard/system76/gaze15/acpi/mainboard.asl +++ b/src/mainboard/system76/gaze15/acpi/mainboard.asl @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include + #define EC_GPE_SCI 0x03 /* GPP_K3 */ #define EC_GPE_SWI 0x06 /* GPP_K6 */ #include @@ -8,6 +10,10 @@ Scope (\_SB) { #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" + Device (PEGP) { + Name (_ADR, CONFIG_DRIVERS_GFX_NVIDIA_BRIDGE << 16) + #include + } } } diff --git a/src/mainboard/system76/gaze15/devicetree.cb b/src/mainboard/system76/gaze15/devicetree.cb index be36abf73f0..e2ea5fda73b 100644 --- a/src/mainboard/system76/gaze15/devicetree.cb +++ b/src/mainboard/system76/gaze15/devicetree.cb @@ -54,6 +54,12 @@ chip soc/intel/cannonlake # PCI Express Graphics #0 x16, Clock 8 (NVIDIA GPU) register "PcieClkSrcUsage[8]" = "0x40" register "PcieClkSrcClkReq[8]" = "8" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller + end end device ref igpu on register "gfx" = "GMA_DEFAULT_PANEL(0)" diff --git a/src/mainboard/system76/gaze15/romstage.c b/src/mainboard/system76/gaze15/romstage.c index 02634ba2ad2..fdb208b88db 100644 --- a/src/mainboard/system76/gaze15/romstage.c +++ b/src/mainboard/system76/gaze15/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include static const struct cnl_mb_cfg memcfg = { .spd[0] = { @@ -20,5 +22,17 @@ static const struct cnl_mb_cfg memcfg = { void mainboard_memory_init_params(FSPM_UPD *memupd) { + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + memupd->FspmConfig.PrimaryDisplay = 0; + cannonlake_memcfg_init(&memupd->FspmConfig, &memcfg); } diff --git a/src/mainboard/system76/gaze15/variants/gaze14/include/variant/gpio.h b/src/mainboard/system76/gaze15/variants/gaze14/include/variant/gpio.h new file mode 100644 index 00000000000..d1647fc437d --- /dev/null +++ b/src/mainboard/system76/gaze15/variants/gaze14/include/variant/gpio.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_K21 +#define DGPU_SSID 0x85501558 + +#ifndef __ACPI__ +void variant_configure_early_gpios(void); +void variant_configure_gpios(void); +#endif + +#endif diff --git a/src/mainboard/system76/gaze15/variants/gaze15/include/variant/gpio.h b/src/mainboard/system76/gaze15/variants/gaze15/include/variant/gpio.h new file mode 100644 index 00000000000..0bfd82ed799 --- /dev/null +++ b/src/mainboard/system76/gaze15/variants/gaze15/include/variant/gpio.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_K21 +#define DGPU_SSID 0x85201558 + +#ifndef __ACPI__ +void variant_configure_early_gpios(void); +void variant_configure_gpios(void); +#endif + +#endif diff --git a/src/mainboard/system76/meer9/Kconfig b/src/mainboard/system76/meer9/Kconfig new file mode 100644 index 00000000000..3c7cb975930 --- /dev/null +++ b/src/mainboard/system76/meer9/Kconfig @@ -0,0 +1,83 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config BOARD_SYSTEM76_MEER9_COMMON + def_bool n + select BOARD_ROMSIZE_KB_32768 + select CRB_TPM + select DRIVERS_GENERIC_CBFS_SERIAL + select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_UART_8250IO + select HAVE_ACPI_RESUME + select HAVE_ACPI_TABLES + select HAVE_CMOS_DEFAULT + select HAVE_INTEL_PTT + select HAVE_OPTION_TABLE + select INTEL_GMA_HAVE_VBT + select MAINBOARD_HAS_TPM2 + select NO_UART_ON_SUPERIO + select PCIEXP_SUPPORT_RESIZABLE_BARS + select SOC_INTEL_COMMON_BLOCK_HDA_VERB + select SOC_INTEL_CRASHLOG + select SOC_INTEL_METEORLAKE + select SPD_READ_BY_WORD + +config BOARD_SYSTEM76_MEER9 + select BOARD_SYSTEM76_MEER9_COMMON + select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES + select SOC_INTEL_METEORLAKE_U_H + +if BOARD_SYSTEM76_MEER9_COMMON + +config MAINBOARD_DIR + default "system76/meer9" + +config VARIANT_DIR + default "meer9" if BOARD_SYSTEM76_MEER9 + +config OVERRIDE_DEVICETREE + default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" + +config MAINBOARD_PART_NUMBER + default "meer9" if BOARD_SYSTEM76_MEER9 + +config MAINBOARD_SMBIOS_PRODUCT_NAME + default "Meerkat" if BOARD_SYSTEM76_MEER9 + +config MAINBOARD_VERSION + default "meer9" if BOARD_SYSTEM76_MEER9 + +config CMOS_DEFAULT_FILE + default "src/mainboard/\$(MAINBOARDDIR)/cmos.default" + +config CONSOLE_POST + default y + +config D3COLD_SUPPORT + default n + +config DIMM_SPD_SIZE + default 1024 + +config FMDFILE + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" + +config ONBOARD_VGA_IS_PRIMARY + default y + +config PCIEXP_DEFAULT_MAX_RESIZABLE_BAR_BITS + default 36 + +config POST_DEVICE + default n + +config TPM_MEASURED_BOOT + default y + +config UART_FOR_CONSOLE + default 0 + +# PM Timer Disabled, saves power +config USE_PM_ACPI_TIMER + default n + +endif diff --git a/src/mainboard/system76/meer9/Kconfig.name b/src/mainboard/system76/meer9/Kconfig.name new file mode 100644 index 00000000000..516503db022 --- /dev/null +++ b/src/mainboard/system76/meer9/Kconfig.name @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config BOARD_SYSTEM76_MEER9 + bool "meer9" diff --git a/src/mainboard/system76/meer9/Makefile.mk b/src/mainboard/system76/meer9/Makefile.mk new file mode 100644 index 00000000000..d687753afad --- /dev/null +++ b/src/mainboard/system76/meer9/Makefile.mk @@ -0,0 +1,13 @@ +## SPDX-License-Identifier: GPL-2.0-only + +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include + +bootblock-y += bootblock.c +bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c + +romstage-y += variants/$(VARIANT_DIR)/romstage.c + +ramstage-y += ramstage.c +ramstage-y += variants/$(VARIANT_DIR)/hda_verb.c +ramstage-y += variants/$(VARIANT_DIR)/gpio.c +ramstage-y += variants/$(VARIANT_DIR)/ramstage.c diff --git a/src/mainboard/system76/meer9/acpi/mainboard.asl b/src/mainboard/system76/meer9/acpi/mainboard.asl new file mode 100644 index 00000000000..99e94438ac4 --- /dev/null +++ b/src/mainboard/system76/meer9/acpi/mainboard.asl @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Scope (\_SB) { + #include "sio.asl" + #include "sleep.asl" + #include "s76.asl" +} diff --git a/src/mainboard/system76/meer9/acpi/s76.asl b/src/mainboard/system76/meer9/acpi/s76.asl new file mode 100644 index 00000000000..12f4ed9f1f2 --- /dev/null +++ b/src/mainboard/system76/meer9/acpi/s76.asl @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +// Notifications: +// 0x80 - hardware backlight toggle +// 0x81 - backlight toggle +// 0x82 - backlight down +// 0x83 - backlight up +// 0x84 - backlight color change +// 0x85 - OLED screen toggle +Device (S76D) { + Name (_HID, "17761776") + Name (_UID, 0) + // Hide the device so that Windows does not warn about a missing driver. + Name (_STA, 0xB) + + OperationRegion (HMIO, SystemIO, 0x295, 0x02) + Field (HMIO, ByteAcc, NoLock, Preserve) { + // Hardware manager index + HMID, 8, + // Hardware manager data + HMDT, 8, + } + + Method (INIT, 0, Serialized) { + Printf ("S76D: INIT") + Return (0) + } + + Method (FINI, 0, Serialized) { + Printf ("S76D: FINI") + Return (0) + } + + // Get Airplane LED + Method (GAPL, 0, Serialized) { + Return (0) + } + + // Set Airplane LED + Method (SAPL, 1, Serialized) {} + + // Get Keyboard Backlight Kind + // 0 - No backlight + // 1 - White backlight + // 2 - RGB backlight + Method (GKBK, 0, Serialized) { + Return (0) + } + + // Get Keyboard Brightness + Method (GKBB, 0, Serialized) { + Return (0) + } + + // Set Keyboard Brightness + Method (SKBB, 1, Serialized) {} + + // Get Keyboard Color + Method (GKBC, 0, Serialized) { + Return (0) + } + + // Set Keyboard Color + Method (SKBC, 1, Serialized) {} + + // Fan names + Method (NFAN, 0, Serialized) { + Return (Package() { + "CPU fan" + }) + } + + // Get fan duty cycle and RPM as a single value + Method (GFAN, 1, Serialized) { + // Set bank 0 + HMID = 0x4E + HMDT = 0x80 + + // Read fan duty cycle + HMID = 0x4B + Local0 = HMDT + + // Read fan RPM (low) + HMID = 0x33 + Local1 = HMDT + + // Read fan RPM (high) + HMID = 0x32 + Local2 = HMDT + + Return ((Local2 << 16) | (Local1 << 8) | Local0) + } + + // Temperature names + Method (NTMP, 0, Serialized) { + Return (Package() { + "CPU temp" + }) + } + + // Get temperature + Method (GTMP, 1, Serialized) { + // Set bank 0 + HMID = 0x4E + HMDT = 0x80 + + // Read temperature + HMID = 0x19 + Local0 = HMDT + + Return (Local0) + } +} diff --git a/src/mainboard/system76/meer9/acpi/sio.asl b/src/mainboard/system76/meer9/acpi/sio.asl new file mode 100644 index 00000000000..4f91a837120 --- /dev/null +++ b/src/mainboard/system76/meer9/acpi/sio.asl @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +Device (SIO) { + Name (_ADR, 0x2E) + OperationRegion (SIOA, SystemIO, 0x2E, 0x02) + Field (SIOA, ByteAcc, NoLock, Preserve) + { + SI2E, 8, + SI2F, 8, + } + IndexField (SI2E, SI2F, ByteAcc, NoLock, Preserve) + { + Offset (0x07), + SLDN, 8, /* Logical Device Number */ + Offset(0xE5), + SRE5, 8, /* Register 0xE5 */ + } + + Method (ENTR, 0, Serialized) { + // Enter config mode + SI2E = 0x87 + SI2E = 0x87 + } + + Method (EXIT, 0, Serialized) { + // Exit config mode + SI2E = 0xAA + } + + Method (PTS, 0, Serialized) { + ENTR() + + // Turn on fading LED + SLDN = 0x15 + SRE5 = 0x43 + + EXIT() + } + + Method (WAK, 0, Serialized) { + ENTR() + + // Turn off fading LED + SLDN = 0x15 + SRE5 = 0x42 + + EXIT() + } +} diff --git a/src/mainboard/system76/meer9/acpi/sleep.asl b/src/mainboard/system76/meer9/acpi/sleep.asl new file mode 100644 index 00000000000..0212e7aeeb8 --- /dev/null +++ b/src/mainboard/system76/meer9/acpi/sleep.asl @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* Method called from _PTS prior to enter sleep state */ +Method (MPTS, 1) { + \_SB.SIO.PTS() +} + +/* Method called from _WAK prior to wakeup */ +Method (MWAK, 1) { + \_SB.SIO.WAK() +} diff --git a/src/mainboard/system76/meer9/board_info.txt b/src/mainboard/system76/meer9/board_info.txt new file mode 100644 index 00000000000..7d87752e22f --- /dev/null +++ b/src/mainboard/system76/meer9/board_info.txt @@ -0,0 +1,6 @@ +Vendor name: System76 +Category: desktop +ROM package: WSON-8 +ROM protocol: SPI +ROM socketed: y +Flashrom support: y diff --git a/src/mainboard/system76/meer9/bootblock.c b/src/mainboard/system76/meer9/bootblock.c new file mode 100644 index 00000000000..86b980bddef --- /dev/null +++ b/src/mainboard/system76/meer9/bootblock.c @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +// nuvoton_pnp_enter_conf_state +static void pnp_enter_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(0x87, port); + outb(0x87, port); +} + +// nuvoton_pnp_exit_conf_state +static void pnp_exit_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(0xaa, port); +} + +static void superio_init(void) +{ + //TODO: use superio driver? + pnp_devfn_t dev = PNP_DEV(0x2E, 0x00); + + printk(BIOS_DEBUG, "entering PNP config mode\n"); + pnp_enter_conf_state(dev); + + printk(BIOS_DEBUG, "configure global PNP\n"); + //TODO: document these + pnp_write_config(dev, 0x1A, 0x88); // Default is 0x03 + pnp_write_config(dev, 0x1B, 0x00); // Default is 0x03 + pnp_write_config(dev, 0x1D, 0x08); // Default is 0x00 + pnp_write_config(dev, 0x2C, 0x03); // Default is 0x0F + pnp_write_config(dev, 0x2F, 0xE4); // Default is 0x74 + + printk(BIOS_DEBUG, "configure GPIO (logical device 7)\n"); + dev = PNP_DEV(0x2E, 0x07); + pnp_set_logical_device(dev); + // Enable GPIO 0, 5, and 6 + pnp_write_config(dev, 0x30, 0x61); // Default is 0x00 + // Set GPIO 00-06 as output, 07 as input + pnp_write_config(dev, 0xE0, 0x80); // Default is 0xFF + // Set GPIO 00-02 and 04-05 high + pnp_write_config(dev, 0xE1, 0x37); // Default is 0x00 + // Set GPIO 53-54 as output, 50-52 and 55-57 as input + pnp_write_config(dev, 0xF8, 0xE7); // Default is 0xFF + // Set GPIO 53-53 high + pnp_write_config(dev, 0xF9, 0x18); // Default is 0x00 + + printk(BIOS_DEBUG, "configure GPIO (logical device 8)\n"); + dev = PNP_DEV(0x2E, 0x08); + pnp_set_logical_device(dev); + // Disable WDT1 + pnp_write_config(dev, 0x30, 0x00); // Default is 0x01 + // GPIO0 multi-function select, set GPIO0 as SUSLED + pnp_write_config(dev, 0xE0, 0x01); // Default is 0x00 + pnp_write_config(dev, 0xE9, 0x00); // Default is 0xFF TODO? + pnp_write_config(dev, 0xEA, 0x00); // Default is 0xFF TODO? + + printk(BIOS_DEBUG, "configure GPIO (logical device 9)\n"); + dev = PNP_DEV(0x2E, 0x09); + pnp_set_logical_device(dev); + // Enable GPIO 8 and 9 + pnp_write_config(dev, 0x30, 0x03); // Default is 0x00 + // GPIO 80-86 set as input, 87 as output + pnp_write_config(dev, 0xF0, 0x7F); // Default is 0xFF + // GPIO 87 set high + pnp_write_config(dev, 0xF1, 0x80); // Default is 0xFF + + printk(BIOS_DEBUG, "configure ACPI (logical device A)\n"); + dev = PNP_DEV(0x2E, 0x0A); + pnp_set_logical_device(dev); + // User-defined resume state after power loss + pnp_write_config(dev, 0xE4, 0x60); // Default is 0x00 + + printk(BIOS_DEBUG, "configure hardware monitor (logical device B)\n"); + dev = PNP_DEV(0x2E, 0x0B); + pnp_set_logical_device(dev); + // Enable hardware monitor + pnp_write_config(dev, 0x30, 0x01); // Default is 0x00 + // Set address base to 0x290 + pnp_write_config(dev, 0x60, 0x02); + pnp_write_config(dev, 0x61, 0x90); + + printk(BIOS_DEBUG, "configure GPIO (logical device F)\n"); + dev = PNP_DEV(0x2E, 0x0F); + pnp_set_logical_device(dev); + // Set GPIO 00, 01, and 07 as open drain, and 2-6 as push-pull + pnp_write_config(dev, 0xE0, 0x83); // Default is 0xFF + // Set GPIO 52-57 as open drain, and 50-51 as push-pull + pnp_write_config(dev, 0xE5, 0xFC); // Default is 0xFF + // Set GPIO 60-62 and 65-67 as open drain, and 63-64 as push-pull + pnp_write_config(dev, 0xE6, 0xE7); // Default is 0xFF + // Set GPIO 80-86 as open drain, and 87 as push-pull + pnp_write_config(dev, 0xE8, 0x7F); // Default is 0xFF + + printk(BIOS_DEBUG, "configure fading LED (logical device 15)\n"); + dev = PNP_DEV(0x2E, 0x15); + pnp_set_logical_device(dev); + // Configure fading LED (divide by 4, frequency 1 Khz, off) + pnp_write_config(dev, 0xE5, 0x42); + + printk(BIOS_DEBUG, "configure deep sleep (logical device 16)\n"); + dev = PNP_DEV(0x2E, 0x16); + pnp_set_logical_device(dev); + // Set deep sleep delay time to 0s + pnp_write_config(dev, 0xE2, 0x00); + + printk(BIOS_DEBUG, "exiting PNP config mode\n"); + pnp_exit_conf_state(dev); +} + +static void hm_write(uint8_t reg, uint8_t value) +{ + outb(reg, 0x295); + outb(value, 0x296); +} + +static void hm_init(void) +{ + // Bank 2 + hm_write(0x4E, 0x82); + + // Enable PECI 3.0 with routine function + hm_write(0x00, 0x85); + + // Enable PECI agent 30 + hm_write(0x02, 0x10); + + // PECI Tbase0 = 110C + hm_write(0x04, 110); + + // Bank 3 + hm_write(0x4E, 0x83); + + // Enable PECI agent 0 mode + hm_write(0x90, 0x01); + + // Bank 1 + hm_write(0x4E, 0x81); + + // CPUFAN T1 = 50C + hm_write(0x70, 50); + // CPUFAN FD1 = 25% = 0x3F + hm_write(0x74, 0x3F); + + // CPUFAN T2 = 75C + hm_write(0x71, 75); + // CPUFAN FD2 = 50% = 0x7F + hm_write(0x75, 0x7F); + + // CPUFAN T3 = 90C + hm_write(0x72, 90); + // CPUFAN FD3 = 75% = 0xBF + hm_write(0x76, 0xBF); + + // CPUFAN T4 = 99C + hm_write(0x73, 99); + // CPUFAN FD4 = 100% = 0xFF + hm_write(0x77, 0xFF); + + // CPUFAN critical temperature = 105C + hm_write(0x2A, 105); + // By default critical duty is 0xFF + + // CPUFAN step up time = 1s + hm_write(0x24, 10); + + // CPUFAN step down time = 0.5s + hm_write(0x25, 5); + + // Use PECI agent 0 as CPUFAN monitoring source + hm_write(0x20, 0x0C); + + // CPUFAN Smart Fan IV mode + hm_write(0x23, 0x40); +} + +void bootblock_mainboard_early_init(void) +{ + mainboard_configure_early_gpios(); + superio_init(); + hm_init(); +} diff --git a/src/mainboard/system76/meer9/cmos.default b/src/mainboard/system76/meer9/cmos.default new file mode 100644 index 00000000000..d2ca53be53c --- /dev/null +++ b/src/mainboard/system76/meer9/cmos.default @@ -0,0 +1,6 @@ +## SPDX-License-Identifier: GPL-2.0-only + +boot_option=Fallback +debug_level=Debug +me_state=Enable +power_on_after_fail=Disable diff --git a/src/mainboard/system76/meer9/cmos.layout b/src/mainboard/system76/meer9/cmos.layout new file mode 100644 index 00000000000..6414d665b6d --- /dev/null +++ b/src/mainboard/system76/meer9/cmos.layout @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: GPL-2.0-only + +entries + +0 384 r 0 reserved_memory + +# RTC_BOOT_BYTE (coreboot hardcoded) +384 1 e 4 boot_option +388 4 h 0 reboot_counter + +# RTC_CLK_ALTCENTURY +400 8 r 0 century + +409 2 e 7 power_on_after_fail +412 4 e 6 debug_level +416 1 e 2 me_state +417 3 h 0 me_state_counter + +# CMOS_VSTART_ramtop +800 80 r 0 ramtop + +984 16 h 0 check_sum + +enumerations + +1 0 Disable +1 1 Enable + +2 0 Enable +2 1 Disable + +4 0 Fallback +4 1 Normal + +6 0 Emergency +6 1 Alert +6 2 Critical +6 3 Error +6 4 Warning +6 5 Notice +6 6 Info +6 7 Debug +6 8 Spew + +7 0 Disable +7 1 Enable +7 2 Keep + +checksums + +checksum 408 799 984 diff --git a/src/mainboard/system76/meer9/devicetree.cb b/src/mainboard/system76/meer9/devicetree.cb new file mode 100644 index 00000000000..b664ef97636 --- /dev/null +++ b/src/mainboard/system76/meer9/devicetree.cb @@ -0,0 +1,56 @@ +chip soc/intel/meteorlake + # Enable Enhanced Intel SpeedStep + register "eist_enable" = "1" + + # Thermal + register "tcc_offset" = "11" # 110C - 11C = 99C + + device cpu_cluster 0 on end + + register "power_limits_config[MTL_P_682_482_CORE]" = "{ + .tdp_pl1_override = 40, + .tdp_pl2_override = 64, + .tdp_pl4 = 120, + }" + + device domain 0 on + device ref system_agent on end + device ref igpu on + # DDIA is HDMI1, DDIB is HDMI2 + register "ddi_ports_config" = "{ + [DDI_PORT_A] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + [DDI_PORT_B] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + }" + end + device ref vpu on end + device ref ioe_shared_sram on end + device ref pmc_shared_sram on end + device ref cnvi_wifi on + register "cnvi_bt_core" = "true" + register "cnvi_bt_audio_offload" = "true" + chip drivers/wifi/generic + register "wake" = "GPE0_PME_B0" + device generic 0 on end + end + end + + device ref heci1 on end + device ref soc_espi on + register "gen1_dec" = "0x007c0281" # Port 0x280 to 0x2FF (hardware monitor) + register "gen2_dec" = "0x000c0081" # Port 0x80 to 0x8F (debug) + end + device ref p2sb on end + device ref hda on + register "pch_hda_sdi_enable[0]" = "1" + register "pch_hda_audio_link_hda_enable" = "1" + register "pch_hda_idisp_codec_enable" = "1" + register "pch_hda_idisp_link_frequency" = "HDA_LINKFREQ_96MHZ" + register "pch_hda_idisp_link_tmode" = "HDA_TMODE_8T" + end + device ref smbus on end + device ref fast_spi on end + end + chip drivers/crb + device mmio 0xfed40000 on end + end +end diff --git a/src/mainboard/starlabs/byte_adl/dsdt.asl b/src/mainboard/system76/meer9/dsdt.asl similarity index 58% rename from src/mainboard/starlabs/byte_adl/dsdt.asl rename to src/mainboard/system76/meer9/dsdt.asl index c0936a74ba9..cf8d58d4345 100644 --- a/src/mainboard/starlabs/byte_adl/dsdt.asl +++ b/src/mainboard/system76/meer9/dsdt.asl @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +//TODO: HACK FOR MISSING MISCCFG_GPIO_PM_CONFIG_BITS +#include + #include DefinitionBlock( "dsdt.aml", @@ -7,7 +10,7 @@ DefinitionBlock( ACPI_DSDT_REV_2, OEM_ID, ACPI_TABLE_CREATOR, - 0x20220930 + 0x20110725 ) { #include @@ -18,24 +21,15 @@ DefinitionBlock( Device (\_SB.PCI0) { #include - #include - #include - - #include + #include + #include } #include - /* Star Labs EC */ - #include - - Scope (\_SB) + Scope (\_SB.PCI0.LPCB) { - /* HID Driver */ - #include - - /* Suspend Methods */ - #include + #include } #include "acpi/mainboard.asl" diff --git a/src/mainboard/system76/meer9/include/mainboard/gpio.h b/src/mainboard/system76/meer9/include/mainboard/gpio.h new file mode 100644 index 00000000000..c6393beebb6 --- /dev/null +++ b/src/mainboard/system76/meer9/include/mainboard/gpio.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef MAINBOARD_GPIO_H +#define MAINBOARD_GPIO_H + +void mainboard_configure_early_gpios(void); +void mainboard_configure_gpios(void); + +#endif diff --git a/src/mainboard/system76/meer9/ramstage.c b/src/mainboard/system76/meer9/ramstage.c new file mode 100644 index 00000000000..c6fca5fcd4a --- /dev/null +++ b/src/mainboard/system76/meer9/ramstage.c @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +static void mainboard_init(void *chip_info) +{ + mainboard_configure_gpios(); + + // The DACC feature resets CMOS and causes a system reset if the + // firmware does not send this message within 10 seconds of power on. + printk(BIOS_DEBUG, "Handling DACC\n"); + do_smbus_write_byte(CONFIG_FIXED_SMBUS_IO_BASE, 0xBA >> 1, 0x0F, 0xAA); +} + +struct chip_operations mainboard_ops = { + .init = mainboard_init, +}; diff --git a/src/mainboard/system76/meer9/variants/meer9/board.fmd b/src/mainboard/system76/meer9/variants/meer9/board.fmd new file mode 100644 index 00000000000..4713b672976 --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/board.fmd @@ -0,0 +1,12 @@ +FLASH 32M { + SI_DESC 16K + SI_ME 10160K + SI_BIOS@16M 16M { + RW_MRC_CACHE 64K + SMMSTORE(PRESERVE) 256K + WP_RO { + FMAP 4K + COREBOOT(CBFS) + } + } +} diff --git a/src/mainboard/system76/meer9/variants/meer9/board_info.txt b/src/mainboard/system76/meer9/variants/meer9/board_info.txt new file mode 100644 index 00000000000..dcb8a8bd1f8 --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/board_info.txt @@ -0,0 +1,2 @@ +Board name: meer9 +Release year: 2024 diff --git a/src/mainboard/system76/meer9/variants/meer9/data.vbt b/src/mainboard/system76/meer9/variants/meer9/data.vbt new file mode 100644 index 00000000000..93276b46fac Binary files /dev/null and b/src/mainboard/system76/meer9/variants/meer9/data.vbt differ diff --git a/src/mainboard/system76/meer9/variants/meer9/gpio.c b/src/mainboard/system76/meer9/variants/meer9/gpio.c new file mode 100644 index 00000000000..c7fc1810b78 --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/gpio.c @@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config gpio_table[] = { + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A00, UP_20K, DEEP, NF1), // ESPI_IO0 + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A01, UP_20K, DEEP, NF1), // ESPI_IO1 + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A02, UP_20K, DEEP, NF1), // ESPI_IO2 + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A03, UP_20K, DEEP, NF1), // ESPI_IO3 + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A04, UP_20K, DEEP, NF1), // ESPI_CS0# + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A05, UP_20K, DEEP, NF1), // ESPI_CLK + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A06, NONE, DEEP, NF1), // ESPI_RESET# + PAD_NC(GPP_A07, NONE), + PAD_NC(GPP_A08, NONE), + PAD_NC(GPP_A09, NONE), + PAD_NC(GPP_A10, NONE), + PAD_CFG_GPI(GPP_A11, NONE, PLTRST), + PAD_CFG_GPI(GPP_A12, NONE, PLTRST), + PAD_CFG_GPI(GPP_A13, UP_20K, PLTRST), + PAD_CFG_GPI(GPP_A14, UP_20K, PLTRST), + PAD_CFG_GPI(GPP_A15, NONE, PLTRST), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_A16, UP_20K, DEEP, NF1), // ESPI_ALERT0# + PAD_CFG_GPI(GPP_A17, UP_20K, PLTRST), + PAD_CFG_GPI(GPP_A18, UP_20K, PLTRST), + PAD_CFG_GPI(GPP_A19, UP_20K, DEEP), + PAD_CFG_GPI(GPP_A20, NATIVE, DEEP), + PAD_CFG_NF(GPP_A21, NATIVE, DEEP, NF1), // PMCALERT# + + PAD_CFG_GPI(GPP_B00, NONE, PLTRST), + PAD_CFG_GPI(GPP_B01, NONE, PLTRST), + PAD_CFG_GPI(GPP_B02, NONE, PLTRST), + PAD_CFG_GPI(GPP_B03, NONE, PLTRST), + PAD_CFG_GPI(GPP_B04, NONE, PLTRST), + PAD_CFG_GPI(GPP_B05, NONE, PLTRST), + PAD_CFG_GPI(GPP_B06, NONE, PLTRST), + PAD_CFG_GPI(GPP_B07, NONE, PLTRST), + PAD_CFG_GPO(GPP_B08, 1, PLTRST), + PAD_CFG_GPI(GPP_B09, NONE, PLTRST), + PAD_CFG_GPI(GPP_B10, NONE, PLTRST), + PAD_CFG_GPI(GPP_B11, NONE, PLTRST), + PAD_CFG_GPI(GPP_B12, NONE, PLTRST), + PAD_CFG_NF(GPP_B13, NONE, PLTRST, NF1), // PLTRST# + PAD_CFG_GPI(GPP_B14, NONE, PLTRST), + PAD_CFG_GPI(GPP_B15, NONE, PLTRST), + PAD_CFG_NF(GPP_B16, NONE, PLTRST, NF2), // HDMI_HPD2 + PAD_CFG_GPI(GPP_B17, NONE, PLTRST), + PAD_CFG_GPO(GPP_B18, 1, PLTRST), + PAD_CFG_GPO(GPP_B19, 1, PLTRST), + PAD_CFG_GPI(GPP_B20, NONE, PLTRST), + PAD_CFG_GPI(GPP_B21, NONE, PLTRST), + PAD_CFG_GPI(GPP_B22, NONE, PLTRST), + PAD_CFG_GPI(GPP_B23, NONE, PLTRST), + + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C00, NONE, DEEP, NF1), // SMBCLK + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C01, NONE, DEEP, NF1), // SMBDATA + PAD_CFG_NF(GPP_C02, NONE, DEEP, NF1), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C03, NONE, DEEP, NF1), // SML0CLK + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C04, NONE, DEEP, NF1), // SML0DATA + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C05, UP_20K, DEEP, NF1), // SM0ALERT# + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C06, NONE, DEEP, NF1), // SML1CLK + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C07, NONE, DEEP, NF1), // SML1DATA + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C08, NONE, DEEP, NF1), // SML1ALERT# + PAD_CFG_NF(GPP_C09, NONE, PLTRST, NF1), + PAD_CFG_NF(GPP_C10, NONE, DEEP, NF1), // SRCCLKREQ1# + PAD_CFG_NF(GPP_C11, NONE, DEEP, NF1), // SRCCLKREQ2# + PAD_CFG_NF(GPP_C12, NONE, DEEP, NF1), // SRCCLKREQ3# + PAD_CFG_GPI(GPP_C13, NONE, PLTRST), + PAD_NC(GPP_C14, NONE), + PAD_CFG_NF(GPP_C15, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), // TBT_LSX0_TXD + PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), // TBT_LSX0_RXD + PAD_NC(GPP_C18, NONE), + PAD_NC(GPP_C19, NONE), + PAD_CFG_GPI(GPP_C20, NONE, PLTRST), + PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_C22, NONE, DEEP, NF1), + PAD_CFG_GPI(GPP_C23, NONE, PLTRST), + + PAD_CFG_GPO(GPP_D00, 0, PWROK), + PAD_CFG_GPI(GPP_D01, NONE, PLTRST), + PAD_CFG_GPI(GPP_D02, NONE, PLTRST), + PAD_CFG_GPI(GPP_D03, NONE, PLTRST), + PAD_CFG_GPO(GPP_D04, 1, PWROK), + PAD_CFG_GPO(GPP_D05, 1, PLTRST), + PAD_CFG_GPO(GPP_D06, 1, PLTRST), + PAD_CFG_GPO(GPP_D07, 1, PLTRST), + PAD_CFG_GPO(GPP_D08, 1, PLTRST), + PAD_CFG_GPO(GPP_D09, 0, PWROK), // ME_OVERRIDE + PAD_CFG_NF(GPP_D10, NONE, PLTRST, NF1), // HDA_BCLK + PAD_CFG_NF(GPP_D11, NATIVE, PLTRST, NF1), // HDA_SYNC + PAD_CFG_NF(GPP_D12, NATIVE, PLTRST, NF1), // HDA_SDO + PAD_CFG_NF(GPP_D13, NATIVE, PLTRST, NF1), // HDA_SDI0 + PAD_CFG_GPI(GPP_D14, NONE, PLTRST), + PAD_CFG_GPI(GPP_D15, NONE, PLTRST), + PAD_CFG_GPI(GPP_D16, NONE, PLTRST), + PAD_CFG_NF(GPP_D17, NONE, PLTRST, NF1), // HDA_RST# + PAD_CFG_NF(GPP_D18, NONE, DEEP, NF1), // SRCCLKREQ6# + PAD_NC(GPP_D19, NONE), + PAD_CFG_NF(GPP_D20, NONE, DEEP, NF1), // SRCCLKREQ8# + PAD_CFG_NF(GPP_D21, NONE, DEEP, NF1), + PAD_CFG_GPI(GPP_D22, NATIVE, PLTRST), + PAD_CFG_GPI(GPP_D23, NATIVE, PLTRST), + + PAD_CFG_GPI(GPP_E00, NONE, PLTRST), + PAD_CFG_GPI(GPP_E01, NONE, PLTRST), + PAD_CFG_GPI(GPP_E02, NONE, PLTRST), + PAD_CFG_GPI(GPP_E03, NONE, PLTRST), + PAD_CFG_GPO(GPP_E04, 0, PLTRST), + PAD_CFG_GPO(GPP_E05, 1, PLTRST), + PAD_CFG_GPI(GPP_E06, NONE, PLTRST), + PAD_CFG_GPI(GPP_E07, NONE, PLTRST), + PAD_CFG_NF(GPP_E08, NONE, PLTRST, NF1), // DDPA_CTRLDATA + PAD_CFG_GPI(GPP_E09, NONE, PLTRST), + PAD_CFG_GPI(GPP_E10, NONE, PLTRST), + PAD_CFG_GPI(GPP_E11, NONE, PLTRST), + PAD_CFG_GPI(GPP_E12, NONE, PLTRST), + PAD_CFG_GPI(GPP_E13, NONE, PLTRST), + PAD_CFG_NF(GPP_E14, NONE, PLTRST, NF1), // HDMI_HPD + PAD_CFG_GPI(GPP_E15, NONE, PLTRST), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_E16, NONE, PLTRST, NF2), // VRALERT# + PAD_CFG_GPI(GPP_E17, NONE, PLTRST), + PAD_NC(GPP_E18, NONE), + PAD_NC(GPP_E19, NONE), + PAD_NC(GPP_E20, NONE), + PAD_NC(GPP_E21, NONE), + PAD_CFG_NF(GPP_E22, DN_20K, PLTRST, NF1), // DDPA_CTRLCLK + + PAD_CFG_NF(GPP_F00, NONE, PLTRST, NF1), // CNV_BRI_DT + PAD_CFG_NF(GPP_F01, UP_20K, PLTRST, NF1), // CNV_BRI_RSP + PAD_CFG_NF(GPP_F02, NONE, PLTRST, NF1), // CNV_BRI_RSP + PAD_CFG_NF(GPP_F03, UP_20K, PLTRST, NF1), // CNV_RGI_DT + PAD_CFG_NF(GPP_F04, NONE, PLTRST, NF1), // CNV_RGI_RSP + PAD_CFG_NF(GPP_F05, NONE, PLTRST, NF3), // CNV_RF_RESET# + PAD_CFG_NF(GPP_F06, NONE, PLTRST, NF1), // MODEM_CLKREQ + PAD_CFG_TERM_GPO(GPP_F07, 1, DN_20K, PWROK), // CNV_PA_BLANKING + PAD_CFG_GPI(GPP_F08, DN_20K, PLTRST), + PAD_CFG_GPI(GPP_F09, NONE, PLTRST), + PAD_CFG_GPI(GPP_F10, NONE, PLTRST), + PAD_CFG_GPI(GPP_F11, NONE, PLTRST), + PAD_CFG_GPI(GPP_F12, NONE, PLTRST), + PAD_CFG_GPI(GPP_F13, NONE, PLTRST), + PAD_CFG_GPI(GPP_F14, NONE, PLTRST), + PAD_CFG_GPI(GPP_F15, NONE, PLTRST), + PAD_CFG_GPI(GPP_F16, NONE, PLTRST), + PAD_CFG_GPI(GPP_F17, NONE, PLTRST), + PAD_CFG_GPI(GPP_F18, NONE, PLTRST), + PAD_CFG_GPI(GPP_F19, NONE, PLTRST), + PAD_CFG_GPI(GPP_F20, NONE, PLTRST), + PAD_CFG_GPI(GPP_F21, NONE, PLTRST), + PAD_CFG_GPI(GPP_F22, NONE, PLTRST), + PAD_CFG_GPI(GPP_F23, NONE, PLTRST), + + PAD_CFG_GPI(GPP_H00, NONE, PLTRST), + PAD_CFG_GPI(GPP_H01, NONE, PLTRST), + PAD_CFG_GPI(GPP_H02, NONE, PLTRST), + PAD_NC(GPP_H03, NONE), + PAD_CFG_NF(GPP_H04, NONE, PLTRST, NF2), // CNV_MFUART2_RXD + PAD_CFG_NF(GPP_H05, NONE, PLTRST, NF2), // CNV_MFUART2_TXD + PAD_CFG_GPI(GPP_H06, UP_20K, PLTRST), + PAD_CFG_GPI(GPP_H07, UP_20K, PLTRST), + PAD_CFG_GPI(GPP_H08, NONE, PLTRST), + PAD_CFG_GPI(GPP_H09, NONE, PLTRST), + PAD_CFG_GPI(GPP_H10, NONE, PLTRST), + PAD_CFG_GPI(GPP_H11, NONE, PLTRST), + PAD_NC(GPP_H12, NONE), + PAD_CFG_GPI(GPP_H13, NONE, PLTRST), + PAD_CFG_GPI(GPP_H14, NONE, PLTRST), + PAD_CFG_GPO(GPP_H15, 1, PLTRST), + PAD_CFG_NF(GPP_H16, NONE, PLTRST, NF1), // DDPB_CTRLCLK + PAD_CFG_NF(GPP_H17, NONE, PLTRST, NF1), // DDPB_CTRLDATA + PAD_NC(GPP_H18, NONE), + PAD_CFG_NF(GPP_H19, NONE, PLTRST, NF1), // CCG6DF_I2C_SDA (PD) + PAD_CFG_NF(GPP_H20, NONE, PLTRST, NF1), // CCG6DF_I2C_SCL (PD) + PAD_CFG_GPO(GPP_H21, 1, PLTRST), + PAD_CFG_GPI(GPP_H22, NONE, PLTRST), + + PAD_CFG_GPI(GPP_S00, NONE, PLTRST), + PAD_CFG_GPI(GPP_S01, NONE, PLTRST), + PAD_CFG_GPI(GPP_S02, NONE, PLTRST), + PAD_CFG_GPI(GPP_S03, NONE, PLTRST), + PAD_CFG_GPI(GPP_S04, NONE, PLTRST), + PAD_CFG_GPI(GPP_S05, NONE, PLTRST), + PAD_CFG_GPI(GPP_S06, NONE, PLTRST), + PAD_CFG_GPI(GPP_S07, NONE, PLTRST), + + PAD_CFG_NF(GPP_V00, NONE, DEEP, NF1), // BATLOW# + PAD_CFG_NF(GPP_V01, NONE, DEEP, NF1), // ACPRESENT + PAD_CFG_NF(GPP_V02, NONE, DEEP, NF1), // SOC_WAKE# + PAD_CFG_NF(GPP_V03, NONE, DEEP, NF1), // PWRBTN# + PAD_CFG_NF(GPP_V04, NONE, DEEP, NF1), // SLP_S3# + PAD_CFG_NF(GPP_V05, UP_20K, PLTRST, NF1), // SLP_S4# + PAD_CFG_NF(GPP_V06, NATIVE, PLTRST, NF1), + PAD_CFG_NF(GPP_V07, NATIVE, PLTRST, NF1), + PAD_CFG_NF(GPP_V08, UP_20K, PLTRST, NF1), // SUSCLK + PAD_CFG_NF(GPP_V09, NONE, PLTRST, NF1), + PAD_CFG_NF(GPP_V10, NONE, PLTRST, NF1), + PAD_CFG_GPI(GPP_V11, NONE, PLTRST), + PAD_NC(GPP_V12, NONE), + PAD_CFG_NF(GPP_V13, NONE, PLTRST, NF1), + PAD_CFG_GPI(GPP_V14, NONE, PLTRST), // WAKE# + PAD_CFG_GPI(GPP_V15, NONE, PLTRST), + PAD_CFG_GPI(GPP_V16, NONE, PLTRST), + PAD_CFG_GPI(GPP_V17, NONE, PLTRST), + PAD_NC(GPP_V18, NONE), + PAD_CFG_NF(GPP_V19, NONE, PLTRST, NF1), + PAD_NC(GPP_V20, NONE), + PAD_NC(GPP_V21, NONE), + PAD_NC(GPP_V22, NONE), + PAD_NC(GPP_V23, NONE), +}; + +void mainboard_configure_gpios(void) +{ + gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table)); +} diff --git a/src/mainboard/system76/meer9/variants/meer9/gpio_early.c b/src/mainboard/system76/meer9/variants/meer9/gpio_early.c new file mode 100644 index 00000000000..b3cd0c99242 --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/gpio_early.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config early_gpio_table[] = { + PAD_CFG_NF(GPP_C00, NONE, DEEP, NF1), // SMB_CLK + PAD_CFG_NF(GPP_C01, NONE, DEEP, NF1), // SMB_DATA +}; + +void mainboard_configure_early_gpios(void) +{ + gpio_configure_pads(early_gpio_table, ARRAY_SIZE(early_gpio_table)); +} diff --git a/src/mainboard/system76/meer9/variants/meer9/hda_verb.c b/src/mainboard/system76/meer9/variants/meer9/hda_verb.c new file mode 100644 index 00000000000..c824b142612 --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/hda_verb.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +const u32 cim_verb_data[] = { + /* Realtek, ALC256 */ + 0x10ec0256, /* Vendor ID */ + 0x18490256, /* Subsystem ID */ + 13, /* Number of entries */ + AZALIA_SUBVENDOR(0, 0x18490256), + AZALIA_RESET(1), + AZALIA_PIN_CFG(0, 0x12, 0x40000000), // DMIC + AZALIA_PIN_CFG(0, 0x13, AZALIA_PIN_CFG_NC(0)), // DMIC + AZALIA_PIN_CFG(0, 0x14, AZALIA_PIN_CFG_NC(0)), // Front (Port-D) + AZALIA_PIN_CFG(0, 0x18, AZALIA_PIN_CFG_NC(0)), // NPC + AZALIA_PIN_CFG(0, 0x19, 0x02a11020), // MIC2 (Port-F) + AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)), // LINE1 (Port-C) + AZALIA_PIN_CFG(0, 0x1b, AZALIA_PIN_CFG_NC(0)), // LINE2 (Port-E) + AZALIA_PIN_CFG(0, 0x1d, 0x40400001), // BEEP-IN + AZALIA_PIN_CFG(0, 0x1e, AZALIA_PIN_CFG_NC(0)), // S/PDIF-OUT + AZALIA_PIN_CFG(0, 0x21, 0x02211010), // HP1-OUT (Port-I) + + // Enable HP-JD + 0x0205001B, 0x02040A4B, 0x0205001B, 0x02040A4B, +}; + +const u32 pc_beep_verbs[] = { + // Dos beep path - 1 + 0x02170C00, 0x02050036, 0x02041151, 0x021707C0, + // Dos beep path - 2 + 0x0213B000, 0x02170C02, 0x02170C02, 0x02170C02, +}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/system76/meer9/variants/meer9/overridetree.cb b/src/mainboard/system76/meer9/variants/meer9/overridetree.cb new file mode 100644 index 00000000000..8807034adf4 --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/overridetree.cb @@ -0,0 +1,102 @@ +chip soc/intel/meteorlake + device domain 0 on + #TODO: all the devices have different subsystem product IDs + #subsystemid 0x1849 TODO inherit + + device ref tbt_pcie_rp0 on end + device ref tcss_xhci on + register "tcss_ports[0]" = "TCSS_PORT_DEFAULT(OC_SKIP)" # TBT + register "tcss_ports[1]" = "TCSS_PORT_DEFAULT(OC_SKIP)" # Type-C + register "tcss_ports[2]" = "TCSS_PORT_DEFAULT(OC_SKIP)" # USB3 Front + chip drivers/usb/acpi + device ref tcss_root_hub on + chip drivers/usb/acpi + register "desc" = ""TBT Type-C"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + device ref tcss_usb3_port0 on end + end + chip drivers/usb/acpi + register "desc" = ""USB Type-C"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + device ref tcss_usb3_port1 on end + end + chip drivers/usb/acpi + register "desc" = ""USB Type-A"" + register "type" = "UPC_TYPE_USB3_A" + device ref tcss_usb3_port2 on end + end + end + end + end + device ref tcss_dma0 on end + device ref xhci on + register "usb2_ports" = "{ + [0] = USB2_PORT_MID(OC_SKIP), /* USB3 Rear */ + [1] = USB2_PORT_MID(OC_SKIP), /* USB3 Rear */ + [2] = USB2_PORT_MID(OC_SKIP), /* USB2 Header */ + [3] = USB2_PORT_MID(OC_SKIP), /* USB2 Header */ + [4] = USB2_PORT_TYPE_C(OC_SKIP), /* TBT */ + [5] = USB2_PORT_TYPE_C(OC_SKIP), /* Type-C */ + [6] = USB2_PORT_MID(OC_SKIP), /* USB3 Front */ + [7] = USB2_PORT_MID(OC_SKIP), /* USB3 Front */ + [8] = USB2_PORT_MID(OC_SKIP), /* M.2 Key M */ + [9] = USB2_PORT_MID(OC_SKIP), /* M.2 Key E */ + }" + register "usb3_ports" = "{ + [0] = USB3_PORT_DEFAULT(OC_SKIP), /* USB3 Rear */ + [1] = USB3_PORT_DEFAULT(OC_SKIP), /* USB3 Rear */ + }" + end + device ref pcie_rp5 on + # GLAN1 + register "pcie_rp[PCH_RP(5)]" = "{ + .clk_src = 2, + .clk_req = 2, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + device pci 00.0 on end + end + device ref pcie_rp6 on + # GLAN2 + register "pcie_rp[PCH_RP(6)]" = "{ + .clk_src = 3, + .clk_req = 3, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + device ref pcie_rp7 on + # M.2 Key-E1 + register "pcie_rp[PCH_RP(7)]" = "{ + .clk_src = 1, + .clk_req = 1, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + device ref pcie_rp10 on + # M.2 Key-M1 + # XXX: Schematics show RP[13:16] used + register "pcie_rp[PCH_RP(10)]" = "{ + .clk_src = 8, + .clk_req = 8, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + device ref pcie_rp11 on + # M.2 Key-M2 + # XXX: Schematics show RP[17:20] used + register "pcie_rp[PCH_RP(11)]" = "{ + .clk_src = 6, + .clk_req = 6, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + device ref sata on + register "sata_salp_support" = "1" + register "sata_ports_enable[0]" = "1" # SATA 0 + register "sata_ports_dev_slp[0]" = "1" + end + device ref hda on + subsystemid 0x1849 0x0256 + end + end +end diff --git a/src/mainboard/system76/meer9/variants/meer9/ramstage.c b/src/mainboard/system76/meer9/variants/meer9/ramstage.c new file mode 100644 index 00000000000..c0c90dd45d3 --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/ramstage.c @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +void mainboard_silicon_init_params(FSP_S_CONFIG *params) +{ + // Enable TCP1 and TCP2 USB-A conversion + // BIT 0:3 is mapping to PCH XHCI USB2 port + // BIT 4:5 is reserved + // BIT 6 is orientational + // BIT 7 is enable + params->EnableTcssCovTypeA[1] = 0x86; + params->EnableTcssCovTypeA[2] = 0x87; + + // XXX: Enabling C10 reporting causes system to constantly enter and + // exit opportunistic suspend when idle. + params->PchEspiHostC10ReportEnable = 0; +} diff --git a/src/mainboard/system76/meer9/variants/meer9/romstage.c b/src/mainboard/system76/meer9/variants/meer9/romstage.c new file mode 100644 index 00000000000..b047f523ac5 --- /dev/null +++ b/src/mainboard/system76/meer9/variants/meer9/romstage.c @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +void mainboard_memory_init_params(FSPM_UPD *mupd) +{ + const struct mb_cfg board_cfg = { + .type = MEM_TYPE_DDR5, + .ect = true, + }; + const struct mem_spd spd_info = { + .topo = MEM_TOPO_DIMM_MODULE, + .smbus = { + [0] = { .addr_dimm[0] = 0x50, }, + [1] = { .addr_dimm[0] = 0x52, }, + }, + }; + const bool half_populated = false; + + mupd->FspmConfig.DmiMaxLinkSpeed = 4; + mupd->FspmConfig.GpioOverride = 0; + + memcfg_init(mupd, &board_cfg, &spd_info, half_populated); +} diff --git a/src/mainboard/system76/mtl/Kconfig b/src/mainboard/system76/mtl/Kconfig index 761c599fdae..9b1f369cd6c 100644 --- a/src/mainboard/system76/mtl/Kconfig +++ b/src/mainboard/system76/mtl/Kconfig @@ -9,6 +9,7 @@ config BOARD_SYSTEM76_MTL_COMMON select DRIVERS_GENERIC_CBFS_UUID select DRIVERS_I2C_HID select EC_SYSTEM76_EC + select EC_SYSTEM76_EC_LOCKDOWN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_CMOS_DEFAULT diff --git a/src/mainboard/system76/mtl/variants/darp10/ramstage.c b/src/mainboard/system76/mtl/variants/darp10/ramstage.c index 0e3baf2ad69..63dfb351519 100644 --- a/src/mainboard/system76/mtl/variants/darp10/ramstage.c +++ b/src/mainboard/system76/mtl/variants/darp10/ramstage.c @@ -9,8 +9,7 @@ void mainboard_silicon_init_params(FSP_S_CONFIG *params) // BIT 4:5 is reserved // BIT 6 is orientational // BIT 7 is enable - // TODO: Add to coreboot FSP headers as no Client FSP release will be made. - //params->EnableTcssCovTypeA[1] = 0x82; + params->EnableTcssCovTypeA[1] = 0x82; // XXX: Enabling C10 reporting causes system to constantly enter and // exit opportunistic suspend when idle. diff --git a/src/mainboard/system76/mtl/variants/lemp13/ramstage.c b/src/mainboard/system76/mtl/variants/lemp13/ramstage.c index f99c93b0f2c..26a52e4c88d 100644 --- a/src/mainboard/system76/mtl/variants/lemp13/ramstage.c +++ b/src/mainboard/system76/mtl/variants/lemp13/ramstage.c @@ -11,9 +11,8 @@ void mainboard_silicon_init_params(FSP_S_CONFIG *params) // BIT 4:5 is reserved // BIT 6 is orientational // BIT 7 is enable - // TODO: Add to coreboot FSP headers as no Client FSP release will be made. - //params->EnableTcssCovTypeA[1] = 0x81; - //params->EnableTcssCovTypeA[3] = 0x85; + params->EnableTcssCovTypeA[1] = 0x81; + params->EnableTcssCovTypeA[3] = 0x85; // Disable reporting CPU C10 state over eSPI (causes LED flicker). params->PchEspiHostC10ReportEnable = 0; diff --git a/src/mainboard/system76/oryp5/Kconfig b/src/mainboard/system76/oryp5/Kconfig index a74bea2339c..28f2fc7bbd2 100644 --- a/src/mainboard/system76/oryp5/Kconfig +++ b/src/mainboard/system76/oryp5/Kconfig @@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_16384 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA select DRIVERS_I2C_HID select DRIVERS_I2C_TAS5825M select EC_SYSTEM76_EC diff --git a/src/mainboard/system76/oryp5/acpi/mainboard.asl b/src/mainboard/system76/oryp5/acpi/mainboard.asl index 17d2221ab4c..f816e3f2dad 100644 --- a/src/mainboard/system76/oryp5/acpi/mainboard.asl +++ b/src/mainboard/system76/oryp5/acpi/mainboard.asl @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include + #define EC_GPE_SCI 0x17 /* GPP_B23 */ #define EC_GPE_SWI 0x26 /* GPP_G6 */ #include @@ -9,6 +11,10 @@ Scope (\_SB) #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" + Device (PEGP) { + Name (_ADR, CONFIG_DRIVERS_GFX_NVIDIA_BRIDGE << 16) + #include + } } } diff --git a/src/mainboard/system76/oryp5/devicetree.cb b/src/mainboard/system76/oryp5/devicetree.cb index b72d9ba854d..0095355492e 100644 --- a/src/mainboard/system76/oryp5/devicetree.cb +++ b/src/mainboard/system76/oryp5/devicetree.cb @@ -62,6 +62,12 @@ chip soc/intel/cannonlake # PCI Express Graphics #0 x16, Clock 8 (NVIDIA GPU) register "PcieClkSrcUsage[8]" = "0x40" register "PcieClkSrcClkReq[8]" = "8" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller + end end device ref igpu on register "gfx" = "GMA_DEFAULT_PANEL(0)" diff --git a/src/mainboard/system76/oryp5/include/mainboard/gpio.h b/src/mainboard/system76/oryp5/include/mainboard/gpio.h index c6393beebb6..2bfbd100afb 100644 --- a/src/mainboard/system76/oryp5/include/mainboard/gpio.h +++ b/src/mainboard/system76/oryp5/include/mainboard/gpio.h @@ -3,7 +3,16 @@ #ifndef MAINBOARD_GPIO_H #define MAINBOARD_GPIO_H +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_C12 +#define DGPU_SSID 0x95e61558 + +#ifndef __ACPI__ void mainboard_configure_early_gpios(void); void mainboard_configure_gpios(void); +#endif #endif diff --git a/src/mainboard/system76/oryp5/romstage.c b/src/mainboard/system76/oryp5/romstage.c index 455a2bb9196..ec24f532b23 100644 --- a/src/mainboard/system76/oryp5/romstage.c +++ b/src/mainboard/system76/oryp5/romstage.c @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include +#include #include #include @@ -20,6 +22,18 @@ static const struct cnl_mb_cfg memcfg = { void mainboard_memory_init_params(FSPM_UPD *memupd) { + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + memupd->FspmConfig.PrimaryDisplay = 0; + // Allow memory speeds higher than 2666 MT/s memupd->FspmConfig.SaOcSupport = 1; diff --git a/src/mainboard/system76/oryp6/Kconfig b/src/mainboard/system76/oryp6/Kconfig index 8fd023d56a7..9bbd624bbe6 100644 --- a/src/mainboard/system76/oryp6/Kconfig +++ b/src/mainboard/system76/oryp6/Kconfig @@ -8,6 +8,7 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_16384 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA select DRIVERS_I2C_HID select DRIVERS_I2C_TAS5825M select EC_SYSTEM76_EC diff --git a/src/mainboard/system76/oryp6/Makefile.mk b/src/mainboard/system76/oryp6/Makefile.mk index ab8e965d872..af0b83b615a 100644 --- a/src/mainboard/system76/oryp6/Makefile.mk +++ b/src/mainboard/system76/oryp6/Makefile.mk @@ -1,6 +1,7 @@ ## SPDX-License-Identifier: GPL-2.0-only CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include bootblock-y += bootblock.c bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c diff --git a/src/mainboard/system76/oryp6/acpi/mainboard.asl b/src/mainboard/system76/oryp6/acpi/mainboard.asl index b235437c25d..610cdd12bad 100644 --- a/src/mainboard/system76/oryp6/acpi/mainboard.asl +++ b/src/mainboard/system76/oryp6/acpi/mainboard.asl @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include + #define EC_GPE_SCI 0x03 /* GPP_K3 */ #define EC_GPE_SWI 0x06 /* GPP_K6 */ #include @@ -8,6 +10,10 @@ Scope (\_SB) { #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" + Device (PEGP) { + Name (_ADR, CONFIG_DRIVERS_GFX_NVIDIA_BRIDGE << 16) + #include + } } } diff --git a/src/mainboard/system76/oryp6/devicetree.cb b/src/mainboard/system76/oryp6/devicetree.cb index bcb75d0b3ce..7b8e6a2329f 100644 --- a/src/mainboard/system76/oryp6/devicetree.cb +++ b/src/mainboard/system76/oryp6/devicetree.cb @@ -59,6 +59,12 @@ chip soc/intel/cannonlake # PCI Express Graphics #0 x16, Clock 8 (NVIDIA GPU) register "PcieClkSrcUsage[8]" = "0x40" register "PcieClkSrcClkReq[8]" = "8" + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller + end end device ref igpu on register "gfx" = "GMA_DEFAULT_PANEL(0)" diff --git a/src/mainboard/system76/oryp6/romstage.c b/src/mainboard/system76/oryp6/romstage.c index 8ea791a2d10..44da3d8c463 100644 --- a/src/mainboard/system76/oryp6/romstage.c +++ b/src/mainboard/system76/oryp6/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include #include static const struct cnl_mb_cfg memcfg = { @@ -21,6 +23,18 @@ static const struct cnl_mb_cfg memcfg = { void mainboard_memory_init_params(FSPM_UPD *memupd) { + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + memupd->FspmConfig.PrimaryDisplay = 0; + variant_configure_fspm(memupd); cannonlake_memcfg_init(&memupd->FspmConfig, &memcfg); diff --git a/src/mainboard/system76/oryp6/variants/oryp6/include/variant/gpio.h b/src/mainboard/system76/oryp6/variants/oryp6/include/variant/gpio.h new file mode 100644 index 00000000000..697e1ecf510 --- /dev/null +++ b/src/mainboard/system76/oryp6/variants/oryp6/include/variant/gpio.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_K21 +#define DGPU_SSID 0x50d31558 + +#ifndef __ACPI__ +void variant_configure_early_gpios(void); +void variant_configure_gpios(void); +#endif + +#endif diff --git a/src/mainboard/system76/oryp6/variants/oryp7/include/variant/gpio.h b/src/mainboard/system76/oryp6/variants/oryp7/include/variant/gpio.h new file mode 100644 index 00000000000..6e1d7dfa127 --- /dev/null +++ b/src/mainboard/system76/oryp6/variants/oryp7/include/variant/gpio.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_F22 +#define DGPU_PWR_EN GPP_F23 +#define DGPU_GC6 GPP_K21 +#define DGPU_SSID 0x65e51558 + +#ifndef __ACPI__ +void variant_configure_early_gpios(void); +void variant_configure_gpios(void); +#endif + +#endif diff --git a/src/mainboard/system76/ptl/Kconfig b/src/mainboard/system76/ptl/Kconfig new file mode 100644 index 00000000000..da29d0a0030 --- /dev/null +++ b/src/mainboard/system76/ptl/Kconfig @@ -0,0 +1,89 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config BOARD_SYSTEM76_PTL_COMMON + def_bool n + select AZALIA_USE_LEGACY_VERB_TABLE + select BOARD_ROMSIZE_KB_32768 + select DRIVERS_GENERIC_BAYHUB_LV2 + select DRIVERS_GENERIC_CBFS_SERIAL + select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_I2C_HID + select EC_SYSTEM76_EC + select EC_SYSTEM76_EC_LOCKDOWN + select HAVE_ACPI_RESUME + select HAVE_ACPI_TABLES + select HAVE_CMOS_DEFAULT + select HAVE_OPTION_TABLE + select INTEL_GMA_HAVE_VBT + select INTEL_LPSS_UART_FOR_CONSOLE + select MAINBOARD_HAS_TPM2 + select MEMORY_MAPPED_TPM + select NO_UART_ON_SUPERIO + select PCIEXP_SUPPORT_RESIZABLE_BARS + select SOC_INTEL_COMMON_BLOCK_HDA_VERB + select SOC_INTEL_CRASHLOG + select SOC_INTEL_PANTHERLAKE_U_H + select SPD_READ_BY_WORD + select SYSTEM_TYPE_LAPTOP + +config BOARD_SYSTEM76_LEMP14 + select BOARD_SYSTEM76_PTL_COMMON + select DRIVERS_I2C_TAS5825M + select HAVE_SPD_IN_CBFS + select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES + +if BOARD_SYSTEM76_PTL_COMMON + +config MAINBOARD_DIR + default "system76/ptl" + +config VARIANT_DIR + default "lemp14" if BOARD_SYSTEM76_LEMP14 + +config OVERRIDE_DEVICETREE + default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" + +config MAINBOARD_PART_NUMBER + default "lemp14" if BOARD_SYSTEM76_LEMP14 + +config MAINBOARD_SMBIOS_PRODUCT_NAME + default "Lemur Pro" if BOARD_SYSTEM76_LEMP14 + +config MAINBOARD_VERSION + default "lemp14" if BOARD_SYSTEM76_LEMP14 + +config CMOS_DEFAULT_FILE + default "src/mainboard/\$(MAINBOARDDIR)/cmos.default" + +config CONSOLE_POST + default y + +config D3COLD_SUPPORT + default n + +config DIMM_SPD_SIZE + default 512 + +config FMDFILE + default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" + +config ONBOARD_VGA_IS_PRIMARY + default y + +config PCIEXP_DEFAULT_MAX_RESIZABLE_BAR_BITS + default 36 + +config POST_DEVICE + default n + +config TPM_MEASURED_BOOT + default y + +config UART_FOR_CONSOLE + default 0 + +# PM Timer Disabled, saves power +config USE_PM_ACPI_TIMER + default n + +endif diff --git a/src/mainboard/system76/ptl/Kconfig.name b/src/mainboard/system76/ptl/Kconfig.name new file mode 100644 index 00000000000..eb83581a0d0 --- /dev/null +++ b/src/mainboard/system76/ptl/Kconfig.name @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config BOARD_SYSTEM76_LEMP14 + bool "lemp14" diff --git a/src/mainboard/system76/ptl/Makefile.mk b/src/mainboard/system76/ptl/Makefile.mk new file mode 100644 index 00000000000..33c81b161cc --- /dev/null +++ b/src/mainboard/system76/ptl/Makefile.mk @@ -0,0 +1,16 @@ +## SPDX-License-Identifier: GPL-2.0-only + +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include + +bootblock-y += bootblock.c +bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c + +romstage-y += variants/$(VARIANT_DIR)/romstage.c + +ramstage-y += ramstage.c +ramstage-y += variants/$(VARIANT_DIR)/hda_verb.c +ramstage-y += variants/$(VARIANT_DIR)/gpio.c +ramstage-y += variants/$(VARIANT_DIR)/ramstage.c +ramstage-$(CONFIG_DRIVERS_I2C_TAS5825M) += variants/$(VARIANT_DIR)/tas5825m.c + +SPD_SOURCES = samsung-K3KL8L80DM-MGCU samsung-K3KL9L90EM-MGCU diff --git a/src/mainboard/system76/ptl/acpi/backlight.asl b/src/mainboard/system76/ptl/acpi/backlight.asl new file mode 100644 index 00000000000..053ce57b5d4 --- /dev/null +++ b/src/mainboard/system76/ptl/acpi/backlight.asl @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +Scope (GFX0) +{ + Name (BRIG, Package (22) { + 100, /* default AC */ + 100, /* default Battery */ + 5, + 10, + 15, + 20, + 25, + 30, + 35, + 40, + 45, + 50, + 55, + 60, + 65, + 70, + 75, + 80, + 85, + 90, + 95, + 100 + }) +} diff --git a/src/mainboard/system76/ptl/acpi/mainboard.asl b/src/mainboard/system76/ptl/acpi/mainboard.asl new file mode 100644 index 00000000000..c982a9ee4cb --- /dev/null +++ b/src/mainboard/system76/ptl/acpi/mainboard.asl @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define EC_GPE_SCI 0x6E +#define EC_GPE_SWI 0x6B +#include + +Scope (\_SB) { + #include "sleep.asl" + Scope (PCI0) { + #include "backlight.asl" + } +} diff --git a/src/mainboard/system76/ptl/acpi/sleep.asl b/src/mainboard/system76/ptl/acpi/sleep.asl new file mode 100644 index 00000000000..8a2a22c55b6 --- /dev/null +++ b/src/mainboard/system76/ptl/acpi/sleep.asl @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +External(\TBTS, MethodObj) + +Method(MPTS, 1, Serialized) { + If (CondRefOf(\TBTS)) { + \TBTS() + } +} diff --git a/src/mainboard/system76/ptl/board_info.txt b/src/mainboard/system76/ptl/board_info.txt new file mode 100644 index 00000000000..e67d8800620 --- /dev/null +++ b/src/mainboard/system76/ptl/board_info.txt @@ -0,0 +1,6 @@ +Vendor name: System76 +Category: laptop +ROM package: WSON-8 +ROM protocol: SPI +ROM socketed: n +Flashrom support: y diff --git a/src/mainboard/system76/ptl/bootblock.c b/src/mainboard/system76/ptl/bootblock.c new file mode 100644 index 00000000000..8d06adc9d7f --- /dev/null +++ b/src/mainboard/system76/ptl/bootblock.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +void bootblock_mainboard_early_init(void) +{ + mainboard_configure_early_gpios(); +} diff --git a/src/mainboard/system76/ptl/cmos.default b/src/mainboard/system76/ptl/cmos.default new file mode 100644 index 00000000000..0cc5970e49b --- /dev/null +++ b/src/mainboard/system76/ptl/cmos.default @@ -0,0 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + +boot_option=Fallback +debug_level=Debug +me_state=Disable diff --git a/src/mainboard/system76/ptl/cmos.layout b/src/mainboard/system76/ptl/cmos.layout new file mode 100644 index 00000000000..b3df3808ccb --- /dev/null +++ b/src/mainboard/system76/ptl/cmos.layout @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: GPL-2.0-only + +entries + +0 384 r 0 reserved_memory + +# RTC_BOOT_BYTE (coreboot hardcoded) +384 1 e 4 boot_option +388 4 h 0 reboot_counter + +# RTC_CLK_ALTCENTURY +400 8 r 0 century + +412 4 e 6 debug_level +416 1 e 2 me_state +417 3 h 0 me_state_counter + +# CMOS_VSTART_ramtop +800 80 r 0 ramtop + +984 16 h 0 check_sum + +enumerations + +2 0 Enable +2 1 Disable + +4 0 Fallback +4 1 Normal + +6 0 Emergency +6 1 Alert +6 2 Critical +6 3 Error +6 4 Warning +6 5 Notice +6 6 Info +6 7 Debug +6 8 Spew + +checksums + +checksum 408 799 984 diff --git a/src/mainboard/system76/ptl/devicetree.cb b/src/mainboard/system76/ptl/devicetree.cb new file mode 100644 index 00000000000..2c5189ca923 --- /dev/null +++ b/src/mainboard/system76/ptl/devicetree.cb @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0-only + +chip soc/intel/pantherlake + register "common_soc_config" = "{ + // Touchpad I2C bus + .i2c[0] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 80, + .fall_time_ns = 110, + }, + }" + + # Enable Enhanced Intel SpeedStep + register "eist_enable" = "true" + + # Thermal + register "tcc_offset" = "8" + + device cpu_cluster 0 on end + + device domain 0 on + device ref system_agent on end + device ref igpu on + # DDIA is eDP, TCP3 is HDMI + register "ddi_port_A_config" = "1" + register "ddi_ports_config" = "{ + [DDI_PORT_A] = DDI_ENABLE_HPD, + [DDI_PORT_3] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + }" + + #TODO: not in pantherlake chip: register "gfx" = "GMA_DEFAULT_PANEL(0)" + end + device ref npu on end + device ref pmc_shared_sram on end + device ref cnvi_wifi on + register "cnvi_wifi_core" = "true" + register "cnvi_bt_core" = "true" + register "cnvi_bt_audio_offload" = "true" + chip drivers/wifi/generic + register "wake" = "GPE0_PME_B0" + device generic 0 on end + end + end + + device ref heci1 on end + device ref soc_espi on + register "gen1_dec" = "0x00040069" # EC PM channel + register "gen2_dec" = "0x00fc0e01" # AP/EC command + register "gen3_dec" = "0x00fc0f01" # AP/EC debug + chip drivers/pc80/tpm + device pnp 0c31.0 on end + end + end + device ref p2sb on end + device ref hda on + register "pch_hda_audio_link_hda_enable" = "1" + register "pch_hda_sdi_enable[0]" = "true" + register "pch_hda_idisp_codec_enable" = "1" + register "pch_hda_idisp_link_frequency" = "HDA_LINKFREQ_96MHZ" + register "pch_hda_idisp_link_tmode" = "HDA_TMODE_8T" + end + device ref smbus on end + device ref fast_spi on end + end +end diff --git a/src/mainboard/system76/ptl/dsdt.asl b/src/mainboard/system76/ptl/dsdt.asl new file mode 100644 index 00000000000..f6e4cf756bf --- /dev/null +++ b/src/mainboard/system76/ptl/dsdt.asl @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +//TODO: HACK FOR MISSING MISCCFG_GPIO_PM_CONFIG_BITS +#include + +#include +DefinitionBlock( + "dsdt.aml", + "DSDT", + ACPI_DSDT_REV_2, + OEM_ID, + ACPI_TABLE_CREATOR, + 0x20110725 +) +{ + #include + #include + #include + #include + + Device (\_SB.PCI0) + { + #include + #include + #include + } + + #include + + Scope (\_SB.PCI0.LPCB) + { + #include + } + + #include "acpi/mainboard.asl" +} diff --git a/src/mainboard/system76/ptl/include/mainboard/gpio.h b/src/mainboard/system76/ptl/include/mainboard/gpio.h new file mode 100644 index 00000000000..c6393beebb6 --- /dev/null +++ b/src/mainboard/system76/ptl/include/mainboard/gpio.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef MAINBOARD_GPIO_H +#define MAINBOARD_GPIO_H + +void mainboard_configure_early_gpios(void); +void mainboard_configure_gpios(void); + +#endif diff --git a/src/mainboard/system76/ptl/ramstage.c b/src/mainboard/system76/ptl/ramstage.c new file mode 100644 index 00000000000..a3b12bb1f2e --- /dev/null +++ b/src/mainboard/system76/ptl/ramstage.c @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static void mainboard_init(void *chip_info) +{ + mainboard_configure_gpios(); +} + +struct chip_operations mainboard_ops = { + .init = mainboard_init, +}; diff --git a/src/mainboard/system76/ptl/spd/samsung-K3KL8L80DM-MGCU.spd.hex b/src/mainboard/system76/ptl/spd/samsung-K3KL8L80DM-MGCU.spd.hex new file mode 100644 index 00000000000..7e41dd28542 --- /dev/null +++ b/src/mainboard/system76/ptl/spd/samsung-K3KL8L80DM-MGCU.spd.hex @@ -0,0 +1,33 @@ +# Samsung K3KL8L80DM-MGCU +23 10 15 0e 86 22 95 08 00 40 00 00 02 01 00 00 +48 00 08 ff 92 55 05 00 aa 00 90 a8 90 c0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 7f c1 89 20 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 4b 33 4b 4c 38 4c 38 +30 44 4d 2d 4d 47 43 55 00 00 00 00 00 00 80 ce +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/system76/ptl/spd/samsung-K3KL9L90EM-MGCU.spd.hex b/src/mainboard/system76/ptl/spd/samsung-K3KL9L90EM-MGCU.spd.hex new file mode 100644 index 00000000000..62f8ae330c1 --- /dev/null +++ b/src/mainboard/system76/ptl/spd/samsung-K3KL9L90EM-MGCU.spd.hex @@ -0,0 +1,33 @@ +# Samsung K3KL9L90EM-MGCU +23 10 15 0e 86 22 b5 08 00 40 00 00 0a 01 00 00 +48 00 08 ff 92 55 05 00 aa 00 90 a8 90 c0 08 60 +04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 7f c1 c5 78 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 4b 33 4b 4c 39 4c 39 +30 44 4d 2d 4d 47 43 55 00 00 00 00 00 00 80 ce +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/system76/ptl/variants/lemp14/board.fmd b/src/mainboard/system76/ptl/variants/lemp14/board.fmd new file mode 100644 index 00000000000..c466748dc44 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/board.fmd @@ -0,0 +1,12 @@ +FLASH 32M { + SI_DESC 16K + SI_ME 9176K + SI_BIOS@16M 16M { + RW_MRC_CACHE 64K + SMMSTORE(PRESERVE) 256K + WP_RO { + FMAP 4K + COREBOOT(CBFS) + } + } +} diff --git a/src/mainboard/system76/ptl/variants/lemp14/board_info.txt b/src/mainboard/system76/ptl/variants/lemp14/board_info.txt new file mode 100644 index 00000000000..75ed180caf4 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/board_info.txt @@ -0,0 +1,2 @@ +Board name: lemp14 +Release year: 2026 diff --git a/src/mainboard/system76/ptl/variants/lemp14/data.vbt b/src/mainboard/system76/ptl/variants/lemp14/data.vbt new file mode 100644 index 00000000000..d7979238a97 Binary files /dev/null and b/src/mainboard/system76/ptl/variants/lemp14/data.vbt differ diff --git a/src/mainboard/system76/ptl/variants/lemp14/gpio.c b/src/mainboard/system76/ptl/variants/lemp14/gpio.c new file mode 100644 index 00000000000..d81813108f6 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/gpio.c @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config gpio_table[] = { + PAD_CFG_NF(GPP_A00, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_A01, 1, DEEP), + PAD_CFG_GPO(GPP_A02, 1, DEEP), + PAD_CFG_GPO(GPP_A03, 1, DEEP), + PAD_CFG_GPO(GPP_A04, 1, DEEP), + PAD_CFG_GPO(GPP_A05, 1, DEEP), + PAD_CFG_GPO(GPP_A06, 1, DEEP), + PAD_CFG_GPO(GPP_A07, 1, DEEP), + PAD_CFG_NF(GPP_A08, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_A09, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_A10, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_A11, UP_20K, DEEP, NF1), + PAD_NC(GPP_A12, NATIVE), + PAD_CFG_NF(GPP_A13, NATIVE, DEEP, NF2), + _PAD_CFG_STRUCT(GPP_A14, 0x40001300, 0x3c00), + PAD_CFG_NF(GPP_A15, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_A16, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_A17, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_B00, NONE, PWROK, NF1), + PAD_CFG_NF(GPP_B01, NONE, PWROK, NF1), + PAD_CFG_GPO(GPP_B02, 1, DEEP), + PAD_CFG_GPO(GPP_B03, 1, DEEP), + PAD_CFG_GPO(GPP_B04, 1, DEEP), + PAD_CFG_GPO(GPP_B05, 1, DEEP), + PAD_CFG_GPO(GPP_B06, 0, PLTRST), + PAD_CFG_GPO(GPP_B07, 1, DEEP), + PAD_CFG_GPO(GPP_B08, 1, DEEP), + PAD_CFG_GPO(GPP_B09, 1, PLTRST), + PAD_CFG_GPO(GPP_B10, 1, PLTRST), + PAD_NC(GPP_B11, NONE), + PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_B14, NONE, DEEP, NF2), + PAD_NC(GPP_B15, NONE), + PAD_CFG_GPO(GPP_B16, 1, DEEP), + PAD_CFG_GPO(GPP_B17, 1, DEEP), + PAD_CFG_GPO(GPP_B18, 1, DEEP), + PAD_CFG_GPO(GPP_B19, 1, DEEP), + PAD_NC(GPP_B20, NONE), + PAD_CFG_GPO(GPP_B21, 0, PLTRST), + PAD_CFG_GPO(GPP_B22, 1, DEEP), + PAD_CFG_GPO(GPP_B23, 1, DEEP), + PAD_CFG_GPO(GPP_B24, 1, DEEP), + PAD_CFG_GPO(GPP_B25, 1, DEEP), + PAD_CFG_NF(GPP_C00, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_C01, UP_20K, DEEP, NF1), + PAD_CFG_GPO(GPP_C02, 1, DEEP), + PAD_CFG_NF(GPP_C03, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_C04, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_C05, 1, DEEP), + PAD_NC(GPP_C06, NONE), + PAD_NC(GPP_C07, NONE), + PAD_CFG_GPO(GPP_C08, 1, DEEP), + PAD_CFG_GPO(GPP_C09, 1, DEEP), + PAD_CFG_GPO(GPP_C10, 1, DEEP), + PAD_CFG_GPO(GPP_C11, 1, DEEP), + PAD_CFG_NF(GPP_C12, NONE, PLTRST, NF1), + PAD_CFG_NF(GPP_C13, NONE, PLTRST, NF1), + PAD_CFG_NF(GPP_C14, NONE, PLTRST, NF1), + PAD_CFG_GPO(GPP_C15, 1, DEEP), + //TODO PAD_CFG_NF(GPP_C16, NONE, TODO_0xc4000700, NF1), + //TODO PAD_CFG_NF(GPP_C17, NONE, TODO_0xc4000700, NF1), + PAD_CFG_GPO(GPP_C18, 1, DEEP), + PAD_CFG_GPO(GPP_C19, 1, DEEP), + PAD_CFG_GPO(GPP_C20, 1, DEEP), + PAD_CFG_GPO(GPP_C21, 1, DEEP), + PAD_CFG_NF(GPP_C22, NONE, DEEP, NF2), + PAD_CFG_NF(GPP_C23, NONE, DEEP, NF2), + PAD_CFG_GPO(GPP_D00, 1, PLTRST), + PAD_CFG_GPO(GPP_D01, 1, DEEP), + PAD_CFG_GPO(GPP_D02, 1, DEEP), + PAD_CFG_GPO(GPP_D03, 1, DEEP), + PAD_CFG_GPO(GPP_D04, 1, DEEP), + PAD_CFG_GPO(GPP_D05, 1, DEEP), + PAD_CFG_GPO(GPP_D06, 1, DEEP), + PAD_CFG_GPO(GPP_D07, 1, DEEP), + PAD_CFG_GPO(GPP_D08, 1, DEEP), + PAD_CFG_GPO(GPP_D09, 1, DEEP), + PAD_CFG_NF(GPP_D10, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_D11, NATIVE, DEEP, NF1), + PAD_CFG_NF(GPP_D12, NATIVE, DEEP, NF1), + PAD_CFG_NF(GPP_D13, NATIVE, DEEP, NF1), + PAD_CFG_GPO(GPP_D14, 1, DEEP), + PAD_NC(GPP_D15, NONE), + PAD_CFG_NF(GPP_D16, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_D17, 1, DEEP), + PAD_CFG_NF(GPP_D18, NONE, PLTRST, NF1), + PAD_CFG_GPO(GPP_D19, 1, PLTRST), + PAD_CFG_GPO(GPP_D20, 1, DEEP), + PAD_CFG_GPO(GPP_D21, 1, DEEP), + PAD_CFG_NF(GPP_D22, NATIVE, DEEP, NF1), + PAD_CFG_NF(GPP_D23, NATIVE, DEEP, NF1), + PAD_CFG_GPO(GPP_D24, 1, DEEP), + PAD_CFG_GPO(GPP_D25, 1, DEEP), + _PAD_CFG_STRUCT(GPP_E01, 0x42880100, 0x0000), + PAD_NC(GPP_E02, NONE), + PAD_CFG_GPO(GPP_E03, 1, DEEP), + PAD_CFG_GPO(GPP_E04, 1, DEEP), + PAD_CFG_GPO(GPP_E05, 1, DEEP), + PAD_CFG_GPO(GPP_E06, 1, DEEP), + PAD_CFG_GPO(GPP_E07, 1, DEEP), + PAD_NC(GPP_E08, NONE), + PAD_NC(GPP_E09, NONE), + PAD_CFG_GPO(GPP_E10, 1, DEEP), + PAD_CFG_GPI(GPP_E11, NONE, DEEP), + _PAD_CFG_STRUCT(GPP_E12, 0x44002300, 0x0000), + _PAD_CFG_STRUCT(GPP_E13, 0x44002300, 0x0000), + PAD_CFG_GPI(GPP_E14, NONE, DEEP), + PAD_CFG_GPI(GPP_E15, NONE, DEEP), + PAD_CFG_GPO(GPP_E16, 1, DEEP), + PAD_CFG_GPI(GPP_E17, NONE, DEEP), + PAD_CFG_GPO(GPP_E18, 1, DEEP), + PAD_CFG_GPO(GPP_E19, 1, DEEP), + PAD_CFG_GPO(GPP_E20, 1, DEEP), + PAD_CFG_NF(GPP_E21, NONE, PWROK, NF1), + PAD_CFG_GPO(GPP_E22, 1, DEEP), + PAD_CFG_NF(GPP_F00, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_F01, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_F02, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_F03, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_F04, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_F05, NONE, DEEP, NF3), + PAD_CFG_GPO(GPP_F06, 1, DEEP), + PAD_CFG_GPO(GPP_F07, 1, DEEP), + PAD_CFG_GPO(GPP_F08, 1, DEEP), + PAD_CFG_GPI(GPP_F09, NONE, DEEP), + PAD_CFG_GPO(GPP_F10, 1, DEEP), + PAD_CFG_GPO(GPP_F11, 1, DEEP), + _PAD_CFG_STRUCT(GPP_F12, 0x44002300, 0x0000), + _PAD_CFG_STRUCT(GPP_F13, 0x44002300, 0x0000), + PAD_CFG_GPO(GPP_F14, 1, DEEP), + PAD_CFG_GPO(GPP_F15, 1, DEEP), + PAD_CFG_GPO(GPP_F16, 1, PLTRST), + PAD_CFG_GPO(GPP_F17, 1, DEEP), + _PAD_CFG_STRUCT(GPP_F18, 0x80800100, 0x0000), + PAD_CFG_GPO(GPP_F19, 1, DEEP), + PAD_CFG_GPO(GPP_F20, 1, DEEP), + PAD_CFG_GPO(GPP_F21, 1, DEEP), + PAD_CFG_GPO(GPP_F22, 1, DEEP), + PAD_CFG_GPO(GPP_F23, 1, DEEP), + PAD_CFG_NF(GPP_H00, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H01, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H02, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H03, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H04, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H05, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H06, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_H07, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_H09, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_H10, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_H11, DN_20K, DEEP, NF1), + //TODO: PAD_CFG_NF(GPP_H12, TODO_0x2400, DEEP, NF1), + PAD_CFG_NF(GPP_H13, DN_20K, DEEP, NF1), + PAD_CFG_NF(GPP_H14, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_H15, 1, DEEP), + PAD_CFG_GPO(GPP_H16, 1, DEEP), + PAD_CFG_GPO(GPP_H17, 1, DEEP), + PAD_NC(GPP_H18, NONE), + _PAD_CFG_STRUCT(GPP_H19, 0x44000601, 0x0000), + _PAD_CFG_STRUCT(GPP_H20, 0x44000601, 0x0000), + PAD_CFG_GPO(GPP_H21, 1, DEEP), + PAD_CFG_GPO(GPP_H22, 1, DEEP), + PAD_NC(GPP_H23, NONE), + PAD_NC(GPP_H24, NONE), + PAD_CFG_GPO(GPP_S00, 1, DEEP), + PAD_CFG_GPO(GPP_S01, 1, DEEP), + PAD_CFG_GPO(GPP_S02, 1, DEEP), + PAD_CFG_GPO(GPP_S03, 1, DEEP), + PAD_CFG_GPO(GPP_S04, 1, DEEP), + PAD_CFG_GPO(GPP_S05, 1, DEEP), + PAD_CFG_GPO(GPP_S06, 1, DEEP), + PAD_CFG_GPO(GPP_S07, 1, DEEP), + PAD_CFG_NF(GPP_V00, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_V01, NATIVE, DEEP, NF1), + PAD_CFG_NF(GPP_V02, NATIVE, DEEP, NF1), + PAD_CFG_NF(GPP_V03, UP_20K, DEEP, NF1), + PAD_CFG_NF(GPP_V04, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_V05, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_V06, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_V07, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_V08, 1, DEEP), + PAD_CFG_GPO(GPP_V09, 1, DEEP), + PAD_CFG_GPO(GPP_V10, 1, DEEP), + PAD_CFG_GPO(GPP_V11, 1, DEEP), + PAD_CFG_NF(GPP_V12, NONE, DEEP, NF1), + _PAD_CFG_STRUCT(GPP_V13, 0x44000601, 0x0000), + _PAD_CFG_STRUCT(GPP_V14, 0x44000601, 0x0000), + _PAD_CFG_STRUCT(GPP_V15, 0x44000601, 0x0000), + PAD_CFG_NF(GPP_V16, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_V17, 1, DEEP), +}; + +void mainboard_configure_gpios(void) +{ + gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table)); +} diff --git a/src/mainboard/system76/ptl/variants/lemp14/gpio_early.c b/src/mainboard/system76/ptl/variants/lemp14/gpio_early.c new file mode 100644 index 00000000000..46ed8112dc5 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/gpio_early.c @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config early_gpio_table[] = { + PAD_CFG_GPI(GPP_E11, NONE, DEEP), // BOARD_ID1 + PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), // UART0_RX + PAD_CFG_NF(GPP_H09, NONE, DEEP, NF1), // UART0_TX +}; + +void mainboard_configure_early_gpios(void) +{ + gpio_configure_pads(early_gpio_table, ARRAY_SIZE(early_gpio_table)); +} diff --git a/src/mainboard/system76/ptl/variants/lemp14/hda_verb.c b/src/mainboard/system76/ptl/variants/lemp14/hda_verb.c new file mode 100644 index 00000000000..004c6fc6851 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/hda_verb.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +const u32 cim_verb_data[] = { + /* Realtek, ALC245 */ + 0x10ec0245, /* Vendor ID */ + 0x15582a00, /* Subsystem ID */ + 34, /* Number of entries */ + + AZALIA_SUBVENDOR(0, 0x15582a00), + AZALIA_RESET(1), + AZALIA_PIN_CFG(0, 0x12, 0x90a60130), + AZALIA_PIN_CFG(0, 0x13, 0x40000000), + AZALIA_PIN_CFG(0, 0x14, 0x411111f0), + AZALIA_PIN_CFG(0, 0x17, 0x90170110), + AZALIA_PIN_CFG(0, 0x18, 0x411111f0), + AZALIA_PIN_CFG(0, 0x19, 0x411111f0), + AZALIA_PIN_CFG(0, 0x1a, 0x411111f0), + AZALIA_PIN_CFG(0, 0x1b, 0x411111f0), + AZALIA_PIN_CFG(0, 0x1d, 0x41789b2d), + AZALIA_PIN_CFG(0, 0x1e, 0x411111f0), + AZALIA_PIN_CFG(0, 0x21, 0x04211020), + + //TODO: VERIFY THESE COMMANDS + 0x05b50006, 0x05b40011, 0x0205001a, 0x0204810b, + 0x0205004a, 0x02042010, 0x02050038, 0x02046909, + 0x05c50000, 0x05c43d82, 0x05c50000, 0x05c43d82, + 0x05350000, 0x0534201a, 0x05350000, 0x0534201a, + 0x0535001d, 0x05340800, 0x0535001e, 0x05340800, + 0x05350003, 0x05341ec4, 0x05350004, 0x05340000, + 0x05450000, 0x05442000, 0x0545001d, 0x05440800, + 0x0545001e, 0x05440800, 0x05450003, 0x05441ec4, + 0x05450004, 0x05440000, 0x05350000, 0x0534a01a, + 0x0205003c, 0x0204f175, 0x0205003c, 0x0204f135, + 0x02050040, 0x02048800, 0x05a50001, 0x05a4001f, + 0x02050010, 0x02040020, 0x02050010, 0x02040020, + 0x0205006b, 0x0204a390, 0x0205006b, 0x0204a390, + 0x0205006c, 0x02040c9e, 0x0205006d, 0x02040c00, + 0x00170500, 0x00170500, 0x05a50004, 0x05a40113, + 0x02050008, 0x02046a8c, 0x02050076, 0x0204f000, + 0x0205000e, 0x020465c0, 0x02050033, 0x02048580, + 0x02050069, 0x0204fda8, 0x02050068, 0x02040000, + 0x02050003, 0x02040002, 0x02050069, 0x02040000, + 0x02050068, 0x02040001, 0x0205002e, 0x0204290e, + 0x02050010, 0x02040020, 0x02050010, 0x02040020, +}; + +const u32 pc_beep_verbs[] = {}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/system76/ptl/variants/lemp14/overridetree.cb b/src/mainboard/system76/ptl/variants/lemp14/overridetree.cb new file mode 100644 index 00000000000..3193b169a71 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/overridetree.cb @@ -0,0 +1,112 @@ +# SPDX-License-Identifier: GPL-2.0-only + +chip soc/intel/pantherlake + #TODO: POWER LIMITS + #register "power_limits_config[RPL_P_282_242_142_15W_CORE]" = "{ + # .tdp_pl1_override = 15, + # .tdp_pl2_override = 46, + #}" + + device domain 0 on + subsystemid 0x1558 0x2a00 inherit + + device ref tbt_pcie_rp0 on end + device ref tcss_xhci on + register "tcss_ports[0]" = "TCSS_PORT_DEFAULT(OC_SKIP)" + #TODO: TCP1 goes to redriver, then USB Type-C + register "tcss_ports[1]" = "TCSS_PORT_DEFAULT(OC_SKIP)" + #TODO: TCP2 is used as USB Type-A + register "tcss_ports[2]" = "TCSS_PORT_DEFAULT(OC_SKIP)" + #TODO: TCP3 is used as HDMI + chip drivers/usb/acpi + device ref tcss_root_hub on + chip drivers/usb/acpi + register "desc" = ""TBT Type-C"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + device ref tcss_usb3_port0 on end + end + chip drivers/usb/acpi + register "desc" = ""USB Type-C"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + device ref tcss_usb3_port1 on end + end + chip drivers/usb/acpi + register "desc" = ""USB Type-A"" + register "type" = "UPC_TYPE_USB3_A" + device ref tcss_usb3_port2 on end + end + end + end + end + device ref tcss_dma0 on end + device ref xhci on + register "usb2_ports" = "{ + [0] = USB2_PORT_TYPE_C(OC_SKIP), /* USB Type-C */ + [1] = USB2_PORT_TYPE_C(OC_SKIP), /* TBT Type-C */ + [2] = USB2_PORT_MID(OC_SKIP), /* USB 3.2 Gen 2 Type-A */ + [4] = USB2_PORT_MID(OC_SKIP), /* USB 3.2 Gen 1 Type-A */ + [6] = USB2_PORT_MID(OC_SKIP), /* Camera */ + [7] = USB2_PORT_MID(OC_SKIP), /* Bluetooth */ + }" + register "usb3_ports" = "{ + [0] = USB3_PORT_DEFAULT(OC_SKIP), /* USB 3.2 Gen 1 Type-A */ + }" + end + + device ref i2c4 on + # Smart Amplifier I2C bus + register "serial_io_i2c_mode[PchSerialIoIndexI2C4]" = "PchSerialIoPci" + chip drivers/i2c/tas5825m + register "id" = "0" + device i2c 4e on end # (8bit address: 0x9c) + end + end + device ref i2c5 on + # Touchpad I2C bus + register "serial_io_i2c_mode[PchSerialIoIndexI2C5]" = "PchSerialIoPci" + chip drivers/i2c/hid + register "generic.hid" = ""ELAN0412"" + register "generic.desc" = ""ELAN Touchpad"" + register "generic.irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_A17)" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 15 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""FTCS1000"" + register "generic.desc" = ""FocalTech Touchpad"" + register "generic.irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_A17)" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 38 on end + end + end + + device ref pcie_rp1 on + # CPU RP#1 x4, Clock 6 (SSD1) + register "pcie_rp[PCIE_RP(1)]" = "{ + .clk_src = 6, + .clk_req = 6, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "M.2/M 2280 (J_SSD1)" "SlotDataBusWidth4X" + end + device ref pcie_rp7 on + # PCH RP#7 x1, Clock 3 (CARD) + register "pcie_rp[PCH_RP(7)]" = "{ + .clk_src = 3, + .clk_req = 3, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + device ref pcie_rp8 on + # PCH RP#8 x1, Clock 4 (WLAN) + register "pcie_rp[PCH_RP(8)]" = "{ + .clk_src = 4, + .clk_req = 4, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + smbios_slot_desc "SlotTypeM2Socket1_SD" "SlotLengthOther" "M.2/E 2230 (J_WLAN1)" "SlotDataBusWidth1X" + end + end +end diff --git a/src/mainboard/system76/ptl/variants/lemp14/ramstage.c b/src/mainboard/system76/ptl/variants/lemp14/ramstage.c new file mode 100644 index 00000000000..9118fea7e96 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/ramstage.c @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +void mainboard_silicon_init_params(FSP_S_CONFIG *params) +{ + // TODO: Pin Mux settings + + // Enable TCP2 USB-A conversion + // BIT 0:3 is mapping to PCH XHCI USB2 port + // BIT 4:5 is reserved + // BIT 6 is orientational + // BIT 7 is enable + params->EnableTcssCovTypeA[2] = 0x83; + + // Disable reporting CPU C10 state over eSPI (causes LED flicker). + params->PchEspiHostC10ReportEnable = 0; +} diff --git a/src/mainboard/system76/ptl/variants/lemp14/romstage.c b/src/mainboard/system76/ptl/variants/lemp14/romstage.c new file mode 100644 index 00000000000..03aec239999 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/romstage.c @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +// Verified from lemp14 schematic mappings +static const struct mb_cfg board_cfg = { + .type = MEM_TYPE_LP5X, + + .lpx_dq_map = { + .ddr0 = { + .dq0 = { 13, 14, 12, 15, 11, 10, 8, 9, }, + .dq1 = { 7, 5, 4, 6, 0, 3, 1, 2 }, + }, + .ddr1 = { + .dq0 = { 1, 3, 0, 2, 7, 4, 6, 5, }, + .dq1 = { 12, 13, 14, 15, 11, 10, 9, 8 }, + }, + .ddr2 = { + .dq0 = { 0, 2, 1, 3, 6, 4, 7, 5 }, + .dq1 = { 14, 13, 15, 12, 8, 11, 10, 9, }, + }, + .ddr3 = { + .dq0 = { 6, 5, 7, 4, 2, 3, 1, 0, }, + .dq1 = { 10, 8, 11, 9, 12, 15, 13, 14 }, + }, + .ddr4 = { + .dq0 = { 2, 1, 3, 0, 4, 7, 5, 6 }, + .dq1 = { 15, 14, 12, 13, 9, 11, 10, 8, }, + }, + .ddr5 = { + .dq0 = { 6, 5, 7, 4, 3, 1, 0, 2, }, + .dq1 = { 10, 9, 11, 8, 13, 14, 12, 15 }, + }, + .ddr6 = { + .dq0 = { 9, 10, 11, 8, 14, 12, 13, 15, }, + .dq1 = { 0, 1, 2, 3, 5, 7, 4, 6 }, + }, + .ddr7 = { + .dq0 = { 0, 1, 2, 3, 7, 5, 6, 4, }, + .dq1 = { 14, 13, 15, 12, 10, 8, 11, 9 }, + }, + }, + + .lpx_dqs_map = { + .ddr0 = { .dqs0 = 1, .dqs1 = 0 }, + .ddr1 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr2 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr3 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr4 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr5 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr6 = { .dqs0 = 1, .dqs1 = 0 }, + .ddr7 = { .dqs0 = 0, .dqs1 = 1 } + }, + + .ect = true, /* Early Command Training */ + + .user_bd = BOARD_TYPE_ULT_ULX, + + .lp5x_config = { + .ccc_config = 0xFF, + }, +}; + + + +static size_t get_spd_index(void) +{ + if (gpio_get(GPP_E11)) { + // If BOARD_ID1 is high, the system has 16 GB of RAM using 4x32Gb modules + return 0; + } else { + // If BOARD_ID1 is low, the system has 32 GB of RAM using 4x64Gb modules + return 1; + } +} + +void mainboard_memory_init_params(FSPM_UPD *mupd) +{ + + const struct mem_spd spd_info = { + .topo = MEM_TOPO_MEMORY_DOWN, + .cbfs_index = get_spd_index(), + }; + const bool half_populated = false; + + mupd->FspmConfig.GpioOverride = 0; + + memcfg_init(mupd, &board_cfg, &spd_info, half_populated); +} diff --git a/src/mainboard/system76/ptl/variants/lemp14/tas5825m.c b/src/mainboard/system76/ptl/variants/lemp14/tas5825m.c new file mode 100644 index 00000000000..171d9c1ed20 --- /dev/null +++ b/src/mainboard/system76/ptl/variants/lemp14/tas5825m.c @@ -0,0 +1,1049 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +int tas5825m_setup(struct device *dev, int id) +{ + int res; + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x01, 0x11); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + mdelay(5); + + res = tas5825m_write_at(dev, 0x03, 0x12); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x48, 0x0C); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x7F, 0x64); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0xFE, 0x00, 0x40, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x50, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x00, 0x82, 0x00, 0x93, 0x00, 0xFC, 0x00, 0x00, + 0x8F, 0x00, 0xFF, 0xEF, 0x84, 0x49, 0x03, 0x27, + 0x84, 0x02, 0x04, 0x06, 0x02, 0x60, 0x00, 0x01, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0x70, 0x00, 0x06, 0x02, 0x78, 0x00, 0x05, + 0x02, 0x68, 0x00, 0x02, 0x02, 0x28, 0x03, 0x4D, + 0x84, 0x2A, 0x04, 0x00, 0xE2, 0x57, 0x91, 0x9F, + 0x84, 0x82, 0x20, 0xE0, 0x84, 0x82, 0x04, 0x01, + 0xF0, 0x1C, 0x31, 0xA0, 0xF0, 0x1C, 0x31, 0xA1, + 0xF0, 0x1C, 0x31, 0xA2, 0xF0, 0x1F, 0x31, 0xA3, + 0xE4, 0x00, 0x11, 0xA6, 0x80, 0x27, 0x80, 0xE1, + 0xF4, 0x00, 0x11, 0xA4, 0xF4, 0x1D, 0x31, 0xA5, + 0xF4, 0x1C, 0x31, 0xA7, 0xF4, 0x1F, 0x31, 0xA8, + 0x02, 0x78, 0x00, 0x03, 0xE2, 0x68, 0xF1, 0xC3, + 0x80, 0x67, 0x80, 0xE9, 0x84, 0x4B, 0x03, 0x27, + 0x02, 0x70, 0x00, 0x04, 0x84, 0x41, 0x03, 0x37, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x00, 0x11, 0xA9, + 0x84, 0x82, 0x00, 0xE0, 0x8E, 0xFC, 0x04, 0x10, + 0xF0, 0x1C, 0x11, 0xAA, 0xF0, 0x1C, 0x11, 0xAB, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x03); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xF0, 0x1C, 0x11, 0xAC, 0xF0, 0x1F, 0x11, 0xAD, + 0x86, 0xA1, 0x01, 0xC2, 0x80, 0x27, 0x80, 0xE8, + 0x60, 0x00, 0x00, 0x00, 0x84, 0x43, 0x03, 0x37, + 0x80, 0x00, 0x00, 0x81, 0x0D, 0x00, 0x10, 0x20, + 0x84, 0x51, 0x03, 0x3E, 0x08, 0x44, 0x26, 0x30, + 0x84, 0xC3, 0x03, 0x47, 0x84, 0xC2, 0x40, 0xE0, + 0x8C, 0xFF, 0x03, 0x23, 0xE0, 0x10, 0x11, 0xB3, + 0xF0, 0x1C, 0x51, 0xB4, 0xF0, 0x1C, 0x51, 0xB5, + 0xF0, 0x1C, 0x51, 0xB6, 0xF0, 0x1F, 0x51, 0xB7, + 0x86, 0xA1, 0x01, 0xC6, 0x80, 0x27, 0x80, 0xEA, + 0x84, 0x53, 0x03, 0x3E, 0x84, 0x82, 0x04, 0x05, + 0x84, 0x51, 0x03, 0x75, 0xE2, 0x6B, 0xC0, 0x00, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x80, 0x31, 0xB8, + 0x84, 0x82, 0x40, 0xE0, 0xF0, 0x1C, 0x51, 0xB9, + 0xF0, 0x1C, 0x51, 0xBA, 0xF0, 0x1C, 0x51, 0xBB, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x04); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xF0, 0x1F, 0x51, 0xBC, 0x86, 0xA1, 0x01, 0xC5, + 0x80, 0x27, 0x80, 0xEA, 0x60, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x81, 0x84, 0xA1, 0x03, 0x4F, + 0xE0, 0x80, 0xA0, 0x00, 0x01, 0x07, 0x11, 0x20, + 0x08, 0x44, 0x26, 0x30, 0x08, 0x00, 0x98, 0x4A, + 0x84, 0x53, 0x03, 0x75, 0x08, 0x00, 0x30, 0x48, + 0x02, 0xCA, 0x00, 0x01, 0x08, 0x60, 0x26, 0x32, + 0x84, 0x51, 0x03, 0x45, 0xE4, 0x10, 0x40, 0x00, + 0x80, 0x40, 0xC0, 0x82, 0x84, 0xC2, 0x40, 0xE0, + 0x84, 0xC3, 0x03, 0x5E, 0x08, 0x00, 0x50, 0x48, + 0xE0, 0x10, 0x11, 0xBD, 0x02, 0xC2, 0x00, 0x02, + 0x08, 0x60, 0x06, 0x12, 0x84, 0xD3, 0x03, 0x4F, + 0xF0, 0x1C, 0x51, 0xBE, 0xF0, 0x1C, 0x51, 0xBF, + 0xF0, 0x1C, 0x51, 0xC0, 0xF0, 0x1F, 0x51, 0xC1, + 0x84, 0xA1, 0x03, 0x65, 0x80, 0x27, 0x80, 0xEA, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x05); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x83, + 0x08, 0x00, 0x98, 0x6B, 0x08, 0x00, 0x30, 0x68, + 0x84, 0x53, 0x03, 0x45, 0x08, 0x60, 0x26, 0x33, + 0x84, 0x51, 0x03, 0x25, 0xE4, 0x10, 0x60, 0x00, + 0x80, 0x40, 0xC0, 0x81, 0x02, 0x70, 0x00, 0x7F, + 0x08, 0x00, 0x50, 0x28, 0x08, 0x60, 0x06, 0x11, + 0x84, 0xCB, 0x03, 0x65, 0xE0, 0x10, 0x51, 0xC4, + 0x84, 0x80, 0x41, 0x00, 0x02, 0xA3, 0x00, 0x10, + 0xE4, 0x00, 0x00, 0x00, 0x84, 0xD0, 0x04, 0x01, + 0x84, 0xA2, 0x04, 0x03, 0x84, 0xD2, 0x50, 0x01, + 0x84, 0x53, 0x03, 0x25, 0x80, 0x00, 0xC4, 0x04, + 0x8F, 0x30, 0x00, 0x00, 0x88, 0x67, 0x03, 0x00, + 0xE4, 0x00, 0x11, 0x9B, 0xEE, 0x64, 0x60, 0x00, + 0x02, 0xD3, 0x00, 0x10, 0x88, 0x47, 0x00, 0x80, + 0x10, 0x00, 0x18, 0x02, 0x86, 0xC1, 0x01, 0x9D, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x06); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x10, 0x31, 0xC7, 0x86, 0xC9, 0x01, 0x9E, + 0x80, 0x00, 0xC4, 0x02, 0x02, 0x50, 0x01, 0x9C, + 0x00, 0xFF, 0x21, 0x65, 0x00, 0xFC, 0x00, 0x00, + 0x02, 0x60, 0x00, 0x01, 0x02, 0x70, 0x00, 0x04, + 0x84, 0xC8, 0x04, 0x10, 0x84, 0x41, 0x03, 0x67, + 0x84, 0x51, 0x03, 0x6D, 0x84, 0xC0, 0x04, 0x02, + 0x04, 0x80, 0x91, 0x20, 0x08, 0x60, 0x26, 0x30, + 0x02, 0x78, 0x00, 0x03, 0x02, 0x68, 0x00, 0x02, + 0x0D, 0x00, 0x10, 0x10, 0x08, 0x60, 0x06, 0x12, + 0x84, 0x49, 0x03, 0x2F, 0xE0, 0x80, 0x71, 0xA9, + 0x02, 0x28, 0x03, 0x55, 0x84, 0x82, 0x00, 0xE0, + 0x84, 0x2A, 0x04, 0x00, 0xF0, 0x1C, 0x11, 0xAA, + 0xF0, 0x1C, 0x11, 0xAB, 0xF0, 0x1C, 0x11, 0xAC, + 0xF0, 0x1F, 0x11, 0xAD, 0x86, 0xA1, 0x01, 0xAE, + 0x80, 0x27, 0x80, 0xE8, 0x84, 0x82, 0x04, 0x07, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x07); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0xE0, 0x80, 0x60, 0x00, 0x84, 0x82, 0x40, 0xE0, + 0x84, 0x43, 0x03, 0x67, 0xF0, 0x1C, 0x51, 0xAF, + 0xF0, 0x1C, 0x51, 0xB0, 0xF0, 0x1C, 0x51, 0xB1, + 0xF0, 0x1F, 0x51, 0xB2, 0x02, 0x78, 0x00, 0x05, + 0x80, 0x27, 0x80, 0xEA, 0x84, 0x82, 0x04, 0x08, + 0x02, 0x70, 0x00, 0x06, 0x84, 0x53, 0x03, 0x6D, + 0x84, 0x80, 0x04, 0x07, 0xE0, 0x00, 0x00, 0x82, + 0xF0, 0x81, 0x00, 0x80, 0x80, 0x07, 0x12, 0xBC, + 0x86, 0xA1, 0x01, 0x9F, 0xE2, 0x57, 0xA0, 0x00, + 0x84, 0x82, 0x04, 0x09, 0x84, 0x82, 0x20, 0xE0, + 0xF0, 0x1C, 0x31, 0xA0, 0xF0, 0x1C, 0x31, 0xA1, + 0xF0, 0x1C, 0x31, 0xA2, 0xF0, 0x1F, 0x31, 0xA3, + 0xE4, 0x00, 0x11, 0xA6, 0x80, 0x27, 0x80, 0xE1, + 0xF4, 0x00, 0x11, 0xA4, 0xF4, 0x1D, 0x31, 0xA5, + 0xF4, 0x1C, 0x31, 0xA7, 0xF4, 0x1F, 0x31, 0xA8, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x08); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0x78, 0x00, 0x03, 0xE2, 0x6A, 0xF1, 0xC3, + 0x80, 0x67, 0x80, 0xE9, 0x84, 0x4B, 0x03, 0x2F, + 0x02, 0x70, 0x00, 0x04, 0x84, 0x59, 0x03, 0x3D, + 0x80, 0x07, 0x00, 0x80, 0xE0, 0x00, 0x11, 0xA9, + 0x84, 0x82, 0x60, 0xE0, 0x8E, 0xFC, 0x04, 0x10, + 0xF0, 0x1C, 0x71, 0xAA, 0xF0, 0x1C, 0x71, 0xAB, + 0xF0, 0x1C, 0x71, 0xAC, 0xF0, 0x1F, 0x71, 0xAD, + 0x86, 0xA1, 0x01, 0xC2, 0x80, 0x27, 0x80, 0xEB, + 0x60, 0x00, 0x00, 0x00, 0x84, 0x5B, 0x03, 0x3D, + 0x80, 0x00, 0x00, 0x81, 0x0D, 0x00, 0x10, 0x20, + 0x84, 0x59, 0x03, 0x3F, 0x08, 0x44, 0x26, 0x30, + 0x84, 0xC3, 0x03, 0x57, 0x84, 0xC2, 0x60, 0xE0, + 0xE0, 0x10, 0x11, 0xB3, 0xF0, 0x1C, 0x71, 0xB4, + 0xF0, 0x1C, 0x71, 0xB5, 0xF0, 0x1C, 0x71, 0xB6, + 0xF0, 0x1F, 0x71, 0xB7, 0x86, 0xA1, 0x01, 0xC6, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x09); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x80, 0x27, 0x80, 0xEB, 0x84, 0x5B, 0x03, 0x3F, + 0x84, 0x82, 0x04, 0x0D, 0x84, 0x41, 0x03, 0x76, + 0xE2, 0x6B, 0xE0, 0x00, 0x80, 0x07, 0x00, 0x80, + 0xE0, 0x81, 0x31, 0xB8, 0x84, 0x82, 0x00, 0xE0, + 0xF0, 0x1C, 0x11, 0xB9, 0xF0, 0x1C, 0x11, 0xBA, + 0xF0, 0x1C, 0x11, 0xBB, 0xF0, 0x1F, 0x11, 0xBC, + 0x86, 0xA1, 0x01, 0xC5, 0x80, 0x27, 0x80, 0xE8, + 0x60, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x81, + 0x84, 0xA1, 0x03, 0x5D, 0xE0, 0x81, 0xA0, 0x00, + 0x01, 0x07, 0x11, 0x20, 0x08, 0x44, 0x26, 0x30, + 0x08, 0x00, 0x98, 0x4A, 0x84, 0x43, 0x03, 0x76, + 0x08, 0x00, 0x30, 0x48, 0x02, 0xCA, 0x00, 0x01, + 0x08, 0x60, 0x26, 0x32, 0x84, 0x41, 0x03, 0x46, + 0xE4, 0x10, 0x40, 0x00, 0x80, 0x40, 0xC0, 0x82, + 0x84, 0xC2, 0x00, 0xE0, 0x84, 0xC3, 0x03, 0x5F, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0A); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x50, 0x48, 0xE0, 0x10, 0x11, 0xBD, + 0x02, 0xC2, 0x00, 0x02, 0x08, 0x60, 0x06, 0x12, + 0x84, 0xD3, 0x03, 0x5D, 0xF0, 0x1C, 0x11, 0xBE, + 0xF0, 0x1C, 0x11, 0xBF, 0xF0, 0x1C, 0x11, 0xC0, + 0xF0, 0x1F, 0x11, 0xC1, 0x84, 0xA1, 0x03, 0x66, + 0x80, 0x27, 0x80, 0xE8, 0xE0, 0x00, 0x00, 0x00, + 0x80, 0x07, 0x00, 0x83, 0x08, 0x00, 0x98, 0x6B, + 0x08, 0x00, 0x30, 0x68, 0x84, 0x43, 0x03, 0x46, + 0x08, 0x60, 0x26, 0x33, 0x84, 0x51, 0x03, 0x26, + 0xE4, 0x10, 0x60, 0x00, 0x80, 0x40, 0xC0, 0x81, + 0x02, 0x70, 0x00, 0x7F, 0x08, 0x00, 0x50, 0x28, + 0x08, 0x60, 0x06, 0x11, 0x8C, 0xFF, 0x03, 0x24, + 0x84, 0xCB, 0x03, 0x66, 0xE0, 0x10, 0x51, 0xC4, + 0x84, 0x80, 0x41, 0x00, 0x02, 0xA3, 0x00, 0x10, + 0xE4, 0x00, 0x00, 0x00, 0x84, 0xD0, 0x04, 0x09, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x84, 0xA2, 0x04, 0x0B, 0x84, 0xD2, 0x50, 0x01, + 0x84, 0x53, 0x03, 0x26, 0x80, 0x00, 0xC4, 0x0C, + 0x8F, 0x30, 0x00, 0x00, 0x88, 0x67, 0x03, 0x00, + 0xE4, 0x00, 0x11, 0x9B, 0xEE, 0x64, 0x80, 0x00, + 0x02, 0xD3, 0x00, 0x10, 0x88, 0x47, 0x00, 0x80, + 0x10, 0x00, 0x18, 0x02, 0x86, 0xC1, 0x01, 0x9D, + 0xE0, 0x10, 0x31, 0xC7, 0x86, 0xC9, 0x01, 0x9E, + 0x80, 0x00, 0xC4, 0x0A, 0x02, 0x50, 0x01, 0x9C, + 0x00, 0xFF, 0x21, 0x65, 0x00, 0xFC, 0x00, 0x00, + 0x02, 0x70, 0x00, 0x04, 0x02, 0x68, 0x00, 0x01, + 0x02, 0x60, 0x00, 0x03, 0x02, 0x78, 0x00, 0x02, + 0x84, 0x49, 0x03, 0x6E, 0x84, 0x41, 0x03, 0x6F, + 0x84, 0xC8, 0x04, 0x10, 0x84, 0xC0, 0x04, 0x0A, + 0x04, 0x81, 0x91, 0x20, 0x08, 0x60, 0x26, 0x30, + 0x0D, 0x00, 0x10, 0x10, 0x08, 0x60, 0x06, 0x12, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x84, 0x00, 0x04, 0x06, 0xE0, 0x81, 0x71, 0xA9, + 0x84, 0x82, 0x20, 0xE8, 0xF0, 0x1D, 0x31, 0xAA, + 0xF0, 0x1D, 0x31, 0xAB, 0xF0, 0x1D, 0x31, 0xAC, + 0xF0, 0x1C, 0x31, 0xAD, 0x86, 0xA1, 0x01, 0xAE, + 0x80, 0x27, 0x80, 0xF9, 0x84, 0x82, 0x04, 0x0E, + 0xE0, 0x81, 0x60, 0x00, 0x84, 0x82, 0x00, 0xE8, + 0x84, 0x4B, 0x03, 0x6E, 0xF0, 0x1D, 0x11, 0xAF, + 0xF0, 0x1D, 0x11, 0xB0, 0xF0, 0x1D, 0x11, 0xB1, + 0xF0, 0x1C, 0x11, 0xB2, 0x02, 0xA3, 0x00, 0x1A, + 0x80, 0x27, 0x80, 0xF8, 0x84, 0x82, 0x04, 0x0F, + 0xE0, 0x81, 0xC0, 0x00, 0xF0, 0x81, 0xE0, 0x80, + 0x84, 0x43, 0x03, 0x6F, 0x80, 0x07, 0x12, 0xBD, + 0x02, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0x50, 0x00, + 0x8F, 0x00, 0x00, 0x11, 0x8F, 0x00, 0xFF, 0xFF, + 0x84, 0x58, 0x04, 0x01, 0x84, 0xC2, 0x04, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x02, 0xC2, 0x60, 0x00, 0x84, 0xA0, 0x61, 0x00, + 0xE0, 0x20, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, + 0x40, 0x40, 0xA0, 0x00, 0x80, 0x00, 0xC0, 0x82, + 0x08, 0xFC, 0x48, 0x3A, 0x08, 0xFC, 0x18, 0x50, + 0x00, 0xFC, 0x00, 0x00, 0xE0, 0x10, 0x00, 0x00, + 0x86, 0xA0, 0x41, 0x00, 0x40, 0x47, 0x20, 0x00, + 0x80, 0x00, 0xC0, 0x83, 0x04, 0xE0, 0x3D, 0x1E, + 0x04, 0x80, 0x11, 0xE0, 0x08, 0x44, 0x26, 0x33, + 0x02, 0xCB, 0x00, 0x10, 0xE0, 0x10, 0x40, 0x83, + 0x08, 0x00, 0x28, 0x21, 0x84, 0xCA, 0x61, 0x00, + 0x80, 0x07, 0x00, 0x81, 0x0C, 0xE0, 0x2C, 0x09, + 0x84, 0xCA, 0x21, 0x00, 0x00, 0xFC, 0x50, 0x00, + 0x8F, 0x00, 0x00, 0x01, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x78); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x18); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x30, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x03, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1C); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x1C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x3C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x40, 0x00, 0x00, 0x03, 0x48, + 0x00, 0x00, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x54, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x58, 0x00, 0x00, 0x03, 0x60, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x74, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1D); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x1C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x3C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x1E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x0C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x03, 0x70, 0x00, 0x00, 0x03, 0x78, + 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x24, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x04, 0x88, 0x00, 0x00, 0x04, 0x90, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x44, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x8C); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0xA7, 0x26, 0x4A, 0x7F, 0xFF, 0xFF, 0xFF, + 0x00, 0x20, 0xC4, 0x9C, 0x00, 0x20, 0xC4, 0x9C, + 0x00, 0x00, 0x68, 0xDB, 0x00, 0x00, 0xD1, 0xB7, + 0x00, 0x00, 0x68, 0xDB, 0x0F, 0xA4, 0xA8, 0xC1, + 0xF8, 0x59, 0x7F, 0x63, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2F, 0xB7, 0xE9, + 0x00, 0x5F, 0x6F, 0xD2, 0x00, 0x2F, 0xB7, 0xE9, + 0x0B, 0x1E, 0x4F, 0x76, 0xFC, 0x23, 0x05, 0x54, + 0xFA, 0x41, 0x20, 0x5C, 0x0B, 0x7D, 0xBF, 0x48, + 0xFA, 0x41, 0x20, 0x5C, 0x0B, 0x1E, 0x4F, 0x76, + 0xFC, 0x23, 0x05, 0x54, 0x00, 0x04, 0x81, 0x6F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x3F, 0xE5, 0xC9, 0xF8, 0xBB, 0x98, 0xC8, + 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x81, 0x6F, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0x3F, 0xE5, 0xC9, 0xF8, 0xBB, 0x98, 0xC8, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x10); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x89, 0xA0, 0x27, 0x7F, 0xEC, 0x56, 0xD5, + 0x7F, 0xFC, 0xB9, 0x23, 0x00, 0x89, 0xA0, 0x27, + 0x7F, 0xEC, 0x56, 0xD5, 0x7F, 0xFC, 0xB9, 0x23, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x40, 0x00); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x11, 0xFF, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x7D, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x51, 0x05); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x19, 0xDF); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x46, 0x11); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x02, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x53, 0x01); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x54, 0x17); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x7F, 0x8C); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x71, 0x94, 0x9A, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x2C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0A); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x64, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0B); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x7A, 0x27, + 0x00, 0x28, 0x7A, 0x27, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x57, 0x62, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x28, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x03, 0x69, 0xC5, 0x00, 0xEE, 0xC9, 0x55, + 0x00, 0x22, 0x1D, 0x95, 0x00, 0x03, 0x69, 0xC5, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x7F, 0xF9, 0x2C, 0x60, 0x07, 0x77, 0x1A, 0x4F, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x5C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x07); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x80, 0x00, 0x00, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x64, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + { + const uint8_t values[] = { + 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0xAA); + if (res < 0) + return res; + + res = tas5825m_set_page(dev, 0x01); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x30, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x02); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x03); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xC5, 0xCA, 0x98, + 0xF0, 0x74, 0x6A, 0xD0, 0x07, 0xC5, 0xCA, 0x98, + 0x0F, 0x8A, 0x9A, 0x1D, 0xF8, 0x73, 0x6F, 0xBD, + 0x07, 0xCC, 0x4D, 0x23, 0xF0, 0x8F, 0xEC, 0x92, + 0x07, 0xA8, 0xA9, 0xB4, 0x0F, 0x70, 0x13, 0x6E, + 0xF8, 0x8B, 0x09, 0x29, 0x08, 0x2F, 0x93, 0x82, + 0xF0, 0x34, 0x1D, 0x7A, 0x07, 0xA1, 0x4F, 0x7F, + 0x0F, 0xCD, 0x63, 0x79, 0xF8, 0x30, 0x9D, 0xF2, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x04); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x05); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xC5, 0xCA, 0x98, 0xF0, 0x74, 0x6A, 0xD0, + 0x07, 0xC5, 0xCA, 0x98, 0x0F, 0x8A, 0x9A, 0x1D, + 0xF8, 0x73, 0x6F, 0xBD, 0x07, 0xCC, 0x4D, 0x23, + 0xF0, 0x8F, 0xEC, 0x92, 0x07, 0xA8, 0xA9, 0xB4, + 0x0F, 0x70, 0x13, 0x6E, 0xF8, 0x8B, 0x09, 0x29, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x06); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x2F, 0x93, 0x82, 0xF0, 0x34, 0x1D, 0x7A, + 0x07, 0xA1, 0x4F, 0x7F, 0x0F, 0xCD, 0x63, 0x79, + 0xF8, 0x30, 0x9D, 0xF2, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0E); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x00, 0x91, 0xDC, 0xC5, 0xFF, 0x04, 0xF3, 0x02, + 0x00, 0x6E, 0x34, 0x0A, 0x0F, 0xD6, 0x6C, 0x7A, + 0xF8, 0x24, 0x8F, 0xB5, 0x00 + }; + res = tas5825m_write_block_at(dev, 0x6C, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_page(dev, 0x0F); + if (res < 0) + return res; + + { + const uint8_t values[] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF4, 0x49, 0x81, + 0xFF, 0xE8, 0x93, 0x02, 0xFF, 0xF4, 0x49, 0x81, + 0x0D, 0x94, 0x7A, 0x64, 0xFA, 0x3C, 0xAB, 0xA1, + 0x06, 0xD5, 0xF3, 0xB1, 0xF2, 0x54, 0x18, 0x9F, + 0x06, 0xD5, 0xF3, 0xB1, 0x0D, 0x94, 0x7A, 0x64, + 0xFA, 0x3C, 0xAB, 0xA1, 0x00, 0x00, 0x38, 0xE4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xD5, 0x55, 0x55, 0xF8, 0x2A, 0x71, 0xC7, + 0x00 + }; + res = tas5825m_write_block_at(dev, 0x08, values, ARRAY_SIZE(values)); + if (res < 0) + return res; + } + + res = tas5825m_set_book(dev, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x30, 0x00); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x60, 0x02); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x62, 0x09); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x4C, 0x30); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x03, 0x03); + if (res < 0) + return res; + + res = tas5825m_write_at(dev, 0x78, 0x80); + if (res < 0) + return res; + + return 0; +} diff --git a/src/mainboard/system76/rpl/Kconfig b/src/mainboard/system76/rpl/Kconfig index f29c110596e..758c29a552d 100644 --- a/src/mainboard/system76/rpl/Kconfig +++ b/src/mainboard/system76/rpl/Kconfig @@ -9,6 +9,7 @@ config BOARD_SYSTEM76_RPL_COMMON select DRIVERS_GENERIC_CBFS_UUID select DRIVERS_I2C_HID select EC_SYSTEM76_EC + select EC_SYSTEM76_EC_LOCKDOWN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_CMOS_DEFAULT @@ -27,6 +28,9 @@ config BOARD_SYSTEM76_RPL_COMMON config BOARD_SYSTEM76_ADDW3 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU select MAINBOARD_USES_IFD_GBE_REGION select PCIEXP_HOTPLUG @@ -34,12 +38,26 @@ config BOARD_SYSTEM76_ADDW3 config BOARD_SYSTEM76_ADDW4 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG select SOC_INTEL_ALDERLAKE_PCH_S config BOARD_SYSTEM76_BONW15 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + select DRIVERS_INTEL_DTBT + select EC_SYSTEM76_EC_DGPU + select PCIEXP_HOTPLUG + select SOC_INTEL_ALDERLAKE_PCH_S + +config BOARD_SYSTEM76_BONW15_B + select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG select SOC_INTEL_ALDERLAKE_PCH_S @@ -56,6 +74,15 @@ config BOARD_SYSTEM76_GALP7 config BOARD_SYSTEM76_GAZE18 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + select EC_SYSTEM76_EC_DGPU + select SOC_INTEL_ALDERLAKE_PCH_P + +config BOARD_SYSTEM76_GAZE20 + select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU select SOC_INTEL_ALDERLAKE_PCH_P @@ -67,19 +94,27 @@ config BOARD_SYSTEM76_LEMP12 config BOARD_SYSTEM76_ORYP11 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select EC_SYSTEM76_EC_DGPU select SOC_INTEL_ALDERLAKE_PCH_P select SOC_INTEL_ENABLE_USB4_PCIE_RESOURCES config BOARD_SYSTEM76_ORYP12 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST select DRIVERS_I2C_TAS5825M + select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG select SOC_INTEL_ALDERLAKE_PCH_S config BOARD_SYSTEM76_SERW13 select BOARD_SYSTEM76_RPL_COMMON + select DRIVERS_GFX_NVIDIA + #select DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST + select DRIVERS_INTEL_DTBT select EC_SYSTEM76_EC_DGPU select PCIEXP_HOTPLUG select SOC_INTEL_ALDERLAKE_PCH_S @@ -93,9 +128,11 @@ config VARIANT_DIR default "addw3" if BOARD_SYSTEM76_ADDW3 default "addw4" if BOARD_SYSTEM76_ADDW4 default "bonw15" if BOARD_SYSTEM76_BONW15 + default "bonw15-b" if BOARD_SYSTEM76_BONW15_B default "darp9" if BOARD_SYSTEM76_DARP9 default "galp7" if BOARD_SYSTEM76_GALP7 default "gaze18" if BOARD_SYSTEM76_GAZE18 + default "gaze20" if BOARD_SYSTEM76_GAZE20 default "lemp12" if BOARD_SYSTEM76_LEMP12 default "oryp11" if BOARD_SYSTEM76_ORYP11 default "oryp12" if BOARD_SYSTEM76_ORYP12 @@ -108,9 +145,11 @@ config MAINBOARD_PART_NUMBER default "addw3" if BOARD_SYSTEM76_ADDW3 default "addw4" if BOARD_SYSTEM76_ADDW4 default "bonw15" if BOARD_SYSTEM76_BONW15 + default "bonw15-b" if BOARD_SYSTEM76_BONW15_B default "darp9" if BOARD_SYSTEM76_DARP9 default "galp7" if BOARD_SYSTEM76_GALP7 default "gaze18" if BOARD_SYSTEM76_GAZE18 + default "gaze20" if BOARD_SYSTEM76_GAZE20 default "lemp12" if BOARD_SYSTEM76_LEMP12 default "oryp11" if BOARD_SYSTEM76_ORYP11 default "oryp12" if BOARD_SYSTEM76_ORYP12 @@ -118,10 +157,10 @@ config MAINBOARD_PART_NUMBER config MAINBOARD_SMBIOS_PRODUCT_NAME default "Adder WS" if BOARD_SYSTEM76_ADDW3 || BOARD_SYSTEM76_ADDW4 - default "Bonobo WS" if BOARD_SYSTEM76_BONW15 + default "Bonobo WS" if BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B default "Darter Pro" if BOARD_SYSTEM76_DARP9 default "Galago Pro" if BOARD_SYSTEM76_GALP7 - default "Gazelle" if BOARD_SYSTEM76_GAZE18 + default "Gazelle" if BOARD_SYSTEM76_GAZE18 || BOARD_SYSTEM76_GAZE20 default "Lemur Pro" if BOARD_SYSTEM76_LEMP12 default "Oryx Pro" if BOARD_SYSTEM76_ORYP11 || BOARD_SYSTEM76_ORYP12 default "Serval WS" if BOARD_SYSTEM76_SERW13 @@ -130,20 +169,37 @@ config MAINBOARD_VERSION default "addw3" if BOARD_SYSTEM76_ADDW3 default "addw4" if BOARD_SYSTEM76_ADDW4 default "bonw15" if BOARD_SYSTEM76_BONW15 + default "bonw15-b" if BOARD_SYSTEM76_BONW15_B default "darp9" if BOARD_SYSTEM76_DARP9 default "galp7" if BOARD_SYSTEM76_GALP7 default "gaze18" if BOARD_SYSTEM76_GAZE18 + default "gaze20" if BOARD_SYSTEM76_GAZE20 default "lemp12" if BOARD_SYSTEM76_LEMP12 default "oryp11" if BOARD_SYSTEM76_ORYP11 default "oryp12" if BOARD_SYSTEM76_ORYP12 default "serw13" if BOARD_SYSTEM76_SERW13 +config CMOS_DEFAULT_FILE + default "src/mainboard/\$(MAINBOARDDIR)/cmos-csme.default" if BOARD_SYSTEM76_DARP9 + default "src/mainboard/\$(MAINBOARDDIR)/cmos.default" + config CONSOLE_POST default y config D3COLD_SUPPORT default n +config DRIVERS_GFX_NVIDIA_BRIDGE + default 0x02 if BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_TPP + default 45 if BOARD_SYSTEM76_ADDW4 || BOARD_SYSTEM76_GAZE20 || BOARD_SYSTEM76_ORYP11 || BOARD_SYSTEM76_ORYP12 + default 55 if BOARD_SYSTEM76_ADDW3 || BOARD_SYSTEM76_GAZE18 || BOARD_SYSTEM76_SERW13 + default 80 if BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B + +config DRIVERS_GFX_NVIDIA_DYNAMIC_BOOST_MAX + default 25 if BOARD_SYSTEM76_ADDW3 || BOARD_SYSTEM76_ADDW4 || BOARD_SYSTEM76_BONW15 || BOARD_SYSTEM76_BONW15_B || BOARD_SYSTEM76_GAZE18 || BOARD_SYSTEM76_GAZE20 || BOARD_SYSTEM76_ORYP11 || BOARD_SYSTEM76_ORYP12 || BOARD_SYSTEM76_SERW13 + config FMDFILE default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/variants/\$(CONFIG_VARIANT_DIR)/board.fmd" diff --git a/src/mainboard/system76/rpl/Kconfig.name b/src/mainboard/system76/rpl/Kconfig.name index 41842651f16..0a09982133a 100644 --- a/src/mainboard/system76/rpl/Kconfig.name +++ b/src/mainboard/system76/rpl/Kconfig.name @@ -9,6 +9,9 @@ config BOARD_SYSTEM76_ADDW4 config BOARD_SYSTEM76_BONW15 bool "bonw15" +config BOARD_SYSTEM76_BONW15_B + bool "bonw15-b" + config BOARD_SYSTEM76_DARP9 bool "darp9" @@ -18,6 +21,9 @@ config BOARD_SYSTEM76_GALP7 config BOARD_SYSTEM76_GAZE18 bool "gaze18" +config BOARD_SYSTEM76_GAZE20 + bool "gaze20" + config BOARD_SYSTEM76_LEMP12 bool "lemp12" diff --git a/src/mainboard/system76/rpl/Makefile.mk b/src/mainboard/system76/rpl/Makefile.mk index 2c8dfba322e..a5011cdba0f 100644 --- a/src/mainboard/system76/rpl/Makefile.mk +++ b/src/mainboard/system76/rpl/Makefile.mk @@ -2,6 +2,10 @@ CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include +ifeq ($(CONFIG_DRIVERS_GFX_NVIDIA),y) +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include +endif + bootblock-y += bootblock.c bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c diff --git a/src/mainboard/system76/rpl/acpi/mainboard.asl b/src/mainboard/system76/rpl/acpi/mainboard.asl index c982a9ee4cb..63ccf020d55 100644 --- a/src/mainboard/system76/rpl/acpi/mainboard.asl +++ b/src/mainboard/system76/rpl/acpi/mainboard.asl @@ -1,5 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#if CONFIG(DRIVERS_GFX_NVIDIA) +#include +#endif + #define EC_GPE_SCI 0x6E #define EC_GPE_SWI 0x6B #include @@ -8,5 +12,17 @@ Scope (\_SB) { #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" + +#if CONFIG(DRIVERS_GFX_NVIDIA) +#if CONFIG(SOC_INTEL_ALDERLAKE_PCH_P) || CONFIG(BOARD_SYSTEM76_BONW15) || CONFIG(BOARD_SYSTEM76_BONW15_B) + Scope (PEG2) { + #include + } +#else + Scope (PEG1) { + #include + } +#endif +#endif // CONFIG(DRIVERS_GFX_NVIDIA) } } diff --git a/src/mainboard/system76/rpl/cmos-csme.default b/src/mainboard/system76/rpl/cmos-csme.default new file mode 100644 index 00000000000..d61046df6b0 --- /dev/null +++ b/src/mainboard/system76/rpl/cmos-csme.default @@ -0,0 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + +boot_option=Fallback +debug_level=Debug +me_state=Enable diff --git a/src/mainboard/system76/rpl/variants/addw3/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/addw3/include/variant/gpio.h new file mode 100644 index 00000000000..9ce0d6701c1 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/addw3/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_R16 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_GC6 GPP_F8 +#define DGPU_SSID 0xa6711558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/addw3/overridetree.cb b/src/mainboard/system76/rpl/variants/addw3/overridetree.cb index 24c272c746d..903421c5868 100644 --- a/src/mainboard/system76/rpl/variants/addw3/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/addw3/overridetree.cb @@ -103,6 +103,9 @@ chip soc/intel/alderlake .clk_req = 15, .flags = PCIE_RP_HOTPLUG | PCIE_RP_LTR, }" + chip drivers/intel/dtbt + device pci 00.0 on end + end end device ref pcie_rp25 on diff --git a/src/mainboard/system76/rpl/variants/addw3/romstage.c b/src/mainboard/system76/rpl/variants/addw3/romstage.c index 30a904544cd..3992095a650 100644 --- a/src/mainboard/system76/rpl/variants/addw3/romstage.c +++ b/src/mainboard/system76/rpl/variants/addw3/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -22,6 +24,15 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/rpl/variants/addw4/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/addw4/include/variant/gpio.h new file mode 100644 index 00000000000..2ad3dfa0c41 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/addw4/include/variant/gpio.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_R16 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_SSID 0x03531558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/addw4/romstage.c b/src/mainboard/system76/rpl/variants/addw4/romstage.c index fe9103240cd..3f9d962b502 100644 --- a/src/mainboard/system76/rpl/variants/addw4/romstage.c +++ b/src/mainboard/system76/rpl/variants/addw4/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -22,6 +24,15 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to hybrid graphics mupd->FspmConfig.PrimaryDisplay = 4; diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/board.fmd b/src/mainboard/system76/rpl/variants/bonw15-b/board.fmd new file mode 100644 index 00000000000..b2615d1e171 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/board.fmd @@ -0,0 +1,12 @@ +FLASH 32M { + SI_DESC 4K + SI_ME 3944K + SI_BIOS@16M 16M { + RW_MRC_CACHE 64K + SMMSTORE(PRESERVE) 256K + WP_RO { + FMAP 4K + COREBOOT(CBFS) + } + } +} diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/board_info.txt b/src/mainboard/system76/rpl/variants/bonw15-b/board_info.txt new file mode 100644 index 00000000000..9dae13e21c3 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/board_info.txt @@ -0,0 +1,2 @@ +Board name: bonw15-b +Release year: 2024 diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/data.vbt b/src/mainboard/system76/rpl/variants/bonw15-b/data.vbt new file mode 100644 index 00000000000..fedf53f295c Binary files /dev/null and b/src/mainboard/system76/rpl/variants/bonw15-b/data.vbt differ diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/gpio.c b/src/mainboard/system76/rpl/variants/bonw15-b/gpio.c new file mode 100644 index 00000000000..3fa5f195d52 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/gpio.c @@ -0,0 +1,294 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config gpio_table[] = { + /* ------- GPIO Group GPD ------- */ + PAD_NC(GPD0, NONE), + PAD_CFG_NF(GPD1, NATIVE, PWROK, NF1), // AC_PRESENT + _PAD_CFG_STRUCT(GPD2, 0x42880100, 0x0000), // PCH_LAN_WAKE# + PAD_CFG_NF(GPD3, UP_20K, PWROK, NF1), // PWR_BTN# + PAD_CFG_NF(GPD4, NONE, PWROK, NF1), // SUSB#_PCH + PAD_CFG_NF(GPD5, NONE, PWROK, NF1), // SUSC#_PCH + PAD_NC(GPD6, NONE), + PAD_CFG_GPI(GPD7, NONE, PWROK), // GPD_7 + PAD_CFG_NF(GPD8, NONE, PWROK, NF1), // CNVI_SUSCLK + PAD_CFG_GPO(GPD9, 0, PWROK), // SLP_WLAN_N + PAD_NC(GPD10, NONE), + PAD_CFG_GPO(GPD11, 0, DEEP), // LANPHYPC + PAD_NC(GPD12, NONE), + + /* ------- GPIO Group GPP_A ------- */ + PAD_CFG_NF(GPP_A0, UP_20K, DEEP, NF1), // ESPI_IO0_EC + PAD_CFG_NF(GPP_A1, UP_20K, DEEP, NF1), // ESPI_IO1_EC + PAD_CFG_NF(GPP_A2, UP_20K, DEEP, NF1), // ESPI_IO2_EC + PAD_CFG_NF(GPP_A3, UP_20K, DEEP, NF1), // ESPI_IO3_EC + PAD_CFG_NF(GPP_A4, UP_20K, DEEP, NF1), // ESPI_CS_EC# + PAD_CFG_NF(GPP_A5, DN_20K, DEEP, NF1), // ESPI_CLK_EC + PAD_CFG_NF(GPP_A6, NONE, DEEP, NF1), // ESPI_RESET_N + PAD_NC(GPP_A7, NONE), + PAD_NC(GPP_A8, NONE), + PAD_NC(GPP_A9, NONE), + PAD_CFG_NF(GPP_A10, NONE, DEEP, NF1), // ESPI_ALERT0# + PAD_NC(GPP_A11, NONE), + PAD_NC(GPP_A12, NONE), + PAD_NC(GPP_A13, NONE), + PAD_NC(GPP_A14, NONE), + + /* ------- GPIO Group GPP_B ------- */ + _PAD_CFG_STRUCT(GPP_B0, 0x82900100, 0x0000), // TPM_PIRQ# + PAD_NC(GPP_B1, NONE), + PAD_CFG_GPI(GPP_B2, NONE, DEEP), // CNVI_WAKE# + PAD_CFG_GPO(GPP_B3, 1, DEEP), // PCH_BT_EN + PAD_NC(GPP_B4, NONE), + PAD_NC(GPP_B5, NONE), + PAD_NC(GPP_B6, NONE), + PAD_NC(GPP_B7, NONE), + PAD_NC(GPP_B8, NONE), + PAD_NC(GPP_B9, NONE), + PAD_NC(GPP_B10, NONE), + PAD_NC(GPP_B11, NONE), + PAD_NC(GPP_B12, NONE), + PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), // PLT_RST# + PAD_CFG_NF(GPP_B14, NONE, DEEP, NF1), // HDA_SPKR + PAD_NC(GPP_B15, NONE), // PS8461_SW + PAD_NC(GPP_B16, NONE), + PAD_NC(GPP_B17, NONE), // 2.5G_LAN_EN + PAD_CFG_NF(GPP_B18, NONE, RSMRST, NF1), // PMCALERT# (tied high) + PAD_CFG_GPO(GPP_B19, 1, DEEP), // PCH_WLAN_EN + PAD_NC(GPP_B20, NONE), + PAD_NC(GPP_B21, NONE), + PAD_CFG_GPO(GPP_B22, 1, DEEP), // LAN_RST# + PAD_CFG_GPI(GPP_B23, NONE, RSMRST), // GPP_B23 (XTAL FREQ SEL1) + + /* ------- GPIO Group GPP_C ------- */ + PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), // SMB_CLK + PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), // SMB_DATA + PAD_CFG_GPI(GPP_C2, NONE, PLTRST), // TLS confidentiality strap + PAD_CFG_GPO(GPP_C3, 0, DEEP), // GPPC_I2C2_SDA (Pantone) + PAD_CFG_GPO(GPP_C4, 0, DEEP), // GPPC_I2C2_SCL (Pantone) + PAD_NC(GPP_C5, NONE), // eSPI disable strap + PAD_NC(GPP_C6, NONE), + PAD_NC(GPP_C7, NONE), + PAD_CFG_GPI(GPP_C8, NONE, DEEP), // TPM_DET + PAD_NC(GPP_C9, NONE), + PAD_NC(GPP_C10, NONE), + PAD_NC(GPP_C11, NONE), + PAD_NC(GPP_C12, NONE), + PAD_NC(GPP_C13, NONE), + PAD_NC(GPP_C14, NONE), + PAD_NC(GPP_C15, NONE), + PAD_CFG_NF(GPP_C16, NONE, DEEP, NF1), // I2C_SDA_TP + PAD_CFG_NF(GPP_C17, NONE, DEEP, NF1), // I2C_SCL_TP + PAD_CFG_NF(GPP_C18, NONE, DEEP, NF1), // PCH_I2C_SDA (TPS65994) + PAD_CFG_NF(GPP_C19, NONE, DEEP, NF1), // PCH_I2C_SCL (TPS65994) + // GPP_C20 (UART2_RXD) configured in bootblock + // GPP_C21 (UART2_TXD) configured in bootblock + PAD_CFG_GPO(GPP_C22, 0, DEEP), // ROM_I2C_EN (TPS65994) + PAD_NC(GPP_C23, NONE), + + /* ------- GPIO Group GPP_D ------- */ + PAD_NC(GPP_D0, NONE), + PAD_NC(GPP_D1, NONE), + PAD_NC(GPP_D2, NONE), + PAD_NC(GPP_D3, NONE), // GFX_DETECT_STRAP + PAD_NC(GPP_D4, NONE), + PAD_CFG_GPO(GPP_D5, 1, DEEP), // M.2_BT_PCMFRM_CRF_RST_N + // GPP_D6 (M.2_BT_PCMOUT_CLKREQ0) configured by FSP + PAD_NC(GPP_D7, NONE), + PAD_NC(GPP_D8, NONE), + PAD_NC(GPP_D9, NONE), + PAD_NC(GPP_D10, NONE), + PAD_NC(GPP_D11, NONE), + PAD_NC(GPP_D12, NONE), + PAD_NC(GPP_D13, NONE), + PAD_NC(GPP_D14, NONE), + PAD_NC(GPP_D15, NONE), + PAD_NC(GPP_D16, NONE), + PAD_NC(GPP_D17, NONE), + PAD_NC(GPP_D18, NONE), + PAD_NC(GPP_D19, NONE), + PAD_NC(GPP_D20, NONE), + PAD_NC(GPP_D21, NONE), + PAD_NC(GPP_D22, NONE), + PAD_NC(GPP_D23, NONE), + + /* ------- GPIO Group GPP_E ------- */ + PAD_CFG_GPO(GPP_E0, 1, DEEP), // GPP_E0_TBT_RST# + PAD_NC(GPP_E1, NONE), + PAD_NC(GPP_E2, NONE), + PAD_NC(GPP_E3, NONE), + PAD_NC(GPP_E4, NONE), + PAD_NC(GPP_E5, NONE), + PAD_NC(GPP_E6, NONE), + PAD_CFG_GPI_INT(GPP_E7, NONE, PLTRST, LEVEL), // TP_ATTN# + PAD_CFG_NF(GPP_E8, NONE, DEEP, NF1), // SATA_LED# + PAD_CFG_NF(GPP_E9, NONE, DEEP, NF1), // GPP_E_9_USB_OC0_N + PAD_CFG_NF(GPP_E10, NONE, DEEP, NF1), // GPP_E_10_USB_OC1_N + PAD_CFG_NF(GPP_E11, NONE, DEEP, NF1), // GPP_E_11_USB_OC2_N + PAD_CFG_NF(GPP_E12, NONE, DEEP, NF1), // GPP_E_12_USB_OC3_N + PAD_NC(GPP_E13, NONE), + PAD_NC(GPP_E14, NONE), + PAD_NC(GPP_E15, NONE), + PAD_NC(GPP_E16, NONE), + PAD_NC(GPP_E17, NONE), + PAD_CFG_GPO(GPP_E18, 1, DEEP), // SB_BLON + _PAD_CFG_STRUCT(GPP_E19, 0x42880100, 0x0000), // GPP_E19_TBT_WAKE# + PAD_NC(GPP_E20, NONE), + PAD_NC(GPP_E21, NONE), + + /* ------- GPIO Group GPP_F ------- */ + PAD_NC(GPP_F0, NONE), + PAD_NC(GPP_F1, NONE), + PAD_NC(GPP_F2, NONE), + PAD_NC(GPP_F3, NONE), + PAD_NC(GPP_F4, NONE), + PAD_NC(GPP_F5, NONE), + PAD_NC(GPP_F6, NONE), + PAD_NC(GPP_F7, NONE), + PAD_CFG_GPI(GPP_F8, NONE, DEEP), // GC6_FB_EN_PCH + PAD_NC(GPP_F9, NONE), + PAD_NC(GPP_F10, NONE), + PAD_NC(GPP_F11, NONE), + PAD_NC(GPP_F12, NONE), + PAD_NC(GPP_F13, NONE), + PAD_CFG_GPI(GPP_F14, NONE, DEEP), // TBT5 strap + PAD_CFG_GPI(GPP_F15, NONE, DEEP), // H_SKTOCC_N + PAD_NC(GPP_F16, NONE), + PAD_NC(GPP_F17, NONE), + PAD_CFG_GPO(GPP_F18, 0, DEEP), // CCD_FW_WP# + PAD_CFG_NF(GPP_F19, NONE, DEEP, NF1), // NB_ENAVDD + PAD_CFG_NF(GPP_F20, NONE, DEEP, NF1), // BLON + PAD_CFG_NF(GPP_F21, NONE, DEEP, NF1), // EDP_BRIGHTNESS + // GPP_F22 (DGPU_PWR_EN) configured in bootblock + PAD_NC(GPP_F23, NONE), + + /* ------- GPIO Group GPP_G ------- */ + PAD_NC(GPP_G0, NONE), + PAD_CFG_GPI(GPP_G1, NONE, DEEP), // GPU SKU strap (L: X9, H: X11) + PAD_NC(GPP_G2, NONE), + PAD_CFG_GPI(GPP_G3, NONE, DEEP), // DDS strap (L: Non-DDS, H: DDS) + PAD_CFG_GPI(GPP_G4, NONE, DEEP), // Smart AMP strap (L: TI, H: Realtek) + PAD_CFG_NF(GPP_G5, NONE, DEEP, NF1), // SLP_DRAM_N + PAD_CFG_GPI(GPP_G6, NONE, DEEP), // Pantone (L: W/O, H: W) + PAD_NC(GPP_G7, NONE), + + /* ------- GPIO Group GPP_H ------- */ + PAD_CFG_GPI(GPP_H0, NONE, DEEP), // VAL_SV_ADVANCE_STRAP + PAD_NC(GPP_H1, NONE), + PAD_NC(GPP_H2, NONE), // WLAN_WAKE_N + // GPP_H3 (WLAN_CLKREQ9#) configured by FSP + // GPP_H4 (SSD1_CLKREQ10#) configured by FSP + // GPP_H5 (SSD2_CLKREQ11#) configured by FSP + // GPP_H6 (SSD3_CLKREQ12#) configured by FSP + // GPP_H7 (TBT_CLKREQ13#) configured by FSP + // GPP_H8 (GPU_PCIE_CLKREQ14#) configured by FSP + // GPP_H9 (GLAN_CLKREQ15#) configured by FSP + PAD_NC(GPP_H10, NONE), + PAD_NC(GPP_H11, NONE), + PAD_CFG_GPI(GPP_H12, NONE, RSMRST), // eSPI flash sharing mode strap (L: MAF, H: SAF) + PAD_NC(GPP_H13, NONE), + PAD_NC(GPP_H14, NONE), + PAD_CFG_GPI(GPP_H15, NONE, RSMRST), // JTAG ODT disable strap (L: Disable, H: Enable) + PAD_NC(GPP_H16, NONE), + PAD_CFG_GPO(GPP_H17, 1, DEEP), // M.2_PLT_RST_CNTRL3# + PAD_CFG_GPI(GPP_H18, NONE, RSMRST), // VCCPSPI strap (L: 3.3V, H: 1.8V) + PAD_NC(GPP_H19, NONE), + PAD_NC(GPP_H20, NONE), + PAD_NC(GPP_H21, NONE), // TBT_MRESET_PCH + PAD_NC(GPP_H22, NONE), + PAD_NC(GPP_H23, NONE), + + /* ------- GPIO Group GPP_I ------- */ + PAD_NC(GPP_I0, NONE), + _PAD_CFG_STRUCT(GPP_I1, 0x86880100, 0x0000), // G_DP_DHPD_E + _PAD_CFG_STRUCT(GPP_I2, 0x86880100, 0x0000), // DP_D_HPD + _PAD_CFG_STRUCT(GPP_I3, 0x86880100, 0x0000), // HDMI_HPD + _PAD_CFG_STRUCT(GPP_I4, 0x86880100, 0x0000), // DP_A_HPD + PAD_NC(GPP_I5, NONE), + PAD_NC(GPP_I6, NONE), + PAD_NC(GPP_I7, NONE), + PAD_NC(GPP_I8, NONE), + PAD_NC(GPP_I9, NONE), + PAD_NC(GPP_I10, NONE), + PAD_CFG_NF(GPP_I11, NONE, DEEP, NF1), // GPP_I_11_USB_OC4_N + PAD_CFG_NF(GPP_I12, NONE, DEEP, NF1), // GPP_I_12_USB_OC5_N + PAD_CFG_NF(GPP_I13, NONE, DEEP, NF1), // GPP_I_13_USB_OC6_N + PAD_CFG_NF(GPP_I14, NONE, DEEP, NF1), // GPP_I_14_USB_OC7_N + PAD_NC(GPP_I15, NONE), + PAD_NC(GPP_I16, NONE), + PAD_NC(GPP_I17, NONE), + PAD_CFG_GPI(GPP_I18, NONE, PWROK), // No reboot strap (L: Disable, H: Enable) + PAD_NC(GPP_I19, NONE), + PAD_NC(GPP_I20, NONE), + PAD_NC(GPP_I21, NONE), + PAD_CFG_GPI(GPP_I22, NONE, PWROK), // Boot BIOS strap (L: MAF or SAF, H: eSPI) + + /* ------- GPIO Group GPP_J ------- */ + PAD_CFG_NF(GPP_J0, NONE, DEEP, NF1), // CNVI_GNSS_PA_BLANKING + PAD_CFG_NF(GPP_J1, NONE, DEEP, NF1), // CPU_C10_GATE# + PAD_CFG_NF(GPP_J2, NONE, DEEP, NF1), // CNVI_BRI_DT_R + PAD_CFG_NF(GPP_J3, UP_20K, DEEP, NF1), // CNVI_BRI_RSP + PAD_CFG_NF(GPP_J4, NONE, DEEP, NF1), // CNVI_RGI_DT_R + PAD_CFG_NF(GPP_J5, UP_20K, DEEP, NF1), // CNVI_RGI_RSP + PAD_CFG_NF(GPP_J6, NONE, DEEP, NF1), // CNVI_MFUART2_RXD + PAD_CFG_NF(GPP_J7, NONE, DEEP, NF1), // CNVI_MFUART2_TXD + PAD_CFG_GPI(GPP_J8, NONE, DEEP), // VAL_TEST_SETUP_MENU + PAD_NC(GPP_J9, NONE), + PAD_NC(GPP_J10, NONE), + PAD_NC(GPP_J11, NONE), + + /* ------- GPIO Group GPP_K ------- */ + PAD_NC(GPP_K0, NONE), + PAD_NC(GPP_K1, NONE), + PAD_NC(GPP_K2, NONE), + PAD_NC(GPP_K3, NONE), + PAD_NC(GPP_K4, NONE), + PAD_NC(GPP_K5, NONE), + // GPP_K6 missing + // GPP_K7 missing + PAD_CFG_NF(GPP_K8, NONE, DEEP, NF1), // GPP_K_8_CORE_VID_0 + PAD_CFG_NF(GPP_K9, NONE, DEEP, NF1), // GPP_K_9_CORE_VID_1 + PAD_CFG_NF(GPP_K10, NONE, DEEP, NF2), + PAD_NC(GPP_K11, NONE), + + /* ------- GPIO Group GPP_R ------- */ + PAD_CFG_NF(GPP_R0, NONE, DEEP, NF1), // HDA_BITCLK + PAD_CFG_NF(GPP_R1, NATIVE, DEEP, NF1), // HDA_SYNC + PAD_CFG_NF(GPP_R2, NATIVE, DEEP, NF1), // HDA_SDOUT + PAD_CFG_NF(GPP_R3, NATIVE, DEEP, NF1), // HDA_SDIN0 + PAD_CFG_NF(GPP_R4, NONE, DEEP, NF1), // HDA_RST# + PAD_NC(GPP_R5, NONE), + PAD_NC(GPP_R6, NONE), + PAD_CFG_GPO(GPP_R7, 1, DEEP), // GPP_R7_TBT_RTD3 + PAD_CFG_GPI(GPP_R8, NONE, DEEP), // DGPU_PWRGD + PAD_CFG_NF(GPP_R9, NONE, DEEP, NF1), // EDP_HPD + PAD_NC(GPP_R10, NONE), + PAD_NC(GPP_R11, NONE), + PAD_NC(GPP_R12, NONE), + PAD_NC(GPP_R13, NONE), + PAD_NC(GPP_R14, NONE), + PAD_NC(GPP_R15, NONE), + // GPP_R16 (DGPU_RST#_PCH) configured in bootblock + PAD_NC(GPP_R17, NONE), + PAD_NC(GPP_R18, NONE), + PAD_NC(GPP_R19, NONE), + PAD_NC(GPP_R20, NONE), + PAD_NC(GPP_R21, NONE), + + /* ------- GPIO Group GPP_S ------- */ + PAD_NC(GPP_S0, NONE), + PAD_NC(GPP_S1, NONE), + PAD_NC(GPP_S2, NONE), + PAD_NC(GPP_S3, NONE), + PAD_NC(GPP_S4, NONE), // GPPS_DMIC_CLK + PAD_NC(GPP_S5, NONE), // GPPS_DMIC_DATA + PAD_NC(GPP_S6, NONE), + PAD_NC(GPP_S7, NONE), +}; + +void mainboard_configure_gpios(void) +{ + gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table)); +} diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/gpio_early.c b/src/mainboard/system76/rpl/variants/bonw15-b/gpio_early.c new file mode 100644 index 00000000000..cea38b54cec --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/gpio_early.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config early_gpio_table[] = { + PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), // UART2_RXD + PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), // UART2_TXD + PAD_CFG_GPO(GPP_F22, 0, DEEP), // DGPU_PWR_EN + PAD_CFG_GPO(GPP_R16, 0, DEEP), // DGPU_RST#_PCH +}; + +void mainboard_configure_early_gpios(void) +{ + gpio_configure_pads(early_gpio_table, ARRAY_SIZE(early_gpio_table)); +} diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/hda_verb.c b/src/mainboard/system76/rpl/variants/bonw15-b/hda_verb.c new file mode 100644 index 00000000000..c1f031cc950 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/hda_verb.c @@ -0,0 +1,263 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +const u32 cim_verb_data[] = { + /* Realtek, ALC1220 */ + 0x10ec1220, /* Vendor ID */ + 0x15583702, /* Subsystem ID */ + 243, /* Number of entries */ + + 0x02050008, 0x020480cb, 0x02050008, 0x0204c0cb, + AZALIA_SUBVENDOR(0, 0x15583702), + AZALIA_RESET(1), + AZALIA_PIN_CFG(0, 0x12, 0x90a60130), + AZALIA_PIN_CFG(0, 0x14, 0x0421101f), + AZALIA_PIN_CFG(0, 0x15, 0x40000000), + AZALIA_PIN_CFG(0, 0x16, 0x411111f0), + AZALIA_PIN_CFG(0, 0x17, 0x411111f0), + AZALIA_PIN_CFG(0, 0x18, 0x04a11040), + AZALIA_PIN_CFG(0, 0x19, 0x411111f0), + AZALIA_PIN_CFG(0, 0x1a, 0x411111f0), + AZALIA_PIN_CFG(0, 0x1b, 0x90170110), + AZALIA_PIN_CFG(0, 0x1d, 0x40b7952d), + AZALIA_PIN_CFG(0, 0x1e, 0x04451150), + + // ALC1318 smart amp + 0x05b50000, 0x05b43530, 0x05750002, 0x05741400, + 0x02050058, 0x02048ed1, 0x02050063, 0x0204e430, + 0x02050016, 0x02048020, 0x02050016, 0x02048020, + 0x02050043, 0x02043005, 0x02050058, 0x02048ed1, + 0x02050063, 0x0204e430, 0x05b50000, 0x05b43530, + 0x05750002, 0x05741400, 0x05b5000a, 0x05b45520, + 0x02050042, 0x020486cb, 0x0143b000, 0x01470700, + 0x02050036, 0x02042a6a, 0x02050008, 0x0204800b, + 0x02050007, 0x020403c3, 0x01470c02, 0x01470c02, + 0x00c37100, 0x01b3b000, 0x01b70700, 0x00b37417, + 0x0205001b, 0x02044002, 0x0205001b, 0x02044002, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c000, 0x0205002b, 0x02040001, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f20d, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f212, 0x0205002b, 0x0204003e, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c001, + 0x0205002b, 0x02040002, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c003, 0x0205002b, 0x02040022, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c004, + 0x0205002b, 0x02040044, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c005, 0x0205002b, 0x02040044, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c007, + 0x0205002b, 0x02040064, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c00e, 0x0205002b, 0x020400e7, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f223, + 0x0205002b, 0x0204007f, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f224, 0x0205002b, 0x020400db, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f225, + 0x0205002b, 0x020400ee, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f226, 0x0205002b, 0x0204003f, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f227, + 0x0205002b, 0x0204000f, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f21a, 0x0205002b, 0x02040078, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f242, + 0x0205002b, 0x0204003c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c120, 0x0205002b, 0x02040040, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c125, + 0x0205002b, 0x02040003, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c321, 0x0205002b, 0x0204000b, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c200, + 0x0205002b, 0x020400d8, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c201, 0x0205002b, 0x02040027, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c202, + 0x0205002b, 0x0204000f, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c400, 0x0205002b, 0x0204000e, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c401, + 0x0205002b, 0x02040043, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c402, 0x0205002b, 0x020400e0, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c403, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c404, 0x0205002b, 0x0204004c, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c406, + 0x0205002b, 0x02040040, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c407, 0x0205002b, 0x02040002, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c408, + 0x0205002b, 0x0204003f, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c300, 0x0205002b, 0x02040001, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c125, + 0x0205002b, 0x02040003, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204df00, 0x0205002b, 0x02040010, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204df5f, + 0x0205002b, 0x02040001, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204df60, 0x0205002b, 0x020400a7, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204ea00, + 0x0205002b, 0x02040047, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c203, 0x0205002b, 0x02040004, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c206, + 0x0205002b, 0x02040078, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f102, 0x0205002b, 0x02040000, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f103, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f104, 0x0205002b, 0x020400f4, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f105, + 0x0205002b, 0x02040003, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f109, 0x0205002b, 0x020400e0, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f10a, + 0x0205002b, 0x0204000b, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f10b, 0x0205002b, 0x0204004c, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f10b, + 0x0205002b, 0x0204005c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f102, 0x0205002b, 0x02040000, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f103, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f104, 0x0205002b, 0x020400f4, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f105, + 0x0205002b, 0x02040004, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f109, 0x0205002b, 0x02040065, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f10a, + 0x0205002b, 0x0204000b, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f10b, 0x0205002b, 0x0204004c, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f10b, + 0x0205002b, 0x0204005c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204e706, 0x0205002b, 0x0204000f, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204e707, + 0x0205002b, 0x02040030, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204e806, 0x0205002b, 0x0204000f, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204e807, + 0x0205002b, 0x02040030, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204ce04, 0x0205002b, 0x02040002, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204ce05, + 0x0205002b, 0x02040087, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204ce06, 0x0205002b, 0x020400a2, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204ce07, + 0x0205002b, 0x0204006c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204cf04, 0x0205002b, 0x02040002, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204cf05, + 0x0205002b, 0x02040087, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204cf06, 0x0205002b, 0x020400a2, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204cf07, + 0x0205002b, 0x0204006c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204ce60, 0x0205002b, 0x020400e3, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204c130, + 0x0205002b, 0x02040051, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204e000, 0x0205002b, 0x020400a8, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f102, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f103, 0x0205002b, 0x02040000, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f104, + 0x0205002b, 0x020400f5, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f105, 0x0205002b, 0x02040023, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f109, + 0x0205002b, 0x02040004, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f10a, 0x0205002b, 0x0204000b, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f10b, + 0x0205002b, 0x0204004c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f10b, 0x0205002b, 0x0204005c, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02044100, 0x02050029, 0x02041888, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204c121, 0x0205002b, 0x0204000b, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f102, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f103, 0x0205002b, 0x02040000, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f104, + 0x0205002b, 0x020400f5, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f105, 0x0205002b, 0x02040023, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f109, + 0x0205002b, 0x02040000, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f10a, 0x0205002b, 0x0204000b, + 0x0205002c, 0x0204b423, 0x02050027, 0x02040010, + 0x02050028, 0x02040000, 0x02050029, 0x0204f10b, + 0x0205002b, 0x0204004c, 0x0205002c, 0x0204b423, + 0x02050027, 0x02040010, 0x02050028, 0x02040000, + 0x02050029, 0x0204f10b, 0x0205002b, 0x0204005c, + 0x0205002c, 0x0204b423, + + // XXX: Duplicate last 2 u32s to keep in 4-dword blocks + 0x0205002c, 0x0204b423, +}; + +const u32 pc_beep_verbs[] = {}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/bonw15-b/include/variant/gpio.h new file mode 100644 index 00000000000..be865bb20dc --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_R16 +#define DGPU_PWR_EN GPP_F22 +#define DGPU_GC6 GPP_F8 +#define DGPU_SSID 0x37021558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/overridetree.cb b/src/mainboard/system76/rpl/variants/bonw15-b/overridetree.cb new file mode 100644 index 00000000000..a633217794a --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/overridetree.cb @@ -0,0 +1,114 @@ +chip soc/intel/alderlake + # Support 5600 MT/s memory + register "max_dram_speed_mts" = "5600" + + device domain 0 on + subsystemid 0x1558 0x3702 inherit + + device ref xhci on + register "usb2_ports" = "{ + [0] = USB2_PORT_MID(OC_SKIP), /* Type-A 3.2 Gen 2 (Left, Front) */ + [1] = USB2_PORT_MID(OC_SKIP), /* Type-A 3.2 Gen 2 (Left, Rear) */ + [5] = USB2_PORT_MID(OC_SKIP), /* Camera */ + [6] = USB2_PORT_MID(OC_SKIP), /* Per-key RGB */ + /* Port reset messaging cannot be used, + * so do not use USB2_PORT_TYPE_C for these */ + [8] = USB2_PORT_MID(OC_SKIP), /* Type-C Thunderbolt (Right, Front) */ + [9] = USB2_PORT_MID(OC_SKIP), /* Type-C Thunderbolt with PD (Right, Rear) */ + [13] = USB2_PORT_MID(OC_SKIP), /* Bluetooth */ + }" + register "usb3_ports" = "{ + [0] = USB3_PORT_DEFAULT(OC_SKIP), /* Type-A 3.2 Gen 2 (Left, Front) */ + [2] = USB3_PORT_DEFAULT(OC_SKIP), /* Type-A 3.2 Gen 2 (Left, Rear) */ + }" + end + + device ref i2c0 on + # Touchpad I2C bus + register "serial_io_i2c_mode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + chip drivers/i2c/hid + register "generic.hid" = ""ELAN0412"" + register "generic.desc" = ""ELAN Touchpad"" + register "generic.irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_E7)" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 15 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""FTCS1000"" + register "generic.desc" = ""FocalTech Touchpad"" + register "generic.irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_E7)" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 38 on end + end + end + + device ref pcie5_0 on + # CPU PCIe RP#3 x4, CLKOUT 2, CLKREQ 11 (SSD2) + register "cpu_pcie_rp[CPU_RP(2)]" = "{ + .clk_src = 2, + .clk_req = 11, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + + device ref pcie5_1 on + # CPU PCIe RP#2 x8, Clock 14 (DGPU) + register "cpu_pcie_rp[CPU_RP(3)]" = "{ + .clk_src = 14, + .clk_req = 14, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + + device ref pcie4_0 on + # CPU PCIe RP#1 x4, Clock 12 (SSD3) + register "cpu_pcie_rp[CPU_RP(1)]" = "{ + .clk_src = 12, + .clk_req = 12, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + + device ref pcie_rp7 on + # PCH RP#7 x1, Clock 13 (GLAN) + register "pch_pcie_rp[PCH_RP(7)]" = "{ + .clk_src = 15, + .clk_req = 15, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + device pci 00.0 on end + end + + device ref pcie_rp8 on + # PCH RP#8 x1, Clock 9 (WLAN) + register "pch_pcie_rp[PCH_RP(8)]" = "{ + .clk_src = 9, + .clk_req = 9, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + + device ref pcie_rp9 on + # PCH RP#9 x4, Clock 15 (TBT) + register "pch_pcie_rp[PCH_RP(9)]" = "{ + .clk_src = 13, + .clk_req = 13, + .flags = PCIE_RP_HOTPLUG | PCIE_RP_LTR, + }" + chip drivers/intel/dtbt + device pci 00.0 on end + end + end + + device ref pcie_rp21 on + # PCH RP#21 x4, Clock 10 (SSD1) + register "pch_pcie_rp[PCH_RP(21)]" = "{ + .clk_src = 10, + .clk_req = 10, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + end +end diff --git a/src/mainboard/system76/rpl/variants/bonw15-b/romstage.c b/src/mainboard/system76/rpl/variants/bonw15-b/romstage.c new file mode 100644 index 00000000000..3992095a650 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15-b/romstage.c @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void mainboard_memory_init_params(FSPM_UPD *mupd) +{ + const struct mb_cfg board_cfg = { + .type = MEM_TYPE_DDR5, + .ect = true, + .LpDdrDqDqsReTraining = 1, + .ddr_config = { + .dq_pins_interleaved = true, + }, + }; + const struct mem_spd spd_info = { + .topo = MEM_TOPO_DIMM_MODULE, + .smbus = { + [0] = { .addr_dimm[0] = 0x50, }, + [1] = { .addr_dimm[0] = 0x52, }, + }, + }; + const bool half_populated = false; + + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + mupd->FspmConfig.PrimaryDisplay = 0; + + mupd->FspmConfig.DmiMaxLinkSpeed = 4; + mupd->FspmConfig.GpioOverride = 0; + + memcfg_init(mupd, &board_cfg, &spd_info, half_populated); +} diff --git a/src/mainboard/system76/rpl/variants/bonw15/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/bonw15/include/variant/gpio.h new file mode 100644 index 00000000000..be865bb20dc --- /dev/null +++ b/src/mainboard/system76/rpl/variants/bonw15/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_R16 +#define DGPU_PWR_EN GPP_F22 +#define DGPU_GC6 GPP_F8 +#define DGPU_SSID 0x37021558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/bonw15/overridetree.cb b/src/mainboard/system76/rpl/variants/bonw15/overridetree.cb index a1191a54342..e3e59e32397 100644 --- a/src/mainboard/system76/rpl/variants/bonw15/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/bonw15/overridetree.cb @@ -99,6 +99,9 @@ chip soc/intel/alderlake .clk_req = 15, .flags = PCIE_RP_HOTPLUG | PCIE_RP_LTR, }" + chip drivers/intel/dtbt + device pci 00.0 on end + end end device ref pcie_rp21 on diff --git a/src/mainboard/system76/rpl/variants/bonw15/romstage.c b/src/mainboard/system76/rpl/variants/bonw15/romstage.c index 30a904544cd..3992095a650 100644 --- a/src/mainboard/system76/rpl/variants/bonw15/romstage.c +++ b/src/mainboard/system76/rpl/variants/bonw15/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -22,6 +24,15 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/rpl/variants/darp9/overridetree.cb b/src/mainboard/system76/rpl/variants/darp9/overridetree.cb index 3dc27864fe0..b83ad748329 100644 --- a/src/mainboard/system76/rpl/variants/darp9/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/darp9/overridetree.cb @@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only chip soc/intel/alderlake + register "s0ix_enable" = "1" + register "power_limits_config[RPL_P_682_482_282_28W_CORE]" = "{ .tdp_pl1_override = 20, .tdp_pl2_override = 56, diff --git a/src/mainboard/system76/rpl/variants/gaze18/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/gaze18/include/variant/gpio.h new file mode 100644 index 00000000000..612710995c0 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze18/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_F13 +#define DGPU_SSID 0x56301558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/gaze18/romstage.c b/src/mainboard/system76/rpl/variants/gaze18/romstage.c index 1e597c72a69..2c8a6737bba 100644 --- a/src/mainboard/system76/rpl/variants/gaze18/romstage.c +++ b/src/mainboard/system76/rpl/variants/gaze18/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -19,6 +21,15 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/rpl/variants/gaze20/board.fmd b/src/mainboard/system76/rpl/variants/gaze20/board.fmd new file mode 100644 index 00000000000..fdf1ebdf52b --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/board.fmd @@ -0,0 +1,12 @@ +FLASH 32M { + SI_DESC 4K + SI_ME 4824K + SI_BIOS@16M 16M { + RW_MRC_CACHE 64K + SMMSTORE(PRESERVE) 256K + WP_RO { + FMAP 4K + COREBOOT(CBFS) + } + } +} diff --git a/src/mainboard/system76/rpl/variants/gaze20/board_info.txt b/src/mainboard/system76/rpl/variants/gaze20/board_info.txt new file mode 100644 index 00000000000..4d60ca7c13d --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/board_info.txt @@ -0,0 +1,2 @@ +Board name: gaze20 +Release year: 2025 diff --git a/src/mainboard/system76/rpl/variants/gaze20/data.vbt b/src/mainboard/system76/rpl/variants/gaze20/data.vbt new file mode 100644 index 00000000000..f01115566a7 Binary files /dev/null and b/src/mainboard/system76/rpl/variants/gaze20/data.vbt differ diff --git a/src/mainboard/system76/rpl/variants/gaze20/gpio.c b/src/mainboard/system76/rpl/variants/gaze20/gpio.c new file mode 100644 index 00000000000..5e256cafa94 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/gpio.c @@ -0,0 +1,227 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config gpio_table[] = { + /* ------- GPIO Group GPD ------- */ + PAD_CFG_NF(GPD0, UP_20K, PWROK, NF1), // PM_BATLOW# + PAD_CFG_NF(GPD1, NATIVE, PWROK, NF1), // AC_PRESENT + PAD_CFG_NF(GPD2, NATIVE, DEEP, NF1), // LANRTD3_WAKE# + PAD_CFG_NF(GPD3, UP_20K, PWROK, NF1), // PWR_BTN# + PAD_CFG_NF(GPD4, NONE, PWROK, NF1), // SUSB#_PCH + PAD_CFG_NF(GPD5, NONE, PWROK, NF1), // SUSC#_PCH + PAD_CFG_NF(GPD6, NONE, PWROK, NF1), // SLP_A# + PAD_NC(GPD7, NONE), + PAD_CFG_NF(GPD8, NONE, PWROK, NF1), // Not documented + PAD_CFG_GPI(GPD9, NONE, DEEP), // SLP_WLAN# + PAD_CFG_NF(GPD10, NONE, PWROK, NF1), // SLP_S5# + PAD_NC(GPD11, NONE), + + /* ------- GPIO Group GPP_A ------- */ + PAD_CFG_NF(GPP_A0, UP_20K, DEEP, NF1), // ESPI_IO0_EC + PAD_CFG_NF(GPP_A1, UP_20K, DEEP, NF1), // ESPI_IO1_EC + PAD_CFG_NF(GPP_A2, UP_20K, DEEP, NF1), // ESPI_IO2_EC + PAD_CFG_NF(GPP_A3, UP_20K, DEEP, NF1), // ESPI_IO3_EC + PAD_CFG_NF(GPP_A4, UP_20K, DEEP, NF1), // ESPI_CS_EC# + PAD_CFG_NF(GPP_A5, UP_20K, DEEP, NF1), // ESPI_ALRT0# + PAD_NC(GPP_A6, NONE), + PAD_NC(GPP_A7, NONE), + PAD_NC(GPP_A8, NONE), + PAD_CFG_NF(GPP_A9, DN_20K, DEEP, NF1), // ESPI_CLK_EC + PAD_CFG_NF(GPP_A10, NONE, DEEP, NF1), // ESPI_RESET_N + PAD_NC(GPP_A11, NONE), + PAD_NC(GPP_A12, NONE), + PAD_CFG_GPO(GPP_A13, 1, PLTRST), // BT_EN + // GPP_A14 (DGPU_PWR_EN) configured in bootblock + PAD_CFG_NF(GPP_A15, NONE, DEEP, NF2), // DP_HPD + PAD_NC(GPP_A16, NONE), + PAD_CFG_GPI_INT(GPP_A17, NONE, PLTRST, LEVEL), // TP_ATTN# + PAD_CFG_NF(GPP_A18, NONE, DEEP, NF1), // MDP_B_HPD + PAD_CFG_GPI(GPP_A19, NONE, DEEP), // DGPU_PWRGD_R + _PAD_CFG_STRUCT(GPP_A20, 0x86880100, 0x0000), // HDMI_HPD + _PAD_CFG_STRUCT(GPP_A21, 0x86880100, 0x0000), // NVVDD_TALERT# + PAD_CFG_GPO(GPP_A22, 1, PLTRST), // LAN_PWR_EN + PAD_NC(GPP_A23, NONE), + + /* ------- GPIO Group GPP_B ------- */ + PAD_CFG_NF(GPP_B0, NONE, DEEP, NF1), // VCCIN_AUX_VID0 + PAD_CFG_NF(GPP_B1, NONE, DEEP, NF1), // VCCIN_AUX_VID1 + // GPP_B2 (DGPU_RST#_PCH) configured in bootblock + PAD_CFG_GPI(GPP_B3, NONE, DEEP), // SCI# + PAD_NC(GPP_B4, NONE), + PAD_CFG_GPO(GPP_B5, 0, DEEP), // PS8461_SW + PAD_NC(GPP_B6, NONE), + PAD_NC(GPP_B7, NONE), + PAD_NC(GPP_B8, NONE), + // GPP_B9 missing + // GPP_B10 missing + PAD_CFG_GPI(GPP_B11, NONE, PLTRST), // PMCALERT# + PAD_CFG_NF(GPP_B12, NONE, DEEP, NF1), // SLP_S0# + PAD_CFG_NF(GPP_B13, NONE, DEEP, NF1), // PLT_RST# + PAD_NC(GPP_B14, NONE), // TOP SWAP OVERRIDE strap + PAD_CFG_GPO(GPP_B15, 1, PLTRST), // WLAN_RST#_R + _PAD_CFG_STRUCT(GPP_B16, 0x80100100, 0x0000), // INTP_OUT + PAD_NC(GPP_B17, NONE), + PAD_NC(GPP_B18, NONE), // NO REBOOT strap + // GPP_B19 missing + // GPP_B20 missing + // GPP_B21 missing + // GPP_B22 missing + PAD_NC(GPP_B23, NONE), // CPUNSSC CLOCK FREQ strap + + /* ------- GPIO Group GPP_C ------- */ + PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), // SMB_CLK + PAD_CFG_NF(GPP_C1, NONE, DEEP, NF1), // SMB_DATA + PAD_CFG_GPO(GPP_C2, 1, PLTRST), // M2_SSD2_PWR_EN + PAD_NC(GPP_C3, NONE), + PAD_NC(GPP_C4, NONE), + PAD_CFG_GPO(GPP_C5, 1, PLTRST), // LAN_RTD3#, TLS CONFIDENTIALITY strap + PAD_NC(GPP_C6, NONE), + PAD_NC(GPP_C7, NONE), + // GPP_C8 missing + // GPP_C9 missing + // GPP_C10 missing + // GPP_C11 missing + // GPP_C12 missing + // GPP_C13 missing + // GPP_C14 missing + // GPP_C15 missing + // GPP_C16 missing + // GPP_C17 missing + // GPP_C18 missing + // GPP_C19 missing + // GPP_C20 missing + // GPP_C21 missing + // GPP_C22 missing + // GPP_C23 missing + + /* ------- GPIO Group GPP_D ------- */ + PAD_CFG_GPO(GPP_D0, 1, DEEP), // SB_BLON + PAD_CFG_GPI(GPP_D1, NONE, DEEP), // SB_KBCRST# + PAD_NC(GPP_D2, NONE), + PAD_NC(GPP_D3, NONE), + PAD_NC(GPP_D4, NONE), + // GPP_D5 (SSD1_CLKREQ#) configured by FSP + PAD_NC(GPP_D6, NONE), + PAD_NC(GPP_D7, NONE), + // GPP_D8 (GPU_PCIE_CLKREQ3#) configured by FSP + PAD_NC(GPP_D9, NONE), + PAD_NC(GPP_D10, NONE), // strap + PAD_NC(GPP_D11, NONE), + PAD_NC(GPP_D12, NONE), // strap + PAD_CFG_GPO(GPP_D13, 0, DEEP), // WLAN_WAKEUP# + PAD_CFG_GPO(GPP_D14, 1, PLTRST), // M2_SSD1_PWR_EN + PAD_NC(GPP_D15, NONE), + PAD_CFG_GPO(GPP_D16, 0, DEEP), // TEST_R + PAD_NC(GPP_D17, NONE), + PAD_NC(GPP_D18, NONE), + PAD_NC(GPP_D19, NONE), + + /* ------- GPIO Group GPP_E ------- */ + PAD_CFG_GPI(GPP_E0, NONE, DEEP), // CNVI_WAKE# + _PAD_CFG_STRUCT(GPP_E1, 0x40100100, 0x3000), // TPM_PIRQ# + PAD_NC(GPP_E2, NONE), // BOARD_ID5 + PAD_CFG_GPO(GPP_E3, 1, DEEP), // PCH_WLAN_EN + PAD_NC(GPP_E4, NONE), + PAD_NC(GPP_E5, NONE), + PAD_NC(GPP_E6, NONE), // JTAG ODT DISABLE strap + PAD_NC(GPP_E7, NONE), + PAD_CFG_GPO(GPP_E8, 0, DEEP), // SLP_DRAM# + PAD_NC(GPP_E9, NONE), // SWI# + PAD_NC(GPP_E10, NONE), // strap + PAD_NC(GPP_E11, NONE), // strap + PAD_NC(GPP_E12, NONE), // BOARD_ID4 + PAD_NC(GPP_E13, NONE), + PAD_CFG_NF(GPP_E14, NONE, DEEP, NF1), // EDP_HPD + PAD_NC(GPP_E15, NONE), + PAD_NC(GPP_E16, NONE), + PAD_NC(GPP_E17, NONE), + PAD_NC(GPP_E18, NONE), + PAD_NC(GPP_E19, NONE), // strap + PAD_NC(GPP_E20, NONE), + PAD_NC(GPP_E21, NONE), // strap + PAD_NC(GPP_E22, NONE), + PAD_NC(GPP_E23, NONE), + + /* ------- GPIO Group GPP_F ------- */ + PAD_CFG_NF(GPP_F0, NONE, DEEP, NF1), // CNVI_BRI_DT + PAD_CFG_NF(GPP_F1, UP_20K, DEEP, NF1), // CNVI_BRI_RSP + PAD_CFG_NF(GPP_F2, NONE, DEEP, NF1), // CNVI_RGI_DT + PAD_CFG_NF(GPP_F3, UP_20K, DEEP, NF1), // CNVI_RGI_RSP + PAD_CFG_NF(GPP_F4, NONE, DEEP, NF1), // CNVI_RF_RST# + // GPP_F5 (XTAL_CLKREQ) configured by FSP + PAD_CFG_NF(GPP_F6, NONE, DEEP, NF1), // CNVI_GNSS_PA_BLANKING + PAD_CFG_GPO(GPP_F7, 1, DEEP), // GPP_LAN_RST# + // GPP_F8 missing + PAD_NC(GPP_F9, NONE), + PAD_NC(GPP_F10, NONE), // strap + PAD_NC(GPP_F11, NONE), // BOARD_ID3 + PAD_CFG_GPI(GPP_F12, NONE, PLTRST), // GPIO4_GC6_NVVDD_EN_R + PAD_CFG_GPI(GPP_F13, NONE, PLTRST), // GC6_FB_EN_PCH + PAD_NC(GPP_F14, NONE), // BOARD_ID1 + PAD_NC(GPP_F15, NONE), // BOARD_ID2 + PAD_NC(GPP_F16, NONE), // BOARD_ID6 + PAD_NC(GPP_F17, NONE), // BOARD_ID7 + PAD_CFG_GPO(GPP_F18, 1, DEEP), // CCD_FW_WP# + // GPP_F19 (GLAN_CLKREQ#) configured by FSP + PAD_CFG_GPO(GPP_F20, 1, PLTRST), // M2_SSD1_RST# + PAD_CFG_GPO(GPP_F21, 1, PLTRST), // M2_SSD2_RST# + PAD_NC(GPP_F22, NONE), + PAD_NC(GPP_F23, NONE), + + /* ------- GPIO Group GPP_H ------- */ + PAD_NC(GPP_H0, NONE), // strap + PAD_NC(GPP_H1, NONE), // strap + PAD_NC(GPP_H2, NONE), // strap + PAD_CFG_GPI(GPP_H3, NONE, DEEP), // TPM_DET + PAD_CFG_NF(GPP_H4, NONE, DEEP, NF1), // I2C_SDA_TP + PAD_CFG_NF(GPP_H5, NONE, DEEP, NF1), // I2C_SCL_TP + PAD_CFG_NF(GPP_H6, NONE, DEEP, NF1), // SMD_7411 + PAD_CFG_NF(GPP_H7, NONE, DEEP, NF1), // SMC_7411 + PAD_CFG_GPO(GPP_H8, 0, DEEP), // CNVI_MFUART2_RXD + PAD_CFG_GPO(GPP_H9, 0, DEEP), // CNVI_MFUART2_TXD + // GPP_H10 (UART0_RX) configured in bootblock + // GPP_H11 (UART0_TX) configured in bootblock + PAD_NC(GPP_H12, NONE), + PAD_NC(GPP_H13, NONE), + // GPP_H14 missing + PAD_CFG_NF(GPP_H15, NONE, DEEP, NF1), // I_MDP_CLK + // GPP_H16 missing + PAD_CFG_NF(GPP_H17, NONE, DEEP, NF1), // I_MDP_DATA + PAD_CFG_NF(GPP_H18, NONE, DEEP, NF1), // CPU_C10_GATE# + // GPP_H19 (SSD2_CLKREQ4#) configured by FSP + PAD_NC(GPP_H20, NONE), + PAD_NC(GPP_H21, NONE), + PAD_NC(GPP_H22, NONE), + // GPP_H23 (WLAN_CLKREQ5#) configured by FSP + + /* ------- GPIO Group GPP_R ------- */ + PAD_CFG_NF(GPP_R0, NONE, DEEP, NF1), // HDA_BITCLK + PAD_CFG_NF(GPP_R1, NATIVE, DEEP, NF1), // HDA_SYNC + PAD_CFG_NF(GPP_R2, NATIVE, DEEP, NF1), // HDA_SDOUT / ME_WE + PAD_CFG_NF(GPP_R3, NATIVE, DEEP, NF1), // HDA_SDIN0 + PAD_CFG_NF(GPP_R4, NONE, DEEP, NF1), // AZ_RST#_R + PAD_NC(GPP_R5, NONE), + PAD_NC(GPP_R6, NONE), + PAD_NC(GPP_R7, NONE), + + /* ------- GPIO Group GPP_S ------- */ + PAD_NC(GPP_S0, NONE), + PAD_NC(GPP_S1, NONE), + PAD_NC(GPP_S2, NONE), + PAD_NC(GPP_S3, NONE), + PAD_NC(GPP_S4, NONE), + PAD_NC(GPP_S5, NONE), + PAD_NC(GPP_S6, NONE), + PAD_NC(GPP_S7, NONE), + + /* ------- GPIO Group GPP_T ------- */ + PAD_NC(GPP_T2, NONE), + PAD_NC(GPP_T3, NONE), +}; + +void mainboard_configure_gpios(void) +{ + gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table)); +} diff --git a/src/mainboard/system76/rpl/variants/gaze20/gpio_early.c b/src/mainboard/system76/rpl/variants/gaze20/gpio_early.c new file mode 100644 index 00000000000..85b9307d456 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/gpio_early.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +static const struct pad_config early_gpio_table[] = { + PAD_CFG_GPO(GPP_A14, 0, DEEP), // DGPU_PWR_EN + PAD_CFG_GPO(GPP_B2, 0, DEEP), // DGPU_RST#_PCH + PAD_CFG_NF(GPP_H10, NONE, DEEP, NF1), // UART0_RX + PAD_CFG_NF(GPP_H11, NONE, DEEP, NF1), // UART0_TX +}; + +void mainboard_configure_early_gpios(void) +{ + gpio_configure_pads(early_gpio_table, ARRAY_SIZE(early_gpio_table)); +} diff --git a/src/mainboard/system76/rpl/variants/gaze20/hda_verb.c b/src/mainboard/system76/rpl/variants/gaze20/hda_verb.c new file mode 100644 index 00000000000..34260753541 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/hda_verb.c @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +const u32 cim_verb_data[] = { + /* Realtek, ALC255 */ + 0x10ec0255, /* Vendor ID */ + 0x15582560, /* Subsystem ID */ + 12, /* Number of entries */ + AZALIA_SUBVENDOR(0, 0x15582560), + AZALIA_RESET(1), + AZALIA_PIN_CFG(0, 0x12, 0x90a60130), + AZALIA_PIN_CFG(0, 0x14, 0x90170110), + AZALIA_PIN_CFG(0, 0x17, 0x40000000), + AZALIA_PIN_CFG(0, 0x18, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x19, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x1a, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x1b, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x1d, 0x41e79b45), + AZALIA_PIN_CFG(0, 0x1e, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x21, 0x04211020), +}; + +const u32 pc_beep_verbs[] = {}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/system76/rpl/variants/gaze20/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/gaze20/include/variant/gpio.h new file mode 100644 index 00000000000..fcf1eef0de2 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_F13 +#define DGPU_SSID 0x25601558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb b/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb new file mode 100644 index 00000000000..79f858a65bc --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/overridetree.cb @@ -0,0 +1,104 @@ +# SPDX-License-Identifier: GPL-2.0-only + +chip soc/intel/alderlake + register "max_dram_speed_mts" = "6400" + + device domain 0 on + subsystemid 0x1558 0x2560 inherit + + device ref igpu on + # DDIA is eDP, DDIB is mDP, TCP3 (DDI4) is USB-C + register "ddi_portA_config" = "1" + register "ddi_ports_config" = "{ + [DDI_PORT_A] = DDI_ENABLE_HPD, + [DDI_PORT_B] = DDI_ENABLE_HPD | DDI_ENABLE_DDC, + [DDI_PORT_4] = DDI_ENABLE_HPD, + }" + + register "gfx" = "GMA_DEFAULT_PANEL(0)" + end + + device ref xhci on + register "usb2_ports" = "{ + [0] = USB2_PORT_MID(OC_SKIP), /* USB Type-C */ + [1] = USB2_PORT_MID(OC_SKIP), /* USB 2.0 Type-A audio board */ + [2] = USB2_PORT_MID(OC_SKIP), /* USB 3.0 Type-A motherboard */ + [3] = USB2_PORT_MID(OC_SKIP), /* USB 3.0 Type-A audio board */ + [5] = USB2_PORT_MID(OC_SKIP), /* Fingerprint */ + [7] = USB2_PORT_MID(OC_SKIP), /* Camera */ + [9] = USB2_PORT_MID(OC_SKIP), /* Bluetooth */ + }" + register "usb3_ports" = "{ + [0] = USB3_PORT_DEFAULT(OC_SKIP), /* USB Type-C */ + [2] = USB3_PORT_DEFAULT(OC_SKIP), /* USB 3.0 Type-A motherboard */ + [3] = USB3_PORT_DEFAULT(OC_SKIP), /* USB 3.0 Type-A audio board */ + }" + end + + device ref i2c0 on + # Touchpad I2C bus + register "serial_io_i2c_mode[PchSerialIoIndexI2C0]" = "PchSerialIoPci" + chip drivers/i2c/hid + register "generic.hid" = ""ELAN0412"" + register "generic.desc" = ""ELAN Touchpad"" + register "generic.irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_A17)" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 15 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""FTCS1000"" + register "generic.desc" = ""FocalTech Touchpad"" + register "generic.irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_A17)" + register "generic.detect" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 38 on end + end + end + + device ref pcie5_0 on + # CPU RP#2 x8, Clock 3 (GPU) + register "cpu_pcie_rp[CPU_RP(2)]" = "{ + .clk_src = 3, + .clk_req = 3, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + end + device ref pcie4_0 on + # CPU RP#1 x4, Clock 0 (SSD1) + register "cpu_pcie_rp[CPU_RP(1)]" = "{ + .clk_src = 0, + .clk_req = 0, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "M.2/M 2280 (J_SSD1)" "SlotDataBusWidth4X" + end + device ref pcie4_1 on + # CPU RP#3 x4, Clock 0 (SSD2) + register "cpu_pcie_rp[CPU_RP(3)]" = "{ + .clk_src = 4, + .clk_req = 4, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "M.2/M 2280 (J_SSD2)" "SlotDataBusWidth4X" + end + device ref pcie_rp5 on + # PCH RP#5 x1, Clock 5 (WLAN) + register "pch_pcie_rp[PCH_RP(5)]" = "{ + .clk_src = 5, + .clk_req = 5, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + smbios_slot_desc "SlotTypeM2Socket1_SD" "SlotLengthOther" "M.2/E 2230 (J_WLAN1)" "SlotDataBusWidth1X" + end + device ref pcie_rp7 on + # PCH RP#7 x1, Clock 6 (GLAN) + register "pch_pcie_rp[PCH_RP(7)]" = "{ + .clk_src = 6, + .clk_req = 6, + .flags = PCIE_RP_LTR | PCIE_RP_AER, + }" + device pci 00.0 on end + end + end +end diff --git a/src/mainboard/system76/rpl/variants/gaze20/romstage.c b/src/mainboard/system76/rpl/variants/gaze20/romstage.c new file mode 100644 index 00000000000..2c8a6737bba --- /dev/null +++ b/src/mainboard/system76/rpl/variants/gaze20/romstage.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void mainboard_memory_init_params(FSPM_UPD *mupd) +{ + const struct mb_cfg board_cfg = { + .type = MEM_TYPE_DDR5, + .ect = true, + .LpDdrDqDqsReTraining = 1, + }; + const struct mem_spd spd_info = { + .topo = MEM_TOPO_DIMM_MODULE, + .smbus = { + [0] = { .addr_dimm[0] = 0x50, }, + [1] = { .addr_dimm[0] = 0x52, }, + }, + }; + const bool half_populated = false; + + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + mupd->FspmConfig.PrimaryDisplay = 0; + + mupd->FspmConfig.DmiMaxLinkSpeed = 4; + mupd->FspmConfig.GpioOverride = 0; + + memcfg_init(mupd, &board_cfg, &spd_info, half_populated); +} diff --git a/src/mainboard/system76/rpl/variants/oryp11/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/oryp11/include/variant/gpio.h new file mode 100644 index 00000000000..070f5518194 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/oryp11/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_B2 +#define DGPU_PWR_EN GPP_A14 +#define DGPU_GC6 GPP_F13 +#define DGPU_SSID 0x66a21558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/oryp11/romstage.c b/src/mainboard/system76/rpl/variants/oryp11/romstage.c index 1e597c72a69..2c8a6737bba 100644 --- a/src/mainboard/system76/rpl/variants/oryp11/romstage.c +++ b/src/mainboard/system76/rpl/variants/oryp11/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -19,6 +21,15 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/rpl/variants/oryp12/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/oryp12/include/variant/gpio.h new file mode 100644 index 00000000000..1ac33c53045 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/oryp12/include/variant/gpio.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_R16 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_SSID 0x66a61558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/oryp12/overridetree.cb b/src/mainboard/system76/rpl/variants/oryp12/overridetree.cb index 54f42bee32b..958ab038ada 100644 --- a/src/mainboard/system76/rpl/variants/oryp12/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/oryp12/overridetree.cb @@ -116,6 +116,9 @@ chip soc/intel/alderlake .clk_req = 15, .flags = PCIE_RP_LTR | PCIE_RP_HOTPLUG, }" + chip drivers/intel/dtbt + device pci 00.0 on end + end end end end diff --git a/src/mainboard/system76/rpl/variants/oryp12/romstage.c b/src/mainboard/system76/rpl/variants/oryp12/romstage.c index fe9103240cd..3f9d962b502 100644 --- a/src/mainboard/system76/rpl/variants/oryp12/romstage.c +++ b/src/mainboard/system76/rpl/variants/oryp12/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -22,6 +24,15 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to hybrid graphics mupd->FspmConfig.PrimaryDisplay = 4; diff --git a/src/mainboard/system76/rpl/variants/serw13/include/variant/gpio.h b/src/mainboard/system76/rpl/variants/serw13/include/variant/gpio.h new file mode 100644 index 00000000000..014f22df511 --- /dev/null +++ b/src/mainboard/system76/rpl/variants/serw13/include/variant/gpio.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#define DGPU_RST_N GPP_R16 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_GC6 GPP_A11 +#define DGPU_SSID 0xd5021558 + +#endif diff --git a/src/mainboard/system76/rpl/variants/serw13/overridetree.cb b/src/mainboard/system76/rpl/variants/serw13/overridetree.cb index cc89764c7fc..99ddd63cb78 100644 --- a/src/mainboard/system76/rpl/variants/serw13/overridetree.cb +++ b/src/mainboard/system76/rpl/variants/serw13/overridetree.cb @@ -108,6 +108,9 @@ chip soc/intel/alderlake .clk_req = 15, .flags = PCIE_RP_LTR | PCIE_RP_HOTPLUG, // XXX: AER causes UnsupReq warnings }" + chip drivers/intel/dtbt + device pci 00.0 on end + end end end end diff --git a/src/mainboard/system76/rpl/variants/serw13/romstage.c b/src/mainboard/system76/rpl/variants/serw13/romstage.c index 30a904544cd..f58abadc3d3 100644 --- a/src/mainboard/system76/rpl/variants/serw13/romstage.c +++ b/src/mainboard/system76/rpl/variants/serw13/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -22,6 +24,14 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + // Enable dGPU power + nvidia_set_power(&config); + // Set primary display to internal graphics mupd->FspmConfig.PrimaryDisplay = 0; diff --git a/src/mainboard/system76/tgl-h/Kconfig b/src/mainboard/system76/tgl-h/Kconfig index 7a0d3f56951..185d95c3f0a 100644 --- a/src/mainboard/system76/tgl-h/Kconfig +++ b/src/mainboard/system76/tgl-h/Kconfig @@ -9,10 +9,12 @@ config BOARD_SPECIFIC_OPTIONS select DRIVERS_GENERIC_BAYHUB_LV2 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA select DRIVERS_I2C_HID select DRIVERS_I2C_TAS5825M if BOARD_SYSTEM76_ORYP8 select EC_SYSTEM76_EC select EC_SYSTEM76_EC_DGPU + select EC_SYSTEM76_EC_LOCKDOWN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_CMOS_DEFAULT diff --git a/src/mainboard/system76/tgl-h/Makefile.mk b/src/mainboard/system76/tgl-h/Makefile.mk index 7debd0d8c9c..f2fda437b57 100644 --- a/src/mainboard/system76/tgl-h/Makefile.mk +++ b/src/mainboard/system76/tgl-h/Makefile.mk @@ -1,6 +1,7 @@ ## SPDX-License-Identifier: GPL-2.0-only CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/include +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include bootblock-y += bootblock.c bootblock-y += variants/$(VARIANT_DIR)/gpio_early.c diff --git a/src/mainboard/system76/tgl-h/acpi/mainboard.asl b/src/mainboard/system76/tgl-h/acpi/mainboard.asl index c982a9ee4cb..1cf2a28bcad 100644 --- a/src/mainboard/system76/tgl-h/acpi/mainboard.asl +++ b/src/mainboard/system76/tgl-h/acpi/mainboard.asl @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include + #define EC_GPE_SCI 0x6E #define EC_GPE_SWI 0x6B #include @@ -8,5 +10,8 @@ Scope (\_SB) { #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" + Scope (PEG1) { + #include + } } } diff --git a/src/mainboard/system76/tgl-h/romstage.c b/src/mainboard/system76/tgl-h/romstage.c index f69bae98eb1..8e304359235 100644 --- a/src/mainboard/system76/tgl-h/romstage.c +++ b/src/mainboard/system76/tgl-h/romstage.c @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include +#include #include static const struct mb_cfg board_cfg = { @@ -21,9 +23,21 @@ static const struct mem_spd spd_info = { void mainboard_memory_init_params(FSPM_UPD *mupd) { - variant_memory_init_params(mupd); - const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + mupd->FspmConfig.PrimaryDisplay = 0; + + variant_memory_init_params(mupd); + memcfg_init(mupd, &board_cfg, &spd_info, half_populated); } diff --git a/src/mainboard/system76/tgl-h/include/variant/gpio.h b/src/mainboard/system76/tgl-h/variants/gaze16-3050/include/variant/gpio.h similarity index 53% rename from src/mainboard/system76/tgl-h/include/variant/gpio.h rename to src/mainboard/system76/tgl-h/variants/gaze16-3050/include/variant/gpio.h index 95d576294f6..27e1dc3ef30 100644 --- a/src/mainboard/system76/tgl-h/include/variant/gpio.h +++ b/src/mainboard/system76/tgl-h/variants/gaze16-3050/include/variant/gpio.h @@ -3,7 +3,16 @@ #ifndef VARIANT_GPIO_H #define VARIANT_GPIO_H +#include + +#define DGPU_RST_N GPP_F8 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_GC6 GPP_K11 +#define DGPU_SSID 0x50151558 + +#ifndef __ACPI__ void variant_configure_early_gpios(void); void variant_configure_gpios(void); +#endif #endif diff --git a/src/mainboard/system76/tgl-h/variants/gaze16-3050/overridetree.cb b/src/mainboard/system76/tgl-h/variants/gaze16-3050/overridetree.cb index 8382c084a81..63783d73b12 100644 --- a/src/mainboard/system76/tgl-h/variants/gaze16-3050/overridetree.cb +++ b/src/mainboard/system76/tgl-h/variants/gaze16-3050/overridetree.cb @@ -8,15 +8,11 @@ chip soc/intel/tigerlake # PCIe PEG2 (remapped to PEG1 by FSP) x8, Clock 0 (DGPU) register "PcieClkSrcUsage[0]" = "0x42" register "PcieClkSrcClkReq[0]" = "0" - chip soc/intel/common/block/pcie/rtd3 - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F9)" # DGPU_PWR_EN - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F8)" # DGPU_RST#_PCH - register "enable_delay_ms" = "16" - register "enable_off_delay_ms" = "4" - register "reset_delay_ms" = "10" - register "reset_off_delay_ms" = "4" - register "srcclk_pin" = "0" # GFX_CLKREQ0# - device generic 0 on end + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller end end device ref igpu on diff --git a/src/mainboard/system76/gaze15/include/variant/gpio.h b/src/mainboard/system76/tgl-h/variants/gaze16-3060/include/variant/gpio.h similarity index 53% rename from src/mainboard/system76/gaze15/include/variant/gpio.h rename to src/mainboard/system76/tgl-h/variants/gaze16-3060/include/variant/gpio.h index 95d576294f6..f3f8b01f59e 100644 --- a/src/mainboard/system76/gaze15/include/variant/gpio.h +++ b/src/mainboard/system76/tgl-h/variants/gaze16-3060/include/variant/gpio.h @@ -3,7 +3,16 @@ #ifndef VARIANT_GPIO_H #define VARIANT_GPIO_H +#include + +#define DGPU_RST_N GPP_F8 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_GC6 GPP_K11 +#define DGPU_SSID 0x50e11558 + +#ifndef __ACPI__ void variant_configure_early_gpios(void); void variant_configure_gpios(void); +#endif #endif diff --git a/src/mainboard/system76/tgl-h/variants/gaze16-3060/overridetree.cb b/src/mainboard/system76/tgl-h/variants/gaze16-3060/overridetree.cb index 2915989eeff..60816d571fd 100644 --- a/src/mainboard/system76/tgl-h/variants/gaze16-3060/overridetree.cb +++ b/src/mainboard/system76/tgl-h/variants/gaze16-3060/overridetree.cb @@ -8,15 +8,11 @@ chip soc/intel/tigerlake # PCIe PEG1 x16, Clock 9 (DGPU) register "PcieClkSrcUsage[9]" = "0x41" register "PcieClkSrcClkReq[9]" = "9" - chip soc/intel/common/block/pcie/rtd3 - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F9)" # DGPU_PWR_EN - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F8)" # DGPU_RST#_PCH - register "enable_delay_ms" = "16" - register "enable_off_delay_ms" = "4" - register "reset_delay_ms" = "10" - register "reset_off_delay_ms" = "4" - register "srcclk_pin" = "9" # PEG_CLKREQ# - device generic 0 on end + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller end end device ref igpu on diff --git a/src/mainboard/system76/addw1/include/variant/gpio.h b/src/mainboard/system76/tgl-h/variants/oryp8/include/variant/gpio.h similarity index 53% rename from src/mainboard/system76/addw1/include/variant/gpio.h rename to src/mainboard/system76/tgl-h/variants/oryp8/include/variant/gpio.h index 95d576294f6..33333f0b35c 100644 --- a/src/mainboard/system76/addw1/include/variant/gpio.h +++ b/src/mainboard/system76/tgl-h/variants/oryp8/include/variant/gpio.h @@ -3,7 +3,16 @@ #ifndef VARIANT_GPIO_H #define VARIANT_GPIO_H +#include + +#define DGPU_RST_N GPP_F8 +#define DGPU_PWR_EN GPP_F9 +#define DGPU_GC6 GPP_K11 +#define DGPU_SSID 0x65f11558 + +#ifndef __ACPI__ void variant_configure_early_gpios(void); void variant_configure_gpios(void); +#endif #endif diff --git a/src/mainboard/system76/tgl-h/variants/oryp8/overridetree.cb b/src/mainboard/system76/tgl-h/variants/oryp8/overridetree.cb index 331fe179a70..5cee4eff906 100644 --- a/src/mainboard/system76/tgl-h/variants/oryp8/overridetree.cb +++ b/src/mainboard/system76/tgl-h/variants/oryp8/overridetree.cb @@ -21,15 +21,11 @@ chip soc/intel/tigerlake # PCIe PEG1 x16, Clock 9 (DGPU) register "PcieClkSrcUsage[9]" = "0x41" register "PcieClkSrcClkReq[9]" = "9" - chip soc/intel/common/block/pcie/rtd3 - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_F9)" # DGPU_PWR_EN - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_F8)" # DGPU_RST#_PCH - register "enable_delay_ms" = "16" - register "enable_off_delay_ms" = "4" - register "reset_delay_ms" = "10" - register "reset_off_delay_ms" = "4" - register "srcclk_pin" = "9" # PEG_CLKREQ# - device generic 0 on end + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller end end device ref peg0 on diff --git a/src/mainboard/system76/tgl-u/Kconfig b/src/mainboard/system76/tgl-u/Kconfig index 56f516ff0a3..8da727eb599 100644 --- a/src/mainboard/system76/tgl-u/Kconfig +++ b/src/mainboard/system76/tgl-u/Kconfig @@ -9,11 +9,13 @@ config BOARD_SPECIFIC_OPTIONS select DRIVERS_GENERIC_BAYHUB_LV2 select DRIVERS_GENERIC_CBFS_SERIAL select DRIVERS_GENERIC_CBFS_UUID + select DRIVERS_GFX_NVIDIA if BOARD_SYSTEM76_GALP5 select DRIVERS_I2C_HID select DRIVERS_INTEL_PMC select DRIVERS_INTEL_USB4_RETIMER select EC_SYSTEM76_EC select EC_SYSTEM76_EC_DGPU if BOARD_SYSTEM76_GALP5 + select EC_SYSTEM76_EC_LOCKDOWN select HAVE_ACPI_TABLES select HAVE_CMOS_DEFAULT select HAVE_OPTION_TABLE @@ -73,4 +75,15 @@ config UART_FOR_CONSOLE config USE_PM_ACPI_TIMER default n +# For galp5 with dGPU +if DRIVERS_GFX_NVIDIA + +config ONBOARD_VGA_IS_PRIMARY + default y + +config DRIVERS_GFX_NVIDIA_BRIDGE + default 0x1c + +endif # DRIVERS_GFX_NVIDIA + endif diff --git a/src/mainboard/system76/tgl-u/acpi/mainboard.asl b/src/mainboard/system76/tgl-u/acpi/mainboard.asl index c982a9ee4cb..6adceba1fdd 100644 --- a/src/mainboard/system76/tgl-u/acpi/mainboard.asl +++ b/src/mainboard/system76/tgl-u/acpi/mainboard.asl @@ -1,5 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#if CONFIG(BOARD_SYSTEM76_GALP5) +#include +#endif + #define EC_GPE_SCI 0x6E #define EC_GPE_SWI 0x6B #include @@ -8,5 +12,10 @@ Scope (\_SB) { #include "sleep.asl" Scope (PCI0) { #include "backlight.asl" +#if CONFIG(BOARD_SYSTEM76_GALP5) + Scope (RP01) { // Remapped from RP05 + #include + } +#endif } } diff --git a/src/mainboard/system76/tgl-u/variants/galp5/overridetree.cb b/src/mainboard/system76/tgl-u/variants/galp5/overridetree.cb index 2d5dc150d68..afceaa10239 100644 --- a/src/mainboard/system76/tgl-u/variants/galp5/overridetree.cb +++ b/src/mainboard/system76/tgl-u/variants/galp5/overridetree.cb @@ -147,15 +147,11 @@ chip soc/intel/tigerlake register "PcieRpLtrEnable[4]" = "true" register "PcieClkSrcUsage[2]" = "4" register "PcieClkSrcClkReq[2]" = "2" - chip soc/intel/common/block/pcie/rtd3 - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_U5)" # DGPU_PWR_EN - register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_U4)" # DGPU_RST#_PCH - register "enable_delay_ms" = "16" - register "enable_off_delay_ms" = "4" - register "reset_delay_ms" = "10" - register "reset_off_delay_ms" = "4" - register "srcclk_pin" = "2" # PEG_CLKREQ# - device generic 0 on end + chip drivers/gfx/nvidia + device pci 00.0 on end # VGA controller + device pci 00.1 on end # Audio device + device pci 00.2 on end # USB xHCI Host controller + device pci 00.3 on end # USB Type-C UCSI controller end end device ref pcie_rp9 on diff --git a/src/mainboard/system76/tgl-u/variants/galp5/romstage.c b/src/mainboard/system76/tgl-u/variants/galp5/romstage.c index eb4fd3974bb..e747521789f 100644 --- a/src/mainboard/system76/tgl-u/variants/galp5/romstage.c +++ b/src/mainboard/system76/tgl-u/variants/galp5/romstage.c @@ -1,8 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include +#include #include #include +#include void mainboard_memory_init_params(FSPM_UPD *mupd) { @@ -18,5 +19,17 @@ void mainboard_memory_init_params(FSPM_UPD *mupd) }; const bool half_populated = false; + const struct nvidia_gpu_config config = { + .power_gpio = DGPU_PWR_EN, + .reset_gpio = DGPU_RST_N, + .enable = true, + }; + + // Enable dGPU power + nvidia_set_power(&config); + + // Set primary display to internal graphics + mupd->FspmConfig.PrimaryDisplay = 0; + memcfg_init(mupd, &board_cfg, &spd_info, half_populated); } diff --git a/src/soc/intel/broadwell/Kconfig b/src/northbridge/intel/broadwell/Kconfig similarity index 97% rename from src/soc/intel/broadwell/Kconfig rename to src/northbridge/intel/broadwell/Kconfig index 74650ff2122..e20ac3f1d7f 100644 --- a/src/soc/intel/broadwell/Kconfig +++ b/src/northbridge/intel/broadwell/Kconfig @@ -10,7 +10,7 @@ config SOC_INTEL_BROADWELL select MRC_SETTINGS_PROTECT select REG_SCRIPT select TCO_SPACE_NOT_YET_SPLIT - select INTEL_LYNXPOINT_LP + select SOUTHBRIDGE_INTEL_WILDCATPOINT help Intel Broadwell and Haswell ULT support. @@ -117,6 +117,4 @@ config REFCODE_BLOB_FILE endif # HAVE_REFCODE_BLOB -source "src/soc/intel/broadwell/pch/Kconfig" - endif diff --git a/src/soc/intel/broadwell/Makefile.mk b/src/northbridge/intel/broadwell/Makefile.mk similarity index 90% rename from src/soc/intel/broadwell/Makefile.mk rename to src/northbridge/intel/broadwell/Makefile.mk index 3565cd180bd..ce037157e20 100644 --- a/src/soc/intel/broadwell/Makefile.mk +++ b/src/northbridge/intel/broadwell/Makefile.mk @@ -1,9 +1,8 @@ ## SPDX-License-Identifier: GPL-2.0-only -ifeq ($(CONFIG_SOC_INTEL_BROADWELL),y) -subdirs-y += pch +ifeq ($(CONFIG_SOC_INTEL_BROADWELL),y) -bootblock-y += bootblock.c +bootblock-y += ../haswell/bootblock.c romstage-y += early_init.c romstage-y += raminit.c @@ -11,7 +10,7 @@ romstage-y += report_platform.c romstage-y += romstage.c romstage-$(CONFIG_HAVE_SPD_IN_CBFS) += spd.c -ramstage-y += acpi.c +ramstage-y += ../haswell/acpi.c ramstage-y += finalize.c ramstage-y += gma.c ramstage-y += memmap.c @@ -23,7 +22,7 @@ ramstage-y += pei_data.c romstage-y += pei_data.c ramstage-$(CONFIG_HAVE_REFCODE_BLOB) += refcode.c -CPPFLAGS_common += -Isrc/soc/intel/broadwell/include +CPPFLAGS_common += -Isrc/northbridge/intel/broadwell/include # If an MRC file is an ELF file determine the entry address and first loadable # section offset in the file. Subtract the offset from the entry address to diff --git a/src/soc/intel/broadwell/chip.h b/src/northbridge/intel/broadwell/chip.h similarity index 94% rename from src/soc/intel/broadwell/chip.h rename to src/northbridge/intel/broadwell/chip.h index 2b5cccd56e4..6b02f59ed38 100644 --- a/src/soc/intel/broadwell/chip.h +++ b/src/northbridge/intel/broadwell/chip.h @@ -6,7 +6,7 @@ #include #include -struct soc_intel_broadwell_config { +struct northbridge_intel_broadwell_config { /* * Digital Port Hotplug Enable: * 0x04 = Enabled, 2ms short pulse diff --git a/src/soc/intel/broadwell/early_init.c b/src/northbridge/intel/broadwell/early_init.c similarity index 100% rename from src/soc/intel/broadwell/early_init.c rename to src/northbridge/intel/broadwell/early_init.c diff --git a/src/soc/intel/broadwell/finalize.c b/src/northbridge/intel/broadwell/finalize.c similarity index 100% rename from src/soc/intel/broadwell/finalize.c rename to src/northbridge/intel/broadwell/finalize.c diff --git a/src/soc/intel/broadwell/gma.c b/src/northbridge/intel/broadwell/gma.c similarity index 98% rename from src/soc/intel/broadwell/gma.c rename to src/northbridge/intel/broadwell/gma.c index 639a945d757..a166b7998b0 100644 --- a/src/soc/intel/broadwell/gma.c +++ b/src/northbridge/intel/broadwell/gma.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -285,7 +285,7 @@ int gtt_poll(u32 reg, u32 mask, u32 value) static void gma_setup_panel(struct device *dev) { - struct soc_intel_broadwell_config *conf = config_of(dev); + struct northbridge_intel_broadwell_config *conf = config_of(dev); const struct i915_gpu_panel_config *panel_cfg = &conf->panel_cfg; u32 reg32; @@ -362,7 +362,7 @@ static void gma_setup_panel(struct device *dev) static int igd_get_cdclk_haswell(u32 *const cdsel, int *const inform_pc, struct device *const dev) { - const struct soc_intel_broadwell_config *const conf = config_of(dev); + const struct northbridge_intel_broadwell_config *const conf = config_of(dev); int cdclk = conf->cdclk; /* Check for ULX GT1 or GT2 */ @@ -397,7 +397,7 @@ static int igd_get_cdclk_broadwell(u32 *const cdsel, int *const inform_pc, struct device *const dev) { static const u32 cdsel_by_cdclk[] = { 0, 2, 0, 1, 3 }; - const struct soc_intel_broadwell_config *const conf = config_of(dev); + const struct northbridge_intel_broadwell_config *const conf = config_of(dev); int cdclk = conf->cdclk; /* Check for ULX */ @@ -576,7 +576,7 @@ static void igd_init(struct device *dev) static void gma_generate_ssdt(const struct device *dev) { - const struct soc_intel_broadwell_config *chip = dev->chip_info; + const struct northbridge_intel_broadwell_config *chip = dev->chip_info; drivers_intel_gma_displays_ssdt_generate(&chip->gfx); } diff --git a/src/soc/intel/broadwell/include/soc/acpi.h b/src/northbridge/intel/broadwell/include/soc/acpi.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/acpi.h rename to src/northbridge/intel/broadwell/include/soc/acpi.h diff --git a/src/soc/intel/broadwell/include/soc/igd.h b/src/northbridge/intel/broadwell/include/soc/igd.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/igd.h rename to src/northbridge/intel/broadwell/include/soc/igd.h diff --git a/src/soc/intel/broadwell/include/soc/pci_devs.h b/src/northbridge/intel/broadwell/include/soc/pci_devs.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/pci_devs.h rename to src/northbridge/intel/broadwell/include/soc/pci_devs.h diff --git a/src/soc/intel/broadwell/include/soc/pei_data.h b/src/northbridge/intel/broadwell/include/soc/pei_data.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/pei_data.h rename to src/northbridge/intel/broadwell/include/soc/pei_data.h diff --git a/src/soc/intel/broadwell/include/soc/pei_wrapper.h b/src/northbridge/intel/broadwell/include/soc/pei_wrapper.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/pei_wrapper.h rename to src/northbridge/intel/broadwell/include/soc/pei_wrapper.h diff --git a/src/soc/intel/broadwell/include/soc/refcode.h b/src/northbridge/intel/broadwell/include/soc/refcode.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/refcode.h rename to src/northbridge/intel/broadwell/include/soc/refcode.h diff --git a/src/soc/intel/broadwell/include/soc/romstage.h b/src/northbridge/intel/broadwell/include/soc/romstage.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/romstage.h rename to src/northbridge/intel/broadwell/include/soc/romstage.h diff --git a/src/soc/intel/broadwell/include/soc/systemagent.h b/src/northbridge/intel/broadwell/include/soc/systemagent.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/systemagent.h rename to src/northbridge/intel/broadwell/include/soc/systemagent.h diff --git a/src/soc/intel/broadwell/memmap.c b/src/northbridge/intel/broadwell/memmap.c similarity index 100% rename from src/soc/intel/broadwell/memmap.c rename to src/northbridge/intel/broadwell/memmap.c diff --git a/src/soc/intel/broadwell/minihd.c b/src/northbridge/intel/broadwell/minihd.c similarity index 100% rename from src/soc/intel/broadwell/minihd.c rename to src/northbridge/intel/broadwell/minihd.c diff --git a/src/soc/intel/broadwell/northbridge.c b/src/northbridge/intel/broadwell/northbridge.c similarity index 97% rename from src/soc/intel/broadwell/northbridge.c rename to src/northbridge/intel/broadwell/northbridge.c index 3d2574ba6d2..771df810447 100644 --- a/src/soc/intel/broadwell/northbridge.c +++ b/src/northbridge/intel/broadwell/northbridge.c @@ -406,19 +406,12 @@ struct device_operations broadwell_pci_domain_ops = { #endif }; -struct device_operations broadwell_cpu_bus_ops = { - .read_resources = noop_read_resources, - .set_resources = noop_set_resources, - .init = mp_cpu_bus_init, - .acpi_fill_ssdt = generate_cpu_entries, -}; - static void broadwell_init_pre_device(void *chip_info) { broadwell_run_reference_code(); } -struct chip_operations soc_intel_broadwell_ops = { +struct chip_operations northbridge_intel_broadwell_ops = { .name = "Intel Broadwell", .init = &broadwell_init_pre_device, }; diff --git a/src/soc/intel/broadwell/pei_data.c b/src/northbridge/intel/broadwell/pei_data.c similarity index 89% rename from src/soc/intel/broadwell/pei_data.c rename to src/northbridge/intel/broadwell/pei_data.c index 4853294e903..28adb30e15e 100644 --- a/src/soc/intel/broadwell/pei_data.c +++ b/src/northbridge/intel/broadwell/pei_data.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include static void ABI_X86 send_to_console(unsigned char b) @@ -15,7 +15,7 @@ static void ABI_X86 send_to_console(unsigned char b) void broadwell_fill_pei_data(struct pei_data *pei_data) { - const struct soc_intel_broadwell_config *cfg = config_of_soc(); + const struct northbridge_intel_broadwell_config *cfg = config_of_soc(); pei_data->pei_version = PEI_VERSION; pei_data->board_type = BOARD_TYPE_ULT; diff --git a/src/soc/intel/broadwell/raminit.c b/src/northbridge/intel/broadwell/raminit.c similarity index 100% rename from src/soc/intel/broadwell/raminit.c rename to src/northbridge/intel/broadwell/raminit.c diff --git a/src/soc/intel/broadwell/refcode.c b/src/northbridge/intel/broadwell/refcode.c similarity index 100% rename from src/soc/intel/broadwell/refcode.c rename to src/northbridge/intel/broadwell/refcode.c diff --git a/src/soc/intel/broadwell/report_platform.c b/src/northbridge/intel/broadwell/report_platform.c similarity index 100% rename from src/soc/intel/broadwell/report_platform.c rename to src/northbridge/intel/broadwell/report_platform.c diff --git a/src/soc/intel/broadwell/romstage.c b/src/northbridge/intel/broadwell/romstage.c similarity index 100% rename from src/soc/intel/broadwell/romstage.c rename to src/northbridge/intel/broadwell/romstage.c diff --git a/src/soc/intel/broadwell/spd.c b/src/northbridge/intel/broadwell/spd.c similarity index 100% rename from src/soc/intel/broadwell/spd.c rename to src/northbridge/intel/broadwell/spd.c diff --git a/src/northbridge/intel/haswell/native_raminit/Makefile.mk b/src/northbridge/intel/haswell/native_raminit/Makefile.mk index 4bd668a2d6c..7a3346ca787 100644 --- a/src/northbridge/intel/haswell/native_raminit/Makefile.mk +++ b/src/northbridge/intel/haswell/native_raminit/Makefile.mk @@ -18,7 +18,10 @@ romstage-y += setup_wdb.c romstage-y += spd_bitmunching.c romstage-y += testing_io.c romstage-y += timings_refresh.c +romstage-y += train_1d_margins.c romstage-y += train_jedec_write_leveling.c romstage-y += train_read_mpr.c romstage-y += train_receive_enable.c romstage-y += train_sense_amp_offset.c + +romstage-$(CONFIG_DEBUG_RAM_SETUP) += info_dumps.c diff --git a/src/northbridge/intel/haswell/native_raminit/change_margin.c b/src/northbridge/intel/haswell/native_raminit/change_margin.c index 517ddc23a60..2ef8712bf86 100644 --- a/src/northbridge/intel/haswell/native_raminit/change_margin.c +++ b/src/northbridge/intel/haswell/native_raminit/change_margin.c @@ -200,18 +200,109 @@ static void update_data_offset_train( } } -static uint32_t get_max_margin(const enum margin_parameter param) +static uint16_t get_per_bit_reg( + const enum margin_parameter param, + const bool multicast, + const uint8_t channel, + const uint8_t rank, + const uint8_t byte) +{ + switch (param) { + case RdTBit: + if (multicast) { + return DDR_DATA_RX_PER_BIT_RANK(rank); + } else { + return RX_PER_BIT(channel, rank, byte); + } + case WrTBit: + if (multicast) { + return DDR_DATA_TX_PER_BIT_RANK(rank); + } else { + return TX_PER_BIT(channel, rank, byte); + } + case RdVBit: + /** TODO: Broadwell has per-rank RX_OFFSET_VDQ registers **/ + if (multicast) { + return DDR_DATA_RX_OFFSET_VDQ; + } else { + return RX_OFFSET_VDQ(channel, byte); + } + default: + die("%s: Invalid margin parameter %d\n", __func__, param); + } +} + +static void update_per_bit_margin( + struct sysinfo *ctrl, + const enum margin_parameter param, + const uint8_t channel, + const uint8_t rank, + const uint8_t byte, + const uint32_t value) +{ + for (uint8_t bit = 0; bit < NUM_BITS; bit++) { + const uint8_t v_bit = value >> (4 * bit) & 0xf; + switch (param) { + case RdTBit: + ctrl->rxdqpb[channel][rank][byte][bit].center = v_bit; + break; + case WrTBit: + ctrl->txdqpb[channel][rank][byte][bit].center = v_bit; + break; + case RdVBit: + ctrl->rxdqvrefpb[channel][rank][byte][bit].center = v_bit; + break; + default: + break; + } + } +} + +static void change_per_bit_margin( + struct sysinfo *ctrl, + const enum margin_parameter param, + const bool multicast, + const uint8_t in_channel, + const uint8_t rank, + const uint8_t in_byte, + const bool update_ctrl, + const uint32_t value, + const enum regfile_mode regfile) +{ + const bool is_rd = param == RdTBit || param == RdVBit; + const bool is_wr = param == WrTBit; + const uint16_t reg = get_per_bit_reg(param, multicast, in_channel, rank, in_byte); + mchbar_write32(reg, value); + if (multicast) { + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + if (!does_ch_exist(ctrl, channel)) + continue; + + download_regfile(ctrl, channel, true, rank, regfile, 0, is_rd, is_wr); + if (!update_ctrl) + continue; + + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { + update_per_bit_margin(ctrl, param, channel, rank, byte, value); + } + } + } else { + download_regfile(ctrl, in_channel, false, rank, regfile, in_byte, is_rd, is_wr); + if (!update_ctrl) + return; + + update_per_bit_margin(ctrl, param, in_channel, rank, in_byte, value); + } +} + +uint32_t get_max_margin_for_param(const enum margin_parameter param) { switch (param) { - case RcvEna: - case RdT: - case WrT: - case WrDqsT: - return MAX_POSSIBLE_TIME; case RdV: + case WrV: return MAX_POSSIBLE_VREF; default: - die("%s: Invalid margin parameter %u\n", __func__, param); + return MAX_POSSIBLE_TIME; } } @@ -233,7 +324,22 @@ void change_margin( if (!en_multicast && !does_ch_exist(ctrl, channel)) die("%s: Tried to change margin of empty channel %u\n", __func__, channel); - const uint32_t max_value = get_max_margin(param); + /* Per-bit margins are handled differently */ + if (param == WrTBit || param == RdTBit || param == RdVBit) { + change_per_bit_margin( + ctrl, + param, + en_multicast, + channel, + rank, + byte, + update_ctrl, + (uint32_t)value0, + regfile); + return; + } + + const uint32_t max_value = get_max_margin_for_param(param); const int32_t v0 = clamp_s32(-max_value, value0, max_value); union ddr_data_offset_train_reg ddr_data_offset_train = { diff --git a/src/northbridge/intel/haswell/native_raminit/info_dumps.c b/src/northbridge/intel/haswell/native_raminit/info_dumps.c new file mode 100644 index 00000000000..5ff6306e7e9 --- /dev/null +++ b/src/northbridge/intel/haswell/native_raminit/info_dumps.c @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include + +#include "raminit_native.h" + +void dump_capid_values(void) +{ + static const char *const no_yes[] = { + [0] = "No", + [1] = "Yes", + }; + static const char *const cdid_decoder[] = { + [0] = "Desktop", + [1] = "Server", + [2] = "Mobile", + [3] = "Marketing Spare", + }; + static const char *const ddrsz_lut[] = { + [0] = "16", + [1] = "8", + [2] = "2", + [3] = "0.5", + }; + static const char *const pegfx1_lut[] = { + [0] = "Unlimited width", + [1] = "Limited to x1", + }; + static const char *const dmfc_lut[] = { + [0] = "Unlimited", + [1] = "Up to DDR3-2667", + [2] = "Up to DDR3-2400", + [3] = "Up to DDR3-2133", + [4] = "Up to DDR3-1867", + [5] = "Up to DDR3-1600", + [6] = "Up to DDR3-1333", + [7] = "Up to DDR3-1067", + }; + static const char *const ddd_lut[] = { + [0] = "Debug", + [1] = "Production", + }; + static const char *const pll100_lut[] = { + [0] = "Not supported", + [1] = "Up to DDR3-1400", + [2] = "Up to DDR3-1600", + [3] = "Up to DDR3-1800", + [4] = "Up to DDR3-2000", + [5] = "Up to DDR3-2200", + [6] = "Up to DDR3-2400", + [7] = "Unlimited", + }; + static const char *const occtl_lut[] = { + [0] = "DSKU", + [1] = "SSKU", + }; + + const union pci_capid0_a_reg capid0_a = { + .raw = pci_read_config32(HOST_BRIDGE, CAPID0_A) + }; + const union pci_capid0_b_reg capid0_b = { + .raw = pci_read_config32(HOST_BRIDGE, CAPID0_B) + }; + printk(BIOS_DEBUG, "\n"); + printk(BIOS_DEBUG, "CAPID0_A: 0x%08x\n", capid0_a.raw); + printk(BIOS_DEBUG, " DDR3L 1.35V: %s\n", no_yes[capid0_a.DDR3L_EN]); + printk(BIOS_DEBUG, " DDR Write Vref: %s\n", no_yes[capid0_a.DDR_WRTVREF]); + printk(BIOS_DEBUG, " OC enabled (DSKU): %s\n", no_yes[capid0_a.OC_ENABLED_DSKU]); + printk(BIOS_DEBUG, " DDR overclock: %s\n", no_yes[capid0_a.DDR_OVERCLOCK]); + printk(BIOS_DEBUG, " Compatibility RID: 0x%01x\n", capid0_a.CRID); + printk(BIOS_DEBUG, " Capability DID: %s\n", cdid_decoder[capid0_a.CDID]); + printk(BIOS_DEBUG, " DID override: %s\n", no_yes[capid0_a.DIDOE]); + printk(BIOS_DEBUG, " Integrated GPU: %s\n", no_yes[!capid0_a.IGD]); + printk(BIOS_DEBUG, " Dual channel: %s\n", no_yes[!capid0_a.PDCD]); + printk(BIOS_DEBUG, " X2APIC support: %s\n", no_yes[capid0_a.X2APIC_EN]); + printk(BIOS_DEBUG, " DIMMs per channel: %u\n", capid0_a.DDPCD ? 1 : 2); + printk(BIOS_DEBUG, " Camarillo device: %s\n", no_yes[!capid0_a.CDD]); + printk(BIOS_DEBUG, " Full ULT info: %s\n", no_yes[!capid0_a.FUFRD]); + printk(BIOS_DEBUG, " DDR 1N mode: %s\n", no_yes[!capid0_a.D1NM]); + printk(BIOS_DEBUG, " PCIe ratio: %s\n", no_yes[!capid0_a.PCIE_RATIO_DIS]); + printk(BIOS_DEBUG, " Max channel size: %s GiB\n", ddrsz_lut[capid0_a.DDRSZ]); + printk(BIOS_DEBUG, " PEG Gen2 support: %s\n", no_yes[!capid0_a.PEGG2DIS]); + printk(BIOS_DEBUG, " DMI Gen2 support: %s\n", no_yes[!capid0_a.DMIG2DIS]); + printk(BIOS_DEBUG, " VT-d support: %s\n", no_yes[!capid0_a.VTDD]); + printk(BIOS_DEBUG, " ECC forced: %s\n", no_yes[capid0_a.FDEE]); + printk(BIOS_DEBUG, " ECC supported: %s\n", no_yes[!capid0_a.ECCDIS]); + printk(BIOS_DEBUG, " DMI width: x%u\n", capid0_a.DW ? 2 : 4); + printk(BIOS_DEBUG, " Width upconfig: %s\n", no_yes[!capid0_a.PELWUD]); + printk(BIOS_DEBUG, " PEG function 0: %s\n", no_yes[!capid0_a.PEG10D]); + printk(BIOS_DEBUG, " PEG function 1: %s\n", no_yes[!capid0_a.PEG11D]); + printk(BIOS_DEBUG, " PEG function 2: %s\n", no_yes[!capid0_a.PEG12D]); + printk(BIOS_DEBUG, " Disp HD audio: %s\n", no_yes[!capid0_a.DHDAD]); + printk(BIOS_DEBUG, "\n"); + printk(BIOS_DEBUG, "CAPID0_B: 0x%08x\n", capid0_b.raw); + printk(BIOS_DEBUG, " PEG for GFX single: %s\n", pegfx1_lut[capid0_b.SPEGFX1]); + printk(BIOS_DEBUG, " PEG for GFX multi: %s\n", pegfx1_lut[capid0_b.DPEGFX1]); + printk(BIOS_DEBUG, " 133 MHz ref clock: %s\n", dmfc_lut[capid0_b.DMFC]); + printk(BIOS_DEBUG, " Silicon mode: %s\n", ddd_lut[capid0_b.DDD]); + printk(BIOS_DEBUG, " HDCP capable: %s\n", no_yes[!capid0_b.HDCPD]); + printk(BIOS_DEBUG, " Num PEG lanes: %u\n", capid0_b.PEGX16D ? 8 : 16); + printk(BIOS_DEBUG, " Add. GFX capable: %s\n", no_yes[!capid0_b.ADDGFXCAP]); + printk(BIOS_DEBUG, " Add. GFX enable: %s\n", no_yes[capid0_b.ADDGFXEN]); + printk(BIOS_DEBUG, " CPU Package Type: %u\n", capid0_b.PKGTYP); + printk(BIOS_DEBUG, " PEG Gen3 support: %s\n", no_yes[!capid0_b.PEGG3_DIS]); + printk(BIOS_DEBUG, " 100 MHz ref clock: %s\n", pll100_lut[capid0_b.PLL_REF100_CFG]); + printk(BIOS_DEBUG, " Soft Bin capable: %s\n", no_yes[capid0_b.SOFTBIN]); + printk(BIOS_DEBUG, " Cache size: %u\n", capid0_b.CACHESZ); + printk(BIOS_DEBUG, " SMT support: %s\n", no_yes[capid0_b.SMT]); + printk(BIOS_DEBUG, " OC enabled (SSKU): %s\n", no_yes[capid0_b.OC_ENABLED_SSKU]); + printk(BIOS_DEBUG, " OC controlled by: %s\n", occtl_lut[capid0_b.OC_CTL_DSKU_DIS]); + printk(BIOS_DEBUG, "\n"); +} diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_main.c b/src/northbridge/intel/haswell/native_raminit/raminit_main.c index 84db33ebdf3..91c1920725a 100644 --- a/src/northbridge/intel/haswell/native_raminit/raminit_main.c +++ b/src/northbridge/intel/haswell/native_raminit/raminit_main.c @@ -129,6 +129,9 @@ static const struct task_entry cold_boot[] = { { train_receive_enable, true, "RCVET", }, { train_read_mpr, true, "RDMPRT", }, { train_jedec_write_leveling, true, "JWRL", }, + { train_write_timing_centering, true, "WRTC1D", }, + { train_read_timing_centering, true, "RDTC1D", }, + { train_read_voltage_centering, true, "RDVC1D", }, { optimise_comp, true, "OPTCOMP", }, { post_training, true, "POSTTRAIN", }, { activate_mc, true, "ACTIVATE", }, diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.c b/src/northbridge/intel/haswell/native_raminit/raminit_native.c index d5b5c117d68..ab1e4ff1a39 100644 --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.c +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.c @@ -171,6 +171,11 @@ void perform_raminit(const bool s3resume) */ const enum raminit_boot_mode orig_bootmode = get_boot_mode(); + if (CONFIG(DEBUG_RAM_SETUP)) { + /* Log CAPID values before dynamic fusing takes place */ + dump_capid_values(); + } + const bool cpu_replaced = early_init_native(s3resume ? BOOTMODE_S3 : orig_bootmode); wait_txt_clear(); diff --git a/src/northbridge/intel/haswell/native_raminit/raminit_native.h b/src/northbridge/intel/haswell/native_raminit/raminit_native.h index 53dbe4df289..59dee35abee 100644 --- a/src/northbridge/intel/haswell/native_raminit/raminit_native.h +++ b/src/northbridge/intel/haswell/native_raminit/raminit_native.h @@ -68,6 +68,29 @@ enum margin_parameter { WrT, WrDqsT, RdV, + WrV, + WrLevel, + WrTBit, + RdTBit, + RdVBit, + INVALID_MARGIN, +}; + +/* + * This enum is used to index an array of margin results. Those are + * used to keep track of available margin in more advanced training + * algorithms (optimisation), c.f. margin_result member in sysinfo. + */ +enum last_margin_param { + LastRxV, + LastRxT, + LastTxV, + LastTxT, + LastRcvEna, + LastWrLevel, + LastCmdT, + LastCmdV, + MAX_RESULT_TYPE, }; enum opt_param { @@ -232,6 +255,7 @@ enum raminit_status { RAMINIT_STATUS_SUCCESS = 0, RAMINIT_STATUS_NO_MEMORY_INSTALLED, RAMINIT_STATUS_UNSUPPORTED_MEMORY, + RAMINIT_STATUS_INVALID_PARAMETER, RAMINIT_STATUS_MPLL_INIT_FAILURE, RAMINIT_STATUS_POLL_TIMEOUT, RAMINIT_STATUS_REUT_ERROR, @@ -239,6 +263,7 @@ enum raminit_status { RAMINIT_STATUS_RCVEN_FAILURE, RAMINIT_STATUS_RMPR_FAILURE, RAMINIT_STATUS_JWRL_FAILURE, + RAMINIT_STATUS_1D_MARGINING_FAILURE, RAMINIT_STATUS_INVALID_CACHE, RAMINIT_STATUS_UNSPECIFIED_ERROR, /** TODO: Deprecated in favor of specific values **/ }; @@ -261,12 +286,32 @@ struct raminit_dimm_info { bool valid; }; +struct last_margin { + uint32_t start; + uint32_t end; +}; + +struct time_margin { + uint8_t left; + uint8_t center; + uint8_t right; +}; + struct vref_margin { uint8_t low; uint8_t center; uint8_t high; }; +union raw_bitlane_errors { + struct { + uint32_t lower; + uint32_t upper; + uint8_t ecc; + }; + uint8_t per_byte[NUM_LANES]; +}; + struct sysinfo { enum raminit_boot_mode bootmode; enum generic_stepping stepping; @@ -355,6 +400,9 @@ struct sysinfo { uint8_t rxdqsn[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES]; int8_t rxvref[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES]; + struct time_margin rxdqpb[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES][NUM_BITS]; + struct time_margin txdqpb[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES][NUM_BITS]; + struct vref_margin rxdqvrefpb[NUM_CHANNELS][NUM_SLOTRANKS][NUM_LANES][NUM_BITS]; uint8_t clk_pi_code[NUM_CHANNELS][NUM_SLOTRANKS]; @@ -365,6 +413,11 @@ struct sysinfo { uint8_t cmd_north_pi_code[NUM_CHANNELS][NUM_GROUPS]; uint8_t cmd_south_pi_code[NUM_CHANNELS][NUM_GROUPS]; + /* + * BIG WARNING: The slotrank comes before the channel! + */ + struct last_margin results[MAX_RESULT_TYPE][NUM_SLOTRANKS][NUM_CHANNELS][NUM_LANES]; + union tc_bank_reg tc_bank[NUM_CHANNELS]; union tc_bank_rank_a_reg tc_bankrank_a[NUM_CHANNELS]; union tc_bank_rank_b_reg tc_bankrank_b[NUM_CHANNELS]; @@ -488,6 +541,9 @@ enum raminit_status train_sense_amp_offset(struct sysinfo *ctrl); enum raminit_status train_receive_enable(struct sysinfo *ctrl); enum raminit_status train_read_mpr(struct sysinfo *ctrl); enum raminit_status train_jedec_write_leveling(struct sysinfo *ctrl); +enum raminit_status train_read_timing_centering(struct sysinfo *ctrl); +enum raminit_status train_write_timing_centering(struct sysinfo *ctrl); +enum raminit_status train_read_voltage_centering(struct sysinfo *ctrl); enum raminit_status optimise_comp(struct sysinfo *ctrl); enum raminit_status save_training_values(struct sysinfo *ctrl); enum raminit_status restore_training_values(struct sysinfo *ctrl); @@ -536,6 +592,7 @@ void reut_issue_mrs_all( const uint16_t val[NUM_SLOTS]); enum raminit_status reut_issue_zq(struct sysinfo *ctrl, uint8_t chanmask, uint8_t zq_type); +union raw_bitlane_errors get_bitlane_errors(const uint8_t channel); void write_wdb_fixed_pat( const struct sysinfo *ctrl, @@ -604,6 +661,8 @@ void download_regfile( bool read_rf_rd, bool read_rf_wr); +uint32_t get_max_margin_for_param(const enum margin_parameter param); + void change_margin( struct sysinfo *ctrl, const enum margin_parameter param, @@ -644,4 +703,6 @@ uint8_t get_tCWL(uint32_t mem_clock_mhz); uint32_t get_tREFI(uint32_t mem_clock_mhz); uint32_t get_tXP(uint32_t mem_clock_mhz); +void dump_capid_values(void); + #endif diff --git a/src/northbridge/intel/haswell/native_raminit/reg_structs.h b/src/northbridge/intel/haswell/native_raminit/reg_structs.h index b0a121fa1aa..9a64b2903ab 100644 --- a/src/northbridge/intel/haswell/native_raminit/reg_structs.h +++ b/src/northbridge/intel/haswell/native_raminit/reg_structs.h @@ -3,6 +3,65 @@ #ifndef HASWELL_RAMINIT_REG_STRUCTS_H #define HASWELL_RAMINIT_REG_STRUCTS_H +union pci_capid0_a_reg { + struct __packed { + uint32_t DDR3L_EN : 1; // Bits 0:0 + uint32_t DDR_WRTVREF : 1; // Bits 1:1 + uint32_t OC_ENABLED_DSKU : 1; // Bits 2:2 + uint32_t DDR_OVERCLOCK : 1; // Bits 3:3 + uint32_t CRID : 4; // Bits 7:4 + uint32_t CDID : 2; // Bits 9:8 + uint32_t DIDOE : 1; // Bits 10:10 + uint32_t IGD : 1; // Bits 11:11 + uint32_t PDCD : 1; // Bits 12:12 + uint32_t X2APIC_EN : 1; // Bits 13:13 + uint32_t DDPCD : 1; // Bits 14:14 + uint32_t CDD : 1; // Bits 15:15 + uint32_t FUFRD : 1; // Bits 16:16 + uint32_t D1NM : 1; // Bits 17:17 + uint32_t PCIE_RATIO_DIS : 1; // Bits 18:18 + uint32_t DDRSZ : 2; // Bits 20:19 + uint32_t PEGG2DIS : 1; // Bits 21:21 + uint32_t DMIG2DIS : 1; // Bits 22:22 + uint32_t VTDD : 1; // Bits 23:23 + uint32_t FDEE : 1; // Bits 24:24 + uint32_t ECCDIS : 1; // Bits 25:25 + uint32_t DW : 1; // Bits 26:26 + uint32_t PELWUD : 1; // Bits 27:27 + uint32_t PEG10D : 1; // Bits 28:28 + uint32_t PEG11D : 1; // Bits 29:29 + uint32_t PEG12D : 1; // Bits 30:30 + uint32_t DHDAD : 1; // Bits 31:31 + }; + uint32_t raw; +}; + +union pci_capid0_b_reg { + struct __packed { + uint32_t SPEGFX1 : 1; // Bits 0:0 + uint32_t DPEGFX1 : 1; // Bits 1:1 + uint32_t : 2; // Bits 3:2 + uint32_t DMFC : 3; // Bits 6:4 + uint32_t DDD : 1; // Bits 7:7 + uint32_t : 3; // Bits 10:8 + uint32_t HDCPD : 1; // Bits 11:11 + uint32_t : 4; // Bits 15:12 + uint32_t PEGX16D : 1; // Bits 16:16 + uint32_t ADDGFXCAP : 1; // Bits 17:17 + uint32_t ADDGFXEN : 1; // Bits 18:18 + uint32_t PKGTYP : 1; // Bits 19:19 + uint32_t PEGG3_DIS : 1; // Bits 20:20 + uint32_t PLL_REF100_CFG : 3; // Bits 23:21 + uint32_t SOFTBIN : 1; // Bits 24:24 + uint32_t CACHESZ : 3; // Bits 27:25 + uint32_t SMT : 1; // Bits 28:28 + uint32_t OC_ENABLED_SSKU : 1; // Bits 29:29 + uint32_t OC_CTL_DSKU_DIS : 1; // Bits 30:30 + uint32_t : 1; // Bits 31:31 + }; + uint32_t raw; +}; + union ddr_data_rx_train_rank_reg { struct __packed { uint32_t rcven : 9; // Bits 8:0 diff --git a/src/northbridge/intel/haswell/native_raminit/reut.c b/src/northbridge/intel/haswell/native_raminit/reut.c index 31019f74a1d..10fb8cc1c36 100644 --- a/src/northbridge/intel/haswell/native_raminit/reut.c +++ b/src/northbridge/intel/haswell/native_raminit/reut.c @@ -194,3 +194,12 @@ enum raminit_status reut_issue_zq(struct sysinfo *ctrl, uint8_t chanmask, uint8_ return status; } + +union raw_bitlane_errors get_bitlane_errors(const uint8_t channel) +{ + return (union raw_bitlane_errors) { + .lower = mchbar_read32(REUT_ch_ERR_DATA_STATUS(channel) + 0), + .upper = mchbar_read32(REUT_ch_ERR_DATA_STATUS(channel) + 4), + .ecc = mchbar_read8(REUT_ch_ERR_MISC_STATUS(channel)), + }; +} diff --git a/src/northbridge/intel/haswell/native_raminit/train_1d_margins.c b/src/northbridge/intel/haswell/native_raminit/train_1d_margins.c new file mode 100644 index 00000000000..bea17f2f1a2 --- /dev/null +++ b/src/northbridge/intel/haswell/native_raminit/train_1d_margins.c @@ -0,0 +1,305 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "raminit_native.h" +#include "ranges.h" + +#define MAX_BITLANE_LINES (2 * MAX_POSSIBLE_BOTH + 1) +#define MARGIN_MIN_WIDTH 8 + +#define MARGIN_1D_PLOT RAM_DEBUG + +static void print_bitlane( + struct sysinfo *ctrl, + const uint8_t channel, + const int32_t m_start, + const int32_t m_step, + const int32_t m_stop, + const union raw_bitlane_errors bit_failures[NUM_CHANNELS][MAX_BITLANE_LINES]) +{ + for (int32_t offset = m_start; offset <= m_stop; offset += m_step) { + const uint32_t index = offset + MAX_POSSIBLE_BOTH; + const union raw_bitlane_errors *failures = &bit_failures[channel][index]; + printk(MARGIN_1D_PLOT, "\n% 5d\t", offset); + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { + const uint8_t byte_errors = failures->per_byte[byte]; + for (uint8_t bit = 0; bit < NUM_BITS; bit++) + printk(MARGIN_1D_PLOT, byte_errors & BIT(bit) ? "#" : "."); + } + } +} + +static enum raminit_status apply_dq_offsets( + struct sysinfo *ctrl, + const uint8_t channel, + const uint8_t rank, + const enum margin_parameter param, + enum raminit_status status, + const struct linear_train_data chan_data[]) +{ + printk(BIOS_DEBUG, "\nC%u.R%u: Left\tRight\tWidth\tCenter\n", channel, rank); + + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { + const struct linear_train_data *const curr_data = &chan_data[byte]; + const int32_t lwidth = range_width(curr_data->largest); + const int32_t center = range_center(curr_data->largest); + printk(BIOS_DEBUG, " B%u: %d\t%d\t%d\t%d", + byte, + curr_data->largest.start, + curr_data->largest.end, + lwidth, + center); + if (lwidth < MARGIN_MIN_WIDTH) { + printk(BIOS_ERR, + "\t1D eye too small! channel: %u byte: %u width: %d\n", + channel, byte, lwidth); + status = RAMINIT_STATUS_1D_MARGINING_FAILURE; + } else { + printk(BIOS_DEBUG, "\n"); + } + const struct last_margin margin = { + .start = ABS(curr_data->largest.start - center) * 10, + .end = ABS(curr_data->largest.end - center) * 10, + }; + switch (param) { + case RdT: + ctrl->rxdqsp[channel][rank][byte] += center; + ctrl->rxdqsn[channel][rank][byte] += center; + update_rxt(ctrl, channel, rank, byte, RXT_RESTORE, 0); + ctrl->results[LastRxT][rank][channel][byte] = margin; + break; + case WrT: + ctrl->tx_dq[channel][rank][byte] += center; + update_txt(ctrl, channel, rank, byte, TXT_RESTORE, 0); + ctrl->results[LastTxT][rank][channel][byte] = margin; + break; + case RdV: + /* RdV training uses half steps */ + ctrl->rxvref[channel][rank][byte] += center / 2; + update_rxt(ctrl, channel, rank, byte, RXT_RESTORE, 0); + ctrl->results[LastRxV][rank][channel][byte] = margin; + break; + default: + break; + } + } + return status; +} + +static const char *const get_delay_string(const enum margin_parameter param) +{ + switch (param) { + case RdT: return "RdDqsDelay"; + case WrT: return "WrDqsDelay"; + case RdV: return "RdVoltage"; + default: return NULL; + } +} + +static enum margin_parameter get_per_bit_margin_param(const enum margin_parameter param) +{ + switch (param) { + case RdT: return RdTBit; + case WrT: return WrTBit; + case RdV: return RdVBit; + default: return INVALID_MARGIN; + } +} + +static enum raminit_status train_1d_margin( + struct sysinfo *ctrl, + const uint8_t chanmask_in, + const enum margin_parameter param, + const bool reset_per_bit, + const uint8_t loopcount) +{ + const char *const delay_string = get_delay_string(param); + if (!delay_string) { + printk(BIOS_ERR, "%s: Invalid margin parameter %u\n", __func__, param); + return RAMINIT_STATUS_INVALID_PARAMETER; + } + setup_io_test_basic_va(ctrl, chanmask_in, loopcount, NSOE); + + const enum margin_parameter param_bit = get_per_bit_margin_param(param); + if (reset_per_bit && param_bit == INVALID_MARGIN) { + printk(BIOS_ERR, "%s: Invalid per-bit margin for param %u\n", __func__, param); + return RAMINIT_STATUS_INVALID_PARAMETER; + } + + const int32_t m_stop = get_max_margin_for_param(param); + const int32_t m_start = -m_stop; + const int32_t m_step = 1; + enum raminit_status status = 0; + for (uint8_t rank = 0; rank < NUM_SLOTRANKS; rank++) { + if (!does_rank_exist(ctrl, rank)) + continue; + + /* Hell thinks this should be resetting the currently selected rank */ + if (reset_per_bit) { + change_1d_margin_multicast( + ctrl, + param_bit, + 0x88888888, + rank, + true, + REG_FILE_USE_RANK); + } + printk(BIOS_DEBUG, "Rank %u\n", rank); + printk(MARGIN_1D_PLOT, "Channel"); + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + if (!rank_in_ch(ctrl, rank, channel)) + continue; + + printk(MARGIN_1D_PLOT, "\t%u\t\t", channel); + } + printk(MARGIN_1D_PLOT, "\nByte"); + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + if (!rank_in_ch(ctrl, rank, channel)) + continue; + + printk(MARGIN_1D_PLOT, "\t"); + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) + printk(MARGIN_1D_PLOT, "%u ", byte); + } + uint8_t chanmask = 0; + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + chanmask |= select_reut_ranks(ctrl, channel, BIT(rank)); + if (!(BIT(channel) & chanmask)) + continue; + + /* Update rank timing to middle value */ + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { + if (param == RdT) { + ctrl->rxdqsp[channel][rank][byte] = 32; + ctrl->rxdqsn[channel][rank][byte] = 32; + update_rxt(ctrl, channel, rank, byte, RXT_RESTORE, 0); + } else if (param == WrT) { + /* + * Put TxDq in the middle of the strobe and ensure + * there is enough room to sweep to the right. + */ + uint16_t tx_dq = ctrl->txdqs[channel][rank][byte] + 32; + if ((tx_dq + m_stop) > 511) + tx_dq = 511 - m_stop; + + ctrl->tx_dq[channel][rank][byte] = tx_dq; + update_txt(ctrl, channel, rank, byte, TXT_RESTORE, 0); + } else if (param == RdV) { + ctrl->rxvref[channel][rank][byte] = 0; + update_rxt(ctrl, channel, rank, byte, RXT_RESTORE, 0); + } + } + + /* Set up REUT error counters to count errors per channel */ + mchbar_write32(REUT_ch_ERR_COUNTER_CTL_x(channel, 0), 0); + } + if (!chanmask) + continue; + + clear_data_offset_train_all(ctrl); + printk(MARGIN_1D_PLOT, "\n%s", delay_string); + struct linear_train_data region_data[NUM_CHANNELS][NUM_LANES] = { 0 }; + union raw_bitlane_errors bit_errors[NUM_CHANNELS][MAX_BITLANE_LINES] = { 0 }; + for (int32_t offset = m_start; offset <= m_stop; offset += m_step) { + printk(MARGIN_1D_PLOT, "\n% 5d", offset); + change_1d_margin_multicast( + ctrl, + param, + offset, + 0, + false, + REG_FILE_USE_START); + + run_io_test(ctrl, chanmask, ctrl->dq_pat, 1); + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + if (!(chanmask & BIT(channel))) + continue; + + /* Read out byte group error results and update limit */ + const uint16_t result = get_byte_group_errors(channel); + bit_errors[channel][offset + MAX_POSSIBLE_BOTH] = + get_bitlane_errors(channel); + printk(MARGIN_1D_PLOT, "\t"); + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) { + const bool pass = !(result & BIT(byte)); + printk(MARGIN_1D_PLOT, pass ? ". " : "# "); + linear_record_pass( + ®ion_data[channel][byte], + pass, + offset, + m_start, + m_step); + } + } + } + printk(MARGIN_1D_PLOT, "\n\nBit lane information"); + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + if (!(chanmask & BIT(channel))) + continue; + + printk(MARGIN_1D_PLOT, "\nChannel %u\nByte ", channel); + for (uint8_t byte = 0; byte < ctrl->lanes; byte++) + printk(MARGIN_1D_PLOT, "%u ", byte); + + printk(MARGIN_1D_PLOT, "\nBit "); + for (uint8_t bit_count = 0; bit_count < ctrl->lanes * 8; bit_count++) + printk(MARGIN_1D_PLOT, "%u", bit_count % 8); + + printk(MARGIN_1D_PLOT, "\n%s", delay_string); + print_bitlane( + ctrl, + channel, + m_start, + m_step, + m_stop, + bit_errors); + + printk(MARGIN_1D_PLOT, "\n"); + } + change_1d_margin_multicast( + ctrl, + param, + 0, + 0, + false, + REG_FILE_USE_CURRENT); + + for (uint8_t channel = 0; channel < NUM_CHANNELS; channel++) { + if (!(chanmask & BIT(channel))) + continue; + + status = apply_dq_offsets( + ctrl, + channel, + rank, + param, + status, + region_data[channel]); + } + printk(BIOS_DEBUG, "\n"); + } + + return status; +} + +#define DATA_TRAIN_LOOP_COUNT 15 + +enum raminit_status train_read_timing_centering(struct sysinfo *ctrl) +{ + return train_1d_margin(ctrl, ctrl->chanmap, RdT, true, DATA_TRAIN_LOOP_COUNT); +} + +enum raminit_status train_write_timing_centering(struct sysinfo *ctrl) +{ + return train_1d_margin(ctrl, ctrl->chanmap, WrT, true, DATA_TRAIN_LOOP_COUNT); +} + +enum raminit_status train_read_voltage_centering(struct sysinfo *ctrl) +{ + /* + * We do not reset per-bit RdV. Haswell only has one RX_OFFSET_VDQ register + * per rank, so this would require combining training results for all ranks + * somehow. While Broadwell and newer platforms have per-rank RX_OFFSET_VDQ + * registers, we can keep using sense amp offset training results, for now. + */ + return train_1d_margin(ctrl, ctrl->chanmap, RdV, false, DATA_TRAIN_LOOP_COUNT); +} diff --git a/src/northbridge/intel/haswell/northbridge.c b/src/northbridge/intel/haswell/northbridge.c index c544ad3c388..e819838175c 100644 --- a/src/northbridge/intel/haswell/northbridge.c +++ b/src/northbridge/intel/haswell/northbridge.c @@ -534,13 +534,6 @@ static const struct pci_driver mc_driver_hsw __pci_driver = { .devices = mc_pci_device_ids, }; -struct device_operations haswell_cpu_bus_ops = { - .read_resources = noop_read_resources, - .set_resources = noop_set_resources, - .init = mp_cpu_bus_init, - .acpi_fill_ssdt = generate_cpu_entries, -}; - struct chip_operations northbridge_intel_haswell_ops = { .name = "Intel Haswell integrated Northbridge", }; diff --git a/src/northbridge/intel/haswell/raminit_shared.c b/src/northbridge/intel/haswell/raminit_shared.c index 6fcb0ec98a5..5e3602c31e5 100644 --- a/src/northbridge/intel/haswell/raminit_shared.c +++ b/src/northbridge/intel/haswell/raminit_shared.c @@ -28,15 +28,30 @@ static const char *const ecc_decoder[] = { "active", }; +static bool is_100_mhz_refclk(void) +{ + return mchbar_read32(MC_BIOS_REQ) & (1 << 4); +} + +static unsigned int get_ddr_freq_mhz(void) +{ + /* Use KHz to minimise rounding errors */ + const unsigned int refclk_khz = is_100_mhz_refclk() ? 100000 : 133333; + const unsigned int multiplier = mchbar_read32(MC_BIOS_DATA) & 0xf; + + return DIV_ROUND_CLOSEST(multiplier * refclk_khz, 1000); +} + /* Print out the memory controller configuration, as per the values in its registers. */ void report_memory_config(void) { const uint32_t addr_decoder_common = mchbar_read32(MAD_CHNL); - printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n", - DIV_ROUND_CLOSEST(mchbar_read32(MC_BIOS_DATA) * 13333 * 2, 100)); + const unsigned int refclk_mhz = is_100_mhz_refclk() ? 100 : 133; + printk(BIOS_DEBUG, "memcfg DDR3 ref clock %u MHz\n", refclk_mhz); + printk(BIOS_DEBUG, "memcfg DDR3 clock %u MHz\n", get_ddr_freq_mhz()); - printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n", + printk(BIOS_DEBUG, "memcfg channel assignment: A: %u, B: %u, C: %u\n", (addr_decoder_common >> 0) & 3, (addr_decoder_common >> 2) & 3, (addr_decoder_common >> 4) & 3); @@ -44,7 +59,7 @@ void report_memory_config(void) for (unsigned int i = 0; i < NUM_CHANNELS; i++) { const uint32_t ch_conf = mchbar_read32(MAD_DIMM(i)); - printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n", i, ch_conf); + printk(BIOS_DEBUG, "memcfg channel[%u] config (%8.8x):\n", i, ch_conf); printk(BIOS_DEBUG, " ECC %s\n", ecc_decoder[(ch_conf >> 24) & 3]); printk(BIOS_DEBUG, " enhanced interleave mode %s\n", ((ch_conf >> 22) & 1) ? "on" : "off"); @@ -52,13 +67,13 @@ void report_memory_config(void) printk(BIOS_DEBUG, " rank interleave %s\n", ((ch_conf >> 21) & 1) ? "on" : "off"); - printk(BIOS_DEBUG, " DIMMA %d MB width %s %s rank%s\n", + printk(BIOS_DEBUG, " DIMMA %u MB width %s %s rank%s\n", ((ch_conf >> 0) & 0xff) * 256, ((ch_conf >> 19) & 1) ? "x16" : "x8 or x32", ((ch_conf >> 17) & 1) ? "dual" : "single", ((ch_conf >> 16) & 1) ? "" : ", selected"); - printk(BIOS_DEBUG, " DIMMB %d MB width %s %s rank%s\n", + printk(BIOS_DEBUG, " DIMMB %u MB width %s %s rank%s\n", ((ch_conf >> 8) & 0xff) * 256, ((ch_conf >> 20) & 1) ? "x16" : "x8 or x32", ((ch_conf >> 18) & 1) ? "dual" : "single", @@ -113,8 +128,7 @@ void setup_sdram_meminfo(const uint8_t *spd_data[NUM_CHANNELS][NUM_SLOTS]) memset(mem_info, 0, sizeof(struct memory_info)); - /* TODO: This looks like an open-coded DIV_ROUND_CLOSEST() */ - const uint32_t ddr_freq_mhz = (mchbar_read32(MC_BIOS_DATA) * 13333 * 2 + 50) / 100; + const uint32_t ddr_freq_mhz = get_ddr_freq_mhz(); unsigned int dimm_cnt = 0; for (unsigned int channel = 0; channel < NUM_CHANNELS; channel++) { diff --git a/src/northbridge/intel/haswell/registers/mchbar.h b/src/northbridge/intel/haswell/registers/mchbar.h index a944e126252..5be398734c4 100644 --- a/src/northbridge/intel/haswell/registers/mchbar.h +++ b/src/northbridge/intel/haswell/registers/mchbar.h @@ -16,7 +16,9 @@ /* DDR DATA per-channel per-bytelane */ #define RX_TRAIN_ch_r_b(ch, rank, byte) _DDRIO_C_R_B(0x0000, ch, rank, byte) +#define RX_PER_BIT(ch, rank, byte) _DDRIO_C_R_B(0x0010, ch, rank, byte) #define TX_TRAIN_ch_r_b(ch, rank, byte) _DDRIO_C_R_B(0x0020, ch, rank, byte) +#define TX_PER_BIT(ch, rank, byte) _DDRIO_C_R_B(0x0030, ch, rank, byte) #define RX_OFFSET_VDQ(ch, byte) _DDRIO_C_R_B(0x004c, ch, 0, byte) @@ -126,8 +128,11 @@ #define REUT_ch_ERR_DATA_MASK(ch) _MCMAIN_C(0x40d8, ch) +#define REUT_ch_ERR_DATA_STATUS(ch) _MCMAIN_C(0x40e0, ch) #define REUT_ch_ERR_MISC_STATUS(ch) _MCMAIN_C(0x40e8, ch) +#define REUT_ch_ERR_COUNTER_CTL_x(ch, byte) _MCMAIN_C_X(0x40f0, ch, byte) + #define REUT_ch_MISC_CKE_CTRL(ch) _MCMAIN_C(0x4190, ch) #define REUT_ch_MISC_ODT_CTRL(ch) _MCMAIN_C(0x4194, ch) #define REUT_ch_MISC_PAT_CADB_CTRL(ch) _MCMAIN_C(0x4198, ch) diff --git a/src/northbridge/intel/sandybridge/northbridge.c b/src/northbridge/intel/sandybridge/northbridge.c index 998562cbed4..0d691d93436 100644 --- a/src/northbridge/intel/sandybridge/northbridge.c +++ b/src/northbridge/intel/sandybridge/northbridge.c @@ -201,6 +201,20 @@ static void mc_read_resources(struct device *dev) printk(BIOS_DEBUG, "DPR base 0x%08x size %uM\n", dpr_base_k * KiB, dpr.size); } + /* Non standard BARs */ + u64 bar = pci_read_config32(dev, MCHBAR); + bar |= ((u64)pci_read_config32(dev, MCHBAR + 4) << 32); + if (bar & 1) + mmio_range(dev, index++, bar & ~0xf, 0x8000); + bar = pci_read_config32(dev, DMIBAR); + bar |= ((u64)pci_read_config32(dev, DMIBAR + 4) << 32); + if (bar & 1) + mmio_range(dev, index++, bar & ~0xf, 0x1000); + bar = pci_read_config32(dev, EPBAR); + bar |= ((u64)pci_read_config32(dev, EPBAR + 4) << 32); + if (bar & 1) + mmio_range(dev, index++, bar & ~0xf, 0x1000); + printk(BIOS_INFO, "Available memory below 4GB: %lluM\n", tomk >> 10); /* Report the memory regions */ diff --git a/src/security/intel/txt/txt_register.h b/src/security/intel/txt/txt_register.h index a00084511fa..588fef13879 100644 --- a/src/security/intel/txt/txt_register.h +++ b/src/security/intel/txt/txt_register.h @@ -3,6 +3,7 @@ #ifndef SECURITY_INTEL_TXT_REGISTER_H_ #define SECURITY_INTEL_TXT_REGISTER_H_ +#include #include /* @@ -162,9 +163,6 @@ #define ACM_FORMAT_SIZE_128KB (128 * KiB / 4) #define ACM_FORMAT_SIZE_256KB (256 * KiB / 4) -/* MSRs */ -#define IA32_MCG_STATUS 0x17a - /* DPR register layout, either in PCI config space or TXT MMIO space */ union dpr_register { struct { diff --git a/src/security/lockdown/Kconfig b/src/security/lockdown/Kconfig index 8de7979904e..ec76cea2133 100644 --- a/src/security/lockdown/Kconfig +++ b/src/security/lockdown/Kconfig @@ -73,6 +73,18 @@ config BOOTMEDIA_LOCK_WPRO_VBOOT_RO is either triggered by coreboot (when INTEL_CHIPSET_LOCKDOWN is set) or has to be triggered later (e.g. by the payload or the OS). +config BOOTMEDIA_LOCK_TOPSWAP + bool "Write-protect the COREBOOT & BOOTBLOCK regions" + depends on TOP_SWAP_REDUNDANCY + depends on BOOTMEDIA_LOCK_CONTROLLER + help + Select this if you want to write-protect the BOOTBLOCK and COREBOOT + (Slot A) regions as specified in the Top Swap FMAP. You will be able to + write to the TOPSWAP and COREBOOT_TS (Slot B) regions and set the + attempt_slot_b CMOS option to run updated firmware. The BOOTBLOCK and + COREBOOT regions will remain a read-only golden copy, which you can + then revert to by resetting CMOS. + endchoice config BOOTMEDIA_LOCK_IN_VERSTAGE @@ -95,6 +107,14 @@ config BOOTMEDIA_SMM_BWP while also preventing unauthorized writes through the internal controller. Note that this breaks flashconsole, since the flash becomes read-only. +config BOOTMEDIA_SMM_BWP_RUNTIME_OPTION + bool "Boot media only writable in SMM can be controlled via option API" + depends on BOOTMEDIA_SMM_BWP + depends on DRIVERS_OPTION_CFR + help + Provide a runtime option "bios_lock" to enable or disable SMM BIOS Write Protection + via the option API. + choice prompt "SPI Flash write protection duration" default BOOTMEDIA_SPI_LOCK_REBOOT diff --git a/src/security/lockdown/lockdown.c b/src/security/lockdown/lockdown.c index c2e2ac35019..6a75111f6b1 100644 --- a/src/security/lockdown/lockdown.c +++ b/src/security/lockdown/lockdown.c @@ -27,6 +27,9 @@ void boot_device_security_lockdown(void) } else if (CONFIG(BOOTMEDIA_LOCK_WPRO_VBOOT_RO)) { printk(BIOS_DEBUG, "'WP_RO only'"); lock_type = CTRLR_WP; + } else if (CONFIG(BOOTMEDIA_LOCK_TOPSWAP)) { + printk(BIOS_DEBUG, "'COREBOOT + BOOTBLOCK'"); + lock_type = CTRLR_WP; } printk(BIOS_DEBUG, " using CTRL...\n"); } else { @@ -45,6 +48,11 @@ void boot_device_security_lockdown(void) printk(BIOS_ERR, "BM-LOCKDOWN: Could not find region 'WP_RO'\n"); else rdev = &dev; + } else if (CONFIG(BOOTMEDIA_LOCK_TOPSWAP)) { + if (fmap_locate_area_as_rdev("COREBOOT", &dev) < 0) + printk(BIOS_ERR, "BM-LOCKDOWN: Could not find region 'COREBOOT'\n"); + else + rdev = &dev; } else { rdev = boot_device_ro(); } @@ -53,6 +61,18 @@ void boot_device_security_lockdown(void) printk(BIOS_INFO, "BM-LOCKDOWN: Enabled bootmedia protection\n"); else printk(BIOS_ERR, "BM-LOCKDOWN: Failed to enable bootmedia protection\n"); + + if (CONFIG(BOOTMEDIA_LOCK_TOPSWAP)) { + /* + * Additionally set a protected range for the BOOTBLOCK region + */ + if (fmap_locate_area_as_rdev("BOOTBLOCK", &dev) < 0) + printk(BIOS_ERR, "BM-LOCKDOWN: Could not find region 'BOOTBLOCK'\n"); + else if (boot_device_wp_region(&dev, lock_type) >= 0) + printk(BIOS_INFO, "BM-LOCKDOWN: Enabled bootmedia protection for BOOTBLOCK\n"); + else + printk(BIOS_ERR, "BM-LOCKDOWN: Failed to enable bootmedia protection for BOOTBLOCK\n"); + } } static void lock(void *unused) diff --git a/src/security/lockdown/lockdown.h b/src/security/lockdown/lockdown.h new file mode 100644 index 00000000000..b81e636c32e --- /dev/null +++ b/src/security/lockdown/lockdown.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef SECURITY_LOCKDOWN_LOCKDOWN_H +#define SECURITY_LOCKDOWN_LOCKDOWN_H + +#include +#include + +static inline bool enable_smm_bios_protection(void) +{ + if (CONFIG(BOOTMEDIA_SMM_BWP_RUNTIME_OPTION)) + return get_uint_option("bios_lock", CONFIG(BOOTMEDIA_SMM_BWP)); + return CONFIG(BOOTMEDIA_SMM_BWP); +} + +#endif /* SECURITY_LOCKDOWN_LOCKDOWN_H */ diff --git a/src/security/tpm/Kconfig b/src/security/tpm/Kconfig index c8eb446839f..a53163dd059 100644 --- a/src/security/tpm/Kconfig +++ b/src/security/tpm/Kconfig @@ -22,7 +22,7 @@ config TPM1 config TPM2 bool "TPM 2.0" - depends on I2C_TPM || MEMORY_MAPPED_TPM || SPI_TPM || CRB_TPM + depends on I2C_TPM || MEMORY_MAPPED_TPM || SPI_TPM || CRB_TPM || AMD_CRB_FTPM default y if MAINBOARD_HAS_TPM2 help Select this option if your TPM uses the newer TPM 2.0 protocol. diff --git a/src/security/tpm/tspi/crtm.c b/src/security/tpm/tspi/crtm.c index 4e0a9b727ae..def2fc35133 100644 --- a/src/security/tpm/tspi/crtm.c +++ b/src/security/tpm/tspi/crtm.c @@ -9,6 +9,10 @@ #include #include +/* This include is available as only if CONFIG_SOC_INTEL_COMMON_BLOCK is + set, which is not guaranteed for this file. */ +#include + static int tpm_log_initialized; static inline int tpm_log_available(void) { @@ -72,7 +76,28 @@ static tpm_result_t tspi_init_crtm(void) /* Mapping measures the file. We know we can safely map here because bootblock-as-a-file is only used on x86, where we don't need cache to map. */ enum cbfs_type type = CBFS_TYPE_BOOTBLOCK; - void *mapping = cbfs_ro_type_map("bootblock", NULL, &type); + void *mapping = NULL; + + if (CONFIG(INTEL_TOP_SWAP_SEPARATE_REGIONS)) { + enum ts_config top_swap = get_rtc_buc_top_swap_status(); + if (top_swap == TS_ENABLE) + printk(BIOS_INFO, + "CRTM Top Swap: Measuring bootblock in TOPSWAP (will be logged as BOOTBLOCK).\n"); + else + printk(BIOS_INFO, + "CRTM Top Swap: Measuring bootblock in BOOTBLOCK.\n"); + + /* + * Whether Top Swap is active or not, FMAP always refers to the same + * memory ranges but the contents of BOOTBLOCK and TOPSWAP are swapped. + * Hence always using BOOTBLOCK region to access the active bootblock. + */ + mapping = cbfs_unverified_area_type_alloc("BOOTBLOCK", "bootblock", + NULL, NULL, NULL, &type); + } else { + mapping = cbfs_ro_type_map("bootblock", NULL, &type); + } + if (!mapping) { printk(BIOS_INFO, "TSPI: Couldn't measure bootblock into CRTM!\n"); diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c index 56b8fa8ede3..b69273e5f2c 100644 --- a/src/security/tpm/tspi/tspi.c +++ b/src/security/tpm/tspi/tspi.c @@ -73,6 +73,14 @@ static tpm_result_t tpm_setup_s3_helper(void) default: printk(BIOS_ERR, "TPM: Resume failed (%#x).\n", rc); + if (CONFIG(TPM2)) { + /* + * TODO: Record EV_SEPARATOR event to indicate to host + * that an error has occurred. + */ + printk(BIOS_WARNING, "TPM: Performing restart\n"); + rc = tlcl_startup(); + } break; } diff --git a/src/security/tpm/tss/tss.c b/src/security/tpm/tss/tss.c index 8e52de73e9d..f4deb2d633b 100644 --- a/src/security/tpm/tss/tss.c +++ b/src/security/tpm/tss/tss.c @@ -29,7 +29,7 @@ tpm_result_t tlcl_lib_init(void) init_done = true; tlcl_tis_sendrecv = NULL; - if (CONFIG(CRB_TPM)) + if (CONFIG(CRB_TPM) || CONFIG(AMD_CRB_FTPM)) tlcl_tis_sendrecv = crb_tis_probe(&tlcl_tpm_family); if (CONFIG(MEMORY_MAPPED_TPM) && tlcl_tis_sendrecv == NULL) tlcl_tis_sendrecv = pc80_tis_probe(&tlcl_tpm_family); diff --git a/src/soc/amd/cezanne/Kconfig b/src/soc/amd/cezanne/Kconfig index 26d3f3e4a8d..dacd542c8e4 100644 --- a/src/soc/amd/cezanne/Kconfig +++ b/src/soc/amd/cezanne/Kconfig @@ -26,7 +26,6 @@ config SOC_AMD_CEZANNE_BASE select RTC select SOC_AMD_COMMON select SOC_AMD_COMMON_BLOCK_ACP_GEN1 - select SOC_AMD_COMMON_BLOCK_ACP_SOC_SPECIFIC_SSDT_ENTRY select SOC_AMD_COMMON_BLOCK_ACPI select SOC_AMD_COMMON_BLOCK_ACPIMMIO select SOC_AMD_COMMON_BLOCK_ACPIMMIO_PM_IO_ACCESS diff --git a/src/soc/amd/cezanne/acpi.c b/src/soc/amd/cezanne/acpi.c index b54b88b2e89..6d7bbefe193 100644 --- a/src/soc/amd/cezanne/acpi.c +++ b/src/soc/amd/cezanne/acpi.c @@ -92,226 +92,3 @@ const acpi_cstate_t *get_cstate_config_data(size_t *size) *size = ARRAY_SIZE(cstate_cfg_table); return cstate_cfg_table; } - -static void acp_soc_write_smn_access_methods(void) -{ - acpigen_write_method_serialized("SMNR", 1); - acpigen_write_store_op_to_namestr(ARG0_OP, "\\_SB.PCI0.GNB.SMNA"); - acpigen_write_return_namestr("\\_SB.PCI0.GNB.SMND"); - acpigen_write_method_end(); - - acpigen_write_method_serialized("SMNW", 2); - acpigen_write_store_op_to_namestr(ARG0_OP, "\\_SB.PCI0.GNB.SMNA"); - acpigen_write_store_op_to_namestr(ARG1_OP, "\\_SB.PCI0.GNB.SMND"); - acpigen_write_method_end(); -} - -/* write value of ACPI variable into SMN register */ -static void acp_soc_write_smn_register_write(uint8_t op, uint32_t smn_address) -{ - acpigen_emit_namestring("^SMNW"); - acpigen_write_integer(smn_address); - acpigen_emit_byte(op); -} - -/* read SMN register and store value into ACPI variable */ -static void acp_soc_write_smn_register_read(uint32_t smn_address, uint8_t op) -{ - acpigen_write_store(); - acpigen_emit_namestring("^SMNR"); - acpigen_write_integer(smn_address); - acpigen_emit_byte(op); -} - -static void acp_soc_write_mailbox_access(void) -{ - acp_soc_write_smn_register_write(ARG0_OP, 0x00058A74); - acp_soc_write_smn_register_write(ARG1_OP, 0x00058A54); - acp_soc_write_smn_register_write(ARG2_OP, 0x00058A14); - acp_soc_write_smn_register_read(0x00058A74, LOCAL0_OP); - - /* While (LEqual (Local0, 0)) */ - acpigen_emit_byte(WHILE_OP); - acpigen_write_len_f(); - acpigen_emit_byte(LEQUAL_OP); - acpigen_emit_byte(LOCAL0_OP); - acpigen_emit_byte(ZERO_OP); - - acp_soc_write_smn_register_read(0x00058A74, LOCAL0_OP); - - acpigen_pop_len(); /* While */ - - acp_soc_write_smn_register_read(0x00058A54, LOCAL1_OP); - - acpigen_write_return_op(LOCAL1_OP); -} - -static void acp_soc_write_psp_mbox_buffer_field(void) -{ - acpigen_write_name("MBOX"); - acpigen_write_byte_buffer(NULL, 4); - acpigen_write_create_buffer_word_field("MBOX", 0, "STAT"); - acpigen_write_create_buffer_byte_field("MBOX", 2, "CMDI"); - acpigen_write_create_buffer_bit_field("MBOX", 31, "REDY"); -} - -static void acp_soc_write_psp_read_mbox_from_hw(void) -{ - acp_soc_write_smn_register_read(0x03810570, LOCAL0_OP); - acpigen_write_store_op_to_namestr(LOCAL0_OP, "MBOX"); -} - -static void acp_soc_write_psp_write_mbox_to_hw(void) -{ - acpigen_write_store_namestr_to_op("MBOX", LOCAL0_OP); - acp_soc_write_smn_register_write(LOCAL0_OP, 0x03810570); -} - -static void acp_soc_write_psp_mailbox_access(void) -{ - - acp_soc_write_psp_mbox_buffer_field(); - - acp_soc_write_psp_read_mbox_from_hw(); - - /* While (LOr (LNotEqual (REDY, 0x1), LNotEqual (CMDI, 0x00))) */ - acpigen_emit_byte(WHILE_OP); - acpigen_write_len_f(); - acpigen_emit_byte(LOR_OP); - acpigen_emit_byte(LNOT_OP); - acpigen_emit_byte(LEQUAL_OP); - acpigen_emit_namestring("REDY"); - acpigen_write_integer(1); - acpigen_emit_byte(LNOT_OP); - acpigen_emit_byte(LEQUAL_OP); - acpigen_emit_namestring("CMDI"); - acpigen_write_integer(0); - - acp_soc_write_psp_read_mbox_from_hw(); - - acpigen_pop_len(); /* While */ - - acpigen_write_store_int_to_op(0, LOCAL0_OP); - acpigen_write_store_op_to_namestr(LOCAL0_OP, "MBOX"); - acpigen_write_store_int_to_namestr(0x33, "CMDI"); - - acp_soc_write_psp_write_mbox_to_hw(); - - acpigen_write_sleep(1); - - acp_soc_write_psp_read_mbox_from_hw(); - - /* While (LNotEqual (CMDI, 0x00)) */ - acpigen_emit_byte(WHILE_OP); - acpigen_write_len_f(); - acpigen_emit_byte(LNOT_OP); - acpigen_emit_byte(LEQUAL_OP); - acpigen_emit_namestring("CMDI"); - acpigen_write_integer(0); - - acp_soc_write_psp_read_mbox_from_hw(); - - acpigen_pop_len(); /* While */ - - acpigen_write_return_op(LOCAL0_OP); -} - -static void acp_soc_write_msg0_method(void) -{ - acpigen_write_method_serialized("MSG0", 3); - - /* If (ARG2 != 0x9) */ - acpigen_write_if_lnotequal_op_int(ARG2_OP, 0x9); - - acp_soc_write_mailbox_access(); - - acpigen_write_else(); - - acp_soc_write_psp_mailbox_access(); - - acpigen_write_if_end(); - - acpigen_write_method_end(); /* MSG0 */ -} - -void acp_soc_write_ssdt_entry(const struct device *dev) -{ - /* - * SMN and mailbox interface using the SMN OperationRegion on the host bridge - * - * Provide both SMN read/write methods for direct SMN register access and the MSG0 - * method which is used by some ACP drivers to access two different mailbox interfaces - * in the hardware. One mailbox interface is used to configure the ACP's clock source, - * the other one is used to notify the PSP that the DSP firmware has been loaded, so - * that the PSP can validate the firmware and set the qualifier bit to enable running - * it. - * - * Scope (\_SB.PCI0.GP41.ACPD) - * { - * Method (SMNR, 1, Serialized) - * { - * Store (Arg0, \_SB.PCI0.GNB.SMNA) - * Return (\_SB.PCI0.GNB.SMND) - * } - * - * Method (SMNW, 2, Serialized) - * { - * Store (Arg0, \_SB.PCI0.GNB.SMNA) - * Store (Arg1, \_SB.PCI0.GNB.SMND) - * } - * - * Method (MSG0, 3, Serialized) - * { - * If (LNotEqual (Arg2, 0x09)) - * { - * ^SMNW (0x00058A74, Arg0) - * ^SMNW (0x00058A54, Arg1) - * ^SMNW (0x00058A14, Arg2) - * Store (^SMNR (0x00058A74), Local0) - * While (LEqual (Local0, Zero)) - * { - * Store (^SMNR (0x00058A74), Local0) - * } - * Store (^SMNR (0x00058A54), Local1) - * Return (Local1) - * } - * Else - * { - * Name (MBOX, Buffer (0x04){}) - * CreateWordField (MBOX, Zero, STAT) - * CreateByteField (MBOX, 0x02, CMDI) - * CreateBitField (MBOX, 0x1F, REDY) - * Store (^SMNR (0x03810570), Local0) - * Store (Local0, MBOX) - * While (LOr (LNotEqual (REDY, One), LNotEqual (CMDI, Zero))) - * { - * Store (^SMNR (0x03810570), Local0) - * Store (Local0, MBOX) - * } - * Store (Zero, Local0) - * Store (Local0, MBOX) - * Store (0x33, CMDI) - * Store (MBOX, Local0) - * ^SMNW (0x03810570, Local0) - * Sleep (One) - * Store (^SMNR (0x03810570), Local0) - * Store (Local0, MBOX) - * While (LNotEqual (CMDI, Zero)) - * { - * Store (^SMNR (0x03810570), Local0) - * Store (Local0, MBOX) - * } - * Return (Local0) - * } - * } - * } - */ - - acpigen_write_scope(acpi_device_path(dev)); - - acp_soc_write_smn_access_methods(); - - acp_soc_write_msg0_method(); - - acpigen_write_scope_end(); -} diff --git a/src/soc/amd/cezanne/acpi/acp.asl b/src/soc/amd/cezanne/acpi/acp.asl new file mode 100644 index 00000000000..51d22183dfa --- /dev/null +++ b/src/soc/amd/cezanne/acpi/acp.asl @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* ACP Audio Configuration */ +Scope (\_SB.PCI0.GP41) { + Device (ACPD) { + /* Device addressing for ACP (Audio Coprocessor) */ + Name (_ADR, 0x05) /* Device 0, Function 5 */ + + Name (STAT, 0x3) /* Decoding Resources, Hide from UI */ + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + + /* Read SMN register and store value into ACPI variable */ + Method (SMNR, 1, Serialized) + { + \_SB.PCI0.GNB.SMNA = Arg0 + Return (\_SB.PCI0.GNB.SMND) + } + + /* Write value of ACPI variable into SMN register */ + Method (SMNW, 2, Serialized) + { + \_SB.PCI0.GNB.SMNA = Arg0 + \_SB.PCI0.GNB.SMND = Arg1 + } + + /* + * SMN and mailbox interface using the SMN OperationRegion on the host bridge + * + * Provide both SMN read/write methods for direct SMN register access and the MSG0 + * method which is used by some ACP drivers to access two different mailbox interfaces + * in the hardware. One mailbox interface is used to configure the ACP's clock source, + * the other one is used to notify the PSP that the DSP firmware has been loaded, so + * that the PSP can validate the firmware and set the qualifier bit to enable running + * it. + */ + Method (MSG0, 3, Serialized) + { + If (Arg2 != 0x09) + { + /* mailbox access */ + ^SMNW (0x00058A74, Arg0) + ^SMNW (0x00058A54, Arg1) + ^SMNW (0x00058A14, Arg2) + Local0 = ^SMNR (0x00058A74) + While (Local0 == 0) + { + Local0 = ^SMNR (0x00058A74) + } + + Local1 = ^SMNR (0x00058A54) + Return (Local1) + } + Else + { + /* PSP mailbox access */ + Name (MBOX, Buffer (0x04) { + 0x20, 0x57, 0x91, 0x7B + }) + CreateWordField (MBOX, Zero, STAT) + CreateByteField (MBOX, 0x02, CMDI) + CreateBitField (MBOX, 0x1F, REDY) + Local0 = ^SMNR (0x03810570) + MBOX = Local0 + While (((REDY != 1) || (CMDI != 0))) + { + Local0 = ^SMNR (0x03810570) + MBOX = Local0 + } + + Local0 = Zero + MBOX = Local0 + CMDI = 0x33 + Local0 = MBOX + ^SMNW (0x03810570, Local0) + Sleep (1) + Local0 = ^SMNR (0x03810570) + MBOX = Local0 + While (CMDI != 0) + { + Local0 = ^SMNR (0x03810570) + MBOX = Local0 + } + + Return (Local0) + } + } + } +} diff --git a/src/soc/amd/cezanne/acpi/pci.asl b/src/soc/amd/cezanne/acpi/pci.asl new file mode 100644 index 00000000000..4942f989e33 --- /dev/null +++ b/src/soc/amd/cezanne/acpi/pci.asl @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +/* + * Keep name in sync with SSDT generator pcie_gpp_acpi_name()! + * Currently the name is hex representation of dev->path.pci.devfn. + */ + +/* Root complex */ +Device (GNB) +{ + Name (_ADR, 0) + Method (_STA, 0, NotSerialized) + { + Return (0x0F) + } + + /* Add opregion to host bridge needed for ACP driver. + * + * This is used by an ACPI method in the ACP's ACPI code to access different mailbox + * interfaces in the hardware. Some ACP drivers will use that to both notify the PSP + * that the DSP firmware has been loaded, so that the PSP can validate the firmware + * and set the qualifier bit to enable running it, and to configure the ACP's clock + * source. + * + * As this SMN access is not arbitrated and there may be other drivers or parts of + * the firmware attempting to use the SMN access register pair, there is a risk of + * conflict / incorrect data, but given the frequency and duration of accesses, the + * risk is deemed to be quite low. + */ + OperationRegion (PSMN, PCI_Config, 0x00, 0x100) + Field(PSMN, AnyAcc, NoLock, Preserve) { + Offset (0xB8), + SMNA, 32, + SMND, 32, + } +} + +/* PCIe GPP */ +ACPI_PCI_DEV(GP09, 1, 1) +ACPI_PCI_DEV(GP0A, 1, 2) +ACPI_PCI_DEV(GP0B, 1, 3) + +/* PCIe GPP */ +ACPI_PCI_DEV(GP11, 2, 1) +ACPI_PCI_DEV(GP12, 2, 2) +ACPI_PCI_DEV(GP13, 2, 3) +ACPI_PCI_DEV(GP14, 2, 4) +ACPI_PCI_DEV(GP15, 2, 5) +ACPI_PCI_DEV(GP16, 2, 6) +ACPI_PCI_DEV(GP17, 2, 7) + +/* Internal GPP bridges */ +ACPI_PCI_DEV(GP41, 8, 1) +ACPI_PCI_DEV(GP42, 8, 2) +ACPI_PCI_DEV(GP43, 8, 3) diff --git a/src/soc/amd/cezanne/acpi/soc.asl b/src/soc/amd/cezanne/acpi/soc.asl index f89aaf4f1f0..5749ff80b42 100644 --- a/src/soc/amd/cezanne/acpi/soc.asl +++ b/src/soc/amd/cezanne/acpi/soc.asl @@ -21,7 +21,11 @@ Scope(\_SB) { Scope(PCI0) { #include + + #include "pci.asl" } /* End PCI0 scope */ + + #include "acp.asl" } /* End \_SB scope */ #include diff --git a/src/soc/amd/cezanne/root_complex.c b/src/soc/amd/cezanne/root_complex.c index 15958dc0a8d..d9999b91635 100644 --- a/src/soc/amd/cezanne/root_complex.c +++ b/src/soc/amd/cezanne/root_complex.c @@ -59,52 +59,6 @@ static void root_complex_fill_ssdt(const struct device *device) { if (CONFIG(SOC_AMD_COMMON_BLOCK_ACPI_DPTC)) acipgen_dptci(); - - /* Add ACPI device, opregion to host bridge needed for ACP driver. - * - * This is used by an ACPI method in the ACP's ACPI code to access different mailbox - * interfaces in th hardware. Some ACP drivers will use that to both notify the PSP - * that the DSP firmware has been loaded, so that the PSP can validate the firmware - * and set the qualifier bit to enable running it, and to configure the ACP's clock - * source. - * - * As this SMN access is not arbitrated and there may be other drivers or parts of - * the firmware attempting to use the SMN access register pair, there is a risk of - * conflict / incorrect data, but given the frequency and duration of accesses, the - * risk is deemed to be quite low. - * - * Scope (\_SB.PCI0) - * { - * Device (GNB) - * { - * Name (_ADR, 0x0000000000000000) - * Method (_STA, 0, NotSerialized) - * { - * Return (0x0F) - * } - * } - * } - * Scope (\_SB.PCI0.GNB) - * { - * OperationRegion(SMN, SystemMemory , 0xF80000B8, 0x8) - * Field(SMN, AnyAcc, NoLock, Preserve) { - * SMNA, 32, - * SMND, 32, - * } - * } - */ - acpi_device_write_pci_dev(device); - acpigen_write_scope(acpi_device_path(device)); - struct opregion opreg = OPREGION("SMN", SYSTEMMEMORY, - CONFIG_ECAM_MMCONF_BASE_ADDRESS + 0xb8, 0x8); - acpigen_write_opregion(&opreg); - static const struct fieldlist list[] = { - FIELDLIST_NAMESTR("SMNA", 32), - FIELDLIST_NAMESTR("SMND", 32), - }; - acpigen_write_field(opreg.name, list, ARRAY_SIZE(list), - FIELD_ANYACC | FIELD_NOLOCK | FIELD_PRESERVE); - acpigen_write_scope_end(); } static const char *gnb_acpi_name(const struct device *dev) diff --git a/src/soc/amd/common/Makefile.mk b/src/soc/amd/common/Makefile.mk index 5d419684938..dbf655737fd 100644 --- a/src/soc/amd/common/Makefile.mk +++ b/src/soc/amd/common/Makefile.mk @@ -11,7 +11,7 @@ ifneq ($(V),) OPT_DEBUG_AMDFWTOOL = --debug endif -ifneq ($(CONFIG_AMDFW_CONFIG_FILE), ) +ifneq ($(call strip_quotes, $(CONFIG_AMDFW_CONFIG_FILE)),) FIRMWARE_LOCATION=$(shell grep -e FIRMWARE_LOCATION $(CONFIG_AMDFW_CONFIG_FILE) | awk '{print $$2}') # Add all the files listed in the config file to the dependency list @@ -77,7 +77,7 @@ amdfwread-range-cmd = $(shell ( \ )) endif # ifeq ($(CONFIG_VBOOT_GSCVD),y) -endif # ifneq ($(CONFIG_AMDFW_CONFIG_FILE), ) +endif # ifneq ($(call strip_quotes, $(CONFIG_AMDFW_CONFIG_FILE)),) MAINBOARD_BLOBS_DIR := $(call strip_quotes, $(CONFIG_APCB_BLOBS_DIR)) diff --git a/src/soc/amd/common/acpi/pci_template.asl b/src/soc/amd/common/acpi/pci_template.asl new file mode 100644 index 00000000000..dd9e4b149a2 --- /dev/null +++ b/src/soc/amd/common/acpi/pci_template.asl @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * Template for fixed PCI devices on the SoC. SSDT will emit STAT=1 when enabled + * in hardware and devicetree.cb. Allows to write DSDT code for such devices or + * it's children. Possible use cases: + * - PowerResources for devices behind PCIe bridges (NVVMe D3cold) + * - _DSM for ACP + * - BOCO and BACO for GPU + */ +#ifdef ACPI_PCI_DEV + #undef ACPI_PCI_DEV +#endif +#define ACPI_PCI_DEV(name, dev, fun) \ + Device(name) { \ + Name(_ADR, (dev << 16) + fun) \ + Name (STAT, 0x0) \ + Method (_STA, 0, NotSerialized) \ + { \ + Return (STAT) \ + } \ + } diff --git a/src/soc/amd/common/block/acp/Kconfig b/src/soc/amd/common/block/acp/Kconfig index a6ff48327b0..bc2dddc1f9f 100644 --- a/src/soc/amd/common/block/acp/Kconfig +++ b/src/soc/amd/common/block/acp/Kconfig @@ -11,9 +11,3 @@ config SOC_AMD_COMMON_BLOCK_ACP_GEN2 help Select this option to perform Audio Co-Processor(ACP) configuration. Used by the ACP in AMD mendocino (family 17h) and possibly newer CPUs. - -config SOC_AMD_COMMON_BLOCK_ACP_SOC_SPECIFIC_SSDT_ENTRY - bool - help - Select this option to call into the SoC code when generating the SSDT - entry for the Audio Co-Processor (ACP). diff --git a/src/soc/amd/common/block/acp/acp.c b/src/soc/amd/common/block/acp/acp.c index 4985980bf52..836d17b052a 100644 --- a/src/soc/amd/common/block/acp/acp.c +++ b/src/soc/amd/common/block/acp/acp.c @@ -22,25 +22,29 @@ static const char *acp_acpi_name(const struct device *dev) static void acp_fill_wov_method(const struct device *dev) { const struct soc_amd_common_config *cfg = soc_get_common_config(); - const char *scope = acpi_device_path(dev); - if (!cfg->acp_config.dmic_present || !scope) + if (!cfg->acp_config.dmic_present) return; /* For ACP DMIC hardware runtime detection on the platform, _WOV method is populated. */ - acpigen_write_scope(scope); /* Scope */ acpigen_write_method("_WOV", 0); acpigen_write_return_integer(1); acpigen_write_method_end(); - acpigen_write_scope_end(); } static void acp_fill_ssdt(const struct device *dev) { - acpi_device_write_pci_dev(dev); + const char *scope = acpi_device_path(dev); + assert(scope); + if (!scope) + return; + + acpigen_write_scope(scope); + + acpigen_write_store_int_to_namestr(acpi_device_status(dev), "STAT"); acp_fill_wov_method(dev); - if (CONFIG(SOC_AMD_COMMON_BLOCK_ACP_SOC_SPECIFIC_SSDT_ENTRY)) - acp_soc_write_ssdt_entry(dev); + + acpigen_pop_len(); /* Scope */ } struct device_operations amd_acp_ops = { diff --git a/src/soc/amd/common/block/acpi/ivrs.c b/src/soc/amd/common/block/acpi/ivrs.c index 2301158a0a0..c3af6285a64 100644 --- a/src/soc/amd/common/block/acpi/ivrs.c +++ b/src/soc/amd/common/block/acpi/ivrs.c @@ -171,7 +171,7 @@ static unsigned long acpi_ivhd_misc(unsigned long current, struct device *dev) /* * Add all possible PCI devices in the domain that can generate transactions * processed by IOMMU. Start with device :01.0 - */ + */ current = ivhd_dev_range(current, PCI_DEVFN(0, 3) | (dev->downstream->secondary << 8), 0xff | (dev->downstream->subordinate << 8), 0); @@ -305,11 +305,13 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) uint64_t mmio_x18_value; uint64_t mmio_x4000_value; uint32_t cap_offset_0; + uint32_t cap_offset_c; uint32_t cap_offset_10; struct acpi_ivrs_ivhd *ivhd; struct device *iommu_dev; struct device *nb_dev; struct device *dev = NULL; + unsigned int domain; if (ivrs == NULL) { printk(BIOS_WARNING, "%s: ivrs is NULL\n", __func__); @@ -321,15 +323,22 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) while ((dev = dev_find_path(dev, DEVICE_PATH_DOMAIN)) != NULL) { nb_dev = pcidev_path_behind(dev->downstream, PCI_DEVFN(0, 0)); iommu_dev = pcidev_path_behind(dev->downstream, PCI_DEVFN(0, 2)); + domain = dev_get_domain_id(dev); if (!nb_dev) { - printk(BIOS_WARNING, "%s: Northbridge device not present!\n", __func__); - printk(BIOS_WARNING, "%s: IVRS table not generated...\n", __func__); - return (unsigned long)ivrs; + printk(BIOS_WARNING, "%s: Northbridge device not present on domain %u!\n", __func__, domain); + if (domain == 0) { + printk(BIOS_WARNING, "%s: IVRS table not generated...\n", __func__); + return (unsigned long)ivrs; + } + continue; } if (!iommu_dev) { - printk(BIOS_WARNING, "%s: IOMMU device not found\n", __func__); - return (unsigned long)ivrs; + printk(BIOS_WARNING, "%s: IOMMU device not found on domain %u\n", __func__, dev_get_domain_id(dev)); + if (domain == 0) + return (unsigned long)ivrs; + + continue; } ivhd->type = IVHD_BLOCK_TYPE_LEGACY__FIXED; @@ -342,6 +351,8 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) ivhd->iommu_base_high = pci_read_config32(iommu_dev, IOMMU_CAP_BASE_HI); cap_offset_0 = pci_read_config32(iommu_dev, ivhd->capability_offset); + cap_offset_c = pci_read_config32(iommu_dev, + ivhd->capability_offset + 0xC); cap_offset_10 = pci_read_config32(iommu_dev, ivhd->capability_offset + 0x10); mmio_x18_value = read64p(ivhd->iommu_base_low + 0x18); @@ -367,10 +378,8 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) ivhd->pci_segment_group = nb_dev->upstream->segment_group; - ivhd->iommu_info = pci_read_config16(iommu_dev, - ivhd->capability_offset + 0x10) & 0x1F; - ivhd->iommu_info |= (pci_read_config16(iommu_dev, - ivhd->capability_offset + 0xC) & 0x1F) << IOMMU_INFO_UNIT_ID_SHIFT; + ivhd->iommu_info = cap_offset_10 & 0x1F; + ivhd->iommu_info |= (cap_offset_c & 0x1F) << IOMMU_INFO_UNIT_ID_SHIFT; ivhd->iommu_feature_info = 0; ivhd->iommu_feature_info |= (mmio_x30_value & MMIO_EXT_FEATURE_HATS_MASK) @@ -409,10 +418,8 @@ static unsigned long acpi_fill_ivrs(acpi_ivrs_t *ivrs, unsigned long current) ? IOMMU_FEATURE_XT_SUP : 0); /* Enable EFR if supported */ - ivrs->iv_info = pci_read_config32(iommu_dev, - ivhd->capability_offset + 0x10) & 0x007fffe0; - if (pci_read_config32(iommu_dev, - ivhd->capability_offset) & EFR_FEATURE_SUP) + ivrs->iv_info = cap_offset_10 & 0x007fffe0; + if (cap_offset_0 & EFR_FEATURE_SUP) ivrs->iv_info |= IVINFO_EFR_SUPPORTED; diff --git a/src/soc/amd/common/block/apob/apob_cache.c b/src/soc/amd/common/block/apob/apob_cache.c index 713826a297d..d9a70676831 100644 --- a/src/soc/amd/common/block/apob/apob_cache.c +++ b/src/soc/amd/common/block/apob/apob_cache.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -16,7 +17,7 @@ #include #include #include -#include +#include #define DEFAULT_MRC_CACHE "RW_MRC_CACHE" #define DEFAULT_MRC_CACHE_SIZE FMAP_SECTION_RW_MRC_CACHE_SIZE @@ -272,6 +273,10 @@ static void soc_update_apob_cache(void *unused) if (CONFIG(SOC_AMD_COMMON_BLOCK_APOB_HASH)) update_apob_nv_hash(ram_hash, &write_rdev); + // update the signature in CMOS to indicate APOB updated. + cmos_write(0x5A, 0x86); + cmos_write(0xA5, 0x87); + timestamp_add_now(TS_AMD_APOB_END); printk(BIOS_INFO, "Updated APOB in flash\n"); diff --git a/src/soc/amd/common/block/cpu/car/cache_as_ram.S b/src/soc/amd/common/block/cpu/car/cache_as_ram.S index 8d41826bfdc..9411ad0a6f0 100644 --- a/src/soc/amd/common/block/cpu/car/cache_as_ram.S +++ b/src/soc/amd/common/block/cpu/car/cache_as_ram.S @@ -3,7 +3,7 @@ /****************************************************************************** * $Workfile:: cache_as_ram.S * - * Description: CAR setup called from bootblock_crt0.S. + * Description: CAR setup called from entry32.S. * ****************************************************************************** */ diff --git a/src/soc/amd/common/block/cpu/mca/mcax.c b/src/soc/amd/common/block/cpu/mca/mcax.c index 46c72f00a87..ad4f67e47de 100644 --- a/src/soc/amd/common/block/cpu/mca/mcax.c +++ b/src/soc/amd/common/block/cpu/mca/mcax.c @@ -20,14 +20,14 @@ bool mca_skip_check(void) /* Print the contents of the MCAX registers for a given bank */ void mca_print_error(unsigned int bank) { - msr_t msr; + msr_t msr, mca_status; printk(BIOS_WARNING, "#MC Error: core %u, bank %u %s\n", initial_lapicid(), bank, mca_get_bank_name(bank)); msr = rdmsr(MCAX_CTL_MSR(bank)); printk(BIOS_WARNING, " MC%u_CTL = %08x_%08x\n", bank, msr.hi, msr.lo); - msr = rdmsr(MCAX_STATUS_MSR(bank)); + msr = mca_status = rdmsr(MCAX_STATUS_MSR(bank)); printk(BIOS_WARNING, " MC%u_STATUS = %08x_%08x\n", bank, msr.hi, msr.lo); msr = rdmsr(MCAX_ADDR_MSR(bank)); printk(BIOS_WARNING, " MC%u_ADDR = %08x_%08x\n", bank, msr.hi, msr.lo); @@ -51,6 +51,12 @@ void mca_print_error(unsigned int bank) printk(BIOS_WARNING, " MC%u_MISC3 = %08x_%08x\n", bank, msr.hi, msr.lo); msr = rdmsr(MCAX_MISC4_MSR(bank)); printk(BIOS_WARNING, " MC%u_MISC4 = %08x_%08x\n", bank, msr.hi, msr.lo); + if (mca_syndv(mca_status)) { + msr = rdmsr(MCAX_SYND1_MSR(bank)); + printk(BIOS_WARNING, " MC%u_SYND1 = %08x_%08x\n", bank, msr.hi, msr.lo); + msr = rdmsr(MCAX_SYND2_MSR(bank)); + printk(BIOS_WARNING, " MC%u_SYND2 = %08x_%08x\n", bank, msr.hi, msr.lo); + } msr = rdmsr(MCA_CTL_MASK_MSR(bank)); printk(BIOS_WARNING, " MC%u_CTL_MASK = %08x_%08x\n", bank, msr.hi, msr.lo); } diff --git a/src/soc/amd/common/block/cpu/mca/mcax_bert.c b/src/soc/amd/common/block/cpu/mca/mcax_bert.c index af2bee407d0..80ee534f453 100644 --- a/src/soc/amd/common/block/cpu/mca/mcax_bert.c +++ b/src/soc/amd/common/block/cpu/mca/mcax_bert.c @@ -10,10 +10,7 @@ #include #include "mca_common_defs.h" -/* MISC4 is the last used register in the MCAX banks of Picasso */ -#define MCAX_USED_REGISTERS_PER_BANK (MCAX_MISC4_OFFSET + 1) - -static inline size_t mca_report_size_reqd(void) +static inline size_t mca_report_size_reqd(int used_registers_per_bank) { size_t size; @@ -32,8 +29,8 @@ static inline size_t mca_report_size_reqd(void) size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, 3); /* Context of CTL, STATUS, ADDR, MISC0, CONFIG, IPID, SYND, RESERVED, DESTAT, DEADDR, - MISC1, MISC2, MISC3, MISC4 */ - size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, MCAX_USED_REGISTERS_PER_BANK); + MISC1, MISC2, MISC3, MISC4, SYND0, SYND1 */ + size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, used_registers_per_bank); /* Context of CTL_MASK */ size += cper_ia32x64_ctx_sz_bytype(CPER_IA32X64_CTX_MSR, 1); @@ -57,7 +54,9 @@ void build_bert_mca_error(struct mca_bank_status *mci) cper_ia32x64_proc_error_info_t *chk; cper_ia32x64_context_t *ctx; - if (mca_report_size_reqd() > bert_storage_remaining()) + int used_registers_per_bank = mca_syndv(mci->sts) ? 16 : 14; + + if (mca_report_size_reqd(used_registers_per_bank) > bert_storage_remaining()) goto failed; status = bert_new_event(&CPER_SEC_PROC_GENERIC_GUID); @@ -80,7 +79,7 @@ void build_bert_mca_error(struct mca_bank_status *mci) if (!ctx) goto failed; ctx = cper_new_ia32x64_context_msr(status, x86_sec, MCAX_CTL_MSR(mci->bank), - MCAX_USED_REGISTERS_PER_BANK); + used_registers_per_bank); if (!ctx) goto failed; ctx = cper_new_ia32x64_context_msr(status, x86_sec, MCA_CTL_MASK_MSR(mci->bank), 1); diff --git a/src/soc/amd/common/block/cpu/smm/smm_relocate.c b/src/soc/amd/common/block/cpu/smm/smm_relocate.c index e5b8d9d17a6..4ca8911e2a5 100644 --- a/src/soc/amd/common/block/cpu/smm/smm_relocate.c +++ b/src/soc/amd/common/block/cpu/smm/smm_relocate.c @@ -17,10 +17,11 @@ /* AP MTRRs will be synced to the BSP in the SIPI vector so set them up before MP init. */ static void pre_mp_init(void) { - x86_setup_mtrrs_with_detect(); - x86_mtrr_check(); if (CONFIG(SOC_AMD_COMMON_BLOCK_UCODE)) amd_load_microcode_from_cbfs(); + + x86_setup_mtrrs_with_detect(); + x86_mtrr_check(); } static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, diff --git a/src/soc/amd/common/block/i2c/i3c.c b/src/soc/amd/common/block/i2c/i3c.c index 43eae71b671..4fbe6ae37b2 100644 --- a/src/soc/amd/common/block/i2c/i3c.c +++ b/src/soc/amd/common/block/i2c/i3c.c @@ -1,28 +1,57 @@ /* SPDX-License-Identifier: GPL-2.0-only */ - +#include #include +#include #include #include #include #include -#if CONFIG(HAVE_ACPI_TABLES) -static const char *i3c_acpi_name(const struct device *dev) +static int get_i3c_bus_for_dev(const struct device *dev, + const struct soc_i3c_ctrlr_info *ctrlr, + const size_t num_ctrlrs) { - size_t i; - size_t num_ctrlrs; - const struct soc_i3c_ctrlr_info *ctrlr = soc_get_i3c_ctrlr_info(&num_ctrlrs); + if (!dev || !ctrlr) + return -1; if (!(uintptr_t)dev->path.mmio.addr) { printk(BIOS_ERR, "NULL MMIO address at %s\n", __func__); - return NULL; + return -1; } - for (i = 0; i < num_ctrlrs; i++) { - if ((uintptr_t)dev->path.mmio.addr == ctrlr[i].bar) - return ctrlr[i].acpi_name; + for (int i = 0; i < num_ctrlrs; i++) { + if (dev->path.mmio.addr != ctrlr[i].bar) + continue; + return i; } - printk(BIOS_ERR, "%s: Could not find %lu\n", __func__, (uintptr_t)dev->path.mmio.addr); + printk(BIOS_ERR, "%s: Could not find i3c bus for %s\n", __func__, dev_path(dev)); + + return -1; +} + +static const struct soc_i3c_ctrlr_info * +get_i3c_info_for_dev(const struct device *dev) +{ + size_t num_ctrlrs; + const struct soc_i3c_ctrlr_info *ctrlr = soc_get_i3c_ctrlr_info(&num_ctrlrs); + const int bus = get_i3c_bus_for_dev(dev, ctrlr, num_ctrlrs); + + if (ctrlr && bus >= 0 && bus < num_ctrlrs) + return &ctrlr[bus]; + + printk(BIOS_ERR, "%s: Could not find soc_i3c_ctrlr_info for %s\n", __func__, dev_path(dev)); + + return NULL; +} + +#if CONFIG(HAVE_ACPI_TABLES) +static const char *i3c_acpi_name(const struct device *dev) +{ + const struct soc_i3c_ctrlr_info *info = get_i3c_info_for_dev(dev); + if (info) + return info->acpi_name; + + printk(BIOS_ERR, "%s: Could not find soc_i3c_ctrlr_info for %s\n", __func__, dev_path(dev)); return NULL; } @@ -34,12 +63,47 @@ static void i3c_acpi_fill_ssdt(const struct device *dev) } #endif +/* Even though this is called enable, it gets called for both enabled and disabled devices. */ +static void i3c_enable(struct device *dev) +{ + const struct soc_i3c_ctrlr_info *info = get_i3c_info_for_dev(dev); + if (!info) + return; + + if (dev->enabled) { + power_on_aoac_device(info->aoac_device); + wait_for_aoac_enabled(info->aoac_device); + } else { + power_off_aoac_device(info->aoac_device); + } +} + +static void i3c_init(struct device *dev) +{ + size_t num_ctrlrs, num_buses; + const struct soc_i3c_ctrlr_info *ctrlr = soc_get_i3c_ctrlr_info(&num_ctrlrs); + const int bus = get_i3c_bus_for_dev(dev, ctrlr, num_ctrlrs); + if (bus < 0) + return; + + const struct dw_i2c_bus_config *cfg = soc_get_i2c_bus_config(&num_buses); + + if (cfg) + soc_i2c_misc_init(bus, cfg); +} + static void i3c_read_resources(struct device *dev) { mmio_range(dev, 0, dev->path.mmio.addr, 4 * KiB); } +/* + * Currently there's no I3C driver, thus the I3C hardware cannot be used pre ramstage. + * It's sufficient to power switch the I3C controllers in the enable method. + */ struct device_operations soc_amd_i3c_mmio_ops = { + .enable = i3c_enable, + .init = i3c_init, .read_resources = i3c_read_resources, .set_resources = noop_set_resources, #if CONFIG(HAVE_ACPI_TABLES) diff --git a/src/soc/amd/common/block/include/amdblocks/acp.h b/src/soc/amd/common/block/include/amdblocks/acp.h index 3ec38c93d54..cdd5202bc7b 100644 --- a/src/soc/amd/common/block/include/amdblocks/acp.h +++ b/src/soc/amd/common/block/include/amdblocks/acp.h @@ -45,6 +45,4 @@ struct acp_config { bool dmic_present; }; -void acp_soc_write_ssdt_entry(const struct device *dev); - #endif /* AMD_COMMON_ACP_H */ diff --git a/src/soc/amd/common/block/include/amdblocks/espi.h b/src/soc/amd/common/block/include/amdblocks/espi.h index b7ab06ee554..5781dea3af8 100644 --- a/src/soc/amd/common/block/include/amdblocks/espi.h +++ b/src/soc/amd/common/block/include/amdblocks/espi.h @@ -7,6 +7,7 @@ /* eSPI MMIO base lives at an offset of 0x10000 from the address in SPI BAR. */ #define ESPI_OFFSET_FROM_BAR 0x10000 +#define ESPI1_OFFSET_FROM_BAR 0x20000 #define ESPI_DECODE 0x40 /* more bits defined in soc/common/amd/blocks/lpc/espi_def.h */ diff --git a/src/soc/amd/common/block/include/amdblocks/i2c.h b/src/soc/amd/common/block/include/amdblocks/i2c.h index fc1a03217aa..553561b7fc3 100644 --- a/src/soc/amd/common/block/include/amdblocks/i2c.h +++ b/src/soc/amd/common/block/include/amdblocks/i2c.h @@ -74,6 +74,7 @@ struct i2c_pad_control { struct soc_i3c_ctrlr_info { uintptr_t bar; const char *acpi_name; + unsigned int aoac_device; }; void fch_i2c_pad_init(unsigned int bus, diff --git a/src/soc/amd/common/block/include/amdblocks/lpc.h b/src/soc/amd/common/block/include/amdblocks/lpc.h index f85c4676cc1..1106e3483a0 100644 --- a/src/soc/amd/common/block/include/amdblocks/lpc.h +++ b/src/soc/amd/common/block/include/amdblocks/lpc.h @@ -140,6 +140,7 @@ void lpc_enable_sio_decode(const bool addr); uintptr_t lpc_spibase(void); void lpc_tpm_decode(void); void lpc_tpm_decode_spi(void); +void soc_lpc_tpm_decode_spi(void); void lpc_enable_rom(void); void lpc_enable_spi_prefetch(void); uint32_t lpc_get_rom2_region(size_t *bios_size); diff --git a/src/soc/amd/common/block/include/amdblocks/msr_zen.h b/src/soc/amd/common/block/include/amdblocks/msr_zen.h index 0e2d2c8fec8..cde4d7bddad 100644 --- a/src/soc/amd/common/block/include/amdblocks/msr_zen.h +++ b/src/soc/amd/common/block/include/amdblocks/msr_zen.h @@ -24,6 +24,9 @@ #define MCAX_MISC2_OFFSET 0xb #define MCAX_MISC3_OFFSET 0xc #define MCAX_MISC4_OFFSET 0xd +#define MCAX_SYND1_OFFSET 0xe +#define MCAX_SYND2_OFFSET 0xf + #define MCAX_MSR(bank, offset) (MCAX_MSR_BASE + (bank) * MCAX_BANK_SIZE + (offset)) #define MCAX_CTL_MSR(bank) MCAX_MSR(bank, MCAX_CTL_OFFSET) #define MCAX_STATUS_MSR(bank) MCAX_MSR(bank, MCAX_STATUS_OFFSET) @@ -38,6 +41,8 @@ #define MCAX_MISC2_MSR(bank) MCAX_MSR(bank, MCAX_MISC2_OFFSET) #define MCAX_MISC3_MSR(bank) MCAX_MSR(bank, MCAX_MISC3_OFFSET) #define MCAX_MISC4_MSR(bank) MCAX_MSR(bank, MCAX_MISC4_OFFSET) +#define MCAX_SYND1_MSR(bank) MCAX_MSR(bank, MCAX_SYND1_OFFSET) +#define MCAX_SYND2_MSR(bank) MCAX_MSR(bank, MCAX_SYND2_OFFSET) /* * The MCA CTL_MASK moved to a new location in the fam 17h+ CPUs and accessing the legacy diff --git a/src/soc/amd/common/block/include/amdblocks/root_complex.h b/src/soc/amd/common/block/include/amdblocks/root_complex.h index bfabf973a7c..c60872aa2a2 100644 --- a/src/soc/amd/common/block/include/amdblocks/root_complex.h +++ b/src/soc/amd/common/block/include/amdblocks/root_complex.h @@ -11,6 +11,11 @@ #define SMN_IOHC_MISC_BASE_13D1 0x13d10000 #define SMN_IOHC_MISC_BASE_13E1 0x13e10000 +#define SMN_IOHC_MISC_BASE_1D41 0x1d410000 +#define SMN_IOHC_MISC_BASE_1D51 0x1d510000 +#define SMN_IOHC_MISC_BASE_1D61 0x1d610000 +#define SMN_IOHC_MISC_BASE_1D71 0x1d710000 + #define IOHC_MMIO_EN BIT(0) #define NON_PCI_RES_IDX_AUTO 0 diff --git a/src/soc/amd/common/block/include/amdblocks/smn.h b/src/soc/amd/common/block/include/amdblocks/smn.h index 0268926bbe4..ad6972114ea 100644 --- a/src/soc/amd/common/block/include/amdblocks/smn.h +++ b/src/soc/amd/common/block/include/amdblocks/smn.h @@ -9,4 +9,12 @@ uint32_t smn_read32(uint32_t reg); uint64_t smn_read64(uint32_t reg); void smn_write32(uint32_t reg, uint32_t val); +#if defined(__SIMPLE_DEVICE__) + +uint32_t smn_io_read32(uint32_t reg); +uint64_t smn_io_read64(uint32_t reg); +void smn_io_write32(uint32_t reg, uint32_t val); + +#endif + #endif /* AMD_BLOCK_SMN_H */ diff --git a/src/soc/amd/common/block/lpc/lpc.c b/src/soc/amd/common/block/lpc/lpc.c index 2392d5f3e81..1aa81f66ca6 100644 --- a/src/soc/amd/common/block/lpc/lpc.c +++ b/src/soc/amd/common/block/lpc/lpc.c @@ -123,6 +123,10 @@ static void lpc_read_resources(struct device *dev) /* Add a memory resource for the eSPI MMIO */ mmio_range(dev, idx++, SPI_BASE_ADDRESS + ESPI_OFFSET_FROM_BAR, 4 * KiB); + /* Add a memory resource for the eSPI1 MMIO */ + if (CONFIG(SOC_AMD_COMMON_BLOCK_HAS_ESPI1)) + mmio_range(dev, idx++, SPI_BASE_ADDRESS + ESPI1_OFFSET_FROM_BAR, 4 * KiB); + /* FCH IOAPIC */ mmio_range(dev, idx++, IO_APIC_ADDR, 4 * KiB); diff --git a/src/soc/amd/common/block/lpc/lpc_util.c b/src/soc/amd/common/block/lpc/lpc_util.c index b796f3faa4b..d41ce0cff1d 100644 --- a/src/soc/amd/common/block/lpc/lpc_util.c +++ b/src/soc/amd/common/block/lpc/lpc_util.c @@ -220,6 +220,8 @@ void lpc_tpm_decode(void) pci_write_config32(_LPCB_DEV, LPC_TRUSTED_PLATFORM_MODULE, value); } +void __weak soc_lpc_tpm_decode_spi(void) { } + /* * Enable FCH to decode TPM associated Memory and IO regions to SPI * @@ -236,6 +238,8 @@ void lpc_tpm_decode_spi(void) SPI_BASE_ADDRESS_REGISTER); pci_write_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER, spibase | ROUTE_TPM_2_SPI); + + soc_lpc_tpm_decode_spi(); } /* diff --git a/src/soc/amd/common/block/pci/pcie_gpp.c b/src/soc/amd/common/block/pci/pcie_gpp.c index 0f983d04bea..03bd45f7ba8 100644 --- a/src/soc/amd/common/block/pci/pcie_gpp.c +++ b/src/soc/amd/common/block/pci/pcie_gpp.c @@ -28,22 +28,16 @@ static const char *pcie_gpp_acpi_name(const struct device *dev) static void acpi_device_write_gpp_pci_dev(const struct device *dev) { - const char *scope = acpi_device_scope(dev); - const char *name = acpi_device_name(dev); + const char *path = acpi_device_path(dev); assert(dev->path.type == DEVICE_PATH_PCI); - assert(name); - assert(scope); + assert(path); - acpigen_write_scope(scope); - acpigen_write_device(name); - - acpigen_write_ADR_pci_device(dev); - acpigen_write_STA(acpi_device_status(dev)); + acpigen_write_scope(path); + acpigen_write_store_int_to_namestr(acpi_device_status(dev), "STAT"); acpigen_write_pci_GNB_PRT(dev); - acpigen_pop_len(); /* Device */ acpigen_pop_len(); /* Scope */ } diff --git a/src/soc/amd/common/block/psp/psp.c b/src/soc/amd/common/block/psp/psp.c index 9ad04e1ce60..98eb0f9e84e 100644 --- a/src/soc/amd/common/block/psp/psp.c +++ b/src/soc/amd/common/block/psp/psp.c @@ -64,7 +64,7 @@ enum cb_err psp_get_ftpm_capabilties(uint32_t *capabilities) }, }; - printk(BIOS_DEBUG, "PSP: Querying fTPM capabilities..."); + printk(BIOS_DEBUG, "PSP: Querying fTPM capabilities... "); cmd_status = send_psp_command(MBOX_BIOS_CMD_PSP_FTPM_QUERY, &buffer); @@ -87,7 +87,7 @@ enum cb_err psp_get_hsti_state(uint32_t *state) }, }; - printk(BIOS_DEBUG, "PSP: Querying HSTI state..."); + printk(BIOS_DEBUG, "PSP: Querying HSTI state... "); cmd_status = send_psp_command(MBOX_BIOS_CMD_HSTI_QUERY, &buffer); diff --git a/src/soc/amd/common/block/smn/smn.c b/src/soc/amd/common/block/smn/smn.c index caf6a41004a..41396701e23 100644 --- a/src/soc/amd/common/block/smn/smn.c +++ b/src/soc/amd/common/block/smn/smn.c @@ -25,3 +25,25 @@ void smn_write32(uint32_t reg, uint32_t val) pci_write_config32(SOC_GNB_DEV, SMN_INDEX_ADDR, reg); pci_write_config32(SOC_GNB_DEV, SMN_DATA_ADDR, val); } + + +#if defined(__SIMPLE_DEVICE__) + +uint32_t smn_io_read32(uint32_t reg) +{ + pci_io_write_config32(SOC_GNB_DEV, SMN_INDEX_ADDR, reg); + return pci_io_read_config32(SOC_GNB_DEV, SMN_DATA_ADDR); +} + +uint64_t smn_io_read64(uint32_t reg) +{ + return smn_io_read32(reg) | (uint64_t)smn_io_read32(reg + 4) << 32; +} + +void smn_io_write32(uint32_t reg, uint32_t val) +{ + pci_io_write_config32(SOC_GNB_DEV, SMN_INDEX_ADDR, reg); + pci_io_write_config32(SOC_GNB_DEV, SMN_DATA_ADDR, val); +} + +#endif diff --git a/src/soc/amd/common/block/spi/fch_spi_ctrl.c b/src/soc/amd/common/block/spi/fch_spi_ctrl.c index c4ec4cc9b80..114c7332441 100644 --- a/src/soc/amd/common/block/spi/fch_spi_ctrl.c +++ b/src/soc/amd/common/block/spi/fch_spi_ctrl.c @@ -1,16 +1,24 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include -#include -#include #include #include #include +#include +#include #include #include +#include +#include #include #include +/* + * Default SPI CS line. When PSP fails to boot from CS0 it will + * attempt to boot from other CS lines as well. Keep track of the + * boot source for DUAL SPI access support. + */ +static uint8_t default_cs; + #define GRANULARITY_TEST_4k 0x0000f000 /* bits 15-12 */ #define WORD_TO_DWORD_UPPER(x) ((x << 16) & 0xffff0000) @@ -18,6 +26,8 @@ #define SPI_RESTRICTED_CMD1 0x04 #define SPI_RESTRICTED_CMD2 0x08 #define SPI_CNTRL1 0x0c +#define SPI_ALT_CS_REG 0x1d +#define SPI_ALT_CS_REG_MASK 0x03 #define SPI_CMD_CODE 0x45 #define SPI_CMD_TRIGGER 0x47 #define SPI_CMD_TRIGGER_EXECUTE BIT(7) @@ -114,9 +124,17 @@ static int execute_command(void) void spi_init(void) { printk(BIOS_DEBUG, "%s: SPI BAR at 0x%08lx\n", __func__, spi_get_bar()); + default_cs = spi_read8(SPI_ALT_CS_REG) & SPI_ALT_CS_REG_MASK; + printk(BIOS_DEBUG, "%s: Booting from SPI CS%d\n", __func__, default_cs); +} + +int boot_device_spi_cs(void) +{ + return default_cs; } static uint8_t cmd_code; +static uint8_t alt_cs; static uint8_t tx_byte_count; static uint8_t rx_byte_count; static uint8_t fifo[SPI_FIFO_DEPTH]; @@ -127,6 +145,7 @@ void fch_spi_backup_registers(void) if (ENV_SMM && (spi_read8(SPI_MISC_CNTRL) & SPI_SEMAPHORE_BIOS_LOCKED)) return; + alt_cs = spi_read8(SPI_ALT_CS_REG); cmd_code = spi_read8(SPI_CMD_CODE); tx_byte_count = spi_read8(SPI_TX_BYTE_COUNT); rx_byte_count = spi_read8(SPI_RX_BYTE_COUNT); @@ -141,6 +160,7 @@ void fch_spi_restore_registers(void) if (ENV_SMM && (spi_read8(SPI_MISC_CNTRL) & SPI_SEMAPHORE_BIOS_LOCKED)) return; + spi_write8(SPI_ALT_CS_REG, alt_cs); spi_write8(SPI_CMD_CODE, cmd_code); spi_write8(SPI_TX_BYTE_COUNT, tx_byte_count); spi_write8(SPI_RX_BYTE_COUNT, rx_byte_count); @@ -333,6 +353,16 @@ static int spi_ctrlr_claim_bus(const struct spi_slave *slave) spi_write8(SPI_MISC_CNTRL, reg8 | SPI_SEMAPHORE_BIOS_LOCKED); } + /* Set chip select line */ + if (slave->cs <= 3) { + reg8 = spi_read8(SPI_ALT_CS_REG); + if ((reg8 & SPI_ALT_CS_REG_MASK) != slave->cs) { + reg8 &= ~SPI_ALT_CS_REG_MASK; + reg8 |= slave->cs; + spi_write8(SPI_ALT_CS_REG, reg8); + } + } + return 0; } @@ -341,6 +371,14 @@ static void spi_ctrlr_release_bus(const struct spi_slave *slave) { uint8_t reg8; + /* Reset chip select line */ + reg8 = spi_read8(SPI_ALT_CS_REG); + if ((reg8 & SPI_ALT_CS_REG_MASK) != default_cs) { + reg8 &= ~SPI_ALT_CS_REG_MASK; + reg8 |= default_cs; + spi_write8(SPI_ALT_CS_REG, reg8); + } + if (ENV_RAMSTAGE && CONFIG(SOC_AMD_COMMON_BLOCK_PSP_SMI)) { reg8 = spi_read8(SPI_MISC_CNTRL); spi_write8(SPI_MISC_CNTRL, reg8 & ~SPI_SEMAPHORE_BIOS_LOCKED); diff --git a/src/soc/amd/genoa_poc/i3c.c b/src/soc/amd/genoa_poc/i3c.c index e6946231773..0e041942b64 100644 --- a/src/soc/amd/genoa_poc/i3c.c +++ b/src/soc/amd/genoa_poc/i3c.c @@ -1,14 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include static const struct soc_i3c_ctrlr_info i3c_ctrlr[I3C_CTRLR_COUNT] = { - { APU_I3C0_BASE, "I3C0" }, - { APU_I3C1_BASE, "I3C1" }, - { APU_I3C2_BASE, "I3C2" }, - { APU_I3C3_BASE, "I3C3" } + { APU_I3C0_BASE, "I3C0", FCH_AOAC_DEV_I3C0}, + { APU_I3C1_BASE, "I3C1", FCH_AOAC_DEV_I3C1}, + { APU_I3C2_BASE, "I3C2", FCH_AOAC_DEV_I3C2}, + { APU_I3C3_BASE, "I3C3", FCH_AOAC_DEV_I3C3} }; const struct soc_i3c_ctrlr_info *soc_get_i3c_ctrlr_info(size_t *num_ctrlrs) diff --git a/src/soc/amd/glinda/Kconfig b/src/soc/amd/glinda/Kconfig index 3be4725763d..70a1fc63310 100644 --- a/src/soc/amd/glinda/Kconfig +++ b/src/soc/amd/glinda/Kconfig @@ -92,7 +92,6 @@ config SOC_AMD_GLINDA_BASE select X86_AMD_FIXED_MTRRS select X86_INIT_NEED_1_SIPI select HAVE_X86_64_SUPPORT - select SOC_AMD_SUPPORTS_WARM_RESET help AMD Glinda support @@ -105,6 +104,7 @@ config SOC_AMD_GLINDA config SOC_AMD_FAEGAN bool select SOC_AMD_GLINDA_BASE + select SOC_AMD_SUPPORTS_WARM_RESET help AMD Faegan support diff --git a/src/soc/amd/glinda/acpi/acp.asl b/src/soc/amd/glinda/acpi/acp.asl new file mode 100644 index 00000000000..0e3dd5a0556 --- /dev/null +++ b/src/soc/amd/glinda/acpi/acp.asl @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* ACP Audio Configuration */ +Scope (\_SB.PCI0.GP41) { + Device (ACPD) { + /* Device addressing for ACP (Audio Coprocessor) */ + Name (_ADR, 0x05) /* Device 0, Function 5 */ + + Name (STAT, 0x3) /* Decoding Resources, Hide from UI */ + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + + /* Child Devices - Audio endpoints */ + Device (HDA0) /* HDA0 - HD Audio */ + { + Name (_ADR, 0x01) + } + + Device (PDMC) /* PDM Controller */ + { + Name (_ADR, 0x02) + } + + Device (I2SC) /* I2S Controller */ + { + Name (_ADR, 0x03) + } + + Device (BTSC) /* BT Sideband Controller */ + { + Name (_ADR, 0x04) + } + + Device (SDWC) /* SoundWire Controller */ + { + Name (_ADR, 0x05) + } + + Device(SDWS) /* SoundWire Streaming */ + { + Name (_ADR, 0x06) + } + + Device(USBS) /* USB Sideband */ + { + Name (_ADR, 0x07) + } + } +} diff --git a/src/soc/amd/glinda/acpi/pci.asl b/src/soc/amd/glinda/acpi/pci.asl new file mode 100644 index 00000000000..ec5e33da884 --- /dev/null +++ b/src/soc/amd/glinda/acpi/pci.asl @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +/* + * Keep name in sync with SSDT generator pcie_gpp_acpi_name()! + * Currently the name is hex representation of dev->path.pci.devfn. + */ + +/* Root complex */ +Device (GNB) +{ + Name (_ADR, 0) + Method (_STA, 0, NotSerialized) + { + Return (0x0F) + } +} + +/* USB4.0 bridge */ +ACPI_PCI_DEV(GP09, 1, 1) +ACPI_PCI_DEV(GP0A, 1, 2) +ACPI_PCI_DEV(GP0B, 1, 3) + +/* PCIe GPP */ +ACPI_PCI_DEV(GP11, 2, 1) +ACPI_PCI_DEV(GP12, 2, 2) +ACPI_PCI_DEV(GP13, 2, 3) +ACPI_PCI_DEV(GP14, 2, 4) +ACPI_PCI_DEV(GP15, 2, 5) +ACPI_PCI_DEV(GP16, 2, 6) + +/* PCIe GPP */ +ACPI_PCI_DEV(GP19, 3, 1) +ACPI_PCI_DEV(GP1A, 3, 2) +ACPI_PCI_DEV(GP1B, 3, 3) +ACPI_PCI_DEV(GP1C, 3, 4) +ACPI_PCI_DEV(GP1D, 3, 5) +ACPI_PCI_DEV(GP1E, 3, 6) + +/* Internal GPP bridges */ +ACPI_PCI_DEV(GP41, 8, 1) +ACPI_PCI_DEV(GP42, 8, 2) +ACPI_PCI_DEV(GP43, 8, 3) diff --git a/src/soc/amd/glinda/acpi/soc.asl b/src/soc/amd/glinda/acpi/soc.asl index 964cad94b52..82d55877510 100644 --- a/src/soc/amd/glinda/acpi/soc.asl +++ b/src/soc/amd/glinda/acpi/soc.asl @@ -23,7 +23,12 @@ Scope(\_SB) { Scope(PCI0) { #include + + #include "pci.asl" } /* End PCI0 scope */ + + #include "acp.asl" + } /* End \_SB scope */ #include diff --git a/src/soc/amd/glinda/fch.c b/src/soc/amd/glinda/fch.c index 849e4664429..1e0b08ced4f 100644 --- a/src/soc/amd/glinda/fch.c +++ b/src/soc/amd/glinda/fch.c @@ -156,6 +156,8 @@ static void cgpll_clock_gate_init(void) void fch_init(void *chip_info) { + if (!CONFIG(SOC_AMD_SUPPORTS_WARM_RESET)) + set_resets_to_cold(); i2c_soc_init(); fch_init_acpi_ports(); diff --git a/src/soc/amd/glinda/fsp_m_params.c b/src/soc/amd/glinda/fsp_m_params.c index 32a708fd70c..ff5f04c7f2c 100644 --- a/src/soc/amd/glinda/fsp_m_params.c +++ b/src/soc/amd/glinda/fsp_m_params.c @@ -3,6 +3,7 @@ /* TODO: Update for Glinda */ /* TODO: See what can be moved to common */ +#include #include #include #include @@ -13,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -176,6 +178,31 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) mcfg->usb_phy_ptr = 0; } + /* Sync AOAC devices */ + int fch_aoac_devs[] = { + FCH_AOAC_DEV_I2C0, + FCH_AOAC_DEV_I2C1, + FCH_AOAC_DEV_I2C2, + FCH_AOAC_DEV_I2C3, + FCH_AOAC_DEV_UART0, + FCH_AOAC_DEV_UART1, + FCH_AOAC_DEV_UART2, + FCH_AOAC_DEV_UART3, + FCH_AOAC_DEV_UART4, + FCH_AOAC_DEV_I3C0, + FCH_AOAC_DEV_I3C1, + FCH_AOAC_DEV_I3C2, + FCH_AOAC_DEV_I3C3, + }; + + for (int i = 0; i < ARRAY_SIZE(fch_aoac_devs); i++) { + const int mask = BIT(fch_aoac_devs[i]); + if (is_aoac_device_enabled(fch_aoac_devs[i])) + mcfg->fch_rt_device_enable_map |= mask; + else + mcfg->fch_rt_device_enable_map &= ~mask; + } + fsp_fill_pcie_ddi_descriptors(mcfg); fsp_assign_ioapic_upds(mcfg); mb_pre_fspm(mcfg); diff --git a/src/soc/amd/glinda/i3c.c b/src/soc/amd/glinda/i3c.c index e6946231773..0e041942b64 100644 --- a/src/soc/amd/glinda/i3c.c +++ b/src/soc/amd/glinda/i3c.c @@ -1,14 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include static const struct soc_i3c_ctrlr_info i3c_ctrlr[I3C_CTRLR_COUNT] = { - { APU_I3C0_BASE, "I3C0" }, - { APU_I3C1_BASE, "I3C1" }, - { APU_I3C2_BASE, "I3C2" }, - { APU_I3C3_BASE, "I3C3" } + { APU_I3C0_BASE, "I3C0", FCH_AOAC_DEV_I3C0}, + { APU_I3C1_BASE, "I3C1", FCH_AOAC_DEV_I3C1}, + { APU_I3C2_BASE, "I3C2", FCH_AOAC_DEV_I3C2}, + { APU_I3C3_BASE, "I3C3", FCH_AOAC_DEV_I3C3} }; const struct soc_i3c_ctrlr_info *soc_get_i3c_ctrlr_info(size_t *num_ctrlrs) diff --git a/src/soc/amd/glinda/xhci.c b/src/soc/amd/glinda/xhci.c index b67bb5a0601..64eb72c8d89 100644 --- a/src/soc/amd/glinda/xhci.c +++ b/src/soc/amd/glinda/xhci.c @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -14,25 +15,25 @@ static const struct sci_source xhci_sci_sources[] = { { .scimap = SMITYPE_XHC0_PME, - .gpe = GEVENT_31, + .gpe = XHCI_GEVENT, .direction = SMI_SCI_LVL_HIGH, .level = SMI_SCI_EDG }, { .scimap = SMITYPE_XHC1_PME, - .gpe = GEVENT_31, + .gpe = XHCI_GEVENT, .direction = SMI_SCI_LVL_HIGH, .level = SMI_SCI_EDG }, { .scimap = SMITYPE_XHC3_PME, - .gpe = GEVENT_31, + .gpe = XHCI_GEVENT, .direction = SMI_SCI_LVL_HIGH, .level = SMI_SCI_EDG }, { .scimap = SMITYPE_XHC4_PME, - .gpe = GEVENT_31, + .gpe = XHCI_GEVENT, .direction = SMI_SCI_LVL_HIGH, .level = SMI_SCI_EDG } diff --git a/src/soc/amd/mendocino/acpi/acp.asl b/src/soc/amd/mendocino/acpi/acp.asl new file mode 100644 index 00000000000..184fe157042 --- /dev/null +++ b/src/soc/amd/mendocino/acpi/acp.asl @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* ACP Audio Configuration */ +Scope (\_SB.PCI0.GP41) { + Device (ACPD) { + /* Device addressing for ACP (Audio Coprocessor) */ + Name (_ADR, 0x05) /* Device 0, Function 5 */ + + Name (STAT, 0x3) /* Decoding Resources, Hide from UI */ + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + } +} diff --git a/src/soc/amd/mendocino/acpi/pci.asl b/src/soc/amd/mendocino/acpi/pci.asl new file mode 100644 index 00000000000..774b4a8f670 --- /dev/null +++ b/src/soc/amd/mendocino/acpi/pci.asl @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +/* + * Keep name in sync with SSDT generator pcie_gpp_acpi_name()! + * Currently the name is hex representation of dev->path.pci.devfn. + */ + +/* Root complex */ +Device (GNB) +{ + Name (_ADR, 0) + Method (_STA, 0, NotSerialized) + { + Return (0x0F) + } +} + +/* PCIe GPP */ +ACPI_PCI_DEV(GP11, 2, 1) +ACPI_PCI_DEV(GP12, 2, 2) +ACPI_PCI_DEV(GP13, 2, 3) +ACPI_PCI_DEV(GP14, 2, 4) +ACPI_PCI_DEV(GP15, 2, 5) +ACPI_PCI_DEV(GP16, 2, 6) + +/* Internal GPP bridges */ +ACPI_PCI_DEV(GP41, 8, 1) +ACPI_PCI_DEV(GP42, 8, 2) +ACPI_PCI_DEV(GP43, 8, 3) diff --git a/src/soc/amd/mendocino/acpi/soc.asl b/src/soc/amd/mendocino/acpi/soc.asl index 5a73f3bd65f..8b78e4ec95c 100644 --- a/src/soc/amd/mendocino/acpi/soc.asl +++ b/src/soc/amd/mendocino/acpi/soc.asl @@ -23,7 +23,12 @@ Scope(\_SB) { Scope(PCI0) { #include + + #include "pci.asl" } /* End PCI0 scope */ + + #include "acp.asl" + } /* End \_SB scope */ #include diff --git a/src/soc/amd/mendocino/i3c.c b/src/soc/amd/mendocino/i3c.c index e6946231773..0e041942b64 100644 --- a/src/soc/amd/mendocino/i3c.c +++ b/src/soc/amd/mendocino/i3c.c @@ -1,14 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include static const struct soc_i3c_ctrlr_info i3c_ctrlr[I3C_CTRLR_COUNT] = { - { APU_I3C0_BASE, "I3C0" }, - { APU_I3C1_BASE, "I3C1" }, - { APU_I3C2_BASE, "I3C2" }, - { APU_I3C3_BASE, "I3C3" } + { APU_I3C0_BASE, "I3C0", FCH_AOAC_DEV_I3C0}, + { APU_I3C1_BASE, "I3C1", FCH_AOAC_DEV_I3C1}, + { APU_I3C2_BASE, "I3C2", FCH_AOAC_DEV_I3C2}, + { APU_I3C3_BASE, "I3C3", FCH_AOAC_DEV_I3C3} }; const struct soc_i3c_ctrlr_info *soc_get_i3c_ctrlr_info(size_t *num_ctrlrs) diff --git a/src/soc/amd/phoenix/acpi/acp.asl b/src/soc/amd/phoenix/acpi/acp.asl new file mode 100644 index 00000000000..2b6a5e876b6 --- /dev/null +++ b/src/soc/amd/phoenix/acpi/acp.asl @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* ACP Audio Configuration */ +Scope (\_SB.PCI0.GP41) { + Device (ACPD) { + /* Device addressing for ACP (Audio Coprocessor) */ + Name (_ADR, 0x05) /* Device 0, Function 5 */ + + Name (STAT, 0x3) /* Decoding Resources, Hide from UI */ + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + + /* Child Devices - Audio endpoints */ + Device (HDA0) /* HDA0 - HD Audio */ + { + Name (_ADR, 0x01) + } + + Device (PDMC) /* PDM Controller */ + { + Name (_ADR, 0x02) + } + + Device (I2SC) /* I2S Controller */ + { + Name (_ADR, 0x03) + } + + Device (BTSC) /* BT Sideband Controller */ + { + Name (_ADR, 0x04) + } + + Device (SDWC) /* SoundWire Controller */ + { + Name (_ADR, 0x05) + } + + Device (SDWS) /* SoundWire Streaming */ + { + Name (_ADR, 0x06) + } + + Device (USBS) /* USB Sideband */ + { + Name (_ADR, 0x07) + } + } +} diff --git a/src/soc/amd/phoenix/acpi/pci.asl b/src/soc/amd/phoenix/acpi/pci.asl new file mode 100644 index 00000000000..ae2c6173813 --- /dev/null +++ b/src/soc/amd/phoenix/acpi/pci.asl @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +/* + * Keep name in sync with SSDT generator pcie_gpp_acpi_name()! + * Currently the name is hex representation of dev->path.pci.devfn. + */ + +/* Root complex */ +Device (GNB) +{ + Name (_ADR, 0) + Method (_STA, 0, NotSerialized) + { + Return (0x0F) + } +} + +/* PCIe GPP */ +ACPI_PCI_DEV(GP09, 1, 1) +ACPI_PCI_DEV(GP0A, 1, 2) +ACPI_PCI_DEV(GP0B, 1, 3) +ACPI_PCI_DEV(GP0C, 1, 4) + +/* PCIe GPP */ +ACPI_PCI_DEV(GP11, 2, 1) +ACPI_PCI_DEV(GP12, 2, 2) +ACPI_PCI_DEV(GP13, 2, 3) +ACPI_PCI_DEV(GP14, 2, 4) +ACPI_PCI_DEV(GP15, 2, 5) +ACPI_PCI_DEV(GP16, 2, 6) + +/* USB4.0 bridges */ +ACPI_PCI_DEV(GP19, 3, 1) +ACPI_PCI_DEV(GP21, 4, 1) + +/* Internal GPP bridges */ +ACPI_PCI_DEV(GP41, 8, 1) +ACPI_PCI_DEV(GP42, 8, 2) +ACPI_PCI_DEV(GP43, 8, 3) diff --git a/src/soc/amd/phoenix/acpi/soc.asl b/src/soc/amd/phoenix/acpi/soc.asl index ee2e9c886b0..fcd41c34e94 100644 --- a/src/soc/amd/phoenix/acpi/soc.asl +++ b/src/soc/amd/phoenix/acpi/soc.asl @@ -23,7 +23,12 @@ Scope(\_SB) { Scope(PCI0) { #include + + #include "pci.asl" } /* End PCI0 scope */ + + #include "acp.asl" + } /* End \_SB scope */ #include diff --git a/src/soc/amd/phoenix/i3c.c b/src/soc/amd/phoenix/i3c.c index e6946231773..0e041942b64 100644 --- a/src/soc/amd/phoenix/i3c.c +++ b/src/soc/amd/phoenix/i3c.c @@ -1,14 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include static const struct soc_i3c_ctrlr_info i3c_ctrlr[I3C_CTRLR_COUNT] = { - { APU_I3C0_BASE, "I3C0" }, - { APU_I3C1_BASE, "I3C1" }, - { APU_I3C2_BASE, "I3C2" }, - { APU_I3C3_BASE, "I3C3" } + { APU_I3C0_BASE, "I3C0", FCH_AOAC_DEV_I3C0}, + { APU_I3C1_BASE, "I3C1", FCH_AOAC_DEV_I3C1}, + { APU_I3C2_BASE, "I3C2", FCH_AOAC_DEV_I3C2}, + { APU_I3C3_BASE, "I3C3", FCH_AOAC_DEV_I3C3} }; const struct soc_i3c_ctrlr_info *soc_get_i3c_ctrlr_info(size_t *num_ctrlrs) diff --git a/src/soc/amd/picasso/acpi/acp.asl b/src/soc/amd/picasso/acpi/acp.asl new file mode 100644 index 00000000000..184fe157042 --- /dev/null +++ b/src/soc/amd/picasso/acpi/acp.asl @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* ACP Audio Configuration */ +Scope (\_SB.PCI0.GP41) { + Device (ACPD) { + /* Device addressing for ACP (Audio Coprocessor) */ + Name (_ADR, 0x05) /* Device 0, Function 5 */ + + Name (STAT, 0x3) /* Decoding Resources, Hide from UI */ + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + } +} diff --git a/src/soc/amd/picasso/acpi/pci.asl b/src/soc/amd/picasso/acpi/pci.asl new file mode 100644 index 00000000000..4f119fe42d6 --- /dev/null +++ b/src/soc/amd/picasso/acpi/pci.asl @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +/* + * Keep name in sync with SSDT generator pcie_gpp_acpi_name()! + * Currently the name is hex representation of dev->path.pci.devfn. + */ + +/* Root complex */ +Device (GNB) +{ + Name (_ADR, 0) + Method (_STA, 0, NotSerialized) + { + Return (0x0F) + } +} + +/* PCIe GPP */ +ACPI_PCI_DEV(GP09, 1, 1) +ACPI_PCI_DEV(GP0A, 1, 2) +ACPI_PCI_DEV(GP0B, 1, 3) +ACPI_PCI_DEV(GP0C, 1, 4) +ACPI_PCI_DEV(GP0D, 1, 5) +ACPI_PCI_DEV(GP0E, 1, 6) +ACPI_PCI_DEV(GP0F, 1, 7) + +/* Internal GPP bridges */ +ACPI_PCI_DEV(GP41, 8, 1) +ACPI_PCI_DEV(GP42, 8, 2) +ACPI_PCI_DEV(GP43, 8, 3) diff --git a/src/soc/amd/picasso/acpi/soc.asl b/src/soc/amd/picasso/acpi/soc.asl index 7c13f0863ec..67eb3f57494 100644 --- a/src/soc/amd/picasso/acpi/soc.asl +++ b/src/soc/amd/picasso/acpi/soc.asl @@ -22,6 +22,7 @@ Scope(\_SB) { /* Start \_SB scope */ Scope(PCI0) { /* Describe the AMD Northbridge */ #include "northbridge.asl" + #include "pci.asl" /* Describe the AMD Fusion Controller Hub */ #include @@ -37,6 +38,8 @@ Scope(\_SB) { /* Start \_SB scope */ /* Describe the MMIO devices in the FCH */ #include "mmio.asl" + #include "acp.asl" + /* Add GPIO library */ #include diff --git a/src/soc/amd/picasso/xhci.c b/src/soc/amd/picasso/xhci.c index a238916b71e..1258234df49 100644 --- a/src/soc/amd/picasso/xhci.c +++ b/src/soc/amd/picasso/xhci.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -12,13 +13,13 @@ static const struct sci_source xhci_sci_sources[] = { { .scimap = SMITYPE_XHC0_PME, - .gpe = GEVENT_31, + .gpe = XHCI_GEVENT, .direction = SMI_SCI_LVL_HIGH, .level = SMI_SCI_EDG }, { .scimap = SMITYPE_XHC1_PME, - .gpe = GEVENT_31, + .gpe = XHCI_GEVENT, .direction = SMI_SCI_LVL_HIGH, .level = SMI_SCI_EDG } diff --git a/src/soc/amd/turin_poc/Kconfig b/src/soc/amd/turin_poc/Kconfig index 55af8c71e6b..afdedfd94a5 100644 --- a/src/soc/amd/turin_poc/Kconfig +++ b/src/soc/amd/turin_poc/Kconfig @@ -10,23 +10,39 @@ config SOC_SPECIFIC_OPTIONS select ACPI_SOC_NVS select ARCH_X86 select DEFAULT_X2APIC + select BOOT_DEVICE_SUPPORTS_WRITES if BOOT_DEVICE_SPI_FLASH + select CACHE_MRC_SETTINGS + select DRIVERS_USB_ACPI + select DRIVERS_USB_PCI_XHCI + select GENERIC_GPIO_LIB select HAVE_ACPI_TABLES + select HAVE_CF9_RESET + select HAVE_EM100_SUPPORT select HAVE_X86_64_SUPPORT - select HAVE_SMI_HANDLER + select HAVE_SMI_HANDLER if !NO_SMM + select IDT_IN_EVERY_STAGE + select PARALLEL_MP_AP_WORK + select PROVIDES_ROM_SHARING + select RTC select SOC_AMD_COMMON select SOC_AMD_COMMON_BLOCK_ACPI select SOC_AMD_COMMON_BLOCK_ACPIMMIO + select SOC_AMD_COMMON_BLOCK_ACPIMMIO_PM_IO_ACCESS select SOC_AMD_COMMON_BLOCK_ACPI_CPU_POWER_STATE select SOC_AMD_COMMON_BLOCK_ACPI_IVRS select SOC_AMD_COMMON_BLOCK_ACPI_MADT select SOC_AMD_COMMON_BLOCK_AOAC + select SOC_AMD_COMMON_BLOCK_APOB select SOC_AMD_COMMON_BLOCK_BANKED_GPIOS - select SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM17H_19H + select SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM1AH select SOC_AMD_COMMON_BLOCK_DATA_FABRIC select SOC_AMD_COMMON_BLOCK_DATA_FABRIC_DOMAIN select SOC_AMD_COMMON_BLOCK_DATA_FABRIC_MULTI_PCI_SEGMENT select SOC_AMD_COMMON_BLOCK_DATA_FABRIC_EXTENDED_MMIO select SOC_AMD_COMMON_BLOCK_HAS_ESPI + select SOC_AMD_COMMON_BLOCK_HAS_ESPI_ALERT_ENABLE + select SOC_AMD_COMMON_BLOCK_ESPI_EXTENDED_DECODE_RANGES + select SOC_AMD_COMMON_BLOCK_ESPI_RETAIN_PORT80_EN select SOC_AMD_COMMON_BLOCK_I2C select SOC_AMD_COMMON_BLOCK_I3C select SOC_AMD_COMMON_BLOCK_IOMMU @@ -35,8 +51,11 @@ config SOC_SPECIFIC_OPTIONS select SOC_AMD_COMMON_BLOCK_NONCAR select SOC_AMD_COMMON_BLOCK_PCI select SOC_AMD_COMMON_BLOCK_PCI_MMCONF + select SOC_AMD_COMMON_BLOCK_PM select SOC_AMD_COMMON_BLOCK_PSP_GEN2 + select SOC_AMD_COMMON_BLOCK_PSP_SMI select SOC_AMD_COMMON_BLOCK_PSP_SPL + select SOC_AMD_COMMON_BLOCK_SMBUS select SOC_AMD_COMMON_BLOCK_SMI select SOC_AMD_COMMON_BLOCK_SMM select SOC_AMD_COMMON_BLOCK_SMU @@ -47,8 +66,16 @@ config SOC_SPECIFIC_OPTIONS select SOC_AMD_COMMON_BLOCK_UART select SOC_AMD_COMMON_BLOCK_UCODE select SOC_AMD_COMMON_BLOCK_USE_ESPI + select SOC_AMD_COMMON_BLOCK_XHCI select SOC_AMD_OPENSIL + select SOC_AMD_OPENSIL_TURIN_POC select OPENSIL_DRIVER + select DRAM_SUPPORT_DDR5 + select SSE2 + select X86_AMD_FIXED_MTRRS + select X86_INIT_NEED_1_SIPI + select VBOOT_X86_SHA256_ACCELERATION if VBOOT + select UDK_2017_BINDING config USE_X86_64_SUPPORT default y @@ -73,7 +100,11 @@ config EARLY_RESERVED_DRAM_BASE config EARLYRAM_BSP_STACK_SIZE hex - default 0x1000 + default 0x10000 + +config STACK_SIZE + hex + default 0x10000 config MAX_CPUS int @@ -81,14 +112,18 @@ config MAX_CPUS config PSP_APOB_DRAM_ADDRESS hex - default 0x7001000 + default 0x7010000 help Location in DRAM where the PSP will copy the AGESA PSP Output Block. config PSP_APOB_DRAM_SIZE hex - default 0x20000 + default 0xd0000 + +config MRC_SETTINGS_CACHE_SIZE + hex + default 0xd0000 config PRERAM_CBMEM_CONSOLE_SIZE hex @@ -106,7 +141,7 @@ config C_ENV_BOOTBLOCK_SIZE config ROMSTAGE_ADDR hex - default 0x7050000 + default 0x7150000 help Sets the address in DRAM where romstage should be loaded. @@ -124,6 +159,14 @@ config ECAM_MMCONF_BUS_NUMBER int default 256 +config DISABLE_KEYBOARD_RESET_PIN + bool + help + Instruct the SoC to not use the state of GPIO_129 as keyboard reset. + +config CPU_PT_ROM_MAP_GB + default 1024 + menu "PSP Configuration Options" config AMDFW_CONFIG_FILE @@ -141,7 +184,7 @@ config PSP_INIT_ESPI Select to initialize the eSPI controller in the PSP Stage 2 Boot Loader. -config PSP_UNLOCK_SECURE_DEBUG +config PSP_UNLOCK_SECURE_DEBUG bool default y @@ -171,6 +214,11 @@ config PSP_SOFTFUSE_BITS 0=SoC MMIO UART, 1=IO port 0x3F8 See #57299 (NDA) for additional bit definitions. + +config PSPV2_MBOX_CMD_OFFSET + hex + default 0x10970 + endmenu config CONSOLE_UART_BASE_ADDRESS @@ -179,6 +227,7 @@ config CONSOLE_UART_BASE_ADDRESS default 0xfedc9000 if UART_FOR_CONSOLE = 0 default 0xfedca000 if UART_FOR_CONSOLE = 1 default 0xfedce000 if UART_FOR_CONSOLE = 2 + default 0xfedcf000 if UART_FOR_CONSOLE = 3 config SMM_TSEG_SIZE hex @@ -208,4 +257,44 @@ config ACPI_BERT_SIZE Specify the amount of DRAM reserved for gathering the data used to generate the ACPI table. +config ASYNC_FILE_LOADING + bool "Loads files from SPI asynchronously" + select COOP_MULTITASKING + select SOC_AMD_COMMON_BLOCK_LPC_SPI_DMA + select CBFS_PRELOAD + help + When enabled, the platform will use the LPC SPI DMA controller to + asynchronously load contents from the SPI ROM. This will improve + boot time because the CPUs can be performing useful work while the + SPI contents are being preloaded. + +config CBFS_CACHE_SIZE + hex + default 0x40000 if CBFS_PRELOAD + +config VBOOT + select VBOOT_STARTS_IN_BOOTBLOCK + select VBOOT_VBNV_CMOS + select VBOOT_VBNV_CMOS_BACKUP_TO_FLASH + +config RO_REGION_ONLY + string + depends on VBOOT_SLOTS_RW_AB || VBOOT_SLOTS_RW_A + default "apu/amdfw" + +config DISABLE_SPI_FLASH_ROM_SHARING + def_bool n + help + Instruct the chipset to not honor the EGPIO67_SPI_ROM_REQ pin + which indicates a board level ROM transaction request. This + removes arbitration with board and assumes the chipset controls + the SPI flash bus entirely. + +config SERIRQ_CONTINUOUS_MODE + bool + default n + help + Set this option to y for serial IRQ in continuous mode. + Otherwise it is in quiet mode. + endif # SOC_AMD_TURIN_POC diff --git a/src/soc/amd/turin_poc/Makefile.mk b/src/soc/amd/turin_poc/Makefile.mk index ab4d40f2570..5cbcbea405a 100644 --- a/src/soc/amd/turin_poc/Makefile.mk +++ b/src/soc/amd/turin_poc/Makefile.mk @@ -8,6 +8,9 @@ all-y += i2c.c all-y += i3c.c all-y += uart.c +all-y += lpc.c +smm-y += lpc.c + bootblock-y += early_fch.c bootblock-y += aoac.c @@ -32,6 +35,7 @@ ifeq ($(call int-gt, $(CONFIG_ROM_SIZE) 0x1000000), 1) CBFSTOOL_ADD_CMD_OPTIONS+= --mmap 0:0xff000000:0x1000000 endif +ifneq ($(call strip_quotes, $(CONFIG_AMDFW_CONFIG_FILE)),) # # PSP Directory Table items # @@ -79,6 +83,14 @@ PSP_ELF_FILE=$(objcbfs)/bootblock_fixed_data.elf PSP_BIOSBIN_SIZE=$(shell $(READELF_bootblock) -Wl $(PSP_ELF_FILE) | grep LOAD | awk '{print $$5}') PSP_BIOSBIN_DEST=$(shell $(READELF_bootblock) -Wl $(PSP_ELF_FILE) | grep LOAD | awk '{print $$3}') +ifneq ($(CONFIG_SOC_AMD_COMMON_BLOCK_APOB_NV_DISABLE),y) +# type = 0x63 - construct APOB NV base/size from flash map +# The flashmap section used for this is expected to be named RW_MRC_CACHE +# Size should be 0xD0000 +APOB_NV_SIZE=$(call get_fmap_value,FMAP_SECTION_RW_MRC_CACHE_SIZE) +APOB_NV_BASE=$(call get_fmap_value,FMAP_SECTION_RW_MRC_CACHE_START) +endif # !CONFIG_SOC_AMD_COMMON_BLOCK_APOB_NV_DISABLE + # Helper function to return a value with given bit set # Soft Fuse type = 0xb - See #57299 (NDA) for bit definitions. set-bit=$(call int-shift-left, 1 $(call _toint,$1)) @@ -104,6 +116,9 @@ OPT_PSP_BIOSBIN_FILE=$(call add_opt_prefix, $(PSP_BIOSBIN_FILE), --bios-bin) OPT_PSP_BIOSBIN_DEST=$(call add_opt_prefix, $(PSP_BIOSBIN_DEST), --bios-bin-dest) OPT_PSP_BIOSBIN_SIZE=$(call add_opt_prefix, $(PSP_BIOSBIN_SIZE), --bios-uncomp-size) +OPT_APOB_NV_SIZE=$(call add_opt_prefix, $(APOB_NV_SIZE), --apob-nv-size) +OPT_APOB_NV_BASE=$(call add_opt_prefix, $(APOB_NV_BASE), --apob-nv-base) + OPT_EFS_SPI_READ_MODE=$(call add_opt_prefix, $(CONFIG_EFS_SPI_READ_MODE), --spi-read-mode) OPT_EFS_SPI_SPEED=$(call add_opt_prefix, $(CONFIG_EFS_SPI_SPEED), --spi-speed) OPT_EFS_SPI_MICRON_FLAG=$(call add_opt_prefix, $(CONFIG_EFS_SPI_MICRON_FLAG), --spi-micron-flag) @@ -112,14 +127,22 @@ OPT_PSP_SOFTFUSE=$(call add_opt_prefix, $(PSP_SOFTFUSE), --soft-fuse) OPT_WHITELIST_FILE=$(call add_opt_prefix, $(PSP_WHITELIST_FILE), --whitelist) OPT_SPL_TABLE_FILE=$(call add_opt_prefix, $(SPL_TABLE_FILE), --spl-table) +OPT_UCODE_FILES=$(foreach i, $(shell seq $(words $(amd_microcode_bins))), \ + $(call add_opt_prefix, $(word $(i), $(amd_microcode_bins)), \ + --instance $(shell printf "%x" $$(($(i)-1))) --ucode)) + AMDFW_COMMON_ARGS=$(OPT_PSP_APCB_FILES) \ $(OPT_APOB_ADDR) \ + $(OPT_APOB_NV_SIZE) \ + $(OPT_APOB_NV_BASE) \ + $(OPT_UCODE_FILES) \ $(OPT_DEBUG_AMDFWTOOL) \ $(OPT_PSP_BIOSBIN_FILE) \ $(OPT_PSP_BIOSBIN_DEST) \ $(OPT_PSP_BIOSBIN_SIZE) \ $(OPT_PSP_SOFTFUSE) \ --use-pspsecureos \ + --load-s0i3 \ $(OPT_TOKEN_UNLOCK) \ $(OPT_WHITELIST_FILE) \ $(OPT_SPL_TABLE_FILE) \ @@ -127,11 +150,12 @@ AMDFW_COMMON_ARGS=$(OPT_PSP_APCB_FILES) \ $(OPT_EFS_SPI_SPEED) \ $(OPT_EFS_SPI_MICRON_FLAG) \ --config $(CONFIG_AMDFW_CONFIG_FILE) \ - --flashsize 0x1000000 + --flashsize $(call strip_quotes, $(CONFIG_ROM_SIZE)) $(obj)/amdfw.rom: $(call strip_quotes, $(PSP_BIOSBIN_FILE)) \ $$(PSP_APCB_FILES) \ $(DEP_FILES) \ + $(UCODE_FILES) \ $(AMDFWTOOL) \ $(obj)/fmap_config.h \ $(objcbfs)/bootblock_fixed_data.elf # this target also creates the .map file @@ -157,4 +181,8 @@ $(PSP_BIOSBIN_FILE): $(PSP_ELF_FILE) $(AMDCOMPRESS) $(AMDCOMPRESS) --infile $(PSP_ELF_FILE) --outfile $@ --compress \ --maxsize $(PSP_BIOSBIN_SIZE) +else +# Set FIRMWARE_LOCATION to get the microcode files +FIRMWARE_LOCATION=3rdparty/amd_firmwares/Firmwares/Turin +endif # ifneq ($(call strip_quotes, $(CONFIG_AMDFW_CONFIG_FILE)),) endif diff --git a/src/soc/amd/turin_poc/acpi.c b/src/soc/amd/turin_poc/acpi.c index 9091050ba5f..224f2464a93 100644 --- a/src/soc/amd/turin_poc/acpi.c +++ b/src/soc/amd/turin_poc/acpi.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -40,6 +39,7 @@ unsigned long soc_acpi_write_tables(const struct device *device, unsigned long c struct acpi_rsdp *rsdp) { /* IVRS */ + printk(BIOS_DEBUG, "ACPI: * IVRS\n"); current = acpi_add_ivrs_table(current, rsdp); return current; @@ -54,7 +54,7 @@ const acpi_cstate_t cstate_cfg_table[] = { }, [1] = { .ctype = 2, - .latency = 0x12, + .latency = 0x64, .power = 0, }, }; diff --git a/src/soc/amd/turin_poc/acpi/mmio.asl b/src/soc/amd/turin_poc/acpi/mmio.asl index 9b5e1d2d2b4..6ec247f788a 100644 --- a/src/soc/amd/turin_poc/acpi/mmio.asl +++ b/src/soc/amd/turin_poc/acpi/mmio.asl @@ -33,6 +33,7 @@ Device (GPIO) Shared, , , IRQR) { 0 } Memory32Fixed (ReadWrite, ACPIMMIO_GPIO0_BASE, 0x400) + Memory32Fixed (ReadWrite, ACPIMMIO_RGPIO_BASE, 0x2C) } CreateDWordField (Local0, IRQR._INT, IRQN) If (PICM) { @@ -43,6 +44,7 @@ Device (GPIO) If (IRQN == 0x1f || IRQN == 0) { Return (ResourceTemplate() { Memory32Fixed (ReadWrite, ACPIMMIO_GPIO0_BASE, 0x400) + Memory32Fixed (ReadWrite, ACPIMMIO_RGPIO_BASE, 0x2C) }) } Else { Return (Local0) @@ -68,6 +70,7 @@ Device (FUR0) Exclusive, , , IRQR) { 0 } Memory32Fixed (ReadWrite, APU_UART0_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA0_BASE, 0x1000) } CreateDWordField (Local0, IRQR._INT, IRQN) If (PICM) { @@ -78,6 +81,7 @@ Device (FUR0) If (IRQN == 0x1f) { Return (ResourceTemplate() { Memory32Fixed (ReadWrite, APU_UART0_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA0_BASE, 0x1000) }) } Else { Return (Local0) @@ -105,6 +109,7 @@ Device (FUR1) { Exclusive, , , IRQR) { 0 } Memory32Fixed (ReadWrite, APU_UART1_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA1_BASE, 0x1000) } CreateDWordField (Local0, IRQR._INT, IRQN) If (PICM) { @@ -115,6 +120,7 @@ Device (FUR1) { If (IRQN == 0x1f) { Return (ResourceTemplate() { Memory32Fixed (ReadWrite, APU_UART1_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA1_BASE, 0x1000) }) } Else { Return (Local0) @@ -142,6 +148,7 @@ Device (FUR2) { Exclusive, , , IRQR) { 0 } Memory32Fixed (ReadWrite, APU_UART2_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA2_BASE, 0x1000) } CreateDWordField (Local0, IRQR._INT, IRQN) If (PICM) { @@ -152,6 +159,7 @@ Device (FUR2) { If (IRQN == 0x1f) { Return (ResourceTemplate() { Memory32Fixed (ReadWrite, APU_UART2_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA2_BASE, 0x1000) }) } Else { Return (Local0) @@ -167,6 +175,45 @@ Device (FUR2) { AOAC_DEVICE(FCH_AOAC_DEV_UART2, 0) } +Device (FUR3) { + Name (_HID, "AMDI0020") + Name (_UID, 0x3) + Method (_CRS, 0) { + Local0 = ResourceTemplate() { + Interrupt ( + ResourceConsumer, + Edge, + ActiveHigh, + Exclusive, , , IRQR) + { 0 } + Memory32Fixed (ReadWrite, APU_UART3_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA3_BASE, 0x1000) + } + CreateDWordField (Local0, IRQR._INT, IRQN) + If (PICM) { + IRQN = IUA3 + } Else { + IRQN = PUA3 + } + If (IRQN == 0x1f) { + Return (ResourceTemplate() { + Memory32Fixed (ReadWrite, APU_UART3_BASE, 0x1000) + Memory32Fixed (ReadWrite, APU_DMA3_BASE, 0x1000) + }) + } Else { + Return (Local0) + } + } + + Name (STAT, 0x0) + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + + AOAC_DEVICE(FCH_AOAC_DEV_UART3, 0) +} + Device (I2C0) { Name (_HID, "AMDI0010") Name (_UID, 0x0) @@ -412,3 +459,187 @@ Device (MISC) Return (0x0B) } } + +Device (I3C0) +{ + Name (STAT, 0x0) + + /* Only return I3C controller HID "AMDI0015" when device is enabled in devicetree */ + Method (_HID, 0x0) { + If (STAT) { + Return ("AMDI0015") + } Else { + Return ("AMDI0016") + } + } + Name (_UID, 0x0) + Method (_CRS, 0) { + Local0 = ResourceTemplate() { + Interrupt ( + ResourceConsumer, + Edge, + ActiveHigh, + Exclusive, , , IRQR) + { 0 } + Memory32Fixed (ReadWrite, APU_I3C0_BASE, 0x1000) + } + CreateDWordField (Local0, IRQR._INT, IRQN) + If (PICM) { + IRQN = II20 + } Else { + IRQN = PI20 + } + If (IRQN == 0x1f) { + Return (ResourceTemplate() { + Memory32Fixed (ReadWrite, APU_I3C0_BASE, 0x1000) + }) + } Else { + Return (Local0) + } + } + + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + + AOAC_DEVICE(FCH_AOAC_DEV_I3C0, 0) +} + +Device (I3C1) +{ + Name (STAT, 0x0) + + /* Only return I3C controller HID "AMDI0015" when device is enabled in devicetree */ + Method (_HID, 0x0) { + If (STAT) { + Return ("AMDI0015") + } Else { + Return ("AMDI0016") + } + } + Name (_UID, 0x1) + Method (_CRS, 0) { + Local0 = ResourceTemplate() { + Interrupt ( + ResourceConsumer, + Edge, + ActiveHigh, + Exclusive, , , IRQR) + { 0 } + Memory32Fixed (ReadWrite, APU_I3C1_BASE, 0x1000) + } + CreateDWordField (Local0, IRQR._INT, IRQN) + If (PICM) { + IRQN = II21 + } Else { + IRQN = PI21 + } + If (IRQN == 0x1f) { + Return (ResourceTemplate() { + Memory32Fixed (ReadWrite, APU_I3C1_BASE, 0x1000) + }) + } Else { + Return (Local0) + } + } + + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + + AOAC_DEVICE(FCH_AOAC_DEV_I3C1, 0) +} + +Device (I3C2) +{ + Name (STAT, 0x0) + + /* Only return I3C controller HID "AMDI0015" when device is enabled in devicetree */ + Method (_HID, 0x0) { + If (STAT) { + Return ("AMDI0015") + } Else { + Return ("AMDI0016") + } + } + Name (_UID, 0x2) + Method (_CRS, 0) { + Local0 = ResourceTemplate() { + Interrupt ( + ResourceConsumer, + Edge, + ActiveHigh, + Exclusive, , , IRQR) + { 0 } + Memory32Fixed (ReadWrite, APU_I3C2_BASE, 0x1000) + } + CreateDWordField (Local0, IRQR._INT, IRQN) + If (PICM) { + IRQN = II22 + } Else { + IRQN = PI22 + } + If (IRQN == 0x1f) { + Return (ResourceTemplate() { + Memory32Fixed (ReadWrite, APU_I3C2_BASE, 0x1000) + }) + } Else { + Return (Local0) + } + } + + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + + AOAC_DEVICE(FCH_AOAC_DEV_I3C2, 0) +} + +Device (I3C3) +{ + Name (STAT, 0x0) + + /* Only return I3C controller HID "AMDI0015" when device is enabled in devicetree */ + Method (_HID, 0x0) { + If (STAT) { + Return ("AMDI0015") + } Else { + Return ("AMDI0016") + } + } + Name (_UID, 0x3) + Method (_CRS, 0) { + Local0 = ResourceTemplate() { + Interrupt ( + ResourceConsumer, + Edge, + ActiveHigh, + Exclusive, , , IRQR) + { 0 } + Memory32Fixed (ReadWrite, APU_I3C3_BASE, 0x1000) + } + CreateDWordField (Local0, IRQR._INT, IRQN) + If (PICM) { + IRQN = II23 + } Else { + IRQN = PI23 + } + If (IRQN == 0x1f) { + Return (ResourceTemplate() { + Memory32Fixed (ReadWrite, APU_I3C3_BASE, 0x1000) + }) + } Else { + Return (Local0) + } + } + + Method (_STA, 0x0, NotSerialized) + { + Return (STAT) + } + + AOAC_DEVICE(FCH_AOAC_DEV_I3C3, 0) +} diff --git a/src/soc/amd/turin_poc/acpi/pci_int_defs.asl b/src/soc/amd/turin_poc/acpi/pci_int_defs.asl index 22455c5cae7..14b2f7db44e 100644 --- a/src/soc/amd/turin_poc/acpi/pci_int_defs.asl +++ b/src/soc/amd/turin_poc/acpi/pci_int_defs.asl @@ -21,17 +21,30 @@ IndexField(PRQI, PRQD, ByteAcc, NoLock, Preserve) { PIRG, 0x00000008, /* Index 6: INTG */ PIRH, 0x00000008, /* Index 7: INTH */ - Offset (0x10), + Offset (0xc), + SIRA, 0x00000008, /* Index 0xc: Serial IRQ A */ + SIRB, 0x00000008, /* Index 0xd: Serial IRQ B */ + SIRC, 0x00000008, /* Index 0xe: Serial IRQ C */ + SIRD, 0x00000008, /* Index 0xf: Serial IRQ D */ PSCI, 0x00000008, /* Index 0x10: SCI */ PSB0, 0x00000008, /* Index 0x11: SMBUS0 */ PASF, 0x00000008, /* Index 0x12: ASF */ + PHDA, 0x00000008, /* Index 0x12: HDA */ Offset (0x16), PPMN, 0x00000008, /* Index 0x16: PerMon */ + PSDC, 0x00000008, /* Index 0x17: SD */ Offset (0x1a), PSIO, 0x00000008, /* Index 0x1A: SDIO */ + Offset (0x30), + PUS1, 0x00000008, /* Index 0x30: USB EMU */ + Offset (0x34), + PUS3, 0x00000008, /* Index 0x34: XHCI0 */ + Offset (0x41), + PSAT, 0x00000008, /* Index 0x41: SATA */ + Offset (0x50), PGP0, 0x00000008, /* Index 0x50: GPP0 */ PGP1, 0x00000008, /* Index 0x51: GPP1 */ @@ -64,27 +77,40 @@ IndexField(PRQI, PRQD, ByteAcc, NoLock, Preserve) { IORG, 0x00000008, /* Index 0x86: INTG */ IORH, 0x00000008, /* Index 0x87: INTH */ - Offset (0x90), + Offset (0x8c), + ISIA, 0x00000008, /* Index 0x8c: Serial IRQ A */ + ISIB, 0x00000008, /* Index 0x8d: Serial IRQ B */ + ISIC, 0x00000008, /* Index 0x8e: Serial IRQ C */ + ISID, 0x00000008, /* Index 0x8f: Serial IRQ D */ ISCI, 0x00000008, /* Index 0x90: SCI */ ISB0, 0x00000008, /* Index 0x91: SMBUS0 */ IASF, 0x00000008, /* Index 0x92: ASF */ + IHDA, 0x00000008, /* Index 0x93: HDA */ Offset (0x96), IPMN, 0x00000008, /* Index 0x96: PerMon */ + ISDC, 0x00000008, /* Index 0x97: SD */ Offset (0x9a), ISIO, 0x00000008, /* Index 0x9A: SDIO */ - Offset (0xD0), + Offset (0xb0), + IUS1, 0x00000008, /* Index 0xb0: USB EMU */ + Offset (0xb4), + IUS3, 0x00000008, /* Index 0xb4: XHCI0 */ + Offset (0xc1), + ISAT, 0x00000008, /* Index 0xc1: SATA */ + + Offset (0xd0), IGP0, 0x00000008, /* Index 0xD0: GPP0 */ IGP1, 0x00000008, /* Index 0xD1: GPP1 */ IGP2, 0x00000008, /* Index 0xD2: GPP2 */ IGP3, 0x00000008, /* Index 0xD3: GPP3 */ - Offset (0xE2), + Offset (0xe2), IGPI, 0x00000008, /* Index 0xE2: GPIO */ - Offset (0xF0), + Offset (0xf0), II20, 0x00000008, /* Index 0xF0: I2C0/I3C0 */ II21, 0x00000008, /* Index 0xF1: I2C1/I3C1 */ II22, 0x00000008, /* Index 0xF2: I2C2/I3C2 */ diff --git a/src/soc/amd/turin_poc/acpi/resources.asl b/src/soc/amd/turin_poc/acpi/resources.asl new file mode 100644 index 00000000000..98437690b56 --- /dev/null +++ b/src/soc/amd/turin_poc/acpi/resources.asl @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* PCI Device Resource Consumption */ +Device (PDRC) { + Name (_HID, EISAID("PNP0C02")) + Name (_UID, 0x700) + Name (_STA, 0x0F) + Name (_CRS, ResourceTemplate () + { + IO (Decode16, 0x0010, 0x0010, 0x00, 0x10, ) + IO (Decode16, 0x0022, 0x0022, 0x00, 0x1e, ) + IO (Decode16, 0x0063, 0x0063, 0x00, 0x01, ) + IO (Decode16, 0x0065, 0x0065, 0x00, 0x01, ) + IO (Decode16, 0x0067, 0x0067, 0x00, 0x09, ) + IO (Decode16, 0x0072, 0x0072, 0x00, 0x0E, ) + IO (Decode16, 0x0080, 0x0080, 0x00, 0x01, ) + IO (Decode16, 0x0084, 0x0084, 0x00, 0x03, ) + IO (Decode16, 0x0088, 0x0088, 0x00, 0x01, ) + IO (Decode16, 0x008c, 0x008c, 0x00, 0x03, ) + IO (Decode16, 0x0090, 0x0090, 0x00, 0x10, ) + IO (Decode16, 0x00a2, 0x00a2, 0x00, 0x1e, ) + IO (Decode16, 0x00b1, 0x00b1, 0x00, 0x01, ) + IO (Decode16, 0x00e0, 0x00e0, 0x00, 0x10, ) + /* ACPI */ + IO (Decode16, 0x0400, 0x0400, 0x00, 0xa0, ) + /* DMA */ + IO (Decode16, 0x040b, 0x040b, 0x00, 0x01, ) + /* INTR edge control */ + IO (Decode16, 0x04d0, 0x04d0, 0x00, 0x02, ) + /* DMA */ + IO (Decode16, 0x04d6, 0x04d6, 0x00, 0x01, ) + IO (Decode16, 0x0900, 0x0900, 0x00, 0x10, ) + IO (Decode16, 0x0910, 0x0910, 0x00, 0x10, ) + /* SMBUS */ + IO (Decode16, 0x0b00, 0x0b00, 0x00, 0x10, ) + /* SMBUS ASF */ + IO (Decode16, 0x0b20, 0x0b20, 0x00, 0x20, ) + /* PCI interrupt router */ + IO (Decode16, 0x0c00, 0x0c00, 0x00, 0x02, ) + /* PCI ERR */ + IO (Decode16, 0x0c14, 0x0c14, 0x00, 0x01, ) + IO (Decode16, 0x0c50, 0x0c50, 0x00, 0x02, ) + IO (Decode16, 0x0c52, 0x0c52, 0x00, 0x01, ) + IO (Decode16, 0x0c6c, 0x0c6c, 0x00, 0x01, ) + /* ISA MISC */ + IO (Decode16, 0x0c6f, 0x0c6f, 0x00, 0x01, ) + IO (Decode16, 0x0cd0, 0x0cd0, 0x00, 0x02, ) + /* PMIO2 */ + IO (Decode16, 0x0cd2, 0x0cd2, 0x00, 0x02, ) + /* BIOSRAM */ + IO (Decode16, 0x0cd4, 0x0cd4, 0x00, 0x02, ) + /* PMIO */ + IO (Decode16, 0x0cd6, 0x0cd6, 0x00, 0x02, ) + /* AB INDX */ + IO (Decode16, 0x0cd8, 0x0cd8, 0x00, 0x08, ) + /* ACPI PMA CNTL BLK */ + IO (Decode16, 0xfe00, 0xfe00, 0x00, 0xff, ) + Memory32Fixed (ReadWrite, 0xfee00000, 0x00001000, ) + /* Remainder of remote GPIO up to GPIO0 bank */ + Memory32Fixed (ReadWrite, 0xfed8122c, 0x000002d4, ) + /* ACPI MMIO above GPIO banks */ + Memory32Fixed (ReadWrite, 0xfed81a00, 0x0000e600, ) + /* Watchdog */ + Memory32Fixed (ReadWrite, 0xfeb00000, 0x00000010, ) + /* ROM */ + Memory32Fixed (ReadWrite, 0xff000000, 0x01000000, ) + }) +} diff --git a/src/soc/amd/turin_poc/acpi/soc.asl b/src/soc/amd/turin_poc/acpi/soc.asl index 75344dc325d..5d180247058 100644 --- a/src/soc/amd/turin_poc/acpi/soc.asl +++ b/src/soc/amd/turin_poc/acpi/soc.asl @@ -19,6 +19,15 @@ Scope(\_SB) { ROOT_BRIDGE(S0B1) ROOT_BRIDGE(S0B2) ROOT_BRIDGE(S0B3) + ROOT_BRIDGE(S0B4) + ROOT_BRIDGE(S0B5) + ROOT_BRIDGE(S0B6) + ROOT_BRIDGE(S0B7) + + Scope(S0B0) { + #include "resources.asl" + #include + } /* End S0B0 scope */ } /* End \_SB scope */ #include @@ -34,6 +43,4 @@ Scope(\_SB) { */ Method (PNOT) { - /* Report AC/DC state to ALIB using WAL1() */ - \WAL1 () } diff --git a/src/soc/amd/turin_poc/chip.c b/src/soc/amd/turin_poc/chip.c index 344617d52e5..ee5ad5e0a06 100644 --- a/src/soc/amd/turin_poc/chip.c +++ b/src/soc/amd/turin_poc/chip.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -10,6 +11,8 @@ static void soc_init(void *chip_info) { default_dev_ops_root.write_acpi_tables = soc_acpi_write_tables; + display_mtrrs(); + amd_opensil_silicon_init(); data_fabric_print_mmio_conf(); diff --git a/src/soc/amd/turin_poc/chip.h b/src/soc/amd/turin_poc/chip.h index f08f348f15f..1bfe6e6c920 100644 --- a/src/soc/amd/turin_poc/chip.h +++ b/src/soc/amd/turin_poc/chip.h @@ -9,6 +9,11 @@ #include #include +#define MAX_DOMAINS 8 + +static const unsigned int domain_to_rb_index[MAX_DOMAINS] = { 2, 7, 3, 6, 4, 1, 5, 0 }; +static const unsigned int domain_to_logical_rb[MAX_DOMAINS] = { 4, 5, 6, 7, 3, 2, 1, 0 }; + struct usb31_phy_settings { uint8_t rx_ana_iq_phase_adjust; uint8_t rx_eq_delta_iq_ovrd_en; @@ -30,33 +35,23 @@ struct soc_usb_config { struct { uint8_t port0 : 4; uint8_t port1 : 4; - uint8_t port2 : 4; - uint8_t port3 : 4; - uint8_t port4 : 4; - uint8_t port5 : 4; - uint8_t port6 : 4; - uint8_t port7 : 4; } usb2_oc_pins[2]; struct { uint8_t port0 : 4; uint8_t port1 : 4; - uint8_t port2 : 4; - uint8_t port3 : 4; } usb3_oc_pins[2]; bool polarity_cfg_low; union { struct { uint8_t port0 : 2; uint8_t port1 : 2; - uint8_t port2 : 2; /* Broken in OpenSIL */ - uint8_t port3 : 2; /* Broken in OpenSIL */ }; uint8_t raw; } usb3_force_gen1; bool usb31_phy_enable; - struct usb31_phy_settings usb31_phy[8]; + struct usb31_phy_settings usb31_phy[2]; bool s1_usb31_phy_enable; - struct usb31_phy_settings s1_usb31_phy[8]; + struct usb31_phy_settings s1_usb31_phy[2]; }; struct soc_amd_turin_poc_config { diff --git a/src/soc/amd/turin_poc/chipset.cb b/src/soc/amd/turin_poc/chipset.cb index 399d3530fcc..f8f48886588 100644 --- a/src/soc/amd/turin_poc/chipset.cb +++ b/src/soc/amd/turin_poc/chipset.cb @@ -4,14 +4,14 @@ chip soc/amd/turin_poc device cpu_cluster 0 on ops amd_cpu_bus_ops end # OC pins - register "usb.usb2_oc_pins[0]" = "{ 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf }" - register "usb.usb2_oc_pins[1]" = "{ 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf }" - register "usb.usb3_oc_pins[0]" = "{ 0xf, 0xf, 0xf, 0xf }" - register "usb.usb3_oc_pins[1]" = "{ 0xf, 0xf, 0xf, 0xf }" + register "usb.usb2_oc_pins[0]" = "{ 0xf, 0xf }" + register "usb.usb2_oc_pins[1]" = "{ 0xf, 0xf }" + register "usb.usb3_oc_pins[0]" = "{ 0xf, 0xf }" + register "usb.usb3_oc_pins[1]" = "{ 0xf, 0xf }" device domain 0 on ops turin_pci_domain_ops - device pci 00.0 alias gnb_0 on end + device pci 00.0 alias gnb_0 on ops turin_root_complex_operations end device pci 00.2 alias iommu_0 off ops amd_iommu_ops end device pci 00.3 alias rcec_0 off end @@ -47,69 +47,19 @@ chip soc/amd/turin_poc end device pci 03.0 on end # Dummy device function, do not disable - chip drivers/amd/opensil/mpio - device pci 03.1 alias gpp_bridge_0_0_b off end - end - chip drivers/amd/opensil/mpio - device pci 03.2 alias gpp_bridge_0_1_b off end - end - chip drivers/amd/opensil/mpio - device pci 03.3 alias gpp_bridge_0_2_b off end - end - chip drivers/amd/opensil/mpio - device pci 03.4 alias gpp_bridge_0_3_b off end - end - chip drivers/amd/opensil/mpio - device pci 03.5 alias gpp_bridge_0_4_b off end - end - chip drivers/amd/opensil/mpio - device pci 03.6 alias gpp_bridge_0_5_b off end - end - chip drivers/amd/opensil/mpio - device pci 03.7 alias gpp_bridge_0_6_b off end - end - device pci 04.0 on end # Dummy device function, do not disable - chip drivers/amd/opensil/mpio - device pci 04.1 alias gpp_bridge_0_7_b off end - end - chip drivers/amd/opensil/mpio - device pci 04.2 alias gpp_bridge_0_8_b off end - end - device pci 05.0 on end # Dummy device function, do not disable - chip drivers/amd/opensil/mpio - device pci 05.1 alias gpp_bridge_0_0_c off end - end - chip drivers/amd/opensil/mpio - device pci 05.2 alias gpp_bridge_0_1_c off end - end - chip drivers/amd/opensil/mpio - device pci 05.3 alias gpp_bridge_0_2_c off end - end - chip drivers/amd/opensil/mpio - device pci 05.4 alias gpp_bridge_0_3_c off end - end device pci 07.0 on end # Dummy device function, do not disable - device pci 07.1 alias gpp_bridge_0_a off # Internal GPP Bridge 0 to Bus B0 - device pci 0.0 on end # Dummy PCIe function - device pci 0.1 off end - device pci 0.2 alias primary_NTB_0 off end # Primary PCIe Non-TransparentBridge - device pci 0.3 alias secondry_NTB_0 off end # Secondary vNTB - device pci 0.4 alias xhci_0 off end # USB - device pci 0.5 alias mp0_0 off end # PSP (MP0) - device pci 0.6 alias acp_0 off end # Audio Processor (ACP) - device pci 0.7 alias hda_0 off end # Audio Processor HD Audio Controller (main AZ) - end - device pci 07.2 alias gpp_bridge_0_b off # Internal GPP Bridge 1 to Bus C0 - device pci 0.0 alias sata_0_0 off end # first SATA controller; AHCI mode - device pci 0.1 alias sata_0_1 off end # second SATA controller; AHCI mode + device pci 07.1 alias gpp_bridge_0_a on # Internal GPP Bridge 0 to Bus C0 + device pci 00.0 alias nbif_0 on end # Dummy PCIe function + device pci 00.1 alias sdxi_1 on end # Smart Data Accelerator Interface + device pci 00.2 alias primary_NTB_1 off end # Primary PCIe Non-TransparentBridge + device pci 00.3 alias secondry_NTB_1 off end # Secondary vNTB end device pci 14.0 alias smbus on end # primary FCH function device pci 14.3 alias lpc_bridge on ops amd_lpc_ops end - device pci 14.6 alias sdhci off end device pci 18.0 alias data_fabric_0 on end device pci 18.1 alias data_fabric_1 on end @@ -123,8 +73,7 @@ chip soc/amd/turin_poc device domain 1 on ops turin_pci_domain_ops - device pci 00.0 alias gnb_1 on end - device pci 00.2 alias iommu_1 off ops amd_iommu_ops end + device pci 00.0 alias gnb_1 on ops turin_root_complex_operations end device pci 00.3 alias rcec_1 off end device pci 01.0 on end # Dummy device function, do not disable @@ -157,224 +106,321 @@ chip soc/amd/turin_poc chip drivers/amd/opensil/mpio device pci 02.2 alias gpp_bridge_1_8_a off end end + end - device pci 03.0 on end # Dummy device function, do not disable + device domain 2 on + ops turin_pci_domain_ops + device pci 00.0 alias gnb_2 on ops turin_root_complex_operations end + device pci 00.2 alias iommu_2 off ops amd_iommu_ops end + + device pci 01.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 03.1 alias gpp_bridge_1_0_b off end + device pci 01.1 alias gpp_bridge_2_0_a off end end chip drivers/amd/opensil/mpio - device pci 03.2 alias gpp_bridge_1_1_b off end + device pci 01.2 alias gpp_bridge_2_1_a off end end chip drivers/amd/opensil/mpio - device pci 03.3 alias gpp_bridge_1_2_b off end + device pci 01.3 alias gpp_bridge_2_2_a off end end chip drivers/amd/opensil/mpio - device pci 03.4 alias gpp_bridge_1_3_b off end + device pci 01.4 alias gpp_bridge_2_3_a off end end chip drivers/amd/opensil/mpio - device pci 03.5 alias gpp_bridge_1_4_b off end + device pci 01.5 alias gpp_bridge_2_4_a off end end chip drivers/amd/opensil/mpio - device pci 03.6 alias gpp_bridge_1_5_b off end + device pci 01.6 alias gpp_bridge_2_5_a off end end chip drivers/amd/opensil/mpio - device pci 03.7 alias gpp_bridge_1_6_b off end + device pci 01.7 alias gpp_bridge_2_6_a off end end - device pci 04.0 on end # Dummy device function, do not disable + device pci 02.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 04.1 alias gpp_bridge_1_7_b off end + device pci 02.1 alias gpp_bridge_2_7_a off end end chip drivers/amd/opensil/mpio - device pci 04.2 alias gpp_bridge_1_8_b off end + device pci 02.2 alias gpp_bridge_2_8_a off end end + device pci 03.0 on end # Dummy device function, do not disable + device pci 04.0 on end # Dummy device function, do not disable + device pci 05.0 on end # Dummy device function, do not disable + chip drivers/amd/opensil/mpio + device pci 05.1 alias gpp_bridge_2_0_c off end + end + chip drivers/amd/opensil/mpio + device pci 05.2 alias gpp_bridge_2_1_c off end + end + chip drivers/amd/opensil/mpio + device pci 05.3 alias gpp_bridge_2_2_c off end + end device pci 07.0 on end # Dummy device function, do not disable - device pci 07.1 alias gpp_bridge_1_a off - device pci 0.0 on end # Dummy PCIe function - device pci 0.1 off end #SDXI - device pci 0.2 alias primary_NTB_1 off end # Primary PCIe Non-TransparentBridge - device pci 0.3 alias secondry_NTB_1 off end # Secondary vNTB + device pci 07.1 alias gpp_bridge_2_a on # Internal GPP Bridge 0 to Bus C1 + device pci 00.0 alias nbif_2 on end # Dummy PCIe function + device pci 00.1 alias sdxi_2 on end # Smart Data Accelerator Interface + device pci 00.3 alias secondry_NTB_2 off end # Secondary vNTB + device pci 00.4 alias xhci_0 off end # USB + device pci 00.7 alias hda off end # HD Audio Controller (AZ) + end + device pci 07.2 alias gpp_bridge_2_b on # Internal GPP Bridge 0 to Bus D1 + device pci 00.0 alias sata_2_0 off end # first SATA controller; AHCI mode + device pci 00.1 alias sata_2_1 off end # second SATA controller; AHCI mode end end - device domain 2 on + device domain 3 on ops turin_pci_domain_ops - device pci 00.0 alias gnb_2 on end - device pci 00.2 alias iommu_2 off ops amd_iommu_ops end - device pci 00.3 alias rcec_2 off end + device pci 00.0 alias gnb_3 on ops turin_root_complex_operations end device pci 01.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 01.1 alias gpp_bridge_2_0_a off end + device pci 01.1 alias gpp_bridge_3_0_a off end end chip drivers/amd/opensil/mpio - device pci 01.2 alias gpp_bridge_2_1_a off end + device pci 01.2 alias gpp_bridge_3_1_a off end end chip drivers/amd/opensil/mpio - device pci 01.3 alias gpp_bridge_2_2_a off end + device pci 01.3 alias gpp_bridge_3_2_a off end end chip drivers/amd/opensil/mpio - device pci 01.4 alias gpp_bridge_2_3_a off end + device pci 01.4 alias gpp_bridge_3_3_a off end end chip drivers/amd/opensil/mpio - device pci 01.5 alias gpp_bridge_2_4_a off end + device pci 01.5 alias gpp_bridge_3_4_a off end end chip drivers/amd/opensil/mpio - device pci 01.6 alias gpp_bridge_2_5_a off end + device pci 01.6 alias gpp_bridge_3_5_a off end end chip drivers/amd/opensil/mpio - device pci 01.7 alias gpp_bridge_2_6_a off end + device pci 01.7 alias gpp_bridge_3_6_a off end end device pci 02.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 02.1 alias gpp_bridge_2_7_a off end + device pci 02.1 alias gpp_bridge_3_7_a off end end chip drivers/amd/opensil/mpio - device pci 02.2 alias gpp_bridge_2_8_a off end + device pci 02.2 alias gpp_bridge_3_8_a off end end + end - device pci 03.0 on end # Dummy device function, do not disable + device domain 4 on + ops turin_pci_domain_ops + device pci 00.0 alias gnb_4 on ops turin_root_complex_operations end + + device pci 01.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 03.1 alias gpp_bridge_2_0_b off end + device pci 01.1 alias gpp_bridge_4_0_a off end end chip drivers/amd/opensil/mpio - device pci 03.2 alias gpp_bridge_2_1_b off end + device pci 01.2 alias gpp_bridge_4_1_a off end end chip drivers/amd/opensil/mpio - device pci 03.3 alias gpp_bridge_2_2_b off end + device pci 01.3 alias gpp_bridge_4_2_a off end end chip drivers/amd/opensil/mpio - device pci 03.4 alias gpp_bridge_2_3_b off end + device pci 01.4 alias gpp_bridge_4_3_a off end end chip drivers/amd/opensil/mpio - device pci 03.5 alias gpp_bridge_2_4_b off end + device pci 01.5 alias gpp_bridge_4_4_a off end end chip drivers/amd/opensil/mpio - device pci 03.6 alias gpp_bridge_2_5_b off end + device pci 01.6 alias gpp_bridge_4_5_a off end end chip drivers/amd/opensil/mpio - device pci 03.7 alias gpp_bridge_2_6_b off end + device pci 01.7 alias gpp_bridge_4_6_a off end end - device pci 04.0 on end # Dummy device function, do not disable + device pci 02.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 04.1 alias gpp_bridge_2_7_b off end + device pci 02.1 alias gpp_bridge_4_7_a off end end chip drivers/amd/opensil/mpio - device pci 04.2 alias gpp_bridge_2_8_b off end - end - - device pci 05.0 on end # Dummy device function, do not disable - - device pci 07.0 on end # Dummy device function, do not disable - device pci 07.1 alias gpp_bridge_2_a off - device pci 0.0 on end # Dummy PCIe function - device pci 0.1 off end - device pci 0.2 alias primary_NTB_2 off end # Primary PCIe Non-TransparentBridge - device pci 0.3 alias secondry_NTB_2 off end # Secondary vNTB + device pci 02.2 alias gpp_bridge_4_8_a off end end end - device domain 3 on + device domain 5 on ops turin_pci_domain_ops - device pci 00.0 alias gnb_3 on end - device pci 00.2 alias iommu_3 off ops amd_iommu_ops end - device pci 00.3 alias rcec_3 off end + device pci 00.0 alias gnb_5 on ops turin_root_complex_operations end + device pci 00.2 alias iommu_5 off ops amd_iommu_ops end device pci 01.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 01.1 alias gpp_bridge_3_0_a off end + device pci 01.1 alias gpp_bridge_5_0_a off end end chip drivers/amd/opensil/mpio - device pci 01.2 alias gpp_bridge_3_1_a off end + device pci 01.2 alias gpp_bridge_5_1_a off end end chip drivers/amd/opensil/mpio - device pci 01.3 alias gpp_bridge_3_2_a off end + device pci 01.3 alias gpp_bridge_5_2_a off end end chip drivers/amd/opensil/mpio - device pci 01.4 alias gpp_bridge_3_3_a off end + device pci 01.4 alias gpp_bridge_5_3_a off end end chip drivers/amd/opensil/mpio - device pci 01.5 alias gpp_bridge_3_4_a off end + device pci 01.5 alias gpp_bridge_5_4_a off end end chip drivers/amd/opensil/mpio - device pci 01.6 alias gpp_bridge_3_5_a off end + device pci 01.6 alias gpp_bridge_5_5_a off end end chip drivers/amd/opensil/mpio - device pci 01.7 alias gpp_bridge_3_6_a off end + device pci 01.7 alias gpp_bridge_5_6_a off end end device pci 02.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 02.1 alias gpp_bridge_3_7_a off end + device pci 02.1 alias gpp_bridge_5_7_a off end end chip drivers/amd/opensil/mpio - device pci 02.2 alias gpp_bridge_3_8_a off end + device pci 02.2 alias gpp_bridge_5_8_a off end end device pci 03.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 03.1 alias gpp_bridge_3_0_b off end + device pci 03.1 alias gpp_bridge_5_0_b off end end chip drivers/amd/opensil/mpio - device pci 03.2 alias gpp_bridge_3_1_b off end + device pci 03.2 alias gpp_bridge_5_1_b off end end chip drivers/amd/opensil/mpio - device pci 03.3 alias gpp_bridge_3_2_b off end + device pci 03.3 alias gpp_bridge_5_2_b off end end chip drivers/amd/opensil/mpio - device pci 03.4 alias gpp_bridge_3_3_b off end + device pci 03.4 alias gpp_bridge_5_3_b off end end chip drivers/amd/opensil/mpio - device pci 03.5 alias gpp_bridge_3_4_b off end + device pci 03.5 alias gpp_bridge_5_4_b off end end chip drivers/amd/opensil/mpio - device pci 03.6 alias gpp_bridge_3_5_b off end + device pci 03.6 alias gpp_bridge_5_5_b off end end chip drivers/amd/opensil/mpio - device pci 03.7 alias gpp_bridge_3_6_b off end + device pci 03.7 alias gpp_bridge_5_6_b off end end device pci 04.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 04.1 alias gpp_bridge_3_7_b off end + device pci 04.1 alias gpp_bridge_5_7_b off end + end + + device pci 05.0 on end # Dummy device function, do not disable + chip drivers/amd/opensil/mpio + device pci 05.1 alias gpp_bridge_5_0_c off end + end + chip drivers/amd/opensil/mpio + device pci 05.2 alias gpp_bridge_5_1_c off end end chip drivers/amd/opensil/mpio - device pci 04.2 alias gpp_bridge_3_8_b off end + device pci 05.3 alias gpp_bridge_5_2_c off end end - device pci 05.0 on end # Dummy device function, do not disable + device pci 07.0 on end # Dummy device function, do not disable + device pci 07.1 alias gpp_bridge_3_a on # Internal GPP Bridge 0 to Bus C2 + device pci 00.0 alias nbif_3 on end # Dummy PCIe function + device pci 00.1 alias sdxi_3 on end # Smart Data Accelerator Interface + device pci 00.2 alias primary_NTB_3 off end # Primary PCIe Non-TransparentBridge + device pci 00.3 alias secondry_NTB_3 off end # Secondary vNTB + device pci 00.5 alias asp off end # PSP (MP0) + end + end + + device domain 6 on + ops turin_pci_domain_ops + device pci 00.0 alias gnb_6 on ops turin_root_complex_operations end + device pci 00.3 alias rcec_6 off end + + device pci 01.0 on end # Dummy device function, do not disable + chip drivers/amd/opensil/mpio + device pci 01.1 alias gpp_bridge_6_0_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.2 alias gpp_bridge_6_1_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.3 alias gpp_bridge_6_2_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.4 alias gpp_bridge_6_3_a off end + end chip drivers/amd/opensil/mpio - device pci 05.1 alias gpp_bridge_3_0_c off end + device pci 01.5 alias gpp_bridge_6_4_a off end end chip drivers/amd/opensil/mpio - device pci 05.2 alias gpp_bridge_3_1_c off end + device pci 01.6 alias gpp_bridge_6_5_a off end end chip drivers/amd/opensil/mpio - device pci 05.3 alias gpp_bridge_3_2_c off end + device pci 01.7 alias gpp_bridge_6_6_a off end end + + device pci 02.0 on end # Dummy device function, do not disable chip drivers/amd/opensil/mpio - device pci 05.4 alias gpp_bridge_3_3_c off end + device pci 02.1 alias gpp_bridge_6_7_a off end end + chip drivers/amd/opensil/mpio + device pci 02.2 alias gpp_bridge_6_8_a off end + end + end + + device domain 7 on + ops turin_pci_domain_ops + device pci 00.0 alias gnb_7 on ops turin_root_complex_operations end + device pci 00.2 alias iommu_7 off ops amd_iommu_ops end + device pci 00.3 alias rcec_7 off end + + device pci 01.0 on end # Dummy device function, do not disable + chip drivers/amd/opensil/mpio + device pci 01.1 alias gpp_bridge_7_0_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.2 alias gpp_bridge_7_1_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.3 alias gpp_bridge_7_2_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.4 alias gpp_bridge_7_3_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.5 alias gpp_bridge_7_4_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.6 alias gpp_bridge_7_5_a off end + end + chip drivers/amd/opensil/mpio + device pci 01.7 alias gpp_bridge_7_6_a off end + end + + device pci 02.0 on end # Dummy device function, do not disable + chip drivers/amd/opensil/mpio + device pci 02.1 alias gpp_bridge_7_7_a off end + end + chip drivers/amd/opensil/mpio + device pci 02.2 alias gpp_bridge_7_8_a off end + end + + device pci 03.0 on end # Dummy device function, do not disable + device pci 04.0 on end # Dummy device function, do not disable + device pci 05.0 on end # Dummy device function, do not disable device pci 07.0 on end # Dummy device function, do not disable - device pci 07.1 alias gpp_bridge_3_a off - device pci 0.0 on end # Dummy PCIe function - device pci 0.1 off end #SDXI - device pci 0.2 alias primary_NTB_3 off end # Primary PCIe Non-TransparentBridge - device pci 0.3 alias secondry_NTB_3 off end # Secondary vNTB - device pci 0.4 alias xhci_3 off end # USB - device pci 0.5 alias mp0_3 off end # PSP (MP0) + device pci 07.1 alias gpp_bridge_7_a on # Internal GPP Bridge 0 to Bus C3 + device pci 00.0 alias nbif_4 on end # Dummy PCIe function + device pci 00.1 alias sdxi_4 on end # Smart Data Accelerator Interface + device pci 00.2 alias primary_NTB_4 off end # Primary PCIe Non-TransparentBridge + device pci 00.3 alias secondry_NTB_4 off end # Secondary vNTB + device pci 00.4 alias xhci_1 off end # USB end - device pci 07.2 alias gpp_bridge_3_b off - device pci 0.0 alias sata_3_0 off end # first SATA controller; AHCI mode - device pci 0.1 alias sata_3_1 off end # second SATA controller; AHCI mode + device pci 07.2 alias gpp_bridge_7_b on # Internal GPP Bridge 0 to Bus D3 + device pci 00.0 alias sata_7_0 off end # first SATA controller; AHCI mode + device pci 00.1 alias sata_7_1 off end # second SATA controller; AHCI mode end + end device mmio 0xfedc2000 alias i2c_0 off ops soc_amd_i2c_mmio_ops end diff --git a/src/soc/amd/turin_poc/cpu.c b/src/soc/amd/turin_poc/cpu.c index aedd0ac6cf4..fc1ad627eb5 100644 --- a/src/soc/amd/turin_poc/cpu.c +++ b/src/soc/amd/turin_poc/cpu.c @@ -10,8 +10,9 @@ static struct device_operations cpu_dev_ops = { }; static struct cpu_device_id cpu_table[] = { - { X86_VENDOR_AMD, TURIN_A0_CPUID, CPUID_ALL_STEPPINGS_MASK }, - { X86_VENDOR_AMD, TURIN_B0_CPUID, CPUID_ALL_STEPPINGS_MASK }, + { X86_VENDOR_AMD, TURIN_Ax_CPUID, CPUID_ALL_STEPPINGS_MASK }, + { X86_VENDOR_AMD, TURIN_Bx_CPUID, CPUID_ALL_STEPPINGS_MASK }, + { X86_VENDOR_AMD, TURIN_Cx_CPUID, CPUID_ALL_STEPPINGS_MASK }, CPU_TABLE_END }; diff --git a/src/soc/amd/turin_poc/domain.c b/src/soc/amd/turin_poc/domain.c index 40177d7dcc9..6991fdc5270 100644 --- a/src/soc/amd/turin_poc/domain.c +++ b/src/soc/amd/turin_poc/domain.c @@ -1,23 +1,56 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include +#include #include #include #include #include #include +#include #include #include +#include #include #define IOHC_IOAPIC_BASE_ADDR_LO 0x2f0 +/* + * 12GiB of DF reserved space at the top of physical address space. The + * address is not fixed and depends on SME state, because it can reduce the + * available physical address space. + */ +#define DATA_FABRIC_RESERVED_BASE \ + (POWER_OF_2(cpu_phys_address_size()) - DF_RESERVED_TOP_12GB_MMIO_SIZE) +#define DATA_FABRIC_RESERVED_SIZE DF_RESERVED_TOP_12GB_MMIO_SIZE + +/* + * 64KiB of ACPI EINJ buffer, reserve it. Reads return FFs and cause errors in + * memtest86 if not reserved, and needless to say, crashes in operating + * systems too. + */ +#define ACPI_EINJ_RESERVED_BASE (4ull * GiB) +#define ACPI_EINJ_RESERVED_SIZE (64 * KiB) + void read_soc_memmap_resources(struct device *domain, unsigned long *idx) { read_lower_soc_memmap_resources(domain, idx); + if (is_domain0(domain)) { + reserved_ram_range(domain, (*idx)++, ACPI_EINJ_RESERVED_BASE, + ACPI_EINJ_RESERVED_SIZE); + + mmio_range(domain, (*idx)++, IOMMU_RESERVED_MMIO_BASE, 12ULL * GiB); + mmio_range(domain, (*idx)++, DATA_FABRIC_RESERVED_BASE, + DATA_FABRIC_RESERVED_SIZE); + + mmio_range(domain, (*idx)++, AMD_SB_ACPI_MMIO_ADDR, 0x2000); + mmio_range(domain, (*idx)++, ALINK_AHB_ADDRESS, 0x20000); + } + amd_opensil_add_memmap(domain, idx); } @@ -48,11 +81,15 @@ static void turin_domain_set_resources(struct device *domain) static const char *turin_domain_acpi_name(const struct device *domain) { const unsigned int domain_id = dev_get_domain_id(domain); - const char *domain_acpi_names[4] = { + const char *domain_acpi_names[8] = { "S0B0", "S0B1", "S0B2", "S0B3", + "S0B4", + "S0B5", + "S0B6", + "S0B7", }; if (domain_id < ARRAY_SIZE(domain_acpi_names)) diff --git a/src/soc/amd/turin_poc/early_fch.c b/src/soc/amd/turin_poc/early_fch.c index d82ebcbcf83..5bcbca0834d 100644 --- a/src/soc/amd/turin_poc/early_fch.c +++ b/src/soc/amd/turin_poc/early_fch.c @@ -1,19 +1,73 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#define __SIMPLE_DEVICE__ + #include #include #include #include +#include #include +#include +#include +#include #include +#include #include #include +#include + +#define SMN_D18F0_BASE 0x49000000 + +static void df_set_pci_mmconf(void) +{ + uint32_t reg; + uint64_t mmconf_base = CONFIG_ECAM_MMCONF_BASE_ADDRESS; + uint64_t mmconf_limit = mmconf_base + CONFIG_ECAM_MMCONF_LENGTH; + + mmconf_limit--; + mmconf_limit &= 0xfff00000; /* Address bits [19:0] are fixed to be FFFFF */ + mmconf_base |= 1; /* Range enable */ + + /* + * We have to use I/O PCI access to SMN index/data, because MMCONF + * will not work with our MMCONF address until this function returns. + */ + reg = smn_io_read32(SMN_D18F0_BASE + 0xc10); + reg &= ~1; /* Disable MMCONF range first */ + smn_io_write32(SMN_D18F0_BASE + 0xc10, reg); + + /* Now repeat the order in which ABL configured the MMCONF */ + reg = mmconf_limit >> 32; + smn_io_write32(SMN_D18F0_BASE + 0xc1c, reg); + reg = mmconf_limit & 0xffffffff; + smn_io_write32(SMN_D18F0_BASE + 0xc18, reg); + reg = mmconf_base >> 32; + smn_io_write32(SMN_D18F0_BASE + 0xc14, reg); + reg = mmconf_base & 0xffffffff; + smn_io_write32(SMN_D18F0_BASE + 0xc10, reg); +} /* Before console init */ void fch_pre_init(void) { + /* + * Before we can proceed with any initialization that touches PCI, we + * have to ensure our PCI MMCONF base matches the register in DF. + */ + df_set_pci_mmconf(); + /* + * Enable_acpimmio_decode_pm04 to enable the ACPIMMIO decode which is + * needed to access the GPIO registers. + */ + enable_acpimmio_decode_pm04(); + /* Setup SPI base by calling lpc_early_init before setting up eSPI. */ + lpc_early_init(); + fch_spi_early_init(); + fch_smbus_init(); fch_enable_cf9_io(); - + fch_enable_legacy_io(); + fch_disable_legacy_dma_io(); enable_aoac_devices(); /* * On reset Range_0 defaults to enabled. We want to start with a clean @@ -24,10 +78,29 @@ void fch_pre_init(void) if (CONFIG(AMD_SOC_CONSOLE_UART)) set_uart_config(CONFIG_UART_FOR_CONSOLE); - configure_espi_with_mb_hook(); + /* disable the keyboard reset function before mainboard GPIO setup */ + if (CONFIG(DISABLE_KEYBOARD_RESET_PIN)) + fch_disable_kb_rst(); + + /* + * Skip eSPI configuration. The EFS/PSP DIR already contains eSPI configuration + * so x86 does not need to configure it. Running configure_espi_with_mb_hook + * and resetting eSPI causes the slave/AST2600 to stop printing output on serial + * port. Boards may still configure I/O decodes early, if needed. + * + * configure_espi_with_mb_hook(); + */ } /* After console init */ void fch_early_init(void) { + reset_i2c_peripherals(); + pm_set_power_failure_state(); + fch_print_pmxc0_status(); + i2c_soc_early_init(); + show_spi_speeds_and_modes(); + + if (CONFIG(DISABLE_SPI_FLASH_ROM_SHARING)) + lpc_disable_spi_rom_sharing(); } diff --git a/src/soc/amd/turin_poc/fch.c b/src/soc/amd/turin_poc/fch.c index 46f97db8ea6..a55abf2718e 100644 --- a/src/soc/amd/turin_poc/fch.c +++ b/src/soc/amd/turin_poc/fch.c @@ -37,8 +37,23 @@ static const struct irq_idx_name irq_association[] = { { PIRQ_SCI, "SCI" }, { PIRQ_SMBUS, "SMBUS" }, { PIRQ_ASF, "ASF" }, + { PIRQ_HDA, "HDA" }, + { PIRQ_GBE0, "GBE0" }, + { PIRQ_GBE1, "GBE1" }, { PIRQ_PMON, "PerMon" }, + { PIRQ_SD, "SD" }, { PIRQ_SDIO, "SDIO" }, + { PIRQ_CIR, "CIR" }, + { PIRQ_GPIOA, "GPIOa" }, + { PIRQ_GPIOB, "GPIOb" }, + { PIRQ_GPIOC, "GPIOc" }, + { PIRQ_USB_EMU, "USB_EMU" }, + { PIRQ_USB_DR0, "USB_DR0" }, + { PIRQ_USB_DR1, "USB_DR1" }, + { PIRQ_XHCI0, "XHCI0" }, + { PIRQ_SSIC, "USB_SSIC" }, + { PIRQ_SATA, "SATA" }, + { PIRQ_UFS, "UFS" }, { PIRQ_GPP0, "GPP0" }, { PIRQ_GPP1, "GPP1" }, { PIRQ_GPP2, "GPP2" }, @@ -64,23 +79,62 @@ const struct irq_idx_name *sb_get_apic_reg_association(size_t *size) return irq_association; } -static void set_pci_irqs(void) +static void fch_init_acpi_ports(void) { - /* Write PCI_INTR regs 0xC00/0xC01 */ - write_pci_int_table(); + uint32_t reg32; + uint8_t reg8; + + if (CONFIG(HAVE_SMI_HANDLER)) { + /* Configure and enable APMC SMI Command Port */ + pm_write16(PM_ACPI_SMI_CMD, APM_CNT); + configure_smi(SMITYPE_SMI_CMD_PORT, SMI_MODE_SMI); - /* TODO: PIRQ configuration */ + /* SMI on SlpTyp requires sending SMI before completion + response of the I/O write. */ + reg32 = pm_read32(PM_PCI_CTRL); + reg32 |= FORCE_SLPSTATE_RETRY; + /* Ths bit should be cleared in case of SlpType SMI trapping */ + reg32 &= ~FORCE_STPCLK_RETRY; + pm_write32(PM_PCI_CTRL, reg32); + + /* Disable SlpTyp feature */ + reg8 = pm_read8(PM_RST_CTRL1); + reg8 &= ~SLPTYPE_CONTROL_EN; + pm_write8(PM_RST_CTRL1, reg8); + + configure_smi(SMITYPE_SLP_TYP, SMI_MODE_SMI); + } else { + pm_write16(PM_ACPI_SMI_CMD, 0); + } + + /* Decode ACPI registers and enable standard features */ + pm_write8(PM_ACPI_CONF, PM_ACPI_DECODE_STD | + PM_ACPI_GLOBAL_EN | + PM_ACPI_RTC_EN_EN | + PM_ACPI_TIMER_EN_EN); } -static void fch_init_acpi_ports(void) +static void fch_clk_output_48Mhz(void) { - /* Configure and enable APMC SMI Command Port */ - pm_write16(PM_ACPI_SMI_CMD, APM_CNT); - configure_smi(SMITYPE_SMI_CMD_PORT, SMI_MODE_SMI); + uint32_t ctrl = misc_read32(MISC_CLK_CNTL0); + /* Enable BP_X48M0 Clock Output */ + ctrl |= BP_X48M0_OUTPUT_EN; + misc_write32(MISC_CLK_CNTL0, ctrl); +} + +static void fch_pci_int_vw_mode(void) +{ + pm_write32(0xa8, 0x80ffcef8); } void fch_init(void *chip_info) { - set_pci_irqs(); fch_init_acpi_ports(); + fch_clk_output_48Mhz(); + + /* Write PCI_INTR regs 0xC00/0xC01 */ + write_pci_int_table(); + fch_pci_int_vw_mode(); + + fch_enable_ioapic_decode(); } diff --git a/src/soc/amd/turin_poc/gpio.c b/src/soc/amd/turin_poc/gpio.c index c38719bf3f5..72d0b2b0a49 100644 --- a/src/soc/amd/turin_poc/gpio.c +++ b/src/soc/amd/turin_poc/gpio.c @@ -20,6 +20,7 @@ static const struct soc_amd_event gpio_event_table[] = { { GPIO_23, GEVENT_16 }, { GPIO_24, GEVENT_14 }, { GPIO_26, GEVENT_15 }, + { GPIO_28, GEVENT_18 }, { GPIO_76, GEVENT_11 }, { GPIO_86, GEVENT_9 }, { GPIO_89, GEVENT_0 }, diff --git a/src/soc/amd/turin_poc/i3c.c b/src/soc/amd/turin_poc/i3c.c index e6946231773..0e041942b64 100644 --- a/src/soc/amd/turin_poc/i3c.c +++ b/src/soc/amd/turin_poc/i3c.c @@ -1,14 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include static const struct soc_i3c_ctrlr_info i3c_ctrlr[I3C_CTRLR_COUNT] = { - { APU_I3C0_BASE, "I3C0" }, - { APU_I3C1_BASE, "I3C1" }, - { APU_I3C2_BASE, "I3C2" }, - { APU_I3C3_BASE, "I3C3" } + { APU_I3C0_BASE, "I3C0", FCH_AOAC_DEV_I3C0}, + { APU_I3C1_BASE, "I3C1", FCH_AOAC_DEV_I3C1}, + { APU_I3C2_BASE, "I3C2", FCH_AOAC_DEV_I3C2}, + { APU_I3C3_BASE, "I3C3", FCH_AOAC_DEV_I3C3} }; const struct soc_i3c_ctrlr_info *soc_get_i3c_ctrlr_info(size_t *num_ctrlrs) diff --git a/src/soc/amd/turin_poc/include/soc/amd_pci_int_defs.h b/src/soc/amd/turin_poc/include/soc/amd_pci_int_defs.h index f093247735e..82915109a72 100644 --- a/src/soc/amd/turin_poc/include/soc/amd_pci_int_defs.h +++ b/src/soc/amd/turin_poc/include/soc/amd_pci_int_defs.h @@ -28,11 +28,29 @@ #define PIRQ_SCI 0x10 /* SCI IRQ */ #define PIRQ_SMBUS 0x11 /* SMBUS0 */ #define PIRQ_ASF 0x12 /* ASF */ -/* 0x13-0x15 reserved */ +#define PIRQ_HDA 0x13 /* HDA */ +#define PIRQ_GBE0 0x14 /* GBE0 */ +#define PIRQ_GBE1 0x15 /* GBE1 */ #define PIRQ_PMON 0x16 /* Performance Monitor */ -/* 0x17-0x19 reserved */ +#define PIRQ_SD 0x17 /* SD */ +/* 0x18-0x19 reserved */ #define PIRQ_SDIO 0x1a /* SDIO */ -/* 0x1b-0x49 reserved */ +/* 0x1b-0x1f reserved */ +#define PIRQ_CIR 0x20 /* CIR */ +#define PIRQ_GPIOA 0x21 /* GPIOa */ +#define PIRQ_GPIOB 0x22 /* GPIOb */ +#define PIRQ_GPIOC 0x23 /* GPIOc */ +/* 0x24-0x2f reserved */ +#define PIRQ_USB_EMU 0x30 /* USB Emulation */ +#define PIRQ_USB_DR0 0x31 /* USB Dual Role 1 */ +#define PIRQ_USB_DR1 0x32 /* USB Dual Role 2 */ +/* 0x33 reserved */ +#define PIRQ_XHCI0 0x34 /* XHCI0 */ +#define PIRQ_SSIC 0x35 /* USB SSIC */ +/* 0x36-0x40 reserved */ +#define PIRQ_SATA 0x41 /* SATA */ +#define PIRQ_UFS 0x42 /* UFS */ +/* 0x43-0x4f reserved */ #define PIRQ_GPP0 0x50 /* GPPInt0 */ #define PIRQ_GPP1 0x51 /* GPPInt1 */ #define PIRQ_GPP2 0x52 /* GPPInt2 */ diff --git a/src/soc/amd/turin_poc/include/soc/aoac_defs.h b/src/soc/amd/turin_poc/include/soc/aoac_defs.h index 156ee349620..2ee168ca594 100644 --- a/src/soc/amd/turin_poc/include/soc/aoac_defs.h +++ b/src/soc/amd/turin_poc/include/soc/aoac_defs.h @@ -18,7 +18,13 @@ #define FCH_AOAC_DEV_I3C3 15 #define FCH_AOAC_DEV_UART2 16 #define FCH_AOAC_DEV_AMBA 17 +/* Bits 18-19 reserved */ +#define FCH_AOAC_DEV_UART4 20 #define FCH_AOAC_DEV_I3C0 21 -#define FCH_AOAC_DEV_ESPI 27 +#define FCH_AOAC_DEV_ESPI1 22 +/* Bits 23-25 reserved */ +#define FCH_AOAC_DEV_UART3 26 +#define FCH_AOAC_DEV_ESPI 27 /* RO */ +#define FCH_AOAC_DEV_CPU 31 #endif /* AMD_TURIN_POC_AOAC_DEFS_H */ diff --git a/src/soc/amd/turin_poc/include/soc/cpu.h b/src/soc/amd/turin_poc/include/soc/cpu.h index eada9233faf..618ecf81d6b 100644 --- a/src/soc/amd/turin_poc/include/soc/cpu.h +++ b/src/soc/amd/turin_poc/include/soc/cpu.h @@ -3,7 +3,8 @@ #ifndef AMD_TURIN_POC_CPU_H #define AMD_TURIN_POC_CPU_H -#define TURIN_A0_CPUID CPUID_FROM_FMS(0x19, 0x10, 0) -#define TURIN_B0_CPUID CPUID_FROM_FMS(0x19, 0x11, 0) +#define TURIN_Ax_CPUID CPUID_FROM_FMS(0x1a, 0x0, 0) +#define TURIN_Bx_CPUID CPUID_FROM_FMS(0x1a, 0x1, 0) +#define TURIN_Cx_CPUID CPUID_FROM_FMS(0x1a, 0x2, 0) #endif /* AMD_TURIN_POC_CPU_H */ diff --git a/src/soc/amd/turin_poc/include/soc/data_fabric.h b/src/soc/amd/turin_poc/include/soc/data_fabric.h index 503dc39afb1..590ada3660e 100644 --- a/src/soc/amd/turin_poc/include/soc/data_fabric.h +++ b/src/soc/amd/turin_poc/include/soc/data_fabric.h @@ -23,7 +23,7 @@ union df_vga_en { #define DF_PCI_CFG_BASE0 DF_REG_ID(0, 0xc80) #define DF_PCI_CFG_LIMIT0 DF_REG_ID(0, 0xc84) -#define DF_PCI_CFG_MAP_COUNT 8 +#define DF_PCI_CFG_MAP_COUNT 16 #define DF_PCI_CFG_REG_OFFSET(instance) ((instance) * 2 * sizeof(uint32_t)) #define DF_PCI_CFG_BASE(reg) (DF_PCI_CFG_BASE0 + DF_PCI_CFG_REG_OFFSET(reg)) @@ -54,7 +54,7 @@ union df_pci_cfg_limit { #define DF_IO_BASE0 DF_REG_ID(0, 0xd00) #define DF_IO_LIMIT0 DF_REG_ID(0, 0xd04) -#define DF_IO_REG_COUNT 8 +#define DF_IO_REG_COUNT 16 #define DF_IO_REG_OFFSET(instance) ((instance) * 2 * sizeof(uint32_t)) #define DF_IO_BASE(reg) (DF_IO_BASE0 + DF_IO_REG_OFFSET(reg)) @@ -93,13 +93,13 @@ union df_io_limit { #define DF_MMIO_EXT_ADDR_SHIFT 48 #define DF_MMIO_REG_SET_SIZE 4 -#define DF_MMIO_REG_SET_COUNT 16 +#define DF_MMIO_REG_SET_COUNT 32 union df_mmio_control { struct { uint32_t re : 1; /* [ 0.. 0] */ uint32_t we : 1; /* [ 1.. 1] */ - uint32_t : 1; /* [ 2.. 2] */ + uint32_t cpu_dis : 1; /* [ 2.. 2] */ uint32_t np : 1; /* [ 3.. 3] */ uint32_t : 12; /* [ 4..15] */ uint32_t dst_fabric_id : 12; /* [16..27] */ @@ -124,13 +124,13 @@ union df_mmio_addr_ext { union df_ficaa { struct { - uint32_t cfg_inst_acc_en : 1; /* [ 0.. 0] */ - uint32_t reg_num : 10; /* [10.. 1] */ - uint32_t func_num : 3; /* [13..11] */ - uint32_t b64_en : 1; /* [14..14] */ - uint32_t : 1; /* [15..15] */ - uint32_t inst_id : 8; /* [23..16] */ - uint32_t : 8; /* [31..24] */ + uint32_t cfg_inst_acc_en : 1; /* [ 0.. 0] */ + uint32_t reg_num : 10; /* [10.. 1] */ + uint32_t func_num : 3; /* [13..11] */ + uint32_t b64_en : 1; /* [14..14] */ + uint32_t : 1; /* [15..15] */ + uint32_t inst_id : 9; /* [24..16] */ + uint32_t : 7; /* [31..25] */ }; uint32_t raw; }; diff --git a/src/soc/amd/turin_poc/include/soc/gpio.h b/src/soc/amd/turin_poc/include/soc/gpio.h index 613fea7f258..d2890aa50b7 100644 --- a/src/soc/amd/turin_poc/include/soc/gpio.h +++ b/src/soc/amd/turin_poc/include/soc/gpio.h @@ -25,7 +25,6 @@ #define GPIO_4 4 #define GPIO_5 5 #define GPIO_6 6 -#define GPIO_7 7 #define GPIO_12 12 #define GPIO_13 13 #define GPIO_14 14 @@ -38,15 +37,29 @@ #define GPIO_23 23 #define GPIO_24 24 #define GPIO_26 26 +#define GPIO_27 27 +#define GPIO_28 28 +#define GPIO_29 29 +#define GPIO_30 30 +#define GPIO_31 31 +#define GPIO_32 32 +#define GPIO_40 40 +#define GPIO_42 42 +#define GPIO_70 70 /* Bank 1: GPIO_64 - GPIO_127 */ #define GPIO_74 74 #define GPIO_75 75 #define GPIO_76 76 +#define GPIO_84 84 +#define GPIO_85 85 #define GPIO_86 86 #define GPIO_87 87 #define GPIO_88 88 #define GPIO_89 89 +#define GPIO_90 90 +#define GPIO_91 91 +#define GPIO_92 92 #define GPIO_104 104 #define GPIO_105 105 #define GPIO_106 106 @@ -54,6 +67,8 @@ #define GPIO_108 108 #define GPIO_109 109 #define GPIO_110 110 +#define GPIO_113 113 +#define GPIO_114 114 #define GPIO_115 115 #define GPIO_116 116 #define GPIO_117 117 @@ -69,6 +84,7 @@ /* Bank 2: GPIO_128 - GPIO_191 */ #define GPIO_129 129 +#define GPIO_130 130 #define GPIO_131 131 #define GPIO_132 132 #define GPIO_133 133 @@ -78,8 +94,11 @@ #define GPIO_137 137 #define GPIO_138 138 #define GPIO_139 139 +#define GPIO_140 140 #define GPIO_141 141 #define GPIO_142 142 +#define GPIO_143 143 +#define GPIO_144 144 #define GPIO_145 145 #define GPIO_146 146 #define GPIO_147 147 @@ -96,16 +115,13 @@ #define GPIO_259 259 #define GPIO_260 260 #define GPIO_261 261 -#define GPIO_262 262 -#define GPIO_263 263 #define GPIO_264 264 #define GPIO_265 265 #define GPIO_266 266 /* IOMUX function names and values */ #define GPIO_0_IOMUX_PWR_BTN_L 0 -#define GPIO_0_IOMUX_GPIO_PU1PD0 1 -#define GPIO_0_IOMUX_GPIOxx 2 +#define GPIO_0_IOMUX_GPIOxx 1 #define GPIO_1_IOMUX_SYS_RESET_L 0 #define GPIO_1_IOMUX_GPIOxx 1 #define GPIO_2_IOMUX_WAKE_L 0 @@ -121,12 +137,10 @@ #define GPIO_12_IOMUX_PWRGD_OUT 0 #define GPIO_12_IOMUX_GPIOxx 1 #define GPIO_13_IOMUX_I2C4_SCL 0 -#define GPIO_13_IOMUX_CLK_48_24_0 1 -#define GPIO_13_IOMUX_GPIOxx 2 +#define GPIO_13_IOMUX_GPIOxx 1 #define GPIO_14_IOMUX_I2C4_SDA 0 -#define GPIO_14_IOMUX_S0A3 1 -#define GPIO_14_IOMUX_GPIOxx 2 -#define GPIO_16_IOMUX_USB_1O_OC_L 0 +#define GPIO_14_IOMUX_GPIOxx 1 +#define GPIO_16_IOMUX_USB10_OC_L 0 #define GPIO_16_IOMUX_GPIOxx 1 #define GPIO_17_IOMUX_USB11_OC_L 0 #define GPIO_17_IOMUX_GPIOxx 1 @@ -136,35 +150,52 @@ #define GPIO_20_IOMUX_I2C5_SDA 0 #define GPIO_20_IOMUX_SMBUS1_SDA 1 #define GPIO_20_IOMUX_GPIOxx 2 -#define GPIO_21_IOMUX_GPIOxx 0 -#define GPIO_22_IOMUX_GPIOxx 0 +#define GPIO_21_IOMUX_GPIOxx 2 +#define GPIO_22_IOMUX_GPIOxx 2 #define GPIO_23_IOMUX_ESPI_RST_OUT_L 0 #define GPIO_23_IOMUX_GPIOxx 1 #define GPIO_24_IOMUX_SMERR_L 0 #define GPIO_24_IOMUX_GPIOxx 1 #define GPIO_26_IOMUX_PCIE_RST1_L 0 #define GPIO_26_IOMUX_GPIOxx 1 +#define GPIO_27_IOMUX_GPIOxx 1 +#define GPIO_28_IOMUX_X48M_OUT 0 +#define GPIO_29_IOMUX_GPIOxx 0 +#define GPIO_30_IOMUX_GPIOxx 0 +#define GPIO_31_IOMUX_GPIOxx 0 +#define GPIO_32_IOMUX_GPIOxx 0 +#define GPIO_40_IOMUX_GPIOxx 0 +#define GPIO_42_IOMUX_GPIOxx 0 +#define GPIO_70_IOMUX_GPIOxx 0 #define GPIO_74_IOMUX_ESPI_CLK2 0 -#define GPIO_74_IOMUX_GPIOxx 1 +#define GPIO_74_IOMUX_GPIOxx 2 #define GPIO_75_IOMUX_ESPI_CLK1 0 -#define GPIO_75_IOMUX_GPIOxx 1 +#define GPIO_75_IOMUX_GPIOxx 2 #define GPIO_76_IOMUX_GPIOxx 0 #define GPIO_76_IOMUX_SPI_TPM_CS_L 1 -#define GPIO_86_IOMUX_NMI_SYNC_FLOOD_L 0 -#define GPIO_87_IOMUX_GPIOxx 0 -#define GPIO_88_IOMUX_GPIOxx 0 +#define GPIO_84_IOMUX_GPIOxx 1 +#define GPIO_85_IOMUX_GPIOxx 1 +#define GPIO_86_IOMUX_GPIOxx 1 +#define GPIO_86_IOMUX_LPC_SMI_L 2 +#define GPIO_87_IOMUX_GPIOxx 2 +#define GPIO_88_IOMUX_GPIOxx 2 #define GPIO_89_IOMUX_GENINT_L 0 #define GPIO_89_IOMUX_PM_INTR_L 1 #define GPIO_89_IOMUX_GPIOxx 2 -#define GPIO_104_IOMUX_GPIOxx 0 -#define GPIO_105_IOMUX_GPIOxx 0 -#define GPIO_106_IOMUX_GPIOxx 0 -#define GPIO_107_IOMUX_GPIOxx 0 +#define GPIO_90_IOMUX_GPIOxx 2 +#define GPIO_91_IOMUX_GPIOxx 1 +#define GPIO_92_IOMUX_GPIOxx 3 +#define GPIO_104_IOMUX_GPIOxx 3 +#define GPIO_105_IOMUX_GPIOxx 3 +#define GPIO_106_IOMUX_GPIOxx 3 +#define GPIO_107_IOMUX_GPIOxx 3 #define GPIO_108_IOMUX_ESPI0_ALERT_D1 0 -#define GPIO_108_IOMUX_GPIOxx 1 -#define GPIO_109_IOMUX_GPIOxx 0 +#define GPIO_108_IOMUX_GPIOxx 2 +#define GPIO_109_IOMUX_GPIOxx 2 #define GPIO_110_IOMUX_ESPI1_ALERT_D1 0 #define GPIO_110_IOMUX_GPIOxx 1 +#define GPIO_113_IOMUX_GPIOxx 2 +#define GPIO_114_IOMUX_GPIOxx 2 #define GPIO_115_IOMUX_GPIOxx 0 #define GPIO_115_IOMUX_CLK_REQ11_L 1 #define GPIO_116_IOMUX_GPIOxx 0 @@ -174,7 +205,7 @@ #define GPIO_118_IOMUX_SPI_CS0_L 0 #define GPIO_118_IOMUX_GPIOxx 1 #define GPIO_119_IOMUX_SPI_CS1_L 0 -#define GPIO_119_IOMUX_GPIOxx 1 +#define GPIO_119_IOMUX_GPIOxx 2 #define GPIO_120_IOMUX_ESPI0_DATA0 0 #define GPIO_120_IOMUX_GPIOxx 1 #define GPIO_121_IOMUX_ESPI0_DATA1 0 @@ -192,8 +223,9 @@ #define GPIO_129_IOMUX_ESPI_RSTIN_L 0 #define GPIO_129_IOMUX_KBRST_L 1 #define GPIO_129_IOMUX_GPIOxx 2 +#define GPIO_130_IOMUX_GPIOxx 1 #define GPIO_131_IOMUX_ESPI1_DATA0 0 -#define GPIO_131_IOMUX_GPIOxx 1 +#define GPIO_131_IOMUX_GPIOxx 3 #define GPIO_132_IOMUX_ESPI1_DATA1 0 #define GPIO_132_IOMUX_GPIOxx 1 #define GPIO_133_IOMUX_ESPI1_DATA2 0 @@ -212,10 +244,15 @@ #define GPIO_138_IOMUX_GPIOxx 1 #define GPIO_139_IOMUX_UART0_INTR 0 #define GPIO_139_IOMUX_GPIOxx 1 +#define GPIO_140_IOMUX_UART3_RXD 0 +#define GPIO_140_IOMUX_GPIOxx 2 #define GPIO_141_IOMUX_UART1_RXD 0 #define GPIO_141_IOMUX_GPIOxx 1 #define GPIO_142_IOMUX_UART1_TXD 0 -#define GPIO_142_IOMUX_GPIOxx 1 +#define GPIO_142_IOMUX_UART3_TXD 1 +#define GPIO_142_IOMUX_GPIOxx 2 +#define GPIO_143_IOMUX_GPIOxx 1 +#define GPIO_144_IOMUX_GPIOxx 1 #define GPIO_145_IOMUX_I3C0_SCL_SPD0_SCL 0 #define GPIO_145_IOMUX_I2C0_SCL_SPD0_SCL 1 #define GPIO_145_IOMUX_SMBUS0_SCL 2 @@ -258,8 +295,6 @@ #define GPIO_260_IOMUX_GPIOxx 1 #define GPIO_261_IOMUX_SGPIO_LOAD 0 #define GPIO_261_IOMUX_GPIOxx 1 -#define GPIO_262_IOMUX_GPIOxx 0 -#define GPIO_263_IOMUX_GPIOxx 0 #define GPIO_264_IOMUX_USB00_OC_L 0 #define GPIO_264_IOMUX_GPIOxx 1 #define GPIO_265_IOMUX_USB01_OC_L 0 diff --git a/src/soc/amd/turin_poc/include/soc/iomap.h b/src/soc/amd/turin_poc/include/soc/iomap.h index f1d692121f5..d85597e051f 100644 --- a/src/soc/amd/turin_poc/include/soc/iomap.h +++ b/src/soc/amd/turin_poc/include/soc/iomap.h @@ -8,17 +8,20 @@ #define I2C_CTRLR_COUNT (I2C_MASTER_DEV_COUNT + I2C_PERIPHERAL_DEV_COUNT) #define I3C_CTRLR_COUNT 4 -#define SPI_BASE_ADDRESS 0xfec10000 +#define ACPIMMIO_RGPIO_BASE 0xfed81200 -/* @Todo : Check these values for Turin */ +#define SPI_BASE_ADDRESS 0xfec10000 -/* I/O Ranges */ -#define ACPI_IO_BASE 0x0400 -#define ACPI_CSTATE_CONTROL (ACPI_IO_BASE + 0x10) +#define FCH_WATCHDOG_BASE 0xfeb00000 /* FCH AL2AHB Registers */ #define ALINK_AHB_ADDRESS 0xfedc0000 +#define APU_DMA0_BASE 0xfedc7000 +#define APU_DMA1_BASE 0xfedc8000 +#define APU_DMA2_BASE 0xfedcc000 +#define APU_DMA3_BASE 0xfedcd000 + #define APU_I2C0_BASE 0xfedc2000 #define APU_I2C1_BASE 0xfedc3000 #define APU_I2C2_BASE 0xfedc4000 @@ -29,10 +32,25 @@ #define APU_UART0_BASE 0xfedc9000 #define APU_UART1_BASE 0xfedca000 #define APU_UART2_BASE 0xfedce000 +#define APU_UART3_BASE 0xfedcf000 +#define APU_UART4_BASE 0xfedd1000 #define APU_I3C0_BASE 0xfedd2000 #define APU_I3C1_BASE 0xfedd3000 #define APU_I3C2_BASE 0xfedd4000 #define APU_I3C3_BASE 0xfedd6000 +/* I/O Ranges */ +#define ACPI_IO_BASE 0x0400 +#define ACPI_PM_EVT_BLK (ACPI_IO_BASE + 0x00) +#define ACPI_PM1_STS (ACPI_PM_EVT_BLK + 0x00) +#define ACPI_PM1_EN (ACPI_PM_EVT_BLK + 0x02) +#define ACPI_PM1_CNT_BLK (ACPI_IO_BASE + 0x04) +#define ACPI_PM_TMR_BLK (ACPI_IO_BASE + 0x08) +#define ACPI_CSTATE_CONTROL (ACPI_IO_BASE + 0x10) +#define ACPI_GPE0_BLK (ACPI_IO_BASE + 0x20) +#define ACPI_GPE0_STS (ACPI_GPE0_BLK + 0x00) +#define ACPI_GPE0_EN (ACPI_GPE0_BLK + 0x04) +#define SMB_BASE_ADDR 0x0b00 + #endif /* AMD_TURIN_POC_IOMAP_H */ diff --git a/src/soc/amd/turin_poc/include/soc/msr.h b/src/soc/amd/turin_poc/include/soc/msr.h index ba2c25f9973..a1773b2269e 100644 --- a/src/soc/amd/turin_poc/include/soc/msr.h +++ b/src/soc/amd/turin_poc/include/soc/msr.h @@ -8,8 +8,8 @@ /* MSRC001_00[6B:64] P-state [7:0] bit definitions */ union pstate_msr { struct { - uint64_t cpu_fid_0_7 : 8; /* [ 0.. 7] */ - uint64_t cpu_dfs_id : 6; /* [ 8..13] */ + uint64_t cpu_fid_0_11 : 12; /* [ 0..11] */ + uint64_t : 2; /* [12..13] */ uint64_t cpu_vid_0_7 : 8; /* [14..21] */ uint64_t idd_value : 8; /* [22..29] */ uint64_t idd_div : 2; /* [30..31] */ diff --git a/src/soc/amd/turin_poc/include/soc/smi.h b/src/soc/amd/turin_poc/include/soc/smi.h index df56b6750fe..77128605310 100644 --- a/src/soc/amd/turin_poc/include/soc/smi.h +++ b/src/soc/amd/turin_poc/include/soc/smi.h @@ -78,7 +78,8 @@ /* 31 Reserved */ #define SMITYPE_WAKE_L2 32 #define SMITYPE_PSP 33 -/* 34-35 Reserved */ +#define SMITYPE_PSP2 34 +#define SMITYPE_PSP3 35 #define SMITYPE_ESPI_SCI_B 36 #define SMITYPE_ESPI1_SYS_EVT_B 37 #define SMITYPE_ESPI1_WAKE_PME 38 diff --git a/src/soc/amd/turin_poc/include/soc/smu.h b/src/soc/amd/turin_poc/include/soc/smu.h index dd340442646..e18fc8e3b07 100644 --- a/src/soc/amd/turin_poc/include/soc/smu.h +++ b/src/soc/amd/turin_poc/include/soc/smu.h @@ -1,11 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef AMD_GENOA_POC_SMU_H -#define AMD_GENOA_POC_SMU_H +#ifndef AMD_TURIN_POC_SMU_H +#define AMD_TURIN_POC_SMU_H /* SMU mailbox register offsets in SMN */ -#define SMN_SMU_MESG_ID 0x3b10530 -#define SMN_SMU_MESG_RESP 0x3b1057c +#define SMN_SMU_MESG_ID 0x3b10930 +#define SMN_SMU_MESG_RESP 0x3b1097c #define SMN_SMU_MESG_ARGS_BASE 0x3b109c4 #define SMU_NUM_ARGS 6 @@ -20,4 +20,4 @@ enum smu_message_id { */ void smu_sx_entry(void); -#endif /* AMD_GENOA_POC_SMU_H */ +#endif /* AMD_TURIN_POC_SMU_H */ diff --git a/src/soc/amd/turin_poc/include/soc/southbridge.h b/src/soc/amd/turin_poc/include/soc/southbridge.h index 1027a584554..8447b32be7b 100644 --- a/src/soc/amd/turin_poc/include/soc/southbridge.h +++ b/src/soc/amd/turin_poc/include/soc/southbridge.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef AMD_GENOA_POC_SOUTHBRIDGE_H -#define AMD_GENOA_POC_SOUTHBRIDGE_H +#ifndef AMD_TURIN_POC_SOUTHBRIDGE_H +#define AMD_TURIN_POC_SOUTHBRIDGE_H #include @@ -9,6 +9,7 @@ #define PM_ISACONTROL 0x04 #define ABCLKGATEEN BIT(16) #define PM_PCI_CTRL 0x08 +#define FORCE_STPCLK_RETRY BIT(24) #define FORCE_SLPSTATE_RETRY BIT(25) #define PWR_RESET_CFG 0x10 #define TOGGLE_ALL_PWR_GOOD (1 << 1) @@ -72,8 +73,6 @@ #define PM_ACPI_RTC_WAKE_EN BIT(29) #define PM_ACPI_USE_GATED_ALINK_CLK BIT(30) #define PM_ACPI_DELAY_GPP_OFF_TIME BIT(31) -#define PM_SPI_PAD_PU_PD 0x90 -#define PM_ESPI_CS_USE_DATA2 BIT(16) #define PM_LPC_GATING 0xec #define PM_LPC_AB_NO_BYPASS_EN BIT(2) #define PM_LPC_A20_EN BIT(1) @@ -119,4 +118,4 @@ void fch_pre_init(void); void fch_early_init(void); void fch_init(void *chip_info); -#endif /* AMD_GENOA_POC_SOUTHBRIDGE_H */ +#endif /* AMD_TURIN_POC_SOUTHBRIDGE_H */ diff --git a/src/soc/amd/turin_poc/include/soc/xhci.h b/src/soc/amd/turin_poc/include/soc/xhci.h new file mode 100644 index 00000000000..4645a629d2b --- /dev/null +++ b/src/soc/amd/turin_poc/include/soc/xhci.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef AMD_TURIN_XHCI_H +#define AMD_TURIN_XHCI_H + +#include + +#define SOC_XHCI_0 DEV_PTR(xhci_0) +#define SOC_XHCI_1 DEV_PTR(xhci_1) +#define SOC_XHCI_2 NULL +#define SOC_XHCI_3 NULL +#define SOC_XHCI_4 NULL +#define SOC_XHCI_5 NULL +#define SOC_XHCI_6 NULL +#define SOC_XHCI_7 NULL + +#endif /* AMD_TURIN_XHCI_H */ diff --git a/src/soc/amd/turin_poc/lpc.c b/src/soc/amd/turin_poc/lpc.c new file mode 100644 index 00000000000..23a32f5de38 --- /dev/null +++ b/src/soc/amd/turin_poc/lpc.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +void soc_lpc_tpm_decode_spi(void) +{ + /* SoC-specific SPI TPM setting */ + pci_or_config32(SOC_LPC_DEV, 0xdc, 1); +} diff --git a/src/soc/amd/turin_poc/mca.c b/src/soc/amd/turin_poc/mca.c index 9a6df2b53ef..460d9afee23 100644 --- a/src/soc/amd/turin_poc/mca.c +++ b/src/soc/amd/turin_poc/mca.c @@ -4,7 +4,11 @@ #include #include -/* TODO: Check if non-core MCA banks are same for all cores */ +/* + * Non-core MCA banks are not the same for all cores. + * Refer to "Table 56: Non-core MCA Bank to Block Mapping" + * in Turin C1 PPR (doc 57238). + */ static const char *const mca_bank_name[] = { [0] = "Load-store unit", [1] = "Instruction fetch unit", @@ -22,22 +26,22 @@ static const char *const mca_bank_name[] = { [13] = "L3 cache unit", [14] = "L3 cache unit", [15] = "Microprocessor5 Management Controller", - [16] = "Parameter Block", - [17] = "GMI Controller", - [18] = "GMI Controller", - [19] = "High Speed Interface Unit (GMI)", - [20] = "High Speed Interface Unit (GMI)", + [16] = "GMI Controller (PCS_GMI)", + [17] = "GMI Controller (PCS_GMI)", + [18] = "High Speed Interface Unit (KPX_GMI)", + [19] = "High Speed Interface Unit (KPX_GMI)", + [20] = "MPDMA", [21] = "Unified Memory Controller", [22] = "Unified Memory Controller", [23] = "Coherent Station", [24] = "Coherent Station", - [25] = "Northbridge IO Unit", - [26] = "PCIe Root Port", - [27] = "PCIe Root Port", - [28] = "Power Management, Interrupts, Etc.", + [25] = "PCIE", + [26] = "SATA", + [27] = "Northbridge IO Unit", + [28] = "NBIF", [29] = "SMU", - [30] = "XGMI Controller", - [31] = "High Speed Interface Unit (XGMI)", + [30] = "Power Management, Interrupts, Etc.", + [31] = "High Speed Interface Unit (SERDES)", }; bool mca_has_expected_bank_count(void) diff --git a/src/soc/amd/turin_poc/root_complex.c b/src/soc/amd/turin_poc/root_complex.c index 3171febe9f0..ffff6d1c322 100644 --- a/src/soc/amd/turin_poc/root_complex.c +++ b/src/soc/amd/turin_poc/root_complex.c @@ -2,24 +2,52 @@ #include #include +#include +#include #include +/* + * The order of IOHCs here is not random. They are sorted so that: + * 1. The First IOHC is the one with primary FCH. We want the LPC/SMBUS + * devices be on bus 0. + * 2. The rest of IOHCs are listed in an order so that ECAM MMIO region is one + * continuous block for all domains. + * + * AGESA/OpenSIL sets up the PCI configuration decoding ranges in line with + * this. + */ static const struct domain_iohc_info iohc_info[] = { [0] = { - .fabric_id = 0x22, - .misc_smn_base = SMN_IOHC_MISC_BASE_13C1, + .fabric_id = 0x24, + .misc_smn_base = SMN_IOHC_MISC_BASE_13D1, }, [1] = { - .fabric_id = 0x23, - .misc_smn_base = SMN_IOHC_MISC_BASE_13B1, + .fabric_id = 0x25, + .misc_smn_base = SMN_IOHC_MISC_BASE_1D61, }, [2] = { - .fabric_id = 0x21, + .fabric_id = 0x26, .misc_smn_base = SMN_IOHC_MISC_BASE_13E1, }, [3] = { + .fabric_id = 0x27, + .misc_smn_base = SMN_IOHC_MISC_BASE_1D51, + }, + [4] = { + .fabric_id = 0x23, + .misc_smn_base = SMN_IOHC_MISC_BASE_1D41, + }, + [5] = { + .fabric_id = 0x22, + .misc_smn_base = SMN_IOHC_MISC_BASE_13C1, + }, + [6] = { + .fabric_id = 0x21, + .misc_smn_base = SMN_IOHC_MISC_BASE_1D71, + }, + [7] = { .fabric_id = 0x20, - .misc_smn_base = SMN_IOHC_MISC_BASE_13D1, + .misc_smn_base = SMN_IOHC_MISC_BASE_13B1, }, }; @@ -33,15 +61,18 @@ static const struct non_pci_mmio_reg non_pci_mmio[] = { { 0x2d8, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, { 0x2e0, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, { 0x2e8, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, - /* The hardware has a 256 byte alignment requirement for the IOAPIC MMIO base, but we - tell the FSP to configure a 4k-aligned base address and this is reported as 4 KiB - resource. */ - { 0x2f0, 0xffffffffff00ull, 4 * KiB, IOMMU_IOAPIC_IDX }, + /* + * The hardware has a 256 byte alignment requirement for the IOAPIC + * MMIO base, but OpenSIL configures 64k-aligned base address and this + * is reported as 256 byte resource. + */ + { 0x2f0, 0xffffffffff00ull, 256, IOMMU_IOAPIC_IDX }, { 0x2f8, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, { 0x300, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, { 0x308, 0xfffffffff000ull, 4 * KiB, NON_PCI_RES_IDX_AUTO }, { 0x310, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, { 0x318, 0xfffffff80000ull, 512 * KiB, NON_PCI_RES_IDX_AUTO }, + { 0x338, 0xfffffff00000ull, 1 * MiB, NON_PCI_RES_IDX_AUTO }, }; const struct non_pci_mmio_reg *get_iohc_non_pci_mmio_regs(size_t *count) @@ -49,3 +80,17 @@ const struct non_pci_mmio_reg *get_iohc_non_pci_mmio_regs(size_t *count) *count = ARRAY_SIZE(non_pci_mmio); return non_pci_mmio; } + +static const char *gnb_acpi_name(const struct device *dev) +{ + return "GNB"; +} + +struct device_operations turin_root_complex_operations = { + /* The root complex has no PCI BARs implemented, so there's no need to call + pci_dev_read_resources for it */ + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, + .enable_resources = pci_dev_enable_resources, + .acpi_name = gnb_acpi_name, +}; diff --git a/src/soc/amd/turin_poc/smihandler.c b/src/soc/amd/turin_poc/smihandler.c index 1eb051317b4..80185a843de 100644 --- a/src/soc/amd/turin_poc/smihandler.c +++ b/src/soc/amd/turin_poc/smihandler.c @@ -61,6 +61,7 @@ static void fch_slp_typ_handler(void) /* Do not send SMI before AcpiPm1CntBlkx00[SlpTyp] */ pci_ctrl = pm_read32(PM_PCI_CTRL); pci_ctrl &= ~FORCE_SLPSTATE_RETRY; + pci_ctrl |= FORCE_STPCLK_RETRY; pm_write32(PM_PCI_CTRL, pci_ctrl); /* Enable SlpTyp */ diff --git a/src/soc/amd/turin_poc/uart.c b/src/soc/amd/turin_poc/uart.c index 19f7746bc8a..c90485318f4 100644 --- a/src/soc/amd/turin_poc/uart.c +++ b/src/soc/amd/turin_poc/uart.c @@ -24,6 +24,10 @@ static const struct soc_uart_ctrlr_info uart_info[] = { PAD_NF(GPIO_137, UART2_RXD, PULL_NONE), PAD_NF(GPIO_135, UART2_TXD, PULL_NONE), } }, + [3] = { APU_UART2_BASE, FCH_AOAC_DEV_UART3, "FUR3", { + PAD_NF(GPIO_140, UART3_RXD, PULL_NONE), + PAD_NF(GPIO_142, UART3_TXD, PULL_NONE), + } }, }; const struct soc_uart_ctrlr_info *soc_get_uart_ctrlr_info(size_t *num_ctrlrs) diff --git a/src/soc/intel/alderlake/Kconfig b/src/soc/intel/alderlake/Kconfig index 97c2ecca70b..334ea26e5b7 100644 --- a/src/soc/intel/alderlake/Kconfig +++ b/src/soc/intel/alderlake/Kconfig @@ -84,6 +84,18 @@ config SOC_INTEL_ALDERLAKE select SOC_INTEL_COMMON_BLOCK_VTD select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN + select SOC_INTEL_COMMON_FEATURE_LOCKDOWN + select SOC_INTEL_COMMON_FEATURE_PMUTIL + select SOC_INTEL_COMMON_FEATURE_SMIHANDLER + select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_RESET @@ -396,6 +408,19 @@ config CONSOLE_CBMEM_BUFFER_SIZE default 0x100000 if BUILDING_WITH_DEBUG_FSP default 0x40000 +config CHIPSETINIT_CBFS_FILE + string + depends on HAVE_CHIPSETINIT_BINARY + default "chipsetinit.bin" + help + Name of the Chipset Initialization binary on the CBFS + +config HAVE_CHIPSETINIT_BINARY + bool + default n + help + Select this option if you want to load the Chipset Initialization binary + config FSP_TYPE_IOT bool default n @@ -557,4 +582,12 @@ config SOC_INTEL_COMMON_BLOCK_ACPI_SLP_S0_FREQ_HZ help slp_s0_residency granularity in 122us ticks (i.e. ~8.2KHz). +config SOC_INTEL_SPI_DEV_MAX + int + default 4 + +config SOC_INTEL_SPI_PSF_DESTINATION_ID + hex + default 0x23a8 + endif diff --git a/src/soc/intel/alderlake/Makefile.mk b/src/soc/intel/alderlake/Makefile.mk index 6262cf29993..5ca354832dc 100644 --- a/src/soc/intel/alderlake/Makefile.mk +++ b/src/soc/intel/alderlake/Makefile.mk @@ -5,41 +5,29 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += gspi.c -all-y += i2c.c -all-y += pmutil.c -all-y += spi.c -all-y += uart.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c bootblock-y += bootblock/report_platform.c -bootblock-y += espi.c bootblock-y += p2sb.c bootblock-$(CONFIG_ALDERLAKE_CONFIGURE_DESCRIPTOR) += bootblock/update_descriptor.c romstage-$(CONFIG_SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY) += cse_telemetry.c -romstage-y += espi.c romstage-y += meminit.c romstage-y += pcie_rp.c -romstage-y += reset.c ramstage-y += acpi.c ramstage-y += chip.c ramstage-y += cpu.c ramstage-y += elog.c -ramstage-y += espi.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += graphics.c ramstage-y += hsphy.c -ramstage-y += lockdown.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c -ramstage-y += reset.c ramstage-$(CONFIG_SOC_INTEL_ALDERLAKE_TCSS_USB4_SUPPORT) += retimer.c -ramstage-y += soundwire.c ramstage-y += systemagent.c ramstage-y += tcss.c ramstage-y += vr_config.c @@ -48,9 +36,6 @@ ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog.c smm-y += elog.c smm-y += p2sb.c -smm-y += pmutil.c -smm-y += smihandler.c -smm-y += uart.c smm-y += xhci.c ifeq ($(CONFIG_SOC_INTEL_ALDERLAKE_PCH_S),y) diff --git a/src/soc/intel/alderlake/chipset.cb b/src/soc/intel/alderlake/chipset.cb index 355ef2e6e28..a18da51a89c 100644 --- a/src/soc/intel/alderlake/chipset.cb +++ b/src/soc/intel/alderlake/chipset.cb @@ -168,19 +168,19 @@ chip soc/intel/alderlake end end end - device pci 0d.1 alias tcss_xdci off end + device pci 0d.1 alias tcss_xdci off ops usb_xdci_ops end device pci 0d.2 alias tcss_dma0 off end device pci 0d.3 alias tcss_dma1 off end device pci 0e.0 alias vmd off end - device pci 10.0 alias i2c6 off end - device pci 10.1 alias i2c7 off end + device pci 10.0 alias i2c6 off ops i2c_dev_ops end + device pci 10.1 alias i2c7 off ops i2c_dev_ops end device pci 10.6 alias thc0 off end device pci 10.7 alias thc1 off end device pci 12.0 alias ish off end - device pci 12.6 alias gspi2 off end + device pci 12.6 alias gspi2 off ops spi_dev_ops end device pci 12.7 alias ufs off end - device pci 13.0 alias gspi3 off end - device pci 14.0 alias xhci off + device pci 13.0 alias gspi3 off ops spi_dev_ops end + device pci 14.0 alias xhci off ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off @@ -231,44 +231,44 @@ chip soc/intel/alderlake end device pci 14.1 alias usb_otg off end device pci 14.2 alias shared_sram off end - device pci 14.3 alias cnvi_wifi off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 16.0 alias heci1 on end device pci 16.1 alias heci2 off end device pci 16.2 alias ide_r off end device pci 16.3 alias kt off end device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end - device pci 17.0 alias sata off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end - device pci 19.2 alias uart2 off end + device pci 17.0 alias sata off ops sata_ops end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end + device pci 19.2 alias uart2 off ops uart_ops end # eMMC device is applicable only for ADL-N device pci 1a.0 alias emmc off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1c.4 alias pcie_rp5 off end - device pci 1c.5 alias pcie_rp6 off end - device pci 1c.6 alias pcie_rp7 off end - device pci 1c.7 alias pcie_rp8 off end - device pci 1d.0 alias pcie_rp9 off end - device pci 1d.1 alias pcie_rp10 off end - device pci 1d.2 alias pcie_rp11 off end - device pci 1d.3 alias pcie_rp12 off end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end + device pci 1d.0 alias pcie_rp9 off ops pcie_rp_ops end + device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end + device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end + device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.3 alias hda off ops hda_ops end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias south_tracehub off end diff --git a/src/soc/intel/alderlake/chipset_pch_s.cb b/src/soc/intel/alderlake/chipset_pch_s.cb index 6bcfab1f450..962a46617b2 100644 --- a/src/soc/intel/alderlake/chipset_pch_s.cb +++ b/src/soc/intel/alderlake/chipset_pch_s.cb @@ -277,11 +277,11 @@ chip soc/intel/alderlake device pci 09.0 alias north_tracehub off end device pci 0a.0 alias crashlog on end device pci 0e.0 alias vmd off end - device pci 11.0 alias uart3 off end + device pci 11.0 alias uart3 off ops uart_ops end device pci 12.0 alias ish off end - device pci 12.6 alias gspi2 off end - device pci 13.0 alias gspi3 off end - device pci 14.0 alias xhci off + device pci 12.6 alias gspi2 off ops spi_dev_ops end + device pci 13.0 alias gspi3 off ops spi_dev_ops end + device pci 14.0 alias xhci off ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off @@ -360,60 +360,60 @@ chip soc/intel/alderlake end end end - device pci 14.1 alias xdci off end + device pci 14.1 alias xdci off ops usb_xdci_ops end device pci 14.2 alias shared_sram off end - device pci 14.3 alias cnvi_wifi off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 16.0 alias heci1 on end device pci 16.1 alias heci2 off end device pci 16.2 alias ide_r off end device pci 16.3 alias kt off end device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end - device pci 17.0 alias sata off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end - device pci 19.2 alias uart2 off end - device pci 1a.0 alias pcie_rp25 off end - device pci 1a.1 alias pcie_rp26 off end - device pci 1a.2 alias pcie_rp27 off end - device pci 1a.3 alias pcie_rp28 off end - device pci 1b.0 alias pcie_rp17 off end - device pci 1b.1 alias pcie_rp18 off end - device pci 1b.2 alias pcie_rp19 off end - device pci 1b.3 alias pcie_rp20 off end - device pci 1b.4 alias pcie_rp21 off end - device pci 1b.5 alias pcie_rp22 off end - device pci 1b.6 alias pcie_rp23 off end - device pci 1b.7 alias pcie_rp24 off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1c.4 alias pcie_rp5 off end - device pci 1c.5 alias pcie_rp6 off end - device pci 1c.6 alias pcie_rp7 off end - device pci 1c.7 alias pcie_rp8 off end - device pci 1d.0 alias pcie_rp9 off end - device pci 1d.1 alias pcie_rp10 off end - device pci 1d.2 alias pcie_rp11 off end - device pci 1d.3 alias pcie_rp12 off end - device pci 1d.4 alias pcie_rp13 off end - device pci 1d.5 alias pcie_rp14 off end - device pci 1d.6 alias pcie_rp15 off end - device pci 1d.7 alias pcie_rp16 off end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 17.0 alias sata off ops sata_ops end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end + device pci 19.2 alias uart2 off ops uart_ops end + device pci 1a.0 alias pcie_rp25 off ops pcie_rp_ops end + device pci 1a.1 alias pcie_rp26 off ops pcie_rp_ops end + device pci 1a.2 alias pcie_rp27 off ops pcie_rp_ops end + device pci 1a.3 alias pcie_rp28 off ops pcie_rp_ops end + device pci 1b.0 alias pcie_rp17 off ops pcie_rp_ops end + device pci 1b.1 alias pcie_rp18 off ops pcie_rp_ops end + device pci 1b.2 alias pcie_rp19 off ops pcie_rp_ops end + device pci 1b.3 alias pcie_rp20 off ops pcie_rp_ops end + device pci 1b.4 alias pcie_rp21 off ops pcie_rp_ops end + device pci 1b.5 alias pcie_rp22 off ops pcie_rp_ops end + device pci 1b.6 alias pcie_rp23 off ops pcie_rp_ops end + device pci 1b.7 alias pcie_rp24 off ops pcie_rp_ops end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end + device pci 1d.0 alias pcie_rp9 off ops pcie_rp_ops end + device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end + device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end + device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end + device pci 1d.4 alias pcie_rp13 off ops pcie_rp_ops end + device pci 1d.5 alias pcie_rp14 off ops pcie_rp_ops end + device pci 1d.6 alias pcie_rp15 off ops pcie_rp_ops end + device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.3 alias hda off ops hda_ops end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias south_tracehub off end diff --git a/src/soc/intel/alderlake/cpu.c b/src/soc/intel/alderlake/cpu.c index c2efff34199..615bd43c310 100644 --- a/src/soc/intel/alderlake/cpu.c +++ b/src/soc/intel/alderlake/cpu.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -140,7 +141,7 @@ void soc_core_init(struct device *cpu) /* Enable Turbo */ enable_turbo(); - if (CONFIG(INTEL_TME) && is_tme_supported()) + if (get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported()) set_tme_core_activate(); } diff --git a/src/soc/intel/alderlake/espi.c b/src/soc/intel/alderlake/espi.c deleted file mode 100644 index bdc41a6a30e..00000000000 --- a/src/soc/intel/alderlake/espi.c +++ /dev/null @@ -1,56 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * This file is created based on Intel Alder Lake Processor PCH Datasheet - * Document number: 621483 - * Chapter number: 2 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]) -{ - const config_t *config = config_of_soc(); - - gen_io_dec[0] = config->gen1_dec; - gen_io_dec[1] = config->gen2_dec; - gen_io_dec[2] = config->gen3_dec; - gen_io_dec[3] = config->gen4_dec; -} - -#if ENV_RAMSTAGE -void lpc_soc_init(struct device *dev) -{ - /* Legacy initialization */ - isa_dma_init(); - pch_misc_init(); - - /* Enable CLKRUN_EN for power gating ESPI */ - lpc_enable_pci_clk_cntl(); - - /* Set ESPI Serial IRQ mode */ - if (CONFIG(SERIRQ_CONTINUOUS_MODE)) - lpc_set_serirq_mode(SERIRQ_CONTINUOUS); - else - lpc_set_serirq_mode(SERIRQ_QUIET); - - /* Interrupt configuration */ - pch_enable_ioapic(); - pch_pirq_init(); - setup_i8259(); - i8259_configure_irq_trigger(9, 1); -} -#endif diff --git a/src/soc/intel/alderlake/fsp_params.c b/src/soc/intel/alderlake/fsp_params.c index bd6f1d548a2..396ea53c5ad 100644 --- a/src/soc/intel/alderlake/fsp_params.c +++ b/src/soc/intel/alderlake/fsp_params.c @@ -664,6 +664,22 @@ static void fill_fsps_tcss_params(FSP_S_CONFIG *s_cfg, s_cfg->Usb4CmMode = CONFIG(SOFTWARE_CONNECTION_MANAGER); } +#if CONFIG(HAVE_CHIPSETINIT_BINARY) +static void fill_fsps_chipsetinit_params(FSP_S_CONFIG *s_cfg, + const struct soc_intel_alderlake_config *config) +{ + void *data; + size_t size; + + data = cbfs_map(CONFIG_CHIPSETINIT_CBFS_FILE, &size); + if (!data || size == 0) + return; + + s_cfg->ChipsetInitBinPtr = (uint32_t)(uintptr_t)data; + s_cfg->ChipsetInitBinLen = (uint32_t)size; +} +#endif + static void fill_fsps_chipset_lockdown_params(FSP_S_CONFIG *s_cfg, const struct soc_intel_alderlake_config *config) { @@ -1284,6 +1300,9 @@ static void soc_silicon_init_params(FSP_S_CONFIG *s_cfg, fill_fsps_cpu_params, fill_fsps_igd_params, fill_fsps_tcss_params, +#if CONFIG(HAVE_CHIPSETINIT_BINARY) + fill_fsps_chipsetinit_params, +#endif fill_fsps_chipset_lockdown_params, fill_fsps_xhci_params, fill_fsps_xdci_params, diff --git a/src/soc/intel/alderlake/gspi.c b/src/soc/intel/alderlake/gspi.c deleted file mode 100644 index dd07b07f1a3..00000000000 --- a/src/soc/intel/alderlake/gspi.c +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/* - * This file is created based on Intel Alder Lake Processor PCH Datasheet - * Document number: 621483 - * Chapter number: 11 - */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCH_DEVFN_GSPI0; - case 1: - return PCH_DEVFN_GSPI1; - case 2: - return PCH_DEVFN_GSPI2; - case 3: - return PCH_DEVFN_GSPI3; - } - return -1; -} diff --git a/src/soc/intel/alderlake/i2c.c b/src/soc/intel/alderlake/i2c.c deleted file mode 100644 index 5fcca2a9e76..00000000000 --- a/src/soc/intel/alderlake/i2c.c +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * This file is created based on Intel Alder Lake Processor PCH Datasheet - * Document number: 621483 - * Chapter number: 13 - */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_I2C0: - return 0; - case PCH_DEVFN_I2C1: - return 1; - case PCH_DEVFN_I2C2: - return 2; - case PCH_DEVFN_I2C3: - return 3; - case PCH_DEVFN_I2C4: - return 4; - case PCH_DEVFN_I2C5: - return 5; - case PCH_DEVFN_I2C6: - return 6; - case PCH_DEVFN_I2C7: - return 7; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCH_DEVFN_I2C0; - case 1: - return PCH_DEVFN_I2C1; - case 2: - return PCH_DEVFN_I2C2; - case 3: - return PCH_DEVFN_I2C3; - case 4: - return PCH_DEVFN_I2C4; - case 5: - return PCH_DEVFN_I2C5; - case 6: - return PCH_DEVFN_I2C6; - case 7: - return PCH_DEVFN_I2C7; - } - return -1; -} diff --git a/src/soc/intel/alderlake/include/soc/cfr.h b/src/soc/intel/alderlake/include/soc/cfr.h index 1cacac618cc..4834ba1bc39 100644 --- a/src/soc/intel/alderlake/include/soc/cfr.h +++ b/src/soc/intel/alderlake/include/soc/cfr.h @@ -11,27 +11,19 @@ #include /* FSP hyperthreading */ -static const struct sm_object hyper_threading = SM_DECLARE_ENUM({ +static const struct sm_object hyper_threading = SM_DECLARE_BOOL({ .opt_name = "hyper_threading", .ui_name = "Hyper-Threading", .ui_helptext = "Enable or disable Hyper-Threading", .default_value = CONFIG(FSP_HYPERTHREADING), - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, }); /* IGD Enabled */ -static const struct sm_object igd_enabled = SM_DECLARE_ENUM({ +static const struct sm_object igd_enabled = SM_DECLARE_BOOL({ .opt_name = "igd_enabled", .ui_name = "Enable the Intel iGPU", .ui_helptext = "Enable or disable the Intel iGPU", .default_value = !CONFIG(SOC_INTEL_DISABLE_IGD), - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, }); /* IGD Aperture Size */ @@ -51,7 +43,7 @@ static const struct sm_object igd_aperture = SM_DECLARE_ENUM({ { " 512 MB", IGD_AP_SZ_512MB }, #endif SM_ENUM_VALUE_END }, -}, WITH_DEP_VALUES(&igd_enabled, 1)); +}, WITH_DEP_VALUES(&igd_enabled, true)); /* IGD DVMT pre-allocated memory */ static const struct sm_object igd_dvmt = SM_DECLARE_ENUM({ @@ -67,42 +59,30 @@ static const struct sm_object igd_dvmt = SM_DECLARE_ENUM({ { "128 MB", IGD_SM_128MB }, { "160 MB", IGD_SM_160MB }, SM_ENUM_VALUE_END }, -}, WITH_DEP_VALUES(&igd_enabled, 1)); +}, WITH_DEP_VALUES(&igd_enabled, true)); /* Legacy 8254 Timer */ -static const struct sm_object legacy_8254_timer = SM_DECLARE_ENUM({ +static const struct sm_object legacy_8254_timer = SM_DECLARE_BOOL({ .opt_name = "legacy_8254_timer", .ui_name = "Legacy 8254 Timer", .ui_helptext = "Enable the legacy 8254 timer by disabling clock gating.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = false, }); /* S0ix Enable */ -static const struct sm_object s0ix_enable = SM_DECLARE_ENUM({ +static const struct sm_object s0ix_enable = SM_DECLARE_BOOL({ .opt_name = "s0ix_enable", .ui_name = "Modern Standby (S0ix)", .ui_helptext = "Enabled: use Modern Standby / S0ix. Disabled: use ACPI S3 sleep", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* VT-d */ -static const struct sm_object vtd = SM_DECLARE_ENUM({ +static const struct sm_object vtd = SM_DECLARE_BOOL({ .opt_name = "vtd", .ui_name = "VT-d", .ui_helptext = "Enable or disable Intel VT-d (virtualization)", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); #endif /* _ALDERLAKE_CFR_H_ */ diff --git a/src/soc/intel/alderlake/include/soc/pci_devs.h b/src/soc/intel/alderlake/include/soc/pci_devs.h index 010a2101ea5..a3f1d7520de 100644 --- a/src/soc/intel/alderlake/include/soc/pci_devs.h +++ b/src/soc/intel/alderlake/include/soc/pci_devs.h @@ -278,4 +278,12 @@ #define PCH_DEV_GBE _PCH_DEV(ESPI, 6) #define PCH_DEV_TRACEHUB _PCH_DEV(ESPI, 7) +/* for common code */ +#define PCI_DEVFN_UART0 PCH_DEVFN_UART0 +#define PCI_DEVFN_UART1 PCH_DEVFN_UART1 +#define PCI_DEVFN_UART2 PCH_DEVFN_UART2 +#define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n +#define SOC_PMC_DEV PCH_DEV_PMC +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n + #endif diff --git a/src/soc/intel/alderlake/include/soc/pmc.h b/src/soc/intel/alderlake/include/soc/pmc.h index 81a99e00eca..aa7df21beeb 100644 --- a/src/soc/intel/alderlake/include/soc/pmc.h +++ b/src/soc/intel/alderlake/include/soc/pmc.h @@ -168,6 +168,9 @@ extern struct device_operations pmc_ops; #define ST_PG_FDIS1 0x1e20 #define ST_FDIS_LOCK (1 << 31) +/* PMC lockdown configuration register for ST_FDIS_LOCK */ +#define PMC_FDIS_LOCK_REG ST_PG_FDIS1 + #define SCIS_IRQ9 0 #define SCIS_IRQ10 1 #define SCIS_IRQ11 2 diff --git a/src/soc/intel/alderlake/lockdown.c b/src/soc/intel/alderlake/lockdown.c deleted file mode 100644 index 59fa065b3dd..00000000000 --- a/src/soc/intel/alderlake/lockdown.c +++ /dev/null @@ -1,60 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * This file is created based on Intel Alder Lake Processor PCH Datasheet - * Document number: 621483 - * Chapter number: 4 - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* PCR PSTH Control Register */ -#define PCR_PSTH_CTRLREG 0x1d00 -#define PSTH_CTRLREG_IOSFPTCGE (1 << 2) - -static void pmc_lockdown_cfg(int chipset_lockdown) -{ - uint8_t *pmcbase = pmc_mmio_regs(); - - /* PMSYNC */ - setbits32(pmcbase + PMSYNC_TPR_CFG, PCH2CPU_TPR_CFG_LOCK); - /* Lock down ABASE and sleep stretching policy */ - setbits32(pmcbase + GEN_PMCON_B, SLP_STR_POL_LOCK | ACPI_BASE_LOCK); - - if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) - setbits32(pmcbase + GEN_PMCON_B, SMI_LOCK); - - if (!CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM)) { - setbits32(pmcbase + ST_PG_FDIS1, ST_FDIS_LOCK); - setbits32(pmcbase + SSML, SSML_SSL_EN); - setbits32(pmcbase + PM_CFG, PM_CFG_DBG_MODE_LOCK | - PM_CFG_XRAM_READ_DISABLE); - } - - /* Send PMC IPC to inform about both BIOS Reset and PCI enumeration done */ - pmc_send_bios_reset_pci_enum_done(); -} - -static void pch_lockdown_cfg(void) -{ - if (CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM)) - return; - - /* Enable IOSF Primary Trunk Clock Gating */ - pcr_rmw32(PID_PSTH, PCR_PSTH_CTRLREG, ~0, PSTH_CTRLREG_IOSFPTCGE); -} - -void soc_lockdown_config(int chipset_lockdown) -{ - /* PMC lock down configuration */ - pmc_lockdown_cfg(chipset_lockdown); - /* PCH lock down configuration */ - pch_lockdown_cfg(); -} diff --git a/src/soc/intel/alderlake/meminit.c b/src/soc/intel/alderlake/meminit.c index efeac5cecdc..d7923401c70 100644 --- a/src/soc/intel/alderlake/meminit.c +++ b/src/soc/intel/alderlake/meminit.c @@ -54,8 +54,8 @@ static const struct soc_mem_cfg soc_mem_cfg[] = { * configuration. */ .half_channel = BIT(0), - /* In mixed topologies, either channel 0 or 1 can be memory-down. */ - .mixed_topo = BIT(0) | BIT(1), + /* In mixed topologies, channel 0 is memory-down. */ + .mixed_topo = BIT(0), }, }, [MEM_TYPE_DDR5] = { @@ -70,8 +70,8 @@ static const struct soc_mem_cfg soc_mem_cfg[] = { * configuration. */ .half_channel = BIT(0), - /* In mixed topologies, either channel 0 or 1 can be memory-down. */ - .mixed_topo = BIT(0) | BIT(1), + /* In mixed topologies, channel 0 is memory-down. */ + .mixed_topo = BIT(0), }, }, [MEM_TYPE_LP4X] = { diff --git a/src/soc/intel/alderlake/pmutil.c b/src/soc/intel/alderlake/pmutil.c deleted file mode 100644 index c4591007e78..00000000000 --- a/src/soc/intel/alderlake/pmutil.c +++ /dev/null @@ -1,290 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * Helper functions for dealing with power management registers - * and the differences between PCH variants. - */ - -/* - * This file is created based on Intel Alder Lake Processor PCH Datasheet - * Document number: 621483 - * Chapter number: 4 - */ - -#define __SIMPLE_DEVICE__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * SMI - */ - -const char *const *soc_smi_sts_array(size_t *a) -{ - static const char *const smi_sts_bits[] = { - [BIOS_STS_BIT] = "BIOS", - [LEGACY_USB_STS_BIT] = "LEGACY_USB", - [SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI", - [APM_STS_BIT] = "APM", - [SWSMI_TMR_STS_BIT] = "SWSMI_TMR", - [PM1_STS_BIT] = "PM1", - [GPE0_STS_BIT] = "GPE0", - [GPIO_STS_BIT] = "GPI", - [MCSMI_STS_BIT] = "MCSMI", - [DEVMON_STS_BIT] = "DEVMON", - [TCO_STS_BIT] = "TCO", - [PERIODIC_STS_BIT] = "PERIODIC", - [SERIRQ_SMI_STS_BIT] = "SERIRQ_SMI", - [SMBUS_SMI_STS_BIT] = "SMBUS_SMI", - [PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI", - [MONITOR_STS_BIT] = "MONITOR", - [SPI_SMI_STS_BIT] = "SPI", - [GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK", - [ESPI_SMI_STS_BIT] = "ESPI_SMI", - }; - - *a = ARRAY_SIZE(smi_sts_bits); - return smi_sts_bits; -} - -/* - * TCO - */ - -const char *const *soc_tco_sts_array(size_t *a) -{ - static const char *const tco_sts_bits[] = { - [0] = "NMI2SMI", - [1] = "SW_TCO", - [2] = "TCO_INT", - [3] = "TIMEOUT", - [7] = "NEWCENTURY", - [8] = "BIOSWR", - [9] = "DMISCI", - [10] = "DMISMI", - [12] = "DMISERR", - [13] = "SLVSEL", - [16] = "INTRD_DET", - [17] = "SECOND_TO", - [18] = "BOOT", - [20] = "SMLINK_SLV" - }; - - *a = ARRAY_SIZE(tco_sts_bits); - return tco_sts_bits; -} - -/* - * GPE0 - */ - -const char *const *soc_std_gpe_sts_array(size_t *a) -{ - static const char *const gpe_sts_bits[] = { - [1] = "HOTPLUG", - [2] = "SWGPE", - [6] = "TCO_SCI", - [7] = "SMB_WAK", - [9] = "PCI_EXP", - [10] = "BATLOW", - [11] = "PME", - [12] = "ME", - [13] = "PME_B0", - [14] = "eSPI", - [15] = "GPIO Tier-2", - [16] = "LAN_WAKE", - [18] = "WADT" - }; - - *a = ARRAY_SIZE(gpe_sts_bits); - return gpe_sts_bits; -} - -void pmc_set_disb(void) -{ - /* Set the DISB after DRAM init */ - uint8_t disb_val; - /* Only care about bits [23:16] of register GEN_PMCON_A */ - uint8_t *addr = (uint8_t *)(pmc_mmio_regs() + GEN_PMCON_A + 2); - - disb_val = read8(addr); - disb_val |= (DISB >> 16); - - /* Don't clear bits that are write-1-to-clear */ - disb_val &= ~((MS4V | SUS_PWR_FLR) >> 16); - write8(addr, disb_val); -} - -/* - * PMC controller gets hidden from PCI bus - * during FSP-Silicon init call. Hence PWRMBASE - * can't be accessible using PCI configuration space - * read/write. - */ -uint8_t *pmc_mmio_regs(void) -{ - return (void *)(uintptr_t)PCH_PWRM_BASE_ADDRESS; -} - -uintptr_t soc_read_pmc_base(void) -{ - return (uintptr_t)pmc_mmio_regs(); -} - -uint32_t *soc_pmc_etr_addr(void) -{ - return (uint32_t *)(soc_read_pmc_base() + ETR); -} - -static void pmc_gpe0_different_values(const struct soc_intel_alderlake_config *config) -{ - bool all_zero = (config->pmc_gpe0_dw0 == 0) && - (config->pmc_gpe0_dw1 == 0) && - (config->pmc_gpe0_dw2 == 0); - - /* Check if all values are different AND not all zero */ - bool all_different = (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw1) && - (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw2) && - (config->pmc_gpe0_dw1 != config->pmc_gpe0_dw2); - - assert(all_different || all_zero); -} - -void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2) -{ - DEVTREE_CONST struct soc_intel_alderlake_config *config; - - config = config_of_soc(); - - pmc_gpe0_different_values(config); - - /* Assign to out variable */ - *dw0 = config->pmc_gpe0_dw0; - *dw1 = config->pmc_gpe0_dw1; - *dw2 = config->pmc_gpe0_dw2; -} - -static int rtc_failed(uint32_t gen_pmcon_b) -{ - return !!(gen_pmcon_b & RTC_BATTERY_DEAD); -} - -int soc_get_rtc_failed(void) -{ - const struct chipset_power_state *ps; - - if (acpi_fetch_pm_state(&ps, PS_CLAIMER_RTC) < 0) - return 1; - - return rtc_failed(ps->gen_pmcon_b); -} - -int vbnv_cmos_failed(void) -{ - return rtc_failed(read32(pmc_mmio_regs() + GEN_PMCON_B)); -} - -static inline int deep_s3_enabled(void) -{ - uint32_t deep_s3_pol; - - deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL); - return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS)); -} - -/* Return 0, 3, or 5 to indicate the previous sleep state. */ -int soc_prev_sleep_state(const struct chipset_power_state *ps, int prev_sleep_state) -{ - /* - * Check for any power failure to determine if this a wake from - * S5 because the PCH does not set the WAK_STS bit when waking - * from a true G3 state. - */ - if (!(ps->pm1_sts & WAK_STS) && (ps->gen_pmcon_a & (PWR_FLR | SUS_PWR_FLR))) - prev_sleep_state = ACPI_S5; - - /* - * If waking from S3 determine if deep S3 is enabled. If not, - * need to check both deep sleep well and normal suspend well. - * Otherwise just check deep sleep well. - */ - if (prev_sleep_state == ACPI_S3) { - /* PWR_FLR represents deep sleep power well loss. */ - uint32_t mask = PWR_FLR; - - /* If deep s3 isn't enabled check the suspend well too. */ - if (!deep_s3_enabled()) - mask |= SUS_PWR_FLR; - - if (ps->gen_pmcon_a & mask) - prev_sleep_state = ACPI_S5; - } - - return prev_sleep_state; -} - -void soc_fill_power_state(struct chipset_power_state *ps) -{ - uint8_t *pmc; - - ps->tco1_sts = tco_read_reg(TCO1_STS); - ps->tco2_sts = tco_read_reg(TCO2_STS); - - printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", ps->tco1_sts, ps->tco2_sts); - - pmc = pmc_mmio_regs(); - ps->gen_pmcon_a = read32(pmc + GEN_PMCON_A); - ps->gen_pmcon_b = read32(pmc + GEN_PMCON_B); - ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0); - ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1); - ps->hpr_cause0 = read32(pmc + HPR_CAUSE0); - - printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n", - ps->gen_pmcon_a, ps->gen_pmcon_b); - - printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n", - ps->gblrst_cause[0], ps->gblrst_cause[1]); - - printk(BIOS_DEBUG, "HPR_CAUSE0: %08x\n", ps->hpr_cause0); -} - -/* STM Support */ -uint16_t get_pmbase(void) -{ - return (uint16_t)ACPI_BASE_ADDRESS; -} - -/* - * Set which power state system will be after reapplying - * the power (from G3 State) - */ -void pmc_soc_set_afterg3_en(const bool on) -{ - uint8_t reg8; - uint8_t *const pmcbase = pmc_mmio_regs(); - - reg8 = read8(pmcbase + GEN_PMCON_A); - if (on) - reg8 &= ~SLEEP_AFTER_POWER_FAIL; - else - reg8 |= SLEEP_AFTER_POWER_FAIL; - write8(pmcbase + GEN_PMCON_A, reg8); -} diff --git a/src/soc/intel/alderlake/romstage/fsp_params.c b/src/soc/intel/alderlake/romstage/fsp_params.c index 730b1f82b25..d6224658aef 100644 --- a/src/soc/intel/alderlake/romstage/fsp_params.c +++ b/src/soc/intel/alderlake/romstage/fsp_params.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -152,9 +153,19 @@ static void fill_fspm_igd_params(FSP_M_CONFIG *m_cfg, [DDI_PORT_3] = {&m_cfg->DdiPort3Ddc, &m_cfg->DdiPort3Hpd}, [DDI_PORT_4] = {&m_cfg->DdiPort4Ddc, &m_cfg->DdiPort4Hpd}, }; - m_cfg->InternalGfx = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) && is_devfn_enabled(SA_DEVFN_IGD); - if (m_cfg->InternalGfx) { + + bool igd_enabled = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) + && is_devfn_enabled(SA_DEVFN_IGD); + + /* Probe for no IGD and disable InternalGfx to prevent a crash in FSP-M. */ + if (igd_enabled && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) == 0xffff) { + printk(BIOS_ERR, "igd_enabled is set, but IGD is not present. Disabling IGD.\n"); + igd_enabled = false; + } + + if (igd_enabled) { /* IGD is enabled, set IGD stolen size to 60MB. */ + m_cfg->InternalGfx = 1; m_cfg->IgdDvmt50PreAlloc = get_uint_option("igd_dvmt_prealloc", IGD_SM_60MB); m_cfg->ApertureSize = get_uint_option("igd_aperture_size", IGD_AP_SZ_256MB); /* DP port config */ @@ -168,6 +179,7 @@ static void fill_fspm_igd_params(FSP_M_CONFIG *m_cfg, } } else { /* IGD is disabled, skip IGD init in FSP. */ + m_cfg->InternalGfx = 0; m_cfg->IgdDvmt50PreAlloc = 0; /* DP port config */ m_cfg->DdiPortAConfig = 0; @@ -214,7 +226,7 @@ static void fill_fspm_security_params(FSP_M_CONFIG *m_cfg, { /* Disable BIOS Guard */ m_cfg->BiosGuard = 0; - m_cfg->TmeEnable = CONFIG(INTEL_TME) && is_tme_supported(); + m_cfg->TmeEnable = get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported(); } static void fill_fspm_uart_params(FSP_M_CONFIG *m_cfg, diff --git a/src/soc/intel/alderlake/smihandler.c b/src/soc/intel/alderlake/smihandler.c deleted file mode 100644 index e1fc5a03ad0..00000000000 --- a/src/soc/intel/alderlake/smihandler.c +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include - -int smihandler_soc_disable_busmaster(pci_devfn_t dev) -{ - /* Skip disabling PMC bus master to keep IO decode enabled */ - if (dev == PCH_DEV_PMC) - return 0; - return 1; -} - -const smi_handler_t southbridge_smi[SMI_STS_BITS] = { - [SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep, - [APM_STS_BIT] = smihandler_southbridge_apmc, - [PM1_STS_BIT] = smihandler_southbridge_pm1, - [GPE0_STS_BIT] = smihandler_southbridge_gpe0, - [GPIO_STS_BIT] = smihandler_southbridge_gpi, - [ESPI_SMI_STS_BIT] = smihandler_southbridge_espi, - [MCSMI_STS_BIT] = smihandler_southbridge_mc, -#if CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE) - [TCO_STS_BIT] = smihandler_southbridge_tco, -#endif - [PERIODIC_STS_BIT] = smihandler_southbridge_periodic, - [MONITOR_STS_BIT] = smihandler_southbridge_monitor, -}; diff --git a/src/soc/intel/alderlake/soundwire.c b/src/soc/intel/alderlake/soundwire.c deleted file mode 100644 index 1fbdb4418e1..00000000000 --- a/src/soc/intel/alderlake/soundwire.c +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static const struct soundwire_link link_xtal_38_4 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 4800 * KHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 50, - .default_frame_col_size = 4, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static const struct soundwire_link link_xtal_24 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 6 * MHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 125, - .default_frame_col_size = 2, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static struct intel_soundwire_controller intel_controller = { - .acpi_address = 0x40000000, - .sdw = { - .master_list_count = 4 - } -}; - -int soc_fill_soundwire_controller(struct intel_soundwire_controller **controller) -{ - const struct soundwire_link *link; - enum pch_pmc_xtal xtal = pmc_get_xtal_freq(); - size_t i; - - /* Select link config based on XTAL frequency and set IP clock. */ - switch (xtal) { - case XTAL_24_MHZ: - link = &link_xtal_24; - intel_controller.ip_clock = 24 * MHz; - break; - case XTAL_38_4_MHZ: - link = &link_xtal_38_4; - intel_controller.ip_clock = 38400 * KHz; - break; - case XTAL_19_2_MHZ: - default: - printk(BIOS_ERR, "%s: XTAL not supported: 0x%x\n", __func__, xtal); - return -1; - } - - /* Fill link config in controller map based on selected XTAL. */ - for (i = 0; i < intel_controller.sdw.master_list_count; i++) - memcpy(&intel_controller.sdw.master_list[i], link, sizeof(*link)); - - *controller = &intel_controller; - return 0; -} diff --git a/src/soc/intel/alderlake/spi.c b/src/soc/intel/alderlake/spi.c deleted file mode 100644 index 11494251014..00000000000 --- a/src/soc/intel/alderlake/spi.c +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/* - * This file is created based on Intel Alder Lake Processor PCH Datasheet - * Document number: 621483 - * Chapter number: 7 - */ - -#include -#include -#include - -#define PSF_SPI_DESTINATION_ID 0x23a8 - -int spi_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_GSPI0: - return 1; - case PCH_DEVFN_GSPI1: - return 2; - case PCH_DEVFN_GSPI2: - return 3; - case PCH_DEVFN_GSPI3: - return 4; - } - return -1; -} - -uint32_t soc_get_spi_psf_destination_id(void) -{ - return PSF_SPI_DESTINATION_ID; -} diff --git a/src/soc/intel/alderlake/systemagent.c b/src/soc/intel/alderlake/systemagent.c index be0c6996a49..bbc421b0cb9 100644 --- a/src/soc/intel/alderlake/systemagent.c +++ b/src/soc/intel/alderlake/systemagent.c @@ -116,7 +116,7 @@ void soc_add_configurable_mmio_resources(struct device *dev, int *resource_cnt) } /* TSEG */ - size = sa_get_tseg_size(); + size = CONFIG_SMM_TSEG_SIZE; tseg_base = sa_get_tseg_base(); if (size > 0) set_mmio_resource(&(cfg_rsrc[count++]), tseg_base, size, "TSEG"); diff --git a/src/soc/intel/alderlake/uart.c b/src/soc/intel/alderlake/uart.c deleted file mode 100644 index 2344a6a717d..00000000000 --- a/src/soc/intel/alderlake/uart.c +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * This file is created based on Intel Alder Lake Processor PCH Datasheet - * Document number: 621483 - * Chapter number: 9 - */ - -#include -#include - -const unsigned int uart_devices[] = { - PCH_DEVFN_UART0, - PCH_DEVFN_UART1, - PCH_DEVFN_UART2, -}; - -const int uart_devices_size = ARRAY_SIZE(uart_devices); diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index ef5d4f6b8ad..d48a010342a 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -20,6 +20,7 @@ config SOC_INTEL_APOLLOLAKE select SOC_INTEL_COMMON_NHLT # Misc options select CACHE_MRC_SETTINGS + select DRIVERS_USB_ACPI select EDK2_CPU_TIMER_LIB if PAYLOAD_EDK2 select FAST_SPI_GENERATE_SSDT select FSP_PLATFORM_MEMORY_SETTINGS_VERSIONS @@ -61,11 +62,13 @@ config SOC_INTEL_APOLLOLAKE select SOC_INTEL_COMMON_BLOCK_GPIO_DUAL_ROUTE_SUPPORT select SOC_INTEL_COMMON_BLOCK_GPIO_MULTI_ACPI_DEVICES select SOC_INTEL_COMMON_BLOCK_GPIO_IOSTANDBY + select SOC_INTEL_COMMON_BLOCK_HDA select SOC_INTEL_COMMON_BLOCK_HECI1_DISABLE_USING_PCR select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_BLOCK_PMC_DISCOVERABLE select SOC_INTEL_COMMON_BLOCK_SRAM select SOC_INTEL_COMMON_BLOCK_SA + select SOC_INTEL_COMMON_BLOCK_SATA select SOC_INTEL_COMMON_BLOCK_SCS select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG select SOC_INTEL_COMMON_BLOCK_SMM @@ -324,6 +327,10 @@ config SMM_RESERVED_SIZE hex default 0x100000 +config SMM_TSEG_SIZE + hex + default 0x800000 + config CHIPSET_DEVICETREE string default "soc/intel/apollolake/chipset_glk.cb" if SOC_INTEL_GEMINILAKE diff --git a/src/soc/intel/apollolake/chipset_apl.cb b/src/soc/intel/apollolake/chipset_apl.cb index 03a67765ec1..547cbee2f87 100644 --- a/src/soc/intel/apollolake/chipset_apl.cb +++ b/src/soc/intel/apollolake/chipset_apl.cb @@ -10,40 +10,91 @@ chip soc/intel/apollolake device pci 0d.1 alias pmc off end # PMC device pci 0d.2 alias fast_spi off end # SPI device pci 0d.3 alias sram off end # Shared SRAM - device pci 0e.0 alias hda off end # HDA + device pci 0e.0 alias hda off ops hda_ops end # HDA device pci 0f.0 alias heci1 off end # HECI1 device pci 0f.1 alias heci2 off end # HECI2 device pci 0f.2 alias heci3 off end # HECI3 device pci 11.0 alias ish off end # SensorHub - device pci 12.0 alias sata off end # SATA - device pci 13.0 alias pcie_rp01 off end # PCIE Express Root Port 1 - device pci 13.1 alias pcie_rp02 off end # PCIE Express Root Port 2 - device pci 13.2 alias pcie_rp03 off end # PCIE Express Root Port 3 - device pci 13.3 alias pcie_rp04 off end # PCIE Express Root Port 4 - device pci 14.0 alias pcie_rp05 off end # PCIE Express Root Port 5 - device pci 14.1 alias pcie_rp06 off end # PCIE Express Root Port 6 - device pci 15.0 alias xhci off end # XHCI - device pci 15.1 alias xdci off end # XDCI - device pci 16.0 alias i2c0 off end # I2C0 - device pci 16.1 alias i2c1 off end # I2C1 - device pci 16.2 alias i2c2 off end # I2C2 - device pci 16.3 alias i2c3 off end # I2C3 - device pci 17.0 alias i2c4 off end # I2C4 - device pci 17.1 alias i2c5 off end # I2C5 - device pci 17.2 alias i2c6 off end # I2C6 - device pci 17.3 alias i2c7 off end # I2C7 - device pci 18.0 alias uart0 off end # UART0 - device pci 18.1 alias uart1 off end # UART1 - device pci 18.2 alias uart2 off end # UART2 - device pci 18.3 alias uart3 off end # UART3 - device pci 19.0 alias spi0 off end # SPI0 - device pci 19.1 alias spi1 off end # SPI1 - device pci 19.2 alias spi2 off end # SPI3 + device pci 12.0 alias sata off ops sata_ops end # SATA + device pci 13.0 alias pcie_rp01 off ops pcie_rp_ops end # PCIE Express Root Port 1 + device pci 13.1 alias pcie_rp02 off ops pcie_rp_ops end # PCIE Express Root Port 2 + device pci 13.2 alias pcie_rp03 off ops pcie_rp_ops end # PCIE Express Root Port 3 + device pci 13.3 alias pcie_rp04 off ops pcie_rp_ops end # PCIE Express Root Port 4 + device pci 14.0 alias pcie_rp05 off ops pcie_rp_ops end # PCIE Express Root Port 5 + device pci 14.1 alias pcie_rp06 off ops pcie_rp_ops end # PCIE Express Root Port 6 + device pci 15.0 alias xhci off ops usb_xhci_ops + chip drivers/usb/acpi + register "type" = "UPC_TYPE_HUB" + device usb 0.0 alias xhci_root_hub off + chip drivers/usb/acpi + device usb 2.0 alias usb2_port1 off end + end + chip drivers/usb/acpi + device usb 2.1 alias usb2_port2 off end + end + chip drivers/usb/acpi + device usb 2.2 alias usb2_port3 off end + end + chip drivers/usb/acpi + device usb 2.3 alias usb2_port4 off end + end + chip drivers/usb/acpi + device usb 2.4 alias usb2_port5 off end + end + chip drivers/usb/acpi + device usb 2.5 alias usb2_port6 off end + end + chip drivers/usb/acpi + device usb 2.6 alias usb2_port7 off end + end + chip drivers/usb/acpi + device usb 2.7 alias usb2_port8 off end + end + chip drivers/usb/acpi + device usb 3.0 alias usb3_port1 off end + end + chip drivers/usb/acpi + device usb 3.1 alias usb3_port2 off end + end + chip drivers/usb/acpi + device usb 3.2 alias usb3_port3 off end + end + chip drivers/usb/acpi + device usb 3.3 alias usb3_port4 off end + end + chip drivers/usb/acpi + device usb 3.4 alias usb3_port5 off end + end + chip drivers/usb/acpi + device usb 3.5 alias usb3_port6 off end + end + chip drivers/usb/acpi + device usb 3.6 alias usb3_port7 off end + end + end + end + end # XHCI + device pci 15.1 alias xdci off ops usb_xdci_ops end # XDCI + device pci 16.0 alias i2c0 off ops i2c_dev_ops end # I2C0 + device pci 16.1 alias i2c1 off ops i2c_dev_ops end # I2C1 + device pci 16.2 alias i2c2 off ops i2c_dev_ops end # I2C2 + device pci 16.3 alias i2c3 off ops i2c_dev_ops end # I2C3 + device pci 17.0 alias i2c4 off ops i2c_dev_ops end # I2C4 + device pci 17.1 alias i2c5 off ops i2c_dev_ops end # I2C5 + device pci 17.2 alias i2c6 off ops i2c_dev_ops end # I2C6 + device pci 17.3 alias i2c7 off ops i2c_dev_ops end # I2C7 + device pci 18.0 alias uart0 off ops uart_ops end # UART0 + device pci 18.1 alias uart1 off ops uart_ops end # UART1 + device pci 18.2 alias uart2 off ops uart_ops end # UART2 + device pci 18.3 alias uart3 off ops uart_ops end # UART3 + device pci 19.0 alias spi0 off ops spi_dev_ops end # SPI0 + device pci 19.1 alias spi1 off ops spi_dev_ops end # SPI1 + device pci 19.2 alias spi2 off ops spi_dev_ops end # SPI3 device pci 1a.0 alias pwm off end # PWM - device pci 1b.0 alias sdcard off end # SD Card + device pci 1b.0 alias sdcard off ops sd_ops end # SD Card device pci 1c.0 alias emmc off end # eMMC device pci 1e.0 alias sdio off end # SDIO device pci 1f.0 alias lpc_espi on end # LPC - device pci 1f.1 alias smbus off end # SMBUS + device pci 1f.1 alias smbus off ops smbus_ops end # SMBUS end end diff --git a/src/soc/intel/apollolake/chipset_glk.cb b/src/soc/intel/apollolake/chipset_glk.cb index c6f2db1fe1a..dbbab3dab3b 100644 --- a/src/soc/intel/apollolake/chipset_glk.cb +++ b/src/soc/intel/apollolake/chipset_glk.cb @@ -6,45 +6,99 @@ chip soc/intel/apollolake device pci 00.2 alias npk off end # NorthPeak device pci 02.0 alias igd off end # Integrated Graphics Device device pci 03.0 alias gmm off end # GMM - device pci 0c.0 alias cnvi off end # CNVi + device pci 0c.0 alias cnvi off ops cnvi_wifi_ops end # CNVi device pci 0d.0 alias p2sb off end # P2SB device pci 0d.1 alias pmc off end # PMC device pci 0d.2 alias fast_spi off end # SPI device pci 0d.3 alias sram off end # Shared SRAM - device pci 0e.0 alias hda off end # HDA + device pci 0e.0 alias hda off ops hda_ops end # HDA device pci 0f.0 alias heci1 off end # HECI1 device pci 0f.1 alias heci2 off end # HECI2 device pci 0f.2 alias heci3 off end # HECI3 device pci 11.0 alias ish off end # SensorHub - device pci 12.0 alias sata off end # SATA - device pci 13.0 alias pcie_rp01 off end # PCIE Express Root Port 1 - device pci 13.1 alias pcie_rp02 off end # PCIE Express Root Port 2 - device pci 13.2 alias pcie_rp03 off end # PCIE Express Root Port 3 - device pci 13.3 alias pcie_rp04 off end # PCIE Express Root Port 4 - device pci 14.0 alias pcie_rp05 off end # PCIE Express Root Port 5 - device pci 14.1 alias pcie_rp06 off end # PCIE Express Root Port 6 - device pci 15.0 alias xhci off end # XHCI - device pci 15.1 alias xdci off end # XDCI - device pci 16.0 alias i2c0 off end # I2C0 - device pci 16.1 alias i2c1 off end # I2C1 - device pci 16.2 alias i2c2 off end # I2C2 - device pci 16.3 alias i2c3 off end # I2C3 - device pci 17.0 alias i2c4 off end # I2C4 - device pci 17.1 alias i2c5 off end # I2C5 - device pci 17.2 alias i2c6 off end # I2C6 - device pci 17.3 alias i2c7 off end # I2C7 - device pci 18.0 alias uart0 off end # UART0 - device pci 18.1 alias uart1 off end # UART1 - device pci 18.2 alias uart2 off end # UART2 - device pci 18.3 alias uart3 off end # UART3 - device pci 19.0 alias spi0 off end # SPI0 - device pci 19.1 alias spi1 off end # SPI1 - device pci 19.2 alias spi2 off end # SPI3 + device pci 12.0 alias sata off ops sata_ops end # SATA + device pci 13.0 alias pcie_rp01 off ops pcie_rp_ops end # PCIE Express Root Port 1 + device pci 13.1 alias pcie_rp02 off ops pcie_rp_ops end # PCIE Express Root Port 2 + device pci 13.2 alias pcie_rp03 off ops pcie_rp_ops end # PCIE Express Root Port 3 + device pci 13.3 alias pcie_rp04 off ops pcie_rp_ops end # PCIE Express Root Port 4 + device pci 14.0 alias pcie_rp05 off ops pcie_rp_ops end # PCIE Express Root Port 5 + device pci 14.1 alias pcie_rp06 off ops pcie_rp_ops end # PCIE Express Root Port 6 + device pci 15.0 alias xhci off ops usb_xhci_ops + chip drivers/usb/acpi + register "type" = "UPC_TYPE_HUB" + device usb 0.0 alias xhci_root_hub off + chip drivers/usb/acpi + device usb 2.0 alias usb2_port1 off end + end + chip drivers/usb/acpi + device usb 2.1 alias usb2_port2 off end + end + chip drivers/usb/acpi + device usb 2.2 alias usb2_port3 off end + end + chip drivers/usb/acpi + device usb 2.3 alias usb2_port4 off end + end + chip drivers/usb/acpi + device usb 2.4 alias usb2_port5 off end + end + chip drivers/usb/acpi + device usb 2.5 alias usb2_port6 off end + end + chip drivers/usb/acpi + device usb 2.6 alias usb2_port7 off end + end + chip drivers/usb/acpi + device usb 2.7 alias usb2_port8 off end + end + chip drivers/usb/acpi + device usb 2.8 alias usb2_port9 off end + end + chip drivers/usb/acpi + device usb 3.0 alias usb3_port1 off end + end + chip drivers/usb/acpi + device usb 3.1 alias usb3_port2 off end + end + chip drivers/usb/acpi + device usb 3.2 alias usb3_port3 off end + end + chip drivers/usb/acpi + device usb 3.3 alias usb3_port4 off end + end + chip drivers/usb/acpi + device usb 3.4 alias usb3_port5 off end + end + chip drivers/usb/acpi + device usb 3.5 alias usb3_port6 off end + end + chip drivers/usb/acpi + device usb 3.6 alias usb3_port7 off end + end + end + end + end # XHCI + device pci 15.1 alias xdci off ops usb_xdci_ops end # XDCI + device pci 16.0 alias i2c0 off ops i2c_dev_ops end # I2C0 + device pci 16.1 alias i2c1 off ops i2c_dev_ops end # I2C1 + device pci 16.2 alias i2c2 off ops i2c_dev_ops end # I2C2 + device pci 16.3 alias i2c3 off ops i2c_dev_ops end # I2C3 + device pci 17.0 alias i2c4 off ops i2c_dev_ops end # I2C4 + device pci 17.1 alias i2c5 off ops i2c_dev_ops end # I2C5 + device pci 17.2 alias i2c6 off ops i2c_dev_ops end # I2C6 + device pci 17.3 alias i2c7 off ops i2c_dev_ops end # I2C7 + device pci 18.0 alias uart0 off ops uart_ops end # UART0 + device pci 18.1 alias uart1 off ops uart_ops end # UART1 + device pci 18.2 alias uart2 off ops uart_ops end # UART2 + device pci 18.3 alias uart3 off ops uart_ops end # UART3 + device pci 19.0 alias spi0 off ops spi_dev_ops end # SPI0 + device pci 19.1 alias spi1 off ops spi_dev_ops end # SPI1 + device pci 19.2 alias spi2 off ops spi_dev_ops end # SPI3 device pci 1a.0 alias pwm off end # PWM device pci 1c.0 alias emmc off end # eMMC device pci 1d.0 alias ufs off end # UFS device pci 1e.0 alias sdio off end # SDIO device pci 1f.0 alias lpc_espi on end # LPC - device pci 1f.1 alias smbus on end # SMBUS + device pci 1f.1 alias smbus on ops smbus_ops end # SMBUS end end diff --git a/src/soc/intel/apollolake/cpu.c b/src/soc/intel/apollolake/cpu.c index fb95009f7d8..ee003805fd2 100644 --- a/src/soc/intel/apollolake/cpu.c +++ b/src/soc/intel/apollolake/cpu.c @@ -162,6 +162,11 @@ static void pre_mp_init(void) fsps_load(); return; } + + /* Make sure BSP is using the microcode from cbfs */ + const struct microcode *microcode_patch = intel_microcode_find(); + intel_microcode_load_unlocked(microcode_patch); + x86_setup_mtrrs_with_detect(); x86_mtrr_check(); } @@ -188,13 +193,14 @@ int get_cpu_count(void) return num_virt_cores; } -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); - *parallel = 1; + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); - /* Make sure BSP is using the microcode from cbfs */ - intel_microcode_load_unlocked(*microcode); + *microcode = microcode_file; + *parallel = 1; } #endif diff --git a/src/soc/intel/apollolake/include/soc/cfr.h b/src/soc/intel/apollolake/include/soc/cfr.h index df4a9200cc3..7cef8127dcf 100644 --- a/src/soc/intel/apollolake/include/soc/cfr.h +++ b/src/soc/intel/apollolake/include/soc/cfr.h @@ -11,39 +11,27 @@ #include /* Legacy 8254 Timer */ -static const struct sm_object legacy_8254_timer = SM_DECLARE_ENUM({ +static const struct sm_object legacy_8254_timer = SM_DECLARE_BOOL({ .opt_name = "legacy_8254_timer", .ui_name = "Legacy 8254 Timer", .ui_helptext = "Enable the legacy 8254 timer by disabling clock gating.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = false, }); /* S0ix Enable */ -static const struct sm_object s0ix_enable = SM_DECLARE_ENUM({ +static const struct sm_object s0ix_enable = SM_DECLARE_BOOL({ .opt_name = "s0ix_enable", .ui_name = "Modern Standby (S0ix)", .ui_helptext = "Enabled: use Modern Standby / S0ix. Disabled: use APCI S3 sleep", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* VT-d */ -static const struct sm_object vtd = SM_DECLARE_ENUM({ +static const struct sm_object vtd = SM_DECLARE_BOOL({ .opt_name = "vtd", .ui_name = "VT-d", .ui_helptext = "Enable or disable Intel VT-d (virtualization)", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); #endif /* _APOLLOLAKE_CFR_H_ */ diff --git a/src/soc/intel/baytrail/acpi/xhci.asl b/src/soc/intel/baytrail/acpi/xhci.asl index 368f34faad7..4e1be831b9a 100644 --- a/src/soc/intel/baytrail/acpi/xhci.asl +++ b/src/soc/intel/baytrail/acpi/xhci.asl @@ -12,18 +12,18 @@ Device (XHCI) // GPLD: Generate Port Location Data (PLD) Method (GPLD, 1, Serialized) { - Name (PCKG, Package (0x01) { + Local0 = Package () { Buffer (0x10) {} - }) + } - // REV: Revision 0x02 for ACPI 5.0 - CreateField (DerefOf (PCKG[0]), 0, 0x07, REV) - REV = 0x02 + // REV: Revision 2 for ACPI 5.0 + CreateField (DerefOf (Local0[0]), 0, 7, REV) + REV = 2 // VISI: Port visibility to user per port - CreateField (DerefOf (PCKG[0]), 0x40, 1, VISI) + CreateField (DerefOf (Local0[0]), 0x40, 1, VISI) VISI = Arg0 - Return (PCKG) + Return (Local0) } Device (PRT1) { Name (_ADR, 1) } diff --git a/src/soc/intel/baytrail/cpu.c b/src/soc/intel/baytrail/cpu.c index 2a4616cec35..7408eb7c642 100644 --- a/src/soc/intel/baytrail/cpu.c +++ b/src/soc/intel/baytrail/cpu.c @@ -146,11 +146,15 @@ static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, *smm_save_state_size = sizeof(em64t100_smm_state_save_area_t); } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { const struct pattrs *pattrs = pattrs_get(); + const struct microcode *microcode_file = pattrs->microcode_patch; - *microcode = pattrs->microcode_patch; + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/soc/intel/braswell/cpu.c b/src/soc/intel/braswell/cpu.c index 23663c3c715..f5e985396bb 100644 --- a/src/soc/intel/braswell/cpu.c +++ b/src/soc/intel/braswell/cpu.c @@ -146,11 +146,15 @@ static void get_smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, *smm_save_state_size = sizeof(em64t100_smm_state_save_area_t); } -static void get_microcode_info(const void **microcode, int *parallel) +static void get_microcode_info(const void **microcode, size_t *size, int *parallel) { const struct pattrs *pattrs = pattrs_get(); + const struct microcode *microcode_file = pattrs->microcode_patch; - *microcode = pattrs->microcode_patch; + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = !intel_ht_supported(); } diff --git a/src/soc/intel/broadwell/acpi.c b/src/soc/intel/broadwell/acpi.c deleted file mode 100644 index 4c1cdf33921..00000000000 --- a/src/soc/intel/broadwell/acpi.c +++ /dev/null @@ -1,102 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static unsigned long acpi_fill_dmar(unsigned long current) -{ - struct device *const igfx_dev = pcidev_path_on_root(SA_DEVFN_IGD); - const u32 gfxvtbar = mchbar_read32(GFXVTBAR) & ~0xfff; - const u32 vtvc0bar = mchbar_read32(VTVC0BAR) & ~0xfff; - const bool gfxvten = mchbar_read32(GFXVTBAR) & 0x1; - const bool vtvc0en = mchbar_read32(VTVC0BAR) & 0x1; - - /* iGFX has to be enabled; GFXVTBAR set, enabled, in 32-bit space */ - const bool emit_igd = - igfx_dev && igfx_dev->enabled && - gfxvtbar && gfxvten && - !mchbar_read32(GFXVTBAR + 4); - - /* First, add DRHD entries */ - if (emit_igd) { - const unsigned long tmp = current; - - current += acpi_create_dmar_drhd_4k(current, 0, 0, gfxvtbar); - current += acpi_create_dmar_ds_pci(current, 0, 2, 0); - - acpi_dmar_drhd_fixup(tmp, current); - } - - /* VTVC0BAR has to be set, enabled, and in 32-bit space */ - if (vtvc0bar && vtvc0en && !mchbar_read32(VTVC0BAR + 4)) { - const unsigned long tmp = current; - current += acpi_create_dmar_drhd_4k(current, - DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar); - current += acpi_create_dmar_ds_ioapic_from_hw(current, - IO_APIC_ADDR, PCH_IOAPIC_PCI_BUS, PCH_IOAPIC_PCI_SLOT, 0); - size_t i; - for (i = 0; i < 8; ++i) - current += acpi_create_dmar_ds_msi_hpet(current, - 0, PCH_HPET_PCI_BUS, - PCH_HPET_PCI_SLOT, i); - acpi_dmar_drhd_fixup(tmp, current); - } - - /* Then, add RMRR entries after all DRHD entries */ - if (emit_igd) { - const unsigned long tmp = current; - - const struct device *sa_dev = pcidev_on_root(0, 0); - - /* Bit 0 is lock bit, not part of address */ - const u32 tolud = pci_read_config32(sa_dev, TOLUD) & ~1; - const u32 bgsm = pci_read_config32(sa_dev, BGSM) & ~1; - - current += acpi_create_dmar_rmrr(current, 0, bgsm, tolud - 1); - current += acpi_create_dmar_ds_pci(current, 0, 2, 0); - acpi_dmar_rmrr_fixup(tmp, current); - } - - return current; -} - -unsigned long northbridge_write_acpi_tables(const struct device *const dev, - unsigned long current, - struct acpi_rsdp *const rsdp) -{ - /* Create DMAR table only if we have VT-d capability. */ - const u32 capid0_a = pci_read_config32(dev, CAPID0_A); - if (capid0_a & VTD_DISABLE) - return current; - - acpi_dmar_t *const dmar = (acpi_dmar_t *)current; - printk(BIOS_DEBUG, "ACPI: * DMAR\n"); - acpi_create_dmar(dmar, DMAR_INTR_REMAP, acpi_fill_dmar); - current += dmar->header.length; - current = acpi_align_current(current); - acpi_add_table(rsdp, dmar); - - return current; -} - -size_t size_of_dnvs(void) -{ - return sizeof(struct device_nvs); -} diff --git a/src/soc/intel/broadwell/bootblock.c b/src/soc/intel/broadwell/bootblock.c deleted file mode 100644 index 8c851cac5de..00000000000 --- a/src/soc/intel/broadwell/bootblock.c +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include - -static uint32_t encode_pciexbar_length(void) -{ - switch (CONFIG_ECAM_MMCONF_BUS_NUMBER) { - case 256: return 0 << 1; - case 128: return 1 << 1; - case 64: return 2 << 1; - default: return dead_code_t(uint32_t); - } -} - -void bootblock_early_northbridge_init(void) -{ - /* - * The "io" variant of the config access is explicitly used to setup the - * PCIEXBAR because CONFIG(ECAM_MMCONF_SUPPORT) is set to true. That way, all - * subsequent non-explicit config accesses use MCFG. This code also assumes - * that bootblock_northbridge_init() is the first thing called in the non-asm - * boot block code. The final assumption is that no assembly code is using the - * CONFIG(ECAM_MMCONF_SUPPORT) option to do PCI config accesses. - * - * The PCIEXBAR is assumed to live in the memory mapped IO space under 4GiB. - */ - const uint32_t reg = CONFIG_ECAM_MMCONF_BASE_ADDRESS | encode_pciexbar_length() | 1; - pci_io_write_config32(HOST_BRIDGE, PCIEXBAR + 4, 0); - pci_io_write_config32(HOST_BRIDGE, PCIEXBAR, reg); -} diff --git a/src/soc/intel/broadwell/pch/Makefile.mk b/src/soc/intel/broadwell/pch/Makefile.mk deleted file mode 100644 index be2f4a42927..00000000000 --- a/src/soc/intel/broadwell/pch/Makefile.mk +++ /dev/null @@ -1,45 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only -bootblock-y += bootblock.c - -ramstage-y += adsp.c -romstage-y += early_pch.c -ramstage-$(CONFIG_ELOG) += elog.c -ramstage-y += finalize.c -ramstage-y += ../../../../southbridge/intel/lynxpoint/lp_gpio.c -romstage-y += ../../../../southbridge/intel/lynxpoint/lp_gpio.c -verstage-y += ../../../../southbridge/intel/lynxpoint/lp_gpio.c -smm-y += ../../../../southbridge/intel/lynxpoint/lp_gpio.c -ramstage-y += hda.c -ramstage-y += ../../../../southbridge/intel/lynxpoint/hda_verb.c -ramstage-y += ../../../../southbridge/intel/lynxpoint/iobp.c -romstage-y += ../../../../southbridge/intel/lynxpoint/iobp.c -ramstage-y += fadt.c -ramstage-y += lpc.c -ramstage-y += me.c -ramstage-y += me_status.c -romstage-y += me_status.c -ramstage-y += pch.c -romstage-y += pch.c -ramstage-y += pcie.c -ramstage-y += pmutil.c -romstage-y += pmutil.c -smm-y += pmutil.c -verstage-y += pmutil.c -romstage-y += power_state.c -ramstage-y += ramstage.c -ramstage-y += sata.c -ramstage-y += serialio.c -ramstage-y += ../../../../southbridge/intel/lynxpoint/smbus.c -ramstage-y += smi.c -smm-y += smihandler.c -bootblock-y += usb_debug.c -romstage-y += usb_debug.c -ramstage-y += usb_debug.c -ramstage-y += usb_ehci.c -ramstage-y += usb_xhci.c -smm-y += usb_xhci.c - -bootblock-$(CONFIG_SERIALIO_UART_CONSOLE) += ../../../../southbridge/intel/lynxpoint/iobp.c -bootblock-$(CONFIG_SERIALIO_UART_CONSOLE) += ../../../../southbridge/intel/lynxpoint/uart_init.c -all-$(CONFIG_SERIALIO_UART_CONSOLE) += ../../../../southbridge/intel/lynxpoint/uart.c -smm-$(CONFIG_SERIALIO_UART_CONSOLE) += ../../../../southbridge/intel/lynxpoint/uart.c diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index 738371bc1b1..cd1eb247606 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -59,6 +59,11 @@ config SOC_INTEL_CANNONLAKE_BASE select SOC_INTEL_COMMON_BLOCK_THERMAL_PCI_DEV select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_NHLT select SOC_INTEL_COMMON_PCH_CLIENT diff --git a/src/soc/intel/cannonlake/Makefile.mk b/src/soc/intel/cannonlake/Makefile.mk index 96c02074ef7..f869176ca77 100644 --- a/src/soc/intel/cannonlake/Makefile.mk +++ b/src/soc/intel/cannonlake/Makefile.mk @@ -10,22 +10,15 @@ bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c bootblock-y += pmutil.c bootblock-y += bootblock/report_platform.c -bootblock-y += gspi.c -bootblock-y += i2c.c bootblock-y += spi.c bootblock-y += lpc.c bootblock-y += p2sb.c -bootblock-y += uart.c romstage-y += cnl_memcfg_init.c -romstage-y += gspi.c -romstage-y += i2c.c romstage-y += lpc.c romstage-y += pcie_rp.c romstage-y += pmutil.c -romstage-y += reset.c romstage-y += spi.c -romstage-y += uart.c ramstage-y += acpi.c ramstage-y += chip.c @@ -34,8 +27,6 @@ ramstage-y += elog.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += graphics.c -ramstage-y += gspi.c -ramstage-y += i2c.c ramstage-y += lockdown.c ramstage-y += lpc.c ramstage-y += nhlt.c @@ -43,10 +34,8 @@ ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c ramstage-y += pmutil.c -ramstage-y += reset.c ramstage-y += spi.c ramstage-y += systemagent.c -ramstage-y += uart.c ramstage-y += vr_config.c ramstage-y += sd.c ramstage-y += xhci.c @@ -55,20 +44,13 @@ smm-y += elog.c smm-y += p2sb.c smm-y += pmutil.c smm-y += smihandler.c -smm-y += uart.c smm-y += xhci.c postcar-y += pmutil.c -postcar-y += i2c.c -postcar-y += gspi.c postcar-y += spi.c -postcar-y += uart.c -verstage-y += gspi.c -verstage-y += i2c.c verstage-y += pmutil.c verstage-y += spi.c -verstage-y += uart.c ifeq ($(CONFIG_SOC_INTEL_CANNONLAKE_PCH_H),y) bootblock-y += gpio_cnp_h.c diff --git a/src/soc/intel/cannonlake/chipset.cb b/src/soc/intel/cannonlake/chipset.cb index b33aadfd32f..ff68963c3e6 100644 --- a/src/soc/intel/cannonlake/chipset.cb +++ b/src/soc/intel/cannonlake/chipset.cb @@ -15,9 +15,9 @@ chip soc/intel/cannonlake device pci 08.0 alias gna off end # Gaussian mixture model, Neural network accelerator device pci 12.0 alias thermal off end # Thermal Subsystem device pci 12.5 alias ufs off end # UFS SCS - device pci 12.6 alias gspi2 off end # GSPI #2 + device pci 12.6 alias gspi2 off ops spi_dev_ops end # GSPI #2 device pci 13.0 alias ish off end # ISH - device pci 14.0 alias xhci off # USB xHCI + device pci 14.0 alias xhci off ops usb_xhci_ops # USB xHCI chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off @@ -78,50 +78,50 @@ chip soc/intel/cannonlake end end end - device pci 14.1 alias xdci off end # USB xDCI (OTG) + device pci 14.1 alias xdci off ops usb_xdci_ops end # USB xDCI (OTG) device pci 14.2 alias shared_sram off end # Shared SRAM - device pci 14.3 alias cnvi_wifi off end # CNVi Wifi - device pci 14.5 alias sdxc off end # SDCard - device pci 15.0 alias i2c0 off end # I2C #0 - device pci 15.1 alias i2c1 off end # I2C #1 - device pci 15.2 alias i2c2 off end # I2C #2 - device pci 15.3 alias i2c3 off end # I2C #3 + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end # CNVi Wifi + device pci 14.5 alias sdxc off ops sd_ops end # SDCard + device pci 15.0 alias i2c0 off ops i2c_dev_ops end # I2C #0 + device pci 15.1 alias i2c1 off ops i2c_dev_ops end # I2C #1 + device pci 15.2 alias i2c2 off ops i2c_dev_ops end # I2C #2 + device pci 15.3 alias i2c3 off ops i2c_dev_ops end # I2C #3 device pci 16.0 alias heci1 on end # Management Engine Interface 1 device pci 16.1 alias heci2 off end # Management Engine Interface 2 device pci 16.2 alias csme_ider off end # Management Engine IDE-R device pci 16.3 alias csme_ktr off end # Management Engine KT Redirection device pci 16.4 alias heci3 off end # Management Engine Interface 3 device pci 16.5 alias heci4 off end # Management Engine Interface 4 - device pci 17.0 alias sata off end # SATA - device pci 19.0 alias i2c4 off end # I2C #4 - device pci 19.1 alias i2c5 off end # I2C #5 - device pci 19.2 alias uart2 off end # UART #2 + device pci 17.0 alias sata off ops sata_ops end # SATA + device pci 19.0 alias i2c4 off ops i2c_dev_ops end # I2C #4 + device pci 19.1 alias i2c5 off ops i2c_dev_ops end # I2C #5 + device pci 19.2 alias uart2 off ops uart_ops end # UART #2 device pci 1a.0 alias emmc off end # eMMC - device pci 1c.0 alias pcie_rp1 off end # PCI Express Port 1 - device pci 1c.1 alias pcie_rp2 off end # PCI Express Port 2 - device pci 1c.2 alias pcie_rp3 off end # PCI Express Port 3 - device pci 1c.3 alias pcie_rp4 off end # PCI Express Port 4 - device pci 1c.4 alias pcie_rp5 off end # PCI Express Port 5 - device pci 1c.5 alias pcie_rp6 off end # PCI Express Port 6 - device pci 1c.6 alias pcie_rp7 off end # PCI Express Port 7 - device pci 1c.7 alias pcie_rp8 off end # PCI Express Port 8 - device pci 1d.0 alias pcie_rp9 off end # PCI Express Port 9 - device pci 1d.1 alias pcie_rp10 off end # PCI Express Port 10 - device pci 1d.2 alias pcie_rp11 off end # PCI Express Port 11 - device pci 1d.3 alias pcie_rp12 off end # PCI Express Port 12 - device pci 1d.4 alias pcie_rp13 off end # PCI Express Port 13 - device pci 1d.5 alias pcie_rp14 off end # PCI Express Port 14 - device pci 1d.6 alias pcie_rp15 off end # PCI Express Port 15 - device pci 1d.7 alias pcie_rp16 off end # PCI Express Port 16 - device pci 1e.0 alias uart0 off end # UART #0 - device pci 1e.1 alias uart1 off end # UART #1 - device pci 1e.2 alias gspi0 off end # GSPI #0 - device pci 1e.3 alias gspi1 off end # GSPI #1 + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end # PCI Express Port 1 + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end # PCI Express Port 2 + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end # PCI Express Port 3 + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end # PCI Express Port 4 + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end # PCI Express Port 5 + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end # PCI Express Port 6 + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end # PCI Express Port 7 + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end # PCI Express Port 8 + device pci 1d.0 alias pcie_rp9 off ops pcie_rp_ops end # PCI Express Port 9 + device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end # PCI Express Port 10 + device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end # PCI Express Port 11 + device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end # PCI Express Port 12 + device pci 1d.4 alias pcie_rp13 off ops pcie_rp_ops end # PCI Express Port 13 + device pci 1d.5 alias pcie_rp14 off ops pcie_rp_ops end # PCI Express Port 14 + device pci 1d.6 alias pcie_rp15 off ops pcie_rp_ops end # PCI Express Port 15 + device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end # PCI Express Port 16 + device pci 1e.0 alias uart0 off ops uart_ops end # UART #0 + device pci 1e.1 alias uart1 off ops uart_ops end # UART #1 + device pci 1e.2 alias gspi0 off ops spi_dev_ops end # GSPI #0 + device pci 1e.3 alias gspi1 off ops spi_dev_ops end # GSPI #1 device pci 1f.0 alias lpc_espi on end # LPC Interface device pci 1f.1 alias p2sb hidden end # P2SB device pci 1f.2 alias pmc hidden end # Power Management Controller - device pci 1f.3 alias hda off end # Intel HDA - device pci 1f.4 alias smbus off end # SMBus + device pci 1f.3 alias hda off ops hda_ops end # Intel HDA + device pci 1f.4 alias smbus off ops smbus_ops end # SMBus device pci 1f.5 alias fast_spi on end # PCH SPI device pci 1f.6 alias gbe off end # GbE device pci 1f.7 alias tracehub off end # TraceHub diff --git a/src/soc/intel/cannonlake/chipset_pch_h.cb b/src/soc/intel/cannonlake/chipset_pch_h.cb index 3904697b118..de36773c501 100644 --- a/src/soc/intel/cannonlake/chipset_pch_h.cb +++ b/src/soc/intel/cannonlake/chipset_pch_h.cb @@ -15,9 +15,9 @@ chip soc/intel/cannonlake device pci 08.0 alias gna off end # Gaussian mixture model, Neural network accelerator device pci 12.0 alias thermal off end # Thermal Subsystem device pci 12.5 alias ufs off end # UFS SCS - device pci 12.6 alias gspi2 off end # GSPI #2 + device pci 12.6 alias gspi2 off ops spi_dev_ops end # GSPI #2 device pci 13.0 alias ish off end # ISH - device pci 14.0 alias xhci off # USB xHCI + device pci 14.0 alias xhci off ops usb_xhci_ops # USB xHCI chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off @@ -102,60 +102,60 @@ chip soc/intel/cannonlake end end end - device pci 14.1 alias xdci off end # USB xDCI (OTG) + device pci 14.1 alias xdci off ops usb_xdci_ops end # USB xDCI (OTG) device pci 14.2 alias shared_sram off end # Shared SRAM - device pci 14.3 alias cnvi_wifi off end # CNVi Wifi - device pci 14.5 alias sdxc off end # SDCard - device pci 15.0 alias i2c0 off end # I2C #0 - device pci 15.1 alias i2c1 off end # I2C #1 - device pci 15.2 alias i2c2 off end # I2C #2 - device pci 15.3 alias i2c3 off end # I2C #3 + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end # CNVi Wifi + device pci 14.5 alias sdxc off ops sd_ops end # SDCard + device pci 15.0 alias i2c0 off ops i2c_dev_ops end # I2C #0 + device pci 15.1 alias i2c1 off ops i2c_dev_ops end # I2C #1 + device pci 15.2 alias i2c2 off ops i2c_dev_ops end # I2C #2 + device pci 15.3 alias i2c3 off ops i2c_dev_ops end # I2C #3 device pci 16.0 alias heci1 on end # Management Engine Interface 1 device pci 16.1 alias heci2 off end # Management Engine Interface 2 device pci 16.2 alias csme_ider off end # Management Engine IDE-R device pci 16.3 alias csme_ktr off end # Management Engine KT Redirection device pci 16.4 alias heci3 off end # Management Engine Interface 3 device pci 16.5 alias heci4 off end # Management Engine Interface 4 - device pci 17.0 alias sata off end # SATA - device pci 19.0 alias i2c4 off end # I2C #4 - device pci 19.1 alias i2c5 off end # I2C #5 + device pci 17.0 alias sata off ops sata_ops end # SATA + device pci 19.0 alias i2c4 off ops i2c_dev_ops end # I2C #4 + device pci 19.1 alias i2c5 off ops i2c_dev_ops end # I2C #5 device pci 19.2 alias uart2 off # UART #2 ops uart_ops end device pci 1a.0 alias emmc off end # eMMC - device pci 1b.0 alias pcie_rp17 off end # PCI Express Port 17 - device pci 1b.1 alias pcie_rp18 off end # PCI Express Port 18 - device pci 1b.2 alias pcie_rp19 off end # PCI Express Port 19 - device pci 1b.3 alias pcie_rp20 off end # PCI Express Port 20 - device pci 1b.4 alias pcie_rp21 off end # PCI Express Port 21 - device pci 1b.5 alias pcie_rp22 off end # PCI Express Port 22 - device pci 1b.6 alias pcie_rp23 off end # PCI Express Port 23 - device pci 1b.7 alias pcie_rp24 off end # PCI Express Port 24 - device pci 1c.0 alias pcie_rp1 off end # PCI Express Port 1 - device pci 1c.1 alias pcie_rp2 off end # PCI Express Port 2 - device pci 1c.2 alias pcie_rp3 off end # PCI Express Port 3 - device pci 1c.3 alias pcie_rp4 off end # PCI Express Port 4 - device pci 1c.4 alias pcie_rp5 off end # PCI Express Port 5 - device pci 1c.5 alias pcie_rp6 off end # PCI Express Port 6 - device pci 1c.6 alias pcie_rp7 off end # PCI Express Port 7 - device pci 1c.7 alias pcie_rp8 off end # PCI Express Port 8 - device pci 1d.0 alias pcie_rp9 off end # PCI Express Port 9 - device pci 1d.1 alias pcie_rp10 off end # PCI Express Port 10 - device pci 1d.2 alias pcie_rp11 off end # PCI Express Port 11 - device pci 1d.3 alias pcie_rp12 off end # PCI Express Port 12 - device pci 1d.4 alias pcie_rp13 off end # PCI Express Port 13 - device pci 1d.5 alias pcie_rp14 off end # PCI Express Port 14 - device pci 1d.6 alias pcie_rp15 off end # PCI Express Port 15 - device pci 1d.7 alias pcie_rp16 off end # PCI Express Port 16 - device pci 1e.0 alias uart0 off end # UART #0 - device pci 1e.1 alias uart1 off end # UART #1 - device pci 1e.2 alias gspi0 off end # GSPI #0 - device pci 1e.3 alias gspi1 off end # GSPI #1 + device pci 1b.0 alias pcie_rp17 off ops pcie_rp_ops end # PCI Express Port 17 + device pci 1b.1 alias pcie_rp18 off ops pcie_rp_ops end # PCI Express Port 18 + device pci 1b.2 alias pcie_rp19 off ops pcie_rp_ops end # PCI Express Port 19 + device pci 1b.3 alias pcie_rp20 off ops pcie_rp_ops end # PCI Express Port 20 + device pci 1b.4 alias pcie_rp21 off ops pcie_rp_ops end # PCI Express Port 21 + device pci 1b.5 alias pcie_rp22 off ops pcie_rp_ops end # PCI Express Port 22 + device pci 1b.6 alias pcie_rp23 off ops pcie_rp_ops end # PCI Express Port 23 + device pci 1b.7 alias pcie_rp24 off ops pcie_rp_ops end # PCI Express Port 24 + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end # PCI Express Port 1 + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end # PCI Express Port 2 + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end # PCI Express Port 3 + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end # PCI Express Port 4 + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end # PCI Express Port 5 + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end # PCI Express Port 6 + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end # PCI Express Port 7 + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end # PCI Express Port 8 + device pci 1d.0 alias pcie_rp9 off ops pcie_rp_ops end # PCI Express Port 9 + device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end # PCI Express Port 10 + device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end # PCI Express Port 11 + device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end # PCI Express Port 12 + device pci 1d.4 alias pcie_rp13 off ops pcie_rp_ops end # PCI Express Port 13 + device pci 1d.5 alias pcie_rp14 off ops pcie_rp_ops end # PCI Express Port 14 + device pci 1d.6 alias pcie_rp15 off ops pcie_rp_ops end # PCI Express Port 15 + device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end # PCI Express Port 16 + device pci 1e.0 alias uart0 off ops uart_ops end # UART #0 + device pci 1e.1 alias uart1 off ops uart_ops end # UART #1 + device pci 1e.2 alias gspi0 off ops spi_dev_ops end # GSPI #0 + device pci 1e.3 alias gspi1 off ops spi_dev_ops end # GSPI #1 device pci 1f.0 alias lpc_espi on end # LPC Interface device pci 1f.1 alias p2sb hidden end # P2SB device pci 1f.2 alias pmc hidden end # Power Management Controller - device pci 1f.3 alias hda off end # Intel HDA - device pci 1f.4 alias smbus off end # SMBus + device pci 1f.3 alias hda off ops hda_ops end # Intel HDA + device pci 1f.4 alias smbus off ops smbus_ops end # SMBus device pci 1f.5 alias fast_spi on end # PCH SPI device pci 1f.6 alias gbe off end # GbE device pci 1f.7 alias tracehub off end # TraceHub diff --git a/src/soc/intel/cannonlake/gspi.c b/src/soc/intel/cannonlake/gspi.c deleted file mode 100644 index 61ad2608db2..00000000000 --- a/src/soc/intel/cannonlake/gspi.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCH_DEVFN_GSPI0; - case 1: - return PCH_DEVFN_GSPI1; - case 2: - return PCH_DEVFN_GSPI2; - } - return -1; -} diff --git a/src/soc/intel/cannonlake/i2c.c b/src/soc/intel/cannonlake/i2c.c deleted file mode 100644 index c13a1a60995..00000000000 --- a/src/soc/intel/cannonlake/i2c.c +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_I2C0: - return 0; - case PCH_DEVFN_I2C1: - return 1; - case PCH_DEVFN_I2C2: - return 2; - case PCH_DEVFN_I2C3: - return 3; - case PCH_DEVFN_I2C4: - return 4; - case PCH_DEVFN_I2C5: - return 5; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCH_DEVFN_I2C0; - case 1: - return PCH_DEVFN_I2C1; - case 2: - return PCH_DEVFN_I2C2; - case 3: - return PCH_DEVFN_I2C3; - case 4: - return PCH_DEVFN_I2C4; - case 5: - return PCH_DEVFN_I2C5; - } - return -1; -} diff --git a/src/soc/intel/cannonlake/include/soc/cfr.h b/src/soc/intel/cannonlake/include/soc/cfr.h index d177d2db831..80ddd18b2e3 100644 --- a/src/soc/intel/cannonlake/include/soc/cfr.h +++ b/src/soc/intel/cannonlake/include/soc/cfr.h @@ -11,27 +11,19 @@ #include /* FSP hyperthreading */ -static const struct sm_object hyper_threading = SM_DECLARE_ENUM({ +static const struct sm_object hyper_threading = SM_DECLARE_BOOL({ .opt_name = "hyper_threading", .ui_name = "Hyper-Threading", .ui_helptext = "Enable or disable Hyper-Threading", .default_value = CONFIG(FSP_HYPERTHREADING), - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, }); /* IGD Enabled */ -static const struct sm_object igd_enabled = SM_DECLARE_ENUM({ +static const struct sm_object igd_enabled = SM_DECLARE_BOOL({ .opt_name = "igd_enabled", .ui_name = "Enable the Intel iGPU", .ui_helptext = "Enable or disable the Intel iGPU", .default_value = !CONFIG(SOC_INTEL_DISABLE_IGD), - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, }); /* IGD Aperture Size */ @@ -45,7 +37,7 @@ static const struct sm_object igd_aperture = SM_DECLARE_ENUM({ { "256 MB", IGD_AP_SZ_256MB }, { "512 MB", IGD_AP_SZ_512MB }, SM_ENUM_VALUE_END }, -}, WITH_DEP_VALUES(&igd_enabled, 1)); +}, WITH_DEP_VALUES(&igd_enabled, true)); /* IGD DVMT pre-allocated memory */ static const struct sm_object igd_dvmt = SM_DECLARE_ENUM({ @@ -59,42 +51,30 @@ static const struct sm_object igd_dvmt = SM_DECLARE_ENUM({ { "96 MB", IGD_SM_96MB }, { "128 MB", IGD_SM_128MB }, SM_ENUM_VALUE_END }, -}, WITH_DEP_VALUES(&igd_enabled, 1)); +}, WITH_DEP_VALUES(&igd_enabled, true)); /* Legacy 8254 Timer */ -static const struct sm_object legacy_8254_timer = SM_DECLARE_ENUM({ +static const struct sm_object legacy_8254_timer = SM_DECLARE_BOOL({ .opt_name = "legacy_8254_timer", .ui_name = "Legacy 8254 Timer", .ui_helptext = "Enable the legacy 8254 timer by disabling clock gating.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = false, }); /* S0ix Enable */ -static const struct sm_object s0ix_enable = SM_DECLARE_ENUM({ +static const struct sm_object s0ix_enable = SM_DECLARE_BOOL({ .opt_name = "s0ix_enable", .ui_name = "Modern Standby (S0ix)", .ui_helptext = "Enabled: use Modern Standby / S0ix. Disabled: use ACPI S3 sleep", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* VT-d */ -static const struct sm_object vtd = SM_DECLARE_ENUM({ +static const struct sm_object vtd = SM_DECLARE_BOOL({ .opt_name = "vtd", .ui_name = "VT-d", .ui_helptext = "Enable or disable Intel VT-d (virtualization)", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); #endif /* CANNONLAKE_CFR_H */ diff --git a/src/soc/intel/cannonlake/include/soc/pci_devs.h b/src/soc/intel/cannonlake/include/soc/pci_devs.h index 6998eb10227..a099294cf23 100644 --- a/src/soc/intel/cannonlake/include/soc/pci_devs.h +++ b/src/soc/intel/cannonlake/include/soc/pci_devs.h @@ -204,4 +204,11 @@ #define PCH_DEV_GBE _PCH_DEV(LPC, 6) #define PCH_DEV_TRACEHUB _PCH_DEV(LPC, 7) +/* for common code */ +#define PCI_DEVFN_UART0 PCH_DEVFN_UART0 +#define PCI_DEVFN_UART1 PCH_DEVFN_UART1 +#define PCI_DEVFN_UART2 PCH_DEVFN_UART2 +#define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n + #endif diff --git a/src/soc/intel/cannonlake/reset.c b/src/soc/intel/cannonlake/reset.c deleted file mode 100644 index 3c13f6dfe56..00000000000 --- a/src/soc/intel/cannonlake/reset.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -void do_global_reset(void) -{ - /* Ask CSE to do the global reset */ - if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) - return; - - /* global reset if CSE fail to reset */ - pmc_global_reset_enable(1); - do_full_reset(); -} diff --git a/src/soc/intel/cannonlake/romstage/fsp_params.c b/src/soc/intel/cannonlake/romstage/fsp_params.c index 38dfdd89225..c86da261d26 100644 --- a/src/soc/intel/cannonlake/romstage/fsp_params.c +++ b/src/soc/intel/cannonlake/romstage/fsp_params.c @@ -30,12 +30,16 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) m_cfg->HyperThreading = get_uint_option("hyper_threading", CONFIG(FSP_HYPERTHREADING)); - /* - * Probe for no IGD and disable InternalGfx and panel power to prevent a - * crash in FSP-M. - */ - const bool igd_on = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) && is_devfn_enabled(SA_DEVFN_IGD); - if (igd_on && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) != 0xffff) { + bool igd_enabled = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) + && is_devfn_enabled(SA_DEVFN_IGD); + + /* Probe for no IGD and disable InternalGfx and panel power to prevent a crash in FSP-M. */ + if (igd_enabled && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) == 0xffff) { + printk(BIOS_ERR, "igd_enabled is set, but IGD is not present. Disabling IGD.\n"); + igd_enabled = false; + } + + if (igd_enabled) { /* Set IGD stolen size to 64MB. */ m_cfg->InternalGfx = 1; m_cfg->IgdDvmt50PreAlloc = get_uint_option("igd_dvmt_prealloc", IGD_SM_64MB); diff --git a/src/soc/intel/cannonlake/uart.c b/src/soc/intel/cannonlake/uart.c deleted file mode 100644 index 99468802634..00000000000 --- a/src/soc/intel/cannonlake/uart.c +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -const unsigned int uart_devices[] = { - PCH_DEVFN_UART0, - PCH_DEVFN_UART1, - PCH_DEVFN_UART2, -}; - -const int uart_devices_size = ARRAY_SIZE(uart_devices); diff --git a/src/soc/intel/common/Kconfig.common b/src/soc/intel/common/Kconfig.common index 964a564303b..5e6ae6b19f6 100644 --- a/src/soc/intel/common/Kconfig.common +++ b/src/soc/intel/common/Kconfig.common @@ -66,6 +66,20 @@ config INTEL_TOP_SWAP_OPTION_CONTROL option. Note that the option must be present in the board's cmos.layout. file. +config TOP_SWAP_REDUNDANCY + bool "Toggle the Intel Top Swap - based redundancy" + depends on HAVE_OPTION_TABLE && INTEL_HAS_TOP_SWAP + select INTEL_ADD_TOP_SWAP_BOOTBLOCK + select MAINBOARD_NEEDS_CMOS_OPTIONS + select INTEL_TOP_SWAP_SEPARATE_REGIONS + select INTEL_TOP_SWAP_OPTION_CONTROL + help + Toggle the Intel Top Swap based redundancy, where the BOOTBLOCK and COREBOOT + regions form a read-only golden copy and TOPSWAP and COREBOOT_TS are an + update partition. CMOS option "attempt_top_swap" decides which of the slots + gets booted, which means the platform can be reverted to the known-good copy + via CMOS reset. + endif config SOC_INTEL_COMMON @@ -80,6 +94,9 @@ if SOC_INTEL_COMMON comment "Intel SoC Common Code for IP blocks" source "src/soc/intel/common/block/Kconfig" +comment "Intel SoC Common Code for features" +source "src/soc/intel/common/feature/Kconfig" + comment "Intel SoC Common PCH Code" source "src/soc/intel/common/pch/Kconfig" diff --git a/src/soc/intel/common/Makefile.mk b/src/soc/intel/common/Makefile.mk index b273ed7c12b..d1eacbfd171 100644 --- a/src/soc/intel/common/Makefile.mk +++ b/src/soc/intel/common/Makefile.mk @@ -3,6 +3,7 @@ ifeq ($(CONFIG_SOC_INTEL_COMMON),y) subdirs-y += basecode/ subdirs-y += block/ +subdirs-y += feature/ subdirs-y += pch/ verstage-$(CONFIG_SOC_INTEL_COMMON_RESET) += reset.c diff --git a/src/soc/intel/common/acpi/iost.asl b/src/soc/intel/common/acpi/iost.asl new file mode 100644 index 00000000000..51d934ca7ab --- /dev/null +++ b/src/soc/intel/common/acpi/iost.asl @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Device: Intel's IO Self-Testing Software (IOST) + * NOTE: The IOSE Name object is used to enable IOST. It is set to 0 by default, + * and its value can be updated in the SSDT. + */ +Device (IOST) +{ + // + // Intel IO Self Testing Device + // + Name (_UID, "IOST") + Name (_HID, "IOS0001") + Name (IVER, 0x00010000) + Name (IOSE, 0x00) + Method (_STA, 0, NotSerialized) + { + If (IOSE > Zero) { + Return (0xf) + } + Return (Zero) + } + + /* + * _DSM Device Specific Method + * + * Arg0: UUID : 893f00a6-660c-494e-bcfd-3043f4fb67c0 + * Arg1: Integer Revision Level + * Arg2: Integer Function Index (0 = Return Supported Functions) + * Arg3: Package Parameters + */ + Method (_DSM, 4, Serialized) + { + If ( (IOSE > Zero) && LEqual (Arg0, ToUUID ("893f00a6-660c-494e-bcfd-3043f4fb67c0"))) + { + If (LEqual (0, ToInteger (Arg1))) + { + Switch (ToInteger (Arg2)) + { + /* Function 0: returns a buffer containing one bit for each function index, starting with zero. + * Bit 0 indicates whether there is support for any function other than function 0 + */ + Case (0) + { + Return (Buffer(){0x07}) + } + /* Function 1: P2SB Read + * Package Details + * Idx0 = PortID + * Idx1 = Offset + */ + Case (1) + { + Local0 = DeRefOf (Index (Arg3, 0)) /* PordID */ + Local1 = DeRefOf (Index (Arg3, 1)) /* offset */ + + Local3 = PCRR(Local0, Local1) + Printf ("[IOST] P2B Read: PortID: %o Offset: %o read = %o", ToHexString(Local0), ToHexString(Local1), ToHexString(Local3)) + Return(Local3) + } + /* Function 2: P2SB Write + * Package Details + * Idx0 = PortID + * Idx1 = Offset + * Idx2 = DataToWrite + */ + Case (2) + { + Local0 = DeRefOf (Index (Arg3, 0)) /* PordID */ + Local1 = DeRefOf (Index (Arg3, 1)) /* offset */ + Local2 = DeRefOf (Index (Arg3, 2)) /* data to Write */ + Printf ("[IOST] P2B Write: PortID: %o Offset: %o with %o", ToHexString(Local0), ToHexString(Local1), ToHexString(Local2)) + PCRW(Local0, Local1, Local2) + Return (0x00) + } + } + } + } + Return (Buffer () {0x00}) + } +} diff --git a/src/soc/intel/common/block/acpi/acpi/northbridge.asl b/src/soc/intel/common/block/acpi/acpi/northbridge.asl index 3b2fb85933f..90c90027d04 100644 --- a/src/soc/intel/common/block/acpi/acpi/northbridge.asl +++ b/src/soc/intel/common/block/acpi/acpi/northbridge.asl @@ -24,7 +24,7 @@ Device (MCHC) Offset(0x48), /* MCHBAR (0:0:0:48) */ MHEN, 1, /* Enable */ , 14, - MHBR, 17, /* MCHBAR [31:15] */ + MHBR, 27, /* MCHBAR [41:15] */ Offset(0x60), /* PCIEXBAR (0:0:0:60) */ PXEN, 1, /* Enable */ @@ -246,6 +246,7 @@ Method (_CRS, 0, Serialized) Method (GMHB, 0, Serialized) { Local0 = \_SB.PCI0.MCHC.MHBR << 15 + Printf ("GMHB: %o", ToHexString(Local0)) Return (Local0) } diff --git a/src/soc/intel/common/block/cnvi/cnvi.c b/src/soc/intel/common/block/cnvi/cnvi.c index 9314c989ed5..214bd0890e8 100644 --- a/src/soc/intel/common/block/cnvi/cnvi.c +++ b/src/soc/intel/common/block/cnvi/cnvi.c @@ -120,7 +120,7 @@ static void cnvw_fill_ssdt(const struct device *dev) acpigen_write_name_integer("WFDL", 50); /* - * PowerResource (CNVP, 0x00, 0x0000) + * PowerResource (CNVP, 0x05, 0x0000) * { * Method (_STA, 0, NotSerialized) // _STA: Status * { @@ -205,12 +205,13 @@ static void cnvw_fill_ssdt(const struct device *dev) * } * Else * { - * PRRS = CNVI_PLDR_NOT_COMPLETE + * PRRS = CNVI_PLDR_TIMEOUT + * \_SB.PCI0.BTRK (One) * } * } * Else * { - * PRRS = CNVI_PLDR_TIMEOUT + * PRRS = CNVI_PLDR_NOT_COMPLETE * } * } * Release (\_SB.PCI0.CNMT) @@ -219,7 +220,7 @@ static void cnvw_fill_ssdt(const struct device *dev) * } * */ - acpigen_write_power_res("CNVP", 0, 0, NULL, 0); + acpigen_write_power_res("CNVP", 5, 0, NULL, 0); { acpigen_write_method("_STA", 0); { @@ -363,13 +364,15 @@ static void cnvw_fill_ssdt(const struct device *dev) } acpigen_write_else(); { - acpigen_write_store_int_to_namestr(CNVI_PLDR_NOT_COMPLETE, "PRRS"); + acpigen_write_store_int_to_namestr(CNVI_PLDR_TIMEOUT, "PRRS"); + acpigen_emit_namestring("\\_SB.PCI0.BTRK"); + acpigen_emit_byte(1); } acpigen_pop_len(); } acpigen_write_else(); { - acpigen_write_store_int_to_namestr(CNVI_PLDR_TIMEOUT, "PRRS"); + acpigen_write_store_int_to_namestr(CNVI_PLDR_NOT_COMPLETE, "PRRS"); } acpigen_pop_len(); } @@ -459,7 +462,7 @@ static void cnvw_fill_ssdt(const struct device *dev) acpigen_write_scope_end(); } -static struct device_operations cnvi_wifi_ops = { +struct device_operations cnvi_wifi_ops = { .read_resources = pci_dev_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, @@ -470,61 +473,14 @@ static struct device_operations cnvi_wifi_ops = { }; static const unsigned short wifi_pci_device_ids[] = { - PCI_DID_INTEL_WCL_CNVI_WIFI_0, - PCI_DID_INTEL_WCL_CNVI_WIFI_1, - PCI_DID_INTEL_WCL_CNVI_WIFI_2, - PCI_DID_INTEL_WCL_CNVI_WIFI_3, - PCI_DID_INTEL_PTL_H_CNVI_WIFI_0, - PCI_DID_INTEL_PTL_H_CNVI_WIFI_1, - PCI_DID_INTEL_PTL_H_CNVI_WIFI_2, - PCI_DID_INTEL_PTL_H_CNVI_WIFI_3, - PCI_DID_INTEL_PTL_U_H_CNVI_WIFI_0, - PCI_DID_INTEL_PTL_U_H_CNVI_WIFI_1, - PCI_DID_INTEL_PTL_U_H_CNVI_WIFI_2, - PCI_DID_INTEL_PTL_U_H_CNVI_WIFI_3, + PCI_DID_INTEL_NVL_CNVI_WIFI_0, + PCI_DID_INTEL_NVL_CNVI_WIFI_1, + PCI_DID_INTEL_NVL_CNVI_WIFI_2, + PCI_DID_INTEL_NVL_CNVI_WIFI_3, PCI_DID_INTEL_LNL_CNVI_WIFI_0, PCI_DID_INTEL_LNL_CNVI_WIFI_1, PCI_DID_INTEL_LNL_CNVI_WIFI_2, PCI_DID_INTEL_LNL_CNVI_WIFI_3, - PCI_DID_INTEL_MTL_CNVI_WIFI_0, - PCI_DID_INTEL_MTL_CNVI_WIFI_1, - PCI_DID_INTEL_MTL_CNVI_WIFI_2, - PCI_DID_INTEL_MTL_CNVI_WIFI_3, - PCI_DID_INTEL_ARL_CNVI_WIFI, - PCI_DID_INTEL_ARP_S_CNVI_WIFI, - PCI_DID_INTEL_CML_LP_CNVI_WIFI, - PCI_DID_INTEL_CML_H_CNVI_WIFI, - PCI_DID_INTEL_CNL_LP_CNVI_WIFI, - PCI_DID_INTEL_CNL_H_CNVI_WIFI, - PCI_DID_INTEL_GLK_CNVI_WIFI, - PCI_DID_INTEL_JSL_CNVI_WIFI_0, - PCI_DID_INTEL_JSL_CNVI_WIFI_1, - PCI_DID_INTEL_JSL_CNVI_WIFI_2, - PCI_DID_INTEL_JSL_CNVI_WIFI_3, - PCI_DID_INTEL_TGL_CNVI_WIFI_0, - PCI_DID_INTEL_TGL_CNVI_WIFI_1, - PCI_DID_INTEL_TGL_CNVI_WIFI_2, - PCI_DID_INTEL_TGL_CNVI_WIFI_3, - PCI_DID_INTEL_TGL_H_CNVI_WIFI_0, - PCI_DID_INTEL_TGL_H_CNVI_WIFI_1, - PCI_DID_INTEL_TGL_H_CNVI_WIFI_2, - PCI_DID_INTEL_TGL_H_CNVI_WIFI_3, - PCI_DID_INTEL_ADL_P_CNVI_WIFI_0, - PCI_DID_INTEL_ADL_P_CNVI_WIFI_1, - PCI_DID_INTEL_ADL_P_CNVI_WIFI_2, - PCI_DID_INTEL_ADL_P_CNVI_WIFI_3, - PCI_DID_INTEL_ADL_S_CNVI_WIFI_0, - PCI_DID_INTEL_ADL_S_CNVI_WIFI_1, - PCI_DID_INTEL_ADL_S_CNVI_WIFI_2, - PCI_DID_INTEL_ADL_S_CNVI_WIFI_3, - PCI_DID_INTEL_ADL_N_CNVI_WIFI_0, - PCI_DID_INTEL_ADL_N_CNVI_WIFI_1, - PCI_DID_INTEL_ADL_N_CNVI_WIFI_2, - PCI_DID_INTEL_ADL_N_CNVI_WIFI_3, - PCI_DID_INTEL_RPL_S_CNVI_WIFI_0, - PCI_DID_INTEL_RPL_S_CNVI_WIFI_1, - PCI_DID_INTEL_RPL_S_CNVI_WIFI_2, - PCI_DID_INTEL_RPL_S_CNVI_WIFI_3, 0 }; @@ -855,6 +811,7 @@ static struct device_operations cnvi_bt_ops = { }; static const unsigned short bt_pci_device_ids[] = { + PCI_DID_INTEL_NVL_CNVI_BT, PCI_DID_INTEL_WCL_CNVI_BT, PCI_DID_INTEL_PTL_H_CNVI_BT, PCI_DID_INTEL_PTL_U_H_CNVI_BT, diff --git a/src/soc/intel/common/block/cpu/car/cache_as_ram_fsp.S b/src/soc/intel/common/block/cpu/car/cache_as_ram_fsp.S index ed735dbce3b..1e55039a3c7 100644 --- a/src/soc/intel/common/block/cpu/car/cache_as_ram_fsp.S +++ b/src/soc/intel/common/block/cpu/car/cache_as_ram_fsp.S @@ -90,7 +90,7 @@ CAR_init_done: or %rsi, %rdi andl $0xfffffff0, %esp #else - /* Restore the timestamp from bootblock_crt0.S (ebp:mm1) */ + /* Restore the timestamp from entry32.S (ebp:mm1) */ push %ebp movd %mm1, %eax push %eax diff --git a/src/soc/intel/common/block/cpu/mp_init.c b/src/soc/intel/common/block/cpu/mp_init.c index fdee38d2549..12d9b95cbdd 100644 --- a/src/soc/intel/common/block/cpu/mp_init.c +++ b/src/soc/intel/common/block/cpu/mp_init.c @@ -32,6 +32,7 @@ static struct device_operations cpu_dev_ops = { }; static const struct cpu_device_id cpu_table[] = { + { X86_VENDOR_INTEL, CPUID_NOVALAKE, CPUID_ALL_STEPPINGS_MASK }, { X86_VENDOR_INTEL, CPUID_WILDCATLAKE, CPUID_ALL_STEPPINGS_MASK }, { X86_VENDOR_INTEL, CPUID_PANTHERLAKE, CPUID_ALL_STEPPINGS_MASK }, { X86_VENDOR_INTEL, CPUID_LUNARLAKE_A0_1, CPUID_EXACT_MATCH_MASK }, @@ -136,9 +137,13 @@ int get_cpu_count(void) * sets the argument *parallel to 1, which allows microcode loading in all * APs to occur in parallel during MP Init. */ -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 1; } diff --git a/src/soc/intel/common/block/cpu/smmrelocate.c b/src/soc/intel/common/block/cpu/smmrelocate.c index 8c45c218b25..fa4c8963a15 100644 --- a/src/soc/intel/common/block/cpu/smmrelocate.c +++ b/src/soc/intel/common/block/cpu/smmrelocate.c @@ -78,6 +78,15 @@ static int bsp_setup_msr_save_state(struct smm_relocation_params *relo_params) { msr_t smm_mca_cap; + /* + * FIXME: On Xeon-SP the MSR SMM_FEATURE_CONTROL_MSR is not implemented. + * SMM feature control resides on the UBOX PCI device. + * FIXME: Need to enable save state in MSRs on all sockets, however BSP + * runs on a single socket only. + */ + if (CONFIG(XEON_SP_COMMON_BASE) || CONFIG(SOC_INTEL_SNOWRIDGE)) + return 0; + smm_mca_cap = rdmsr(SMM_MCA_CAP_MSR); if (smm_mca_cap.hi & SMM_CPU_SVRSTR_MASK) { msr_t smm_feature_control; @@ -155,7 +164,7 @@ void smm_relocation_handler(int cpu, uintptr_t curr_smbase, relo_params->smrr_mask.lo |= SMRR_PHYS_MASK_LOCK; /* Write SMRRs if supported */ - if (mtrr_cap.lo & SMRR_SUPPORTED) + if (mtrr_cap.lo & MTRR_CAP_SMRR) write_smrr(relo_params); } diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index d02bb85b37f..d60b9b51958 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -1527,6 +1527,7 @@ struct device_operations cse_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_CSE0, PCI_DID_INTEL_WCL_CSE0, PCI_DID_INTEL_PTL_H_CSE0, PCI_DID_INTEL_PTL_U_H_CSE0, diff --git a/src/soc/intel/common/block/dsp/dsp.c b/src/soc/intel/common/block/dsp/dsp.c index 9155a2a7b73..6656042674e 100644 --- a/src/soc/intel/common/block/dsp/dsp.c +++ b/src/soc/intel/common/block/dsp/dsp.c @@ -14,6 +14,14 @@ static struct device_operations dsp_dev_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_AUDIO_1, + PCI_DID_INTEL_NVL_AUDIO_2, + PCI_DID_INTEL_NVL_AUDIO_3, + PCI_DID_INTEL_NVL_AUDIO_4, + PCI_DID_INTEL_NVL_AUDIO_5, + PCI_DID_INTEL_NVL_AUDIO_6, + PCI_DID_INTEL_NVL_AUDIO_7, + PCI_DID_INTEL_NVL_AUDIO_8, PCI_DID_INTEL_WCL_AUDIO_1, PCI_DID_INTEL_WCL_AUDIO_2, PCI_DID_INTEL_WCL_AUDIO_3, diff --git a/src/soc/intel/common/block/fast_spi/fast_spi.c b/src/soc/intel/common/block/fast_spi/fast_spi.c index 627ab28e9ba..a939369ecdc 100644 --- a/src/soc/intel/common/block/fast_spi/fast_spi.c +++ b/src/soc/intel/common/block/fast_spi/fast_spi.c @@ -572,7 +572,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_CMP_H_HWSEQ_SPI, PCI_DID_INTEL_CNL_HWSEQ_SPI, PCI_DID_INTEL_CNP_H_HWSEQ_SPI, - PCI_DID_INTEL_ICP_HWSEQ_SPI, PCI_DID_INTEL_JSP_HWSEQ_SPI, PCI_DID_INTEL_LWB_SPI, PCI_DID_INTEL_LWB_SPI_SUPER, diff --git a/src/soc/intel/common/block/fast_spi/fast_spi_flash.c b/src/soc/intel/common/block/fast_spi/fast_spi_flash.c index a7762711fa7..89ae6d2cd32 100644 --- a/src/soc/intel/common/block/fast_spi/fast_spi_flash.c +++ b/src/soc/intel/common/block/fast_spi/fast_spi_flash.c @@ -9,6 +9,7 @@ #include #include #include +#include /* Helper to create a FAST_SPI context on API entry. */ #define BOILERPLATE_CREATE_CTX(ctx) \ @@ -32,6 +33,9 @@ struct fast_spi_flash_ctx { uintptr_t mmio_base; }; +/* Spinlock to protect concurrent SPI flash controller access from multiple CPUs */ +DECLARE_SPIN_LOCK(fast_spi_lock); + static void _fast_spi_flash_get_ctx(struct fast_spi_flash_ctx *ctx) { ctx->mmio_base = (uintptr_t)fast_spi_get_bar(); @@ -160,15 +164,28 @@ static int exec_sync_hwseq_xfer(struct fast_spi_flash_ctx *ctx, uint32_t hsfsts_cycle, uint32_t flash_addr, size_t len) { + int ret; + + /* Protect SPI flash controller from concurrent access by multiple CPUs. + * The spinlock serializes access to the SPI controller hardware. + * If SMP is not enabled, spinlock functions are no-ops. + */ + spin_lock(&fast_spi_lock); + if (wait_for_hwseq_spi_cycle_complete(ctx) != SUCCESS) { printk(BIOS_ERR, "SPI Transaction Timeout (Exceeded %d ms) due to prior" " operation at Flash Offset %x\n", SPIBAR_HWSEQ_XFER_TIMEOUT_MS, flash_addr); - return E_TIMEOUT; + ret = E_TIMEOUT; + goto unlock; } start_hwseq_xfer(ctx, hsfsts_cycle, flash_addr, len); - return wait_for_hwseq_xfer(ctx, flash_addr); + ret = wait_for_hwseq_xfer(ctx, flash_addr); + +unlock: + spin_unlock(&fast_spi_lock); + return ret; } int fast_spi_cycle_in_progress(void) diff --git a/src/soc/intel/common/block/graphics/graphics.c b/src/soc/intel/common/block/graphics/graphics.c index 12f29b567b9..14893869a0a 100644 --- a/src/soc/intel/common/block/graphics/graphics.c +++ b/src/soc/intel/common/block/graphics/graphics.c @@ -361,6 +361,11 @@ const struct device_operations graphics_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_GT2_1, + PCI_DID_INTEL_NVL_GT2_2, + PCI_DID_INTEL_NVL_GT2_3, + PCI_DID_INTEL_NVL_GT2_4, + PCI_DID_INTEL_NVL_GT2_5, PCI_DID_INTEL_WCL_GT2_1, PCI_DID_INTEL_WCL_GT2_2, PCI_DID_INTEL_PTL_U_GT2_1, diff --git a/src/soc/intel/common/block/gspi/Makefile.mk b/src/soc/intel/common/block/gspi/Makefile.mk index a820866cebb..5b52f2146fc 100644 --- a/src/soc/intel/common/block/gspi/Makefile.mk +++ b/src/soc/intel/common/block/gspi/Makefile.mk @@ -1,6 +1,2 @@ ## SPDX-License-Identifier: GPL-2.0-only -bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI) += gspi.c -romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI) += gspi.c -ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI) += gspi.c -verstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI) += gspi.c -postcar-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI) += gspi.c +all-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI) += gspi.c diff --git a/src/soc/intel/common/block/hda/hda.c b/src/soc/intel/common/block/hda/hda.c index f5e22bc6d99..66ad97dd12d 100644 --- a/src/soc/intel/common/block/hda/hda.c +++ b/src/soc/intel/common/block/hda/hda.c @@ -30,30 +30,14 @@ struct device_operations hda_ops = { }; static const unsigned short pci_device_ids[] = { - PCI_DID_INTEL_WCL_AUDIO_1, - PCI_DID_INTEL_WCL_AUDIO_2, - PCI_DID_INTEL_WCL_AUDIO_3, - PCI_DID_INTEL_WCL_AUDIO_4, - PCI_DID_INTEL_WCL_AUDIO_5, - PCI_DID_INTEL_WCL_AUDIO_6, - PCI_DID_INTEL_WCL_AUDIO_7, - PCI_DID_INTEL_WCL_AUDIO_8, - PCI_DID_INTEL_PTL_H_AUDIO_1, - PCI_DID_INTEL_PTL_H_AUDIO_2, - PCI_DID_INTEL_PTL_H_AUDIO_3, - PCI_DID_INTEL_PTL_H_AUDIO_4, - PCI_DID_INTEL_PTL_H_AUDIO_5, - PCI_DID_INTEL_PTL_H_AUDIO_6, - PCI_DID_INTEL_PTL_H_AUDIO_7, - PCI_DID_INTEL_PTL_H_AUDIO_8, - PCI_DID_INTEL_PTL_U_H_AUDIO_1, - PCI_DID_INTEL_PTL_U_H_AUDIO_2, - PCI_DID_INTEL_PTL_U_H_AUDIO_3, - PCI_DID_INTEL_PTL_U_H_AUDIO_4, - PCI_DID_INTEL_PTL_U_H_AUDIO_5, - PCI_DID_INTEL_PTL_U_H_AUDIO_6, - PCI_DID_INTEL_PTL_U_H_AUDIO_7, - PCI_DID_INTEL_PTL_U_H_AUDIO_8, + PCI_DID_INTEL_NVL_AUDIO_1, + PCI_DID_INTEL_NVL_AUDIO_2, + PCI_DID_INTEL_NVL_AUDIO_3, + PCI_DID_INTEL_NVL_AUDIO_4, + PCI_DID_INTEL_NVL_AUDIO_5, + PCI_DID_INTEL_NVL_AUDIO_6, + PCI_DID_INTEL_NVL_AUDIO_7, + PCI_DID_INTEL_NVL_AUDIO_8, PCI_DID_INTEL_LNL_AUDIO_1, PCI_DID_INTEL_LNL_AUDIO_2, PCI_DID_INTEL_LNL_AUDIO_3, @@ -62,54 +46,10 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_LNL_AUDIO_6, PCI_DID_INTEL_LNL_AUDIO_7, PCI_DID_INTEL_LNL_AUDIO_8, - PCI_DID_INTEL_MTL_AUDIO_1, - PCI_DID_INTEL_MTL_AUDIO_2, - PCI_DID_INTEL_MTL_AUDIO_3, - PCI_DID_INTEL_MTL_AUDIO_4, - PCI_DID_INTEL_MTL_AUDIO_5, - PCI_DID_INTEL_MTL_AUDIO_6, - PCI_DID_INTEL_MTL_AUDIO_7, - PCI_DID_INTEL_MTL_AUDIO_8, - PCI_DID_INTEL_ARL_AUDIO, - PCI_DID_INTEL_ARP_S_AUDIO, - PCI_DID_INTEL_RPP_P_AUDIO, - PCI_DID_INTEL_RPP_S_AUDIO_1, - PCI_DID_INTEL_RPP_S_AUDIO_2, - PCI_DID_INTEL_RPP_S_AUDIO_3, - PCI_DID_INTEL_RPP_S_AUDIO_4, - PCI_DID_INTEL_RPP_S_AUDIO_5, - PCI_DID_INTEL_RPP_S_AUDIO_6, - PCI_DID_INTEL_RPP_S_AUDIO_7, - PCI_DID_INTEL_RPP_S_AUDIO_8, - PCI_DID_INTEL_APL_AUDIO, - PCI_DID_INTEL_GLK_AUDIO, PCI_DID_INTEL_LWB_AUDIO, PCI_DID_INTEL_LWB_AUDIO_SUPER, - PCI_DID_INTEL_CNL_AUDIO, - PCI_DID_INTEL_CNP_H_AUDIO, - PCI_DID_INTEL_CMP_AUDIO, - PCI_DID_INTEL_CMP_H_AUDIO, PCI_DID_INTEL_BSW_AUDIO, - PCI_DID_INTEL_TGL_AUDIO, - PCI_DID_INTEL_TGL_H_AUDIO, PCI_DID_INTEL_MCC_AUDIO, - PCI_DID_INTEL_JSP_AUDIO, - PCI_DID_INTEL_ADP_P_AUDIO, - PCI_DID_INTEL_ADP_S_AUDIO_1, - PCI_DID_INTEL_ADP_S_AUDIO_2, - PCI_DID_INTEL_ADP_S_AUDIO_3, - PCI_DID_INTEL_ADP_S_AUDIO_4, - PCI_DID_INTEL_ADP_S_AUDIO_5, - PCI_DID_INTEL_ADP_S_AUDIO_6, - PCI_DID_INTEL_ADP_S_AUDIO_7, - PCI_DID_INTEL_ADP_S_AUDIO_8, - PCI_DID_INTEL_ADP_M_N_AUDIO_1, - PCI_DID_INTEL_ADP_M_N_AUDIO_2, - PCI_DID_INTEL_ADP_M_N_AUDIO_3, - PCI_DID_INTEL_ADP_M_N_AUDIO_4, - PCI_DID_INTEL_ADP_M_N_AUDIO_5, - PCI_DID_INTEL_ADP_M_N_AUDIO_6, - PCI_DID_INTEL_ADP_M_N_AUDIO_7, 0 }; diff --git a/src/soc/intel/common/block/i2c/i2c.c b/src/soc/intel/common/block/i2c/i2c.c index 2c0e010ccb2..8018ee573de 100644 --- a/src/soc/intel/common/block/i2c/i2c.c +++ b/src/soc/intel/common/block/i2c/i2c.c @@ -174,105 +174,18 @@ struct device_operations i2c_dev_ops = { }; static const unsigned short pci_device_ids[] = { - PCI_DID_INTEL_WCL_I2C0, - PCI_DID_INTEL_WCL_I2C1, - PCI_DID_INTEL_WCL_I2C2, - PCI_DID_INTEL_WCL_I2C3, - PCI_DID_INTEL_WCL_I2C4, - PCI_DID_INTEL_WCL_I2C5, - PCI_DID_INTEL_PTL_H_I2C0, - PCI_DID_INTEL_PTL_H_I2C1, - PCI_DID_INTEL_PTL_H_I2C2, - PCI_DID_INTEL_PTL_H_I2C3, - PCI_DID_INTEL_PTL_H_I2C4, - PCI_DID_INTEL_PTL_H_I2C5, - PCI_DID_INTEL_PTL_U_H_I2C0, - PCI_DID_INTEL_PTL_U_H_I2C1, - PCI_DID_INTEL_PTL_U_H_I2C2, - PCI_DID_INTEL_PTL_U_H_I2C3, - PCI_DID_INTEL_PTL_U_H_I2C4, - PCI_DID_INTEL_PTL_U_H_I2C5, + PCI_DID_INTEL_NVL_I2C0, + PCI_DID_INTEL_NVL_I2C1, + PCI_DID_INTEL_NVL_I2C2, + PCI_DID_INTEL_NVL_I2C3, + PCI_DID_INTEL_NVL_I2C4, + PCI_DID_INTEL_NVL_I2C5, PCI_DID_INTEL_LNL_I2C0, PCI_DID_INTEL_LNL_I2C1, PCI_DID_INTEL_LNL_I2C2, PCI_DID_INTEL_LNL_I2C3, PCI_DID_INTEL_LNL_I2C4, PCI_DID_INTEL_LNL_I2C5, - PCI_DID_INTEL_MTL_I2C0, - PCI_DID_INTEL_MTL_I2C1, - PCI_DID_INTEL_MTL_I2C2, - PCI_DID_INTEL_MTL_I2C3, - PCI_DID_INTEL_MTL_I2C4, - PCI_DID_INTEL_MTL_I2C5, - PCI_DID_INTEL_ARL_I2C0, - PCI_DID_INTEL_ARL_I2C1, - PCI_DID_INTEL_ARL_I2C2, - PCI_DID_INTEL_ARL_I2C3, - PCI_DID_INTEL_ARL_I2C4, - PCI_DID_INTEL_ARL_I2C5, - PCI_DID_INTEL_ARP_S_I2C0, - PCI_DID_INTEL_ARP_S_I2C1, - PCI_DID_INTEL_ARP_S_I2C2, - PCI_DID_INTEL_ARP_S_I2C3, - PCI_DID_INTEL_ARP_S_I2C4, - PCI_DID_INTEL_ARP_S_I2C5, - PCI_DID_INTEL_APL_I2C0, - PCI_DID_INTEL_APL_I2C1, - PCI_DID_INTEL_APL_I2C2, - PCI_DID_INTEL_APL_I2C3, - PCI_DID_INTEL_APL_I2C4, - PCI_DID_INTEL_APL_I2C5, - PCI_DID_INTEL_APL_I2C6, - PCI_DID_INTEL_APL_I2C7, - PCI_DID_INTEL_CNL_I2C0, - PCI_DID_INTEL_CNL_I2C1, - PCI_DID_INTEL_CNL_I2C2, - PCI_DID_INTEL_CNL_I2C3, - PCI_DID_INTEL_CNL_I2C4, - PCI_DID_INTEL_CNL_I2C5, - PCI_DID_INTEL_GLK_I2C0, - PCI_DID_INTEL_GLK_I2C1, - PCI_DID_INTEL_GLK_I2C2, - PCI_DID_INTEL_GLK_I2C3, - PCI_DID_INTEL_GLK_I2C4, - PCI_DID_INTEL_GLK_I2C5, - PCI_DID_INTEL_GLK_I2C6, - PCI_DID_INTEL_GLK_I2C7, - PCI_DID_INTEL_CNP_H_I2C0, - PCI_DID_INTEL_CNP_H_I2C1, - PCI_DID_INTEL_CNP_H_I2C2, - PCI_DID_INTEL_CNP_H_I2C3, - PCI_DID_INTEL_ICP_I2C0, - PCI_DID_INTEL_ICP_I2C1, - PCI_DID_INTEL_ICP_I2C2, - PCI_DID_INTEL_ICP_I2C3, - PCI_DID_INTEL_ICP_I2C4, - PCI_DID_INTEL_ICP_I2C5, - PCI_DID_INTEL_CMP_I2C0, - PCI_DID_INTEL_CMP_I2C1, - PCI_DID_INTEL_CMP_I2C2, - PCI_DID_INTEL_CMP_I2C3, - PCI_DID_INTEL_CMP_I2C4, - PCI_DID_INTEL_CMP_I2C5, - PCI_DID_INTEL_CMP_H_I2C0, - PCI_DID_INTEL_CMP_H_I2C1, - PCI_DID_INTEL_CMP_H_I2C2, - PCI_DID_INTEL_CMP_H_I2C3, - PCI_DID_INTEL_TGP_I2C0, - PCI_DID_INTEL_TGP_I2C1, - PCI_DID_INTEL_TGP_I2C2, - PCI_DID_INTEL_TGP_I2C3, - PCI_DID_INTEL_TGP_I2C4, - PCI_DID_INTEL_TGP_I2C5, - PCI_DID_INTEL_TGP_I2C6, - PCI_DID_INTEL_TGP_I2C7, - PCI_DID_INTEL_TGP_H_I2C0, - PCI_DID_INTEL_TGP_H_I2C1, - PCI_DID_INTEL_TGP_H_I2C2, - PCI_DID_INTEL_TGP_H_I2C3, - PCI_DID_INTEL_TGP_H_I2C4, - PCI_DID_INTEL_TGP_H_I2C5, - PCI_DID_INTEL_TGP_H_I2C6, PCI_DID_INTEL_MCC_I2C0, PCI_DID_INTEL_MCC_I2C1, PCI_DID_INTEL_MCC_I2C2, @@ -281,38 +194,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_MCC_I2C5, PCI_DID_INTEL_MCC_I2C6, PCI_DID_INTEL_MCC_I2C7, - PCI_DID_INTEL_JSP_I2C0, - PCI_DID_INTEL_JSP_I2C1, - PCI_DID_INTEL_JSP_I2C2, - PCI_DID_INTEL_JSP_I2C3, - PCI_DID_INTEL_JSP_I2C4, - PCI_DID_INTEL_JSP_I2C5, - PCI_DID_INTEL_ADP_P_I2C0, - PCI_DID_INTEL_ADP_P_I2C1, - PCI_DID_INTEL_ADP_P_I2C2, - PCI_DID_INTEL_ADP_P_I2C3, - PCI_DID_INTEL_ADP_P_I2C4, - PCI_DID_INTEL_ADP_P_I2C5, - PCI_DID_INTEL_ADP_P_I2C6, - PCI_DID_INTEL_ADP_P_I2C7, - PCI_DID_INTEL_ADP_S_I2C0, - PCI_DID_INTEL_ADP_S_I2C1, - PCI_DID_INTEL_ADP_S_I2C2, - PCI_DID_INTEL_ADP_S_I2C3, - PCI_DID_INTEL_ADP_S_I2C4, - PCI_DID_INTEL_ADP_S_I2C5, - PCI_DID_INTEL_ADP_M_N_I2C0, - PCI_DID_INTEL_ADP_M_N_I2C1, - PCI_DID_INTEL_ADP_M_N_I2C2, - PCI_DID_INTEL_ADP_M_N_I2C3, - PCI_DID_INTEL_ADP_M_N_I2C4, - PCI_DID_INTEL_ADP_M_N_I2C5, - PCI_DID_INTEL_RPP_S_I2C0, - PCI_DID_INTEL_RPP_S_I2C1, - PCI_DID_INTEL_RPP_S_I2C2, - PCI_DID_INTEL_RPP_S_I2C3, - PCI_DID_INTEL_RPP_S_I2C4, - PCI_DID_INTEL_RPP_S_I2C5, 0, }; diff --git a/src/soc/intel/common/block/include/intelblocks/cfr.h b/src/soc/intel/common/block/include/intelblocks/cfr.h index 7828e1f3597..0185b0c0280 100644 --- a/src/soc/intel/common/block/include/intelblocks/cfr.h +++ b/src/soc/intel/common/block/include/intelblocks/cfr.h @@ -8,6 +8,7 @@ #define SOC_INTEL_CMN_CFR_H #include +#include #include #include @@ -59,6 +60,35 @@ static const struct sm_object power_on_after_fail_bool = SM_DECLARE_BOOL({ }); /* PCIe PCH RP ASPM */ +static void update_pcie_aspm(struct sm_object *new) +{ + if (!CONFIG(PCIEXP_ASPM)) + new->sm_enum.flags |= CFR_OPTFLAG_SUPPRESS; +} + +static void update_pcie_aspm_cpu(struct sm_object *new) +{ + if (!CONFIG(PCIEXP_ASPM) || !CONFIG(HAS_INTEL_CPU_ROOT_PORTS)) + new->sm_enum.flags |= CFR_OPTFLAG_SUPPRESS; +} + +static void update_pcie_l1ss(struct sm_object *new) +{ + if (!CONFIG(PCIEXP_ASPM) || !CONFIG(PCIEXP_L1_SUB_STATE)) + new->sm_enum.flags |= CFR_OPTFLAG_SUPPRESS; +} + +/* PCIe Clock PM */ +static const struct sm_object pciexp_clk_pm = SM_DECLARE_BOOL({ + .opt_name = "pciexp_clk_pm", + .ui_name = "PCIe Clock Power Management", + .ui_helptext = "Enables or disables power management for the PCIe clock. When" + " enabled, it reduces power consumption during idle states." + " This can help lower overall energy use but may impact" + " performance in power-sensitive tasks.", + .default_value = true, +}); + static const struct sm_object pciexp_aspm = SM_DECLARE_ENUM({ .opt_name = "pciexp_aspm", .ui_name = "PCIe PCH RP ASPM", @@ -73,7 +103,7 @@ static const struct sm_object pciexp_aspm = SM_DECLARE_ENUM({ { "L0sL1", ASPM_L0S_L1 }, { "Auto", ASPM_AUTO }, SM_ENUM_VALUE_END }, -}); +}, WITH_DEP_VALUES(&pciexp_clk_pm, true), WITH_CALLBACK(update_pcie_aspm)); /* PCIe CPU RP ASPM */ static const struct sm_object pciexp_aspm_cpu = SM_DECLARE_ENUM({ @@ -89,18 +119,7 @@ static const struct sm_object pciexp_aspm_cpu = SM_DECLARE_ENUM({ { "L1", ASPM_L1 }, { "L0sL1", ASPM_L0S_L1 }, SM_ENUM_VALUE_END }, -}); - -/* PCIe Clock PM */ -static const struct sm_object pciexp_clk_pm = SM_DECLARE_BOOL({ - .opt_name = "pciexp_clk_pm", - .ui_name = "PCIe Clock Power Management", - .ui_helptext = "Enables or disables power management for the PCIe clock. When" - " enabled, it reduces power consumption during idle states." - " This can help lower overall energy use but may impact" - " performance in power-sensitive tasks.", - .default_value = true, -}); +}, WITH_DEP_VALUES(&pciexp_clk_pm, true), WITH_CALLBACK(update_pcie_aspm_cpu)); /* PCIe L1 Substates */ static const struct sm_object pciexp_l1ss = SM_DECLARE_ENUM({ @@ -116,7 +135,7 @@ static const struct sm_object pciexp_l1ss = SM_DECLARE_ENUM({ { "L1.1", L1_SS_L1_1 }, { "L1.2", L1_SS_L1_2 }, SM_ENUM_VALUE_END }, -}); +}, WITH_DEP_VALUES(&pciexp_clk_pm, true), WITH_CALLBACK(update_pcie_l1ss)); /* PCIe PCH Root Port Speed */ static const struct sm_object pciexp_speed = SM_DECLARE_ENUM({ @@ -133,4 +152,36 @@ static const struct sm_object pciexp_speed = SM_DECLARE_ENUM({ SM_ENUM_VALUE_END }, }); +/* TME */ +static void update_intel_tme(struct sm_object *new) +{ + if (!is_tme_supported()) + new->sm_bool.flags |= CFR_OPTFLAG_SUPPRESS; +} + +static const struct sm_object intel_tme = SM_DECLARE_BOOL({ + .opt_name = "intel_tme", + .ui_name = "Total Memory Encryption", + .ui_helptext = "Enable TME (Total Memory Encryption). When enabled, all data stored in" + " system memory is encrypted to prevent unauthorized access or data theft." + " Disabling TME decreases boot time by around 100ms", + .default_value = CONFIG(INTEL_TME), +}, WITH_CALLBACK(update_intel_tme)); + +/* BIOS Lock */ +static void update_smm_bwp(struct sm_object *new) +{ + if (!CONFIG(BOOTMEDIA_SMM_BWP_RUNTIME_OPTION)) + new->sm_bool.flags |= CFR_OPTFLAG_SUPPRESS; +} + +static const struct sm_object bios_lock = SM_DECLARE_BOOL({ + .opt_name = "bios_lock", + .ui_name = "BIOS Lock", + .ui_helptext = "Enable BIOS write protection in SMM. When enabled, the boot media" + " (SPI flash) is only writable in System Management Mode, preventing" + " unauthorized writes through the internal controller.", + .default_value = CONFIG(BOOTMEDIA_SMM_BWP), +}, WITH_CALLBACK(update_smm_bwp)); + #endif /* SOC_INTEL_CMN_CFR_H */ diff --git a/src/soc/intel/common/block/include/intelblocks/mp_init.h b/src/soc/intel/common/block/include/intelblocks/mp_init.h index 0dd2109e4a1..a0579b7db2b 100644 --- a/src/soc/intel/common/block/include/intelblocks/mp_init.h +++ b/src/soc/intel/common/block/include/intelblocks/mp_init.h @@ -21,7 +21,7 @@ int get_cpu_count(void); * sets the argument *parallel to 1, which allows microcode loading in all * APs to occur in parallel during MP Init. */ -void get_microcode_info(const void **microcode, int *parallel); +void get_microcode_info(const void **microcode, size_t *size, int *parallel); /* * Perform BSP and AP initialization diff --git a/src/soc/intel/common/block/include/intelblocks/msr.h b/src/soc/intel/common/block/include/intelblocks/msr.h index 4bdd90c5366..1965b36d595 100644 --- a/src/soc/intel/common/block/include/intelblocks/msr.h +++ b/src/soc/intel/common/block/include/intelblocks/msr.h @@ -110,8 +110,6 @@ #define MSR_L2_QOS_MASK(reg) (0xd10 + reg) /* MTRR_CAP_MSR bits */ -#define SMRR_SUPPORTED (1<<11) -#define PRMRR_SUPPORTED (1<<12) #define SMRR_LOCK_SUPPORTED (1<<14) #define SGX_SUPPORTED (1<<2) diff --git a/src/soc/intel/common/block/include/intelblocks/p2sb.h b/src/soc/intel/common/block/include/intelblocks/p2sb.h index e587a4d25ec..a431f617c77 100644 --- a/src/soc/intel/common/block/include/intelblocks/p2sb.h +++ b/src/soc/intel/common/block/include/intelblocks/p2sb.h @@ -3,6 +3,7 @@ #ifndef SOC_INTEL_COMMON_BLOCK_P2SB_H #define SOC_INTEL_COMMON_BLOCK_P2SB_H +#include #include #include @@ -68,4 +69,11 @@ void p2sb_set_ioapic_bdf(union p2sb_bdf bdf); */ void p2sb_soc_get_sb_mask(uint32_t *ep_mask, size_t count); +/* + * SoC might define this function to fill additional P2SB-related ACPI objects. + * For instance, the SoC might include the IOST ACPI interface to use P2SB and + * enable it via SSDT for debug purposes at the OS level. + */ +void soc_fill_p2sb_ssdt(const struct device *dev); + #endif /* SOC_INTEL_COMMON_BLOCK_P2SB_H */ diff --git a/src/soc/intel/common/block/include/intelblocks/pcie_rp.h b/src/soc/intel/common/block/include/intelblocks/pcie_rp.h index 68137490b91..9538e3bf064 100644 --- a/src/soc/intel/common/block/include/intelblocks/pcie_rp.h +++ b/src/soc/intel/common/block/include/intelblocks/pcie_rp.h @@ -3,7 +3,7 @@ #ifndef SOC_INTEL_COMMON_BLOCK_PCIE_RP_H #define SOC_INTEL_COMMON_BLOCK_PCIE_RP_H -#include +#include /* * In schematic PCIe root port numbers are 1-based, but FSP use 0-based indexes for @@ -85,6 +85,24 @@ struct pcie_rp_config { enum PCIE_SPEED_control pcie_rp_pcie_speed; }; +struct pcie_modphy_config { + /* TX Output Downscale Amplitude Adjustment */ + bool tx_gen1_downscale_amp_override; + uint8_t tx_gen1_downscale_amp; + /* TX Output Downscale Amplitude Adjustment */ + bool tx_gen2_downscale_amp_override; + uint8_t tx_gen2_downscale_amp; + /* TX Output Downscale Amplitude Adjustment */ + bool tx_gen3_downscale_amp_override; + uint8_t tx_gen3_downscale_amp; + /* TX Output -3.5dB Mode De-Emphasis Adjustment Setting */ + uint8_t tx_gen1_de_emph; + /* TX Output -3.5dB Mode De-Emphasis Adjustment Setting */ + uint8_t tx_gen2_de_emph_3p5; + /* TX Output -6.0dB Mode De-Emphasis Adjustment Setting */ + uint8_t tx_gen2_de_emph_6p0; +}; + /* * The PCIe Root Ports usually come in groups of up to 8 PCI-device * functions. diff --git a/src/soc/intel/common/block/include/intelblocks/systemagent.h b/src/soc/intel/common/block/include/intelblocks/systemagent.h index a3ae8c38bf2..5047f1d9aaa 100644 --- a/src/soc/intel/common/block/include/intelblocks/systemagent.h +++ b/src/soc/intel/common/block/include/intelblocks/systemagent.h @@ -91,8 +91,6 @@ uintptr_t sa_get_tolud_base(void); uintptr_t sa_get_gsm_base(void); /* API to get TSEG base address */ uintptr_t sa_get_tseg_base(void); -/* API to get TSEG size */ -size_t sa_get_tseg_size(void); /* API to lock PAM registers */ void sa_lock_pam(void); /* API to get MMIO config size */ diff --git a/src/soc/intel/common/block/ipu/ipu.c b/src/soc/intel/common/block/ipu/ipu.c index 989da2e76a0..a0acc6332d4 100644 --- a/src/soc/intel/common/block/ipu/ipu.c +++ b/src/soc/intel/common/block/ipu/ipu.c @@ -12,6 +12,7 @@ struct device_operations ipu_pci_ops = { }; static const uint16_t pci_device_ids[] = { + PCI_DID_INTEL_NVL_IPU, PCI_DID_INTEL_PTL_IPU, PCI_DID_INTEL_LNL_IPU, PCI_DID_INTEL_RPL_IPU, diff --git a/src/soc/intel/common/block/lpc/lpc.c b/src/soc/intel/common/block/lpc/lpc.c index 391a0182f2d..99c628e12cc 100644 --- a/src/soc/intel/common/block/lpc/lpc.c +++ b/src/soc/intel/common/block/lpc/lpc.c @@ -151,6 +151,38 @@ struct device_operations lpc_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_ESPI_0, + PCI_DID_INTEL_NVL_ESPI_1, + PCI_DID_INTEL_NVL_ESPI_2, + PCI_DID_INTEL_NVL_ESPI_3, + PCI_DID_INTEL_NVL_ESPI_4, + PCI_DID_INTEL_NVL_ESPI_5, + PCI_DID_INTEL_NVL_ESPI_6, + PCI_DID_INTEL_NVL_ESPI_7, + PCI_DID_INTEL_NVL_ESPI_8, + PCI_DID_INTEL_NVL_ESPI_9, + PCI_DID_INTEL_NVL_ESPI_10, + PCI_DID_INTEL_NVL_ESPI_11, + PCI_DID_INTEL_NVL_ESPI_12, + PCI_DID_INTEL_NVL_ESPI_13, + PCI_DID_INTEL_NVL_ESPI_14, + PCI_DID_INTEL_NVL_ESPI_15, + PCI_DID_INTEL_NVL_ESPI_16, + PCI_DID_INTEL_NVL_ESPI_17, + PCI_DID_INTEL_NVL_ESPI_18, + PCI_DID_INTEL_NVL_ESPI_19, + PCI_DID_INTEL_NVL_ESPI_20, + PCI_DID_INTEL_NVL_ESPI_21, + PCI_DID_INTEL_NVL_ESPI_22, + PCI_DID_INTEL_NVL_ESPI_23, + PCI_DID_INTEL_NVL_ESPI_24, + PCI_DID_INTEL_NVL_ESPI_25, + PCI_DID_INTEL_NVL_ESPI_26, + PCI_DID_INTEL_NVL_ESPI_27, + PCI_DID_INTEL_NVL_ESPI_28, + PCI_DID_INTEL_NVL_ESPI_29, + PCI_DID_INTEL_NVL_ESPI_30, + PCI_DID_INTEL_NVL_ESPI_31, PCI_DID_INTEL_WCL_ESPI_0, PCI_DID_INTEL_WCL_ESPI_1, PCI_DID_INTEL_WCL_ESPI_2, diff --git a/src/soc/intel/common/block/lpc/lpc_lib.c b/src/soc/intel/common/block/lpc/lpc_lib.c index 9a7165baafe..18cf1670af0 100644 --- a/src/soc/intel/common/block/lpc/lpc_lib.c +++ b/src/soc/intel/common/block/lpc/lpc_lib.c @@ -169,14 +169,25 @@ void lpc_open_pmio_window(uint16_t base, uint16_t size) alignment = 1UL << (log2_ceil(window_size)); window_size = ALIGN_UP(window_size, alignment); - /* Address[15:2] in LGIR[15:12] and Mask[7:2] in LGIR[23:18]. */ - lgir = (bridge_base & LPC_LGIR_ADDR_MASK) | LPC_LGIR_EN; - lgir |= ((window_size - 1) << 16) & LPC_LGIR_AMASK_MASK; + const struct region win = region_create(bridge_base, window_size); - /* Skip programming if same range already programmed. */ + /* Skip programming if covered by existing window. */ for (i = 0; i < LPC_NUM_GENERIC_IO_RANGES; i++) { - if (lgir == pci_read_config32(PCH_DEV_LPC, - LPC_GENERIC_IO_RANGE(i))) + const u32 reg32 = pci_read_config32(PCH_DEV_LPC, LPC_GENERIC_IO_RANGE(i)); + if (!(reg32 & LPC_LGIR_EN)) + continue; + + /* The AMASK field stores bits [7:2] of the address mask. + * Bits [1:0] are always set (4-byte granularity). + * To decode: mask = (amask_raw & 0xfc) | 0x3 + * size = mask + 1 + */ + const u32 exist_base = reg32 & LPC_LGIR_ADDR_MASK; + const u32 amask_raw = (reg32 & LPC_LGIR_AMASK_MASK) >> 16; + const u32 exist_size = ((amask_raw & 0xfc) | 0x3) + 1; + const struct region exist = region_create(exist_base, exist_size); + + if (region_is_subregion(&exist, &win)) return; } @@ -190,6 +201,10 @@ void lpc_open_pmio_window(uint16_t base, uint16_t size) } lgir_reg_offset = LPC_GENERIC_IO_RANGE(lgir_reg_num); + /* Address[15:2] in LGIR[15:12] and Mask[7:2] in LGIR[23:18]. */ + lgir = (bridge_base & LPC_LGIR_ADDR_MASK) | LPC_LGIR_EN; + lgir |= ((window_size - 1) << 16) & LPC_LGIR_AMASK_MASK; + pci_write_config32(PCH_DEV_LPC, lgir_reg_offset, lgir); if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_GPMR)) gpmr_write32(GPMR_LPCLGIR1 + lgir_reg_num * 4, lgir); diff --git a/src/soc/intel/common/block/p2sb/p2sb.c b/src/soc/intel/common/block/p2sb/p2sb.c index fea31030269..64600b197c4 100644 --- a/src/soc/intel/common/block/p2sb/p2sb.c +++ b/src/soc/intel/common/block/p2sb/p2sb.c @@ -130,13 +130,22 @@ static void read_resources(struct device *dev) mmio_range(dev, PCI_BASE_ADDRESS_0, P2SB_BAR, P2SB_SIZE); } +__weak void soc_fill_p2sb_ssdt(const struct device *dev) +{ + /* no-op */ +} + const struct device_operations p2sb_ops = { .read_resources = read_resources, .set_resources = noop_set_resources, .ops_pci = &pci_dev_ops_pci, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_fill_ssdt = soc_fill_p2sb_ssdt, +#endif }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_P2SB, PCI_DID_INTEL_WCL_P2SB, PCI_DID_INTEL_PTL_H_P2SB, PCI_DID_INTEL_PTL_U_H_P2SB, diff --git a/src/soc/intel/common/block/p2sb/p2sb2.c b/src/soc/intel/common/block/p2sb/p2sb2.c index 2627a7182c8..1223f7339a8 100644 --- a/src/soc/intel/common/block/p2sb/p2sb2.c +++ b/src/soc/intel/common/block/p2sb/p2sb2.c @@ -37,6 +37,7 @@ struct device_operations p2sb2_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_P2SB2, PCI_DID_INTEL_WCL_P2SB2, PCI_DID_INTEL_PTL_H_P2SB2, PCI_DID_INTEL_PTL_U_H_P2SB2, diff --git a/src/soc/intel/common/block/pcie/pcie.c b/src/soc/intel/common/block/pcie/pcie.c index 18b938e280e..ccddb8026fc 100644 --- a/src/soc/intel/common/block/pcie/pcie.c +++ b/src/soc/intel/common/block/pcie/pcie.c @@ -67,34 +67,20 @@ struct device_operations pcie_rp_ops = { }; static const unsigned short pcie_device_ids[] = { - PCI_DID_INTEL_WCL_PCIE_RP1, - PCI_DID_INTEL_WCL_PCIE_RP2, - PCI_DID_INTEL_WCL_PCIE_RP3, - PCI_DID_INTEL_WCL_PCIE_RP4, - PCI_DID_INTEL_WCL_PCIE_RP5, - PCI_DID_INTEL_WCL_PCIE_RP6, - PCI_DID_INTEL_PTL_H_PCIE_RP1, - PCI_DID_INTEL_PTL_H_PCIE_RP2, - PCI_DID_INTEL_PTL_H_PCIE_RP3, - PCI_DID_INTEL_PTL_H_PCIE_RP4, - PCI_DID_INTEL_PTL_H_PCIE_RP5, - PCI_DID_INTEL_PTL_H_PCIE_RP6, - PCI_DID_INTEL_PTL_H_PCIE_RP7, - PCI_DID_INTEL_PTL_H_PCIE_RP8, - PCI_DID_INTEL_PTL_H_PCIE_RP9, - PCI_DID_INTEL_PTL_H_PCIE_RP10, - PCI_DID_INTEL_PTL_U_H_PCIE_RP1, - PCI_DID_INTEL_PTL_U_H_PCIE_RP2, - PCI_DID_INTEL_PTL_U_H_PCIE_RP3, - PCI_DID_INTEL_PTL_U_H_PCIE_RP4, - PCI_DID_INTEL_PTL_U_H_PCIE_RP5, - PCI_DID_INTEL_PTL_U_H_PCIE_RP6, - PCI_DID_INTEL_PTL_U_H_PCIE_RP7, - PCI_DID_INTEL_PTL_U_H_PCIE_RP8, - PCI_DID_INTEL_PTL_U_H_PCIE_RP9, - PCI_DID_INTEL_PTL_U_H_PCIE_RP10, - PCI_DID_INTEL_PTL_U_H_PCIE_RP11, - PCI_DID_INTEL_PTL_U_H_PCIE_RP12, + PCI_DID_INTEL_NVL_PCIE_RP1, + PCI_DID_INTEL_NVL_PCIE_RP2, + PCI_DID_INTEL_NVL_PCIE_RP3, + PCI_DID_INTEL_NVL_PCIE_RP4, + PCI_DID_INTEL_NVL_PCIE_RP5, + PCI_DID_INTEL_NVL_PCIE_RP6, + PCI_DID_INTEL_NVL_PCIE_RP7, + PCI_DID_INTEL_NVL_PCIE_RP8, + PCI_DID_INTEL_NVL_PCIE_RP9, + PCI_DID_INTEL_NVL_PCIE_RP10, + PCI_DID_INTEL_NVL_PCIE_RP11, + PCI_DID_INTEL_NVL_PCIE_RP12, + PCI_DID_INTEL_NVL_PCIE_RP13, + PCI_DID_INTEL_NVL_PCIE_RP14, PCI_DID_INTEL_LNL_PCIE_RP1, PCI_DID_INTEL_LNL_PCIE_RP2, PCI_DID_INTEL_LNL_PCIE_RP3, @@ -103,234 +89,6 @@ static const unsigned short pcie_device_ids[] = { PCI_DID_INTEL_LNL_PCIE_RP6, PCI_DID_INTEL_LNL_PCIE_RP7, PCI_DID_INTEL_LNL_PCIE_RP8, - PCI_DID_INTEL_RPL_P_PCIE_RP1, - PCI_DID_INTEL_RPL_P_PCIE_RP2, - PCI_DID_INTEL_RPL_P_PCIE_RP3, - PCI_DID_INTEL_RPL_P_PCIE_RP4, - PCI_DID_INTEL_MTL_SOC_PCIE_RP1, - PCI_DID_INTEL_MTL_SOC_PCIE_RP2, - PCI_DID_INTEL_MTL_SOC_PCIE_RP3, - PCI_DID_INTEL_MTL_SOC_PCIE_RP4, - PCI_DID_INTEL_MTL_SOC_PCIE_RP5, - PCI_DID_INTEL_MTL_SOC_PCIE_RP6, - PCI_DID_INTEL_MTL_SOC_PCIE_RP7, - PCI_DID_INTEL_MTL_SOC_PCIE_RP8, - PCI_DID_INTEL_MTL_SOC_PCIE_RP9, - PCI_DID_INTEL_MTL_IOE_P_PCIE_RP10, - PCI_DID_INTEL_MTL_IOE_P_PCIE_RP11, - PCI_DID_INTEL_MTL_IOE_P_PCIE_RP12, - PCI_DID_INTEL_ARL_SOC_PCIE_RP1, - PCI_DID_INTEL_ARL_SOC_PCIE_RP2, - PCI_DID_INTEL_ARL_SOC_PCIE_RP3, - PCI_DID_INTEL_ARL_SOC_PCIE_RP4, - PCI_DID_INTEL_ARL_SOC_PCIE_RP5, - PCI_DID_INTEL_ARL_SOC_PCIE_RP6, - PCI_DID_INTEL_ARL_SOC_PCIE_RP7, - PCI_DID_INTEL_ARL_SOC_PCIE_RP8, - PCI_DID_INTEL_ARL_SOC_PCIE_RP9, - PCI_DID_INTEL_ARL_S_PCIE_RP13, - PCI_DID_INTEL_ARL_S_PCIE_RP14, - PCI_DID_INTEL_ARL_S_PCIE_RP15, - PCI_DID_INTEL_ARP_S_PCIE_RP1, - PCI_DID_INTEL_ARP_S_PCIE_RP2, - PCI_DID_INTEL_ARP_S_PCIE_RP3, - PCI_DID_INTEL_ARP_S_PCIE_RP4, - PCI_DID_INTEL_ARP_S_PCIE_RP5, - PCI_DID_INTEL_ARP_S_PCIE_RP6, - PCI_DID_INTEL_ARP_S_PCIE_RP7, - PCI_DID_INTEL_ARP_S_PCIE_RP8, - PCI_DID_INTEL_ARP_S_PCIE_RP9, - PCI_DID_INTEL_ARP_S_PCIE_RP10, - PCI_DID_INTEL_ARP_S_PCIE_RP11, - PCI_DID_INTEL_ARP_S_PCIE_RP12, - PCI_DID_INTEL_ARP_S_PCIE_RP13, - PCI_DID_INTEL_ARP_S_PCIE_RP14, - PCI_DID_INTEL_ARP_S_PCIE_RP15, - PCI_DID_INTEL_ARP_S_PCIE_RP16, - PCI_DID_INTEL_ARP_S_PCIE_RP17, - PCI_DID_INTEL_ARP_S_PCIE_RP18, - PCI_DID_INTEL_ARP_S_PCIE_RP19, - PCI_DID_INTEL_ARP_S_PCIE_RP20, - PCI_DID_INTEL_ARP_S_PCIE_RP21, - PCI_DID_INTEL_ARP_S_PCIE_RP22, - PCI_DID_INTEL_ARP_S_PCIE_RP23, - PCI_DID_INTEL_ARP_S_PCIE_RP24, - PCI_DID_INTEL_LWB_PCIE_RP1, - PCI_DID_INTEL_LWB_PCIE_RP2, - PCI_DID_INTEL_LWB_PCIE_RP3, - PCI_DID_INTEL_LWB_PCIE_RP4, - PCI_DID_INTEL_LWB_PCIE_RP5, - PCI_DID_INTEL_LWB_PCIE_RP6, - PCI_DID_INTEL_LWB_PCIE_RP7, - PCI_DID_INTEL_LWB_PCIE_RP8, - PCI_DID_INTEL_LWB_PCIE_RP9, - PCI_DID_INTEL_LWB_PCIE_RP10, - PCI_DID_INTEL_LWB_PCIE_RP11, - PCI_DID_INTEL_LWB_PCIE_RP12, - PCI_DID_INTEL_LWB_PCIE_RP13, - PCI_DID_INTEL_LWB_PCIE_RP14, - PCI_DID_INTEL_LWB_PCIE_RP15, - PCI_DID_INTEL_LWB_PCIE_RP16, - PCI_DID_INTEL_LWB_PCIE_RP17, - PCI_DID_INTEL_LWB_PCIE_RP18, - PCI_DID_INTEL_LWB_PCIE_RP19, - PCI_DID_INTEL_LWB_PCIE_RP20, - PCI_DID_INTEL_LWB_PCIE_RP1_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP2_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP3_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP4_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP5_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP6_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP7_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP8_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP9_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP10_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP11_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP12_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP13_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP14_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP15_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP16_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP17_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP18_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP19_SUPER, - PCI_DID_INTEL_LWB_PCIE_RP20_SUPER, - PCI_DID_INTEL_CNL_LP_PCIE_RP1, - PCI_DID_INTEL_CNL_LP_PCIE_RP2, - PCI_DID_INTEL_CNL_LP_PCIE_RP3, - PCI_DID_INTEL_CNL_LP_PCIE_RP4, - PCI_DID_INTEL_CNL_LP_PCIE_RP5, - PCI_DID_INTEL_CNL_LP_PCIE_RP6, - PCI_DID_INTEL_CNL_LP_PCIE_RP7, - PCI_DID_INTEL_CNL_LP_PCIE_RP8, - PCI_DID_INTEL_CNL_LP_PCIE_RP9, - PCI_DID_INTEL_CNL_LP_PCIE_RP10, - PCI_DID_INTEL_CNL_LP_PCIE_RP11, - PCI_DID_INTEL_CNL_LP_PCIE_RP12, - PCI_DID_INTEL_CNL_LP_PCIE_RP13, - PCI_DID_INTEL_CNL_LP_PCIE_RP14, - PCI_DID_INTEL_CNL_LP_PCIE_RP15, - PCI_DID_INTEL_CNL_LP_PCIE_RP16, - PCI_DID_INTEL_CNP_H_PCIE_RP1, - PCI_DID_INTEL_CNP_H_PCIE_RP2, - PCI_DID_INTEL_CNP_H_PCIE_RP3, - PCI_DID_INTEL_CNP_H_PCIE_RP4, - PCI_DID_INTEL_CNP_H_PCIE_RP5, - PCI_DID_INTEL_CNP_H_PCIE_RP6, - PCI_DID_INTEL_CNP_H_PCIE_RP7, - PCI_DID_INTEL_CNP_H_PCIE_RP8, - PCI_DID_INTEL_CNP_H_PCIE_RP9, - PCI_DID_INTEL_CNP_H_PCIE_RP10, - PCI_DID_INTEL_CNP_H_PCIE_RP11, - PCI_DID_INTEL_CNP_H_PCIE_RP12, - PCI_DID_INTEL_CNP_H_PCIE_RP13, - PCI_DID_INTEL_CNP_H_PCIE_RP14, - PCI_DID_INTEL_CNP_H_PCIE_RP15, - PCI_DID_INTEL_CNP_H_PCIE_RP16, - PCI_DID_INTEL_CNP_H_PCIE_RP17, - PCI_DID_INTEL_CNP_H_PCIE_RP18, - PCI_DID_INTEL_CNP_H_PCIE_RP19, - PCI_DID_INTEL_CNP_H_PCIE_RP20, - PCI_DID_INTEL_CNP_H_PCIE_RP21, - PCI_DID_INTEL_CNP_H_PCIE_RP22, - PCI_DID_INTEL_CNP_H_PCIE_RP23, - PCI_DID_INTEL_CNP_H_PCIE_RP24, - PCI_DID_INTEL_ICP_LP_PCIE_RP1, - PCI_DID_INTEL_ICP_LP_PCIE_RP2, - PCI_DID_INTEL_ICP_LP_PCIE_RP3, - PCI_DID_INTEL_ICP_LP_PCIE_RP4, - PCI_DID_INTEL_ICP_LP_PCIE_RP5, - PCI_DID_INTEL_ICP_LP_PCIE_RP6, - PCI_DID_INTEL_ICP_LP_PCIE_RP7, - PCI_DID_INTEL_ICP_LP_PCIE_RP8, - PCI_DID_INTEL_ICP_LP_PCIE_RP9, - PCI_DID_INTEL_ICP_LP_PCIE_RP10, - PCI_DID_INTEL_ICP_LP_PCIE_RP11, - PCI_DID_INTEL_ICP_LP_PCIE_RP12, - PCI_DID_INTEL_ICP_LP_PCIE_RP13, - PCI_DID_INTEL_ICP_LP_PCIE_RP14, - PCI_DID_INTEL_ICP_LP_PCIE_RP15, - PCI_DID_INTEL_ICP_LP_PCIE_RP16, - PCI_DID_INTEL_CMP_LP_PCIE_RP1, - PCI_DID_INTEL_CMP_LP_PCIE_RP2, - PCI_DID_INTEL_CMP_LP_PCIE_RP3, - PCI_DID_INTEL_CMP_LP_PCIE_RP4, - PCI_DID_INTEL_CMP_LP_PCIE_RP5, - PCI_DID_INTEL_CMP_LP_PCIE_RP6, - PCI_DID_INTEL_CMP_LP_PCIE_RP7, - PCI_DID_INTEL_CMP_LP_PCIE_RP8, - PCI_DID_INTEL_CMP_LP_PCIE_RP9, - PCI_DID_INTEL_CMP_LP_PCIE_RP10, - PCI_DID_INTEL_CMP_LP_PCIE_RP11, - PCI_DID_INTEL_CMP_LP_PCIE_RP12, - PCI_DID_INTEL_CMP_LP_PCIE_RP13, - PCI_DID_INTEL_CMP_LP_PCIE_RP14, - PCI_DID_INTEL_CMP_LP_PCIE_RP15, - PCI_DID_INTEL_CMP_LP_PCIE_RP16, - PCI_DID_INTEL_CMP_H_PCIE_RP1, - PCI_DID_INTEL_CMP_H_PCIE_RP2, - PCI_DID_INTEL_CMP_H_PCIE_RP3, - PCI_DID_INTEL_CMP_H_PCIE_RP4, - PCI_DID_INTEL_CMP_H_PCIE_RP5, - PCI_DID_INTEL_CMP_H_PCIE_RP6, - PCI_DID_INTEL_CMP_H_PCIE_RP7, - PCI_DID_INTEL_CMP_H_PCIE_RP8, - PCI_DID_INTEL_CMP_H_PCIE_RP9, - PCI_DID_INTEL_CMP_H_PCIE_RP10, - PCI_DID_INTEL_CMP_H_PCIE_RP11, - PCI_DID_INTEL_CMP_H_PCIE_RP12, - PCI_DID_INTEL_CMP_H_PCIE_RP13, - PCI_DID_INTEL_CMP_H_PCIE_RP14, - PCI_DID_INTEL_CMP_H_PCIE_RP15, - PCI_DID_INTEL_CMP_H_PCIE_RP16, - PCI_DID_INTEL_CMP_H_PCIE_RP17, - PCI_DID_INTEL_CMP_H_PCIE_RP18, - PCI_DID_INTEL_CMP_H_PCIE_RP19, - PCI_DID_INTEL_CMP_H_PCIE_RP20, - PCI_DID_INTEL_CMP_H_PCIE_RP21, - PCI_DID_INTEL_CMP_H_PCIE_RP22, - PCI_DID_INTEL_CMP_H_PCIE_RP23, - PCI_DID_INTEL_CMP_H_PCIE_RP24, - PCI_DID_INTEL_TGP_LP_PCIE_RP1, - PCI_DID_INTEL_TGP_LP_PCIE_RP2, - PCI_DID_INTEL_TGP_LP_PCIE_RP3, - PCI_DID_INTEL_TGP_LP_PCIE_RP4, - PCI_DID_INTEL_TGP_LP_PCIE_RP5, - PCI_DID_INTEL_TGP_LP_PCIE_RP6, - PCI_DID_INTEL_TGP_LP_PCIE_RP7, - PCI_DID_INTEL_TGP_LP_PCIE_RP8, - PCI_DID_INTEL_TGP_LP_PCIE_RP9, - PCI_DID_INTEL_TGP_LP_PCIE_RP10, - PCI_DID_INTEL_TGP_LP_PCIE_RP11, - PCI_DID_INTEL_TGP_LP_PCIE_RP12, - PCI_DID_INTEL_TGP_LP_PCIE_RP13, - PCI_DID_INTEL_TGP_LP_PCIE_RP14, - PCI_DID_INTEL_TGP_LP_PCIE_RP15, - PCI_DID_INTEL_TGP_LP_PCIE_RP16, - PCI_DID_INTEL_TGP_H_PCIE_RP1, - PCI_DID_INTEL_TGP_H_PCIE_RP2, - PCI_DID_INTEL_TGP_H_PCIE_RP3, - PCI_DID_INTEL_TGP_H_PCIE_RP4, - PCI_DID_INTEL_TGP_H_PCIE_RP5, - PCI_DID_INTEL_TGP_H_PCIE_RP6, - PCI_DID_INTEL_TGP_H_PCIE_RP7, - PCI_DID_INTEL_TGP_H_PCIE_RP8, - PCI_DID_INTEL_TGP_H_PCIE_RP9, - PCI_DID_INTEL_TGP_H_PCIE_RP10, - PCI_DID_INTEL_TGP_H_PCIE_RP11, - PCI_DID_INTEL_TGP_H_PCIE_RP12, - PCI_DID_INTEL_TGP_H_PCIE_RP13, - PCI_DID_INTEL_TGP_H_PCIE_RP14, - PCI_DID_INTEL_TGP_H_PCIE_RP15, - PCI_DID_INTEL_TGP_H_PCIE_RP16, - PCI_DID_INTEL_TGP_H_PCIE_RP17, - PCI_DID_INTEL_TGP_H_PCIE_RP18, - PCI_DID_INTEL_TGP_H_PCIE_RP19, - PCI_DID_INTEL_TGP_H_PCIE_RP20, - PCI_DID_INTEL_TGP_H_PCIE_RP21, - PCI_DID_INTEL_TGP_H_PCIE_RP22, - PCI_DID_INTEL_TGP_H_PCIE_RP23, - PCI_DID_INTEL_TGP_H_PCIE_RP24, PCI_DID_INTEL_MCC_PCIE_RP1, PCI_DID_INTEL_MCC_PCIE_RP2, PCI_DID_INTEL_MCC_PCIE_RP3, @@ -338,97 +96,6 @@ static const unsigned short pcie_device_ids[] = { PCI_DID_INTEL_MCC_PCIE_RP5, PCI_DID_INTEL_MCC_PCIE_RP6, PCI_DID_INTEL_MCC_PCIE_RP7, - PCI_DID_INTEL_JSP_PCIE_RP1, - PCI_DID_INTEL_JSP_PCIE_RP2, - PCI_DID_INTEL_JSP_PCIE_RP3, - PCI_DID_INTEL_JSP_PCIE_RP4, - PCI_DID_INTEL_JSP_PCIE_RP5, - PCI_DID_INTEL_JSP_PCIE_RP6, - PCI_DID_INTEL_JSP_PCIE_RP7, - PCI_DID_INTEL_JSP_PCIE_RP8, - PCI_DID_INTEL_ADL_P_PCIE_RP1, - PCI_DID_INTEL_ADL_P_PCIE_RP2, - PCI_DID_INTEL_ADL_P_PCIE_RP3, - PCI_DID_INTEL_ADP_P_PCIE_RP1, - PCI_DID_INTEL_ADP_P_PCIE_RP2, - PCI_DID_INTEL_ADP_P_PCIE_RP3, - PCI_DID_INTEL_ADP_P_PCIE_RP4, - PCI_DID_INTEL_ADP_P_PCIE_RP5, - PCI_DID_INTEL_ADP_P_PCIE_RP6, - PCI_DID_INTEL_ADP_P_PCIE_RP7, - PCI_DID_INTEL_ADP_P_PCIE_RP8, - PCI_DID_INTEL_ADP_P_PCIE_RP9, - PCI_DID_INTEL_ADP_P_PCIE_RP10, - PCI_DID_INTEL_ADP_P_PCIE_RP11, - PCI_DID_INTEL_ADP_P_PCIE_RP12, - PCI_DID_INTEL_ADP_S_PCIE_RP1, - PCI_DID_INTEL_ADP_S_PCIE_RP2, - PCI_DID_INTEL_ADP_S_PCIE_RP3, - PCI_DID_INTEL_ADP_S_PCIE_RP4, - PCI_DID_INTEL_ADP_S_PCIE_RP5, - PCI_DID_INTEL_ADP_S_PCIE_RP6, - PCI_DID_INTEL_ADP_S_PCIE_RP7, - PCI_DID_INTEL_ADP_S_PCIE_RP8, - PCI_DID_INTEL_ADP_S_PCIE_RP9, - PCI_DID_INTEL_ADP_S_PCIE_RP10, - PCI_DID_INTEL_ADP_S_PCIE_RP11, - PCI_DID_INTEL_ADP_S_PCIE_RP12, - PCI_DID_INTEL_ADP_S_PCIE_RP13, - PCI_DID_INTEL_ADP_S_PCIE_RP14, - PCI_DID_INTEL_ADP_S_PCIE_RP15, - PCI_DID_INTEL_ADP_S_PCIE_RP16, - PCI_DID_INTEL_ADP_S_PCIE_RP17, - PCI_DID_INTEL_ADP_S_PCIE_RP18, - PCI_DID_INTEL_ADP_S_PCIE_RP19, - PCI_DID_INTEL_ADP_S_PCIE_RP20, - PCI_DID_INTEL_ADP_S_PCIE_RP21, - PCI_DID_INTEL_ADP_S_PCIE_RP22, - PCI_DID_INTEL_ADP_S_PCIE_RP23, - PCI_DID_INTEL_ADP_S_PCIE_RP24, - PCI_DID_INTEL_ADP_S_PCIE_RP25, - PCI_DID_INTEL_ADP_S_PCIE_RP26, - PCI_DID_INTEL_ADP_S_PCIE_RP27, - PCI_DID_INTEL_ADP_S_PCIE_RP28, - PCI_DID_INTEL_ADP_M_N_PCIE_RP1, - PCI_DID_INTEL_ADP_M_N_PCIE_RP2, - PCI_DID_INTEL_ADP_M_N_PCIE_RP3, - PCI_DID_INTEL_ADP_M_N_PCIE_RP4, - PCI_DID_INTEL_ADP_M_PCIE_RP5, - PCI_DID_INTEL_ADP_M_PCIE_RP6, - PCI_DID_INTEL_ADP_M_N_PCIE_RP7, - PCI_DID_INTEL_ADP_M_PCIE_RP8, - PCI_DID_INTEL_ADP_M_N_PCIE_RP9, - PCI_DID_INTEL_ADP_M_N_PCIE_RP10, - PCI_DID_INTEL_ADP_N_PCIE_RP11, - PCI_DID_INTEL_ADP_N_PCIE_RP12, - PCI_DID_INTEL_RPP_S_PCIE_RP1, - PCI_DID_INTEL_RPP_S_PCIE_RP2, - PCI_DID_INTEL_RPP_S_PCIE_RP3, - PCI_DID_INTEL_RPP_S_PCIE_RP4, - PCI_DID_INTEL_RPP_S_PCIE_RP5, - PCI_DID_INTEL_RPP_S_PCIE_RP6, - PCI_DID_INTEL_RPP_S_PCIE_RP7, - PCI_DID_INTEL_RPP_S_PCIE_RP8, - PCI_DID_INTEL_RPP_S_PCIE_RP9, - PCI_DID_INTEL_RPP_S_PCIE_RP10, - PCI_DID_INTEL_RPP_S_PCIE_RP11, - PCI_DID_INTEL_RPP_S_PCIE_RP12, - PCI_DID_INTEL_RPP_S_PCIE_RP13, - PCI_DID_INTEL_RPP_S_PCIE_RP14, - PCI_DID_INTEL_RPP_S_PCIE_RP15, - PCI_DID_INTEL_RPP_S_PCIE_RP16, - PCI_DID_INTEL_RPP_S_PCIE_RP17, - PCI_DID_INTEL_RPP_S_PCIE_RP18, - PCI_DID_INTEL_RPP_S_PCIE_RP19, - PCI_DID_INTEL_RPP_S_PCIE_RP20, - PCI_DID_INTEL_RPP_S_PCIE_RP21, - PCI_DID_INTEL_RPP_S_PCIE_RP22, - PCI_DID_INTEL_RPP_S_PCIE_RP23, - PCI_DID_INTEL_RPP_S_PCIE_RP24, - PCI_DID_INTEL_RPP_S_PCIE_RP25, - PCI_DID_INTEL_RPP_S_PCIE_RP26, - PCI_DID_INTEL_RPP_S_PCIE_RP27, - PCI_DID_INTEL_RPP_S_PCIE_RP28, 0 }; diff --git a/src/soc/intel/common/block/pcie/rtd3/rtd3.c b/src/soc/intel/common/block/pcie/rtd3/rtd3.c index 3a7c8b4afcb..06775f125b1 100644 --- a/src/soc/intel/common/block/pcie/rtd3/rtd3.c +++ b/src/soc/intel/common/block/pcie/rtd3/rtd3.c @@ -384,7 +384,7 @@ static void pcie_rtd3_acpi_fill_ssdt(const struct device *dev) static bool mutex_created = false; const struct soc_intel_common_block_pcie_rtd3_config *config = config_of(dev); - static const char *const power_res_states[] = {"_PR0"}; + static const char *const power_res_states[] = {"_PR0", "_PR3"}; const struct device *parent = dev->upstream->dev; const char *scope = acpi_device_path(parent); const struct opregion opregion = OPREGION("PXCS", PCI_CONFIG, 0, 0xff); diff --git a/src/soc/intel/common/block/pmc/pmc.c b/src/soc/intel/common/block/pmc/pmc.c index 09c08cdbb58..0b7a9495cef 100644 --- a/src/soc/intel/common/block/pmc/pmc.c +++ b/src/soc/intel/common/block/pmc/pmc.c @@ -111,6 +111,7 @@ struct device_operations pmc_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_PMC, PCI_DID_INTEL_WCL_PMC, PCI_DID_INTEL_PTL_H_PMC, PCI_DID_INTEL_PTL_U_H_PMC, @@ -128,7 +129,6 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_APL_PMC, PCI_DID_INTEL_GLK_PMC, PCI_DID_INTEL_CNP_H_PMC, - PCI_DID_INTEL_ICP_PMC, PCI_DID_INTEL_CMP_PMC, PCI_DID_INTEL_CMP_H_PMC, PCI_DID_INTEL_TGP_PMC, diff --git a/src/soc/intel/common/block/pmc/pmclib.c b/src/soc/intel/common/block/pmc/pmclib.c index 64b9bb997c6..dc36d30bdbf 100644 --- a/src/soc/intel/common/block/pmc/pmclib.c +++ b/src/soc/intel/common/block/pmc/pmclib.c @@ -632,14 +632,16 @@ static void pmc_control_poweroff(void) void poweroff(void) { - if (!ENV_ROMSTAGE_OR_BEFORE) { - pmc_control_poweroff(); - } else if (CONFIG(HAVE_EARLY_POWEROFF_SUPPORT)) { + if (CONFIG(HAVE_EARLY_POWEROFF_SUPPORT)) { platform_do_early_poweroff(); } else { - printk(BIOS_EMERG, "This platform cannot be powered off until the silicon" - " initialization is complete, hanging!\n"); - halt(); + if (!ENV_ROMSTAGE_OR_BEFORE) { + pmc_control_poweroff(); + } else { + printk(BIOS_EMERG, "This platform cannot be powered off until the silicon" + " initialization is complete, hanging!\n"); + halt(); + } } } diff --git a/src/soc/intel/common/block/sata/sata.c b/src/soc/intel/common/block/sata/sata.c index f406096c857..dd92b9d7ec2 100644 --- a/src/soc/intel/common/block/sata/sata.c +++ b/src/soc/intel/common/block/sata/sata.c @@ -35,13 +35,6 @@ struct device_operations sata_ops = { }; static const unsigned short pci_device_ids[] = { - PCI_DID_INTEL_MTL_SATA, - PCI_DID_INTEL_ARL_SATA, - PCI_DID_INTEL_ARP_S_SATA_1, - PCI_DID_INTEL_ARP_S_SATA_2, - PCI_DID_INTEL_RPP_P_SATA_1, - PCI_DID_INTEL_RPP_P_SATA_2, - PCI_DID_INTEL_RPP_S_SATA, PCI_DID_INTEL_LWB_SATA_AHCI, PCI_DID_INTEL_LWB_SSATA_AHCI, PCI_DID_INTEL_LWB_SATA_RAID, @@ -54,44 +47,7 @@ static const unsigned short pci_device_ids[] = { PCI_DID_INTEL_LWB_SATA_ALT_RST, PCI_DID_INTEL_LWB_SSATA_ALT, PCI_DID_INTEL_LWB_SSATA_ALT_RST, - PCI_DID_INTEL_CNL_SATA, - PCI_DID_INTEL_CNL_PREMIUM_SATA, - PCI_DID_INTEL_CNP_CMP_COMPAT_SATA, - PCI_DID_INTEL_CNP_H_SATA, - PCI_DID_INTEL_CNP_H_HALO_SATA, - PCI_DID_INTEL_CNP_LP_SATA, - PCI_DID_INTEL_ICP_U_SATA, - PCI_DID_INTEL_CMP_SATA, - PCI_DID_INTEL_CMP_PREMIUM_SATA, - PCI_DID_INTEL_CMP_LP_SATA, - PCI_DID_INTEL_CMP_H_SATA, - PCI_DID_INTEL_CMP_H_HALO_SATA, - PCI_DID_INTEL_CMP_H_PREMIUM_SATA, - PCI_DID_INTEL_TGP_LP_SATA, - PCI_DID_INTEL_TGP_SATA, - PCI_DID_INTEL_TGP_PREMIUM_SATA, - PCI_DID_INTEL_TGP_COMPAT_SATA, - PCI_DID_INTEL_TGP_H_SATA, PCI_DID_INTEL_MCC_AHCI_SATA, - PCI_DID_INTEL_JSP_SATA_1, - PCI_DID_INTEL_JSP_SATA_2, - PCI_DID_INTEL_ADP_P_SATA_1, - PCI_DID_INTEL_ADP_P_SATA_2, - PCI_DID_INTEL_ADP_P_SATA_3, - PCI_DID_INTEL_ADP_P_SATA_4, - PCI_DID_INTEL_ADP_P_SATA_5, - PCI_DID_INTEL_ADP_P_SATA_6, - PCI_DID_INTEL_ADP_S_SATA_1, - PCI_DID_INTEL_ADP_S_SATA_2, - PCI_DID_INTEL_ADP_S_SATA_3, - PCI_DID_INTEL_ADP_S_SATA_4, - PCI_DID_INTEL_ADP_S_SATA_5, - PCI_DID_INTEL_ADP_S_SATA_6, - PCI_DID_INTEL_ADP_M_SATA_1, - PCI_DID_INTEL_ADP_M_SATA_2, - PCI_DID_INTEL_ADP_M_SATA_3, - PCI_DID_INTEL_APL_SATA, - PCI_DID_INTEL_GLK_SATA, 0 }; diff --git a/src/soc/intel/common/block/scs/sd.c b/src/soc/intel/common/block/scs/sd.c index eee02009f18..84eac7ef75d 100644 --- a/src/soc/intel/common/block/scs/sd.c +++ b/src/soc/intel/common/block/scs/sd.c @@ -49,14 +49,8 @@ struct device_operations sd_ops = { }; static const unsigned short pci_device_ids[] = { - PCI_DID_INTEL_APL_SD, - PCI_DID_INTEL_CNL_SD, PCI_DID_INTEL_GLK_SD, - PCI_DID_INTEL_CNP_H_SD, - PCI_DID_INTEL_CMP_SD, - PCI_DID_INTEL_CMP_H_SD, PCI_DID_INTEL_MCC_SD, - PCI_DID_INTEL_JSP_SD, 0 }; diff --git a/src/soc/intel/common/block/smbus/smbus.c b/src/soc/intel/common/block/smbus/smbus.c index dba5ed29d82..573aea5b8e7 100644 --- a/src/soc/intel/common/block/smbus/smbus.c +++ b/src/soc/intel/common/block/smbus/smbus.c @@ -49,33 +49,11 @@ struct device_operations smbus_ops = { }; static const unsigned short pci_device_ids[] = { - PCI_DID_INTEL_WCL_SMBUS, - PCI_DID_INTEL_PTL_H_SMBUS, - PCI_DID_INTEL_PTL_U_H_SMBUS, PCI_DID_INTEL_LNL_SMBUS, - PCI_DID_INTEL_MTL_SMBUS, - PCI_DID_INTEL_ARL_SMBUS, - PCI_DID_INTEL_ARL_S_SMBUS, - PCI_DID_INTEL_ARP_S_SMBUS, - PCI_DID_INTEL_RPP_P_SMBUS, - PCI_DID_INTEL_RPP_S_SMBUS, - PCI_DID_INTEL_APL_SMBUS, - PCI_DID_INTEL_GLK_SMBUS, - PCI_DID_INTEL_CNL_SMBUS, - PCI_DID_INTEL_CNP_H_SMBUS, PCI_DID_INTEL_EBG_SMBUS, PCI_DID_INTEL_LWB_SMBUS_SUPER, PCI_DID_INTEL_LWB_SMBUS, - PCI_DID_INTEL_ICP_LP_SMBUS, - PCI_DID_INTEL_CMP_SMBUS, - PCI_DID_INTEL_CMP_H_SMBUS, - PCI_DID_INTEL_TGP_LP_SMBUS, - PCI_DID_INTEL_TGP_H_SMBUS, PCI_DID_INTEL_MCC_SMBUS, - PCI_DID_INTEL_JSP_SMBUS, - PCI_DID_INTEL_ADP_P_SMBUS, - PCI_DID_INTEL_ADP_S_SMBUS, - PCI_DID_INTEL_ADP_M_N_SMBUS, PCI_DID_INTEL_DNV_SMBUS_LEGACY, 0 }; diff --git a/src/soc/intel/common/block/smbus/tco.c b/src/soc/intel/common/block/smbus/tco.c index b7c99225909..fa462e0921e 100644 --- a/src/soc/intel/common/block/smbus/tco.c +++ b/src/soc/intel/common/block/smbus/tco.c @@ -102,15 +102,15 @@ static void tco_timer_disable(void) tco_write_reg(TCO1_CNT, tcocnt); } -/* Enable and initialize TCO intruder SMI */ -static void tco_intruder_smi_enable(void) +/* Configure TCO intruder routing */ +static void tco_intruder_smi_configure(void) { uint16_t tcocnt; - /* Make TCO issue an SMI on INTRD_DET assertion */ tcocnt = tco_read_reg(TCO2_CNT); tcocnt &= ~TCO2_INTRD_SEL_MASK; - tcocnt |= TCO2_INTRD_SEL_SMI; + if (CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_INTRUDER_SMI_ENABLE)) + tcocnt |= TCO2_INTRD_SEL_SMI; tco_write_reg(TCO2_CNT, tcocnt); } @@ -148,9 +148,8 @@ void tco_configure(void) tco_timer_disable(); - /* Enable intruder interrupt if TCO interrupts are enabled*/ if (CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE)) - tco_intruder_smi_enable(); + tco_intruder_smi_configure(); } uint32_t tco_get_timer_period(void) diff --git a/src/soc/intel/common/block/smm/Kconfig b/src/soc/intel/common/block/smm/Kconfig index 84c406ef3e0..446c371bce6 100644 --- a/src/soc/intel/common/block/smm/Kconfig +++ b/src/soc/intel/common/block/smm/Kconfig @@ -30,6 +30,15 @@ config SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE help Enable TCO SMI source to e.g. handle case instrusion. +config SOC_INTEL_COMMON_BLOCK_SMM_TCO_INTRUDER_SMI_ENABLE + bool "Enable TCO INTRUDER# SMI" + depends on SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE + default y + help + When enabled, route the TCO INTRUDER# event to SMI. + Some boards may see INTRUDER# asserted continuously. Routing it to + SMI would then cause an SMI storm and prevent boot. + config SOC_INTEL_COMMON_BLOCK_SMM_S5_DELAY_MS int default 100 if CHROMEOS diff --git a/src/soc/intel/common/block/smm/smihandler.c b/src/soc/intel/common/block/smm/smihandler.c index 59489a4f037..1af03739d24 100644 --- a/src/soc/intel/common/block/smm/smihandler.c +++ b/src/soc/intel/common/block/smm/smihandler.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -220,6 +222,9 @@ void smihandler_southbridge_sleep( break; } + /* Allow mainboard to restore wake sources (e.g. for S5 WOL). */ + mainboard_smi_sleep_finalize(slp_typ); + /* * Write back to the SLP register to cause the originally intended * event again. We need to set BIT13 (SLP_EN) though to make the @@ -349,7 +354,7 @@ static void finalize(void) /* Re-init SPI driver to handle locked BAR */ fast_spi_init(); - if (CONFIG(BOOTMEDIA_SMM_BWP)) { + if (enable_smm_bios_protection()) { fast_spi_enable_wp(); set_insmm_sts(false); } @@ -440,7 +445,7 @@ void smihandler_southbridge_tco( fast_spi_clear_sync_smi_status(); /* If enabled, enforce SMM BIOS write protection */ - if (CONFIG(BOOTMEDIA_SMM_BWP) && fast_spi_wpd_status()) { + if (enable_smm_bios_protection() && fast_spi_wpd_status()) { /* * BWE is RW, so the SMI was caused by a * write to BWE, not by a write to the BIOS diff --git a/src/soc/intel/common/block/spi/spi.c b/src/soc/intel/common/block/spi/spi.c index 1ac0de0d7c0..5c75a2240b9 100644 --- a/src/soc/intel/common/block/spi/spi.c +++ b/src/soc/intel/common/block/spi/spi.c @@ -123,91 +123,16 @@ struct device_operations spi_dev_ops = { }; static const unsigned short pci_device_ids[] = { - PCI_DID_INTEL_WCL_HWSEQ_SPI, - PCI_DID_INTEL_WCL_SPI0, - PCI_DID_INTEL_WCL_SPI1, - PCI_DID_INTEL_WCL_SPI2, - PCI_DID_INTEL_PTL_H_HWSEQ_SPI, - PCI_DID_INTEL_PTL_H_SPI0, - PCI_DID_INTEL_PTL_H_SPI1, - PCI_DID_INTEL_PTL_H_SPI2, - PCI_DID_INTEL_PTL_U_H_HWSEQ_SPI, - PCI_DID_INTEL_PTL_U_H_SPI0, - PCI_DID_INTEL_PTL_U_H_SPI1, - PCI_DID_INTEL_PTL_U_H_SPI2, + PCI_DID_INTEL_NVL_HWSEQ_SPI, + PCI_DID_INTEL_NVL_SPI0, + PCI_DID_INTEL_NVL_SPI1, + PCI_DID_INTEL_NVL_SPI2, PCI_DID_INTEL_LNL_GSPI0, PCI_DID_INTEL_LNL_GSPI1, PCI_DID_INTEL_LNL_GSPI2, - PCI_DID_INTEL_MTL_GSPI0, - PCI_DID_INTEL_MTL_GSPI1, - PCI_DID_INTEL_MTL_GSPI2, - PCI_DID_INTEL_ARL_GSPI0, - PCI_DID_INTEL_ARL_GSPI1, - PCI_DID_INTEL_ARL_GSPI2, - PCI_DID_INTEL_ARP_S_GSPI0, - PCI_DID_INTEL_ARP_S_GSPI1, - PCI_DID_INTEL_ARP_S_GSPI2, - PCI_DID_INTEL_ARP_S_GSPI3, - PCI_DID_INTEL_APL_SPI0, - PCI_DID_INTEL_APL_SPI1, - PCI_DID_INTEL_APL_SPI2, - PCI_DID_INTEL_GLK_SPI0, - PCI_DID_INTEL_GLK_SPI1, - PCI_DID_INTEL_GLK_SPI2, - PCI_DID_INTEL_CNL_SPI0, - PCI_DID_INTEL_CNL_SPI1, - PCI_DID_INTEL_CNL_SPI2, - PCI_DID_INTEL_CNP_H_SPI0, - PCI_DID_INTEL_CNP_H_SPI1, - PCI_DID_INTEL_CNP_H_SPI2, - PCI_DID_INTEL_ICP_SPI0, - PCI_DID_INTEL_ICP_SPI1, - PCI_DID_INTEL_ICP_SPI2, - PCI_DID_INTEL_CMP_SPI0, - PCI_DID_INTEL_CMP_SPI1, - PCI_DID_INTEL_CMP_SPI2, - PCI_DID_INTEL_CMP_H_SPI0, - PCI_DID_INTEL_CMP_H_SPI1, - PCI_DID_INTEL_CMP_H_SPI2, - PCI_DID_INTEL_TGP_GSPI0, - PCI_DID_INTEL_TGP_GSPI1, - PCI_DID_INTEL_TGP_GSPI2, - PCI_DID_INTEL_TGP_GSPI3, - PCI_DID_INTEL_TGP_GSPI4, - PCI_DID_INTEL_TGP_GSPI5, - PCI_DID_INTEL_TGP_GSPI6, - PCI_DID_INTEL_TGP_H_SPI0, - PCI_DID_INTEL_TGP_H_GSPI0, - PCI_DID_INTEL_TGP_H_GSPI1, - PCI_DID_INTEL_TGP_H_GSPI2, - PCI_DID_INTEL_TGP_H_GSPI3, PCI_DID_INTEL_MCC_GSPI0, PCI_DID_INTEL_MCC_GSPI1, PCI_DID_INTEL_MCC_GSPI2, - PCI_DID_INTEL_JSP_SPI0, - PCI_DID_INTEL_JSP_SPI1, - PCI_DID_INTEL_JSP_SPI2, - PCI_DID_INTEL_ADP_P_SPI0, - PCI_DID_INTEL_ADP_P_SPI1, - PCI_DID_INTEL_ADP_P_SPI2, - PCI_DID_INTEL_ADP_P_SPI3, - PCI_DID_INTEL_ADP_P_SPI4, - PCI_DID_INTEL_ADP_P_SPI5, - PCI_DID_INTEL_ADP_P_SPI6, - PCI_DID_INTEL_ADP_S_SPI0, - PCI_DID_INTEL_ADP_S_SPI1, - PCI_DID_INTEL_ADP_S_SPI2, - PCI_DID_INTEL_ADP_S_SPI3, - PCI_DID_INTEL_ADP_S_SPI4, - PCI_DID_INTEL_ADP_S_SPI5, - PCI_DID_INTEL_ADP_S_SPI6, - PCI_DID_INTEL_ADP_M_N_SPI0, - PCI_DID_INTEL_ADP_M_N_SPI1, - PCI_DID_INTEL_ADP_M_SPI2, - PCI_DID_INTEL_RPP_S_SPI0, - PCI_DID_INTEL_RPP_S_SPI1, - PCI_DID_INTEL_RPP_S_SPI2, - PCI_DID_INTEL_RPP_S_SPI3, PCI_DID_INTEL_DNV_SPI, 0 }; diff --git a/src/soc/intel/common/block/sram/sram.c b/src/soc/intel/common/block/sram/sram.c index ba2ed8616fa..cc51bcd084f 100644 --- a/src/soc/intel/common/block/sram/sram.c +++ b/src/soc/intel/common/block/sram/sram.c @@ -33,6 +33,8 @@ static const struct device_operations device_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_SRAM, + PCI_DID_INTEL_NVL_PUNIT_CRASHLOG_SRAM, PCI_DID_INTEL_WCL_SRAM, PCI_DID_INTEL_WCL_PUNIT_CRASHLOG_SRAM, PCI_DID_INTEL_PTL_H_SRAM, diff --git a/src/soc/intel/common/block/systemagent/memmap.c b/src/soc/intel/common/block/systemagent/memmap.c index 3b0fb6e8aee..9a3971098f6 100644 --- a/src/soc/intel/common/block/systemagent/memmap.c +++ b/src/soc/intel/common/block/systemagent/memmap.c @@ -54,7 +54,7 @@ void smm_region(uintptr_t *start, size_t *size) { *start = sa_get_tseg_base(); - *size = sa_get_tseg_size(); + *size = CONFIG_SMM_TSEG_SIZE; } void fill_postcar_frame(struct postcar_frame *pcf) diff --git a/src/soc/intel/common/block/systemagent/systemagent.c b/src/soc/intel/common/block/systemagent/systemagent.c index 749e9c6ad94..7ea802ae06d 100644 --- a/src/soc/intel/common/block/systemagent/systemagent.c +++ b/src/soc/intel/common/block/systemagent/systemagent.c @@ -425,6 +425,11 @@ struct device_operations systemagent_ops = { }; static const unsigned short systemagent_ids[] = { + PCI_DID_INTEL_NVL_ID_1, + PCI_DID_INTEL_NVL_ID_2, + PCI_DID_INTEL_NVL_ID_3, + PCI_DID_INTEL_NVL_ID_4, + PCI_DID_INTEL_NVL_ID_5, PCI_DID_INTEL_WCL_ID_1, PCI_DID_INTEL_WCL_ID_2, PCI_DID_INTEL_WCL_ID_3, diff --git a/src/soc/intel/common/block/systemagent/systemagent_early.c b/src/soc/intel/common/block/systemagent/systemagent_early.c index aecdfbb429f..993d008eb66 100644 --- a/src/soc/intel/common/block/systemagent/systemagent_early.c +++ b/src/soc/intel/common/block/systemagent/systemagent_early.c @@ -146,11 +146,6 @@ uintptr_t sa_get_tseg_base(void) return ALIGN_DOWN(pci_read_config32(SA_DEV_ROOT, TSEG), 1*MiB); } -size_t sa_get_tseg_size(void) -{ - return sa_get_gsm_base() - sa_get_tseg_base(); -} - union dpr_register txt_get_chipset_dpr(void) { return (union dpr_register) { .raw = pci_read_config32(SA_DEV_ROOT, DPR) }; diff --git a/src/soc/intel/common/block/tracehub/tracehub.c b/src/soc/intel/common/block/tracehub/tracehub.c index dc8c3fd2d6f..1341779630d 100644 --- a/src/soc/intel/common/block/tracehub/tracehub.c +++ b/src/soc/intel/common/block/tracehub/tracehub.c @@ -42,6 +42,7 @@ static struct device_operations dev_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_TRACEHUB, PCI_DID_INTEL_WCL_TRACEHUB, PCI_DID_INTEL_PTL_H_TRACEHUB, PCI_DID_INTEL_PTL_U_H_TRACEHUB, diff --git a/src/soc/intel/common/block/uart/uart.c b/src/soc/intel/common/block/uart/uart.c index 8133551a276..f16d337e644 100644 --- a/src/soc/intel/common/block/uart/uart.c +++ b/src/soc/intel/common/block/uart/uart.c @@ -308,6 +308,7 @@ static const char *uart_acpi_hid(const struct device *dev) static const char *uart_acpi_name(const struct device *dev) { switch (dev->device) { + case PCI_DID_INTEL_NVL_UART0: case PCI_DID_INTEL_WCL_UART0: case PCI_DID_INTEL_PTL_H_UART0: case PCI_DID_INTEL_PTL_U_H_UART0: @@ -319,6 +320,7 @@ static const char *uart_acpi_name(const struct device *dev) case PCI_DID_INTEL_SPT_H_UART0: case PCI_DID_INTEL_CNP_H_UART0: return "UAR0"; + case PCI_DID_INTEL_NVL_UART1: case PCI_DID_INTEL_WCL_UART1: case PCI_DID_INTEL_PTL_H_UART1: case PCI_DID_INTEL_PTL_U_H_UART1: @@ -330,6 +332,7 @@ static const char *uart_acpi_name(const struct device *dev) case PCI_DID_INTEL_SPT_H_UART1: case PCI_DID_INTEL_CNP_H_UART1: return "UAR1"; + case PCI_DID_INTEL_NVL_UART2: case PCI_DID_INTEL_WCL_UART2: case PCI_DID_INTEL_PTL_H_UART2: case PCI_DID_INTEL_PTL_U_H_UART2: @@ -360,86 +363,15 @@ struct device_operations uart_ops = { }; static const unsigned short pci_device_ids[] = { - PCI_DID_INTEL_WCL_UART0, - PCI_DID_INTEL_WCL_UART1, - PCI_DID_INTEL_WCL_UART2, - PCI_DID_INTEL_PTL_H_UART0, - PCI_DID_INTEL_PTL_H_UART1, - PCI_DID_INTEL_PTL_H_UART2, - PCI_DID_INTEL_PTL_U_H_UART0, - PCI_DID_INTEL_PTL_U_H_UART1, - PCI_DID_INTEL_PTL_U_H_UART2, + PCI_DID_INTEL_NVL_UART0, + PCI_DID_INTEL_NVL_UART1, + PCI_DID_INTEL_NVL_UART2, PCI_DID_INTEL_LNL_UART0, PCI_DID_INTEL_LNL_UART1, PCI_DID_INTEL_LNL_UART2, - PCI_DID_INTEL_MTL_UART0, - PCI_DID_INTEL_MTL_UART1, - PCI_DID_INTEL_MTL_UART2, - PCI_DID_INTEL_ARL_UART0, - PCI_DID_INTEL_ARL_UART1, - PCI_DID_INTEL_ARL_UART2, - PCI_DID_INTEL_ARP_S_UART0, - PCI_DID_INTEL_ARP_S_UART1, - PCI_DID_INTEL_ARP_S_UART2, - PCI_DID_INTEL_ARP_S_UART3, - PCI_DID_INTEL_APL_UART0, - PCI_DID_INTEL_APL_UART1, - PCI_DID_INTEL_APL_UART2, - PCI_DID_INTEL_APL_UART3, - PCI_DID_INTEL_CNL_UART0, - PCI_DID_INTEL_CNL_UART1, - PCI_DID_INTEL_CNL_UART2, - PCI_DID_INTEL_GLK_UART0, - PCI_DID_INTEL_GLK_UART1, - PCI_DID_INTEL_GLK_UART2, - PCI_DID_INTEL_GLK_UART3, - PCI_DID_INTEL_CNP_H_UART0, - PCI_DID_INTEL_CNP_H_UART1, - PCI_DID_INTEL_CNP_H_UART2, - PCI_DID_INTEL_ICP_UART0, - PCI_DID_INTEL_ICP_UART1, - PCI_DID_INTEL_ICP_UART2, - PCI_DID_INTEL_CMP_UART0, - PCI_DID_INTEL_CMP_UART1, - PCI_DID_INTEL_CMP_UART2, - PCI_DID_INTEL_CMP_H_UART0, - PCI_DID_INTEL_CMP_H_UART1, - PCI_DID_INTEL_CMP_H_UART2, - PCI_DID_INTEL_TGP_UART0, - PCI_DID_INTEL_TGP_UART1, - PCI_DID_INTEL_TGP_UART2, - PCI_DID_INTEL_TGP_H_UART0, - PCI_DID_INTEL_TGP_H_UART1, - PCI_DID_INTEL_TGP_H_UART2, - PCI_DID_INTEL_TGP_H_UART3, PCI_DID_INTEL_MCC_UART0, PCI_DID_INTEL_MCC_UART1, PCI_DID_INTEL_MCC_UART2, - PCI_DID_INTEL_JSP_UART0, - PCI_DID_INTEL_JSP_UART1, - PCI_DID_INTEL_JSP_UART2, - PCI_DID_INTEL_ADP_S_UART0, - PCI_DID_INTEL_ADP_S_UART1, - PCI_DID_INTEL_ADP_S_UART2, - PCI_DID_INTEL_ADP_S_UART3, - PCI_DID_INTEL_ADP_S_UART4, - PCI_DID_INTEL_ADP_S_UART5, - PCI_DID_INTEL_ADP_S_UART6, - PCI_DID_INTEL_ADP_P_UART0, - PCI_DID_INTEL_ADP_P_UART1, - PCI_DID_INTEL_ADP_P_UART2, - PCI_DID_INTEL_ADP_P_UART3, - PCI_DID_INTEL_ADP_P_UART4, - PCI_DID_INTEL_ADP_P_UART5, - PCI_DID_INTEL_ADP_P_UART6, - PCI_DID_INTEL_ADP_M_N_UART0, - PCI_DID_INTEL_ADP_M_N_UART1, - PCI_DID_INTEL_ADP_M_N_UART2, - PCI_DID_INTEL_ADP_M_N_UART3, - PCI_DID_INTEL_RPP_S_UART0, - PCI_DID_INTEL_RPP_S_UART1, - PCI_DID_INTEL_RPP_S_UART2, - PCI_DID_INTEL_RPP_S_UART3, 0, }; diff --git a/src/soc/intel/common/block/usb4/usb4.c b/src/soc/intel/common/block/usb4/usb4.c index 9d176a3695e..1daaf86fbb4 100644 --- a/src/soc/intel/common/block/usb4/usb4.c +++ b/src/soc/intel/common/block/usb4/usb4.c @@ -52,6 +52,7 @@ static void tbt_dma_fill_ssdt(const struct device *dev) #endif static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_TBT_DMA0, PCI_DID_INTEL_WCL_TBT_DMA0, PCI_DID_INTEL_PTL_TBT_DMA0, PCI_DID_INTEL_PTL_TBT_DMA1, diff --git a/src/soc/intel/common/block/usb4/xhci.c b/src/soc/intel/common/block/usb4/xhci.c index a23845820aa..ac455f284ca 100644 --- a/src/soc/intel/common/block/usb4/xhci.c +++ b/src/soc/intel/common/block/usb4/xhci.c @@ -26,6 +26,7 @@ static struct device_operations usb4_xhci_ops = { }; static const unsigned short pci_device_ids[] = { + PCI_DID_INTEL_NVL_TCSS_XHCI, PCI_DID_INTEL_WCL_TCSS_XHCI, PCI_DID_INTEL_PTL_H_TCSS_XHCI, PCI_DID_INTEL_PTL_U_H_TCSS_XHCI, diff --git a/src/soc/intel/common/block/xdci/xdci.c b/src/soc/intel/common/block/xdci/xdci.c index ed6a15b363f..28f8231e7be 100644 --- a/src/soc/intel/common/block/xdci/xdci.c +++ b/src/soc/intel/common/block/xdci/xdci.c @@ -28,27 +28,8 @@ struct device_operations usb_xdci_ops = { }; static const unsigned short pci_device_ids[] = { - PCI_DID_INTEL_WCL_XDCI, - PCI_DID_INTEL_PTL_H_XDCI, - PCI_DID_INTEL_PTL_U_H_XDCI, - PCI_DID_INTEL_MTL_XDCI, - PCI_DID_INTEL_ARL_XDCI, - PCI_DID_INTEL_ARP_S_XDCI, - PCI_DID_INTEL_APL_XDCI, - PCI_DID_INTEL_CNL_LP_XDCI, - PCI_DID_INTEL_GLK_XDCI, - PCI_DID_INTEL_CNP_H_XDCI, - PCI_DID_INTEL_ICP_LP_XDCI, - PCI_DID_INTEL_CMP_LP_XDCI, - PCI_DID_INTEL_CMP_H_XDCI, - PCI_DID_INTEL_TGP_LP_XDCI, - PCI_DID_INTEL_TGP_H_XDCI, + PCI_DID_INTEL_NVL_XDCI, PCI_DID_INTEL_MCC_XDCI, - PCI_DID_INTEL_JSP_XDCI, - PCI_DID_INTEL_ADP_P_XDCI, - PCI_DID_INTEL_ADP_S_XDCI, - PCI_DID_INTEL_ADP_M_XDCI, - PCI_DID_INTEL_RPP_S_XDCI, 0 }; diff --git a/src/soc/intel/common/block/xhci/xhci.c b/src/soc/intel/common/block/xhci/xhci.c index 8350c3650b3..a7b56e8d5cf 100644 --- a/src/soc/intel/common/block/xhci/xhci.c +++ b/src/soc/intel/common/block/xhci/xhci.c @@ -131,30 +131,11 @@ struct device_operations usb_xhci_ops = { }; static const unsigned short pci_device_ids[] = { - PCI_DID_INTEL_WCL_XHCI, - PCI_DID_INTEL_PTL_H_XHCI, - PCI_DID_INTEL_PTL_U_H_XHCI, + PCI_DID_INTEL_NVL_XHCI, PCI_DID_INTEL_LNL_XHCI, - PCI_DID_INTEL_MTL_XHCI, - PCI_DID_INTEL_ARL_XHCI, - PCI_DID_INTEL_ARP_S_XHCI, - PCI_DID_INTEL_APL_XHCI, - PCI_DID_INTEL_CNL_LP_XHCI, - PCI_DID_INTEL_GLK_XHCI, PCI_DID_INTEL_LWB_XHCI, PCI_DID_INTEL_LWB_XHCI_SUPER, - PCI_DID_INTEL_CNP_H_XHCI, - PCI_DID_INTEL_ICP_LP_XHCI, - PCI_DID_INTEL_CMP_LP_XHCI, - PCI_DID_INTEL_CMP_H_XHCI, - PCI_DID_INTEL_TGP_LP_XHCI, - PCI_DID_INTEL_TGP_H_XHCI, PCI_DID_INTEL_MCC_XHCI, - PCI_DID_INTEL_JSP_XHCI, - PCI_DID_INTEL_ADP_P_XHCI, - PCI_DID_INTEL_ADP_S_XHCI, - PCI_DID_INTEL_ADP_M_XHCI, - PCI_DID_INTEL_RPP_S_XHCI, PCI_DID_INTEL_SNR_XHCI, 0 }; diff --git a/src/soc/intel/common/feature/Kconfig b/src/soc/intel/common/feature/Kconfig new file mode 100644 index 00000000000..357ebf36438 --- /dev/null +++ b/src/soc/intel/common/feature/Kconfig @@ -0,0 +1,18 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE + bool + help + Intel SoC common feature code. This option enables sharing of + SoC-specific code across Intel SoC generations to reduce code + duplication. Unlike the common block code which is intended for + reusable IP blocks, the feature code is for SoC-specific + functionality that is similar across multiple generations but + may have minor platform-specific differences handled through + configuration options or platform-specific macros. + +if SOC_INTEL_COMMON_FEATURE + +source "src/soc/intel/common/feature/*/Kconfig" + +endif diff --git a/src/soc/intel/common/feature/Makefile.mk b/src/soc/intel/common/feature/Makefile.mk new file mode 100644 index 00000000000..62cccaad42b --- /dev/null +++ b/src/soc/intel/common/feature/Makefile.mk @@ -0,0 +1,6 @@ +## SPDX-License-Identifier: GPL-2.0-only +ifeq ($(CONFIG_SOC_INTEL_COMMON_FEATURE),y) + +subdirs-y += ./* + +endif diff --git a/src/soc/intel/common/feature/espi/Kconfig b/src/soc/intel/common/feature/espi/Kconfig new file mode 100644 index 00000000000..521c7bbe5c2 --- /dev/null +++ b/src/soc/intel/common/feature/espi/Kconfig @@ -0,0 +1,8 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_ESPI + bool + help + Select this if the platform supports common eSPI/LPC initialization + with generic IO decode range configuration and standard interrupt + setup. This is applicable for most modern Intel client platforms. diff --git a/src/soc/intel/common/feature/espi/Makefile.mk b/src/soc/intel/common/feature/espi/Makefile.mk new file mode 100644 index 00000000000..69542218b32 --- /dev/null +++ b/src/soc/intel/common/feature/espi/Makefile.mk @@ -0,0 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + +bootblock-$(CONFIG_SOC_INTEL_COMMON_FEATURE_ESPI) += espi.c +romstage-$(CONFIG_SOC_INTEL_COMMON_FEATURE_ESPI) += espi.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_FEATURE_ESPI) += espi.c diff --git a/src/soc/intel/meteorlake/espi.c b/src/soc/intel/common/feature/espi/espi.c similarity index 95% rename from src/soc/intel/meteorlake/espi.c rename to src/soc/intel/common/feature/espi/espi.c index 98fd9fc045b..b0620c683d9 100644 --- a/src/soc/intel/meteorlake/espi.c +++ b/src/soc/intel/common/feature/espi/espi.c @@ -1,17 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include -#include -#include #include +#include #include #include -#include #include +#include +#include #include #include #include -#include #include #include diff --git a/src/soc/intel/common/feature/finalize/Kconfig b/src/soc/intel/common/feature/finalize/Kconfig new file mode 100644 index 00000000000..87a48b22a4e --- /dev/null +++ b/src/soc/intel/common/feature/finalize/Kconfig @@ -0,0 +1,8 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_FINALIZE + bool + help + Include common finalize implementation for Intel SoCs. This driver + consolidates the nearly identical finalize implementations across + Meteor Lake and Panther Lake platforms. diff --git a/src/soc/intel/common/feature/finalize/Makefile.mk b/src/soc/intel/common/feature/finalize/Makefile.mk new file mode 100644 index 00000000000..7f56bee8572 --- /dev/null +++ b/src/soc/intel/common/feature/finalize/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-$(CONFIG_SOC_INTEL_COMMON_FEATURE_FINALIZE) += finalize.c diff --git a/src/soc/intel/meteorlake/finalize.c b/src/soc/intel/common/feature/finalize/finalize.c similarity index 85% rename from src/soc/intel/meteorlake/finalize.c rename to src/soc/intel/common/feature/finalize/finalize.c index 1fd1d98fb5f..7830fb8e637 100644 --- a/src/soc/intel/meteorlake/finalize.c +++ b/src/soc/intel/common/feature/finalize/finalize.c @@ -1,28 +1,24 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include #include #include #include #include -#include +#include #include -#include -#include #include #include #include -#include -#include #include -#include #include -#include -#include -#include -#include #include +/* + * Common finalize implementation for Intel SoCs. + * This consolidates the nearly identical finalize.c implementations + * across Meteor Lake and Panther Lake platforms. + */ + static void pch_finalize(void) { /* TCO Lock down */ diff --git a/src/soc/intel/common/feature/globalreset/Kconfig b/src/soc/intel/common/feature/globalreset/Kconfig new file mode 100644 index 00000000000..77c695d51a6 --- /dev/null +++ b/src/soc/intel/common/feature/globalreset/Kconfig @@ -0,0 +1,9 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC + bool + help + Include common implementation of do_global_reset() that uses CSE + (Converged Security Engine) with PMC (Power Management Controller) + fallback. This implementation is identical across multiple Intel + client platforms. diff --git a/src/soc/intel/common/feature/globalreset/Makefile.mk b/src/soc/intel/common/feature/globalreset/Makefile.mk new file mode 100644 index 00000000000..cff5f7a5e5a --- /dev/null +++ b/src/soc/intel/common/feature/globalreset/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +all-$(CONFIG_SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC) += global_reset_cse_pmc.c diff --git a/src/soc/intel/alderlake/reset.c b/src/soc/intel/common/feature/globalreset/global_reset_cse_pmc.c similarity index 100% rename from src/soc/intel/alderlake/reset.c rename to src/soc/intel/common/feature/globalreset/global_reset_cse_pmc.c diff --git a/src/soc/intel/common/feature/gspi/Kconfig b/src/soc/intel/common/feature/gspi/Kconfig new file mode 100644 index 00000000000..4ac4e47693b --- /dev/null +++ b/src/soc/intel/common/feature/gspi/Kconfig @@ -0,0 +1,9 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + bool + help + Common GSPI device function to bus mapping implementation. + SoCs using this must define SOC_GSPI_DEVFN(n) macro in their + pci_devs.h and CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX in their + Kconfig. diff --git a/src/soc/intel/common/feature/gspi/Makefile.mk b/src/soc/intel/common/feature/gspi/Makefile.mk new file mode 100644 index 00000000000..6ac84bac548 --- /dev/null +++ b/src/soc/intel/common/feature/gspi/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +all-$(CONFIG_SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN) += gspi_devfn.c diff --git a/src/soc/intel/common/feature/gspi/gspi_devfn.c b/src/soc/intel/common/feature/gspi/gspi_devfn.c new file mode 100644 index 00000000000..23cdaaaf14e --- /dev/null +++ b/src/soc/intel/common/feature/gspi/gspi_devfn.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include + +/* + * Ensure the platform defines SOC_GSPI_DEVFN(n) macro to map GSPI bus numbers + * to their PCI device/function values. The macro should be defined in the + * platform's soc/pci_devs.h header. + */ + +_Static_assert(CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX <= 7, + "CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX greater than 7 is not supported."); + +int gspi_soc_bus_to_devfn(unsigned int gspi_bus) +{ + switch (gspi_bus) { + case 0: + return SOC_GSPI_DEVFN(0); + case 1: + return SOC_GSPI_DEVFN(1); +#if CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX > 2 + case 2: + return SOC_GSPI_DEVFN(2); +#endif +#if CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX > 3 + case 3: + return SOC_GSPI_DEVFN(3); +#endif +#if CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX > 4 + case 4: + return SOC_GSPI_DEVFN(4); +#endif +#if CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX > 5 + case 5: + return SOC_GSPI_DEVFN(5); +#endif +#if CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX > 6 + case 6: + return SOC_GSPI_DEVFN(6); +#endif + } + return -1; +} diff --git a/src/soc/intel/common/feature/i2c/Kconfig b/src/soc/intel/common/feature/i2c/Kconfig new file mode 100644 index 00000000000..5dede903d33 --- /dev/null +++ b/src/soc/intel/common/feature/i2c/Kconfig @@ -0,0 +1,8 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_I2C_DEVFN + bool + help + Common I2C device function to bus mapping implementation. + SoCs using this must define SOC_I2C_DEVFN(n) macro in their + pci_devs.h and CONFIG_SOC_INTEL_I2C_DEV_MAX in their Kconfig. diff --git a/src/soc/intel/common/feature/i2c/Makefile.mk b/src/soc/intel/common/feature/i2c/Makefile.mk new file mode 100644 index 00000000000..2b4a6ab6fb2 --- /dev/null +++ b/src/soc/intel/common/feature/i2c/Makefile.mk @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +all-$(CONFIG_SOC_INTEL_COMMON_FEATURE_I2C_DEVFN) += i2c_devfn.c +smm-$(CONFIG_SOC_INTEL_COMMON_FEATURE_I2C_DEVFN) += i2c_devfn.c diff --git a/src/soc/intel/common/feature/i2c/i2c_devfn.c b/src/soc/intel/common/feature/i2c/i2c_devfn.c new file mode 100644 index 00000000000..e8adb2fe4b4 --- /dev/null +++ b/src/soc/intel/common/feature/i2c/i2c_devfn.c @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +/* + * SoC-specific I2C device function to bus number mapping. + * + * Each SoC must define: + * - CONFIG_SOC_INTEL_I2C_DEV_MAX: Maximum number of I2C controllers + * - SOC_I2C_DEVFN(n): Macro that expands to the SoC-specific I2C device + * function name (e.g., PCH_DEVFN_I2Cn or PCI_DEVFN_I2Cn) + */ + +_Static_assert(CONFIG_SOC_INTEL_I2C_DEV_MAX <= 8, + "CONFIG_SOC_INTEL_I2C_DEV_MAX greater than 8 is not supported."); + +int dw_i2c_soc_devfn_to_bus(unsigned int devfn) +{ + switch (devfn) { + case SOC_I2C_DEVFN(0): + return 0; + case SOC_I2C_DEVFN(1): + return 1; + case SOC_I2C_DEVFN(2): + return 2; + case SOC_I2C_DEVFN(3): + return 3; +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 4 + case SOC_I2C_DEVFN(4): + return 4; +#endif +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 5 + case SOC_I2C_DEVFN(5): + return 5; +#endif +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 6 + case SOC_I2C_DEVFN(6): + return 6; +#endif +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 7 + case SOC_I2C_DEVFN(7): + return 7; +#endif + } + return -1; +} + +int dw_i2c_soc_bus_to_devfn(unsigned int bus) +{ + switch (bus) { + case 0: + return SOC_I2C_DEVFN(0); + case 1: + return SOC_I2C_DEVFN(1); + case 2: + return SOC_I2C_DEVFN(2); + case 3: + return SOC_I2C_DEVFN(3); +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 4 + case 4: + return SOC_I2C_DEVFN(4); +#endif +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 5 + case 5: + return SOC_I2C_DEVFN(5); +#endif +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 6 + case 6: + return SOC_I2C_DEVFN(6); +#endif +#if CONFIG_SOC_INTEL_I2C_DEV_MAX > 7 + case 7: + return SOC_I2C_DEVFN(7); +#endif + } + return -1; +} diff --git a/src/soc/intel/common/feature/lockdown/Kconfig b/src/soc/intel/common/feature/lockdown/Kconfig new file mode 100644 index 00000000000..75a59b0d629 --- /dev/null +++ b/src/soc/intel/common/feature/lockdown/Kconfig @@ -0,0 +1,8 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_LOCKDOWN + bool + help + Include common PMC lockdown driver for Intel SoCs. This driver + consolidates the nearly identical PMC lockdown implementations + across multiple Intel platform generations. diff --git a/src/soc/intel/common/feature/lockdown/Makefile.mk b/src/soc/intel/common/feature/lockdown/Makefile.mk new file mode 100644 index 00000000000..6a39d8a3096 --- /dev/null +++ b/src/soc/intel/common/feature/lockdown/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-$(CONFIG_SOC_INTEL_COMMON_FEATURE_LOCKDOWN) += lockdown.c diff --git a/src/soc/intel/meteorlake/lockdown.c b/src/soc/intel/common/feature/lockdown/lockdown.c similarity index 81% rename from src/soc/intel/meteorlake/lockdown.c rename to src/soc/intel/common/feature/lockdown/lockdown.c index 324c37ba385..5da2bd93bd1 100644 --- a/src/soc/intel/meteorlake/lockdown.c +++ b/src/soc/intel/common/feature/lockdown/lockdown.c @@ -7,13 +7,14 @@ #include #include #include +#include #include /* PCR PSTH Control Register */ -#define PCR_PSTH_CTRLREG 0x1d00 -#define PSTH_CTRLREG_IOSFPTCGE (1 << 2) +#define PCR_PSTH_CTRLREG 0x1d00 +#define PSTH_CTRLREG_IOSFPTCGE BIT(2) -static void pmc_lockdown_cfg(int chipset_lockdown) +static void pmc_lockdown_config(int chipset_lockdown) { uint8_t *pmcbase = pmc_mmio_regs(); @@ -26,7 +27,7 @@ static void pmc_lockdown_cfg(int chipset_lockdown) setbits32(pmcbase + GEN_PMCON_B, SMI_LOCK); if (!CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM)) { - setbits32(pmcbase + GEN_PMCON_B, ST_FDIS_LOCK); + setbits32(pmcbase + PMC_FDIS_LOCK_REG, ST_FDIS_LOCK); setbits32(pmcbase + SSML, SSML_SSL_EN); setbits32(pmcbase + PM_CFG, PM_CFG_DBG_MODE_LOCK | PM_CFG_XRAM_READ_DISABLE); @@ -48,7 +49,7 @@ static void soc_die_lockdown_cfg(void) void soc_lockdown_config(int chipset_lockdown) { /* PMC lock down configuration */ - pmc_lockdown_cfg(chipset_lockdown); - /* SOC Die lock down configuration */ + pmc_lockdown_config(chipset_lockdown); + /* SOC/PCH die lock down configuration */ soc_die_lockdown_cfg(); } diff --git a/src/soc/intel/common/feature/pmutil/Kconfig b/src/soc/intel/common/feature/pmutil/Kconfig new file mode 100644 index 00000000000..e0934a5e4e6 --- /dev/null +++ b/src/soc/intel/common/feature/pmutil/Kconfig @@ -0,0 +1,10 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_PMUTIL + bool + help + Select this if the platform supports common PMC utility driver + for modern Intel platforms that share consistent PM register + layouts. This consolidates power management utility functions + including SMI/TCO/GPE status handling, PMC MMIO access, RTC + failure detection, sleep state management, and GPE configuration. diff --git a/src/soc/intel/common/feature/pmutil/Makefile.mk b/src/soc/intel/common/feature/pmutil/Makefile.mk new file mode 100644 index 00000000000..3bda095d2a5 --- /dev/null +++ b/src/soc/intel/common/feature/pmutil/Makefile.mk @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +all-$(CONFIG_SOC_INTEL_COMMON_FEATURE_PMUTIL) += pmutil.c +smm-$(CONFIG_SOC_INTEL_COMMON_FEATURE_PMUTIL) += pmutil.c diff --git a/src/soc/intel/pantherlake/pmutil.c b/src/soc/intel/common/feature/pmutil/pmutil.c similarity index 95% rename from src/soc/intel/pantherlake/pmutil.c rename to src/soc/intel/common/feature/pmutil/pmutil.c index 7ce1dacfa31..5d7db19f746 100644 --- a/src/soc/intel/pantherlake/pmutil.c +++ b/src/soc/intel/common/feature/pmutil/pmutil.c @@ -1,8 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Helper functions for dealing with power management registers - * and the differences between PCH variants. + * Common helper functions for dealing with power management registers + * for modern Intel platforms. + * + * This driver consolidates PM utility functions that were duplicated + * across multiple Intel SoC platforms. */ #define __SIMPLE_DEVICE__ @@ -18,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -145,7 +147,7 @@ uint32_t *soc_pmc_etr_addr(void) return (uint32_t *)(soc_read_pmc_base() + ETR); } -static void pmc_gpe0_different_values(const struct soc_intel_pantherlake_config *config) +static void pmc_gpe0_different_values(const config_t *config) { bool all_zero = (config->pmc_gpe0_dw0 == 0) && (config->pmc_gpe0_dw1 == 0) && @@ -161,7 +163,7 @@ static void pmc_gpe0_different_values(const struct soc_intel_pantherlake_config void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2) { - DEVTREE_CONST struct soc_intel_pantherlake_config *config; + DEVTREE_CONST config_t *config; config = config_of_soc(); if (config == NULL) { diff --git a/src/soc/intel/common/feature/smihandler/Kconfig b/src/soc/intel/common/feature/smihandler/Kconfig new file mode 100644 index 00000000000..a927e1828ea --- /dev/null +++ b/src/soc/intel/common/feature/smihandler/Kconfig @@ -0,0 +1,9 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_SMIHANDLER + bool + help + Select this if the platform supports common PCH client SMI handler + implementation. This consolidates SMI handler code for PCH client + platforms including PMC bus master control and standard SMI handler + mappings. The platform must define SOC_PMC_DEV in soc/pci_devs.h. diff --git a/src/soc/intel/common/feature/smihandler/Makefile.mk b/src/soc/intel/common/feature/smihandler/Makefile.mk new file mode 100644 index 00000000000..cda860ed0b9 --- /dev/null +++ b/src/soc/intel/common/feature/smihandler/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +smm-$(CONFIG_SOC_INTEL_COMMON_FEATURE_SMIHANDLER) += smihandler.c diff --git a/src/soc/intel/meteorlake/smihandler.c b/src/soc/intel/common/feature/smihandler/smihandler.c similarity index 94% rename from src/soc/intel/meteorlake/smihandler.c rename to src/soc/intel/common/feature/smihandler/smihandler.c index 6a21f0a757c..35726049d03 100644 --- a/src/soc/intel/meteorlake/smihandler.c +++ b/src/soc/intel/common/feature/smihandler/smihandler.c @@ -2,14 +2,13 @@ #include #include -#include #include #include int smihandler_soc_disable_busmaster(pci_devfn_t dev) { /* Skip disabling PMC bus master to keep IO decode enabled */ - if (dev == PCI_DEV_PMC) + if (dev == SOC_PMC_DEV) return 0; return 1; } diff --git a/src/soc/intel/common/feature/soundwire/Kconfig b/src/soc/intel/common/feature/soundwire/Kconfig new file mode 100644 index 00000000000..c53b0e39b80 --- /dev/null +++ b/src/soc/intel/common/feature/soundwire/Kconfig @@ -0,0 +1,24 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_SOUNDWIRE + bool + help + Intel Processor Common SoundWire support. This provides a common + implementation of soc_fill_soundwire_controller() for platforms + that use the same SoundWire link configuration. The platform must + define SOC_SOUNDWIRE_ACPI_ADDRESS and SOC_SOUNDWIRE_MASTER_COUNT + in their Kconfig. + +config SOC_SOUNDWIRE_ACPI_ADDRESS + hex + default 0x40000000 + depends on SOC_INTEL_COMMON_FEATURE_SOUNDWIRE + help + ACPI address for the SoundWire controller. + +config SOC_SOUNDWIRE_MASTER_COUNT + int + default 4 + depends on SOC_INTEL_COMMON_FEATURE_SOUNDWIRE + help + Number of SoundWire master interfaces supported by the platform. diff --git a/src/soc/intel/common/feature/soundwire/Makefile.mk b/src/soc/intel/common/feature/soundwire/Makefile.mk new file mode 100644 index 00000000000..a668fdbaa9f --- /dev/null +++ b/src/soc/intel/common/feature/soundwire/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-$(CONFIG_SOC_INTEL_COMMON_FEATURE_SOUNDWIRE) += soundwire.c diff --git a/src/soc/intel/meteorlake/soundwire.c b/src/soc/intel/common/feature/soundwire/soundwire.c similarity index 94% rename from src/soc/intel/meteorlake/soundwire.c rename to src/soc/intel/common/feature/soundwire/soundwire.c index c3ff05d2e37..d9528df1a79 100644 --- a/src/soc/intel/meteorlake/soundwire.c +++ b/src/soc/intel/common/feature/soundwire/soundwire.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include @@ -35,9 +34,9 @@ static const struct soundwire_link link_xtal_24 = { }; static struct intel_soundwire_controller intel_controller = { - .acpi_address = 0x40000000, + .acpi_address = CONFIG_SOC_SOUNDWIRE_ACPI_ADDRESS, .sdw = { - .master_list_count = 4 + .master_list_count = CONFIG_SOC_SOUNDWIRE_MASTER_COUNT } }; diff --git a/src/soc/intel/common/feature/spi/Kconfig b/src/soc/intel/common/feature/spi/Kconfig new file mode 100644 index 00000000000..4f09abbd033 --- /dev/null +++ b/src/soc/intel/common/feature/spi/Kconfig @@ -0,0 +1,36 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + bool + default n + depends on SOC_INTEL_COMMON_BLOCK_SPI + help + Use common SPI device function to bus mapping. SoCs must define + CONFIG_SOC_INTEL_SPI_DEV_MAX and SOC_GSPI_DEVFN(n) macro in + soc/pci_devs.h. + +config SOC_INTEL_SPI_DEV_MAX + int + default 0 + depends on SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + help + Number of SPI controllers available on the platform. This is used + for SPI device function to bus number mapping. Platforms should + override this with the actual count of SPI controllers. + +config SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF + bool + default n + depends on SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + help + SoC provides soc_get_spi_psf_destination_id() via common driver. + Platforms must define CONFIG_SOC_INTEL_SPI_PSF_DESTINATION_ID. + +config SOC_INTEL_SPI_PSF_DESTINATION_ID + hex + default 0x0 + depends on SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF + help + PSF destination ID for SPI controller. This value is platform-specific + and is used for PSF programming. Platforms should override this with + the correct value from their hardware specification. diff --git a/src/soc/intel/common/feature/spi/Makefile.mk b/src/soc/intel/common/feature/spi/Makefile.mk new file mode 100644 index 00000000000..798c7ec12e4 --- /dev/null +++ b/src/soc/intel/common/feature/spi/Makefile.mk @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +all-$(CONFIG_SOC_INTEL_COMMON_FEATURE_SPI_DEVFN) += spi_devfn.c +smm-$(CONFIG_SOC_INTEL_COMMON_FEATURE_SPI_DEVFN) += spi_devfn.c diff --git a/src/soc/intel/common/feature/spi/spi_devfn.c b/src/soc/intel/common/feature/spi/spi_devfn.c new file mode 100644 index 00000000000..eb39c5dfcae --- /dev/null +++ b/src/soc/intel/common/feature/spi/spi_devfn.c @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include + +/* + * Ensure the platform defines SOC_GSPI_DEVFN(n) macro to map GSPI bus numbers + * to their PCI device/function values. The macro should be defined in the + * platform's soc/pci_devs.h header. + */ + +_Static_assert(CONFIG_SOC_INTEL_SPI_DEV_MAX <= 5, + "CONFIG_SOC_INTEL_SPI_DEV_MAX greater than 5 is not supported."); + +int spi_soc_devfn_to_bus(unsigned int devfn) +{ + switch (devfn) { +#if CONFIG_SOC_INTEL_SPI_DEV_MAX > 0 + case SOC_GSPI_DEVFN(0): + return 1; +#endif +#if CONFIG_SOC_INTEL_SPI_DEV_MAX > 1 + case SOC_GSPI_DEVFN(1): + return 2; +#endif +#if CONFIG_SOC_INTEL_SPI_DEV_MAX > 2 + case SOC_GSPI_DEVFN(2): + return 3; +#endif +#if CONFIG_SOC_INTEL_SPI_DEV_MAX > 3 + case SOC_GSPI_DEVFN(3): + return 4; +#endif +#if CONFIG_SOC_INTEL_SPI_DEV_MAX > 4 + case SOC_GSPI_DEVFN(4): + return 5; +#endif + } + return -1; +} + +#if CONFIG(SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF) +uint32_t soc_get_spi_psf_destination_id(void) +{ + return CONFIG_SOC_INTEL_SPI_PSF_DESTINATION_ID; +} +#endif diff --git a/src/soc/intel/common/feature/uart/Kconfig b/src/soc/intel/common/feature/uart/Kconfig new file mode 100644 index 00000000000..73429af3350 --- /dev/null +++ b/src/soc/intel/common/feature/uart/Kconfig @@ -0,0 +1,9 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config SOC_INTEL_COMMON_FEATURE_UART_DEVICES + bool + help + Include common UART device list support. This option eliminates + per-platform duplication of uart.c files by providing a common + implementation. Platforms must define PCI_UART_DEVFN* macro in + their soc/pci_devs.h header. diff --git a/src/soc/intel/common/feature/uart/Makefile.mk b/src/soc/intel/common/feature/uart/Makefile.mk new file mode 100644 index 00000000000..dfc36965bae --- /dev/null +++ b/src/soc/intel/common/feature/uart/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only +all-$(CONFIG_SOC_INTEL_COMMON_FEATURE_UART_DEVICES) += uart_devices.c +smm-$(CONFIG_SOC_INTEL_COMMON_FEATURE_UART_DEVICES) += uart_devices.c diff --git a/src/soc/intel/meteorlake/uart.c b/src/soc/intel/common/feature/uart/uart_devices.c similarity index 100% rename from src/soc/intel/meteorlake/uart.c rename to src/soc/intel/common/feature/uart/uart_devices.c diff --git a/src/soc/intel/common/pch/lockdown/lockdown.c b/src/soc/intel/common/pch/lockdown/lockdown.c index eec3beb01b4..ff7ca959fc8 100644 --- a/src/soc/intel/common/pch/lockdown/lockdown.c +++ b/src/soc/intel/common/pch/lockdown/lockdown.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include @@ -81,7 +83,7 @@ static void fast_spi_lockdown_cfg(int chipset_lockdown) fast_spi_set_bios_interface_lock_down(); /* Only allow writes in SMM */ - if (CONFIG(BOOTMEDIA_SMM_BWP)) { + if (enable_smm_bios_protection()) { fast_spi_set_eiss(); fast_spi_enable_wp(); } @@ -102,7 +104,7 @@ static void lpc_lockdown_config(int chipset_lockdown) lpc_set_bios_interface_lock_down(); /* Only allow writes in SMM */ - if (CONFIG(BOOTMEDIA_SMM_BWP)) { + if (enable_smm_bios_protection()) { lpc_set_eiss(); lpc_enable_wp(); } diff --git a/src/soc/intel/common/reset.c b/src/soc/intel/common/reset.c index 307be5769af..14a32c16977 100644 --- a/src/soc/intel/common/reset.c +++ b/src/soc/intel/common/reset.c @@ -1,10 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include -#include -#include #include #include @@ -26,10 +25,7 @@ void do_board_reset(void) void do_low_battery_poweroff(void) { - if (CONFIG(PLATFORM_HAS_LOW_BATTERY_INDICATOR)) { - elog_add_event_byte(ELOG_TYPE_LOW_BATTERY_INDICATOR, ELOG_FW_ISSUE_SHUTDOWN); - delay(CONFIG_PLATFORM_LOW_BATTERY_SHUTDOWN_DELAY_SEC); - } + platform_handle_emergency_low_battery(); poweroff(); halt(); diff --git a/src/soc/intel/elkhartlake/Kconfig b/src/soc/intel/elkhartlake/Kconfig index 6fb4f52d613..a3abfe650d5 100644 --- a/src/soc/intel/elkhartlake/Kconfig +++ b/src/soc/intel/elkhartlake/Kconfig @@ -55,6 +55,12 @@ config SOC_INTEL_ELKHARTLAKE select SOC_INTEL_COMMON_BLOCK_SCS select SOC_INTEL_COMMON_BLOCK_SMM select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_RESET diff --git a/src/soc/intel/elkhartlake/Makefile.mk b/src/soc/intel/elkhartlake/Makefile.mk index b5f5f2ad743..5fc53367230 100644 --- a/src/soc/intel/elkhartlake/Makefile.mk +++ b/src/soc/intel/elkhartlake/Makefile.mk @@ -6,29 +6,22 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += gspi.c -all-y += i2c.c all-y += pmutil.c all-y += spi.c -all-y += uart.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c bootblock-y += bootblock/report_platform.c -bootblock-y += espi.c bootblock-y += gpio.c bootblock-y += p2sb.c -romstage-y += espi.c romstage-y += gpio.c romstage-y += meminit.c romstage-y += pcie_rp.c -romstage-y += reset.c ramstage-y += acpi.c ramstage-y += chip.c ramstage-y += cpu.c -ramstage-y += espi.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += gpio.c @@ -36,7 +29,6 @@ ramstage-y += lockdown.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c -ramstage-y += reset.c ramstage-y += systemagent.c ramstage-y += sd.c ramstage-$(CONFIG_EHL_TSN_DRIVER) += tsn_gbe.c @@ -45,7 +37,6 @@ smm-y += gpio.c smm-y += p2sb.c smm-y += pmutil.c smm-y += smihandler.c -smm-y += uart.c verstage-y += gpio.c diff --git a/src/soc/intel/elkhartlake/chip.h b/src/soc/intel/elkhartlake/chip.h index d4bb04ff75e..e7593f8d146 100644 --- a/src/soc/intel/elkhartlake/chip.h +++ b/src/soc/intel/elkhartlake/chip.h @@ -238,6 +238,9 @@ struct soc_intel_elkhartlake_config { /* PCIe RP L1 substate */ enum L1_substates_control PcieRpL1Substates[CONFIG_MAX_ROOT_PORTS]; + /* PCIe ModPhy related */ + struct pcie_modphy_config pcie_mp_cfg[CONFIG_MAX_ROOT_PORTS]; + /* PCIe root port maximum payload size, default is set to 128 bytes. */ enum { RpMaxPayload_128, diff --git a/src/soc/intel/elkhartlake/espi.c b/src/soc/intel/elkhartlake/espi.c deleted file mode 100644 index de2a84f8f03..00000000000 --- a/src/soc/intel/elkhartlake/espi.c +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]) -{ - const config_t *config = config_of_soc(); - - gen_io_dec[0] = config->gen1_dec; - gen_io_dec[1] = config->gen2_dec; - gen_io_dec[2] = config->gen3_dec; - gen_io_dec[3] = config->gen4_dec; -} - -#if ENV_RAMSTAGE -void lpc_soc_init(struct device *dev) -{ - /* Legacy initialization */ - isa_dma_init(); - pch_misc_init(); - - /* Enable CLKRUN_EN for power gating ESPI */ - lpc_enable_pci_clk_cntl(); - - /* Set ESPI Serial IRQ mode */ - if (CONFIG(SERIRQ_CONTINUOUS_MODE)) - lpc_set_serirq_mode(SERIRQ_CONTINUOUS); - else - lpc_set_serirq_mode(SERIRQ_QUIET); - - /* Interrupt configuration */ - pch_enable_ioapic(); - pch_pirq_init(); - setup_i8259(); - i8259_configure_irq_trigger(9, 1); -} - -#endif diff --git a/src/soc/intel/elkhartlake/gspi.c b/src/soc/intel/elkhartlake/gspi.c deleted file mode 100644 index 61ad2608db2..00000000000 --- a/src/soc/intel/elkhartlake/gspi.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCH_DEVFN_GSPI0; - case 1: - return PCH_DEVFN_GSPI1; - case 2: - return PCH_DEVFN_GSPI2; - } - return -1; -} diff --git a/src/soc/intel/elkhartlake/i2c.c b/src/soc/intel/elkhartlake/i2c.c deleted file mode 100644 index 78ee37b72dd..00000000000 --- a/src/soc/intel/elkhartlake/i2c.c +++ /dev/null @@ -1,51 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_I2C0: - return 0; - case PCH_DEVFN_I2C1: - return 1; - case PCH_DEVFN_I2C2: - return 2; - case PCH_DEVFN_I2C3: - return 3; - case PCH_DEVFN_I2C4: - return 4; - case PCH_DEVFN_I2C5: - return 5; - case PCH_DEVFN_I2C6: - return 6; - case PCH_DEVFN_I2C7: - return 7; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCH_DEVFN_I2C0; - case 1: - return PCH_DEVFN_I2C1; - case 2: - return PCH_DEVFN_I2C2; - case 3: - return PCH_DEVFN_I2C3; - case 4: - return PCH_DEVFN_I2C4; - case 5: - return PCH_DEVFN_I2C5; - case 6: - return PCH_DEVFN_I2C6; - case 7: - return PCH_DEVFN_I2C7; - } - return -1; -} diff --git a/src/soc/intel/elkhartlake/include/soc/pci_devs.h b/src/soc/intel/elkhartlake/include/soc/pci_devs.h index 8cf193829cd..1dd6d6c6783 100644 --- a/src/soc/intel/elkhartlake/include/soc/pci_devs.h +++ b/src/soc/intel/elkhartlake/include/soc/pci_devs.h @@ -247,4 +247,11 @@ #define PCH_DEV_SPI _PCH_DEV(ESPI, 5) #define PCH_DEV_TRACEHUB _PCH_DEV(ESPI, 7) +/* for common code */ +#define PCI_DEVFN_UART0 PCH_DEVFN_UART0 +#define PCI_DEVFN_UART1 PCH_DEVFN_UART1 +#define PCI_DEVFN_UART2 PCH_DEVFN_UART2 +#define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n + #endif diff --git a/src/soc/intel/elkhartlake/reset.c b/src/soc/intel/elkhartlake/reset.c deleted file mode 100644 index 3c13f6dfe56..00000000000 --- a/src/soc/intel/elkhartlake/reset.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -void do_global_reset(void) -{ - /* Ask CSE to do the global reset */ - if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) - return; - - /* global reset if CSE fail to reset */ - pmc_global_reset_enable(1); - do_full_reset(); -} diff --git a/src/soc/intel/elkhartlake/romstage/fsp_params.c b/src/soc/intel/elkhartlake/romstage/fsp_params.c index d05a94d2aad..71bd473ca87 100644 --- a/src/soc/intel/elkhartlake/romstage/fsp_params.c +++ b/src/soc/intel/elkhartlake/romstage/fsp_params.c @@ -22,6 +22,8 @@ enum { static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, const struct soc_intel_elkhartlake_config *config) { + size_t i; + /* * If IGD is enabled, set IGD stolen size to 60MB. * Otherwise, skip IGD init in FSP. @@ -33,6 +35,40 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, m_cfg->SaGv = config->SaGv; m_cfg->RMT = config->RMT; + /* PCIe ModPhy configuration */ + for (i = 0; i < CONFIG_MAX_ROOT_PORTS; i++) { + if (config->pcie_mp_cfg[i].tx_gen1_downscale_amp_override) { + m_cfg->PchPcieHsioTxGen1DownscaleAmpEnable[i] = 1; + m_cfg->PchPcieHsioTxGen1DownscaleAmp[i] = + config->pcie_mp_cfg[i].tx_gen1_downscale_amp; + } + if (config->pcie_mp_cfg[i].tx_gen2_downscale_amp_override) { + m_cfg->PchPcieHsioTxGen2DownscaleAmpEnable[i] = 1; + m_cfg->PchPcieHsioTxGen2DownscaleAmp[i] = + config->pcie_mp_cfg[i].tx_gen2_downscale_amp; + } + if (config->pcie_mp_cfg[i].tx_gen3_downscale_amp_override) { + m_cfg->PchPcieHsioTxGen3DownscaleAmpEnable[i] = 1; + m_cfg->PchPcieHsioTxGen3DownscaleAmp[i] = + config->pcie_mp_cfg[i].tx_gen3_downscale_amp; + } + if (config->pcie_mp_cfg[i].tx_gen1_de_emph) { + m_cfg->PchPcieHsioTxGen1DeEmphEnable[i] = 1; + m_cfg->PchPcieHsioTxGen1DeEmph[i] = + config->pcie_mp_cfg[i].tx_gen1_de_emph; + } + if (config->pcie_mp_cfg[i].tx_gen2_de_emph_3p5) { + m_cfg->PchPcieHsioTxGen2DeEmph3p5Enable[i] = 1; + m_cfg->PchPcieHsioTxGen2DeEmph3p5[i] = + config->pcie_mp_cfg[i].tx_gen2_de_emph_3p5; + } + if (config->pcie_mp_cfg[i].tx_gen2_de_emph_6p0) { + m_cfg->PchPcieHsioTxGen2DeEmph6p0Enable[i] = 1; + m_cfg->PchPcieHsioTxGen2DeEmph6p0[i] = + config->pcie_mp_cfg[i].tx_gen2_de_emph_6p0; + } + } + m_cfg->PcieRpEnableMask = pcie_rp_enable_mask(pch_rp_groups); FSP_ARRAY_LOAD(m_cfg->PcieClkSrcUsage, config->PcieClkSrcUsage); diff --git a/src/soc/intel/elkhartlake/uart.c b/src/soc/intel/elkhartlake/uart.c deleted file mode 100644 index 99468802634..00000000000 --- a/src/soc/intel/elkhartlake/uart.c +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -const unsigned int uart_devices[] = { - PCH_DEVFN_UART0, - PCH_DEVFN_UART1, - PCH_DEVFN_UART2, -}; - -const int uart_devices_size = ARRAY_SIZE(uart_devices); diff --git a/src/soc/intel/jasperlake/Kconfig b/src/soc/intel/jasperlake/Kconfig index 727e9609cea..a9b19b9a12a 100644 --- a/src/soc/intel/jasperlake/Kconfig +++ b/src/soc/intel/jasperlake/Kconfig @@ -55,6 +55,13 @@ config SOC_INTEL_JASPERLAKE select SOC_INTEL_COMMON_BLOCK_POWER_LIMIT select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_RESET @@ -105,6 +112,10 @@ config IFD_CHIPSET string default "jsl" +config CHIPSET_DEVICETREE + string + default "soc/intel/jasperlake/chipset.cb" + config IED_REGION_SIZE hex default 0x400000 @@ -207,4 +218,8 @@ config INTEL_GMA_BCLM_OFFSET config INTEL_GMA_BCLM_WIDTH default 32 + +config SOC_INTEL_SPI_DEV_MAX + int + default 3 endif diff --git a/src/soc/intel/jasperlake/Makefile.mk b/src/soc/intel/jasperlake/Makefile.mk index 1377fff9e07..bff546748e1 100644 --- a/src/soc/intel/jasperlake/Makefile.mk +++ b/src/soc/intel/jasperlake/Makefile.mk @@ -6,30 +6,22 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += gspi.c -all-y += i2c.c all-y += pmutil.c -all-y += spi.c -all-y += uart.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c bootblock-y += bootblock/report_platform.c -bootblock-y += espi.c bootblock-y += gpio.c bootblock-y += p2sb.c -romstage-y += espi.c romstage-y += gpio.c romstage-y += meminit.c romstage-y += pcie_rp.c -romstage-y += reset.c ramstage-y += acpi.c ramstage-y += chip.c ramstage-y += cpu.c ramstage-y += elog.c -ramstage-y += espi.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += gpio.c @@ -38,7 +30,6 @@ ramstage-y += lockdown.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c -ramstage-y += reset.c ramstage-y += systemagent.c ramstage-y += sd.c ramstage-y += xhci.c @@ -47,7 +38,6 @@ smm-y += gpio.c smm-y += p2sb.c smm-y += pmutil.c smm-y += smihandler.c -smm-y += uart.c smm-y += elog.c smm-y += xhci.c diff --git a/src/soc/intel/jasperlake/chip.c b/src/soc/intel/jasperlake/chip.c index e1f60991277..5b4a8232d45 100644 --- a/src/soc/intel/jasperlake/chip.c +++ b/src/soc/intel/jasperlake/chip.c @@ -63,6 +63,7 @@ const char *soc_acpi_name(const struct device *dev) switch (dev->path.pci.devfn) { case SA_DEVFN_ROOT: return "MCHC"; + case SA_DEVFN_IGD: return "GFX0"; case SA_DEVFN_IPU: return "IPU0"; case PCH_DEVFN_ISH: return "ISHB"; case SA_DEVFN_GNA: return "GNA"; diff --git a/src/soc/intel/jasperlake/chip.h b/src/soc/intel/jasperlake/chip.h index 380549451e3..3fdf82db975 100644 --- a/src/soc/intel/jasperlake/chip.h +++ b/src/soc/intel/jasperlake/chip.h @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/src/soc/intel/jasperlake/chipset.cb b/src/soc/intel/jasperlake/chipset.cb new file mode 100644 index 00000000000..cbd5d2efc9f --- /dev/null +++ b/src/soc/intel/jasperlake/chipset.cb @@ -0,0 +1,100 @@ +chip soc/intel/jasperlake + + device cpu_cluster 0 on end + + device domain 0 on + device pci 00.0 alias system_agent on end + device pci 02.0 alias igpu off end + device pci 04.0 alias dptf off end + device pci 05.0 alias ipu off end + device pci 08.0 alias gna off end + device pci 09.0 alias north_tracehub off end + device pci 12.0 alias ish off end + device pci 12.5 alias ufs_scs off end + device pci 12.6 alias gspi2 off ops spi_dev_ops end + device pci 14.0 alias south_xhci off ops usb_xhci_ops + chip drivers/usb/acpi + register "type" = "UPC_TYPE_HUB" + device usb 0.0 alias xhci_root_hub off + chip drivers/usb/acpi + device usb 2.0 alias usb2_port1 off end + end + chip drivers/usb/acpi + device usb 2.1 alias usb2_port2 off end + end + chip drivers/usb/acpi + device usb 2.2 alias usb2_port3 off end + end + chip drivers/usb/acpi + device usb 2.3 alias usb2_port4 off end + end + chip drivers/usb/acpi + device usb 2.4 alias usb2_port5 off end + end + chip drivers/usb/acpi + device usb 2.5 alias usb2_port6 off end + end + chip drivers/usb/acpi + device usb 2.6 alias usb2_port7 off end + end + chip drivers/usb/acpi + device usb 2.7 alias usb2_port8 off end + end + chip drivers/usb/acpi + device usb 3.0 alias usb3_port1 off end + end + chip drivers/usb/acpi + device usb 3.1 alias usb3_port2 off end + end + chip drivers/usb/acpi + device usb 3.2 alias usb3_port3 off end + end + chip drivers/usb/acpi + device usb 3.3 alias usb3_port4 off end + end + chip drivers/usb/acpi + device usb 3.4 alias usb3_port5 off end + end + chip drivers/usb/acpi + device usb 3.5 alias usb3_port6 off end + end + end + end + end + device pci 14.1 alias south_xdci off ops usb_xdci_ops end + device pci 14.2 alias shared_ram off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end + device pci 14.5 alias sdxc off ops sd_ops end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end + device pci 16.0 alias heci1 off end + device pci 16.1 alias heci2 off end + device pci 16.4 alias heci3 off end + device pci 17.0 alias sata off ops sata_ops end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end + device pci 19.2 alias uart2 off ops uart_ops end + device pci 1a.0 alias emmc off end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end + device pci 1f.0 alias pch_espi on end + device pci 1f.1 alias p2sb hidden end + device pci 1f.2 alias pmc hidden end + device pci 1f.3 alias hda off ops hda_ops end + device pci 1f.4 alias smbus off ops smbus_ops end + device pci 1f.5 alias fast_spi on end + device pci 1f.7 alias south_tracehub off end + end +end diff --git a/src/soc/intel/jasperlake/espi.c b/src/soc/intel/jasperlake/espi.c deleted file mode 100644 index dfa3b19f9aa..00000000000 --- a/src/soc/intel/jasperlake/espi.c +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]) -{ - const config_t *config = config_of_soc(); - - gen_io_dec[0] = config->gen1_dec; - gen_io_dec[1] = config->gen2_dec; - gen_io_dec[2] = config->gen3_dec; - gen_io_dec[3] = config->gen4_dec; -} - -#if ENV_RAMSTAGE -void lpc_soc_init(struct device *dev) -{ - /* Legacy initialization */ - isa_dma_init(); - pch_misc_init(); - - /* Enable CLKRUN_EN for power gating ESPI */ - lpc_enable_pci_clk_cntl(); - - /* Set ESPI Serial IRQ mode */ - if (CONFIG(SERIRQ_CONTINUOUS_MODE)) - lpc_set_serirq_mode(SERIRQ_CONTINUOUS); - else - lpc_set_serirq_mode(SERIRQ_QUIET); - - /* Interrupt configuration */ - pch_enable_ioapic(); - pch_pirq_init(); - setup_i8259(); - i8259_configure_irq_trigger(9, 1); -} - -#endif diff --git a/src/soc/intel/jasperlake/gspi.c b/src/soc/intel/jasperlake/gspi.c deleted file mode 100644 index 61ad2608db2..00000000000 --- a/src/soc/intel/jasperlake/gspi.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCH_DEVFN_GSPI0; - case 1: - return PCH_DEVFN_GSPI1; - case 2: - return PCH_DEVFN_GSPI2; - } - return -1; -} diff --git a/src/soc/intel/jasperlake/i2c.c b/src/soc/intel/jasperlake/i2c.c deleted file mode 100644 index c13a1a60995..00000000000 --- a/src/soc/intel/jasperlake/i2c.c +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_I2C0: - return 0; - case PCH_DEVFN_I2C1: - return 1; - case PCH_DEVFN_I2C2: - return 2; - case PCH_DEVFN_I2C3: - return 3; - case PCH_DEVFN_I2C4: - return 4; - case PCH_DEVFN_I2C5: - return 5; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCH_DEVFN_I2C0; - case 1: - return PCH_DEVFN_I2C1; - case 2: - return PCH_DEVFN_I2C2; - case 3: - return PCH_DEVFN_I2C3; - case 4: - return PCH_DEVFN_I2C4; - case 5: - return PCH_DEVFN_I2C5; - } - return -1; -} diff --git a/src/soc/intel/jasperlake/include/soc/cfr.h b/src/soc/intel/jasperlake/include/soc/cfr.h index c275324d656..e3ff9f87ef0 100644 --- a/src/soc/intel/jasperlake/include/soc/cfr.h +++ b/src/soc/intel/jasperlake/include/soc/cfr.h @@ -11,15 +11,11 @@ #include /* IGD Enabled */ -static const struct sm_object igd_enabled = SM_DECLARE_ENUM({ +static const struct sm_object igd_enabled = SM_DECLARE_BOOL({ .opt_name = "igd_enabled", .ui_name = "Enable the Intel iGPU", .ui_helptext = "Enable or disable the Intel iGPU", .default_value = !CONFIG(SOC_INTEL_DISABLE_IGD), - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, }); /* IGD Aperture Size */ @@ -33,7 +29,7 @@ static const struct sm_object igd_aperture = SM_DECLARE_ENUM({ { " 256 MB", IGD_AP_SZ_256MB }, { " 512 MB", IGD_AP_SZ_512MB }, SM_ENUM_VALUE_END }, -}, WITH_DEP_VALUES(&igd_enabled, 1)); +}, WITH_DEP_VALUES(&igd_enabled, true)); /* IGD DVMT pre-allocated memory */ static const struct sm_object igd_dvmt = SM_DECLARE_ENUM({ @@ -49,42 +45,30 @@ static const struct sm_object igd_dvmt = SM_DECLARE_ENUM({ { "128 MB", IGD_SM_128MB }, { "160 MB", IGD_SM_160MB }, SM_ENUM_VALUE_END }, -}, WITH_DEP_VALUES(&igd_enabled, 1)); +}, WITH_DEP_VALUES(&igd_enabled, true)); /* Legacy 8254 Timer */ -static const struct sm_object legacy_8254_timer = SM_DECLARE_ENUM({ +static const struct sm_object legacy_8254_timer = SM_DECLARE_BOOL({ .opt_name = "legacy_8254_timer", .ui_name = "Legacy 8254 Timer", .ui_helptext = "Enable the legacy 8254 timer by disabling clock gating.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = false, }); /* S0ix Enable */ -static const struct sm_object s0ix_enable = SM_DECLARE_ENUM({ +static const struct sm_object s0ix_enable = SM_DECLARE_BOOL({ .opt_name = "s0ix_enable", .ui_name = "Modern Standby (S0ix)", .ui_helptext = "Enabled: use Modern Standby / S0ix. Disabled: use ACPI S3 sleep", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* VT-d */ -static const struct sm_object vtd = SM_DECLARE_ENUM({ +static const struct sm_object vtd = SM_DECLARE_BOOL({ .opt_name = "vtd", .ui_name = "VT-d", .ui_helptext = "Enable or disable Intel VT-d (virtualization)", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); #endif /* _JASPERLAKE_CFR_H_ */ diff --git a/src/soc/intel/jasperlake/include/soc/pci_devs.h b/src/soc/intel/jasperlake/include/soc/pci_devs.h index e3276458bf3..4267d9bfdf0 100644 --- a/src/soc/intel/jasperlake/include/soc/pci_devs.h +++ b/src/soc/intel/jasperlake/include/soc/pci_devs.h @@ -193,4 +193,11 @@ #define PCH_DEV_GBE _PCH_DEV(ESPI, 6) #define PCH_DEV_TRACEHUB _PCH_DEV(ESPI, 7) +/* for common code */ +#define PCI_DEVFN_UART0 PCH_DEVFN_UART0 +#define PCI_DEVFN_UART1 PCH_DEVFN_UART1 +#define PCI_DEVFN_UART2 PCH_DEVFN_UART2 +#define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n + #endif diff --git a/src/soc/intel/jasperlake/include/soc/pcie_modphy.h b/src/soc/intel/jasperlake/include/soc/pcie_modphy.h deleted file mode 100644 index 60f145195fb..00000000000 --- a/src/soc/intel/jasperlake/include/soc/pcie_modphy.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef _SOC_JASPERLAKE_PCIE_MODPHY_H_ -#define _SOC_JASPERLAKE_PCIE_MODPHY_H_ - -struct pcie_modphy_config { - /* TX Output Downscale Amplitude Adjustment */ - bool tx_gen1_downscale_amp_override; - uint8_t tx_gen1_downscale_amp; - /* TX Output Downscale Amplitude Adjustment */ - bool tx_gen2_downscale_amp_override; - uint8_t tx_gen2_downscale_amp; - /* TX Output Downscale Amplitude Adjustment */ - bool tx_gen3_downscale_amp_override; - uint8_t tx_gen3_downscale_amp; - /* TX Output -3.5dB Mode De-Emphasis Adjustment Setting */ - uint8_t tx_gen1_de_emph; - /* TX Output -3.5dB Mode De-Emphasis Adjustment Setting */ - uint8_t tx_gen2_de_emph_3p5; - /* TX Output -6.0dB Mode De-Emphasis Adjustment Setting */ - uint8_t tx_gen2_de_emph_6p0; -}; - -#endif diff --git a/src/soc/intel/jasperlake/reset.c b/src/soc/intel/jasperlake/reset.c deleted file mode 100644 index 3c13f6dfe56..00000000000 --- a/src/soc/intel/jasperlake/reset.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -void do_global_reset(void) -{ - /* Ask CSE to do the global reset */ - if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) - return; - - /* global reset if CSE fail to reset */ - pmc_global_reset_enable(1); - do_full_reset(); -} diff --git a/src/soc/intel/jasperlake/spi.c b/src/soc/intel/jasperlake/spi.c deleted file mode 100644 index 8a7ed73b477..00000000000 --- a/src/soc/intel/jasperlake/spi.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include - -int spi_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_GSPI0: - return 1; - case PCH_DEVFN_GSPI1: - return 2; - case PCH_DEVFN_GSPI2: - return 3; - } - return -1; -} diff --git a/src/soc/intel/jasperlake/uart.c b/src/soc/intel/jasperlake/uart.c deleted file mode 100644 index 99468802634..00000000000 --- a/src/soc/intel/jasperlake/uart.c +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -const unsigned int uart_devices[] = { - PCH_DEVFN_UART0, - PCH_DEVFN_UART1, - PCH_DEVFN_UART2, -}; - -const int uart_devices_size = ARRAY_SIZE(uart_devices); diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index a0e648a8569..aa8d5eeb60a 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -86,6 +86,19 @@ config SOC_INTEL_METEORLAKE select SOC_INTEL_COMMON_BLOCK_THERMAL_BEHIND_PMC select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_FINALIZE + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN + select SOC_INTEL_COMMON_FEATURE_LOCKDOWN + select SOC_INTEL_COMMON_FEATURE_PMUTIL + select SOC_INTEL_COMMON_FEATURE_SMIHANDLER + select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_BASECODE select SOC_INTEL_COMMON_BASECODE_RAMTOP select SOC_INTEL_COMMON_FSP_RESET @@ -335,11 +348,11 @@ config VBOOT_HASH_BLOCK_SIZE config CBFS_SIZE hex - default 0x200000 + default 0x400000 config PRERAM_CBMEM_CONSOLE_SIZE hex - default 0x2000 + default 0x4000 config CONSOLE_CBMEM_BUFFER_SIZE hex @@ -474,4 +487,12 @@ config SKIP_SEND_CONNECT_TOPOLOGY_CMD config TME_KEY_REGENERATION_ON_WARM_BOOT default y if INTEL_TME +config SOC_INTEL_SPI_DEV_MAX + int + default 3 + +config SOC_INTEL_SPI_PSF_DESTINATION_ID + hex + default 0x5140 + endif diff --git a/src/soc/intel/meteorlake/Makefile.mk b/src/soc/intel/meteorlake/Makefile.mk index ab4e8a7f562..9d6e8403694 100644 --- a/src/soc/intel/meteorlake/Makefile.mk +++ b/src/soc/intel/meteorlake/Makefile.mk @@ -6,25 +6,17 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += gspi.c -all-y += i2c.c -all-y += pmutil.c -all-y += spi.c -all-y += uart.c all-y += gpio.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/ioe_die.c bootblock-y += bootblock/report_platform.c bootblock-y += bootblock/soc_die.c -bootblock-y += espi.c bootblock-y += soc_info.c romstage-$(CONFIG_SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY) += cse_telemetry.c -romstage-y += espi.c romstage-y += meminit.c romstage-y += pcie_rp.c -romstage-y += reset.c romstage-y += soc_info.c ramstage-y += acpi.c @@ -33,17 +25,12 @@ ramstage-y += cpu.c ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog.c ramstage-y += ioe_pmc.c ramstage-y += elog.c -ramstage-y += espi.c -ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += graphics.c -ramstage-y += lockdown.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c -ramstage-y += reset.c ramstage-y += retimer.c -ramstage-y += soundwire.c ramstage-y += systemagent.c ramstage-y += tcss.c ramstage-y += xhci.c @@ -52,17 +39,17 @@ ramstage-y += soc_info.c smm-y += elog.c smm-y += gpio.c smm-y += p2sb.c -smm-y += pmutil.c -smm-y += smihandler.c smm-y += soc_info.c -smm-y += uart.c smm-y += xhci.c CPPFLAGS_common += -I$(src)/soc/intel/meteorlake CPPFLAGS_common += -I$(src)/soc/intel/meteorlake/include ifeq ($(CONFIG_SOC_INTEL_METEORLAKE_U_H),y) -cpu_microcode_bins += 3rdparty/intel-microcode/intel-ucode/06-aa-04 +cpu_microcode_bins += \ + 3rdparty/intel-microcode/intel-ucode/06-aa-04 \ + 3rdparty/intel-microcode/intel-ucode/06-b5-00 \ + 3rdparty/intel-microcode/intel-ucode/06-c6-02 endif endif diff --git a/src/soc/intel/meteorlake/chip.h b/src/soc/intel/meteorlake/chip.h index 7c4c954d268..c32bb74adeb 100644 --- a/src/soc/intel/meteorlake/chip.h +++ b/src/soc/intel/meteorlake/chip.h @@ -52,7 +52,8 @@ enum soc_intel_meteorlake_power_limits { /* TDP values for different SKUs */ enum soc_intel_meteorlake_cpu_tdps { TDP_15W = 15, - TDP_28W = 28 + TDP_28W = 28, + TDP_45W = 45, }; /* Mapping of different SKUs based on CPU ID and TDP values */ @@ -66,6 +67,7 @@ static const struct { { PCI_DID_INTEL_MTL_P_ID_3, MTL_P_682_482_CORE, TDP_28W }, { PCI_DID_INTEL_MTL_P_ID_1, MTL_P_682_482_CORE, TDP_28W }, { PCI_DID_INTEL_ARL_H_ID_1, MTL_P_682_482_CORE, TDP_28W }, + { PCI_DID_INTEL_ARL_H_ID_1, MTL_P_682_482_CORE, TDP_45W }, { PCI_DID_INTEL_ARL_H_ID_2, MTL_P_682_482_CORE, TDP_28W }, }; diff --git a/src/soc/intel/meteorlake/chipset.cb b/src/soc/intel/meteorlake/chipset.cb index 7b26670ff8e..3488a0f684a 100644 --- a/src/soc/intel/meteorlake/chipset.cb +++ b/src/soc/intel/meteorlake/chipset.cb @@ -31,13 +31,13 @@ chip soc/intel/meteorlake device domain 0 on device pci 00.0 alias system_agent on end - device pci 01.0 alias pcie_rp12 off end + device pci 01.0 alias pcie_rp12 off ops pcie_rp_ops end device pci 02.0 alias igpu off end device pci 04.0 alias dtt off end device pci 05.0 alias ipu off end - device pci 06.0 alias pcie_rp9 off end - device pci 06.1 alias pcie_rp10 off end - device pci 06.2 alias pcie_rp11 off end + device pci 06.0 alias pcie_rp9 off ops pcie_rp_ops end + device pci 06.1 alias pcie_rp10 off ops pcie_rp_ops end + device pci 06.2 alias pcie_rp11 off ops pcie_rp_ops end device pci 07.0 alias tbt_pcie_rp0 off chip soc/intel/common/block/usb4 use tcss_dma0 as usb4_port @@ -87,20 +87,20 @@ chip soc/intel/meteorlake end end end - device pci 0d.1 alias tcss_xdci off end + device pci 0d.1 alias tcss_xdci off ops usb_xdci_ops end device pci 0d.2 alias tcss_dma0 off end device pci 0d.3 alias tcss_dma1 off end device pci 0e.0 alias vmd off end device pci 10.0 alias thc0 off end device pci 10.1 alias thc1 off end device pci 12.0 alias ish off end - device pci 12.6 alias gspi2 off end + device pci 12.6 alias gspi2 off ops spi_dev_ops end device pci 12.7 alias ufs off end device pci 13.0 alias ioe_p2sb hidden end device pci 13.1 alias ieh2 off end device pci 13.2 alias pmc2 hidden end device pci 13.3 alias ioe_shared_sram off end - device pci 14.0 alias xhci off + device pci 14.0 alias xhci off ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off @@ -151,43 +151,43 @@ chip soc/intel/meteorlake end device pci 14.1 alias usb_otg off end device pci 14.2 alias pmc_shared_sram off end - device pci 14.3 alias cnvi_wifi off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end device pci 14.5 alias ieh off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 15.4 alias i3c off end device pci 16.0 alias heci1 on end device pci 16.1 alias heci2 off end device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end - device pci 17.0 alias sata off end + device pci 17.0 alias sata off ops sata_ops end device pci 18.0 alias eheci1 off end device pci 18.1 alias eheci2 off end device pci 18.2 alias eheci3 off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end - device pci 19.2 alias uart2 off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1c.4 alias pcie_rp5 off end - device pci 1c.5 alias pcie_rp6 off end - device pci 1c.6 alias pcie_rp7 off end - device pci 1c.7 alias pcie_rp8 off end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end + device pci 19.2 alias uart2 off ops uart_ops end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1e.4 alias tsn_gbe1 off end device pci 1e.5 alias tsn_gbe2 off end device pci 1f.0 alias soc_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.3 alias hda off ops hda_ops end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias npk off end diff --git a/src/soc/intel/meteorlake/cpu.c b/src/soc/intel/meteorlake/cpu.c index b4854cb6ef0..05fe9a97562 100644 --- a/src/soc/intel/meteorlake/cpu.c +++ b/src/soc/intel/meteorlake/cpu.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -142,7 +143,7 @@ void soc_core_init(struct device *cpu) /* Set core type in struct cpu_info */ set_dev_core_type(); - if (CONFIG(INTEL_TME) && is_tme_supported()) + if (get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported()) set_tme_core_activate(); if (CONFIG(DROP_CPU_FEATURE_PROGRAM_IN_FSP)) { diff --git a/src/soc/intel/meteorlake/fsp_params.c b/src/soc/intel/meteorlake/fsp_params.c index 61be03ad478..5e7bdc53aba 100644 --- a/src/soc/intel/meteorlake/fsp_params.c +++ b/src/soc/intel/meteorlake/fsp_params.c @@ -641,6 +641,7 @@ static void fill_fsps_pcie_params(FSP_S_CONFIG *s_cfg, s_cfg->PcieRpHotPlug[i] = !!(rp_cfg->flags & PCIE_RP_HOTPLUG) || CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE); s_cfg->PcieRpClkReqDetect[i] = !!(rp_cfg->flags & PCIE_RP_CLK_REQ_DETECT); + s_cfg->PcieRpDetectTimeoutMs[i] = rp_cfg->pcie_rp_detect_timeout_ms; configure_pch_rp_power_management(s_cfg, rp_cfg, i); } s_cfg->PcieComplianceTestMode = CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE); diff --git a/src/soc/intel/meteorlake/gspi.c b/src/soc/intel/meteorlake/gspi.c deleted file mode 100644 index 387d3e3949b..00000000000 --- a/src/soc/intel/meteorlake/gspi.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCI_DEVFN_GSPI0; - case 1: - return PCI_DEVFN_GSPI1; - case 2: - return PCI_DEVFN_GSPI2; - } - return -1; -} diff --git a/src/soc/intel/meteorlake/i2c.c b/src/soc/intel/meteorlake/i2c.c deleted file mode 100644 index 50ab4a73eb4..00000000000 --- a/src/soc/intel/meteorlake/i2c.c +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCI_DEVFN_I2C0: - return 0; - case PCI_DEVFN_I2C1: - return 1; - case PCI_DEVFN_I2C2: - return 2; - case PCI_DEVFN_I2C3: - return 3; - case PCI_DEVFN_I2C4: - return 4; - case PCI_DEVFN_I2C5: - return 5; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCI_DEVFN_I2C0; - case 1: - return PCI_DEVFN_I2C1; - case 2: - return PCI_DEVFN_I2C2; - case 3: - return PCI_DEVFN_I2C3; - case 4: - return PCI_DEVFN_I2C4; - case 5: - return PCI_DEVFN_I2C5; - } - return -1; -} diff --git a/src/soc/intel/meteorlake/include/soc/cfr.h b/src/soc/intel/meteorlake/include/soc/cfr.h index 5379f439c49..acc7fb6b7af 100644 --- a/src/soc/intel/meteorlake/include/soc/cfr.h +++ b/src/soc/intel/meteorlake/include/soc/cfr.h @@ -11,27 +11,19 @@ #include /* FSP hyperthreading */ -static const struct sm_object hyper_threading = SM_DECLARE_ENUM({ +static const struct sm_object hyper_threading = SM_DECLARE_BOOL({ .opt_name = "hyper_threading", .ui_name = "Hyper-Threading", .ui_helptext = "Enable or disable Hyper-Threading", .default_value = CONFIG(FSP_HYPERTHREADING), - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, }); /* IGD Enabled */ -static const struct sm_object igd_enabled = SM_DECLARE_ENUM({ +static const struct sm_object igd_enabled = SM_DECLARE_BOOL({ .opt_name = "igd_enabled", .ui_name = "Enable the Intel iGPU", .ui_helptext = "Enable or disable the Intel iGPU", .default_value = !CONFIG(SOC_INTEL_DISABLE_IGD), - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, }); /* IGD DVMT pre-allocated memory */ @@ -47,42 +39,30 @@ static const struct sm_object igd_dvmt = SM_DECLARE_ENUM({ { "128 MB", IGD_SM_128MB }, { "160 MB", IGD_SM_160MB }, SM_ENUM_VALUE_END }, -}, WITH_DEP_VALUES(&igd_enabled, 1)); +}, WITH_DEP_VALUES(&igd_enabled, true)); /* Legacy 8254 Timer */ -static const struct sm_object legacy_8254_timer = SM_DECLARE_ENUM({ +static const struct sm_object legacy_8254_timer = SM_DECLARE_BOOL({ .opt_name = "legacy_8254_timer", .ui_name = "Legacy 8254 Timer", .ui_helptext = "Enable the legacy 8254 timer by disabling clock gating.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = false, }); /* S0ix Enable */ -static const struct sm_object s0ix_enable = SM_DECLARE_ENUM({ +static const struct sm_object s0ix_enable = SM_DECLARE_BOOL({ .opt_name = "s0ix_enable", .ui_name = "Modern Standby (S0ix)", .ui_helptext = "Enabled: use Modern Standby / S0ix. Disabled: use ACPI S3 sleep", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* VT-d */ -static const struct sm_object vtd = SM_DECLARE_ENUM({ +static const struct sm_object vtd = SM_DECLARE_BOOL({ .opt_name = "vtd", .ui_name = "VT-d", .ui_helptext = "Enable or disable Intel VT-d (virtualization)", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); #endif /* _METEORLAKE_CFR_H_ */ diff --git a/src/soc/intel/meteorlake/include/soc/pci_devs.h b/src/soc/intel/meteorlake/include/soc/pci_devs.h index 0e55da24bbb..61485fc450d 100644 --- a/src/soc/intel/meteorlake/include/soc/pci_devs.h +++ b/src/soc/intel/meteorlake/include/soc/pci_devs.h @@ -241,5 +241,8 @@ #define SA_DEVFN_TCSS_DMA1 PCI_DEVFN_TCSS_DMA1 #define SA_DEV_IGD PCI_DEV_IGD #define SA_DEVFN_IGD PCI_DEVFN_IGD +#define SOC_I2C_DEVFN(n) PCI_DEVFN_I2C##n +#define SOC_GSPI_DEVFN(n) PCI_DEVFN_GSPI##n +#define SOC_PMC_DEV PCI_DEV_PMC #endif // _SOC_METEORLAKE_PCI_DEVS_H_ diff --git a/src/soc/intel/meteorlake/include/soc/pm.h b/src/soc/intel/meteorlake/include/soc/pm.h index 7474cdd8bce..c486232e7da 100644 --- a/src/soc/intel/meteorlake/include/soc/pm.h +++ b/src/soc/intel/meteorlake/include/soc/pm.h @@ -150,9 +150,6 @@ struct chipset_power_state { /* Get base address PMC memory mapped registers. */ uint8_t *pmc_mmio_regs(void); -/* Get base address IOE.PMC memory mapped registers. */ -uint8_t *ioe_pmc_mmio_regs(void); - /* Get base address of TCO I/O registers. */ uint16_t smbus_tco_regs(void); diff --git a/src/soc/intel/meteorlake/include/soc/pmc.h b/src/soc/intel/meteorlake/include/soc/pmc.h index 6c40b4a5ee4..19365ea122a 100644 --- a/src/soc/intel/meteorlake/include/soc/pmc.h +++ b/src/soc/intel/meteorlake/include/soc/pmc.h @@ -62,6 +62,9 @@ extern struct device_operations ioe_pmc_ops; #define SMI_LOCK (1 << 4) #define RTC_BATTERY_DEAD (1 << 2) +/* PMC lockdown configuration register for ST_FDIS_LOCK */ +#define PMC_FDIS_LOCK_REG GEN_PMCON_B + #define ETR 0x1048 #define CF9_LOCK (1 << 31) #define CF9_GLB_RST (1 << 20) diff --git a/src/soc/intel/meteorlake/ioe_pmc.c b/src/soc/intel/meteorlake/ioe_pmc.c index 418c4a5535f..e2fb49be4d7 100644 --- a/src/soc/intel/meteorlake/ioe_pmc.c +++ b/src/soc/intel/meteorlake/ioe_pmc.c @@ -5,6 +5,11 @@ #include #include +static uint8_t *ioe_pmc_mmio_regs(void) +{ + return (void *)(uintptr_t)IOE_PWRM_BASE_ADDRESS; +} + static void ioe_pmc_read_resources(struct device *dev) { /* Add the fixed MMIO resource */ diff --git a/src/soc/intel/meteorlake/meminit.c b/src/soc/intel/meteorlake/meminit.c index f4cde7e168f..eb405bf8a8e 100644 --- a/src/soc/intel/meteorlake/meminit.c +++ b/src/soc/intel/meteorlake/meminit.c @@ -46,8 +46,8 @@ static const struct soc_mem_cfg soc_mem_cfg[] = { * configuration. */ .half_channel = BIT(0), - /* In mixed topologies, either channel 0 or 1 can be memory-down. */ - .mixed_topo = BIT(0) | BIT(1), + /* In mixed topologies, channel 0 is memory-down. */ + .mixed_topo = BIT(0), }, }, [MEM_TYPE_LP5X] = { diff --git a/src/soc/intel/meteorlake/pmutil.c b/src/soc/intel/meteorlake/pmutil.c deleted file mode 100644 index a0bba92f11e..00000000000 --- a/src/soc/intel/meteorlake/pmutil.c +++ /dev/null @@ -1,286 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * Helper functions for dealing with power management registers - * and the differences between PCH variants. - */ - -#define __SIMPLE_DEVICE__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * SMI - */ -const char *const *soc_smi_sts_array(size_t *a) -{ - static const char *const smi_sts_bits[] = { - [BIOS_STS_BIT] = "BIOS", - [LEGACY_USB_STS_BIT] = "LEGACY_USB", - [SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI", - [APM_STS_BIT] = "APM", - [SWSMI_TMR_STS_BIT] = "SWSMI_TMR", - [PM1_STS_BIT] = "PM1", - [GPE0_STS_BIT] = "GPE0", - [GPIO_STS_BIT] = "GPI", - [MCSMI_STS_BIT] = "MCSMI", - [DEVMON_STS_BIT] = "DEVMON", - [TCO_STS_BIT] = "TCO", - [PERIODIC_STS_BIT] = "PERIODIC", - [SERIRQ_SMI_STS_BIT] = "SERIRQ_SMI", - [SMBUS_SMI_STS_BIT] = "SMBUS_SMI", - [PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI", - [MONITOR_STS_BIT] = "MONITOR", - [SPI_SMI_STS_BIT] = "SPI", - [GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK", - [ESPI_SMI_STS_BIT] = "ESPI_SMI", - }; - - *a = ARRAY_SIZE(smi_sts_bits); - return smi_sts_bits; -} - -/* - * TCO - */ -const char *const *soc_tco_sts_array(size_t *a) -{ - static const char *const tco_sts_bits[] = { - [0] = "NMI2SMI", - [1] = "SW_TCO", - [2] = "TCO_INT", - [3] = "TIMEOUT", - [7] = "NEWCENTURY", - [8] = "BIOSWR", - [9] = "DMISCI", - [10] = "DMISMI", - [12] = "DMISERR", - [13] = "SLVSEL", - [16] = "INTRD_DET", - [17] = "SECOND_TO", - [18] = "BOOT", - [20] = "SMLINK_SLV" - }; - - *a = ARRAY_SIZE(tco_sts_bits); - return tco_sts_bits; -} - -/* - * GPE0 - */ -const char *const *soc_std_gpe_sts_array(size_t *a) -{ - static const char *const gpe_sts_bits[] = { - [1] = "HOTPLUG", - [2] = "SWGPE", - [6] = "TCO_SCI", - [7] = "SMB_WAK", - [9] = "PCI_EXP", - [10] = "BATLOW", - [11] = "PME", - [12] = "ME", - [13] = "PME_B0", - [14] = "eSPI", - [15] = "GPIO Tier-2", - [16] = "LAN_WAKE", - [18] = "WADT" - }; - - *a = ARRAY_SIZE(gpe_sts_bits); - return gpe_sts_bits; -} - -void pmc_set_disb(void) -{ - /* Set the DISB after DRAM init */ - uint8_t disb_val; - /* Only care about bits [23:16] of register GEN_PMCON_A */ - uint8_t *addr = (uint8_t *)(pmc_mmio_regs() + GEN_PMCON_A + 2); - - disb_val = read8(addr); - disb_val |= (DISB >> 16); - - /* Don't clear bits that are write-1-to-clear */ - disb_val &= ~((MS4V | SUS_PWR_FLR) >> 16); - write8(addr, disb_val); -} - -/* - * PMC controller gets hidden from PCI bus - * during FSP-Silicon init call. Hence PWRMBASE - * can't be accessible using PCI configuration space - * read/write. - */ -uint8_t *pmc_mmio_regs(void) -{ - return (void *)(uintptr_t)PCH_PWRM_BASE_ADDRESS; -} - -uint8_t *ioe_pmc_mmio_regs(void) -{ - return (void *)(uintptr_t)IOE_PWRM_BASE_ADDRESS; -} - -uintptr_t soc_read_pmc_base(void) -{ - return (uintptr_t)pmc_mmio_regs(); -} - -uint32_t *soc_pmc_etr_addr(void) -{ - return (uint32_t *)(soc_read_pmc_base() + ETR); -} - -static void pmc_gpe0_different_values(const struct soc_intel_meteorlake_config *config) -{ - bool all_zero = (config->pmc_gpe0_dw0 == 0) && - (config->pmc_gpe0_dw1 == 0) && - (config->pmc_gpe0_dw2 == 0); - - /* Check if all values are different AND not all zero */ - bool all_different = (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw1) && - (config->pmc_gpe0_dw0 != config->pmc_gpe0_dw2) && - (config->pmc_gpe0_dw1 != config->pmc_gpe0_dw2); - - assert(all_different || all_zero); -} - -void soc_get_gpi_gpe_configs(uint8_t *dw0, uint8_t *dw1, uint8_t *dw2) -{ - DEVTREE_CONST struct soc_intel_meteorlake_config *config; - - config = config_of_soc(); - - pmc_gpe0_different_values(config); - - /* Assign to out variable */ - *dw0 = config->pmc_gpe0_dw0; - *dw1 = config->pmc_gpe0_dw1; - *dw2 = config->pmc_gpe0_dw2; -} - -static int rtc_failed(uint32_t gen_pmcon_b) -{ - return !!(gen_pmcon_b & RTC_BATTERY_DEAD); -} - -int soc_get_rtc_failed(void) -{ - const struct chipset_power_state *ps; - - if (acpi_fetch_pm_state(&ps, PS_CLAIMER_RTC) < 0) - return 1; - - return rtc_failed(ps->gen_pmcon_b); -} - -int vbnv_cmos_failed(void) -{ - return rtc_failed(read32(pmc_mmio_regs() + GEN_PMCON_B)); -} - -static inline int deep_s3_enabled(void) -{ - uint32_t deep_s3_pol; - - deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL); - return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS)); -} - -/* Return 0, 3, or 5 to indicate the previous sleep state. */ -int soc_prev_sleep_state(const struct chipset_power_state *ps, int prev_sleep_state) -{ - /* - * Check for any power failure to determine if this a wake from - * S5 because the PCH does not set the WAK_STS bit when waking - * from a true G3 state. - */ - if (!(ps->pm1_sts & WAK_STS) && (ps->gen_pmcon_a & (PWR_FLR | SUS_PWR_FLR))) - prev_sleep_state = ACPI_S5; - - /* - * If waking from S3 determine if deep S3 is enabled. If not, - * need to check both deep sleep well and normal suspend well. - * Otherwise just check deep sleep well. - */ - if (prev_sleep_state == ACPI_S3) { - /* PWR_FLR represents deep sleep power well loss. */ - uint32_t mask = PWR_FLR; - - /* If deep s3 isn't enabled check the suspend well too. */ - if (!deep_s3_enabled()) - mask |= SUS_PWR_FLR; - - if (ps->gen_pmcon_a & mask) - prev_sleep_state = ACPI_S5; - } - - return prev_sleep_state; -} - -void soc_fill_power_state(struct chipset_power_state *ps) -{ - uint8_t *pmc; - - ps->tco1_sts = tco_read_reg(TCO1_STS); - ps->tco2_sts = tco_read_reg(TCO2_STS); - - printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", ps->tco1_sts, ps->tco2_sts); - - pmc = pmc_mmio_regs(); - ps->gen_pmcon_a = read32(pmc + GEN_PMCON_A); - ps->gen_pmcon_b = read32(pmc + GEN_PMCON_B); - ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0); - ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1); - ps->hpr_cause0 = read32(pmc + HPR_CAUSE0); - - printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n", - ps->gen_pmcon_a, ps->gen_pmcon_b); - - printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n", - ps->gblrst_cause[0], ps->gblrst_cause[1]); - - printk(BIOS_DEBUG, "HPR_CAUSE0: %08x\n", ps->hpr_cause0); -} - -/* STM Support */ -uint16_t get_pmbase(void) -{ - return (uint16_t)ACPI_BASE_ADDRESS; -} - -/* - * Set which power state system will be after reapplying - * the power (from G3 State) - */ -void pmc_soc_set_afterg3_en(const bool on) -{ - uint8_t reg8; - uint8_t *const pmcbase = pmc_mmio_regs(); - - reg8 = read8(pmcbase + GEN_PMCON_A); - if (on) - reg8 &= ~SLEEP_AFTER_POWER_FAIL; - else - reg8 |= SLEEP_AFTER_POWER_FAIL; - write8(pmcbase + GEN_PMCON_A, reg8); -} diff --git a/src/soc/intel/meteorlake/reset.c b/src/soc/intel/meteorlake/reset.c deleted file mode 100644 index 3c13f6dfe56..00000000000 --- a/src/soc/intel/meteorlake/reset.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -void do_global_reset(void) -{ - /* Ask CSE to do the global reset */ - if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) - return; - - /* global reset if CSE fail to reset */ - pmc_global_reset_enable(1); - do_full_reset(); -} diff --git a/src/soc/intel/meteorlake/romstage/fsp_params.c b/src/soc/intel/meteorlake/romstage/fsp_params.c index cec83042819..3ab06181748 100644 --- a/src/soc/intel/meteorlake/romstage/fsp_params.c +++ b/src/soc/intel/meteorlake/romstage/fsp_params.c @@ -198,7 +198,7 @@ static void fill_fspm_cpu_params(FSP_M_CONFIG *m_cfg, static void fill_tme_params(FSP_M_CONFIG *m_cfg) { - m_cfg->TmeEnable = CONFIG(INTEL_TME) && is_tme_supported(); + m_cfg->TmeEnable = get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported(); if (!m_cfg->TmeEnable || acpi_is_wakeup_s3()) return; m_cfg->GenerateNewTmeKey = CONFIG(TME_KEY_REGENERATION_ON_WARM_BOOT) && @@ -294,6 +294,8 @@ static void fill_fspm_misc_params(FSP_M_CONFIG *m_cfg, static void fill_fspm_audio_params(FSP_M_CONFIG *m_cfg, const struct soc_intel_meteorlake_config *config) { + const struct device *dev; + /* Audio: HDAUDIO_LINK_MODE I2S/SNDW */ m_cfg->PchHdaEnable = is_devfn_enabled(PCI_DEVFN_HDA); m_cfg->PchHdaDspEnable = config->pch_hda_dsp_enable; @@ -308,6 +310,13 @@ static void fill_fspm_audio_params(FSP_M_CONFIG *m_cfg, memset(m_cfg->PchHdaAudioLinkDmicEnable, 0, sizeof(m_cfg->PchHdaAudioLinkDmicEnable)); memset(m_cfg->PchHdaAudioLinkSspEnable, 0, sizeof(m_cfg->PchHdaAudioLinkSspEnable)); memset(m_cfg->PchHdaAudioLinkSndwEnable, 0, sizeof(m_cfg->PchHdaAudioLinkSndwEnable)); + + dev = pcidev_path_on_root(PCI_DEVFN_HDA); + if (dev) { + uint16_t svid = CONFIG_SUBSYSTEM_VENDOR_ID ? : (dev->subsystem_vendor ? : 0x8086); + uint16_t ssid = CONFIG_SUBSYSTEM_DEVICE_ID ? : (dev->subsystem_device ? : 0x7e28); + m_cfg->PchHdaSubSystemIds = (ssid << 16) | svid; + } } static void fill_fspm_cnvi_params(FSP_M_CONFIG *m_cfg, diff --git a/src/soc/intel/meteorlake/spi.c b/src/soc/intel/meteorlake/spi.c deleted file mode 100644 index f7d751f98eb..00000000000 --- a/src/soc/intel/meteorlake/spi.c +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include -#include - -#define PSF_SPI_DESTINATION_ID 0x5140 - -int spi_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCI_DEVFN_GSPI0: - return 1; - case PCI_DEVFN_GSPI1: - return 2; - case PCI_DEVFN_GSPI2: - return 3; - } - return -1; -} - -uint32_t soc_get_spi_psf_destination_id(void) -{ - return PSF_SPI_DESTINATION_ID; -} diff --git a/src/soc/intel/meteorlake/systemagent.c b/src/soc/intel/meteorlake/systemagent.c index bb841aa60b0..9dc771f6e2a 100644 --- a/src/soc/intel/meteorlake/systemagent.c +++ b/src/soc/intel/meteorlake/systemagent.c @@ -108,7 +108,7 @@ void soc_add_configurable_mmio_resources(struct device *dev, int *resource_cnt) } /* TSEG */ - size = sa_get_tseg_size(); + size = CONFIG_SMM_TSEG_SIZE; tseg_base = sa_get_tseg_base(); if (size > 0) set_mmio_resource(&(cfg_rsrc[count++]), tseg_base, size, "TSEG"); diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index bf02cde32f3..00616f14a57 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -62,6 +62,7 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_BLOCK_ACPI_LPIT select SOC_INTEL_COMMON_BLOCK_ACPI_PEP select SOC_INTEL_COMMON_BLOCK_ACPI_PEP_LPM_REQ + select SOC_INTEL_COMMON_BLOCK_ASPM select SOC_INTEL_COMMON_BLOCK_CAR select SOC_INTEL_COMMON_BLOCK_CHIP_CONFIG select SOC_INTEL_COMMON_BLOCK_CNVI @@ -95,6 +96,19 @@ config SOC_INTEL_PANTHERLAKE_BASE select SOC_INTEL_COMMON_BLOCK_TRACEHUB select SOC_INTEL_COMMON_BLOCK_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_FINALIZE + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN + select SOC_INTEL_COMMON_FEATURE_LOCKDOWN + select SOC_INTEL_COMMON_FEATURE_PMUTIL + select SOC_INTEL_COMMON_FEATURE_SMIHANDLER + select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_RESET @@ -252,7 +266,6 @@ config MAX_TBT_ROOT_PORTS config MAX_ROOT_PORTS int default 6 if SOC_INTEL_WILDCATLAKE - default 10 if SOC_INTEL_PANTHERLAKE_H default 12 config MAX_PCIE_CLOCK_SRC @@ -475,4 +488,12 @@ config RAMSTAGE_CBFS_CACHE_SIZE config CBFS_CACHE_ALIGN default 1024 +config SOC_INTEL_SPI_DEV_MAX + int + default 3 + +config SOC_INTEL_SPI_PSF_DESTINATION_ID + hex + default 0x5140 + endif diff --git a/src/soc/intel/pantherlake/Makefile.mk b/src/soc/intel/pantherlake/Makefile.mk index 6476bf6e36d..b7ea31b1f60 100644 --- a/src/soc/intel/pantherlake/Makefile.mk +++ b/src/soc/intel/pantherlake/Makefile.mk @@ -7,23 +7,16 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += gspi.c -all-y += i2c.c -all-y += pmutil.c -all-y += spi.c -all-y += uart.c all-y += gpio.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pcd.c bootblock-y += bootblock/report_platform.c -bootblock-y += espi.c romstage-$(CONFIG_SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY) += cse_telemetry.c -romstage-y += espi.c romstage-y += meminit.c romstage-y += pcie_rp.c -romstage-y += reset.c +romstage-y += tdp.c ramstage-y += acpi.c ramstage-y += cbfs_preload.c @@ -31,27 +24,20 @@ ramstage-y += chip.c ramstage-y += cpu.c ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog.c ramstage-y += elog.c -ramstage-y += espi.c -ramstage-y += finalize.c ramstage-y += fsp_params.c -ramstage-y += lockdown.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c -ramstage-y += reset.c ramstage-y += retimer.c -ramstage-y += soundwire.c ramstage-y += systemagent.c ramstage-y += tcss.c +ramstage-y += tdp.c ramstage-y += xhci.c ramstage-$(CONFIG_DRIVERS_INTEL_TOUCH) += touch.c smm-y += elog.c smm-y += gpio.c smm-y += p2sb.c -smm-y += pmutil.c -smm-y += smihandler.c -smm-y += uart.c smm-y += xhci.c CPPFLAGS_common += -I$(src)/soc/intel/pantherlake CPPFLAGS_common += -I$(src)/soc/intel/pantherlake/include diff --git a/src/soc/intel/pantherlake/acpi/southbridge.asl b/src/soc/intel/pantherlake/acpi/southbridge.asl index f2ad16b36ba..fc74ce00b28 100644 --- a/src/soc/intel/pantherlake/acpi/southbridge.asl +++ b/src/soc/intel/pantherlake/acpi/southbridge.asl @@ -57,3 +57,6 @@ #if CONFIG(SOC_INTEL_WILDCATLAKE) #include #endif + +/* P2B access for IOST */ +#include diff --git a/src/soc/intel/pantherlake/acpi/xhci.asl b/src/soc/intel/pantherlake/acpi/xhci.asl index cd3b9f22feb..d1a8919c9b1 100644 --- a/src/soc/intel/pantherlake/acpi/xhci.asl +++ b/src/soc/intel/pantherlake/acpi/xhci.asl @@ -2,6 +2,9 @@ #include +/* Include UWES method for enabling USB wake */ +#include + /* XHCI Controller 0:14.0 */ Device (XHCI) @@ -10,6 +13,20 @@ Device (XHCI) Name (_PRW, Package () { GPE0_PME_B0, 3 }) + OperationRegion (XPRT, PCI_Config, 0x00, 0x100) + Field (XPRT, AnyAcc, NoLock, Preserve) + { + Offset (0x10), + , 16, + XMEM, 16, /* MEM_BASE */ + } + + Method (_DSW, 3) + { + UWES ((\U2WE & 0xFFF), PORTSCN_OFFSET, XMEM) + UWES ((\U3WE & 0x3F ), PORTSCXUSB3_OFFSET, XMEM) + } + Name (_S3D, 3) /* D3 supported in S3 */ Name (_S0W, 3) /* D3 can wake device in S0 */ Name (_S3W, 3) /* D3 can wake system from S3 */ diff --git a/src/soc/intel/pantherlake/bootblock/pcd.c b/src/soc/intel/pantherlake/bootblock/pcd.c index 50e6ebd73d0..bd87dfa82ae 100644 --- a/src/soc/intel/pantherlake/bootblock/pcd.c +++ b/src/soc/intel/pantherlake/bootblock/pcd.c @@ -48,8 +48,8 @@ static void pcd_die_config_pwrmbase(void) static void pcd_die_early_iorange_init(void) { - uint16_t io_enables = LPC_IOE_SUPERIO_2E_2F | LPC_IOE_KBC_60_64 | - LPC_IOE_EC_62_66 | LPC_IOE_LGE_200; + uint16_t io_enables = LPC_IOE_SUPERIO_2E_2F | LPC_IOE_EC_4E_4F | + LPC_IOE_KBC_60_64 | LPC_IOE_EC_62_66 | LPC_IOE_LGE_200; /* IO Decode Range */ if (CONFIG(DRIVERS_UART_8250IO)) diff --git a/src/soc/intel/pantherlake/chip.c b/src/soc/intel/pantherlake/chip.c index 80052404753..739cd9452ab 100644 --- a/src/soc/intel/pantherlake/chip.c +++ b/src/soc/intel/pantherlake/chip.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include @@ -15,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -221,6 +223,40 @@ static void cpu_fill_ssdt(const struct device *dev) generate_cpu_entries(dev); } +/* + * This implements SoC-specific function used in common P2SB code to generate + * additional P2SB-related ACPI code. + */ +void soc_fill_p2sb_ssdt(const struct device *dev) +{ + /* + * Enable IOST for debug via P2SB at OS level. The associated IOST ASL file + * (i.e., src/soc/intel/common/acpi/iost.asl) is included in the SoC's + * southbridge.asl. The CBFS option "iost_enable" is used to expose this + * IOST interface to the OS. + * Use cbfstool command to add this option to the image. + */ + if (!get_uint_option("iost_enable", 0)) + return; + + printk(BIOS_INFO, "IOST is enabled\n"); + /* + * The following generates: + * Scope (\_SB.PCI0.IOST) + * { + * If (CondRefOf (IOSE)) + * { + * IOSE = 0x0F + * } + * } + */ + acpigen_write_scope("\\_SB.PCI0.IOST"); + acpigen_write_if_cond_ref_of("IOSE"); + acpigen_write_store_int_to_namestr(0xf, "IOSE"); + acpigen_write_if_end(); + acpigen_write_scope_end(); +} + static void cpu_set_north_irqs(struct device *dev) { irq_program_non_pch(); diff --git a/src/soc/intel/pantherlake/chip.h b/src/soc/intel/pantherlake/chip.h index d383d63fa56..0db0b14036a 100644 --- a/src/soc/intel/pantherlake/chip.h +++ b/src/soc/intel/pantherlake/chip.h @@ -78,10 +78,6 @@ enum soc_intel_pantherlake_sku { PTL_SKU_6, PTL_SKU_7, WCL_SKU_1, - WCL_SKU_2, - WCL_SKU_3, - WCL_SKU_4, - WCL_SKU_5, MAX_PTL_SKUS, }; @@ -119,10 +115,10 @@ static const struct soc_intel_pantherlake_power_map { { PCI_DID_INTEL_PTL_H_ID_7, PTL_CORE_4, TDP_25W, PTL_SKU_7, PTL_TDC_4 }, { PCI_DID_INTEL_PTL_H_ID_8, PTL_CORE_3, TDP_25W, PTL_SKU_2, PTL_TDC_3 }, { PCI_DID_INTEL_WCL_ID_1, WCL_CORE, TDP_15W, WCL_SKU_1, WCL_TDC_1 }, - { PCI_DID_INTEL_WCL_ID_2, WCL_CORE, TDP_15W, WCL_SKU_2, WCL_TDC_1 }, - { PCI_DID_INTEL_WCL_ID_3, WCL_CORE, TDP_15W, WCL_SKU_3, WCL_TDC_1 }, - { PCI_DID_INTEL_WCL_ID_4, WCL_CORE, TDP_15W, WCL_SKU_4, WCL_TDC_1 }, - { PCI_DID_INTEL_WCL_ID_5, WCL_CORE, TDP_15W, WCL_SKU_5, WCL_TDC_1 }, + { PCI_DID_INTEL_WCL_ID_2, WCL_CORE, TDP_15W, WCL_SKU_1, WCL_TDC_1 }, + { PCI_DID_INTEL_WCL_ID_3, WCL_CORE, TDP_15W, WCL_SKU_1, WCL_TDC_1 }, + { PCI_DID_INTEL_WCL_ID_4, WCL_CORE, TDP_15W, WCL_SKU_1, WCL_TDC_1 }, + { PCI_DID_INTEL_WCL_ID_5, WCL_CORE, TDP_15W, WCL_SKU_1, WCL_TDC_1 }, }; /* Types of display ports */ @@ -341,7 +337,8 @@ struct soc_intel_pantherlake_config { IGD_SM_0MB = 0x00, IGD_SM_32MB = 0x01, IGD_SM_64MB = 0x02, - IGD_SM_128MB = 0x03, + IGD_SM_96MB = 0x03, + IGD_SM_128MB = 0x04, IGD_SM_4MB = 0xF0, IGD_SM_8MB = 0xF1, IGD_SM_12MB = 0xF2, @@ -382,18 +379,18 @@ struct soc_intel_pantherlake_config { * Fast Vmode I_TRIP Thresholds for VR Domains * * This two-dimensional array represents the Fast Vmode I_TRIP thresholds - * for various Voltage Regulator (VR) domains across different power limit - * configurations in Panther Lake SoCs. + * for various Voltage Regulator (VR) domains across different SKUs + * in Panther Lake SoCs. * * The Fast Vmode I_TRIP threshold is used to override the default current * threshold settings, ensuring optimal power management by adapting to - * specific VR domain requirements under different power limit scenarios. + * specific VR domain requirements for each SKU's hardware capabilities. * * 0-255A in 1/4 A units. Example: 400 = 100A * This setting overrides the default value set by FSPs when Fast VMode * is enabled. */ - uint16_t fast_vmode_i_trip[PTL_POWER_LIMITS_COUNT][NUM_VR_DOMAINS]; + uint16_t fast_vmode_i_trip[MAX_PTL_SKUS][NUM_VR_DOMAINS]; /* * Power state current threshold 1. @@ -485,6 +482,15 @@ struct soc_intel_pantherlake_config { uint16_t ps2_threshold[NUM_VR_DOMAINS]; uint16_t ps3_threshold[NUM_VR_DOMAINS]; + /* + * Thermal Design Power setting. + * + * Certain Panther Lake SKUs are compatible with multiple TDP options. For these + * SKUs, the following field can be set to choose the TDP that best fits the + * board's power and thermal requirements. + */ + enum soc_intel_pantherlake_cpu_tdps tdp; + /* * SerialIO device mode selection: * PchSerialIoDisabled, @@ -752,6 +758,19 @@ struct soc_intel_pantherlake_config { /* Disable the progress bar during MRC training operations. */ bool disable_progress_bar; + + /* + * VgaInitControl CD Clock Frequency Selection + * 0: CD_CLK_NONE - No higher CD Clock required + * 1: CD_CLK_442MHZ - 441 MHz + * 2: CD_CLK_461MHZ - 461 MHz + */ + enum cd_clock { + CD_CLK_NONE = 0, + CD_CLK_442MHZ, + CD_CLK_461MHZ, + MAX_CD_CLOCK = CD_CLK_461MHZ + } vga_cd_clk_freq_sel; }; typedef struct soc_intel_pantherlake_config config_t; diff --git a/src/soc/intel/pantherlake/chipset_ptl.cb b/src/soc/intel/pantherlake/chipset_ptl.cb index e646c5dc4e3..d2521efc783 100644 --- a/src/soc/intel/pantherlake/chipset_ptl.cb +++ b/src/soc/intel/pantherlake/chipset_ptl.cb @@ -3,7 +3,7 @@ chip soc/intel/pantherlake device cpu_cluster 0 on end register "power_limits_config[PTL_CORE_1]" = "{ - .tdp_pl1_override = 15, + .tdp_pl1_override = 0, /* Use TDP */ .tdp_pl2_override = 55, .tdp_pl4 = 163, .tdp_pl4_fastvmode = 150, @@ -24,7 +24,7 @@ chip soc/intel/pantherlake }" register "power_limits_config[PTL_CORE_2]" = "{ - .tdp_pl1_override = 15, + .tdp_pl1_override = 0, /* Use TDP */ .tdp_pl2_override = 55, .tdp_pl4 = 163, .tdp_pl4_fastvmode = 150, @@ -37,7 +37,7 @@ chip soc/intel/pantherlake }" register "power_limits_config[PTL_CORE_3]" = "{ - .tdp_pl1_override = 25, + .tdp_pl1_override = 0, /* Use TDP */ .tdp_pl2_override = 65, .tdp_pl4 = 175, .tdp_pl4_fastvmode = 160, @@ -58,7 +58,7 @@ chip soc/intel/pantherlake }" register "power_limits_config[PTL_CORE_4]" = "{ - .tdp_pl1_override = 25, + .tdp_pl1_override = 0, /* Use TDP */ .tdp_pl2_override = 65, .tdp_pl4 = 160, .tdp_pl4_fastvmode = 140 @@ -82,11 +82,11 @@ chip soc/intel/pantherlake register "tdc_time_window_ms[VR_DOMAIN_IA]" = "28000" # Set the power state thresholds according to document 813278 - # Panther Lake H Platform - Design Guide - Rev 2.0 + # Panther Lake H Platform - Design Guide - Draft > 2.1 register "ps1_threshold" = "{ - [VR_DOMAIN_IA] = 20 * 4, - [VR_DOMAIN_GT] = 20 * 4, - [VR_DOMAIN_SA] = 20 * 4 + [VR_DOMAIN_IA] = 15 * 4, + [VR_DOMAIN_GT] = 15 * 4, + [VR_DOMAIN_SA] = 15 * 4 }" register "ps2_threshold" = "{ [VR_DOMAIN_IA] = 5 * 4, @@ -112,10 +112,10 @@ chip soc/intel/pantherlake device pci 02.0 alias igpu on end device pci 04.0 alias dtt off end device pci 05.0 alias ipu off end - device pci 06.0 alias pcie_rp9 off end - device pci 06.1 alias pcie_rp10 off end - device pci 06.2 alias pcie_rp11 off end - device pci 06.3 alias pcie_rp12 off end + device pci 06.0 alias pcie_rp9 off ops pcie_rp_ops end + device pci 06.1 alias pcie_rp10 off ops pcie_rp_ops end + device pci 06.2 alias pcie_rp11 off ops pcie_rp_ops end + device pci 06.3 alias pcie_rp12 off ops pcie_rp_ops end device pci 07.0 alias tbt_pcie_rp0 off chip soc/intel/common/block/usb4 use tcss_dma0 as usb4_port @@ -162,7 +162,7 @@ chip soc/intel/pantherlake end end end - device pci 0d.1 alias tcss_xdci off end + device pci 0d.1 alias tcss_xdci off ops usb_xdci_ops end device pci 0d.2 alias tcss_dma0 off end device pci 0d.3 alias tcss_dma1 off end device pci 0e.0 alias vmd off end @@ -170,11 +170,11 @@ chip soc/intel/pantherlake device pci 10.1 alias thc1 off end device pci 12.0 alias ish off end device pci 12.1 alias p2sb2 hidden end - device pci 12.6 alias gspi0a off end + device pci 12.6 alias gspi0a off ops spi_dev_ops end device pci 13.0 alias heci_1 off end device pci 13.1 alias heci_2 off end device pci 13.2 alias heci_3 off end - device pci 14.0 alias xhci on + device pci 14.0 alias xhci on ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off @@ -212,13 +212,13 @@ chip soc/intel/pantherlake end end device pci 14.2 alias pmc_shared_sram off end - device pci 14.3 alias cnvi_wifi off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end device pci 14.7 alias cnvi_bluetooth off end device pci 14.5 alias ieh off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 16.0 alias heci1 on end device pci 16.1 alias heci2 off end device pci 16.4 alias heci3 off end @@ -226,26 +226,26 @@ chip soc/intel/pantherlake device pci 18.0 alias eheci1 off end device pci 18.1 alias eheci2 off end device pci 18.2 alias eheci3 off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end - device pci 19.2 alias uart2 off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1c.4 alias pcie_rp5 off end - device pci 1c.5 alias pcie_rp6 off end - device pci 1c.6 alias pcie_rp7 off end - device pci 1c.7 alias pcie_rp8 off end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end + device pci 19.2 alias uart2 off ops uart_ops end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1f.0 alias soc_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.3 alias hda off ops hda_ops end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias npk off end diff --git a/src/soc/intel/pantherlake/chipset_wcl.cb b/src/soc/intel/pantherlake/chipset_wcl.cb index 31abe5be944..ed32d4826d6 100644 --- a/src/soc/intel/pantherlake/chipset_wcl.cb +++ b/src/soc/intel/pantherlake/chipset_wcl.cb @@ -8,6 +8,13 @@ chip soc/intel/pantherlake .tdp_pl4 = 93, }" + register "icc_max[WCL_SKU_1]" = "{ + [VR_DOMAIN_GT] = 36 * 4, + }" + + register "tdc_mode[VR_DOMAIN_IA]" = "TDC_IRMS" + register "tdc_time_window_ms[VR_DOMAIN_IA]" = "28000" + # Reduce the size of BasicMemoryTests to speed up the boot time. register "lower_basic_mem_test_size" = "true" @@ -20,8 +27,8 @@ chip soc/intel/pantherlake device pci 00.0 alias system_agent on end device pci 02.0 alias igpu on end device pci 04.0 alias dtt off end - device pci 06.0 alias pcie_rp5 off end - device pci 06.1 alias pcie_rp6 off end + device pci 06.0 alias pcie_rp5 off ops pcie_rp_ops end + device pci 06.1 alias pcie_rp6 off ops pcie_rp_ops end device pci 07.0 alias tbt_pcie_rp0 off chip soc/intel/common/block/usb4 use tcss_dma0 as usb4_port @@ -56,11 +63,11 @@ chip soc/intel/pantherlake device pci 10.1 alias thc1 off end device pci 12.0 alias ish off end device pci 12.1 alias p2sb2 hidden end - device pci 12.6 alias gspi0a off end + device pci 12.6 alias gspi0a off ops spi_dev_ops end device pci 13.0 alias heci_1 off end device pci 13.1 alias heci_2 off end device pci 13.2 alias heci_3 off end - device pci 14.0 alias xhci on + device pci 14.0 alias xhci on ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off @@ -98,13 +105,13 @@ chip soc/intel/pantherlake end end device pci 14.2 alias pmc_shared_sram off end - device pci 14.3 alias cnvi_wifi off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end device pci 14.7 alias cnvi_bluetooth off end device pci 14.5 alias ieh off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 16.0 alias heci1 on end device pci 16.1 alias heci2 off end device pci 16.4 alias heci3 off end @@ -113,22 +120,22 @@ chip soc/intel/pantherlake device pci 18.0 alias eheci1 off end device pci 18.1 alias eheci2 off end device pci 18.2 alias eheci3 off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end - device pci 19.2 alias uart2 off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end + device pci 19.2 alias uart2 off ops uart_ops end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1f.0 alias soc_espi on end device pci 1f.1 alias p2sb hidden end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.3 alias hda off ops hda_ops end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias npk off end diff --git a/src/soc/intel/pantherlake/cpu.c b/src/soc/intel/pantherlake/cpu.c index f8215077490..40b216d697e 100644 --- a/src/soc/intel/pantherlake/cpu.c +++ b/src/soc/intel/pantherlake/cpu.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -141,7 +142,7 @@ void soc_core_init(struct device *cpu) /* Set core type in struct cpu_info */ set_dev_core_type(); - if (CONFIG(INTEL_TME) && is_tme_supported()) + if (get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported()) set_tme_core_activate(); if (CONFIG(DROP_CPU_FEATURE_PROGRAM_IN_FSP)) { diff --git a/src/soc/intel/pantherlake/espi.c b/src/soc/intel/pantherlake/espi.c deleted file mode 100644 index d5b5cf93c9d..00000000000 --- a/src/soc/intel/pantherlake/espi.c +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]) -{ - const struct soc_intel_pantherlake_config *config = config_of_soc(); - - gen_io_dec[0] = config->gen1_dec; - gen_io_dec[1] = config->gen2_dec; - gen_io_dec[2] = config->gen3_dec; - gen_io_dec[3] = config->gen4_dec; -} - -void lpc_soc_init(struct device *dev) -{ - /* Legacy initialization */ - isa_dma_init(); - pch_misc_init(); - - /* Enable CLKRUN_EN for power gating ESPI */ - lpc_enable_pci_clk_cntl(); - - /* Set ESPI Serial IRQ mode */ - if (CONFIG(SERIRQ_CONTINUOUS_MODE)) - lpc_set_serirq_mode(SERIRQ_CONTINUOUS); - else - lpc_set_serirq_mode(SERIRQ_QUIET); - - /* Interrupt configuration */ - pch_enable_ioapic(); - pch_pirq_init(); - setup_i8259(); - i8259_configure_irq_trigger(9, 1); -} diff --git a/src/soc/intel/pantherlake/finalize.c b/src/soc/intel/pantherlake/finalize.c deleted file mode 100644 index 05ec3eaaca9..00000000000 --- a/src/soc/intel/pantherlake/finalize.c +++ /dev/null @@ -1,82 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void pch_finalize(void) -{ - /* TCO Lock down */ - tco_lockdown(); - - pmc_clear_pmcon_sts(); -} - -static void tbt_finalize(void) -{ - int i; - const struct device *dev; - - /* Disable Thunderbolt PCIe root ports bus master */ - for (i = 0; i < NUM_TBT_FUNCTIONS; i++) { - dev = pcidev_path_on_root(PCI_DEVFN_TBT(i)); - if (dev) - pci_dev_disable_bus_master(dev); - } -} - -static void sa_finalize(void) -{ - if (get_lockdown_config() == CHIPSET_LOCKDOWN_COREBOOT) - sa_lock_pam(); -} - -static void heci_finalize(void) -{ - heci_set_to_d0i3(); - if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT)) - heci1_disable(); -} - -static void soc_finalize(void *unused) -{ - printk(BIOS_DEBUG, "Finalizing chipset.\n"); - - pch_finalize(); - apm_control(APM_CNT_FINALIZE); - tbt_finalize(); - sa_finalize(); - if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && - CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE)) - heci_finalize(); - - /* Indicate finalize step with post code */ - post_code(POSTCODE_OS_BOOT); -} - -BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL); -/* - * The purpose of this change is to accommodate more time to push out sending - * CSE EOP messages at post. - */ -BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, soc_finalize, NULL); diff --git a/src/soc/intel/pantherlake/fsp_params.c b/src/soc/intel/pantherlake/fsp_params.c index 0133e72c00e..226ae1677ab 100644 --- a/src/soc/intel/pantherlake/fsp_params.c +++ b/src/soc/intel/pantherlake/fsp_params.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -59,47 +60,6 @@ static const pci_devfn_t gspi_dev[] = { PCI_DEVFN_GSPI2 }; -/* - * Chip config parameter PcieRpL1Substates uses (UPD value + 1) - * because UPD value of 0 for PcieRpL1Substates means disabled for FSP. - * In order to ensure that mainboard setting does not disable L1 substates - * incorrectly, chip config parameter values are offset by 1 with 0 meaning - * use FSP UPD default. get_l1_substate_control() ensures that the right UPD - * value is set in fsp_params. - * 0: Use FSP UPD default - * 1: Disable L1 substates - * 2: Use L1.1 - * 3: Use L1.2 (FSP UPD default) - */ -static int get_l1_substate_control(enum L1_substates_control ctl) -{ - if (CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE)) - ctl = L1_SS_DISABLED; - else if (ctl > L1_SS_L1_2 || ctl == L1_SS_FSP_DEFAULT) - ctl = L1_SS_L1_2; - return ctl - 1; -} - -/* - * Chip config parameter pcie_rp_aspm uses (UPD value + 1) because - * a UPD value of 0 for pcie_rp_aspm means disabled. In order to ensure - * that the mainboard setting does not disable ASPM incorrectly, chip - * config parameter values are offset by 1 with 0 meaning use FSP UPD default. - * get_aspm_control() ensures that the right UPD value is set in fsp_params. - * 0: Use FSP UPD default - * 1: Disable ASPM - * 2: L0s only - * 3: L1 only - * 4: L0s and L1 - * 5: Auto configuration - */ -static unsigned int get_aspm_control(enum ASPM_control ctl) -{ - if (ctl > ASPM_AUTO || ctl == ASPM_DEFAULT) - ctl = ASPM_AUTO; - return ctl - 1; -} - __weak void mainboard_update_soc_chip_config(struct soc_intel_pantherlake_config *config) { /* Override settings per board. */ @@ -629,18 +589,20 @@ static void fill_fsps_pcie_params(FSP_S_CONFIG *s_cfg, uint32_t enable_mask = pcie_rp_enable_mask(get_pcie_rp_table()); for (size_t i = 0; i < CONFIG_MAX_ROOT_PORTS; i++) { - const struct pcie_rp_config *rp_cfg = &config->pcie_rp[i]; + if (CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE)) { + s_cfg->PcieClockGating[i] = 0; + s_cfg->PciePowerGating[i] = 0; + } if (!(enable_mask & BIT(i))) continue; - s_cfg->PcieRpL1Substates[i] = - get_l1_substate_control(rp_cfg->PcieRpL1Substates); + const struct pcie_rp_config *rp_cfg = &config->pcie_rp[i]; s_cfg->PcieRpLtrEnable[i] = !!(rp_cfg->flags & PCIE_RP_LTR); s_cfg->PcieRpAdvancedErrorReporting[i] = !!(rp_cfg->flags & PCIE_RP_AER); s_cfg->PcieRpHotPlug[i] = !!(rp_cfg->flags & PCIE_RP_HOTPLUG) || CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE); s_cfg->PcieRpClkReqDetect[i] = !!(rp_cfg->flags & PCIE_RP_CLK_REQ_DETECT); - if (rp_cfg->pcie_rp_aspm) - s_cfg->PcieRpAspm[i] = get_aspm_control(rp_cfg->pcie_rp_aspm); + s_cfg->PcieRpDetectTimeoutMs[i] = rp_cfg->pcie_rp_detect_timeout_ms; + configure_pch_rp_power_management(s_cfg, rp_cfg, i); } s_cfg->PcieComplianceTestMode = CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE); diff --git a/src/soc/intel/pantherlake/gspi.c b/src/soc/intel/pantherlake/gspi.c deleted file mode 100644 index 387d3e3949b..00000000000 --- a/src/soc/intel/pantherlake/gspi.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCI_DEVFN_GSPI0; - case 1: - return PCI_DEVFN_GSPI1; - case 2: - return PCI_DEVFN_GSPI2; - } - return -1; -} diff --git a/src/soc/intel/pantherlake/i2c.c b/src/soc/intel/pantherlake/i2c.c deleted file mode 100644 index 50ab4a73eb4..00000000000 --- a/src/soc/intel/pantherlake/i2c.c +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCI_DEVFN_I2C0: - return 0; - case PCI_DEVFN_I2C1: - return 1; - case PCI_DEVFN_I2C2: - return 2; - case PCI_DEVFN_I2C3: - return 3; - case PCI_DEVFN_I2C4: - return 4; - case PCI_DEVFN_I2C5: - return 5; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCI_DEVFN_I2C0; - case 1: - return PCI_DEVFN_I2C1; - case 2: - return PCI_DEVFN_I2C2; - case 3: - return PCI_DEVFN_I2C3; - case 4: - return PCI_DEVFN_I2C4; - case 5: - return PCI_DEVFN_I2C5; - } - return -1; -} diff --git a/src/soc/intel/pantherlake/include/soc/meminit.h b/src/soc/intel/pantherlake/include/soc/meminit.h index 63404f8c170..d9506500ef3 100644 --- a/src/soc/intel/pantherlake/include/soc/meminit.h +++ b/src/soc/intel/pantherlake/include/soc/meminit.h @@ -3,6 +3,7 @@ #ifndef _SOC_PANTHERLAKE_MEMINIT_H_ #define _SOC_PANTHERLAKE_MEMINIT_H_ +#include #include #include #include diff --git a/src/soc/intel/pantherlake/include/soc/pci_devs.h b/src/soc/intel/pantherlake/include/soc/pci_devs.h index 25468ab39ab..1834dec9a5a 100644 --- a/src/soc/intel/pantherlake/include/soc/pci_devs.h +++ b/src/soc/intel/pantherlake/include/soc/pci_devs.h @@ -256,5 +256,8 @@ #define SA_DEVFN_TCSS_DMA1 PCI_DEVFN_TCSS_DMA1 #define SA_DEV_IGD PCI_DEV_IGD #define SA_DEVFN_IGD PCI_DEVFN_IGD +#define SOC_I2C_DEVFN(n) PCI_DEVFN_I2C##n +#define SOC_GSPI_DEVFN(n) PCI_DEVFN_GSPI##n +#define SOC_PMC_DEV PCI_DEV_PMC #endif // _SOC_PANTHERLAKE_PCI_DEVS_H_ diff --git a/src/soc/intel/pantherlake/include/soc/pmc.h b/src/soc/intel/pantherlake/include/soc/pmc.h index 415bf074fbe..bf0f6b59783 100644 --- a/src/soc/intel/pantherlake/include/soc/pmc.h +++ b/src/soc/intel/pantherlake/include/soc/pmc.h @@ -62,6 +62,9 @@ extern struct device_operations pmc_ops; #define SMI_LOCK BIT(4) #define RTC_BATTERY_DEAD BIT(2) +/* PMC lockdown configuration register for ST_FDIS_LOCK */ +#define PMC_FDIS_LOCK_REG GEN_PMCON_B + /* Extended Test Mode Register */ #define ETR 0x1048 #define CF9_LOCK BIT(31) diff --git a/src/soc/intel/pantherlake/lockdown.c b/src/soc/intel/pantherlake/lockdown.c deleted file mode 100644 index 2994952d00a..00000000000 --- a/src/soc/intel/pantherlake/lockdown.c +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* PCR PSTH Control Register */ -#define PCR_PSTH_CTRLREG 0x1d00 -#define PSTH_CTRLREG_IOSFPTCGE BIT(2) - -static void pmc_lockdown_cfg(int chipset_lockdown) -{ - uint8_t *pmcbase = pmc_mmio_regs(); - - /* PMSYNC */ - setbits32(pmcbase + PMSYNC_TPR_CFG, PCH2CPU_TPR_CFG_LOCK); - /* Lock down ABASE and sleep stretching policy */ - setbits32(pmcbase + GEN_PMCON_B, SLP_STR_POL_LOCK | ACPI_BASE_LOCK); - - if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) - setbits32(pmcbase + GEN_PMCON_B, SMI_LOCK); - - if (!CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM)) { - setbits32(pmcbase + GEN_PMCON_B, ST_FDIS_LOCK); - setbits32(pmcbase + SSML, SSML_SSL_EN); - setbits32(pmcbase + PM_CFG, PM_CFG_DBG_MODE_LOCK | - PM_CFG_XRAM_READ_DISABLE); - } - - /* Send PMC IPC to inform about both BIOS Reset and PCI enumeration done */ - pmc_send_bios_reset_pci_enum_done(); -} - -static void soc_die_lockdown_cfg(void) -{ - if (CONFIG(USE_FSP_NOTIFY_PHASE_POST_PCI_ENUM)) - return; - - /* Enable IOSF Primary Trunk Clock Gating */ - pcr_rmw32(PID_PSTH, PCR_PSTH_CTRLREG, ~0, PSTH_CTRLREG_IOSFPTCGE); -} - -void soc_lockdown_config(int chipset_lockdown) -{ - /* PMC lock down configuration */ - pmc_lockdown_cfg(chipset_lockdown); - /* SOC Die lock down configuration */ - soc_die_lockdown_cfg(); -} diff --git a/src/soc/intel/pantherlake/meminit.c b/src/soc/intel/pantherlake/meminit.c index eef4adf5f0c..894ec30643a 100644 --- a/src/soc/intel/pantherlake/meminit.c +++ b/src/soc/intel/pantherlake/meminit.c @@ -35,18 +35,16 @@ static const struct soc_mem_cfg soc_mem_cfg[] = { .num_phys_channels = DDR5_CHANNELS, .phys_to_mrc_map = { [0] = 0, - [1] = 1, - [2] = 4, - [3] = 5, + [1] = 4, }, .md_phy_masks = { /* - * Physical channels 0 and 1 are populated in case of - * half-populated configurations. + * Only channel 0 is populated in case of half-populated + * configuration. */ - .half_channel = BIT(0) | BIT(1), - /* In mixed topology, channels 2 and 3 are always memory-down. */ - .mixed_topo = BIT(2) | BIT(3), + .half_channel = BIT(0), + /* In mixed topologies, either channel 0 or 1 can be memory-down. */ + .mixed_topo = BIT(0) | BIT(1), }, }, [MEM_TYPE_LP5X] = { @@ -72,7 +70,8 @@ static const struct soc_mem_cfg soc_mem_cfg[] = { }, }; -static void mem_init_spd_upds(FSP_M_CONFIG *mem_cfg, const struct mem_channel_data *data) +static void mem_init_spd_upds(FSP_M_CONFIG *mem_cfg, const struct mem_channel_data *data, + bool expand_channels) { uint64_t *spd_upds[MRC_CHANNELS][CONFIG_DIMMS_PER_CHANNEL] = { [0] = { &mem_cfg->MemorySpdPtr000, &mem_cfg->MemorySpdPtr001, }, @@ -105,7 +104,19 @@ static void mem_init_spd_upds(FSP_M_CONFIG *mem_cfg, const struct mem_channel_da for (dimm = 0; dimm < CONFIG_DIMMS_PER_CHANNEL; dimm++) { uint64_t *spd_ptr = spd_upds[ch][dimm]; - *spd_ptr = data->spd[ch][dimm]; + /* + * In DDR5 systems, since each DIMM has 2 channels, + * we need to copy the SPD data such that: + * Channel 0 data is used by channel 0 and 1 + * Channel 2 data is used by channel 2 and 3 + * Channel 4 data is used by channel 4 and 5 + * Channel 6 data is used by channel 6 and 7 + */ + if (expand_channels) + *spd_ptr = data->spd[ch & ~1][dimm]; + else + *spd_ptr = data->spd[ch][dimm]; + if (*spd_ptr) enable_channel = 1; } @@ -186,6 +197,7 @@ void memcfg_init(FSPM_UPD *memupd, const struct mb_cfg *mb_cfg, { struct mem_channel_data data; bool dq_dqs_auto_detect = false; + bool expand_channels = false; FSP_M_CONFIG *mem_cfg = &memupd->FspmConfig; mem_cfg->ECT = mb_cfg->ect; @@ -197,16 +209,7 @@ void memcfg_init(FSPM_UPD *memupd, const struct mb_cfg *mb_cfg, printk(BIOS_DEBUG, "%s: module type is DDR5\n", __func__); meminit_ddr(mem_cfg, &mb_cfg->ddr_config); dq_dqs_auto_detect = true; - /* - * TODO: Drop this workaround once SMBus driver in coreboot is - * updated to support DDR5 EEPROM reading. - */ - if (spd_info->topo == MEM_TOPO_DIMM_MODULE) { - fill_dimm_module_info(mem_cfg, mb_cfg, spd_info); - mem_init_dq_upds(mem_cfg, NULL, mb_cfg, true); - mem_init_dqs_upds(mem_cfg, NULL, mb_cfg, true); - return; - } + expand_channels = true; break; case MEM_TYPE_LP5X: meminit_lp5x(mem_cfg, &mb_cfg->lp5x_config); @@ -220,7 +223,7 @@ void memcfg_init(FSPM_UPD *memupd, const struct mb_cfg *mb_cfg, mem_populate_channel_data(memupd, &soc_mem_cfg[mb_cfg->type], spd_info, half_populated, &data); - mem_init_spd_upds(mem_cfg, &data); + mem_init_spd_upds(mem_cfg, &data, expand_channels); mem_init_dq_upds(mem_cfg, &data, mb_cfg, dq_dqs_auto_detect); mem_init_dqs_upds(mem_cfg, &data, mb_cfg, dq_dqs_auto_detect); } diff --git a/src/soc/intel/pantherlake/reset.c b/src/soc/intel/pantherlake/reset.c deleted file mode 100644 index 3c13f6dfe56..00000000000 --- a/src/soc/intel/pantherlake/reset.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -void do_global_reset(void) -{ - /* Ask CSE to do the global reset */ - if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) - return; - - /* global reset if CSE fail to reset */ - pmc_global_reset_enable(1); - do_full_reset(); -} diff --git a/src/soc/intel/pantherlake/romstage/fsp_params.c b/src/soc/intel/pantherlake/romstage/fsp_params.c index 63a3f3b013c..5e652da1874 100644 --- a/src/soc/intel/pantherlake/romstage/fsp_params.c +++ b/src/soc/intel/pantherlake/romstage/fsp_params.c @@ -10,10 +10,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include "ux.h" @@ -39,8 +41,8 @@ static void fill_fspm_igd_params(FSP_M_CONFIG *m_cfg, }; m_cfg->InternalGraphics = !CONFIG(SOC_INTEL_DISABLE_IGD) && is_devfn_enabled(PCI_DEVFN_IGD); if (m_cfg->InternalGraphics) { - /* IGD is enabled, set IGD stolen size to 64MB. */ - m_cfg->IgdDvmt50PreAlloc = IGD_SM_64MB; + /* IGD is enabled, set IGD stolen size to 128MB. */ + m_cfg->IgdDvmt50PreAlloc = IGD_SM_128MB; /* DP port config */ m_cfg->DdiPortAConfig = config->ddi_port_A_config; m_cfg->DdiPortBConfig = config->ddi_port_B_config; @@ -111,7 +113,7 @@ static void fill_fspm_cpu_params(FSP_M_CONFIG *m_cfg, static void fill_tme_params(FSP_M_CONFIG *m_cfg) { - m_cfg->TmeEnable = CONFIG(INTEL_TME) && is_tme_supported(); + m_cfg->TmeEnable = get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported(); if (!m_cfg->TmeEnable || acpi_is_wakeup_s3()) return; m_cfg->GenerateNewTmeKey = CONFIG(TME_KEY_REGENERATION_ON_WARM_BOOT); @@ -311,6 +313,7 @@ static void fill_fspm_thermal_params(FSP_M_CONFIG *m_cfg, const struct soc_intel_pantherlake_config *config) { m_cfg->TccActivationOffset = config->tcc_offset; + m_cfg->TccOffsetLock = 0; } static const struct soc_intel_pantherlake_power_map *get_map(const struct soc_intel_pantherlake_config *config) @@ -321,7 +324,7 @@ static const struct soc_intel_pantherlake_power_map *get_map(const struct soc_in return NULL; } - uint8_t tdp = get_cpu_tdp(); + enum soc_intel_pantherlake_cpu_tdps tdp = soc_get_cpu_tdp(); for (size_t i = 0; i < ARRAY_SIZE(cpuid_to_ptl); i++) { const struct soc_intel_pantherlake_power_map *current = &cpuid_to_ptl[i]; if (current->cpu_id == sa_pci_id && current->cpu_tdp == tdp) @@ -345,7 +348,7 @@ static void fill_fspm_vr_config_params(FSP_M_CONFIG *m_cfg, m_cfg->CepEnable[i] = config->cep_enable[i]; if (config->enable_fast_vmode[i]) { m_cfg->EnableFastVmode[i] = config->enable_fast_vmode[i]; - m_cfg->IccLimit[i] = config->fast_vmode_i_trip[map->limits][i]; + m_cfg->IccLimit[i] = config->fast_vmode_i_trip[map->sku][i]; } } @@ -363,8 +366,10 @@ static void fill_fspm_vr_config_params(FSP_M_CONFIG *m_cfg, } for (size_t i = 0; i < ARRAY_SIZE(config->tdc_mode); i++) { - m_cfg->TdcMode[i] = config->tdc_mode[i]; - m_cfg->TdcTimeWindow[i] = config->tdc_time_window_ms[i]; + if (config->tdc_mode[i]) + m_cfg->TdcMode[i] = config->tdc_mode[i]; + if (config->tdc_time_window_ms[i]) + m_cfg->TdcTimeWindow[i] = config->tdc_time_window_ms[i]; } for (size_t i = 0; i < ARRAY_SIZE(config->ps1_threshold); i++) { diff --git a/src/soc/intel/pantherlake/romstage/ux.c b/src/soc/intel/pantherlake/romstage/ux.c index e0a84257dc0..4f9519b6e85 100644 --- a/src/soc/intel/pantherlake/romstage/ux.c +++ b/src/soc/intel/pantherlake/romstage/ux.c @@ -50,6 +50,17 @@ static void setup_vga_mode12_params(FSP_M_CONFIG *m_cfg, enum ux_locale_msg id) m_cfg->VgaInitControl |= VGA_INIT_CONTROL_MODE12_MONOCHROME; } +static void set_cd_clock(FSP_M_CONFIG *m_cfg, enum cd_clock clk) +{ + if (clk > MAX_CD_CLOCK) { + printk(BIOS_ERR, "CD Clock setting out of bounds!\n"); + return; + } + + m_cfg->VgaInitControl = (m_cfg->VgaInitControl & ~(0x3 << 6)) | (clk << 6); + printk(BIOS_DEBUG, "CD Clock: %d\n", clk); +} + static bool ux_inform_user_of_operation(const char *name, enum ux_locale_msg id, FSPM_UPD *mupd) { @@ -90,6 +101,9 @@ static bool ux_inform_user_of_operation(const char *name, enum ux_locale_msg id, m_cfg->VgaInitControl = VGA_INIT_CONTROL_ENABLE; if (config->disable_progress_bar) m_cfg->VgaInitControl |= VGA_INIT_DISABLE_ANIMATION; + + set_cd_clock(m_cfg, config->vga_cd_clk_freq_sel); + m_cfg->VbtPtr = (efi_uintn_t)vbt; m_cfg->VbtSize = vbt_size; m_cfg->LidStatus = CONFIG(VBOOT_LID_SWITCH) ? get_lid_switch() : CONFIG(RUN_FSP_GOP); diff --git a/src/soc/intel/pantherlake/smihandler.c b/src/soc/intel/pantherlake/smihandler.c deleted file mode 100644 index 6a21f0a757c..00000000000 --- a/src/soc/intel/pantherlake/smihandler.c +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include - -int smihandler_soc_disable_busmaster(pci_devfn_t dev) -{ - /* Skip disabling PMC bus master to keep IO decode enabled */ - if (dev == PCI_DEV_PMC) - return 0; - return 1; -} - -const smi_handler_t southbridge_smi[SMI_STS_BITS] = { - [SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep, - [APM_STS_BIT] = smihandler_southbridge_apmc, - [PM1_STS_BIT] = smihandler_southbridge_pm1, - [GPE0_STS_BIT] = smihandler_southbridge_gpe0, - [GPIO_STS_BIT] = smihandler_southbridge_gpi, - [ESPI_SMI_STS_BIT] = smihandler_southbridge_espi, - [MCSMI_STS_BIT] = smihandler_southbridge_mc, -#if CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE) - [TCO_STS_BIT] = smihandler_southbridge_tco, -#endif - [PERIODIC_STS_BIT] = smihandler_southbridge_periodic, - [MONITOR_STS_BIT] = smihandler_southbridge_monitor, -}; diff --git a/src/soc/intel/pantherlake/soundwire.c b/src/soc/intel/pantherlake/soundwire.c deleted file mode 100644 index ab1d0bc683f..00000000000 --- a/src/soc/intel/pantherlake/soundwire.c +++ /dev/null @@ -1,72 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static const struct soundwire_link link_xtal_38_4 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 4800 * KHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 50, - .default_frame_col_size = 4, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static const struct soundwire_link link_xtal_24 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 6 * MHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 125, - .default_frame_col_size = 2, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static struct intel_soundwire_controller intel_controller = { - .acpi_address = 0x40000000, /* Custom address for SNDW driver */ - .sdw = { - .master_list_count = 4 - } -}; - -int soc_fill_soundwire_controller(struct intel_soundwire_controller **controller) -{ - const struct soundwire_link *link; - enum pch_pmc_xtal xtal = pmc_get_xtal_freq(); - size_t i; - - /* Select link config based on XTAL frequency and set IP clock. */ - switch (xtal) { - case XTAL_24_MHZ: - link = &link_xtal_24; - intel_controller.ip_clock = 24 * MHz; - break; - case XTAL_38_4_MHZ: - link = &link_xtal_38_4; - intel_controller.ip_clock = 38400 * KHz; - break; - case XTAL_19_2_MHZ: - default: - printk(BIOS_ERR, "%s: XTAL not supported: 0x%x\n", __func__, xtal); - return -1; - } - - /* Fill link config in controller map based on selected XTAL. */ - for (i = 0; i < intel_controller.sdw.master_list_count; i++) - memcpy(&intel_controller.sdw.master_list[i], link, sizeof(*link)); - - *controller = &intel_controller; - return 0; -} diff --git a/src/soc/intel/pantherlake/spi.c b/src/soc/intel/pantherlake/spi.c deleted file mode 100644 index f7d751f98eb..00000000000 --- a/src/soc/intel/pantherlake/spi.c +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include -#include - -#define PSF_SPI_DESTINATION_ID 0x5140 - -int spi_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCI_DEVFN_GSPI0: - return 1; - case PCI_DEVFN_GSPI1: - return 2; - case PCI_DEVFN_GSPI2: - return 3; - } - return -1; -} - -uint32_t soc_get_spi_psf_destination_id(void) -{ - return PSF_SPI_DESTINATION_ID; -} diff --git a/src/soc/intel/pantherlake/systemagent.c b/src/soc/intel/pantherlake/systemagent.c index 82e5d244c71..f88aedb95c1 100644 --- a/src/soc/intel/pantherlake/systemagent.c +++ b/src/soc/intel/pantherlake/systemagent.c @@ -16,6 +16,7 @@ #include #include #include +#include /* * SoC implementation @@ -104,7 +105,7 @@ void soc_add_configurable_mmio_resources(struct device *dev, int *resource_cnt) } /* TSEG */ - size = sa_get_tseg_size(); + size = CONFIG_SMM_TSEG_SIZE; tseg_base = sa_get_tseg_base(); if (size > 0) set_mmio_resource(&(cfg_rsrc[count++]), tseg_base, size, "TSEG"); @@ -145,7 +146,7 @@ static void configure_tdp(struct device *dev) struct soc_power_limits_config *soc_config; struct device *sa; uint16_t sa_pci_id; - u8 tdp; + enum soc_intel_pantherlake_cpu_tdps tdp; size_t i; bool config_tdp = false; struct soc_intel_pantherlake_config *config; @@ -161,7 +162,7 @@ static void configure_tdp(struct device *dev) return; } - tdp = get_cpu_tdp(); + tdp = soc_get_cpu_tdp(); /* * Choose power limits configuration based on the CPU SA PCI ID and @@ -174,6 +175,7 @@ static void configure_tdp(struct device *dev) if (config->enable_fast_vmode[VR_DOMAIN_IA] && soc_config->tdp_pl4_fastvmode) soc_config->tdp_pl4 = soc_config->tdp_pl4_fastvmode; + soc_config->tdp_pl1_override = tdp; set_power_limits(MOBILE_SKU_PL1_TIME_SEC, soc_config); config_tdp = true; printk(BIOS_DEBUG, "Configured power limits for SA PCI ID: 0x%4x\n", diff --git a/src/soc/intel/pantherlake/tdp.c b/src/soc/intel/pantherlake/tdp.c new file mode 100644 index 00000000000..30b03366fed --- /dev/null +++ b/src/soc/intel/pantherlake/tdp.c @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +enum soc_intel_pantherlake_cpu_tdps soc_get_cpu_tdp(void) +{ + if (CONFIG(MAINBOARD_HAS_CHROMEOS)) { + const unsigned int variable_tdp_mch_ids[] = { + PCI_DID_INTEL_PTL_U_ID_1, + PCI_DID_INTEL_PTL_U_ID_2, + PCI_DID_INTEL_PTL_U_ID_3 + }; + uint16_t mch_id = pci_read_config16(_PCI_DEV(ROOT, 0), PCI_DEVICE_ID); + + for (size_t i = 0; i < ARRAY_SIZE(variable_tdp_mch_ids); i++) + if (variable_tdp_mch_ids[i] == mch_id) + return TDP_15W; + } + + const struct soc_intel_pantherlake_config *config = config_of_soc(); + return config->tdp ? : get_cpu_tdp(); +} diff --git a/src/soc/intel/pantherlake/tdp.h b/src/soc/intel/pantherlake/tdp.h new file mode 100644 index 00000000000..46f5188a245 --- /dev/null +++ b/src/soc/intel/pantherlake/tdp.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_PANTHERLAKE_TDP_H_ +#define _SOC_PANTHERLAKE_TDP_H_ + +#include + +enum soc_intel_pantherlake_cpu_tdps soc_get_cpu_tdp(void); + +#endif /* _SOC_PANTHERLAKE_TDP_H_ */ diff --git a/src/soc/intel/pantherlake/uart.c b/src/soc/intel/pantherlake/uart.c deleted file mode 100644 index 9f549c5ae8c..00000000000 --- a/src/soc/intel/pantherlake/uart.c +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -const unsigned int uart_devices[] = { - PCI_DEVFN_UART0, - PCI_DEVFN_UART1, - PCI_DEVFN_UART2, -}; - -const int uart_devices_size = ARRAY_SIZE(uart_devices); diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig index 7c530f2c75f..e0d2c4d2220 100644 --- a/src/soc/intel/skylake/Kconfig +++ b/src/soc/intel/skylake/Kconfig @@ -58,6 +58,10 @@ config SOC_INTEL_COMMON_SKYLAKE_BASE select SOC_INTEL_COMMON_BLOCK_THERMAL_PCI_DEV select SOC_INTEL_COMMON_BLOCK_UART select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_NHLT diff --git a/src/soc/intel/skylake/Makefile.mk b/src/soc/intel/skylake/Makefile.mk index 04ba96b7dd0..73479d95bcb 100644 --- a/src/soc/intel/skylake/Makefile.mk +++ b/src/soc/intel/skylake/Makefile.mk @@ -8,33 +8,24 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo bootblock-y += bootblock/bootblock.c -bootblock-y += i2c.c bootblock-y += bootblock/pch.c bootblock-y += bootblock/report_platform.c bootblock-y += gpio.c -bootblock-y += gspi.c bootblock-y += p2sb.c bootblock-y += pmutil.c bootblock-y += spi.c bootblock-y += lpc.c -bootblock-y += uart.c verstage-y += gpio.c -verstage-y += gspi.c verstage-y += pmutil.c -verstage-y += i2c.c verstage-y += spi.c -verstage-y += uart.c romstage-y += gpio.c -romstage-y += gspi.c -romstage-y += i2c.c romstage-y += me.c romstage-y += pcie_rp.c romstage-y += pmutil.c romstage-y += reset.c romstage-y += spi.c -romstage-y += uart.c ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c ramstage-y += chip.c @@ -43,8 +34,6 @@ ramstage-y += elog.c ramstage-y += fadt.c ramstage-y += finalize.c ramstage-y += gpio.c -ramstage-y += gspi.c -ramstage-y += i2c.c ramstage-y += graphics.c ramstage-y += irq.c ramstage-y += lockdown.c @@ -58,7 +47,6 @@ ramstage-y += reset.c ramstage-y += sd.c ramstage-y += spi.c ramstage-y += systemagent.c -ramstage-y += uart.c ramstage-y += vr_config.c ramstage-y += xhci.c @@ -67,13 +55,9 @@ smm-y += gpio.c smm-y += p2sb.c smm-y += pmutil.c smm-y += smihandler.c -smm-y += uart.c smm-y += xhci.c -postcar-y += gspi.c postcar-y += spi.c -postcar-y += i2c.c -postcar-y += uart.c ifeq ($(CONFIG_SKYLAKE_SOC_PCH_H),y) ifeq ($(CONFIG_MAINBOARD_SUPPORTS_SKYLAKE_CPU),y) diff --git a/src/soc/intel/skylake/acpi/xhci.asl b/src/soc/intel/skylake/acpi/xhci.asl index bfe6c6df773..5ce7b0d809e 100644 --- a/src/soc/intel/skylake/acpi/xhci.asl +++ b/src/soc/intel/skylake/acpi/xhci.asl @@ -159,23 +159,19 @@ Device (XHCI) Name (_ADR, 0) // GPLD: Generate Port Location Data (PLD) - Method (GPLD, 1, Serialized) - { - - Name (PCKG, Package (0x01) - { + Method (GPLD, 1, Serialized) { + Local0 = Package () { Buffer (0x10) {} - }) + } - // REV: Revision 0x02 for ACPI 5.0 - CreateField (DerefOf (PCKG[0]), 0, 0x07, REV) - REV = 0x02 + // REV: Revision 2 for ACPI 5.0 + CreateField (DerefOf (Local0[0]), 0, 7, REV) + REV = 2 // VISI: Port visibility to user per port - CreateField (DerefOf (PCKG[0]), 0x40, 1, VISI) + CreateField (DerefOf (Local0[0]), 0x40, 1, VISI) VISI = Arg0 - - Return (PCKG) + Return (Local0) } /* USB2 */ diff --git a/src/soc/intel/skylake/chip.c b/src/soc/intel/skylake/chip.c index 0061c10ae81..a884035f596 100644 --- a/src/soc/intel/skylake/chip.c +++ b/src/soc/intel/skylake/chip.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -491,7 +492,18 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) /* Enable VT-d and X2APIC */ if (soc_vtd_enabled()) { - params->VtdBaseAddress[0] = GFXVT_BASE_ADDRESS; + /* + * Probe for no IGD and set VtdBaseAddress accordingly to prevent a + * crash in FSP-S. + */ + const struct device *igd_dev = pcidev_path_on_root(SA_DEVFN_IGD); + if (igd_dev && pci_read_config16(igd_dev, PCI_VENDOR_ID) != 0xffff) { + printk(BIOS_DEBUG, "iGPU present - GFXVT_BASE_ADDRESS set\n"); + params->VtdBaseAddress[0] = GFXVT_BASE_ADDRESS; + } else { + printk(BIOS_DEBUG, "No iGPU - GFXVT_BASE_ADDRESS disabled\n"); + params->VtdBaseAddress[0] = 0; + } params->VtdBaseAddress[1] = VTVC0_BASE_ADDRESS; params->X2ApicOptOut = 0; tconfig->VtdDisable = 0; diff --git a/src/soc/intel/skylake/gpio.c b/src/soc/intel/skylake/gpio.c index 50628a7d982..00099794d82 100644 --- a/src/soc/intel/skylake/gpio.c +++ b/src/soc/intel/skylake/gpio.c @@ -57,6 +57,7 @@ static const struct pad_community skl_gpio_communities[] = { .last_pad = GPP_B23, .num_gpi_regs = NUM_GPIO_COM0_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, + .pad_cfg_lock_offset = PAD_CFG_LOCK_OFFSET_COM0, .host_own_reg_0 = HOSTSW_OWN_REG_0, .gpi_int_sts_reg_0 = GPI_INT_STS_0, .gpi_int_en_reg_0 = GPI_INT_EN_0, @@ -81,6 +82,7 @@ static const struct pad_community skl_gpio_communities[] = { #endif .num_gpi_regs = NUM_GPIO_COM1_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, + .pad_cfg_lock_offset = PAD_CFG_LOCK_OFFSET_COM1, .host_own_reg_0 = HOSTSW_OWN_REG_0, .gpi_int_sts_reg_0 = GPI_INT_STS_0, .gpi_int_en_reg_0 = GPI_INT_EN_0, @@ -106,6 +108,7 @@ static const struct pad_community skl_gpio_communities[] = { #endif .num_gpi_regs = NUM_GPIO_COM3_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, + .pad_cfg_lock_offset = PAD_CFG_LOCK_OFFSET_COM3, .host_own_reg_0 = HOSTSW_OWN_REG_0, .gpi_int_sts_reg_0 = GPI_INT_STS_0, .gpi_int_en_reg_0 = GPI_INT_EN_0, @@ -126,6 +129,7 @@ static const struct pad_community skl_gpio_communities[] = { .last_pad = GPD11, .num_gpi_regs = NUM_GPIO_COM2_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, + .pad_cfg_lock_offset = PAD_CFG_LOCK_OFFSET_COM2, .host_own_reg_0 = HOSTSW_OWN_REG_0, .gpi_int_sts_reg_0 = GPI_INT_STS_0, .gpi_int_en_reg_0 = GPI_INT_EN_0, diff --git a/src/soc/intel/skylake/gspi.c b/src/soc/intel/skylake/gspi.c deleted file mode 100644 index 4952dffc7d2..00000000000 --- a/src/soc/intel/skylake/gspi.c +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCH_DEVFN_GSPI0; - case 1: - return PCH_DEVFN_GSPI1; - } - return -1; -} diff --git a/src/soc/intel/skylake/i2c.c b/src/soc/intel/skylake/i2c.c deleted file mode 100644 index 521fcb0dd7e..00000000000 --- a/src/soc/intel/skylake/i2c.c +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_I2C0: - return 0; - case PCH_DEVFN_I2C1: - return 1; - case PCH_DEVFN_I2C2: - return 2; - case PCH_DEVFN_I2C3: - return 3; - case PCH_DEVFN_I2C4: - return 4; - case PCH_DEVFN_I2C5: - return 5; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCH_DEVFN_I2C0; - case 1: - return PCH_DEVFN_I2C1; - case 2: - return PCH_DEVFN_I2C2; - case 3: - return PCH_DEVFN_I2C3; - case 4: - return PCH_DEVFN_I2C4; - case 5: - return PCH_DEVFN_I2C5; - } - return -1; -} diff --git a/src/soc/intel/skylake/include/soc/cfr.h b/src/soc/intel/skylake/include/soc/cfr.h index 355dea6b8f9..f68f1d4599c 100644 --- a/src/soc/intel/skylake/include/soc/cfr.h +++ b/src/soc/intel/skylake/include/soc/cfr.h @@ -11,27 +11,19 @@ #include /* FSP hyperthreading */ -static const struct sm_object hyper_threading = SM_DECLARE_ENUM({ +static const struct sm_object hyper_threading = SM_DECLARE_BOOL({ .opt_name = "hyper_threading", .ui_name = "Hyper-Threading", .ui_helptext = "Enable or disable Hyper-Threading", .default_value = CONFIG(FSP_HYPERTHREADING), - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, }); /* IGD Enabled */ -static const struct sm_object igd_enabled = SM_DECLARE_ENUM({ +static const struct sm_object igd_enabled = SM_DECLARE_BOOL({ .opt_name = "igd_enabled", .ui_name = "Enable the Intel iGPU", .ui_helptext = "Enable or disable the Intel iGPU", .default_value = !CONFIG(SOC_INTEL_DISABLE_IGD), - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, }); /* IGD Aperture Size */ @@ -45,7 +37,7 @@ static const struct sm_object igd_aperture = SM_DECLARE_ENUM({ { "256 MB", IGD_AP_SZ_256MB }, { "512 MB", IGD_AP_SZ_512MB }, SM_ENUM_VALUE_END }, -}, WITH_DEP_VALUES(&igd_enabled, 1)); +}, WITH_DEP_VALUES(&igd_enabled, true)); /* IGD DVMT pre-allocated memory */ static const struct sm_object igd_dvmt = SM_DECLARE_ENUM({ @@ -59,42 +51,30 @@ static const struct sm_object igd_dvmt = SM_DECLARE_ENUM({ { "96 MB", IGD_SM_96MB }, { "128 MB", IGD_SM_128MB }, SM_ENUM_VALUE_END }, -}, WITH_DEP_VALUES(&igd_enabled, 1)); +}, WITH_DEP_VALUES(&igd_enabled, true)); /* Legacy 8254 Timer */ -static const struct sm_object legacy_8254_timer = SM_DECLARE_ENUM({ +static const struct sm_object legacy_8254_timer = SM_DECLARE_BOOL({ .opt_name = "legacy_8254_timer", .ui_name = "Legacy 8254 Timer", .ui_helptext = "Enable the legacy 8254 timer by disabling clock gating.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = false, }); /* S0ix Enable */ -static const struct sm_object s0ix_enable = SM_DECLARE_ENUM({ +static const struct sm_object s0ix_enable = SM_DECLARE_BOOL({ .opt_name = "s0ix_enable", .ui_name = "Modern Standby (S0ix)", .ui_helptext = "Enabled: use Modern Standby / S0ix. Disabled: use ACPI S3 sleep", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* VT-d */ -static const struct sm_object vtd = SM_DECLARE_ENUM({ +static const struct sm_object vtd = SM_DECLARE_BOOL({ .opt_name = "vtd", .ui_name = "VT-d", .ui_helptext = "Enable or disable Intel VT-d (virtualization)", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); #endif /* SKYLAKE_CFR_H */ diff --git a/src/soc/intel/skylake/include/soc/gpio_defs.h b/src/soc/intel/skylake/include/soc/gpio_defs.h index 0e98b891693..f91dd633009 100644 --- a/src/soc/intel/skylake/include/soc/gpio_defs.h +++ b/src/soc/intel/skylake/include/soc/gpio_defs.h @@ -209,6 +209,19 @@ #define GPIO_DRIVER_IRQ_ROUTE_IRQ14 0 #define GPIO_DRIVER_IRQ_ROUTE_IRQ15 8 #define HOSTSW_OWN_REG_0 0xd0 + +#if CONFIG(SKYLAKE_SOC_PCH_H) +#define PAD_CFG_LOCK_OFFSET_COM0 0xa0 +#define PAD_CFG_LOCK_OFFSET_COM1 0x90 +#define PAD_CFG_LOCK_OFFSET_COM2 0x90 +#define PAD_CFG_LOCK_OFFSET_COM3 0x90 +#else +#define PAD_CFG_LOCK_OFFSET_COM0 0xa0 +#define PAD_CFG_LOCK_OFFSET_COM1 0xa0 +#define PAD_CFG_LOCK_OFFSET_COM2 0xa0 +#define PAD_CFG_LOCK_OFFSET_COM3 0xa0 +#endif /* CONFIG(SKYLAKE_SOC_PCH_H) */ + #define PAD_CFG_BASE 0x400 #define GPI_INT_STS_0 0x100 #define GPI_INT_EN_0 0x120 diff --git a/src/soc/intel/skylake/include/soc/pci_devs.h b/src/soc/intel/skylake/include/soc/pci_devs.h index 661ed5cd657..876170cfcec 100644 --- a/src/soc/intel/skylake/include/soc/pci_devs.h +++ b/src/soc/intel/skylake/include/soc/pci_devs.h @@ -187,4 +187,11 @@ #define PCH_DEV_GBE _PCH_DEV(LPC, 6) #define PCH_DEV_TRACEHUB _PCH_DEV(LPC, 7) +/* for common code */ +#define PCI_DEVFN_UART0 PCH_DEVFN_UART0 +#define PCI_DEVFN_UART1 PCH_DEVFN_UART1 +#define PCI_DEVFN_UART2 PCH_DEVFN_UART2 +#define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n + #endif diff --git a/src/soc/intel/skylake/romstage/fsp_params.c b/src/soc/intel/skylake/romstage/fsp_params.c index 3ca8a484724..5d59ff18c3f 100644 --- a/src/soc/intel/skylake/romstage/fsp_params.c +++ b/src/soc/intel/skylake/romstage/fsp_params.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include #include @@ -104,7 +105,14 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, static void soc_primary_gfx_config_params(FSP_M_CONFIG *m_cfg, const struct soc_intel_skylake_config *config) { - m_cfg->InternalGfx = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) && is_devfn_enabled(SA_DEVFN_IGD); + bool igd_enabled = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) + && is_devfn_enabled(SA_DEVFN_IGD); + + /* Probe for no IGD and disable InternalGfx to prevent a crash in FSP-M. */ + if (igd_enabled && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) == 0xffff) { + printk(BIOS_ERR, "igd_enabled is set, but IGD is not present. Disabling IGD.\n"); + igd_enabled = false; + } /* * If iGPU is enabled, set IGD stolen size to 64MB. The FBC @@ -116,12 +124,13 @@ static void soc_primary_gfx_config_params(FSP_M_CONFIG *m_cfg, * * If disabled, don't reserve memory for it. */ - if (m_cfg->InternalGfx) { - /* IGD is enabled, set IGD stolen size to 64MB. */ + if (igd_enabled) { + /* Set IGD stolen size to 64MB. */ + m_cfg->InternalGfx = 1; m_cfg->IgdDvmt50PreAlloc = get_uint_option("igd_dvmt_prealloc", IGD_SM_64MB); m_cfg->ApertureSize = get_uint_option("igd_aperture_size", IGD_AP_SZ_256MB); } else { - /* IGD is disabled, skip IGD init in FSP. */ + m_cfg->InternalGfx = 0; m_cfg->IgdDvmt50PreAlloc = 0; } diff --git a/src/soc/intel/skylake/uart.c b/src/soc/intel/skylake/uart.c deleted file mode 100644 index 99468802634..00000000000 --- a/src/soc/intel/skylake/uart.c +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include - -const unsigned int uart_devices[] = { - PCH_DEVFN_UART0, - PCH_DEVFN_UART1, - PCH_DEVFN_UART2, -}; - -const int uart_devices_size = ARRAY_SIZE(uart_devices); diff --git a/src/soc/intel/snowridge/include/soc/msr.h b/src/soc/intel/snowridge/include/soc/msr.h index b45050b7948..45bf8312900 100644 --- a/src/soc/intel/snowridge/include/soc/msr.h +++ b/src/soc/intel/snowridge/include/soc/msr.h @@ -5,14 +5,6 @@ #include -/** - * @brief Force serialized SMM relocation by hardcoding `SMM_CPU_SVRSTR` feature as not supported. - */ -#ifdef SMM_CPU_SVRSTR_MASK -#undef SMM_CPU_SVRSTR_MASK -#endif -#define SMM_CPU_SVRSTR_MASK 0 - #define MSR_BIOS_DONE 0x151 #define ENABLE_IA_UNTRUSTED BIT(0) diff --git a/src/soc/intel/snowridge/include/soc/pci_devs.h b/src/soc/intel/snowridge/include/soc/pci_devs.h index ca50bf8eb1c..09336c07242 100644 --- a/src/soc/intel/snowridge/include/soc/pci_devs.h +++ b/src/soc/intel/snowridge/include/soc/pci_devs.h @@ -68,6 +68,12 @@ /* Stack U0. */ #define UBOX_DEV_RACU _UBOX0_DEV(0x00, 1) + +#define SMM_FEATURE_CONTROL 0x8c +#define SMM_CODE_CHK_EN BIT(2) +#define SMM_FC_CPU_SAVE_EN BIT(1) +#define SMM_FEATURE_CONTROL_LOCK BIT(0) + #define UBOX_DEV_NCDECS _UBOX0_DEV(0x00, 2) /* Stack U1. */ diff --git a/src/soc/intel/snowridge/lockdown.c b/src/soc/intel/snowridge/lockdown.c index b74b74ca4bf..485d3413d36 100644 --- a/src/soc/intel/snowridge/lockdown.c +++ b/src/soc/intel/snowridge/lockdown.c @@ -8,10 +8,6 @@ #include #include -#define SMM_FEATURE_CONTROL 0x8c -#define SMM_CODE_CHK_EN (1 << 2) -#define SMM_FEATURE_CONTROL_LOCK (1 << 0) - static void pmc_lockdown_cfg(int chipset_lockdown) { pmc_or_mmio32(PMSYNC_TPR_CFG, PCH2CPU_TPR_CFG_LOCK); diff --git a/src/soc/intel/tigerlake/Kconfig b/src/soc/intel/tigerlake/Kconfig index d76ddec3358..406d3ffb930 100644 --- a/src/soc/intel/tigerlake/Kconfig +++ b/src/soc/intel/tigerlake/Kconfig @@ -72,6 +72,16 @@ config SOC_INTEL_TIGERLAKE select SOC_INTEL_COMMON_BLOCK_USB4_PCIE select SOC_INTEL_COMMON_BLOCK_USB4_XHCI select SOC_INTEL_COMMON_BLOCK_XHCI_ELOG + select SOC_INTEL_COMMON_FEATURE + select SOC_INTEL_COMMON_FEATURE_ESPI + select SOC_INTEL_COMMON_FEATURE_GLOBAL_RESET_CSE_PMC + select SOC_INTEL_COMMON_FEATURE_GSPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_I2C_DEVFN + select SOC_INTEL_COMMON_FEATURE_SMIHANDLER + select SOC_INTEL_COMMON_FEATURE_SOUNDWIRE + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN + select SOC_INTEL_COMMON_FEATURE_SPI_DEVFN_PSF + select SOC_INTEL_COMMON_FEATURE_UART_DEVICES select SOC_INTEL_COMMON_FSP_RESET select SOC_INTEL_COMMON_PCH_CLIENT select SOC_INTEL_COMMON_RESET @@ -300,4 +310,13 @@ config INTEL_GMA_BCLM_OFFSET config INTEL_GMA_BCLM_WIDTH default 32 +config SOC_INTEL_SPI_DEV_MAX + int + default 3 + +config SOC_INTEL_SPI_PSF_DESTINATION_ID + hex + default 0x23b0 if SOC_INTEL_TIGERLAKE_PCH_H + default 0x23a8 + endif diff --git a/src/soc/intel/tigerlake/Makefile.mk b/src/soc/intel/tigerlake/Makefile.mk index 27e07a99b4e..09b02a96d42 100644 --- a/src/soc/intel/tigerlake/Makefile.mk +++ b/src/soc/intel/tigerlake/Makefile.mk @@ -6,28 +6,20 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo # all (bootblock, verstage, romstage, postcar, ramstage) -all-y += gspi.c -all-y += i2c.c all-y += pmutil.c -all-y += spi.c -all-y += uart.c bootblock-y += bootblock/bootblock.c bootblock-y += bootblock/pch.c bootblock-y += bootblock/report_platform.c -bootblock-y += espi.c bootblock-y += p2sb.c -romstage-y += espi.c romstage-y += meminit.c romstage-y += pcie_rp.c -romstage-y += reset.c ramstage-y += acpi.c ramstage-y += chip.c ramstage-y += cpu.c ramstage-y += elog.c -ramstage-y += espi.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += graphics.c @@ -36,9 +28,7 @@ ramstage-y += lpm.c ramstage-y += p2sb.c ramstage-y += pcie_rp.c ramstage-y += pmc.c -ramstage-y += reset.c ramstage-y += retimer.c -ramstage-y += soundwire.c ramstage-y += systemagent.c ramstage-y += tcss.c ramstage-y += xhci.c @@ -46,8 +36,6 @@ ramstage-$(CONFIG_SOC_INTEL_CRASHLOG) += crashlog_lib.c smm-y += p2sb.c smm-y += pmutil.c -smm-y += smihandler.c -smm-y += uart.c smm-y += elog.c smm-y += xhci.c diff --git a/src/soc/intel/tigerlake/chipset.cb b/src/soc/intel/tigerlake/chipset.cb index f0576ad5e62..725f8296a3b 100644 --- a/src/soc/intel/tigerlake/chipset.cb +++ b/src/soc/intel/tigerlake/chipset.cb @@ -61,9 +61,9 @@ chip soc/intel/tigerlake device pci 10.6 alias thc0 off end device pci 10.7 alias thc1 off end device pci 12.0 alias ish off end - device pci 12.6 alias gspi2 off end - device pci 13.0 alias gspi3 off end - device pci 14.0 alias south_xhci off + device pci 12.6 alias gspi2 off ops spi_dev_ops end + device pci 13.0 alias gspi3 off ops spi_dev_ops end + device pci 14.0 alias south_xhci off ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off @@ -112,44 +112,44 @@ chip soc/intel/tigerlake end end end - device pci 14.1 alias south_xdci off end + device pci 14.1 alias south_xdci off ops usb_xdci_ops end device pci 14.2 alias shared_ram off end - device pci 14.3 alias cnvi_wifi off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 16.0 alias heci1 off end device pci 16.1 alias heci2 off end device pci 16.2 alias csme1 off end device pci 16.3 alias csme2 off end device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end - device pci 17.0 alias sata off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end - device pci 19.2 alias uart2 off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1c.4 alias pcie_rp5 off end - device pci 1c.5 alias pcie_rp6 off end - device pci 1c.6 alias pcie_rp7 off end - device pci 1c.7 alias pcie_rp8 off end - device pci 1d.0 alias pcie_rp9 off end - device pci 1d.1 alias pcie_rp10 off end - device pci 1d.2 alias pcie_rp11 off end - device pci 1d.3 alias pcie_rp12 off end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 17.0 alias sata off ops sata_ops end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end + device pci 19.2 alias uart2 off ops uart_ops end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end + device pci 1d.0 alias pcie_rp9 off ops pcie_rp_ops end + device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end + device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end + device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb off end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.3 alias hda off ops hda_ops end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias tracehub off end diff --git a/src/soc/intel/tigerlake/chipset_pch_h.cb b/src/soc/intel/tigerlake/chipset_pch_h.cb index 40f613ff4ad..28adb940e4f 100644 --- a/src/soc/intel/tigerlake/chipset_pch_h.cb +++ b/src/soc/intel/tigerlake/chipset_pch_h.cb @@ -62,12 +62,12 @@ chip soc/intel/tigerlake device pci 0e.0 alias vmd off end device pci 10.6 alias thc0 off end device pci 10.7 alias thc1 off end - device pci 11.0 alias uart3 off end - device pci 11.3 alias i2c6 off end + device pci 11.0 alias uart3 off ops uart_ops end + device pci 11.3 alias i2c6 off ops i2c_dev_ops end device pci 12.0 alias ish off end - device pci 12.6 alias gspi2 off end - device pci 13.0 alias gspi3 off end - device pci 14.0 alias south_xhci off + device pci 12.6 alias gspi2 off ops spi_dev_ops end + device pci 13.0 alias gspi3 off ops spi_dev_ops end + device pci 14.0 alias south_xhci off ops usb_xhci_ops chip drivers/usb/acpi register "type" = "UPC_TYPE_HUB" device usb 0.0 alias xhci_root_hub off @@ -134,56 +134,56 @@ chip soc/intel/tigerlake end end end - device pci 14.1 alias south_xdci off end + device pci 14.1 alias south_xdci off ops usb_xdci_ops end device pci 14.2 alias shared_ram off end - device pci 14.3 alias cnvi_wifi off end - device pci 15.0 alias i2c0 off end - device pci 15.1 alias i2c1 off end - device pci 15.2 alias i2c2 off end - device pci 15.3 alias i2c3 off end + device pci 14.3 alias cnvi_wifi off ops cnvi_wifi_ops end + device pci 15.0 alias i2c0 off ops i2c_dev_ops end + device pci 15.1 alias i2c1 off ops i2c_dev_ops end + device pci 15.2 alias i2c2 off ops i2c_dev_ops end + device pci 15.3 alias i2c3 off ops i2c_dev_ops end device pci 16.0 alias heci1 off end device pci 16.1 alias heci2 off end device pci 16.2 alias csme1 off end device pci 16.3 alias csme2 off end device pci 16.4 alias heci3 off end device pci 16.5 alias heci4 off end - device pci 17.0 alias sata off end - device pci 19.0 alias i2c4 off end - device pci 19.1 alias i2c5 off end - device pci 19.2 alias uart2 off end - device pci 1b.0 alias pcie_rp17 off end - device pci 1b.1 alias pcie_rp18 off end - device pci 1b.2 alias pcie_rp19 off end - device pci 1b.3 alias pcie_rp20 off end - device pci 1b.4 alias pcie_rp21 off end - device pci 1b.5 alias pcie_rp22 off end - device pci 1b.6 alias pcie_rp23 off end - device pci 1b.7 alias pcie_rp24 off end - device pci 1c.0 alias pcie_rp1 off end - device pci 1c.1 alias pcie_rp2 off end - device pci 1c.2 alias pcie_rp3 off end - device pci 1c.3 alias pcie_rp4 off end - device pci 1c.4 alias pcie_rp5 off end - device pci 1c.5 alias pcie_rp6 off end - device pci 1c.6 alias pcie_rp7 off end - device pci 1c.7 alias pcie_rp8 off end - device pci 1d.0 alias pcie_rp9 off end - device pci 1d.1 alias pcie_rp10 off end - device pci 1d.2 alias pcie_rp11 off end - device pci 1d.3 alias pcie_rp12 off end - device pci 1d.4 alias pcie_rp13 off end - device pci 1d.5 alias pcie_rp14 off end - device pci 1d.6 alias pcie_rp15 off end - device pci 1d.7 alias pcie_rp16 off end - device pci 1e.0 alias uart0 off end - device pci 1e.1 alias uart1 off end - device pci 1e.2 alias gspi0 off end - device pci 1e.3 alias gspi1 off end + device pci 17.0 alias sata off ops sata_ops end + device pci 19.0 alias i2c4 off ops i2c_dev_ops end + device pci 19.1 alias i2c5 off ops i2c_dev_ops end + device pci 19.2 alias uart2 off ops uart_ops end + device pci 1b.0 alias pcie_rp17 off ops pcie_rp_ops end + device pci 1b.1 alias pcie_rp18 off ops pcie_rp_ops end + device pci 1b.2 alias pcie_rp19 off ops pcie_rp_ops end + device pci 1b.3 alias pcie_rp20 off ops pcie_rp_ops end + device pci 1b.4 alias pcie_rp21 off ops pcie_rp_ops end + device pci 1b.5 alias pcie_rp22 off ops pcie_rp_ops end + device pci 1b.6 alias pcie_rp23 off ops pcie_rp_ops end + device pci 1b.7 alias pcie_rp24 off ops pcie_rp_ops end + device pci 1c.0 alias pcie_rp1 off ops pcie_rp_ops end + device pci 1c.1 alias pcie_rp2 off ops pcie_rp_ops end + device pci 1c.2 alias pcie_rp3 off ops pcie_rp_ops end + device pci 1c.3 alias pcie_rp4 off ops pcie_rp_ops end + device pci 1c.4 alias pcie_rp5 off ops pcie_rp_ops end + device pci 1c.5 alias pcie_rp6 off ops pcie_rp_ops end + device pci 1c.6 alias pcie_rp7 off ops pcie_rp_ops end + device pci 1c.7 alias pcie_rp8 off ops pcie_rp_ops end + device pci 1d.0 alias pcie_rp9 off ops pcie_rp_ops end + device pci 1d.1 alias pcie_rp10 off ops pcie_rp_ops end + device pci 1d.2 alias pcie_rp11 off ops pcie_rp_ops end + device pci 1d.3 alias pcie_rp12 off ops pcie_rp_ops end + device pci 1d.4 alias pcie_rp13 off ops pcie_rp_ops end + device pci 1d.5 alias pcie_rp14 off ops pcie_rp_ops end + device pci 1d.6 alias pcie_rp15 off ops pcie_rp_ops end + device pci 1d.7 alias pcie_rp16 off ops pcie_rp_ops end + device pci 1e.0 alias uart0 off ops uart_ops end + device pci 1e.1 alias uart1 off ops uart_ops end + device pci 1e.2 alias gspi0 off ops spi_dev_ops end + device pci 1e.3 alias gspi1 off ops spi_dev_ops end device pci 1f.0 alias pch_espi on end device pci 1f.1 alias p2sb off end device pci 1f.2 alias pmc hidden end - device pci 1f.3 alias hda off end - device pci 1f.4 alias smbus off end + device pci 1f.3 alias hda off ops hda_ops end + device pci 1f.4 alias smbus off ops smbus_ops end device pci 1f.5 alias fast_spi on end device pci 1f.6 alias gbe off end device pci 1f.7 alias thermal off end diff --git a/src/soc/intel/tigerlake/espi.c b/src/soc/intel/tigerlake/espi.c deleted file mode 100644 index 3b56e290d11..00000000000 --- a/src/soc/intel/tigerlake/espi.c +++ /dev/null @@ -1,58 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * This file is created based on Intel Tiger Lake Processor PCH Datasheet - * Document number: 575857 - * Chapter number: 2 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void soc_get_gen_io_dec_range(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]) -{ - const config_t *config = config_of_soc(); - - gen_io_dec[0] = config->gen1_dec; - gen_io_dec[1] = config->gen2_dec; - gen_io_dec[2] = config->gen3_dec; - gen_io_dec[3] = config->gen4_dec; -} - -#if ENV_RAMSTAGE -void lpc_soc_init(struct device *dev) -{ - /* Legacy initialization */ - isa_dma_init(); - pch_misc_init(); - - /* Enable CLKRUN_EN for power gating ESPI */ - lpc_enable_pci_clk_cntl(); - - /* Set ESPI Serial IRQ mode */ - if (CONFIG(SERIRQ_CONTINUOUS_MODE)) - lpc_set_serirq_mode(SERIRQ_CONTINUOUS); - else - lpc_set_serirq_mode(SERIRQ_QUIET); - - /* Interrupt configuration */ - pch_enable_ioapic(); - pch_pirq_init(); - setup_i8259(); - i8259_configure_irq_trigger(9, 1); -} - -#endif diff --git a/src/soc/intel/tigerlake/gspi.c b/src/soc/intel/tigerlake/gspi.c deleted file mode 100644 index 83552f9435e..00000000000 --- a/src/soc/intel/tigerlake/gspi.c +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/* - * This file is created based on Intel Tiger Lake Processor PCH Datasheet - * Document number: 575857 - * Chapter number: 11 - */ - -#include -#include - -int gspi_soc_bus_to_devfn(unsigned int gspi_bus) -{ - switch (gspi_bus) { - case 0: - return PCH_DEVFN_GSPI0; - case 1: - return PCH_DEVFN_GSPI1; - case 2: - return PCH_DEVFN_GSPI2; - } - return -1; -} diff --git a/src/soc/intel/tigerlake/i2c.c b/src/soc/intel/tigerlake/i2c.c deleted file mode 100644 index 5b4e0cb2148..00000000000 --- a/src/soc/intel/tigerlake/i2c.c +++ /dev/null @@ -1,49 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * This file is created based on Intel Tiger Lake Processor PCH Datasheet - * Document number: 575857 - * Chapter number: 13 - */ - -#include -#include -#include - -int dw_i2c_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_I2C0: - return 0; - case PCH_DEVFN_I2C1: - return 1; - case PCH_DEVFN_I2C2: - return 2; - case PCH_DEVFN_I2C3: - return 3; - case PCH_DEVFN_I2C4: - return 4; - case PCH_DEVFN_I2C5: - return 5; - } - return -1; -} - -int dw_i2c_soc_bus_to_devfn(unsigned int bus) -{ - switch (bus) { - case 0: - return PCH_DEVFN_I2C0; - case 1: - return PCH_DEVFN_I2C1; - case 2: - return PCH_DEVFN_I2C2; - case 3: - return PCH_DEVFN_I2C3; - case 4: - return PCH_DEVFN_I2C4; - case 5: - return PCH_DEVFN_I2C5; - } - return -1; -} diff --git a/src/soc/intel/tigerlake/include/soc/cfr.h b/src/soc/intel/tigerlake/include/soc/cfr.h index d424946c5aa..a7f965ce8f8 100644 --- a/src/soc/intel/tigerlake/include/soc/cfr.h +++ b/src/soc/intel/tigerlake/include/soc/cfr.h @@ -11,27 +11,19 @@ #include /* FSP hyperthreading */ -static const struct sm_object hyper_threading = SM_DECLARE_ENUM({ +static const struct sm_object hyper_threading = SM_DECLARE_BOOL({ .opt_name = "hyper_threading", .ui_name = "Hyper-Threading", .ui_helptext = "Enable or disable Hyper-Threading", .default_value = CONFIG(FSP_HYPERTHREADING), - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, }); /* IGD Enabled */ -static const struct sm_object igd_enabled = SM_DECLARE_ENUM({ +static const struct sm_object igd_enabled = SM_DECLARE_BOOL({ .opt_name = "igd_enabled", .ui_name = "Enable the Intel iGPU", .ui_helptext = "Enable or disable the Intel iGPU", .default_value = !CONFIG(SOC_INTEL_DISABLE_IGD), - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, }); /* IGD Aperture Size */ @@ -51,7 +43,7 @@ static const struct sm_object igd_aperture = SM_DECLARE_ENUM({ { " 512 MB", IGD_AP_SZ_512MB }, #endif SM_ENUM_VALUE_END }, -}, WITH_DEP_VALUES(&igd_enabled, 1)); +}, WITH_DEP_VALUES(&igd_enabled, true)); /* IGD DVMT pre-allocated memory */ static const struct sm_object igd_dvmt = SM_DECLARE_ENUM({ @@ -67,42 +59,30 @@ static const struct sm_object igd_dvmt = SM_DECLARE_ENUM({ { "128 MB", IGD_SM_128MB }, { "160 MB", IGD_SM_160MB }, SM_ENUM_VALUE_END }, -}, WITH_DEP_VALUES(&igd_enabled, 1)); +}, WITH_DEP_VALUES(&igd_enabled, true)); /* Legacy 8254 Timer */ -static const struct sm_object legacy_8254_timer = SM_DECLARE_ENUM({ +static const struct sm_object legacy_8254_timer = SM_DECLARE_BOOL({ .opt_name = "legacy_8254_timer", .ui_name = "Legacy 8254 Timer", .ui_helptext = "Enable the legacy 8254 timer by disabling clock gating.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = false, }); /* S0ix Enable */ -static const struct sm_object s0ix_enable = SM_DECLARE_ENUM({ +static const struct sm_object s0ix_enable = SM_DECLARE_BOOL({ .opt_name = "s0ix_enable", .ui_name = "Modern Standby (S0ix)", .ui_helptext = "Enabled: use Modern Standby / S0ix. Disabled: use ACPI S3 sleep", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); /* VT-d */ -static const struct sm_object vtd = SM_DECLARE_ENUM({ +static const struct sm_object vtd = SM_DECLARE_BOOL({ .opt_name = "vtd", .ui_name = "VT-d", .ui_helptext = "Enable or disable Intel VT-d (virtualization)", - .default_value = 1, - .values = (const struct sm_enum_value[]) { - { "Disabled", 0 }, - { "Enabled", 1 }, - SM_ENUM_VALUE_END }, + .default_value = true, }); #endif /* _TIGERLAKE_CFR_H_ */ diff --git a/src/soc/intel/tigerlake/include/soc/pci_devs.h b/src/soc/intel/tigerlake/include/soc/pci_devs.h index d93c97f3c33..66eff3490ca 100644 --- a/src/soc/intel/tigerlake/include/soc/pci_devs.h +++ b/src/soc/intel/tigerlake/include/soc/pci_devs.h @@ -245,4 +245,12 @@ #define PCH_DEV_GBE _PCH_DEV(ESPI, 6) #define PCH_DEV_TRACEHUB _PCH_DEV(ESPI, 7) +/* for common code */ +#define PCI_DEVFN_UART0 PCH_DEVFN_UART0 +#define PCI_DEVFN_UART1 PCH_DEVFN_UART1 +#define PCI_DEVFN_UART2 PCH_DEVFN_UART2 +#define SOC_GSPI_DEVFN(n) PCH_DEVFN_GSPI##n +#define SOC_PMC_DEV PCH_DEV_PMC +#define SOC_I2C_DEVFN(n) PCH_DEVFN_I2C##n + #endif diff --git a/src/soc/intel/tigerlake/reset.c b/src/soc/intel/tigerlake/reset.c deleted file mode 100644 index 3c13f6dfe56..00000000000 --- a/src/soc/intel/tigerlake/reset.c +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include - -void do_global_reset(void) -{ - /* Ask CSE to do the global reset */ - if (cse_request_global_reset() == CSE_TX_RX_SUCCESS) - return; - - /* global reset if CSE fail to reset */ - pmc_global_reset_enable(1); - do_full_reset(); -} diff --git a/src/soc/intel/tigerlake/romstage/fsp_params.c b/src/soc/intel/tigerlake/romstage/fsp_params.c index 3e171b198ae..6f8c5eb9e66 100644 --- a/src/soc/intel/tigerlake/romstage/fsp_params.c +++ b/src/soc/intel/tigerlake/romstage/fsp_params.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -27,14 +28,23 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, m_cfg->HyperThreading = get_uint_option("hyper_threading", CONFIG(FSP_HYPERTHREADING)); - m_cfg->InternalGfx = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) && is_devfn_enabled(SA_DEVFN_IGD); + bool igd_enabled = get_uint_option("igd_enabled", !CONFIG(SOC_INTEL_DISABLE_IGD)) + && is_devfn_enabled(SA_DEVFN_IGD); - if (m_cfg->InternalGfx) { + /* Probe for no IGD and disable InternalGfx to prevent a crash in FSP-M. */ + if (igd_enabled && pci_read_config16(SA_DEV_IGD, PCI_VENDOR_ID) == 0xffff) { + printk(BIOS_ERR, "igd_enabled is set, but IGD is not present. Disabling IGD.\n"); + igd_enabled = false; + } + + if (igd_enabled) { /* IGD is enabled, set IGD stolen size to 60MB. */ + m_cfg->InternalGfx = 1; m_cfg->IgdDvmt50PreAlloc = get_uint_option("igd_dvmt_prealloc", IGD_SM_60MB); m_cfg->ApertureSize = get_uint_option("igd_aperture_size", IGD_AP_SZ_256MB); } else { /* IGD is disabled, skip IGD init in FSP. */ + m_cfg->InternalGfx = 0; m_cfg->IgdDvmt50PreAlloc = 0; } @@ -210,7 +220,7 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, m_cfg->CpuPcieRpEnableMask |= 1 << i; } - m_cfg->TmeEnable = CONFIG(INTEL_TME) && is_tme_supported(); + m_cfg->TmeEnable = get_uint_option("intel_tme", CONFIG(INTEL_TME)) && is_tme_supported(); /* crashLog config */ m_cfg->CpuCrashLogDevice = CONFIG(SOC_INTEL_CRASHLOG) && is_devfn_enabled(SA_DEVFN_TMT); diff --git a/src/soc/intel/tigerlake/smihandler.c b/src/soc/intel/tigerlake/smihandler.c deleted file mode 100644 index e1fc5a03ad0..00000000000 --- a/src/soc/intel/tigerlake/smihandler.c +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include - -int smihandler_soc_disable_busmaster(pci_devfn_t dev) -{ - /* Skip disabling PMC bus master to keep IO decode enabled */ - if (dev == PCH_DEV_PMC) - return 0; - return 1; -} - -const smi_handler_t southbridge_smi[SMI_STS_BITS] = { - [SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep, - [APM_STS_BIT] = smihandler_southbridge_apmc, - [PM1_STS_BIT] = smihandler_southbridge_pm1, - [GPE0_STS_BIT] = smihandler_southbridge_gpe0, - [GPIO_STS_BIT] = smihandler_southbridge_gpi, - [ESPI_SMI_STS_BIT] = smihandler_southbridge_espi, - [MCSMI_STS_BIT] = smihandler_southbridge_mc, -#if CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE) - [TCO_STS_BIT] = smihandler_southbridge_tco, -#endif - [PERIODIC_STS_BIT] = smihandler_southbridge_periodic, - [MONITOR_STS_BIT] = smihandler_southbridge_monitor, -}; diff --git a/src/soc/intel/tigerlake/soundwire.c b/src/soc/intel/tigerlake/soundwire.c deleted file mode 100644 index 878ce1973c7..00000000000 --- a/src/soc/intel/tigerlake/soundwire.c +++ /dev/null @@ -1,70 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include -#include -#include -#include -#include - -static const struct soundwire_link link_xtal_38_4 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 4800 * KHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 50, - .default_frame_col_size = 4, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static const struct soundwire_link link_xtal_24 = { - .clock_stop_mode0_supported = 1, - .clock_stop_mode1_supported = 1, - .clock_frequencies_supported_count = 1, - .clock_frequencies_supported = { 6 * MHz }, - .default_frame_rate = 48 * KHz, - .default_frame_row_size = 125, - .default_frame_col_size = 2, - .dynamic_frame_shape = 1, - .command_error_threshold = 16, -}; - -static struct intel_soundwire_controller intel_controller = { - .acpi_address = 0x40000000, - .sdw = { - .master_list_count = 4 - } -}; - -int soc_fill_soundwire_controller(struct intel_soundwire_controller **controller) -{ - const struct soundwire_link *link; - enum pch_pmc_xtal xtal = pmc_get_xtal_freq(); - size_t i; - - /* Select link config based on XTAL frequency and set IP clock. */ - switch (xtal) { - case XTAL_24_MHZ: - link = &link_xtal_24; - intel_controller.ip_clock = 24 * MHz; - break; - case XTAL_38_4_MHZ: - link = &link_xtal_38_4; - intel_controller.ip_clock = 38400 * KHz; - break; - case XTAL_19_2_MHZ: - default: - printk(BIOS_ERR, "%s: XTAL not supported: 0x%x\n", __func__, xtal); - return -1; - } - - /* Fill link config in controller map based on selected XTAL. */ - for (i = 0; i < intel_controller.sdw.master_list_count; i++) - memcpy(&intel_controller.sdw.master_list[i], link, sizeof(*link)); - - *controller = &intel_controller; - return 0; -} diff --git a/src/soc/intel/tigerlake/spi.c b/src/soc/intel/tigerlake/spi.c deleted file mode 100644 index 47b3b33ce2d..00000000000 --- a/src/soc/intel/tigerlake/spi.c +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/* - * This file is created based on Intel Tiger Lake Processor PCH Datasheet - * Document number: 575857 - * Chapter number: 7 - */ - -#include -#include -#include -#include - -#define PSF_SPI_DESTINATION_ID_H 0x23b0 -#define PSF_SPI_DESTINATION_ID 0x23a8 - -int spi_soc_devfn_to_bus(unsigned int devfn) -{ - switch (devfn) { - case PCH_DEVFN_GSPI0: - return 1; - case PCH_DEVFN_GSPI1: - return 2; - case PCH_DEVFN_GSPI2: - return 3; - } - return -1; -} - -uint32_t soc_get_spi_psf_destination_id(void) -{ - if (CONFIG(SOC_INTEL_TIGERLAKE_PCH_H)) - return PSF_SPI_DESTINATION_ID_H; - return PSF_SPI_DESTINATION_ID; -} diff --git a/src/soc/intel/tigerlake/uart.c b/src/soc/intel/tigerlake/uart.c deleted file mode 100644 index fa4760c1185..00000000000 --- a/src/soc/intel/tigerlake/uart.c +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* - * This file is created based on Intel Tiger Lake Processor PCH Datasheet - * Document number: 575857 - * Chapter number: 9 - */ - -#include -#include - -const unsigned int uart_devices[] = { - PCH_DEVFN_UART0, - PCH_DEVFN_UART1, - PCH_DEVFN_UART2, -}; - -const int uart_devices_size = ARRAY_SIZE(uart_devices); diff --git a/src/soc/intel/xeon_sp/cpx/cpu.c b/src/soc/intel/xeon_sp/cpx/cpu.c index 5df399a61ba..57f9ea9a294 100644 --- a/src/soc/intel/xeon_sp/cpx/cpu.c +++ b/src/soc/intel/xeon_sp/cpx/cpu.c @@ -25,8 +25,6 @@ #include "chip.h" -static const void *microcode_patch; - static const config_t *chip_config = NULL; bool cpu_soc_is_in_untrusted_mode(void) @@ -68,9 +66,13 @@ static void xeon_configure_mca(void) * the BSP. Loading MCU on AP in parallel seems to fail in 10% of the cases * so do it serialized. */ -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 0; } @@ -167,6 +169,9 @@ static void set_max_turbo_freq(void) */ static void pre_mp_init(void) { + const void *microcode_patch = intel_microcode_find(); + intel_microcode_load_unlocked(microcode_patch); + x86_setup_mtrrs_with_detect(); x86_mtrr_check(); } @@ -195,13 +200,6 @@ static const struct mp_ops mp_ops = { void mp_init_cpus(struct bus *bus) { - microcode_patch = intel_microcode_find(); - - if (!microcode_patch) - printk(BIOS_ERR, "microcode not found in CBFS!\n"); - - intel_microcode_load_unlocked(microcode_patch); - /* TODO: Handle mp_init_with_smm failure? */ mp_init_with_smm(bus, &mp_ops); diff --git a/src/soc/intel/xeon_sp/gnr/cpu.c b/src/soc/intel/xeon_sp/gnr/cpu.c index 44f466d2e51..9969287b3c5 100644 --- a/src/soc/intel/xeon_sp/gnr/cpu.c +++ b/src/soc/intel/xeon_sp/gnr/cpu.c @@ -13,8 +13,6 @@ #include "chip.h" -static const void *microcode_patch; - static const config_t *chip_config = NULL; bool cpu_soc_is_in_untrusted_mode(void) @@ -23,9 +21,13 @@ bool cpu_soc_is_in_untrusted_mode(void) return false; } -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 0; } @@ -59,6 +61,9 @@ static const struct cpu_driver driver __cpu_driver = { */ static void pre_mp_init(void) { + const void *microcode_patch = intel_microcode_find(); + intel_microcode_load_unlocked(microcode_patch); + x86_setup_mtrrs_with_detect(); x86_mtrr_check(); } @@ -89,9 +94,6 @@ void mp_init_cpus(struct bus *bus) */ chip_config = bus->dev->chip_info; - microcode_patch = intel_microcode_find(); - intel_microcode_load_unlocked(microcode_patch); - enum cb_err ret = mp_init_with_smm(bus, &mp_ops); if (ret != CB_SUCCESS) printk(BIOS_ERR, "MP initialization failure %d.\n", ret); diff --git a/src/soc/intel/xeon_sp/skx/cpu.c b/src/soc/intel/xeon_sp/skx/cpu.c index e829aa988c2..ddb509bfb4b 100644 --- a/src/soc/intel/xeon_sp/skx/cpu.c +++ b/src/soc/intel/xeon_sp/skx/cpu.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -70,9 +71,13 @@ static void xeon_configure_mca(void) * FSP-S updates microcodes serialized, so do the same. * */ -static void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 0; } @@ -246,6 +251,9 @@ static void pre_mp_init(void) { printk(BIOS_DEBUG, "%s: entry\n", __func__); + const void *microcode_patch = intel_microcode_find(); + intel_microcode_load_unlocked(microcode_patch); + x86_setup_mtrrs_with_detect(); x86_mtrr_check(); } @@ -279,13 +287,6 @@ void mp_init_cpus(struct bus *bus) { FUNC_ENTER(); - const void *microcode_patch = intel_microcode_find(); - - if (!microcode_patch) - printk(BIOS_ERR, "microcode not found in CBFS!\n"); - - intel_microcode_load_unlocked(microcode_patch); - /* * This gets used in cpu device callback. Other than cpu 0, * rest of the CPU devices do not have diff --git a/src/soc/intel/xeon_sp/spr/cpu.c b/src/soc/intel/xeon_sp/spr/cpu.c index cafdc379709..55568cc8ffa 100644 --- a/src/soc/intel/xeon_sp/spr/cpu.c +++ b/src/soc/intel/xeon_sp/spr/cpu.c @@ -17,8 +17,6 @@ #include "chip.h" -static const void *microcode_patch; - static const config_t *chip_config = NULL; bool cpu_soc_is_in_untrusted_mode(void) @@ -58,9 +56,13 @@ static void xeon_configure_mca(void) * the BSP. Loading MCU on AP in parallel seems to fail in 10% of the cases * so do it serialized. */ -void get_microcode_info(const void **microcode, int *parallel) +void get_microcode_info(const void **microcode, size_t *size, int *parallel) { - *microcode = intel_microcode_find(); + const struct microcode *microcode_file = intel_microcode_find(); + if (microcode_file != NULL) + *size = get_microcode_size(microcode_file); + + *microcode = microcode_file; *parallel = 0; } @@ -219,6 +221,9 @@ static void set_max_turbo_freq(void) */ static void pre_mp_init(void) { + const void *microcode_patch = intel_microcode_find(); + intel_microcode_load_unlocked(microcode_patch); + x86_setup_mtrrs_with_detect(); x86_mtrr_check(); } @@ -255,9 +260,6 @@ void mp_init_cpus(struct bus *bus) */ chip_config = bus->dev->chip_info; - microcode_patch = intel_microcode_find(); - intel_microcode_load_unlocked(microcode_patch); - enum cb_err ret = mp_init_with_smm(bus, &mp_ops); if (ret != CB_SUCCESS) printk(BIOS_ERR, "MP initialization failure %d.\n", ret); diff --git a/src/soc/mediatek/common/Kconfig b/src/soc/mediatek/common/Kconfig index 30cab53df66..c52f8ed407d 100644 --- a/src/soc/mediatek/common/Kconfig +++ b/src/soc/mediatek/common/Kconfig @@ -69,6 +69,12 @@ config MEDIATEK_WDT_RESET_BY_SW If the kernel disables WDT external reset (mediatek,disable-extrst), then this option must be disabled to allow WDT hardware external reset. +config MEDIATEK_DSI_DUAL_CHANNEL + bool + default n + help + The configuration to support DSI dual channel. + config MEMORY_TEST bool default y diff --git a/src/soc/mediatek/common/display.c b/src/soc/mediatek/common/display.c index d1880e42997..d1fce217a69 100644 --- a/src/soc/mediatek/common/display.c +++ b/src/soc/mediatek/common/display.c @@ -14,6 +14,10 @@ #include #include #include +#include + +static u32 dsi_mode_flags; +static struct panel_serializable_data *mipi_data; static struct panel_serializable_data *get_mipi_cmd_from_cbfs(struct panel_description *desc) { @@ -78,7 +82,8 @@ static void panel_configure_backlight(struct panel_description *panel, static void display_logo(struct panel_description *panel, uintptr_t fb_addr, - const struct edid *edid) + const struct edid *edid, + enum disp_path_sel path) { memset((void *)fb_addr, 0, edid->bytes_per_line * edid->y_resolution); @@ -86,13 +91,15 @@ static void display_logo(struct panel_description *panel, .panel_orientation = panel->orientation, .halignment = FW_SPLASH_HALIGNMENT_CENTER, .valignment = FW_SPLASH_VALIGNMENT_CENTER, - .logo_bottom_margin = 100, + .logo_bottom_margin = CONFIG(FRAMEBUFFER_SPLASH_TEXT) ? 200 : 100, }; render_logo_to_framebuffer(&config); - mtk_ddp_ovlsys_start(fb_addr); + mtk_ddp_ovlsys_start(fb_addr, edid, path); panel_configure_backlight(panel, true); + + timestamp_add_now(TS_FIRMWARE_SPLASH_RENDERED); } int mtk_display_init(void) @@ -132,8 +139,6 @@ int mtk_display_init(void) return -1; } } else { - struct panel_serializable_data *mipi_data = NULL; - if (panel->get_edid) { if (panel->get_edid(&edid) < 0) return -1; @@ -168,6 +173,8 @@ int mtk_display_init(void) lanes = 4; } + dsi_mode_flags = mipi_dsi_flags; + if (mtk_dsi_init(mipi_dsi_flags, MIPI_DSI_FMT_RGB888, lanes, &edid, mipi_data ? mipi_data->init : NULL) < 0) { printk(BIOS_ERR, "%s: Failed in DSI init\n", __func__); @@ -183,12 +190,13 @@ int mtk_display_init(void) name = edid.ascii_string; if (name[0] == '\0') name = "unknown name"; - printk(BIOS_INFO, "%s: '%s %s' %dx%d@%dHz\n", __func__, - edid.manufacturer_name, name, edid.mode.ha, edid.mode.va, - edid.mode.refresh); edid_set_framebuffer_bits_per_pixel(&edid, 32, 0); + printk(BIOS_INFO, "%s: '%s %s' %dx%d@%dHz bpp %u\n", __func__, + edid.manufacturer_name, name, edid.mode.ha, edid.mode.va, + edid.mode.refresh, edid.framebuffer_bits_per_pixel / 8); + mtk_ddp_mode_set(&edid, panel->disp_path, dsc_config_var); if (panel->disp_path == DISP_PATH_EDP) { @@ -209,33 +217,41 @@ int mtk_display_init(void) fb_set_dual_pipe_flag(info, true); if (CONFIG(BMP_LOGO)) - display_logo(panel, fb_addr, &edid); + display_logo(panel, fb_addr, &edid, panel->disp_path); return 0; } -void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, - struct dsc_config *dsc_config) +int mtk_mipi_panel_poweroff(void) +{ + if (!mipi_data) + return 0; + + return mtk_dsi_panel_poweroff(dsi_mode_flags, mipi_data->poweroff); +} + +u32 mtk_get_vrefresh(const struct edid *edid) { - u32 fmt = OVL_INFMT_RGBA8888; - u32 bpp = edid->framebuffer_bits_per_pixel / 8; u32 width = edid->mode.ha; u32 height = edid->mode.va; u32 vrefresh = edid->mode.refresh; - printk(BIOS_DEBUG, "%s: display resolution: %ux%u@%u bpp %u\n", __func__, width, height, - vrefresh, bpp); + if (vrefresh) + return vrefresh; - if (!vrefresh) { - if (!width || !height) - vrefresh = 60; - else - vrefresh = edid->mode.pixel_clock * 1000 / - ((width + edid->mode.hbl) * (height + edid->mode.vbl)); + if (!width || !height) + vrefresh = 60; + else + vrefresh = edid->mode.pixel_clock * 1000 / + ((width + edid->mode.hbl) * (height + edid->mode.vbl)); - printk(BIOS_WARNING, "%s: vrefresh is not provided; using %u\n", __func__, - vrefresh); - } + printk(BIOS_WARNING, "%s: vrefresh is not provided; using %u\n", __func__, + vrefresh); - mtk_ddp_soc_mode_set(fmt, bpp, width, height, vrefresh, path, dsc_config); + return vrefresh; +} + +const struct panel_serializable_data *mtk_get_mipi_panel_data(void) +{ + return mipi_data; } diff --git a/src/soc/mediatek/common/dp/dptx_v2.c b/src/soc/mediatek/common/dp/dptx_v2.c index 5b917a501ac..81cfa766819 100644 --- a/src/soc/mediatek/common/dp/dptx_v2.c +++ b/src/soc/mediatek/common/dp/dptx_v2.c @@ -41,7 +41,7 @@ static void mtk_edp_pattern(struct mtk_dp *mtk_dp, u8 lane_count, u8 pattern) break; case DPTX_PATTERN_UNKNOWN: default: - printk(BIOS_ERR, "Set default or unknown pattern\n"); + printk(BIOS_ERR, "Set default or unknown pattern %d\n", pattern); mtk_dp_mask(mtk_dp, REG_3400_DP_TRANS_P0, 0x0, PATTERN_EN_DP_TRANS_4P_MASK); return; } diff --git a/src/soc/mediatek/common/dp/include/soc/dptx_reg_v2.h b/src/soc/mediatek/common/dp/include/soc/dptx_reg_v2.h index da0654ab9de..d1f4f411efe 100644 --- a/src/soc/mediatek/common/dp/include/soc/dptx_reg_v2.h +++ b/src/soc/mediatek/common/dp/include/soc/dptx_reg_v2.h @@ -157,7 +157,6 @@ #define REG_3F44_DP_ENC_4P_3 0x3F44 #define PHY_PWR_STATE_OW_EN_DP_ENC_4P_3 BIT(2) #define PHY_PWR_STATE_OW_EN_DP_ENC_4P_3_MASK BIT(2) -#define BIAS_POWER_ON (0x01 << 3) #define PHY_PWR_STATE_OW_VALUE_DP_ENC_4P_3_MASK GENMASK(4, 3) #define REG_3F80_DP_ENC_4P_3 0x3F80 #define PSR_PATGEN_AVT_EN_FLDMASK 0x20 diff --git a/src/soc/mediatek/common/dsi_common.c b/src/soc/mediatek/common/dsi_common.c index 2298aa0ace9..04dc0a85c35 100644 --- a/src/soc/mediatek/common/dsi_common.c +++ b/src/soc/mediatek/common/dsi_common.c @@ -16,6 +16,25 @@ #define CPHY_SYMBOL_RATE 7 #define CPHY_SYMBOL_RATE_DIVISOR 16 +#define COMPRESSION_RATIO 3 +#define UNCOMPRESSED_RATIO 1 + +static const struct { + struct dsi_regs *const dsi_reg; + struct mipi_tx_regs *const mipi_reg; +} dsi_mipi_regs[] = { + { + .dsi_reg = dsi0, + .mipi_reg = mipi_tx0, + }, +#if CONFIG(MEDIATEK_DSI_DUAL_CHANNEL) + { + .dsi_reg = dsi1, + .mipi_reg = mipi_tx1, + }, +#endif +}; + static unsigned int mtk_dsi_get_bits_per_pixel(u32 format) { switch (format) { @@ -33,7 +52,7 @@ static unsigned int mtk_dsi_get_bits_per_pixel(u32 format) } static u32 mtk_dsi_get_data_rate(u32 bits_per_pixel, u32 lanes, - const struct edid *edid, bool is_cphy) + const struct edid *edid, u32 mode_flags) { /* data_rate = pixel_clock * bits_per_pixel * mipi_ratio / lanes * Note pixel_clock comes in kHz and returned data_rate is in bps. @@ -41,9 +60,18 @@ static u32 mtk_dsi_get_data_rate(u32 bits_per_pixel, u32 lanes, * for older platforms which do not have complete implementation in HFP. * Newer platforms should just set that to 1.0 (100 / 100). */ + u64 pixel_clock = edid->mode.pixel_clock; u32 data_rate; - u64 dividend = (u64)edid->mode.pixel_clock * bits_per_pixel * 1000 * - MTK_DSI_MIPI_RATIO_NUMERATOR; + bool is_cphy = !!(mode_flags & MIPI_DSI_MODE_CPHY); + bool is_dsi_dual_channel = !!(mode_flags & MIPI_DSI_DUAL_CHANNEL); + bool is_dsc_enabled = !!(mode_flags & MIPI_DSI_DSC_MODE); + + if (is_dsc_enabled) + pixel_clock = pixel_clock * + (DIV_ROUND_UP(edid->mode.ha, 3) + edid->mode.hbl) / + (edid->mode.ha + edid->mode.hbl); + + u64 dividend = pixel_clock * bits_per_pixel * 1000 * MTK_DSI_MIPI_RATIO_NUMERATOR; u64 divisor = (u64)lanes * MTK_DSI_MIPI_RATIO_DENOMINATOR; if (is_cphy) { @@ -51,15 +79,20 @@ static u32 mtk_dsi_get_data_rate(u32 bits_per_pixel, u32 lanes, divisor *= CPHY_SYMBOL_RATE_DIVISOR; } data_rate = DIV_ROUND_UP(dividend, divisor); - printk(BIOS_INFO, "DSI data_rate: %u bps\n", data_rate); + printk(BIOS_INFO, "pixel_clock: %lld\n", pixel_clock); + printk(BIOS_INFO, "bits_per_pixel: %d\n", bits_per_pixel); + if (is_dsi_dual_channel) + data_rate = data_rate / 2; + + printk(BIOS_INFO, "DSI final data_rate: %u bps\n", data_rate); if (data_rate < MTK_DSI_DATA_RATE_MIN_MHZ * MHz) { printk(BIOS_ERR, "data rate (%ubps) must be >= %ubps. " - "Please check the pixel clock (%u), " + "Please check the pixel clock (%llu), " "bits per pixel (%u), " "mipi_ratio (%d%%) and number of lanes (%d)\n", data_rate, MTK_DSI_DATA_RATE_MIN_MHZ * MHz, - edid->mode.pixel_clock, bits_per_pixel, + pixel_clock, bits_per_pixel, (100 * MTK_DSI_MIPI_RATIO_NUMERATOR / MTK_DSI_MIPI_RATIO_DENOMINATOR), lanes); return 0; @@ -72,7 +105,8 @@ __weak void mtk_dsi_override_phy_timing(struct mtk_phy_timing *timing) /* Do nothing. */ } -static void mtk_dsi_dphy_timing(u32 data_rate, struct mtk_phy_timing *timing) +static void mtk_dsi_dphy_timing(struct dsi_regs *dsi_reg, u32 data_rate, + struct mtk_phy_timing *timing) { u32 timcon0, timcon1, timcon2, timcon3; u32 data_rate_mhz = DIV_ROUND_UP(data_rate, MHz); @@ -91,23 +125,23 @@ static void mtk_dsi_dphy_timing(u32 data_rate, struct mtk_phy_timing *timing) timcon3 = timing->clk_hs_prepare | timing->clk_hs_post << 8 | timing->clk_hs_exit << 16; - write32(&dsi0->dsi_phy_timecon0, timcon0); - write32(&dsi0->dsi_phy_timecon1, timcon1); - write32(&dsi0->dsi_phy_timecon2, timcon2); - write32(&dsi0->dsi_phy_timecon3, timcon3); + write32(&dsi_reg->dsi_phy_timecon0, timcon0); + write32(&dsi_reg->dsi_phy_timecon1, timcon1); + write32(&dsi_reg->dsi_phy_timecon2, timcon2); + write32(&dsi_reg->dsi_phy_timecon3, timcon3); } -static void mtk_dsi_clk_hs_mode_enable(void) +static void mtk_dsi_clk_hs_mode_enable(struct dsi_regs *dsi_reg) { - setbits32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN); + setbits32(&dsi_reg->dsi_phy_lccon, LC_HS_TX_EN); } -static void mtk_dsi_clk_hs_mode_disable(void) +static void mtk_dsi_clk_hs_mode_disable(struct dsi_regs *dsi_reg) { - clrbits32(&dsi0->dsi_phy_lccon, LC_HS_TX_EN); + clrbits32(&dsi_reg->dsi_phy_lccon, LC_HS_TX_EN); } -static void mtk_dsi_set_mode(u32 mode_flags) +static void mtk_dsi_set_mode(struct dsi_regs *dsi_reg, u32 mode_flags) { u32 tmp_reg1 = 0; @@ -121,10 +155,10 @@ static void mtk_dsi_set_mode(u32 mode_flags) tmp_reg1 = SYNC_PULSE_MODE; } - write32(&dsi0->dsi_mode_ctrl, tmp_reg1); + write32(&dsi_reg->dsi_mode_ctrl, tmp_reg1); } -static void mtk_dsi_rxtx_control(u32 mode_flags, u32 lanes) +static void mtk_dsi_rxtx_control(struct dsi_regs *dsi_reg, u32 mode_flags, u32 lanes) { u32 tmp_reg = 0; @@ -150,7 +184,7 @@ static void mtk_dsi_rxtx_control(u32 mode_flags, u32 lanes) if (!(mode_flags & MIPI_DSI_MODE_EOT_PACKET)) tmp_reg |= EOTP_DISABLE; - write32(&dsi0->dsi_txrx_ctrl, tmp_reg); + write32(&dsi_reg->dsi_txrx_ctrl, tmp_reg); } static void mtk_dsi_dphy_vdo_timing(const u32 mode_flags, @@ -168,6 +202,9 @@ static void mtk_dsi_dphy_vdo_timing(const u32 mode_flags, phy_timing->da_hs_zero + phy_timing->da_hs_exit + 3; u32 delta = 10; + int channels = (mode_flags & MIPI_DSI_DUAL_CHANNEL) ? 2 : 1; + int dsc_ratio = (mode_flags & MIPI_DSI_DSC_MODE) ? COMPRESSION_RATIO : + UNCOMPRESSED_RATIO; if (mode_flags & MIPI_DSI_MODE_EOT_PACKET) delta += 2; @@ -188,17 +225,44 @@ static void mtk_dsi_dphy_vdo_timing(const u32 mode_flags, hbp * bytes_per_pixel, d_phy); } - *hsync_active_byte = edid->mode.hspw * bytes_per_pixel - 10; + *hsync_active_byte = edid->mode.hspw / channels * bytes_per_pixel - 10; + if (mode_flags & MIPI_DSI_MODE_LINE_END) { *hsync_active_byte = DIV_ROUND_UP(*hsync_active_byte, lanes) * lanes - 2; *hbp_byte = DIV_ROUND_UP(*hbp_byte, lanes) * lanes - 2; *hfp_byte = DIV_ROUND_UP(*hfp_byte, lanes) * lanes - 2; - *hbp_byte -= (edid->mode.ha * bytes_per_pixel + 2) % lanes; + *hbp_byte -= (edid->mode.ha / dsc_ratio / channels * bytes_per_pixel + 2) % + lanes; } } -static void mtk_dsi_config_vdo_timing(u32 mode_flags, u32 format, u32 lanes, - const struct edid *edid, +static u32 mtk_dsi_get_packet_fmt(u32 format) +{ + u32 packet_fmt; + + switch (format) { + case MIPI_DSI_FMT_RGB888: + packet_fmt = PACKED_PS_24BIT_RGB888; + break; + case MIPI_DSI_FMT_RGB666: + packet_fmt = LOOSELY_PS_18BIT_RGB666; + break; + case MIPI_DSI_FMT_RGB666_PACKED: + packet_fmt = PACKED_PS_18BIT_RGB666; + break; + case MIPI_DSI_FMT_RGB565: + packet_fmt = PACKED_PS_16BIT_RGB565; + break; + default: + packet_fmt = PACKED_PS_24BIT_RGB888; + break; + } + + return packet_fmt; +} + +static void mtk_dsi_config_vdo_timing(struct dsi_regs *const dsi_reg, u32 mode_flags, + u32 format, u32 lanes, const struct edid *edid, const struct mtk_phy_timing *phy_timing) { u32 hsync_active_byte; @@ -211,26 +275,30 @@ static void mtk_dsi_config_vdo_timing(u32 mode_flags, u32 format, u32 lanes, u32 bytes_per_pixel; u32 packet_fmt; u32 hactive; + u32 hbp_offset; bool is_cphy = !!(mode_flags & MIPI_DSI_MODE_CPHY); + bool is_dsc_enabled = !!(mode_flags & MIPI_DSI_DSC_MODE); + int channels = !!(mode_flags & MIPI_DSI_DUAL_CHANNEL) ? 2 : 1; + int dsc_ratio = is_dsc_enabled ? COMPRESSION_RATIO : UNCOMPRESSED_RATIO; bytes_per_pixel = DIV_ROUND_UP(mtk_dsi_get_bits_per_pixel(format), 8); vbp_byte = edid->mode.vbl - edid->mode.vso - edid->mode.vspw - edid->mode.vborder; vfp_byte = edid->mode.vso - edid->mode.vborder; - write32(&dsi0->dsi_vsa_nl, edid->mode.vspw); - write32(&dsi0->dsi_vbp_nl, vbp_byte); - write32(&dsi0->dsi_vfp_nl, vfp_byte); - write32(&dsi0->dsi_vact_nl, edid->mode.va); + write32(&dsi_reg->dsi_vsa_nl, edid->mode.vspw); + write32(&dsi_reg->dsi_vbp_nl, vbp_byte); + write32(&dsi_reg->dsi_vfp_nl, vfp_byte); + write32(&dsi_reg->dsi_vact_nl, edid->mode.va); - hbp = edid->mode.hbl - edid->mode.hso - edid->mode.hspw - - edid->mode.hborder; - hfp = edid->mode.hso - edid->mode.hborder; + hbp = (edid->mode.hbl - edid->mode.hso - edid->mode.hspw - + edid->mode.hborder) / channels; + hfp = (edid->mode.hso - edid->mode.hborder) / channels; + + hbp_offset = (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) ? + 0 : (edid->mode.hspw / channels); + hbp_byte = (hbp + hbp_offset) * bytes_per_pixel - 10; - if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) - hbp_byte = hbp * bytes_per_pixel - 10; - else - hbp_byte = (hbp + edid->mode.hspw) * bytes_per_pixel - 10; hfp_byte = hfp * bytes_per_pixel; if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) @@ -255,49 +323,40 @@ static void mtk_dsi_config_vdo_timing(u32 mode_flags, u32 format, u32 lanes, hbp_byte = MIN_HBP_BYTE; } - write32(&dsi0->dsi_hsa_wc, hsync_active_byte); - write32(&dsi0->dsi_hbp_wc, hbp_byte); - write32(&dsi0->dsi_hfp_wc, hfp_byte); + write32(&dsi_reg->dsi_hsa_wc, hsync_active_byte); + write32(&dsi_reg->dsi_hbp_wc, hbp_byte); + write32(&dsi_reg->dsi_hfp_wc, hfp_byte); - switch (format) { - case MIPI_DSI_FMT_RGB888: - packet_fmt = PACKED_PS_24BIT_RGB888; - break; - case MIPI_DSI_FMT_RGB666: - packet_fmt = LOOSELY_PS_18BIT_RGB666; - break; - case MIPI_DSI_FMT_RGB666_PACKED: - packet_fmt = PACKED_PS_18BIT_RGB666; - break; - case MIPI_DSI_FMT_RGB565: - packet_fmt = PACKED_PS_16BIT_RGB565; - break; - default: - packet_fmt = PACKED_PS_24BIT_RGB888; - break; - } + if (is_dsc_enabled) + packet_fmt = COMPRESSED_PIXEL_STREAM_V2; + else + packet_fmt = mtk_dsi_get_packet_fmt(format); - hactive = edid->mode.ha; + hactive = edid->mode.ha / dsc_ratio / channels; packet_fmt |= (hactive * bytes_per_pixel) & DSI_PS_WC; - write32(&dsi0->dsi_psctrl, + write32(&dsi_reg->dsi_psctrl, PIXEL_STREAM_CUSTOM_HEADER << DSI_PSCON_CUSTOM_HEADER_SHIFT | packet_fmt); /* Older systems like MT8173 do not support size_con. */ if (MTK_DSI_HAVE_SIZE_CON) - write32(&dsi0->dsi_size_con, + write32(&dsi_reg->dsi_size_con, edid->mode.va << DSI_SIZE_CON_HEIGHT_SHIFT | hactive << DSI_SIZE_CON_WIDTH_SHIFT); if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) - mtk_dsi_cphy_enable_cmdq_6byte(dsi0); + mtk_dsi_cphy_enable_cmdq_6byte(dsi_reg); +} + +static void mtk_dsi_dual_enable(struct dsi_regs *dsi_reg, bool enable) +{ + clrsetbits32(&dsi_reg->dsi_con_ctrl, DSI_DUAL, (enable ? DSI_DUAL : 0)); } -static void mtk_dsi_start(void) +static void mtk_dsi_start(struct dsi_regs *dsi_reg) { - write32(&dsi0->dsi_start, 0); - /* Only start master DSI */ - write32(&dsi0->dsi_start, 1); + write32(&dsi_reg->dsi_start, 0); + write32(&dsi_reg->dsi_start, 1); } static bool mtk_dsi_is_read_command(enum mipi_dsi_transaction type) @@ -313,60 +372,81 @@ static bool mtk_dsi_is_read_command(enum mipi_dsi_transaction type) } } +static void mtk_dsi_enable_and_start(bool is_dsi_dual_channel) +{ + /* + * For dual channel synchronization, + * the secondary dsi1 must be dual-enabled before starting the primary dsi0. + */ + if (is_dsi_dual_channel) + mtk_dsi_dual_enable(dsi_mipi_regs[ARRAY_SIZE(dsi_mipi_regs) - 1].dsi_reg, true); + /* + * Only start primary dsi0 for single or dual channel mode. + * The secondary dsi1 is dual-enabled in mtk_dsi_dual_enable() + * and does not require a separate start. + * Starting only the primary dsi0 ensures correct synchronization + * with secondary dsi1 if there is. + */ + mtk_dsi_start(dsi_mipi_regs[0].dsi_reg); +} + static enum cb_err mtk_dsi_cmdq(enum mipi_dsi_transaction type, const u8 *data, u8 len, void *user_data) { const u8 *tx_buf = data; u32 config; - int i, j; - - if (!wait_ms(20, !(read32(&dsi0->dsi_intsta) & DSI_BUSY))) { - printk(BIOS_ERR, "%s: cannot get DSI ready for sending commands" - " after 20ms and the panel may not work properly.\n", - __func__); - return CB_ERR; - } - write32(&dsi0->dsi_intsta, 0); - - if (mtk_dsi_is_read_command(type)) - config = BTA; - else - config = (len > 2) ? LONG_PACKET : SHORT_PACKET; - - if (len <= 2) { - uint32_t val = (type << 8) | config; - for (i = 0; i < len; i++) - val |= tx_buf[i] << (i + 2) * 8; - write32(&dsi0->dsi_cmdq[0], val); - write32(&dsi0->dsi_cmdq_size, 1); - } else { - /* TODO(hungte) Replace by buffer_to_fifo32_prefix */ - write32(&dsi0->dsi_cmdq[0], (len << 16) | (type << 8) | config); - for (i = 0; i < len; i += 4) { - uint32_t val = 0; - for (j = 0; j < MIN(len - i, 4); j++) - val |= tx_buf[i + j] << j * 8; - write32(&dsi0->dsi_cmdq[i / 4 + 1], val); + uint32_t *mode_flags = (uint32_t *)user_data; + bool is_dsi_dual_channel = (*mode_flags & MIPI_DSI_DUAL_CHANNEL); + + for (unsigned int k = 0; k < ARRAY_SIZE(dsi_mipi_regs); k++) { + struct dsi_regs *dsi = dsi_mipi_regs[k].dsi_reg; + if (!wait_ms(20, !(read32(&dsi->dsi_intsta) & DSI_BUSY))) { + printk(BIOS_ERR, "%s: cannot get DSI-%d ready for sending commands" + " after 20ms and the panel may not work properly.\n", + __func__, k); + return CB_ERR; } - write32(&dsi0->dsi_cmdq_size, 1 + DIV_ROUND_UP(len, 4)); + write32(&dsi->dsi_intsta, 0); + + if (mtk_dsi_is_read_command(type)) + config = BTA; + else + config = (len > 2) ? LONG_PACKET : SHORT_PACKET; + + u32 prefix = config | type << 8; + int prefsz = 2; + if (len > 2) { + prefix |= len << 16; + prefsz += 2; + } + buffer_to_fifo32_prefix(tx_buf, prefix, prefsz, prefsz + len, &dsi->dsi_cmdq[0], + 4, 4); + write32(&dsi->dsi_cmdq_size, DIV_ROUND_UP(prefsz + len, 4) | CMDQ_SIZE_SEL); } - setbits32(&dsi0->dsi_cmdq_size, CMDQ_SIZE_SEL); - mtk_dsi_start(); + mtk_dsi_enable_and_start(is_dsi_dual_channel); - if (!wait_us(400, read32(&dsi0->dsi_intsta) & CMD_DONE_INT_FLAG)) { - printk(BIOS_ERR, "%s: failed sending DSI command, " - "panel may not work.\n", __func__); - return CB_ERR; + for (unsigned int k = 0; k < ARRAY_SIZE(dsi_mipi_regs); k++) { + struct dsi_regs *dsi = dsi_mipi_regs[k].dsi_reg; + if (!wait_us(400, read32(&dsi->dsi_intsta) & CMD_DONE_INT_FLAG)) { + printk(BIOS_ERR, "%s: failed sending DSI-%d command, " + "panel may not work.\n", __func__, k); + return CB_ERR; + } } return CB_SUCCESS; } -static void mtk_dsi_reset_phy(void) +static void mtk_dsi_reset_phy(struct dsi_regs *const dsi_reg) { - setbits32(&dsi0->dsi_con_ctrl, DPHY_RESET); - clrbits32(&dsi0->dsi_con_ctrl, DPHY_RESET); + setbits32(&dsi_reg->dsi_con_ctrl, DPHY_RESET); + clrbits32(&dsi_reg->dsi_con_ctrl, DPHY_RESET); +} + +static void mtk_dsi_stop(struct dsi_regs *dsi) +{ + write32(&dsi->dsi_start, 0); } int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, @@ -375,6 +455,8 @@ int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, u32 data_rate; u32 bits_per_pixel = mtk_dsi_get_bits_per_pixel(format); bool is_cphy = !!(mode_flags & MIPI_DSI_MODE_CPHY); + bool is_dsi_dual_channel = !!(mode_flags & MIPI_DSI_DUAL_CHANNEL); + unsigned int num_dsi = is_dsi_dual_channel ? 2 : 1; if (!CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) { printk(BIOS_ERR, "%s: Board is built without C-PHY interface support. " @@ -382,27 +464,88 @@ int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, return -1; } - data_rate = mtk_dsi_get_data_rate(bits_per_pixel, lanes, edid, is_cphy); + if (num_dsi > ARRAY_SIZE(dsi_mipi_regs)) { + printk(BIOS_ERR, "%s: num_dsi %d > %lu\n", __func__, + num_dsi, ARRAY_SIZE(dsi_mipi_regs)); + return -1; + } + + data_rate = mtk_dsi_get_data_rate(bits_per_pixel, lanes, edid, mode_flags); if (!data_rate) return -1; - mtk_dsi_configure_mipi_tx(mipi_tx0, data_rate, lanes, is_cphy); - mtk_dsi_reset(dsi0); - struct mtk_phy_timing phy_timing = {}; - if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) - mtk_dsi_cphy_timing(data_rate, &phy_timing); - else - mtk_dsi_dphy_timing(data_rate, &phy_timing); - mtk_dsi_rxtx_control(mode_flags, lanes); - mdelay(1); - mtk_dsi_reset_phy(); - mtk_dsi_clk_hs_mode_disable(); - mtk_dsi_config_vdo_timing(mode_flags, format, lanes, edid, &phy_timing); - mtk_dsi_clk_hs_mode_enable(); + for (unsigned int i = 0; i < num_dsi; i++) { + struct dsi_regs *dsi = dsi_mipi_regs[i].dsi_reg; + struct mipi_tx_regs *mipi = dsi_mipi_regs[i].mipi_reg; + if (!dsi || !mipi) { + printk(BIOS_ERR, "%s: Null dsi/mipi reg for DSI-%d\n", __func__, i); + return -1; + } + mtk_dsi_configure_mipi_tx(mipi, data_rate, lanes, is_cphy); + mtk_dsi_reset(dsi); + struct mtk_phy_timing phy_timing = {}; + if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) + mtk_dsi_cphy_timing(dsi, data_rate, &phy_timing); + else + mtk_dsi_dphy_timing(dsi, data_rate, &phy_timing); + + mtk_dsi_rxtx_control(dsi, mode_flags, lanes); + mdelay(1); + mtk_dsi_reset_phy(dsi); + mtk_dsi_clk_hs_mode_disable(dsi); + mtk_dsi_config_vdo_timing(dsi, mode_flags, format, lanes, edid, &phy_timing); + mtk_dsi_clk_hs_mode_enable(dsi); + } + if (init_commands) - mipi_panel_parse_init_commands(init_commands, mtk_dsi_cmdq, NULL); - mtk_dsi_set_mode(mode_flags); - mtk_dsi_start(); + mipi_panel_parse_commands(init_commands, mtk_dsi_cmdq, &mode_flags); + + for (unsigned int i = 0; i < num_dsi; i++) + mtk_dsi_set_mode(dsi_mipi_regs[i].dsi_reg, mode_flags); + + mtk_dsi_enable_and_start(is_dsi_dual_channel); return 0; } + +int mtk_dsi_panel_poweroff(u32 mode_flags, const u8 *poweroff_cmds) +{ + int ret; + unsigned int num_dsi = (mode_flags & MIPI_DSI_DUAL_CHANNEL) ? 2 : 1; + + /* Stop DSI-0 engine */ + mtk_dsi_stop(dsi_mipi_regs[0].dsi_reg); + + /* Wait for DSI engines to become idle */ + for (unsigned int i = 0; i < num_dsi; i++) { + struct dsi_regs *dsi = dsi_mipi_regs[i].dsi_reg; + + if (!wait_ms(20, !(read32(&dsi->dsi_intsta) & DSI_BUSY))) { + u32 intsta = read32(&dsi->dsi_intsta); + + printk(BIOS_ERR, "%s: Timeout (20ms) waiting for DSI-%d idle " + "and the panel may not power-off properly. " + "DSI_INTSTA=0x%08x.\n", + __func__, i, intsta); + return -1; + } + + write32(&dsi->dsi_intsta, 0); + write32(&dsi->dsi_mode_ctrl, CMD_MODE); + } + + /* Send panel poweroff commands */ + ret = mipi_panel_parse_commands(poweroff_cmds, mtk_dsi_cmdq, + &mode_flags); + + /* Final shutdown: stop + disable PHY */ + mtk_dsi_stop(dsi_mipi_regs[0].dsi_reg); + + for (unsigned int i = 0; i < num_dsi; i++) { + struct dsi_regs *dsi = dsi_mipi_regs[i].dsi_reg; + + write32(&dsi->dsi_phy_lccon, 0x0); + } + + return ret; +} diff --git a/src/soc/mediatek/common/include/soc/display.h b/src/soc/mediatek/common/include/soc/display.h index ca8782280e3..87a6a04d9db 100644 --- a/src/soc/mediatek/common/include/soc/display.h +++ b/src/soc/mediatek/common/include/soc/display.h @@ -4,6 +4,7 @@ #define __SOC_MEDIATEK_COMMON_DISPLAY_H__ #include +#include #include #include @@ -31,12 +32,15 @@ struct panel_description { struct panel_description *get_active_panel(void); void mtk_display_disable_secure_mode(void); int mtk_display_init(void); +int mtk_mipi_panel_poweroff(void); void mtk_ddp_init(void); -void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, - enum disp_path_sel path, struct dsc_config *dsc_config); +u32 mtk_get_vrefresh(const struct edid *edid); void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, struct dsc_config *dsc_config); -void mtk_ddp_ovlsys_start(uintptr_t fb_addr); +void mtk_ddp_ovlsys_start(uintptr_t fb_addr, const struct edid *edid, + enum disp_path_sel path); + +const struct panel_serializable_data *mtk_get_mipi_panel_data(void); #endif diff --git a/src/soc/mediatek/common/include/soc/display_dsi.h b/src/soc/mediatek/common/include/soc/display_dsi.h index 62bdb3cca32..6a51dca55a4 100644 --- a/src/soc/mediatek/common/include/soc/display_dsi.h +++ b/src/soc/mediatek/common/include/soc/display_dsi.h @@ -51,5 +51,6 @@ enum { /* Public API for common display code (display.c). */ int mtk_dsi_init(u32 mode_flags, u32 format, u32 lanes, const struct edid *edid, const u8 *init_commands); +int mtk_dsi_panel_poweroff(u32 mode_flags, const u8 *poweroff_cmds); #endif /* SOC_MEDIATEK_DISPLAY_DSI_H */ diff --git a/src/soc/mediatek/common/include/soc/dsi_common.h b/src/soc/mediatek/common/include/soc/dsi_common.h index e06701f490b..62bff790a94 100644 --- a/src/soc/mediatek/common/include/soc/dsi_common.h +++ b/src/soc/mediatek/common/include/soc/dsi_common.h @@ -4,8 +4,8 @@ #define SOC_MEDIATEK_DSI_COMMON_H #include +#include #include -#include #include #include #include @@ -59,6 +59,7 @@ enum { LOOSELY_PS_18BIT_RGB666 = (1 << 16), PACKED_PS_18BIT_RGB666 = (2 << 16), PACKED_PS_24BIT_RGB888 = (3 << 16), + COMPRESSED_PIXEL_STREAM_V2 = (5 << 16), DSI_PSCON_CUSTOM_HEADER_SHIFT = 26, }; @@ -173,7 +174,8 @@ void mtk_dsi_override_phy_timing(struct mtk_phy_timing *timing); void mtk_dsi_cphy_enable(struct mipi_tx_regs *mipi_tx_reg); void mtk_dsi_cphy_enable_cmdq_6byte(struct dsi_regs *dsi_reg); void mtk_dsi_cphy_lane_sel_setting(struct mipi_tx_regs *mipi_tx_reg); -void mtk_dsi_cphy_timing(u32 data_rate, struct mtk_phy_timing *timing); +void mtk_dsi_cphy_timing(struct dsi_regs *dsi_reg, u32 data_rate, + struct mtk_phy_timing *timing); void mtk_dsi_cphy_vdo_timing(const u32 lanes, const struct edid *edid, const struct mtk_phy_timing *phy_timing, const u32 bytes_per_pixel, const u32 hbp, const u32 hfp, diff --git a/src/soc/mediatek/common/low_battery.c b/src/soc/mediatek/common/low_battery.c new file mode 100644 index 00000000000..7a00341d8e7 --- /dev/null +++ b/src/soc/mediatek/common/low_battery.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include + +void __weak poweroff(void) +{ + if (!CONFIG(EC_GOOGLE_CHROMEEC)) + return; + google_chromeec_ap_poweroff(); +} + +static void low_battery_poweroff(void *unused) +{ + if (!platform_is_low_battery_shutdown_needed()) + return; + + printk(BIOS_INFO, "%s: powering off...\n", __func__); + + platform_handle_emergency_low_battery(); + poweroff(); +} + +BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, low_battery_poweroff, NULL); diff --git a/src/soc/mediatek/common/mtk_mipi_cphy.c b/src/soc/mediatek/common/mtk_mipi_cphy.c index 3e783769510..ecf7915f674 100644 --- a/src/soc/mediatek/common/mtk_mipi_cphy.c +++ b/src/soc/mediatek/common/mtk_mipi_cphy.c @@ -42,7 +42,8 @@ void mtk_dsi_cphy_enable_cmdq_6byte(struct dsi_regs *dsi_reg) clrbits32(&dsi_reg->dsi_cmd_type1_hs, CMD_CPHY_6BYTE_EN); } -void mtk_dsi_cphy_timing(u32 data_rate, struct mtk_phy_timing *timing) +void mtk_dsi_cphy_timing(struct dsi_regs *dsi_reg, u32 data_rate, + struct mtk_phy_timing *timing) { u32 cycle_time, value; @@ -72,14 +73,14 @@ void mtk_dsi_cphy_timing(u32 data_rate, struct mtk_phy_timing *timing) value = timing->lpx | timing->da_hs_prepare << 8 | timing->da_hs_zero << 16 | timing->da_hs_trail << 24; - write32(&dsi0->dsi_phy_timecon0, value); + write32(&dsi_reg->dsi_phy_timecon0, value); value = timing->ta_go | timing->ta_sure << 8 | timing->ta_get << 16 | timing->da_hs_exit << 24; - write32(&dsi0->dsi_phy_timecon1, value); + write32(&dsi_reg->dsi_phy_timecon1, value); - write32(&dsi0->dsi_cphy_con0, 0x012C0003); - write32(&dsi0->dsi_bllp_wc, 16 * 3); + write32(&dsi_reg->dsi_cphy_con0, 0x012C0003); + write32(&dsi_reg->dsi_bllp_wc, 16 * 3); } void mtk_dsi_cphy_vdo_timing(const u32 lanes, diff --git a/src/soc/mediatek/mt8186/ddp.c b/src/soc/mediatek/mt8186/ddp.c index df796fcba49..f1d17bc502e 100644 --- a/src/soc/mediatek/mt8186/ddp.c +++ b/src/soc/mediatek/mt8186/ddp.c @@ -142,10 +142,15 @@ void mtk_ddp_init(void) write32((void *)(SMI_LARB0 + SMI_LARB_PORT_L0_OVL_RDMA0), 0); } -void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, - enum disp_path_sel path, struct dsc_config *dsc_config) +void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, + struct dsc_config *dsc_config) { + u32 bpp = edid->framebuffer_bits_per_pixel / 8; + u32 width = edid->mode.ha; + u32 height = edid->mode.va; + u32 vrefresh = mtk_get_vrefresh(edid); + main_disp_path_setup(width, height, vrefresh); rdma_start(); - ovl_layer_config(fmt, bpp, width, height); + ovl_layer_config(OVL_INFMT_RGBA8888, bpp, width, height); } diff --git a/src/soc/mediatek/mt8188/ddp.c b/src/soc/mediatek/mt8188/ddp.c index dfc0de32170..b5d12271118 100644 --- a/src/soc/mediatek/mt8188/ddp.c +++ b/src/soc/mediatek/mt8188/ddp.c @@ -146,10 +146,15 @@ void mtk_ddp_init(void) write32p(SMI_LARB0 + SMI_LARB_PORT_L0_OVL_RDMA0, 0); } -void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, - enum disp_path_sel path, struct dsc_config *dsc_config) +void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, + struct dsc_config *dsc_config) { + u32 bpp = edid->framebuffer_bits_per_pixel / 8; + u32 width = edid->mode.ha; + u32 height = edid->mode.va; + u32 vrefresh = mtk_get_vrefresh(edid); + main_disp_path_setup(width, height, vrefresh, path); rdma_start(); - ovl_layer_config(fmt, bpp, width, height); + ovl_layer_config(OVL_INFMT_RGBA8888, bpp, width, height); } diff --git a/src/soc/mediatek/mt8189/ddp.c b/src/soc/mediatek/mt8189/ddp.c index 6959fdbc1c2..ec633a911e8 100644 --- a/src/soc/mediatek/mt8189/ddp.c +++ b/src/soc/mediatek/mt8189/ddp.c @@ -138,10 +138,15 @@ void mtk_ddp_init(void) __func__, read32(&smi_larb0->port_l0_ovl_rdma[0])); } -void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, - enum disp_path_sel path, struct dsc_config *dsc_config) +void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, + struct dsc_config *dsc_config) { + u32 bpp = edid->framebuffer_bits_per_pixel / 8; + u32 width = edid->mode.ha; + u32 height = edid->mode.va; + u32 vrefresh = mtk_get_vrefresh(edid); + main_disp_path_setup(width, height, vrefresh, path); rdma_start(); - ovl_layer_config(fmt, bpp, width, height); + ovl_layer_config(OVL_INFMT_RGBA8888, bpp, width, height); } diff --git a/src/soc/mediatek/mt8189/include/soc/dptx_reg.h b/src/soc/mediatek/mt8189/include/soc/dptx_reg.h index af2e6a131e5..b65d6c2bed6 100644 --- a/src/soc/mediatek/mt8189/include/soc/dptx_reg.h +++ b/src/soc/mediatek/mt8189/include/soc/dptx_reg.h @@ -5,6 +5,7 @@ #include +#define BIAS_POWER_ON (0x03 << 3) #define DP_PHY_DIG_TX_CTL_0 0x1444 #define RGS_AUX_LDO_EN_READY_MASK BIT(0) #define DRIVING_FORCE 0x18 diff --git a/src/soc/mediatek/mt8195/ddp.c b/src/soc/mediatek/mt8195/ddp.c index 28fc34b68df..e84be64021a 100644 --- a/src/soc/mediatek/mt8195/ddp.c +++ b/src/soc/mediatek/mt8195/ddp.c @@ -151,11 +151,16 @@ void mtk_ddp_init(void) write32((void *)(SMI_LARB0 + SMI_LARB_PORT_L0_OVL_RDMA0), 0); } -void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, - enum disp_path_sel path, struct dsc_config *dsc_config) +void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, + struct dsc_config *dsc_config) { + u32 bpp = edid->framebuffer_bits_per_pixel / 8; + u32 width = edid->mode.ha; + u32 height = edid->mode.va; + u32 vrefresh = mtk_get_vrefresh(edid); + main_disp_path_setup(width, height, vrefresh); rdma_start(); - ovl_layer_config(fmt, bpp, width, height); + ovl_layer_config(OVL_INFMT_RGBA8888, bpp, width, height); ovl_bgclr_in_sel(1); } diff --git a/src/soc/mediatek/mt8196/Kconfig b/src/soc/mediatek/mt8196/Kconfig index 90c85007efa..c6eedf9341c 100644 --- a/src/soc/mediatek/mt8196/Kconfig +++ b/src/soc/mediatek/mt8196/Kconfig @@ -18,6 +18,7 @@ config SOC_MEDIATEK_MT8196 select ARM64_USE_ARCH_TIMER select PCI select EARLY_MMU_INIT + select MEDIATEK_DSI_DUAL_CHANNEL if SOC_MEDIATEK_MT8196 diff --git a/src/soc/mediatek/mt8196/Makefile.mk b/src/soc/mediatek/mt8196/Makefile.mk index cc7ec0ad11c..1a6159079ed 100644 --- a/src/soc/mediatek/mt8196/Makefile.mk +++ b/src/soc/mediatek/mt8196/Makefile.mk @@ -64,12 +64,15 @@ ramstage-y += ../common/dp/dp_intf_v2.c ramstage-y += ../common/dp/dptx_common.c ../common/dp/dptx_v2.c dptx.c ramstage-y += ../common/dp/dptx_hal_common.c ../common/dp/dptx_hal_v2.c dptx_hal.c ramstage-y += ../common/dramc_info.c +ramstage-y += ../common/dsi_common.c dsi.c ramstage-y += ../common/early_init.c ramstage-y += ../common/emi.c ramstage-y += gpueb.c ramstage-y += l2c_ops.c +ramstage-y += ../common/low_battery.c ramstage-y += ../common/mcu.c mcupm.c ramstage-y += ../common/mmu_operations.c +ramstage-y += ../common/mtk_mipi_dphy.c mtk_mipi_dphy.c ramstage-$(CONFIG_PCI) += ../common/pcie.c pcie.c ramstage-$(CONFIG_COMMONLIB_STORAGE_MMC) += msdc.c ramstage-y += ../common/mt6363.c mt6363.c diff --git a/src/soc/mediatek/mt8196/booker.c b/src/soc/mediatek/mt8196/booker.c index 13a0248653b..2525043f5fc 100644 --- a/src/soc/mediatek/mt8196/booker.c +++ b/src/soc/mediatek/mt8196/booker.c @@ -4,6 +4,7 @@ #include #include #include +#include #define REG_READ_ONLY_HASH_VALUE (MCUCFG_BASE + 0x059C) #define REG_MCUSYS_RESERVED_REG2 (MCUCFG_BASE + 0xFFE8) @@ -61,6 +62,9 @@ void booker_mte_init(uint64_t mte_tag_addr) { int i; + /* Notify MCUPM to configure MTE on resume path. */ + setbits32p(MTE_ENABLE_REG, 0xF); + printk(BIOS_DEBUG, "%s: MTE tag addr %#llx\n", __func__, mte_tag_addr); /* Setting MTU TAG */ diff --git a/src/soc/mediatek/mt8196/ddp.c b/src/soc/mediatek/mt8196/ddp.c index 380d52f1713..5c4366a80e2 100644 --- a/src/soc/mediatek/mt8196/ddp.c +++ b/src/soc/mediatek/mt8196/ddp.c @@ -11,6 +11,30 @@ #define SIZE(w, h) ((u32)(h) << 16 | (w)) #define DUAL_PIPE(path) ((path) == DISP_PATH_DUAL_MIPI) +#define DSC_EN BIT(0) +#define DSC_DUAL_INOUT BIT(2) +#define DSC_IN_SRC_SEL BIT(3) +#define DSC_BYPASS BIT(4) +#define DSC_RELAY BIT(5) +#define DSC_PT_MEM_EN BIT(7) +#define DSC_EMPTY_FLAG_SEL GENMASK(15, 14) +#define DSC_EMPTY_FLAG_ALWAYS_LOW BIT(15) +#define DSC_UFOE_SEL BIT(16) +#define DSC_ZERO_FIFO_STALL_DISABLE BIT(20) + +#define DSC_INTEN_SEL GENMASK(6, 0) +#define DSC_ZERO_FIFO BIT(2) + +#define DSC_INTACK_SEL GENMASK(6, 0) +#define DSC_INTACK_BUF_UNDERFLOW BIT(6) + +#define DSC_PIC_PREPAD_HEIGHT_SEL GENMASK(15, 0) +#define DSC_PIC_PREPAD_WIDTH_SEL GENMASK(31, 16) + +#define ALIGN_PADDING(V, N) (((N) - ((V) % (N))) % (N)) +/* Provide default value for x == 0. */ +#define DEF(x, default) ((x) == 0 ? (default) : (x)) + struct disp_pipe_regs { struct disp_mdp_rsz_regs *const mdp_rsz; struct disp_tdshp_regs *const tdshp; @@ -44,6 +68,248 @@ static const struct disp_pipe_regs disp_pipe1_regs = { .dsc = disp_dsc3_reg, }; +static void dsc_configure_registers(struct disp_dsc_regs *reg, u16 w, u16 h, + const struct dsc_config *dsc_cfg, + const struct edid *edid) +{ + u32 pic_width = edid->mode.ha; + u32 init_delay_limit, init_delay_height; + u32 pic_group_width, pic_height_ext_num; + u32 slice_group_width; + u32 pad_num; + u32 slice_mode; + u32 dsc_cfg_mode = 0x22; + u32 mask; + u32 val; + u32 rgb_swap = 0; + + if (dsc_cfg->bits_per_component == 0xA) + dsc_cfg_mode = 0x828; + + assert(pic_width > 0); + assert(pic_width >= dsc_cfg->slice_width); + assert(dsc_cfg->slice_width > 0); + slice_mode = pic_width / dsc_cfg->slice_width - 1; + pic_group_width = DIV_ROUND_UP(pic_width, 3); + pic_height_ext_num = DIV_ROUND_UP(h, dsc_cfg->slice_height); + slice_group_width = DIV_ROUND_UP(dsc_cfg->slice_width, 3); + pad_num = ALIGN_PADDING(dsc_cfg->slice_chunk_size * (slice_mode + 1), 3); + init_delay_limit = DIV_ROUND_UP(dsc_cfg->initial_xmit_delay, 3); + init_delay_limit = DIV_ROUND_UP((128 + init_delay_limit) * 3, dsc_cfg->slice_width); + init_delay_height = MIN(15, init_delay_limit); + + mask = DSC_EN | DSC_DUAL_INOUT | DSC_IN_SRC_SEL | DSC_BYPASS | DSC_RELAY | + DSC_PT_MEM_EN | DSC_EMPTY_FLAG_SEL | DSC_UFOE_SEL | + DSC_ZERO_FIFO_STALL_DISABLE; + val = DSC_PT_MEM_EN | DSC_EMPTY_FLAG_ALWAYS_LOW | DSC_UFOE_SEL | + DSC_ZERO_FIFO_STALL_DISABLE; + + clrsetbits32(®->dsc_con, mask, val); + clrsetbits32(®->dsc_inten, DSC_INTEN_SEL, 0x7F); + clrsetbits32(®->dsc_intack, DSC_INTACK_SEL, DSC_INTACK_BUF_UNDERFLOW); + + write32(®->dsc_spr, 0x0); + + val = w | (pic_group_width - 1) << 16; + write32(®->pic_w, val); + + val = (h - 1) | (pic_height_ext_num * dsc_cfg->slice_height - 1) << 16; + write32(®->pic_h, val); + + val = dsc_cfg->slice_width | (slice_group_width - 1) << 16; + write32(®->dsc_slice_w, val); + + val = (dsc_cfg->slice_height - 1) | (pic_height_ext_num - 1) << 16 | + (dsc_cfg->slice_width % 3) << 30; + write32(®->dsc_slice_h, val); + + val = dsc_cfg->slice_chunk_size | + (((dsc_cfg->slice_chunk_size << slice_mode) + 2) / 3) << 16; + write32(®->chunk_size, val); + + mask = GENMASK(23, 0); + val = dsc_cfg->slice_chunk_size * dsc_cfg->slice_height; + clrsetbits32(®->dsc_buf_size, mask, val); + + mask = BIT(0) | BIT(2) | GENMASK(11, 8); + val = slice_mode | rgb_swap << 2 | init_delay_height << 8; + clrsetbits32(®->dsc_mode, mask, val); + + write32(®->dsc_cfg, dsc_cfg_mode); + + mask = GENMASK(2, 0); + val = pad_num; + clrsetbits32(®->dsc_pad, mask, val); + + val = dsc_cfg->slice_width | pic_width << 16; + write32(®->dsc_enc_width, val); + + mask = DSC_PIC_PREPAD_HEIGHT_SEL | DSC_PIC_PREPAD_WIDTH_SEL; + val = h | w << 16; + clrsetbits32(®->dsc_pic_pre_pad_size, mask, val); + + setbits32(®->dsc_dbg_con, BIT(9)); + + write32(®->dsc_obuf, 0x410); + + DEFINE_BITFIELD(LINE_BUF_DEPTH, 3, 0) + DEFINE_BITFIELD(BITS_PER_COMPONENT, 7, 4) + DEFINE_BITFIELD(BITS_PER_PIXEL, 17, 8) + DEFINE_BIT(CONVERT_RGB, 18) + DEFINE_BIT(BLOCK_PRED_ENABLE, 19) + SET32_BITFIELDS(®->dsc_pps[0], + LINE_BUF_DEPTH, DEF(dsc_cfg->line_buf_depth, 0x9), + BITS_PER_COMPONENT, DEF(dsc_cfg->bits_per_component, 0x8), + BITS_PER_PIXEL, DEF(dsc_cfg->bits_per_pixel, 0x80), + CONVERT_RGB, DEF((u8)dsc_cfg->convert_rgb, 1), + BLOCK_PRED_ENABLE, DEF((u8)dsc_cfg->block_pred_enable, 0)); + + DEFINE_BITFIELD(INITIAL_DEC_DELAY, 31, 16) + DEFINE_BITFIELD(INITIAL_XMIT_DELAY, 15, 0) + WRITE32_BITFIELDS(®->dsc_pps[1], + INITIAL_DEC_DELAY, DEF(dsc_cfg->initial_dec_delay, 0x268), + INITIAL_XMIT_DELAY, DEF(dsc_cfg->initial_xmit_delay, 0x200)); + + DEFINE_BITFIELD(INITIAL_SCALE_VALUE, 15, 0) + DEFINE_BITFIELD(SCALE_INCREMENT_INTERVAL, 31, 16) + WRITE32_BITFIELDS(®->dsc_pps[2], + INITIAL_SCALE_VALUE, DEF(dsc_cfg->initial_scale_value, 0x20), + SCALE_INCREMENT_INTERVAL, + DEF(dsc_cfg->scale_increment_interval, 0x387)); + + DEFINE_BITFIELD(FIRST_LINE_BPG_OFFSET, 31, 16) + DEFINE_BITFIELD(SCALE_DECREMENT_INTERVAL, 15, 0) + WRITE32_BITFIELDS(®->dsc_pps[3], + FIRST_LINE_BPG_OFFSET, DEF(dsc_cfg->first_line_bpg_offset, 0xc), + SCALE_DECREMENT_INTERVAL, + DEF(dsc_cfg->scale_decrement_interval, 0xa)); + + DEFINE_BITFIELD(NFL_BPG_OFFSET, 15, 0) + DEFINE_BITFIELD(SLICE_BPG_OFFSET, 31, 16) + WRITE32_BITFIELDS(®->dsc_pps[4], + NFL_BPG_OFFSET, DEF(dsc_cfg->nfl_bpg_offset, 0x319), + SLICE_BPG_OFFSET, DEF(dsc_cfg->slice_bpg_offset, 0x263)); + + DEFINE_BITFIELD(INITIAL_OFFSET, 15, 0) + DEFINE_BITFIELD(FINAL_OFFSET, 31, 16) + WRITE32_BITFIELDS(®->dsc_pps[5], + INITIAL_OFFSET, DEF(dsc_cfg->initial_offset, 0x1800), + FINAL_OFFSET, DEF(dsc_cfg->final_offset, 0x10f0)); + + DEFINE_BITFIELD(FLATNESS_MIN_QP, 4, 0) + DEFINE_BITFIELD(FLATNESS_MAX_QP, 12, 8) + DEFINE_BITFIELD(RC_MODEL_SIZE, 31, 16) + SET32_BITFIELDS(®->dsc_pps[6], + FLATNESS_MIN_QP, DEF(dsc_cfg->flatness_min_qp, 0x3), + FLATNESS_MAX_QP, DEF(dsc_cfg->flatness_max_qp, 0xc), + RC_MODEL_SIZE, DEF(dsc_cfg->rc_model_size, 0x2000)); + + DEFINE_BITFIELD(RC_TGT_OFFSET_LOW, 31, 28) + DEFINE_BITFIELD(RC_TGT_OFFSET_HIGH, 27, 24) + DEFINE_BITFIELD(RC_QUANT_INCR_LIMIT1, 20, 16) + DEFINE_BITFIELD(RC_QUANT_INCR_LIMIT0, 12, 8) + DEFINE_BITFIELD(RC_EDGE_FACTOR, 7, 0) + WRITE32_BITFIELDS(®->dsc_pps[7], + RC_TGT_OFFSET_LOW, dsc_cfg->rc_tgt_offset_low, + RC_TGT_OFFSET_HIGH, dsc_cfg->rc_tgt_offset_high, + RC_QUANT_INCR_LIMIT1, dsc_cfg->rc_quant_incr_limit1, + RC_QUANT_INCR_LIMIT0, dsc_cfg->rc_quant_incr_limit0, + RC_EDGE_FACTOR, dsc_cfg->rc_edge_factor); + + DEFINE_BITFIELD(RC_BUF_THRESH_3, 31, 24) + DEFINE_BITFIELD(RC_BUF_THRESH_2, 23, 16) + DEFINE_BITFIELD(RC_BUF_THRESH_1, 15, 8) + DEFINE_BITFIELD(RC_BUF_THRESH_0, 7, 0) + WRITE32_BITFIELDS(®->dsc_pps[8], + RC_BUF_THRESH_3, dsc_cfg->rc_buf_thresh[3], + RC_BUF_THRESH_2, dsc_cfg->rc_buf_thresh[2], + RC_BUF_THRESH_1, dsc_cfg->rc_buf_thresh[1], + RC_BUF_THRESH_0, dsc_cfg->rc_buf_thresh[0]); + + DEFINE_BITFIELD(RC_BUF_THRESH_7, 31, 24) + DEFINE_BITFIELD(RC_BUF_THRESH_6, 23, 16) + DEFINE_BITFIELD(RC_BUF_THRESH_5, 15, 8) + DEFINE_BITFIELD(RC_BUF_THRESH_4, 7, 0) + WRITE32_BITFIELDS(®->dsc_pps[9], + RC_BUF_THRESH_7, dsc_cfg->rc_buf_thresh[7], + RC_BUF_THRESH_6, dsc_cfg->rc_buf_thresh[6], + RC_BUF_THRESH_5, dsc_cfg->rc_buf_thresh[5], + RC_BUF_THRESH_4, dsc_cfg->rc_buf_thresh[4]); + + DEFINE_BITFIELD(RC_BUF_THRESH_11, 31, 24) + DEFINE_BITFIELD(RC_BUF_THRESH_10, 23, 16) + DEFINE_BITFIELD(RC_BUF_THRESH_9, 15, 8) + DEFINE_BITFIELD(RC_BUF_THRESH_8, 7, 0) + WRITE32_BITFIELDS(®->dsc_pps[10], + RC_BUF_THRESH_11, dsc_cfg->rc_buf_thresh[11], + RC_BUF_THRESH_10, dsc_cfg->rc_buf_thresh[10], + RC_BUF_THRESH_9, dsc_cfg->rc_buf_thresh[9], + RC_BUF_THRESH_8, dsc_cfg->rc_buf_thresh[8]); + + DEFINE_BITFIELD(RC_BUF_THRESH_13, 15, 8) + DEFINE_BITFIELD(RC_BUF_THRESH_12, 7, 0) + WRITE32_BITFIELDS(®->dsc_pps[11], + RC_BUF_THRESH_13, dsc_cfg->rc_buf_thresh[13], + RC_BUF_THRESH_12, dsc_cfg->rc_buf_thresh[12]); + + DEFINE_BITFIELD(RC_RANGE_BPG_OFFSET_ODD, 31, 26) + DEFINE_BITFIELD(RC_RANGE_MAX_QP_ODD, 25, 21) + DEFINE_BITFIELD(RC_RANGE_MIN_QP_ODD, 20, 16) + DEFINE_BITFIELD(RC_RANGE_BPG_OFFSET_EVEN, 15, 10) + DEFINE_BITFIELD(RC_RANGE_MAX_QP_EVEN, 9, 5) + DEFINE_BITFIELD(RC_RANGE_MIN_QP_EVEN, 4, 0) + for (int i = 0; i < 7; i++) { + WRITE32_BITFIELDS(®->dsc_pps_rc_range_params[i], + RC_RANGE_BPG_OFFSET_ODD, + dsc_cfg->rc_range_params[2 * i + 1].range_bpg_offset, + RC_RANGE_MAX_QP_ODD, + dsc_cfg->rc_range_params[2 * i + 1].range_max_qp, + RC_RANGE_MIN_QP_ODD, + dsc_cfg->rc_range_params[2 * i + 1].range_min_qp, + RC_RANGE_BPG_OFFSET_EVEN, + dsc_cfg->rc_range_params[2 * i].range_bpg_offset, + RC_RANGE_MAX_QP_EVEN, + dsc_cfg->rc_range_params[2 * i].range_max_qp, + RC_RANGE_MIN_QP_EVEN, + dsc_cfg->rc_range_params[2 * i].range_min_qp); + } + /* Special case for the last register */ + WRITE32_BITFIELDS(®->dsc_pps_rc_range_params[7], + RC_RANGE_BPG_OFFSET_EVEN, + dsc_cfg->rc_range_params[14].range_bpg_offset, + RC_RANGE_MAX_QP_EVEN, dsc_cfg->rc_range_params[14].range_max_qp, + RC_RANGE_MIN_QP_EVEN, dsc_cfg->rc_range_params[14].range_min_qp); + + if (dsc_cfg->dsc_version_minor == 1) + write32(®->dsc_shadow, 0x20); + else if (dsc_cfg->dsc_version_minor == 2) + write32(®->dsc_shadow, 0x40); + else + printk(BIOS_WARNING, "%s : wrong version minor:%d\n", __func__, + dsc_cfg->dsc_version_minor); +} + +static void dsc_config(struct disp_dsc_regs *reg, u16 w, u16 h, + const struct dsc_config *dsc_cfg, + const struct edid *edid) +{ + bool dsc_enable; + + dsc_enable = (dsc_cfg && dsc_cfg->dsc_version_major); + printk(BIOS_INFO, "%s: w:%d, h:%d, dsc enable:%d\n", __func__, w, h, dsc_enable); + + if (!dsc_enable) { + setbits32(®->dsc_con, DSC_RELAY); + clrsetbits32(®->chunk_size, GENMASK(31, 16), w << 16); + clrsetbits32(®->pic_w, GENMASK(15, 0), w); + clrsetbits32(®->pic_h, GENMASK(15, 0), h); + printk(BIOS_INFO, "%s: DSC_relay mode\n", __func__); + return; + } + + dsc_configure_registers(reg, w, h, dsc_cfg, edid); +} + static void blender_config(struct blender *reg, u16 width, u16 height, enum mtk_disp_blender_layer type) { @@ -157,17 +423,9 @@ static void dither_start(struct disp_dither_regs *reg) setbits32(®->en, BIT(0)); } -static void dsc_config(struct disp_dsc_regs *reg, u16 width, u16 height) -{ - write32(®->dsc_con, BIT(5)); - write32(®->pic_w, width); - write32(®->pic_h, height); - write32(®->chunk_size, width << 16); -} - static void dsc_start(struct disp_dsc_regs *reg) { - setbits32(®->dsc_con, BIT(0)); + setbits32(®->dsc_con, DSC_EN); } static void ovlsys_path_connect(struct ovlsys_cfg *reg) @@ -325,7 +583,8 @@ static void disp_config_blender(struct blender *const blenders[], size_t size, u } } -static void main_disp_path_setup(u16 width, u16 height, u32 vrefresh, enum disp_path_sel path) +static void main_disp_path_setup(u16 width, u16 height, u32 vrefresh, enum disp_path_sel path, + const struct dsc_config *dsc_cfg, const struct edid *edid) { u16 w = width; size_t num_pipe = DUAL_PIPE(path) ? 2 : 1; @@ -361,7 +620,7 @@ static void main_disp_path_setup(u16 width, u16 height, u32 vrefresh, enum disp_ postmask_start(pipes[i].postmask); dither_config(pipes[i].dither, w, height); dither_start(pipes[i].dither); - dsc_config(pipes[i].dsc, w, height); + dsc_config(pipes[i].dsc, w, height, dsc_cfg, edid); dsc_start(pipes[i].dsc); } @@ -429,20 +688,37 @@ void mtk_ddp_init(void) disp_clock_on(); } -void mtk_ddp_soc_mode_set(u32 fmt, u32 bpp, u32 width, u32 height, u32 vrefresh, - enum disp_path_sel path, struct dsc_config *dsc_config) +void mtk_ddp_mode_set(const struct edid *edid, enum disp_path_sel path, + struct dsc_config *dsc_config) { + u32 bpp = edid->framebuffer_bits_per_pixel / 8; + u32 width = edid->mode.ha; + u32 height = edid->mode.va; + u32 vrefresh = mtk_get_vrefresh(edid); + if (width > 0x1FFF || height > 0x1FFF) printk(BIOS_WARNING, "%s: w/h: %d/%d exceed hw limit %u\n", __func__, width, height, 0x1FFF); - main_disp_path_setup(width, height, vrefresh, path); - ovlsys_layer_config(fmt, bpp, width, height, path); + main_disp_path_setup(width, height, vrefresh, path, dsc_config, edid); + ovlsys_layer_config(OVL_INFMT_RGBA8888, bpp, width, height, path); } -void mtk_ddp_ovlsys_start(uintptr_t fb_addr) +void mtk_ddp_ovlsys_start(uintptr_t fb_addr, const struct edid *edid, + enum disp_path_sel path) { + uint32_t offset; + write32(&ovl_exdma2_reg->ovl_addr, fb_addr); setbits32(&ovl_exdma2_reg->ovl_en, BIT(0)); setbits32(&ovl_exdma2_reg->ovl_l_en, BIT(0)); setbits32(&ovl_blenders[0]->bld_l_en, BIT(0)); + + if (!DUAL_PIPE(path)) + return; + + offset = edid->x_resolution * edid->framebuffer_bits_per_pixel / 8 / 2; + write32(&ovl1_exdma2_reg->ovl_addr, fb_addr + offset); + setbits32(&ovl1_exdma2_reg->ovl_en, BIT(0)); + setbits32(&ovl1_exdma2_reg->ovl_l_en, BIT(0)); + setbits32(&ovl1_blenders[0]->bld_l_en, BIT(0)); } diff --git a/src/soc/mediatek/mt8196/dsi.c b/src/soc/mediatek/mt8196/dsi.c new file mode 100644 index 00000000000..0ea12b29313 --- /dev/null +++ b/src/soc/mediatek/mt8196/dsi.c @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#include +#include +#include +#include +#include + +#define RG_DSI_PRD_REF_SEL GENMASK(5, 0) +#define RG_DSI_PRD_REF_MINI 0 +#define RG_DSI_PRD_REF_DEF 4 +#define RG_DSI_PRD_REF_MAX 7 + +void mtk_dsi_configure_mipi_tx(struct mipi_tx_regs *mipi_tx_reg, u32 data_rate, + u32 lanes, bool is_cphy) +{ + unsigned int txdiv0; + u64 pcw; + + /* Select different voltage when different data rate */ + if (data_rate < (u32)2500 * MHz) { + clrsetbits32(&mipi_tx_reg->voltage_sel, RG_DSI_PRD_REF_SEL, RG_DSI_PRD_REF_MINI); + write32(&mipi_tx_reg->cdphy_preserved, 0xFFFF00F0); + } else { + clrsetbits32(&mipi_tx_reg->voltage_sel, RG_DSI_PRD_REF_SEL, RG_DSI_PRD_REF_DEF); + write32(&mipi_tx_reg->cdphy_preserved, 0xFFFF0030); + } + + if (data_rate >= 2000 * MHz) { + txdiv0 = 0; + } else if (data_rate >= 1000 * MHz) { + txdiv0 = 1; + } else if (data_rate >= 500 * MHz) { + txdiv0 = 2; + } else if (data_rate > 250 * MHz) { + /* (data_rate == 250MHz) is a special case that should go to the + else-block below (txdiv0 = 4) */ + txdiv0 = 3; + } else { + /* MIN = 125 */ + assert(data_rate >= MTK_DSI_DATA_RATE_MIN_MHZ * MHz); + txdiv0 = 4; + } + + if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) + mtk_dsi_cphy_lane_sel_setting(mipi_tx_reg); + + clrbits32(&mipi_tx_reg->pll_con4, BIT(11) | BIT(10)); + setbits32(&mipi_tx_reg->pll_pwr, AD_DSI_PLL_SDM_PWR_ON); + udelay(30); + clrbits32(&mipi_tx_reg->pll_pwr, AD_DSI_PLL_SDM_ISO_EN); + + pcw = (u64)(data_rate >> 1) * (1 << txdiv0); + pcw <<= 24; + pcw /= CLK26M_HZ; + + write32(&mipi_tx_reg->pll_con0, pcw); + clrsetbits32(&mipi_tx_reg->pll_con1, RG_DSI_PLL_POSDIV, txdiv0 << 8); + udelay(30); + setbits32(&mipi_tx_reg->pll_con1, RG_DSI_PLL_EN); + + /* BG_LPF_EN / BG_CORE_EN */ + write32(&mipi_tx_reg->lane_con, 0x3FFF0180); + udelay(40); + write32(&mipi_tx_reg->lane_con, 0x3FFF00C0); + + if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) + mtk_dsi_cphy_enable(mipi_tx_reg); + + /* Switch OFF each Lane */ + clrbits32(&mipi_tx_reg->d0_sw_ctl_en, DSI_SW_CTL_EN); + clrbits32(&mipi_tx_reg->d1_sw_ctl_en, DSI_SW_CTL_EN); + clrbits32(&mipi_tx_reg->d2_sw_ctl_en, DSI_SW_CTL_EN); + clrbits32(&mipi_tx_reg->d3_sw_ctl_en, DSI_SW_CTL_EN); + clrbits32(&mipi_tx_reg->ck_sw_ctl_en, DSI_SW_CTL_EN); + + if (CONFIG(MEDIATEK_DSI_CPHY) && is_cphy) + mtk_dsi_cphy_disable_ck_mode(mipi_tx_reg); + else + mtk_dsi_dphy_disable_ck_mode(mipi_tx_reg); +} + +void mtk_dsi_reset(struct dsi_regs *dsi_reg) +{ + write32(&dsi_reg->dsi_shadow_ctrl, DSI_FORCE_COMMIT_ALWAYS); + write32(&dsi_reg->dsi_con_ctrl, 1); + write32(&dsi_reg->dsi_con_ctrl, 0); +} diff --git a/src/soc/mediatek/mt8196/include/soc/booker.h b/src/soc/mediatek/mt8196/include/soc/booker.h index 25c2d140af2..ea819429fdf 100644 --- a/src/soc/mediatek/mt8196/include/soc/booker.h +++ b/src/soc/mediatek/mt8196/include/soc/booker.h @@ -5,8 +5,6 @@ #include -#define MTE_TAG_ADDR 0x460E80000 - void booker_init(void); void booker_mte_init(uint64_t mte_tag_addr); diff --git a/src/soc/mediatek/mt8196/include/soc/ddp.h b/src/soc/mediatek/mt8196/include/soc/ddp.h index 2c91747345a..5d0130842fd 100644 --- a/src/soc/mediatek/mt8196/include/soc/ddp.h +++ b/src/soc/mediatek/mt8196/include/soc/ddp.h @@ -539,17 +539,55 @@ check_member(disp_postmask_regs, size, 0x30); struct disp_dsc_regs { u32 dsc_con; - u32 reserved0x4[5]; + u32 dsc_inten; + u32 dsc_intsta; + u32 dsc_intack; + u32 dsc_sta; + u32 dsc_spr; u32 pic_w; u32 pic_h; - u32 reserved0x20; - u32 reserved0x24; + u32 dsc_slice_w; + u32 dsc_slice_h; u32 chunk_size; + u32 dsc_buf_size; + u32 dsc_mode; + u32 dsc_cfg; + u32 dsc_pad; + u32 dsc_enc_width; + u32 dsc_pic_pre_pad_size; + u32 dsc_pic_pre_pad_value; + u32 reserved0[6]; + u32 dsc_dbg_con; + u32 dsc_cksm_mon0; + u32 dsc_cksm_mon1; + u32 dsc_resv; + u32 dsc_obuf; + u32 dsc_obuf_mon; + u32 dsc_mute_con; + u32 dsc_ddren; + u32 dsc_pps[12]; + u32 dsc_pps_rc_range_params[8]; + u32 reserved1[12]; + u32 dsc_dbg[21]; + u32 reserved2[3]; + u32 dsc_enc_dbg[5]; + u32 dsc_enc_cov; + u32 reserved3[34]; + u32 dsc_shadow; + u32 reserved4[7]; + u32 dsc_dummy; + u32 reserved5; + u32 shadow_ctrl; + u32 reserved6; + u32 dsc_up_inten; + u32 dsc_up_intsta; + u32 dsc_up_intack; }; -check_member(disp_dsc_regs, dsc_con, 0x0); -check_member(disp_dsc_regs, pic_w, 0x18); -check_member(disp_dsc_regs, pic_h, 0x1C); -check_member(disp_dsc_regs, chunk_size, 0x28); +check_member(disp_dsc_regs, dsc_slice_w, 0x20); +check_member(disp_dsc_regs, dsc_dbg_con, 0x60); +check_member(disp_dsc_regs, dsc_enc_cov, 0x174); +check_member(disp_dsc_regs, dsc_shadow, 0x200); +check_member(disp_dsc_regs, dsc_up_intack, 0x238); static struct disp_mdp_rsz_regs *const disp_mdp_rsz0_reg = (void *)DISP_MDP_RSZ0_BASE; static struct disp_mdp_rsz_regs *const disp_mdp_rsz1_reg = (void *)DISP_MDP_RSZ1_BASE; diff --git a/src/soc/mediatek/mt8196/include/soc/dptx_reg.h b/src/soc/mediatek/mt8196/include/soc/dptx_reg.h index df7a29630a8..a26328dd24b 100644 --- a/src/soc/mediatek/mt8196/include/soc/dptx_reg.h +++ b/src/soc/mediatek/mt8196/include/soc/dptx_reg.h @@ -5,6 +5,7 @@ #include +#define BIAS_POWER_ON (0x01 << 3) #define DP_PHY_DIG_TX_CTL_0 0x1474 #define RGS_AUX_LDO_EN_READY_MASK BIT(1) #define DRIVING_FORCE 0x30 diff --git a/src/soc/mediatek/mt8196/include/soc/mcupm_plat.h b/src/soc/mediatek/mt8196/include/soc/mcupm_plat.h index 6ce58e4799a..37d62c96df8 100644 --- a/src/soc/mediatek/mt8196/include/soc/mcupm_plat.h +++ b/src/soc/mediatek/mt8196/include/soc/mcupm_plat.h @@ -92,5 +92,6 @@ #define ABNORMALBOOT_REG GPR_BASE_ADDR_MCU(1) #define WARMBOOT_REG GPR_BASE_ADDR_MCU(23) +#define MTE_ENABLE_REG GPR_BASE_ADDR_MCU(25) #endif /* __SOC_MEDIATEK_MT8196_INCLUDE_SOC_MCUPM_PLAT_H__ */ diff --git a/src/soc/mediatek/mt8196/include/soc/memlayout.ld b/src/soc/mediatek/mt8196/include/soc/memlayout.ld index 8c64d661db7..48f4dc77ce2 100644 --- a/src/soc/mediatek/mt8196/include/soc/memlayout.ld +++ b/src/soc/mediatek/mt8196/include/soc/memlayout.ld @@ -13,13 +13,15 @@ SECTIONS { - /* MT8196 has 256KB SRAM. */ + /* MT8196 has 256KB SRAM. Per HW design, on SoC reset via GPIO + * AP_SYSRST_ODL (SYSRSTB), SRAM will be powered down. That means + * SRAM data will be lost across SoC resets. + */ SRAM_START(0x00100000) /* Regions that need to stay in SRAM. */ TTB(0x00100000, 28K) DMA_COHERENT(0x00107000, 4K) STACK(0x00108000, 15K) - WATCHDOG_TOMBSTONE(0x0010bc00, 4) EARLY_INIT(0x0010bc10, 128) /* EMPTY(0x0010bc90, 29K - 144) */ /* @@ -56,7 +58,8 @@ SECTIONS #endif OVERLAP_DECOMPRESSOR_VERSTAGE_ROMSTAGE(0x02096000, 272K) PRERAM_CBFS_CACHE(0x020DA000, 48K) - PRERAM_CBMEM_CONSOLE(0x020E6000, 340K) + PRERAM_CBMEM_CONSOLE(0x020E6000, 339K) + WATCHDOG_TOMBSTONE(0x0213AC00, 4) FSP_ROMSTAGE_INIT_CODE(0x02140000, 64K) SRAM_L2C_END(0x02200000) @@ -73,5 +76,5 @@ SECTIONS RESV_MEMORY_GPUEB(0xA0000000, 2M) /* Reserved memory for the dedicated secured memory allocator of GPU Mali firmware */ GPU_SEC_BUF(0xA2000000, 16M) - FRAMEBUFFER(0xBEC00000, 24M) + FRAMEBUFFER(0xBEC00000, 32M) } diff --git a/src/soc/mediatek/mt8196/mtk_mipi_dphy.c b/src/soc/mediatek/mt8196/mtk_mipi_dphy.c new file mode 100644 index 00000000000..62001ec2544 --- /dev/null +++ b/src/soc/mediatek/mt8196/mtk_mipi_dphy.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#include +#include + +#define PHY_TIMING_DIV(x) (((x) / 8000) + 1) + +void mtk_dsi_dphy_timing_calculation(u32 data_rate_mhz, struct mtk_phy_timing *timing) +{ + u32 temp; + timing->lpx = ALIGN_UP(PHY_TIMING_DIV(80 * data_rate_mhz), 2); + timing->da_hs_prepare = ALIGN_UP(PHY_TIMING_DIV(59 * data_rate_mhz + 4 * 1000), 2); + timing->da_hs_zero = PHY_TIMING_DIV(163 * data_rate_mhz + 11 * 1000) - + timing->da_hs_prepare; + + temp = data_rate_mhz < 740 ? 443 : 420; + timing->da_hs_trail = PHY_TIMING_DIV(66 * data_rate_mhz + temp * 100); + timing->ta_go = 4 * timing->lpx; + timing->ta_sure = 3 * timing->lpx / 2; + timing->ta_get = 5 * timing->lpx; + timing->da_hs_exit = ALIGN_UP(PHY_TIMING_DIV(118 * data_rate_mhz), 2); + timing->da_hs_sync = 1; + + timing->clk_hs_prepare = ALIGN_UP(PHY_TIMING_DIV(57 * data_rate_mhz), 2); + timing->clk_hs_post = PHY_TIMING_DIV(65 * data_rate_mhz + 53 * 1000); + timing->clk_hs_trail = PHY_TIMING_DIV(65 * data_rate_mhz + 52 * 1000); + timing->clk_hs_zero = PHY_TIMING_DIV(330 * data_rate_mhz) - timing->clk_hs_prepare; + timing->clk_hs_exit = PHY_TIMING_DIV(118 * data_rate_mhz); +} diff --git a/src/soc/mediatek/mt8196/soc.c b/src/soc/mediatek/mt8196/soc.c index bacbe0c2c52..1e228c8a54b 100644 --- a/src/soc/mediatek/mt8196/soc.c +++ b/src/soc/mediatek/mt8196/soc.c @@ -1,10 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include #include #include +#include #include #include #include @@ -14,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -54,7 +57,7 @@ static void mte_setup(void) booker_mte_init(mte_start); } -static void soc_init(struct device *dev) +static void fsp_init(void *arg) { uint32_t storage_type = mainboard_get_storage_type(); @@ -63,8 +66,24 @@ static void soc_init(struct device *dev) mtk_fsp_add_param(FSP_PARAM_TYPE_STORAGE, sizeof(storage_type), &storage_type); pi_image_add_mtk_fsp_params(); mtk_fsp_load_and_run(); +} + +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, fsp_init, NULL); +static void mmu_disable_l2c_sram(void *unused) +{ mtk_mmu_disable_l2c_sram(); +} + +BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, mmu_disable_l2c_sram, NULL); + +static void soc_init(struct device *dev) +{ + if (dpm_init()) + printk(BIOS_ERR, "dpm init failed, DVFS may not work\n"); + if (spm_init()) + printk(BIOS_ERR, "spm init failed, Suspend may not work\n"); + sspm_init(); gpueb_init(); mcupm_init(); @@ -90,15 +109,22 @@ static struct device_operations pci_domain_ops = { .enable = &mtk_pcie_domain_enable, }; +static struct device_operations noop_domain_ops = { + .read_resources = &noop_read_resources, + .set_resources = &noop_set_resources, +}; + static void enable_soc_dev(struct device *dev) { if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) { dev->ops = &soc_ops; } else if (dev->path.type == DEVICE_PATH_DOMAIN) { - if (mainboard_needs_pcie_init()) + if (mainboard_needs_pcie_init()) { dev->ops = &pci_domain_ops; - else + } else { printk(BIOS_DEBUG, "Skip setting PCIe ops\n"); + dev->ops = &noop_domain_ops; + } } } diff --git a/src/soc/nvidia/tegra210/include/soc/mipi_display.h b/src/soc/nvidia/tegra210/include/soc/mipi_display.h index e5c7596b979..87591878c8e 100644 --- a/src/soc/nvidia/tegra210/include/soc/mipi_display.h +++ b/src/soc/nvidia/tegra210/include/soc/mipi_display.h @@ -8,7 +8,7 @@ #ifndef __SOC_MIPI_DISPLAY_H__ #define __SOC_MIPI_DISPLAY_H__ -#include +#include /* MIPI DCS pixel formats */ #define MIPI_DCS_PIXEL_FMT_24BIT 7 diff --git a/src/soc/qualcomm/common/Kconfig b/src/soc/qualcomm/common/Kconfig index 5d692779b09..98760cec63f 100644 --- a/src/soc/qualcomm/common/Kconfig +++ b/src/soc/qualcomm/common/Kconfig @@ -41,4 +41,17 @@ config QC_RAMDUMP_ENABLE Ramdump is a debug image that is loaded during a system crash to capture memory contents for post-crash analysis. +config SOC_QUALCOMM_QCLIB_SKIP_MMU_TOGGLE + bool + default n + help + Avoid disabling and re-enabling the MMU during QCLib execution. + + Select this option if the platform's QCLib version supports running + within the existing coreboot MMU configuration without modification. + + Enabling this reduces boot latency by eliminating redundant cache + flushes and TLB invalidations associated with mmu_disable() and + mmu_enable() calls. + endif diff --git a/src/soc/qualcomm/common/include/soc/rpmh.h b/src/soc/qualcomm/common/include/soc/rpmh.h new file mode 100644 index 00000000000..5b7d76de0be --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/rpmh.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_QUALCOMM_RPMH_H__ +#define __SOC_QUALCOMM_RPMH_H__ + +#include +#include + +int rpmh_write(enum rpmh_state state, const struct tcs_cmd *cmd, u32 n); + +int rpmh_write_async(enum rpmh_state state, const struct tcs_cmd *cmd, u32 n); + +int rpmh_write_batch(enum rpmh_state state, const struct tcs_cmd *cmd, u32 *n); + +void rpmh_invalidate(void); + +int rpmh_write_sleep_and_wake(void); + +int rpmh_mode_solver_set(bool enable); + +int rpmh_init_fast_path(struct tcs_cmd *cmd, int n); + +int rpmh_update_fast_path(struct tcs_cmd *cmd, int n, u32 update_mask); + +#endif /* __SOC_QUALCOMM_RPMH_H__ */ diff --git a/src/soc/qualcomm/common/include/soc/rpmh_bcm.h b/src/soc/qualcomm/common/include/soc/rpmh_bcm.h new file mode 100644 index 00000000000..e359a26fcbd --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/rpmh_bcm.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_QUALCOMM_RPMH_BCM_H__ +#define __SOC_QUALCOMM_RPMH_BCM_H__ + +#include + +/** + * rpmh_bcm_vote() - Send BCM (Bus Clock Manager) vote to RPMh + * @resource_name: BCM resource name + * @vote_value: Vote value to send + * + * Return: 0 on success, negative error code on failure + */ +int rpmh_bcm_vote(const char *resource_name, u32 vote_value); + +#endif /* __SOC_QUALCOMM_RPMH_BCM_H__ */ diff --git a/src/soc/qualcomm/common/include/soc/rpmh_internal.h b/src/soc/qualcomm/common/include/soc/rpmh_internal.h new file mode 100644 index 00000000000..23cc3a74566 --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/rpmh_internal.h @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_QUALCOMM_RPMH_INTERNAL_H__ +#define __SOC_QUALCOMM_RPMH_INTERNAL_H__ + +#include +#include + +#define MAX_NAME_LENGTH 20 + +#define USECS_1S 1000000 +#define USECS_100MS 100000 +#define USECS_10MS 10000 +#define USECS_100US 100 +#define USECS_5US 5 +#define LOOP_DELAY_US 1 +#define LOOP_DELAY_10US 10 + +/* DRV Channel IDs */ +enum { + CH0, + CH1, + MAX_CHANNEL, +}; + +#define TCS_TYPE_NR 5 +#define MAX_CMDS_PER_TCS 16 +#define MAX_TCS_PER_TYPE 3 +#define MAX_TCS_NR (MAX_TCS_PER_TYPE * TCS_TYPE_NR) +#define MAX_TCS_SLOTS (MAX_CMDS_PER_TCS * MAX_TCS_PER_TYPE) + +#define SOLVER_PRESENT 1 +#define HW_CHANNEL_PRESENT 2 + +#define CMD_DB_MAX_RESOURCES 250 + +/* TCS types */ +enum { + ACTIVE_TCS, + SLEEP_TCS, + WAKE_TCS, + CONTROL_TCS, + FAST_PATH_TCS, +}; + +/* RSC register offsets */ +enum { + RSC_DRV_TCS_OFFSET, + RSC_DRV_CMD_OFFSET, + DRV_SOLVER_CONFIG, + DRV_PRNT_CHLD_CONFIG, + RSC_DRV_IRQ_ENABLE, + RSC_DRV_IRQ_STATUS, + RSC_DRV_IRQ_CLEAR, + RSC_DRV_CMD_WAIT_FOR_CMPL, + RSC_DRV_CONTROL, + RSC_DRV_STATUS, + RSC_DRV_CMD_ENABLE, + RSC_DRV_CMD_MSGID, + RSC_DRV_CMD_ADDR, + RSC_DRV_CMD_DATA, + RSC_DRV_CMD_STATUS, + RSC_DRV_CMD_RESP_DATA, + RSC_DRV_CHN_TCS_TRIGGER, + RSC_DRV_CHN_TCS_COMPLETE, + RSC_DRV_CHN_SEQ_BUSY, + RSC_DRV_CHN_SEQ_PC, + RSC_DRV_CHN_UPDATE, + RSC_DRV_CHN_BUSY, + RSC_DRV_CHN_EN, +}; + +/* DRV TCS Configuration Information Register */ +#define DRV_NUM_TCS_MASK 0x3F +#define DRV_NUM_TCS_SHIFT 6 +#define DRV_NCPT_MASK 0x1F +#define DRV_NCPT_SHIFT 27 + +struct rsc_drv; + +/** + * struct cache_req: the request object for caching + * + * @addr: the address of the resource + * @sleep_val: the sleep vote + * @wake_val: the wake vote + */ +struct cache_req { + u32 addr; + u32 sleep_val; + u32 wake_val; +}; + +/** + * struct tcs_group: group of Trigger Command Sets (TCS) to send state requests + * to the controller + * + * @drv: The controller. + * @type: Type of the TCS in this group - active, sleep, wake. + * @mask: Mask of the TCSes relative to all the TCSes in the RSC. + * @offset: Start of the TCS group relative to the TCSes in the RSC. + * @num_tcs: Number of TCSes in this type. + * @ncpt: Number of commands in each TCS. + * @req: Requests that are sent from the TCS. + * @slots: Bitmap indicating which slots are occupied. + */ +struct tcs_group { + struct rsc_drv *drv; + int type; + u32 mask; + u32 offset; + int num_tcs; + int ncpt; + const struct tcs_request *req[MAX_TCS_PER_TYPE]; + u32 slots[MAX_TCS_SLOTS / 32]; +}; + +/** + * struct rpmh_request: the message to be sent to rpmh-rsc + * + * @msg: the request + * @cmd: the payload that will be part of the @msg + */ +struct rpmh_request { + struct tcs_request msg; + struct tcs_cmd cmd[MAX_RPMH_PAYLOAD]; +}; + +/** + * struct rpmh_ctrlr: our representation of the controller + * + * @dirty: was the cache updated since flush + * @in_solver_mode: Controller is busy in solver mode + * @flags: Controller specific flags + * @batch_cache: Cache sleep and wake requests sent as batch + * @non_batch_cache_idx: Index for non-batch cache + * @non_batch_cache: Cache for non-batch requests + */ +struct rpmh_ctrlr { + bool dirty; + bool in_solver_mode; + u32 flags; + struct rpmh_request batch_cache[RPMH_ACTIVE_ONLY_STATE]; + u32 non_batch_cache_idx; + struct cache_req *non_batch_cache; +}; + +/** + * struct drv_channel: our representation of the drv channels + * + * @tcs: TCS groups + * @drv: DRV containing the channel + * @initialized: Whether channel is initialized + */ +struct drv_channel { + struct tcs_group tcs[TCS_TYPE_NR]; + struct rsc_drv *drv; + bool initialized; +}; + +/** + * struct rsc_drv: the Direct Resource Voter (DRV) of the + * Resource State Coordinator controller (RSC) + * + * @name: Controller identifier + * @base: Start address of the DRV registers in this controller + * @tcs_base: Start address of the TCS registers in this controller + * @tcs_distance: Distance between two TCSes + * @id: Instance id in the controller (Direct Resource Voter) + * @num_tcs: Number of TCSes in this DRV + * @num_channels: Number of channels in this DRV + * @in_solver_mode: Controller is busy in solver mode + * @initialized: Whether DRV is initialized + * @tcs: TCS groups + * @ch: DRV channels + * @tcs_in_use: S/W state of the TCS bitmap + * @client: Handle to the DRV's client + * @dev: RSC device + * @regs: Register offsets for RSC controller + */ +struct rsc_drv { + char name[MAX_NAME_LENGTH]; + void *base; + void *tcs_base; + u32 tcs_distance; + unsigned int id; + int num_tcs; + int num_channels; + bool in_solver_mode; + bool initialized; + struct tcs_group tcs[TCS_TYPE_NR]; + struct drv_channel ch[MAX_CHANNEL]; + u32 tcs_in_use[(MAX_TCS_NR + 31) / 32]; + struct rpmh_ctrlr client; + struct device *dev; + u32 *regs; +}; + +extern bool rpmh_standalone; + +int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg, int ch); +int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, + const struct tcs_request *msg, + int ch); +void rpmh_rsc_invalidate(struct rsc_drv *drv, int ch); +int rpmh_rsc_mode_solver_set(struct rsc_drv *drv, bool enable); +int rpmh_rsc_get_channel(struct rsc_drv *drv); +int rpmh_rsc_switch_channel(struct rsc_drv *drv, int ch); +int rpmh_rsc_drv_enable(struct rsc_drv *drv, bool enable); + +int rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch); + +int rpmh_rsc_init_fast_path(struct rsc_drv *drv, const struct tcs_request *msg, int ch); +int rpmh_rsc_update_fast_path(struct rsc_drv *drv, + const struct tcs_request *msg, + u32 update_mask, int ch); + +void rpmh_set_rsc_drv(struct rsc_drv *drv); + +#endif /* __SOC_QUALCOMM_RPMH_INTERNAL_H__ */ diff --git a/src/soc/qualcomm/common/include/soc/rpmh_regulator.h b/src/soc/qualcomm/common/include/soc/rpmh_regulator.h new file mode 100644 index 00000000000..310cd4c7efd --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/rpmh_regulator.h @@ -0,0 +1,220 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_QUALCOMM_RPMH_REGULATOR_H__ +#define __SOC_QUALCOMM_RPMH_REGULATOR_H__ + +#include +#include + +#define RPMH_ARC_LEVEL_SIZE 2 +#define RPMH_ARC_MAX_LEVELS 32 +#define RPMH_REGULATOR_LEVEL_OFF 0 + +/* Min and max limits of VRM resource request parameters */ +#define RPMH_VRM_MIN_UV 0 +#define RPMH_VRM_MAX_UV 8191000 +#define RPMH_VRM_STEP_UV 1000 +#define RPMH_VRM_HEADROOM_MIN_UV 0 +#define RPMH_VRM_HEADROOM_MAX_UV 511000 + +#define RPMH_VRM_MODE_MIN 0 +#define RPMH_VRM_MODE_MAX 7 + +/* XOB and PBS voting registers are found in the VRM hardware module */ +#define CMD_DB_HW_XOB CMD_DB_HW_VRM +#define CMD_DB_HW_PBS CMD_DB_HW_VRM + +/* Voltage unknown placeholder */ +#define VOLTAGE_UNKNOWN 1 + +/** + * enum rpmh_regulator_type - supported RPMh accelerator types + * @RPMH_REGULATOR_TYPE_VRM: RPMh VRM accelerator which supports voting on + * enable, voltage, mode, and headroom voltage of + * LDO, SMPS, VS, and BOB type PMIC regulators. + * @RPMH_REGULATOR_TYPE_ARC: RPMh ARC accelerator which supports voting on + * the CPR managed voltage level of LDO and SMPS + * type PMIC regulators. + * @RPMH_REGULATOR_TYPE_XOB: RPMh XOB accelerator which supports voting on + * the enable state of PMIC regulators. + * @RPMH_REGULATOR_TYPE_PBS: RPMh PBS accelerator which supports voting on + * the enable state of PBS resources. + * @RPMH_REGULATOR_TYPE_BCM: RPMh BCM (Bus Clock Manager) accelerator which + * supports voting on bandwidth and clock frequency + * requirements for interconnect and bus resources. + */ +enum rpmh_regulator_type { + RPMH_REGULATOR_TYPE_VRM, + RPMH_REGULATOR_TYPE_ARC, + RPMH_REGULATOR_TYPE_XOB, + RPMH_REGULATOR_TYPE_PBS, + RPMH_REGULATOR_TYPE_BCM, +}; + +/** + * enum rpmh_regulator_reg_index - RPMh accelerator register indices + * @RPMH_REGULATOR_REG_VRM_VOLTAGE: VRM voltage voting register index + * @RPMH_REGULATOR_REG_ARC_LEVEL: ARC voltage level voting register index + * @RPMH_REGULATOR_REG_PBS_ENABLE: PBS enable voting register index + * @RPMH_REGULATOR_REG_VRM_ENABLE: VRM enable voltage voting register index + * @RPMH_REGULATOR_REG_ARC_PSEUDO_ENABLE: Place-holder for enable aggregation + * @RPMH_REGULATOR_REG_XOB_ENABLE: XOB enable voting register index + * @RPMH_REGULATOR_REG_ENABLE: Common enable index + * @RPMH_REGULATOR_REG_VRM_MODE: VRM regulator mode voting register index + * @RPMH_REGULATOR_REG_VRM_HEADROOM: VRM headroom voltage voting register index + * @RPMH_REGULATOR_REG_MAX: Maximum number of registers + */ +enum rpmh_regulator_reg_index { + RPMH_REGULATOR_REG_VRM_VOLTAGE = 0, + RPMH_REGULATOR_REG_ARC_LEVEL = 0, + RPMH_REGULATOR_REG_PBS_ENABLE = 0, + RPMH_REGULATOR_REG_VRM_ENABLE = 1, + RPMH_REGULATOR_REG_ARC_PSEUDO_ENABLE = 1, + RPMH_REGULATOR_REG_XOB_ENABLE = 1, + RPMH_REGULATOR_REG_ENABLE = 1, + RPMH_REGULATOR_REG_VRM_MODE = 2, + RPMH_REGULATOR_REG_VRM_HEADROOM = 3, + RPMH_REGULATOR_REG_MAX = 4, +}; + +/** + * struct rpmh_regulator_request - internal request structure + */ +struct rpmh_regulator_request { + u32 reg[RPMH_REGULATOR_REG_MAX]; + u32 valid; +}; + +/** + * struct rpmh_vreg - individual rpmh regulator data structure + * @resource_name: Name of rpmh regulator resource + * @addr: Base address of the regulator resource within an RPMh accelerator + * @type: RPMh accelerator type for this regulator resource + * @level: Mapping from ARC resource specific voltage levels to consumer levels + * @level_count: The number of valid entries in the level array + * @req_active: Active set RPMh accelerator register request + * @req_sleep: Sleep set RPMh accelerator register request + */ + +struct rpmh_vreg { + const char *resource_name; + u32 addr; + enum rpmh_regulator_type type; + u32 level[RPMH_ARC_MAX_LEVELS]; + int level_count; + struct rpmh_regulator_request req_active; + struct rpmh_regulator_request req_sleep; +}; + + +/** + * rpmh_regulator_init() - initialize an rpmh regulator + * @vreg: Pointer to the rpmh regulator structure to initialize + * @dev: Device pointer for RPMh communication + * @resource_name: Name of the RPMh resource (e.g., "ldoa1") + * @type: Type of regulator (VRM, ARC, XOB, PBS) + * + * This function initializes an RPMh regulator by looking up its address + * in the command DB and loading any necessary configuration data. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_init(struct rpmh_vreg *vreg, const char *resource_name, + enum rpmh_regulator_type type); + +/** + * rpmh_regulator_vrm_set_voltage() - set the voltage of a VRM regulator + * @vreg: Pointer to the rpmh regulator + * @min_uv: Minimum voltage in microvolts + * @max_uv: Maximum voltage in microvolts + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * This function sets the voltage for a VRM type regulator. The actual + * voltage set will be the minimum value that satisfies min_uv. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_vrm_set_voltage(struct rpmh_vreg *vreg, int min_uv, int max_uv, + bool set_active, bool set_sleep); + +/** + * rpmh_regulator_vrm_set_mode() - set the mode of a VRM regulator + * @vreg: Pointer to the rpmh regulator + * @mode: PMIC mode value (use RPMH_REGULATOR_MODE_* defines) + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * This function sets the operating mode for a VRM type regulator. + * The mode value should be one of the RPMH_REGULATOR_MODE_PMIC*_* defines + * appropriate for the regulator type. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_vrm_set_mode(struct rpmh_vreg *vreg, u32 mode, + bool set_active, bool set_sleep); + +/** + * rpmh_regulator_enable() - enable a regulator + * @vreg: Pointer to the rpmh regulator + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * This function enables the regulator. Works for VRM, ARC, XOB, and PBS types. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_enable(struct rpmh_vreg *vreg, bool set_active, bool set_sleep); + +/** + * rpmh_regulator_disable() - disable a regulator + * @vreg: Pointer to the rpmh regulator + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * This function disables the regulator. Works for VRM, ARC, XOB, and PBS types. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_disable(struct rpmh_vreg *vreg, bool set_active, bool set_sleep); + +/** + * rpmh_regulator_arc_set_level() - set the voltage level of an ARC regulator + * @vreg: Pointer to the rpmh regulator + * @level: ARC voltage level (0 to level_count-1) + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * This function sets the voltage level for an ARC type regulator. + * The level is an index into the voltage level table loaded from command DB. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_arc_set_level(struct rpmh_vreg *vreg, u32 level, + bool set_active, bool set_sleep); + +/** + * rpmh_regulator_arc_get_level() - get the current voltage level of an ARC regulator + * @vreg: Pointer to the rpmh regulator + * + * This function returns the cached ARC voltage level that was last set. + * Note: This returns the requested level, not necessarily the actual hardware level, + * as there's no way to read back from RPMh hardware. + * + * Return: ARC voltage level (0 to level_count-1) on success, -1 on failure + */ +int rpmh_regulator_arc_get_level(struct rpmh_vreg *vreg); + +/** + * rpmh_regulator_arc_get_voltage_level() - get the voltage level value for an ARC level + * @vreg: Pointer to the rpmh regulator + * @level: ARC level index + * + * This function returns the actual voltage level value (vlvl) that corresponds + * to the given ARC hardware level (hlvl). + * + * Return: voltage level value on success, 0 on failure + */ +u32 rpmh_regulator_arc_get_voltage_level(struct rpmh_vreg *vreg, u32 level); + +#endif /* __SOC_QUALCOMM_RPMH_REGULATOR_H__ */ diff --git a/src/soc/qualcomm/common/include/soc/rpmh_rsc.h b/src/soc/qualcomm/common/include/soc/rpmh_rsc.h new file mode 100644 index 00000000000..cfe7d601aea --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/rpmh_rsc.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_QUALCOMM_RPMH_RSC_H__ +#define __SOC_QUALCOMM_RPMH_RSC_H__ + +#include +#include + +u32 rpmh_rsc_reg_offset_ver_2_7[] = { + [RSC_DRV_TCS_OFFSET] = 672, + [RSC_DRV_CMD_OFFSET] = 20, + [DRV_SOLVER_CONFIG] = 0x04, + [DRV_PRNT_CHLD_CONFIG] = 0x0C, + [RSC_DRV_IRQ_ENABLE] = 0x00, + [RSC_DRV_IRQ_STATUS] = 0x04, + [RSC_DRV_IRQ_CLEAR] = 0x08, + [RSC_DRV_CMD_WAIT_FOR_CMPL] = 0x10, + [RSC_DRV_CONTROL] = 0x14, + [RSC_DRV_STATUS] = 0x18, + [RSC_DRV_CMD_ENABLE] = 0x1C, + [RSC_DRV_CMD_MSGID] = 0x30, + [RSC_DRV_CMD_ADDR] = 0x34, + [RSC_DRV_CMD_DATA] = 0x38, + [RSC_DRV_CMD_STATUS] = 0x3C, + [RSC_DRV_CMD_RESP_DATA] = 0x40, + [RSC_DRV_CHN_SEQ_BUSY] = 0x0, + [RSC_DRV_CHN_SEQ_PC] = 0x0, + [RSC_DRV_CHN_TCS_TRIGGER] = 0x0, + [RSC_DRV_CHN_TCS_COMPLETE] = 0x0, + [RSC_DRV_CHN_UPDATE] = 0x0, + [RSC_DRV_CHN_BUSY] = 0x0, + [RSC_DRV_CHN_EN] = 0x0, +}; + +u32 rpmh_rsc_reg_offset_ver_3_0[] = { + [RSC_DRV_TCS_OFFSET] = 672, + [RSC_DRV_CMD_OFFSET] = 24, + [DRV_SOLVER_CONFIG] = 0x04, + [DRV_PRNT_CHLD_CONFIG] = 0x0C, + [RSC_DRV_IRQ_ENABLE] = 0x00, + [RSC_DRV_IRQ_STATUS] = 0x04, + [RSC_DRV_IRQ_CLEAR] = 0x08, + [RSC_DRV_CMD_WAIT_FOR_CMPL] = 0x20, + [RSC_DRV_CONTROL] = 0x24, + [RSC_DRV_STATUS] = 0x28, + [RSC_DRV_CMD_ENABLE] = 0x2C, + [RSC_DRV_CMD_MSGID] = 0x34, + [RSC_DRV_CMD_ADDR] = 0x38, + [RSC_DRV_CMD_DATA] = 0x3C, + [RSC_DRV_CMD_STATUS] = 0x40, + [RSC_DRV_CMD_RESP_DATA] = 0x44, + [RSC_DRV_CHN_SEQ_BUSY] = 0x464, + [RSC_DRV_CHN_SEQ_PC] = 0x468, + [RSC_DRV_CHN_TCS_TRIGGER] = 0x490, + [RSC_DRV_CHN_TCS_COMPLETE] = 0x494, + [RSC_DRV_CHN_UPDATE] = 0x498, + [RSC_DRV_CHN_BUSY] = 0x49C, + [RSC_DRV_CHN_EN] = 0x4A0, +}; + +u32 rpmh_rsc_reg_offset_ver_3_0_hw_channel[] = { + [RSC_DRV_TCS_OFFSET] = 336, + [RSC_DRV_CMD_OFFSET] = 24, + [DRV_SOLVER_CONFIG] = 0x04, + [DRV_PRNT_CHLD_CONFIG] = 0x0C, + [RSC_DRV_IRQ_ENABLE] = 0x00, + [RSC_DRV_IRQ_STATUS] = 0x04, + [RSC_DRV_IRQ_CLEAR] = 0x08, + [RSC_DRV_CMD_WAIT_FOR_CMPL] = 0x20, + [RSC_DRV_CONTROL] = 0x24, + [RSC_DRV_STATUS] = 0x28, + [RSC_DRV_CMD_ENABLE] = 0x2C, + [RSC_DRV_CMD_MSGID] = 0x34, + [RSC_DRV_CMD_ADDR] = 0x38, + [RSC_DRV_CMD_DATA] = 0x3C, + [RSC_DRV_CMD_STATUS] = 0x40, + [RSC_DRV_CMD_RESP_DATA] = 0x44, + [RSC_DRV_CHN_SEQ_BUSY] = 0x464, + [RSC_DRV_CHN_SEQ_PC] = 0x468, + [RSC_DRV_CHN_TCS_TRIGGER] = 0x490, + [RSC_DRV_CHN_TCS_COMPLETE] = 0x494, + [RSC_DRV_CHN_UPDATE] = 0x498, + [RSC_DRV_CHN_BUSY] = 0x49C, + [RSC_DRV_CHN_EN] = 0x4A0, +}; + +#endif /* __SOC_QUALCOMM_RPMH_RSC_H__ */ diff --git a/src/soc/qualcomm/common/include/soc/symbols_common.h b/src/soc/qualcomm/common/include/soc/symbols_common.h index ee2d3510b61..847225216ab 100644 --- a/src/soc/qualcomm/common/include/soc/symbols_common.h +++ b/src/soc/qualcomm/common/include/soc/symbols_common.h @@ -48,7 +48,6 @@ DECLARE_REGION(dram_llcc_lpi) DECLARE_REGION(dram_ta) DECLARE_REGION(dram_pdp) DECLARE_REGION(dram_pil) -DECLARE_REGION(dram_display) /* * DDR_SPACE (2 GB) aka `_dram`: 0x80000000 - 0x100000000 diff --git a/src/soc/qualcomm/common/include/soc/tcs.h b/src/soc/qualcomm/common/include/soc/tcs.h new file mode 100644 index 00000000000..260e0108621 --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/tcs.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_QUALCOMM_TCS_H__ +#define __SOC_QUALCOMM_TCS_H__ + +#include + +#define MAX_RPMH_PAYLOAD 16 + +/** + * rpmh_state: state for the request + * + * RPMH_SLEEP_STATE: State of the resource when the processor subsystem + * is powered down. There is no client using the + * resource actively. + * RPMH_WAKE_ONLY_STATE: Resume resource state to the value previously + * requested before the processor was powered down. + * RPMH_ACTIVE_ONLY_STATE: Active or AMC mode requests. Resource state + * is aggregated immediately. + */ +enum rpmh_state { + RPMH_SLEEP_STATE, + RPMH_WAKE_ONLY_STATE, + RPMH_ACTIVE_ONLY_STATE, +}; + +/** + * struct tcs_cmd: an individual request to RPMH. + * + * @addr: the address of the resource slv_id:18:16 | offset:0:15 + * @data: the resource state request + * @wait: ensure that this command is complete before returning. + */ +struct tcs_cmd { + u32 addr; + u32 data; + u32 wait; +}; + +/** + * struct tcs_request: A set of tcs_cmds sent together in a TCS + * + * @state: state for the request. + * @wait_for_compl: wait until we get a response from the h/w accelerator + * @num_cmds: the number of @cmds in this request + * @cmds: an array of tcs_cmds + */ +struct tcs_request { + enum rpmh_state state; + u32 wait_for_compl; + u32 num_cmds; + struct tcs_cmd *cmds; +}; + +#define BCM_TCS_CMD_COMMIT_SHFT 30 +#define BCM_TCS_CMD_COMMIT_MASK 0x40000000 +#define BCM_TCS_CMD_VALID_SHFT 29 +#define BCM_TCS_CMD_VALID_MASK 0x20000000 +#define BCM_TCS_CMD_VOTE_X_SHFT 14 +#define BCM_TCS_CMD_VOTE_MASK 0x3fff +#define BCM_TCS_CMD_VOTE_Y_SHFT 0 +#define BCM_TCS_CMD_VOTE_Y_MASK 0xfffc000 + +/* Construct a Bus Clock Manager (BCM) specific TCS command */ +#define BCM_TCS_CMD(commit, valid, vote_x, vote_y) \ + cpu_to_le32( \ + (((uint32_t)(commit) & 0x1) << BCM_TCS_CMD_COMMIT_SHFT) | \ + (((uint32_t)(valid) & 0x1) << BCM_TCS_CMD_VALID_SHFT) | \ + (((uint32_t)(vote_x) & BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_X_SHFT) | \ + (((uint32_t)(vote_y) & BCM_TCS_CMD_VOTE_MASK) << BCM_TCS_CMD_VOTE_Y_SHFT) \ + ) +#endif /* __SOC_QUALCOMM_TCS_H__ */ diff --git a/src/soc/qualcomm/common/qclib.c b/src/soc/qualcomm/common/qclib.c index 8dad95715d8..8b7843540bc 100644 --- a/src/soc/qualcomm/common/qclib.c +++ b/src/soc/qualcomm/common/qclib.c @@ -224,20 +224,28 @@ static void qclib_prepare_and_run(void) printk(BIOS_DEBUG, "Jumping to QCLib code at %p(%p)\n", prog_entry(&qclib), prog_entry_arg(&qclib)); - /* back-up mmu context before disabling mmu and executing qclib */ - mmu_save_context(&pre_qclib_mmu_context); - /* disable mmu before jumping to qclib. mmu_disable also - flushes and invalidates caches before disabling mmu. */ - mmu_disable(); + /* + * Backup MMU context and disable the MMU before executing QCLib, + * unless the platform handles QCLib with the MMU enabled. + * mmu_disable() also handles required cache maintenance. + */ + if (!CONFIG(SOC_QUALCOMM_QCLIB_SKIP_MMU_TOGGLE)) { + mmu_save_context(&pre_qclib_mmu_context); + mmu_disable(); + } prog_run(&qclib); - /* Before returning, QCLib flushes cache and disables mmu. - Explicitly disable mmu (flush, invalidate and disable mmu) - before re-enabling mmu with backed-up mmu context */ - mmu_disable(); - mmu_restore_context(&pre_qclib_mmu_context); - mmu_enable(); + /* + * Post-QCLib execution: If the MMU was toggled off, ensure it is + * cleanly disabled (flushed/invalidated) before restoring the + * previous context and re-enabling. Otherwise, just restore context. + */ + if (!CONFIG(SOC_QUALCOMM_QCLIB_SKIP_MMU_TOGGLE)) { + mmu_disable(); + mmu_restore_context(&pre_qclib_mmu_context); + mmu_enable(); + } if (qclib_cb_if_table.global_attributes & QCLIB_GA_FORCE_COLD_REBOOT) { printk(BIOS_NOTICE, "QcLib requested cold reboot\n"); diff --git a/src/soc/qualcomm/common/rpmh.c b/src/soc/qualcomm/common/rpmh.c new file mode 100644 index 00000000000..bd348a07a97 --- /dev/null +++ b/src/soc/qualcomm/common/rpmh.c @@ -0,0 +1,408 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include + +#define RPMH_TIMEOUT_MS 10000 + +#define DEFINE_RPMH_MSG_ONSTACK(s, name) \ + struct rpmh_request name = { \ + .msg = { \ + .state = s, \ + .cmds = name.cmd, \ + .num_cmds = 0, \ + .wait_for_compl = 1, \ + }, \ + .cmd = { { 0 } }, \ + } + +#define ctrlr_to_drv(ctrlr) \ + ((struct rsc_drv *)((char *)(ctrlr) - offsetof(struct rsc_drv, client))) + +bool rpmh_standalone; + +static struct rsc_drv *g_rsc_drv = NULL; + +static struct rpmh_ctrlr *get_rpmh_ctrlr(void) +{ + return g_rsc_drv ? &g_rsc_drv->client : NULL; +} + +void rpmh_set_rsc_drv(struct rsc_drv *drv) +{ + g_rsc_drv = drv; +} + +static int check_ctrlr_state(struct rpmh_ctrlr *ctrlr, enum rpmh_state state) +{ + if (state != RPMH_ACTIVE_ONLY_STATE) + return 0; + + if (!(ctrlr->flags & SOLVER_PRESENT)) + return 0; + + if (ctrlr->in_solver_mode) + return -1; + + return 0; +} + +static struct cache_req *get_non_batch_cache_req(struct rpmh_ctrlr *ctrlr, u32 addr) +{ + struct cache_req *req = ctrlr->non_batch_cache; + unsigned int i; + + if (ctrlr->non_batch_cache_idx >= CMD_DB_MAX_RESOURCES) + return NULL; + + for (i = 0; i < ctrlr->non_batch_cache_idx; i++) { + req = &ctrlr->non_batch_cache[i]; + if (req->addr == addr) + return req; + } + + req = &ctrlr->non_batch_cache[ctrlr->non_batch_cache_idx]; + req->sleep_val = req->wake_val = UINT_MAX; + ctrlr->non_batch_cache_idx++; + + return req; +} + +static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr, + enum rpmh_state state, + struct tcs_cmd *cmd) +{ + struct cache_req *req; + u32 old_sleep_val, old_wake_val; + + req = get_non_batch_cache_req(ctrlr, cmd->addr); + if (!req) + return NULL; + + req->addr = cmd->addr; + old_sleep_val = req->sleep_val; + old_wake_val = req->wake_val; + + switch (state) { + case RPMH_ACTIVE_ONLY_STATE: + case RPMH_WAKE_ONLY_STATE: + req->wake_val = cmd->data; + break; + case RPMH_SLEEP_STATE: + req->sleep_val = cmd->data; + break; + } + + ctrlr->dirty |= (req->sleep_val != old_sleep_val || + req->wake_val != old_wake_val) && + req->sleep_val != UINT_MAX && + req->wake_val != UINT_MAX; + + return req; +} + +static int __rpmh_write(enum rpmh_state state, struct rpmh_request *rpm_msg) +{ + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + int ret = -1; + struct cache_req *req; + int i, ch; + + if (rpmh_standalone) + return 0; + + if (!ctrlr) + return -1; + + for (i = 0; i < rpm_msg->msg.num_cmds; i++) { + req = cache_rpm_request(ctrlr, state, &rpm_msg->msg.cmds[i]); + if (!req) + return -1; + } + + if (state == RPMH_ACTIVE_ONLY_STATE) { + ch = rpmh_rsc_get_channel(ctrlr_to_drv(ctrlr)); + if (ch < 0) + return ch; + + ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msg->msg, ch); + } else { + ret = 0; + } + + return ret; +} + +static int __fill_rpmh_msg(struct rpmh_request *req, enum rpmh_state state, + const struct tcs_cmd *cmd, u32 num_cmds) +{ + if (!cmd || !num_cmds || num_cmds > MAX_RPMH_PAYLOAD) + return -1; + + memcpy(req->cmd, cmd, num_cmds * sizeof(*cmd)); + + req->msg.state = state; + req->msg.cmds = req->cmd; + req->msg.num_cmds = num_cmds; + + return 0; +} + +int rpmh_write_async(enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) +{ + DEFINE_RPMH_MSG_ONSTACK(state, rpm_msg); + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + int ret; + + if (rpmh_standalone) + return 0; + + if (!ctrlr) + return -1; + + rpm_msg.msg.wait_for_compl = 0; + ret = check_ctrlr_state(ctrlr, state); + if (ret) + return ret; + + ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n); + if (ret) + return ret; + + return __rpmh_write(state, &rpm_msg); +} + +int rpmh_write(enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) +{ + DEFINE_RPMH_MSG_ONSTACK(state, rpm_msg); + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + int ret; + + if (rpmh_standalone) + return 0; + + if (!ctrlr) + return -1; + + ret = check_ctrlr_state(ctrlr, state); + if (ret) + return ret; + + ret = __fill_rpmh_msg(&rpm_msg, state, cmd, n); + if (ret) + return ret; + + ret = __rpmh_write(state, &rpm_msg); + + return ret; +} + +static int flush_batch(struct rpmh_ctrlr *ctrlr, int ch) +{ + int ret; + + /* Send Sleep/Wake requests to the controller */ + ret = rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr), + &ctrlr->batch_cache[RPMH_SLEEP_STATE].msg, ch); + if (ret) + return ret; + + return rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr), + &ctrlr->batch_cache[RPMH_WAKE_ONLY_STATE].msg, ch); +} + +int rpmh_write_batch(enum rpmh_state state, const struct tcs_cmd *cmd, u32 *n) +{ + DEFINE_RPMH_MSG_ONSTACK(state, rpm_msg); + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + int ret, ch; + + if (rpmh_standalone) + return 0; + + if (!ctrlr) + return -1; + + ret = check_ctrlr_state(ctrlr, state); + if (ret) + return ret; + + if (state == RPMH_ACTIVE_ONLY_STATE) { + ret = __fill_rpmh_msg(&rpm_msg, state, cmd, *n); + if (ret) + return ret; + } else { + memset(&ctrlr->batch_cache[state], 0, sizeof(struct rpmh_request)); + ret = __fill_rpmh_msg(&ctrlr->batch_cache[state], state, cmd, *n); + ctrlr->dirty = 1; + return ret; + } + + ch = rpmh_rsc_get_channel(ctrlr_to_drv(ctrlr)); + if (ch < 0) + return ch; + + ret = rpmh_rsc_send_data(ctrlr_to_drv(ctrlr), &rpm_msg.msg, ch); + if (ret) { + printk(BIOS_ERR, "RPMH: Error sending message addr=%#x\n", + rpm_msg.msg.cmds[0].addr); + return ret; + } + + return 0; +} + +static int is_req_valid(struct cache_req *req) +{ + return (req->sleep_val != UINT_MAX && + req->wake_val != UINT_MAX && + req->sleep_val != req->wake_val); +} + +static int send_single(struct rpmh_ctrlr *ctrlr, enum rpmh_state state, + u32 addr, u32 data, int ch) +{ + DEFINE_RPMH_MSG_ONSTACK(state, rpm_msg); + + /* Wake sets are always complete and sleep sets are not */ + rpm_msg.msg.wait_for_compl = (state == RPMH_WAKE_ONLY_STATE); + rpm_msg.cmd[0].addr = addr; + rpm_msg.cmd[0].data = data; + rpm_msg.msg.num_cmds = 1; + + return rpmh_rsc_write_ctrl_data(ctrlr_to_drv(ctrlr), &rpm_msg.msg, ch); +} + +int rpmh_flush(struct rpmh_ctrlr *ctrlr, int ch) +{ + struct cache_req *p; + int ret = 0, i; + + if (!ctrlr->dirty) { + printk(BIOS_DEBUG, "RPMH: Skipping flush, TCS has latest data\n"); + return 0; + } + + /* Invalidate the TCSes first to avoid stale data */ + rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr), ch); + + /* First flush the cached batch requests */ + ret = flush_batch(ctrlr, ch); + if (ret) + return ret; + + for (i = 0; i < ctrlr->non_batch_cache_idx; i++) { + p = &ctrlr->non_batch_cache[i]; + if (!is_req_valid(p)) { + printk(BIOS_DEBUG, "RPMH: skipping req: a:%#x s:%#x w:%#x\n", + p->addr, p->sleep_val, p->wake_val); + continue; + } + ret = send_single(ctrlr, RPMH_SLEEP_STATE, p->addr, + p->sleep_val, ch); + if (ret) + return ret; + ret = send_single(ctrlr, RPMH_WAKE_ONLY_STATE, p->addr, + p->wake_val, ch); + if (ret) + return ret; + } + + ctrlr->dirty = 0; + return ret; +} + +int rpmh_write_sleep_and_wake(void) +{ + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + int ch, ret; + + if (!ctrlr) + return -1; + + ch = rpmh_rsc_get_channel(ctrlr_to_drv(ctrlr)); + if (ch < 0) + return ch; + + ret = rpmh_flush(ctrlr, ch); + if (ret || !(ctrlr->flags & HW_CHANNEL_PRESENT)) + return ret; + + return rpmh_rsc_switch_channel(ctrlr_to_drv(ctrlr), ch); +} + +void rpmh_invalidate(void) +{ + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + + if (rpmh_standalone || !ctrlr) + return; + + memset(&ctrlr->batch_cache[RPMH_SLEEP_STATE], 0, sizeof(struct rpmh_request)); + memset(&ctrlr->batch_cache[RPMH_WAKE_ONLY_STATE], 0, sizeof(struct rpmh_request)); + ctrlr->dirty = 1; +} + +int rpmh_mode_solver_set(bool enable) +{ + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + int ret; + + if (rpmh_standalone || !ctrlr) + return 0; + + if (!(ctrlr->flags & SOLVER_PRESENT)) + return -1; + + ret = rpmh_rsc_mode_solver_set(ctrlr_to_drv(ctrlr), enable); + if (!ret) + ctrlr->in_solver_mode = enable; + + return ret; +} + +int rpmh_init_fast_path(struct tcs_cmd *cmd, int n) +{ + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + struct tcs_request req; + int ch; + + if (rpmh_standalone || !ctrlr) + return 0; + + ch = rpmh_rsc_get_channel(ctrlr_to_drv(ctrlr)); + if (ch < 0) + return ch; + + req.cmds = cmd; + req.num_cmds = n; + req.wait_for_compl = 0; + + return rpmh_rsc_init_fast_path(ctrlr_to_drv(ctrlr), &req, ch); +} + +int rpmh_update_fast_path(struct tcs_cmd *cmd, int n, u32 update_mask) +{ + struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(); + struct tcs_request req; + int ch; + + if (rpmh_standalone || !ctrlr) + return 0; + + ch = rpmh_rsc_get_channel(ctrlr_to_drv(ctrlr)); + if (ch < 0) + return ch; + + req.cmds = cmd; + req.num_cmds = n; + req.wait_for_compl = 0; + + return rpmh_rsc_update_fast_path(ctrlr_to_drv(ctrlr), &req, + update_mask, ch); +} diff --git a/src/soc/qualcomm/common/rpmh_bcm.c b/src/soc/qualcomm/common/rpmh_bcm.c new file mode 100644 index 00000000000..01de7ffd880 --- /dev/null +++ b/src/soc/qualcomm/common/rpmh_bcm.c @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include +#include +#include +#include +#include +#include + +/** + * rpmh_bcm_vote() - Send BCM (Bus Clock Manager) vote to RPMh + * @dev: Device pointer for RPMh communication + * @resource_name: BCM resource name (e.g., "MM0", "SH0") + * @vote_value: Vote value to send + * + * This function sends a BCM vote to RPMh to enable bandwidth/clock requirements. + * It looks up the resource address from Command DB and sends the vote via TCS command. + * + * Return: 0 on success, negative error code on failure + */ +int rpmh_bcm_vote(const char *resource_name, u32 vote_value) +{ + u32 bcm_addr; + struct tcs_cmd cmd; + int rc; + + if (!resource_name) { + printk(BIOS_ERR, "BCM: Invalid parameters\n"); + return -1; + } + + /* Get the RPMh address for the BCM resource from Command DB */ + bcm_addr = cmd_db_read_addr(resource_name); + if (!bcm_addr) { + printk(BIOS_ERR, "BCM: Could not find RPMh address for resource %s\n", + resource_name); + return -1; + } + + printk(BIOS_DEBUG, "BCM: Found address 0x%08X for resource %s\n", + bcm_addr, resource_name); + + /* Prepare TCS command */ + cmd.addr = bcm_addr; + cmd.data = vote_value; + cmd.wait = true; + + /* Send BCM vote via RPMh in active-only state */ + rc = rpmh_write(RPMH_ACTIVE_ONLY_STATE, &cmd, 1); + if (rc) { + printk(BIOS_ERR, "BCM: Failed to send vote for %s (addr=0x%08X, val=0x%08X): %d\n", + resource_name, bcm_addr, vote_value, rc); + return rc; + } + + printk(BIOS_INFO, "BCM: Successfully voted for %s (addr=0x%08X, val=0x%08X)\n", + resource_name, bcm_addr, vote_value); + + return 0; +} diff --git a/src/soc/qualcomm/common/rpmh_regulator.c b/src/soc/qualcomm/common/rpmh_regulator.c new file mode 100644 index 00000000000..c2733333490 --- /dev/null +++ b/src/soc/qualcomm/common/rpmh_regulator.c @@ -0,0 +1,458 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * rpmh_regulator_load_arc_level_mapping() - load the RPMh ARC resource's + * voltage level mapping from command db + * @vreg: Pointer to the rpmh regulator + * + * Return: 0 on success, -1 on failure + */ +static int rpmh_regulator_load_arc_level_mapping(struct rpmh_vreg *vreg) +{ + size_t len = 0; + int i, j; + const u8 *buf; + + buf = cmd_db_read_aux_data(vreg->resource_name, &len); + if (!buf) { + printk(BIOS_ERR, "RPMH_REG: Could not retrieve ARC aux data for %s\n", + vreg->resource_name); + return -1; + } + + if (len == 0) { + printk(BIOS_ERR, "RPMH_REG: ARC level mapping data missing for %s\n", + vreg->resource_name); + return -1; + } + + if (len > RPMH_ARC_MAX_LEVELS * RPMH_ARC_LEVEL_SIZE) { + printk(BIOS_ERR, "RPMH_REG: Too many ARC levels defined for %s: %zu > %d\n", + vreg->resource_name, len, RPMH_ARC_MAX_LEVELS * RPMH_ARC_LEVEL_SIZE); + return -1; + } + + if (len % RPMH_ARC_LEVEL_SIZE) { + printk(BIOS_ERR, "RPMH_REG: Invalid ARC aux data size for %s: %zu\n", + vreg->resource_name, len); + return -1; + } + + vreg->level_count = len / RPMH_ARC_LEVEL_SIZE; + + for (i = 0; i < vreg->level_count; i++) { + vreg->level[i] = 0; + for (j = 0; j < RPMH_ARC_LEVEL_SIZE; j++) + vreg->level[i] |= buf[i * RPMH_ARC_LEVEL_SIZE + j] << (8 * j); + + /* The AUX data may be zero padded - ignore 0 valued entries at the end */ + if (i > 0 && vreg->level[i] == 0) { + vreg->level_count = i; + break; + } + + printk(BIOS_DEBUG, "RPMH_REG: %s ARC hlvl=%2d --> vlvl=%4u\n", + vreg->resource_name, i, vreg->level[i]); + } + + return 0; +} + +/** + * rpmh_regulator_send_request() - send the RPMh request + * @vreg: Pointer to the rpmh regulator + * @req: Request to send + * @state: RPMh state (active/sleep) + * @wait: Whether to wait for completion + * + * Return: 0 on success, -1 on failure + */ +static int rpmh_regulator_send_request(struct rpmh_vreg *vreg, + struct rpmh_regulator_request *req, + enum rpmh_state state, bool wait) +{ + struct tcs_cmd cmd[RPMH_REGULATOR_REG_MAX]; + int i, j = 0; + int rc; + + /* Build command array from valid registers */ + for (i = 0; i < RPMH_REGULATOR_REG_MAX; i++) { + if (req->valid & BIT(i)) { + cmd[j].addr = vreg->addr + i * 4; + cmd[j].data = req->reg[i]; + cmd[j].wait = true; + j++; + } + } + if (j == 0) + return 0; + + /* Send the request */ + if (wait) + rc = rpmh_write(state, cmd, j); + else + rc = rpmh_write_async(state, cmd, j); + + if (rc) { + printk(BIOS_ERR, "RPMH_REG: Failed to send %s request for %s, rc=%d\n", + state == RPMH_ACTIVE_ONLY_STATE ? "active" : "sleep", + vreg->resource_name, rc); + return rc; + } + + printk(BIOS_DEBUG, "RPMH_REG: Sent %s request for %s\n", + state == RPMH_ACTIVE_ONLY_STATE ? "active" : "sleep", + vreg->resource_name); + + return 0; +} + +/** + * rpmh_regulator_vrm_set_voltage() - set the voltage of a VRM regulator + * @vreg: Pointer to the rpmh regulator + * @min_uv: Minimum voltage in microvolts + * @max_uv: Maximum voltage in microvolts + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_vrm_set_voltage(struct rpmh_vreg *vreg, int min_uv, int max_uv, + bool set_active, bool set_sleep) +{ + int mv; + int rc = 0; + + if (!vreg || vreg->type != RPMH_REGULATOR_TYPE_VRM) + return -1; + + if (min_uv < RPMH_VRM_MIN_UV || max_uv > RPMH_VRM_MAX_UV) { + printk(BIOS_ERR, "RPMH_REG: Voltage range %d-%d uV out of bounds for %s\n", + min_uv, max_uv, vreg->resource_name); + return -1; + } + + mv = DIV_ROUND_UP(min_uv, 1000); + if (mv * 1000 > max_uv) { + printk(BIOS_ERR, "RPMH_REG: No set points available in range %d-%d uV for %s\n", + min_uv, max_uv, vreg->resource_name); + return -1; + } + + if (set_active) { + vreg->req_active.reg[RPMH_REGULATOR_REG_VRM_VOLTAGE] = mv; + vreg->req_active.valid |= BIT(RPMH_REGULATOR_REG_VRM_VOLTAGE); + rc = rpmh_regulator_send_request(vreg, &vreg->req_active, + RPMH_ACTIVE_ONLY_STATE, true); + if (rc) + return rc; + } + + if (set_sleep) { + vreg->req_sleep.reg[RPMH_REGULATOR_REG_VRM_VOLTAGE] = mv; + vreg->req_sleep.valid |= BIT(RPMH_REGULATOR_REG_VRM_VOLTAGE); + rc = rpmh_regulator_send_request(vreg, &vreg->req_sleep, + RPMH_SLEEP_STATE, false); + } + + return rc; +} + +/** + * rpmh_regulator_vrm_set_mode() - set the mode of a VRM regulator + * @vreg: Pointer to the rpmh regulator + * @mode: PMIC mode value + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_vrm_set_mode(struct rpmh_vreg *vreg, u32 mode, + bool set_active, bool set_sleep) +{ + int rc = 0; + + if (!vreg || vreg->type != RPMH_REGULATOR_TYPE_VRM) + return -1; + + if (mode < RPMH_VRM_MODE_MIN || mode > RPMH_VRM_MODE_MAX) { + printk(BIOS_ERR, "RPMH_REG: Mode %u out of range for %s\n", + mode, vreg->resource_name); + return -1; + } + + if (set_active) { + vreg->req_active.reg[RPMH_REGULATOR_REG_VRM_MODE] = mode; + vreg->req_active.valid |= BIT(RPMH_REGULATOR_REG_VRM_MODE); + rc = rpmh_regulator_send_request(vreg, &vreg->req_active, + RPMH_ACTIVE_ONLY_STATE, true); + if (rc) + return rc; + } + + if (set_sleep) { + vreg->req_sleep.reg[RPMH_REGULATOR_REG_VRM_MODE] = mode; + vreg->req_sleep.valid |= BIT(RPMH_REGULATOR_REG_VRM_MODE); + rc = rpmh_regulator_send_request(vreg, &vreg->req_sleep, + RPMH_SLEEP_STATE, false); + } + + return rc; +} + +/** + * rpmh_regulator_enable() - enable a regulator + * @vreg: Pointer to the rpmh regulator + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_enable(struct rpmh_vreg *vreg, bool set_active, bool set_sleep) +{ + int rc = 0; + int reg_index; + + if (!vreg) + return -1; + + /* Determine the correct enable register based on type */ + switch (vreg->type) { + case RPMH_REGULATOR_TYPE_VRM: + case RPMH_REGULATOR_TYPE_ARC: + case RPMH_REGULATOR_TYPE_XOB: + reg_index = RPMH_REGULATOR_REG_ENABLE; + break; + case RPMH_REGULATOR_TYPE_PBS: + reg_index = RPMH_REGULATOR_REG_PBS_ENABLE; + break; + default: + return -1; + } + + if (set_active) { + vreg->req_active.reg[reg_index] = 1; + vreg->req_active.valid |= BIT(reg_index); + rc = rpmh_regulator_send_request(vreg, &vreg->req_active, + RPMH_ACTIVE_ONLY_STATE, true); + if (rc) + return rc; + } + + if (set_sleep) { + vreg->req_sleep.reg[reg_index] = 1; + vreg->req_sleep.valid |= BIT(reg_index); + rc = rpmh_regulator_send_request(vreg, &vreg->req_sleep, + RPMH_SLEEP_STATE, false); + } + + return rc; +} + +/** + * rpmh_regulator_disable() - disable a regulator + * @vreg: Pointer to the rpmh regulator + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_disable(struct rpmh_vreg *vreg, bool set_active, bool set_sleep) +{ + int rc = 0; + int reg_index; + + if (!vreg) + return -1; + + /* Determine the correct enable register based on type */ + switch (vreg->type) { + case RPMH_REGULATOR_TYPE_VRM: + case RPMH_REGULATOR_TYPE_ARC: + case RPMH_REGULATOR_TYPE_XOB: + reg_index = RPMH_REGULATOR_REG_ENABLE; + break; + case RPMH_REGULATOR_TYPE_PBS: + reg_index = RPMH_REGULATOR_REG_PBS_ENABLE; + break; + default: + return -1; + } + + if (set_active) { + vreg->req_active.reg[reg_index] = 0; + vreg->req_active.valid |= BIT(reg_index); + rc = rpmh_regulator_send_request(vreg, &vreg->req_active, + RPMH_ACTIVE_ONLY_STATE, true); + if (rc) + return rc; + } + + if (set_sleep) { + vreg->req_sleep.reg[reg_index] = 0; + vreg->req_sleep.valid |= BIT(reg_index); + rc = rpmh_regulator_send_request(vreg, &vreg->req_sleep, + RPMH_SLEEP_STATE, false); + } + + return rc; +} + +/** + * rpmh_regulator_arc_set_level() - set the voltage level of an ARC regulator + * @vreg: Pointer to the rpmh regulator + * @level: ARC voltage level (0 to level_count-1) + * @set_active: Set in active state + * @set_sleep: Set in sleep state + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_arc_set_level(struct rpmh_vreg *vreg, u32 level, + bool set_active, bool set_sleep) +{ + int rc = 0; + + if (!vreg || vreg->type != RPMH_REGULATOR_TYPE_ARC) + return -1; + + if (level >= vreg->level_count) { + printk(BIOS_ERR, "RPMH_REG: Level %u out of range for %s (max %d)\n", + level, vreg->resource_name, vreg->level_count - 1); + return -1; + } + + if (set_active) { + vreg->req_active.reg[RPMH_REGULATOR_REG_ARC_LEVEL] = level; + vreg->req_active.valid |= BIT(RPMH_REGULATOR_REG_ARC_LEVEL); + rc = rpmh_regulator_send_request(vreg, &vreg->req_active, + RPMH_ACTIVE_ONLY_STATE, true); + if (rc) + return rc; + } + + if (set_sleep) { + vreg->req_sleep.reg[RPMH_REGULATOR_REG_ARC_LEVEL] = level; + vreg->req_sleep.valid |= BIT(RPMH_REGULATOR_REG_ARC_LEVEL); + rc = rpmh_regulator_send_request(vreg, &vreg->req_sleep, + RPMH_SLEEP_STATE, false); + } + + return rc; +} + +/** + * rpmh_regulator_arc_get_level() - get the current voltage level of an ARC regulator + * @vreg: Pointer to the rpmh regulator + * + * This function returns the cached ARC voltage level that was last set. + * Note: This returns the requested level, not necessarily the actual hardware level, + * as there's no way to read back from RPMh hardware. + * + * Return: ARC voltage level (0 to level_count-1) on success, -1 on failure + */ +int rpmh_regulator_arc_get_level(struct rpmh_vreg *vreg) +{ + if (!vreg || vreg->type != RPMH_REGULATOR_TYPE_ARC) + return -1; + + /* Return the active set level if valid, otherwise return 0 */ + if (vreg->req_active.valid & BIT(RPMH_REGULATOR_REG_ARC_LEVEL)) + return vreg->req_active.reg[RPMH_REGULATOR_REG_ARC_LEVEL]; + + return 0; +} + +/** + * rpmh_regulator_arc_get_voltage_level() - get the voltage level value for an ARC level + * @vreg: Pointer to the rpmh regulator + * @level: ARC level index + * + * This function returns the actual voltage level value (vlvl) that corresponds + * to the given ARC hardware level (hlvl). + * + * Return: voltage level value on success, 0 on failure + */ +u32 rpmh_regulator_arc_get_voltage_level(struct rpmh_vreg *vreg, u32 level) +{ + if (!vreg || vreg->type != RPMH_REGULATOR_TYPE_ARC) + return 0; + + if (level >= vreg->level_count) + return 0; + + return vreg->level[level]; +} + +/** + * rpmh_regulator_init() - initialize an rpmh regulator + * @vreg: Pointer to the rpmh regulator structure to initialize + * @dev: Device pointer for RPMh communication + * @resource_name: Name of the RPMh resource + * @type: Type of regulator (VRM, ARC, XOB, PBS) + * + * Return: 0 on success, -1 on failure + */ +int rpmh_regulator_init(struct rpmh_vreg *vreg, const char *resource_name, + enum rpmh_regulator_type type) +{ + enum cmd_db_hw_type hw_type; + int rc; + + if (!vreg || !resource_name) + return -1; + + memset(vreg, 0, sizeof(*vreg)); + + vreg->resource_name = resource_name; + vreg->type = type; + + /* Get the RPMh address for this resource */ + vreg->addr = cmd_db_read_addr(resource_name); + if (!vreg->addr) { + printk(BIOS_ERR, "RPMH_REG: Could not find RPMh address for %s\n", + resource_name); + return -1; + } + + /* Verify the slave ID matches the expected type */ + hw_type = cmd_db_read_slave_id(resource_name); + if (hw_type == CMD_DB_HW_INVALID) { + printk(BIOS_ERR, "RPMH_REG: Could not find slave ID for %s\n", + resource_name); + return -1; + } + + /* Validate hardware type matches regulator type */ + if ((type == RPMH_REGULATOR_TYPE_ARC && hw_type != CMD_DB_HW_ARC) || + (type == RPMH_REGULATOR_TYPE_VRM && hw_type != CMD_DB_HW_VRM) || + (type == RPMH_REGULATOR_TYPE_XOB && hw_type != CMD_DB_HW_XOB) || + (type == RPMH_REGULATOR_TYPE_BCM && hw_type != CMD_DB_HW_BCM) || + (type == RPMH_REGULATOR_TYPE_PBS && hw_type != CMD_DB_HW_PBS)) { + printk(BIOS_ERR, "RPMH_REG: Hardware type mismatch for %s\n", + resource_name); + return -1; + } + + /* Load ARC level mapping if this is an ARC regulator */ + if (type == RPMH_REGULATOR_TYPE_ARC) { + rc = rpmh_regulator_load_arc_level_mapping(vreg); + if (rc) { + printk(BIOS_ERR, "RPMH_REG: Failed to load ARC level mapping for %s\n", + resource_name); + return rc; + } + } + printk(BIOS_INFO, "RPMH_REG: Initialized %s at addr=0x%05X\n", + resource_name, vreg->addr); + + return 0; +} diff --git a/src/soc/qualcomm/common/rpmh_rsc.c b/src/soc/qualcomm/common/rpmh_rsc.c new file mode 100644 index 00000000000..e93d4454eb3 --- /dev/null +++ b/src/soc/qualcomm/common/rpmh_rsc.c @@ -0,0 +1,511 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TCS_AMC_MODE_ENABLE BIT(16) +#define TCS_AMC_MODE_TRIGGER BIT(24) + +/* TCS CMD register bit mask */ +#define CMD_MSGID_LEN 8 +#define CMD_MSGID_RESP_REQ BIT(8) +#define CMD_MSGID_WRITE BIT(16) +#define CMD_STATUS_ISSUED BIT(8) +#define CMD_STATUS_COMPL BIT(16) + +/* Offsets for DRV channel status register */ +#define CH0_CHN_BUSY BIT(0) +#define CH1_CHN_BUSY BIT(1) +#define CH0_WAKE_TCS_STATUS BIT(0) +#define CH0_SLEEP_TCS_STATUS BIT(1) +#define CH1_WAKE_TCS_STATUS BIT(2) +#define CH1_SLEEP_TCS_STATUS BIT(3) +#define CH_CLEAR_STATUS BIT(31) + +static inline void *tcs_reg_addr(const struct rsc_drv *drv, int reg, int tcs_id) +{ + if (!drv->tcs_distance) + return drv->tcs_base + drv->regs[RSC_DRV_TCS_OFFSET] * tcs_id + reg; + + return drv->tcs_base + drv->tcs_distance * tcs_id + reg; +} + +static inline void *tcs_cmd_addr(const struct rsc_drv *drv, int reg, int tcs_id, int cmd_id) +{ + return tcs_reg_addr(drv, reg, tcs_id) + drv->regs[RSC_DRV_CMD_OFFSET] * cmd_id; +} + +static u32 read_tcs_cmd(const struct rsc_drv *drv, int reg, int tcs_id, int cmd_id) +{ + return read32(tcs_cmd_addr(drv, reg, tcs_id, cmd_id)); +} + +static u32 read_tcs_reg(const struct rsc_drv *drv, int reg, int tcs_id) +{ + return read32(tcs_reg_addr(drv, reg, tcs_id)); +} + +static void write_tcs_cmd(const struct rsc_drv *drv, int reg, int tcs_id, + int cmd_id, u32 data) +{ + write32(tcs_cmd_addr(drv, reg, tcs_id, cmd_id), data); +} + +static void write_tcs_reg(const struct rsc_drv *drv, int reg, int tcs_id, u32 data) +{ + write32(tcs_reg_addr(drv, reg, tcs_id), data); +} + +static void write_tcs_reg_sync(const struct rsc_drv *drv, int reg, int tcs_id, u32 data) +{ + struct stopwatch sw; + + write32(tcs_reg_addr(drv, reg, tcs_id), data); + + /* Wait until we read back the same value */ + stopwatch_init_usecs_expire(&sw, USECS_1S); + while (read32(tcs_reg_addr(drv, reg, tcs_id)) != data) { + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "%s: error writing %#x to %d:%#x\n", drv->name, + data, tcs_id, reg); + break; + } + udelay(LOOP_DELAY_US); + } +} + +static void tcs_invalidate(struct rsc_drv *drv, int type, int ch) +{ + int m; + struct tcs_group *tcs = &drv->ch[ch].tcs[type]; + + /* Check if already empty */ + if (tcs->slots[0] == 0) + return; + + for (m = tcs->offset; m < tcs->offset + tcs->num_tcs; m++) { + write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], m, 0); + write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], m, 0); + } + + memset(tcs->slots, 0, sizeof(tcs->slots)); +} + +int rpmh_rsc_get_channel(struct rsc_drv *drv) +{ + int chn_update, chn_busy; + + if (drv->num_channels == 1) + return CH0; + + /* Select Unused channel */ + do { + chn_update = read32(drv->base + drv->regs[RSC_DRV_CHN_UPDATE]); + chn_busy = read32(drv->base + drv->regs[RSC_DRV_CHN_BUSY]); + } while (chn_busy != chn_update); + + if (chn_busy & CH0_CHN_BUSY) + return CH1; + else if (chn_busy & CH1_CHN_BUSY) + return CH0; + else + return -1; +} + +void rpmh_rsc_invalidate(struct rsc_drv *drv, int ch) +{ + tcs_invalidate(drv, SLEEP_TCS, ch); + tcs_invalidate(drv, WAKE_TCS, ch); +} + +static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv, + enum rpmh_state state, + int ch) +{ + int type; + struct tcs_group *tcs; + + switch (state) { + case RPMH_ACTIVE_ONLY_STATE: + type = ACTIVE_TCS; + break; + case RPMH_WAKE_ONLY_STATE: + type = WAKE_TCS; + break; + case RPMH_SLEEP_STATE: + type = SLEEP_TCS; + break; + default: + return NULL; + } + + tcs = &drv->ch[ch].tcs[type]; + if (state == RPMH_ACTIVE_ONLY_STATE && !tcs->num_tcs) + tcs = &drv->ch[ch].tcs[WAKE_TCS]; + + return tcs; +} + +static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger) +{ + u32 enable; + u32 reg = drv->regs[RSC_DRV_CONTROL]; + + enable = read_tcs_reg(drv, reg, tcs_id); + enable &= ~TCS_AMC_MODE_TRIGGER; + write_tcs_reg_sync(drv, reg, tcs_id, enable); + enable &= ~TCS_AMC_MODE_ENABLE; + write_tcs_reg_sync(drv, reg, tcs_id, enable); + + if (trigger) { + enable = TCS_AMC_MODE_ENABLE; + write_tcs_reg_sync(drv, reg, tcs_id, enable); + enable |= TCS_AMC_MODE_TRIGGER; + write_tcs_reg(drv, reg, tcs_id, enable); + } +} + +static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, + const struct tcs_request *msg) +{ + u32 msgid; + u32 cmd_msgid = CMD_MSGID_LEN | CMD_MSGID_WRITE; + u32 cmd_enable = 0; + u32 cmd_complete; + struct tcs_cmd *cmd; + int i, j; + + cmd_msgid |= msg->wait_for_compl ? CMD_MSGID_RESP_REQ : 0; + cmd_complete = read_tcs_reg(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], tcs_id); + + for (i = 0, j = cmd_id; i < msg->num_cmds; i++, j++) { + cmd = &msg->cmds[i]; + cmd_enable |= BIT(j); + cmd_complete |= cmd->wait << j; + msgid = cmd_msgid; + msgid |= cmd->wait ? CMD_MSGID_RESP_REQ : 0; + + write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_MSGID], tcs_id, j, msgid); + write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], tcs_id, j, cmd->addr); + write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, j, cmd->data); + } + + write_tcs_reg(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], tcs_id, cmd_complete); + cmd_enable |= read_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id); + write_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, cmd_enable); +} + +static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs, + const struct tcs_request *msg) +{ + u32 curr_enabled; + u32 addr; + int j, k; + int i = tcs->offset; + + for (; i < tcs->offset + tcs->num_tcs; i++) { + if (!(drv->tcs_in_use[i / 32] & BIT(i % 32))) + continue; + + curr_enabled = read_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], i); + + for (j = 0; j < tcs->ncpt; j++) { + if (!(curr_enabled & BIT(j))) + continue; + + addr = read_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], i, j); + for (k = 0; k < msg->num_cmds; k++) { + if (cmd_db_match_resource_addr(msg->cmds[k].addr, addr)) + return -1; + } + } + } + + return 0; +} + +static int find_free_tcs(struct tcs_group *tcs) +{ + const struct rsc_drv *drv = tcs->drv; + struct stopwatch sw; + int i; + u32 sts; + + for (i = tcs->offset; i < tcs->offset + tcs->num_tcs; i++) { + if (drv->tcs_in_use[i / 32] & BIT(i % 32)) + continue; + + stopwatch_init_usecs_expire(&sw, USECS_100US); + while (1) { + sts = read_tcs_reg(drv, drv->regs[RSC_DRV_STATUS], i); + if (sts) + return i; + if (stopwatch_expired(&sw)) + return -1; + udelay(LOOP_DELAY_US); + } + } + + return -1; +} + +static int claim_tcs_for_req(struct rsc_drv *drv, struct tcs_group *tcs, + const struct tcs_request *msg) +{ + int ret; + + ret = check_for_req_inflight(drv, tcs, msg); + if (ret) + return ret; + + return find_free_tcs(tcs); +} + +int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg, int ch) +{ + struct tcs_group *tcs; + struct stopwatch sw; + int tcs_id; + u32 status; + + tcs = get_tcs_for_msg(drv, msg->state, ch); + if (!tcs) + return -1; + + /* Controller is busy in 'solver' mode */ + if (drv->in_solver_mode) { + printk(BIOS_ERR, "RPMH RSC: Cannot send ACTIVE request in solver mode\n"); + return -1; + } + + /* Wait for a free tcs with hardware status verification */ + stopwatch_init_usecs_expire(&sw, USECS_100MS); + while (1) { + tcs_id = claim_tcs_for_req(drv, tcs, msg); + if (tcs_id >= 0) { + /* Double-check hardware status register */ + status = read_tcs_reg(drv, drv->regs[RSC_DRV_STATUS], tcs_id); + if (status) { /* 1 = IDLE, 0 = BUSY */ + break; + } + /* TCS claimed but hardware still busy, retry */ + printk(BIOS_DEBUG, "RPMH RSC: TCS %d claimed but HW busy, retrying\n", tcs_id); + } + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "RPMH RSC: No free TCS available (timeout after 100ms)\n"); + return -1; + } + udelay(LOOP_DELAY_10US); + } + + tcs->req[tcs_id - tcs->offset] = msg; + drv->tcs_in_use[tcs_id / 32] |= BIT(tcs_id % 32); + + write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, 0); + write_tcs_reg_sync(drv, drv->regs[RSC_DRV_CMD_WAIT_FOR_CMPL], tcs_id, 0); + + __tcs_buffer_write(drv, tcs_id, 0, msg); + __tcs_set_trigger(drv, tcs_id, 1); + + /* Poll for completion if wait_for_compl is set */ + if (msg->wait_for_compl) { + stopwatch_init_usecs_expire(&sw, USECS_10MS); + while (1) { + u32 sts = read_tcs_reg(drv, drv->regs[RSC_DRV_STATUS], tcs_id); + if (sts) + break; + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "RPMH RSC: TCS %d timeout\n", tcs_id); + return -1; + } + udelay(LOOP_DELAY_US); + } + } + + drv->tcs_in_use[tcs_id / 32] &= ~BIT(tcs_id % 32); + + return 0; +} + +static int find_slots(struct tcs_group *tcs, const struct tcs_request *msg, + int *tcs_id, int *cmd_id) +{ + int slot, offset; + int i = 0; + int slots_needed = msg->num_cmds; + + /* Find contiguous slots */ + do { + slot = 0; + for (i = 0; i < tcs->ncpt * tcs->num_tcs; i++) { + if (tcs->slots[i / 32] & BIT(i % 32)) { + slot = 0; + } else { + slot++; + if (slot >= slots_needed) + break; + } + } + if (slot < slots_needed) + return -1; + + i = i - slot + 1; + } while (i + slots_needed - 1 >= ((i / tcs->ncpt) + 1) * tcs->ncpt); + + /* Mark slots as used */ + for (slot = i; slot < i + slots_needed; slot++) + tcs->slots[slot / 32] |= BIT(slot % 32); + + offset = i / tcs->ncpt; + *tcs_id = offset + tcs->offset; + *cmd_id = i % tcs->ncpt; + + return 0; +} + +int rpmh_rsc_write_ctrl_data(struct rsc_drv *drv, const struct tcs_request *msg, int ch) +{ + struct tcs_group *tcs; + int tcs_id = 0, cmd_id = 0; + int ret; + + if (!msg->num_cmds) + return 0; + + tcs = get_tcs_for_msg(drv, msg->state, ch); + if (!tcs) + return -1; + + ret = find_slots(tcs, msg, &tcs_id, &cmd_id); + if (!ret) + __tcs_buffer_write(drv, tcs_id, cmd_id, msg); + + return ret; +} + +int rpmh_rsc_mode_solver_set(struct rsc_drv *drv, bool enable) +{ + drv->in_solver_mode = enable; + return 0; +} + +int rpmh_rsc_switch_channel(struct rsc_drv *drv, int ch) +{ + struct stopwatch sw; + u32 sts; + u32 mask = (ch == 0) ? CH0_WAKE_TCS_STATUS : CH1_WAKE_TCS_STATUS; + + write32(drv->base + drv->regs[RSC_DRV_CHN_UPDATE], BIT(ch)); + + stopwatch_init_usecs_expire(&sw, USECS_100US); + while (1) { + sts = read32(drv->base + drv->regs[RSC_DRV_CHN_TCS_COMPLETE]); + if (sts & mask) + break; + if (stopwatch_expired(&sw)) + return -1; + udelay(LOOP_DELAY_US); + } + + write32(drv->base + drv->regs[RSC_DRV_CHN_TCS_COMPLETE], CH_CLEAR_STATUS); + + return 0; +} + +int rpmh_rsc_drv_enable(struct rsc_drv *drv, bool enable) +{ + int ret = 0, ch; + u32 chn_en; + + chn_en = read32(drv->base + drv->regs[RSC_DRV_CHN_EN]); + if (chn_en == enable) + return -1; + + if (enable) { + ch = 0; + ret = rpmh_flush(&drv->client, ch); + if (ret) + return ret; + + write32(drv->base + drv->regs[RSC_DRV_CHN_EN], enable); + ret = rpmh_rsc_switch_channel(drv, ch); + } else { + ch = rpmh_rsc_get_channel(drv); + if (ch < 0) + return ch; + + ret = rpmh_flush(&drv->client, ch); + if (ret) + return ret; + + ret = rpmh_rsc_switch_channel(drv, ch); + if (ret) + return ret; + + write32(drv->base + drv->regs[RSC_DRV_CHN_UPDATE], 0); + write32(drv->base + drv->regs[RSC_DRV_CHN_EN], enable); + } + + return ret; +} + +int rpmh_rsc_init_fast_path(struct rsc_drv *drv, const struct tcs_request *msg, int ch) +{ + int tcs_id; + + if (!drv->ch[ch].tcs[FAST_PATH_TCS].num_tcs) + return -1; + + tcs_id = drv->ch[ch].tcs[FAST_PATH_TCS].offset; + __tcs_buffer_write(drv, tcs_id, 0, msg); + + return 0; +} + +int rpmh_rsc_update_fast_path(struct rsc_drv *drv, + const struct tcs_request *msg, + u32 mask, int ch) +{ + struct stopwatch sw; + int i; + u32 sts; + int tcs_id; + struct tcs_cmd *cmd; + + if (!drv->ch[ch].tcs[FAST_PATH_TCS].num_tcs) + return -1; + + tcs_id = drv->ch[ch].tcs[FAST_PATH_TCS].offset; + + /* Ensure the TCS is free before writing */ + stopwatch_init_usecs_expire(&sw, USECS_5US); + while (1) { + sts = read_tcs_reg(drv, drv->regs[RSC_DRV_STATUS], tcs_id); + if (sts) + break; + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "Fast-path TCS is too busy\n"); + return -1; + } + udelay(LOOP_DELAY_US); + } + + /* Update only the data fields */ + for (i = 0; i < msg->num_cmds; i++) { + if (!(mask & BIT(i))) + continue; + cmd = &msg->cmds[i]; + write_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_DATA], tcs_id, i, cmd->data); + } + + /* Trigger the TCS */ + __tcs_set_trigger(drv, tcs_id, 1); + + return 0; +} diff --git a/src/soc/qualcomm/sc7180/display/dsi.c b/src/soc/qualcomm/sc7180/display/dsi.c index c1e75e1090a..ef219777b32 100644 --- a/src/soc/qualcomm/sc7180/display/dsi.c +++ b/src/soc/qualcomm/sc7180/display/dsi.c @@ -1,6 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include #include #include #include @@ -287,8 +286,7 @@ enum cb_err mdss_dsi_panel_initialize(const u8 *init_cmds) /* Enable command mode before sending the commands */ write32(&dsi0->ctrl, ctrl_mode | 0x04); - enum cb_err ret = mipi_panel_parse_init_commands(init_cmds, mdss_dsi_send_init_cmd, - NULL); + enum cb_err ret = mipi_panel_parse_commands(init_cmds, mdss_dsi_send_init_cmd, NULL); write32(&dsi0->ctrl, ctrl_mode); mdss_dsi_clear_intr(); diff --git a/src/soc/qualcomm/sc7280/display/edp_aux.c b/src/soc/qualcomm/sc7280/display/edp_aux.c index 9d330a61d10..0f37c21b479 100644 --- a/src/soc/qualcomm/sc7280/display/edp_aux.c +++ b/src/soc/qualcomm/sc7280/display/edp_aux.c @@ -179,7 +179,7 @@ int edp_read_edid(struct edid *out) } if (edid[EDID_EXTENSION_FLAG]) { - printk(BIOS_ERR, " read EDID ext block.\n"); + printk(BIOS_INFO, " read EDID ext block.\n"); edid_size += EDID_LENGTH; reg_addr = EDID_LENGTH; err = edp_aux_transfer(EDID_I2C_ADDR, DP_AUX_I2C_WRITE, ®_addr, 1); diff --git a/src/soc/qualcomm/x1p42100/Makefile.mk b/src/soc/qualcomm/x1p42100/Makefile.mk index abf5971e20f..68eff9a46b5 100644 --- a/src/soc/qualcomm/x1p42100/Makefile.mk +++ b/src/soc/qualcomm/x1p42100/Makefile.mk @@ -53,6 +53,10 @@ ramstage-y += ../common/spmi.c ramstage-$(CONFIG_PCI) += pcie.c ramstage-y += cpucp_load_reset.c ramstage-y += ../common/cmd_db.c +ramstage-y += ../common/rpmh.c ../common/rpmh_bcm.c ../common/rpmh_regulator.c ../common/rpmh_rsc.c +ramstage-y += rpmh_rsc_init.c +ramstage-y += display/disp.c +ramstage-y += lpass.c ################################################################################ @@ -63,9 +67,14 @@ CPPFLAGS_common += -Isrc/soc/qualcomm/common/include # look for QC blobs if QC SoC blobs are only available in upstream else ignore ifeq ($(CONFIG_QC_BLOBS_UPSTREAM),y) ifeq ($(CONFIG_USE_QC_BLOBS),y) -# TODO: Upload X1P42100 SoC blobs X1P42100_BLOB := $(top)/3rdparty/qc_blobs/x1p42100 +ifeq ($(CONFIG_QC_SECURE_BOOT_BLOBS),y) +BLOB_VARIANT := secure +else +BLOB_VARIANT := non_secure +endif + ifeq ($(CONFIG_SOC_QUALCOMM_HAMOA),y) DTB_DCB_BLOB_PATH := hamoa else @@ -90,9 +99,9 @@ cbfs-files-y += $(QCSDI_CBFS) endif ################################################################################ -QC_SEC_FILE := $(X1P42100_BLOB)/qc_sec/qc_sec.mbn -TME_SEQ_FILE := $(X1P42100_BLOB)/tme/sequencer_ram.elf -TME_FW_FILE := $(X1P42100_BLOB)/tme/signed_firmware_soc_view.elf +QC_SEC_FILE := $(X1P42100_BLOB)/$(BLOB_VARIANT)/qc_sec/qc_sec.mbn +TME_SEQ_FILE := $(X1P42100_BLOB)/$(BLOB_VARIANT)/tme/sequencer_ram.elf +TME_FW_FILE := $(X1P42100_BLOB)/$(BLOB_VARIANT)/tme/signed_firmware_soc_view.elf $(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.raw.elf @util/qualcomm/createxbl.py --mbn_version 7 -f $(objcbfs)/bootblock.raw.elf \ @@ -161,7 +170,7 @@ $(I2C_FW_CBFS)-compression := none cbfs-files-y += $(I2C_FW_CBFS) ################################################################################ -AOP_FILE := $(X1P42100_BLOB)/aop/aop.mbn +AOP_FILE := $(X1P42100_BLOB)/$(BLOB_VARIANT)/aop/aop.mbn AOP_CBFS := $(CONFIG_CBFS_PREFIX)/aop $(AOP_CBFS)-file := $(AOP_FILE) $(AOP_CBFS)-type := payload @@ -171,7 +180,7 @@ cbfs-files-y += $(AOP_CBFS) ################################################################################ # Rule to create aop_meta from aop.mbn # This rule depends on aop.mbn built and the extractor script existing. -$(obj)/mainboard/$(MAINBOARDDIR)/aop_meta: $(X1P42100_BLOB)/aop/aop.mbn util/qualcomm/elf_segment_extractor.py +$(obj)/mainboard/$(MAINBOARDDIR)/aop_meta: $(X1P42100_BLOB)/$(BLOB_VARIANT)/aop/aop.mbn util/qualcomm/elf_segment_extractor.py @echo "Extracting ELF headers and hash table segment from $< to $@" @util/qualcomm/elf_segment_extractor.py --eh --pht --hashtable $< $@ @@ -183,7 +192,7 @@ $(AOP_META_CBFS)-compression := $(CBFS_COMPRESS_FLAG) cbfs-files-y += $(AOP_META_CBFS) ################################################################################ -AOP_CFG_FILE := $(X1P42100_BLOB)/aop/aop_devcfg.mbn +AOP_CFG_FILE := $(X1P42100_BLOB)/$(BLOB_VARIANT)/aop/aop_devcfg.mbn AOP_CFG_CBFS := $(CONFIG_CBFS_PREFIX)/aop_cfg $(AOP_CFG_CBFS)-file := $(AOP_CFG_FILE) $(AOP_CFG_CBFS)-type := payload @@ -193,7 +202,7 @@ cbfs-files-y += $(AOP_CFG_CBFS) ################################################################################ # Rule to create aop_meta from aop_devcfg.mbn # This rule depends on aop_devcfg.mbn built and the extractor script existing. -$(obj)/mainboard/$(MAINBOARDDIR)/aop_devcfg_meta: $(X1P42100_BLOB)/aop/aop_devcfg.mbn util/qualcomm/elf_segment_extractor.py +$(obj)/mainboard/$(MAINBOARDDIR)/aop_devcfg_meta: $(X1P42100_BLOB)/$(BLOB_VARIANT)/aop/aop_devcfg.mbn util/qualcomm/elf_segment_extractor.py @echo "Extracting ELF headers and hash table segment from $< to $@" @util/qualcomm/elf_segment_extractor.py --eh --pht --hashtable $< $@ @@ -235,7 +244,7 @@ $(CPUCP_DTBS_CBFS)-compression := $(CBFS_COMPRESS_FLAG) cbfs-files-y += $(CPUCP_DTBS_CBFS) ################################################################################ -SHRM_FILE := $(X1P42100_BLOB)/shrm/shrm.elf +SHRM_FILE := $(X1P42100_BLOB)/$(BLOB_VARIANT)/shrm/shrm.elf SHRM_CBFS := $(CONFIG_CBFS_PREFIX)/shrm $(SHRM_CBFS)-file := $(SHRM_FILE) $(SHRM_CBFS)-type := payload @@ -245,7 +254,7 @@ cbfs-files-y += $(SHRM_CBFS) ################################################################################ # Rule to create shrm_meta from shrm.elf # This rule depends on shrm.elf being built and the extractor script existing. -$(obj)/mainboard/$(MAINBOARDDIR)/shrm_meta: $(X1P42100_BLOB)/shrm/shrm.elf util/qualcomm/elf_segment_extractor.py +$(obj)/mainboard/$(MAINBOARDDIR)/shrm_meta: $(X1P42100_BLOB)/$(BLOB_VARIANT)/shrm/shrm.elf util/qualcomm/elf_segment_extractor.py @echo "Extracting ELF headers and hash table segment from $< to $@" @util/qualcomm/elf_segment_extractor.py --eh --pht --hashtable $< $@ diff --git a/src/soc/qualcomm/x1p42100/bootblock.c b/src/soc/qualcomm/x1p42100/bootblock.c index d106912de7e..44641397d2b 100644 --- a/src/soc/qualcomm/x1p42100/bootblock.c +++ b/src/soc/qualcomm/x1p42100/bootblock.c @@ -5,7 +5,7 @@ #include #include -#define SPI_BUS_CLOCK_FREQ (50 * MHz) +#define SPI_BUS_CLOCK_FREQ (75 * MHz) void bootblock_soc_early_init(void) { diff --git a/src/soc/qualcomm/x1p42100/cbmem.c b/src/soc/qualcomm/x1p42100/cbmem.c index 6836a3ca840..568f23ab74c 100644 --- a/src/soc/qualcomm/x1p42100/cbmem.c +++ b/src/soc/qualcomm/x1p42100/cbmem.c @@ -6,5 +6,5 @@ uintptr_t cbmem_top_chipset(void) { - return (uintptr_t)CBMEM_TOP; + return (uintptr_t)_dram_pil; } diff --git a/src/soc/qualcomm/x1p42100/clock.c b/src/soc/qualcomm/x1p42100/clock.c index 377f529a08f..eba4987217e 100644 --- a/src/soc/qualcomm/x1p42100/clock.c +++ b/src/soc/qualcomm/x1p42100/clock.c @@ -28,6 +28,11 @@ static struct clock_freq_config qspi_core_cfg[] = { .src = SRC_GPLL0_MAIN_600MHZ, .div = QCOM_CLOCK_DIV(3), }, + { + .hz = 300 * MHz, + .src = SRC_GPLL0_MAIN_600MHZ, + .div = QCOM_CLOCK_DIV(2), + }, { .hz = 400 * MHz, .src = SRC_GPLL0_MAIN_600MHZ, @@ -294,6 +299,26 @@ static u32 *usb_sec_cbcr[USB_SEC_CLK_COUNT] = { [USB_SEC_SYS_NOC_USB_AXI_CBCR] = &gcc->gcc_sys_noc_usb_axi_cbcr, }; +static u32 *disp_gdsc[MAX_DISP_GDSC] = { + [DISP_CC_CORE_GDSC] = &disp_cc->mdss_core_gdscr, +}; + +static u32 *mdss_cbcr[MDSS_CLK_COUNT] = { + [GCC_DISP_AHB_CBCR] = &gcc->gcc_disp_ahb_cbcr, + [GCC_DISP_XO_CBCR] = &gcc->gcc_disp_xo_cbcr, + [GCC_DISP_HF_AXI_CBCR] = &gcc->gcc_disp_hf_axi_cbcr, + [DISP_CC_MDSS_AHB_CBCR] = &disp_cc->mdss_ahb_cbcr, + [DISP_CC_MDSS_MDP_CBCR] = &disp_cc->mdss_mdp_cbcr, + [DISP_CC_MDSS_VSYNC_CBCR] = &disp_cc->mdss_vsync_cbcr, + [DISP_CC_MDSS_RSCC_AHB_CBCR] = &disp_cc->mdss_rscc_ahb_cbcr, + [DISP_CC_MDSS_RSCC_VSYNC_CBCR] = &disp_cc->mdss_rscc_vsync_cbcr, + [DISP_CC_XO_CBCR] = &disp_cc->xo_cbcr, + [DISP_CC_MDSS_DPTX3_PIXEL0_CBCR] = &disp_cc->mdss_dptx3_pixel0_cbcr, + [DISP_CC_MDSS_DPTX3_LINK_CBCR] = &disp_cc->mdss_dptx3_link_cbcr, + [DISP_CC_MDSS_DPTX3_AUX_CBCR] = &disp_cc->mdss_dptx3_aux_cbcr, + [DISP_CC_MDSS_DPTX3_LINK_INTF_CBCR] = &disp_cc->mdss_dptx3_link_intf_cbcr, +}; + static struct clock_freq_config pcie_core_cfg[] = { { .hz = 100 * MHz, @@ -500,6 +525,14 @@ enum cb_err clock_enable_usb_gdsc(enum clk_usb_gdsc gdsc_type) return enable_and_poll_gdsc_status(usb_gdsc[gdsc_type]); } +enum cb_err clock_enable_disp_gdsc(enum clk_disp_gdsc gdsc_type) +{ + if (gdsc_type >= MAX_DISP_GDSC) + return CB_ERR; + + return enable_and_poll_gdsc_status(disp_gdsc[gdsc_type]); +} + enum cb_err usb_clock_enable(enum clk_usb clk_type) { if (clk_type >= USB_CLK_COUNT) @@ -623,6 +656,45 @@ static enum cb_err pll_init_and_set(struct x1p42100_ncc0_clock *ncc0, u32 l_val) return CB_SUCCESS; } +enum cb_err disp_pll_init_and_set(struct x1p42100_disp_pll_clock *disp_pll, u32 l_val, u32 alpha_val) +{ + int ret; + struct alpha_pll_reg_val_config disp_pll_cfg = {0}; + + disp_pll_cfg.reg_l = &disp_pll->pll_l; + disp_pll_cfg.l_val = l_val; + + disp_pll_cfg.reg_alpha = &disp_pll->pll_alpha; + disp_pll_cfg.alpha_val = alpha_val; + + disp_pll_cfg.reg_user_ctl = &disp_pll->pll_user_ctl; + disp_pll_cfg.user_ctl_val = 0x1; + + clock_configure_enable_gpll(&disp_pll_cfg, false, 0); + + disp_pll_cfg.reg_mode = &disp_pll->pll_mode; + disp_pll_cfg.reg_opmode = &disp_pll->pll_opmode; + ret = lucidole_pll_enable(&disp_pll_cfg); + if (ret != CB_SUCCESS) + return CB_ERR; + + return CB_SUCCESS; +} + +enum cb_err mdss_clock_enable(enum clk_mdss clk_type) +{ + if (clk_type >= MDSS_CLK_COUNT) + return CB_ERR; + + /* Enable clock */ + return clock_enable(mdss_cbcr[clk_type]); +} + +void enable_disp_clock_tcsr(void) +{ + write32(TCSR_GCC_EDP_CLKREF_EN_ADDR, 0x1); +} + static void speed_up_boot_cpu(void) { /* 1363.2 MHz */ diff --git a/src/soc/qualcomm/x1p42100/display/disp.c b/src/soc/qualcomm/x1p42100/display/disp.c new file mode 100644 index 00000000000..f4a999ec80c --- /dev/null +++ b/src/soc/qualcomm/x1p42100/display/disp.c @@ -0,0 +1,132 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct clock_freq_config disp_cc_mdss_ahb_cfg[] = { + { + .hz = SRC_XO_HZ, /* 19.2MHz */ + .src = SRC_XO_19_2MHZ_AHB, + .div = QCOM_CLOCK_DIV(1), + }, + { + .hz = CLK_37_5MHZ, + .src = SRC_DISP_CC_PLL1_MAIN_AHB, + .div = QCOM_CLOCK_DIV(16), + }, + { + .hz = CLK_75MHZ, + .src = SRC_DISP_CC_PLL1_MAIN_AHB, + .div = QCOM_CLOCK_DIV(8), + }, +}; + +static struct clock_freq_config disp_cc_mdss_mdp_cfg[] = { + { + .hz = CLK_575MHZ, + .src = SRC_DISP_CC_PLL0_MAIN_MDP, + .div = QCOM_CLOCK_DIV(3), + }, + { + .hz = CLK_400MHZ, + .src = SRC_DISP_CC_PLL1_MAIN_MDP, + .div = QCOM_CLOCK_DIV(1.5), + }, +}; + +void enable_mdss_clk(void) +{ + /* + * Display clock initialization sequence + * 1. Enable GCC clocks (AHB, AXI) - GCC clocks that are required for display + * 2. Enable GDSC (power domain) - powers up the display subsystem + * 3. Initialize display PLLs - required to use clock sources from disp_cc domain + * 4. Configure and enable disp_cc clocks - enable display clocks + */ + mdss_clock_enable(GCC_DISP_AHB_CBCR); + clock_enable_disp_gdsc(DISP_CC_CORE_GDSC); + mdss_clock_enable(GCC_DISP_HF_AXI_CBCR); + disp_pll_init_and_set(apss_disp_pll0, L_VAL_1725MHz, DISP_PLL0_ALPHA_VAL); + disp_pll_init_and_set(apss_disp_pll1, L_VAL_600MHz, DISP_PLL1_ALPHA_VAL); + clock_configure(&disp_cc->mdss_ahb_rcg, + disp_cc_mdss_ahb_cfg, CLK_75MHZ, ARRAY_SIZE(disp_cc_mdss_ahb_cfg)); + mdss_clock_enable(DISP_CC_MDSS_AHB_CBCR); + clock_configure(&disp_cc->mdss_mdp_rcg, + disp_cc_mdss_mdp_cfg, CLK_575MHZ, ARRAY_SIZE(disp_cc_mdss_mdp_cfg)); + mdss_clock_enable(DISP_CC_MDSS_MDP_CBCR); + mdss_clock_enable(DISP_CC_MDSS_VSYNC_CBCR); + enable_disp_clock_tcsr(); +} + +/** + * display_rpmh_init() - Initialize RPMh for display power management + * + * Initializes the RPMh (Resource Power Manager-Hardened) subsystem for display: + * - Waits for AOP boot + * - Initializes Command DB and RPMh RSC (Resource State Coordinator) + * - Configures MMCX ARC regulator for display power rail + * - Votes for MM0 BCM (Bus Clock Manager) for display bus clocks + * + * Return: CB_SUCCESS on success, CB_ERR on failure + */ +enum cb_err display_rpmh_init(void) +{ + enum cb_err ret; + struct rpmh_vreg arc_reg; + int rc; + volatile u32 *boot_cookie = (volatile u32 *)AOP_BOOT_COOKIE_ADDR; + + if (!wait_us(AOP_BOOT_TIMEOUT_US, *boot_cookie == AOP_BOOT_COOKIE)) { + printk(BIOS_ERR, "AOP not booted after %dus (cookie: 0x%x, expected: 0x%x)\n", + AOP_BOOT_TIMEOUT_US, *boot_cookie, AOP_BOOT_COOKIE); + return CB_ERR; + } + + printk(BIOS_INFO, "AOP boot detected (cookie: 0x%x)\n", *boot_cookie); + + ret = cmd_db_init(CMD_DB_BASE_ADDR, CMD_DB_SIZE); + if (ret != CB_SUCCESS) { + printk(BIOS_ERR, "Failed to initialize Command DB\n"); + return CB_ERR; + } + + rc = rpmh_rsc_init(); + if (rc) { + printk(BIOS_ERR, "Failed to initialize RPMh RSC\n"); + return CB_ERR; + } + + rc = rpmh_regulator_init(&arc_reg, "mmcx.lvl", RPMH_REGULATOR_TYPE_ARC); + if (rc) { + printk(BIOS_ERR, "Failed to initialize display power rail mmcx ARC regulator\n"); + return CB_ERR; + } + + printk(BIOS_INFO, "ARC regulator initialized successfully\n"); + + rc = rpmh_regulator_arc_set_level(&arc_reg, RPMH_REGULATOR_LEVEL_MIN_MM0, true, false); + if (rc) { + printk(BIOS_ERR, "Failed to set ARC level\n"); + return CB_ERR; + } + + printk(BIOS_INFO, "ARC level was set successfully\n"); + + rc = rpmh_bcm_vote("MM0", BCM_MM0_VOTE_VALUE); + if (rc) { + printk(BIOS_ERR, "Failed to send BCM vote for display bus clock manager MM0\n"); + return CB_ERR; + } + + printk(BIOS_INFO, "BCM vote for MM0 sent successfully\n"); + + return CB_SUCCESS; +} diff --git a/src/soc/qualcomm/x1p42100/include/soc/addressmap.h b/src/soc/qualcomm/x1p42100/include/soc/addressmap.h index 1c309a06d4e..dc45a668d66 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/addressmap.h +++ b/src/soc/qualcomm/x1p42100/include/soc/addressmap.h @@ -18,7 +18,19 @@ #define DISP_PLL1_BASE 0xAF01000 #define DISP_CC_BASE 0xAF08000 -#define CBMEM_TOP 0xC7800000 +/* LPASS BASE ADDRESSES */ +#define LPASS_BASE 0x06000000 +#define LPASS_AUDIO_CC_PLL_BASE (LPASS_BASE + 0x00BC0000) +#define LPASS_AON_CC_BASE (LPASS_BASE + 0x00E08000) +#define LPASS_AON_CC_PLL_CM_BASE (LPASS_BASE + 0x00E01000) +#define LPASS_CORE_GDSC_REG_BASE (LPASS_BASE + 0x01E00000) + +#define RPMH_BASE 0x17520000 +#define CMD_DB_BASE_ADDR 0x81c60000 +#define CMD_DB_SIZE 0x20000 + +#define AOP_BOOT_COOKIE_ADDR 0xC3F0040 + /* X1P42100 NCC0 PLL CONFIG ADDRESSES */ #define NCC0_NCC_CMU_NCC_PLL_CFG 0x199A2010 #define NCC0_NCC_CMU_NCC_CLK_CFG 0x199A2030 diff --git a/src/soc/qualcomm/x1p42100/include/soc/clock.h b/src/soc/qualcomm/x1p42100/include/soc/clock.h index da082f66bd6..c126baac622 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/clock.h +++ b/src/soc/qualcomm/x1p42100/include/soc/clock.h @@ -16,6 +16,7 @@ #define CLK_400MHZ (400 * MHz) #define CLK_75MHZ (75 * MHz) #define CLK_575MHZ (575 * MHz) +#define CLK_37_5MHZ (37.5 * MHz) /* CPU PLL*/ #define L_VAL_1363P2MHz 0x47 @@ -59,6 +60,15 @@ enum clk_ctl_gpll_user_ctl_x1p42100 { PLL_POST_DIV_ODD_SHFT_X1P42100 = 14, }; +enum clk_ctl_lpass_aon_cc_pll_user_ctl_x1p42100 { + AON_CC_PLL_PLLOUT_MAIN_SHFT_X1P42100 = 0, + AON_CC_PLL_PLLOUT_EVEN_SHFT_X1P42100 = 1, + AON_CC_PLL_PLLOUT_ODD_SHFT_X1P42100 = 2, + AON_CC_PLL_POST_DIV_EVEN_SHFT_X1P42100 = 10, + AON_CC_PLL_POST_DIV_ODD_SHFT_X1P42100 = 14, + AON_CC_PLL_ENABLE_VOTE_RUN = 25 +}; + enum clk_pll_src { SRC_XO_19_2MHZ = 0, SRC_GPLL0_MAIN_600MHZ = 1, @@ -192,6 +202,102 @@ struct x1p42100_disp_pll_clock { u32 pll_user_ctl_u; }; +/* LPASS AON CC PLL register structure */ +struct x1p42100_lpass_aon_cc_pll_clock { + u32 pll_mode; + u32 pll_opmode; + u32 pll_state; + u32 pll_status; + u32 pll_l_val; + u32 pll_alpha_val; + u32 pll_user_ctl; + u32 pll_user_ctl_u; + u32 pll_config_ctl; + u32 pll_config_ctl_u; + u32 pll_config_ctl_u1; + u32 pll_test_ctl; + u32 pll_test_ctl_u; + u32 pll_test_ctl_u1; + u32 pll_test_ctl_u2; +}; + +/* LPASS Audio CC register structure */ +struct x1p42100_lpass_audio_cc { + u8 _res0[0x28018]; + u32 codec_ext_mclk0_cbcr; + u8 _res1[0xffc]; + u32 codec_ext_mclk1_cbcr; + u8 _res2[0x10b0]; + u32 wsa_mclk_2x_cbcr; + u8 _res3[0x4]; + u32 wsa_mclk_cbcr; + u8 _res4[0x18]; + u32 tx_mclk_2x_wsa_cbcr; + u32 tx_mclk_wsa_cbcr; + u8 _res5[0x2f08]; + u32 wsa2_mclk_2x_cbcr; + u32 wsa2_mclk_cbcr; + u32 tx_mclk_wsa2_cbcr; + u32 tx_mclk_2x_wsa2_cbcr; + u8 _res6[0xff0]; + u32 codec_mem_cbcr; + u32 codec_mem0_cbcr; + u32 codec_mem0_sregr; + u32 codec_mem0_cfg_sregr; + u32 codec_mem1_cbcr; + u32 codec_mem1_sregr; + u32 codec_mem1_cfg_sregr; + u32 codec_mem2_cbcr; + u32 codec_mem2_sregr; + u32 codec_mem2_cfg_sregr; + u32 codec_mem3_cbcr; + u32 codec_mem3_sregr; + u32 codec_mem3_cfg_sregr; +}; + +check_member(x1p42100_lpass_audio_cc, codec_ext_mclk0_cbcr, 0x28018); +check_member(x1p42100_lpass_audio_cc, codec_ext_mclk1_cbcr, 0x29018); +check_member(x1p42100_lpass_audio_cc, wsa_mclk_2x_cbcr, 0x2A0CC); +check_member(x1p42100_lpass_audio_cc, wsa_mclk_cbcr, 0x2A0D4); +check_member(x1p42100_lpass_audio_cc, tx_mclk_2x_wsa_cbcr, 0x2A0F0); +check_member(x1p42100_lpass_audio_cc, wsa2_mclk_2x_cbcr, 0x2D000); +check_member(x1p42100_lpass_audio_cc, codec_mem_cbcr, 0x2E000); + +/* LPASS Core GDSC register structure */ +struct x1p42100_lpass_core_gdsc { + u32 core_hm_gdscr; + u8 _res0[0xB4]; + u32 lpass_core_gds_hm_ready; + u8 _res1[0x8F44]; + u32 lpass_top_cc_lpass_core_sway_ahb_ls_cbcr; +}; + +check_member(x1p42100_lpass_core_gdsc, lpass_core_gds_hm_ready, 0x000B8); +check_member(x1p42100_lpass_core_gdsc, lpass_top_cc_lpass_core_sway_ahb_ls_cbcr, 0x09000); + +/* LPASS AON CC register structure */ +struct x1p42100_lpass_aon_cc { + u8 _res0[0x9060]; + u32 va_mem0_cbcr; + u8 _res1[0x2c]; + u32 lpass_audio_hm_gdscr; + u8 _res2[0x2f6c]; + u32 lpass_hm_collapse_vote_for_q6; + u8 _res3[0x6008]; + u32 va_2x_cbcr; + u8 _res4[0x4]; + u32 va_cbcr; + u8 _res5[0xffc]; + u32 tx_mclk_cbcr; +}; + +check_member(x1p42100_lpass_aon_cc, va_mem0_cbcr, 0x9060); +check_member(x1p42100_lpass_aon_cc, lpass_audio_hm_gdscr, 0x9090); +check_member(x1p42100_lpass_aon_cc, lpass_hm_collapse_vote_for_q6, 0xc000); +check_member(x1p42100_lpass_aon_cc, va_2x_cbcr, 0x1200C); +check_member(x1p42100_lpass_aon_cc, va_cbcr, 0x12014); +check_member(x1p42100_lpass_aon_cc, tx_mclk_cbcr, 0x13014); + struct x1p42100_disp_cc { uint8_t _res0[0x00C]; uint32_t mdss_mdp_cbcr; @@ -413,80 +519,82 @@ struct x1p42100_gcc { u32 gcc_aggre_usb3_prim_axi_cbcr; u8 _res36[0x42004 - 0x39094]; struct qupv3_clock qup_wrap0_s[8]; - u8 _res37[0x4b000 - 0x429c4]; + u8 _res37[0x47000 - 0x429c4]; + u32 lpass_cfg_noc_sway_cbcr; + u8 _res38[0x4b000 - 0x47004]; u32 qspi_bcr; u32 qspi_cnoc_ahb_cbcr; u32 qspi_core_cbcr; struct clock_rcg qspi_core; - u8 _res38[0x50000 - 0x4b014]; + u8 _res39[0x50000 - 0x4b014]; u32 gcc_usb3_phy_prim_bcr; u32 gcc_usb3phy_phy_prim_bcr; - u8 _res39[0x50010 - 0x50008]; + u8 _res40[0x50010 - 0x50008]; u32 gcc_usb4_0_dp0_phy_prim_bcr; - u8 _res40[0x52000 - 0x50014]; + u8 _res41[0x52000 - 0x50014]; u32 apcs_clk_br_en; - u8 _res41[0x52008 - 0x52004]; + u8 _res42[0x52008 - 0x52004]; u32 apcs_clk_br_en1; - u8 _res42[0x52010 - 0x5200c]; + u8 _res43[0x52010 - 0x5200c]; u32 apcs_clk_br_en2; - u8 _res43[0x52018 - 0x52014]; + u8 _res44[0x52018 - 0x52014]; u32 apcs_clk_br_en3; - u8 _res44[0x52020 - 0x5201c]; + u8 _res45[0x52020 - 0x5201c]; u32 apcs_clk_br_en4; - u8 _res45[0x52028 - 0x52024]; + u8 _res46[0x52028 - 0x52024]; u32 apcs_clk_br_en5; - u8 _res46[0x52030 - 0x5202c]; + u8 _res47[0x52030 - 0x5202c]; u32 apcs_pll_br_en; - u8 _res47[0x54000 - 0x52034]; + u8 _res48[0x54000 - 0x52034]; u32 usb3_uniphy_mp1_bcr; u32 usb3uniphy_phy_mp1_bcr; u32 gcc_usb3_mp_ss1_phy_bcr; u32 gcc_usb3_mp_ss1_phy_gdscr; - u8 _res48[0x8e000 - 0x54010]; + u8 _res49[0x8e000 - 0x54010]; u32 pcie_6_phy_gdscr; - u8 _res49[0xa1000 - 0x8e004]; + u8 _res50[0xa1000 - 0x8e004]; u32 gcc_usb30_sec_bcr; u32 gcc_usb30_sec_gdscr; - u8 _res50[0xa1018 - 0xa1008]; + u8 _res51[0xa1018 - 0xa1008]; u32 gcc_usb30_sec_master_cbcr; - u8 _res51[0xa1024 - 0xa101c]; + u8 _res52[0xa1024 - 0xa101c]; u32 gcc_usb30_sec_sleep_cbcr; u32 gcc_usb30_sec_mock_utmi_cbcr; struct clock_rcg usb30_sec_master_rcg; - u8 _res52[0xa1060 - 0xa1034]; + u8 _res53[0xa1060 - 0xa1034]; u32 gcc_usb3_sec_phy_aux_cbcr; u32 gcc_usb3_sec_phy_com_aux_cbcr; u32 gcc_usb3_sec_phy_pipe_cbcr; u32 gcc_usb3_sec_phy_pipe_muxr; - u8 _res53[0xa108c - 0xa1070]; + u8 _res54[0xa108c - 0xa1070]; u32 gcc_cfg_noc_usb3_sec_axi_cbcr; u32 gcc_aggre_usb3_sec_axi_cbcr; - u8 _res54[0xa2000 - 0xa1094]; + u8 _res55[0xa2000 - 0xa1094]; u32 gcc_usb30_tert_bcr; u32 gcc_usb30_tert_gdscr; - u8 _res55[0xa2018 - 0xa2008]; + u8 _res56[0xa2018 - 0xa2008]; u32 gcc_usb30_tert_master_cbcr; - u8 _res56[0xa2024 - 0xa201c]; + u8 _res57[0xa2024 - 0xa201c]; u32 gcc_usb30_tert_sleep_cbcr; u32 gcc_usb30_tert_mock_utmi_cbcr; - u8 _res57[0xa2034 - 0xa202c]; + u8 _res58[0xa2034 - 0xa202c]; u32 gcc_usb30_tert_master_m; u32 gcc_usb30_tert_master_n; u32 gcc_usb30_tert_master_d; - u8 _res58[0xa2060 - 0xa2040]; + u8 _res59[0xa2060 - 0xa2040]; u32 gcc_usb3_tert_phy_aux_cbcr; u32 gcc_usb3_tert_phy_com_aux_cbcr; u32 gcc_usb3_tert_phy_pipe_cbcr; u32 gcc_usb3_tert_phy_pipe_muxr; - u8 _res59[0xa208c - 0xa2070]; + u8 _res60[0xa208c - 0xa2070]; u32 gcc_cfg_noc_usb3_tert_axi_cbcr; u32 gcc_aggre_usb3_tert_axi_cbcr; - u8 _res60[0xa3000 - 0xa2094]; + u8 _res61[0xa3000 - 0xa2094]; u32 gcc_usb3_phy_tert_bcr; u32 gcc_usb3phy_phy_tert_bcr; - u8 _res61[0xa3010 - 0xa3008]; + u8 _res62[0xa3010 - 0xa3008]; u32 gcc_usb4_2_dp0_phy_tert_bcr; - u8 _res62[0xac01c - 0xa3014]; + u8 _res63[0xac01c - 0xa3014]; u32 pcie_6a_phy_bcr; }; @@ -535,6 +643,7 @@ check_member(x1p42100_gcc, gcc_aggre_usb_noc_axi_cbcr, 0x2d034); check_member(x1p42100_gcc, gcc_aggre_noc_usb_south_axi_cbcr, 0x2d174); check_member(x1p42100_gcc, gcc_aggre_noc_usb_north_axi_cbcr, 0x2d17c); check_member(x1p42100_gcc, qup_wrap0_s, 0x42004); +check_member(x1p42100_gcc, lpass_cfg_noc_sway_cbcr, 0x47000); check_member(x1p42100_gcc, qspi_bcr, 0x4b000); check_member(x1p42100_gcc, apcs_clk_br_en, 0x52000); check_member(x1p42100_gcc, apcs_clk_br_en1, 0x52008); @@ -734,6 +843,29 @@ enum clk_usb_phy_src_sel { USB_PHY_XO_SRC_SEL = 2, }; +enum clk_lpass { + LPASS_CODEC_MEM_CBCR, + LPASS_CODEC_MEM0_CBCR, + LPASS_CODEC_MEM1_CBCR, + LPASS_CODEC_MEM2_CBCR, + LPASS_CODEC_MEM3_CBCR, + LPASS_EXT_MCLK0_CBCR, + LPASS_EXT_MCLK1_CBCR, + LPASS_TX_MCLK_CBCR, + LPASS_TX_MCLK_2X_WSA_CBCR, + LPASS_TX_MCLK_WSA_CBCR, + LPASS_WSA_MCLK_2X_CBCR, + LPASS_WSA_MCLK_CBCR, + LPASS_TX_MCLK_2X_WSA2_CBCR, + LPASS_TX_MCLK_WSA2_CBCR, + LPASS_WSA2_MCLK_2X_CBCR, + LPASS_WSA2_MCLK_CBCR, + LPASS_VA_MEM0_CBCR, + LPASS_VA_CBCR, + LPASS_VA_2X_CBCR, + LPASS_CLK_COUNT +}; + enum subsystem_reset { AOP_RESET_SHFT, CORE_SW_RESET, @@ -745,14 +877,22 @@ void clock_enable_qup(int qup); void clock_configure_dfsr(int qup); void clock_configure_pcie(void); void clock_configure_usb(void); +void enable_disp_clock_tcsr(void); +void enable_mdss_clk(void); enum cb_err clock_enable_gdsc(enum clk_gdsc gdsc_type); enum cb_err clock_enable_pcie(enum clk_pcie clk_type); enum cb_err clock_configure_mux(enum clk_pcie clk_type, u32 src_type); enum cb_err usb_clock_configure_mux(enum clk_pipe_usb clk_type, u32 src_type); enum cb_err usb_clock_enable(enum clk_usb clk_type); enum cb_err clock_enable_usb_gdsc(enum clk_usb_gdsc gdsc_type); +enum cb_err clock_enable_disp_gdsc(enum clk_disp_gdsc gdsc_type); enum cb_err usb_prim_clock_enable(enum clk_usb_prim clk_type); enum cb_err usb_sec_clock_enable(enum clk_usb_sec clk_type); +enum cb_err mdss_clock_enable(enum clk_mdss clk_type); +enum cb_err disp_pll_init_and_set(struct x1p42100_disp_pll_clock *disp_pll, + u32 l_val, u32 alpha_val); +enum cb_err lpass_init(void); + void clock_configure_dfsr_table_x1p42100(int qup, struct clock_freq_config *clk_cfg, uint32_t num_perfs); @@ -771,6 +911,12 @@ static struct x1p42100_qupv3_wrap *const qup_wrap0_clk = (void *)GCC_QUPV3_WRAP0 static struct x1p42100_qupv3_wrap *const qup_wrap1_clk = (void *)GCC_QUPV3_WRAP1_BASE; static struct x1p42100_qupv3_wrap *const qup_wrap2_clk = (void *)GCC_QUPV3_WRAP2_BASE; +/* Static pointers to LPASS register blocks */ +static struct x1p42100_lpass_audio_cc *const lpass_audio_cc = (void *)LPASS_AUDIO_CC_PLL_BASE; +static struct x1p42100_lpass_aon_cc *const lpass_aon_cc = (void *)LPASS_AON_CC_BASE; +static struct x1p42100_lpass_aon_cc_pll_clock *const lpass_aon_cc_pll = (void *)LPASS_AON_CC_PLL_CM_BASE; +static struct x1p42100_lpass_core_gdsc *const lpass_core_gdsc = (void *)LPASS_CORE_GDSC_REG_BASE; + /* Does nothing */ #define clock_reset_aop() do {} while (0) /* Does nothing */ diff --git a/src/soc/qualcomm/x1p42100/include/soc/lpass.h b/src/soc/qualcomm/x1p42100/include/soc/lpass.h new file mode 100644 index 00000000000..0b5a8bd4dd4 --- /dev/null +++ b/src/soc/qualcomm/x1p42100/include/soc/lpass.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_QUALCOMM_X1P42100_LPASS_H_ +#define _SOC_QUALCOMM_X1P42100_LPASS_H_ + +#include + +/* LPASS AON CC PLL Settings */ +#define HAL_CLK_LPASS_AON_CC_PLL_L_VALUE 0x00000020 +#define HAL_CLK_LPASS_AON_CC_PLL_ALPHA_VALUE 0x00000000 +#define HAL_CLK_LPASS_AON_CC_PLL_RING_CAL_L_VALUE (0x44 << 16) +#define HAL_CLK_LPASS_AON_CC_PLL_PROC_CAL_L_VALUE (0x44 << 24) +#define HAL_CLK_LPASS_AON_CC_PLL_CONFIG_CTL 0x20485699 +#define HAL_CLK_LPASS_AON_CC_PLL_CONFIG_CTL_U 0x00182261 +#define HAL_CLK_LPASS_AON_CC_PLL_CONFIG_CTL_U1 0x82AA299C +#define HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL 0x00000000 +#define HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL_U 0x00000003 +#define HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL_U1 0x00009000 +#define HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL_U2 0x00000034 +#define HAL_CLK_LPASS_AON_CC_PLL_USER_CTL 0x00E00041 +#define HAL_CLK_LPASS_AON_CC_PLL_USER_CTL_U 0x00000105 + +#define LPASS_CORE_HM_READY BIT(0) +#define HW_CTL BIT(1) +#define GDSC_ENABLE_BIT 0 + +#define LPASS_CORE_HM_VOTE_POWER_ON 0x0 +#define GDSC_PWR_ON BIT(31) + +#define BCM_LP0_VOTE_VALUE 0x60004001 +#endif /* _SOC_QUALCOMM_X1P42100_LPASS_H_ */ diff --git a/src/soc/qualcomm/x1p42100/include/soc/rpmh_config.h b/src/soc/qualcomm/x1p42100/include/soc/rpmh_config.h new file mode 100644 index 00000000000..c1f9c4630ce --- /dev/null +++ b/src/soc/qualcomm/x1p42100/include/soc/rpmh_config.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_QUALCOMM_X1P42100_RPMH_CONFIG_H_ +#define _SOC_QUALCOMM_X1P42100_RPMH_CONFIG_H_ + +#include + +/* + * X1P42100 RPMh RSC Configuration + */ + +#define RPMH_RSC_DRV_ID 2 + +#define RPMH_TCS_OFFSET 0xd00 +#define RPMH_TCS_DISTANCE 0x2a0 + +/* TCS Configuration */ +#define RPMH_NUM_ACTIVE_TCS 2 +#define RPMH_NUM_SLEEP_TCS 3 +#define RPMH_NUM_WAKE_TCS 3 +#define RPMH_NUM_CONTROL_TCS 0 +#define RPMH_NUM_FAST_PATH_TCS 0 + +#define RPMH_NUM_CHANNELS 1 + +#define RPMH_HW_SOLVER_SUPPORTED true +#define RPMH_HW_CHANNEL_MODE false + +#define RPMH_RSC_NAME "apps_rsc" + +#define RPMH_REGULATOR_LEVEL_MIN_MM0 1 +#define RPMH_REGULATOR_LEVEL_TURBO_MM0 6 + +#define BCM_MM0_VOTE_VALUE 0x60004001 + +#define AOP_BOOT_COOKIE 0xA0C00C1E +#define AOP_BOOT_TIMEOUT_US 200000 + +int rpmh_rsc_init(void); +enum cb_err display_rpmh_init(void); + +#endif /* _SOC_QUALCOMM_X1P42100_RPMH_CONFIG_H_ */ diff --git a/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h b/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h index 250ae55c70f..b6d1ff50dd4 100644 --- a/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h +++ b/src/soc/qualcomm/x1p42100/include/soc/usb/usb.h @@ -103,24 +103,13 @@ #define SMB2_SLAVE_ID 0x0A /* SCHG DCDC register offsets */ -#define SCHG_DCDC_CMD_OTG 0x2740 #define SCHG_DCDC_OTG_CFG 0x2753 -#define SCHG_DCDC_OTG_STATUS 0x270D -#define SCHG_DCDC_ENG_SDCDC_CFG7 0x27C7 -#define SCHG_DCDC_ENG_SDCDC_GM_CLOOP_PD_OTG_BUCK_MASK 0x30 - -/* OTG Status register bit definitions */ -#define OTG_STATE_MASK 0x07 -#define OTG_STATE_ENABLED 0x02 -#define OTG_STATUS_TIMEOUT_MS 20 -#define OTG_STATUS_POLL_DELAY_MS 2 +#define OTG_BUCK_CFG 0x26 /* Type-C register offsets */ #define SCHG_TYPE_C_TYPE_C_MISC_STATUS 0x2B0B #define SCHG_TYPE_C_TYPE_C_SRC_STATUS 0x2B08 #define SCHG_TYPE_C_TYPE_C_MODE_CFG 0x2B44 -#define TYPEC_VBUS_STATUS_MASK BIT(5) -#define TYPEC_SNK_SRC_MODE BIT(6) #define CCOUT_INVERT_POLARITY 0x03 /* USB Repeater SPMI Tune register offsets */ @@ -151,7 +140,7 @@ int qcom_enable_usb_clk(void); void enable_clock_tcsr(void); /* Enable TCSR CLKREF */ void usb_update_refclk_for_core(u32 core_num, bool enable); -/* Enables VBUS SuperSpeed for specified USB core */ -void enable_vbus_ss(const struct dwc3_controller_config *config); /* Reads comprehensive Type-C status from PMIC */ void usb_typec_status_check(const struct dwc3_controller_config *config); +/* Performs mainboard-specific USB Type-C configuration */ +void mainboard_usb_typec_configure(uint8_t port_num, bool inverse_polarity); diff --git a/src/soc/qualcomm/x1p42100/lpass.c b/src/soc/qualcomm/x1p42100/lpass.c new file mode 100644 index 00000000000..fb96616dbdc --- /dev/null +++ b/src/soc/qualcomm/x1p42100/lpass.c @@ -0,0 +1,148 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include + +static enum cb_err lpass_aon_cc_pll_enable(void) +{ + struct alpha_pll_reg_val_config pll_cfg = {0}; + + pll_cfg.reg_mode = &lpass_aon_cc_pll->pll_mode; + pll_cfg.reg_l = &lpass_aon_cc_pll->pll_l_val; + pll_cfg.l_val = HAL_CLK_LPASS_AON_CC_PLL_L_VALUE | + HAL_CLK_LPASS_AON_CC_PLL_PROC_CAL_L_VALUE | + HAL_CLK_LPASS_AON_CC_PLL_RING_CAL_L_VALUE; + + pll_cfg.reg_alpha = &lpass_aon_cc_pll->pll_alpha_val; + pll_cfg.alpha_val = HAL_CLK_LPASS_AON_CC_PLL_ALPHA_VALUE; + + pll_cfg.reg_cal_l = &lpass_aon_cc_pll->pll_l_val; + + pll_cfg.reg_config_ctl = &lpass_aon_cc_pll->pll_config_ctl; + pll_cfg.config_ctl_val = HAL_CLK_LPASS_AON_CC_PLL_CONFIG_CTL; + pll_cfg.reg_config_ctl_hi = &lpass_aon_cc_pll->pll_config_ctl_u; + pll_cfg.config_ctl_hi_val = HAL_CLK_LPASS_AON_CC_PLL_CONFIG_CTL_U; + pll_cfg.reg_config_ctl_hi1 = &lpass_aon_cc_pll->pll_config_ctl_u1; + pll_cfg.config_ctl_hi1_val = HAL_CLK_LPASS_AON_CC_PLL_CONFIG_CTL_U1; + + pll_cfg.reg_user_ctl = &lpass_aon_cc_pll->pll_user_ctl; + pll_cfg.user_ctl_val = HAL_CLK_LPASS_AON_CC_PLL_USER_CTL; + pll_cfg.reg_user_ctl_hi = &lpass_aon_cc_pll->pll_user_ctl_u; + pll_cfg.user_ctl_hi_val = HAL_CLK_LPASS_AON_CC_PLL_USER_CTL_U; + + pll_cfg.reg_opmode = &lpass_aon_cc_pll->pll_opmode; + + if (clock_configure_enable_gpll(&pll_cfg, false, 0) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: AON CC PLL configuration failed\n"); + return CB_ERR; + } + + write32(&lpass_aon_cc_pll->pll_test_ctl, HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL); + write32(&lpass_aon_cc_pll->pll_test_ctl_u, HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL_U); + write32(&lpass_aon_cc_pll->pll_test_ctl_u1, HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL_U1); + write32(&lpass_aon_cc_pll->pll_test_ctl_u2, HAL_CLK_LPASS_AON_CC_PLL_TEST_CTL_U2); + + setbits32(&lpass_aon_cc_pll->pll_user_ctl, BIT(AON_CC_PLL_ENABLE_VOTE_RUN)); + setbits32(&lpass_aon_cc_pll->pll_mode, BIT(PLL_RESET_SHFT)); + + setbits32(&lpass_aon_cc_pll->pll_user_ctl, (BIT(AON_CC_PLL_PLLOUT_EVEN_SHFT_X1P42100) | + BIT(AON_CC_PLL_PLLOUT_ODD_SHFT_X1P42100))); + + return CB_SUCCESS; +} + +static enum cb_err lpass_setup_core_infrastructure(void) +{ + + if (clock_enable(&gcc->lpass_cfg_noc_sway_cbcr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable CFG NOC SWAY clock\n"); + return CB_ERR; + } + + setbits32(&lpass_core_gdsc->lpass_top_cc_lpass_core_sway_ahb_ls_cbcr, HW_CTL); + + write32(&lpass_aon_cc->lpass_hm_collapse_vote_for_q6, LPASS_CORE_HM_VOTE_POWER_ON); + + if (!wait_us(150000, !(read32(&lpass_core_gdsc->core_hm_gdscr) & GDSC_PWR_ON))) { + printk(BIOS_ERR, "LPASS: Core HM GDSC PWR_ON timeout after vote\n"); + return CB_ERR; + } + + if (!wait_us(1000000, read32(&lpass_core_gdsc->lpass_core_gds_hm_ready) & LPASS_CORE_HM_READY)) { + printk(BIOS_ERR, "LPASS: Core HM ready timeout\n"); + return CB_ERR; + } + + return CB_SUCCESS; +} + +static u32 *lpass_cbcr[LPASS_CLK_COUNT] = { + [LPASS_CODEC_MEM_CBCR] = &lpass_audio_cc->codec_mem_cbcr, + [LPASS_CODEC_MEM0_CBCR] = &lpass_audio_cc->codec_mem0_cbcr, + [LPASS_CODEC_MEM1_CBCR] = &lpass_audio_cc->codec_mem1_cbcr, + [LPASS_CODEC_MEM2_CBCR] = &lpass_audio_cc->codec_mem2_cbcr, + [LPASS_CODEC_MEM3_CBCR] = &lpass_audio_cc->codec_mem3_cbcr, + [LPASS_EXT_MCLK0_CBCR] = &lpass_audio_cc->codec_ext_mclk0_cbcr, + [LPASS_EXT_MCLK1_CBCR] = &lpass_audio_cc->codec_ext_mclk1_cbcr, + [LPASS_TX_MCLK_CBCR] = &lpass_aon_cc->tx_mclk_cbcr, + [LPASS_TX_MCLK_2X_WSA_CBCR] = &lpass_audio_cc->tx_mclk_2x_wsa_cbcr, + [LPASS_TX_MCLK_WSA_CBCR] = &lpass_audio_cc->tx_mclk_wsa_cbcr, + [LPASS_WSA_MCLK_2X_CBCR] = &lpass_audio_cc->wsa_mclk_2x_cbcr, + [LPASS_WSA_MCLK_CBCR] = &lpass_audio_cc->wsa_mclk_cbcr, + [LPASS_TX_MCLK_2X_WSA2_CBCR] = &lpass_audio_cc->tx_mclk_2x_wsa2_cbcr, + [LPASS_TX_MCLK_WSA2_CBCR] = &lpass_audio_cc->tx_mclk_wsa2_cbcr, + [LPASS_WSA2_MCLK_2X_CBCR] = &lpass_audio_cc->wsa2_mclk_2x_cbcr, + [LPASS_WSA2_MCLK_CBCR] = &lpass_audio_cc->wsa2_mclk_cbcr, + [LPASS_VA_MEM0_CBCR] = &lpass_aon_cc->va_mem0_cbcr, + [LPASS_VA_CBCR] = &lpass_aon_cc->va_cbcr, + [LPASS_VA_2X_CBCR] = &lpass_aon_cc->va_2x_cbcr, +}; + +static enum cb_err lpass_audio_clocks_enable(void) +{ + for (size_t i = 0; i < LPASS_CLK_COUNT; i++) { + if (clock_enable(lpass_cbcr[i]) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable audio clock\n"); + return CB_ERR; + } + } + + return CB_SUCCESS; +} + +enum cb_err lpass_init(void) +{ + int rc; + rc = rpmh_bcm_vote("LP0", BCM_LP0_VOTE_VALUE); + if (rc) { + printk(BIOS_ERR, "LPASS: Failed to send BCM vote for LPASS bus clock manager LP0\n"); + return CB_ERR; + } + + if (enable_and_poll_gdsc_status(&lpass_aon_cc->lpass_audio_hm_gdscr) != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable Core HM GDSC\n"); + return CB_ERR; + } + + if (lpass_setup_core_infrastructure() != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to setup core infrastructure\n"); + return CB_ERR; + } + + if (lpass_aon_cc_pll_enable() != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable AON CC PLL\n"); + return CB_ERR; + } + + if (lpass_audio_clocks_enable() != CB_SUCCESS) { + printk(BIOS_ERR, "LPASS: Failed to enable audio clocks\n"); + return CB_ERR; + } + + printk(BIOS_INFO, "LPASS: BCM vote for LP0 and LPASS Init completed successfully\n"); + return CB_SUCCESS; +} diff --git a/src/soc/qualcomm/x1p42100/memlayout.ld b/src/soc/qualcomm/x1p42100/memlayout.ld index 110444a87ac..2c06eccd24e 100644 --- a/src/soc/qualcomm/x1p42100/memlayout.ld +++ b/src/soc/qualcomm/x1p42100/memlayout.ld @@ -41,8 +41,6 @@ * 0xD7800000 +----------------------------------------------------------+ | | * | Linux Kernel Reserve | | | * 0xC7800000 +----------------------------------------------------------+ | | - * | CBMEM | | | - * +----------------------------------------------------------+ | | * | ... Usable memory ... | | | * 0xA1800000 +----------------------------------------------------------+ | | * | RAMSTAGE | DRAM Space 0 | @@ -53,6 +51,8 @@ * 0x91380000 +----------------------------------------------------------+ | | * | dram_pil | | | * 0x866C0000 +----------------------------------------------------------+ | | + * | CBMEM | | | + * +----------------------------------------------------------+ | | * | ... Usable memory ... | | | * 0x85F80000 +----------------------------------------------------------+ | | * | dram_wlan | | | @@ -215,7 +215,7 @@ SECTIONS TTB(0x14842000, 56K) PRERAM_STACK(0x14850000, 16K) VBOOT2_WORK(0x14854000, 12K) - PRERAM_DMA_COHERENT(0x14857000, 8K) + PRERAM_DMA_COHERENT(0x14858000, 8K) REGION(qclib_serial_log, 0x1485B000, 4K, 4K) CBFS_MCACHE(0x1485C000,16K) FMAP_CACHE(0x14860400, 2K) @@ -236,8 +236,8 @@ SECTIONS REGION(shrm, 0x24040000, 128K , 4K) DRAM_START(0x80000000) - POSTRAM_STACK(0x80000000, 16K) - POSTRAM_DMA_COHERENT(0x80004000, 8K) + POSTRAM_STACK(0x80000000, 32K) + POSTRAM_DMA_COHERENT(0x8000C000, 16K) REGION(dram_ncc, 0x80A00000, 0x400000, 4K) REGION(dram_cpucp, 0x80E00000, 0x7A0000, 4K) diff --git a/src/soc/qualcomm/x1p42100/qclib.c b/src/soc/qualcomm/x1p42100/qclib.c index c67b3591f05..6baabccb204 100644 --- a/src/soc/qualcomm/x1p42100/qclib.c +++ b/src/soc/qualcomm/x1p42100/qclib.c @@ -47,15 +47,17 @@ int qclib_soc_override(struct qclib_cb_if_table *table) } qclib_add_if_table_entry(QCLIB_TE_CPR_SETTINGS, _cpr_settings, data_size, 0); - /* Attempt to load shrm_meta Blob */ - data_size = cbfs_load(qclib_file(QCLIB_CBFS_SHRM_META), - _qc_blob_meta, REGION_SIZE(qc_blob_meta)); - if (!data_size) { - printk(BIOS_ERR, "[%s] /shrm_meta failed\n", __func__); - return -1; - } + if (!qclib_check_dload_mode()) { + /* Attempt to load shrm_meta Blob */ + data_size = cbfs_load(qclib_file(QCLIB_CBFS_SHRM_META), + _qc_blob_meta, REGION_SIZE(qc_blob_meta)); + if (!data_size) { + printk(BIOS_ERR, "[%s] /shrm_meta failed\n", __func__); + return -1; + } - qclib_add_if_table_entry(QCLIB_TE_SHRM_META_SETTINGS, _qc_blob_meta, data_size, 0); + qclib_add_if_table_entry(QCLIB_TE_SHRM_META_SETTINGS, _qc_blob_meta, data_size, 0); + } /* hook for platform specific policy configuration */ if (qclib_mainboard_override(table)) { diff --git a/src/soc/qualcomm/x1p42100/rpmh_rsc_init.c b/src/soc/qualcomm/x1p42100/rpmh_rsc_init.c new file mode 100644 index 00000000000..7ddb3ac10d2 --- /dev/null +++ b/src/soc/qualcomm/x1p42100/rpmh_rsc_init.c @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct rsc_drv rsc_driver; +static struct cache_req non_batch_cache[CMD_DB_MAX_RESOURCES]; + +/** + * rpmh_rsc_init - Initialize the RPMh RSC driver + * + * Initializes the RPMh Resource State Coordinator driver with platform-specific configuration. + * Configuration is read from soc/rpmh_config.h for this chipset. + * + * Return: 0 on success, -1 on failure + */ +int rpmh_rsc_init(void) +{ + struct rsc_drv *drv = &rsc_driver; + u32 rsc_id, major_rsc_version, minor_rsc_version, config, max_tcs, ncpt; + int offset; + u32 solver_config; + + /* Check if already initialized */ + if (drv->initialized) { + printk(BIOS_INFO, "RPMH RSC: Already initialized, skipping re-initialization\n"); + return 0; + } + + memset(drv, 0, sizeof(*drv)); + + /* Set configuration from chipset-specific header */ + drv->base = (void *)RPMH_BASE; + drv->tcs_base = (void *)(RPMH_BASE + RPMH_TCS_OFFSET); + drv->tcs_distance = RPMH_TCS_DISTANCE; + drv->id = RPMH_RSC_DRV_ID; + drv->num_channels = RPMH_NUM_CHANNELS; + strncpy(drv->name, RPMH_RSC_NAME, sizeof(drv->name) - 1); + + /* Read hardware version */ + rsc_id = read32(drv->base); + major_rsc_version = (rsc_id >> 16) & 0xFF; + minor_rsc_version = (rsc_id >> 8) & 0xFF; + + /* Select register offsets based on version and HW channel mode */ + if (RPMH_HW_CHANNEL_MODE && major_rsc_version >= 3) { + drv->regs = rpmh_rsc_reg_offset_ver_3_0_hw_channel; + printk(BIOS_INFO, "RPMH RSC: Using v3.0 HW channel register offsets\n"); + } else if (major_rsc_version >= 3) { + drv->regs = rpmh_rsc_reg_offset_ver_3_0; + printk(BIOS_INFO, "RPMH RSC: Using v3.0 register offsets\n"); + } else { + drv->regs = rpmh_rsc_reg_offset_ver_2_7; + printk(BIOS_INFO, "RPMH RSC: Using v2.7 register offsets\n"); + } + + /* Read TCS configuration from hardware */ + config = read32(drv->base + drv->regs[DRV_PRNT_CHLD_CONFIG]); + max_tcs = (config >> (DRV_NUM_TCS_SHIFT * drv->id)) & DRV_NUM_TCS_MASK; + ncpt = (config >> DRV_NCPT_SHIFT) & DRV_NCPT_MASK; + + /* Configure TCS groups for Channel 0 - explicit approach */ + offset = 0; + drv->num_tcs = 0; + + if (RPMH_NUM_ACTIVE_TCS > 0) { + drv->ch[CH0].tcs[ACTIVE_TCS].drv = drv; + drv->ch[CH0].tcs[ACTIVE_TCS].type = ACTIVE_TCS; + drv->ch[CH0].tcs[ACTIVE_TCS].num_tcs = RPMH_NUM_ACTIVE_TCS; + drv->ch[CH0].tcs[ACTIVE_TCS].ncpt = ncpt; + drv->ch[CH0].tcs[ACTIVE_TCS].offset = offset; + drv->ch[CH0].tcs[ACTIVE_TCS].mask = ((1 << RPMH_NUM_ACTIVE_TCS) - 1) << offset; + offset += RPMH_NUM_ACTIVE_TCS; + drv->num_tcs += RPMH_NUM_ACTIVE_TCS; + printk(BIOS_DEBUG, "RPMH RSC: ACTIVE TCS: %d TCSes at offset %d (mask=0x%x)\n", + RPMH_NUM_ACTIVE_TCS, drv->ch[CH0].tcs[ACTIVE_TCS].offset, + drv->ch[CH0].tcs[ACTIVE_TCS].mask); + } + + if (RPMH_NUM_SLEEP_TCS > 0) { + drv->ch[CH0].tcs[SLEEP_TCS].drv = drv; + drv->ch[CH0].tcs[SLEEP_TCS].type = SLEEP_TCS; + drv->ch[CH0].tcs[SLEEP_TCS].num_tcs = RPMH_NUM_SLEEP_TCS; + drv->ch[CH0].tcs[SLEEP_TCS].ncpt = ncpt; + drv->ch[CH0].tcs[SLEEP_TCS].offset = offset; + drv->ch[CH0].tcs[SLEEP_TCS].mask = ((1 << RPMH_NUM_SLEEP_TCS) - 1) << offset; + offset += RPMH_NUM_SLEEP_TCS; + drv->num_tcs += RPMH_NUM_SLEEP_TCS; + printk(BIOS_DEBUG, "RPMH RSC: SLEEP TCS: %d TCSes at offset %d (mask=0x%x)\n", + RPMH_NUM_SLEEP_TCS, drv->ch[CH0].tcs[SLEEP_TCS].offset, + drv->ch[CH0].tcs[SLEEP_TCS].mask); + } + + if (RPMH_NUM_WAKE_TCS > 0) { + drv->ch[CH0].tcs[WAKE_TCS].drv = drv; + drv->ch[CH0].tcs[WAKE_TCS].type = WAKE_TCS; + drv->ch[CH0].tcs[WAKE_TCS].num_tcs = RPMH_NUM_WAKE_TCS; + drv->ch[CH0].tcs[WAKE_TCS].ncpt = ncpt; + drv->ch[CH0].tcs[WAKE_TCS].offset = offset; + drv->ch[CH0].tcs[WAKE_TCS].mask = ((1 << RPMH_NUM_WAKE_TCS) - 1) << offset; + offset += RPMH_NUM_WAKE_TCS; + drv->num_tcs += RPMH_NUM_WAKE_TCS; + printk(BIOS_DEBUG, "RPMH RSC: WAKE TCS: %d TCSes at offset %d (mask=0x%x)\n", + RPMH_NUM_WAKE_TCS, drv->ch[CH0].tcs[WAKE_TCS].offset, + drv->ch[CH0].tcs[WAKE_TCS].mask); + } + + /* Check if total TCS count exceeds hardware limit */ + if (drv->num_tcs > max_tcs) { + printk(BIOS_ERR, "RPMH RSC: TCS config exceeds hardware limit (configured: %d, max: %d)\n", + drv->num_tcs, max_tcs); + return -1; + } + + drv->ch[CH0].drv = drv; + drv->ch[CH0].initialized = true; + drv->client.non_batch_cache = non_batch_cache; + drv->client.non_batch_cache_idx = 0; + + for (int i = 0; i < CMD_DB_MAX_RESOURCES; i++) { + non_batch_cache[i].addr = 0; + non_batch_cache[i].sleep_val = UINT_MAX; + non_batch_cache[i].wake_val = UINT_MAX; + } + + /* Initialize TCS in-use bitmap */ + memset(drv->tcs_in_use, 0, sizeof(drv->tcs_in_use)); + + /* Detect solver mode from hardware */ + solver_config = read32(drv->base + drv->regs[DRV_SOLVER_CONFIG]); + solver_config = (solver_config >> 24) & 0x1; + + if (solver_config || RPMH_HW_SOLVER_SUPPORTED) { + drv->client.flags |= SOLVER_PRESENT; + printk(BIOS_INFO, "RPMH RSC: Hardware solver mode supported\n"); + + if (RPMH_HW_CHANNEL_MODE) { + drv->client.flags |= HW_CHANNEL_PRESENT; + drv->in_solver_mode = true; + drv->client.in_solver_mode = true; + printk(BIOS_INFO, "RPMH RSC: HW channel mode enabled\n"); + } else { + drv->in_solver_mode = false; + drv->client.in_solver_mode = false; + printk(BIOS_INFO, "RPMH RSC: Software control mode\n"); + } + } else { + printk(BIOS_INFO, "RPMH RSC: Hardware solver mode not supported\n"); + } + + drv->initialized = true; + + rpmh_set_rsc_drv(drv); + + printk(BIOS_INFO, "RPMH RSC: Initialized %s (drv-%d) at 0x%lx Version %d.%d\n", + drv->name, drv->id, (uintptr_t)drv->base, major_rsc_version, minor_rsc_version); + + return 0; +} diff --git a/src/soc/qualcomm/x1p42100/soc.c b/src/soc/qualcomm/x1p42100/soc.c index d1762237d54..df4e8036275 100644 --- a/src/soc/qualcomm/x1p42100/soc.c +++ b/src/soc/qualcomm/x1p42100/soc.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -51,7 +52,6 @@ static void soc_read_resources(struct device *dev) reserved_ram_range(dev, index++, (uintptr_t)_dram_wlan, REGION_SIZE(dram_wlan)); reserved_ram_range(dev, index++, (uintptr_t)_dram_pil, REGION_SIZE(dram_pil)); reserved_ram_range(dev, index++, (uintptr_t)_dram_ta, REGION_SIZE(dram_ta)); - reserved_ram_range(dev, index++, (uintptr_t)_dram_display, REGION_SIZE(dram_display)); /* ACDB carveout region located at 0xFF800000 - (n*5.5 +1+32+3) where n is size of DDR */ reserved_ram_range(dev, index++, (uintptr_t)(_dram_llcc_lpi - calc_acdb_carveout_size()), @@ -90,6 +90,7 @@ static void soc_init(struct device *dev) { cpucp_fw_load_reset(); qtee_fw_config_load(); + lpass_init(); } static struct device_operations soc_ops = { diff --git a/src/soc/qualcomm/x1p42100/usb/usb.c b/src/soc/qualcomm/x1p42100/usb/usb.c index ec61ebd5be2..afc44e6a5f7 100644 --- a/src/soc/qualcomm/x1p42100/usb/usb.c +++ b/src/soc/qualcomm/x1p42100/usb/usb.c @@ -495,6 +495,15 @@ static bool get_usb_typec_polarity(const struct dwc3_controller_config *config) return (misc_status & CCOUT_INVERT_POLARITY) == CCOUT_INVERT_POLARITY; } +/* + * Configures OTG buck for host mode + * @config: Controller configuration containing SMB slave address + */ +static void usb_configure_otg_buck(const struct dwc3_controller_config *config) +{ + spmi_write8(SPMI_ADDR(config->smb_slave_addr, SCHG_DCDC_OTG_CFG), OTG_BUCK_CFG); +} + /* Initialization of DWC3 Core and PHY */ static void setup_usb_host(struct usb_dwc3_cfg *dwc3) { @@ -581,15 +590,16 @@ static void setup_usb_host(struct usb_dwc3_cfg *dwc3) clock_reset_bcr(dwc3->gcc_usb4_0_dp0_phy_prim_bcr, 0); udelay(10); /* Initialize USB4/USB3 EDP_DP_Con PHY Configuration */ - int ss0_ret = qmp_usb4_dp_phy_ss_init(0, get_usb_typec_polarity(&prim_config)); + bool polarity_prim = get_usb_typec_polarity(&prim_config); + int ss0_ret = qmp_usb4_dp_phy_ss_init(0, polarity_prim); if (ss0_ret != CB_SUCCESS) { printk(BIOS_ERR, "SS0 QMP PHY initialization failed\n"); high_speed_only_primary = true; } - /* Enable VBUS for C0 */ - enable_vbus_ss(&prim_config); - udelay(50); + /* Configure OTG buck */ + usb_configure_otg_buck(&prim_config); usb_typec_status_check(&prim_config); + mainboard_usb_typec_configure(0, polarity_prim); /* Type C port 1 - C1 */ /* Reset USB secondary[C1] PHY BCRs */ @@ -610,15 +620,16 @@ static void setup_usb_host(struct usb_dwc3_cfg *dwc3) clock_reset_bcr(dwc3->gcc_usb4_1_dp0_phy_sec_bcr, 0); udelay(10); /* Initialize USB4/USB3 EDP_DP_Con PHY Configuration (secondary) */ - int ss1_ret = qmp_usb4_dp_phy_ss_init(1, get_usb_typec_polarity(&sec_config)); + bool polarity_sec = get_usb_typec_polarity(&sec_config); + int ss1_ret = qmp_usb4_dp_phy_ss_init(1, polarity_sec); if (ss1_ret != CB_SUCCESS) { printk(BIOS_ERR, "SS1 QMP PHY initialization failed\n"); high_speed_only_secondary = true; } - /* Enable VBUS for C1 */ - enable_vbus_ss(&sec_config); - udelay(50); + /* Configure OTG buck */ + usb_configure_otg_buck(&sec_config); usb_typec_status_check(&sec_config); + mainboard_usb_typec_configure(1, polarity_sec); /* Initialize USB Controller for Type A */ setup_dwc3(dwc3->usb_host_dwc3); @@ -668,52 +679,6 @@ void usb_update_refclk_for_core(u32 core_num, bool enable) } } -/* - * enable_vbus_ss - Enables VBUS SuperSpeed for specified USB core - * @config: Controller configuration containing SMB slave address - */ -void enable_vbus_ss(const struct dwc3_controller_config *config) -{ - u8 slave = config->smb_slave_addr; - u8 misc_status, otg_status = 0, otg_state = 0; - struct stopwatch sw; - - printk(BIOS_INFO, "Enabling %s VBUS SuperSpeed\n", config->name); - - /* Configure SDCDC CFG7 register before enabling OTG */ - spmi_write8(SPMI_ADDR(slave, SCHG_DCDC_ENG_SDCDC_CFG7), - SCHG_DCDC_ENG_SDCDC_GM_CLOOP_PD_OTG_BUCK_MASK); - - spmi_write8(SPMI_ADDR(slave, SCHG_DCDC_OTG_CFG), 0x20); - spmi_write8(SPMI_ADDR(slave, SCHG_DCDC_CMD_OTG), 0x1); - - /* Check Type-C mode */ - misc_status = spmi_read8(SPMI_ADDR(slave, SCHG_TYPE_C_TYPE_C_MISC_STATUS)); - - /* Check SNK_SRC_MODE bit (bit 6): 0 = SNK, 1 = SRC */ - if (misc_status & TYPEC_SNK_SRC_MODE) { - /* In SRC mode, poll OTG status until enabled */ - stopwatch_init_msecs_expire(&sw, OTG_STATUS_TIMEOUT_MS); - while (!stopwatch_expired(&sw)) { - otg_status = spmi_read8(SPMI_ADDR(slave, SCHG_DCDC_OTG_STATUS)); - otg_state = otg_status & OTG_STATE_MASK; - - if (otg_state == OTG_STATE_ENABLED) { - printk(BIOS_INFO, "%s in SRC mode - OTG Status: 0x%02x, State: 0x%02x (OTG Enabled)\n", - config->name, otg_status, otg_state); - return; - } - mdelay(OTG_STATUS_POLL_DELAY_MS); - } - - /* Timeout - log final state */ - printk(BIOS_INFO, "%s in SRC mode - OTG Status: 0x%02x, State: 0x%02x - Timeout after %d ms\n", - config->name, otg_status, otg_state, OTG_STATUS_TIMEOUT_MS); - } else { - printk(BIOS_INFO, "%s in SNK mode - skipping OTG status read\n", config->name); - } -} - /* * usb_typec_status_check - Reads comprehensive Type-C status from PMIC * @config: Controller configuration containing SMB slave address diff --git a/src/soc/rockchip/rk3399/include/soc/mipi.h b/src/soc/rockchip/rk3399/include/soc/mipi.h index f5bd797850a..839eb5185cb 100644 --- a/src/soc/rockchip/rk3399/include/soc/mipi.h +++ b/src/soc/rockchip/rk3399/include/soc/mipi.h @@ -3,7 +3,7 @@ #ifndef __RK_MIPI_H #define __RK_MIPI_H -#include +#include #include struct rk_mipi_regs { diff --git a/src/southbridge/intel/bd82x6x/acpi/usb.asl b/src/southbridge/intel/bd82x6x/acpi/usb.asl index 3e2ba78db47..4d80c40e1b0 100644 --- a/src/southbridge/intel/bd82x6x/acpi/usb.asl +++ b/src/southbridge/intel/bd82x6x/acpi/usb.asl @@ -26,25 +26,20 @@ Device (EHC1) { Name (_ADR, 0x00000000) - // GPLD: Generate Port Location Data (PLD) - Method (GPLD, 1, Serialized) - { - - Name (PCKG, Package (0x01) - { + Method (GPLD, 1, Serialized) { + Local0 = Package () { Buffer (0x10) {} - }) + } - // REV: Revision 0x02 for ACPI 5.0 - CreateField (DerefOf (PCKG [0]), 0, 0x07, REV) - REV = 0x02 + // REV: Revision 2 for ACPI 5.0 + CreateField (DerefOf (Local0[0]), 0, 7, REV) + REV = 2 // VISI: Port visibility to user per port - CreateField (DerefOf (PCKG [0]), 0x40, 1, VISI) + CreateField (DerefOf (Local0[0]), 0x40, 1, VISI) VISI = Arg0 - - Return (PCKG) + Return (Local0) } // How many are there? @@ -82,22 +77,19 @@ Device (EHC2) Name (_ADR, 0x00000000) // GPLD: Generate Port Location Data (PLD) - Method (GPLD, 1, Serialized) - { - Name (PCKG, Package (0x01) - { + Method (GPLD, 1, Serialized) { + Local0 = Package () { Buffer (0x10) {} - }) + } - // REV: Revision 0x02 for ACPI 5.0 - CreateField (DerefOf (PCKG [0]), 0, 0x07, REV) - REV = 0x02 + // REV: Revision 2 for ACPI 5.0 + CreateField (DerefOf (Local0[0]), 0, 7, REV) + REV = 2 // VISI: Port visibility to user per port - CreateField (DerefOf (PCKG [0]), 0x40, 1, VISI) + CreateField (DerefOf (Local0[0]), 0x40, 1, VISI) VISI = Arg0 - - Return (PCKG) + Return (Local0) } // How many are there? diff --git a/src/southbridge/intel/bd82x6x/cfr.h b/src/southbridge/intel/bd82x6x/cfr.h index 8b9f928f349..064636d6b52 100644 --- a/src/southbridge/intel/bd82x6x/cfr.h +++ b/src/southbridge/intel/bd82x6x/cfr.h @@ -11,6 +11,14 @@ #include #include "me.h" +#define DEFINE_RP_ENABLE_OPTION(_rp, _name) \ +static const struct sm_object pcie_rp##_rp = SM_DECLARE_BOOL({ \ + .opt_name = "pch_pcie_enable_rp"#_rp, \ + .ui_name = _name, \ + .ui_helptext = "Enable or disable "#_name, \ + .default_value = true, \ +}) + /* Power state after power loss */ static const struct sm_object power_on_after_fail = SM_DECLARE_ENUM({ .opt_name = "power_on_after_fail", diff --git a/src/southbridge/intel/bd82x6x/early_usb.c b/src/southbridge/intel/bd82x6x/early_usb.c index 7bca0bbc494..50b66d5acf8 100644 --- a/src/southbridge/intel/bd82x6x/early_usb.c +++ b/src/southbridge/intel/bd82x6x/early_usb.c @@ -10,6 +10,11 @@ #include "pch.h" #include "chip.h" +__weak uint16_t mb_usb20_port_override(void) +{ + return 0x3fff; +} + void early_usb_init(void) { u32 reg32; @@ -68,7 +73,11 @@ void early_usb_init(void) for (i = 0; i < 14; i++) if (!portmap[i].enabled) reg32 |= (1 << i); - RCBA32(USBPDO) = reg32; + + /* Allow mainboard to disable ports based on SKU or user config */ + reg32 |= ~mb_usb20_port_override(); + + RCBA32(USBPDO) = reg32 & 0x3fff; reg32 = 0; for (i = 0; i < 8; i++) if (portmap[i].enabled && portmap[i].oc_pin >= 0) diff --git a/src/southbridge/intel/bd82x6x/early_usb_mrc.c b/src/southbridge/intel/bd82x6x/early_usb_mrc.c index bf43e263a48..e12ade0287a 100644 --- a/src/southbridge/intel/bd82x6x/early_usb_mrc.c +++ b/src/southbridge/intel/bd82x6x/early_usb_mrc.c @@ -32,6 +32,11 @@ void enable_usb_bar(void) pci_or_config16(usb1, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); } +__weak uint16_t mb_usb20_port_override(void) +{ + return 0x3fff; +} + /* * Translate coreboot native USB port configuration in devicetree * into a format reference code expects: @@ -64,6 +69,10 @@ void southbridge_fill_pei_data(struct pei_data *pei_data) const uint16_t currents[] = { 0x40, 0x80, 0x130, 0, 0, 0, /* 3-5 not seen in MRC */ 0x40, 0x130, 0x40, 0x80}; + + /* Allow mainboard to disable ports based on SKU or user config */ + u16 mb_usb20_enable = mb_usb20_port_override(); + for (unsigned int port = 0; port < ARRAY_SIZE(config->usb_port_config); port++) { uint16_t current = 0; int ocp = config->usb_port_config[port].oc_pin; @@ -84,7 +93,8 @@ void southbridge_fill_pei_data(struct pei_data *pei_data) __func__, port, config->usb_port_config[port].current); } - pei_data->usb_port_config[port][0] = config->usb_port_config[port].enabled; + pei_data->usb_port_config[port][0] = config->usb_port_config[port].enabled && + (mb_usb20_enable & BIT(port)); pei_data->usb_port_config[port][1] = ocp; pei_data->usb_port_config[port][2] = current; } diff --git a/src/southbridge/intel/bd82x6x/lpc.c b/src/southbridge/intel/bd82x6x/lpc.c index 67d883ad485..cdd1bb3f116 100644 --- a/src/southbridge/intel/bd82x6x/lpc.c +++ b/src/southbridge/intel/bd82x6x/lpc.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include @@ -560,19 +561,66 @@ static void pch_lpc_read_resources(struct device *dev) res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; - res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0)); + res = new_resource(dev, 2); res->base = 0xff000000; /* Some systems (e.g. X230) have 12 MiB flash. SPI controller supports up to 2 x 16 MiB of flash but address map limits this to 16MiB. */ res->size = 0x01000000; /* 16 MB for flash */ - res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | - IORESOURCE_ASSIGNED | IORESOURCE_FIXED; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | + IORESOURCE_FIXED | IORESOURCE_RESERVE; res = new_resource(dev, 3); /* IOAPIC */ res->base = IO_APIC_ADDR; res->size = 0x00001000; - res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | + IORESOURCE_FIXED | IORESOURCE_RESERVE; + + /* HPET */ + res = new_resource(dev, 4); + res->base = (resource_t)HPET_BASE_ADDRESS; + res->size = 4 * KiB; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | + IORESOURCE_FIXED | IORESOURCE_RESERVE; + + /* TXT_PRIVATE_SPACE */ + res = new_resource(dev, 5); + res->base = (resource_t)0xfed20000; + res->size = 0x20000; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | + IORESOURCE_FIXED | IORESOURCE_RESERVE; + + /* Misc ICH + TXT_RESERVED_SPACE */ + res = new_resource(dev, 6); + res->base = (resource_t)0xfed45000; + res->size = 0x4b000; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | + IORESOURCE_FIXED | IORESOURCE_RESERVE; + + /* RCBA */ + res = new_resource(dev, RCBA); + res->base = (resource_t)CONFIG_FIXED_RCBA_MMIO_BASE; + res->size = CONFIG_RCBA_LENGTH; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | + IORESOURCE_FIXED | IORESOURCE_RESERVE; + + /* LPC TPM TIS */ + res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0)); + res->base = 0xfed40000; + res->size = 0x00005000; + res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | + IORESOURCE_ASSIGNED | IORESOURCE_FIXED; + + /* Check LPC Memory Decode register. */ + u32 reg = pci_read_config32(dev, LGMR); + if (reg & 1) { + reg &= ~0xffff; + res = new_resource(dev, LGMR); + res->base = reg; + res->size = 64 * 1024; + res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | + IORESOURCE_FIXED | IORESOURCE_RESERVE; + } /* Set PCH IO decode ranges if required.*/ if ((config->gen1_dec & 0xFFFC) > 0x1000) { diff --git a/src/southbridge/intel/bd82x6x/pch.h b/src/southbridge/intel/bd82x6x/pch.h index 2fb97f0d607..534251d5e8c 100644 --- a/src/southbridge/intel/bd82x6x/pch.h +++ b/src/southbridge/intel/bd82x6x/pch.h @@ -39,6 +39,9 @@ bool pch_is_mobile(void); void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue); void enable_usb_bar(void); +/* Optional mainboard hook to do disable additional USB ports + based on SKU or user configuration. Set bit to 0 to disable port. */ +uint16_t mb_usb20_port_override(void); void early_thermal_init(void); void southbridge_configure_default_intmap(void); diff --git a/src/southbridge/intel/common/finalize.c b/src/southbridge/intel/common/finalize.c index 490bdae74e0..759ab8ea2da 100644 --- a/src/southbridge/intel/common/finalize.c +++ b/src/southbridge/intel/common/finalize.c @@ -2,6 +2,8 @@ #include #include +#include +#include #include #include #include @@ -45,7 +47,7 @@ void intel_pch_finalize_smm(void) pci_write_config32(PCI_DEV(0, 27, 0), 0x74, pci_read_config32(PCI_DEV(0, 27, 0), 0x74)); - if (CONFIG(BOOTMEDIA_SMM_BWP)) + if (enable_smm_bios_protection()) write_pmbase16(SMI_EN, read_pmbase16(SMI_EN) | TCO_EN); write_pmbase16(TCO1_CNT, read_pmbase16(TCO1_CNT) | TCO_LOCK); diff --git a/src/southbridge/intel/common/smbus_ops.c b/src/southbridge/intel/common/smbus_ops.c index 8542ba3d04a..242603765ae 100644 --- a/src/southbridge/intel/common/smbus_ops.c +++ b/src/southbridge/intel/common/smbus_ops.c @@ -56,11 +56,24 @@ static int lsmbus_block_read(struct device *dev, u8 cmd, u8 bytes, u8 *buf) return do_smbus_block_read(res->base, device, cmd, bytes, buf); } +static int lsmbus_i2c_eeprom_read(struct device *dev, u8 offset, u8 bytes, u8 *buf) +{ + u16 device; + struct resource *res; + struct bus *pbus; + + device = dev->path.i2c.device; + pbus = get_pbus_smbus(dev); + res = find_resource(pbus->dev, PCI_BASE_ADDRESS_4); + return do_i2c_eeprom_read(res->base, device, offset, bytes, buf); +} + struct smbus_bus_operations lops_smbus_bus = { - .read_byte = lsmbus_read_byte, - .write_byte = lsmbus_write_byte, - .block_read = lsmbus_block_read, - .block_write = lsmbus_block_write, + .read_byte = lsmbus_read_byte, + .write_byte = lsmbus_write_byte, + .block_read = lsmbus_block_read, + .block_write = lsmbus_block_write, + .i2c_eeprom_read = lsmbus_i2c_eeprom_read, }; void smbus_read_resources(struct device *dev) diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c index 068062bae0e..089e3ce234c 100644 --- a/src/southbridge/intel/common/spi.c +++ b/src/southbridge/intel/common/spi.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -619,14 +621,28 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, */ while (trans.bytesout || trans.bytesin) { uint32_t data_length; + uint32_t max_length; /* SPI addresses are 24 bit only */ writel_(trans.offset & 0x00FFFFFF, cntlr.addr); if (trans.bytesout) - data_length = MIN(trans.bytesout, cntlr.databytes); + max_length = MIN(trans.bytesout, cntlr.databytes); else - data_length = MIN(trans.bytesin, cntlr.databytes); + max_length = MIN(trans.bytesin, cntlr.databytes); + + /* + * Avoid transfers that cross 4KiB boundaries. The ICH SPI controller + * has been observed to fail on some platforms when a single transfer + * spans a 4KiB boundary (e.g., offset 0x...3ff0, len 0x3c crosses 0x...4000). + */ + if (with_address) { + uint32_t off_in_4k = trans.offset & 0xfff; + uint32_t max_to_boundary = 0x1000 - off_in_4k; + data_length = MIN(max_length, max_to_boundary); + } else { + data_length = max_length; + } /* Program data into FDATA0 to N */ if (trans.bytesout) { @@ -1102,7 +1118,7 @@ void spi_finalize_ops(void) } writew_(optype, cntlr.optype); - spi_set_smm_only_flashing(CONFIG(BOOTMEDIA_SMM_BWP)); + spi_set_smm_only_flashing(enable_smm_bios_protection()); } __weak void intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config) diff --git a/src/southbridge/intel/ibexpeak/azalia.c b/src/southbridge/intel/ibexpeak/azalia.c index 6196096a14b..6a738f356da 100644 --- a/src/southbridge/intel/ibexpeak/azalia.c +++ b/src/southbridge/intel/ibexpeak/azalia.c @@ -117,8 +117,6 @@ static struct device_operations azalia_ops = { }; static const unsigned short pci_device_ids[] = { - 0x1c20, - 0x1e20, PCI_DID_INTEL_IBEXPEAK_AUDIO, 0 }; diff --git a/src/southbridge/intel/ibexpeak/me.c b/src/southbridge/intel/ibexpeak/me.c index fbcb01dc3a1..68a0ca5b3a1 100644 --- a/src/southbridge/intel/ibexpeak/me.c +++ b/src/southbridge/intel/ibexpeak/me.c @@ -515,7 +515,6 @@ static struct device_operations device_ops = { }; static const unsigned short pci_device_ids[] = { - 0x1c3a, PCI_DID_INTEL_IBEXPEAK_HECI1, 0 }; diff --git a/src/southbridge/intel/ibexpeak/smbus.c b/src/southbridge/intel/ibexpeak/smbus.c index 6bbd1e44f87..13886131bba 100644 --- a/src/southbridge/intel/ibexpeak/smbus.c +++ b/src/southbridge/intel/ibexpeak/smbus.c @@ -33,8 +33,6 @@ static struct device_operations smbus_ops = { }; static const unsigned short pci_device_ids[] = { - 0x1c22, - 0x1e22, PCI_DID_INTEL_IBEXPEAK_SMBUS, 0 }; diff --git a/src/southbridge/intel/lynxpoint/acpi/gpio.asl b/src/southbridge/intel/lynxpoint/acpi/gpio.asl index a673b256048..f18c5486d9e 100644 --- a/src/southbridge/intel/lynxpoint/acpi/gpio.asl +++ b/src/southbridge/intel/lynxpoint/acpi/gpio.asl @@ -3,7 +3,15 @@ Device (GPIO) { // GPIO Controller - Name (_HID, "INT33C7") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3437") + } + // LynxPoint-LP + Return ("INT33C7") + } Name (_CID, "INT33C7") Name (_UID, 1) diff --git a/src/southbridge/intel/lynxpoint/acpi/serialio.asl b/src/southbridge/intel/lynxpoint/acpi/serialio.asl index 845949ce988..95a3466709d 100644 --- a/src/southbridge/intel/lynxpoint/acpi/serialio.asl +++ b/src/southbridge/intel/lynxpoint/acpi/serialio.asl @@ -16,6 +16,28 @@ External (\S5EN) External (\S6EN) External (\S7EN) +// Put SerialIO device in D0 state +// Arg0 - Ref to offset 0x84 of device's PCI config space +Method (LPD0, 1, Serialized) +{ + Arg0 = DeRefOf (Arg0) & 0xFFFFFFFC + Local0 = DeRefOf (Arg0) // Read back after writing + + // Use Local0 to avoid iasl warning: Method Local is set but never used + Local0 &= Ones +} + +// Put SerialIO device in D3 state +// Arg0 - Ref to offset 0x84 of device's PCI config space +Method (LPD3, 1, Serialized) +{ + Arg0 = DeRefOf (Arg0) | 0x3 + Local0 = DeRefOf (Arg0) // Read back after writing + + // Use Local0 to avoid iasl warning: Method Local is set but never used + Local0 &= Ones +} + // Serial IO Resource Consumption for BAR1 Device (SIOR) { @@ -145,7 +167,15 @@ Device (SDMA) Device (I2C0) { // Serial IO I2C0 Controller - Name (_HID, "INT33C2") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3432") + } + // LynxPoint-LP + Return ("INT33C2") + } Name (_CID, "INT33C2") Name (_UID, 1) @@ -193,39 +223,35 @@ Device (I2C0) } } - // Access to PCI Config in ACPI mode - OperationRegion (KEYS, SystemMemory, \S1B1, 0x100) - Field (KEYS, DWordAcc, NoLock, Preserve) + OperationRegion (SPRT, SystemMemory, \S1B1 + 0x84, 4) + Field (SPRT, DWordAcc, NoLock, Preserve) { - Offset (0x84), - PSAT, 32, + SPCS, 32 } - // Put controller in D0 state Method (_PS0, 0, Serialized) { - ^PSAT &= 0xfffffffc - Local0 = ^PSAT // Read back after writing - - // Use Local0 to avoid iasl warning: Method Local is set but never used - Local0 &= Ones + ^^LPD0 (RefOf (SPCS)) } - // Put controller in D3Hot state Method (_PS3, 0, Serialized) { - ^PSAT |= 0x00000003 - Local0 = ^PSAT // Read back after writing - - // Use Local0 to avoid iasl warning: Method Local is set but never used - Local0 &= Ones + ^^LPD3 (RefOf (SPCS)) } } Device (I2C1) { // Serial IO I2C1 Controller - Name (_HID, "INT33C3") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3433") + } + // LynxPoint-LP + Return ("INT33C3") + } Name (_CID, "INT33C3") Name (_UID, 1) @@ -273,39 +299,35 @@ Device (I2C1) } } - // Access to PCI Config in ACPI mode - OperationRegion (KEYS, SystemMemory, \S2B1, 0x100) - Field (KEYS, DWordAcc, NoLock, Preserve) + OperationRegion (SPRT, SystemMemory, \S2B1 + 0x84, 4) + Field (SPRT, DWordAcc, NoLock, Preserve) { - Offset (0x84), - PSAT, 32, + SPCS, 32 } - // Put controller in D0 state Method (_PS0, 0, Serialized) { - ^PSAT &= 0xfffffffc - Local0 = ^PSAT // Read back after writing - - // Use Local0 to avoid iasl warning: Method Local is set but never used - Local0 &= Ones + ^^LPD0 (RefOf (SPCS)) } - // Put controller in D3Hot state Method (_PS3, 0, Serialized) { - ^PSAT |= 0x00000003 - Local0 = ^PSAT // Read back after writing - - // Use Local0 to avoid iasl warning: Method Local is set but never used - Local0 &= Ones + ^^LPD3 (RefOf (SPCS)) } } Device (SPI0) { // Serial IO SPI0 Controller - Name (_HID, "INT33C0") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3430") + } + // LynxPoint-LP + Return ("INT33C0") + } Name (_CID, "INT33C0") Name (_UID, 1) @@ -337,12 +359,36 @@ Device (SPI0) Return (0xF) } } + + OperationRegion (SPRT, SystemMemory, \S3B1 + 0x84, 4) + Field (SPRT, DWordAcc, NoLock, Preserve) + { + SPCS, 32 + } + + Method (_PS0, 0, Serialized) + { + ^^LPD0 (RefOf (SPCS)) + } + + Method (_PS3, 0, Serialized) + { + ^^LPD3 (RefOf (SPCS)) + } } Device (SPI1) { // Serial IO SPI1 Controller - Name (_HID, "INT33C1") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3431") + } + // LynxPoint-LP + Return ("INT33C1") + } Name (_CID, "INT33C1") Name (_UID, 1) @@ -386,12 +432,36 @@ Device (SPI1) Return (0xF) } } + + OperationRegion (SPRT, SystemMemory, \S4B1 + 0x84, 4) + Field (SPRT, DWordAcc, NoLock, Preserve) + { + SPCS, 32 + } + + Method (_PS0, 0, Serialized) + { + ^^LPD0 (RefOf (SPCS)) + } + + Method (_PS3, 0, Serialized) + { + ^^LPD3 (RefOf (SPCS)) + } } Device (UAR0) { // Serial IO UART0 Controller - Name (_HID, "INT33C4") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3434") + } + // LynxPoint-LP + Return ("INT33C4") + } Name (_CID, "INT33C4") Name (_UID, 1) @@ -435,12 +505,36 @@ Device (UAR0) Return (0xF) } } + + OperationRegion (SPRT, SystemMemory, \S5B1 + 0x84, 4) + Field (SPRT, DWordAcc, NoLock, Preserve) + { + SPCS, 32 + } + + Method (_PS0, 0, Serialized) + { + ^^LPD0 (RefOf (SPCS)) + } + + Method (_PS3, 0, Serialized) + { + ^^LPD3 (RefOf (SPCS)) + } } Device (UAR1) { // Serial IO UART1 Controller - Name (_HID, "INT33C5") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3435") + } + // LynxPoint-LP + Return ("INT33C5") + } Name (_CID, "INT33C5") Name (_UID, 1) @@ -472,12 +566,36 @@ Device (UAR1) Return (0xF) } } + + OperationRegion (SPRT, SystemMemory, \S6B1 + 0x84, 4) + Field (SPRT, DWordAcc, NoLock, Preserve) + { + SPCS, 32 + } + + Method (_PS0, 0, Serialized) + { + ^^LPD0 (RefOf (SPCS)) + } + + Method (_PS3, 0, Serialized) + { + ^^LPD3 (RefOf (SPCS)) + } } Device (SDIO) { // Serial IO SDIO Controller - Name (_HID, "INT33C6") + Method (_HID) + { + If (\ISWP ()) { + // WildcatPoint + Return ("INT3436") + } + // LynxPoint-LP + Return ("INT33C6") + } Name (_CID, "PNP0D40") Name (_UID, 1) diff --git a/src/southbridge/intel/lynxpoint/acpi/xhci.asl b/src/southbridge/intel/lynxpoint/acpi/xhci.asl index c7b0c181ed8..c38a5923720 100644 --- a/src/southbridge/intel/lynxpoint/acpi/xhci.asl +++ b/src/southbridge/intel/lynxpoint/acpi/xhci.asl @@ -6,9 +6,6 @@ Device (XHCI) { Name (_ADR, 0x00140000) - Name (PLSD, 5) // Port Link State - RxDetect - Name (PLSP, 7) // Port Link State - Polling - OperationRegion (XPRT, PCI_Config, 0, 0x100) Field (XPRT, AnyAcc, NoLock, Preserve) { @@ -41,6 +38,7 @@ Device (XHCI) PR3M, 32, // USB3PRM } +#if CONFIG(INTEL_LYNXPOINT_LP) // Clear status bits Method (LPCL, 0, Serialized) { @@ -57,27 +55,24 @@ Device (XHCI) PSC3, 32, } - // Port Enabled/Disabled (Bit 1) - Name (PEDB, 1 << 1) - - // Change Status (Bits 23:17) - Name (CHST, 0x7f << 17) +#define PSC_PORT_ENABLED (1 << 1) +#define PSC_PORT_CHANGE_BITS (0x7f << 17) // Port 0 - Local0 = PSC0 & ~PEDB - PSC0 = Local0 | CHST + Local0 = PSC0 & ~PSC_PORT_ENABLED + PSC0 = Local0 | PSC_PORT_CHANGE_BITS // Port 1 - Local0 = PSC1 & ~PEDB - PSC1 = Local0 | CHST + Local0 = PSC1 & ~PSC_PORT_ENABLED + PSC1 = Local0 | PSC_PORT_CHANGE_BITS // Port 2 - Local0 = PSC2 & ~PEDB - PSC2 = Local0 | CHST + Local0 = PSC2 & ~PSC_PORT_ENABLED + PSC2 = Local0 | PSC_PORT_CHANGE_BITS // Port 3 - Local0 = PSC3 & ~PEDB - PSC3 = Local0 | CHST + Local0 = PSC3 & ~PSC_PORT_ENABLED + PSC3 = Local0 | PSC_PORT_CHANGE_BITS } Method (LPS0, 0, Serialized) @@ -127,10 +122,12 @@ Device (XHCI) WPR4, 1, // [31] Warm Port Reset } +#define PLS_POLLING 7 + // Wait for all powered ports to finish polling Local0 = 10 - While ((PPR1 == 1 && PLS1 == PLSP || PPR2 == 1 && PLS2 == PLSP) || - (PPR3 == 1 && PLS3 == PLSP || PPR4 == 1 && PLS4 == PLSP)) + While ((PPR1 == 1 && PLS1 == PLS_POLLING || PPR2 == 1 && PLS2 == PLS_POLLING) || + (PPR3 == 1 && PLS3 == PLS_POLLING || PPR4 == 1 && PLS4 == PLS_POLLING)) { If (Local0 == 0) { Break @@ -151,19 +148,21 @@ Device (XHCI) Local3 = 0 Local4 = 0 - If (PLS1 == PLSD && (CSC1 == 0 && PPR1 == 1)) { +#define PLS_RX_DETECT 5 + + If (PLS1 == PLS_RX_DETECT && (CSC1 == 0 && PPR1 == 1)) { WPR1 = 1 // Issue warm reset Local1 = 1 } - If (PLS2 == PLSD && (CSC2 == 0 && PPR2 == 1)) { + If (PLS2 == PLS_RX_DETECT && (CSC2 == 0 && PPR2 == 1)) { WPR2 = 1 // Issue warm reset Local2 = 1 } - If (PLS3 == PLSD && (CSC3 == 0 && PPR3 == 1)) { + If (PLS3 == PLS_RX_DETECT && (CSC3 == 0 && PPR3 == 1)) { WPR3 = 1 // Issue warm reset Local3 = 1 } - If (PLS4 == PLSD && (CSC4 == 0 && PPR4 == 1)) { + If (PLS4 == PLS_RX_DETECT && (CSC4 == 0 && PPR4 == 1)) { WPR4 = 1 // Issue warm reset Local4 = 1 } @@ -183,6 +182,7 @@ Device (XHCI) // Clear status bits in all ports LPCL () } +#endif Method (_PSC, 0, NotSerialized) { @@ -256,12 +256,6 @@ Device (XHCI) ^SAIP = 0 #endif - // Clear PCI CFG offset 0x40[11] - ^SWAI = 0 - - // Clear PCI CFG offset 0x44[13:12] - ^SAIP = 0 - Return () } @@ -332,12 +326,6 @@ Device (XHCI) ^SAIP = 1 #endif - // Set PCI CFG offset 0x40[11] - ^SWAI = 1 - - // Set PCI CFG offset 0x44[13:12] - ^SAIP = 1 - // Put device in D3 ^D0D3 = 3 @@ -364,18 +352,18 @@ Device (XHCI) // GPLD: Generate Port Location Data (PLD) Method (GPLD, 1, Serialized) { - Name (PCKG, Package () { + Local0 = Package () { Buffer (0x10) {} - }) + } // REV: Revision 2 for ACPI 5.0 - CreateField (DerefOf (PCKG [0]), 0, 7, REV) + CreateField (DerefOf (Local0[0]), 0, 7, REV) REV = 2 // VISI: Port visibility to user per port - CreateField (DerefOf (PCKG [0]), 0x40, 1, VISI) + CreateField (DerefOf (Local0[0]), 0x40, 1, VISI) VISI = Arg0 - Return (PCKG) + Return (Local0) } Device (PRT1) { Name (_ADR, 1) } // USB Port 0 diff --git a/src/southbridge/intel/lynxpoint/early_me.c b/src/southbridge/intel/lynxpoint/early_me.c index 07013c55397..6dab65238e5 100644 --- a/src/southbridge/intel/lynxpoint/early_me.c +++ b/src/southbridge/intel/lynxpoint/early_me.c @@ -159,9 +159,6 @@ int intel_early_me_init_done(u8 status) printk(BIOS_NOTICE, "ME: Requested BIOS Action: %s\n", me_ack_values[hfs.ack_data]); - /* Check status after acknowledgement */ - intel_early_me_status(); - reset = 0; switch (hfs.ack_data) { case ME_HFS_ACK_CONTINUE: @@ -190,6 +187,9 @@ int intel_early_me_init_done(u8 status) /* Perform the requested reset */ if (reset) { + /* Show ME status before resetting */ + intel_early_me_status(); + outb(reset, 0xcf9); halt(); } diff --git a/src/southbridge/intel/lynxpoint/pcie.c b/src/southbridge/intel/lynxpoint/pcie.c index 7aff60895c9..969095207d9 100644 --- a/src/southbridge/intel/lynxpoint/pcie.c +++ b/src/southbridge/intel/lynxpoint/pcie.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -131,6 +132,29 @@ static void update_num_ports(void) rpc.num_ports); } +static u16 get_port_grant(u32 strpfusecfg) +{ + switch ((strpfusecfg >> 14) & 0x3) { + case 1: /* 2+1+1 */ + case 3: /* 4 */ + return 0x02; + case 2: /* 2+2 */ + return 0x22; + case 0: /* 1+1+1+1 */ + default: + return 0x00; + } +} + +static void set_iosf_port_grant_count(void) +{ + u16 reg16 = get_port_grant(rpc.strpfusecfg1) << 0; + if (!pch_is_lp()) + reg16 |= get_port_grant(rpc.strpfusecfg2) << 8; + + RCBA16(0x103c) = reg16; +} + static void root_port_init_config(struct device *dev) { int rp; @@ -307,6 +331,9 @@ static void root_port_commit_config(void) /* Perform clock gating configuration. */ pcie_enable_clock_gating(); + /* 8.13 IOSF Port Configuration and Grant Count Programming */ + set_iosf_port_grant_count(); + for (i = 0; i < rpc.num_ports; i++) { struct device *dev; @@ -326,6 +353,26 @@ static void root_port_commit_config(void) pci_and_config16(dev, PCI_COMMAND, ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO)); + /* 8.2 Configuration of PCI Express Root Ports */ + /* TODO: This should not be done if a card is detected */ + pci_or_config32(dev, 0x338, 1 << 26); + + /* TODO: BWG specifies 50 ms timeout */ + int n = 0; + do { + u32 reg32 = pci_read_config32(dev, 0x328); + n++; + if (((reg32 & 0xff000000) == 0x01000000) || (n > 50)) + break; + udelay(100); + } while (1); + + if (n > 50) + printk(BIOS_DEBUG, "%s: Timeout waiting for 328h\n", + dev_path(dev)); + + pci_or_config32(dev, 0x408, 1 << 27); + /* Disable this device if possible */ pch_disable_devfn(dev); } diff --git a/src/soc/intel/broadwell/pch/Kconfig b/src/southbridge/intel/wildcatpoint/Kconfig similarity index 93% rename from src/soc/intel/broadwell/pch/Kconfig rename to src/southbridge/intel/wildcatpoint/Kconfig index a671207b679..424b91d8329 100644 --- a/src/soc/intel/broadwell/pch/Kconfig +++ b/src/southbridge/intel/wildcatpoint/Kconfig @@ -1,6 +1,6 @@ ## SPDX-License-Identifier: GPL-2.0-only -config INTEL_LYNXPOINT_LP +config SOUTHBRIDGE_INTEL_WILDCATPOINT bool select ACPI_COMMON_MADT_IOAPIC select ACPI_COMMON_MADT_LAPIC @@ -14,6 +14,7 @@ config INTEL_LYNXPOINT_LP select HAVE_SMI_HANDLER select HAVE_USBDEBUG select INTEL_DESCRIPTOR_MODE_CAPABLE + select INTEL_LYNXPOINT_LP select RTC select SOUTHBRIDGE_INTEL_COMMON_EARLY_SMBUS select SOUTHBRIDGE_INTEL_COMMON_RESET @@ -23,6 +24,12 @@ config INTEL_LYNXPOINT_LP select SPI_FLASH select TCO_SPACE_NOT_YET_SPLIT +if SOUTHBRIDGE_INTEL_WILDCATPOINT + +# Placeholder +config INTEL_LYNXPOINT_LP + bool + config EHCI_BAR hex default 0xd8000000 @@ -72,3 +79,5 @@ config DISABLE_ME_PCI Disable and hide the ME PCI interface during finalize stage of boot. This will prevent the OS (and userspace apps) from interacting with the ME via the PCI interface after boot. + +endif diff --git a/src/southbridge/intel/wildcatpoint/Makefile.mk b/src/southbridge/intel/wildcatpoint/Makefile.mk new file mode 100644 index 00000000000..59f48805ce2 --- /dev/null +++ b/src/southbridge/intel/wildcatpoint/Makefile.mk @@ -0,0 +1,53 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ifeq ($(CONFIG_SOUTHBRIDGE_INTEL_WILDCATPOINT),y) + +bootblock-y += bootblock.c + +ramstage-y += acpi.c +ramstage-y += adsp.c +romstage-y += early_pch.c +ramstage-$(CONFIG_ELOG) += elog.c +ramstage-y += finalize.c +ramstage-y += ../lynxpoint/lp_gpio.c +romstage-y += ../lynxpoint/lp_gpio.c +verstage-y += ../lynxpoint/lp_gpio.c +smm-y += ../lynxpoint/lp_gpio.c +ramstage-y += hda.c +ramstage-y += ../lynxpoint/hda_verb.c +ramstage-y += ../lynxpoint/iobp.c +romstage-y += ../lynxpoint/iobp.c +ramstage-y += fadt.c +ramstage-y += lpc.c +ramstage-y += me.c +ramstage-y += me_status.c +romstage-y += me_status.c +ramstage-y += pch.c +romstage-y += pch.c +ramstage-y += pcie.c +ramstage-y += pmutil.c +romstage-y += pmutil.c +smm-y += pmutil.c +verstage-y += pmutil.c +romstage-y += power_state.c +ramstage-y += ramstage.c +ramstage-y += sata.c +ramstage-y += serialio.c +ramstage-y += ../lynxpoint/smbus.c +ramstage-y += smi.c +smm-y += smihandler.c +bootblock-y += usb_debug.c +romstage-y += usb_debug.c +ramstage-y += usb_debug.c +ramstage-y += usb_ehci.c +ramstage-y += usb_xhci.c +smm-y += usb_xhci.c + +bootblock-$(CONFIG_SERIALIO_UART_CONSOLE) += ../lynxpoint/iobp.c +bootblock-$(CONFIG_SERIALIO_UART_CONSOLE) += ../lynxpoint/uart_init.c +all-$(CONFIG_SERIALIO_UART_CONSOLE) += ../lynxpoint/uart.c +smm-$(CONFIG_SERIALIO_UART_CONSOLE) += ../lynxpoint/uart.c + +CPPFLAGS_common += -Isrc/southbridge/intel/wildcatpoint/include + +endif diff --git a/src/southbridge/intel/wildcatpoint/acpi.c b/src/southbridge/intel/wildcatpoint/acpi.c new file mode 100644 index 00000000000..091bb50319c --- /dev/null +++ b/src/southbridge/intel/wildcatpoint/acpi.c @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +size_t size_of_dnvs(void) +{ + return sizeof(struct device_nvs); +} diff --git a/src/soc/intel/broadwell/pch/acpi/adsp.asl b/src/southbridge/intel/wildcatpoint/acpi/adsp.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/adsp.asl rename to src/southbridge/intel/wildcatpoint/acpi/adsp.asl diff --git a/src/soc/intel/broadwell/acpi/device_nvs.asl b/src/southbridge/intel/wildcatpoint/acpi/device_nvs.asl similarity index 100% rename from src/soc/intel/broadwell/acpi/device_nvs.asl rename to src/southbridge/intel/wildcatpoint/acpi/device_nvs.asl diff --git a/src/soc/intel/broadwell/pch/acpi/globalnvs.asl b/src/southbridge/intel/wildcatpoint/acpi/globalnvs.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/globalnvs.asl rename to src/southbridge/intel/wildcatpoint/acpi/globalnvs.asl diff --git a/src/soc/intel/broadwell/pch/acpi/gpio.asl b/src/southbridge/intel/wildcatpoint/acpi/gpio.asl similarity index 99% rename from src/soc/intel/broadwell/pch/acpi/gpio.asl rename to src/southbridge/intel/wildcatpoint/acpi/gpio.asl index bd9f581cf6a..48167bfae53 100644 --- a/src/soc/intel/broadwell/pch/acpi/gpio.asl +++ b/src/southbridge/intel/wildcatpoint/acpi/gpio.asl @@ -13,6 +13,7 @@ Device (GPIO) // LynxPoint-LP Return ("INT33C7") } + Name (_CID, "INT33C7") Name (_UID, 1) Name (RBUF, ResourceTemplate () diff --git a/src/soc/intel/broadwell/pch/acpi/lpc.asl b/src/southbridge/intel/wildcatpoint/acpi/lpc.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/lpc.asl rename to src/southbridge/intel/wildcatpoint/acpi/lpc.asl diff --git a/src/soc/intel/broadwell/pch/acpi/pch.asl b/src/southbridge/intel/wildcatpoint/acpi/pch.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/pch.asl rename to src/southbridge/intel/wildcatpoint/acpi/pch.asl diff --git a/src/soc/intel/broadwell/pch/acpi/pci_irqs.asl b/src/southbridge/intel/wildcatpoint/acpi/pci_irqs.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/pci_irqs.asl rename to src/southbridge/intel/wildcatpoint/acpi/pci_irqs.asl diff --git a/src/soc/intel/broadwell/acpi/platform.asl b/src/southbridge/intel/wildcatpoint/acpi/platform.asl similarity index 90% rename from src/soc/intel/broadwell/acpi/platform.asl rename to src/southbridge/intel/wildcatpoint/acpi/platform.asl index fe254ff6f04..af60f5cee72 100644 --- a/src/soc/intel/broadwell/acpi/platform.asl +++ b/src/southbridge/intel/wildcatpoint/acpi/platform.asl @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include +#include #include /* diff --git a/src/soc/intel/broadwell/pch/acpi/serialio.asl b/src/southbridge/intel/wildcatpoint/acpi/serialio.asl similarity index 100% rename from src/soc/intel/broadwell/pch/acpi/serialio.asl rename to src/southbridge/intel/wildcatpoint/acpi/serialio.asl diff --git a/src/soc/intel/broadwell/pch/acpi/xhci.asl b/src/southbridge/intel/wildcatpoint/acpi/xhci.asl similarity index 86% rename from src/soc/intel/broadwell/pch/acpi/xhci.asl rename to src/southbridge/intel/wildcatpoint/acpi/xhci.asl index 0656a6cf2ab..d040201e5bf 100644 --- a/src/soc/intel/broadwell/pch/acpi/xhci.asl +++ b/src/southbridge/intel/wildcatpoint/acpi/xhci.asl @@ -6,9 +6,6 @@ Device (XHCI) { Name (_ADR, 0x00140000) - Name (PLSD, 5) // Port Link State - RxDetect - Name (PLSP, 7) // Port Link State - Polling - OperationRegion (XPRT, PCI_Config, 0, 0x100) Field (XPRT, AnyAcc, NoLock, Preserve) { @@ -57,27 +54,24 @@ Device (XHCI) PSC3, 32, } - // Port Enabled/Disabled (Bit 1) - Name (PEDB, 1 << 1) - - // Change Status (Bits 23:17) - Name (CHST, 0x7f << 17) +#define PSC_PORT_ENABLED (1 << 1) +#define PSC_PORT_CHANGE_BITS (0x7f << 17) // Port 0 - Local0 = PSC0 & ~PEDB - PSC0 = Local0 | CHST + Local0 = PSC0 & ~PSC_PORT_ENABLED + PSC0 = Local0 | PSC_PORT_CHANGE_BITS // Port 1 - Local0 = PSC1 & ~PEDB - PSC1 = Local0 | CHST + Local0 = PSC1 & ~PSC_PORT_ENABLED + PSC1 = Local0 | PSC_PORT_CHANGE_BITS // Port 2 - Local0 = PSC2 & ~PEDB - PSC2 = Local0 | CHST + Local0 = PSC2 & ~PSC_PORT_ENABLED + PSC2 = Local0 | PSC_PORT_CHANGE_BITS // Port 3 - Local0 = PSC3 & ~PEDB - PSC3 = Local0 | CHST + Local0 = PSC3 & ~PSC_PORT_ENABLED + PSC3 = Local0 | PSC_PORT_CHANGE_BITS } Method (LPS0, 0, Serialized) @@ -127,10 +121,12 @@ Device (XHCI) WPR4, 1, // [31] Warm Port Reset } +#define PLS_POLLING 7 + // Wait for all powered ports to finish polling Local0 = 10 - While ((PPR1 == 1 && PLS1 == PLSP || PPR2 == 1 && PLS2 == PLSP) || - (PPR3 == 1 && PLS3 == PLSP || PPR4 == 1 && PLS4 == PLSP)) + While ((PPR1 == 1 && PLS1 == PLS_POLLING || PPR2 == 1 && PLS2 == PLS_POLLING) || + (PPR3 == 1 && PLS3 == PLS_POLLING || PPR4 == 1 && PLS4 == PLS_POLLING)) { If (Local0 == 0) { Break @@ -151,19 +147,21 @@ Device (XHCI) Local3 = 0 Local4 = 0 - If (PLS1 == PLSD && (CSC1 == 0 && PPR1 == 1)) { +#define PLS_RX_DETECT 5 + + If (PLS1 == PLS_RX_DETECT && (CSC1 == 0 && PPR1 == 1)) { WPR1 = 1 // Issue warm reset Local1 = 1 } - If (PLS2 == PLSD && (CSC2 == 0 && PPR2 == 1)) { + If (PLS2 == PLS_RX_DETECT && (CSC2 == 0 && PPR2 == 1)) { WPR2 = 1 // Issue warm reset Local2 = 1 } - If (PLS3 == PLSD && (CSC3 == 0 && PPR3 == 1)) { + If (PLS3 == PLS_RX_DETECT && (CSC3 == 0 && PPR3 == 1)) { WPR3 = 1 // Issue warm reset Local3 = 1 } - If (PLS4 == PLSD && (CSC4 == 0 && PPR4 == 1)) { + If (PLS4 == PLS_RX_DETECT && (CSC4 == 0 && PPR4 == 1)) { WPR4 = 1 // Issue warm reset Local4 = 1 } @@ -330,18 +328,18 @@ Device (XHCI) // GPLD: Generate Port Location Data (PLD) Method (GPLD, 1, Serialized) { - Name (PCKG, Package () { + Local0 = Package () { Buffer (0x10) {} - }) + } // REV: Revision 2 for ACPI 5.0 - CreateField (DerefOf (PCKG [0]), 0, 7, REV) + CreateField (DerefOf (Local0[0]), 0, 7, REV) REV = 2 // VISI: Port visibility to user per port - CreateField (DerefOf (PCKG [0]), 0x40, 1, VISI) + CreateField (DerefOf (Local0[0]), 0x40, 1, VISI) VISI = Arg0 - Return (PCKG) + Return (Local0) } Device (PRT1) { Name (_ADR, 1) } // USB Port 0 diff --git a/src/soc/intel/broadwell/pch/adsp.c b/src/southbridge/intel/wildcatpoint/adsp.c similarity index 96% rename from src/soc/intel/broadwell/pch/adsp.c rename to src/southbridge/intel/wildcatpoint/adsp.c index 05b1e60af28..c56f9cc5848 100644 --- a/src/soc/intel/broadwell/pch/adsp.c +++ b/src/southbridge/intel/wildcatpoint/adsp.c @@ -11,13 +11,13 @@ #include #include #include -#include +#include #include #include static void adsp_init(struct device *dev) { - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); struct resource *bar0, *bar1; u32 tmp32; diff --git a/src/soc/intel/broadwell/pch/bootblock.c b/src/southbridge/intel/wildcatpoint/bootblock.c similarity index 100% rename from src/soc/intel/broadwell/pch/bootblock.c rename to src/southbridge/intel/wildcatpoint/bootblock.c diff --git a/src/soc/intel/broadwell/pch/chip.h b/src/southbridge/intel/wildcatpoint/chip.h similarity index 97% rename from src/soc/intel/broadwell/pch/chip.h rename to src/southbridge/intel/wildcatpoint/chip.h index 84ad8fe820d..dd316458498 100644 --- a/src/soc/intel/broadwell/pch/chip.h +++ b/src/southbridge/intel/wildcatpoint/chip.h @@ -5,7 +5,7 @@ #include -struct soc_intel_broadwell_pch_config { +struct southbridge_intel_wildcatpoint_config { /* GPE configuration */ uint32_t gpe0_en_1; uint32_t gpe0_en_2; diff --git a/src/soc/intel/broadwell/pch/early_pch.c b/src/southbridge/intel/wildcatpoint/early_pch.c similarity index 95% rename from src/soc/intel/broadwell/pch/early_pch.c rename to src/southbridge/intel/wildcatpoint/early_pch.c index cb459717726..adb65e61451 100644 --- a/src/soc/intel/broadwell/pch/early_pch.c +++ b/src/southbridge/intel/wildcatpoint/early_pch.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include static void pch_route_interrupts(void) { @@ -56,7 +56,7 @@ static void pch_enable_lpc(void) if (!dev || !dev->chip_info) return; - const struct soc_intel_broadwell_pch_config *config = dev->chip_info; + const struct southbridge_intel_wildcatpoint_config *config = dev->chip_info; pci_write_config32(PCH_DEV_LPC, LPC_GEN1_DEC, config->gen1_dec); pci_write_config32(PCH_DEV_LPC, LPC_GEN2_DEC, config->gen2_dec); diff --git a/src/soc/intel/broadwell/pch/elog.c b/src/southbridge/intel/wildcatpoint/elog.c similarity index 100% rename from src/soc/intel/broadwell/pch/elog.c rename to src/southbridge/intel/wildcatpoint/elog.c diff --git a/src/soc/intel/broadwell/pch/fadt.c b/src/southbridge/intel/wildcatpoint/fadt.c similarity index 100% rename from src/soc/intel/broadwell/pch/fadt.c rename to src/southbridge/intel/wildcatpoint/fadt.c diff --git a/src/soc/intel/broadwell/pch/finalize.c b/src/southbridge/intel/wildcatpoint/finalize.c similarity index 100% rename from src/soc/intel/broadwell/pch/finalize.c rename to src/southbridge/intel/wildcatpoint/finalize.c diff --git a/src/soc/intel/broadwell/pch/hda.c b/src/southbridge/intel/wildcatpoint/hda.c similarity index 100% rename from src/soc/intel/broadwell/pch/hda.c rename to src/southbridge/intel/wildcatpoint/hda.c diff --git a/src/soc/intel/broadwell/include/soc/adsp.h b/src/southbridge/intel/wildcatpoint/include/soc/adsp.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/adsp.h rename to src/southbridge/intel/wildcatpoint/include/soc/adsp.h diff --git a/src/soc/intel/broadwell/include/soc/cfr.h b/src/southbridge/intel/wildcatpoint/include/soc/cfr.h similarity index 95% rename from src/soc/intel/broadwell/include/soc/cfr.h rename to src/southbridge/intel/wildcatpoint/include/soc/cfr.h index 91dc9048c7a..7f1e604e145 100644 --- a/src/soc/intel/broadwell/include/soc/cfr.h +++ b/src/southbridge/intel/wildcatpoint/include/soc/cfr.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * CFR enums and structs for soc/intel/broadwell + * CFR enums and structs for northbridge/intel/broadwell */ #ifndef _BROADWELL_CFR_H_ diff --git a/src/soc/intel/broadwell/include/soc/chromeos.h b/src/southbridge/intel/wildcatpoint/include/soc/chromeos.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/chromeos.h rename to src/southbridge/intel/wildcatpoint/include/soc/chromeos.h diff --git a/src/soc/intel/broadwell/include/soc/device_nvs.h b/src/southbridge/intel/wildcatpoint/include/soc/device_nvs.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/device_nvs.h rename to src/southbridge/intel/wildcatpoint/include/soc/device_nvs.h diff --git a/src/soc/intel/broadwell/include/soc/ehci.h b/src/southbridge/intel/wildcatpoint/include/soc/ehci.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/ehci.h rename to src/southbridge/intel/wildcatpoint/include/soc/ehci.h diff --git a/src/soc/intel/broadwell/include/soc/gpio.h b/src/southbridge/intel/wildcatpoint/include/soc/gpio.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/gpio.h rename to src/southbridge/intel/wildcatpoint/include/soc/gpio.h diff --git a/src/soc/intel/broadwell/include/soc/iomap.h b/src/southbridge/intel/wildcatpoint/include/soc/iomap.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/iomap.h rename to src/southbridge/intel/wildcatpoint/include/soc/iomap.h diff --git a/src/soc/intel/broadwell/include/soc/lpc.h b/src/southbridge/intel/wildcatpoint/include/soc/lpc.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/lpc.h rename to src/southbridge/intel/wildcatpoint/include/soc/lpc.h diff --git a/src/soc/intel/broadwell/include/soc/me.h b/src/southbridge/intel/wildcatpoint/include/soc/me.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/me.h rename to src/southbridge/intel/wildcatpoint/include/soc/me.h diff --git a/src/soc/intel/broadwell/include/soc/nvs.h b/src/southbridge/intel/wildcatpoint/include/soc/nvs.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/nvs.h rename to src/southbridge/intel/wildcatpoint/include/soc/nvs.h diff --git a/src/soc/intel/broadwell/include/soc/pch.h b/src/southbridge/intel/wildcatpoint/include/soc/pch.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/pch.h rename to src/southbridge/intel/wildcatpoint/include/soc/pch.h diff --git a/src/soc/intel/broadwell/include/soc/pm.h b/src/southbridge/intel/wildcatpoint/include/soc/pm.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/pm.h rename to src/southbridge/intel/wildcatpoint/include/soc/pm.h diff --git a/src/soc/intel/broadwell/include/soc/rcba.h b/src/southbridge/intel/wildcatpoint/include/soc/rcba.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/rcba.h rename to src/southbridge/intel/wildcatpoint/include/soc/rcba.h diff --git a/src/soc/intel/broadwell/include/soc/sata.h b/src/southbridge/intel/wildcatpoint/include/soc/sata.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/sata.h rename to src/southbridge/intel/wildcatpoint/include/soc/sata.h diff --git a/src/soc/intel/broadwell/include/soc/serialio.h b/src/southbridge/intel/wildcatpoint/include/soc/serialio.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/serialio.h rename to src/southbridge/intel/wildcatpoint/include/soc/serialio.h diff --git a/src/soc/intel/broadwell/include/soc/spi.h b/src/southbridge/intel/wildcatpoint/include/soc/spi.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/spi.h rename to src/southbridge/intel/wildcatpoint/include/soc/spi.h diff --git a/src/soc/intel/broadwell/include/soc/xhci.h b/src/southbridge/intel/wildcatpoint/include/soc/xhci.h similarity index 100% rename from src/soc/intel/broadwell/include/soc/xhci.h rename to src/southbridge/intel/wildcatpoint/include/soc/xhci.h diff --git a/src/soc/intel/broadwell/pch/lpc.c b/src/southbridge/intel/wildcatpoint/lpc.c similarity index 98% rename from src/soc/intel/broadwell/pch/lpc.c rename to src/southbridge/intel/wildcatpoint/lpc.c index 49a36b148ab..9dd2350c93c 100644 --- a/src/soc/intel/broadwell/pch/lpc.c +++ b/src/southbridge/intel/wildcatpoint/lpc.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -162,7 +162,7 @@ static void pch_power_options(struct device *dev) printk(BIOS_INFO, "Set power %s after power failure.\n", state); if (dev->chip_info) { - const struct soc_intel_broadwell_pch_config *config = dev->chip_info; + const struct southbridge_intel_wildcatpoint_config *config = dev->chip_info; /* GPE setup based on device tree configuration */ enable_all_gpe(config->gpe0_en_1, config->gpe0_en_2, @@ -326,7 +326,7 @@ static void pch_enable_mphy(void) static void pch_init_deep_sx(struct device *dev) { - const struct soc_intel_broadwell_pch_config *config = dev->chip_info; + const struct southbridge_intel_wildcatpoint_config *config = dev->chip_info; if (!config) return; @@ -575,7 +575,7 @@ static void pch_lpc_add_io_resources(struct device *dev) /* LPC Generic IO Decode range. */ if (dev->chip_info) { - const struct soc_intel_broadwell_pch_config *config = dev->chip_info; + const struct southbridge_intel_wildcatpoint_config *config = dev->chip_info; pch_lpc_add_gen_io_resources(dev, config->gen1_dec, LPC_GEN1_DEC); pch_lpc_add_gen_io_resources(dev, config->gen2_dec, LPC_GEN2_DEC); pch_lpc_add_gen_io_resources(dev, config->gen3_dec, LPC_GEN3_DEC); diff --git a/src/soc/intel/broadwell/pch/me.c b/src/southbridge/intel/wildcatpoint/me.c similarity index 99% rename from src/soc/intel/broadwell/pch/me.c rename to src/southbridge/intel/wildcatpoint/me.c index 5756bdb00d0..33bf915fae2 100644 --- a/src/soc/intel/broadwell/pch/me.c +++ b/src/southbridge/intel/wildcatpoint/me.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include @@ -948,7 +948,7 @@ static int intel_me_read_mbp(me_bios_payload *mbp_data, struct device *dev) /* Check whether ME is present and do basic init */ static void intel_me_init(struct device *dev) { - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); me_bios_path path = intel_me_path(dev); me_bios_payload mbp_data; int mbp_ret; diff --git a/src/soc/intel/broadwell/pch/me_status.c b/src/southbridge/intel/wildcatpoint/me_status.c similarity index 100% rename from src/soc/intel/broadwell/pch/me_status.c rename to src/southbridge/intel/wildcatpoint/me_status.c diff --git a/src/soc/intel/broadwell/pch/pch.c b/src/southbridge/intel/wildcatpoint/pch.c similarity index 98% rename from src/soc/intel/broadwell/pch/pch.c rename to src/southbridge/intel/wildcatpoint/pch.c index fa03d7359a7..3714a7d8a71 100644 --- a/src/soc/intel/broadwell/pch/pch.c +++ b/src/southbridge/intel/wildcatpoint/pch.c @@ -196,7 +196,7 @@ static void broadwell_pch_enable_dev(struct device *dev) } } -struct chip_operations soc_intel_broadwell_pch_ops = { +struct chip_operations southbridge_intel_wildcatpoint_ops = { .name = "Intel Broadwell PCH", .enable_dev = &broadwell_pch_enable_dev, }; diff --git a/src/soc/intel/broadwell/pch/pcie.c b/src/southbridge/intel/wildcatpoint/pcie.c similarity index 98% rename from src/soc/intel/broadwell/pch/pcie.c rename to src/southbridge/intel/wildcatpoint/pcie.c index 4847da67887..9262d3c628b 100644 --- a/src/soc/intel/broadwell/pch/pcie.c +++ b/src/southbridge/intel/wildcatpoint/pcie.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include @@ -121,7 +121,7 @@ static void root_port_init_config(struct device *dev) root_port_config_update_gbe_port(); pci_or_config8(dev, 0xe2, 3 << 4); - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); rpc.coalesce = config->pcie_port_coalesce; } @@ -435,7 +435,7 @@ static void pcie_add_0x0202000_iobp(u32 reg) static void pch_pcie_early(struct device *dev) { - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); int do_aspm = 0; int rp = root_port_number(dev); diff --git a/src/soc/intel/broadwell/pch/pmutil.c b/src/southbridge/intel/wildcatpoint/pmutil.c similarity index 100% rename from src/soc/intel/broadwell/pch/pmutil.c rename to src/southbridge/intel/wildcatpoint/pmutil.c diff --git a/src/soc/intel/broadwell/pch/power_state.c b/src/southbridge/intel/wildcatpoint/power_state.c similarity index 100% rename from src/soc/intel/broadwell/pch/power_state.c rename to src/southbridge/intel/wildcatpoint/power_state.c diff --git a/src/soc/intel/broadwell/pch/ramstage.c b/src/southbridge/intel/wildcatpoint/ramstage.c similarity index 96% rename from src/soc/intel/broadwell/pch/ramstage.c rename to src/southbridge/intel/wildcatpoint/ramstage.c index 027b3bb1c92..19105ff7994 100644 --- a/src/soc/intel/broadwell/pch/ramstage.c +++ b/src/southbridge/intel/wildcatpoint/ramstage.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include /* Save bit index for PM1_STS and GPE_STS for ACPI _SWS */ static void pm_fill_gnvs(struct global_nvs *gnvs, const struct chipset_power_state *ps) diff --git a/src/soc/intel/broadwell/pch/sata.c b/src/southbridge/intel/wildcatpoint/sata.c similarity index 97% rename from src/soc/intel/broadwell/pch/sata.c rename to src/southbridge/intel/wildcatpoint/sata.c index 92d34c302c9..d2bb5d37a13 100644 --- a/src/soc/intel/broadwell/pch/sata.c +++ b/src/southbridge/intel/wildcatpoint/sata.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include static inline u32 sir_read(struct device *dev, int idx) @@ -26,7 +26,7 @@ static inline void sir_write(struct device *dev, int idx, u32 value) static void sata_init(struct device *dev) { - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); u32 reg32; u8 *abar; u16 reg16; @@ -259,7 +259,7 @@ static void sata_init(struct device *dev) static void sata_enable(struct device *dev) { /* Get the chip configuration */ - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); u16 map = 0x0060; map |= (config->sata_port_map ^ 0xf) << 8; diff --git a/src/soc/intel/broadwell/pch/serialio.c b/src/southbridge/intel/wildcatpoint/serialio.c similarity index 98% rename from src/soc/intel/broadwell/pch/serialio.c rename to src/southbridge/intel/wildcatpoint/serialio.c index 336b501b32c..bc86db30982 100644 --- a/src/soc/intel/broadwell/pch/serialio.c +++ b/src/southbridge/intel/wildcatpoint/serialio.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include @@ -156,7 +156,7 @@ static void serialio_init_once(int acpi_mode) static void serialio_init(struct device *dev) { - const struct soc_intel_broadwell_pch_config *config = config_of(dev); + const struct southbridge_intel_wildcatpoint_config *config = config_of(dev); struct resource *bar0, *bar1; int sio_index = -1; diff --git a/src/soc/intel/broadwell/pch/smi.c b/src/southbridge/intel/wildcatpoint/smi.c similarity index 100% rename from src/soc/intel/broadwell/pch/smi.c rename to src/southbridge/intel/wildcatpoint/smi.c diff --git a/src/soc/intel/broadwell/pch/smihandler.c b/src/southbridge/intel/wildcatpoint/smihandler.c similarity index 100% rename from src/soc/intel/broadwell/pch/smihandler.c rename to src/southbridge/intel/wildcatpoint/smihandler.c diff --git a/src/soc/intel/broadwell/pch/usb_debug.c b/src/southbridge/intel/wildcatpoint/usb_debug.c similarity index 100% rename from src/soc/intel/broadwell/pch/usb_debug.c rename to src/southbridge/intel/wildcatpoint/usb_debug.c diff --git a/src/soc/intel/broadwell/pch/usb_ehci.c b/src/southbridge/intel/wildcatpoint/usb_ehci.c similarity index 100% rename from src/soc/intel/broadwell/pch/usb_ehci.c rename to src/southbridge/intel/wildcatpoint/usb_ehci.c diff --git a/src/soc/intel/broadwell/pch/usb_xhci.c b/src/southbridge/intel/wildcatpoint/usb_xhci.c similarity index 100% rename from src/soc/intel/broadwell/pch/usb_xhci.c rename to src/southbridge/intel/wildcatpoint/usb_xhci.c diff --git a/src/superio/acpi/pnp_kbc.asl b/src/superio/acpi/pnp_kbc.asl index b0055be2258..fca0c77382f 100644 --- a/src/superio/acpi/pnp_kbc.asl +++ b/src/superio/acpi/pnp_kbc.asl @@ -11,12 +11,18 @@ * SUPERIO_CHIP_NAME The name of the Super I/O chip (unique, required) * SUPERIO_KBC_LDN The logical device number on the Super I/O * chip for this keyboard controller (required) + * SUPERIO_KBC_PS2KID The name of PS/2 keyboard controller device. + * If not defined, defaults to KBD# where # is + * SUPERIO_KBC_LDN. * SUPERIO_KBC_PS2M If defined, PS/2 mouse support is included in * the KBC_LDN. Mouse irq is set at IRQ1 of the * KBC_LDN. * SUPERIO_KBC_PS2LDN If defined, specifies a second LDN to configure * PS/2 mouse support. Mouse irq is set at IRQ0 of * this LDN. + * SUPERIO_KBC_PS2MID The name of PS/2 mouse support device. + * If not defined, defaults to PS2# where # is + * KBC_LDN or KBC_PS2LDN as appropriate. * SUPERIO_KBC_PS2M and SUPERIO_KBC_PS2LDN are mutually exclusive. */ @@ -34,8 +40,20 @@ # error "SUPERIO_KBC_PS2M and SUPERIO_KBC_PS2LDN are mutually exclusive." #endif -Device (SUPERIO_ID(KBD, SUPERIO_KBC_LDN)) { - Name (_HID, EisaId ("PNP0303")) +#ifndef SUPERIO_KBC_PS2KID +#define SUPERIO_KBC_PS2KID SUPERIO_ID(KBD, SUPERIO_KBC_LDN) +#endif + +#ifndef SUPERIO_KBC_PS2MID +#ifdef SUPERIO_KBC_PS2LDN +#define SUPERIO_KBC_PS2MID SUPERIO_ID(PS2, SUPERIO_KBC_PS2LDN) +#else +#define SUPERIO_KBC_PS2MID SUPERIO_ID(PS2, SUPERIO_KBC_LDN) +#endif /* SUPERIO_KBC_PS2LDN */ +#endif + +Device (SUPERIO_KBC_PS2KID) { + Name (_HID, EisaId (CONFIG_PS2K_EISAID)) Name (_UID, SUPERIO_UID(KBD, SUPERIO_KBC_LDN)) Method (_STA) @@ -48,10 +66,8 @@ Device (SUPERIO_ID(KBD, SUPERIO_KBC_LDN)) { ENTER_CONFIG_MODE (SUPERIO_KBC_LDN) PNP_DEVICE_ACTIVE = 0 EXIT_CONFIG_MODE () - #if defined(SUPERIO_KBC_PS2LDN) - Notify (SUPERIO_ID(PS2, SUPERIO_KBC_PS2LDN), 1) - #elif defined(SUPERIO_KBC_PS2M) - Notify (SUPERIO_ID(PS2, SUPERIO_KBC_LDN), 1) + #if defined(SUPERIO_KBC_PS2LDN) || defined(SUPERIO_KBC_PS2M) + Notify (SUPERIO_KBC_PS2MID, 1) #endif } @@ -97,26 +113,24 @@ Device (SUPERIO_ID(KBD, SUPERIO_KBC_LDN)) { PNP_WRITE_IRQ(PNP_IRQ0, Arg0, IR0) PNP_DEVICE_ACTIVE = 1 EXIT_CONFIG_MODE () - #if defined(SUPERIO_KBC_PS2LDN) - Notify (SUPERIO_ID(PS2, SUPERIO_KBC_PS2LDN), 1) - #elif defined(SUPERIO_KBC_PS2M) - Notify (SUPERIO_ID(PS2, SUPERIO_KBC_LDN), 1) + #if defined(SUPERIO_KBC_PS2LDN) || defined(SUPERIO_KBC_PS2M) + Notify (SUPERIO_KBC_PS2MID, 1) #endif } } #if defined(SUPERIO_KBC_PS2M) -Device (SUPERIO_ID(PS2, SUPERIO_KBC_LDN)) { - Name (_HID, EisaId ("PNP0F13")) +Device (SUPERIO_KBC_PS2MID) { + Name (_HID, EisaId (CONFIG_PS2M_EISAID)) Name (_UID, SUPERIO_UID(PS2, SUPERIO_KBC_LDN)) Method (_STA) { - Return (^^SUPERIO_ID(KBD, SUPERIO_KBC_LDN)._STA ()) + Return (^^SUPERIO_KBC_PS2KID._STA ()) } Method (_PSC) { - Return (^^SUPERIO_ID(KBD, SUPERIO_KBC_LDN)._PSC ()) + Return (^^SUPERIO_KBC_PS2KID._PSC ()) } Method (_CRS, 0, Serialized) @@ -149,13 +163,13 @@ Device (SUPERIO_ID(PS2, SUPERIO_KBC_LDN)) { } } #elif defined(SUPERIO_KBC_PS2LDN) -Device (SUPERIO_ID(PS2, SUPERIO_KBC_PS2LDN)) { - Name (_HID, EisaId ("PNP0F13")) +Device (SUPERIO_KBC_PS2MID) { + Name (_HID, EisaId (CONFIG_PS2M_EISAID)) Name (_UID, SUPERIO_UID(PS2, SUPERIO_KBC_PS2LDN)) Method (_STA) { - Local0 = ^^SUPERIO_ID(KBD, SUPERIO_KBC_LDN)._STA () + Local0 = ^^SUPERIO_KBC_PS2KID._STA () If (Local0 == DEVICE_PRESENT_ACTIVE) { PNP_GENERIC_STA(SUPERIO_KBC_PS2LDN) } Else { diff --git a/src/superio/nuvoton/Makefile.mk b/src/superio/nuvoton/Makefile.mk index 3c8df4f8f10..eab992a666d 100644 --- a/src/superio/nuvoton/Makefile.mk +++ b/src/superio/nuvoton/Makefile.mk @@ -3,6 +3,8 @@ ## include generic nuvoton pre-ram stage driver bootblock-$(CONFIG_SUPERIO_NUVOTON_COMMON_PRE_RAM) += common/early_serial.c romstage-$(CONFIG_SUPERIO_NUVOTON_COMMON_PRE_RAM) += common/early_serial.c +## include generic nuvoton helper +ramstage-$(CONFIG_SUPERIO_NUVOTON_COMMON_PRE_RAM) += common/common.c subdirs-$(CONFIG_SUPERIO_NUVOTON_WPCM450) += wpcm450 subdirs-$(CONFIG_SUPERIO_NUVOTON_NCT5104D) += nct5104d @@ -13,4 +15,5 @@ subdirs-$(CONFIG_SUPERIO_NUVOTON_NCT6687D) += nct6687d subdirs-$(CONFIG_SUPERIO_NUVOTON_NCT6776) += nct6776 subdirs-$(CONFIG_SUPERIO_NUVOTON_NCT6779D) += nct6779d subdirs-$(CONFIG_SUPERIO_NUVOTON_NCT6791D) += nct6791d +subdirs-$(CONFIG_SUPERIO_NUVOTON_NCT6796D) += nct6796d subdirs-$(CONFIG_SUPERIO_NUVOTON_NPCD378) += npcd378 diff --git a/src/superio/nuvoton/common/Kconfig b/src/superio/nuvoton/common/Kconfig index 376ae16422a..f3e8e4ae932 100644 --- a/src/superio/nuvoton/common/Kconfig +++ b/src/superio/nuvoton/common/Kconfig @@ -18,6 +18,11 @@ config HAVE_SHARED_PS2_PORT help Select this option if your mainboard has a single PS/2 port for both keyboard and mouse, and where a Y-cable cannot allow both keyboard and mouse to work off the same - port. This one port usually works for keyboards only. Add the nvram option - "swap_keyboard_and_mouse" to cmos.layout to allow changing this port into a - mouse port. + port. This one port usually works for keyboards only. Add the nvram/CFR option + "ps2_port_role" to allow changing this port into a mouse port. + +config SUPERIO_NUVOTON_PNP_BASE + hex + depends on SUPERIO_NUVOTON_COMMON_PRE_RAM + help + Set the base port of the super I/O chip. diff --git a/src/superio/nuvoton/common/acpi/superio.asl b/src/superio/nuvoton/common/acpi/superio.asl new file mode 100644 index 00000000000..9e49cf5b9eb --- /dev/null +++ b/src/superio/nuvoton/common/acpi/superio.asl @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * Include this file into a mainboard's DSDT _SB device tree and it will + * expose the NCT677x SuperIO and some of its functionality. + * + * It allows the change of IO ports, IRQs and DMA settings on logical + * devices, disabling and reenabling logical devices. + * + * LDN State + * NCT677X_PP Implemented, untested + * NCT677x_SP1 Implemented, untested + * NCT677x_SP2 Implemented, untested + * NCT677x_KBC Implemented, untested + * 0x308 GPIO Implemented, untested + * 0xb HWM Implemented, untested + * + * Controllable through preprocessor defines: + * + * SIO identities + * SUPERIO_DEV Device identifier for this SIO (e.g. SIO0; required) + * SUPERIO_CHIP_NAME Chip name (@) + * SUPERIO_FULL_CHIP_NAME Unicode device name (@) + * SUPERIO_PNP_BASE I/O address of the first PnP configuration register (@) + * Items with @ are required if multiple SIO chips are being used. + * + * Functionality exposed if defined: + * NCT677X_SHOW_PP Parallel port + * NCT677X_SHOW_SP1 Serial port 1 + * NCT677X_SHOW_SP2 Serial port 2 + * NCT677X_SHOW_KBC Keyboard controller + * NCT677X_SHOW_GPIO GPIO by I/O support + * NCT677X_SHOW_HWM Hardware monitor + */ +#include + +/* Get SUPERIO_PNP_BASE from Kconfig if not redefined */ +#ifndef SUPERIO_PNP_BASE +#define SUPERIO_PNP_BASE CONFIG_SUPERIO_NUVOTON_PNP_BASE +#endif + +#include + +#undef PNP_DEFAULT_PSC +#define PNP_DEFAULT_PSC Return (0) /* no power management */ + +#define ENABLE_KEYBOARD_WAKEUP SKWK +#define POWER_LOSS_LAST_STATE PLSF + +Device(SUPERIO_DEV) { + Name (_HID, EisaId("PNP0A05")) + Name (_STR, Unicode(SUPERIO_FULL_CHIP_NAME)) + Name (_UID, SUPERIO_UID(SUPERIO_DEV,)) + + /* SuperIO configuration ports */ + OperationRegion (CREG, SystemIO, SUPERIO_PNP_BASE, 2) + Field (CREG, ByteAcc, NoLock, Preserve) + { + PNP_ADDR_REG, 8, + PNP_DATA_REG, 8, + } + IndexField (PNP_ADDR_REG, PNP_DATA_REG, ByteAcc, NoLock, Preserve) + { + Offset (0x07), + PNP_LOGICAL_DEVICE, 8, /* Logical device selector */ + + Offset (0x30), + PNP_DEVICE_ACTIVE, 1, /* Logical device activation */ + ACT1, 1, /* Logical device activation */ + ACT2, 1, /* Logical device activation */ + ACT3, 1, /* Logical device activation */ + ACT4, 1, /* Logical device activation */ + ACT5, 1, /* Logical device activation */ + ACT6, 1, /* Logical device activation */ + ACT7, 1, /* Logical device activation */ + + Offset (0x60), + PNP_IO0_HIGH_BYTE, 8, /* First I/O port base - high byte */ + PNP_IO0_LOW_BYTE, 8, /* First I/O port base - low byte */ + Offset (0x62), + PNP_IO1_HIGH_BYTE, 8, /* Second I/O port base - high byte */ + PNP_IO1_LOW_BYTE, 8, /* Second I/O port base - low byte */ + Offset (0x64), + PNP_IO2_HIGH_BYTE, 8, /* Third I/O port base - high byte */ + PNP_IO2_LOW_BYTE, 8, /* Third I/O port base - low byte */ + Offset (0x70), + PNP_IRQ0, 8, /* First IRQ */ + Offset (0x72), + PNP_IRQ1, 8, /* Second IRQ */ + Offset (0x74), + PNP_DMA0, 8, /* DRQ */ + + Offset (0xe0), /* Config register 0xe0 etc. */ + ,6, + ENABLE_KEYBOARD_WAKEUP, 1, + Offset (0xe6), + ,4, + POWER_LOSS_LAST_STATE, 1, + Offset (0xf2), + SPME, 1, /* Enable PME */ + ,7, + OPT3, 8, + OPT4, 8, + ,8, + OPT6, 8, + OPT7, 8 + } + + Method (_CRS) + { + /* Announce the used I/O ports to the OS */ + Return (ResourceTemplate () { + IO (Decode16, SUPERIO_PNP_BASE, SUPERIO_PNP_BASE, 1, 2) + }) + } + + Method (SIOS, 1, NotSerialized) + { + ENTER_CONFIG_MODE(NCT677X_ACPI) + if (Arg0 == 5) + { + ENABLE_KEYBOARD_WAKEUP = 0 + /* Log "power off" state */ + POWER_LOSS_LAST_STATE = 1 + } + EXIT_CONFIG_MODE() + } + + Method (SIOW, 1, NotSerialized) + { + } + + #undef PNP_ENTER_MAGIC_1ST + #undef PNP_ENTER_MAGIC_2ND + #undef PNP_ENTER_MAGIC_3RD + #undef PNP_ENTER_MAGIC_4TH + #undef PNP_EXIT_MAGIC_1ST + #undef PNP_EXIT_SPECIAL_REG + #undef PNP_EXIT_SPECIAL_VAL + #define PNP_ENTER_MAGIC_1ST 0x87 + #define PNP_ENTER_MAGIC_2ND 0x87 + #define PNP_EXIT_MAGIC_1ST 0xaa + #include + +#ifdef NCT677X_SHOW_PP + #undef SUPERIO_PNP_HID + #undef SUPERIO_PNP_LDN + #undef SUPERIO_PNP_IO0 + #undef SUPERIO_PNP_IRQ0 + #undef SUPERIO_PNP_DMA + /* + * The extra code required to dynamically reflect ECP in the HID + * isn't currently justified, so the HID is hardcoded as not + * using ECP. "PNP0401" would indicate ECP. + */ + #define SUPERIO_PNP_HID "PNP0400" + #define SUPERIO_PNP_LDN NCT677X_PP + #define SUPERIO_PNP_IO0 0x08, 0x08 + #define SUPERIO_PNP_IRQ0 + #define SUPERIO_PNP_DMA + #include +#endif + +#undef SUPERIO_UART_DDN +#undef SUPERIO_UART_PM_REG + +#ifdef NCT677X_SHOW_SP1 + #undef SUPERIO_UART_LDN + #define SUPERIO_UART_LDN NCT677X_SP1 + #include +#endif + +#ifdef NCT677X_SHOW_SP2 + #undef SUPERIO_UART_LDN + #define SUPERIO_UART_LDN NCT677X_SP2 + #include +#endif + +#ifdef NCT677X_SHOW_KBC + #undef SUPERIO_KBC_LDN + #undef SUPERIO_KBC_PS2M + #undef SUPERIO_KBC_PS2LDN + #define SUPERIO_KBC_LDN NCT677X_KBC + #define SUPERIO_KBC_PS2M + #include +#endif + +#undef SUPERIO_PNP_HID +#undef SUPERIO_PNP_DMA + +#ifdef NCT677X_SHOW_HWM + #undef SUPERIO_PNP_LDN + #undef SUPERIO_PNP_IO0 + #undef SUPERIO_PNP_IO1 + #undef SUPERIO_PNP_IRQ0 + #define SUPERIO_PNP_LDN NCT677X_HWM_FPLED + #define SUPERIO_PNP_IO0 0x08, 0x08 + #define SUPERIO_PNP_IO1 0x08, 0x08 + #define SUPERIO_PNP_IRQ0 + #include +#endif + +#ifdef NCT677X_SHOW_GPIO + #undef SUPERIO_PNP_LDN + #undef SUPERIO_PNP_IO0 + #undef SUPERIO_PNP_IO1 + #undef SUPERIO_PNP_IRQ0 + #undef PNP_DEVICE_ACTIVE + #define PNP_DEVICE_ACTIVE ACT3 + #define SUPERIO_PNP_LDN 8 + #define SUPERIO_PNP_IO0 0x08, 0x08 + #include +#endif +} diff --git a/src/superio/nuvoton/common/common.c b/src/superio/nuvoton/common/common.c new file mode 100644 index 00000000000..e2948cfb2d0 --- /dev/null +++ b/src/superio/nuvoton/common/common.c @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * Configuration routines common to Nuvoton SIO chips, + * except nct5104d, nct6687d, npcd378, wpcm450. + */ + +#include +#include +#include +#include +#include +#include +#include "nuvoton.h" + +#define MAINBOARD_POWER_OFF 0 +#define MAINBOARD_POWER_ON 1 +#define MAINBOARD_POWER_KEEP 2 + +#define POWER_LOSS_CONTROL_SHIFT 5 +#define POWER_LOSS_CONTROL_MASK (3 << POWER_LOSS_CONTROL_SHIFT) + +/* CR 0xe0 */ +#define KBD_WAKEUP_PSOUT BIT(6) +#define KBD_MS_SWAP BIT(2) +#define KBXKEY BIT(0) +/* CR 0xe4 */ +/* Power RAM in S3; for reference only; this needs to be enabled in bootblock */ +#define EN_3VSBSW BIT(4) +#define KBD_WAKEUP_ANYKEY BIT(3) + +static void enable_ps2_mouse(struct device *dev, bool en) +{ + if (!CONFIG(HAVE_SHARED_PS2_PORT)) + return; + + pnp_enter_conf_mode(dev); + u8 bit = KBD_MS_SWAP; + /* pnp_set_logical_device() is not used because the bit is in another LD. */ + pnp_write_config(dev, 0x7, NCT677X_ACPI); + pnp_unset_and_set_config(dev, 0xe0, bit, en ? bit : 0); + pnp_exit_conf_mode(dev); +} + +void nuvoton_common_init(struct device *dev) +{ + u8 byte, role, mask; + + if (!dev->enabled) + return; + + switch (dev->path.pnp.device) { + case NCT677X_KBC: + /* + * If mainboard has both PS/2 keyboard and mouse ports, bootblock code + * should enable both and leave them enabled. + */ + role = PS2_PORT_ROLE_KEYBOARD; + if (CONFIG(HAVE_SHARED_PS2_PORT)) { + role = get_uint_option("ps2_port_role", PS2_PORT_ROLE_KEYBOARD); + if (role > PS2_PORT_ROLE_AUTO) + break; /* Invalid setting; abort */ + } + if (role != PS2_PORT_ROLE_KEYBOARD) { + enable_ps2_mouse(dev, true); + if (role == PS2_PORT_ROLE_MOUSE) + break; /* Leave the port swapped; we're done */ + + /* This leaves PS2_PORT_ROLE_AUTO */ + if (pc_keyboard_init(PROBE_AUX_DEVICE)) { + break; /* Mouse found; leave the port swapped */ + } else { + printk(BIOS_INFO, "%s: Mouse not detected.\n", __func__); + } + } + /* Set port as keyboard, and initialize keyboard if enabled in Kconfig */ + enable_ps2_mouse(dev, false); + pc_keyboard_init(NO_AUX_DEVICE); + break; + case NCT677X_ACPI: + pnp_enter_conf_mode(dev); + pnp_set_logical_device(dev); + + /* + * Keyboard wakeup: any key + * NOTE: Bits related to keyboard wakeup are kept even in S5 (soft off), + * and will allow keyboard to wake system even from this state. + * Add SMM/ACPI code to turn it back off before entering S5. + */ + pnp_unset_and_set_config(dev, 0xe0, 0, KBD_WAKEUP_PSOUT | KBXKEY); + + byte = KBD_WAKEUP_ANYKEY; + mask = 0; + /* + * Set power state after power fail. + * + * Important: Make sure the definitions in mainboard/Kconfig around + * MAINBOARD_POWER_FAILURE_STATE and your board's cmos.layout match. + * And if MAINBOARD_POWER_FAILURE_STATE deviates from the chip's + * expectation (ie. 0=off, 1=on, 2=keep), this code must be adapted. + */ + if (CONFIG(HAVE_POWER_STATE_AFTER_FAILURE)) { + unsigned int power_status = get_uint_option("power_on_after_fail", + CONFIG_MAINBOARD_POWER_FAILURE_STATE); + + switch (power_status) { + case MAINBOARD_POWER_KEEP: + /* + * KEEP power state is software emulated using USER and + * a manually set power state. + */ + power_status = 3; + __fallthrough; + case MAINBOARD_POWER_OFF: + case MAINBOARD_POWER_ON: + byte |= (power_status << POWER_LOSS_CONTROL_SHIFT); + mask = POWER_LOSS_CONTROL_MASK; + break; + } + /* Log a "on" power state */ + pnp_unset_and_set_config(dev, 0xe6, BIT(4), 0); + } + + pnp_unset_and_set_config(dev, 0xe4, mask, byte); + pnp_exit_conf_mode(dev); + break; + } +} + +struct device_operations nuvoton_common_ops = { + .read_resources = noop_read_resources, + .set_resources = pnp_set_resources, + .enable_resources = pnp_enable_resources, + .enable = pnp_alt_enable, + .init = nuvoton_common_init, + .ops_pnp_mode = &pnp_conf_mode_8787_aa, +}; diff --git a/src/superio/nuvoton/common/early_serial.c b/src/superio/nuvoton/common/early_serial.c index f86e7a27d05..f0162a8f9d9 100644 --- a/src/superio/nuvoton/common/early_serial.c +++ b/src/superio/nuvoton/common/early_serial.c @@ -2,21 +2,6 @@ /* * A generic romstage (pre-ram) driver for Nuvoton variant Super I/O chips. - * - * The following is derived directly from the vendor Nuvoton's data-sheets: - * - * To toggle between `configuration mode` and `normal operation mode` as to - * manipulate the various LDN's in Nuvoton Super I/O's we are required to - * pass magic numbers `passwords keys`. - * - * NUVOTON_ENTRY_KEY := enable configuration : 0x87 - * NUVOTON_EXIT_KEY := disable configuration : 0xAA - * - * To modify a LDN's configuration register, we use the index port to select - * the index of the LDN and then write to the data port to alter the - * parameters. A default index, data port pair is 0x4E, 0x4F respectively, a - * user modified pair is 0x2E, 0x2F respectively. - * */ #include @@ -25,25 +10,6 @@ #include #include "nuvoton.h" -#define NUVOTON_ENTRY_KEY 0x87 -#define NUVOTON_EXIT_KEY 0xAA - -/* Enable configuration: pass entry key '0x87' into index port dev - * two times. */ -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_ENTRY_KEY, port); - outb(NUVOTON_ENTRY_KEY, port); -} - -/* Disable configuration: pass exit key '0xAA' into index port dev. */ -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) -{ - u16 port = dev >> 8; - outb(NUVOTON_EXIT_KEY, port); -} - /* Bring up early serial debugging output before the RAM is initialized. */ void nuvoton_enable_serial(pnp_devfn_t dev, u16 iobase) { diff --git a/src/superio/nuvoton/common/nuvoton.h b/src/superio/nuvoton/common/nuvoton.h index 0243c69b3ec..1dd20923e08 100644 --- a/src/superio/nuvoton/common/nuvoton.h +++ b/src/superio/nuvoton/common/nuvoton.h @@ -4,14 +4,55 @@ #define SUPERIO_NUVOTON_COMMON_H #ifndef __ACPI__ +#include #include #include -void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev); -void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev); +#if ENV_PNP_SIMPLE_DEVICE +#include + +/* + * To toggle between `configuration mode` and `normal operation mode` as to + * manipulate the various LDN's in Nuvoton Super I/O's we are required to + * pass magic numbers `passwords keys`. + */ +#define NUVOTON_ENTRY_KEY 0x87 +#define NUVOTON_EXIT_KEY 0xAA + +static __always_inline void nuvoton_pnp_enter_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(NUVOTON_ENTRY_KEY, port); + outb(NUVOTON_ENTRY_KEY, port); +} + +static __always_inline void nuvoton_pnp_exit_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(NUVOTON_EXIT_KEY, port); +} + void nuvoton_enable_serial(pnp_devfn_t dev, u16 iobase); +#endif /* SIMPLE_DEVICE */ + +#if ENV_RAMSTAGE +extern struct device_operations nuvoton_common_ops; + +void nuvoton_common_init(struct device *dev); +#endif + +#if ENV_SMM +void nuvoton_smi_sleep(u8 slp_typ); #endif +enum e_ps2role { + PS2_PORT_ROLE_KEYBOARD = 0, + PS2_PORT_ROLE_MOUSE = 1, + PS2_PORT_ROLE_AUTO = 2 +}; + +#endif /* __ACPI__ */ + /* * Logical Device Numbers (LDN) common to all Nuvoton SIOs. * Because they will be incorporated into ACPI device IDs, diff --git a/src/superio/nuvoton/common/smm.c b/src/superio/nuvoton/common/smm.c new file mode 100644 index 00000000000..9fdefc43b63 --- /dev/null +++ b/src/superio/nuvoton/common/smm.c @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * SMM routines common to Nuvoton NCTxxxx SIO chips, + * except 5104, 6687, npcd378, wpcm450. + */ + +/* SMM code needs to be kept simple */ +#define __SIMPLE_DEVICE__ + +#include +#include +#include +#include +#include "nuvoton.h" + +#define ACPI_DEV PNP_DEV(CONFIG_SUPERIO_NUVOTON_PNP_BASE, NCT677X_ACPI) + +void nuvoton_smi_sleep(u8 slp_typ) +{ + if (slp_typ != ACPI_S5) + return; + + _Static_assert(CONFIG_SUPERIO_NUVOTON_PNP_BASE != 0, + "Kconfig SUPERIO_NUVOTON_PNP_BASE must be set!"); + nuvoton_pnp_enter_conf_state(ACPI_DEV); + pnp_set_logical_device(ACPI_DEV); + pnp_unset_and_set_config(ACPI_DEV, 0xe0, BIT(6), 0); /* KB wakeup off */ + pnp_unset_and_set_config(ACPI_DEV, 0xe6, 0, BIT(4)); /* Power off */ + nuvoton_pnp_exit_conf_state(ACPI_DEV); +} diff --git a/src/superio/nuvoton/nct5535d/Makefile.mk b/src/superio/nuvoton/nct5535d/Makefile.mk index bfac11a5f6d..1b48a19ec3c 100644 --- a/src/superio/nuvoton/nct5535d/Makefile.mk +++ b/src/superio/nuvoton/nct5535d/Makefile.mk @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-or-later -ramstage-$(CONFIG_SUPERIO_NUVOTON_NCT5535D) += nct5535d.c +ramstage-$(CONFIG_SUPERIO_NUVOTON_NCT5535D) += superio.c diff --git a/src/superio/nuvoton/nct5535d/acpi/superio.asl b/src/superio/nuvoton/nct5535d/acpi/superio.asl index c23c3b47bfe..332792b14be 100644 --- a/src/superio/nuvoton/nct5535d/acpi/superio.asl +++ b/src/superio/nuvoton/nct5535d/acpi/superio.asl @@ -1,175 +1,15 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Include this file into a mainboard's DSDT _SB device tree and it will - * expose the NCT5535D SuperIO and some of its functionality. - * - * It allows the change of IO ports, IRQs and DMA settings on logical - * devices, disabling and reenabling logical devices. - * - * LDN State - * 0x2 SP1 Implemented, untested - * 0x5 KBC Implemented, untested - * 0x8 GPIO Implemented, untested - * 0xb HWM Implemented, untested - * - * Controllable through preprocessor defines: - * SUPERIO_DEV Device identifier for this SIO (e.g. SIO0) - * SUPERIO_PNP_BASE I/O address of the first PnP configuration register - * NCT5535D_SHOW_SP1 If defined, Serial Port 1 will be exposed. - * NCT5535D_SHOW_KBC If defined, the Keyboard Controller will be exposed. - * NCT5535D_SHOW_GPIO If defined, GPIO support will be exposed. - * NCT5535D_SHOW_HWM If defined, the Environment Controller will be exposed. - */ -#include - -#undef SUPERIO_CHIP_NAME +#ifndef SUPERIO_CHIP_NAME #define SUPERIO_CHIP_NAME NCT5535D -#include - -#undef PNP_DEFAULT_PSC -#define PNP_DEFAULT_PSC Return (0) /* no power management */ - -#define ENABLE_KEYBOARD_WAKEUP SKWK -#define POWER_LOSS_CONTROL SPWL - -Device(SUPERIO_DEV) { - Name (_HID, EisaId("PNP0A05")) - Name (_STR, Unicode("Nuvoton NCT5535D Super I/O")) - Name (_UID, SUPERIO_UID(SUPERIO_DEV,)) - - /* SuperIO configuration ports */ - OperationRegion (CREG, SystemIO, SUPERIO_PNP_BASE, 2) - Field (CREG, ByteAcc, NoLock, Preserve) - { - PNP_ADDR_REG, 8, - PNP_DATA_REG, 8, - } - IndexField (PNP_ADDR_REG, PNP_DATA_REG, ByteAcc, NoLock, Preserve) - { - Offset (0x07), - PNP_LOGICAL_DEVICE, 8, /* Logical device selector */ - - Offset (0x30), - PNP_DEVICE_ACTIVE, 1, /* Logical device activation */ - ACT1, 1, /* Logical device activation */ - ACT2, 1, /* Logical device activation */ - ACT3, 1, /* Logical device activation */ - ACT4, 1, /* Logical device activation */ - ACT5, 1, /* Logical device activation */ - ACT6, 1, /* Logical device activation */ - ACT7, 1, /* Logical device activation */ - - Offset (0x60), - PNP_IO0_HIGH_BYTE, 8, /* First I/O port base - high byte */ - PNP_IO0_LOW_BYTE, 8, /* First I/O port base - low byte */ - Offset (0x62), - PNP_IO1_HIGH_BYTE, 8, /* Second I/O port base - high byte */ - PNP_IO1_LOW_BYTE, 8, /* Second I/O port base - low byte */ - - Offset (0x70), - PNP_IRQ0, 8, /* First IRQ */ - Offset (0x72), - PNP_IRQ1, 8, /* Second IRQ */ - Offset (0x74), - PNP_DMA0, 8, /* DRQ */ - Offset (0xe0), /* Config register 0xe0 etc. */ - ,6, - ENABLE_KEYBOARD_WAKEUP, 1, - Offset (0xe4), - ,5, - POWER_LOSS_CONTROL, 2, - } - - Method (_CRS) - { - /* Announce the used I/O ports to the OS */ - Return (ResourceTemplate () { - IO (Decode16, SUPERIO_PNP_BASE, SUPERIO_PNP_BASE, 0x01, 0x02) - }) - } - - Method (SIOS, 1, NotSerialized) - { - if (Arg0 == 5) - { - ENTER_CONFIG_MODE(NCT5535D_ACPI) - ENABLE_KEYBOARD_WAKEUP = 0 - EXIT_CONFIG_MODE() - } - } - - Method (SIOW, 1, NotSerialized) - { - } - - #undef PNP_ENTER_MAGIC_1ST - #undef PNP_ENTER_MAGIC_2ND - #undef PNP_ENTER_MAGIC_3RD - #undef PNP_ENTER_MAGIC_4TH - #undef PNP_EXIT_MAGIC_1ST - #undef PNP_EXIT_SPECIAL_REG - #undef PNP_EXIT_SPECIAL_VAL - #define PNP_ENTER_MAGIC_1ST 0x87 - #define PNP_ENTER_MAGIC_2ND 0x87 - #define PNP_EXIT_MAGIC_1ST 0xaa - #include - -#ifdef NCT5535D_SHOW_SP1 - #undef SUPERIO_UART_LDN - #undef SUPERIO_UART_DDN - #undef SUPERIO_UART_PM_REG - #undef SUPERIO_UART_PM_VAL - #undef SUPERIO_UART_PM_LDN - #define SUPERIO_UART_LDN NCT5535D_SP1 - #include #endif -#ifdef NCT5535D_SHOW_KBC - #undef SUPERIO_KBC_LDN - #undef SUPERIO_KBC_PS2M - #undef SUPERIO_KBC_PS2LDN - #define SUPERIO_KBC_LDN NCT5535D_KBC - #define SUPERIO_KBC_PS2M - #include +#ifndef SUPERIO_FULL_CHIP_NAME +#define SUPERIO_FULL_CHIP_NAME "Nuvoton NCT5535D Super I/O" #endif -#ifdef NCT5535D_SHOW_HWM - #undef SUPERIO_PNP_HID - #undef SUPERIO_PNP_LDN - #undef SUPERIO_PNP_DDN - #undef SUPERIO_PNP_NO_DIS - #undef SUPERIO_PNP_PM_REG - #undef SUPERIO_PNP_PM_VAL - #undef SUPERIO_PNP_PM_LDN - #undef SUPERIO_PNP_IO0 - #undef SUPERIO_PNP_IO1 - #undef SUPERIO_PNP_IO2 - #undef SUPERIO_PNP_IRQ0 - #undef SUPERIO_PNP_IRQ1 - #undef SUPERIO_PNP_DMA - #define SUPERIO_PNP_LDN NCT5535D_HWM_FPLED - #define SUPERIO_PNP_IO0 0x08, 0x08 - #define SUPERIO_PNP_IO1 0x08, 0x08 - #define SUPERIO_PNP_IRQ0 - #include -#endif - -#ifdef NCT5535D_SHOW_GPIO - #undef SUPERIO_PNP_HID - #undef SUPERIO_PNP_LDN - #undef SUPERIO_PNP_DDN - #undef SUPERIO_PNP_NO_DIS - #undef SUPERIO_PNP_PM_REG - #undef SUPERIO_PNP_PM_VAL - #undef SUPERIO_PNP_PM_LDN - #undef SUPERIO_PNP_IO0 - #undef SUPERIO_PNP_IO1 - #undef SUPERIO_PNP_IRQ0 - #undef PNP_DEVICE_ACTIVE - #define PNP_DEVICE_ACTIVE ACT3 - #define SUPERIO_PNP_LDN 8 - #define SUPERIO_PNP_IO0 0x08, 0x08 - #include -#endif -} +/* + * See ASL file below for details of defines to control + * device visibilities. + */ +#include diff --git a/src/superio/nuvoton/nct5535d/nct5535d.c b/src/superio/nuvoton/nct5535d/superio.c similarity index 76% rename from src/superio/nuvoton/nct5535d/nct5535d.c rename to src/superio/nuvoton/nct5535d/superio.c index 0b183a8bc1e..ef2209ce643 100644 --- a/src/superio/nuvoton/nct5535d/nct5535d.c +++ b/src/superio/nuvoton/nct5535d/superio.c @@ -2,10 +2,11 @@ #include #include +#include #include "nct5535d.h" -/* Initialization C code is provided by nct6779d */ +/* Initialization C code is provided by common code */ static struct pnp_info pnp_dev_info[] = { { NULL, NCT5535D_SP1, PNP_IO0 | PNP_IRQ0, 0x0ff8, }, @@ -18,7 +19,7 @@ static struct pnp_info pnp_dev_info[] = { static void enable_dev(struct device *dev) { - pnp_enable_devices(dev, &_nuvoton_nct6779d_ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info); + pnp_enable_devices(dev, &nuvoton_common_ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info); } struct chip_operations superio_nuvoton_nct5535d_ops = { diff --git a/src/superio/nuvoton/nct6776/acpi/superio.asl b/src/superio/nuvoton/nct6776/acpi/superio.asl index 1297aa15a07..d9d823b36db 100644 --- a/src/superio/nuvoton/nct6776/acpi/superio.asl +++ b/src/superio/nuvoton/nct6776/acpi/superio.asl @@ -1,186 +1,30 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Include this file into a mainboard's DSDT _SB device tree and it will - * expose the NCT6776 SuperIO and some of its functionality. - * - * It allows the change of IO ports, IRQs and DMA settings on logical - * devices, disabling and reenabling logical devices. - * - * LDN State - * 0x1 PP Implemented, untested - * 0x2 SP1 Implemented, untested - * 0x5 KBC Implemented, untested - * 0x8 GPIO Implemented, untested - * 0xb HWM Implemented, untested - * - * Controllable through preprocessor defines: - * SUPERIO_DEV Device identifier for this SIO (e.g. SIO0) - * SUPERIO_PNP_BASE I/O address of the first PnP configuration register - * NCT6776_SHOW_PP If defined, the parallel port will be exposed. - * NCT6776_SHOW_SP1 If defined, Serial Port 1 will be exposed. - * NCT6776_SHOW_KBC If defined, the Keyboard Controller will be exposed. - * NCT6776_SHOW_GPIO If defined, GPIO support will be exposed. - * NCT6776_SHOW_HWM If defined, the Environment Controller will be exposed. - */ - -#undef SUPERIO_CHIP_NAME +#ifndef SUPERIO_CHIP_NAME #define SUPERIO_CHIP_NAME NCT6776 -#include - -#undef PNP_DEFAULT_PSC -#define PNP_DEFAULT_PSC Return (0) /* no power management */ - -Device(SUPERIO_DEV) { - Name (_HID, EisaId("PNP0A05")) - Name (_STR, Unicode("Nuvoton NCT6776 Super I/O")) - Name (_UID, SUPERIO_UID(SUPERIO_DEV,)) - - /* SuperIO configuration ports */ - OperationRegion (CREG, SystemIO, SUPERIO_PNP_BASE, 0x02) - Field (CREG, ByteAcc, NoLock, Preserve) - { - PNP_ADDR_REG, 8, - PNP_DATA_REG, 8, - } - IndexField (PNP_ADDR_REG, PNP_DATA_REG, ByteAcc, NoLock, Preserve) - { - Offset (0x07), - PNP_LOGICAL_DEVICE, 8, /* Logical device selector */ - - Offset (0x30), - PNP_DEVICE_ACTIVE, 1, /* Logical device activation */ - ACT1, 1, /* Logical device activation */ - ACT2, 1, /* Logical device activation */ - ACT3, 1, /* Logical device activation */ - ACT4, 1, /* Logical device activation */ - ACT5, 1, /* Logical device activation */ - ACT6, 1, /* Logical device activation */ - ACT7, 1, /* Logical device activation */ - - Offset (0x60), - PNP_IO0_HIGH_BYTE, 8, /* First I/O port base - high byte */ - PNP_IO0_LOW_BYTE, 8, /* First I/O port base - low byte */ - Offset (0x62), - PNP_IO1_HIGH_BYTE, 8, /* Second I/O port base - high byte */ - PNP_IO1_LOW_BYTE, 8, /* Second I/O port base - low byte */ - Offset (0x64), - PNP_IO2_HIGH_BYTE, 8, /* Third I/O port base - high byte */ - PNP_IO2_LOW_BYTE, 8, /* Third I/O port base - low byte */ - - Offset (0x70), - PNP_IRQ0, 8, /* First IRQ */ - Offset (0x72), - PNP_IRQ1, 8, /* Second IRQ */ - Offset (0x74), - PNP_DMA0, 8, /* DRQ */ - } - - Method (_CRS) - { - /* Announce the used I/O ports to the OS */ - Return (ResourceTemplate () { - IO (Decode16, SUPERIO_PNP_BASE, SUPERIO_PNP_BASE, 0x01, 0x02) - }) - } +#endif - #undef PNP_ENTER_MAGIC_1ST - #undef PNP_ENTER_MAGIC_2ND - #undef PNP_ENTER_MAGIC_3RD - #undef PNP_ENTER_MAGIC_4TH - #undef PNP_EXIT_MAGIC_1ST - #undef PNP_EXIT_SPECIAL_REG - #undef PNP_EXIT_SPECIAL_VAL - #define PNP_ENTER_MAGIC_1ST 0x87 - #define PNP_ENTER_MAGIC_2ND 0x87 - #define PNP_EXIT_MAGIC_1ST 0xaa - #include +#ifndef SUPERIO_FULL_CHIP_NAME +#define SUPERIO_FULL_CHIP_NAME "Nuvoton NCT6776 Super I/O" +#endif #ifdef NCT6776_SHOW_PP - #undef SUPERIO_PNP_HID - #undef SUPERIO_PNP_LDN - #undef SUPERIO_PNP_DDN - #undef SUPERIO_PNP_NO_DIS - #undef SUPERIO_PNP_PM_REG - #undef SUPERIO_PNP_PM_VAL - #undef SUPERIO_PNP_PM_LDN - #undef SUPERIO_PNP_IO0 - #undef SUPERIO_PNP_IO1 - #undef SUPERIO_PNP_IO2 - #undef SUPERIO_PNP_IRQ0 - #undef SUPERIO_PNP_IRQ1 - #undef SUPERIO_PNP_DMA - /* - * The extra code required to dynamically reflect ECP in the HID - * isn't currently justified, so the HID is hardcoded as not - * using ECP. "PNP0401" would indicate ECP. - */ - #define SUPERIO_PNP_HID "PNP0400" - #define SUPERIO_PNP_LDN 1 - #define SUPERIO_PNP_IO0 0x08, 0x08 - #define SUPERIO_PNP_IRQ0 - #define SUPERIO_PNP_DMA - #include +#define NCT677X_SHOW_PP #endif - #ifdef NCT6776_SHOW_SP1 - #undef SUPERIO_UART_LDN - #undef SUPERIO_UART_DDN - #undef SUPERIO_UART_PM_REG - #undef SUPERIO_UART_PM_VAL - #undef SUPERIO_UART_PM_LDN - #define SUPERIO_UART_LDN 2 - #include +#define NCT677X_SHOW_SP1 +#endif +#ifdef NCT6776_SHOW_SP2 +#define NCT677X_SHOW_SP2 #endif - #ifdef NCT6776_SHOW_KBC - #undef SUPERIO_KBC_LDN - #undef SUPERIO_KBC_PS2M - #undef SUPERIO_KBC_PS2LDN - #define SUPERIO_KBC_LDN 5 - #define SUPERIO_KBC_PS2M - #include +#define NCT677X_SHOW_KBC #endif - #ifdef NCT6776_SHOW_HWM - #undef SUPERIO_PNP_HID - #undef SUPERIO_PNP_LDN - #undef SUPERIO_PNP_DDN - #undef SUPERIO_PNP_NO_DIS - #undef SUPERIO_PNP_PM_REG - #undef SUPERIO_PNP_PM_VAL - #undef SUPERIO_PNP_PM_LDN - #undef SUPERIO_PNP_IO0 - #undef SUPERIO_PNP_IO1 - #undef SUPERIO_PNP_IO2 - #undef SUPERIO_PNP_IRQ0 - #undef SUPERIO_PNP_IRQ1 - #undef SUPERIO_PNP_DMA - #define SUPERIO_PNP_LDN 11 - #define SUPERIO_PNP_IO0 0x08, 0x08 - #define SUPERIO_PNP_IO1 0x08, 0x08 - #define SUPERIO_PNP_IRQ0 - #include +#define NCT677X_SHOW_HWM #endif - #ifdef NCT6776_SHOW_GPIO - #undef SUPERIO_PNP_HID - #undef SUPERIO_PNP_LDN - #undef SUPERIO_PNP_DDN - #undef SUPERIO_PNP_NO_DIS - #undef SUPERIO_PNP_PM_REG - #undef SUPERIO_PNP_PM_VAL - #undef SUPERIO_PNP_PM_LDN - #undef SUPERIO_PNP_IO0 - #undef SUPERIO_PNP_IO1 - #undef SUPERIO_PNP_IO2 - #undef SUPERIO_PNP_IRQ0 - #undef SUPERIO_PNP_IRQ1 - #undef SUPERIO_PNP_DMA - #undef PNP_DEVICE_ACTIVE - #define PNP_DEVICE_ACTIVE ACT3 - #define SUPERIO_PNP_LDN 8 - #define SUPERIO_PNP_IO0 0x08, 0x08 - #include +#define NCT677X_SHOW_GPIO #endif -} + +#include diff --git a/src/superio/nuvoton/nct6776/superio.c b/src/superio/nuvoton/nct6776/superio.c index d98e303b96d..2cce5975085 100644 --- a/src/superio/nuvoton/nct6776/superio.c +++ b/src/superio/nuvoton/nct6776/superio.c @@ -2,35 +2,12 @@ #include #include -#include -#include +#include #include "nct6776.h" /* Both NCT6776D and NCT6776F package variants are supported. */ -static void nct6776_init(struct device *dev) -{ - if (!dev->enabled) - return; - - switch (dev->path.pnp.device) { - /* TODO: Might potentially need code for HWM or FDC etc. */ - case NCT6776_KBC: - pc_keyboard_init(NO_AUX_DEVICE); - break; - } -} - -static struct device_operations ops = { - .read_resources = pnp_read_resources, - .set_resources = pnp_set_resources, - .enable_resources = pnp_enable_resources, - .enable = pnp_alt_enable, - .init = nct6776_init, - .ops_pnp_mode = &pnp_conf_mode_8787_aa, -}; - static struct pnp_info pnp_dev_info[] = { { NULL, NCT6776_FDC, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, 0x0ff8 }, { NULL, NCT6776_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, 0x0ff8 }, @@ -63,7 +40,7 @@ static struct pnp_info pnp_dev_info[] = { static void enable_dev(struct device *dev) { - pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info); + pnp_enable_devices(dev, &nuvoton_common_ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info); } struct chip_operations superio_nuvoton_nct6776_ops = { diff --git a/src/superio/nuvoton/nct6779d/Makefile.mk b/src/superio/nuvoton/nct6779d/Makefile.mk index 327081f7f92..d5476e46259 100644 --- a/src/superio/nuvoton/nct6779d/Makefile.mk +++ b/src/superio/nuvoton/nct6779d/Makefile.mk @@ -1,4 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-or-later -ramstage-$(CONFIG_SUPERIO_NUVOTON_NCT6779D) += superio.c nct6779d.c -ramstage-$(CONFIG_SUPERIO_NUVOTON_NCT5535D) += superio.c +ramstage-$(CONFIG_SUPERIO_NUVOTON_NCT6779D) += superio.c diff --git a/src/superio/nuvoton/nct6779d/acpi/superio.asl b/src/superio/nuvoton/nct6779d/acpi/superio.asl new file mode 100644 index 00000000000..181f1985648 --- /dev/null +++ b/src/superio/nuvoton/nct6779d/acpi/superio.asl @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SUPERIO_CHIP_NAME +#define SUPERIO_CHIP_NAME NCT6779D +#endif + +#ifndef SUPERIO_FULL_CHIP_NAME +#define SUPERIO_FULL_CHIP_NAME "Nuvoton NCT6779D Super I/O" +#endif + +/* + * See ASL file below for details of defines to control + * device visibilities. + */ +#include diff --git a/src/superio/nuvoton/nct6779d/nct6779d.c b/src/superio/nuvoton/nct6779d/nct6779d.c deleted file mode 100644 index 940f6007756..00000000000 --- a/src/superio/nuvoton/nct6779d/nct6779d.c +++ /dev/null @@ -1,42 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include -#include "nct6779d.h" - -static struct pnp_info pnp_dev_info[] = { - { NULL, NCT6779D_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, 0x0ff8, }, - { NULL, NCT6779D_SP1, PNP_IO0 | PNP_IRQ0, 0x0ff8, }, - { NULL, NCT6779D_SP2, PNP_IO0 | PNP_IRQ0, 0x0ff8, }, - { NULL, NCT6779D_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1, - 0x0fff, 0x0fff, }, - { NULL, NCT6779D_CIR, PNP_IO0 | PNP_IRQ0, 0x0ff8, }, - { NULL, NCT6779D_ACPI, PNP_MSC2,}, - { NULL, NCT6779D_HWM_FPLED, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_MSC0, - 0x0ffe, 0x0ffe, }, - { NULL, NCT6779D_WDT1}, - { NULL, NCT6779D_CIRWKUP, PNP_IO0 | PNP_IRQ0, 0x0ff8, }, - { NULL, NCT6779D_GPIO_PP_OD}, - { NULL, NCT6779D_PRT80}, - { NULL, NCT6779D_DSLP}, - { NULL, NCT6779D_GPIOBASE, PNP_IO0, 0x0ff8, }, - { NULL, NCT6779D_GPIO0}, - { NULL, NCT6779D_GPIO1}, - { NULL, NCT6779D_GPIO2}, - { NULL, NCT6779D_GPIO3}, - { NULL, NCT6779D_GPIO4}, - { NULL, NCT6779D_GPIO5, PNP_MSC4 | PNP_MSC5}, - { NULL, NCT6779D_GPIO6, PNP_MSC4 | PNP_MSC5}, - { NULL, NCT6779D_GPIO7}, - { NULL, NCT6779D_GPIO8}, -}; - -static void enable_dev(struct device *dev) -{ - pnp_enable_devices(dev, &_nuvoton_nct6779d_ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info); -} - -struct chip_operations superio_nuvoton_nct6779d_ops = { - .name = "NUVOTON NCT6779D Super I/O", - .enable_dev = enable_dev, -}; diff --git a/src/superio/nuvoton/nct6779d/nct6779d.h b/src/superio/nuvoton/nct6779d/nct6779d.h index 133450a083f..63b7b0e9143 100644 --- a/src/superio/nuvoton/nct6779d/nct6779d.h +++ b/src/superio/nuvoton/nct6779d/nct6779d.h @@ -3,8 +3,6 @@ #ifndef SUPERIO_NUVOTON_NCT6779D_H #define SUPERIO_NUVOTON_NCT6779D_H -#include - /* Logical Device Numbers (LDN). */ #define NCT6779D_PP 0x01 /* Parallel port */ #define NCT6779D_SP1 0x02 /* Com1 */ @@ -36,6 +34,4 @@ #define NCT6779D_GPIO7 ((7 << 8) | NCT6779D_GPIO12345678_V) #define NCT6779D_GPIO8 ((0 << 8) | NCT6779D_GPIO12345678_V) -extern struct device_operations _nuvoton_nct6779d_ops; - #endif /* SUPERIO_NUVOTON_NCT6779D_H */ diff --git a/src/superio/nuvoton/nct6779d/superio.c b/src/superio/nuvoton/nct6779d/superio.c index 262170770ca..785c30059ce 100644 --- a/src/superio/nuvoton/nct6779d/superio.c +++ b/src/superio/nuvoton/nct6779d/superio.c @@ -2,53 +2,43 @@ #include #include -#include -#include -#include +#include #include "nct6779d.h" -/* C code shared by NCT6779D and NCT5535D */ - -#define MAINBOARD_POWER_OFF 0 -#define MAINBOARD_POWER_ON 1 -#define MAINBOARD_POWER_KEEP 2 +static struct pnp_info pnp_dev_info[] = { + { NULL, NCT6779D_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, 0x0ff8, }, + { NULL, NCT6779D_SP1, PNP_IO0 | PNP_IRQ0, 0x0ff8, }, + { NULL, NCT6779D_SP2, PNP_IO0 | PNP_IRQ0, 0x0ff8, }, + { NULL, NCT6779D_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1, + 0x0fff, 0x0fff, }, + { NULL, NCT6779D_CIR, PNP_IO0 | PNP_IRQ0, 0x0ff8, }, + { NULL, NCT6779D_ACPI, PNP_MSC2,}, + { NULL, NCT6779D_HWM_FPLED, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_MSC0, + 0x0ffe, 0x0ffe, }, + { NULL, NCT6779D_WDT1}, + { NULL, NCT6779D_CIRWKUP, PNP_IO0 | PNP_IRQ0, 0x0ff8, }, + { NULL, NCT6779D_GPIO_PP_OD}, + { NULL, NCT6779D_PRT80}, + { NULL, NCT6779D_DSLP}, + { NULL, NCT6779D_GPIOBASE, PNP_IO0, 0x0ff8, }, + { NULL, NCT6779D_GPIO0}, + { NULL, NCT6779D_GPIO1}, + { NULL, NCT6779D_GPIO2}, + { NULL, NCT6779D_GPIO3}, + { NULL, NCT6779D_GPIO4}, + { NULL, NCT6779D_GPIO5, PNP_MSC4 | PNP_MSC5}, + { NULL, NCT6779D_GPIO6, PNP_MSC4 | PNP_MSC5}, + { NULL, NCT6779D_GPIO7}, + { NULL, NCT6779D_GPIO8}, +}; -static void nct6779d_init(struct device *dev) +static void enable_dev(struct device *dev) { - uint8_t byte, power_status; - - if (!dev->enabled) - return; - - switch (dev->path.pnp.device) { - /* TODO: Might potentially need code for HWM or FDC etc. */ - case NCT6779D_KBC: - pc_keyboard_init(NO_AUX_DEVICE); - break; - case NCT6779D_ACPI: - /* Set power state after power fail */ - power_status = get_uint_option("power_on_after_fail", - CONFIG_MAINBOARD_POWER_FAILURE_STATE); - pnp_enter_conf_mode(dev); - pnp_set_logical_device(dev); - byte = pnp_read_config(dev, 0xe4) & ~0x60; - if (power_status == MAINBOARD_POWER_ON) - byte |= (MAINBOARD_POWER_ON << 5); - else if (power_status == MAINBOARD_POWER_KEEP) - byte |= (MAINBOARD_POWER_KEEP << 5); - pnp_write_config(dev, 0xe4, byte); - pnp_exit_conf_mode(dev); - printk(BIOS_INFO, "set power %s after power fail\n", power_status ? "on" : "off"); - break; - } + pnp_enable_devices(dev, &nuvoton_common_ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info); } -struct device_operations _nuvoton_nct6779d_ops = { - .read_resources = pnp_read_resources, - .set_resources = pnp_set_resources, - .enable_resources = pnp_enable_resources, - .enable = pnp_alt_enable, - .init = nct6779d_init, - .ops_pnp_mode = &pnp_conf_mode_8787_aa, +struct chip_operations superio_nuvoton_nct6779d_ops = { + .name = "NUVOTON NCT6779D Super I/O", + .enable_dev = enable_dev, }; diff --git a/src/superio/nuvoton/nct6791d/acpi/superio.asl b/src/superio/nuvoton/nct6791d/acpi/superio.asl new file mode 100644 index 00000000000..d9fcb50f44d --- /dev/null +++ b/src/superio/nuvoton/nct6791d/acpi/superio.asl @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SUPERIO_CHIP_NAME +#define SUPERIO_CHIP_NAME NCT6791D +#endif + +#ifndef SUPERIO_FULL_CHIP_NAME +#define SUPERIO_FULL_CHIP_NAME "Nuvoton NCT6791D Super I/O" +#endif + +/* + * See ASL file below for details of defines to control + * device visibilities. + */ +#include diff --git a/src/superio/nuvoton/nct6791d/superio.c b/src/superio/nuvoton/nct6791d/superio.c index 91a39084a99..343dd13475a 100644 --- a/src/superio/nuvoton/nct6791d/superio.c +++ b/src/superio/nuvoton/nct6791d/superio.c @@ -30,7 +30,8 @@ static const char *nct6791d_acpi_hid(const struct device *dev) return NULL; switch (dev->path.pnp.device & 0xff) { - case NCT6791D_SP1: /* fallthrough */ + case NCT6791D_SP1: + __fallthrough; case NCT6791D_SP2: return ACPI_HID_COM; case NCT6791D_KBC: diff --git a/src/superio/nuvoton/nct6796d/Kconfig b/src/superio/nuvoton/nct6796d/Kconfig new file mode 100644 index 00000000000..49689e27098 --- /dev/null +++ b/src/superio/nuvoton/nct6796d/Kconfig @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config SUPERIO_NUVOTON_NCT6796D + bool + select SUPERIO_NUVOTON_COMMON_PRE_RAM diff --git a/src/superio/nuvoton/nct6796d/Makefile.mk b/src/superio/nuvoton/nct6796d/Makefile.mk new file mode 100644 index 00000000000..9700af5de56 --- /dev/null +++ b/src/superio/nuvoton/nct6796d/Makefile.mk @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +ramstage-$(CONFIG_SUPERIO_NUVOTON_NCT6796D) += superio.c +ramstage-$(CONFIG_SUPERIO_NUVOTON_NCT6796D) += ../../common/ssdt.c +ramstage-$(CONFIG_SUPERIO_NUVOTON_NCT6796D) += ../../common/generic.c diff --git a/src/superio/nuvoton/nct6796d/nct6796d.h b/src/superio/nuvoton/nct6796d/nct6796d.h new file mode 100644 index 00000000000..5468acbab14 --- /dev/null +++ b/src/superio/nuvoton/nct6796d/nct6796d.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef SUPERIO_NUVOTON_NCT6796D_H +#define SUPERIO_NUVOTON_NCT6796D_H + +/* Logical Device Numbers (LDN). */ +#define NCT6796D_PP 0x01 /* Parallel port */ +#define NCT6796D_SP1 0x02 /* UART A */ +#define NCT6796D_SP2 0x03 /* UART B, IR */ +#define NCT6796D_KBC 0x05 /* Keyboard Controller */ +#define NCT6796D_CIR 0x06 /* Consumer IR */ +#define NCT6796D_GPIO678 0x07 /* GPIO 6, 7 & 8 */ +#define NCT6796D_WDT1_WDTMEM_GPIO01 0x08 /* WDT1, WDT_MEM, GPIO 0 & 1 */ +#define NCT6796D_GPIO2345 0x09 /* GPIO 2, 3, 4 & 5 */ +#define NCT6796D_ACPI 0x0A /* ACPI */ +#define NCT6796D_HWM_FPLED 0x0B /* HW Monitor, Front Panel LED */ +#define NCT6796D_BCLK_WDT2_WDTMEM 0x0D /* BCLK, WDT2, WDT_MEM */ +#define NCT6796D_CIRWUP 0x0E /* CIR Wake-Up */ +#define NCT6796D_GPIO_PP_OD 0x0F /* GPIO Push-Pull/Open-Drain */ +#define NCT6796D_PGPIO_RI_PSOUT 0x11 /* PGPIO, RI PSOUT Wake-Up */ +#define NCT6796D_LED 0x12 /* LED control */ +#define NCT6796D_PORT80 0x14 /* Port 80 UART */ +#define NCT6796D_LED2 0x15 /* LED Control 2 */ +#define NCT6796D_DS 0x16 /* Deep Sleep */ + +/* Virtual LDNs */ +#define NCT6796D_WDT1 ((0 << 8) | NCT6796D_WDT1_WDTMEM_GPIO01) +#define NCT6796D_WDTMEM ((4 << 8) | NCT6796D_WDT1_WDTMEM_GPIO01) +#define NCT6796D_GPIOBASE ((3 << 8) | NCT6796D_WDT1_WDTMEM_GPIO01) +#define NCT6796D_GPIO0 ((1 << 8) | NCT6796D_WDT1_WDTMEM_GPIO01) +#define NCT6796D_GPIO1 ((7 << 8) | NCT6796D_WDT1_WDTMEM_GPIO01) +#define NCT6796D_GPIO2 ((0 << 8) | NCT6796D_GPIO2345) +#define NCT6796D_GPIO3 ((1 << 8) | NCT6796D_GPIO2345) +#define NCT6796D_GPIO4 ((2 << 8) | NCT6796D_GPIO2345) +#define NCT6796D_GPIO5 ((3 << 8) | NCT6796D_GPIO2345) +#define NCT6796D_GPIO6 ((0 << 8) | NCT6796D_GPIO678) +#define NCT6796D_GPIO7 ((1 << 8) | NCT6796D_GPIO678) +#define NCT6796D_GPIO8 ((2 << 8) | NCT6796D_GPIO678) +#define NCT6796D_DS5 ((0 << 8) | NCT6796D_DS) +#define NCT6796D_DS3 ((1 << 8) | NCT6796D_DS) +#define NCT6796D_PCHDSW ((3 << 8) | NCT6796D_DS) +#define NCT6796D_DSWWOPT ((4 << 8) | NCT6796D_DS) +#define NCT6796D_DS3OPT ((5 << 8) | NCT6796D_DS) +#define NCT6796D_DSDSS ((6 << 8) | NCT6796D_DS) +#define NCT6796D_DSPU ((7 << 8) | NCT6796D_DS) + +#endif /* SUPERIO_NUVOTON_NCT6796D_H */ diff --git a/src/superio/nuvoton/nct6796d/superio.c b/src/superio/nuvoton/nct6796d/superio.c new file mode 100644 index 00000000000..79dc685eeff --- /dev/null +++ b/src/superio/nuvoton/nct6796d/superio.c @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include +#include "nct6796d.h" + +static void nct6796d_init(struct device *dev) +{ + if (!dev->enabled) + return; + + switch (dev->path.pnp.device) { + case NCT6796D_KBC: + pc_keyboard_init(NO_AUX_DEVICE); + break; + } +} + +#if CONFIG(HAVE_ACPI_TABLES) +/* Provide ACPI HIDs for generic Super I/O SSDT */ +static const char *nct6796d_acpi_hid(const struct device *dev) +{ + if ((dev->path.type != DEVICE_PATH_PNP) || + (dev->path.pnp.port == 0) || + ((dev->path.pnp.device & 0xff) > NCT6796D_DS)) + return NULL; + + switch (dev->path.pnp.device & 0xff) { + case NCT6796D_SP1: + __fallthrough; + case NCT6796D_SP2: + return ACPI_HID_COM; + case NCT6796D_KBC: + return ACPI_HID_KEYBOARD; + default: + return ACPI_HID_PNP; + } +} +#endif + +static struct device_operations ops = { + .read_resources = pnp_read_resources, + .set_resources = pnp_set_resources, + .enable_resources = pnp_enable_resources, + .enable = pnp_alt_enable, + .init = nct6796d_init, + .ops_pnp_mode = &pnp_conf_mode_8787_aa, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_fill_ssdt = superio_common_fill_ssdt_generator, + .acpi_name = superio_common_ldn_acpi_name, + .acpi_hid = nct6796d_acpi_hid, +#endif +}; + +static struct pnp_info pnp_dev_info[] = { + { NULL, NCT6796D_PP, PNP_IO0 | PNP_IRQ0 | PNP_DRQ0, + 0x0ff8, }, + { NULL, NCT6796D_SP1, PNP_IO0 | PNP_IRQ0, + 0x0ff8, }, + { NULL, NCT6796D_SP2, PNP_IO0 | PNP_IRQ0, + 0x0ff8, }, + { NULL, NCT6796D_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1, + 0x0fff, 0x0fff, }, + { NULL, NCT6796D_CIR, PNP_IO0 | PNP_IRQ0, + 0x0ff8, }, + { NULL, NCT6796D_ACPI}, + { NULL, NCT6796D_HWM_FPLED, PNP_IO0 | PNP_IO1 | PNP_IRQ0, + 0x0ffe, 0x0ffe, }, + { NULL, NCT6796D_BCLK_WDT2_WDTMEM}, + { NULL, NCT6796D_CIRWUP, PNP_IO0 | PNP_IRQ0, + 0x0ff8, }, + { NULL, NCT6796D_GPIO_PP_OD}, + { NULL, NCT6796D_PGPIO_RI_PSOUT}, + { NULL, NCT6796D_LED}, + { NULL, NCT6796D_PORT80}, + { NULL, NCT6796D_LED2}, + { NULL, NCT6796D_WDT1}, + { NULL, NCT6796D_WDTMEM}, + { NULL, NCT6796D_GPIOBASE, PNP_IO0, + 0x0ff8, }, + { NULL, NCT6796D_GPIO0}, + { NULL, NCT6796D_GPIO1}, + { NULL, NCT6796D_GPIO2}, + { NULL, NCT6796D_GPIO3}, + { NULL, NCT6796D_GPIO4}, + { NULL, NCT6796D_GPIO5}, + { NULL, NCT6796D_GPIO6}, + { NULL, NCT6796D_GPIO7}, + { NULL, NCT6796D_GPIO8}, + { NULL, NCT6796D_DS5}, + { NULL, NCT6796D_DS3}, + { NULL, NCT6796D_PCHDSW}, + { NULL, NCT6796D_DSWWOPT}, + { NULL, NCT6796D_DS3OPT}, + { NULL, NCT6796D_DSDSS}, + { NULL, NCT6796D_DSPU}, +}; + +static void enable_dev(struct device *dev) +{ + pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info); +} + +struct chip_operations superio_nuvoton_nct6796d_ops = { + .name = "NUVOTON NCT6796D Super I/O", + .enable_dev = enable_dev, +}; diff --git a/src/vendorcode/amd/fsp/cezanne/soc_dmi_info.h b/src/vendorcode/amd/fsp/cezanne/soc_dmi_info.h index 47500defa36..cc18977cf57 100644 --- a/src/vendorcode/amd/fsp/cezanne/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/cezanne/soc_dmi_info.h @@ -10,6 +10,8 @@ #define AGESA_STRUCT_SOCKET_COUNT 2 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 8 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 4 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_T19_REGION_SUPPORTED 3 ///< Max SMBIOS T19 Memory Region count +#define AGESA_STRUCT_T20_REGION_SUPPORTED 1 ///< Max SMBIOS T20 Memory Region count #define AGESA_STRUCT_PART_NUMBER_SIZE 21 #define SMBIOS_3_2_SUPPORT 1 diff --git a/src/vendorcode/amd/fsp/common/dmi_info.h b/src/vendorcode/amd/fsp/common/dmi_info.h index e38a44ed94a..8879b4b3a16 100644 --- a/src/vendorcode/amd/fsp/common/dmi_info.h +++ b/src/vendorcode/amd/fsp/common/dmi_info.h @@ -185,8 +185,60 @@ typedef struct { #endif } __packed TYPE17_DMI_INFO; +/// DMI Type 19 - Memory Array Mapped Address +typedef struct { + OUT UINT32 StartingAddr; ///< The physical address, in kilobytes, + ///< of a range of memory mapped to the + ///< specified physical memory array. + OUT UINT32 EndingAddr; ///< The physical ending address of the + ///< last kilobyte of a range of addresses + ///< mapped to the specified physical memory array. + OUT UINT16 MemoryArrayHandle; ///< The handle, or instance number, associated + ///< with the physical memory array to which this + ///< address range is mapped. + OUT UINT8 PartitionWidth; ///< Identifies the number of memory devices that + ///< form a single row of memory for the address + ///< partition defined by this structure. + OUT UINT64 ExtStartingAddr; ///< The physical address, in bytes, of a range of + ///< memory mapped to the specified Physical Memory Array. + OUT UINT64 ExtEndingAddr; ///< The physical address, in bytes, of a range of + ///< memory mapped to the specified Physical Memory Array. +} __packed TYPE19_DMI_INFO; + +///DMI Type 20 - Memory Device Mapped Address +typedef struct { + OUT UINT32 StartingAddr; ///< The physical address, in kilobytes, of a range + ///< of memory mapped to the referenced Memory Device. + OUT UINT32 EndingAddr; ///< The handle, or instance number, associated with + ///< the Memory Device structure to which this address + ///< range is mapped. + OUT UINT16 MemoryDeviceHandle; ///< The handle, or instance number, associated with + ///< the Memory Device structure to which this address + ///< range is mapped. + OUT UINT16 MemoryArrayMappedAddressHandle; ///< The handle, or instance number, associated + ///< with the Memory Array Mapped Address structure to + ///< which this device address range is mapped. + OUT UINT8 PartitionRowPosition; ///< Identifies the position of the referenced Memory + ///< Device in a row of the address partition. + OUT UINT8 InterleavePosition; ///< The position of the referenced Memory Device in + ///< an interleave. + OUT UINT8 InterleavedDataDepth; ///< The maximum number of consecutive rows from the + ///< referenced Memory Device that are accessed in a + ///< single interleaved transfer. + OUT UINT64 ExtStartingAddr; ///< The physical address, in bytes, of a range of + ///< memory mapped to the referenced Memory Device. + OUT UINT64 ExtEndingAddr; ///< The physical ending address, in bytes, of the last of + ///< a range of addresses mapped to the referenced Memory Device. +} __packed TYPE20_DMI_INFO; + /// Collection of pointers to the DMI records typedef struct { OUT TYPE16_DMI_INFO T16; ///< Type 16 struc OUT TYPE17_DMI_INFO T17[AGESA_STRUCT_SOCKET_COUNT][AGESA_STRUCT_CHANNELS_PER_SOCKET][AGESA_STRUCT_DIMMS_PER_CHANNEL]; ///< Type 17 struc +#ifdef AGESA_STRUCT_T19_REGION_SUPPORTED + OUT TYPE19_DMI_INFO T19[AGESA_STRUCT_T19_REGION_SUPPORTED]; +#endif +#ifdef AGESA_STRUCT_T20_REGION_SUPPORTED + OUT TYPE20_DMI_INFO T20[AGESA_STRUCT_SOCKET_COUNT][AGESA_STRUCT_CHANNELS_PER_SOCKET][AGESA_STRUCT_DIMMS_PER_CHANNEL][AGESA_STRUCT_T20_REGION_SUPPORTED]; ///< Type 20 struc +#endif } DMI_INFO; diff --git a/src/vendorcode/amd/fsp/glinda/soc_dmi_info.h b/src/vendorcode/amd/fsp/glinda/soc_dmi_info.h index 15c7b63a718..85381fd6911 100644 --- a/src/vendorcode/amd/fsp/glinda/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/glinda/soc_dmi_info.h @@ -2,7 +2,6 @@ /* * These definitions are used to describe memory modules physical layout - * TODO: Update for Glinda */ #ifndef SOC_DMI_INFO_H @@ -11,6 +10,8 @@ #define AGESA_STRUCT_SOCKET_COUNT 4 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 16 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 2 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_T19_REGION_SUPPORTED 3 ///< Max SMBIOS T19 Memory Region count +#define AGESA_STRUCT_T20_REGION_SUPPORTED 3 ///< Max SMBIOS T20 Memory Region count #define AGESA_STRUCT_PART_NUMBER_SIZE 31 #define SMBIOS_3_2_SUPPORT 1 diff --git a/src/vendorcode/amd/fsp/mendocino/soc_dmi_info.h b/src/vendorcode/amd/fsp/mendocino/soc_dmi_info.h index bf35aea3e52..4c3776e4586 100644 --- a/src/vendorcode/amd/fsp/mendocino/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/mendocino/soc_dmi_info.h @@ -10,6 +10,8 @@ #define AGESA_STRUCT_SOCKET_COUNT 4 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 12 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 2 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_T19_REGION_SUPPORTED 3 ///< Max SMBIOS T19 Memory Region count +#define AGESA_STRUCT_T20_REGION_SUPPORTED 1 ///< Max SMBIOS T20 Memory Region count #define AGESA_STRUCT_PART_NUMBER_SIZE 21 #define SMBIOS_3_2_SUPPORT 1 diff --git a/src/vendorcode/amd/fsp/phoenix/soc_dmi_info.h b/src/vendorcode/amd/fsp/phoenix/soc_dmi_info.h index bf35aea3e52..4c3776e4586 100644 --- a/src/vendorcode/amd/fsp/phoenix/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/phoenix/soc_dmi_info.h @@ -10,6 +10,8 @@ #define AGESA_STRUCT_SOCKET_COUNT 4 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 12 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 2 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_T19_REGION_SUPPORTED 3 ///< Max SMBIOS T19 Memory Region count +#define AGESA_STRUCT_T20_REGION_SUPPORTED 1 ///< Max SMBIOS T20 Memory Region count #define AGESA_STRUCT_PART_NUMBER_SIZE 21 #define SMBIOS_3_2_SUPPORT 1 diff --git a/src/vendorcode/amd/fsp/picasso/soc_dmi_info.h b/src/vendorcode/amd/fsp/picasso/soc_dmi_info.h index 94a43f55b06..c9063ac6407 100644 --- a/src/vendorcode/amd/fsp/picasso/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/picasso/soc_dmi_info.h @@ -10,6 +10,8 @@ #define AGESA_STRUCT_SOCKET_COUNT 1 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 4 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 4 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_T19_REGION_SUPPORTED 3 ///< Max SMBIOS T19 Memory Region count +#define AGESA_STRUCT_T20_REGION_SUPPORTED 1 ///< Max SMBIOS T20 Memory Region count #define AGESA_STRUCT_PART_NUMBER_SIZE 21 #endif /* SOC_DMI_INFO_H */ diff --git a/src/vendorcode/amd/fsp/renoir/soc_dmi_info.h b/src/vendorcode/amd/fsp/renoir/soc_dmi_info.h index 762320cdc3b..701c91f166f 100644 --- a/src/vendorcode/amd/fsp/renoir/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/renoir/soc_dmi_info.h @@ -10,6 +10,8 @@ #define AGESA_STRUCT_SOCKET_COUNT 2 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 8 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 4 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_T19_REGION_SUPPORTED 3 ///< Max SMBIOS T19 Memory Region count +#define AGESA_STRUCT_T20_REGION_SUPPORTED 1 ///< Max SMBIOS T20 Memory Region count #define AGESA_STRUCT_PART_NUMBER_SIZE 21 //TODO check #define SMBIOS_3_2_SUPPORT 1 diff --git a/src/vendorcode/amd/opensil/Kconfig b/src/vendorcode/amd/opensil/Kconfig index 11308a7f737..735d6e1febc 100644 --- a/src/vendorcode/amd/opensil/Kconfig +++ b/src/vendorcode/amd/opensil/Kconfig @@ -15,10 +15,17 @@ config SOC_AMD_OPENSIL_GENOA_POC Select this on SoCs that use the Genoa proof of concept version of openSIL. +config SOC_AMD_OPENSIL_TURIN_POC + bool + help + Select this on SoCs that use the Turin proof of concept version of + openSIL. + config AMD_OPENSIL_PATH string "Path to openSIL source" depends on !SOC_AMD_OPENSIL_STUB default "$(top)/src/vendorcode/amd/opensil/genoa_poc/opensil" if SOC_AMD_OPENSIL_GENOA_POC + default "$(top)/src/vendorcode/amd/opensil/turin_poc/opensil" if SOC_AMD_OPENSIL_TURIN_POC help Set to the path of the openSIL directory containing meson.build. example @@ -26,6 +33,7 @@ config AMD_OPENSIL_PATH config AMD_OPENSIL_MPIO_CHIP_H_FILE string "Location of specific MPIO chip.h implementation" default "$(top)/src/vendorcode/amd/opensil/genoa_poc/mpio/chip.h" if SOC_AMD_OPENSIL_GENOA_POC + default "$(top)/src/vendorcode/amd/opensil/turin_poc/mpio/chip.h" if SOC_AMD_OPENSIL_TURIN_POC default "$(top)/src/vendorcode/amd/opensil/stub/mpio/chip.h" help Set to the location of the MPIO chip.h in the selected openSIL diff --git a/src/vendorcode/amd/opensil/Kconfig.debug b/src/vendorcode/amd/opensil/Kconfig.debug index 859122b2a8f..14b57662c6f 100644 --- a/src/vendorcode/amd/opensil/Kconfig.debug +++ b/src/vendorcode/amd/opensil/Kconfig.debug @@ -66,6 +66,36 @@ config OPENSIL_DEBUG_RAS help Enable printing RAS related messages. +config OPENSIL_DEBUG_MPIO + bool "Enable MPIO messages" + default y + help + Enable printing MPIO related messages. + +config OPENSIL_DEBUG_CXL + bool "Enable CXL messages" + default y + help + Enable printing CXL related messages. + +config OPENSIL_DEBUG_SDXI + bool "Enable SDXI messages" + default y + help + Enable printing SDXI related messages. + +config OPENSIL_DEBUG_RCMGR + bool "Enable RC MGR messages" + default y + help + Enable printing Resource Manager related messages. + +config OPENSIL_DEBUG_XUSL_CMN + bool "Enable xUSL CommonLib messages" + default y + help + Enable printing xUSL CommonLib related messages. + endif # OPENSIL_DEBUG_OUTPUT endif # SOC_AMD_OPENSIL diff --git a/src/vendorcode/amd/opensil/Makefile.mk b/src/vendorcode/amd/opensil/Makefile.mk index 5c881f9bc6a..beebaf5782e 100644 --- a/src/vendorcode/amd/opensil/Makefile.mk +++ b/src/vendorcode/amd/opensil/Makefile.mk @@ -15,6 +15,7 @@ endif opensil_dir := $(call strip_quotes,$(CONFIG_AMD_OPENSIL_PATH)) subdirs-$(CONFIG_SOC_AMD_OPENSIL_GENOA_POC) += genoa_poc +subdirs-$(CONFIG_SOC_AMD_OPENSIL_TURIN_POC) += turin_poc ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y) cpu_family_string="x86" @@ -63,7 +64,11 @@ $(OBJPATH)/$(OPENSIL_CONFIG): $(opensil_dir)/../opensil_config.template $< > $@ $(OBJPATH)/$(OPENSIL_CONFIG).h: $(OBJPATH)/$(OPENSIL_CONFIG) $(obj)/config.h $(objutil)/kconfig/conf - cd $(opensil_dir); KCONFIG_CONFIG=$(OBJPATH)/$(OPENSIL_CONFIG) KCONFIG_AUTOHEADER=$@ $(PYTHON) util/kconfig/lib/genconfig.py Kconfig + cd $(opensil_dir); \ + KCONFIG_CONFIG=$(OBJPATH)/$(OPENSIL_CONFIG) \ + KCONFIG_AUTOHEADER=$@ \ + $(PYTHON) util/kconfig/lib/genconfig.py \ + --config-out $(OBJPATH)/$(OPENSIL_CONFIG) Kconfig # meson handles ccache on its own OPENSIL_COMPILER=$(filter-out $(CCACHE), $(CC_ramstage)) diff --git a/src/vendorcode/amd/opensil/turin_poc/Makefile.mk b/src/vendorcode/amd/opensil/turin_poc/Makefile.mk new file mode 100644 index 00000000000..c2034765024 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/Makefile.mk @@ -0,0 +1,20 @@ +## SPDX-License-Identifier: GPL-2.0-only + +CFLAGS_opensil = -D_MSC_EXTENSIONS=0 -DHAS_STRING_H=1 -Wno-unknown-pragmas + +subdirs-y += mpio + +CPPFLAGS_common += -I$(opensil_dir)/Include -I$(opensil_dir)/xUSL -I$(opensil_dir)/xUSL/Include -I$(opensil_dir)/xUSL/FCH -I$(opensil_dir)/xUSL/FCH/Common -I$(opensil_dir)/xSIM -I$(opensil_dir)/xPRF + +romstage-y += opensil_console.c +romstage-y += romstage.c + +ramstage-y += acpi.c +ramstage-y += memmap.c +ramstage-y += opensil_console.c +ramstage-y += ramstage.c + +$(obj)/romstage/vendorcode/amd/opensil/turin_poc/opensil_console.o: CFLAGS_romstage += $(CFLAGS_opensil) +$(obj)/romstage/vendorcode/amd/opensil/turin_poc/romstage.o: CFLAGS_romstage += $(CFLAGS_opensil) + +$(obj)/ramstage/vendorcode/amd/opensil/turin_poc/opensil_console.o: CFLAGS_ramstage += $(CFLAGS_opensil) diff --git a/src/vendorcode/amd/opensil/turin_poc/acpi.c b/src/vendorcode/amd/opensil/turin_poc/acpi.c new file mode 100644 index 00000000000..dc172e3311a --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/acpi.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +#include "../opensil.h" + +void opensil_fill_fadt(acpi_fadt_t *fadt) +{ + FCHHWACPI_INPUT_BLK *blk = SilFindStructure(SilId_FchHwAcpiP, 0); + + fadt->pm1a_evt_blk = blk->AcpiPm1EvtBlkAddr; + fadt->pm1a_cnt_blk = blk->AcpiPm1CntBlkAddr; + fadt->pm_tmr_blk = blk->AcpiPmTmrBlkAddr; + fadt->gpe0_blk = blk->AcpiGpe0BlkAddr; +} + +unsigned long add_opensil_acpi_table(unsigned long current, acpi_rsdp_t *rsdp) +{ + return current; +} diff --git a/src/vendorcode/amd/opensil/turin_poc/filter.h b/src/vendorcode/amd/opensil/turin_poc/filter.h new file mode 100644 index 00000000000..84f1db1f38d --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/filter.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* Keep this in sync with openSIL SilCommon.h file */ +#define DEBUG_FILTER_APOB 0x00000001UL +#define DEBUG_FILTER_NBIO 0x00000002UL +#define DEBUG_FILTER_CCX 0x00000004UL +#define DEBUG_FILTER_SMU 0x00000008UL +#define DEBUG_FILTER_DF 0x00000010UL +#define DEBUG_FILTER_MPIO 0x00000020UL +#define DEBUG_FILTER_MEM 0x00000040UL +#define DEBUG_FILTER_FCH 0x00000080UL +#define DEBUG_FILTER_RAS 0x00000100UL +#define DEBUG_FILTER_CXL 0x00000200UL +#define DEBUG_FILTER_SDXI 0x00000400UL +#define DEBUG_FILTER_RCMGR 0x00000800UL +#define DEBUG_FILTER_XUSL_CMN 0x00001000UL + +#define SIL_DEBUG(topic) (CONFIG(OPENSIL_DEBUG_##topic) ? DEBUG_FILTER_##topic : 0) + +#define SIL_DEBUG_MODULE_FILTER ( \ + SIL_DEBUG(APOB) | \ + SIL_DEBUG(NBIO) | \ + SIL_DEBUG(CCX) | \ + SIL_DEBUG(SMU) | \ + SIL_DEBUG(DF) | \ + SIL_DEBUG(MPIO) | \ + SIL_DEBUG(MEM) | \ + SIL_DEBUG(FCH) | \ + SIL_DEBUG(RAS) | \ + SIL_DEBUG(CXL) | \ + SIL_DEBUG(SDXI) | \ + SIL_DEBUG(RCMGR) | \ + SIL_DEBUG(XUSL_CMN) ) diff --git a/src/vendorcode/amd/opensil/turin_poc/memmap.c b/src/vendorcode/amd/opensil/turin_poc/memmap.c new file mode 100644 index 00000000000..cf95b312e5e --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/memmap.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include // needed above ApobCmn.h +#include +#include + +#include "../opensil.h" + +_Static_assert(sizeof(uint32_t) == sizeof(((MEMORY_HOLE_DESCRIPTOR){0}).Type), + "Unexpected size of MEMORY_HOLE_TYPES in the MEMORY_HOLE_DESCRIPTOR " + "struct which doesn't match the code in drivers/amd/opensil/memmap.c"); + +const char *opensil_get_hole_info_type(uint32_t type) +{ + const struct hole_type { + MEMORY_HOLE_TYPES type; + const char *string; + } types[] = { + {UMA, "UMA"}, + {MMIO, "MMIO"}, + {PrivilegedDRAM, "PrivilegedDRAM"}, + {Reserved1TbRemap, "Reserved1TbRemap"}, + {ReservedSLink, "ReservedSLink"}, + {ReservedSLinkAlignment, "ReservedSLinkAlignment"}, + {ReservedDrtm, "ReservedDrtm"}, + {ReservedCvip, "ReservedCvip"}, + {ReservedSmuFeatures, "ReservedSmuFeatures"}, + {ReservedFwtpm, "ReservedFwtpm"}, + {ReservedMpioC20, "ReservedMpioC20"}, + {ReservedNbif, "ReservedNbif"}, + {ReservedCxl, "ReservedCxl"}, + {ReservedCxlAlignment, "ReservedCxlAlignment"}, + {ReservedCpuTmr, "ReservedCpuTmr"}, + {ReservedRasEinj, "ReservedRasEinj"}, + {MaxMemoryHoleTypes, "MaxMemoryHoleTypes"}, + }; + + int i; + MEMORY_HOLE_TYPES enum_type = (MEMORY_HOLE_TYPES)type; // Cast int to enum + for (i = 0; i < ARRAY_SIZE(types); i++) + if (enum_type == types[i].type) + return types[i].string; + return "Unknown type"; +} + +void opensil_get_hole_info(uint32_t *n_holes, uint64_t *top_of_mem, void **hole_info) +{ + SIL_STATUS status = xPrfGetSystemMemoryMap(n_holes, top_of_mem, hole_info); + SIL_STATUS_report("xPrfGetSystemMemoryMap", status); + // Make sure hole_info does not get initialized to something odd by xPRF on failure + if (status != SilPass) { + *hole_info = NULL; + *n_holes = 0; + *top_of_mem = 0; + } +} diff --git a/src/vendorcode/amd/opensil/turin_poc/meson_cross.template b/src/vendorcode/amd/opensil/turin_poc/meson_cross.template new file mode 100644 index 00000000000..b8fdf618faa --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/meson_cross.template @@ -0,0 +1,37 @@ +[binaries] +c = '##COMPILER##' +ar = '##AR##' +nasm = '##NASM##' + +[built-in options] +c_args = ['-nostdinc', + '-I##OBJPATH##', + '-I##COREBOOT_DIR##/src/include', + '-I##COREBOOT_DIR##/src/arch/x86/include', + '-I##COREBOOT_DIR##/src/commonlib/include', + '-I##COREBOOT_DIR##/src/commonlib/bsd/include', + '-include', '##COREBOOT_DIR##/src/include/kconfig.h', + '-include', '##OBJPATH##/config.h', + '-include', '##COREBOOT_DIR##/src/commonlib/bsd/include/commonlib/bsd/compiler.h', + '-include', '##OPENSIL_DIR##/../filter.h', + '-DHAS_STRING_H=1', + # openSIL isn't compatible with coreboot's assert implementation, so use special case + '-D_PORTING_H_=1', + '-DSIL_DEBUG_ENABLE=##SIL_DEBUG_ENABLE##', + # openSIL uses coreboot assert which uses printk which warns about unused-param + '-Wno-unused-parameter', + # ubiquitous problem in openSIL + '-Wno-missing-field-initializers', + # remove after https://github.com/openSIL/openSIL/pull/39 is merged + '-Wno-unused-but-set-variable', + ##CLANG_ARGS## + ] + +[host_machine] +system = 'linux' +cpu_family = '##CPU_FAMILY##' +cpu = '##CPU##' +endian = 'little' + +[properties] +is32bit = ##IS32BIT## diff --git a/src/vendorcode/amd/opensil/turin_poc/mpio/Makefile.mk b/src/vendorcode/amd/opensil/turin_poc/mpio/Makefile.mk new file mode 100644 index 00000000000..8ee80c97b05 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/mpio/Makefile.mk @@ -0,0 +1,5 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-y += chip.c + +$(obj)/ramstage/vendorcode/amd/opensil/turin_poc/mpio/chip.o: CFLAGS_ramstage += $(CFLAGS_opensil) diff --git a/src/vendorcode/amd/opensil/turin_poc/mpio/chip.c b/src/vendorcode/amd/opensil/turin_poc/mpio/chip.c new file mode 100644 index 00000000000..3586245b54b --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/mpio/chip.c @@ -0,0 +1,244 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "chip.h" + +static void mpio_params_config(void) +{ + MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0); + struct device *gnb = DEV_PTR(gnb_0); + struct device *iommu = DEV_PTR(iommu_0); + struct device *psp = DEV_PTR(asp); + struct device *nbif = DEV_PTR(nbif_0); + + mpio_data->CfgNbioSsid = gnb->subsystem_vendor | + ((uint32_t)gnb->subsystem_device << 16); + mpio_data->CfgIommuSsid = iommu->subsystem_vendor | + ((uint32_t)iommu->subsystem_device << 16); + mpio_data->CfgPspccpSsid = psp->subsystem_vendor | + ((uint32_t)psp->subsystem_device << 16); + mpio_data->CfgNbifF0Ssid = nbif->subsystem_vendor | + ((uint32_t)nbif->subsystem_device << 16); + mpio_data->CfgNtbSsid = 0; // Not implemented in OpenSIL + mpio_data->CfgNtbccpSsid = 0; // Not implemented in OpenSIL + + mpio_data->CfgDxioClockGating = 1; + mpio_data->PcieDxioTimingControlEnable = 0; + mpio_data->PCIELinkReceiverDetectionPolling = 0; + mpio_data->PCIELinkResetToTrainingTime = 0; + mpio_data->PCIELinkL0Polling = 0; + mpio_data->PCIeExactMatchEnable = 0; + mpio_data->DxioPhyValid = 1; + mpio_data->DxioPhyProgramming = 1; + mpio_data->CfgSkipPspMessage = 1; + mpio_data->DxioSaveRestoreModes = 0xff; + mpio_data->AmdAllowCompliance = 0xf; + mpio_data->SrisEnableMode = 0xff; + mpio_data->SrisSkipInterval = 0; + mpio_data->SrisSkpIntervalSel = 1; + mpio_data->SrisCfgType = 0; + mpio_data->SrisAutoDetectMode = 0xf; + mpio_data->SrisAutodetectFactor = 0; + mpio_data->SrisLowerSkpOsGenSup = 0; + mpio_data->SrisLowerSkpOsRcvSup = 0; + mpio_data->AmdCxlOnAllPorts = 1; + mpio_data->CxlCorrectableErrorLogging = 1; + mpio_data->CxlUnCorrectableErrorLogging = 1; + // This is also available in Nbio. How to handle duplicate entries? + mpio_data->CfgAEREnable = 1; + mpio_data->CfgMcCapEnable = 0; + mpio_data->CfgRcvErrEnable = 0; + mpio_data->EarlyBmcLinkTraining = 1; + mpio_data->SurpriseDownFeature = 1; + mpio_data->LcMultAutoSpdChgOnLastRateEnable = 0; + mpio_data->AmdRxMarginEnabled = 1; + mpio_data->CfgPcieCVTestWA = 0; + mpio_data->CfgPcieAriSupport = 1; + mpio_data->CfgNbioCTOtoSC = 0; + mpio_data->CfgNbioCTOIgnoreError = 1; + mpio_data->AmdPcieSubsystemDeviceID = 0x1453; + mpio_data->AmdPcieSubsystemVendorID = 0x1022; + mpio_data->GppAtomicOps = 1; + mpio_data->GfxAtomicOps = 1; + mpio_data->AmdNbioReportEdbErrors = 0; + mpio_data->OpnSpare = 0; + mpio_data->MPIOAncDataSupport = 1; + mpio_data->AfterResetDelay = 0; + mpio_data->CfgEarlyLink = 0; + mpio_data->AmdCfgExposeUnusedPciePorts = 1; // Show all ports + mpio_data->CfgForcePcieGenSpeed = 0xff; + mpio_data->CfgSataPhyTuning = 0; + mpio_data->PcieLinkComplianceModeAllPorts = 0; + mpio_data->AmdMCTPEnable = 0; + mpio_data->SbrBrokenLaneAvoidanceSup = 1; + mpio_data->AutoFullMarginSup = 1; + // A getter and setter, both are needed for this PCD. + mpio_data->AmdPciePresetMask8GtAllPort = 0xffffffff; + // A getter and setter, both are needed for this PCD. + mpio_data->AmdPciePresetMask16GtAllPort = 0xffffffff; + // A getter and setter, both are needed for this PCD. + mpio_data->AmdPciePresetMask32GtAllPort = 0xffffffff; + mpio_data->PcieLinkAspmAllPort = 0xff; + mpio_data->SyncHeaderByPass = 1; + mpio_data->CxlTempGen5AdvertAltPtcl = 0; + mpio_data->CfgSevSnpSupport = 0; + mpio_data->CfgSevTioSupport = 0; + mpio_data->PcieIdeCapSup = 0; + mpio_data->Master7bitSteeringTag = 1; + + /* TODO handle this differently on multisocket */ + mpio_data->PcieTopologyData.PlatformData[0].Flags = DESCRIPTOR_TERMINATE_LIST; + mpio_data->PcieTopologyData.PlatformData[0].PciePortList = mpio_data->PcieTopologyData.PortList; +} + +static void cxl_params_config(void) +{ + CXLCLASS_DATA_BLK *cxl_data = SilFindStructure(SilId_CxlClass, 0); + CXLCLASS_INPUT_BLK *input = &cxl_data->CxlInputBlock; + input->AmdPcieAerReportMechanism = 1; +} + +static void nbio_params_config(void) +{ + NBIOCLASS_DATA_BLOCK *nbio_data = SilFindStructure(SilId_NbioClass, 0); + NBIO_CONFIG_DATA *input = &nbio_data->NbioConfigData; + input->EsmEnableAllRootPorts = false; + input->EsmTargetSpeed = 16; + input->CfgRxMarginPersistenceMode = 1; + input->SevSnpSupport = false; + input->AerEnRccDev0 = false; + input->CfgAEREnable = true; + input->AtomicRoutingEnStrap5 = true; + input->CfgSriovEnDev0F1 = true; + input->CfgAriEnDev0F1 = true; + input->CfgAerEnDev0F1 = true; + input->CfgAcsEnDev0F1 = true; + input->CfgAtsEnDev0F1 = true; + input->CfgPasidEnDev0F1 = true; + input->CfgRtrEnDev0F1 = true; + input->CfgPriEnDev0F1 = true; + input->CfgPwrEnDev0F1 = true; + input->AtcEnable = true; + input->NbifDev0F1AtomicRequestEn = true; + input->AcsEnRccDev0 = true; + input->AcsP2pReq = true; + input->AcsSourceVal = true; + input->RccDev0E2EPrefix = true; + input->RccDev0ExtendedFmtSupported = true; + input->CfgSyshubMgcgClkGating = 1; + input->IoApicIdPreDefineEn = true; + /* Up to 16 IOAPICs for 2 sockets (8 per socket) */ + input->IoApicIdBase = 240; + input->IommuAvicSupport = true; + + if (CONFIG(XAPIC_ONLY) || CONFIG(X2APIC_LATE_WORKAROUND)) + input->AmdApicMode = xApicMode; + else if (CONFIG(X2APIC_ONLY)) + input->AmdApicMode = x2ApicMode; + else + input->AmdApicMode = ApicAutoMode; +} + +static void setup_bmc_lanes(uint8_t lane, uint8_t socket) +{ + DFX_RCMGR_INPUT_BLK *rc_mgr_input_block = SilFindStructure(SilId_RcManager, 0); + rc_mgr_input_block->BmcSocket = socket; + rc_mgr_input_block->EarlyBmcLinkLaneNum = lane; + + MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0); + mpio_data->EarlyBmcLinkSocket = socket; + mpio_data->EarlyBmcLinkLaneNum = lane; + mpio_data->EarlyBmcLinkDie = 0; + mpio_data->EarlyBmcLinkTraining = true; +} + +void opensil_mpio_per_device_config(struct device *dev) +{ + /* Cache *mpio_data from SilFindStructure */ + static MPIOCLASS_INPUT_BLK *mpio_data = NULL; + if (mpio_data == NULL) { + mpio_data = SilFindStructure(SilId_MpioClass, 0); + } + + static uint32_t slot_num; + const uint32_t domain = dev_get_domain_id(dev); + const uint32_t devfn = dev->path.pci.devfn; + const struct drivers_amd_opensil_mpio_config *const config = dev->chip_info; + printk(BIOS_DEBUG, "Setting MPIO port for domain 0x%x, PCI %d:%d\n", + domain, PCI_SLOT(devfn), PCI_FUNC(devfn)); + + if (config->type == IFTYPE_UNUSED) { + if (is_dev_enabled(dev)) { + printk(BIOS_WARNING, "Unused MPIO chip, disabling PCI device.\n"); + dev->enabled = false; + } else { + printk(BIOS_DEBUG, "Unused MPIO chip, skipping.\n"); + } + return; + } + + if (config->bmc) { + setup_bmc_lanes(config->start_lane, 0); // TODO support multiple sockets + return; + } + + static int mpio_port = 0; + MPIO_PORT_DESCRIPTOR port = { .Flags = DESCRIPTOR_TERMINATE_LIST }; + if (config->type == IFTYPE_PCIE) { + const MPIO_ENGINE_DATA engine_data = + MPIO_ENGINE_DATA_INITIALIZER(MpioPcieEngine, + config->start_lane, config->end_lane, + config->hotplug == HotplugDisabled ? 0 : 1, + config->gpio_group); + port.EngineData = engine_data; + const MPIO_PORT_DATA port_data = + MPIO_PORT_DATA_INITIALIZER_PCIE(is_dev_enabled(dev) ? + MpioPortEnabled : MpioPortDisabled, + PCI_SLOT(devfn), + PCI_FUNC(devfn), + config->hotplug, + config->speed, + 0, // No backup PCIe speed + config->aspm, + config->aspm_l1_1, + config->aspm_l1_2, + config->clock_pm); + port.Port = port_data; + } else if (config->type == IFTYPE_SATA) { + const MPIO_ENGINE_DATA engine_data = + MPIO_ENGINE_DATA_INITIALIZER(MpioSATAEngine, + config->start_lane, config->end_lane, + 0, // meaningless field + config->gpio_group); + port.EngineData = engine_data; + const MPIO_PORT_DATA port_data = { .PortPresent = 1 }; + port.Port = port_data; + + } + port.Port.AlwaysExpose = 1; + port.Port.SlotNum = ++slot_num; + mpio_data->PcieTopologyData.PortList[mpio_port] = port; + /* Update TERMINATE list */ + if (mpio_port > 0) + mpio_data->PcieTopologyData.PortList[mpio_port - 1].Flags = 0; + mpio_port++; +} + +void opensil_mpio_global_config(void) +{ + mpio_params_config(); + cxl_params_config(); + nbio_params_config(); +} diff --git a/src/vendorcode/amd/opensil/turin_poc/mpio/chip.h b/src/vendorcode/amd/opensil/turin_poc/mpio/chip.h new file mode 100644 index 00000000000..db6a094ed45 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/mpio/chip.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef OPENSIL_TURIN_POC_MPIO_CHIP_H +#define OPENSIL_TURIN_POC_MPIO_CHIP_H + +#include + +/* + * TURIN MPIO mapping + * P0 -> [0-15] + * P3 -> [16-31] + * P1 -> [32-47] + * P2 -> [48-63] + * G1 -> [64-79] + * G3 -> [80-95] + * G0 -> [96-111] + * G2 -> [112-127] + * P4 -> [128-131] + * P5 -> [132-136] + */ + +enum mpio_type { + IFTYPE_UNUSED, + IFTYPE_PCIE, + IFTYPE_SATA, +}; + +/* Sync with PCIE_HOTPLUG_TYPE */ +enum mpio_hotplug { + HotplugDisabled, ///< Hotplug disable + Basic, ///< Basic Hotplug + ServerExpress, ///< Server Hotplug Express Module + Enhanced, ///< Enhanced + Inboard, ///< Inboard + ServerEntSSD, ///< Server Hotplug Enterprise SSD + UBM, ///< UBM Backplane + OCP, ///< OCP NIC 3.0 +}; + +enum pcie_link_speed { + MaxSupported, + Gen1, + Gen2, + Gen3, + Gen4, + Gen5, +}; + +/* Sync with PCIE_ASPM_TYPE */ +enum pcie_aspm { + aspm_disabled, + L0s, + L1, + L0sL1, +}; + +struct drivers_amd_opensil_mpio_config { + enum mpio_type type; + uint8_t start_lane; + uint8_t end_lane; + uint8_t gpio_group; + enum mpio_hotplug hotplug; + enum pcie_link_speed speed; + enum pcie_aspm aspm; + uint8_t aspm_l1_1 : 1; + uint8_t aspm_l1_2 : 1; + uint8_t clock_pm : 1; + uint8_t bmc : 1; +}; + +#endif /* OPENSIL_TURIN_POC_MPIO_CHIP_H */ diff --git a/src/vendorcode/amd/opensil/turin_poc/opensil b/src/vendorcode/amd/opensil/turin_poc/opensil new file mode 160000 index 00000000000..a65485ffa7b --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/opensil @@ -0,0 +1 @@ +Subproject commit a65485ffa7bddec696576323c6fc839ea5bb081d diff --git a/src/vendorcode/amd/opensil/turin_poc/opensil_config.template b/src/vendorcode/amd/opensil/turin_poc/opensil_config.template new file mode 100644 index 00000000000..1bbc650990f --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/opensil_config.template @@ -0,0 +1,5 @@ +CONFIG_PLAT_APOB_ADDRESS=##APOB_BASE## +CONFIG_PSP_BIOS_BIN_BASE=##BIOS_ENTRY_BASE## +CONFIG_PSP_BIOS_BIN_SIZE=##BIOS_ENTRY_SIZE## +CONFIG_PLAT_NUMBER_SOCKETS=1 +CONFIG_SOC_F1AM00=y diff --git a/src/vendorcode/amd/opensil/turin_poc/opensil_console.c b/src/vendorcode/amd/opensil/turin_poc/opensil_console.c new file mode 100644 index 00000000000..7a7d451f72d --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/opensil_console.c @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include "opensil_console.h" +#include + +static int translate_opensil_debug_level(size_t MsgLevel) +{ + switch (MsgLevel) { + case SIL_TRACE_ERROR: + return BIOS_ERR; + case SIL_TRACE_WARNING: + return BIOS_WARNING; + case SIL_TRACE_INFO: + return BIOS_DEBUG; + case SIL_TRACE_ENTRY: + case SIL_TRACE_EXIT: + case SIL_TRACE_RAW: + case SIL_TRACE_VERBOSE: + return BIOS_SPEW; + default: + return BIOS_NEVER; + } +} + +void HostDebugService(size_t MsgLevel, const char *SilPrefix, const char *Message, + const char *Function, size_t Line, ...) +{ + if (!CONFIG(OPENSIL_DEBUG_OUTPUT)) + return; + + const int loglevel = translate_opensil_debug_level(MsgLevel); + + /* print formatted prefix */ + if (CONFIG(OPENSIL_DEBUG_PREFIX)) { + switch (MsgLevel) { + case SIL_TRACE_RAW: break; // Raw print do nothing + case SIL_TRACE_ENTRY: + printk(loglevel, "%s Enter %s:%zu:", SilPrefix, Function, Line); + break; + case SIL_TRACE_EXIT: + printk(loglevel, "%s Exit %s:%zu:", SilPrefix, Function, Line); + break; + case SIL_TRACE_ERROR: + case SIL_TRACE_WARNING: + case SIL_TRACE_INFO: + case SIL_TRACE_VERBOSE: + /* fallthrough */ + default: + printk(loglevel, "%s%s:%zu:", SilPrefix, Function, Line); + break; + } + } + + /* print formatted message */ + va_list args; + va_start(args, Line); + vprintk(loglevel, Message, args); + va_end(args); +} diff --git a/src/vendorcode/amd/opensil/turin_poc/opensil_console.h b/src/vendorcode/amd/opensil/turin_poc/opensil_console.h new file mode 100644 index 00000000000..424f002d37d --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/opensil_console.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _VENDORCODE_AMD_OPENSIL_CONSOLE +#define _VENDORCODE_AMD_OPENSIL_CONSOLE + +#include + +void HostDebugService(size_t MsgLevel, const char *SilPrefix, const char *Message, + const char *Function, size_t Line, ...); + +#endif diff --git a/src/vendorcode/amd/opensil/turin_poc/ramstage.c b/src/vendorcode/amd/opensil/turin_poc/ramstage.c new file mode 100644 index 00000000000..f206ef5f584 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/ramstage.c @@ -0,0 +1,375 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* opensil_config.h needed for PROJ_MAX_* defines */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "opensil_console.h" +#include "../opensil.h" + + +#define TURIN_USB_STRUCT_MAJOR_VERSION 0xd +#define TURIN_USB_STRUCT_MINOR_VERSION 0x13 + +#define TURIN_USB_PORT_PER_CONTROLLER 2 +#define TURIN_USB_CONTROLLERS_PER_SOCKET 2 +#define TURIN_NUM_USB_PORTS \ + (TURIN_USB_PORT_PER_CONTROLLER * TURIN_USB_CONTROLLERS_PER_SOCKET) + +/* + * Structures copied from Genoa POC code, because Turin POC does not define these. + * It appears the USB structures are identical for Turin and Genoa. + */ +typedef struct { + uint8_t COMPDSTUNE; + uint8_t SQRXTUNE; + uint8_t TXFSLSTUNE; + uint8_t TXPREEMPAMPTUNE; + uint8_t TXPREEMPPULSETUNE; + uint8_t TXRISETUNE; + uint8_t TXVREFTUNE; + uint8_t TXHSXVTUNE; + uint8_t TXRESTUNE; +} __packed FCH_USB20_PHY; + +typedef struct { + uint8_t RX_ANA_IQ_PHASE_ADJUST; + uint8_t RX_EQ_DELTA_IQ_OVRD_EN; + uint8_t RX_EQ_DELTA_IQ_OVRD_VAL; + uint8_t RX_IQ_PHASE_ADJUST; + uint8_t TX_VBOOST_LVL_EN; + uint8_t TX_VBOOST_LVL; + uint8_t RX_VREF_CTRL_EN; + uint8_t RX_VREF_CTRL; + uint8_t TX_VBOOST_LVL_EN_X; + uint8_t TX_VBOOST_LVL_X; + uint8_t RX_VREF_CTRL_EN_X; + uint8_t RX_VREF_CTRL_X; +} __packed FCH_USB31_PHY; + +typedef struct { + uint8_t Version_Major; + uint8_t Version_Minor; + uint8_t TableLength; + uint8_t Reserved0; + uint8_t Usb20PhyEnable; + FCH_USB20_PHY Usb20PhyPort[TURIN_NUM_USB_PORTS]; + uint8_t Reserved1; + uint8_t S1Usb20PhyEnable; + FCH_USB20_PHY S1Usb20PhyPort[TURIN_NUM_USB_PORTS]; + uint8_t Usb31PhyEnable; + FCH_USB31_PHY Usb31PhyPort[TURIN_NUM_USB_PORTS]; + uint8_t S1Usb31PhyEnable; + FCH_USB31_PHY S1Usb31PhyPort[TURIN_NUM_USB_PORTS]; +} __packed FCH_USB_OEM_PLATFORM_TABLE; + +static FCH_USB_OEM_PLATFORM_TABLE usb_config = { 0 }; + +void SIL_STATUS_report(const char *function, const int status) +{ + const int log_level = status == SilPass ? BIOS_DEBUG : BIOS_ERR; + const char *error_string = "Unknown error"; + + const struct error_string_entry { + SIL_STATUS status; + const char *string; + } errors[] = { + {SilPass, "SilPass"}, + {SilUnsupportedHardware, "SilUnsupportedHardware"}, + {SilUnsupported, "SilUnsupported"}, + {SilInvalidParameter, "SilInvalidParameter"}, + {SilAborted, "SilAborted"}, + {SilOutOfResources, "SilOutOfResources"}, + {SilNotFound, "SilNotFound"}, + {SilOutOfBounds, "SilOutOfBounds"}, + {SilDeviceError, "SilDeviceError"}, + {SilResetRequestColdImm, "SilResetRequestColdImm"}, + {SilResetRequestColdDef, "SilResetRequestColdDef"}, + {SilResetRequestWarmImm, "SilResetRequestWarmImm"}, + {SilResetRequestWarmDef, "SilResetRequestWarmDef"}, + }; + + int i; + for (i = 0; i < ARRAY_SIZE(errors); i++) { + if (errors[i].status == status) { + error_string = errors[i].string; + break; + } + } + printk(log_level, "%s returned %d (%s)\n", function, status, error_string); +} + +static void setup_rc_manager_default(void) +{ + DFX_RCMGR_INPUT_BLK *rc_mgr_input_block = SilFindStructure(SilId_RcManager, 0); + + /* Let openSIL distribute the resources to the different PCI roots */ + rc_mgr_input_block->SetRcBasedOnNv = false; + + /* Currently 1P is the only supported configuration */ + rc_mgr_input_block->SocketNumber = 1; + rc_mgr_input_block->RbsPerSocket = 8; /* PCI root bridges per socket */ + rc_mgr_input_block->McptEnable = true; + rc_mgr_input_block->PciExpressBaseAddress = CONFIG_ECAM_MMCONF_BASE_ADDRESS; + rc_mgr_input_block->BottomMmioReservedForPrimaryRb = 4ull * GiB - 32 * MiB; + rc_mgr_input_block->MmioSizePerRbForNonPciDevice = 16 * MiB; + /* + * Turin has 52 bits of available physical address space without SME + * enabled. To avoid using 5-level paging (which we do not support yet + * in coreboot and UEFI payload) required to cover MMIO above 48 bits + * of address space (since 4-level paging can cover only 48 bits of + * physical address space), limit the MMIO to maximum of 48 bits. + * MmioAbove4GLimit will be adjusted down in openSIL if needed. + */ + rc_mgr_input_block->MmioAbove4GLimit = POWER_OF_2(MIN(48, cpu_phys_address_size())); + rc_mgr_input_block->Above4GMmioSizePerRbForNonPciDevice = 0; +} + +static void setup_data_fabric_default(void) +{ + DFCLASS_INPUT_BLK *df_input_block = SilFindStructure(SilId_DfClass, 0); + + if (!df_input_block) { + printk(BIOS_ERR, "OpenSIL: Data Fabric block not found\n"); + return; + } + + df_input_block->AmdPciExpressBaseAddress = CONFIG_ECAM_MMCONF_BASE_ADDRESS; +} + +#define NUM_XHCI_CONTROLLERS 2 +static void configure_usb(void) +{ + const struct soc_amd_turin_poc_config *soc_config = config_of_soc(); + const struct soc_usb_config *usb = &soc_config->usb; + + FCHUSB_INPUT_BLK *fch_usb_data = SilFindStructure(SilId_FchUsb, 0); + + fch_usb_data->Xhci0Enable = usb->xhci0_enable; + fch_usb_data->Xhci1Enable = usb->xhci1_enable; + fch_usb_data->Xhci2Enable = false; /* there's no XHCI2 on this SoC */ + for (int i = 0; i < NUM_XHCI_CONTROLLERS; i++) { + memcpy(&fch_usb_data->XhciOCpinSelect[i].Usb20OcPin, &usb->usb2_oc_pins[i], + sizeof(fch_usb_data->XhciOCpinSelect[i].Usb20OcPin)); + memcpy(&fch_usb_data->XhciOCpinSelect[i].Usb31OcPin, &usb->usb3_oc_pins[i], + sizeof(fch_usb_data->XhciOCpinSelect[i].Usb31OcPin)); + } + fch_usb_data->XhciOcPolarityCfgLow = usb->polarity_cfg_low; + fch_usb_data->Usb3PortForceGen1 = usb->usb3_force_gen1.raw; + + memset(&usb_config, 0, sizeof(usb_config)); + + usb_config.Version_Major = TURIN_USB_STRUCT_MAJOR_VERSION; + usb_config.Version_Minor = TURIN_USB_STRUCT_MINOR_VERSION; + usb_config.TableLength = sizeof(FCH_USB_OEM_PLATFORM_TABLE); + + usb_config.Usb31PhyEnable = usb->usb31_phy_enable; + memcpy(usb_config.Usb31PhyPort, usb->usb31_phy, sizeof(usb_config.Usb31PhyPort)); + + usb_config.S1Usb31PhyEnable = usb->s1_usb31_phy_enable; + memcpy(usb_config.S1Usb31PhyPort, usb->s1_usb31_phy, sizeof(usb_config.S1Usb31PhyPort)); + + fch_usb_data->OemUsbConfigurationTable = (uintptr_t)&usb_config; +} + +#define NUM_SATA_CONTROLLERS 4 +static void configure_sata(void) +{ + FCHSATA_INPUT_BLK *fch_sata_data = SilFindStructure(SilId_FchSata, 0); + FCHSATA_INPUT_BLK *fch_sata_defaults = FchSataGetInputBlk(); + struct device *sata[NUM_SATA_CONTROLLERS] = { + DEV_PTR(sata_2_0), + DEV_PTR(sata_2_1), + DEV_PTR(sata_7_0), + DEV_PTR(sata_7_1) + }; + + for (int i = 0; i < NUM_SATA_CONTROLLERS; i++) { + fch_sata_data[i] = fch_sata_defaults[i]; + fch_sata_data[i].SataAhciSsid = (sata[i])->subsystem_vendor | + ((uint32_t)((sata[i])->subsystem_device) << 16); + fch_sata_data[i].SataSetMaxGen2 = false; + fch_sata_data[i].SataMsiEnable = true; + fch_sata_data[i].SataEspPort = 0xFF; + fch_sata_data[i].SataRasSupport = true; + fch_sata_data[i].SataDevSlpPort1Num = 1; + fch_sata_data[i].SataMsiEnable = true; + fch_sata_data[i].SataControllerAutoShutdown = true; + fch_sata_data[i].SataRxPolarity = 0xFF; + } +} + +static void configure_fch_isa(void) +{ + FCHISA_INPUT_BLK *fch_isa_data = SilFindStructure(SilId_FchIsa, 0); + struct device *lpc = DEV_PTR(lpc_bridge); + + fch_isa_data->LpcConfig.LpcSsid = lpc->subsystem_vendor | + ((uint32_t)lpc->subsystem_device << 16); + + /* Keep defaults that were set by either EFS or coreboot */ + fch_isa_data->SpiConfig.SpiSpeed = 0; + fch_isa_data->SpiConfig.SpiTpmSpeed = 0; + fch_isa_data->SpiConfig.WriteSpeed = 0; +} + +#define FCH_DEV_ENABLE(dev, aoac_bit) \ + fch_data->FchRunTime.FchDeviceEnableMap |= ((DEV_PTR(dev))->enabled ? aoac_bit : 0) + +static void configure_fch_acpi(void) +{ + FCHHWACPI_INPUT_BLK *fch_hwacpi_data = SilFindStructure(SilId_FchHwAcpiP, 0); + FCHCLASS_INPUT_BLK *fch_data = SilFindStructure(SilId_FchClass, 0); + struct device *smb = DEV_PTR(smbus); + + fch_data->Smbus.SmbusSsid = smb->subsystem_vendor | + ((uint32_t)smb->subsystem_device << 16); + + fch_data->FchBldCfg.CfgSioPmeBaseAddress = 0; + fch_data->FchBldCfg.CfgAcpiPm1EvtBlkAddr = ACPI_PM_EVT_BLK; + fch_data->FchBldCfg.CfgAcpiPm1CntBlkAddr = ACPI_PM1_CNT_BLK; + fch_data->FchBldCfg.CfgAcpiPmTmrBlkAddr = ACPI_PM_TMR_BLK; + fch_data->FchBldCfg.CfgCpuControlBlkAddr = ACPI_CSTATE_CONTROL; + fch_data->FchBldCfg.CfgAcpiGpe0BlkAddr = ACPI_GPE0_BLK; + fch_data->FchBldCfg.CfgSmiCmdPortAddr = APM_CNT; + + fch_data->CfgIoApicIdPreDefEnable = true; + fch_data->FchIoApicId = 128; + + fch_data->WdtEnable = false; + + /* Servers usually don't have KBC on SIO */ + fch_data->Misc.NoneSioKbcSupport = true; + + fch_hwacpi_data->PwrFailShadow = (CONFIG_MAINBOARD_POWER_FAILURE_STATE == 2) ? + 3 : CONFIG_MAINBOARD_POWER_FAILURE_STATE; + + fch_data->FchRunTime.FchDeviceEnableMap = 0; + FCH_DEV_ENABLE(i2c_0, FCH_AOAC_DEV_I2C0); + FCH_DEV_ENABLE(i2c_1, FCH_AOAC_DEV_I2C1); + FCH_DEV_ENABLE(i2c_2, FCH_AOAC_DEV_I2C2); + FCH_DEV_ENABLE(i2c_3, FCH_AOAC_DEV_I2C3); + FCH_DEV_ENABLE(i2c_4, FCH_AOAC_DEV_I2C4); + FCH_DEV_ENABLE(i2c_5, FCH_AOAC_DEV_I2C5); + FCH_DEV_ENABLE(uart_0, FCH_AOAC_DEV_UART0); + FCH_DEV_ENABLE(uart_1, FCH_AOAC_DEV_UART1); + FCH_DEV_ENABLE(uart_2, FCH_AOAC_DEV_UART2); + FCH_DEV_ENABLE(i3c_0, FCH_AOAC_DEV_I3C0); + FCH_DEV_ENABLE(i3c_1, FCH_AOAC_DEV_I3C1); + FCH_DEV_ENABLE(i3c_2, FCH_AOAC_DEV_I3C2); + FCH_DEV_ENABLE(i3c_3, FCH_AOAC_DEV_I3C3); +} + +static void configure_sdxi(void) +{ + MPIOCLASS_INPUT_BLK *mpio_data = SilFindStructure(SilId_MpioClass, 0); + SDXICLASS_INPUT_BLK *sdxi_data = SilFindStructure(SilId_SdxiClass, 0); + + mpio_data->AmdFabricSdxi = true; + sdxi_data->AmdFabricSdxi = true; +} + +static void configure_ccx(void) +{ + CCXCLASS_DATA_BLK *ccx_data = SilFindStructure(SilId_CcxClass, 0); + + if (CONFIG(XAPIC_ONLY) || CONFIG(X2APIC_LATE_WORKAROUND)) + ccx_data->CcxInputBlock.AmdApicMode = xApicMode; + else if (CONFIG(X2APIC_ONLY)) + ccx_data->CcxInputBlock.AmdApicMode = x2ApicMode; + else + ccx_data->CcxInputBlock.AmdApicMode = ApicAutoMode; + + ccx_data->CcxInputBlock.EnableAvx512 = 1; + ccx_data->CcxInputBlock.EnableSvmX2AVIC = 1; + ccx_data->CcxInputBlock.EnableSvmAVIC = true; + ccx_data->CcxInputBlock.AmdCStateIoBaseAddress = ACPI_CSTATE_CONTROL; +} + +void setup_opensil(void) +{ + const SIL_STATUS debug_ret = SilDebugSetup(HostDebugService); + SIL_STATUS_report("SilDebugSetup", debug_ret); + const size_t mem_req = xSimQueryMemoryRequirements(); + void *buf = cbmem_add(CBMEM_ID_AMD_OPENSIL, mem_req); + assert(buf); + /* We run all openSIL timepoints in the same stage so using TP1 as argument is fine. */ + const SIL_STATUS assign_mem_ret = xSimAssignMemoryTp1(buf, mem_req); + SIL_STATUS_report("xSimAssignMemory", assign_mem_ret); + + setup_rc_manager_default(); + setup_data_fabric_default(); + configure_ccx(); + configure_fch_isa(); + configure_fch_acpi(); + configure_usb(); + configure_sata(); + configure_sdxi(); +} + +static void opensil_entry(SIL_TIMEPOINT timepoint) +{ + SIL_STATUS ret; + SIL_TIMEPOINT tp = (uintptr_t)timepoint; + + switch (tp) { + case SIL_TP1: + ret = InitializeAMDSiTp1(); + break; + case SIL_TP2: + ret = InitializeAMDSiTp2(); + break; + case SIL_TP3: + ret = InitializeAMDSiTp3(); + break; + default: + printk(BIOS_ERR, "Unknown openSIL timepoint\n"); + return; + } + char opensil_function[16]; + snprintf(opensil_function, sizeof(opensil_function), "InitializeSiTp%d", tp + 1); + SIL_STATUS_report(opensil_function, ret); + if (ret == SilResetRequestColdImm || ret == SilResetRequestColdDef) { + printk(BIOS_INFO, "openSIL requested a cold reset"); + do_cold_reset(); + } else if (ret == SilResetRequestWarmImm || ret == SilResetRequestWarmDef) { + printk(BIOS_INFO, "openSIL requested a warm reset"); + do_warm_reset(); + } +} + +void opensil_xSIM_timepoint_1(void) +{ + opensil_entry(SIL_TP1); +} + +void opensil_xSIM_timepoint_2(void) +{ + opensil_entry(SIL_TP2); +} + +void opensil_xSIM_timepoint_3(void) +{ + opensil_entry(SIL_TP3); +} diff --git a/src/vendorcode/amd/opensil/turin_poc/romstage.c b/src/vendorcode/amd/opensil/turin_poc/romstage.c new file mode 100644 index 00000000000..5b871f60255 --- /dev/null +++ b/src/vendorcode/amd/opensil/turin_poc/romstage.c @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include "opensil_console.h" +#include +#include + +#include "../opensil.h" + +uintptr_t opensil_get_low_usable_dram_address(void) +{ + SilDebugSetup(HostDebugService); + uintptr_t low_usable_dram_addr = xPrfGetLowUsableDramAddress(0); + printk(BIOS_DEBUG, "xPrfGetLowUsableDramAddress: 0x%lx\n", low_usable_dram_addr); + + return low_usable_dram_addr; +} diff --git a/src/vendorcode/google/chromeos/Makefile.mk b/src/vendorcode/google/chromeos/Makefile.mk index cfb4af45deb..644003e603d 100644 --- a/src/vendorcode/google/chromeos/Makefile.mk +++ b/src/vendorcode/google/chromeos/Makefile.mk @@ -24,6 +24,7 @@ romstage-$(CONFIG_CHROMEOS_DRAM_PART_NUMBER_IN_CBI) += dram_part_num_override.c ramstage-$(CONFIG_PLATFORM_HAS_LOW_BATTERY_INDICATOR) += battery.c ramstage-$(CONFIG_CHROMEOS_FW_SPLASH_SCREEN) += splash.c +ramstage-$(CONFIG_FRAMEBUFFER_SPLASH_TEXT) += splash_text.c ramstage-$(CONFIG_CHROMEOS_PVMFW_CBMEM) += pvmfw_cbmem.c # Add logo to the cbfs image diff --git a/src/vendorcode/google/chromeos/battery.c b/src/vendorcode/google/chromeos/battery.c index 438098256ba..0e676b3f2a1 100644 --- a/src/vendorcode/google/chromeos/battery.c +++ b/src/vendorcode/google/chromeos/battery.c @@ -2,6 +2,8 @@ #include #include +#include +#include /* * Check if low battery shutdown is needed @@ -32,3 +34,25 @@ bool platform_is_low_battery_shutdown_needed(void) return result; } + +/* + * Platform hooks for system shutdown due to critical battery levels. + * Provides visual feedback via the Lightbar/LEDs and logs the event + * to non-volatile storage before signaling to cut power. + */ +void platform_handle_emergency_low_battery(void) +{ + if (!CONFIG(EC_GOOGLE_CHROMEEC)) + return; + + /* Visual alert: Set Lightbar to solid Red */ + google_chromeec_set_lightbar_rgb(0xff, 0xff, 0x00, 0x00); + + /* Record the event for post-mortem diagnostics (stored in CMOS/Flash) */ + elog_add_event_byte(ELOG_TYPE_LOW_BATTERY_INDICATOR, ELOG_FW_ISSUE_SHUTDOWN); + + /* * Pause briefly to ensure the user perceives the LED change and + * the event log is safely committed to storage. + */ + delay(CONFIG_PLATFORM_POST_RENDER_DELAY_SEC); +} diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h index 540f3635aaa..d8f7e6117c1 100644 --- a/src/vendorcode/google/chromeos/chromeos.h +++ b/src/vendorcode/google/chromeos/chromeos.h @@ -34,6 +34,8 @@ void chromeos_set_ramoops(void *ram_oops, size_t size); * Return "UNDEFINED_FACTORY_CONFIG" in case of error. */ uint64_t chromeos_get_factory_config(void); + +#if CONFIG(TPM_GOOGLE) /* * Determines whether a ChromeOS device is branded as a Chromebook-Plus * based on specific bit flags: @@ -57,6 +59,18 @@ bool chromeos_device_branded_plus_hard(void); * To be considered a soft-branded Chromebook-Plus, both of these conditions need to be met. */ bool chromeos_device_branded_plus_soft(void); +#else +/* Inline fallback for platforms without Google TPM */ +static inline bool chromeos_device_branded_plus_hard(void) +{ + return false; +} + +static inline bool chromeos_device_branded_plus_soft(void) +{ + return false; +} +#endif /* * Declaration for mainboards to use to generate ACPI-specific ChromeOS needs. diff --git a/src/vendorcode/google/chromeos/splash.c b/src/vendorcode/google/chromeos/splash.c index 5923513473c..ff6d83d6dd9 100644 --- a/src/vendorcode/google/chromeos/splash.c +++ b/src/vendorcode/google/chromeos/splash.c @@ -3,8 +3,22 @@ #include #include +/* + * Mainboard-specific override for logo filenames. + * Default implementation returns NULL to signal no override. + */ +__weak const char *mainboard_bmp_logo_filename(void) +{ + return NULL; +} + const char *bmp_logo_filename(void) { + /* Check if the mainboard wants to provide a logo */ + const char *mainboard_logo = mainboard_bmp_logo_filename(); + if (mainboard_logo) + return mainboard_logo; + /* * If the device has a custom boot splash footer logo (SPLASH_SCREEN_FOOTER Kconfig * is enabled and a logo path is provided), we only return the main OEM logo, which diff --git a/src/vendorcode/google/chromeos/splash_text.c b/src/vendorcode/google/chromeos/splash_text.c new file mode 100644 index 00000000000..bad33f3b49d --- /dev/null +++ b/src/vendorcode/google/chromeos/splash_text.c @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +static bool get_battery_status_msg(char *msg, size_t msg_max) +{ + uint32_t batt_pct; + + if (google_chromeec_read_batt_state_of_charge(&batt_pct)) { + printk(BIOS_WARNING, "Failed to get battery level\n"); + return false; + } + + if (google_chromeec_is_critically_low_on_battery()) { + snprintf(msg, msg_max, "%u%%", batt_pct); + } else if (google_chromeec_is_charger_present()) { + if (batt_pct == 100) + snprintf(msg, msg_max, "Charged"); + else + snprintf(msg, msg_max, "Charging: %u%%", batt_pct); + } + + return true; +} + +bool platform_get_splash_text(enum bootsplash_type logo_type, char *msg, size_t msg_max) +{ + if (!CONFIG(EC_GOOGLE_CHROMEEC) || !msg || msg_max == 0) + return false; + + memset(msg, 0, msg_max); + + if (logo_type == BOOTSPLASH_LOW_BATTERY || logo_type == BOOTSPLASH_OFF_MODE_CHARGING) + return get_battery_status_msg(msg, msg_max); + + return false; +} diff --git a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspmUpd.h b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspmUpd.h index 5c26bcd685e..cb221b9e143 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspmUpd.h +++ b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspmUpd.h @@ -93,9 +93,11 @@ typedef struct { **/ UINT32 SerialIoUartDebugCtsPinMux; -/** Offset 0x0074 - Reserved +/** Offset 0x0074 - SerialIo Uart PowerGating + Select SerialIo Uart Powergating mode + 0:Disabled, 1:Enabled, 2:Auto **/ - UINT8 Reserved1; + UINT8 SerialIoUartPowerGating; /** Offset 0x0075 - DCI Enable Determine if to enable DCI debug from host @@ -110,9 +112,28 @@ typedef struct { **/ UINT8 DciDbcMode; -/** Offset 0x0077 - Reserved +/** Offset 0x0077 - DCI Clock Enable + Enable/Disable DCI clock in lowest power state + $EN_DIS +**/ + UINT8 DciClkEnable; + +/** Offset 0x0078 - Keep Early Trace + Trace is activated by default. When enable, keep early trace data and keep tracing, + may block s0ix.\n + When disabled will abandon trace data and stop tracing which allows enter s0ix\n + \n + noted:enable this option will not enable TraceHub; When probe is connected, keep + early trace will then be configured by tool, this option will not take effect. + $EN_DIS +**/ + UINT8 KeepEarlyTrace; + +/** Offset 0x0079 - Enable/Disable MemoryOverlap check + Enable(Default): Enable MemoryOverlap check, Disable: Disable MemoryOverlap check + $EN_DIS **/ - UINT8 Reserved2[3]; + UINT8 MemMapOverlapCheckSupport; /** Offset 0x007A - Memory Test on Warm Boot Run Base Memory Test on Warm Boot @@ -122,7 +143,7 @@ typedef struct { /** Offset 0x007B - Reserved **/ - UINT8 Reserved3[5]; + UINT8 Reserved1[5]; /** Offset 0x0080 - Platform Reserved Memory Size The minimum platform memory size required to pass control into DXE @@ -137,7 +158,7 @@ typedef struct { /** Offset 0x008A - Reserved **/ - UINT8 Reserved4[6]; + UINT8 Reserved2[6]; /** Offset 0x0090 - Memory SPD Pointer Controller 0 Channel 0 Dimm 0 Pointer to SPD data, will be used only when SpdAddressTable SPD Address are marked as 00 @@ -316,9 +337,19 @@ typedef struct { **/ UINT8 LowerBasicMemTestSize; -/** Offset 0x01AD - Reserved +/** Offset 0x01AD - EccGranularity32BEn + Reduce BasicMemTest size. 0: Disabled (default), regular BasicMemTest. 1: Enabled, + shorter BasicMemTest (faster boot) + $EN_DIS +**/ + UINT8 EccGranularity32BEn; + +/** Offset 0x01AE - EccCorrectionMode + Reduce BasicMemTest size. 0: Disabled (default), regular BasicMemTest. 1: Enabled, + shorter BasicMemTest (faster boot) + $EN_DIS **/ - UINT8 Reserved5[2]; + UINT8 EccCorrectionMode; /** Offset 0x01AF - CaVrefHigh DDR5 CA Sweep High Vref Value for DDR5 OC @@ -350,9 +381,13 @@ typedef struct { **/ UINT8 DFETap2StepSize; -/** Offset 0x01B5 - Reserved +/** Offset 0x01B5 - IbeccEccInjControl + IBECC Error Injection Control + 0: No Error Injection, 1:Inject Correctable Error Address match, 3:Inject Correctable + Error on insertion counter, 5: Inject Uncorrectable Error Address match, 7:Inject + Uncorrectable Error on insertion counter **/ - UINT8 Reserved6; + UINT8 IbeccEccInjControl; /** Offset 0x01B6 - VDD2 override VDD2 override for DDR5 OC; 0 - Auto @@ -473,9 +508,17 @@ typedef struct { **/ UINT16 tCCD_L_WR; -/** Offset 0x01E2 - Reserved +/** Offset 0x01E2 - Periodic COMP + Enable/disable Periodic Compensation + $EN_DIS **/ - UINT8 Reserved7[2]; + UINT8 EnPeriodicComp; + +/** Offset 0x01E3 - LPMode4 Support + LPMode4 Options + 0: Disable, 1:Enable, 2:Dynamic Threshold 2, 3:Dynamic Threshold 3 +**/ + UINT8 LpMode4; /** Offset 0x01E4 - LPMode Support Bit[0]: Enable Lpmode0p5 (Idle_enable), Bit[1]: Enable Lpmode2 (Powerdown_enable), @@ -483,9 +526,17 @@ typedef struct { **/ UINT8 LpMode; -/** Offset 0x01E5 - Reserved +/** Offset 0x01E5 - Opportunistic Read + Enables/Disable Opportunistic Read (Def= Enable) + $EN_DIS +**/ + UINT8 OpportunisticRead; + +/** Offset 0x01E6 - Cycle Bypass Support + Enables/Disable Cycle Bypass Support(Def=Disable) + $EN_DIS **/ - UINT8 Reserved8[2]; + UINT8 Disable2CycleBypass; /** Offset 0x01E7 - MRC OCSafeMode OverClocking Safe Mode for tCL @@ -493,9 +544,13 @@ typedef struct { **/ UINT8 OCSafeMode; -/** Offset 0x01E8 - Reserved +/** Offset 0x01E8 - DQ Vref Ctrl Offset + Offset to be applied to DDRDATA7CH1_CR_DDRCRVREFADJUST1.Ch0VrefCtl + 0xF4:-12,0xF5:-11, 0xF6:-10, 0xF7:-9, 0xF8:-8, 0xF9:-7, 0xFA:-6, 0xFB:-5, 0xFC:-4, + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3, 4:+4, 5:+5, 6:+6, 7:+7, 8:+8, + 9:+9, 10:+10, 11:+11, 12:+12 **/ - UINT8 Reserved9; + UINT8 VrefCtlOffset; /** Offset 0x01E9 - Dqs Pins Interleaved Setting Indicates DqPinsInterleaved setting: board-dependent @@ -536,9 +591,10 @@ typedef struct { **/ UINT8 ProbelessTrace; -/** Offset 0x01EF - Reserved +/** Offset 0x01EF - IbeccEccInjCount + Number of memory transactions between ECC error injection **/ - UINT8 Reserved10; + UINT8 IbeccEccInjCount; /** Offset 0x01F0 - DDR Frequency Limit Maximum Memory Frequency Selections in Mhz. Options are 1067, 1333, 1600, 1867, @@ -676,9 +732,11 @@ typedef struct { **/ UINT8 TXDQSDCC; -/** Offset 0x0213 - Reserved +/** Offset 0x0213 - Rx DQS Duty Cycle Correction + Enables/Disable Rx DQS Duty Cycle Correction + $EN_DIS **/ - UINT8 Reserved11; + UINT8 RXDQSDCC; /** Offset 0x0214 - Ch Hash Override Select if Channel Hash setting values will be taken from input parameters or automatically @@ -687,9 +745,17 @@ typedef struct { **/ UINT8 ChHashOverride; -/** Offset 0x0215 - Reserved +/** Offset 0x0215 - Voltage Readout + Enables/Disable Voltage Readout for VCCClk and PBias + $EN_DIS +**/ + UINT8 VoltageReadout; + +/** Offset 0x0216 - DQS Rise/Fall + Enables/Disable DQS Rise/Fall + $EN_DIS **/ - UINT8 Reserved12[2]; + UINT8 DQSRF; /** Offset 0x0217 - DQS Rise/Fall Enables/Disable DQS Rise/Fall @@ -697,9 +763,17 @@ typedef struct { **/ UINT8 RDDQSODTT; -/** Offset 0x0218 - Reserved +/** Offset 0x0218 - PreTraining + Enables/Disable PreTraining + $EN_DIS +**/ + UINT8 PRETRAIN; + +/** Offset 0x0219 - DUNIT Configuration + Enables/Disable Dunit Configuration + $EN_DIS **/ - UINT8 Reserved13[2]; + UINT8 DUNITC; /** Offset 0x021A - Functional Duty Cycle Correction for DDR5 CLK Enable/Disable Functional Duty Cycle Correction for DDR5 CLK @@ -729,9 +803,11 @@ typedef struct { **/ UINT8 DQDQSSWZ; -/** Offset 0x021F - Reserved +/** Offset 0x021F - LP5 Dca Training + Enable/Disable LP5 Dca Training + $EN_DIS **/ - UINT8 Reserved14; + UINT8 DCCLP5READDCA; /** Offset 0x0220 - Functional Duty Cycle Correction for Data DQ Enable/Disable Functional Duty Cycle Correction for Data DQ @@ -739,9 +815,39 @@ typedef struct { **/ UINT8 FUNCDCCDQ; -/** Offset 0x0221 - Reserved +/** Offset 0x0221 - SubCh Hash Override + Select if SubChannel Hash setting values will be taken from input parameters or + automatically taken from POR values depending on DRAM type detected. NOTE: ONLY + if Memory interleaved Mode + $EN_DIS +**/ + UINT8 SubChHashOverride; + +/** Offset 0x0222 - DDR5 Auto Precharge Enable + Auto Precharge Enable for DDR5: O=Auto, 1=Disable, 2=Enable + $EN_DIS +**/ + UINT8 Ddr5AutoPrechargeEnable; + +/** Offset 0x0223 - Lp5 SplitACT Enable + SplitACT enable for LP5 + 0:Auto, 1:Disable, 2:Enable +**/ + UINT8 Lp5SplitACTEnable; + +/** Offset 0x0224 - CCC Half Frequency + CCC Half Frequency (CccGear4) Mode: 0 = Auto (Default), 1 = Disable, 2 = GroupGv0 + (SaGv0 only), 3 = GroupGv1 (Up to SaGv1), 4 = GroupGv2 (Up to SaGv2), 5 = GroupGv3 + (Up to SaGv3) + 0: Auto, 1: Disable, 2: GroupGv0, 3: GroupGv1, 4: GroupGv2, 5: GroupGv3 **/ - UINT8 Reserved15[5]; + UINT8 CccHalfFrequency; + +/** Offset 0x0225 - DIMM Non-Target ODT Training + Enables/Disable DIMM Non-Target ODT Training + $EN_DIS +**/ + UINT8 DIMMNTODT; /** Offset 0x0226 - Unmatched Rx Calibration Enable/Disable Rx Unmatched Calibration @@ -749,9 +855,60 @@ typedef struct { **/ UINT8 RXUNMATCHEDCAL; -/** Offset 0x0227 - Reserved +/** Offset 0x0227 - Hard Post Package Repair + Deprecated + $EN_DIS +**/ + UINT8 PPR; + +/** Offset 0x0228 - PPR Test Type + Deprecated +**/ + UINT8 PprTestType; + +/** Offset 0x0229 - PPR Run Once + When Eanble, PPR will run only once and then is disabled at next training cycle + $EN_DIS +**/ + UINT8 PprRunOnce; + +/** Offset 0x022A - PPR Run During Fastboot + Deprecated + $EN_DIS +**/ + UINT8 PprRunAtFastboot; + +/** Offset 0x022B - PPR Repair Type + PPR Repair Type: 0:Do not Repair (Default), 1:Soft Repair, 2:Hard Repair + 0:Do not Repair (Default), 1:Soft Repair, 2:Hard Repair +**/ + UINT8 PprRepairType; + +/** Offset 0x022C - PPR Error Injection + When Eanble, PPR will inject bad rows during testing + $EN_DIS +**/ + UINT8 PprErrorInjection; + +/** Offset 0x022D - PPR Repair Controller + Deprecated +**/ + UINT8 PprRepairController; + +/** Offset 0x022E - PPR Repair Channel + Deprecated +**/ + UINT8 PprRepairChannel; + +/** Offset 0x022F - PPR Repair Dimm + Deprecated +**/ + UINT8 PprRepairDimm; + +/** Offset 0x0230 - PPR Repair Rank + Deprecated **/ - UINT8 Reserved16[10]; + UINT8 PprRepairRank; /** Offset 0x0231 - Memory Slice Hash LSB Bit Memory Slice (Controller) Hash LSB bit. Valid values are 0..7 for BITS 6..13; used @@ -766,9 +923,25 @@ typedef struct { **/ UINT16 MsHashMask; -/** Offset 0x0234 - Reserved +/** Offset 0x0234 - PPR Repair Row + Deprecated +**/ + UINT32 PprRepairRow; + +/** Offset 0x0238 - PPR Repair Physical Address Low + Deprecated +**/ + UINT32 PprRepairPhysicalAddrLow; + +/** Offset 0x023C - PPR Repair Physical Address High + Deprecated +**/ + UINT32 PprRepairPhysicalAddrHigh; + +/** Offset 0x0240 - PPR Repair BankGroup + Deprecated **/ - UINT8 Reserved17[13]; + UINT8 PprRepairBankGroup; /** Offset 0x0241 - LVR Auto Trim Enable/disable LVR Auto Trim @@ -788,9 +961,23 @@ typedef struct { **/ UINT8 WRTRETRAIN; -/** Offset 0x0244 - Reserved +/** Offset 0x0244 - DCC Phase Clk Calibration + Enable/disable DCC Phase Clk Calibration + $EN_DIS +**/ + UINT8 PHASECLKCAL; + +/** Offset 0x0245 - DCC Tline Clk Calibration + Enable/disable DCC Tline Clk Calibration + $EN_DIS +**/ + UINT8 TLINECLKCAL; + +/** Offset 0x0246 - DCC Tline Serializer Calibration + Enable/disable DCC PI Serializer Calibratio + $EN_DIS **/ - UINT8 Reserved18[3]; + UINT8 DCCPISERIALCAL; /** Offset 0x0247 - RDDQODTT Enable/disable Read DQ ODT Training @@ -1000,9 +1187,11 @@ typedef struct { **/ UINT8 TAT; -/** Offset 0x026A - Reserved +/** Offset 0x026A - Rmt Even Odd + Enables/Disable Rmt Even Odd + $EN_DIS **/ - UINT8 Reserved19; + UINT8 RMTEVENODD; /** Offset 0x026B - DIMM SPD Alias Test Enables/Disable DIMM SPD Alias Test @@ -1028,9 +1217,17 @@ typedef struct { **/ UINT8 EccSupport; -/** Offset 0x026F - Reserved +/** Offset 0x026F - DLL DCC Calibration + Enables/Disable DLL DCC Calibration + $EN_DIS +**/ + UINT8 DLLDCC; + +/** Offset 0x0270 - DLL BW Select Calibration + Enables/Disable DLL BW Select Calibration + $EN_DIS **/ - UINT8 Reserved20[2]; + UINT8 DLLBWSEL; /** Offset 0x0271 - Ibecc In-Band ECC Support @@ -1044,9 +1241,11 @@ typedef struct { **/ UINT8 IbeccParity; -/** Offset 0x0273 - Reserved +/** Offset 0x0273 - MsHashEnable + Controller Hash Enable: 0=Disable, 1=Enable + $EN_DIS **/ - UINT8 Reserved21; + UINT8 MsHashEnable; /** Offset 0x0274 - IbeccOperationMode In-Band ECC Operation Mode @@ -1062,7 +1261,7 @@ typedef struct { /** Offset 0x027D - Reserved **/ - UINT8 Reserved22; + UINT8 Reserved3; /** Offset 0x027E - IbeccProtectedRegionBases IBECC Protected Region Bases per IBECC instance @@ -1135,9 +1334,17 @@ typedef struct { **/ UINT8 ExitOnFailure; -/** Offset 0x02A8 - Reserved +/** Offset 0x02A8 - Wck Pad DCC Calibration + Enable/disable Wck Pad DCC Calibration + $EN_DIS +**/ + UINT8 WCKPADDCCCAL; + +/** Offset 0x02A9 - DCC PI Code LUT Calibration + Enable/Disable DCC PI Code LUT Calibration + $EN_DIS **/ - UINT8 Reserved23[2]; + UINT8 DCCPICODELUT; /** Offset 0x02AA - Read Voltage Centering 1D Enable/Disable Read Voltage Centering 1D @@ -1223,9 +1430,11 @@ typedef struct { **/ UINT8 RowPressEn; -/** Offset 0x02B8 - Reserved +/** Offset 0x02B8 - DBI feature + Enables/Disable DBI feature + $EN_DIS **/ - UINT8 Reserved24; + UINT8 DBI; /** Offset 0x02B9 - DDR5 MR7 WICA support Enable if DDR5 DRAM Device supports MR7 WICA 0.5 tCK offset alignment @@ -1252,9 +1461,10 @@ typedef struct { **/ UINT16 ChHashMask; -/** Offset 0x02BE - Reserved +/** Offset 0x02BE - CccPinsInterleaved + Interleaving mode of CCC pins which depends on board routing: 0=Disable, 1=Enable **/ - UINT8 Reserved25; + UINT8 CccPinsInterleaved; /** Offset 0x02BF - Throttler CKEMin Timer Timer value for CKEMin, range[255;0]. Req'd min of SC_ROUND_T + BYTE_LENGTH (4). @@ -1333,7 +1543,12 @@ typedef struct { /** Offset 0x02CB - Reserved **/ - UINT8 Reserved26[5]; + UINT8 Reserved4; + +/** Offset 0x02CC - IbeccEccInjAddrBase + Address to match against for ECC error injection. Example: 1 = 32MB, 2 = 64MB +**/ + UINT32 IbeccEccInjAddrBase; /** Offset 0x02D0 - DDR Phy Safe Mode Support DdrSafeMode[0]: Basic PM Features, DdrSafeMode[1]: Spine Gating, DdrSafeMode[2]: @@ -1353,9 +1568,56 @@ typedef struct { **/ UINT8 CleanMemory; -/** Offset 0x02D6 - Reserved +/** Offset 0x02D6 - Tseg Retry Count + Tseg Retry count will increase based on TSEG Region Fail count + 0: Default, 1:3 +**/ + UINT8 RetryCount; + +/** Offset 0x02D7 - Mrc Ppr Status + Get Mrc PPR Status after PPR Recovery flow will get Trigger + 0: PASS, 1: FAIL(Default) +**/ + UINT8 MrcPprStatus; + +/** Offset 0x02D8 - Tseg Memory Test Status + If enabled, PPR Recovery flow will get Trigger + 0: PASS, 1: FAIL(Default) +**/ + UINT8 TsegMemoryTestStatus; + +/** Offset 0x02D9 - Ppr Recovery Status Enable + 0: Disabled(Default), 1: Enabled. If enabled, PPR Recovery flow will get Trigger. + $EN_DIS +**/ + UINT8 PprRecoveryStatusEnable; + +/** Offset 0x02DA - Safe Loading Bios Enable State + 0: Disabled(Default), 1: Enabled. If enabled, Memory diagnostic will perform for + TSEG Region. + $EN_DIS +**/ + UINT8 SafeLoadingBiosEnableState; + +/** Offset 0x02DB - BDAT test type + When BdatEnable is set to TRUE, this option selects the type of data which will + be populated in the BIOS Data ACPI Tables: 0=RMT, 1=RMT Per Bit, 2=Margin 2D. + 0:RMT per Rank, 1:RMT per Bit, 2:Margin2D +**/ + UINT8 MrcBdatTestType; + +/** Offset 0x02DC - MrcBdatEnable + 0: Disabled(Default), 1: Enabled. This field enables the generation of the BIOS + DATA ACPI Tables: 0=FALSE, 1=TRUE. + $EN_DIS +**/ + UINT8 MrcBdatEnable; + +/** Offset 0x02DD - DisableMrcRetraining + 0: Disabled(Default), 1: Enabled. Enable/Disable DisableMrcRetraining + $EN_DIS **/ - UINT8 Reserved27[8]; + UINT8 DisableMrcRetraining; /** Offset 0x02DE - RMTLoopCount Specifies the Loop Count to be used during Rank Margin Tool Testing. 0 - AUTO @@ -1391,7 +1653,7 @@ typedef struct { /** Offset 0x02E7 - Reserved **/ - UINT8 Reserved28; + UINT8 Reserved5; /** Offset 0x02E8 - Margin limit check L2 Margin limit check L2 threshold: 100=Default @@ -1404,9 +1666,12 @@ typedef struct { **/ UINT8 ExtendedBankHashing; -/** Offset 0x02EB - Reserved +/** Offset 0x02EB - DRFM Blast Radius Configuration + Row Hammer DRFM Blast Radius Configuration determines number of victim rows around + aggressor row targeted to send the DRFM sequence to: 2=BlastRadius 2, 3=BlastRadius + 3, 4=BlastRadius 4 **/ - UINT8 Reserved29; + UINT8 DrfmBrc; /** Offset 0x02EC - LP5 Command Pins Mapping BitMask where bits [3:0] are Controller 0 Channel [3:0] and bits [7:4] are Controller @@ -1426,9 +1691,73 @@ typedef struct { **/ UINT8 MrcTimeMeasure; -/** Offset 0x02EF - Reserved +/** Offset 0x02EF - DVFSQ Enabled + Enable/Disable DVFSQ + $EN_DIS +**/ + UINT8 DvfsqEnabled; + +/** Offset 0x02F0 - E-DVFSC Enabled + Eanble/Disable DVFSC + $EN_DIS +**/ + UINT8 DvfscEnabled; + +/** Offset 0x02F1 - Ddr5 Dca Training + Enable/Disable DDR5 Dca Training + $EN_DIS +**/ + UINT8 DCCDDR5READDCA; + +/** Offset 0x02F2 - PPR Run WCHMATS8 + Run WCHMATS8 in Post Package Repair flow +**/ + UINT8 PprRunWCHMATS8; + +/** Offset 0x02F3 - PPR Run Retention + Run Data Retention in Post Package Repair flow +**/ + UINT8 PprRunRetention; + +/** Offset 0x02F4 - PPR Run XMarch + Run XMarch in Post Package Repair flow +**/ + UINT8 PprRunXMarch; + +/** Offset 0x02F5 - PPR Run XMarchG + Run XMarchG in Post Package Repair flow +**/ + UINT8 PprRunXMarchG; + +/** Offset 0x02F6 - PPR Run YMarchShort + Run YMarchShort in Post Package Repair flow +**/ + UINT8 PprRunYMarchShort; + +/** Offset 0x02F7 - PPR Run YMarchLong + Run YMarchLong in Post Package Repair flow +**/ + UINT8 PprRunYMarchLong; + +/** Offset 0x02F8 - PPR Run Mmrw + Run Mmrw in Post Package Repair flow +**/ + UINT8 PprRunMmrw; + +/** Offset 0x02F9 - PPR Test Disabled + Don't run any test in Post Package Repair flow +**/ + UINT8 PprTestDisabled; + +/** Offset 0x02FA - PPR Entry Info + PPR Repair Info +**/ + UINT8 PprEntryInfo[16]; + +/** Offset 0x030A - PPR Entry Address + PPR Repair Memory Address **/ - UINT8 Reserved30[43]; + UINT8 PprEntryAddress[16]; /** Offset 0x031A - Read Vref Decap Training* Enable/Disable Read Timing Centering Training with SR stress* @@ -1454,9 +1783,15 @@ typedef struct { **/ UINT8 IsWckIdleExitEnabled; -/** Offset 0x031E - Reserved +/** Offset 0x031E - LP5 Safe Speed + Enable / Disable LP5 Safe Speed feature + $EN_DIS +**/ + UINT8 Lp5SafeSpeed; + +/** Offset 0x031F - Reserved **/ - UINT8 Reserved31[17]; + UINT8 Reserved6[16]; /** Offset 0x032F - Board Type MrcBoardType, Options are 0=Mobile/Mobile Halo, 1=Desktop/DT Halo, 5=ULT/ULX/Mobile @@ -1478,9 +1813,11 @@ typedef struct { **/ UINT8 TxtImplemented; -/** Offset 0x0341 - Reserved +/** Offset 0x0341 - PCIE Resizable BAR Support + Enable/Disable PCIE Resizable BAR Support.0: Disable; 1: Enable; 2: Auto(Default). + $EN_DIS **/ - UINT8 Reserved32; + UINT8 PcieResizableBarSupport; /** Offset 0x0342 - Skip external display device scanning Enable: Do not scan for external display device, Disable (Default): Scan external @@ -1608,7 +1945,7 @@ typedef struct { /** Offset 0x04D6 - Reserved **/ - UINT8 Reserved33[2]; + UINT8 Reserved7[2]; /** Offset 0x04D8 - DMIC ClkA Pin Muxing (N - DMIC number) Determines DMIC ClkA Pin muxing. See GPIO_*_MUXING_DMIC_CLKA_* @@ -1623,7 +1960,7 @@ typedef struct { /** Offset 0x04E1 - Reserved **/ - UINT8 Reserved34[3]; + UINT8 Reserved8[3]; /** Offset 0x04E4 - DMIC Data Pin Muxing Determines DMIC Data Pin muxing. See GPIO_*_MUXING_DMIC_DATA_* @@ -1635,9 +1972,35 @@ typedef struct { **/ UINT8 PchHdaAudioLinkSspEnable[7]; -/** Offset 0x04F3 - Reserved +/** Offset 0x04F3 - PCH Hda Disc Bt Off Enabled + Hda Disc Bt Off Enabled +**/ + UINT8 PchHdaDiscBtOffEnabled; + +/** Offset 0x04F4 - PCH HDA Discrete BT Offload Ssp Link + Discrete BT Offload Ssp Link +**/ + UINT32 PchHdaDiscBtOffSspLink; + +/** Offset 0x04F8 - SSP Sclk Pin Muxing (N - SSP Number) + Determines SSP Sclk Pin muxing. See GPIOV2_*_MUXING_I2S*_SCLK +**/ + UINT32 PchHdaAudioLinkSspSclkPinMux[7]; + +/** Offset 0x0514 - SSP Sfmr Pin Muxing (N - SSP Number) + Determines SSP Sfmr Pin muxing. See GPIOV2_*_MUXING_I2S*_SFMR +**/ + UINT32 PchHdaAudioLinkSspSfmrPinMux[7]; + +/** Offset 0x0530 - SSP Txd Pin Muxing (N - SSP Number) + Determines SSP Txd Pin muxing. See GPIOV2_*_MUXING_I2S*_TXD +**/ + UINT32 PchHdaAudioLinkSspTxdPinMux[7]; + +/** Offset 0x054C - SSP Rxd Pin Muxing (N - SSP Number) + Determines SSP Rxd Pin muxing. See GPIOV2_*_MUXING_I2S*_RXD **/ - UINT8 Reserved35[117]; + UINT32 PchHdaAudioLinkSspRxdPinMux[7]; /** Offset 0x0568 - Enable HD Audio SoundWire#N Link Enable/disable HD Audio SNDW#N link. Muxed with HDA. @@ -1656,9 +2019,41 @@ typedef struct { **/ UINT8 PchHdaIDispLinkTmode; -/** Offset 0x056F - Reserved +/** Offset 0x056F - Sndw Multilane enablement + SoundWire Multiline enablement. Default is DISABLE. 0: DISABLE, 1: Two lines enabled, + 2: Three lines enabled, 3: Four Lines enabled. + $EN_DIS +**/ + UINT8 PchHdAudioSndwMultilaneEnable[2]; + +/** Offset 0x0571 - Reserved +**/ + UINT8 Reserved9[3]; + +/** Offset 0x0574 - SoundWire Clk Pin Muxing (N - SoundWire number) + Determines SoundWire Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_CLK* +**/ + UINT32 PchHdaAudioLinkMultilaneClkPinMux[2]; + +/** Offset 0x057C - SoundWire Multilane Data0 Pin Muxing (N - SoundWire number) + Determines SoundWire Multilane Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_DATA0* +**/ + UINT32 PchHdaAudioLinkMultilaneData0PinMux[2]; + +/** Offset 0x0584 - SoundWire Multilane Data1 Pin Muxing (N - SoundWire number) + Determines SoundWire Multilane Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_DATA1* +**/ + UINT32 PchHdaAudioLinkMultilaneData1PinMux[2]; + +/** Offset 0x058C - SoundWire Multilane Data2 Pin Muxing (N - SoundWire number) + Determines SoundWire Multilane Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_DATA2* +**/ + UINT32 PchHdaAudioLinkMultilaneData2PinMux[2]; + +/** Offset 0x0594 - SoundWire Multilane Data3 Pin Muxing (N - SoundWire number) + Determines SoundWire Multilane Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_DATA3* **/ - UINT8 Reserved36[45]; + UINT32 PchHdaAudioLinkMultilaneData3PinMux[2]; /** Offset 0x059C - iDisplay Audio Codec disconnection 0: Not disconnected, enumerable, 1: Disconnected SDI, not enumerable. @@ -1666,9 +2061,20 @@ typedef struct { **/ UINT8 PchHdaIDispCodecDisconnect; -/** Offset 0x059D - Reserved +/** Offset 0x059D - Sndw Interface for Multilanes (N - SoundWire number) + 0: Not disconnected, enumerable, 1: Disconnected SDI, not enumerable. + 0: Sndw0, 1: Sndw1, 2: Sndw2, 3: Sndw3, 4: Sndw4, 5: Sndw5 +**/ + UINT8 PchHdAudioSndwMultilaneSndwInterface[2]; + +/** Offset 0x059F - Reserved **/ - UINT8 Reserved37[5]; + UINT8 Reserved10; + +/** Offset 0x05A0 - Audio Sub System IDs + Set default Audio Sub System IDs. If its set to 0 then value from Strap is used. +**/ + UINT16 ResetWaitTimer; /** Offset 0x05A2 - HDA Power/Clock Gating (PGD/CGD) Enable/Disable HD Audio Power and Clock Gating(POR: Enable). 0: PLATFORM_POR, 1: @@ -1677,18 +2083,22 @@ typedef struct { **/ UINT8 PchHdaTestPowerClockGating; -/** Offset 0x05A3 - Reserved +/** Offset 0x05A3 - Low Frequency Link Clock Source (LFLCS) + 0: POR (Enable), 1: Enable (XTAL), 2: Disable (Audio PLL). + 0: POR (Enable), 1: Enable (XTAL), 2: Disable (Audio PLL) **/ - UINT8 Reserved38; + UINT8 PchHdaTestLowFreqLinkClkSrc; /** Offset 0x05A4 - Audio Sub System IDs Set default Audio Sub System IDs. If its set to 0 then value from Strap is used. **/ UINT32 PchHdaSubSystemIds; -/** Offset 0x05A8 - Reserved +/** Offset 0x05A8 - SoundWire clock source select + Select clock source for the SoundWire controllers. 0: XTAL, 1: Audio PLL. + $EN_DIS **/ - UINT8 Reserved39; + UINT8 PchHdaSndwClockSourceSelect; /** Offset 0x05A9 - PCH LPC Enhance the port 8xh decoding Original LPC only decodes one byte of port 80h. @@ -1708,7 +2118,12 @@ typedef struct { /** Offset 0x05CE - Reserved **/ - UINT8 Reserved40[46]; + UINT8 Reserved11[14]; + +/** Offset 0x05DC - Clk Req GPIO Pin + Select Clk Req Pin. Refer to GPIO_*_MUXING_SRC_CLKREQ_x* for possible values. +**/ + UINT32 PcieClkReqGpioMux[8]; /** Offset 0x05FC - Enable PCIE RP Mask Enable/disable PCIE Root Ports. 0: disable, 1: enable. One bit for each port, bit0 @@ -1724,7 +2139,7 @@ typedef struct { /** Offset 0x0601 - Reserved **/ - UINT8 Reserved41[3]; + UINT8 Reserved12[3]; /** Offset 0x0604 - Serial Io Uart Debug Mmio Base Select SerialIo Uart default MMIO resource in SEC/PEI phase when PcdLpssUartMode @@ -1799,9 +2214,13 @@ typedef struct { **/ UINT8 WdtDisableAndLock; -/** Offset 0x061A - Reserved +/** Offset 0x061A **/ - UINT8 Reserved42[2]; + UINT8 FabricGVDisable; + +/** Offset 0x061B - Reserved +**/ + UINT8 Reserved13; /** Offset 0x061C - HECI Timeouts 0: Disable, 1: Enable (Default) timeout check for HECI @@ -1852,9 +2271,18 @@ typedef struct { **/ UINT8 SkipMbpHob; -/** Offset 0x0624 - Reserved +/** Offset 0x0624 - HECI Communication + Test, 0: POR, 1: enable, 2: disable, Disables HECI communication causing ME to enter + error state. + $EN_DIS +**/ + UINT8 HeciCommunication; + +/** Offset 0x0625 - HECI3 Interface Communication + Test, 0: POR, 1: enable, 2: disable, Adds or Removes HECI3 Device from PCI space. + $EN_DIS **/ - UINT8 Reserved43[2]; + UINT8 HeciCommunication3; /** Offset 0x0626 - ISA Serial Base selection Select ISA Serial Base address. Default is 0x3F8. @@ -1873,9 +2301,47 @@ typedef struct { **/ UINT16 PostCodeOutputPort; -/** Offset 0x062A - Reserved +/** Offset 0x062A - Enable/Disable I2cPostcode + Enable (Default): Postcode via I2C, Disable: Postcode via Port80 + $EN_DIS +**/ + UINT8 I2cPostCodeEnable; + +/** Offset 0x062B - Reserved +**/ + UINT8 Reserved14[5]; + +/** Offset 0x0630 - FSPM Validation Pointer + Point to FSPM Validation configuration structure +**/ + UINT64 FspmValidationPtr; + +/** Offset 0x0638 - Extended BIOS Support + Enable/Disable Extended BIOS Region Support. Default is DISABLE. 0: DISABLE, 1: ENABLE + $EN_DIS +**/ + UINT8 ExtendedBiosDecodeRange; + +/** Offset 0x0639 - Extented BIOS Direct Read Decode enable + Enable/Disable access to bigger than 16MB BIOS Region through Direct Memory Reads. + 0: disabled (default), 1: enabled + $EN_DIS +**/ + UINT8 PchSpiExtendedBiosDecodeRangeEnable; + +/** Offset 0x063A - Reserved +**/ + UINT8 Reserved15[2]; + +/** Offset 0x063C - Extended BIOS Direct Read Decode Range base + Bits of 31:16 of a memory address that'll be a base for Extended BIOS Direct Read Decode. +**/ + UINT32 PchSpiExtendedBiosDecodeRangeBase; + +/** Offset 0x0640 - Extended BIOS Direct Read Decode Range limit + Bits of 31:16 of a memory address that'll be a limit for Extended BIOS Direct Read Decode. **/ - UINT8 Reserved44[26]; + UINT32 PchSpiExtendedBiosDecodeRangeLimit; /** Offset 0x0644 - Enable SMBus Enable/disable SMBus controller. @@ -1896,7 +2362,7 @@ typedef struct { /** Offset 0x0647 - Reserved **/ - UINT8 Reserved45; + UINT8 Reserved16; /** Offset 0x0648 - SMBUS Base Address SMBUS Base Address (IO space). @@ -1911,7 +2377,7 @@ typedef struct { /** Offset 0x064B - Reserved **/ - UINT8 Reserved46[13]; + UINT8 Reserved17[13]; /** Offset 0x0658 - Smbus dynamic power gating Disable or Enable Smbus dynamic power gating. @@ -1932,9 +2398,51 @@ typedef struct { **/ UINT8 SaOcSupport; -/** Offset 0x065B - Reserved +/** Offset 0x065B - VF Point Count + Number of supported Voltage & Frequency Point Offset +**/ + UINT8 VfPointCount[10]; + +/** Offset 0x0665 - ProcessVmaxLimit + Disabling Process Vmax Limit will allow user to set any voltage +**/ + UINT8 ProcessVmaxLimit; + +/** Offset 0x0666 - CorePllCurrentRefTuningOffset + Core PLL Current Reference Tuning Offset. 0: No offset. Range 0-15 +**/ + UINT8 CorePllCurrentRefTuningOffset; + +/** Offset 0x0667 - RingPllCurrentRefTuningOffset + Ring PLL Current Reference Tuning Offset. 0: No offset. Range 0-15 +**/ + UINT8 RingPllCurrentRefTuningOffset; + +/** Offset 0x0668 - IaAtomPllCurrentRefTuningOffset + IaAtom PLL Current Reference Tuning Offset. 0: No offset. Range 0-15 +**/ + UINT8 IaAtomPllCurrentRefTuningOffset; + +/** Offset 0x0669 - CoreMinRatio + equest Core Min Ratio. Limit Core minimum ratio for extreme overclocking. Default + 0 indicates no request +**/ + UINT8 CoreMinRatio; + +/** Offset 0x066A - CoreMiNegativeTemperatureReportingnRatio + Negative Temperature Reporting Enable. 0: Disable, 1: enable +**/ + UINT8 NegativeTemperatureReporting; + +/** Offset 0x066B - PcorePowerDensityThrottle + Power Density Throttle control allows user to disable P-core +**/ + UINT8 PcorePowerDensityThrottle; + +/** Offset 0x066C - EcorePowerDensityThrottle + Power Density Throttle control allows user to disable P-core **/ - UINT8 Reserved47[18]; + UINT8 EcorePowerDensityThrottle; /** Offset 0x066D - Over clocking support Over clocking support; 0: Disable; 1: Enable @@ -1942,9 +2450,12 @@ typedef struct { **/ UINT8 OcSupport; -/** Offset 0x066E - Reserved +/** Offset 0x066E - UnderVolt Protection + When UnderVolt Protection is enabled, user will be not be able to program under + voltage in OS runtime. 0: Disabled; 1: Enabled + $EN_DIS **/ - UINT8 Reserved48; + UINT8 UnderVoltProtection; /** Offset 0x066F - Realtime Memory Timing 0(Default): Disabled, 1: Enabled. When enabled, it will allow the system to perform @@ -2005,9 +2516,18 @@ typedef struct { **/ UINT8 Lfsr1Mask; -/** Offset 0x067B - Reserved +/** Offset 0x067B - Row Hammer DRAM Refresh Management Mode + Row Hammer Adaptive Refresh Management Level: 0-RFM (default), 1-ARFMLevel A, 2-ARFMLevel + B, 3-ARFMLevel C, 4-Disable ARFM and RFM + 0: RFM, 1: ARFM Level A, 2: ARFM Level B, 3: ARFM Level C, 4: ARFM and RFM Disabled +**/ + UINT8 DramRfmMode; + +/** Offset 0x067C - Row Hammer Targeted Row Refresh Mode + Row Hammer Targeted Row Refresh: 0-DRFM, 1-pTRR (default), 2-Disable DRFM and pTRR + 0: DRFM, 1: pTRR, 2: Targeted Row Refresh Disabled **/ - UINT8 Reserved49[2]; + UINT8 TargetedRowRefreshMode; /** Offset 0x067D - TjMax Offset TjMax offset.Specified value here is clipped by pCode (125 - TjMax Offset) to support @@ -2015,9 +2535,27 @@ typedef struct { **/ UINT8 TjMaxOffset; -/** Offset 0x067E - Reserved +/** Offset 0x067E - Per-Atom-Cluster VF Offset + Array used to specifies the selected Atom Core Cluster Offset Voltage. This voltage + is specified in millivolts. +**/ + UINT16 PerAtomClusterVoltageOffset[8]; + +/** Offset 0x068E - Per-Atom-Cluster VF Offset Prefix + Sets the PerAtomCLusterVoltageOffset value as positive or negative for the selected + Core; 0: Positive ; 1: Negative. +**/ + UINT8 PerAtomClusterVoltageOffsetPrefix[8]; + +/** Offset 0x0696 - Per-Atom-Cluster Voltage Mode + Array used to specifies the selected Atom Core ClusterVoltage Mode. +**/ + UINT8 PerAtomClusterVoltageMode[8]; + +/** Offset 0x069E - Per-Atom-Cluster Voltage Override + Array used to specifies the selected Atom Core Cluster Voltage Override. **/ - UINT8 Reserved50[48]; + UINT16 PerAtomClusterVoltageOverride[8]; /** Offset 0x06AE - Core VF Point Offset Array used to specifies the Core Voltage Offset applied to the each selected VF @@ -2037,9 +2575,28 @@ typedef struct { **/ UINT8 CoreVfPointRatio[15]; -/** Offset 0x06EA - Reserved +/** Offset 0x06EA - Core VF Configuration Scope + Allows both all-core VF curve or per-core VF curve configuration; 0: All-core; + 1: Per-core. + 0:All-core, 1:Per-core +**/ + UINT8 CoreVfConfigScope; + +/** Offset 0x06EB - Reserved +**/ + UINT8 Reserved18; + +/** Offset 0x06EC - Per-core VF Offset + Array used to specifies the selected Core Offset Voltage. This voltage is specified + in millivolts. +**/ + UINT16 PerCoreVoltageOffset[8]; + +/** Offset 0x06FC - Per-core VF Offset Prefix + Sets the PerCoreVoltageOffset value as positive or negative for the selected Core; + 0: Positive ; 1: Negative. **/ - UINT8 Reserved51[26]; + UINT8 PerCoreVoltageOffsetPrefix[8]; /** Offset 0x0704 - Per Core Max Ratio override Enable or disable Per Core PState OC supported by writing OCMB 0x1D to program new @@ -2048,18 +2605,30 @@ typedef struct { **/ UINT8 PerCoreRatioOverride; -/** Offset 0x0705 - Reserved +/** Offset 0x0705 - Per-core Voltage Mode + Array used to specifies the selected Core Voltage Mode. +**/ + UINT8 PerCoreVoltageMode[8]; + +/** Offset 0x070D - Reserved +**/ + UINT8 Reserved19; + +/** Offset 0x070E - Per-core Voltage Override + Array used to specifies the selected Core Voltage Override. **/ - UINT8 Reserved52[25]; + UINT16 PerCoreVoltageOverride[8]; /** Offset 0x071E - Per Core Current Max Ratio Array for the Per Core Max Ratio **/ UINT8 PerCoreRatio[8]; -/** Offset 0x0726 - Reserved +/** Offset 0x0726 - Atom Cluster Max Ratio + Array for Atom Cluster Max Ratio, 4 ATOM cores are in the same Cluster and their + max core ratio will be aligned. **/ - UINT8 Reserved53[8]; + UINT8 AtomClusterRatio[8]; /** Offset 0x072E - Pvd Ratio Threshold for SOC/CPU die Array of Pvd Ratio Threshold for SOC/CPU die is the threshold value for input ratio @@ -2070,34 +2639,92 @@ typedef struct { **/ UINT8 PvdRatioThreshold; -/** Offset 0x072F - Reserved +/** Offset 0x072F - Pvd Mode SOC/CPU die + Array of PVD Mode. Value from 0 to 3 for SOC/CPU. 0x0 = div-1 (VCO = Output clock), + 0x1 = div-2 (VCO = 2x Output clock), 0x2 = div-4 (VCO = 4x Output clock), 0x3 = + div-8 (VCO = 8x Output clock). **/ - UINT8 Reserved54[65]; + UINT8 PvdMode; -/** Offset 0x0770 - CPU BCLK OC Frequency - CPU BCLK OC Frequency in KHz units. 98000000Hz = 98MHz 0 - Auto. Range is - 40Mhz-1000Mhz. +/** Offset 0x0730 - FLL Overclock Mode + Select FLL Mode Value from 0 to 3. 0x0 = no overclocking, 0x1 = ratio overclocking + with nominal (0.5-1x) reference clock frequency, 0x2 = BCLK overclocking with elevated + (1-3x) reference clock frequency, 0x3 = BCLK overclocking with extreme elevated + (3-5x) reference clock frequency and ratio limited to 63. **/ - UINT32 CpuBclkOcFrequency; + UINT8 FllOverclockMode; -/** Offset 0x0774 - Reserved +/** Offset 0x0731 - Reserved **/ - UINT8 Reserved55[13]; + UINT8 Reserved20; -/** Offset 0x0781 - Avx2 Voltage Guardband Scaling Factor - AVX2 Voltage Guardband Scale factor applied to AVX2 workloads. Range is 0-200 in - 1/100 units, where a value of 125 would apply a 1.25 scale factor. +/** Offset 0x0732 - Ring VF Point Offset + Array used to specifies the Ring Voltage Offset applied to the each selected VF + Point. This voltage is specified in millivolts. **/ - UINT8 Avx2VoltageScaleFactor; + UINT16 RingVfPointOffset[15]; -/** Offset 0x0782 - Ring PLL voltage offset - Core PLL voltage offset. 0: No offset. Range 0-15 +/** Offset 0x0750 - Ring VF Point Offset Prefix + Sets the RingVfPointOffset value as positive or negative for corresponding core + VF Point; 0: Positive ; 1: Negative. +**/ + UINT8 RingVfPointOffsetPrefix[15]; + +/** Offset 0x075F - Ring VF Point Ratio + Array for the each selected Ring VF Point to display the ration. +**/ + UINT8 RingVfPointRatio[15]; + +/** Offset 0x076E - Soc Die SSC enable + Enable/Disable Soc-Die SSC Configuration. 0(Default)=Disable, 1=Enable + $EN_DIS +**/ + UINT8 SocDieSscEnable; + +/** Offset 0x076F - Core Operating Point Reporting + Enables Core Operating point reporting. 0: Disable; 1: Enable + 0:Disable, 1:Enable +**/ + UINT8 CoreOpPointReportingEn; + +/** Offset 0x0770 - CPU BCLK OC Frequency + CPU BCLK OC Frequency in KHz units. 98000000Hz = 98MHz 0 - Auto. Range is + 40Mhz-1000Mhz. +**/ + UINT32 CpuBclkOcFrequency; + +/** Offset 0x0774 - SOC BCLK OC Frequency + SOC BCLK OC Frequency in KHz units. 98000000Hz = 98MHz 0 - Auto. Range is + 40Mhz-1000Mhz. +**/ + UINT32 SocBclkOcFrequency; + +/** Offset 0x0778 - Bitmask of disable cores + Core mask is a bitwise indication of which core should be disabled. 0x00=Default; + Bit 0 - core 0, bit 7 - core 7. +**/ + UINT64 DisablePerCoreMask; + +/** Offset 0x0780 - Granular Ratio Override + Enable or disable OC Granular Ratio Override. 0: Disable, 1: enable + $EN_DIS +**/ + UINT8 GranularRatioOverride; + +/** Offset 0x0781 - Avx2 Voltage Guardband Scaling Factor + AVX2 Voltage Guardband Scale factor applied to AVX2 workloads. Range is 0-200 in + 1/100 units, where a value of 125 would apply a 1.25 scale factor. +**/ + UINT8 Avx2VoltageScaleFactor; + +/** Offset 0x0782 - Ring PLL voltage offset + Core PLL voltage offset. 0: No offset. Range 0-15 **/ UINT8 RingPllVoltageOffset; /** Offset 0x0783 - Reserved **/ - UINT8 Reserved56[5]; + UINT8 Reserved21[5]; /** Offset 0x0788 - Enable PCH ISH Controller 0: Disable, 1: Enable (Default) ISH Controller @@ -2107,7 +2734,7 @@ typedef struct { /** Offset 0x0789 - Reserved **/ - UINT8 Reserved57; + UINT8 Reserved22; /** Offset 0x078A - BiosSize The size of the BIOS region of the IFWI. Used if FspmUpd->FspmConfig.BiosGuard != @@ -2140,9 +2767,24 @@ typedef struct { **/ UINT8 SkipStopPbet; -/** Offset 0x0790 - Reserved +/** Offset 0x0790 - Reset Auxiliary content + Reset Auxiliary content, 0: Disabled, 1: Enabled + $EN_DIS +**/ + UINT8 ResetAux; + +/** Offset 0x0791 - TseEnable + Enable/Disable. 0: Disable, Enable/Disable Tse feature, 1: enable + $EN_DIS +**/ + UINT8 TseEnable; + +/** Offset 0x0792 - Enable or Disable TDX + Configure Trust Domain Extension (TDX) to isolate VMs from Virtual-Machine Manager + (VMM)/hypervisor 0: Disable; 1: Enable. + $EN_DIS **/ - UINT8 Reserved58[3]; + UINT8 TdxEnable; /** Offset 0x0793 - MKTME Key-Id Bits Override Enable Configure Trust Domain Extension (TDX) to isolate VMs from Virtual-Machine Manager @@ -2153,7 +2795,7 @@ typedef struct { /** Offset 0x0794 - Reserved **/ - UINT8 Reserved59[4]; + UINT8 Reserved23[4]; /** Offset 0x0798 - TME Exclude Base Address TME Exclude Base Address. @@ -2165,9 +2807,26 @@ typedef struct { **/ UINT64 TmeExcludeSize; -/** Offset 0x07A8 - Reserved +/** Offset 0x07A8 - TdxActmModuleAddr + Base address of Tdx Actm module, used for launching the Actm +**/ + UINT64 TdxActmModuleAddr; + +/** Offset 0x07B0 - TdxActmModuleSize + size of Tdx Actm module, used for launching the Actm +**/ + UINT32 TdxActmModuleSize; + +/** Offset 0x07B4 - TdxSeamldrSvn + TdxSeamldrSvn +**/ + UINT8 TdxSeamldrSvn; + +/** Offset 0x07B5 - Boot max frequency + Enable Boot Maximum Frequency in CPU strap. 0: Disable; 1: Enable + $EN_DIS **/ - UINT8 Reserved60[14]; + UINT8 BootMaxFrequency; /** Offset 0x07B6 - BIST on Reset Enable/Disable BIST (Built-In Self Test) on reset. 0: Disable; 1: Enable. @@ -2175,9 +2834,11 @@ typedef struct { **/ UINT8 BistOnReset; -/** Offset 0x07B7 - Reserved +/** Offset 0x07B7 - Reduce XeCores + Enable/Disable Reduce XeCores. 0: Disable(strap=1) ; 1: Enable(strap=0. + $EN_DIS **/ - UINT8 Reserved61; + UINT8 ReduceXecores; /** Offset 0x07B8 - Enable or Disable VMX Enable or Disable VMX, When enabled, a VMM can utilize the additional hardware capabilities @@ -2245,9 +2906,29 @@ typedef struct { **/ UINT8 ActiveCoreCount; -/** Offset 0x07C2 - Reserved +/** Offset 0x07C2 - Number of active small cores + Number of E-cores to enable in each processor package. Note: Number of P-Cores and + E-Cores are looked at together. When both are {0,0 + 0:Disable all small cores, 1:1, 2:2, 3:3, 0xFF:Active all small cores +**/ + UINT8 ActiveSmallCoreCount; + +/** Offset 0x07C3 - Number of LP Atom cores + Number of LP E-cores to enable in LP. 0: Disable all LP Atom cores; 1: 1; 2: 2; + 0xFF: Active all LP Atom cores + 0:Disable all LP Atom cores, 1:1, 2:2, 0xFF:Active all cores +**/ + UINT8 ActiveLpAtomCoreCount; + +/** Offset 0x07C4 - DFD Enable + Enable or Disable DFD. 0: Disable, 1:Enable + $EN_DIS +**/ + UINT8 DfdEnable; + +/** Offset 0x07C5 - Reserved **/ - UINT8 Reserved62[6]; + UINT8 Reserved24[3]; /** Offset 0x07C8 - PrmrrSize Enable/Disable. 0: Disable, define default value of PrmrrSize , 1: enable @@ -2275,7 +2956,351 @@ typedef struct { /** Offset 0x07D2 - Reserved **/ - UINT8 Reserved63[98]; + UINT8 Reserved25[2]; + +/** Offset 0x07D4 - Platform PL1 power + Platform Power Limit 1 Power in Milli Watts. BIOS will round to the nearest 1/8W + when programming. Value set 120 = 15W. Any value can be programmed between Max + and Min Power Limits. This setting will act as the new PL1 value for the Package + RAPL algorithm. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. Valid Range + 0 to 32767. +**/ + UINT32 PsysPowerLimit1Power; + +/** Offset 0x07D8 - PlatformAtxTelemetryUnit Mode + Enable/Disable PlatformAtxTelemetryUnit Mode. 0: Disable ; 1:Enable + $EN_DIS +**/ + UINT32 PlatformAtxTelemetryUnit; + +/** Offset 0x07DC - Platform PL1 power + Short term Power Limit value for custom cTDP level. Units are 125 milliwatt. +**/ + UINT16 CustomPowerLimit1; + +/** Offset 0x07DE - Platform PL1 power + Short term Power Limit value for custom cTDP level. Units are 125 milliwatt. +**/ + UINT16 CustomPowerLimit2; + +/** Offset 0x07E0 - Platform PL2 power + Platform Power Limit 2 Power in Milli Watts. BIOS will round to the nearest 1/8W + when programming. Value set 120 = 15W. Any value can be programmed between Max + and Min Power Limits. This setting will act as the new Max Turbo Power (PL2) value + for the Package RAPL algorithm. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 PsysPowerLimit2Power; + +/** Offset 0x07E4 - Vsys Max System battery volatge + Vsys Max defined in 1/1000 increments. Range is 0-65535. For a 1.25 voltage, enter + 1250. Default =0xFF. +**/ + UINT16 VsysMax; + +/** Offset 0x07E6 - ThETA Ibatt Feature + Enable or Disable ThETA Ibatt Feature. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 ThETAIbattEnable; + +/** Offset 0x07E7 - Reserved +**/ + UINT8 Reserved26; + +/** Offset 0x07E8 - ISYS Current Limit L1 + This field indicated the current limitiation of L1. Indicate current limit for which + dependency is on AC/DC mode before PSYS.Units of measurements are 1/8 A +**/ + UINT16 IsysCurrentLimitL1; + +/** Offset 0x07EA - ISYS Current Limit L1 Tau + This Specifies the time window used to calculate average current for ISYS_L1. The + units of measuremnts are specified in PACKAGE_POWER_SKU[TIME_UNIT] +**/ + UINT8 IsysCurrentL1Tau; + +/** Offset 0x07EB - Reserved +**/ + UINT8 Reserved27; + +/** Offset 0x07EC - ISYS Current Limit L2 + This bits enables disables ISYS_CURRENT_LIMIT_L2 algorithm.Indicate current limit + for which dependency is on AC/DC mode before PSYS. Units of measurements are 1/8 A +**/ + UINT16 IsysCurrentLimitL2; + +/** Offset 0x07EE - ISYS Current Limit L1 Enable + This bits enables disables ISYS_CURRENT_LIMIT_L1 algorithm. It control loop based + on the system power source AC or DC mode. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 IsysCurrentLimitL1Enable; + +/** Offset 0x07EF - ISYS Current Limit L2 Enable + This bits enables disables ISYS_CURRENT_LIMIT_L2 algorithm. It control loop based + on the system power source AC or DC mode. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 IsysCurrentLimitL2Enable; + +/** Offset 0x07F0 - Package PL4 boost configuration + Configure Power Limit 4 Boost in Watts. Valid Range 0 to 63000 in step size of 125 + mWatt. The value 0 means disable. +**/ + UINT16 PowerLimit4Boost; + +/** Offset 0x07F2 - Skin Temperature Target + Target temperature is limit to which the control mechanism is regulating.It is defined + in 1/2 C increments.Range is 0-255. Temperature Range is 0-122.5 C.0: Auto. +**/ + UINT8 SkinTargetTemp[3]; + +/** Offset 0x07F5 - Skin Control Temperature Enable MMIO + Enables the skin temperature control for MMIO register. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 SkinTempControlEnable[3]; + +/** Offset 0x07F8 - Skin Temperature Loop Gain + Sets the aggressiveness of control loop where 0 is graceful, favors performance + on expense of temperature overshoots and 7 is for aggressive, favors tight regulation + over performance. Range is 0-7.0: Auto. +**/ + UINT8 SkinControlLoopGain[3]; + +/** Offset 0x07FB - Skin Temperature Override Enable + When set, Pcode will use TEMPERATURE_OVERRIDE values instead of reading from corresponding + sensor.. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 SkinTempOverrideEnable[3]; + +/** Offset 0x07FE - Skin Temperature Minimum Performance Level + Minimum Performance level below which the STC limit will not throttle. 0 - all levels + of throttling allowed incl. survivability actions. 256 - no throttling allowed.0: Auto. +**/ + UINT8 SkinMinPerformanceLevel[3]; + +/** Offset 0x0801 - Skin Temperature Override + Allows SW to override the input temperature. Pcode will use this value instead of + the sensor temperature. EC control is not impacted. Units: 0.5C. Values are 0 to + 255 which represents 0C-122.5C range.0: Auto. +**/ + UINT8 SkinTempOverride[3]; + +/** Offset 0x0804 - Skin Temperature Control Enable + Enables Skin Temperature Control Sensors Feature. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 SkinTempControl; + +/** Offset 0x0805 - AC or DC Power State + AC or DC power State; 0: DC; 1: AC + 0:DC, 1:AC +**/ + UINT8 AcDcPowerState; + +/** Offset 0x0806 - Enable or Disable VR Thermal Alert + Enable or Disable VR Thermal Alert; 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 DisableVrThermalAlert; + +/** Offset 0x0807 - Enable or Disable Thermal Monitor + Enable or Disable Thermal Monitor; 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 ThermalMonitor; + +/** Offset 0x0808 - Configuration for boot TDP selection + Assured Power (cTDP) Mode as Nominal/Level1/Level2/Deactivate Base Power (TDP) selection. + Deactivate option will set MSR to Nominal and MMIO to Zero. 0: Base Power (TDP) + Nominal; 1: Base Power (TDP) Down; 2: Base Power (TDP) Up;0xFF : Deactivate +**/ + UINT8 ConfigTdpLevel; + +/** Offset 0x0809 - ConfigTdp mode settings Lock + Assured Power (cTDP) Mode Lock sets the Lock bits on TURBO_ACTIVATION_RATIO and + CONFIG_TDP_CONTROL. Note: When CTDP (Assured Power) Lock is enabled Custom ConfigTDP + Count will be forced to 1 and Custom ConfigTDP Boot Index will be forced to 0. + 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 ConfigTdpLock; + +/** Offset 0x080A - Load Configurable TDP SSDT + Enables Assured Power (cTDP) control via runtime ACPI BIOS methods. This 'BIOS only' + feature does not require EC or driver support. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 ConfigTdpBios; + +/** Offset 0x080B - CustomTurboActivationRatio + Turbo Activation Ratio for custom cTDP level + $EN_DIS +**/ + UINT8 CustomTurboActivationRatio; + +/** Offset 0x080C - CustomPowerLimit1Time + Short term Power Limit time window value for custom cTDP level. + $EN_DIS +**/ + UINT8 CustomPowerLimit1Time; + +/** Offset 0x080D - PL1 Enable value + Enable/Disable Platform Power Limit 1 programming. If this option is enabled, it + activates the PL1 value to be used by the processor to limit the average power + of given time window. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 PsysPowerLimit1; + +/** Offset 0x080E - PL1 timewindow + Platform Power Limit 1 Time Window value in seconds. The value may vary from 0 to + 128. 0 = default values. Indicates the time window over which Platform Processor + Base Power (TDP) value should be maintained. Valid values(Unit in seconds) 0 to + 8 , 10 , 12 ,14 , 16 , 20 , 24 , 28 , 32 , 40 , 48 , 56 , 64 , 80 , 96 , 112 , 128 +**/ + UINT8 PsysPowerLimit1Time; + +/** Offset 0x080F - PL2 Enable Value + Enable/Disable Platform Power Limit 2 programming. If this option is disabled, BIOS + will program the default values for Platform Power Limit 2. 0: Disable; + 1: Enable. + $EN_DIS +**/ + UINT8 PsysPowerLimit2; + +/** Offset 0x0810 - Package PL3 time window + Power Limit 3 Time Window value in Milli seconds. Indicates the time window over + which Power Limit 3 value should be maintained. If the value is 0, BIOS leaves + the hardware default value. Valid value: 0, 3-8, 10, 12, 14, 16, 20, 24, + 28, 32, 40, 48, 56, 64. +**/ + UINT8 PowerLimit3Time; + +/** Offset 0x0811 - Package Long duration turbo mode time + Power Limit 1 Time Window value in seconds. The value may vary from 0 to 128. 0 + = default value (28 sec for Mobile and 8 sec for Desktop). Defines time window + which Processor Base Power (TDP) value should be maintained. Valid values(Unit + in seconds) 0 to 8 , 10 , 12 ,14 , 16 , 20 , 24 , 28 , 32 , 40 , 48 , 56 , 64 , + 80 , 96 , 112 , 128 +**/ + UINT8 PowerLimit1Time; + +/** Offset 0x0812 - Reserved +**/ + UINT8 Reserved28[2]; + +/** Offset 0x0814 - Package Long duration turbo mode power limit + Power Limit 1 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. 0 = no custom override. Overclocking SKU: Value must be between + Max and Min Power Limits. Other SKUs: This value must be between Min Power Limit + and Processor Base Power (TDP) Limit. If value is 0, BIOS will program Processor + Base Power (TDP) value. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. Valid + Range 0 to 32767. +**/ + UINT32 PowerLimit1; + +/** Offset 0x0818 - Package Short duration turbo mode power limit + Power Limit 2 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. If the value is 0, BIOS will program this value as 1.25*Processor + Base Power (TDP). Processor applies control policies such that the package power + does not exceed this limit. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 PowerLimit2Power; + +/** Offset 0x081C - Package PL3 power limit + Power Limit 3 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. XE SKU: Any value can be programmed. Overclocking SKU: Value + must be between Max and Min Power Limits. Other SKUs: This value must be between + Min Power Limit and Processor Base Power (TDP) Limit. If the value is 0, BIOS leaves + the hardware default value. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 PowerLimit3; + +/** Offset 0x0820 - Package PL4 power limit + Power Limit 4 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. If the value is 0, BIOS leaves default value. Units are based + on POWER_MGMT_CONFIG.CustomPowerUnit. Valid Range 0 to 32767. +**/ + UINT32 PowerLimit4; + +/** Offset 0x0824 - Short term Power Limit value for custom cTDP level 1 + Power Limit 1 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. 0 = no custom override. Overclocking SKU: Value must be between + Max and Min Power Limits. Other SKUs: This value must be between Min Power Limit + and Processor Base Power (TDP) Limit. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 Custom1PowerLimit1; + +/** Offset 0x0828 - Long term Power Limit value for custom cTDP level 1 + Power Limit 2 value in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. 0 = no custom override. Processor applies control policies + such that the package power does not exceed this limit. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 Custom1PowerLimit2; + +/** Offset 0x082C - Enable Configurable TDP + Applies Assured Power (cTDP) initialization settings based on non-Assured Power + (cTDP) or Assured Power (cTDP). Default is 1: Applies to Assured Power (cTDP) ; + if 0 then applies non-Assured Power (cTDP) and BIOS will bypass Assured Power (cTDP) + initialization flow + $EN_DIS +**/ + UINT8 ApplyConfigTdp; + +/** Offset 0x082D - Dual Tau Boost + Enable Dual Tau Boost feature. This is only applicable for Desktop 35W/65W/125W + sku. When DPTF is enabled this feature is ignored. 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 DualTauBoost; + +/** Offset 0x082E - Tcc Offset Lock + Tcc Offset Lock for Runtime Average Temperature Limit (RATL) to lock temperature + target; 1:Enabled ; 0: Disabled. + $EN_DIS +**/ + UINT8 TccOffsetLock; + +/** Offset 0x082F - Package PL3 Duty Cycle + Specify the duty cycle in percentage that the CPU is required to maintain over the + configured time window. Range is 0-100. +**/ + UINT8 PowerLimit3DutyCycle; + +/** Offset 0x0830 - Package PL3 Lock + Power Limit 3 Lock. When enabled PL3 configurations are locked during OS. When disabled + PL3 configuration can be changed during OS. 0: Disable ; 1:Enable + $EN_DIS +**/ + UINT8 PowerLimit3Lock; + +/** Offset 0x0831 - Package PL4 Lock + Power Limit 4 Lock. When enabled PL4 configurations are locked during OS. When disabled + PL4 configuration can be changed during OS. 0: Disable ; 1:Enable + $EN_DIS +**/ + UINT8 PowerLimit4Lock; + +/** Offset 0x0832 - Short Duration Turbo Mode + Enable/Disable Power Limit 2 override. If this option is disabled, BIOS will program + the default values for Power Limit 2. 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 PowerLimit2; + +/** Offset 0x0833 - Response Mode + Enable/Disable Response Mode. 0: Disable ; 1:Enable + $EN_DIS +**/ + UINT8 ResponseMode; /** Offset 0x0834 - SinitMemorySize Enable/Disable. 0: Disable, define default value of SinitMemorySize , 1: enable @@ -2340,9 +3365,18 @@ typedef struct { **/ UINT8 AcousticNoiseMitigation; -/** Offset 0x086E - Reserved +/** Offset 0x086E - RfiMitigation + Enable or Disable RFI Mitigation. 0: Disable - DCM is the IO_N default; 1: + Enable - Enable IO_N DCM/CCM switching as RFI mitigation. + $EN_DIS +**/ + UINT8 RfiMitigation; + +/** Offset 0x086F - Platform Psys slope correction + PSYS Slope defined in 1/100 increments. 0 - Auto Specified in 1/100 increment + values. Range is 0-200. 125 = 1.25 **/ - UINT8 Reserved64[2]; + UINT8 PsysSlope; /** Offset 0x0870 - Platform Power Pmax PSYS PMax power, defined in 1/8 Watt increments. 0 - Auto Specified in 1/8 @@ -2394,7 +3428,14 @@ typedef struct { /** Offset 0x08BA - Reserved **/ - UINT8 Reserved65[26]; + UINT8 Reserved29[2]; + +/** Offset 0x08BC - Imon offset correction + IMON Offset is an 32-bit signed value (2's complement). Units 1/1000, Range is [-128000, + 127999]. For an offset of 25.348, enter 25348. 0: Auto. [0] for IA, [1] + for GT, [2] for SA, [3] through [5] are Reserved. +**/ + UINT32 ImonOffset[6]; /** Offset 0x08D4 - Icc Max limit Voltage Regulator Current Limit (Icc Max). This value represents the Maximum instantaneous @@ -2404,9 +3445,34 @@ typedef struct { **/ UINT16 IccMax[6]; -/** Offset 0x08E0 - Reserved +/** Offset 0x08E0 - VR Fast Vmode VoltageLimit support + Voltage Regulator Fast VoltageLimit . +**/ + UINT16 VrVoltageLimit[6]; + +/** Offset 0x08EC - Imon slope correction + IMON Slope defined in 1/100 increments. Range is 0-200. For a 1.25 slope, enter + 125. 0: Auto. [0] for IA, [1] for GT, [2] for SA, [3] through [5] are Reserved. +**/ + UINT16 ImonSlope[6]; + +/** Offset 0x08F8 - Power State 3 enable/disable + PS3 Enable/Disable. 0 - Disabled, 1 - Enabled. [0] for IA, [1] for GT, [2] for SA, + [3] through [5] are Reserved. +**/ + UINT8 Ps3Enable[6]; + +/** Offset 0x08FE - Power State 4 enable/disable + PS4 Enable/Disable. 0 - Disabled, 1 - Enabled. [0] for IA, [1] for GT, [2] for SA, + [3] through [5] are Reserved. **/ - UINT8 Reserved66[42]; + UINT8 Ps4Enable[6]; + +/** Offset 0x0904 - Enable/Disable BIOS configuration of VR + VR Config Enable. [0] for IA, [1] for GT, [2] for SA, [3] through [5] are Reserved. + 0: Disable; 1: Enable. +**/ + UINT8 VrConfigEnable[6]; /** Offset 0x090A - Thermal Design Current enable/disable Thermal Design Current enable/disable; 0: Disable; 1: Enable. [0] for IA, @@ -2414,9 +3480,11 @@ typedef struct { **/ UINT8 TdcEnable[6]; -/** Offset 0x0910 - Reserved +/** Offset 0x0910 - Thermal Design Current Lock + Thermal Design Current Lock; 0: Disable; 1: Enable. [0] for IA, [1] for GT, + [2] for SA, [3] for atom, [4]-[5] are Reserved. **/ - UINT8 Reserved67[6]; + UINT8 TdcLock[6]; /** Offset 0x0916 - Disable Fast Slew Rate for Deep Package C States for VR domains This option needs to be configured to reduce acoustic noise during deeper C states. @@ -2438,7 +3506,14 @@ typedef struct { /** Offset 0x0922 - Reserved **/ - UINT8 Reserved68[6]; + UINT8 Reserved30[2]; + +/** Offset 0x0924 - Platform Psys offset correction + PSYS Offset defined in 1/1000 increments. 0 - Auto This is an 32-bit signed + value (2's complement). Units 1/1000, Range is [-128000, 127999]. For an offset + of 25.348, enter 25348. +**/ + UINT32 PsysOffset; /** Offset 0x0928 - Thermal Design Current time window Auto = 0 is default. Range is from 1ms to 448s. 0: Auto. [0] for IA, [1] @@ -2452,9 +3527,17 @@ typedef struct { **/ UINT8 TdcMode[6]; -/** Offset 0x0946 - Reserved +/** Offset 0x0946 - DLVR RFI Enable + Enable/Disable DLVR RFI frequency hopping. 0: Disable; 1: Enable. + $EN_DIS **/ - UINT8 Reserved69[2]; + UINT8 FivrSpectrumEnable; + +/** Offset 0x0947 - DLVR RFI Spread Spectrum Percentage + DLVR SSC in percentage with multiple of 0.25%. 0 = 0%, 10 = 4%. 0x00: 0% , 0x02: + 0.5%, 0x04: 1% , 0x08: 2% ,0x10: 4%; u3.2 value from 0% - 4%. +**/ + UINT8 DlvrSpreadSpectrumPercentage; /** Offset 0x0948 - DLVR RFI Enable Enable/Disable DLVR RFI frequency hopping. 0: Disable; 1: Enable. @@ -2463,18 +3546,64 @@ typedef struct { UINT8 DlvrRfiEnable; /** Offset 0x0949 - Pcore VR Hysteresis time window - Enable/Disable DLVR RFI frequency hopping. 0: Disable; 1: Enable. + 0 is default. Range of PcoreHysteresisWindow from 1ms to 50ms. **/ UINT8 PcoreHysteresisWindow; /** Offset 0x094A - Ecore VR Hysteresis time window - Enable/Disable DLVR RFI frequency hopping. 0: Disable; 1: Enable. + 0 is default. Range of EcoreHysteresisWindow from 1ms to 50ms. **/ UINT8 EcoreHysteresisWindow; /** Offset 0x094B - Reserved **/ - UINT8 Reserved70[11]; + UINT8 Reserved31; + +/** Offset 0x094C - DLVR RFI Frequency + DLVR RFI Frequency in MHz. 0: 2227 MHz , 1: 2140MHZ. +**/ + UINT16 DlvrRfiFrequency; + +/** Offset 0x094E - DLVR PHASE_SSC Enable + Enable/Disable DLVR PHASE_SSC. 0: Disable. 1:Enable. + $EN_DIS +**/ + UINT8 VrPowerDeliveryDesign; + +/** Offset 0x094F - DLVR PHASE_SSC Enable + Enable/Disable DLVR PHASE_SSC. 0: Disable. 1:Enable. + $EN_DIS +**/ + UINT8 DlvrPhaseSsc; + +/** Offset 0x0950 - Vsys Critical + PCODE MMIO Mailbox: Vsys Critical. 0: Disable; 1: Enable Range is 0-255. +**/ + UINT8 EnableVsysCritical; + +/** Offset 0x0951 - Assertion Deglitch Mantissa + Assertion Deglitch Mantissa, Range is 0-255 +**/ + UINT8 VsysAssertionDeglitchMantissa; + +/** Offset 0x0952 - Assertion Deglitch Exponent + Assertion Deglitch Exponent, Range is 0-255 +**/ + UINT8 VsysAssertionDeglitchExponent; + +/** Offset 0x0953 - De assertion Deglitch Mantissa + De assertion Deglitch Mantissa, Range is 0-255 +**/ + UINT8 VsysDeassertionDeglitchMantissa; + +/** Offset 0x0954 - De assertion Deglitch Exponent + De assertion Deglitch Exponent, Range is 0-255 +**/ + UINT8 VsysDeassertionDeglitchExponent; + +/** Offset 0x0955 - Reserved +**/ + UINT8 Reserved32; /** Offset 0x0956 - VR Fast Vmode ICC Limit support Voltage Regulator Fast Vmode ICC Limit. A value of 400 = 100A. A value of 0 corresponds @@ -2499,7 +3628,44 @@ typedef struct { /** Offset 0x096E - Reserved **/ - UINT8 Reserved71[28]; + UINT8 Reserved33[2]; + +/** Offset 0x0970 - Vsys Full Scale + Vsys Full Scale, Range is 0-255000mV +**/ + UINT32 VsysFullScale; + +/** Offset 0x0974 - Vsys Critical Threshold + Vsys Critical Threshold, Range is 0-255000mV +**/ + UINT32 VsysCriticalThreshold; + +/** Offset 0x0978 - Psys Full Scale + Psys Full Scale, Range is 0-255000mV +**/ + UINT32 PsysFullScale; + +/** Offset 0x097C - Psys Critical Threshold + Psys Critical Threshold, Range is 0-255000mV +**/ + UINT32 PsysCriticalThreshold; + +/** Offset 0x0980 - Reserved +**/ + UINT8 Reserved34[8]; + +/** Offset 0x0988 - IOE Debug Enable + Enable/Disable IOE Debug. When enabled, IOE D2D Dfx link will keep up and clock + is enabled + $EN_DIS +**/ + UINT8 IoeDebugEn; + +/** Offset 0x0989 - Pmode Clock Enable + Enable/Disable PMODE clock. When enabled, Pmode clock will toggle for XDP use + $EN_DIS +**/ + UINT8 PmodeClkEn; /** Offset 0x098A - PCH Port80 Route Control where the Port 80h cycles are sent, 0: LPC; 1: PCI. @@ -2514,9 +3680,21 @@ typedef struct { **/ UINT8 GpioOverride; -/** Offset 0x098C - Reserved +/** Offset 0x098C - Pmc Privacy Consent + Enable/Disable Pmc Privacy Consent + $EN_DIS +**/ + UINT8 PmcPrivacyConsent; + +/** Offset 0x098D - DMI ME UMA Root Space Check + DMI IOSF Root Space attribute check for RS3 for cycles targeting MEUMA. + 0: POR, 1: enable, 2: disable **/ - UINT8 Reserved72[4]; + UINT8 PchTestDmiMeUmaRootSpaceCheck; + +/** Offset 0x098E - Reserved +**/ + UINT8 Reserved35[2]; /** Offset 0x0990 - PMR Size Size of PMR memory buffer. 0x400000 for normal boot and 0x200000 for S3 boot @@ -2540,9 +3718,11 @@ typedef struct { **/ UINT8 VtdDisable; -/** Offset 0x0997 - Reserved +/** Offset 0x0997 - State of Vtd Capabilities + 0x0=(No operation), BIT0 = 1 (Defeature Nested Support), BIT1 = 1 (Defeature Posted + Interrupt Support) **/ - UINT8 Reserved73; + UINT8 VtdCapabilityControl; /** Offset 0x0998 - Base addresses for VT-d function MMIO access Base addresses for VT-d MMIO access per VT-d engine @@ -2551,7 +3731,17 @@ typedef struct { /** Offset 0x09BC - Reserved **/ - UINT8 Reserved74[20]; + UINT8 Reserved36[4]; + +/** Offset 0x09C0 - MMIO Size + Size of MMIO space reserved for devices. 0(Default)=Auto, non-Zero=size in MB +**/ + UINT64 MchBar; + +/** Offset 0x09C8 - MMIO Size + Size of MMIO space reserved for devices. 0(Default)=Auto, non-Zero=size in MB +**/ + UINT64 RegBar; /** Offset 0x09D0 - MMIO Size Size of MMIO space reserved for devices. 0(Default)=Auto, non-Zero=size in MB @@ -2564,9 +3754,50 @@ typedef struct { **/ UINT16 MmioSizeAdjustment; -/** Offset 0x09D4 - Reserved +/** Offset 0x09D4 - Temporary address for ApicLocalAddress + The reference code will use this as Temporary address space +**/ + UINT32 ApicLocalAddress; + +/** Offset 0x09D8 - Temporary address for NvmeHcPeiMmioBase + The reference code will use this as Temporary address space +**/ + UINT32 NvmeHcPeiMmioBase; + +/** Offset 0x09DC - Temporary address for NvmeHcPeiMmioLimit + The reference code will use this as Temporary address space +**/ + UINT32 NvmeHcPeiMmioLimit; + +/** Offset 0x09E0 - Temporary address for AhciPeiMmioBase + The reference code will use this as Temporary address space +**/ + UINT32 AhciPeiMmioBase; + +/** Offset 0x09E4 - Temporary address for AhciPeiMmioLimit + The reference code will use this as Temporary address space +**/ + UINT32 AhciPeiMmioLimit; + +/** Offset 0x09E8 - Temporary address for EcExtraIoBase + The reference code will use this as Temporary address space +**/ + UINT16 EcExtraIoBase; + +/** Offset 0x09EA - Temporary address for SioBaseAddress + The reference code will use this as Temporary address space +**/ + UINT16 SioBaseAddress; + +/** Offset 0x09EC - Temporary CfgBar address for VMD + The reference code will use this as Temporary address space +**/ + UINT32 VmdCfgBarBar; + +/** Offset 0x09F0 - System Agent SafBar + Address of System Agent SafBar **/ - UINT8 Reserved75[36]; + UINT64 SafBar; /** Offset 0x09F8 - Enable above 4GB MMIO resource support Enable/disable above 4GB MMIO resource support @@ -2582,7 +3813,20 @@ typedef struct { /** Offset 0x09FA - Reserved **/ - UINT8 Reserved76[10]; + UINT8 Reserved37[2]; + +/** Offset 0x09FC - StreamTracer Mode + Disable: Disable StreamTracer, Advanced Tracing: StreamTracer size 512MB - Recommended + when all groups in high verbosity are traced in 'red', Auto: StreamTracer size + 8MB - Recommended when using up to 8 groups red or up to 16 groups in green in + med verbosity, User input: Allow User to enter a size in the range of 64KB-512MB + 0: Disable (Default), 524288: Advanced Tracing , 8192: Auto , 3: User input +**/ + UINT32 StreamTracerMode; + +/** Offset 0x0A00 +**/ + UINT32 StreamTracerSize; /** Offset 0x0A04 - Enable/Disable CrashLog Device Enable or Disable CrashLog/Telemetry Device 0- Disable, 1- Enable @@ -2590,9 +3834,39 @@ typedef struct { **/ UINT32 CpuCrashLogDevice; -/** Offset 0x0A08 - Reserved +/** Offset 0x0A08 - StreamTracer physical address + StreamTracer physical address +**/ + UINT64 StreamTracerBase; + +/** Offset 0x0A10 - Temporary MemBar1 address for VMD + StreamTracer physical address +**/ + UINT32 VmdMemBar1Bar; + +/** Offset 0x0A14 - Temporary MemBar2 address for VMD + StreamTracer physical address +**/ + UINT32 VmdMemBar2Bar; + +/** Offset 0x0A18 - Skip override boot mode When Fw Update. + When set to TRUE and boot mode is BOOT_ON_FLASH_UPDATE, skip setting boot mode to + BOOT_WITH_FULL_CONFIGURATION in PEI memory init. + $EN_DIS +**/ + UINT8 SiSkipOverrideBootModeWhenFwUpdate; + +/** Offset 0x0A19 - Reserved +**/ + UINT8 Reserved38; + +/** Offset 0x0A1A - Static Content at 4GB Location + 0 (Default): No Allocation, 0x20:32MB, 0x40:64MB, 0x80:128MB, 0x100:256MB, 0x200:512MB, + 0x400:1GB, 0x800:2GB, 0xC00:3GB, 0x1000:4GB, 0x2000:8GB + 0: No Allocation, 0x20:32MB, 0x40:64MB, 0x80:128MB, 0x100:256MB, 0x200:512MB, 0x400:1GB, + 0x800:2GB, 0xC00:3GB, 0x1000:4GB, 0x2000:8GB **/ - UINT8 Reserved77[20]; + UINT16 StaticContentSizeAt4Gb; /** Offset 0x0A1C - Platform Debug Option Enabled Trace active: TraceHub is enabled and trace is active, blocks s0ix.\n @@ -2607,9 +3881,14 @@ typedef struct { **/ UINT8 PlatformDebugOption; -/** Offset 0x0A1D - Reserved +/** Offset 0x0A1D - TXT CMOS Offset + CMOS Offset for TXT policy data. Default 0x2A +**/ + UINT8 CmosTxtOffset; + +/** Offset 0x0A1E - Reserved **/ - UINT8 Reserved78[14]; + UINT8 Reserved39[13]; /** Offset 0x0A2B - Program GPIOs for LFP on DDI port-A device 0=Disabled,1(Default)=eDP, 2=MIPI DSI @@ -2617,9 +3896,10 @@ typedef struct { **/ UINT8 DdiPortAConfig; -/** Offset 0x0A2C - Reserved +/** Offset 0x0A2C - HgSubSystemId + Hybrid Graphics SubSystemId **/ - UINT8 Reserved79[2]; + UINT16 HgSubSystemId; /** Offset 0x0A2E - Program GPIOs for LFP on DDI port-B device 0(Default)=Disabled,1=eDP, 2=MIPI DSI @@ -2711,9 +3991,15 @@ typedef struct { **/ UINT8 DdiPort4Ddc; -/** Offset 0x0A3D - Reserved +/** Offset 0x0A3D - Oem T12 Dealy Override + Oem T12 Dealy Override. 0(Default)=Disable 1=Enable + $EN_DIS +**/ + UINT8 OemT12DelayOverride; + +/** Offset 0x0A3E - Reserved **/ - UINT8 Reserved80[3]; + UINT8 Reserved40[2]; /** Offset 0x0A40 - Temporary MMIO address for GMADR The reference code will use this as Temporary MMIO address space to access GMADR @@ -2730,9 +4016,12 @@ typedef struct { **/ UINT64 GttMmAdr; -/** Offset 0x0A50 - Reserved +/** Offset 0x0A50 - Delta T12 Power Cycle Delay required in ms + Select the value for delay required. 0= No delay, 0xFFFF(Default) = Auto calculate + T12 Delay to max 500ms + 0 : No Delay, 0xFFFF : Auto Calulate T12 Delay **/ - UINT8 Reserved81[2]; + UINT16 DeltaT12PowerCycleDelay; /** Offset 0x0A52 - Enable/Disable Memory Bandwidth Compression 0=Disable, 1(Default)=Enable @@ -2762,7 +4051,7 @@ typedef struct { /** Offset 0x0A56 - Reserved **/ - UINT8 Reserved82[2]; + UINT8 Reserved41[2]; /** Offset 0x0A58 - Intel Graphics VBT (Video BIOS Table) Size Size of Internal Graphics VBT Image @@ -2771,7 +4060,7 @@ typedef struct { /** Offset 0x0A5C - Reserved **/ - UINT8 Reserved83[4]; + UINT8 Reserved42[4]; /** Offset 0x0A60 - Graphics Configuration Ptr Points to VBT @@ -2793,7 +4082,8 @@ typedef struct { Initialise SOL Init, BIT0 - (0 : Disable VGA Support, 1 : Enable VGA Support),, BIT1 - (0 : VGA Text Mode 3, 1 : VGA Graphics Mode 12), BIT2 - (0 : VGA Exit Supported, 1: NO VGA Exit), BIT3 - (0 : VGA Init During Display Init, 1 - VGA Init During - MRC Cold Boot), BIT4 - (0 : Enable Progress Bar, 1 : Disable Progress Bar) + MRC Cold Boot), BIT4 - (0 : Enable Progress Bar, 1 : Disable Progress Bar), BIT5 + - (0 : VGA Mode 12 16 Color Support, 1 : VGA Mode 12 Monochrome Black and White Support) 0:VGA Disable, 1:Mode 3 VGA, 2:Mode 12 VGA **/ UINT8 VgaInitControl; @@ -2830,9 +4120,11 @@ typedef struct { **/ UINT8 TcssXhciEn; -/** Offset 0x0A83 - Reserved +/** Offset 0x0A83 - IomUsbCDpConfig + Set IomUsbCDpConfig expect 4 values from 0 to 3 + 0:Disabled, 1:IOM_DP, 2:IOM_HDMI, 3: IOM_EDP **/ - UINT8 Reserved84[4]; + UINT8 IomUsbCDpConfig[4]; /** Offset 0x0A87 - TCSS Type C Port 0 Set TCSS Type C Port 0 Type, Options are 0=DISABLE, 1=DP_ONLY, 2=NO_TBT, 3=NO_PCIE, @@ -2862,9 +4154,11 @@ typedef struct { **/ UINT8 TcssPort3; -/** Offset 0x0A8B - Reserved +/** Offset 0x0A8B - TCSS Platform Configuration + Set TCSS Platform Configuration - Retimer Map, TCP0 - Bits[1:0], TCP1 - Bits[3:2], + TCP2 - Bits[5:4], TCP3 - Bits[7:6]; 0=Retimerless, 1=Retimer **/ - UINT8 Reserved85; + UINT8 TcssPlatConf; /** Offset 0x0A8C - TypeC port GPIO setting GPIO Pin number for Type C Aux orientation setting, use the GpioPad that is defined @@ -2930,9 +4224,11 @@ typedef struct { **/ UINT8 InternalGraphics; -/** Offset 0x0AC9 - Reserved +/** Offset 0x0AC9 - Asynchronous ODT + This option configures the Memory Controler Asynchronous ODT control + 0:Enabled, 1:Disabled **/ - UINT8 Reserved86; + UINT8 AsyncOdtDis; /** Offset 0x0ACA - DLL Weak Lock Support Enables/Disable DLL Weak Lock Support @@ -2942,7 +4238,7 @@ typedef struct { /** Offset 0x0ACB - Reserved **/ - UINT8 Reserved87; + UINT8 Reserved43; /** Offset 0x0ACC - Rx DQS Delay Comp Support Enables/Disable Rx DQS Delay Comp Support @@ -2952,7 +4248,7 @@ typedef struct { /** Offset 0x0ACD - Reserved **/ - UINT8 Reserved88[2]; + UINT8 Reserved44[2]; /** Offset 0x0ACF - Mrc Failure On Unsupported Dimm Enables/Disable Mrc Failure On Unsupported Dimm @@ -2960,9 +4256,11 @@ typedef struct { **/ UINT8 MrcFailureOnUnsupportedDimm; -/** Offset 0x0AD0 - Reserved +/** Offset 0x0AD0 - Fore Single Rank config + Enables/Disable Fore Single Rank config + $EN_DIS **/ - UINT8 Reserved89[4]; + UINT32 ForceSingleRank; /** Offset 0x0AD4 - DynamicMemoryBoost Enable/Disable Dynamic Memory Boost Feature. Only valid if SpdProfileSelected is @@ -2978,9 +4276,55 @@ typedef struct { **/ UINT32 RealtimeMemoryFrequency; -/** Offset 0x0ADC - Reserved +/** Offset 0x0ADC - SelfRefresh IdleTimer + SelfRefresh IdleTimer, Default is 256 +**/ + UINT16 SrefCfgIdleTmr; + +/** Offset 0x0ADE - MC Register Offset + Apply user offsets to select MC registers(Def=Disable) + $EN_DIS +**/ + UINT8 MCREGOFFSET; + +/** Offset 0x0ADF - CA Vref Ctl Offset + Offset to be applied to DDRDATA7CH1_CR_DDRCRVREFADJUST1.CAVref + 0xF4:-12,0xF5:-11, 0xF6:-10, 0xF7:-9, 0xF8:-8, 0xF9:-7, 0xFA:-6, 0xFB:-5, 0xFC:-4, + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3, 4:+4, 5:+5, 6:+6, 7:+7, 8:+8, + 9:+9, 10:+10, 11:+11, 12:+12 +**/ + UINT8 CAVrefCtlOffset; + +/** Offset 0x0AE0 - Clk PI Code Offset + Offset to be applied to DDRCLKCH0_CR_DDRCRCLKPICODE.PiSettingRank[0-3] + 0xFA:-6, 0xFB:-5, 0xFC:-4, 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3, 4:+4, + 5:+5, 6:+6 +**/ + UINT8 ClkPiCodeOffset; + +/** Offset 0x0AE1 - RcvEn Offset + Offset to be applied to DDRDATACH0_CR_DDRCRDATAOFFSETTRAIN.RcvEn + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3 +**/ + UINT8 RcvEnOffset; + +/** Offset 0x0AE2 - Rx Dqs Offset + Offset to be applied to DDRDATACHX_CR_DDRCRDATAOFFSETTRAIN.RxDqsOffset + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3 +**/ + UINT8 RxDqsOffset; + +/** Offset 0x0AE3 - Tx Dq Offset + Offset to be applied to DDRDATACH0_CR_DDRCRDATAOFFSETTRAIN.TxDqOffset + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3 +**/ + UINT8 TxDqOffset; + +/** Offset 0x0AE4 - Tx Dqs Offset + Offset to be applied to DDRDATACH0_CR_DDRCRDATAOFFSETTRAIN.TxDqsOffset + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3 **/ - UINT8 Reserved90[9]; + UINT8 TxDqsOffset; /** Offset 0x0AE5 - Vref Offset Offset to be applied to DDRDATACH0_CR_DDRCRDATAOFFSETTRAIN.VrefOffset @@ -2989,9 +4333,15 @@ typedef struct { **/ UINT8 VrefOffset; -/** Offset 0x0AE6 - Reserved +/** Offset 0x0AE6 - Controller mask + Controller mask to apply on parameter offset +**/ + UINT8 CntrlrMask; + +/** Offset 0x0AE7 - Channel mask + Channel mask to apply on parameter offset **/ - UINT8 Reserved91[2]; + UINT8 ChMask; /** Offset 0x0AE8 - tRRSG Delta Delay between Read-to-Read commands in the same Bank Group. 0 - Auto. Signed TAT @@ -3105,9 +4455,158 @@ typedef struct { **/ UINT8 tRWDD; -/** Offset 0x0AF8 - Reserved +/** Offset 0x0AF8 - MRC Interpreter + Select CMOS location match of DD01 or Ctrl-Break key or force entry + 0:CMOS, 1:Break, 2:Force +**/ + UINT8 Interpreter; + +/** Offset 0x0AF9 - ODT mode + ODT mode + 0:Default, 1:Vtt, 2:Vddq, 3:Vss, 4:Max +**/ + UINT8 IoOdtMode; + +/** Offset 0x0AFA - PerBankRefresh + Control of Per Bank Refresh feature for LPDDR DRAMs + $EN_DIS +**/ + UINT8 PerBankRefresh; + +/** Offset 0x0AFB - Mimic WC display pattern in IPQ + Using for Disable/Enable Mimic WC display pattern in IPQ: 0:Disable, 1:Enable 1 + ACT resources usage, 3:Enable 2 ACT resources usage, 3:Enable 3 ACT resources usage,0xf: + Enable 4 ACT resources usage + 1:1, 3:3, 0xf:0xf, 0:Auto +**/ + UINT8 MimicWcDisaplayInIpq; + +/** Offset 0x0AFC - Fake SAGV + Fake SAGV: 0:Disabled, 1:Enabled + $EN_DIS +**/ + UINT32 FakeSagv; + +/** Offset 0x0B00 - Lock DPR register + Lock DPR register. 0: Platform POR ; 1: Enable; 2: Disable + 0:Platform POR, 1: Enable, 2: Disable +**/ + UINT32 DprLock; + +/** Offset 0x0B04 - Board Stack Up + Board Stack Up: 0=Typical, 1=Freq Limited + 0:Typical, 1:Freq Limited +**/ + UINT8 BoardStackUp; + +/** Offset 0x0B05 - PPR ForceRepair + When Eanble, PPR will force repair some rows many times (90) + $EN_DIS +**/ + UINT8 PprForceRepair; + +/** Offset 0x0B06 - PPR Repair Bank + Deprecated +**/ + UINT8 PprRepairBank; + +/** Offset 0x0B07 - Board Topology + Board Topology: 0=Daisy Chain, 1=Tee. + 0:Daisy Chain, 1:Tee +**/ + UINT8 BoardTopology; + +/** Offset 0x0B08 - SubCh Hash Interleaved Bit + Select the MC Enhanced Channel interleave bit, to set different address bit for + sub channel selection than bit-6 + 0:BIT6, 1:BIT7, 2:BIT8, 3:BIT9, 4:BIT10, 5:BIT11, 6:BIT12, 7:BIT13 +**/ + UINT8 SubChHashInterleaveBit; + +/** Offset 0x0B09 - Reserved +**/ + UINT8 Reserved45; + +/** Offset 0x0B0A - SubCh Hash Mask + Set the BIT(s) to be included in the XOR function. NOTE BIT mask corresponds to + BITS [19:6] Default is 0x834 +**/ + UINT16 SubChHashMask; + +/** Offset 0x0B0C - Force CKD in Bypass Mode + Enable/Disable Force CKD in Bypass Mode + $EN_DIS +**/ + UINT8 ForceCkdBypass; + +/** Offset 0x0B0D - Reserved +**/ + UINT8 Reserved46[3]; + +/** Offset 0x0B10 - Disable Zq + Enable/Disable Zq Calibration: 0:Enabled, 1:Disabled + $EN_DIS +**/ + UINT32 DisableZq; + +/** Offset 0x0B14 - Replicate SAGV + Replicate SAGV: 0:Disabled, 1:Enabled + $EN_DIS +**/ + UINT32 ReplicateSagv; + +/** Offset 0x0B18 - Adjust wck mode + Adjust wck mode: 0:safe mode, 1:manual mode, 2:dynamic mode, 3:Default + 0:safe mode, 1:manual mode, 2:dynamic mode, 3:Default +**/ + UINT8 AdjustWckMode; + +/** Offset 0x0B19 - Control MC/PMA telemetry + Control MC/PMA telemetry: 0: Default, 1: Enable, 2: Disable + 0: Default, 1: Enable, 2: Disable +**/ + UINT8 TelemetryControl; + +/** Offset 0x0B1A - PHclk\Qclk SPINE gating Control + PHclk\Qclk SPINE gating Control: 0:Disabled, 1:Enabled + $EN_DIS +**/ + UINT8 SpineAndPhclkGateControl; + +/** Offset 0x0B1B - SpineGating per lpmode + SpineGatePerLpmode[0]:Lpmode0.5, SpineGatePerLpmode[1]:Lpmode2, SpineGatePerLpmode[2]:Lpmode3, + SpineGatePerLpmode[3]:Lpmode4 +**/ + UINT8 SpineGatePerLpmode; + +/** Offset 0x0B1C - PhClkGating control per lpmode + PhclkGatePerLpmode[0]:Lpmode0.5, PhclkGatePerLpmode[1]:Lpmode1, PhclkGatePerLpmode[2]:Lpmode2, + PhclkGatePerLpmode[3]:Lpmode3, PhclkGatePerLpmode[4]:Lpmode4 +**/ + UINT8 PhclkGatePerLpmode; + +/** Offset 0x0B1D - DFI Control after cold boot + Disable Switch DFI Control to MC after cold boot: 0(Default)=switch DFI to MC, 1=Keep + with PHY/MPTU + $EN_DIS +**/ + UINT8 DisableSwitchDfiToMc; + +/** Offset 0x0B1E - Enable/Disable SmbusPostcode + Disable (Default): Postcode via Port80, Enable: Postcode via Smbus + $EN_DIS +**/ + UINT8 SmbusPostCodeEnable; + +/** Offset 0x0B1F - SmbusPostcode Address + Slave address for Smbus postcode device **/ - UINT8 Reserved92[41]; + UINT8 SmbusPostCodeAddress; + +/** Offset 0x0B20 - SmbusPostcode Command + Command value for Smbus postcode device +**/ + UINT8 SmbusPostCodeCommand; /** Offset 0x0B21 - Channel to CKD QCK Mapping Specify Channel to CKD QCK Mapping for CH0D0/CH0D1/CH1D0&CH1D1 @@ -3119,9 +4618,40 @@ typedef struct { **/ UINT8 PhyClockToCkdDimm[8]; -/** Offset 0x0B31 - Reserved +/** Offset 0x0B31 - CKD Address Table + Specify CKD Address table for all DIMMs +**/ + UINT8 CkdAddressTable[16]; + +/** Offset 0x0B41 - Single VDD2 Rail + LP5x VDD2 rail: 0: Dual rail (E-DVFSC is possible), 1: Single rail(No E-DVFSC; VDD2L == VDD2H) + $EN_DIS +**/ + UINT8 SingleVdd2Rail; + +/** Offset 0x0B42 - VDD2 Voltage + Voltage is multiple of 5mV where 0 means Auto. +**/ + UINT16 Vdd2HVoltage; + +/** Offset 0x0B44 - VDD1 Voltage + Voltage is multiple of 5mV where 0 means Auto. +**/ + UINT16 Vdd1Voltage; + +/** Offset 0x0B46 - VDD2L Voltage Override + Voltage is multiple of 5mV where 0 means Auto. +**/ + UINT16 Vdd2LVoltage; + +/** Offset 0x0B48 - VDDQ Voltage Override + Voltage is multiple of 5mV where 0 means Auto. +**/ + UINT16 VddqVoltage; + +/** Offset 0x0B4A - Reserved **/ - UINT8 Reserved93[55]; + UINT8 Reserved47[30]; } FSP_M_CONFIG; /** Fsp M UPD Configuration diff --git a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspsUpd.h b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspsUpd.h index b5194418b1d..be67c19c806 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspsUpd.h +++ b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/FspsUpd.h @@ -104,9 +104,24 @@ typedef struct { **/ UINT64 BiosGuardModulePtr; -/** Offset 0x0080 - Reserved +/** Offset 0x0080 - EcProvisionEav + EcProvisionEav function pointer. \n + @code typedef EFI_STATUS (EFIAPI *EC_PROVISION_EAV) (IN UINT32 Eav, OUT UINT8 + *ReturnValue); @endcode **/ - UINT8 Reserved1[17]; + UINT64 EcProvisionEav; + +/** Offset 0x0088 - EcBiosGuardCmdLock + EcBiosGuardCmdLock function pointer. \n + @code typedef EFI_STATUS (EFIAPI *EC_CMD_LOCK) (OUT UINT8 *ReturnValue); @endcode +**/ + UINT64 EcBiosGuardCmdLock; + +/** Offset 0x0090 - PCH eSPI Host and Device BME enabled + PCH eSPI Host and Device BME enabled + $EN_DIS +**/ + UINT8 PchEspiBmeHostDeviceEnabled; /** Offset 0x0091 - PCH eSPI Link Configuration Lock (SBLCL) Enable/Disable lock of communication through SET_CONFIG/GET_CONFIG to eSPI target @@ -127,9 +142,27 @@ typedef struct { **/ UINT8 PchEspiLgmrEnable; -/** Offset 0x0094 - Reserved +/** Offset 0x0094 - PCH eSPI PmHAE + This option enables or disables espi lgmr + $EN_DIS +**/ + UINT8 PchEspiPmHAE; + +/** Offset 0x0095 - PCH eSPI HideNonFatalErrors + This option enables or disables espi lgmr + $EN_DIS +**/ + UINT8 PchEspiHideNonFatalErrors; + +/** Offset 0x0096 - PCH eSPI NmiEnableCs1 + Set this bit to enable eSPI NMI VW events to be processed by the SOC + $EN_DIS +**/ + UINT8 PchEspiNmiEnableCs1; + +/** Offset 0x0097 - Reserved **/ - UINT8 Reserved2[4]; + UINT8 Reserved1; /** Offset 0x0098 - CpuBistData Pointer CPU BIST Data @@ -151,7 +184,16 @@ typedef struct { /** Offset 0x00A9 - Reserved **/ - UINT8 Reserved3[7]; + UINT8 Reserved2[3]; + +/** Offset 0x00AC - StreamTracer Mode + Disable: Disable StreamTracer, Advanced Tracing: StreamTracer size 512MB - Recommended + when all groups in high verbosity are traced in 'red', Auto: StreamTracer size + 8MB - Recommended when using up to 8 groups red or up to 16 groups in green in + med verbosity, User input: Allow User to enter a size in the range of 64KB-512MB + 0: Disable (Default), 524288: Advanced Tracing , 8192: Auto , 3: User input +**/ + UINT32 StreamTracerMode; /** Offset 0x00B0 - MicrocodeRegionBase Memory Base of Microcode Updates @@ -192,9 +234,12 @@ typedef struct { **/ UINT8 AvxDisable; -/** Offset 0x00C4 - Reserved +/** Offset 0x00C4 - X2ApicEnable + Enable/Disable X2APIC Operating Mode. When this option is configured as 'Enabled', + 'VT-d' option must be 'Enabled'. + $EN_DIS **/ - UINT8 Reserved4; + UINT8 X2ApicEnable; /** Offset 0x00C5 - P-state ratios for max 16 version of custom P-state table P-state ratios for max 16 version of custom P-state table. This table is used for @@ -287,9 +332,17 @@ typedef struct { **/ UINT8 PkgCStateLimit; -/** Offset 0x00E1 - Reserved +/** Offset 0x00E1 - ForcePr Demotion Algorithm configuration + ForcePr Demotion Algorithm configuration. 0: Disable; 1: Enable + 0: Disable, 1: Enable +**/ + UINT8 ForcePrDemotion; + +/** Offset 0x00E2 - VrAlert Demotion Algorithm configuration + VrAlert Demotion Algorithm configuration. 0: Disable; 1: Enable + 0: Disable, 1: Enable **/ - UINT8 Reserved5[2]; + UINT8 VrAlertDemotion; /** Offset 0x00E3 - Interrupt Redirection Mode Select Interrupt Redirection Mode Select for Logical Interrupts. 0: Fixed priority; 1: @@ -303,9 +356,12 @@ typedef struct { **/ UINT8 TurboMode; -/** Offset 0x00E5 - Reserved +/** Offset 0x00E5 - Power Floor PCIe Gen Downgrade + SoC can downgrade PCIe gen speed to lower SoC floor power (Default enabled). 0: + Disable: Reduction in PCIe gen speed will not be used by SoC., 1: Enable + $EN_DIS **/ - UINT8 Reserved6; + UINT8 PowerFloorPcieGenDowngrade; /** Offset 0x00E6 - P-state ratios for custom P-state table P-state ratios for custom P-state table. NumberOfEntries has valid range between @@ -325,9 +381,12 @@ typedef struct { **/ UINT8 MaxRatio; -/** Offset 0x0110 - Reserved +/** Offset 0x0110 - Boot frequency + Select the performance state that the BIOS will set starting from reset vector. + 0: Maximum battery performance. 1: Maximum non-turbo performance. 2: Turbo performance + 0:0, 1:1, 2:2 **/ - UINT8 Reserved7; + UINT8 BootFrequency; /** Offset 0x0111 - Turbo settings Lock Enable/Disable locking of Package Power Limit settings. When enabled, PACKAGE_POWER_LIMIT @@ -337,9 +396,41 @@ typedef struct { **/ UINT8 TurboPowerLimitLock; -/** Offset 0x0112 - Reserved +/** Offset 0x0112 - FastMsrHwpReq + 0: Disable; 1: Enable; + $EN_DIS +**/ + UINT8 EnableFastMsrHwpReq; + +/** Offset 0x0113 - Turbo Ratio Limit Ratio array + Performance-core Turbo Ratio Limit Ratio0-7 (TRLR) defines the turbo ratio (max + is 85 in normal mode and 120 in core extension mode). Ratio[0]: This Turbo Ratio + Limit Ratio0 must be greater than or equal all other ratio values. If this value + is invalid, thn set all other active cores to minimum. Otherwise, align the Ratio + Limit to 0. Please check each active cores. Ratio[1~7]: This Turbo Ratio Limit + Ratio1 must be <= to Turbo Ratio Limit Ratio0~6. +**/ + UINT8 TurboRatioLimitRatio[8]; + +/** Offset 0x011B - Turbo Ratio Limit Num Core array + Performance-core Turbo Ratio Limit Core0~7 defines the core range, the turbo ratio + is defined in Turbo Ratio Limit Ratio0~7. If value is zero, this entry is ignored. +**/ + UINT8 TurboRatioLimitNumCore[8]; + +/** Offset 0x0123 - ATOM Turbo Ratio Limit Ratio array + Efficient-core Turbo Ratio Limit Ratio0-7 defines the turbo ratio (max is 85 irrespective + of the core extension mode), the core range is defined in E-core Turbo Ratio Limit + CoreCount0-7. +**/ + UINT8 AtomTurboRatioLimitRatio[8]; + +/** Offset 0x012B - ATOM Turbo Ratio Limit Num Core array + Efficient-core Turbo Ratio Limit CoreCount0-7 defines the core range, the turbo + ratio is defined in E-core Turbo Ratio Limit Ratio0-7. If value is zero, this entry + is ignored. **/ - UINT8 Reserved8[33]; + UINT8 AtomTurboRatioLimitNumCore[8]; /** Offset 0x0133 - Race To Halt Enable/Disable Race To Halt feature. RTH will dynamically increase CPU frequency @@ -373,9 +464,11 @@ typedef struct { **/ UINT8 MaxRingRatioLimit; -/** Offset 0x0138 - Reserved +/** Offset 0x0138 - Resource Priority Feature + Enable/Disable Resource Priority Feature. Enable/Disable; 0: Disable, 1: Enable + $EN_DIS **/ - UINT8 Reserved9; + UINT8 EnableRp; /** Offset 0x0139 - Enable or Disable HWP Enable/Disable Intel(R) Speed Shift Technology support. Enabling will expose the @@ -406,9 +499,42 @@ typedef struct { **/ UINT8 EnableHwpAutoEppGrouping; -/** Offset 0x013D - Reserved +/** Offset 0x013D - Dynamic Efficiency Control + Enable or Disable SoC to control energy efficiency targets autonomously, regardless + of EPP, EPB and other SW inputs. 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 EnableDynamicEfficiencyControl; + +/** Offset 0x013E - Misc Power Management MSR Lock + Enable/Disable HWP Lock support in Misc Power Management MSR. 0: Disable, 1: + Enable + $EN_DIS +**/ + UINT8 HwpLock; + +/** Offset 0x013F - Power Floor Managment for SOC + Option to disable Power Floor Managment for SOC. Disabling this might effectively + raise power floor of the SoC and may lead to stability issues. 0: Disable, 1: + Enable + $EN_DIS +**/ + UINT8 PowerFloorManagement; + +/** Offset 0x0140 - Power Floor Disaplay Disconnect + SoC can disconnect secondary/external display to lower SoC floor power (Default + disabled). 0: Disable: Display disconnect will not be used by SoC., 1: Enable + $EN_DIS +**/ + UINT8 PowerFloorDisplayDisconnect; + +/** Offset 0x0141 - Memory size per thread allocated for Processor Trace + Memory size per thread for Processor Trace. Processor Trace requires 2^N alignment + and size in bytes per thread, from 4KB to 128MB.\n + 0xff:none , 0:4k, 0x1:8k, 0x2:16k, 0x3:32k, 0x4:64k, 0x5:128k, 0x6:256k, + 0x7:512k, 0x8:1M, 0x9:2M, 0xa:4M. 0xb:8M, 0xc:16M, 0xd:32M, 0xe:64M, 0xf:128M **/ - UINT8 Reserved10[5]; + UINT8 ProcessorTraceMemSize; /** Offset 0x0142 - Enable or Disable MLC Streamer Prefetcher Enable or Disable MLC Streamer Prefetcher; 0: Disable; 1: Enable. @@ -447,9 +573,25 @@ typedef struct { **/ UINT8 ProcessorTraceEnable; -/** Offset 0x0148 - Reserved +/** Offset 0x0148 - Processor trace enabled for Bsp only or all cores + Processor trace enabled for Bsp only or all cores; 0: all cores; 1: Bsp only. + 0: all cores, 1: Bsp only +**/ + UINT8 ProcessorTraceBspOnly; + +/** Offset 0x0149 - Enable/Disable processor trace Timing Packet + Enable/Disable collocting processor trace performance (CYC, TSC); 0: Disable; + 1: Enable. + $EN_DIS +**/ + UINT8 ProcessorTraceTimingPacket; + +/** Offset 0x014A - Enable or Disable Three Strike Counter + Enable (default): Three Strike counter will be incremented. Disable: Prevents Three + Strike counter from incrementing; 0: Disable; 1: Enable + $EN_DIS **/ - UINT8 Reserved11[3]; + UINT8 ThreeStrikeCounter; /** Offset 0x014B - UFS enable/disable Enable/Disable UFS controller, One byte for each Controller - (1,0) to enable controller @@ -458,9 +600,20 @@ typedef struct { **/ UINT8 UfsEnable[2]; -/** Offset 0x014D - Reserved +/** Offset 0x014D - UFS Inline Encryption enable/disable + Enable/Disable UFS Inline Encryption feature, One byte for each Controller - (1,0) + to enable Inline Encryption for controller 0 and (0, 1) to enable Inline Encryption + for controller 1 + $EN_DIS +**/ + UINT8 UfsInlineEncryption[2]; + +/** Offset 0x014F - UFS Connection Status + UFS Connection Status, One byte for each Controller - (1,0) to UFS connected to + controller 0 and (0,1) to UFS connected to controller 1 + $EN_DIS **/ - UINT8 Reserved12[4]; + UINT8 UfsDeviceConnected[2]; /** Offset 0x0151 - Enable/Disable PCIe tunneling for USB4 Enable/Disable PCIe tunneling for USB4, default is enable @@ -470,7 +623,7 @@ typedef struct { /** Offset 0x0152 - Reserved **/ - UINT8 Reserved13[2]; + UINT8 Reserved3[2]; /** Offset 0x0154 - ITBTForcePowerOn Timeout value ITBTForcePowerOn value. Specified increment values in miliseconds. Range is 0-1000. @@ -496,7 +649,12 @@ typedef struct { /** Offset 0x015D - Reserved **/ - UINT8 Reserved14[19]; + UINT8 Reserved4[11]; + +/** Offset 0x0168 - FSPS Validation + Point to FSPS Validation configuration structure +**/ + UINT64 FspsValidationPtr; /** Offset 0x0170 - IEH Mode Integrated Error Handler Mode, 0: Bypass, 1: Enable @@ -555,7 +713,7 @@ typedef struct { /** Offset 0x017B - Reserved **/ - UINT8 Reserved15; + UINT8 Reserved5; /** Offset 0x017C - ISH GP GPIO Pin Muxing Determines ISH GP GPIO Pin muxing. See GPIO_*_MUXING_ISH_GP_x_GPIO_*. 'x' are GP_NUMBER @@ -738,9 +896,11 @@ typedef struct { **/ UINT8 PchIshPdtUnlock; -/** Offset 0x025C - Reserved +/** Offset 0x025C - PCH ISH MSI Interrupts + 0: False; 1: True. + $EN_DIS **/ - UINT8 Reserved16; + UINT8 PchIshMsiInterrupt; /** Offset 0x025D - End of Post message Test, Send End of Post message. Disable(0x0): Disable EOP message, Send in PEI(0x1): @@ -770,9 +930,44 @@ typedef struct { **/ UINT8 MeUnconfigOnRtcClear; -/** Offset 0x0261 - Reserved +/** Offset 0x0261 - CSE Data Resilience Support + 0: Disable CSE Data Resilience Support. 1: Enable CSE Data Resilience Support. + 2: Enable CSE Data Resilience but defer to DXE. + $EN_DIS +**/ + UINT8 CseDataResilience; + +/** Offset 0x0262 - PSE EOM Flow Control + 0: Disable PSE EOM Flow. 1: Enable PSE EOM Flow. + $EN_DIS +**/ + UINT8 PseEomFlowEnable; + +/** Offset 0x0263 - ISH I3C SDA Pin Muxing + Select ISH I3C SDA Pin muxing. Refer to GPIO_*_MUXING_ISH_I3Cx_SDA_* for possible values. +**/ + UINT8 IshI3cSdaPinMuxing[8]; + +/** Offset 0x026B - ISH I3C SCL Pin Muxing + Select ISH I3C SCL Pin muxing. Refer to GPIO_*_MUXING_ISH_I3Cx_SCL_* for possible values. +**/ + UINT8 IshI3cSclPinMuxing[8]; + +/** Offset 0x0273 - ISH I3C SDA Pad termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C#N Sda pads termination + respectively. #N-byte for each controller, byte0 for I2C0 Sda, byte1 for I2C1 Sda, + and so on. +**/ + UINT8 IshI3cSdaPadTermination[2]; + +/** Offset 0x0275 - ISH I3C SCL Pad termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C#N Scl pads termination + respectively. #N-byte for each controller, byte0 for I2C0 Scl, byte1 for I2C1 Scl, + and so on. **/ - UINT8 Reserved17[22]; + UINT8 IshI3cSclPadTermination[2]; /** Offset 0x0277 - Enable PCH ISH I3C pins assigned Set if ISH I3C native pins are to be enabled by BIOS. 0: Disable; 1: Enable. @@ -781,7 +976,7 @@ typedef struct { /** Offset 0x0279 - Reserved **/ - UINT8 Reserved18[3]; + UINT8 Reserved6[3]; /** Offset 0x027C - Power button debounce configuration Debounce time for PWRBTN in microseconds. For values not supported by HW, they will @@ -964,9 +1159,11 @@ typedef struct { **/ UINT8 PmcLpmS0ixSubStateEnableMask; -/** Offset 0x029C - Reserved +/** Offset 0x029C - PCH PMC ER Debug mode + Disable/Enable Energy Reporting Debug Mode. + $EN_DIS **/ - UINT8 Reserved19; + UINT8 PchPmErDebugMode; /** Offset 0x029D - PMC C10 dynamic threshold dajustment enable Set if you want to enable PMC C10 dynamic threshold adjustment. Only works on supported SKUs @@ -1135,9 +1332,11 @@ typedef struct { **/ UINT8 PcieRpAspm[28]; -/** Offset 0x053C - Reserved +/** Offset 0x053C - HostL0sTxDis + Disable Host L0 transmission state + $EN_DIS **/ - UINT8 Reserved20[28]; + UINT8 HostL0sTxDis[28]; /** Offset 0x0558 - PCIE RP L1 Substates The L1 Substates configuration of the root port (see: PCH_PCIE_L1SUBSTATES_CONTROL). @@ -1161,308 +1360,1102 @@ typedef struct { **/ UINT8 PcieEqOverrideDefault[12]; -/** Offset 0x05B8 - Reserved +/** Offset 0x05B8 - PCIE RP choose EQ method + Choose PCIe EQ method + 0: HardwareEq, 1: FixedEq +**/ + UINT8 PcieGen3EqMethod[12]; + +/** Offset 0x05C4 - PCIE RP choose EQ mode + Choose PCIe EQ mode + 0: PresetEq, 1: CoefficientEq **/ - UINT8 Reserved21[1525]; + UINT8 PcieGen3EqMode[12]; -/** Offset 0x0BAD - PCIE RP Enable Peer Memory Write - This member describes whether Peer Memory Writes are enabled on the platform. +/** Offset 0x05D0 - PCIE RP EQ local transmitter override + Enable/Disable local transmitter override $EN_DIS **/ - UINT8 PcieEnablePeerMemoryWrite[12]; + UINT8 PcieGen3EqLocalTxOverrideEn[12]; -/** Offset 0x0BB9 - Assertion on Link Down GPIOs - GPIO Assertion on Link Down. Disabled(0x0)(Default): Disable assertion on Link Down - GPIOs, Enabled(0x1): Enable assertion on Link Down GPIOs - 0:Disable, 1:Enable +/** Offset 0x05DC - PCI RP number of valid list entries + Select number of presets or coefficients depending on the mode **/ - UINT8 PcieRpLinkDownGpios[12]; + UINT8 PcieGen3EqPh3NoOfPresetOrCoeff[12]; -/** Offset 0x0BC5 - PCIE Compliance Test Mode - Compliance Test Mode shall be enabled when using Compliance Load Board. - $EN_DIS +/** Offset 0x05E8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieComplianceTestMode; + UINT8 PcieGen3EqPh3PreCursor0List[12]; -/** Offset 0x0BC6 - PCIE Rp Function Swap - Allows BIOS to use root port function number swapping when root port of function - 0 is disabled. - $EN_DIS +/** Offset 0x05F4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpFunctionSwap; + UINT8 PcieGen3EqPh3PostCursor0List[12]; -/** Offset 0x0BC7 - Reserved +/** Offset 0x0600 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved22[12]; + UINT8 PcieGen3EqPh3PreCursor1List[12]; -/** Offset 0x0BD3 - PCIe RootPort Power Gating - Describes whether the PCI Express Power Gating for each root port is enabled by - platform modules. 0: Disable; 1: Enable(Default). - $EN_DIS +/** Offset 0x060C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PciePowerGating[12]; + UINT8 PcieGen3EqPh3PostCursor1List[12]; -/** Offset 0x0BDF - Reserved +/** Offset 0x0618 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved23[49]; + UINT8 PcieGen3EqPh3PreCursor2List[12]; -/** Offset 0x0C10 - PCIE RP Ltr Max Snoop Latency - Latency Tolerance Reporting, Max Snoop Latency. +/** Offset 0x0624 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpLtrMaxSnoopLatency[24]; + UINT8 PcieGen3EqPh3PostCursor2List[12]; -/** Offset 0x0C40 - PCIE RP Ltr Max No Snoop Latency - Latency Tolerance Reporting, Max Non-Snoop Latency. +/** Offset 0x0630 - PCIR RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpLtrMaxNoSnoopLatency[24]; + UINT8 PcieGen3EqPh3PreCursor3List[12]; -/** Offset 0x0C70 - PCIE RP Snoop Latency Override Mode - Latency Tolerance Reporting, Snoop Latency Override Mode. +/** Offset 0x063C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpSnoopLatencyOverrideMode[28]; + UINT8 PcieGen3EqPh3PostCursor3List[12]; -/** Offset 0x0C8C - PCIE RP Snoop Latency Override Multiplier - Latency Tolerance Reporting, Snoop Latency Override Multiplier. +/** Offset 0x0648 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpSnoopLatencyOverrideMultiplier[28]; + UINT8 PcieGen3EqPh3PreCursor4List[12]; -/** Offset 0x0CA8 - PCIE RP Snoop Latency Override Value - Latency Tolerance Reporting, Snoop Latency Override Value. +/** Offset 0x0654 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpSnoopLatencyOverrideValue[24]; + UINT8 PcieGen3EqPh3PostCursor4List[12]; -/** Offset 0x0CD8 - PCIE RP Non Snoop Latency Override Mode - Latency Tolerance Reporting, Non-Snoop Latency Override Mode. +/** Offset 0x0660 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpNonSnoopLatencyOverrideMode[28]; + UINT8 PcieGen3EqPh3PreCursor5List[12]; -/** Offset 0x0CF4 - PCIE RP Non Snoop Latency Override Multiplier - Latency Tolerance Reporting, Non-Snoop Latency Override Multiplier. +/** Offset 0x066C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpNonSnoopLatencyOverrideMultiplier[28]; + UINT8 PcieGen3EqPh3PostCursor5List[12]; -/** Offset 0x0D10 - PCIE RP Non Snoop Latency Override Value - Latency Tolerance Reporting, Non-Snoop Latency Override Value. +/** Offset 0x0678 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpNonSnoopLatencyOverrideValue[24]; + UINT8 PcieGen3EqPh3PreCursor6List[12]; -/** Offset 0x0D40 - PCIE RP Slot Power Limit Scale - Specifies scale used for slot power limit value. Leave as 0 to set to default. +/** Offset 0x0684 - PCIe post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpSlotPowerLimitScale[28]; + UINT8 PcieGen3EqPh3PostCursor6List[12]; -/** Offset 0x0D5C - PCIE RP Slot Power Limit Value - Specifies upper limit on power supplie by slot. Leave as 0 to set to default. +/** Offset 0x0690 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpSlotPowerLimitValue[24]; + UINT8 PcieGen3EqPh3PreCursor7List[12]; -/** Offset 0x0D8C - PCIE RP Enable Port8xh Decode - This member describes whether PCIE root port Port 8xh Decode is enabled. 0: Disable; - 1: Enable. - $EN_DIS +/** Offset 0x069C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieEnablePort8xhDecode; + UINT8 PcieGen3EqPh3PostCursor7List[12]; -/** Offset 0x0D8D - PCIE Port8xh Decode Port Index - The Index of PCIe Port that is selected for Port8xh Decode (1 Based). +/** Offset 0x06A8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PchPciePort8xhDecodePortIndex; + UINT8 PcieGen3EqPh3PreCursor8List[12]; -/** Offset 0x0D8E - Reserved +/** Offset 0x06B4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved24[114]; + UINT8 PcieGen3EqPh3PostCursor8List[12]; -/** Offset 0x0E00 - SPIn Device Mode - Selects SPI operation mode. N represents controller index: SPI0, SPI1, ... Available - modes: 0:LpssSpiDisabled, 1:LpssSpiPci, 2:LpssSpiHidden +/** Offset 0x06C0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 SerialIoLpssSpiMode[7]; + UINT8 PcieGen3EqPh3PreCursor9List[12]; -/** Offset 0x0E07 - Reserved +/** Offset 0x06CC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved25[85]; + UINT8 PcieGen3EqPh3PostCursor9List[12]; -/** Offset 0x0E5C - SPIn Default Chip Select Mode HW/SW - Sets Default CS Mode Hardware or Software. N represents controller index: SPI0, - SPI1, ... Available options: 0:HW, 1:SW +/** Offset 0x06D8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoLpssSpiCsMode[7]; + UINT8 PcieGen3EqPh3Preset0List[12]; -/** Offset 0x0E63 - SPIn Default Chip Select State Low/High - Sets Default CS State Low or High. N represents controller index: SPI0, SPI1, ... - Available options: 0:Low, 1:High +/** Offset 0x06E4 - PCIe preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoLpssSpiCsState[7]; + UINT8 PcieGen3EqPh3Preset1List[12]; -/** Offset 0x0E6A - UARTn Device Mode - Selects Uart operation mode. N represents controller index: Uart0, Uart1, ... Available - modes: 0:SerialIoUartDisabled, 1:SerialIoUartPci, 2:SerialIoUartHidden, 3:SerialIoUartCom, - 4:SerialIoUartSkipInit +/** Offset 0x06F0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartMode[7]; + UINT8 PcieGen3EqPh3Preset2List[12]; -/** Offset 0x0E71 - Reserved +/** Offset 0x06FC - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 Reserved26[3]; + UINT8 PcieGen3EqPh3Preset3List[12]; -/** Offset 0x0E74 - Default BaudRate for each Serial IO UART - Set default BaudRate Supported from 0 - default to 6000000 +/** Offset 0x0708 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT32 SerialIoUartBaudRate[7]; + UINT8 PcieGen3EqPh3Preset4List[12]; -/** Offset 0x0E90 - Default ParityType for each Serial IO UART - Set default Parity. 0: DefaultParity, 1: NoParity, 2: EvenParity, 3: OddParity +/** Offset 0x0714 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartParity[7]; + UINT8 PcieGen3EqPh3Preset5List[12]; -/** Offset 0x0E97 - Default DataBits for each Serial IO UART - Set default word length. 0: Default, 5,6,7,8 +/** Offset 0x0720 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartDataBits[7]; + UINT8 PcieGen3EqPh3Preset6List[12]; -/** Offset 0x0E9E - Default StopBits for each Serial IO UART - Set default stop bits. 0: DefaultStopBits, 1: OneStopBit, 2: OneFiveStopBits, 3: - TwoStopBits +/** Offset 0x072C - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartStopBits[7]; + UINT8 PcieGen3EqPh3Preset7List[12]; -/** Offset 0x0EA5 - Power Gating mode for each Serial IO UART that works in COM mode - Set Power Gating. 0: Disabled, 1: Enabled, 2: Auto +/** Offset 0x0738 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartPowerGating[7]; + UINT8 PcieGen3EqPh3Preset8List[12]; -/** Offset 0x0EAC - Enable Dma for each Serial IO UART that supports it - Set DMA/PIO mode. 0: Disabled, 1: Enabled +/** Offset 0x0744 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartDmaEnable[7]; + UINT8 PcieGen3EqPh3Preset9List[12]; -/** Offset 0x0EB3 - Enables UART hardware flow control, CTS and RTS lines - Enables UART hardware flow control, CTS and RTS lines. +/** Offset 0x0750 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartAutoFlow[7]; + UINT8 PcieGen3EqPh3Preset10List[12]; -/** Offset 0x0EBA - Reserved +/** Offset 0x075C - PCIe EQ phase 1 downstream transmitter port preset + Allows to select the downstream port preset value that will be used during phase + 1 of equalization **/ - UINT8 Reserved27[2]; + UINT8 PcieGen3EqPh1DpTxPreset[12]; -/** Offset 0x0EBC - SerialIoUartRtsPinMuxPolicy - Select SerialIo Uart Rts pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RTS* - for possible values. +/** Offset 0x0768 - PCIE RP EQ phase 1 upstream tranmitter port preset + Allows to select the upstream port preset value that will be used during phase 1 + of equalization **/ - UINT32 SerialIoUartRtsPinMuxPolicy[7]; + UINT8 PcieGen3EqPh1UpTxPreset[12]; -/** Offset 0x0ED8 - SerialIoUartRxPinMuxPolicy - Select SerialIo Uart Rx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RX* for - possible values. +/** Offset 0x0774 - PCIE RP EQ phase 2 local transmitter override preset + Allows to select the value of the preset used during phase 2 local transmitter override **/ - UINT32 SerialIoUartRxPinMuxPolicy[7]; + UINT8 PcieGen3EqPh2LocalTxOverridePreset[12]; -/** Offset 0x0EF4 - SerialIoUartTxPinMuxPolicy - Select SerialIo Uart Tx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_TX* for - possible values. +/** Offset 0x0780 - PCIE RP choose EQ method + Choose PCIe EQ method + 0: HardwareEq, 1: FixedEq **/ - UINT32 SerialIoUartTxPinMuxPolicy[7]; + UINT8 PcieGen4EqMethod[12]; -/** Offset 0x0F10 - Serial IO UART DBG2 table - Enable or disable Serial Io UART DBG2 table, default is Disable; 0: Disable; - 1: Enable. +/** Offset 0x078C - PCIE RP choose EQ mode + Choose PCIe EQ mode + 0: PresetEq, 1: CoefficientEq **/ - UINT8 SerialIoUartDbg2[7]; + UINT8 PcieGen4EqMode[12]; -/** Offset 0x0F17 - Reserved +/** Offset 0x0798 - PCIE RP EQ local transmitter override + Enable/Disable local transmitter override + $EN_DIS **/ - UINT8 Reserved28[7]; + UINT8 PcieGen4EqLocalTxOverrideEn[12]; -/** Offset 0x0F1E - I2Cn Device Mode - Selects I2c operation mode. N represents controller index: I2c0, I2c1, ... Available - modes: 0:SerialIoI2cDisabled, 1:SerialIoI2cPci, 2:SerialIoI2cHidden +/** Offset 0x07A4 - PCI RP number of valid list entries + Select number of presets or coefficients depending on the mode **/ - UINT8 SerialIoI2cMode[8]; + UINT8 PcieGen4EqPh3NoOfPresetOrCoeff[12]; -/** Offset 0x0F26 - Reserved +/** Offset 0x07B0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved29[2]; + UINT8 PcieGen4EqPh3PreCursor0List[12]; -/** Offset 0x0F28 - Serial IO I2C SDA Pin Muxing - Select SerialIo I2c Sda pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SDA* for - possible values. +/** Offset 0x07BC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT32 PchSerialIoI2cSdaPinMux[8]; + UINT8 PcieGen4EqPh3PostCursor0List[12]; -/** Offset 0x0F48 - Serial IO I2C SCL Pin Muxing - Select SerialIo I2c Scl pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SCL* for - possible values. +/** Offset 0x07C8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT32 PchSerialIoI2cSclPinMux[8]; + UINT8 PcieGen4EqPh3PreCursor1List[12]; -/** Offset 0x0F68 - PCH SerialIo I2C Pads Termination - 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, - 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C0,I2C1,... pads termination - respectively. One byte for each controller, byte0 for I2C0, byte1 for I2C1, and so on. +/** Offset 0x07D4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PchSerialIoI2cPadsTermination[8]; + UINT8 PcieGen4EqPh3PostCursor1List[12]; -/** Offset 0x0F70 - I3C Device Mode - Selects I3c operation mode. Available modes: 0:SerialIoI3cDisabled, 1:SerialIoI3cPci, - 2:SerialIoI3cPhantom (only applicable to I3C1, controlls GPIO enabling) +/** Offset 0x07E0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 SerialIoI3cMode[3]; + UINT8 PcieGen4EqPh3PreCursor2List[12]; -/** Offset 0x0F73 - Reserved +/** Offset 0x07EC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved30[48]; + UINT8 PcieGen4EqPh3PostCursor2List[12]; -/** Offset 0x0FA3 - Enable VMD controller - Enable/disable to VMD controller.0: Disable; 1: Enable(Default) - $EN_DIS +/** Offset 0x07F8 - PCIR RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdEnable; + UINT8 PcieGen4EqPh3PreCursor3List[12]; -/** Offset 0x0FA4 - Enable VMD Global Mapping - Enable/disable to VMD controller.0: Disable(Default); 1: Enable - $EN_DIS +/** Offset 0x0804 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdGlobalMapping; + UINT8 PcieGen4EqPh3PostCursor3List[12]; -/** Offset 0x0FA5 - Map port under VMD - Map/UnMap port under VMD - $EN_DIS +/** Offset 0x0810 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdPort[31]; + UINT8 PcieGen4EqPh3PreCursor4List[12]; -/** Offset 0x0FC4 - Reserved +/** Offset 0x081C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved31[31]; + UINT8 PcieGen4EqPh3PostCursor4List[12]; -/** Offset 0x0FE3 - VMD Port Device - VMD Root port device number. +/** Offset 0x0828 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdPortDev[31]; + UINT8 PcieGen4EqPh3PreCursor5List[12]; -/** Offset 0x1002 - VMD Port Func - VMD Root port function number. +/** Offset 0x0834 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdPortFunc[31]; + UINT8 PcieGen4EqPh3PostCursor5List[12]; -/** Offset 0x1021 - Reserved +/** Offset 0x0840 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved32[7]; + UINT8 PcieGen4EqPh3PreCursor6List[12]; -/** Offset 0x1028 - VMD Variable - VMD Variable Pointer. +/** Offset 0x084C - PCIe post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT64 VmdVariablePtr; + UINT8 PcieGen4EqPh3PostCursor6List[12]; -/** Offset 0x1030 - Reserved +/** Offset 0x0858 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved33[4]; + UINT8 PcieGen4EqPh3PreCursor7List[12]; -/** Offset 0x1034 - Temporary MemBar1 address for VMD - VMD Variable Pointer. +/** Offset 0x0864 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT32 VmdMemBar1Base; + UINT8 PcieGen4EqPh3PostCursor7List[12]; -/** Offset 0x1038 - Temporary MemBar2 address for VMD +/** Offset 0x0870 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3PreCursor8List[12]; + +/** Offset 0x087C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3PostCursor8List[12]; + +/** Offset 0x0888 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3PreCursor9List[12]; + +/** Offset 0x0894 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3PostCursor9List[12]; + +/** Offset 0x08A0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset0List[12]; + +/** Offset 0x08AC - PCIe preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset1List[12]; + +/** Offset 0x08B8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset2List[12]; + +/** Offset 0x08C4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset3List[12]; + +/** Offset 0x08D0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset4List[12]; + +/** Offset 0x08DC - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset5List[12]; + +/** Offset 0x08E8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset6List[12]; + +/** Offset 0x08F4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset7List[12]; + +/** Offset 0x0900 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset8List[12]; + +/** Offset 0x090C - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset9List[12]; + +/** Offset 0x0918 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset10List[12]; + +/** Offset 0x0924 - PCIe EQ phase 1 downstream transmitter port preset + Allows to select the downstream port preset value that will be used during phase + 1 of equalization +**/ + UINT8 PcieGen4EqPh1DpTxPreset[12]; + +/** Offset 0x0930 - PCIE RP EQ phase 1 upstream tranmitter port preset + Allows to select the upstream port preset value that will be used during phase 1 + of equalization +**/ + UINT8 PcieGen4EqPh1UpTxPreset[12]; + +/** Offset 0x093C - PCIE RP EQ phase 2 local transmitter override preset + Allows to select the value of the preset used during phase 2 local transmitter override +**/ + UINT8 PcieGen4EqPh2LocalTxOverridePreset[12]; + +/** Offset 0x0948 - PCIE RP choose EQ method + Choose PCIe EQ method + 0: HardwareEq, 1: FixedEq +**/ + UINT8 PcieGen5EqMethod[12]; + +/** Offset 0x0954 - PCIE RP choose EQ mode + Choose PCIe EQ mode + 0: PresetEq, 1: CoefficientEq +**/ + UINT8 PcieGen5EqMode[12]; + +/** Offset 0x0960 - PCIE RP EQ local transmitter override + Enable/Disable local transmitter override + $EN_DIS +**/ + UINT8 PcieGen5EqLocalTxOverrideEn[12]; + +/** Offset 0x096C - PCI RP number of valid list entries + Select number of presets or coefficients depending on the mode +**/ + UINT8 PcieGen5EqPh3NoOfPresetOrCoeff[12]; + +/** Offset 0x0978 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor0List[12]; + +/** Offset 0x0984 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor0List[12]; + +/** Offset 0x0990 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor1List[12]; + +/** Offset 0x099C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor1List[12]; + +/** Offset 0x09A8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor2List[12]; + +/** Offset 0x09B4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor2List[12]; + +/** Offset 0x09C0 - PCIR RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor3List[12]; + +/** Offset 0x09CC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor3List[12]; + +/** Offset 0x09D8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor4List[12]; + +/** Offset 0x09E4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor4List[12]; + +/** Offset 0x09F0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor5List[12]; + +/** Offset 0x09FC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor5List[12]; + +/** Offset 0x0A08 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor6List[12]; + +/** Offset 0x0A14 - PCIe post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor6List[12]; + +/** Offset 0x0A20 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor7List[12]; + +/** Offset 0x0A2C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor7List[12]; + +/** Offset 0x0A38 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor8List[12]; + +/** Offset 0x0A44 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor8List[12]; + +/** Offset 0x0A50 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor9List[12]; + +/** Offset 0x0A5C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor9List[12]; + +/** Offset 0x0A68 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset0List[12]; + +/** Offset 0x0A74 - PCIe preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset1List[12]; + +/** Offset 0x0A80 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset2List[12]; + +/** Offset 0x0A8C - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset3List[12]; + +/** Offset 0x0A98 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset4List[12]; + +/** Offset 0x0AA4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset5List[12]; + +/** Offset 0x0AB0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset6List[12]; + +/** Offset 0x0ABC - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset7List[12]; + +/** Offset 0x0AC8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset8List[12]; + +/** Offset 0x0AD4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset9List[12]; + +/** Offset 0x0AE0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset10List[12]; + +/** Offset 0x0AEC - PCIe EQ phase 1 downstream transmitter port preset + Allows to select the downstream port preset value that will be used during phase + 1 of equalization +**/ + UINT8 PcieGen5EqPh1DpTxPreset[12]; + +/** Offset 0x0AF8 - PCIE RP EQ phase 1 upstream tranmitter port preset + Allows to select the upstream port preset value that will be used during phase 1 + of equalization +**/ + UINT8 PcieGen5EqPh1UpTxPreset[12]; + +/** Offset 0x0B04 - PCIE RP EQ phase 2 local transmitter override preset + Allows to select the value of the preset used during phase 2 local transmitter override +**/ + UINT8 PcieGen5EqPh2LocalTxOverridePreset[12]; + +/** Offset 0x0B10 - Phase3 RP Gen3 EQ enable + Phase3 Gen3 EQ enable. Disabled(0x0)(Default): Disable phase 3, Enabled(0x1): Enable phase 3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen3EqPh3Bypass[12]; + +/** Offset 0x0B1C - Phase3 RP Gen4 EQ enable + Phase3 Gen4 EQ enable. Disabled(0x0)(Default): Disable phase 3, Enabled(0x1): Enable phase 3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen4EqPh3Bypass[12]; + +/** Offset 0x0B28 - Phase3 RP Gen5 EQ enable + Phase3 Gen5 EQ enable. Disabled(0x0)(Default): Disable phase 3, Enabled(0x1): Enable phase 3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen5EqPh3Bypass[12]; + +/** Offset 0x0B34 - Phase2-3 RP Gen3 EQ enable + Phase2-3 Gen3 EQ enable. Disabled(0x0)(Default): Disable Phase2-3, Enabled(0x1): + Enable Phase2-3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen3EqPh23Bypass[12]; + +/** Offset 0x0B40 - Phase2-3 RP Gen4 EQ enable + Phase2-3 Gen4 EQ enable. Disabled(0x0)(Default): Disable Phase2-3, Enabled(0x1): + Enable Phase2-3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen4EqPh23Bypass[12]; + +/** Offset 0x0B4C - Phase2-3 RP Gen5 EQ enable + Phase2-3 Gen5 EQ enable. Disabled(0x0)(Default): Disable Phase2-3, Enabled(0x1): + Enable Phase2-3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen5EqPh23Bypass[12]; + +/** Offset 0x0B58 - PCET Timer + Preset/Coefficient Evaluation Timeout Gen3 PCET Timer. See PCIE_GEN3_PCET. Default + is 0x0(2ms) +**/ + UINT8 PcieGen3PcetTimer[12]; + +/** Offset 0x0B64 - Gen4 PCET Timer + Preset/Coefficient Evaluation Timeout - Gen4 PCET Timer. See PCIE_GEN4_PCET. Default + is 0x0(2ms) +**/ + UINT8 PcieGen4PcetTimer[12]; + +/** Offset 0x0B70 - Gen5 PCET Timer + Preset/Coefficient Evaluation Timeout - Gen5 PCET Timer. See PCIE_GEN5_PCET. Default + is 0x0(2ms) +**/ + UINT8 PcieGen5PcetTimer[12]; + +/** Offset 0x0B7C - TS Lock Timer for Gen3 + Training Sequence Wait Latency For Presets/Coefficients Evaluation - Gen3 TS Lock + Timer. See PCIE_GEN3_TS_LOCK_TIMER. Default is 0x0 +**/ + UINT8 PcieGen3TsLockTimer[12]; + +/** Offset 0x0B88 - PTS Lock Timer for Gen4 + Training Sequence Wait Latency For Presets/Coefficients Evaluation - Gen4 TS Lock + Timer. See PCIE_GEN4_TS_LCOK_TIMER. Default is 0x0 +**/ + UINT8 PcieGen4TsLockTimer[12]; + +/** Offset 0x0B94 - PTS Lock Timer for Gen5 + Training Sequence Wait Latency For Presets/Coefficients Evaluation - Gen5 TS Lock + Timer. See PCIE_GEN5_TS_LCOK_TIMER. Default is 0x0 +**/ + UINT8 PcieGen5TsLockTimer[12]; + +/** Offset 0x0BA0 - PCIE Secure Register Lock + Describes whether Secure Register Lock is enaled or disabled. When it will be enbaled, + load PcieRpSetSecuredRegisterLock recipe. 0: Disable(Default); 1: Enable + $EN_DIS +**/ + UINT8 PcieSetSecuredRegisterLock; + +/** Offset 0x0BA1 - Enable/Disable ASPM Optionality Compliance + Enable/Disable ASPM Optionality Compliance. +**/ + UINT8 PcieRpTestAspmOc[12]; + +/** Offset 0x0BAD - PCIE RP Enable Peer Memory Write + This member describes whether Peer Memory Writes are enabled on the platform. + $EN_DIS +**/ + UINT8 PcieEnablePeerMemoryWrite[12]; + +/** Offset 0x0BB9 - Assertion on Link Down GPIOs + GPIO Assertion on Link Down. Disabled(0x0)(Default): Disable assertion on Link Down + GPIOs, Enabled(0x1): Enable assertion on Link Down GPIOs + 0:Disable, 1:Enable +**/ + UINT8 PcieRpLinkDownGpios[12]; + +/** Offset 0x0BC5 - PCIE Compliance Test Mode + Compliance Test Mode shall be enabled when using Compliance Load Board. + $EN_DIS +**/ + UINT8 PcieComplianceTestMode; + +/** Offset 0x0BC6 - PCIE Rp Function Swap + Allows BIOS to use root port function number swapping when root port of function + 0 is disabled. + $EN_DIS +**/ + UINT8 PcieRpFunctionSwap; + +/** Offset 0x0BC7 - PCIe RootPort Clock Gating + Describes whether the PCI Express Clock Gating for each root port is enabled by + platform modules. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieClockGating[12]; + +/** Offset 0x0BD3 - PCIe RootPort Power Gating + Describes whether the PCI Express Power Gating for each root port is enabled by + platform modules. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PciePowerGating[12]; + +/** Offset 0x0BDF - PCIe RootPort VISA Clock Gating + Describes whether the PCI Express VISA Clock Gating. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieVisaClockGating[12]; + +/** Offset 0x0BEB - PCIe RootPort AutoPower Gating + Describes the Auto Power Gating for per controller. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieAutoPowerGating[12]; + +/** Offset 0x0BF7 - PCIe RootPort PHY AutoPower Gating + Describes the PHY Auto Power Gating for per controller. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PciePhyAutoPowerGating; + +/** Offset 0x0BF8 - FOMS Control Policy + Choose the Foms Control Policy, Default = 0 + 0: Auto, 1: Gen3 Foms, 2: Gen4 Foms, 3: Gen3 and Gen4 Foms +**/ + UINT8 PcieFomsCp[12]; + +/** Offset 0x0C04 - EqPhBypass Control Policy + PCIe Equalization Phase Enable Control, Disabled (0x0) : Disable Phase + (Default), Enabled (0x1) : Enable Phase + 0: Auto, 1: Gen3 Foms, 2: Gen4 Foms, 3: Gen3 and Gen4 Foms +**/ + UINT8 PcieEqPhBypass[12]; + +/** Offset 0x0C10 - PCIE RP Ltr Max Snoop Latency + Latency Tolerance Reporting, Max Snoop Latency. +**/ + UINT16 PcieRpLtrMaxSnoopLatency[24]; + +/** Offset 0x0C40 - PCIE RP Ltr Max No Snoop Latency + Latency Tolerance Reporting, Max Non-Snoop Latency. +**/ + UINT16 PcieRpLtrMaxNoSnoopLatency[24]; + +/** Offset 0x0C70 - PCIE RP Snoop Latency Override Mode + Latency Tolerance Reporting, Snoop Latency Override Mode. +**/ + UINT8 PcieRpSnoopLatencyOverrideMode[28]; + +/** Offset 0x0C8C - PCIE RP Snoop Latency Override Multiplier + Latency Tolerance Reporting, Snoop Latency Override Multiplier. +**/ + UINT8 PcieRpSnoopLatencyOverrideMultiplier[28]; + +/** Offset 0x0CA8 - PCIE RP Snoop Latency Override Value + Latency Tolerance Reporting, Snoop Latency Override Value. +**/ + UINT16 PcieRpSnoopLatencyOverrideValue[24]; + +/** Offset 0x0CD8 - PCIE RP Non Snoop Latency Override Mode + Latency Tolerance Reporting, Non-Snoop Latency Override Mode. +**/ + UINT8 PcieRpNonSnoopLatencyOverrideMode[28]; + +/** Offset 0x0CF4 - PCIE RP Non Snoop Latency Override Multiplier + Latency Tolerance Reporting, Non-Snoop Latency Override Multiplier. +**/ + UINT8 PcieRpNonSnoopLatencyOverrideMultiplier[28]; + +/** Offset 0x0D10 - PCIE RP Non Snoop Latency Override Value + Latency Tolerance Reporting, Non-Snoop Latency Override Value. +**/ + UINT16 PcieRpNonSnoopLatencyOverrideValue[24]; + +/** Offset 0x0D40 - PCIE RP Slot Power Limit Scale + Specifies scale used for slot power limit value. Leave as 0 to set to default. +**/ + UINT8 PcieRpSlotPowerLimitScale[28]; + +/** Offset 0x0D5C - PCIE RP Slot Power Limit Value + Specifies upper limit on power supplie by slot. Leave as 0 to set to default. +**/ + UINT16 PcieRpSlotPowerLimitValue[24]; + +/** Offset 0x0D8C - PCIE RP Enable Port8xh Decode + This member describes whether PCIE root port Port 8xh Decode is enabled. 0: Disable; + 1: Enable. + $EN_DIS +**/ + UINT8 PcieEnablePort8xhDecode; + +/** Offset 0x0D8D - PCIE Port8xh Decode Port Index + The Index of PCIe Port that is selected for Port8xh Decode (1 Based). +**/ + UINT8 PchPciePort8xhDecodePortIndex; + +/** Offset 0x0D8E - PCIE RP LTR Override Spec Compliant + Override LTR based on Ep capability. +**/ + UINT8 PcieRpLtrOverrideSpecCompliant[28]; + +/** Offset 0x0DAA - PCIe AER _OSC Setting + Enable/Disable Global PCIe Advanced Error Reporting + 0:Disable, 1:Enable +**/ + UINT8 GlobalPcieAer; + +/** Offset 0x0DAB - PCIe TBT Performance Boost Bitmap + Bitmap of TBT performance boost enabled PCIe controllers to which discrete TBT controllers + connect. Bit0: PXPA, Bit1: PXPB, Bit2: PXPC, Bit3: PXPD, Bit4: PXPE +**/ + UINT8 PcieTbtPerfBoost; + +/** Offset 0x0DAC - Serial IO SPI CLK Pin Muxing + Select SerialIo LPSS SPI CS pin muxing. Refer to GPIO_*_MUXING_SERIALIO_SPIx_CLK* + for possible values. +**/ + UINT32 SerialIoLpssSpiClkPinMux[7]; + +/** Offset 0x0DC8 - Serial IO SPI CS Pin Muxing + Select SerialIo LPSS SPI CS pin muxing. Refer to GPIO_*_MUXING_SERIALIO_SPIx_CS* + for possible values. +**/ + UINT32 SerialIoLpssSpiCsPinMux[14]; + +/** Offset 0x0E00 - SPIn Device Mode + Selects SPI operation mode. N represents controller index: SPI0, SPI1, ... Available + modes: 0:LpssSpiDisabled, 1:LpssSpiPci, 2:LpssSpiHidden +**/ + UINT8 SerialIoLpssSpiMode[7]; + +/** Offset 0x0E07 - Reserved +**/ + UINT8 Reserved7; + +/** Offset 0x0E08 - LPSS SPI MOSI Pin Muxing + Select LPSS SPI MOSI pin muxing. Refer to GPIO_*_MUXING_LPSS_SPIx_MOSI* for possible values. +**/ + UINT32 SerialIoLpssSpiMosiPinMux[7]; + +/** Offset 0x0E24 - LPSS SPI MISO Pin Muxing + Select Lpss SPI MISO pin muxing. Refer to GPIO_*_MUXING_LPSS_SPIx_MISO* for possible values. +**/ + UINT32 SerialIoLpssSpiMisoPinMux[7]; + +/** Offset 0x0E40 - SPI Chip Select Polarity + Sets polarity for each chip Select. Available options: 0:LpssSpiCsActiveLow, 1:LpssSpiCsActiveHigh +**/ + UINT8 SerialIoLpssSpiCsPolarity[14]; + +/** Offset 0x0E4E - SPI Chip Select Enable + 0:Disabled, 1:Enabled. Enables GPIO for CS0 or CS1 if it is Enabled +**/ + UINT8 SerialIoLpssSpiCsEnable[14]; + +/** Offset 0x0E5C - SPIn Default Chip Select Mode HW/SW + Sets Default CS Mode Hardware or Software. N represents controller index: SPI0, + SPI1, ... Available options: 0:HW, 1:SW +**/ + UINT8 SerialIoLpssSpiCsMode[7]; + +/** Offset 0x0E63 - SPIn Default Chip Select State Low/High + Sets Default CS State Low or High. N represents controller index: SPI0, SPI1, ... + Available options: 0:Low, 1:High +**/ + UINT8 SerialIoLpssSpiCsState[7]; + +/** Offset 0x0E6A - UARTn Device Mode + Selects Uart operation mode. N represents controller index: Uart0, Uart1, ... Available + modes: 0:SerialIoUartDisabled, 1:SerialIoUartPci, 2:SerialIoUartHidden, 3:SerialIoUartCom, + 4:SerialIoUartSkipInit +**/ + UINT8 SerialIoUartMode[7]; + +/** Offset 0x0E71 - Reserved +**/ + UINT8 Reserved8[3]; + +/** Offset 0x0E74 - Default BaudRate for each Serial IO UART + Set default BaudRate Supported from 0 - default to 6000000 +**/ + UINT32 SerialIoUartBaudRate[7]; + +/** Offset 0x0E90 - Default ParityType for each Serial IO UART + Set default Parity. 0: DefaultParity, 1: NoParity, 2: EvenParity, 3: OddParity +**/ + UINT8 SerialIoUartParity[7]; + +/** Offset 0x0E97 - Default DataBits for each Serial IO UART + Set default word length. 0: Default, 5,6,7,8 +**/ + UINT8 SerialIoUartDataBits[7]; + +/** Offset 0x0E9E - Default StopBits for each Serial IO UART + Set default stop bits. 0: DefaultStopBits, 1: OneStopBit, 2: OneFiveStopBits, 3: + TwoStopBits +**/ + UINT8 SerialIoUartStopBits[7]; + +/** Offset 0x0EA5 - Power Gating mode for each Serial IO UART that works in COM mode + Set Power Gating. 0: Disabled, 1: Enabled, 2: Auto +**/ + UINT8 SerialIoUartPowerGating[7]; + +/** Offset 0x0EAC - Enable Dma for each Serial IO UART that supports it + Set DMA/PIO mode. 0: Disabled, 1: Enabled +**/ + UINT8 SerialIoUartDmaEnable[7]; + +/** Offset 0x0EB3 - Enables UART hardware flow control, CTS and RTS lines + Enables UART hardware flow control, CTS and RTS lines. +**/ + UINT8 SerialIoUartAutoFlow[7]; + +/** Offset 0x0EBA - Reserved +**/ + UINT8 Reserved9[2]; + +/** Offset 0x0EBC - SerialIoUartRtsPinMuxPolicy + Select SerialIo Uart Rts pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RTS* + for possible values. +**/ + UINT32 SerialIoUartRtsPinMuxPolicy[7]; + +/** Offset 0x0ED8 - SerialIoUartRxPinMuxPolicy + Select SerialIo Uart Rx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RX* for + possible values. +**/ + UINT32 SerialIoUartRxPinMuxPolicy[7]; + +/** Offset 0x0EF4 - SerialIoUartTxPinMuxPolicy + Select SerialIo Uart Tx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_TX* for + possible values. +**/ + UINT32 SerialIoUartTxPinMuxPolicy[7]; + +/** Offset 0x0F10 - Serial IO UART DBG2 table + Enable or disable Serial Io UART DBG2 table, default is Disable; 0: Disable; + 1: Enable. +**/ + UINT8 SerialIoUartDbg2[7]; + +/** Offset 0x0F17 - Serial IO UART PG DBG2 table + Enable or disable Serial Io UART PG DBG2 table, default is Disable; 0: Disable; + 1: Enable. +**/ + UINT8 SerialIoUartPgDbg2[7]; + +/** Offset 0x0F1E - I2Cn Device Mode + Selects I2c operation mode. N represents controller index: I2c0, I2c1, ... Available + modes: 0:SerialIoI2cDisabled, 1:SerialIoI2cPci, 2:SerialIoI2cHidden +**/ + UINT8 SerialIoI2cMode[8]; + +/** Offset 0x0F26 - Reserved +**/ + UINT8 Reserved10[2]; + +/** Offset 0x0F28 - Serial IO I2C SDA Pin Muxing + Select SerialIo I2c Sda pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SDA* for + possible values. +**/ + UINT32 PchSerialIoI2cSdaPinMux[8]; + +/** Offset 0x0F48 - Serial IO I2C SCL Pin Muxing + Select SerialIo I2c Scl pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SCL* for + possible values. +**/ + UINT32 PchSerialIoI2cSclPinMux[8]; + +/** Offset 0x0F68 - PCH SerialIo I2C Pads Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C0,I2C1,... pads termination + respectively. One byte for each controller, byte0 for I2C0, byte1 for I2C1, and so on. +**/ + UINT8 PchSerialIoI2cPadsTermination[8]; + +/** Offset 0x0F70 - I3C Device Mode + Selects I3c operation mode. Available modes: 0:SerialIoI3cDisabled, 1:SerialIoI3cPci, + 2:SerialIoI3cPhantom (only applicable to I3C1, controlls GPIO enabling) +**/ + UINT8 SerialIoI3cMode[3]; + +/** Offset 0x0F73 - Reserved +**/ + UINT8 Reserved11; + +/** Offset 0x0F74 - Serial IO I3C SDA Pin Muxing + Select SerialIo I3c Sda pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I3Cx_SDA* for + possible values. +**/ + UINT32 SerialIoI3cSdaPinMux[3]; + +/** Offset 0x0F80 - Serial IO I3C SDA Pad Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I3C0,I3C1,... pads termination + respectively. One byte for each controller, byte0 for I3C0, byte1 for I3C1, and so on. +**/ + UINT8 SerialIoI3cSdaPadTermination[3]; + +/** Offset 0x0F83 - Reserved +**/ + UINT8 Reserved12; + +/** Offset 0x0F84 - Serial IO I3C SCL Pin Muxing + Select SerialIo I3c Scl pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I3Cx_SCL* for + possible values. +**/ + UINT32 SerialIoI3cSclPinMux[3]; + +/** Offset 0x0F90 - Serial IO I3C SCL Pad Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I3C0,I3C1,... pads termination + respectively. One byte for each controller, byte0 for I3C0, byte1 for I3C1, and so on. +**/ + UINT8 SerialIoI3cSclPadTermination[3]; + +/** Offset 0x0F93 - Reserved +**/ + UINT8 Reserved13; + +/** Offset 0x0F94 - Serial IO I3C SCL FB Pin Muxing + Select SerialIo I3c SclFb pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I3Cx_SCL FB* + for possible values. +**/ + UINT32 SerialIoI3cSclFbPinMux[3]; + +/** Offset 0x0FA0 - Serial IO I3C SCL FB Pad Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I3C0,I3C1,... pads termination + respectively. One byte for each controller, byte0 for I3C0, byte1 for I3C1, and so on. +**/ + UINT8 SerialIoI3cSclFbPadTermination[3]; + +/** Offset 0x0FA3 - Enable VMD controller + Enable/disable to VMD controller.0: Disable; 1: Enable(Default) + $EN_DIS +**/ + UINT8 VmdEnable; + +/** Offset 0x0FA4 - Enable VMD Global Mapping + Enable/disable to VMD controller.0: Disable(Default); 1: Enable + $EN_DIS +**/ + UINT8 VmdGlobalMapping; + +/** Offset 0x0FA5 - Map port under VMD + Map/UnMap port under VMD + $EN_DIS +**/ + UINT8 VmdPort[31]; + +/** Offset 0x0FC4 - VMD Port Bus + VMD Root port bus number. +**/ + UINT8 VmdPortBus[31]; + +/** Offset 0x0FE3 - VMD Port Device + VMD Root port device number. +**/ + UINT8 VmdPortDev[31]; + +/** Offset 0x1002 - VMD Port Func + VMD Root port function number. +**/ + UINT8 VmdPortFunc[31]; + +/** Offset 0x1021 - Reserved +**/ + UINT8 Reserved14[7]; + +/** Offset 0x1028 - VMD Variable + VMD Variable Pointer. +**/ + UINT64 VmdVariablePtr; + +/** Offset 0x1030 - Temporary CfgBar address for VMD + VMD Variable Pointer. +**/ + UINT32 VmdCfgBarBase; + +/** Offset 0x1034 - Temporary MemBar1 address for VMD + VMD Variable Pointer. +**/ + UINT32 VmdMemBar1Base; + +/** Offset 0x1038 - Temporary MemBar2 address for VMD VMD Variable Pointer. **/ UINT32 VmdMemBar2Base; @@ -1473,9 +2466,15 @@ typedef struct { **/ UINT8 D3HotEnable; -/** Offset 0x103D - Reserved +/** Offset 0x103D - TCSS TBT Performance Boost Bitmap + Bitmap of TBT performance boost enabled TCSS PCIe root ports. Bit0: TCSS port0, + Bit1: TCSS port1, Bit2: TCSS port2, Bit3: TCSS port3 **/ - UINT8 Reserved34[3]; + UINT8 TcssTbtPerfBoost; + +/** Offset 0x103E - Reserved +**/ + UINT8 Reserved15[2]; /** Offset 0x1040 - TypeC port GPIO setting GPIO Ping number for Type C Aux orientation setting, use the GpioPad that is defined @@ -1500,9 +2499,17 @@ typedef struct { **/ UINT8 TcCstateLimit; -/** Offset 0x107C - Reserved +/** Offset 0x107C - TC Notify Igd + Tc Notify Igd +**/ + UINT8 TcNotifyIgd; + +/** Offset 0x107D - TCSS CPU USB PDO Programming + Enable/disable PDO programming for TCSS CPU USB in PEI phase. Disabling will allow + for programming during later phase. 1: enable, 0: disable + $EN_DIS **/ - UINT8 Reserved35[2]; + UINT8 TcssCpuUsbPdoProgramming; /** Offset 0x107E - Enable/Disable PMC-PD Solution This policy will enable/disable PMC-PD Solution vs EC-TCPC Solution @@ -1512,7 +2519,7 @@ typedef struct { /** Offset 0x107F - Reserved **/ - UINT8 Reserved36; + UINT8 Reserved16; /** Offset 0x1080 - TCSS Aux Orientation Override Enable Bits 0, 2, ... 10 control override enables, bits 1, 3, ... 11 control overrides @@ -1586,9 +2593,11 @@ typedef struct { **/ UINT8 SaPcieItbtRpLtrConfigLock[4]; -/** Offset 0x10B6 - Reserved +/** Offset 0x10B6 - Type C Port x Convert to TypeA + Enable / Disable(default) Type C Port x Convert to TypeA + $EN_DIS **/ - UINT8 Reserved37[4]; + UINT8 EnableTcssCovTypeA[4]; /** Offset 0x10BA - Touch Host Controller Assignment Assign THC 0x0:ThcAssignmentNone, 0x1:ThcAssignmentThc0, 0x2:ThcAssignmentThc1 @@ -1612,9 +2621,276 @@ typedef struct { **/ UINT8 ThcWakeOnTouch[2]; -/** Offset 0x10C8 - Reserved +/** Offset 0x10C8 - Touch Host Controller Active Ltr + Expose Active Ltr for OS driver to set +**/ + UINT32 ThcActiveLtr[2]; + +/** Offset 0x10D0 - Touch Host Controller Idle Ltr + Expose Idle Ltr for OS driver to set +**/ + UINT32 ThcIdleLtr[2]; + +/** Offset 0x10D8 - Touch Host Controller Timestamp timer behavior in D0i2 + Timestamp timer behavior in D0i2. 1 = Timer resets to 0 when entering D0i2 0 = Timer + is paused instead of reset to 0 when entering D0i2 +**/ + UINT8 TimestampTimerMode[2]; + +/** Offset 0x10DA - Reserved +**/ + UINT8 Reserved17[2]; + +/** Offset 0x10DC - Touch Host Controller Display Frame Sync Period + Period of the emulated display frame sync [ms] The minimum period is 2ms, maximum + period is 100ms +**/ + UINT32 DisplayFrameSyncPeriod[2]; + +/** Offset 0x10E4 - Touch Host Controller ResetPad + ResetPad +**/ + UINT32 ThcResetPad[2]; + +/** Offset 0x10EC - Touch Host Controller ResetPad Trigger + Hid Over Spi Reset Pad Trigger 0x0:Low, 0x1:High +**/ + UINT32 ThcResetPadTrigger[2]; + +/** Offset 0x10F4 - Touch Host Controller DYSync + Based on this setting GPIO for given THC will be in native mode +**/ + UINT8 ThcDsyncPad[2]; + +/** Offset 0x10F6 - Reserved +**/ + UINT8 Reserved18[2]; + +/** Offset 0x10F8 - Touch Host Controller Hid Over Spi Connection Speed + Hid Over Spi Connection Speed - SPI Frequency +**/ + UINT32 ThcHidSpiConnectionSpeed[2]; + +/** Offset 0x1100 - Touch Host Controller Hid Over Spi Limit PacketSize + When set, limits SPI read & write packet size to 64B. Otherwise, THC uses Max Soc + packet size for SPI Read and Write 0x0- Max Soc Packet Size, 0x11 - 64 Bytes +**/ + UINT32 ThcHidSpiLimitPacketSize[2]; + +/** Offset 0x1108 - Touch Host Controller Hid Over Spi Limit PacketSize + Minimum amount of delay the THC/QUICKSPI driver must wait between end of write operation + and begin of read operation. This value shall be in 10us multiples 0x0: Disabled, + 1-65535 (0xFFFF) - up to 655350 us +**/ + UINT32 ThcPerformanceLimitation[2]; + +/** Offset 0x1110 - Touch Host Controller Hid Over Spi Input Report Header Address + Hid Over Spi Input Report Header Address +**/ + UINT32 ThcHidSpiInputReportHeaderAddress[2]; + +/** Offset 0x1118 - Touch Host Controller Hid Over Spi Input Report Body Address + Hid Over Spi Input Report Body Address +**/ + UINT32 ThcHidSpiInputReportBodyAddress[2]; + +/** Offset 0x1120 - Touch Host Controller Hid Over Spi Output Report Address + Hid Over Spi Output Report Address +**/ + UINT32 ThcHidSpiOutputReportAddress[2]; + +/** Offset 0x1128 - Touch Host Controller Hid Over Spi Read Opcode + Hid Over Spi Read Opcode +**/ + UINT32 ThcHidSpiReadOpcode[2]; + +/** Offset 0x1130 - Touch Host Controller Hid Over Spi Write Opcode + Hid Over Spi Write Opcode +**/ + UINT32 ThcHidSpiWriteOpcode[2]; + +/** Offset 0x1138 - Touch Host Controller Hid Over Spi Flags + Hid Over Spi Flags 0x0:Single SPI Mode, 0x4000:Dual SPI Mode, 0x8000:Quad SPI Mode +**/ + UINT32 ThcHidSpiFlags[2]; + +/** Offset 0x1140 - Touch Host Controller Reset Sequencing Delay [ms] + Policy control for reset sequencing delay (ACPI _INI, _RST) default 300ms +**/ + UINT16 ThcResetSequencingDelay[2]; + +/** Offset 0x1144 - Touch Host Controller Hid Over I2c Device Address + Hid Over I2c Device Address +**/ + UINT32 ThcHidI2cDeviceAddress[2]; + +/** Offset 0x114C - Touch Host Controller Hid Over I2c Connection Speed + Hid Over I2c Connection Speed [Hz] +**/ + UINT32 ThcHidI2cConnectionSpeed[2]; + +/** Offset 0x1154 - Touch Host Controller Hid Over I2c Addressing Mode + Hid Over I2c Addressing Mode - 0x1: The connection uses 10-bit addressing. 0x0: + The connection uses 7-bit addressing. +**/ + UINT8 ThcHidI2cAddressingMode[2]; + +/** Offset 0x1156 - Reserved +**/ + UINT8 Reserved19[2]; + +/** Offset 0x1158 - Touch Host Controller Hid Over I2c Device Descriptor Address + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cDeviceDescriptorAddress[2]; + +/** Offset 0x1160 - Touch Host Controller Hid Over I2c Serial Clock Line High Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialClockLineHighPeriod[2]; + +/** Offset 0x1168 - Touch Host Controller Hid Over I2c Standard Mode Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialClockLineLowPeriod[2]; + +/** Offset 0x1170 - Touch Host Controller Hid Over I2c Standard Mode Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x1178 - Touch Host Controller Hid Over I2c Standard Mode Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x1180 - Touch Host Controller Hid Over I2c Fast Mode Serial Clock Line High Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialClockLineHighPeriod[2]; + +/** Offset 0x1188 - Touch Host Controller Hid Over I2c Fast Mode Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialClockLineLowPeriod[2]; + +/** Offset 0x1190 - Touch Host Controller Hid Over I2c Fast Mode Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x1198 - Touch Host Controller Hid Over I2c Fast Mode Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x11A0 - Touch Host Controller Hid Over I2c Maximum Length Of Suppressed Spikes In Std Mode Fast Mode And Fast Mode Plus + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cMaxSuppressedSpikesSMFMFMP[2]; + +/** Offset 0x11A8 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Clock Line High Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialClockLineHighPeriod[2]; + +/** Offset 0x11B0 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialClockLineLowPeriod[2]; + +/** Offset 0x11B8 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x11C0 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x11C8 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Clock Line High Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cHighSpeedModePlusSerialClockLineHighPeriod[2]; + +/** Offset 0x11D0 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address **/ - UINT8 Reserved38[337]; + UINT32 ThcHidI2cHighSpeedModePlusSerialClockLineLowPeriod[2]; + +/** Offset 0x11D8 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cHighSpeedModePlusSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x11E0 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cHighSpeedModePlusSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x11E8 - Touch Host Controller Hid Over I2c Maximum Length Of Suppressed Spikes In High Speed Mode + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cMaximumLengthOfSuppressedSpikesInHighSpeedMode[2]; + +/** Offset 0x11F0 - THC Wake On Touch GPIO resource Edge or Level + Definition of GPIO resource configuration of Edge or Level +**/ + UINT8 ThcWotEdgeLevel[2]; + +/** Offset 0x11F2 - THC Wake On Touch GPIO resource of Active Level + Definition of GPIO resource configuration of Active Level +**/ + UINT8 ThcWotActiveLevel[2]; + +/** Offset 0x11F4 - THC Wake On Touch GPIO resource of pin configuration + Definition of GPIO resource configuration of pin configuration +**/ + UINT8 ThcWotPinConfig[2]; + +/** Offset 0x11F6 - THC customized SubSytem ID for Port + Definition of GPIO resource configuration of pin configuration +**/ + UINT16 ThcCustomizedSsid[2]; + +/** Offset 0x11FA - THC Sets Customized SubSytem Vendor ID for Port + Definition of GPIO resource configuration of pin configuration +**/ + UINT16 ThcCustomizedSvid[2]; + +/** Offset 0x11FE - Reserved +**/ + UINT8 Reserved20[2]; + +/** Offset 0x1200 - USB 3.1 Speed Selection + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT32 Usb31PortSpeed; + +/** Offset 0x1204 - Touch Host Controller Hid Over I2c Maximum Frame Size Enable + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT8 ThcHidI2cMaxFrameSize[2]; + +/** Offset 0x1206 - Touch Host Controller Hid Over I2c Maximum Frame Size Value + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT16 ThcHidI2cMaxFrameSizeValue[2]; + +/** Offset 0x120A - Touch Host Controller Hid Over I2c Interrupt Delay Enable + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT8 ThcHidI2cIntDelay[2]; + +/** Offset 0x120C - Touch Host Controller Hid Over I2c Interrupt Delay Value + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT16 ThcHidI2cIntDelayValue[2]; + +/** Offset 0x1210 - Reserved +**/ + UINT8 Reserved21[9]; /** Offset 0x1219 - PCHHOT# pin Enable PCHHOT# pin assertion when temperature is higher than PchHotLevel. 0: disable, 1: enable @@ -1675,7 +2951,47 @@ typedef struct { /** Offset 0x122A - Reserved **/ - UINT8 Reserved39[34]; + UINT8 Reserved22[2]; + +/** Offset 0x122C - PCH TSN MAC Address High Bits + Set TSN MAC Address High. +**/ + UINT32 PchTsn1MacAddressHigh; + +/** Offset 0x1230 - PCH TSN MAC Address Low Bits + Set TSN MAC Address Low. +**/ + UINT32 PchTsn1MacAddressLow; + +/** Offset 0x1234 - PCH TSN2 MAC Address High Bits + Set TSN2 MAC Address High. +**/ + UINT32 PchTsn2MacAddressHigh; + +/** Offset 0x1238 - PCH TSN2 MAC Address Low Bits + Set TSN2 MAC Address Low. +**/ + UINT32 PchTsn2MacAddressLow; + +/** Offset 0x123C - PCH TSN3 MAC Address High Bits + Set TSN3 MAC Address High. +**/ + UINT32 PchTsn3MacAddressHigh; + +/** Offset 0x1240 - PCH TSN3 MAC Address Low Bits + Set TSN3 MAC Address Low. +**/ + UINT32 PchTsn3MacAddressLow; + +/** Offset 0x1244 - PCH TSN4 MAC Address High Bits + Set TSN4 MAC Address High. +**/ + UINT32 PchTsn4MacAddressHigh; + +/** Offset 0x1248 - PCH TSN MAC4 Address Low Bits + Set TSN MAC4 Address Low. +**/ + UINT32 PchTsn4MacAddressLow; /** Offset 0x124C - Enable USB2 ports Enable/disable per USB2 ports. One byte for each port, byte0 for port0, byte1 for @@ -1702,9 +3018,11 @@ typedef struct { **/ UINT8 UsbPdoProgramming; -/** Offset 0x1268 - Reserved +/** Offset 0x1268 - USB Audio Offload enable + Enable/Disable USB Audio Offload capabilites. 0: disabled, 1: enabled (default) + $EN_DIS **/ - UINT8 Reserved40; + UINT8 PchXhciUaolEnable; /** Offset 0x1269 - PCH USB OverCurrent mapping enable 1: Will program USB OC pin mapping in xHCI controller memory, 0: Will clear OC pin @@ -1729,9 +3047,15 @@ typedef struct { **/ UINT8 PchUsbLtrOverrideEnable; -/** Offset 0x1285 - Reserved +/** Offset 0x1285 - USB DWB enable + Enable/Disable USB DWB. 0: disabled, 1: enabled (default) + $EN_DIS +**/ + UINT8 PchXhciDwbEnable; + +/** Offset 0x1286 - Reserved **/ - UINT8 Reserved41[3]; + UINT8 Reserved23[2]; /** Offset 0x1288 - xHCI High Idle Time LTR override Value used for overriding LTR recommendation for xHCI High Idle Time LTR setting @@ -1889,9 +3213,21 @@ typedef struct { **/ UINT8 Usb3HsioTxRate0UniqTran[10]; -/** Offset 0x13AD - Reserved +/** Offset 0x13AD - PCIe Fia Programming + Load Fia configuration if enable. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieFiaProgramming; + +/** Offset 0x13AE - Enable SSE Device + Test, 0: POR, 1: enable, 2: disable, Enable/Disable SSE/SSE++ Devices from PCI config space + $EN_DIS +**/ + UINT8 SseCommunication; + +/** Offset 0x13AF - Reserved **/ - UINT8 Reserved42[4]; + UINT8 Reserved24[2]; /** Offset 0x13B1 - Enable/Disable NPU Device Enable(Default): Enable NPU Device, Disable: Disable NPU Device @@ -1911,9 +3247,11 @@ typedef struct { **/ UINT8 PchLanLtrEnable; -/** Offset 0x13B4 - Reserved +/** Offset 0x13B4 - PCH Lan WOL Fast Support + Enables bit B_PCH_ACPI_GPE0_EN_127_96_PME_B0 during PchLanSxCallback in PchLanSxSmm. + $EN_DIS **/ - UINT8 Reserved43; + UINT8 PchLanWOLFastSupport; /** Offset 0x13B5 - Skip Ssid Programming. When set to TRUE, silicon code will not do any SSID programming and platform code @@ -1934,9 +3272,15 @@ typedef struct { **/ UINT16 SiCustomizedSsid; -/** Offset 0x13BA - Reserved +/** Offset 0x13BA - CAN Configurations + Enable/Disable CAN Controllers.0: Disable, 1: Enable + $EN_DIS +**/ + UINT8 PchCanEnable[2]; + +/** Offset 0x13BC - Reserved **/ - UINT8 Reserved44[6]; + UINT8 Reserved25[4]; /** Offset 0x13C0 - SVID SDID table Poniter. The address of the table of SVID SDID to customize each SVID SDID entry. This is @@ -1950,9 +3294,15 @@ typedef struct { **/ UINT16 SiNumberOfSsidTableEntry; -/** Offset 0x13CA - Reserved +/** Offset 0x13CA - Skip DFX. + Skip DFX. + $EN_DIS +**/ + UINT8 DfxSkipBiosDone; + +/** Offset 0x13CB - Reserved **/ - UINT8 Reserved45[10]; + UINT8 Reserved26[9]; /** Offset 0x13D4 - LogoPixelHeight Address Address of LogoPixelHeight @@ -1966,7 +3316,7 @@ typedef struct { /** Offset 0x13DC - Reserved **/ - UINT8 Reserved46[4]; + UINT8 Reserved27[4]; /** Offset 0x13E0 - Blt Buffer Address Address of Blt buffer @@ -1984,9 +3334,11 @@ typedef struct { **/ UINT8 SkipFspGop; -/** Offset 0x13F1 - Reserved +/** Offset 0x13F1 - Enable/Disable Media Configuration + Enable(Default): Configure Media for use, Disable: Skip Media Configuration + $EN_DIS **/ - UINT8 Reserved47; + UINT8 ConfigureMedia; /** Offset 0x13F2 - Enable/Disable IGFX RenderStandby Enable(Default): Enable IGFX RenderStandby, Disable: Disable IGFX RenderStandby @@ -1994,9 +3346,23 @@ typedef struct { **/ UINT8 RenderStandby; -/** Offset 0x13F3 - Reserved +/** Offset 0x13F3 - Enable/Disable GT Configuration + Enable(Default): Configure GT for use, Disable: Skip GT Configuration + $EN_DIS +**/ + UINT8 ConfigureGT; + +/** Offset 0x13F4 - Enable RC1p GT frequency request to PMA (provided all other conditions are met) + 0(Default)=Disable, 1=Enable + $EN_DIS **/ - UINT8 Reserved48[3]; + UINT8 RC1pGtFreqEnable; + +/** Offset 0x13F5 - Enable RC1p Media frequency request to PMA (provided all other conditions are met) + 0(Default)=Disable, 1=Enable + $EN_DIS +**/ + UINT8 RC1pMediaFreqEnable; /** Offset 0x13F6 - Enable/Disable PavpEnable Enable(Default): Enable PavpEnable, Disable: Disable PavpEnable @@ -2011,9 +3377,21 @@ typedef struct { **/ UINT8 PeiGraphicsPeimInit; -/** Offset 0x13F8 - Reserved +/** Offset 0x13F8 - Enable/Disable IGFX Media Standby + Enable(Default): Enable IGFX Media Standby, Disable: Disable IGFX MediaStandby + $EN_DIS +**/ + UINT8 MediaStandby; + +/** Offset 0x13F9 - Enable/Disable Gfx Workstation + Enable(Default): Is a workstation, Disable: Is not a workstation + $EN_DIS +**/ + UINT8 Dev2IsGfxWorkstation; + +/** Offset 0x13FA - Reserved **/ - UINT8 Reserved49[4]; + UINT8 Reserved28[2]; /** Offset 0x13FC - Intel Graphics VBT (Video BIOS Table) Size Size of Internal Graphics VBT Image @@ -2026,9 +3404,29 @@ typedef struct { **/ UINT8 LidStatus; -/** Offset 0x1401 - Reserved +/** Offset 0x1401 - Select MaxActiveDisplays + Max Active Display : 0 - Default VBT, 1 - 1 display, 2 - 2 displays, Maximum supported + is 2 displays only +**/ + UINT8 MaxActiveDisplays; + +/** Offset 0x1402 - Reserved +**/ + UINT8 Reserved29[2]; + +/** Offset 0x1404 - HorizontalResolution for PEI Logo + HorizontalResolution from PEIm Gfx for PEI Logo +**/ + UINT32 HorizontalResolution; + +/** Offset 0x1408 - VerticalResolution for PEI Logo + VerticalResolution from PEIm Gfx for PEI Logo **/ - UINT8 Reserved50[67]; + UINT32 VerticalResolution; + +/** Offset 0x140C - Reserved +**/ + UINT8 Reserved30[56]; /** Offset 0x1444 - Address of PCH_DEVICE_INTERRUPT_CONFIG table. The address of the table of PCH_DEVICE_INTERRUPT_CONFIG. @@ -2062,9 +3460,33 @@ typedef struct { **/ UINT8 TcoIrqEnable; -/** Offset 0x144D - Reserved +/** Offset 0x144D - PMC ADR enable + Enable/disable asynchronous DRAM refresh + $EN_DIS +**/ + UINT8 PmcAdrEn; + +/** Offset 0x144E - PMC ADR timer configuration enable + Enable/disable ADR timer configuration + $EN_DIS +**/ + UINT8 PmcAdrTimerEn; + +/** Offset 0x144F - PMC ADR phase 1 timer value + Enable/disable ADR timer configuration +**/ + UINT8 PmcAdrTimer1Val; + +/** Offset 0x1450 - PMC ADR phase 1 timer multiplier value + Specify the multiplier value for phase 1 ADR timer +**/ + UINT8 PmcAdrMultiplier1Val; + +/** Offset 0x1451 - PMC ADR host reset partition enable + Specify whether PMC should set ADR_RST_STS bit after receiving Reset_Warn_Ack DMI message + $EN_DIS **/ - UINT8 Reserved51[5]; + UINT8 PmcAdrHostPartitionReset; /** Offset 0x1452 - Mask to enable the usage of external V1p05 VR rail in specific S0ix or Sx states Enable External V1P05 Rail in: BIT0:S0i1/S0i2, BIT1:S0i3, BIT2:S3, BIT3:S4, BIT5:S5 @@ -2098,7 +3520,7 @@ typedef struct { /** Offset 0x1459 - Reserved **/ - UINT8 Reserved52; + UINT8 Reserved31; /** Offset 0x145A - External Vnn Voltage Value that will be used in S0ix/Sx states Value is given in 2.5mV increments (0=0mV, 1=2.5mV, 2=5mV...), Default is set to 420 @@ -2159,7 +3581,7 @@ typedef struct { /** Offset 0x1467 - Reserved **/ - UINT8 Reserved53; + UINT8 Reserved32; /** Offset 0x1468 - External V1P05 Icc Max Value Granularity of this setting is 1mA and maximal possible value is 500mA @@ -2199,9 +3621,11 @@ typedef struct { **/ UINT8 PchLegacyIoLowLatency; -/** Offset 0x1472 - Reserved +/** Offset 0x1472 - PCH P2SB + PCH P2SB + $EN_DIS **/ - UINT8 Reserved54; + UINT8 SvTestUnhideP2sb; /** Offset 0x1473 - PCH Unlock SideBand access The SideBand PortID mask for certain end point (e.g. PSFx) will be locked before @@ -2268,9 +3692,19 @@ typedef struct { **/ UINT8 CnviBtAudioOffload; -/** Offset 0x147D - Reserved +/** Offset 0x147D - WWAN Coex + WWAN Coex is getting updated from UEFI variable +**/ + UINT8 CnviWwanCoex; + +/** Offset 0x147E - Skip BtPreInit + BtPreInit can be skipped if SkipBtPreInit is enabled **/ - UINT8 Reserved55[3]; + UINT8 SkipBtPreInit; + +/** Offset 0x147F - Reserved +**/ + UINT8 Reserved33; /** Offset 0x1480 - CNVi RF_RESET pin muxing Select CNVi RF_RESET# pin depending on board routing. LP/P/M: GPP_A8 = 0x2942E408(default) @@ -2285,9 +3719,11 @@ typedef struct { **/ UINT32 CnviClkreqPinMux; -/** Offset 0x1488 - Reserved +/** Offset 0x1488 - CNVi BT Audio OffOffloadInterfaceload + Enable/Disable BT Audio OffloadInterface, Default is ENABLE. 0: DISABLE, 1: ENABLE + $EN_DIS **/ - UINT8 Reserved56; + UINT8 CnviBtAudioOffloadInterface; /** Offset 0x1489 - Enable Device 4 Enable/disable Device 4 @@ -2302,9 +3738,10 @@ typedef struct { **/ UINT8 SkipPamLock; -/** Offset 0x148B - Reserved +/** Offset 0x148B - TCSS LSx OE Enable + Bits 0, 1, ... max Type C Rettimerless port LSx OE enables **/ - UINT8 Reserved57; + UINT8 TcssLsxOe; /** Offset 0x148C - PCH HDA Verb Table Entry Number Number of Entries in Verb Table. @@ -2313,7 +3750,7 @@ typedef struct { /** Offset 0x148D - Reserved **/ - UINT8 Reserved58[3]; + UINT8 Reserved34[3]; /** Offset 0x1490 - PCH HDA Verb Table Pointer Pointer to Array of pointers to Verb Table. @@ -2345,9 +3782,11 @@ typedef struct { **/ UINT8 PchHdaMicPrivacyMode; -/** Offset 0x149C - Reserved +/** Offset 0x149C - HD Audio Microphone Privacy Deglitch + HD Audio Microphone Privacy Deglitch: 0: Disable, 1: Enable + $EN_DIS **/ - UINT8 Reserved59; + UINT8 PchHdaMicPrivacyDeglitch; /** Offset 0x149D - HD Audio Microphone Privacy applied for SoundWire Link number 0 in HW Mode HD Audio Microphone Privacy applied for SoundWire Link number 0 in HW Mode: 0: Disable, 1: Enable @@ -2387,7 +3826,17 @@ typedef struct { /** Offset 0x14A3 - Reserved **/ - UINT8 Reserved60[13]; + UINT8 Reserved35; + +/** Offset 0x14A4 - HD Audio Microphone Privacy Timeout. Indicates the time-out duration to wait before forcing the actual microphone privacy DMA data zeroing. + HD Audio Microphone Privacy Timeout. Indicates the time-out duration to wait before + forcing the actual microphone privacy DMA data zeroing. +**/ + UINT32 PchHdaMicPrivacyTimeout; + +/** Offset 0x14A8 - Reserved +**/ + UINT8 Reserved36[8]; /** Offset 0x14B0 - Pointer to ChipsetInit Binary ChipsetInit Binary Pointer. @@ -2401,7 +3850,49 @@ typedef struct { /** Offset 0x14BC - Reserved **/ - UINT8 Reserved61[36]; + UINT8 Reserved37[4]; + +/** Offset 0x14C0 - Pointer to NPHY Binary + Nphy Binary Pointer. +**/ + UINT64 NphyBinPtr; + +/** Offset 0x14C8 - Length of NPHY Binary + Nphy Binary Length. +**/ + UINT32 NphyBinLen; + +/** Offset 0x14CC - Reserved +**/ + UINT8 Reserved38[4]; + +/** Offset 0x14D0 - Pointer to SYNPS PHY Binary + Synps Binary Pointer. +**/ + UINT64 SynpsPhyBinPtr; + +/** Offset 0x14D8 - Length of SYNPS PHY Binary + Synps Binary Length. +**/ + UINT32 SynpsPhyBinLen; + +/** Offset 0x14DC - Skip setting BIOS_DONE When Fw Update. + When set to TRUE and boot mode is BOOT_ON_FLASH_UPDATE,skip setting BIOS_DONE MSR + at EndofPei. Note: BIOS_DONE MSR should be set in later phase before executing + 3rd party code if SiSkipBiosDoneWhenFwUpdate set to TRUE. + $EN_DIS +**/ + UINT8 SiSkipBiosDoneWhenFwUpdate; + +/** Offset 0x14DD - PMC WDT enable + Enable/disable PMC WDT configuration + $EN_DIS +**/ + UINT8 PmcWdtTimerEn; + +/** Offset 0x14DE - Reserved +**/ + UINT8 Reserved39[2]; } FSP_S_CONFIG; /** Fsp S UPD Configuration diff --git a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/MemInfoHob.h b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/MemInfoHob.h index c89cf2cab1e..e50c114e416 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/pantherlake/MemInfoHob.h +++ b/src/vendorcode/intel/fsp/fsp2_0/pantherlake/MemInfoHob.h @@ -312,7 +312,8 @@ typedef struct _PPR_RESULT_COLUMNS_HOB { - DIMM_INFO: Added SerialNumber, TotalWidth and DataWidth - DIMM_INFO: Removed SpdModuleMemoryBusWidth - MFG ID fields: use HOB_MANUFACTURER_ID_CODE instead of UINT16 for easier parsing - + Revision 4: + - Added FailingChannelMask **/ typedef struct { UINT8 Revision; @@ -363,6 +364,7 @@ typedef struct { UINT8 MaxRankCapacity; ///< Maximum possible rank capacity in [GB] UINT16 PprFailingChannelBitMask; ///< PPR failing channel mask BOOLEAN PprTargetedStatus[PPR_REQUEST_MAX]; ///< PPR status of each Targeted PPR request (0 = Targeted PPR was successful, 1 = PPR failed) + UINT8 FailingChannelMask; ///< Limp Home mode failing channel bitmask } MEMORY_INFO_DATA_HOB; /** diff --git a/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspUpd.h b/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspUpd.h index 9661285ef31..33ae66b1e5c 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspUpd.h +++ b/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspUpd.h @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2024, Intel Corporation. All rights reserved.
+Copyright (c) 2026, Intel Corporation. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspmUpd.h b/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspmUpd.h index 661948e3259..50e13411f6b 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspmUpd.h +++ b/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspmUpd.h @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2025, Intel Corporation. All rights reserved.
+Copyright (c) 2026, Intel Corporation. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -93,9 +93,11 @@ typedef struct { **/ UINT32 SerialIoUartDebugCtsPinMux; -/** Offset 0x0074 - Reserved +/** Offset 0x0074 - SerialIo Uart PowerGating + Select SerialIo Uart Powergating mode + 0:Disabled, 1:Enabled, 2:Auto **/ - UINT8 Reserved1; + UINT8 SerialIoUartPowerGating; /** Offset 0x0075 - DCI Enable Determine if to enable DCI debug from host @@ -110,9 +112,28 @@ typedef struct { **/ UINT8 DciDbcMode; -/** Offset 0x0077 - Reserved +/** Offset 0x0077 - DCI Clock Enable + Enable/Disable DCI clock in lowest power state + $EN_DIS +**/ + UINT8 DciClkEnable; + +/** Offset 0x0078 - Keep Early Trace + Trace is activated by default. When enable, keep early trace data and keep tracing, + may block s0ix.\n + When disabled will abandon trace data and stop tracing which allows enter s0ix\n + \n + noted:enable this option will not enable TraceHub; When probe is connected, keep + early trace will then be configured by tool, this option will not take effect. + $EN_DIS +**/ + UINT8 KeepEarlyTrace; + +/** Offset 0x0079 - Enable/Disable MemoryOverlap check + Enable(Default): Enable MemoryOverlap check, Disable: Disable MemoryOverlap check + $EN_DIS **/ - UINT8 Reserved2[3]; + UINT8 MemMapOverlapCheckSupport; /** Offset 0x007A - Memory Test on Warm Boot Run Base Memory Test on Warm Boot @@ -122,7 +143,7 @@ typedef struct { /** Offset 0x007B - Reserved **/ - UINT8 Reserved3[5]; + UINT8 Reserved1[5]; /** Offset 0x0080 - Platform Reserved Memory Size The minimum platform memory size required to pass control into DXE @@ -137,7 +158,7 @@ typedef struct { /** Offset 0x008A - Reserved **/ - UINT8 Reserved4[6]; + UINT8 Reserved2[6]; /** Offset 0x0090 - Memory SPD Pointer Controller 0 Channel 0 Dimm 0 Pointer to SPD data, will be used only when SpdAddressTable SPD Address are marked as 00 @@ -316,9 +337,19 @@ typedef struct { **/ UINT8 LowerBasicMemTestSize; -/** Offset 0x01AD - Reserved +/** Offset 0x01AD - EccGranularity32BEn + Reduce BasicMemTest size. 0: Disabled (default), regular BasicMemTest. 1: Enabled, + shorter BasicMemTest (faster boot) + $EN_DIS +**/ + UINT8 EccGranularity32BEn; + +/** Offset 0x01AE - EccCorrectionMode + Reduce BasicMemTest size. 0: Disabled (default), regular BasicMemTest. 1: Enabled, + shorter BasicMemTest (faster boot) + $EN_DIS **/ - UINT8 Reserved5[2]; + UINT8 EccCorrectionMode; /** Offset 0x01AF - CaVrefHigh DDR5 CA Sweep High Vref Value for DDR5 OC @@ -350,9 +381,13 @@ typedef struct { **/ UINT8 DFETap2StepSize; -/** Offset 0x01B5 - Reserved +/** Offset 0x01B5 - IbeccEccInjControl + IBECC Error Injection Control + 0: No Error Injection, 1:Inject Correctable Error Address match, 3:Inject Correctable + Error on insertion counter, 5: Inject Uncorrectable Error Address match, 7:Inject + Uncorrectable Error on insertion counter **/ - UINT8 Reserved6; + UINT8 IbeccEccInjControl; /** Offset 0x01B6 - VDD2 override VDD2 override for DDR5 OC; 0 - Auto @@ -473,9 +508,17 @@ typedef struct { **/ UINT16 tCCD_L_WR; -/** Offset 0x01E2 - Reserved +/** Offset 0x01E2 - Periodic COMP + Enable/disable Periodic Compensation + $EN_DIS **/ - UINT8 Reserved7[2]; + UINT8 EnPeriodicComp; + +/** Offset 0x01E3 - LPMode4 Support + LPMode4 Options + 0: Disable, 1:Enable, 2:Dynamic Threshold 2, 3:Dynamic Threshold 3 +**/ + UINT8 LpMode4; /** Offset 0x01E4 - LPMode Support Bit[0]: Enable Lpmode0p5 (Idle_enable), Bit[1]: Enable Lpmode2 (Powerdown_enable), @@ -483,9 +526,17 @@ typedef struct { **/ UINT8 LpMode; -/** Offset 0x01E5 - Reserved +/** Offset 0x01E5 - Opportunistic Read + Enables/Disable Opportunistic Read (Def= Enable) + $EN_DIS +**/ + UINT8 OpportunisticRead; + +/** Offset 0x01E6 - Cycle Bypass Support + Enables/Disable Cycle Bypass Support(Def=Disable) + $EN_DIS **/ - UINT8 Reserved8[2]; + UINT8 Disable2CycleBypass; /** Offset 0x01E7 - MRC OCSafeMode OverClocking Safe Mode for tCL @@ -493,9 +544,13 @@ typedef struct { **/ UINT8 OCSafeMode; -/** Offset 0x01E8 - Reserved +/** Offset 0x01E8 - DQ Vref Ctrl Offset + Offset to be applied to DDRDATA7CH1_CR_DDRCRVREFADJUST1.Ch0VrefCtl + 0xF4:-12,0xF5:-11, 0xF6:-10, 0xF7:-9, 0xF8:-8, 0xF9:-7, 0xFA:-6, 0xFB:-5, 0xFC:-4, + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3, 4:+4, 5:+5, 6:+6, 7:+7, 8:+8, + 9:+9, 10:+10, 11:+11, 12:+12 **/ - UINT8 Reserved9; + UINT8 VrefCtlOffset; /** Offset 0x01E9 - Dqs Pins Interleaved Setting Indicates DqPinsInterleaved setting: board-dependent @@ -536,9 +591,10 @@ typedef struct { **/ UINT8 ProbelessTrace; -/** Offset 0x01EF - Reserved +/** Offset 0x01EF - IbeccEccInjCount + Number of memory transactions between ECC error injection **/ - UINT8 Reserved10; + UINT8 IbeccEccInjCount; /** Offset 0x01F0 - DDR Frequency Limit Maximum Memory Frequency Selections in Mhz. Options are 1067, 1333, 1600, 1867, @@ -676,9 +732,11 @@ typedef struct { **/ UINT8 TXDQSDCC; -/** Offset 0x0213 - Reserved +/** Offset 0x0213 - Rx DQS Duty Cycle Correction + Enables/Disable Rx DQS Duty Cycle Correction + $EN_DIS **/ - UINT8 Reserved11; + UINT8 RXDQSDCC; /** Offset 0x0214 - Ch Hash Override Select if Channel Hash setting values will be taken from input parameters or automatically @@ -687,9 +745,17 @@ typedef struct { **/ UINT8 ChHashOverride; -/** Offset 0x0215 - Reserved +/** Offset 0x0215 - Voltage Readout + Enables/Disable Voltage Readout for VCCClk and PBias + $EN_DIS +**/ + UINT8 VoltageReadout; + +/** Offset 0x0216 - DQS Rise/Fall + Enables/Disable DQS Rise/Fall + $EN_DIS **/ - UINT8 Reserved12[2]; + UINT8 DQSRF; /** Offset 0x0217 - DQS Rise/Fall Enables/Disable DQS Rise/Fall @@ -697,9 +763,17 @@ typedef struct { **/ UINT8 RDDQSODTT; -/** Offset 0x0218 - Reserved +/** Offset 0x0218 - PreTraining + Enables/Disable PreTraining + $EN_DIS +**/ + UINT8 PRETRAIN; + +/** Offset 0x0219 - DUNIT Configuration + Enables/Disable Dunit Configuration + $EN_DIS **/ - UINT8 Reserved13[2]; + UINT8 DUNITC; /** Offset 0x021A - Functional Duty Cycle Correction for DDR5 CLK Enable/Disable Functional Duty Cycle Correction for DDR5 CLK @@ -729,9 +803,11 @@ typedef struct { **/ UINT8 DQDQSSWZ; -/** Offset 0x021F - Reserved +/** Offset 0x021F - LP5 Dca Training + Enable/Disable LP5 Dca Training + $EN_DIS **/ - UINT8 Reserved14; + UINT8 DCCLP5READDCA; /** Offset 0x0220 - Functional Duty Cycle Correction for Data DQ Enable/Disable Functional Duty Cycle Correction for Data DQ @@ -739,9 +815,39 @@ typedef struct { **/ UINT8 FUNCDCCDQ; -/** Offset 0x0221 - Reserved +/** Offset 0x0221 - SubCh Hash Override + Select if SubChannel Hash setting values will be taken from input parameters or + automatically taken from POR values depending on DRAM type detected. NOTE: ONLY + if Memory interleaved Mode + $EN_DIS +**/ + UINT8 SubChHashOverride; + +/** Offset 0x0222 - DDR5 Auto Precharge Enable + Auto Precharge Enable for DDR5: O=Auto, 1=Disable, 2=Enable + $EN_DIS +**/ + UINT8 Ddr5AutoPrechargeEnable; + +/** Offset 0x0223 - Lp5 SplitACT Enable + SplitACT enable for LP5 + 0:Auto, 1:Disable, 2:Enable +**/ + UINT8 Lp5SplitACTEnable; + +/** Offset 0x0224 - CCC Half Frequency + CCC Half Frequency (CccGear4) Mode: 0 = Auto (Default), 1 = Disable, 2 = GroupGv0 + (SaGv0 only), 3 = GroupGv1 (Up to SaGv1), 4 = GroupGv2 (Up to SaGv2), 5 = GroupGv3 + (Up to SaGv3) + 0: Auto, 1: Disable, 2: GroupGv0, 3: GroupGv1, 4: GroupGv2, 5: GroupGv3 **/ - UINT8 Reserved15[5]; + UINT8 CccHalfFrequency; + +/** Offset 0x0225 - DIMM Non-Target ODT Training + Enables/Disable DIMM Non-Target ODT Training + $EN_DIS +**/ + UINT8 DIMMNTODT; /** Offset 0x0226 - Unmatched Rx Calibration Enable/Disable Rx Unmatched Calibration @@ -749,9 +855,60 @@ typedef struct { **/ UINT8 RXUNMATCHEDCAL; -/** Offset 0x0227 - Reserved +/** Offset 0x0227 - Hard Post Package Repair + Deprecated + $EN_DIS +**/ + UINT8 PPR; + +/** Offset 0x0228 - PPR Test Type + Deprecated +**/ + UINT8 PprTestType; + +/** Offset 0x0229 - PPR Run Once + When Eanble, PPR will run only once and then is disabled at next training cycle + $EN_DIS +**/ + UINT8 PprRunOnce; + +/** Offset 0x022A - PPR Run During Fastboot + Deprecated + $EN_DIS +**/ + UINT8 PprRunAtFastboot; + +/** Offset 0x022B - PPR Repair Type + PPR Repair Type: 0:Do not Repair (Default), 1:Soft Repair, 2:Hard Repair + 0:Do not Repair (Default), 1:Soft Repair, 2:Hard Repair +**/ + UINT8 PprRepairType; + +/** Offset 0x022C - PPR Error Injection + When Eanble, PPR will inject bad rows during testing + $EN_DIS +**/ + UINT8 PprErrorInjection; + +/** Offset 0x022D - PPR Repair Controller + Deprecated +**/ + UINT8 PprRepairController; + +/** Offset 0x022E - PPR Repair Channel + Deprecated +**/ + UINT8 PprRepairChannel; + +/** Offset 0x022F - PPR Repair Dimm + Deprecated +**/ + UINT8 PprRepairDimm; + +/** Offset 0x0230 - PPR Repair Rank + Deprecated **/ - UINT8 Reserved16[10]; + UINT8 PprRepairRank; /** Offset 0x0231 - Memory Slice Hash LSB Bit Memory Slice (Controller) Hash LSB bit. Valid values are 0..7 for BITS 6..13; used @@ -766,9 +923,25 @@ typedef struct { **/ UINT16 MsHashMask; -/** Offset 0x0234 - Reserved +/** Offset 0x0234 - PPR Repair Row + Deprecated +**/ + UINT32 PprRepairRow; + +/** Offset 0x0238 - PPR Repair Physical Address Low + Deprecated +**/ + UINT32 PprRepairPhysicalAddrLow; + +/** Offset 0x023C - PPR Repair Physical Address High + Deprecated +**/ + UINT32 PprRepairPhysicalAddrHigh; + +/** Offset 0x0240 - PPR Repair BankGroup + Deprecated **/ - UINT8 Reserved17[13]; + UINT8 PprRepairBankGroup; /** Offset 0x0241 - LVR Auto Trim Enable/disable LVR Auto Trim @@ -788,9 +961,23 @@ typedef struct { **/ UINT8 WRTRETRAIN; -/** Offset 0x0244 - Reserved +/** Offset 0x0244 - DCC Phase Clk Calibration + Enable/disable DCC Phase Clk Calibration + $EN_DIS +**/ + UINT8 PHASECLKCAL; + +/** Offset 0x0245 - DCC Tline Clk Calibration + Enable/disable DCC Tline Clk Calibration + $EN_DIS +**/ + UINT8 TLINECLKCAL; + +/** Offset 0x0246 - DCC Tline Serializer Calibration + Enable/disable DCC PI Serializer Calibratio + $EN_DIS **/ - UINT8 Reserved18[3]; + UINT8 DCCPISERIALCAL; /** Offset 0x0247 - RDDQODTT Enable/disable Read DQ ODT Training @@ -1000,9 +1187,11 @@ typedef struct { **/ UINT8 TAT; -/** Offset 0x026A - Reserved +/** Offset 0x026A - Rmt Even Odd + Enables/Disable Rmt Even Odd + $EN_DIS **/ - UINT8 Reserved19; + UINT8 RMTEVENODD; /** Offset 0x026B - DIMM SPD Alias Test Enables/Disable DIMM SPD Alias Test @@ -1028,9 +1217,17 @@ typedef struct { **/ UINT8 EccSupport; -/** Offset 0x026F - Reserved +/** Offset 0x026F - DLL DCC Calibration + Enables/Disable DLL DCC Calibration + $EN_DIS +**/ + UINT8 DLLDCC; + +/** Offset 0x0270 - DLL BW Select Calibration + Enables/Disable DLL BW Select Calibration + $EN_DIS **/ - UINT8 Reserved20[2]; + UINT8 DLLBWSEL; /** Offset 0x0271 - Ibecc In-Band ECC Support @@ -1044,9 +1241,11 @@ typedef struct { **/ UINT8 IbeccParity; -/** Offset 0x0273 - Reserved +/** Offset 0x0273 - MsHashEnable + Controller Hash Enable: 0=Disable, 1=Enable + $EN_DIS **/ - UINT8 Reserved21; + UINT8 MsHashEnable; /** Offset 0x0274 - IbeccOperationMode In-Band ECC Operation Mode @@ -1062,7 +1261,7 @@ typedef struct { /** Offset 0x027D - Reserved **/ - UINT8 Reserved22; + UINT8 Reserved3; /** Offset 0x027E - IbeccProtectedRegionBases IBECC Protected Region Bases per IBECC instance @@ -1135,9 +1334,17 @@ typedef struct { **/ UINT8 ExitOnFailure; -/** Offset 0x02A8 - Reserved +/** Offset 0x02A8 - Wck Pad DCC Calibration + Enable/disable Wck Pad DCC Calibration + $EN_DIS +**/ + UINT8 WCKPADDCCCAL; + +/** Offset 0x02A9 - DCC PI Code LUT Calibration + Enable/Disable DCC PI Code LUT Calibration + $EN_DIS **/ - UINT8 Reserved23[2]; + UINT8 DCCPICODELUT; /** Offset 0x02AA - Read Voltage Centering 1D Enable/Disable Read Voltage Centering 1D @@ -1223,9 +1430,11 @@ typedef struct { **/ UINT8 RowPressEn; -/** Offset 0x02B8 - Reserved +/** Offset 0x02B8 - DBI feature + Enables/Disable DBI feature + $EN_DIS **/ - UINT8 Reserved24; + UINT8 DBI; /** Offset 0x02B9 - DDR5 MR7 WICA support Enable if DDR5 DRAM Device supports MR7 WICA 0.5 tCK offset alignment @@ -1252,9 +1461,10 @@ typedef struct { **/ UINT16 ChHashMask; -/** Offset 0x02BE - Reserved +/** Offset 0x02BE - CccPinsInterleaved + Interleaving mode of CCC pins which depends on board routing: 0=Disable, 1=Enable **/ - UINT8 Reserved25; + UINT8 CccPinsInterleaved; /** Offset 0x02BF - Throttler CKEMin Timer Timer value for CKEMin, range[255;0]. Req'd min of SC_ROUND_T + BYTE_LENGTH (4). @@ -1333,7 +1543,12 @@ typedef struct { /** Offset 0x02CB - Reserved **/ - UINT8 Reserved26[5]; + UINT8 Reserved4; + +/** Offset 0x02CC - IbeccEccInjAddrBase + Address to match against for ECC error injection. Example: 1 = 32MB, 2 = 64MB +**/ + UINT32 IbeccEccInjAddrBase; /** Offset 0x02D0 - DDR Phy Safe Mode Support DdrSafeMode[0]: Basic PM Features, DdrSafeMode[1]: Spine Gating, DdrSafeMode[2]: @@ -1353,9 +1568,56 @@ typedef struct { **/ UINT8 CleanMemory; -/** Offset 0x02D6 - Reserved +/** Offset 0x02D6 - Tseg Retry Count + Tseg Retry count will increase based on TSEG Region Fail count + 0: Default, 1:3 +**/ + UINT8 RetryCount; + +/** Offset 0x02D7 - Mrc Ppr Status + Get Mrc PPR Status after PPR Recovery flow will get Trigger + 0: PASS, 1: FAIL(Default) +**/ + UINT8 MrcPprStatus; + +/** Offset 0x02D8 - Tseg Memory Test Status + If enabled, PPR Recovery flow will get Trigger + 0: PASS, 1: FAIL(Default) +**/ + UINT8 TsegMemoryTestStatus; + +/** Offset 0x02D9 - Ppr Recovery Status Enable + 0: Disabled(Default), 1: Enabled. If enabled, PPR Recovery flow will get Trigger. + $EN_DIS +**/ + UINT8 PprRecoveryStatusEnable; + +/** Offset 0x02DA - Safe Loading Bios Enable State + 0: Disabled(Default), 1: Enabled. If enabled, Memory diagnostic will perform for + TSEG Region. + $EN_DIS +**/ + UINT8 SafeLoadingBiosEnableState; + +/** Offset 0x02DB - BDAT test type + When BdatEnable is set to TRUE, this option selects the type of data which will + be populated in the BIOS Data ACPI Tables: 0=RMT, 1=RMT Per Bit, 2=Margin 2D. + 0:RMT per Rank, 1:RMT per Bit, 2:Margin2D +**/ + UINT8 MrcBdatTestType; + +/** Offset 0x02DC - MrcBdatEnable + 0: Disabled(Default), 1: Enabled. This field enables the generation of the BIOS + DATA ACPI Tables: 0=FALSE, 1=TRUE. + $EN_DIS +**/ + UINT8 MrcBdatEnable; + +/** Offset 0x02DD - DisableMrcRetraining + 0: Disabled(Default), 1: Enabled. Enable/Disable DisableMrcRetraining + $EN_DIS **/ - UINT8 Reserved27[8]; + UINT8 DisableMrcRetraining; /** Offset 0x02DE - RMTLoopCount Specifies the Loop Count to be used during Rank Margin Tool Testing. 0 - AUTO @@ -1391,7 +1653,7 @@ typedef struct { /** Offset 0x02E7 - Reserved **/ - UINT8 Reserved28; + UINT8 Reserved5; /** Offset 0x02E8 - Margin limit check L2 Margin limit check L2 threshold: 100=Default @@ -1404,9 +1666,12 @@ typedef struct { **/ UINT8 ExtendedBankHashing; -/** Offset 0x02EB - Reserved +/** Offset 0x02EB - DRFM Blast Radius Configuration + Row Hammer DRFM Blast Radius Configuration determines number of victim rows around + aggressor row targeted to send the DRFM sequence to: 2=BlastRadius 2, 3=BlastRadius + 3, 4=BlastRadius 4 **/ - UINT8 Reserved29; + UINT8 DrfmBrc; /** Offset 0x02EC - LP5 Command Pins Mapping BitMask where bits [3:0] are Controller 0 Channel [3:0] and bits [7:4] are Controller @@ -1426,9 +1691,73 @@ typedef struct { **/ UINT8 MrcTimeMeasure; -/** Offset 0x02EF - Reserved +/** Offset 0x02EF - DVFSQ Enabled + Enable/Disable DVFSQ + $EN_DIS +**/ + UINT8 DvfsqEnabled; + +/** Offset 0x02F0 - E-DVFSC Enabled + Eanble/Disable DVFSC + $EN_DIS +**/ + UINT8 DvfscEnabled; + +/** Offset 0x02F1 - Ddr5 Dca Training + Enable/Disable DDR5 Dca Training + $EN_DIS +**/ + UINT8 DCCDDR5READDCA; + +/** Offset 0x02F2 - PPR Run WCHMATS8 + Run WCHMATS8 in Post Package Repair flow +**/ + UINT8 PprRunWCHMATS8; + +/** Offset 0x02F3 - PPR Run Retention + Run Data Retention in Post Package Repair flow +**/ + UINT8 PprRunRetention; + +/** Offset 0x02F4 - PPR Run XMarch + Run XMarch in Post Package Repair flow +**/ + UINT8 PprRunXMarch; + +/** Offset 0x02F5 - PPR Run XMarchG + Run XMarchG in Post Package Repair flow +**/ + UINT8 PprRunXMarchG; + +/** Offset 0x02F6 - PPR Run YMarchShort + Run YMarchShort in Post Package Repair flow +**/ + UINT8 PprRunYMarchShort; + +/** Offset 0x02F7 - PPR Run YMarchLong + Run YMarchLong in Post Package Repair flow +**/ + UINT8 PprRunYMarchLong; + +/** Offset 0x02F8 - PPR Run Mmrw + Run Mmrw in Post Package Repair flow +**/ + UINT8 PprRunMmrw; + +/** Offset 0x02F9 - PPR Test Disabled + Don't run any test in Post Package Repair flow +**/ + UINT8 PprTestDisabled; + +/** Offset 0x02FA - PPR Entry Info + PPR Repair Info +**/ + UINT8 PprEntryInfo[16]; + +/** Offset 0x030A - PPR Entry Address + PPR Repair Memory Address **/ - UINT8 Reserved30[43]; + UINT8 PprEntryAddress[16]; /** Offset 0x031A - Read Vref Decap Training* Enable/Disable Read Timing Centering Training with SR stress* @@ -1454,9 +1783,27 @@ typedef struct { **/ UINT8 IsWckIdleExitEnabled; -/** Offset 0x031E - Reserved +/** Offset 0x031E - LP5 Safe Speed + Enable / Disable LP5 Safe Speed feature + $EN_DIS +**/ + UINT8 Lp5SafeSpeed; + +/** Offset 0x031F - Force InternalClkOn + Force InternalClocksOn and TxPiOn to be set to 1 for frequencies >= 7467 + $EN_DIS +**/ + UINT8 ForceInternalClkOn; + +/** Offset 0x0320 - DIMM Rx Offset Calibration training + Enable/Disable DIMM Rx Offset Calibration training + $EN_DIS +**/ + UINT8 DIMMRXOFFSET; + +/** Offset 0x0321 - Reserved **/ - UINT8 Reserved31[17]; + UINT8 Reserved6[14]; /** Offset 0x032F - Board Type MrcBoardType, Options are 0=Mobile/Mobile Halo, 1=Desktop/DT Halo, 5=ULT/ULX/Mobile @@ -1478,9 +1825,11 @@ typedef struct { **/ UINT8 TxtImplemented; -/** Offset 0x0341 - Reserved +/** Offset 0x0341 - PCIE Resizable BAR Support + Enable/Disable PCIE Resizable BAR Support.0: Disable; 1: Enable; 2: Auto(Default). + $EN_DIS **/ - UINT8 Reserved32; + UINT8 PcieResizableBarSupport; /** Offset 0x0342 - Skip external display device scanning Enable: Do not scan for external display device, Disable (Default): Scan external @@ -1608,7 +1957,7 @@ typedef struct { /** Offset 0x04D6 - Reserved **/ - UINT8 Reserved33[2]; + UINT8 Reserved7[2]; /** Offset 0x04D8 - DMIC ClkA Pin Muxing (N - DMIC number) Determines DMIC ClkA Pin muxing. See GPIO_*_MUXING_DMIC_CLKA_* @@ -1623,7 +1972,7 @@ typedef struct { /** Offset 0x04E1 - Reserved **/ - UINT8 Reserved34[3]; + UINT8 Reserved8[3]; /** Offset 0x04E4 - DMIC Data Pin Muxing Determines DMIC Data Pin muxing. See GPIO_*_MUXING_DMIC_DATA_* @@ -1635,9 +1984,35 @@ typedef struct { **/ UINT8 PchHdaAudioLinkSspEnable[7]; -/** Offset 0x04F3 - Reserved +/** Offset 0x04F3 - PCH Hda Disc Bt Off Enabled + Hda Disc Bt Off Enabled +**/ + UINT8 PchHdaDiscBtOffEnabled; + +/** Offset 0x04F4 - PCH HDA Discrete BT Offload Ssp Link + Discrete BT Offload Ssp Link +**/ + UINT32 PchHdaDiscBtOffSspLink; + +/** Offset 0x04F8 - SSP Sclk Pin Muxing (N - SSP Number) + Determines SSP Sclk Pin muxing. See GPIOV2_*_MUXING_I2S*_SCLK **/ - UINT8 Reserved35[117]; + UINT32 PchHdaAudioLinkSspSclkPinMux[7]; + +/** Offset 0x0514 - SSP Sfmr Pin Muxing (N - SSP Number) + Determines SSP Sfmr Pin muxing. See GPIOV2_*_MUXING_I2S*_SFMR +**/ + UINT32 PchHdaAudioLinkSspSfmrPinMux[7]; + +/** Offset 0x0530 - SSP Txd Pin Muxing (N - SSP Number) + Determines SSP Txd Pin muxing. See GPIOV2_*_MUXING_I2S*_TXD +**/ + UINT32 PchHdaAudioLinkSspTxdPinMux[7]; + +/** Offset 0x054C - SSP Rxd Pin Muxing (N - SSP Number) + Determines SSP Rxd Pin muxing. See GPIOV2_*_MUXING_I2S*_RXD +**/ + UINT32 PchHdaAudioLinkSspRxdPinMux[7]; /** Offset 0x0568 - Enable HD Audio SoundWire#N Link Enable/disable HD Audio SNDW#N link. Muxed with HDA. @@ -1656,9 +2031,41 @@ typedef struct { **/ UINT8 PchHdaIDispLinkTmode; -/** Offset 0x056F - Reserved +/** Offset 0x056F - Sndw Multilane enablement + SoundWire Multiline enablement. Default is DISABLE. 0: DISABLE, 1: Two lines enabled, + 2: Three lines enabled, 3: Four Lines enabled. + $EN_DIS +**/ + UINT8 PchHdAudioSndwMultilaneEnable[2]; + +/** Offset 0x0571 - Reserved +**/ + UINT8 Reserved9[3]; + +/** Offset 0x0574 - SoundWire Clk Pin Muxing (N - SoundWire number) + Determines SoundWire Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_CLK* +**/ + UINT32 PchHdaAudioLinkMultilaneClkPinMux[2]; + +/** Offset 0x057C - SoundWire Multilane Data0 Pin Muxing (N - SoundWire number) + Determines SoundWire Multilane Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_DATA0* +**/ + UINT32 PchHdaAudioLinkMultilaneData0PinMux[2]; + +/** Offset 0x0584 - SoundWire Multilane Data1 Pin Muxing (N - SoundWire number) + Determines SoundWire Multilane Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_DATA1* +**/ + UINT32 PchHdaAudioLinkMultilaneData1PinMux[2]; + +/** Offset 0x058C - SoundWire Multilane Data2 Pin Muxing (N - SoundWire number) + Determines SoundWire Multilane Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_DATA2* +**/ + UINT32 PchHdaAudioLinkMultilaneData2PinMux[2]; + +/** Offset 0x0594 - SoundWire Multilane Data3 Pin Muxing (N - SoundWire number) + Determines SoundWire Multilane Clk Pin muxing. See GPIOV2_*_MUXING_SNDW_DATA3* **/ - UINT8 Reserved36[45]; + UINT32 PchHdaAudioLinkMultilaneData3PinMux[2]; /** Offset 0x059C - iDisplay Audio Codec disconnection 0: Not disconnected, enumerable, 1: Disconnected SDI, not enumerable. @@ -1666,9 +2073,20 @@ typedef struct { **/ UINT8 PchHdaIDispCodecDisconnect; -/** Offset 0x059D - Reserved +/** Offset 0x059D - Sndw Interface for Multilanes (N - SoundWire number) + 0: Not disconnected, enumerable, 1: Disconnected SDI, not enumerable. + 0: Sndw0, 1: Sndw1, 2: Sndw2, 3: Sndw3, 4: Sndw4, 5: Sndw5 +**/ + UINT8 PchHdAudioSndwMultilaneSndwInterface[2]; + +/** Offset 0x059F - Reserved +**/ + UINT8 Reserved10; + +/** Offset 0x05A0 - Audio Sub System IDs + Set default Audio Sub System IDs. If its set to 0 then value from Strap is used. **/ - UINT8 Reserved37[5]; + UINT16 ResetWaitTimer; /** Offset 0x05A2 - HDA Power/Clock Gating (PGD/CGD) Enable/Disable HD Audio Power and Clock Gating(POR: Enable). 0: PLATFORM_POR, 1: @@ -1677,18 +2095,22 @@ typedef struct { **/ UINT8 PchHdaTestPowerClockGating; -/** Offset 0x05A3 - Reserved +/** Offset 0x05A3 - Low Frequency Link Clock Source (LFLCS) + 0: POR (Enable), 1: Enable (XTAL), 2: Disable (Audio PLL). + 0: POR (Enable), 1: Enable (XTAL), 2: Disable (Audio PLL) **/ - UINT8 Reserved38; + UINT8 PchHdaTestLowFreqLinkClkSrc; /** Offset 0x05A4 - Audio Sub System IDs Set default Audio Sub System IDs. If its set to 0 then value from Strap is used. **/ UINT32 PchHdaSubSystemIds; -/** Offset 0x05A8 - Reserved +/** Offset 0x05A8 - SoundWire clock source select + Select clock source for the SoundWire controllers. 0: XTAL, 1: Audio PLL. + $EN_DIS **/ - UINT8 Reserved39; + UINT8 PchHdaSndwClockSourceSelect; /** Offset 0x05A9 - PCH LPC Enhance the port 8xh decoding Original LPC only decodes one byte of port 80h. @@ -1708,7 +2130,12 @@ typedef struct { /** Offset 0x05CE - Reserved **/ - UINT8 Reserved40[46]; + UINT8 Reserved11[14]; + +/** Offset 0x05DC - Clk Req GPIO Pin + Select Clk Req Pin. Refer to GPIO_*_MUXING_SRC_CLKREQ_x* for possible values. +**/ + UINT32 PcieClkReqGpioMux[8]; /** Offset 0x05FC - Enable PCIE RP Mask Enable/disable PCIE Root Ports. 0: disable, 1: enable. One bit for each port, bit0 @@ -1724,7 +2151,7 @@ typedef struct { /** Offset 0x0601 - Reserved **/ - UINT8 Reserved41[3]; + UINT8 Reserved12[3]; /** Offset 0x0604 - Serial Io Uart Debug Mmio Base Select SerialIo Uart default MMIO resource in SEC/PEI phase when PcdLpssUartMode @@ -1799,9 +2226,13 @@ typedef struct { **/ UINT8 WdtDisableAndLock; -/** Offset 0x061A - Reserved +/** Offset 0x061A +**/ + UINT8 FabricGVDisable; + +/** Offset 0x061B - Reserved **/ - UINT8 Reserved42[2]; + UINT8 Reserved13; /** Offset 0x061C - HECI Timeouts 0: Disable, 1: Enable (Default) timeout check for HECI @@ -1852,9 +2283,18 @@ typedef struct { **/ UINT8 SkipMbpHob; -/** Offset 0x0624 - Reserved +/** Offset 0x0624 - HECI Communication + Test, 0: POR, 1: enable, 2: disable, Disables HECI communication causing ME to enter + error state. + $EN_DIS +**/ + UINT8 HeciCommunication; + +/** Offset 0x0625 - HECI3 Interface Communication + Test, 0: POR, 1: enable, 2: disable, Adds or Removes HECI3 Device from PCI space. + $EN_DIS **/ - UINT8 Reserved43[2]; + UINT8 HeciCommunication3; /** Offset 0x0626 - ISA Serial Base selection Select ISA Serial Base address. Default is 0x3F8. @@ -1873,9 +2313,47 @@ typedef struct { **/ UINT16 PostCodeOutputPort; -/** Offset 0x062A - Reserved +/** Offset 0x062A - Enable/Disable I2cPostcode + Enable (Default): Postcode via I2C, Disable: Postcode via Port80 + $EN_DIS +**/ + UINT8 I2cPostCodeEnable; + +/** Offset 0x062B - Reserved +**/ + UINT8 Reserved14[5]; + +/** Offset 0x0630 - FSPM Validation Pointer + Point to FSPM Validation configuration structure +**/ + UINT64 FspmValidationPtr; + +/** Offset 0x0638 - Extended BIOS Support + Enable/Disable Extended BIOS Region Support. Default is DISABLE. 0: DISABLE, 1: ENABLE + $EN_DIS +**/ + UINT8 ExtendedBiosDecodeRange; + +/** Offset 0x0639 - Extented BIOS Direct Read Decode enable + Enable/Disable access to bigger than 16MB BIOS Region through Direct Memory Reads. + 0: disabled (default), 1: enabled + $EN_DIS +**/ + UINT8 PchSpiExtendedBiosDecodeRangeEnable; + +/** Offset 0x063A - Reserved +**/ + UINT8 Reserved15[2]; + +/** Offset 0x063C - Extended BIOS Direct Read Decode Range base + Bits of 31:16 of a memory address that'll be a base for Extended BIOS Direct Read Decode. +**/ + UINT32 PchSpiExtendedBiosDecodeRangeBase; + +/** Offset 0x0640 - Extended BIOS Direct Read Decode Range limit + Bits of 31:16 of a memory address that'll be a limit for Extended BIOS Direct Read Decode. **/ - UINT8 Reserved44[26]; + UINT32 PchSpiExtendedBiosDecodeRangeLimit; /** Offset 0x0644 - Enable SMBus Enable/disable SMBus controller. @@ -1896,7 +2374,7 @@ typedef struct { /** Offset 0x0647 - Reserved **/ - UINT8 Reserved45; + UINT8 Reserved16; /** Offset 0x0648 - SMBUS Base Address SMBUS Base Address (IO space). @@ -1911,7 +2389,7 @@ typedef struct { /** Offset 0x064B - Reserved **/ - UINT8 Reserved46[13]; + UINT8 Reserved17[13]; /** Offset 0x0658 - Smbus dynamic power gating Disable or Enable Smbus dynamic power gating. @@ -1932,9 +2410,51 @@ typedef struct { **/ UINT8 SaOcSupport; -/** Offset 0x065B - Reserved +/** Offset 0x065B - VF Point Count + Number of supported Voltage & Frequency Point Offset +**/ + UINT8 VfPointCount[10]; + +/** Offset 0x0665 - ProcessVmaxLimit + Disabling Process Vmax Limit will allow user to set any voltage +**/ + UINT8 ProcessVmaxLimit; + +/** Offset 0x0666 - CorePllCurrentRefTuningOffset + Core PLL Current Reference Tuning Offset. 0: No offset. Range 0-15 +**/ + UINT8 CorePllCurrentRefTuningOffset; + +/** Offset 0x0667 - RingPllCurrentRefTuningOffset + Ring PLL Current Reference Tuning Offset. 0: No offset. Range 0-15 +**/ + UINT8 RingPllCurrentRefTuningOffset; + +/** Offset 0x0668 - IaAtomPllCurrentRefTuningOffset + IaAtom PLL Current Reference Tuning Offset. 0: No offset. Range 0-15 +**/ + UINT8 IaAtomPllCurrentRefTuningOffset; + +/** Offset 0x0669 - CoreMinRatio + equest Core Min Ratio. Limit Core minimum ratio for extreme overclocking. Default + 0 indicates no request **/ - UINT8 Reserved47[18]; + UINT8 CoreMinRatio; + +/** Offset 0x066A - CoreMiNegativeTemperatureReportingnRatio + Negative Temperature Reporting Enable. 0: Disable, 1: enable +**/ + UINT8 NegativeTemperatureReporting; + +/** Offset 0x066B - PcorePowerDensityThrottle + Power Density Throttle control allows user to disable P-core +**/ + UINT8 PcorePowerDensityThrottle; + +/** Offset 0x066C - EcorePowerDensityThrottle + Power Density Throttle control allows user to disable P-core +**/ + UINT8 EcorePowerDensityThrottle; /** Offset 0x066D - Over clocking support Over clocking support; 0: Disable; 1: Enable @@ -1942,9 +2462,12 @@ typedef struct { **/ UINT8 OcSupport; -/** Offset 0x066E - Reserved +/** Offset 0x066E - UnderVolt Protection + When UnderVolt Protection is enabled, user will be not be able to program under + voltage in OS runtime. 0: Disabled; 1: Enabled + $EN_DIS **/ - UINT8 Reserved48; + UINT8 UnderVoltProtection; /** Offset 0x066F - Realtime Memory Timing 0(Default): Disabled, 1: Enabled. When enabled, it will allow the system to perform @@ -2005,9 +2528,18 @@ typedef struct { **/ UINT8 Lfsr1Mask; -/** Offset 0x067B - Reserved +/** Offset 0x067B - Row Hammer DRAM Refresh Management Mode + Row Hammer Adaptive Refresh Management Level: 0-RFM (default), 1-ARFMLevel A, 2-ARFMLevel + B, 3-ARFMLevel C, 4-Disable ARFM and RFM + 0: RFM, 1: ARFM Level A, 2: ARFM Level B, 3: ARFM Level C, 4: ARFM and RFM Disabled +**/ + UINT8 DramRfmMode; + +/** Offset 0x067C - Row Hammer Targeted Row Refresh Mode + Row Hammer Targeted Row Refresh: 0-DRFM, 1-pTRR (default), 2-Disable DRFM and pTRR + 0: DRFM, 1: pTRR, 2: Targeted Row Refresh Disabled **/ - UINT8 Reserved49[2]; + UINT8 TargetedRowRefreshMode; /** Offset 0x067D - TjMax Offset TjMax offset.Specified value here is clipped by pCode (125 - TjMax Offset) to support @@ -2015,9 +2547,27 @@ typedef struct { **/ UINT8 TjMaxOffset; -/** Offset 0x067E - Reserved +/** Offset 0x067E - Per-Atom-Cluster VF Offset + Array used to specifies the selected Atom Core Cluster Offset Voltage. This voltage + is specified in millivolts. +**/ + UINT16 PerAtomClusterVoltageOffset[8]; + +/** Offset 0x068E - Per-Atom-Cluster VF Offset Prefix + Sets the PerAtomCLusterVoltageOffset value as positive or negative for the selected + Core; 0: Positive ; 1: Negative. +**/ + UINT8 PerAtomClusterVoltageOffsetPrefix[8]; + +/** Offset 0x0696 - Per-Atom-Cluster Voltage Mode + Array used to specifies the selected Atom Core ClusterVoltage Mode. +**/ + UINT8 PerAtomClusterVoltageMode[8]; + +/** Offset 0x069E - Per-Atom-Cluster Voltage Override + Array used to specifies the selected Atom Core Cluster Voltage Override. **/ - UINT8 Reserved50[48]; + UINT16 PerAtomClusterVoltageOverride[8]; /** Offset 0x06AE - Core VF Point Offset Array used to specifies the Core Voltage Offset applied to the each selected VF @@ -2037,9 +2587,28 @@ typedef struct { **/ UINT8 CoreVfPointRatio[15]; -/** Offset 0x06EA - Reserved +/** Offset 0x06EA - Core VF Configuration Scope + Allows both all-core VF curve or per-core VF curve configuration; 0: All-core; + 1: Per-core. + 0:All-core, 1:Per-core +**/ + UINT8 CoreVfConfigScope; + +/** Offset 0x06EB - Reserved +**/ + UINT8 Reserved18; + +/** Offset 0x06EC - Per-core VF Offset + Array used to specifies the selected Core Offset Voltage. This voltage is specified + in millivolts. +**/ + UINT16 PerCoreVoltageOffset[8]; + +/** Offset 0x06FC - Per-core VF Offset Prefix + Sets the PerCoreVoltageOffset value as positive or negative for the selected Core; + 0: Positive ; 1: Negative. **/ - UINT8 Reserved51[26]; + UINT8 PerCoreVoltageOffsetPrefix[8]; /** Offset 0x0704 - Per Core Max Ratio override Enable or disable Per Core PState OC supported by writing OCMB 0x1D to program new @@ -2048,18 +2617,30 @@ typedef struct { **/ UINT8 PerCoreRatioOverride; -/** Offset 0x0705 - Reserved +/** Offset 0x0705 - Per-core Voltage Mode + Array used to specifies the selected Core Voltage Mode. +**/ + UINT8 PerCoreVoltageMode[8]; + +/** Offset 0x070D - Reserved +**/ + UINT8 Reserved19; + +/** Offset 0x070E - Per-core Voltage Override + Array used to specifies the selected Core Voltage Override. **/ - UINT8 Reserved52[25]; + UINT16 PerCoreVoltageOverride[8]; /** Offset 0x071E - Per Core Current Max Ratio Array for the Per Core Max Ratio **/ UINT8 PerCoreRatio[8]; -/** Offset 0x0726 - Reserved +/** Offset 0x0726 - Atom Cluster Max Ratio + Array for Atom Cluster Max Ratio, 4 ATOM cores are in the same Cluster and their + max core ratio will be aligned. **/ - UINT8 Reserved53[8]; + UINT8 AtomClusterRatio[8]; /** Offset 0x072E - Pvd Ratio Threshold for SOC/CPU die Array of Pvd Ratio Threshold for SOC/CPU die is the threshold value for input ratio @@ -2070,22 +2651,80 @@ typedef struct { **/ UINT8 PvdRatioThreshold; -/** Offset 0x072F - Reserved +/** Offset 0x072F - Pvd Mode SOC/CPU die + Array of PVD Mode. Value from 0 to 3 for SOC/CPU. 0x0 = div-1 (VCO = Output clock), + 0x1 = div-2 (VCO = 2x Output clock), 0x2 = div-4 (VCO = 4x Output clock), 0x3 = + div-8 (VCO = 8x Output clock). **/ - UINT8 Reserved54[65]; + UINT8 PvdMode; -/** Offset 0x0770 - CPU BCLK OC Frequency - CPU BCLK OC Frequency in KHz units. 98000000Hz = 98MHz 0 - Auto. Range is - 40Mhz-1000Mhz. +/** Offset 0x0730 - FLL Overclock Mode + Select FLL Mode Value from 0 to 3. 0x0 = no overclocking, 0x1 = ratio overclocking + with nominal (0.5-1x) reference clock frequency, 0x2 = BCLK overclocking with elevated + (1-3x) reference clock frequency, 0x3 = BCLK overclocking with extreme elevated + (3-5x) reference clock frequency and ratio limited to 63. **/ - UINT32 CpuBclkOcFrequency; + UINT8 FllOverclockMode; -/** Offset 0x0774 - Reserved +/** Offset 0x0731 - Reserved **/ - UINT8 Reserved55[13]; + UINT8 Reserved20; -/** Offset 0x0781 - Avx2 Voltage Guardband Scaling Factor - AVX2 Voltage Guardband Scale factor applied to AVX2 workloads. Range is 0-200 in +/** Offset 0x0732 - Ring VF Point Offset + Array used to specifies the Ring Voltage Offset applied to the each selected VF + Point. This voltage is specified in millivolts. +**/ + UINT16 RingVfPointOffset[15]; + +/** Offset 0x0750 - Ring VF Point Offset Prefix + Sets the RingVfPointOffset value as positive or negative for corresponding core + VF Point; 0: Positive ; 1: Negative. +**/ + UINT8 RingVfPointOffsetPrefix[15]; + +/** Offset 0x075F - Ring VF Point Ratio + Array for the each selected Ring VF Point to display the ration. +**/ + UINT8 RingVfPointRatio[15]; + +/** Offset 0x076E - Soc Die SSC enable + Enable/Disable Soc-Die SSC Configuration. 0(Default)=Disable, 1=Enable + $EN_DIS +**/ + UINT8 SocDieSscEnable; + +/** Offset 0x076F - Core Operating Point Reporting + Enables Core Operating point reporting. 0: Disable; 1: Enable + 0:Disable, 1:Enable +**/ + UINT8 CoreOpPointReportingEn; + +/** Offset 0x0770 - CPU BCLK OC Frequency + CPU BCLK OC Frequency in KHz units. 98000000Hz = 98MHz 0 - Auto. Range is + 40Mhz-1000Mhz. +**/ + UINT32 CpuBclkOcFrequency; + +/** Offset 0x0774 - SOC BCLK OC Frequency + SOC BCLK OC Frequency in KHz units. 98000000Hz = 98MHz 0 - Auto. Range is + 40Mhz-1000Mhz. +**/ + UINT32 SocBclkOcFrequency; + +/** Offset 0x0778 - Bitmask of disable cores + Core mask is a bitwise indication of which core should be disabled. 0x00=Default; + Bit 0 - core 0, bit 7 - core 7. +**/ + UINT64 DisablePerCoreMask; + +/** Offset 0x0780 - Granular Ratio Override + Enable or disable OC Granular Ratio Override. 0: Disable, 1: enable + $EN_DIS +**/ + UINT8 GranularRatioOverride; + +/** Offset 0x0781 - Avx2 Voltage Guardband Scaling Factor + AVX2 Voltage Guardband Scale factor applied to AVX2 workloads. Range is 0-200 in 1/100 units, where a value of 125 would apply a 1.25 scale factor. **/ UINT8 Avx2VoltageScaleFactor; @@ -2097,7 +2736,7 @@ typedef struct { /** Offset 0x0783 - Reserved **/ - UINT8 Reserved56[5]; + UINT8 Reserved21[5]; /** Offset 0x0788 - Enable PCH ISH Controller 0: Disable, 1: Enable (Default) ISH Controller @@ -2107,7 +2746,7 @@ typedef struct { /** Offset 0x0789 - Reserved **/ - UINT8 Reserved57; + UINT8 Reserved22; /** Offset 0x078A - BiosSize The size of the BIOS region of the IFWI. Used if FspmUpd->FspmConfig.BiosGuard != @@ -2140,9 +2779,24 @@ typedef struct { **/ UINT8 SkipStopPbet; -/** Offset 0x0790 - Reserved +/** Offset 0x0790 - Reset Auxiliary content + Reset Auxiliary content, 0: Disabled, 1: Enabled + $EN_DIS +**/ + UINT8 ResetAux; + +/** Offset 0x0791 - TseEnable + Enable/Disable. 0: Disable, Enable/Disable Tse feature, 1: enable + $EN_DIS **/ - UINT8 Reserved58[3]; + UINT8 TseEnable; + +/** Offset 0x0792 - Enable or Disable TDX + Configure Trust Domain Extension (TDX) to isolate VMs from Virtual-Machine Manager + (VMM)/hypervisor 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 TdxEnable; /** Offset 0x0793 - MKTME Key-Id Bits Override Enable Configure Trust Domain Extension (TDX) to isolate VMs from Virtual-Machine Manager @@ -2153,7 +2807,7 @@ typedef struct { /** Offset 0x0794 - Reserved **/ - UINT8 Reserved59[4]; + UINT8 Reserved23[4]; /** Offset 0x0798 - TME Exclude Base Address TME Exclude Base Address. @@ -2165,9 +2819,26 @@ typedef struct { **/ UINT64 TmeExcludeSize; -/** Offset 0x07A8 - Reserved +/** Offset 0x07A8 - TdxActmModuleAddr + Base address of Tdx Actm module, used for launching the Actm +**/ + UINT64 TdxActmModuleAddr; + +/** Offset 0x07B0 - TdxActmModuleSize + size of Tdx Actm module, used for launching the Actm +**/ + UINT32 TdxActmModuleSize; + +/** Offset 0x07B4 - TdxSeamldrSvn + TdxSeamldrSvn +**/ + UINT8 TdxSeamldrSvn; + +/** Offset 0x07B5 - Boot max frequency + Enable Boot Maximum Frequency in CPU strap. 0: Disable; 1: Enable + $EN_DIS **/ - UINT8 Reserved60[14]; + UINT8 BootMaxFrequency; /** Offset 0x07B6 - BIST on Reset Enable/Disable BIST (Built-In Self Test) on reset. 0: Disable; 1: Enable. @@ -2175,9 +2846,11 @@ typedef struct { **/ UINT8 BistOnReset; -/** Offset 0x07B7 - Reserved +/** Offset 0x07B7 - Reduce XeCores + Enable/Disable Reduce XeCores. 0: Disable(strap=1) ; 1: Enable(strap=0. + $EN_DIS **/ - UINT8 Reserved61; + UINT8 ReduceXecores; /** Offset 0x07B8 - Enable or Disable VMX Enable or Disable VMX, When enabled, a VMM can utilize the additional hardware capabilities @@ -2245,9 +2918,29 @@ typedef struct { **/ UINT8 ActiveCoreCount; -/** Offset 0x07C2 - Reserved +/** Offset 0x07C2 - Number of active small cores + Number of E-cores to enable in each processor package. Note: Number of P-Cores and + E-Cores are looked at together. When both are {0,0 + 0:Disable all small cores, 1:1, 2:2, 3:3, 0xFF:Active all small cores +**/ + UINT8 ActiveSmallCoreCount; + +/** Offset 0x07C3 - Number of LP Atom cores + Number of LP E-cores to enable in LP. 0: Disable all LP Atom cores; 1: 1; 2: 2; + 0xFF: Active all LP Atom cores + 0:Disable all LP Atom cores, 1:1, 2:2, 0xFF:Active all cores +**/ + UINT8 ActiveLpAtomCoreCount; + +/** Offset 0x07C4 - DFD Enable + Enable or Disable DFD. 0: Disable, 1:Enable + $EN_DIS +**/ + UINT8 DfdEnable; + +/** Offset 0x07C5 - Reserved **/ - UINT8 Reserved62[6]; + UINT8 Reserved24[3]; /** Offset 0x07C8 - PrmrrSize Enable/Disable. 0: Disable, define default value of PrmrrSize , 1: enable @@ -2275,7 +2968,351 @@ typedef struct { /** Offset 0x07D2 - Reserved **/ - UINT8 Reserved63[98]; + UINT8 Reserved25[2]; + +/** Offset 0x07D4 - Platform PL1 power + Platform Power Limit 1 Power in Milli Watts. BIOS will round to the nearest 1/8W + when programming. Value set 120 = 15W. Any value can be programmed between Max + and Min Power Limits. This setting will act as the new PL1 value for the Package + RAPL algorithm. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. Valid Range + 0 to 32767. +**/ + UINT32 PsysPowerLimit1Power; + +/** Offset 0x07D8 - PlatformAtxTelemetryUnit Mode + Enable/Disable PlatformAtxTelemetryUnit Mode. 0: Disable ; 1:Enable + $EN_DIS +**/ + UINT32 PlatformAtxTelemetryUnit; + +/** Offset 0x07DC - Platform PL1 power + Short term Power Limit value for custom cTDP level. Units are 125 milliwatt. +**/ + UINT16 CustomPowerLimit1; + +/** Offset 0x07DE - Platform PL1 power + Short term Power Limit value for custom cTDP level. Units are 125 milliwatt. +**/ + UINT16 CustomPowerLimit2; + +/** Offset 0x07E0 - Platform PL2 power + Platform Power Limit 2 Power in Milli Watts. BIOS will round to the nearest 1/8W + when programming. Value set 120 = 15W. Any value can be programmed between Max + and Min Power Limits. This setting will act as the new Max Turbo Power (PL2) value + for the Package RAPL algorithm. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 PsysPowerLimit2Power; + +/** Offset 0x07E4 - Vsys Max System battery volatge + Vsys Max defined in 1/1000 increments. Range is 0-65535. For a 1.25 voltage, enter + 1250. Default =0xFF. +**/ + UINT16 VsysMax; + +/** Offset 0x07E6 - ThETA Ibatt Feature + Enable or Disable ThETA Ibatt Feature. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 ThETAIbattEnable; + +/** Offset 0x07E7 - Reserved +**/ + UINT8 Reserved26; + +/** Offset 0x07E8 - ISYS Current Limit L1 + This field indicated the current limitiation of L1. Indicate current limit for which + dependency is on AC/DC mode before PSYS.Units of measurements are 1/8 A +**/ + UINT16 IsysCurrentLimitL1; + +/** Offset 0x07EA - ISYS Current Limit L1 Tau + This Specifies the time window used to calculate average current for ISYS_L1. The + units of measuremnts are specified in PACKAGE_POWER_SKU[TIME_UNIT] +**/ + UINT8 IsysCurrentL1Tau; + +/** Offset 0x07EB - Reserved +**/ + UINT8 Reserved27; + +/** Offset 0x07EC - ISYS Current Limit L2 + This bits enables disables ISYS_CURRENT_LIMIT_L2 algorithm.Indicate current limit + for which dependency is on AC/DC mode before PSYS. Units of measurements are 1/8 A +**/ + UINT16 IsysCurrentLimitL2; + +/** Offset 0x07EE - ISYS Current Limit L1 Enable + This bits enables disables ISYS_CURRENT_LIMIT_L1 algorithm. It control loop based + on the system power source AC or DC mode. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 IsysCurrentLimitL1Enable; + +/** Offset 0x07EF - ISYS Current Limit L2 Enable + This bits enables disables ISYS_CURRENT_LIMIT_L2 algorithm. It control loop based + on the system power source AC or DC mode. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 IsysCurrentLimitL2Enable; + +/** Offset 0x07F0 - Package PL4 boost configuration + Configure Power Limit 4 Boost in Watts. Valid Range 0 to 63000 in step size of 125 + mWatt. The value 0 means disable. +**/ + UINT16 PowerLimit4Boost; + +/** Offset 0x07F2 - Skin Temperature Target + Target temperature is limit to which the control mechanism is regulating.It is defined + in 1/2 C increments.Range is 0-255. Temperature Range is 0-122.5 C.0: Auto. +**/ + UINT8 SkinTargetTemp[3]; + +/** Offset 0x07F5 - Skin Control Temperature Enable MMIO + Enables the skin temperature control for MMIO register. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 SkinTempControlEnable[3]; + +/** Offset 0x07F8 - Skin Temperature Loop Gain + Sets the aggressiveness of control loop where 0 is graceful, favors performance + on expense of temperature overshoots and 7 is for aggressive, favors tight regulation + over performance. Range is 0-7.0: Auto. +**/ + UINT8 SkinControlLoopGain[3]; + +/** Offset 0x07FB - Skin Temperature Override Enable + When set, Pcode will use TEMPERATURE_OVERRIDE values instead of reading from corresponding + sensor.. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 SkinTempOverrideEnable[3]; + +/** Offset 0x07FE - Skin Temperature Minimum Performance Level + Minimum Performance level below which the STC limit will not throttle. 0 - all levels + of throttling allowed incl. survivability actions. 256 - no throttling allowed.0: Auto. +**/ + UINT8 SkinMinPerformanceLevel[3]; + +/** Offset 0x0801 - Skin Temperature Override + Allows SW to override the input temperature. Pcode will use this value instead of + the sensor temperature. EC control is not impacted. Units: 0.5C. Values are 0 to + 255 which represents 0C-122.5C range.0: Auto. +**/ + UINT8 SkinTempOverride[3]; + +/** Offset 0x0804 - Skin Temperature Control Enable + Enables Skin Temperature Control Sensors Feature. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 SkinTempControl; + +/** Offset 0x0805 - AC or DC Power State + AC or DC power State; 0: DC; 1: AC + 0:DC, 1:AC +**/ + UINT8 AcDcPowerState; + +/** Offset 0x0806 - Enable or Disable VR Thermal Alert + Enable or Disable VR Thermal Alert; 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 DisableVrThermalAlert; + +/** Offset 0x0807 - Enable or Disable Thermal Monitor + Enable or Disable Thermal Monitor; 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 ThermalMonitor; + +/** Offset 0x0808 - Configuration for boot TDP selection + Assured Power (cTDP) Mode as Nominal/Level1/Level2/Deactivate Base Power (TDP) selection. + Deactivate option will set MSR to Nominal and MMIO to Zero. 0: Base Power (TDP) + Nominal; 1: Base Power (TDP) Down; 2: Base Power (TDP) Up;0xFF : Deactivate +**/ + UINT8 ConfigTdpLevel; + +/** Offset 0x0809 - ConfigTdp mode settings Lock + Assured Power (cTDP) Mode Lock sets the Lock bits on TURBO_ACTIVATION_RATIO and + CONFIG_TDP_CONTROL. Note: When CTDP (Assured Power) Lock is enabled Custom ConfigTDP + Count will be forced to 1 and Custom ConfigTDP Boot Index will be forced to 0. + 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 ConfigTdpLock; + +/** Offset 0x080A - Load Configurable TDP SSDT + Enables Assured Power (cTDP) control via runtime ACPI BIOS methods. This 'BIOS only' + feature does not require EC or driver support. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 ConfigTdpBios; + +/** Offset 0x080B - CustomTurboActivationRatio + Turbo Activation Ratio for custom cTDP level + $EN_DIS +**/ + UINT8 CustomTurboActivationRatio; + +/** Offset 0x080C - CustomPowerLimit1Time + Short term Power Limit time window value for custom cTDP level. + $EN_DIS +**/ + UINT8 CustomPowerLimit1Time; + +/** Offset 0x080D - PL1 Enable value + Enable/Disable Platform Power Limit 1 programming. If this option is enabled, it + activates the PL1 value to be used by the processor to limit the average power + of given time window. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 PsysPowerLimit1; + +/** Offset 0x080E - PL1 timewindow + Platform Power Limit 1 Time Window value in seconds. The value may vary from 0 to + 128. 0 = default values. Indicates the time window over which Platform Processor + Base Power (TDP) value should be maintained. Valid values(Unit in seconds) 0 to + 8 , 10 , 12 ,14 , 16 , 20 , 24 , 28 , 32 , 40 , 48 , 56 , 64 , 80 , 96 , 112 , 128 +**/ + UINT8 PsysPowerLimit1Time; + +/** Offset 0x080F - PL2 Enable Value + Enable/Disable Platform Power Limit 2 programming. If this option is disabled, BIOS + will program the default values for Platform Power Limit 2. 0: Disable; + 1: Enable. + $EN_DIS +**/ + UINT8 PsysPowerLimit2; + +/** Offset 0x0810 - Package PL3 time window + Power Limit 3 Time Window value in Milli seconds. Indicates the time window over + which Power Limit 3 value should be maintained. If the value is 0, BIOS leaves + the hardware default value. Valid value: 0, 3-8, 10, 12, 14, 16, 20, 24, + 28, 32, 40, 48, 56, 64. +**/ + UINT8 PowerLimit3Time; + +/** Offset 0x0811 - Package Long duration turbo mode time + Power Limit 1 Time Window value in seconds. The value may vary from 0 to 128. 0 + = default value (28 sec for Mobile and 8 sec for Desktop). Defines time window + which Processor Base Power (TDP) value should be maintained. Valid values(Unit + in seconds) 0 to 8 , 10 , 12 ,14 , 16 , 20 , 24 , 28 , 32 , 40 , 48 , 56 , 64 , + 80 , 96 , 112 , 128 +**/ + UINT8 PowerLimit1Time; + +/** Offset 0x0812 - Reserved +**/ + UINT8 Reserved28[2]; + +/** Offset 0x0814 - Package Long duration turbo mode power limit + Power Limit 1 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. 0 = no custom override. Overclocking SKU: Value must be between + Max and Min Power Limits. Other SKUs: This value must be between Min Power Limit + and Processor Base Power (TDP) Limit. If value is 0, BIOS will program Processor + Base Power (TDP) value. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. Valid + Range 0 to 32767. +**/ + UINT32 PowerLimit1; + +/** Offset 0x0818 - Package Short duration turbo mode power limit + Power Limit 2 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. If the value is 0, BIOS will program this value as 1.25*Processor + Base Power (TDP). Processor applies control policies such that the package power + does not exceed this limit. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 PowerLimit2Power; + +/** Offset 0x081C - Package PL3 power limit + Power Limit 3 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. XE SKU: Any value can be programmed. Overclocking SKU: Value + must be between Max and Min Power Limits. Other SKUs: This value must be between + Min Power Limit and Processor Base Power (TDP) Limit. If the value is 0, BIOS leaves + the hardware default value. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 PowerLimit3; + +/** Offset 0x0820 - Package PL4 power limit + Power Limit 4 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. If the value is 0, BIOS leaves default value. Units are based + on POWER_MGMT_CONFIG.CustomPowerUnit. Valid Range 0 to 32767. +**/ + UINT32 PowerLimit4; + +/** Offset 0x0824 - Short term Power Limit value for custom cTDP level 1 + Power Limit 1 in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. 0 = no custom override. Overclocking SKU: Value must be between + Max and Min Power Limits. Other SKUs: This value must be between Min Power Limit + and Processor Base Power (TDP) Limit. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 Custom1PowerLimit1; + +/** Offset 0x0828 - Long term Power Limit value for custom cTDP level 1 + Power Limit 2 value in Milli Watts. BIOS will round to the nearest 1/8W when programming. + Value set 120 = 15W. 0 = no custom override. Processor applies control policies + such that the package power does not exceed this limit. Units are based on POWER_MGMT_CONFIG.CustomPowerUnit. + Valid Range 0 to 32767. +**/ + UINT32 Custom1PowerLimit2; + +/** Offset 0x082C - Enable Configurable TDP + Applies Assured Power (cTDP) initialization settings based on non-Assured Power + (cTDP) or Assured Power (cTDP). Default is 1: Applies to Assured Power (cTDP) ; + if 0 then applies non-Assured Power (cTDP) and BIOS will bypass Assured Power (cTDP) + initialization flow + $EN_DIS +**/ + UINT8 ApplyConfigTdp; + +/** Offset 0x082D - Dual Tau Boost + Enable Dual Tau Boost feature. This is only applicable for Desktop 35W/65W/125W + sku. When DPTF is enabled this feature is ignored. 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 DualTauBoost; + +/** Offset 0x082E - Tcc Offset Lock + Tcc Offset Lock for Runtime Average Temperature Limit (RATL) to lock temperature + target; 1:Enabled ; 0: Disabled. + $EN_DIS +**/ + UINT8 TccOffsetLock; + +/** Offset 0x082F - Package PL3 Duty Cycle + Specify the duty cycle in percentage that the CPU is required to maintain over the + configured time window. Range is 0-100. +**/ + UINT8 PowerLimit3DutyCycle; + +/** Offset 0x0830 - Package PL3 Lock + Power Limit 3 Lock. When enabled PL3 configurations are locked during OS. When disabled + PL3 configuration can be changed during OS. 0: Disable ; 1:Enable + $EN_DIS +**/ + UINT8 PowerLimit3Lock; + +/** Offset 0x0831 - Package PL4 Lock + Power Limit 4 Lock. When enabled PL4 configurations are locked during OS. When disabled + PL4 configuration can be changed during OS. 0: Disable ; 1:Enable + $EN_DIS +**/ + UINT8 PowerLimit4Lock; + +/** Offset 0x0832 - Short Duration Turbo Mode + Enable/Disable Power Limit 2 override. If this option is disabled, BIOS will program + the default values for Power Limit 2. 0: Disable; 1: Enable + $EN_DIS +**/ + UINT8 PowerLimit2; + +/** Offset 0x0833 - Response Mode + Enable/Disable Response Mode. 0: Disable ; 1:Enable + $EN_DIS +**/ + UINT8 ResponseMode; /** Offset 0x0834 - SinitMemorySize Enable/Disable. 0: Disable, define default value of SinitMemorySize , 1: enable @@ -2340,9 +3377,18 @@ typedef struct { **/ UINT8 AcousticNoiseMitigation; -/** Offset 0x086E - Reserved +/** Offset 0x086E - RfiMitigation + Enable or Disable RFI Mitigation. 0: Disable - DCM is the IO_N default; 1: + Enable - Enable IO_N DCM/CCM switching as RFI mitigation. + $EN_DIS +**/ + UINT8 RfiMitigation; + +/** Offset 0x086F - Platform Psys slope correction + PSYS Slope defined in 1/100 increments. 0 - Auto Specified in 1/100 increment + values. Range is 0-200. 125 = 1.25 **/ - UINT8 Reserved64[2]; + UINT8 PsysSlope; /** Offset 0x0870 - Platform Power Pmax PSYS PMax power, defined in 1/8 Watt increments. 0 - Auto Specified in 1/8 @@ -2394,7 +3440,14 @@ typedef struct { /** Offset 0x08BA - Reserved **/ - UINT8 Reserved65[26]; + UINT8 Reserved29[2]; + +/** Offset 0x08BC - Imon offset correction + IMON Offset is an 32-bit signed value (2's complement). Units 1/1000, Range is [-128000, + 127999]. For an offset of 25.348, enter 25348. 0: Auto. [0] for IA, [1] + for GT, [2] for SA, [3] through [5] are Reserved. +**/ + UINT32 ImonOffset[6]; /** Offset 0x08D4 - Icc Max limit Voltage Regulator Current Limit (Icc Max). This value represents the Maximum instantaneous @@ -2404,9 +3457,34 @@ typedef struct { **/ UINT16 IccMax[6]; -/** Offset 0x08E0 - Reserved +/** Offset 0x08E0 - VR Fast Vmode VoltageLimit support + Voltage Regulator Fast VoltageLimit . +**/ + UINT16 VrVoltageLimit[6]; + +/** Offset 0x08EC - Imon slope correction + IMON Slope defined in 1/100 increments. Range is 0-200. For a 1.25 slope, enter + 125. 0: Auto. [0] for IA, [1] for GT, [2] for SA, [3] through [5] are Reserved. **/ - UINT8 Reserved66[42]; + UINT16 ImonSlope[6]; + +/** Offset 0x08F8 - Power State 3 enable/disable + PS3 Enable/Disable. 0 - Disabled, 1 - Enabled. [0] for IA, [1] for GT, [2] for SA, + [3] through [5] are Reserved. +**/ + UINT8 Ps3Enable[6]; + +/** Offset 0x08FE - Power State 4 enable/disable + PS4 Enable/Disable. 0 - Disabled, 1 - Enabled. [0] for IA, [1] for GT, [2] for SA, + [3] through [5] are Reserved. +**/ + UINT8 Ps4Enable[6]; + +/** Offset 0x0904 - Enable/Disable BIOS configuration of VR + VR Config Enable. [0] for IA, [1] for GT, [2] for SA, [3] through [5] are Reserved. + 0: Disable; 1: Enable. +**/ + UINT8 VrConfigEnable[6]; /** Offset 0x090A - Thermal Design Current enable/disable Thermal Design Current enable/disable; 0: Disable; 1: Enable. [0] for IA, @@ -2414,9 +3492,11 @@ typedef struct { **/ UINT8 TdcEnable[6]; -/** Offset 0x0910 - Reserved +/** Offset 0x0910 - Thermal Design Current Lock + Thermal Design Current Lock; 0: Disable; 1: Enable. [0] for IA, [1] for GT, + [2] for SA, [3] for atom, [4]-[5] are Reserved. **/ - UINT8 Reserved67[6]; + UINT8 TdcLock[6]; /** Offset 0x0916 - Disable Fast Slew Rate for Deep Package C States for VR domains This option needs to be configured to reduce acoustic noise during deeper C states. @@ -2438,7 +3518,14 @@ typedef struct { /** Offset 0x0922 - Reserved **/ - UINT8 Reserved68[6]; + UINT8 Reserved30[2]; + +/** Offset 0x0924 - Platform Psys offset correction + PSYS Offset defined in 1/1000 increments. 0 - Auto This is an 32-bit signed + value (2's complement). Units 1/1000, Range is [-128000, 127999]. For an offset + of 25.348, enter 25348. +**/ + UINT32 PsysOffset; /** Offset 0x0928 - Thermal Design Current time window Auto = 0 is default. Range is from 1ms to 448s. 0: Auto. [0] for IA, [1] @@ -2452,9 +3539,17 @@ typedef struct { **/ UINT8 TdcMode[6]; -/** Offset 0x0946 - Reserved +/** Offset 0x0946 - DLVR RFI Enable + Enable/Disable DLVR RFI frequency hopping. 0: Disable; 1: Enable. + $EN_DIS +**/ + UINT8 FivrSpectrumEnable; + +/** Offset 0x0947 - DLVR RFI Spread Spectrum Percentage + DLVR SSC in percentage with multiple of 0.25%. 0 = 0%, 10 = 4%. 0x00: 0% , 0x02: + 0.5%, 0x04: 1% , 0x08: 2% ,0x10: 4%; u3.2 value from 0% - 4%. **/ - UINT8 Reserved69[2]; + UINT8 DlvrSpreadSpectrumPercentage; /** Offset 0x0948 - DLVR RFI Enable Enable/Disable DLVR RFI frequency hopping. 0: Disable; 1: Enable. @@ -2474,7 +3569,53 @@ typedef struct { /** Offset 0x094B - Reserved **/ - UINT8 Reserved70[11]; + UINT8 Reserved31; + +/** Offset 0x094C - DLVR RFI Frequency + DLVR RFI Frequency in MHz. 0: 2227 MHz , 1: 2140MHZ. +**/ + UINT16 DlvrRfiFrequency; + +/** Offset 0x094E - DLVR PHASE_SSC Enable + Enable/Disable DLVR PHASE_SSC. 0: Disable. 1:Enable. + $EN_DIS +**/ + UINT8 VrPowerDeliveryDesign; + +/** Offset 0x094F - DLVR PHASE_SSC Enable + Enable/Disable DLVR PHASE_SSC. 0: Disable. 1:Enable. + $EN_DIS +**/ + UINT8 DlvrPhaseSsc; + +/** Offset 0x0950 - Vsys Critical + PCODE MMIO Mailbox: Vsys Critical. 0: Disable; 1: Enable Range is 0-255. +**/ + UINT8 EnableVsysCritical; + +/** Offset 0x0951 - Assertion Deglitch Mantissa + Assertion Deglitch Mantissa, Range is 0-255 +**/ + UINT8 VsysAssertionDeglitchMantissa; + +/** Offset 0x0952 - Assertion Deglitch Exponent + Assertion Deglitch Exponent, Range is 0-255 +**/ + UINT8 VsysAssertionDeglitchExponent; + +/** Offset 0x0953 - De assertion Deglitch Mantissa + De assertion Deglitch Mantissa, Range is 0-255 +**/ + UINT8 VsysDeassertionDeglitchMantissa; + +/** Offset 0x0954 - De assertion Deglitch Exponent + De assertion Deglitch Exponent, Range is 0-255 +**/ + UINT8 VsysDeassertionDeglitchExponent; + +/** Offset 0x0955 - Reserved +**/ + UINT8 Reserved32; /** Offset 0x0956 - VR Fast Vmode ICC Limit support Voltage Regulator Fast Vmode ICC Limit. A value of 400 = 100A. A value of 0 corresponds @@ -2499,7 +3640,44 @@ typedef struct { /** Offset 0x096E - Reserved **/ - UINT8 Reserved71[28]; + UINT8 Reserved33[2]; + +/** Offset 0x0970 - Vsys Full Scale + Vsys Full Scale, Range is 0-255000mV +**/ + UINT32 VsysFullScale; + +/** Offset 0x0974 - Vsys Critical Threshold + Vsys Critical Threshold, Range is 0-255000mV +**/ + UINT32 VsysCriticalThreshold; + +/** Offset 0x0978 - Psys Full Scale + Psys Full Scale, Range is 0-255000mV +**/ + UINT32 PsysFullScale; + +/** Offset 0x097C - Psys Critical Threshold + Psys Critical Threshold, Range is 0-255000mV +**/ + UINT32 PsysCriticalThreshold; + +/** Offset 0x0980 - Reserved +**/ + UINT8 Reserved34[8]; + +/** Offset 0x0988 - IOE Debug Enable + Enable/Disable IOE Debug. When enabled, IOE D2D Dfx link will keep up and clock + is enabled + $EN_DIS +**/ + UINT8 IoeDebugEn; + +/** Offset 0x0989 - Pmode Clock Enable + Enable/Disable PMODE clock. When enabled, Pmode clock will toggle for XDP use + $EN_DIS +**/ + UINT8 PmodeClkEn; /** Offset 0x098A - PCH Port80 Route Control where the Port 80h cycles are sent, 0: LPC; 1: PCI. @@ -2514,9 +3692,21 @@ typedef struct { **/ UINT8 GpioOverride; -/** Offset 0x098C - Reserved +/** Offset 0x098C - Pmc Privacy Consent + Enable/Disable Pmc Privacy Consent + $EN_DIS +**/ + UINT8 PmcPrivacyConsent; + +/** Offset 0x098D - DMI ME UMA Root Space Check + DMI IOSF Root Space attribute check for RS3 for cycles targeting MEUMA. + 0: POR, 1: enable, 2: disable +**/ + UINT8 PchTestDmiMeUmaRootSpaceCheck; + +/** Offset 0x098E - Reserved **/ - UINT8 Reserved72[4]; + UINT8 Reserved35[2]; /** Offset 0x0990 - PMR Size Size of PMR memory buffer. 0x400000 for normal boot and 0x200000 for S3 boot @@ -2540,9 +3730,11 @@ typedef struct { **/ UINT8 VtdDisable; -/** Offset 0x0997 - Reserved +/** Offset 0x0997 - State of Vtd Capabilities + 0x0=(No operation), BIT0 = 1 (Defeature Nested Support), BIT1 = 1 (Defeature Posted + Interrupt Support) **/ - UINT8 Reserved73; + UINT8 VtdCapabilityControl; /** Offset 0x0998 - Base addresses for VT-d function MMIO access Base addresses for VT-d MMIO access per VT-d engine @@ -2551,7 +3743,17 @@ typedef struct { /** Offset 0x09BC - Reserved **/ - UINT8 Reserved74[20]; + UINT8 Reserved36[4]; + +/** Offset 0x09C0 - MMIO Size + Size of MMIO space reserved for devices. 0(Default)=Auto, non-Zero=size in MB +**/ + UINT64 MchBar; + +/** Offset 0x09C8 - MMIO Size + Size of MMIO space reserved for devices. 0(Default)=Auto, non-Zero=size in MB +**/ + UINT64 RegBar; /** Offset 0x09D0 - MMIO Size Size of MMIO space reserved for devices. 0(Default)=Auto, non-Zero=size in MB @@ -2564,9 +3766,50 @@ typedef struct { **/ UINT16 MmioSizeAdjustment; -/** Offset 0x09D4 - Reserved +/** Offset 0x09D4 - Temporary address for ApicLocalAddress + The reference code will use this as Temporary address space +**/ + UINT32 ApicLocalAddress; + +/** Offset 0x09D8 - Temporary address for NvmeHcPeiMmioBase + The reference code will use this as Temporary address space +**/ + UINT32 NvmeHcPeiMmioBase; + +/** Offset 0x09DC - Temporary address for NvmeHcPeiMmioLimit + The reference code will use this as Temporary address space +**/ + UINT32 NvmeHcPeiMmioLimit; + +/** Offset 0x09E0 - Temporary address for AhciPeiMmioBase + The reference code will use this as Temporary address space +**/ + UINT32 AhciPeiMmioBase; + +/** Offset 0x09E4 - Temporary address for AhciPeiMmioLimit + The reference code will use this as Temporary address space +**/ + UINT32 AhciPeiMmioLimit; + +/** Offset 0x09E8 - Temporary address for EcExtraIoBase + The reference code will use this as Temporary address space +**/ + UINT16 EcExtraIoBase; + +/** Offset 0x09EA - Temporary address for SioBaseAddress + The reference code will use this as Temporary address space +**/ + UINT16 SioBaseAddress; + +/** Offset 0x09EC - Temporary CfgBar address for VMD + The reference code will use this as Temporary address space +**/ + UINT32 VmdCfgBarBar; + +/** Offset 0x09F0 - System Agent SafBar + Address of System Agent SafBar **/ - UINT8 Reserved75[36]; + UINT64 SafBar; /** Offset 0x09F8 - Enable above 4GB MMIO resource support Enable/disable above 4GB MMIO resource support @@ -2582,7 +3825,20 @@ typedef struct { /** Offset 0x09FA - Reserved **/ - UINT8 Reserved76[10]; + UINT8 Reserved37[2]; + +/** Offset 0x09FC - StreamTracer Mode + Disable: Disable StreamTracer, Advanced Tracing: StreamTracer size 512MB - Recommended + when all groups in high verbosity are traced in 'red', Auto: StreamTracer size + 8MB - Recommended when using up to 8 groups red or up to 16 groups in green in + med verbosity, User input: Allow User to enter a size in the range of 64KB-512MB + 0: Disable (Default), 524288: Advanced Tracing , 8192: Auto , 3: User input +**/ + UINT32 StreamTracerMode; + +/** Offset 0x0A00 +**/ + UINT32 StreamTracerSize; /** Offset 0x0A04 - Enable/Disable CrashLog Device Enable or Disable CrashLog/Telemetry Device 0- Disable, 1- Enable @@ -2590,9 +3846,39 @@ typedef struct { **/ UINT32 CpuCrashLogDevice; -/** Offset 0x0A08 - Reserved +/** Offset 0x0A08 - StreamTracer physical address + StreamTracer physical address +**/ + UINT64 StreamTracerBase; + +/** Offset 0x0A10 - Temporary MemBar1 address for VMD + StreamTracer physical address +**/ + UINT32 VmdMemBar1Bar; + +/** Offset 0x0A14 - Temporary MemBar2 address for VMD + StreamTracer physical address +**/ + UINT32 VmdMemBar2Bar; + +/** Offset 0x0A18 - Skip override boot mode When Fw Update. + When set to TRUE and boot mode is BOOT_ON_FLASH_UPDATE, skip setting boot mode to + BOOT_WITH_FULL_CONFIGURATION in PEI memory init. + $EN_DIS +**/ + UINT8 SiSkipOverrideBootModeWhenFwUpdate; + +/** Offset 0x0A19 - Reserved +**/ + UINT8 Reserved38; + +/** Offset 0x0A1A - Static Content at 4GB Location + 0 (Default): No Allocation, 0x20:32MB, 0x40:64MB, 0x80:128MB, 0x100:256MB, 0x200:512MB, + 0x400:1GB, 0x800:2GB, 0xC00:3GB, 0x1000:4GB, 0x2000:8GB + 0: No Allocation, 0x20:32MB, 0x40:64MB, 0x80:128MB, 0x100:256MB, 0x200:512MB, 0x400:1GB, + 0x800:2GB, 0xC00:3GB, 0x1000:4GB, 0x2000:8GB **/ - UINT8 Reserved77[20]; + UINT16 StaticContentSizeAt4Gb; /** Offset 0x0A1C - Platform Debug Option Enabled Trace active: TraceHub is enabled and trace is active, blocks s0ix.\n @@ -2607,9 +3893,14 @@ typedef struct { **/ UINT8 PlatformDebugOption; -/** Offset 0x0A1D - Reserved +/** Offset 0x0A1D - TXT CMOS Offset + CMOS Offset for TXT policy data. Default 0x2A +**/ + UINT8 CmosTxtOffset; + +/** Offset 0x0A1E - Reserved **/ - UINT8 Reserved78[14]; + UINT8 Reserved39[13]; /** Offset 0x0A2B - Program GPIOs for LFP on DDI port-A device 0=Disabled,1(Default)=eDP, 2=MIPI DSI @@ -2617,9 +3908,10 @@ typedef struct { **/ UINT8 DdiPortAConfig; -/** Offset 0x0A2C - Reserved +/** Offset 0x0A2C - HgSubSystemId + Hybrid Graphics SubSystemId **/ - UINT8 Reserved79[2]; + UINT16 HgSubSystemId; /** Offset 0x0A2E - Program GPIOs for LFP on DDI port-B device 0(Default)=Disabled,1=eDP, 2=MIPI DSI @@ -2711,9 +4003,15 @@ typedef struct { **/ UINT8 DdiPort4Ddc; -/** Offset 0x0A3D - Reserved +/** Offset 0x0A3D - Oem T12 Dealy Override + Oem T12 Dealy Override. 0(Default)=Disable 1=Enable + $EN_DIS +**/ + UINT8 OemT12DelayOverride; + +/** Offset 0x0A3E - Reserved **/ - UINT8 Reserved80[3]; + UINT8 Reserved40[2]; /** Offset 0x0A40 - Temporary MMIO address for GMADR The reference code will use this as Temporary MMIO address space to access GMADR @@ -2730,9 +4028,12 @@ typedef struct { **/ UINT64 GttMmAdr; -/** Offset 0x0A50 - Reserved +/** Offset 0x0A50 - Delta T12 Power Cycle Delay required in ms + Select the value for delay required. 0= No delay, 0xFFFF(Default) = Auto calculate + T12 Delay to max 500ms + 0 : No Delay, 0xFFFF : Auto Calulate T12 Delay **/ - UINT8 Reserved81[2]; + UINT16 DeltaT12PowerCycleDelay; /** Offset 0x0A52 - Enable/Disable Memory Bandwidth Compression 0=Disable, 1(Default)=Enable @@ -2762,7 +4063,7 @@ typedef struct { /** Offset 0x0A56 - Reserved **/ - UINT8 Reserved82[2]; + UINT8 Reserved41[2]; /** Offset 0x0A58 - Intel Graphics VBT (Video BIOS Table) Size Size of Internal Graphics VBT Image @@ -2771,7 +4072,7 @@ typedef struct { /** Offset 0x0A5C - Reserved **/ - UINT8 Reserved83[4]; + UINT8 Reserved42[4]; /** Offset 0x0A60 - Graphics Configuration Ptr Points to VBT @@ -2793,7 +4094,8 @@ typedef struct { Initialise SOL Init, BIT0 - (0 : Disable VGA Support, 1 : Enable VGA Support),, BIT1 - (0 : VGA Text Mode 3, 1 : VGA Graphics Mode 12), BIT2 - (0 : VGA Exit Supported, 1: NO VGA Exit), BIT3 - (0 : VGA Init During Display Init, 1 - VGA Init During - MRC Cold Boot), BIT4 - (0 : Enable Progress Bar, 1 : Disable Progress Bar) + MRC Cold Boot), BIT4 - (0 : Enable Progress Bar, 1 : Disable Progress Bar), BIT5 + - (0 : VGA Mode 12 16 Color Support, 1 : VGA Mode 12 Monochrome Black and White Support) 0:VGA Disable, 1:Mode 3 VGA, 2:Mode 12 VGA **/ UINT8 VgaInitControl; @@ -2830,9 +4132,11 @@ typedef struct { **/ UINT8 TcssXhciEn; -/** Offset 0x0A83 - Reserved +/** Offset 0x0A83 - IomUsbCDpConfig + Set IomUsbCDpConfig expect 4 values from 0 to 3 + 0:Disabled, 1:IOM_DP, 2:IOM_HDMI, 3: IOM_EDP **/ - UINT8 Reserved84[4]; + UINT8 IomUsbCDpConfig[4]; /** Offset 0x0A87 - TCSS Type C Port 0 Set TCSS Type C Port 0 Type, Options are 0=DISABLE, 1=DP_ONLY, 2=NO_TBT, 3=NO_PCIE, @@ -2862,9 +4166,11 @@ typedef struct { **/ UINT8 TcssPort3; -/** Offset 0x0A8B - Reserved +/** Offset 0x0A8B - TCSS Platform Configuration + Set TCSS Platform Configuration - Retimer Map, TCP0 - Bits[1:0], TCP1 - Bits[3:2], + TCP2 - Bits[5:4], TCP3 - Bits[7:6]; 0=Retimerless, 1=Retimer **/ - UINT8 Reserved85; + UINT8 TcssPlatConf; /** Offset 0x0A8C - TypeC port GPIO setting GPIO Pin number for Type C Aux orientation setting, use the GpioPad that is defined @@ -2930,9 +4236,11 @@ typedef struct { **/ UINT8 InternalGraphics; -/** Offset 0x0AC9 - Reserved +/** Offset 0x0AC9 - Asynchronous ODT + This option configures the Memory Controler Asynchronous ODT control + 0:Enabled, 1:Disabled **/ - UINT8 Reserved86; + UINT8 AsyncOdtDis; /** Offset 0x0ACA - DLL Weak Lock Support Enables/Disable DLL Weak Lock Support @@ -2942,7 +4250,7 @@ typedef struct { /** Offset 0x0ACB - Reserved **/ - UINT8 Reserved87; + UINT8 Reserved43; /** Offset 0x0ACC - Rx DQS Delay Comp Support Enables/Disable Rx DQS Delay Comp Support @@ -2952,7 +4260,7 @@ typedef struct { /** Offset 0x0ACD - Reserved **/ - UINT8 Reserved88[2]; + UINT8 Reserved44[2]; /** Offset 0x0ACF - Mrc Failure On Unsupported Dimm Enables/Disable Mrc Failure On Unsupported Dimm @@ -2960,9 +4268,11 @@ typedef struct { **/ UINT8 MrcFailureOnUnsupportedDimm; -/** Offset 0x0AD0 - Reserved +/** Offset 0x0AD0 - Fore Single Rank config + Enables/Disable Fore Single Rank config + $EN_DIS **/ - UINT8 Reserved89[4]; + UINT32 ForceSingleRank; /** Offset 0x0AD4 - DynamicMemoryBoost Enable/Disable Dynamic Memory Boost Feature. Only valid if SpdProfileSelected is @@ -2978,9 +4288,55 @@ typedef struct { **/ UINT32 RealtimeMemoryFrequency; -/** Offset 0x0ADC - Reserved +/** Offset 0x0ADC - SelfRefresh IdleTimer + SelfRefresh IdleTimer, Default is 256 +**/ + UINT16 SrefCfgIdleTmr; + +/** Offset 0x0ADE - MC Register Offset + Apply user offsets to select MC registers(Def=Disable) + $EN_DIS +**/ + UINT8 MCREGOFFSET; + +/** Offset 0x0ADF - CA Vref Ctl Offset + Offset to be applied to DDRDATA7CH1_CR_DDRCRVREFADJUST1.CAVref + 0xF4:-12,0xF5:-11, 0xF6:-10, 0xF7:-9, 0xF8:-8, 0xF9:-7, 0xFA:-6, 0xFB:-5, 0xFC:-4, + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3, 4:+4, 5:+5, 6:+6, 7:+7, 8:+8, + 9:+9, 10:+10, 11:+11, 12:+12 +**/ + UINT8 CAVrefCtlOffset; + +/** Offset 0x0AE0 - Clk PI Code Offset + Offset to be applied to DDRCLKCH0_CR_DDRCRCLKPICODE.PiSettingRank[0-3] + 0xFA:-6, 0xFB:-5, 0xFC:-4, 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3, 4:+4, + 5:+5, 6:+6 +**/ + UINT8 ClkPiCodeOffset; + +/** Offset 0x0AE1 - RcvEn Offset + Offset to be applied to DDRDATACH0_CR_DDRCRDATAOFFSETTRAIN.RcvEn + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3 +**/ + UINT8 RcvEnOffset; + +/** Offset 0x0AE2 - Rx Dqs Offset + Offset to be applied to DDRDATACHX_CR_DDRCRDATAOFFSETTRAIN.RxDqsOffset + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3 +**/ + UINT8 RxDqsOffset; + +/** Offset 0x0AE3 - Tx Dq Offset + Offset to be applied to DDRDATACH0_CR_DDRCRDATAOFFSETTRAIN.TxDqOffset + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3 **/ - UINT8 Reserved90[9]; + UINT8 TxDqOffset; + +/** Offset 0x0AE4 - Tx Dqs Offset + Offset to be applied to DDRDATACH0_CR_DDRCRDATAOFFSETTRAIN.TxDqsOffset + 0xFD:-3, 0xFE:-2, 0xFF:-1, 0:0, 1:+1, 2:+2, 3:+3 +**/ + UINT8 TxDqsOffset; /** Offset 0x0AE5 - Vref Offset Offset to be applied to DDRDATACH0_CR_DDRCRDATAOFFSETTRAIN.VrefOffset @@ -2989,9 +4345,15 @@ typedef struct { **/ UINT8 VrefOffset; -/** Offset 0x0AE6 - Reserved +/** Offset 0x0AE6 - Controller mask + Controller mask to apply on parameter offset +**/ + UINT8 CntrlrMask; + +/** Offset 0x0AE7 - Channel mask + Channel mask to apply on parameter offset **/ - UINT8 Reserved91[2]; + UINT8 ChMask; /** Offset 0x0AE8 - tRRSG Delta Delay between Read-to-Read commands in the same Bank Group. 0 - Auto. Signed TAT @@ -3105,9 +4467,158 @@ typedef struct { **/ UINT8 tRWDD; -/** Offset 0x0AF8 - Reserved +/** Offset 0x0AF8 - MRC Interpreter + Select CMOS location match of DD01 or Ctrl-Break key or force entry + 0:CMOS, 1:Break, 2:Force +**/ + UINT8 Interpreter; + +/** Offset 0x0AF9 - ODT mode + ODT mode + 0:Default, 1:Vtt, 2:Vddq, 3:Vss, 4:Max +**/ + UINT8 IoOdtMode; + +/** Offset 0x0AFA - PerBankRefresh + Control of Per Bank Refresh feature for LPDDR DRAMs + $EN_DIS +**/ + UINT8 PerBankRefresh; + +/** Offset 0x0AFB - Mimic WC display pattern in IPQ + Using for Disable/Enable Mimic WC display pattern in IPQ: 0:Disable, 1:Enable 1 + ACT resources usage, 3:Enable 2 ACT resources usage, 3:Enable 3 ACT resources usage,0xf: + Enable 4 ACT resources usage + 1:1, 3:3, 0xf:0xf, 0:Auto +**/ + UINT8 MimicWcDisaplayInIpq; + +/** Offset 0x0AFC - Fake SAGV + Fake SAGV: 0:Disabled, 1:Enabled + $EN_DIS +**/ + UINT32 FakeSagv; + +/** Offset 0x0B00 - Lock DPR register + Lock DPR register. 0: Platform POR ; 1: Enable; 2: Disable + 0:Platform POR, 1: Enable, 2: Disable +**/ + UINT32 DprLock; + +/** Offset 0x0B04 - Board Stack Up + Board Stack Up: 0=Typical, 1=Freq Limited + 0:Typical, 1:Freq Limited +**/ + UINT8 BoardStackUp; + +/** Offset 0x0B05 - PPR ForceRepair + When Eanble, PPR will force repair some rows many times (90) + $EN_DIS +**/ + UINT8 PprForceRepair; + +/** Offset 0x0B06 - PPR Repair Bank + Deprecated **/ - UINT8 Reserved92[41]; + UINT8 PprRepairBank; + +/** Offset 0x0B07 - Board Topology + Board Topology: 0=Daisy Chain, 1=Tee. + 0:Daisy Chain, 1:Tee +**/ + UINT8 BoardTopology; + +/** Offset 0x0B08 - SubCh Hash Interleaved Bit + Select the MC Enhanced Channel interleave bit, to set different address bit for + sub channel selection than bit-6 + 0:BIT6, 1:BIT7, 2:BIT8, 3:BIT9, 4:BIT10, 5:BIT11, 6:BIT12, 7:BIT13 +**/ + UINT8 SubChHashInterleaveBit; + +/** Offset 0x0B09 - Reserved +**/ + UINT8 Reserved45; + +/** Offset 0x0B0A - SubCh Hash Mask + Set the BIT(s) to be included in the XOR function. NOTE BIT mask corresponds to + BITS [19:6] Default is 0x834 +**/ + UINT16 SubChHashMask; + +/** Offset 0x0B0C - Force CKD in Bypass Mode + Enable/Disable Force CKD in Bypass Mode + $EN_DIS +**/ + UINT8 ForceCkdBypass; + +/** Offset 0x0B0D - Reserved +**/ + UINT8 Reserved46[3]; + +/** Offset 0x0B10 - Disable Zq + Enable/Disable Zq Calibration: 0:Enabled, 1:Disabled + $EN_DIS +**/ + UINT32 DisableZq; + +/** Offset 0x0B14 - Replicate SAGV + Replicate SAGV: 0:Disabled, 1:Enabled + $EN_DIS +**/ + UINT32 ReplicateSagv; + +/** Offset 0x0B18 - Adjust wck mode + Adjust wck mode: 0:safe mode, 1:manual mode, 2:dynamic mode, 3:Default + 0:safe mode, 1:manual mode, 2:dynamic mode, 3:Default +**/ + UINT8 AdjustWckMode; + +/** Offset 0x0B19 - Control MC/PMA telemetry + Control MC/PMA telemetry: 0: Default, 1: Enable, 2: Disable + 0: Default, 1: Enable, 2: Disable +**/ + UINT8 TelemetryControl; + +/** Offset 0x0B1A - PHclk\Qclk SPINE gating Control + PHclk\Qclk SPINE gating Control: 0:Disabled, 1:Enabled + $EN_DIS +**/ + UINT8 SpineAndPhclkGateControl; + +/** Offset 0x0B1B - SpineGating per lpmode + SpineGatePerLpmode[0]:Lpmode0.5, SpineGatePerLpmode[1]:Lpmode2, SpineGatePerLpmode[2]:Lpmode3, + SpineGatePerLpmode[3]:Lpmode4 +**/ + UINT8 SpineGatePerLpmode; + +/** Offset 0x0B1C - PhClkGating control per lpmode + PhclkGatePerLpmode[0]:Lpmode0.5, PhclkGatePerLpmode[1]:Lpmode1, PhclkGatePerLpmode[2]:Lpmode2, + PhclkGatePerLpmode[3]:Lpmode3, PhclkGatePerLpmode[4]:Lpmode4 +**/ + UINT8 PhclkGatePerLpmode; + +/** Offset 0x0B1D - DFI Control after cold boot + Disable Switch DFI Control to MC after cold boot: 0(Default)=switch DFI to MC, 1=Keep + with PHY/MPTU + $EN_DIS +**/ + UINT8 DisableSwitchDfiToMc; + +/** Offset 0x0B1E - Enable/Disable SmbusPostcode + Disable (Default): Postcode via Port80, Enable: Postcode via Smbus + $EN_DIS +**/ + UINT8 SmbusPostCodeEnable; + +/** Offset 0x0B1F - SmbusPostcode Address + Slave address for Smbus postcode device +**/ + UINT8 SmbusPostCodeAddress; + +/** Offset 0x0B20 - SmbusPostcode Command + Command value for Smbus postcode device +**/ + UINT8 SmbusPostCodeCommand; /** Offset 0x0B21 - Channel to CKD QCK Mapping Specify Channel to CKD QCK Mapping for CH0D0/CH0D1/CH1D0&CH1D1 @@ -3119,9 +4630,16 @@ typedef struct { **/ UINT8 PhyClockToCkdDimm[8]; -/** Offset 0x0B31 - Reserved +/** Offset 0x0B31 - CKD Address Table + Specify CKD Address table for all DIMMs +**/ + UINT8 CkdAddressTable[16]; + +/** Offset 0x0B41 - Single VDD2 Rail + LP5x VDD2 rail: 0: Dual rail (E-DVFSC is possible), 1: Single rail(No E-DVFSC; VDD2L == VDD2H) + $EN_DIS **/ - UINT8 Reserved93[17]; + UINT8 SingleVdd2Rail; /** Offset 0x0B42 - VDD2 Voltage Voltage is multiple of 5mV where 0 means Auto. @@ -3145,7 +4663,7 @@ typedef struct { /** Offset 0x0B4A - Reserved **/ - UINT8 Reserved94[30]; + UINT8 Reserved47[30]; } FSP_M_CONFIG; /** Fsp M UPD Configuration diff --git a/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspsUpd.h b/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspsUpd.h index ae0ffe29dda..051aa8c2ded 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspsUpd.h +++ b/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/FspsUpd.h @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2025, Intel Corporation. All rights reserved.
+Copyright (c) 2026, Intel Corporation. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -104,9 +104,24 @@ typedef struct { **/ UINT64 BiosGuardModulePtr; -/** Offset 0x0080 - Reserved +/** Offset 0x0080 - EcProvisionEav + EcProvisionEav function pointer. \n + @code typedef EFI_STATUS (EFIAPI *EC_PROVISION_EAV) (IN UINT32 Eav, OUT UINT8 + *ReturnValue); @endcode **/ - UINT8 Reserved1[17]; + UINT64 EcProvisionEav; + +/** Offset 0x0088 - EcBiosGuardCmdLock + EcBiosGuardCmdLock function pointer. \n + @code typedef EFI_STATUS (EFIAPI *EC_CMD_LOCK) (OUT UINT8 *ReturnValue); @endcode +**/ + UINT64 EcBiosGuardCmdLock; + +/** Offset 0x0090 - PCH eSPI Host and Device BME enabled + PCH eSPI Host and Device BME enabled + $EN_DIS +**/ + UINT8 PchEspiBmeHostDeviceEnabled; /** Offset 0x0091 - PCH eSPI Link Configuration Lock (SBLCL) Enable/Disable lock of communication through SET_CONFIG/GET_CONFIG to eSPI target @@ -127,9 +142,27 @@ typedef struct { **/ UINT8 PchEspiLgmrEnable; -/** Offset 0x0094 - Reserved +/** Offset 0x0094 - PCH eSPI PmHAE + This option enables or disables espi lgmr + $EN_DIS +**/ + UINT8 PchEspiPmHAE; + +/** Offset 0x0095 - PCH eSPI HideNonFatalErrors + This option enables or disables espi lgmr + $EN_DIS +**/ + UINT8 PchEspiHideNonFatalErrors; + +/** Offset 0x0096 - PCH eSPI NmiEnableCs1 + Set this bit to enable eSPI NMI VW events to be processed by the SOC + $EN_DIS +**/ + UINT8 PchEspiNmiEnableCs1; + +/** Offset 0x0097 - Reserved **/ - UINT8 Reserved2[4]; + UINT8 Reserved1; /** Offset 0x0098 - CpuBistData Pointer CPU BIST Data @@ -151,7 +184,16 @@ typedef struct { /** Offset 0x00A9 - Reserved **/ - UINT8 Reserved3[7]; + UINT8 Reserved2[3]; + +/** Offset 0x00AC - StreamTracer Mode + Disable: Disable StreamTracer, Advanced Tracing: StreamTracer size 512MB - Recommended + when all groups in high verbosity are traced in 'red', Auto: StreamTracer size + 8MB - Recommended when using up to 8 groups red or up to 16 groups in green in + med verbosity, User input: Allow User to enter a size in the range of 64KB-512MB + 0: Disable (Default), 524288: Advanced Tracing , 8192: Auto , 3: User input +**/ + UINT32 StreamTracerMode; /** Offset 0x00B0 - MicrocodeRegionBase Memory Base of Microcode Updates @@ -192,9 +234,12 @@ typedef struct { **/ UINT8 AvxDisable; -/** Offset 0x00C4 - Reserved +/** Offset 0x00C4 - X2ApicEnable + Enable/Disable X2APIC Operating Mode. When this option is configured as 'Enabled', + 'VT-d' option must be 'Enabled'. + $EN_DIS **/ - UINT8 Reserved4; + UINT8 X2ApicEnable; /** Offset 0x00C5 - P-state ratios for max 16 version of custom P-state table P-state ratios for max 16 version of custom P-state table. This table is used for @@ -287,9 +332,17 @@ typedef struct { **/ UINT8 PkgCStateLimit; -/** Offset 0x00E1 - Reserved +/** Offset 0x00E1 - ForcePr Demotion Algorithm configuration + ForcePr Demotion Algorithm configuration. 0: Disable; 1: Enable + 0: Disable, 1: Enable +**/ + UINT8 ForcePrDemotion; + +/** Offset 0x00E2 - VrAlert Demotion Algorithm configuration + VrAlert Demotion Algorithm configuration. 0: Disable; 1: Enable + 0: Disable, 1: Enable **/ - UINT8 Reserved5[2]; + UINT8 VrAlertDemotion; /** Offset 0x00E3 - Interrupt Redirection Mode Select Interrupt Redirection Mode Select for Logical Interrupts. 0: Fixed priority; 1: @@ -303,9 +356,12 @@ typedef struct { **/ UINT8 TurboMode; -/** Offset 0x00E5 - Reserved +/** Offset 0x00E5 - Power Floor PCIe Gen Downgrade + SoC can downgrade PCIe gen speed to lower SoC floor power (Default enabled). 0: + Disable: Reduction in PCIe gen speed will not be used by SoC., 1: Enable + $EN_DIS **/ - UINT8 Reserved6; + UINT8 PowerFloorPcieGenDowngrade; /** Offset 0x00E6 - P-state ratios for custom P-state table P-state ratios for custom P-state table. NumberOfEntries has valid range between @@ -325,9 +381,12 @@ typedef struct { **/ UINT8 MaxRatio; -/** Offset 0x0110 - Reserved +/** Offset 0x0110 - Boot frequency + Select the performance state that the BIOS will set starting from reset vector. + 0: Maximum battery performance. 1: Maximum non-turbo performance. 2: Turbo performance + 0:0, 1:1, 2:2 **/ - UINT8 Reserved7; + UINT8 BootFrequency; /** Offset 0x0111 - Turbo settings Lock Enable/Disable locking of Package Power Limit settings. When enabled, PACKAGE_POWER_LIMIT @@ -337,9 +396,41 @@ typedef struct { **/ UINT8 TurboPowerLimitLock; -/** Offset 0x0112 - Reserved +/** Offset 0x0112 - FastMsrHwpReq + 0: Disable; 1: Enable; + $EN_DIS +**/ + UINT8 EnableFastMsrHwpReq; + +/** Offset 0x0113 - Turbo Ratio Limit Ratio array + Performance-core Turbo Ratio Limit Ratio0-7 (TRLR) defines the turbo ratio (max + is 85 in normal mode and 120 in core extension mode). Ratio[0]: This Turbo Ratio + Limit Ratio0 must be greater than or equal all other ratio values. If this value + is invalid, thn set all other active cores to minimum. Otherwise, align the Ratio + Limit to 0. Please check each active cores. Ratio[1~7]: This Turbo Ratio Limit + Ratio1 must be <= to Turbo Ratio Limit Ratio0~6. +**/ + UINT8 TurboRatioLimitRatio[8]; + +/** Offset 0x011B - Turbo Ratio Limit Num Core array + Performance-core Turbo Ratio Limit Core0~7 defines the core range, the turbo ratio + is defined in Turbo Ratio Limit Ratio0~7. If value is zero, this entry is ignored. +**/ + UINT8 TurboRatioLimitNumCore[8]; + +/** Offset 0x0123 - ATOM Turbo Ratio Limit Ratio array + Efficient-core Turbo Ratio Limit Ratio0-7 defines the turbo ratio (max is 85 irrespective + of the core extension mode), the core range is defined in E-core Turbo Ratio Limit + CoreCount0-7. +**/ + UINT8 AtomTurboRatioLimitRatio[8]; + +/** Offset 0x012B - ATOM Turbo Ratio Limit Num Core array + Efficient-core Turbo Ratio Limit CoreCount0-7 defines the core range, the turbo + ratio is defined in E-core Turbo Ratio Limit Ratio0-7. If value is zero, this entry + is ignored. **/ - UINT8 Reserved8[33]; + UINT8 AtomTurboRatioLimitNumCore[8]; /** Offset 0x0133 - Race To Halt Enable/Disable Race To Halt feature. RTH will dynamically increase CPU frequency @@ -373,9 +464,11 @@ typedef struct { **/ UINT8 MaxRingRatioLimit; -/** Offset 0x0138 - Reserved +/** Offset 0x0138 - Resource Priority Feature + Enable/Disable Resource Priority Feature. Enable/Disable; 0: Disable, 1: Enable + $EN_DIS **/ - UINT8 Reserved9; + UINT8 EnableRp; /** Offset 0x0139 - Enable or Disable HWP Enable/Disable Intel(R) Speed Shift Technology support. Enabling will expose the @@ -406,9 +499,42 @@ typedef struct { **/ UINT8 EnableHwpAutoEppGrouping; -/** Offset 0x013D - Reserved +/** Offset 0x013D - Dynamic Efficiency Control + Enable or Disable SoC to control energy efficiency targets autonomously, regardless + of EPP, EPB and other SW inputs. 0: Disable;
1: Enable + $EN_DIS +**/ + UINT8 EnableDynamicEfficiencyControl; + +/** Offset 0x013E - Misc Power Management MSR Lock + Enable/Disable HWP Lock support in Misc Power Management MSR. 0: Disable, 1: + Enable + $EN_DIS +**/ + UINT8 HwpLock; + +/** Offset 0x013F - Power Floor Managment for SOC + Option to disable Power Floor Managment for SOC. Disabling this might effectively + raise power floor of the SoC and may lead to stability issues. 0: Disable, 1: + Enable + $EN_DIS +**/ + UINT8 PowerFloorManagement; + +/** Offset 0x0140 - Power Floor Disaplay Disconnect + SoC can disconnect secondary/external display to lower SoC floor power (Default + disabled). 0: Disable: Display disconnect will not be used by SoC., 1: Enable + $EN_DIS +**/ + UINT8 PowerFloorDisplayDisconnect; + +/** Offset 0x0141 - Memory size per thread allocated for Processor Trace + Memory size per thread for Processor Trace. Processor Trace requires 2^N alignment + and size in bytes per thread, from 4KB to 128MB.\n + 0xff:none , 0:4k, 0x1:8k, 0x2:16k, 0x3:32k, 0x4:64k, 0x5:128k, 0x6:256k, + 0x7:512k, 0x8:1M, 0x9:2M, 0xa:4M. 0xb:8M, 0xc:16M, 0xd:32M, 0xe:64M, 0xf:128M **/ - UINT8 Reserved10[5]; + UINT8 ProcessorTraceMemSize; /** Offset 0x0142 - Enable or Disable MLC Streamer Prefetcher Enable or Disable MLC Streamer Prefetcher; 0: Disable; 1: Enable. @@ -447,9 +573,25 @@ typedef struct { **/ UINT8 ProcessorTraceEnable; -/** Offset 0x0148 - Reserved +/** Offset 0x0148 - Processor trace enabled for Bsp only or all cores + Processor trace enabled for Bsp only or all cores; 0: all cores; 1: Bsp only. + 0: all cores, 1: Bsp only +**/ + UINT8 ProcessorTraceBspOnly; + +/** Offset 0x0149 - Enable/Disable processor trace Timing Packet + Enable/Disable collocting processor trace performance (CYC, TSC); 0: Disable; + 1: Enable. + $EN_DIS +**/ + UINT8 ProcessorTraceTimingPacket; + +/** Offset 0x014A - Enable or Disable Three Strike Counter + Enable (default): Three Strike counter will be incremented. Disable: Prevents Three + Strike counter from incrementing; 0: Disable; 1: Enable + $EN_DIS **/ - UINT8 Reserved11[3]; + UINT8 ThreeStrikeCounter; /** Offset 0x014B - UFS enable/disable Enable/Disable UFS controller, One byte for each Controller - (1,0) to enable controller @@ -466,9 +608,12 @@ typedef struct { **/ UINT8 UfsInlineEncryption[2]; -/** Offset 0x014F - Reserved +/** Offset 0x014F - UFS Connection Status + UFS Connection Status, One byte for each Controller - (1,0) to UFS connected to + controller 0 and (0,1) to UFS connected to controller 1 + $EN_DIS **/ - UINT8 Reserved12[2]; + UINT8 UfsDeviceConnected[2]; /** Offset 0x0151 - Enable/Disable PCIe tunneling for USB4 Enable/Disable PCIe tunneling for USB4, default is enable @@ -478,7 +623,7 @@ typedef struct { /** Offset 0x0152 - Reserved **/ - UINT8 Reserved13[2]; + UINT8 Reserved3[2]; /** Offset 0x0154 - ITBTForcePowerOn Timeout value ITBTForcePowerOn value. Specified increment values in miliseconds. Range is 0-1000. @@ -504,7 +649,12 @@ typedef struct { /** Offset 0x015D - Reserved **/ - UINT8 Reserved14[19]; + UINT8 Reserved4[11]; + +/** Offset 0x0168 - FSPS Validation + Point to FSPS Validation configuration structure +**/ + UINT64 FspsValidationPtr; /** Offset 0x0170 - IEH Mode Integrated Error Handler Mode, 0: Bypass, 1: Enable @@ -563,7 +713,7 @@ typedef struct { /** Offset 0x017B - Reserved **/ - UINT8 Reserved15; + UINT8 Reserved5; /** Offset 0x017C - ISH GP GPIO Pin Muxing Determines ISH GP GPIO Pin muxing. See GPIO_*_MUXING_ISH_GP_x_GPIO_*. 'x' are GP_NUMBER @@ -746,9 +896,11 @@ typedef struct { **/ UINT8 PchIshPdtUnlock; -/** Offset 0x025C - Reserved +/** Offset 0x025C - PCH ISH MSI Interrupts + 0: False; 1: True. + $EN_DIS **/ - UINT8 Reserved16; + UINT8 PchIshMsiInterrupt; /** Offset 0x025D - End of Post message Test, Send End of Post message. Disable(0x0): Disable EOP message, Send in PEI(0x1): @@ -778,9 +930,44 @@ typedef struct { **/ UINT8 MeUnconfigOnRtcClear; -/** Offset 0x0261 - Reserved +/** Offset 0x0261 - CSE Data Resilience Support + 0: Disable CSE Data Resilience Support. 1: Enable CSE Data Resilience Support. + 2: Enable CSE Data Resilience but defer to DXE. + $EN_DIS +**/ + UINT8 CseDataResilience; + +/** Offset 0x0262 - PSE EOM Flow Control + 0: Disable PSE EOM Flow. 1: Enable PSE EOM Flow. + $EN_DIS +**/ + UINT8 PseEomFlowEnable; + +/** Offset 0x0263 - ISH I3C SDA Pin Muxing + Select ISH I3C SDA Pin muxing. Refer to GPIO_*_MUXING_ISH_I3Cx_SDA_* for possible values. **/ - UINT8 Reserved17[22]; + UINT8 IshI3cSdaPinMuxing[8]; + +/** Offset 0x026B - ISH I3C SCL Pin Muxing + Select ISH I3C SCL Pin muxing. Refer to GPIO_*_MUXING_ISH_I3Cx_SCL_* for possible values. +**/ + UINT8 IshI3cSclPinMuxing[8]; + +/** Offset 0x0273 - ISH I3C SDA Pad termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C#N Sda pads termination + respectively. #N-byte for each controller, byte0 for I2C0 Sda, byte1 for I2C1 Sda, + and so on. +**/ + UINT8 IshI3cSdaPadTermination[2]; + +/** Offset 0x0275 - ISH I3C SCL Pad termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C#N Scl pads termination + respectively. #N-byte for each controller, byte0 for I2C0 Scl, byte1 for I2C1 Scl, + and so on. +**/ + UINT8 IshI3cSclPadTermination[2]; /** Offset 0x0277 - Enable PCH ISH I3C pins assigned Set if ISH I3C native pins are to be enabled by BIOS. 0: Disable; 1: Enable. @@ -789,7 +976,7 @@ typedef struct { /** Offset 0x0279 - Reserved **/ - UINT8 Reserved18[3]; + UINT8 Reserved6[3]; /** Offset 0x027C - Power button debounce configuration Debounce time for PWRBTN in microseconds. For values not supported by HW, they will @@ -972,9 +1159,11 @@ typedef struct { **/ UINT8 PmcLpmS0ixSubStateEnableMask; -/** Offset 0x029C - Reserved +/** Offset 0x029C - PCH PMC ER Debug mode + Disable/Enable Energy Reporting Debug Mode. + $EN_DIS **/ - UINT8 Reserved19; + UINT8 PchPmErDebugMode; /** Offset 0x029D - PMC C10 dynamic threshold dajustment enable Set if you want to enable PMC C10 dynamic threshold adjustment. Only works on supported SKUs @@ -1143,9 +1332,11 @@ typedef struct { **/ UINT8 PcieRpAspm[28]; -/** Offset 0x053C - Reserved +/** Offset 0x053C - HostL0sTxDis + Disable Host L0 transmission state + $EN_DIS **/ - UINT8 Reserved20[28]; + UINT8 HostL0sTxDis[28]; /** Offset 0x0558 - PCIE RP L1 Substates The L1 Substates configuration of the root port (see: PCH_PCIE_L1SUBSTATES_CONTROL). @@ -1169,321 +1360,1121 @@ typedef struct { **/ UINT8 PcieEqOverrideDefault[12]; -/** Offset 0x05B8 - Reserved +/** Offset 0x05B8 - PCIE RP choose EQ method + Choose PCIe EQ method + 0: HardwareEq, 1: FixedEq **/ - UINT8 Reserved21[1525]; + UINT8 PcieGen3EqMethod[12]; -/** Offset 0x0BAD - PCIE RP Enable Peer Memory Write - This member describes whether Peer Memory Writes are enabled on the platform. +/** Offset 0x05C4 - PCIE RP choose EQ mode + Choose PCIe EQ mode + 0: PresetEq, 1: CoefficientEq +**/ + UINT8 PcieGen3EqMode[12]; + +/** Offset 0x05D0 - PCIE RP EQ local transmitter override + Enable/Disable local transmitter override $EN_DIS **/ - UINT8 PcieEnablePeerMemoryWrite[12]; + UINT8 PcieGen3EqLocalTxOverrideEn[12]; -/** Offset 0x0BB9 - Assertion on Link Down GPIOs - GPIO Assertion on Link Down. Disabled(0x0)(Default): Disable assertion on Link Down - GPIOs, Enabled(0x1): Enable assertion on Link Down GPIOs - 0:Disable, 1:Enable +/** Offset 0x05DC - PCI RP number of valid list entries + Select number of presets or coefficients depending on the mode **/ - UINT8 PcieRpLinkDownGpios[12]; + UINT8 PcieGen3EqPh3NoOfPresetOrCoeff[12]; -/** Offset 0x0BC5 - PCIE Compliance Test Mode - Compliance Test Mode shall be enabled when using Compliance Load Board. - $EN_DIS +/** Offset 0x05E8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieComplianceTestMode; + UINT8 PcieGen3EqPh3PreCursor0List[12]; -/** Offset 0x0BC6 - PCIE Rp Function Swap - Allows BIOS to use root port function number swapping when root port of function - 0 is disabled. - $EN_DIS +/** Offset 0x05F4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpFunctionSwap; + UINT8 PcieGen3EqPh3PostCursor0List[12]; -/** Offset 0x0BC7 - Reserved +/** Offset 0x0600 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved22[12]; + UINT8 PcieGen3EqPh3PreCursor1List[12]; -/** Offset 0x0BD3 - PCIe RootPort Power Gating - Describes whether the PCI Express Power Gating for each root port is enabled by - platform modules. 0: Disable; 1: Enable(Default). - $EN_DIS +/** Offset 0x060C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PciePowerGating[12]; + UINT8 PcieGen3EqPh3PostCursor1List[12]; -/** Offset 0x0BDF - Reserved +/** Offset 0x0618 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved23[49]; + UINT8 PcieGen3EqPh3PreCursor2List[12]; -/** Offset 0x0C10 - PCIE RP Ltr Max Snoop Latency - Latency Tolerance Reporting, Max Snoop Latency. +/** Offset 0x0624 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpLtrMaxSnoopLatency[24]; + UINT8 PcieGen3EqPh3PostCursor2List[12]; -/** Offset 0x0C40 - PCIE RP Ltr Max No Snoop Latency - Latency Tolerance Reporting, Max Non-Snoop Latency. +/** Offset 0x0630 - PCIR RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpLtrMaxNoSnoopLatency[24]; + UINT8 PcieGen3EqPh3PreCursor3List[12]; -/** Offset 0x0C70 - PCIE RP Snoop Latency Override Mode - Latency Tolerance Reporting, Snoop Latency Override Mode. +/** Offset 0x063C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpSnoopLatencyOverrideMode[28]; + UINT8 PcieGen3EqPh3PostCursor3List[12]; -/** Offset 0x0C8C - PCIE RP Snoop Latency Override Multiplier - Latency Tolerance Reporting, Snoop Latency Override Multiplier. +/** Offset 0x0648 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpSnoopLatencyOverrideMultiplier[28]; + UINT8 PcieGen3EqPh3PreCursor4List[12]; -/** Offset 0x0CA8 - PCIE RP Snoop Latency Override Value - Latency Tolerance Reporting, Snoop Latency Override Value. +/** Offset 0x0654 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpSnoopLatencyOverrideValue[24]; + UINT8 PcieGen3EqPh3PostCursor4List[12]; -/** Offset 0x0CD8 - PCIE RP Non Snoop Latency Override Mode - Latency Tolerance Reporting, Non-Snoop Latency Override Mode. +/** Offset 0x0660 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpNonSnoopLatencyOverrideMode[28]; + UINT8 PcieGen3EqPh3PreCursor5List[12]; -/** Offset 0x0CF4 - PCIE RP Non Snoop Latency Override Multiplier - Latency Tolerance Reporting, Non-Snoop Latency Override Multiplier. +/** Offset 0x066C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpNonSnoopLatencyOverrideMultiplier[28]; + UINT8 PcieGen3EqPh3PostCursor5List[12]; -/** Offset 0x0D10 - PCIE RP Non Snoop Latency Override Value - Latency Tolerance Reporting, Non-Snoop Latency Override Value. +/** Offset 0x0678 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpNonSnoopLatencyOverrideValue[24]; + UINT8 PcieGen3EqPh3PreCursor6List[12]; -/** Offset 0x0D40 - PCIE RP Slot Power Limit Scale - Specifies scale used for slot power limit value. Leave as 0 to set to default. +/** Offset 0x0684 - PCIe post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieRpSlotPowerLimitScale[28]; + UINT8 PcieGen3EqPh3PostCursor6List[12]; -/** Offset 0x0D5C - PCIE RP Slot Power Limit Value - Specifies upper limit on power supplie by slot. Leave as 0 to set to default. +/** Offset 0x0690 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT16 PcieRpSlotPowerLimitValue[24]; + UINT8 PcieGen3EqPh3PreCursor7List[12]; -/** Offset 0x0D8C - PCIE RP Enable Port8xh Decode - This member describes whether PCIE root port Port 8xh Decode is enabled. 0: Disable; - 1: Enable. - $EN_DIS +/** Offset 0x069C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PcieEnablePort8xhDecode; + UINT8 PcieGen3EqPh3PostCursor7List[12]; -/** Offset 0x0D8D - PCIE Port8xh Decode Port Index - The Index of PCIe Port that is selected for Port8xh Decode (1 Based). +/** Offset 0x06A8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PchPciePort8xhDecodePortIndex; + UINT8 PcieGen3EqPh3PreCursor8List[12]; -/** Offset 0x0D8E - Reserved +/** Offset 0x06B4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved24[114]; + UINT8 PcieGen3EqPh3PostCursor8List[12]; -/** Offset 0x0E00 - SPIn Device Mode - Selects SPI operation mode. N represents controller index: SPI0, SPI1, ... Available - modes: 0:LpssSpiDisabled, 1:LpssSpiPci, 2:LpssSpiHidden +/** Offset 0x06C0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 SerialIoLpssSpiMode[7]; + UINT8 PcieGen3EqPh3PreCursor9List[12]; -/** Offset 0x0E07 - Reserved +/** Offset 0x06CC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved25[85]; + UINT8 PcieGen3EqPh3PostCursor9List[12]; -/** Offset 0x0E5C - SPIn Default Chip Select Mode HW/SW - Sets Default CS Mode Hardware or Software. N represents controller index: SPI0, - SPI1, ... Available options: 0:HW, 1:SW +/** Offset 0x06D8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoLpssSpiCsMode[7]; + UINT8 PcieGen3EqPh3Preset0List[12]; -/** Offset 0x0E63 - SPIn Default Chip Select State Low/High - Sets Default CS State Low or High. N represents controller index: SPI0, SPI1, ... - Available options: 0:Low, 1:High +/** Offset 0x06E4 - PCIe preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoLpssSpiCsState[7]; + UINT8 PcieGen3EqPh3Preset1List[12]; -/** Offset 0x0E6A - UARTn Device Mode - Selects Uart operation mode. N represents controller index: Uart0, Uart1, ... Available - modes: 0:SerialIoUartDisabled, 1:SerialIoUartPci, 2:SerialIoUartHidden, 3:SerialIoUartCom, - 4:SerialIoUartSkipInit +/** Offset 0x06F0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartMode[7]; + UINT8 PcieGen3EqPh3Preset2List[12]; -/** Offset 0x0E71 - Reserved +/** Offset 0x06FC - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 Reserved26[3]; + UINT8 PcieGen3EqPh3Preset3List[12]; -/** Offset 0x0E74 - Default BaudRate for each Serial IO UART - Set default BaudRate Supported from 0 - default to 6000000 +/** Offset 0x0708 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT32 SerialIoUartBaudRate[7]; + UINT8 PcieGen3EqPh3Preset4List[12]; -/** Offset 0x0E90 - Default ParityType for each Serial IO UART - Set default Parity. 0: DefaultParity, 1: NoParity, 2: EvenParity, 3: OddParity +/** Offset 0x0714 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartParity[7]; + UINT8 PcieGen3EqPh3Preset5List[12]; -/** Offset 0x0E97 - Default DataBits for each Serial IO UART - Set default word length. 0: Default, 5,6,7,8 +/** Offset 0x0720 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartDataBits[7]; + UINT8 PcieGen3EqPh3Preset6List[12]; -/** Offset 0x0E9E - Default StopBits for each Serial IO UART - Set default stop bits. 0: DefaultStopBits, 1: OneStopBit, 2: OneFiveStopBits, 3: - TwoStopBits +/** Offset 0x072C - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartStopBits[7]; + UINT8 PcieGen3EqPh3Preset7List[12]; -/** Offset 0x0EA5 - Power Gating mode for each Serial IO UART that works in COM mode - Set Power Gating. 0: Disabled, 1: Enabled, 2: Auto +/** Offset 0x0738 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartPowerGating[7]; + UINT8 PcieGen3EqPh3Preset8List[12]; -/** Offset 0x0EAC - Enable Dma for each Serial IO UART that supports it - Set DMA/PIO mode. 0: Disabled, 1: Enabled +/** Offset 0x0744 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartDmaEnable[7]; + UINT8 PcieGen3EqPh3Preset9List[12]; -/** Offset 0x0EB3 - Enables UART hardware flow control, CTS and RTS lines - Enables UART hardware flow control, CTS and RTS lines. +/** Offset 0x0750 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ **/ - UINT8 SerialIoUartAutoFlow[7]; + UINT8 PcieGen3EqPh3Preset10List[12]; -/** Offset 0x0EBA - Reserved +/** Offset 0x075C - PCIe EQ phase 1 downstream transmitter port preset + Allows to select the downstream port preset value that will be used during phase + 1 of equalization **/ - UINT8 Reserved27[2]; + UINT8 PcieGen3EqPh1DpTxPreset[12]; -/** Offset 0x0EBC - SerialIoUartRtsPinMuxPolicy - Select SerialIo Uart Rts pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RTS* - for possible values. +/** Offset 0x0768 - PCIE RP EQ phase 1 upstream tranmitter port preset + Allows to select the upstream port preset value that will be used during phase 1 + of equalization **/ - UINT32 SerialIoUartRtsPinMuxPolicy[7]; + UINT8 PcieGen3EqPh1UpTxPreset[12]; -/** Offset 0x0ED8 - SerialIoUartRxPinMuxPolicy - Select SerialIo Uart Rx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RX* for - possible values. +/** Offset 0x0774 - PCIE RP EQ phase 2 local transmitter override preset + Allows to select the value of the preset used during phase 2 local transmitter override **/ - UINT32 SerialIoUartRxPinMuxPolicy[7]; + UINT8 PcieGen3EqPh2LocalTxOverridePreset[12]; -/** Offset 0x0EF4 - SerialIoUartTxPinMuxPolicy - Select SerialIo Uart Tx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_TX* for - possible values. +/** Offset 0x0780 - PCIE RP choose EQ method + Choose PCIe EQ method + 0: HardwareEq, 1: FixedEq **/ - UINT32 SerialIoUartTxPinMuxPolicy[7]; + UINT8 PcieGen4EqMethod[12]; -/** Offset 0x0F10 - Serial IO UART DBG2 table - Enable or disable Serial Io UART DBG2 table, default is Disable; 0: Disable; - 1: Enable. +/** Offset 0x078C - PCIE RP choose EQ mode + Choose PCIe EQ mode + 0: PresetEq, 1: CoefficientEq **/ - UINT8 SerialIoUartDbg2[7]; + UINT8 PcieGen4EqMode[12]; -/** Offset 0x0F17 - Reserved +/** Offset 0x0798 - PCIE RP EQ local transmitter override + Enable/Disable local transmitter override + $EN_DIS **/ - UINT8 Reserved28[7]; + UINT8 PcieGen4EqLocalTxOverrideEn[12]; -/** Offset 0x0F1E - I2Cn Device Mode - Selects I2c operation mode. N represents controller index: I2c0, I2c1, ... Available - modes: 0:SerialIoI2cDisabled, 1:SerialIoI2cPci, 2:SerialIoI2cHidden +/** Offset 0x07A4 - PCI RP number of valid list entries + Select number of presets or coefficients depending on the mode **/ - UINT8 SerialIoI2cMode[8]; + UINT8 PcieGen4EqPh3NoOfPresetOrCoeff[12]; -/** Offset 0x0F26 - Reserved +/** Offset 0x07B0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved29[2]; + UINT8 PcieGen4EqPh3PreCursor0List[12]; -/** Offset 0x0F28 - Serial IO I2C SDA Pin Muxing - Select SerialIo I2c Sda pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SDA* for - possible values. +/** Offset 0x07BC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT32 PchSerialIoI2cSdaPinMux[8]; + UINT8 PcieGen4EqPh3PostCursor0List[12]; -/** Offset 0x0F48 - Serial IO I2C SCL Pin Muxing - Select SerialIo I2c Scl pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SCL* for - possible values. +/** Offset 0x07C8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT32 PchSerialIoI2cSclPinMux[8]; + UINT8 PcieGen4EqPh3PreCursor1List[12]; -/** Offset 0x0F68 - PCH SerialIo I2C Pads Termination - 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, - 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C0,I2C1,... pads termination - respectively. One byte for each controller, byte0 for I2C0, byte1 for I2C1, and so on. +/** Offset 0x07D4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 PchSerialIoI2cPadsTermination[8]; + UINT8 PcieGen4EqPh3PostCursor1List[12]; -/** Offset 0x0F70 - I3C Device Mode - Selects I3c operation mode. Available modes: 0:SerialIoI3cDisabled, 1:SerialIoI3cPci, - 2:SerialIoI3cPhantom (only applicable to I3C1, controlls GPIO enabling) +/** Offset 0x07E0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 SerialIoI3cMode[3]; + UINT8 PcieGen4EqPh3PreCursor2List[12]; -/** Offset 0x0F73 - Reserved +/** Offset 0x07EC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved30[48]; + UINT8 PcieGen4EqPh3PostCursor2List[12]; -/** Offset 0x0FA3 - Enable VMD controller - Enable/disable to VMD controller.0: Disable; 1: Enable(Default) - $EN_DIS +/** Offset 0x07F8 - PCIR RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdEnable; + UINT8 PcieGen4EqPh3PreCursor3List[12]; -/** Offset 0x0FA4 - Enable VMD Global Mapping - Enable/disable to VMD controller.0: Disable(Default); 1: Enable - $EN_DIS +/** Offset 0x0804 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdGlobalMapping; + UINT8 PcieGen4EqPh3PostCursor3List[12]; -/** Offset 0x0FA5 - Map port under VMD - Map/UnMap port under VMD - $EN_DIS +/** Offset 0x0810 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdPort[31]; + UINT8 PcieGen4EqPh3PreCursor4List[12]; -/** Offset 0x0FC4 - Reserved +/** Offset 0x081C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved31[31]; + UINT8 PcieGen4EqPh3PostCursor4List[12]; -/** Offset 0x0FE3 - VMD Port Device - VMD Root port device number. +/** Offset 0x0828 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdPortDev[31]; + UINT8 PcieGen4EqPh3PreCursor5List[12]; -/** Offset 0x1002 - VMD Port Func - VMD Root port function number. +/** Offset 0x0834 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT8 VmdPortFunc[31]; + UINT8 PcieGen4EqPh3PostCursor5List[12]; -/** Offset 0x1021 - Reserved +/** Offset 0x0840 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved32[7]; + UINT8 PcieGen4EqPh3PreCursor6List[12]; -/** Offset 0x1028 - VMD Variable - VMD Variable Pointer. +/** Offset 0x084C - PCIe post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT64 VmdVariablePtr; + UINT8 PcieGen4EqPh3PostCursor6List[12]; -/** Offset 0x1030 - Reserved +/** Offset 0x0858 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT8 Reserved33[4]; + UINT8 PcieGen4EqPh3PreCursor7List[12]; -/** Offset 0x1034 - Temporary MemBar1 address for VMD - VMD Variable Pointer. +/** Offset 0x0864 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ **/ - UINT32 VmdMemBar1Base; + UINT8 PcieGen4EqPh3PostCursor7List[12]; -/** Offset 0x1038 - Temporary MemBar2 address for VMD - VMD Variable Pointer. +/** Offset 0x0870 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ **/ - UINT32 VmdMemBar2Base; + UINT8 PcieGen4EqPh3PreCursor8List[12]; -/** Offset 0x103C - Enable D3 Hot in TCSS +/** Offset 0x087C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3PostCursor8List[12]; + +/** Offset 0x0888 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3PreCursor9List[12]; + +/** Offset 0x0894 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3PostCursor9List[12]; + +/** Offset 0x08A0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset0List[12]; + +/** Offset 0x08AC - PCIe preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset1List[12]; + +/** Offset 0x08B8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset2List[12]; + +/** Offset 0x08C4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset3List[12]; + +/** Offset 0x08D0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset4List[12]; + +/** Offset 0x08DC - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset5List[12]; + +/** Offset 0x08E8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset6List[12]; + +/** Offset 0x08F4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset7List[12]; + +/** Offset 0x0900 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset8List[12]; + +/** Offset 0x090C - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset9List[12]; + +/** Offset 0x0918 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen4EqPh3Preset10List[12]; + +/** Offset 0x0924 - PCIe EQ phase 1 downstream transmitter port preset + Allows to select the downstream port preset value that will be used during phase + 1 of equalization +**/ + UINT8 PcieGen4EqPh1DpTxPreset[12]; + +/** Offset 0x0930 - PCIE RP EQ phase 1 upstream tranmitter port preset + Allows to select the upstream port preset value that will be used during phase 1 + of equalization +**/ + UINT8 PcieGen4EqPh1UpTxPreset[12]; + +/** Offset 0x093C - PCIE RP EQ phase 2 local transmitter override preset + Allows to select the value of the preset used during phase 2 local transmitter override +**/ + UINT8 PcieGen4EqPh2LocalTxOverridePreset[12]; + +/** Offset 0x0948 - PCIE RP choose EQ method + Choose PCIe EQ method + 0: HardwareEq, 1: FixedEq +**/ + UINT8 PcieGen5EqMethod[12]; + +/** Offset 0x0954 - PCIE RP choose EQ mode + Choose PCIe EQ mode + 0: PresetEq, 1: CoefficientEq +**/ + UINT8 PcieGen5EqMode[12]; + +/** Offset 0x0960 - PCIE RP EQ local transmitter override + Enable/Disable local transmitter override + $EN_DIS +**/ + UINT8 PcieGen5EqLocalTxOverrideEn[12]; + +/** Offset 0x096C - PCI RP number of valid list entries + Select number of presets or coefficients depending on the mode +**/ + UINT8 PcieGen5EqPh3NoOfPresetOrCoeff[12]; + +/** Offset 0x0978 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor0List[12]; + +/** Offset 0x0984 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor0List[12]; + +/** Offset 0x0990 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor1List[12]; + +/** Offset 0x099C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor1List[12]; + +/** Offset 0x09A8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor2List[12]; + +/** Offset 0x09B4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor2List[12]; + +/** Offset 0x09C0 - PCIR RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor3List[12]; + +/** Offset 0x09CC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor3List[12]; + +/** Offset 0x09D8 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor4List[12]; + +/** Offset 0x09E4 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor4List[12]; + +/** Offset 0x09F0 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor5List[12]; + +/** Offset 0x09FC - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor5List[12]; + +/** Offset 0x0A08 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor6List[12]; + +/** Offset 0x0A14 - PCIe post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor6List[12]; + +/** Offset 0x0A20 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor7List[12]; + +/** Offset 0x0A2C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor7List[12]; + +/** Offset 0x0A38 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor8List[12]; + +/** Offset 0x0A44 - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor8List[12]; + +/** Offset 0x0A50 - PCIE RP pre-cursor coefficient list + Provide a list of pre-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PreCursor9List[12]; + +/** Offset 0x0A5C - PCIE RP post-cursor coefficient list + Provide a list of post-cursor coefficients to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3PostCursor9List[12]; + +/** Offset 0x0A68 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset0List[12]; + +/** Offset 0x0A74 - PCIe preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset1List[12]; + +/** Offset 0x0A80 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset2List[12]; + +/** Offset 0x0A8C - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset3List[12]; + +/** Offset 0x0A98 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset4List[12]; + +/** Offset 0x0AA4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset5List[12]; + +/** Offset 0x0AB0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset6List[12]; + +/** Offset 0x0ABC - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset7List[12]; + +/** Offset 0x0AC8 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset8List[12]; + +/** Offset 0x0AD4 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset9List[12]; + +/** Offset 0x0AE0 - PCIE RP preset list + Provide a list of presets to be used during phase 3 EQ +**/ + UINT8 PcieGen5EqPh3Preset10List[12]; + +/** Offset 0x0AEC - PCIe EQ phase 1 downstream transmitter port preset + Allows to select the downstream port preset value that will be used during phase + 1 of equalization +**/ + UINT8 PcieGen5EqPh1DpTxPreset[12]; + +/** Offset 0x0AF8 - PCIE RP EQ phase 1 upstream tranmitter port preset + Allows to select the upstream port preset value that will be used during phase 1 + of equalization +**/ + UINT8 PcieGen5EqPh1UpTxPreset[12]; + +/** Offset 0x0B04 - PCIE RP EQ phase 2 local transmitter override preset + Allows to select the value of the preset used during phase 2 local transmitter override +**/ + UINT8 PcieGen5EqPh2LocalTxOverridePreset[12]; + +/** Offset 0x0B10 - Phase3 RP Gen3 EQ enable + Phase3 Gen3 EQ enable. Disabled(0x0)(Default): Disable phase 3, Enabled(0x1): Enable phase 3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen3EqPh3Bypass[12]; + +/** Offset 0x0B1C - Phase3 RP Gen4 EQ enable + Phase3 Gen4 EQ enable. Disabled(0x0)(Default): Disable phase 3, Enabled(0x1): Enable phase 3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen4EqPh3Bypass[12]; + +/** Offset 0x0B28 - Phase3 RP Gen5 EQ enable + Phase3 Gen5 EQ enable. Disabled(0x0)(Default): Disable phase 3, Enabled(0x1): Enable phase 3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen5EqPh3Bypass[12]; + +/** Offset 0x0B34 - Phase2-3 RP Gen3 EQ enable + Phase2-3 Gen3 EQ enable. Disabled(0x0)(Default): Disable Phase2-3, Enabled(0x1): + Enable Phase2-3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen3EqPh23Bypass[12]; + +/** Offset 0x0B40 - Phase2-3 RP Gen4 EQ enable + Phase2-3 Gen4 EQ enable. Disabled(0x0)(Default): Disable Phase2-3, Enabled(0x1): + Enable Phase2-3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen4EqPh23Bypass[12]; + +/** Offset 0x0B4C - Phase2-3 RP Gen5 EQ enable + Phase2-3 Gen5 EQ enable. Disabled(0x0)(Default): Disable Phase2-3, Enabled(0x1): + Enable Phase2-3 + 0:Disable, 1:Enable, 2:Auto +**/ + UINT8 PcieRpGen5EqPh23Bypass[12]; + +/** Offset 0x0B58 - PCET Timer + Preset/Coefficient Evaluation Timeout Gen3 PCET Timer. See PCIE_GEN3_PCET. Default + is 0x0(2ms) +**/ + UINT8 PcieGen3PcetTimer[12]; + +/** Offset 0x0B64 - Gen4 PCET Timer + Preset/Coefficient Evaluation Timeout - Gen4 PCET Timer. See PCIE_GEN4_PCET. Default + is 0x0(2ms) +**/ + UINT8 PcieGen4PcetTimer[12]; + +/** Offset 0x0B70 - Gen5 PCET Timer + Preset/Coefficient Evaluation Timeout - Gen5 PCET Timer. See PCIE_GEN5_PCET. Default + is 0x0(2ms) +**/ + UINT8 PcieGen5PcetTimer[12]; + +/** Offset 0x0B7C - TS Lock Timer for Gen3 + Training Sequence Wait Latency For Presets/Coefficients Evaluation - Gen3 TS Lock + Timer. See PCIE_GEN3_TS_LOCK_TIMER. Default is 0x0 +**/ + UINT8 PcieGen3TsLockTimer[12]; + +/** Offset 0x0B88 - PTS Lock Timer for Gen4 + Training Sequence Wait Latency For Presets/Coefficients Evaluation - Gen4 TS Lock + Timer. See PCIE_GEN4_TS_LCOK_TIMER. Default is 0x0 +**/ + UINT8 PcieGen4TsLockTimer[12]; + +/** Offset 0x0B94 - PTS Lock Timer for Gen5 + Training Sequence Wait Latency For Presets/Coefficients Evaluation - Gen5 TS Lock + Timer. See PCIE_GEN5_TS_LCOK_TIMER. Default is 0x0 +**/ + UINT8 PcieGen5TsLockTimer[12]; + +/** Offset 0x0BA0 - PCIE Secure Register Lock + Describes whether Secure Register Lock is enaled or disabled. When it will be enbaled, + load PcieRpSetSecuredRegisterLock recipe. 0: Disable(Default); 1: Enable + $EN_DIS +**/ + UINT8 PcieSetSecuredRegisterLock; + +/** Offset 0x0BA1 - Enable/Disable ASPM Optionality Compliance + Enable/Disable ASPM Optionality Compliance. +**/ + UINT8 PcieRpTestAspmOc[12]; + +/** Offset 0x0BAD - PCIE RP Enable Peer Memory Write + This member describes whether Peer Memory Writes are enabled on the platform. + $EN_DIS +**/ + UINT8 PcieEnablePeerMemoryWrite[12]; + +/** Offset 0x0BB9 - Assertion on Link Down GPIOs + GPIO Assertion on Link Down. Disabled(0x0)(Default): Disable assertion on Link Down + GPIOs, Enabled(0x1): Enable assertion on Link Down GPIOs + 0:Disable, 1:Enable +**/ + UINT8 PcieRpLinkDownGpios[12]; + +/** Offset 0x0BC5 - PCIE Compliance Test Mode + Compliance Test Mode shall be enabled when using Compliance Load Board. + $EN_DIS +**/ + UINT8 PcieComplianceTestMode; + +/** Offset 0x0BC6 - PCIE Rp Function Swap + Allows BIOS to use root port function number swapping when root port of function + 0 is disabled. + $EN_DIS +**/ + UINT8 PcieRpFunctionSwap; + +/** Offset 0x0BC7 - PCIe RootPort Clock Gating + Describes whether the PCI Express Clock Gating for each root port is enabled by + platform modules. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieClockGating[12]; + +/** Offset 0x0BD3 - PCIe RootPort Power Gating + Describes whether the PCI Express Power Gating for each root port is enabled by + platform modules. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PciePowerGating[12]; + +/** Offset 0x0BDF - PCIe RootPort VISA Clock Gating + Describes whether the PCI Express VISA Clock Gating. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieVisaClockGating[12]; + +/** Offset 0x0BEB - PCIe RootPort AutoPower Gating + Describes the Auto Power Gating for per controller. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieAutoPowerGating[12]; + +/** Offset 0x0BF7 - PCIe RootPort PHY AutoPower Gating + Describes the PHY Auto Power Gating for per controller. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PciePhyAutoPowerGating; + +/** Offset 0x0BF8 - FOMS Control Policy + Choose the Foms Control Policy, Default = 0 + 0: Auto, 1: Gen3 Foms, 2: Gen4 Foms, 3: Gen3 and Gen4 Foms +**/ + UINT8 PcieFomsCp[12]; + +/** Offset 0x0C04 - EqPhBypass Control Policy + PCIe Equalization Phase Enable Control, Disabled (0x0) : Disable Phase + (Default), Enabled (0x1) : Enable Phase + 0: Auto, 1: Gen3 Foms, 2: Gen4 Foms, 3: Gen3 and Gen4 Foms +**/ + UINT8 PcieEqPhBypass[12]; + +/** Offset 0x0C10 - PCIE RP Ltr Max Snoop Latency + Latency Tolerance Reporting, Max Snoop Latency. +**/ + UINT16 PcieRpLtrMaxSnoopLatency[24]; + +/** Offset 0x0C40 - PCIE RP Ltr Max No Snoop Latency + Latency Tolerance Reporting, Max Non-Snoop Latency. +**/ + UINT16 PcieRpLtrMaxNoSnoopLatency[24]; + +/** Offset 0x0C70 - PCIE RP Snoop Latency Override Mode + Latency Tolerance Reporting, Snoop Latency Override Mode. +**/ + UINT8 PcieRpSnoopLatencyOverrideMode[28]; + +/** Offset 0x0C8C - PCIE RP Snoop Latency Override Multiplier + Latency Tolerance Reporting, Snoop Latency Override Multiplier. +**/ + UINT8 PcieRpSnoopLatencyOverrideMultiplier[28]; + +/** Offset 0x0CA8 - PCIE RP Snoop Latency Override Value + Latency Tolerance Reporting, Snoop Latency Override Value. +**/ + UINT16 PcieRpSnoopLatencyOverrideValue[24]; + +/** Offset 0x0CD8 - PCIE RP Non Snoop Latency Override Mode + Latency Tolerance Reporting, Non-Snoop Latency Override Mode. +**/ + UINT8 PcieRpNonSnoopLatencyOverrideMode[28]; + +/** Offset 0x0CF4 - PCIE RP Non Snoop Latency Override Multiplier + Latency Tolerance Reporting, Non-Snoop Latency Override Multiplier. +**/ + UINT8 PcieRpNonSnoopLatencyOverrideMultiplier[28]; + +/** Offset 0x0D10 - PCIE RP Non Snoop Latency Override Value + Latency Tolerance Reporting, Non-Snoop Latency Override Value. +**/ + UINT16 PcieRpNonSnoopLatencyOverrideValue[24]; + +/** Offset 0x0D40 - PCIE RP Slot Power Limit Scale + Specifies scale used for slot power limit value. Leave as 0 to set to default. +**/ + UINT8 PcieRpSlotPowerLimitScale[28]; + +/** Offset 0x0D5C - PCIE RP Slot Power Limit Value + Specifies upper limit on power supplie by slot. Leave as 0 to set to default. +**/ + UINT16 PcieRpSlotPowerLimitValue[24]; + +/** Offset 0x0D8C - PCIE RP Enable Port8xh Decode + This member describes whether PCIE root port Port 8xh Decode is enabled. 0: Disable; + 1: Enable. + $EN_DIS +**/ + UINT8 PcieEnablePort8xhDecode; + +/** Offset 0x0D8D - PCIE Port8xh Decode Port Index + The Index of PCIe Port that is selected for Port8xh Decode (1 Based). +**/ + UINT8 PchPciePort8xhDecodePortIndex; + +/** Offset 0x0D8E - PCIE RP LTR Override Spec Compliant + Override LTR based on Ep capability. +**/ + UINT8 PcieRpLtrOverrideSpecCompliant[28]; + +/** Offset 0x0DAA - PCIe AER _OSC Setting + Enable/Disable Global PCIe Advanced Error Reporting + 0:Disable, 1:Enable +**/ + UINT8 GlobalPcieAer; + +/** Offset 0x0DAB - PCIe TBT Performance Boost Bitmap + Bitmap of TBT performance boost enabled PCIe controllers to which discrete TBT controllers + connect. Bit0: PXPA, Bit1: PXPB, Bit2: PXPC, Bit3: PXPD, Bit4: PXPE +**/ + UINT8 PcieTbtPerfBoost; + +/** Offset 0x0DAC - Serial IO SPI CLK Pin Muxing + Select SerialIo LPSS SPI CS pin muxing. Refer to GPIO_*_MUXING_SERIALIO_SPIx_CLK* + for possible values. +**/ + UINT32 SerialIoLpssSpiClkPinMux[7]; + +/** Offset 0x0DC8 - Serial IO SPI CS Pin Muxing + Select SerialIo LPSS SPI CS pin muxing. Refer to GPIO_*_MUXING_SERIALIO_SPIx_CS* + for possible values. +**/ + UINT32 SerialIoLpssSpiCsPinMux[14]; + +/** Offset 0x0E00 - SPIn Device Mode + Selects SPI operation mode. N represents controller index: SPI0, SPI1, ... Available + modes: 0:LpssSpiDisabled, 1:LpssSpiPci, 2:LpssSpiHidden +**/ + UINT8 SerialIoLpssSpiMode[7]; + +/** Offset 0x0E07 - Reserved +**/ + UINT8 Reserved7; + +/** Offset 0x0E08 - LPSS SPI MOSI Pin Muxing + Select LPSS SPI MOSI pin muxing. Refer to GPIO_*_MUXING_LPSS_SPIx_MOSI* for possible values. +**/ + UINT32 SerialIoLpssSpiMosiPinMux[7]; + +/** Offset 0x0E24 - LPSS SPI MISO Pin Muxing + Select Lpss SPI MISO pin muxing. Refer to GPIO_*_MUXING_LPSS_SPIx_MISO* for possible values. +**/ + UINT32 SerialIoLpssSpiMisoPinMux[7]; + +/** Offset 0x0E40 - SPI Chip Select Polarity + Sets polarity for each chip Select. Available options: 0:LpssSpiCsActiveLow, 1:LpssSpiCsActiveHigh +**/ + UINT8 SerialIoLpssSpiCsPolarity[14]; + +/** Offset 0x0E4E - SPI Chip Select Enable + 0:Disabled, 1:Enabled. Enables GPIO for CS0 or CS1 if it is Enabled +**/ + UINT8 SerialIoLpssSpiCsEnable[14]; + +/** Offset 0x0E5C - SPIn Default Chip Select Mode HW/SW + Sets Default CS Mode Hardware or Software. N represents controller index: SPI0, + SPI1, ... Available options: 0:HW, 1:SW +**/ + UINT8 SerialIoLpssSpiCsMode[7]; + +/** Offset 0x0E63 - SPIn Default Chip Select State Low/High + Sets Default CS State Low or High. N represents controller index: SPI0, SPI1, ... + Available options: 0:Low, 1:High +**/ + UINT8 SerialIoLpssSpiCsState[7]; + +/** Offset 0x0E6A - UARTn Device Mode + Selects Uart operation mode. N represents controller index: Uart0, Uart1, ... Available + modes: 0:SerialIoUartDisabled, 1:SerialIoUartPci, 2:SerialIoUartHidden, 3:SerialIoUartCom, + 4:SerialIoUartSkipInit +**/ + UINT8 SerialIoUartMode[7]; + +/** Offset 0x0E71 - Reserved +**/ + UINT8 Reserved8[3]; + +/** Offset 0x0E74 - Default BaudRate for each Serial IO UART + Set default BaudRate Supported from 0 - default to 6000000 +**/ + UINT32 SerialIoUartBaudRate[7]; + +/** Offset 0x0E90 - Default ParityType for each Serial IO UART + Set default Parity. 0: DefaultParity, 1: NoParity, 2: EvenParity, 3: OddParity +**/ + UINT8 SerialIoUartParity[7]; + +/** Offset 0x0E97 - Default DataBits for each Serial IO UART + Set default word length. 0: Default, 5,6,7,8 +**/ + UINT8 SerialIoUartDataBits[7]; + +/** Offset 0x0E9E - Default StopBits for each Serial IO UART + Set default stop bits. 0: DefaultStopBits, 1: OneStopBit, 2: OneFiveStopBits, 3: + TwoStopBits +**/ + UINT8 SerialIoUartStopBits[7]; + +/** Offset 0x0EA5 - Power Gating mode for each Serial IO UART that works in COM mode + Set Power Gating. 0: Disabled, 1: Enabled, 2: Auto +**/ + UINT8 SerialIoUartPowerGating[7]; + +/** Offset 0x0EAC - Enable Dma for each Serial IO UART that supports it + Set DMA/PIO mode. 0: Disabled, 1: Enabled +**/ + UINT8 SerialIoUartDmaEnable[7]; + +/** Offset 0x0EB3 - Enables UART hardware flow control, CTS and RTS lines + Enables UART hardware flow control, CTS and RTS lines. +**/ + UINT8 SerialIoUartAutoFlow[7]; + +/** Offset 0x0EBA - Reserved +**/ + UINT8 Reserved9[2]; + +/** Offset 0x0EBC - SerialIoUartRtsPinMuxPolicy + Select SerialIo Uart Rts pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RTS* + for possible values. +**/ + UINT32 SerialIoUartRtsPinMuxPolicy[7]; + +/** Offset 0x0ED8 - SerialIoUartRxPinMuxPolicy + Select SerialIo Uart Rx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_RX* for + possible values. +**/ + UINT32 SerialIoUartRxPinMuxPolicy[7]; + +/** Offset 0x0EF4 - SerialIoUartTxPinMuxPolicy + Select SerialIo Uart Tx pin muxing. Refer to GPIO_*_MUXING_SERIALIO_UARTx_TX* for + possible values. +**/ + UINT32 SerialIoUartTxPinMuxPolicy[7]; + +/** Offset 0x0F10 - Serial IO UART DBG2 table + Enable or disable Serial Io UART DBG2 table, default is Disable; 0: Disable; + 1: Enable. +**/ + UINT8 SerialIoUartDbg2[7]; + +/** Offset 0x0F17 - Serial IO UART PG DBG2 table + Enable or disable Serial Io UART PG DBG2 table, default is Disable; 0: Disable; + 1: Enable. +**/ + UINT8 SerialIoUartPgDbg2[7]; + +/** Offset 0x0F1E - I2Cn Device Mode + Selects I2c operation mode. N represents controller index: I2c0, I2c1, ... Available + modes: 0:SerialIoI2cDisabled, 1:SerialIoI2cPci, 2:SerialIoI2cHidden +**/ + UINT8 SerialIoI2cMode[8]; + +/** Offset 0x0F26 - Reserved +**/ + UINT8 Reserved10[2]; + +/** Offset 0x0F28 - Serial IO I2C SDA Pin Muxing + Select SerialIo I2c Sda pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SDA* for + possible values. +**/ + UINT32 PchSerialIoI2cSdaPinMux[8]; + +/** Offset 0x0F48 - Serial IO I2C SCL Pin Muxing + Select SerialIo I2c Scl pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I2Cx_SCL* for + possible values. +**/ + UINT32 PchSerialIoI2cSclPinMux[8]; + +/** Offset 0x0F68 - PCH SerialIo I2C Pads Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I2C0,I2C1,... pads termination + respectively. One byte for each controller, byte0 for I2C0, byte1 for I2C1, and so on. +**/ + UINT8 PchSerialIoI2cPadsTermination[8]; + +/** Offset 0x0F70 - I3C Device Mode + Selects I3c operation mode. Available modes: 0:SerialIoI3cDisabled, 1:SerialIoI3cPci, + 2:SerialIoI3cPhantom (only applicable to I3C1, controlls GPIO enabling) +**/ + UINT8 SerialIoI3cMode[3]; + +/** Offset 0x0F73 - Reserved +**/ + UINT8 Reserved11; + +/** Offset 0x0F74 - Serial IO I3C SDA Pin Muxing + Select SerialIo I3c Sda pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I3Cx_SDA* for + possible values. +**/ + UINT32 SerialIoI3cSdaPinMux[3]; + +/** Offset 0x0F80 - Serial IO I3C SDA Pad Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I3C0,I3C1,... pads termination + respectively. One byte for each controller, byte0 for I3C0, byte1 for I3C1, and so on. +**/ + UINT8 SerialIoI3cSdaPadTermination[3]; + +/** Offset 0x0F83 - Reserved +**/ + UINT8 Reserved12; + +/** Offset 0x0F84 - Serial IO I3C SCL Pin Muxing + Select SerialIo I3c Scl pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I3Cx_SCL* for + possible values. +**/ + UINT32 SerialIoI3cSclPinMux[3]; + +/** Offset 0x0F90 - Serial IO I3C SCL Pad Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I3C0,I3C1,... pads termination + respectively. One byte for each controller, byte0 for I3C0, byte1 for I3C1, and so on. +**/ + UINT8 SerialIoI3cSclPadTermination[3]; + +/** Offset 0x0F93 - Reserved +**/ + UINT8 Reserved13; + +/** Offset 0x0F94 - Serial IO I3C SCL FB Pin Muxing + Select SerialIo I3c SclFb pin muxing. Refer to GPIO_*_MUXING_SERIALIO_I3Cx_SCL FB* + for possible values. +**/ + UINT32 SerialIoI3cSclFbPinMux[3]; + +/** Offset 0x0FA0 - Serial IO I3C SCL FB Pad Termination + 0x0: Hardware default, 0x1: None, 0x13: 1kOhm weak pull-up, 0x15: 5kOhm weak pull-up, + 0x19: 20kOhm weak pull-up - Enable/disable SerialIo I3C0,I3C1,... pads termination + respectively. One byte for each controller, byte0 for I3C0, byte1 for I3C1, and so on. +**/ + UINT8 SerialIoI3cSclFbPadTermination[3]; + +/** Offset 0x0FA3 - Enable VMD controller + Enable/disable to VMD controller.0: Disable; 1: Enable(Default) + $EN_DIS +**/ + UINT8 VmdEnable; + +/** Offset 0x0FA4 - Enable VMD Global Mapping + Enable/disable to VMD controller.0: Disable(Default); 1: Enable + $EN_DIS +**/ + UINT8 VmdGlobalMapping; + +/** Offset 0x0FA5 - Map port under VMD + Map/UnMap port under VMD + $EN_DIS +**/ + UINT8 VmdPort[31]; + +/** Offset 0x0FC4 - VMD Port Bus + VMD Root port bus number. +**/ + UINT8 VmdPortBus[31]; + +/** Offset 0x0FE3 - VMD Port Device + VMD Root port device number. +**/ + UINT8 VmdPortDev[31]; + +/** Offset 0x1002 - VMD Port Func + VMD Root port function number. +**/ + UINT8 VmdPortFunc[31]; + +/** Offset 0x1021 - Reserved +**/ + UINT8 Reserved14[7]; + +/** Offset 0x1028 - VMD Variable + VMD Variable Pointer. +**/ + UINT64 VmdVariablePtr; + +/** Offset 0x1030 - Temporary CfgBar address for VMD + VMD Variable Pointer. +**/ + UINT32 VmdCfgBarBase; + +/** Offset 0x1034 - Temporary MemBar1 address for VMD + VMD Variable Pointer. +**/ + UINT32 VmdMemBar1Base; + +/** Offset 0x1038 - Temporary MemBar2 address for VMD + VMD Variable Pointer. +**/ + UINT32 VmdMemBar2Base; + +/** Offset 0x103C - Enable D3 Hot in TCSS This policy will enable/disable D3 hot support in IOM $EN_DIS **/ UINT8 D3HotEnable; -/** Offset 0x103D - Reserved +/** Offset 0x103D - TCSS TBT Performance Boost Bitmap + Bitmap of TBT performance boost enabled TCSS PCIe root ports. Bit0: TCSS port0, + Bit1: TCSS port1, Bit2: TCSS port2, Bit3: TCSS port3 **/ - UINT8 Reserved34[3]; + UINT8 TcssTbtPerfBoost; + +/** Offset 0x103E - Reserved +**/ + UINT8 Reserved15[2]; /** Offset 0x1040 - TypeC port GPIO setting GPIO Ping number for Type C Aux orientation setting, use the GpioPad that is defined @@ -1508,9 +2499,17 @@ typedef struct { **/ UINT8 TcCstateLimit; -/** Offset 0x107C - Reserved +/** Offset 0x107C - TC Notify Igd + Tc Notify Igd **/ - UINT8 Reserved35[2]; + UINT8 TcNotifyIgd; + +/** Offset 0x107D - TCSS CPU USB PDO Programming + Enable/disable PDO programming for TCSS CPU USB in PEI phase. Disabling will allow + for programming during later phase. 1: enable, 0: disable + $EN_DIS +**/ + UINT8 TcssCpuUsbPdoProgramming; /** Offset 0x107E - Enable/Disable PMC-PD Solution This policy will enable/disable PMC-PD Solution vs EC-TCPC Solution @@ -1520,7 +2519,7 @@ typedef struct { /** Offset 0x107F - Reserved **/ - UINT8 Reserved36; + UINT8 Reserved16; /** Offset 0x1080 - TCSS Aux Orientation Override Enable Bits 0, 2, ... 10 control override enables, bits 1, 3, ... 11 control overrides @@ -1594,9 +2593,11 @@ typedef struct { **/ UINT8 SaPcieItbtRpLtrConfigLock[4]; -/** Offset 0x10B6 - Reserved +/** Offset 0x10B6 - Type C Port x Convert to TypeA + Enable / Disable(default) Type C Port x Convert to TypeA + $EN_DIS **/ - UINT8 Reserved37[4]; + UINT8 EnableTcssCovTypeA[4]; /** Offset 0x10BA - Touch Host Controller Assignment Assign THC 0x0:ThcAssignmentNone, 0x1:ThcAssignmentThc0, 0x2:ThcAssignmentThc1 @@ -1620,9 +2621,276 @@ typedef struct { **/ UINT8 ThcWakeOnTouch[2]; -/** Offset 0x10C8 - Reserved +/** Offset 0x10C8 - Touch Host Controller Active Ltr + Expose Active Ltr for OS driver to set +**/ + UINT32 ThcActiveLtr[2]; + +/** Offset 0x10D0 - Touch Host Controller Idle Ltr + Expose Idle Ltr for OS driver to set +**/ + UINT32 ThcIdleLtr[2]; + +/** Offset 0x10D8 - Touch Host Controller Timestamp timer behavior in D0i2 + Timestamp timer behavior in D0i2. 1 = Timer resets to 0 when entering D0i2 0 = Timer + is paused instead of reset to 0 when entering D0i2 +**/ + UINT8 TimestampTimerMode[2]; + +/** Offset 0x10DA - Reserved +**/ + UINT8 Reserved17[2]; + +/** Offset 0x10DC - Touch Host Controller Display Frame Sync Period + Period of the emulated display frame sync [ms] The minimum period is 2ms, maximum + period is 100ms +**/ + UINT32 DisplayFrameSyncPeriod[2]; + +/** Offset 0x10E4 - Touch Host Controller ResetPad + ResetPad +**/ + UINT32 ThcResetPad[2]; + +/** Offset 0x10EC - Touch Host Controller ResetPad Trigger + Hid Over Spi Reset Pad Trigger 0x0:Low, 0x1:High +**/ + UINT32 ThcResetPadTrigger[2]; + +/** Offset 0x10F4 - Touch Host Controller DYSync + Based on this setting GPIO for given THC will be in native mode +**/ + UINT8 ThcDsyncPad[2]; + +/** Offset 0x10F6 - Reserved +**/ + UINT8 Reserved18[2]; + +/** Offset 0x10F8 - Touch Host Controller Hid Over Spi Connection Speed + Hid Over Spi Connection Speed - SPI Frequency +**/ + UINT32 ThcHidSpiConnectionSpeed[2]; + +/** Offset 0x1100 - Touch Host Controller Hid Over Spi Limit PacketSize + When set, limits SPI read & write packet size to 64B. Otherwise, THC uses Max Soc + packet size for SPI Read and Write 0x0- Max Soc Packet Size, 0x11 - 64 Bytes +**/ + UINT32 ThcHidSpiLimitPacketSize[2]; + +/** Offset 0x1108 - Touch Host Controller Hid Over Spi Limit PacketSize + Minimum amount of delay the THC/QUICKSPI driver must wait between end of write operation + and begin of read operation. This value shall be in 10us multiples 0x0: Disabled, + 1-65535 (0xFFFF) - up to 655350 us +**/ + UINT32 ThcPerformanceLimitation[2]; + +/** Offset 0x1110 - Touch Host Controller Hid Over Spi Input Report Header Address + Hid Over Spi Input Report Header Address +**/ + UINT32 ThcHidSpiInputReportHeaderAddress[2]; + +/** Offset 0x1118 - Touch Host Controller Hid Over Spi Input Report Body Address + Hid Over Spi Input Report Body Address +**/ + UINT32 ThcHidSpiInputReportBodyAddress[2]; + +/** Offset 0x1120 - Touch Host Controller Hid Over Spi Output Report Address + Hid Over Spi Output Report Address +**/ + UINT32 ThcHidSpiOutputReportAddress[2]; + +/** Offset 0x1128 - Touch Host Controller Hid Over Spi Read Opcode + Hid Over Spi Read Opcode +**/ + UINT32 ThcHidSpiReadOpcode[2]; + +/** Offset 0x1130 - Touch Host Controller Hid Over Spi Write Opcode + Hid Over Spi Write Opcode +**/ + UINT32 ThcHidSpiWriteOpcode[2]; + +/** Offset 0x1138 - Touch Host Controller Hid Over Spi Flags + Hid Over Spi Flags 0x0:Single SPI Mode, 0x4000:Dual SPI Mode, 0x8000:Quad SPI Mode +**/ + UINT32 ThcHidSpiFlags[2]; + +/** Offset 0x1140 - Touch Host Controller Reset Sequencing Delay [ms] + Policy control for reset sequencing delay (ACPI _INI, _RST) default 300ms +**/ + UINT16 ThcResetSequencingDelay[2]; + +/** Offset 0x1144 - Touch Host Controller Hid Over I2c Device Address + Hid Over I2c Device Address +**/ + UINT32 ThcHidI2cDeviceAddress[2]; + +/** Offset 0x114C - Touch Host Controller Hid Over I2c Connection Speed + Hid Over I2c Connection Speed [Hz] +**/ + UINT32 ThcHidI2cConnectionSpeed[2]; + +/** Offset 0x1154 - Touch Host Controller Hid Over I2c Addressing Mode + Hid Over I2c Addressing Mode - 0x1: The connection uses 10-bit addressing. 0x0: + The connection uses 7-bit addressing. +**/ + UINT8 ThcHidI2cAddressingMode[2]; + +/** Offset 0x1156 - Reserved +**/ + UINT8 Reserved19[2]; + +/** Offset 0x1158 - Touch Host Controller Hid Over I2c Device Descriptor Address + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cDeviceDescriptorAddress[2]; + +/** Offset 0x1160 - Touch Host Controller Hid Over I2c Serial Clock Line High Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialClockLineHighPeriod[2]; + +/** Offset 0x1168 - Touch Host Controller Hid Over I2c Standard Mode Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialClockLineLowPeriod[2]; + +/** Offset 0x1170 - Touch Host Controller Hid Over I2c Standard Mode Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x1178 - Touch Host Controller Hid Over I2c Standard Mode Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cStandardModeSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x1180 - Touch Host Controller Hid Over I2c Fast Mode Serial Clock Line High Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialClockLineHighPeriod[2]; + +/** Offset 0x1188 - Touch Host Controller Hid Over I2c Fast Mode Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialClockLineLowPeriod[2]; + +/** Offset 0x1190 - Touch Host Controller Hid Over I2c Fast Mode Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x1198 - Touch Host Controller Hid Over I2c Fast Mode Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModeSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x11A0 - Touch Host Controller Hid Over I2c Maximum Length Of Suppressed Spikes In Std Mode Fast Mode And Fast Mode Plus + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cMaxSuppressedSpikesSMFMFMP[2]; + +/** Offset 0x11A8 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Clock Line High Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialClockLineHighPeriod[2]; + +/** Offset 0x11B0 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialClockLineLowPeriod[2]; + +/** Offset 0x11B8 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x11C0 - Touch Host Controller Hid Over I2c Fast Mode Plus Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cFastModePlusSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x11C8 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Clock Line High Period + Hid Over I2c Device Descriptor Address **/ - UINT8 Reserved38[337]; + UINT32 ThcHidI2cHighSpeedModePlusSerialClockLineHighPeriod[2]; + +/** Offset 0x11D0 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Clock Line Low Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cHighSpeedModePlusSerialClockLineLowPeriod[2]; + +/** Offset 0x11D8 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Data Line Transmit Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cHighSpeedModePlusSerialDataLineTransmitHoldPeriod[2]; + +/** Offset 0x11E0 - Touch Host Controller Hid Over I2c High Speed Mode Plus Serial Data Line Receive Hold Period + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cHighSpeedModePlusSerialDataLineReceiveHoldPeriod[2]; + +/** Offset 0x11E8 - Touch Host Controller Hid Over I2c Maximum Length Of Suppressed Spikes In High Speed Mode + Hid Over I2c Device Descriptor Address +**/ + UINT32 ThcHidI2cMaximumLengthOfSuppressedSpikesInHighSpeedMode[2]; + +/** Offset 0x11F0 - THC Wake On Touch GPIO resource Edge or Level + Definition of GPIO resource configuration of Edge or Level +**/ + UINT8 ThcWotEdgeLevel[2]; + +/** Offset 0x11F2 - THC Wake On Touch GPIO resource of Active Level + Definition of GPIO resource configuration of Active Level +**/ + UINT8 ThcWotActiveLevel[2]; + +/** Offset 0x11F4 - THC Wake On Touch GPIO resource of pin configuration + Definition of GPIO resource configuration of pin configuration +**/ + UINT8 ThcWotPinConfig[2]; + +/** Offset 0x11F6 - THC customized SubSytem ID for Port + Definition of GPIO resource configuration of pin configuration +**/ + UINT16 ThcCustomizedSsid[2]; + +/** Offset 0x11FA - THC Sets Customized SubSytem Vendor ID for Port + Definition of GPIO resource configuration of pin configuration +**/ + UINT16 ThcCustomizedSvid[2]; + +/** Offset 0x11FE - Reserved +**/ + UINT8 Reserved20[2]; + +/** Offset 0x1200 - USB 3.1 Speed Selection + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT32 Usb31PortSpeed; + +/** Offset 0x1204 - Touch Host Controller Hid Over I2c Maximum Frame Size Enable + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT8 ThcHidI2cMaxFrameSize[2]; + +/** Offset 0x1206 - Touch Host Controller Hid Over I2c Maximum Frame Size Value + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT16 ThcHidI2cMaxFrameSizeValue[2]; + +/** Offset 0x120A - Touch Host Controller Hid Over I2c Interrupt Delay Enable + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT8 ThcHidI2cIntDelay[2]; + +/** Offset 0x120C - Touch Host Controller Hid Over I2c Interrupt Delay Value + Choose USB 3.1 Port Speed Selection. Each bit represents a port. 1: Gen1, 0: Gen2 +**/ + UINT16 ThcHidI2cIntDelayValue[2]; + +/** Offset 0x1210 - Reserved +**/ + UINT8 Reserved21[9]; /** Offset 0x1219 - PCHHOT# pin Enable PCHHOT# pin assertion when temperature is higher than PchHotLevel. 0: disable, 1: enable @@ -1683,7 +2951,47 @@ typedef struct { /** Offset 0x122A - Reserved **/ - UINT8 Reserved39[34]; + UINT8 Reserved22[2]; + +/** Offset 0x122C - PCH TSN MAC Address High Bits + Set TSN MAC Address High. +**/ + UINT32 PchTsn1MacAddressHigh; + +/** Offset 0x1230 - PCH TSN MAC Address Low Bits + Set TSN MAC Address Low. +**/ + UINT32 PchTsn1MacAddressLow; + +/** Offset 0x1234 - PCH TSN2 MAC Address High Bits + Set TSN2 MAC Address High. +**/ + UINT32 PchTsn2MacAddressHigh; + +/** Offset 0x1238 - PCH TSN2 MAC Address Low Bits + Set TSN2 MAC Address Low. +**/ + UINT32 PchTsn2MacAddressLow; + +/** Offset 0x123C - PCH TSN3 MAC Address High Bits + Set TSN3 MAC Address High. +**/ + UINT32 PchTsn3MacAddressHigh; + +/** Offset 0x1240 - PCH TSN3 MAC Address Low Bits + Set TSN3 MAC Address Low. +**/ + UINT32 PchTsn3MacAddressLow; + +/** Offset 0x1244 - PCH TSN4 MAC Address High Bits + Set TSN4 MAC Address High. +**/ + UINT32 PchTsn4MacAddressHigh; + +/** Offset 0x1248 - PCH TSN MAC4 Address Low Bits + Set TSN MAC4 Address Low. +**/ + UINT32 PchTsn4MacAddressLow; /** Offset 0x124C - Enable USB2 ports Enable/disable per USB2 ports. One byte for each port, byte0 for port0, byte1 for @@ -1710,9 +3018,11 @@ typedef struct { **/ UINT8 UsbPdoProgramming; -/** Offset 0x1268 - Reserved +/** Offset 0x1268 - USB Audio Offload enable + Enable/Disable USB Audio Offload capabilites. 0: disabled, 1: enabled (default) + $EN_DIS **/ - UINT8 Reserved40; + UINT8 PchXhciUaolEnable; /** Offset 0x1269 - PCH USB OverCurrent mapping enable 1: Will program USB OC pin mapping in xHCI controller memory, 0: Will clear OC pin @@ -1737,9 +3047,15 @@ typedef struct { **/ UINT8 PchUsbLtrOverrideEnable; -/** Offset 0x1285 - Reserved +/** Offset 0x1285 - USB DWB enable + Enable/Disable USB DWB. 0: disabled, 1: enabled (default) + $EN_DIS +**/ + UINT8 PchXhciDwbEnable; + +/** Offset 0x1286 - Reserved **/ - UINT8 Reserved41[3]; + UINT8 Reserved23[2]; /** Offset 0x1288 - xHCI High Idle Time LTR override Value used for overriding LTR recommendation for xHCI High Idle Time LTR setting @@ -1897,9 +3213,21 @@ typedef struct { **/ UINT8 Usb3HsioTxRate0UniqTran[10]; -/** Offset 0x13AD - Reserved +/** Offset 0x13AD - PCIe Fia Programming + Load Fia configuration if enable. 0: Disable; 1: Enable(Default). + $EN_DIS +**/ + UINT8 PcieFiaProgramming; + +/** Offset 0x13AE - Enable SSE Device + Test, 0: POR, 1: enable, 2: disable, Enable/Disable SSE/SSE++ Devices from PCI config space + $EN_DIS +**/ + UINT8 SseCommunication; + +/** Offset 0x13AF - Reserved **/ - UINT8 Reserved42[4]; + UINT8 Reserved24[2]; /** Offset 0x13B1 - Enable/Disable NPU Device Enable(Default): Enable NPU Device, Disable: Disable NPU Device @@ -1919,9 +3247,11 @@ typedef struct { **/ UINT8 PchLanLtrEnable; -/** Offset 0x13B4 - Reserved +/** Offset 0x13B4 - PCH Lan WOL Fast Support + Enables bit B_PCH_ACPI_GPE0_EN_127_96_PME_B0 during PchLanSxCallback in PchLanSxSmm. + $EN_DIS **/ - UINT8 Reserved43; + UINT8 PchLanWOLFastSupport; /** Offset 0x13B5 - Skip Ssid Programming. When set to TRUE, silicon code will not do any SSID programming and platform code @@ -1942,9 +3272,15 @@ typedef struct { **/ UINT16 SiCustomizedSsid; -/** Offset 0x13BA - Reserved +/** Offset 0x13BA - CAN Configurations + Enable/Disable CAN Controllers.0: Disable, 1: Enable + $EN_DIS +**/ + UINT8 PchCanEnable[2]; + +/** Offset 0x13BC - Reserved **/ - UINT8 Reserved44[6]; + UINT8 Reserved25[4]; /** Offset 0x13C0 - SVID SDID table Poniter. The address of the table of SVID SDID to customize each SVID SDID entry. This is @@ -1958,9 +3294,15 @@ typedef struct { **/ UINT16 SiNumberOfSsidTableEntry; -/** Offset 0x13CA - Reserved +/** Offset 0x13CA - Skip DFX. + Skip DFX. + $EN_DIS +**/ + UINT8 DfxSkipBiosDone; + +/** Offset 0x13CB - Reserved **/ - UINT8 Reserved45[10]; + UINT8 Reserved26[9]; /** Offset 0x13D4 - LogoPixelHeight Address Address of LogoPixelHeight @@ -1974,7 +3316,7 @@ typedef struct { /** Offset 0x13DC - Reserved **/ - UINT8 Reserved46[4]; + UINT8 Reserved27[4]; /** Offset 0x13E0 - Blt Buffer Address Address of Blt buffer @@ -1992,9 +3334,11 @@ typedef struct { **/ UINT8 SkipFspGop; -/** Offset 0x13F1 - Reserved +/** Offset 0x13F1 - Enable/Disable Media Configuration + Enable(Default): Configure Media for use, Disable: Skip Media Configuration + $EN_DIS **/ - UINT8 Reserved47; + UINT8 ConfigureMedia; /** Offset 0x13F2 - Enable/Disable IGFX RenderStandby Enable(Default): Enable IGFX RenderStandby, Disable: Disable IGFX RenderStandby @@ -2002,9 +3346,23 @@ typedef struct { **/ UINT8 RenderStandby; -/** Offset 0x13F3 - Reserved +/** Offset 0x13F3 - Enable/Disable GT Configuration + Enable(Default): Configure GT for use, Disable: Skip GT Configuration + $EN_DIS +**/ + UINT8 ConfigureGT; + +/** Offset 0x13F4 - Enable RC1p GT frequency request to PMA (provided all other conditions are met) + 0(Default)=Disable, 1=Enable + $EN_DIS +**/ + UINT8 RC1pGtFreqEnable; + +/** Offset 0x13F5 - Enable RC1p Media frequency request to PMA (provided all other conditions are met) + 0(Default)=Disable, 1=Enable + $EN_DIS **/ - UINT8 Reserved48[3]; + UINT8 RC1pMediaFreqEnable; /** Offset 0x13F6 - Enable/Disable PavpEnable Enable(Default): Enable PavpEnable, Disable: Disable PavpEnable @@ -2019,9 +3377,21 @@ typedef struct { **/ UINT8 PeiGraphicsPeimInit; -/** Offset 0x13F8 - Reserved +/** Offset 0x13F8 - Enable/Disable IGFX Media Standby + Enable(Default): Enable IGFX Media Standby, Disable: Disable IGFX MediaStandby + $EN_DIS +**/ + UINT8 MediaStandby; + +/** Offset 0x13F9 - Enable/Disable Gfx Workstation + Enable(Default): Is a workstation, Disable: Is not a workstation + $EN_DIS +**/ + UINT8 Dev2IsGfxWorkstation; + +/** Offset 0x13FA - Reserved **/ - UINT8 Reserved49[4]; + UINT8 Reserved28[2]; /** Offset 0x13FC - Intel Graphics VBT (Video BIOS Table) Size Size of Internal Graphics VBT Image @@ -2042,7 +3412,21 @@ typedef struct { /** Offset 0x1402 - Reserved **/ - UINT8 Reserved50[66]; + UINT8 Reserved29[2]; + +/** Offset 0x1404 - HorizontalResolution for PEI Logo + HorizontalResolution from PEIm Gfx for PEI Logo +**/ + UINT32 HorizontalResolution; + +/** Offset 0x1408 - VerticalResolution for PEI Logo + VerticalResolution from PEIm Gfx for PEI Logo +**/ + UINT32 VerticalResolution; + +/** Offset 0x140C - Reserved +**/ + UINT8 Reserved30[56]; /** Offset 0x1444 - Address of PCH_DEVICE_INTERRUPT_CONFIG table. The address of the table of PCH_DEVICE_INTERRUPT_CONFIG. @@ -2076,9 +3460,33 @@ typedef struct { **/ UINT8 TcoIrqEnable; -/** Offset 0x144D - Reserved +/** Offset 0x144D - PMC ADR enable + Enable/disable asynchronous DRAM refresh + $EN_DIS +**/ + UINT8 PmcAdrEn; + +/** Offset 0x144E - PMC ADR timer configuration enable + Enable/disable ADR timer configuration + $EN_DIS +**/ + UINT8 PmcAdrTimerEn; + +/** Offset 0x144F - PMC ADR phase 1 timer value + Enable/disable ADR timer configuration +**/ + UINT8 PmcAdrTimer1Val; + +/** Offset 0x1450 - PMC ADR phase 1 timer multiplier value + Specify the multiplier value for phase 1 ADR timer +**/ + UINT8 PmcAdrMultiplier1Val; + +/** Offset 0x1451 - PMC ADR host reset partition enable + Specify whether PMC should set ADR_RST_STS bit after receiving Reset_Warn_Ack DMI message + $EN_DIS **/ - UINT8 Reserved51[5]; + UINT8 PmcAdrHostPartitionReset; /** Offset 0x1452 - Mask to enable the usage of external V1p05 VR rail in specific S0ix or Sx states Enable External V1P05 Rail in: BIT0:S0i1/S0i2, BIT1:S0i3, BIT2:S3, BIT3:S4, BIT5:S5 @@ -2112,7 +3520,7 @@ typedef struct { /** Offset 0x1459 - Reserved **/ - UINT8 Reserved52; + UINT8 Reserved31; /** Offset 0x145A - External Vnn Voltage Value that will be used in S0ix/Sx states Value is given in 2.5mV increments (0=0mV, 1=2.5mV, 2=5mV...), Default is set to 420 @@ -2173,7 +3581,7 @@ typedef struct { /** Offset 0x1467 - Reserved **/ - UINT8 Reserved53; + UINT8 Reserved32; /** Offset 0x1468 - External V1P05 Icc Max Value Granularity of this setting is 1mA and maximal possible value is 500mA @@ -2213,9 +3621,11 @@ typedef struct { **/ UINT8 PchLegacyIoLowLatency; -/** Offset 0x1472 - Reserved +/** Offset 0x1472 - PCH P2SB + PCH P2SB + $EN_DIS **/ - UINT8 Reserved54; + UINT8 SvTestUnhideP2sb; /** Offset 0x1473 - PCH Unlock SideBand access The SideBand PortID mask for certain end point (e.g. PSFx) will be locked before @@ -2282,9 +3692,19 @@ typedef struct { **/ UINT8 CnviBtAudioOffload; -/** Offset 0x147D - Reserved +/** Offset 0x147D - WWAN Coex + WWAN Coex is getting updated from UEFI variable +**/ + UINT8 CnviWwanCoex; + +/** Offset 0x147E - Skip BtPreInit + BtPreInit can be skipped if SkipBtPreInit is enabled **/ - UINT8 Reserved55[3]; + UINT8 SkipBtPreInit; + +/** Offset 0x147F - Reserved +**/ + UINT8 Reserved33; /** Offset 0x1480 - CNVi RF_RESET pin muxing Select CNVi RF_RESET# pin depending on board routing. LP/P/M: GPP_A8 = 0x2942E408(default) @@ -2299,9 +3719,11 @@ typedef struct { **/ UINT32 CnviClkreqPinMux; -/** Offset 0x1488 - Reserved +/** Offset 0x1488 - CNVi BT Audio OffOffloadInterfaceload + Enable/Disable BT Audio OffloadInterface, Default is ENABLE. 0: DISABLE, 1: ENABLE + $EN_DIS **/ - UINT8 Reserved56; + UINT8 CnviBtAudioOffloadInterface; /** Offset 0x1489 - Enable Device 4 Enable/disable Device 4 @@ -2316,9 +3738,10 @@ typedef struct { **/ UINT8 SkipPamLock; -/** Offset 0x148B - Reserved +/** Offset 0x148B - TCSS LSx OE Enable + Bits 0, 1, ... max Type C Rettimerless port LSx OE enables **/ - UINT8 Reserved57; + UINT8 TcssLsxOe; /** Offset 0x148C - PCH HDA Verb Table Entry Number Number of Entries in Verb Table. @@ -2327,7 +3750,7 @@ typedef struct { /** Offset 0x148D - Reserved **/ - UINT8 Reserved58[3]; + UINT8 Reserved34[3]; /** Offset 0x1490 - PCH HDA Verb Table Pointer Pointer to Array of pointers to Verb Table. @@ -2359,9 +3782,11 @@ typedef struct { **/ UINT8 PchHdaMicPrivacyMode; -/** Offset 0x149C - Reserved +/** Offset 0x149C - HD Audio Microphone Privacy Deglitch + HD Audio Microphone Privacy Deglitch: 0: Disable, 1: Enable + $EN_DIS **/ - UINT8 Reserved59; + UINT8 PchHdaMicPrivacyDeglitch; /** Offset 0x149D - HD Audio Microphone Privacy applied for SoundWire Link number 0 in HW Mode HD Audio Microphone Privacy applied for SoundWire Link number 0 in HW Mode: 0: Disable, 1: Enable @@ -2401,7 +3826,17 @@ typedef struct { /** Offset 0x14A3 - Reserved **/ - UINT8 Reserved60[13]; + UINT8 Reserved35; + +/** Offset 0x14A4 - HD Audio Microphone Privacy Timeout. Indicates the time-out duration to wait before forcing the actual microphone privacy DMA data zeroing. + HD Audio Microphone Privacy Timeout. Indicates the time-out duration to wait before + forcing the actual microphone privacy DMA data zeroing. +**/ + UINT32 PchHdaMicPrivacyTimeout; + +/** Offset 0x14A8 - Reserved +**/ + UINT8 Reserved36[8]; /** Offset 0x14B0 - Pointer to ChipsetInit Binary ChipsetInit Binary Pointer. @@ -2415,7 +3850,49 @@ typedef struct { /** Offset 0x14BC - Reserved **/ - UINT8 Reserved61[36]; + UINT8 Reserved37[4]; + +/** Offset 0x14C0 - Pointer to NPHY Binary + Nphy Binary Pointer. +**/ + UINT64 NphyBinPtr; + +/** Offset 0x14C8 - Length of NPHY Binary + Nphy Binary Length. +**/ + UINT32 NphyBinLen; + +/** Offset 0x14CC - Reserved +**/ + UINT8 Reserved38[4]; + +/** Offset 0x14D0 - Pointer to SYNPS PHY Binary + Synps Binary Pointer. +**/ + UINT64 SynpsPhyBinPtr; + +/** Offset 0x14D8 - Length of SYNPS PHY Binary + Synps Binary Length. +**/ + UINT32 SynpsPhyBinLen; + +/** Offset 0x14DC - Skip setting BIOS_DONE When Fw Update. + When set to TRUE and boot mode is BOOT_ON_FLASH_UPDATE,skip setting BIOS_DONE MSR + at EndofPei. Note: BIOS_DONE MSR should be set in later phase before executing + 3rd party code if SiSkipBiosDoneWhenFwUpdate set to TRUE. + $EN_DIS +**/ + UINT8 SiSkipBiosDoneWhenFwUpdate; + +/** Offset 0x14DD - PMC WDT enable + Enable/disable PMC WDT configuration + $EN_DIS +**/ + UINT8 PmcWdtTimerEn; + +/** Offset 0x14DE - Reserved +**/ + UINT8 Reserved39[2]; } FSP_S_CONFIG; /** Fsp S UPD Configuration diff --git a/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/MemInfoHob.h b/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/MemInfoHob.h index c89cf2cab1e..a6d862368f8 100644 --- a/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/MemInfoHob.h +++ b/src/vendorcode/intel/fsp/fsp2_0/wildcatlake/MemInfoHob.h @@ -312,7 +312,8 @@ typedef struct _PPR_RESULT_COLUMNS_HOB { - DIMM_INFO: Added SerialNumber, TotalWidth and DataWidth - DIMM_INFO: Removed SpdModuleMemoryBusWidth - MFG ID fields: use HOB_MANUFACTURER_ID_CODE instead of UINT16 for easier parsing - + Revision 4: + - Added FailingChannelMask **/ typedef struct { UINT8 Revision; @@ -363,6 +364,7 @@ typedef struct { UINT8 MaxRankCapacity; ///< Maximum possible rank capacity in [GB] UINT16 PprFailingChannelBitMask; ///< PPR failing channel mask BOOLEAN PprTargetedStatus[PPR_REQUEST_MAX]; ///< PPR status of each Targeted PPR request (0 = Targeted PPR was successful, 1 = PPR failed) + UINT8 FailingChannelMask; ///< Limp Home mode failing channel bitmask } MEMORY_INFO_DATA_HOB; /** @@ -387,6 +389,9 @@ typedef struct { PSMI_MEM_INFO PsmiInfo[MAX_TRACE_CACHE_TYPE]; PSMI_MEM_INFO PsmiRegionInfo[MAX_TRACE_REGION]; BOOLEAN MrcBasicMemoryTestPass; + UINT8 Reserved1[3]; // Reserved for alignment + UINT64 BiosPeiMemoryBaseAddress; + UINT64 BiosPeiMemoryLength; } MEMORY_PLATFORM_DATA; typedef struct { diff --git a/tests/Makefile.common b/tests/Makefile.common index a8bb19c4f1f..085e4cffc43 100644 --- a/tests/Makefile.common +++ b/tests/Makefile.common @@ -18,7 +18,7 @@ CMAKE := cmake OBJCOPY ?= objcopy OBJDUMP ?= objdump -TEST_DEFAULT_CONFIG ?= $(top)/configs/config.emulation_qemu_x86_i440fx +TEST_DEFAULT_CONFIG ?= $(top)/configs/config.google_octopus_spi_flash_console TEST_DOTCONFIG := $(testobj)/.config TEST_KCONFIG_AUTOHEADER := $(testobj)/config.src.h TEST_KCONFIG_AUTOCONFIG := $(testobj)/auto.conf @@ -157,7 +157,7 @@ $($(1)-sysobjs): $(testobj)/$(1)/%.o: $$$$*.c $$($(1)-config-file) # Link against Cmocka if not disabled ifeq ($(strip $(filter-out 0 n no,$($(1)-no_test_framework))),) -ifneq ($(USE_SYSTEM_CMOCKA),) +ifneq ($(USE_SYSTEM_CMOCKA),1) $($(1)-objs): TEST_CFLAGS += -I$(cmockasrc)/include $($(1)-bin): TEST_LDFLAGS += -L$(cmockaobj)/src -Wl,-rpath=$(cmockaobj)/src $($(1)-bin): TEST_CFLAGS += -I$(cmockasrc)/include diff --git a/tests/Makefile.mk b/tests/Makefile.mk index f3f122dd38f..9e3f86a1385 100644 --- a/tests/Makefile.mk +++ b/tests/Makefile.mk @@ -149,8 +149,8 @@ clean-junit.xml-unit-tests: ifeq ($(COV),1) coverage-report: lcov -o $(testobj)/tests.info -c -d $(testobj) --exclude '$(testsrc)/*' - genhtml -q -o $(testobj)/$(coverage_dir) -t "coreboot unit tests" \ - -s $(testobj)/tests.info + # TODO: fix inconsistent and corrupt error reports + # genhtml --ignore-errors inconsistent,corrupt -q -o $(testobj)/$(coverage_dir) -t "coreboot unit tests" -s $(testobj)/tests.info clean-coverage-report: rm -Rf $(testobj)/$(coverage_dir) diff --git a/tests/commonlib/list-test.c b/tests/commonlib/list-test.c index 4ca48a468fe..e4dbd8e14a4 100644 --- a/tests/commonlib/list-test.c +++ b/tests/commonlib/list-test.c @@ -1,9 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include +#include #include #include -#include +#include +#include struct test_container { int value; @@ -11,10 +12,40 @@ struct test_container { struct list_node list_node; }; -void test_list_insert_after(void **state) +static void test_list_empty(void **state) +{ + struct list_node head = {}; + struct test_container *node; + + list_for_each(node, head, list_node) { + assert_true(false); + } + + assert_true(list_is_empty(&head)); + assert_null(list_first(&head)); + assert_null(list_last(&head)); + assert_int_equal(0, list_length(&head)); +} + +static void test_list_one_node(void **state) +{ + struct list_node head = {}; + struct test_container c = { .value = 1 }; + + list_insert_after(&c.list_node, &head); + + assert_false(list_is_empty(&head)); + assert_null(list_next(&c.list_node, &head)); + assert_null(list_prev(&c.list_node, &head)); + assert_ptr_equal(&c.list_node, list_first(&head)); + assert_ptr_equal(&c.list_node, list_last(&head)); + assert_int_equal(1, list_length(&head)); +} + +static void test_list_insert_after(void **state) { int i = 0; - struct list_node root = { .prev = NULL, .next = NULL }; + struct list_node head = {}; struct test_container *c1 = (struct test_container *)malloc(sizeof(*c1)); struct test_container *c2 = (struct test_container *)malloc(sizeof(*c2)); struct test_container *c3 = (struct test_container *)malloc(sizeof(*c2)); @@ -29,26 +60,33 @@ void test_list_insert_after(void **state) c2->value = values[1]; c3->value = values[2]; - list_insert_after(&c1->list_node, &root); + list_insert_after(&c1->list_node, &head); list_insert_after(&c2->list_node, &c1->list_node); list_insert_after(&c3->list_node, &c2->list_node); - list_for_each(ptr, root, list_node) { + list_for_each(ptr, head, list_node) { assert_int_equal(values[i], ptr->value); i++; } assert_int_equal(3, i); + assert_int_equal(3, list_length(&head)); + assert_false(list_is_empty(&head)); + + assert_ptr_equal(&c3->list_node, list_next(&c2->list_node, &head)); + assert_ptr_equal(&c1->list_node, list_prev(&c2->list_node, &head)); + assert_ptr_equal(&c1->list_node, list_first(&head)); + assert_ptr_equal(&c3->list_node, list_last(&head)); free(c3); free(c2); free(c1); } -void test_list_insert_before(void **state) +static void test_list_insert_before(void **state) { int i = 0; - struct list_node root = { .prev = NULL, .next = NULL }; + struct list_node head = {}; struct test_container *c1 = (struct test_container *)malloc(sizeof(*c1)); struct test_container *c2 = (struct test_container *)malloc(sizeof(*c2)); struct test_container *c3 = (struct test_container *)malloc(sizeof(*c2)); @@ -63,87 +101,93 @@ void test_list_insert_before(void **state) c2->value = values[1]; c3->value = values[2]; - list_insert_after(&c3->list_node, &root); + list_insert_after(&c3->list_node, &head); list_insert_before(&c2->list_node, &c3->list_node); list_insert_before(&c1->list_node, &c2->list_node); - - list_for_each(ptr, root, list_node) { + list_for_each(ptr, head, list_node) { assert_int_equal(values[i], ptr->value); i++; } assert_int_equal(3, i); + assert_int_equal(3, list_length(&head)); + assert_false(list_is_empty(&head)); free(c3); free(c2); free(c1); } -void test_list_remove(void **state) +static void test_list_insert_before_head(void **state) +{ + struct list_node head = {}; + struct test_container c = {}; + + expect_assert_failure(list_insert_before(&c.list_node, &head)); +} + +static void test_list_remove(void **state) { - struct list_node root = { .prev = NULL, .next = NULL }; + struct list_node head = {}; struct test_container *c1 = (struct test_container *)malloc(sizeof(*c1)); struct test_container *c2 = (struct test_container *)malloc(sizeof(*c2)); - struct test_container *ptr; - int len; - list_insert_after(&c1->list_node, &root); + list_insert_after(&c1->list_node, &head); list_insert_after(&c2->list_node, &c1->list_node); - len = 0; - list_for_each(ptr, root, list_node) { - len++; - } - assert_int_equal(2, len); + assert_int_equal(2, list_length(&head)); list_remove(&c1->list_node); - - len = 0; - list_for_each(ptr, root, list_node) { - len++; - } - assert_int_equal(1, len); + assert_int_equal(1, list_length(&head)); list_remove(&c2->list_node); - len = 0; - list_for_each(ptr, root, list_node) { - len++; - } - assert_int_equal(0, len); + assert_int_equal(0, list_length(&head)); free(c2); free(c1); } -void test_list_append(void **state) +static void test_list_remove_head(void **state) +{ + struct list_node head = {}; + expect_assert_failure(list_remove(&head)); +} + +static void test_list_append(void **state) { size_t idx; struct test_container *node; - struct list_node root = {}; + struct list_node head = {}; struct test_container nodes[] = { {1}, {2}, {3} }; for (idx = 0; idx < ARRAY_SIZE(nodes); ++idx) - list_append(&nodes[idx].list_node, &root); + list_append(&nodes[idx].list_node, &head); idx = 0; - list_for_each(node, root, list_node) { + list_for_each(node, head, list_node) { assert_ptr_equal(node, &nodes[idx]); idx++; } + + assert_int_equal(3, idx); + assert_int_equal(3, list_length(&head)); } int main(void) { const struct CMUnitTest tests[] = { + cmocka_unit_test(test_list_empty), + cmocka_unit_test(test_list_one_node), cmocka_unit_test(test_list_insert_after), cmocka_unit_test(test_list_insert_before), + cmocka_unit_test(test_list_insert_before_head), cmocka_unit_test(test_list_remove), + cmocka_unit_test(test_list_remove_head), cmocka_unit_test(test_list_append), }; - return cb_run_group_tests(tests, NULL, NULL); } diff --git a/tests/include/tests/lib/fmap_config.h b/tests/include/tests/lib/fmap_config.h index 5b3540020b5..690ee19fcae 100644 --- a/tests/include/tests/lib/fmap_config.h +++ b/tests/include/tests/lib/fmap_config.h @@ -8,5 +8,6 @@ * Keeps the build tests from failing since fmap.h needs fmap_config.h */ #define FMAP_SECTION_FLASH_START 0 +#define FMAP_SECTION_FLASH_SIZE 0x1000000 #endif diff --git a/tests/lib/cbfs-lookup-test.c b/tests/lib/cbfs-lookup-test.c index 75628683b60..d6cc5d95a2c 100644 --- a/tests/lib/cbfs-lookup-test.c +++ b/tests/lib/cbfs-lookup-test.c @@ -62,6 +62,14 @@ size_t ulzman(const void *src, size_t srcn, void *dst, size_t dstn) return dstn; } +size_t uzstdn(const void *src, size_t srcn, void *dst, size_t dstn) +{ + check_expected(srcn); + check_expected(dstn); + memcpy(dst, src, dstn); + return dstn; +} + size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn) { check_expected(srcn); diff --git a/tests/lib/cbfs-verification-test.c b/tests/lib/cbfs-verification-test.c index b1a39bcaacb..8abc36c053c 100644 --- a/tests/lib/cbfs-verification-test.c +++ b/tests/lib/cbfs-verification-test.c @@ -52,6 +52,12 @@ size_t ulzman(const void *src, size_t srcn, void *dst, size_t dstn) return 0; } +size_t uzstdn(const void *src, size_t srcn, void *dst, size_t dstn) +{ + fail_msg("Unexpected call to %s", __func__); + return 0; +} + size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn) { fail_msg("Unexpected call to %s", __func__); diff --git a/tests/lib/coreboot_table-test.c b/tests/lib/coreboot_table-test.c index 9547ee07a67..2197b956318 100644 --- a/tests/lib/coreboot_table-test.c +++ b/tests/lib/coreboot_table-test.c @@ -176,6 +176,8 @@ const unsigned int coreboot_minor_revision = 13; const char coreboot_compile_time[] = "13:58:22"; const char coreboot_dmi_date[] = "03/31/2021"; +const uint8_t platform_blob_version[] = "3.2.1"; + const struct bcd_date coreboot_build_date = { .century = 0x20, .year = 0x20, @@ -228,6 +230,18 @@ enum cb_err fill_lb_serial(struct lb_serial *serial) return CB_SUCCESS; } +void lb_string_platform_blob_version(struct lb_header *header) +{ + struct lb_string *rec; + size_t len; + + rec = (struct lb_string *)lb_new_record(header); + rec->tag = LB_TAG_PLATFORM_BLOB_VERSION; + len = sizeof(platform_blob_version); + rec->size = ALIGN_UP(sizeof(*rec) + len, 8); + memcpy(rec->string, platform_blob_version, len); +} + struct cbfs_boot_device cbfs_boot_dev = { .rdev = REGION_DEV_INIT(NULL, 0, 0x1000), .mcache = (void *)0x1000, @@ -464,6 +478,11 @@ static void test_write_tables(void **state) const struct lb_acpi_rsdp *acpi_rsdp = (struct lb_acpi_rsdp *)record; assert_int_equal(ebda_base, acpi_rsdp->rsdp_pointer); break; + case LB_TAG_PLATFORM_BLOB_VERSION: + uint32_t platform_blob_version_size = + ALIGN_UP(sizeof(struct lb_string) + sizeof(platform_blob_version), 8); + assert_int_equal(platform_blob_version_size, record->size); + break; default: fail_msg("Unexpected tag found in record. Tag ID: 0x%x", record->tag); } diff --git a/tests/lib/ux_locales-test.c b/tests/lib/ux_locales-test.c index 4edac5c9d2f..8d643e6e111 100644 --- a/tests/lib/ux_locales-test.c +++ b/tests/lib/ux_locales-test.c @@ -191,7 +191,7 @@ static void test_ux_locales_null_terminated(void **state) #define UX_LOCALES_GET_TEXT_TEST(_msg_id, _lang_id, _expect) \ ((struct CMUnitTest) { \ .name = "test_ux_locales_get_text(msg_id=" #_msg_id ", lang_id=" #_lang_id \ - ", expect=" #_expect ")", \ + ", expect=" _expect ")", \ .test_func = test_ux_locales_get_text, \ .setup_func = setup_default, \ .teardown_func = teardown_unmap, \ diff --git a/util/amdfwtool/amdfwread.c b/util/amdfwtool/amdfwread.c index ddd0bc3fb0a..4dde162cd3c 100644 --- a/util/amdfwtool/amdfwread.c +++ b/util/amdfwtool/amdfwread.c @@ -113,6 +113,9 @@ static int read_psp_directory(FILE *fw, uint32_t offset, uint32_t expected_cooki return 1; } + if (!entries || !num_entries) + return 0; + /* Read the entries */ *num_entries = header->num_entries; *entries = malloc(sizeof(psp_directory_entry) * header->num_entries); @@ -148,6 +151,9 @@ static int read_bios_directory(FILE *fw, uint32_t offset, uint32_t expected_cook return 1; } + if (!entries || !num_entries) + return 0; + /* Read the entries */ *num_entries = header->num_entries; *entries = malloc(sizeof(bios_directory_entry) * header->num_entries); @@ -263,7 +269,7 @@ static int amdfw_bios_dir_walk(FILE *fw, uint32_t bios_offset, uint32_t cookie, size_t num_current_entries = 0; bios_directory_hdr header; uint32_t l2_dir_offset = 0; - uint64_t dir_mode = 0; + uint64_t dir_mode = AMD_ADDR_PHYSICAL; char indent[MAX_INDENTATION_LEN] = {0}; if (read_bios_directory(fw, bios_offset, cookie, &header, @@ -281,7 +287,7 @@ static int amdfw_bios_dir_walk(FILE *fw, uint32_t bios_offset, uint32_t cookie, uint64_t mode = current_entries[i].address_mode; uint64_t addr = current_entries[i].source; - if (dir_mode < 2) + if (dir_mode < AMD_ADDR_REL_TAB) mode = dir_mode; if (type == AMD_BIOS_APOB || type == AMD_BIOS_PSP_SHARED_MEM) @@ -313,6 +319,64 @@ static int amdfw_bios_dir_walk(FILE *fw, uint32_t bios_offset, uint32_t cookie, return 0; } +/* + * Returns the size of the PSP directory. + * + * @param fw File to operate on + * @param psp_offset Relative offset to PSP directory + * @param cookie Expected table cookie + * @param size Where to write the size to + * + * @return 0 on success, or < 0 on error. + */ +static int amdfw_psp_dir_size(FILE *fw, uint32_t psp_offset, uint32_t cookie, uint32_t *size) +{ + psp_directory_header header; + + if (!fw || !size) + return -1; + + if (read_psp_directory(fw, psp_offset, cookie, &header, NULL, NULL) != 0) + return -1; + + if (header.additional_info_fields.version == 1) + *size = header.additional_info_fields_v1.dir_size; + else + *size = header.additional_info_fields.dir_size; + + *size *= TABLE_ALIGNMENT; + return 0; +} + +/* + * Returns the size of the BIOS directory. + * + * @param fw File to operate on + * @param bios_offset Relative offset to BIOS directory + * @param cookie Expected table cookie + * @param size Where to write the size to + * + * @return 0 on success, or < 0 on error. + */ +static int amdfw_bios_dir_size(FILE *fw, uint32_t bios_offset, uint32_t cookie, uint32_t *size) +{ + bios_directory_hdr header; + + if (!fw || !size) + return -1; + + if (read_bios_directory(fw, bios_offset, cookie, &header, NULL, NULL) != 0) + return -1; + + if (header.additional_info_fields.version == 1) + *size = header.additional_info_fields_v1.dir_size; + else + *size = header.additional_info_fields.dir_size; + + *size *= TABLE_ALIGNMENT; + return 0; +} + static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, uint8_t level) { psp_directory_entry *current_entries = NULL; @@ -322,7 +386,7 @@ static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, ui uint32_t bios_dir_offset = 0; uint32_t ish_dir_offset = 0; ish_directory_table ish_dir; - uint64_t dir_mode = 0; + uint64_t dir_mode = AMD_ADDR_PHYSICAL; char indent[MAX_INDENTATION_LEN] = {0}; if (read_psp_directory(fw, psp_offset, cookie, &header, @@ -339,8 +403,9 @@ static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, ui uint32_t type = current_entries[i].type; uint64_t mode = current_entries[i].address_mode; uint64_t addr = current_entries[i].addr; + uint32_t dir_size = 0; - if (dir_mode < 2) + if (dir_mode < AMD_ADDR_REL_TAB) mode = dir_mode; if (type == AMD_PSP_FUSE_CHAIN) @@ -365,6 +430,10 @@ static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, ui l2_dir_offset = relative_offset(psp_offset, addr, mode); printf(" %sPSPL2: Dir 0x%08x\n", indent, l2_dir_offset); + if (amdfw_psp_dir_size(fw, l2_dir_offset, PSPL2_COOKIE, &dir_size) == 0) + printf(" %sPSPL2: Dir [0x%08x-0x%08x)\n", indent, l2_dir_offset, l2_dir_offset + dir_size); + else + printf(" %sPSPL2: Dir @0x%08x\n", indent, l2_dir_offset); amdfw_psp_dir_walk(fw, l2_dir_offset, PSPL2_COOKIE, level + 2); break; @@ -384,13 +453,19 @@ static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, ui } l2_dir_offset = ish_dir.pl2_location; - printf(" %sPSPL2: Dir 0x%08x\n", indent, l2_dir_offset); + if (amdfw_psp_dir_size(fw, l2_dir_offset, PSPL2_COOKIE, &dir_size) == 0) + printf(" %sPSPL2: Dir [0x%08x-0x%08x)\n", indent, l2_dir_offset, l2_dir_offset + dir_size); + else + printf(" %sPSPL2: Dir @0x%08x\n", indent, l2_dir_offset); amdfw_psp_dir_walk(fw, l2_dir_offset, PSPL2_COOKIE, level + 2); break; case AMD_FW_BIOS_TABLE: bios_dir_offset = relative_offset(psp_offset, addr, mode); - printf(" %sBIOSL2: Dir 0x%08x\n", indent, bios_dir_offset); + if (amdfw_bios_dir_size(fw, bios_dir_offset, BHDL2_COOKIE, &dir_size) == 0) + printf(" %sBIOSL2: Dir [0x%08x-0x%08x)\n", indent, bios_dir_offset, bios_dir_offset + dir_size); + else + printf(" %sBIOSL2: Dir @0x%08x\n", indent, bios_dir_offset); amdfw_bios_dir_walk(fw, bios_dir_offset, BHDL2_COOKIE, level + 2); break; @@ -406,7 +481,7 @@ static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, ui static int list_amdfw_psp_dir(FILE *fw, const embedded_firmware *fw_header) { - uint32_t psp_offset = 0; + uint32_t psp_offset = 0, dir_size = 0; /* 0xffffffff or 0x00000000 indicates that the offset is in new_psp_directory */ if (fw_header->psp_directory != 0xffffffff && fw_header->psp_directory != 0x00000000) @@ -414,18 +489,28 @@ static int list_amdfw_psp_dir(FILE *fw, const embedded_firmware *fw_header) else psp_offset = fw_header->new_psp_directory; - printf("PSPL1: Dir 0x%08x\n", psp_offset); + if (amdfw_psp_dir_size(fw, psp_offset, PSP_COOKIE, &dir_size) == 0) + printf("PSPL1: Dir [0x%08x-0x%08x)\n", psp_offset, psp_offset + dir_size); + else + printf("PSPL1: Dir @0x%08x\n", psp_offset); + amdfw_psp_dir_walk(fw, psp_offset, PSP_COOKIE, 0); return 0; } static int list_amdfw_bios_dir(FILE *fw, const embedded_firmware *fw_header) { + uint32_t dir_size = 0; + /* 0xffffffff or 0x00000000 implies that the SoC uses recovery A/B layout. Only BIOS L2 directory is present and that too as part of PSP L2 directory. */ if (fw_header->bios3_entry != 0xffffffff && fw_header->bios3_entry != 0x00000000) { - printf("BIOSL1: Dir 0x%08x\n", fw_header->bios3_entry); + if (amdfw_psp_dir_size(fw, fw_header->bios3_entry, BHD_COOKIE, &dir_size) == 0) + printf("BIOSL1: Dir [0x%08x-0x%08x)\n", fw_header->bios3_entry, fw_header->bios3_entry + dir_size); + else + printf("BIOSL1: Dir @0x%08x\n", fw_header->bios3_entry); + amdfw_bios_dir_walk(fw, fw_header->bios3_entry, BHD_COOKIE, 0); } return 0; diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c index 9e9ada79a79..af24697bca8 100644 --- a/util/amdfwtool/amdfwtool.c +++ b/util/amdfwtool/amdfwtool.c @@ -255,7 +255,6 @@ amd_fw_entry amd_psp_fw_table[] = { { .type = AMD_FW_AMF_WLAN, .inst = 2, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_AMF_WLAN, .inst = 3, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_AMF_MFD, .level = PSP_LVL2 | PSP_LVL2_AB }, - { .type = AMD_TA_IKEK, .level = PSP_BOTH | PSP_LVL2_AB, .skip_hashing = true }, { .type = AMD_FW_MPCCX, .subprog = 0, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_MPCCX, .subprog = 1, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_LSDMA, .level = PSP_LVL2 | PSP_LVL2_AB }, @@ -267,7 +266,6 @@ amd_fw_entry amd_psp_fw_table[] = { { .type = AMD_FW_GFXIMU_0, .subprog = 1, .level = PSP_BOTH | PSP_LVL2_AB }, { .type = AMD_FW_GFXIMU_1, .subprog = 0, .level = PSP_BOTH | PSP_LVL2_AB }, { .type = AMD_FW_GFXIMU_1, .subprog = 1, .level = PSP_BOTH | PSP_LVL2_AB }, - { .type = AMD_FW_GFXIMU_2, .level = PSP_BOTH | PSP_LVL2_AB }, { .type = AMD_FW_SRAM_FW_EXT, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_UMSMU, .level = PSP_LVL2 | PSP_LVL2_AB }, { .type = AMD_FW_S3IMG, .level = PSP_LVL2 | PSP_LVL2_AB }, @@ -1090,7 +1088,7 @@ static void integrate_psp_firmwares(context *ctx, pspdir->entries[count].rsvd = 0; pspdir->entries[count].size = 0xFFFFFFFF; pspdir->entries[count].addr = fw_table[i].other; - pspdir->entries[count].address_mode = 0; + pspdir->entries[count].address_mode = fw_table[i].other >> 62; count++; } else if (fw_table[i].type == AMD_FW_PSP_NVRAM || fw_table[i].type == AMD_RPMC_NVRAM) { diff --git a/util/amdfwtool/amdfwtool.h b/util/amdfwtool/amdfwtool.h index dbc1c4adc0a..fe3f72b85d6 100644 --- a/util/amdfwtool/amdfwtool.h +++ b/util/amdfwtool/amdfwtool.h @@ -118,7 +118,6 @@ typedef enum _amd_fw_type { AMD_FW_MINIMSMU = 0x9a, AMD_FW_GFXIMU_0 = 0x9b, AMD_FW_GFXIMU_1 = 0x9c, - AMD_FW_GFXIMU_2 = 0x9d, AMD_FW_SRAM_FW_EXT = 0x9d, AMD_FW_UMSMU = 0xa2, AMD_FW_S3IMG = 0xa0, diff --git a/util/amdfwtool/data_parse.c b/util/amdfwtool/data_parse.c index 13922d63c9f..2ea37efd671 100644 --- a/util/amdfwtool/data_parse.c +++ b/util/amdfwtool/data_parse.c @@ -407,10 +407,6 @@ static uint8_t find_register_fw_filename_psp_dir(char *fw_name, char *filename, fw_type = AMD_FW_GFXIMU_1; instance = 0; subprog = 1; - } else if (strcmp(fw_name, "PSP_GFX_IMMU_FILE_2") == 0) { - fw_type = AMD_FW_GFXIMU_2; - instance = 0; - subprog = 0; } else if (strcmp(fw_name, "MINIMSMU_FILE_INS1") == 0) { fw_type = AMD_FW_MINIMSMU; instance = 1; diff --git a/util/autoport/azalia.go b/util/autoport/azalia.go index a7c8b7253b6..e5681ae9dcb 100644 --- a/util/autoport/azalia.go +++ b/util/autoport/azalia.go @@ -11,7 +11,7 @@ type azalia struct { func (i azalia) Scan(ctx Context, addr PCIDevData) { /* FIXME: Rework to output new verb table format, or better yet use hda-decoder to avoid duplicating functionality */ - KconfigBool["AZALIA_USE_LEGACY_VERB_TABLE"] = true + KconfigSelect["AZALIA_USE_LEGACY_VERB_TABLE"] = "" az := Create(ctx, "hda_verb.c") defer az.Close() @@ -65,7 +65,9 @@ func init() { RegisterPCI(0x8086, 0x1c20, azalia{}) /* C216/ivybridge */ RegisterPCI(0x8086, 0x1e20, azalia{}) - /* Lynx Point */ + /* Lynx Point (8 Series PCH) */ RegisterPCI(0x8086, 0x8c20, azalia{}) RegisterPCI(0x8086, 0x9c20, azalia{}) + /* Lynx Point Refresh (9 Series PCH) */ + RegisterPCI(0x8086, 0x8ca0, azalia{}) } diff --git a/util/autoport/bd82x6x.go b/util/autoport/bd82x6x.go index a94b359b513..919c043d07a 100644 --- a/util/autoport/bd82x6x.go +++ b/util/autoport/bd82x6x.go @@ -62,8 +62,8 @@ func (b bd82x6x) Scan(ctx Context, addr PCIDevData) { inteltool := ctx.InfoSource.GetInteltool() GPIO(ctx, inteltool) - KconfigBool["SOUTHBRIDGE_INTEL_"+b.variant] = true - KconfigBool["SERIRQ_CONTINUOUS_MODE"] = true + KconfigSelect["SOUTHBRIDGE_INTEL_"+b.variant] = "" + KconfigSelect["SERIRQ_CONTINUOUS_MODE"] = "" KconfigInt["USBDEBUG_HCD_INDEX"] = 2 KconfigComment["USBDEBUG_HCD_INDEX"] = "FIXME: check this" dmi := ctx.InfoSource.GetDMI() diff --git a/util/autoport/ec_fixme.go b/util/autoport/ec_fixme.go index e0a6554016e..bdb29660772 100644 --- a/util/autoport/ec_fixme.go +++ b/util/autoport/ec_fixme.go @@ -55,12 +55,12 @@ Method(_PTS,1) MainboardInit += ` printk(BIOS_DEBUG, "Replaying EC dump ..."); for (i = 0; i < 256; i++) - ec_write (i, dmp[i]); + ec_write(i, dmp[i]); printk(BIOS_DEBUG, "done\n"); } ` - KconfigBool["EC_ACPI"] = true + KconfigSelect["EC_ACPI"] = "" si := Create(ctx, "acpi/superio.asl") defer si.Close() diff --git a/util/autoport/ec_lenovo.go b/util/autoport/ec_lenovo.go index 38257d0edab..267b64f6f55 100644 --- a/util/autoport/ec_lenovo.go +++ b/util/autoport/ec_lenovo.go @@ -149,8 +149,8 @@ void mainboard_smi_sleep(u8 slp_typ) Add_SPDX(ec, ASL, GPL2_only) ec.WriteString("#include \n") - KconfigBool["EC_LENOVO_PMH7"] = true - KconfigBool["EC_LENOVO_H8"] = true + KconfigSelect["EC_LENOVO_PMH7"] = "" + KconfigSelect["EC_LENOVO_H8"] = "" pmh := DevTreeNode{ Chip: "ec/lenovo/pmh7", diff --git a/util/autoport/go.mod b/util/autoport/go.mod index 55a89cc9e12..dac59c12850 100644 --- a/util/autoport/go.mod +++ b/util/autoport/go.mod @@ -1 +1,2 @@ module autoport +go 1.18 diff --git a/util/autoport/haswell.go b/util/autoport/haswell.go index 668771b7543..f4f331e0365 100644 --- a/util/autoport/haswell.go +++ b/util/autoport/haswell.go @@ -101,9 +101,9 @@ func (i haswellmc) Scan(ctx Context, addr PCIDevData) { PutPCIDev(addr, "Host bridge") - KconfigBool["NORTHBRIDGE_INTEL_HASWELL"] = true - KconfigBool["HAVE_ACPI_TABLES"] = true - KconfigBool["HAVE_ACPI_RESUME"] = true + KconfigSelect["NORTHBRIDGE_INTEL_HASWELL"] = "" + KconfigSelect["HAVE_ACPI_TABLES"] = "" + KconfigSelect["HAVE_ACPI_RESUME"] = "" DSDTIncludes = append(DSDTIncludes, DSDTInclude{ File: "cpu/intel/common/acpi/cpu.asl", diff --git a/util/autoport/lynxpoint.go b/util/autoport/lynxpoint.go index 899736ef228..ffb955d2295 100644 --- a/util/autoport/lynxpoint.go +++ b/util/autoport/lynxpoint.go @@ -9,6 +9,7 @@ const ( LYNX_POINT_DESKTOP LYNX_POINT_SERVER LYNX_POINT_ULT + LYNX_POINT_REFRESH ) type lynxpoint struct { @@ -143,11 +144,11 @@ func (b lynxpoint) Scan(ctx Context, addr PCIDevData) { GPIO(ctx, inteltool) } - KconfigBool["SOUTHBRIDGE_INTEL_LYNXPOINT"] = true + KconfigSelect["SOUTHBRIDGE_INTEL_LYNXPOINT"] = "" if isULT { - KconfigBool["INTEL_LYNXPOINT_LP"] = true + KconfigSelect["INTEL_LYNXPOINT_LP"] = "" } - KconfigBool["SERIRQ_CONTINUOUS_MODE"] = true + KconfigSelect["SERIRQ_CONTINUOUS_MODE"] = "" if isULT { KconfigInt["USBDEBUG_HCD_INDEX"] = 1 } else { @@ -161,6 +162,10 @@ func (b lynxpoint) Scan(ctx Context, addr PCIDevData) { ich9GetFlashSize(ctx) } + if (b.variant == LYNX_POINT_REFRESH) { + KconfigSelect["USE_BROADWELL_MRC"] = "!USE_NATIVE_RAMINIT" + } + FADT := ctx.InfoSource.GetACPI()["FACP"] sp0dtle_data := (inteltool.IOBP[0xea002750] >> 24) & 0xf @@ -393,12 +398,14 @@ const struct usb3_port_config mainboard_usb3_ports[MAX_USB3_PORTS] = { func init() { for _, id := range []uint16{ + /* Lynx Point (8 Series PCH) */ 0x8c41, 0x8c49, 0x8c4b, 0x8c4f, } { RegisterPCI(0x8086, uint16(id), lynxpoint{variant: LYNX_POINT_MOBILE}) } for _, id := range []uint16{ + /* Lynx Point (8 Series PCH) */ 0x8c42, 0x8c44, 0x8c46, 0x8c4a, 0x8c4c, 0x8c4e, 0x8c50, 0x8c5c, } { @@ -417,52 +424,78 @@ func init() { RegisterPCI(0x8086, uint16(id), lynxpoint{variant: LYNX_POINT_ULT}) } + for _, id := range []uint16{ + /* Lynx Point Refresh (9 Series PCH) */ + 0x8cc1, 0x8cc2, 0x8cc3, 0x8cc4, 0x8cc6, + } { + RegisterPCI(0x8086, uint16(id), lynxpoint{variant: LYNX_POINT_REFRESH}) + } + /* PCIe bridge */ for _, id := range []uint16{ + /* Lynx Point (8 Series PCH) */ 0x8c10, 0x8c12, 0x8c14, 0x8c16, 0x8c18, 0x8c1a, 0x8c1c, 0x8c1e, + /* Lynx Point LP */ 0x9c10, 0x9c12, 0x9c14, 0x9c16, 0x9c18, 0x9c1a, + /* Lynx Point Refresh (9 Series PCH) */ + 0x8c90, 0x8c92, 0x8c94, 0x8c96, 0x8c98, 0x8c9a, 0x8c9c, 0x8c9e, } { RegisterPCI(0x8086, id, GenericPCI{}) } /* SMBus controller */ - RegisterPCI(0x8086, 0x8c22, GenericPCI{MissingParent: "smbus"}) - RegisterPCI(0x8086, 0x9c22, GenericPCI{MissingParent: "smbus"}) + RegisterPCI(0x8086, 0x8c22, GenericPCI{MissingParent: "smbus"}) /* Lynx Point (8 Series PCH) */ + RegisterPCI(0x8086, 0x9c22, GenericPCI{MissingParent: "smbus"}) /* Lynx Point LP */ + RegisterPCI(0x8086, 0x8ca2, GenericPCI{MissingParent: "smbus"}) /* Lynx Point Refresh (9 Series PCH) */ /* SATA */ for _, id := range []uint16{ + /* Lynx Point (8 Series PCH) */ 0x8c00, 0x8c02, 0x8c04, 0x8c06, 0x8c08, 0x8c0e, 0x8c01, 0x8c03, 0x8c05, 0x8c07, 0x8c09, 0x8c0f, + /* Lynx Point LP */ 0x9c03, 0x9c05, 0x9c07, 0x9c0f, + /* Lynx Point Refresh (9 Series PCH) */ + 0x8c80, 0x8c82, 0x8c84, 0x8c86, 0x8c88, 0x8c8e, + 0x8c81, 0x8c83, 0x8c85, 0x8c87, 0x8c89, 0x8c8f, } { RegisterPCI(0x8086, id, GenericPCI{}) } /* EHCI */ for _, id := range []uint16{ - 0x9c26, 0x8c26, 0x8c2d, + 0x8c26, 0x8c2d, /* Lynx Point (8 Series PCH) */ + 0x9c26, /* Lynx Point LP */ + 0x8ca6, 0x8cad, /* Lynx Point Refresh (9 Series PCH) */ } { RegisterPCI(0x8086, id, GenericPCI{}) } /* XHCI */ - RegisterPCI(0x8086, 0x8c31, GenericPCI{}) - RegisterPCI(0x8086, 0x9c31, GenericPCI{}) + RegisterPCI(0x8086, 0x8c31, GenericPCI{}) /* Lynx Point (8 Series PCH) */ + RegisterPCI(0x8086, 0x9c31, GenericPCI{}) /* Lynx Point LP */ + RegisterPCI(0x8086, 0x8cb1, GenericPCI{}) /* Lynx Point Refresh (9 Series PCH) */ /* ME and children */ for _, id := range []uint16{ + /* Lynx Point (8 Series PCH) */ 0x8c3a, 0x8c3b, 0x8c3c, 0x8c3d, + /* Lynx Point LP */ 0x9c3a, 0x9c3b, 0x9c3c, 0x9c3d, + /* Lynx Point Refresh (9 Series PCH) */ + 0x8cba, 0x8cbb, 0x8cbc, 0x8cbd, } { RegisterPCI(0x8086, id, GenericPCI{}) } /* Ethernet */ - RegisterPCI(0x8086, 0x8c33, GenericPCI{}) + RegisterPCI(0x8086, 0x8c33, GenericPCI{}) /* Lynx Point (8 Series PCH) */ + RegisterPCI(0x8086, 0x8cb3, GenericPCI{}) /* Lynx Point Refresh (9 Series PCH) */ /* Thermal */ - RegisterPCI(0x8086, 0x8c24, GenericPCI{}) - RegisterPCI(0x8086, 0x9c24, GenericPCI{}) + RegisterPCI(0x8086, 0x8c24, GenericPCI{}) /* Lynx Point (8 Series PCH) */ + RegisterPCI(0x8086, 0x9c24, GenericPCI{}) /* Lynx Point LP */ + RegisterPCI(0x8086, 0x8ca4, GenericPCI{}) /* Lynx Point Refresh (9 Series PCH) */ /* LAN Controller on LP PCH (if EEPROM has 0x0000/0xffff in DID) */ RegisterPCI(0x8086, 0x155a, GenericPCI{}) diff --git a/util/autoport/main.go b/util/autoport/main.go index 1246e3277cd..1718b4f24de 100644 --- a/util/autoport/main.go +++ b/util/autoport/main.go @@ -130,6 +130,7 @@ var KconfigComment map[string]string = map[string]string{} var KconfigString map[string]string = map[string]string{} var KconfigHex map[string]uint32 = map[string]uint32{} var KconfigInt map[string]int = map[string]int{} +var KconfigSelect map[string]string = map[string]string{} var ROMSizeKB = 0 var ROMProtocol = "" var FlashROMSupport = "" @@ -572,6 +573,23 @@ func makeComment(name string) string { return " # " + cmt } +func makeSelect(name string) string { + condition, ok := KconfigSelect[name] + if !ok || condition == "" { + return name + makeComment(name) + } + return name + " if " + condition + makeComment(name) +} + +func getSortedKeys[T any](strMap map[string]T) []string { + keys := []string{} + for k, _ := range strMap { + keys = append(keys, k) + } + sort.Strings(keys) + return keys +} + func makeKconfig(ctx Context) { kc := Create(ctx, "Kconfig") defer kc.Close() @@ -580,44 +598,21 @@ func makeKconfig(ctx Context) { fmt.Fprintf(kc, "if %s\n\n", ctx.KconfigName) fmt.Fprintf(kc, "config BOARD_SPECIFIC_OPTIONS\n\tdef_bool y\n") - keys := []string{} - for name, val := range KconfigBool { - if val { - keys = append(keys, name) - } - } - - sort.Strings(keys) - - for _, name := range keys { - fmt.Fprintf(kc, "\tselect %s%s\n", name, makeComment(name)) - } - keys = nil - for name, val := range KconfigBool { - if !val { - keys = append(keys, name) - } + for _, name := range getSortedKeys(KconfigSelect) { + fmt.Fprintf(kc, "\tselect %s\n", makeSelect(name)) } - sort.Strings(keys) - - for _, name := range keys { + for _, name := range getSortedKeys(KconfigBool) { + var mapper map[bool]rune = map[bool]rune{false: 'n', true: 'y'} fmt.Fprintf(kc, ` config %s%s bool - default n -`, name, makeComment(name)) - } - - keys = nil - for name, _ := range KconfigString { - keys = append(keys, name) + default %c +`, name, makeComment(name), mapper[KconfigBool[name]]) } - sort.Strings(keys) - - for _, name := range keys { + for _, name := range getSortedKeys(KconfigString) { fmt.Fprintf(kc, ` config %s%s string @@ -625,14 +620,7 @@ config %s%s `, name, makeComment(name), KconfigString[name]) } - keys = nil - for name, _ := range KconfigHex { - keys = append(keys, name) - } - - sort.Strings(keys) - - for _, name := range keys { + for _, name := range getSortedKeys(KconfigHex) { fmt.Fprintf(kc, ` config %s%s hex @@ -640,14 +628,7 @@ config %s%s `, name, makeComment(name), KconfigHex[name]) } - keys = nil - for name, _ := range KconfigInt { - keys = append(keys, name) - } - - sort.Strings(keys) - - for _, name := range keys { + for _, name := range getSortedKeys(KconfigInt) { fmt.Fprintf(kc, ` config %s%s int @@ -742,7 +723,7 @@ func main() { } if dmi.IsLaptop { - KconfigBool["SYSTEM_TYPE_LAPTOP"] = true + KconfigSelect["SYSTEM_TYPE_LAPTOP"] = "" } ctx.SaneVendor = sanitize(ctx.Vendor) for { @@ -767,7 +748,7 @@ func main() { ScanRoot(ctx) if IGDEnabled { - KconfigBool["MAINBOARD_HAS_LIBGFXINIT"] = true + KconfigSelect["MAINBOARD_HAS_LIBGFXINIT"] = "" KconfigComment["MAINBOARD_HAS_LIBGFXINIT"] = "FIXME: check this" AddRAMStageFile("gma-mainboard.ads", "CONFIG_MAINBOARD_USE_LIBGFXINIT") } @@ -851,10 +832,10 @@ func main() { } if ROMSizeKB == 0 { - KconfigBool["BOARD_ROMSIZE_KB_2048"] = true + KconfigSelect["BOARD_ROMSIZE_KB_2048"] = "" KconfigComment["BOARD_ROMSIZE_KB_2048"] = "FIXME: correct this" } else { - KconfigBool[fmt.Sprintf("BOARD_ROMSIZE_KB_%d", ROMSizeKB)] = true + KconfigSelect[fmt.Sprintf("BOARD_ROMSIZE_KB_%d", ROMSizeKB)] = "" } makeKconfig(ctx) diff --git a/util/autoport/rce823.go b/util/autoport/rce823.go index 7c921093f4a..20fab4a33d5 100644 --- a/util/autoport/rce823.go +++ b/util/autoport/rce823.go @@ -30,7 +30,7 @@ func (r rce823) Scan(ctx Context, addr PCIDevData) { PutPCIChip(addr, cur) } PutPCIDev(addr, "Ricoh SD card reader") - KconfigBool["DRIVERS_RICOH_RCE822"] = true + KconfigSelect["DRIVERS_RICOH_RCE822"] = "" } func init() { diff --git a/util/autoport/sandybridge.go b/util/autoport/sandybridge.go index 552bd66d481..b479bfe7394 100644 --- a/util/autoport/sandybridge.go +++ b/util/autoport/sandybridge.go @@ -62,11 +62,11 @@ func (i sandybridgemc) Scan(ctx Context, addr PCIDevData) { PutPCIDev(addr, "") /* FIXME:XX some configs are unsupported. */ - KconfigBool["NORTHBRIDGE_INTEL_SANDYBRIDGE"] = true - KconfigBool["USE_NATIVE_RAMINIT"] = true - KconfigBool["INTEL_INT15"] = true - KconfigBool["HAVE_ACPI_TABLES"] = true - KconfigBool["HAVE_ACPI_RESUME"] = true + KconfigSelect["NORTHBRIDGE_INTEL_SANDYBRIDGE"] = "" + KconfigSelect["USE_NATIVE_RAMINIT"] = "" + KconfigSelect["INTEL_INT15"] = "" + KconfigSelect["HAVE_ACPI_TABLES"] = "" + KconfigSelect["HAVE_ACPI_RESUME"] = "" DSDTIncludes = append(DSDTIncludes, DSDTInclude{ File: "cpu/intel/common/acpi/cpu.asl", diff --git a/util/cbfstool/Makefile.mk b/util/cbfstool/Makefile.mk index 8577874044e..d3f07f97773 100644 --- a/util/cbfstool/Makefile.mk +++ b/util/cbfstool/Makefile.mk @@ -12,6 +12,34 @@ compressionobj += lzma.o compressionobj += LzFind.o compressionobj += LzmaDec.o compressionobj += LzmaEnc.o +# ZSTD +# common +compressionobj += debug.o +compressionobj += entropy_common.o +compressionobj += error_private.o +compressionobj += fse_decompress.o +compressionobj += zstd_common.o +# compress +compressionobj += fse_compress.o +compressionobj += hist.o +compressionobj += huf_compress.o +compressionobj += zstd_compress.o +compressionobj += zstd_compress_literals.o +compressionobj += zstd_compress_sequences.o +compressionobj += zstd_compress_superblock.o +compressionobj += zstd_double_fast.o +compressionobj += zstd_fast.o +compressionobj += zstd_lazy.o +compressionobj += zstd_ldm.o +compressionobj += zstd_preSplit.o +compressionobj += zstd_opt.o +# xxhash.o Already included for LZ4 +# decompress +compressionobj += huf_decompress.o +compressionobj += zstd_ddict.o +compressionobj += zstd_decompress_block.o +compressionobj += zstd_decompress.o +#compressionobj += huf_decomppress_amd64.o cbfsobj := cbfsobj += cbfstool.o @@ -132,6 +160,7 @@ TOOLCPPFLAGS += -I$(VBOOT_SOURCE)/host/lib/include # have right now. TOOLCPPFLAGS += -I$(top)/src TOOLCPPFLAGS += -I$(top)/src/vendorcode/intel/edk2/uefi_2.4/MdePkg/Include +TOOLCPPFLAGS += -I$(top)/src/commonlib/bsd/zstd/ TOOLLDFLAGS ?= @@ -147,6 +176,7 @@ TOOLCFLAGS+=-std=c11 endif LZ4CFLAGS ?= -Wno-strict-prototypes +ZSTDCPPFLAGS ?= -DZSTD_DISABLE_ASM=1 VBOOT_HOSTLIB = $(VBOOT_HOST_BUILD)/libvboot_host.a @@ -189,6 +219,10 @@ $(objutil)/cbfstool/%.o: $(top)/src/commonlib/bsd/%.c printf " HOSTCC $(subst $(objutil)/,,$(@))\n" $(HOSTCC) $(TOOLCPPFLAGS) $(TOOLCFLAGS) $(HOSTCFLAGS) -c -o $@ $< +$(objutil)/cbfstool/%.o: $(top)/src/commonlib/bsd/zstd/*/%.c + printf " HOSTCC $(subst $(objutil)/,,$(@))\n" + $(HOSTCC) $(TOOLCPPFLAGS) $(TOOLCFLAGS) $(HOSTCFLAGS) $(ZSTDCPPFLAGS) -c -o $@ $< + $(objutil)/cbfstool/%.o: $(top)/util/cbfstool/lz4/lib/%.c printf " HOSTCC $(subst $(objutil)/,,$(@))\n" $(HOSTCC) $(TOOLCPPFLAGS) $(TOOLCFLAGS) $(HOSTCFLAGS) $(LZ4CFLAGS) -c -o $@ $< diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h index 3336e08930d..cb903b1ba3e 100644 --- a/util/cbfstool/cbfs.h +++ b/util/cbfstool/cbfs.h @@ -25,6 +25,7 @@ static const struct typedesc_t types_cbfs_compression[] = { {CBFS_COMPRESS_NONE, "none"}, {CBFS_COMPRESS_LZMA, "LZMA"}, {CBFS_COMPRESS_LZ4, "LZ4"}, + {CBFS_COMPRESS_ZSTD, "ZSTD"}, {0, NULL}, }; diff --git a/util/cbfstool/cbfs_sections.h b/util/cbfstool/cbfs_sections.h index 99a4761b644..c3479bbfd29 100644 --- a/util/cbfstool/cbfs_sections.h +++ b/util/cbfstool/cbfs_sections.h @@ -10,7 +10,9 @@ #define SECTION_NAME_FMAP "FMAP" #define SECTION_NAME_PRIMARY_CBFS "COREBOOT" +#define SECTION_NAME_TOPSWAP_CBFS "COREBOOT_TS" #define SECTION_NAME_BOOTBLOCK "BOOTBLOCK" +#define SECTION_NAME_TOPSWAP "TOPSWAP" #define SECTION_ANNOTATION_CBFS "CBFS" diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c index 1b9931063e0..68dbd32984d 100644 --- a/util/cbfstool/cbfstool.c +++ b/util/cbfstool/cbfstool.c @@ -14,7 +14,7 @@ #include "cbfs_sections.h" #include "elfparsing.h" #include "partitioned_file.h" -#include "lz4/lib/xxhash.h" +#include "lz4/lib/lz4_xxhash.h" #include #include #include @@ -135,6 +135,18 @@ struct mh_cache { bool initialized; }; +static bool is_main_cbfs_region(const char *region_name) +{ + return strcmp(region_name, SECTION_NAME_PRIMARY_CBFS) == 0 || + strcmp(region_name, SECTION_NAME_TOPSWAP_CBFS) == 0; +} + +static bool is_topswap_region(const char *region_name) +{ + return strcmp(region_name, SECTION_NAME_TOPSWAP_CBFS) == 0 || + strcmp(region_name, SECTION_NAME_TOPSWAP) == 0; +} + static struct mh_cache *get_mh_cache(void) { static struct mh_cache mhc; @@ -148,22 +160,24 @@ static struct mh_cache *get_mh_cache(void) if (!fmap) goto no_metadata_hash; + const char *bootblock_region = SECTION_NAME_BOOTBLOCK; + if (is_topswap_region(param.region_name)) + bootblock_region = SECTION_NAME_TOPSWAP; + /* Find the metadata_hash container. If there is a "BOOTBLOCK" FMAP section, it's there. If not, it's a normal file in the primary CBFS section. */ size_t offset, size; struct buffer buffer; - if (fmap_find_area(fmap, SECTION_NAME_BOOTBLOCK)) { - if (!partitioned_file_read_region(&buffer, param.image_file, - SECTION_NAME_BOOTBLOCK)) + if (fmap_find_area(fmap, bootblock_region)) { + if (!partitioned_file_read_region(&buffer, param.image_file, bootblock_region)) goto no_metadata_hash; - mhc.region = SECTION_NAME_BOOTBLOCK; + mhc.region = bootblock_region; offset = 0; size = buffer.size; } else { struct cbfs_image cbfs; struct cbfs_file *mh_container; - if (!partitioned_file_read_region(&buffer, param.image_file, - SECTION_NAME_PRIMARY_CBFS)) + if (!partitioned_file_read_region(&buffer, param.image_file, SECTION_NAME_PRIMARY_CBFS)) goto no_metadata_hash; mhc.region = SECTION_NAME_PRIMARY_CBFS; if (cbfs_image_from_buffer(&cbfs, &buffer, param.headeroffset)) @@ -245,7 +259,7 @@ static int update_anchor(struct mh_cache *mhc, uint8_t *fmap_hash) will recalculate and update the metadata hash in the bootblock if needed. */ static int maybe_update_metadata_hash(struct cbfs_image *cbfs) { - if (strcmp(param.region_name, SECTION_NAME_PRIMARY_CBFS)) + if (!is_main_cbfs_region(param.region_name)) return 0; /* Metadata hash only embedded in primary CBFS. */ struct mh_cache *mhc = get_mh_cache(); @@ -268,6 +282,7 @@ static int maybe_update_metadata_hash(struct cbfs_image *cbfs) static int maybe_update_fmap_hash(void) { if (strcmp(param.region_name, SECTION_NAME_BOOTBLOCK) && + strcmp(param.region_name, SECTION_NAME_TOPSWAP) && strcmp(param.region_name, SECTION_NAME_FMAP) && param.type != CBFS_TYPE_BOOTBLOCK && param.type != CBFS_TYPE_AMDFW) @@ -1603,7 +1618,7 @@ static int cbfs_print(void) vb2_digest_size(real_hash.algo)); printf("[METADATA HASH]\t%s:%s", vb2_get_hash_algorithm_name(real_hash.algo), hash_str); - if (!strcmp(param.region_name, SECTION_NAME_PRIMARY_CBFS)) { + if (is_main_cbfs_region(param.region_name)) { if (!memcmp(mhc->cbfs_hash.raw, real_hash.raw, vb2_digest_size(real_hash.algo))) { printf(":valid"); @@ -2364,6 +2379,10 @@ int main(int argc, char **argv) strcpy(region_name_scratch, param.region_name); param.region_name = strtok(region_name_scratch, ","); for (unsigned region = 0; region < num_regions; ++region) { + // Reset metadata cache in case region uses anchor from a different + // location. + get_mh_cache()->initialized = false; + if (!param.region_name) { ERROR("Encountered illegal degenerate region name in -r list\n"); ERROR("The image will be left unmodified.\n"); @@ -2371,8 +2390,7 @@ int main(int argc, char **argv) return 1; } - if (strcmp(param.region_name, SECTION_NAME_PRIMARY_CBFS) - == 0) + if (is_main_cbfs_region(param.region_name)) seen_primary_cbfs = true; param.image_region = image_regions + region; diff --git a/util/cbfstool/compress.c b/util/cbfstool/compress.c index 96df1a74991..d2cc5dd6b2a 100644 --- a/util/cbfstool/compress.c +++ b/util/cbfstool/compress.c @@ -6,9 +6,11 @@ #include #include "common.h" #include "lz4/lib/lz4frame.h" +#include #include -static int lz4_compress(char *in, int in_len, char *out, int *out_len) +static int +lz4_compress(char *in, int in_len, char *out, int *out_len) { LZ4F_preferences_t prefs = { .compressionLevel = 20, @@ -53,6 +55,52 @@ static int lzma_decompress(char *in, int in_len, char *out, unused int out_len, { return do_lzma_uncompress(out, out_len, in, in_len, actual_size); } + +static int zstd_compress(char *in, int in_len, char *out, int *out_len) +{ + size_t worst_size = ZSTD_compressBound(in_len); + size_t ret; + + void *bounce = malloc(worst_size); + if (!bounce) + return -1; + ret = ZSTD_compress(bounce, worst_size, in, in_len, ZSTD_maxCLevel()); + if (ZSTD_isError(ret)) { + ERROR("ZSTD_compress (v%s) returned %zu (%s)\n", + ZSTD_versionString(), ret, ZSTD_getErrorName(ret)); + free(bounce); + return -2; + } + if (ret >= (size_t)in_len) { + free(bounce); + return -3; + } + *out_len = (int)ret; + + memcpy(out, bounce, *out_len); + free(bounce); + return 0; +} + +static int zstd_decompress(char *in, int in_len, char *out, int out_len, + size_t *actual_size) +{ + ZSTD_DCtx* dctx = ZSTD_createDCtx(); + size_t ret = ZSTD_decompressDCtx(dctx, out, out_len, in, in_len); + ZSTD_freeDCtx(dctx); + + if (ret == 0) + return -1; + if (ZSTD_isError(ret)) { + ERROR("ZSTD_decompress (v%s) returned %zu (%s)\n", + ZSTD_versionString(), ret, ZSTD_getErrorName(ret)); + return -2; + } + if (actual_size != NULL) + *actual_size = ret; + return 0; +} + static int none_compress(char *in, int in_len, char *out, int *out_len) { memcpy(out, in, in_len); @@ -82,6 +130,9 @@ comp_func_ptr compression_function(enum cbfs_compression algo) case CBFS_COMPRESS_LZ4: compress = lz4_compress; break; + case CBFS_COMPRESS_ZSTD: + compress = zstd_compress; + break; default: ERROR("Unknown compression algorithm %d!\n", algo); return NULL; @@ -102,6 +153,9 @@ decomp_func_ptr decompression_function(enum cbfs_compression algo) case CBFS_COMPRESS_LZ4: decompress = lz4_decompress; break; + case CBFS_COMPRESS_ZSTD: + decompress = zstd_decompress; + break; default: ERROR("Unknown compression algorithm %d!\n", algo); return NULL; diff --git a/util/cbfstool/default-x86.fmd b/util/cbfstool/default-x86.fmd index 795e025f9f1..d0e17b194e4 100644 --- a/util/cbfstool/default-x86.fmd +++ b/util/cbfstool/default-x86.fmd @@ -1,5 +1,5 @@ # layout for firmware residing at top of 4GB address space -# +-------------+ <-- 4GB - ROM_SIZE / start of flash +# +-------------+ <-- 4GB - FLASH_SIZE / start of flash # | unspecified | # +-------------+ <-- 4GB - BIOS_SIZE # | FMAP | @@ -7,7 +7,7 @@ # | CBFS | # +-------------+ <-- 4GB / end of flash -FLASH ##ROM_SIZE## { +FLASH ##FLASH_SIZE## { BIOS@##BIOS_BASE## ##BIOS_SIZE## { ##CONSOLE_ENTRY## ##MRC_CACHE_ENTRY## diff --git a/util/cbfstool/default.fmd b/util/cbfstool/default.fmd index d20789f4048..97cf441445c 100644 --- a/util/cbfstool/default.fmd +++ b/util/cbfstool/default.fmd @@ -7,9 +7,9 @@ # | FMAP | # +-------------+ <-- BIOS_BASE + 128K + FMAP_SIZE # | CBFS | -# +-------------+ <-- ROM_SIZE +# +-------------+ <-- FLASH_SIZE -FLASH ##ROM_SIZE## { +FLASH ##FLASH_SIZE## { BIOS@##BIOS_BASE## ##BIOS_SIZE## { BOOTBLOCK 128K FMAP@##FMAP_BASE## ##FMAP_SIZE## diff --git a/util/cbfstool/elf.h b/util/cbfstool/elf.h index e2d04219297..b47e080e671 100644 --- a/util/cbfstool/elf.h +++ b/util/cbfstool/elf.h @@ -2714,48 +2714,69 @@ typedef Elf32_Addr Elf32_Conflict; #define R_M32R_NUM 256 /* Keep this the last entry. */ -/* RISC-V relocation types */ +/* RISC-V relocations */ #define R_RISCV_NONE 0 -#define R_RISCV_32 2 -#define R_RISCV_REL32 3 -#define R_RISCV_JAL 4 -#define R_RISCV_HI20 5 -#define R_RISCV_LO12_I 6 -#define R_RISCV_LO12_S 7 -#define R_RISCV_PCREL_LO12_I 8 -#define R_RISCV_PCREL_LO12_S 9 -#define R_RISCV_BRANCH 10 -#define R_RISCV_CALL 11 -#define R_RISCV_PCREL_HI20 12 -#define R_RISCV_CALL_PLT 13 -#define R_RISCV_64 18 -#define R_RISCV_GOT_HI20 22 -#define R_RISCV_GOT_LO12 23 -#define R_RISCV_COPY 24 -#define R_RISCV_JUMP_SLOT 25 -/* TLS relocations */ -#define R_RISCV_TPREL_HI20 30 -#define R_RISCV_TPREL_LO12_I 31 -#define R_RISCV_TPREL_LO12_S 32 -#define R_RISCV_TLS_DTPMOD32 38 -#define R_RISCV_TLS_DTPREL32 39 -#define R_RISCV_TLS_DTPMOD64 40 -#define R_RISCV_TLS_DTPREL64 41 -#define R_RISCV_TLS_GD 42 -#define R_RISCV_TLS_DTPREL_HI16 44 -#define R_RISCV_TLS_DTPREL_LO16 45 -#define R_RISCV_TLS_GOTTPREL 46 -#define R_RISCV_TLS_TPREL32 47 -#define R_RISCV_TLS_TPREL64 48 -#define R_RISCV_TLS_GOT_HI20 51 -#define R_RISCV_TLS_GOT_LO12 52 -#define R_RISCV_TLS_GD_HI20 53 -#define R_RISCV_TLS_GD_LO12 54 -#define R_RISCV_GLOB_DAT 57 -#define R_RISCV_ADD32 58 -#define R_RISCV_ADD64 59 -#define R_RISCV_SUB32 60 -#define R_RISCV_SUB64 61 +#define R_RISCV_32 1 +#define R_RISCV_64 2 +#define R_RISCV_RELATIVE 3 +#define R_RISCV_COPY 4 +#define R_RISCV_JUMP_SLOT 5 +#define R_RISCV_TLS_DTPMOD32 6 +#define R_RISCV_TLS_DTPMOD64 7 +#define R_RISCV_TLS_DTPREL32 8 +#define R_RISCV_TLS_DTPREL64 9 +#define R_RISCV_TLS_TPREL32 10 +#define R_RISCV_TLS_TPREL64 11 +#define R_RISCV_TLSDESC 12 + +#define R_RISCV_BRANCH 16 +#define R_RISCV_JAL 17 +#define R_RISCV_CALL 18 +#define R_RISCV_CALL_PLT 19 +#define R_RISCV_GOT_HI20 20 +#define R_RISCV_TLS_GOT_HI20 21 +#define R_RISCV_TLS_GD_HI20 22 +#define R_RISCV_PCREL_HI20 23 +#define R_RISCV_PCREL_LO12_I 24 +#define R_RISCV_PCREL_LO12_S 25 +#define R_RISCV_HI20 26 +#define R_RISCV_LO12_I 27 +#define R_RISCV_LO12_S 28 +#define R_RISCV_TPREL_HI20 29 +#define R_RISCV_TPREL_LO12_I 30 +#define R_RISCV_TPREL_LO12_S 31 +#define R_RISCV_TPREL_ADD 32 +#define R_RISCV_ADD8 33 +#define R_RISCV_ADD16 34 +#define R_RISCV_ADD32 35 +#define R_RISCV_ADD64 36 +#define R_RISCV_SUB8 37 +#define R_RISCV_SUB16 38 +#define R_RISCV_SUB32 39 +#define R_RISCV_SUB64 40 +#define R_RISCV_ALIGN 43 +#define R_RISCV_RVC_BRANCH 44 +#define R_RISCV_RVC_JUMP 45 +#define R_RISCV_RVC_LUI 46 +#define R_RISCV_GPREL_I 47 +#define R_RISCV_GPREL_S 48 +#define R_RISCV_TPREL_I 49 +#define R_RISCV_TPREL_S 50 +#define R_RISCV_RELAX 51 +#define R_RISCV_SUB6 52 +#define R_RISCV_SET6 53 +#define R_RISCV_SET8 54 +#define R_RISCV_SET16 55 +#define R_RISCV_SET32 56 +#define R_RISCV_32_PCREL 57 +#define R_RISCV_IRELATIVE 58 + +#define R_RISCV_SET_ULEB128 60 +#define R_RISCV_SUB_ULEB128 61 +#define R_RISCV_TLSDESC_HI20 62 +#define R_RISCV_TLSDESC_LOAD_LO12 63 +#define R_RISCV_TLSDESC_ADD_LO12 64 +#define R_RISCV_TLSDESC_CALL 65 #define EM_RISCV 0xF3 diff --git a/util/cbfstool/flashmap/kv_pair.h b/util/cbfstool/flashmap/kv_pair.h index 57715707435..a582ff764d9 100644 --- a/util/cbfstool/flashmap/kv_pair.h +++ b/util/cbfstool/flashmap/kv_pair.h @@ -78,7 +78,7 @@ extern struct kv_pair *kv_pair_fmt(struct kv_pair *kv_list, #if defined(_WIN32) || (_WIN64) __attribute__((format(gnu_printf, 3, 4))); #else - __attribute__((format(printf, 3, 4))); + __printf(3, 4); #endif /* diff --git a/util/cbfstool/lz4/lib/lz4_xxhash.h b/util/cbfstool/lz4/lib/lz4_xxhash.h new file mode 100644 index 00000000000..2e380e4e208 --- /dev/null +++ b/util/cbfstool/lz4/lib/lz4_xxhash.h @@ -0,0 +1,13 @@ +#include + +typedef struct xxh64_state XXH64_state_t; +#define XXH64_update xxh64_update +#define XXH64_reset xxh64_reset +#define XXH64_digest xxh64_digest +#define XXH64 xxh64 + +typedef struct xxh32_state XXH32_state_t; +#define XXH32_update xxh32_update +#define XXH32_reset xxh32_reset +#define XXH32_digest xxh32_digest +#define XXH32 xxh32 diff --git a/util/cbfstool/lz4/lib/lz4frame.c b/util/cbfstool/lz4/lib/lz4frame.c index aef508d8dfc..8aebc63cd3f 100644 --- a/util/cbfstool/lz4/lib/lz4frame.c +++ b/util/cbfstool/lz4/lib/lz4frame.c @@ -62,7 +62,7 @@ You can contact the author at : #include "lz4frame_static.h" #include "lz4.h" #include "lz4hc.h" -#include "xxhash.h" +#include "lz4_xxhash.h" /************************************** diff --git a/util/cbfstool/lz4/lib/xxhash.c b/util/cbfstool/lz4/lib/xxhash.c deleted file mode 100644 index 0f896266f03..00000000000 --- a/util/cbfstool/lz4/lib/xxhash.c +++ /dev/null @@ -1,962 +0,0 @@ -/* -xxHash - Fast Hash algorithm -Copyright (C) 2012-2015, Yann Collet - -BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -You can contact the author at : -- xxHash source repository : https://github.com/Cyan4973/xxHash -*/ - - -/************************************** -* Tuning parameters -**************************************/ -/* XXH_FORCE_MEMORY_ACCESS - * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. - * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. - * The below switch allow to select different access method for improved performance. - * Method 0 (default) : use `memcpy()`. Safe and portable. - * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). - * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. - * Method 2 : direct access. This method is portable but violate C standard. - * It can generate buggy code on targets which generate assembly depending on alignment. - * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) - * See http://stackoverflow.com/a/32095106/646947 for details. - * Prefer these methods in priority order (0 > 1 > 2) - */ -#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ -# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) -# define XXH_FORCE_MEMORY_ACCESS 2 -# elif defined(__INTEL_COMPILER) || \ - (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) -# define XXH_FORCE_MEMORY_ACCESS 1 -# endif -#endif - -/* XXH_ACCEPT_NULL_INPUT_POINTER : - * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer. - * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input. - * By default, this option is disabled. To enable it, uncomment below define : - */ -/* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */ - -/* XXH_FORCE_NATIVE_FORMAT : - * By default, xxHash library provides endian-independent Hash values, based on little-endian convention. - * Results are therefore identical for little-endian and big-endian CPU. - * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. - * Should endian-independance be of no importance for your application, you may set the #define below to 1, - * to improve speed for Big-endian CPU. - * This option has no impact on Little_Endian CPU. - */ -#define XXH_FORCE_NATIVE_FORMAT 0 - -/* XXH_USELESS_ALIGN_BRANCH : - * This is a minor performance trick, only useful with lots of very small keys. - * It means : don't make a test between aligned/unaligned, because performance will be the same. - * It saves one initial branch per hash. - */ -#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) -# define XXH_USELESS_ALIGN_BRANCH 1 -#endif - - -/************************************** -* Compiler Specific Options -***************************************/ -#ifdef _MSC_VER /* Visual Studio */ -# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ -# define FORCE_INLINE static __forceinline -#else -# if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# ifdef __GNUC__ -# define FORCE_INLINE static inline __attribute__((always_inline)) -# else -# define FORCE_INLINE static inline -# endif -# else -# define FORCE_INLINE static -# endif /* __STDC_VERSION__ */ -#endif - - -/************************************** -* Includes & Memory related functions -***************************************/ -#include "xxhash.h" -/* Modify the local functions below should you wish to use some other memory routines */ -/* for malloc(), free() */ -#include -static void* XXH_malloc(size_t s) { return malloc(s); } -static void XXH_free (void* p) { free(p); } -/* for memcpy() */ -#include -static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } - - -/************************************** -* Basic Types -***************************************/ -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ -# include - typedef uint8_t BYTE; - typedef uint16_t U16; - typedef uint32_t U32; - typedef int32_t S32; - typedef uint64_t U64; -#else - typedef unsigned char BYTE; - typedef unsigned short U16; - typedef unsigned int U32; - typedef signed int S32; - typedef unsigned long long U64; -#endif - - -#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) - -/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ -static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; } -static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; } - -#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) - -/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ -/* currently only defined for gcc and icc */ -typedef union { U32 u32; U64 u64; } __packed unalign; - -static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } -static U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } - -#else - -/* portable and safe solution. Generally efficient. - * see : http://stackoverflow.com/a/32095106/646947 - */ - -static U32 XXH_read32(const void* memPtr) -{ - U32 val; - memcpy(&val, memPtr, sizeof(val)); - return val; -} - -static U64 XXH_read64(const void* memPtr) -{ - U64 val; - memcpy(&val, memPtr, sizeof(val)); - return val; -} - -#endif // XXH_FORCE_DIRECT_MEMORY_ACCESS - - -/****************************************** -* Compiler-specific Functions and Macros -******************************************/ -#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) - -/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ -#if defined(_MSC_VER) -# define XXH_rotl32(x,r) _rotl(x,r) -# define XXH_rotl64(x,r) _rotl64(x,r) -#else -# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) -# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) -#endif - -#if defined(_MSC_VER) /* Visual Studio */ -# define XXH_swap32 _byteswap_ulong -# define XXH_swap64 _byteswap_uint64 -#elif GCC_VERSION >= 403 -# define XXH_swap32 __builtin_bswap32 -# define XXH_swap64 __builtin_bswap64 -#else -static U32 XXH_swap32 (U32 x) -{ - return ((x << 24) & 0xff000000 ) | - ((x << 8) & 0x00ff0000 ) | - ((x >> 8) & 0x0000ff00 ) | - ((x >> 24) & 0x000000ff ); -} -static U64 XXH_swap64 (U64 x) -{ - return ((x << 56) & 0xff00000000000000ULL) | - ((x << 40) & 0x00ff000000000000ULL) | - ((x << 24) & 0x0000ff0000000000ULL) | - ((x << 8) & 0x000000ff00000000ULL) | - ((x >> 8) & 0x00000000ff000000ULL) | - ((x >> 24) & 0x0000000000ff0000ULL) | - ((x >> 40) & 0x000000000000ff00ULL) | - ((x >> 56) & 0x00000000000000ffULL); -} -#endif - - -/*************************************** -* Architecture Macros -***************************************/ -typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianness; - -/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example one the compiler command line */ -#ifndef XXH_CPU_LITTLE_ENDIAN - static const int one = 1; -# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&one)) -#endif - - -/***************************** -* Memory reads -*****************************/ -typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; - -FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianness endian, XXH_alignment align) -{ - if (align==XXH_unaligned) - return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr)); - else - return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr); -} - -FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianness endian) -{ - return XXH_readLE32_align(ptr, endian, XXH_unaligned); -} - -FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianness endian, XXH_alignment align) -{ - if (align==XXH_unaligned) - return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr)); - else - return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr); -} - -FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianness endian) -{ - return XXH_readLE64_align(ptr, endian, XXH_unaligned); -} - - -/*************************************** -* Macros -***************************************/ -#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } /* use only *after* variable declarations */ - - -/*************************************** -* Constants -***************************************/ -#define PRIME32_1 2654435761U -#define PRIME32_2 2246822519U -#define PRIME32_3 3266489917U -#define PRIME32_4 668265263U -#define PRIME32_5 374761393U - -#define PRIME64_1 11400714785074694791ULL -#define PRIME64_2 14029467366897019727ULL -#define PRIME64_3 1609587929392839161ULL -#define PRIME64_4 9650029242287828579ULL -#define PRIME64_5 2870177450012600261ULL - - -/***************************** -* Simple Hash Functions -*****************************/ -FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianness endian, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* bEnd = p + len; - U32 h32; -#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align) - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) - { - len=0; - bEnd=p=(const BYTE*)(size_t)16; - } -#endif - - if (len>=16) - { - const BYTE* const limit = bEnd - 16; - U32 v1 = seed + PRIME32_1 + PRIME32_2; - U32 v2 = seed + PRIME32_2; - U32 v3 = seed + 0; - U32 v4 = seed - PRIME32_1; - - do - { - v1 += XXH_get32bits(p) * PRIME32_2; - v1 = XXH_rotl32(v1, 13); - v1 *= PRIME32_1; - p+=4; - v2 += XXH_get32bits(p) * PRIME32_2; - v2 = XXH_rotl32(v2, 13); - v2 *= PRIME32_1; - p+=4; - v3 += XXH_get32bits(p) * PRIME32_2; - v3 = XXH_rotl32(v3, 13); - v3 *= PRIME32_1; - p+=4; - v4 += XXH_get32bits(p) * PRIME32_2; - v4 = XXH_rotl32(v4, 13); - v4 *= PRIME32_1; - p+=4; - } - while (p<=limit); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); - } - else - { - h32 = seed + PRIME32_5; - } - - h32 += (U32) len; - - while (p+4<=bEnd) - { - h32 += XXH_get32bits(p) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - - -unsigned int XXH32 (const void* input, size_t len, unsigned int seed) -{ -#if 0 - /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ - XXH32_state_t state; - XXH32_reset(&state, seed); - XXH32_update(&state, input, len); - return XXH32_digest(&state); -#else - XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN; - -# if !defined(XXH_USELESS_ALIGN_BRANCH) - if ((((size_t)input) & 3) == 0) /* Input is 4-bytes aligned, leverage the speed benefit */ - { - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } -# endif - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); - else - return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); -#endif -} - -FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianness endian, XXH_alignment align) -{ - const BYTE* p = (const BYTE*)input; - const BYTE* bEnd = p + len; - U64 h64; -#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align) - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (p==NULL) - { - len=0; - bEnd=p=(const BYTE*)(size_t)32; - } -#endif - - if (len>=32) - { - const BYTE* const limit = bEnd - 32; - U64 v1 = seed + PRIME64_1 + PRIME64_2; - U64 v2 = seed + PRIME64_2; - U64 v3 = seed + 0; - U64 v4 = seed - PRIME64_1; - - do - { - v1 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - v2 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - v3 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - v4 += XXH_get64bits(p) * PRIME64_2; - p+=8; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - } - while (p<=limit); - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - - v1 *= PRIME64_2; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - h64 ^= v1; - h64 = h64 * PRIME64_1 + PRIME64_4; - - v2 *= PRIME64_2; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - h64 ^= v2; - h64 = h64 * PRIME64_1 + PRIME64_4; - - v3 *= PRIME64_2; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - h64 ^= v3; - h64 = h64 * PRIME64_1 + PRIME64_4; - - v4 *= PRIME64_2; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - h64 ^= v4; - h64 = h64 * PRIME64_1 + PRIME64_4; - } - else - { - h64 = seed + PRIME64_5; - } - - h64 += (U64) len; - - while (p+8<=bEnd) - { - U64 k1 = XXH_get64bits(p); - k1 *= PRIME64_2; - k1 = XXH_rotl64(k1,31); - k1 *= PRIME64_1; - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; - p+=8; - } - - if (p+4<=bEnd) - { - h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - p+=4; - } - - while (p> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - - return h64; -} - - -unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed) -{ -#if 0 - /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ - XXH64_state_t state; - XXH64_reset(&state, seed); - XXH64_update(&state, input, len); - return XXH64_digest(&state); -#else - XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN; - -# if !defined(XXH_USELESS_ALIGN_BRANCH) - if ((((size_t)input) & 7)==0) /* Input is aligned, let's leverage the speed advantage */ - { - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); - else - return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); - } -# endif - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); - else - return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); -#endif -} - -/**************************************************** -* Advanced Hash Functions -****************************************************/ - -/*** Allocation ***/ -typedef struct -{ - U64 total_len; - U32 seed; - U32 v1; - U32 v2; - U32 v3; - U32 v4; - U32 mem32[4]; /* defined as U32 for alignment */ - U32 memsize; -} XXH_istate32_t; - -typedef struct -{ - U64 total_len; - U64 seed; - U64 v1; - U64 v2; - U64 v3; - U64 v4; - U64 mem64[4]; /* defined as U64 for alignment */ - U32 memsize; -} XXH_istate64_t; - - -XXH32_state_t* XXH32_createState(void) -{ - XXH_STATIC_ASSERT(sizeof(XXH32_state_t) >= sizeof(XXH_istate32_t)); /* A compilation error here means XXH32_state_t is not large enough */ - return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t)); -} -XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - -XXH64_state_t* XXH64_createState(void) -{ - XXH_STATIC_ASSERT(sizeof(XXH64_state_t) >= sizeof(XXH_istate64_t)); /* A compilation error here means XXH64_state_t is not large enough */ - return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t)); -} -XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr) -{ - XXH_free(statePtr); - return XXH_OK; -} - - -/*** Hash feed ***/ - -XXH_errorcode XXH32_reset(XXH32_state_t* state_in, unsigned int seed) -{ - XXH_istate32_t* state = (XXH_istate32_t*) state_in; - state->seed = seed; - state->v1 = seed + PRIME32_1 + PRIME32_2; - state->v2 = seed + PRIME32_2; - state->v3 = seed + 0; - state->v4 = seed - PRIME32_1; - state->total_len = 0; - state->memsize = 0; - return XXH_OK; -} - -XXH_errorcode XXH64_reset(XXH64_state_t* state_in, unsigned long long seed) -{ - XXH_istate64_t* state = (XXH_istate64_t*) state_in; - state->seed = seed; - state->v1 = seed + PRIME64_1 + PRIME64_2; - state->v2 = seed + PRIME64_2; - state->v3 = seed + 0; - state->v4 = seed - PRIME64_1; - state->total_len = 0; - state->memsize = 0; - return XXH_OK; -} - - -FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state_in, const void* input, size_t len, XXH_endianness endian) -{ - XXH_istate32_t* state = (XXH_istate32_t *) state_in; - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (input==NULL) return XXH_ERROR; -#endif - - state->total_len += len; - - if (state->memsize + len < 16) /* fill in tmp buffer */ - { - XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len); - state->memsize += (U32)len; - return XXH_OK; - } - - if (state->memsize) /* some data left from previous update */ - { - XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize); - { - const U32* p32 = state->mem32; - state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v1 = XXH_rotl32(state->v1, 13); - state->v1 *= PRIME32_1; - p32++; - state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v2 = XXH_rotl32(state->v2, 13); - state->v2 *= PRIME32_1; - p32++; - state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v3 = XXH_rotl32(state->v3, 13); - state->v3 *= PRIME32_1; - p32++; - state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; - state->v4 = XXH_rotl32(state->v4, 13); - state->v4 *= PRIME32_1; - p32++; - } - p += 16-state->memsize; - state->memsize = 0; - } - - if (p <= bEnd-16) - { - const BYTE* const limit = bEnd - 16; - U32 v1 = state->v1; - U32 v2 = state->v2; - U32 v3 = state->v3; - U32 v4 = state->v4; - - do - { - v1 += XXH_readLE32(p, endian) * PRIME32_2; - v1 = XXH_rotl32(v1, 13); - v1 *= PRIME32_1; - p+=4; - v2 += XXH_readLE32(p, endian) * PRIME32_2; - v2 = XXH_rotl32(v2, 13); - v2 *= PRIME32_1; - p+=4; - v3 += XXH_readLE32(p, endian) * PRIME32_2; - v3 = XXH_rotl32(v3, 13); - v3 *= PRIME32_1; - p+=4; - v4 += XXH_readLE32(p, endian) * PRIME32_2; - v4 = XXH_rotl32(v4, 13); - v4 *= PRIME32_1; - p+=4; - } - while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) - { - XXH_memcpy(state->mem32, p, bEnd-p); - state->memsize = (int)(bEnd-p); - } - - return XXH_OK; -} - -XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len) -{ - XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_update_endian(state_in, input, len, XXH_littleEndian); - else - return XXH32_update_endian(state_in, input, len, XXH_bigEndian); -} - - - -FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state_in, XXH_endianness endian) -{ - const XXH_istate32_t* state = (const XXH_istate32_t*) state_in; - const BYTE * p = (const BYTE*)state->mem32; - const BYTE* bEnd = (const BYTE*)(state->mem32) + state->memsize; - U32 h32; - - if (state->total_len >= 16) - { - h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); - } - else - { - h32 = state->seed + PRIME32_5; - } - - h32 += (U32) state->total_len; - - while (p+4<=bEnd) - { - h32 += XXH_readLE32(p, endian) * PRIME32_3; - h32 = XXH_rotl32(h32, 17) * PRIME32_4; - p+=4; - } - - while (p> 15; - h32 *= PRIME32_2; - h32 ^= h32 >> 13; - h32 *= PRIME32_3; - h32 ^= h32 >> 16; - - return h32; -} - - -unsigned int XXH32_digest (const XXH32_state_t* state_in) -{ - XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH32_digest_endian(state_in, XXH_littleEndian); - else - return XXH32_digest_endian(state_in, XXH_bigEndian); -} - - -FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state_in, const void* input, size_t len, XXH_endianness endian) -{ - XXH_istate64_t * state = (XXH_istate64_t *) state_in; - const BYTE* p = (const BYTE*)input; - const BYTE* const bEnd = p + len; - -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER - if (input==NULL) return XXH_ERROR; -#endif - - state->total_len += len; - - if (state->memsize + len < 32) /* fill in tmp buffer */ - { - XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len); - state->memsize += (U32)len; - return XXH_OK; - } - - if (state->memsize) /* some data left from previous update */ - { - XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize); - { - const U64* p64 = state->mem64; - state->v1 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v1 = XXH_rotl64(state->v1, 31); - state->v1 *= PRIME64_1; - p64++; - state->v2 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v2 = XXH_rotl64(state->v2, 31); - state->v2 *= PRIME64_1; - p64++; - state->v3 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v3 = XXH_rotl64(state->v3, 31); - state->v3 *= PRIME64_1; - p64++; - state->v4 += XXH_readLE64(p64, endian) * PRIME64_2; - state->v4 = XXH_rotl64(state->v4, 31); - state->v4 *= PRIME64_1; - p64++; - } - p += 32-state->memsize; - state->memsize = 0; - } - - if (p+32 <= bEnd) - { - const BYTE* const limit = bEnd - 32; - U64 v1 = state->v1; - U64 v2 = state->v2; - U64 v3 = state->v3; - U64 v4 = state->v4; - - do - { - v1 += XXH_readLE64(p, endian) * PRIME64_2; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - p+=8; - v2 += XXH_readLE64(p, endian) * PRIME64_2; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - p+=8; - v3 += XXH_readLE64(p, endian) * PRIME64_2; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - p+=8; - v4 += XXH_readLE64(p, endian) * PRIME64_2; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - p+=8; - } - while (p<=limit); - - state->v1 = v1; - state->v2 = v2; - state->v3 = v3; - state->v4 = v4; - } - - if (p < bEnd) - { - XXH_memcpy(state->mem64, p, bEnd-p); - state->memsize = (int)(bEnd-p); - } - - return XXH_OK; -} - -XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len) -{ - XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_update_endian(state_in, input, len, XXH_littleEndian); - else - return XXH64_update_endian(state_in, input, len, XXH_bigEndian); -} - - - -FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state_in, XXH_endianness endian) -{ - const XXH_istate64_t * state = (const XXH_istate64_t *) state_in; - const BYTE * p = (const BYTE*)state->mem64; - const BYTE* bEnd = (const BYTE*)state->mem64 + state->memsize; - U64 h64; - - if (state->total_len >= 32) - { - U64 v1 = state->v1; - U64 v2 = state->v2; - U64 v3 = state->v3; - U64 v4 = state->v4; - - h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); - - v1 *= PRIME64_2; - v1 = XXH_rotl64(v1, 31); - v1 *= PRIME64_1; - h64 ^= v1; - h64 = h64*PRIME64_1 + PRIME64_4; - - v2 *= PRIME64_2; - v2 = XXH_rotl64(v2, 31); - v2 *= PRIME64_1; - h64 ^= v2; - h64 = h64*PRIME64_1 + PRIME64_4; - - v3 *= PRIME64_2; - v3 = XXH_rotl64(v3, 31); - v3 *= PRIME64_1; - h64 ^= v3; - h64 = h64*PRIME64_1 + PRIME64_4; - - v4 *= PRIME64_2; - v4 = XXH_rotl64(v4, 31); - v4 *= PRIME64_1; - h64 ^= v4; - h64 = h64*PRIME64_1 + PRIME64_4; - } - else - { - h64 = state->seed + PRIME64_5; - } - - h64 += (U64) state->total_len; - - while (p+8<=bEnd) - { - U64 k1 = XXH_readLE64(p, endian); - k1 *= PRIME64_2; - k1 = XXH_rotl64(k1,31); - k1 *= PRIME64_1; - h64 ^= k1; - h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; - p+=8; - } - - if (p+4<=bEnd) - { - h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1; - h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; - p+=4; - } - - while (p> 33; - h64 *= PRIME64_2; - h64 ^= h64 >> 29; - h64 *= PRIME64_3; - h64 ^= h64 >> 32; - - return h64; -} - - -unsigned long long XXH64_digest (const XXH64_state_t* state_in) -{ - XXH_endianness endian_detected = (XXH_endianness)XXH_CPU_LITTLE_ENDIAN; - - if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) - return XXH64_digest_endian(state_in, XXH_littleEndian); - else - return XXH64_digest_endian(state_in, XXH_bigEndian); -} - - diff --git a/util/cbfstool/lz4/lib/xxhash.h b/util/cbfstool/lz4/lib/xxhash.h deleted file mode 100644 index c60aa61571c..00000000000 --- a/util/cbfstool/lz4/lib/xxhash.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - xxHash - Extremely Fast Hash algorithm - Header File - Copyright (C) 2012-2015, Yann Collet. - - BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - You can contact the author at : - - xxHash source repository : https://github.com/Cyan4973/xxHash -*/ - -/* Notice extracted from xxHash homepage : - -xxHash is an extremely fast Hash algorithm, running at RAM speed limits. -It also successfully passes all tests from the SMHasher suite. - -Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) - -Name Speed Q.Score Author -xxHash 5.4 GB/s 10 -CrapWow 3.2 GB/s 2 Andrew -MumurHash 3a 2.7 GB/s 10 Austin Appleby -SpookyHash 2.0 GB/s 10 Bob Jenkins -SBox 1.4 GB/s 9 Bret Mulvey -Lookup3 1.2 GB/s 9 Bob Jenkins -SuperFastHash 1.2 GB/s 1 Paul Hsieh -CityHash64 1.05 GB/s 10 Pike & Alakuijala -FNV 0.55 GB/s 5 Fowler, Noll, Vo -CRC32 0.43 GB/s 9 -MD5-32 0.33 GB/s 10 Ronald L. Rivest -SHA1-32 0.28 GB/s 10 - -Q.Score is a measure of quality of the hash function. -It depends on successfully passing SMHasher test set. -10 is a perfect score. - -A 64-bits version, named XXH64, is available since r35. -It offers much better speed, but for 64-bits applications only. -Name Speed on 64 bits Speed on 32 bits -XXH64 13.8 GB/s 1.9 GB/s -XXH32 6.8 GB/s 6.0 GB/s -*/ - -#pragma once - -#if defined (__cplusplus) -extern "C" { -#endif - - -/***************************** -* Definitions -*****************************/ -#include /* size_t */ -typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; - - -/***************************** -* Namespace Emulation -*****************************/ -/* Motivations : - -If you need to include xxHash into your library, -but wish to avoid xxHash symbols to be present on your library interface -in an effort to avoid potential name collision if another library also includes xxHash, - -you can use XXH_NAMESPACE, which will automatically prefix any symbol from xxHash -with the value of XXH_NAMESPACE (so avoid to keep it NULL, and avoid numeric values). - -Note that no change is required within the calling program : -it can still call xxHash functions using their regular name. -They will be automatically translated by this header. -*/ -#ifdef XXH_NAMESPACE -# define XXH_CAT(A,B) A##B -# define XXH_NAME2(A,B) XXH_CAT(A,B) -# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) -# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) -# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) -# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) -# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) -# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) -# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) -# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) -# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) -# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) -# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) -# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) -#endif - - -/***************************** -* Simple Hash Functions -*****************************/ - -unsigned int XXH32 (const void* input, size_t length, unsigned seed); -unsigned long long XXH64 (const void* input, size_t length, unsigned long long seed); - -/* -XXH32() : - Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". - The memory between input & input+length must be valid (allocated and read-accessible). - "seed" can be used to alter the result predictably. - This function successfully passes all SMHasher tests. - Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s -XXH64() : - Calculate the 64-bits hash of sequence of length "len" stored at memory address "input". - Faster on 64-bits systems. Slower on 32-bits systems. -*/ - - - -/***************************** -* Advanced Hash Functions -*****************************/ -typedef struct { long long ll[ 6]; } XXH32_state_t; -typedef struct { long long ll[11]; } XXH64_state_t; - -/* -These structures allow static allocation of XXH states. -States must then be initialized using XXHnn_reset() before first use. - -If you prefer dynamic allocation, please refer to functions below. -*/ - -XXH32_state_t* XXH32_createState(void); -XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); - -XXH64_state_t* XXH64_createState(void); -XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); - -/* -These functions create and release memory for XXH state. -States must then be initialized using XXHnn_reset() before first use. -*/ - - -XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned seed); -XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); -unsigned int XXH32_digest (const XXH32_state_t* statePtr); - -XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); -XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); -unsigned long long XXH64_digest (const XXH64_state_t* statePtr); - -/* -These functions calculate the xxHash of an input provided in multiple smaller packets, -as opposed to an input provided as a single block. - -XXH state space must first be allocated, using either static or dynamic method provided above. - -Start a new hash by initializing state with a seed, using XXHnn_reset(). - -Then, feed the hash state by calling XXHnn_update() as many times as necessary. -Obviously, input must be valid, meaning allocated and read accessible. -The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. - -Finally, you can produce a hash anytime, by using XXHnn_digest(). -This function returns the final nn-bits hash. -You can nonetheless continue feeding the hash state with more input, -and therefore get some new hashes, by calling again XXHnn_digest(). - -When you are done, don't forget to free XXH state space, using typically XXHnn_freeState(). -*/ - - -#if defined (__cplusplus) -} -#endif diff --git a/util/cbfstool/platform_fixups.c b/util/cbfstool/platform_fixups.c index 7e29cd7e2ba..97fdd2e15b9 100644 --- a/util/cbfstool/platform_fixups.c +++ b/util/cbfstool/platform_fixups.c @@ -312,12 +312,14 @@ static int mediatek_fixup(struct buffer *buffer, unused size_t offset) platform_fixup_func platform_fixups_probe(struct buffer *buffer, size_t offset, const char *region_name) { - if (!strcmp(region_name, SECTION_NAME_BOOTBLOCK)) { + if (!strcmp(region_name, SECTION_NAME_BOOTBLOCK) || + !strcmp(region_name, SECTION_NAME_TOPSWAP)) { if (qualcomm_probe(buffer, offset)) return qualcomm_fixup; else if (mediatek_probe(buffer)) return mediatek_fixup; - } else if (!strcmp(region_name, SECTION_NAME_PRIMARY_CBFS)) { + } else if (!strcmp(region_name, SECTION_NAME_PRIMARY_CBFS) || + !strcmp(region_name, SECTION_NAME_TOPSWAP_CBFS)) { /* TODO: add fixups for primary CBFS bootblock platforms, if needed */ } else { ERROR("%s called for unexpected FMAP region %s!\n", __func__, region_name); diff --git a/util/chromeos/crosfirmware.sh b/util/chromeos/crosfirmware.sh index 673f3b38a53..3be613de195 100755 --- a/util/chromeos/crosfirmware.sh +++ b/util/chromeos/crosfirmware.sh @@ -5,27 +5,35 @@ # On some systems, `parted` and `debugfs` are located in /sbin. export PATH="$PATH:/sbin" -exit_if_uninstalled() { - local cmd_name="$1" - local deb_pkg_name="$2" +exit_if_dependencies_are_missing() { + local missing_deps=() + local -A deps_map=( + ["uudecode"]="sharutils" + ["debugfs"]="e2fsprogs" + ["parted"]="parted" + ["curl"]="curl" + ["unzip"]="unzip" + ["7z"]="p7zip" + ) + + # Check all dependencies at once + for cmd_name in "${!deps_map[@]}"; do + if ! type "$cmd_name" >/dev/null 2>&1; then + missing_deps+=("$cmd_name:${deps_map[$cmd_name]}") + fi + done - if type "$cmd_name" >/dev/null 2>&1; then - return + # Exit if any dependencies are missing + if [ ${#missing_deps[@]} -gt 0 ]; then + printf 'The following required commands were not found:\n' >&2 + for dep_info in "${missing_deps[@]}"; do + cmd_name="${dep_info%%:*}" + deb_pkg_name="${dep_info##*:}" + printf ' - `%s`\n' "$cmd_name" >&2 + printf ' On Debian-based systems, install with: `apt install %s`\n' "$deb_pkg_name" >&2 + done + exit 1 fi - - printf '`%s` was not found. ' "$cmd_name" >&2 - printf 'On Debian-based systems, it can be installed\n' >&2 - printf 'by running `apt install %s`.\n' "$deb_pkg_name" >&2 - - exit 1 -} - -exit_if_dependencies_are_missing() { - exit_if_uninstalled "uudecode" "sharutils" - exit_if_uninstalled "debugfs" "e2fsprogs" - exit_if_uninstalled "parted" "parted" - exit_if_uninstalled "curl" "curl" - exit_if_uninstalled "unzip" "unzip" } get_inventory() { @@ -95,7 +103,11 @@ extract_coreboot() { echo "Extracting coreboot image" if ! sh $_shellball --unpack $_unpacked >/dev/null 2>&1; then - sh $_shellball --sb_extract $_unpacked >/dev/null 2>&1 + if ! sh $_shellball --sb_extract $_unpacked >$_unpacked/sb_extract.log 2>&1; then + echo "Failed to extract shellball image" + cat $_unpacked/sb_extract.log + exit 1 + fi fi if [ -d $_unpacked/models/ ]; then diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc index cf4a8d6bcee..cfcd44e8a7e 100755 --- a/util/crossgcc/buildgcc +++ b/util/crossgcc/buildgcc @@ -49,7 +49,7 @@ NASM_VERSION=2.16.03 # x86 assembly IASL_VERSION=20250807 # ACPI compiler # Clang/LLVM Toolchain (alternative to GCC, built separately) -CLANG_VERSION=18.1.8 +CLANG_VERSION=21.1.8 CMAKE_VERSION=4.0.3 # Required for building Clang # Architecture-specific options @@ -72,6 +72,7 @@ CTE_ARCHIVE="clang-tools-extra-${CLANG_VERSION}.src.tar.xz" LLVMCMAKE_ARCHIVE="cmake-${CLANG_VERSION}.src.tar.xz" LIBUNWIND_ARCHIVE="libunwind-${CLANG_VERSION}.src.tar.xz" RUNTIMES_ARCHIVE="runtimes-${CLANG_VERSION}.src.tar.xz" +THIRD_PARTY_ARCHIVE="third-party-${CLANG_VERSION}.src.tar.xz" CMAKE_ARCHIVE="cmake-${CMAKE_VERSION}.tar.gz" NASM_ARCHIVE="nasm-${NASM_VERSION}.tar.bz2" @@ -96,6 +97,7 @@ LLVMCMAKE_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmo LLD_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}" LIBUNWIND_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}" RUNTIMES_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}" +THIRD_PARTY_BASE_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VERSION}" CMAKE_BASE_URL="https://cmake.org/files/v${CMAKE_VERSION%.*}" NASM_BASE_URL="https://www.nasm.us/pub/nasm/releasebuilds/${NASM_VERSION}" @@ -104,7 +106,8 @@ ALL_ARCHIVES="$GMP_BASE_URL/$GMP_ARCHIVE $MPFR_BASE_URL/$MPFR_ARCHIVE $MPC_BASE_ $LLD_BASE_URL/$LLD_ARCHIVE $LLVM_BASE_URL/$LLVM_ARCHIVE $CLANG_BASE_URL/$CLANG_ARCHIVE \ $LLVMCMAKE_BASE_URL/$LLVMCMAKE_ARCHIVE $CRT_BASE_URL/$CRT_ARCHIVE $CTE_BASE_URL/$CTE_ARCHIVE \ $LIBUNWIND_BASE_URL/$LIBUNWIND_ARCHIVE $RUNTIMES_BASE_URL/$RUNTIMES_ARCHIVE \ - $CMAKE_BASE_URL/$CMAKE_ARCHIVE $NASM_BASE_URL/$NASM_ARCHIVE $LIBSTDCXX_BASE_URL/$LIBSTDCXX_ARCHIVE" + $THIRD_PARTY_BASE_URL/$THIRD_PARTY_ARCHIVE $CMAKE_BASE_URL/$CMAKE_ARCHIVE \ + $NASM_BASE_URL/$NASM_ARCHIVE $LIBSTDCXX_BASE_URL/$LIBSTDCXX_ARCHIVE" # GCC toolchain directories GMP_DIR="gmp-${GMP_VERSION}" @@ -125,6 +128,7 @@ CTE_DIR="clang-tools-extra-${CLANG_VERSION}.src" LLVMCMAKE_DIR="cmake-${CLANG_VERSION}.src" LIBUNWIND_DIR="libunwind-${CLANG_VERSION}.src" RUNTIMES_DIR="runtimes-${CLANG_VERSION}.src" +THIRD_PARTY_DIR="third-party-${CLANG_VERSION}.src" CMAKE_DIR="cmake-${CMAKE_VERSION}" NASM_DIR="nasm-${NASM_VERSION}" @@ -331,9 +335,38 @@ hostcc_has_gnat1() { [ -x "$(${CC} -print-prog-name=gnat1)" ] } +hostcc_has_gnatbind() { + # GCC configure requires unversioned gnatbind in PATH + # In GNAT 15+, tools may only be available as versioned (e.g., gnatbind-15) + # Check for unversioned first (required by configure) + if command -v gnatbind >/dev/null 2>&1; then + return 0 + fi + + # If only versioned tools exist, configure will fail + # So we return false to prevent Ada from being enabled + return 1 +} + +hostcc_has_gnatmake() { + # GCC configure requires unversioned gnatmake in PATH + # In GNAT 15+, tools may only be available as versioned (e.g., gnatmake-15) + # Check for unversioned first (required by configure) + if command -v gnatmake >/dev/null 2>&1; then + return 0 + fi + + # If only versioned tools exist, configure will fail + # So we return false to prevent Ada from being enabled + return 1 +} + have_gnat() { - hostcc_has_gnat1 && \ - searchtool gnatbind "Free Software Foundation" nofail > /dev/null + # Require all GNAT tools that configure needs + # Configure checks for gnatbind and gnatmake (unversioned names) + # Even though GNAT 15+ may only provide versioned tools or use gcc -b, + # the configure script still requires the unversioned names + hostcc_has_gnat1 && hostcc_has_gnatbind && hostcc_has_gnatmake } ada_requested() { @@ -924,6 +957,7 @@ build_LLVM() { ln -nsf "$LLVMCMAKE_DIR" ../cmake ln -nsf "$LIBUNWIND_DIR" ../libunwind ln -nsf "$RUNTIMES_DIR" ../runtimes + ln -nsf "$THIRD_PARTY_DIR" ../third-party $CMAKE -G "Unix Makefiles" \ -DCMAKE_INSTALL_PREFIX="$DESTDIR$TARGETDIR" \ @@ -1080,7 +1114,7 @@ case "$PACKAGE" in CLANG|clang) NAME="LLVM clang" LLVM_VERSION=${CLANG_VERSION} - PACKAGES="CMAKE LLVM CLANG CRT CTE LLVMCMAKE LLD LIBUNWIND RUNTIMES" + PACKAGES="CMAKE LLVM CLANG CRT CTE LLVMCMAKE LLD LIBUNWIND RUNTIMES THIRD_PARTY" CMAKE=${DESTDIR}${TARGETDIR}/bin/cmake ;; IASL|iasl) @@ -1235,23 +1269,51 @@ if [ -z "${LANGUAGES}" ]; then printf "\nFound compatible Ada compiler, enabling Ada support by default.\n\n" LANGUAGES="ada,${DEFAULT_LANGUAGES}" else + # Check if versioned tools exist (GNAT 15+) + gcc_version=$(${CC} -dumpversion 2>/dev/null | cut -d. -f1) + gnatbind_ver="" + gnatmake_ver="" + gnatbind_path="" + gnatmake_path="" + if [ -n "$gcc_version" ]; then + gnatbind_ver="gnatbind-${gcc_version}" + gnatmake_ver="gnatmake-${gcc_version}" + gnatbind_path=$(command -v "$gnatbind_ver" 2>/dev/null) + gnatmake_path=$(command -v "$gnatmake_ver" 2>/dev/null) + fi + printf "\n${red}WARNING${NC}\n" - printf "No compatible Ada compiler (GNAT) found. You can continue without\n" - printf "Ada support, but this will limit the features of ${blue}coreboot${NC} (e.g.\n" - printf "native graphics initialization won't be available on most Intel\n" - printf "boards).\n\n" - - printf "Usually, you can install GNAT with your package management system\n" - printf "(the package is called \`gnat\` or \`gcc-ada\`). It has to match the\n" - printf "\`gcc\` package in version. If there are multiple versions of GCC in-\n" - printf "stalled, you can point this script to the matching version through\n" - printf "the \`CC\` and \`CXX\` environment variables.\n\n" - - printf "e.g. on Ubuntu 14.04, if \`gcc\` is \`gcc-4.8\`:\n" - printf " apt-get install gnat-4.8 && make crossgcc\n\n" - - printf "on Ubuntu 16.04, if \`gcc\` is \`gcc-5\`:\n" - printf " apt-get install gnat-5 && make crossgcc\n" + if [ -n "$gnatbind_path" ] || [ -n "$gnatmake_path" ]; then + printf "GNAT tools are only available as versioned executables (e.g., %s, %s),\n" \ + "${gnatbind_ver:-gnatbind-N}" "${gnatmake_ver:-gnatmake-N}" + printf "but GCC configure requires unversioned names (gnatbind, gnatmake).\n\n" + printf "To enable Ada support, create symlinks or install the unversioned tools:\n" + if [ -n "$gnatbind_path" ]; then + printf " sudo ln -s %s /usr/local/bin/gnatbind\n" "$gnatbind_path" + fi + if [ -n "$gnatmake_path" ]; then + printf " sudo ln -s %s /usr/local/bin/gnatmake\n" "$gnatmake_path" + fi + printf "\nAlternatively, disable Ada support by setting BUILD_LANGUAGES=c:\n" + printf " make crossgcc-i386 BUILD_LANGUAGES=c\n\n" + else + printf "No compatible Ada compiler (GNAT) found. You can continue without\n" + printf "Ada support, but this will limit the features of ${blue}coreboot${NC} (e.g.\n" + printf "native graphics initialization won't be available on most Intel\n" + printf "boards).\n\n" + + printf "Usually, you can install GNAT with your package management system\n" + printf "(the package is called \`gnat\` or \`gcc-ada\`). It has to match the\n" + printf "\`gcc\` package in version. If there are multiple versions of GCC in-\n" + printf "stalled, you can point this script to the matching version through\n" + printf "the \`CC\` and \`CXX\` environment variables.\n\n" + + printf "e.g. on Ubuntu 14.04, if \`gcc\` is \`gcc-4.8\`:\n" + printf " apt-get install gnat-4.8 && make crossgcc\n\n" + + printf "on Ubuntu 16.04, if \`gcc\` is \`gcc-5\`:\n" + printf " apt-get install gnat-5 && make crossgcc\n" + fi timeout 30 LANGUAGES="${DEFAULT_LANGUAGES}" fi diff --git a/util/crossgcc/patches/clang-18.1.8.src_x86_baremetal.patch b/util/crossgcc/patches/clang-18.1.8.src_x86_baremetal.patch deleted file mode 100644 index 61c608cbbe2..00000000000 --- a/util/crossgcc/patches/clang-18.1.8.src_x86_baremetal.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git a/lib/Driver/ToolChains/BareMetal.cpp b/lib/Driver/ToolChains/BareMetal.cpp -index 852e0442..eb84a785 100644 ---- a/lib/Driver/ToolChains/BareMetal.cpp -+++ b/lib/Driver/ToolChains/BareMetal.cpp -@@ -169,6 +169,12 @@ static bool isPPCBareMetal(const llvm::Triple &Triple) { - Triple.getEnvironment() == llvm::Triple::EABI; - } - -+/// Is the triple x86_32 or x86_64 -*-none-elf? -+static bool isX86BareMetal(const llvm::Triple &Triple) { -+ return Triple.isX86() && Triple.getOS() == llvm::Triple::UnknownOS && -+ Triple.getEnvironmentName() == "elf"; -+} -+ - static void findMultilibsFromYAML(const ToolChain &TC, const Driver &D, - StringRef MultilibPath, const ArgList &Args, - DetectedMultilibs &Result) { -@@ -234,9 +240,10 @@ void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple, - - bool BareMetal::handlesTarget(const llvm::Triple &Triple) { - return isARMBareMetal(Triple) || isAArch64BareMetal(Triple) || -- isRISCVBareMetal(Triple) || isPPCBareMetal(Triple); -+ isRISCVBareMetal(Triple) || isPPCBareMetal(Triple) || isX86BareMetal(Triple); - } - -+ - Tool *BareMetal::buildLinker() const { - return new tools::baremetal::Linker(*this); - } diff --git a/util/crossgcc/patches/clang-21.1.8.src_x86_baremetal.patch b/util/crossgcc/patches/clang-21.1.8.src_x86_baremetal.patch new file mode 100644 index 00000000000..809b2903396 --- /dev/null +++ b/util/crossgcc/patches/clang-21.1.8.src_x86_baremetal.patch @@ -0,0 +1,25 @@ +diff -u a/lib/Driver/ToolChains/BareMetal.cpp b/lib/Driver/ToolChains/BareMetal.cpp +--- a/lib/Driver/ToolChains/BareMetal.cpp ++++ b/lib/Driver/ToolChains/BareMetal.cpp +@@ -51,6 +51,12 @@ + Triple.getEnvironment() == llvm::Triple::EABI; + } + ++/// Is the triple x86_32 or x86_64 -*-none-elf? ++static bool isX86BareMetal(const llvm::Triple &Triple) { ++ return Triple.isX86() && Triple.getOS() == llvm::Triple::UnknownOS && ++ Triple.getEnvironmentName() == "elf"; ++} ++ + static bool findRISCVMultilibs(const Driver &D, + const llvm::Triple &TargetTriple, + const ArgList &Args, DetectedMultilibs &Result) { +@@ -351,7 +357,7 @@ + bool BareMetal::handlesTarget(const llvm::Triple &Triple) { + return arm::isARMEABIBareMetal(Triple) || + aarch64::isAArch64BareMetal(Triple) || isRISCVBareMetal(Triple) || +- isPPCBareMetal(Triple); ++ isPPCBareMetal(Triple) || isX86BareMetal(Triple); + } + + Tool *BareMetal::buildLinker() const { diff --git a/util/crossgcc/sum/clang-18.1.8.src.tar.xz.cksum b/util/crossgcc/sum/clang-18.1.8.src.tar.xz.cksum deleted file mode 100644 index a517ab901ac..00000000000 --- a/util/crossgcc/sum/clang-18.1.8.src.tar.xz.cksum +++ /dev/null @@ -1 +0,0 @@ -581e929ba0d9fafc555081ab18d8c3fdf4478ac2 tarballs/clang-18.1.8.src.tar.xz diff --git a/util/crossgcc/sum/clang-21.1.8.src.tar.xz.cksum b/util/crossgcc/sum/clang-21.1.8.src.tar.xz.cksum new file mode 100644 index 00000000000..243e5e2616a --- /dev/null +++ b/util/crossgcc/sum/clang-21.1.8.src.tar.xz.cksum @@ -0,0 +1 @@ +052b4b826aba886d0a3fada696445d2fb1ffec88 tarballs/clang-21.1.8.src.tar.xz diff --git a/util/crossgcc/sum/clang-tools-extra-18.1.8.src.tar.xz.cksum b/util/crossgcc/sum/clang-tools-extra-18.1.8.src.tar.xz.cksum deleted file mode 100644 index 6b9b67cb643..00000000000 --- a/util/crossgcc/sum/clang-tools-extra-18.1.8.src.tar.xz.cksum +++ /dev/null @@ -1 +0,0 @@ -32923b812700526b76451384e4662ca45360d564 tarballs/clang-tools-extra-18.1.8.src.tar.xz diff --git a/util/crossgcc/sum/clang-tools-extra-21.1.8.src.tar.xz.cksum b/util/crossgcc/sum/clang-tools-extra-21.1.8.src.tar.xz.cksum new file mode 100644 index 00000000000..0e31f14c51c --- /dev/null +++ b/util/crossgcc/sum/clang-tools-extra-21.1.8.src.tar.xz.cksum @@ -0,0 +1 @@ +2429c7b1836e6db177e26cf4c85b5a817cda7c62 tarballs/clang-tools-extra-21.1.8.src.tar.xz diff --git a/util/crossgcc/sum/cmake-18.1.8.src.tar.xz.cksum b/util/crossgcc/sum/cmake-18.1.8.src.tar.xz.cksum deleted file mode 100644 index d0e63313d94..00000000000 --- a/util/crossgcc/sum/cmake-18.1.8.src.tar.xz.cksum +++ /dev/null @@ -1 +0,0 @@ -1ea03e355b705b4cada3051bd7301a57daa19283 tarballs/cmake-18.1.8.src.tar.xz diff --git a/util/crossgcc/sum/cmake-21.1.8.src.tar.xz.cksum b/util/crossgcc/sum/cmake-21.1.8.src.tar.xz.cksum new file mode 100644 index 00000000000..63174983554 --- /dev/null +++ b/util/crossgcc/sum/cmake-21.1.8.src.tar.xz.cksum @@ -0,0 +1 @@ +da308aa4c0e80835e123771ebe3e5fbfc5244a45 tarballs/cmake-21.1.8.src.tar.xz diff --git a/util/crossgcc/sum/compiler-rt-18.1.8.src.tar.xz.cksum b/util/crossgcc/sum/compiler-rt-18.1.8.src.tar.xz.cksum deleted file mode 100644 index 711ef353c43..00000000000 --- a/util/crossgcc/sum/compiler-rt-18.1.8.src.tar.xz.cksum +++ /dev/null @@ -1 +0,0 @@ -6ecbfa5516b60adb4e4e60f991b0d8ddf5aab12a tarballs/compiler-rt-18.1.8.src.tar.xz diff --git a/util/crossgcc/sum/compiler-rt-21.1.8.src.tar.xz.cksum b/util/crossgcc/sum/compiler-rt-21.1.8.src.tar.xz.cksum new file mode 100644 index 00000000000..2362125c5a4 --- /dev/null +++ b/util/crossgcc/sum/compiler-rt-21.1.8.src.tar.xz.cksum @@ -0,0 +1 @@ +141a3877eedd036349feaddc0d303abeeff96b6c tarballs/compiler-rt-21.1.8.src.tar.xz diff --git a/util/crossgcc/sum/libunwind-18.1.8.src.tar.xz.cksum b/util/crossgcc/sum/libunwind-18.1.8.src.tar.xz.cksum deleted file mode 100644 index d3819e303a0..00000000000 --- a/util/crossgcc/sum/libunwind-18.1.8.src.tar.xz.cksum +++ /dev/null @@ -1 +0,0 @@ -5bee6cd2847f6d468861c78a21236e1c6fdc8374 tarballs/libunwind-18.1.8.src.tar.xz diff --git a/util/crossgcc/sum/libunwind-21.1.8.src.tar.xz.cksum b/util/crossgcc/sum/libunwind-21.1.8.src.tar.xz.cksum new file mode 100644 index 00000000000..6b0516a6b27 --- /dev/null +++ b/util/crossgcc/sum/libunwind-21.1.8.src.tar.xz.cksum @@ -0,0 +1 @@ +c71485804e2a8e531469ee461fc312218686d641 tarballs/libunwind-21.1.8.src.tar.xz diff --git a/util/crossgcc/sum/lld-18.1.8.src.tar.xz.cksum b/util/crossgcc/sum/lld-18.1.8.src.tar.xz.cksum deleted file mode 100644 index 490a83596e6..00000000000 --- a/util/crossgcc/sum/lld-18.1.8.src.tar.xz.cksum +++ /dev/null @@ -1 +0,0 @@ -1cf1fa9848b05a07d3d52e69949d44003f2ab2af tarballs/lld-18.1.8.src.tar.xz diff --git a/util/crossgcc/sum/lld-21.1.8.src.tar.xz.cksum b/util/crossgcc/sum/lld-21.1.8.src.tar.xz.cksum new file mode 100644 index 00000000000..6e98bb89dc5 --- /dev/null +++ b/util/crossgcc/sum/lld-21.1.8.src.tar.xz.cksum @@ -0,0 +1 @@ +c41039defb66d59d292567fe1d3e4d28fc2dec70 tarballs/lld-21.1.8.src.tar.xz diff --git a/util/crossgcc/sum/llvm-18.1.8.src.tar.xz.cksum b/util/crossgcc/sum/llvm-18.1.8.src.tar.xz.cksum deleted file mode 100644 index 4845fb5b01d..00000000000 --- a/util/crossgcc/sum/llvm-18.1.8.src.tar.xz.cksum +++ /dev/null @@ -1 +0,0 @@ -f9befa4cbef3f688ab48fca42449e13c5bcb872d tarballs/llvm-18.1.8.src.tar.xz diff --git a/util/crossgcc/sum/llvm-21.1.8.src.tar.xz.cksum b/util/crossgcc/sum/llvm-21.1.8.src.tar.xz.cksum new file mode 100644 index 00000000000..a4ca09f05e6 --- /dev/null +++ b/util/crossgcc/sum/llvm-21.1.8.src.tar.xz.cksum @@ -0,0 +1 @@ +5aea9c8a3b1f1fa7ddebc2d2cc6742d4a1ee569e tarballs/llvm-21.1.8.src.tar.xz diff --git a/util/crossgcc/sum/runtimes-18.1.8.src.tar.xz.cksum b/util/crossgcc/sum/runtimes-18.1.8.src.tar.xz.cksum deleted file mode 100644 index fbee9941d1f..00000000000 --- a/util/crossgcc/sum/runtimes-18.1.8.src.tar.xz.cksum +++ /dev/null @@ -1 +0,0 @@ -4a5ea2f22b2d81467e739f4b070cf7ff52785856 tarballs/runtimes-18.1.8.src.tar.xz diff --git a/util/crossgcc/sum/runtimes-21.1.8.src.tar.xz.cksum b/util/crossgcc/sum/runtimes-21.1.8.src.tar.xz.cksum new file mode 100644 index 00000000000..0022a207577 --- /dev/null +++ b/util/crossgcc/sum/runtimes-21.1.8.src.tar.xz.cksum @@ -0,0 +1 @@ +2edc085c606ef464cde44b5cbfb5727c59ae2fd3 tarballs/runtimes-21.1.8.src.tar.xz diff --git a/util/crossgcc/sum/third-party-21.1.8.src.tar.xz.cksum b/util/crossgcc/sum/third-party-21.1.8.src.tar.xz.cksum new file mode 100644 index 00000000000..654980e1a14 --- /dev/null +++ b/util/crossgcc/sum/third-party-21.1.8.src.tar.xz.cksum @@ -0,0 +1 @@ +a1a50bb1f6a02aa82ef6de5942b164061f9acbc4 tarballs/third-party-21.1.8.src.tar.xz diff --git a/util/font/generate_font.py b/util/font/generate_font.py new file mode 100644 index 00000000000..81b45b16897 --- /dev/null +++ b/util/font/generate_font.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later + +""" +This utility generates an anti-aliased (smoothed) font table from a TTF/OTF file. +The output is a C source file containing: +1. Font dimensions and range macros. +2. An 8-bit alpha map font table (0=transparent, 255=opaque). +3. A character width table for proportional spacing. + +Usage: + python generate_font.py --width 24 --height 32 > font_table.c +""" +import argparse +from PIL import Image, ImageFont, ImageDraw +import sys +import os + +# PRINTABLE ASCII RANGE +START_CHAR = 32 +END_CHAR = 126 +NUM_CHARS = END_CHAR - START_CHAR + 1 + +def generate_c_table(font_path, canvas_width, canvas_height): + if not os.path.exists(font_path): + print(f"Error: Font file '{font_path}' not found.", file=sys.stderr) + sys.exit(1) + + # RESTRICTION: Width and Height checks for firmware safety + if canvas_width > 64 or canvas_height > 64: + print(f"Warning: Large dimensions ({canvas_width}x{canvas_height}) " + "will consume significant flash memory.", file=sys.stderr) + + # Validation: Basic sanity check for positive dimensions + if canvas_width <= 0 or canvas_height <= 0: + print("Error: Width and Height must be positive integers.", file=sys.stderr) + sys.exit(1) + + # Use canvas_width as font size to maintain original calculation style + font_size = canvas_width + + try: + font = ImageFont.truetype(font_path, font_size) + except OSError: + print(f"Error: Could not open font file '{font_path}'.", file=sys.stderr) + sys.exit(1) + + # Check for vertical clipping based on font metrics + ascent, descent = font.getmetrics() + total_font_height = ascent + descent + if total_font_height > canvas_height: + print(f"Warning: Font vertical size ({total_font_height}px) exceeds " + f"canvas height ({canvas_height}px).", file=sys.stderr) + y_offset = 0 + else: + y_offset = (canvas_height - total_font_height) // 2 + + # Header for the generated C file + print("/* SPDX-License-Identifier: GPL-2.0-or-later */\n") + print("/*") + print(" * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.") + print(f" * Source: {os.path.basename(font_path)}") + print(f" * Command: python {os.path.basename(__file__)} {font_path} --width {canvas_width} --height {canvas_height}") + print(" */\n") + print("#include \n") + + # 1. Output the Macros for C code usage + print(f"#define FONT_WIDTH {canvas_width}") + print(f"#define FONT_HEIGHT {canvas_height}") + print(f"#define FONT_START_CHAR {START_CHAR}") + print(f"#define FONT_END_CHAR {END_CHAR}") + print(f"#define FONT_NUM_CHARS (FONT_END_CHAR - FONT_START_CHAR + 1)\n") + + widths = [] + + print(f"const uint8_t font_table[FONT_NUM_CHARS][FONT_HEIGHT * FONT_WIDTH] = {{") + + clipped_glyphs = [] + + for char_code in range(START_CHAR, END_CHAR + 1): + char = chr(char_code) + image = Image.new("L", (canvas_width, canvas_height), 0) + draw = ImageDraw.Draw(image) + draw.text((0, y_offset), char, font=font, fill=255) + + pixels = list(image.getdata()) + + leftmost = canvas_width + rightmost = 0 + has_pixels = False + + for y in range(canvas_height): + for x in range(canvas_width): + if pixels[y * canvas_width + x] > 0: + if x < leftmost: leftmost = x + if x > rightmost: rightmost = x + has_pixels = True + + if has_pixels: + actual_width = rightmost - leftmost + 1 + if actual_width >= canvas_width: + clipped_glyphs.append(char) + else: + actual_width = canvas_width // 3 # Default width for space + + widths.append(actual_width) + + char_repr = f"'{char}'" if char not in ["'", "\\"] else f"'\\{char}'" + + print(f"\t[0x{char_code:02x} - FONT_START_CHAR] = {{") + + # Format with line breaks every 8 entries + for i in range(0, len(pixels), canvas_width): + row = pixels[i : i + canvas_width] + for j in range(0, len(row), 8): + chunk = row[j : j + 8] + line = ", ".join([f"0x{p:02x}" for p in chunk]) + print(f"\t\t{line},") + + print(f"\t}}, /* {char_repr} */") + + print("};\n") + + # 3. Output Width Table + print(f"const uint8_t font_widths[FONT_NUM_CHARS] = {{") + for i, w in enumerate(widths): + char_code = i + START_CHAR + print(f"\t[0x{char_code:02x} - FONT_START_CHAR] = {w},") + print("};") + + if clipped_glyphs: + print(f"/* Warning: Characters clipped: {' '.join(clipped_glyphs)} */", file=sys.stderr) + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Generate anti-aliased font table.") + parser.add_argument("font_path", help="Path to TTF/OTF font file") + parser.add_argument("--width", type=int, default=24, help="Canvas width (default: 24)") + parser.add_argument("--height", type=int, default=32, help="Canvas height (default: 32)") + + args = parser.parse_args() + generate_c_table(args.font_path, args.width, args.height) diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c index 75238c73b2b..c741e1d7c5d 100644 --- a/util/ifdtool/ifdtool.c +++ b/util/ifdtool/ifdtool.c @@ -1094,7 +1094,7 @@ static void create_fmap_template(char *image, int size, const char *layout_fname exit(EXIT_FAILURE); } - char *bbuf = "FLASH ##ROM_SIZE## {\n"; + char *bbuf = "FLASH ##FLASH_SIZE## {\n"; if (write(layout_fd, bbuf, strlen(bbuf)) < 0) { perror("Could not write to file"); exit(EXIT_FAILURE); @@ -2094,7 +2094,18 @@ static void new_layout(const char *filename, char *image, int size, for (j = i + 1; j < max_regions; j++) { if (regions_collide(&new_regions[i], &new_regions[j])) { - fprintf(stderr, "Regions would overlap.\n"); + fprintf(stderr, "Regions would overlap:\n"); + + /* See which string is longer and make sure we pad the shorter one */ + int region_name_len_i = strlen(region_name(i)); + int region_name_len_j = strlen(region_name(j)); + int padding = MAX(region_name_len_i, region_name_len_j); + + /* Print the regions that overlap, and where each region is */ + fprintf(stderr, " %*s : %x-%x\n", padding, region_name(i), + new_regions[i].base, new_regions[i].limit); + fprintf(stderr, " %*s : %x-%x\n", padding, region_name(j), + new_regions[j].base, new_regions[j].limit); exit(EXIT_FAILURE); } } diff --git a/util/inteltool/amb.c b/util/inteltool/amb.c index 961c0abf364..b01ea4326bf 100644 --- a/util/inteltool/amb.c +++ b/util/inteltool/amb.c @@ -431,7 +431,7 @@ int print_ambs(struct pci_dev *dev, struct pci_access *pacc) break; default: - fprintf(stderr, "Error: Dumping AMBs on this MCH is not (yet) supported.\n"); + printf("Error: Dumping AMBs on this MCH is not (yet) supported.\n"); return 1; } diff --git a/util/inteltool/gpio.c b/util/inteltool/gpio.c index ff21d2452b9..891b3abffd3 100644 --- a/util/inteltool/gpio.c +++ b/util/inteltool/gpio.c @@ -228,7 +228,7 @@ static const io_register_t pch_gpio_registers[] = { { 0x40, 4, "GPIO_USE_SEL3" }, { 0x44, 4, "GP_IO_SEL3" }, { 0x48, 4, "GP_LVL3" }, - { 0x4c, 4, "RESERVED" }, + { 0x4c, 4, "GPI_INV2" }, // GPIO Signal Invert 2 { 0x50, 4, "RESERVED" }, { 0x54, 4, "RESERVED" }, { 0x58, 4, "RESERVED" }, @@ -861,6 +861,9 @@ int print_gpios(struct pci_dev *sb, int show_all, int show_diffs) case PCI_DEVICE_ID_INTEL_HM97: case PCI_DEVICE_ID_INTEL_Z97: case PCI_DEVICE_ID_INTEL_H97: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER: + case PCI_DEVICE_ID_INTEL_WELLSBURG_C612: + case PCI_DEVICE_ID_INTEL_WELLSBURG_X99: gpiobase = pci_read_word(sb, 0x48) & 0xfffc; gpio_registers = pch_gpio_registers; size = ARRAY_SIZE(pch_gpio_registers); @@ -1118,6 +1121,8 @@ int print_gpios(struct pci_dev *sb, int show_all, int show_diffs) case PCI_DEVICE_ID_INTEL_B760: case PCI_DEVICE_ID_INTEL_HM770: case PCI_DEVICE_ID_INTEL_WM790: + case PCI_DEVICE_ID_INTEL_HM470: + case PCI_DEVICE_ID_INTEL_Q470: case PCI_DEVICE_ID_INTEL_C262: case PCI_DEVICE_ID_INTEL_C266: case PCI_DEVICE_ID_INTEL_ADL_P: @@ -1133,6 +1138,7 @@ int print_gpios(struct pci_dev *sb, int show_all, int show_diffs) case PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_3: case PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_4: case PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_5: + case PCI_DEVICE_ID_INTEL_CORE_ARL_ID_H_1: case PCI_DEVICE_ID_INTEL_MTL_0: case PCI_DEVICE_ID_INTEL_MTL_1: case PCI_DEVICE_ID_INTEL_MTL_2: @@ -1141,6 +1147,7 @@ int print_gpios(struct pci_dev *sb, int show_all, int show_diffs) case PCI_DEVICE_ID_INTEL_MTL_5: case PCI_DEVICE_ID_INTEL_MTL_6: case PCI_DEVICE_ID_INTEL_MTL_7: + case PCI_DEVICE_ID_INTEL_ARL_1: print_gpio_groups(sb); return 0; case PCI_DEVICE_ID_INTEL_82371XX: diff --git a/util/inteltool/gpio_groups.c b/util/inteltool/gpio_groups.c index fb50905b25a..77b808fff91 100644 --- a/util/inteltool/gpio_groups.c +++ b/util/inteltool/gpio_groups.c @@ -186,6 +186,8 @@ const struct gpio_community *const *get_gpio_communities(struct pci_dev *const s case PCI_DEVICE_ID_INTEL_QM370: case PCI_DEVICE_ID_INTEL_HM370: case PCI_DEVICE_ID_INTEL_CM246: + case PCI_DEVICE_ID_INTEL_HM470: + case PCI_DEVICE_ID_INTEL_Q470: *community_count = ARRAY_SIZE(cannonlake_pch_h_communities); *pad_stepping = 16; return cannonlake_pch_h_communities; @@ -264,6 +266,7 @@ const struct gpio_community *const *get_gpio_communities(struct pci_dev *const s case PCI_DEVICE_ID_INTEL_MTL_5: case PCI_DEVICE_ID_INTEL_MTL_6: case PCI_DEVICE_ID_INTEL_MTL_7: + case PCI_DEVICE_ID_INTEL_ARL_1: *community_count = ARRAY_SIZE(meteorlake_pch_communities); *pad_stepping = 16; return meteorlake_pch_communities; diff --git a/util/inteltool/inteltool.c b/util/inteltool/inteltool.c index d58b8507172..05d5c092fd5 100644 --- a/util/inteltool/inteltool.c +++ b/util/inteltool/inteltool.c @@ -145,11 +145,27 @@ static const struct { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_10TH_GEN_U, "10th generation (Icelake family) Core Processor (Mobile)" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_U1, - "10th generation (Comet Lake family) Core Processor (Mobile)" }, + "10th generation (Comet Lake-U family) Core Processor (Mobile)" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_U2, - "10th generation (Comet Lake family) Core Processor (Mobile)" }, + "10th generation (Comet Lake-U family) Core Processor (Mobile)" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_U3, - "10th generation (Comet Lake family) Core Processor (Mobile)" }, + "10th generation (Comet Lake-U family) Core Processor (Mobile)" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_H_8_2, + "10th generation (Comet Lake-H family) Core Processor (Mobile)" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_H_6_2, + "10th generation (Comet Lake-H family) Core Processor (Mobile)" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_H_4_2, + "10th generation (Comet Lake-H family) Core Processor (Mobile)" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_S_10, + "10th generation (Comet Lake-S family) Core Processor (Desktop)" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_S_8, + "10th generation (Comet Lake-S family) Core Processor (Desktop)" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_S_6, + "10th generation (Comet Lake-S family) Core Processor (Desktop)" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_S_4, + "10th generation (Comet Lake-S family) Core Processor (Desktop)" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_CML_S_2, + "10th generation (Comet Lake-S family) Core Processor (Desktop)" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HEWITTLAKE, "Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D (Hewitt Lake)" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SAPPHIRERAPIDS_SP, @@ -204,6 +220,8 @@ static const struct { "14th generation (Meteor Lake P family) Core Processor"}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_5, "14th generation (Meteor Lake P family) Core Processor"}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_ARL_ID_H_1, + "14th generation (Arrow Lake H family) Core Processor"}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ELKHART_LAKE_1, "Elkhart Lake Processor" }, @@ -429,10 +447,15 @@ static const struct { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Z97, "Z97"}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_H97, "H97"}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL_LPC, "Apollo Lake" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER, "Wellsburg Super SKU" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_C612, "Wellsburg C612" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WELLSBURG_X99, "Wellsburg X99" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DNV_LPC, "Denverton" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GLK_LPC, "Gemini Lake" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_H510, "H510" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_H570, "H570" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Q470, "Q470" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HM470, "HM470" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Z590, "Z590" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Q570, "Q570" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_B560, "B560" }, @@ -463,8 +486,12 @@ static const struct { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_C266, "C266" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL, "Elkhart Lake" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_JSL, "Jasper Lake" }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_N, "Alder Lake-N"}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_RPL_P, "Raptor Lake" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_M, "Alder Lake-M" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_N, "Alder Lake-N" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_P, "Alder Lake-P" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_RPL_P, "Raptor Lake-P" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MTL_P, "Meteor Lake-P"}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ARL_H, "Arrow Lake-H"}, /* Intel GPUs */ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_G35_EXPRESS, @@ -613,6 +640,22 @@ static const struct { "Intel(R) UHD Graphics for 11th Gen Intel(R) Processors" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGL_GT2_ULT_2, "Intel(R) UHD Graphics for 11th Gen Intel(R) Processors" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT1_S_1, + "Intel(R) CometLake-S GT1" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT1_S_2, + "Intel(R) CometLake-S GT1" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT2_S_G0, + "Intel(R) CometLake-S GT2" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT2_S_P0, + "Intel(R) CometLake-S GT2" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT1_H_1, + "Intel(R) CometLake-H GT1" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT1_H_2, + "Intel(R) CometLake-H GT1" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT2_H_R0, + "Intel(R) CometLake-H GT2" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CML_GT2_H_R1, + "Intel(R) CometLake-H GT2" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_S_GT1, "Intel(R) AlderLake-S GT1" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ADL_S_GT1_2, @@ -643,6 +686,8 @@ static const struct { "Intel(R) MeteorLake-P GT2" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MTL_P_GT2_4, "Intel(R) MeteorLake-P GT2" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ARL_H_GT2_1, + "Intel(R) ArrowLake-H GT2" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_GT1_1, "Intel(R) Elkhart Lake GT1" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_GT1_2, diff --git a/util/inteltool/inteltool.h b/util/inteltool/inteltool.h index f0ddef283d2..e38fb190bb9 100644 --- a/util/inteltool/inteltool.h +++ b/util/inteltool/inteltool.h @@ -224,6 +224,8 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_WM590 0x4389 #define PCI_DEVICE_ID_INTEL_QM580 0x438a #define PCI_DEVICE_ID_INTEL_HM570 0x438b +#define PCI_DEVICE_ID_INTEL_Q470 0x0687 +#define PCI_DEVICE_ID_INTEL_HM470 0x068d #define PCI_DEVICE_ID_INTEL_C252 0x438c #define PCI_DEVICE_ID_INTEL_C256 0x438d #define PCI_DEVICE_ID_INTEL_W580 0x438f @@ -258,6 +260,8 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_MTL_6 0x7e06 #define PCI_DEVICE_ID_INTEL_MTL_7 0x7e07 +#define PCI_DEVICE_ID_INTEL_ARL_1 0x7702 + #define PCI_DEVICE_ID_INTEL_82810 0x7120 #define PCI_DEVICE_ID_INTEL_82810_DC 0x7122 #define PCI_DEVICE_ID_INTEL_82810E_DC 0x7124 @@ -305,6 +309,9 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_HM97 0x8cc3 #define PCI_DEVICE_ID_INTEL_Z97 0x8cc4 #define PCI_DEVICE_ID_INTEL_H97 0x8cc6 +#define PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER 0x8d40 +#define PCI_DEVICE_ID_INTEL_WELLSBURG_C612 0x8d44 +#define PCI_DEVICE_ID_INTEL_WELLSBURG_X99 0x8d47 #define PCI_DEVICE_ID_INTEL_82X58 0x3405 #define PCI_DEVICE_ID_INTEL_SCH_POULSBO 0x8100 @@ -321,6 +328,9 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_RPL_P 0x519d #define PCI_DEVICE_ID_INTEL_ADL_N 0x5481 +#define PCI_DEVICE_ID_INTEL_MTL_P 0x7e27 +#define PCI_DEVICE_ID_INTEL_ARL_H 0x7727 + #define PCI_DEVICE_ID_INTEL_EHL 0x4b00 #define PCI_DEVICE_ID_INTEL_JSL 0x4d87 @@ -394,6 +404,14 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_CORE_CML_U1 0x9b51 /* Cometlake U (Mobile) */ #define PCI_DEVICE_ID_INTEL_CORE_CML_U2 0x9b61 /* Cometlake U (Mobile) */ #define PCI_DEVICE_ID_INTEL_CORE_CML_U3 0x9b71 /* Cometlake U (Mobile) */ +#define PCI_DEVICE_ID_INTEL_CORE_CML_H_8_2 0x9b44 /* Cometlake H 8+2 (Mobile) */ +#define PCI_DEVICE_ID_INTEL_CORE_CML_H_6_2 0x9b54 /* Cometlake H 6+2 (Mobile) */ +#define PCI_DEVICE_ID_INTEL_CORE_CML_H_4_2 0x9b64 /* Cometlake H 4+2 (Mobile) */ +#define PCI_DEVICE_ID_INTEL_CORE_CML_S_10 0x9b33 /* Cometlake S 10 (Desktop) */ +#define PCI_DEVICE_ID_INTEL_CORE_CML_S_8 0x9b43 /* Cometlake S 8 (Desktop) */ +#define PCI_DEVICE_ID_INTEL_CORE_CML_S_6 0x9b53 /* Cometlake S 6 (Desktop) */ +#define PCI_DEVICE_ID_INTEL_CORE_CML_S_4 0x9b63 /* Cometlake S 4 (Desktop) */ +#define PCI_DEVICE_ID_INTEL_CORE_CML_S_2 0x9b73 /* Cometlake S 2 (Desktop) */ #define PCI_DEVICE_ID_INTEL_CORE_TGL_ID_U_2 0x9a04 /* Tigerlake UP3 2 Cores */ #define PCI_DEVICE_ID_INTEL_CORE_TGL_ID_U_4 0x9a14 /* Tigerlake UP3 4 Cores */ #define PCI_DEVICE_ID_INTEL_CORE_TGL_ID_Y_2 0x9a02 /* Tigerlake UP4 2 Cores */ @@ -420,6 +438,7 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_CORE_MTL_ID_M 0x7D00 /* Meteorlake M */ #define PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_1 0x7D01 /* Meteorlake P */ #define PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_2 0x7D02 /* Meteorlake P */ +#define PCI_DEVICE_ID_INTEL_CORE_ARL_ID_H_1 0x7D06 /* Arrowlake H */ #define PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_3 0x7d14 /* Meteorlake P */ #define PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_4 0x7d15 /* Meteorlake P */ #define PCI_DEVICE_ID_INTEL_CORE_MTL_ID_P_5 0x7d16 /* Meteorlake P */ @@ -500,6 +519,14 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_TGL_GT1_2 0x9A68 #define PCI_DEVICE_ID_INTEL_TGL_GT2_ULT_1 0x9A78 #define PCI_DEVICE_ID_INTEL_TGL_GT2_ULT_2 0x9A70 +#define PCI_DEVICE_ID_INTEL_CML_GT1_S_1 0x9BA5 +#define PCI_DEVICE_ID_INTEL_CML_GT1_S_2 0x9BA8 +#define PCI_DEVICE_ID_INTEL_CML_GT2_S_G0 0x9BC8 +#define PCI_DEVICE_ID_INTEL_CML_GT2_S_P0 0x9BC5 +#define PCI_DEVICE_ID_INTEL_CML_GT1_H_1 0x9BA4 +#define PCI_DEVICE_ID_INTEL_CML_GT1_H_2 0x9BA2 +#define PCI_DEVICE_ID_INTEL_CML_GT2_H_R0 0x9BC2 +#define PCI_DEVICE_ID_INTEL_CML_GT2_H_R1 0x9BC4 /* Elkhart Lake */ #define PCI_DEVICE_ID_INTEL_EHL_GT1_1 0x4541 #define PCI_DEVICE_ID_INTEL_EHL_GT1_2 0x4551 @@ -521,6 +548,7 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_MTL_P_GT2_2 0x7d50 #define PCI_DEVICE_ID_INTEL_MTL_P_GT2_3 0x7d55 #define PCI_DEVICE_ID_INTEL_MTL_P_GT2_4 0x7d60 +#define PCI_DEVICE_ID_INTEL_ARL_H_GT2_1 0x7d51 #define PCI_DEVICE_ID_INTEL_RPL_H_IRIS_XE 0xa7a0 #if !defined(__DARWIN__) && !defined(__FreeBSD__) diff --git a/util/inteltool/lpc.c b/util/inteltool/lpc.c index 4ce06ae5b9c..af452a24d1d 100644 --- a/util/inteltool/lpc.c +++ b/util/inteltool/lpc.c @@ -9,6 +9,47 @@ #define SUNRISE_LPC_BC 0xdc +static const io_register_t c610_lpc_cfg_registers[] = { + {0x00, 2, "VID"}, // Vendor Identification + {0x02, 2, "DID"}, // Device Identification + {0x04, 2, "PCICMD"}, // PCI Command + {0x06, 2, "PCISTS"}, // PCI Status + {0x08, 1, "RID"}, // Revision Identification + {0x09, 1, "PI"}, // Programming Interface + {0x0A, 1, "SCC"}, // Sub Class Code + {0x0B, 1, "BCC"}, // Base Class Code + {0x0D, 1, "PLT"}, // Primary Latency Timer + {0x0E, 1, "HEADTYP"}, // Header Type + {0x2C, 4, "SS"}, // Sub System Identifiers + {0x40, 4, "PMBASE"}, // ACPI Base Address + {0x44, 1, "ACPI_CNTL"}, // ACPI Control + {0x48, 4, "GPIOBASE"}, // ACPI Base Address + {0x4C, 1, "GC"}, // GPIO Control + {0x60, 4, "PIRQ[n]_ROUT"}, // PIRQ[A-D] Routing Control + {0x64, 1, "SIRQ_CNTL"}, // Serial IRQ Control + {0x68, 4, "PIRQ[n]_ROUT"}, // PIRQ[E-H] Routing Control + {0x6C, 2, "LPC_IBDF"}, // IOxAPIC Bus:Device:Function + {0x70, 8, "LPC_HnBDF"}, // HPET Configuration + {0x80, 1, "LPC_I/O_DEC"}, // I/O Decode + {0x82, 2, "LPC_EN"}, // LPC I/F Enables + {0x84, 4, "GEN1_DEC"}, // LPC I/F Generic Decode Range 1 + {0x88, 4, "GEN2_DEC"}, // LPC I/F Generic Decode Range 2 + {0x8C, 4, "GEN3_DEC"}, // LPC I/F Generic Decode Range 3 + {0x90, 4, "GEN4_DEC"}, // LPC I/F Generic Decode Range 4 00000000h R/W + {0x94, 4, "ULKMC"}, // USB Legacy Keyboard / Mouse Control 00000000h RO, R/WC, R/W, RW1L + {0x98, 4, "LGMR LPC"}, // I/F Generic Memory Range 00000000h R/W + {0xD0, 4, "BIOS_SEL1"}, // BIOS Select + {0xD4, 2, "BIOS_SEL2"}, // BIOS Select + {0xD8, 2, "BIOS_DEC_EN1"}, // BIOS Decode Enable + {0xDC, 1, "BIOS_CNTL"}, // BIOS Control + {0xE0, 2, "FDCAP"}, // Feature Detection Capability ID + {0xE2, 1, "FDLEN"}, // Feature Detection Capability Length + {0xE3, 1, "FDVER"}, // Feature Detection Version + {0xE4, 4, "FVECIDX"}, // Feature Vector Index + {0xE8, 4, "FVECD"}, // Feature Vector Data + {0xF0, 4, "RCBA"}, // Root Complex Base Address +}; + static const io_register_t sunrise_lpc_cfg_registers[] = { {0x00, 4, "ID"}, {0x04, 2, "CMD"}, @@ -109,6 +150,17 @@ int print_lpc(struct pci_dev *sb, struct pci_access *pacc) printf("\n========== LPC/eSPI =========\n\n"); switch (sb->device_id) { + case PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER: + case PCI_DEVICE_ID_INTEL_WELLSBURG_C612: + case PCI_DEVICE_ID_INTEL_WELLSBURG_X99: + dev = pci_get_dev(pacc, sb->domain, sb->bus, sb->dev, 0); + if (!dev) { + printf("LPC interface not found.\n"); + return 1; + } + cfg_registers = c610_lpc_cfg_registers; + cfg_registers_size = ARRAY_SIZE(c610_lpc_cfg_registers); + break; case PCI_DEVICE_ID_INTEL_H110: case PCI_DEVICE_ID_INTEL_H170: case PCI_DEVICE_ID_INTEL_Z170: @@ -150,7 +202,28 @@ int print_lpc(struct pci_dev *sb, struct pci_access *pacc) cfg_registers_size = ARRAY_SIZE(sunrise_lpc_cfg_registers); } break; + case PCI_DEVICE_ID_INTEL_HM470: + case PCI_DEVICE_ID_INTEL_Q470: + dev = pci_get_dev(pacc, sb->domain, sb->bus, sb->dev, 0); + if (!dev) { + printf("LPC/eSPI interface not found.\n"); + return 1; + } + bc = pci_read_long(dev, SUNRISE_LPC_BC); + if (bc & (1 << 2)) { + printf("Device 0:1f.0 is eSPI (BC.LPC_ESPI=1)\n\n"); + cfg_registers = alderlake_espi_cfg_registers; + cfg_registers_size = ARRAY_SIZE(alderlake_espi_cfg_registers); + } else { + printf("Device 0:1f.0 is LPC (BC.LPC_ESPI=0)\n\n"); + cfg_registers = sunrise_lpc_cfg_registers; + cfg_registers_size = ARRAY_SIZE(sunrise_lpc_cfg_registers); + } + break; + case PCI_DEVICE_ID_INTEL_ADL_M: case PCI_DEVICE_ID_INTEL_ADL_N: + case PCI_DEVICE_ID_INTEL_ADL_P: + case PCI_DEVICE_ID_INTEL_RPL_P: dev = pci_get_dev(pacc, sb->domain, sb->bus, sb->dev, 0); if (!dev) { printf("LPC/eSPI interface not found.\n"); @@ -191,6 +264,13 @@ int print_lpc(struct pci_dev *sb, struct pci_access *pacc) pci_read_long(dev, cfg_registers[i].addr), cfg_registers[i].name); break; + case 3: + printf("0x%04x: 0x%04x%02x (%s)\n", + cfg_registers[i].addr, + pci_read_word(dev, cfg_registers[i].addr), + pci_read_byte(dev, cfg_registers[i].addr + 2), + cfg_registers[i].name); + break; case 2: printf("0x%04x: 0x%04x (%s)\n", cfg_registers[i].addr, diff --git a/util/inteltool/memory.c b/util/inteltool/memory.c index bb7ad606171..0fb36aa38cc 100644 --- a/util/inteltool/memory.c +++ b/util/inteltool/memory.c @@ -229,6 +229,14 @@ int print_mchbar(struct pci_dev *nb, struct pci_access *pacc, const char *dump_s case PCI_DEVICE_ID_INTEL_CORE_CML_U1: case PCI_DEVICE_ID_INTEL_CORE_CML_U2: case PCI_DEVICE_ID_INTEL_CORE_CML_U3: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_8_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_6_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_4_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_10: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_8: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_6: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_4: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_2: mchbar_phys = pci_read_long(nb, 0x48); mchbar_phys |= ((uint64_t)pci_read_long(nb, 0x4c)) << 32; mchbar_phys &= 0x0000007fffff8000UL; /* 38:15 */ diff --git a/util/inteltool/pcie.c b/util/inteltool/pcie.c index 32afa714fc8..6544bac5a78 100644 --- a/util/inteltool/pcie.c +++ b/util/inteltool/pcie.c @@ -227,6 +227,35 @@ static const io_register_t alderlake_dmi_registers[] = { { 0x1D4, 4, "DMICEMSK" }, // DMI Correctable Error Mask }; +/* 10th Generation Intel® Core™ Processors, Datasheet Volume 2 of 2, ID 615211 */ +static const io_register_t cometlake_dmi_registers[] = { + { 0x00, 4, "DMIVCECH" }, // DMI Virtual Channel Enhanced Capability + { 0x04, 4, "DMIPVCCAP1" }, // DMI Port VC Capability Register 1 + { 0x08, 4, "DMIPVCCAP2" }, // DMI Port VC Capability Register 2 + { 0x0C, 2, "DMIPVCCTL" }, // DMI Port VC Control + { 0x10, 4, "DMIVC0RCAP" }, // DMI VC0 Resource Capability + { 0x14, 4, "DMIVC0RCTL" }, // DMI VC0 Resource Control + { 0x1A, 2, "DMIVC0RSTS" }, // DMI VC0 Resource Status + { 0x1C, 4, "DMIVC1RCAP" }, // DMI VC1 Resource Capability + { 0x20, 4, "DMIVC1RCTL" }, // DMI VC1 Resource Control + { 0x26, 2, "DMIVC1RSTS" }, // DMI VC1 Resource Status + { 0x34, 4, "DMIVCMRCAP" }, // DMI VCm Resource Capability + { 0x38, 4, "DMIVCMRCTL" }, // DMI VCm Resource Control + { 0x3E, 2, "DMIVCMRSTS" }, // DMI VCm Resource Status + { 0x40, 4, "DMIRCLDECH" }, // DMI Root Complex Link Declaration + { 0x44, 4, "DMIESD" }, // DMI Element Self Description + { 0x50, 4, "DMILE1D" }, // DMI Link Entry 1 Description + { 0x58, 4, "DMILE1A" }, // DMI Link Entry 1 Address + { 0x5C, 4, "DMILUE1A" }, // DMI Link Upper Entry 1 Address + { 0x60, 4, "DMILE2D" }, // DMI Link Entry 2 Description + { 0x68, 4, "DMILE2A" }, // DMI Link Entry 2 Address + { 0x84, 4, "LCAP" }, // Link Capabilities + { 0x88, 2, "LCTL" }, // Link Control + { 0x8A, 2, "LSTS" }, // DMI Link Status + { 0x98, 2, "LCTL2" }, // Link Control 2 + { 0x9A, 2, "LSTS2" }, // Link Status 2 +}; + /* * Egress Port Root Complex MMIO configuration space */ @@ -292,6 +321,17 @@ int print_epbar(struct pci_dev *nb) case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_8: case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4: case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4_1: + case PCI_DEVICE_ID_INTEL_CORE_CML_U1: + case PCI_DEVICE_ID_INTEL_CORE_CML_U2: + case PCI_DEVICE_ID_INTEL_CORE_CML_U3: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_8_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_6_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_4_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_10: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_8: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_6: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_4: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_2: epbar_phys = pci_read_long(nb, 0x40) & 0xfffffffe; epbar_phys |= ((uint64_t)pci_read_long(nb, 0x44)) << 32; break; @@ -433,6 +473,23 @@ int print_dmibar(struct pci_dev *nb) dmibar_phys |= ((uint64_t)pci_read_long(nb, 0x6c)) << 32; dmibar_phys &= 0x0000007ffffff000UL; /* 38:12 */ break; + case PCI_DEVICE_ID_INTEL_CORE_CML_U1: + case PCI_DEVICE_ID_INTEL_CORE_CML_U2: + case PCI_DEVICE_ID_INTEL_CORE_CML_U3: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_8_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_6_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_4_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_10: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_8: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_6: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_4: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_2: + dmi_registers = cometlake_dmi_registers; + size = ARRAY_SIZE(cometlake_dmi_registers); + dmibar_phys = pci_read_long(nb, 0x68); + dmibar_phys |= ((uint64_t)pci_read_long(nb, 0x6c)) << 32; + dmibar_phys &= 0x0000007ffffff000UL; /* 38:12 */ + break; case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_8: case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4: case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4_1: @@ -555,6 +612,17 @@ int print_pciexbar(struct pci_dev *nb) case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_8: case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4: case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4_1: + case PCI_DEVICE_ID_INTEL_CORE_CML_U1: + case PCI_DEVICE_ID_INTEL_CORE_CML_U2: + case PCI_DEVICE_ID_INTEL_CORE_CML_U3: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_8_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_6_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_H_4_2: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_10: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_8: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_6: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_4: + case PCI_DEVICE_ID_INTEL_CORE_CML_S_2: pciexbar_reg = pci_read_long(nb, 0x60); pciexbar_reg |= ((uint64_t)pci_read_long(nb, 0x64)) << 32; break; diff --git a/util/inteltool/pcr.c b/util/inteltool/pcr.c index 6594561257a..cfc12911f38 100644 --- a/util/inteltool/pcr.c +++ b/util/inteltool/pcr.c @@ -141,6 +141,8 @@ void pcr_init(struct pci_dev *const sb) case PCI_DEVICE_ID_INTEL_C252: case PCI_DEVICE_ID_INTEL_C256: case PCI_DEVICE_ID_INTEL_W580: + case PCI_DEVICE_ID_INTEL_HM470: + case PCI_DEVICE_ID_INTEL_Q470: case PCI_DEVICE_ID_INTEL_CANNONPOINT_LP_U_PREM: case PCI_DEVICE_ID_INTEL_COMETPOINT_LP_U_PREM: case PCI_DEVICE_ID_INTEL_COMETPOINT_LP_U_BASE: @@ -188,6 +190,7 @@ void pcr_init(struct pci_dev *const sb) case PCI_DEVICE_ID_INTEL_MTL_5: case PCI_DEVICE_ID_INTEL_MTL_6: case PCI_DEVICE_ID_INTEL_MTL_7: + case PCI_DEVICE_ID_INTEL_ARL_1: sbbar_phys = 0xe0000000; use_p2sb = false; break; diff --git a/util/inteltool/powermgt.c b/util/inteltool/powermgt.c index 716b85ce039..31b33252233 100644 --- a/util/inteltool/powermgt.c +++ b/util/inteltool/powermgt.c @@ -97,7 +97,8 @@ static const io_register_t pch_pm_registers[] = { { 0x52, 2, "RESERVED" }, { 0x54, 4, "RESERVED" }, { 0x58, 4, "RESERVED" }, - { 0x5c, 4, "RESERVED" }, + { 0x5c, 2, "ALT_GPI_SMI_EN2" }, // Alternate GPI SMI Enable 2 Register + { 0x5e, 2, "ALT_GPI_SMI_STS2" }, // Alternate GPI SMI Status 2 Register /* The TCO registers start here. */ { 0x60, 2, "TCO_RLD" }, { 0x62, 1, "TCO_DAT_IN" }, @@ -771,6 +772,9 @@ int print_pmbase(struct pci_dev *sb, struct pci_access *pacc) case PCI_DEVICE_ID_INTEL_HM97: case PCI_DEVICE_ID_INTEL_Z97: case PCI_DEVICE_ID_INTEL_H97: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER: + case PCI_DEVICE_ID_INTEL_WELLSBURG_C612: + case PCI_DEVICE_ID_INTEL_WELLSBURG_X99: pmbase = pci_read_word(sb, 0x40) & 0xff80; pm_registers = pch_pm_registers; pm_registers_size = ARRAY_SIZE(pch_pm_registers); diff --git a/util/inteltool/rootcmplx.c b/util/inteltool/rootcmplx.c index 87fa38ffbc1..965c492e8da 100644 --- a/util/inteltool/rootcmplx.c +++ b/util/inteltool/rootcmplx.c @@ -106,6 +106,9 @@ int print_rcba(struct pci_dev *sb) case PCI_DEVICE_ID_INTEL_HM97: case PCI_DEVICE_ID_INTEL_Z97: case PCI_DEVICE_ID_INTEL_H97: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER: + case PCI_DEVICE_ID_INTEL_WELLSBURG_C612: + case PCI_DEVICE_ID_INTEL_WELLSBURG_X99: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL: @@ -125,6 +128,8 @@ int print_rcba(struct pci_dev *sb) case PCI_DEVICE_ID_INTEL_ICH4M: case PCI_DEVICE_ID_INTEL_ICH5: case PCI_DEVICE_ID_INTEL_ADL_N: + case PCI_DEVICE_ID_INTEL_HM470: + case PCI_DEVICE_ID_INTEL_Q470: printf("This southbridge does not have RCBA.\n"); return 1; default: diff --git a/util/inteltool/spi.c b/util/inteltool/spi.c index cba43ed10e9..6d6b500eeb1 100644 --- a/util/inteltool/spi.c +++ b/util/inteltool/spi.c @@ -171,6 +171,53 @@ static const io_register_t elkhart_spi_bar_registers[] = { { 0x198, 4, "CSXE_WPR0 - Write Protected Range 0" }, }; +/* Intel® 400 Series Chipset Family Platform Controller Hub, 620855-002 */ +static const io_register_t cometlake_spi_bar_registers[] = { + { 0x00, 4, "BFPREG - BIOS Flash Primary Region" }, + { 0x04, 2, "HSFSTS - Hardware Sequencing Flash Status" }, + { 0x06, 2, "HSFCTL - Hardware Sequencing Flash Control" }, + { 0x08, 4, "FADDR - Flash Address" }, + { 0x0c, 4, "DLOCK - Discrete Lock Bits" }, + { 0x10, 4, "FDATA0 - Flash Data 0" }, + { 0x14, 4, "FDATA1 - Flash Data 1" }, + { 0x18, 4, "FDATA2 - Flash Data 2" }, + { 0x1c, 4, "FDATA3 - Flash Data 3" }, + { 0x20, 4, "FDATA4 - Flash Data 4" }, + { 0x24, 4, "FDATA5 - Flash Data 5" }, + { 0x28, 4, "FDATA6 - Flash Data 6" }, + { 0x2c, 4, "FDATA7 - Flash Data 7" }, + { 0x30, 4, "FDATA8 - Flash Data 8" }, + { 0x34, 4, "FDATA9 - Flash Data 9" }, + { 0x38, 4, "FDATA10 - Flash Data 10" }, + { 0x3c, 4, "FDATA11 - Flash Data 11" }, + { 0x40, 4, "FDATA12 - Flash Data 12" }, + { 0x44, 4, "FDATA13 - Flash Data 13" }, + { 0x48, 4, "FDATA14 - Flash Data 14" }, + { 0x4c, 4, "FDATA15 - Flash Data 15" }, + { 0x50, 4, "FRACC - Flash Region Access Permissions" }, + { 0x54, 4, "FREG0 - Flash Region 0" }, + { 0x58, 4, "FREG1 - Flash Region 1" }, + { 0x5c, 4, "FREG2 - Flash Region 2" }, + { 0x60, 4, "FREG3 - Flash Region 3" }, + { 0x64, 4, "FREG4 - Flash Region 4" }, + { 0x68, 4, "FREG5 - Flash Region 5" }, + { 0x84, 4, "FPR0 - Flash Protected Range 0" }, + { 0x88, 4, "FPR1 - Flash Protected Range 1" }, + { 0x8c, 4, "FPR2 - Flash Protected Range 2" }, + { 0x90, 4, "FPR3 - Flash Protected Range 3" }, + { 0x94, 4, "FPR4 - Flash Protected Range 4" }, + { 0x98, 4, "GPR0 - Global Protected Range 0" }, + { 0xb0, 4, "SFRACC - Secondary Flash Region Access Permissions" }, + { 0xb4, 4, "FDOC - Flash Descriptor Observability Control" }, + { 0xb8, 4, "FDOD - Flash Descriptor Observability Data" }, + { 0xc0, 4, "AFC - Additional Flash Control" }, + { 0xc4, 4, "SFDP0_VSCC0 - Vendor Specific Component Capabilities for Component 0" }, + { 0xc8, 4, "SFDP1_VSCC1 - Vendor Specific Component Capabilities for Component 1" }, + { 0xcc, 4, "PTINX - Parameter Table Index" }, + { 0xd0, 4, "PTDATA - Parameter Table Data" }, + { 0xd4, 4, "SBRS - SPI Bus Requester Status" }, +}; + static int print_bioscntl(struct pci_dev *sb) { int i, size = 0; @@ -274,6 +321,9 @@ static int print_bioscntl(struct pci_dev *sb) case PCI_DEVICE_ID_INTEL_HM97: case PCI_DEVICE_ID_INTEL_Z97: case PCI_DEVICE_ID_INTEL_H97: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER: + case PCI_DEVICE_ID_INTEL_WELLSBURG_C612: + case PCI_DEVICE_ID_INTEL_WELLSBURG_X99: case PCI_DEVICE_ID_INTEL_H110: case PCI_DEVICE_ID_INTEL_H170: case PCI_DEVICE_ID_INTEL_Z170: @@ -303,6 +353,8 @@ static int print_bioscntl(struct pci_dev *sb) size = ARRAY_SIZE(pch_bios_cntl_registers); break; case PCI_DEVICE_ID_INTEL_ADL_N: + case PCI_DEVICE_ID_INTEL_HM470: + case PCI_DEVICE_ID_INTEL_Q470: bios_cntl = pci_read_byte(sb, 0xdc); bios_cntl_register = adl_pch_bios_cntl_registers; size = ARRAY_SIZE(adl_pch_bios_cntl_registers); @@ -330,13 +382,29 @@ static int print_bioscntl(struct pci_dev *sb) return 0; } +static int get_espibar_phys(struct pci_dev *sb, struct pci_access *pacc, uint8_t func, uint8_t offset, uint32_t mask, uint32_t *addr) { + struct pci_dev *spidev; + + if (!(spidev = pci_get_dev(pacc, sb->domain, sb->bus, sb->dev, func))) { + fprintf(stderr, "Error: no spi device 0:31.%x\n", func); + return 1; + } + + *addr = pci_read_long(spidev, offset) & mask; + if (!*addr) { + fprintf(stderr, "Error: no valid bar 0 of device 0:31.%x found %x\n", func, *addr); + return 1; + } + + return 0; +} + static int print_spibar(struct pci_dev *sb, struct pci_access *pacc) { int i, size = 0, rcba_size = 0x4000; volatile uint8_t *rcba; uint32_t rcba_phys; const io_register_t *spi_register = NULL; uint32_t spibaroffset; - struct pci_dev *spidev; printf("\n============= SPI Bar ==============\n\n"); @@ -444,6 +512,9 @@ static int print_spibar(struct pci_dev *sb, struct pci_access *pacc) { case PCI_DEVICE_ID_INTEL_HM97: case PCI_DEVICE_ID_INTEL_Z97: case PCI_DEVICE_ID_INTEL_H97: + case PCI_DEVICE_ID_INTEL_WELLSBURG_SUPER: + case PCI_DEVICE_ID_INTEL_WELLSBURG_C612: + case PCI_DEVICE_ID_INTEL_WELLSBURG_X99: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL: @@ -461,23 +532,23 @@ static int print_spibar(struct pci_dev *sb, struct pci_access *pacc) { break; case PCI_DEVICE_ID_INTEL_EHL: /* the southbridge is the eSPI controller, we need to get the SPI flash controller */ - if (!(spidev = pci_get_dev(pacc, sb->domain, sb->bus, sb->dev, 5))) { - perror("Error: no spi device 0:31.5\n"); + /* this is not rcba, but we keep it to use common code */ + if (get_espibar_phys(sb, pacc, 5, 0x10, 0xfffff000, &rcba_phys)) return 1; - } - - rcba_phys = ((uint64_t)pci_read_long(spidev, 0x10) & 0xfffff000); rcba_size = 4096; - if (!rcba_phys) { - fprintf(stderr, "Error: no valid bar 0 of device 0:31.5 found %x %x\n", rcba_phys, rcba_size); - return 1; - } - - /* this is not rcba, but we keep it to use common code */ spibaroffset = 0; spi_register = elkhart_spi_bar_registers; size = ARRAY_SIZE(elkhart_spi_bar_registers); break; + case PCI_DEVICE_ID_INTEL_HM470: + case PCI_DEVICE_ID_INTEL_Q470: + if (get_espibar_phys(sb, pacc, 5, 0x10, 0xfffff000, &rcba_phys)) + return 1; + rcba_size = 4096; + spibaroffset = 0; + spi_register = cometlake_spi_bar_registers; + size = ARRAY_SIZE(cometlake_spi_bar_registers); + break; case PCI_DEVICE_ID_INTEL_ICH: case PCI_DEVICE_ID_INTEL_ICH0: case PCI_DEVICE_ID_INTEL_ICH2: diff --git a/util/mec152x/Makefile.mk b/util/mec152x/Makefile.mk index 067fdb097ff..ccbdda0cf96 100644 --- a/util/mec152x/Makefile.mk +++ b/util/mec152x/Makefile.mk @@ -8,6 +8,7 @@ MEC152XCFLAGS := -Wno-array-bounds -Wextra -O3 -Wshadow $(WERROR) MEC152XCFLAGS += -I $(top)/util/cbfstool/flashmap/ MEC152XCFLAGS += -I $(top)/util/mec152x MEC152XCFLAGS += -I $(top)/src/commonlib/bsd/include +MEC152XCFLAGS += -include $(top)/src/commonlib/bsd/include/commonlib/bsd/compiler.h additional-dirs += $(objutil)/mec152x diff --git a/util/mediatek/gen-bl-img.py b/util/mediatek/gen-bl-img.py index 7cd7dbb079e..a98b1ea8457 100755 --- a/util/mediatek/gen-bl-img.py +++ b/util/mediatek/gen-bl-img.py @@ -43,7 +43,7 @@ def gen_gfh_info(chip, data): 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00006400, 0x00001388, + 0x00000000, 0x52000000, 0x00006400, 0x00001388, 0x00000000, 0x00000000, 0x00000000, 0x00000000) return gfh diff --git a/util/spd_tools/src/spd_gen/lp5.go b/util/spd_tools/src/spd_gen/lp5.go index f3586c75393..acb10abc660 100644 --- a/util/spd_tools/src/spd_gen/lp5.go +++ b/util/spd_tools/src/spd_gen/lp5.go @@ -209,6 +209,7 @@ var LP5SetInfo = map[int]LP5Set{ * = 1 / (speed grade / 2 / WCK:CK) // "double data rate" */ speedToTCKMinPs: map[int]int{ + 9600: 833, /* 1 / (9600 / 2 / 4) */ 8533: 937, /* 1 / (8533 / 2 / 4) */ 7500: 1066, /* 1 / (7500 / 2 / 4) */ 6400: 1250, /* 1 / (6400 / 2 / 4) */ @@ -374,6 +375,10 @@ var LP5BankArchToSPDEncoding = map[int]LP5BankArchParams{ * From Table 220 of JESD209-5B, using a 4:1 WCK:CK ratio and Set 0. */ var LP5SpeedMbpsToSPDEncoding = map[int]LP5SpeedParams{ + 9600: { + defaultTCKMinPs: 208, /* 1 / (9600 / 2) */ + MaxCASLatency: 26, + }, 8533: { defaultTCKMinPs: 234, /* 1 / (8533 / 2) */ MaxCASLatency: 23, diff --git a/util/superiotool/nuvoton.c b/util/superiotool/nuvoton.c index 80ba12ecdd8..8f9a029aea2 100644 --- a/util/superiotool/nuvoton.c +++ b/util/superiotool/nuvoton.c @@ -688,8 +688,8 @@ static const struct superio_registers reg_table[] = { {EOT}}}, {0xc803, "NCT6791D", { {NOLDN, NULL, - {0x07,0x10,0x11,0x13,0x14,0x1a,0x1b,0x1c,0x1d,0x20,0x21,0x22,0x24,0x25,0x26,0x27,0x28,0x2a,0x2b,0x2c,0x2d,0x2f,EOT}, - {0x00,0xff,0xff,0x00,0x00,0x30,0x70,0x10,0x00,0xc8,0x03,0xff,0x04,0x00,MISC,0x00,0x00,0xc0,0x00,0x01,0x00,MISC,EOT}}, + {0x07,0x10,0x11,0x13,0x14,0x1a,0x1b,0x1c,0x1d,0x20,0x21,0x22,0x24,0x25,0x26,0x27,0x28,0x2a,0x2b,0x2c,0x2f,EOT}, + {0x00,0xff,0xff,0x00,0x00,0x30,0x70,0x10,0x00,0xc8,0x03,0xff,0x04,0x00,MISC,0x00,0x00,0xc0,0x00,0x01,MISC,EOT}}, {0x01, "Parallel Port", {0x30,0x60,0x61,0x70,0x74,0xf0,EOT}, {0x01,0x03,0x78,0x07,0x04,0x3f,EOT}}, @@ -907,6 +907,50 @@ static const struct superio_registers reg_table[] = { {0x30,0xe0,0xe1,0xe2,0xe3,EOT}, {0xa0,0x20,0x04,0x05,0x01,EOT}}, {EOT}}}, + {0x1c11, "NPCD378 (experimental)", { + {NOLDN, NULL, + {0x10,0x11,0x13,0x14,0x1a,0x1b,0x1c,0x1d,0x20,0x21,0x22,0x24,0x25,0x26,0x27,0x28,0x2a,0x2b,0x2c,0x2d,0x2f,EOT}, + {NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}}, + {0x00, "FDC", + {0x30,0x60,0x61,0x70,0x74,0xf0,0xf1,0xf2,0xf4,0xf5,EOT}, + {0x01,0x03,0xf0,0x06,0x02,0x0e,0x00,0xff,0x00,0x00,EOT}}, + {0x01, "Parallel Port", + {0x30,0x60,0x61,0x70,0x74,0xf0,EOT}, + {0x01,0x03,0x78,0x07,0x04,0x3f,EOT}}, + {0x02, "UART A", + {0x30,0x60,0x61,0x70,0xf0,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,EOT}, + {0x01,0x03,0xf8,0x04,0x00,0x00,0x00,0xff,0xff,0x02,0x00,0x00,EOT}}, + {0x03, "UART B", + {0x30,0x60,0x61,0x70,0xf0,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,EOT}, + {0x01,0x02,0xf8,0x03,0x00,0x00,0x00,0xff,0xff,0x02,0x00,0x00,EOT}}, + {0x04, "LED Control", + {0x30,0x60,0x61,0x62,0x63,0x70,0xf0,0xf1,0xf2,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,NANA,NANA,NANA,EOT}}, + {0x05, "?", + {0x30,0x60,0x61,0x62,0x63,0x70,0xf0,0xf1,0xf2,0xf3,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x09,0x32,0x00,EOT}}, + {0x06, "Keyboard Controller", + {0x30,0x60,0x61,0x62,0x63,0x70,0x72,0xf0,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,EOT}}, + {0x07, "?", + {0x30,0x60,0x61,0x70,0x72,0xf0,EOT}, + {0x00,0x00,0x00,0x00,0x00,NANA,EOT}}, + {0x08, "Hardware Monitor", + {0x30,0x60,0x61,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,EOT}, + {0x00,0x00,0x00,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}}, + {0x0f, "?", + {0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe9,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,EOT}, + {NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}}, + {0x15, "?", + {0x30,0x60,0x61,0x62,0x63,0x70,0x72,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}}, + {0x1c, "?", + {0x30,0x60,0x61,0x62,0x63,0x70,0x72,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}}, + {0x1e, "?", + {0x30,0x60,0x61,0x62,0x63,0x70,0x72,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff,EOT}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,NANA,EOT}}, + {EOT}}}, {EOT} }; @@ -1054,6 +1098,16 @@ void probe_idregs_nuvoton(uint16_t port) for (i = 0; i < 10; i++) dump_data(iobase + 5, i); break; + case 0xc800: /* NCT6791D */ + printf("HWM banked registers:\n"); + for (i = 0; i <= 0xa; i++) + dump_data(iobase + 5, i); + break; + case 0xd420: /* NCT6796D */ + printf("HWM banked registers:\n"); + for (i = 0; i <= 0xb; i++) + dump_data(iobase + 5, i); + break; case 0xd590: /* NCT6687D-W */ dump_nct6687d_gpios(port); /* One can use the APCI/BIOS register set, although the diff --git a/util/vgabios/include/console/console.h b/util/vgabios/include/console/console.h index 0aa55955902..edad4d084bf 100644 --- a/util/vgabios/include/console/console.h +++ b/util/vgabios/include/console/console.h @@ -3,6 +3,6 @@ #ifndef _CONSOLE_CONSOLE_H #define _CONSOLE_CONSOLE_H -int printk(int msg_level, const char *fmt, ...) __attribute__((format(printf, 2, 3))); +int printk(int msg_level, const char *fmt, ...) __printf(2, 3); #endif diff --git a/util/xcompile/xcompile b/util/xcompile/xcompile index 8f0d19a6a6d..f88da69306b 100755 --- a/util/xcompile/xcompile +++ b/util/xcompile/xcompile @@ -526,7 +526,7 @@ test_architecture() { for clang_arch in $TCLIST invalid; do for clang_prefix in $search $XGCCPATH "$GENERIC_COMPILER_PREFIX"; do - testcc "${clang_prefix}clang" "-target ${clang_arch}-none-unknown-${TABI} -c" && break 2 + testcc "${clang_prefix}clang" "-target ${clang_arch}-none-${TABI} -c" && break 2 done done @@ -535,7 +535,7 @@ test_architecture() { # but that's more of a clang limitation. Let's be optimistic # that this will change in the future. CLANG="${clang_prefix}clang" - CLANG_TARGET="-target ${clang_arch}-none-unknown-${TABI}" + CLANG_TARGET="-target ${clang_arch}-none-${TABI}" CFLAGS_CLANG="$CLANG_TARGET $CFLAGS_CLANG" CPPFLAGS_CLANG="$CLANG_TARGET $CPPFLAGS_CLANG" fi