1/* 2 * Copyright 2016 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23#ifndef _VEGA10_PPTABLE_H_ 24#define _VEGA10_PPTABLE_H_ 25 26#pragma pack(push, 1) 27 28#define ATOM_VEGA10_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK 0x0f 29#define ATOM_VEGA10_PP_FANPARAMETERS_NOFAN 0x80 30 31#define ATOM_VEGA10_PP_THERMALCONTROLLER_NONE 0 32#define ATOM_VEGA10_PP_THERMALCONTROLLER_LM96163 17 33#define ATOM_VEGA10_PP_THERMALCONTROLLER_VEGA10 24 34 35#define ATOM_VEGA10_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL 0x89 36#define ATOM_VEGA10_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL 0x8D 37 38#define ATOM_VEGA10_PP_PLATFORM_CAP_POWERPLAY 0x1 39#define ATOM_VEGA10_PP_PLATFORM_CAP_SBIOSPOWERSOURCE 0x2 40#define ATOM_VEGA10_PP_PLATFORM_CAP_HARDWAREDC 0x4 41#define ATOM_VEGA10_PP_PLATFORM_CAP_BACO 0x8 42#define ATOM_VEGA10_PP_PLATFORM_COMBINE_PCC_WITH_THERMAL_SIGNAL 0x10 43 44 45/* ATOM_PPLIB_NONCLOCK_INFO::usClassification */ 46#define ATOM_PPLIB_CLASSIFICATION_UI_MASK 0x0007 47#define ATOM_PPLIB_CLASSIFICATION_UI_SHIFT 0 48#define ATOM_PPLIB_CLASSIFICATION_UI_NONE 0 49#define ATOM_PPLIB_CLASSIFICATION_UI_BATTERY 1 50#define ATOM_PPLIB_CLASSIFICATION_UI_BALANCED 3 51#define ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE 5 52/* 2, 4, 6, 7 are reserved */ 53 54#define ATOM_PPLIB_CLASSIFICATION_BOOT 0x0008 55#define ATOM_PPLIB_CLASSIFICATION_THERMAL 0x0010 56#define ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE 0x0020 57#define ATOM_PPLIB_CLASSIFICATION_REST 0x0040 58#define ATOM_PPLIB_CLASSIFICATION_FORCED 0x0080 59#define ATOM_PPLIB_CLASSIFICATION_ACPI 0x1000 60 61/* ATOM_PPLIB_NONCLOCK_INFO::usClassification2 */ 62#define ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2 0x0001 63 64#define ATOM_Vega10_DISALLOW_ON_DC 0x00004000 65#define ATOM_Vega10_ENABLE_VARIBRIGHT 0x00008000 66 67#define ATOM_Vega10_TABLE_REVISION_VEGA10 8 68 69#define ATOM_Vega10_VoltageMode_AVFS_Interpolate 0 70#define ATOM_Vega10_VoltageMode_AVFS_WorstCase 1 71#define ATOM_Vega10_VoltageMode_Static 2 72 73typedef struct _ATOM_Vega10_POWERPLAYTABLE { 74 struct atom_common_table_header sHeader; 75 UCHAR ucTableRevision; 76 USHORT usTableSize; /* the size of header structure */ 77 ULONG ulGoldenPPID; /* PPGen use only */ 78 ULONG ulGoldenRevision; /* PPGen use only */ 79 USHORT usFormatID; /* PPGen use only */ 80 ULONG ulPlatformCaps; /* See ATOM_Vega10_CAPS_* */ 81 ULONG ulMaxODEngineClock; /* For Overdrive. */ 82 ULONG ulMaxODMemoryClock; /* For Overdrive. */ 83 USHORT usPowerControlLimit; 84 USHORT usUlvVoltageOffset; /* in mv units */ 85 USHORT usUlvSmnclkDid; 86 USHORT usUlvMp1clkDid; 87 USHORT usUlvGfxclkBypass; 88 USHORT usGfxclkSlewRate; 89 UCHAR ucGfxVoltageMode; 90 UCHAR ucSocVoltageMode; 91 UCHAR ucUclkVoltageMode; 92 UCHAR ucUvdVoltageMode; 93 UCHAR ucVceVoltageMode; 94 UCHAR ucMp0VoltageMode; 95 UCHAR ucDcefVoltageMode; 96 USHORT usStateArrayOffset; /* points to ATOM_Vega10_State_Array */ 97 USHORT usFanTableOffset; /* points to ATOM_Vega10_Fan_Table */ 98 USHORT usThermalControllerOffset; /* points to ATOM_Vega10_Thermal_Controller */ 99 USHORT usSocclkDependencyTableOffset; /* points to ATOM_Vega10_SOCCLK_Dependency_Table */ 100 USHORT usMclkDependencyTableOffset; /* points to ATOM_Vega10_MCLK_Dependency_Table */ 101 USHORT usGfxclkDependencyTableOffset; /* points to ATOM_Vega10_GFXCLK_Dependency_Table */ 102 USHORT usDcefclkDependencyTableOffset; /* points to ATOM_Vega10_DCEFCLK_Dependency_Table */ 103 USHORT usVddcLookupTableOffset; /* points to ATOM_Vega10_Voltage_Lookup_Table */ 104 USHORT usVddmemLookupTableOffset; /* points to ATOM_Vega10_Voltage_Lookup_Table */ 105 USHORT usMMDependencyTableOffset; /* points to ATOM_Vega10_MM_Dependency_Table */ 106 USHORT usVCEStateTableOffset; /* points to ATOM_Vega10_VCE_State_Table */ 107 USHORT usReserve; /* No PPM Support for Vega10 */ 108 USHORT usPowerTuneTableOffset; /* points to ATOM_Vega10_PowerTune_Table */ 109 USHORT usHardLimitTableOffset; /* points to ATOM_Vega10_Hard_Limit_Table */ 110 USHORT usVddciLookupTableOffset; /* points to ATOM_Vega10_Voltage_Lookup_Table */ 111 USHORT usPCIETableOffset; /* points to ATOM_Vega10_PCIE_Table */ 112 USHORT usPixclkDependencyTableOffset; /* points to ATOM_Vega10_PIXCLK_Dependency_Table */ 113 USHORT usDispClkDependencyTableOffset; /* points to ATOM_Vega10_DISPCLK_Dependency_Table */ 114 USHORT usPhyClkDependencyTableOffset; /* points to ATOM_Vega10_PHYCLK_Dependency_Table */ 115} ATOM_Vega10_POWERPLAYTABLE; 116 117typedef struct _ATOM_Vega10_State { 118 UCHAR ucSocClockIndexHigh; 119 UCHAR ucSocClockIndexLow; 120 UCHAR ucGfxClockIndexHigh; 121 UCHAR ucGfxClockIndexLow; 122 UCHAR ucMemClockIndexHigh; 123 UCHAR ucMemClockIndexLow; 124 USHORT usClassification; 125 ULONG ulCapsAndSettings; 126 USHORT usClassification2; 127} ATOM_Vega10_State; 128 129typedef struct _ATOM_Vega10_State_Array { 130 UCHAR ucRevId; 131 UCHAR ucNumEntries; /* Number of entries. */ 132 ATOM_Vega10_State states[1]; /* Dynamically allocate entries. */ 133} ATOM_Vega10_State_Array; 134 135typedef struct _ATOM_Vega10_CLK_Dependency_Record { 136 ULONG ulClk; /* Frequency of Clock */ 137 UCHAR ucVddInd; /* Base voltage */ 138} ATOM_Vega10_CLK_Dependency_Record; 139 140typedef struct _ATOM_Vega10_GFXCLK_Dependency_Record { 141 ULONG ulClk; /* Clock Frequency */ 142 UCHAR ucVddInd; /* SOC_VDD index */ 143 USHORT usCKSVOffsetandDisable; /* Bits 0~30: Voltage offset for CKS, Bit 31: Disable/enable for the GFXCLK level. */ 144 USHORT usAVFSOffset; /* AVFS Voltage offset */ 145} ATOM_Vega10_GFXCLK_Dependency_Record; 146 147typedef struct _ATOM_Vega10_GFXCLK_Dependency_Record_V2 { 148 ULONG ulClk; 149 UCHAR ucVddInd; 150 USHORT usCKSVOffsetandDisable; 151 USHORT usAVFSOffset; 152 UCHAR ucACGEnable; 153 UCHAR ucReserved[3]; 154} ATOM_Vega10_GFXCLK_Dependency_Record_V2; 155 156typedef struct _ATOM_Vega10_MCLK_Dependency_Record { 157 ULONG ulMemClk; /* Clock Frequency */ 158 UCHAR ucVddInd; /* SOC_VDD index */ 159 UCHAR ucVddMemInd; /* MEM_VDD - only non zero for MCLK record */ 160 UCHAR ucVddciInd; /* VDDCI = only non zero for MCLK record */ 161} ATOM_Vega10_MCLK_Dependency_Record; 162 163typedef struct _ATOM_Vega10_GFXCLK_Dependency_Table { 164 UCHAR ucRevId; 165 UCHAR ucNumEntries; /* Number of entries. */ 166 ATOM_Vega10_GFXCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ 167} ATOM_Vega10_GFXCLK_Dependency_Table; 168 169typedef struct _ATOM_Vega10_MCLK_Dependency_Table { 170 UCHAR ucRevId; 171 UCHAR ucNumEntries; /* Number of entries. */ 172 ATOM_Vega10_MCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ 173} ATOM_Vega10_MCLK_Dependency_Table; 174 175typedef struct _ATOM_Vega10_SOCCLK_Dependency_Table { 176 UCHAR ucRevId; 177 UCHAR ucNumEntries; /* Number of entries. */ 178 ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ 179} ATOM_Vega10_SOCCLK_Dependency_Table; 180 181typedef struct _ATOM_Vega10_DCEFCLK_Dependency_Table { 182 UCHAR ucRevId; 183 UCHAR ucNumEntries; /* Number of entries. */ 184 ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ 185} ATOM_Vega10_DCEFCLK_Dependency_Table; 186 187typedef struct _ATOM_Vega10_PIXCLK_Dependency_Table { 188 UCHAR ucRevId; 189 UCHAR ucNumEntries; /* Number of entries. */ 190 ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ 191} ATOM_Vega10_PIXCLK_Dependency_Table; 192 193typedef struct _ATOM_Vega10_DISPCLK_Dependency_Table { 194 UCHAR ucRevId; 195 UCHAR ucNumEntries; /* Number of entries.*/ 196 ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ 197} ATOM_Vega10_DISPCLK_Dependency_Table; 198 199typedef struct _ATOM_Vega10_PHYCLK_Dependency_Table { 200 UCHAR ucRevId; 201 UCHAR ucNumEntries; /* Number of entries. */ 202 ATOM_Vega10_CLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ 203} ATOM_Vega10_PHYCLK_Dependency_Table; 204 205typedef struct _ATOM_Vega10_MM_Dependency_Record { 206 UCHAR ucVddcInd; /* SOC_VDD voltage */ 207 ULONG ulDClk; /* UVD D-clock */ 208 ULONG ulVClk; /* UVD V-clock */ 209 ULONG ulEClk; /* VCE clock */ 210 ULONG ulPSPClk; /* PSP clock */ 211} ATOM_Vega10_MM_Dependency_Record; 212 213typedef struct _ATOM_Vega10_MM_Dependency_Table { 214 UCHAR ucRevId; 215 UCHAR ucNumEntries; /* Number of entries */ 216 ATOM_Vega10_MM_Dependency_Record entries[1]; /* Dynamically allocate entries */ 217} ATOM_Vega10_MM_Dependency_Table; 218 219typedef struct _ATOM_Vega10_PCIE_Record { 220 ULONG ulLCLK; /* LClock */ 221 UCHAR ucPCIEGenSpeed; /* PCIE Speed */ 222 UCHAR ucPCIELaneWidth; /* PCIE Lane Width */ 223} ATOM_Vega10_PCIE_Record; 224 225typedef struct _ATOM_Vega10_PCIE_Table { 226 UCHAR ucRevId; 227 UCHAR ucNumEntries; /* Number of entries */ 228 ATOM_Vega10_PCIE_Record entries[1]; /* Dynamically allocate entries. */ 229} ATOM_Vega10_PCIE_Table; 230 231typedef struct _ATOM_Vega10_Voltage_Lookup_Record { 232 USHORT usVdd; /* Base voltage */ 233} ATOM_Vega10_Voltage_Lookup_Record; 234 235typedef struct _ATOM_Vega10_Voltage_Lookup_Table { 236 UCHAR ucRevId; 237 UCHAR ucNumEntries; /* Number of entries */ 238 ATOM_Vega10_Voltage_Lookup_Record entries[1]; /* Dynamically allocate entries */ 239} ATOM_Vega10_Voltage_Lookup_Table; 240 241typedef struct _ATOM_Vega10_Fan_Table { 242 UCHAR ucRevId; /* Change this if the table format changes or version changes so that the other fields are not the same. */ 243 USHORT usFanOutputSensitivity; /* Sensitivity of fan reaction to temepature changes. */ 244 USHORT usFanRPMMax; /* The default value in RPM. */ 245 USHORT usThrottlingRPM; 246 USHORT usFanAcousticLimit; /* Minimum Fan Controller Frequency Acoustic Limit. */ 247 USHORT usTargetTemperature; /* The default ideal temperature in Celcius. */ 248 USHORT usMinimumPWMLimit; /* The minimum PWM that the advanced fan controller can set. */ 249 USHORT usTargetGfxClk; /* The ideal Fan Controller GFXCLK Frequency Acoustic Limit. */ 250 USHORT usFanGainEdge; 251 USHORT usFanGainHotspot; 252 USHORT usFanGainLiquid; 253 USHORT usFanGainVrVddc; 254 USHORT usFanGainVrMvdd; 255 USHORT usFanGainPlx; 256 USHORT usFanGainHbm; 257 UCHAR ucEnableZeroRPM; 258 USHORT usFanStopTemperature; 259 USHORT usFanStartTemperature; 260} ATOM_Vega10_Fan_Table; 261 262typedef struct _ATOM_Vega10_Fan_Table_V2 { 263 UCHAR ucRevId; 264 USHORT usFanOutputSensitivity; 265 USHORT usFanAcousticLimitRpm; 266 USHORT usThrottlingRPM; 267 USHORT usTargetTemperature; 268 USHORT usMinimumPWMLimit; 269 USHORT usTargetGfxClk; 270 USHORT usFanGainEdge; 271 USHORT usFanGainHotspot; 272 USHORT usFanGainLiquid; 273 USHORT usFanGainVrVddc; 274 USHORT usFanGainVrMvdd; 275 USHORT usFanGainPlx; 276 USHORT usFanGainHbm; 277 UCHAR ucEnableZeroRPM; 278 USHORT usFanStopTemperature; 279 USHORT usFanStartTemperature; 280 UCHAR ucFanParameters; 281 UCHAR ucFanMinRPM; 282 UCHAR ucFanMaxRPM; 283} ATOM_Vega10_Fan_Table_V2; 284 285typedef struct _ATOM_Vega10_Fan_Table_V3 { 286 UCHAR ucRevId; 287 USHORT usFanOutputSensitivity; 288 USHORT usFanAcousticLimitRpm; 289 USHORT usThrottlingRPM; 290 USHORT usTargetTemperature; 291 USHORT usMinimumPWMLimit; 292 USHORT usTargetGfxClk; 293 USHORT usFanGainEdge; 294 USHORT usFanGainHotspot; 295 USHORT usFanGainLiquid; 296 USHORT usFanGainVrVddc; 297 USHORT usFanGainVrMvdd; 298 USHORT usFanGainPlx; 299 USHORT usFanGainHbm; 300 UCHAR ucEnableZeroRPM; 301 USHORT usFanStopTemperature; 302 USHORT usFanStartTemperature; 303 UCHAR ucFanParameters; 304 UCHAR ucFanMinRPM; 305 UCHAR ucFanMaxRPM; 306 USHORT usMGpuThrottlingRPM; 307} ATOM_Vega10_Fan_Table_V3; 308 309typedef struct _ATOM_Vega10_Thermal_Controller { 310 UCHAR ucRevId; 311 UCHAR ucType; /* one of ATOM_VEGA10_PP_THERMALCONTROLLER_*/ 312 UCHAR ucI2cLine; /* as interpreted by DAL I2C */ 313 UCHAR ucI2cAddress; 314 UCHAR ucFanParameters; /* Fan Control Parameters. */ 315 UCHAR ucFanMinRPM; /* Fan Minimum RPM (hundreds) -- for display purposes only.*/ 316 UCHAR ucFanMaxRPM; /* Fan Maximum RPM (hundreds) -- for display purposes only.*/ 317 UCHAR ucFlags; /* to be defined */ 318} ATOM_Vega10_Thermal_Controller; 319 320typedef struct _ATOM_Vega10_VCE_State_Record 321{ 322 UCHAR ucVCEClockIndex; /*index into usVCEDependencyTableOffset of 'ATOM_Vega10_MM_Dependency_Table' type */ 323 UCHAR ucFlag; /* 2 bits indicates memory p-states */ 324 UCHAR ucSCLKIndex; /* index into ATOM_Vega10_SCLK_Dependency_Table */ 325 UCHAR ucMCLKIndex; /* index into ATOM_Vega10_MCLK_Dependency_Table */ 326} ATOM_Vega10_VCE_State_Record; 327 328typedef struct _ATOM_Vega10_VCE_State_Table 329{ 330 UCHAR ucRevId; 331 UCHAR ucNumEntries; 332 ATOM_Vega10_VCE_State_Record entries[1]; 333} ATOM_Vega10_VCE_State_Table; 334 335typedef struct _ATOM_Vega10_PowerTune_Table { 336 UCHAR ucRevId; 337 USHORT usSocketPowerLimit; 338 USHORT usBatteryPowerLimit; 339 USHORT usSmallPowerLimit; 340 USHORT usTdcLimit; 341 USHORT usEdcLimit; 342 USHORT usSoftwareShutdownTemp; 343 USHORT usTemperatureLimitHotSpot; 344 USHORT usTemperatureLimitLiquid1; 345 USHORT usTemperatureLimitLiquid2; 346 USHORT usTemperatureLimitHBM; 347 USHORT usTemperatureLimitVrSoc; 348 USHORT usTemperatureLimitVrMem; 349 USHORT usTemperatureLimitPlx; 350 USHORT usLoadLineResistance; 351 UCHAR ucLiquid1_I2C_address; 352 UCHAR ucLiquid2_I2C_address; 353 UCHAR ucVr_I2C_address; 354 UCHAR ucPlx_I2C_address; 355 UCHAR ucLiquid_I2C_LineSCL; 356 UCHAR ucLiquid_I2C_LineSDA; 357 UCHAR ucVr_I2C_LineSCL; 358 UCHAR ucVr_I2C_LineSDA; 359 UCHAR ucPlx_I2C_LineSCL; 360 UCHAR ucPlx_I2C_LineSDA; 361 USHORT usTemperatureLimitTedge; 362} ATOM_Vega10_PowerTune_Table; 363 364typedef struct _ATOM_Vega10_PowerTune_Table_V2 365{ 366 UCHAR ucRevId; 367 USHORT usSocketPowerLimit; 368 USHORT usBatteryPowerLimit; 369 USHORT usSmallPowerLimit; 370 USHORT usTdcLimit; 371 USHORT usEdcLimit; 372 USHORT usSoftwareShutdownTemp; 373 USHORT usTemperatureLimitHotSpot; 374 USHORT usTemperatureLimitLiquid1; 375 USHORT usTemperatureLimitLiquid2; 376 USHORT usTemperatureLimitHBM; 377 USHORT usTemperatureLimitVrSoc; 378 USHORT usTemperatureLimitVrMem; 379 USHORT usTemperatureLimitPlx; 380 USHORT usLoadLineResistance; 381 UCHAR ucLiquid1_I2C_address; 382 UCHAR ucLiquid2_I2C_address; 383 UCHAR ucLiquid_I2C_Line; 384 UCHAR ucVr_I2C_address; 385 UCHAR ucVr_I2C_Line; 386 UCHAR ucPlx_I2C_address; 387 UCHAR ucPlx_I2C_Line; 388 USHORT usTemperatureLimitTedge; 389} ATOM_Vega10_PowerTune_Table_V2; 390 391typedef struct _ATOM_Vega10_PowerTune_Table_V3 392{ 393 UCHAR ucRevId; 394 USHORT usSocketPowerLimit; 395 USHORT usBatteryPowerLimit; 396 USHORT usSmallPowerLimit; 397 USHORT usTdcLimit; 398 USHORT usEdcLimit; 399 USHORT usSoftwareShutdownTemp; 400 USHORT usTemperatureLimitHotSpot; 401 USHORT usTemperatureLimitLiquid1; 402 USHORT usTemperatureLimitLiquid2; 403 USHORT usTemperatureLimitHBM; 404 USHORT usTemperatureLimitVrSoc; 405 USHORT usTemperatureLimitVrMem; 406 USHORT usTemperatureLimitPlx; 407 USHORT usLoadLineResistance; 408 UCHAR ucLiquid1_I2C_address; 409 UCHAR ucLiquid2_I2C_address; 410 UCHAR ucLiquid_I2C_Line; 411 UCHAR ucVr_I2C_address; 412 UCHAR ucVr_I2C_Line; 413 UCHAR ucPlx_I2C_address; 414 UCHAR ucPlx_I2C_Line; 415 USHORT usTemperatureLimitTedge; 416 USHORT usBoostStartTemperature; 417 USHORT usBoostStopTemperature; 418 ULONG ulBoostClock; 419 ULONG Reserved[2]; 420} ATOM_Vega10_PowerTune_Table_V3; 421 422typedef struct _ATOM_Vega10_Hard_Limit_Record { 423 ULONG ulSOCCLKLimit; 424 ULONG ulGFXCLKLimit; 425 ULONG ulMCLKLimit; 426 USHORT usVddcLimit; 427 USHORT usVddciLimit; 428 USHORT usVddMemLimit; 429} ATOM_Vega10_Hard_Limit_Record; 430 431typedef struct _ATOM_Vega10_Hard_Limit_Table 432{ 433 UCHAR ucRevId; 434 UCHAR ucNumEntries; 435 ATOM_Vega10_Hard_Limit_Record entries[1]; 436} ATOM_Vega10_Hard_Limit_Table; 437 438typedef struct _Vega10_PPTable_Generic_SubTable_Header 439{ 440 UCHAR ucRevId; 441} Vega10_PPTable_Generic_SubTable_Header; 442 443#pragma pack(pop) 444 445#endif 446