packages feed

cpu (empty) → 0.1.0

raw patch · 10 files changed

+421/−0 lines, 10 filesdep +basedep +bytestringdep +cpusetup-changed

Dependencies added: base, bytestring, cpu

Files

+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2012 Vincent Hanquez <vincent@snarc.org>++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of his contributors+   may be used to endorse or promote products derived from this software+   without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,8 @@+Cpu haskell library+===================++The library provides access to property and information helpers related to the cpu:++* Endianness+* Architecture+* Cpuid (for x86 and x86\_64)
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ System/Arch.hs view
@@ -0,0 +1,66 @@+{-# LANGUAGE CPP #-}+-- |+-- Module      : System.Arch+-- License     : BSD-style+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>+-- Stability   : experimental+-- Portability : unknown+--+module System.Arch+    ( Arch(..)+    , getSystemArch+    ) where++-- | List of all cpu architecture+data Arch = X86+          | X86_64+          | PPC+          | PPC64+          | Sparc+          | Arm+          | Mips+          | SH+          | IA64+          | S390+          | Alpha+          | Hppa+          | Rs6000+          | M68K+          | VAX+          deriving (Show,Eq)++-- | Return the system's cpu architecture+getSystemArch :: Arch+#if defined(ARCH_X86)+getSystemArch = X86+#elif defined(ARCH_X86_64)+getSystemArch = X86_64+#elif defined(ARCH_PPC)+getSystemArch = PPC+#elif defined(ARCH_PPC64)+getSystemArch = PPC64+#elif defined(ARCH_SPARC)+getSystemArch = Sparc+#elif defined(ARCH_ARM)+getSystemArch = Arm+#elif defined(ARCH_MIPS)+getSystemArch = Mips+#elif defined(ARCH_SH)+getSystemArch = SH+#elif defined(ARCH_IA64)+getSystemArch = IA64+#elif defined(ARCH_S390)+getSystemArch = S390+#elif defined(ARCH_ALPHA)+getSystemArch = Alpha+#elif defined(ARCH_HPPA)+getSystemArch = Hppa+#elif defined(ARCH_RS6000)+getSystemArch = Rs6000+#elif defined(ARCH_M68K)+getSystemArch = M68K+#elif defined(ARCH_VAX)+getSystemArch = VAX+#else+getSystemArch = undefined+#endif
+ System/Cpuid.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE CPP #-}+-- |+-- Module      : System.Cpuid+-- License     : BSD-style+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>+-- Stability   : experimental+-- Portability : unknown+--+module System.Cpuid+    ( cpuidWithIndex+    , cpuid+    ) where++import Data.Word+import Control.Applicative+import Foreign.C.Types+import Foreign.Ptr+import Foreign.Storable+import Foreign.Marshal.Alloc++#if defined(ARCH_X86) || defined(ARCH_X86_64)++foreign import ccall safe "cpuid" c_cpuid :: CUInt -> CUInt -> Ptr CUInt -> IO ()++-- | complete cpuid call with eax and ecx set.+cpuidWithIndex :: Word32 -> Word32 -> IO (Word32, Word32, Word32, Word32)+cpuidWithIndex eax ecx = allocaBytes 16 $ \ptr -> do+    c_cpuid (fromIntegral eax) (fromIntegral ecx) ptr+    (,,,) <$> peekW32 ptr <*> peekW32 (ptr `plusPtr` 4) <*> peekW32 (ptr `plusPtr` 8) <*> peekW32 (ptr `plusPtr` 12)+    where peekW32 :: Ptr CUInt -> IO Word32+          peekW32 ptr = fromIntegral <$> peek ptr++#else++cpuidWithIndex :: Word32 -> Word32 -> IO (Word32, Word32, Word32, Word32)+cpuidWithIndex _ _ = error "cpuid is not supported on non-x86 architecture"++#endif++-- | simple cpuid call.+cpuid :: Word32 -> IO (Word32, Word32, Word32, Word32)+cpuid eax = cpuidWithIndex eax 0
+ System/Endian.hs view
@@ -0,0 +1,95 @@+{-# LANGUAGE CPP, ForeignFunctionInterface #-}+-- |+-- Module      : System.Endian+-- License     : BSD-style+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>+-- Stability   : experimental+-- Portability : unknown+--+module System.Endian+    ( Endianness(..)+    , getSystemEndianness+    -- little endian to and from cpu+    , fromLE32+    , fromLE64+    , toLE32+    , toLE64+    -- big endian to and from cpu+    , fromBE32+    , fromBE64+    , toBE32+    , toBE64+    ) where++import Foreign.Marshal.Alloc+import Foreign.Storable+import Foreign.Ptr+import Foreign.C.Types+import System.IO.Unsafe (unsafePerformIO)+import Data.Word++-- | represent the CPU endianness+--+-- Big endian system stores bytes with the MSB as the first byte.+-- Little endian system stores bytes with the LSB as the first byte.+--+-- middle endian is purposely avoided.+data Endianness = LittleEndian+                | BigEndian+                deriving (Show,Eq)++-- | return the system endianness+getSystemEndianness :: Endianness+getSystemEndianness = unsafePerformIO $ alloca $ \p ->+    poke p cst >> peek (castPtr p) >>= return . check+    where cst :: Word32+          cst = 0x01000000+          check :: Word8 -> Endianness+          check x+              | x == 0x01 = BigEndian +              | otherwise = LittleEndian++-- | Convert from a big endian 64 bit value to the cpu endianness+fromBE64 :: Word64 -> Word64+fromBE64 = if getSystemEndianness == BigEndian then id else swap64++-- | Convert from a little endian 64 bit value to the cpu endianness+fromLE64 :: Word64 -> Word64+fromLE64 = if getSystemEndianness == LittleEndian then id else swap64++-- | Convert from a big endian 32 bit value to the cpu endianness+fromBE32 :: Word32 -> Word32+fromBE32 = if getSystemEndianness == BigEndian then id else swap32++-- | Convert from a little endian 32 bit value to the cpu endianness+fromLE32 :: Word32 -> Word32+fromLE32 = if getSystemEndianness == LittleEndian then id else swap32++-- | Convert a 64 bit value in cpu endianess to big endian+toBE64 :: Word64 -> Word64+toBE64 = fromBE64++-- | Convert a 64 bit value in cpu endianess to little endian+toLE64 :: Word64 -> Word64+toLE64 = fromLE64++-- | Convert a 32 bit value in cpu endianess to big endian+toBE32 :: Word32 -> Word32+toBE32 = fromBE32++-- | Convert a 32 bit value in cpu endianess to little endian+toLE32 :: Word32 -> Word32+toLE32 = fromLE32++-- | Transform a 32 bit value bytes from a.b.c.d to d.c.b.a+{-# INLINE swap32 #-}+swap32 :: Word32 -> Word32+swap32 = fromIntegral . c_swap32 . fromIntegral++-- | Transform a 64 bit value bytes from a.b.c.d.e.f.g.h to h.g.f.e.d.c.b.a+{-# INLINE swap64 #-}+swap64 :: Word64 -> Word64+swap64 = fromIntegral . c_swap64 . fromIntegral++foreign import ccall safe "bitfn_swap32" c_swap32 :: CUInt -> CUInt+foreign import ccall safe "bitfn_swap64" c_swap64 :: CULLong -> CULLong
+ cbits/cpuid.c view
@@ -0,0 +1,29 @@+#include <stdint.h>++void cpuid(uint32_t eax, uint32_t ecx, uint32_t regs[4])+{+	asm volatile (+#ifdef __i386__+		"push %%ebx\n\t"+		"push %%edx\n\t"+#else+		"push %%rbx\n\t"+		"push %%rdx\n\t"+#endif+		"cpuid\n\t"+		"mov %%eax,(%4)\n\t"+		"mov %%ebx,4(%4)\n\t"+		"mov %%ecx,8(%4)\n\t"+		"mov %%edx,12(%4)\n\t"+#ifdef __i386__+		"pop %%edx\n\t"+		"pop %%ebx\n\t"+#else+		"pop %%rdx\n\t"+		"pop %%rbx\n\t"+#endif+		: "=a" (eax), "=c" (ecx)+		: "0" (eax), "1" (ecx), "S" (regs)+		: "memory"+	);+}
+ cbits/endian.c view
@@ -0,0 +1,54 @@+#include <stdint.h>++#if (defined(__i386__))+#  define ARCH_HAS_SWAP32+uint32_t bitfn_swap32(uint32_t a)+{+	asm ("bswap %0" : "=r" (a) : "0" (a));+	return a;+}+/**********************************************************/+# elif (defined(__arm__))+#  define ARCH_HAS_SWAP32+uint32_t bitfn_swap32(uint32_t a)+{+	uint32_t tmp = a;+	asm volatile ("eor %1, %0, %0, ror #16\n"+	              "bic %1, %1, #0xff0000\n"+	              "mov %0, %0, ror #8\n"+	              "eor %0, %0, %1, lsr #8\n"+	              : "=r" (a), "=r" (tmp) : "0" (a), "1" (tmp));+	return a;+}+/**********************************************************/+# elif defined(__x86_64__)+#  define ARCH_HAS_SWAP32+#  define ARCH_HAS_SWAP64+uint32_t bitfn_swap32(uint32_t a)+{+	asm ("bswap %0" : "=r" (a) : "0" (a));+	return a;+}++uint64_t bitfn_swap64(uint64_t a)+{+	asm ("bswap %0" : "=r" (a) : "0" (a));+	return a;+}++# endif++#ifndef ARCH_HAS_SWAP32+uint32_t bitfn_swap32(uint32_t a)+{+	return (a << 24) | ((a & 0xff00) << 8) | ((a >> 8) & 0xff00) | (a >> 24);+}+#endif++#ifndef ARCH_HAS_SWAP64+uint64_t bitfn_swap64(uint64_t a)+{+	return ((uint64_t) bitfn_swap32((uint32_t) (a >> 32))) |+	        (((uint64_t) bitfn_swap32((uint32_t) a)) << 32);+}+#endif
+ cpu.cabal view
@@ -0,0 +1,79 @@+Name:                cpu+Version:             0.1.0+Description:         +    Lowlevel cpu routines to get basic properties of the cpu platform, like endianness and architecture.+License:             BSD3+License-file:        LICENSE+Copyright:           Vincent Hanquez <vincent@snarc.org>+Author:              Vincent Hanquez <vincent@snarc.org>+Maintainer:          Vincent Hanquez <vincent@snarc.org>+Synopsis:            Cpu information and properties helpers.+Build-Type:          Simple+Category:            Data+stability:           experimental+Cabal-Version:       >=1.8+Homepage:            http://github.com/vincenthz/hs-cpu+data-files:          README.md++Flag executable+  Description:       Build the executable+  Default:           False++Library+  Build-Depends:     base >= 3 && < 5+  Exposed-modules:   System.Cpuid+                     System.Endian+                     System.Arch+  ghc-options:       -Wall++  C-sources:   cbits/endian.c++  if arch(i386)+    Cpp-options: -DARCH_X86+  if arch(x86_64)+    Cpp-options: -DARCH_X86_64+  if arch(ppc)+    Cpp-options: -DARCH_PPC+  if arch(ppc64)+    Cpp-options: -DARCH_PPC64+  if arch(sparc)+    Cpp-options: -DARCH_SPARC+  if arch(arm)+    Cpp-options: -DARCH_ARM+  if arch(mips)+    Cpp-options: -DARCH_MIPS+  if arch(sh)+    Cpp-options: -DARCH_SH+  if arch(ia64)+    Cpp-options: -DARCH_IA64+  if arch(s390)+    Cpp-options: -DARCH_S390+  if arch(alpha)+    Cpp-options: -DARCH_ALPHA+  if arch(hppa)+    Cpp-options: -DARCH_HPPA+  if arch(rs6000)+    Cpp-options: -DARCH_RS6000+  if arch(m68k)+    Cpp-options: -DARCH_M68K+  if arch(vax)+    Cpp-options: -DARCH_VAX++  if arch(i386) || arch(x86_64)+    C-sources:   cbits/cpuid.c++executable           cpuid+  hs-source-dirs:    cpuid+  Main-is:           Cpuid.hs+  if flag(executable)+    Buildable:       True+    Build-Depends:   base >= 3 && < 5+                   , cpu+                   , bytestring+  else+    Buildable:       False+  ghc-options:       -Wall -fno-warn-orphans -fno-warn-missing-signatures++source-repository head+  type: git+  location: git://github.com/vincenthz/hs-cpu
+ cpuid/Cpuid.hs view
@@ -0,0 +1,18 @@+module Main where++import System.Environment+import System.Cpuid+import Text.Printf++usage = do+    error "usage: cpuid <eax> [ecx]"++printResult (eax,ebx,ecx,edx) = do+    printf "%.8x %.8x %.8x %.8x\n" eax ebx ecx edx++main = do+    args <- getArgs+    case args of+        []        -> usage+        eax:[]    -> cpuid (read eax) >>= printResult+        eax:ecx:_ -> cpuidWithIndex (read eax) (read ecx) >>= printResult