1ded66d0fSJason Ling /*
2ded66d0fSJason Ling * Copyright 2018 Google Inc.
3ded66d0fSJason Ling *
4ded66d0fSJason Ling * Licensed under the Apache License, Version 2.0 (the "License");
5ded66d0fSJason Ling * you may not use this file except in compliance with the License.
6ded66d0fSJason Ling * You may obtain a copy of the License at
7ded66d0fSJason Ling *
8ded66d0fSJason Ling * http://www.apache.org/licenses/LICENSE-2.0
9ded66d0fSJason Ling *
10ded66d0fSJason Ling * Unless required by applicable law or agreed to in writing, software
11ded66d0fSJason Ling * distributed under the License is distributed on an "AS IS" BASIS,
12ded66d0fSJason Ling * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ded66d0fSJason Ling * See the License for the specific language governing permissions and
14ded66d0fSJason Ling * limitations under the License.
15ded66d0fSJason Ling */
16ded66d0fSJason Ling
17ded66d0fSJason Ling #include "data.hpp"
18ded66d0fSJason Ling #include "pci_handler.hpp"
19ded66d0fSJason Ling
20ded66d0fSJason Ling #include <fcntl.h>
21ded66d0fSJason Ling
22ded66d0fSJason Ling #include <cstdint>
23ded66d0fSJason Ling #include <cstring>
24ded66d0fSJason Ling #include <string>
25ded66d0fSJason Ling #include <vector>
26ded66d0fSJason Ling
27ded66d0fSJason Ling namespace ipmi_flash
28ded66d0fSJason Ling {
29ded66d0fSJason Ling
open()30ded66d0fSJason Ling bool PciDataHandler::open()
31ded66d0fSJason Ling {
32ded66d0fSJason Ling static constexpr auto devmem = "/dev/mem";
33ded66d0fSJason Ling
34ded66d0fSJason Ling mappedFd = sys->open(devmem, O_RDWR | O_SYNC);
35ded66d0fSJason Ling if (mappedFd == -1)
36ded66d0fSJason Ling {
37ded66d0fSJason Ling std::fprintf(stderr, "PciDataHandler::Unable to open /dev/mem");
38ded66d0fSJason Ling return false;
39ded66d0fSJason Ling }
40ded66d0fSJason Ling
41ded66d0fSJason Ling mapped = reinterpret_cast<uint8_t*>(sys->mmap(
42ded66d0fSJason Ling 0, memoryRegionSize, PROT_READ, MAP_SHARED, mappedFd, regionAddress));
43ded66d0fSJason Ling if (mapped == MAP_FAILED)
44ded66d0fSJason Ling {
45ded66d0fSJason Ling sys->close(mappedFd);
46ded66d0fSJason Ling mappedFd = -1;
47ded66d0fSJason Ling mapped = nullptr;
48ded66d0fSJason Ling
49ded66d0fSJason Ling std::fprintf(stderr, "PciDataHandler::Unable to map region");
50ded66d0fSJason Ling return false;
51ded66d0fSJason Ling }
52ded66d0fSJason Ling
53ded66d0fSJason Ling return true;
54ded66d0fSJason Ling }
55ded66d0fSJason Ling
close()56ded66d0fSJason Ling bool PciDataHandler::close()
57ded66d0fSJason Ling {
58ded66d0fSJason Ling /* TODO: Turn off the P2A bridge and region to disable host-side access.
59ded66d0fSJason Ling */
60ded66d0fSJason Ling if (mapped)
61ded66d0fSJason Ling {
62ded66d0fSJason Ling sys->munmap(mapped, memoryRegionSize);
63ded66d0fSJason Ling mapped = nullptr;
64ded66d0fSJason Ling }
65ded66d0fSJason Ling
66ded66d0fSJason Ling if (mappedFd != -1)
67ded66d0fSJason Ling {
68ded66d0fSJason Ling sys->close(mappedFd);
69ded66d0fSJason Ling mappedFd = -1;
70ded66d0fSJason Ling }
71ded66d0fSJason Ling
72ded66d0fSJason Ling return true;
73ded66d0fSJason Ling }
74ded66d0fSJason Ling
copyFrom(std::uint32_t length)75ded66d0fSJason Ling std::vector<std::uint8_t> PciDataHandler::copyFrom(std::uint32_t length)
76ded66d0fSJason Ling {
77ded66d0fSJason Ling std::vector<std::uint8_t> results(length);
78ded66d0fSJason Ling std::memcpy(results.data(), mapped, length);
79ded66d0fSJason Ling
80ded66d0fSJason Ling return results;
81ded66d0fSJason Ling }
82ded66d0fSJason Ling
writeMeta(const std::vector<std::uint8_t> &)83*b487eb47SWilly Tu bool PciDataHandler::writeMeta(const std::vector<std::uint8_t>&)
84ded66d0fSJason Ling {
85ded66d0fSJason Ling /* PCI handler doesn't require configuration write, only read. */
86ded66d0fSJason Ling return false;
87ded66d0fSJason Ling }
88ded66d0fSJason Ling
readMeta()89ded66d0fSJason Ling std::vector<std::uint8_t> PciDataHandler::readMeta()
90ded66d0fSJason Ling {
91ded66d0fSJason Ling /* PCI handler does require returning a configuration from read. */
92ded66d0fSJason Ling struct PciConfigResponse reply;
93ded66d0fSJason Ling reply.address = regionAddress;
94ded66d0fSJason Ling
95ded66d0fSJason Ling std::vector<std::uint8_t> bytes;
96ded66d0fSJason Ling bytes.resize(sizeof(reply));
97ded66d0fSJason Ling std::memcpy(bytes.data(), &reply, sizeof(reply));
98ded66d0fSJason Ling
99ded66d0fSJason Ling return bytes;
100ded66d0fSJason Ling }
101ded66d0fSJason Ling
102ded66d0fSJason Ling } // namespace ipmi_flash
103