blob: dd9e64a4e954e1eeb8a48e8f78c44a75e3a4edf9 [file] [log] [blame]
Andrew Jeffery943aba02018-03-26 15:37:33 +10301#include "config.h"
2
3extern "C" {
4#include "mbox.h"
5#include "mboxd_msg.h"
6};
7
8#include "vpnor/mboxd_msg.hpp"
Andrew Jeffery52a83192018-03-27 10:35:31 +10309#include "vpnor/pnor_partition_table.hpp"
Andrew Jeffery943aba02018-03-26 15:37:33 +103010
11// clang-format off
12const mboxd_mbox_handler vpnor_mbox_handlers[NUM_MBOX_CMDS] =
13{
14 mbox_handle_reset,
15 mbox_handle_mbox_info,
16 mbox_handle_flash_info,
17 mbox_handle_read_window,
18 mbox_handle_close_window,
Andrew Jeffery52a83192018-03-27 10:35:31 +103019 vpnor_handle_write_window,
Andrew Jeffery943aba02018-03-26 15:37:33 +103020 mbox_handle_dirty_window,
21 mbox_handle_flush_window,
22 mbox_handle_ack,
23 mbox_handle_erase_window
24};
25// clang-format on
Andrew Jeffery52a83192018-03-27 10:35:31 +103026
27/* XXX: Maybe this should be a method on a class? */
28static bool vpnor_partition_is_readonly(const pnor_partition& part)
29{
30 return part.data.user.data[1] & PARTITION_READONLY;
31}
32
33int vpnor_handle_write_window(struct mbox_context* context,
34 union mbox_regs* req, struct mbox_msg* resp)
35{
36 size_t offset = get_u16(&req->msg.args[0]);
37 offset <<= context->block_size_shift;
38 try
39 {
40 const pnor_partition& part = context->vpnor->table->partition(offset);
41 if (vpnor_partition_is_readonly(part))
42 {
43 return -MBOX_R_WINDOW_ERROR;
44 }
45 }
46 catch (const openpower::virtual_pnor::UnmappedOffset& e)
47 {
48 /*
49 * Writes to unmapped areas are not meaningful, so deny the request.
50 * This removes the ability for a compromised host to abuse unused
51 * space if any data was to be persisted (which it isn't).
52 */
53 return -MBOX_R_WINDOW_ERROR;
54 }
55
56 /* Defer to the default handler */
57 return mbox_handle_write_window(context, req, resp);
58}