{-# LINE 1 "src/System/LibCPUID/CPUID.hsc" #-}
module System.LibCPUID.CPUID
(
CPUID(..), cpuid
, isCPUIDPresent
) where
import Foreign.C.String (peekCString)
import Foreign.C.Types (CInt(..), CUChar(..))
import Foreign.Marshal (advancePtr, allocaBytes)
import Foreign.Ptr (Ptr, castPtr, plusPtr)
import Foreign.Storable (Storable(..))
data CPUID = CPUID
{ vendorString :: String
, brandString :: String
, hasTSC :: Bool
, physicalCores :: Int
, logicalCores :: Int
, totalLogicalCores :: Int
}
instance Storable CPUID where
alignment _ = 8
{-# LINE 63 "src/System/LibCPUID/CPUID.hsc" #-}
sizeOf _ = (432)
{-# LINE 64 "src/System/LibCPUID/CPUID.hsc" #-}
peek ptr = do
vendorString <- peekCString $ plusPtr ptr (0)
{-# LINE 66 "src/System/LibCPUID/CPUID.hsc" #-}
brandString <- peekCString $ plusPtr ptr (16)
{-# LINE 67 "src/System/LibCPUID/CPUID.hsc" #-}
hasTSC <-
let ptr' = advancePtr (castPtr @CPUID @CUChar ptr) 4
{-# LINE 69 "src/System/LibCPUID/CPUID.hsc" #-}
in (/= 0) <$> peekElemOff ptr' (84)
{-# LINE 70 "src/System/LibCPUID/CPUID.hsc" #-}
physicalCores <- fromIntegral @CInt <$> (\hsc_ptr -> peekByteOff hsc_ptr 232) ptr
{-# LINE 71 "src/System/LibCPUID/CPUID.hsc" #-}
logicalCores <- fromIntegral @CInt <$> (\hsc_ptr -> peekByteOff hsc_ptr 236) ptr
{-# LINE 72 "src/System/LibCPUID/CPUID.hsc" #-}
totalLogicalCores <- fromIntegral @CInt <$> (\hsc_ptr -> peekByteOff hsc_ptr 240) ptr
{-# LINE 73 "src/System/LibCPUID/CPUID.hsc" #-}
pure CPUID {..}
poke _ _ = error "CPUID is read-only"
cpuid :: IO (Either String CPUID)
cpuid = do
allocaBytes (1344) \cpu_raw_data_t_ptr -> do
{-# LINE 81 "src/System/LibCPUID/CPUID.hsc" #-}
res <- c_cpuid_get_raw_data cpu_raw_data_t_ptr
case toMaybeError res of
Just err -> pure $ Left err
Nothing ->
allocaBytes (432) \cpu_id_t_ptr -> do
{-# LINE 86 "src/System/LibCPUID/CPUID.hsc" #-}
res' <- c_cpu_identify cpu_raw_data_t_ptr cpu_id_t_ptr
case toMaybeError res' of
Just err -> pure $ Left err
Nothing -> Right <$> peek cpu_id_t_ptr
foreign import ccall "cpuid_get_raw_data"
c_cpuid_get_raw_data :: Ptr cpu_raw_data_t -> IO CInt
foreign import ccall "cpu_identify"
c_cpu_identify :: Ptr cpu_raw_data_r -> Ptr cpu_id_t -> IO CInt
toMaybeError :: CInt -> Maybe String
toMaybeError = \case
0 -> Nothing
{-# LINE 100 "src/System/LibCPUID/CPUID.hsc" #-}
err -> Just
case err of
-1 -> "CPUID instruction is not supported"
{-# LINE 103 "src/System/LibCPUID/CPUID.hsc" #-}
-2 -> "RDTSC instruction is not supported"
{-# LINE 104 "src/System/LibCPUID/CPUID.hsc" #-}
-3 -> "Memory allocation failed"
{-# LINE 105 "src/System/LibCPUID/CPUID.hsc" #-}
-4 -> "File open operation failed"
{-# LINE 106 "src/System/LibCPUID/CPUID.hsc" #-}
-5 -> "Bad file format"
{-# LINE 107 "src/System/LibCPUID/CPUID.hsc" #-}
-6 -> "Not implemented"
{-# LINE 108 "src/System/LibCPUID/CPUID.hsc" #-}
-7 -> "Unsupported processor"
{-# LINE 109 "src/System/LibCPUID/CPUID.hsc" #-}
-8 -> "RDMSR instruction is not supported"
{-# LINE 110 "src/System/LibCPUID/CPUID.hsc" #-}
-9 -> "RDMSR driver error (generic)"
{-# LINE 111 "src/System/LibCPUID/CPUID.hsc" #-}
-10 -> "No permissions to install RDMSR driver"
{-# LINE 112 "src/System/LibCPUID/CPUID.hsc" #-}
-11 -> "Cannot extract RDMSR driver (read only media?)"
{-# LINE 113 "src/System/LibCPUID/CPUID.hsc" #-}
-12 -> "Bad handle"
{-# LINE 114 "src/System/LibCPUID/CPUID.hsc" #-}
-13 -> "Invalid MSR"
{-# LINE 115 "src/System/LibCPUID/CPUID.hsc" #-}
-14 -> "Invalid core number"
{-# LINE 116 "src/System/LibCPUID/CPUID.hsc" #-}
-15 -> "Error on handle read"
{-# LINE 117 "src/System/LibCPUID/CPUID.hsc" #-}
-16 -> "Invalid given range"
{-# LINE 118 "src/System/LibCPUID/CPUID.hsc" #-}
_ -> "Unknown error"
isCPUIDPresent :: IO Bool
isCPUIDPresent = (== 1) <$> c_cpuid_present
foreign import ccall "cpuid_present"
c_cpuid_present :: IO CInt