blob: cc9e7d1e0a573e2ae1ac02821d9cbbe22c9e4eb1 [file] [log] [blame]
Patrick Venture030b1a82019-01-18 08:33:02 -08001#include "io.hpp"
2
3#include "internal/sys.hpp"
4
5#include <fcntl.h>
6
7#include <cstdint>
8#include <cstring>
9#include <string>
10
11namespace host_tool
12{
13
14const std::string DevMemDevice::devMemPath = "/dev/mem";
15
Patrick Ventureac4ff972019-05-03 17:35:00 -070016bool DevMemDevice::read(const std::size_t offset, const std::size_t length,
17 void* const destination)
18{
19 if (!opened)
20 {
21 devMemFd = sys->open(devMemPath.c_str(), O_RDWR);
22 if (devMemFd < 0)
23 {
24 return false;
25 }
26
27 opened = true;
28 }
29
Patrick Venture206097b2019-05-07 13:37:01 -070030 /* Map based on aligned addresses - behind the scenes. */
31 const std::size_t alignedDiff = offset % sys->getpagesize();
32 const std::size_t alignedOffset = offset - alignedDiff;
33 const std::size_t alignedSize = length + alignedDiff;
34
Patrick Ventureac4ff972019-05-03 17:35:00 -070035 // addr, length, prot, flags, fd, offset
Patrick Venture206097b2019-05-07 13:37:01 -070036 devMemMapped = sys->mmap(0, alignedSize, PROT_READ, MAP_SHARED, devMemFd,
37 alignedOffset);
Patrick Ventureac4ff972019-05-03 17:35:00 -070038 if (devMemMapped == MAP_FAILED)
39 {
40 return false; /* but leave the file open. */
41 }
42
Patrick Venture206097b2019-05-07 13:37:01 -070043 void* alignedSource =
44 static_cast<std::uint8_t*>(devMemMapped) + alignedDiff;
45
Patrick Ventureac4ff972019-05-03 17:35:00 -070046 /* Copy the bytes. */
Patrick Venture206097b2019-05-07 13:37:01 -070047 std::memcpy(destination, alignedSource, length);
Patrick Ventureac4ff972019-05-03 17:35:00 -070048
49 /* Close the map between reads for now. */
50 sys->munmap(devMemMapped, length);
51
52 return true;
53}
54
Patrick Venture030b1a82019-01-18 08:33:02 -080055bool DevMemDevice::write(const std::size_t offset, const std::size_t length,
56 const void* const source)
57{
58 if (!opened)
59 {
60 devMemFd = sys->open(devMemPath.c_str(), O_RDWR);
61 if (devMemFd < 0)
62 {
63 return false;
64 }
65
66 opened = true;
67 }
68
Patrick Venture206097b2019-05-07 13:37:01 -070069 /* Map based on aligned addresses - behind the scenes. */
70 const std::size_t alignedDiff = offset % sys->getpagesize();
71 const std::size_t alignedOffset = offset - alignedDiff;
72 const std::size_t alignedSize = length + alignedDiff;
73
Patrick Venture030b1a82019-01-18 08:33:02 -080074 // addr, length, prot, flags, fd, offset
Patrick Venture206097b2019-05-07 13:37:01 -070075 devMemMapped = sys->mmap(0, alignedSize, PROT_WRITE, MAP_SHARED, devMemFd,
76 alignedOffset);
77
Patrick Venture030b1a82019-01-18 08:33:02 -080078 if (devMemMapped == MAP_FAILED)
79 {
80 return false; /* but leave the file open. */
81 }
82
Patrick Venture206097b2019-05-07 13:37:01 -070083 void* alignedDestination =
84 static_cast<std::uint8_t*>(devMemMapped) + alignedDiff;
85
Patrick Venture030b1a82019-01-18 08:33:02 -080086 /* Copy the bytes. */
Patrick Venture206097b2019-05-07 13:37:01 -070087 std::memcpy(alignedDestination, source, length);
Patrick Venture030b1a82019-01-18 08:33:02 -080088
89 /* Close the map between writes for now. */
90 sys->munmap(devMemMapped, length);
91
92 return true;
93}
94
95} // namespace host_tool