2019-10-28 02:48:26 +08:00
/*
2023-12-12 22:49:00 +08:00
* Copyright ( C ) 2020 - 2023 Intel Corporation
2019-10-28 02:48:26 +08:00
*
* SPDX - License - Identifier : MIT
*
*/
2020-02-24 05:44:01 +08:00
# include "shared/source/device_binary_format/patchtokens_validator.h"
2019-10-28 02:48:26 +08:00
2020-02-24 05:44:01 +08:00
# include "shared/source/device_binary_format/patchtokens_decoder.h"
# include "shared/source/helpers/hw_info.h"
2021-04-08 17:05:45 +08:00
# include "shared/source/kernel/kernel_arg_descriptor.h"
2019-10-28 02:48:26 +08:00
# include "igfxfmid.h"
# include <string>
namespace NEO {
namespace PatchTokenBinary {
2020-01-26 02:18:48 +08:00
bool allowUnhandledTokens = true ;
2019-10-28 02:48:26 +08:00
2020-01-26 02:18:48 +08:00
DecodeError validate ( const ProgramFromPatchtokens & decodedProgram ,
std : : string & outErrReason , std : : string & outWarnings ) {
2023-12-12 22:49:00 +08:00
if ( decodedProgram . decodeStatus ! = DecodeError : : success ) {
2019-10-28 02:48:26 +08:00
outErrReason = " ProgramFromPatchtokens wasn't successfully decoded " ;
2023-12-12 22:49:00 +08:00
return DecodeError : : invalidBinary ;
2019-10-28 02:48:26 +08:00
}
if ( decodedProgram . programScopeTokens . allocateConstantMemorySurface . size ( ) > 1 ) {
outErrReason = " Unhandled number of global constants surfaces > 1 " ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2019-10-28 02:48:26 +08:00
}
if ( decodedProgram . programScopeTokens . allocateGlobalMemorySurface . size ( ) > 1 ) {
outErrReason = " Unhandled number of global variables surfaces > 1 " ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2019-10-28 02:48:26 +08:00
}
for ( const auto & globalConstantPointerToken : decodedProgram . programScopeTokens . constantPointer ) {
bool isUnhandled = ( globalConstantPointerToken - > ConstantBufferIndex ! = 0 ) ;
isUnhandled | = ( globalConstantPointerToken - > BufferIndex ! = 0 ) ;
2020-01-05 01:56:34 +08:00
isUnhandled | = ( globalConstantPointerToken - > BufferType ! = PROGRAM_SCOPE_CONSTANT_BUFFER ) & & ( globalConstantPointerToken - > BufferType ! = PROGRAM_SCOPE_GLOBAL_BUFFER ) ;
isUnhandled | = ( globalConstantPointerToken - > BufferType = = PROGRAM_SCOPE_GLOBAL_BUFFER ) & & ( decodedProgram . programScopeTokens . allocateGlobalMemorySurface . empty ( ) ) ;
isUnhandled | = ( decodedProgram . programScopeTokens . allocateConstantMemorySurface . empty ( ) ) | | decodedProgram . programScopeTokens . allocateConstantMemorySurface [ 0 ] - > InlineDataSize < globalConstantPointerToken - > ConstantPointerOffset + sizeof ( uint32_t ) ;
2019-10-28 02:48:26 +08:00
if ( isUnhandled ) {
outErrReason = " Unhandled SPatchConstantPointerProgramBinaryInfo " ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2019-10-28 02:48:26 +08:00
}
}
for ( const auto & globalVariablePointerToken : decodedProgram . programScopeTokens . globalPointer ) {
bool isUnhandled = ( globalVariablePointerToken - > GlobalBufferIndex ! = 0 ) ;
isUnhandled | = ( globalVariablePointerToken - > BufferIndex ! = 0 ) ;
2020-01-05 01:56:34 +08:00
isUnhandled | = ( globalVariablePointerToken - > BufferType ! = PROGRAM_SCOPE_GLOBAL_BUFFER ) & & ( globalVariablePointerToken - > BufferType ! = PROGRAM_SCOPE_CONSTANT_BUFFER ) ;
isUnhandled | = ( globalVariablePointerToken - > BufferType = = PROGRAM_SCOPE_CONSTANT_BUFFER ) & & ( decodedProgram . programScopeTokens . allocateConstantMemorySurface . empty ( ) ) ;
isUnhandled | = ( decodedProgram . programScopeTokens . allocateGlobalMemorySurface . empty ( ) ) | | decodedProgram . programScopeTokens . allocateGlobalMemorySurface [ 0 ] - > InlineDataSize < globalVariablePointerToken - > GlobalPointerOffset + sizeof ( uint32_t ) ;
2019-10-28 02:48:26 +08:00
if ( isUnhandled ) {
outErrReason = " Unhandled SPatchGlobalPointerProgramBinaryInfo " ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2019-10-28 02:48:26 +08:00
}
}
for ( const auto & unhandledToken : decodedProgram . unhandledTokens ) {
2020-01-26 02:18:48 +08:00
if ( allowUnhandledTokens ) {
2019-10-28 02:48:26 +08:00
outWarnings = " Unknown program-scope Patch Token : " + std : : to_string ( unhandledToken - > Token ) ;
2020-01-26 02:18:48 +08:00
} else {
outErrReason = " Unhandled required program-scope Patch Token : " + std : : to_string ( unhandledToken - > Token ) ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2019-10-28 02:48:26 +08:00
}
}
UNRECOVERABLE_IF ( nullptr = = decodedProgram . header ) ;
if ( decodedProgram . header - > Version ! = CURRENT_ICBE_VERSION ) {
outErrReason = " Unhandled Version of Patchtokens: expected: " + std : : to_string ( CURRENT_ICBE_VERSION ) + " , got: " + std : : to_string ( decodedProgram . header - > Version ) ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2019-10-28 02:48:26 +08:00
}
2020-01-12 01:25:26 +08:00
if ( ( decodedProgram . header - > GPUPointerSizeInBytes ! = 4U ) & & ( decodedProgram . header - > GPUPointerSizeInBytes ! = 8U ) ) {
outErrReason = " Invalid pointer size " ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2019-10-28 02:48:26 +08:00
}
for ( const auto & decodedKernel : decodedProgram . kernels ) {
2023-12-12 22:49:00 +08:00
if ( decodedKernel . decodeStatus ! = DecodeError : : success ) {
2019-10-28 02:48:26 +08:00
outErrReason = " KernelFromPatchtokens wasn't successfully decoded " ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2019-10-28 02:48:26 +08:00
}
UNRECOVERABLE_IF ( nullptr = = decodedKernel . header ) ;
if ( hasInvalidChecksum ( decodedKernel ) ) {
outErrReason = " KernelFromPatchtokens has invalid checksum " ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2019-10-28 02:48:26 +08:00
}
2020-01-12 01:25:26 +08:00
if ( nullptr = = decodedKernel . tokens . executionEnvironment ) {
outErrReason = " Missing execution environment " ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2020-01-12 01:25:26 +08:00
} else {
switch ( decodedKernel . tokens . executionEnvironment - > LargestCompiledSIMDSize ) {
case 1 :
break ;
case 8 :
break ;
case 16 :
break ;
case 32 :
break ;
default :
outErrReason = " Invalid LargestCompiledSIMDSize " ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2019-10-28 02:48:26 +08:00
}
}
2020-01-12 01:25:26 +08:00
for ( auto & kernelArg : decodedKernel . tokens . kernelArgs ) {
if ( kernelArg . argInfo = = nullptr ) {
2020-01-29 23:52:27 +08:00
continue ;
2020-01-12 01:25:26 +08:00
}
auto argInfoInlineData = getInlineData ( kernelArg . argInfo ) ;
auto accessQualifier = KernelArgMetadata : : parseAccessQualifier ( parseLimitedString ( argInfoInlineData . accessQualifier . begin ( ) , argInfoInlineData . accessQualifier . size ( ) ) ) ;
2020-02-25 05:07:46 +08:00
if ( KernelArgMetadata : : AccessUnknown = = accessQualifier ) {
2020-01-12 01:25:26 +08:00
outErrReason = " Unhandled access qualifier " ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2020-01-12 01:25:26 +08:00
}
auto addressQualifier = KernelArgMetadata : : parseAddressSpace ( parseLimitedString ( argInfoInlineData . addressQualifier . begin ( ) , argInfoInlineData . addressQualifier . size ( ) ) ) ;
2020-02-25 05:07:46 +08:00
if ( KernelArgMetadata : : AddrUnknown = = addressQualifier ) {
2020-01-12 01:25:26 +08:00
outErrReason = " Unhandled address qualifier " ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2020-01-12 01:25:26 +08:00
}
}
2019-10-28 02:48:26 +08:00
for ( const auto & unhandledToken : decodedKernel . unhandledTokens ) {
2020-01-26 02:18:48 +08:00
if ( allowUnhandledTokens ) {
2019-10-28 02:48:26 +08:00
outWarnings = " Unknown kernel-scope Patch Token : " + std : : to_string ( unhandledToken - > Token ) ;
2020-01-26 02:18:48 +08:00
} else {
outErrReason = " Unhandled required kernel-scope Patch Token : " + std : : to_string ( unhandledToken - > Token ) ;
2023-12-12 22:49:00 +08:00
return DecodeError : : unhandledBinary ;
2019-10-28 02:48:26 +08:00
}
}
}
2023-12-12 22:49:00 +08:00
return DecodeError : : success ;
2019-10-28 02:48:26 +08:00
}
} // namespace PatchTokenBinary
} // namespace NEO