Skip to content

Commit

Permalink
Add CLI flag to allow setting of OpenFirmware environment variables
Browse files Browse the repository at this point in the history
Allows enabling of verbose booting via the command-line interface (instead of having to drop into the interactive debugger).
  • Loading branch information
mihaip committed Mar 3, 2025
1 parent 6e74146 commit a6e1b8c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 12 deletions.
10 changes: 8 additions & 2 deletions debugger/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -784,9 +784,15 @@ void DppcDebugger::enter_debugger() {
ss >> var_name;
std::istream::sentry se(ss); // skip white space
getline(ss, value); // get everything up to eol
if (ofnvram->init())
if (ofnvram->init()) {
cout << " Cannot open NVRAM" << endl;
continue;
ofnvram->setenv(var_name, value);
}
if (!ofnvram->setenv(var_name, value)) {
cout << " Please try again" << endl;
} else {
cout << " ok" << endl; // mimic Forth
}
#ifndef _WIN32
} else if (cmd == "nvedit") {
cmd = "";
Expand Down
13 changes: 6 additions & 7 deletions devices/common/ofnvram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,9 @@ bool OfConfigChrp::validate()
bool wip = true;
bool of_part_found = false;

if (this->nvram_obj == nullptr)
return false;

// search the entire 8KB NVRAM for CHRP OF config partition.
// Bail out if an unknown partition or free space is encountered.
// Skip over known partitions.
Expand Down Expand Up @@ -592,16 +595,12 @@ void OfConfigUtils::printenv() {
}
}

void OfConfigUtils::setenv(string var_name, string value)
bool OfConfigUtils::setenv(string var_name, string value)
{
if (!this->open_container())
return;
return false;

OfConfigImpl::config_dict vars = this->cfg_impl->get_config_vars();

if (!this->cfg_impl->set_var(var_name, value)) {
cout << " Please try again" << endl;
} else {
cout << " ok" << endl; // mimic Forth
}
return this->cfg_impl->set_var(var_name, value);
}
2 changes: 1 addition & 1 deletion devices/common/ofnvram.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class OfConfigUtils {

int init();
void printenv();
void setenv(std::string var_name, std::string value);
bool setenv(std::string var_name, std::string value);

protected:
bool open_container();
Expand Down
34 changes: 32 additions & 2 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cpu/ppc/ppcemu.h>
#include <cpu/ppc/ppcmmu.h>
#include <debugger/debugger.h>
#include <devices/common/ofnvram.h>
#include <machines/machinebase.h>
#include <machines/machinefactory.h>
#include <utils/profiler.h>
Expand Down Expand Up @@ -94,6 +95,7 @@ const WorkingDirectoryValidator WorkingDirectory;

void run_machine(
std::string machine_str, char *rom_data, size_t rom_size, uint32_t execution_mode
,const std::vector<std::string> &env_vars
,uint32_t profiling_interval_ms
);

Expand All @@ -110,7 +112,7 @@ int main(int argc, char** argv) {
string keyboard_string = "Eng_USA";

const std::map<std::string, int> kbd_map{
{"Eng_USA", 0}, {"Eng_GBR", 1}, {"Fra_FRA", 10}, {"Deu_DEU", 20},
{"Eng_USA", 0}, {"Eng_GBR", 1}, {"Fra_FRA", 10}, {"Deu_DEU", 20},
{"Ita_ITA", 30},{"Spa_ESP", 40}, {"Jpn_JPN", 80},
};

Expand Down Expand Up @@ -142,6 +144,10 @@ int main(int argc, char** argv) {
app.add_flag("--log-no-uptime", log_no_uptime,
"Disable the uptime preamble of logged messages");

std::vector<std::string> env_vars;
app.add_option("--setenv", env_vars, "Set OpenFirmware variables at startup")
->take_all();

uint32_t profiling_interval_ms = 0;
#ifdef CPU_PROFILING
app.add_option("--profiling-interval-ms", profiling_interval_ms,
Expand Down Expand Up @@ -280,6 +286,7 @@ int main(int argc, char** argv) {
&rom_data[0],
rom_size,
execution_mode,
env_vars,
profiling_interval_ms);
if (power_off_reason == po_restarting) {
LOG_F(INFO, "Restarting...");
Expand All @@ -306,6 +313,7 @@ int main(int argc, char** argv) {
void run_machine(std::string machine_str, char* rom_data,
size_t rom_size,
uint32_t execution_mode,
const std::vector<std::string> &env_vars,
uint32_t
#ifdef CPU_PROFILING
profiling_interval_ms
Expand All @@ -315,6 +323,28 @@ void run_machine(std::string machine_str, char* rom_data,
return;
}

if (!env_vars.empty()) {
OfConfigUtils ofnvram;
if (!ofnvram.init()) {
for (const auto &env_var : env_vars) {
auto pos = env_var.find('=');
if (pos != std::string::npos) {
std::string name = env_var.substr(0, pos);
std::string value = env_var.substr(pos + 1);
if (ofnvram.setenv(name, value)) {
LOG_F(INFO, "Set OpenFirmware variable %ss to %s", name.c_str(), value.c_str());
} else {
LOG_F(WARNING, "Cannot set OpenFirmware variable %s to %s", name.c_str(), value.c_str());
}
} else {
LOG_F(WARNING, "Invalid format for --setenv: %s", env_var.c_str());
}
}
} else {
LOG_F(WARNING, "Cannot initialize NVRAM wrapper, will not set OpenFirmware variables");
}
}

uint32_t deterministic_timer;
if (is_deterministic) {
EventManager::get_instance()->disable_input_handlers();
Expand All @@ -332,7 +362,7 @@ void run_machine(std::string machine_str, char* rom_data,

// set up system wide event polling using
// default Macintosh polling rate of 11 ms
uint32_t event_timer = TimerManager::get_instance()->add_cyclic_timer(MSECS_TO_NSECS(11), [] {
uint32_t event_timer = TimerManager::get_instance()->add_cyclic_timer(MSECS_TO_NSECS(11), [] {
EventManager::get_instance()->poll_events(keyboard_id);
});

Expand Down

0 comments on commit a6e1b8c

Please sign in to comment.