Finish NVRAM implementation.

This commit is contained in:
Maxim Poliakovski 2020-01-07 11:52:38 +01:00
parent bd5ae4a45a
commit c2bbdc4144
3 changed files with 68 additions and 57 deletions

View File

@ -7,7 +7,6 @@
#include <cinttypes> #include <cinttypes>
#include <iostream> #include <iostream>
#include <cassert>
#include "macio.h" #include "macio.h"
#include "viacuda.h" #include "viacuda.h"
@ -21,13 +20,14 @@ using namespace std;
HeathrowIC::HeathrowIC() : PCIDevice("mac-io/heathrow") HeathrowIC::HeathrowIC() : PCIDevice("mac-io/heathrow")
{ {
this->viacuda = new ViaCuda(); this->viacuda = new ViaCuda();
this->nvram = new NVram(); this->nvram = new NVram();
assert(this->viacuda); // FIXME: do proper exception handling!
assert(this->nvram); // FIXME: do proper exception handling!
} }
HeathrowIC::~HeathrowIC() HeathrowIC::~HeathrowIC()
{ {
if (this->nvram)
delete(this->nvram);
if (this->viacuda) if (this->viacuda)
delete(this->viacuda); delete(this->viacuda);
} }
@ -83,6 +83,9 @@ uint32_t HeathrowIC::read(uint32_t offset, int size)
case 0x17: case 0x17:
res = this->viacuda->read((offset - 0x16000) >> 9); res = this->viacuda->read((offset - 0x16000) >> 9);
break; break;
case 0x60:
case 0x70:
res = this->nvram->read_byte((offset - 0x60000) >> 4);
default: default:
cout << "unmapped I/O space: " << sub_dev << endl; cout << "unmapped I/O space: " << sub_dev << endl;
} }

View File

@ -10,60 +10,70 @@
#include <cinttypes> #include <cinttypes>
#include "nvram.h" #include "nvram.h"
/** @file Non-volatile RAM implementation.
*/
using namespace std; using namespace std;
/** the signature for NVRAM backing file identification. */
static char NVRAM_FILE_ID[] = "DINGUSPPCNVRAM";
NVram::NVram() NVram::NVram(std::string file_name, uint32_t ram_size)
{ {
this->nvram_init(); this->file_name = file_name;
this->ram_size = ram_size;
this->storage = new uint8_t[ram_size];
this->init();
} }
NVram::~NVram() NVram::~NVram()
{ {
this->nvram_save(); this->save();
if (this->storage)
delete this->storage;
} }
void NVram::nvram_init() { uint8_t NVram::read_byte(uint32_t offset)
NVram::nvram_file.open("nvram.bin", ios::in | ios::out | ios::binary); {
return (this->storage[offset]);
}
if (nvram_file.fail()) { void NVram::write_byte(uint32_t offset, uint8_t val)
std::cout << "Warning: Could not find the NVRAM file. This will be blank. \n" << endl; {
NVram::nvram_file.write(0x00, 8192); this->storage[offset] = val;
return; }
}
NVram::nvram_file.seekg(0, nvram_file.end); void NVram::init() {
NVram::nvram_filesize = nvram_file.tellg(); char sig[sizeof(NVRAM_FILE_ID)];
NVram::nvram_file.seekg(0, nvram_file.beg); uint16_t data_size;
if (NVram::nvram_filesize != 0x2000) { ifstream f(this->file_name, ios::in | ios::binary);
NVram::nvram_file.write(0x00, 8192);
}
char temp_storage[8192]; if (f.fail() || !f.read(sig, sizeof(NVRAM_FILE_ID)) ||
!f.read((char *)&data_size, sizeof(data_size)) ||
NVram::nvram_file.read(temp_storage, 8192); memcmp(sig, NVRAM_FILE_ID, sizeof(NVRAM_FILE_ID)) ||
data_size != this->ram_size ||
//hack copying to the NVRAM Array GO! !f.read((char *)this->storage, this->ram_size))
for (int i = 0; i < 8192; i++)
{ {
NVram::nvram_storage[i] = (uint8_t) temp_storage[i]; cout << "WARN: Could not restore NVRAM content from the given file." << endl;
memset(this->storage, 0, sizeof(this->ram_size));
} }
f.close();
} }
void NVram::nvram_save() { void NVram::save()
NVram::nvram_savefile.open("nvram.bin", ios::out | ios::binary); {
ofstream f(this->file_name, ios::out | ios::binary);
NVram::nvram_savefile.write((char*)nvram_storage, 8192); /* write file identification */
f.write(NVRAM_FILE_ID, sizeof(NVRAM_FILE_ID));
f.write((char *)&this->ram_size, sizeof(this->ram_size));
NVram::nvram_savefile.close(); /* write NVRAM content */
f.write((char *)this->storage, this->ram_size);
f.close();
} }
uint8_t NVram::nvram_read(uint32_t nvram_offset){
nvram_value = NVram::nvram_storage[nvram_offset];
return nvram_value;
}
void NVram::nvram_write(uint32_t nvram_offset, uint8_t write_val){
NVram::nvram_storage[nvram_offset] = write_val;
}

View File

@ -1,33 +1,31 @@
#ifndef NVRAM_H #ifndef NVRAM_H
#define NVRAM_H #define NVRAM_H
#include <iostream> #include <string>
#include <fstream>
#include <cinttypes> #include <cinttypes>
/** @file Non-volatile RAM emulation.
It implements a non-volatile random access storage whose content will be
automatically saved to and restored from the dedicated file.
*/
class NVram class NVram
{ {
public: public:
NVram(); NVram(std::string file_name = "nvram.bin", uint32_t ram_size = 8192);
~NVram(); ~NVram();
uint8_t read(int value); uint8_t read_byte(uint32_t offset);
void write(int reg, uint8_t value); void write_byte(uint32_t offset, uint8_t value);
private: private:
std::fstream nvram_file; //NVRAM file for storing and reading values std::string file_name; /* file name for the backing file. */
std::ofstream nvram_savefile; //Save file when closing out DingusPPC uint16_t ram_size; /* NVRAM size. */
uint8_t* storage;
/* NVRAM state. */ void init();
uint32_t nvram_offset; void save();
uint32_t nvram_filesize;
uint8_t nvram_value;
uint8_t nvram_storage[8192];
void nvram_init();
void nvram_save();
uint8_t nvram_read(uint32_t nvram_offset);
void nvram_write(uint32_t nvram_offset, uint8_t write_val);
}; };
#endif /* NVRAM_H */ #endif /* NVRAM_H */