+#----------------------------------------------------------------------------\r
+# EstablishStackFsp\r
+#\r
+# Following is the code copied from BYTFSP, need to figure out what it is doing..\r
+#\r
+#----------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(EstablishStackFsp)\r
+ASM_PFX(EstablishStackFsp):\r
+ #\r
+ # Save parameter pointer in edx \r
+ #\r
+ movl 4(%esp), %edx\r
+ \r
+ #\r
+ # Enable FSP STACK\r
+ #\r
+ movl PcdGet32(PcdTemporaryRamBase), %esp\r
+ addl PcdGet32(PcdTemporaryRamSize), %esp\r
+\r
+ pushl $DATA_LEN_OF_MCUD # Size of the data region\r
+ pushl $0x4455434D # Signature of the data region 'MCUD'\r
+ pushl 12(%edx) # Code size\r
+ pushl 8(%edx) # Code base\r
+ cmpl $0, %edx # Is parameter pointer valid ?\r
+ jz InvalidMicrocodeRegion\r
+ pushl 4(%edx) # Microcode size\r
+ pushl (%edx) # Microcode base\r
+ jmp EstablishStackFspExit\r
+\r
+InvalidMicrocodeRegion:\r
+ push $0 # Microcode size\r
+ push $0 # Microcode base\r
+ \r
+EstablishStackFspExit:\r
+ #\r
+ # Save API entry/exit timestamp into stack\r
+ #\r
+ pushl $DATA_LEN_OF_PER0 # Size of the data region\r
+ pushl $0x30524550 # Signature of the data region 'PER0'\r
+ movd %xmm4, %eax\r
+ pushl %eax\r
+ movd %xmm5, %eax\r
+ pushl %eax\r
+ rdtsc\r
+ pushl %edx\r
+ pushl %eax\r
+\r
+ #\r
+ # Terminator for the data on stack\r
+ # \r
+ push $0x00\r
+\r
+ #\r
+ # Set ECX/EDX to the bootloader temporary memory range\r
+ #\r
+ movl PcdGet32 (PcdTemporaryRamBase), %ecx\r
+ movl %ecx, %edx\r
+ addl PcdGet32 (PcdTemporaryRamSize), %edx\r
+ subl PcdGet32 (PcdFspTemporaryRamSize), %edx\r
+\r
+ xorl %eax, %eax\r
+ \r
+ movd %mm7, %esi #RET_ESI\r
+ jmp *%esi\r
+\r