require-fwup-version="1.4.0"  # For the GPT support

include("${NERVES_SDK_IMAGES:-.}/fwup_include/fwup-common.conf")

gpt gpt-a {
    guid = ${NERVES_SYSTEM_DISK_UUID}
    partition 0 {
        block-offset = ${SPL1_PART_OFFSET}
        block-count = ${SPL1_PART_COUNT}
        guid = ${NERVES_SYSTEM_SPL_PART_UUID}
        type = ${LINUX_FILESYSTEM_DATA_TYPE}
        name = "fsbl1"
    }
    partition 1 {
        block-offset = ${SPL2_PART_OFFSET}
        block-count = ${SPL2_PART_COUNT}
        guid = ${NERVES_SYSTEM_SPL_PART_UUID}
        type = ${LINUX_FILESYSTEM_DATA_TYPE}
        name = "fsbl2"
    }
    partition 2 {
        block-offset = ${UBOOT_PART_OFFSET}
        block-count = ${UBOOT_PART_COUNT}
        guid = ${NERVES_SYSETM_UBOOT_PART_UUID}
        type = ${LINUX_FILESYSTEM_DATA_TYPE}
        name = "fip"
    }
    partition 3 {
        block-offset = ${EFI_A_PART_OFFSET}
        block-count = ${EFI_A_PART_COUNT}
        guid = ${NERVES_SYSTEM_EFI_PART_UUID}
        type = ${EFI_TYPE}
        name = "boot"
    }
    partition 4 {
        block-offset = ${ROOTFS_A_PART_OFFSET}
        block-count = ${ROOTFS_A_PART_COUNT}
        guid = ${NERVES_SYSTEM_ROOTFS_PART_UUID}
        name = "rootfs"
        type = ${LINUX_FILESYSTEM_DATA_TYPE}
        flags = 0x4
    }
    partition 5 {
        block-offset = ${APP_PART_OFFSET}
        block-count = ${APP_PART_COUNT}
        guid = ${NERVES_SYSTEM_APP_PART_UUID}
        type = ${LINUX_FILESYSTEM_DATA_TYPE}
        expand = true
    }
}

gpt gpt-b {
    guid = ${NERVES_SYSTEM_DISK_UUID}
    partition 0 {
        block-offset = ${SPL1_PART_OFFSET}
        block-count = ${SPL1_PART_COUNT}
        guid = ${NERVES_SYSTEM_SPL_PART_UUID}
        type = ${LINUX_FILESYSTEM_DATA_TYPE}
        name = "fsbl1"
    }
    partition 1 {
        block-offset = ${SPL2_PART_OFFSET}
        block-count = ${SPL2_PART_COUNT}
        guid = ${NERVES_SYSTEM_SPL_PART_UUID}
        type = ${LINUX_FILESYSTEM_DATA_TYPE}
        name = "fsbl2"
    }
    partition 2 {
        block-offset = ${UBOOT_PART_OFFSET}
        block-count = ${UBOOT_PART_COUNT}
        guid = ${NERVES_SYSETM_UBOOT_PART_UUID}
        type = ${LINUX_FILESYSTEM_DATA_TYPE}
        name = "fip"
    }
    partition 3 {
        block-offset = ${EFI_B_PART_OFFSET}
        block-count = ${EFI_B_PART_COUNT}
        guid = ${NERVES_SYSTEM_EFI_PART_UUID}
        type = ${EFI_TYPE}
        name = "boot"
    }
    partition 4 {
        block-offset = ${ROOTFS_B_PART_OFFSET}
        block-count = ${ROOTFS_B_PART_COUNT}
        guid = ${NERVES_SYSTEM_ROOTFS_PART_UUID}
        name = "rootfs"
        type = ${LINUX_FILESYSTEM_DATA_TYPE}
        flags = 0x4
    }
    partition 5 {
        block-offset = ${APP_PART_OFFSET}
        block-count = ${APP_PART_COUNT}
        guid = ${NERVES_SYSTEM_APP_PART_UUID}
        type = ${LINUX_FILESYSTEM_DATA_TYPE}
        expand = true
    }
}

# Location where installed firmware information is stored.
# While this is called "u-boot", u-boot isn't involved in this
# setup. It just provides a convenient key/value store format.
uboot-environment uboot-env {
    block-offset = ${UBOOT_ENV_OFFSET}
    block-count = ${UBOOT_ENV_COUNT}
}

task revert.a {
    # This task reverts to the A partition, so check that we're running on B
    require-uboot-variable(uboot-env, "nerves_fw_active", "b")

    # Verify that partition A has the expected platform/architecture
    require-uboot-variable(uboot-env, "a.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
    require-uboot-variable(uboot-env, "a.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")

    on-finish {
      info("Reverting to partition A")

      uboot_setenv(uboot-env, "nerves_fw_active", "a")
      uboot_setenv(uboot-env, "nerves_fw_validated", "1")
      gpt_write(gpt-a)
    }
}

task revert.b {
    # This task reverts to the B partition, so check that we're running on A
    require-uboot-variable(uboot-env, "nerves_fw_active", "a")

    # Verify that partition B has the expected platform/architecture
    require-uboot-variable(uboot-env, "b.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
    require-uboot-variable(uboot-env, "b.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")

    on-finish {
      info("Reverting to partition B")

      # Switch over
      uboot_setenv(uboot-env, "nerves_fw_active", "b")
      uboot_setenv(uboot-env, "nerves_fw_validated", "1")
      gpt_write(gpt-b)
    }
}

task revert.unexpected.a {
    require-uboot-variable(uboot-env, "a.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
    require-uboot-variable(uboot-env, "a.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")
    on-init {
        # Case where A is good, and the desire is to go to B.
        error("It doesn't look like there's anything to revert to in partition B.")
    }
}
task revert.unexpected.b {
    require-uboot-variable(uboot-env, "b.nerves_fw_platform", "${NERVES_FW_PLATFORM}")
    require-uboot-variable(uboot-env, "b.nerves_fw_architecture", "${NERVES_FW_ARCHITECTURE}")
    on-init {
        # Case where B is good, and the desire is to go to A.
        error("It doesn't look like there's anything to revert to in partition A.")
    }
}

task revert.wrongplatform {
    on-init {
        error("Expecting platform=${NERVES_FW_PLATFORM} and architecture=${NERVES_FW_ARCHITECTURE}")
    }
}
