master
c 99 lines 2.46 KB
Raw
1 /*
2 * Call Logical Processor (CLP) architecture
3 *
4 * Copyright 2025 IBM Corp.
5 * Author(s): Jared Rossi <jrossi@linux.ibm.com>
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "clp.h"
11 #include <stdio.h>
12 #include <string.h>
13
14 int clp_pci(void *data)
15 {
16 struct { uint8_t _[CLP_BLK_SIZE]; } *req = data;
17 int cc = 3;
18
19 asm volatile (
20 " .insn rrf,0xb9a00000,0,%[req],0,2\n"
21 " ipm %[cc]\n"
22 " srl %[cc],28\n"
23 : [cc] "+d" (cc), "+m" (*req)
24 : [req] "a" (req)
25 : "cc");
26 if (cc) {
27 printf("CLP returned with non-zero condition code %d\n", cc);
28 }
29 return cc;
30 }
31
32 /*
33 * Get the PCI function entry for a given function ID
34 * Return 0 on success, 1 if the FID is not found, or a negative RC on error
35 */
36 int find_pci_function(uint32_t fid, ClpFhListEntry *entry)
37 {
38 int count = 0;
39 int limit = PCI_MAX_FUNCTIONS;
40 ClpReqRspListPci rrb;
41
42 rrb.request.hdr.len = sizeof(ClpReqListPci);
43 rrb.request.hdr.cmd = 0x02;
44 rrb.request.resume_token = 0;
45 rrb.response.hdr.len = sizeof(ClpRspListPci);
46
47 do {
48 if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) {
49 puts("Failed to list PCI functions");
50 return -1;
51 }
52
53 /* Resume token set when max entries are returned */
54 if (rrb.response.resume_token) {
55 count = CLP_FH_LIST_NR_ENTRIES;
56 rrb.request.resume_token = rrb.response.resume_token;
57 } else {
58 count = (rrb.response.hdr.len - 32) / sizeof(ClpFhListEntry);
59 }
60
61 limit -= count;
62
63 for (int i = 0; i < count; i++) {
64 if (rrb.response.fh_list[i].fid == fid) {
65 memcpy(entry, &rrb.response.fh_list[i], sizeof(ClpFhListEntry));
66 return 0;
67 }
68 }
69
70 } while (rrb.request.resume_token && limit > 0);
71
72 puts("No function entry found for FID!");
73
74 return 1;
75 }
76
77 /*
78 * Enable the PCI function associated with a given handle
79 * Return 0 on success or a negative RC on error
80 */
81 int enable_pci_function(uint32_t *fhandle)
82 {
83 ClpReqRspSetPci rrb;
84
85 rrb.request.hdr.len = sizeof(ClpReqSetPci);
86 rrb.request.hdr.cmd = 0x05;
87 rrb.request.fh = *fhandle;
88 rrb.request.oc = 0;
89 rrb.request.ndas = 1;
90 rrb.response.hdr.len = sizeof(ClpRspSetPci);
91
92 if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) {
93 puts("Failed to enable PCI function");
94 return -1;
95 }
96
97 *fhandle = rrb.response.fh;
98 return 0;
99 }