Index: arch/ia64/include/cpu.h
===================================================================
--- arch/ia64/include/cpu.h	(revision 59e07c91fccb189beb5623b72a240b638917ebb2)
+++ arch/ia64/include/cpu.h	(revision 0172ebaa7b25d1de67dbebe413b28e7ad722e43f)
@@ -30,8 +30,31 @@
 #define __ia64_CPU_H__
 
+#include <arch/types.h>
 #include <typedefs.h>
+#include <arch/register.h>
+
+#define FAMILY_ITANIUM	0x7
+#define FAMILY_ITANIUM2	0x1f
 
 struct cpu_arch {
+	__u64 cpuid0;
+	__u64 cpuid1;
+	cpuid3_t cpuid3;
 };
+
+/** Read CPUID register.
+ *
+ * @param n CPUID register number.
+ *
+ * @return Value of CPUID[n] register.
+ */
+static inline __u64 cpuid_read(int n)
+{
+	__u64 v;
 	
+	__asm__ volatile ("mov %0 = cpuid[%1]\n" : "=r" (v) : "r" (n));
+	
+	return v;
+}
+
 #endif
Index: arch/ia64/include/register.h
===================================================================
--- arch/ia64/include/register.h	(revision 59e07c91fccb189beb5623b72a240b638917ebb2)
+++ arch/ia64/include/register.h	(revision 0172ebaa7b25d1de67dbebe413b28e7ad722e43f)
@@ -179,4 +179,18 @@
 typedef union cr_isr cr_isr_t;
 
+/** CPUID Register 3 */
+union cpuid3 {
+	struct {
+		__u8 number;
+		__u8 revision;
+		__u8 model;
+		__u8 family;
+		__u8 archrev;
+	} __attribute__ ((packed));
+	__u64 value;
+};
+
+typedef union cpuid3 cpuid3_t;
+
 #endif /* !__ASM__ */
 
Index: arch/ia64/src/cpu/cpu.c
===================================================================
--- arch/ia64/src/cpu/cpu.c	(revision 59e07c91fccb189beb5623b72a240b638917ebb2)
+++ arch/ia64/src/cpu/cpu.c	(revision 0172ebaa7b25d1de67dbebe413b28e7ad722e43f)
@@ -28,4 +28,7 @@
 
 #include <cpu.h>
+#include <arch.h>
+#include <arch/register.h>
+#include <print.h>
 
 void cpu_arch_init(void)
@@ -33,3 +36,32 @@
 }
 
+void cpu_identify(void)
+{
+	CPU->arch.cpuid0 = cpuid_read(0);
+	CPU->arch.cpuid1 = cpuid_read(1);
+	CPU->arch.cpuid3.value = cpuid_read(3);
+}
 
+void cpu_print_report(cpu_t *m)
+{
+	char *family_str;
+	char vendor[2*sizeof(__u64)+1];
+	
+	*((__u64 *) &vendor[0*sizeof(__u64)]) = CPU->arch.cpuid0;
+	*((__u64 *) &vendor[1*sizeof(__u64)]) = CPU->arch.cpuid1;
+	vendor[sizeof(vendor)-1] = '\0';
+	
+	switch(m->arch.cpuid3.family) {
+	    case FAMILY_ITANIUM:
+	    	family_str = "Itanium";
+		break;
+	    case FAMILY_ITANIUM2:
+	    	family_str = "Itanium 2";
+		break;
+	    default:
+	    	family_str = "Unknown";
+		break;
+	}
+	
+	printf("cpu%d: %s (%s), archrev=%d, model=%d, revision=%d\n", CPU->id, family_str, vendor, CPU->arch.cpuid3.archrev, CPU->arch.cpuid3.model, CPU->arch.cpuid3.revision);
+}
Index: arch/ia64/src/dummy.s
===================================================================
--- arch/ia64/src/dummy.s	(revision 59e07c91fccb189beb5623b72a240b638917ebb2)
+++ arch/ia64/src/dummy.s	(revision 0172ebaa7b25d1de67dbebe413b28e7ad722e43f)
@@ -34,6 +34,4 @@
 .global before_thread_runs_arch
 .global arch_late_init
-.global cpu_identify
-.global cpu_print_report
 .global cpu_sleep
 .global dummy
@@ -47,6 +45,4 @@
 asm_delay_loop:
 arch_late_init:
-cpu_identify:
-cpu_print_report:
 cpu_sleep:
 fpu_init:
