diff --git a/ccan/cpuid/cpuid.c b/ccan/cpuid/cpuid.c
index 153f52d4a4ad513b7898095f880d2777d44d9b5e..57883e2bd0982b17fccdeaf34fd5da945c1134ea 100644
--- a/ccan/cpuid/cpuid.c
+++ b/ccan/cpuid/cpuid.c
@@ -92,6 +92,8 @@ static struct {
 
 bool cpuid_is_supported(void)
 {
+	int ret = 0;
+#if defined(__GNUC__) || defined(__clang__)
 	/* The following assembly code uses EAX as the return value,
 	 * but we store the value of EAX into ret since GCC uses EAX
 	 * as the return register for every C function.  That's a double
@@ -115,16 +117,15 @@ bool cpuid_is_supported(void)
 #define ASM_POPF	"popfq\n\t"
 #define ASM_PUSHEAX 	"pushq %%rax\n\t"
 #define ASM_POPEAX 	"popq %%rax\n\t"
-#define ASM_PUSHECX 	"popq %%rcx\n\t"
+#define ASM_PUSHECX 	"pushq %%rcx\n\t"
 #elif UINTPTR_MAX == 0xffffffff
 #define ASM_PUSHF 	"pushfl\n\t"
 #define ASM_POPF	"popfl\n\t"
 #define ASM_PUSHEAX 	"pushl %%eax\n\t"
 #define ASM_POPEAX 	"popl %%eax\n\t"
-#define ASM_PUSHECX 	"popl %%ecx\n\t"
+#define ASM_PUSHECX 	"pushl %%ecx\n\t"
 #endif
 
-	int ret = 0;
 	asm volatile(
 		ASM_PUSHF
 		ASM_POPEAX
@@ -147,7 +148,26 @@ bool cpuid_is_supported(void)
 #undef ASM_PUSHEAX
 #undef ASM_POPEAX
 #undef ASM_PUSHECX
-
+#elif defined _MSC_VER
+	__asm {
+		pushfd
+		pop eax
+		mov ecx, eax
+		xor eax, 0x200000
+		push eax
+		popfd
+
+		pushfd
+		pop eax
+		xor eax, ecx
+		shr eax, 0x21
+		and eax, 0x1
+		push ecx
+		popfd
+
+		mov eax, ret
+	};
+#endif
 	return !!ret;
 }
 
@@ -220,9 +240,14 @@ cputype_t cpuid_get_cpu_type(void)
 	return cputype;
 }
 
-const char *cpuid_get_cpu_type_string(const cputype_t cputype)
+bool cpuid_sprintf_cputype(const cputype_t cputype, char *buf)
 {
-	return cpuids[(int)cputype];
+	if (cputype == CT_NONE)
+		return false;
+
+	memcpy(buf, cpuids[(int)cputype], 12);
+	buf[12] = '\0';
+	return true;
 }
 
 uint32_t cpuid_highest_ext_func_supported(void)
@@ -230,11 +255,19 @@ uint32_t cpuid_highest_ext_func_supported(void)
 	static uint32_t highest;
 
 	if (!highest) {
+#if defined(__GNUC__) || defined(__clang__)
 		asm volatile(
 			"cpuid\n\t"
 			: "=a" (highest)
 			: "a" (CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED)
 		);
+#elif defined _MSC_VER
+		__asm {
+			mov eax, CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
+			cpuid
+			mov highest, eax
+		};
+#endif
 	}
 
 	return highest;
@@ -298,13 +331,16 @@ void cpuid(cpuid_t info, uint32_t *buf)
 			buf[3] = edx;
 			break;
 		case CPU_EXTENDED_L2_CACHE_FEATURES:
-			*buf = ecx;
+			buf[0] = ecx & 0xFF; 		/* Line size.  */
+			buf[1] = (ecx >> 12) & 0xFF; 	/* Associativity.  */
+			buf[2] = ecx >> 16; 		/* Cache size.  */
 			break;
 		case CPU_ADV_POWER_MGT_INFO:
 			*buf = edx;
 			break;
 		case CPU_VIRT_PHYS_ADDR_SIZES:
-			*buf = eax;
+			buf[0] = eax & 0xFF; 		/* physical.  */
+			buf[1] = (eax >> 8) & 0xFF; 	/* virtual.  */
 			break;
 		default:
 			*buf = 0xbaadf00d;
diff --git a/ccan/cpuid/cpuid.h b/ccan/cpuid/cpuid.h
index 0a9fc9d91ac84bb1d98cc27e80bb1b5ae5a914da..7bf903a6db397af69c454cd20eab3a061d1b084a 100644
--- a/ccan/cpuid/cpuid.h
+++ b/ccan/cpuid/cpuid.h
@@ -26,7 +26,7 @@
 #include <stdint.h>
 
 /**
- * enum cpuid - stuff to get information on from the CPU.
+ * enum cpuid - stuff to get information about from the CPU.
  *
  * This is used as a parameter in cpuid().
  *
@@ -124,14 +124,17 @@ typedef enum cputype {
  *
  * See also: cpuid_get_cpu_type_string()
  */
+#define is_intel_cpu() 	cpuid_get_cpu_type() == CT_INTEL
+#define is_amd_cpu() 	cpuid_get_cpu_type() == CT_AMDK5 || cpuid_get_cpu_type() == CT_AMD
 cputype_t cpuid_get_cpu_type(void);
 
 /**
- * cpuid_get_cpu_type_string - Get CPU Type string
+ * cpuid_sprintf_cputype - Get CPU Type string
+ * @cputype: a char of atleast 12 bytes in it.
  *
- * Returns the CPU type string based off cputype_t.
+ * Returns true on success, false on failure
  */
-const char *cpuid_get_cpu_type_string(const cputype_t cputype);
+bool cpuid_sprintf_cputype(const cputype_t cputype, char *buf);
 
 /**
  * cpuid_is_supported - test if the CPUID instruction is supported
@@ -205,8 +208,14 @@ uint32_t cpuid_highest_ext_func_supported(void);
  * For CPU_EXTENDED_PROC_INFO_FEATURE_BITS:
  * 	Returns them in buf[0] and buf[1].
  *
+ * For CPU_EXTENDED_L2_CACHE_FEATURES:
+ * 	buf[0]: Line size
+ * 	buf[1]: Associativity
+ * 	buf[2]: Cache size.
+ *
  * For CPU_VIRT_PHYS_ADDR_SIZES:
- * 	Returns it as an integer in *buf.
+ * 	buf[0]: Physical
+ * 	buf[1]: Virtual
  *
  * For CPU_PROC_BRAND_STRING:
  * 	Have a char array with at least 48 bytes assigned to it.
@@ -269,4 +278,3 @@ bool cpuid_has_feature(int feature, bool extended);
 
 #endif
 #endif
-
diff --git a/ccan/cpuid/test/run.c b/ccan/cpuid/test/run.c
index 85b1497043727f584762d671cafe830329ab65fa..843389fa2a7733178b4399bfb6d6fe3e2c07dd5d 100644
--- a/ccan/cpuid/test/run.c
+++ b/ccan/cpuid/test/run.c
@@ -10,7 +10,9 @@ int main(void)
 		return 1;
 	}
 
-	printf ("Vendor ID: %s\n", cpuid_get_cpu_type_string (cpuid_get_cpu_type ()));
+	char cputype[12];
+	if (cpuid_sprintf_cputype(cpuid_get_cpu_type(), cputype))
+		printf ("Vendor ID: %s\n", cputype);
 
 	char buf[48];
 	cpuid(CPU_PROC_BRAND_STRING, (uint32_t *)buf);
@@ -18,39 +20,21 @@ int main(void)
 
 	printf ("Highest extended function supported: %#010x\n", cpuid_highest_ext_func_supported());
 
-	union {
-		struct {
-			uint32_t phys_bits : 8;
-			uint32_t virt_bits : 8;
-			uint32_t reserved  : 16;
-		};
-		uint32_t w;
-	} s;
-	cpuid(CPU_VIRT_PHYS_ADDR_SIZES, &s.w);
-	printf ("Physical address size: %d\nVirtual address size: %d\n", s.phys_bits, s.virt_bits);
+	uint32_t phys_virt[2];
+	cpuid(CPU_VIRT_PHYS_ADDR_SIZES, phys_virt);
+	printf ("Physical address size: %d\nVirtual address size: %d\n", phys_virt[0], phys_virt[1]);
 
 	uint32_t extfeatures[2];
 	cpuid(CPU_EXTENDED_PROC_INFO_FEATURE_BITS, extfeatures);
 	printf ("Extended processor info and feature bits: %d %d\n", extfeatures[0], extfeatures[1]);
 
-	union {
-		struct {
-			uint32_t line_size : 8;
-			uint32_t reserved : 4;
-			uint32_t assoc : 4;
-			uint32_t cache_size : 16;
-		};
-
-		uint32_t w;
-	} l2c;
-
-	cpuid(CPU_EXTENDED_L2_CACHE_FEATURES, &l2c.w);
-	printf ("L2 Cache Size: %u KB\tLine Size: %u bytes\tAssociativity: %02xh\n",
-			l2c.cache_size, l2c.line_size, l2c.assoc);
+	uint32_t l2c[3];
+	cpuid(CPU_EXTENDED_L2_CACHE_FEATURES, l2c);
+	printf("L2 Line size: %u bytes\tAssociativity: %02xh\tCache Size: %u KB\n",
+		l2c[0], l2c[1], l2c[2]);
 
 	uint32_t invalid;
 	cpuid(0x0ffffffUL, &invalid);
 	printf ("Testing invalid: %#010x\n", invalid);
 	return 0;
 }
-