1*d391177aSMatt Evans /* 2*d391177aSMatt Evans * PPC CPU identification 3*d391177aSMatt Evans * 4*d391177aSMatt Evans * This is a very simple "host CPU info" struct to get us going. 5*d391177aSMatt Evans * For the little host information we need, I don't want to grub about 6*d391177aSMatt Evans * parsing stuff in /proc/device-tree so just match host PVR to differentiate 7*d391177aSMatt Evans * PPC970 and POWER7 (which is all that's currently supported). 8*d391177aSMatt Evans * 9*d391177aSMatt Evans * Qemu does something similar but this is MUCH simpler! 10*d391177aSMatt Evans * 11*d391177aSMatt Evans * Copyright 2012 Matt Evans <matt@ozlabs.org>, IBM Corporation. 12*d391177aSMatt Evans * 13*d391177aSMatt Evans * This program is free software; you can redistribute it and/or modify it 14*d391177aSMatt Evans * under the terms of the GNU General Public License version 2 as published 15*d391177aSMatt Evans * by the Free Software Foundation. 16*d391177aSMatt Evans */ 17*d391177aSMatt Evans 18*d391177aSMatt Evans #include "cpu_info.h" 19*d391177aSMatt Evans #include "kvm/util.h" 20*d391177aSMatt Evans 21*d391177aSMatt Evans /* POWER7 */ 22*d391177aSMatt Evans 23*d391177aSMatt Evans /* 24*d391177aSMatt Evans * Basic set of pages for POWER7. It actually supports more but there were some 25*d391177aSMatt Evans * limitations as to which may be advertised to the guest. FIXME when this 26*d391177aSMatt Evans * settles down -- for now use basic set: 27*d391177aSMatt Evans */ 28*d391177aSMatt Evans static u32 power7_page_sizes_prop[] = {0xc, 0x0, 0x1, 0xc, 0x0, 0x18, 0x100, 0x1, 0x18, 0x0}; 29*d391177aSMatt Evans /* POWER7 has 1T segments, so advertise these */ 30*d391177aSMatt Evans static u32 power7_segment_sizes_prop[] = {0x1c, 0x28, 0xffffffff, 0xffffffff}; 31*d391177aSMatt Evans 32*d391177aSMatt Evans static struct cpu_info cpu_power7_info = { 33*d391177aSMatt Evans "POWER7", 34*d391177aSMatt Evans power7_page_sizes_prop, sizeof(power7_page_sizes_prop), 35*d391177aSMatt Evans power7_segment_sizes_prop, sizeof(power7_segment_sizes_prop), 36*d391177aSMatt Evans 32, /* SLB size */ 37*d391177aSMatt Evans 512000000, /* TB frequency */ 38*d391177aSMatt Evans 128, /* d-cache block size */ 39*d391177aSMatt Evans 128, /* i-cache block size */ 40*d391177aSMatt Evans CPUINFO_FLAG_DFP | CPUINFO_FLAG_VSX | CPUINFO_FLAG_VMX 41*d391177aSMatt Evans }; 42*d391177aSMatt Evans 43*d391177aSMatt Evans /* PPC970/G5 */ 44*d391177aSMatt Evans 45*d391177aSMatt Evans static u32 g5_page_sizes_prop[] = {0xc, 0x0, 0x1, 0xc, 0x0, 0x18, 0x100, 0x1, 0x18, 0x0}; 46*d391177aSMatt Evans 47*d391177aSMatt Evans static struct cpu_info cpu_970_info = { 48*d391177aSMatt Evans "G5", 49*d391177aSMatt Evans g5_page_sizes_prop, sizeof(g5_page_sizes_prop), 50*d391177aSMatt Evans 0 /* Null = no segment sizes prop, use defaults */, 0, 51*d391177aSMatt Evans 0, /* SLB size default */ 52*d391177aSMatt Evans 33333333, /* TB frequency */ 53*d391177aSMatt Evans 128, /* d-cache block size */ 54*d391177aSMatt Evans 128, /* i-cache block size */ 55*d391177aSMatt Evans CPUINFO_FLAG_VMX 56*d391177aSMatt Evans }; 57*d391177aSMatt Evans 58*d391177aSMatt Evans /* This is a default catchall for 'no match' on PVR: */ 59*d391177aSMatt Evans static struct cpu_info cpu_dummy_info = { "unknown", 0, 0, 0, 0, 0, 0, 0, 0 }; 60*d391177aSMatt Evans 61*d391177aSMatt Evans static struct pvr_info host_pvr_info[] = { 62*d391177aSMatt Evans { 0xffffffff, 0x0f000003, &cpu_power7_info }, 63*d391177aSMatt Evans { 0xffff0000, 0x003f0000, &cpu_power7_info }, 64*d391177aSMatt Evans { 0xffff0000, 0x004a0000, &cpu_power7_info }, 65*d391177aSMatt Evans { 0xffff0000, 0x00390000, &cpu_970_info }, 66*d391177aSMatt Evans { 0xffff0000, 0x003c0000, &cpu_970_info }, 67*d391177aSMatt Evans { 0xffff0000, 0x00440000, &cpu_970_info }, 68*d391177aSMatt Evans { 0xffff0000, 0x00450000, &cpu_970_info }, 69*d391177aSMatt Evans }; 70*d391177aSMatt Evans 71*d391177aSMatt Evans struct cpu_info *find_cpu_info(u32 pvr) 72*d391177aSMatt Evans { 73*d391177aSMatt Evans unsigned int i; 74*d391177aSMatt Evans for (i = 0; i < sizeof(host_pvr_info)/sizeof(struct pvr_info); i++) { 75*d391177aSMatt Evans if ((pvr & host_pvr_info[i].pvr_mask) == 76*d391177aSMatt Evans host_pvr_info[i].pvr) { 77*d391177aSMatt Evans return host_pvr_info[i].cpu_info; 78*d391177aSMatt Evans } 79*d391177aSMatt Evans } 80*d391177aSMatt Evans /* Didn't find anything? Rut-ro. */ 81*d391177aSMatt Evans pr_warning("Host CPU unsupported by kvmtool\n"); 82*d391177aSMatt Evans return &cpu_dummy_info; 83*d391177aSMatt Evans } 84