1943aba06SAndrew Jeffery #include "config.h"
2943aba06SAndrew Jeffery 
3943aba06SAndrew Jeffery extern "C" {
4943aba06SAndrew Jeffery #include "mbox.h"
5943aba06SAndrew Jeffery #include "mboxd_msg.h"
6943aba06SAndrew Jeffery };
7943aba06SAndrew Jeffery 
8943aba06SAndrew Jeffery #include "vpnor/mboxd_msg.hpp"
9*52a83196SAndrew Jeffery #include "vpnor/pnor_partition_table.hpp"
10943aba06SAndrew Jeffery 
11943aba06SAndrew Jeffery // clang-format off
12943aba06SAndrew Jeffery const mboxd_mbox_handler vpnor_mbox_handlers[NUM_MBOX_CMDS] =
13943aba06SAndrew Jeffery {
14943aba06SAndrew Jeffery 	mbox_handle_reset,
15943aba06SAndrew Jeffery 	mbox_handle_mbox_info,
16943aba06SAndrew Jeffery 	mbox_handle_flash_info,
17943aba06SAndrew Jeffery 	mbox_handle_read_window,
18943aba06SAndrew Jeffery 	mbox_handle_close_window,
19*52a83196SAndrew Jeffery 	vpnor_handle_write_window,
20943aba06SAndrew Jeffery 	mbox_handle_dirty_window,
21943aba06SAndrew Jeffery 	mbox_handle_flush_window,
22943aba06SAndrew Jeffery 	mbox_handle_ack,
23943aba06SAndrew Jeffery 	mbox_handle_erase_window
24943aba06SAndrew Jeffery };
25943aba06SAndrew Jeffery // clang-format on
26*52a83196SAndrew Jeffery 
27*52a83196SAndrew Jeffery /* XXX: Maybe this should be a method on a class? */
vpnor_partition_is_readonly(const pnor_partition & part)28*52a83196SAndrew Jeffery static bool vpnor_partition_is_readonly(const pnor_partition& part)
29*52a83196SAndrew Jeffery {
30*52a83196SAndrew Jeffery     return part.data.user.data[1] & PARTITION_READONLY;
31*52a83196SAndrew Jeffery }
32*52a83196SAndrew Jeffery 
vpnor_handle_write_window(struct mbox_context * context,union mbox_regs * req,struct mbox_msg * resp)33*52a83196SAndrew Jeffery int vpnor_handle_write_window(struct mbox_context* context,
34*52a83196SAndrew Jeffery                               union mbox_regs* req, struct mbox_msg* resp)
35*52a83196SAndrew Jeffery {
36*52a83196SAndrew Jeffery     size_t offset = get_u16(&req->msg.args[0]);
37*52a83196SAndrew Jeffery     offset <<= context->block_size_shift;
38*52a83196SAndrew Jeffery     try
39*52a83196SAndrew Jeffery     {
40*52a83196SAndrew Jeffery         const pnor_partition& part = context->vpnor->table->partition(offset);
41*52a83196SAndrew Jeffery         if (vpnor_partition_is_readonly(part))
42*52a83196SAndrew Jeffery         {
43*52a83196SAndrew Jeffery             return -MBOX_R_WINDOW_ERROR;
44*52a83196SAndrew Jeffery         }
45*52a83196SAndrew Jeffery     }
46*52a83196SAndrew Jeffery     catch (const openpower::virtual_pnor::UnmappedOffset& e)
47*52a83196SAndrew Jeffery     {
48*52a83196SAndrew Jeffery         /*
49*52a83196SAndrew Jeffery          * Writes to unmapped areas are not meaningful, so deny the request.
50*52a83196SAndrew Jeffery          * This removes the ability for a compromised host to abuse unused
51*52a83196SAndrew Jeffery          * space if any data was to be persisted (which it isn't).
52*52a83196SAndrew Jeffery          */
53*52a83196SAndrew Jeffery         return -MBOX_R_WINDOW_ERROR;
54*52a83196SAndrew Jeffery     }
55*52a83196SAndrew Jeffery 
56*52a83196SAndrew Jeffery     /* Defer to the default handler */
57*52a83196SAndrew Jeffery     return mbox_handle_write_window(context, req, resp);
58*52a83196SAndrew Jeffery }
59