blob: dd08372b767680c576693ae3cb965895491cef61 [file] [log] [blame]
Patrick Ventureb36c0042017-04-05 10:39:04 -07001# Copyright (C) 2017 Google Inc.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15#!/usr/bin/env python
16"""Basic utility for reading and writing registers on an ASPEED BMC.
17
18The values hardcoded are for the ASPEED AST2400.
19"""
20
21import subprocess
22import sys
23
24IO_TOOL = 'devmem'
25PROTECTION_KEY = '0x1E6E2000'
26HWTRAP = '0x1E6E2070'
27# The AST2400 SCU Password (as int for write_register)
28SCU_PASSWORD = 0x1688A8A8
29
30# Bits 13:12
31SPI_MASK = 0xffffcfff
32# Enable SPI Master
33SPI_MASTER = 0x1000
34# Enable SPI Master and SPI Slave to AHB Bridge
35SPI_MASTER_SLAVE = 0x2000
36# Enable SPI Pass-through
37SPI_BYPASS = 0x3000
38
39
40def read_register(address):
41 """Run a tool to read a register value.
42
43 This will convert it to an integer.
44 """
45
46 output = subprocess.check_output([IO_TOOL, address]).replace('\n', '')
47 value = int(output, 16)
48 return value
49
50
51def write_register(address, value):
52 """Run a tool to write the 32-bit register value."""
53
54 subprocess.check_output([IO_TOOL, address, '32', '0x%x' % value])
55 return
56
57
58def set_master(value):
59 """Set Hardware Strapping to SPI Master."""
60
61 print 'Setting to "SPI Master"'
62
63 masked = value & SPI_MASK
64 masked |= SPI_MASTER
65
66 print 'setting: 0x%x' % masked
67 write_register(HWTRAP, masked)
68
69
70def set_ahb_bridge(value):
71 """Set hardware strapping to spi master and spi-slave to ahb."""
72
73 print 'Setting to "SPI Master and SPI Slave to AHB Bridge"'
74 masked = value & SPI_MASK
75 masked |= SPI_MASTER_SLAVE
76
77 print 'setting: 0x%x' % masked
78 write_register(HWTRAP, masked)
79
80
81def set_bypass(value):
82 """Set hardware strappign to spi bypass."""
83
84 print 'Setting to "Enable SPI Pass-through"'
85 masked = value & SPI_MASK
86 masked |= SPI_BYPASS
87
88 print 'setting: 0x%x' % masked
89 write_register(HWTRAP, masked)
90
91
92def usage():
93 """Print usage string."""
94
95 print 'usage: %s master|bridge|bypass' % sys.argv[0]
96 print 'master sets the BMC SPI to Master.'
97 print ('bridge sets the BMC SPI to Master-Slave bridge to AHB (for BIOS ' +
98 'Update).')
99 print 'bypass sets the BMC SPI to Bypass (default).'
100
101
102def main():
103 """Main entry point for execution."""
104
105 if len(sys.argv) != 2:
106 usage()
107 sys.exit(-1)
108
109 ctrl = sys.argv[1].lower()
110 if ctrl not in ('master', 'bridge', 'bypass'):
111 usage()
112 sys.exit(-1)
113
114 locked = False
115 # Check if locked
116 value = read_register(PROTECTION_KEY)
117 if value == 1:
118 print 'Presently unlocked'
119 else:
120 print 'Presently locked'
121 locked = True
122
123 # if Locked we need to unlock it.
124 if locked:
125 write_register(PROTECTION_KEY, SCU_PASSWORD)
126
127 # Read the value.
128 value = read_register(HWTRAP)
129 if value & SPI_BYPASS == SPI_BYPASS:
130 print 'Presently set to bypass'
131 elif value & SPI_MASTER == SPI_MASTER:
132 print 'Presently set to master'
133 elif value & SPI_MASTER_SLAVE == SPI_MASTER_SLAVE:
134 print 'Presently set to master-slave'
135
136 if ctrl == 'master':
137 set_master(value)
138 elif ctrl == 'bridge':
139 set_ahb_bridge(value)
140 elif ctrl == 'bypass':
141 set_bypass(value)
142
143 # We leave it unlocked in case it was locked.
144 # we could lock it.
145 # TODO(venture): lock it by writing any non-password value.
146
147if __name__ == '__main__':
148 main()