1# SPDX-License-Identifier: GPL-2.0
2# Copyright (c) 2015 Stephen Warren
3# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
4
5"""
6Logic to interact with the sandbox port of U-Boot, running as a sub-process.
7"""
8
9import time
10from u_boot_spawn import Spawn
11from u_boot_console_base import ConsoleBase
12
13class ConsoleSandbox(ConsoleBase):
14    """Represents a connection to a sandbox U-Boot console, executed as a sub-
15    process."""
16
17    def __init__(self, log, config):
18        """Initialize a U-Boot console connection.
19
20        Args:
21            log: A multiplexed_log.Logfile instance.
22            config: A "configuration" object as defined in conftest.py.
23
24        Returns:
25            Nothing.
26        """
27
28        super(ConsoleSandbox, self).__init__(log, config, max_fifo_fill=1024)
29        self.sandbox_flags = []
30        self.use_dtb = True
31
32    def get_spawn(self):
33        """Connect to a fresh U-Boot instance.
34
35        A new sandbox process is created, so that U-Boot begins running from
36        scratch.
37
38        Args:
39            None.
40
41        Returns:
42            A u_boot_spawn.Spawn object that is attached to U-Boot.
43        """
44
45        bcfg = self.config.buildconfig
46        config_spl = bcfg.get('config_spl', 'n') == 'y'
47        config_vpl = bcfg.get('config_vpl', 'n') == 'y'
48        if config_vpl:
49            # Run TPL first, which runs VPL
50            fname = '/tpl/u-boot-tpl'
51        else:
52            fname = '/spl/u-boot-spl' if config_spl else '/u-boot'
53        print(fname)
54        cmd = []
55        if self.config.gdbserver:
56            cmd += ['gdbserver', self.config.gdbserver]
57        cmd += [self.config.build_dir + fname, '-v']
58        if self.use_dtb:
59            cmd += ['-d', self.config.dtb]
60        cmd += self.sandbox_flags
61        return Spawn(cmd, cwd=self.config.source_dir)
62
63    def restart_uboot_with_flags(self, flags, expect_reset=False, use_dtb=True):
64        """Run U-Boot with the given command-line flags
65
66        Args:
67            flags: List of flags to pass, each a string
68            expect_reset: Boolean indication whether this boot is expected
69                to be reset while the 1st boot process after main boot before
70                prompt. False by default.
71            use_dtb: True to use a device tree file, False to run without one
72
73        Returns:
74            A u_boot_spawn.Spawn object that is attached to U-Boot.
75        """
76
77        try:
78            self.sandbox_flags = flags
79            self.use_dtb = use_dtb
80            return self.restart_uboot(expect_reset)
81        finally:
82            self.sandbox_flags = []
83            self.use_dtb = True
84
85    def kill(self, sig):
86        """Send a specific Unix signal to the sandbox process.
87
88        Args:
89            sig: The Unix signal to send to the process.
90
91        Returns:
92            Nothing.
93        """
94
95        self.log.action('kill %d' % sig)
96        self.p.kill(sig)
97
98    def validate_exited(self):
99        """Determine whether the sandbox process has exited.
100
101        If required, this function waits a reasonable time for the process to
102        exit.
103
104        Args:
105            None.
106
107        Returns:
108            Boolean indicating whether the process has exited.
109        """
110
111        p = self.p
112        self.p = None
113        for i in range(100):
114            ret = not p.isalive()
115            if ret:
116                break
117            time.sleep(0.1)
118        p.close()
119        return ret
120