| ... | @@ -65,18 +65,91 @@ const SparcCpuinfoImpl = struct { | ... | @@ -65,18 +65,91 @@ const SparcCpuinfoImpl = struct { |
| 65 | const SparcCpuinfoParser = CpuinfoParser(SparcCpuinfoImpl); | 65 | const SparcCpuinfoParser = CpuinfoParser(SparcCpuinfoImpl); |
| 66 | | 66 | |
| 67 | test "cpuinfo: SPARC" { | 67 | test "cpuinfo: SPARC" { |
| 68 | const mock_cpuinfo = | 68 | try testParser(SparcCpuinfoParser, &Target.sparc.cpu.niagara2, |
| 69 | \\cpu : UltraSparc T2 (Niagara2) | 69 | \\cpu : UltraSparc T2 (Niagara2) |
| 70 | \\fpu : UltraSparc T2 integrated FPU | 70 | \\fpu : UltraSparc T2 integrated FPU |
| 71 | \\pmu : niagara2 | 71 | \\pmu : niagara2 |
| 72 | \\type : sun4v | 72 | \\type : sun4v |
| 73 | ; | 73 | ); |
| | 74 | } |
| | 75 | |
| | 76 | const PowerpcCpuinfoImpl = struct { |
| | 77 | model: ?*const Target.Cpu.Model = null, |
| | 78 | |
| | 79 | const cpu_names = .{ |
| | 80 | .{ "604e", &Target.powerpc.cpu.@"604e" }, |
| | 81 | .{ "604", &Target.powerpc.cpu.@"604" }, |
| | 82 | .{ "7400", &Target.powerpc.cpu.@"7400" }, |
| | 83 | .{ "7410", &Target.powerpc.cpu.@"7400" }, |
| | 84 | .{ "7447", &Target.powerpc.cpu.@"7400" }, |
| | 85 | .{ "7455", &Target.powerpc.cpu.@"7450" }, |
| | 86 | .{ "G4", &Target.powerpc.cpu.@"g4" }, |
| | 87 | .{ "POWER4", &Target.powerpc.cpu.@"970" }, |
| | 88 | .{ "PPC970FX", &Target.powerpc.cpu.@"970" }, |
| | 89 | .{ "PPC970MP", &Target.powerpc.cpu.@"970" }, |
| | 90 | .{ "G5", &Target.powerpc.cpu.@"g5" }, |
| | 91 | .{ "POWER5", &Target.powerpc.cpu.@"g5" }, |
| | 92 | .{ "A2", &Target.powerpc.cpu.@"a2" }, |
| | 93 | .{ "POWER6", &Target.powerpc.cpu.@"pwr6" }, |
| | 94 | .{ "POWER7", &Target.powerpc.cpu.@"pwr7" }, |
| | 95 | .{ "POWER8", &Target.powerpc.cpu.@"pwr8" }, |
| | 96 | .{ "POWER8E", &Target.powerpc.cpu.@"pwr8" }, |
| | 97 | .{ "POWER8NVL", &Target.powerpc.cpu.@"pwr8" }, |
| | 98 | .{ "POWER9", &Target.powerpc.cpu.@"pwr9" }, |
| | 99 | .{ "POWER10", &Target.powerpc.cpu.@"pwr10" }, |
| | 100 | }; |
| | 101 | |
| | 102 | fn line_hook(self: *PowerpcCpuinfoImpl, key: []const u8, value: []const u8) !bool { |
| | 103 | if (mem.eql(u8, key, "cpu")) { |
| | 104 | // The model name is often followed by a comma or space and extra |
| | 105 | // info. |
| | 106 | inline for (cpu_names) |pair| { |
| | 107 | const end_index = mem.indexOfAny(u8, value, ", ") orelse value.len; |
| | 108 | if (mem.eql(u8, value[0..end_index], pair[0])) { |
| | 109 | self.model = pair[1]; |
| | 110 | break; |
| | 111 | } |
| | 112 | } |
| | 113 | |
| | 114 | // Stop the detection once we've seen the first core. |
| | 115 | return false; |
| | 116 | } |
| | 117 | |
| | 118 | return true; |
| | 119 | } |
| | 120 | |
| | 121 | fn finalize(self: *const PowerpcCpuinfoImpl, arch: Target.Cpu.Arch) ?Target.Cpu { |
| | 122 | const model = self.model orelse Target.Cpu.Model.generic(arch); |
| | 123 | return Target.Cpu{ |
| | 124 | .arch = arch, |
| | 125 | .model = model, |
| | 126 | .features = model.features, |
| | 127 | }; |
| | 128 | } |
| | 129 | }; |
| 74 | | 130 | |
| 75 | var fbs = io.fixedBufferStream(mock_cpuinfo); | 131 | const PowerpcCpuinfoParser = CpuinfoParser(PowerpcCpuinfoImpl); |
| | 132 | |
| | 133 | test "cpuinfo: PowerPC" { |
| | 134 | try testParser(PowerpcCpuinfoParser, &Target.powerpc.cpu.@"970", |
| | 135 | \\processor	: 0 |
| | 136 | \\cpu		: PPC970MP, altivec supported |
| | 137 | \\clock		: 1250.000000MHz |
| | 138 | \\revision	: 1.1 (pvr 0044 0101) |
| | 139 | ); |
| | 140 | try testParser(PowerpcCpuinfoParser, &Target.powerpc.cpu.pwr8, |
| | 141 | \\processor	: 0 |
| | 142 | \\cpu		: POWER8 (raw), altivec supported |
| | 143 | \\clock		: 2926.000000MHz |
| | 144 | \\revision	: 2.0 (pvr 004d 0200) |
| | 145 | ); |
| | 146 | } |
| 76 | | 147 | |
| 77 | const r = SparcCpuinfoParser.parse(.sparcv9, fbs.reader()) catch unreachable; | 148 | fn testParser(parser: anytype, expected_model: *const Target.Cpu.Model, input: []const u8) !void { |
| 78 | testing.expectEqual(&Target.sparc.cpu.niagara2, r.?.model); | 149 | var fbs = io.fixedBufferStream(input); |
| 79 | testing.expect(Target.sparc.cpu.niagara2.features.eql(r.?.features)); | 150 | const result = try parser.parse(.powerpc, fbs.reader()); |
| | 151 | testing.expectEqual(expected_model, result.?.model); |
| | 152 | testing.expect(expected_model.features.eql(result.?.features)); |
| 80 | } | 153 | } |
| 81 | | 154 | |
| 82 | // The generic implementation of a /proc/cpuinfo parser. | 155 | // The generic implementation of a /proc/cpuinfo parser. |
| ... | @@ -111,8 +184,14 @@ pub fn detectNativeCpuAndFeatures() ?Target.Cpu { | ... | @@ -111,8 +184,14 @@ pub fn detectNativeCpuAndFeatures() ?Target.Cpu { |
| 111 | }; | 184 | }; |
| 112 | defer f.close(); | 185 | defer f.close(); |
| 113 | | 186 | |
| 114 | switch (std.Target.current.cpu.arch) { | 187 | const current_arch = std.Target.current.cpu.arch; |
| 115 | .sparcv9 => return SparcCpuinfoParser.parse(.sparcv9, f.reader()) catch null, | 188 | switch (current_arch) { |
| | 189 | .sparcv9 => { |
| | 190 | return SparcCpuinfoParser.parse(current_arch, f.reader()) catch null; |
| | 191 | }, |
| | 192 | .powerpc, .powerpcle, .powerpc64, .powerpc64le => { |
| | 193 | return PowerpcCpuinfoParser.parse(current_arch, f.reader()) catch null; |
| | 194 | }, |
| 116 | else => {}, | 195 | else => {}, |
| 117 | } | 196 | } |
| 118 | | 197 | |