Ignore this patch for now. there are still problems with newer gcc versions that aren't fixed yet.
Alex
On Tue, Aug 20, 2013 at 1:16 PM, Alex Deucher alexdeucher@gmail.com wrote:
Newer versions of gcc seem to wander off into no-man's land when using variably sized arrays. Atombios tends to do things like:
struct object { u8 version; u8 num_elements; u32 elements[1]; /* num_elements entries */ };
We then do things like the following in the driver code:
for (i = 0; i < atom_object->num_elements; i++) { driver_object[i] = atom_object->elements[i]; }
With previous versions of gcc this used to work fine, but with 4.7 and 4.8, it seems to generate code that wanders off into the weeds.
According to: http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html The traditional way of handling variably sized arrays (ISO C90) is to use an array length of 1. Gcc allows you to use an array length of 0 and newer versions of gcc only seem to do the right thing when 0 is used.
This is tricky in this case because atombios.h is shared between multiple components and is used for allocation in the vbios.
v2: update commit message
Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org
drivers/gpu/drm/radeon/atombios.h | 100 +++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 50 deletions(-)
diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 16b120c..3f1f011 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -3592,7 +3592,7 @@ typedef struct _ATOM_FAKE_EDID_PATCH_RECORD { UCHAR ucRecordType; UCHAR ucFakeEDIDLength;
- UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements.
- UCHAR ucFakeEDIDString[0]; // This actually has ucFakeEdidLength elements.
} ATOM_FAKE_EDID_PATCH_RECORD;
typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD @@ -3868,7 +3868,7 @@ typedef struct _ATOM_GPIO_PIN_ASSIGNMENT typedef struct _ATOM_GPIO_PIN_LUT { ATOM_COMMON_TABLE_HEADER sHeader;
- ATOM_GPIO_PIN_ASSIGNMENT asGPIO_Pin[1];
- ATOM_GPIO_PIN_ASSIGNMENT asGPIO_Pin[0];
}ATOM_GPIO_PIN_LUT;
/****************************************************************************/ @@ -3995,7 +3995,7 @@ typedef struct _ATOM_DISPLAY_OBJECT_PATH USHORT usSize; //the size of ATOM_DISPLAY_OBJECT_PATH USHORT usConnObjectId; //Connector Object ID USHORT usGPUObjectId; //GPU ID
- USHORT usGraphicObjIds[1]; //1st Encoder Obj source from GPU to last Graphic Obj destinate to connector.
- USHORT usGraphicObjIds[0]; //1st Encoder Obj source from GPU to last Graphic Obj destinate to connector.
}ATOM_DISPLAY_OBJECT_PATH;
typedef struct _ATOM_DISPLAY_EXTERNAL_OBJECT_PATH @@ -4012,7 +4012,7 @@ typedef struct _ATOM_DISPLAY_OBJECT_PATH_TABLE UCHAR ucNumOfDispPath; UCHAR ucVersion; UCHAR ucPadding[2];
- ATOM_DISPLAY_OBJECT_PATH asDispPath[1];
- ATOM_DISPLAY_OBJECT_PATH asDispPath[0];
}ATOM_DISPLAY_OBJECT_PATH_TABLE;
@@ -4028,15 +4028,15 @@ typedef struct _ATOM_OBJECT_TABLE //Above 4 object table { UCHAR ucNumberOfObjects; UCHAR ucPadding[3];
- ATOM_OBJECT asObjects[1];
- ATOM_OBJECT asObjects[0];
}ATOM_OBJECT_TABLE;
typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT //usSrcDstTableOffset pointing to this structure { UCHAR ucNumberOfSrc;
- USHORT usSrcObjectID[1];
- USHORT usSrcObjectID[0]; UCHAR ucNumberOfDst;
- USHORT usDstObjectID[1];
- USHORT usDstObjectID[0];
}ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT;
@@ -4208,7 +4208,7 @@ typedef struct _ATOM_CONNECTOR_DEVICE_TAG_RECORD ATOM_COMMON_RECORD_HEADER sheader; UCHAR ucNumberOfDevice; UCHAR ucReserved;
- ATOM_CONNECTOR_DEVICE_TAG asDeviceTag[1]; //This Id is same as "ATOM_DEVICE_XXX_SUPPORT", 1 is only for allocation
- ATOM_CONNECTOR_DEVICE_TAG asDeviceTag[0]; //This Id is same as "ATOM_DEVICE_XXX_SUPPORT", 1 is only for allocation
}ATOM_CONNECTOR_DEVICE_TAG_RECORD;
@@ -4268,7 +4268,7 @@ typedef struct _ATOM_OBJECT_GPIO_CNTL_RECORD ATOM_COMMON_RECORD_HEADER sheader; UCHAR ucFlags; // Future expnadibility UCHAR ucNumberOfPins; // Number of GPIO pins used to control the object
- ATOM_GPIO_PIN_CONTROL_PAIR asGpio[1]; // the real gpio pin pair determined by number of pins ucNumberOfPins
- ATOM_GPIO_PIN_CONTROL_PAIR asGpio[0]; // the real gpio pin pair determined by number of pins ucNumberOfPins
}ATOM_OBJECT_GPIO_CNTL_RECORD;
//Definitions for GPIO pin state @@ -4549,7 +4549,7 @@ typedef struct _ATOM_I2C_VOLTAGE_OBJECT_V3 UCHAR ucVoltageControlAddress; UCHAR ucVoltageControlOffset; ULONG ulReserved;
- VOLTAGE_LUT_ENTRY asVolI2cLut[1]; // end with 0xff
- VOLTAGE_LUT_ENTRY asVolI2cLut[0]; // end with 0xff
}ATOM_I2C_VOLTAGE_OBJECT_V3;
typedef struct _ATOM_GPIO_VOLTAGE_OBJECT_V3 @@ -4560,7 +4560,7 @@ typedef struct _ATOM_GPIO_VOLTAGE_OBJECT_V3 UCHAR ucPhaseDelay; // phase delay in unit of micro second UCHAR ucReserved; ULONG ulGpioMaskVal; // GPIO Mask value
- VOLTAGE_LUT_ENTRY_V2 asVolGpioLut[1];
- VOLTAGE_LUT_ENTRY_V2 asVolGpioLut[0];
}ATOM_GPIO_VOLTAGE_OBJECT_V3;
typedef struct _ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 @@ -4570,7 +4570,7 @@ typedef struct _ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 UCHAR ucLeakageEntryNum; // indicate the entry number of LeakageId/Voltage Lut table UCHAR ucReserved[2]; ULONG ulMaxVoltageLevel;
- LEAKAGE_VOLTAGE_LUT_ENTRY_V2 asLeakageIdLut[1];
- LEAKAGE_VOLTAGE_LUT_ENTRY_V2 asLeakageIdLut[0];
}ATOM_LEAKAGE_VOLTAGE_OBJECT_V3;
@@ -4654,7 +4654,7 @@ typedef struct _ATOM_POWER_SOURCE_INFO { ATOM_COMMON_TABLE_HEADER asHeader; UCHAR asPwrbehave[16];
ATOM_POWER_SOURCE_OBJECT asPwrObj[1];
ATOM_POWER_SOURCE_OBJECT asPwrObj[0];
}ATOM_POWER_SOURCE_INFO;
@@ -5341,7 +5341,7 @@ typedef struct _ATOM_FUSION_SYSTEM_INFO_V2 typedef struct _ATOM_I2C_DATA_RECORD { UCHAR ucNunberOfBytes; //Indicates how many bytes SW needs to write to the external ASIC for one block, besides to "Start" and "Stop"
- UCHAR ucI2CData[1]; //I2C data in bytes, should be less than 16 bytes usually
- UCHAR ucI2CData[0]; //I2C data in bytes, should be less than 16 bytes usually
}ATOM_I2C_DATA_RECORD;
@@ -5352,14 +5352,14 @@ typedef struct _ATOM_I2C_DEVICE_SETUP_INFO UCHAR ucSSChipID; //SS chip being used UCHAR ucSSChipSlaveAddr; //Slave Address to set up this SS chip UCHAR ucNumOfI2CDataRecords; //number of data block
- ATOM_I2C_DATA_RECORD asI2CData[1];
- ATOM_I2C_DATA_RECORD asI2CData[0];
}ATOM_I2C_DEVICE_SETUP_INFO;
//========================================================================================== typedef struct _ATOM_ASIC_MVDD_INFO { ATOM_COMMON_TABLE_HEADER sHeader;
- ATOM_I2C_DEVICE_SETUP_INFO asI2CSetup[1];
- ATOM_I2C_DEVICE_SETUP_INFO asI2CSetup[0];
}ATOM_ASIC_MVDD_INFO;
//========================================================================================== @@ -5421,7 +5421,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 { ATOM_COMMON_TABLE_HEADER sHeader;
- ATOM_ASIC_SS_ASSIGNMENT_V2 asSpreadSpectrum[1]; //this is point only.
- ATOM_ASIC_SS_ASSIGNMENT_V2 asSpreadSpectrum[0]; //this is point only.
}ATOM_ASIC_INTERNAL_SS_INFO_V2;
typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V3 @@ -5443,7 +5443,7 @@ typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V3 typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 { ATOM_COMMON_TABLE_HEADER sHeader;
- ATOM_ASIC_SS_ASSIGNMENT_V3 asSpreadSpectrum[1]; //this is pointer only.
- ATOM_ASIC_SS_ASSIGNMENT_V3 asSpreadSpectrum[0]; //this is pointer only.
}ATOM_ASIC_INTERNAL_SS_INFO_V3;
@@ -6181,7 +6181,7 @@ typedef union _ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS
typedef struct _ATOM_MEMORY_SETTING_DATA_BLOCK{ ATOM_MEMORY_SETTING_ID_CONFIG_ACCESS ulMemoryID;
ULONG aulMemData[1];
ULONG aulMemData[0];
}ATOM_MEMORY_SETTING_DATA_BLOCK;
@@ -6194,8 +6194,8 @@ typedef struct _ATOM_INIT_REG_INDEX_FORMAT{ typedef struct _ATOM_INIT_REG_BLOCK{ USHORT usRegIndexTblSize; //size of asRegIndexBuf USHORT usRegDataBlkSize; //size of ATOM_MEMORY_SETTING_DATA_BLOCK
ATOM_INIT_REG_INDEX_FORMAT asRegIndexBuf[1];
ATOM_MEMORY_SETTING_DATA_BLOCK asRegDataBuf[1];
ATOM_INIT_REG_INDEX_FORMAT asRegIndexBuf[0];
ATOM_MEMORY_SETTING_DATA_BLOCK asRegDataBuf[0];
}ATOM_INIT_REG_BLOCK;
#define END_OF_REG_INDEX_BLOCK 0x0ffff @@ -6938,8 +6938,8 @@ typedef struct _ATOM_DISP_OUT_INFO ATOM_COMMON_TABLE_HEADER sHeader; USHORT ptrTransmitterInfo; USHORT ptrEncoderInfo;
ASIC_TRANSMITTER_INFO asTransmitterInfo[1];
ASIC_ENCODER_INFO asEncoderInfo[1];
ASIC_TRANSMITTER_INFO asTransmitterInfo[0];
ASIC_ENCODER_INFO asEncoderInfo[0];
}ATOM_DISP_OUT_INFO;
typedef struct _ATOM_DISP_OUT_INFO_V2 @@ -6948,8 +6948,8 @@ typedef struct _ATOM_DISP_OUT_INFO_V2 USHORT ptrTransmitterInfo; USHORT ptrEncoderInfo; USHORT ptrMainCallParserFar; // direct address of main parser call in VBIOS binary.
ASIC_TRANSMITTER_INFO asTransmitterInfo[1];
ASIC_ENCODER_INFO asEncoderInfo[1];
ASIC_TRANSMITTER_INFO asTransmitterInfo[0];
ASIC_ENCODER_INFO asEncoderInfo[0];
}ATOM_DISP_OUT_INFO_V2;
@@ -6989,7 +6989,7 @@ typedef struct _ATOM_DISP_OUT_INFO_V3 UCHAR ucMaxPPLLNum; UCHAR ucCoreRefClkSource; // value of CORE_REF_CLK_SOURCE UCHAR ucReserved[3];
ASIC_TRANSMITTER_INFO_V2 asTransmitterInfo[1]; // for alligment only
ASIC_TRANSMITTER_INFO_V2 asTransmitterInfo[0]; // for alligment only
}ATOM_DISP_OUT_INFO_V3;
//ucDispCaps @@ -7221,12 +7221,12 @@ typedef struct _CLOCK_CONDITION_SETTING_ENTRY{ USHORT usMaxClockFreq; UCHAR ucEncodeMode; UCHAR ucPhySel;
- ULONG ulAnalogSetting[1];
- ULONG ulAnalogSetting[0];
}CLOCK_CONDITION_SETTING_ENTRY;
typedef struct _CLOCK_CONDITION_SETTING_INFO{ USHORT usEntrySize;
- CLOCK_CONDITION_SETTING_ENTRY asClkCondSettingEntry[1];
- CLOCK_CONDITION_SETTING_ENTRY asClkCondSettingEntry[0];
}CLOCK_CONDITION_SETTING_INFO;
typedef struct _PHY_CONDITION_REG_VAL{ @@ -7243,27 +7243,27 @@ typedef struct _PHY_CONDITION_REG_VAL_V2{ typedef struct _PHY_CONDITION_REG_INFO{ USHORT usRegIndex; USHORT usSize;
- PHY_CONDITION_REG_VAL asRegVal[1];
- PHY_CONDITION_REG_VAL asRegVal[0];
}PHY_CONDITION_REG_INFO;
typedef struct _PHY_CONDITION_REG_INFO_V2{ USHORT usRegIndex; USHORT usSize;
- PHY_CONDITION_REG_VAL_V2 asRegVal[1];
- PHY_CONDITION_REG_VAL_V2 asRegVal[0];
}PHY_CONDITION_REG_INFO_V2;
typedef struct _PHY_ANALOG_SETTING_INFO{ UCHAR ucEncodeMode; UCHAR ucPhySel; USHORT usSize;
- PHY_CONDITION_REG_INFO asAnalogSetting[1];
- PHY_CONDITION_REG_INFO asAnalogSetting[0];
}PHY_ANALOG_SETTING_INFO;
typedef struct _PHY_ANALOG_SETTING_INFO_V2{ UCHAR ucEncodeMode; UCHAR ucPhySel; USHORT usSize;
- PHY_CONDITION_REG_INFO_V2 asAnalogSetting[1];
- PHY_CONDITION_REG_INFO_V2 asAnalogSetting[0];
}PHY_ANALOG_SETTING_INFO_V2;
typedef struct _GFX_HAVESTING_PARAMETERS { @@ -7709,7 +7709,7 @@ typedef struct _ATOM_PPLIB_THERMALCONTROLLER typedef struct _ATOM_PPLIB_STATE { UCHAR ucNonClockStateIndex;
- UCHAR ucClockStateIndices[1]; // variable-sized
- UCHAR ucClockStateIndices[0]; // variable-sized
} ATOM_PPLIB_STATE;
@@ -8057,14 +8057,14 @@ typedef struct _ATOM_PPLIB_STATE_V2 /** * Driver will read the first ucNumDPMLevels in this array */
UCHAR clockInfoIndex[1];
UCHAR clockInfoIndex[0];
} ATOM_PPLIB_STATE_V2;
typedef struct _StateArray{ //how many states we have UCHAR ucNumEntries;
- ATOM_PPLIB_STATE_V2 states[1];
- ATOM_PPLIB_STATE_V2 states[0];
}StateArray;
@@ -8075,7 +8075,7 @@ typedef struct _ClockInfoArray{ //sizeof(ATOM_PPLIB_CLOCK_INFO) UCHAR ucEntrySize;
- UCHAR clockInfo[1];
- UCHAR clockInfo[0];
}ClockInfoArray;
typedef struct _NonClockInfoArray{ @@ -8085,7 +8085,7 @@ typedef struct _NonClockInfoArray{ //sizeof(ATOM_PPLIB_NONCLOCK_INFO) UCHAR ucEntrySize;
- ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[1];
- ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[0];
}NonClockInfoArray;
typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record @@ -8098,7 +8098,7 @@ typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Table { UCHAR ucNumEntries; // Number of entries.
- ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[1]; // Dynamically allocate entries.
- ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[0]; // Dynamically allocate entries.
}ATOM_PPLIB_Clock_Voltage_Dependency_Table;
typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Record @@ -8114,7 +8114,7 @@ typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Record typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Table { UCHAR ucNumEntries; // Number of entries.
- ATOM_PPLIB_Clock_Voltage_Limit_Record entries[1]; // Dynamically allocate entries.
- ATOM_PPLIB_Clock_Voltage_Limit_Record entries[0]; // Dynamically allocate entries.
}ATOM_PPLIB_Clock_Voltage_Limit_Table;
typedef struct _ATOM_PPLIB_CAC_Leakage_Record @@ -8126,7 +8126,7 @@ typedef struct _ATOM_PPLIB_CAC_Leakage_Record typedef struct _ATOM_PPLIB_CAC_Leakage_Table { UCHAR ucNumEntries; // Number of entries.
- ATOM_PPLIB_CAC_Leakage_Record entries[1]; // Dynamically allocate entries.
- ATOM_PPLIB_CAC_Leakage_Record entries[0]; // Dynamically allocate entries.
}ATOM_PPLIB_CAC_Leakage_Table;
typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Record @@ -8141,7 +8141,7 @@ typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Record typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Table { UCHAR ucNumEntries; // Number of entries.
- ATOM_PPLIB_PhaseSheddingLimits_Record entries[1]; // Dynamically allocate entries.
- ATOM_PPLIB_PhaseSheddingLimits_Record entries[0]; // Dynamically allocate entries.
}ATOM_PPLIB_PhaseSheddingLimits_Table;
typedef struct _VCEClockInfo{ @@ -8153,7 +8153,7 @@ typedef struct _VCEClockInfo{
typedef struct _VCEClockInfoArray{ UCHAR ucNumEntries;
- VCEClockInfo entries[1];
- VCEClockInfo entries[0];
}VCEClockInfoArray;
typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record @@ -8165,7 +8165,7 @@ typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table { UCHAR numEntries;
- ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record entries[1];
- ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record entries[0];
}ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table;
typedef struct _ATOM_PPLIB_VCE_State_Record @@ -8177,7 +8177,7 @@ typedef struct _ATOM_PPLIB_VCE_State_Record typedef struct _ATOM_PPLIB_VCE_State_Table { UCHAR numEntries;
- ATOM_PPLIB_VCE_State_Record entries[1];
- ATOM_PPLIB_VCE_State_Record entries[0];
}ATOM_PPLIB_VCE_State_Table;
@@ -8199,7 +8199,7 @@ typedef struct _UVDClockInfo{
typedef struct _UVDClockInfoArray{ UCHAR ucNumEntries;
- UVDClockInfo entries[1];
- UVDClockInfo entries[0];
}UVDClockInfoArray;
typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record @@ -8211,7 +8211,7 @@ typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table { UCHAR numEntries;
- ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record entries[1];
- ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record entries[0];
}ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table;
typedef struct _ATOM_PPLIB_UVD_State_Record @@ -8223,7 +8223,7 @@ typedef struct _ATOM_PPLIB_UVD_State_Record typedef struct _ATOM_PPLIB_UVD_State_Table { UCHAR numEntries;
- ATOM_PPLIB_UVD_State_Record entries[1];
- ATOM_PPLIB_UVD_State_Record entries[0];
}ATOM_PPLIB_UVD_State_Table;
@@ -8245,7 +8245,7 @@ typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Record
typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Table{ UCHAR numEntries;
- ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[1];
- ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[0];
}ATOM_PPLIB_SAMClk_Voltage_Limit_Table;
typedef struct _ATOM_PPLIB_SAMU_Table @@ -8473,12 +8473,12 @@ typedef struct {
typedef struct { VFCT_IMAGE_HEADER VbiosHeader;
- UCHAR VbiosContent[1];
- UCHAR VbiosContent[0];
}GOP_VBIOS_CONTENT;
typedef struct { VFCT_IMAGE_HEADER Lib1Header;
- UCHAR Lib1Content[1];
- UCHAR Lib1Content[0];
}GOP_LIB1_CONTENT;
#pragma pack()
1.8.3.1