astlpc: Consolidate direct vs indirect LPC access
Use helpers to wrap up LPC accessors so we're not littering the code
with conditional checks for direct or indirect access. As a result, drop
the priv_hdr pointer from struct mctp_binding_astlpc as we're utilising
the buffers provided by the caller, which in turn removes a heap
allocation.
Change-Id: Iab9ca4295879a3f3a0209fb23163c0383476c223
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/tests/test_astlpc.c b/tests/test_astlpc.c
index 772ba26..7a2b9d9 100644
--- a/tests/test_astlpc.c
+++ b/tests/test_astlpc.c
@@ -118,7 +118,8 @@
return 0;
}
-int mctp_astlpc_mmio_lpc_write(void *data, void *buf, long offset, size_t len)
+int mctp_astlpc_mmio_lpc_write(void *data, const void *buf, long offset,
+ size_t len)
{
struct mctp_binding_astlpc_mmio *mmio = binding_to_mmio(data);
@@ -150,7 +151,12 @@
test->count++;
}
-static const struct mctp_binding_astlpc_ops mctp_binding_astlpc_mmio_ops = {
+static const struct mctp_binding_astlpc_ops astlpc_direct_mmio_ops = {
+ .kcs_read = mctp_astlpc_mmio_kcs_read,
+ .kcs_write = mctp_astlpc_mmio_kcs_write,
+};
+
+static const struct mctp_binding_astlpc_ops astlpc_indirect_mmio_ops = {
.kcs_read = mctp_astlpc_mmio_kcs_read,
.kcs_write = mctp_astlpc_mmio_kcs_write,
.lpc_read = mctp_astlpc_mmio_lpc_read,
@@ -158,8 +164,7 @@
};
static void endpoint_init(struct astlpc_endpoint *ep, mctp_eid_t eid,
- uint8_t mode, uint8_t (*kcs)[2], void *lpc_mem,
- size_t lpc_size)
+ uint8_t mode, uint8_t (*kcs)[2], void *lpc_mem)
{
/*
* Configure the direction of the KCS interface so we know whether to
@@ -173,13 +178,9 @@
/* Inject KCS registers */
ep->mmio.kcs = kcs;
- /* Inject the heap allocation as the LPC mapping */
- ep->mmio.lpc_size = lpc_size;
- ep->mmio.lpc = lpc_mem;
-
/* Initialise the binding */
ep->astlpc = mctp_astlpc_init(mode, MCTP_BTU, lpc_mem,
- &mctp_binding_astlpc_mmio_ops, &ep->mmio);
+ &astlpc_direct_mmio_ops, &ep->mmio);
mctp_register_bus(ep->mctp, &ep->astlpc->binding, eid);
}
@@ -192,18 +193,16 @@
static void network_init(struct astlpc_test *ctx)
{
- const size_t lpc_size = 1 * 1024 * 1024;
-
- ctx->lpc_mem = calloc(1, lpc_size);
+ ctx->lpc_mem = calloc(1, 1 * 1024 * 1024);
assert(ctx->lpc_mem);
/* BMC initialisation */
endpoint_init(&ctx->bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, &ctx->kcs,
- ctx->lpc_mem, lpc_size);
+ ctx->lpc_mem);
/* Host initialisation */
endpoint_init(&ctx->host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, &ctx->kcs,
- ctx->lpc_mem, lpc_size);
+ ctx->lpc_mem);
/* BMC processes host channel init request, alerts host */
mctp_astlpc_poll(ctx->bmc.astlpc);
@@ -366,7 +365,7 @@
/* Initialise the binding */
astlpc = mctp_astlpc_init(MCTP_BINDING_ASTLPC_MODE_HOST, MCTP_BTU, NULL,
- &mctp_binding_astlpc_mmio_ops, &mmio);
+ &astlpc_direct_mmio_ops, &mmio);
/* Register the binding to trigger the start-up sequence */
rc = mctp_register_bus(mctp, &astlpc->binding, 8);
@@ -382,24 +381,20 @@
{
struct astlpc_endpoint bmc, host;
uint8_t kcs[2] = { 0 };
- size_t lpc_size;
void *lpc_mem;
/* Test harness initialisation */
- lpc_size = 1 * 1024 * 1024;
- lpc_mem = calloc(1, lpc_size);
+ lpc_mem = calloc(1, 1 * 1024 * 1024);
assert(lpc_mem);
/* BMC initialisation */
- endpoint_init(&bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, &kcs, lpc_mem,
- lpc_size);
+ endpoint_init(&bmc, 8, MCTP_BINDING_ASTLPC_MODE_BMC, &kcs, lpc_mem);
/* Verify the BMC binding was initialised */
assert(kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_BMC_READY);
/* Host initialisation */
- endpoint_init(&host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, &kcs, lpc_mem,
- lpc_size);
+ endpoint_init(&host, 9, MCTP_BINDING_ASTLPC_MODE_HOST, &kcs, lpc_mem);
/* Host sends channel init command */
assert(kcs[MCTP_ASTLPC_KCS_REG_STATUS] & KCS_STATUS_IBF);
@@ -421,6 +416,72 @@
free(lpc_mem);
}
+static void astlpc_test_simple_indirect_message_bmc_to_host(void)
+{
+ struct astlpc_test ctx = { 0 };
+ uint8_t kcs[2] = { 0 };
+ uint8_t msg[MCTP_BTU];
+ int rc;
+
+ ctx.lpc_mem = calloc(1, LPC_WIN_SIZE);
+ assert(ctx.lpc_mem);
+
+ /* Test message data */
+ memset(&msg[0], 0x5a, MCTP_BTU);
+
+ /* Manually set up the network so we can inject the indirect ops */
+
+ /* BMC initialisation */
+ ctx.bmc.mmio.bmc = true;
+ ctx.bmc.mctp = mctp_init();
+ assert(ctx.bmc.mctp);
+ ctx.bmc.mmio.kcs = &kcs;
+ ctx.bmc.mmio.lpc = ctx.lpc_mem;
+ ctx.bmc.mmio.lpc_size = LPC_WIN_SIZE;
+ ctx.bmc.astlpc =
+ mctp_astlpc_init(MCTP_BINDING_ASTLPC_MODE_BMC, MCTP_BTU, NULL,
+ &astlpc_indirect_mmio_ops, &ctx.bmc.mmio);
+ mctp_register_bus(ctx.bmc.mctp, &ctx.bmc.astlpc->binding, 8);
+
+ /* Host initialisation */
+ ctx.host.mmio.bmc = false;
+ ctx.host.mctp = mctp_init();
+ assert(ctx.host.mctp);
+ ctx.host.mmio.kcs = &kcs;
+ ctx.host.mmio.lpc = ctx.lpc_mem;
+ ctx.host.mmio.lpc_size = LPC_WIN_SIZE;
+ ctx.host.astlpc =
+ mctp_astlpc_init(MCTP_BINDING_ASTLPC_MODE_HOST, MCTP_BTU, NULL,
+ &astlpc_indirect_mmio_ops, &ctx.host.mmio);
+ mctp_register_bus(ctx.host.mctp, &ctx.host.astlpc->binding, 9);
+
+ /* BMC processes host channel init request, alerts host */
+ mctp_astlpc_poll(ctx.bmc.astlpc);
+
+ /* Host dequeues channel init result */
+ mctp_astlpc_poll(ctx.host.astlpc);
+
+ ctx.msg = &msg[0];
+ ctx.count = 0;
+ mctp_set_rx_all(ctx.host.mctp, rx_message, &ctx);
+
+ /* BMC sends the single-packet message */
+ rc = mctp_message_tx(ctx.bmc.mctp, 9, msg, sizeof(msg));
+ assert(rc == 0);
+
+ /* Host receives the single-packet message */
+ rc = mctp_astlpc_poll(ctx.host.astlpc);
+ assert(rc == 0);
+ assert(ctx.count == 1);
+
+ /* BMC dequeues ownership hand-over and sends the queued packet */
+ rc = mctp_astlpc_poll(ctx.bmc.astlpc);
+ assert(rc == 0);
+
+ /* Can still tear-down the network in the normal fashion */
+ network_destroy(&ctx);
+}
+
/* clang-format off */
#define TEST_CASE(test) { #test, test }
static const struct {
@@ -432,6 +493,7 @@
TEST_CASE(astlpc_test_simple_message_bmc_to_host),
TEST_CASE(astlpc_test_simple_message_host_to_bmc),
TEST_CASE(astlpc_test_packetised_message_bmc_to_host),
+ TEST_CASE(astlpc_test_simple_indirect_message_bmc_to_host)
};
/* clang-format on */