Decoder.c revision 209ff23f
1/* 2 * Copyright 2006-2007 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/** 24 25Module Name: 26 27 Decoder.c 28 29Abstract: 30 31 Commands Decoder 32 33Revision History: 34 35 NEG:24.09.2002 Initiated. 36--*/ 37 38#ifdef HAVE_CONFIG_H 39#include "config.h" 40#endif 41 42#include <X11/Xos.h> 43 44 45#include "Decoder.h" 46#include "atombios.h" 47#include "CD_binding.h" 48#include "CD_Common_Types.h" 49 50#ifndef DISABLE_EASF 51 #include "easf.h" 52#endif 53 54 55 56#define INDIRECT_IO_TABLE (((UINT16)(ULONG_PTR)&((ATOM_MASTER_LIST_OF_DATA_TABLES*)0)->IndirectIOAccess)/sizeof(TABLE_UNIT_TYPE) ) 57extern COMMANDS_PROPERTIES CallTable[]; 58 59 60UINT8 ProcessCommandProperties(PARSER_TEMP_DATA STACK_BASED * pParserTempData) 61{ 62 UINT8 opcode=((COMMAND_HEADER*)pParserTempData->pWorkingTableData->IP)->Opcode; 63 pParserTempData->pWorkingTableData->IP+=CallTable[opcode].headersize; 64 pParserTempData->ParametersType.Destination=CallTable[opcode].destination; 65 pParserTempData->ParametersType.Source = pParserTempData->pCmd->Header.Attribute.Source; 66 pParserTempData->CD_Mask.SrcAlignment=pParserTempData->pCmd->Header.Attribute.SourceAlignment; 67 pParserTempData->CD_Mask.DestAlignment=pParserTempData->pCmd->Header.Attribute.DestinationAlignment; 68 return opcode; 69} 70 71UINT16* GetCommandMasterTablePointer(DEVICE_DATA STACK_BASED* pDeviceData) 72{ 73 UINT16 *MasterTableOffset; 74#ifndef DISABLE_EASF 75 if (pDeviceData->format == TABLE_FORMAT_EASF) 76 { 77 /* 78 make MasterTableOffset point to EASF_ASIC_SETUP_TABLE structure, including usSize. 79 */ 80 MasterTableOffset = (UINT16 *) (pDeviceData->pBIOS_Image+((EASF_ASIC_DESCRIPTOR*)pDeviceData->pBIOS_Image)->usAsicSetupTable_Offset); 81 } else 82#endif 83 { 84#ifndef UEFI_BUILD 85 MasterTableOffset = (UINT16 *)(*(UINT16 *)(pDeviceData->pBIOS_Image+OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER) + pDeviceData->pBIOS_Image); 86 MasterTableOffset = (UINT16 *)((ULONG)((ATOM_ROM_HEADER *)MasterTableOffset)->usMasterCommandTableOffset + pDeviceData->pBIOS_Image ); 87 MasterTableOffset =(UINT16 *) &(((ATOM_MASTER_COMMAND_TABLE *)MasterTableOffset)->ListOfCommandTables); 88#else 89 MasterTableOffset = (UINT16 *)(&(GetCommandMasterTable( )->ListOfCommandTables)); 90#endif 91 } 92 return MasterTableOffset; 93} 94 95UINT16* GetDataMasterTablePointer(DEVICE_DATA STACK_BASED* pDeviceData) 96{ 97 UINT16 *MasterTableOffset; 98 99#ifndef UEFI_BUILD 100 MasterTableOffset = (UINT16 *)(*(UINT16 *)(pDeviceData->pBIOS_Image+OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER) + pDeviceData->pBIOS_Image); 101 MasterTableOffset = (UINT16 *)((ULONG)((ATOM_ROM_HEADER *)MasterTableOffset)->usMasterDataTableOffset + pDeviceData->pBIOS_Image ); 102 MasterTableOffset =(UINT16 *) &(((ATOM_MASTER_DATA_TABLE *)MasterTableOffset)->ListOfDataTables); 103#else 104 MasterTableOffset = (UINT16 *)(&(GetDataMasterTable( )->ListOfDataTables)); 105#endif 106 return MasterTableOffset; 107} 108 109 110UINT8 GetTrueIndexInMasterTable(PARSER_TEMP_DATA STACK_BASED * pParserTempData, UINT8 IndexInMasterTable) 111{ 112#ifndef DISABLE_EASF 113 UINT16 i; 114 if ( pParserTempData->pDeviceData->format == TABLE_FORMAT_EASF) 115 { 116/* 117 Consider EASF_ASIC_SETUP_TABLE structure pointed by pParserTempData->pCmd as UINT16[] 118 ((UINT16*)pParserTempData->pCmd)[0] = EASF_ASIC_SETUP_TABLE.usSize; 119 ((UINT16*)pParserTempData->pCmd)[1+n*4] = usFunctionID; 120 usFunctionID has to be shifted left by 2 before compare it to the value provided by caller. 121*/ 122 for (i=1; (i < ((UINT16*)pParserTempData->pCmd)[0] >> 1);i+=4) 123 if ((UINT8)(((UINT16*)pParserTempData->pCmd)[i] << 2)==(IndexInMasterTable & EASF_TABLE_INDEX_MASK)) return (i+1+(IndexInMasterTable & EASF_TABLE_ATTR_MASK)); 124 return 1; 125 } else 126#endif 127 { 128 return IndexInMasterTable; 129 } 130} 131 132CD_STATUS ParseTable(DEVICE_DATA STACK_BASED* pDeviceData, UINT8 IndexInMasterTable) 133{ 134 PARSER_TEMP_DATA ParserTempData; 135 WORKING_TABLE_DATA STACK_BASED* prevWorkingTableData; 136 137 ParserTempData.pDeviceData=(DEVICE_DATA*)pDeviceData; 138#ifndef DISABLE_EASF 139 if (pDeviceData->format == TABLE_FORMAT_EASF) 140 { 141 ParserTempData.IndirectIOTablePointer = 0; 142 } else 143#endif 144 { 145 ParserTempData.pCmd=(GENERIC_ATTRIBUTE_COMMAND*)GetDataMasterTablePointer(pDeviceData); 146 ParserTempData.IndirectIOTablePointer=(UINT8*)((ULONG)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[INDIRECT_IO_TABLE]) + pDeviceData->pBIOS_Image); 147 ParserTempData.IndirectIOTablePointer+=sizeof(ATOM_COMMON_TABLE_HEADER); 148 } 149 150 ParserTempData.pCmd=(GENERIC_ATTRIBUTE_COMMAND*)GetCommandMasterTablePointer(pDeviceData); 151 IndexInMasterTable=GetTrueIndexInMasterTable((PARSER_TEMP_DATA STACK_BASED *)&ParserTempData,IndexInMasterTable); 152 if(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]!=0 ) // if the offset is not ZERO 153 { 154 ParserTempData.CommandSpecific.IndexInMasterTable=IndexInMasterTable; 155 ParserTempData.Multipurpose.CurrentPort=ATI_RegsPort; 156 ParserTempData.CurrentPortID=INDIRECT_IO_MM; 157 ParserTempData.CurrentRegBlock=0; 158 ParserTempData.CurrentFB_Window=0; 159 prevWorkingTableData=NULL; 160 ParserTempData.Status=CD_CALL_TABLE; 161 162 do{ 163 164 if (ParserTempData.Status==CD_CALL_TABLE) 165 { 166 IndexInMasterTable=ParserTempData.CommandSpecific.IndexInMasterTable; 167 if(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]!=0) // if the offset is not ZERO 168 { 169#ifndef UEFI_BUILD 170 ParserTempData.pWorkingTableData =(WORKING_TABLE_DATA STACK_BASED*) AllocateWorkSpace(pDeviceData, 171 ((ATOM_COMMON_ROM_COMMAND_TABLE_HEADER*)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]+pDeviceData->pBIOS_Image))->TableAttribute.WS_SizeInBytes+sizeof(WORKING_TABLE_DATA)); 172#else 173 ParserTempData.pWorkingTableData =(WORKING_TABLE_DATA STACK_BASED*) AllocateWorkSpace(pDeviceData, 174 ((ATOM_COMMON_ROM_COMMAND_TABLE_HEADER*)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]))->TableAttribute.WS_SizeInBytes+sizeof(WORKING_TABLE_DATA)); 175#endif 176 if (ParserTempData.pWorkingTableData!=NULL) 177 { 178 ParserTempData.pWorkingTableData->pWorkSpace=(WORKSPACE_POINTER STACK_BASED*)((UINT8*)ParserTempData.pWorkingTableData+sizeof(WORKING_TABLE_DATA)); 179#ifndef UEFI_BUILD 180 ParserTempData.pWorkingTableData->pTableHead = (UINT8 *)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]+pDeviceData->pBIOS_Image); 181#else 182 ParserTempData.pWorkingTableData->pTableHead = (UINT8 *)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]); 183#endif 184 ParserTempData.pWorkingTableData->IP=((UINT8*)ParserTempData.pWorkingTableData->pTableHead)+sizeof(ATOM_COMMON_ROM_COMMAND_TABLE_HEADER); 185 ParserTempData.pWorkingTableData->prevWorkingTableData=prevWorkingTableData; 186 prevWorkingTableData=ParserTempData.pWorkingTableData; 187 ParserTempData.Status = CD_SUCCESS; 188 } else ParserTempData.Status = CD_UNEXPECTED_BEHAVIOR; 189 } else ParserTempData.Status = CD_EXEC_TABLE_NOT_FOUND; 190 } 191 if (!CD_ERROR(ParserTempData.Status)) 192 { 193 ParserTempData.Status = CD_SUCCESS; 194 while (!CD_ERROR_OR_COMPLETED(ParserTempData.Status)) 195 { 196 197 if (IS_COMMAND_VALID(((COMMAND_HEADER*)ParserTempData.pWorkingTableData->IP)->Opcode)) 198 { 199 ParserTempData.pCmd = (GENERIC_ATTRIBUTE_COMMAND*)ParserTempData.pWorkingTableData->IP; 200 201 if (IS_END_OF_TABLE(((COMMAND_HEADER*)ParserTempData.pWorkingTableData->IP)->Opcode)) 202 { 203 ParserTempData.Status=CD_COMPLETED; 204 prevWorkingTableData=ParserTempData.pWorkingTableData->prevWorkingTableData; 205 206 FreeWorkSpace(pDeviceData, ParserTempData.pWorkingTableData); 207 ParserTempData.pWorkingTableData=prevWorkingTableData; 208 if (prevWorkingTableData!=NULL) 209 { 210 ParserTempData.pDeviceData->pParameterSpace-= 211 (((ATOM_COMMON_ROM_COMMAND_TABLE_HEADER*)ParserTempData.pWorkingTableData-> 212 pTableHead)->TableAttribute.PS_SizeInBytes>>2); 213 } 214 // if there is a parent table where to return, then restore PS_pointer to the original state 215 } 216 else 217 { 218 IndexInMasterTable=ProcessCommandProperties((PARSER_TEMP_DATA STACK_BASED *)&ParserTempData); 219 (*CallTable[IndexInMasterTable].function)((PARSER_TEMP_DATA STACK_BASED *)&ParserTempData); 220#if (PARSER_TYPE!=DRIVER_TYPE_PARSER) 221 BIOS_STACK_MODIFIER(); 222#endif 223 } 224 } 225 else 226 { 227 ParserTempData.Status=CD_INVALID_OPCODE; 228 break; 229 } 230 231 } // while 232 } // if 233 else 234 break; 235 } while (prevWorkingTableData!=NULL); 236 if (ParserTempData.Status == CD_COMPLETED) return CD_SUCCESS; 237 return ParserTempData.Status; 238 } else return CD_SUCCESS; 239} 240 241// EOF 242 243