npc: wip, cannot build
This commit is contained in:
parent
29a9850210
commit
3acab0a751
19 changed files with 404 additions and 128 deletions
3
npc/csrc/devices/CMakeLists.txt
Normal file
3
npc/csrc/devices/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
add_library(devices serial.cpp rtc.cpp)
|
||||
|
||||
target_include_directories(devices PUBLIC include)
|
85
npc/csrc/devices/include/devices.hpp
Normal file
85
npc/csrc/devices/include/devices.hpp
Normal 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
49
npc/csrc/devices/rtc.cpp
Normal 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
|
22
npc/csrc/devices/serial.cpp
Normal file
22
npc/csrc/devices/serial.cpp
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue