xref: /openbmc/linux/tools/crypto/ccp/dbc_cli.py (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1*f40d42f1SMario Limonciello#!/usr/bin/python3
2*f40d42f1SMario Limonciello# SPDX-License-Identifier: GPL-2.0
3*f40d42f1SMario Limoncielloimport argparse
4*f40d42f1SMario Limoncielloimport binascii
5*f40d42f1SMario Limoncielloimport os
6*f40d42f1SMario Limoncielloimport errno
7*f40d42f1SMario Limonciellofrom dbc import *
8*f40d42f1SMario Limonciello
9*f40d42f1SMario LimoncielloERRORS = {
10*f40d42f1SMario Limonciello    errno.EACCES: "Access is denied",
11*f40d42f1SMario Limonciello    errno.E2BIG: "Excess data provided",
12*f40d42f1SMario Limonciello    errno.EINVAL: "Bad parameters",
13*f40d42f1SMario Limonciello    errno.EAGAIN: "Bad state",
14*f40d42f1SMario Limonciello    errno.ENOENT: "Not implemented or message failure",
15*f40d42f1SMario Limonciello    errno.EBUSY: "Busy",
16*f40d42f1SMario Limonciello    errno.ENFILE: "Overflow",
17*f40d42f1SMario Limonciello    errno.EPERM: "Signature invalid",
18*f40d42f1SMario Limonciello}
19*f40d42f1SMario Limonciello
20*f40d42f1SMario Limonciellomessages = {
21*f40d42f1SMario Limonciello    "get-fmax-cap": PARAM_GET_FMAX_CAP,
22*f40d42f1SMario Limonciello    "set-fmax-cap": PARAM_SET_FMAX_CAP,
23*f40d42f1SMario Limonciello    "get-power-cap": PARAM_GET_PWR_CAP,
24*f40d42f1SMario Limonciello    "set-power-cap": PARAM_SET_PWR_CAP,
25*f40d42f1SMario Limonciello    "get-graphics-mode": PARAM_GET_GFX_MODE,
26*f40d42f1SMario Limonciello    "set-graphics-mode": PARAM_SET_GFX_MODE,
27*f40d42f1SMario Limonciello    "get-current-temp": PARAM_GET_CURR_TEMP,
28*f40d42f1SMario Limonciello    "get-fmax-max": PARAM_GET_FMAX_MAX,
29*f40d42f1SMario Limonciello    "get-fmax-min": PARAM_GET_FMAX_MIN,
30*f40d42f1SMario Limonciello    "get-soc-power-max": PARAM_GET_SOC_PWR_MAX,
31*f40d42f1SMario Limonciello    "get-soc-power-min": PARAM_GET_SOC_PWR_MIN,
32*f40d42f1SMario Limonciello    "get-soc-power-cur": PARAM_GET_SOC_PWR_CUR,
33*f40d42f1SMario Limonciello}
34*f40d42f1SMario Limonciello
35*f40d42f1SMario Limonciello
36*f40d42f1SMario Limonciellodef _pretty_buffer(ba):
37*f40d42f1SMario Limonciello    return str(binascii.hexlify(ba, " "))
38*f40d42f1SMario Limonciello
39*f40d42f1SMario Limonciello
40*f40d42f1SMario Limonciellodef parse_args():
41*f40d42f1SMario Limonciello    parser = argparse.ArgumentParser(
42*f40d42f1SMario Limonciello        description="Dynamic Boost control command line interface"
43*f40d42f1SMario Limonciello    )
44*f40d42f1SMario Limonciello    parser.add_argument(
45*f40d42f1SMario Limonciello        "command",
46*f40d42f1SMario Limonciello        choices=["get-nonce", "get-param", "set-param", "set-uid"],
47*f40d42f1SMario Limonciello        help="Command to send",
48*f40d42f1SMario Limonciello    )
49*f40d42f1SMario Limonciello    parser.add_argument("--device", default="/dev/dbc", help="Device to operate")
50*f40d42f1SMario Limonciello    parser.add_argument("--signature", help="File containing signature for command")
51*f40d42f1SMario Limonciello    parser.add_argument("--message", choices=messages.keys(), help="Message index")
52*f40d42f1SMario Limonciello    parser.add_argument("--data", help="Argument to pass to message")
53*f40d42f1SMario Limonciello    parser.add_argument("--uid", help="File containing UID to pass")
54*f40d42f1SMario Limonciello    return parser.parse_args()
55*f40d42f1SMario Limonciello
56*f40d42f1SMario Limonciello
57*f40d42f1SMario Limonciellodef pretty_error(code):
58*f40d42f1SMario Limonciello    if code in ERRORS:
59*f40d42f1SMario Limonciello        print(ERRORS[code])
60*f40d42f1SMario Limonciello    else:
61*f40d42f1SMario Limonciello        print("failed with return code %d" % code)
62*f40d42f1SMario Limonciello
63*f40d42f1SMario Limonciello
64*f40d42f1SMario Limoncielloif __name__ == "__main__":
65*f40d42f1SMario Limonciello    args = parse_args()
66*f40d42f1SMario Limonciello    data = 0
67*f40d42f1SMario Limonciello    sig = None
68*f40d42f1SMario Limonciello    uid = None
69*f40d42f1SMario Limonciello    if not os.path.exists(args.device):
70*f40d42f1SMario Limonciello        raise IOError("Missing device {device}".format(device=args.device))
71*f40d42f1SMario Limonciello    if args.signature:
72*f40d42f1SMario Limonciello        if not os.path.exists(args.signature):
73*f40d42f1SMario Limonciello            raise ValueError("Invalid signature file %s" % args.signature)
74*f40d42f1SMario Limonciello        with open(args.signature, "rb") as f:
75*f40d42f1SMario Limonciello            sig = f.read()
76*f40d42f1SMario Limonciello        if len(sig) != DBC_SIG_SIZE:
77*f40d42f1SMario Limonciello            raise ValueError(
78*f40d42f1SMario Limonciello                "Invalid signature length %d (expected %d)" % (len(sig), DBC_SIG_SIZE)
79*f40d42f1SMario Limonciello            )
80*f40d42f1SMario Limonciello    if args.uid:
81*f40d42f1SMario Limonciello        if not os.path.exists(args.uid):
82*f40d42f1SMario Limonciello            raise ValueError("Invalid uid file %s" % args.uid)
83*f40d42f1SMario Limonciello        with open(args.uid, "rb") as f:
84*f40d42f1SMario Limonciello            uid = f.read()
85*f40d42f1SMario Limonciello        if len(uid) != DBC_UID_SIZE:
86*f40d42f1SMario Limonciello            raise ValueError(
87*f40d42f1SMario Limonciello                "Invalid UID length %d (expected %d)" % (len(uid), DBC_UID_SIZE)
88*f40d42f1SMario Limonciello            )
89*f40d42f1SMario Limonciello    if args.data:
90*f40d42f1SMario Limonciello        try:
91*f40d42f1SMario Limonciello            data = int(args.data, 10)
92*f40d42f1SMario Limonciello        except ValueError:
93*f40d42f1SMario Limonciello            data = int(args.data, 16)
94*f40d42f1SMario Limonciello
95*f40d42f1SMario Limonciello    with open(args.device) as d:
96*f40d42f1SMario Limonciello        if args.command == "get-nonce":
97*f40d42f1SMario Limonciello            try:
98*f40d42f1SMario Limonciello                nonce = get_nonce(d, sig)
99*f40d42f1SMario Limonciello                print("Nonce: %s" % _pretty_buffer(bytes(nonce)))
100*f40d42f1SMario Limonciello            except OSError as e:
101*f40d42f1SMario Limonciello                pretty_error(e.errno)
102*f40d42f1SMario Limonciello        elif args.command == "set-uid":
103*f40d42f1SMario Limonciello            try:
104*f40d42f1SMario Limonciello                result = set_uid(d, uid, sig)
105*f40d42f1SMario Limonciello                if result:
106*f40d42f1SMario Limonciello                    print("Set UID")
107*f40d42f1SMario Limonciello            except OSError as e:
108*f40d42f1SMario Limonciello                pretty_error(e.errno)
109*f40d42f1SMario Limonciello        elif args.command == "get-param":
110*f40d42f1SMario Limonciello            if not args.message or args.message.startswith("set"):
111*f40d42f1SMario Limonciello                raise ValueError("Invalid message %s" % args.message)
112*f40d42f1SMario Limonciello            try:
113*f40d42f1SMario Limonciello                param, signature = process_param(d, messages[args.message], sig)
114*f40d42f1SMario Limonciello                print(
115*f40d42f1SMario Limonciello                    "Parameter: {par}, response signature {sig}".format(
116*f40d42f1SMario Limonciello                        par=param,
117*f40d42f1SMario Limonciello                        sig=_pretty_buffer(bytes(signature)),
118*f40d42f1SMario Limonciello                    )
119*f40d42f1SMario Limonciello                )
120*f40d42f1SMario Limonciello            except OSError as e:
121*f40d42f1SMario Limonciello                pretty_error(e.errno)
122*f40d42f1SMario Limonciello        elif args.command == "set-param":
123*f40d42f1SMario Limonciello            if not args.message or args.message.startswith("get"):
124*f40d42f1SMario Limonciello                raise ValueError("Invalid message %s" % args.message)
125*f40d42f1SMario Limonciello            try:
126*f40d42f1SMario Limonciello                param, signature = process_param(d, messages[args.message], sig, data)
127*f40d42f1SMario Limonciello                print(
128*f40d42f1SMario Limonciello                    "Parameter: {par}, response signature {sig}".format(
129*f40d42f1SMario Limonciello                        par=param,
130*f40d42f1SMario Limonciello                        sig=_pretty_buffer(bytes(signature)),
131*f40d42f1SMario Limonciello                    )
132*f40d42f1SMario Limonciello                )
133*f40d42f1SMario Limonciello            except OSError as e:
134*f40d42f1SMario Limonciello                pretty_error(e.errno)
135