npc: wip, cannot build

This commit is contained in:
xinyangli 2024-07-09 20:42:01 +08:00
parent 29a9850210
commit 3acab0a751
Signed by: xin
SSH key fingerprint: SHA256:qZ/tzd8lYRtUFSrfBDBMcUqV4GHKxqeqRA3huItgvbk
19 changed files with 404 additions and 128 deletions

View file

@ -0,0 +1,3 @@
add_library(devices serial.cpp rtc.cpp)
target_include_directories(devices PUBLIC include)

View file

@ -0,0 +1,85 @@
#include <array>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <initializer_list>
#include <iostream>
#include <iterator>
#include <map>
#include <memory>
#include <unordered_map>
#include <utility>
namespace Devices {
class Device {
public:
uint8_t *p_buf;
uint64_t addr;
size_t len;
Device(uint64_t addr, size_t len, uint8_t buf[])
: addr(addr), len(len), p_buf(buf) {}
virtual ~Device(){};
virtual void io_handler(uint32_t offset, size_t len, bool is_write) = 0;
void transfer(uint8_t *src, size_t len, bool is_write) {
if (is_write) {
memmove(p_buf, src, len);
} else {
memmove(src, p_buf, len);
}
};
};
class Serial : public Device {
uint8_t buf[1];
public:
Serial(uint64_t addr, size_t len);
~Serial() override{};
void io_handler(uint32_t offset, size_t len, bool is_write) override;
// void transfer(uint8_t *src, size_t len, bool is_write) override;
};
class RTC : public Device {
uint8_t buf[8];
uint64_t boot_time;
uint64_t get_time_internal();
uint64_t get_time();
public:
RTC(uint64_t addr, size_t len);
~RTC() override{};
void io_handler(uint32_t offset, size_t len, bool is_write) override;
// void transfer(uint8_t *src, size_t len, bool is_write) override;
};
class DeviceMap {
std::map<uint64_t, Device *> addr_to_device;
public:
DeviceMap(std::initializer_list<Device *> devices) {
for (auto device : devices) {
addr_to_device.insert(std::make_pair(device->addr, device));
}
}
bool handle(uint64_t addr, uint8_t *data, size_t len, bool is_write) {
auto it = addr_to_device.upper_bound(addr);
if (it == addr_to_device.begin() ||
(--it)->second->addr + it->second->len <= addr) {
std::cerr << "Use of a unintialized device at memory addr: 0x" << std::hex
<< addr << std::dec << std::endl;
return false;
}
auto &device = it->second;
uint32_t offset = addr - device->addr;
if (is_write) {
device->transfer(data, len, is_write);
device->io_handler(offset, len, is_write);
} else {
device->io_handler(offset, len, is_write);
device->transfer(data, len, is_write);
}
return true;
}
};
} // namespace Devices

49
npc/csrc/devices/rtc.cpp Normal file
View file

@ -0,0 +1,49 @@
#include <cstdint>
#include <devices.hpp>
namespace Devices {
uint64_t RTC::get_time_internal() {
#if defined(CONFIG_TARGET_AM)
uint64_t us = io_read(AM_TIMER_UPTIME).us;
#elif defined(CONFIG_TIMER_GETTIMEOFDAY)
struct timeval now;
gettimeofday(&now, NULL);
uint64_t us = now.tv_sec * 1000000 + now.tv_usec;
#else
struct timespec now;
clock_gettime(CLOCK_MONOTONIC_COARSE, &now);
uint64_t us = now.tv_sec * 1000000 + now.tv_nsec / 1000;
#endif
return us;
}
uint64_t RTC::get_time() {
if (boot_time == 0)
boot_time = get_time_internal();
uint64_t now = get_time_internal();
return now - boot_time;
}
RTC::RTC(uint64_t addr, size_t len) : Device(addr, len, buf) {
*(uint64_t *)buf = 0;
};
void RTC::io_handler(uint32_t offset, size_t len, bool is_write) {
assert(offset == 0 || offset == 4);
if (!is_write && offset == 4) {
uint64_t us = get_time();
buf[0] = (uint32_t)us;
buf[1] = us >> 32;
}
}
// void RTC::transfer(uint8_t *src, size_t len, bool is_write) {
// if (is_write) {
// for (size_t i = 0; i < len; i++)
// buf[i] = src[i];
// } else {
// for (size_t i = 0; i < len; i++)
// src[i] = buf[i];
// }
// }
} // namespace Devices

View file

@ -0,0 +1,22 @@
#include <devices.hpp>
#include <iostream>
namespace Devices {
Serial::Serial(uint64_t addr, size_t len) : Device(addr, len, buf) {
buf[0] = 0;
};
void Serial::io_handler(uint32_t offset, size_t len, bool is_write) {
if (is_write) {
std::cout << (char)buf[0];
}
}
// void Serial::transfer(uint8_t *src, size_t len, bool is_write) {
// if (is_write) {
// for (size_t i = 0; i < len; i++)
// buf[i] = src[i];
// } else {
// for (size_t i = 0; i < len; i++)
// src[i] = buf[i];
// }
// }
} // namespace Devices