8fb72585d9f1380bf7b7e4f075c75666f6311633
[linux-2.6-microblaze.git] / arch / sparc / kernel / adi_64.c
1 /* adi_64.c: support for ADI (Application Data Integrity) feature on
2  * sparc m7 and newer processors. This feature is also known as
3  * SSM (Silicon Secured Memory).
4  *
5  * Copyright (C) 2016 Oracle and/or its affiliates. All rights reserved.
6  * Author: Khalid Aziz (khalid.aziz@oracle.com)
7  *
8  * This work is licensed under the terms of the GNU GPL, version 2.
9  */
10 #include <linux/init.h>
11 #include <asm/mdesc.h>
12 #include <asm/adi_64.h>
13
14 struct adi_config adi_state;
15
16 /* mdesc_adi_init() : Parse machine description provided by the
17  *      hypervisor to detect ADI capabilities
18  *
19  * Hypervisor reports ADI capabilities of platform in "hwcap-list" property
20  * for "cpu" node. If the platform supports ADI, "hwcap-list" property
21  * contains the keyword "adp". If the platform supports ADI, "platform"
22  * node will contain "adp-blksz", "adp-nbits" and "ue-on-adp" properties
23  * to describe the ADI capabilities.
24  */
25 void __init mdesc_adi_init(void)
26 {
27         struct mdesc_handle *hp = mdesc_grab();
28         const char *prop;
29         u64 pn, *val;
30         int len;
31
32         if (!hp)
33                 goto adi_not_found;
34
35         pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "cpu");
36         if (pn == MDESC_NODE_NULL)
37                 goto adi_not_found;
38
39         prop = mdesc_get_property(hp, pn, "hwcap-list", &len);
40         if (!prop)
41                 goto adi_not_found;
42
43         /*
44          * Look for "adp" keyword in hwcap-list which would indicate
45          * ADI support
46          */
47         adi_state.enabled = false;
48         while (len) {
49                 int plen;
50
51                 if (!strcmp(prop, "adp")) {
52                         adi_state.enabled = true;
53                         break;
54                 }
55
56                 plen = strlen(prop) + 1;
57                 prop += plen;
58                 len -= plen;
59         }
60
61         if (!adi_state.enabled)
62                 goto adi_not_found;
63
64         /* Find the ADI properties in "platform" node. If all ADI
65          * properties are not found, ADI support is incomplete and
66          * do not enable ADI in the kernel.
67          */
68         pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "platform");
69         if (pn == MDESC_NODE_NULL)
70                 goto adi_not_found;
71
72         val = (u64 *) mdesc_get_property(hp, pn, "adp-blksz", &len);
73         if (!val)
74                 goto adi_not_found;
75         adi_state.caps.blksz = *val;
76
77         val = (u64 *) mdesc_get_property(hp, pn, "adp-nbits", &len);
78         if (!val)
79                 goto adi_not_found;
80         adi_state.caps.nbits = *val;
81
82         val = (u64 *) mdesc_get_property(hp, pn, "ue-on-adp", &len);
83         if (!val)
84                 goto adi_not_found;
85         adi_state.caps.ue_on_adi = *val;
86
87         mdesc_release(hp);
88         return;
89
90 adi_not_found:
91         adi_state.enabled = false;
92         adi_state.caps.blksz = 0;
93         adi_state.caps.nbits = 0;
94         if (hp)
95                 mdesc_release(hp);
96 }