StarletBootstrapProbe: --broadway-h1a's report and budget, from the final review
Two findings of the review of 2df9dfc909 (StarOS H-1A, D2):
- The report reads the bench window too (hw0c_report(): HW-M4-0D's
area, and H-1A's record if it was never read), but a refused access
there did not fail the run, as one during the run does. It does now:
the failure on stderr, and the run fails.
- --cycles' bound of 2^34 was raised whenever "--broadway-h1a" appeared
among the arguments, even as the value of --ipc-script or --stage-spk
(a file of that name), the run then not in the client's mode.
ClientRequested reads the options with their grammar: the word after
--ipc-script, --stage-spk or --cycles is a value, never an option.
StarletProbeBroadwayTest: ClientRequested.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
2df9dfc909
commit
9ad22f00bd
3 files changed
+42
-9
No files matched your search
@@ -112,6 +112,22 @@ TEST(StarletProbeBroadway, TheClientsBudgetIsBoundedAndOnlyItsOwn)
|
||||
EXPECT_FALSE(ParseCycles("17179869184"));
|
||||
}
|
||||
|
||||
TEST(StarletProbeBroadway, OnlyTheOptionItselfRaisesTheBudget)
|
||||
{
|
||||
const auto requested = [](std::vector<const char*> argv) {
|
||||
return ClientRequested(static_cast<int>(argv.size()), argv.data());
|
||||
};
|
||||
EXPECT_TRUE(requested({"probe", "image.elf", "--broadway-h1a"}));
|
||||
EXPECT_TRUE(requested({"probe", "image.elf", "--jit", "--cycles", "4096", "--broadway-h1a"}));
|
||||
EXPECT_TRUE(requested({"probe", "image.elf", "--stage-spk", "p.bin", "--broadway-h1a"}));
|
||||
EXPECT_FALSE(requested({"probe", "image.elf"}));
|
||||
// The image's own name, or another option's value, is no option.
|
||||
EXPECT_FALSE(requested({"probe", "--broadway-h1a"}));
|
||||
EXPECT_FALSE(requested({"probe", "image.elf", "--ipc-script", "--broadway-h1a"}));
|
||||
EXPECT_FALSE(requested({"probe", "image.elf", "--stage-spk", "--broadway-h1a", "--jit"}));
|
||||
EXPECT_FALSE(requested({"probe", "image.elf", "--cycles", "--broadway-h1a"}));
|
||||
}
|
||||
|
||||
TEST(StarletProbeBroadway, TheStarletIsDoneAsTheLoadersMonitorSaysIt)
|
||||
{
|
||||
// StarOS boot/contract/staros_boot.h: RUNNING 2, IDLE 3, FATAL 4, PANIC 5, FAULT 6; EXI PPC 1.
|
||||
|
||||
@@ -48,6 +48,22 @@ constexpr bool StarletDone(bool trace_terminal, u32 sbr1_state, u32 sbr1_exi_own
|
||||
return trace_terminal || (sbr1_state >= SBR1_STATE_IDLE && sbr1_exi_owner == SBR1_EXI_PPC);
|
||||
}
|
||||
|
||||
// Whether --broadway-h1a is among the probe's options (argv[2] on), read with their grammar: the
|
||||
// word after --ipc-script, --stage-spk or --cycles is that option's value, never an option. It
|
||||
// raises --cycles' bound, which is read where it stands, before the other options are known.
|
||||
inline bool ClientRequested(int argc, const char* const* argv)
|
||||
{
|
||||
for (int index = 2; index < argc; ++index)
|
||||
{
|
||||
const std::string_view option = argv[index];
|
||||
if (option == "--ipc-script" || option == "--stage-spk" || option == "--cycles")
|
||||
++index;
|
||||
else if (option == "--broadway-h1a")
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Whether a whole word at `address` lies in the bench window.
|
||||
constexpr bool InBenchWindow(u64 address)
|
||||
{
|
||||
|
||||
@@ -236,11 +236,15 @@ bool Run(const std::string& path, bool jit, bool mmu_faults, SBR1Mode sbr1,
|
||||
std::cerr << "Starlet panic state " << memory.Read32(info.panic_state) << " code "
|
||||
<< memory.Read32(info.panic_code) << '\n';
|
||||
};
|
||||
// The client's capture on stdout, after the trace, and its counts on stderr.
|
||||
// The client's capture on stdout, after the trace, and its counts on stderr. The report reads the
|
||||
// window too: false if it reached outside (the access refused, as during the run).
|
||||
const auto report_client = [&](std::string_view status) {
|
||||
std::cout << client->Report(status);
|
||||
std::cerr << "--broadway-h1a: " << client->Steps() << " steps, timebase 0x" << std::hex
|
||||
<< client->Timebase() << std::dec << ", done " << client->Done() << '\n';
|
||||
if (client->Failed())
|
||||
std::cerr << "--broadway-h1a: " << client->Failure() << '\n';
|
||||
return !client->Failed();
|
||||
};
|
||||
ProbeBus script_bus(mem1, system.GetWiiIPC());
|
||||
// The model's own line raises the IPC cause: the probe has no Starlet object (ProbeScript.h).
|
||||
@@ -324,7 +328,7 @@ bool Run(const std::string& path, bool jit, bool mmu_faults, SBR1Mode sbr1,
|
||||
<< " instructions=" << core.GetExecutedInstructions() << '\n';
|
||||
if (length == TRACE_CAPACITY)
|
||||
std::cerr << "--broadway-h1a: the trace is full: its last lines are in the SBR1 ring\n";
|
||||
report_client(CLIENT_STATUS_DONE);
|
||||
const bool reported = report_client(CLIENT_STATUS_DONE);
|
||||
const bool startup_ok = trace.find("REV:BOOT:ENTRY\n") != std::string::npos &&
|
||||
trace.find("REV:BOOT:BSS_OK\n") != std::string::npos &&
|
||||
trace.find("REV:BOOT:DATA_OK\n") != std::string::npos &&
|
||||
@@ -332,7 +336,7 @@ bool Run(const std::string& path, bool jit, bool mmu_faults, SBR1Mode sbr1,
|
||||
trace.find("REV:BOOT:RUST\n") != std::string::npos;
|
||||
const bool idle =
|
||||
state == SBR1_STATE_IDLE || trace.find("REV:BOOT:IDLE\n") != std::string::npos;
|
||||
return startup_ok && idle && trace.find("REV:PANIC") == std::string::npos &&
|
||||
return reported && startup_ok && idle && trace.find("REV:PANIC") == std::string::npos &&
|
||||
trace.find("REV:FATAL") == std::string::npos;
|
||||
}
|
||||
if (memory.Read32(info.trace) != TRACE_MAGIC)
|
||||
@@ -426,12 +430,9 @@ int main(int argc, char** argv)
|
||||
std::optional<u64> cycles;
|
||||
bool broadway_h1a = false;
|
||||
// --cycles' bound: MAX_CYCLES, or MAX_CLIENT_CYCLES when --broadway-h1a is among the options
|
||||
// (ProbeBudget.h), known before they are read so that --cycles is read where it stands.
|
||||
const auto is_client = [](const char* argument) {
|
||||
return std::string_view(argument) == "--broadway-h1a";
|
||||
};
|
||||
const u64 max_cycles =
|
||||
std::any_of(argv + 2, argv + argc, is_client) ? MAX_CLIENT_CYCLES : MAX_CYCLES;
|
||||
// (ProbeBudget.h, ClientRequested), known before they are read so that --cycles is read where
|
||||
// it stands.
|
||||
const u64 max_cycles = ClientRequested(argc, argv) ? MAX_CLIENT_CYCLES : MAX_CYCLES;
|
||||
std::optional<std::string> package_path;
|
||||
std::optional<std::string> script_path;
|
||||
for (int index = 2; index < argc; ++index)
|
||||
|
||||
Reference in new issue
Block a user