blob: 87bae3bb84bb9997c3ab392e2dd660e0bff1ab09 [file] [log] [blame]
Andrew Jeffery4fe996c2018-02-27 12:16:48 +10301/* SPDX-License-Identifier: Apache-2.0 */
2/* Copyright (C) 2018 IBM Corp. */
Ratan Guptac0ef9872017-06-06 14:31:37 +05303#pragma once
4
Andrew Jefferyad343102018-02-28 00:35:50 +10305extern "C" {
6#include "mbox.h"
7};
8
Ratan Guptac0ef9872017-06-06 14:31:37 +05309#include "mboxd_pnor_partition_table.h"
Andrew Jefferyad343102018-02-28 00:35:50 +103010#include "pnor_partition_table.hpp"
Ratan Guptac0ef9872017-06-06 14:31:37 +053011#include <fcntl.h>
12#include <string>
13#include <unistd.h>
14#include <experimental/filesystem>
15
16namespace openpower
17{
18namespace file
19{
20
21class Descriptor
22{
Andrew Jefferyf34db312018-03-09 15:27:03 +103023 private:
24 /** default value */
25 int fd = -1;
Ratan Guptac0ef9872017-06-06 14:31:37 +053026
Andrew Jefferyf34db312018-03-09 15:27:03 +103027 public:
28 Descriptor() = default;
29 Descriptor(const Descriptor&) = delete;
30 Descriptor& operator=(const Descriptor&) = delete;
31 Descriptor(Descriptor&&) = delete;
32 Descriptor& operator=(Descriptor&&) = delete;
Ratan Guptac0ef9872017-06-06 14:31:37 +053033
Andrew Jefferyf34db312018-03-09 15:27:03 +103034 Descriptor(int fd) : fd(fd)
35 {
36 }
Ratan Guptac0ef9872017-06-06 14:31:37 +053037
Andrew Jefferyf34db312018-03-09 15:27:03 +103038 ~Descriptor()
39 {
40 if (fd >= 0)
Ratan Guptac0ef9872017-06-06 14:31:37 +053041 {
Andrew Jefferyf34db312018-03-09 15:27:03 +103042 close(fd);
Ratan Guptac0ef9872017-06-06 14:31:37 +053043 }
Andrew Jefferyf34db312018-03-09 15:27:03 +103044 }
Ratan Guptac0ef9872017-06-06 14:31:37 +053045
Andrew Jefferyf34db312018-03-09 15:27:03 +103046 int operator()() const
47 {
48 return fd;
49 }
Ratan Guptac0ef9872017-06-06 14:31:37 +053050
Andrew Jefferyf34db312018-03-09 15:27:03 +103051 void set(int descriptor)
52 {
53 fd = descriptor;
54 }
Ratan Guptac0ef9872017-06-06 14:31:37 +053055};
56
Andrew Jefferyf34db312018-03-09 15:27:03 +103057} // namespace file
Ratan Guptac0ef9872017-06-06 14:31:37 +053058
59namespace virtual_pnor
60{
61
62namespace fs = std::experimental::filesystem;
63
64enum class ReturnCode : uint8_t
65{
66 FILE_NOT_FOUND = 0,
67 PARTITION_NOT_FOUND = 1,
68 PARTITION_READ_ONLY = 2,
69 FILE_OPEN_FAILURE = 3,
70 SUCCESS = 4,
71};
72
73class Request
74{
Andrew Jefferyf34db312018-03-09 15:27:03 +103075 public:
Andrew Jefferyad343102018-02-28 00:35:50 +103076 /** @brief Construct a flash access request
77 *
78 * @param[in] ctx - The mbox context used to process the request
79 * @param[in] offset - The absolute offset into the flash device as
80 * provided by the mbox message associated with the
81 * request
82 *
83 * The class does not take ownership of the ctx pointer. The lifetime of
84 * the ctx pointer must strictly exceed the lifetime of the class
85 * instance.
86 */
87 Request(struct mbox_context* ctx, size_t offset) :
88 ctx(ctx), partition(ctx->vpnor->table->partition(offset)),
89 base(partition.data.base << ctx->block_size_shift),
90 offset(offset - base)
91 {
92 }
Andrew Jefferyf34db312018-03-09 15:27:03 +103093 Request(const Request&) = delete;
94 Request& operator=(const Request&) = delete;
95 Request(Request&&) = default;
96 Request& operator=(Request&&) = default;
97 ~Request() = default;
Ratan Guptac0ef9872017-06-06 14:31:37 +053098
Andrew Jefferyad343102018-02-28 00:35:50 +103099 ssize_t read(void* dst, size_t len)
100 {
101 return fulfil(dst, len, O_RDONLY);
102 }
Ratan Guptac0ef9872017-06-06 14:31:37 +0530103
Andrew Jefferyad343102018-02-28 00:35:50 +1030104 ssize_t write(void* dst, size_t len)
105 {
106 return fulfil(dst, len, O_RDWR);
107 }
108
109 private:
110 /** @brief Returns the partition file path associated with the offset.
Andrew Jefferyf34db312018-03-09 15:27:03 +1030111 *
Andrew Jefferyad343102018-02-28 00:35:50 +1030112 * The search strategy for the partition file depends on the value of the
113 * flags parameter.
Andrew Jefferyf34db312018-03-09 15:27:03 +1030114 *
Andrew Jefferyad343102018-02-28 00:35:50 +1030115 * For the O_RDONLY case:
Andrew Jefferyf34db312018-03-09 15:27:03 +1030116 *
117 * 1. Depending on the partition type,tries to open the file
118 * from the associated partition(RW/PRSV/RO).
119 * 1a. if file not found in the corresponding
120 * partition(RW/PRSV/RO) then tries to read the file from
121 * the read only partition.
122 * 1b. if the file not found in the read only partition then
123 * throw exception.
124 *
Andrew Jefferyad343102018-02-28 00:35:50 +1030125 * For the O_RDWR case:
Andrew Jefferyf34db312018-03-09 15:27:03 +1030126 *
127 * 1. Depending on the partition type tries to open the file
128 * from the associated partition.
129 * 1a. if file not found in the corresponding partition(RW/PRSV)
130 * then copy the file from the read only partition to the (RW/PRSV)
131 * partition depending on the partition type.
132 * 1b. if the file not found in the read only partition then throw
Andrew Jefferyad343102018-02-28 00:35:50 +1030133 * exception.
Andrew Jefferyf34db312018-03-09 15:27:03 +1030134 *
Andrew Jefferyad343102018-02-28 00:35:50 +1030135 * @param[in] flags - The flags that will be used to open the file. Must
136 * be one of O_RDONLY or O_RDWR.
137 *
138 * Post-condition: The file described by the returned path exists
139 *
140 * Throws: std::filesystem_error, std::bad_alloc
Andrew Jefferyf34db312018-03-09 15:27:03 +1030141 */
Andrew Jefferyad343102018-02-28 00:35:50 +1030142 std::experimental::filesystem::path getPartitionFilePath(int flags);
143
144 /** @brief Fill dst with the content of the partition relative to offset.
145 *
146 * @param[in] offset - The pnor offset(bytes).
147 * @param[out] dst - The buffer to fill with partition data
148 * @param[in] len - The length of the destination buffer
149 */
150 ssize_t fulfil(void* dst, size_t len, int flags);
151
152 struct mbox_context* ctx;
153 const pnor_partition& partition;
154 size_t base;
155 size_t offset;
Ratan Guptac0ef9872017-06-06 14:31:37 +0530156};
157
Andrew Jefferyf34db312018-03-09 15:27:03 +1030158} // namespace virtual_pnor
159} // namespace openpower