mem.c (d3b75029f353c64e1e0e45ba5083cf8679d17f0a) mem.c (e7ad1bf683295024e7a4e09e41015989a004a0f5)
1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright(c) 2021 Intel Corporation. All rights reserved.
3
4#include <linux/platform_device.h>
5#include <linux/mod_devicetable.h>
6#include <linux/module.h>
7#include <linux/delay.h>
8#include <linux/sizes.h>
9#include <linux/bits.h>
10#include <cxlmem.h>
11
12#define LSA_SIZE SZ_128K
1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright(c) 2021 Intel Corporation. All rights reserved.
3
4#include <linux/platform_device.h>
5#include <linux/mod_devicetable.h>
6#include <linux/module.h>
7#include <linux/delay.h>
8#include <linux/sizes.h>
9#include <linux/bits.h>
10#include <cxlmem.h>
11
12#define LSA_SIZE SZ_128K
13#define DEV_SIZE SZ_2G
13#define EFFECT(x) (1U << x)
14
15static struct cxl_cel_entry mock_cel[] = {
16 {
17 .opcode = cpu_to_le16(CXL_MBOX_OP_GET_SUPPORTED_LOGS),
18 .effect = cpu_to_le16(0),
19 },
20 {
21 .opcode = cpu_to_le16(CXL_MBOX_OP_IDENTIFY),
22 .effect = cpu_to_le16(0),
23 },
24 {
25 .opcode = cpu_to_le16(CXL_MBOX_OP_GET_LSA),
26 .effect = cpu_to_le16(0),
27 },
28 {
14#define EFFECT(x) (1U << x)
15
16static struct cxl_cel_entry mock_cel[] = {
17 {
18 .opcode = cpu_to_le16(CXL_MBOX_OP_GET_SUPPORTED_LOGS),
19 .effect = cpu_to_le16(0),
20 },
21 {
22 .opcode = cpu_to_le16(CXL_MBOX_OP_IDENTIFY),
23 .effect = cpu_to_le16(0),
24 },
25 {
26 .opcode = cpu_to_le16(CXL_MBOX_OP_GET_LSA),
27 .effect = cpu_to_le16(0),
28 },
29 {
30 .opcode = cpu_to_le16(CXL_MBOX_OP_GET_PARTITION_INFO),
31 .effect = cpu_to_le16(0),
32 },
33 {
29 .opcode = cpu_to_le16(CXL_MBOX_OP_SET_LSA),
30 .effect = cpu_to_le16(EFFECT(1) | EFFECT(2)),
31 },
32 {
33 .opcode = cpu_to_le16(CXL_MBOX_OP_GET_HEALTH_INFO),
34 .effect = cpu_to_le16(0),
35 },
36};

--- 55 unchanged lines hidden (view full) ---

92
93 memcpy(cmd->payload_out, data + offset, length);
94
95 return 0;
96}
97
98static int mock_id(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd)
99{
34 .opcode = cpu_to_le16(CXL_MBOX_OP_SET_LSA),
35 .effect = cpu_to_le16(EFFECT(1) | EFFECT(2)),
36 },
37 {
38 .opcode = cpu_to_le16(CXL_MBOX_OP_GET_HEALTH_INFO),
39 .effect = cpu_to_le16(0),
40 },
41};

--- 55 unchanged lines hidden (view full) ---

97
98 memcpy(cmd->payload_out, data + offset, length);
99
100 return 0;
101}
102
103static int mock_id(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd)
104{
100 struct platform_device *pdev = to_platform_device(cxlds->dev);
101 struct cxl_mbox_identify id = {
102 .fw_revision = { "mock fw v1 " },
103 .lsa_size = cpu_to_le32(LSA_SIZE),
105 struct cxl_mbox_identify id = {
106 .fw_revision = { "mock fw v1 " },
107 .lsa_size = cpu_to_le32(LSA_SIZE),
104 /* FIXME: Add partition support */
105 .partition_align = cpu_to_le64(0),
108 .partition_align =
109 cpu_to_le64(SZ_256M / CXL_CAPACITY_MULTIPLIER),
110 .total_capacity =
111 cpu_to_le64(DEV_SIZE / CXL_CAPACITY_MULTIPLIER),
106 };
112 };
107 u64 capacity = 0;
108 int i;
109
110 if (cmd->size_out < sizeof(id))
111 return -EINVAL;
112
113
114 if (cmd->size_out < sizeof(id))
115 return -EINVAL;
116
113 for (i = 0; i < 2; i++) {
114 struct resource *res;
117 memcpy(cmd->payload_out, &id, sizeof(id));
115
118
116 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
117 if (!res)
118 break;
119 return 0;
120}
119
121
120 capacity += resource_size(res) / CXL_CAPACITY_MULTIPLIER;
122static int mock_partition_info(struct cxl_dev_state *cxlds,
123 struct cxl_mbox_cmd *cmd)
124{
125 struct cxl_mbox_get_partition_info pi = {
126 .active_volatile_cap =
127 cpu_to_le64(DEV_SIZE / 2 / CXL_CAPACITY_MULTIPLIER),
128 .active_persistent_cap =
129 cpu_to_le64(DEV_SIZE / 2 / CXL_CAPACITY_MULTIPLIER),
130 };
121
131
122 if (le64_to_cpu(id.partition_align))
123 continue;
132 if (cmd->size_out < sizeof(pi))
133 return -EINVAL;
124
134
125 if (res->desc == IORES_DESC_PERSISTENT_MEMORY)
126 id.persistent_capacity = cpu_to_le64(
127 resource_size(res) / CXL_CAPACITY_MULTIPLIER);
128 else
129 id.volatile_capacity = cpu_to_le64(
130 resource_size(res) / CXL_CAPACITY_MULTIPLIER);
131 }
135 memcpy(cmd->payload_out, &pi, sizeof(pi));
132
136
133 id.total_capacity = cpu_to_le64(capacity);
134
135 memcpy(cmd->payload_out, &id, sizeof(id));
136
137 return 0;
138}
139
140static int mock_get_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd)
141{
142 struct cxl_mbox_get_lsa *get_lsa = cmd->payload_in;
143 void *lsa = dev_get_drvdata(cxlds->dev);
144 u32 offset, length;

--- 71 unchanged lines hidden (view full) ---

216 rc = mock_get_log(cxlds, cmd);
217 break;
218 case CXL_MBOX_OP_IDENTIFY:
219 rc = mock_id(cxlds, cmd);
220 break;
221 case CXL_MBOX_OP_GET_LSA:
222 rc = mock_get_lsa(cxlds, cmd);
223 break;
137 return 0;
138}
139
140static int mock_get_lsa(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd)
141{
142 struct cxl_mbox_get_lsa *get_lsa = cmd->payload_in;
143 void *lsa = dev_get_drvdata(cxlds->dev);
144 u32 offset, length;

--- 71 unchanged lines hidden (view full) ---

216 rc = mock_get_log(cxlds, cmd);
217 break;
218 case CXL_MBOX_OP_IDENTIFY:
219 rc = mock_id(cxlds, cmd);
220 break;
221 case CXL_MBOX_OP_GET_LSA:
222 rc = mock_get_lsa(cxlds, cmd);
223 break;
224 case CXL_MBOX_OP_GET_PARTITION_INFO:
225 rc = mock_partition_info(cxlds, cmd);
226 break;
224 case CXL_MBOX_OP_SET_LSA:
225 rc = mock_set_lsa(cxlds, cmd);
226 break;
227 case CXL_MBOX_OP_GET_HEALTH_INFO:
228 rc = mock_health_info(cxlds, cmd);
229 break;
230 default:
231 break;

--- 76 unchanged lines hidden ---
227 case CXL_MBOX_OP_SET_LSA:
228 rc = mock_set_lsa(cxlds, cmd);
229 break;
230 case CXL_MBOX_OP_GET_HEALTH_INFO:
231 rc = mock_health_info(cxlds, cmd);
232 break;
233 default:
234 break;

--- 76 unchanged lines hidden ---