diff --git a/tools/test_apps/system/.build-test-rules.yml b/tools/test_apps/system/.build-test-rules.yml index 209d0e9866..c98392018b 100644 --- a/tools/test_apps/system/.build-test-rules.yml +++ b/tools/test_apps/system/.build-test-rules.yml @@ -62,6 +62,15 @@ tools/test_apps/system/memprot: temporary: true reason: the other targets are not tested yet +tools/test_apps/system/mmu_page_size: + enable: + - if: IDF_TARGET in ["esp32c6", "esp32h2"] + reason: Coverage for two targets with configurable MMU page size is sufficient + depends_components: + - esp_app_format + - bootloader_support + - esp_mm + tools/test_apps/system/no_embedded_paths: enable: - if: IDF_TARGET in ["esp32", "esp32c3", "esp32s2"] diff --git a/tools/test_apps/system/mmu_page_size/CMakeLists.txt b/tools/test_apps/system/mmu_page_size/CMakeLists.txt new file mode 100644 index 0000000000..9a2312cf5b --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/CMakeLists.txt @@ -0,0 +1,7 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.16) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +set(COMPONENTS main) +project(test_mmu_page_size) diff --git a/tools/test_apps/system/mmu_page_size/README.md b/tools/test_apps/system/mmu_page_size/README.md new file mode 100644 index 0000000000..0163e2dec5 --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/README.md @@ -0,0 +1,5 @@ +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | + +This test app ensures that bootloader can support configurable MMU page size as per the application binary header. +This test tries to boot the application with different MMU page sizes and checks if the application is able to boot successfully. diff --git a/tools/test_apps/system/mmu_page_size/conftest.py b/tools/test_apps/system/mmu_page_size/conftest.py new file mode 100644 index 0000000000..21d1a1145e --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/conftest.py @@ -0,0 +1,51 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import logging +import os + +import pytest +from _pytest.fixtures import FixtureRequest +from _pytest.monkeypatch import MonkeyPatch +from pytest_embedded_idf.app import FlashFile +from pytest_embedded_idf.serial import IdfSerial + + +# This is a custom IdfSerial class to support custom functionality +# which is required only for this test +class FlashBootloader(IdfSerial): + def bootloader_flash(self, binary_path: str) -> None: + """ + Flash bootloader. + + :return: None + """ + logging.info('Flashing bootloader') + bootloader_path = os.path.join(binary_path, 'bootloader', 'bootloader.bin') + logging.info(bootloader_path) + offs = int(self.app.sdkconfig.get('BOOTLOADER_OFFSET_IN_FLASH', 0)) + logging.info('bootloader offset is {0}'.format(hex(offs))) + prev_flash_files = self.app.flash_files + flash_files = [] + flash_files.append( + FlashFile( + offs, + bootloader_path, + False, + ) + ) + self.app.flash_files = flash_files + self.flash() + # Restore self.app.flash files to original value + self.app.flash_files = prev_flash_files + + +@pytest.fixture(scope='module') +def monkeypatch_module(request: FixtureRequest) -> MonkeyPatch: + mp = MonkeyPatch() + request.addfinalizer(mp.undo) + return mp + + +@pytest.fixture(scope='module', autouse=True) +def replace_dut_class(monkeypatch_module: MonkeyPatch) -> None: + monkeypatch_module.setattr('pytest_embedded_idf.IdfSerial', FlashBootloader) diff --git a/tools/test_apps/system/mmu_page_size/main/CMakeLists.txt b/tools/test_apps/system/mmu_page_size/main/CMakeLists.txt new file mode 100644 index 0000000000..06087b89d5 --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "main.c" + PRIV_REQUIRES unity esp_partition) diff --git a/tools/test_apps/system/mmu_page_size/main/main.c b/tools/test_apps/system/mmu_page_size/main/main.c new file mode 100644 index 0000000000..a820c55c54 --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/main/main.c @@ -0,0 +1,40 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "unity.h" +#include "esp_partition.h" + +#define SZ 4096 + +void app_main(void) +{ + printf("App is running\n"); + + // Perform some partition and memory map related operations + char src_p_1[32] = "Test data pattern 123456789"; + char buf[32]; + + // Find storage partition + const esp_partition_t* partition = esp_partition_find_first( + ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, NULL); + TEST_ASSERT_NOT_NULL(partition); + + esp_partition_mmap_handle_t handle1; + const void *ptr1; + TEST_ESP_OK(esp_partition_mmap(partition, 0, SZ, ESP_PARTITION_MMAP_DATA, &ptr1, &handle1)); + TEST_ESP_OK(esp_partition_erase_range(partition, 0, SZ)); + TEST_ESP_OK(esp_partition_write(partition, 0, src_p_1, sizeof(src_p_1))); + memcpy(buf, ptr1, sizeof(buf)); + + TEST_ASSERT_EQUAL(0, memcmp(buf, src_p_1, sizeof(buf))); + esp_partition_munmap(handle1); + + printf("Partition test done\n"); +} diff --git a/tools/test_apps/system/mmu_page_size/partitions.csv b/tools/test_apps/system/mmu_page_size/partitions.csv new file mode 100644 index 0000000000..5f1296d92d --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/partitions.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap +nvs, data, nvs, , 0x6000, +phy_init, data, phy, , 0x1000, +factory, app, factory, , 1M, +storage, data, fat, , 64K, diff --git a/tools/test_apps/system/mmu_page_size/pytest_mmu_page_size.py b/tools/test_apps/system/mmu_page_size/pytest_mmu_page_size.py new file mode 100644 index 0000000000..cd9eb47db2 --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/pytest_mmu_page_size.py @@ -0,0 +1,52 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import os + +import pytest +from artifacts_handler import ArtifactType +from idf_ci_utils import IDF_PATH +from pytest_embedded import Dut + + +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.generic +@pytest.mark.parametrize('config', ['32K'], indirect=True) +def test_app_mmu_page_size_32k_and_bootloader_mmu_page_size_64k(dut: Dut, app_downloader, config) -> None: # type: ignore + dut.expect('App is running') + + assert '32K' in config + app_config = config.replace('32K', '64K') + + path_to_mmu_page_size_64k_build = os.path.join(dut.app.app_path, f'build_{dut.target}_{app_config}') + if app_downloader: + app_downloader.download_app( + os.path.relpath(path_to_mmu_page_size_64k_build, IDF_PATH), ArtifactType.BUILD_DIR_WITHOUT_MAP_AND_ELF_FILES + ) + + dut.serial.bootloader_flash(path_to_mmu_page_size_64k_build) + dut.expect('MMU page size mismatch') + dut.expect('App is running') + dut.expect('Partition test done\n') + + +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.generic +@pytest.mark.parametrize('config', ['64K'], indirect=True) +def test_app_mmu_page_size_64k_and_bootloader_mmu_page_size_32k(dut: Dut, app_downloader, config) -> None: # type: ignore + dut.expect('App is running') + + assert '64K' in config + app_config = config.replace('64K', '32K') + + path_to_mmu_page_size_32k_build = os.path.join(dut.app.app_path, f'build_{dut.target}_{app_config}') + if app_downloader: + app_downloader.download_app( + os.path.relpath(path_to_mmu_page_size_32k_build, IDF_PATH), ArtifactType.BUILD_DIR_WITHOUT_MAP_AND_ELF_FILES + ) + + dut.serial.bootloader_flash(path_to_mmu_page_size_32k_build) + dut.expect('MMU page size mismatch') + dut.expect('App is running') + dut.expect('Partition test done\n') diff --git a/tools/test_apps/system/mmu_page_size/sdkconfig.ci.32K b/tools/test_apps/system/mmu_page_size/sdkconfig.ci.32K new file mode 100644 index 0000000000..d2d45ce8e2 --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/sdkconfig.ci.32K @@ -0,0 +1,2 @@ +# This config option internally select 32KB MMU page size +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y diff --git a/tools/test_apps/system/mmu_page_size/sdkconfig.ci.64K b/tools/test_apps/system/mmu_page_size/sdkconfig.ci.64K new file mode 100644 index 0000000000..f57de8fda2 --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/sdkconfig.ci.64K @@ -0,0 +1,2 @@ +# This config option internally select 64KB MMU page size +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y diff --git a/tools/test_apps/system/mmu_page_size/sdkconfig.defaults b/tools/test_apps/system/mmu_page_size/sdkconfig.defaults new file mode 100644 index 0000000000..4b0421e1ab --- /dev/null +++ b/tools/test_apps/system/mmu_page_size/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_PARTITION_TABLE_CUSTOM=y