• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <string>
19 #include <unordered_map>
20 #include <vector>
21 
22 #include "common/libs/fs/shared_fd.h"
23 #include "common/libs/utils/result.h"
24 #include "host/libs/config/command_source.h"
25 #include "host/libs/vm_manager/vm_manager.h"
26 
27 namespace cuttlefish {
28 namespace vm_manager {
29 
30 // Starts a guest VM using the gem5 command directly. It requires the host
31 // package to support the gem5 capability.
32 class Gem5Manager : public VmManager {
33  public:
name()34   static std::string name() { return "gem5"; }
35 
36   Gem5Manager(Arch);
37   virtual ~Gem5Manager() = default;
38 
39   bool IsSupported() override;
40 
41   Result<std::unordered_map<std::string, std::string>> ConfigureGraphics(
42       const CuttlefishConfig::InstanceSpecific& instance) override;
43 
44   Result<std::unordered_map<std::string, std::string>> ConfigureBootDevices(
45       int num_disks, bool have_gpu) override;
46 
47   Result<std::vector<MonitorCommand>> StartCommands(
48       const CuttlefishConfig& config) override;
49 
50  private:
51   Arch arch_;
52 };
53 
54 const std::string fs_header = R"CPP_STR_END(import argparse
55 import devices
56 import os
57 import shutil
58 import m5
59 from m5.util import addToPath
60 from m5.objects import *
61 from m5.options import *
62 from m5.objects.Ethernet import NSGigE, IGbE_igb, IGbE_e1000, EtherTap
63 from common import SysPaths
64 from common import ObjectList
65 from common import MemConfig
66 from common.cores.arm import HPI
67 m5.util.addToPath('../..')
68 )CPP_STR_END";
69 
70 const std::string fs_mem_pci = R"CPP_STR_END(
71   MemConfig.config_mem(args, root.system)
72 
73   pci_devices = []
74   pci_devices.append(PciVirtIO(vio=VirtIOConsole(device=Terminal(number=0))))
75   pci_devices.append(PciVirtIO(vio=VirtIOConsole(device=Terminal(number=1, outfile="none"))))
76   pci_devices.append(PciVirtIO(vio=VirtIOConsole(device=Terminal(number=2))))
77   pci_devices.append(PciVirtIO(vio=VirtIOConsole(device=Terminal(number=3, outfile="none"))))
78   pci_devices.append(PciVirtIO(vio=VirtIOConsole(device=Terminal(number=4, outfile="none"))))
79   pci_devices.append(PciVirtIO(vio=VirtIOConsole(device=Terminal(number=5, outfile="none"))))
80   pci_devices.append(PciVirtIO(vio=VirtIOConsole(device=Terminal(number=6, outfile="none"))))
81   pci_devices.append(PciVirtIO(vio=VirtIOConsole(device=Terminal(number=7, outfile="none"))))
82   pci_devices.append(PciVirtIO(vio=VirtIOConsole(device=Terminal(number=8, outfile="none"))))
83   pci_devices.append(PciVirtIO(vio=VirtIOConsole(device=Terminal(number=9, outfile="none"))))
84 
85   for each_item in args.disk_image:
86     disk_image = CowDiskImage()
87     disk_image.child.image_file = SysPaths.disk(each_item)
88     pci_devices.append(PciVirtIO(vio=VirtIOBlock(image=disk_image)))
89 
90   nic = IGbE_e1000(pci_bus=0, pci_dev=0, pci_func=0, InterruptLine=1, InterruptPin=1)
91   pci_devices.append(nic)
92   root.system.pci_devices = pci_devices
93   for pci_device in root.system.pci_devices:
94     root.system.attach_pci(pci_device)
95 
96   root.tap = EtherTap(tun_clone_device='/dev/net/tun', tap_device_name='cvd-mtap-01')
97   root.tap.tap = nic.interface
98   root.system.connect()
99 )CPP_STR_END";
100 
101 const std::string fs_kernel_cmd = R"CPP_STR_END(
102   kernel_cmd = [
103     "lpj=19988480",
104     "norandmaps",
105     "mem=%s" % args.mem_size,
106     "console=hvc0",
107     "panic=-1",
108     "earlycon=pl011,mmio32,0x1c090000",
109     "audit=1",
110     "printk.devkmsg=on",
111     "firmware_class.path=/vendor/etc/",
112     "kfence.sample_interval=500",
113     "loop.max_part=7",
114     "bootconfig",
115     "androidboot.force_normal_boot=1",
116   ]
117   root.system.workload.command_line = " ".join(kernel_cmd)
118   if args.restore is not None:
119     m5.instantiate(args.restore)
120   else:
121     m5.instantiate()
122 
123   while True:
124     event = m5.simulate()
125     msg = event.getCause()
126     cur_tick = m5.curTick()
127     if msg == "checkpoint":
128       backup_path = backup_path = os.path.join(root_dir, "gem5_checkpoint")
129       if not os.path.isdir(backup_path):
130         os.mkdir(backup_path)
131 
132       print("Checkpoint @", cur_tick)
133       src_dir = os.path.join(m5.options.outdir, "cpt.%d" % cur_tick)
134       backup_path = os.path.join(backup_path, "cpt.%d" % cur_tick)
135       m5.checkpoint(src_dir)
136       shutil.copytree(src_dir, backup_path)
137       print("Checkpoint done.")
138     else:
139       print("Exit msg: " + msg + " @", cur_tick)
140       break
141   sys.exit(event.getCode())
142 )CPP_STR_END";
143 
144 const std::string fs_exe_main = R"CPP_STR_END(
145 if __name__ == "__m5_main__":
146   main()
147 )CPP_STR_END";
148 
149 } // namespace vm_manager
150 } // namespace cuttlefish
151