--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2008-2009, Apple Inc. All rights reserved.\r
+ \r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+ \r
+#include <CpuDxe.h>\r
+\r
+\r
+EFI_EXCEPTION_CALLBACK gExceptionHandlers[0x100];\r
+\r
+\r
+/**\r
+ This function registers and enables the handler specified by InterruptHandler for a processor \r
+ interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the \r
+ handler for the processor interrupt or exception type specified by InterruptType is uninstalled. \r
+ The installed handler is called once for each processor interrupt or exception.\r
+\r
+ @param InterruptType A pointer to the processor's current interrupt state. Set to TRUE if interrupts\r
+ are enabled and FALSE if interrupts are disabled.\r
+ @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called\r
+ when a processor interrupt occurs. If this parameter is NULL, then the handler\r
+ will be uninstalled.\r
+\r
+ @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.\r
+ @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was\r
+ previously installed.\r
+ @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not\r
+ previously installed.\r
+ @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.\r
+\r
+**/\r
+EFI_STATUS\r
+RegisterInterruptHandler (\r
+ IN EFI_EXCEPTION_TYPE InterruptType,\r
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler\r
+ )\r
+{\r
+ if (InterruptType > 0xFF) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ if ((InterruptHandler == NULL) && (gExceptionHandlers[InterruptType] == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((InterruptHandler != NULL) && (gExceptionHandlers[InterruptType] != NULL)) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+\r
+ gExceptionHandlers[InterruptType] = InterruptHandler;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+\r
+VOID\r
+EFIAPI\r
+DefaultExceptionHandler (\r
+ IN EFI_EXCEPTION_TYPE ExceptionType,\r
+ IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
+ )\r
+{\r
+ DEBUG ((EFI_D_ERROR, "Exception %d from %x\n", ExceptionType, SystemContext.SystemContextX64->Rip));\r
+ ASSERT (FALSE);\r
+\r
+ return;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+InitializeExceptions (\r
+ IN EFI_CPU_ARCH_PROTOCOL *Cpu\r
+ )\r
+{\r
+ // You need to initialize gExceptionHandlers[] to point to DefaultExceptionHandler()\r
+ // and write all the assembly to handle the interrupts.\r
+ ASSERT (FALSE);\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+\r
+\r
+/**\r
+ This function reads the processor timer specified by TimerIndex and returns it in TimerValue.\r
+\r
+ @param TimerIndex Specifies which processor timer is to be returned in TimerValue. This parameter\r
+ must be between 0 and NumberOfTimers-1.\r
+ @param TimerValue Pointer to the returned timer value.\r
+ @param TimerPeriod A pointer to the amount of time that passes in femtoseconds for each increment\r
+ of TimerValue.\r
+\r
+ @retval EFI_SUCCESS The processor timer value specified by TimerIndex was returned in TimerValue.\r
+ @retval EFI_DEVICE_ERROR An error occurred attempting to read one of the processor's timers.\r
+ @retval EFI_INVALID_PARAMETER TimerValue is NULL or TimerIndex is not valid.\r
+ @retval EFI_UNSUPPORTED The processor does not have any readable timers.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetTimerValue (\r
+ IN UINT32 TimerIndex,\r
+ OUT UINT64 *TimerValue,\r
+ OUT UINT64 *TimerPeriod OPTIONAL\r
+ )\r
+{\r
+ if (TimerValue == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ \r
+ if (TimerIndex == 0) {\r
+ *TimerValue = AsmReadTsc ();\r
+ if (TimerPeriod != NULL) {\r
+ //\r
+ // BugBug: Hard coded. Don't know how to do this generically\r
+ //\r
+ *TimerPeriod = 1000000000;\r
+ }\r
+ return EFI_SUCCESS;\r
+ }\r
+ return EFI_INVALID_PARAMETER;\r
+}\r
+\r
+\r
+/**\r
+ This function flushes the range of addresses from Start to Start+Length \r
+ from the processor's data cache. If Start is not aligned to a cache line \r
+ boundary, then the bytes before Start to the preceding cache line boundary \r
+ are also flushed. If Start+Length is not aligned to a cache line boundary, \r
+ then the bytes past Start+Length to the end of the next cache line boundary \r
+ are also flushed. The FlushType of EfiCpuFlushTypeWriteBackInvalidate must be \r
+ supported. If the data cache is fully coherent with all DMA operations, then \r
+ this function can just return EFI_SUCCESS. If the processor does not support \r
+ flushing a range of the data cache, then the entire data cache can be flushed.\r
+\r
+ @param Start The beginning physical address to flush from the processor's data\r
+ cache.\r
+ @param Length The number of bytes to flush from the processor's data cache. This\r
+ function may flush more bytes than Length specifies depending upon\r
+ the granularity of the flush operation that the processor supports.\r
+ @param FlushType Specifies the type of flush operation to perform.\r
+\r
+ @retval EFI_SUCCESS The address range from Start to Start+Length was flushed from\r
+ the processor's data cache.\r
+ @retval EFI_UNSUPPORTED The processor does not support the cache flush type specified\r
+ by FlushType.\r
+ @retval EFI_DEVICE_ERROR The address range from Start to Start+Length could not be flushed\r
+ from the processor's data cache.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FlushCpuDataCache (\r
+ IN EFI_PHYSICAL_ADDRESS Start,\r
+ IN UINT64 Length,\r
+ IN EFI_CPU_FLUSH_TYPE FlushType\r
+ )\r
+{\r
+ if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {\r
+ AsmWbinvd ();\r
+ return EFI_SUCCESS;\r
+ } else if (FlushType == EfiCpuFlushTypeInvalidate) {\r
+ AsmInvd (); \r
+ return EFI_SUCCESS;\r
+ } else {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+}\r
+\r
+\r
+\r
+\r