diff --git a/ChangeLog b/ChangeLog
index 8c5b05b..9923b5b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+04/14/2021 Release 8.0.0
+	* Fixed Bug #161: Accept arm64 as an alias for aarch64
+	* Fixed Bug #160: Add MIPS architecture support
+	* Fixed Bug #74: Add option to trace code paths to file
+	* Fixed Bug #157: Remove multiple checks for sestatus
+
+07/05/2020 Release 7.0.0
+	* Fixed Bug #133: CPU flags vary between runs on Mac OS X
+	* Fixed Bug #150: Change 'byte code' to 'machine code'
+	* Fixed Bug #128: Overhead from generating machine code throws off CPUID HZ
+	* Fixed Bug #136: On non BeOS systems, calling sysinfo may open GUI program
+	* Fixed Bug #138: Invalid escape sequences warn when building in Python 3.8
+	* Fixed Bug #147: Remove extended_model and extended_family fields
+	* Fixed Bug #146: CPUID family and model is wrong
+	* Fixed Bug #144: Cache fields should be full ints instead of kb strings
+
+06/11/2020 Release 6.0.0
+	* Fixed Bug #140: The get_cache function has swapped fields
+	* Fixed Bug #142: Remove empty and zeroed fields
+	* Fixed Bug #115: Missing data on Ryzen CPUs
+	* Fixed Bug #122: Rename fields to be more clear
+	* Fixed Bug #125: Add option to return --version
+ 	* Fixed Bug #126: Make test suite also check SELinux
+	* Fixed Bug #120: Make unit tests also test CPUID
+	* Fixed Bug #69: Add s390x support
+
 03/20/2019 Release 5.0.0
 	* Fixed Bug #117: Remove PyInstaller hacks
 	* Fixed Bug #108: Client script runs multiple times without __main__
diff --git a/LICENSE b/LICENSE
index 3f2a5ae..8a14f4b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2014-2019 Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
+Copyright (c) 2014-2021 Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
diff --git a/PKG-INFO b/PKG-INFO
index 8495ee5..79160ee 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: py-cpuinfo
-Version: 5.0.0
+Version: 8.0.0
 Summary: Get CPU info with pure Python 2 & 3
 Home-page: https://github.com/workhorsy/py-cpuinfo
 Author: Matthew Brennan Jones
diff --git a/cpuinfo/cpuinfo.py b/cpuinfo/cpuinfo.py
index b8fc7e5..3a2752d 100644
--- a/cpuinfo/cpuinfo.py
+++ b/cpuinfo/cpuinfo.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
-# Copyright (c) 2014-2019, Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
+# Copyright (c) 2014-2021 Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
 # Py-cpuinfo gets CPU info with pure Python 2 & 3
 # It uses the MIT License
 # It is hosted at: https://github.com/workhorsy/py-cpuinfo
@@ -25,29 +25,154 @@
 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-CPUINFO_VERSION = (5, 0, 0)
+CPUINFO_VERSION = (8, 0, 0)
+CPUINFO_VERSION_STRING = '.'.join([str(n) for n in CPUINFO_VERSION])
 
 import os, sys
 import platform
 import multiprocessing
 import ctypes
 
-try:
-	import _winreg as winreg
-except ImportError as err:
-	try:
-		import winreg
-	except ImportError as err:
-		pass
 
 IS_PY2 = sys.version_info[0] == 2
+CAN_CALL_CPUID_IN_SUBPROCESS = True
+
+g_trace = None
+
 
+class Trace(object):
+	def __init__(self, is_active, is_stored_in_string):
+		self._is_active = is_active
+		if not self._is_active:
+			return
+
+		from datetime import datetime
+
+		if IS_PY2:
+			from cStringIO import StringIO
+		else:
+			from io import StringIO
+
+		if is_stored_in_string:
+			self._output = StringIO()
+		else:
+			date = datetime.now().strftime("%Y-%m-%d_%H-%M-%S-%f")
+			self._output = open('cpuinfo_trace_{0}.trace'.format(date), 'w')
+
+		self._stdout = StringIO()
+		self._stderr = StringIO()
+		self._err = None
+
+	def header(self, msg):
+		if not self._is_active: return
+
+		from inspect import stack
+		frame = stack()[1]
+		file = frame[1]
+		line = frame[2]
+		self._output.write("{0} ({1} {2})\n".format(msg, file, line))
+		self._output.flush()
+
+	def success(self):
+		if not self._is_active: return
+
+		from inspect import stack
+		frame = stack()[1]
+		file = frame[1]
+		line = frame[2]
+
+		self._output.write("Success ... ({0} {1})\n\n".format(file, line))
+		self._output.flush()
+
+	def fail(self, msg):
+		if not self._is_active: return
+
+		from inspect import stack
+		frame = stack()[1]
+		file = frame[1]
+		line = frame[2]
+
+		if isinstance(msg, str):
+			msg = ''.join(['\t' + line for line in msg.split('\n')]) + '\n'
+
+			self._output.write(msg)
+			self._output.write("Failed ... ({0} {1})\n\n".format(file, line))
+			self._output.flush()
+		elif isinstance(msg, Exception):
+			from traceback import format_exc
+			err_string = format_exc()
+			self._output.write("\tFailed ... ({0} {1})\n".format(file, line))
+			self._output.write(''.join(['\t\t{0}\n'.format(n) for n in err_string.split('\n')]) + '\n')
+			self._output.flush()
+
+	def command_header(self, msg):
+		if not self._is_active: return
+
+		from inspect import stack
+		frame = stack()[3]
+		file = frame[1]
+		line = frame[2]
+		self._output.write("\t{0} ({1} {2})\n".format(msg, file, line))
+		self._output.flush()
+
+	def command_output(self, msg, output):
+		if not self._is_active: return
+
+		self._output.write("\t\t{0}\n".format(msg))
+		self._output.write(''.join(['\t\t\t{0}\n'.format(n) for n in output.split('\n')]) + '\n')
+		self._output.flush()
+
+	def keys(self, keys, info, new_info):
+		if not self._is_active: return
+
+		from inspect import stack
+		frame = stack()[2]
+		file = frame[1]
+		line = frame[2]
+
+		# List updated keys
+		self._output.write("\tChanged keys ({0} {1})\n".format(file, line))
+		changed_keys = [key for key in keys if key in info and key in new_info and info[key] != new_info[key]]
+		if changed_keys:
+			for key in changed_keys:
+				self._output.write('\t\t{0}: {1} to {2}\n'.format(key, info[key], new_info[key]))
+		else:
+			self._output.write('\t\tNone\n')
+
+		# List new keys
+		self._output.write("\tNew keys ({0} {1})\n".format(file, line))
+		new_keys = [key for key in keys if key in new_info and key not in info]
+		if new_keys:
+			for key in new_keys:
+				self._output.write('\t\t{0}: {1}\n'.format(key, new_info[key]))
+		else:
+			self._output.write('\t\tNone\n')
+
+		self._output.write('\n')
+		self._output.flush()
+
+	def write(self, msg):
+		if not self._is_active: return
+
+		self._output.write(msg + '\n')
+		self._output.flush()
+
+	def to_dict(self, info, is_fail):
+		return {
+		'output' : self._output.getvalue(),
+		'stdout' : self._stdout.getvalue(),
+		'stderr' : self._stderr.getvalue(),
+		'info' : info,
+		'err' : self._err,
+		'is_fail' : is_fail
+		}
 
 class DataSource(object):
 	bits = platform.architecture()[0]
 	cpu_count = multiprocessing.cpu_count()
 	is_windows = platform.system().lower() == 'windows'
-	raw_arch_string = platform.machine()
+	arch_string_raw = platform.machine()
+	uname_string_raw = platform.uname()[5]
 	can_cpuid = True
 
 	@staticmethod
@@ -85,7 +210,9 @@ class DataSource(object):
 
 	@staticmethod
 	def has_sysinfo():
-		return len(_program_paths('sysinfo')) > 0
+		uname = platform.system().strip().strip('"').strip("'").strip().lower()
+		is_beos = 'beos' in uname or 'haiku' in uname
+		return is_beos and len(_program_paths('sysinfo')) > 0
 
 	@staticmethod
 	def has_lscpu():
@@ -109,12 +236,8 @@ class DataSource(object):
 		return _run_and_get_stdout(['cpufreq-info'])
 
 	@staticmethod
-	def sestatus_allow_execheap():
-		return _run_and_get_stdout(['sestatus', '-b'], ['grep', '-i', '"allow_execheap"'])[1].strip().lower().endswith('on')
-
-	@staticmethod
-	def sestatus_allow_execmem():
-		return _run_and_get_stdout(['sestatus', '-b'], ['grep', '-i', '"allow_execmem"'])[1].strip().lower().endswith('on')
+	def sestatus_b():
+		return _run_and_get_stdout(['sestatus', '-b'])
 
 	@staticmethod
 	def dmesg_a():
@@ -158,38 +281,28 @@ class DataSource(object):
 
 	@staticmethod
 	def winreg_processor_brand():
-		key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"Hardware\Description\System\CentralProcessor\0")
-		processor_brand = winreg.QueryValueEx(key, "ProcessorNameString")[0]
-		winreg.CloseKey(key)
-		return processor_brand
+		processor_brand = _read_windows_registry_key(r"Hardware\Description\System\CentralProcessor\0", "ProcessorNameString")
+		return processor_brand.strip()
 
 	@staticmethod
-	def winreg_vendor_id():
-		key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"Hardware\Description\System\CentralProcessor\0")
-		vendor_id = winreg.QueryValueEx(key, "VendorIdentifier")[0]
-		winreg.CloseKey(key)
-		return vendor_id
+	def winreg_vendor_id_raw():
+		vendor_id_raw = _read_windows_registry_key(r"Hardware\Description\System\CentralProcessor\0", "VendorIdentifier")
+		return vendor_id_raw
 
 	@staticmethod
-	def winreg_raw_arch_string():
-		key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment")
-		raw_arch_string = winreg.QueryValueEx(key, "PROCESSOR_ARCHITECTURE")[0]
-		winreg.CloseKey(key)
-		return raw_arch_string
+	def winreg_arch_string_raw():
+		arch_string_raw = _read_windows_registry_key(r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", "PROCESSOR_ARCHITECTURE")
+		return arch_string_raw
 
 	@staticmethod
 	def winreg_hz_actual():
-		key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"Hardware\Description\System\CentralProcessor\0")
-		hz_actual = winreg.QueryValueEx(key, "~Mhz")[0]
-		winreg.CloseKey(key)
-		hz_actual = _to_hz_string(hz_actual)
+		hz_actual = _read_windows_registry_key(r"Hardware\Description\System\CentralProcessor\0", "~Mhz")
+		hz_actual = _to_decimal_string(hz_actual)
 		return hz_actual
 
 	@staticmethod
 	def winreg_feature_bits():
-		key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"Hardware\Description\System\CentralProcessor\0")
-		feature_bits = winreg.QueryValueEx(key, "FeatureSet")[0]
-		winreg.CloseKey(key)
+		feature_bits = _read_windows_registry_key(r"Hardware\Description\System\CentralProcessor\0", "FeatureSet")
 		return feature_bits
 
 
@@ -210,26 +323,56 @@ def _program_paths(program_name):
 def _run_and_get_stdout(command, pipe_command=None):
 	from subprocess import Popen, PIPE
 
+	p1, p2, stdout_output, stderr_output = None, None, None, None
+
+	g_trace.command_header('Running command "' + ' '.join(command) + '" ...')
+
+	# Run the command normally
 	if not pipe_command:
 		p1 = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
-		output = p1.communicate()[0]
-		if not IS_PY2:
-			output = output.decode(encoding='UTF-8')
-		return p1.returncode, output
+	# Run the command and pipe it into another command
 	else:
-		p1 = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
-		p2 = Popen(pipe_command, stdin=p1.stdout, stdout=PIPE, stderr=PIPE)
-		p1.stdout.close()
-		output = p2.communicate()[0]
-		if not IS_PY2:
-			output = output.decode(encoding='UTF-8')
-		return p2.returncode, output
+		p2 = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
+		p1 = Popen(pipe_command, stdin=p2.stdout, stdout=PIPE, stderr=PIPE)
+		p2.stdout.close()
+
+	# Get the stdout and stderr
+	stdout_output, stderr_output = p1.communicate()
+	if not IS_PY2:
+		stdout_output = stdout_output.decode(encoding='UTF-8')
+		stderr_output = stderr_output.decode(encoding='UTF-8')
+
+	# Send the result to the logger
+	g_trace.command_output('return code:', str(p1.returncode))
+	g_trace.command_output('stdout:', stdout_output)
+
+	# Return the return code and stdout
+	return p1.returncode, stdout_output
+
+def _read_windows_registry_key(key_name, field_name):
+	g_trace.command_header('Reading Registry key "{0}" field "{1}" ...'.format(key_name, field_name))
+
+	try:
+		import _winreg as winreg
+	except ImportError as err:
+		try:
+			import winreg
+		except ImportError as err:
+			pass
+
+	key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key_name)
+	value = winreg.QueryValueEx(key, field_name)[0]
+	winreg.CloseKey(key)
+	g_trace.command_output('value:', str(value))
+	return value
 
 # Make sure we are running on a supported system
 def _check_arch():
-	arch, bits = _parse_arch(DataSource.raw_arch_string)
-	if not arch in ['X86_32', 'X86_64', 'ARM_7', 'ARM_8', 'PPC_64']:
-		raise Exception("py-cpuinfo currently only works on X86 and some PPC and ARM CPUs.")
+	arch, bits = _parse_arch(DataSource.arch_string_raw)
+	if not arch in ['X86_32', 'X86_64', 'ARM_7', 'ARM_8',
+	               'PPC_64', 'S390X', 'MIPS_32', 'MIPS_64']:
+		raise Exception("py-cpuinfo currently only works on X86 "
+		                "and some ARM/PPC/S390X/MIPS CPUs.")
 
 def _obj_to_b64(thing):
 	import pickle
@@ -265,14 +408,18 @@ def _utf_to_str(input):
 
 def _copy_new_fields(info, new_info):
 	keys = [
-		'vendor_id', 'hardware', 'brand', 'hz_advertised', 'hz_actual',
-		'hz_advertised_raw', 'hz_actual_raw', 'arch', 'bits', 'count',
-		'raw_arch_string', 'l2_cache_size', 'l2_cache_line_size',
-		'l2_cache_associativity', 'stepping', 'model', 'family',
-		'processor_type', 'extended_model', 'extended_family', 'flags',
+		'vendor_id_raw', 'hardware_raw', 'brand_raw', 'hz_advertised_friendly', 'hz_actual_friendly',
+		'hz_advertised', 'hz_actual', 'arch', 'bits', 'count',
+		'arch_string_raw', 'uname_string_raw',
+		'l2_cache_size', 'l2_cache_line_size', 'l2_cache_associativity',
+		'stepping', 'model', 'family',
+		'processor_type', 'flags',
 		'l3_cache_size', 'l1_data_cache_size', 'l1_instruction_cache_size'
 	]
 
+	g_trace.keys(keys, info, new_info)
+
+	# Update the keys with new values
 	for key in keys:
 		if new_info.get(key, None) and not info.get(key, None):
 			info[key] = new_info[key]
@@ -314,88 +461,110 @@ def _get_field(cant_be_number, raw_string, convert_to, default_value, *field_nam
 
 	return retval
 
-def _get_hz_string_from_brand(processor_brand):
-	# Just return 0 if the processor brand does not have the Hz
-	if not 'hz' in processor_brand.lower():
-		return (1, '0.0')
-
-	hz_brand = processor_brand.lower()
-	scale = 1
-
-	if hz_brand.endswith('mhz'):
-		scale = 6
-	elif hz_brand.endswith('ghz'):
-		scale = 9
-	if '@' in hz_brand:
-		hz_brand = hz_brand.split('@')[1]
-	else:
-		hz_brand = hz_brand.rsplit(None, 1)[1]
-
-	hz_brand = hz_brand.rstrip('mhz').rstrip('ghz').strip()
-	hz_brand = _to_hz_string(hz_brand)
-
-	return (scale, hz_brand)
-
-def _to_friendly_hz(ticks, scale):
-	# Get the raw Hz as a string
-	left, right = _to_raw_hz(ticks, scale)
-	ticks = '{0}.{1}'.format(left, right)
-
-	# Get the location of the dot, and remove said dot
-	dot_index = ticks.index('.')
-	ticks = ticks.replace('.', '')
-
-	# Get the Hz symbol and scale
-	symbol = "Hz"
-	scale = 0
-	if dot_index > 9:
-		symbol = "GHz"
-		scale = 9
-	elif dot_index > 6:
-		symbol = "MHz"
-		scale = 6
-	elif dot_index > 3:
-		symbol = "KHz"
-		scale = 3
-
-	# Get the Hz with the dot at the new scaled point
-	ticks = '{0}.{1}'.format(ticks[:-scale-1], ticks[-scale-1:])
-
-	# Format the ticks to have 4 numbers after the decimal
-	# and remove any superfluous zeroes.
-	ticks = '{0:.4f} {1}'.format(float(ticks), symbol)
-	ticks = ticks.rstrip('0')
+def _to_decimal_string(ticks):
+	try:
+		# Convert to string
+		ticks = '{0}'.format(ticks)
+		# Sometimes ',' is used as a decimal separator
+		ticks = ticks.replace(',', '.')
+
+		# Strip off non numbers and decimal places
+		ticks = "".join(n for n in ticks if n.isdigit() or n=='.').strip()
+		if ticks == '':
+			ticks = '0'
+
+		# Add decimal if missing
+		if '.' not in ticks:
+			ticks = '{0}.0'.format(ticks)
+
+		# Remove trailing zeros
+		ticks = ticks.rstrip('0')
+
+		# Add one trailing zero for empty right side
+		if ticks.endswith('.'):
+			ticks = '{0}0'.format(ticks)
+
+		# Make sure the number can be converted to a float
+		ticks = float(ticks)
+		ticks = '{0}'.format(ticks)
+		return ticks
+	except:
+		return '0.0'
 
-	return ticks
+def _hz_short_to_full(ticks, scale):
+	try:
+		# Make sure the number can be converted to a float
+		ticks = float(ticks)
+		ticks = '{0}'.format(ticks)
+
+		# Scale the numbers
+		hz = ticks.lstrip('0')
+		old_index = hz.index('.')
+		hz = hz.replace('.', '')
+		hz = hz.ljust(scale + old_index+1, '0')
+		new_index = old_index + scale
+		hz = '{0}.{1}'.format(hz[:new_index], hz[new_index:])
+		left, right = hz.split('.')
+		left, right = int(left), int(right)
+		return (left, right)
+	except:
+		return (0, 0)
 
-def _to_raw_hz(ticks, scale):
-	# Scale the numbers
-	ticks = ticks.lstrip('0')
-	old_index = ticks.index('.')
-	ticks = ticks.replace('.', '')
-	ticks = ticks.ljust(scale + old_index+1, '0')
-	new_index = old_index + scale
-	ticks = '{0}.{1}'.format(ticks[:new_index], ticks[new_index:])
-	left, right = ticks.split('.')
-	left, right = int(left), int(right)
-	return (left, right)
+def _hz_friendly_to_full(hz_string):
+	try:
+		hz_string = hz_string.strip().lower()
+		hz, scale = (None, None)
 
-def _to_hz_string(ticks):
-	# Convert to string
-	ticks = '{0}'.format(ticks)
+		if hz_string.endswith('ghz'):
+			scale = 9
+		elif hz_string.endswith('mhz'):
+			scale = 6
+		elif hz_string.endswith('hz'):
+			scale = 0
 
-	# Add decimal if missing
-	if '.' not in ticks:
-		ticks = '{0}.0'.format(ticks)
+		hz = "".join(n for n in hz_string if n.isdigit() or n=='.').strip()
+		if not '.' in hz:
+			hz += '.0'
 
-	# Remove trailing zeros
-	ticks = ticks.rstrip('0')
+		hz, scale = _hz_short_to_full(hz, scale)
 
-	# Add one trailing zero for empty right side
-	if ticks.endswith('.'):
-		ticks = '{0}0'.format(ticks)
+		return (hz, scale)
+	except:
+		return (0, 0)
 
-	return ticks
+def _hz_short_to_friendly(ticks, scale):
+	try:
+		# Get the raw Hz as a string
+		left, right = _hz_short_to_full(ticks, scale)
+		result = '{0}.{1}'.format(left, right)
+
+		# Get the location of the dot, and remove said dot
+		dot_index = result.index('.')
+		result = result.replace('.', '')
+
+		# Get the Hz symbol and scale
+		symbol = "Hz"
+		scale = 0
+		if dot_index > 9:
+			symbol = "GHz"
+			scale = 9
+		elif dot_index > 6:
+			symbol = "MHz"
+			scale = 6
+		elif dot_index > 3:
+			symbol = "KHz"
+			scale = 3
+
+		# Get the Hz with the dot at the new scaled point
+		result = '{0}.{1}'.format(result[:-scale-1], result[-scale-1:])
+
+		# Format the ticks to have 4 numbers after the decimal
+		# and remove any superfluous zeroes.
+		result = '{0:.4f} {1}'.format(float(result), symbol)
+		result = result.rstrip('0')
+		return result
+	except:
+		return '0.0000 Hz'
 
 def _to_friendly_bytes(input):
 	import re
@@ -417,38 +586,68 @@ def _to_friendly_bytes(input):
 
 	return input
 
-def _parse_cpu_string(cpu_string):
-	# Get location of fields at end of string
-	fields_index = cpu_string.find('(', cpu_string.find('@'))
-	#print(fields_index)
+def _friendly_bytes_to_int(friendly_bytes):
+	input = friendly_bytes.lower()
 
-	# Processor Brand
-	processor_brand = cpu_string
-	if fields_index != -1:
-		processor_brand = cpu_string[0 : fields_index].strip()
-	#print('processor_brand: ', processor_brand)
+	formats = {
+		'gb' : 1024 * 1024 * 1024,
+		'mb' : 1024 * 1024,
+		'kb' : 1024,
+
+		'g' : 1024 * 1024 * 1024,
+		'm' : 1024 * 1024,
+		'k' : 1024,
+		'b' : 1,
+	}
 
-	fields = None
-	if fields_index != -1:
-		fields = cpu_string[fields_index : ]
-	#print('fields: ', fields)
+	try:
+		for pattern, multiplier in formats.items():
+			if input.endswith(pattern):
+				return int(input.split(pattern)[0].strip()) * multiplier
+
+	except Exception as err:
+		pass
 
-	# Hz
-	scale, hz_brand = _get_hz_string_from_brand(processor_brand)
+	return friendly_bytes
+
+def _parse_cpu_brand_string(cpu_string):
+	# Just return 0 if the processor brand does not have the Hz
+	if not 'hz' in cpu_string.lower():
+		return ('0.0', 0)
+
+	hz = cpu_string.lower()
+	scale = 0
 
-	# Various fields
+	if hz.endswith('mhz'):
+		scale = 6
+	elif hz.endswith('ghz'):
+		scale = 9
+	if '@' in hz:
+		hz = hz.split('@')[1]
+	else:
+		hz = hz.rsplit(None, 1)[1]
+
+	hz = hz.rstrip('mhz').rstrip('ghz').strip()
+	hz = _to_decimal_string(hz)
+
+	return (hz, scale)
+
+def _parse_cpu_brand_string_dx(cpu_string):
+	import re
+
+	# Find all the strings inside brackets ()
+	starts = [m.start() for m in re.finditer(r"\(", cpu_string)]
+	ends = [m.start() for m in re.finditer(r"\)", cpu_string)]
+	insides = {k: v for k, v in zip(starts, ends)}
+	insides = [cpu_string[start+1 : end] for start, end in insides.items()]
+
+	# Find all the fields
 	vendor_id, stepping, model, family = (None, None, None, None)
-	if fields:
-		try:
-			fields = fields.rsplit('(', 1)[1].split(')')[0].split(',')
-			fields = [f.strip().lower() for f in fields]
-			fields = [f.split(':') for f in fields]
-			fields = [{f[0].strip() : f[1].strip()} for f in fields]
-			#print('fields: ', fields)
-			for field in fields:
-				name = list(field.keys())[0]
-				value = list(field.values())[0]
-				#print('name:{0}, value:{1}'.format(name, value))
+	for inside in insides:
+		for pair in inside.split(','):
+			pair = [n.strip() for n in pair.split(':')]
+			if len(pair) > 1:
+				name, value = pair[0], pair[1]
 				if name == 'origin':
 					vendor_id = value.strip('"')
 				elif name == 'stepping':
@@ -457,11 +656,33 @@ def _parse_cpu_string(cpu_string):
 					model = int(value.lstrip('0x'), 16)
 				elif name in ['fam', 'family']:
 					family = int(value.lstrip('0x'), 16)
-		except:
-			#raise
-			pass
 
-	return (processor_brand, hz_brand, scale, vendor_id, stepping, model, family)
+	# Find the Processor Brand
+	# Strip off extra strings in brackets at end
+	brand = cpu_string.strip()
+	is_working = True
+	while is_working:
+		is_working = False
+		for inside in insides:
+			full = "({0})".format(inside)
+			if brand.endswith(full):
+				brand = brand[ :-len(full)].strip()
+				is_working = True
+
+	# Find the Hz in the brand string
+	hz_brand, scale = _parse_cpu_brand_string(brand)
+
+	# Find Hz inside brackets () after the brand string
+	if hz_brand == '0.0':
+		for inside in insides:
+			hz = inside
+			for entry in ['GHz', 'MHz', 'Hz']:
+				if entry in hz:
+					hz = "CPU @ " + hz[ : hz.find(entry) + len(entry)]
+					hz_brand, scale = _parse_cpu_brand_string(hz)
+					break
+
+	return (hz_brand, scale, brand, vendor_id, stepping, model, family)
 
 def _parse_dmesg_output(output):
 	try:
@@ -475,7 +696,7 @@ def _parse_dmesg_output(output):
 		lines = [l.split('\n')[0].strip() for l in lines]
 
 		# Convert the lines to CPU strings
-		cpu_strings = [_parse_cpu_string(l) for l in lines]
+		cpu_strings = [_parse_cpu_brand_string_dx(l) for l in lines]
 
 		# Find the CPU string that has the most fields
 		best_string = None
@@ -490,7 +711,7 @@ def _parse_dmesg_output(output):
 		if not best_string:
 			return {}
 
-		processor_brand, hz_actual, scale, vendor_id, stepping, model, family = best_string
+		hz_actual, scale, processor_brand, vendor_id, stepping, model, family = best_string
 
 		# Origin
 		if '  Origin=' in output:
@@ -498,11 +719,11 @@ def _parse_dmesg_output(output):
 			fields = fields.strip().split()
 			fields = [n.strip().split('=') for n in fields]
 			fields = [{n[0].strip().lower() : n[1].strip()} for n in fields]
-			#print('fields: ', fields)
+
 			for field in fields:
 				name = list(field.keys())[0]
 				value = list(field.values())[0]
-				#print('name:{0}, value:{1}'.format(name, value))
+
 				if name == 'origin':
 					vendor_id = value.strip('"')
 				elif name == 'stepping':
@@ -511,7 +732,6 @@ def _parse_dmesg_output(output):
 					model = int(value.lstrip('0x'), 16)
 				elif name in ['fam', 'family']:
 					family = int(value.lstrip('0x'), 16)
-		#print('FIELDS: ', (vendor_id, stepping, model, family))
 
 		# Features
 		flag_lines = []
@@ -527,11 +747,16 @@ def _parse_dmesg_output(output):
 		flags.sort()
 
 		# Convert from GHz/MHz string to Hz
-		scale, hz_advertised = _get_hz_string_from_brand(processor_brand)
+		hz_advertised, scale = _parse_cpu_brand_string(processor_brand)
+
+		# If advertised hz not found, use the actual hz
+		if hz_advertised == '0.0':
+			scale = 6
+			hz_advertised = _to_decimal_string(hz_actual)
 
 		info = {
-		'vendor_id' : vendor_id,
-		'brand' : processor_brand,
+		'vendor_id_raw' : vendor_id,
+		'brand_raw' : processor_brand,
 
 		'stepping' : stepping,
 		'model' : model,
@@ -540,57 +765,68 @@ def _parse_dmesg_output(output):
 		}
 
 		if hz_advertised and hz_advertised != '0.0':
-			info['hz_advertised'] = _to_friendly_hz(hz_advertised, scale)
-			info['hz_actual'] = _to_friendly_hz(hz_actual, scale)
+			info['hz_advertised_friendly'] = _hz_short_to_friendly(hz_advertised, scale)
+			info['hz_actual_friendly'] = _hz_short_to_friendly(hz_actual, scale)
 
 		if hz_advertised and hz_advertised != '0.0':
-			info['hz_advertised_raw'] = _to_raw_hz(hz_advertised, scale)
-			info['hz_actual_raw'] = _to_raw_hz(hz_actual, scale)
+			info['hz_advertised'] = _hz_short_to_full(hz_advertised, scale)
+			info['hz_actual'] = _hz_short_to_full(hz_actual, scale)
 
 		return {k: v for k, v in info.items() if v}
-	except:
+	except Exception as err:
+		g_trace.fail(err)
 		#raise
 		pass
 
 	return {}
 
-def _parse_arch(raw_arch_string):
+def _parse_arch(arch_string_raw):
 	import re
 
 	arch, bits = None, None
-	raw_arch_string = raw_arch_string.lower()
+	arch_string_raw = arch_string_raw.lower()
 
 	# X86
-	if re.match('^i\d86$|^x86$|^x86_32$|^i86pc$|^ia32$|^ia-32$|^bepc$', raw_arch_string):
+	if re.match(r'^i\d86$|^x86$|^x86_32$|^i86pc$|^ia32$|^ia-32$|^bepc$', arch_string_raw):
 		arch = 'X86_32'
 		bits = 32
-	elif re.match('^x64$|^x86_64$|^x86_64t$|^i686-64$|^amd64$|^ia64$|^ia-64$', raw_arch_string):
+	elif re.match(r'^x64$|^x86_64$|^x86_64t$|^i686-64$|^amd64$|^ia64$|^ia-64$', arch_string_raw):
 		arch = 'X86_64'
 		bits = 64
 	# ARM
-	elif re.match('^armv8-a|aarch64$', raw_arch_string):
+	elif re.match(r'^armv8-a|aarch64|arm64$', arch_string_raw):
 		arch = 'ARM_8'
 		bits = 64
-	elif re.match('^armv7$|^armv7[a-z]$|^armv7-[a-z]$|^armv6[a-z]$', raw_arch_string):
+	elif re.match(r'^armv7$|^armv7[a-z]$|^armv7-[a-z]$|^armv6[a-z]$', arch_string_raw):
 		arch = 'ARM_7'
 		bits = 32
-	elif re.match('^armv8$|^armv8[a-z]$|^armv8-[a-z]$', raw_arch_string):
+	elif re.match(r'^armv8$|^armv8[a-z]$|^armv8-[a-z]$', arch_string_raw):
 		arch = 'ARM_8'
 		bits = 32
 	# PPC
-	elif re.match('^ppc32$|^prep$|^pmac$|^powermac$', raw_arch_string):
+	elif re.match(r'^ppc32$|^prep$|^pmac$|^powermac$', arch_string_raw):
 		arch = 'PPC_32'
 		bits = 32
-	elif re.match('^powerpc$|^ppc64$|^ppc64le$', raw_arch_string):
+	elif re.match(r'^powerpc$|^ppc64$|^ppc64le$', arch_string_raw):
 		arch = 'PPC_64'
 		bits = 64
 	# SPARC
-	elif re.match('^sparc32$|^sparc$', raw_arch_string):
+	elif re.match(r'^sparc32$|^sparc$', arch_string_raw):
 		arch = 'SPARC_32'
 		bits = 32
-	elif re.match('^sparc64$|^sun4u$|^sun4v$', raw_arch_string):
+	elif re.match(r'^sparc64$|^sun4u$|^sun4v$', arch_string_raw):
 		arch = 'SPARC_64'
 		bits = 64
+	# S390X
+	elif re.match(r'^s390x$', arch_string_raw):
+		arch = 'S390X'
+		bits = 64
+	elif arch_string_raw == 'mips':
+		arch = 'MIPS_32'
+		bits = 32
+	elif arch_string_raw == 'mips64':
+		arch = 'MIPS_64'
+		bits = 64
 
 	return (arch, bits)
 
@@ -600,49 +836,93 @@ def _is_bit_set(reg, bit):
 	return is_set
 
 
-class CPUID(object):
-	def __init__(self):
-		self.prochandle = None
+def _is_selinux_enforcing(trace):
+	# Just return if the SE Linux Status Tool is not installed
+	if not DataSource.has_sestatus():
+		trace.fail('Failed to find sestatus.')
+		return False
+
+	# Run the sestatus, and just return if it failed to run
+	returncode, output = DataSource.sestatus_b()
+	if returncode != 0:
+		trace.fail('Failed to run sestatus. Skipping ...')
+		return False
+
+	# Figure out if explicitly in enforcing mode
+	for line in output.splitlines():
+		line = line.strip().lower()
+		if line.startswith("current mode:"):
+			if line.endswith("enforcing"):
+				return True
+			else:
+				return False
+
+	# Figure out if we can execute heap and execute memory
+	can_selinux_exec_heap = False
+	can_selinux_exec_memory = False
+	for line in output.splitlines():
+		line = line.strip().lower()
+		if line.startswith("allow_execheap") and line.endswith("on"):
+			can_selinux_exec_heap = True
+		elif line.startswith("allow_execmem") and line.endswith("on"):
+			can_selinux_exec_memory = True
+
+	trace.command_output('can_selinux_exec_heap:', can_selinux_exec_heap)
+	trace.command_output('can_selinux_exec_memory:', can_selinux_exec_memory)
+
+	return (not can_selinux_exec_heap or not can_selinux_exec_memory)
+
+def _filter_dict_keys_with_empty_values(info):
+	# Filter out None, 0, "", (), {}, []
+	info = {k: v for k, v in info.items() if v}
 
-		# Figure out if SE Linux is on and in enforcing mode
-		self.is_selinux_enforcing = False
+	# Filter out (0, 0)
+	info = {k: v for k, v in info.items() if v != (0, 0)}
+
+	# Filter out strings that start with "0.0"
+	info = {k: v for k, v in info.items() if not (type(v) == str and v.startswith('0.0'))}
+
+	return info
 
-		# Just return if the SE Linux Status Tool is not installed
-		if not DataSource.has_sestatus():
-			return
 
-		# Figure out if we can execute heap and execute memory
-		can_selinux_exec_heap = DataSource.sestatus_allow_execheap()
-		can_selinux_exec_memory = DataSource.sestatus_allow_execmem()
-		self.is_selinux_enforcing = (not can_selinux_exec_heap or not can_selinux_exec_memory)
+class ASM(object):
+	def __init__(self, restype=None, argtypes=(), machine_code=[]):
+		self.restype = restype
+		self.argtypes = argtypes
+		self.machine_code = machine_code
+		self.prochandle = None
+		self.mm = None
+		self.func = None
+		self.address = None
+		self.size = 0
 
-	def _asm_func(self, restype=None, argtypes=(), byte_code=[]):
-		byte_code = bytes.join(b'', byte_code)
-		address = None
+	def compile(self):
+		machine_code = bytes.join(b'', self.machine_code)
+		self.size = ctypes.c_size_t(len(machine_code))
 
 		if DataSource.is_windows:
-			# Allocate a memory segment the size of the byte code, and make it executable
-			size = len(byte_code)
+			# Allocate a memory segment the size of the machine code, and make it executable
+			size = len(machine_code)
 			# Alloc at least 1 page to ensure we own all pages that we want to change protection on
 			if size < 0x1000: size = 0x1000
 			MEM_COMMIT = ctypes.c_ulong(0x1000)
 			PAGE_READWRITE = ctypes.c_ulong(0x4)
 			pfnVirtualAlloc = ctypes.windll.kernel32.VirtualAlloc
 			pfnVirtualAlloc.restype = ctypes.c_void_p
-			address = pfnVirtualAlloc(None, ctypes.c_size_t(size), MEM_COMMIT, PAGE_READWRITE)
-			if not address:
+			self.address = pfnVirtualAlloc(None, ctypes.c_size_t(size), MEM_COMMIT, PAGE_READWRITE)
+			if not self.address:
 				raise Exception("Failed to VirtualAlloc")
 
-			# Copy the byte code into the memory segment
+			# Copy the machine code into the memory segment
 			memmove = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t)(ctypes._memmove_addr)
-			if memmove(address, byte_code, size) < 0:
+			if memmove(self.address, machine_code, size) < 0:
 				raise Exception("Failed to memmove")
 
 			# Enable execute permissions
 			PAGE_EXECUTE = ctypes.c_ulong(0x10)
 			old_protect = ctypes.c_ulong(0)
 			pfnVirtualProtect = ctypes.windll.kernel32.VirtualProtect
-			res = pfnVirtualProtect(ctypes.c_void_p(address), ctypes.c_size_t(size), PAGE_EXECUTE, ctypes.byref(old_protect))
+			res = pfnVirtualProtect(ctypes.c_void_p(self.address), ctypes.c_size_t(size), PAGE_EXECUTE, ctypes.byref(old_protect))
 			if not res:
 				raise Exception("Failed VirtualProtect")
 
@@ -653,86 +933,71 @@ class CPUID(object):
 				pfnGetCurrentProcess.restype = ctypes.c_void_p
 				self.prochandle = ctypes.c_void_p(pfnGetCurrentProcess())
 			# Actually flush cache
-			res = ctypes.windll.kernel32.FlushInstructionCache(self.prochandle, ctypes.c_void_p(address), ctypes.c_size_t(size))
+			res = ctypes.windll.kernel32.FlushInstructionCache(self.prochandle, ctypes.c_void_p(self.address), ctypes.c_size_t(size))
 			if not res:
 				raise Exception("Failed FlushInstructionCache")
 		else:
-			# Allocate a memory segment the size of the byte code
-			size = len(byte_code)
-			pfnvalloc = ctypes.pythonapi.valloc
-			pfnvalloc.restype = ctypes.c_void_p
-			address = pfnvalloc(ctypes.c_size_t(size))
-			if not address:
-				raise Exception("Failed to valloc")
-
-			# Mark the memory segment as writeable only
-			if not self.is_selinux_enforcing:
-				WRITE = 0x2
-				if ctypes.pythonapi.mprotect(ctypes.c_void_p(address), size, WRITE) < 0:
-					raise Exception("Failed to mprotect")
-
-			# Copy the byte code into the memory segment
-			if ctypes.pythonapi.memmove(ctypes.c_void_p(address), byte_code, ctypes.c_size_t(size)) < 0:
-				raise Exception("Failed to memmove")
+			from mmap import mmap, MAP_PRIVATE, MAP_ANONYMOUS, PROT_WRITE, PROT_READ, PROT_EXEC
 
-			# Mark the memory segment as writeable and executable only
-			if not self.is_selinux_enforcing:
-				WRITE_EXECUTE = 0x2 | 0x4
-				if ctypes.pythonapi.mprotect(ctypes.c_void_p(address), size, WRITE_EXECUTE) < 0:
-					raise Exception("Failed to mprotect")
+			# Allocate a private and executable memory segment the size of the machine code
+			machine_code = bytes.join(b'', self.machine_code)
+			self.size = len(machine_code)
+			self.mm = mmap(-1, self.size, flags=MAP_PRIVATE | MAP_ANONYMOUS, prot=PROT_WRITE | PROT_READ | PROT_EXEC)
 
-		# Cast the memory segment into a function
-		functype = ctypes.CFUNCTYPE(restype, *argtypes)
-		fun = functype(address)
-		return fun, address
+			# Copy the machine code into the memory segment
+			self.mm.write(machine_code)
+			self.address = ctypes.addressof(ctypes.c_int.from_buffer(self.mm))
 
-	def _run_asm(self, *byte_code):
-		# Convert the byte code into a function that returns an int
-		restype = ctypes.c_uint32
-		argtypes = ()
-		func, address = self._asm_func(restype, argtypes, byte_code)
+		# Cast the memory segment into a function
+		functype = ctypes.CFUNCTYPE(self.restype, *self.argtypes)
+		self.func = functype(self.address)
 
-		# Call the byte code like a function
-		retval = func()
+	def run(self):
+		# Call the machine code like a function
+		retval = self.func()
 
-		byte_code = bytes.join(b'', byte_code)
-		size = ctypes.c_size_t(len(byte_code))
+		return retval
 
+	def free(self):
 		# Free the function memory segment
 		if DataSource.is_windows:
 			MEM_RELEASE = ctypes.c_ulong(0x8000)
-			ctypes.windll.kernel32.VirtualFree(ctypes.c_void_p(address), ctypes.c_size_t(0), MEM_RELEASE)
+			ctypes.windll.kernel32.VirtualFree(ctypes.c_void_p(self.address), ctypes.c_size_t(0), MEM_RELEASE)
 		else:
-			# Remove the executable tag on the memory
-			READ_WRITE = 0x1 | 0x2
-			if ctypes.pythonapi.mprotect(ctypes.c_void_p(address), size, READ_WRITE) < 0:
-				raise Exception("Failed to mprotect")
+			self.mm.close()
 
-			ctypes.pythonapi.free(ctypes.c_void_p(address))
+		self.prochandle = None
+		self.mm = None
+		self.func = None
+		self.address = None
+		self.size = 0
 
-		return retval
 
-	# FIXME: We should not have to use different instructions to
-	# set eax to 0 or 1, on 32bit and 64bit machines.
-	def _zero_eax(self):
-		return (
-			b"\x31\xC0"         # xor eax,eax
-		)
+class CPUID(object):
+	def __init__(self, trace=None):
+		if trace == None:
+			trace = Trace(False, False)
 
-	def _zero_ecx(self):
-		return (
-			b"\x31\xC9"         # xor ecx,ecx
-		)
-	def _one_eax(self):
-		return (
-			b"\xB8\x01\x00\x00\x00" # mov eax,0x1"
-		)
+		# Figure out if SE Linux is on and in enforcing mode
+		self.is_selinux_enforcing = _is_selinux_enforcing(trace)
+
+	def _asm_func(self, restype=None, argtypes=(), machine_code=[]):
+		asm = ASM(restype, argtypes, machine_code)
+		asm.compile()
+		return asm
+
+	def _run_asm(self, *machine_code):
+		asm = ASM(ctypes.c_uint32, (), machine_code)
+		asm.compile()
+		retval = asm.run()
+		asm.free()
+		return retval
 
 	# http://en.wikipedia.org/wiki/CPUID#EAX.3D0:_Get_vendor_ID
 	def get_vendor_id(self):
 		# EBX
 		ebx = self._run_asm(
-			self._zero_eax(),
+			b"\x31\xC0",        # xor eax,eax
 			b"\x0F\xA2"         # cpuid
 			b"\x89\xD8"         # mov ax,bx
 			b"\xC3"             # ret
@@ -740,7 +1005,7 @@ class CPUID(object):
 
 		# ECX
 		ecx = self._run_asm(
-			self._zero_eax(),
+			b"\x31\xC0",        # xor eax,eax
 			b"\x0f\xa2"         # cpuid
 			b"\x89\xC8"         # mov ax,cx
 			b"\xC3"             # ret
@@ -748,7 +1013,7 @@ class CPUID(object):
 
 		# EDX
 		edx = self._run_asm(
-			self._zero_eax(),
+			b"\x31\xC0",        # xor eax,eax
 			b"\x0f\xa2"         # cpuid
 			b"\x89\xD0"         # mov ax,dx
 			b"\xC3"             # ret
@@ -767,26 +1032,33 @@ class CPUID(object):
 	def get_info(self):
 		# EAX
 		eax = self._run_asm(
-			self._one_eax(),
-			b"\x0f\xa2"         # cpuid
-			b"\xC3"             # ret
+			b"\xB8\x01\x00\x00\x00",   # mov eax,0x1"
+			b"\x0f\xa2"                # cpuid
+			b"\xC3"                    # ret
 		)
 
 		# Get the CPU info
-		stepping = (eax >> 0) & 0xF # 4 bits
+		stepping_id = (eax >> 0) & 0xF # 4 bits
 		model = (eax >> 4) & 0xF # 4 bits
-		family = (eax >> 8) & 0xF # 4 bits
+		family_id = (eax >> 8) & 0xF # 4 bits
 		processor_type = (eax >> 12) & 0x3 # 2 bits
-		extended_model = (eax >> 16) & 0xF # 4 bits
-		extended_family = (eax >> 20) & 0xFF # 8 bits
+		extended_model_id = (eax >> 16) & 0xF # 4 bits
+		extended_family_id = (eax >> 20) & 0xFF # 8 bits
+		family = 0
+
+		if family_id in [15]:
+			family = extended_family_id + family_id
+		else:
+			family = family_id
+
+		if family_id in [6, 15]:
+			model = (extended_model_id << 4) + model
 
 		return {
-			'stepping' : stepping,
+			'stepping' : stepping_id,
 			'model' : model,
 			'family' : family,
-			'processor_type' : processor_type,
-			'extended_model' : extended_model,
-			'extended_family' : extended_family
+			'processor_type' : processor_type
 		}
 
 	# http://en.wikipedia.org/wiki/CPUID#EAX.3D80000000h:_Get_Highest_Extended_Function_Supported
@@ -804,18 +1076,18 @@ class CPUID(object):
 	def get_flags(self, max_extension_support):
 		# EDX
 		edx = self._run_asm(
-			self._one_eax(),
-			b"\x0f\xa2"         # cpuid
-			b"\x89\xD0"         # mov ax,dx
-			b"\xC3"             # ret
+			b"\xB8\x01\x00\x00\x00",   # mov eax,0x1"
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xD0"                # mov ax,dx
+			b"\xC3"                    # ret
 		)
 
 		# ECX
 		ecx = self._run_asm(
-			self._one_eax(),
-			b"\x0f\xa2"         # cpuid
-			b"\x89\xC8"         # mov ax,cx
-			b"\xC3"             # ret
+			b"\xB8\x01\x00\x00\x00",   # mov eax,0x1"
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xC8"                # mov ax,cx
+			b"\xC3"                    # ret
 		)
 
 		# Get the CPU flags
@@ -894,7 +1166,7 @@ class CPUID(object):
 		if max_extension_support >= 7:
 			# EBX
 			ebx = self._run_asm(
-				self._zero_ecx(),
+				b"\x31\xC9",            # xor ecx,ecx
 				b"\xB8\x07\x00\x00\x00" # mov eax,7
 				b"\x0f\xa2"         # cpuid
 				b"\x89\xD8"         # mov ax,bx
@@ -903,7 +1175,7 @@ class CPUID(object):
 
 			# ECX
 			ecx = self._run_asm(
-				self._zero_ecx(),
+				b"\x31\xC9",            # xor ecx,ecx
 				b"\xB8\x07\x00\x00\x00" # mov eax,7
 				b"\x0f\xa2"         # cpuid
 				b"\x89\xC8"         # mov ax,cx
@@ -1148,21 +1420,21 @@ class CPUID(object):
 		)
 
 		cache_info = {
-			'size_kb' : ecx & 0xFF,
-			'line_size_b' : (ecx >> 12) & 0xF,
-			'associativity' : (ecx >> 16) & 0xFFFF
+			'size_b' : (ecx & 0xFF) * 1024,
+			'associativity' : (ecx >> 12) & 0xF,
+			'line_size_b' : (ecx >> 16) & 0xFFFF
 		}
 
 		return cache_info
 
-	def get_ticks(self):
+	def get_ticks_func(self):
 		retval = None
 
 		if DataSource.bits == '32bit':
 			# Works on x86_32
 			restype = None
 			argtypes = (ctypes.POINTER(ctypes.c_uint), ctypes.POINTER(ctypes.c_uint))
-			get_ticks_x86_32, address = self._asm_func(restype, argtypes,
+			get_ticks_x86_32 = self._asm_func(restype, argtypes,
 				[
 				b"\x55",         # push bp
 				b"\x89\xE5",     # mov bp,sp
@@ -1178,16 +1450,25 @@ class CPUID(object):
 				]
 			)
 
-			high = ctypes.c_uint32(0)
-			low = ctypes.c_uint32(0)
+			# Monkey patch func to combine high and low args into one return
+			old_func = get_ticks_x86_32.func
+			def new_func():
+				# Pass two uint32s into function
+				high = ctypes.c_uint32(0)
+				low = ctypes.c_uint32(0)
+				old_func(ctypes.byref(high), ctypes.byref(low))
 
-			get_ticks_x86_32(ctypes.byref(high), ctypes.byref(low))
-			retval = ((high.value << 32) & 0xFFFFFFFF00000000) | low.value
+				# Shift the two uint32s into one uint64
+				retval = ((high.value << 32) & 0xFFFFFFFF00000000) | low.value
+				return retval
+			get_ticks_x86_32.func = new_func
+
+			retval = get_ticks_x86_32
 		elif DataSource.bits == '64bit':
 			# Works on x86_64
 			restype = ctypes.c_uint64
 			argtypes = ()
-			get_ticks_x86_64, address = self._asm_func(restype, argtypes,
+			get_ticks_x86_64 = self._asm_func(restype, argtypes,
 				[
 				b"\x48",         # dec ax
 				b"\x31\xC0",     # xor ax,ax
@@ -1200,86 +1481,112 @@ class CPUID(object):
 				b"\xC3",         # ret
 				]
 			)
-			retval = get_ticks_x86_64()
 
+			retval = get_ticks_x86_64
 		return retval
 
 	def get_raw_hz(self):
-		import time
-
-		start = self.get_ticks()
+		from time import sleep
 
-		time.sleep(1)
+		ticks_fn = self.get_ticks_func()
 
-		end = self.get_ticks()
+		start = ticks_fn.func()
+		sleep(1)
+		end = ticks_fn.func()
 
 		ticks = (end - start)
+		ticks_fn.free()
 
 		return ticks
 
-def _actual_get_cpu_info_from_cpuid(queue):
+def _get_cpu_info_from_cpuid_actual():
 	'''
 	Warning! This function has the potential to crash the Python runtime.
 	Do not call it directly. Use the _get_cpu_info_from_cpuid function instead.
 	It will safely call this function in another process.
 	'''
 
-	# Pipe all output to nothing
-	sys.stdout = open(os.devnull, 'w')
-	sys.stderr = open(os.devnull, 'w')
+	if IS_PY2:
+		from cStringIO import StringIO
+	else:
+		from io import StringIO
 
-	# Get the CPU arch and bits
-	arch, bits = _parse_arch(DataSource.raw_arch_string)
+	trace = Trace(True, True)
+	info = {}
 
-	# Return none if this is not an X86 CPU
-	if not arch in ['X86_32', 'X86_64']:
-		queue.put(_obj_to_b64({}))
-		return
+	# Pipe stdout and stderr to strings
+	sys.stdout = trace._stdout
+	sys.stderr = trace._stderr
 
-	# Return none if SE Linux is in enforcing mode
-	cpuid = CPUID()
-	if cpuid.is_selinux_enforcing:
-		queue.put(_obj_to_b64({}))
-		return
+	try:
+		# Get the CPU arch and bits
+		arch, bits = _parse_arch(DataSource.arch_string_raw)
 
-	# Get the cpu info from the CPUID register
-	max_extension_support = cpuid.get_max_extension_support()
-	cache_info = cpuid.get_cache(max_extension_support)
-	info = cpuid.get_info()
+		# Return none if this is not an X86 CPU
+		if not arch in ['X86_32', 'X86_64']:
+			trace.fail('Not running on X86_32 or X86_64. Skipping ...')
+			return trace.to_dict(info, True)
 
-	processor_brand = cpuid.get_processor_brand(max_extension_support)
+		# Return none if SE Linux is in enforcing mode
+		cpuid = CPUID(trace)
+		if cpuid.is_selinux_enforcing:
+			trace.fail('SELinux is enforcing. Skipping ...')
+			return trace.to_dict(info, True)
 
-	# Get the Hz and scale
-	hz_actual = cpuid.get_raw_hz()
-	hz_actual = _to_hz_string(hz_actual)
+		# Get the cpu info from the CPUID register
+		max_extension_support = cpuid.get_max_extension_support()
+		cache_info = cpuid.get_cache(max_extension_support)
+		info = cpuid.get_info()
 
-	# Get the Hz and scale
-	scale, hz_advertised = _get_hz_string_from_brand(processor_brand)
-	info = {
-	'vendor_id' : cpuid.get_vendor_id(),
-	'hardware' : '',
-	'brand' : processor_brand,
-
-	'hz_advertised' : _to_friendly_hz(hz_advertised, scale),
-	'hz_actual' : _to_friendly_hz(hz_actual, 0),
-	'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale),
-	'hz_actual_raw' : _to_raw_hz(hz_actual, 0),
-
-	'l2_cache_size' : _to_friendly_bytes(cache_info['size_kb']),
-	'l2_cache_line_size' : cache_info['line_size_b'],
-	'l2_cache_associativity' : hex(cache_info['associativity']),
-
-	'stepping' : info['stepping'],
-	'model' : info['model'],
-	'family' : info['family'],
-	'processor_type' : info['processor_type'],
-	'extended_model' : info['extended_model'],
-	'extended_family' : info['extended_family'],
-	'flags' : cpuid.get_flags(max_extension_support)
-	}
+		processor_brand = cpuid.get_processor_brand(max_extension_support)
 
-	info = {k: v for k, v in info.items() if v}
-	queue.put(_obj_to_b64(info))
+		# Get the Hz and scale
+		hz_actual = cpuid.get_raw_hz()
+		hz_actual = _to_decimal_string(hz_actual)
+
+		# Get the Hz and scale
+		hz_advertised, scale = _parse_cpu_brand_string(processor_brand)
+		info = {
+		'vendor_id_raw' : cpuid.get_vendor_id(),
+		'hardware_raw' : '',
+		'brand_raw' : processor_brand,
+
+		'hz_advertised_friendly' : _hz_short_to_friendly(hz_advertised, scale),
+		'hz_actual_friendly' : _hz_short_to_friendly(hz_actual, 0),
+		'hz_advertised' : _hz_short_to_full(hz_advertised, scale),
+		'hz_actual' : _hz_short_to_full(hz_actual, 0),
+
+		'l2_cache_size' : cache_info['size_b'],
+		'l2_cache_line_size' : cache_info['line_size_b'],
+		'l2_cache_associativity' : cache_info['associativity'],
+
+		'stepping' : info['stepping'],
+		'model' : info['model'],
+		'family' : info['family'],
+		'processor_type' : info['processor_type'],
+		'flags' : cpuid.get_flags(max_extension_support)
+		}
+
+		info = _filter_dict_keys_with_empty_values(info)
+		trace.success()
+	except Exception as err:
+		from traceback import format_exc
+		err_string = format_exc()
+		trace._err = ''.join(['\t\t{0}\n'.format(n) for n in err_string.split('\n')]) + '\n'
+		return trace.to_dict(info, True)
+
+	return trace.to_dict(info, False)
+
+def _get_cpu_info_from_cpuid_subprocess_wrapper(queue):
+	orig_stdout = sys.stdout
+	orig_stderr = sys.stderr
+
+	output = _get_cpu_info_from_cpuid_actual()
+
+	sys.stdout = orig_stdout
+	sys.stderr = orig_stderr
+
+	queue.put(_obj_to_b64(output))
 
 def _get_cpu_info_from_cpuid():
 	'''
@@ -1287,38 +1594,96 @@ def _get_cpu_info_from_cpuid():
 	Returns {} on non X86 cpus.
 	Returns {} if SELinux is in enforcing mode.
 	'''
+
+	g_trace.header('Tying to get info from CPUID ...')
+
 	from multiprocessing import Process, Queue
 
 	# Return {} if can't cpuid
 	if not DataSource.can_cpuid:
+		g_trace.fail('Can\'t CPUID. Skipping ...')
 		return {}
 
 	# Get the CPU arch and bits
-	arch, bits = _parse_arch(DataSource.raw_arch_string)
+	arch, bits = _parse_arch(DataSource.arch_string_raw)
 
 	# Return {} if this is not an X86 CPU
 	if not arch in ['X86_32', 'X86_64']:
+		g_trace.fail('Not running on X86_32 or X86_64. Skipping ...')
 		return {}
 
 	try:
-		# Start running the function in a subprocess
-		queue = Queue()
-		p = Process(target=_actual_get_cpu_info_from_cpuid, args=(queue,))
-		p.start()
+		if CAN_CALL_CPUID_IN_SUBPROCESS:
+			# Start running the function in a subprocess
+			queue = Queue()
+			p = Process(target=_get_cpu_info_from_cpuid_subprocess_wrapper, args=(queue,))
+			p.start()
+
+			# Wait for the process to end, while it is still alive
+			while p.is_alive():
+				p.join(0)
+
+			# Return {} if it failed
+			if p.exitcode != 0:
+				g_trace.fail('Failed to run CPUID in process. Skipping ...')
+				return {}
+
+			# Return {} if no results
+			if queue.empty():
+				g_trace.fail('Failed to get anything from CPUID process. Skipping ...')
+				return {}
+			# Return the result, only if there is something to read
+			else:
+				output = _b64_to_obj(queue.get())
+				import pprint
+				pp = pprint.PrettyPrinter(indent=4)
+				#pp.pprint(output)
+
+				if 'output' in output and output['output']:
+					g_trace.write(output['output'])
+
+				if 'stdout' in output and output['stdout']:
+					sys.stdout.write('{0}\n'.format(output['stdout']))
+					sys.stdout.flush()
+
+				if 'stderr' in output and output['stderr']:
+					sys.stderr.write('{0}\n'.format(output['stderr']))
+					sys.stderr.flush()
+
+				if 'is_fail' not in output:
+					g_trace.fail('Failed to get is_fail from CPUID process. Skipping ...')
+					return {}
+
+				# Fail if there was an exception
+				if 'err' in output and output['err']:
+					g_trace.fail('Failed to run CPUID in process. Skipping ...')
+					g_trace.write(output['err'])
+					g_trace.write('Failed ...')
+					return {}
+
+				if 'is_fail' in output and output['is_fail']:
+					g_trace.write('Failed ...')
+					return {}
+
+				if 'info' not in output or not output['info']:
+					g_trace.fail('Failed to get return info from CPUID process. Skipping ...')
+					return {}
+
+				return output['info']
+		else:
+			# FIXME: This should write the values like in the above call to actual
+			orig_stdout = sys.stdout
+			orig_stderr = sys.stderr
 
-		# Wait for the process to end, while it is still alive
-		while p.is_alive():
-			p.join(0)
+			output = _get_cpu_info_from_cpuid_actual()
 
-		# Return {} if it failed
-		if p.exitcode != 0:
-			return {}
+			sys.stdout = orig_stdout
+			sys.stderr = orig_stderr
 
-		# Return the result, only if there is something to read
-		if not queue.empty():
-			output = queue.get()
-			return _b64_to_obj(output)
-	except:
+			g_trace.success()
+			return output['info']
+	except Exception as err:
+		g_trace.fail(err)
 		pass
 
 	# Return {} if everything failed
@@ -1329,13 +1694,18 @@ def _get_cpu_info_from_proc_cpuinfo():
 	Returns the CPU info gathered from /proc/cpuinfo.
 	Returns {} if /proc/cpuinfo is not found.
 	'''
+
+	g_trace.header('Tying to get info from /proc/cpuinfo ...')
+
 	try:
 		# Just return {} if there is no cpuinfo
 		if not DataSource.has_proc_cpuinfo():
+			g_trace.fail('Failed to find /proc/cpuinfo. Skipping ...')
 			return {}
 
 		returncode, output = DataSource.cat_proc_cpuinfo()
 		if returncode != 0:
+			g_trace.fail('Failed to run cat /proc/cpuinfo. Skipping ...')
 			return {}
 
 		# Various fields
@@ -1346,31 +1716,47 @@ def _get_cpu_info_from_proc_cpuinfo():
 		model = _get_field(False, output, int, 0, 'model')
 		family = _get_field(False, output, int, 0, 'cpu family')
 		hardware = _get_field(False, output, None, '', 'Hardware')
+
 		# Flags
-		flags = _get_field(False, output, None, None, 'flags', 'Features')
+		flags = _get_field(False, output, None, None, 'flags', 'Features', 'ASEs implemented')
 		if flags:
 			flags = flags.split()
 			flags.sort()
 
+		# Check for other cache format
+		if not cache_size:
+			try:
+				for i in range(0, 10):
+					name = "cache{0}".format(i)
+					value = _get_field(False, output, None, None, name)
+					if value:
+						value = [entry.split('=') for entry in value.split(' ')]
+						value = dict(value)
+						if 'level' in value and value['level'] == '3' and 'size' in value:
+							cache_size = value['size']
+							break
+			except Exception:
+				pass
+
 		# Convert from MHz string to Hz
-		hz_actual = _get_field(False, output, None, '', 'cpu MHz', 'cpu speed', 'clock')
+		hz_actual = _get_field(False, output, None, '', 'cpu MHz', 'cpu speed', 'clock', 'cpu MHz dynamic', 'cpu MHz static')
 		hz_actual = hz_actual.lower().rstrip('mhz').strip()
-		hz_actual = _to_hz_string(hz_actual)
+		hz_actual = _to_decimal_string(hz_actual)
 
 		# Convert from GHz/MHz string to Hz
-		scale, hz_advertised = (0, None)
+		hz_advertised, scale = (None, 0)
 		try:
-			scale, hz_advertised = _get_hz_string_from_brand(processor_brand)
+			hz_advertised, scale = _parse_cpu_brand_string(processor_brand)
 		except Exception:
 			pass
 
 		info = {
-		'hardware' : hardware,
-		'brand' : processor_brand,
+		'hardware_raw' : hardware,
+		'brand_raw' : processor_brand,
 
-		'l3_cache_size' : _to_friendly_bytes(cache_size),
+		'l3_cache_size' : _friendly_bytes_to_int(cache_size),
 		'flags' : flags,
-		'vendor_id' : vendor_id,
+		'vendor_id_raw' : vendor_id,
 		'stepping' : stepping,
 		'model' : model,
 		'family' : family,
@@ -1384,16 +1770,18 @@ def _get_cpu_info_from_proc_cpuinfo():
 			hz_actual = hz_advertised
 
 		# Add the Hz if there is one
-		if _to_raw_hz(hz_advertised, scale) > (0, 0):
-			info['hz_advertised'] = _to_friendly_hz(hz_advertised, scale)
-			info['hz_advertised_raw'] = _to_raw_hz(hz_advertised, scale)
-		if _to_raw_hz(hz_actual, scale) > (0, 0):
-			info['hz_actual'] = _to_friendly_hz(hz_actual, 6)
-			info['hz_actual_raw'] = _to_raw_hz(hz_actual, 6)
-
-		info = {k: v for k, v in info.items() if v}
+		if _hz_short_to_full(hz_advertised, scale) > (0, 0):
+			info['hz_advertised_friendly'] = _hz_short_to_friendly(hz_advertised, scale)
+			info['hz_advertised'] = _hz_short_to_full(hz_advertised, scale)
+		if _hz_short_to_full(hz_actual, scale) > (0, 0):
+			info['hz_actual_friendly'] = _hz_short_to_friendly(hz_actual, 6)
+			info['hz_actual'] = _hz_short_to_full(hz_actual, 6)
+
+		info = _filter_dict_keys_with_empty_values(info)
+		g_trace.success()
 		return info
-	except:
+	except Exception as err:
+		g_trace.fail(err)
 		#raise # NOTE: To have this throw on error, uncomment this line
 		return {}
 
@@ -1402,14 +1790,19 @@ def _get_cpu_info_from_cpufreq_info():
 	Returns the CPU info gathered from cpufreq-info.
 	Returns {} if cpufreq-info is not found.
 	'''
+
+	g_trace.header('Tying to get info from cpufreq-info ...')
+
 	try:
-		scale, hz_brand = 1, '0.0'
+		hz_brand, scale = '0.0', 0
 
 		if not DataSource.has_cpufreq_info():
+			g_trace.fail('Failed to find cpufreq-info. Skipping ...')
 			return {}
 
 		returncode, output = DataSource.cpufreq_info()
 		if returncode != 0:
+			g_trace.fail('Failed to run cpufreq-info. Skipping ...')
 			return {}
 
 		hz_brand = output.split('current CPU frequency is')[1].split('\n')[0]
@@ -1422,18 +1815,20 @@ def _get_cpu_info_from_cpufreq_info():
 		elif hz_brand.endswith('ghz'):
 			scale = 9
 		hz_brand = hz_brand.rstrip('mhz').rstrip('ghz').strip()
-		hz_brand = _to_hz_string(hz_brand)
+		hz_brand = _to_decimal_string(hz_brand)
 
 		info = {
-			'hz_advertised' : _to_friendly_hz(hz_brand, scale),
-			'hz_actual' : _to_friendly_hz(hz_brand, scale),
-			'hz_advertised_raw' : _to_raw_hz(hz_brand, scale),
-			'hz_actual_raw' : _to_raw_hz(hz_brand, scale),
+			'hz_advertised_friendly' : _hz_short_to_friendly(hz_brand, scale),
+			'hz_actual_friendly' : _hz_short_to_friendly(hz_brand, scale),
+			'hz_advertised' : _hz_short_to_full(hz_brand, scale),
+			'hz_actual' : _hz_short_to_full(hz_brand, scale),
 		}
 
-		info = {k: v for k, v in info.items() if v}
+		info = _filter_dict_keys_with_empty_values(info)
+		g_trace.success()
 		return info
-	except:
+	except Exception as err:
+		g_trace.fail(err)
 		#raise # NOTE: To have this throw on error, uncomment this line
 		return {}
 
@@ -1442,32 +1837,50 @@ def _get_cpu_info_from_lscpu():
 	Returns the CPU info gathered from lscpu.
 	Returns {} if lscpu is not found.
 	'''
+
+	g_trace.header('Tying to get info from lscpu ...')
+
 	try:
 		if not DataSource.has_lscpu():
+			g_trace.fail('Failed to find lscpu. Skipping ...')
 			return {}
 
 		returncode, output = DataSource.lscpu()
 		if returncode != 0:
+			g_trace.fail('Failed to run lscpu. Skipping ...')
 			return {}
 
 		info = {}
 
 		new_hz = _get_field(False, output, None, None, 'CPU max MHz', 'CPU MHz')
 		if new_hz:
-			new_hz = _to_hz_string(new_hz)
+			new_hz = _to_decimal_string(new_hz)
+			scale = 6
+			info['hz_advertised_friendly'] = _hz_short_to_friendly(new_hz, scale)
+			info['hz_actual_friendly'] = _hz_short_to_friendly(new_hz, scale)
+			info['hz_advertised'] = _hz_short_to_full(new_hz, scale)
+			info['hz_actual'] = _hz_short_to_full(new_hz, scale)
+
+		new_hz = _get_field(False, output, None, None, 'CPU dynamic MHz', 'CPU static MHz')
+		if new_hz:
+			new_hz = _to_decimal_string(new_hz)
 			scale = 6
-			info['hz_advertised'] = _to_friendly_hz(new_hz, scale)
-			info['hz_actual'] = _to_friendly_hz(new_hz, scale)
-			info['hz_advertised_raw'] = _to_raw_hz(new_hz, scale)
-			info['hz_actual_raw'] = _to_raw_hz(new_hz, scale)
+			info['hz_advertised_friendly'] = _hz_short_to_friendly(new_hz, scale)
+			info['hz_actual_friendly'] = _hz_short_to_friendly(new_hz, scale)
+			info['hz_advertised'] = _hz_short_to_full(new_hz, scale)
+			info['hz_actual'] = _hz_short_to_full(new_hz, scale)
 
 		vendor_id = _get_field(False, output, None, None, 'Vendor ID')
 		if vendor_id:
-			info['vendor_id'] = vendor_id
+			info['vendor_id_raw'] = vendor_id
 
 		brand = _get_field(False, output, None, None, 'Model name')
 		if brand:
-			info['brand'] = brand
+			info['brand_raw'] = brand
+		else:
+			brand = _get_field(False, output, None, None, 'Model')
+			if brand and not brand.isdigit():
+				info['brand_raw'] = brand
 
 		family = _get_field(False, output, None, None, 'CPU family')
 		if family and family.isdigit():
@@ -1483,30 +1896,32 @@ def _get_cpu_info_from_lscpu():
 
 		l1_data_cache_size = _get_field(False, output, None, None, 'L1d cache')
 		if l1_data_cache_size:
-			info['l1_data_cache_size'] = _to_friendly_bytes(l1_data_cache_size)
+			info['l1_data_cache_size'] = _friendly_bytes_to_int(l1_data_cache_size)
 
 		l1_instruction_cache_size = _get_field(False, output, None, None, 'L1i cache')
 		if l1_instruction_cache_size:
-			info['l1_instruction_cache_size'] = _to_friendly_bytes(l1_instruction_cache_size)
+			info['l1_instruction_cache_size'] = _friendly_bytes_to_int(l1_instruction_cache_size)
 
-		l2_cache_size = _get_field(False, output, None, None, 'L2 cache')
+		l2_cache_size = _get_field(False, output, None, None, 'L2 cache', 'L2d cache')
 		if l2_cache_size:
-			info['l2_cache_size'] = _to_friendly_bytes(l2_cache_size)
+			info['l2_cache_size'] = _friendly_bytes_to_int(l2_cache_size)
 
 		l3_cache_size = _get_field(False, output, None, None, 'L3 cache')
 		if l3_cache_size:
-			info['l3_cache_size'] = _to_friendly_bytes(l3_cache_size)
+			info['l3_cache_size'] = _friendly_bytes_to_int(l3_cache_size)
 
 		# Flags
-		flags = _get_field(False, output, None, None, 'flags', 'Features')
+		flags = _get_field(False, output, None, None, 'flags', 'Features', 'ASEs implemented')
 		if flags:
 			flags = flags.split()
 			flags.sort()
 			info['flags'] = flags
 
-		info = {k: v for k, v in info.items() if v}
+		info = _filter_dict_keys_with_empty_values(info)
+		g_trace.success()
 		return info
-	except:
+	except Exception as err:
+		g_trace.fail(err)
 		#raise # NOTE: To have this throw on error, uncomment this line
 		return {}
 
@@ -1515,16 +1930,29 @@ def _get_cpu_info_from_dmesg():
 	Returns the CPU info gathered from dmesg.
 	Returns {} if dmesg is not found or does not have the desired info.
 	'''
+
+	g_trace.header('Tying to get info from the dmesg ...')
+
+	# Just return {} if this arch has an unreliable dmesg log
+	arch, bits = _parse_arch(DataSource.arch_string_raw)
+	if arch in ['S390X']:
+		g_trace.fail('Running on S390X. Skipping ...')
+		return {}
+
 	# Just return {} if there is no dmesg
 	if not DataSource.has_dmesg():
+		g_trace.fail('Failed to find dmesg. Skipping ...')
 		return {}
 
 	# If dmesg fails return {}
 	returncode, output = DataSource.dmesg_a()
 	if output == None or returncode != 0:
+		g_trace.fail('Failed to run \"dmesg -a\". Skipping ...')
 		return {}
 
-	return _parse_dmesg_output(output)
+	info = _parse_dmesg_output(output)
+	g_trace.success()
+	return info
 
 
 # https://openpowerfoundation.org/wp-content/uploads/2016/05/LoPAPR_DRAFT_v11_24March2016_cmt1.pdf
@@ -1534,14 +1962,19 @@ def _get_cpu_info_from_ibm_pa_features():
 	Returns the CPU info gathered from lsprop /proc/device-tree/cpus/*/ibm,pa-features
 	Returns {} if lsprop is not found or ibm,pa-features does not have the desired info.
 	'''
+
+	g_trace.header('Tying to get info from lsprop ...')
+
 	try:
 		# Just return {} if there is no lsprop
 		if not DataSource.has_ibm_pa_features():
+			g_trace.fail('Failed to find lsprop. Skipping ...')
 			return {}
 
 		# If ibm,pa-features fails return {}
 		returncode, output = DataSource.ibm_pa_features()
 		if output == None or returncode != 0:
+			g_trace.fail('Failed to glob /proc/device-tree/cpus/*/ibm,pa-features. Skipping ...')
 			return {}
 
 		# Filter out invalid characters from output
@@ -1643,10 +2076,11 @@ def _get_cpu_info_from_ibm_pa_features():
 		info = {
 			'flags' : flags
 		}
-		info = {k: v for k, v in info.items() if v}
-
+		info = _filter_dict_keys_with_empty_values(info)
+		g_trace.success()
 		return info
-	except:
+	except Exception as err:
+		g_trace.fail(err)
 		return {}
 
 
@@ -1655,16 +2089,23 @@ def _get_cpu_info_from_cat_var_run_dmesg_boot():
 	Returns the CPU info gathered from /var/run/dmesg.boot.
 	Returns {} if dmesg is not found or does not have the desired info.
 	'''
+
+	g_trace.header('Tying to get info from the /var/run/dmesg.boot log ...')
+
 	# Just return {} if there is no /var/run/dmesg.boot
 	if not DataSource.has_var_run_dmesg_boot():
+		g_trace.fail('Failed to find /var/run/dmesg.boot file. Skipping ...')
 		return {}
 
 	# If dmesg.boot fails return {}
 	returncode, output = DataSource.cat_var_run_dmesg_boot()
 	if output == None or returncode != 0:
+		g_trace.fail('Failed to run \"cat /var/run/dmesg.boot\". Skipping ...')
 		return {}
 
-	return _parse_dmesg_output(output)
+	info = _parse_dmesg_output(output)
+	g_trace.success()
+	return info
 
 
 def _get_cpu_info_from_sysctl():
@@ -1672,20 +2113,25 @@ def _get_cpu_info_from_sysctl():
 	Returns the CPU info gathered from sysctl.
 	Returns {} if sysctl is not found.
 	'''
+
+	g_trace.header('Tying to get info from sysctl ...')
+
 	try:
 		# Just return {} if there is no sysctl
 		if not DataSource.has_sysctl():
+			g_trace.fail('Failed to find sysctl. Skipping ...')
 			return {}
 
 		# If sysctl fails return {}
 		returncode, output = DataSource.sysctl_machdep_cpu_hw_cpufrequency()
 		if output == None or returncode != 0:
+			g_trace.fail('Failed to run \"sysctl machdep.cpu hw.cpufrequency\". Skipping ...')
 			return {}
 
 		# Various fields
 		vendor_id = _get_field(False, output, None, None, 'machdep.cpu.vendor')
 		processor_brand = _get_field(True, output, None, None, 'machdep.cpu.brand_string')
-		cache_size = _get_field(False, output, None, None, 'machdep.cpu.cache.size')
+		cache_size = _get_field(False, output, int, 0, 'machdep.cpu.cache.size')
 		stepping = _get_field(False, output, int, 0, 'machdep.cpu.stepping')
 		model = _get_field(False, output, int, 0, 'machdep.cpu.model')
 		family = _get_field(False, output, int, 0, 'machdep.cpu.family')
@@ -1697,20 +2143,20 @@ def _get_cpu_info_from_sysctl():
 		flags.sort()
 
 		# Convert from GHz/MHz string to Hz
-		scale, hz_advertised = _get_hz_string_from_brand(processor_brand)
+		hz_advertised, scale = _parse_cpu_brand_string(processor_brand)
 		hz_actual = _get_field(False, output, None, None, 'hw.cpufrequency')
-		hz_actual = _to_hz_string(hz_actual)
+		hz_actual = _to_decimal_string(hz_actual)
 
 		info = {
-		'vendor_id' : vendor_id,
-		'brand' : processor_brand,
+		'vendor_id_raw' : vendor_id,
+		'brand_raw' : processor_brand,
 
-		'hz_advertised' : _to_friendly_hz(hz_advertised, scale),
-		'hz_actual' : _to_friendly_hz(hz_actual, 0),
-		'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale),
-		'hz_actual_raw' : _to_raw_hz(hz_actual, 0),
+		'hz_advertised_friendly' : _hz_short_to_friendly(hz_advertised, scale),
+		'hz_actual_friendly' : _hz_short_to_friendly(hz_actual, 0),
+		'hz_advertised' : _hz_short_to_full(hz_advertised, scale),
+		'hz_actual' : _hz_short_to_full(hz_actual, 0),
 
-		'l2_cache_size' : _to_friendly_bytes(cache_size),
+		'l2_cache_size' : int(cache_size) * 1024,
 
 		'stepping' : stepping,
 		'model' : model,
@@ -1718,9 +2164,11 @@ def _get_cpu_info_from_sysctl():
 		'flags' : flags
 		}
 
-		info = {k: v for k, v in info.items() if v}
+		info = _filter_dict_keys_with_empty_values(info)
+		g_trace.success()
 		return info
-	except:
+	except Exception as err:
+		g_trace.fail(err)
 		return {}
 
 
@@ -1729,6 +2177,7 @@ def _get_cpu_info_from_sysinfo():
 	Returns the CPU info gathered from sysinfo.
 	Returns {} if sysinfo is not found.
 	'''
+
 	info = _get_cpu_info_from_sysinfo_v1()
 	info.update(_get_cpu_info_from_sysinfo_v2())
 	return info
@@ -1738,19 +2187,24 @@ def _get_cpu_info_from_sysinfo_v1():
 	Returns the CPU info gathered from sysinfo.
 	Returns {} if sysinfo is not found.
 	'''
+
+	g_trace.header('Tying to get info from sysinfo version 1 ...')
+
 	try:
 		# Just return {} if there is no sysinfo
 		if not DataSource.has_sysinfo():
+			g_trace.fail('Failed to find sysinfo. Skipping ...')
 			return {}
 
 		# If sysinfo fails return {}
 		returncode, output = DataSource.sysinfo_cpu()
 		if output == None or returncode != 0:
+			g_trace.fail('Failed to run \"sysinfo -cpu\". Skipping ...')
 			return {}
 
 		# Various fields
 		vendor_id = '' #_get_field(False, output, None, None, 'CPU #0: ')
-		processor_brand = output.split('CPU #0: "')[1].split('"\n')[0]
+		processor_brand = output.split('CPU #0: "')[1].split('"\n')[0].strip()
 		cache_size = '' #_get_field(False, output, None, None, 'machdep.cpu.cache.size')
 		stepping = int(output.split(', stepping ')[1].split(',')[0].strip())
 		model = int(output.split(', model ')[1].split(',')[0].strip())
@@ -1765,17 +2219,17 @@ def _get_cpu_info_from_sysinfo_v1():
 		flags.sort()
 
 		# Convert from GHz/MHz string to Hz
-		scale, hz_advertised = _get_hz_string_from_brand(processor_brand)
+		hz_advertised, scale = _parse_cpu_brand_string(processor_brand)
 		hz_actual = hz_advertised
 
 		info = {
-		'vendor_id' : vendor_id,
-		'brand' : processor_brand,
+		'vendor_id_raw' : vendor_id,
+		'brand_raw' : processor_brand,
 
-		'hz_advertised' : _to_friendly_hz(hz_advertised, scale),
-		'hz_actual' : _to_friendly_hz(hz_actual, scale),
-		'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale),
-		'hz_actual_raw' : _to_raw_hz(hz_actual, scale),
+		'hz_advertised_friendly' : _hz_short_to_friendly(hz_advertised, scale),
+		'hz_actual_friendly' : _hz_short_to_friendly(hz_actual, scale),
+		'hz_advertised' : _hz_short_to_full(hz_advertised, scale),
+		'hz_actual' : _hz_short_to_full(hz_actual, scale),
 
 		'l2_cache_size' : _to_friendly_bytes(cache_size),
 
@@ -1785,9 +2239,12 @@ def _get_cpu_info_from_sysinfo_v1():
 		'flags' : flags
 		}
 
-		info = {k: v for k, v in info.items() if v}
+		info = _filter_dict_keys_with_empty_values(info)
+		g_trace.success()
 		return info
-	except:
+	except Exception as err:
+		g_trace.fail(err)
+		#raise # NOTE: To have this throw on error, uncomment this line
 		return {}
 
 def _get_cpu_info_from_sysinfo_v2():
@@ -1795,19 +2252,24 @@ def _get_cpu_info_from_sysinfo_v2():
 	Returns the CPU info gathered from sysinfo.
 	Returns {} if sysinfo is not found.
 	'''
+
+	g_trace.header('Tying to get info from sysinfo version 2 ...')
+
 	try:
 		# Just return {} if there is no sysinfo
 		if not DataSource.has_sysinfo():
+			g_trace.fail('Failed to find sysinfo. Skipping ...')
 			return {}
 
 		# If sysinfo fails return {}
 		returncode, output = DataSource.sysinfo_cpu()
 		if output == None or returncode != 0:
+			g_trace.fail('Failed to run \"sysinfo -cpu\". Skipping ...')
 			return {}
 
 		# Various fields
 		vendor_id = '' #_get_field(False, output, None, None, 'CPU #0: ')
-		processor_brand = output.split('CPU #0: "')[1].split('"\n')[0]
+		processor_brand = output.split('CPU #0: "')[1].split('"\n')[0].strip()
 		cache_size = '' #_get_field(False, output, None, None, 'machdep.cpu.cache.size')
 		signature = output.split('Signature:')[1].split('\n')[0].strip()
 		#
@@ -1819,7 +2281,7 @@ def _get_cpu_info_from_sysinfo_v2():
 		def get_subsection_flags(output):
 			retval = []
 			for line in output.split('\n')[1:]:
-				if not line.startswith('                '): break
+				if not line.startswith('                ') and not line.startswith('		'): break
 				for entry in line.strip().lower().split(' '):
 					retval.append(entry)
 			return retval
@@ -1830,17 +2292,26 @@ def _get_cpu_info_from_sysinfo_v2():
 		flags.sort()
 
 		# Convert from GHz/MHz string to Hz
-		scale, hz_advertised = _get_hz_string_from_brand(processor_brand)
+		lines = [n for n in output.split('\n') if n]
+		raw_hz = lines[0].split('running at ')[1].strip().lower()
+		hz_advertised = raw_hz.rstrip('mhz').rstrip('ghz').strip()
+		hz_advertised = _to_decimal_string(hz_advertised)
 		hz_actual = hz_advertised
 
+		scale = 0
+		if raw_hz.endswith('mhz'):
+			scale = 6
+		elif raw_hz.endswith('ghz'):
+			scale = 9
+
 		info = {
-		'vendor_id' : vendor_id,
-		'brand' : processor_brand,
+		'vendor_id_raw' : vendor_id,
+		'brand_raw' : processor_brand,
 
-		'hz_advertised' : _to_friendly_hz(hz_advertised, scale),
-		'hz_actual' : _to_friendly_hz(hz_actual, scale),
-		'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale),
-		'hz_actual_raw' : _to_raw_hz(hz_actual, scale),
+		'hz_advertised_friendly' : _hz_short_to_friendly(hz_advertised, scale),
+		'hz_actual_friendly' : _hz_short_to_friendly(hz_actual, scale),
+		'hz_advertised' : _hz_short_to_full(hz_advertised, scale),
+		'hz_actual' : _hz_short_to_full(hz_actual, scale),
 
 		'l2_cache_size' : _to_friendly_bytes(cache_size),
 
@@ -1850,9 +2321,12 @@ def _get_cpu_info_from_sysinfo_v2():
 		'flags' : flags
 		}
 
-		info = {k: v for k, v in info.items() if v}
+		info = _filter_dict_keys_with_empty_values(info)
+		g_trace.success()
 		return info
-	except:
+	except Exception as err:
+		g_trace.fail(err)
+		#raise # NOTE: To have this throw on error, uncomment this line
 		return {}
 
 def _get_cpu_info_from_wmic():
@@ -1860,14 +2334,17 @@ def _get_cpu_info_from_wmic():
 	Returns the CPU info gathered from WMI.
 	Returns {} if not on Windows, or wmic is not installed.
 	'''
+	g_trace.header('Tying to get info from wmic ...')
 
 	try:
 		# Just return {} if not Windows or there is no wmic
 		if not DataSource.is_windows or not DataSource.has_wmic():
+			g_trace.fail('Failed to find WMIC, or not on Windows. Skipping ...')
 			return {}
 
 		returncode, output = DataSource.wmic_cpu()
 		if output == None or returncode != 0:
+			g_trace.fail('Failed to run wmic. Skipping ...')
 			return {}
 
 		# Break the list into key values pairs
@@ -1877,22 +2354,22 @@ def _get_cpu_info_from_wmic():
 
 		# Get the advertised MHz
 		processor_brand = value.get('Name')
-		scale_advertised, hz_advertised = _get_hz_string_from_brand(processor_brand)
+		hz_advertised, scale_advertised = _parse_cpu_brand_string(processor_brand)
 
 		# Get the actual MHz
 		hz_actual = value.get('CurrentClockSpeed')
 		scale_actual = 6
 		if hz_actual:
-			hz_actual = _to_hz_string(hz_actual)
+			hz_actual = _to_decimal_string(hz_actual)
 
 		# Get cache sizes
-		l2_cache_size = value.get('L2CacheSize')
+		l2_cache_size = value.get('L2CacheSize') # NOTE: L2CacheSize is in kilobytes
 		if l2_cache_size:
-			l2_cache_size = l2_cache_size + ' KB'
+			l2_cache_size = int(l2_cache_size) * 1024
 
-		l3_cache_size = value.get('L3CacheSize')
+		l3_cache_size = value.get('L3CacheSize') # NOTE: L3CacheSize is in kilobytes
 		if l3_cache_size:
-			l3_cache_size = l3_cache_size + ' KB'
+			l3_cache_size = int(l3_cache_size) * 1024
 
 		# Get family, model, and stepping
 		family, model, stepping = '', '', ''
@@ -1912,13 +2389,13 @@ def _get_cpu_info_from_wmic():
 			stepping = int(entries[i + 1])
 
 		info = {
-			'vendor_id' : value.get('Manufacturer'),
-			'brand' : processor_brand,
+			'vendor_id_raw' : value.get('Manufacturer'),
+			'brand_raw' : processor_brand,
 
-			'hz_advertised' : _to_friendly_hz(hz_advertised, scale_advertised),
-			'hz_actual' : _to_friendly_hz(hz_actual, scale_actual),
-			'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale_advertised),
-			'hz_actual_raw' : _to_raw_hz(hz_actual, scale_actual),
+			'hz_advertised_friendly' : _hz_short_to_friendly(hz_advertised, scale_advertised),
+			'hz_actual_friendly' : _hz_short_to_friendly(hz_actual, scale_actual),
+			'hz_advertised' : _hz_short_to_full(hz_advertised, scale_advertised),
+			'hz_actual' : _hz_short_to_full(hz_actual, scale_actual),
 
 			'l2_cache_size' : l2_cache_size,
 			'l3_cache_size' : l3_cache_size,
@@ -1928,39 +2405,49 @@ def _get_cpu_info_from_wmic():
 			'family' : family,
 		}
 
-		info = {k: v for k, v in info.items() if v}
+		info = _filter_dict_keys_with_empty_values(info)
+		g_trace.success()
 		return info
-	except:
+	except Exception as err:
+		g_trace.fail(err)
 		#raise # NOTE: To have this throw on error, uncomment this line
 		return {}
 
 def _get_cpu_info_from_registry():
 	'''
-	FIXME: Is missing many of the newer CPU flags like sse3
 	Returns the CPU info gathered from the Windows Registry.
 	Returns {} if not on Windows.
 	'''
+
+	g_trace.header('Tying to get info from Windows registry ...')
+
 	try:
 		# Just return {} if not on Windows
 		if not DataSource.is_windows:
+			g_trace.fail('Not running on Windows. Skipping ...')
 			return {}
 
 		# Get the CPU name
-		processor_brand = DataSource.winreg_processor_brand()
+		processor_brand = DataSource.winreg_processor_brand().strip()
 
 		# Get the CPU vendor id
-		vendor_id = DataSource.winreg_vendor_id()
+		vendor_id = DataSource.winreg_vendor_id_raw()
 
 		# Get the CPU arch and bits
-		raw_arch_string = DataSource.winreg_raw_arch_string()
-		arch, bits = _parse_arch(raw_arch_string)
+		arch_string_raw = DataSource.winreg_arch_string_raw()
+		arch, bits = _parse_arch(arch_string_raw)
 
 		# Get the actual CPU Hz
 		hz_actual = DataSource.winreg_hz_actual()
-		hz_actual = _to_hz_string(hz_actual)
+		hz_actual = _to_decimal_string(hz_actual)
 
 		# Get the advertised CPU Hz
-		scale, hz_advertised = _get_hz_string_from_brand(processor_brand)
+		hz_advertised, scale = _parse_cpu_brand_string(processor_brand)
+
+		# If advertised hz not found, use the actual hz
+		if hz_advertised == '0.0':
+			scale = 6
+			hz_advertised = _to_decimal_string(hz_actual)
 
 		# Get the CPU features
 		feature_bits = DataSource.winreg_feature_bits()
@@ -2013,20 +2500,22 @@ def _get_cpu_info_from_registry():
 		flags.sort()
 
 		info = {
-		'vendor_id' : vendor_id,
-		'brand' : processor_brand,
+		'vendor_id_raw' : vendor_id,
+		'brand_raw' : processor_brand,
 
-		'hz_advertised' : _to_friendly_hz(hz_advertised, scale),
-		'hz_actual' : _to_friendly_hz(hz_actual, 6),
-		'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale),
-		'hz_actual_raw' : _to_raw_hz(hz_actual, 6),
+		'hz_advertised_friendly' : _hz_short_to_friendly(hz_advertised, scale),
+		'hz_actual_friendly' : _hz_short_to_friendly(hz_actual, 6),
+		'hz_advertised' : _hz_short_to_full(hz_advertised, scale),
+		'hz_actual' : _hz_short_to_full(hz_actual, 6),
 
 		'flags' : flags
 		}
 
-		info = {k: v for k, v in info.items() if v}
+		info = _filter_dict_keys_with_empty_values(info)
+		g_trace.success()
 		return info
-	except:
+	except Exception as err:
+		g_trace.fail(err)
 		return {}
 
 def _get_cpu_info_from_kstat():
@@ -2034,19 +2523,25 @@ def _get_cpu_info_from_kstat():
 	Returns the CPU info gathered from isainfo and kstat.
 	Returns {} if isainfo or kstat are not found.
 	'''
+
+	g_trace.header('Tying to get info from kstat ...')
+
 	try:
 		# Just return {} if there is no isainfo or kstat
 		if not DataSource.has_isainfo() or not DataSource.has_kstat():
+			g_trace.fail('Failed to find isinfo or kstat. Skipping ...')
 			return {}
 
 		# If isainfo fails return {}
 		returncode, flag_output = DataSource.isainfo_vb()
 		if flag_output == None or returncode != 0:
+			g_trace.fail('Failed to run \"isainfo -vb\". Skipping ...')
 			return {}
 
 		# If kstat fails return {}
 		returncode, kstat = DataSource.kstat_m_cpu_info()
 		if kstat == None or returncode != 0:
+			g_trace.fail('Failed to run \"kstat -m cpu_info\". Skipping ...')
 			return {}
 
 		# Various fields
@@ -2063,20 +2558,20 @@ def _get_cpu_info_from_kstat():
 		# Convert from GHz/MHz string to Hz
 		scale = 6
 		hz_advertised = kstat.split('\tclock_MHz ')[1].split('\n')[0].strip()
-		hz_advertised = _to_hz_string(hz_advertised)
+		hz_advertised = _to_decimal_string(hz_advertised)
 
 		# Convert from GHz/MHz string to Hz
 		hz_actual = kstat.split('\tcurrent_clock_Hz ')[1].split('\n')[0].strip()
-		hz_actual = _to_hz_string(hz_actual)
+		hz_actual = _to_decimal_string(hz_actual)
 
 		info = {
-		'vendor_id' : vendor_id,
-		'brand' : processor_brand,
+		'vendor_id_raw' : vendor_id,
+		'brand_raw' : processor_brand,
 
-		'hz_advertised' : _to_friendly_hz(hz_advertised, scale),
-		'hz_actual' : _to_friendly_hz(hz_actual, 0),
-		'hz_advertised_raw' : _to_raw_hz(hz_advertised, scale),
-		'hz_actual_raw' : _to_raw_hz(hz_actual, 0),
+		'hz_advertised_friendly' : _hz_short_to_friendly(hz_advertised, scale),
+		'hz_actual_friendly' : _hz_short_to_friendly(hz_actual, 0),
+		'hz_advertised' : _hz_short_to_full(hz_advertised, scale),
+		'hz_actual' : _hz_short_to_full(hz_actual, 0),
 
 		'stepping' : stepping,
 		'model' : model,
@@ -2084,9 +2579,45 @@ def _get_cpu_info_from_kstat():
 		'flags' : flags
 		}
 
-		info = {k: v for k, v in info.items() if v}
+		info = _filter_dict_keys_with_empty_values(info)
+		g_trace.success()
 		return info
-	except:
+	except Exception as err:
+		g_trace.fail(err)
+		return {}
+
+def _get_cpu_info_from_platform_uname():
+
+	g_trace.header('Tying to get info from platform.uname ...')
+
+	try:
+		uname = DataSource.uname_string_raw.split(',')[0]
+
+		family, model, stepping = (None, None, None)
+		entries = uname.split(' ')
+
+		if 'Family' in entries and entries.index('Family') < len(entries)-1:
+			i = entries.index('Family')
+			family = int(entries[i + 1])
+
+		if 'Model' in entries and entries.index('Model') < len(entries)-1:
+			i = entries.index('Model')
+			model = int(entries[i + 1])
+
+		if 'Stepping' in entries and entries.index('Stepping') < len(entries)-1:
+			i = entries.index('Stepping')
+			stepping = int(entries[i + 1])
+
+		info = {
+			'family' : family,
+			'model' : model,
+			'stepping' : stepping
+		}
+		info = _filter_dict_keys_with_empty_values(info)
+		g_trace.success()
+		return info
+	except Exception as err:
+		g_trace.fail(err)
 		return {}
 
 def _get_cpu_info_internal():
@@ -2095,8 +2626,10 @@ def _get_cpu_info_internal():
 	Returns {} if nothing is found.
 	'''
 
+	g_trace.write('!' * 80)
+
 	# Get the CPU arch and bits
-	arch, bits = _parse_arch(DataSource.raw_arch_string)
+	arch, bits = _parse_arch(DataSource.arch_string_raw)
 
 	friendly_maxsize = { 2**31-1: '32 bit', 2**63-1: '64 bit' }.get(sys.maxsize) or 'unknown bits'
 	friendly_version = "{0}.{1}.{2}.{3}.{4}".format(*sys.version_info)
@@ -2105,12 +2638,20 @@ def _get_cpu_info_internal():
 	info = {
 		'python_version' : PYTHON_VERSION,
 		'cpuinfo_version' : CPUINFO_VERSION,
+		'cpuinfo_version_string' : CPUINFO_VERSION_STRING,
 		'arch' : arch,
 		'bits' : bits,
 		'count' : DataSource.cpu_count,
-		'raw_arch_string' : DataSource.raw_arch_string,
+		'arch_string_raw' : DataSource.arch_string_raw,
 	}
 
+	g_trace.write("python_version: {0}".format(info['python_version']))
+	g_trace.write("cpuinfo_version: {0}".format(info['cpuinfo_version']))
+	g_trace.write("arch: {0}".format(info['arch']))
+	g_trace.write("bits: {0}".format(info['bits']))
+	g_trace.write("count: {0}".format(info['count']))
+	g_trace.write("arch_string_raw: {0}".format(info['arch_string_raw']))
+
 	# Try the Windows wmic
 	_copy_new_fields(info, _get_cpu_info_from_wmic())
 
@@ -2145,8 +2686,14 @@ def _get_cpu_info_internal():
 	_copy_new_fields(info, _get_cpu_info_from_sysinfo())
 
 	# Try querying the CPU cpuid register
+	# FIXME: This should print stdout and stderr to trace log
 	_copy_new_fields(info, _get_cpu_info_from_cpuid())
 
+	# Try platform.uname
+	_copy_new_fields(info, _get_cpu_info_from_platform_uname())
+
+	g_trace.write('!' * 80)
+
 	return info
 
 def get_cpu_info_json():
@@ -2204,8 +2751,13 @@ def main():
 	# Parse args
 	parser = ArgumentParser(description='Gets CPU info with pure Python 2 & 3')
 	parser.add_argument('--json', action='store_true', help='Return the info in JSON format')
+	parser.add_argument('--version', action='store_true', help='Return the version of py-cpuinfo')
+	parser.add_argument('--trace', action='store_true', help='Traces code paths used to find CPU info to file')
 	args = parser.parse_args()
 
+	global g_trace
+	g_trace = Trace(args.trace, False)
+
 	try:
 		_check_arch()
 	except Exception as err:
@@ -2220,22 +2772,22 @@ def main():
 
 	if args.json:
 		print(json.dumps(info))
+	elif args.version:
+		print(CPUINFO_VERSION_STRING)
 	else:
 		print('Python Version: {0}'.format(info.get('python_version', '')))
-		print('Cpuinfo Version: {0}'.format(info.get('cpuinfo_version', '')))
-		print('Vendor ID: {0}'.format(info.get('vendor_id', '')))
-		print('Hardware Raw: {0}'.format(info.get('hardware', '')))
-		print('Brand: {0}'.format(info.get('brand', '')))
+		print('Cpuinfo Version: {0}'.format(info.get('cpuinfo_version_string', '')))
+		print('Vendor ID Raw: {0}'.format(info.get('vendor_id_raw', '')))
+		print('Hardware Raw: {0}'.format(info.get('hardware_raw', '')))
+		print('Brand Raw: {0}'.format(info.get('brand_raw', '')))
+		print('Hz Advertised Friendly: {0}'.format(info.get('hz_advertised_friendly', '')))
+		print('Hz Actual Friendly: {0}'.format(info.get('hz_actual_friendly', '')))
 		print('Hz Advertised: {0}'.format(info.get('hz_advertised', '')))
 		print('Hz Actual: {0}'.format(info.get('hz_actual', '')))
-		print('Hz Advertised Raw: {0}'.format(info.get('hz_advertised_raw', '')))
-		print('Hz Actual Raw: {0}'.format(info.get('hz_actual_raw', '')))
 		print('Arch: {0}'.format(info.get('arch', '')))
 		print('Bits: {0}'.format(info.get('bits', '')))
 		print('Count: {0}'.format(info.get('count', '')))
-
-		print('Raw Arch String: {0}'.format(info.get('raw_arch_string', '')))
-
+		print('Arch String Raw: {0}'.format(info.get('arch_string_raw', '')))
 		print('L1 Data Cache Size: {0}'.format(info.get('l1_data_cache_size', '')))
 		print('L1 Instruction Cache Size: {0}'.format(info.get('l1_instruction_cache_size', '')))
 		print('L2 Cache Size: {0}'.format(info.get('l2_cache_size', '')))
@@ -2246,12 +2798,11 @@ def main():
 		print('Model: {0}'.format(info.get('model', '')))
 		print('Family: {0}'.format(info.get('family', '')))
 		print('Processor Type: {0}'.format(info.get('processor_type', '')))
-		print('Extended Model: {0}'.format(info.get('extended_model', '')))
-		print('Extended Family: {0}'.format(info.get('extended_family', '')))
 		print('Flags: {0}'.format(', '.join(info.get('flags', ''))))
 
 
 if __name__ == '__main__':
 	main()
 else:
+	g_trace = Trace(False, False)
 	_check_arch()
diff --git a/py_cpuinfo.egg-info/PKG-INFO b/py_cpuinfo.egg-info/PKG-INFO
index 8495ee5..79160ee 100644
--- a/py_cpuinfo.egg-info/PKG-INFO
+++ b/py_cpuinfo.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: py-cpuinfo
-Version: 5.0.0
+Version: 8.0.0
 Summary: Get CPU info with pure Python 2 & 3
 Home-page: https://github.com/workhorsy/py-cpuinfo
 Author: Matthew Brennan Jones
diff --git a/py_cpuinfo.egg-info/SOURCES.txt b/py_cpuinfo.egg-info/SOURCES.txt
index 908a413..3e9bb22 100644
--- a/py_cpuinfo.egg-info/SOURCES.txt
+++ b/py_cpuinfo.egg-info/SOURCES.txt
@@ -15,30 +15,40 @@ py_cpuinfo.egg-info/top_level.txt
 tests/helpers.py
 tests/test_actual.py
 tests/test_cli.py
+tests/test_compile_errors.py
 tests/test_cpuid.py
 tests/test_example.py
 tests/test_free_bsd_11_x86_64.py
 tests/test_haiku_x86_32.py
 tests/test_haiku_x86_64.py
+tests/test_haiku_x86_64_beta_1_ryzen_7.py
 tests/test_invalid_cpu.py
 tests/test_linux_aarch64_64.py
+tests/test_linux_alt_p9_mipsel_bfk3.py
 tests/test_linux_beagle_bone_arm.py
 tests/test_linux_debian_8_5_x86_64.py
 tests/test_linux_debian_8_7_1_ppc64le.py
 tests/test_linux_debian_8_x86_64.py
 tests/test_linux_fedora_24_ppc64le.py
 tests/test_linux_fedora_24_x86_64.py
+tests/test_linux_fedora_29_x86_64_ryzen_7.py
+tests/test_linux_fedora_5_s390x.py
 tests/test_linux_gentoo_2_2_x86_64.py
+tests/test_linux_mips64el_loongson3A3000.py
 tests/test_linux_odroid_c2_aarch64.py
 tests/test_linux_odroid_xu3_arm_32.py
 tests/test_linux_raspberry_pi_model_b_arm.py
 tests/test_linux_rhel_7_3_ppc64le.py
 tests/test_linux_ubuntu_16_04_x86_64.py
+tests/test_open_indiana_5_11_x86_64_ryzen_7.py
 tests/test_osx_10_12_x86_64.py
 tests/test_osx_10_9_x86_64.py
 tests/test_parse_cpu_string.py
 tests/test_parse_errors.py
 tests/test_pcbsd_10_x86_64.py
+tests/test_selinux.py
 tests/test_solaris_11_x86_32.py
+tests/test_true_os_18_x86_64_ryzen_7.py
 tests/test_windows_10_x86_64.py
+tests/test_windows_10_x86_64_ryzen_7.py
 tests/test_windows_8_x86_64.py
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 2da6fb9..8f602c0 100644
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2014-2019, Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
+# Copyright (c) 2014-2021 Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
 # Py-cpuinfo gets CPU info with pure Python 2 & 3
 # It uses the MIT License
 # It is hosted at: https://github.com/workhorsy/py-cpuinfo
@@ -11,7 +11,7 @@ with open(os.path.join(os.getcwd(), 'README.rst'), 'r') as f:
 
 setup(
     name = "py-cpuinfo",
-    version = "5.0.0",
+    version = "8.0.0",
     author = "Matthew Brennan Jones",
     author_email = "matthew.brennan.jones@gmail.com",
     description = "Get CPU info with pure Python 2 & 3",
diff --git a/test_suite.py b/test_suite.py
index f2fe6e9..4c61ae2 100644
--- a/test_suite.py
+++ b/test_suite.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
-# Copyright (c) 2014-2019, Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
+# Copyright (c) 2014-2021 Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
 # Py-cpuinfo gets CPU info with pure Python 2 & 3
 # It uses the MIT License
 # It is hosted at: https://github.com/workhorsy/py-cpuinfo
@@ -35,16 +35,20 @@ sys.path.append(os.path.realpath('tests'))
 
 
 # Import all the test files
+from test_compile_errors import TestCompileErrors
 from test_example import TestExample
 from test_parse_errors import TestParseErrors
 from test_parse_cpu_string import TestParseCPUString
 from test_invalid_cpu import TestInvalidCPU
+from test_selinux import TestSELinux
 from test_linux_debian_8_x86_64 import TestLinuxDebian_8_X86_64
 from test_linux_debian_8_5_x86_64 import TestLinuxDebian_8_5_X86_64
 from test_linux_debian_8_7_1_ppc64le import TestLinuxDebian_8_7_1_ppc64le
 from test_linux_ubuntu_16_04_x86_64 import TestLinuxUbuntu_16_04_X86_64
 from test_linux_fedora_24_x86_64 import TestLinuxFedora_24_X86_64
 from test_linux_fedora_24_ppc64le import TestLinuxFedora_24_ppc64le
+from test_linux_fedora_29_x86_64_ryzen_7 import Test_Linux_Fedora_29_X86_64_Ryzen_7
+from test_linux_fedora_5_s390x import TestLinuxFedora_5_s390x
 from test_linux_aarch64_64 import TestLinux_Aarch_64
 from test_linux_gentoo_2_2_x86_64 import TestLinuxGentoo_2_2_X86_64
 from test_linux_rhel_7_3_ppc64le import TestLinuxRHEL_7_3_ppc64le
@@ -52,15 +56,21 @@ from test_linux_beagle_bone_arm import TestLinux_BeagleBone
 from test_linux_raspberry_pi_model_b_arm import TestLinux_RaspberryPiModelB
 from test_linux_odroid_c2_aarch64 import TestLinux_Odroid_C2_Aarch_64
 from test_linux_odroid_xu3_arm_32 import TestLinux_Odroid_XU3_arm_32
+from test_linux_alt_p9_mipsel_bfk3 import TestLinuxAlt_p9_mipsel_bfk3
+from test_linux_mips64el_loongson3A3000 import TestLinux_mips64el_Loongson3A3000
 from test_pcbsd_10_x86_64 import TestPCBSD
 from test_free_bsd_11_x86_64 import TestFreeBSD_11_X86_64
 from test_osx_10_9_x86_64 import TestOSX_10_9
 from test_osx_10_12_x86_64 import TestOSX_10_12
-from test_solaris_11_x86_32 import TestSolaris
+from test_solaris_11_x86_32 import TestSolaris_11
+from test_open_indiana_5_11_x86_64_ryzen_7 import TestOpenIndiana_5_11_Ryzen_7
 from test_haiku_x86_32 import TestHaiku_x86_32
 from test_haiku_x86_64 import TestHaiku_x86_64
+from test_haiku_x86_64_beta_1_ryzen_7 import TestHaiku_x86_64_Beta_1_Ryzen7
+from test_true_os_18_x86_64_ryzen_7 import TestTrueOS_18_X86_64_Ryzen7
 from test_windows_8_x86_64 import TestWindows_8_X86_64
 from test_windows_10_x86_64 import TestWindows_10_X86_64
+from test_windows_10_x86_64_ryzen_7 import TestWindows_10_X86_64_Ryzen7
 from test_cpuid import TestCPUID
 from test_actual import TestActual
 from test_cli import TestCLI
@@ -73,16 +83,22 @@ if __name__ == '__main__':
 
 	# Get all the tests
 	tests = [
+		TestCompileErrors,
 		TestParseCPUString,
 		TestExample,
 		TestParseErrors,
 		TestInvalidCPU,
+		TestSELinux,
+		TestLinuxAlt_p9_mipsel_bfk3,
+		TestLinux_mips64el_Loongson3A3000,
 		TestLinuxDebian_8_X86_64,
 		TestLinuxDebian_8_5_X86_64,
 		TestLinuxDebian_8_7_1_ppc64le,
 		TestLinuxUbuntu_16_04_X86_64,
 		TestLinuxFedora_24_X86_64,
 		TestLinuxFedora_24_ppc64le,
+		Test_Linux_Fedora_29_X86_64_Ryzen_7,
+		TestLinuxFedora_5_s390x,
 		TestLinux_Aarch_64,
 		TestLinuxGentoo_2_2_X86_64,
 		TestLinuxRHEL_7_3_ppc64le,
@@ -94,11 +110,15 @@ if __name__ == '__main__':
 		TestPCBSD,
 		TestOSX_10_9,
 		TestOSX_10_12,
-		TestSolaris,
+		TestSolaris_11,
+		TestOpenIndiana_5_11_Ryzen_7,
 		TestHaiku_x86_32,
 		TestHaiku_x86_64,
+		TestHaiku_x86_64_Beta_1_Ryzen7,
+		TestTrueOS_18_X86_64_Ryzen7,
 		TestWindows_8_X86_64,
 		TestWindows_10_X86_64,
+		TestWindows_10_X86_64_Ryzen7,
 		TestCPUID,
 		TestActual,
 		TestCLI
diff --git a/tests/helpers.py b/tests/helpers.py
index a29b344..6818374 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
-# Copyright (c) 2014-2019, Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
+# Copyright (c) 2014-2021 Matthew Brennan Jones <matthew.brennan.jones@gmail.com>
 # Py-cpuinfo gets CPU info with pure Python 2 & 3
 # It uses the MIT License
 # It is hosted at: https://github.com/workhorsy/py-cpuinfo
@@ -115,8 +115,10 @@ def _actual_monkey_patch_data_source(cpuinfo, NewDataSource):
 		cpuinfo.DataSource.cpu_count = NewDataSource.cpu_count
 	if hasattr(NewDataSource, 'is_windows'):
 		cpuinfo.DataSource.is_windows = NewDataSource.is_windows
-	if hasattr(NewDataSource, 'raw_arch_string'):
-		cpuinfo.DataSource.raw_arch_string = NewDataSource.raw_arch_string
+	if hasattr(NewDataSource, 'arch_string_raw'):
+		cpuinfo.DataSource.arch_string_raw = NewDataSource.arch_string_raw
+	if hasattr(NewDataSource, 'uname_string_raw'):
+		cpuinfo.DataSource.uname_string_raw = NewDataSource.uname_string_raw
 	if hasattr(NewDataSource, 'can_cpuid'):
 		cpuinfo.DataSource.can_cpuid = NewDataSource.can_cpuid
 
@@ -148,10 +150,8 @@ def _actual_monkey_patch_data_source(cpuinfo, NewDataSource):
 		cpuinfo.DataSource.cat_proc_cpuinfo = staticmethod(NewDataSource.cat_proc_cpuinfo)
 	if hasattr(NewDataSource, 'cpufreq_info'):
 		cpuinfo.DataSource.cpufreq_info = staticmethod(NewDataSource.cpufreq_info)
-	if hasattr(NewDataSource, 'sestatus_allow_execheap'):
-		cpuinfo.DataSource.sestatus_allow_execheap = staticmethod(NewDataSource.sestatus_allow_execheap)
-	if hasattr(NewDataSource, 'sestatus_allow_execmem'):
-		cpuinfo.DataSource.sestatus_allow_execmem = staticmethod(NewDataSource.sestatus_allow_execmem)
+	if hasattr(NewDataSource, 'sestatus_b'):
+		cpuinfo.DataSource.sestatus_b = staticmethod(NewDataSource.sestatus_b)
 	if hasattr(NewDataSource, 'dmesg_a'):
 		cpuinfo.DataSource.dmesg_a = staticmethod(NewDataSource.dmesg_a)
 	if hasattr(NewDataSource, 'cat_var_run_dmesg_boot'):
@@ -172,10 +172,10 @@ def _actual_monkey_patch_data_source(cpuinfo, NewDataSource):
 		cpuinfo.DataSource.sysinfo_cpu = staticmethod(NewDataSource.sysinfo_cpu)
 	if hasattr(NewDataSource, 'winreg_processor_brand'):
 		cpuinfo.DataSource.winreg_processor_brand = staticmethod(NewDataSource.winreg_processor_brand)
-	if hasattr(NewDataSource, 'winreg_vendor_id'):
-		cpuinfo.DataSource.winreg_vendor_id = staticmethod(NewDataSource.winreg_vendor_id)
-	if hasattr(NewDataSource, 'winreg_raw_arch_string'):
-		cpuinfo.DataSource.winreg_raw_arch_string = staticmethod(NewDataSource.winreg_raw_arch_string)
+	if hasattr(NewDataSource, 'winreg_vendor_id_raw'):
+		cpuinfo.DataSource.winreg_vendor_id_raw = staticmethod(NewDataSource.winreg_vendor_id_raw)
+	if hasattr(NewDataSource, 'winreg_arch_string_raw'):
+		cpuinfo.DataSource.winreg_arch_string_raw = staticmethod(NewDataSource.winreg_arch_string_raw)
 	if hasattr(NewDataSource, 'winreg_hz_actual'):
 		cpuinfo.DataSource.winreg_hz_actual = staticmethod(NewDataSource.winreg_hz_actual)
 	if hasattr(NewDataSource, 'winreg_feature_bits'):
@@ -187,7 +187,8 @@ def backup_data_source(cpuinfo):
 	cpuinfo.BackupDataSource.bits = cpuinfo.DataSource.bits
 	cpuinfo.BackupDataSource.cpu_count = cpuinfo.DataSource.cpu_count
 	cpuinfo.BackupDataSource.is_windows = cpuinfo.DataSource.is_windows
-	cpuinfo.BackupDataSource.raw_arch_string = cpuinfo.DataSource.raw_arch_string
+	cpuinfo.BackupDataSource.arch_string_raw = cpuinfo.DataSource.arch_string_raw
+	cpuinfo.BackupDataSource.uname_string_raw = cpuinfo.DataSource.uname_string_raw
 	cpuinfo.BackupDataSource.can_cpuid = cpuinfo.DataSource.can_cpuid
 
 	cpuinfo.BackupDataSource.has_proc_cpuinfo = staticmethod(cpuinfo.DataSource.has_proc_cpuinfo)
@@ -204,8 +205,7 @@ def backup_data_source(cpuinfo):
 	cpuinfo.BackupDataSource.has_wmic = staticmethod(cpuinfo.DataSource.has_wmic)
 	cpuinfo.BackupDataSource.cat_proc_cpuinfo = staticmethod(cpuinfo.DataSource.cat_proc_cpuinfo)
 	cpuinfo.BackupDataSource.cpufreq_info = staticmethod(cpuinfo.DataSource.cpufreq_info)
-	cpuinfo.BackupDataSource.sestatus_allow_execheap = staticmethod(cpuinfo.DataSource.sestatus_allow_execheap)
-	cpuinfo.BackupDataSource.sestatus_allow_execmem = staticmethod(cpuinfo.DataSource.sestatus_allow_execmem)
+	cpuinfo.BackupDataSource.sestatus_b = staticmethod(cpuinfo.DataSource.sestatus_b)
 	cpuinfo.BackupDataSource.dmesg_a = staticmethod(cpuinfo.DataSource.dmesg_a)
 	cpuinfo.BackupDataSource.cat_var_run_dmesg_boot = staticmethod(cpuinfo.DataSource.cat_var_run_dmesg_boot)
 	cpuinfo.BackupDataSource.sysctl_machdep_cpu_hw_cpufrequency = staticmethod(cpuinfo.DataSource.sysctl_machdep_cpu_hw_cpufrequency)
@@ -216,8 +216,8 @@ def backup_data_source(cpuinfo):
 	cpuinfo.BackupDataSource.wmic_cpu = staticmethod(cpuinfo.DataSource.wmic_cpu)
 	cpuinfo.BackupDataSource.sysinfo_cpu = staticmethod(cpuinfo.DataSource.sysinfo_cpu)
 	cpuinfo.BackupDataSource.winreg_processor_brand = staticmethod(cpuinfo.DataSource.winreg_processor_brand)
-	cpuinfo.BackupDataSource.winreg_vendor_id = staticmethod(cpuinfo.DataSource.winreg_vendor_id)
-	cpuinfo.BackupDataSource.winreg_raw_arch_string = staticmethod(cpuinfo.DataSource.winreg_raw_arch_string)
+	cpuinfo.BackupDataSource.winreg_vendor_id_raw = staticmethod(cpuinfo.DataSource.winreg_vendor_id_raw)
+	cpuinfo.BackupDataSource.winreg_arch_string_raw = staticmethod(cpuinfo.DataSource.winreg_arch_string_raw)
 	cpuinfo.BackupDataSource.winreg_hz_actual = staticmethod(cpuinfo.DataSource.winreg_hz_actual)
 	cpuinfo.BackupDataSource.winreg_feature_bits = staticmethod(cpuinfo.DataSource.winreg_feature_bits)
 
@@ -225,7 +225,8 @@ def restore_data_source(cpuinfo):
 	cpuinfo.DataSource.bits = cpuinfo.BackupDataSource.bits
 	cpuinfo.DataSource.cpu_count = cpuinfo.BackupDataSource.cpu_count
 	cpuinfo.DataSource.is_windows = cpuinfo.BackupDataSource.is_windows
-	cpuinfo.DataSource.raw_arch_string = cpuinfo.BackupDataSource.raw_arch_string
+	cpuinfo.DataSource.arch_string_raw = cpuinfo.BackupDataSource.arch_string_raw
+	cpuinfo.DataSource.uname_string_raw = cpuinfo.BackupDataSource.uname_string_raw
 	cpuinfo.DataSource.can_cpuid = cpuinfo.BackupDataSource.can_cpuid
 
 	cpuinfo.DataSource.has_proc_cpuinfo = cpuinfo.BackupDataSource.has_proc_cpuinfo
@@ -242,8 +243,7 @@ def restore_data_source(cpuinfo):
 	cpuinfo.DataSource.has_wmic = cpuinfo.BackupDataSource.has_wmic
 	cpuinfo.DataSource.cat_proc_cpuinfo = cpuinfo.BackupDataSource.cat_proc_cpuinfo
 	cpuinfo.DataSource.cpufreq_info = cpuinfo.BackupDataSource.cpufreq_info
-	cpuinfo.DataSource.sestatus_allow_execheap = cpuinfo.BackupDataSource.sestatus_allow_execheap
-	cpuinfo.DataSource.sestatus_allow_execmem = cpuinfo.BackupDataSource.sestatus_allow_execmem
+	cpuinfo.DataSource.sestatus_b = cpuinfo.BackupDataSource.sestatus_b
 	cpuinfo.DataSource.dmesg_a = cpuinfo.BackupDataSource.dmesg_a
 	cpuinfo.DataSource.cat_var_run_dmesg_boot = cpuinfo.BackupDataSource.cat_var_run_dmesg_boot
 	cpuinfo.DataSource.sysctl_machdep_cpu_hw_cpufrequency = cpuinfo.BackupDataSource.sysctl_machdep_cpu_hw_cpufrequency
@@ -254,7 +254,66 @@ def restore_data_source(cpuinfo):
 	cpuinfo.DataSource.wmic_cpu = cpuinfo.BackupDataSource.wmic_cpu
 	cpuinfo.DataSource.sysinfo_cpu = cpuinfo.BackupDataSource.sysinfo_cpu
 	cpuinfo.DataSource.winreg_processor_brand = cpuinfo.BackupDataSource.winreg_processor_brand
-	cpuinfo.DataSource.winreg_vendor_id = cpuinfo.BackupDataSource.winreg_vendor_id
-	cpuinfo.DataSource.winreg_raw_arch_string = cpuinfo.BackupDataSource.winreg_raw_arch_string
+	cpuinfo.DataSource.winreg_vendor_id_raw = cpuinfo.BackupDataSource.winreg_vendor_id_raw
+	cpuinfo.DataSource.winreg_arch_string_raw = cpuinfo.BackupDataSource.winreg_arch_string_raw
 	cpuinfo.DataSource.winreg_hz_actual = cpuinfo.BackupDataSource.winreg_hz_actual
 	cpuinfo.DataSource.winreg_feature_bits = cpuinfo.BackupDataSource.winreg_feature_bits
+
+def backup_cpuid(cpuinfo):
+	BackupCPUID = type('BackupCPUID', (object,), {})
+	cpuinfo.BackupCPUID = BackupCPUID()
+	cpuinfo.BackupCPUID._run_asm = cpuinfo.CPUID._run_asm
+	cpuinfo.BackupCPUID._asm_func = cpuinfo.CPUID._asm_func
+
+def monkey_patch_cpuid(cpuinfo, return_hz, return_values):
+	class MockCPUID(object):
+		_counter = 0
+		_is_first = False
+
+		def _asm_func(self, restype=None, argtypes=(), machine_code=[]):
+			class CPUIDGetTicks(object):
+				# NOTE: This assumes that the function returned is a get_ticks function
+				def func(self):
+					MockCPUID._is_first = not MockCPUID._is_first
+
+					if MockCPUID._is_first:
+						return return_hz
+					else:
+						return 0
+
+				def free(self):
+					pass
+
+			return CPUIDGetTicks()
+
+		def _run_asm(self, *machine_code):
+			result = return_values[MockCPUID._counter]
+			MockCPUID._counter += 1
+			if MockCPUID._counter == len(return_values):
+				MockCPUID._counter = 0
+			return result
+
+	cpuinfo.CPUID._run_asm = MockCPUID.__dict__['_run_asm']
+	cpuinfo.CPUID._asm_func = MockCPUID.__dict__['_asm_func']
+
+def restore_cpuid(cpuinfo):
+	cpuinfo.CPUID._run_asm = cpuinfo.BackupCPUID._run_asm
+	cpuinfo.CPUID._asm_func = cpuinfo.BackupCPUID._asm_func
+
+
+def backup_asm(cpuinfo):
+	BackupASM = type('BackupASM', (object,), {})
+	cpuinfo.BackupASM = BackupASM()
+	cpuinfo.BackupASM.compile = cpuinfo.ASM.compile
+	cpuinfo.BackupASM.run = cpuinfo.ASM.run
+	cpuinfo.BackupASM.free = cpuinfo.ASM.free
+
+def monkey_patch_asm(cpuinfo, NewASM):
+	cpuinfo.ASM.compile = NewASM.__dict__['compile']
+	cpuinfo.ASM.run = NewASM.__dict__['run']
+	cpuinfo.ASM.free = NewASM.__dict__['free']
+
+def restore_asm(cpuinfo):
+	cpuinfo.ASM.compile = cpuinfo.BackupASM.compile
+	cpuinfo.ASM.run = cpuinfo.BackupASM.run
+	cpuinfo.ASM.free = cpuinfo.BackupASM.free
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 991f9c8..f8a1867 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -29,6 +29,53 @@ class TestCLI(unittest.TestCase):
 		info = json.loads(output, object_hook = cpuinfo._utf_to_str)
 
 		self.assertEqual(list(cpuinfo.CPUINFO_VERSION), info['cpuinfo_version'])
+		self.assertEqual(cpuinfo.CPUINFO_VERSION_STRING, info['cpuinfo_version_string'])
+
+	def test_version(self):
+		from subprocess import Popen, PIPE
+
+		command = [sys.executable, 'cpuinfo/cpuinfo.py', '--version']
+		p1 = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
+		output = p1.communicate()[0]
+
+		self.assertEqual(0, p1.returncode)
+
+		if not IS_PY2:
+			output = output.decode(encoding='UTF-8')
+		output = output.strip()
+
+		self.assertEqual(cpuinfo.CPUINFO_VERSION_STRING, output)
+
+	def test_trace(self):
+		import os
+		import re
+		from subprocess import Popen, PIPE
+
+		# Get all log files before test
+		before_log_files = [f for f in os.listdir('.') if os.path.isfile(f) and re.match(r'^cpuinfo_trace_\d+-\d+-\d+_\d+-\d+-\d+-\d+.trace$', f)]
+		#print('\n', before_log_files)
+
+		# Run with trace to generate new log file
+		command = [sys.executable, 'cpuinfo/cpuinfo.py', '--trace']
+		p1 = Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE)
+		output = p1.communicate()[0]
+		self.assertEqual(0, p1.returncode)
+
+		# Get all log files after test
+		after_log_files = [f for f in os.listdir('.') if os.path.isfile(f) and re.match(r'^cpuinfo_trace_\d+-\d+-\d+_\d+-\d+-\d+-\d+.trace$', f)]
+		#print('\n', after_log_files)
+
+		# Read the new log file into a string
+		new_log_file = list(set(after_log_files) - set(before_log_files))[0]
+		with open(new_log_file, 'r') as f:
+			output = f.read().strip()
+
+		# Remove the new log file
+		os.remove(new_log_file)
+
+		self.assertTrue(len(output) > 200)
+		self.assertTrue(output.startswith('!' * 80))
+		self.assertTrue(output.endswith('!' * 80))
 
 	def test_default(self):
 		from subprocess import Popen, PIPE
@@ -44,4 +91,4 @@ class TestCLI(unittest.TestCase):
 
 		version = output.split('Cpuinfo Version: ')[1].split('\n')[0].strip()
 
-		self.assertEqual(str(cpuinfo.CPUINFO_VERSION), version)
+		self.assertEqual(cpuinfo.CPUINFO_VERSION_STRING, version)
diff --git a/tests/test_compile_errors.py b/tests/test_compile_errors.py
new file mode 100644
index 0000000..7bd490a
--- /dev/null
+++ b/tests/test_compile_errors.py
@@ -0,0 +1,37 @@
+
+
+import unittest
+from cpuinfo import *
+import helpers
+
+
+class TestCompileErrors(unittest.TestCase):
+	def test_all(self):
+		self.maxDiff = None
+
+		import os
+		from subprocess import Popen, PIPE
+
+		# Find all the python files
+		py_files = []
+		for root, dirs, files in os.walk("."):
+			for file in files:
+					if file.lower().endswith(".py"):
+						py_files.append(os.path.join(root, file).lstrip(".\\").lstrip('/'))
+
+
+		# Compile the files and check for errors
+		command = sys.executable + " -Wall -m py_compile " + ' '.join(py_files)
+		p1 = Popen(command.split(' '), stdout=PIPE, stderr=PIPE, stdin=PIPE)
+		p1_stdout, p1_stderr = p1.communicate()
+
+		if not cpuinfo.IS_PY2:
+			p1_stdout = p1_stdout.decode(encoding='UTF-8')
+
+		if not cpuinfo.IS_PY2:
+			p1_stderr = p1_stderr.decode(encoding='UTF-8')
+
+		# Check for no errors
+		self.assertEqual("", p1_stderr)
+		self.assertEqual("", p1_stdout)
+		self.assertEqual(0, p1.returncode)
diff --git a/tests/test_cpuid.py b/tests/test_cpuid.py
index 093e949..dc5e4f6 100644
--- a/tests/test_cpuid.py
+++ b/tests/test_cpuid.py
@@ -5,12 +5,218 @@ from cpuinfo import *
 import helpers
 
 
+class MockASM(ASM):
+	is_first = False
+
+	def __init__(self, restype=None, argtypes=(), machine_code=[]):
+		super(MockASM, self).__init__(restype, argtypes, machine_code)
+
+	def compile(self):
+		self.func = self.run
+
+	def run(self):
+		machine_code = tuple(self.machine_code)
+
+		# get_max_extension_support
+		if machine_code == \
+			(b"\xB8\x00\x00\x00\x80" # mov ax,0x80000000
+			b"\x0f\xa2"               # cpuid
+			b"\xC3",):               # ret
+			return 0x8000001f
+
+		# get_cache
+		if machine_code == \
+			(b"\xB8\x06\x00\x00\x80"  # mov ax,0x80000006
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xC8"                # mov ax,cx
+			b"\xC3",):                # ret))
+			return 0x2006140
+
+		# get_info
+		if machine_code == \
+			(b"\xB8\x01\x00\x00\x00",  # mov eax,0x1"
+			b"\x0f\xa2"                # cpuid
+			b"\xC3",):                # ret
+			return 0x800f82
+
+		# get_processor_brand
+		if machine_code == \
+			(b"\xB8\x02\x00\x00\x80",  # mov ax,0x80000002
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xC0"                # mov ax,ax
+			b"\xC3",):                 # ret
+			return 0x20444d41
+		elif machine_code == \
+			(b"\xB8\x02\x00\x00\x80",  # mov ax,0x80000002
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xD8"                # mov ax,bx
+			b"\xC3",):                 # ret
+			return 0x657a7952
+		elif machine_code == \
+			(b"\xB8\x02\x00\x00\x80",  # mov ax,0x80000002
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xC8"                # mov ax,cx
+			b"\xC3",):                 # ret
+			return 0x2037206e
+		elif machine_code == \
+			(b"\xB8\x02\x00\x00\x80",  # mov ax,0x80000002
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xD0"                # mov ax,dx
+			b"\xC3",):                 # ret
+			return 0x30303732
+		elif machine_code == \
+			(b"\xB8\x03\x00\x00\x80",  # mov ax,0x80000003
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xC0"                # mov ax,ax
+			b"\xC3",):                 # ret
+			return 0x69452058
+		elif machine_code == \
+			(b"\xB8\x03\x00\x00\x80",  # mov ax,0x80000003
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xD8"                # mov ax,bx
+			b"\xC3",):                 # ret
+			return 0x2d746867
+		elif machine_code == \
+			(b"\xB8\x03\x00\x00\x80",  # mov ax,0x80000003
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xC8"                # mov ax,cx
+			b"\xC3",):                 # ret
+			return 0x65726f43
+		elif machine_code == \
+			(b"\xB8\x03\x00\x00\x80",  # mov ax,0x80000003
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xD0"                # mov ax,dx
+			b"\xC3",):                 # ret
+			return 0x6f725020
+		elif machine_code == \
+			(b"\xB8\x04\x00\x00\x80",  # mov ax,0x80000004
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xC0"                # mov ax,ax
+			b"\xC3",):                 # ret
+			return 0x73736563
+		elif machine_code == \
+			(b"\xB8\x04\x00\x00\x80",  # mov ax,0x80000004
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xD8"                # mov ax,bx
+			b"\xC3",):                 # ret
+			return 0x2020726f
+		elif machine_code == \
+			(b"\xB8\x04\x00\x00\x80",  # mov ax,0x80000004
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xC8"                # mov ax,cx
+			b"\xC3",):                 # ret
+			return 0x20202020
+		elif machine_code == \
+			(b"\xB8\x04\x00\x00\x80",  # mov ax,0x80000004
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xD0"                # mov ax,dx
+			b"\xC3",):                 # ret
+			return 0x202020
+
+		# get_vendor_id
+		if machine_code == \
+			(b"\x31\xC0",             # xor eax,eax
+			b"\x0F\xA2"               # cpuid
+			b"\x89\xD8"               # mov ax,bx
+			b"\xC3",):                # ret
+			return 0x68747541
+		elif machine_code == \
+			(b"\x31\xC0",             # xor eax,eax
+			b"\x0f\xa2"               # cpuid
+			b"\x89\xC8"               # mov ax,cx
+			b"\xC3",):                # ret
+			return 0x444d4163
+		elif machine_code == \
+			(b"\x31\xC0",             # xor eax,eax
+			b"\x0f\xa2"               # cpuid
+			b"\x89\xD0"               # mov ax,dx
+			b"\xC3",):                # ret
+			return 0x69746e65
+
+		# get_flags
+		if machine_code == \
+			(b"\xB8\x01\x00\x00\x00", # mov eax,0x1"
+			b"\x0f\xa2"               # cpuid
+			b"\x89\xD0"               # mov ax,dx
+			b"\xC3",):                 # ret
+			return 0x178bfbff
+		elif machine_code == \
+			(b"\xB8\x01\x00\x00\x00", # mov eax,0x1"
+			b"\x0f\xa2"               # cpuid
+			b"\x89\xC8"               # mov ax,cx
+			b"\xC3",):                # ret
+			return 0x7ed8320b
+		elif machine_code == \
+			(b"\x31\xC9",              # xor ecx,ecx
+			b"\xB8\x07\x00\x00\x00"    # mov eax,7
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xD8"                # mov ax,bx
+			b"\xC3",):                 # ret
+			return 0x209c01a9
+		elif machine_code == \
+			(b"\x31\xC9",              # xor ecx,ecx
+			b"\xB8\x07\x00\x00\x00"    # mov eax,7
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xC8"                # mov ax,cx
+			b"\xC3",):                 # ret
+			return 0x0
+		elif machine_code == \
+			(b"\xB8\x01\x00\x00\x80"   # mov ax,0x80000001
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xD8"                # mov ax,bx
+			b"\xC3",):                 # ret
+			return 0x20000000
+		elif machine_code == \
+			(b"\xB8\x01\x00\x00\x80"   # mov ax,0x80000001
+			b"\x0f\xa2"                # cpuid
+			b"\x89\xC8"                # mov ax,cx
+			b"\xC3",):                 # ret
+			return 0x35c233ff
+
+		# get_ticks
+		# 32 bit
+		if machine_code == \
+			(b"\x55",         # push bp
+			b"\x89\xE5",     # mov bp,sp
+			b"\x31\xC0",     # xor ax,ax
+			b"\x0F\xA2",     # cpuid
+			b"\x0F\x31",     # rdtsc
+			b"\x8B\x5D\x08", # mov bx,[di+0x8]
+			b"\x8B\x4D\x0C", # mov cx,[di+0xc]
+			b"\x89\x13",     # mov [bp+di],dx
+			b"\x89\x01",     # mov [bx+di],ax
+			b"\x5D",         # pop bp
+			b"\xC3",):          # ret
+			raise Exception("FIXME: Add ticks for 32bit get_ticks")
+		# 64 bit
+		elif machine_code == \
+			(b"\x48",         # dec ax
+			b"\x31\xC0",     # xor ax,ax
+			b"\x0F\xA2",     # cpuid
+			b"\x0F\x31",     # rdtsc
+			b"\x48",         # dec ax
+			b"\xC1\xE2\x20", # shl dx,byte 0x20
+			b"\x48",         # dec ax
+			b"\x09\xD0",     # or ax,dx
+			b"\xC3",):         # ret
+			MockASM.is_first = not MockASM.is_first
+			if MockASM.is_first:
+				return 19233706151817
+			else:
+				return 19237434253761
+
+		raise Exception("Unexpected machine code")
+
+	def free(self):
+		self.func = None
+
 
 class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 1
-	is_windows = False
-	raw_arch_string = 'INVALID'
+	is_windows = platform.system().lower() == 'windows'
+	arch_string_raw = 'INVALID'
+	uname_string_raw = 'INVALID'
 	can_cpuid = True
 
 
@@ -19,9 +225,51 @@ class TestCPUID(unittest.TestCase):
 		helpers.backup_data_source(cpuinfo)
 		helpers.monkey_patch_data_source(cpuinfo, MockDataSource)
 
+		helpers.backup_asm(cpuinfo)
+		helpers.monkey_patch_asm(cpuinfo, MockASM)
+
 	def tearDown(self):
 		helpers.restore_data_source(cpuinfo)
 
+		helpers.restore_asm(cpuinfo)
+
 	# Make sure this returns {} on an invalid arch
 	def test_return_empty(self):
 		self.assertEqual({}, cpuinfo._get_cpu_info_from_cpuid())
+
+	def test_normal(self):
+		cpuid = CPUID()
+		self.assertIsNotNone(cpuid)
+
+		self.assertFalse(cpuid.is_selinux_enforcing)
+
+		max_extension_support = cpuid.get_max_extension_support()
+		self.assertEqual(0x8000001f, max_extension_support)
+
+		cache_info = cpuid.get_cache(max_extension_support)
+		self.assertEqual({'size_b': 64 * 1024, 'line_size_b': 512, 'associativity': 6}, cache_info)
+
+		info = cpuid.get_info()
+		self.assertEqual({'stepping': 2, 'model': 8, 'family': 23, 'processor_type': 0}, info)
+
+		processor_brand = cpuid.get_processor_brand(max_extension_support)
+		self.assertEqual("AMD Ryzen 7 2700X Eight-Core Processor", processor_brand)
+
+		hz_actual = cpuid.get_raw_hz()
+		self.assertEqual(3728101944, hz_actual)
+
+		vendor_id = cpuid.get_vendor_id()
+		self.assertEqual('AuthenticAMD', vendor_id)
+
+		flags = cpuid.get_flags(max_extension_support)
+		self.assertEqual(
+		['3dnowprefetch', 'abm', 'adx', 'aes', 'apic', 'avx', 'avx2', 'bmi1',
+		'bmi2', 'clflush', 'clflushopt', 'cmov', 'cmp_legacy', 'cr8_legacy',
+		'cx16', 'cx8', 'dbx', 'de', 'extapic', 'f16c', 'fma', 'fpu', 'fxsr',
+		'ht', 'lahf_lm', 'lm', 'mca', 'mce', 'misalignsse', 'mmx', 'monitor',
+		'movbe', 'msr', 'mtrr', 'osvw', 'osxsave', 'pae', 'pat', 'pci_l2i',
+		'pclmulqdq', 'perfctr_core', 'perfctr_nb', 'pge', 'pni', 'popcnt',
+		'pse', 'pse36', 'rdrnd', 'rdseed', 'sep', 'sha', 'skinit', 'smap',
+		'smep', 'sse', 'sse2', 'sse4_1', 'sse4_2', 'sse4a', 'ssse3', 'svm',
+		'tce', 'topoext', 'tsc', 'vme', 'wdt', 'xsave'
+		], flags)
diff --git a/tests/test_example.py b/tests/test_example.py
index 32b0e3b..50358c9 100644
--- a/tests/test_example.py
+++ b/tests/test_example.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 1
 	is_windows = False
-	raw_arch_string = 'x86_64'
+	arch_string_raw = 'x86_64'
+	uname_string_raw = 'x86_64'
 
 	@staticmethod
 	def has_proc_cpuinfo():
@@ -60,12 +61,8 @@ class MockDataSource(object):
 		return 1, None
 
 	@staticmethod
-	def sestatus_allow_execheap():
-		return False
-
-	@staticmethod
-	def sestatus_allow_execmem():
-		return False
+	def sestatus_b():
+		return 1, None
 
 	@staticmethod
 	def dmesg_a():
@@ -100,11 +97,11 @@ class MockDataSource(object):
 		return None
 
 	@staticmethod
-	def winreg_vendor_id():
+	def winreg_vendor_id_raw():
 		return None
 
 	@staticmethod
-	def winreg_raw_arch_string():
+	def winreg_arch_string_raw():
 		return None
 
 	@staticmethod
diff --git a/tests/test_free_bsd_11_x86_64.py b/tests/test_free_bsd_11_x86_64.py
index 4b8ad80..a90f2ae 100644
--- a/tests/test_free_bsd_11_x86_64.py
+++ b/tests/test_free_bsd_11_x86_64.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 1
 	is_windows = False
-	raw_arch_string = 'amd64'
+	arch_string_raw = 'amd64'
+	uname_string_raw = 'x86_64'
 	can_cpuid = False
 
 	@staticmethod
@@ -23,7 +24,7 @@ class MockDataSource(object):
 	@staticmethod
 	def dmesg_a():
 		retcode = 0
-		output = '''Copyright (c) 1992-2014 The FreeBSD Project.
+		output = r'''Copyright (c) 1992-2014 The FreeBSD Project.
 Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
     The Regents of the University of California. All rights reserved.
 FreeBSD is a registered trademark of The FreeBSD Foundation.
@@ -44,7 +45,7 @@ CPU: Intel(R) Pentium(R) CPU G640 @ 2.80GHz (2793.73-MHz K8-class CPU)
 	@staticmethod
 	def cat_var_run_dmesg_boot():
 		retcode = 0
-		output = '''
+		output = r'''
 VT(vga): text 80x25
 CPU: Intel(R) Pentium(R) CPU G640 @ 2.80GHz (2793.73-MHz K8-class CPU)
   Origin="GenuineIntel"  Id=0x206a7  Family=0x6  Model=02a  Stepping=7
@@ -81,17 +82,17 @@ class TestFreeBSD_11_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(16, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(17, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_dmesg(self):
 		info = cpuinfo._get_cpu_info_from_dmesg()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('2.8000 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2800000000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.8000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((2800000000, 0), info['hz_actual'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
@@ -109,12 +110,12 @@ class TestFreeBSD_11_X86_64(unittest.TestCase):
 	def test_get_cpu_info_from_cat_var_run_dmesg_boot(self):
 		info = cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('2.8000 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2800000000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.8000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((2800000000, 0), info['hz_actual'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
@@ -132,17 +133,17 @@ class TestFreeBSD_11_X86_64(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('2.8000 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2800000000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.8000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((2800000000, 0), info['hz_actual'])
 		self.assertEqual('X86_64', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(1, info['count'])
 
-		self.assertEqual('amd64', info['raw_arch_string'])
+		self.assertEqual('amd64', info['arch_string_raw'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
diff --git a/tests/test_haiku_x86_32.py b/tests/test_haiku_x86_32.py
index f235eb1..fd362ea 100644
--- a/tests/test_haiku_x86_32.py
+++ b/tests/test_haiku_x86_32.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '32bit'
 	cpu_count = 4
 	is_windows = False
-	raw_arch_string = 'BePC'
+	arch_string_raw = 'BePC'
+	uname_string_raw = 'x86_32'
 	can_cpuid = False
 
 	@staticmethod
@@ -19,7 +20,7 @@ class MockDataSource(object):
 	@staticmethod
 	def sysinfo_cpu():
 		returncode = 0
-		output = '''
+		output = r'''
 4 Intel Core i7, revision 46e5 running at 2928MHz (ID: 0x00000000 0x00000000)
 
 CPU #0: "Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz"
@@ -74,16 +75,16 @@ class TestHaiku_x86_32(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(9, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(15, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(16, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_sysinfo(self):
 		info = cpuinfo._get_cpu_info_from_sysinfo()
 
-		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand'])
-		self.assertEqual('2.9300 GHz', info['hz_advertised'])
-		self.assertEqual('2.9300 GHz', info['hz_actual'])
-		self.assertEqual((2930000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2930000000, 0), info['hz_actual_raw'])
+		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand_raw'])
+		self.assertEqual('2.9300 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.9300 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2930000000, 0), info['hz_advertised'])
+		self.assertEqual((2930000000, 0), info['hz_actual'])
 
 		self.assertEqual(5, info['stepping'])
 		self.assertEqual(30, info['model'])
@@ -99,16 +100,16 @@ class TestHaiku_x86_32(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand'])
-		self.assertEqual('2.9300 GHz', info['hz_advertised'])
-		self.assertEqual('2.9300 GHz', info['hz_actual'])
-		self.assertEqual((2930000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2930000000, 0), info['hz_actual_raw'])
+		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand_raw'])
+		self.assertEqual('2.9300 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.9300 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2930000000, 0), info['hz_advertised'])
+		self.assertEqual((2930000000, 0), info['hz_actual'])
 		self.assertEqual('X86_32', info['arch'])
 		self.assertEqual(32, info['bits'])
 		self.assertEqual(4, info['count'])
 
-		self.assertEqual('BePC', info['raw_arch_string'])
+		self.assertEqual('BePC', info['arch_string_raw'])
 
 		self.assertEqual(5, info['stepping'])
 		self.assertEqual(30, info['model'])
diff --git a/tests/test_haiku_x86_64.py b/tests/test_haiku_x86_64.py
index e44d0b2..1b2bbb7 100644
--- a/tests/test_haiku_x86_64.py
+++ b/tests/test_haiku_x86_64.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 4
 	is_windows = False
-	raw_arch_string = 'BePC'
+	arch_string_raw = 'BePC'
+	uname_string_raw = 'x86_64'
 	can_cpuid = False
 
 	@staticmethod
@@ -19,7 +20,7 @@ class MockDataSource(object):
 	@staticmethod
 	def sysinfo_cpu():
 		returncode = 0
-		output = '''
+		output = r'''
 1 Intel Core i7, revision 106e5 running at 2933MHz
 
 CPU #0: "Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz"
@@ -74,16 +75,16 @@ class TestHaiku_x86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(9, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(15, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(16, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_sysinfo(self):
 		info = cpuinfo._get_cpu_info_from_sysinfo()
 
-		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand'])
-		self.assertEqual('2.9300 GHz', info['hz_advertised'])
-		self.assertEqual('2.9300 GHz', info['hz_actual'])
-		self.assertEqual((2930000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2930000000, 0), info['hz_actual_raw'])
+		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand_raw'])
+		self.assertEqual('2.9330 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.9330 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2933000000, 0), info['hz_advertised'])
+		self.assertEqual((2933000000, 0), info['hz_actual'])
 
 		self.assertEqual(5, info['stepping'])
 		self.assertEqual(30, info['model'])
@@ -100,16 +101,16 @@ class TestHaiku_x86_64(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand'])
-		self.assertEqual('2.9300 GHz', info['hz_advertised'])
-		self.assertEqual('2.9300 GHz', info['hz_actual'])
-		self.assertEqual((2930000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2930000000, 0), info['hz_actual_raw'])
+		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand_raw'])
+		self.assertEqual('2.9330 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.9330 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2933000000, 0), info['hz_advertised'])
+		self.assertEqual((2933000000, 0), info['hz_actual'])
 		self.assertEqual('X86_32', info['arch'])
 		self.assertEqual(32, info['bits'])
 		self.assertEqual(4, info['count'])
 
-		self.assertEqual('BePC', info['raw_arch_string'])
+		self.assertEqual('BePC', info['arch_string_raw'])
 
 		self.assertEqual(5, info['stepping'])
 		self.assertEqual(30, info['model'])
diff --git a/tests/test_haiku_x86_64_beta_1_ryzen_7.py b/tests/test_haiku_x86_64_beta_1_ryzen_7.py
new file mode 100644
index 0000000..1e6b02b
--- /dev/null
+++ b/tests/test_haiku_x86_64_beta_1_ryzen_7.py
@@ -0,0 +1,127 @@
+
+
+import unittest
+from cpuinfo import *
+import helpers
+
+
+class MockDataSource(object):
+	bits = '32bit'
+	cpu_count = 2
+	is_windows = False
+	arch_string_raw = 'BePC'
+	uname_string_raw = 'x86_32'
+	can_cpuid = False
+
+	@staticmethod
+	def has_sysinfo():
+		return True
+
+	@staticmethod
+	def sysinfo_cpu():
+		returncode = 0
+		output = r'''
+2 AMD Ryzen 7, revision 800f82 running at 3693MHz
+
+CPU #0: "AMD Ryzen 7 2700X Eight-Core Processor         "
+	Signature: 0x800f82; Type 0, family 23, model 8, stepping 2
+	Features: 0x178bfbff
+		FPU VME DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE MCA CMOV PAT
+		PSE36 CFLUSH MMX FXSTR SSE SSE2 HTT
+	Extended Features (0x00000001): 0x56d82203
+		SSE3 PCLMULDQ SSSE3 CX16 SSE4.1 SSE4.2 MOVEB POPCNT AES XSAVE AVX RDRND
+	Extended Features (0x80000001): 0x2bd3fb7f
+		SCE NX AMD-MMX FXSR FFXSR RDTSCP 64
+	Extended Features (0x80000007): 0x00000100
+		ITSC
+	Extended Features (0x80000008): 0x00000000
+
+	Inst TLB: 2M/4M-byte pages, 64 entries, fully associative
+	Data TLB: 2M/4M-byte pages, 64 entries, fully associative
+	Inst TLB: 4K-byte pages, 64 entries, fully associative
+	Data TLB: 4K-byte pages, 64 entries, fully associative
+	L1 inst cache: 32 KB, 8-way set associative, 1 lines/tag, 64 bytes/line
+	L1 data cache: 64 KB, 4-way set associative, 1 lines/tag, 64 bytes/line
+	L2 cache: 512 KB, 8-way set associative, 1 lines/tag, 64 bytes/line
+
+'''
+		return returncode, output
+
+
+
+
+class TestHaiku_x86_64_Beta_1_Ryzen7(unittest.TestCase):
+	def setUp(self):
+		helpers.backup_data_source(cpuinfo)
+		helpers.monkey_patch_data_source(cpuinfo, MockDataSource)
+
+	def tearDown(self):
+		helpers.restore_data_source(cpuinfo)
+
+	'''
+	Make sure calls return the expected number of fields.
+	'''
+	def test_returns(self):
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_registry()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpufreq_info()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_lscpu()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_proc_cpuinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysctl()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_kstat()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_dmesg()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
+		self.assertEqual(9, len(cpuinfo._get_cpu_info_from_sysinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
+		self.assertEqual(16, len(cpuinfo._get_cpu_info_internal()))
+
+	def test_get_cpu_info_from_sysinfo(self):
+		info = cpuinfo._get_cpu_info_from_sysinfo()
+
+		self.assertEqual('AMD Ryzen 7 2700X Eight-Core Processor', info['brand_raw'])
+		self.assertEqual('3.6930 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.6930 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3693000000, 0), info['hz_advertised'])
+		self.assertEqual((3693000000, 0), info['hz_actual'])
+
+		self.assertEqual(2, info['stepping'])
+		self.assertEqual(8, info['model'])
+		self.assertEqual(23, info['family'])
+		self.assertEqual(
+			['64', 'aes', 'amd-mmx', 'apic', 'avx', 'cflush', 'cmov', 'cx16',
+			'cx8', 'de', 'ffxsr', 'fpu', 'fxsr', 'fxstr', 'htt', 'mca', 'mce',
+			'mmx', 'moveb', 'msr', 'mtrr', 'nx', 'pae', 'pat', 'pclmuldq',
+			'pge', 'popcnt', 'pse', 'pse36', 'rdrnd', 'rdtscp', 'sce', 'sep',
+			'sse', 'sse2', 'sse3', 'sse4.1', 'sse4.2', 'ssse3', 'tsc', 'vme',
+			'xsave']
+			,
+			info['flags']
+		)
+
+	def test_all(self):
+		info = cpuinfo._get_cpu_info_internal()
+
+		self.assertEqual('AMD Ryzen 7 2700X Eight-Core Processor', info['brand_raw'])
+		self.assertEqual('3.6930 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.6930 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3693000000, 0), info['hz_advertised'])
+		self.assertEqual((3693000000, 0), info['hz_actual'])
+		self.assertEqual('X86_32', info['arch'])
+		self.assertEqual(32, info['bits'])
+		self.assertEqual(2, info['count'])
+
+		self.assertEqual('BePC', info['arch_string_raw'])
+
+		self.assertEqual(2, info['stepping'])
+		self.assertEqual(8, info['model'])
+		self.assertEqual(23, info['family'])
+		self.assertEqual(
+			['64', 'aes', 'amd-mmx', 'apic', 'avx', 'cflush', 'cmov', 'cx16',
+			'cx8', 'de', 'ffxsr', 'fpu', 'fxsr', 'fxstr', 'htt', 'mca', 'mce',
+			'mmx', 'moveb', 'msr', 'mtrr', 'nx', 'pae', 'pat', 'pclmuldq',
+			'pge', 'popcnt', 'pse', 'pse36', 'rdrnd', 'rdtscp', 'sce', 'sep',
+			'sse', 'sse2', 'sse3', 'sse4.1', 'sse4.2', 'ssse3', 'tsc', 'vme',
+			'xsave']
+			,
+			info['flags']
+		)
diff --git a/tests/test_invalid_cpu.py b/tests/test_invalid_cpu.py
index 2f6843d..1931ecf 100644
--- a/tests/test_invalid_cpu.py
+++ b/tests/test_invalid_cpu.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '32bit'
 	cpu_count = 1
 	is_windows = False
-	raw_arch_string = 'unknown_cpu'
+	arch_string_raw = 'unknown_cpu'
+	uname_string_raw = 'unknown_cpu'
 
 
 class TestInvalidCPU(unittest.TestCase):
@@ -22,7 +23,7 @@ class TestInvalidCPU(unittest.TestCase):
 
 	def test_arch_parse_unknown(self):
 		# If the arch is unknown, the result should be null
-		arch, bits = cpuinfo._parse_arch(DataSource.raw_arch_string)
+		arch, bits = cpuinfo._parse_arch(DataSource.arch_string_raw)
 		self.assertIsNone(arch)
 		self.assertIsNone(bits)
 
@@ -32,4 +33,4 @@ class TestInvalidCPU(unittest.TestCase):
 			cpuinfo._check_arch()
 			self.fail('Failed to raise Exception')
 		except Exception as err:
-			self.assertEqual('py-cpuinfo currently only works on X86 and some PPC and ARM CPUs.', err.args[0])
+			self.assertEqual('py-cpuinfo currently only works on X86 and some ARM/PPC/S390X/MIPS CPUs.', err.args[0])
diff --git a/tests/test_linux_aarch64_64.py b/tests/test_linux_aarch64_64.py
index 20779f0..6f80302 100644
--- a/tests/test_linux_aarch64_64.py
+++ b/tests/test_linux_aarch64_64.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 6
 	is_windows = False
-	raw_arch_string = 'aarch64'
+	arch_string_raw = 'aarch64'
+	uname_string_raw = ''
 	can_cpuid = False
 
 	@staticmethod
@@ -23,7 +24,7 @@ class MockDataSource(object):
 	@staticmethod
 	def cat_proc_cpuinfo():
 		returncode = 0
-		output = '''
+		output = r'''
 processor       : 90
 BogoMIPS        : 200.00
 Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
@@ -85,7 +86,7 @@ CPU revision    : 0
 	@staticmethod
 	def lscpu():
 		returncode = 0
-		output = '''
+		output = r'''
 Architecture:          aarch64
 Byte Order:            Little Endian
 CPU(s):                96
@@ -126,15 +127,15 @@ class TestLinux_Aarch_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(10, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(11, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
 
-		self.assertEqual('78 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('32 KB', info['l1_data_cache_size'])
+		self.assertEqual(78 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
 
-		self.assertEqual('16384 KB', info['l2_cache_size'])
+		self.assertEqual(16384 * 1024, info['l2_cache_size'])
 
 		self.assertEqual(3, len(info))
 
@@ -152,34 +153,32 @@ class TestLinux_Aarch_64(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('', info['vendor_id'])
-		self.assertEqual('FIXME', info['hardware'])
-		self.assertEqual('FIXME', info['brand'])
-		self.assertEqual('FIXME', info['hz_advertised'])
-		self.assertEqual('FIXME', info['hz_actual'])
-		self.assertEqual((1000000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1000000000, 0), info['hz_actual_raw'])
+		self.assertEqual('', info['vendor_id_raw'])
+		self.assertEqual('FIXME', info['hardware_raw'])
+		self.assertEqual('FIXME', info['brand_raw'])
+		self.assertEqual('FIXME', info['hz_advertised_friendly'])
+		self.assertEqual('FIXME', info['hz_actual_friendly'])
+		self.assertEqual((1000000000, 0), info['hz_advertised'])
+		self.assertEqual((1000000000, 0), info['hz_actual'])
 		self.assertEqual('ARM_8', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(6, info['count'])
 
-		self.assertEqual('aarch64', info['raw_arch_string'])
+		self.assertEqual('aarch64', info['arch_string_raw'])
 
-		self.assertEqual('78K', info['l1_instruction_cache_size'])
-		self.assertEqual('32K', info['l1_data_cache_size'])
+		self.assertEqual(78 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
 
-		self.assertEqual('16384K', info['l2_cache_size'])
+		self.assertEqual(16384 * 1024, info['l2_cache_size'])
 		self.assertEqual(0, info['l2_cache_line_size'])
 		self.assertEqual(0, info['l2_cache_associativity'])
 
-		self.assertEqual('', info['l3_cache_size'])
+		self.assertEqual(0, info['l3_cache_size'])
 
 		self.assertEqual(0, info['stepping'])
 		self.assertEqual(0, info['model'])
 		self.assertEqual(0, info['family'])
 		self.assertEqual(0, info['processor_type'])
-		self.assertEqual(0, info['extended_model'])
-		self.assertEqual(0, info['extended_family'])
 		self.assertEqual(
 			['aes', 'asimd', 'atomics', 'crc32', 'evtstrm',
 			'fp', 'pmull', 'sha1', 'sha2']
diff --git a/tests/test_linux_alt_p9_mipsel_bfk3.py b/tests/test_linux_alt_p9_mipsel_bfk3.py
new file mode 100644
index 0000000..d85c6d2
--- /dev/null
+++ b/tests/test_linux_alt_p9_mipsel_bfk3.py
@@ -0,0 +1,136 @@
+
+
+import unittest
+from cpuinfo import *
+import helpers
+
+
+class MockDataSource(object):
+	bits = '32bit'
+	cpu_count = 2
+	is_windows = False
+	arch_string_raw = 'mips'
+	uname_string_raw = ''
+	can_cpuid = False
+
+	@staticmethod
+	def has_proc_cpuinfo():
+		return True
+
+	@staticmethod
+	def has_lscpu():
+		return True
+
+
+	@staticmethod
+	def cat_proc_cpuinfo():
+		returncode = 0
+		output = r'''
+system type		: Baikal-T Generic SoC
+machine			: Baikal-T1 BFK3 evaluation board
+processor		: 0
+cpu model		: MIPS P5600 V3.0  FPU V2.0
+BogoMIPS		: 1196.85
+wait instruction	: yes
+microsecond timers	: yes
+tlb_entries		: 576
+extra interrupt vector	: yes
+hardware watchpoint	: yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ffb]
+isa			: mips1 mips2 mips32r1 mips32r2
+ASEs implemented	: vz msa eva xpa
+shadow register sets	: 1
+kscratch registers	: 3
+package			: 0
+core			: 0
+VCED exceptions		: not available
+VCEI exceptions		: not available
+
+processor		: 1
+cpu model		: MIPS P5600 V3.0  FPU V2.0
+BogoMIPS		: 1202.58
+wait instruction	: yes
+microsecond timers	: yes
+tlb_entries		: 576
+extra interrupt vector	: yes
+hardware watchpoint	: yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ffb]
+isa			: mips1 mips2 mips32r1 mips32r2
+ASEs implemented	: vz msa eva xpa
+shadow register sets	: 1
+kscratch registers	: 3
+package			: 0
+core			: 1
+VCED exceptions		: not available
+VCEI exceptions		: not available
+'''
+		return returncode, output
+
+	@staticmethod
+	def lscpu():
+		returncode = 0
+		output = r'''
+Architecture:        mips
+Byte Order:          Little Endian
+CPU(s):              2
+On-line CPU(s) list: 0,1
+Thread(s) per core:  1
+Core(s) per socket:  2
+Socket(s):           1
+Model:               MIPS P5600 V3.0  FPU V2.0
+CPU max MHz:         1200,0000
+CPU min MHz:         200,0000
+BogoMIPS:            1196.85
+Flags:               vz msa eva xpa
+'''
+		return returncode, output
+
+
+class TestLinuxAlt_p9_mipsel_bfk3(unittest.TestCase):
+
+	def setUp(self):
+		helpers.backup_data_source(cpuinfo)
+		helpers.monkey_patch_data_source(cpuinfo, MockDataSource)
+
+	def tearDown(self):
+		helpers.restore_data_source(cpuinfo)
+
+	'''
+	Make sure calls return the expected number of fields.
+	'''
+	def test_returns(self):
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_registry()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpufreq_info()))
+		self.assertEqual(6, len(cpuinfo._get_cpu_info_from_lscpu()))
+		self.assertEqual(1, len(cpuinfo._get_cpu_info_from_proc_cpuinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysctl()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_kstat()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_dmesg()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
+		self.assertEqual(13, len(cpuinfo._get_cpu_info_internal()))
+
+	def test_get_cpu_info_from_lscpu(self):
+		info = cpuinfo._get_cpu_info_from_lscpu()
+
+		self.assertEqual('MIPS P5600 V3.0  FPU V2.0', info['brand_raw'])
+		self.assertEqual('1.2000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.2000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1200000000, 0), info['hz_advertised'])
+		self.assertEqual((1200000000, 0), info['hz_actual'])
+		self.assertEqual(['eva', 'msa', 'vz', 'xpa'], info['flags'])
+
+	def test_get_cpu_info_from_proc_cpuinfo(self):
+		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
+
+		self.assertEqual(['eva', 'msa', 'vz', 'xpa'], info['flags'])
+
+	def test_all(self):
+		info = cpuinfo._get_cpu_info_internal()
+
+		self.assertEqual('MIPS P5600 V3.0  FPU V2.0', info['brand_raw'])
+		self.assertEqual('MIPS_32', info['arch'])
+		self.assertEqual(32, info['bits'])
+		self.assertEqual(2, info['count'])
+		self.assertEqual('mips', info['arch_string_raw'])
+		self.assertEqual(['eva', 'msa', 'vz', 'xpa'], info['flags'])
diff --git a/tests/test_linux_beagle_bone_arm.py b/tests/test_linux_beagle_bone_arm.py
index d38eae4..05ac573 100644
--- a/tests/test_linux_beagle_bone_arm.py
+++ b/tests/test_linux_beagle_bone_arm.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '32bit'
 	cpu_count = 1
 	is_windows = False
-	raw_arch_string = 'armv7l'
+	arch_string_raw = 'armv7l'
+	uname_string_raw = ''
 
 	@staticmethod
 	def has_proc_cpuinfo():
@@ -22,7 +23,7 @@ class MockDataSource(object):
 	@staticmethod
 	def cat_proc_cpuinfo():
 		returncode = 0
-		output = '''
+		output = r'''
 processor       : 0
 model name      : ARMv6-compatible processor rev 7 (v6l)
 Features        : swp half thumb fastmult vfp edsp java tls
@@ -44,7 +45,7 @@ Serial          : 00000000be6d9ba0
 	@staticmethod
 	def cpufreq_info():
 		returncode = 0
-		output = '''
+		output = r'''
 cpufrequtils 008: cpufreq-info (C) Dominik Brodowski 2004-2009
 Report errors and bugs to cpufreq@vger.kernel.org, please.
 analyzing CPU 0:
@@ -87,21 +88,21 @@ class TestLinux_BeagleBone(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(13, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(14, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_cpufreq_info(self):
 		info = cpuinfo._get_cpu_info_from_cpufreq_info()
 
-		self.assertEqual('1.0000 GHz', info['hz_advertised'])
-		self.assertEqual('1.0000 GHz', info['hz_actual'])
-		self.assertEqual((1000000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1000000000, 0), info['hz_actual_raw'])
+		self.assertEqual('1.0000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.0000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1000000000, 0), info['hz_advertised'])
+		self.assertEqual((1000000000, 0), info['hz_actual'])
 
 	def test_get_cpu_info_from_proc_cpuinfo(self):
 		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
 
-		self.assertEqual('BCM2708', info['hardware'])
-		self.assertEqual('ARMv6-compatible processor rev 7 (v6l)', info['brand'])
+		self.assertEqual('BCM2708', info['hardware_raw'])
+		self.assertEqual('ARMv6-compatible processor rev 7 (v6l)', info['brand_raw'])
 
 		self.assertEqual(
 			['edsp', 'fastmult', 'half', 'java', 'swp', 'thumb', 'tls', 'vfp']
@@ -112,17 +113,17 @@ class TestLinux_BeagleBone(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('BCM2708', info['hardware'])
-		self.assertEqual('ARMv6-compatible processor rev 7 (v6l)', info['brand'])
-		self.assertEqual('1.0000 GHz', info['hz_advertised'])
-		self.assertEqual('1.0000 GHz', info['hz_actual'])
-		self.assertEqual((1000000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1000000000, 0), info['hz_actual_raw'])
+		self.assertEqual('BCM2708', info['hardware_raw'])
+		self.assertEqual('ARMv6-compatible processor rev 7 (v6l)', info['brand_raw'])
+		self.assertEqual('1.0000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.0000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1000000000, 0), info['hz_advertised'])
+		self.assertEqual((1000000000, 0), info['hz_actual'])
 		self.assertEqual('ARM_7', info['arch'])
 		self.assertEqual(32, info['bits'])
 		self.assertEqual(1, info['count'])
 
-		self.assertEqual('armv7l', info['raw_arch_string'])
+		self.assertEqual('armv7l', info['arch_string_raw'])
 
 		self.assertEqual(
 			['edsp', 'fastmult', 'half', 'java', 'swp', 'thumb', 'tls', 'vfp']
diff --git a/tests/test_linux_debian_8_5_x86_64.py b/tests/test_linux_debian_8_5_x86_64.py
index a9a3bbd..2171b4d 100644
--- a/tests/test_linux_debian_8_5_x86_64.py
+++ b/tests/test_linux_debian_8_5_x86_64.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 2
 	is_windows = False
-	raw_arch_string = 'x86_64'
+	arch_string_raw = 'x86_64'
+	uname_string_raw = 'x86_64'
 	can_cpuid = False
 
 	@staticmethod
@@ -27,7 +28,7 @@ class MockDataSource(object):
 	@staticmethod
 	def cat_proc_cpuinfo():
 		returncode = 0
-		output = '''
+		output = r'''
 processor	: 0
 vendor_id	: GenuineIntel
 cpu family	: 6
@@ -85,7 +86,7 @@ power management:
 	@staticmethod
 	def dmesg_a():
 		returncode = 0
-		output = '''
+		output = r'''
 [    0.000000] Initializing cgroup subsys cpuset
 [    0.000000] Initializing cgroup subsys cpu
 [    0.000000] Initializing cgroup subsys cpuacct
@@ -409,7 +410,7 @@ tlb_flushall_shift: 6
 	@staticmethod
 	def lscpu():
 		returncode = 0
-		output = '''
+		output = r'''
 Architecture:          x86_64
 CPU op-mode(s):        32-bit, 64-bit
 Byte Order:            Little Endian
@@ -461,36 +462,36 @@ class TestLinuxDebian_8_5_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(20, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(21, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.7937 GHz', info['hz_advertised'])
-		self.assertEqual('2.7937 GHz', info['hz_actual'])
-		self.assertEqual((2793652000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2793652000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.7937 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.7937 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2793652000, 0), info['hz_advertised'])
+		self.assertEqual((2793652000, 0), info['hz_actual'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
 		self.assertEqual(6, info['family'])
 
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('32 KB', info['l1_data_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
 
-		self.assertEqual('256 KB', info['l2_cache_size'])
-		self.assertEqual('3072 KB', info['l3_cache_size'])
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
 
 	def test_get_cpu_info_from_dmesg(self):
 		info = cpuinfo._get_cpu_info_from_dmesg()
 
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('2.8000 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2800000000, 0), info['hz_actual_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.8000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((2800000000, 0), info['hz_actual'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
@@ -499,14 +500,14 @@ class TestLinuxDebian_8_5_X86_64(unittest.TestCase):
 	def test_get_cpu_info_from_proc_cpuinfo(self):
 		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('2.7937 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2793652000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.7937 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((2793652000, 0), info['hz_actual'])
 
-		self.assertEqual('3072 KB', info['l3_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
@@ -525,23 +526,23 @@ class TestLinuxDebian_8_5_X86_64(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('2.7937 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2793652000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.7937 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((2793652000, 0), info['hz_actual'])
 		self.assertEqual('X86_64', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(2, info['count'])
 
-		self.assertEqual('x86_64', info['raw_arch_string'])
+		self.assertEqual('x86_64', info['arch_string_raw'])
 
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('32 KB', info['l1_data_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
 
-		self.assertEqual('256 KB', info['l2_cache_size'])
-		self.assertEqual('3072 KB', info['l3_cache_size'])
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
diff --git a/tests/test_linux_debian_8_7_1_ppc64le.py b/tests/test_linux_debian_8_7_1_ppc64le.py
index d601b6b..5669002 100644
--- a/tests/test_linux_debian_8_7_1_ppc64le.py
+++ b/tests/test_linux_debian_8_7_1_ppc64le.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 2
 	is_windows = False
-	raw_arch_string = 'ppc64le'
+	arch_string_raw = 'ppc64le'
+	uname_string_raw = ''
 	can_cpuid = False
 
 	@staticmethod
@@ -31,7 +32,7 @@ class MockDataSource(object):
 	@staticmethod
 	def ibm_pa_features():
 		returncode = 0
-		output = '''
+		output = r'''
 /proc/device-tree/cpus/PowerPC,POWER8@0/ibm,pa-features
                  18 00 f6 3f c7 c0 80 f0 80 00 00 00 00 00 00 00...?............
                  00 00 80 00 80 00 80 00 80 00                  ..........
@@ -42,7 +43,7 @@ class MockDataSource(object):
 	@staticmethod
 	def cat_proc_cpuinfo():
 		returncode = 0
-		output = '''
+		output = r'''
 processor	: 0
 cpu		: POWER7 (raw), altivec supported
 clock		: 1000.000000MHz
@@ -64,7 +65,7 @@ machine		: CHRP IBM pSeries (emulated by qemu)
 	@staticmethod
 	def dmesg_a():
 		returncode = 0
-		output = '''
+		output = r'''
 [    0.000000] Allocated 4718592 bytes for 2048 pacas at c00000000fb80000
 [    0.000000] Using pSeries machine description
 [    0.000000] Page sizes from device-tree:
@@ -389,7 +390,7 @@ machine		: CHRP IBM pSeries (emulated by qemu)
 	@staticmethod
 	def lscpu():
 		returncode = 0
-		output = '''
+		output = r'''
 Architecture:          ppc64le
 Byte Order:            Little Endian
 CPU(s):                2
@@ -422,7 +423,7 @@ class TestLinuxDebian_8_7_1_ppc64le(unittest.TestCase):
 	def test_returns(self):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_registry()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpufreq_info()))
-		self.assertEqual(2, len(cpuinfo._get_cpu_info_from_lscpu()))
+		self.assertEqual(3, len(cpuinfo._get_cpu_info_from_lscpu()))
 		self.assertEqual(5, len(cpuinfo._get_cpu_info_from_proc_cpuinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysctl()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_kstat()))
@@ -431,13 +432,14 @@ class TestLinuxDebian_8_7_1_ppc64le(unittest.TestCase):
 		self.assertEqual(1, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(14, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(15, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('32 KB', info['l1_data_cache_size'])
-		self.assertEqual(2, len(info))
+		self.assertEqual('IBM pSeries (emulated by qemu)', info['brand_raw'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
+		self.assertEqual(3, len(info))
 
 	def test_get_cpu_info_from_ibm_pa_features(self):
 		info = cpuinfo._get_cpu_info_from_ibm_pa_features()
@@ -449,26 +451,26 @@ class TestLinuxDebian_8_7_1_ppc64le(unittest.TestCase):
 	def test_get_cpu_info_from_proc_cpuinfo(self):
 		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
 
-		self.assertEqual('POWER7 (raw), altivec supported', info['brand'])
-		self.assertEqual('1.0000 GHz', info['hz_advertised'])
-		self.assertEqual('1.0000 GHz', info['hz_actual'])
-		self.assertEqual((1000000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1000000000, 0), info['hz_actual_raw'])
+		self.assertEqual('POWER7 (raw), altivec supported', info['brand_raw'])
+		self.assertEqual('1.0000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.0000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1000000000, 0), info['hz_advertised'])
+		self.assertEqual((1000000000, 0), info['hz_actual'])
 
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('POWER7 (raw), altivec supported', info['brand'])
-		self.assertEqual('1.0000 GHz', info['hz_advertised'])
-		self.assertEqual('1.0000 GHz', info['hz_actual'])
-		self.assertEqual((1000000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1000000000, 0), info['hz_actual_raw'])
+		self.assertEqual('POWER7 (raw), altivec supported', info['brand_raw'])
+		self.assertEqual('1.0000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.0000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1000000000, 0), info['hz_advertised'])
+		self.assertEqual((1000000000, 0), info['hz_actual'])
 		self.assertEqual('PPC_64', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(2, info['count'])
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('32 KB', info['l1_data_cache_size'])
-		self.assertEqual('ppc64le', info['raw_arch_string'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
+		self.assertEqual('ppc64le', info['arch_string_raw'])
 		self.assertEqual(
 			['dabr', 'dabrx', 'dsisr', 'fpu', 'lp', 'mmu', 'pp', 'rislb', 'run', 'slb', 'sprg3'],
 			info['flags']
diff --git a/tests/test_linux_debian_8_x86_64.py b/tests/test_linux_debian_8_x86_64.py
index fd74c44..2348b0e 100644
--- a/tests/test_linux_debian_8_x86_64.py
+++ b/tests/test_linux_debian_8_x86_64.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 1
 	is_windows = False
-	raw_arch_string = 'x86_64'
+	arch_string_raw = 'x86_64'
+	uname_string_raw = 'x86_64'
 	can_cpuid = False
 
 	@staticmethod
@@ -19,7 +20,7 @@ class MockDataSource(object):
 	@staticmethod
 	def cat_proc_cpuinfo():
 		returncode = 0
-		output = '''
+		output = r'''
 processor	: 0
 vendor_id	: GenuineIntel
 cpu family	: 6
@@ -75,19 +76,19 @@ class TestLinuxDebian_8_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(17, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(18, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_proc_cpuinfo(self):
 		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand'])
-		self.assertEqual('2.9300 GHz', info['hz_advertised'])
-		self.assertEqual('2.9283 GHz', info['hz_actual'])
-		self.assertEqual((2930000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2928283000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand_raw'])
+		self.assertEqual('2.9300 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.9283 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2930000000, 0), info['hz_advertised'])
+		self.assertEqual((2928283000, 0), info['hz_actual'])
 
-		self.assertEqual('6144 KB', info['l3_cache_size'])
+		self.assertEqual(6144 * 1024, info['l3_cache_size'])
 
 		self.assertEqual(5, info['stepping'])
 		self.assertEqual(30, info['model'])
@@ -104,19 +105,19 @@ class TestLinuxDebian_8_X86_64(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand'])
-		self.assertEqual('2.9300 GHz', info['hz_advertised'])
-		self.assertEqual('2.9283 GHz', info['hz_actual'])
-		self.assertEqual((2930000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2928283000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand_raw'])
+		self.assertEqual('2.9300 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.9283 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2930000000, 0), info['hz_advertised'])
+		self.assertEqual((2928283000, 0), info['hz_actual'])
 		self.assertEqual('X86_64', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(1, info['count'])
 
-		self.assertEqual('x86_64', info['raw_arch_string'])
+		self.assertEqual('x86_64', info['arch_string_raw'])
 
-		self.assertEqual('6144 KB', info['l3_cache_size'])
+		self.assertEqual(6144 * 1024, info['l3_cache_size'])
 
 		self.assertEqual(5, info['stepping'])
 		self.assertEqual(30, info['model'])
diff --git a/tests/test_linux_fedora_24_ppc64le.py b/tests/test_linux_fedora_24_ppc64le.py
index 2e081b9..c9adda6 100644
--- a/tests/test_linux_fedora_24_ppc64le.py
+++ b/tests/test_linux_fedora_24_ppc64le.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 2
 	is_windows = False
-	raw_arch_string = 'ppc64le'
+	arch_string_raw = 'ppc64le'
+	uname_string_raw = ''
 	can_cpuid = False
 
 	@staticmethod
@@ -31,7 +32,7 @@ class MockDataSource(object):
 	@staticmethod
 	def ibm_pa_features():
 		returncode = 0
-		output = '''
+		output = r'''
 /proc/device-tree/cpus/PowerPC,POWER7@1/ibm,pa-features 3ff60006 c08000c7
 
 '''
@@ -40,7 +41,7 @@ class MockDataSource(object):
 	@staticmethod
 	def cat_proc_cpuinfo():
 		returncode = 0
-		output = '''
+		output = r'''
 processor	: 0
 cpu		: POWER8E (raw), altivec supported
 clock		: 3425.000000MHz
@@ -60,7 +61,7 @@ machine		: CHRP IBM pSeries (emulated by qemu)
 	@staticmethod
 	def dmesg_a():
 		returncode = 0
-		output = '''
+		output = r'''
 [    0.000000] Allocated 2359296 bytes for 1024 pacas at c00000000fdc0000
 [    0.000000] Using pSeries machine description
 [    0.000000] Page sizes from device-tree:
@@ -320,7 +321,7 @@ machine		: CHRP IBM pSeries (emulated by qemu)
 	@staticmethod
 	def lscpu():
 		returncode = 0
-		output = '''
+		output = r'''
 Architecture:          ppc64le
 Byte Order:            Little Endian
 CPU(s):                2
@@ -364,15 +365,15 @@ class TestLinuxFedora_24_ppc64le(unittest.TestCase):
 		self.assertEqual(1, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(14, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(15, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
 
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('64 KB', info['l1_data_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(64 * 1024, info['l1_data_cache_size'])
 
-		self.assertEqual('POWER8E (raw), altivec supported', info['brand'])
+		self.assertEqual('POWER8E (raw), altivec supported', info['brand_raw'])
 
 	def test_get_cpu_info_from_ibm_pa_features(self):
 		info = cpuinfo._get_cpu_info_from_ibm_pa_features()
@@ -384,26 +385,26 @@ class TestLinuxFedora_24_ppc64le(unittest.TestCase):
 	def test_get_cpu_info_from_proc_cpuinfo(self):
 		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
 
-		self.assertEqual('POWER8E (raw), altivec supported', info['brand'])
-		self.assertEqual('3.4250 GHz', info['hz_advertised'])
-		self.assertEqual('3.4250 GHz', info['hz_actual'])
-		self.assertEqual((3425000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((3425000000, 0), info['hz_actual_raw'])
+		self.assertEqual('POWER8E (raw), altivec supported', info['brand_raw'])
+		self.assertEqual('3.4250 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.4250 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3425000000, 0), info['hz_advertised'])
+		self.assertEqual((3425000000, 0), info['hz_actual'])
 
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('POWER8E (raw), altivec supported', info['brand'])
-		self.assertEqual('3.4250 GHz', info['hz_advertised'])
-		self.assertEqual('3.4250 GHz', info['hz_actual'])
-		self.assertEqual((3425000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((3425000000, 0), info['hz_actual_raw'])
+		self.assertEqual('POWER8E (raw), altivec supported', info['brand_raw'])
+		self.assertEqual('3.4250 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.4250 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3425000000, 0), info['hz_advertised'])
+		self.assertEqual((3425000000, 0), info['hz_actual'])
 		self.assertEqual('PPC_64', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(2, info['count'])
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('64 KB', info['l1_data_cache_size'])
-		self.assertEqual('ppc64le', info['raw_arch_string'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(64 * 1024, info['l1_data_cache_size'])
+		self.assertEqual('ppc64le', info['arch_string_raw'])
 		self.assertEqual(
 			['dss_2.02', 'dss_2.05', 'dss_2.06', 'fpu', 'lsd_in_dscr', 'ppr', 'slb', 'sso_2.06', 'ugr_in_dscr'],
 			info['flags']
diff --git a/tests/test_linux_fedora_24_x86_64.py b/tests/test_linux_fedora_24_x86_64.py
index fb3bdc7..4c673a7 100644
--- a/tests/test_linux_fedora_24_x86_64.py
+++ b/tests/test_linux_fedora_24_x86_64.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 2
 	is_windows = False
-	raw_arch_string = 'x86_64'
+	arch_string_raw = 'x86_64'
+	uname_string_raw = 'x86_64'
 	can_cpuid = False
 
 	@staticmethod
@@ -27,7 +28,7 @@ class MockDataSource(object):
 	@staticmethod
 	def cat_proc_cpuinfo():
 		returncode = 0
-		output = '''
+		output = r'''
 processor	: 0
 vendor_id	: GenuineIntel
 cpu family	: 6
@@ -85,7 +86,7 @@ power management:
 	@staticmethod
 	def dmesg_a():
 		returncode = 0
-		output = '''
+		output = r'''
 [    0.000000] Initializing cgroup subsys cpuset
 [    0.000000] Initializing cgroup subsys cpu
 [    0.000000] Initializing cgroup subsys cpuacct
@@ -409,7 +410,7 @@ tlb_flushall_shift: 6
 	@staticmethod
 	def lscpu():
 		returncode = 0
-		output = '''
+		output = r'''
 Architecture:          x86_64
 CPU op-mode(s):        32-bit, 64-bit
 Byte Order:            Little Endian
@@ -461,36 +462,36 @@ class TestLinuxFedora_24_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(20, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(21, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.7937 GHz', info['hz_advertised'])
-		self.assertEqual('2.7937 GHz', info['hz_actual'])
-		self.assertEqual((2793652000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2793652000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.7937 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.7937 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2793652000, 0), info['hz_advertised'])
+		self.assertEqual((2793652000, 0), info['hz_actual'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
 		self.assertEqual(6, info['family'])
 
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('32 KB', info['l1_data_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
 
-		self.assertEqual('256 KB', info['l2_cache_size'])
-		self.assertEqual('3072 KB', info['l3_cache_size'])
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
 
 	def test_get_cpu_info_from_dmesg(self):
 		info = cpuinfo._get_cpu_info_from_dmesg()
 
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('2.8000 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2800000000, 0), info['hz_actual_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.8000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((2800000000, 0), info['hz_actual'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
@@ -500,14 +501,14 @@ class TestLinuxFedora_24_X86_64(unittest.TestCase):
 	def test_get_cpu_info_from_proc_cpuinfo(self):
 		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('2.7937 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2793652000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.7937 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((2793652000, 0), info['hz_actual'])
 
-		self.assertEqual('3072 KB', info['l3_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
@@ -526,23 +527,23 @@ class TestLinuxFedora_24_X86_64(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('2.7937 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2793652000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.7937 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((2793652000, 0), info['hz_actual'])
 		self.assertEqual('X86_64', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(2, info['count'])
 
-		self.assertEqual('x86_64', info['raw_arch_string'])
+		self.assertEqual('x86_64', info['arch_string_raw'])
 
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('32 KB', info['l1_data_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
 
-		self.assertEqual('256 KB', info['l2_cache_size'])
-		self.assertEqual('3072 KB', info['l3_cache_size'])
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
diff --git a/tests/test_linux_fedora_29_x86_64_ryzen_7.py b/tests/test_linux_fedora_29_x86_64_ryzen_7.py
new file mode 100644
index 0000000..013bc5b
--- /dev/null
+++ b/tests/test_linux_fedora_29_x86_64_ryzen_7.py
@@ -0,0 +1,570 @@
+
+
+import unittest
+from cpuinfo import *
+import helpers
+
+
+class MockDataSource(object):
+	bits = '64bit'
+	cpu_count = 8
+	is_windows = False
+	arch_string_raw = 'x86_64'
+	uname_string_raw = 'x86_64'
+	can_cpuid = False
+
+	@staticmethod
+	def has_proc_cpuinfo():
+		return True
+
+	@staticmethod
+	def has_lscpu():
+		return True
+
+	@staticmethod
+	def has_sestatus():
+		return True
+
+	@staticmethod
+	def cat_proc_cpuinfo():
+		returncode = 0
+		output = r'''
+processor	: 0
+vendor_id	: AuthenticAMD
+cpu family	: 23
+model		: 8
+model name	: AMD Ryzen 7 2700X Eight-Core Processor
+stepping	: 2
+microcode	: 0x6000626
+cpu MHz		: 3693.060
+cache size	: 512 KB
+physical id	: 0
+siblings	: 8
+core id		: 0
+cpu cores	: 8
+apicid		: 0
+initial apicid	: 0
+fpu		: yes
+fpu_exception	: yes
+cpuid level	: 13
+wp		: yes
+flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid tsc_known_freq pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm cmp_legacy cr8_legacy abm sse4a misalignsse 3dnowprefetch cpb ssbd vmmcall fsgsbase avx2 rdseed clflushopt arat
+bugs		: fxsave_leak sysret_ss_attrs null_seg spectre_v1 spectre_v2 spec_store_bypass
+bogomips	: 7386.12
+TLB size	: 2560 4K pages
+clflush size	: 64
+cache_alignment	: 64
+address sizes	: 48 bits physical, 48 bits virtual
+power management:
+
+
+'''
+		return returncode, output
+
+	@staticmethod
+	def lscpu():
+		returncode = 0
+		output = r'''
+Architecture:        x86_64
+CPU op-mode(s):      32-bit, 64-bit
+Byte Order:          Little Endian
+CPU(s):              8
+On-line CPU(s) list: 0-7
+Thread(s) per core:  1
+Core(s) per socket:  8
+Socket(s):           1
+NUMA node(s):        1
+Vendor ID:           AuthenticAMD
+CPU family:          23
+Model:               8
+Model name:          AMD Ryzen 7 2700X Eight-Core Processor
+Stepping:            2
+CPU MHz:             3693.060
+BogoMIPS:            7386.12
+Hypervisor vendor:   KVM
+Virtualization type: full
+L1d cache:           32K
+L1i cache:           64K
+L2 cache:            512K
+L3 cache:            16384K
+NUMA node0 CPU(s):   0-7
+Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt rdtscp lm constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid tsc_known_freq pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm cmp_legacy cr8_legacy abm sse4a misalignsse 3dnowprefetch cpb ssbd vmmcall fsgsbase avx2 rdseed clflushopt arat
+
+
+'''
+		return returncode, output
+
+	@staticmethod
+	def sestatus_b():
+		returncode = 0
+		output = r'''
+SELinux status:                 enabled
+SELinuxfs mount:                /sys/fs/selinux
+SELinux root directory:         /etc/selinux
+Loaded policy name:             targeted
+Current mode:                   enforcing
+Mode from config file:          enforcing
+Policy MLS status:              enabled
+Policy deny_unknown status:     allowed
+Memory protection checking:     actual (secure)
+Max kernel policy version:      31
+
+Policy booleans:
+abrt_anon_write                             off
+abrt_handle_event                           off
+abrt_upload_watch_anon_write                on
+antivirus_can_scan_system                   off
+antivirus_use_jit                           off
+auditadm_exec_content                       on
+authlogin_nsswitch_use_ldap                 off
+authlogin_radius                            off
+authlogin_yubikey                           off
+awstats_purge_apache_log_files              off
+boinc_execmem                               on
+cdrecord_read_content                       off
+cluster_can_network_connect                 off
+cluster_manage_all_files                    off
+cluster_use_execmem                         off
+cobbler_anon_write                          off
+cobbler_can_network_connect                 off
+cobbler_use_cifs                            off
+cobbler_use_nfs                             off
+collectd_tcp_network_connect                off
+colord_use_nfs                              off
+condor_tcp_network_connect                  off
+conman_can_network                          off
+conman_use_nfs                              off
+cron_can_relabel                            off
+cron_system_cronjob_use_shares              off
+cron_userdomain_transition                  on
+cups_execmem                                off
+cvs_read_shadow                             off
+daemons_dump_core                           off
+daemons_enable_cluster_mode                 off
+daemons_use_tcp_wrapper                     off
+daemons_use_tty                             off
+dbadm_exec_content                          on
+dbadm_manage_user_files                     off
+dbadm_read_user_files                       off
+deny_execmem                                off
+deny_ptrace                                 off
+dhcpc_exec_iptables                         off
+dhcpd_use_ldap                              off
+domain_can_mmap_files                       off
+domain_can_write_kmsg                       off
+domain_fd_use                               on
+domain_kernel_load_modules                  off
+entropyd_use_audio                          on
+exim_can_connect_db                         off
+exim_manage_user_files                      off
+exim_read_user_files                        off
+fcron_crond                                 off
+fenced_can_network_connect                  off
+fenced_can_ssh                              off
+fips_mode                                   on
+ftpd_anon_write                             off
+ftpd_connect_all_unreserved                 off
+ftpd_connect_db                             off
+ftpd_full_access                            off
+ftpd_use_cifs                               off
+ftpd_use_fusefs                             off
+ftpd_use_nfs                                off
+ftpd_use_passive_mode                       off
+git_cgi_enable_homedirs                     off
+git_cgi_use_cifs                            off
+git_cgi_use_nfs                             off
+git_session_bind_all_unreserved_ports       off
+git_session_users                           off
+git_system_enable_homedirs                  off
+git_system_use_cifs                         off
+git_system_use_nfs                          off
+gitosis_can_sendmail                        off
+glance_api_can_network                      off
+glance_use_execmem                          off
+glance_use_fusefs                           off
+global_ssp                                  off
+gluster_anon_write                          off
+gluster_export_all_ro                       off
+gluster_export_all_rw                       on
+gluster_use_execmem                         off
+gpg_web_anon_write                          off
+gssd_read_tmp                               on
+guest_exec_content                          on
+haproxy_connect_any                         off
+httpd_anon_write                            off
+httpd_builtin_scripting                     on
+httpd_can_check_spam                        off
+httpd_can_connect_ftp                       off
+httpd_can_connect_ldap                      off
+httpd_can_connect_mythtv                    off
+httpd_can_connect_zabbix                    off
+httpd_can_network_connect                   off
+httpd_can_network_connect_cobbler           off
+httpd_can_network_connect_db                off
+httpd_can_network_memcache                  off
+httpd_can_network_relay                     off
+httpd_can_sendmail                          off
+httpd_dbus_avahi                            off
+httpd_dbus_sssd                             off
+httpd_dontaudit_search_dirs                 off
+httpd_enable_cgi                            on
+httpd_enable_ftp_server                     off
+httpd_enable_homedirs                       off
+httpd_execmem                               off
+httpd_graceful_shutdown                     off
+httpd_manage_ipa                            off
+httpd_mod_auth_ntlm_winbind                 off
+httpd_mod_auth_pam                          off
+httpd_read_user_content                     off
+httpd_run_ipa                               off
+httpd_run_preupgrade                        off
+httpd_run_stickshift                        off
+httpd_serve_cobbler_files                   off
+httpd_setrlimit                             off
+httpd_ssi_exec                              off
+httpd_sys_script_anon_write                 off
+httpd_tmp_exec                              off
+httpd_tty_comm                              off
+httpd_unified                               off
+httpd_use_cifs                              off
+httpd_use_fusefs                            off
+httpd_use_gpg                               off
+httpd_use_nfs                               off
+httpd_use_openstack                         off
+httpd_use_sasl                              off
+httpd_verify_dns                            off
+icecast_use_any_tcp_ports                   off
+irc_use_any_tcp_ports                       off
+irssi_use_full_network                      off
+kdumpgui_run_bootloader                     off
+keepalived_connect_any                      off
+kerberos_enabled                            on
+ksmtuned_use_cifs                           off
+ksmtuned_use_nfs                            off
+logadm_exec_content                         on
+logging_syslogd_can_sendmail                off
+logging_syslogd_run_nagios_plugins          off
+logging_syslogd_use_tty                     on
+login_console_enabled                       on
+logrotate_read_inside_containers            off
+logrotate_use_nfs                           off
+logwatch_can_network_connect_mail           off
+lsmd_plugin_connect_any                     off
+mailman_use_fusefs                          off
+mcelog_client                               off
+mcelog_exec_scripts                         on
+mcelog_foreground                           off
+mcelog_server                               off
+minidlna_read_generic_user_content          off
+mmap_low_allowed                            off
+mock_enable_homedirs                        off
+mount_anyfile                               on
+mozilla_plugin_bind_unreserved_ports        off
+mozilla_plugin_can_network_connect          on
+mozilla_plugin_use_bluejeans                off
+mozilla_plugin_use_gps                      off
+mozilla_plugin_use_spice                    off
+mozilla_read_content                        off
+mpd_enable_homedirs                         off
+mpd_use_cifs                                off
+mpd_use_nfs                                 off
+mplayer_execstack                           off
+mysql_connect_any                           off
+mysql_connect_http                          off
+nagios_run_pnp4nagios                       off
+nagios_run_sudo                             off
+nagios_use_nfs                              off
+named_tcp_bind_http_port                    off
+named_write_master_zones                    off
+neutron_can_network                         off
+nfs_export_all_ro                           on
+nfs_export_all_rw                           on
+nfsd_anon_write                             off
+nis_enabled                                 off
+nscd_use_shm                                on
+openshift_use_nfs                           off
+openvpn_can_network_connect                 on
+openvpn_enable_homedirs                     on
+openvpn_run_unconfined                      off
+pcp_bind_all_unreserved_ports               off
+pcp_read_generic_logs                       off
+pdns_can_network_connect_db                 off
+piranha_lvs_can_network_connect             off
+polipo_connect_all_unreserved               off
+polipo_session_bind_all_unreserved_ports    off
+polipo_session_users                        off
+polipo_use_cifs                             off
+polipo_use_nfs                              off
+polyinstantiation_enabled                   off
+postfix_local_write_mail_spool              on
+postgresql_can_rsync                        off
+postgresql_selinux_transmit_client_label    off
+postgresql_selinux_unconfined_dbadm         on
+postgresql_selinux_users_ddl                on
+pppd_can_insmod                             off
+pppd_for_user                               off
+privoxy_connect_any                         on
+prosody_bind_http_port                      off
+puppetagent_manage_all_files                off
+puppetmaster_use_db                         off
+racoon_read_shadow                          off
+radius_use_jit                              off
+redis_enable_notify                         off
+rpcd_use_fusefs                             off
+rsync_anon_write                            off
+rsync_client                                off
+rsync_export_all_ro                         off
+rsync_full_access                           off
+samba_create_home_dirs                      off
+samba_domain_controller                     off
+samba_enable_home_dirs                      off
+samba_export_all_ro                         off
+samba_export_all_rw                         off
+samba_load_libgfapi                         off
+samba_portmapper                            off
+samba_run_unconfined                        off
+samba_share_fusefs                          off
+samba_share_nfs                             off
+sanlock_enable_home_dirs                    off
+sanlock_use_fusefs                          off
+sanlock_use_nfs                             off
+sanlock_use_samba                           off
+saslauthd_read_shadow                       off
+secadm_exec_content                         on
+secure_mode                                 off
+secure_mode_insmod                          off
+secure_mode_policyload                      off
+selinuxuser_direct_dri_enabled              on
+selinuxuser_execheap                        off
+selinuxuser_execmod                         on
+selinuxuser_execstack                       on
+selinuxuser_mysql_connect_enabled           off
+selinuxuser_ping                            on
+selinuxuser_postgresql_connect_enabled      off
+selinuxuser_rw_noexattrfile                 on
+selinuxuser_share_music                     off
+selinuxuser_tcp_server                      off
+selinuxuser_udp_server                      off
+selinuxuser_use_ssh_chroot                  off
+sge_domain_can_network_connect              off
+sge_use_nfs                                 off
+smartmon_3ware                              off
+smbd_anon_write                             off
+spamassassin_can_network                    off
+spamd_enable_home_dirs                      on
+spamd_update_can_network                    off
+squid_connect_any                           on
+squid_use_tproxy                            off
+ssh_chroot_rw_homedirs                      off
+ssh_keysign                                 off
+ssh_sysadm_login                            off
+ssh_use_tcpd                                off
+sslh_can_bind_any_port                      off
+sslh_can_connect_any_port                   off
+staff_exec_content                          on
+staff_use_svirt                             off
+swift_can_network                           off
+sysadm_exec_content                         on
+telepathy_connect_all_ports                 off
+telepathy_tcp_connect_generic_network_ports on
+tftp_anon_write                             off
+tftp_home_dir                               off
+tmpreaper_use_cifs                          off
+tmpreaper_use_nfs                           off
+tmpreaper_use_samba                         off
+tomcat_can_network_connect_db               off
+tomcat_read_rpm_db                          off
+tomcat_use_execmem                          off
+tor_bind_all_unreserved_ports               off
+tor_can_network_relay                       off
+tor_can_onion_services                      off
+unconfined_chrome_sandbox_transition        on
+unconfined_login                            on
+unconfined_mozilla_plugin_transition        on
+unprivuser_use_svirt                        off
+use_ecryptfs_home_dirs                      off
+use_fusefs_home_dirs                        off
+use_lpd_server                              off
+use_nfs_home_dirs                           off
+use_samba_home_dirs                         off
+use_virtualbox                              off
+user_exec_content                           on
+varnishd_connect_any                        off
+virt_read_qemu_ga_data                      off
+virt_rw_qemu_ga_data                        off
+virt_sandbox_share_apache_content           off
+virt_sandbox_use_all_caps                   on
+virt_sandbox_use_audit                      on
+virt_sandbox_use_fusefs                     off
+virt_sandbox_use_mknod                      off
+virt_sandbox_use_netlink                    off
+virt_sandbox_use_sys_admin                  off
+virt_transition_userdomain                  off
+virt_use_comm                               off
+virt_use_execmem                            off
+virt_use_fusefs                             off
+virt_use_glusterd                           off
+virt_use_nfs                                off
+virt_use_pcscd                              off
+virt_use_rawip                              off
+virt_use_samba                              off
+virt_use_sanlock                            off
+virt_use_usb                                on
+virt_use_xserver                            off
+webadm_manage_user_files                    off
+webadm_read_user_files                      off
+wine_mmap_zero_ignore                       off
+xdm_bind_vnc_tcp_port                       off
+xdm_exec_bootloader                         off
+xdm_sysadm_login                            off
+xdm_write_home                              off
+xen_use_nfs                                 off
+xend_run_blktap                             on
+xend_run_qemu                               on
+xguest_connect_network                      on
+xguest_exec_content                         on
+xguest_mount_media                          on
+xguest_use_bluetooth                        on
+xserver_clients_write_xshm                  off
+xserver_execmem                             off
+xserver_object_manager                      off
+zabbix_can_network                          off
+zabbix_run_sudo                             off
+zarafa_setrlimit                            off
+zebra_write_config                          off
+zoneminder_anon_write                       off
+zoneminder_run_sudo off
+'''
+		return returncode, output
+
+
+class Test_Linux_Fedora_29_X86_64_Ryzen_7(unittest.TestCase):
+	def setUp(self):
+		helpers.backup_data_source(cpuinfo)
+		helpers.monkey_patch_data_source(cpuinfo, MockDataSource)
+
+	def tearDown(self):
+		helpers.restore_data_source(cpuinfo)
+
+	'''
+	Make sure calls return the expected number of fields.
+	'''
+	def test_returns(self):
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_registry()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpufreq_info()))
+		self.assertEqual(14, len(cpuinfo._get_cpu_info_from_lscpu()))
+		self.assertEqual(11, len(cpuinfo._get_cpu_info_from_proc_cpuinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysctl()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_kstat()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_dmesg()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
+		self.assertEqual(21, len(cpuinfo._get_cpu_info_internal()))
+
+	def test_get_cpu_info_from_lscpu(self):
+		info = cpuinfo._get_cpu_info_from_lscpu()
+
+		self.assertEqual('AuthenticAMD', info['vendor_id_raw'])
+		self.assertEqual('AMD Ryzen 7 2700X Eight-Core Processor', info['brand_raw'])
+		self.assertEqual('3.6931 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.6931 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3693060000, 0), info['hz_advertised'])
+		self.assertEqual((3693060000, 0), info['hz_actual'])
+
+		self.assertEqual(2, info['stepping'])
+		self.assertEqual(8, info['model'])
+		self.assertEqual(23, info['family'])
+
+		self.assertEqual(64 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
+		self.assertEqual(512 * 1024, info['l2_cache_size'])
+		self.assertEqual(16384 * 1024, info['l3_cache_size'])
+
+		self.assertEqual(
+			['3dnowprefetch', 'abm', 'aes', 'apic', 'arat', 'avx', 'avx2',
+			'clflush', 'clflushopt', 'cmov', 'cmp_legacy', 'constant_tsc',
+			'cpb', 'cpuid', 'cr8_legacy', 'cx16', 'cx8', 'de', 'extd_apicid',
+			'fpu', 'fsgsbase', 'fxsr', 'fxsr_opt', 'ht', 'hypervisor',
+			'lahf_lm', 'lm', 'mca', 'mce', 'misalignsse', 'mmx', 'mmxext',
+			'movbe', 'msr', 'mtrr', 'nonstop_tsc', 'nopl', 'nx', 'pae', 'pat',
+			'pclmulqdq', 'pge', 'pni', 'popcnt', 'pse', 'pse36', 'rdrand',
+			'rdseed', 'rdtscp', 'rep_good', 'sep', 'ssbd', 'sse', 'sse2',
+			'sse4_1', 'sse4_2', 'sse4a', 'ssse3', 'syscall', 'tsc',
+			'tsc_known_freq', 'vme', 'vmmcall', 'x2apic', 'xsave']
+			,
+			info['flags']
+		)
+
+	def test_get_cpu_info_from_proc_cpuinfo(self):
+		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
+
+		self.assertEqual('AuthenticAMD', info['vendor_id_raw'])
+		self.assertEqual('AMD Ryzen 7 2700X Eight-Core Processor', info['brand_raw'])
+		self.assertEqual('3.6931 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.6931 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3693060000, 0), info['hz_advertised'])
+		self.assertEqual((3693060000, 0), info['hz_actual'])
+
+		# FIXME: This is l2 cache size not l3 cache size
+		self.assertEqual(512 * 1024, info['l3_cache_size'])
+
+		self.assertEqual(2, info['stepping'])
+		self.assertEqual(8, info['model'])
+		self.assertEqual(23, info['family'])
+		self.assertEqual(
+			['3dnowprefetch', 'abm', 'aes', 'apic', 'arat', 'avx', 'avx2',
+			'clflush', 'clflushopt', 'cmov', 'cmp_legacy', 'constant_tsc',
+			'cpb', 'cpuid', 'cr8_legacy', 'cx16', 'cx8', 'de', 'extd_apicid',
+			'fpu', 'fsgsbase', 'fxsr', 'fxsr_opt', 'ht', 'hypervisor',
+			'lahf_lm', 'lm', 'mca', 'mce', 'misalignsse', 'mmx', 'mmxext',
+			'movbe', 'msr', 'mtrr', 'nonstop_tsc', 'nopl', 'nx', 'pae',
+			'pat', 'pclmulqdq', 'pge', 'pni', 'popcnt', 'pse', 'pse36',
+			'rdrand', 'rdseed', 'rdtscp', 'rep_good', 'sep', 'ssbd', 'sse',
+			'sse2', 'sse4_1', 'sse4_2', 'sse4a', 'ssse3', 'syscall', 'tsc',
+			'tsc_known_freq', 'vme', 'vmmcall', 'x2apic', 'xsave']
+			,
+			info['flags']
+		)
+
+	def test_all(self):
+		info = cpuinfo._get_cpu_info_internal()
+
+		self.assertEqual('AuthenticAMD', info['vendor_id_raw'])
+		self.assertEqual('AMD Ryzen 7 2700X Eight-Core Processor', info['brand_raw'])
+		self.assertEqual('3.6931 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.6931 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3693060000, 0), info['hz_advertised'])
+		self.assertEqual((3693060000, 0), info['hz_actual'])
+		self.assertEqual('X86_64', info['arch'])
+		self.assertEqual(64, info['bits'])
+		self.assertEqual(8, info['count'])
+
+		self.assertEqual('x86_64', info['arch_string_raw'])
+
+		self.assertEqual(64 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
+
+		self.assertEqual(512 * 1024, info['l2_cache_size'])
+		# FIXME: This is l2 cache size not l3 cache size
+		# it is wrong in /proc/cpuinfo
+		self.assertEqual(512 * 1024, info['l3_cache_size'])
+
+		self.assertEqual(2, info['stepping'])
+		self.assertEqual(8, info['model'])
+		self.assertEqual(23, info['family'])
+		self.assertEqual(
+			['3dnowprefetch', 'abm', 'aes', 'apic', 'arat', 'avx', 'avx2',
+			'clflush', 'clflushopt', 'cmov', 'cmp_legacy', 'constant_tsc',
+			'cpb', 'cpuid', 'cr8_legacy', 'cx16', 'cx8', 'de', 'extd_apicid',
+			'fpu', 'fsgsbase', 'fxsr', 'fxsr_opt', 'ht', 'hypervisor',
+			'lahf_lm', 'lm', 'mca', 'mce', 'misalignsse', 'mmx', 'mmxext',
+			'movbe', 'msr', 'mtrr', 'nonstop_tsc', 'nopl', 'nx', 'pae', 'pat',
+			'pclmulqdq', 'pge', 'pni', 'popcnt', 'pse', 'pse36', 'rdrand',
+			'rdseed', 'rdtscp', 'rep_good', 'sep', 'ssbd', 'sse', 'sse2',
+			'sse4_1', 'sse4_2', 'sse4a', 'ssse3', 'syscall', 'tsc',
+			'tsc_known_freq', 'vme', 'vmmcall', 'x2apic', 'xsave']
+			,
+			info['flags']
+		)
diff --git a/tests/test_linux_fedora_5_s390x.py b/tests/test_linux_fedora_5_s390x.py
new file mode 100644
index 0000000..ab52f9b
--- /dev/null
+++ b/tests/test_linux_fedora_5_s390x.py
@@ -0,0 +1,483 @@
+
+
+import unittest
+from cpuinfo import *
+import helpers
+
+
+class MockDataSource(object):
+	bits = '64bit'
+	cpu_count = 4
+	is_windows = False
+	arch_string_raw = 's390x'
+	uname_string_raw = ''
+	can_cpuid = False
+
+	@staticmethod
+	def has_proc_cpuinfo():
+		return True
+
+	@staticmethod
+	def has_dmesg():
+		return True
+
+	@staticmethod
+	def has_lscpu():
+		return True
+
+	@staticmethod
+	def cat_proc_cpuinfo():
+		returncode = 0
+		output = r'''
+vendor_id       : IBM/S390
+# processors    : 4
+bogomips per cpu: 2913.00
+max thread id   : 0
+features	: esan3 zarch stfle msa ldisp eimm dfp edat etf3eh highgprs te sie
+cache0          : level=1 type=Data scope=Private size=96K line_size=256 associativity=6
+cache1          : level=1 type=Instruction scope=Private size=64K line_size=256 associativity=4
+cache2          : level=2 type=Data scope=Private size=1024K line_size=256 associativity=8
+cache3          : level=2 type=Instruction scope=Private size=1024K line_size=256 associativity=8
+cache4          : level=3 type=Unified scope=Shared size=49152K line_size=256 associativity=12
+cache5          : level=4 type=Unified scope=Shared size=393216K line_size=256 associativity=24
+processor 0: version = FF,  identification = 14C047,  machine = 2827
+processor 1: version = FF,  identification = 14C047,  machine = 2827
+processor 2: version = FF,  identification = 14C047,  machine = 2827
+processor 3: version = FF,  identification = 14C047,  machine = 2827
+cpu number      : 0
+cpu MHz dynamic : 5504
+cpu MHz static  : 5504
+cpu number      : 1
+cpu MHz dynamic : 5504
+cpu MHz static  : 5504
+cpu number      : 2
+cpu MHz dynamic : 5504
+cpu MHz static  : 5504
+cpu number      : 3
+cpu MHz dynamic : 5504
+cpu MHz static  : 5504
+
+
+'''
+		return returncode, output
+
+	@staticmethod
+	def lscpu():
+		returncode = 0
+		output = r'''
+Architecture:          s390x
+CPU op-mode(s):        32-bit, 64-bit
+Byte Order:            Big Endian
+CPU(s):                4
+On-line CPU(s) list:   0-3
+Thread(s) per core:    1
+Core(s) per socket:    1
+Socket(s) per book:    1
+Book(s) per drawer:    1
+Drawer(s):             4
+Vendor ID:             IBM/S390
+Machine type:          2827
+CPU dynamic MHz:       5504
+CPU static MHz:        5504
+BogoMIPS:              2913.00
+Hypervisor:            z/VM 5.4.0
+Hypervisor vendor:     IBM
+Virtualization type:   full
+Dispatching mode:      horizontal
+L1d cache:             96K
+L1i cache:             64K
+L2d cache:             1024K
+L2i cache:             1024K
+L3 cache:              49152K
+L4 cache:              393216K
+Flags:                 esan3 zarch stfle msa ldisp eimm dfp etf3eh highgprs sie
+
+
+'''
+		return returncode, output
+
+	@staticmethod
+	def dmesg_a():
+		returncode = 0
+		output = r'''
+[623985.026158]            000003ffda1f9118 00e1526ff184ab35 00000000800008a0 000003ffda1f90f0
+[623985.026161]            0000000080000740 0000000000000000 000002aa4b1cf0a0 000003ffaa476f30
+[623985.026165]            000003ffaa428f58 000002aa4b1bf6b0 000003ffa9e22b9e 000003ffda1f8ee0
+[623985.026175] User Code: 0000000080000828: c0f4ffffffc0	brcl	15,800007a8
+[623985.026175]            000000008000082e: 0707		bcr	0,%r7
+[623985.026175]           #0000000080000830: a7f40001		brc	15,80000832
+[623985.026175]           >0000000080000834: 0707		bcr	0,%r7
+[623985.026175]            0000000080000836: 0707		bcr	0,%r7
+[623985.026175]            0000000080000838: eb7ff0380024	stmg	%r7,%r15,56(%r15)
+[623985.026175]            000000008000083e: e3f0ff60ff71	lay	%r15,-160(%r15)
+[623985.026175]            0000000080000844: b9040092		lgr	%r9,%r2
+[623985.026211] Last Breaking-Event-Address:
+[623985.026214]  [<0000000080000830>] 0x80000830
+[624418.306980] User process fault: interruption code 0038 ilc:3 in libstdc++.so.6.0.23[3ff9d000000+1b9000]
+[624418.306992] Failing address: 46726f6200005000 TEID: 46726f6200005800
+[624418.306994] Fault in primary space mode while using user ASCE.
+[624418.306997] AS:0000000081d081c7 R3:0000000000000024
+[624418.307003] CPU: 3 PID: 56744 Comm: try-catch-2.exe Not tainted 4.8.15-300.fc25.s390x #1
+[624418.307005] Hardware name: IBM              2827 H43              400              (z/VM)
+[624418.307009] task: 00000000f74c1c80 task.stack: 00000000ab6f0000
+[624418.307012] User PSW : 0705000180000000 000003ff9d0a7f58
+[624418.307016]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:1 AS:0 CC:0 PM:0 RI:0 EA:3
+[624418.307016] User GPRS: 0000000000000000 46726f6200005465 0000000080003528 000003ff9d1bba00
+[624418.307024]            000003fff8278e88 000003fff8278dc0 000000008000187a fffffffffffffffd
+[624418.307028]            000003ff00000000 000003fff8278e88 0000000080003528 000003ff9d1bba00
+[624418.307032]            0000000080003428 000003ff9d172658 000003ff9d0a7f32 000003fff8278d20
+[624418.307050] User Code: 000003ff9d0a7f4a: e310a0000004	lg	%r1,0(%r10)
+[624418.307050]            000003ff9d0a7f50: b904003b		lgr	%r3,%r11
+[624418.307050]           #000003ff9d0a7f54: b904002a		lgr	%r2,%r10
+[624418.307050]           >000003ff9d0a7f58: e31010200004	lg	%r1,32(%r1)
+[624418.307050]            000003ff9d0a7f5e: a7590001		lghi	%r5,1
+[624418.307050]            000003ff9d0a7f62: 4140f0a0		la	%r4,160(%r15)
+[624418.307050]            000003ff9d0a7f66: 0de1		basr	%r14,%r1
+[624418.307050]            000003ff9d0a7f68: ec280009007c	cgij	%r2,0,8,3ff9d0a7f7a
+[624418.307061] Last Breaking-Event-Address:
+[624418.307065]  [<000003ff9d0a7f32>] 0x3ff9d0a7f32
+[624418.806616] User process fault: interruption code 0038 ilc:3 in libstdc++.so.6.0.23[3ffac780000+1b9000]
+[624418.806627] Failing address: 5465737473756000 TEID: 5465737473756800
+[624418.806629] Fault in primary space mode while using user ASCE.
+[624418.806633] AS:00000000a44441c7 R3:0000000000000024
+[624418.806638] CPU: 3 PID: 56971 Comm: try-catch-9.exe Not tainted 4.8.15-300.fc25.s390x #1
+[624418.806641] Hardware name: IBM              2827 H43              400              (z/VM)
+[624418.806644] task: 0000000001a9b900 task.stack: 0000000082968000
+[624418.806647] User PSW : 0705000180000000 000003ffac827f58
+[624418.806650]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:1 AS:0 CC:0 PM:0 RI:0 EA:3
+[624418.806650] User GPRS: 0000000000000000 5465737473756974 00000000800032a4 000003ffac93ba00
+[624418.806658]            000003ffdd4f8bb0 000003ffdd4f8ae8 0000000080001338 0000000000000000
+[624418.806662]            000003ff00000000 000003ffdd4f8bb0 00000000800032a4 000003ffac93ba00
+[624418.806666]            0000000087919e90 000003ffac8f2658 000003ffac827f32 000003ffdd4f8a48
+[624418.806683] User Code: 000003ffac827f4a: e310a0000004	lg	%r1,0(%r10)
+[624418.806683]            000003ffac827f50: b904003b		lgr	%r3,%r11
+[624418.806683]           #000003ffac827f54: b904002a		lgr	%r2,%r10
+[624418.806683]           >000003ffac827f58: e31010200004	lg	%r1,32(%r1)
+[624418.806683]            000003ffac827f5e: a7590001		lghi	%r5,1
+[624418.806683]            000003ffac827f62: 4140f0a0		la	%r4,160(%r15)
+[624418.806683]            000003ffac827f66: 0de1		basr	%r14,%r1
+[624418.806683]            000003ffac827f68: ec280009007c	cgij	%r2,0,8,3ffac827f7a
+[624418.806694] Last Breaking-Event-Address:
+[624418.806697]  [<000003ffac827f32>] 0x3ffac827f32
+[624457.542811] User process fault: interruption code 0038 ilc:3 in libstdc++.so.6.0.23[3ffbc080000+1b9000]
+[624457.542823] Failing address: 46726f6200005000 TEID: 46726f6200005800
+[624457.542825] Fault in primary space mode while using user ASCE.
+[624457.542829] AS:0000000002e701c7 R3:0000000000000024
+[624457.542834] CPU: 2 PID: 6763 Comm: try-catch-2.exe Not tainted 4.8.15-300.fc25.s390x #1
+[624457.542837] Hardware name: IBM              2827 H43              400              (z/VM)
+[624457.542840] task: 00000000f7aa0000 task.stack: 0000000003530000
+[624457.542844] User PSW : 0705000180000000 000003ffbc127f58
+[624457.542847]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:1 AS:0 CC:0 PM:0 RI:0 EA:3
+[624457.542847] User GPRS: 0000000000000000 46726f6200005465 0000000080003528 000003ffbc23ba00
+[624457.542856]            000003ffc14f8dd8 000003ffc14f8d10 000000008000187a fffffffffffffffd
+[624457.542859]            000003ff00000000 000003ffc14f8dd8 0000000080003528 000003ffbc23ba00
+[624457.542863]            0000000080003428 000003ffbc1f2658 000003ffbc127f32 000003ffc14f8c70
+[624457.542882] User Code: 000003ffbc127f4a: e310a0000004	lg	%r1,0(%r10)
+[624457.542882]            000003ffbc127f50: b904003b		lgr	%r3,%r11
+[624457.542882]           #000003ffbc127f54: b904002a		lgr	%r2,%r10
+[624457.542882]           >000003ffbc127f58: e31010200004	lg	%r1,32(%r1)
+[624457.542882]            000003ffbc127f5e: a7590001		lghi	%r5,1
+[624457.542882]            000003ffbc127f62: 4140f0a0		la	%r4,160(%r15)
+[624457.542882]            000003ffbc127f66: 0de1		basr	%r14,%r1
+[624457.542882]            000003ffbc127f68: ec280009007c	cgij	%r2,0,8,3ffbc127f7a
+[624457.542893] Last Breaking-Event-Address:
+[624457.542896]  [<000003ffbc127f32>] 0x3ffbc127f32
+[624458.013783] User process fault: interruption code 0038 ilc:3 in libstdc++.so.6.0.23[3ff94f00000+1b9000]
+[624458.013795] Failing address: 5465737473756000 TEID: 5465737473756800
+[624458.013797] Fault in primary space mode while using user ASCE.
+[624458.013801] AS:0000000004be41c7 R3:0000000000000024
+[624458.013806] CPU: 1 PID: 6896 Comm: try-catch-9.exe Not tainted 4.8.15-300.fc25.s390x #1
+[624458.013809] Hardware name: IBM              2827 H43              400              (z/VM)
+[624458.013812] task: 00000000f5b4b900 task.stack: 00000000061f4000
+[624458.013815] User PSW : 0705000180000000 000003ff94fa7f58
+[624458.013818]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:1 AS:0 CC:0 PM:0 RI:0 EA:3
+[624458.013818] User GPRS: 0000000000000000 5465737473756974 00000000800032a4 000003ff950bba00
+[624458.013826]            000003ffd0df96f0 000003ffd0df9628 0000000080001338 0000000000000000
+[624458.013830]            000003ff00000000 000003ffd0df96f0 00000000800032a4 000003ff950bba00
+[624458.013834]            00000000a19d4e90 000003ff95072658 000003ff94fa7f32 000003ffd0df9588
+[624458.013852] User Code: 000003ff94fa7f4a: e310a0000004	lg	%r1,0(%r10)
+[624458.013852]            000003ff94fa7f50: b904003b		lgr	%r3,%r11
+[624458.013852]           #000003ff94fa7f54: b904002a		lgr	%r2,%r10
+[624458.013852]           >000003ff94fa7f58: e31010200004	lg	%r1,32(%r1)
+[624458.013852]            000003ff94fa7f5e: a7590001		lghi	%r5,1
+[624458.013852]            000003ff94fa7f62: 4140f0a0		la	%r4,160(%r15)
+[624458.013852]            000003ff94fa7f66: 0de1		basr	%r14,%r1
+[624458.013852]            000003ff94fa7f68: ec280009007c	cgij	%r2,0,8,3ff94fa7f7a
+[624458.013863] Last Breaking-Event-Address:
+[624458.013866]  [<000003ff94fa7f32>] 0x3ff94fa7f32
+[682281.933336] User process fault: interruption code 003b ilc:3 in cmsysTestProcess[2aa16200000+9000]
+[682281.933347] Failing address: 0000000000000000 TEID: 0000000000000400
+[682281.933349] Fault in primary space mode while using user ASCE.
+[682281.933353] AS:00000000829e01c7 R3:0000000000000024
+[682281.933358] CPU: 0 PID: 29755 Comm: cmsysTestProces Not tainted 4.8.15-300.fc25.s390x #1
+[682281.933362] Hardware name: IBM              2827 H43              400              (z/VM)
+[682281.933365] task: 00000000f5f13900 task.stack: 00000000c2610000
+[682281.933368] User PSW : 0705000180000000 000002aa162027a2
+[682281.933371]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:1 AS:0 CC:0 PM:0 RI:0 EA:3
+[682281.933371] User GPRS: 0000000000000000 000003ff00000000 0000000000000000 0000000000000001
+[682281.933380]            000000000000002e 000003ff7f848c88 000002aa16207430 000003ffe33ff0a0
+[682281.933383]            000002aa1620769e 0000000000000000 000003ff7f848d70 000003ff7f848d68
+[682281.933388]            000003ff7f928f58 000002aa16207df0 000002aa16202794 000003ffe33feb68
+[682281.934367] User Code: 000002aa16202794: e350a0000004	lg	%r5,0(%r10)
+[682281.934367]            000002aa1620279a: a749002e		lghi	%r4,46
+[682281.934367]           #000002aa1620279e: a7390001		lghi	%r3,1
+[682281.934367]           >000002aa162027a2: e54c00040000	mvhi	4,0
+[682281.934367]            000002aa162027a8: c02000002867	larl	%r2,2aa16207876
+[682281.934367]            000002aa162027ae: c0e5fffffabd	brasl	%r14,2aa16201d28
+[682281.934367]            000002aa162027b4: e350b0000004	lg	%r5,0(%r11)
+[682281.934367]            000002aa162027ba: a749002e		lghi	%r4,46
+[682281.934379] Last Breaking-Event-Address:
+[682281.934382]  [<000003ff7f6fccb8>] 0x3ff7f6fccb8
+[682281.935888] User process fault: interruption code 003b ilc:3 in cmsysTestProcess[2aa36500000+9000]
+[682281.935896] Failing address: 0000000000000000 TEID: 0000000000000400
+[682281.935900] Fault in primary space mode while using user ASCE.
+[682281.935910] AS:00000000ab3f01c7 R3:0000000000000024
+[682281.935917] CPU: 0 PID: 29759 Comm: cmsysTestProces Not tainted 4.8.15-300.fc25.s390x #1
+[682281.935940] Hardware name: IBM              2827 H43              400              (z/VM)
+[682281.935941] task: 0000000083025580 task.stack: 00000000bebf4000
+[682281.935942] User PSW : 0705000180000000 000002aa365027a2
+[682281.935943]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:1 AS:0 CC:0 PM:0 RI:0 EA:3
+[682281.935943] User GPRS: 0000000000000000 000003ff00000000 0000000000000000 0000000000000001
+[682281.935946]            000000000000002e 000003ff9ce48c88 000002aa36507430 000003ffd60febe0
+[682281.935947]            000002aa3650769e 0000000000000000 000003ff9ce48d70 000003ff9ce48d68
+[682281.935948]            000003ff9cf28f58 000002aa36507df0 000002aa36502794 000003ffd60fe6a8
+[682281.935954] User Code: 000002aa36502794: e350a0000004	lg	%r5,0(%r10)
+[682281.935954]            000002aa3650279a: a749002e		lghi	%r4,46
+[682281.935954]           #000002aa3650279e: a7390001		lghi	%r3,1
+[682281.935954]           >000002aa365027a2: e54c00040000	mvhi	4,0
+[682281.935954]            000002aa365027a8: c02000002867	larl	%r2,2aa36507876
+[682281.935954]            000002aa365027ae: c0e5fffffabd	brasl	%r14,2aa36501d28
+[682281.935954]            000002aa365027b4: e350b0000004	lg	%r5,0(%r11)
+[682281.935954]            000002aa365027ba: a749002e		lghi	%r4,46
+[682281.935964] Last Breaking-Event-Address:
+[682281.935965]  [<000003ff9ccfccb8>] 0x3ff9ccfccb8
+[682695.568959] User process fault: interruption code 0010 ilc:3 in Crash[1000000+1000]
+[682695.568971] Failing address: 0000000000000000 TEID: 0000000000000400
+[682695.568973] Fault in primary space mode while using user ASCE.
+[682695.568977] AS:00000000549a41c7 R3:000000006654c007 S:0000000000000020
+[682695.568983] CPU: 0 PID: 6485 Comm: Crash Not tainted 4.8.15-300.fc25.s390x #1
+[682695.568986] Hardware name: IBM              2827 H43              400              (z/VM)
+[682695.568989] task: 00000000f81fb900 task.stack: 0000000004058000
+[682695.568992] User PSW : 0705100180000000 0000000001000776
+[682695.568995]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:1 AS:0 CC:1 PM:0 RI:0 EA:3
+[682695.568995] User GPRS: 0000000000000000 0000000000000000 0000000000000001 000003ffd4cfe438
+[682695.569003]            000003ffd4cfe448 0090305969303276 0000000001000800 000003ffd4cfe420
+[682695.569007]            0000000001000668 0000000000000000 000002aa3e31b1f0 000003ffd4cfe168
+[682695.569011]            000003ff91328f58 000002aa3e3251f0 000003ff90d22b9e 000003ffd4cfe168
+[682695.572673] User Code: 0000000001000766: b90400bf		lgr	%r11,%r15
+[682695.572673]            000000000100076a: e548b0a00000	mvghi	160(%r11),0
+[682695.572673]           #0000000001000770: e310b0a00004	lg	%r1,160(%r11)
+[682695.572673]           >0000000001000776: e54c10000001	mvhi	0(%r1),1
+[682695.572673]            000000000100077c: a7180000		lhi	%r1,0
+[682695.572673]            0000000001000780: b9140011		lgfr	%r1,%r1
+[682695.572673]            0000000001000784: b9040021		lgr	%r2,%r1
+[682695.572673]            0000000001000788: b3cd00b2		lgdr	%r11,%f2
+[682695.572686] Last Breaking-Event-Address:
+[682695.572690]  [<000003ff90d22b9c>] 0x3ff90d22b9c
+[699521.918071] User process fault: interruption code 0004 ilc:3 in conftest[1000000+c5000]
+[699521.918083] Failing address: 00000000010c6000 TEID: 00000000010c6404
+[699521.918085] Fault in primary space mode while using user ASCE.
+[699521.918089] AS:00000000a80d41c7 R3:00000000a462c007 S:000000008267e000 P:00000000918ff21d
+[699521.918095] CPU: 2 PID: 42951 Comm: conftest Not tainted 4.8.15-300.fc25.s390x #1
+[699521.918098] Hardware name: IBM              2827 H43              400              (z/VM)
+[699521.918101] task: 00000000f4a41c80 task.stack: 0000000082ff0000
+[699521.918104] User PSW : 0705000180000000 000000000100de62
+[699521.918107]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:1 AS:0 CC:0 PM:0 RI:0 EA:3
+[699521.918107] User GPRS: fffffffffffffff0 0000000000000000 000003ffde67c020 0000000000000001
+[699521.918116]            000003ffde67c0d8 000000000100e590 000000000100e638 000003ffde67c0c0
+[699521.918120]            000000000100dca8 000002aa3f932170 0000000000000000 000002aa3f9d0e10
+[699521.918124]            000000000100e590 000002aa3f9d1010 000000000100dce6 000003ffde67beb0
+[699521.918140] User Code: 000000000100de54: a71affff		ahi	%r1,-1
+[699521.918140]            000000000100de58: 8810001f		srl	%r1,31
+[699521.918140]           #000000000100de5c: c41f0005d5a6	strl	%r1,10c89a8
+[699521.918140]           >000000000100de62: c42b0005c7ff	stgrl	%r2,10c6e60
+[699521.918140]            000000000100de68: e310f0a00004	lg	%r1,160(%r15)
+[699521.918140]            000000000100de6e: ec21000100d9	aghik	%r2,%r1,1
+[699521.918140]            000000000100de74: eb220003000d	sllg	%r2,%r2,3
+[699521.918140]            000000000100de7a: e320f0a80008	ag	%r2,168(%r15)
+[699521.918152] Last Breaking-Event-Address:
+[699521.918155]  [<000000000100dce0>] 0x100dce0
+[701836.544344] User process fault: interruption code 0004 ilc:3 in conftest[1000000+c5000]
+[701836.544354] Failing address: 00000000010c6000 TEID: 00000000010c6404
+[701836.544357] Fault in primary space mode while using user ASCE.
+[701836.544360] AS:00000000ef6401c7 R3:00000000b52c0007 S:00000000a9721000 P:00000000ce7c021d
+[701836.544367] CPU: 3 PID: 48640 Comm: conftest Not tainted 4.8.15-300.fc25.s390x #1
+[701836.544370] Hardware name: IBM              2827 H43              400              (z/VM)
+[701836.544374] task: 00000000f5b4b900 task.stack: 000000008287c000
+[701836.544377] User PSW : 0705000180000000 000000000100de62
+[701836.544380]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:1 AS:0 CC:0 PM:0 RI:0 EA:3
+[701836.544380] User GPRS: fffffffffffffff0 0000000000000000 000003ffeaf7bfa0 0000000000000001
+[701836.544389]            000003ffeaf7c058 000000000100e590 000000000100e638 000003ffeaf7c040
+[701836.544393]            000000000100dca8 000002aa48a418c0 0000000000000000 000002aa48a4b240
+[701836.544397]            000000000100e590 000002aa48a52730 000000000100dce6 000003ffeaf7be30
+[701836.544414] User Code: 000000000100de54: a71affff		ahi	%r1,-1
+[701836.544414]            000000000100de58: 8810001f		srl	%r1,31
+[701836.544414]           #000000000100de5c: c41f0005d5a6	strl	%r1,10c89a8
+[701836.544414]           >000000000100de62: c42b0005c7ff	stgrl	%r2,10c6e60
+[701836.544414]            000000000100de68: e310f0a00004	lg	%r1,160(%r15)
+[701836.544414]            000000000100de6e: ec21000100d9	aghik	%r2,%r1,1
+[701836.544414]            000000000100de74: eb220003000d	sllg	%r2,%r2,3
+[701836.544414]            000000000100de7a: e320f0a80008	ag	%r2,168(%r15)
+[701836.544427] Last Breaking-Event-Address:
+[701836.544429]  [<000000000100dce0>] 0x100dce0
+[702856.049112] User process fault: interruption code 0004 ilc:3 in conftest[1000000+c5000]
+[702856.049125] Failing address: 00000000010c6000 TEID: 00000000010c6404
+[702856.049127] Fault in primary space mode while using user ASCE.
+[702856.049131] AS:00000000801581c7 R3:00000000a7da4007 S:00000000802e9000 P:00000000a540621d
+[702856.049138] CPU: 2 PID: 53342 Comm: conftest Not tainted 4.8.15-300.fc25.s390x #1
+[702856.049141] Hardware name: IBM              2827 H43              400              (z/VM)
+[702856.049144] task: 00000000f5b49c80 task.stack: 00000000f3f70000
+[702856.049147] User PSW : 0705000180000000 000000000100de62
+[702856.049151]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:1 AS:0 CC:0 PM:0 RI:0 EA:3
+[702856.049151] User GPRS: fffffffffffffff0 0000000000000000 000003fff267b9b0 0000000000000001
+[702856.049160]            000003fff267ba68 000000000100e590 000000000100e638 000003fff267ba50
+[702856.049163]            000000000100dca8 000002aa1fc0f9b0 0000000000000000 000002aa1fced3e0
+[702856.049168]            000000000100e590 000002aa1fceda20 000000000100dce6 000003fff267b840
+[702856.049188] User Code: 000000000100de54: a71affff		ahi	%r1,-1
+[702856.049188]            000000000100de58: 8810001f		srl	%r1,31
+[702856.049188]           #000000000100de5c: c41f0005d5a6	strl	%r1,10c89a8
+[702856.049188]           >000000000100de62: c42b0005c7ff	stgrl	%r2,10c6e60
+[702856.049188]            000000000100de68: e310f0a00004	lg	%r1,160(%r15)
+[702856.049188]            000000000100de6e: ec21000100d9	aghik	%r2,%r1,1
+[702856.049188]            000000000100de74: eb220003000d	sllg	%r2,%r2,3
+[702856.049188]            000000000100de7a: e320f0a80008	ag	%r2,168(%r15)
+[702856.049200] Last Breaking-Event-Address:
+[702856.049203]  [<000000000100dce0>] 0x100dce0
+[703009.939101] User process fault: interruption code 0004 ilc:3 in conftest[1000000+c5000]
+[703009.939113] Failing address: 00000000010c6000 TEID: 00000000010c6404
+[703009.939116] Fault in primary space mode while using user ASCE.
+[703009.939119] AS:0000000000dd41c7 R3:00000000014e8007 S:0000000000ea3000 P:00000000405c321d
+[703009.939126] CPU: 0 PID: 47870 Comm: conftest Not tainted 4.8.15-300.fc25.s390x #1
+[703009.939129] Hardware name: IBM              2827 H43              400              (z/VM)
+[703009.939132] task: 0000000005645580 task.stack: 000000000c554000
+[703009.939135] User PSW : 0705000180000000 000000000100de62
+[703009.939139]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:1 AS:0 CC:0 PM:0 RI:0 EA:3
+[703009.939139] User GPRS: fffffffffffffff0 0000000000000000 000003fff327c090 0000000000000001
+[703009.939147]            000003fff327c148 000000000100e590 000000000100e638 000003fff327c130
+[703009.939151]            000000000100dca8 000002aa309f3570 0000000000000000 000002aa309ee380
+[703009.939155]            000000000100e590 000002aa30a96c80 000000000100dce6 000003fff327bf20
+[703009.939894] User Code: 000000000100de54: a71affff		ahi	%r1,-1
+[703009.939894]            000000000100de58: 8810001f		srl	%r1,31
+[703009.939894]           #000000000100de5c: c41f0005d5a6	strl	%r1,10c89a8
+[703009.939894]           >000000000100de62: c42b0005c7ff	stgrl	%r2,10c6e60
+[703009.939894]            000000000100de68: e310f0a00004	lg	%r1,160(%r15)
+[703009.939894]            000000000100de6e: ec21000100d9	aghik	%r2,%r1,1
+[703009.939894]            000000000100de74: eb220003000d	sllg	%r2,%r2,3
+[703009.939894]            000000000100de7a: e320f0a80008	ag	%r2,168(%r15)
+[703009.939931] Last Breaking-Event-Address:
+[703009.939936]  [<000000000100dce0>] 0x100dce0
+[703026.481842] User process fault: interruption code 0004 ilc:3 in conftest[1000000+c5000]
+[703026.481852] Failing address: 00000000010c6000 TEID: 00000000010c6404
+[703026.481854]
+
+'''
+		return returncode, output
+
+
+class TestLinuxFedora_5_s390x(unittest.TestCase):
+	def setUp(self):
+		helpers.backup_data_source(cpuinfo)
+		helpers.monkey_patch_data_source(cpuinfo, MockDataSource)
+
+	def tearDown(self):
+		helpers.restore_data_source(cpuinfo)
+
+	'''
+	Make sure calls return the expected number of fields.
+	'''
+	def test_returns(self):
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_registry()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpufreq_info()))
+		self.assertEqual(10, len(cpuinfo._get_cpu_info_from_lscpu()))
+		self.assertEqual(7, len(cpuinfo._get_cpu_info_from_proc_cpuinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysctl()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_kstat()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_dmesg()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
+		self.assertEqual(17, len(cpuinfo._get_cpu_info_internal()))
+
+	def test_get_cpu_info_from_lscpu(self):
+		info = cpuinfo._get_cpu_info_from_lscpu()
+
+		self.assertEqual('IBM/S390', info['vendor_id_raw'])
+		#self.assertEqual('FIXME', info['brand'])
+		self.assertEqual('5.5040 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('5.5040 GHz', info['hz_actual_friendly'])
+		self.assertEqual((5504000000, 0), info['hz_advertised'])
+		self.assertEqual((5504000000, 0), info['hz_actual'])
+
+		#self.assertEqual(7, info['stepping'])
+		#self.assertEqual(42, info['model'])
+		#self.assertEqual(6, info['family'])
+
+		self.assertEqual(64 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(96 * 1024, info['l1_data_cache_size'])
+
+		self.assertEqual(1024 * 1024, info['l2_cache_size'])
+		self.assertEqual(49152 * 1024, info['l3_cache_size'])
+
+		self.assertEqual(
+			['dfp', 'eimm', 'esan3', 'etf3eh', 'highgprs', 'ldisp',
+			'msa', 'sie', 'stfle', 'zarch']
+			,
+			info['flags']
+		)
+
+	def test_get_cpu_info_from_dmesg(self):
+		info = cpuinfo._get_cpu_info_from_dmesg()
+
+		#self.assertEqual('FIXME', info['brand'])
+
+	def test_get_cpu_info_from_proc_cpuinfo(self):
+		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
+
+		self.assertEqual('IBM/S390', info['vendor_id_raw'])
+		#self.assertEqual('FIXME', info['brand'])
+		self.assertEqual('5.5040 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('5.5040 GHz', info['hz_actual_friendly'])
+		self.assertEqual((5504000000, 0), info['hz_advertised'])
+		self.assertEqual((5504000000, 0), info['hz_actual'])
+
+		self.assertEqual(49152 * 1024, info['l3_cache_size'])
+
+		#self.assertEqual(7, info['stepping'])
+		#self.assertEqual(42, info['model'])
+		#self.assertEqual(6, info['family'])
+		self.assertEqual(
+			['dfp', 'edat', 'eimm', 'esan3', 'etf3eh', 'highgprs', 'ldisp',
+			'msa', 'sie', 'stfle', 'te', 'zarch']
+			,
+			info['flags']
+		)
+
+	def test_all(self):
+		info = cpuinfo._get_cpu_info_internal()
+		self.assertEqual('IBM/S390', info['vendor_id_raw'])
+		#self.assertEqual('FIXME', info['brand'])
+		self.assertEqual('5.5040 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('5.5040 GHz', info['hz_actual_friendly'])
+		self.assertEqual((5504000000, 0), info['hz_advertised'])
+		self.assertEqual((5504000000, 0), info['hz_actual'])
+		self.assertEqual('S390X', info['arch'])
+		self.assertEqual(64, info['bits'])
+		self.assertEqual(4, info['count'])
+
+		self.assertEqual('s390x', info['arch_string_raw'])
+
+		self.assertEqual(64 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(96 * 1024, info['l1_data_cache_size'])
+
+		self.assertEqual(1024 * 1024, info['l2_cache_size'])
+		self.assertEqual(49152 * 1024, info['l3_cache_size'])
+
+		#self.assertEqual(7, info['stepping'])
+		#self.assertEqual(42, info['model'])
+		#self.assertEqual(6, info['family'])
+		self.assertEqual(
+			['dfp', 'edat', 'eimm', 'esan3', 'etf3eh', 'highgprs', 'ldisp',
+			'msa', 'sie', 'stfle', 'te', 'zarch'],
+			info['flags']
+		)
diff --git a/tests/test_linux_gentoo_2_2_x86_64.py b/tests/test_linux_gentoo_2_2_x86_64.py
index 9a4cbb3..ff736e6 100644
--- a/tests/test_linux_gentoo_2_2_x86_64.py
+++ b/tests/test_linux_gentoo_2_2_x86_64.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 2
 	is_windows = False
-	raw_arch_string = 'x86_64'
+	arch_string_raw = 'x86_64'
+	uname_string_raw = 'x86_64'
 	can_cpuid = False
 
 	@staticmethod
@@ -27,7 +28,7 @@ class MockDataSource(object):
 	@staticmethod
 	def cat_proc_cpuinfo():
 		returncode = 0
-		output = '''
+		output = r'''
 processor	: 0
 vendor_id	: GenuineIntel
 cpu family	: 6
@@ -87,7 +88,7 @@ power management:
 	@staticmethod
 	def dmesg_a():
 		returncode = 0
-		output = '''
+		output = r'''
 ===============================================================================
 [    0.000000] Linux version 4.5.2-aufs-r1 (root@jasmin) (gcc version 5.4.0 (Gentoo 5.4.0 p1.0, pie-0.6.5) ) #1 SMP Sun Jul 3 17:17:11 UTC 2016
 [    0.000000] Command line: BOOT_IMAGE=/isolinux/gentoo root=/dev/ram0 init=/linuxrc dokeymap aufs looptype=squashfs loop=/image.squashfs cdroot initrd=/isolinux/gentoo.xz console=tty1
@@ -412,7 +413,7 @@ power management:
 	@staticmethod
 	def lscpu():
 		returncode = 0
-		output = '''
+		output = r'''
 Architecture:          x86_64
 CPU op-mode(s):        32-bit, 64-bit
 Byte Order:            Little Endian
@@ -464,26 +465,26 @@ class TestLinuxGentoo_2_2_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(20, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(21, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.7937 GHz', info['hz_advertised'])
-		self.assertEqual('2.7937 GHz', info['hz_actual'])
-		self.assertEqual((2793652000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2793652000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.7937 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.7937 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2793652000, 0), info['hz_advertised'])
+		self.assertEqual((2793652000, 0), info['hz_actual'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
 		self.assertEqual(6, info['family'])
 
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('32 KB', info['l1_data_cache_size'])
-		self.assertEqual('256 KB', info['l2_cache_size'])
-		self.assertEqual('3072 KB', info['l3_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
 
 		self.assertEqual(
 			['apic', 'clflush', 'cmov', 'constant_tsc', 'cx16', 'cx8', 'de',
@@ -499,11 +500,11 @@ class TestLinuxGentoo_2_2_X86_64(unittest.TestCase):
 	def test_get_cpu_info_from_dmesg(self):
 		info = cpuinfo._get_cpu_info_from_dmesg()
 
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('2.8000 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2800000000, 0), info['hz_actual_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.8000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((2800000000, 0), info['hz_actual'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
@@ -512,14 +513,14 @@ class TestLinuxGentoo_2_2_X86_64(unittest.TestCase):
 	def test_get_cpu_info_from_proc_cpuinfo(self):
 		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('2.7937 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2793652000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.7937 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((2793652000, 0), info['hz_actual'])
 
-		self.assertEqual('3072 KB', info['l3_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
@@ -538,22 +539,22 @@ class TestLinuxGentoo_2_2_X86_64(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('2.7937 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2793652000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.7937 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((2793652000, 0), info['hz_actual'])
 		self.assertEqual('X86_64', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(2, info['count'])
 
-		self.assertEqual('x86_64', info['raw_arch_string'])
+		self.assertEqual('x86_64', info['arch_string_raw'])
 
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('32 KB', info['l1_data_cache_size'])
-		self.assertEqual('256 KB', info['l2_cache_size'])
-		self.assertEqual('3072 KB', info['l3_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
diff --git a/tests/test_linux_mips64el_loongson3A3000.py b/tests/test_linux_mips64el_loongson3A3000.py
new file mode 100644
index 0000000..2daac82
--- /dev/null
+++ b/tests/test_linux_mips64el_loongson3A3000.py
@@ -0,0 +1,181 @@
+
+
+import unittest
+from cpuinfo import *
+import helpers
+
+
+class MockDataSource(object):
+	bits = '64bit'
+	cpu_count = 4
+	is_windows = False
+	arch_string_raw = 'mips64'
+	uname_string_raw = ''
+	can_cpuid = False
+
+	@staticmethod
+	def has_proc_cpuinfo():
+		return True
+
+	@staticmethod
+	def has_lscpu():
+		return True
+
+
+	@staticmethod
+	def cat_proc_cpuinfo():
+		returncode = 0
+		output = r'''
+system type             : generic-loongson-machine
+machine                 : Unknown
+processor               : 0
+cpu model               : ICT Loongson-3 V0.13  FPU V0.1
+model name              : ICT Loongson-3A R3 (Loongson-3A3000) @ 1449MHz
+BogoMIPS                : 2887.52
+wait instruction        : yes
+microsecond timers      : yes
+tlb_entries             : 1088
+extra interrupt vector  : no
+hardware watchpoint     : yes, count: 0, address/irw mask: []
+isa                     : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2
+ASEs implemented        : vz
+shadow register sets    : 1
+kscratch registers      : 6
+package                 : 0
+core                    : 0
+VCED exceptions         : not available
+VCEI exceptions         : not available
+
+processor               : 1
+cpu model               : ICT Loongson-3 V0.13  FPU V0.1
+model name              : ICT Loongson-3A R3 (Loongson-3A3000) @ 1449MHz
+BogoMIPS                : 2902.61
+wait instruction        : yes
+microsecond timers      : yes
+tlb_entries             : 1088
+extra interrupt vector  : no
+hardware watchpoint     : yes, count: 0, address/irw mask: []
+isa                     : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2
+ASEs implemented        : vz
+shadow register sets    : 1
+kscratch registers      : 6
+package                 : 0
+core                    : 1
+VCED exceptions         : not available
+VCEI exceptions         : not available
+
+processor               : 2
+cpu model               : ICT Loongson-3 V0.13  FPU V0.1
+model name              : ICT Loongson-3A R3 (Loongson-3A3000) @ 1449MHz
+BogoMIPS                : 2902.61
+wait instruction        : yes
+microsecond timers      : yes
+tlb_entries             : 1088
+extra interrupt vector  : no
+hardware watchpoint     : yes, count: 0, address/irw mask: []
+isa                     : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2
+ASEs implemented        : vz
+shadow register sets    : 1
+kscratch registers      : 6
+package                 : 0
+core                    : 2
+VCED exceptions         : not available
+VCEI exceptions         : not available
+
+processor               : 3
+cpu model               : ICT Loongson-3 V0.13  FPU V0.1
+model name              : ICT Loongson-3A R3 (Loongson-3A3000) @ 1449MHz
+BogoMIPS                : 2887.52
+wait instruction        : yes
+microsecond timers      : yes
+tlb_entries             : 1088
+extra interrupt vector  : no
+hardware watchpoint     : yes, count: 0, address/irw mask: []
+isa                     : mips1 mips2 mips3 mips4 mips5 mips32r1 mips32r2 mips64r1 mips64r2
+ASEs implemented        : vz
+shadow register sets    : 1
+kscratch registers      : 6
+package                 : 0
+core                    : 3
+VCED exceptions         : not available
+VCEI exceptions         : not available
+'''
+		return returncode, output
+
+	@staticmethod
+	def lscpu():
+		returncode = 0
+		output = r'''
+Architecture:          mips64
+Byte Order:            Little Endian
+CPU(s):                4
+On-line CPU(s) list:   0-3
+Thread(s) per core:    1
+Core(s) per socket:    4
+Socket(s):             1
+NUMA node(s):          1
+Model name:            ICT Loongson-3A R3 (Loongson-3A3000) @ 1449MHz
+BogoMIPS:              2887.52
+L1d cache:             64K
+L1i cache:             64K
+L2 cache:              256K
+L3 cache:              2048K
+NUMA node0 CPU(s):     0-3
+'''
+		return returncode, output
+
+
+class TestLinux_mips64el_Loongson3A3000(unittest.TestCase):
+
+	def setUp(self):
+		helpers.backup_data_source(cpuinfo)
+		helpers.monkey_patch_data_source(cpuinfo, MockDataSource)
+
+	def tearDown(self):
+		helpers.restore_data_source(cpuinfo)
+
+	'''
+	Make sure calls return the expected number of fields.
+	'''
+	def test_returns(self):
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_registry()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpufreq_info()))
+		self.assertEqual(5, len(cpuinfo._get_cpu_info_from_lscpu()))
+		self.assertEqual(6, len(cpuinfo._get_cpu_info_from_proc_cpuinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysctl()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_kstat()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_dmesg()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
+		self.assertEqual(17, len(cpuinfo._get_cpu_info_internal()))
+
+	def test_get_cpu_info_from_lscpu(self):
+		info = cpuinfo._get_cpu_info_from_lscpu()
+
+		self.assertEqual('ICT Loongson-3A R3 (Loongson-3A3000) @ 1449MHz', info['brand_raw'])
+		self.assertEqual(65536, info['l1_data_cache_size'])
+		self.assertEqual(65536, info['l1_instruction_cache_size'])
+		self.assertEqual(262144, info['l2_cache_size'])
+		self.assertEqual(2097152, info['l3_cache_size'])
+
+	def test_get_cpu_info_from_proc_cpuinfo(self):
+		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
+
+		self.assertEqual('ICT Loongson-3A R3 (Loongson-3A3000) @ 1449MHz', info['brand_raw'])
+		self.assertEqual('1.4490 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.4490 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1449000000, 0), info['hz_advertised'])
+		self.assertEqual((1449000000, 0), info['hz_actual'])
+		self.assertEqual(['vz'], info['flags'])
+
+	def test_all(self):
+		info = cpuinfo._get_cpu_info_internal()
+
+		self.assertEqual('ICT Loongson-3A R3 (Loongson-3A3000) @ 1449MHz', info['brand_raw'])
+		self.assertEqual('MIPS_64', info['arch'])
+		self.assertEqual(64, info['bits'])
+		self.assertEqual(4, info['count'])
+		self.assertEqual('mips64', info['arch_string_raw'])
+		self.assertEqual(['vz'], info['flags'])
diff --git a/tests/test_linux_odroid_c2_aarch64.py b/tests/test_linux_odroid_c2_aarch64.py
index da94b92..6db81a8 100644
--- a/tests/test_linux_odroid_c2_aarch64.py
+++ b/tests/test_linux_odroid_c2_aarch64.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 4
 	is_windows = False
-	raw_arch_string = 'aarch64'
+	arch_string_raw = 'aarch64'
+	uname_string_raw = 'x86_64'
 	can_cpuid = False
 
 	@staticmethod
@@ -27,7 +28,7 @@ class MockDataSource(object):
 	@staticmethod
 	def cat_proc_cpuinfo():
 		returncode = 0
-		output = '''
+		output = r'''
 processor	: 0
 BogoMIPS	: 2.00
 Features	: fp asimd crc32
@@ -74,7 +75,7 @@ Revision	: 020c
 	@staticmethod
 	def lscpu():
 		returncode = 0
-		output = '''
+		output = r'''
 Architecture:          aarch64
 Byte Order:            Little Endian
 CPU(s):                4
@@ -90,7 +91,7 @@ CPU min MHz:           100.0000
 	@staticmethod
 	def cpufreq_info():
 		returncode = 0
-		output = '''
+		output = r'''
 cpufrequtils 008: cpufreq-info (C) Dominik Brodowski 2004-2009
 Report errors and bugs to cpufreq@vger.kernel.org, please.
 analyzing CPU 0:
@@ -173,28 +174,28 @@ class TestLinux_Odroid_C2_Aarch_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(12, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(13, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_cpufreq_info(self):
 		info = cpuinfo._get_cpu_info_from_cpufreq_info()
 
-		self.assertEqual('1.5400 GHz', info['hz_advertised'])
-		self.assertEqual('1.5400 GHz', info['hz_actual'])
-		self.assertEqual((1540000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1540000000, 0), info['hz_actual_raw'])
+		self.assertEqual('1.5400 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.5400 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1540000000, 0), info['hz_advertised'])
+		self.assertEqual((1540000000, 0), info['hz_actual'])
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
 
-		self.assertEqual('1.5360 GHz', info['hz_advertised'])
-		self.assertEqual('1.5360 GHz', info['hz_actual'])
-		self.assertEqual((1536000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1536000000, 0), info['hz_actual_raw'])
+		self.assertEqual('1.5360 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.5360 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1536000000, 0), info['hz_advertised'])
+		self.assertEqual((1536000000, 0), info['hz_actual'])
 
 	def test_get_cpu_info_from_proc_cpuinfo(self):
 		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
 
-		self.assertEqual('ODROID-C2', info['hardware'])
+		self.assertEqual('ODROID-C2', info['hardware_raw'])
 
 		self.assertEqual(
 			['asimd', 'crc32', 'fp'],
@@ -204,16 +205,16 @@ class TestLinux_Odroid_C2_Aarch_64(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('ODROID-C2', info['hardware'])
-		self.assertEqual('1.5400 GHz', info['hz_advertised'])
-		self.assertEqual('1.5400 GHz', info['hz_actual'])
-		self.assertEqual((1540000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1540000000, 0), info['hz_actual_raw'])
+		self.assertEqual('ODROID-C2', info['hardware_raw'])
+		self.assertEqual('1.5400 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.5400 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1540000000, 0), info['hz_advertised'])
+		self.assertEqual((1540000000, 0), info['hz_actual'])
 		self.assertEqual('ARM_8', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(4, info['count'])
 
-		self.assertEqual('aarch64', info['raw_arch_string'])
+		self.assertEqual('aarch64', info['arch_string_raw'])
 
 		self.assertEqual(
 			['asimd', 'crc32', 'fp'],
diff --git a/tests/test_linux_odroid_xu3_arm_32.py b/tests/test_linux_odroid_xu3_arm_32.py
index 52291ea..a753290 100644
--- a/tests/test_linux_odroid_xu3_arm_32.py
+++ b/tests/test_linux_odroid_xu3_arm_32.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '32bit'
 	cpu_count = 8
 	is_windows = False
-	raw_arch_string = 'armv7l'
+	arch_string_raw = 'armv7l'
+	uname_string_raw = ''
 	can_cpuid = False
 
 	@staticmethod
@@ -27,7 +28,7 @@ class MockDataSource(object):
 	@staticmethod
 	def cat_proc_cpuinfo():
 		returncode = 0
-		output = '''
+		output = r'''
 processor	: 0
 model name	: ARMv7 Processor rev 3 (v7l)
 BogoMIPS	: 84.00
@@ -119,7 +120,7 @@ Serial		: 0000000000000000
 	@staticmethod
 	def lscpu():
 		returncode = 0
-		output = '''
+		output = r'''
 Architecture:          armv7l
 Byte Order:            Little Endian
 CPU(s):                8
@@ -137,7 +138,7 @@ CPU min MHz:           200.0000
 	@staticmethod
 	def cpufreq_info():
 		returncode = 0
-		output = '''
+		output = r'''
 cpufrequtils 008: cpufreq-info (C) Dominik Brodowski 2004-2009
 Report errors and bugs to cpufreq@vger.kernel.org, please.
 analyzing CPU 0:
@@ -264,30 +265,30 @@ class TestLinux_Odroid_XU3_arm_32(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(13, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(14, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_cpufreq_info(self):
 		info = cpuinfo._get_cpu_info_from_cpufreq_info()
 
-		self.assertEqual('1.4000 GHz', info['hz_advertised'])
-		self.assertEqual('1.4000 GHz', info['hz_actual'])
-		self.assertEqual((1400000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1400000000, 0), info['hz_actual_raw'])
+		self.assertEqual('1.4000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.4000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1400000000, 0), info['hz_advertised'])
+		self.assertEqual((1400000000, 0), info['hz_actual'])
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
 
-		self.assertEqual('ARMv7 Processor rev 3 (v7l)', info['brand'])
-		self.assertEqual('1.4000 GHz', info['hz_advertised'])
-		self.assertEqual('1.4000 GHz', info['hz_actual'])
-		self.assertEqual((1400000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1400000000, 0), info['hz_actual_raw'])
+		self.assertEqual('ARMv7 Processor rev 3 (v7l)', info['brand_raw'])
+		self.assertEqual('1.4000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.4000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1400000000, 0), info['hz_advertised'])
+		self.assertEqual((1400000000, 0), info['hz_actual'])
 
 	def test_get_cpu_info_from_proc_cpuinfo(self):
 		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
 
-		self.assertEqual('ARMv7 Processor rev 3 (v7l)', info['brand'])
-		self.assertEqual('ODROID-XU3', info['hardware'])
+		self.assertEqual('ARMv7 Processor rev 3 (v7l)', info['brand_raw'])
+		self.assertEqual('ODROID-XU3', info['hardware_raw'])
 
 		self.assertEqual(
 			['edsp', 'fastmult', 'half', 'idiva', 'idivt', 'neon', 'swp',
@@ -298,17 +299,17 @@ class TestLinux_Odroid_XU3_arm_32(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('ARMv7 Processor rev 3 (v7l)', info['brand'])
-		self.assertEqual('ODROID-XU3', info['hardware'])
-		self.assertEqual('1.4000 GHz', info['hz_advertised'])
-		self.assertEqual('1.4000 GHz', info['hz_actual'])
-		self.assertEqual((1400000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1400000000, 0), info['hz_actual_raw'])
+		self.assertEqual('ARMv7 Processor rev 3 (v7l)', info['brand_raw'])
+		self.assertEqual('ODROID-XU3', info['hardware_raw'])
+		self.assertEqual('1.4000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.4000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1400000000, 0), info['hz_advertised'])
+		self.assertEqual((1400000000, 0), info['hz_actual'])
 		self.assertEqual('ARM_7', info['arch'])
 		self.assertEqual(32, info['bits'])
 		self.assertEqual(8, info['count'])
 
-		self.assertEqual('armv7l', info['raw_arch_string'])
+		self.assertEqual('armv7l', info['arch_string_raw'])
 
 		self.assertEqual(
 			['edsp', 'fastmult', 'half', 'idiva', 'idivt', 'neon', 'swp',
diff --git a/tests/test_linux_raspberry_pi_model_b_arm.py b/tests/test_linux_raspberry_pi_model_b_arm.py
index ecc7114..f267683 100644
--- a/tests/test_linux_raspberry_pi_model_b_arm.py
+++ b/tests/test_linux_raspberry_pi_model_b_arm.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '32bit'
 	cpu_count = 1
 	is_windows = False
-	raw_arch_string = 'armv6l'
+	arch_string_raw = 'armv6l'
+	uname_string_raw = ''
 
 	@staticmethod
 	def has_proc_cpuinfo():
@@ -22,7 +23,7 @@ class MockDataSource(object):
 	@staticmethod
 	def cat_proc_cpuinfo():
 		returncode = 0
-		output = '''
+		output = r'''
 Processor	: ARMv6-compatible processor rev 7 (v6l)
 BogoMIPS	: 697.95
 Features	: swp half thumb fastmult vfp edsp java tls
@@ -43,7 +44,7 @@ Serial		: 0000000066564a8f
 	@staticmethod
 	def lscpu():
 		returncode = 0
-		output = '''
+		output = r'''
 Architecture:          armv6l
 Byte Order:            Little Endian
 CPU(s):                1
@@ -81,21 +82,21 @@ class TestLinux_RaspberryPiModelB(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(13, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(14, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
 
-		self.assertEqual('700.0000 MHz', info['hz_advertised'])
-		self.assertEqual('700.0000 MHz', info['hz_actual'])
-		self.assertEqual((700000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((700000000, 0), info['hz_actual_raw'])
+		self.assertEqual('700.0000 MHz', info['hz_advertised_friendly'])
+		self.assertEqual('700.0000 MHz', info['hz_actual_friendly'])
+		self.assertEqual((700000000, 0), info['hz_advertised'])
+		self.assertEqual((700000000, 0), info['hz_actual'])
 
 	def test_get_cpu_info_from_proc_cpuinfo(self):
 		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
 
-		self.assertEqual('BCM2708', info['hardware'])
-		self.assertEqual('ARMv6-compatible processor rev 7 (v6l)', info['brand'])
+		self.assertEqual('BCM2708', info['hardware_raw'])
+		self.assertEqual('ARMv6-compatible processor rev 7 (v6l)', info['brand_raw'])
 
 		self.assertEqual(
 			['edsp', 'fastmult', 'half', 'java', 'swp', 'thumb', 'tls', 'vfp']
@@ -106,17 +107,17 @@ class TestLinux_RaspberryPiModelB(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('BCM2708', info['hardware'])
-		self.assertEqual('ARMv6-compatible processor rev 7 (v6l)', info['brand'])
-		self.assertEqual('700.0000 MHz', info['hz_advertised'])
-		self.assertEqual('700.0000 MHz', info['hz_actual'])
-		self.assertEqual((700000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((700000000, 0), info['hz_actual_raw'])
+		self.assertEqual('BCM2708', info['hardware_raw'])
+		self.assertEqual('ARMv6-compatible processor rev 7 (v6l)', info['brand_raw'])
+		self.assertEqual('700.0000 MHz', info['hz_advertised_friendly'])
+		self.assertEqual('700.0000 MHz', info['hz_actual_friendly'])
+		self.assertEqual((700000000, 0), info['hz_advertised'])
+		self.assertEqual((700000000, 0), info['hz_actual'])
 		self.assertEqual('ARM_7', info['arch'])
 		self.assertEqual(32, info['bits'])
 		self.assertEqual(1, info['count'])
 
-		self.assertEqual('armv6l', info['raw_arch_string'])
+		self.assertEqual('armv6l', info['arch_string_raw'])
 
 		self.assertEqual(
 			['edsp', 'fastmult', 'half', 'java', 'swp', 'thumb', 'tls', 'vfp']
diff --git a/tests/test_linux_rhel_7_3_ppc64le.py b/tests/test_linux_rhel_7_3_ppc64le.py
index 7f34206..b591ad8 100644
--- a/tests/test_linux_rhel_7_3_ppc64le.py
+++ b/tests/test_linux_rhel_7_3_ppc64le.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 16
 	is_windows = False
-	raw_arch_string = 'ppc64le'
+	arch_string_raw = 'ppc64le'
+	uname_string_raw = ''
 	can_cpuid = False
 
 	@staticmethod
@@ -31,7 +32,7 @@ class MockDataSource(object):
 	@staticmethod
 	def ibm_pa_features():
 		returncode = 0
-		output = '''
+		output = r'''
 /proc/device-tree/cpus/PowerPC,POWER7@1/ibm,pa-features 3ff60006 c08000c7
 
 '''
@@ -40,7 +41,7 @@ class MockDataSource(object):
 	@staticmethod
 	def cat_proc_cpuinfo():
 		returncode = 0
-		output = '''
+		output = r'''
 processor	: 0
 cpu		: POWER8E (raw), altivec supported
 clock		: 3425.000000MHz
@@ -132,7 +133,7 @@ machine		: CHRP IBM pSeries (emulated by qemu)
 	@staticmethod
 	def dmesg_a():
 		returncode = 0
-		output = '''
+		output = r'''
 [3269512.154534] convolution_var[11236]: unhandled signal 4 at 00003fff6c390004 nip 00003fff6c390004 lr 00003fff9a648d58 code 30001
 [3269512.234818] convolution_var[11344]: unhandled signal 5 at 00003fff84390000 nip 00003fff84390000 lr 00003fffb2217ce0 code 30001
 [3269512.234823] convolution_var[11347]: unhandled signal 11 at 0000000000000304 nip 00003fff8439001c lr 00003fffb2217ce0 code 30001
@@ -300,7 +301,7 @@ machine		: CHRP IBM pSeries (emulated by qemu)
 	@staticmethod
 	def lscpu():
 		returncode = 0
-		output = '''
+		output = r'''
 Architecture:          ppc64le
 Byte Order:            Little Endian
 CPU(s):                16
@@ -342,13 +343,13 @@ class TestLinuxRHEL_7_3_ppc64le(unittest.TestCase):
 		self.assertEqual(1, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(14, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(15, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('64 KB', info['l1_data_cache_size'])
-		self.assertEqual('POWER8E (raw), altivec supported', info['brand'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(64 * 1024, info['l1_data_cache_size'])
+		self.assertEqual('POWER8E (raw), altivec supported', info['brand_raw'])
 
 	def test_get_cpu_info_from_ibm_pa_features(self):
 		info = cpuinfo._get_cpu_info_from_ibm_pa_features()
@@ -360,26 +361,26 @@ class TestLinuxRHEL_7_3_ppc64le(unittest.TestCase):
 	def test_get_cpu_info_from_proc_cpuinfo(self):
 		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
 
-		self.assertEqual('POWER8E (raw), altivec supported', info['brand'])
-		self.assertEqual('3.4250 GHz', info['hz_advertised'])
-		self.assertEqual('3.4250 GHz', info['hz_actual'])
-		self.assertEqual((3425000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((3425000000, 0), info['hz_actual_raw'])
+		self.assertEqual('POWER8E (raw), altivec supported', info['brand_raw'])
+		self.assertEqual('3.4250 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.4250 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3425000000, 0), info['hz_advertised'])
+		self.assertEqual((3425000000, 0), info['hz_actual'])
 
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('POWER8E (raw), altivec supported', info['brand'])
-		self.assertEqual('3.4250 GHz', info['hz_advertised'])
-		self.assertEqual('3.4250 GHz', info['hz_actual'])
-		self.assertEqual((3425000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((3425000000, 0), info['hz_actual_raw'])
+		self.assertEqual('POWER8E (raw), altivec supported', info['brand_raw'])
+		self.assertEqual('3.4250 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.4250 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3425000000, 0), info['hz_advertised'])
+		self.assertEqual((3425000000, 0), info['hz_actual'])
 		self.assertEqual('PPC_64', info['arch'])
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('64 KB', info['l1_data_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(64 * 1024, info['l1_data_cache_size'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(16, info['count'])
-		self.assertEqual('ppc64le', info['raw_arch_string'])
+		self.assertEqual('ppc64le', info['arch_string_raw'])
 		self.assertEqual(
 			['dss_2.02', 'dss_2.05', 'dss_2.06', 'fpu', 'lsd_in_dscr', 'ppr', 'slb', 'sso_2.06', 'ugr_in_dscr'],
 			info['flags']
diff --git a/tests/test_linux_ubuntu_16_04_x86_64.py b/tests/test_linux_ubuntu_16_04_x86_64.py
index 13dd60a..d96366f 100644
--- a/tests/test_linux_ubuntu_16_04_x86_64.py
+++ b/tests/test_linux_ubuntu_16_04_x86_64.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 2
 	is_windows = False
-	raw_arch_string = 'x86_64'
+	arch_string_raw = 'x86_64'
+	uname_string_raw = 'x86_64'
 	can_cpuid = False
 
 	@staticmethod
@@ -27,7 +28,7 @@ class MockDataSource(object):
 	@staticmethod
 	def cat_proc_cpuinfo():
 		returncode = 0
-		output = '''
+		output = r'''
 processor	: 0
 vendor_id	: GenuineIntel
 cpu family	: 6
@@ -89,7 +90,7 @@ power management:
 	@staticmethod
 	def lscpu():
 		returncode = 0
-		output = '''
+		output = r'''
 Architecture:          x86_64
 CPU op-mode(s):        32-bit, 64-bit
 Byte Order:            Little Endian
@@ -123,7 +124,7 @@ Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca
 	@staticmethod
 	def dmesg_a():
 		returncode = 0
-		output = '''
+		output = r'''
 [    0.000000] microcode: CPU0 microcode updated early to revision 0x29, date = 2013-06-12
 [    0.000000] Initializing cgroup subsys cpuset
 [    0.000000] Initializing cgroup subsys cpu
@@ -465,26 +466,26 @@ class TestLinuxUbuntu_16_04_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(20, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(21, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_lscpu(self):
 		info = cpuinfo._get_cpu_info_from_lscpu()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.0708 GHz', info['hz_advertised'])
-		self.assertEqual('2.0708 GHz', info['hz_actual'])
-		self.assertEqual((2070796000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2070796000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.0708 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.0708 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2070796000, 0), info['hz_advertised'])
+		self.assertEqual((2070796000, 0), info['hz_actual'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
 		self.assertEqual(6, info['family'])
 
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('32 KB', info['l1_data_cache_size'])
-		self.assertEqual('256 KB', info['l2_cache_size'])
-		self.assertEqual('3072 KB', info['l3_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
 		self.assertEqual(
 			['acpi', 'aperfmperf', 'apic', 'arat', 'arch_perfmon', 'bts',
 			'clflush', 'cmov', 'constant_tsc', 'cx16', 'cx8', 'de', 'ds_cpl',
@@ -504,11 +505,11 @@ class TestLinuxUbuntu_16_04_X86_64(unittest.TestCase):
 	def test_get_cpu_info_from_dmesg(self):
 		info = cpuinfo._get_cpu_info_from_dmesg()
 
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('2.8000 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2800000000, 0), info['hz_actual_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.8000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((2800000000, 0), info['hz_actual'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
@@ -517,14 +518,14 @@ class TestLinuxUbuntu_16_04_X86_64(unittest.TestCase):
 	def test_get_cpu_info_from_proc_cpuinfo(self):
 		info = cpuinfo._get_cpu_info_from_proc_cpuinfo()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('1.9014 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1901375000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.9014 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((1901375000, 0), info['hz_actual'])
 
-		self.assertEqual('3072 KB', info['l3_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
@@ -548,24 +549,24 @@ class TestLinuxUbuntu_16_04_X86_64(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand'])
-		self.assertEqual('2.8000 GHz', info['hz_advertised'])
-		self.assertEqual('1.9014 GHz', info['hz_actual'])
-		self.assertEqual((2800000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1901375000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', info['brand_raw'])
+		self.assertEqual('2.8000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.9014 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2800000000, 0), info['hz_advertised'])
+		self.assertEqual((1901375000, 0), info['hz_actual'])
 		self.assertEqual('X86_64', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(2, info['count'])
 
-		self.assertEqual('x86_64', info['raw_arch_string'])
+		self.assertEqual('x86_64', info['arch_string_raw'])
 
-		self.assertEqual('32 KB', info['l1_instruction_cache_size'])
-		self.assertEqual('32 KB', info['l1_data_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_instruction_cache_size'])
+		self.assertEqual(32 * 1024, info['l1_data_cache_size'])
 
-		self.assertEqual('256 KB', info['l2_cache_size'])
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
 
-		self.assertEqual('3072 KB', info['l3_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
diff --git a/tests/test_open_indiana_5_11_x86_64_ryzen_7.py b/tests/test_open_indiana_5_11_x86_64_ryzen_7.py
new file mode 100644
index 0000000..c5e4c56
--- /dev/null
+++ b/tests/test_open_indiana_5_11_x86_64_ryzen_7.py
@@ -0,0 +1,141 @@
+
+
+import unittest
+from cpuinfo import *
+import helpers
+
+
+class MockDataSource(object):
+	bits = '32bit'
+	cpu_count = 8
+	is_windows = False
+	arch_string_raw = 'i86pc'
+	uname_string_raw = 'i386'
+	can_cpuid = False
+
+	@staticmethod
+	def has_isainfo():
+		return True
+
+	@staticmethod
+	def has_kstat():
+		return True
+
+	@staticmethod
+	def isainfo_vb():
+		returncode = 0
+		output = r'''
+64-bit amd64 applications
+	rdseed avx2 rdrand avx xsave pclmulqdq aes movbe sse4.2 sse4.1
+	ssse3 amd_lzcnt popcnt amd_sse4a tscp ahf cx16 sse3 sse2 sse fxsr
+amd_mmx mmx cmov amd_sysc cx8 tsc fpu
+
+'''
+		return returncode, output
+
+	@staticmethod
+	def kstat_m_cpu_info():
+		returncode = 0
+		output = r'''
+module: cpu_info                        instance: 0
+name:   cpu_info0                       class:    misc
+	brand                           AMD Ryzen 7 2700X Eight-Core Processor
+	cache_id                        0
+	chip_id                         0
+	clock_MHz                       3693
+	clog_id                         0
+	core_id                         0
+	cpu_type                        i386
+	crtime                          22.539390752
+	current_clock_Hz                3692643590
+	current_cstate                  1
+	family                          23
+	fpu_type                        i387 compatible
+	implementation                  x86 (chipid 0x0 AuthenticAMD 800F82 family 23 model 8 step 2 clock 3693 MHz)
+	model                           8
+	ncore_per_chip                  8
+	ncpu_per_chip                   8
+	pg_id                           1
+	pkg_core_id                     0
+	snaptime                        120.971135132
+	socket_type                     Unknown
+	state                           on-line
+	state_begin                     1553482276
+	stepping                        2
+	supported_frequencies_Hz        3692643590
+	supported_max_cstates           0
+	vendor_id                       AuthenticAMD
+
+
+'''
+		return returncode, output
+
+
+
+class TestOpenIndiana_5_11_Ryzen_7(unittest.TestCase):
+	def setUp(self):
+		helpers.backup_data_source(cpuinfo)
+		helpers.monkey_patch_data_source(cpuinfo, MockDataSource)
+
+	def tearDown(self):
+		helpers.restore_data_source(cpuinfo)
+
+	'''
+	Make sure calls return the expected number of fields.
+	'''
+	def test_returns(self):
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_registry()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpufreq_info()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_lscpu()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_proc_cpuinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysctl()))
+		self.assertEqual(10, len(cpuinfo._get_cpu_info_from_kstat()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_dmesg()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
+		self.assertEqual(17, len(cpuinfo._get_cpu_info_internal()))
+
+	def test_get_cpu_info_from_kstat(self):
+		info = cpuinfo._get_cpu_info_from_kstat()
+
+		self.assertEqual('AuthenticAMD', info['vendor_id_raw'])
+		self.assertEqual('AMD Ryzen 7 2700X Eight-Core Processor', info['brand_raw'])
+		self.assertEqual('3.6930 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.6926 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3693000000, 0), info['hz_advertised'])
+		self.assertEqual((3692643590, 0), info['hz_actual'])
+
+		self.assertEqual(2, info['stepping'])
+		self.assertEqual(8, info['model'])
+		self.assertEqual(23, info['family'])
+		self.assertEqual(
+			['amd_mmx', 'amd_sysc', 'cmov', 'cx8', 'fpu', 'mmx', 'tsc']
+			,
+			info['flags']
+		)
+
+	def test_all(self):
+		info = cpuinfo._get_cpu_info_internal()
+
+		self.assertEqual('AuthenticAMD', info['vendor_id_raw'])
+		self.assertEqual('AMD Ryzen 7 2700X Eight-Core Processor', info['brand_raw'])
+		self.assertEqual('3.6930 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.6926 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3693000000, 0), info['hz_advertised'])
+		self.assertEqual((3692643590, 0), info['hz_actual'])
+		self.assertEqual('X86_32', info['arch'])
+		self.assertEqual(32, info['bits'])
+		self.assertEqual(8, info['count'])
+
+		self.assertEqual('i86pc', info['arch_string_raw'])
+
+		self.assertEqual(2, info['stepping'])
+		self.assertEqual(8, info['model'])
+		self.assertEqual(23, info['family'])
+		self.assertEqual(
+			['amd_mmx', 'amd_sysc', 'cmov', 'cx8', 'fpu', 'mmx', 'tsc']
+			,
+			info['flags']
+		)
diff --git a/tests/test_osx_10_12_x86_64.py b/tests/test_osx_10_12_x86_64.py
index b58d637..b9d471b 100644
--- a/tests/test_osx_10_12_x86_64.py
+++ b/tests/test_osx_10_12_x86_64.py
@@ -11,7 +11,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 4
 	is_windows = False
-	raw_arch_string = 'x86_64'
+	arch_string_raw = 'x86_64'
+	uname_string_raw = 'x86_64'
 	can_cpuid = False
 
 	@staticmethod
@@ -21,7 +22,7 @@ class MockDataSource(object):
 	@staticmethod
 	def sysctl_machdep_cpu_hw_cpufrequency():
 		returncode = 0
-		output = '''
+		output = r'''
 machdep.cpu.tsc_ccc.denominator: 0
 machdep.cpu.tsc_ccc.numerator: 0
 machdep.cpu.thread_count: 4
@@ -108,19 +109,19 @@ class TestOSX_10_12(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(17, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(18, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_sysctl(self):
 		info = cpuinfo._get_cpu_info_from_sysctl()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Core(TM) i5-2557M CPU @ 1.70GHz', info['brand'])
-		self.assertEqual('1.7000 GHz', info['hz_advertised'])
-		self.assertEqual('1.7000 GHz', info['hz_actual'])
-		self.assertEqual((1700000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1700000000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i5-2557M CPU @ 1.70GHz', info['brand_raw'])
+		self.assertEqual('1.7000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.7000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1700000000, 0), info['hz_advertised'])
+		self.assertEqual((1700000000, 0), info['hz_actual'])
 
-		self.assertEqual('256', info['l2_cache_size'])
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
@@ -142,19 +143,19 @@ class TestOSX_10_12(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Core(TM) i5-2557M CPU @ 1.70GHz', info['brand'])
-		self.assertEqual('1.7000 GHz', info['hz_advertised'])
-		self.assertEqual('1.7000 GHz', info['hz_actual'])
-		self.assertEqual((1700000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((1700000000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i5-2557M CPU @ 1.70GHz', info['brand_raw'])
+		self.assertEqual('1.7000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('1.7000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1700000000, 0), info['hz_advertised'])
+		self.assertEqual((1700000000, 0), info['hz_actual'])
 		self.assertEqual('X86_64', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(4, info['count'])
 
-		self.assertEqual('x86_64', info['raw_arch_string'])
+		self.assertEqual('x86_64', info['arch_string_raw'])
 
-		self.assertEqual('256', info['l2_cache_size'])
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
 
 		self.assertEqual(7, info['stepping'])
 		self.assertEqual(42, info['model'])
diff --git a/tests/test_osx_10_9_x86_64.py b/tests/test_osx_10_9_x86_64.py
index b247813..ecf97a4 100644
--- a/tests/test_osx_10_9_x86_64.py
+++ b/tests/test_osx_10_9_x86_64.py
@@ -11,7 +11,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 4
 	is_windows = False
-	raw_arch_string = 'x86_64'
+	arch_string_raw = 'x86_64'
+	uname_string_raw = 'x86_64'
 	can_cpuid = False
 
 	@staticmethod
@@ -21,7 +22,7 @@ class MockDataSource(object):
 	@staticmethod
 	def sysctl_machdep_cpu_hw_cpufrequency():
 		returncode = 0
-		output = '''
+		output = r'''
 machdep.cpu.max_basic: 5
 machdep.cpu.max_ext: 2147483656
 machdep.cpu.vendor: GenuineIntel
@@ -88,19 +89,19 @@ class TestOSX_10_9(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(17, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(18, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_sysctl(self):
 		info = cpuinfo._get_cpu_info_from_sysctl()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Core(TM) i5-4440 CPU @ 3.10GHz', info['brand'])
-		self.assertEqual('3.1000 GHz', info['hz_advertised'])
-		self.assertEqual('2.8900 GHz', info['hz_actual'])
-		self.assertEqual((3100000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2890000000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i5-4440 CPU @ 3.10GHz', info['brand_raw'])
+		self.assertEqual('3.1000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.8900 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3100000000, 0), info['hz_advertised'])
+		self.assertEqual((2890000000, 0), info['hz_actual'])
 
-		self.assertEqual('256', info['l2_cache_size'])
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
 
 		self.assertEqual(9, info['stepping'])
 		self.assertEqual(58, info['model'])
@@ -118,19 +119,19 @@ class TestOSX_10_9(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Core(TM) i5-4440 CPU @ 3.10GHz', info['brand'])
-		self.assertEqual('3.1000 GHz', info['hz_advertised'])
-		self.assertEqual('2.8900 GHz', info['hz_actual'])
-		self.assertEqual((3100000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2890000000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i5-4440 CPU @ 3.10GHz', info['brand_raw'])
+		self.assertEqual('3.1000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.8900 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3100000000, 0), info['hz_advertised'])
+		self.assertEqual((2890000000, 0), info['hz_actual'])
 		self.assertEqual('X86_64', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(4, info['count'])
 
-		self.assertEqual('x86_64', info['raw_arch_string'])
+		self.assertEqual('x86_64', info['arch_string_raw'])
 
-		self.assertEqual('256', info['l2_cache_size'])
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
 
 		self.assertEqual(9, info['stepping'])
 		self.assertEqual(58, info['model'])
diff --git a/tests/test_parse_cpu_string.py b/tests/test_parse_cpu_string.py
index 3310163..27fdfd1 100644
--- a/tests/test_parse_cpu_string.py
+++ b/tests/test_parse_cpu_string.py
@@ -6,88 +6,110 @@ import helpers
 
 
 
+
 class TestParseCPUString(unittest.TestCase):
-	def test_parse_cpu_string(self):
-		processor_brand, hz_actual, scale, vendor_id, stepping, model, family = \
-		cpuinfo._parse_cpu_string("Intel(R) Pentium(R) CPU G640 @ 2.80GHz (fam: 06, model: 2a, stepping: 07)")
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', processor_brand)
-		self.assertEqual('2.8', hz_actual)
-		self.assertEqual(9, scale)
-		self.assertEqual(None, vendor_id)
-		self.assertEqual(7, stepping)
-		self.assertEqual(42, model)
-		self.assertEqual(6, family)
-
-		processor_brand, hz_actual, scale, vendor_id, stepping, model, family = \
-		cpuinfo._parse_cpu_string("Intel(R) Pentium(R) CPU G640 @ 2.80GHz (family: 0x6, model: 0x2a, stepping: 0x7)")
-		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', processor_brand)
-		self.assertEqual('2.8', hz_actual)
-		self.assertEqual(9, scale)
-		self.assertEqual(None, vendor_id)
-		self.assertEqual(7, stepping)
-		self.assertEqual(42, model)
-		self.assertEqual(6, family)
-
-		processor_brand, hz_actual, scale, vendor_id, stepping, model, family = \
-		cpuinfo._parse_cpu_string("Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz")
-		self.assertEqual("Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz", processor_brand)
-		self.assertEqual('2.93', hz_actual)
-		self.assertEqual(9, scale)
-		self.assertEqual(None, vendor_id)
-		self.assertEqual(None, stepping)
-		self.assertEqual(None, model)
-		self.assertEqual(None, family)
-
-		processor_brand, hz_actual, scale, vendor_id, stepping, model, family = \
-		cpuinfo._parse_cpu_string("Intel(R) Pentium(R) CPU G640 @ 2.80GHz (2793.73-MHz K8-class CPU)")
-		self.assertEqual("Intel(R) Pentium(R) CPU G640 @ 2.80GHz", processor_brand)
-		self.assertEqual('2.8', hz_actual)
-		self.assertEqual(9, scale)
-		self.assertEqual(None, vendor_id)
-		self.assertEqual(None, stepping)
-		self.assertEqual(None, model)
-		self.assertEqual(None, family)
+	def test_to_decimal_string(self):
+		self.assertEqual('2.8', cpuinfo._to_decimal_string('2.80'))
+		self.assertEqual('2.0', cpuinfo._to_decimal_string('2'))
+		self.assertEqual('3.0', cpuinfo._to_decimal_string(3))
+		self.assertEqual('6.5', cpuinfo._to_decimal_string(6.5))
+		self.assertEqual('7.002', cpuinfo._to_decimal_string(7.002))
+		self.assertEqual('4.00000000001', cpuinfo._to_decimal_string('4.00000000001'))
+		self.assertEqual('5.0', cpuinfo._to_decimal_string('5.000000000000'))
+
+		self.assertEqual('0.0', cpuinfo._to_decimal_string('invalid'))
+		self.assertEqual('0.0', cpuinfo._to_decimal_string('8.778.9'))
+		self.assertEqual('0.0', cpuinfo._to_decimal_string(''))
+		self.assertEqual('0.0', cpuinfo._to_decimal_string(None))
+
+	def test_hz_short_to_full(self):
+		self.assertEqual((2800000000, 0), cpuinfo._hz_short_to_full('2.8', 9))
+		self.assertEqual((1200000, 0), cpuinfo._hz_short_to_full('1.2', 6))
+		self.assertEqual((3200000000, 0), cpuinfo._hz_short_to_full('3.2', 9))
+		self.assertEqual((9001200000, 0), cpuinfo._hz_short_to_full('9001.2', 6))
+		self.assertEqual((0, 0), cpuinfo._hz_short_to_full('0.0', 0))
+		self.assertEqual((2, 87), cpuinfo._hz_short_to_full('2.87', 0))
+
+		self.assertEqual((0, 0), cpuinfo._hz_short_to_full('invalid', 0))
+		self.assertEqual((0, 0), cpuinfo._hz_short_to_full('8.778.9', 0))
+		self.assertEqual((0, 0), cpuinfo._hz_short_to_full('', 0))
+		self.assertEqual((0, 0), cpuinfo._hz_short_to_full(None, 0))
+
+	def test_hz_friendly_to_full(self):
+		self.assertEqual((2800000000, 0), cpuinfo._hz_friendly_to_full('2.80GHz'))
+		self.assertEqual((1200000, 0), cpuinfo._hz_friendly_to_full('1.20 mHz'))
+		self.assertEqual((3693150000, 0), cpuinfo._hz_friendly_to_full('3693.15-MHz'))
+		self.assertEqual((12000000000, 0), cpuinfo._hz_friendly_to_full('12 GHz'))
+		self.assertEqual((2, 6), cpuinfo._hz_friendly_to_full('2.6 Hz'))
+		self.assertEqual((0, 0), cpuinfo._hz_friendly_to_full('0 Hz'))
+
+		self.assertEqual((0, 0), cpuinfo._hz_friendly_to_full('invalid'))
+		self.assertEqual((0, 0), cpuinfo._hz_friendly_to_full('8.778.9'))
+		self.assertEqual((0, 0), cpuinfo._hz_friendly_to_full(''))
+		self.assertEqual((0, 0), cpuinfo._hz_friendly_to_full(None))
+
+	def test_hz_short_to_friendly(self):
+		self.assertEqual('2.8000 GHz', cpuinfo._hz_short_to_friendly('2.8', 9))
+		self.assertEqual('1.2000 MHz', cpuinfo._hz_short_to_friendly('1.2', 6))
+		self.assertEqual('3.2000 GHz', cpuinfo._hz_short_to_friendly('3.2', 9))
+		self.assertEqual('1.3000 Hz', cpuinfo._hz_short_to_friendly('1.3', 0))
+		self.assertEqual('0.0000 Hz', cpuinfo._hz_short_to_friendly('0.0', 0))
+
+		self.assertEqual('0.0000 Hz', cpuinfo._hz_short_to_friendly('invalid', 0))
+		self.assertEqual('0.0000 Hz', cpuinfo._hz_short_to_friendly('8.778.9', 0))
+		self.assertEqual('0.0000 Hz', cpuinfo._hz_short_to_friendly('', 0))
+		self.assertEqual('0.0000 Hz', cpuinfo._hz_short_to_friendly(None, 0))
+
+	def test_parse_cpu_brand_string(self):
+		hz, scale = cpuinfo._parse_cpu_brand_string('Intel(R) Pentium(R) CPU G640 @ 2.80GHz')
+		self.assertEqual((hz, scale), ('2.8', 9))
+
+		hz, scale = cpuinfo._parse_cpu_brand_string('Intel(R) Pentium(R) CPU @ 1.20MHz')
+		self.assertEqual((hz, scale), ('1.2', 6))
 
 		# NOTE: No @ symbol
-		processor_brand, hz_actual, scale, vendor_id, stepping, model, family = \
-		cpuinfo._parse_cpu_string("Intel(R) Pentium(R) D CPU 3.20GHz")
-		self.assertEqual("Intel(R) Pentium(R) D CPU 3.20GHz", processor_brand)
-		self.assertEqual('3.2', hz_actual)
-		self.assertEqual(9, scale)
-		self.assertEqual(None, vendor_id)
-		self.assertEqual(None, stepping)
-		self.assertEqual(None, model)
-		self.assertEqual(None, family)
-
-	def test_to_friendly_hz(self):
-		scale, hz_brand = cpuinfo._get_hz_string_from_brand('Intel(R) Pentium(R) CPU G640 @ 2.80GHz')
-		self.assertEqual(9, scale)
-		self.assertEqual('2.8', hz_brand)
-		self.assertEqual('2.8000 GHz', cpuinfo._to_friendly_hz(hz_brand, scale))
-
-		scale, hz_brand = cpuinfo._get_hz_string_from_brand('Intel(R) Pentium(R) CPU @ 1.20MHz')
-		self.assertEqual(6, scale)
-		self.assertEqual('1.2', hz_brand)
-		self.assertEqual('1.2000 MHz', cpuinfo._to_friendly_hz(hz_brand, scale))
-
-		scale, hz_brand = cpuinfo._get_hz_string_from_brand('Intel(R) Pentium(R) D CPU 3.20GHz')
-		self.assertEqual(9, scale)
-		self.assertEqual('3.2', hz_brand)
-		self.assertEqual('3.2000 GHz', cpuinfo._to_friendly_hz(hz_brand, scale))
-
-	def test_to_raw_hz(self):
-		scale, hz_brand = cpuinfo._get_hz_string_from_brand('Intel(R) Pentium(R) CPU G640 @ 2.80GHz')
-		self.assertEqual(9, scale)
-		self.assertEqual('2.8', hz_brand)
-		self.assertEqual((2800000000, 0), cpuinfo._to_raw_hz(hz_brand, scale))
-
-		scale, hz_brand = cpuinfo._get_hz_string_from_brand('Intel(R) Pentium(R) CPU @ 1.20MHz')
-		self.assertEqual(6, scale)
-		self.assertEqual('1.2', hz_brand)
-		self.assertEqual((1200000, 0), cpuinfo._to_raw_hz(hz_brand, scale))
+		hz, scale = cpuinfo._parse_cpu_brand_string('Intel(R) Pentium(R) D CPU 3.20GHz')
+		self.assertEqual((hz, scale), ('3.2', 9))
+
+		# NOTE: No @ symbol and no Hz
+		hz, scale = cpuinfo._parse_cpu_brand_string('AMD Ryzen 7 2700X Eight-Core Processor')
+		self.assertEqual((hz, scale), ('0.0', 0))
+
+	def test_parse_cpu_brand_string_dx(self):
+		hz, scale, brand, vendor_id, stepping, model, family = \
+		cpuinfo._parse_cpu_brand_string_dx("Intel(R) Pentium(R) CPU G640 @ 2.80GHz (fam: 06, model: 2a, stepping: 07)")
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', brand)
+		self.assertEqual((hz, scale), ('2.8', 9))
+		self.assertEqual((vendor_id, stepping, model, family), (None, 7, 42, 6))
+
+		hz, scale, brand, vendor_id, stepping, model, family = \
+		cpuinfo._parse_cpu_brand_string_dx("Intel(R) Pentium(R) CPU G640 @ 2.80GHz (family: 0x6, model: 0x2a, stepping: 0x7)")
+		self.assertEqual('Intel(R) Pentium(R) CPU G640 @ 2.80GHz', brand)
+		self.assertEqual((hz, scale), ('2.8', 9))
+		self.assertEqual((vendor_id, stepping, model, family), (None, 7, 42, 6))
+
+		hz, scale, brand, vendor_id, stepping, model, family = \
+		cpuinfo._parse_cpu_brand_string_dx("Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz")
+		self.assertEqual("Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz", brand)
+		self.assertEqual((hz, scale), ('2.93', 9))
+		self.assertEqual((vendor_id, stepping, model, family), (None, None, None, None))
+
+		hz, scale, brand, vendor_id, stepping, model, family = \
+		cpuinfo._parse_cpu_brand_string_dx("Intel(R) Pentium(R) CPU G640 @ 2.80GHz (2793.73-MHz K8-class CPU)")
+		self.assertEqual("Intel(R) Pentium(R) CPU G640 @ 2.80GHz", brand)
+		self.assertEqual((hz, scale), ('2.8', 9))
+		self.assertEqual((vendor_id, stepping, model, family), (None, None, None, None))
 
 		# NOTE: No @ symbol
-		scale, hz_brand = cpuinfo._get_hz_string_from_brand('Intel(R) Pentium(R) D CPU 3.20GHz')
-		self.assertEqual(9, scale)
-		self.assertEqual('3.2', hz_brand)
-		self.assertEqual((3200000000, 0), cpuinfo._to_raw_hz(hz_brand, scale))
+		hz, scale, brand, vendor_id, stepping, model, family = \
+		cpuinfo._parse_cpu_brand_string_dx("Intel(R) Pentium(R) D CPU 3.20GHz")
+		self.assertEqual("Intel(R) Pentium(R) D CPU 3.20GHz", brand)
+		self.assertEqual((hz, scale), ('3.2', 9))
+		self.assertEqual((vendor_id, stepping, model, family), (None, None, None, None))
+
+		# NOTE: No @ symbol and no Hz
+		hz, scale, brand, vendor_id, stepping, model, family = \
+		cpuinfo._parse_cpu_brand_string_dx("AMD Ryzen 7 2700X Eight-Core Processor          (3693.15-MHz K8-class CPU) (fam: 06, model: 2a, stepping: 07)")
+		self.assertEqual("AMD Ryzen 7 2700X Eight-Core Processor", brand)
+		self.assertEqual((hz, scale), ('3693.15', 6))
+		self.assertEqual((vendor_id, stepping, model, family), (None, 7, 42, 6))
diff --git a/tests/test_parse_errors.py b/tests/test_parse_errors.py
index 0d24d02..6d88f81 100644
--- a/tests/test_parse_errors.py
+++ b/tests/test_parse_errors.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 1
 	is_windows = True
-	raw_arch_string = 'x86_64'
+	arch_string_raw = 'x86_64'
+	uname_string_raw = 'x86_64'
 	can_cpuid = False
 
 	@staticmethod
@@ -57,12 +58,8 @@ class MockDataSource(object):
 		return 0, ""
 
 	@staticmethod
-	def sestatus_allow_execheap():
-		return True
-
-	@staticmethod
-	def sestatus_allow_execmem():
-		return True
+	def sestatus_b():
+		return 0, ""
 
 	@staticmethod
 	def dmesg_a():
@@ -94,11 +91,11 @@ class MockDataSource(object):
 		return {}
 
 	@staticmethod
-	def winreg_vendor_id():
+	def winreg_vendor_id_raw():
 		return {}
 
 	@staticmethod
-	def winreg_raw_arch_string():
+	def winreg_arch_string_raw():
 		return {}
 
 	@staticmethod
diff --git a/tests/test_pcbsd_10_x86_64.py b/tests/test_pcbsd_10_x86_64.py
index 17653c6..50fa6ff 100644
--- a/tests/test_pcbsd_10_x86_64.py
+++ b/tests/test_pcbsd_10_x86_64.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 1
 	is_windows = False
-	raw_arch_string = 'amd64'
+	arch_string_raw = 'amd64'
+	uname_string_raw = 'x86_64'
 	can_cpuid = False
 
 	@staticmethod
@@ -19,7 +20,7 @@ class MockDataSource(object):
 	@staticmethod
 	def dmesg_a():
 		retcode = 0
-		output = '''Copyright (c) 1992-2014 The FreeBSD Project.
+		output = r'''Copyright (c) 1992-2014 The FreeBSD Project.
 Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
     The Regents of the University of California. All rights reserved.
 FreeBSD is a registered trademark of The FreeBSD Foundation.
@@ -62,16 +63,16 @@ class TestPCBSD(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(12, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(13, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_dmesg(self):
 		info = cpuinfo._get_cpu_info_from_dmesg()
 
-		self.assertEqual('Intel(R) Core(TM) i5-4440 CPU @ 3.10GHz', info['brand'])
-		self.assertEqual('3.1000 GHz', info['hz_advertised'])
-		self.assertEqual('3.1000 GHz', info['hz_actual'])
-		self.assertEqual((3100000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((3100000000, 0), info['hz_actual_raw'])
+		self.assertEqual('Intel(R) Core(TM) i5-4440 CPU @ 3.10GHz', info['brand_raw'])
+		self.assertEqual('3.1000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.1000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3100000000, 0), info['hz_advertised'])
+		self.assertEqual((3100000000, 0), info['hz_actual'])
 
 		self.assertEqual(
 			['apic', 'clflush', 'cmov', 'cx8', 'de', 'fpu', 'fxsr', 'lahf',
@@ -85,16 +86,16 @@ class TestPCBSD(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('Intel(R) Core(TM) i5-4440 CPU @ 3.10GHz', info['brand'])
-		self.assertEqual('3.1000 GHz', info['hz_advertised'])
-		self.assertEqual('3.1000 GHz', info['hz_actual'])
-		self.assertEqual((3100000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((3100000000, 0), info['hz_actual_raw'])
+		self.assertEqual('Intel(R) Core(TM) i5-4440 CPU @ 3.10GHz', info['brand_raw'])
+		self.assertEqual('3.1000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.1000 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3100000000, 0), info['hz_advertised'])
+		self.assertEqual((3100000000, 0), info['hz_actual'])
 		self.assertEqual('X86_64', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(1, info['count'])
 
-		self.assertEqual('amd64', info['raw_arch_string'])
+		self.assertEqual('amd64', info['arch_string_raw'])
 
 		self.assertEqual(
 			['apic', 'clflush', 'cmov', 'cx8', 'de', 'fpu', 'fxsr', 'lahf',
diff --git a/tests/test_selinux.py b/tests/test_selinux.py
new file mode 100644
index 0000000..d7654d3
--- /dev/null
+++ b/tests/test_selinux.py
@@ -0,0 +1,103 @@
+
+
+import unittest
+from cpuinfo import *
+import helpers
+
+
+class MockDataSource_enforcing(object):
+	@staticmethod
+	def has_sestatus():
+		return True
+
+	@staticmethod
+	def sestatus_b():
+		returncode = 0
+		output = r'''
+SELinux status:                 enabled
+SELinuxfs mount:                /sys/fs/selinux
+SELinux root directory:         /etc/selinux
+Loaded policy name:             targeted
+Current mode:                   enforcing
+Mode from config file:          enforcing
+Policy MLS status:              enabled
+Policy deny_unknown status:     allowed
+Memory protection checking:     actual (secure)
+Max kernel policy version:      31
+'''
+		return returncode, output
+
+class MockDataSource_not_enforcing(object):
+	@staticmethod
+	def has_sestatus():
+		return True
+
+	@staticmethod
+	def sestatus_b():
+		returncode = 0
+		output = r'''
+SELinux status:                 enabled
+SELinuxfs mount:                /sys/fs/selinux
+SELinux root directory:         /etc/selinux
+Loaded policy name:             targeted
+Current mode:                   eating
+Mode from config file:          enforcing
+Policy MLS status:              enabled
+Policy deny_unknown status:     allowed
+Memory protection checking:     actual (secure)
+Max kernel policy version:      31
+'''
+		return returncode, output
+
+class MockDataSource_exec_mem_and_heap(object):
+	@staticmethod
+	def has_sestatus():
+		return True
+
+	@staticmethod
+	def sestatus_b():
+		returncode = 0
+		output = r'''
+allow_execheap                  on
+allow_execmem                   on
+'''
+		return returncode, output
+
+class MockDataSource_no_exec_mem_and_heap(object):
+	@staticmethod
+	def has_sestatus():
+		return True
+
+	@staticmethod
+	def sestatus_b():
+		returncode = 0
+		output = r'''
+allow_execheap                  off
+allow_execmem                   off
+'''
+		return returncode, output
+
+
+class TestSELinux(unittest.TestCase):
+	def setUp(self):
+		helpers.backup_data_source(cpuinfo)
+		self.trace = Trace(False, False)
+
+	def tearDown(self):
+		helpers.restore_data_source(cpuinfo)
+
+	def test_enforcing(self):
+		helpers.monkey_patch_data_source(cpuinfo, MockDataSource_enforcing)
+		self.assertEqual(True, cpuinfo._is_selinux_enforcing(self.trace))
+
+	def test_not_enforcing(self):
+		helpers.monkey_patch_data_source(cpuinfo, MockDataSource_not_enforcing)
+		self.assertEqual(False, cpuinfo._is_selinux_enforcing(self.trace))
+
+	def test_exec_mem_and_heap(self):
+		helpers.monkey_patch_data_source(cpuinfo, MockDataSource_exec_mem_and_heap)
+		self.assertEqual(False, cpuinfo._is_selinux_enforcing(self.trace))
+
+	def test_no_exec_mem_and_heap(self):
+		helpers.monkey_patch_data_source(cpuinfo, MockDataSource_no_exec_mem_and_heap)
+		self.assertEqual(True, cpuinfo._is_selinux_enforcing(self.trace))
diff --git a/tests/test_solaris_11_x86_32.py b/tests/test_solaris_11_x86_32.py
index 2acc448..553ca59 100644
--- a/tests/test_solaris_11_x86_32.py
+++ b/tests/test_solaris_11_x86_32.py
@@ -9,7 +9,8 @@ class MockDataSource(object):
 	bits = '32bit'
 	cpu_count = 4
 	is_windows = False
-	raw_arch_string = 'i86pc'
+	arch_string_raw = 'i86pc'
+	uname_string_raw = 'x86_32'
 	can_cpuid = False
 
 	@staticmethod
@@ -23,7 +24,7 @@ class MockDataSource(object):
 	@staticmethod
 	def isainfo_vb():
 		returncode = 0
-		output = '''
+		output = r'''
 64-bit amd64 applications
 	ssse3 tscp ahf sse3 sse2 sse fxsr mmx cmov amd_sysc cx8 tsc fpu
 
@@ -33,7 +34,7 @@ class MockDataSource(object):
 	@staticmethod
 	def kstat_m_cpu_info():
 		returncode = 0
-		output = '''
+		output = r'''
 module: cpu_info                        instance: 0
 name:   cpu_info0                       class:    misc
 	brand                           Intel(r) Core(tm) i7 CPU         870  @ 2.93GHz
@@ -79,7 +80,7 @@ name:   cpu_info0                       class:    misc
 
 
 
-class TestSolaris(unittest.TestCase):
+class TestSolaris_11(unittest.TestCase):
 	def setUp(self):
 		helpers.backup_data_source(cpuinfo)
 		helpers.monkey_patch_data_source(cpuinfo, MockDataSource)
@@ -102,17 +103,17 @@ class TestSolaris(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(16, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(17, len(cpuinfo._get_cpu_info_internal()))
 
 	def test_get_cpu_info_from_kstat(self):
 		info = cpuinfo._get_cpu_info_from_kstat()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(r) Core(tm) i7 CPU         870  @ 2.93GHz', info['brand'])
-		self.assertEqual('2.9310 GHz', info['hz_advertised'])
-		self.assertEqual('2.9305 GHz', info['hz_actual'])
-		self.assertEqual((2931000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2930505167, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(r) Core(tm) i7 CPU         870  @ 2.93GHz', info['brand_raw'])
+		self.assertEqual('2.9310 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.9305 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2931000000, 0), info['hz_advertised'])
+		self.assertEqual((2930505167, 0), info['hz_actual'])
 
 		self.assertEqual(5, info['stepping'])
 		self.assertEqual(30, info['model'])
@@ -126,17 +127,17 @@ class TestSolaris(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(r) Core(tm) i7 CPU         870  @ 2.93GHz', info['brand'])
-		self.assertEqual('2.9310 GHz', info['hz_advertised'])
-		self.assertEqual('2.9305 GHz', info['hz_actual'])
-		self.assertEqual((2931000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2930505167, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(r) Core(tm) i7 CPU         870  @ 2.93GHz', info['brand_raw'])
+		self.assertEqual('2.9310 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.9305 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2931000000, 0), info['hz_advertised'])
+		self.assertEqual((2930505167, 0), info['hz_actual'])
 		self.assertEqual('X86_32', info['arch'])
 		self.assertEqual(32, info['bits'])
 		self.assertEqual(4, info['count'])
 
-		self.assertEqual('i86pc', info['raw_arch_string'])
+		self.assertEqual('i86pc', info['arch_string_raw'])
 
 		self.assertEqual(5, info['stepping'])
 		self.assertEqual(30, info['model'])
diff --git a/tests/test_true_os_18_x86_64_ryzen_7.py b/tests/test_true_os_18_x86_64_ryzen_7.py
new file mode 100644
index 0000000..adef138
--- /dev/null
+++ b/tests/test_true_os_18_x86_64_ryzen_7.py
@@ -0,0 +1,123 @@
+
+
+import unittest
+from cpuinfo import *
+import helpers
+
+
+class MockDataSource(object):
+	bits = '64bit'
+	cpu_count = 8
+	is_windows = False
+	arch_string_raw = 'amd64'
+	uname_string_raw = 'amd64'
+	can_cpuid = False
+
+	@staticmethod
+	def has_dmesg():
+		return True
+
+	@staticmethod
+	def dmesg_a():
+		retcode = 0
+		output = r'''Copyright (c) 1992-2018 The FreeBSD Project.
+Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
+	The Regents of the University of California. All rights reserved.
+FreeBSD is a registered trademark of The FreeBSD Foundation.
+FreeBSD 12.0-CURRENT #26 fa797a5a3(trueos-stable-18.03): Mon Mar 26 00:24:47 UTC 2018
+    root@chimera:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64
+FreeBSD clang version 6.0.0 (branches/release_60 324090) (based on LLVM 6.0.0)
+VT(vga): text 80x25
+CPU: AMD Ryzen 7 2700X Eight-Core Processor          (3693.15-MHz K8-class CPU)
+  Origin="AuthenticAMD"  Id=0x800f82  Family=0x17  Model=0x8  Stepping=2
+  Features=0x1783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2,HTT>
+  Features2=0x5ed82203<SSE3,PCLMULQDQ,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,AVX,RDRAND>
+  AMD Features=0x2a500800<SYSCALL,NX,MMX+,FFXSR,RDTSCP,LM>
+  AMD Features2=0x1f3<LAHF,CMP,CR8,ABM,SSE4A,MAS,Prefetch>
+  Structured Extended Features=0x40021<FSGSBASE,AVX2,RDSEED>
+  TSC: P-state invariant
+
+ '''
+		return retcode, output
+
+class TestTrueOS_18_X86_64_Ryzen7(unittest.TestCase):
+	def setUp(self):
+		helpers.backup_data_source(cpuinfo)
+		helpers.monkey_patch_data_source(cpuinfo, MockDataSource)
+
+	def tearDown(self):
+		helpers.restore_data_source(cpuinfo)
+
+	'''
+	Make sure calls return the expected number of fields.
+	'''
+	def test_returns(self):
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_registry()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpufreq_info()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_lscpu()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_proc_cpuinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysctl()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_kstat()))
+		self.assertEqual(10, len(cpuinfo._get_cpu_info_from_dmesg()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
+		self.assertEqual(17, len(cpuinfo._get_cpu_info_internal()))
+
+	def test_get_cpu_info_from_dmesg(self):
+		info = cpuinfo._get_cpu_info_from_dmesg()
+
+		self.assertEqual('AuthenticAMD', info['vendor_id_raw'])
+		self.assertEqual('AMD Ryzen 7 2700X Eight-Core Processor', info['brand_raw'])
+		self.assertEqual('3.6932 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.6932 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3693150000, 0), info['hz_advertised'])
+		self.assertEqual((3693150000, 0), info['hz_actual'])
+
+		self.assertEqual(2, info['stepping'])
+		self.assertEqual(8, info['model'])
+		self.assertEqual(23, info['family'])
+
+		self.assertEqual(
+			['abm', 'aesni', 'apic', 'avx', 'cmov', 'cmp', 'cr8', 'cx16',
+			'cx8', 'de', 'ffxsr', 'fpu', 'fxsr', 'htt', 'lahf', 'lm', 'mas',
+			'mca', 'mce', 'mmx', 'mmx+', 'movbe', 'msr', 'mtrr', 'nx',
+			'osxsave', 'pae', 'pat', 'pclmulqdq', 'pge', 'popcnt', 'prefetch',
+			'pse', 'pse36', 'rdrand', 'rdtscp', 'sep', 'sse', 'sse2', 'sse3',
+			'sse4.1', 'sse4.2', 'sse4a', 'ssse3', 'syscall', 'tsc', 'vme',
+			'xsave']
+			,
+			info['flags']
+		)
+
+	def test_all(self):
+		info = cpuinfo._get_cpu_info_internal()
+
+		self.assertEqual('AuthenticAMD', info['vendor_id_raw'])
+		self.assertEqual('AMD Ryzen 7 2700X Eight-Core Processor', info['brand_raw'])
+		self.assertEqual('3.6932 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.6932 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3693150000, 0), info['hz_advertised'])
+		self.assertEqual((3693150000, 0), info['hz_actual'])
+
+		self.assertEqual('X86_64', info['arch'])
+		self.assertEqual(64, info['bits'])
+		self.assertEqual(8, info['count'])
+		self.assertEqual('amd64', info['arch_string_raw'])
+
+		self.assertEqual(2, info['stepping'])
+		self.assertEqual(8, info['model'])
+		self.assertEqual(23, info['family'])
+
+		self.assertEqual(
+			['abm', 'aesni', 'apic', 'avx', 'cmov', 'cmp', 'cr8', 'cx16',
+			'cx8', 'de', 'ffxsr', 'fpu', 'fxsr', 'htt', 'lahf', 'lm', 'mas',
+			'mca', 'mce', 'mmx', 'mmx+', 'movbe', 'msr', 'mtrr', 'nx',
+			'osxsave', 'pae', 'pat', 'pclmulqdq', 'pge', 'popcnt', 'prefetch',
+			'pse', 'pse36', 'rdrand', 'rdtscp', 'sep', 'sse', 'sse2', 'sse3',
+			'sse4.1', 'sse4.2', 'sse4a', 'ssse3', 'syscall', 'tsc', 'vme',
+			'xsave']
+			,
+			info['flags']
+		)
diff --git a/tests/test_windows_10_x86_64.py b/tests/test_windows_10_x86_64.py
index 6f87e78..1d2d1ed 100644
--- a/tests/test_windows_10_x86_64.py
+++ b/tests/test_windows_10_x86_64.py
@@ -9,8 +9,9 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 4
 	is_windows = True
-	raw_arch_string = 'AMD64'
-	can_cpuid = False
+	arch_string_raw = 'AMD64'
+	uname_string_raw = 'Intel64 Family 6 Model 69 Stepping 1, GenuineIntel'
+	can_cpuid = True
 
 	@staticmethod
 	def has_wmic():
@@ -19,7 +20,7 @@ class MockDataSource(object):
 	@staticmethod
 	def wmic_cpu():
 		returncode = 0
-		output = '''
+		output = r'''
 Caption=Intel64 Family 6 Model 69 Stepping 1
 CurrentClockSpeed=2494
 Description=Intel64 Family 6 Model 69 Stepping 1
@@ -36,11 +37,11 @@ Name=Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz
 		return 'Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz'
 
 	@staticmethod
-	def winreg_vendor_id():
+	def winreg_vendor_id_raw():
 		return 'GenuineIntel'
 
 	@staticmethod
-	def winreg_raw_arch_string():
+	def winreg_arch_string_raw():
 		return 'AMD64'
 
 	@staticmethod
@@ -56,11 +57,34 @@ Name=Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz
 
 class TestWindows_10_X86_64(unittest.TestCase):
 	def setUp(self):
+		cpuinfo.CAN_CALL_CPUID_IN_SUBPROCESS = False
 		helpers.backup_data_source(cpuinfo)
 		helpers.monkey_patch_data_source(cpuinfo, MockDataSource)
 
+		helpers.backup_cpuid(cpuinfo)
+		helpers.monkey_patch_cpuid(cpuinfo, 2494000000, [
+			# max_extension_support
+			0x80000008,
+			# get_cache
+			0x1006040,
+			# get_info
+			0x40651,
+			# get_processor_brand
+			0x65746e49, 0x2952286c, 0x726f4320,
+			0x4d542865, 0x35692029, 0x3033342d,
+			0x43205530, 0x40205550, 0x392e3120,
+			0x7a484730, 0x0, 0x0,
+			# get_vendor_id
+			0x756e6547, 0x6c65746e, 0x49656e69,
+			# get_flags
+			0xbfebfbff, 0x7ffafbff, 0x27ab,
+			0x0, 0x0, 0x21,
+		])
+
 	def tearDown(self):
 		helpers.restore_data_source(cpuinfo)
+		helpers.restore_cpuid(cpuinfo)
+		cpuinfo.CAN_CALL_CPUID_IN_SUBPROCESS = True
 
 	'''
 	Make sure calls return the expected number of fields.
@@ -77,37 +101,75 @@ class TestWindows_10_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
-		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(18, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(13, len(cpuinfo._get_cpu_info_from_cpuid()))
+		self.assertEqual(3, len(cpuinfo._get_cpu_info_from_platform_uname()))
+		self.assertEqual(21, len(cpuinfo._get_cpu_info_internal()))
+
+	def test_get_cpu_info_from_cpuid(self):
+		info = cpuinfo._get_cpu_info_from_cpuid()
+
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz', info['brand_raw'])
+		#self.assertEqual('2.4940 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.4940 GHz', info['hz_actual_friendly'])
+		#self.assertEqual((2494000000, 0), info['hz_advertised'])
+		self.assertEqual((2494000000, 0), info['hz_actual'])
+
+		self.assertEqual(1, info['stepping'])
+		self.assertEqual(69, info['model'])
+		self.assertEqual(6, info['family'])
+
+		self.assertEqual(64 * 1024, info['l2_cache_size'])
+		self.assertEqual(256, info['l2_cache_line_size'])
+		self.assertEqual(6, info['l2_cache_associativity'])
+
+		self.assertEqual(
+			['abm', 'acpi', 'aes', 'apic', 'avx', 'avx2', 'bmi1', 'bmi2',
+			'clflush', 'cmov', 'cx16', 'cx8', 'de', 'ds_cpl', 'dtes64',
+			'dts', 'erms', 'est', 'f16c', 'fma', 'fpu', 'fxsr', 'ht',
+			'invpcid', 'lahf_lm', 'mca', 'mce', 'mmx', 'monitor', 'movbe',
+			'msr', 'mtrr', 'osxsave', 'pae', 'pat', 'pbe', 'pcid',
+			'pclmulqdq', 'pdcm', 'pge', 'pni', 'popcnt', 'pse', 'pse36',
+			'rdrnd', 'sep', 'smep', 'smx', 'ss', 'sse', 'sse2', 'sse4_1',
+			'sse4_2', 'ssse3', 'tm', 'tm2', 'tsc', 'tscdeadline', 'vme',
+			'vmx', 'x2apic', 'xsave', 'xtpr']
+			,
+			info['flags']
+		)
+
+	def test_get_cpu_info_from_platform_uname(self):
+		info = cpuinfo._get_cpu_info_from_platform_uname()
+
+		self.assertEqual(1, info['stepping'])
+		self.assertEqual(69, info['model'])
+		self.assertEqual(6, info['family'])
 
 	def test_get_cpu_info_from_wmic(self):
 		info = cpuinfo._get_cpu_info_from_wmic()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz', info['brand'])
-		self.assertEqual('1.9000 GHz', info['hz_advertised'])
-		self.assertEqual('2.4940 GHz', info['hz_actual'])
-		self.assertEqual((1900000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2494000000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz', info['brand_raw'])
+		self.assertEqual('1.9000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.4940 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1900000000, 0), info['hz_advertised'])
+		self.assertEqual((2494000000, 0), info['hz_actual'])
 
 		self.assertEqual(1, info['stepping'])
 		self.assertEqual(69, info['model'])
 		self.assertEqual(6, info['family'])
 
-		self.assertEqual('512 KB', info['l2_cache_size'])
-		self.assertEqual('3072 KB', info['l3_cache_size'])
+		self.assertEqual(512 * 1024, info['l2_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
 
 	def test_get_cpu_info_from_registry(self):
 		info = cpuinfo._get_cpu_info_from_registry()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz', info['brand'])
-		self.assertEqual('1.9000 GHz', info['hz_advertised'])
-		self.assertEqual('2.4940 GHz', info['hz_actual'])
-		self.assertEqual((1900000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2494000000, 0), info['hz_actual_raw'])
-
-		if "logger" in dir(unittest): unittest.logger("FIXME: Missing flags such as sse3 and sse4")
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz', info['brand_raw'])
+		self.assertEqual('1.9000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.4940 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1900000000, 0), info['hz_advertised'])
+		self.assertEqual((2494000000, 0), info['hz_actual'])
 
 		self.assertEqual(
 			['3dnow', 'acpi', 'clflush', 'cmov', 'de', 'dts', 'fxsr',
@@ -120,31 +182,37 @@ class TestWindows_10_X86_64(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz', info['brand'])
-		self.assertEqual('1.9000 GHz', info['hz_advertised'])
-		self.assertEqual('2.4940 GHz', info['hz_actual'])
-		self.assertEqual((1900000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2494000000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz', info['brand_raw'])
+		self.assertEqual('1.9000 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.4940 GHz', info['hz_actual_friendly'])
+		self.assertEqual((1900000000, 0), info['hz_advertised'])
+		self.assertEqual((2494000000, 0), info['hz_actual'])
 		self.assertEqual('X86_64', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(4, info['count'])
 
-		self.assertEqual('AMD64', info['raw_arch_string'])
+		self.assertEqual('AMD64', info['arch_string_raw'])
 
 		self.assertEqual(1, info['stepping'])
 		self.assertEqual(69, info['model'])
 		self.assertEqual(6, info['family'])
 
-		self.assertEqual('512 KB', info['l2_cache_size'])
-		self.assertEqual('3072 KB', info['l3_cache_size'])
-
-		if "logger" in dir(unittest): unittest.logger("FIXME: Missing flags such as sse3 and sse4")
+		self.assertEqual(512 * 1024, info['l2_cache_size'])
+		self.assertEqual(3072 * 1024, info['l3_cache_size'])
+		self.assertEqual(6, info['l2_cache_associativity'])
+		self.assertEqual(256, info['l2_cache_line_size'])
 
 		self.assertEqual(
-			['3dnow', 'acpi', 'clflush', 'cmov', 'de', 'dts', 'fxsr',
-			'ia64', 'mca', 'mce', 'mmx', 'msr', 'mtrr', 'pse', 'sep',
-			'serial', 'ss', 'sse', 'sse2', 'tm', 'tsc']
+			['3dnow', 'abm', 'acpi', 'aes', 'apic', 'avx', 'avx2', 'bmi1',
+			'bmi2', 'clflush', 'cmov', 'cx16', 'cx8', 'de', 'ds_cpl',
+			'dtes64', 'dts', 'erms', 'est', 'f16c', 'fma', 'fpu', 'fxsr',
+			'ht', 'ia64', 'invpcid', 'lahf_lm', 'mca', 'mce', 'mmx',
+			'monitor', 'movbe', 'msr', 'mtrr', 'osxsave', 'pae', 'pat',
+			'pbe', 'pcid', 'pclmulqdq', 'pdcm', 'pge', 'pni', 'popcnt',
+			'pse', 'pse36', 'rdrnd', 'sep', 'serial', 'smep', 'smx', 'ss',
+			'sse', 'sse2', 'sse4_1', 'sse4_2', 'ssse3', 'tm', 'tm2', 'tsc',
+			'tscdeadline', 'vme', 'vmx', 'x2apic', 'xsave', 'xtpr']
 			,
 			info['flags']
 		)
diff --git a/tests/test_windows_10_x86_64_ryzen_7.py b/tests/test_windows_10_x86_64_ryzen_7.py
new file mode 100644
index 0000000..f95db1c
--- /dev/null
+++ b/tests/test_windows_10_x86_64_ryzen_7.py
@@ -0,0 +1,185 @@
+
+
+import unittest
+from cpuinfo import *
+import helpers
+
+
+class MockDataSource(object):
+	bits = '64bit'
+	cpu_count = 16
+	is_windows = True
+	arch_string_raw = 'AMD64'
+	uname_string_raw = 'AMD64 Family 23 Model 8 Stepping 2, AuthenticAMD'
+	can_cpuid = True
+
+	@staticmethod
+	def winreg_processor_brand():
+		return 'AMD Ryzen 7 2700X Eight-Core Processor         '
+
+	@staticmethod
+	def winreg_vendor_id_raw():
+		return 'AuthenticAMD'
+
+	@staticmethod
+	def winreg_arch_string_raw():
+		return 'AMD64'
+
+	@staticmethod
+	def winreg_hz_actual():
+		return 3693
+
+	@staticmethod
+	def winreg_feature_bits():
+		return 1010515455
+
+
+
+
+class TestWindows_10_X86_64_Ryzen7(unittest.TestCase):
+	def setUp(self):
+		cpuinfo.CAN_CALL_CPUID_IN_SUBPROCESS = False
+		helpers.backup_data_source(cpuinfo)
+		helpers.monkey_patch_data_source(cpuinfo, MockDataSource)
+
+		helpers.backup_cpuid(cpuinfo)
+		helpers.monkey_patch_cpuid(cpuinfo, 3693000000, [
+			# get_max_extension_support
+			0x8000001f,
+			# get_cache
+			0x2006140,
+			# get_info
+			0x800f82,
+			# get_processor_brand
+			0x20444d41, 0x657a7952, 0x2037206e,
+			0x30303732, 0x69452058, 0x2d746867,
+			0x65726f43, 0x6f725020, 0x73736563,
+			0x2020726f, 0x20202020, 0x202020,
+			# get_vendor_id
+			0x68747541, 0x444d4163, 0x69746e65,
+			# get_flags
+			0x178bfbff, 0x7ed8320b, 0x209c01a9,
+			0x0, 0x20000000, 0x35c233ff,
+		])
+
+	def tearDown(self):
+		helpers.restore_data_source(cpuinfo)
+		helpers.restore_cpuid(cpuinfo)
+		cpuinfo.CAN_CALL_CPUID_IN_SUBPROCESS = True
+
+	'''
+	Make sure calls return the expected number of fields.
+	'''
+	def test_returns(self):
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_wmic()));
+		self.assertEqual(7, len(cpuinfo._get_cpu_info_from_registry()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpufreq_info()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_lscpu()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_proc_cpuinfo()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysctl()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_kstat()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_dmesg()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
+		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
+		self.assertEqual(11, len(cpuinfo._get_cpu_info_from_cpuid()))
+		self.assertEqual(3, len(cpuinfo._get_cpu_info_from_platform_uname()))
+		self.assertEqual(20, len(cpuinfo._get_cpu_info_internal()))
+
+
+	def test_get_cpu_info_from_cpuid(self):
+		info = cpuinfo._get_cpu_info_from_cpuid()
+
+		self.assertEqual('AuthenticAMD', info['vendor_id_raw'])
+		self.assertEqual('AMD Ryzen 7 2700X Eight-Core Processor', info['brand_raw'])
+		#self.assertEqual('3.6930 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.6930 GHz', info['hz_actual_friendly'])
+		#self.assertEqual((3693000000, 0), info['hz_advertised'])
+		self.assertEqual((3693000000, 0), info['hz_actual'])
+
+		self.assertEqual(2, info['stepping'])
+		self.assertEqual(8, info['model'])
+		self.assertEqual(23, info['family'])
+
+		self.assertEqual(64 * 1024, info['l2_cache_size'])
+		self.assertEqual(512, info['l2_cache_line_size'])
+		self.assertEqual(6, info['l2_cache_associativity'])
+
+		self.assertEqual(
+			['3dnowprefetch', 'abm', 'adx', 'aes', 'apic', 'avx', 'avx2',
+			'bmi1', 'bmi2', 'clflush', 'clflushopt', 'cmov', 'cmp_legacy',
+			'cr8_legacy', 'cx16', 'cx8', 'dbx', 'de', 'extapic', 'f16c',
+			'fma', 'fpu', 'fxsr', 'ht', 'lahf_lm', 'lm', 'mca', 'mce',
+			'misalignsse', 'mmx', 'monitor', 'movbe', 'msr', 'mtrr', 'osvw',
+			'osxsave', 'pae', 'pat', 'pci_l2i', 'pclmulqdq', 'perfctr_core',
+			'perfctr_nb', 'pge', 'pni', 'popcnt', 'pse', 'pse36', 'rdrnd',
+			'rdseed', 'sep', 'sha', 'skinit', 'smap', 'smep', 'sse', 'sse2',
+			'sse4_1', 'sse4_2', 'sse4a', 'ssse3', 'svm', 'tce', 'topoext',
+			'tsc', 'vme', 'wdt', 'xsave']
+			,
+			info['flags']
+		)
+
+	def test_get_cpu_info_from_platform_uname(self):
+		info = cpuinfo._get_cpu_info_from_platform_uname()
+
+		self.assertEqual(2, info['stepping'])
+		self.assertEqual(8, info['model'])
+		self.assertEqual(23, info['family'])
+
+	def test_get_cpu_info_from_registry(self):
+		info = cpuinfo._get_cpu_info_from_registry()
+
+		self.assertEqual('AuthenticAMD', info['vendor_id_raw'])
+		self.assertEqual('AMD Ryzen 7 2700X Eight-Core Processor', info['brand_raw'])
+		self.assertEqual('3.6930 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.6930 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3693000000, 0), info['hz_advertised'])
+		self.assertEqual((3693000000, 0), info['hz_actual'])
+
+		self.assertEqual(
+			['3dnow', 'clflush', 'cmov', 'de', 'dts', 'fxsr', 'ia64', 'mca',
+			'mmx', 'msr', 'mtrr', 'pse', 'sep', 'sepamd', 'serial', 'ss',
+			'sse', 'sse2', 'tm', 'tsc']
+			,
+			info['flags']
+		)
+
+	def test_all(self):
+		info = cpuinfo._get_cpu_info_internal()
+
+		self.assertEqual('AuthenticAMD', info['vendor_id_raw'])
+		self.assertEqual('AMD Ryzen 7 2700X Eight-Core Processor', info['brand_raw'])
+		self.assertEqual('3.6930 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('3.6930 GHz', info['hz_actual_friendly'])
+		self.assertEqual((3693000000, 0), info['hz_advertised'])
+		self.assertEqual((3693000000, 0), info['hz_actual'])
+		self.assertEqual('X86_64', info['arch'])
+		self.assertEqual(64, info['bits'])
+		self.assertEqual(16, info['count'])
+
+		self.assertEqual('AMD64', info['arch_string_raw'])
+
+		self.assertEqual(2, info['stepping'])
+		self.assertEqual(8, info['model'])
+		self.assertEqual(23, info['family'])
+
+		self.assertEqual(64 * 1024, info['l2_cache_size'])
+		self.assertEqual(6, info['l2_cache_associativity'])
+		self.assertEqual(512, info['l2_cache_line_size'])
+
+		self.assertEqual(
+			['3dnow', '3dnowprefetch', 'abm', 'adx', 'aes', 'apic', 'avx',
+			'avx2', 'bmi1', 'bmi2', 'clflush', 'clflushopt', 'cmov',
+			'cmp_legacy', 'cr8_legacy', 'cx16', 'cx8', 'dbx', 'de', 'dts',
+			'extapic', 'f16c', 'fma', 'fpu', 'fxsr', 'ht', 'ia64', 'lahf_lm',
+			'lm', 'mca', 'mce', 'misalignsse', 'mmx', 'monitor', 'movbe',
+			'msr', 'mtrr', 'osvw', 'osxsave', 'pae', 'pat', 'pci_l2i',
+			'pclmulqdq', 'perfctr_core', 'perfctr_nb', 'pge', 'pni',
+			'popcnt', 'pse', 'pse36', 'rdrnd', 'rdseed', 'sep', 'sepamd',
+			'serial', 'sha', 'skinit', 'smap', 'smep', 'ss', 'sse', 'sse2',
+			'sse4_1', 'sse4_2', 'sse4a', 'ssse3', 'svm', 'tce', 'tm',
+			'topoext', 'tsc', 'vme', 'wdt', 'xsave']
+			,
+			info['flags']
+		)
diff --git a/tests/test_windows_8_x86_64.py b/tests/test_windows_8_x86_64.py
index 5e2b284..3c55693 100644
--- a/tests/test_windows_8_x86_64.py
+++ b/tests/test_windows_8_x86_64.py
@@ -9,8 +9,9 @@ class MockDataSource(object):
 	bits = '64bit'
 	cpu_count = 4
 	is_windows = True
-	raw_arch_string = 'AMD64'
-	can_cpuid = False
+	arch_string_raw = 'AMD64'
+	uname_string_raw = 'AMD64 Family 6 Model 30 Stepping 5, GenuineIntel'
+	can_cpuid = True
 
 	@staticmethod
 	def has_wmic():
@@ -19,7 +20,7 @@ class MockDataSource(object):
 	@staticmethod
 	def wmic_cpu():
 		returncode = 0
-		output = '''
+		output = r'''
 Caption=Intel64 Family 6 Model 30 Stepping 5
 CurrentClockSpeed=2933
 Description=Intel64 Family 6 Model 30 Stepping 5
@@ -36,11 +37,11 @@ Name=Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz
 		return 'Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz'
 
 	@staticmethod
-	def winreg_vendor_id():
+	def winreg_vendor_id_raw():
 		return 'GenuineIntel'
 
 	@staticmethod
-	def winreg_raw_arch_string():
+	def winreg_arch_string_raw():
 		return 'AMD64'
 
 	@staticmethod
@@ -56,11 +57,34 @@ Name=Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz
 
 class TestWindows_8_X86_64(unittest.TestCase):
 	def setUp(self):
+		cpuinfo.CAN_CALL_CPUID_IN_SUBPROCESS = False
 		helpers.backup_data_source(cpuinfo)
 		helpers.monkey_patch_data_source(cpuinfo, MockDataSource)
 
+		helpers.backup_cpuid(cpuinfo)
+		helpers.monkey_patch_cpuid(cpuinfo, 2930000000, [
+			# max_extension_support
+			0x80000008,
+			# get_cache
+			0x1006040,
+			# get_info
+			0x106e5,
+			# get_processor_brand
+			0x65746e49, 0x2952286c, 0x726f4320,
+			0x4d542865, 0x37692029, 0x55504320,
+			0x20202020, 0x20202020, 0x30373820,
+			0x20402020, 0x33392e32, 0x7a4847,
+			# get_vendor_id
+			0x756e6547, 0x6c65746e, 0x49656e69,
+			# get_flags
+			0xbfebfbff, 0x98e3fd, 0x0,
+			0x0, 0x0, 0x1,
+		])
+
 	def tearDown(self):
 		helpers.restore_data_source(cpuinfo)
+		helpers.restore_cpuid(cpuinfo)
+		cpuinfo.CAN_CALL_CPUID_IN_SUBPROCESS = True
 
 	'''
 	Make sure calls return the expected number of fields.
@@ -77,37 +101,72 @@ class TestWindows_8_X86_64(unittest.TestCase):
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_ibm_pa_features()))
 		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_sysinfo()))
-		self.assertEqual(0, len(cpuinfo._get_cpu_info_from_cpuid()))
-		self.assertEqual(18, len(cpuinfo._get_cpu_info_internal()))
+		self.assertEqual(13, len(cpuinfo._get_cpu_info_from_cpuid()))
+		self.assertEqual(3, len(cpuinfo._get_cpu_info_from_platform_uname()))
+		self.assertEqual(21, len(cpuinfo._get_cpu_info_internal()))
+
+	def test_get_cpu_info_from_cpuid(self):
+		info = cpuinfo._get_cpu_info_from_cpuid()
+
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand_raw'])
+		#self.assertEqual('2.9300 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.9300 GHz', info['hz_actual_friendly'])
+		#self.assertEqual((2930000000, 0), info['hz_advertised'])
+		self.assertEqual((2930000000, 0), info['hz_actual'])
+
+		self.assertEqual(5, info['stepping'])
+		self.assertEqual(30, info['model'])
+		self.assertEqual(6, info['family'])
+
+		self.assertEqual(64 * 1024, info['l2_cache_size'])
+		self.assertEqual(256, info['l2_cache_line_size'])
+		self.assertEqual(6, info['l2_cache_associativity'])
+
+		self.assertEqual(
+			['acpi', 'apic', 'clflush', 'cmov', 'cx16', 'cx8', 'de', 'ds_cpl',
+			'dtes64', 'dts', 'est', 'fpu', 'fxsr', 'ht', 'lahf_lm', 'mca',
+			'mce', 'mmx', 'monitor', 'msr', 'mtrr', 'pae', 'pat', 'pbe',
+			'pdcm', 'pge', 'pni', 'popcnt', 'pse', 'pse36', 'sep', 'smx',
+			'ss', 'sse', 'sse2', 'sse4_1', 'sse4_2', 'ssse3', 'tm', 'tm2',
+			'tsc', 'vme', 'vmx', 'xtpr']
+			,
+			info['flags']
+		)
+
+	def test_get_cpu_info_from_platform_uname(self):
+		info = cpuinfo._get_cpu_info_from_platform_uname()
+
+		self.assertEqual(5, info['stepping'])
+		self.assertEqual(30, info['model'])
+		self.assertEqual(6, info['family'])
 
 	def test_get_cpu_info_from_wmic(self):
 		info = cpuinfo._get_cpu_info_from_wmic()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand'])
-		self.assertEqual('2.9300 GHz', info['hz_advertised'])
-		self.assertEqual('2.9330 GHz', info['hz_actual'])
-		self.assertEqual((2930000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2933000000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand_raw'])
+		self.assertEqual('2.9300 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.9330 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2930000000, 0), info['hz_advertised'])
+		self.assertEqual((2933000000, 0), info['hz_actual'])
 
 		self.assertEqual(5, info['stepping'])
 		self.assertEqual(30, info['model'])
 		self.assertEqual(6, info['family'])
 
-		self.assertEqual('256 KB', info['l2_cache_size'])
-		self.assertEqual('8192 KB', info['l3_cache_size'])
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
+		self.assertEqual(8192 * 1024, info['l3_cache_size'])
 
 	def test_get_cpu_info_from_registry(self):
 		info = cpuinfo._get_cpu_info_from_registry()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand'])
-		self.assertEqual('2.9300 GHz', info['hz_advertised'])
-		self.assertEqual('2.9330 GHz', info['hz_actual'])
-		self.assertEqual((2930000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2933000000, 0), info['hz_actual_raw'])
-
-		if "logger" in dir(unittest): unittest.logger("FIXME: Missing flags such as sse3 and sse4")
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand_raw'])
+		self.assertEqual('2.9300 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.9330 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2930000000, 0), info['hz_advertised'])
+		self.assertEqual((2933000000, 0), info['hz_actual'])
 
 		self.assertEqual(
 			['acpi', 'clflush', 'cmov', 'de', 'dts', 'fxsr', 'ia64',
@@ -120,31 +179,34 @@ class TestWindows_8_X86_64(unittest.TestCase):
 	def test_all(self):
 		info = cpuinfo._get_cpu_info_internal()
 
-		self.assertEqual('GenuineIntel', info['vendor_id'])
-		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand'])
-		self.assertEqual('2.9300 GHz', info['hz_advertised'])
-		self.assertEqual('2.9330 GHz', info['hz_actual'])
-		self.assertEqual((2930000000, 0), info['hz_advertised_raw'])
-		self.assertEqual((2933000000, 0), info['hz_actual_raw'])
+		self.assertEqual('GenuineIntel', info['vendor_id_raw'])
+		self.assertEqual('Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz', info['brand_raw'])
+		self.assertEqual('2.9300 GHz', info['hz_advertised_friendly'])
+		self.assertEqual('2.9330 GHz', info['hz_actual_friendly'])
+		self.assertEqual((2930000000, 0), info['hz_advertised'])
+		self.assertEqual((2933000000, 0), info['hz_actual'])
 		self.assertEqual('X86_64', info['arch'])
 		self.assertEqual(64, info['bits'])
 		self.assertEqual(4, info['count'])
 
-		self.assertEqual('AMD64', info['raw_arch_string'])
+		self.assertEqual('AMD64', info['arch_string_raw'])
 
 		self.assertEqual(5, info['stepping'])
 		self.assertEqual(30, info['model'])
 		self.assertEqual(6, info['family'])
 
-		self.assertEqual('256 KB', info['l2_cache_size'])
-		self.assertEqual('8192 KB', info['l3_cache_size'])
-
-		if "logger" in dir(unittest): unittest.logger("FIXME: Missing flags such as sse3 and sse4")
+		self.assertEqual(256 * 1024, info['l2_cache_size'])
+		self.assertEqual(8192 * 1024, info['l3_cache_size'])
+		self.assertEqual(6, info['l2_cache_associativity'])
+		self.assertEqual(256, info['l2_cache_line_size'])
 
 		self.assertEqual(
-			['acpi', 'clflush', 'cmov', 'de', 'dts', 'fxsr', 'ia64',
-			'mce', 'mmx', 'msr', 'mtrr', 'sep', 'serial', 'ss',
-			'sse', 'sse2', 'tm', 'tsc']
+			['acpi', 'apic', 'clflush', 'cmov', 'cx16', 'cx8', 'de', 'ds_cpl',
+			'dtes64', 'dts', 'est', 'fpu', 'fxsr', 'ht', 'ia64', 'lahf_lm',
+			'mca', 'mce', 'mmx', 'monitor', 'msr', 'mtrr', 'pae', 'pat',
+			'pbe', 'pdcm', 'pge', 'pni', 'popcnt', 'pse', 'pse36', 'sep',
+			'serial', 'smx', 'ss', 'sse', 'sse2', 'sse4_1', 'sse4_2', 'ssse3',
+			'tm', 'tm2', 'tsc', 'vme', 'vmx', 'xtpr']
 			,
 			info['flags']
 		)