Decoder.c revision 209ff23f
1209ff23fSmrg/* 2209ff23fSmrg * Copyright 2006-2007 Advanced Micro Devices, Inc. 3209ff23fSmrg * 4209ff23fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5209ff23fSmrg * copy of this software and associated documentation files (the "Software"), 6209ff23fSmrg * to deal in the Software without restriction, including without limitation 7209ff23fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8209ff23fSmrg * and/or sell copies of the Software, and to permit persons to whom the 9209ff23fSmrg * Software is furnished to do so, subject to the following conditions: 10209ff23fSmrg * 11209ff23fSmrg * The above copyright notice and this permission notice shall be included in 12209ff23fSmrg * all copies or substantial portions of the Software. 13209ff23fSmrg * 14209ff23fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15209ff23fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16209ff23fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17209ff23fSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18209ff23fSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19209ff23fSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20209ff23fSmrg * OTHER DEALINGS IN THE SOFTWARE. 21209ff23fSmrg */ 22209ff23fSmrg 23209ff23fSmrg/** 24209ff23fSmrg 25209ff23fSmrgModule Name: 26209ff23fSmrg 27209ff23fSmrg Decoder.c 28209ff23fSmrg 29209ff23fSmrgAbstract: 30209ff23fSmrg 31209ff23fSmrg Commands Decoder 32209ff23fSmrg 33209ff23fSmrgRevision History: 34209ff23fSmrg 35209ff23fSmrg NEG:24.09.2002 Initiated. 36209ff23fSmrg--*/ 37209ff23fSmrg 38209ff23fSmrg#ifdef HAVE_CONFIG_H 39209ff23fSmrg#include "config.h" 40209ff23fSmrg#endif 41209ff23fSmrg 42209ff23fSmrg#include <X11/Xos.h> 43209ff23fSmrg 44209ff23fSmrg 45209ff23fSmrg#include "Decoder.h" 46209ff23fSmrg#include "atombios.h" 47209ff23fSmrg#include "CD_binding.h" 48209ff23fSmrg#include "CD_Common_Types.h" 49209ff23fSmrg 50209ff23fSmrg#ifndef DISABLE_EASF 51209ff23fSmrg #include "easf.h" 52209ff23fSmrg#endif 53209ff23fSmrg 54209ff23fSmrg 55209ff23fSmrg 56209ff23fSmrg#define INDIRECT_IO_TABLE (((UINT16)(ULONG_PTR)&((ATOM_MASTER_LIST_OF_DATA_TABLES*)0)->IndirectIOAccess)/sizeof(TABLE_UNIT_TYPE) ) 57209ff23fSmrgextern COMMANDS_PROPERTIES CallTable[]; 58209ff23fSmrg 59209ff23fSmrg 60209ff23fSmrgUINT8 ProcessCommandProperties(PARSER_TEMP_DATA STACK_BASED * pParserTempData) 61209ff23fSmrg{ 62209ff23fSmrg UINT8 opcode=((COMMAND_HEADER*)pParserTempData->pWorkingTableData->IP)->Opcode; 63209ff23fSmrg pParserTempData->pWorkingTableData->IP+=CallTable[opcode].headersize; 64209ff23fSmrg pParserTempData->ParametersType.Destination=CallTable[opcode].destination; 65209ff23fSmrg pParserTempData->ParametersType.Source = pParserTempData->pCmd->Header.Attribute.Source; 66209ff23fSmrg pParserTempData->CD_Mask.SrcAlignment=pParserTempData->pCmd->Header.Attribute.SourceAlignment; 67209ff23fSmrg pParserTempData->CD_Mask.DestAlignment=pParserTempData->pCmd->Header.Attribute.DestinationAlignment; 68209ff23fSmrg return opcode; 69209ff23fSmrg} 70209ff23fSmrg 71209ff23fSmrgUINT16* GetCommandMasterTablePointer(DEVICE_DATA STACK_BASED* pDeviceData) 72209ff23fSmrg{ 73209ff23fSmrg UINT16 *MasterTableOffset; 74209ff23fSmrg#ifndef DISABLE_EASF 75209ff23fSmrg if (pDeviceData->format == TABLE_FORMAT_EASF) 76209ff23fSmrg { 77209ff23fSmrg /* 78209ff23fSmrg make MasterTableOffset point to EASF_ASIC_SETUP_TABLE structure, including usSize. 79209ff23fSmrg */ 80209ff23fSmrg MasterTableOffset = (UINT16 *) (pDeviceData->pBIOS_Image+((EASF_ASIC_DESCRIPTOR*)pDeviceData->pBIOS_Image)->usAsicSetupTable_Offset); 81209ff23fSmrg } else 82209ff23fSmrg#endif 83209ff23fSmrg { 84209ff23fSmrg#ifndef UEFI_BUILD 85209ff23fSmrg MasterTableOffset = (UINT16 *)(*(UINT16 *)(pDeviceData->pBIOS_Image+OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER) + pDeviceData->pBIOS_Image); 86209ff23fSmrg MasterTableOffset = (UINT16 *)((ULONG)((ATOM_ROM_HEADER *)MasterTableOffset)->usMasterCommandTableOffset + pDeviceData->pBIOS_Image ); 87209ff23fSmrg MasterTableOffset =(UINT16 *) &(((ATOM_MASTER_COMMAND_TABLE *)MasterTableOffset)->ListOfCommandTables); 88209ff23fSmrg#else 89209ff23fSmrg MasterTableOffset = (UINT16 *)(&(GetCommandMasterTable( )->ListOfCommandTables)); 90209ff23fSmrg#endif 91209ff23fSmrg } 92209ff23fSmrg return MasterTableOffset; 93209ff23fSmrg} 94209ff23fSmrg 95209ff23fSmrgUINT16* GetDataMasterTablePointer(DEVICE_DATA STACK_BASED* pDeviceData) 96209ff23fSmrg{ 97209ff23fSmrg UINT16 *MasterTableOffset; 98209ff23fSmrg 99209ff23fSmrg#ifndef UEFI_BUILD 100209ff23fSmrg MasterTableOffset = (UINT16 *)(*(UINT16 *)(pDeviceData->pBIOS_Image+OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER) + pDeviceData->pBIOS_Image); 101209ff23fSmrg MasterTableOffset = (UINT16 *)((ULONG)((ATOM_ROM_HEADER *)MasterTableOffset)->usMasterDataTableOffset + pDeviceData->pBIOS_Image ); 102209ff23fSmrg MasterTableOffset =(UINT16 *) &(((ATOM_MASTER_DATA_TABLE *)MasterTableOffset)->ListOfDataTables); 103209ff23fSmrg#else 104209ff23fSmrg MasterTableOffset = (UINT16 *)(&(GetDataMasterTable( )->ListOfDataTables)); 105209ff23fSmrg#endif 106209ff23fSmrg return MasterTableOffset; 107209ff23fSmrg} 108209ff23fSmrg 109209ff23fSmrg 110209ff23fSmrgUINT8 GetTrueIndexInMasterTable(PARSER_TEMP_DATA STACK_BASED * pParserTempData, UINT8 IndexInMasterTable) 111209ff23fSmrg{ 112209ff23fSmrg#ifndef DISABLE_EASF 113209ff23fSmrg UINT16 i; 114209ff23fSmrg if ( pParserTempData->pDeviceData->format == TABLE_FORMAT_EASF) 115209ff23fSmrg { 116209ff23fSmrg/* 117209ff23fSmrg Consider EASF_ASIC_SETUP_TABLE structure pointed by pParserTempData->pCmd as UINT16[] 118209ff23fSmrg ((UINT16*)pParserTempData->pCmd)[0] = EASF_ASIC_SETUP_TABLE.usSize; 119209ff23fSmrg ((UINT16*)pParserTempData->pCmd)[1+n*4] = usFunctionID; 120209ff23fSmrg usFunctionID has to be shifted left by 2 before compare it to the value provided by caller. 121209ff23fSmrg*/ 122209ff23fSmrg for (i=1; (i < ((UINT16*)pParserTempData->pCmd)[0] >> 1);i+=4) 123209ff23fSmrg if ((UINT8)(((UINT16*)pParserTempData->pCmd)[i] << 2)==(IndexInMasterTable & EASF_TABLE_INDEX_MASK)) return (i+1+(IndexInMasterTable & EASF_TABLE_ATTR_MASK)); 124209ff23fSmrg return 1; 125209ff23fSmrg } else 126209ff23fSmrg#endif 127209ff23fSmrg { 128209ff23fSmrg return IndexInMasterTable; 129209ff23fSmrg } 130209ff23fSmrg} 131209ff23fSmrg 132209ff23fSmrgCD_STATUS ParseTable(DEVICE_DATA STACK_BASED* pDeviceData, UINT8 IndexInMasterTable) 133209ff23fSmrg{ 134209ff23fSmrg PARSER_TEMP_DATA ParserTempData; 135209ff23fSmrg WORKING_TABLE_DATA STACK_BASED* prevWorkingTableData; 136209ff23fSmrg 137209ff23fSmrg ParserTempData.pDeviceData=(DEVICE_DATA*)pDeviceData; 138209ff23fSmrg#ifndef DISABLE_EASF 139209ff23fSmrg if (pDeviceData->format == TABLE_FORMAT_EASF) 140209ff23fSmrg { 141209ff23fSmrg ParserTempData.IndirectIOTablePointer = 0; 142209ff23fSmrg } else 143209ff23fSmrg#endif 144209ff23fSmrg { 145209ff23fSmrg ParserTempData.pCmd=(GENERIC_ATTRIBUTE_COMMAND*)GetDataMasterTablePointer(pDeviceData); 146209ff23fSmrg ParserTempData.IndirectIOTablePointer=(UINT8*)((ULONG)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[INDIRECT_IO_TABLE]) + pDeviceData->pBIOS_Image); 147209ff23fSmrg ParserTempData.IndirectIOTablePointer+=sizeof(ATOM_COMMON_TABLE_HEADER); 148209ff23fSmrg } 149209ff23fSmrg 150209ff23fSmrg ParserTempData.pCmd=(GENERIC_ATTRIBUTE_COMMAND*)GetCommandMasterTablePointer(pDeviceData); 151209ff23fSmrg IndexInMasterTable=GetTrueIndexInMasterTable((PARSER_TEMP_DATA STACK_BASED *)&ParserTempData,IndexInMasterTable); 152209ff23fSmrg if(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]!=0 ) // if the offset is not ZERO 153209ff23fSmrg { 154209ff23fSmrg ParserTempData.CommandSpecific.IndexInMasterTable=IndexInMasterTable; 155209ff23fSmrg ParserTempData.Multipurpose.CurrentPort=ATI_RegsPort; 156209ff23fSmrg ParserTempData.CurrentPortID=INDIRECT_IO_MM; 157209ff23fSmrg ParserTempData.CurrentRegBlock=0; 158209ff23fSmrg ParserTempData.CurrentFB_Window=0; 159209ff23fSmrg prevWorkingTableData=NULL; 160209ff23fSmrg ParserTempData.Status=CD_CALL_TABLE; 161209ff23fSmrg 162209ff23fSmrg do{ 163209ff23fSmrg 164209ff23fSmrg if (ParserTempData.Status==CD_CALL_TABLE) 165209ff23fSmrg { 166209ff23fSmrg IndexInMasterTable=ParserTempData.CommandSpecific.IndexInMasterTable; 167209ff23fSmrg if(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]!=0) // if the offset is not ZERO 168209ff23fSmrg { 169209ff23fSmrg#ifndef UEFI_BUILD 170209ff23fSmrg ParserTempData.pWorkingTableData =(WORKING_TABLE_DATA STACK_BASED*) AllocateWorkSpace(pDeviceData, 171209ff23fSmrg ((ATOM_COMMON_ROM_COMMAND_TABLE_HEADER*)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]+pDeviceData->pBIOS_Image))->TableAttribute.WS_SizeInBytes+sizeof(WORKING_TABLE_DATA)); 172209ff23fSmrg#else 173209ff23fSmrg ParserTempData.pWorkingTableData =(WORKING_TABLE_DATA STACK_BASED*) AllocateWorkSpace(pDeviceData, 174209ff23fSmrg ((ATOM_COMMON_ROM_COMMAND_TABLE_HEADER*)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]))->TableAttribute.WS_SizeInBytes+sizeof(WORKING_TABLE_DATA)); 175209ff23fSmrg#endif 176209ff23fSmrg if (ParserTempData.pWorkingTableData!=NULL) 177209ff23fSmrg { 178209ff23fSmrg ParserTempData.pWorkingTableData->pWorkSpace=(WORKSPACE_POINTER STACK_BASED*)((UINT8*)ParserTempData.pWorkingTableData+sizeof(WORKING_TABLE_DATA)); 179209ff23fSmrg#ifndef UEFI_BUILD 180209ff23fSmrg ParserTempData.pWorkingTableData->pTableHead = (UINT8 *)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]+pDeviceData->pBIOS_Image); 181209ff23fSmrg#else 182209ff23fSmrg ParserTempData.pWorkingTableData->pTableHead = (UINT8 *)(((PTABLE_UNIT_TYPE)ParserTempData.pCmd)[IndexInMasterTable]); 183209ff23fSmrg#endif 184209ff23fSmrg ParserTempData.pWorkingTableData->IP=((UINT8*)ParserTempData.pWorkingTableData->pTableHead)+sizeof(ATOM_COMMON_ROM_COMMAND_TABLE_HEADER); 185209ff23fSmrg ParserTempData.pWorkingTableData->prevWorkingTableData=prevWorkingTableData; 186209ff23fSmrg prevWorkingTableData=ParserTempData.pWorkingTableData; 187209ff23fSmrg ParserTempData.Status = CD_SUCCESS; 188209ff23fSmrg } else ParserTempData.Status = CD_UNEXPECTED_BEHAVIOR; 189209ff23fSmrg } else ParserTempData.Status = CD_EXEC_TABLE_NOT_FOUND; 190209ff23fSmrg } 191209ff23fSmrg if (!CD_ERROR(ParserTempData.Status)) 192209ff23fSmrg { 193209ff23fSmrg ParserTempData.Status = CD_SUCCESS; 194209ff23fSmrg while (!CD_ERROR_OR_COMPLETED(ParserTempData.Status)) 195209ff23fSmrg { 196209ff23fSmrg 197209ff23fSmrg if (IS_COMMAND_VALID(((COMMAND_HEADER*)ParserTempData.pWorkingTableData->IP)->Opcode)) 198209ff23fSmrg { 199209ff23fSmrg ParserTempData.pCmd = (GENERIC_ATTRIBUTE_COMMAND*)ParserTempData.pWorkingTableData->IP; 200209ff23fSmrg 201209ff23fSmrg if (IS_END_OF_TABLE(((COMMAND_HEADER*)ParserTempData.pWorkingTableData->IP)->Opcode)) 202209ff23fSmrg { 203209ff23fSmrg ParserTempData.Status=CD_COMPLETED; 204209ff23fSmrg prevWorkingTableData=ParserTempData.pWorkingTableData->prevWorkingTableData; 205209ff23fSmrg 206209ff23fSmrg FreeWorkSpace(pDeviceData, ParserTempData.pWorkingTableData); 207209ff23fSmrg ParserTempData.pWorkingTableData=prevWorkingTableData; 208209ff23fSmrg if (prevWorkingTableData!=NULL) 209209ff23fSmrg { 210209ff23fSmrg ParserTempData.pDeviceData->pParameterSpace-= 211209ff23fSmrg (((ATOM_COMMON_ROM_COMMAND_TABLE_HEADER*)ParserTempData.pWorkingTableData-> 212209ff23fSmrg pTableHead)->TableAttribute.PS_SizeInBytes>>2); 213209ff23fSmrg } 214209ff23fSmrg // if there is a parent table where to return, then restore PS_pointer to the original state 215209ff23fSmrg } 216209ff23fSmrg else 217209ff23fSmrg { 218209ff23fSmrg IndexInMasterTable=ProcessCommandProperties((PARSER_TEMP_DATA STACK_BASED *)&ParserTempData); 219209ff23fSmrg (*CallTable[IndexInMasterTable].function)((PARSER_TEMP_DATA STACK_BASED *)&ParserTempData); 220209ff23fSmrg#if (PARSER_TYPE!=DRIVER_TYPE_PARSER) 221209ff23fSmrg BIOS_STACK_MODIFIER(); 222209ff23fSmrg#endif 223209ff23fSmrg } 224209ff23fSmrg } 225209ff23fSmrg else 226209ff23fSmrg { 227209ff23fSmrg ParserTempData.Status=CD_INVALID_OPCODE; 228209ff23fSmrg break; 229209ff23fSmrg } 230209ff23fSmrg 231209ff23fSmrg } // while 232209ff23fSmrg } // if 233209ff23fSmrg else 234209ff23fSmrg break; 235209ff23fSmrg } while (prevWorkingTableData!=NULL); 236209ff23fSmrg if (ParserTempData.Status == CD_COMPLETED) return CD_SUCCESS; 237209ff23fSmrg return ParserTempData.Status; 238209ff23fSmrg } else return CD_SUCCESS; 239209ff23fSmrg} 240209ff23fSmrg 241209ff23fSmrg// EOF 242209ff23fSmrg 243