blob: 4e4e149e8b0cf8b0f8eb196510942d53004badcf [file] [log] [blame]
Deepak Kodihalli6c2fa902017-05-01 06:36:02 -05001/*
2 * Mailbox Daemon Window Helpers
3 *
4 * Copyright 2017 IBM
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
Ratan Gupta8441a392017-05-05 21:42:53 +053020#include <fcntl.h>
Deepak Kodihalli6c2fa902017-05-01 06:36:02 -050021#include <stdint.h>
22#include <stdlib.h>
23#include <syslog.h>
Ratan Gupta8441a392017-05-05 21:42:53 +053024#include <sys/mman.h>
25#include <unistd.h>
Deepak Kodihalli6c2fa902017-05-01 06:36:02 -050026
27extern "C" {
28#include "common.h"
29}
30
Ratan Gupta8441a392017-05-05 21:42:53 +053031#include "config.h"
Deepak Kodihalli6c2fa902017-05-01 06:36:02 -050032#include "mboxd_flash.h"
33#include "mboxd_pnor_partition_table.h"
34
Ratan Gupta8441a392017-05-05 21:42:53 +053035#include <string>
36#include <exception>
37#include <stdexcept>
38#include <experimental/filesystem>
39
Deepak Kodihalli6c2fa902017-05-01 06:36:02 -050040/*
41 * copy_flash() - Copy data from the virtual pnor into a provided buffer
42 * @context: The mbox context pointer
43 * @offset: The pnor offset to copy from (bytes)
44 * @mem: The buffer to copy into (must be of atleast 'size' bytes)
45 * @size: The number of bytes to copy
46 *
47 * Return: 0 on success otherwise negative error code
48 */
49int copy_flash(struct mbox_context* context, uint32_t offset, void* mem,
50 uint32_t size)
51{
Ratan Gupta8441a392017-05-05 21:42:53 +053052 namespace fs = std::experimental::filesystem;
Deepak Kodihalli6c2fa902017-05-01 06:36:02 -050053 int rc = 0;
54
55 MSG_DBG("Copy virtual pnor to %p for size 0x%.8x from offset 0x%.8x\n",
56 mem, size, offset);
57
58 /* The virtual PNOR partition table starts at offset 0 in the virtual
59 * pnor image. Check if host asked for an offset that lies within the
60 * partition table.
61 */
Ratan Gupta8441a392017-05-05 21:42:53 +053062 try
Deepak Kodihalli6c2fa902017-05-01 06:36:02 -050063 {
Ratan Gupta8441a392017-05-05 21:42:53 +053064 size_t sz =
65 vpnor_get_partition_table_size(context) << context->block_size_shift;
66 if (offset < sz)
67 {
68 const struct pnor_partition_table* table =
69 vpnor_get_partition_table(context);
70 memcpy(mem,
71 ((uint8_t*)table) + offset,
72 min_u32(sz - offset, size));
73 }
74 else
75 {
76 /* Copy from virtual pnor into the window buffer */
77 auto partition = vpnor_get_partition(context, offset);
78 if (!partition)
79 {
80 std::string msg = "Couldn't get the partition info for offset " +
81 offset;
82 throw std::runtime_error(msg);
83 }
Deepak Kodihalli6c2fa902017-05-01 06:36:02 -050084
Ratan Gupta8441a392017-05-05 21:42:53 +053085 fs::path partitionFilePath = context->paths.ro_loc;
86 partitionFilePath /= partition->data.name;
87
88 auto fd = open(partitionFilePath.c_str(), O_RDONLY);
89 if (fd == -1)
90 {
91 throw std::runtime_error("Couldn't open the partition file");
92 }
93
94 auto mapped_mem = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
95 if (mem == MAP_FAILED)
96 {
97 std::string msg = "Failed to map" + partitionFilePath.string() + ":"
98 + strerror(errno);
99 close(fd);
100 throw std::runtime_error(msg);
101 }
102
103 //copy to the reserved memory area
104 memcpy(mem, mapped_mem, size);
105 munmap(mapped_mem, size);
106 close(fd);
107 }
108 }
109 catch (const std::exception& e)
110 {
111 MSG_ERR("%s", e.what());
112 rc = -1;
113 }
Deepak Kodihalli6c2fa902017-05-01 06:36:02 -0500114 return rc;
115}