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