{
  stdenv,
  fetchFromGitHub,
  lib,
  MODEL ? "5",
  RELEASE_TYPE ? "RELEASE",
  EDK2_FLAGS ? "",
  nasm,
  perl,
  python3,
  python3Packages,
  openssl,
  git,
  libuuid,
  acpica-tools,
  pkgs,
  namespace,
}:
let
  inherit (lib.trivial) importJSON;

  pname = "edk2";
  version = "stable202511";
  versions = importJSON ./versions.json;

  repoOwner = (if MODEL == "5" then "-mjallen" else "");

  edk2Src =  fetchFromGitHub rec {
    owner = versions."edk2${repoOwner}".owner;
    repo = "edk2";
    name = repo;
    rev = (if MODEL == "5" then versions."edk2${repoOwner}".rev else null);
    tag = (if MODEL == "5" then null else versions."edk2${repoOwner}".tag);
    hash = versions."edk2${repoOwner}".hash;
    fetchSubmodules = true;
  };

  edk2NonOsiSrc = fetchFromGitHub rec {
    owner = versions."edk2-non-osi${repoOwner}".owner;
    repo = "edk2-non-osi";
    name = repo;
    rev = versions."edk2-non-osi${repoOwner}".rev;
    hash = versions."edk2-non-osi${repoOwner}".hash;
  };

  edk2PlatformsSrc = fetchFromGitHub rec {
    owner = versions."edk2-platforms${repoOwner}".owner;
    repo = "edk2-platforms";
    name = repo;
    rev = versions."edk2-platforms${repoOwner}".rev;
    hash = versions."edk2-platforms${repoOwner}".hash;
  };

  baseTools = pkgs.${namespace}.edk2-basetools.override {
    version = "stable202511";
    src = edk2Src;
  };
  armTrustedFirmware = pkgs.${namespace}.arm-trusted-firmware.override { inherit MODEL; };

  pythonEnv = python3.withPackages (
    _ps: with python3Packages; [
      libfdt
    ]
  );
in
stdenv.mkDerivation rec {
  inherit pname version;

  srcs = [
    edk2Src
    edk2NonOsiSrc
    edk2PlatformsSrc
  ];

  # Add required host tools if needed:
  nativeBuildInputs = [
    openssl
    nasm
    perl
    pythonEnv
    git
    libuuid
    baseTools
    acpica-tools
  ];

  env = {
    NIX_CFLAGS_COMPILE =
      "-Wno-return-type -Wno-error"
      + lib.optionalString (stdenv.cc.isGNU) " -Wno-error=stringop-truncation"
      + lib.optionalString (stdenv.hostPlatform.isDarwin) " -Wno-error=macro-redefined";
    PYTHON_COMMAND = lib.getExe pythonEnv;
    # trick taken from https://src.fedoraproject.org/rpms/edk2/blob/08f2354cd280b4ce5a7888aa85cf520e042955c3/f/edk2.spec#_319
    ${"GCC5_AARCH64_PREFIX"} = stdenv.cc.targetPrefix;

  };

  # Don’t force a single root; we keep both dirs side by side
  sourceRoot = ".";

  unpackPhase = ''
    runHook preUnpack

    for src in $srcs; do
      unpackFile "$src"
    done

    chmod -R u+w .

    patchShebangs ./edk2

    runHook postUnpack
  '';

  prePatch = ''
    rm -rf ./edk2/BaseTools
    ln -sv ${baseTools}/BaseTools ./edk2/BaseTools
  '';

  configurePhase = ''
    runHook preConfigure
    export WORKSPACE=$PWD
    export PACKAGES_PATH=$WORKSPACE/edk2:$WORKSPACE/edk2-non-osi:$WORKSPACE/edk2-platforms
    export EDK_TOOLS_PATH=${baseTools}/BaseTools
    export ATF_BUILD_DIR="${armTrustedFirmware}/rpi${MODEL}/${lib.toLower RELEASE_TYPE}"

    . ${baseTools}/edksetup.sh BaseTools
    runHook postConfigure
  '';

  buildPhase = ''
    build \
        -a AARCH64 \
        -t GCC \
        -b ${RELEASE_TYPE} \
        -p edk2-platforms/Platform/RaspberryPi/RPi${MODEL}/RPi${MODEL}.dsc \
        -D TFA_BUILD_ARTIFACTS=$ATF_BUILD_DIR \
        --pcd gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString=L${version} \
        ${EDK2_FLAGS}
  '';

  installPhase = ''
    mkdir -p $out
    cp -r /build/Build/RPi${MODEL}/${RELEASE_TYPE}_GCC/FV/RPI_EFI.fd $out/RPI_EFI.fd
  '';

  meta = with lib; {
    description = "ARM Trusted Firmware-A for Raspberry Pi";
    license = licenses.bsd3;
    platforms = [ "aarch64-linux" ];
    maintainers = with maintainers; [ kazenyuk ];
  };
}
