diff --git a/src/comm/CMakeLists.txt b/src/comm/CMakeLists.txt index 00a7823f..f9fcf19a 100644 --- a/src/comm/CMakeLists.txt +++ b/src/comm/CMakeLists.txt @@ -113,6 +113,12 @@ set(TILEXR_SOURCE_FILE tilexr_comm.cpp ccu/tilexr_ccu_hccp_types.h ccu/tilexr_ccu_hccp_loader.h ccu/tilexr_ccu_hccp_loader.cpp + ccu/tilexr_ccu_launch_package.h + ccu/tilexr_ccu_launch_package.cpp + ccu/tilexr_ccu_install_provider.h + ccu/tilexr_ccu_install_provider.cpp + ccu/tilexr_ccu_lower_layer_plan_builder.h + ccu/tilexr_ccu_lower_layer_plan_builder.cpp ccu/tilexr_ccu_lower_layer_payloads.h ccu/tilexr_ccu_lower_layer_payloads.cpp ccu/tilexr_ccu_memory_program.h @@ -121,8 +127,12 @@ set(TILEXR_SOURCE_FILE tilexr_comm.cpp ccu/tilexr_ccu_microcode.cpp ccu/tilexr_ccu_producer_plan.h ccu/tilexr_ccu_producer_plan.cpp + ccu/tilexr_ccu_provider.h + ccu/tilexr_ccu_provider.cpp ccu/tilexr_ccu_ra_custom_channel_provider.h ccu/tilexr_ccu_ra_custom_channel_provider.cpp + ccu/tilexr_ccu_repository.h + ccu/tilexr_ccu_repository.cpp ccu/tilexr_ccu_resource_allocator.h ccu/tilexr_ccu_resource_allocator.cpp ccu/tilexr_ccu_runtime.h diff --git a/src/comm/ccu/tilexr_ccu_install_provider.cpp b/src/comm/ccu/tilexr_ccu_install_provider.cpp new file mode 100644 index 00000000..f0adbe71 --- /dev/null +++ b/src/comm/ccu/tilexr_ccu_install_provider.cpp @@ -0,0 +1,1534 @@ +/* + * Copyright (c) 2026 TileXR Project + * Licensed under the Apache License, Version 2.0 + */ + +#include "ccu/tilexr_ccu_install_provider.h" + +#include + +namespace TileXR { +namespace { + +void ResetReport(TileXRCcuInstallProviderReport* report) +{ + if (report == nullptr) { + return; + } + *report = TileXRCcuInstallProviderReport{}; +} + +void ResetManifestReport(TileXRCcuInstallManifestReport* report) +{ + if (report == nullptr) { + return; + } + report->requirementCount = 0; + report->message.clear(); +} + +int FailManifest(TileXRCcuInstallManifest* manifest, TileXRCcuInstallManifestReport* report, const std::string& message) +{ + if (manifest != nullptr) { + *manifest = TileXRCcuInstallManifest{}; + } + if (report != nullptr) { + report->requirementCount = 0; + report->message = message; + } + return TILEXR_ERROR_PARA_CHECK_FAIL; +} + +void MarkMissingStep(TileXRCcuInstallStepEvidence* step, const std::string& message) +{ + if (step == nullptr) { + return; + } + step->satisfied = false; + step->source.kind = TileXRCcuEvidenceKind::Missing; + step->source.surface = TileXRCcuEvidenceSurface::Unspecified; + step->source.source.clear(); + step->source.detail = message; + step->message = message; +} + +void FillUnsupportedReport(TileXRCcuInstallProviderReport* report) +{ + if (report == nullptr) { + return; + } + const std::string message = "no public no-hcomm CCU install provider is available"; + report->offlineOnly = true; + report->installAttempted = false; + report->installSucceeded = false; + report->message = message; + MarkMissingStep(&report->mission, message); + MarkMissingStep(&report->repository, message); + MarkMissingStep(&report->localXn, message); + MarkMissingStep(&report->remoteXn, message); + MarkMissingStep(&report->notifyCke, message); + MarkMissingStep(&report->channelBinding, message); +} + +void FillScopeFailureReport(TileXRCcuInstallProviderReport* report, const std::string& message) +{ + if (report == nullptr) { + return; + } + report->offlineOnly = true; + report->installAttempted = false; + report->installSucceeded = false; + report->message = message; + MarkMissingStep(&report->mission, message); + MarkMissingStep(&report->repository, message); + MarkMissingStep(&report->localXn, message); + MarkMissingStep(&report->remoteXn, message); + MarkMissingStep(&report->notifyCke, message); + MarkMissingStep(&report->channelBinding, message); +} + +TileXRCcuEvidenceSource MissingSource(const std::string& detail) +{ + TileXRCcuEvidenceSource source; + source.kind = TileXRCcuEvidenceKind::Missing; + source.surface = TileXRCcuEvidenceSurface::Unspecified; + source.detail = detail; + return source; +} + +TileXRCcuEvidenceSource SourceOrMissing(const TileXRCcuInstallStepEvidence& step, const std::string& detail) +{ + return step.satisfied ? step.source : MissingSource(detail); +} + +uint64_t MixReceiptWord(uint64_t hash, uint64_t value) +{ + constexpr uint64_t prime = 1099511628211ULL; + for (uint32_t i = 0; i < 8U; ++i) { + hash ^= static_cast((value >> (i * 8U)) & 0xffU); + hash *= prime; + } + return hash; +} + +uint64_t BuildRepositoryInstallReceiptId( + const TileXRCcuLaunchPackage& package, + const TileXRCcuRepositoryInstallReceipt& receipt) +{ + uint64_t hash = 1469598103934665603ULL; + hash = MixReceiptWord(hash, TileXRCcuComputeLaunchPackageFingerprint(package)); + hash = MixReceiptWord(hash, receipt.dieId); + hash = MixReceiptWord(hash, receipt.instructionStartId); + hash = MixReceiptWord(hash, receipt.instructionCount); + hash = MixReceiptWord(hash, receipt.instructionBytes); + hash = MixReceiptWord(hash, receipt.deviceInstructionAddr); + return hash == 0 ? 1 : hash; +} + +TileXRCcuInstallStepEvidence PublicVerifiedStep( + const TileXRCcuLaunchPackage& package, + const TileXRCcuInstallRequest& request, + uint64_t receiptId, + const std::string& source, + const std::string& detail, + bool endpointRouteVerified = false) +{ + TileXRCcuInstallStepEvidence step; + step.satisfied = true; + step.source.kind = TileXRCcuEvidenceKind::PublicVerified; + step.source.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + step.source.packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + step.source.deviceId = request.deviceId; + step.source.rank = request.rank; + step.source.provider = request.provider; + step.source.installAttemptReceiptId = receiptId; + step.source.endpointRouteVerified = endpointRouteVerified; + step.source.source = source; + step.source.detail = detail; + step.message = detail; + return step; +} + +TileXRCcuInstallRequirement BaseRequirement( + TileXRCcuInstallRequirementKind kind, + uint64_t packageFingerprint, + uint8_t dieId, + const std::string& label, + const std::string& detail) +{ + TileXRCcuInstallRequirement requirement; + requirement.kind = kind; + requirement.packageFingerprint = packageFingerprint; + requirement.dieId = dieId; + requirement.label = label; + requirement.detail = detail; + return requirement; +} + +uint32_t TotalBindingCount(const std::vector& resources) +{ + uint32_t total = 0; + for (const auto& resource : resources) { + total += resource.bindingCount; + } + return total; +} + +bool SameBindingChannel( + const TileXRCcuRemoteXnBindingProof& lhs, + const TileXRCcuRemoteXnBindingProof& rhs) +{ + return lhs.dieId == rhs.dieId && lhs.channelId == rhs.channelId; +} + +bool HasInstalledChannel( + const std::vector& channels, + uint8_t dieId, + uint16_t channelId) +{ + for (const auto& channel : channels) { + if (channel.dieId == dieId && channel.channelId == channelId) { + return true; + } + } + return false; +} + +uint32_t CountUniqueRemoteBindingChannels(const std::vector& bindings) +{ + uint32_t count = 0; + for (size_t i = 0; i < bindings.size(); ++i) { + bool seen = false; + for (size_t j = 0; j < i; ++j) { + if (SameBindingChannel(bindings[i], bindings[j])) { + seen = true; + break; + } + } + if (!seen) { + ++count; + } + } + return count; +} + +uint32_t CountInstalledRemoteBindingChannels( + const std::vector& bindings, + const std::vector& channels) +{ + uint32_t count = 0; + for (size_t i = 0; i < bindings.size(); ++i) { + bool seen = false; + for (size_t j = 0; j < i; ++j) { + if (SameBindingChannel(bindings[i], bindings[j])) { + seen = true; + break; + } + } + if (!seen && HasInstalledChannel(channels, bindings[i].dieId, bindings[i].channelId)) { + ++count; + } + } + return count; +} + +const TileXRCcuInstallRequirement* FindRequirement( + const TileXRCcuInstallManifest& manifest, + TileXRCcuInstallRequirementKind kind); + +bool RangeContainsId(const TileXRCcuRange& range, uint8_t dieId, uint16_t id) +{ + if (range.dieId != dieId || range.num == 0) { + return false; + } + const uint32_t begin = range.startId; + const uint32_t end = begin + range.num; + return id >= begin && id < end; +} + +bool RepositoryMissionWindowContainsTask(const TileXRCcuRepositoryImage& repository, const TileXRCcuTask& task) +{ + if (repository.dieId != task.dieId || repository.missionCount == 0 || task.instCnt == 0) { + return false; + } + const uint32_t begin = repository.missionStartId; + const uint32_t end = begin + repository.missionCount; + const uint32_t taskBegin = task.instStartId; + const uint32_t taskEnd = taskBegin + task.instCnt; + return taskBegin >= begin && taskEnd <= end; +} + +bool FailMissionLaunchDescriptorProof(std::string* diagnostic, const std::string& reason) +{ + if (diagnostic != nullptr) { + *diagnostic = "mission/key launch task descriptor proof failed: " + reason; + } + return false; +} + +bool ValidateMissionLaunchDescriptorProof( + const TileXRCcuLaunchPackage& package, + const TileXRCcuInstallManifest* manifest, + std::string* diagnostic) +{ + if (diagnostic != nullptr) { + diagnostic->clear(); + } + if (!package.plan.mission.installed || package.plan.mission.key == 0) { + return FailMissionLaunchDescriptorProof(diagnostic, "mission key is not installed in the producer plan"); + } + if (!RangeContainsId( + package.plan.kernelLocalMission, + package.plan.mission.dieId, + package.plan.mission.missionId)) { + return FailMissionLaunchDescriptorProof( + diagnostic, + "mission id is outside the kernel-local mission range"); + } + if (manifest == nullptr) { + return FailMissionLaunchDescriptorProof(diagnostic, "install manifest mission requirement is missing"); + } + const TileXRCcuInstallRequirement* mission = + FindRequirement(*manifest, TileXRCcuInstallRequirementKind::MissionKey); + const uint64_t packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + if (mission == nullptr || + mission->packageFingerprint != packageFingerprint || + mission->dieId != package.plan.mission.dieId || + mission->missionId != package.plan.mission.missionId || + mission->missionKey != package.plan.mission.key || + mission->resourceStartId != package.plan.kernelLocalMission.startId || + mission->resourceCount != package.plan.kernelLocalMission.num) { + return FailMissionLaunchDescriptorProof( + diagnostic, + "install manifest mission requirement does not match the launch package"); + } + if (package.repository.instructions.empty() || + package.repository.dieId != package.plan.mission.dieId || + package.repository.missionCount == 0) { + return FailMissionLaunchDescriptorProof(diagnostic, "repository mission instruction window is missing"); + } + if (package.tasks.empty()) { + return FailMissionLaunchDescriptorProof(diagnostic, "launch task descriptor list is missing"); + } + for (const auto& task : package.tasks) { + if (task.dieId != package.plan.mission.dieId || + task.missionId != package.plan.mission.missionId || + task.key != package.plan.mission.key) { + return FailMissionLaunchDescriptorProof( + diagnostic, + "launch task descriptor mission id or mission key does not match the producer plan"); + } + if (!RepositoryMissionWindowContainsTask(package.repository, task)) { + return FailMissionLaunchDescriptorProof( + diagnostic, + "launch task descriptor instruction range is outside the repository mission window"); + } + } + if (diagnostic != nullptr) { + *diagnostic = + "mission/key carried by launch task descriptor mission id and mission key within repository window"; + } + return true; +} + +bool FailRemoteXnExchangeBindingProof(std::string* diagnostic, const std::string& reason) +{ + if (diagnostic != nullptr) { + *diagnostic = "remote XN peer exchange proof failed: " + reason; + } + return false; +} + +bool HasInstalledChannelRoute( + const TileXRCcuLowerLayerInstallPlan& lowerLayerPlan, + uint8_t dieId, + uint16_t channelId) +{ + for (const auto& channel : lowerLayerPlan.channels) { + if (channel.dieId == dieId && channel.channelId == channelId) { + return true; + } + } + return false; +} + +bool HasVerifiedEndpointRoutes(const TileXRCcuLowerLayerInstallPlan* lowerLayerPlan) +{ + if (lowerLayerPlan == nullptr || lowerLayerPlan->remoteXnBindings.empty()) { + return false; + } + for (const auto& proof : lowerLayerPlan->remoteXnBindings) { + if (!proof.peerExchangeObserved || !proof.endpointRouteVerified || + !HasInstalledChannelRoute(*lowerLayerPlan, proof.dieId, proof.channelId)) { + return false; + } + } + return true; +} + +bool HasVerifiedChannelResourceBindings(const TileXRCcuLowerLayerInstallPlan* lowerLayerPlan) +{ + if (lowerLayerPlan == nullptr || lowerLayerPlan->remoteXnBindings.empty()) { + return false; + } + for (const auto& proof : lowerLayerPlan->remoteXnBindings) { + if (!proof.peerExchangeObserved || + !proof.endpointRouteVerified || + !proof.channelResourceOwnerVerified || + !proof.transportResourceExchangeVerified || + !HasInstalledChannelRoute(*lowerLayerPlan, proof.dieId, proof.channelId)) { + return false; + } + } + return true; +} + +bool RequiresRemoteXnBindingEvidence(TileXRCcuBarrierMode mode) +{ + return mode == TileXRCcuBarrierMode::SyncXn || + mode == TileXRCcuBarrierMode::SyncXnPostOnly || + mode == TileXRCcuBarrierMode::SyncXnLoadPostOnly; +} + +bool RequiresChannelBindingEvidence(TileXRCcuBarrierMode mode) +{ + return mode != TileXRCcuBarrierMode::LocalCke && + mode != TileXRCcuBarrierMode::LocalCkePostOnly; +} + +uint16_t EffectiveResourceLocalWaitCke(const TileXRCcuSyncResource& resource) +{ + return resource.localWaitCke == 0 ? resource.notifyCke : resource.localWaitCke; +} + +uint16_t EffectiveProofLocalWaitCke(const TileXRCcuRemoteXnBindingProof& proof) +{ + return proof.localWaitCke == 0 ? proof.notifyCke : proof.localWaitCke; +} + +bool ValidateRemoteXnExchangeBindingProof( + const TileXRCcuLaunchPackage& package, + const TileXRCcuInstallManifest* manifest, + const TileXRCcuLowerLayerInstallPlan* lowerLayerPlan, + std::string* diagnostic) +{ + if (diagnostic != nullptr) { + diagnostic->clear(); + } + if (manifest == nullptr) { + return FailRemoteXnExchangeBindingProof(diagnostic, "install manifest remote XN requirement is missing"); + } + const TileXRCcuInstallRequirement* remoteXn = + FindRequirement(*manifest, TileXRCcuInstallRequirementKind::RemoteXnBinding); + const uint64_t packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + if (remoteXn == nullptr || + remoteXn->packageFingerprint != packageFingerprint || + remoteXn->syncResourceCount != package.plan.syncResources.size()) { + return FailRemoteXnExchangeBindingProof( + diagnostic, + "install manifest remote XN requirement does not match the launch package"); + } + if (lowerLayerPlan == nullptr || lowerLayerPlan->remoteXnBindings.empty()) { + return FailRemoteXnExchangeBindingProof( + diagnostic, + "remote XN install provider is missing; peer exchange proof is missing"); + } + if (lowerLayerPlan->remoteXnBindings.size() != package.plan.syncResources.size()) { + return FailRemoteXnExchangeBindingProof( + diagnostic, + "peer exchange proof count does not match sync resource count"); + } + + for (const auto& resource : package.plan.syncResources) { + bool identityMatched = false; + bool remoteNotifyCkeMismatch = false; + bool localWaitCkeMismatch = false; + bool matched = false; + for (const auto& proof : lowerLayerPlan->remoteXnBindings) { + if (proof.dieId != resource.dieId || + proof.channelId != resource.channelId || + proof.localXn != resource.localXn || + proof.remoteXn != resource.remoteXn) { + continue; + } + identityMatched = true; + if (proof.notifyCke != resource.notifyCke) { + remoteNotifyCkeMismatch = true; + continue; + } + if (EffectiveProofLocalWaitCke(proof) != EffectiveResourceLocalWaitCke(resource)) { + localWaitCkeMismatch = true; + continue; + } + if (!proof.peerExchangeObserved) { + return FailRemoteXnExchangeBindingProof(diagnostic, "peer exchange was not observed"); + } + if (!HasInstalledChannelRoute(*lowerLayerPlan, proof.dieId, proof.channelId)) { + return FailRemoteXnExchangeBindingProof(diagnostic, "matching channel route is not installed"); + } + if (!proof.endpointRouteVerified) { + return FailRemoteXnExchangeBindingProof( + diagnostic, + "endpoint route provenance was not verified"); + } + if (!proof.channelResourceOwnerVerified) { + return FailRemoteXnExchangeBindingProof( + diagnostic, + "channel resource owner did not verify channel-bound remote XN allocation"); + } + if (!proof.transportResourceExchangeVerified) { + return FailRemoteXnExchangeBindingProof( + diagnostic, + "transport resource exchange did not verify remote XN and notify CKE binding"); + } + matched = true; + break; + } + if (!matched) { + if (identityMatched && remoteNotifyCkeMismatch) { + return FailRemoteXnExchangeBindingProof( + diagnostic, + "syncXn remote notify CKE is not covered by peer exchange proof"); + } + if (identityMatched && localWaitCkeMismatch) { + return FailRemoteXnExchangeBindingProof( + diagnostic, + "syncXn local wait CKE is not covered by peer exchange proof"); + } + return FailRemoteXnExchangeBindingProof( + diagnostic, + "syncXn remote XN operand is not covered by peer exchange proof"); + } + } + + if (diagnostic != nullptr) { + *diagnostic = + "remote XN peer exchange proof matches syncXn operands, verified endpoint route channel contexts, " + "channel resource owner allocation, and transport resource exchange"; + } + return true; +} + +int ValidateInstallManifestScope( + const TileXRCcuLaunchPackage& package, + uint64_t packageFingerprint, + TileXRCcuInstallManifest* manifest, + TileXRCcuInstallManifestReport* report) +{ + if (package.tasks.empty()) { + return FailManifest(manifest, report, "missing CCU launch tasks for install manifest"); + } + if (package.repository.instructions.empty()) { + return FailManifest(manifest, report, "missing CCU repository image for install manifest"); + } + if (package.installScope.packageFingerprint == 0 || package.installScope.provider.empty()) { + return FailManifest(manifest, report, "launch install scope is not bound"); + } + if (package.installScope.packageFingerprint != packageFingerprint) { + return FailManifest(manifest, report, "launch install scope is stale"); + } + return TILEXR_SUCCESS; +} + +bool HasRequirementKind(const TileXRCcuInstallManifest& manifest, TileXRCcuInstallRequirementKind kind) +{ + bool found = false; + for (const auto& requirement : manifest.requirements) { + if (requirement.kind != kind) { + continue; + } + if (found) { + return false; + } + found = true; + } + return found; +} + +const TileXRCcuInstallRequirement* FindRequirement( + const TileXRCcuInstallManifest& manifest, + TileXRCcuInstallRequirementKind kind) +{ + for (const auto& requirement : manifest.requirements) { + if (requirement.kind == kind) { + return &requirement; + } + } + return nullptr; +} + +int ValidateRequirementMetadata( + const TileXRCcuInstallRequirement* requirement, + uint64_t packageFingerprint, + TileXRCcuInstallProviderReport* report) +{ + if (requirement == nullptr || requirement->label.empty() || requirement->detail.empty() || + requirement->packageFingerprint != packageFingerprint) { + FillScopeFailureReport(report, "install manifest requirement metadata mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + return TILEXR_SUCCESS; +} + +bool IsPublicVerifiedStep(const TileXRCcuInstallStepEvidence& step) +{ + return step.satisfied && step.source.kind == TileXRCcuEvidenceKind::PublicVerified; +} + +uint32_t CountPublicVerifiedSteps(const TileXRCcuInstallProviderReport& report) +{ + uint32_t count = 0; + count += IsPublicVerifiedStep(report.mission) ? 1U : 0U; + count += IsPublicVerifiedStep(report.repository) ? 1U : 0U; + count += IsPublicVerifiedStep(report.localXn) ? 1U : 0U; + count += IsPublicVerifiedStep(report.remoteXn) ? 1U : 0U; + count += IsPublicVerifiedStep(report.notifyCke) ? 1U : 0U; + count += IsPublicVerifiedStep(report.channelBinding) ? 1U : 0U; + return count; +} + +bool IsRequirementSatisfied( + TileXRCcuInstallRequirementKind kind, + const TileXRCcuInstallProviderReport& report) +{ + switch (kind) { + case TileXRCcuInstallRequirementKind::MissionKey: + return IsPublicVerifiedStep(report.mission); + case TileXRCcuInstallRequirementKind::RepositoryImage: + return IsPublicVerifiedStep(report.repository); + case TileXRCcuInstallRequirementKind::LocalXn: + return IsPublicVerifiedStep(report.localXn); + case TileXRCcuInstallRequirementKind::RemoteXnBinding: + return IsPublicVerifiedStep(report.remoteXn); + case TileXRCcuInstallRequirementKind::NotifyCke: + return IsPublicVerifiedStep(report.notifyCke); + case TileXRCcuInstallRequirementKind::ChannelBinding: + return IsPublicVerifiedStep(report.channelBinding); + default: + return false; + } +} + +uint32_t CountPublicVerifiedRequiredSteps( + const TileXRCcuInstallManifest& manifest, + const TileXRCcuInstallProviderReport& report) +{ + uint32_t count = 0; + for (const auto& requirement : manifest.requirements) { + count += IsRequirementSatisfied(requirement.kind, report) ? 1U : 0U; + } + return count; +} + +void FillManifestInstallSurfaceCounts( + const TileXRCcuInstallManifest* manifest, + TileXRCcuInstallProviderReport* report) +{ + if (manifest == nullptr || report == nullptr) { + return; + } + report->requiredInstallSurfaceCount = static_cast(manifest->requirements.size()); + report->publicVerifiedInstallSurfaceCount = CountPublicVerifiedRequiredSteps(*manifest, *report); + report->missingInstallSurfaceCount = + report->requiredInstallSurfaceCount > report->publicVerifiedInstallSurfaceCount ? + report->requiredInstallSurfaceCount - report->publicVerifiedInstallSurfaceCount : + 0U; +} + +bool RejectOfflinePublicVerified(const TileXRCcuInstallProviderReport& installReport) +{ + return installReport.offlineOnly && + (IsPublicVerifiedStep(installReport.mission) || + IsPublicVerifiedStep(installReport.repository) || + IsPublicVerifiedStep(installReport.localXn) || + IsPublicVerifiedStep(installReport.remoteXn) || + IsPublicVerifiedStep(installReport.notifyCke) || + IsPublicVerifiedStep(installReport.channelBinding)); +} + +bool HasPublicVerifiedStep(const TileXRCcuInstallProviderReport& installReport) +{ + return IsPublicVerifiedStep(installReport.mission) || + IsPublicVerifiedStep(installReport.repository) || + IsPublicVerifiedStep(installReport.localXn) || + IsPublicVerifiedStep(installReport.remoteXn) || + IsPublicVerifiedStep(installReport.notifyCke) || + IsPublicVerifiedStep(installReport.channelBinding); +} + +int ValidateInstallReceiptStep( + const std::string& label, + uint64_t expectedReceiptId, + const TileXRCcuInstallStepEvidence& step) +{ + (void)label; + if (!IsPublicVerifiedStep(step)) { + return TILEXR_SUCCESS; + } + if (expectedReceiptId == 0 || step.source.installAttemptReceiptId == 0) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (step.source.installAttemptReceiptId != expectedReceiptId) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + return TILEXR_SUCCESS; +} + +int ValidatePublicVerifiedStepScope(const std::string& label, const TileXRCcuInstallStepEvidence& step) +{ + (void)label; + if (!IsPublicVerifiedStep(step)) { + return TILEXR_SUCCESS; + } + if (step.source.surface != TileXRCcuEvidenceSurface::PublicInstallProvider || + step.source.packageFingerprint == 0 || + step.source.provider.empty() || + step.source.source.empty() || + step.source.detail.empty()) { + const std::string reason = "public verified evidence scope is incomplete"; + (void)reason; + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + return TILEXR_SUCCESS; +} + +int ValidateInstallReceipt(const TileXRCcuInstallProviderReport& installReport) +{ + if (HasPublicVerifiedStep(installReport) && + (!installReport.installAttempted || !installReport.installSucceeded)) { + const std::string reason = "install attempt did not succeed"; + (void)reason; + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidatePublicVerifiedStepScope("mission/key", installReport.mission) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidatePublicVerifiedStepScope("repository", installReport.repository) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidatePublicVerifiedStepScope("local XN", installReport.localXn) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidatePublicVerifiedStepScope("remote XN", installReport.remoteXn) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidatePublicVerifiedStepScope("notify CKE", installReport.notifyCke) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidatePublicVerifiedStepScope("channel binding", installReport.channelBinding) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateInstallReceiptStep( + "mission/key", installReport.installAttemptReceiptId, installReport.mission) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateInstallReceiptStep( + "repository", installReport.installAttemptReceiptId, installReport.repository) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateInstallReceiptStep( + "local XN", installReport.installAttemptReceiptId, installReport.localXn) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateInstallReceiptStep( + "remote XN", installReport.installAttemptReceiptId, installReport.remoteXn) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateInstallReceiptStep( + "notify CKE", installReport.installAttemptReceiptId, installReport.notifyCke) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateInstallReceiptStep( + "channel binding", installReport.installAttemptReceiptId, installReport.channelBinding) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + return TILEXR_SUCCESS; +} + +int ValidateInstallRequestScope(const TileXRCcuInstallRequest& request, TileXRCcuInstallProviderReport* report) +{ + const TileXRCcuLaunchPackage& package = *request.package; + const uint64_t packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + if (package.installScope.packageFingerprint == 0 || + package.installScope.packageFingerprint != packageFingerprint || + package.installScope.provider.empty()) { + FillScopeFailureReport(report, "launch install scope is not bound"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (request.deviceId != package.installScope.deviceId) { + FillScopeFailureReport(report, "device scope mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (request.rank != package.installScope.rank) { + FillScopeFailureReport(report, "rank scope mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (request.provider.empty() || request.provider != package.installScope.provider) { + FillScopeFailureReport(report, "provider scope mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + return TILEXR_SUCCESS; +} + +int ValidateInstallRequestManifest(const TileXRCcuInstallRequest& request, TileXRCcuInstallProviderReport* report) +{ + if (request.manifest == nullptr) { + return TILEXR_SUCCESS; + } + + const TileXRCcuLaunchPackage& package = *request.package; + const TileXRCcuInstallManifest& manifest = *request.manifest; + const uint64_t packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + if (manifest.packageFingerprint == 0 || manifest.packageFingerprint != packageFingerprint) { + FillScopeFailureReport(report, "install manifest fingerprint mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (manifest.deviceId != request.deviceId) { + FillScopeFailureReport(report, "install manifest device mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (manifest.rank != request.rank) { + FillScopeFailureReport(report, "install manifest rank mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (manifest.provider.empty() || manifest.provider != request.provider) { + FillScopeFailureReport(report, "install manifest provider mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (manifest.requiredEvidenceKind != TileXRCcuEvidenceKind::PublicVerified || + manifest.requiredEvidenceSurface != TileXRCcuEvidenceSurface::PublicInstallProvider) { + FillScopeFailureReport(report, "install manifest evidence contract mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (!manifest.installAttemptReceiptRequired) { + FillScopeFailureReport(report, "install manifest receipt contract mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + uint32_t expectedRequirementCount = 4U; + if (RequiresRemoteXnBindingEvidence(package.plan.barrierMode)) { + ++expectedRequirementCount; + } + if (RequiresChannelBindingEvidence(package.plan.barrierMode)) { + ++expectedRequirementCount; + } + if (manifest.requirements.size() != expectedRequirementCount) { + FillScopeFailureReport(report, "install manifest requirement count mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (!HasRequirementKind(manifest, TileXRCcuInstallRequirementKind::MissionKey) || + !HasRequirementKind(manifest, TileXRCcuInstallRequirementKind::RepositoryImage) || + !HasRequirementKind(manifest, TileXRCcuInstallRequirementKind::LocalXn) || + !HasRequirementKind(manifest, TileXRCcuInstallRequirementKind::NotifyCke)) { + FillScopeFailureReport(report, "install manifest requirement kind mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (RequiresRemoteXnBindingEvidence(package.plan.barrierMode) != + HasRequirementKind(manifest, TileXRCcuInstallRequirementKind::RemoteXnBinding)) { + FillScopeFailureReport(report, "install manifest remote XN requirement kind mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (RequiresChannelBindingEvidence(package.plan.barrierMode) != + HasRequirementKind(manifest, TileXRCcuInstallRequirementKind::ChannelBinding)) { + FillScopeFailureReport(report, "install manifest channel binding requirement kind mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + + if (manifest.requiresHardwareInstall != package.requiresHardwareInstall) { + FillScopeFailureReport(report, "install manifest hardware requirement mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + + const TileXRCcuInstallRequirement* mission = + FindRequirement(manifest, TileXRCcuInstallRequirementKind::MissionKey); + if (ValidateRequirementMetadata(mission, packageFingerprint, report) != TILEXR_SUCCESS || + mission->dieId != package.plan.mission.dieId || + mission->missionId != package.plan.mission.missionId || + mission->missionKey != package.plan.mission.key || + mission->resourceStartId != package.plan.kernelLocalMission.startId || + mission->resourceCount != package.plan.kernelLocalMission.num) { + FillScopeFailureReport(report, "install manifest mission requirement mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + + const TileXRCcuInstallRequirement* repository = + FindRequirement(manifest, TileXRCcuInstallRequirementKind::RepositoryImage); + if (ValidateRequirementMetadata(repository, packageFingerprint, report) != TILEXR_SUCCESS || + repository->dieId != package.repository.dieId || + repository->repositoryStartId != package.repository.repositoryStartId || + repository->repositoryCount != package.repository.repositoryCount || + repository->missionStartId != package.repository.missionStartId || + repository->missionCount != package.repository.missionCount || + repository->instructionCount != package.repository.instructions.size()) { + FillScopeFailureReport(report, "install manifest repository requirement mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + + const TileXRCcuInstallRequirement* localXn = + FindRequirement(manifest, TileXRCcuInstallRequirementKind::LocalXn); + if (ValidateRequirementMetadata(localXn, packageFingerprint, report) != TILEXR_SUCCESS || + localXn->dieId != package.plan.kernelLocalXn.dieId || + localXn->resourceStartId != package.plan.kernelLocalXn.startId || + localXn->resourceCount != package.plan.kernelLocalXn.num) { + FillScopeFailureReport(report, "install manifest local XN requirement mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + + if (RequiresRemoteXnBindingEvidence(package.plan.barrierMode)) { + const TileXRCcuInstallRequirement* remoteXn = + FindRequirement(manifest, TileXRCcuInstallRequirementKind::RemoteXnBinding); + if (ValidateRequirementMetadata(remoteXn, packageFingerprint, report) != TILEXR_SUCCESS || + remoteXn->dieId != package.plan.kernelLocalXn.dieId || + remoteXn->syncResourceCount != package.plan.syncResources.size()) { + FillScopeFailureReport(report, "install manifest remote XN requirement mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + } + + const TileXRCcuInstallRequirement* notifyCke = + FindRequirement(manifest, TileXRCcuInstallRequirementKind::NotifyCke); + if (ValidateRequirementMetadata(notifyCke, packageFingerprint, report) != TILEXR_SUCCESS || + notifyCke->dieId != package.plan.kernelLocalCke.dieId || + notifyCke->resourceStartId != package.plan.kernelLocalCke.startId || + notifyCke->resourceCount != package.plan.kernelLocalCke.num || + notifyCke->syncResourceCount != package.plan.syncResources.size()) { + FillScopeFailureReport(report, "install manifest notify CKE requirement mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + + if (RequiresChannelBindingEvidence(package.plan.barrierMode)) { + const TileXRCcuInstallRequirement* channel = + FindRequirement(manifest, TileXRCcuInstallRequirementKind::ChannelBinding); + if (ValidateRequirementMetadata(channel, packageFingerprint, report) != TILEXR_SUCCESS || + channel->dieId != package.plan.kernelLocalXn.dieId || + channel->syncResourceCount != package.plan.syncResources.size() || + channel->bindingCount != TotalBindingCount(package.plan.syncResources)) { + FillScopeFailureReport(report, "install manifest channel requirement mismatch"); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + } + return TILEXR_SUCCESS; +} + +bool HasRepositoryInstallProviderInputs(const TileXRCcuInstallRequest& request) +{ + return !request.offlineOnly && + request.driverAdapter != nullptr && + request.repositoryMemoryOps.alloc != nullptr && + request.repositoryMemoryOps.copyHostToDevice != nullptr && + request.repositoryMemoryOps.free != nullptr && + request.repositoryReceipt != nullptr; +} + +struct TileXRCcuLowerLayerInstallResult { + uint32_t msidTokenCount = 0; + uint32_t pfeCount = 0; + uint32_t jettyCount = 0; + uint32_t channelCount = 0; + uint32_t xnClearCount = 0; + uint32_t ckeClearCount = 0; + bool localXnInstalled = false; + bool notifyCkeInstalled = false; + bool channelBindingInstalled = false; + std::string message; +}; + +std::string FormatLowerLayerPreconditionSummary(const TileXRCcuLowerLayerInstallResult& result) +{ + std::ostringstream summary; + summary << "lowerLayerPreconditions{" + << "msidTokenCount=" << result.msidTokenCount + << " pfeCount=" << result.pfeCount + << " jettyCount=" << result.jettyCount + << " channelCount=" << result.channelCount + << " xnClearCount=" << result.xnClearCount + << " ckeClearCount=" << result.ckeClearCount + << " localXnInstalled=" << (result.localXnInstalled ? 1 : 0) + << " notifyCkeInstalled=" << (result.notifyCkeInstalled ? 1 : 0) + << " channelBindingInstalled=" << (result.channelBindingInstalled ? 1 : 0) + << "}"; + return summary.str(); +} + +std::string FormatLowerLayerPlanSummary(const TileXRCcuLowerLayerInstallPlan& plan) +{ + std::ostringstream summary; + if (!plan.msidTokens.empty()) { + const auto& token = plan.msidTokens.front(); + summary << " msidToken0{dieId=" << static_cast(token.dieId) + << " msId=" << token.msId + << " tokenId=0x" << std::hex << token.tokenId + << " tokenValue=0x" << token.tokenValue << std::dec + << "}"; + } + if (!plan.pfes.empty()) { + const auto& pfe = plan.pfes.front(); + summary << " pfe0{dieId=" << static_cast(pfe.dieId) + << " offset=" << pfe.pfeOffset + << "}"; + } + if (!plan.jettys.empty()) { + const auto& jetty = plan.jettys.front(); + summary << " jetty0{dieId=" << static_cast(jetty.dieId) + << " startJettyCtxId=" << jetty.startJettyCtxId + << " ctxCount=" << jetty.ctxs.size() + << "}"; + } + if (!plan.channels.empty()) { + const auto& channel = plan.channels.front(); + summary << " channel0{dieId=" << static_cast(channel.dieId) + << " channelId=" << channel.channelId + << "}"; + } + if (!plan.xnClears.empty()) { + const auto& xn = plan.xnClears.front(); + summary << " xnClear0{dieId=" << static_cast(xn.dieId) + << " startXnId=" << xn.startXnId + << " count=" << xn.count + << "}"; + } + if (!plan.ckeClears.empty()) { + const auto& cke = plan.ckeClears.front(); + summary << " ckeClear0{dieId=" << static_cast(cke.dieId) + << " startCkeId=" << cke.startCkeId + << " count=" << cke.count + << "}"; + } + if (!plan.remoteXnBindings.empty()) { + const auto& remote = plan.remoteXnBindings.front(); + summary << " remoteXn0{dieId=" << static_cast(remote.dieId) + << " channelId=" << remote.channelId + << " localXn=" << remote.localXn + << " remoteXn=" << remote.remoteXn + << " notifyCke=" << remote.notifyCke + << " localWaitCke=" << remote.localWaitCke + << " peerExchangeObserved=" << (remote.peerExchangeObserved ? 1 : 0) + << " endpointRouteVerified=" << (remote.endpointRouteVerified ? 1 : 0) + << " channelResourceOwnerVerified=" << (remote.channelResourceOwnerVerified ? 1 : 0) + << " transportResourceExchangeVerified=" << (remote.transportResourceExchangeVerified ? 1 : 0) + << "}"; + } + return summary.str(); +} + +int InstallLowerLayerResources( + const TileXRCcuDriverAdapter& adapter, + const TileXRCcuLowerLayerInstallPlan& plan, + TileXRCcuLowerLayerInstallResult* result) +{ + if (result == nullptr) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + *result = TileXRCcuLowerLayerInstallResult{}; + + TileXRCcuDriverAdapterReport driverReport; + for (const auto& token : plan.msidTokens) { + const int ret = adapter.InstallMsidToken( + token.dieId, + token.msId, + token.tokenId, + token.tokenValue, + &driverReport); + if (ret != TILEXR_SUCCESS) { + result->message = "failed to install CCU MSID token via SET_MSID_TOKEN: " + driverReport.message; + return ret; + } + ++result->msidTokenCount; + } + + for (const auto& pfe : plan.pfes) { + const int ret = adapter.InstallPfeCtx(pfe.dieId, pfe.pfeOffset, pfe.ctx, &driverReport); + if (ret != TILEXR_SUCCESS) { + result->message = "failed to install CCU PFE context via SET_PFE: " + driverReport.message; + return ret; + } + ++result->pfeCount; + } + + for (const auto& jetty : plan.jettys) { + const TileXRCcuLocalJettyCtxData* ctxs = jetty.ctxs.empty() ? nullptr : jetty.ctxs.data(); + const int ret = adapter.InstallJettyCtx( + jetty.dieId, + jetty.startJettyCtxId, + ctxs, + static_cast(jetty.ctxs.size()), + &driverReport); + if (ret != TILEXR_SUCCESS) { + result->message = "failed to install CCU local jetty contexts via SET_JETTY_CTX: " + + driverReport.message; + return ret; + } + ++result->jettyCount; + } + + for (const auto& channel : plan.channels) { + const int ret = adapter.InstallChannelCtxV1(channel.dieId, channel.channelId, channel.ctx, &driverReport); + if (ret != TILEXR_SUCCESS) { + result->message = "failed to install CCU channel context via SET_CHANNEL: " + driverReport.message; + return ret; + } + ++result->channelCount; + } + + for (const auto& xn : plan.xnClears) { + const int ret = adapter.InstallXnRange(xn.dieId, xn.startXnId, xn.count, &driverReport); + if (ret != TILEXR_SUCCESS) { + result->message = "failed to install CCU local XN range via SET_XN: " + driverReport.message; + return ret; + } + ++result->xnClearCount; + } + + for (const auto& cke : plan.ckeClears) { + const int ret = adapter.ClearCkeRange(cke.dieId, cke.startCkeId, cke.count, &driverReport); + if (ret != TILEXR_SUCCESS) { + result->message = "failed to clear CCU CKE range via SET_CKE: " + driverReport.message; + return ret; + } + ++result->ckeClearCount; + } + + result->localXnInstalled = result->xnClearCount > 0; + result->notifyCkeInstalled = result->ckeClearCount > 0; + const uint32_t expectedChannelCount = plan.remoteXnBindings.empty() ? + static_cast(plan.channels.size()) : + CountUniqueRemoteBindingChannels(plan.remoteXnBindings); + const uint32_t installedChannelCount = plan.remoteXnBindings.empty() ? + static_cast(result->channelCount) : + CountInstalledRemoteBindingChannels(plan.remoteXnBindings, plan.channels); + result->channelBindingInstalled = + result->pfeCount > 0 && result->jettyCount > 0 && expectedChannelCount > 0 && + installedChannelCount >= expectedChannelCount; + result->message = + "lower-layer CCU resources installed via SET_MSID_TOKEN, SET_PFE, SET_JETTY_CTX, SET_CHANNEL, SET_XN, SET_CKE"; + return TILEXR_SUCCESS; +} + +int InstallRepositoryImageForRequest( + const TileXRCcuInstallRequest& request, + TileXRCcuRepositoryReport* repositoryReport) +{ + return TileXRCcuInstallRepositoryImageWithOptions( + request.package->repository, + request.repositoryInstallOptions, + request.repositoryMemoryOps, + request.repositoryMemoryUserData, + *request.driverAdapter, + request.repositoryReceipt, + repositoryReport); +} + +int InstallRepositoryOnly( + const TileXRCcuInstallRequest& request, + TileXRCcuHardwareInstallEvidence* evidence, + TileXRCcuInstallProviderReport* report) +{ + const TileXRCcuLaunchPackage& package = *request.package; + TileXRCcuRepositoryReport repositoryReport; + TileXRCcuLowerLayerInstallResult lowerLayerResult; + + int lowerLayerRet = TILEXR_SUCCESS; + if (request.installOrder == TileXRCcuInstallOrder::InstallLowerLayerFirst && + request.lowerLayerPlan != nullptr) { + lowerLayerRet = InstallLowerLayerResources(*request.driverAdapter, *request.lowerLayerPlan, &lowerLayerResult); + if (lowerLayerRet != TILEXR_SUCCESS) { + TileXRCcuInstallProviderReport nextReport; + nextReport.offlineOnly = false; + nextReport.installAttempted = true; + nextReport.installSucceeded = false; + nextReport.message = lowerLayerResult.message; + MarkMissingStep(&nextReport.mission, "mission/key install provider is not implemented"); + MarkMissingStep(&nextReport.repository, "repository install skipped after lower-layer install failure"); + MarkMissingStep(&nextReport.localXn, lowerLayerResult.message); + MarkMissingStep(&nextReport.remoteXn, "remote XN binding provider is not implemented"); + MarkMissingStep(&nextReport.notifyCke, lowerLayerResult.message); + MarkMissingStep(&nextReport.channelBinding, lowerLayerResult.message); + FillManifestInstallSurfaceCounts(request.manifest, &nextReport); + if (report != nullptr) { + *report = nextReport; + } + if (TileXRCcuBuildInstallEvidence(nextReport, evidence) != TILEXR_SUCCESS) { + return TILEXR_ERROR_INTERNAL; + } + return lowerLayerRet; + } + } + + const int installRet = InstallRepositoryImageForRequest(request, &repositoryReport); + + TileXRCcuInstallProviderReport nextReport; + nextReport.offlineOnly = false; + nextReport.installAttempted = true; + + if (installRet != TILEXR_SUCCESS) { + nextReport.installSucceeded = false; + const bool lowerLayerFirstAttempted = + request.installOrder == TileXRCcuInstallOrder::InstallLowerLayerFirst && + request.lowerLayerPlan != nullptr; + const std::string lowerLayerSummary = lowerLayerFirstAttempted ? + FormatLowerLayerPreconditionSummary(lowerLayerResult) + + FormatLowerLayerPlanSummary(*request.lowerLayerPlan) : + std::string(); + const std::string repositoryFailureMessage = lowerLayerFirstAttempted ? + lowerLayerSummary + "; " + repositoryReport.message : + repositoryReport.message; + nextReport.message = repositoryFailureMessage; + MarkMissingStep(&nextReport.mission, "mission/key install provider is not implemented"); + MarkMissingStep(&nextReport.repository, repositoryReport.message); + MarkMissingStep( + &nextReport.localXn, + lowerLayerFirstAttempted ? lowerLayerSummary : "local XN install provider is not implemented"); + MarkMissingStep( + &nextReport.remoteXn, + lowerLayerFirstAttempted ? lowerLayerSummary : "remote XN binding provider is not implemented"); + MarkMissingStep( + &nextReport.notifyCke, + lowerLayerFirstAttempted ? lowerLayerSummary : "notify CKE install provider is not implemented"); + MarkMissingStep( + &nextReport.channelBinding, + lowerLayerFirstAttempted ? lowerLayerSummary : "channel binding provider is not implemented"); + FillManifestInstallSurfaceCounts(request.manifest, &nextReport); + if (report != nullptr) { + *report = nextReport; + } + if (TileXRCcuBuildInstallEvidence(nextReport, evidence) != TILEXR_SUCCESS) { + return TILEXR_ERROR_INTERNAL; + } + return installRet; + } + + nextReport.installSucceeded = true; + nextReport.installAttemptReceiptId = BuildRepositoryInstallReceiptId(package, *request.repositoryReceipt); + + if (request.lowerLayerPlan != nullptr && + request.installOrder != TileXRCcuInstallOrder::InstallLowerLayerFirst) { + lowerLayerRet = InstallLowerLayerResources(*request.driverAdapter, *request.lowerLayerPlan, &lowerLayerResult); + if (lowerLayerRet != TILEXR_SUCCESS) { + nextReport.installSucceeded = false; + nextReport.message = lowerLayerResult.message; + MarkMissingStep(&nextReport.mission, "mission/key install provider is not implemented"); + MarkMissingStep( + &nextReport.repository, + "repository install evidence withheld after lower-layer install failure"); + MarkMissingStep(&nextReport.localXn, lowerLayerResult.message); + MarkMissingStep(&nextReport.remoteXn, "remote XN binding provider is not implemented"); + MarkMissingStep(&nextReport.notifyCke, lowerLayerResult.message); + MarkMissingStep(&nextReport.channelBinding, lowerLayerResult.message); + FillManifestInstallSurfaceCounts(request.manifest, &nextReport); + if (report != nullptr) { + *report = nextReport; + } + if (TileXRCcuBuildInstallEvidence(nextReport, evidence) != TILEXR_SUCCESS) { + return TILEXR_ERROR_INTERNAL; + } + return lowerLayerRet; + } + } + + std::string missionProofMessage; + if (ValidateMissionLaunchDescriptorProof(package, request.manifest, &missionProofMessage)) { + nextReport.mission = PublicVerifiedStep( + package, + request, + nextReport.installAttemptReceiptId, + "ValidateMissionLaunchDescriptorProof", + missionProofMessage); + } else { + MarkMissingStep(&nextReport.mission, missionProofMessage); + } + nextReport.repository = PublicVerifiedStep( + package, + request, + nextReport.installAttemptReceiptId, + "TileXRCcuInstallRepositoryImage", + "repository instruction image installed via SET_INSTRUCTION"); + if (lowerLayerResult.localXnInstalled) { + nextReport.localXn = PublicVerifiedStep( + package, + request, + nextReport.installAttemptReceiptId, + "InstallLowerLayerResources", + "kernel-local XN resources initialized via SET_XN"); + } else { + MarkMissingStep(&nextReport.localXn, "local XN install provider is not implemented"); + } + std::string remoteXnProofMessage; + if (!RequiresRemoteXnBindingEvidence(package.plan.barrierMode)) { + MarkMissingStep( + &nextReport.remoteXn, + "remote XN binding is not required for this CCU barrier mode"); + } else if (ValidateRemoteXnExchangeBindingProof( + package, + request.manifest, + request.lowerLayerPlan, + &remoteXnProofMessage)) { + nextReport.remoteXn = PublicVerifiedStep( + package, + request, + nextReport.installAttemptReceiptId, + "ValidateRemoteXnExchangeBindingProof", + remoteXnProofMessage, + true); + } else { + MarkMissingStep(&nextReport.remoteXn, remoteXnProofMessage); + } + if (lowerLayerResult.notifyCkeInstalled) { + nextReport.notifyCke = PublicVerifiedStep( + package, + request, + nextReport.installAttemptReceiptId, + "InstallLowerLayerResources", + "notify CKE resources cleared via SET_CKE"); + } else { + MarkMissingStep(&nextReport.notifyCke, "notify CKE install provider is not implemented"); + } + if (!RequiresChannelBindingEvidence(package.plan.barrierMode)) { + MarkMissingStep( + &nextReport.channelBinding, + "channel binding is not required for this CCU barrier mode"); + } else if (lowerLayerResult.channelBindingInstalled && HasVerifiedChannelResourceBindings(request.lowerLayerPlan)) { + nextReport.channelBinding = PublicVerifiedStep( + package, + request, + nextReport.installAttemptReceiptId, + "InstallLowerLayerResources", + "channel binding contexts installed via SET_PFE, SET_JETTY_CTX, SET_CHANNEL with verified endpoint routes, " + "channel resource owner allocation, and transport resource exchange", + true); + } else if (lowerLayerResult.channelBindingInstalled && HasVerifiedEndpointRoutes(request.lowerLayerPlan)) { + MarkMissingStep( + &nextReport.channelBinding, + "channel binding channel resource owner or transport resource exchange provenance was not verified"); + } else if (lowerLayerResult.channelBindingInstalled) { + MarkMissingStep(&nextReport.channelBinding, "channel binding endpoint route provenance was not verified"); + } else { + MarkMissingStep(&nextReport.channelBinding, "channel binding provider is not implemented"); + } + if (request.lowerLayerPlan == nullptr) { + nextReport.message = + "repository instruction image installed via SET_INSTRUCTION; " + + (nextReport.mission.satisfied ? missionProofMessage : nextReport.mission.message) + + "; lower-layer CCU resources are missing"; + } else { + nextReport.message = + "repository instruction image installed via SET_INSTRUCTION; " + lowerLayerResult.message + + "; " + (nextReport.mission.satisfied ? remoteXnProofMessage : + nextReport.mission.message + "; " + remoteXnProofMessage); + } + FillManifestInstallSurfaceCounts(request.manifest, &nextReport); + + if (report != nullptr) { + *report = nextReport; + } + if (TileXRCcuBuildInstallEvidence(nextReport, evidence) != TILEXR_SUCCESS) { + return TILEXR_ERROR_INTERNAL; + } + if (nextReport.missingInstallSurfaceCount == 0) { + return TILEXR_SUCCESS; + } + return TILEXR_ERROR_NOT_FOUND; +} + +} // namespace + +int TileXRCcuBuildInstallEvidence( + const TileXRCcuInstallProviderReport& installReport, + TileXRCcuHardwareInstallEvidence* evidence) +{ + if (evidence == nullptr) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + *evidence = TileXRCcuHardwareInstallEvidence{}; + + if (RejectOfflinePublicVerified(installReport)) { + const std::string reason = "offline install evidence cannot be public verified"; + (void)reason; + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateInstallReceipt(installReport) != TILEXR_SUCCESS) { + const std::string reason = "install attempt receipt mismatch"; + (void)reason; + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + + TileXRCcuHardwareInstallEvidence result; + result.missionInstalled = installReport.mission.satisfied; + result.repositoryInstalled = installReport.repository.satisfied; + result.localXnInstalled = installReport.localXn.satisfied; + result.remoteXnBound = installReport.remoteXn.satisfied; + result.notifyCkeInstalled = installReport.notifyCke.satisfied; + result.channelBindingsInstalled = installReport.channelBinding.satisfied; + result.missionSource = SourceOrMissing(installReport.mission, "mission/key install evidence is missing"); + result.repositorySource = SourceOrMissing(installReport.repository, "repository install evidence is missing"); + result.localXnSource = SourceOrMissing(installReport.localXn, "local XN install evidence is missing"); + result.remoteXnSource = SourceOrMissing(installReport.remoteXn, "remote XN binding evidence is missing"); + result.notifyCkeSource = SourceOrMissing(installReport.notifyCke, "notify CKE install evidence is missing"); + result.channelBindingSource = + SourceOrMissing(installReport.channelBinding, "channel binding install evidence is missing"); + + *evidence = result; + return TILEXR_SUCCESS; +} + +int TileXRCcuBuildInstallManifest( + const TileXRCcuLaunchPackage& package, + TileXRCcuInstallManifest* manifest, + TileXRCcuInstallManifestReport* report) +{ + ResetManifestReport(report); + if (manifest == nullptr) { + return FailManifest(nullptr, report, "missing output CCU install manifest"); + } + *manifest = TileXRCcuInstallManifest{}; + + const uint64_t packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + if (ValidateInstallManifestScope(package, packageFingerprint, manifest, report) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + + TileXRCcuInstallManifest result; + result.packageFingerprint = packageFingerprint; + result.deviceId = package.installScope.deviceId; + result.rank = package.installScope.rank; + result.provider = package.installScope.provider; + result.requiresHardwareInstall = package.requiresHardwareInstall; + result.installAttemptReceiptRequired = true; + result.requiredEvidenceKind = TileXRCcuEvidenceKind::PublicVerified; + result.requiredEvidenceSurface = TileXRCcuEvidenceSurface::PublicInstallProvider; + + TileXRCcuInstallRequirement mission = BaseRequirement( + TileXRCcuInstallRequirementKind::MissionKey, + packageFingerprint, + package.plan.mission.dieId, + "mission/key", + "install CCU mission id and key"); + mission.missionId = package.plan.mission.missionId; + mission.missionKey = package.plan.mission.key; + mission.resourceStartId = package.plan.kernelLocalMission.startId; + mission.resourceCount = package.plan.kernelLocalMission.num; + result.requirements.push_back(mission); + + TileXRCcuInstallRequirement repository = BaseRequirement( + TileXRCcuInstallRequirementKind::RepositoryImage, + packageFingerprint, + package.repository.dieId, + "repository", + "install generated CCU repository image"); + repository.repositoryStartId = package.repository.repositoryStartId; + repository.repositoryCount = package.repository.repositoryCount; + repository.missionStartId = package.repository.missionStartId; + repository.missionCount = package.repository.missionCount; + repository.instructionCount = static_cast(package.repository.instructions.size()); + result.requirements.push_back(repository); + + TileXRCcuInstallRequirement localXn = BaseRequirement( + TileXRCcuInstallRequirementKind::LocalXn, + packageFingerprint, + package.plan.kernelLocalXn.dieId, + "local XN", + "install kernel-local CCU XN resource window"); + localXn.resourceStartId = package.plan.kernelLocalXn.startId; + localXn.resourceCount = package.plan.kernelLocalXn.num; + result.requirements.push_back(localXn); + + if (RequiresRemoteXnBindingEvidence(package.plan.barrierMode)) { + TileXRCcuInstallRequirement remoteXn = BaseRequirement( + TileXRCcuInstallRequirementKind::RemoteXnBinding, + packageFingerprint, + package.plan.kernelLocalXn.dieId, + "remote XN binding", + "bind remote CCU XN resources referenced by sync instructions"); + remoteXn.syncResourceCount = static_cast(package.plan.syncResources.size()); + result.requirements.push_back(remoteXn); + } + + TileXRCcuInstallRequirement notifyCke = BaseRequirement( + TileXRCcuInstallRequirementKind::NotifyCke, + packageFingerprint, + package.plan.kernelLocalCke.dieId, + "notify CKE", + "install notify CKE resources referenced by sync instructions"); + notifyCke.resourceStartId = package.plan.kernelLocalCke.startId; + notifyCke.resourceCount = package.plan.kernelLocalCke.num; + notifyCke.syncResourceCount = static_cast(package.plan.syncResources.size()); + result.requirements.push_back(notifyCke); + + if (RequiresChannelBindingEvidence(package.plan.barrierMode)) { + TileXRCcuInstallRequirement channel = BaseRequirement( + TileXRCcuInstallRequirementKind::ChannelBinding, + packageFingerprint, + package.plan.kernelLocalXn.dieId, + "channel binding", + "bind CCU channel routes for sync resources"); + channel.syncResourceCount = static_cast(package.plan.syncResources.size()); + channel.bindingCount = TotalBindingCount(package.plan.syncResources); + result.requirements.push_back(channel); + } + + if (report != nullptr) { + report->requirementCount = static_cast(result.requirements.size()); + report->message = "ok"; + } + *manifest = result; + return TILEXR_SUCCESS; +} + +int TileXRCcuInstallHardware( + const TileXRCcuInstallRequest& request, + TileXRCcuHardwareInstallEvidence* evidence, + TileXRCcuInstallProviderReport* report) +{ + ResetReport(report); + if (evidence == nullptr) { + FillUnsupportedReport(report); + if (report != nullptr) { + report->message = "missing output CCU hardware install evidence"; + } + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + *evidence = TileXRCcuHardwareInstallEvidence{}; + + if (request.package == nullptr) { + FillUnsupportedReport(report); + if (report != nullptr) { + report->message = "missing CCU launch package for hardware install"; + } + TileXRCcuInstallProviderReport missingReport; + FillUnsupportedReport(&missingReport); + return TileXRCcuBuildInstallEvidence(missingReport, evidence) == TILEXR_SUCCESS ? + TILEXR_ERROR_PARA_CHECK_FAIL : + TILEXR_ERROR_INTERNAL; + } + + if (ValidateInstallRequestScope(request, report) != TILEXR_SUCCESS) { + TileXRCcuInstallProviderReport missingReport; + FillScopeFailureReport(&missingReport, report == nullptr ? "install request scope mismatch" : report->message); + return TileXRCcuBuildInstallEvidence(missingReport, evidence) == TILEXR_SUCCESS ? + TILEXR_ERROR_PARA_CHECK_FAIL : + TILEXR_ERROR_INTERNAL; + } + if (ValidateInstallRequestManifest(request, report) != TILEXR_SUCCESS) { + TileXRCcuInstallProviderReport missingReport; + FillScopeFailureReport( + &missingReport, + report == nullptr ? "install request manifest mismatch" : report->message); + return TileXRCcuBuildInstallEvidence(missingReport, evidence) == TILEXR_SUCCESS ? + TILEXR_ERROR_PARA_CHECK_FAIL : + TILEXR_ERROR_INTERNAL; + } + + if (HasRepositoryInstallProviderInputs(request)) { + return InstallRepositoryOnly(request, evidence, report); + } + + FillUnsupportedReport(report); + FillManifestInstallSurfaceCounts(request.manifest, report); + TileXRCcuInstallProviderReport missingReport; + FillUnsupportedReport(&missingReport); + if (TileXRCcuBuildInstallEvidence(missingReport, evidence) != TILEXR_SUCCESS) { + return TILEXR_ERROR_INTERNAL; + } + return TILEXR_ERROR_NOT_FOUND; +} + +} // namespace TileXR diff --git a/src/comm/ccu/tilexr_ccu_install_provider.h b/src/comm/ccu/tilexr_ccu_install_provider.h new file mode 100644 index 00000000..5d12b51f --- /dev/null +++ b/src/comm/ccu/tilexr_ccu_install_provider.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2026 TileXR Project + * Licensed under the Apache License, Version 2.0 + */ + +#ifndef TILEXR_CCU_INSTALL_PROVIDER_H +#define TILEXR_CCU_INSTALL_PROVIDER_H + +#include "ccu/tilexr_ccu_provider.h" + +#include +#include +#include + +namespace TileXR { + +enum class TileXRCcuInstallRequirementKind : uint8_t { + MissionKey = 0, + RepositoryImage = 1, + LocalXn = 2, + RemoteXnBinding = 3, + NotifyCke = 4, + ChannelBinding = 5, +}; + +struct TileXRCcuInstallRequirement { + TileXRCcuInstallRequirementKind kind = TileXRCcuInstallRequirementKind::MissionKey; + uint64_t packageFingerprint = 0; + uint8_t dieId = 0; + uint8_t missionId = 0; + uint32_t missionKey = 0; + uint16_t resourceStartId = 0; + uint16_t resourceCount = 0; + uint16_t repositoryStartId = 0; + uint16_t repositoryCount = 0; + uint16_t missionStartId = 0; + uint16_t missionCount = 0; + uint32_t instructionCount = 0; + uint32_t syncResourceCount = 0; + uint32_t bindingCount = 0; + std::string label; + std::string detail; +}; + +struct TileXRCcuInstallManifest { + uint64_t packageFingerprint = 0; + uint32_t deviceId = 0; + uint32_t rank = 0; + std::string provider; + bool requiresHardwareInstall = true; + bool installAttemptReceiptRequired = true; + TileXRCcuEvidenceKind requiredEvidenceKind = TileXRCcuEvidenceKind::PublicVerified; + TileXRCcuEvidenceSurface requiredEvidenceSurface = TileXRCcuEvidenceSurface::PublicInstallProvider; + std::vector requirements; +}; + +struct TileXRCcuInstallManifestReport { + uint32_t requirementCount = 0; + std::string message; +}; + +struct TileXRCcuMsidTokenInstall { + uint8_t dieId = 0; + uint32_t msId = 0; + uint32_t tokenId = 0; + uint32_t tokenValue = 0; +}; + +struct TileXRCcuPfeInstall { + uint8_t dieId = 0; + uint32_t pfeOffset = 0; + TileXRCcuPfeCtx ctx; +}; + +struct TileXRCcuJettyInstall { + uint8_t dieId = 0; + uint16_t startJettyCtxId = 0; + std::vector ctxs; +}; + +struct TileXRCcuChannelInstall { + uint8_t dieId = 0; + uint32_t channelId = 0; + TileXRCcuChannelCtxDataV1 ctx; +}; + +struct TileXRCcuCkeClearInstall { + uint8_t dieId = 0; + uint32_t startCkeId = 0; + uint32_t count = 0; +}; + +struct TileXRCcuXnClearInstall { + uint8_t dieId = 0; + uint32_t startXnId = 0; + uint32_t count = 0; +}; + +struct TileXRCcuRemoteXnBindingProof { + uint8_t dieId = 0; + uint16_t channelId = 0; + uint16_t localXn = 0; + uint16_t remoteXn = 0; + uint16_t notifyCke = 0; + uint32_t peerRank = 0; + bool peerExchangeObserved = false; + uint16_t localWaitCke = 0; + bool endpointRouteVerified = false; + bool channelResourceOwnerVerified = false; + bool transportResourceExchangeVerified = false; +}; + +struct TileXRCcuLowerLayerInstallPlan { + std::vector msidTokens; + std::vector pfes; + std::vector jettys; + std::vector channels; + std::vector xnClears; + std::vector ckeClears; + std::vector remoteXnBindings; +}; + +enum class TileXRCcuInstallOrder : uint8_t { + RepositoryFirst = 0, + InstallLowerLayerFirst = 1, +}; + +struct TileXRCcuInstallRequest { + const TileXRCcuLaunchPackage* package = nullptr; + const TileXRCcuInstallManifest* manifest = nullptr; + uint32_t deviceId = 0; + uint32_t rank = 0; + std::string provider; + bool offlineOnly = true; + const TileXRCcuDriverAdapter* driverAdapter = nullptr; + TileXRCcuDeviceMemoryOps repositoryMemoryOps; + void* repositoryMemoryUserData = nullptr; + TileXRCcuRepositoryInstallOptions repositoryInstallOptions; + TileXRCcuRepositoryInstallReceipt* repositoryReceipt = nullptr; + TileXRCcuInstallOrder installOrder = TileXRCcuInstallOrder::RepositoryFirst; + const TileXRCcuLowerLayerInstallPlan* lowerLayerPlan = nullptr; +}; + +struct TileXRCcuInstallStepEvidence { + bool satisfied = false; + TileXRCcuEvidenceSource source; + std::string message; +}; + +struct TileXRCcuInstallProviderReport { + TileXRCcuInstallStepEvidence mission; + TileXRCcuInstallStepEvidence repository; + TileXRCcuInstallStepEvidence localXn; + TileXRCcuInstallStepEvidence remoteXn; + TileXRCcuInstallStepEvidence notifyCke; + TileXRCcuInstallStepEvidence channelBinding; + bool offlineOnly = true; + bool installAttempted = false; + bool installSucceeded = false; + uint32_t requiredInstallSurfaceCount = 0; + uint32_t publicVerifiedInstallSurfaceCount = 0; + uint32_t missingInstallSurfaceCount = 0; + uint64_t installAttemptReceiptId = 0; + std::string message; +}; + +int TileXRCcuBuildInstallEvidence( + const TileXRCcuInstallProviderReport& installReport, + TileXRCcuHardwareInstallEvidence* evidence); + +int TileXRCcuBuildInstallManifest( + const TileXRCcuLaunchPackage& package, + TileXRCcuInstallManifest* manifest, + TileXRCcuInstallManifestReport* report); + +int TileXRCcuInstallHardware( + const TileXRCcuInstallRequest& request, + TileXRCcuHardwareInstallEvidence* evidence, + TileXRCcuInstallProviderReport* report); + +} // namespace TileXR + +#endif // TILEXR_CCU_INSTALL_PROVIDER_H diff --git a/src/comm/ccu/tilexr_ccu_launch_package.cpp b/src/comm/ccu/tilexr_ccu_launch_package.cpp new file mode 100644 index 00000000..fa1a5ec0 --- /dev/null +++ b/src/comm/ccu/tilexr_ccu_launch_package.cpp @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2026 TileXR Project + * Licensed under the Apache License, Version 2.0 + */ + +#include "ccu/tilexr_ccu_launch_package.h" + +namespace TileXR { +namespace { + +constexpr uint64_t TILEXR_CCU_FNV_OFFSET = 1469598103934665603ULL; +constexpr uint64_t TILEXR_CCU_FNV_PRIME = 1099511628211ULL; + +void MixByte(uint8_t value, uint64_t* hash) +{ + *hash ^= value; + *hash *= TILEXR_CCU_FNV_PRIME; +} + +void MixU16(uint16_t value, uint64_t* hash) +{ + MixByte(static_cast(value & 0xffU), hash); + MixByte(static_cast((value >> 8U) & 0xffU), hash); +} + +void MixU32(uint32_t value, uint64_t* hash) +{ + MixU16(static_cast(value & 0xffffU), hash); + MixU16(static_cast((value >> 16U) & 0xffffU), hash); +} + +void MixU64(uint64_t value, uint64_t* hash) +{ + MixU32(static_cast(value & 0xffffffffULL), hash); + MixU32(static_cast((value >> 32ULL) & 0xffffffffULL), hash); +} + +void MixRange(const TileXRCcuRange& range, uint64_t* hash) +{ + MixByte(range.dieId, hash); + MixU16(range.startId, hash); + MixU16(range.num, hash); +} + +void MixMission(const TileXRCcuMission& mission, uint64_t* hash) +{ + MixByte(mission.dieId, hash); + MixByte(mission.missionId, hash); + MixU32(mission.key, hash); + MixByte(mission.installed ? 1U : 0U, hash); +} + +void MixInstructionWindow(const TileXRCcuInstructionWindow& window, uint64_t* hash) +{ + MixByte(window.dieId, hash); + MixU16(window.repositoryStartId, hash); + MixU16(window.repositoryCount, hash); + MixU16(window.missionStartId, hash); + MixU16(window.missionCount, hash); +} + +void MixSyncResource(const TileXRCcuSyncResource& resource, uint64_t* hash) +{ + MixByte(resource.dieId, hash); + MixU16(resource.localXn, hash); + MixU16(resource.remoteXn, hash); + MixU16(resource.notifyCke, hash); + MixU16(resource.channelId, hash); + MixU16(resource.bindingCount, hash); + MixU16(resource.localWaitCke, hash); + MixU16(resource.localWaitMask, hash); + MixU16(resource.remoteNotifyMask, hash); + MixU16(resource.sourceCke, hash); + MixU16(resource.sourceCkeMask, hash); +} + +void MixTaskWindow(const TileXRCcuTaskWindow& window, uint64_t* hash) +{ + MixByte(window.dieId, hash); + MixU16(window.instStartId, hash); + MixU16(window.instCnt, hash); + MixU32(window.argSize, hash); + MixU64(static_cast(window.args.size()), hash); + for (uint64_t arg : window.args) { + MixU64(arg, hash); + } +} + +void MixInstr(const TileXRCcuInstr& instr, uint64_t* hash) +{ + for (uint64_t word : instr.words) { + MixU64(word, hash); + } +} + +void MixRepository(const TileXRCcuRepositoryImage& repository, uint64_t* hash) +{ + MixByte(repository.dieId, hash); + MixU16(repository.repositoryStartId, hash); + MixU16(repository.repositoryCount, hash); + MixU16(repository.missionStartId, hash); + MixU16(repository.missionCount, hash); + MixU16(repository.missionOffset, hash); + MixU16(repository.sqeLoadOffset, hash); + MixU16(repository.sqeLoadCount, hash); + MixU16(repository.syncOffset, hash); + MixU16(repository.syncCount, hash); + MixU64(static_cast(repository.instructions.size()), hash); + for (const auto& instr : repository.instructions) { + MixInstr(instr, hash); + } +} + +void MixTask(const TileXRCcuTask& task, uint64_t* hash) +{ + MixByte(task.dieId, hash); + MixByte(task.missionId, hash); + MixU16(task.timeout, hash); + MixU16(task.instStartId, hash); + MixU16(task.instCnt, hash); + MixU32(task.key, hash); + MixU32(task.argSize, hash); + for (uint64_t arg : task.args) { + MixU64(arg, hash); + } +} + +void ResetReport(TileXRCcuLaunchPackageReport* report) +{ + if (report == nullptr) { + return; + } + report->taskCount = 0; + report->repositoryCount = 0; + report->installedInstructionCount = 0; + report->message.clear(); +} + +void ClearPackage(TileXRCcuLaunchPackage* package) +{ + if (package == nullptr) { + return; + } + package->plan = TileXRCcuProducerPlan{}; + package->program = TileXRCcuProgram{}; + package->repository = TileXRCcuRepositoryImage{}; + package->tasks.clear(); + package->installScope = TileXRCcuLaunchInstallScope{}; + package->requiresHardwareInstall = true; +} + +int Fail(TileXRCcuLaunchPackageReport* report, const std::string& message) +{ + if (report != nullptr) { + report->message = message; + } + return TILEXR_ERROR_PARA_CHECK_FAIL; +} + +void FillReport(const TileXRCcuLaunchPackage& package, TileXRCcuLaunchPackageReport* report) +{ + if (report == nullptr) { + return; + } + report->taskCount = static_cast(package.tasks.size()); + report->repositoryCount = package.repository.repositoryCount; + report->installedInstructionCount = + static_cast(package.repository.sqeLoadCount + package.repository.syncCount); + report->message = "ok"; +} + +} // namespace + +int TileXRCcuBuildLaunchPackage( + const TileXRCcuProducerPlan& plan, + TileXRCcuLaunchPackage* package, + TileXRCcuLaunchPackageReport* report) +{ + ResetReport(report); + if (package == nullptr) { + return Fail(report, "missing output CCU launch package"); + } + ClearPackage(package); + + TileXRCcuProducerPlanReport planReport; + TileXRCcuProgram program; + if (TileXRCcuBuildMicrocode(plan, &program, &planReport) != TILEXR_SUCCESS) { + ClearPackage(package); + return Fail(report, planReport.message); + } + + TileXRCcuRepositoryImage repository; + TileXRCcuRepositoryReport repositoryReport; + if (TileXRCcuBuildRepositoryImage(plan, program, &repository, &repositoryReport) != TILEXR_SUCCESS) { + ClearPackage(package); + return Fail(report, repositoryReport.message); + } + + std::vector tasks; + if (TileXRCcuBuildTasks(plan, &tasks, &planReport) != TILEXR_SUCCESS) { + ClearPackage(package); + return Fail(report, planReport.message); + } + + package->plan = plan; + package->program = program; + package->repository = repository; + package->tasks = tasks; + package->installScope = TileXRCcuLaunchInstallScope{}; + package->requiresHardwareInstall = true; + FillReport(*package, report); + return TILEXR_SUCCESS; +} + +uint64_t TileXRCcuComputeLaunchPackageFingerprint(const TileXRCcuLaunchPackage& package) +{ + uint64_t hash = TILEXR_CCU_FNV_OFFSET; + MixU64(0x54494c4558524343ULL, &hash); // "TILEXRCC" + MixMission(package.plan.mission, &hash); + MixRange(package.plan.kernelLocalXn, &hash); + MixRange(package.plan.kernelLocalGsa, &hash); + MixRange(package.plan.kernelLocalCke, &hash); + MixRange(package.plan.kernelLocalMission, &hash); + MixU32(static_cast(package.plan.barrierMode), &hash); + MixInstructionWindow(package.plan.instructionWindow, &hash); + MixU64(static_cast(package.plan.syncResources.size()), &hash); + for (const auto& resource : package.plan.syncResources) { + MixSyncResource(resource, &hash); + } + MixU64(static_cast(package.plan.taskWindows.size()), &hash); + for (const auto& window : package.plan.taskWindows) { + MixTaskWindow(window, &hash); + } + MixU64(static_cast(package.program.sqeLoad.size()), &hash); + for (const auto& instr : package.program.sqeLoad) { + MixInstr(instr, &hash); + } + MixU64(static_cast(package.program.sync.size()), &hash); + for (const auto& instr : package.program.sync) { + MixInstr(instr, &hash); + } + MixRepository(package.repository, &hash); + MixU64(static_cast(package.tasks.size()), &hash); + for (const auto& task : package.tasks) { + MixTask(task, &hash); + } + MixByte(package.requiresHardwareInstall ? 1U : 0U, &hash); + return hash == 0 ? 1 : hash; +} + +int TileXRCcuBindLaunchPackageInstallScope( + TileXRCcuLaunchPackage* package, + uint32_t deviceId, + uint32_t rank, + const std::string& provider) +{ + if (package == nullptr || provider.empty()) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (package->tasks.empty() || package->repository.instructions.empty()) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + package->installScope.deviceId = deviceId; + package->installScope.rank = rank; + package->installScope.provider = provider; + package->installScope.packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(*package); + return TILEXR_SUCCESS; +} + +} // namespace TileXR diff --git a/src/comm/ccu/tilexr_ccu_launch_package.h b/src/comm/ccu/tilexr_ccu_launch_package.h new file mode 100644 index 00000000..891b4d4e --- /dev/null +++ b/src/comm/ccu/tilexr_ccu_launch_package.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2026 TileXR Project + * Licensed under the Apache License, Version 2.0 + */ + +#ifndef TILEXR_CCU_LAUNCH_PACKAGE_H +#define TILEXR_CCU_LAUNCH_PACKAGE_H + +#include "ccu/tilexr_ccu_repository.h" + +#include +#include +#include + +namespace TileXR { + +struct TileXRCcuLaunchInstallScope { + uint32_t deviceId = 0; + uint32_t rank = 0; + uint64_t packageFingerprint = 0; + std::string provider; +}; + +struct TileXRCcuLaunchPackage { + TileXRCcuProducerPlan plan; + TileXRCcuProgram program; + TileXRCcuRepositoryImage repository; + std::vector tasks; + TileXRCcuLaunchInstallScope installScope; + bool requiresHardwareInstall = true; +}; + +struct TileXRCcuLaunchPackageReport { + uint32_t taskCount = 0; + uint32_t repositoryCount = 0; + uint32_t installedInstructionCount = 0; + std::string message; +}; + +int TileXRCcuBuildLaunchPackage( + const TileXRCcuProducerPlan& plan, + TileXRCcuLaunchPackage* package, + TileXRCcuLaunchPackageReport* report); + +uint64_t TileXRCcuComputeLaunchPackageFingerprint(const TileXRCcuLaunchPackage& package); + +int TileXRCcuBindLaunchPackageInstallScope( + TileXRCcuLaunchPackage* package, + uint32_t deviceId, + uint32_t rank, + const std::string& provider); + +} // namespace TileXR + +#endif // TILEXR_CCU_LAUNCH_PACKAGE_H diff --git a/src/comm/ccu/tilexr_ccu_lower_layer_plan_builder.cpp b/src/comm/ccu/tilexr_ccu_lower_layer_plan_builder.cpp new file mode 100644 index 00000000..095c38aa --- /dev/null +++ b/src/comm/ccu/tilexr_ccu_lower_layer_plan_builder.cpp @@ -0,0 +1,671 @@ +/* + * Copyright (c) 2026 TileXR Project + * Licensed under the Apache License, Version 2.0 + */ + +#include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + +#include +#include +#include +#include + +namespace TileXR { +namespace { + +constexpr uint16_t TILEXR_CCU_DEFAULT_START_JETTY_ID = 1024; +constexpr uint16_t TILEXR_CCU_DEFAULT_START_LOCAL_JETTY_CTX_ID = 0; +constexpr uint16_t TILEXR_CCU_WQE_BASIC_BLOCKS_PER_ROUTE = 4; +constexpr uint16_t TILEXR_CCU_HCOMM_WQE_BASIC_BLOCKS_PER_ROUTE = 256; +constexpr uint32_t TILEXR_CCU_HCOMM_PER_DIE_PFE_RESERVED_NUM = 16; +constexpr uint16_t TILEXR_CCU_HCOMM_INNER_FE_JETTY_NUM = 23; +constexpr uint16_t TILEXR_CCU_HCOMM_OUTER_FE_START_JETTY_CTX_ID = 92; +constexpr uint16_t TILEXR_CCU_HCOMM_OUTER_FE_JETTY_NUM = 36; +constexpr uint32_t TILEXR_CCU_HCOMM_MAX_INNER_FE_ID = 7; + +void ResetReport(TileXRCcuLowerLayerPlanBuilderReport* report) +{ + if (report != nullptr) { + *report = TileXRCcuLowerLayerPlanBuilderReport{}; + } +} + +int Fail( + TileXRCcuLowerLayerInstallPlan* plan, + TileXRCcuLowerLayerPlanBuilderReport* report, + const std::string& message) +{ + if (plan != nullptr) { + *plan = TileXRCcuLowerLayerInstallPlan{}; + } + if (report != nullptr) { + report->message = message; + } + return TILEXR_ERROR_PARA_CHECK_FAIL; +} + +int FailPayload( + TileXRCcuLowerLayerInstallPlan* plan, + TileXRCcuLowerLayerPlanBuilderReport* report, + const TileXRCcuLowerLayerPayloadReport& payloadReport) +{ + return Fail(plan, report, payloadReport.message.empty() ? "invalid lower-layer CCU payload spec" : + payloadReport.message); +} + +uint16_t CheckedU16(uint32_t value) +{ + return static_cast(std::min(value, std::numeric_limits::max())); +} + +bool AddOverflowsU16(uint16_t start, uint32_t count) +{ + return static_cast(start) + count > + static_cast(std::numeric_limits::max()) + 1U; +} + +TileXRCcuRange EffectiveLocalWaitCkeRange(const TileXRCcuResourceAllocation& allocation) +{ + TileXRCcuRange local = allocation.localWaitCke.num == 0 ? allocation.notifyCke : allocation.localWaitCke; + if (allocation.sourceCke.num == 0) { + return local; + } + if (local.dieId == allocation.sourceCke.dieId && + static_cast(local.startId) + local.num == allocation.sourceCke.startId) { + local.num = CheckedU16(static_cast(local.num) + allocation.sourceCke.num); + } + return local; +} + +TileXRCcuRange EffectiveRemoteNotifyCkeRange(const TileXRCcuResourceAllocation& allocation) +{ + return allocation.remoteNotifyCke.num == 0 ? allocation.notifyCke : allocation.remoteNotifyCke; +} + +uint16_t SelectLowerLayerWqeBasicBlockStride() +{ + const char* value = std::getenv("TILEXR_CCU_DIRECT_LOWER_LAYER_WQE_MODE"); + if (value != nullptr && std::strcmp(value, "hcomm_cap") == 0) { + return TILEXR_CCU_HCOMM_WQE_BASIC_BLOCKS_PER_ROUTE; + } + return TILEXR_CCU_WQE_BASIC_BLOCKS_PER_ROUTE; +} + +bool LowerLayerEnvEquals(const char* name, const char* expected) +{ + const char* value = std::getenv(name); + return value != nullptr && std::strcmp(value, expected) == 0; +} + +bool IsEmptyEndpointEid(const std::array& eid) +{ + return std::all_of(eid.begin(), eid.end(), [](uint8_t value) { + return value == 0; + }); +} + +bool HasCompleteVerifiedEndpointRoute(const TileXRCcuLowerLayerTransportRoute& route) +{ + return route.endpointRouteVerified && + !IsEmptyEndpointEid(route.remoteEid) && + route.doorbellVa != 0 && + route.doorbellTokenId != 0 && + route.sqDepth != 0; +} + +bool RangeContains(uint32_t start, uint32_t count, uint32_t value) +{ + return count != 0 && value >= start && value < start + count; +} + +uint32_t SelectLowerLayerPfeOffset(uint8_t dieId, uint32_t pfeId) +{ + if (LowerLayerEnvEquals("TILEXR_CCU_DIRECT_LOWER_LAYER_PFE_OFFSET_SOURCE", "hcomm_die")) { + return static_cast(dieId) * TILEXR_CCU_HCOMM_PER_DIE_PFE_RESERVED_NUM + pfeId; + } + return pfeId; +} + +void ApplyHcommFeIdPfePartition(uint32_t pfeId, TileXRCcuLowerLayerTransportSnapshot* snapshot) +{ + if (snapshot == nullptr) { + return; + } + if (pfeId > TILEXR_CCU_HCOMM_MAX_INNER_FE_ID) { + snapshot->startLocalJettyCtxId = TILEXR_CCU_HCOMM_OUTER_FE_START_JETTY_CTX_ID; + snapshot->pfeJettyCount = TILEXR_CCU_HCOMM_OUTER_FE_JETTY_NUM; + } else { + snapshot->startLocalJettyCtxId = CheckedU16(pfeId * TILEXR_CCU_HCOMM_INNER_FE_JETTY_NUM); + snapshot->pfeJettyCount = TILEXR_CCU_HCOMM_INNER_FE_JETTY_NUM; + } + snapshot->startJettyId = CheckedU16(TILEXR_CCU_DEFAULT_START_JETTY_ID + snapshot->startLocalJettyCtxId); +} + +void ApplyHcommOrderedPfePartition(TileXRCcuLowerLayerTransportSnapshot* snapshot) +{ + if (snapshot == nullptr) { + return; + } + snapshot->startLocalJettyCtxId = 0; + snapshot->pfeJettyCount = TILEXR_CCU_HCOMM_INNER_FE_JETTY_NUM; + snapshot->startJettyId = TILEXR_CCU_DEFAULT_START_JETTY_ID; +} + +void ApplyLowerLayerPfePartition(uint32_t pfeId, TileXRCcuLowerLayerTransportSnapshot* snapshot) +{ + if (LowerLayerEnvEquals("TILEXR_CCU_DIRECT_LOWER_LAYER_PFE_PARTITION", "hcomm_fe_id")) { + ApplyHcommFeIdPfePartition(pfeId, snapshot); + return; + } + if (LowerLayerEnvEquals("TILEXR_CCU_DIRECT_LOWER_LAYER_PFE_PARTITION", "hcomm_ordered") || + LowerLayerEnvEquals("TILEXR_CCU_DIRECT_LOWER_LAYER_PFE_PARTITION", "hcomm")) { + ApplyHcommOrderedPfePartition(snapshot); + } +} + +int ValidateSpec( + const TileXRCcuLowerLayerPlanSpec& spec, + TileXRCcuLowerLayerInstallPlan* plan, + TileXRCcuLowerLayerPlanBuilderReport* report) +{ + if (!spec.msidToken.valid) { + return Fail(plan, report, "missing lower-layer CCU MSID token"); + } + if (spec.jettys.empty()) { + return Fail(plan, report, "missing lower-layer CCU local jetty contexts"); + } + if (spec.channels.empty()) { + return Fail(plan, report, "missing lower-layer CCU channel contexts"); + } + if (!spec.xnClear.valid || spec.xnClear.count == 0) { + return Fail(plan, report, "missing lower-layer CCU local XN clear range"); + } + if (!spec.ckeClear.valid || spec.ckeClear.count == 0) { + return Fail(plan, report, "missing lower-layer CCU CKE clear range"); + } + if (spec.jettys.size() > std::numeric_limits::max()) { + return Fail(plan, report, "too many lower-layer CCU local jetty contexts"); + } + if (spec.pfe.jettyCount != 0 && spec.pfe.jettyCount > 128U) { + return Fail(plan, report, "lower-layer CCU PFE jetty count is out of range"); + } + if (spec.pfe.jettyCount != 0 && spec.pfe.jettyCount < spec.jettys.size()) { + return Fail(plan, report, "lower-layer CCU PFE jetty window is smaller than local jetty contexts"); + } + if (AddOverflowsU16(spec.pfe.startLocalJettyCtxId, static_cast(spec.jettys.size()))) { + return Fail(plan, report, "lower-layer CCU local jetty context range overflows"); + } + return TILEXR_SUCCESS; +} + +void FillReport(const TileXRCcuLowerLayerInstallPlan& plan, TileXRCcuLowerLayerPlanBuilderReport* report) +{ + if (report == nullptr) { + return; + } + report->msidTokenCount = static_cast(plan.msidTokens.size()); + report->pfeCount = static_cast(plan.pfes.size()); + report->jettyCount = static_cast(plan.jettys.size()); + report->localJettyCtxCount = 0; + for (const auto& jetty : plan.jettys) { + report->localJettyCtxCount += static_cast(jetty.ctxs.size()); + } + report->channelCount = static_cast(plan.channels.size()); + report->ckeClearCount = static_cast(plan.ckeClears.size()); + report->message = "ok"; +} + +void FillTemplateReport( + const TileXRCcuLowerLayerTransportSnapshot& snapshot, + TileXRCcuLowerLayerPlanBuilderReport* report) +{ + if (report == nullptr) { + return; + } + report->msidTokenCount = snapshot.msidToken.valid ? 1U : 0U; + report->pfeCount = snapshot.routes.empty() ? 0U : 1U; + report->jettyCount = static_cast(snapshot.routes.size()); + report->localJettyCtxCount = static_cast(snapshot.routes.size()); + report->channelCount = static_cast(snapshot.routes.size()); + report->ckeClearCount = snapshot.ckeCount == 0 ? 0U : 1U; + report->message = "ok"; +} + +void AppendRemoteNotifyCkeClears( + const TileXRCcuLowerLayerTransportSnapshot& snapshot, + TileXRCcuLowerLayerInstallPlan* plan) +{ + if (plan == nullptr) { + return; + } + std::vector notifyCkes; + notifyCkes.reserve(snapshot.routes.size()); + for (const auto& route : snapshot.routes) { + if (route.remoteNotifyCke == 0 || + RangeContains(snapshot.ckeStartId, snapshot.ckeCount, route.remoteNotifyCke)) { + continue; + } + notifyCkes.push_back(route.remoteNotifyCke); + } + if (notifyCkes.empty()) { + return; + } + + std::sort(notifyCkes.begin(), notifyCkes.end()); + notifyCkes.erase(std::unique(notifyCkes.begin(), notifyCkes.end()), notifyCkes.end()); + + uint32_t rangeStart = notifyCkes.front(); + uint32_t previous = rangeStart; + for (size_t i = 1; i <= notifyCkes.size(); ++i) { + if (i < notifyCkes.size() && notifyCkes[i] == previous + 1U) { + previous = notifyCkes[i]; + continue; + } + plan->ckeClears.push_back({ + snapshot.dieId, + rangeStart, + previous - rangeStart + 1U, + }); + if (i < notifyCkes.size()) { + rangeStart = notifyCkes[i]; + previous = rangeStart; + } + } +} + +void AppendRemoteXnClears( + const TileXRCcuLowerLayerTransportSnapshot& snapshot, + TileXRCcuLowerLayerInstallPlan* plan) +{ + if (plan == nullptr) { + return; + } + std::vector remoteXns; + remoteXns.reserve(snapshot.routes.size()); + for (const auto& route : snapshot.routes) { + if (route.remoteXnId == 0 || + RangeContains(snapshot.xnStartId, snapshot.xnCount, route.remoteXnId)) { + continue; + } + remoteXns.push_back(route.remoteXnId); + } + if (remoteXns.empty()) { + return; + } + + std::sort(remoteXns.begin(), remoteXns.end()); + remoteXns.erase(std::unique(remoteXns.begin(), remoteXns.end()), remoteXns.end()); + + uint32_t rangeStart = remoteXns.front(); + uint32_t previous = rangeStart; + for (size_t i = 1; i <= remoteXns.size(); ++i) { + if (i < remoteXns.size() && remoteXns[i] == previous + 1U) { + previous = remoteXns[i]; + continue; + } + plan->xnClears.push_back({ + snapshot.dieId, + rangeStart, + previous - rangeStart + 1U, + }); + if (i < remoteXns.size()) { + rangeStart = remoteXns[i]; + previous = rangeStart; + } + } +} + +} // namespace + +int TileXRCcuBuildLowerLayerInstallPlan( + const TileXRCcuLowerLayerPlanSpec& spec, + TileXRCcuLowerLayerInstallPlan* plan, + TileXRCcuLowerLayerPlanBuilderReport* report) +{ + ResetReport(report); + if (plan == nullptr) { + return Fail(nullptr, report, "missing output lower-layer CCU install plan"); + } + *plan = TileXRCcuLowerLayerInstallPlan{}; + + if (ValidateSpec(spec, plan, report) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + + TileXRCcuLowerLayerInstallPlan result; + result.msidTokens.push_back({ + spec.msidToken.dieId, + spec.msidToken.msId, + spec.msidToken.tokenId, + spec.msidToken.tokenValue, + }); + + TileXRCcuLowerLayerPayloadReport payloadReport; + TileXRCcuPfeInstall pfe; + pfe.dieId = spec.pfe.dieId; + pfe.pfeOffset = spec.pfe.pfeOffset; + TileXRCcuPfeCtxSpec pfeCtxSpec; + pfeCtxSpec.startJettyId = spec.pfe.startJettyId; + pfeCtxSpec.jettyCount = spec.pfe.jettyCount == 0 ? + CheckedU16(static_cast(spec.jettys.size())) : + spec.pfe.jettyCount; + pfeCtxSpec.startLocalJettyCtxId = spec.pfe.startLocalJettyCtxId; + if (TileXRCcuBuildPfeCtx(pfeCtxSpec, &pfe.ctx, &payloadReport) != TILEXR_SUCCESS) { + return FailPayload(plan, report, payloadReport); + } + result.pfes.push_back(pfe); + + TileXRCcuJettyInstall jettyInstall; + jettyInstall.dieId = spec.pfe.dieId; + jettyInstall.startJettyCtxId = spec.pfe.startLocalJettyCtxId; + for (const auto& jettySpec : spec.jettys) { + if (jettySpec.startJettyCtxId != 0 && jettySpec.startJettyCtxId != jettyInstall.startJettyCtxId + + jettyInstall.ctxs.size()) { + return Fail(plan, report, "lower-layer CCU local jetty contexts must be contiguous"); + } + TileXRCcuLocalJettyCtxData ctx; + TileXRCcuLocalJettyCtxSpec ctxSpec; + ctxSpec.dieId = jettySpec.dieId; + ctxSpec.pfeId = jettySpec.pfeId; + ctxSpec.doorbellVa = jettySpec.doorbellVa; + ctxSpec.doorbellTokenId = jettySpec.doorbellTokenId; + ctxSpec.doorbellTokenValue = jettySpec.doorbellTokenValue; + ctxSpec.sqDepth = jettySpec.sqDepth; + ctxSpec.wqeBasicBlockStartId = jettySpec.wqeBasicBlockStartId; + if (TileXRCcuBuildLocalJettyCtx(ctxSpec, &ctx, &payloadReport) != TILEXR_SUCCESS) { + return FailPayload(plan, report, payloadReport); + } + jettyInstall.ctxs.push_back(ctx); + } + result.jettys.push_back(jettyInstall); + + for (const auto& channelSpec : spec.channels) { + TileXRCcuChannelInstall channel; + channel.dieId = channelSpec.dieId; + channel.channelId = channelSpec.channelId; + TileXRCcuChannelCtxV1Spec ctxSpec; + ctxSpec.remoteEid = channelSpec.remoteEid; + ctxSpec.tpn = channelSpec.tpn; + ctxSpec.sourcePfeId = channelSpec.sourcePfeId; + ctxSpec.startJettyId = channelSpec.startJettyId; + ctxSpec.jettyCount = channelSpec.jettyCount == 0 ? + CheckedU16(static_cast(spec.jettys.size())) : + channelSpec.jettyCount; + ctxSpec.dieId = channelSpec.dieId; + ctxSpec.memoryTokenId = channelSpec.memoryTokenId; + ctxSpec.memoryTokenValue = channelSpec.memoryTokenValue; + ctxSpec.remoteCcuVa = channelSpec.remoteCcuVa; + if (TileXRCcuBuildChannelCtxV1(ctxSpec, &channel.ctx, &payloadReport) != TILEXR_SUCCESS) { + return FailPayload(plan, report, payloadReport); + } + result.channels.push_back(channel); + } + + result.xnClears.push_back({ + spec.xnClear.dieId, + spec.xnClear.startXnId, + spec.xnClear.count, + }); + + result.ckeClears.push_back({ + spec.ckeClear.dieId, + spec.ckeClear.startCkeId, + spec.ckeClear.count, + }); + result.remoteXnBindings = spec.remoteXnBindings; + + *plan = result; + FillReport(*plan, report); + return TILEXR_SUCCESS; +} + +int TileXRCcuBuildLowerLayerTransportTemplate( + const TileXRCcuBasicInfo& basicInfo, + const TileXRCcuResourceAllocation& allocation, + const std::vector& remoteCcuBuffers, + TileXRCcuLowerLayerTransportSnapshot* snapshot, + TileXRCcuLowerLayerPlanBuilderReport* report) +{ + ResetReport(report); + if (snapshot == nullptr) { + return Fail(nullptr, report, "missing output lower-layer CCU transport template"); + } + *snapshot = TileXRCcuLowerLayerTransportSnapshot{}; + + const TileXRCcuRange localWaitCke = EffectiveLocalWaitCkeRange(allocation); + const TileXRCcuRange remoteNotifyCke = EffectiveRemoteNotifyCkeRange(allocation); + if (allocation.channels.num == 0 || allocation.localXn.num == 0 || localWaitCke.num == 0 || + remoteNotifyCke.num == 0 || allocation.remoteXn.num == 0) { + return Fail(nullptr, report, "missing lower-layer CCU allocated resources"); + } + if (remoteCcuBuffers.empty() || remoteCcuBuffers.size() != allocation.remoteXn.num) { + return Fail(nullptr, report, "remote CCU buffer template count does not match remote XN allocation"); + } + if (allocation.channels.num < remoteCcuBuffers.size()) { + return Fail(nullptr, report, "channel allocation count does not match lower-layer route count"); + } + if (remoteCcuBuffers.size() > std::numeric_limits::max()) { + return Fail(nullptr, report, "too many lower-layer CCU remote routes"); + } + + TileXRCcuLowerLayerTransportSnapshot result; + result.msidToken.dieId = basicInfo.dieId; + result.msidToken.msId = basicInfo.msId; + if (basicInfo.msidToken.valid && basicInfo.msidToken.tokenId != 0) { + result.msidToken.tokenId = basicInfo.msidToken.tokenId; + result.msidToken.tokenValue = basicInfo.msidToken.tokenValue; + result.msidToken.valid = true; + } + result.dieId = basicInfo.dieId; + result.pfeId = allocation.channels.startId; + result.pfeOffset = SelectLowerLayerPfeOffset(basicInfo.dieId, result.pfeId); + result.startJettyId = TILEXR_CCU_DEFAULT_START_JETTY_ID; + result.startLocalJettyCtxId = TILEXR_CCU_DEFAULT_START_LOCAL_JETTY_CTX_ID; + ApplyLowerLayerPfePartition(result.pfeId, &result); + result.xnStartId = allocation.localXn.startId; + result.xnCount = allocation.localXn.num; + result.ckeStartId = localWaitCke.startId; + result.ckeCount = localWaitCke.num; + result.routes.reserve(remoteCcuBuffers.size()); + + const uint16_t wqeBasicBlockStride = SelectLowerLayerWqeBasicBlockStride(); + for (uint32_t i = 0; i < remoteCcuBuffers.size(); ++i) { + const auto& remoteCcuBuffer = remoteCcuBuffers[i]; + if (remoteCcuBuffer.remoteCcuVa == 0) { + return Fail(nullptr, report, "missing remote CCU VA for lower-layer route"); + } + TileXRCcuLowerLayerTransportRoute route; + route.channelId = allocation.channels.startId + i; + route.peerRank = remoteCcuBuffer.peerRank == TILEXR_CCU_REMOTE_PEER_RANK_UNKNOWN ? + i : + remoteCcuBuffer.peerRank; + route.remoteXnId = remoteCcuBuffer.remoteXnId == 0 ? + static_cast(allocation.remoteXn.startId + i) : + remoteCcuBuffer.remoteXnId; + route.remoteNotifyCke = remoteCcuBuffer.remoteNotifyCke == 0 ? + static_cast(remoteNotifyCke.startId + i) : + remoteCcuBuffer.remoteNotifyCke; + if (i > std::numeric_limits::max() / wqeBasicBlockStride) { + return Fail(nullptr, report, "lower-layer CCU WQE basic block start overflows"); + } + route.wqeBasicBlockStartId = static_cast(i * wqeBasicBlockStride); + route.remoteCcuVa = remoteCcuBuffer.remoteCcuVa; + route.memoryTokenId = remoteCcuBuffer.memoryTokenId; + route.memoryTokenValue = remoteCcuBuffer.memoryTokenValue; + route.channelResourceOwnerVerified = remoteCcuBuffer.channelResourceOwnerVerified; + route.transportResourceExchangeVerified = remoteCcuBuffer.transportResourceExchangeVerified; + if (remoteCcuBuffer.endpointRouteVerified && + !IsEmptyEndpointEid(remoteCcuBuffer.remoteEid) && + remoteCcuBuffer.doorbellVa != 0 && + remoteCcuBuffer.doorbellTokenId != 0 && + remoteCcuBuffer.sqDepth != 0) { + route.remoteEid = remoteCcuBuffer.remoteEid; + route.tpn = remoteCcuBuffer.tpn; + route.doorbellVa = remoteCcuBuffer.doorbellVa; + route.doorbellTokenId = remoteCcuBuffer.doorbellTokenId; + route.doorbellTokenValue = remoteCcuBuffer.doorbellTokenValue; + route.sqDepth = remoteCcuBuffer.sqDepth; + route.localDoorbellVa = remoteCcuBuffer.localDoorbellVa; + route.localDoorbellTokenId = remoteCcuBuffer.localDoorbellTokenId; + route.localDoorbellTokenValue = remoteCcuBuffer.localDoorbellTokenValue; + route.localSqDepth = remoteCcuBuffer.localSqDepth; + route.endpointRouteVerified = true; + } + result.routes.push_back(route); + } + + *snapshot = result; + FillTemplateReport(*snapshot, report); + return TILEXR_SUCCESS; +} + +int TileXRCcuOverlayVerifiedEndpointRoutes( + const std::vector& verifiedRoutes, + TileXRCcuLowerLayerTransportSnapshot* snapshot, + TileXRCcuLowerLayerPlanBuilderReport* report) +{ + ResetReport(report); + if (snapshot == nullptr) { + return Fail(nullptr, report, "missing lower-layer CCU transport snapshot for endpoint route overlay"); + } + if (verifiedRoutes.empty()) { + FillTemplateReport(*snapshot, report); + return TILEXR_SUCCESS; + } + + for (const auto& verified : verifiedRoutes) { + if (!HasCompleteVerifiedEndpointRoute(verified)) { + return Fail(nullptr, report, "verified endpoint route is incomplete"); + } + auto routeIt = std::find_if( + snapshot->routes.begin(), + snapshot->routes.end(), + [&verified](const TileXRCcuLowerLayerTransportRoute& route) { + return route.channelId == verified.channelId; + }); + if (routeIt == snapshot->routes.end()) { + return Fail(nullptr, report, "verified endpoint route does not match an allocated channel"); + } + + routeIt->remoteEid = verified.remoteEid; + routeIt->tpn = verified.tpn; + routeIt->doorbellVa = verified.doorbellVa; + routeIt->doorbellTokenId = verified.doorbellTokenId; + routeIt->doorbellTokenValue = verified.doorbellTokenValue; + routeIt->sqDepth = verified.sqDepth; + routeIt->localDoorbellVa = verified.localDoorbellVa; + routeIt->localDoorbellTokenId = verified.localDoorbellTokenId; + routeIt->localDoorbellTokenValue = verified.localDoorbellTokenValue; + routeIt->localSqDepth = verified.localSqDepth; + routeIt->endpointRouteVerified = true; + routeIt->channelResourceOwnerVerified = verified.channelResourceOwnerVerified; + routeIt->transportResourceExchangeVerified = verified.transportResourceExchangeVerified; + } + + FillTemplateReport(*snapshot, report); + return TILEXR_SUCCESS; +} + +int TileXRCcuBuildLowerLayerInstallPlanFromTransportSnapshot( + const TileXRCcuLowerLayerTransportSnapshot& snapshot, + TileXRCcuLowerLayerInstallPlan* plan, + TileXRCcuLowerLayerPlanBuilderReport* report) +{ + ResetReport(report); + if (plan == nullptr) { + return Fail(nullptr, report, "missing output lower-layer CCU install plan"); + } + *plan = TileXRCcuLowerLayerInstallPlan{}; + + if (snapshot.routes.empty()) { + return Fail(plan, report, "missing lower-layer CCU transport routes"); + } + if (snapshot.routes.size() > std::numeric_limits::max()) { + return Fail(plan, report, "too many lower-layer CCU transport routes"); + } + + TileXRCcuLowerLayerPlanSpec spec; + spec.msidToken = snapshot.msidToken; + spec.pfe.dieId = snapshot.dieId; + spec.pfe.pfeOffset = snapshot.pfeOffset; + spec.pfe.startJettyId = snapshot.startJettyId; + spec.pfe.jettyCount = snapshot.pfeJettyCount; + spec.pfe.startLocalJettyCtxId = snapshot.startLocalJettyCtxId; + spec.xnClear.dieId = snapshot.dieId; + spec.xnClear.startXnId = snapshot.xnStartId; + spec.xnClear.count = snapshot.xnCount; + spec.xnClear.valid = snapshot.xnCount != 0; + spec.ckeClear.dieId = snapshot.dieId; + spec.ckeClear.startCkeId = snapshot.ckeStartId; + spec.ckeClear.count = snapshot.ckeCount; + spec.ckeClear.valid = snapshot.ckeCount != 0; + + uint32_t routeIndex = 0; + for (const auto& route : snapshot.routes) { + TileXRCcuLowerLayerJettySpec jetty; + jetty.dieId = snapshot.dieId; + jetty.pfeId = snapshot.pfeId; + jetty.startJettyCtxId = static_cast(snapshot.startLocalJettyCtxId + routeIndex); + jetty.doorbellVa = route.localDoorbellVa == 0 ? route.doorbellVa : route.localDoorbellVa; + jetty.doorbellTokenId = route.localDoorbellTokenId == 0 ? + route.doorbellTokenId : + route.localDoorbellTokenId; + jetty.doorbellTokenValue = route.localDoorbellVa == 0 ? + route.doorbellTokenValue : + route.localDoorbellTokenValue; + jetty.sqDepth = route.localSqDepth == 0 ? route.sqDepth : route.localSqDepth; + jetty.wqeBasicBlockStartId = route.wqeBasicBlockStartId; + spec.jettys.push_back(jetty); + + TileXRCcuLowerLayerChannelSpec channel; + channel.dieId = snapshot.dieId; + channel.channelId = route.channelId; + channel.remoteEid = route.remoteEid; + channel.tpn = route.tpn; + channel.sourcePfeId = snapshot.pfeId; + channel.startJettyId = route.startJettyId == 0 ? + static_cast(snapshot.startJettyId + routeIndex) : + route.startJettyId; + channel.jettyCount = 1; + channel.memoryTokenId = route.memoryTokenId; + channel.memoryTokenValue = route.memoryTokenValue; + channel.remoteCcuVa = route.remoteCcuVa; + const auto channelIt = std::find_if( + spec.channels.begin(), + spec.channels.end(), + [&channel](const TileXRCcuLowerLayerChannelSpec& existing) { + return existing.dieId == channel.dieId && existing.channelId == channel.channelId; + }); + if (channelIt == spec.channels.end()) { + spec.channels.push_back(channel); + } + + TileXRCcuRemoteXnBindingProof remoteXn; + remoteXn.dieId = snapshot.dieId; + remoteXn.channelId = static_cast(route.channelId); + remoteXn.localXn = static_cast(snapshot.xnStartId + routeIndex); + remoteXn.remoteXn = route.remoteXnId; + remoteXn.notifyCke = route.remoteNotifyCke == 0 ? + static_cast(snapshot.ckeStartId + routeIndex) : + route.remoteNotifyCke; + remoteXn.peerRank = route.peerRank; + remoteXn.peerExchangeObserved = route.remoteXnId != 0; + remoteXn.localWaitCke = static_cast(snapshot.ckeStartId + routeIndex); + remoteXn.endpointRouteVerified = route.endpointRouteVerified; + remoteXn.channelResourceOwnerVerified = route.channelResourceOwnerVerified; + remoteXn.transportResourceExchangeVerified = route.transportResourceExchangeVerified; + spec.remoteXnBindings.push_back(remoteXn); + ++routeIndex; + } + + const int ret = TileXRCcuBuildLowerLayerInstallPlan(spec, plan, report); + if (ret != TILEXR_SUCCESS) { + return ret; + } + AppendRemoteXnClears(snapshot, plan); + AppendRemoteNotifyCkeClears(snapshot, plan); + FillReport(*plan, report); + return TILEXR_SUCCESS; +} + +} // namespace TileXR diff --git a/src/comm/ccu/tilexr_ccu_lower_layer_plan_builder.h b/src/comm/ccu/tilexr_ccu_lower_layer_plan_builder.h new file mode 100644 index 00000000..26ff8c7f --- /dev/null +++ b/src/comm/ccu/tilexr_ccu_lower_layer_plan_builder.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2026 TileXR Project + * Licensed under the Apache License, Version 2.0 + */ + +#ifndef TILEXR_CCU_LOWER_LAYER_PLAN_BUILDER_H +#define TILEXR_CCU_LOWER_LAYER_PLAN_BUILDER_H + +#include "ccu/tilexr_ccu_install_provider.h" +#include "ccu/tilexr_ccu_lower_layer_payloads.h" + +#include +#include +#include +#include + +namespace TileXR { + +constexpr uint32_t TILEXR_CCU_REMOTE_PEER_RANK_UNKNOWN = 0xffffffffU; + +struct TileXRCcuLowerLayerMsidTokenSpec { + uint8_t dieId = 0; + uint32_t msId = 0; + uint32_t tokenId = 0; + uint32_t tokenValue = 0; + bool valid = false; +}; + +struct TileXRCcuLowerLayerPfeSpec { + uint8_t dieId = 0; + uint32_t pfeOffset = 0; + uint16_t startJettyId = 0; + uint16_t jettyCount = 0; + uint16_t startLocalJettyCtxId = 0; +}; + +struct TileXRCcuLowerLayerJettySpec { + uint8_t dieId = 0; + uint32_t pfeId = 0; + uint16_t startJettyCtxId = 0; + uint64_t doorbellVa = 0; + uint32_t doorbellTokenId = 0; + uint32_t doorbellTokenValue = 0; + uint32_t sqDepth = 0; + uint16_t wqeBasicBlockStartId = 0; +}; + +struct TileXRCcuLowerLayerChannelSpec { + uint8_t dieId = 0; + uint32_t channelId = 0; + std::array remoteEid {}; + uint32_t tpn = 0; + uint32_t sourcePfeId = 0; + uint16_t startJettyId = 0; + uint16_t jettyCount = 0; + uint32_t memoryTokenId = 0; + uint32_t memoryTokenValue = 0; + uint64_t remoteCcuVa = 0; +}; + +struct TileXRCcuLowerLayerCkeClearSpec { + uint8_t dieId = 0; + uint32_t startCkeId = 0; + uint32_t count = 0; + bool valid = false; +}; + +struct TileXRCcuLowerLayerXnClearSpec { + uint8_t dieId = 0; + uint32_t startXnId = 0; + uint32_t count = 0; + bool valid = false; +}; + +struct TileXRCcuLowerLayerPlanSpec { + TileXRCcuLowerLayerMsidTokenSpec msidToken; + TileXRCcuLowerLayerPfeSpec pfe; + std::vector jettys; + std::vector channels; + TileXRCcuLowerLayerXnClearSpec xnClear; + TileXRCcuLowerLayerCkeClearSpec ckeClear; + std::vector remoteXnBindings; +}; + +struct TileXRCcuLowerLayerPlanBuilderReport { + uint32_t msidTokenCount = 0; + uint32_t pfeCount = 0; + uint32_t jettyCount = 0; + uint32_t localJettyCtxCount = 0; + uint32_t channelCount = 0; + uint32_t ckeClearCount = 0; + std::string message; +}; + +struct TileXRCcuRemoteCcuBufferInfo { + uint64_t remoteCcuVa = 0; + uint32_t peerRank = TILEXR_CCU_REMOTE_PEER_RANK_UNKNOWN; + uint32_t memoryTokenId = 0; + uint32_t rawMemoryTokenId = 0; + uint32_t memoryTokenValue = 0; + uint16_t remoteXnId = 0; + uint16_t remoteNotifyCke = 0; + std::array remoteEid {}; + uint32_t tpn = 0; + uint64_t doorbellVa = 0; + uint32_t doorbellTokenId = 0; + uint32_t doorbellTokenValue = 0; + uint32_t sqDepth = 0; + uint64_t localDoorbellVa = 0; + uint32_t localDoorbellTokenId = 0; + uint32_t localDoorbellTokenValue = 0; + uint32_t localSqDepth = 0; + bool endpointRouteVerified = false; + bool channelResourceOwnerVerified = false; + bool transportResourceExchangeVerified = false; +}; + +struct TileXRCcuLowerLayerTransportRoute { + uint32_t channelId = 0; + uint32_t peerRank = 0; + uint16_t remoteXnId = 0; + uint16_t remoteNotifyCke = 0; + std::array remoteEid {}; + uint32_t tpn = 0; + uint64_t doorbellVa = 0; + uint32_t doorbellTokenId = 0; + uint32_t doorbellTokenValue = 0; + uint32_t sqDepth = 0; + uint64_t localDoorbellVa = 0; + uint32_t localDoorbellTokenId = 0; + uint32_t localDoorbellTokenValue = 0; + uint32_t localSqDepth = 0; + uint16_t startJettyId = 0; + uint16_t wqeBasicBlockStartId = 0; + uint32_t memoryTokenId = 0; + uint32_t memoryTokenValue = 0; + uint64_t remoteCcuVa = 0; + bool endpointRouteVerified = false; + bool channelResourceOwnerVerified = false; + bool transportResourceExchangeVerified = false; +}; + +struct TileXRCcuLowerLayerTransportSnapshot { + TileXRCcuLowerLayerMsidTokenSpec msidToken; + uint8_t dieId = 0; + uint32_t pfeOffset = 0; + uint32_t pfeId = 0; + uint16_t startJettyId = 0; + uint16_t pfeJettyCount = 0; + uint16_t startLocalJettyCtxId = 0; + uint32_t xnStartId = 0; + uint32_t xnCount = 0; + uint32_t ckeStartId = 0; + uint32_t ckeCount = 0; + std::vector routes; +}; + +int TileXRCcuBuildLowerLayerInstallPlan( + const TileXRCcuLowerLayerPlanSpec& spec, + TileXRCcuLowerLayerInstallPlan* plan, + TileXRCcuLowerLayerPlanBuilderReport* report); + +int TileXRCcuBuildLowerLayerTransportTemplate( + const TileXRCcuBasicInfo& basicInfo, + const TileXRCcuResourceAllocation& allocation, + const std::vector& remoteCcuBuffers, + TileXRCcuLowerLayerTransportSnapshot* snapshot, + TileXRCcuLowerLayerPlanBuilderReport* report); + +int TileXRCcuOverlayVerifiedEndpointRoutes( + const std::vector& verifiedRoutes, + TileXRCcuLowerLayerTransportSnapshot* snapshot, + TileXRCcuLowerLayerPlanBuilderReport* report); + +int TileXRCcuBuildLowerLayerInstallPlanFromTransportSnapshot( + const TileXRCcuLowerLayerTransportSnapshot& snapshot, + TileXRCcuLowerLayerInstallPlan* plan, + TileXRCcuLowerLayerPlanBuilderReport* report); + +} // namespace TileXR + +#endif // TILEXR_CCU_LOWER_LAYER_PLAN_BUILDER_H diff --git a/src/comm/ccu/tilexr_ccu_provider.cpp b/src/comm/ccu/tilexr_ccu_provider.cpp new file mode 100644 index 00000000..d42265b6 --- /dev/null +++ b/src/comm/ccu/tilexr_ccu_provider.cpp @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2026 TileXR Project + * Licensed under the Apache License, Version 2.0 + */ + +#include "ccu/tilexr_ccu_provider.h" + +namespace TileXR { +namespace { + +void ResetReport(TileXRCcuProviderReport* report) +{ + if (report == nullptr) { + return; + } + report->taskCount = 0; + report->repositoryCount = 0; + report->installedInstructionCount = 0; + report->evidenceBitCount = 0; + report->publicVerifiedEvidenceCount = 0; + report->legacyEvidenceCount = 0; + report->publicCandidateEvidenceCount = 0; + report->privateObservedEvidenceCount = 0; + report->missingEvidenceCount = 0; + report->submitReady = false; + report->message.clear(); +} + +int Fail(TileXRCcuProviderReport* report, const std::string& message) +{ + if (report != nullptr) { + report->message = message; + } + return TILEXR_ERROR_PARA_CHECK_FAIL; +} + +const char* EvidenceKindName(TileXRCcuEvidenceKind kind) +{ + switch (kind) { + case TileXRCcuEvidenceKind::LegacyBoolean: + return "legacy"; + case TileXRCcuEvidenceKind::PublicVerified: + return "public verified"; + case TileXRCcuEvidenceKind::PublicCandidate: + return "public candidate"; + case TileXRCcuEvidenceKind::PrivateObserved: + return "private observed"; + case TileXRCcuEvidenceKind::Missing: + return "missing"; + default: + return "unknown"; + } +} + +const char* EvidenceSurfaceName(TileXRCcuEvidenceSurface surface) +{ + switch (surface) { + case TileXRCcuEvidenceSurface::Unspecified: + return "unspecified surface"; + case TileXRCcuEvidenceSurface::PublicInstallProvider: + return "public install provider"; + case TileXRCcuEvidenceSurface::LowerLayerResourceHelper: + return "lower-layer resource helper"; + case TileXRCcuEvidenceSurface::PrivateProducerObservation: + return "private producer observation"; + default: + return "unknown surface"; + } +} + +std::string EvidenceMessage( + const std::string& label, + const TileXRCcuEvidenceSource& source, + const std::string& suffix) +{ + std::string message = label + " " + suffix; + if (source.kind != TileXRCcuEvidenceKind::LegacyBoolean) { + message += " (" + std::string(EvidenceKindName(source.kind)); + message += ", " + std::string(EvidenceSurfaceName(source.surface)); + if (!source.source.empty()) { + message += ": " + source.source; + } + if (!source.detail.empty()) { + message += "; " + source.detail; + } + message += ")"; + } + return message; +} + +int ValidateEvidenceSource( + const std::string& label, + bool installed, + const TileXRCcuEvidenceSource& source, + TileXRCcuProviderReport* report) +{ + if (!installed || source.kind == TileXRCcuEvidenceKind::Missing) { + return Fail(report, EvidenceMessage(label, source, "hardware install evidence is missing")); + } + if (source.kind == TileXRCcuEvidenceKind::LegacyBoolean || + source.kind == TileXRCcuEvidenceKind::PublicVerified) { + return TILEXR_SUCCESS; + } + if (source.kind == TileXRCcuEvidenceKind::PublicCandidate) { + return Fail(report, EvidenceMessage(label, source, "evidence is only a public candidate")); + } + if (source.kind == TileXRCcuEvidenceKind::PrivateObserved) { + return Fail(report, EvidenceMessage(label, source, "evidence is private observed")); + } + return Fail(report, EvidenceMessage(label, source, "evidence kind is not accepted")); +} + +void CountEvidenceKind(bool installed, const TileXRCcuEvidenceSource& source, TileXRCcuProviderReport* report) +{ + if (report == nullptr) { + return; + } + ++report->evidenceBitCount; + if (!installed || source.kind == TileXRCcuEvidenceKind::Missing) { + ++report->missingEvidenceCount; + return; + } + switch (source.kind) { + case TileXRCcuEvidenceKind::LegacyBoolean: + ++report->legacyEvidenceCount; + break; + case TileXRCcuEvidenceKind::PublicVerified: + ++report->publicVerifiedEvidenceCount; + break; + case TileXRCcuEvidenceKind::PublicCandidate: + ++report->publicCandidateEvidenceCount; + break; + case TileXRCcuEvidenceKind::PrivateObserved: + ++report->privateObservedEvidenceCount; + break; + case TileXRCcuEvidenceKind::Missing: + ++report->missingEvidenceCount; + break; + default: + ++report->missingEvidenceCount; + break; + } +} + +void CountInstallEvidence(const TileXRCcuHardwareInstallEvidence& evidence, TileXRCcuProviderReport* report) +{ + CountEvidenceKind(evidence.missionInstalled, evidence.missionSource, report); + CountEvidenceKind(evidence.repositoryInstalled, evidence.repositorySource, report); + CountEvidenceKind(evidence.localXnInstalled, evidence.localXnSource, report); + CountEvidenceKind(evidence.remoteXnBound, evidence.remoteXnSource, report); + CountEvidenceKind(evidence.notifyCkeInstalled, evidence.notifyCkeSource, report); + CountEvidenceKind(evidence.channelBindingsInstalled, evidence.channelBindingSource, report); +} + +void FillReadyReport(const TileXRCcuLaunchPackage& package, TileXRCcuProviderReport* report) +{ + if (report == nullptr) { + return; + } + report->taskCount = static_cast(package.tasks.size()); + report->repositoryCount = package.repository.repositoryCount; + report->installedInstructionCount = + static_cast(package.repository.sqeLoadCount + package.repository.syncCount); + report->submitReady = true; + report->message = "ok"; +} + +int ValidatePackageShape(const TileXRCcuLaunchPackage& package, TileXRCcuProviderReport* report) +{ + if (package.tasks.empty()) { + return Fail(report, "missing CCU launch tasks in provider package"); + } + if (package.repository.instructions.empty()) { + return Fail(report, "missing CCU repository image in provider package"); + } + if (package.program.sync.empty()) { + return Fail(report, "missing generated CCU microcode in provider package"); + } + return TILEXR_SUCCESS; +} + +bool RequiresRemoteXnBindingEvidence(TileXRCcuBarrierMode mode) +{ + return mode == TileXRCcuBarrierMode::SyncXn || + mode == TileXRCcuBarrierMode::SyncXnPostOnly || + mode == TileXRCcuBarrierMode::SyncXnLoadPostOnly; +} + +bool RequiresChannelBindingEvidence(TileXRCcuBarrierMode mode) +{ + return mode != TileXRCcuBarrierMode::LocalCke && + mode != TileXRCcuBarrierMode::LocalCkePostOnly; +} + +int ValidateInstallEvidence( + const TileXRCcuLaunchPackage& package, + const TileXRCcuHardwareInstallEvidence& evidence, + TileXRCcuProviderReport* report) +{ + CountInstallEvidence(evidence, report); + if (ValidateEvidenceSource("mission/key", evidence.missionInstalled, evidence.missionSource, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateEvidenceSource("repository", evidence.repositoryInstalled, evidence.repositorySource, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateEvidenceSource("local XN", evidence.localXnInstalled, evidence.localXnSource, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (RequiresRemoteXnBindingEvidence(package.plan.barrierMode) && + ValidateEvidenceSource("remote XN binding", evidence.remoteXnBound, evidence.remoteXnSource, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateEvidenceSource("notify CKE install", evidence.notifyCkeInstalled, evidence.notifyCkeSource, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (RequiresChannelBindingEvidence(package.plan.barrierMode) && + ValidateEvidenceSource( + "channel binding", evidence.channelBindingsInstalled, evidence.channelBindingSource, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + return TILEXR_SUCCESS; +} + +int ValidateSubmitEvidenceSource( + const std::string& label, + const TileXRCcuLaunchPackage& package, + bool installed, + const TileXRCcuEvidenceSource& source, + bool endpointRouteRequired, + TileXRCcuProviderReport* report) +{ + if (!installed || source.kind != TileXRCcuEvidenceKind::PublicVerified) { + return Fail(report, EvidenceMessage(label, source, "submit requires public verified evidence")); + } + if (source.source.empty() || source.detail.empty()) { + return Fail(report, EvidenceMessage(label, source, "public verified evidence source/detail required")); + } + if (source.surface != TileXRCcuEvidenceSurface::PublicInstallProvider) { + return Fail(report, EvidenceMessage( + label, source, "submit requires public install provider evidence")); + } + const uint64_t packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + if (package.installScope.packageFingerprint == 0 || + package.installScope.packageFingerprint != packageFingerprint || + package.installScope.provider.empty()) { + return Fail(report, EvidenceMessage(label, source, "launch install scope is not bound")); + } + if (source.packageFingerprint == 0 || source.packageFingerprint != packageFingerprint) { + return Fail(report, EvidenceMessage(label, source, "package fingerprint mismatch")); + } + if (source.deviceId != package.installScope.deviceId) { + return Fail(report, EvidenceMessage(label, source, "device scope mismatch")); + } + if (source.rank != package.installScope.rank) { + return Fail(report, EvidenceMessage(label, source, "rank scope mismatch")); + } + if (source.provider.empty() || source.provider != package.installScope.provider) { + return Fail(report, EvidenceMessage(label, source, "provider scope mismatch")); + } + if (source.installAttemptReceiptId == 0) { + return Fail(report, EvidenceMessage(label, source, "install attempt receipt is missing")); + } + if (endpointRouteRequired && !source.endpointRouteVerified) { + return Fail(report, EvidenceMessage(label, source, "submit requires verified endpoint route evidence")); + } + return TILEXR_SUCCESS; +} + +int ValidateSameInstallAttemptReceipt( + const TileXRCcuEvidenceSource& expected, + const std::string& label, + const TileXRCcuEvidenceSource& source, + TileXRCcuProviderReport* report) +{ + if (source.installAttemptReceiptId != expected.installAttemptReceiptId) { + return Fail(report, EvidenceMessage(label, source, "install attempt receipt mismatch")); + } + return TILEXR_SUCCESS; +} + +int ValidateSubmitEvidence( + const TileXRCcuLaunchPackage& package, + const TileXRCcuHardwareInstallEvidence& evidence, + TileXRCcuProviderReport* report) +{ + if (ValidateSubmitEvidenceSource( + "mission/key", package, evidence.missionInstalled, evidence.missionSource, false, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateSubmitEvidenceSource( + "repository", package, evidence.repositoryInstalled, evidence.repositorySource, false, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateSubmitEvidenceSource( + "local XN", package, evidence.localXnInstalled, evidence.localXnSource, false, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (RequiresRemoteXnBindingEvidence(package.plan.barrierMode) && + ValidateSubmitEvidenceSource( + "remote XN binding", package, evidence.remoteXnBound, evidence.remoteXnSource, true, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateSubmitEvidenceSource( + "notify CKE install", package, evidence.notifyCkeInstalled, evidence.notifyCkeSource, false, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (RequiresChannelBindingEvidence(package.plan.barrierMode) && + ValidateSubmitEvidenceSource( + "channel binding", package, evidence.channelBindingsInstalled, evidence.channelBindingSource, true, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + const TileXRCcuEvidenceSource& expected = evidence.missionSource; + if (ValidateSameInstallAttemptReceipt(expected, "repository", evidence.repositorySource, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateSameInstallAttemptReceipt(expected, "local XN", evidence.localXnSource, report) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (RequiresRemoteXnBindingEvidence(package.plan.barrierMode) && + ValidateSameInstallAttemptReceipt(expected, "remote XN binding", evidence.remoteXnSource, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateSameInstallAttemptReceipt(expected, "notify CKE install", evidence.notifyCkeSource, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (RequiresChannelBindingEvidence(package.plan.barrierMode) && + ValidateSameInstallAttemptReceipt(expected, "channel binding", evidence.channelBindingSource, report) != + TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + return TILEXR_SUCCESS; +} + +} // namespace + +int TileXRCcuValidateHardwareInstall( + const TileXRCcuLaunchPackage& package, + const TileXRCcuHardwareInstallEvidence& evidence, + TileXRCcuProviderReport* report) +{ + ResetReport(report); + if (ValidatePackageShape(package, report) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateInstallEvidence(package, evidence, report) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (report != nullptr) { + report->taskCount = static_cast(package.tasks.size()); + report->repositoryCount = package.repository.repositoryCount; + report->installedInstructionCount = + static_cast(package.repository.sqeLoadCount + package.repository.syncCount); + report->submitReady = false; + report->message = "hardware install evidence is validate-compatible"; + } + return TILEXR_SUCCESS; +} + +int TileXRCcuPrepareSubmitTasks( + const TileXRCcuLaunchPackage& package, + const TileXRCcuHardwareInstallEvidence& evidence, + std::vector* submitTasks, + TileXRCcuProviderReport* report) +{ + ResetReport(report); + if (submitTasks == nullptr) { + return Fail(report, "missing output submit task vector"); + } + submitTasks->clear(); + + if (TileXRCcuValidateHardwareInstall(package, evidence, report) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (report != nullptr) { + report->submitReady = false; + } + if (ValidateSubmitEvidence(package, evidence, report) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + *submitTasks = package.tasks; + FillReadyReport(package, report); + return TILEXR_SUCCESS; +} + +} // namespace TileXR diff --git a/src/comm/ccu/tilexr_ccu_provider.h b/src/comm/ccu/tilexr_ccu_provider.h new file mode 100644 index 00000000..2a96436f --- /dev/null +++ b/src/comm/ccu/tilexr_ccu_provider.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2026 TileXR Project + * Licensed under the Apache License, Version 2.0 + */ + +#ifndef TILEXR_CCU_PROVIDER_H +#define TILEXR_CCU_PROVIDER_H + +#include "ccu/tilexr_ccu_launch_package.h" + +#include +#include +#include + +namespace TileXR { + +enum class TileXRCcuEvidenceKind : uint8_t { + LegacyBoolean = 0, + PublicVerified = 1, + PublicCandidate = 2, + PrivateObserved = 3, + Missing = 4, +}; + +enum class TileXRCcuEvidenceSurface : uint8_t { + Unspecified = 0, + PublicInstallProvider = 1, + LowerLayerResourceHelper = 2, + PrivateProducerObservation = 3, +}; + +struct TileXRCcuEvidenceSource { + TileXRCcuEvidenceKind kind = TileXRCcuEvidenceKind::LegacyBoolean; + TileXRCcuEvidenceSurface surface = TileXRCcuEvidenceSurface::Unspecified; + uint64_t packageFingerprint = 0; + uint32_t deviceId = 0; + uint32_t rank = 0; + std::string provider; + uint64_t installAttemptReceiptId = 0; + bool endpointRouteVerified = false; + std::string source; + std::string detail; +}; + +struct TileXRCcuHardwareInstallEvidence { + bool missionInstalled = false; + bool repositoryInstalled = false; + bool localXnInstalled = false; + bool remoteXnBound = false; + bool notifyCkeInstalled = false; + bool channelBindingsInstalled = false; + TileXRCcuEvidenceSource missionSource; + TileXRCcuEvidenceSource repositorySource; + TileXRCcuEvidenceSource localXnSource; + TileXRCcuEvidenceSource remoteXnSource; + TileXRCcuEvidenceSource notifyCkeSource; + TileXRCcuEvidenceSource channelBindingSource; +}; + +struct TileXRCcuProviderReport { + uint32_t taskCount = 0; + uint32_t repositoryCount = 0; + uint32_t installedInstructionCount = 0; + uint32_t evidenceBitCount = 0; + uint32_t publicVerifiedEvidenceCount = 0; + uint32_t legacyEvidenceCount = 0; + uint32_t publicCandidateEvidenceCount = 0; + uint32_t privateObservedEvidenceCount = 0; + uint32_t missingEvidenceCount = 0; + bool submitReady = false; + std::string message; +}; + +int TileXRCcuValidateHardwareInstall( + const TileXRCcuLaunchPackage& package, + const TileXRCcuHardwareInstallEvidence& evidence, + TileXRCcuProviderReport* report); + +int TileXRCcuPrepareSubmitTasks( + const TileXRCcuLaunchPackage& package, + const TileXRCcuHardwareInstallEvidence& evidence, + std::vector* submitTasks, + TileXRCcuProviderReport* report); + +} // namespace TileXR + +#endif // TILEXR_CCU_PROVIDER_H diff --git a/src/comm/ccu/tilexr_ccu_repository.cpp b/src/comm/ccu/tilexr_ccu_repository.cpp new file mode 100644 index 00000000..4b9b6bcf --- /dev/null +++ b/src/comm/ccu/tilexr_ccu_repository.cpp @@ -0,0 +1,894 @@ +/* + * Copyright (c) 2026 TileXR Project + * Licensed under the Apache License, Version 2.0 + */ + +#include "ccu/tilexr_ccu_repository.h" + +#if defined(__has_include) +#if __has_include() +#define TILEXR_CCU_HAVE_ACL_RT_HEADER 1 +#include +#else +#define TILEXR_CCU_HAVE_ACL_RT_HEADER 0 +#endif +#else +#define TILEXR_CCU_HAVE_ACL_RT_HEADER 1 +#include +#endif + +#if defined(__has_include) +#if __has_include() +#define TILEXR_CCU_HAVE_RUNTIME_MEM_HEADER 1 +#include +#else +#define TILEXR_CCU_HAVE_RUNTIME_MEM_HEADER 0 +#endif +#else +#define TILEXR_CCU_HAVE_RUNTIME_MEM_HEADER 1 +#include +#endif + +#include +#include +#include +#include +#include + +namespace TileXR { +namespace { + +constexpr uint16_t TILEXR_CCU_ACL_MODULE3_ID = 3U; +constexpr uint16_t TILEXR_CCU_RT_HBM_MODULE_ID = 0U; + +struct TileXRCcuUploadReadbackDiagnostic { + bool attempted = false; + bool ok = false; + int ret = 0; + uint64_t bytes = 0; + uint64_t fnv1a64 = 0; + uint32_t mismatchCount = 0; + std::string firstInstructionWords; + std::string lastInstructionWords; +}; + +void ResetReport(TileXRCcuRepositoryReport* report) +{ + if (report == nullptr) { + return; + } + report->repositoryCount = 0; + report->installedInstructionCount = 0; + report->sqeLoadOffset = 0; + report->syncOffset = 0; + report->repositoryUploaded = false; + report->repositoryInstalled = false; + report->message.clear(); +} + +int Fail( + TileXRCcuRepositoryReport* report, + const std::string& message, + int code = TILEXR_ERROR_PARA_CHECK_FAIL) +{ + if (report != nullptr) { + report->message = message; + } + return code; +} + +bool ContainsWindow(uint16_t outerStart, uint16_t outerCount, uint16_t innerStart, uint16_t innerCount) +{ + if (outerCount == 0 || innerCount == 0) { + return false; + } + const uint32_t outerBegin = outerStart; + const uint32_t outerEnd = outerBegin + outerCount; + const uint32_t innerBegin = innerStart; + const uint32_t innerEnd = innerBegin + innerCount; + return innerBegin >= outerBegin && innerEnd <= outerEnd; +} + +uint16_t OffsetFrom(uint16_t base, uint16_t id) +{ + return static_cast(static_cast(id) - base); +} + +int ValidateProgramShape( + const TileXRCcuProducerPlan& plan, + const TileXRCcuProgram& program, + TileXRCcuRepositoryReport* report) +{ + if (program.sync.empty()) { + return Fail(report, "missing sync microcode for repository image"); + } + if (program.sqeLoad.empty()) { + if (plan.taskWindows.size() != 1) { + return Fail(report, "pure sync repository image requires exactly one task window"); + } + const auto& syncTask = plan.taskWindows[0]; + if (syncTask.instCnt < program.sync.size()) { + return Fail(report, "sync task window is too small for generated sync microcode"); + } + return TILEXR_SUCCESS; + } + if (plan.taskWindows.size() < 2) { + return Fail(report, "repository image requires SQE and sync task windows"); + } + + const auto& sqeTask = plan.taskWindows[0]; + const auto& syncTask = plan.taskWindows[1]; + if (sqeTask.instCnt != program.sqeLoad.size()) { + return Fail(report, "SQE task window does not match generated SQE microcode"); + } + if (syncTask.instStartId != static_cast(sqeTask.instStartId) + sqeTask.instCnt) { + return Fail(report, "sync task window must start immediately after SQE microcode"); + } + if (syncTask.instCnt < program.sync.size()) { + return Fail(report, "sync task window is too small for generated sync microcode"); + } + return TILEXR_SUCCESS; +} + +int ValidateRepositoryWindow(const TileXRCcuProducerPlan& plan, TileXRCcuRepositoryReport* report) +{ + const auto& window = plan.instructionWindow; + if (!ContainsWindow( + window.repositoryStartId, window.repositoryCount, window.missionStartId, window.missionCount)) { + return Fail(report, "mission instruction window is outside the repository image"); + } + for (const auto& task : plan.taskWindows) { + if (task.dieId != window.dieId) { + return Fail(report, "task die does not match repository image die"); + } + if (!ContainsWindow(window.missionStartId, window.missionCount, task.instStartId, task.instCnt)) { + return Fail(report, "task instruction window is outside the mission image"); + } + if (!ContainsWindow(window.repositoryStartId, window.repositoryCount, task.instStartId, task.instCnt)) { + return Fail(report, "task instruction window is outside the repository image"); + } + } + return TILEXR_SUCCESS; +} + +void FillImageHeader(const TileXRCcuInstructionWindow& window, TileXRCcuRepositoryImage* image) +{ + image->dieId = window.dieId; + image->repositoryStartId = window.repositoryStartId; + image->repositoryCount = window.repositoryCount; + image->missionStartId = window.missionStartId; + image->missionCount = window.missionCount; + image->missionOffset = OffsetFrom(window.repositoryStartId, window.missionStartId); +} + +void FillReport(const TileXRCcuRepositoryImage& image, TileXRCcuRepositoryReport* report) +{ + if (report == nullptr) { + return; + } + report->repositoryCount = image.repositoryCount; + report->installedInstructionCount = static_cast(image.sqeLoadCount + image.syncCount); + report->sqeLoadOffset = image.sqeLoadOffset; + report->syncOffset = image.syncOffset; + report->repositoryUploaded = false; + report->repositoryInstalled = false; + report->message = "ok"; +} + +int BuildRepositoryPaddingInstruction(const TileXRCcuProducerPlan& plan, TileXRCcuInstr* instr, + TileXRCcuRepositoryReport* report) +{ + if (plan.kernelLocalXn.startId == 0 || + TileXRCcuEncodeLoadImdToXn(plan.kernelLocalXn.startId, 0, 0, instr) != TILEXR_SUCCESS) { + return Fail(report, "failed to build valid repository padding instruction"); + } + return TILEXR_SUCCESS; +} + +int ValidateMemoryOps(const TileXRCcuDeviceMemoryOps& memoryOps, TileXRCcuRepositoryReport* report) +{ + if (memoryOps.alloc == nullptr) { + return Fail(report, "missing CCU repository device allocation hook"); + } + if (memoryOps.copyHostToDevice == nullptr) { + return Fail(report, "missing CCU repository host-to-device copy hook"); + } + if (memoryOps.free == nullptr) { + return Fail(report, "missing CCU repository device free hook"); + } + return TILEXR_SUCCESS; +} + +int ValidateInstallImage(const TileXRCcuRepositoryImage& image, TileXRCcuRepositoryReport* report) +{ + if (image.instructions.empty()) { + return Fail(report, "missing CCU repository instruction image"); + } + if (image.missionCount == 0) { + return Fail(report, "missing CCU repository mission instruction window"); + } + if (image.missionOffset >= image.instructions.size() || + static_cast(image.missionOffset) + image.missionCount > image.instructions.size()) { + return Fail(report, "CCU repository mission window is outside instruction image"); + } + if (image.missionStartId == 0) { + return Fail(report, "missing CCU repository mission start instruction id"); + } + return TILEXR_SUCCESS; +} + +void FillInstallReport(const TileXRCcuRepositoryInstallReceipt& receipt, TileXRCcuRepositoryReport* report) +{ + if (report == nullptr) { + return; + } + report->repositoryCount = receipt.instructionCount; + report->installedInstructionCount = receipt.instructionCount; + report->sqeLoadOffset = 0; + report->syncOffset = 0; + report->repositoryUploaded = receipt.uploaded; + report->repositoryInstalled = receipt.installed; + report->message = "ok"; +} + +bool FitsSizeT(uint64_t bytes) +{ + return bytes <= static_cast(std::numeric_limits::max()); +} + +uint16_t InstallStartId(const TileXRCcuRepositoryImage& image, const TileXRCcuRepositoryInstallOptions& options) +{ + return options.window == TileXRCcuRepositoryInstallWindow::FullRepository ? + image.repositoryStartId : + image.missionStartId; +} + +uint16_t InstallInstructionCount( + const TileXRCcuRepositoryImage& image, + const TileXRCcuRepositoryInstallOptions& options) +{ + return options.window == TileXRCcuRepositoryInstallWindow::FullRepository ? + image.repositoryCount : + image.missionCount; +} + +uint16_t InstallImageOffset(const TileXRCcuRepositoryImage& image, const TileXRCcuRepositoryInstallOptions& options) +{ + return options.window == TileXRCcuRepositoryInstallWindow::FullRepository ? 0 : image.missionOffset; +} + +uint32_t InstallCustomChannelDataLen( + uint64_t instructionBytes, + const TileXRCcuRepositoryInstallOptions& options) +{ + return options.dataLenMode == TileXRCcuRepositoryInstallDataLenMode::DescriptorBytes ? + static_cast(sizeof(TileXRCcuInstrInfo)) : + static_cast(instructionBytes); +} + +const char* InstallWindowText(TileXRCcuRepositoryInstallWindow window) +{ + return window == TileXRCcuRepositoryInstallWindow::FullRepository ? "full_repository" : "mission"; +} + +const char* InstallDataLenModeText(TileXRCcuRepositoryInstallDataLenMode mode) +{ + return mode == TileXRCcuRepositoryInstallDataLenMode::DescriptorBytes ? + "descriptor_bytes" : + "instruction_bytes"; +} + +uint64_t MixFnv1aByte(uint64_t hash, uint8_t value) +{ + constexpr uint64_t prime = 1099511628211ULL; + hash ^= value; + hash *= prime; + return hash; +} + +uint64_t BuildInstructionFnv1a64(const TileXRCcuInstr* instructions, uint16_t count) +{ + uint64_t hash = 1469598103934665603ULL; + for (uint16_t i = 0; i < count; ++i) { + for (uint64_t word : instructions[i].words) { + for (uint32_t byte = 0; byte < 8U; ++byte) { + hash = MixFnv1aByte(hash, static_cast((word >> (byte * 8U)) & 0xffU)); + } + } + } + return hash; +} + +std::string FormatInstructionWords(const TileXRCcuInstr& instr) +{ + std::ostringstream out; + out << std::hex << std::setfill('0'); + for (uint32_t i = 0; i < 4U; ++i) { + if (i != 0) { + out << ","; + } + out << "0x" << std::setw(16) << instr.words[i]; + } + return out.str(); +} + +uint32_t CountInstructionMismatches( + const TileXRCcuInstr* expected, + const TileXRCcuInstr* actual, + uint16_t count) +{ + uint32_t mismatches = 0; + for (uint16_t i = 0; i < count; ++i) { + if (expected[i].words[0] != actual[i].words[0] || + expected[i].words[1] != actual[i].words[1] || + expected[i].words[2] != actual[i].words[2] || + expected[i].words[3] != actual[i].words[3]) { + ++mismatches; + } + } + return mismatches; +} + +const char* UploadReadbackStatusText(const TileXRCcuUploadReadbackDiagnostic& diagnostic) +{ + if (!diagnostic.attempted) { + return "skipped"; + } + if (diagnostic.ret != 0) { + return "failed"; + } + if (!diagnostic.ok) { + return "mismatch"; + } + return "ok"; +} + +void FillSuccessfulReadbackDiagnostic( + const std::vector& readback, + const TileXRCcuInstr* expectedInstructions, + uint16_t instructionCount, + TileXRCcuUploadReadbackDiagnostic* diagnostic) +{ + if (diagnostic == nullptr || readback.empty() || expectedInstructions == nullptr || instructionCount == 0) { + return; + } + diagnostic->fnv1a64 = BuildInstructionFnv1a64(readback.data(), instructionCount); + diagnostic->firstInstructionWords = FormatInstructionWords(readback.front()); + diagnostic->lastInstructionWords = FormatInstructionWords(readback.back()); + diagnostic->mismatchCount = CountInstructionMismatches(expectedInstructions, readback.data(), instructionCount); + diagnostic->ok = diagnostic->mismatchCount == 0; +} + +void BuildUploadReadbackDiagnostic( + const TileXRCcuDeviceMemoryOps& memoryOps, + void* devicePtr, + uint64_t instructionBytes, + const TileXRCcuInstr* expectedInstructions, + uint16_t instructionCount, + void* memoryUserData, + TileXRCcuUploadReadbackDiagnostic* diagnostic) +{ + if (diagnostic == nullptr) { + return; + } + *diagnostic = TileXRCcuUploadReadbackDiagnostic {}; + if (memoryOps.copyDeviceToHost == nullptr) { + return; + } + diagnostic->attempted = true; + diagnostic->bytes = instructionBytes; + if (devicePtr == nullptr || expectedInstructions == nullptr || instructionCount == 0 || + !FitsSizeT(instructionBytes)) { + diagnostic->ret = TILEXR_ERROR_PARA_CHECK_FAIL; + return; + } + + std::vector readback(instructionCount); + diagnostic->ret = memoryOps.copyDeviceToHost( + readback.data(), + instructionBytes, + devicePtr, + instructionBytes, + memoryUserData); + if (diagnostic->ret != 0) { + return; + } + + FillSuccessfulReadbackDiagnostic(readback, expectedInstructions, instructionCount, diagnostic); +} + +void BuildDriverInstructionReadbackDiagnostic( + const TileXRCcuDriverAdapter& adapter, + uint8_t dieId, + uint16_t instructionStartId, + uint16_t instructionCount, + uint64_t instructionBytes, + const TileXRCcuInstr* expectedInstructions, + TileXRCcuUploadReadbackDiagnostic* diagnostic) +{ + if (diagnostic == nullptr) { + return; + } + *diagnostic = TileXRCcuUploadReadbackDiagnostic {}; + diagnostic->attempted = true; + diagnostic->bytes = instructionBytes; + if (expectedInstructions == nullptr || instructionCount == 0 || !FitsSizeT(instructionBytes)) { + diagnostic->ret = TILEXR_ERROR_PARA_CHECK_FAIL; + return; + } + + std::vector readback(instructionCount); + uint16_t readOffset = 0; + while (readOffset < instructionCount) { + const uint32_t batch = std::min( + TILEXR_CCU_MAX_DATA_ARRAY_SIZE, + static_cast(instructionCount - readOffset)); + TileXRCcuDriverAdapterReport driverReport; + diagnostic->ret = adapter.ReadInstructions( + dieId, + static_cast(instructionStartId + readOffset), + readback.data() + readOffset, + batch, + batch * TILEXR_CCU_INSTRUCTION_BYTES, + &driverReport); + if (diagnostic->ret != TILEXR_SUCCESS) { + return; + } + readOffset = static_cast(readOffset + batch); + } + + FillSuccessfulReadbackDiagnostic(readback, expectedInstructions, instructionCount, diagnostic); +} + +std::string BuildInstallFailureDiagnostic( + const std::string& driverMessage, + const TileXRCcuRepositoryImage& image, + const TileXRCcuRepositoryInstallOptions& options, + uint16_t installOffset, + uint16_t installStartId, + uint16_t installCount, + uint64_t instructionBytes, + uint32_t customChannelDataLen, + uint64_t deviceInstructionAddr, + const TileXRCcuUploadReadbackDiagnostic& uploadReadback, + const TileXRCcuUploadReadbackDiagnostic& driverReadback) +{ + const TileXRCcuInstr* firstInstruction = image.instructions.data() + installOffset; + const TileXRCcuInstr* lastInstruction = firstInstruction + installCount - 1U; + const uint64_t hash = BuildInstructionFnv1a64(firstInstruction, installCount); + + std::ostringstream message; + message << "failed to install CCU repository instruction image: " << driverMessage + << " dieId=" << static_cast(image.dieId) + << " installStartId=" << installStartId + << " installCount=" << installCount + << " instructionBytes=" << instructionBytes + << " customChannelDataLen=" << customChannelDataLen + << " deviceInstructionAddr=0x" << std::hex << deviceInstructionAddr << std::dec + << " window=" << InstallWindowText(options.window) + << " dataLenMode=" << InstallDataLenModeText(options.dataLenMode) + << " firstInstructionWords=" << FormatInstructionWords(*firstInstruction) + << " lastInstructionWords=" << FormatInstructionWords(*lastInstruction) + << " instructionFnv1a64=0x" << std::hex << hash << std::dec + << " uploadReadback=" << UploadReadbackStatusText(uploadReadback); + if (uploadReadback.attempted) { + message << " uploadReadbackRet=" << uploadReadback.ret + << " uploadReadbackBytes=" << uploadReadback.bytes; + if (uploadReadback.ret == 0) { + message << " uploadReadbackFnv1a64=0x" << std::hex << uploadReadback.fnv1a64 << std::dec + << " uploadReadbackFirstInstructionWords=" << uploadReadback.firstInstructionWords + << " uploadReadbackLastInstructionWords=" << uploadReadback.lastInstructionWords + << " uploadReadbackMismatchCount=" << uploadReadback.mismatchCount; + } + } + message << " driverReadback=" << UploadReadbackStatusText(driverReadback); + if (driverReadback.attempted) { + message << " driverReadbackRet=" << driverReadback.ret + << " driverReadbackBytes=" << driverReadback.bytes; + if (driverReadback.ret == 0) { + message << " driverReadbackFnv1a64=0x" << std::hex << driverReadback.fnv1a64 << std::dec + << " driverReadbackFirstInstructionWords=" << driverReadback.firstInstructionWords + << " driverReadbackLastInstructionWords=" << driverReadback.lastInstructionWords + << " driverReadbackMismatchCount=" << driverReadback.mismatchCount; + } + } + return message.str(); +} + +int AclDeviceAlloc(uint64_t bytes, void** devicePtr, void*) +{ + if (devicePtr == nullptr || bytes == 0 || !FitsSizeT(bytes)) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } +#if TILEXR_CCU_HAVE_ACL_RT_HEADER + return aclrtMalloc(devicePtr, static_cast(bytes), ACL_MEM_MALLOC_HUGE_FIRST); +#else + *devicePtr = nullptr; + return TILEXR_ERROR_MKIRT; +#endif +} + +int AclModule3DeviceAlloc(uint64_t bytes, void** devicePtr, void*) +{ + if (devicePtr == nullptr || bytes == 0 || !FitsSizeT(bytes)) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } +#if TILEXR_CCU_HAVE_ACL_RT_HEADER + aclrtMallocAttrValue moduleIdValue {}; + moduleIdValue.moduleId = TILEXR_CCU_ACL_MODULE3_ID; + aclrtMallocAttribute attrs {ACL_RT_MEM_ATTR_MODULE_ID, moduleIdValue}; + aclrtMallocConfig cfg {&attrs, 1}; + return aclrtMallocWithCfg( + devicePtr, + static_cast(bytes), + static_cast(ACL_MEM_TYPE_HIGH_BAND_WIDTH | ACL_MEM_MALLOC_HUGE_FIRST), + &cfg); +#else + *devicePtr = nullptr; + return TILEXR_ERROR_MKIRT; +#endif +} + +int AclCopyHostToDevice(void* deviceDst, uint64_t deviceDstBytes, const void* hostSrc, uint64_t bytes, void*) +{ + if (deviceDst == nullptr || hostSrc == nullptr || bytes == 0 || bytes > deviceDstBytes || + !FitsSizeT(deviceDstBytes) || !FitsSizeT(bytes)) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } +#if TILEXR_CCU_HAVE_ACL_RT_HEADER + return aclrtMemcpy( + deviceDst, + static_cast(deviceDstBytes), + hostSrc, + static_cast(bytes), + ACL_MEMCPY_HOST_TO_DEVICE); +#else + return TILEXR_ERROR_MKIRT; +#endif +} + +int AclCopyDeviceToHost(void* hostDst, uint64_t hostDstBytes, const void* deviceSrc, uint64_t bytes, void*) +{ + if (hostDst == nullptr || deviceSrc == nullptr || bytes == 0 || bytes > hostDstBytes || + !FitsSizeT(hostDstBytes) || !FitsSizeT(bytes)) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } +#if TILEXR_CCU_HAVE_ACL_RT_HEADER + return aclrtMemcpy( + hostDst, + static_cast(hostDstBytes), + deviceSrc, + static_cast(bytes), + ACL_MEMCPY_DEVICE_TO_HOST); +#else + return TILEXR_ERROR_MKIRT; +#endif +} + +int AclDeviceFree(void* devicePtr, void*) +{ + if (devicePtr == nullptr) { + return TILEXR_SUCCESS; + } +#if TILEXR_CCU_HAVE_ACL_RT_HEADER + return aclrtFree(devicePtr); +#else + return TILEXR_ERROR_MKIRT; +#endif +} + +int RtHbmDeviceAlloc(uint64_t bytes, void** devicePtr, void*) +{ + if (devicePtr == nullptr || bytes == 0) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } +#if TILEXR_CCU_HAVE_RUNTIME_MEM_HEADER + return rtMalloc(devicePtr, bytes, RT_MEMORY_HBM, TILEXR_CCU_RT_HBM_MODULE_ID); +#else + *devicePtr = nullptr; + return TILEXR_ERROR_MKIRT; +#endif +} + +int RtHbmCopyHostToDevice(void* deviceDst, uint64_t deviceDstBytes, const void* hostSrc, uint64_t bytes, void*) +{ + if (deviceDst == nullptr || hostSrc == nullptr || bytes == 0 || bytes > deviceDstBytes) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } +#if TILEXR_CCU_HAVE_RUNTIME_MEM_HEADER + return rtMemcpy(deviceDst, deviceDstBytes, hostSrc, bytes, RT_MEMCPY_HOST_TO_DEVICE); +#else + return TILEXR_ERROR_MKIRT; +#endif +} + +int RtHbmCopyDeviceToHost(void* hostDst, uint64_t hostDstBytes, const void* deviceSrc, uint64_t bytes, void*) +{ + if (hostDst == nullptr || deviceSrc == nullptr || bytes == 0 || bytes > hostDstBytes) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } +#if TILEXR_CCU_HAVE_RUNTIME_MEM_HEADER + return rtMemcpy(hostDst, hostDstBytes, deviceSrc, bytes, RT_MEMCPY_DEVICE_TO_HOST); +#else + return TILEXR_ERROR_MKIRT; +#endif +} + +int RtHbmDeviceFree(void* devicePtr, void*) +{ + if (devicePtr == nullptr) { + return TILEXR_SUCCESS; + } +#if TILEXR_CCU_HAVE_RUNTIME_MEM_HEADER + return rtFree(devicePtr); +#else + return TILEXR_ERROR_MKIRT; +#endif +} + +} // namespace + +TileXRCcuDeviceMemoryOps TileXRCcuMakeAclDeviceMemoryOps() +{ + TileXRCcuDeviceMemoryOps ops; +#if TILEXR_CCU_HAVE_ACL_RT_HEADER + ops.alloc = AclDeviceAlloc; + ops.copyHostToDevice = AclCopyHostToDevice; + ops.free = AclDeviceFree; + ops.copyDeviceToHost = AclCopyDeviceToHost; +#endif + return ops; +} + +TileXRCcuDeviceMemoryOps TileXRCcuMakeAclModule3DeviceMemoryOps() +{ + TileXRCcuDeviceMemoryOps ops; +#if TILEXR_CCU_HAVE_ACL_RT_HEADER + ops.alloc = AclModule3DeviceAlloc; + ops.copyHostToDevice = AclCopyHostToDevice; + ops.free = AclDeviceFree; + ops.copyDeviceToHost = AclCopyDeviceToHost; +#endif + return ops; +} + +TileXRCcuDeviceMemoryOps TileXRCcuMakeRtHbmDeviceMemoryOps() +{ + TileXRCcuDeviceMemoryOps ops; +#if TILEXR_CCU_HAVE_RUNTIME_MEM_HEADER + ops.alloc = RtHbmDeviceAlloc; + ops.copyHostToDevice = RtHbmCopyHostToDevice; + ops.free = RtHbmDeviceFree; + ops.copyDeviceToHost = RtHbmCopyDeviceToHost; +#endif + return ops; +} + +TileXRCcuDeviceMemoryOps TileXRCcuMakeRepositoryDeviceMemoryOps(TileXRCcuRepositoryMemoryAllocMode mode) +{ + if (mode == TileXRCcuRepositoryMemoryAllocMode::AclModule3) { + return TileXRCcuMakeAclModule3DeviceMemoryOps(); + } + if (mode == TileXRCcuRepositoryMemoryAllocMode::RtHbm) { + return TileXRCcuMakeRtHbmDeviceMemoryOps(); + } + return TileXRCcuMakeAclDeviceMemoryOps(); +} + +int TileXRCcuBuildRepositoryImage( + const TileXRCcuProducerPlan& plan, + const TileXRCcuProgram& program, + TileXRCcuRepositoryImage* image, + TileXRCcuRepositoryReport* report) +{ + ResetReport(report); + if (image == nullptr) { + return Fail(report, "missing output repository image"); + } + image->instructions.clear(); + + TileXRCcuProducerPlanReport planReport; + if (TileXRCcuValidateProducerPlan(plan, &planReport) != TILEXR_SUCCESS) { + return Fail(report, planReport.message); + } + if (ValidateProgramShape(plan, program, report) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + if (ValidateRepositoryWindow(plan, report) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + + FillImageHeader(plan.instructionWindow, image); + const size_t syncTaskIndex = program.sqeLoad.empty() ? 0U : 1U; + image->sqeLoadOffset = program.sqeLoad.empty() ? + 0 : + OffsetFrom(plan.instructionWindow.repositoryStartId, plan.taskWindows[0].instStartId); + image->sqeLoadCount = static_cast(program.sqeLoad.size()); + image->syncOffset = OffsetFrom(plan.instructionWindow.repositoryStartId, plan.taskWindows[syncTaskIndex].instStartId); + image->syncCount = static_cast(program.sync.size()); + + const uint32_t sqeEnd = static_cast(image->sqeLoadOffset) + image->sqeLoadCount; + const uint32_t syncEnd = static_cast(image->syncOffset) + image->syncCount; + if (sqeEnd > image->repositoryCount || syncEnd > image->repositoryCount) { + image->instructions.clear(); + return Fail(report, "generated microcode does not fit in repository image"); + } + + TileXRCcuInstr paddingInstr; + if (BuildRepositoryPaddingInstruction(plan, &paddingInstr, report) != TILEXR_SUCCESS) { + image->instructions.clear(); + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + image->instructions.assign(image->repositoryCount, paddingInstr); + std::copy(program.sqeLoad.begin(), program.sqeLoad.end(), image->instructions.begin() + image->sqeLoadOffset); + std::copy(program.sync.begin(), program.sync.end(), image->instructions.begin() + image->syncOffset); + + FillReport(*image, report); + return TILEXR_SUCCESS; +} + +int TileXRCcuInstallRepositoryImage( + const TileXRCcuRepositoryImage& image, + const TileXRCcuDeviceMemoryOps& memoryOps, + void* memoryUserData, + const TileXRCcuDriverAdapter& adapter, + TileXRCcuRepositoryInstallReceipt* receipt, + TileXRCcuRepositoryReport* report) +{ + TileXRCcuRepositoryInstallOptions options; + return TileXRCcuInstallRepositoryImageWithOptions( + image, + options, + memoryOps, + memoryUserData, + adapter, + receipt, + report); +} + +int TileXRCcuInstallRepositoryImageWithOptions( + const TileXRCcuRepositoryImage& image, + const TileXRCcuRepositoryInstallOptions& options, + const TileXRCcuDeviceMemoryOps& memoryOps, + void* memoryUserData, + const TileXRCcuDriverAdapter& adapter, + TileXRCcuRepositoryInstallReceipt* receipt, + TileXRCcuRepositoryReport* report) +{ + ResetReport(report); + if (receipt == nullptr) { + return Fail(report, "missing output CCU repository install receipt"); + } + *receipt = TileXRCcuRepositoryInstallReceipt{}; + + if (ValidateMemoryOps(memoryOps, report) != TILEXR_SUCCESS || + ValidateInstallImage(image, report) != TILEXR_SUCCESS) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + + const uint16_t installOffset = InstallImageOffset(image, options); + const uint16_t installStartId = InstallStartId(image, options); + const uint16_t installCount = InstallInstructionCount(image, options); + if (installCount == 0 || + installOffset >= image.instructions.size() || + static_cast(installOffset) + installCount > image.instructions.size()) { + return Fail(report, "CCU repository selected install window is outside instruction image"); + } + + const uint64_t instructionBytes = static_cast(installCount) * sizeof(TileXRCcuInstr); + void* devicePtr = nullptr; + const int allocRet = memoryOps.alloc(instructionBytes, &devicePtr, memoryUserData); + if (allocRet != 0 || devicePtr == nullptr) { + return Fail(report, "failed to allocate CCU repository device instruction image", TILEXR_ERROR_MKIRT); + } + + const auto* firstInstruction = image.instructions.data() + installOffset; + const int copyRet = memoryOps.copyHostToDevice( + devicePtr, + instructionBytes, + firstInstruction, + instructionBytes, + memoryUserData); + if (copyRet != 0) { + (void)memoryOps.free(devicePtr, memoryUserData); + return Fail(report, "failed to copy CCU repository instruction image to device", TILEXR_ERROR_MKIRT); + } + + TileXRCcuRepositoryInstallReceipt result; + result.dieId = image.dieId; + result.instructionStartId = installStartId; + result.instructionCount = installCount; + result.instructionBytes = instructionBytes; + result.deviceInstructionAddr = reinterpret_cast(devicePtr); + result.deviceInstructionPtr = devicePtr; + result.uploaded = true; + + TileXRCcuUploadReadbackDiagnostic uploadReadback; + BuildUploadReadbackDiagnostic( + memoryOps, + devicePtr, + instructionBytes, + firstInstruction, + installCount, + memoryUserData, + &uploadReadback); + + const uint32_t customChannelDataLen = InstallCustomChannelDataLen(instructionBytes, options); + TileXRCcuDriverAdapterReport driverReport; + const int installRet = adapter.InstallInstructionsWithDataLen( + image.dieId, + installStartId, + installCount, + result.deviceInstructionAddr, + static_cast(instructionBytes), + customChannelDataLen, + &driverReport); + if (installRet != TILEXR_SUCCESS) { + TileXRCcuUploadReadbackDiagnostic driverReadback; + BuildDriverInstructionReadbackDiagnostic( + adapter, + image.dieId, + installStartId, + installCount, + instructionBytes, + firstInstruction, + &driverReadback); + (void)memoryOps.free(devicePtr, memoryUserData); + return Fail( + report, + BuildInstallFailureDiagnostic( + driverReport.message, + image, + options, + installOffset, + installStartId, + installCount, + instructionBytes, + customChannelDataLen, + result.deviceInstructionAddr, + uploadReadback, + driverReadback), + TILEXR_ERROR_MKIRT); + } + + result.installed = true; + *receipt = result; + FillInstallReport(*receipt, report); + if (report != nullptr && + (options.window != TileXRCcuRepositoryInstallWindow::Mission || + options.dataLenMode != TileXRCcuRepositoryInstallDataLenMode::InstructionBytes)) { + report->message = std::string("ok window=") + InstallWindowText(options.window) + + " dataLenMode=" + InstallDataLenModeText(options.dataLenMode); + } + return TILEXR_SUCCESS; +} + +int TileXRCcuReleaseRepositoryInstallReceipt( + TileXRCcuRepositoryInstallReceipt& receipt, + const TileXRCcuDeviceMemoryOps& memoryOps, + void* memoryUserData, + TileXRCcuRepositoryReport* report) +{ + ResetReport(report); + if (memoryOps.free == nullptr) { + return Fail(report, "missing CCU repository device free hook"); + } + if (receipt.deviceInstructionPtr == nullptr) { + receipt = TileXRCcuRepositoryInstallReceipt{}; + if (report != nullptr) { + report->message = "ok"; + } + return TILEXR_SUCCESS; + } + const int freeRet = memoryOps.free(receipt.deviceInstructionPtr, memoryUserData); + if (freeRet != 0) { + return Fail(report, "failed to release CCU repository device instruction image", TILEXR_ERROR_MKIRT); + } + receipt = TileXRCcuRepositoryInstallReceipt{}; + if (report != nullptr) { + report->message = "ok"; + } + return TILEXR_SUCCESS; +} + +} // namespace TileXR diff --git a/src/comm/ccu/tilexr_ccu_repository.h b/src/comm/ccu/tilexr_ccu_repository.h new file mode 100644 index 00000000..5a7fdc02 --- /dev/null +++ b/src/comm/ccu/tilexr_ccu_repository.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2026 TileXR Project + * Licensed under the Apache License, Version 2.0 + */ + +#ifndef TILEXR_CCU_REPOSITORY_H +#define TILEXR_CCU_REPOSITORY_H + +#include "ccu/tilexr_ccu_driver_adapter.h" +#include "ccu/tilexr_ccu_producer_plan.h" + +#include +#include +#include + +namespace TileXR { + +struct TileXRCcuRepositoryImage { + uint8_t dieId = 0; + uint16_t repositoryStartId = 0; + uint16_t repositoryCount = 0; + uint16_t missionStartId = 0; + uint16_t missionCount = 0; + uint16_t missionOffset = 0; + uint16_t sqeLoadOffset = 0; + uint16_t sqeLoadCount = 0; + uint16_t syncOffset = 0; + uint16_t syncCount = 0; + std::vector instructions; +}; + +struct TileXRCcuRepositoryReport { + uint16_t repositoryCount = 0; + uint16_t installedInstructionCount = 0; + uint16_t sqeLoadOffset = 0; + uint16_t syncOffset = 0; + bool repositoryUploaded = false; + bool repositoryInstalled = false; + std::string message; +}; + +using TileXRCcuDeviceAllocFn = int (*)(uint64_t bytes, void** devicePtr, void* userData); +using TileXRCcuCopyHostToDeviceFn = int (*)( + void* deviceDst, + uint64_t deviceDstBytes, + const void* hostSrc, + uint64_t bytes, + void* userData); +using TileXRCcuCopyDeviceToHostFn = int (*)( + void* hostDst, + uint64_t hostDstBytes, + const void* deviceSrc, + uint64_t bytes, + void* userData); +using TileXRCcuDeviceFreeFn = int (*)(void* devicePtr, void* userData); + +struct TileXRCcuDeviceMemoryOps { + TileXRCcuDeviceAllocFn alloc = nullptr; + TileXRCcuCopyHostToDeviceFn copyHostToDevice = nullptr; + TileXRCcuDeviceFreeFn free = nullptr; + TileXRCcuCopyDeviceToHostFn copyDeviceToHost = nullptr; +}; + +enum class TileXRCcuRepositoryMemoryAllocMode : uint8_t { + Acl = 0, + AclModule3 = 1, + RtHbm = 2, +}; + +struct TileXRCcuRepositoryInstallReceipt { + uint8_t dieId = 0; + uint16_t instructionStartId = 0; + uint16_t instructionCount = 0; + uint64_t instructionBytes = 0; + uint64_t deviceInstructionAddr = 0; + void* deviceInstructionPtr = nullptr; + bool uploaded = false; + bool installed = false; +}; + +enum class TileXRCcuRepositoryInstallWindow : uint8_t { + Mission = 0, + FullRepository = 1, +}; + +enum class TileXRCcuRepositoryInstallDataLenMode : uint8_t { + InstructionBytes = 0, + DescriptorBytes = 1, +}; + +struct TileXRCcuRepositoryInstallOptions { + TileXRCcuRepositoryInstallWindow window = TileXRCcuRepositoryInstallWindow::Mission; + TileXRCcuRepositoryInstallDataLenMode dataLenMode = TileXRCcuRepositoryInstallDataLenMode::InstructionBytes; +}; + +TileXRCcuDeviceMemoryOps TileXRCcuMakeAclDeviceMemoryOps(); +TileXRCcuDeviceMemoryOps TileXRCcuMakeAclModule3DeviceMemoryOps(); +TileXRCcuDeviceMemoryOps TileXRCcuMakeRtHbmDeviceMemoryOps(); +TileXRCcuDeviceMemoryOps TileXRCcuMakeRepositoryDeviceMemoryOps(TileXRCcuRepositoryMemoryAllocMode mode); + +int TileXRCcuBuildRepositoryImage( + const TileXRCcuProducerPlan& plan, + const TileXRCcuProgram& program, + TileXRCcuRepositoryImage* image, + TileXRCcuRepositoryReport* report); + +int TileXRCcuInstallRepositoryImage( + const TileXRCcuRepositoryImage& image, + const TileXRCcuDeviceMemoryOps& memoryOps, + void* memoryUserData, + const TileXRCcuDriverAdapter& adapter, + TileXRCcuRepositoryInstallReceipt* receipt, + TileXRCcuRepositoryReport* report); + +int TileXRCcuInstallRepositoryImageWithOptions( + const TileXRCcuRepositoryImage& image, + const TileXRCcuRepositoryInstallOptions& options, + const TileXRCcuDeviceMemoryOps& memoryOps, + void* memoryUserData, + const TileXRCcuDriverAdapter& adapter, + TileXRCcuRepositoryInstallReceipt* receipt, + TileXRCcuRepositoryReport* report); + +int TileXRCcuReleaseRepositoryInstallReceipt( + TileXRCcuRepositoryInstallReceipt& receipt, + const TileXRCcuDeviceMemoryOps& memoryOps, + void* memoryUserData, + TileXRCcuRepositoryReport* report); + +} // namespace TileXR + +#endif // TILEXR_CCU_REPOSITORY_H diff --git a/tests/ccu/test_tilexr_ccu_install_provider.py b/tests/ccu/test_tilexr_ccu_install_provider.py new file mode 100644 index 00000000..5e62452e --- /dev/null +++ b/tests/ccu/test_tilexr_ccu_install_provider.py @@ -0,0 +1,3334 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2026 TileXR Project +# + +import shutil +import subprocess +import tempfile +import textwrap +import unittest +import os +import platform +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[2] +INSTALL_HEADER = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_install_provider.h" +INSTALL_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_install_provider.cpp" +PROVIDER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_provider.cpp" +PACKAGE_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_launch_package.cpp" +REPOSITORY_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_repository.cpp" +DRIVER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp" +SPECS_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_specs.cpp" +PRODUCER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_producer_plan.cpp" +BARRIER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_barrier_program.cpp" +MICROCODE_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_microcode.cpp" +COMM_CMAKE = REPO_ROOT / "src" / "comm" / "CMakeLists.txt" +INCLUDE_DIR = REPO_ROOT / "src" / "include" +COMM_DIR = REPO_ROOT / "src" / "comm" + + +PRIVATE_CCU_PRODUCER_NEEDLES = [ + "#include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 10; + } + + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport installReport; + TileXRCcuInstallRequest request; + request.package = &package; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = true; + if (TileXRCcuInstallHardware(request, &evidence, &installReport) != TILEXR_ERROR_NOT_FOUND) { + std::cerr << "default install provider unexpectedly succeeded\n"; + return 2; + } + if (installReport.installAttempted || installReport.installSucceeded) { + std::cerr << "default install provider reported an attempted/succeeded install\n"; + return 3; + } + if (installReport.message.find("no public no-hcomm CCU install provider") == std::string::npos) { + std::cerr << "weak install provider diagnostic: " << installReport.message << "\n"; + return 4; + } + if (evidence.missionInstalled || evidence.repositoryInstalled || evidence.localXnInstalled || + evidence.remoteXnBound || evidence.notifyCkeInstalled || evidence.channelBindingsInstalled) { + std::cerr << "default install provider filled install evidence\n"; + return 5; + } + if (evidence.missionSource.kind != TileXRCcuEvidenceKind::Missing || + evidence.repositorySource.kind != TileXRCcuEvidenceKind::Missing || + evidence.localXnSource.kind != TileXRCcuEvidenceKind::Missing || + evidence.remoteXnSource.kind != TileXRCcuEvidenceKind::Missing || + evidence.notifyCkeSource.kind != TileXRCcuEvidenceKind::Missing || + evidence.channelBindingSource.kind != TileXRCcuEvidenceKind::Missing) { + std::cerr << "default install provider did not mark sources missing\n"; + return 6; + } + + std::vector submitTasks; + TileXRCcuProviderReport providerReport; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &providerReport) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "unsupported install evidence became submit-ready\n"; + return 7; + } + if (!submitTasks.empty() || providerReport.submitReady) { + std::cerr << "failed prepare leaked submit-ready state\n"; + return 8; + } + if (providerReport.message.find("mission") == std::string::npos || + providerReport.message.find("missing") == std::string::npos) { + std::cerr << "weak provider diagnostic: " << providerReport.message << "\n"; + return 9; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_install_request_must_match_bound_launch_scope(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int ExpectScopeFailure( + const TileXRCcuInstallRequest& request, + const char* diagnostic) + { + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport report; + const int ret = TileXRCcuInstallHardware(request, &evidence, &report); + if (ret != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "scope mismatch was not rejected: " << diagnostic << "\n"; + return 1; + } + if (report.message.find(diagnostic) == std::string::npos) { + std::cerr << "weak scope mismatch diagnostic: " << report.message << "\n"; + return 2; + } + if (evidence.missionInstalled || evidence.repositoryInstalled || evidence.localXnInstalled || + evidence.remoteXnBound || evidence.notifyCkeInstalled || evidence.channelBindingsInstalled) { + std::cerr << "failed scope mismatch left install evidence\n"; + return 3; + } + return 0; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuInstallRequest request; + request.package = &package; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = false; + + TileXRCcuInstallRequest wrongDevice = request; + wrongDevice.deviceId = 4; + if (ExpectScopeFailure(wrongDevice, "device scope mismatch") != 0) { + return 3; + } + + TileXRCcuInstallRequest wrongRank = request; + wrongRank.rank = 0; + if (ExpectScopeFailure(wrongRank, "rank scope mismatch") != 0) { + return 4; + } + + TileXRCcuInstallRequest wrongProvider = request; + wrongProvider.provider = "other-public-install-provider"; + if (ExpectScopeFailure(wrongProvider, "provider scope mismatch") != 0) { + return 5; + } + + TileXRCcuInstallRequest missingProvider = request; + missingProvider.provider.clear(); + if (ExpectScopeFailure(missingProvider, "provider scope mismatch") != 0) { + return 6; + } + + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport report; + if (TileXRCcuInstallHardware(request, &evidence, &report) != TILEXR_ERROR_NOT_FOUND) { + std::cerr << "matching scope should reach unsupported provider: " << report.message << "\n"; + return 7; + } + if (report.message.find("no public no-hcomm CCU install provider") == std::string::npos) { + std::cerr << "matching scope diagnostic was weak: " << report.message << "\n"; + return 8; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_online_install_provider_installs_repository_and_keeps_remaining_bits_missing(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + #include + #include + + using namespace TileXR; + + struct FakeState { + std::vector deviceBytes; + uint32_t observedOp = 0; + uint32_t observedOffset = 0; + uint32_t observedDataLen = 0; + uint64_t observedResourceAddr = 0; + bool freed = false; + }; + + int FakeAlloc(uint64_t bytes, void** ptr, void* userData) + { + auto* state = static_cast(userData); + state->deviceBytes.assign(static_cast(bytes), 0); + *ptr = state->deviceBytes.data(); + return 0; + } + + int FakeCopy(void* dst, uint64_t dstBytes, const void* src, uint64_t bytes, void* userData) + { + auto* state = static_cast(userData); + if (dst != state->deviceBytes.data() || dstBytes != state->deviceBytes.size() || + bytes != state->deviceBytes.size()) { + return -1; + } + std::memcpy(dst, src, static_cast(bytes)); + return 0; + } + + int FakeFree(void* ptr, void* userData) + { + auto* state = static_cast(userData); + if (ptr != state->deviceBytes.data()) { + return -1; + } + state->freed = true; + state->deviceBytes.clear(); + return 0; + } + + int FakeCustomChannel( + uint32_t, + const TileXRCcuCustomChannelIn& in, + TileXRCcuCustomChannelOut* out, + void* userData) + { + auto* state = static_cast(userData); + state->observedOp = in.op; + state->observedOffset = in.offsetStartIdx; + state->observedDataLen = in.data.dataInfo.dataLen; + state->observedResourceAddr = in.data.dataInfo.dataArray[0].insinfo.resourceAddr; + out->opRet = 0; + return 0; + } + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport manifestReport; + if (TileXRCcuBuildInstallManifest(package, &manifest, &manifestReport) != TILEXR_SUCCESS) { + std::cerr << "manifest build failed: " << manifestReport.message << "\n"; + return 3; + } + + FakeState state; + TileXRCcuDriverAdapter adapter; + TileXRCcuDriverAdapterReport driverReport; + if (adapter.Init(5, FakeCustomChannel, &state, &driverReport) != TILEXR_SUCCESS) { + std::cerr << "adapter init failed\n"; + return 4; + } + + TileXRCcuDeviceMemoryOps memoryOps; + memoryOps.alloc = FakeAlloc; + memoryOps.copyHostToDevice = FakeCopy; + memoryOps.free = FakeFree; + + TileXRCcuRepositoryInstallReceipt receipt; + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport installReport; + TileXRCcuInstallRequest request; + request.package = &package; + request.manifest = &manifest; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = false; + request.driverAdapter = &adapter; + request.repositoryMemoryOps = memoryOps; + request.repositoryMemoryUserData = &state; + request.repositoryReceipt = &receipt; + + if (TileXRCcuInstallHardware(request, &evidence, &installReport) != TILEXR_ERROR_NOT_FOUND) { + std::cerr << "partial hardware install should stop at missing lower-layer resources: " + << installReport.message << "\n"; + return 5; + } + if (!installReport.installAttempted || !installReport.installSucceeded || + installReport.installAttemptReceiptId == 0 || + installReport.publicVerifiedInstallSurfaceCount != 2 || + installReport.missingInstallSurfaceCount != 4) { + std::cerr << "repository install report mismatch\n"; + return 6; + } + if (!installReport.repository.satisfied || !installReport.mission.satisfied || + installReport.localXn.satisfied || installReport.remoteXn.satisfied || + installReport.notifyCke.satisfied || installReport.channelBinding.satisfied) { + std::cerr << "unexpected install step evidence bits\n"; + return 7; + } + if (!evidence.repositoryInstalled || !evidence.missionInstalled || evidence.localXnInstalled || + evidence.remoteXnBound || evidence.notifyCkeInstalled || evidence.channelBindingsInstalled) { + std::cerr << "unexpected hardware evidence bits\n"; + return 8; + } + if (evidence.repositorySource.kind != TileXRCcuEvidenceKind::PublicVerified || + evidence.repositorySource.surface != TileXRCcuEvidenceSurface::PublicInstallProvider || + evidence.repositorySource.packageFingerprint != TileXRCcuComputeLaunchPackageFingerprint(package) || + evidence.repositorySource.deviceId != 3 || evidence.repositorySource.rank != 1 || + evidence.repositorySource.provider != "unit-test-public-install-provider" || + evidence.repositorySource.installAttemptReceiptId != installReport.installAttemptReceiptId) { + std::cerr << "repository evidence scope mismatch\n"; + return 9; + } + if (evidence.missionSource.kind != TileXRCcuEvidenceKind::PublicVerified || + evidence.missionSource.surface != TileXRCcuEvidenceSurface::PublicInstallProvider || + evidence.missionSource.installAttemptReceiptId != installReport.installAttemptReceiptId || + evidence.missionSource.detail.find("launch task descriptor") == std::string::npos || + evidence.missionSource.detail.find("mission key") == std::string::npos) { + std::cerr << "mission descriptor evidence mismatch\n"; + return 12; + } + if (state.observedOp != TILEXR_CCU_U_OP_SET_INSTRUCTION || + state.observedOffset != 489 || + state.observedDataLen != 156U * sizeof(TileXRCcuInstr) || + state.observedResourceAddr != receipt.deviceInstructionAddr || + receipt.instructionStartId != 489 || receipt.instructionCount != 156 || + !receipt.uploaded || !receipt.installed) { + std::cerr << "SET_INSTRUCTION request or receipt mismatch\n"; + return 10; + } + + TileXRCcuRepositoryReport releaseReport; + if (TileXRCcuReleaseRepositoryInstallReceipt(receipt, memoryOps, &state, &releaseReport) != + TILEXR_SUCCESS || !state.freed) { + std::cerr << "release failed: " << releaseReport.message << "\n"; + return 11; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_online_install_provider_installs_lower_layer_payloads_without_unlocking_submit_gate(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + #include + #include + + using namespace TileXR; + + struct ObservedCall { + uint32_t op = 0; + uint32_t die = 0; + uint32_t offset = 0; + uint32_t dataLen = 0; + uint32_t arraySize = 0; + uint8_t raw[160] = {0}; + uint32_t msId = 0; + uint32_t tokenId = 0; + uint32_t tokenValue = 0; + }; + + struct FakeState { + std::vector deviceBytes; + std::vector calls; + bool freed = false; + }; + + int FakeAlloc(uint64_t bytes, void** ptr, void* userData) + { + auto* state = static_cast(userData); + state->deviceBytes.assign(static_cast(bytes), 0); + *ptr = state->deviceBytes.data(); + return 0; + } + + int FakeCopy(void* dst, uint64_t dstBytes, const void* src, uint64_t bytes, void* userData) + { + auto* state = static_cast(userData); + if (dst != state->deviceBytes.data() || dstBytes != state->deviceBytes.size() || + bytes != state->deviceBytes.size()) { + return -1; + } + std::memcpy(dst, src, static_cast(bytes)); + return 0; + } + + int FakeFree(void* ptr, void* userData) + { + auto* state = static_cast(userData); + if (ptr != state->deviceBytes.data()) { + return -1; + } + state->freed = true; + state->deviceBytes.clear(); + return 0; + } + + int FakeCustomChannel( + uint32_t, + const TileXRCcuCustomChannelIn& in, + TileXRCcuCustomChannelOut* out, + void* userData) + { + auto* state = static_cast(userData); + ObservedCall call; + call.op = in.op; + call.die = in.data.dataInfo.udieIdx; + call.offset = in.offsetStartIdx; + call.dataLen = in.data.dataInfo.dataLen; + call.arraySize = in.data.dataInfo.dataArraySize; + call.msId = in.data.dataInfo.dataArray[0].baseinfo.msId; + call.tokenId = in.data.dataInfo.dataArray[0].baseinfo.tokenId; + call.tokenValue = in.data.dataInfo.dataArray[0].baseinfo.tokenValue; + std::memcpy(call.raw, in.data.dataInfo.dataArray, sizeof(call.raw)); + state->calls.push_back(call); + out->opRet = 0; + return 0; + } + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport manifestReport; + if (TileXRCcuBuildInstallManifest(package, &manifest, &manifestReport) != TILEXR_SUCCESS) { + std::cerr << "manifest build failed: " << manifestReport.message << "\n"; + return 3; + } + + FakeState state; + TileXRCcuDriverAdapter adapter; + TileXRCcuDriverAdapterReport driverReport; + if (adapter.Init(5, FakeCustomChannel, &state, &driverReport) != TILEXR_SUCCESS) { + std::cerr << "adapter init failed\n"; + return 4; + } + + TileXRCcuDeviceMemoryOps memoryOps; + memoryOps.alloc = FakeAlloc; + memoryOps.copyHostToDevice = FakeCopy; + memoryOps.free = FakeFree; + + TileXRCcuLowerLayerInstallPlan lowerLayer; + lowerLayer.msidTokens.push_back({1, 0x45, 0x1234, 0x5678}); + + TileXRCcuPfeInstall pfe; + pfe.dieId = 1; + pfe.pfeOffset = 7; + for (uint32_t i = 0; i < TILEXR_CCU_PFE_CTX_BYTES; ++i) { + pfe.ctx.raw[i] = static_cast(0xa0 + i); + } + lowerLayer.pfes.push_back(pfe); + + TileXRCcuJettyInstall jetty; + jetty.dieId = 1; + jetty.startJettyCtxId = 9; + jetty.ctxs.resize(2); + for (uint32_t i = 0; i < TILEXR_CCU_LOCAL_JETTY_CTX_BYTES; ++i) { + jetty.ctxs[0].raw[i] = static_cast(0x10 + i); + jetty.ctxs[1].raw[i] = static_cast(0x50 + i); + } + lowerLayer.jettys.push_back(jetty); + + TileXRCcuChannelInstall channel; + channel.dieId = 1; + channel.channelId = 11; + for (uint32_t i = 0; i < TILEXR_CCU_CHANNEL_CTX_V1_BYTES; ++i) { + channel.ctx.raw[i] = static_cast(0xc0 + i); + } + lowerLayer.channels.push_back(channel); + lowerLayer.xnClears.push_back({1, 32, 10}); + lowerLayer.ckeClears.push_back({1, 16, 10}); + + TileXRCcuRepositoryInstallReceipt receipt; + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport installReport; + TileXRCcuInstallRequest request; + request.package = &package; + request.manifest = &manifest; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = false; + request.driverAdapter = &adapter; + request.repositoryMemoryOps = memoryOps; + request.repositoryMemoryUserData = &state; + request.repositoryReceipt = &receipt; + request.lowerLayerPlan = &lowerLayer; + + if (TileXRCcuInstallHardware(request, &evidence, &installReport) != TILEXR_ERROR_NOT_FOUND) { + std::cerr << "partial lower-layer install should not unlock submit gate: " + << installReport.message << "\n"; + return 5; + } + if (!installReport.installAttempted || !installReport.installSucceeded || + installReport.publicVerifiedInstallSurfaceCount != 4 || + installReport.missingInstallSurfaceCount != 2) { + std::cerr << "lower-layer install report mismatch\n"; + return 6; + } + if (!evidence.repositoryInstalled || !evidence.missionInstalled || !evidence.localXnInstalled || + !evidence.notifyCkeInstalled || evidence.channelBindingsInstalled || + evidence.remoteXnBound) { + std::cerr << "unexpected evidence bits after lower-layer install\n"; + return 7; + } + if (evidence.repositorySource.installAttemptReceiptId != installReport.installAttemptReceiptId || + evidence.missionSource.installAttemptReceiptId != installReport.installAttemptReceiptId || + evidence.localXnSource.installAttemptReceiptId != installReport.installAttemptReceiptId || + evidence.notifyCkeSource.installAttemptReceiptId != installReport.installAttemptReceiptId) { + std::cerr << "lower-layer evidence receipts mismatch\n"; + return 8; + } + if (evidence.missionSource.detail.find("launch task descriptor") == std::string::npos || + evidence.missionSource.detail.find("mission key") == std::string::npos || + evidence.localXnSource.detail.find("SET_XN") == std::string::npos || + evidence.notifyCkeSource.detail.find("SET_CKE") == std::string::npos || + evidence.channelBindingSource.kind != TileXRCcuEvidenceKind::Missing || + evidence.channelBindingSource.detail.find("channel binding install evidence is missing") == + std::string::npos || + installReport.channelBinding.satisfied || + installReport.channelBinding.message.find("channel binding endpoint route provenance was not verified") == + std::string::npos) { + std::cerr << "lower-layer evidence detail is weak\n"; + return 9; + } + + if (state.calls.size() != 9 || + state.calls[0].op != TILEXR_CCU_U_OP_SET_INSTRUCTION || + state.calls[1].op != TILEXR_CCU_U_OP_SET_MSID_TOKEN || + state.calls[2].op != TILEXR_CCU_U_OP_SET_PFE || + state.calls[3].op != TILEXR_CCU_U_OP_SET_JETTY_CTX || + state.calls[4].op != TILEXR_CCU_U_OP_SET_CHANNEL || + state.calls[5].op != TILEXR_CCU_U_OP_SET_XN || + state.calls[6].op != TILEXR_CCU_U_OP_SET_XN || + state.calls[7].op != TILEXR_CCU_U_OP_SET_CKE || + state.calls[8].op != TILEXR_CCU_U_OP_SET_CKE) { + std::cerr << "unexpected lower-layer call sequence\n"; + return 10; + } + if (state.calls[1].msId != 0x45 || state.calls[1].tokenId != 0x1234 || + state.calls[1].tokenValue != 0x5678) { + std::cerr << "MSID token request mismatch\n"; + return 11; + } + if (state.calls[2].offset != 7 || state.calls[2].dataLen != TILEXR_CCU_PFE_CTX_BYTES || + std::memcmp(state.calls[2].raw, pfe.ctx.raw, TILEXR_CCU_PFE_CTX_BYTES) != 0) { + std::cerr << "PFE request mismatch\n"; + return 12; + } + if (state.calls[3].offset != 9 || + state.calls[3].dataLen != 2 * TILEXR_CCU_LOCAL_JETTY_CTX_BYTES || + std::memcmp(state.calls[3].raw, jetty.ctxs[0].raw, TILEXR_CCU_LOCAL_JETTY_CTX_BYTES) != 0 || + std::memcmp( + state.calls[3].raw + TILEXR_CCU_DATA_ARRAY_SLOT_BYTES, + jetty.ctxs[1].raw, + TILEXR_CCU_LOCAL_JETTY_CTX_BYTES) != 0) { + std::cerr << "Jetty request mismatch\n"; + return 13; + } + if (state.calls[4].offset != 11 || + state.calls[4].dataLen != TILEXR_CCU_CHANNEL_CTX_V1_BYTES || + std::memcmp(state.calls[4].raw, channel.ctx.raw, TILEXR_CCU_CHANNEL_CTX_V1_BYTES) != 0) { + std::cerr << "Channel request mismatch\n"; + return 14; + } + if (state.calls[5].offset != 32 || state.calls[5].arraySize != 8 || + state.calls[6].offset != 40 || state.calls[6].arraySize != 2) { + std::cerr << "XN batching mismatch\n"; + return 15; + } + if (state.calls[7].offset != 16 || state.calls[7].arraySize != 8 || + state.calls[8].offset != 24 || state.calls[8].arraySize != 2) { + std::cerr << "CKE batching mismatch\n"; + return 16; + } + + std::vector submitTasks; + TileXRCcuProviderReport providerReport; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &providerReport) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "partial lower-layer evidence became submit-ready\n"; + return 17; + } + if (providerReport.message.find("remote XN") == std::string::npos || + providerReport.message.find("missing") == std::string::npos) { + std::cerr << "submit rejection diagnostic is weak: " << providerReport.message << "\n"; + return 18; + } + + TileXRCcuRepositoryReport releaseReport; + if (TileXRCcuReleaseRepositoryInstallReceipt(receipt, memoryOps, &state, &releaseReport) != + TILEXR_SUCCESS || !state.freed) { + std::cerr << "release failed: " << releaseReport.message << "\n"; + return 19; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_online_install_provider_promotes_remote_xn_when_peer_exchange_matches_sync_resources(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + #include + #include + + using namespace TileXR; + + struct ObservedCall { + uint32_t op = 0; + uint32_t offset = 0; + }; + + struct FakeState { + std::vector deviceBytes; + std::vector calls; + bool freed = false; + }; + + int FakeAlloc(uint64_t bytes, void** ptr, void* userData) + { + auto* state = static_cast(userData); + state->deviceBytes.assign(static_cast(bytes), 0); + *ptr = state->deviceBytes.data(); + return 0; + } + + int FakeCopy(void* dst, uint64_t dstBytes, const void* src, uint64_t bytes, void* userData) + { + auto* state = static_cast(userData); + if (dst != state->deviceBytes.data() || dstBytes != state->deviceBytes.size() || + bytes != state->deviceBytes.size()) { + return -1; + } + std::memcpy(dst, src, static_cast(bytes)); + return 0; + } + + int FakeFree(void*, void* userData) + { + auto* state = static_cast(userData); + state->freed = true; + return 0; + } + + int FakeCustomChannel( + uint32_t, + const TileXRCcuCustomChannelIn& in, + TileXRCcuCustomChannelOut* out, + void* userData) + { + auto* state = static_cast(userData); + state->calls.push_back({in.op, in.offsetStartIdx}); + out->opRet = 0; + return 0; + } + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 3}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 365, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 366, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + TileXRCcuLowerLayerInstallPlan MakeLowerLayer(bool staleRemoteXn) + { + TileXRCcuLowerLayerInstallPlan lowerLayer; + lowerLayer.msidTokens.push_back({1, 0x45, 0x1234, 0x5678}); + + TileXRCcuPfeInstall pfe; + pfe.dieId = 1; + pfe.pfeOffset = 2; + pfe.ctx.raw[0] = 0xa0; + lowerLayer.pfes.push_back(pfe); + + TileXRCcuJettyInstall jetty; + jetty.dieId = 1; + jetty.startJettyCtxId = 9; + jetty.ctxs.resize(1); + jetty.ctxs[0].raw[0] = 0xb0; + lowerLayer.jettys.push_back(jetty); + + for (uint32_t i = 0; i < 3; ++i) { + TileXRCcuChannelInstall channel; + channel.dieId = 1; + channel.channelId = 2 + i; + channel.ctx.raw[0] = 0xc0 + i; + lowerLayer.channels.push_back(channel); + } + + lowerLayer.xnClears.push_back({1, 1961, 3}); + lowerLayer.ckeClears.push_back({1, 332, 3}); + + lowerLayer.remoteXnBindings.push_back( + {1, 2, 1961, staleRemoteXn ? 2369 : 2361, 364, 0, true, 0, true, true, true}); + lowerLayer.remoteXnBindings.push_back({1, 3, 1962, 2362, 365, 0, true, 0, true, true, true}); + lowerLayer.remoteXnBindings.push_back({1, 4, 1963, 2364, 366, 0, true, 0, true, true, true}); + return lowerLayer; + } + + int RunInstall(const TileXRCcuLaunchPackage& package, + const TileXRCcuInstallManifest& manifest, + const TileXRCcuLowerLayerInstallPlan& lowerLayer, + FakeState* state, + TileXRCcuHardwareInstallEvidence* evidence, + TileXRCcuInstallProviderReport* installReport) + { + TileXRCcuDriverAdapter adapter; + TileXRCcuDriverAdapterReport driverReport; + if (adapter.Init(5, FakeCustomChannel, state, &driverReport) != TILEXR_SUCCESS) { + std::cerr << "adapter init failed\n"; + return 100; + } + + TileXRCcuDeviceMemoryOps memoryOps; + memoryOps.alloc = FakeAlloc; + memoryOps.copyHostToDevice = FakeCopy; + memoryOps.free = FakeFree; + + TileXRCcuRepositoryInstallReceipt receipt; + TileXRCcuInstallRequest request; + request.package = &package; + request.manifest = &manifest; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = false; + request.driverAdapter = &adapter; + request.repositoryMemoryOps = memoryOps; + request.repositoryMemoryUserData = state; + request.repositoryReceipt = &receipt; + request.lowerLayerPlan = &lowerLayer; + + const int ret = TileXRCcuInstallHardware(request, evidence, installReport); + TileXRCcuRepositoryReport releaseReport; + if (receipt.deviceInstructionAddr != 0 && + TileXRCcuReleaseRepositoryInstallReceipt(receipt, memoryOps, state, &releaseReport) != + TILEXR_SUCCESS) { + std::cerr << "release failed: " << releaseReport.message << "\n"; + return 101; + } + return ret; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport manifestReport; + if (TileXRCcuBuildInstallManifest(package, &manifest, &manifestReport) != TILEXR_SUCCESS) { + std::cerr << "manifest build failed: " << manifestReport.message << "\n"; + return 3; + } + + FakeState staleState; + TileXRCcuHardwareInstallEvidence staleEvidence; + TileXRCcuInstallProviderReport staleReport; + TileXRCcuLowerLayerInstallPlan staleLowerLayer = MakeLowerLayer(true); + if (RunInstall(package, manifest, staleLowerLayer, &staleState, &staleEvidence, &staleReport) != + TILEXR_ERROR_NOT_FOUND) { + std::cerr << "stale remote XN proof should not complete install\n"; + return 4; + } + if (staleEvidence.remoteXnBound || staleReport.remoteXn.satisfied || + staleReport.publicVerifiedInstallSurfaceCount != 5 || + staleReport.missingInstallSurfaceCount != 1 || + staleReport.remoteXn.message.find("remote XN peer exchange proof") == std::string::npos) { + std::cerr << "stale remote XN proof was accepted or weakly diagnosed: " + << staleReport.remoteXn.message << "\n"; + return 5; + } + + FakeState state; + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport installReport; + TileXRCcuLowerLayerInstallPlan lowerLayer = MakeLowerLayer(false); + if (RunInstall(package, manifest, lowerLayer, &state, &evidence, &installReport) != + TILEXR_SUCCESS) { + std::cerr << "complete remote XN proof should complete install: " + << installReport.message << "\n"; + return 6; + } + if (!installReport.installAttempted || !installReport.installSucceeded || + installReport.publicVerifiedInstallSurfaceCount != 6 || + installReport.missingInstallSurfaceCount != 0) { + std::cerr << "complete install report mismatch\n"; + return 7; + } + if (!evidence.repositoryInstalled || !evidence.missionInstalled || + !evidence.localXnInstalled || !evidence.remoteXnBound || + !evidence.notifyCkeInstalled || !evidence.channelBindingsInstalled) { + std::cerr << "complete install evidence mismatch\n"; + return 8; + } + if (evidence.remoteXnSource.source.find("ValidateRemoteXnExchangeBindingProof") == + std::string::npos || + evidence.remoteXnSource.detail.find("peer exchange") == std::string::npos || + evidence.remoteXnSource.detail.find("verified endpoint route channel contexts") == + std::string::npos || + evidence.remoteXnSource.detail.find("channel resource owner") == std::string::npos || + evidence.remoteXnSource.detail.find("transport resource exchange") == std::string::npos || + !evidence.remoteXnSource.endpointRouteVerified) { + std::cerr << "remote XN evidence detail is weak\n"; + return 9; + } + + std::vector submitTasks; + TileXRCcuProviderReport providerReport; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &providerReport) != + TILEXR_SUCCESS) { + std::cerr << "submit preparation failed: " << providerReport.message << "\n"; + return 10; + } + if (!providerReport.submitReady || submitTasks.size() != package.tasks.size()) { + std::cerr << "submit readiness mismatch\n"; + return 11; + } + if (state.calls.size() != 9 || + state.calls[0].op != TILEXR_CCU_U_OP_SET_INSTRUCTION || + state.calls[4].op != TILEXR_CCU_U_OP_SET_CHANNEL || + state.calls[5].op != TILEXR_CCU_U_OP_SET_CHANNEL || + state.calls[6].op != TILEXR_CCU_U_OP_SET_CHANNEL || + state.calls[7].op != TILEXR_CCU_U_OP_SET_XN || + state.calls[8].op != TILEXR_CCU_U_OP_SET_CKE) { + std::cerr << "unexpected complete install call sequence\n"; + return 12; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_lower_layer_first_repository_failure_reports_installed_preconditions(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + #include + #include + + using namespace TileXR; + + struct ObservedCall { + uint32_t op = 0; + }; + + struct FakeState { + std::vector deviceBytes; + std::vector calls; + bool freed = false; + }; + + int FakeAlloc(uint64_t bytes, void** ptr, void* userData) + { + auto* state = static_cast(userData); + state->deviceBytes.assign(static_cast(bytes), 0); + *ptr = state->deviceBytes.data(); + return 0; + } + + int FakeCopy(void* dst, uint64_t dstBytes, const void* src, uint64_t bytes, void* userData) + { + auto* state = static_cast(userData); + if (dst != state->deviceBytes.data() || dstBytes != state->deviceBytes.size() || + bytes != state->deviceBytes.size()) { + return -1; + } + std::memcpy(dst, src, static_cast(bytes)); + return 0; + } + + int FakeFree(void*, void* userData) + { + auto* state = static_cast(userData); + state->freed = true; + return 0; + } + + int FakeCustomChannel( + uint32_t, + const TileXRCcuCustomChannelIn& in, + TileXRCcuCustomChannelOut* out, + void* userData) + { + auto* state = static_cast(userData); + state->calls.push_back({in.op}); + out->opRet = in.op == TILEXR_CCU_U_OP_SET_INSTRUCTION ? 0x51 : 0; + return 0; + } + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 365, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 366, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + TileXRCcuLowerLayerInstallPlan MakeLowerLayer() + { + TileXRCcuLowerLayerInstallPlan lowerLayer; + lowerLayer.msidTokens.push_back({1, 0x45, 0x1234, 0x5678}); + + TileXRCcuPfeInstall pfe; + pfe.dieId = 1; + pfe.pfeOffset = 2; + pfe.ctx.raw[0] = 0xa0; + lowerLayer.pfes.push_back(pfe); + + TileXRCcuJettyInstall jetty; + jetty.dieId = 1; + jetty.startJettyCtxId = 9; + jetty.ctxs.resize(1); + jetty.ctxs[0].raw[0] = 0xb0; + lowerLayer.jettys.push_back(jetty); + + for (uint32_t i = 0; i < 3; ++i) { + TileXRCcuChannelInstall channel; + channel.dieId = 1; + channel.channelId = 2 + i; + channel.ctx.raw[0] = static_cast(0xc0 + i); + lowerLayer.channels.push_back(channel); + } + + lowerLayer.xnClears.push_back({1, 1961, 3}); + lowerLayer.ckeClears.push_back({1, 332, 3}); + lowerLayer.remoteXnBindings.push_back({1, 2, 1961, 2361, 364, 0, true, 0, true}); + lowerLayer.remoteXnBindings.push_back({1, 3, 1962, 2362, 365, 0, true, 0, true}); + lowerLayer.remoteXnBindings.push_back({1, 4, 1963, 2364, 366, 0, true, 0, true}); + return lowerLayer; + } + + bool Contains(const std::string& text, const char* needle) + { + return text.find(needle) != std::string::npos; + } + + bool Contains(const std::string& text, const std::string& needle) + { + return text.find(needle) != std::string::npos; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport manifestReport; + if (TileXRCcuBuildInstallManifest(package, &manifest, &manifestReport) != TILEXR_SUCCESS) { + std::cerr << "manifest build failed: " << manifestReport.message << "\n"; + return 3; + } + + FakeState state; + TileXRCcuDriverAdapter adapter; + TileXRCcuDriverAdapterReport driverReport; + if (adapter.Init(5, FakeCustomChannel, &state, &driverReport) != TILEXR_SUCCESS) { + std::cerr << "adapter init failed\n"; + return 4; + } + + TileXRCcuDeviceMemoryOps memoryOps; + memoryOps.alloc = FakeAlloc; + memoryOps.copyHostToDevice = FakeCopy; + memoryOps.free = FakeFree; + + TileXRCcuLowerLayerInstallPlan lowerLayer = MakeLowerLayer(); + TileXRCcuRepositoryInstallReceipt receipt; + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport installReport; + TileXRCcuInstallRequest request; + request.package = &package; + request.manifest = &manifest; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = false; + request.driverAdapter = &adapter; + request.repositoryMemoryOps = memoryOps; + request.repositoryMemoryUserData = &state; + request.repositoryReceipt = &receipt; + request.installOrder = TileXRCcuInstallOrder::InstallLowerLayerFirst; + request.lowerLayerPlan = &lowerLayer; + + if (TileXRCcuInstallHardware(request, &evidence, &installReport) != TILEXR_ERROR_MKIRT) { + std::cerr << "repository failure should propagate MKIRT: " << installReport.message << "\n"; + return 5; + } + if (!installReport.installAttempted || installReport.installSucceeded || + installReport.publicVerifiedInstallSurfaceCount != 0 || + installReport.missingInstallSurfaceCount != 6) { + std::cerr << "repository failure report counts mismatch\n"; + return 6; + } + if (evidence.repositoryInstalled || evidence.localXnInstalled || + evidence.remoteXnBound || evidence.notifyCkeInstalled || + evidence.channelBindingsInstalled || evidence.missionInstalled) { + std::cerr << "failed repository install leaked hardware evidence\n"; + return 7; + } + std::vector submitTasks; + TileXRCcuProviderReport providerReport; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &providerReport) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "failed repository install released submit gate\n"; + return 8; + } + if (providerReport.submitReady || !submitTasks.empty()) { + std::cerr << "failed repository install leaked submit-ready state\n"; + return 9; + } + if (state.calls.size() < 9 || + state.calls[0].op != TILEXR_CCU_U_OP_SET_MSID_TOKEN || + state.calls[1].op != TILEXR_CCU_U_OP_SET_PFE || + state.calls[2].op != TILEXR_CCU_U_OP_SET_JETTY_CTX || + state.calls[3].op != TILEXR_CCU_U_OP_SET_CHANNEL || + state.calls[4].op != TILEXR_CCU_U_OP_SET_CHANNEL || + state.calls[5].op != TILEXR_CCU_U_OP_SET_CHANNEL || + state.calls[6].op != TILEXR_CCU_U_OP_SET_XN || + state.calls[7].op != TILEXR_CCU_U_OP_SET_CKE || + state.calls[8].op != TILEXR_CCU_U_OP_SET_INSTRUCTION) { + std::cerr << "lower-layer-first call sequence mismatch\n"; + return 10; + } + for (size_t i = 9; i < state.calls.size(); ++i) { + if (state.calls[i].op != TILEXR_CCU_U_OP_GET_INSTRUCTION) { + std::cerr << "repository failure diagnostic readback sequence mismatch\n"; + return 10; + } + } + if (!state.freed || receipt.deviceInstructionPtr != nullptr || receipt.installed) { + std::cerr << "failed repository install did not release uploaded image\n"; + return 11; + } + const std::string summaryNeedles[] = { + "lowerLayerPreconditions{", + "msidTokenCount=1", + "pfeCount=1", + "jettyCount=1", + "channelCount=3", + "xnClearCount=1", + "ckeClearCount=1", + "localXnInstalled=1", + "notifyCkeInstalled=1", + "channelBindingInstalled=1", + "msidToken0{dieId=1 msId=69 tokenId=0x1234 tokenValue=0x5678}", + "pfe0{dieId=1 offset=2}", + "jetty0{dieId=1 startJettyCtxId=9 ctxCount=1}", + "channel0{dieId=1 channelId=2}", + "xnClear0{dieId=1 startXnId=1961 count=3}", + "ckeClear0{dieId=1 startCkeId=332 count=3}", + "remoteXn0{dieId=1 channelId=2 localXn=1961 remoteXn=2361 notifyCke=364", + }; + for (const auto& needle : summaryNeedles) { + if (!Contains(installReport.message, needle)) { + std::cerr << "missing lower-layer precondition summary: " << needle + << " in " << installReport.message << "\n"; + return 12; + } + } + if (!Contains(installReport.message, "CCU custom channel operation failed op=") || + !Contains(installReport.message, "opRet=81")) { + std::cerr << "repository failure context is missing: " << installReport.message << "\n"; + return 13; + } + if (!Contains(installReport.localXn.message, "lowerLayerPreconditions{") || + !Contains(installReport.remoteXn.message, "lowerLayerPreconditions{") || + !Contains(installReport.notifyCke.message, "lowerLayerPreconditions{") || + !Contains(installReport.channelBinding.message, "lowerLayerPreconditions{")) { + std::cerr << "lower-layer step messages lost precondition summary\n"; + return 14; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_remote_xn_proof_checks_remote_notify_and_local_wait_cke(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + #include + #include + + using namespace TileXR; + + struct FakeState { + std::vector deviceBytes; + }; + + int FakeAlloc(uint64_t bytes, void** ptr, void* userData) + { + auto* state = static_cast(userData); + state->deviceBytes.assign(static_cast(bytes), 0); + *ptr = state->deviceBytes.data(); + return 0; + } + + int FakeCopy(void* dst, uint64_t dstBytes, const void* src, uint64_t bytes, void* userData) + { + auto* state = static_cast(userData); + if (dst != state->deviceBytes.data() || dstBytes != state->deviceBytes.size() || + bytes != state->deviceBytes.size()) { + return -1; + } + std::memcpy(dst, src, static_cast(bytes)); + return 0; + } + + int FakeFree(void*, void*) + { + return 0; + } + + int FakeCustomChannel(uint32_t, const TileXRCcuCustomChannelIn&, TileXRCcuCustomChannelOut* out, void*) + { + out->opRet = 0; + return 0; + } + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 4}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + + TileXRCcuSyncResource resource; + resource.dieId = 1; + resource.localXn = 1961; + resource.remoteXn = 2361; + resource.notifyCke = 364; + resource.channelId = 2; + resource.bindingCount = 3; + resource.localWaitCke = 332; + resource.localWaitMask = 1; + resource.remoteNotifyMask = 1; + plan.syncResources.push_back(resource); + + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + TileXRCcuLowerLayerInstallPlan MakeLowerLayer(uint16_t remoteNotifyCke, uint16_t localWaitCke) + { + TileXRCcuLowerLayerInstallPlan lowerLayer; + lowerLayer.msidTokens.push_back({1, 0x45, 0x1234, 0x5678}); + + TileXRCcuPfeInstall pfe; + pfe.dieId = 1; + pfe.pfeOffset = 2; + pfe.ctx.raw[0] = 0xa0; + lowerLayer.pfes.push_back(pfe); + + TileXRCcuJettyInstall jetty; + jetty.dieId = 1; + jetty.startJettyCtxId = 9; + jetty.ctxs.resize(1); + jetty.ctxs[0].raw[0] = 0xb0; + lowerLayer.jettys.push_back(jetty); + + TileXRCcuChannelInstall channel; + channel.dieId = 1; + channel.channelId = 2; + channel.ctx.raw[0] = 0xc0; + lowerLayer.channels.push_back(channel); + + lowerLayer.xnClears.push_back({1, 1961, 1}); + lowerLayer.ckeClears.push_back({1, 332, 4}); + + TileXRCcuRemoteXnBindingProof proof; + proof.dieId = 1; + proof.channelId = 2; + proof.localXn = 1961; + proof.remoteXn = 2361; + proof.notifyCke = remoteNotifyCke; + proof.localWaitCke = localWaitCke; + proof.peerRank = 0; + proof.peerExchangeObserved = true; + proof.endpointRouteVerified = true; + proof.channelResourceOwnerVerified = true; + proof.transportResourceExchangeVerified = true; + lowerLayer.remoteXnBindings.push_back(proof); + return lowerLayer; + } + + int RunInstall( + const TileXRCcuLaunchPackage& package, + const TileXRCcuInstallManifest& manifest, + const TileXRCcuLowerLayerInstallPlan& lowerLayer, + TileXRCcuInstallProviderReport* report) + { + FakeState state; + TileXRCcuDriverAdapter adapter; + TileXRCcuDriverAdapterReport driverReport; + if (adapter.Init(5, FakeCustomChannel, &state, &driverReport) != TILEXR_SUCCESS) { + return TILEXR_ERROR_INTERNAL; + } + + TileXRCcuDeviceMemoryOps memoryOps; + memoryOps.alloc = FakeAlloc; + memoryOps.copyHostToDevice = FakeCopy; + memoryOps.free = FakeFree; + + TileXRCcuRepositoryInstallReceipt receipt; + TileXRCcuInstallRequest request; + request.package = &package; + request.manifest = &manifest; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = false; + request.driverAdapter = &adapter; + request.repositoryMemoryOps = memoryOps; + request.repositoryMemoryUserData = &state; + request.repositoryReceipt = &receipt; + request.lowerLayerPlan = &lowerLayer; + + TileXRCcuHardwareInstallEvidence evidence; + return TileXRCcuInstallHardware(request, &evidence, report); + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport manifestReport; + if (TileXRCcuBuildInstallManifest(package, &manifest, &manifestReport) != TILEXR_SUCCESS) { + std::cerr << "manifest build failed: " << manifestReport.message << "\n"; + return 3; + } + + TileXRCcuInstallProviderReport staleLocalWait; + if (RunInstall(package, manifest, MakeLowerLayer(364, 333), &staleLocalWait) != + TILEXR_ERROR_NOT_FOUND) { + std::cerr << "stale local wait CKE proof was accepted\n"; + return 4; + } + if (staleLocalWait.remoteXn.satisfied || + staleLocalWait.remoteXn.message.find("local wait CKE") == std::string::npos) { + std::cerr << "local wait CKE diagnostic was weak: " + << staleLocalWait.remoteXn.message << "\n"; + return 5; + } + + TileXRCcuInstallProviderReport staleRemoteNotify; + if (RunInstall(package, manifest, MakeLowerLayer(365, 332), &staleRemoteNotify) != + TILEXR_ERROR_NOT_FOUND) { + std::cerr << "stale remote notify CKE proof was accepted\n"; + return 6; + } + if (staleRemoteNotify.remoteXn.satisfied || + staleRemoteNotify.remoteXn.message.find("remote notify CKE") == std::string::npos) { + std::cerr << "remote notify CKE diagnostic was weak: " + << staleRemoteNotify.remoteXn.message << "\n"; + return 7; + } + + TileXRCcuInstallProviderReport ok; + if (RunInstall(package, manifest, MakeLowerLayer(364, 332), &ok) != TILEXR_SUCCESS || + !ok.remoteXn.satisfied) { + std::cerr << "complete dual CKE proof was rejected: " << ok.message << "\n"; + return 8; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_online_install_provider_rejects_stale_mission_launch_descriptor_proof(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + #include + #include + + using namespace TileXR; + + struct FakeState { + std::vector deviceBytes; + uint32_t observedOp = 0; + }; + + int FakeAlloc(uint64_t bytes, void** ptr, void* userData) + { + auto* state = static_cast(userData); + state->deviceBytes.assign(static_cast(bytes), 0); + *ptr = state->deviceBytes.data(); + return 0; + } + + int FakeCopy(void* dst, uint64_t dstBytes, const void* src, uint64_t bytes, void* userData) + { + auto* state = static_cast(userData); + if (dst != state->deviceBytes.data() || dstBytes != state->deviceBytes.size() || + bytes != state->deviceBytes.size()) { + return -1; + } + std::memcpy(dst, src, static_cast(bytes)); + return 0; + } + + int FakeFree(void*, void*) + { + return 0; + } + + int FakeCustomChannel( + uint32_t, + const TileXRCcuCustomChannelIn& in, + TileXRCcuCustomChannelOut* out, + void* userData) + { + auto* state = static_cast(userData); + state->observedOp = in.op; + out->opRet = 0; + return 0; + } + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + + package.tasks[0].key ^= 0x1U; + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport manifestReport; + if (TileXRCcuBuildInstallManifest(package, &manifest, &manifestReport) != TILEXR_SUCCESS) { + std::cerr << "manifest build failed: " << manifestReport.message << "\n"; + return 3; + } + + FakeState state; + TileXRCcuDriverAdapter adapter; + TileXRCcuDriverAdapterReport driverReport; + if (adapter.Init(5, FakeCustomChannel, &state, &driverReport) != TILEXR_SUCCESS) { + std::cerr << "adapter init failed\n"; + return 4; + } + + TileXRCcuDeviceMemoryOps memoryOps; + memoryOps.alloc = FakeAlloc; + memoryOps.copyHostToDevice = FakeCopy; + memoryOps.free = FakeFree; + + TileXRCcuRepositoryInstallReceipt receipt; + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport installReport; + TileXRCcuInstallRequest request; + request.package = &package; + request.manifest = &manifest; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = false; + request.driverAdapter = &adapter; + request.repositoryMemoryOps = memoryOps; + request.repositoryMemoryUserData = &state; + request.repositoryReceipt = &receipt; + + if (TileXRCcuInstallHardware(request, &evidence, &installReport) != TILEXR_ERROR_NOT_FOUND) { + std::cerr << "stale mission descriptor should leave install incomplete: " + << installReport.message << "\n"; + return 5; + } + if (!installReport.repository.satisfied || installReport.mission.satisfied || + !evidence.repositoryInstalled || evidence.missionInstalled) { + std::cerr << "stale mission descriptor was promoted\n"; + return 6; + } + if (installReport.publicVerifiedInstallSurfaceCount != 1 || + installReport.missingInstallSurfaceCount != 5) { + std::cerr << "stale descriptor install counts mismatch\n"; + return 7; + } + if (evidence.missionSource.kind != TileXRCcuEvidenceKind::Missing || + installReport.mission.message.find("launch task descriptor") == std::string::npos || + installReport.mission.message.find("mission key") == std::string::npos) { + std::cerr << "stale descriptor diagnostic is weak: " + << installReport.mission.message << "\n"; + return 8; + } + if (state.observedOp != TILEXR_CCU_U_OP_SET_INSTRUCTION) { + std::cerr << "repository install did not run before descriptor proof\n"; + return 9; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_install_evidence_adapter_keeps_offline_candidates_not_submit_ready(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + TileXRCcuInstallStepEvidence Candidate(const char* source, const char* detail) + { + TileXRCcuInstallStepEvidence step; + step.satisfied = true; + step.source.kind = TileXRCcuEvidenceKind::PublicCandidate; + step.source.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + step.source.source = source; + step.source.detail = detail; + step.message = detail; + return step; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 8; + } + + TileXRCcuInstallProviderReport installReport; + installReport.offlineOnly = true; + installReport.mission = Candidate("scan:mission", "public-looking mission candidate"); + installReport.repository = Candidate("scan:repository", "public-looking repository candidate"); + installReport.localXn = Candidate("scan:local-xn", "public-looking local XN candidate"); + installReport.remoteXn = Candidate("scan:remote-xn", "public-looking remote XN candidate"); + installReport.notifyCke = Candidate("scan:notify-cke", "public-looking notify CKE candidate"); + installReport.channelBinding = Candidate("scan:channel", "public-looking channel candidate"); + + TileXRCcuHardwareInstallEvidence evidence; + if (TileXRCcuBuildInstallEvidence(installReport, &evidence) != TILEXR_SUCCESS) { + std::cerr << "adapter rejected candidate report\n"; + return 2; + } + if (!evidence.missionInstalled || !evidence.repositoryInstalled || !evidence.localXnInstalled || + !evidence.remoteXnBound || !evidence.notifyCkeInstalled || !evidence.channelBindingsInstalled) { + std::cerr << "adapter dropped candidate evidence unexpectedly\n"; + return 3; + } + if (evidence.missionSource.kind != TileXRCcuEvidenceKind::PublicCandidate || + evidence.channelBindingSource.kind != TileXRCcuEvidenceKind::PublicCandidate) { + std::cerr << "adapter upgraded/downgraded candidate evidence unexpectedly\n"; + return 4; + } + + std::vector submitTasks; + TileXRCcuProviderReport providerReport; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &providerReport) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "offline public candidates became submit-ready\n"; + return 5; + } + if (!submitTasks.empty() || providerReport.submitReady) { + std::cerr << "failed candidate prepare leaked submit-ready state\n"; + return 6; + } + if (providerReport.message.find("candidate") == std::string::npos || + providerReport.message.find("public install provider") == std::string::npos) { + std::cerr << "weak candidate diagnostic: " << providerReport.message << "\n"; + return 7; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_install_evidence_adapter_does_not_accept_offline_public_verified_claims(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuInstallStepEvidence ForgedVerified(const char* source, const char* detail) + { + TileXRCcuInstallStepEvidence step; + step.satisfied = true; + step.source.kind = TileXRCcuEvidenceKind::PublicVerified; + step.source.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + step.source.source = source; + step.source.detail = detail; + step.message = detail; + return step; + } + + int main() + { + TileXRCcuInstallProviderReport installReport; + installReport.offlineOnly = true; + installReport.mission = ForgedVerified("forged:mission", "forged mission/key evidence"); + installReport.repository = ForgedVerified("forged:repository", "forged repository evidence"); + installReport.localXn = ForgedVerified("forged:local-xn", "forged local XN evidence"); + installReport.remoteXn = ForgedVerified("forged:remote-xn", "forged remote XN evidence"); + installReport.notifyCke = ForgedVerified("forged:notify-cke", "forged notify CKE evidence"); + installReport.channelBinding = ForgedVerified("forged:channel", "forged channel binding evidence"); + + TileXRCcuHardwareInstallEvidence evidence; + if (TileXRCcuBuildInstallEvidence(installReport, &evidence) != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "offline public verified install claims were accepted\n"; + return 1; + } + if (evidence.missionInstalled || evidence.repositoryInstalled || evidence.localXnInstalled || + evidence.remoteXnBound || evidence.notifyCkeInstalled || evidence.channelBindingsInstalled) { + std::cerr << "failed offline verified adapter left install evidence\n"; + return 2; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_install_evidence_adapter_requires_consistent_online_receipt(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuInstallStepEvidence VerifiedStep( + const char* source, + const char* detail, + uint64_t receipt) + { + TileXRCcuInstallStepEvidence step; + step.satisfied = true; + step.source.kind = TileXRCcuEvidenceKind::PublicVerified; + step.source.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + step.source.packageFingerprint = 0xfeed001ULL; + step.source.deviceId = 3; + step.source.rank = 1; + step.source.provider = "unit-test-public-install-provider"; + step.source.source = source; + step.source.detail = detail; + step.source.installAttemptReceiptId = receipt; + step.message = detail; + return step; + } + + TileXRCcuInstallProviderReport VerifiedReport(uint64_t receipt) + { + TileXRCcuInstallProviderReport report; + report.offlineOnly = false; + report.installAttempted = true; + report.installSucceeded = true; + report.installAttemptReceiptId = receipt; + report.mission = VerifiedStep("provider:mission", "mission/key installed", receipt); + report.repository = VerifiedStep("provider:repository", "repository installed", receipt); + report.localXn = VerifiedStep("provider:local-xn", "local XN installed", receipt); + report.remoteXn = VerifiedStep("provider:remote-xn", "remote XN bound", receipt); + report.notifyCke = VerifiedStep("provider:notify-cke", "notify CKE installed", receipt); + report.channelBinding = VerifiedStep("provider:channel", "channel binding installed", receipt); + return report; + } + + int main() + { + TileXRCcuHardwareInstallEvidence evidence; + + TileXRCcuInstallProviderReport missingReceipt = VerifiedReport(0); + if (TileXRCcuBuildInstallEvidence(missingReceipt, &evidence) != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "online public verified report with missing receipt was accepted\n"; + return 1; + } + if (evidence.missionInstalled || evidence.repositoryInstalled || evidence.localXnInstalled || + evidence.remoteXnBound || evidence.notifyCkeInstalled || evidence.channelBindingsInstalled) { + std::cerr << "failed missing receipt adapter left install evidence\n"; + return 2; + } + + TileXRCcuInstallProviderReport mixedReceipt = VerifiedReport(0xabc001ULL); + mixedReceipt.remoteXn.source.installAttemptReceiptId = 0xabc002ULL; + if (TileXRCcuBuildInstallEvidence(mixedReceipt, &evidence) != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "online public verified report with mixed receipts was accepted\n"; + return 3; + } + if (evidence.missionInstalled || evidence.repositoryInstalled || evidence.localXnInstalled || + evidence.remoteXnBound || evidence.notifyCkeInstalled || evidence.channelBindingsInstalled) { + std::cerr << "failed mixed receipt adapter left install evidence\n"; + return 4; + } + + TileXRCcuInstallProviderReport notAttempted = VerifiedReport(0xabc001ULL); + notAttempted.installAttempted = false; + if (TileXRCcuBuildInstallEvidence(notAttempted, &evidence) != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "online public verified report without attempted install was accepted\n"; + return 5; + } + if (evidence.missionInstalled || evidence.repositoryInstalled || evidence.localXnInstalled || + evidence.remoteXnBound || evidence.notifyCkeInstalled || evidence.channelBindingsInstalled) { + std::cerr << "failed not-attempted adapter left install evidence\n"; + return 6; + } + + TileXRCcuInstallProviderReport notSucceeded = VerifiedReport(0xabc001ULL); + notSucceeded.installSucceeded = false; + if (TileXRCcuBuildInstallEvidence(notSucceeded, &evidence) != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "online public verified report without successful install was accepted\n"; + return 7; + } + if (evidence.missionInstalled || evidence.repositoryInstalled || evidence.localXnInstalled || + evidence.remoteXnBound || evidence.notifyCkeInstalled || evidence.channelBindingsInstalled) { + std::cerr << "failed not-succeeded adapter left install evidence\n"; + return 8; + } + + TileXRCcuInstallProviderReport matchingReceipt = VerifiedReport(0xabc001ULL); + if (TileXRCcuBuildInstallEvidence(matchingReceipt, &evidence) != TILEXR_SUCCESS) { + std::cerr << "matching receipt report was rejected\n"; + return 9; + } + if (evidence.missionSource.installAttemptReceiptId != 0xabc001ULL || + evidence.repositorySource.installAttemptReceiptId != 0xabc001ULL || + evidence.localXnSource.installAttemptReceiptId != 0xabc001ULL || + evidence.remoteXnSource.installAttemptReceiptId != 0xabc001ULL || + evidence.notifyCkeSource.installAttemptReceiptId != 0xabc001ULL || + evidence.channelBindingSource.installAttemptReceiptId != 0xabc001ULL) { + std::cerr << "adapter did not preserve matching receipt ids\n"; + return 10; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_install_manifest_from_launch_package_lists_all_required_surfaces(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + const TileXRCcuInstallRequirement* FindRequirement( + const TileXRCcuInstallManifest& manifest, + TileXRCcuInstallRequirementKind kind) + { + for (const auto& requirement : manifest.requirements) { + if (requirement.kind == kind) { + return &requirement; + } + } + return nullptr; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport manifestReport; + if (TileXRCcuBuildInstallManifest(package, &manifest, &manifestReport) != TILEXR_SUCCESS) { + std::cerr << "manifest build failed: " << manifestReport.message << "\n"; + return 3; + } + + const uint64_t fingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + if (manifest.deviceId != 3 || manifest.rank != 1 || + manifest.provider != "unit-test-public-install-provider" || + manifest.packageFingerprint != fingerprint || + !manifest.requiresHardwareInstall || + !manifest.installAttemptReceiptRequired || + manifest.requiredEvidenceKind != TileXRCcuEvidenceKind::PublicVerified || + manifest.requiredEvidenceSurface != TileXRCcuEvidenceSurface::PublicInstallProvider) { + std::cerr << "manifest did not preserve scope/fingerprint/evidence contract\n"; + return 4; + } + if (manifest.requirements.size() != 6 || manifestReport.requirementCount != 6 || + manifestReport.message != "ok") { + std::cerr << "manifest did not list the six required install surfaces\n"; + return 5; + } + + const TileXRCcuInstallRequirement* mission = + FindRequirement(manifest, TileXRCcuInstallRequirementKind::MissionKey); + const TileXRCcuInstallRequirement* repository = + FindRequirement(manifest, TileXRCcuInstallRequirementKind::RepositoryImage); + const TileXRCcuInstallRequirement* localXn = + FindRequirement(manifest, TileXRCcuInstallRequirementKind::LocalXn); + const TileXRCcuInstallRequirement* remoteXn = + FindRequirement(manifest, TileXRCcuInstallRequirementKind::RemoteXnBinding); + const TileXRCcuInstallRequirement* notifyCke = + FindRequirement(manifest, TileXRCcuInstallRequirementKind::NotifyCke); + const TileXRCcuInstallRequirement* channel = + FindRequirement(manifest, TileXRCcuInstallRequirementKind::ChannelBinding); + if (mission == nullptr || repository == nullptr || localXn == nullptr || + remoteXn == nullptr || notifyCke == nullptr || channel == nullptr) { + std::cerr << "manifest missed one or more required install kinds\n"; + return 6; + } + if (mission->missionId != 6 || mission->missionKey != 0x059b0f03U || + mission->resourceStartId != 6 || mission->resourceCount != 1) { + std::cerr << "manifest mission/key requirement is incomplete\n"; + return 7; + } + if (repository->repositoryStartId != 475 || repository->repositoryCount != 170 || + repository->missionStartId != 489 || repository->missionCount != 156 || + repository->instructionCount != 170) { + std::cerr << "manifest repository requirement is incomplete\n"; + return 8; + } + if (localXn->resourceStartId != 1961 || localXn->resourceCount != 62) { + std::cerr << "manifest local XN requirement is incomplete\n"; + return 9; + } + if (remoteXn->syncResourceCount != 3 || notifyCke->syncResourceCount != 3 || + channel->syncResourceCount != 3 || channel->bindingCount != 9) { + std::cerr << "manifest sync resource requirements are incomplete\n"; + return 10; + } + for (const auto& requirement : manifest.requirements) { + if (requirement.packageFingerprint != fingerprint || + requirement.label.empty() || + requirement.detail.empty()) { + std::cerr << "manifest requirement missed audit metadata\n"; + return 11; + } + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_install_manifest_rejects_unbound_or_stale_scope_without_partial_output(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int ExpectManifestFailure( + const TileXRCcuLaunchPackage& package, + const char* diagnostic) + { + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport report; + const int ret = TileXRCcuBuildInstallManifest(package, &manifest, &report); + if (ret != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "manifest build unexpectedly succeeded for " << diagnostic << "\n"; + return 1; + } + if (report.message.find(diagnostic) == std::string::npos) { + std::cerr << "weak manifest diagnostic: " << report.message << "\n"; + return 2; + } + if (!manifest.requirements.empty() || report.requirementCount != 0) { + std::cerr << "failed manifest build left partial requirements\n"; + return 3; + } + return 0; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (ExpectManifestFailure(package, "launch install scope is not bound") != 0) { + return 2; + } + + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 3; + } + package.tasks[0].key ^= 0x1U; + if (ExpectManifestFailure(package, "launch install scope is stale") != 0) { + return 4; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_install_manifest_contract_does_not_make_default_provider_submit_ready(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport manifestReport; + if (TileXRCcuBuildInstallManifest(package, &manifest, &manifestReport) != TILEXR_SUCCESS) { + std::cerr << "manifest build failed: " << manifestReport.message << "\n"; + return 3; + } + + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport installReport; + TileXRCcuInstallRequest request; + request.package = &package; + request.manifest = &manifest; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = false; + if (TileXRCcuInstallHardware(request, &evidence, &installReport) != TILEXR_ERROR_NOT_FOUND) { + std::cerr << "default install provider accepted manifest as installed evidence\n"; + return 4; + } + if (evidence.missionInstalled || evidence.repositoryInstalled || evidence.localXnInstalled || + evidence.remoteXnBound || evidence.notifyCkeInstalled || evidence.channelBindingsInstalled) { + std::cerr << "manifest leaked into install evidence\n"; + return 5; + } + + std::vector submitTasks; + TileXRCcuProviderReport providerReport; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &providerReport) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "manifest-only default provider became submit-ready\n"; + return 6; + } + if (!submitTasks.empty() || providerReport.submitReady || + providerReport.missingEvidenceCount == 0) { + std::cerr << "failed manifest-only prepare leaked submit-ready state\n"; + return 7; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_install_manifest_default_provider_reports_missing_required_surfaces(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport manifestReport; + if (TileXRCcuBuildInstallManifest(package, &manifest, &manifestReport) != TILEXR_SUCCESS) { + std::cerr << "manifest build failed: " << manifestReport.message << "\n"; + return 3; + } + + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport installReport; + TileXRCcuInstallRequest request; + request.package = &package; + request.manifest = &manifest; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = false; + + if (TileXRCcuInstallHardware(request, &evidence, &installReport) != TILEXR_ERROR_NOT_FOUND) { + std::cerr << "default provider did not stop at unsupported install path\n"; + return 4; + } + if (installReport.requiredInstallSurfaceCount != 6 || + installReport.publicVerifiedInstallSurfaceCount != 0 || + installReport.missingInstallSurfaceCount != 6) { + std::cerr << "manifest requirement counts were not reported: required=" + << installReport.requiredInstallSurfaceCount + << " verified=" << installReport.publicVerifiedInstallSurfaceCount + << " missing=" << installReport.missingInstallSurfaceCount << "\n"; + return 5; + } + if (installReport.message.find("no public no-hcomm CCU install provider") == std::string::npos) { + std::cerr << "weak unsupported provider diagnostic: " << installReport.message << "\n"; + return 6; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_install_request_rejects_mismatched_manifest_scope(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int ExpectManifestFailure( + const TileXRCcuInstallRequest& request, + const char* diagnostic) + { + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport report; + const int ret = TileXRCcuInstallHardware(request, &evidence, &report); + if (ret != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "manifest mismatch was not rejected: " << diagnostic << "\n"; + return 1; + } + if (report.message.find(diagnostic) == std::string::npos) { + std::cerr << "weak manifest mismatch diagnostic: " << report.message << "\n"; + return 2; + } + if (evidence.missionInstalled || evidence.repositoryInstalled || evidence.localXnInstalled || + evidence.remoteXnBound || evidence.notifyCkeInstalled || evidence.channelBindingsInstalled) { + std::cerr << "failed manifest mismatch left install evidence\n"; + return 3; + } + return 0; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport manifestReport; + if (TileXRCcuBuildInstallManifest(package, &manifest, &manifestReport) != TILEXR_SUCCESS) { + std::cerr << "manifest build failed: " << manifestReport.message << "\n"; + return 3; + } + + TileXRCcuInstallRequest request; + request.package = &package; + request.manifest = &manifest; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = false; + + TileXRCcuInstallManifest wrongDevice = manifest; + wrongDevice.deviceId = 4; + request.manifest = &wrongDevice; + if (ExpectManifestFailure(request, "install manifest device mismatch") != 0) { + return 4; + } + + TileXRCcuInstallManifest wrongFingerprint = manifest; + wrongFingerprint.packageFingerprint ^= 0x1ULL; + request.manifest = &wrongFingerprint; + if (ExpectManifestFailure(request, "install manifest fingerprint mismatch") != 0) { + return 5; + } + + TileXRCcuInstallManifest wrongRequirementKind = manifest; + wrongRequirementKind.requirements[5].kind = wrongRequirementKind.requirements[0].kind; + request.manifest = &wrongRequirementKind; + if (ExpectManifestFailure(request, "install manifest requirement kind mismatch") != 0) { + return 6; + } + + TileXRCcuInstallManifest wrongHardwareRequirement = manifest; + wrongHardwareRequirement.requiresHardwareInstall = false; + request.manifest = &wrongHardwareRequirement; + if (ExpectManifestFailure(request, "install manifest hardware requirement mismatch") != 0) { + return 7; + } + + TileXRCcuInstallManifest wrongMission = manifest; + wrongMission.requirements[0].missionKey ^= 0x1U; + request.manifest = &wrongMission; + if (ExpectManifestFailure(request, "install manifest mission requirement mismatch") != 0) { + return 8; + } + + TileXRCcuInstallManifest wrongChannel = manifest; + wrongChannel.requirements[5].bindingCount = 1; + request.manifest = &wrongChannel; + if (ExpectManifestFailure(request, "install manifest channel requirement mismatch") != 0) { + return 9; + } + + request.manifest = &manifest; + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport report; + if (TileXRCcuInstallHardware(request, &evidence, &report) != TILEXR_ERROR_NOT_FOUND) { + std::cerr << "matching manifest should reach unsupported provider: " << report.message << "\n"; + return 10; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_install_evidence_adapter_rejects_public_verified_with_bad_surface_or_scope(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuInstallStepEvidence VerifiedStep( + const char* source, + const char* detail, + uint64_t receipt) + { + TileXRCcuInstallStepEvidence step; + step.satisfied = true; + step.source.kind = TileXRCcuEvidenceKind::PublicVerified; + step.source.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + step.source.packageFingerprint = 0xfeed001ULL; + step.source.deviceId = 3; + step.source.rank = 1; + step.source.provider = "unit-test-public-install-provider"; + step.source.installAttemptReceiptId = receipt; + step.source.source = source; + step.source.detail = detail; + step.message = detail; + return step; + } + + TileXRCcuInstallProviderReport VerifiedReport(uint64_t receipt) + { + TileXRCcuInstallProviderReport report; + report.offlineOnly = false; + report.installAttempted = true; + report.installSucceeded = true; + report.installAttemptReceiptId = receipt; + report.mission = VerifiedStep("provider:mission", "mission/key installed", receipt); + report.repository = VerifiedStep("provider:repository", "repository installed", receipt); + report.localXn = VerifiedStep("provider:local-xn", "local XN installed", receipt); + report.remoteXn = VerifiedStep("provider:remote-xn", "remote XN bound", receipt); + report.notifyCke = VerifiedStep("provider:notify-cke", "notify CKE installed", receipt); + report.channelBinding = VerifiedStep("provider:channel", "channel binding installed", receipt); + return report; + } + + int ExpectAdapterFailure(const TileXRCcuInstallProviderReport& report, const char* diagnostic) + { + TileXRCcuHardwareInstallEvidence evidence; + const int ret = TileXRCcuBuildInstallEvidence(report, &evidence); + if (ret != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "invalid public verified evidence was accepted: " << diagnostic << "\n"; + return 1; + } + if (evidence.missionInstalled || evidence.repositoryInstalled || evidence.localXnInstalled || + evidence.remoteXnBound || evidence.notifyCkeInstalled || evidence.channelBindingsInstalled) { + std::cerr << "failed adapter left invalid public verified evidence\n"; + return 2; + } + return 0; + } + + int main() + { + TileXRCcuInstallProviderReport wrongSurface = VerifiedReport(0xabc001ULL); + wrongSurface.mission.source.surface = TileXRCcuEvidenceSurface::LowerLayerResourceHelper; + if (ExpectAdapterFailure(wrongSurface, "surface mismatch") != 0) { + return 1; + } + + TileXRCcuInstallProviderReport missingScope = VerifiedReport(0xabc001ULL); + missingScope.repository.source.packageFingerprint = 0; + if (ExpectAdapterFailure(missingScope, "missing fingerprint") != 0) { + return 2; + } + + TileXRCcuInstallProviderReport missingProvider = VerifiedReport(0xabc001ULL); + missingProvider.localXn.source.provider.clear(); + if (ExpectAdapterFailure(missingProvider, "missing provider") != 0) { + return 3; + } + + TileXRCcuInstallProviderReport missingDetail = VerifiedReport(0xabc001ULL); + missingDetail.remoteXn.source.detail.clear(); + if (ExpectAdapterFailure(missingDetail, "missing source/detail") != 0) { + return 4; + } + + TileXRCcuHardwareInstallEvidence evidence; + if (TileXRCcuBuildInstallEvidence(VerifiedReport(0xabc001ULL), &evidence) != TILEXR_SUCCESS) { + std::cerr << "valid public verified evidence was rejected\n"; + return 5; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_peer_exchange_without_endpoint_route_provenance_does_not_submit(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + #include + #include + + using namespace TileXR; + + struct FakeState { + std::vector deviceBytes; + }; + + int FakeAlloc(uint64_t bytes, void** ptr, void* userData) + { + auto* state = static_cast(userData); + state->deviceBytes.assign(static_cast(bytes), 0); + *ptr = state->deviceBytes.data(); + return 0; + } + + int FakeCopy(void* dst, uint64_t dstBytes, const void* src, uint64_t bytes, void* userData) + { + auto* state = static_cast(userData); + if (dst != state->deviceBytes.data() || dstBytes != state->deviceBytes.size() || + bytes != state->deviceBytes.size()) { + return -1; + } + std::memcpy(dst, src, static_cast(bytes)); + return 0; + } + + int FakeFree(void*, void*) + { + return 0; + } + + int FakeCustomChannel( + uint32_t, + const TileXRCcuCustomChannelIn&, + TileXRCcuCustomChannelOut* out, + void*) + { + out->opRet = 0; + return 0; + } + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 3}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 1}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + TileXRCcuLowerLayerInstallPlan MakeSyntheticLowerLayer() + { + TileXRCcuLowerLayerInstallPlan lowerLayer; + lowerLayer.msidTokens.push_back({1, 0x45, 0x1234, 0x5678}); + + TileXRCcuPfeInstall pfe; + pfe.dieId = 1; + pfe.pfeOffset = 2; + pfe.ctx.raw[0] = 0xa0; + lowerLayer.pfes.push_back(pfe); + + TileXRCcuJettyInstall jetty; + jetty.dieId = 1; + jetty.startJettyCtxId = 9; + jetty.ctxs.resize(1); + jetty.ctxs[0].raw[0] = 0xb0; + lowerLayer.jettys.push_back(jetty); + + TileXRCcuChannelInstall channel; + channel.dieId = 1; + channel.channelId = 2; + channel.ctx.raw[0] = 0xc0; + lowerLayer.channels.push_back(channel); + + lowerLayer.xnClears.push_back({1, 1961, 1}); + lowerLayer.ckeClears.push_back({1, 332, 1}); + + TileXRCcuRemoteXnBindingProof proof; + proof.dieId = 1; + proof.channelId = 2; + proof.localXn = 1961; + proof.remoteXn = 2361; + proof.notifyCke = 364; + proof.peerRank = 0; + proof.peerExchangeObserved = true; + lowerLayer.remoteXnBindings.push_back(proof); + return lowerLayer; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport manifestReport; + if (TileXRCcuBuildInstallManifest(package, &manifest, &manifestReport) != TILEXR_SUCCESS) { + std::cerr << "manifest build failed: " << manifestReport.message << "\n"; + return 3; + } + + FakeState state; + TileXRCcuDriverAdapter adapter; + TileXRCcuDriverAdapterReport driverReport; + if (adapter.Init(5, FakeCustomChannel, &state, &driverReport) != TILEXR_SUCCESS) { + std::cerr << "adapter init failed\n"; + return 4; + } + + TileXRCcuDeviceMemoryOps memoryOps; + memoryOps.alloc = FakeAlloc; + memoryOps.copyHostToDevice = FakeCopy; + memoryOps.free = FakeFree; + + TileXRCcuLowerLayerInstallPlan lowerLayer = MakeSyntheticLowerLayer(); + TileXRCcuRepositoryInstallReceipt receipt; + TileXRCcuInstallRequest request; + request.package = &package; + request.manifest = &manifest; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = false; + request.driverAdapter = &adapter; + request.repositoryMemoryOps = memoryOps; + request.repositoryMemoryUserData = &state; + request.repositoryReceipt = &receipt; + request.lowerLayerPlan = &lowerLayer; + + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport installReport; + const int ret = TileXRCcuInstallHardware(request, &evidence, &installReport); + if (ret != TILEXR_ERROR_NOT_FOUND) { + std::cerr << "synthetic endpoint route unexpectedly completed install: " + << installReport.message << "\n"; + return 5; + } + if (evidence.remoteXnBound || evidence.channelBindingsInstalled || + installReport.remoteXn.satisfied || installReport.channelBinding.satisfied || + installReport.publicVerifiedInstallSurfaceCount != 4 || + installReport.missingInstallSurfaceCount != 2) { + std::cerr << "synthetic endpoint route produced submit evidence\n"; + return 6; + } + if (installReport.remoteXn.message.find("endpoint route") == std::string::npos || + installReport.channelBinding.message.find("endpoint route") == std::string::npos) { + std::cerr << "weak synthetic endpoint diagnostic remote=\"" + << installReport.remoteXn.message << "\" channel=\"" + << installReport.channelBinding.message << "\"\n"; + return 7; + } + + std::vector submitTasks; + TileXRCcuProviderReport providerReport; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &providerReport) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "synthetic endpoint route became submit-ready\n"; + return 8; + } + if (!submitTasks.empty() || providerReport.submitReady) { + std::cerr << "submit-ready state leaked from synthetic endpoint route\n"; + return 9; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_peer_exchange_with_endpoint_route_but_without_channel_resource_binding_does_not_submit(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + #include + #include + + using namespace TileXR; + + struct FakeState { + std::vector deviceBytes; + }; + + int FakeAlloc(uint64_t bytes, void** ptr, void* userData) + { + auto* state = static_cast(userData); + state->deviceBytes.assign(static_cast(bytes), 0); + *ptr = state->deviceBytes.data(); + return 0; + } + + int FakeCopy(void* dst, uint64_t dstBytes, const void* src, uint64_t bytes, void* userData) + { + auto* state = static_cast(userData); + if (dst != state->deviceBytes.data() || dstBytes != state->deviceBytes.size() || + bytes != state->deviceBytes.size()) { + return -1; + } + std::memcpy(dst, src, static_cast(bytes)); + return 0; + } + + int FakeFree(void*, void*) + { + return 0; + } + + int FakeCustomChannel( + uint32_t, + const TileXRCcuCustomChannelIn&, + TileXRCcuCustomChannelOut* out, + void*) + { + out->opRet = 0; + return 0; + } + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 3}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + TileXRCcuSyncResource resource; + resource.dieId = 1; + resource.localXn = 1961; + resource.remoteXn = 2361; + resource.notifyCke = 364; + resource.channelId = 2; + resource.bindingCount = 1; + resource.localWaitCke = 332; + plan.syncResources.push_back(resource); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + return plan; + } + + TileXRCcuLowerLayerInstallPlan MakeEndpointOnlyLowerLayer() + { + TileXRCcuLowerLayerInstallPlan lowerLayer; + lowerLayer.msidTokens.push_back({1, 0x45, 0x1234, 0x5678}); + + TileXRCcuPfeInstall pfe; + pfe.dieId = 1; + pfe.pfeOffset = 2; + pfe.ctx.raw[0] = 0xa0; + lowerLayer.pfes.push_back(pfe); + + TileXRCcuJettyInstall jetty; + jetty.dieId = 1; + jetty.startJettyCtxId = 9; + jetty.ctxs.resize(1); + jetty.ctxs[0].raw[0] = 0xb0; + lowerLayer.jettys.push_back(jetty); + + TileXRCcuChannelInstall channel; + channel.dieId = 1; + channel.channelId = 2; + channel.ctx.raw[0] = 0xc0; + lowerLayer.channels.push_back(channel); + + lowerLayer.xnClears.push_back({1, 1961, 1}); + lowerLayer.ckeClears.push_back({1, 332, 3}); + + TileXRCcuRemoteXnBindingProof proof; + proof.dieId = 1; + proof.channelId = 2; + proof.localXn = 1961; + proof.remoteXn = 2361; + proof.notifyCke = 364; + proof.peerRank = 0; + proof.peerExchangeObserved = true; + proof.localWaitCke = 332; + proof.endpointRouteVerified = true; + lowerLayer.remoteXnBindings.push_back(proof); + return lowerLayer; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport manifestReport; + if (TileXRCcuBuildInstallManifest(package, &manifest, &manifestReport) != TILEXR_SUCCESS) { + std::cerr << "manifest build failed: " << manifestReport.message << "\n"; + return 3; + } + + FakeState state; + TileXRCcuDriverAdapter adapter; + TileXRCcuDriverAdapterReport driverReport; + if (adapter.Init(5, FakeCustomChannel, &state, &driverReport) != TILEXR_SUCCESS) { + std::cerr << "adapter init failed\n"; + return 4; + } + + TileXRCcuDeviceMemoryOps memoryOps; + memoryOps.alloc = FakeAlloc; + memoryOps.copyHostToDevice = FakeCopy; + memoryOps.free = FakeFree; + + TileXRCcuLowerLayerInstallPlan lowerLayer = MakeEndpointOnlyLowerLayer(); + TileXRCcuRepositoryInstallReceipt receipt; + TileXRCcuInstallRequest request; + request.package = &package; + request.manifest = &manifest; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = false; + request.driverAdapter = &adapter; + request.repositoryMemoryOps = memoryOps; + request.repositoryMemoryUserData = &state; + request.repositoryReceipt = &receipt; + request.lowerLayerPlan = &lowerLayer; + + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport installReport; + const int ret = TileXRCcuInstallHardware(request, &evidence, &installReport); + if (ret != TILEXR_ERROR_NOT_FOUND) { + std::cerr << "endpoint-only remote XN proof unexpectedly completed install: " + << installReport.message << "\n"; + return 5; + } + if (evidence.remoteXnBound || evidence.channelBindingsInstalled || + installReport.remoteXn.satisfied || installReport.channelBinding.satisfied) { + std::cerr << "endpoint-only remote XN proof produced submit evidence\n"; + return 6; + } + if (installReport.remoteXn.message.find("channel resource owner") == std::string::npos || + installReport.channelBinding.message.find("channel resource owner") == std::string::npos) { + std::cerr << "weak endpoint-only diagnostic remote=\"" + << installReport.remoteXn.message << "\" channel=\"" + << installReport.channelBinding.message << "\"\n"; + return 7; + } + + std::vector submitTasks; + TileXRCcuProviderReport providerReport; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &providerReport) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "endpoint-only remote XN proof became submit-ready\n"; + return 8; + } + if (!submitTasks.empty() || providerReport.submitReady) { + std::cerr << "submit-ready state leaked from endpoint-only remote XN proof\n"; + return 9; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_peer_exchange_with_channel_owner_but_without_transport_exchange_does_not_submit(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_install_provider.h" + + #include + #include + #include + + using namespace TileXR; + + struct FakeState { + std::vector deviceBytes; + }; + + int FakeAlloc(uint64_t bytes, void** ptr, void* userData) + { + auto* state = static_cast(userData); + state->deviceBytes.assign(static_cast(bytes), 0); + *ptr = state->deviceBytes.data(); + return 0; + } + + int FakeCopy(void* dst, uint64_t dstBytes, const void* src, uint64_t bytes, void* userData) + { + auto* state = static_cast(userData); + if (dst != state->deviceBytes.data() || dstBytes != state->deviceBytes.size() || + bytes != state->deviceBytes.size()) { + return -1; + } + std::memcpy(dst, src, static_cast(bytes)); + return 0; + } + + int FakeFree(void*, void*) + { + return 0; + } + + int FakeCustomChannel( + uint32_t, + const TileXRCcuCustomChannelIn&, + TileXRCcuCustomChannelOut* out, + void*) + { + out->opRet = 0; + return 0; + } + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 3}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + TileXRCcuSyncResource resource; + resource.dieId = 1; + resource.localXn = 1961; + resource.remoteXn = 2361; + resource.notifyCke = 364; + resource.channelId = 2; + resource.bindingCount = 1; + resource.localWaitCke = 332; + plan.syncResources.push_back(resource); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + return plan; + } + + TileXRCcuLowerLayerInstallPlan MakeLowerLayer() + { + TileXRCcuLowerLayerInstallPlan lowerLayer; + lowerLayer.msidTokens.push_back({1, 0x45, 0x1234, 0x5678}); + + TileXRCcuPfeInstall pfe; + pfe.dieId = 1; + pfe.pfeOffset = 2; + pfe.ctx.raw[0] = 0xa0; + lowerLayer.pfes.push_back(pfe); + + TileXRCcuJettyInstall jetty; + jetty.dieId = 1; + jetty.startJettyCtxId = 9; + jetty.ctxs.resize(1); + jetty.ctxs[0].raw[0] = 0xb0; + lowerLayer.jettys.push_back(jetty); + + TileXRCcuChannelInstall channel; + channel.dieId = 1; + channel.channelId = 2; + channel.ctx.raw[0] = 0xc0; + lowerLayer.channels.push_back(channel); + + lowerLayer.xnClears.push_back({1, 1961, 1}); + lowerLayer.ckeClears.push_back({1, 332, 3}); + + TileXRCcuRemoteXnBindingProof proof; + proof.dieId = 1; + proof.channelId = 2; + proof.localXn = 1961; + proof.remoteXn = 2361; + proof.notifyCke = 364; + proof.peerRank = 0; + proof.peerExchangeObserved = true; + proof.localWaitCke = 332; + proof.endpointRouteVerified = true; + proof.channelResourceOwnerVerified = true; + proof.transportResourceExchangeVerified = false; + lowerLayer.remoteXnBindings.push_back(proof); + return lowerLayer; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuInstallManifest manifest; + TileXRCcuInstallManifestReport manifestReport; + if (TileXRCcuBuildInstallManifest(package, &manifest, &manifestReport) != TILEXR_SUCCESS) { + std::cerr << "manifest build failed: " << manifestReport.message << "\n"; + return 3; + } + + FakeState state; + TileXRCcuDriverAdapter adapter; + TileXRCcuDriverAdapterReport driverReport; + if (adapter.Init(5, FakeCustomChannel, &state, &driverReport) != TILEXR_SUCCESS) { + std::cerr << "adapter init failed\n"; + return 4; + } + + TileXRCcuDeviceMemoryOps memoryOps; + memoryOps.alloc = FakeAlloc; + memoryOps.copyHostToDevice = FakeCopy; + memoryOps.free = FakeFree; + + TileXRCcuLowerLayerInstallPlan lowerLayer = MakeLowerLayer(); + TileXRCcuRepositoryInstallReceipt receipt; + TileXRCcuInstallRequest request; + request.package = &package; + request.manifest = &manifest; + request.deviceId = 3; + request.rank = 1; + request.provider = "unit-test-public-install-provider"; + request.offlineOnly = false; + request.driverAdapter = &adapter; + request.repositoryMemoryOps = memoryOps; + request.repositoryMemoryUserData = &state; + request.repositoryReceipt = &receipt; + request.lowerLayerPlan = &lowerLayer; + + TileXRCcuHardwareInstallEvidence evidence; + TileXRCcuInstallProviderReport installReport; + const int ret = TileXRCcuInstallHardware(request, &evidence, &installReport); + if (ret != TILEXR_ERROR_NOT_FOUND) { + std::cerr << "missing transport exchange proof unexpectedly completed install: " + << installReport.message << "\n"; + return 5; + } + if (evidence.remoteXnBound || evidence.channelBindingsInstalled || + installReport.remoteXn.satisfied || installReport.channelBinding.satisfied) { + std::cerr << "missing transport exchange proof produced submit evidence\n"; + return 6; + } + if (installReport.remoteXn.message.find("transport resource exchange") == std::string::npos || + installReport.channelBinding.message.find("transport resource exchange") == std::string::npos) { + std::cerr << "weak transport-exchange diagnostic remote=\"" + << installReport.remoteXn.message << "\" channel=\"" + << installReport.channelBinding.message << "\"\n"; + return 7; + } + + std::vector submitTasks; + TileXRCcuProviderReport providerReport; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &providerReport) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "missing transport exchange proof became submit-ready\n"; + return 8; + } + if (!submitTasks.empty() || providerReport.submitReady) { + std::cerr << "submit-ready state leaked from missing transport exchange proof\n"; + return 9; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_install_provider_layer_is_wired_and_has_no_private_hcomm_surface(self): + cmake = COMM_CMAKE.read_text(encoding="utf-8") + header = INSTALL_HEADER.read_text(encoding="utf-8") + source = INSTALL_SOURCE.read_text(encoding="utf-8") + + self.assertIn("ccu/tilexr_ccu_install_provider.h", cmake) + self.assertIn("ccu/tilexr_ccu_install_provider.cpp", cmake) + self.assertIn("struct TileXRCcuInstallRequest", header) + self.assertIn("struct TileXRCcuInstallStepEvidence", header) + self.assertIn("struct TileXRCcuInstallProviderReport", header) + self.assertIn("TileXRCcuBuildInstallEvidence", header) + self.assertIn("TileXRCcuInstallHardware", header) + self.assertIn("TileXRCcuHardwareInstallEvidence", header) + self.assertIn("deviceId", header) + self.assertIn("rank", header) + self.assertIn("provider", header) + self.assertIn("offlineOnly", header) + self.assertIn("driverAdapter", header) + self.assertIn("repositoryMemoryOps", header) + self.assertIn("repositoryMemoryUserData", header) + self.assertIn("repositoryInstallOptions", header) + self.assertIn("repositoryReceipt", header) + self.assertIn("TileXRCcuInstallOrder", header) + self.assertIn("installOrder", header) + self.assertIn("TileXRCcuLowerLayerInstallPlan", header) + self.assertIn("TileXRCcuMsidTokenInstall", header) + self.assertIn("TileXRCcuPfeInstall", header) + self.assertIn("TileXRCcuJettyInstall", header) + self.assertIn("TileXRCcuChannelInstall", header) + self.assertIn("TileXRCcuCkeClearInstall", header) + self.assertIn("TileXRCcuXnClearInstall", header) + self.assertIn("TileXRCcuRemoteXnBindingProof", header) + self.assertIn("localWaitCke", header) + self.assertIn("lowerLayerPlan", header) + self.assertIn("xnClears", header) + self.assertIn("remoteXnBindings", header) + self.assertIn("installAttempted", header) + self.assertIn("installSucceeded", header) + self.assertIn("installAttemptReceiptId", header) + self.assertIn("TileXRCcuInstallRepositoryImage", source) + self.assertIn("TileXRCcuInstallRepositoryImageWithOptions", source) + self.assertIn("InstallLowerLayerResources", source) + self.assertIn("InstallLowerLayerFirst", source) + self.assertIn("ValidateRemoteXnExchangeBindingProof", source) + self.assertIn("local wait CKE", source) + self.assertIn("remote notify CKE", source) + self.assertIn("InstallMsidToken", source) + self.assertIn("InstallPfeCtx", source) + self.assertIn("InstallJettyCtx", source) + self.assertIn("InstallChannelCtxV1", source) + self.assertIn("const uint32_t expectedChannelCount", source) + self.assertIn("CountInstalledRemoteBindingChannels", source) + self.assertIn("installedChannelCount >= expectedChannelCount", source) + self.assertIn("InstallXnRange", source) + self.assertIn("ClearCkeRange", source) + self.assertIn("BuildRepositoryInstallReceiptId", source) + self.assertIn("repository instruction image installed via SET_INSTRUCTION", source) + self.assertIn("ValidateInstallRequestScope", source) + self.assertIn("ValidateInstallReceipt", source) + self.assertIn("install attempt did not succeed", source) + self.assertIn("device scope mismatch", source) + self.assertIn("rank scope mismatch", source) + self.assertIn("provider scope mismatch", source) + self.assertIn("no public no-hcomm CCU install provider", source) + self.assertIn("offline install evidence cannot be public verified", source) + self.assertIn("install attempt receipt", source) + self.assertIn("RejectOfflinePublicVerified", source) + self.assertIn("TileXRCcuInstallManifest", header) + self.assertIn("TileXRCcuInstallRequirement", header) + self.assertIn("TileXRCcuBuildInstallManifest", header) + self.assertIn("ValidateInstallManifestScope", source) + self.assertIn("ValidateInstallRequestManifest", source) + self.assertIn("install manifest fingerprint mismatch", source) + self.assertIn("install manifest requirement kind mismatch", source) + self.assertIn("install manifest hardware requirement mismatch", source) + self.assertIn("install manifest mission requirement mismatch", source) + self.assertIn("ValidateMissionLaunchDescriptorProof", source) + self.assertIn("launch task descriptor", source) + self.assertIn("install manifest channel requirement mismatch", source) + self.assertIn("ValidatePublicVerifiedStepScope", source) + self.assertIn("public verified evidence scope is incomplete", source) + self.assertIn("launch install scope is stale", source) + + combined = header + "\n" + source + self.assertNotIn("SET_MISSION_CTX", combined) + self.assertNotIn("TILEXR_CCU_U_OP_SET_MISSION_CTX", combined) + self.assertNotIn("258", combined) + for needle in PRIVATE_CCU_PRODUCER_NEEDLES: + with self.subTest(needle=needle): + self.assertNotIn(needle, combined) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/ccu/test_tilexr_ccu_launch_package.py b/tests/ccu/test_tilexr_ccu_launch_package.py new file mode 100644 index 00000000..dda0ace7 --- /dev/null +++ b/tests/ccu/test_tilexr_ccu_launch_package.py @@ -0,0 +1,501 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2026 TileXR Project +# + +import shutil +import subprocess +import tempfile +import textwrap +import unittest +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[2] +PACKAGE_HEADER = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_launch_package.h" +PACKAGE_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_launch_package.cpp" +REPOSITORY_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_repository.cpp" +DRIVER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp" +PRODUCER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_producer_plan.cpp" +BARRIER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_barrier_program.cpp" +MICROCODE_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_microcode.cpp" +COMM_CMAKE = REPO_ROOT / "src" / "comm" / "CMakeLists.txt" +INCLUDE_DIR = REPO_ROOT / "src" / "include" +COMM_DIR = REPO_ROOT / "src" / "comm" + + +PRIVATE_CCU_PRODUCER_NEEDLES = [ + "#include + + using namespace TileXR; + + int main() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {0x100051152e00ULL, 0x100051152e00ULL}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport report; + if (TileXRCcuBuildLaunchPackage(plan, &package, &report) != TILEXR_SUCCESS) { + std::cerr << "launch package build failed: " << report.message << "\n"; + return 1; + } + + if (package.tasks.size() != 2 || package.program.sqeLoad.size() != 13 || + package.program.sync.size() != 11 || package.repository.instructions.size() != 170) { + std::cerr << "unexpected package sizes\n"; + return 2; + } + if (package.tasks[0].instStartId != 489 || package.tasks[0].instCnt != 13 || + package.tasks[0].argSize != 13 || package.tasks[0].key != 0x059b0f03U || + package.tasks[0].args[0] != 0x100051152e00ULL) { + std::cerr << "unexpected sqe-load mission task\n"; + return 3; + } + if (package.tasks[1].instStartId != 502 || package.tasks[1].instCnt != 143 || + package.tasks[1].argSize != 13 || package.tasks[1].key != 0x059b0f03U) { + std::cerr << "unexpected sync mission task\n"; + return 4; + } + if (package.repository.sqeLoadOffset != 14 || package.repository.syncOffset != 27 || + package.repository.instructions[14].words[0] != 0x0000000007a90001ULL || + package.repository.instructions[27].words[0] != 0x0000000007a90001ULL || + package.repository.instructions[31].words[0] != 0x0001016c00000802ULL || + package.repository.instructions[32].words[0] != 0x000007a90939100dULL || + package.repository.instructions[35].words[0] != 0x0000000000010802ULL) { + std::cerr << "unexpected repository image\n"; + return 5; + } + if (!package.requiresHardwareInstall) { + std::cerr << "package should still require hardware install\n"; + return 6; + } + if (report.taskCount != 2 || report.repositoryCount != 170 || + report.installedInstructionCount != 24 || report.message != "ok") { + std::cerr << "unexpected package report\n"; + return 7; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_launch_package_rejects_invalid_inputs_without_partial_outputs(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_launch_package.h" + + #include + + using namespace TileXR; + + int main() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + + TileXRCcuLaunchPackageReport report; + if (TileXRCcuBuildLaunchPackage(plan, nullptr, &report) != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "null package output accepted\n"; + return 1; + } + if (report.message.find("package") == std::string::npos) { + std::cerr << "null output diagnostic was weak: " << report.message << "\n"; + return 2; + } + + TileXRCcuLaunchPackage package; + plan.syncResources[0].bindingCount = 0; + if (TileXRCcuBuildLaunchPackage(plan, &package, &report) != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "invalid producer state accepted\n"; + return 3; + } + if (!package.tasks.empty() || !package.repository.instructions.empty()) { + std::cerr << "failed build left partial package state\n"; + return 4; + } + if (report.message.find("binding") == std::string::npos) { + std::cerr << "invalid producer diagnostic was weak: " << report.message << "\n"; + return 5; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_launch_package_builds_pure_barrier_without_sqe_load_task(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_launch_package.h" + + #include + + using namespace TileXR; + + int main() + { + TileXRCcuProducerPlan plan; + plan.mission = {0, 1, 0x12345678U, true}; + plan.kernelLocalXn = {0, 1, 1}; + plan.kernelLocalCke = {0, 1, 1}; + plan.kernelLocalMission = {0, 1, 1}; + plan.instructionWindow = {0, 1, 2, 1, 2}; + plan.syncResources.push_back({0, 1, 2, 1, 1, 1, 1, 1, 1}); + plan.taskWindows.push_back({0, 1, 2, 13, {}}); + + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport report; + if (TileXRCcuBuildLaunchPackage(plan, &package, &report) != TILEXR_SUCCESS) { + std::cerr << "pure barrier package build failed: " << report.message << "\n"; + return 1; + } + if (package.tasks.size() != 1 || !package.program.sqeLoad.empty() || + package.program.sync.size() != 2 || package.repository.instructions.size() != 2) { + std::cerr << "pure barrier package size mismatch\n"; + return 2; + } + if (package.tasks[0].instStartId != 1 || package.tasks[0].instCnt != 2 || + package.tasks[0].argSize != 13 || package.tasks[0].args[0] != 0) { + std::cerr << "pure barrier task mismatch\n"; + return 3; + } + if (package.repository.sqeLoadCount != 0 || package.repository.syncOffset != 0 || + package.repository.syncCount != 2 || + package.repository.instructions[0].words[0] != package.program.sync[0].words[0] || + package.repository.instructions[0].words[1] != package.program.sync[0].words[1] || + package.repository.instructions[1].words[0] != package.program.sync[1].words[0] || + package.repository.instructions[1].words[1] != package.program.sync[1].words[1]) { + std::cerr << "pure barrier repository mismatch\n"; + return 4; + } + if (report.taskCount != 1 || report.installedInstructionCount != 2 || + report.message != "ok") { + std::cerr << "pure barrier report mismatch\n"; + return 5; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_launch_package_install_scope_records_current_package_fingerprint(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_launch_package.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {0x100051152e00ULL}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + if (TileXRCcuBindLaunchPackageInstallScope( + nullptr, 3, 1, "unit-test-public-install-provider") != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "null package scope bind was accepted\n"; + return 1; + } + + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport report; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &report) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << report.message << "\n"; + return 2; + } + if (TileXRCcuBindLaunchPackageInstallScope(&package, 3, 1, "") != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "empty provider scope bind was accepted\n"; + return 3; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 4; + } + + const uint64_t fingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + if (package.installScope.deviceId != 3 || + package.installScope.rank != 1 || + package.installScope.provider != "unit-test-public-install-provider" || + package.installScope.packageFingerprint != fingerprint) { + std::cerr << "unexpected install scope binding\n"; + return 5; + } + + package.tasks[0].key ^= 0x1U; + if (TileXRCcuComputeLaunchPackageFingerprint(package) == fingerprint) { + std::cerr << "mutated package kept old fingerprint\n"; + return 6; + } + if (package.installScope.packageFingerprint == TileXRCcuComputeLaunchPackageFingerprint(package)) { + std::cerr << "install scope fingerprint silently tracked mutation\n"; + return 7; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_launch_package_fingerprint_changes_for_local_wait_cke(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_launch_package.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan(uint16_t localWaitCke) + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 4}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + + TileXRCcuSyncResource resource; + resource.dieId = 1; + resource.localXn = 1961; + resource.remoteXn = 2361; + resource.notifyCke = 364; + resource.channelId = 2; + resource.bindingCount = 3; + resource.localWaitCke = localWaitCke; + resource.localWaitMask = 1; + resource.remoteNotifyMask = 1; + plan.syncResources.push_back(resource); + + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + TileXRCcuLaunchPackage packageA; + TileXRCcuLaunchPackage packageB; + TileXRCcuLaunchPackageReport report; + if (TileXRCcuBuildLaunchPackage(MakePlan(332), &packageA, &report) != TILEXR_SUCCESS || + TileXRCcuBuildLaunchPackage(MakePlan(333), &packageB, &report) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << report.message << "\n"; + return 1; + } + const uint64_t fingerprintA = TileXRCcuComputeLaunchPackageFingerprint(packageA); + const uint64_t fingerprintB = TileXRCcuComputeLaunchPackageFingerprint(packageB); + if (fingerprintA == 0 || fingerprintB == 0 || fingerprintA == fingerprintB) { + std::cerr << "local wait CKE did not affect launch package fingerprint\n"; + return 2; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_launch_package_fingerprint_changes_for_kernel_local_gsa(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_launch_package.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan(uint16_t gsaStart) + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalGsa = {1, gsaStart, 1}; + plan.kernelLocalCke = {1, 332, 4}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3, 332, 1, 1}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + TileXRCcuLaunchPackage packageA; + TileXRCcuLaunchPackage packageB; + TileXRCcuLaunchPackageReport report; + if (TileXRCcuBuildLaunchPackage(MakePlan(510), &packageA, &report) != TILEXR_SUCCESS || + TileXRCcuBuildLaunchPackage(MakePlan(511), &packageB, &report) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << report.message << "\n"; + return 1; + } + const uint64_t fingerprintA = TileXRCcuComputeLaunchPackageFingerprint(packageA); + const uint64_t fingerprintB = TileXRCcuComputeLaunchPackageFingerprint(packageB); + if (fingerprintA == 0 || fingerprintB == 0 || fingerprintA == fingerprintB) { + std::cerr << "kernel-local GSA did not affect launch package fingerprint\n"; + return 2; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_launch_package_layer_is_wired_and_has_no_private_hcomm_surface(self): + cmake = COMM_CMAKE.read_text(encoding="utf-8") + header = PACKAGE_HEADER.read_text(encoding="utf-8") + source = PACKAGE_SOURCE.read_text(encoding="utf-8") + + self.assertIn("ccu/tilexr_ccu_launch_package.h", cmake) + self.assertIn("ccu/tilexr_ccu_launch_package.cpp", cmake) + self.assertIn("struct TileXRCcuLaunchPackage", header) + self.assertIn("struct TileXRCcuLaunchPackageReport", header) + self.assertIn("TileXRCcuBuildLaunchPackage", header) + self.assertIn("TileXRCcuLaunchInstallScope", header) + self.assertIn("installScope", header) + self.assertIn("TileXRCcuBindLaunchPackageInstallScope", header) + self.assertIn("requiresHardwareInstall", header) + self.assertIn("tilexr_ccu_repository.h", header) + self.assertIn("resource.localWaitCke", source) + self.assertIn("resource.localWaitMask", source) + self.assertIn("resource.remoteNotifyMask", source) + + combined = header + "\n" + source + for needle in PRIVATE_CCU_PRODUCER_NEEDLES: + with self.subTest(needle=needle): + self.assertNotIn(needle, combined) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/ccu/test_tilexr_ccu_lower_layer_plan_builder.py b/tests/ccu/test_tilexr_ccu_lower_layer_plan_builder.py new file mode 100644 index 00000000..8cd8c8b8 --- /dev/null +++ b/tests/ccu/test_tilexr_ccu_lower_layer_plan_builder.py @@ -0,0 +1,3829 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2026 TileXR Project +# + +import shutil +import os +import subprocess +import tempfile +import textwrap +import unittest +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[2] +BUILDER_HEADER = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_lower_layer_plan_builder.h" +BUILDER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_lower_layer_plan_builder.cpp" +DIRECT_RUNTIME_HEADER = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_direct_runtime.h" +DIRECT_RUNTIME_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_direct_runtime.cpp" +PAYLOAD_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_lower_layer_payloads.cpp" +SPECS_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_specs.cpp" +ALLOCATOR_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_resource_allocator.cpp" +PRODUCER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_producer_plan.cpp" +BARRIER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_barrier_program.cpp" +MICROCODE_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_microcode.cpp" +COMM_HEADER_FILE = REPO_ROOT / "src" / "comm" / "tilexr_comm.h" +COMM_SOURCE_FILE = REPO_ROOT / "src" / "comm" / "tilexr_comm.cpp" +CCU_BACKEND_HEADER = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_backend.h" +CCU_BACKEND_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_backend.cpp" +CCU_RUNTIME_SESSION_HEADER = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_runtime_session.h" +CCU_RUNTIME_SESSION_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_runtime_session.cpp" +CCU_PLANNER_HEADER = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_collective_planner.h" +CCU_PLANNER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_collective_planner.cpp" +CCU_EXECUTOR_HEADER = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_executor.h" +CCU_EXECUTOR_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_executor.cpp" +COMM_CMAKE = REPO_ROOT / "src" / "comm" / "CMakeLists.txt" +INCLUDE_DIR = REPO_ROOT / "src" / "include" +COMM_DIR = REPO_ROOT / "src" / "comm" + + +class TileXRCcuLowerLayerPlanBuilderTest(unittest.TestCase): + def setUp(self): + runtime_integration_prefixes = ( + "test_plan_builder_surface_", + "test_tilexr_comm_", + "test_direct_ccu_runtime_", + "test_remote_xn_", + "test_remote_notify_", + "test_peer_xn_", + ) + if (not CCU_BACKEND_SOURCE.exists() and + self._testMethodName.startswith(runtime_integration_prefixes)): + self.skipTest("direct CCU runtime integration is introduced by the next stack layer") + + def compile_and_run(self, code: str, env=None, extra_sources=None, extra_link_flags=None): + compiler = shutil.which("g++") or shutil.which("clang++") or shutil.which("c++") + if compiler is None: + self.skipTest("no local C++ compiler found") + extra_sources = extra_sources or [] + extra_link_flags = extra_link_flags or [] + with tempfile.TemporaryDirectory() as temp_dir: + temp_path = Path(temp_dir) + test_cpp = temp_path / "lower_layer_plan_builder_test.cpp" + test_bin = temp_path / "lower_layer_plan_builder_test" + test_cpp.write_text(code, encoding="utf-8") + compile_cmd = [ + compiler, + "-std=c++14", + "-I", + str(INCLUDE_DIR), + "-I", + str(COMM_DIR), + str(test_cpp), + str(BUILDER_SOURCE), + str(PAYLOAD_SOURCE), + str(SPECS_SOURCE), + str(ALLOCATOR_SOURCE), + str(PRODUCER_SOURCE), + str(BARRIER_SOURCE), + str(MICROCODE_SOURCE), + *[str(source) for source in extra_sources], + "-o", + str(test_bin), + *extra_link_flags, + ] + try: + subprocess.run( + compile_cmd, + cwd=REPO_ROOT, + check=True, + text=True, + capture_output=True, + ) + except subprocess.CalledProcessError as exc: + self.fail(exc.stdout + exc.stderr) + return subprocess.run( + [str(test_bin)], + cwd=REPO_ROOT, + check=False, + text=True, + capture_output=True, + env=env) + + def compile_only(self, code: str): + compiler = shutil.which("g++") or shutil.which("clang++") or shutil.which("c++") + if compiler is None: + self.skipTest("no local C++ compiler found") + with tempfile.TemporaryDirectory() as temp_dir: + temp_path = Path(temp_dir) + test_cpp = temp_path / "comm_lower_layer_plan_api_test.cpp" + test_obj = temp_path / "comm_lower_layer_plan_api_test.o" + test_cpp.write_text(code, encoding="utf-8") + return subprocess.run( + [ + compiler, + "-std=c++14", + "-I", + str(INCLUDE_DIR), + "-I", + str(COMM_DIR), + "-c", + str(test_cpp), + "-o", + str(test_obj), + ], + cwd=REPO_ROOT, + check=False, + text=True, + capture_output=True, + ) + + def test_builds_lower_layer_install_plan_from_tilexr_owned_specs(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + uint16_t Read16(const uint8_t* raw, uint32_t offset) + { + return static_cast(raw[offset]) | + static_cast(static_cast(raw[offset + 1]) << 8U); + } + + int main() + { + TileXRCcuLowerLayerPlanSpec spec; + spec.msidToken.dieId = 1; + spec.msidToken.msId = 0x55; + spec.msidToken.tokenId = 0x45678; + spec.msidToken.tokenValue = 0; + spec.msidToken.valid = true; + + spec.pfe.dieId = 1; + spec.pfe.pfeOffset = 3; + spec.pfe.startJettyId = 0x120; + spec.pfe.startLocalJettyCtxId = 0x21; + + TileXRCcuLowerLayerJettySpec jetty0; + jetty0.dieId = 1; + jetty0.pfeId = 3; + jetty0.startJettyCtxId = 0x21; + jetty0.doorbellVa = 0x1122334455667788ULL; + jetty0.doorbellTokenId = 0x45678; + jetty0.doorbellTokenValue = 0; + jetty0.sqDepth = 16; + jetty0.wqeBasicBlockStartId = 0x40; + spec.jettys.push_back(jetty0); + + TileXRCcuLowerLayerJettySpec jetty1 = jetty0; + jetty1.startJettyCtxId = 0x22; + jetty1.doorbellVa = 0x2122334455667788ULL; + jetty1.wqeBasicBlockStartId = 0x44; + spec.jettys.push_back(jetty1); + + TileXRCcuLowerLayerChannelSpec channel; + channel.dieId = 1; + channel.channelId = 5; + for (uint32_t i = 0; i < TILEXR_CCU_EID_BYTES; ++i) { + channel.remoteEid[i] = static_cast(0x20 + i); + } + channel.tpn = 0x123456; + channel.sourcePfeId = 3; + channel.startJettyId = 0x120; + channel.memoryTokenId = 0xabcde; + channel.memoryTokenValue = 0; + channel.remoteCcuVa = 0x0001234567800000ULL; + spec.channels.push_back(channel); + + spec.xnClear.dieId = 1; + spec.xnClear.startXnId = 0x1f0; + spec.xnClear.count = 3; + spec.xnClear.valid = true; + + spec.ckeClear.dieId = 1; + spec.ckeClear.startCkeId = 0x180; + spec.ckeClear.count = 2; + spec.ckeClear.valid = true; + + TileXRCcuLowerLayerInstallPlan plan; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerInstallPlan(spec, &plan, &report) != TILEXR_SUCCESS) { + std::cerr << "plan build failed: " << report.message << "\n"; + return 1; + } + if (report.msidTokenCount != 1 || report.pfeCount != 1 || + report.jettyCount != 1 || report.localJettyCtxCount != 2 || + report.channelCount != 1 || report.ckeClearCount != 1) { + std::cerr << "unexpected plan report counts\n"; + return 2; + } + if (plan.msidTokens.size() != 1 || plan.pfes.size() != 1 || + plan.jettys.size() != 1 || plan.jettys[0].ctxs.size() != 2 || + plan.channels.size() != 1 || plan.xnClears.size() != 1 || + plan.ckeClears.size() != 1) { + std::cerr << "unexpected install plan shape\n"; + return 3; + } + if (plan.msidTokens[0].tokenValue != 0 || + plan.msidTokens[0].tokenId != 0x45678U || + plan.xnClears[0].startXnId != 0x1f0 || + plan.xnClears[0].count != 3 || + plan.ckeClears[0].startCkeId != 0x180 || + plan.ckeClears[0].count != 2) { + std::cerr << "scalar plan fields mismatch\n"; + return 4; + } + if (Read16(plan.pfes[0].ctx.raw, 0) != 0x120 || + Read16(plan.pfes[0].ctx.raw, 2) != static_cast(1U | (0x21U << 7U))) { + std::cerr << "pfe payload mismatch\n"; + return 5; + } + if (Read16(plan.jettys[0].ctxs[0].raw, 0) != 0x7788 || + Read16(plan.jettys[0].ctxs[1].raw, 0) != 0x7788 || + Read16(plan.jettys[0].ctxs[0].raw, 8) != 0x7873) { + std::cerr << "jetty payload mismatch\n"; + return 6; + } + if (plan.channels[0].ctx.raw[0] != 0x20 || + plan.channels[0].ctx.raw[15] != 0x2f || + Read16(plan.channels[0].ctx.raw, 16) != 0x3456) { + std::cerr << "channel payload mismatch\n"; + return 7; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_template_can_use_hcomm_compatible_wqe_stride_for_direct_ccu_experiment(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuBasicInfo basic; + basic.dieId = 1; + basic.msId = 0x45; + basic.msidToken.tokenId = 0x1234; + basic.msidToken.valid = true; + + TileXRCcuResourceAllocation allocation; + allocation.channels = {1, 2, 2}; + allocation.localXn = {1, 0x120, 2}; + allocation.remoteXn = {1, 0x240, 2}; + allocation.notifyCke = {1, 0x330, 2}; + + std::vector remoteCcuBuffers; + TileXRCcuRemoteCcuBufferInfo remote0; + remote0.remoteCcuVa = 0x0000009234000000ULL; + remote0.memoryTokenId = 0x23456; + remote0.remoteNotifyCke = 0x360; + remoteCcuBuffers.push_back(remote0); + TileXRCcuRemoteCcuBufferInfo remote1 = remote0; + remote1.remoteCcuVa = 0x0000009334000000ULL; + remote1.memoryTokenId = 0x23457; + remote1.remoteNotifyCke = 0x361; + remoteCcuBuffers.push_back(remote1); + + TileXRCcuLowerLayerTransportSnapshot snapshot; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, remoteCcuBuffers, &snapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "template build failed: " << report.message << "\n"; + return 1; + } + if (snapshot.routes.size() != 2 || + snapshot.routes[0].wqeBasicBlockStartId != 0 || + snapshot.routes[1].wqeBasicBlockStartId != 256) { + std::cerr << "hcomm-compatible WQE stride not applied\n"; + return 2; + } + return 0; + } + ''' + ) + env = os.environ.copy() + env["TILEXR_CCU_DIRECT_LOWER_LAYER_WQE_MODE"] = "hcomm_cap" + + result = self.compile_and_run(code, env=env) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_template_preserves_explicit_peer_rank_from_remote_buffer(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuBasicInfo basic; + basic.dieId = 1; + basic.msId = 0x45; + basic.msidToken.tokenId = 0x1234; + basic.msidToken.valid = true; + + TileXRCcuResourceAllocation allocation; + allocation.channels = {1, 7, 1}; + allocation.localXn = {1, 0x120, 1}; + allocation.remoteXn = {1, 0x240, 1}; + allocation.notifyCke = {1, 0x330, 1}; + + TileXRCcuRemoteCcuBufferInfo remote; + remote.peerRank = 1; + remote.remoteCcuVa = 0x0000009234000000ULL; + remote.memoryTokenId = 0x23456; + std::vector remoteCcuBuffers {remote}; + + TileXRCcuLowerLayerTransportSnapshot snapshot; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, remoteCcuBuffers, &snapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "template build failed: " << report.message << "\n"; + return 1; + } + if (snapshot.routes.size() != 1 || snapshot.routes[0].peerRank != 1) { + std::cerr << "explicit peer rank from remote buffer was not preserved\n"; + return 2; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_template_can_use_hcomm_die_pfe_offset_for_direct_ccu_experiment(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuBasicInfo basic; + basic.dieId = 1; + basic.msId = 0x45; + basic.msidToken.tokenId = 0x1234; + basic.msidToken.valid = true; + basic.caps.cap4 = 15U; + + TileXRCcuResourceAllocation allocation; + allocation.channels = {1, 2, 2}; + allocation.localXn = {1, 0x120, 2}; + allocation.remoteXn = {1, 0x240, 2}; + allocation.notifyCke = {1, 0x330, 2}; + + std::vector remoteCcuBuffers; + TileXRCcuRemoteCcuBufferInfo remote0; + remote0.remoteCcuVa = 0x0000009234000000ULL; + remote0.memoryTokenId = 0x23456; + remoteCcuBuffers.push_back(remote0); + TileXRCcuRemoteCcuBufferInfo remote1 = remote0; + remote1.remoteCcuVa = 0x0000009334000000ULL; + remote1.memoryTokenId = 0x23457; + remoteCcuBuffers.push_back(remote1); + + TileXRCcuLowerLayerTransportSnapshot snapshot; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, remoteCcuBuffers, &snapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "template build failed: " << report.message << "\n"; + return 1; + } + if (snapshot.pfeId != 2 || snapshot.pfeOffset != 18) { + std::cerr << "hcomm die pfe offset not applied: pfeId=" << snapshot.pfeId + << " pfeOffset=" << snapshot.pfeOffset << "\n"; + return 2; + } + return 0; + } + ''' + ) + env = os.environ.copy() + env["TILEXR_CCU_DIRECT_LOWER_LAYER_PFE_OFFSET_SOURCE"] = "hcomm_die" + + result = self.compile_and_run(code, env=env) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_template_can_use_hcomm_ordered_pfe_partition_for_direct_ccu_experiment(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuBasicInfo basic; + basic.dieId = 1; + basic.msId = 0x45; + basic.msidToken.tokenId = 0x1234; + basic.msidToken.valid = true; + + TileXRCcuResourceAllocation allocation; + allocation.channels = {1, 3, 2}; + allocation.localXn = {1, 0x120, 2}; + allocation.remoteXn = {1, 0x240, 2}; + allocation.notifyCke = {1, 0x330, 2}; + + std::vector remoteCcuBuffers; + TileXRCcuRemoteCcuBufferInfo remote0; + remote0.remoteCcuVa = 0x0000009234000000ULL; + remote0.memoryTokenId = 0x23456; + remoteCcuBuffers.push_back(remote0); + TileXRCcuRemoteCcuBufferInfo remote1 = remote0; + remote1.remoteCcuVa = 0x0000009334000000ULL; + remote1.memoryTokenId = 0x23457; + remoteCcuBuffers.push_back(remote1); + + TileXRCcuLowerLayerTransportSnapshot snapshot; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, remoteCcuBuffers, &snapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "template build failed: " << report.message << "\n"; + return 1; + } + if (snapshot.pfeId != 3 || + snapshot.startLocalJettyCtxId != 0 || + snapshot.startJettyId != 1024 || + snapshot.pfeJettyCount != 23 || + snapshot.routes.size() != 2) { + std::cerr << "hcomm ordered pfe partition not applied: pfeId=" << snapshot.pfeId + << " startLocalJettyCtxId=" << snapshot.startLocalJettyCtxId + << " startJettyId=" << snapshot.startJettyId + << " pfeJettyCount=" << snapshot.pfeJettyCount << "\n"; + return 2; + } + return 0; + } + ''' + ) + env = os.environ.copy() + env["TILEXR_CCU_DIRECT_LOWER_LAYER_PFE_PARTITION"] = "hcomm" + + result = self.compile_and_run(code, env=env) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_template_can_use_hcomm_fe_id_pfe_partition_for_direct_ccu_experiment(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuBasicInfo basic; + basic.dieId = 1; + basic.msId = 0x45; + basic.msidToken.tokenId = 0x1234; + basic.msidToken.valid = true; + + TileXRCcuResourceAllocation allocation; + allocation.channels = {1, 3, 2}; + allocation.localXn = {1, 0x120, 2}; + allocation.remoteXn = {1, 0x240, 2}; + allocation.notifyCke = {1, 0x330, 2}; + + std::vector remoteCcuBuffers; + TileXRCcuRemoteCcuBufferInfo remote0; + remote0.remoteCcuVa = 0x0000009234000000ULL; + remote0.memoryTokenId = 0x23456; + remoteCcuBuffers.push_back(remote0); + TileXRCcuRemoteCcuBufferInfo remote1 = remote0; + remote1.remoteCcuVa = 0x0000009334000000ULL; + remote1.memoryTokenId = 0x23457; + remoteCcuBuffers.push_back(remote1); + + TileXRCcuLowerLayerTransportSnapshot snapshot; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, remoteCcuBuffers, &snapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "template build failed: " << report.message << "\n"; + return 1; + } + if (snapshot.pfeId != 3 || + snapshot.startLocalJettyCtxId != 69 || + snapshot.startJettyId != 1093 || + snapshot.pfeJettyCount != 23) { + std::cerr << "hcomm fe-id pfe partition not applied: pfeId=" << snapshot.pfeId + << " startLocalJettyCtxId=" << snapshot.startLocalJettyCtxId + << " startJettyId=" << snapshot.startJettyId + << " pfeJettyCount=" << snapshot.pfeJettyCount << "\n"; + return 2; + } + return 0; + } + ''' + ) + env = os.environ.copy() + env["TILEXR_CCU_DIRECT_LOWER_LAYER_PFE_PARTITION"] = "hcomm_fe_id" + + result = self.compile_and_run(code, env=env) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_builds_lower_layer_install_plan_from_transport_snapshot(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + uint16_t Read16(const uint8_t* raw, uint32_t offset) + { + return static_cast(raw[offset]) | + static_cast(static_cast(raw[offset + 1]) << 8U); + } + + int main() + { + TileXRCcuLowerLayerTransportSnapshot snapshot; + snapshot.msidToken.dieId = 0; + snapshot.msidToken.msId = 0x9; + snapshot.msidToken.tokenId = 0x12345; + snapshot.msidToken.tokenValue = 0; + snapshot.msidToken.valid = true; + snapshot.dieId = 0; + snapshot.pfeOffset = 2; + snapshot.pfeId = 2; + snapshot.startJettyId = 0x80; + snapshot.startLocalJettyCtxId = 0x10; + snapshot.xnStartId = 0x1a0; + snapshot.xnCount = 6; + snapshot.ckeStartId = 0x220; + snapshot.ckeCount = 2; + + TileXRCcuLowerLayerTransportRoute route0; + route0.channelId = 7; + route0.remoteXnId = 0x2a0; + route0.remoteNotifyCke = 0x360; + for (uint32_t i = 0; i < TILEXR_CCU_EID_BYTES; ++i) { + route0.remoteEid[i] = static_cast(0x40 + i); + } + route0.tpn = 0x010203; + route0.doorbellVa = 0x1111222233334444ULL; + route0.doorbellTokenId = 0x12345; + route0.doorbellTokenValue = 0; + route0.sqDepth = 8; + route0.wqeBasicBlockStartId = 0x30; + route0.memoryTokenId = 0x23456; + route0.memoryTokenValue = 0; + route0.remoteCcuVa = 0x0000009234000000ULL; + route0.peerRank = 7; + route0.endpointRouteVerified = true; + snapshot.routes.push_back(route0); + + TileXRCcuLowerLayerTransportRoute route1 = route0; + route1.channelId = 8; + route1.remoteXnId = 0x2a1; + route1.remoteNotifyCke = 0x361; + route1.remoteEid[0] = 0x50; + route1.tpn = 0x010204; + route1.doorbellVa = 0x5555666677778888ULL; + route1.wqeBasicBlockStartId = 0x34; + route1.memoryTokenId = 0x23457; + route1.remoteCcuVa = 0x0000009334000000ULL; + route1.peerRank = 9; + route1.endpointRouteVerified = true; + snapshot.routes.push_back(route1); + + TileXRCcuLowerLayerInstallPlan plan; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerInstallPlanFromTransportSnapshot(snapshot, &plan, &report) != + TILEXR_SUCCESS) { + std::cerr << "transport snapshot build failed: " << report.message << "\n"; + return 1; + } + if (plan.msidTokens.size() != 1 || plan.pfes.size() != 1 || + plan.jettys.size() != 1 || plan.jettys[0].ctxs.size() != 2 || + plan.channels.size() != 2 || plan.xnClears.size() != 2 || + plan.ckeClears.size() != 2 || plan.remoteXnBindings.size() != 2) { + std::cerr << "unexpected transport-derived plan shape\n"; + return 2; + } + if (report.channelCount != 2 || report.localJettyCtxCount != 2 || + report.ckeClearCount != 2) { + std::cerr << "unexpected transport-derived report counts\n"; + return 3; + } + if (Read16(plan.pfes[0].ctx.raw, 0) != 0x80 || + Read16(plan.pfes[0].ctx.raw, 2) != static_cast(1U | (0x10U << 7U))) { + std::cerr << "transport pfe payload mismatch\n"; + return 4; + } + if (Read16(plan.jettys[0].ctxs[0].raw, 0) != 0x4444 || + Read16(plan.jettys[0].ctxs[1].raw, 0) != 0x8888) { + std::cerr << "transport jetty payload mismatch\n"; + return 5; + } + if (plan.channels[0].channelId != 7 || plan.channels[1].channelId != 8 || + plan.channels[0].ctx.raw[0] != 0x40 || plan.channels[1].ctx.raw[0] != 0x50 || + Read16(plan.channels[0].ctx.raw, 16) != 0x0203 || + Read16(plan.channels[1].ctx.raw, 16) != 0x0204) { + std::cerr << "transport channel payload mismatch\n"; + return 6; + } + if (Read16(plan.channels[0].ctx.raw, 18) != 0x0201 || + Read16(plan.channels[0].ctx.raw, 20) != 0x0008 || + Read16(plan.channels[1].ctx.raw, 18) != 0x1201 || + Read16(plan.channels[1].ctx.raw, 20) != 0x0008) { + std::cerr << "transport channel jetty window mismatch\n"; + return 9; + } + if (plan.xnClears[0].startXnId != 0x1a0 || plan.xnClears[0].count != 6 || + plan.xnClears[1].startXnId != 0x2a0 || plan.xnClears[1].count != 2 || + plan.ckeClears[0].startCkeId != 0x220 || plan.ckeClears[0].count != 2 || + plan.ckeClears[1].startCkeId != 0x360 || plan.ckeClears[1].count != 2) { + std::cerr << "transport local/channel XN or CKE clear mismatch\n"; + return 7; + } + if (!plan.remoteXnBindings[0].peerExchangeObserved || + plan.remoteXnBindings[0].channelId != 7 || + plan.remoteXnBindings[0].localXn != 0x1a0 || + plan.remoteXnBindings[0].remoteXn != 0x2a0 || + plan.remoteXnBindings[0].notifyCke != 0x360 || + plan.remoteXnBindings[0].peerRank != 7 || + plan.remoteXnBindings[0].localWaitCke != 0x220 || + !plan.remoteXnBindings[0].endpointRouteVerified || + plan.remoteXnBindings[1].channelId != 8 || + plan.remoteXnBindings[1].localXn != 0x1a1 || + plan.remoteXnBindings[1].remoteXn != 0x2a1 || + plan.remoteXnBindings[1].notifyCke != 0x361 || + plan.remoteXnBindings[1].peerRank != 9 || + plan.remoteXnBindings[1].localWaitCke != 0x221 || + !plan.remoteXnBindings[1].endpointRouteVerified) { + std::cerr << "transport remote XN proof mismatch\n"; + return 8; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_snapshot_pfe_jetty_count_reaches_pfe_ctx(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + uint16_t Read16(const uint8_t* raw, uint32_t offset) + { + return static_cast(raw[offset]) | + static_cast(static_cast(raw[offset + 1]) << 8U); + } + + int main() + { + TileXRCcuLowerLayerTransportSnapshot snapshot; + snapshot.msidToken.dieId = 1; + snapshot.msidToken.msId = 0x9; + snapshot.msidToken.tokenId = 0x12345; + snapshot.msidToken.valid = true; + snapshot.dieId = 1; + snapshot.pfeOffset = 18; + snapshot.pfeId = 2; + snapshot.startJettyId = 1024; + snapshot.pfeJettyCount = 23; + snapshot.startLocalJettyCtxId = 0; + snapshot.xnStartId = 0x1a0; + snapshot.xnCount = 1; + snapshot.ckeStartId = 0x220; + snapshot.ckeCount = 1; + + TileXRCcuLowerLayerTransportRoute route; + route.channelId = 7; + route.remoteXnId = 0x2a0; + route.remoteNotifyCke = 0x360; + for (uint32_t i = 0; i < TILEXR_CCU_EID_BYTES; ++i) { + route.remoteEid[i] = static_cast(0x40 + i); + } + route.tpn = 0x010203; + route.doorbellVa = 0x1111222233334444ULL; + route.doorbellTokenId = 0x12345; + route.sqDepth = 8; + route.memoryTokenId = 0x23456; + route.remoteCcuVa = 0x0000009234000000ULL; + snapshot.routes.push_back(route); + + TileXRCcuLowerLayerInstallPlan plan; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerInstallPlanFromTransportSnapshot(snapshot, &plan, &report) != + TILEXR_SUCCESS) { + std::cerr << "transport snapshot build failed: " << report.message << "\n"; + return 1; + } + if (plan.pfes.size() != 1 || plan.pfes[0].pfeOffset != 18) { + std::cerr << "pfe install shape mismatch\n"; + return 2; + } + const uint16_t pfeWord = Read16(plan.pfes[0].ctx.raw, 2); + if ((pfeWord & 0x7fU) != 22U) { + std::cerr << "pfe jetty count did not reach ctx: word=" << pfeWord << "\n"; + return 3; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_snapshot_installs_remote_xn_range_separately(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + + using namespace TileXR; + + int main() + { + TileXRCcuLowerLayerTransportSnapshot snapshot; + snapshot.msidToken.dieId = 1; + snapshot.msidToken.msId = 0x45; + snapshot.msidToken.tokenId = 0x1234; + snapshot.msidToken.valid = true; + snapshot.dieId = 1; + snapshot.pfeOffset = 0x80; + snapshot.pfeId = 2; + snapshot.startJettyId = 0x400; + snapshot.pfeJettyCount = 2; + snapshot.startLocalJettyCtxId = 0; + snapshot.xnStartId = 0x1a0; + snapshot.xnCount = 2; + snapshot.ckeStartId = 0x220; + snapshot.ckeCount = 2; + + snapshot.routes.resize(2); + snapshot.routes[0].channelId = 7; + snapshot.routes[0].remoteXnId = 0x2a0; + snapshot.routes[0].remoteNotifyCke = 0x360; + for (uint32_t i = 0; i < TILEXR_CCU_EID_BYTES; ++i) { + snapshot.routes[0].remoteEid[i] = static_cast(0x40 + i); + } + snapshot.routes[0].tpn = 0x010203; + snapshot.routes[0].doorbellVa = 0x1111222233334444ULL; + snapshot.routes[0].doorbellTokenId = 0x12345; + snapshot.routes[0].sqDepth = 8; + snapshot.routes[0].remoteCcuVa = 0x90000000ULL; + snapshot.routes[0].memoryTokenId = 0x1234; + + snapshot.routes[1] = snapshot.routes[0]; + snapshot.routes[1].channelId = 8; + snapshot.routes[1].remoteXnId = 0x2a1; + snapshot.routes[1].remoteNotifyCke = 0x361; + snapshot.routes[1].tpn = 0x010204; + + TileXRCcuLowerLayerInstallPlan plan; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerInstallPlanFromTransportSnapshot(snapshot, &plan, &report) != + TILEXR_SUCCESS) { + std::cerr << "transport snapshot build failed: " << report.message << "\n"; + return 1; + } + if (plan.xnClears.size() != 2) { + std::cerr << "expected local and channel remote XN clears, got " << + plan.xnClears.size() << "\n"; + return 2; + } + if (plan.xnClears[0].startXnId != 0x1a0 || plan.xnClears[0].count != 2) { + std::cerr << "local XN clear mismatch\n"; + return 3; + } + if (plan.xnClears[1].startXnId != 0x2a0 || plan.xnClears[1].count != 2) { + std::cerr << "channel remote XN clear mismatch\n"; + return 4; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_snapshot_installs_remote_notify_cke_range_separately(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + + using namespace TileXR; + + int main() + { + TileXRCcuLowerLayerTransportSnapshot snapshot; + snapshot.msidToken.dieId = 1; + snapshot.msidToken.msId = 0x45; + snapshot.msidToken.tokenId = 0x1234; + snapshot.msidToken.valid = true; + snapshot.dieId = 1; + snapshot.pfeOffset = 0x80; + snapshot.pfeId = 2; + snapshot.startJettyId = 0x400; + snapshot.pfeJettyCount = 2; + snapshot.startLocalJettyCtxId = 0; + snapshot.xnStartId = 0x1a0; + snapshot.xnCount = 2; + snapshot.ckeStartId = 0x220; + snapshot.ckeCount = 3; + + snapshot.routes.resize(2); + snapshot.routes[0].channelId = 7; + snapshot.routes[0].remoteXnId = 0x2a0; + snapshot.routes[0].remoteNotifyCke = 0x360; + for (uint32_t i = 0; i < TILEXR_CCU_EID_BYTES; ++i) { + snapshot.routes[0].remoteEid[i] = static_cast(0x40 + i); + } + snapshot.routes[0].tpn = 0x010203; + snapshot.routes[0].doorbellVa = 0x1111222233334444ULL; + snapshot.routes[0].doorbellTokenId = 0x12345; + snapshot.routes[0].sqDepth = 8; + snapshot.routes[0].remoteCcuVa = 0x90000000ULL; + snapshot.routes[0].memoryTokenId = 0x1234; + snapshot.routes[1] = snapshot.routes[0]; + snapshot.routes[1].channelId = 8; + snapshot.routes[1].remoteXnId = 0x2a1; + snapshot.routes[1].remoteNotifyCke = 0x361; + snapshot.routes[1].tpn = 0x010204; + + TileXRCcuLowerLayerInstallPlan plan; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerInstallPlanFromTransportSnapshot(snapshot, &plan, &report) != + TILEXR_SUCCESS) { + std::cerr << "transport snapshot build failed: " << report.message << "\n"; + return 1; + } + if (plan.ckeClears.size() != 2 || report.ckeClearCount != 2) { + std::cerr << "expected local and remote notify CKE clears, got " << + plan.ckeClears.size() << " report=" << report.ckeClearCount << "\n"; + return 2; + } + if (plan.ckeClears[0].startCkeId != 0x220 || plan.ckeClears[0].count != 3) { + std::cerr << "local CKE clear mismatch\n"; + return 3; + } + if (plan.ckeClears[1].startCkeId != 0x360 || plan.ckeClears[1].count != 2) { + std::cerr << "remote notify CKE clear mismatch\n"; + return 4; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_builds_transport_template_from_basic_info_and_resource_allocation(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuBasicInfo basic; + basic.dieId = 1; + basic.msId = 0x45; + basic.msidToken.tokenId = 0x1234; + basic.msidToken.tokenValue = 0; + basic.msidToken.valid = true; + basic.missionKey = 0x059b0f03U; + basic.resourceAddr = 0x100000000ULL; + basic.caps.cap0 = (5U << 16) | 255U; + basic.caps.cap1 = (127U << 16) | 63U; + basic.caps.cap2 = (31U << 16) | 15U; + basic.caps.cap3 = (7U << 16) | 1U; + basic.caps.cap4 = 9U; + + TileXRCcuSpecInfo specInfo; + TileXRCcuSpecsReport specsReport; + if (TileXRCcuDecodeBasicInfo(basic, &specInfo, &specsReport) != TILEXR_SUCCESS) { + std::cerr << "decode failed: " << specsReport.message << "\n"; + return 1; + } + + TileXRCcuResourceSpec resourceSpec; + if (TileXRCcuBuildResourceSpec(specInfo, 6, 475, 1961, 332, 2, &resourceSpec, &specsReport) != + TILEXR_SUCCESS) { + std::cerr << "resource spec failed: " << specsReport.message << "\n"; + return 2; + } + + TileXRCcuResourceAllocator allocator; + if (allocator.Init(resourceSpec) != TILEXR_SUCCESS) { + std::cerr << "allocator init failed\n"; + return 3; + } + TileXRCcuResourceRequest request; + request.sqeArgCount = TILEXR_CCU_SQE_ARGS_LEN; + request.syncResourceCount = 2; + request.syncInstructionCount = 9; + request.bindingsPerSyncResource = 1; + TileXRCcuProducerPlan producerPlan; + TileXRCcuResourceAllocation allocation; + TileXRCcuResourceAllocatorReport allocatorReport; + if (allocator.Allocate(request, &producerPlan, &allocation, &allocatorReport) != TILEXR_SUCCESS) { + std::cerr << "allocate failed: " << allocatorReport.message << "\n"; + return 4; + } + + std::vector remoteCcuBuffers; + TileXRCcuRemoteCcuBufferInfo remote0; + remote0.remoteCcuVa = specInfo.xnBaseAddr + allocation.remoteXn.startId * 8ULL; + remote0.memoryTokenId = 0x23456; + remote0.memoryTokenValue = 0x5678; + remote0.remoteNotifyCke = 0x360; + remoteCcuBuffers.push_back(remote0); + TileXRCcuRemoteCcuBufferInfo remote1 = remote0; + remote1.remoteCcuVa = specInfo.xnBaseAddr + (allocation.remoteXn.startId + 1U) * 8ULL; + remote1.memoryTokenId = 0x23457; + remote1.memoryTokenValue = 0x5679; + remote1.remoteNotifyCke = 0x361; + remoteCcuBuffers.push_back(remote1); + + TileXRCcuLowerLayerTransportSnapshot snapshot; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, remoteCcuBuffers, &snapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "template build failed: " << report.message << "\n"; + return 5; + } + if (!snapshot.msidToken.valid || snapshot.msidToken.dieId != 1 || + snapshot.msidToken.msId != 0x45 || snapshot.msidToken.tokenId != 0x1234 || + snapshot.msidToken.tokenValue != 0) { + std::cerr << "msid token template mismatch\n"; + return 6; + } + if (snapshot.dieId != 1 || snapshot.pfeOffset != allocation.channels.startId || + snapshot.pfeId != allocation.channels.startId || + snapshot.startJettyId != 1024 || snapshot.startLocalJettyCtxId != 0 || + snapshot.xnStartId != allocation.localXn.startId || + snapshot.xnCount != allocation.localXn.num || + snapshot.ckeStartId != allocation.notifyCke.startId || + snapshot.ckeCount != allocation.notifyCke.num) { + std::cerr << "template scalar mismatch\n"; + return 7; + } + if (snapshot.routes.size() != 2 || snapshot.routes[0].channelId != allocation.channels.startId || + snapshot.routes[1].channelId != allocation.channels.startId + 1U || + snapshot.routes[0].remoteXnId != allocation.remoteXn.startId || + snapshot.routes[1].remoteXnId != allocation.remoteXn.startId + 1U || + snapshot.routes[0].remoteNotifyCke != 0x360 || + snapshot.routes[1].remoteNotifyCke != 0x361 || + snapshot.routes[0].wqeBasicBlockStartId != 0 || + snapshot.routes[1].wqeBasicBlockStartId != 4 || + snapshot.routes[0].remoteCcuVa != remoteCcuBuffers[0].remoteCcuVa || + snapshot.routes[1].remoteCcuVa != remoteCcuBuffers[1].remoteCcuVa || + snapshot.routes[0].memoryTokenId != 0x23456 || + snapshot.routes[0].memoryTokenValue != 0x5678 || + snapshot.routes[1].memoryTokenId != 0x23457 || + snapshot.routes[1].memoryTokenValue != 0x5679) { + std::cerr << "route template mismatch\n"; + return 8; + } + if (report.message != "ok" || report.channelCount != 2 || report.ckeClearCount != 1) { + std::cerr << "report mismatch\n"; + return 9; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_template_accepts_basic_info_without_basic_msid_token(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuBasicInfo basic; + basic.dieId = 1; + basic.msId = 0x45; + basic.msidToken.tokenId = 0; + basic.msidToken.tokenValue = 0; + basic.msidToken.valid = false; + + TileXRCcuResourceAllocation allocation; + allocation.channels = {1, 2, 1}; + allocation.localXn = {1, 0x1a0, 1}; + allocation.remoteXn = {1, 0x2a0, 1}; + allocation.notifyCke = {1, 0x220, 1}; + + std::vector remoteCcuBuffers; + TileXRCcuRemoteCcuBufferInfo remote; + remote.remoteCcuVa = 0x0000009234000000ULL; + remote.memoryTokenId = 0x23456; + remote.memoryTokenValue = 0x5678; + remote.remoteNotifyCke = 0x360; + remoteCcuBuffers.push_back(remote); + + TileXRCcuLowerLayerTransportSnapshot snapshot; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, remoteCcuBuffers, &snapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "template build failed: " << report.message << "\n"; + return 1; + } + if (snapshot.msidToken.valid || snapshot.msidToken.tokenId != 0 || + snapshot.msidToken.tokenValue != 0 || snapshot.msidToken.dieId != 1 || + snapshot.msidToken.msId != 0x45) { + std::cerr << "basic-info token should remain absent in template\n"; + return 2; + } + if (report.msidTokenCount != 0 || report.channelCount != 1 || + snapshot.routes.size() != 1 || snapshot.routes[0].memoryTokenId != 0x23456) { + std::cerr << "template route/report mismatch\n"; + return 3; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_template_promotes_verified_endpoint_route_from_remote_buffer_info(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuBasicInfo basic; + basic.dieId = 1; + basic.msId = 0x45; + basic.msidToken.tokenId = 0x1234; + basic.msidToken.valid = true; + + TileXRCcuResourceAllocation allocation; + allocation.channels = {1, 2, 1}; + allocation.localXn = {1, 0x1a0, 1}; + allocation.remoteXn = {1, 0x2a0, 1}; + allocation.notifyCke = {1, 0x220, 1}; + + TileXRCcuRemoteCcuBufferInfo remote; + remote.remoteCcuVa = 0x0000009234000000ULL; + remote.memoryTokenId = 0x23456; + remote.memoryTokenValue = 0x5678; + remote.remoteXnId = 0x2a7; + remote.remoteNotifyCke = 0x361; + for (uint32_t i = 0; i < remote.remoteEid.size(); ++i) { + remote.remoteEid[i] = static_cast(0x80 + i); + } + remote.tpn = 0x010203; + remote.doorbellVa = 0x1122334455667788ULL; + remote.doorbellTokenId = 0x3456; + remote.doorbellTokenValue = 0; + remote.sqDepth = 64; + remote.endpointRouteVerified = true; + std::vector remoteCcuBuffers {remote}; + + TileXRCcuLowerLayerTransportSnapshot snapshot; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, remoteCcuBuffers, &snapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "template build failed: " << report.message << "\n"; + return 1; + } + if (snapshot.routes.size() != 1 || + !snapshot.routes[0].endpointRouteVerified || + snapshot.routes[0].remoteEid[0] != 0x80 || + snapshot.routes[0].tpn != remote.tpn || + snapshot.routes[0].doorbellVa != remote.doorbellVa || + snapshot.routes[0].doorbellTokenId != remote.doorbellTokenId || + snapshot.routes[0].doorbellTokenValue != remote.doorbellTokenValue || + snapshot.routes[0].sqDepth != remote.sqDepth || + snapshot.routes[0].remoteXnId != remote.remoteXnId || + snapshot.routes[0].remoteNotifyCke != remote.remoteNotifyCke) { + std::cerr << "verified endpoint route was not promoted from remote buffer info\n"; + return 2; + } + + TileXRCcuLowerLayerInstallPlan plan; + if (TileXRCcuBuildLowerLayerInstallPlanFromTransportSnapshot(snapshot, &plan, &report) != + TILEXR_SUCCESS) { + std::cerr << "install plan build failed: " << report.message << "\n"; + return 3; + } + if (plan.remoteXnBindings.size() != 1 || + !plan.remoteXnBindings[0].endpointRouteVerified || + plan.remoteXnBindings[0].remoteXn != remote.remoteXnId || + plan.remoteXnBindings[0].notifyCke != remote.remoteNotifyCke) { + std::cerr << "verified endpoint proof was not propagated\n"; + return 4; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_template_rejects_incomplete_verified_endpoint_route_from_remote_buffer_info(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuBasicInfo basic; + basic.dieId = 1; + basic.msId = 0x45; + basic.msidToken.tokenId = 0x1234; + basic.msidToken.valid = true; + + TileXRCcuResourceAllocation allocation; + allocation.channels = {1, 2, 1}; + allocation.localXn = {1, 0x1a0, 1}; + allocation.remoteXn = {1, 0x2a0, 1}; + allocation.notifyCke = {1, 0x220, 1}; + + TileXRCcuRemoteCcuBufferInfo remote; + remote.remoteCcuVa = 0x0000009234000000ULL; + remote.memoryTokenId = 0x23456; + remote.memoryTokenValue = 0x5678; + remote.remoteXnId = 0x2a7; + remote.remoteNotifyCke = 0x361; + remote.remoteEid[0] = 0x80; + remote.tpn = 0x010203; + remote.doorbellVa = 0x1122334455667788ULL; + remote.doorbellTokenId = 0; + remote.sqDepth = 64; + remote.endpointRouteVerified = true; + std::vector remoteCcuBuffers {remote}; + + TileXRCcuLowerLayerTransportSnapshot snapshot; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, remoteCcuBuffers, &snapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "template build failed: " << report.message << "\n"; + return 1; + } + if (snapshot.routes.size() != 1 || + snapshot.routes[0].endpointRouteVerified || + snapshot.routes[0].remoteEid[0] != 0 || + snapshot.routes[0].tpn != 0 || + snapshot.routes[0].doorbellVa != 0 || + snapshot.routes[0].sqDepth != 0) { + std::cerr << "incomplete endpoint route should fail closed\n"; + return 2; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_template_rejects_channel_allocation_smaller_than_routes(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuBasicInfo basic; + basic.dieId = 1; + basic.msId = 0x45; + basic.msidToken.tokenId = 0x1234; + basic.msidToken.valid = true; + + TileXRCcuResourceAllocation allocation; + allocation.channels = {1, 2, 1}; + allocation.localXn = {1, 0x1a0, 2}; + allocation.remoteXn = {1, 0x2a0, 2}; + allocation.notifyCke = {1, 0x360, 2}; + allocation.localWaitCke = {1, 0x220, 2}; + allocation.remoteNotifyCke = {1, 0x360, 2}; + + std::vector remoteCcuBuffers; + TileXRCcuRemoteCcuBufferInfo remote0; + remote0.remoteCcuVa = 0x0000009234000000ULL; + remote0.memoryTokenId = 0x23456; + remote0.memoryTokenValue = 0x5678; + remoteCcuBuffers.push_back(remote0); + TileXRCcuRemoteCcuBufferInfo remote1 = remote0; + remote1.remoteCcuVa = 0x0000009334000000ULL; + remote1.memoryTokenId = 0x23457; + remoteCcuBuffers.push_back(remote1); + + TileXRCcuLowerLayerTransportSnapshot snapshot; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, remoteCcuBuffers, &snapshot, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "template accepted an allocation with too few channels\n"; + return 1; + } + if (report.message.find("channel allocation count") == std::string::npos) { + std::cerr << "weak channel allocation diagnostic: " << report.message << "\n"; + return 2; + } + if (!snapshot.routes.empty()) { + std::cerr << "failed template should not retain routes\n"; + return 3; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_template_uses_local_wait_cke_for_clear_and_remote_notify_cke_for_routes(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuBasicInfo basic; + basic.dieId = 1; + basic.msId = 0x45; + basic.msidToken.tokenId = 0x1234; + basic.msidToken.tokenValue = 0; + basic.msidToken.valid = true; + + TileXRCcuResourceAllocation allocation; + allocation.channels = {1, 2, 2}; + allocation.localXn = {1, 0x1a0, 2}; + allocation.remoteXn = {1, 0x2a0, 2}; + allocation.notifyCke = {1, 0x360, 2}; + allocation.localWaitCke = {1, 0x220, 2}; + allocation.remoteNotifyCke = {1, 0x360, 2}; + + std::vector remoteCcuBuffers; + TileXRCcuRemoteCcuBufferInfo remote0; + remote0.remoteCcuVa = 0x0000009234000000ULL; + remote0.memoryTokenId = 0x23456; + remote0.memoryTokenValue = 0x5678; + remote0.remoteNotifyCke = 0; + remoteCcuBuffers.push_back(remote0); + TileXRCcuRemoteCcuBufferInfo remote1 = remote0; + remote1.remoteCcuVa = 0x0000009334000000ULL; + remote1.memoryTokenId = 0x23457; + remote1.memoryTokenValue = 0x5679; + remoteCcuBuffers.push_back(remote1); + + TileXRCcuLowerLayerTransportSnapshot snapshot; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, remoteCcuBuffers, &snapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "template build failed: " << report.message << "\n"; + return 1; + } + if (snapshot.ckeStartId != 0x220 || snapshot.ckeCount != 2) { + std::cerr << "local wait CKE clear range mismatch\n"; + return 2; + } + if (snapshot.routes.size() != 2 || + snapshot.routes[0].remoteNotifyCke != 0x360 || + snapshot.routes[1].remoteNotifyCke != 0x361) { + std::cerr << "remote notify CKE route fallback mismatch\n"; + return 3; + } + for (uint32_t i = 0; i < snapshot.routes.size(); ++i) { + for (uint32_t eidIndex = 0; eidIndex < TILEXR_CCU_EID_BYTES; ++eidIndex) { + snapshot.routes[i].remoteEid[eidIndex] = + static_cast(0x40 + i * 0x10 + eidIndex); + } + snapshot.routes[i].tpn = 0x010200 + i; + snapshot.routes[i].doorbellVa = 0x1111222233334444ULL + i * 0x1000ULL; + snapshot.routes[i].doorbellTokenId = 0x12345; + snapshot.routes[i].doorbellTokenValue = 0; + snapshot.routes[i].sqDepth = 8; + } + + TileXRCcuLowerLayerInstallPlan plan; + if (TileXRCcuBuildLowerLayerInstallPlanFromTransportSnapshot(snapshot, &plan, &report) != + TILEXR_SUCCESS) { + std::cerr << "install plan build failed: " << report.message << "\n"; + return 4; + } + if (plan.remoteXnBindings.size() != 2 || + plan.remoteXnBindings[0].notifyCke != 0x360 || + plan.remoteXnBindings[0].localWaitCke != 0x220 || + plan.remoteXnBindings[1].notifyCke != 0x361 || + plan.remoteXnBindings[1].localWaitCke != 0x221) { + std::cerr << "split CKE remote XN proof mismatch\n"; + return 5; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_overlay_verified_endpoint_routes_updates_only_matching_endpoint_fields(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuLowerLayerTransportSnapshot snapshot; + snapshot.routes.resize(2); + snapshot.routes[0].channelId = 0x20; + snapshot.routes[0].peerRank = 3; + snapshot.routes[0].remoteXnId = 0x1a0; + snapshot.routes[0].remoteNotifyCke = 0x360; + snapshot.routes[0].wqeBasicBlockStartId = 0x12; + snapshot.routes[0].memoryTokenId = 0x2001; + snapshot.routes[0].remoteCcuVa = 0x90000000ULL; + snapshot.routes[1].channelId = 0x21; + snapshot.routes[1].peerRank = 4; + snapshot.routes[1].remoteXnId = 0x1a1; + snapshot.routes[1].remoteNotifyCke = 0x361; + + TileXRCcuLowerLayerTransportRoute verified; + verified.channelId = 0x20; + verified.peerRank = 99; + verified.remoteXnId = 0x2b0; + verified.remoteNotifyCke = 0x470; + for (uint32_t i = 0; i < verified.remoteEid.size(); ++i) { + verified.remoteEid[i] = static_cast(0xc0 + i); + } + verified.tpn = 0x010203; + verified.doorbellVa = 0x1122334455667788ULL; + verified.doorbellTokenId = 0x3456; + verified.doorbellTokenValue = 0; + verified.sqDepth = 64; + verified.wqeBasicBlockStartId = 0x77; + verified.memoryTokenId = 0x9999; + verified.remoteCcuVa = 0xabcdefULL; + verified.endpointRouteVerified = true; + + TileXRCcuLowerLayerPlanBuilderReport report; + std::vector routes {verified}; + if (TileXRCcuOverlayVerifiedEndpointRoutes(routes, &snapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "overlay failed: " << report.message << "\n"; + return 1; + } + + const auto& route0 = snapshot.routes[0]; + if (!route0.endpointRouteVerified || + route0.remoteEid[0] != 0xc0 || + route0.tpn != verified.tpn || + route0.doorbellVa != verified.doorbellVa || + route0.doorbellTokenId != verified.doorbellTokenId || + route0.doorbellTokenValue != verified.doorbellTokenValue || + route0.sqDepth != verified.sqDepth) { + std::cerr << "verified endpoint fields were not overlaid\n"; + return 2; + } + if (route0.peerRank != 3 || + route0.remoteXnId != 0x1a0 || + route0.remoteNotifyCke != 0x360 || + route0.wqeBasicBlockStartId != 0x12 || + route0.memoryTokenId != 0x2001 || + route0.remoteCcuVa != 0x90000000ULL) { + std::cerr << "overlay changed non-endpoint resource fields\n"; + return 3; + } + if (snapshot.routes[1].endpointRouteVerified || + snapshot.routes[1].remoteEid[0] != 0 || + snapshot.routes[1].tpn != 0 || + snapshot.routes[1].doorbellVa != 0) { + std::cerr << "overlay changed an unmatched route\n"; + return 4; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_template_uses_peer_exchanged_remote_xn_ids_when_present(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuBasicInfo basic; + basic.dieId = 1; + basic.msId = 0x45; + basic.msidToken.tokenId = 0x1234; + basic.msidToken.valid = true; + + TileXRCcuResourceAllocation allocation; + allocation.channels = {1, 2, 2}; + allocation.localXn = {1, 0x2a0, 2}; + allocation.remoteXn = {1, 0x2b0, 2}; + allocation.notifyCke = {1, 0x360, 2}; + allocation.localWaitCke = {1, 0x220, 2}; + allocation.remoteNotifyCke = {1, 0x360, 2}; + + std::vector remoteCcuBuffers; + TileXRCcuRemoteCcuBufferInfo remote0; + remote0.remoteCcuVa = 0x0000009234000000ULL; + remote0.memoryTokenId = 0x23456; + remote0.memoryTokenValue = 0x5678; + remote0.remoteXnId = 0x1a0; + remote0.remoteNotifyCke = 0x360; + remoteCcuBuffers.push_back(remote0); + TileXRCcuRemoteCcuBufferInfo remote1 = remote0; + remote1.remoteCcuVa = 0x0000009334000000ULL; + remote1.memoryTokenId = 0x23457; + remote1.memoryTokenValue = 0x5679; + remote1.remoteXnId = 0x1a1; + remote1.remoteNotifyCke = 0x361; + remoteCcuBuffers.push_back(remote1); + + TileXRCcuLowerLayerTransportSnapshot snapshot; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, remoteCcuBuffers, &snapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "template build failed: " << report.message << "\n"; + return 1; + } + if (snapshot.routes.size() != 2 || + snapshot.routes[0].remoteXnId != 0x1a0 || + snapshot.routes[1].remoteXnId != 0x1a1) { + std::cerr << "peer exchanged remote XN IDs were not preserved\n"; + return 2; + } + for (uint32_t i = 0; i < snapshot.routes.size(); ++i) { + for (uint32_t eidIndex = 0; eidIndex < TILEXR_CCU_EID_BYTES; ++eidIndex) { + snapshot.routes[i].remoteEid[eidIndex] = + static_cast(0x40 + i * 0x10 + eidIndex); + } + snapshot.routes[i].tpn = 0x010200 + i; + snapshot.routes[i].doorbellVa = 0x1111222233334444ULL + i * 0x1000ULL; + snapshot.routes[i].doorbellTokenId = 0x12345; + snapshot.routes[i].sqDepth = 8; + } + + TileXRCcuLowerLayerInstallPlan plan; + if (TileXRCcuBuildLowerLayerInstallPlanFromTransportSnapshot(snapshot, &plan, &report) != + TILEXR_SUCCESS) { + std::cerr << "install plan build failed: " << report.message << "\n"; + return 3; + } + if (plan.remoteXnBindings.size() != 2 || + plan.remoteXnBindings[0].remoteXn != 0x1a0 || + plan.remoteXnBindings[1].remoteXn != 0x1a1 || + !plan.remoteXnBindings[0].peerExchangeObserved || + !plan.remoteXnBindings[1].peerExchangeObserved || + plan.remoteXnBindings[0].endpointRouteVerified || + plan.remoteXnBindings[1].endpointRouteVerified) { + std::cerr << "peer exchanged remote XN proof mismatch\n"; + return 4; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_transport_template_carries_explicit_channel_owner_exchange_proof(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + #include + + using namespace TileXR; + + int main() + { + TileXRCcuBasicInfo basic; + basic.dieId = 1; + basic.msId = 0x45; + basic.msidToken.tokenId = 0x1234; + basic.msidToken.valid = true; + + TileXRCcuResourceAllocation allocation; + allocation.channels = {1, 2, 1}; + allocation.localXn = {1, 0x2a0, 1}; + allocation.remoteXn = {1, 0x2b0, 1}; + allocation.notifyCke = {1, 0x360, 1}; + allocation.localWaitCke = {1, 0x220, 1}; + allocation.remoteNotifyCke = {1, 0x360, 1}; + + TileXRCcuRemoteCcuBufferInfo endpointOnly; + endpointOnly.remoteCcuVa = 0x0000009234000000ULL; + endpointOnly.memoryTokenId = 0x23456; + endpointOnly.memoryTokenValue = 0x5678; + endpointOnly.remoteXnId = 0x1a0; + endpointOnly.remoteNotifyCke = 0x360; + for (uint32_t i = 0; i < TILEXR_CCU_EID_BYTES; ++i) { + endpointOnly.remoteEid[i] = static_cast(0x40 + i); + } + endpointOnly.tpn = 0x010200; + endpointOnly.doorbellVa = 0x1111222233334444ULL; + endpointOnly.doorbellTokenId = 0x12345; + endpointOnly.sqDepth = 8; + endpointOnly.endpointRouteVerified = true; + + TileXRCcuLowerLayerTransportSnapshot endpointOnlySnapshot; + TileXRCcuLowerLayerPlanBuilderReport report; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, {endpointOnly}, &endpointOnlySnapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "endpoint-only template build failed: " << report.message << "\n"; + return 1; + } + TileXRCcuLowerLayerInstallPlan endpointOnlyPlan; + if (TileXRCcuBuildLowerLayerInstallPlanFromTransportSnapshot( + endpointOnlySnapshot, &endpointOnlyPlan, &report) != TILEXR_SUCCESS) { + std::cerr << "endpoint-only plan build failed: " << report.message << "\n"; + return 2; + } + if (!endpointOnlyPlan.remoteXnBindings[0].endpointRouteVerified || + endpointOnlyPlan.remoteXnBindings[0].channelResourceOwnerVerified || + endpointOnlyPlan.remoteXnBindings[0].transportResourceExchangeVerified) { + std::cerr << "endpoint route alone was promoted to owner/exchange proof\n"; + return 3; + } + + TileXRCcuRemoteCcuBufferInfo proven = endpointOnly; + proven.channelResourceOwnerVerified = true; + proven.transportResourceExchangeVerified = true; + + TileXRCcuLowerLayerTransportSnapshot provenSnapshot; + if (TileXRCcuBuildLowerLayerTransportTemplate( + basic, allocation, {proven}, &provenSnapshot, &report) != TILEXR_SUCCESS) { + std::cerr << "proven template build failed: " << report.message << "\n"; + return 4; + } + if (!provenSnapshot.routes[0].channelResourceOwnerVerified || + !provenSnapshot.routes[0].transportResourceExchangeVerified) { + std::cerr << "route did not preserve owner/exchange proof\n"; + return 5; + } + + TileXRCcuLowerLayerInstallPlan provenPlan; + if (TileXRCcuBuildLowerLayerInstallPlanFromTransportSnapshot( + provenSnapshot, &provenPlan, &report) != TILEXR_SUCCESS) { + std::cerr << "proven plan build failed: " << report.message << "\n"; + return 6; + } + const auto& proof = provenPlan.remoteXnBindings[0]; + if (!proof.endpointRouteVerified || + !proof.channelResourceOwnerVerified || + !proof.transportResourceExchangeVerified) { + std::cerr << "install proof did not preserve owner/exchange proof\n"; + return 7; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_plan_builder_rejects_incomplete_lower_layer_inputs(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_lower_layer_plan_builder.h" + + #include + + using namespace TileXR; + + int main() + { + TileXRCcuLowerLayerInstallPlan plan; + TileXRCcuLowerLayerPlanBuilderReport report; + TileXRCcuLowerLayerPlanSpec spec; + if (TileXRCcuBuildLowerLayerInstallPlan(spec, &plan, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "empty lower-layer spec accepted\n"; + return 1; + } + if (report.message.find("missing lower-layer CCU MSID token") == std::string::npos) { + std::cerr << "weak empty-spec diagnostic: " << report.message << "\n"; + return 2; + } + + spec.msidToken.valid = true; + spec.msidToken.tokenId = 0; + spec.pfe.dieId = 0; + spec.pfe.pfeOffset = 1; + spec.pfe.startJettyId = 0x10; + spec.pfe.startLocalJettyCtxId = 0x2; + TileXRCcuLowerLayerJettySpec jetty; + jetty.startJettyCtxId = 0x2; + jetty.doorbellVa = 0x1000; + jetty.doorbellTokenId = 9; + jetty.sqDepth = 8; + spec.jettys.push_back(jetty); + TileXRCcuLowerLayerChannelSpec channel; + channel.channelId = 1; + channel.sourcePfeId = 1; + channel.startJettyId = 0x10; + channel.memoryTokenId = 7; + channel.remoteCcuVa = 0x200000; + spec.channels.push_back(channel); + spec.xnClear.valid = true; + spec.xnClear.count = 1; + spec.ckeClear.valid = true; + spec.ckeClear.count = 1; + if (TileXRCcuBuildLowerLayerInstallPlan(spec, &plan, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "channel with empty remote EID accepted\n"; + return 3; + } + if (report.message.find("invalid CCU channel context v1 spec") == std::string::npos) { + std::cerr << "weak channel diagnostic: " << report.message << "\n"; + return 4; + } + + for (uint32_t i = 0; i < TILEXR_CCU_EID_BYTES; ++i) { + spec.channels[0].remoteEid[i] = static_cast(0x40 + i); + } + if (TileXRCcuBuildLowerLayerInstallPlan(spec, &plan, &report) != TILEXR_SUCCESS) { + std::cerr << "valid zero-token lower-layer spec rejected: " << report.message << "\n"; + return 5; + } + if (plan.msidTokens.empty() || plan.msidTokens[0].tokenId != 0 || + plan.channels.empty() || plan.channels[0].ctx.raw[0] != 0x40) { + std::cerr << "valid zero-token lower-layer plan mismatch\n"; + return 6; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_plan_builder_surface_is_wired_into_tilexr_comm_without_udma_boundary(self): + header = BUILDER_HEADER.read_text(encoding="utf-8") + source = BUILDER_SOURCE.read_text(encoding="utf-8") + runtime_header = DIRECT_RUNTIME_HEADER.read_text(encoding="utf-8") + runtime_source = DIRECT_RUNTIME_SOURCE.read_text(encoding="utf-8") + + self.assertIn("TileXRCcuLowerLayerTransportSnapshot", header) + self.assertIn("TileXRCcuLowerLayerTransportRoute", header) + self.assertIn("TileXRCcuRemoteCcuBufferInfo", header) + self.assertIn("TileXRCcuBuildLowerLayerTransportTemplate", header) + self.assertIn("TileXRCcuBuildLowerLayerInstallPlanFromTransportSnapshot", header) + self.assertIn("remoteXnBindings", header) + self.assertIn("localWaitCke", source) + self.assertIn("TileXRCcuBuildPfeCtx", source) + self.assertIn("TileXRCcuBuildLocalJettyCtx", source) + self.assertIn("TileXRCcuBuildChannelCtxV1", source) + self.assertIn("allocation.channels.num < remoteCcuBuffers.size()", source) + self.assertIn("channel allocation count does not match lower-layer route count", source) + self.assertNotIn("TILEXR_CCU_DIRECT_SYNC_RESOURCE_MAP", source) + self.assertNotIn("UseHcommTraceSyncResourceMap", source) + self.assertIn("SelectLowerLayerWqeBasicBlockStride", source) + self.assertIn("TILEXR_CCU_DIRECT_LOWER_LAYER_WQE_MODE", source) + self.assertIn("TILEXR_CCU_DIRECT_LOWER_LAYER_PFE_OFFSET_SOURCE", source) + self.assertIn("TILEXR_CCU_DIRECT_LOWER_LAYER_PFE_PARTITION", source) + + self.assertIn("TileXRCcuDirectRuntime", runtime_header) + self.assertIn("ExportLowerLayerTransportSnapshot", runtime_header) + self.assertIn("RegisterCcuResourceRmaBuffer", runtime_header) + self.assertIn("ExportRemoteCcuRmaBuffers", runtime_header) + self.assertIn("TileXRCcuLocalResourceWindowInfo", runtime_header) + self.assertIn("TileXRCcuDirectRuntime::ExportLowerLayerTransportSnapshot", runtime_source) + self.assertIn("TILEXR_CCU_DIRECT_ENDPOINT_ROUTE_EXCHANGE_MODE", runtime_source) + self.assertIn("UseImportedPeerEndpointRoute", runtime_source) + self.assertIn("useImportedPeerRoute &&", runtime_source) + self.assertIn("usePeerExportedRoute", runtime_source) + self.assertRegex( + runtime_source, + r"(?s)\} else \{\s*remote\.tpn = peerWindow\.tpn;.*?usePeerExportedRoute", + ) + self.assertNotIn( + "} else if (!useImportedPeerRoute && TraceEndpointRoute() && peerWindow.endpointRouteVerified)", + runtime_source, + ) + self.assertNotIn("udma/", runtime_header + "\n" + runtime_source) + + combined = header + "\n" + source + "\n" + runtime_header + "\n" + runtime_source + for needle in [ + "#include &remoteCcuBuffers", planner_source) + self.assertIn("TileXRCcuBuildLowerLayerInstallPlanFromTransportSnapshot", planner_source) + self.assertIn("session.RegisterCcuResourceRmaBuffer(basicInfo->resourceAddr)", planner_source) + self.assertIn("session.ExportRemoteCcuRmaBuffers", planner_source) + self.assertIn("ccuDirectRuntime_->ExportLowerLayerTransportSnapshot", runtime_session_source) + self.assertIn("RefreshDirectCcuLowerLayerPlan(session);", planner_source) + self.assertIn("direct CCU lower-layer template is not configured", planner_source) + self.assertIn("direct CCU lower-layer install plan cached", planner_source) + + register_body = comm_source[ + comm_source.index("int TileXRComm::RegisterUDMAMemory"): + comm_source.index("int TileXRComm::UnregisterUDMAMemory") + ] + self.assertIn("return udmaContext_->RegisterMemory(localPtr, bytes, handle);", register_body) + self.assertNotIn("RefreshDirectCcuLowerLayerPlan();", register_body) + self.assertNotIn("ResetDirectCcuLowerLayerPlan();", register_body) + + apply_state_body = comm_source[ + comm_source.index("int TileXRComm::ApplyUDMACommArgsState("): + comm_source.index("int TileXRComm::ApplyUDMACommArgsStateCallback") + ] + self.assertIn("const int ret = UpdateCommArgsDev();", apply_state_body) + + unregister_body = comm_source[ + comm_source.index("int TileXRComm::UnregisterUDMAMemory"): + comm_source.index("GM_ADDR TileXRComm::GetUDMARegistryPtr") + ] + self.assertNotIn("ResetDirectCcuLowerLayerPlan();", unregister_body) + + init_udma_body = comm_source[ + comm_source.index("int TileXRComm::InitUDMA"): + comm_source.index("int TileXRComm::InitCcuBackend") + ] + self.assertNotIn("RefreshDirectCcuBasicInfo", init_udma_body) + self.assertNotIn("ResetDirectCcuBasicInfo", init_udma_body) + + forbidden_patterns = [ + ("udmaTransport_->", "RegisterCcuResourceRmaBuffer"), + ("udmaTransport_->", "ExportLocalCcuRmaBuffer"), + ("udmaTransport_->", "ExportRemoteCcuRmaBuffers"), + ("udmaTransport_->", "ExportLowerLayerTransportSnapshot"), + ] + for prefix, suffix in forbidden_patterns: + self.assertNotIn(prefix + suffix, comm_header + "\n" + comm_source) + for forbidden in [ + "rtCCULaunch", + "TileXRCcuSubmitTask", + "HcclGetCcuTaskInfo", + "HcomGetCcuTaskInfo", + "libhcomm", + "libhccl_v2", + ]: + self.assertNotIn(forbidden, comm_header + "\n" + comm_source + "\n" + backend_source) + + def test_direct_ccu_runtime_owns_resource_window_boundary(self): + runtime_header = DIRECT_RUNTIME_HEADER.read_text(encoding="utf-8") + runtime_source = DIRECT_RUNTIME_SOURCE.read_text(encoding="utf-8") + specs_header = (REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_specs.h").read_text(encoding="utf-8") + comm_header = COMM_HEADER_FILE.read_text(encoding="utf-8") + comm_source = COMM_SOURCE_FILE.read_text(encoding="utf-8") + backend_header = CCU_BACKEND_HEADER.read_text(encoding="utf-8") + backend_source = CCU_BACKEND_SOURCE.read_text(encoding="utf-8") + runtime_session_source = CCU_RUNTIME_SESSION_SOURCE.read_text(encoding="utf-8") + runtime_session_source = CCU_RUNTIME_SESSION_SOURCE.read_text(encoding="utf-8") + runtime_session_source = CCU_RUNTIME_SESSION_SOURCE.read_text(encoding="utf-8") + planner_source = CCU_PLANNER_SOURCE.read_text(encoding="utf-8") + builder_header = BUILDER_HEADER.read_text(encoding="utf-8") + + self.assertIn("TileXRCcuLocalResourceWindowInfo", runtime_header) + self.assertIn("rawTokenId", runtime_header) + self.assertIn("rawMemoryTokenId", builder_header) + self.assertIn("TileXRCcuDirectAllGatherFn", runtime_header) + self.assertIn("localResourceWindow_", runtime_header) + self.assertIn("resourceWindowRegistered_", runtime_header) + self.assertIn("int RegisterCcuResourceRmaBuffer(", runtime_header) + self.assertIn("ExportLocalCcuRmaBuffer", runtime_header) + self.assertIn("int ExportRemoteCcuRmaBuffers(", runtime_header) + self.assertIn("int TileXRCcuDirectRuntime::RegisterCcuResourceRmaBuffer", runtime_source) + self.assertIn("int TileXRCcuDirectRuntime::ExportLocalCcuRmaBuffer", runtime_source) + self.assertIn("int TileXRCcuDirectRuntime::ExportRemoteCcuRmaBuffers", runtime_source) + self.assertIn("int TileXRCcuDirectRuntime::ExportLowerLayerTransportSnapshot", runtime_source) + self.assertIn("localResourceWindow_.addr = resourceAddr", runtime_source) + self.assertIn("resourceWindowRegistered_ = true", runtime_source) + self.assertIn("TILEXR_CCU_RESOURCE_WINDOW_BYTES", specs_header) + self.assertIn("72ULL * 1024ULL * 1024ULL", specs_header) + self.assertIn("return TILEXR_CCU_RESOURCE_WINDOW_BYTES", runtime_source) + self.assertIn("options_.allGather", runtime_source) + self.assertIn("route.remoteEid", runtime_source) + self.assertIn("route.doorbellVa", runtime_source) + self.assertIn("route.sqDepth", runtime_source) + + for leaked in [ + "ConfigureDirectCcuLowerLayerTemplateFromAllocation(", + "PrepareDirectCcuLowerLayerTemplateFromAllocation", + "ExchangeDirectCcuRemoteNotifyCke", + "DirectCcuAllGatherCallback", + "DirectCcuThreadAllGather", + "directCcuVerifiedEndpointRoutes_", + "directCcuLocalVerifiedEndpointRoute_", + ]: + with self.subTest(leaked=leaked): + self.assertNotIn(leaked, comm_header) + self.assertNotIn(leaked, backend_header) + + self.assertIn("const std::vector &remoteCcuBuffers", planner_source) + self.assertIn("ccuDirectRuntime_->RegisterCcuResourceRmaBuffer", runtime_session_source) + self.assertIn("ccuDirectRuntime_->ExportLocalCcuRmaBuffer", runtime_session_source) + self.assertIn("ccuDirectRuntime_->ExportRemoteCcuRmaBuffers", runtime_session_source) + self.assertIn("runtimeOptions.allGather = &TileXRCcuRuntimeSession::DirectCcuAllGatherCallback", runtime_session_source) + self.assertIn("runtimeOptions.allGatherUserData = this", runtime_session_source) + self.assertIn("int TileXRCcuCollectivePlanner::ExchangeDirectCcuRemoteNotifyCke", planner_source) + self.assertIn("int TileXRCcuRuntimeSession::DirectCcuThreadAllGather", runtime_session_source) + self.assertIn("session.AllGather(&local, sizeof(local), all.data())", planner_source) + self.assertIn("session->DirectCcuThreadAllGather(sendBuf, sendBytes, recvBuf)", runtime_session_source) + self.assertIn("TileXRComm::InitCcuBackend", comm_source) + self.assertIn("return ccuBackend_->Init(options);", comm_source) + exchange_body = planner_source[ + planner_source.index("int TileXRCcuCollectivePlanner::ExchangeDirectCcuRemoteNotifyCke"): + planner_source.index("int TileXRCcuCollectivePlanner::PrepareDirectCcuLowerLayerPlanCallback") + ] + self.assertNotIn("SelectDirectCcuRemoteBindingOverride", exchange_body) + self.assertIn("peerLocalWaitCkeOffset", exchange_body) + self.assertIn("peerResources.localWaitCkeStartId", exchange_body) + self.assertIn("peerResources.localWaitCkeCount", exchange_body) + self.assertNotIn("allocation.remoteNotifyCke.startId,\n routeIndex", exchange_body) + self.assertIn("allocation.localXn.startId", planner_source) + self.assertIn("remoteXnStartId", exchange_body) + self.assertIn("remoteXnCount", exchange_body) + self.assertNotIn("TILEXR_CCU_V1_XN_RESOURCE_OFFSET", exchange_body) + self.assertNotIn("TILEXR_CCU_XN_SLOT_BYTES", exchange_body) + self.assertIn("remoteXnId", planner_source) + self.assertIn("remoteNotifyCke", planner_source) + self.assertIn("templateSnapshot.msidToken.tokenId = localCcuResourceWindow.tokenId", planner_source) + self.assertIn("templateSnapshot.msidToken.tokenValue = localCcuResourceWindow.tokenValue", planner_source) + self.assertIn("templateSnapshot.msidToken.valid = true", planner_source) + self.assertIn("directCcuVerifiedEndpointRoutes_", planner_source) + self.assertIn("TileXRCcuCollectivePlanner::ConfigureDirectCcuVerifiedEndpointRoutes", planner_source) + self.assertIn("directCcuLocalVerifiedEndpointRoute_", planner_source) + self.assertIn("TileXRCcuCollectivePlanner::ConfigureDirectCcuLocalVerifiedEndpointRoute", planner_source) + self.assertIn("ccuDirectRuntime_->ConfigureLocalVerifiedEndpointRoute", runtime_session_source) + self.assertIn("ccuDirectRuntime_->RefreshLocalVerifiedEndpointRoute", runtime_session_source) + self.assertIn("TileXRCcuLocalEndpointRouteCollectorFn", runtime_header) + self.assertIn("localEndpointRouteCollector", runtime_header) + self.assertIn("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_EID", runtime_source) + self.assertIn("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_DOORBELL_VA", runtime_source) + self.assertIn("direct CCU local endpoint route collected", runtime_source) + self.assertIn("TileXRCcuOverlayVerifiedEndpointRoutes", builder_header) + self.assertGreaterEqual(planner_source.count("TileXRCcuOverlayVerifiedEndpointRoutes("), 3) + init_runtime_body = runtime_session_source[ + runtime_session_source.index("int TileXRCcuRuntimeSession::Init("): + runtime_session_source.index("void TileXRCcuRuntimeSession::ResetDirectCcuBasicInfo") + ] + self.assertIn("logicDevId", init_runtime_body) + self.assertIn("devicePhyId", init_runtime_body) + self.assertIn("hdcType", init_runtime_body) + self.assertIn("raInitialized", init_runtime_body) + self.assertNotIn("udma/", runtime_header + "\n" + runtime_source) + + register_body = runtime_source[ + runtime_source.index("int TileXRCcuDirectRuntime::RegisterCcuResourceRmaBuffer"): + runtime_source.index("int TileXRCcuDirectRuntime::ExportLocalCcuRmaBuffer") + ] + export_local_body = runtime_source[ + runtime_source.index("int TileXRCcuDirectRuntime::ExportLocalCcuRmaBuffer"): + runtime_source.index("int TileXRCcuDirectRuntime::ExportRemoteCcuRmaBuffers") + ] + export_remote_body = runtime_source[ + runtime_source.index("int TileXRCcuDirectRuntime::ExportRemoteCcuRmaBuffers"): + runtime_source.index("int TileXRCcuDirectRuntime::ExportLowerLayerTransportSnapshot") + ] + prepare_from_allocation_body = planner_source[ + planner_source.index("int TileXRCcuCollectivePlanner::PrepareDirectCcuLowerLayerTemplateFromAllocation"): + planner_source.index("int TileXRCcuCollectivePlanner::FillDirectCcuLowerLayerPlanFromAllocation") + ] + export_snapshot_body = runtime_source[ + runtime_source.index("int TileXRCcuDirectRuntime::ExportLowerLayerTransportSnapshot"): + ] + self.assertNotIn("int TileXRCcuDirectRuntime::RegisterCcuResourceRmaBuffer(uint64_t)\n{\n return TILEXR_ERROR_NOT_FOUND;\n}", runtime_source) + self.assertNotIn("*info = TileXRCcuLocalResourceWindowInfo{};\n return TILEXR_ERROR_NOT_FOUND;", export_local_body) + self.assertNotIn("buffers->clear();\n return TILEXR_ERROR_NOT_FOUND;", export_remote_body) + self.assertNotIn("*snapshot = TileXRCcuLowerLayerTransportSnapshot{};\n return TILEXR_ERROR_NOT_FOUND;", export_snapshot_body) + self.assertLess( + prepare_from_allocation_body.index("session.ConfigureLocalVerifiedEndpointRoute"), + prepare_from_allocation_body.index("session.ExportRemoteCcuRmaBuffers"), + ) + + register_memory_body = comm_source[ + comm_source.index("int TileXRComm::RegisterUDMAMemory"): + comm_source.index("int TileXRComm::UnregisterUDMAMemory") + ] + self.assertNotIn("RefreshDirectCcuLowerLayerPlan();", register_memory_body) + self.assertNotIn("ResetDirectCcuLowerLayerPlan();", register_memory_body) + + def test_remote_xn_exchange_uses_peer_channel_local_xn_operand(self): + planner_source = CCU_PLANNER_SOURCE.read_text(encoding="utf-8") + exchange_body = planner_source[ + planner_source.index("int TileXRCcuCollectivePlanner::ExchangeDirectCcuRemoteNotifyCke"): + planner_source.index("int TileXRCcuCollectivePlanner::PrepareDirectCcuLowerLayerPlanCallback") + ] + compact_body = " ".join(exchange_body.split()) + + self.assertIn( + "channelBoundRemoteXnId = SelectDirectCcuChannelBoundRemoteXnId( peerResources.remoteXnStartId, peerLocalIndex, syncIndex, peerRouteCount)", + compact_body) + self.assertIn( + "peerLocalXnId = static_cast(static_cast(peerResources.localXnStartId) + peerLocalXnOffset)", + compact_body) + self.assertIn("selectedRemoteXnOffset >= peerResources.remoteXnCount", compact_body) + self.assertNotIn("SelectDirectCcuRemoteBindingOverride", compact_body) + self.assertIn("(*remoteCcuBuffers)[routeIndex].remoteXnId = channelBoundRemoteXnId", compact_body) + self.assertNotIn("(*remoteCcuBuffers)[routeIndex].remoteCcuVa +=", compact_body) + self.assertNotIn("static_cast(peerLocalXnId) * TILEXR_CCU_XN_SLOT_BYTES", compact_body) + self.assertNotIn("TILEXR_CCU_V1_XN_RESOURCE_OFFSET + static_cast(peerLocalXnId)", compact_body) + self.assertNotIn( + "uint16_t remoteXnId = static_cast(peerResources.localXnStartId + peerLocalIndex)", + compact_body) + self.assertNotIn( + "channelBoundRemoteXnId = static_cast(allocation.remoteXn.startId + routeIndex)", + compact_body) + self.assertNotIn( + "static_cast((*remoteCcuBuffers)[routeIndex].remoteXnId) * TILEXR_CCU_XN_SLOT_BYTES", + compact_body) + + def test_remote_notify_cke_comes_from_peer_exported_local_wait_cke(self): + planner_source = CCU_PLANNER_SOURCE.read_text(encoding="utf-8") + exchange_body = planner_source[ + planner_source.index("int TileXRCcuCollectivePlanner::ExchangeDirectCcuRemoteNotifyCke"): + planner_source.index("int TileXRCcuCollectivePlanner::PrepareDirectCcuLowerLayerPlanCallback") + ] + compact_body = " ".join(exchange_body.split()) + + self.assertIn("peerLocalWaitCkeOffset", exchange_body) + self.assertIn("peerLocalWaitCkeOffset >= peerResources.localWaitCkeCount", compact_body) + self.assertIn( + "remoteNotifyCke = static_cast(static_cast(peerResources.localWaitCkeStartId) + peerLocalWaitCkeOffset)", + compact_body) + self.assertNotIn( + "remoteNotifyCke = SelectDirectCcuRemoteNotifyCkeId( allocation.remoteNotifyCke.startId, routeIndex)", + compact_body) + self.assertIn("notifyCkeOwnerVerified", exchange_body) + self.assertIn("notifyCkeOwnerVerified &&", compact_body) + + def test_peer_xn_exchange_expands_one_peer_window_to_multiple_sync_routes(self): + planner_source = CCU_PLANNER_SOURCE.read_text(encoding="utf-8") + exchange_body = planner_source[ + planner_source.index("int TileXRCcuCollectivePlanner::ExchangeDirectCcuRemoteNotifyCke"): + planner_source.index("int TileXRCcuCollectivePlanner::PrepareDirectCcuLowerLayerPlanCallback") + ] + compact_body = " ".join(exchange_body.split()) + + self.assertIn("const size_t peerRouteCount = static_cast(rankSize - 1)", compact_body) + self.assertIn("const size_t syncRouteCount = allocation.remoteXn.num", compact_body) + self.assertIn("allocation.remoteXn.num < static_cast(rankSize - 1)", compact_body) + self.assertNotIn("allocation.remoteXn.num != static_cast(rankSize - 1)", compact_body) + self.assertIn("std::vector peerCcuBuffers = *remoteCcuBuffers", compact_body) + self.assertIn("remoteCcuBuffers->assign(syncRouteCount, TileXRCcuRemoteCcuBufferInfo{})", compact_body) + self.assertIn("for (uint32_t syncIndex = 0; syncIndex < allocation.remoteXn.num; ++syncIndex)", compact_body) + self.assertIn("const size_t peerBufferIndex = syncIndex % peerRouteCount", compact_body) + self.assertIn("(*remoteCcuBuffers)[routeIndex] = peerCcuBuffers[peerBufferIndex]", compact_body) + self.assertIn("channelBoundRemoteXnId = SelectDirectCcuChannelBoundRemoteXnId(", compact_body) + self.assertIn("DirectCcuRemoteXnProofSpan(allocation.remoteXn.num)", compact_body) + + def test_direct_ccu_runtime_imports_peer_endpoint_route_before_export(self): + runtime_source = DIRECT_RUNTIME_SOURCE.read_text(encoding="utf-8") + export_body = runtime_source[ + runtime_source.index("int TileXRCcuDirectRuntime::ExportRemoteCcuRmaBuffers"): + runtime_source.index("int TileXRCcuDirectRuntime::ExportLowerLayerTransportSnapshot") + ] + compact_body = " ".join(export_body.split()) + + self.assertIn("ImportPeerEndpointRoute(", runtime_source) + self.assertIn( + "if (importedPeerRoute) { remote.remoteEid = importedRoute.remoteEid; remote.tpn = importedRoute.tpn", + compact_body) + self.assertIn("} else { remote.tpn = peerWindow.tpn", compact_body) + self.assertIn("TILEXR_CCU_DIRECT_REMOTE_CCU_VA_OFFSET", runtime_source) + self.assertIn("const uint64_t remoteCcuVaOffset = SelectRemoteCcuVaOffset()", compact_body) + self.assertIn("remote.remoteCcuVa = peerWindow.addr + remoteCcuVaOffset", compact_body) + self.assertNotIn("remote.remoteCcuVa = peerWindow.addr;", compact_body) + self.assertIn("remote.localDoorbellVa = localVerifiedEndpointRoute_.doorbellVa", compact_body) + self.assertIn("remote.localDoorbellTokenId = localVerifiedEndpointRoute_.doorbellTokenId", compact_body) + self.assertIn("remote.localDoorbellTokenValue = localVerifiedEndpointRoute_.doorbellTokenValue", compact_body) + + def test_direct_ccu_runtime_can_override_resource_window_token_from_rank_env(self): + code = textwrap.dedent( + r''' + #include + #include + + #define private public + #include "ccu/tilexr_ccu_direct_runtime.h" + #undef private + + using namespace TileXR; + + int FakeRaCustomChannel(TileXRCcuRaInfo, TileXRCcuCustomChannelIn*, TileXRCcuCustomChannelOut*) + { + return 0; + } + + int main() + { + TileXRCcuDirectRuntime runtime; + runtime.initialized_ = true; + runtime.loader_.RaCustomChannel = FakeRaCustomChannel; + runtime.loader_.loaded_ = true; + runtime.options_.rank = 1; + runtime.cachedBasicInfoValid_ = true; + runtime.cachedBasicInfo_.resourceAddr = 0x10000000ULL; + runtime.cachedBasicInfo_.msidToken.tokenId = 0x1234; + runtime.cachedBasicInfo_.msidToken.tokenValue = 0x5678; + runtime.cachedBasicInfo_.msidToken.valid = true; + runtime.cachedBasicInfo_.caps.cap1 = 7U << 16U; + + if (runtime.RegisterCcuResourceRmaBuffer(0x10000000ULL) != TILEXR_SUCCESS) { + std::cerr << "register failed\n"; + return 1; + } + TileXRCcuLocalResourceWindowInfo local; + if (runtime.ExportLocalCcuRmaBuffer(&local) != TILEXR_SUCCESS) { + std::cerr << "export failed\n"; + return 2; + } + if (local.tokenId != 0x2222U || + local.rawTokenId != 0x3333U || + local.tokenValue != 0x4444U) { + std::cerr << "rank override was not applied tokenId=" << local.tokenId + << " rawTokenId=" << local.rawTokenId + << " tokenValue=" << local.tokenValue << "\n"; + return 3; + } + + TileXRCcuDirectRuntime defaultRuntime; + defaultRuntime.initialized_ = true; + defaultRuntime.loader_.RaCustomChannel = FakeRaCustomChannel; + defaultRuntime.loader_.loaded_ = true; + defaultRuntime.options_.rank = 0; + defaultRuntime.cachedBasicInfoValid_ = true; + defaultRuntime.cachedBasicInfo_ = runtime.cachedBasicInfo_; + if (defaultRuntime.RegisterCcuResourceRmaBuffer(0x10000000ULL) != TILEXR_SUCCESS || + defaultRuntime.ExportLocalCcuRmaBuffer(&local) != TILEXR_SUCCESS) { + std::cerr << "default register/export failed\n"; + return 4; + } + if (local.tokenId != 0x1111U || + local.rawTokenId != 0x1111U || + local.tokenValue != 0x7777U) { + std::cerr << "common override fallback was not applied\n"; + return 5; + } + return 0; + } + ''' + ) + env = os.environ.copy() + env["TILEXR_CCU_DIRECT_RESOURCE_WINDOW_TOKEN_ID"] = "0x1111" + env["TILEXR_CCU_DIRECT_RESOURCE_WINDOW_TOKEN_VALUE"] = "0x7777" + env["TILEXR_CCU_DIRECT_RESOURCE_WINDOW_TOKEN_ID_RANK1"] = "0x2222" + env["TILEXR_CCU_DIRECT_RESOURCE_WINDOW_RAW_TOKEN_ID_RANK1"] = "0x3333" + env["TILEXR_CCU_DIRECT_RESOURCE_WINDOW_TOKEN_VALUE_RANK1"] = "0x4444" + + result = self.compile_and_run( + code, + env=env, + extra_sources=[ + DIRECT_RUNTIME_SOURCE, + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_hccp_loader.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_ra_custom_channel_provider.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp", + ], + extra_link_flags=["-ldl"]) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_direct_ccu_runtime_can_register_resource_window_with_public_ra_ctx(self): + code = textwrap.dedent( + r''' + #include + #include + #include + + #define private public + #include "ccu/tilexr_ccu_direct_runtime.h" + #undef private + + using namespace TileXR; + constexpr uint64_t kResourceAddr = 0x10001234ULL; + constexpr uint64_t kAlignedResourceAddr = 0x10001000ULL; + constexpr uint64_t kAlignedResourceBytes = + TILEXR_CCU_RESOURCE_WINDOW_BYTES + (kResourceAddr - kAlignedResourceAddr); + + int FakeRaCustomChannel(TileXRCcuRaInfo, TileXRCcuCustomChannelIn*, TileXRCcuCustomChannelOut*) + { + return 0; + } + + int FakeRaGetDevEidInfoNum(TileXRCcuRaInfo, uint32_t* num) + { + *num = 1; + return 0; + } + + int FakeRaGetDevEidInfoList(TileXRCcuRaInfo, TileXRCcuHccpDevEidInfo* list, uint32_t* num) + { + if (list == nullptr || num == nullptr || *num != 1) { + return -1; + } + list[0].eidIndex = 3; + for (uint32_t i = 0; i < TILEXR_CCU_EID_BYTES; ++i) { + list[0].eid.raw[i] = static_cast(0xa0 + i); + } + return 0; + } + + int FakeRaCtxInit(TileXRCcuHccpCtxInitCfg*, TileXRCcuHccpCtxInitAttr* attr, void** ctx) + { + if (attr == nullptr || attr->phyId != 0x55 || attr->ub.eidIndex != 3) { + return -1; + } + *ctx = reinterpret_cast(0x1000); + return 0; + } + + int FakeRaCtxDeinit(void*) + { + return 0; + } + + int FakeRaCtxTokenIdAlloc(void* ctx, TileXRCcuHccpTokenId* token, void** tokenHandle) + { + if (ctx != reinterpret_cast(0x1000)) { + return -1; + } + token->tokenId = 0x12345600U; + *tokenHandle = reinterpret_cast(0x2000); + return 0; + } + + int FakeRaCtxTokenIdFree(void*, void*) + { + return 0; + } + + int FakeRaGetSecRandom(TileXRCcuRaInfo* info, uint32_t* value) + { + if (info == nullptr || info->phyId != 0x55 || info->mode != TILEXR_CCU_NETWORK_OFFLINE) { + return -1; + } + *value = 0xabcdef01U; + return 0; + } + + int FakeRaCtxLmemRegister(void* ctx, TileXRCcuHccpMrRegInfo* mr, void** handle) + { + if (ctx != reinterpret_cast(0x1000) || mr == nullptr || + mr->in.mem.addr != kAlignedResourceAddr || mr->in.mem.size != kAlignedResourceBytes || + mr->in.ub.tokenValue != 0xabcdef01U || + mr->in.ub.tokenIdHandle != reinterpret_cast(0x2000) || + mr->in.ub.flags.bs.tokenIdValid != 1 || + mr->in.ub.flags.bs.nonPin != 1) { + return -1; + } + mr->out.ub.tokenId = 0x12345600U; + mr->out.ub.targetSegHandle = 0x4455667788ULL; + mr->out.key.size = 5; + *handle = reinterpret_cast(0x3000); + return 0; + } + + int FakeRaCtxLmemUnregister(void*, void*) + { + return 0; + } + + int main() + { + TileXRCcuDirectRuntime runtime; + runtime.initialized_ = true; + runtime.loader_.RaCustomChannel = FakeRaCustomChannel; + runtime.loader_.loaded_ = true; + runtime.loader_.RaGetDevEidInfoNum = FakeRaGetDevEidInfoNum; + runtime.loader_.RaGetDevEidInfoList = FakeRaGetDevEidInfoList; + runtime.loader_.RaCtxInit = FakeRaCtxInit; + runtime.loader_.RaCtxDeinit = FakeRaCtxDeinit; + runtime.loader_.RaCtxTokenIdAlloc = FakeRaCtxTokenIdAlloc; + runtime.loader_.RaCtxTokenIdFree = FakeRaCtxTokenIdFree; + runtime.loader_.RaGetSecRandom = FakeRaGetSecRandom; + runtime.loader_.RaCtxLmemRegister = FakeRaCtxLmemRegister; + runtime.loader_.RaCtxLmemUnregister = FakeRaCtxLmemUnregister; + runtime.devicePhyId_ = 0x55; + runtime.options_.rank = 0; + runtime.cachedBasicInfoValid_ = true; + runtime.cachedBasicInfo_.resourceAddr = kResourceAddr; + runtime.cachedBasicInfo_.msidToken.tokenId = 0x1111; + runtime.cachedBasicInfo_.msidToken.tokenValue = 0x2222; + runtime.cachedBasicInfo_.msidToken.valid = true; + runtime.cachedBasicInfo_.caps.cap1 = 7U << 16U; + + if (runtime.RegisterCcuResourceRmaBuffer(kResourceAddr) != TILEXR_SUCCESS) { + std::cerr << "ra ctx resource window register failed\n"; + return 1; + } + + TileXRCcuLocalResourceWindowInfo local; + if (runtime.ExportLocalCcuRmaBuffer(&local) != TILEXR_SUCCESS) { + std::cerr << "export failed\n"; + return 2; + } + if (local.tokenId != 0x123456U || + local.rawTokenId != 0x12345600U || + local.tokenValue != 0xabcdef01U || + local.addr != kResourceAddr || + local.bytes != TILEXR_CCU_RESOURCE_WINDOW_BYTES) { + std::cerr << "unexpected registered resource window tokenId=" << local.tokenId + << " rawTokenId=" << local.rawTokenId + << " tokenValue=" << local.tokenValue + << " bytes=" << local.bytes << "\n"; + return 3; + } + + runtime.Shutdown(); + return 0; + } + ''' + ) + env = os.environ.copy() + env["TILEXR_CCU_DIRECT_RESOURCE_WINDOW_REGISTRATION_MODE"] = "ra_ctx" + + result = self.compile_and_run( + code, + env=env, + extra_sources=[ + DIRECT_RUNTIME_SOURCE, + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_hccp_loader.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_ra_custom_channel_provider.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp", + ], + extra_link_flags=["-ldl"]) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_direct_ccu_runtime_collects_ra_ctx_endpoint_route_when_resource_window_uses_ra_ctx(self): + code = textwrap.dedent( + r''' + #include + #include + #include + #include + #include + + #define private public + #include "ccu/tilexr_ccu_direct_runtime.h" + #undef private + + using namespace TileXR; + constexpr uint32_t kExpectedSqDepth = 8; + + int EchoLocalExchangeAsPeer(const void* sendBuf, size_t sendBytes, void* recvBuf, void*) + { + if (sendBuf == nullptr || recvBuf == nullptr || + sendBytes != sizeof(TileXRCcuResourceWindowExchange)) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + const auto* local = static_cast(sendBuf); + if (!local->endpointRouteVerified || + local->remoteEid[0] != 0xb0 || + local->tpn != 0x010203 || + local->doorbellVa != 0x1122334455667788ULL || + local->doorbellTokenId != 0x3456 || + local->sqDepth != kExpectedSqDepth) { + return TILEXR_ERROR_NOT_FOUND; + } + auto* out = static_cast(recvBuf); + std::memset(out, 0, sizeof(TileXRCcuResourceWindowExchange) * 2); + out[1] = *local; + return TILEXR_SUCCESS; + } + + int FakeRaCtxCqCreate(void* ctx, TileXRCcuHccpCqInfo*, void** cqHandle) + { + if (ctx != reinterpret_cast(0x1000)) { + return -1; + } + *cqHandle = reinterpret_cast(0x2000); + return 0; + } + + int FakeRaCtxCqDestroy(void*, void*) + { + return 0; + } + + int FakeRaCtxQpCreate( + void* ctx, + TileXRCcuHccpQpCreateAttr* attr, + TileXRCcuHccpQpCreateInfo* info, + void** qpHandle) + { + if (ctx != reinterpret_cast(0x1000) || + attr == nullptr || + attr->ub.tokenIdHandle != reinterpret_cast(0x1100) || + attr->ub.tokenValue != 0xabcdef01U || + info == nullptr) { + return -1; + } + info->key.size = 4; + info->ub.dbAddr = 0x1122334455667788ULL; + info->ub.dbTokenId = 0x345600U; + *qpHandle = reinterpret_cast(0x3000); + return 0; + } + + int FakeRaCtxQpDestroy(void*) + { + return 0; + } + + int FakeRaGetTpInfoListAsync( + void* ctx, + TileXRCcuHccpGetTpCfg*, + TileXRCcuHccpTpInfo infoList[], + uint32_t* num, + void** reqHandle) + { + if (ctx != reinterpret_cast(0x1000) || + infoList == nullptr || + num == nullptr || + *num == 0) { + return -1; + } + infoList[0].tpHandle = 0x99887766ULL; + *num = 1; + *reqHandle = reinterpret_cast(0x4000); + return 0; + } + + int FakeRaGetAsyncReqResult(void* reqHandle, int* reqResult) + { + if (reqHandle != reinterpret_cast(0x4000) || reqResult == nullptr) { + return -1; + } + *reqResult = 0; + return 0; + } + + int FakeRaCtxQpImport(void* ctx, TileXRCcuHccpQpImportInfo* info, void** remoteQpHandle) + { + if (ctx != reinterpret_cast(0x1000) || + info == nullptr || + info->in.ub.expImportCfg.tpHandle != 0x99887766ULL) { + return -1; + } + info->out.ub.tpn = 0x010203; + *remoteQpHandle = reinterpret_cast(0x5000); + return 0; + } + + int FakeRaCtxQpUnimport(void*, void*) + { + return 0; + } + + int main() + { + unsetenv("TILEXR_CCU_DIRECT_ENDPOINT_ROUTE_COLLECTION_MODE"); + unsetenv("TILEXR_CCU_ENDPOINT_ROUTE_PROVIDER"); + unsetenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_EID"); + unsetenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_TPN"); + unsetenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_DOORBELL_VA"); + unsetenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_DOORBELL_TOKEN_ID"); + unsetenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_DOORBELL_TOKEN_VALUE"); + unsetenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_SQ_DEPTH"); + + TileXRCcuDirectRuntime runtime; + runtime.initialized_ = true; + runtime.resourceWindowRegistered_ = true; + runtime.options_.rank = 0; + runtime.options_.rankSize = 2; + runtime.options_.allGather = EchoLocalExchangeAsPeer; + runtime.localResourceWindow_.addr = 0x10000000ULL; + runtime.localResourceWindow_.bytes = TILEXR_CCU_RESOURCE_WINDOW_BYTES; + runtime.localResourceWindow_.tokenId = 0x123456U; + runtime.localResourceWindow_.rawTokenId = 0x12345600U; + runtime.localResourceWindow_.tokenValue = 0xabcdef01U; + runtime.localResourceWindow_.raCtxHandle = reinterpret_cast(0x1000); + runtime.localResourceWindow_.tokenIdHandle = reinterpret_cast(0x1100); + runtime.localResourceWindow_.raCtxRegistered = true; + for (uint32_t i = 0; i < runtime.localResourceWindow_.eid.size(); ++i) { + runtime.localResourceWindow_.eid[i] = static_cast(0xb0 + i); + } + runtime.loader_.RaCtxCqCreate = FakeRaCtxCqCreate; + runtime.loader_.RaCtxCqDestroy = FakeRaCtxCqDestroy; + runtime.loader_.RaCtxQpCreate = FakeRaCtxQpCreate; + runtime.loader_.RaCtxQpDestroy = FakeRaCtxQpDestroy; + runtime.loader_.RaCtxQpImport = FakeRaCtxQpImport; + runtime.loader_.RaCtxQpUnimport = FakeRaCtxQpUnimport; + runtime.loader_.RaGetTpInfoListAsync = FakeRaGetTpInfoListAsync; + runtime.loader_.RaGetAsyncReqResult = FakeRaGetAsyncReqResult; + + TileXRCcuDirectRuntimeReport report; + if (runtime.RefreshLocalVerifiedEndpointRoute(&report) != TILEXR_SUCCESS) { + std::cerr << "ra ctx endpoint route was not collected by default: " + << report.message << "\n"; + return 1; + } + + std::vector buffers; + if (runtime.ExportRemoteCcuRmaBuffers(&buffers) != TILEXR_SUCCESS) { + std::cerr << "remote export failed after ra ctx route collection\n"; + return 2; + } + if (buffers.size() != 1 || + !buffers[0].endpointRouteVerified || + buffers[0].remoteEid[0] != 0xbf || + buffers[0].remoteEid[15] != 0xb0 || + buffers[0].tpn != 0x010203 || + buffers[0].doorbellVa != 0x1122334455667788ULL || + buffers[0].doorbellTokenId != 0x3456 || + buffers[0].doorbellTokenValue != 0xabcdef01U || + buffers[0].sqDepth != kExpectedSqDepth) { + std::cerr << "ra ctx collected endpoint route was not exported\n"; + return 3; + } + return 0; + } + ''' + ) + env = os.environ.copy() + env["TILEXR_CCU_DIRECT_RESOURCE_WINDOW_REGISTRATION_MODE"] = "ra_ctx" + + result = self.compile_and_run( + code, + env=env, + extra_sources=[ + DIRECT_RUNTIME_SOURCE, + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_hccp_loader.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_ra_custom_channel_provider.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp", + ], + extra_link_flags=["-ldl"]) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_direct_ccu_runtime_rejects_zero_resource_window_token_override(self): + code = textwrap.dedent( + r''' + #include + #include + + #define private public + #include "ccu/tilexr_ccu_direct_runtime.h" + #undef private + + using namespace TileXR; + + int FakeRaCustomChannel(TileXRCcuRaInfo, TileXRCcuCustomChannelIn*, TileXRCcuCustomChannelOut*) + { + return 0; + } + + int main() + { + TileXRCcuDirectRuntime runtime; + runtime.initialized_ = true; + runtime.loader_.RaCustomChannel = FakeRaCustomChannel; + runtime.loader_.loaded_ = true; + runtime.options_.rank = 0; + runtime.cachedBasicInfoValid_ = true; + runtime.cachedBasicInfo_.resourceAddr = 0x10000000ULL; + runtime.cachedBasicInfo_.msidToken.tokenId = 0x1234; + runtime.cachedBasicInfo_.msidToken.valid = true; + + if (runtime.RegisterCcuResourceRmaBuffer(0x10000000ULL) != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "zero token override was accepted\n"; + return 1; + } + TileXRCcuLocalResourceWindowInfo local; + if (runtime.ExportLocalCcuRmaBuffer(&local) != TILEXR_ERROR_NOT_INITIALIZED) { + std::cerr << "resource window remained registered after invalid override\n"; + return 2; + } + return 0; + } + ''' + ) + env = os.environ.copy() + env["TILEXR_CCU_DIRECT_RESOURCE_WINDOW_TOKEN_ID"] = "0" + + result = self.compile_and_run( + code, + env=env, + extra_sources=[ + DIRECT_RUNTIME_SOURCE, + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_hccp_loader.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_ra_custom_channel_provider.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp", + ], + extra_link_flags=["-ldl"]) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_direct_ccu_runtime_preserves_verified_endpoint_routes_from_template(self): + code = textwrap.dedent( + r''' + #include + #include + + #define private public + #include "ccu/tilexr_ccu_direct_runtime.h" + #undef private + + using namespace TileXR; + + int main() + { + TileXRCcuDirectRuntime runtime; + runtime.initialized_ = true; + runtime.resourceWindowRegistered_ = true; + runtime.devicePhyId_ = 0x1234; + runtime.options_.rank = 0; + runtime.options_.rankSize = 2; + runtime.localResourceWindow_.addr = 0x100000000ULL; + runtime.localResourceWindow_.tokenId = 0x1234; + runtime.localResourceWindow_.tokenValue = 0x5678; + + TileXRCcuLowerLayerTransportSnapshot templ; + templ.dieId = 1; + templ.xnStartId = 1961; + TileXRCcuLowerLayerTransportRoute route; + route.peerRank = 1; + route.channelId = 9; + for (uint32_t i = 0; i < route.remoteEid.size(); ++i) { + route.remoteEid[i] = static_cast(0xa0 + i); + } + route.tpn = 0; + route.doorbellVa = 0x1122334455667788ULL; + route.doorbellTokenId = 0x2345; + route.doorbellTokenValue = 0; + route.sqDepth = 64; + route.endpointRouteVerified = true; + templ.routes.push_back(route); + + TileXRCcuLowerLayerTransportRoute synthetic = route; + synthetic.peerRank = 2; + synthetic.channelId = 10; + synthetic.remoteEid = {}; + synthetic.tpn = 0; + synthetic.doorbellVa = 0; + synthetic.doorbellTokenId = 0; + synthetic.doorbellTokenValue = 0; + synthetic.sqDepth = 0; + synthetic.endpointRouteVerified = true; + templ.routes.push_back(synthetic); + + TileXRCcuLowerLayerTransportSnapshot snapshot; + if (runtime.ExportLowerLayerTransportSnapshot(templ, &snapshot) != TILEXR_SUCCESS) { + std::cerr << "export snapshot failed\n"; + return 4; + } + if (snapshot.routes.size() != 2 || !snapshot.routes[0].endpointRouteVerified || + snapshot.routes[0].remoteEid[0] != 0xa0 || + snapshot.routes[0].tpn != route.tpn || + snapshot.routes[0].doorbellVa != route.doorbellVa || + snapshot.routes[0].doorbellTokenId != route.doorbellTokenId || + snapshot.routes[0].doorbellTokenValue != route.doorbellTokenValue || + snapshot.routes[0].sqDepth != route.sqDepth) { + std::cerr << "verified endpoint route was not preserved\n"; + return 5; + } + if (snapshot.routes[1].endpointRouteVerified || + snapshot.routes[1].remoteEid[0] == 0 || + snapshot.routes[1].tpn == 0 || + snapshot.routes[1].doorbellVa == 0 || + snapshot.routes[1].doorbellTokenId != runtime.localResourceWindow_.tokenId || + snapshot.routes[1].doorbellTokenValue != runtime.localResourceWindow_.tokenValue || + snapshot.routes[1].sqDepth == 0) { + std::cerr << "synthetic endpoint route did not fail closed\n"; + return 6; + } + return 0; + } + ''' + ) + + result = self.compile_and_run( + code, + extra_sources=[ + DIRECT_RUNTIME_SOURCE, + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_hccp_loader.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_ra_custom_channel_provider.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp", + ], + extra_link_flags=["-ldl"]) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_direct_ccu_runtime_can_trust_synthetic_endpoint_routes_only_with_diagnostic_env(self): + code = textwrap.dedent( + r''' + #include + #include + + #define private public + #include "ccu/tilexr_ccu_direct_runtime.h" + #undef private + + using namespace TileXR; + + int main() + { + setenv("TILEXR_CCU_DIRECT_TRUST_SYNTHETIC_ENDPOINT_ROUTE", "1", 1); + + TileXRCcuDirectRuntime runtime; + runtime.initialized_ = true; + runtime.resourceWindowRegistered_ = true; + runtime.devicePhyId_ = 0x1234; + runtime.options_.rank = 0; + runtime.options_.rankSize = 2; + runtime.localResourceWindow_.addr = 0x100000000ULL; + runtime.localResourceWindow_.tokenId = 0x1234; + runtime.localResourceWindow_.tokenValue = 0x5678; + + TileXRCcuLowerLayerTransportSnapshot templ; + templ.dieId = 1; + templ.xnStartId = 1961; + TileXRCcuLowerLayerTransportRoute route; + route.peerRank = 1; + route.channelId = 9; + route.endpointRouteVerified = true; + templ.routes.push_back(route); + + TileXRCcuLowerLayerTransportSnapshot snapshot; + if (runtime.ExportLowerLayerTransportSnapshot(templ, &snapshot) != TILEXR_SUCCESS) { + std::cerr << "export snapshot failed\n"; + return 1; + } + if (snapshot.routes.size() != 1 || + !snapshot.routes[0].endpointRouteVerified || + snapshot.routes[0].remoteEid[0] == 0 || + snapshot.routes[0].tpn == 0 || + snapshot.routes[0].doorbellVa == 0 || + snapshot.routes[0].doorbellTokenId != runtime.localResourceWindow_.tokenId || + snapshot.routes[0].doorbellTokenValue != runtime.localResourceWindow_.tokenValue || + snapshot.routes[0].sqDepth == 0) { + std::cerr << "synthetic endpoint route was not trusted under diagnostic env\n"; + return 2; + } + return 0; + } + ''' + ) + + result = self.compile_and_run( + code, + extra_sources=[ + DIRECT_RUNTIME_SOURCE, + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_hccp_loader.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_ra_custom_channel_provider.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp", + ], + extra_link_flags=["-ldl"]) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_direct_ccu_runtime_exchanges_verified_endpoint_route_with_resource_window(self): + code = textwrap.dedent( + r''' + #include + #include + #include + + #define private public + #include "ccu/tilexr_ccu_direct_runtime.h" + #undef private + + using namespace TileXR; + + int FakeAllGather(const void* sendBuf, size_t sendBytes, void* recvBuf, void* userData) + { + (void)sendBuf; + if (sendBytes != sizeof(TileXRCcuResourceWindowExchange) || userData == nullptr) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + auto* peer = static_cast(userData); + auto* out = static_cast(recvBuf); + std::memset(out, 0, sizeof(TileXRCcuResourceWindowExchange) * 2); + out[1] = *peer; + return TILEXR_SUCCESS; + } + + int main() + { + TileXRCcuResourceWindowExchange peer {}; + peer.addr = 0x0000009234000000ULL; + peer.bytes = 0x2000; + peer.tokenId = 0x23456; + peer.rawTokenId = 0x33456; + peer.tokenValue = 0x5678; + for (uint32_t i = 0; i < peer.remoteEid.size(); ++i) { + peer.remoteEid[i] = static_cast(0x90 + i); + } + peer.tpn = 0x010203; + peer.doorbellVa = 0x1122334455667788ULL; + peer.doorbellTokenId = 0x3456; + peer.doorbellTokenValue = 0; + peer.sqDepth = 64; + peer.endpointRouteVerified = true; + peer.channelResourceOwnerVerified = true; + peer.transportResourceExchangeVerified = true; + + TileXRCcuDirectRuntime runtime; + runtime.initialized_ = true; + runtime.resourceWindowRegistered_ = true; + runtime.options_.rank = 0; + runtime.options_.rankSize = 2; + runtime.options_.allGather = FakeAllGather; + runtime.options_.allGatherUserData = &peer; + runtime.localResourceWindow_.addr = 0x10000000ULL; + runtime.localResourceWindow_.bytes = 0x2000; + runtime.localResourceWindow_.tokenId = 0x1234; + runtime.localResourceWindow_.rawTokenId = 0x2234; + runtime.localResourceWindow_.tokenValue = 0x4567; + + std::vector buffers; + if (runtime.ExportRemoteCcuRmaBuffers(&buffers) != TILEXR_SUCCESS) { + std::cerr << "remote export failed\n"; + return 1; + } + if (buffers.size() != 1 || + buffers[0].remoteCcuVa != peer.addr || + buffers[0].memoryTokenId != peer.tokenId || + buffers[0].rawMemoryTokenId != peer.rawTokenId || + buffers[0].memoryTokenValue != peer.tokenValue || + !buffers[0].endpointRouteVerified || + buffers[0].remoteEid[0] != 0x9f || + buffers[0].remoteEid[15] != 0x90 || + buffers[0].tpn != peer.tpn || + buffers[0].doorbellVa != peer.doorbellVa || + buffers[0].doorbellTokenId != peer.doorbellTokenId || + buffers[0].doorbellTokenValue != peer.doorbellTokenValue || + buffers[0].sqDepth != peer.sqDepth || + !buffers[0].channelResourceOwnerVerified || + !buffers[0].transportResourceExchangeVerified) { + std::cerr << "verified endpoint route was not exchanged with resource window\n"; + return 2; + } + return 0; + } + ''' + ) + + result = self.compile_and_run( + code, + extra_sources=[ + DIRECT_RUNTIME_SOURCE, + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_hccp_loader.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_ra_custom_channel_provider.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp", + ], + extra_link_flags=["-ldl"]) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_direct_ccu_runtime_imported_peer_route_uses_hcomm_reverse_channel_eid(self): + code = textwrap.dedent( + r''' + #include + #include + #include + #include + + #define private public + #include "ccu/tilexr_ccu_direct_runtime.h" + #undef private + + using namespace TileXR; + + struct TpExchange { + uint64_t tpHandles[128] = {}; + uint32_t psn = 0; + }; + + struct ExchangeState { + TileXRCcuResourceWindowExchange peer; + }; + + int FakeAllGather(const void* sendBuf, size_t sendBytes, void* recvBuf, void* userData) + { + if (sendBuf == nullptr || recvBuf == nullptr || userData == nullptr) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + auto* state = static_cast(userData); + if (sendBytes == sizeof(TileXRCcuResourceWindowExchange)) { + const auto* local = static_cast(sendBuf); + if (!local->endpointRouteVerified || local->qpKey.size == 0) { + return TILEXR_ERROR_NOT_FOUND; + } + auto* out = static_cast(recvBuf); + std::memset(out, 0, sizeof(TileXRCcuResourceWindowExchange) * 2); + out[1] = state->peer; + return TILEXR_SUCCESS; + } + if (sendBytes == sizeof(TpExchange)) { + const auto* local = static_cast(sendBuf); + if (local->tpHandles[1] != 0x1111222233334444ULL || local->psn != 5) { + return TILEXR_ERROR_NOT_FOUND; + } + auto* out = static_cast(recvBuf); + std::memset(out, 0, sizeof(TpExchange) * 2); + out[1].tpHandles[0] = 0x5555666677778888ULL; + out[1].psn = 9; + return TILEXR_SUCCESS; + } + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + + int FakeGetTpInfoListAsync( + void* ctx, + TileXRCcuHccpGetTpCfg* cfg, + TileXRCcuHccpTpInfo* tpInfo, + uint32_t* tpInfoNum, + void** reqHandle) + { + if (ctx != reinterpret_cast(0x1000) || cfg == nullptr || + tpInfo == nullptr || tpInfoNum == nullptr || reqHandle == nullptr || + cfg->peerEid.raw[0] != 0xa0 || cfg->peerEid.raw[15] != 0xaf) { + return -1; + } + tpInfo->tpHandle = 0x1111222233334444ULL; + *tpInfoNum = 1; + *reqHandle = reinterpret_cast(0x2000); + return 0; + } + + int FakeGetAsyncReqResult(void* reqHandle, int* reqResult) + { + if (reqHandle != reinterpret_cast(0x2000) || reqResult == nullptr) { + return -1; + } + *reqResult = 0; + return 0; + } + + int FakeQpImport(void* ctx, TileXRCcuHccpQpImportInfo* info, void** remoteQpHandle) + { + if (ctx != reinterpret_cast(0x1000) || info == nullptr || remoteQpHandle == nullptr || + info->in.ub.expImportCfg.tpHandle != 0x1111222233334444ULL || + info->in.ub.expImportCfg.peerTpHandle != 0x5555666677778888ULL || + info->in.ub.expImportCfg.txPsn != 5 || + info->in.ub.expImportCfg.rxPsn != 9 || + info->in.key.size == 0) { + return -1; + } + info->out.ub.tpn = 0x47; + *remoteQpHandle = reinterpret_cast(0x3000); + return 0; + } + + int main() + { + ExchangeState state; + state.peer.addr = 0x0000009234000000ULL; + state.peer.bytes = 0x2000; + state.peer.tokenId = 0x23456; + state.peer.rawTokenId = 0x33456; + state.peer.tokenValue = 0x5678; + for (uint32_t i = 0; i < state.peer.remoteEid.size(); ++i) { + state.peer.remoteEid[i] = static_cast(0xa0 + i); + state.peer.qpKey.value[i] = static_cast(0x40 + i); + } + state.peer.qpKey.size = TILEXR_CCU_HCCP_QP_KEY_BYTES; + state.peer.endpointRouteVerified = true; + + TileXRCcuDirectRuntime runtime; + runtime.initialized_ = true; + runtime.resourceWindowRegistered_ = true; + runtime.options_.rank = 0; + runtime.options_.rankSize = 2; + runtime.options_.allGather = FakeAllGather; + runtime.options_.allGatherUserData = &state; + runtime.localResourceWindow_.raCtxHandle = reinterpret_cast(0x1000); + runtime.localResourceWindow_.addr = 0x10000000ULL; + runtime.localResourceWindow_.bytes = 0x2000; + runtime.localResourceWindow_.tokenId = 0x1234; + runtime.localResourceWindow_.rawTokenId = 0x2234; + runtime.localResourceWindow_.tokenValue = 0x4567; + runtime.localResourceWindow_.eid[0] = 0x10; + runtime.localResourceWindow_.eid[15] = 0x1f; + runtime.loader_.RaGetTpInfoListAsync = FakeGetTpInfoListAsync; + runtime.loader_.RaGetAsyncReqResult = FakeGetAsyncReqResult; + runtime.loader_.RaCtxQpImport = FakeQpImport; + runtime.endpointPsn_ = 5; + runtime.endpointQpKeyValid_ = true; + runtime.endpointQpKey_.size = TILEXR_CCU_HCCP_QP_KEY_BYTES; + runtime.localVerifiedEndpointRouteValid_ = true; + runtime.localVerifiedEndpointRoute_.endpointRouteVerified = true; + runtime.localVerifiedEndpointRoute_.remoteEid[0] = 0x10; + runtime.localVerifiedEndpointRoute_.tpn = 0x22; + runtime.localVerifiedEndpointRoute_.doorbellVa = 0x1122334455667788ULL; + runtime.localVerifiedEndpointRoute_.doorbellTokenId = 0x3456; + runtime.localVerifiedEndpointRoute_.doorbellTokenValue = 0x4567; + runtime.localVerifiedEndpointRoute_.sqDepth = 8; + + std::vector buffers; + if (runtime.ExportRemoteCcuRmaBuffers(&buffers) != TILEXR_SUCCESS) { + std::cerr << "remote export failed\n"; + return 1; + } + if (buffers.size() != 1 || buffers[0].tpn != 0x47 || + buffers[0].remoteEid[0] != 0xaf || buffers[0].remoteEid[15] != 0xa0 || + buffers[0].doorbellVa != runtime.localVerifiedEndpointRoute_.doorbellVa || + buffers[0].doorbellTokenId != runtime.localVerifiedEndpointRoute_.doorbellTokenId || + !buffers[0].endpointRouteVerified) { + std::cerr << "imported peer route did not use hcomm-style reverse EID and imported TPN" + << " size=" << buffers.size(); + if (!buffers.empty()) { + std::cerr << " tpn=0x" << std::hex << buffers[0].tpn + << " eid0=0x" << static_cast(buffers[0].remoteEid[0]) + << " eid15=0x" << static_cast(buffers[0].remoteEid[15]) + << " doorbellVa=0x" << buffers[0].doorbellVa + << " doorbellTokenId=0x" << buffers[0].doorbellTokenId + << std::dec + << " endpointRouteVerified=" << buffers[0].endpointRouteVerified; + } + std::cerr << "\n"; + return 2; + } + return 0; + } + ''' + ) + + result = self.compile_and_run( + code, + extra_sources=[ + DIRECT_RUNTIME_SOURCE, + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_hccp_loader.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_ra_custom_channel_provider.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp", + ], + extra_link_flags=["-ldl"]) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_direct_ccu_runtime_exports_global_peer_rank_with_remote_buffer(self): + code = textwrap.dedent( + r''' + #include + #include + #include + #include + + #define private public + #include "ccu/tilexr_ccu_direct_runtime.h" + #undef private + + using namespace TileXR; + + int FakeAllGather(const void* sendBuf, size_t sendBytes, void* recvBuf, void*) + { + if (sendBuf == nullptr || recvBuf == nullptr || + sendBytes != sizeof(TileXRCcuResourceWindowExchange)) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + const auto* local = static_cast(sendBuf); + auto* out = static_cast(recvBuf); + std::memset(out, 0, sizeof(TileXRCcuResourceWindowExchange) * 2); + out[1] = *local; + out[1].addr = 0x20000000ULL; + out[1].bytes = 0x2000; + out[1].tokenId = 0x2222; + return TILEXR_SUCCESS; + } + + int main() + { + TileXRCcuDirectRuntime runtime; + runtime.initialized_ = true; + runtime.resourceWindowRegistered_ = true; + runtime.options_.rank = 0; + runtime.options_.rankSize = 2; + runtime.options_.allGather = FakeAllGather; + runtime.localResourceWindow_.addr = 0x10000000ULL; + runtime.localResourceWindow_.bytes = 0x2000; + runtime.localResourceWindow_.tokenId = 0x1234; + + std::vector buffers; + if (runtime.ExportRemoteCcuRmaBuffers(&buffers) != TILEXR_SUCCESS) { + std::cerr << "remote export failed\n"; + return 1; + } + if (buffers.size() != 1 || buffers[0].peerRank != 1) { + std::cerr << "global peer rank was not exported with remote buffer\n"; + return 2; + } + return 0; + } + ''' + ) + + result = self.compile_and_run( + code, + extra_sources=[ + DIRECT_RUNTIME_SOURCE, + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_hccp_loader.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_ra_custom_channel_provider.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp", + ], + extra_link_flags=["-ldl"]) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_direct_ccu_runtime_exports_configured_local_verified_endpoint_route(self): + code = textwrap.dedent( + r''' + #include + #include + #include + + #define private public + #include "ccu/tilexr_ccu_direct_runtime.h" + #undef private + + using namespace TileXR; + + int EchoLocalExchangeAsPeer(const void* sendBuf, size_t sendBytes, void* recvBuf, void* userData) + { + (void)userData; + if (sendBuf == nullptr || sendBytes != sizeof(TileXRCcuResourceWindowExchange)) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + const auto* local = static_cast(sendBuf); + if (!local->endpointRouteVerified || + local->remoteEid[0] != 0x70 || + local->tpn != 0x010203 || + local->doorbellVa != 0x1122334455667788ULL || + local->doorbellTokenId != 0x3456 || + local->sqDepth != 64) { + return TILEXR_ERROR_NOT_FOUND; + } + auto* out = static_cast(recvBuf); + std::memset(out, 0, sizeof(TileXRCcuResourceWindowExchange) * 2); + out[1] = *local; + return TILEXR_SUCCESS; + } + + int main() + { + TileXRCcuLowerLayerTransportRoute localRoute; + for (uint32_t i = 0; i < localRoute.remoteEid.size(); ++i) { + localRoute.remoteEid[i] = static_cast(0x70 + i); + } + localRoute.tpn = 0x010203; + localRoute.doorbellVa = 0x1122334455667788ULL; + localRoute.doorbellTokenId = 0x3456; + localRoute.doorbellTokenValue = 0; + localRoute.sqDepth = 64; + localRoute.endpointRouteVerified = true; + + TileXRCcuDirectRuntime runtime; + runtime.initialized_ = true; + runtime.resourceWindowRegistered_ = true; + runtime.options_.rank = 0; + runtime.options_.rankSize = 2; + runtime.options_.allGather = EchoLocalExchangeAsPeer; + runtime.localResourceWindow_.addr = 0x10000000ULL; + runtime.localResourceWindow_.bytes = 0x2000; + runtime.localResourceWindow_.tokenId = 0x1234; + runtime.localResourceWindow_.rawTokenId = 0x2234; + runtime.localResourceWindow_.tokenValue = 0x4567; + + if (runtime.ConfigureLocalVerifiedEndpointRoute(localRoute) != TILEXR_SUCCESS) { + std::cerr << "failed to configure local verified endpoint route\n"; + return 1; + } + + std::vector buffers; + if (runtime.ExportRemoteCcuRmaBuffers(&buffers) != TILEXR_SUCCESS) { + std::cerr << "remote export failed\n"; + return 2; + } + if (buffers.size() != 1 || + !buffers[0].endpointRouteVerified || + buffers[0].remoteEid[0] != 0x7f || + buffers[0].remoteEid[15] != 0x70 || + buffers[0].tpn != localRoute.tpn || + buffers[0].doorbellVa != localRoute.doorbellVa || + buffers[0].doorbellTokenId != localRoute.doorbellTokenId || + buffers[0].doorbellTokenValue != localRoute.doorbellTokenValue || + buffers[0].sqDepth != localRoute.sqDepth) { + std::cerr << "configured local verified endpoint route was not exported\n"; + return 3; + } + return 0; + } + ''' + ) + + result = self.compile_and_run( + code, + extra_sources=[ + DIRECT_RUNTIME_SOURCE, + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_hccp_loader.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_ra_custom_channel_provider.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp", + ], + extra_link_flags=["-ldl"]) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_direct_ccu_runtime_collects_local_verified_endpoint_route_before_exchange(self): + code = textwrap.dedent( + r''' + #include + #include + #include + + #define private public + #include "ccu/tilexr_ccu_direct_runtime.h" + #undef private + + using namespace TileXR; + + struct CollectorState { + int calls = 0; + uint32_t observedDevicePhyId = 0; + uint64_t observedResourceWindow = 0; + }; + + int FakeCollector( + uint32_t devicePhyId, + const TileXRCcuLocalResourceWindowInfo& localResourceWindow, + TileXRCcuLowerLayerTransportRoute* route, + void* userData) + { + auto* state = static_cast(userData); + state->calls++; + state->observedDevicePhyId = devicePhyId; + state->observedResourceWindow = localResourceWindow.addr; + for (uint32_t i = 0; i < route->remoteEid.size(); ++i) { + route->remoteEid[i] = static_cast(0x80 + i); + } + route->tpn = 0x010203; + route->doorbellVa = 0x1122334455667788ULL; + route->doorbellTokenId = 0x3456; + route->doorbellTokenValue = 0; + route->sqDepth = 64; + route->endpointRouteVerified = true; + return TILEXR_SUCCESS; + } + + int EchoLocalExchangeAsPeer(const void* sendBuf, size_t sendBytes, void* recvBuf, void*) + { + if (sendBuf == nullptr || sendBytes != sizeof(TileXRCcuResourceWindowExchange)) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + const auto* local = static_cast(sendBuf); + if (!local->endpointRouteVerified || local->remoteEid[0] != 0x80 || + local->tpn != 0x010203 || local->doorbellVa != 0x1122334455667788ULL || + local->doorbellTokenId != 0x3456 || local->sqDepth != 64) { + return TILEXR_ERROR_NOT_FOUND; + } + auto* out = static_cast(recvBuf); + std::memset(out, 0, sizeof(TileXRCcuResourceWindowExchange) * 2); + out[1] = *local; + return TILEXR_SUCCESS; + } + + int main() + { + CollectorState state; + TileXRCcuDirectRuntime runtime; + runtime.initialized_ = true; + runtime.resourceWindowRegistered_ = true; + runtime.devicePhyId_ = 0x1234; + runtime.options_.rank = 0; + runtime.options_.rankSize = 2; + runtime.options_.allGather = EchoLocalExchangeAsPeer; + runtime.options_.localEndpointRouteCollector = FakeCollector; + runtime.options_.localEndpointRouteCollectorUserData = &state; + runtime.localResourceWindow_.addr = 0x10000000ULL; + runtime.localResourceWindow_.bytes = 0x2000; + runtime.localResourceWindow_.tokenId = 0x1234; + runtime.localResourceWindow_.rawTokenId = 0x2234; + runtime.localResourceWindow_.tokenValue = 0x4567; + + TileXRCcuDirectRuntimeReport report; + if (runtime.RefreshLocalVerifiedEndpointRoute(&report) != TILEXR_SUCCESS) { + std::cerr << "failed to refresh local endpoint route: " << report.message << "\n"; + return 1; + } + if (state.calls != 1 || state.observedDevicePhyId != 0x1234 || + state.observedResourceWindow != runtime.localResourceWindow_.addr) { + std::cerr << "collector did not receive runtime context\n"; + return 2; + } + + std::vector buffers; + if (runtime.ExportRemoteCcuRmaBuffers(&buffers) != TILEXR_SUCCESS) { + std::cerr << "remote export failed after collector refresh\n"; + return 3; + } + if (buffers.size() != 1 || !buffers[0].endpointRouteVerified || + buffers[0].remoteEid[0] != 0x8f || + buffers[0].remoteEid[15] != 0x80 || + buffers[0].tpn != 0x010203 || + buffers[0].doorbellVa != 0x1122334455667788ULL || + buffers[0].doorbellTokenId != 0x3456 || + buffers[0].doorbellTokenValue != 0 || + buffers[0].sqDepth != 64) { + std::cerr << "collected local endpoint route was not exported\n"; + return 4; + } + return 0; + } + ''' + ) + + result = self.compile_and_run( + code, + extra_sources=[ + DIRECT_RUNTIME_SOURCE, + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_hccp_loader.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_ra_custom_channel_provider.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp", + ], + extra_link_flags=["-ldl"]) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_direct_ccu_runtime_endpoint_collector_failure_fails_closed(self): + code = textwrap.dedent( + r''' + #include + #include + + #define private public + #include "ccu/tilexr_ccu_direct_runtime.h" + #undef private + + using namespace TileXR; + + int IncompleteCollector( + uint32_t, + const TileXRCcuLocalResourceWindowInfo&, + TileXRCcuLowerLayerTransportRoute* route, + void*) + { + route->remoteEid[0] = 0x90; + route->tpn = 0; + route->doorbellVa = 0x1122334455667788ULL; + route->doorbellTokenId = 0; + route->sqDepth = 64; + route->endpointRouteVerified = true; + return TILEXR_SUCCESS; + } + + int main() + { + TileXRCcuDirectRuntime runtime; + runtime.initialized_ = true; + runtime.resourceWindowRegistered_ = true; + runtime.devicePhyId_ = 0x1234; + runtime.options_.rank = 0; + runtime.options_.rankSize = 2; + runtime.options_.localEndpointRouteCollector = IncompleteCollector; + runtime.localResourceWindow_.addr = 0x10000000ULL; + runtime.localResourceWindow_.bytes = 0x2000; + runtime.localResourceWindow_.tokenId = 0x1234; + runtime.localResourceWindow_.rawTokenId = 0x2234; + runtime.localResourceWindow_.tokenValue = 0x4567; + + TileXRCcuDirectRuntimeReport report; + if (runtime.RefreshLocalVerifiedEndpointRoute(&report) != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "incomplete collected route was accepted\n"; + return 1; + } + if (runtime.localVerifiedEndpointRouteValid_) { + std::cerr << "incomplete collected route remained verified\n"; + return 2; + } + + TileXRCcuLowerLayerTransportSnapshot templ; + templ.dieId = 1; + templ.xnStartId = 1961; + TileXRCcuLowerLayerTransportRoute route; + route.peerRank = 1; + route.channelId = 9; + templ.routes.push_back(route); + + TileXRCcuLowerLayerTransportSnapshot snapshot; + if (runtime.ExportLowerLayerTransportSnapshot(templ, &snapshot) != TILEXR_SUCCESS) { + std::cerr << "export snapshot failed\n"; + return 3; + } + if (snapshot.routes.size() != 1 || snapshot.routes[0].endpointRouteVerified || + snapshot.routes[0].remoteEid[0] == 0 || snapshot.routes[0].tpn == 0 || + snapshot.routes[0].doorbellVa == 0 || snapshot.routes[0].doorbellTokenId == 0 || + snapshot.routes[0].sqDepth == 0) { + std::cerr << "collector failure did not fail closed to synthetic unverified route\n"; + return 4; + } + return 0; + } + ''' + ) + + result = self.compile_and_run( + code, + extra_sources=[ + DIRECT_RUNTIME_SOURCE, + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_hccp_loader.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_ra_custom_channel_provider.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp", + ], + extra_link_flags=["-ldl"]) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_direct_ccu_runtime_collects_ranked_env_local_verified_endpoint_route(self): + code = textwrap.dedent( + r''' + #include + #include + #include + #include + + #define private public + #include "ccu/tilexr_ccu_direct_runtime.h" + #undef private + + using namespace TileXR; + + int EchoLocalExchangeAsPeer(const void* sendBuf, size_t sendBytes, void* recvBuf, void*) + { + if (sendBuf == nullptr || sendBytes != sizeof(TileXRCcuResourceWindowExchange)) { + return TILEXR_ERROR_PARA_CHECK_FAIL; + } + const auto* local = static_cast(sendBuf); + if (!local->endpointRouteVerified || local->remoteEid[0] != 0xa0 || + local->tpn != 0x010203 || local->doorbellVa != 0x1122334455667788ULL || + local->doorbellTokenId != 0x3456 || local->doorbellTokenValue != 0 || + local->sqDepth != 64) { + return TILEXR_ERROR_NOT_FOUND; + } + auto* out = static_cast(recvBuf); + std::memset(out, 0, sizeof(TileXRCcuResourceWindowExchange) * 2); + out[0] = *local; + return TILEXR_SUCCESS; + } + + int main() + { + setenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_EID", "00112233445566778899aabbccddeeff", 1); + setenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_TPN", "7", 1); + setenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_DOORBELL_VA", "0x1111111111111111", 1); + setenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_DOORBELL_TOKEN_ID", "0x1111", 1); + setenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_DOORBELL_TOKEN_VALUE", "0x22", 1); + setenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_SQ_DEPTH", "8", 1); + setenv( + "TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_EID_RANK1", + "a0:a1:a2:a3:a4:a5:a6:a7:a8:a9:aa:ab:ac:ad:ae:af", + 1); + setenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_TPN_RANK1", "0x010203", 1); + setenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_DOORBELL_VA_RANK1", "0x1122334455667788", 1); + setenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_DOORBELL_TOKEN_ID_RANK1", "0x3456", 1); + setenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_DOORBELL_TOKEN_VALUE_RANK1", "0", 1); + setenv("TILEXR_CCU_DIRECT_LOCAL_ENDPOINT_SQ_DEPTH_RANK1", "64", 1); + + TileXRCcuDirectRuntime runtime; + runtime.initialized_ = true; + runtime.resourceWindowRegistered_ = true; + runtime.devicePhyId_ = 0x1234; + runtime.options_.rank = 1; + runtime.options_.rankSize = 2; + runtime.options_.allGather = EchoLocalExchangeAsPeer; + runtime.localResourceWindow_.addr = 0x10000000ULL; + runtime.localResourceWindow_.bytes = 0x2000; + runtime.localResourceWindow_.tokenId = 0x1234; + runtime.localResourceWindow_.rawTokenId = 0x2234; + runtime.localResourceWindow_.tokenValue = 0x4567; + + TileXRCcuDirectRuntimeReport report; + if (runtime.RefreshLocalVerifiedEndpointRoute(&report) != TILEXR_SUCCESS) { + std::cerr << "ranked env route was not collected: " << report.message << "\n"; + return 1; + } + + std::vector buffers; + if (runtime.ExportRemoteCcuRmaBuffers(&buffers) != TILEXR_SUCCESS) { + std::cerr << "remote export failed after env route collection\n"; + return 2; + } + if (buffers.size() != 1 || !buffers[0].endpointRouteVerified || + buffers[0].remoteEid[0] != 0xaf || + buffers[0].remoteEid[15] != 0xa0 || + buffers[0].tpn != 0x010203 || + buffers[0].doorbellVa != 0x1122334455667788ULL || + buffers[0].doorbellTokenId != 0x3456 || + buffers[0].doorbellTokenValue != 0 || + buffers[0].sqDepth != 64) { + std::cerr << "ranked env route was not exported\n"; + return 3; + } + return 0; + } + ''' + ) + + result = self.compile_and_run( + code, + extra_sources=[ + DIRECT_RUNTIME_SOURCE, + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_hccp_loader.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_ra_custom_channel_provider.cpp", + REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp", + ], + extra_link_flags=["-ldl"]) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_tilexr_comm_caches_direct_ccu_basic_info_without_submit_readiness(self): + comm_header = COMM_HEADER_FILE.read_text(encoding="utf-8") + comm_source = COMM_SOURCE_FILE.read_text(encoding="utf-8") + backend_header = CCU_BACKEND_HEADER.read_text(encoding="utf-8") + backend_source = CCU_BACKEND_SOURCE.read_text(encoding="utf-8") + runtime_session_source = CCU_RUNTIME_SESSION_SOURCE.read_text(encoding="utf-8") + + for leaked in [ + "RefreshDirectCcuBasicInfo", + "HasDirectCcuBasicInfo", + "GetDirectCcuBasicInfoStatus", + "GetDirectCcuBasicInfo", + "GetDirectCcuBasicInfoReport", + "directCcuBasicInfo_", + "directCcuBasicInfoReport_", + ]: + with self.subTest(leaked=leaked): + self.assertNotIn(leaked, comm_header) + self.assertNotIn(leaked, backend_header) + + self.assertIn("int TileXRCcuRuntimeSession::RefreshDirectCcuBasicInfo", runtime_session_source) + self.assertIn("bool TileXRCcuRuntimeSession::HasDirectCcuBasicInfo", runtime_session_source) + self.assertIn("ccuDirectRuntime_->QueryBasicInfo", runtime_session_source) + self.assertIn("direct CCU basic info cached", runtime_session_source) + self.assertIn("ResetDirectCcuBasicInfo", runtime_session_source) + self.assertIn("ResetDirectCcuBasicInfo();", runtime_session_source) + self.assertNotIn("udmaTransport_->" + "QueryCcuBasicInfo", comm_source + "\n" + backend_source + "\n" + runtime_session_source) + + for forbidden in [ + "TileXRCcuPrepareSubmitTasks", + "TileXRCcuSubmitTask", + "rtCCULaunch", + "HcclGetCcuTaskInfo", + "HcomGetCcuTaskInfo", + "libhcomm", + "libhccl_v2", + ]: + self.assertNotIn(forbidden, comm_header + "\n" + comm_source + "\n" + backend_source) + + def test_tilexr_comm_prepares_direct_ccu_install_attempt_without_submitting(self): + comm_header = COMM_HEADER_FILE.read_text(encoding="utf-8") + comm_source = COMM_SOURCE_FILE.read_text(encoding="utf-8") + backend_header = CCU_BACKEND_HEADER.read_text(encoding="utf-8") + backend_source = CCU_BACKEND_SOURCE.read_text(encoding="utf-8") + planner_header = CCU_PLANNER_HEADER.read_text(encoding="utf-8") + planner_source = CCU_PLANNER_SOURCE.read_text(encoding="utf-8") + runtime_session_source = CCU_RUNTIME_SESSION_SOURCE.read_text(encoding="utf-8") + runtime_header = DIRECT_RUNTIME_HEADER.read_text(encoding="utf-8") + runtime_source = DIRECT_RUNTIME_SOURCE.read_text(encoding="utf-8") + + self.assertIn('ccu/tilexr_ccu_direct_orchestrator.h', planner_header + "\n" + planner_source) + self.assertIn('ccu/tilexr_ccu_direct_runtime.h', CCU_RUNTIME_SESSION_HEADER.read_text(encoding="utf-8")) + for leaked in [ + "PrepareDirectCcuInstallAttempt", + "FillDirectCcuLowerLayerPlanFromAllocation", + "PrepareDirectCcuLowerLayerPlanCallback", + ]: + with self.subTest(leaked=leaked): + self.assertNotIn(leaked, comm_header) + self.assertNotIn(leaked, backend_header) + self.assertIn("int CreateDriverAdapter(", runtime_header) + + self.assertIn("int TileXRCcuCollectivePlanner::PrepareDirectCcuInstallAttempt", planner_source) + self.assertIn("int TileXRCcuCollectivePlanner::FillDirectCcuLowerLayerPlanFromAllocation", planner_source) + self.assertIn("int TileXRCcuCollectivePlanner::PrepareDirectCcuLowerLayerPlanCallback", planner_source) + self.assertIn("ccuDirectRuntime_->CreateDriverAdapter", runtime_session_source) + self.assertIn("TileXRCcuMakeRepositoryDeviceMemoryOps(next.repositoryMemoryAllocMode)", planner_source) + self.assertIn("next.lowerLayerPlan = nullptr", planner_source) + self.assertIn( + "next.prepareLowerLayerPlan = &TileXRCcuCollectivePlanner::PrepareDirectCcuLowerLayerPlanCallback", + planner_source, + ) + self.assertIn("next.lowerLayerPlanUserData = &callbackContext", planner_source) + self.assertIn("TileXRCcuRunDirectInstallAttempt(next, attempt, report)", planner_source) + self.assertRegex( + planner_header, + r"(?s)#ifdef TILEXR_CCU_TESTING.*PrepareDirectCcuMemoryCopyInstallAttempt.*#endif", + ) + self.assertRegex( + planner_source, + r"(?s)#ifdef TILEXR_CCU_TESTING.*PrepareDirectCcuMemoryCopyInstallAttempt.*#endif", + ) + self.assertIn("int TileXRCcuDirectRuntime::CreateDriverAdapter", runtime_source) + self.assertNotIn("udmaTransport_->" + "CreateCcuDriverAdapter", comm_source + "\n" + backend_source + "\n" + runtime_session_source) + + combined = ( + comm_header + "\n" + comm_source + "\n" + backend_source + "\n" + + planner_source + "\n" + runtime_session_source + "\n" + runtime_header + "\n" + runtime_source + ) + for forbidden in [ + "TileXRCcuPrepareSubmitTasks", + "TileXRCcuSubmitTask", + "rtCCULaunch", + "HcclGetCcuTaskInfo", + "HcomGetCcuTaskInfo", + "libhcomm", + "libhccl_v2", + ]: + self.assertNotIn(forbidden, combined) + + def test_tilexr_comm_direct_ccu_prepare_fails_fast_after_process_init_failure(self): + runtime_session_source = CCU_RUNTIME_SESSION_SOURCE.read_text(encoding="utf-8") + planner_source = CCU_PLANNER_SOURCE.read_text(encoding="utf-8") + + self.assertIn("g_ccuDirectRuntimeUnavailableMessage", runtime_session_source) + init_body = runtime_session_source[ + runtime_session_source.index("int TileXRCcuRuntimeSession::Init("): + runtime_session_source.index("void TileXRCcuRuntimeSession::ResetDirectCcuBasicInfo") + ] + prepare_body = planner_source[ + planner_source.index("int TileXRCcuCollectivePlanner::PrepareDirectCcuInstallAttempt"): + planner_source.index("int TileXRCcuCollectivePlanner::PrepareDirectCcuMemoryCopyInstallAttempt") + ] + + self.assertIn("g_ccuDirectRuntimeUnavailableMessage = runtimeReport.message", init_body) + self.assertIn("direct CCU runtime unavailable after process-level init failure", runtime_session_source) + self.assertIn("ProcessDirectCcuRuntimeUnavailableMessage()", prepare_body) + self.assertLess( + prepare_body.index("ProcessDirectCcuRuntimeUnavailableMessage()"), + prepare_body.index("RefreshDirectCcuBasicInfo(installDieId)"), + ) + + def test_tilexr_comm_direct_ccu_runtime_init_serializes_ra_initialization(self): + runtime_session_source = CCU_RUNTIME_SESSION_SOURCE.read_text(encoding="utf-8") + init_body = runtime_session_source[ + runtime_session_source.index("int TileXRCcuRuntimeSession::Init("): + runtime_session_source.index("void TileXRCcuRuntimeSession::ResetDirectCcuBasicInfo") + ] + + lock_pos = init_body.index("lock_guard lock(g_ccuDirectRuntimeMtx);") + allocation_pos = init_body.index("ccuDirectRuntime_.reset(new (nothrow) TileXRCcuDirectRuntime())") + runtime_init_pos = init_body.index("ccuDirectRuntime_->Init(runtimeOptions, &runtimeReport)") + unavailable_set_pos = init_body.index("g_ccuDirectRuntimeUnavailable = true") + + self.assertLess(lock_pos, allocation_pos) + self.assertLess(allocation_pos, runtime_init_pos) + self.assertLess(runtime_init_pos, unavailable_set_pos) + self.assertEqual(1, init_body.count("lock_guard lock(g_ccuDirectRuntimeMtx);")) + + def test_tilexr_comm_direct_ccu_prepare_can_select_install_die_for_diagnostics(self): + planner_source = CCU_PLANNER_SOURCE.read_text(encoding="utf-8") + prepare_body = planner_source[ + planner_source.index("int TileXRCcuCollectivePlanner::PrepareDirectCcuInstallAttempt"): + planner_source.index("int TileXRCcuCollectivePlanner::PrepareDirectCcuMemoryCopyInstallAttempt") + ] + + self.assertIn("TILEXR_CCU_DIRECT_INSTALL_DIE_ID", planner_source) + self.assertIn("SelectDirectCcuInstallDieId", planner_source) + self.assertIn("RefreshDirectCcuBasicInfo(installDieId)", prepare_body) + self.assertIn("basicInfo->dieId != installDieId", prepare_body) + self.assertNotIn("RefreshDirectCcuBasicInfo(0)", prepare_body) + + def test_tilexr_comm_direct_ccu_thread_allgather_aborts_after_process_init_failure(self): + runtime_session_source = CCU_RUNTIME_SESSION_SOURCE.read_text(encoding="utf-8") + thread_allgather_body = runtime_session_source[ + runtime_session_source.index("int TileXRCcuRuntimeSession::DirectCcuThreadAllGather"): + runtime_session_source.index("} // namespace TileXR") + ] + + self.assertIn("ProcessDirectCcuRuntimeUnavailableMessage()", thread_allgather_body) + self.assertIn("direct CCU thread allgather abort", thread_allgather_body) + self.assertLess( + thread_allgather_body.index("ProcessDirectCcuRuntimeUnavailableMessage()"), + thread_allgather_body.index("TILEXR_INIT_TIMEOUT"), + ) + + def test_tilexr_comm_direct_ccu_lower_layer_plan_api_is_header_visible(self): + comm_header = COMM_HEADER_FILE.read_text(encoding="utf-8") + for leaked in [ + "ConfigureDirectCcuLowerLayerTemplate", + "ConfigureDirectCcuLowerLayerTemplateFromAllocation", + "PrepareDirectCcuLowerLayerTemplateFromAllocation", + "RefreshDirectCcuLowerLayerPlan", + "HasDirectCcuLowerLayerPlan", + "GetDirectCcuLowerLayerPlanStatus", + "GetDirectCcuLowerLayerPlanReport", + "GetDirectCcuLowerLayerPlan", + "RefreshDirectCcuBasicInfo", + "HasDirectCcuBasicInfo", + "GetDirectCcuBasicInfoStatus", + "GetDirectCcuBasicInfo", + "GetDirectCcuBasicInfoReport", + "ConfigureDirectCcuVerifiedEndpointRoutes", + "ConfigureDirectCcuLocalVerifiedEndpointRoute", + "PrepareDirectCcuInstallAttempt", + ]: + with self.subTest(leaked=leaked): + self.assertNotIn(leaked, comm_header) + + code = textwrap.dedent( + r''' + #include "tilexr_comm.h" + + #include + + using namespace TileXR; + + int main() + { + using InitFn = int (TileXRComm::*)(); + using GetterFn = TileXRCcuBackend* (TileXRComm::*)(); + using ConstGetterFn = const TileXRCcuBackend* (TileXRComm::*)() const; + using EnableForTestFn = int (TileXRComm::*)(); + + InitFn init = &TileXRComm::InitCcuBackend; + GetterFn getter = &TileXRComm::GetCcuBackendForCollectives; + ConstGetterFn constGetter = &TileXRComm::GetCcuBackendForCollectives; + EnableForTestFn enableForTest = &TileXRComm::EnableCcuBackendForTest; + (void)init; + (void)getter; + (void)constGetter; + (void)enableForTest; + return 0; + } + ''' + ) + + result = self.compile_only(code) + + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/ccu/test_tilexr_ccu_provider.py b/tests/ccu/test_tilexr_ccu_provider.py new file mode 100644 index 00000000..797bb62f --- /dev/null +++ b/tests/ccu/test_tilexr_ccu_provider.py @@ -0,0 +1,1618 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2026 TileXR Project +# + +import shutil +import subprocess +import tempfile +import textwrap +import unittest +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[2] +PROVIDER_HEADER = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_provider.h" +PROVIDER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_provider.cpp" +PACKAGE_HEADER = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_launch_package.h" +PACKAGE_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_launch_package.cpp" +REPOSITORY_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_repository.cpp" +DRIVER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp" +PRODUCER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_producer_plan.cpp" +BARRIER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_barrier_program.cpp" +MICROCODE_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_microcode.cpp" +COMM_CMAKE = REPO_ROOT / "src" / "comm" / "CMakeLists.txt" +INCLUDE_DIR = REPO_ROOT / "src" / "include" +COMM_DIR = REPO_ROOT / "src" / "comm" + + +PRIVATE_CCU_PRODUCER_NEEDLES = [ + "#include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 1}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 1}; + plan.barrierMode = TileXRCcuBarrierMode::LocalCkePostOnly; + + TileXRCcuSyncResource resource; + resource.dieId = 1; + resource.localXn = 1961; + resource.remoteXn = 2361; + resource.notifyCke = 364; + resource.channelId = 2; + resource.bindingCount = 1; + resource.localWaitCke = 332; + plan.syncResources.push_back(resource); + + plan.taskWindows.push_back({1, 489, 1, 13, {}}); + return plan; + } + + TileXRCcuEvidenceSource Source( + const TileXRCcuLaunchPackage& package, + const char* label, + bool endpointRouteVerified) + { + TileXRCcuEvidenceSource source; + source.kind = TileXRCcuEvidenceKind::PublicVerified; + source.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + source.packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + source.deviceId = package.installScope.deviceId; + source.rank = package.installScope.rank; + source.provider = package.installScope.provider; + source.installAttemptReceiptId = 0xabc001ULL; + source.endpointRouteVerified = endpointRouteVerified; + source.source = std::string("unit-test-public-provider:") + label; + source.detail = std::string("audited ") + label + " evidence"; + return source; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed: " << packageReport.message << "\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 2; + } + + TileXRCcuHardwareInstallEvidence evidence; + evidence.missionInstalled = true; + evidence.repositoryInstalled = true; + evidence.localXnInstalled = true; + evidence.notifyCkeInstalled = true; + evidence.missionSource = Source(package, "mission", false); + evidence.repositorySource = Source(package, "repository", false); + evidence.localXnSource = Source(package, "local-xn", false); + evidence.notifyCkeSource = Source(package, "notify-cke", false); + + std::vector submitTasks; + TileXRCcuProviderReport report; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &report) != TILEXR_SUCCESS) { + std::cerr << "local CKE post-only submit was rejected: " << report.message << "\n"; + return 3; + } + if (!report.submitReady || submitTasks.size() != package.tasks.size()) { + std::cerr << "local CKE submit readiness mismatch\n"; + return 4; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_provider_gate_requires_complete_hardware_install_evidence(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {0x100051152e00ULL}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed\n"; + return 1; + } + + TileXRCcuProviderReport report; + if (TileXRCcuValidateHardwareInstall(package, {}, &report) != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "empty install evidence was accepted\n"; + return 2; + } + if (report.message.find("mission") == std::string::npos) { + std::cerr << "empty install diagnostic was weak: " << report.message << "\n"; + return 3; + } + + TileXRCcuHardwareInstallEvidence evidence; + evidence.missionInstalled = true; + evidence.repositoryInstalled = true; + evidence.localXnInstalled = true; + evidence.remoteXnBound = true; + evidence.notifyCkeInstalled = true; + if (TileXRCcuValidateHardwareInstall(package, evidence, &report) != TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "missing channel binding was accepted\n"; + return 4; + } + if (report.message.find("channel") == std::string::npos) { + std::cerr << "channel diagnostic was weak: " << report.message << "\n"; + return 5; + } + + evidence.channelBindingsInstalled = true; + if (TileXRCcuValidateHardwareInstall(package, evidence, &report) != TILEXR_SUCCESS) { + std::cerr << "complete install evidence was rejected: " << report.message << "\n"; + return 6; + } + if (report.taskCount != 2 || report.installedInstructionCount != 24 || + report.repositoryCount != 170 || report.submitReady || + report.message.find("validate-compatible") == std::string::npos) { + std::cerr << "unexpected provider report\n"; + return 7; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_provider_gate_marks_package_submit_ready_only_after_install_evidence(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_provider.h" + + #include + + using namespace TileXR; + + int main() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(plan, &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 8; + } + + std::vector submitTasks; + TileXRCcuProviderReport report; + if (TileXRCcuPrepareSubmitTasks(package, {}, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "uninstalled package became submit-ready\n"; + return 2; + } + if (!submitTasks.empty()) { + std::cerr << "failed prepare left submit tasks\n"; + return 3; + } + + const uint64_t packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + TileXRCcuHardwareInstallEvidence evidence; + evidence.missionInstalled = true; + evidence.repositoryInstalled = true; + evidence.localXnInstalled = true; + evidence.remoteXnBound = true; + evidence.notifyCkeInstalled = true; + evidence.channelBindingsInstalled = true; + evidence.missionSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.missionSource.source = "unit-test-public-provider:mission"; + evidence.missionSource.detail = "audited mission/key evidence"; + evidence.missionSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.repositorySource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.repositorySource.source = "unit-test-public-provider:repository"; + evidence.repositorySource.detail = "audited repository evidence"; + evidence.repositorySource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.localXnSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.localXnSource.source = "unit-test-public-provider:local-xn"; + evidence.localXnSource.detail = "audited local XN evidence"; + evidence.localXnSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.remoteXnSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.remoteXnSource.source = "ValidateRemoteXnExchangeBindingProof"; + evidence.remoteXnSource.detail = + "remote XN peer exchange proof matches syncXn operands and verified endpoint route channel contexts"; + evidence.remoteXnSource.endpointRouteVerified = true; + evidence.remoteXnSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.notifyCkeSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.notifyCkeSource.source = "unit-test-public-provider:notify-cke"; + evidence.notifyCkeSource.detail = "audited notify CKE evidence"; + evidence.notifyCkeSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.channelBindingSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.channelBindingSource.source = "unit-test-public-provider:channel-binding"; + evidence.channelBindingSource.detail = + "channel binding contexts installed via SET_PFE, SET_JETTY_CTX, SET_CHANNEL with verified endpoint routes"; + evidence.channelBindingSource.endpointRouteVerified = true; + evidence.channelBindingSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.missionSource.packageFingerprint = packageFingerprint; + evidence.repositorySource.packageFingerprint = packageFingerprint; + evidence.localXnSource.packageFingerprint = packageFingerprint; + evidence.remoteXnSource.packageFingerprint = packageFingerprint; + evidence.notifyCkeSource.packageFingerprint = packageFingerprint; + evidence.channelBindingSource.packageFingerprint = packageFingerprint; + evidence.missionSource.deviceId = 3; + evidence.repositorySource.deviceId = 3; + evidence.localXnSource.deviceId = 3; + evidence.remoteXnSource.deviceId = 3; + evidence.notifyCkeSource.deviceId = 3; + evidence.channelBindingSource.deviceId = 3; + evidence.missionSource.rank = 1; + evidence.repositorySource.rank = 1; + evidence.localXnSource.rank = 1; + evidence.remoteXnSource.rank = 1; + evidence.notifyCkeSource.rank = 1; + evidence.channelBindingSource.rank = 1; + evidence.missionSource.provider = "unit-test-public-install-provider"; + evidence.repositorySource.provider = "unit-test-public-install-provider"; + evidence.localXnSource.provider = "unit-test-public-install-provider"; + evidence.remoteXnSource.provider = "unit-test-public-install-provider"; + evidence.notifyCkeSource.provider = "unit-test-public-install-provider"; + evidence.channelBindingSource.provider = "unit-test-public-install-provider"; + evidence.missionSource.installAttemptReceiptId = 0xabc001ULL; + evidence.repositorySource.installAttemptReceiptId = 0xabc001ULL; + evidence.localXnSource.installAttemptReceiptId = 0xabc001ULL; + evidence.remoteXnSource.installAttemptReceiptId = 0xabc001ULL; + evidence.notifyCkeSource.installAttemptReceiptId = 0xabc001ULL; + evidence.channelBindingSource.installAttemptReceiptId = 0xabc001ULL; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &report) != TILEXR_SUCCESS) { + std::cerr << "complete install evidence was rejected: " << report.message << "\n"; + return 4; + } + if (submitTasks.size() != 2 || submitTasks[0].instStartId != 489 || + submitTasks[0].instCnt != 13 || submitTasks[0].argSize != 13 || + submitTasks[1].instStartId != 502 || submitTasks[1].instCnt != 143 || + submitTasks[1].argSize != 13) { + std::cerr << "unexpected submit tasks\n"; + return 5; + } + if (!report.submitReady || report.message != "ok") { + std::cerr << "unexpected submit-ready report\n"; + return 6; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_prepare_rejects_legacy_bool_only_evidence_for_submit(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_provider.h" + + #include + + using namespace TileXR; + + int main() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(plan, &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed\n"; + return 1; + } + + TileXRCcuHardwareInstallEvidence evidence; + evidence.missionInstalled = true; + evidence.repositoryInstalled = true; + evidence.localXnInstalled = true; + evidence.remoteXnBound = true; + evidence.notifyCkeInstalled = true; + evidence.channelBindingsInstalled = true; + + TileXRCcuProviderReport report; + if (TileXRCcuValidateHardwareInstall(package, evidence, &report) != TILEXR_SUCCESS) { + std::cerr << "legacy bool install evidence should remain validate-compatible: " + << report.message << "\n"; + return 2; + } + if (report.submitReady || report.legacyEvidenceCount != 6) { + std::cerr << "legacy validate report incorrectly claimed submit-ready\n"; + return 3; + } + + std::vector submitTasks; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "legacy bool-only evidence became submit-ready\n"; + return 4; + } + if (!submitTasks.empty()) { + std::cerr << "failed legacy prepare left submit tasks\n"; + return 5; + } + if (report.submitReady || report.legacyEvidenceCount != 6) { + std::cerr << "unexpected failed prepare report\n"; + return 6; + } + if (report.message.find("submit requires public verified evidence") == std::string::npos) { + std::cerr << "legacy submit diagnostic was weak: " << report.message << "\n"; + return 7; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_prepare_requires_auditable_public_verified_evidence_sources(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + TileXRCcuHardwareInstallEvidence VerifiedEvidence(const TileXRCcuLaunchPackage& package) + { + const uint64_t packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + TileXRCcuHardwareInstallEvidence evidence; + evidence.missionInstalled = true; + evidence.repositoryInstalled = true; + evidence.localXnInstalled = true; + evidence.remoteXnBound = true; + evidence.notifyCkeInstalled = true; + evidence.channelBindingsInstalled = true; + evidence.missionSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.repositorySource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.localXnSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.remoteXnSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.notifyCkeSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.channelBindingSource.kind = TileXRCcuEvidenceKind::PublicVerified; + return evidence; + } + + void FillAuditSources(TileXRCcuHardwareInstallEvidence& evidence, const TileXRCcuLaunchPackage& package) + { + const uint64_t packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + evidence.missionSource.source = "unit-test-public-provider:mission"; + evidence.missionSource.detail = "audited mission/key evidence"; + evidence.missionSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.missionSource.packageFingerprint = packageFingerprint; + evidence.repositorySource.source = "unit-test-public-provider:repository"; + evidence.repositorySource.detail = "audited repository evidence"; + evidence.repositorySource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.repositorySource.packageFingerprint = packageFingerprint; + evidence.localXnSource.source = "unit-test-public-provider:local-xn"; + evidence.localXnSource.detail = "audited local XN evidence"; + evidence.localXnSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.localXnSource.packageFingerprint = packageFingerprint; + evidence.remoteXnSource.source = "unit-test-public-provider:remote-xn"; + evidence.remoteXnSource.detail = "audited remote XN evidence"; + evidence.remoteXnSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.remoteXnSource.endpointRouteVerified = true; + evidence.remoteXnSource.packageFingerprint = packageFingerprint; + evidence.notifyCkeSource.source = "unit-test-public-provider:notify-cke"; + evidence.notifyCkeSource.detail = "audited notify CKE evidence"; + evidence.notifyCkeSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.notifyCkeSource.packageFingerprint = packageFingerprint; + evidence.channelBindingSource.source = "unit-test-public-provider:channel-binding"; + evidence.channelBindingSource.detail = "audited channel binding evidence"; + evidence.channelBindingSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.channelBindingSource.endpointRouteVerified = true; + evidence.channelBindingSource.packageFingerprint = packageFingerprint; + evidence.missionSource.deviceId = package.installScope.deviceId; + evidence.repositorySource.deviceId = package.installScope.deviceId; + evidence.localXnSource.deviceId = package.installScope.deviceId; + evidence.remoteXnSource.deviceId = package.installScope.deviceId; + evidence.notifyCkeSource.deviceId = package.installScope.deviceId; + evidence.channelBindingSource.deviceId = package.installScope.deviceId; + evidence.missionSource.rank = package.installScope.rank; + evidence.repositorySource.rank = package.installScope.rank; + evidence.localXnSource.rank = package.installScope.rank; + evidence.remoteXnSource.rank = package.installScope.rank; + evidence.notifyCkeSource.rank = package.installScope.rank; + evidence.channelBindingSource.rank = package.installScope.rank; + evidence.missionSource.provider = package.installScope.provider; + evidence.repositorySource.provider = package.installScope.provider; + evidence.localXnSource.provider = package.installScope.provider; + evidence.remoteXnSource.provider = package.installScope.provider; + evidence.notifyCkeSource.provider = package.installScope.provider; + evidence.channelBindingSource.provider = package.installScope.provider; + evidence.missionSource.installAttemptReceiptId = 0xabc001ULL; + evidence.repositorySource.installAttemptReceiptId = 0xabc001ULL; + evidence.localXnSource.installAttemptReceiptId = 0xabc001ULL; + evidence.remoteXnSource.installAttemptReceiptId = 0xabc001ULL; + evidence.notifyCkeSource.installAttemptReceiptId = 0xabc001ULL; + evidence.channelBindingSource.installAttemptReceiptId = 0xabc001ULL; + } + + void MarkEndpointRoutesVerified(TileXRCcuHardwareInstallEvidence& evidence) + { + evidence.remoteXnSource.endpointRouteVerified = true; + evidence.channelBindingSource.endpointRouteVerified = true; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 10; + } + + TileXRCcuHardwareInstallEvidence evidence = VerifiedEvidence(package); + TileXRCcuProviderReport report; + if (TileXRCcuValidateHardwareInstall(package, evidence, &report) != TILEXR_SUCCESS) { + std::cerr << "validate compatibility rejected verified kind without audit strings: " + << report.message << "\n"; + return 2; + } + + std::vector submitTasks; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "public verified evidence without source/detail became submit-ready\n"; + return 3; + } + if (!submitTasks.empty()) { + std::cerr << "failed unaudited prepare left submit tasks\n"; + return 4; + } + if (report.message.find("public verified evidence source/detail required") == std::string::npos) { + std::cerr << "unaudited diagnostic was weak: " << report.message << "\n"; + return 5; + } + + FillAuditSources(evidence, package); + evidence.missionSource.surface = TileXRCcuEvidenceSurface::Unspecified; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "public verified evidence without provider surface became submit-ready\n"; + return 6; + } + if (report.message.find("public install provider evidence") == std::string::npos) { + std::cerr << "unclassified surface diagnostic was weak: " << report.message << "\n"; + return 7; + } + + evidence.missionSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.remoteXnSource.endpointRouteVerified = false; + evidence.channelBindingSource.endpointRouteVerified = false; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "generic endpoint evidence became submit-ready\n"; + return 8; + } + if (report.message.find("verified endpoint route") == std::string::npos) { + std::cerr << "endpoint provenance diagnostic was weak: " << report.message << "\n"; + return 9; + } + + MarkEndpointRoutesVerified(evidence); + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &report) != TILEXR_SUCCESS) { + std::cerr << "audited public verified evidence was rejected: " << report.message << "\n"; + return 10; + } + if (submitTasks.size() != 2 || submitTasks[0].instStartId != 489 || + submitTasks[0].instCnt != 13 || submitTasks[1].instStartId != 502 || + submitTasks[1].instCnt != 143 || !report.submitReady || + report.publicVerifiedEvidenceCount != 6) { + std::cerr << "unexpected audited submit report\n"; + return 11; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_prepare_requires_install_evidence_to_match_launch_package_fingerprint(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan(uint32_t key, uint64_t firstArg) + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, key, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {firstArg}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + TileXRCcuEvidenceSource Source(const char* label, const TileXRCcuLaunchPackage& package) + { + TileXRCcuEvidenceSource source; + source.kind = TileXRCcuEvidenceKind::PublicVerified; + source.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + source.source = label; + const uint64_t fingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + source.detail = std::string("installed package fingerprint=") + std::to_string(fingerprint); + const std::string labelText(label); + if (labelText.find("remote-xn") != std::string::npos || + labelText.find("channel-binding") != std::string::npos) { + source.endpointRouteVerified = true; + } + source.packageFingerprint = fingerprint; + source.deviceId = package.installScope.deviceId; + source.rank = package.installScope.rank; + source.provider = package.installScope.provider; + source.installAttemptReceiptId = 0xabc001ULL; + return source; + } + + TileXRCcuHardwareInstallEvidence EvidenceFor(const TileXRCcuLaunchPackage& package) + { + TileXRCcuHardwareInstallEvidence evidence; + evidence.missionInstalled = true; + evidence.repositoryInstalled = true; + evidence.localXnInstalled = true; + evidence.remoteXnBound = true; + evidence.notifyCkeInstalled = true; + evidence.channelBindingsInstalled = true; + evidence.missionSource = Source("unit-test-public-provider:mission", package); + evidence.repositorySource = Source("unit-test-public-provider:repository", package); + evidence.localXnSource = Source("unit-test-public-provider:local-xn", package); + evidence.remoteXnSource = Source("unit-test-public-provider:remote-xn", package); + evidence.notifyCkeSource = Source("unit-test-public-provider:notify-cke", package); + evidence.channelBindingSource = Source("unit-test-public-provider:channel-binding", package); + return evidence; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(0x059b0f03U, 0x100051152e00ULL), &package, &packageReport) != + TILEXR_SUCCESS) { + std::cerr << "package build failed\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 11; + } + const uint64_t fingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + if (fingerprint == 0) { + std::cerr << "package fingerprint was zero\n"; + return 2; + } + + TileXRCcuHardwareInstallEvidence evidence = EvidenceFor(package); + std::vector submitTasks; + TileXRCcuProviderReport report; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &report) != TILEXR_SUCCESS) { + std::cerr << "matching evidence rejected: " << report.message << "\n"; + return 3; + } + + TileXRCcuLaunchPackage changedKeyPackage; + if (TileXRCcuBuildLaunchPackage( + MakePlan(0xe0ac084cU, 0x100051152e00ULL), &changedKeyPackage, &packageReport) != + TILEXR_SUCCESS) { + std::cerr << "changed-key package build failed\n"; + return 4; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &changedKeyPackage, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "changed-key scope bind failed\n"; + return 12; + } + if (TileXRCcuComputeLaunchPackageFingerprint(changedKeyPackage) == fingerprint) { + std::cerr << "changed key did not affect package fingerprint\n"; + return 5; + } + if (TileXRCcuPrepareSubmitTasks(changedKeyPackage, evidence, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "evidence for old key was accepted for changed package\n"; + return 6; + } + if (report.message.find("fingerprint") == std::string::npos) { + std::cerr << "fingerprint diagnostic was weak: " << report.message << "\n"; + return 7; + } + + TileXRCcuLaunchPackage changedArgsPackage; + if (TileXRCcuBuildLaunchPackage( + MakePlan(0x059b0f03U, 0x200051152e00ULL), &changedArgsPackage, &packageReport) != + TILEXR_SUCCESS) { + std::cerr << "changed-args package build failed\n"; + return 8; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &changedArgsPackage, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "changed-args scope bind failed\n"; + return 13; + } + if (TileXRCcuComputeLaunchPackageFingerprint(changedArgsPackage) == fingerprint) { + std::cerr << "changed task args did not affect package fingerprint\n"; + return 9; + } + if (TileXRCcuPrepareSubmitTasks(changedArgsPackage, evidence, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "evidence for old task args was accepted for changed package\n"; + return 10; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_prepare_requires_install_evidence_to_match_launch_scope(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {0x100051152e00ULL}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + TileXRCcuEvidenceSource Source( + const char* label, + const TileXRCcuLaunchPackage& package, + uint32_t deviceId, + uint32_t rank, + const char* provider) + { + TileXRCcuEvidenceSource source; + source.kind = TileXRCcuEvidenceKind::PublicVerified; + source.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + source.source = label; + source.detail = "installed for explicit launch scope"; + const std::string labelText(label); + if (labelText.find("remote-xn") != std::string::npos || + labelText.find("channel-binding") != std::string::npos) { + source.endpointRouteVerified = true; + } + source.packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + source.deviceId = deviceId; + source.rank = rank; + source.provider = provider; + source.installAttemptReceiptId = 0xabc001ULL; + return source; + } + + TileXRCcuHardwareInstallEvidence EvidenceFor( + const TileXRCcuLaunchPackage& package, + uint32_t deviceId, + uint32_t rank, + const char* provider) + { + TileXRCcuHardwareInstallEvidence evidence; + evidence.missionInstalled = true; + evidence.repositoryInstalled = true; + evidence.localXnInstalled = true; + evidence.remoteXnBound = true; + evidence.notifyCkeInstalled = true; + evidence.channelBindingsInstalled = true; + evidence.missionSource = Source("unit-test-public-provider:mission", package, deviceId, rank, provider); + evidence.repositorySource = + Source("unit-test-public-provider:repository", package, deviceId, rank, provider); + evidence.localXnSource = + Source("unit-test-public-provider:local-xn", package, deviceId, rank, provider); + evidence.remoteXnSource = + Source("unit-test-public-provider:remote-xn", package, deviceId, rank, provider); + evidence.notifyCkeSource = + Source("unit-test-public-provider:notify-cke", package, deviceId, rank, provider); + evidence.channelBindingSource = + Source("unit-test-public-provider:channel-binding", package, deviceId, rank, provider); + return evidence; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "failed to bind launch install scope\n"; + return 2; + } + + TileXRCcuProviderReport report; + std::vector submitTasks; + + TileXRCcuHardwareInstallEvidence wrongDevice = + EvidenceFor(package, 4, 1, "unit-test-public-install-provider"); + if (TileXRCcuPrepareSubmitTasks(package, wrongDevice, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "evidence from another device became submit-ready\n"; + return 3; + } + if (!submitTasks.empty() || report.submitReady || + report.message.find("device") == std::string::npos) { + std::cerr << "device-scope diagnostic was weak: " << report.message << "\n"; + return 4; + } + + TileXRCcuHardwareInstallEvidence wrongRank = + EvidenceFor(package, 3, 0, "unit-test-public-install-provider"); + if (TileXRCcuPrepareSubmitTasks(package, wrongRank, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "evidence from another rank became submit-ready\n"; + return 5; + } + if (!submitTasks.empty() || report.submitReady || + report.message.find("rank") == std::string::npos) { + std::cerr << "rank-scope diagnostic was weak: " << report.message << "\n"; + return 6; + } + + TileXRCcuHardwareInstallEvidence wrongProvider = + EvidenceFor(package, 3, 1, "other-public-install-provider"); + if (TileXRCcuPrepareSubmitTasks(package, wrongProvider, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "evidence from another provider became submit-ready\n"; + return 7; + } + if (!submitTasks.empty() || report.submitReady || + report.message.find("provider") == std::string::npos) { + std::cerr << "provider-scope diagnostic was weak: " << report.message << "\n"; + return 8; + } + + TileXRCcuHardwareInstallEvidence matching = + EvidenceFor(package, 3, 1, "unit-test-public-install-provider"); + if (TileXRCcuPrepareSubmitTasks(package, matching, &submitTasks, &report) != TILEXR_SUCCESS) { + std::cerr << "matching scope evidence was rejected: " << report.message << "\n"; + return 9; + } + if (submitTasks.size() != package.tasks.size() || !report.submitReady) { + std::cerr << "unexpected matching scope submit state\n"; + return 10; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_prepare_requires_all_public_verified_evidence_from_same_install_receipt(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {0x100051152e00ULL}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + TileXRCcuEvidenceSource Source( + const char* label, + const TileXRCcuLaunchPackage& package, + uint64_t receipt) + { + TileXRCcuEvidenceSource source; + source.kind = TileXRCcuEvidenceKind::PublicVerified; + source.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + source.source = label; + source.detail = "installed for a single public install attempt"; + const std::string labelText(label); + if (labelText.find("remote-xn") != std::string::npos || + labelText.find("channel-binding") != std::string::npos) { + source.endpointRouteVerified = true; + } + source.packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + source.deviceId = package.installScope.deviceId; + source.rank = package.installScope.rank; + source.provider = package.installScope.provider; + source.installAttemptReceiptId = receipt; + return source; + } + + TileXRCcuHardwareInstallEvidence EvidenceFor( + const TileXRCcuLaunchPackage& package, + uint64_t receipt) + { + TileXRCcuHardwareInstallEvidence evidence; + evidence.missionInstalled = true; + evidence.repositoryInstalled = true; + evidence.localXnInstalled = true; + evidence.remoteXnBound = true; + evidence.notifyCkeInstalled = true; + evidence.channelBindingsInstalled = true; + evidence.missionSource = Source("unit-test-public-provider:mission", package, receipt); + evidence.repositorySource = Source("unit-test-public-provider:repository", package, receipt); + evidence.localXnSource = Source("unit-test-public-provider:local-xn", package, receipt); + evidence.remoteXnSource = Source("unit-test-public-provider:remote-xn", package, receipt); + evidence.notifyCkeSource = Source("unit-test-public-provider:notify-cke", package, receipt); + evidence.channelBindingSource = Source("unit-test-public-provider:channel-binding", package, receipt); + return evidence; + } + + int ExpectReceiptFailure( + const TileXRCcuLaunchPackage& package, + const TileXRCcuHardwareInstallEvidence& evidence, + const char* expectedDiagnostic) + { + std::vector submitTasks; + TileXRCcuProviderReport report; + if (TileXRCcuPrepareSubmitTasks(package, evidence, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "receipt mismatch became submit-ready\n"; + return 1; + } + if (!submitTasks.empty() || report.submitReady || + report.message.find(expectedDiagnostic) == std::string::npos) { + std::cerr << "weak receipt diagnostic: " << report.message << "\n"; + return 2; + } + return 0; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "failed to bind launch install scope\n"; + return 2; + } + + TileXRCcuHardwareInstallEvidence missingReceipt = EvidenceFor(package, 0); + if (ExpectReceiptFailure(package, missingReceipt, "receipt") != 0) { + return 3; + } + + TileXRCcuHardwareInstallEvidence mixedReceipt = EvidenceFor(package, 0xabc001ULL); + mixedReceipt.notifyCkeSource.installAttemptReceiptId = 0xabc002ULL; + if (ExpectReceiptFailure(package, mixedReceipt, "receipt") != 0) { + return 4; + } + + TileXRCcuHardwareInstallEvidence matchingReceipt = EvidenceFor(package, 0xabc001ULL); + std::vector submitTasks; + TileXRCcuProviderReport report; + if (TileXRCcuPrepareSubmitTasks(package, matchingReceipt, &submitTasks, &report) != TILEXR_SUCCESS) { + std::cerr << "matching receipt evidence was rejected: " << report.message << "\n"; + return 5; + } + if (submitTasks.size() != package.tasks.size() || !report.submitReady) { + std::cerr << "unexpected matching receipt submit state\n"; + return 6; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_prepare_rejects_public_verified_evidence_from_lower_layer_or_private_sources(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + TileXRCcuHardwareInstallEvidence AuditedEvidence(const TileXRCcuLaunchPackage& package) + { + const uint64_t packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + TileXRCcuHardwareInstallEvidence evidence; + evidence.missionInstalled = true; + evidence.repositoryInstalled = true; + evidence.localXnInstalled = true; + evidence.remoteXnBound = true; + evidence.notifyCkeInstalled = true; + evidence.channelBindingsInstalled = true; + evidence.missionSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.missionSource.source = "unit-test-public-provider:mission"; + evidence.missionSource.detail = "audited mission/key evidence"; + evidence.missionSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.missionSource.packageFingerprint = packageFingerprint; + evidence.repositorySource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.repositorySource.source = "unit-test-public-provider:repository"; + evidence.repositorySource.detail = "audited repository evidence"; + evidence.repositorySource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.repositorySource.packageFingerprint = packageFingerprint; + evidence.localXnSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.localXnSource.source = "unit-test-public-provider:local-xn"; + evidence.localXnSource.detail = "audited local XN evidence"; + evidence.localXnSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.localXnSource.packageFingerprint = packageFingerprint; + evidence.remoteXnSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.remoteXnSource.source = "unit-test-public-provider:remote-xn"; + evidence.remoteXnSource.detail = "audited remote XN evidence"; + evidence.remoteXnSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.remoteXnSource.endpointRouteVerified = true; + evidence.remoteXnSource.packageFingerprint = packageFingerprint; + evidence.notifyCkeSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.notifyCkeSource.source = "unit-test-public-provider:notify-cke"; + evidence.notifyCkeSource.detail = "audited notify CKE evidence"; + evidence.notifyCkeSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.notifyCkeSource.packageFingerprint = packageFingerprint; + evidence.channelBindingSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.channelBindingSource.source = "unit-test-public-provider:channel-binding"; + evidence.channelBindingSource.detail = "audited channel binding evidence"; + evidence.channelBindingSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.channelBindingSource.endpointRouteVerified = true; + evidence.channelBindingSource.packageFingerprint = packageFingerprint; + evidence.missionSource.deviceId = package.installScope.deviceId; + evidence.repositorySource.deviceId = package.installScope.deviceId; + evidence.localXnSource.deviceId = package.installScope.deviceId; + evidence.remoteXnSource.deviceId = package.installScope.deviceId; + evidence.notifyCkeSource.deviceId = package.installScope.deviceId; + evidence.channelBindingSource.deviceId = package.installScope.deviceId; + evidence.missionSource.rank = package.installScope.rank; + evidence.repositorySource.rank = package.installScope.rank; + evidence.localXnSource.rank = package.installScope.rank; + evidence.remoteXnSource.rank = package.installScope.rank; + evidence.notifyCkeSource.rank = package.installScope.rank; + evidence.channelBindingSource.rank = package.installScope.rank; + evidence.missionSource.provider = package.installScope.provider; + evidence.repositorySource.provider = package.installScope.provider; + evidence.localXnSource.provider = package.installScope.provider; + evidence.remoteXnSource.provider = package.installScope.provider; + evidence.notifyCkeSource.provider = package.installScope.provider; + evidence.channelBindingSource.provider = package.installScope.provider; + evidence.missionSource.installAttemptReceiptId = 0xabc001ULL; + evidence.repositorySource.installAttemptReceiptId = 0xabc001ULL; + evidence.localXnSource.installAttemptReceiptId = 0xabc001ULL; + evidence.remoteXnSource.installAttemptReceiptId = 0xabc001ULL; + evidence.notifyCkeSource.installAttemptReceiptId = 0xabc001ULL; + evidence.channelBindingSource.installAttemptReceiptId = 0xabc001ULL; + return evidence; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 8; + } + + TileXRCcuProviderReport report; + std::vector submitTasks; + + TileXRCcuHardwareInstallEvidence mappingEvidence = AuditedEvidence(package); + mappingEvidence.localXnSource.source = "unit-test-public-mapper:local-xn"; + mappingEvidence.localXnSource.detail = "maps existing XN resources but does not install them"; + mappingEvidence.localXnSource.surface = TileXRCcuEvidenceSurface::LowerLayerResourceHelper; + if (TileXRCcuValidateHardwareInstall(package, mappingEvidence, &report) != TILEXR_SUCCESS) { + std::cerr << "validate compatibility rejected mapping evidence: " << report.message << "\n"; + return 2; + } + if (TileXRCcuPrepareSubmitTasks(package, mappingEvidence, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "lower-layer mapping helper became submit-ready\n"; + return 3; + } + if (report.message.find("public install provider evidence") == std::string::npos || + report.message.find("lower-layer resource helper") == std::string::npos) { + std::cerr << "mapping diagnostic was weak: " << report.message << "\n"; + return 4; + } + + TileXRCcuHardwareInstallEvidence notifyEvidence = AuditedEvidence(package); + notifyEvidence.notifyCkeSource.source = "unit-test-public-notify-reader:notify-cke"; + notifyEvidence.notifyCkeSource.detail = "reads an existing notify address but does not install CKE"; + notifyEvidence.notifyCkeSource.surface = TileXRCcuEvidenceSurface::LowerLayerResourceHelper; + if (TileXRCcuPrepareSubmitTasks(package, notifyEvidence, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "lower-layer notify helper became submit-ready\n"; + return 5; + } + + TileXRCcuHardwareInstallEvidence privateEvidence = AuditedEvidence(package); + privateEvidence.repositorySource.source = "unit-test-private-observation:repository"; + privateEvidence.repositorySource.detail = "private repository install observation"; + privateEvidence.repositorySource.surface = TileXRCcuEvidenceSurface::PrivateProducerObservation; + if (TileXRCcuPrepareSubmitTasks(package, privateEvidence, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "private repository installer became submit-ready\n"; + return 6; + } + + TileXRCcuHardwareInstallEvidence audited = AuditedEvidence(package); + if (TileXRCcuPrepareSubmitTasks(package, audited, &submitTasks, &report) != TILEXR_SUCCESS) { + std::cerr << "neutral audited evidence was rejected: " << report.message << "\n"; + return 7; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_provider_gate_rejects_private_and_unvalidated_candidate_evidence(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + TileXRCcuHardwareInstallEvidence VerifiedEvidence(const TileXRCcuLaunchPackage& package) + { + const uint64_t packageFingerprint = TileXRCcuComputeLaunchPackageFingerprint(package); + TileXRCcuHardwareInstallEvidence evidence; + evidence.missionInstalled = true; + evidence.repositoryInstalled = true; + evidence.localXnInstalled = true; + evidence.remoteXnBound = true; + evidence.notifyCkeInstalled = true; + evidence.channelBindingsInstalled = true; + evidence.missionSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.missionSource.source = "unit-test-public-provider:mission"; + evidence.missionSource.detail = "audited mission/key evidence"; + evidence.missionSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.missionSource.packageFingerprint = packageFingerprint; + evidence.repositorySource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.repositorySource.source = "unit-test-public-provider:repository"; + evidence.repositorySource.detail = "audited repository evidence"; + evidence.repositorySource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.repositorySource.packageFingerprint = packageFingerprint; + evidence.localXnSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.localXnSource.source = "unit-test-public-provider:local-xn"; + evidence.localXnSource.detail = "audited local XN evidence"; + evidence.localXnSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.localXnSource.packageFingerprint = packageFingerprint; + evidence.remoteXnSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.remoteXnSource.source = "unit-test-public-provider:remote-xn"; + evidence.remoteXnSource.detail = "audited remote XN evidence"; + evidence.remoteXnSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.remoteXnSource.endpointRouteVerified = true; + evidence.remoteXnSource.packageFingerprint = packageFingerprint; + evidence.notifyCkeSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.notifyCkeSource.source = "unit-test-public-provider:notify-cke"; + evidence.notifyCkeSource.detail = "audited notify CKE evidence"; + evidence.notifyCkeSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.notifyCkeSource.packageFingerprint = packageFingerprint; + evidence.channelBindingSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.channelBindingSource.source = "unit-test-public-provider:channel-binding"; + evidence.channelBindingSource.detail = "audited channel binding evidence"; + evidence.channelBindingSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.channelBindingSource.endpointRouteVerified = true; + evidence.channelBindingSource.packageFingerprint = packageFingerprint; + evidence.missionSource.deviceId = package.installScope.deviceId; + evidence.repositorySource.deviceId = package.installScope.deviceId; + evidence.localXnSource.deviceId = package.installScope.deviceId; + evidence.remoteXnSource.deviceId = package.installScope.deviceId; + evidence.notifyCkeSource.deviceId = package.installScope.deviceId; + evidence.channelBindingSource.deviceId = package.installScope.deviceId; + evidence.missionSource.rank = package.installScope.rank; + evidence.repositorySource.rank = package.installScope.rank; + evidence.localXnSource.rank = package.installScope.rank; + evidence.remoteXnSource.rank = package.installScope.rank; + evidence.notifyCkeSource.rank = package.installScope.rank; + evidence.channelBindingSource.rank = package.installScope.rank; + evidence.missionSource.provider = package.installScope.provider; + evidence.repositorySource.provider = package.installScope.provider; + evidence.localXnSource.provider = package.installScope.provider; + evidence.remoteXnSource.provider = package.installScope.provider; + evidence.notifyCkeSource.provider = package.installScope.provider; + evidence.channelBindingSource.provider = package.installScope.provider; + evidence.missionSource.installAttemptReceiptId = 0xabc001ULL; + evidence.repositorySource.installAttemptReceiptId = 0xabc001ULL; + evidence.localXnSource.installAttemptReceiptId = 0xabc001ULL; + evidence.remoteXnSource.installAttemptReceiptId = 0xabc001ULL; + evidence.notifyCkeSource.installAttemptReceiptId = 0xabc001ULL; + evidence.channelBindingSource.installAttemptReceiptId = 0xabc001ULL; + return evidence; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed\n"; + return 1; + } + if (TileXRCcuBindLaunchPackageInstallScope( + &package, 3, 1, "unit-test-public-install-provider") != TILEXR_SUCCESS) { + std::cerr << "scope bind failed\n"; + return 9; + } + + TileXRCcuProviderReport report; + TileXRCcuHardwareInstallEvidence privateEvidence = VerifiedEvidence(package); + privateEvidence.remoteXnSource.kind = TileXRCcuEvidenceKind::PrivateObserved; + privateEvidence.remoteXnSource.source = "hcomm::CcuKernel::CreateVariable"; + if (TileXRCcuValidateHardwareInstall(package, privateEvidence, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "private remote XN evidence was accepted\n"; + return 2; + } + if (report.message.find("remote XN") == std::string::npos || + report.message.find("private") == std::string::npos) { + std::cerr << "private evidence diagnostic was weak: " << report.message << "\n"; + return 3; + } + + TileXRCcuHardwareInstallEvidence candidateEvidence = VerifiedEvidence(package); + candidateEvidence.channelBindingSource.kind = TileXRCcuEvidenceKind::PublicCandidate; + candidateEvidence.channelBindingSource.source = "rtCcuBindChannel"; + if (TileXRCcuPrepareSubmitTasks(package, candidateEvidence, nullptr, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "null submit vector was not rejected first\n"; + return 4; + } + + std::vector submitTasks; + if (TileXRCcuPrepareSubmitTasks(package, candidateEvidence, &submitTasks, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "public candidate channel binding was accepted\n"; + return 5; + } + if (!submitTasks.empty()) { + std::cerr << "candidate prepare left submit tasks\n"; + return 6; + } + if (report.message.find("channel") == std::string::npos || + report.message.find("candidate") == std::string::npos) { + std::cerr << "candidate diagnostic was weak: " << report.message << "\n"; + return 7; + } + + TileXRCcuHardwareInstallEvidence verified = VerifiedEvidence(package); + if (TileXRCcuPrepareSubmitTasks(package, verified, &submitTasks, &report) != TILEXR_SUCCESS) { + std::cerr << "public verified evidence was rejected: " << report.message << "\n"; + return 8; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_provider_report_counts_evidence_kinds_for_auditing(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_provider.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + TileXRCcuLaunchPackage package; + TileXRCcuLaunchPackageReport packageReport; + if (TileXRCcuBuildLaunchPackage(MakePlan(), &package, &packageReport) != TILEXR_SUCCESS) { + std::cerr << "package build failed\n"; + return 1; + } + + TileXRCcuHardwareInstallEvidence evidence; + evidence.missionInstalled = true; + evidence.repositoryInstalled = true; + evidence.localXnInstalled = true; + evidence.remoteXnBound = true; + evidence.notifyCkeInstalled = true; + evidence.channelBindingsInstalled = false; + evidence.missionSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.repositorySource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.localXnSource.kind = TileXRCcuEvidenceKind::LegacyBoolean; + evidence.remoteXnSource.kind = TileXRCcuEvidenceKind::PrivateObserved; + evidence.notifyCkeSource.kind = TileXRCcuEvidenceKind::PublicCandidate; + evidence.channelBindingSource.kind = TileXRCcuEvidenceKind::Missing; + + TileXRCcuProviderReport report; + if (TileXRCcuValidateHardwareInstall(package, evidence, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "mixed bad evidence was accepted\n"; + return 2; + } + if (report.evidenceBitCount != 6 || + report.publicVerifiedEvidenceCount != 2 || + report.legacyEvidenceCount != 1 || + report.privateObservedEvidenceCount != 1 || + report.publicCandidateEvidenceCount != 1 || + report.missingEvidenceCount != 1) { + std::cerr << "unexpected evidence counters: bits=" << report.evidenceBitCount + << " public=" << report.publicVerifiedEvidenceCount + << " legacy=" << report.legacyEvidenceCount + << " private=" << report.privateObservedEvidenceCount + << " candidate=" << report.publicCandidateEvidenceCount + << " missing=" << report.missingEvidenceCount << "\n"; + return 3; + } + if (report.message.find("remote XN") == std::string::npos || + report.message.find("private") == std::string::npos) { + std::cerr << "first rejection diagnostic was weak: " << report.message << "\n"; + return 4; + } + + evidence.remoteXnSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.remoteXnSource.source = "unit-test-public-provider:remote-xn"; + evidence.remoteXnSource.detail = "audited remote XN evidence"; + evidence.remoteXnSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.remoteXnSource.endpointRouteVerified = true; + evidence.notifyCkeSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.notifyCkeSource.source = "unit-test-public-provider:notify-cke"; + evidence.notifyCkeSource.detail = "audited notify CKE evidence"; + evidence.notifyCkeSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.channelBindingsInstalled = true; + evidence.channelBindingSource.kind = TileXRCcuEvidenceKind::PublicVerified; + evidence.channelBindingSource.source = "unit-test-public-provider:channel-binding"; + evidence.channelBindingSource.detail = "audited channel binding evidence"; + evidence.channelBindingSource.surface = TileXRCcuEvidenceSurface::PublicInstallProvider; + evidence.channelBindingSource.endpointRouteVerified = true; + if (TileXRCcuValidateHardwareInstall(package, evidence, &report) != TILEXR_SUCCESS) { + std::cerr << "fixed evidence was rejected: " << report.message << "\n"; + return 5; + } + if (report.evidenceBitCount != 6 || + report.publicVerifiedEvidenceCount != 5 || + report.legacyEvidenceCount != 1 || + report.privateObservedEvidenceCount != 0 || + report.publicCandidateEvidenceCount != 0 || + report.missingEvidenceCount != 0 || + report.submitReady) { + std::cerr << "unexpected ready evidence counters\n"; + return 6; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_provider_layer_is_wired_and_has_no_private_hcomm_surface(self): + cmake = COMM_CMAKE.read_text(encoding="utf-8") + header = PROVIDER_HEADER.read_text(encoding="utf-8") + source = PROVIDER_SOURCE.read_text(encoding="utf-8") + package_header = PACKAGE_HEADER.read_text(encoding="utf-8") + package_source = PACKAGE_SOURCE.read_text(encoding="utf-8") + + self.assertIn("ccu/tilexr_ccu_provider.h", cmake) + self.assertIn("ccu/tilexr_ccu_provider.cpp", cmake) + self.assertIn("struct TileXRCcuHardwareInstallEvidence", header) + self.assertIn("enum class TileXRCcuEvidenceKind", header) + self.assertIn("enum class TileXRCcuEvidenceSurface", header) + self.assertIn("struct TileXRCcuEvidenceSource", header) + self.assertIn("TileXRCcuValidateHardwareInstall", header) + self.assertIn("TileXRCcuPrepareSubmitTasks", header) + self.assertIn("tilexr_ccu_launch_package.h", header) + self.assertIn("submitReady", header) + self.assertIn("evidenceBitCount", header) + self.assertIn("publicVerifiedEvidenceCount", header) + self.assertIn("publicCandidateEvidenceCount", header) + self.assertIn("privateObservedEvidenceCount", header) + self.assertIn("missingEvidenceCount", header) + self.assertIn("uint64_t packageFingerprint", header) + self.assertIn("uint32_t deviceId", header) + self.assertIn("uint32_t rank", header) + self.assertIn("std::string provider", header) + self.assertIn("uint64_t installAttemptReceiptId", header) + self.assertIn("TileXRCcuComputeLaunchPackageFingerprint", package_header) + self.assertIn("TileXRCcuComputeLaunchPackageFingerprint", package_source) + self.assertIn("package fingerprint mismatch", source) + self.assertIn("TileXRCcuLaunchInstallScope", package_header) + self.assertIn("installScope", package_header) + self.assertIn("TileXRCcuBindLaunchPackageInstallScope", package_header) + self.assertIn("device scope mismatch", source) + self.assertIn("rank scope mismatch", source) + self.assertIn("provider scope mismatch", source) + self.assertIn("install attempt receipt", source) + self.assertIn("endpointRouteVerified", header) + self.assertIn("submit requires verified endpoint route evidence", source) + + combined = header + "\n" + source + for needle in PRIVATE_CCU_PRODUCER_NEEDLES: + with self.subTest(needle=needle): + self.assertNotIn(needle, combined) + + def test_prepare_path_requires_public_verified_evidence_source(self): + source = PROVIDER_SOURCE.read_text(encoding="utf-8") + prepare_start = source.index("int TileXRCcuPrepareSubmitTasks(") + prepare_body = source[prepare_start:] + + validate_pos = prepare_body.index("TileXRCcuValidateHardwareInstall(package, evidence, report)") + submit_gate_pos = prepare_body.index("ValidateSubmitEvidence(package, evidence, report)") + copy_pos = prepare_body.index("*submitTasks = package.tasks") + + self.assertIn("submit requires public verified evidence", source) + self.assertLess(validate_pos, submit_gate_pos) + self.assertLess(submit_gate_pos, copy_pos) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/ccu/test_tilexr_ccu_repository.py b/tests/ccu/test_tilexr_ccu_repository.py new file mode 100644 index 00000000..93b0c2aa --- /dev/null +++ b/tests/ccu/test_tilexr_ccu_repository.py @@ -0,0 +1,1018 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2026 TileXR Project +# + +import shutil +import subprocess +import tempfile +import textwrap +import unittest +import os +import platform +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[2] +REPOSITORY_HEADER = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_repository.h" +REPOSITORY_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_repository.cpp" +DRIVER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_driver_adapter.cpp" +SPECS_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_specs.cpp" +PRODUCER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_producer_plan.cpp" +BARRIER_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_barrier_program.cpp" +MICROCODE_SOURCE = REPO_ROOT / "src" / "comm" / "ccu" / "tilexr_ccu_microcode.cpp" +COMM_CMAKE = REPO_ROOT / "src" / "comm" / "CMakeLists.txt" +INCLUDE_DIR = REPO_ROOT / "src" / "include" +COMM_DIR = REPO_ROOT / "src" / "comm" + + +PRIVATE_CCU_PRODUCER_NEEDLES = [ + "#include + + using namespace TileXR; + + int main() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {0x100051152e00ULL}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + + TileXRCcuProgram program; + TileXRCcuProducerPlanReport planReport; + if (TileXRCcuBuildMicrocode(plan, &program, &planReport) != TILEXR_SUCCESS) { + std::cerr << "microcode build failed: " << planReport.message << "\n"; + return 1; + } + + TileXRCcuRepositoryImage image; + TileXRCcuRepositoryReport report; + if (TileXRCcuBuildRepositoryImage(plan, program, &image, &report) != TILEXR_SUCCESS) { + std::cerr << "repository image build failed: " << report.message << "\n"; + return 2; + } + + if (image.repositoryStartId != 475 || image.repositoryCount != 170 || + image.missionStartId != 489 || image.missionCount != 156 || + image.missionOffset != 14 || image.sqeLoadOffset != 14 || + image.sqeLoadCount != 13 || image.syncOffset != 27 || image.syncCount != 11) { + std::cerr << "unexpected repository metadata\n"; + return 3; + } + if (image.instructions.size() != 170) { + std::cerr << "unexpected repository image size\n"; + return 4; + } + if (image.instructions[14].words[0] != 0x0000000007a90001ULL || + image.instructions[26].words[0] != 0x0000000c07b50001ULL || + image.instructions[27].words[0] != 0x0000000007a90001ULL || + image.instructions[28].words[0] != 0x0000000107aa0001ULL || + image.instructions[29].words[0] != 0x0000000007b60003ULL || + image.instructions[30].words[0] != 0x0000000007b60003ULL || + image.instructions[31].words[0] != 0x0001016c00000802ULL || + image.instructions[31].words[1] != 0 || + image.instructions[32].words[0] != 0x000007a90939100dULL || + image.instructions[32].words[1] != 0x00000001016c0002ULL || + image.instructions[32].words[2] != 0x0001000000000000ULL || + image.instructions[35].words[0] != 0x0000000000010802ULL || + image.instructions[35].words[1] != 0x000000000001016cULL) { + std::cerr << "unexpected installed instructions\n"; + return 5; + } + TileXRCcuInstr expectedNop; + if (TileXRCcuEncodeLoadImdToXn(plan.kernelLocalXn.startId, 0, 0, &expectedNop) != + TILEXR_SUCCESS) { + std::cerr << "failed to encode expected repository padding nop\n"; + return 6; + } + if (image.instructions[13].words[0] != expectedNop.words[0] || + image.instructions[13].words[1] != expectedNop.words[1] || + image.instructions[13].words[2] != expectedNop.words[2] || + image.instructions[13].words[3] != expectedNop.words[3] || + image.instructions[38].words[0] != expectedNop.words[0] || + image.instructions[38].words[1] != expectedNop.words[1] || + image.instructions[38].words[2] != expectedNop.words[2] || + image.instructions[38].words[3] != expectedNop.words[3]) { + std::cerr << "unused repository slots should contain valid nop padding\n"; + return 6; + } + if (report.repositoryCount != 170 || report.installedInstructionCount != 24 || + report.sqeLoadOffset != 14 || report.syncOffset != 27 || report.message != "ok") { + std::cerr << "unexpected repository report\n"; + return 7; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_repository_image_uploads_mission_window_and_installs_via_driver_adapter(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_repository.h" + + #include + #include + #include + + using namespace TileXR; + + struct FakeState { + std::vector deviceBytes; + uint64_t allocBytes = 0; + uint64_t copiedBytes = 0; + bool freed = false; + uint32_t observedOp = 0; + uint32_t observedOffset = 0; + uint32_t observedDataLen = 0; + uint64_t observedResourceAddr = 0; + }; + + int FakeAlloc(uint64_t bytes, void** ptr, void* userData) + { + auto* state = static_cast(userData); + state->allocBytes = bytes; + state->deviceBytes.assign(static_cast(bytes), 0); + *ptr = state->deviceBytes.data(); + return 0; + } + + int FakeCopy(void* dst, uint64_t dstBytes, const void* src, uint64_t bytes, void* userData) + { + auto* state = static_cast(userData); + if (dst != state->deviceBytes.data() || dstBytes != state->deviceBytes.size() || + bytes != state->deviceBytes.size()) { + return -1; + } + std::memcpy(dst, src, static_cast(bytes)); + state->copiedBytes = bytes; + return 0; + } + + int FakeFree(void* ptr, void* userData) + { + auto* state = static_cast(userData); + if (ptr != state->deviceBytes.data()) { + return -1; + } + state->freed = true; + state->deviceBytes.clear(); + return 0; + } + + int FakeCustomChannel( + uint32_t, + const TileXRCcuCustomChannelIn& in, + TileXRCcuCustomChannelOut* out, + void* userData) + { + auto* state = static_cast(userData); + state->observedOp = in.op; + state->observedOffset = in.offsetStartIdx; + state->observedDataLen = in.data.dataInfo.dataLen; + state->observedResourceAddr = in.data.dataInfo.dataArray[0].insinfo.resourceAddr; + out->opRet = 0; + return 0; + } + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {0x100051152e00ULL}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + TileXRCcuProducerPlan plan = MakePlan(); + TileXRCcuProgram program; + TileXRCcuProducerPlanReport planReport; + if (TileXRCcuBuildMicrocode(plan, &program, &planReport) != TILEXR_SUCCESS) { + std::cerr << "microcode build failed: " << planReport.message << "\n"; + return 1; + } + + TileXRCcuRepositoryImage image; + TileXRCcuRepositoryReport report; + if (TileXRCcuBuildRepositoryImage(plan, program, &image, &report) != TILEXR_SUCCESS) { + std::cerr << "repository build failed: " << report.message << "\n"; + return 2; + } + + FakeState state; + TileXRCcuDriverAdapter adapter; + TileXRCcuDriverAdapterReport driverReport; + if (adapter.Init(5, FakeCustomChannel, &state, &driverReport) != TILEXR_SUCCESS) { + std::cerr << "adapter init failed\n"; + return 3; + } + + TileXRCcuDeviceMemoryOps memoryOps; + memoryOps.alloc = FakeAlloc; + memoryOps.copyHostToDevice = FakeCopy; + memoryOps.free = FakeFree; + + TileXRCcuRepositoryInstallReceipt receipt; + if (TileXRCcuInstallRepositoryImage( + image, memoryOps, &state, adapter, &receipt, &report) != TILEXR_SUCCESS) { + std::cerr << "repository install failed: " << report.message << "\n"; + return 4; + } + + const uint64_t expectedBytes = 156ULL * sizeof(TileXRCcuInstr); + if (state.allocBytes != expectedBytes || state.copiedBytes != expectedBytes || + receipt.instructionStartId != 489 || receipt.instructionCount != 156 || + receipt.instructionBytes != expectedBytes || !receipt.uploaded || !receipt.installed) { + std::cerr << "upload receipt mismatch\n"; + return 5; + } + if (state.observedOp != TILEXR_CCU_U_OP_SET_INSTRUCTION || + state.observedOffset != 489 || state.observedDataLen != expectedBytes || + state.observedResourceAddr != receipt.deviceInstructionAddr) { + std::cerr << "install adapter request mismatch\n"; + return 6; + } + + const auto* installed = reinterpret_cast(state.deviceBytes.data()); + if (installed[0].words[0] != image.instructions[image.missionOffset].words[0] || + installed[12].words[0] != image.instructions[image.missionOffset + 12].words[0] || + installed[13].words[0] != image.instructions[image.syncOffset].words[0]) { + std::cerr << "mission-window upload content mismatch\n"; + return 7; + } + if (report.installedInstructionCount != 156 || !report.repositoryInstalled || + report.message != "ok") { + std::cerr << "install report mismatch\n"; + return 8; + } + + if (TileXRCcuReleaseRepositoryInstallReceipt(receipt, memoryOps, &state, &report) != + TILEXR_SUCCESS || !state.freed) { + std::cerr << "release failed: " << report.message << "\n"; + return 9; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_repository_install_options_can_upload_full_repository_with_descriptor_len(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_repository.h" + + #include + #include + #include + + using namespace TileXR; + + struct FakeState { + uint64_t allocBytes = 0; + uint64_t copiedBytes = 0; + std::vector deviceBytes; + uint32_t observedOffset = 0; + uint32_t observedDataLen = 0; + uint64_t observedResourceAddr = 0; + bool freed = false; + }; + + int FakeAlloc(uint64_t bytes, void** ptr, void* userData) + { + auto* state = static_cast(userData); + state->allocBytes = bytes; + state->deviceBytes.assign(static_cast(bytes), 0); + *ptr = state->deviceBytes.data(); + return 0; + } + + int FakeCopy(void* dst, uint64_t dstBytes, const void* src, uint64_t bytes, void* userData) + { + auto* state = static_cast(userData); + if (dst != state->deviceBytes.data() || dstBytes != state->deviceBytes.size()) { + return -1; + } + state->copiedBytes = bytes; + std::memcpy(dst, src, static_cast(bytes)); + return 0; + } + + int FakeFree(void* ptr, void* userData) + { + auto* state = static_cast(userData); + if (ptr != state->deviceBytes.data()) { + return -1; + } + state->freed = true; + state->deviceBytes.clear(); + return 0; + } + + int FakeCustomChannel( + uint32_t, + const TileXRCcuCustomChannelIn& in, + TileXRCcuCustomChannelOut* out, + void* userData) + { + auto* state = static_cast(userData); + state->observedOffset = in.offsetStartIdx; + state->observedDataLen = in.data.dataInfo.dataLen; + state->observedResourceAddr = in.data.dataInfo.dataArray[0].insinfo.resourceAddr; + out->opRet = 0; + return 0; + } + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {0x100051152e00ULL}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + TileXRCcuProducerPlan plan = MakePlan(); + TileXRCcuProgram program; + TileXRCcuProducerPlanReport planReport; + if (TileXRCcuBuildMicrocode(plan, &program, &planReport) != TILEXR_SUCCESS) { + std::cerr << "microcode build failed: " << planReport.message << "\n"; + return 1; + } + + TileXRCcuRepositoryImage image; + TileXRCcuRepositoryReport report; + if (TileXRCcuBuildRepositoryImage(plan, program, &image, &report) != TILEXR_SUCCESS) { + std::cerr << "repository build failed: " << report.message << "\n"; + return 2; + } + + FakeState state; + TileXRCcuDriverAdapter adapter; + TileXRCcuDriverAdapterReport driverReport; + if (adapter.Init(5, FakeCustomChannel, &state, &driverReport) != TILEXR_SUCCESS) { + std::cerr << "adapter init failed\n"; + return 3; + } + + TileXRCcuRepositoryInstallOptions options; + options.window = TileXRCcuRepositoryInstallWindow::FullRepository; + options.dataLenMode = TileXRCcuRepositoryInstallDataLenMode::DescriptorBytes; + + TileXRCcuDeviceMemoryOps memoryOps = {FakeAlloc, FakeCopy, FakeFree}; + TileXRCcuRepositoryInstallReceipt receipt; + if (TileXRCcuInstallRepositoryImageWithOptions( + image, options, memoryOps, &state, adapter, &receipt, &report) != TILEXR_SUCCESS) { + std::cerr << "repository install failed: " << report.message << "\n"; + return 4; + } + + const uint64_t expectedBytes = 170ULL * sizeof(TileXRCcuInstr); + if (state.allocBytes != expectedBytes || state.copiedBytes != expectedBytes || + receipt.instructionStartId != 475 || receipt.instructionCount != 170 || + receipt.instructionBytes != expectedBytes || !receipt.uploaded || !receipt.installed) { + std::cerr << "full repository receipt mismatch\n"; + return 5; + } + if (state.observedOffset != 475 || + state.observedDataLen != sizeof(TileXRCcuInstrInfo) || + state.observedResourceAddr != receipt.deviceInstructionAddr) { + std::cerr << "full repository SET_INSTRUCTION envelope mismatch\n"; + return 6; + } + const auto* installed = reinterpret_cast(state.deviceBytes.data()); + if (installed[0].words[0] != image.instructions[0].words[0] || + installed[14].words[0] != image.instructions[image.missionOffset].words[0]) { + std::cerr << "full repository upload content mismatch\n"; + return 7; + } + if (report.installedInstructionCount != 170 || + report.message.find("window=full_repository") == std::string::npos || + report.message.find("dataLenMode=descriptor_bytes") == std::string::npos) { + std::cerr << "install report missing option detail: " << report.message << "\n"; + return 8; + } + if (TileXRCcuReleaseRepositoryInstallReceipt(receipt, memoryOps, &state, &report) != + TILEXR_SUCCESS || !state.freed) { + std::cerr << "release failed: " << report.message << "\n"; + return 9; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_repository_install_failure_reports_full_set_instruction_context(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_repository.h" + + #include + #include + #include + #include + + using namespace TileXR; + + struct FakeState { + std::vector deviceBytes; + uint64_t readbackBytes = 0; + uint64_t driverReadbackBytes = 0; + bool freed = false; + }; + + int FakeAlloc(uint64_t bytes, void** ptr, void* userData) + { + auto* state = static_cast(userData); + state->deviceBytes.assign(static_cast(bytes), 0); + *ptr = state->deviceBytes.data(); + return 0; + } + + int FakeCopy(void* dst, uint64_t dstBytes, const void* src, uint64_t bytes, void* userData) + { + auto* state = static_cast(userData); + if (dst != state->deviceBytes.data() || dstBytes != state->deviceBytes.size() || + bytes != dstBytes) { + return -1; + } + std::memcpy(dst, src, static_cast(bytes)); + return 0; + } + + int FakeCopyDeviceToHost(void* dst, uint64_t dstBytes, const void* src, uint64_t bytes, void* userData) + { + auto* state = static_cast(userData); + if (src != state->deviceBytes.data() || dstBytes < bytes || + bytes != state->deviceBytes.size()) { + return -1; + } + std::memcpy(dst, src, static_cast(bytes)); + state->readbackBytes = bytes; + return 0; + } + + int FakeFree(void* ptr, void* userData) + { + auto* state = static_cast(userData); + if (ptr != state->deviceBytes.data()) { + return -1; + } + state->freed = true; + state->deviceBytes.clear(); + return 0; + } + + int FakeCustomChannel( + uint32_t, + const TileXRCcuCustomChannelIn& in, + TileXRCcuCustomChannelOut* out, + void* userData) + { + out->opRet = 0; + if (in.op == TILEXR_CCU_U_OP_SET_INSTRUCTION) { + return 328107; + } + if (in.op != TILEXR_CCU_U_OP_GET_INSTRUCTION) { + return -1; + } + auto* state = static_cast(userData); + constexpr uint32_t kBaseInstruction = 475; + const uint32_t count = in.data.dataInfo.dataArraySize; + if (count == 0 || count > TILEXR_CCU_MAX_DATA_ARRAY_SIZE || + in.offsetStartIdx < kBaseInstruction || + in.data.dataInfo.dataLen != count * TILEXR_CCU_INSTRUCTION_BYTES) { + return -2; + } + const uint64_t byteOffset = + static_cast(in.offsetStartIdx - kBaseInstruction) * + TILEXR_CCU_INSTRUCTION_BYTES; + const uint64_t bytes = static_cast(count) * TILEXR_CCU_INSTRUCTION_BYTES; + if (byteOffset + bytes > state->deviceBytes.size()) { + return -3; + } + for (uint32_t i = 0; i < count; ++i) { + std::memcpy( + out->data.dataInfo.dataArray[i].byte32.raw, + state->deviceBytes.data() + byteOffset + + static_cast(i) * TILEXR_CCU_INSTRUCTION_BYTES, + TILEXR_CCU_INSTRUCTION_BYTES); + } + out->data.dataInfo.dataArraySize = count; + out->data.dataInfo.dataLen = static_cast(bytes); + out->offsetNextIdx = in.offsetStartIdx + count; + state->driverReadbackBytes += bytes; + return 0; + } + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {0x100051152e00ULL}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + bool Has(const std::string& haystack, const std::string& needle) + { + return haystack.find(needle) != std::string::npos; + } + + int main() + { + TileXRCcuProducerPlan plan = MakePlan(); + TileXRCcuProgram program; + TileXRCcuProducerPlanReport planReport; + if (TileXRCcuBuildMicrocode(plan, &program, &planReport) != TILEXR_SUCCESS) { + std::cerr << "microcode build failed: " << planReport.message << "\n"; + return 1; + } + + TileXRCcuRepositoryImage image; + TileXRCcuRepositoryReport report; + if (TileXRCcuBuildRepositoryImage(plan, program, &image, &report) != TILEXR_SUCCESS) { + std::cerr << "repository build failed: " << report.message << "\n"; + return 2; + } + + FakeState state; + TileXRCcuDriverAdapter adapter; + TileXRCcuDriverAdapterReport driverReport; + if (adapter.Init(5, FakeCustomChannel, &state, &driverReport) != TILEXR_SUCCESS) { + std::cerr << "adapter init failed\n"; + return 3; + } + + TileXRCcuRepositoryInstallOptions options; + options.window = TileXRCcuRepositoryInstallWindow::FullRepository; + options.dataLenMode = TileXRCcuRepositoryInstallDataLenMode::InstructionBytes; + + TileXRCcuDeviceMemoryOps memoryOps; + memoryOps.alloc = FakeAlloc; + memoryOps.copyHostToDevice = FakeCopy; + memoryOps.free = FakeFree; + memoryOps.copyDeviceToHost = FakeCopyDeviceToHost; + TileXRCcuRepositoryInstallReceipt receipt; + const int ret = TileXRCcuInstallRepositoryImageWithOptions( + image, options, memoryOps, &state, adapter, &receipt, &report); + if (ret != TILEXR_ERROR_MKIRT || !state.freed || receipt.deviceInstructionPtr != nullptr || + state.readbackBytes != 5440ULL || state.driverReadbackBytes != 5440ULL) { + std::cerr << "install failure handling mismatch ret=" << ret + << " freed=" << state.freed + << " readbackBytes=" << state.readbackBytes + << " driverReadbackBytes=" << state.driverReadbackBytes << "\n"; + return 4; + } + + const std::string msg = report.message; + for (const char* needle : { + "failed to install CCU repository instruction image", + "CCU custom channel call failed op=251 driverRet=328107 opRet=0", + "dieId=1", + "installStartId=475", + "installCount=170", + "instructionBytes=5440", + "customChannelDataLen=5440", + "deviceInstructionAddr=0x", + "window=full_repository", + "dataLenMode=instruction_bytes", + "firstInstructionWords=", + "lastInstructionWords=", + "instructionFnv1a64=0x", + "uploadReadback=ok", + "uploadReadbackBytes=5440", + "uploadReadbackFnv1a64=0x", + "uploadReadbackFirstInstructionWords=", + "uploadReadbackLastInstructionWords=", + "uploadReadbackMismatchCount=0", + "driverReadback=ok", + "driverReadbackRet=0", + "driverReadbackBytes=5440", + "driverReadbackFnv1a64=0x", + "driverReadbackFirstInstructionWords=", + "driverReadbackLastInstructionWords=", + "driverReadbackMismatchCount=0"}) { + if (!Has(msg, needle)) { + std::cerr << "missing diagnostic field '" << needle << "' in: " << msg << "\n"; + return 5; + } + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_repository_image_places_pure_barrier_sync_microcode_without_sqe_load(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_repository.h" + + #include + + using namespace TileXR; + + int main() + { + TileXRCcuProducerPlan plan; + plan.mission = {0, 1, 0x12345678U, true}; + plan.kernelLocalXn = {0, 1, 1}; + plan.kernelLocalCke = {0, 1, 1}; + plan.kernelLocalMission = {0, 1, 1}; + plan.instructionWindow = {0, 1, 2, 1, 2}; + plan.syncResources.push_back({0, 1, 2, 1, 1, 1, 1, 1, 1}); + plan.taskWindows.push_back({0, 1, 2, 13, {}}); + + TileXRCcuProgram program; + TileXRCcuProducerPlanReport planReport; + if (TileXRCcuBuildMicrocode(plan, &program, &planReport) != TILEXR_SUCCESS) { + std::cerr << "microcode build failed: " << planReport.message << "\n"; + return 1; + } + if (!program.sqeLoad.empty() || program.sync.size() != 2) { + std::cerr << "pure barrier microcode size mismatch\n"; + return 2; + } + + TileXRCcuRepositoryImage image; + TileXRCcuRepositoryReport report; + if (TileXRCcuBuildRepositoryImage(plan, program, &image, &report) != TILEXR_SUCCESS) { + std::cerr << "repository image build failed: " << report.message << "\n"; + return 3; + } + if (image.repositoryStartId != 1 || image.repositoryCount != 2 || + image.missionStartId != 1 || image.missionCount != 2 || + image.missionOffset != 0 || image.sqeLoadCount != 0 || + image.syncOffset != 0 || image.syncCount != 2 || + image.instructions.size() != 2) { + std::cerr << "pure barrier repository metadata mismatch\n"; + return 4; + } + if (image.instructions[0].words[0] == 0 || + image.instructions[1].words[0] == 0 || + report.installedInstructionCount != 2 || + report.sqeLoadOffset != 0 || report.syncOffset != 0) { + std::cerr << "pure barrier repository content/report mismatch\n"; + return 5; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_repository_image_rejects_inconsistent_windows(self): + code = textwrap.dedent( + r''' + #include "ccu/tilexr_ccu_repository.h" + + #include + + using namespace TileXR; + + TileXRCcuProducerPlan MakePlan() + { + TileXRCcuProducerPlan plan; + plan.mission = {1, 6, 0x059b0f03U, true}; + plan.kernelLocalXn = {1, 1961, 62}; + plan.kernelLocalCke = {1, 332, 1}; + plan.kernelLocalMission = {1, 6, 1}; + plan.instructionWindow = {1, 475, 170, 489, 156}; + plan.syncResources.push_back({1, 1961, 2361, 364, 2, 3}); + plan.syncResources.push_back({1, 1962, 2362, 364, 3, 3}); + plan.syncResources.push_back({1, 1963, 2364, 364, 4, 3}); + plan.taskWindows.push_back({1, 489, 13, 13, {}}); + plan.taskWindows.push_back({1, 502, 143, 13, {}}); + return plan; + } + + int main() + { + TileXRCcuProducerPlan plan = MakePlan(); + TileXRCcuProgram program; + TileXRCcuProducerPlanReport planReport; + if (TileXRCcuBuildMicrocode(plan, &program, &planReport) != TILEXR_SUCCESS) { + std::cerr << "microcode build failed\n"; + return 1; + } + + TileXRCcuRepositoryImage image; + TileXRCcuRepositoryReport report; + + TileXRCcuProducerPlan smallRepo = plan; + smallRepo.instructionWindow.repositoryCount = 15; + if (TileXRCcuBuildRepositoryImage(smallRepo, program, &image, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "small repository was accepted\n"; + return 2; + } + if (report.message.find("repository") == std::string::npos) { + std::cerr << "small repository diagnostic was weak: " << report.message << "\n"; + return 3; + } + + TileXRCcuProducerPlan shortSqeTask = plan; + shortSqeTask.taskWindows[0].instCnt = 12; + if (TileXRCcuBuildRepositoryImage(shortSqeTask, program, &image, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "short SQE task window was accepted\n"; + return 4; + } + if (report.message.find("SQE") == std::string::npos) { + std::cerr << "short SQE task diagnostic was weak: " << report.message << "\n"; + return 5; + } + + TileXRCcuProducerPlan shiftedSyncTask = plan; + shiftedSyncTask.taskWindows[1].instStartId = 501; + if (TileXRCcuBuildRepositoryImage(shiftedSyncTask, program, &image, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "misaligned sync task window was accepted\n"; + return 6; + } + if (report.message.find("sync") == std::string::npos) { + std::cerr << "misaligned sync diagnostic was weak: " << report.message << "\n"; + return 7; + } + + if (TileXRCcuBuildRepositoryImage(plan, program, nullptr, &report) != + TILEXR_ERROR_PARA_CHECK_FAIL) { + std::cerr << "null output image was accepted\n"; + return 8; + } + return 0; + } + ''' + ) + + result = self.compile_and_run(code) + + self.assertEqual("", result.stderr) + self.assertEqual(0, result.returncode, result.stdout + result.stderr) + + def test_repository_layer_is_wired_and_has_no_private_hcomm_surface(self): + cmake = COMM_CMAKE.read_text(encoding="utf-8") + header = REPOSITORY_HEADER.read_text(encoding="utf-8") + source = REPOSITORY_SOURCE.read_text(encoding="utf-8") + + self.assertIn("ccu/tilexr_ccu_repository.h", cmake) + self.assertIn("ccu/tilexr_ccu_repository.cpp", cmake) + self.assertIn("struct TileXRCcuRepositoryImage", header) + self.assertIn("struct TileXRCcuRepositoryReport", header) + self.assertIn("struct TileXRCcuDeviceMemoryOps", header) + self.assertIn("TileXRCcuCopyDeviceToHostFn", header) + self.assertIn("copyDeviceToHost", header) + self.assertIn("struct TileXRCcuRepositoryInstallReceipt", header) + self.assertIn("enum class TileXRCcuRepositoryMemoryAllocMode", header) + self.assertIn("TileXRCcuMakeAclModule3DeviceMemoryOps", header) + self.assertIn("RtHbm", header) + self.assertIn("TileXRCcuMakeRtHbmDeviceMemoryOps", header) + self.assertIn("TileXRCcuMakeRepositoryDeviceMemoryOps", header) + self.assertIn("TileXRCcuRepositoryInstallOptions", header) + self.assertIn("TileXRCcuBuildRepositoryImage", header) + self.assertIn("TileXRCcuInstallRepositoryImageWithOptions", header) + self.assertIn("TileXRCcuInstallRepositoryImage", header) + self.assertIn("TileXRCcuReleaseRepositoryInstallReceipt", header) + self.assertIn("TileXRCcuMakeAclDeviceMemoryOps", header) + self.assertIn("tilexr_ccu_producer_plan.h", header) + self.assertIn("missionOffset", header) + self.assertIn("sqeLoadOffset", header) + self.assertIn("syncOffset", header) + self.assertIn("#include ", source) + self.assertIn("#include ", source) + self.assertIn("aclrtMalloc", source) + self.assertIn("ACL_MEM_MALLOC_HUGE_FIRST", source) + self.assertIn("aclrtMallocWithCfg", source) + self.assertIn("ACL_RT_MEM_ATTR_MODULE_ID", source) + self.assertIn("ACL_MEM_TYPE_HIGH_BAND_WIDTH", source) + self.assertIn("TILEXR_CCU_ACL_MODULE3_ID", source) + self.assertIn("aclrtMemcpy", source) + self.assertIn("ACL_MEMCPY_HOST_TO_DEVICE", source) + self.assertIn("ACL_MEMCPY_DEVICE_TO_HOST", source) + self.assertIn("aclrtFree", source) + self.assertIn("rtMalloc", source) + self.assertIn("RT_MEMORY_HBM", source) + self.assertIn("rtMemcpy", source) + self.assertIn("RT_MEMCPY_HOST_TO_DEVICE", source) + self.assertIn("RT_MEMCPY_DEVICE_TO_HOST", source) + self.assertIn("rtFree", source) + self.assertIn("TileXRCcuMakeAclDeviceMemoryOps", source) + self.assertIn("TileXRCcuMakeAclModule3DeviceMemoryOps", source) + self.assertIn("TileXRCcuMakeRtHbmDeviceMemoryOps", source) + self.assertIn("TileXRCcuMakeRepositoryDeviceMemoryOps", source) + + combined = header + "\n" + source + for needle in PRIVATE_CCU_PRODUCER_NEEDLES: + with self.subTest(needle=needle): + self.assertNotIn(needle, combined) + + def test_repository_install_failure_diagnostic_source_contract(self): + source = REPOSITORY_SOURCE.read_text(encoding="utf-8") + + for needle in [ + "BuildInstallFailureDiagnostic", + "dieId=", + "installStartId=", + "installCount=", + "instructionBytes=", + "customChannelDataLen=", + "deviceInstructionAddr=0x", + "window=", + "dataLenMode=", + "firstInstructionWords=", + "lastInstructionWords=", + "instructionFnv1a64=0x", + "uploadReadback=", + "uploadReadbackBytes=", + "uploadReadbackFnv1a64=0x", + "uploadReadbackFirstInstructionWords=", + "uploadReadbackLastInstructionWords=", + "uploadReadbackMismatchCount=", + "driverReadback=", + "driverReadbackRet=", + "driverReadbackBytes=", + "driverReadbackFnv1a64=0x", + "driverReadbackFirstInstructionWords=", + "driverReadbackLastInstructionWords=", + "driverReadbackMismatchCount=", + ]: + with self.subTest(needle=needle): + self.assertIn(needle, source) + + +if __name__ == "__main__": + unittest.main()