|
12 | 12 | #include <asm/plpar_wrappers.h>
|
13 | 13 |
|
14 | 14 | static void *htm_buf;
|
| 15 | +static void *htm_status_buf; |
15 | 16 | static u32 nodeindex;
|
16 | 17 | static u32 nodalchipindex;
|
17 | 18 | static u32 coreindexonchip;
|
@@ -205,6 +206,53 @@ static int htmstart_get(void *data, u64 *val)
|
205 | 206 | return 0;
|
206 | 207 | }
|
207 | 208 |
|
| 209 | +static ssize_t htmstatus_read(struct file *filp, char __user *ubuf, |
| 210 | + size_t count, loff_t *ppos) |
| 211 | +{ |
| 212 | + void *htm_status_buf = filp->private_data; |
| 213 | + long rc, ret; |
| 214 | + u64 *num_entries; |
| 215 | + u64 to_copy; |
| 216 | + int htmstatus_flag; |
| 217 | + |
| 218 | + /* |
| 219 | + * Invoke H_HTM call with: |
| 220 | + * - operation as htm status (H_HTM_OP_STATUS) |
| 221 | + * - last three values as addr, size and offset |
| 222 | + */ |
| 223 | + rc = htm_hcall_wrapper(nodeindex, nodalchipindex, coreindexonchip, |
| 224 | + htmtype, H_HTM_OP_STATUS, virt_to_phys(htm_status_buf), |
| 225 | + PAGE_SIZE, 0); |
| 226 | + |
| 227 | + ret = htm_return_check(rc); |
| 228 | + if (ret <= 0) { |
| 229 | + pr_debug("H_HTM hcall failed for op: H_HTM_OP_STATUS, returning %ld\n", ret); |
| 230 | + return ret; |
| 231 | + } |
| 232 | + |
| 233 | + /* |
| 234 | + * HTM status buffer, start of buffer + 0x10 gives the |
| 235 | + * number of HTM entries in the buffer. Each nest htm status |
| 236 | + * entry is 0x6 bytes where each core htm status entry is |
| 237 | + * 0x8 bytes. |
| 238 | + * So total count to copy is: |
| 239 | + * 32 bytes (for first 7 fields) + (number of HTM entries * entry size) |
| 240 | + */ |
| 241 | + num_entries = htm_status_buf + 0x10; |
| 242 | + if (htmtype == 0x2) |
| 243 | + htmstatus_flag = 0x8; |
| 244 | + else |
| 245 | + htmstatus_flag = 0x6; |
| 246 | + to_copy = 32 + (be64_to_cpu(*num_entries) * htmstatus_flag); |
| 247 | + return simple_read_from_buffer(ubuf, count, ppos, htm_status_buf, to_copy); |
| 248 | +} |
| 249 | + |
| 250 | +static const struct file_operations htmstatus_fops = { |
| 251 | + .llseek = NULL, |
| 252 | + .read = htmstatus_read, |
| 253 | + .open = simple_open, |
| 254 | +}; |
| 255 | + |
208 | 256 | DEFINE_SIMPLE_ATTRIBUTE(htmconfigure_fops, htmconfigure_get, htmconfigure_set, "%llu\n");
|
209 | 257 | DEFINE_SIMPLE_ATTRIBUTE(htmstart_fops, htmstart_get, htmstart_set, "%llu\n");
|
210 | 258 |
|
@@ -235,6 +283,15 @@ static int htmdump_init_debugfs(void)
|
235 | 283 | debugfs_create_file("htmconfigure", 0600, htmdump_debugfs_dir, NULL, &htmconfigure_fops);
|
236 | 284 | debugfs_create_file("htmstart", 0600, htmdump_debugfs_dir, NULL, &htmstart_fops);
|
237 | 285 |
|
| 286 | + /* Debugfs interface file to present status of HTM */ |
| 287 | + htm_status_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); |
| 288 | + if (!htm_status_buf) { |
| 289 | + pr_err("Failed to allocate htmstatus buf\n"); |
| 290 | + return -ENOMEM; |
| 291 | + } |
| 292 | + |
| 293 | + debugfs_create_file("htmstatus", 0400, htmdump_debugfs_dir, htm_status_buf, &htmstatus_fops); |
| 294 | + |
238 | 295 | return 0;
|
239 | 296 | }
|
240 | 297 |
|
|
0 commit comments