mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-18 02:40:08 +00:00
parent
8cdc266417
commit
237f6a6a62
@ -135,6 +135,13 @@ namespace Nova {
|
||||
uint8_t thread;
|
||||
uint8_t core;
|
||||
uint8_t package;
|
||||
uint8_t acpi_id;
|
||||
uint8_t family;
|
||||
uint8_t model;
|
||||
uint8_t stepping:4;
|
||||
uint8_t platform:3;
|
||||
uint8_t reserved:1;
|
||||
uint32_t patch;
|
||||
} __attribute__((packed));
|
||||
|
||||
unsigned cpu_max() const {
|
||||
|
@ -1 +1 @@
|
||||
79dfa0facd434fa14cc92d48d0474118e718139b
|
||||
96a3ed33cf48798847b43f6023ae92a002224875
|
||||
|
@ -2,9 +2,9 @@ LICENSE := GPLv2
|
||||
VERSION := git
|
||||
DOWNLOADS := nova.git
|
||||
|
||||
# r9 branch - use r9_debug for more verbose kernel messages
|
||||
# r10 branch
|
||||
URL(nova) := https://github.com/alex-ab/NOVA.git
|
||||
REV(nova) := 720fd5033a830d9425dbb33d8ced86d01353881b
|
||||
REV(nova) := b44329a8601ff3936aa77336752d85cff95f1a94
|
||||
DIR(nova) := src/kernel/nova
|
||||
|
||||
PATCHES := $(sort $(wildcard $(REP_DIR)/patches/*.patch))
|
||||
|
@ -283,7 +283,7 @@ Platform::Platform() :
|
||||
{
|
||||
Hip *hip = (Hip *)__initial_sp;
|
||||
/* check for right API version */
|
||||
if (hip->api_version != 7)
|
||||
if (hip->api_version != 8)
|
||||
nova_die();
|
||||
|
||||
/*
|
||||
@ -700,6 +700,23 @@ Platform::Platform() :
|
||||
xml.attribute("invariant", cpuid_invariant_tsc());
|
||||
xml.attribute("freq_khz" , hip->tsc_freq);
|
||||
});
|
||||
xml.node("cpus", [&] () {
|
||||
unsigned const cpus = hip->cpus();
|
||||
for (unsigned i = 0; i < cpus; i++) {
|
||||
xml.node("cpu", [&] () {
|
||||
unsigned const kernel_cpu_id = Platform::kernel_cpu_id(i);
|
||||
xml.attribute("id", i);
|
||||
xml.attribute("package", hip->cpu_desc_of_cpu(kernel_cpu_id)->package);
|
||||
xml.attribute("core", hip->cpu_desc_of_cpu(kernel_cpu_id)->core);
|
||||
xml.attribute("thread", hip->cpu_desc_of_cpu(kernel_cpu_id)->thread);
|
||||
xml.attribute("family", String<5>(Hex(hip->cpu_desc_of_cpu(kernel_cpu_id)->family)));
|
||||
xml.attribute("model", String<5>(Hex(hip->cpu_desc_of_cpu(kernel_cpu_id)->model)));
|
||||
xml.attribute("stepping", String<5>(Hex(hip->cpu_desc_of_cpu(kernel_cpu_id)->stepping)));
|
||||
xml.attribute("platform", String<5>(Hex(hip->cpu_desc_of_cpu(kernel_cpu_id)->platform)));
|
||||
xml.attribute("patch", String<12>(Hex(hip->cpu_desc_of_cpu(kernel_cpu_id)->patch)));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
76
repos/ports/run/microcode.run
Normal file
76
repos/ports/run/microcode.run
Normal file
@ -0,0 +1,76 @@
|
||||
assert_spec x86
|
||||
|
||||
if { [get_cmd_switch --autopilot] } {
|
||||
|
||||
if {[have_include "power_on/qemu"]} {
|
||||
puts "\nRun script does not support Qemu.\n"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# platform_info data about CPUs on other kernels missing
|
||||
assert_spec nova
|
||||
}
|
||||
|
||||
build "core init test/microcode"
|
||||
|
||||
create_boot_directory
|
||||
|
||||
install_config {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="LOG"/>
|
||||
<service name="PD"/>
|
||||
<service name="CPU"/>
|
||||
<service name="ROM"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> </any-service>
|
||||
</default-route>
|
||||
<default caps="50"/>
|
||||
<start name="test-microcode">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
set ::env(MAKEFLAGS) s
|
||||
set path_microcode [exec [genode_dir]/tool/ports/current microcode_intel]
|
||||
set microcode_files [glob -dir $path_microcode/src/app/intel *-*-*]
|
||||
|
||||
file copy -force {*}$microcode_files bin/
|
||||
|
||||
|
||||
set boot_modules { core ld.lib.so init test-microcode }
|
||||
|
||||
|
||||
set microcode_files [glob -tails -dir bin {[0-9,a-f][0-9,a-f]-[0-9,a-f][0-9,a-f]-[0-9,a-f][0-9,a-f]}]
|
||||
append boot_modules $microcode_files
|
||||
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
|
||||
append qemu_args "-nographic "
|
||||
append qemu_args "-smp 4 "
|
||||
|
||||
run_genode_until "microcode check done" 30
|
||||
|
||||
# cleanup
|
||||
if { [get_cmd_switch --autopilot] } {
|
||||
foreach file $microcode_files {
|
||||
file delete bin/$file
|
||||
}
|
||||
}
|
||||
|
||||
# check results
|
||||
grep_output {\[init -\> test-microcode}
|
||||
|
||||
# no errors please
|
||||
set filtered_output $output
|
||||
grep_output {Error: }
|
||||
compare_output_to {}
|
||||
|
||||
# no warnings please
|
||||
set output $filtered_output
|
||||
grep_output {Warning: }
|
||||
compare_output_to {}
|
165
repos/ports/src/test/microcode/main.cc
Normal file
165
repos/ports/src/test/microcode/main.cc
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* \brief Testing microcode status
|
||||
* \author Alexander Boetcher
|
||||
* \date 2018-08-01
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#include <base/component.h>
|
||||
#include <base/log.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
|
||||
#include <util/mmio.h>
|
||||
|
||||
using Genode::uint8_t;
|
||||
|
||||
struct Microcode : Genode::Mmio
|
||||
{
|
||||
struct Version : Register< 0, 32> { };
|
||||
struct Revision : Register< 4, 32> { };
|
||||
struct Date : Register< 8, 32> {
|
||||
struct Year : Bitfield< 0, 16> { };
|
||||
struct Day : Bitfield<16, 8> { };
|
||||
struct Month : Bitfield<24, 8> { };
|
||||
};
|
||||
struct Cpuid : Register<12, 32> {
|
||||
struct Stepping : Bitfield< 0, 4> { };
|
||||
struct Model : Bitfield< 4, 4> { };
|
||||
struct Family : Bitfield< 8, 4> { };
|
||||
struct Type : Bitfield< 12, 2> { };
|
||||
struct Model_ext : Bitfield< 16, 4> { };
|
||||
struct Family_ext : Bitfield< 20, 8> { };
|
||||
};
|
||||
struct Processor_flags : Register<24, 32> {
|
||||
struct Flags : Bitfield< 0, 8> { };
|
||||
};
|
||||
struct Datasize : Register<28, 32> { };
|
||||
struct Totalsize : Register<32, 32> { };
|
||||
|
||||
Microcode(Genode::addr_t const addr) : Mmio(addr) { }
|
||||
};
|
||||
|
||||
static void read_micro_code_rom(Genode::Env &env, Genode::String<9> &rom_name,
|
||||
unsigned const id, uint8_t const family,
|
||||
uint8_t const model, uint8_t const stepping,
|
||||
uint8_t const platform, unsigned const patch)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
try {
|
||||
Attached_rom_dataspace mc_rom(env, rom_name.string());
|
||||
Microcode mc_bits(reinterpret_cast<addr_t>(mc_rom.local_addr<uint8_t>()));
|
||||
|
||||
unsigned total_size = mc_bits.read<Microcode::Totalsize>();
|
||||
unsigned data_size = mc_bits.read<Microcode::Datasize>();
|
||||
|
||||
/* see Intel - 9.11 MICROCODE UPDATE FACILITIES */
|
||||
if (data_size == 0) data_size = 2000;
|
||||
if (total_size == 0) total_size = data_size + 48;
|
||||
|
||||
if (total_size < data_size || total_size <= 48) {
|
||||
error(id, " ", rom_name, " - microcode sizes are bogus ", total_size, " ", data_size);
|
||||
return;
|
||||
}
|
||||
unsigned const extension_size = total_size - data_size - 48;
|
||||
if (extension_size)
|
||||
warning("microcode patch contains extension we don't support yet!");
|
||||
|
||||
if (mc_bits.read<Microcode::Version>() != 1) {
|
||||
error(id, " ", rom_name, " - unsupported microcode version");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t mc_family = (mc_bits.read<Microcode::Cpuid::Family_ext>() << 4)
|
||||
| mc_bits.read<Microcode::Cpuid::Family>();
|
||||
uint8_t mc_model = (mc_bits.read<Microcode::Cpuid::Model_ext>() << 4)
|
||||
| mc_bits.read<Microcode::Cpuid::Model>();
|
||||
uint8_t mc_stepping = mc_bits.read<Microcode::Cpuid::Stepping>();
|
||||
unsigned mc_patch = mc_bits.read<Microcode::Revision>();
|
||||
uint8_t mc_flags = mc_bits.read<Microcode::Processor_flags::Flags>();
|
||||
|
||||
bool const platform_match = (1U << platform) & mc_flags;
|
||||
bool const match = (mc_family == family) && (mc_model == model) &&
|
||||
(mc_stepping == stepping) && platform_match;
|
||||
|
||||
log(id,
|
||||
" ", Hex(family, Hex::OMIT_PREFIX, Hex::PAD),
|
||||
":", Hex(model, Hex::OMIT_PREFIX, Hex::PAD),
|
||||
":", Hex(stepping, Hex::OMIT_PREFIX, Hex::PAD),
|
||||
" [", Hex(patch, Hex::OMIT_PREFIX), "]",
|
||||
" - microcode: "
|
||||
" ", Hex(mc_family, Hex::OMIT_PREFIX, Hex::PAD),
|
||||
":", Hex(mc_model, Hex::OMIT_PREFIX, Hex::PAD),
|
||||
":", Hex(mc_stepping, Hex::OMIT_PREFIX, Hex::PAD),
|
||||
" [", Hex(mc_patch, Hex::OMIT_PREFIX), "] from ",
|
||||
Hex(mc_bits.read<Microcode::Date::Month>(), Hex::OMIT_PREFIX), "/",
|
||||
Hex(mc_bits.read<Microcode::Date::Day>() , Hex::OMIT_PREFIX), "/",
|
||||
Hex(mc_bits.read<Microcode::Date::Year>() , Hex::OMIT_PREFIX),
|
||||
match ? " matches" : " mismatches",
|
||||
platform_match ? "" : ", platform mismatch");
|
||||
|
||||
if (!match)
|
||||
warning(id, " - microcode not applicable to CPU");
|
||||
else
|
||||
if (mc_patch > patch)
|
||||
warning(id, " - microcode of CPU is not on last patch level!");
|
||||
} catch (...) {
|
||||
warning(id, " ", rom_name, " - no microcode available");
|
||||
}
|
||||
}
|
||||
|
||||
static void inline cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
|
||||
{
|
||||
asm volatile ("cpuid" : "+a" (*eax), "+d" (*edx), "+b" (*ebx), "+c"(*ecx) :: "memory");
|
||||
}
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/* we support currently solely Intel CPUs */
|
||||
uint32_t eax = 0x0, ebx = 0, edx = 0, ecx = 0;
|
||||
cpuid(&eax, &ebx, &ecx, &edx);
|
||||
const char * intel = "GenuineIntel";
|
||||
|
||||
if (memcmp(intel, &ebx, 4) || memcmp(intel + 4, &edx, 4) || memcmp(intel + 8, &ecx, 4)) {
|
||||
error("no Intel CPU detected");
|
||||
return;
|
||||
}
|
||||
|
||||
Attached_rom_dataspace const platform_info { env, "platform_info" };
|
||||
|
||||
log("CPU family:model:stepping [patch]");
|
||||
|
||||
try {
|
||||
Xml_node const cpus = platform_info.xml().sub_node("hardware").sub_node("cpus");
|
||||
cpus.for_each_sub_node("cpu", [&] (Xml_node cpu) {
|
||||
uint8_t family = 0, model = 0, stepping = 0, platform = 0;
|
||||
unsigned id = 0, patch = 0;
|
||||
|
||||
cpu.attribute("id").value(&id);
|
||||
cpu.attribute("family").value(&family);
|
||||
cpu.attribute("model").value(&model);
|
||||
cpu.attribute("stepping").value(&stepping);
|
||||
cpu.attribute("platform").value(&platform);
|
||||
cpu.attribute("patch").value(&patch);
|
||||
|
||||
String<9> name(Hex(family, Hex::OMIT_PREFIX, Hex::PAD), "-",
|
||||
Hex(model, Hex::OMIT_PREFIX, Hex::PAD), "-",
|
||||
Hex(stepping, Hex::OMIT_PREFIX, Hex::PAD));
|
||||
|
||||
read_micro_code_rom(env, name, id, family, model, stepping,
|
||||
platform, patch);
|
||||
});
|
||||
} catch (...) {
|
||||
error("could not parse CPU data from platform_info");
|
||||
}
|
||||
log("microcode check done");
|
||||
}
|
5
repos/ports/src/test/microcode/target.mk
Normal file
5
repos/ports/src/test/microcode/target.mk
Normal file
@ -0,0 +1,5 @@
|
||||
TARGET = test-microcode
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
||||
|
||||
REQUIRES = nova
|
Loading…
Reference in New Issue
Block a user