mirror of
https://github.com/daeken/Zookeeper.git
synced 2024-05-15 19:34:47 -04:00
136 lines
3.9 KiB
C++
136 lines
3.9 KiB
C++
#include "Zookeeper.hpp"
|
|
|
|
string read_string(uint32_t addr) {
|
|
string str = "";
|
|
do {
|
|
auto c = box->cpu->read_memory<uint8_t>(addr++);
|
|
if(c == 0)
|
|
break;
|
|
str += c;
|
|
} while(true);
|
|
return str;
|
|
}
|
|
|
|
void Hypercall::log_(uint32_t message) {
|
|
auto str = read_string(message);
|
|
str.erase(std::find_if(str.rbegin(), str.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), str.end());
|
|
cout << "Guest Log: \"" << str << "\"" << endl;
|
|
}
|
|
|
|
uint32_t Hypercall::map(uint32_t virt_base, uint32_t count) {
|
|
return box->pm->map(virt_base, count);
|
|
}
|
|
uint32_t Hypercall::map_contiguous(uint32_t virt_base, uint32_t phys_low, uint32_t phys_high, uint32_t count) {
|
|
return box->pm->map_contiguous(virt_base, phys_low, phys_high, count);
|
|
}
|
|
uint32_t Hypercall::query_map_size(uint32_t base) {
|
|
auto count = 0;
|
|
while(box->cpu->is_mapped(base + count * PAGE_SIZE))
|
|
count++;
|
|
return count * PAGE_SIZE;
|
|
}
|
|
void Hypercall::unmap(uint32_t virt_base, uint32_t count) {
|
|
box->pm->unmap(virt_base, count);
|
|
}
|
|
|
|
uint32_t Hypercall::create_thread(uint32_t eip, uint32_t esp, uint32_t arg) {
|
|
esp -= 12;
|
|
auto tid = box->tm->create(eip, esp);
|
|
box->cpu->write_memory(esp + 4, tid);
|
|
box->cpu->write_memory(esp + 8, arg);
|
|
return tid;
|
|
}
|
|
|
|
void Hypercall::terminate_thread() {
|
|
box->tm->terminate();
|
|
}
|
|
|
|
uint32_t Hypercall::get_xbebase() {
|
|
return box->xbebase;
|
|
}
|
|
|
|
uint32_t Hypercall::query_eeprom(uint32_t index) {
|
|
return 0;
|
|
}
|
|
|
|
uint32_t Hypercall::io_open(uint32_t dir_handle, uint32_t fn, FSFlags flags) {
|
|
auto fnstr = read_string(fn);
|
|
if(dir_handle != 0) {
|
|
auto dirhnd = box->hm->get<DirHandle>(dir_handle);
|
|
assert(dirhnd->type == IOType::IO_DIRECTORY);
|
|
fnstr = dirhnd->path + "\\" + fnstr;
|
|
}
|
|
auto file = box->io->open(fnstr, flags);
|
|
if(file == NULL)
|
|
return 0;
|
|
return file->handle;
|
|
}
|
|
|
|
bool Hypercall::io_read(uint32_t handle, uint32_t buf, uint32_t count, int64_t offset) {
|
|
auto nbuf = new uint8_t[count];
|
|
auto hnd = box->hm->get<IOHandle>(handle);
|
|
hnd->read(nbuf, count, offset);
|
|
box->cpu->write_memory(buf, count, nbuf);
|
|
delete nbuf;
|
|
return true;
|
|
}
|
|
|
|
bool Hypercall::io_write(uint32_t handle, uint32_t buf, uint32_t count, int64_t offset) {
|
|
auto nbuf = new uint8_t[count];
|
|
box->cpu->read_memory(buf, count, nbuf);
|
|
auto hnd = box->hm->get<IOHandle>(handle);
|
|
hnd->write(nbuf, count, offset);
|
|
delete nbuf;
|
|
return true;
|
|
}
|
|
|
|
bool Hypercall::io_ioctl(uint32_t handle, uint32_t code, uint32_t ibuf, uint32_t isize, uint32_t obuf, uint32_t osize) {
|
|
auto irb = isize != 0 ? new uint8_t[isize] : NULL;
|
|
auto orb = osize != 0 ? new uint8_t[osize] : NULL;
|
|
if(orb) memset(orb, 0, osize);
|
|
box->cpu->read_memory(ibuf, isize, irb);
|
|
auto hnd = box->hm->get<IOHandle>(handle);
|
|
hnd->ioctl(code, irb, isize, orb, osize);
|
|
box->cpu->write_memory(obuf, osize, orb);
|
|
if(isize != 0) delete irb;
|
|
if(osize != 0) delete orb;
|
|
return true;
|
|
}
|
|
|
|
void Hypercall::close(uint32_t handle) {
|
|
box->hm->remove(handle);
|
|
}
|
|
|
|
void Hypercall::get_system_time(uint32_t addr) {
|
|
timeval stime;
|
|
gettimeofday(&stime, NULL);
|
|
auto time = ((uint64_t) stime.tv_sec) * 10000000 + ((uint64_t) stime.tv_usec) * 10;
|
|
box->cpu->write_memory<uint64_t>(addr, time);
|
|
}
|
|
|
|
void Hypercall::pci_read(uint32_t bus, uint32_t slot, uint32_t reg, uint32_t buffer, uint32_t length) {
|
|
auto addr = (bus << 16) | slot;
|
|
auto buf = new uint8_t[length];
|
|
if(IN(addr, box->pci)) {
|
|
auto dev = box->pci[addr];
|
|
dev->readPci(reg, buf, length);
|
|
box->cpu->write_memory(buffer, length, buf);
|
|
} else {
|
|
cout << format("Read from PCI device at %04x:%04x") % bus % slot << endl;
|
|
break_in(true);
|
|
}
|
|
}
|
|
|
|
void Hypercall::pci_write(uint32_t bus, uint32_t slot, uint32_t reg, uint32_t buffer, uint32_t length) {
|
|
auto addr = (bus << 16) | slot;
|
|
auto buf = new uint8_t[length];
|
|
box->cpu->read_memory(buffer, length, buf);
|
|
if(IN(addr, box->pci)) {
|
|
auto dev = box->pci[addr];
|
|
dev->writePci(reg, buf, length);
|
|
} else {
|
|
cout << format("Write to unknown PCI device at %04x:%04x") % bus % slot << endl;
|
|
break_in(true);
|
|
}
|
|
}
|