1
1
import asyncio
2
+ import binascii
3
+ import logging
2
4
import os
3
5
import shlex
4
6
import socket
12
14
if t .TYPE_CHECKING :
13
15
from .app import QemuApp
14
16
17
+ QEMU_DEFAULT_EFUSE = {
18
+ 'esp32' : binascii .unhexlify (
19
+ '00000000000000000000000000800000000000000000100000000000000000000000000000000000'
20
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
21
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
22
+ '00000000'
23
+ ),
24
+ 'esp32c3' : binascii .unhexlify (
25
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000c00'
26
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
27
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
28
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
29
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
30
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
31
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
32
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
33
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
34
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
35
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
36
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
37
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
38
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
39
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
40
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
41
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
42
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
43
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
44
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
45
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
46
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
47
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
48
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
49
+ '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
50
+ '000000000000000000000000000000000000000000000000'
51
+ ),
52
+ }
53
+
15
54
16
55
class Qemu (DuplicateStdoutPopen ):
17
56
"""
@@ -37,6 +76,7 @@ def __init__(
37
76
qemu_prog_path : t .Optional [str ] = None ,
38
77
qemu_cli_args : t .Optional [str ] = None ,
39
78
qemu_extra_args : t .Optional [str ] = None ,
79
+ qemu_efuse_path : t .Optional [str ] = None ,
40
80
app : t .Optional ['QemuApp' ] = None ,
41
81
** kwargs ,
42
82
):
@@ -55,11 +95,28 @@ def __init__(
55
95
56
96
qemu_prog_path = qemu_prog_path or self .qemu_prog_name
57
97
98
+ self .current_qemu_executable_path = qemu_prog_path
99
+ self .image_path = image_path
100
+ self .efuse_path = qemu_efuse_path
101
+
58
102
if qemu_cli_args :
59
103
qemu_cli_args = qemu_cli_args .strip ('"' ).strip ("'" )
60
104
qemu_cli_args = shlex .split (qemu_cli_args or self .qemu_default_args )
61
105
qemu_extra_args = shlex .split (qemu_extra_args or '' )
62
106
107
+ if self .efuse_path :
108
+ logging .debug ('The eFuse file will be saved to: %s' , self .efuse_path )
109
+ with open (self .efuse_path , 'wb' ) as f :
110
+ f .write (QEMU_DEFAULT_EFUSE [self .app .target ])
111
+ qemu_extra_args += [
112
+ '-global' ,
113
+ f'driver={ self .app .target } .gpio,property=strap_mode,value=0x08' ,
114
+ '-drive' ,
115
+ f'file={ self .efuse_path } ,if=none,format=raw,id=efuse' ,
116
+ '-global' ,
117
+ f'driver=nvram.{ self .app .target } .efuse,property=drive,value=efuse' ,
118
+ ]
119
+
63
120
self .qmp_addr = None
64
121
self .qmp_port = None
65
122
@@ -87,6 +144,47 @@ def __init__(
87
144
** kwargs ,
88
145
)
89
146
147
+ def execute_efuse_command (self , command : str ):
148
+ import espefuse
149
+ import pexpect
150
+
151
+ with socket .socket (socket .AF_INET , socket .SOCK_STREAM ) as s :
152
+ s .bind (('127.0.0.1' , 0 ))
153
+ _ , available_port = s .getsockname ()
154
+
155
+ run_qemu_command = [
156
+ '-nographic' ,
157
+ '-machine' ,
158
+ self .app .target ,
159
+ '-drive' ,
160
+ f'file={ self .image_path } ,if=mtd,format=raw' ,
161
+ '-global' ,
162
+ f'driver={ self .app .target } .gpio,property=strap_mode,value=0x0f' ,
163
+ '-drive' ,
164
+ f'file={ self .efuse_path } ,if=none,format=raw,id=efuse' ,
165
+ '-global' ,
166
+ f'driver=nvram.{ self .app .target } .efuse,property=drive,value=efuse' ,
167
+ '-serial' ,
168
+ f'tcp::{ available_port } ,server,nowait' ,
169
+ ]
170
+ try :
171
+ child = pexpect .spawn (self .current_qemu_executable_path , run_qemu_command )
172
+ res = shlex .split (command )
173
+ child .expect ('qemu' )
174
+
175
+ res = [r for r in res if r != '--do-not-confirm' ]
176
+ espefuse .main ([
177
+ '--port' ,
178
+ f'socket://localhost:{ available_port } ' ,
179
+ '--before' ,
180
+ 'no_reset' ,
181
+ '--do-not-confirm' ,
182
+ * res ,
183
+ ])
184
+ self ._hard_reset ()
185
+ finally :
186
+ child .terminate ()
187
+
90
188
@property
91
189
def qemu_prog_name (self ):
92
190
if self .app :
0 commit comments