Skip to content

Commit 132f008

Browse files
lifenggitacckartben
authored andcommitted
ish build: add new manifest v1.1 support
ISH manifest v1.1 applies to ISH 5.8. Signed-off-by: Li Feng <li1.feng@intel.com>
1 parent 644dd75 commit 132f008

File tree

2 files changed

+235
-3
lines changed

2 files changed

+235
-3
lines changed

soc/intel/intel_ish/utils/build_ish_firmware.cmake

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@
33
# SPDX-License-Identifier: Apache-2.0
44
#
55

6+
if(CONFIG_BOARD_INTEL_ISH_5_8_0)
7+
set(BUILD_ISH_FIRMWARE_SCRIPT "build_ish_firmware_v1p1.py")
8+
set(BUILD_VERSION "5.8.0.0")
9+
set(VERSION_ARG "-v ${BUILD_VERSION}")
10+
else()
11+
set(BUILD_ISH_FIRMWARE_SCRIPT "build_ish_firmware.py")
12+
set(VERSION_ARG "")
13+
endif()
14+
615
if(CONFIG_PM)
716
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
817
COMMAND ${CMAKE_OBJCOPY} -O binary --remove-section=aon
@@ -11,15 +20,17 @@ set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
1120
COMMAND ${CMAKE_OBJCOPY} -O binary --only-section=aon
1221
${ZEPHYR_BINARY_DIR}/${KERNEL_ELF_NAME} ${PROJECT_BINARY_DIR}/ish_aon.bin
1322

14-
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/build_ish_firmware.py
15-
-k ${PROJECT_BINARY_DIR}/ish_kernel.bin
23+
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/${BUILD_ISH_FIRMWARE_SCRIPT}
24+
ARGS -k ${PROJECT_BINARY_DIR}/ish_kernel.bin
1625
-a ${PROJECT_BINARY_DIR}/ish_aon.bin
1726
-o ${PROJECT_BINARY_DIR}/ish_fw.bin
27+
${VERSION_ARG}
1828
)
1929
else()
2030
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
21-
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/build_ish_firmware.py
31+
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/${BUILD_ISH_FIRMWARE_SCRIPT}
2232
ARGS -k ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.bin
2333
-o ${PROJECT_BINARY_DIR}/ish_fw.bin
34+
${VERSION_ARG}
2435
)
2536
endif()
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright 2019 The Chromium OS Authors. All rights reserved.
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
"""Script to pack EC binary with manifest header.
7+
8+
Package ecos main FW binary (kernel) and AON task binary into final EC binary
9+
image with a manifest header, ISH shim loader will parse this header and load
10+
each binaries into right memory location.
11+
"""
12+
13+
import argparse
14+
import os
15+
import struct
16+
17+
MANIFEST_ENTRY_SIZE = 0x80
18+
HEADER_SIZE = 0x1000
19+
HEADER_VER = 0x00010001
20+
PAGE_SIZE = 0x1000
21+
MAIN_FW_ADDR = 0xFF200000
22+
SRAM_BASE_ADDR = MAIN_FW_ADDR
23+
SRAM_BANK_SIZE = 0x00008000
24+
SRAM_BIT_WIDTH = 64
25+
SRAM_SIZE = 0x000A0000
26+
AON_RF_ADDR = 0xFF800000
27+
AON_RF_SIZE = 0x2000
28+
KERN_LOAD_ADDR = MAIN_FW_ADDR
29+
AON_LOAD_ADDR = AON_RF_ADDR
30+
31+
32+
def parseargs():
33+
parser = argparse.ArgumentParser(allow_abbrev=False)
34+
parser.add_argument(
35+
"-k",
36+
"--kernel",
37+
help="EC kernel binary to pack, \
38+
usually ec.RW.bin or ec.RW.flat.",
39+
required=True,
40+
)
41+
parser.add_argument(
42+
"-a",
43+
"--aon",
44+
help="EC aontask binary to pack, \
45+
usually ish_aontask.bin.",
46+
required=False,
47+
)
48+
parser.add_argument("-o", "--output", help="Output flash binary file")
49+
50+
parser.add_argument(
51+
"-v", "--version", help="Specify the version of the EC firmware", required=True
52+
)
53+
54+
return parser.parse_args()
55+
56+
57+
def gen_global_manifest():
58+
"""Returns a binary blob that represents a manifest entry"""
59+
m = bytearray(MANIFEST_ENTRY_SIZE)
60+
61+
args = parseargs()
62+
version_parts = args.version.split('.')
63+
if len(version_parts) != 4:
64+
raise ValueError("Version must be in format major.minor.patch.build")
65+
major, minor, patch, build = map(int, version_parts)
66+
67+
# 4 bytes of ASCII encode ID (little endian)
68+
struct.pack_into('<4s', m, 0, b'ISHG')
69+
# 4 bytes of extension size, fixed 128 (little endian)
70+
struct.pack_into('<I', m, 4, MANIFEST_ENTRY_SIZE)
71+
# 4 bytes of header version, fixed (little endian)
72+
struct.pack_into('<I', m, 8, HEADER_VER)
73+
# 4 bytes of flags (little endian)
74+
struct.pack_into('<I', m, 12, 0)
75+
76+
# 8 bytes of ISH build version (little endian)
77+
struct.pack_into('<I', m, 16, major)
78+
struct.pack_into('<I', m, 18, minor)
79+
struct.pack_into('<I', m, 20, patch)
80+
struct.pack_into('<I', m, 22, build)
81+
# 4 bytes of entry point
82+
struct.pack_into('<I', m, 24, MAIN_FW_ADDR)
83+
84+
# 4 bytes of AON start physical address
85+
struct.pack_into('<I', m, 28, AON_RF_ADDR)
86+
# 4 bytes of AON RF limit
87+
struct.pack_into('<I', m, 32, AON_RF_SIZE)
88+
# 4 bytes of SRAM bank size
89+
struct.pack_into('<I', m, 36, SRAM_BANK_SIZE)
90+
# 4 bytes of SRAM bit width
91+
struct.pack_into('<I', m, 40, SRAM_BIT_WIDTH)
92+
# 4 bytes of SRAM base
93+
struct.pack_into('<I', m, 44, SRAM_BASE_ADDR)
94+
# 4 bytes of SRAM limit
95+
struct.pack_into('<I', m, 48, SRAM_SIZE)
96+
97+
return m
98+
99+
100+
def gen_manifest_end():
101+
"""Returns a binary blob that represents a manifest entry"""
102+
m = bytearray(MANIFEST_ENTRY_SIZE)
103+
104+
# 4 bytes of ASCII encode ID (little endian)
105+
struct.pack_into('<4s', m, 0, b'ISHE')
106+
107+
return m
108+
109+
110+
def gen_module_manifest(ext_id, comp_app_name, code_offset, module_size, load_addr):
111+
"""Returns a binary blob that represents a manifest entry"""
112+
m = bytearray(MANIFEST_ENTRY_SIZE)
113+
114+
# 4 bytes of ASCII encode ID (little endian)
115+
struct.pack_into('<4s', m, 0, ext_id)
116+
# 4 bytes of extension size, fixed 128 (little endian)
117+
struct.pack_into('<I', m, 4, MANIFEST_ENTRY_SIZE)
118+
# 8 bytes of ASCII module name (little endian)
119+
struct.pack_into('<8s', m, 8, comp_app_name)
120+
121+
# 4 bytes of module offset (little endian)
122+
struct.pack_into('<I', m, 16, code_offset)
123+
# 4 bytes of module size (little endian)
124+
struct.pack_into('<I', m, 20, module_size)
125+
# 4 bytes of load offset (little endian)
126+
struct.pack_into('<I', m, 24, 0)
127+
# 4 bytes of load size (little endian)
128+
struct.pack_into('<I', m, 28, module_size)
129+
130+
# 4 bytes of load address (little endian)
131+
struct.pack_into('<I', m, 32, load_addr)
132+
133+
return m
134+
135+
136+
def roundup_page(size):
137+
"""Returns roundup-ed page size from size of bytes"""
138+
return int(size / PAGE_SIZE) + (size % PAGE_SIZE > 0)
139+
140+
141+
def main():
142+
args = parseargs()
143+
print(" Packing EC image file for ISH")
144+
print("args.version", args.version)
145+
with open(args.output, 'wb') as f:
146+
kernel_size = os.path.getsize(args.kernel)
147+
148+
if args.aon is not None:
149+
aon_size = os.path.getsize(args.aon)
150+
151+
print(" kernel binary size:", kernel_size)
152+
kern_rdup_pg_size = roundup_page(kernel_size)
153+
154+
# Global SOC configuration
155+
f.write(gen_global_manifest())
156+
157+
# Add manifest for main ISH binary
158+
f.write(gen_module_manifest(b'ISHM', b'ISH_KERN', HEADER_SIZE, kernel_size, KERN_LOAD_ADDR))
159+
160+
if args.aon is not None:
161+
print(" AON binary size: ", aon_size)
162+
aon_rdup_pg_size = roundup_page(aon_size)
163+
# Add manifest for aontask binary
164+
f.write(
165+
gen_module_manifest(
166+
b'ISHM',
167+
b'AON_TASK',
168+
(HEADER_SIZE + kern_rdup_pg_size * PAGE_SIZE),
169+
aon_size,
170+
AON_LOAD_ADDR,
171+
)
172+
)
173+
else:
174+
aon_rdup_pg_size = 0
175+
176+
# ICCM DCCM placeholder
177+
f.write(
178+
gen_module_manifest(
179+
b'ISHM',
180+
b'ICCM_IMG',
181+
(HEADER_SIZE + (kern_rdup_pg_size + aon_rdup_pg_size) * PAGE_SIZE),
182+
0,
183+
0,
184+
)
185+
)
186+
f.write(
187+
gen_module_manifest(
188+
b'ISHM',
189+
b'DCCM_IMG',
190+
(HEADER_SIZE + (kern_rdup_pg_size + aon_rdup_pg_size) * PAGE_SIZE),
191+
0,
192+
0,
193+
)
194+
)
195+
196+
# Add manifest that signals end of manifests
197+
# f.write(gen_manifest(b'ISHE', b'', 0, 0))
198+
f.write(gen_manifest_end())
199+
200+
# Pad the remaining HEADER with 0s
201+
if args.aon is not None:
202+
f.write(b'\x00' * (HEADER_SIZE - (MANIFEST_ENTRY_SIZE * 6)))
203+
else:
204+
f.write(b'\x00' * (HEADER_SIZE - (MANIFEST_ENTRY_SIZE * 5)))
205+
206+
# Append original kernel image
207+
with open(args.kernel, 'rb') as in_file:
208+
f.write(in_file.read())
209+
# Filling padings due to size round up as pages
210+
f.write(b'\x00' * (kern_rdup_pg_size * PAGE_SIZE - kernel_size))
211+
212+
if args.aon is not None:
213+
# Append original aon image
214+
with open(args.aon, 'rb') as in_file:
215+
f.write(in_file.read())
216+
# Filling padings due to size round up as pages
217+
f.write(b'\x00' * (aon_rdup_pg_size * PAGE_SIZE - aon_size))
218+
219+
220+
if __name__ == '__main__':
221+
main()

0 commit comments

Comments
 (0)