blob: 3a09c92b58e011b2fb661a8cc69be062e4216f7d [file] [log] [blame]
Deepak Kodihallib6a446f2017-04-29 13:01:49 -05001#include "mboxd_pnor_partition_table.h"
Deepak Kodihalli017e45c2017-07-12 01:06:30 -05002#include "common.h"
Deepak Kodihallib6a446f2017-04-29 13:01:49 -05003#include "mbox.h"
Deepak Kodihalli017e45c2017-07-12 01:06:30 -05004#include "mboxd_flash.h"
Deepak Kodihallib6a446f2017-04-29 13:01:49 -05005#include "pnor_partition_table.hpp"
Deepak Kodihalli64ec3e42017-07-17 06:15:16 -05006#include "config.h"
Deepak Kodihalli6e6aa3a2017-08-28 06:13:43 -05007#include "xyz/openbmc_project/Common/error.hpp"
8#include <phosphor-logging/elog-errors.hpp>
Ratan Gupta3214b512017-05-11 08:58:19 +05309#include <experimental/filesystem>
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050010
11struct vpnor_partition_table
12{
Andrew Jefferyf34db312018-03-09 15:27:03 +103013 openpower::virtual_pnor::partition::Table *table = nullptr;
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050014};
15
Deepak Kodihalli64ec3e42017-07-17 06:15:16 -050016void init_vpnor(struct mbox_context *context)
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050017{
Ratan Gupta3214b512017-05-11 08:58:19 +053018 if (context && !context->vpnor)
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050019 {
Deepak Kodihalli64ec3e42017-07-17 06:15:16 -050020 strcpy(context->paths.ro_loc, PARTITION_FILES_RO_LOC);
21 strcpy(context->paths.rw_loc, PARTITION_FILES_RW_LOC);
22 strcpy(context->paths.prsv_loc, PARTITION_FILES_PRSV_LOC);
Adriana Kobylakc71dfd72017-07-22 11:10:43 -050023 strcpy(context->paths.patch_loc, PARTITION_FILES_PATCH_LOC);
Deepak Kodihalli64ec3e42017-07-17 06:15:16 -050024
Ratan Gupta3214b512017-05-11 08:58:19 +053025 context->vpnor = new vpnor_partition_table;
Andrew Jefferyf34db312018-03-09 15:27:03 +103026 context->vpnor->table = new openpower::virtual_pnor::partition::Table(
27 1 << context->erase_size_shift, context->flash_size);
Ratan Gupta3214b512017-05-11 08:58:19 +053028 }
29}
30
31void vpnor_create_partition_table_from_path(struct mbox_context *context,
32 const char *path)
33{
34 std::experimental::filesystem::path dir(path);
35
36 if (context && !context->vpnor)
37 {
38 context->vpnor = new vpnor_partition_table;
Andrew Jefferyf34db312018-03-09 15:27:03 +103039 context->vpnor->table = new openpower::virtual_pnor::partition::Table(
40 std::move(dir), 1 << context->erase_size_shift,
41 context->flash_size);
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050042 }
43}
44
45size_t vpnor_get_partition_table_size(const struct mbox_context *context)
46{
Andrew Jefferyf34db312018-03-09 15:27:03 +103047 return context && context->vpnor ? context->vpnor->table->size() : 0;
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050048}
49
Andrew Jefferyf34db312018-03-09 15:27:03 +103050const struct pnor_partition_table *
51vpnor_get_partition_table(const struct mbox_context *context)
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050052{
Andrew Jefferyf34db312018-03-09 15:27:03 +103053 return context && context->vpnor ? &(context->vpnor->table->getHostTable())
54 : nullptr;
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050055}
56
Andrew Jefferyf34db312018-03-09 15:27:03 +103057const struct pnor_partition *
58vpnor_get_partition(const struct mbox_context *context, const size_t offset)
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050059{
Andrew Jefferyf34db312018-03-09 15:27:03 +103060 return context && context->vpnor
61 ? &(context->vpnor->table->partition(offset))
62 : nullptr;
Deepak Kodihallib6a446f2017-04-29 13:01:49 -050063}
64
Deepak Kodihalli017e45c2017-07-12 01:06:30 -050065void vpnor_copy_bootloader_partition(const struct mbox_context *context)
66{
67 // The hostboot bootloader has certain size/offset assumptions, so
68 // we need a special partition table here.
69 // It assumes the PNOR is 64M, the TOC size is 32K, the erase block is
70 // 4K, the page size is 4K.
71 // It also assumes the TOC is at the 'end of pnor - toc size - 1 page size'
72 // offset, and first looks for the TOC here, before proceeding to move up
73 // page by page looking for the TOC. So it is optimal to place the TOC at
74 // this offset.
75 constexpr size_t eraseSize = 0x1000;
76 constexpr size_t pageSize = 0x1000;
77 constexpr size_t pnorSize = 0x4000000;
78 constexpr size_t tocMaxSize = 0x8000;
79 constexpr size_t tocStart = pnorSize - tocMaxSize - pageSize;
80 constexpr auto blPartitionName = "HBB";
81
82 openpower::virtual_pnor::partition::Table blTable(eraseSize, pnorSize);
83 vpnor_partition_table vtbl{};
84 vtbl.table = &blTable;
Andrew Jefferyf34db312018-03-09 15:27:03 +103085 struct mbox_context local
86 {
87 };
Deepak Kodihalli017e45c2017-07-12 01:06:30 -050088 local.vpnor = &vtbl;
89 local.block_size_shift = log_2(eraseSize);
90 memcpy(&local.paths, &context->paths, sizeof(local.paths));
91
92 size_t tocOffset = 0;
Deepak Kodihalli7ee307c2017-07-12 03:41:08 -050093 uint32_t tocSize = blTable.size() * eraseSize;
Deepak Kodihalli6e6aa3a2017-08-28 06:13:43 -050094 using namespace phosphor::logging;
95 using namespace sdbusplus::xyz::openbmc_project::Common::Error;
96 try
97 {
98 // Copy TOC
99 copy_flash(&local, tocOffset,
Andrew Jefferyf34db312018-03-09 15:27:03 +1030100 static_cast<uint8_t *>(context->mem) + tocStart, tocSize);
101 const pnor_partition &partition = blTable.partition(blPartitionName);
Deepak Kodihalli6e6aa3a2017-08-28 06:13:43 -0500102 size_t hbbOffset = partition.data.base * eraseSize;
103 uint32_t hbbSize = partition.data.actual;
104 // Copy HBB
105 copy_flash(&local, hbbOffset,
Andrew Jefferyf34db312018-03-09 15:27:03 +1030106 static_cast<uint8_t *>(context->mem) + hbbOffset, hbbSize);
Deepak Kodihalli6e6aa3a2017-08-28 06:13:43 -0500107 }
Andrew Jefferyf34db312018-03-09 15:27:03 +1030108 catch (InternalFailure &e)
Deepak Kodihalli6e6aa3a2017-08-28 06:13:43 -0500109 {
110 commit<InternalFailure>();
111 }
Deepak Kodihalli017e45c2017-07-12 01:06:30 -0500112}
113
Deepak Kodihalli64ec3e42017-07-17 06:15:16 -0500114void destroy_vpnor(struct mbox_context *context)
Deepak Kodihallib6a446f2017-04-29 13:01:49 -0500115{
Andrew Jefferyf34db312018-03-09 15:27:03 +1030116 if (context && context->vpnor)
Deepak Kodihallib6a446f2017-04-29 13:01:49 -0500117 {
118 delete context->vpnor->table;
119 delete context->vpnor;
120 context->vpnor = nullptr;
121 }
122}