|
| 1 | +# Copyright (c) 2021 The Regents of the University of California |
| 2 | +# All rights reserved. |
| 3 | +# |
| 4 | +# Redistribution and use in source and binary forms, with or without |
| 5 | +# modification, are permitted provided that the following conditions are |
| 6 | +# met: redistributions of source code must retain the above copyright |
| 7 | +# notice, this list of conditions and the following disclaimer; |
| 8 | +# redistributions in binary form must reproduce the above copyright |
| 9 | +# notice, this list of conditions and the following disclaimer in the |
| 10 | +# documentation and/or other materials provided with the distribution; |
| 11 | +# neither the name of the copyright holders nor the names of its |
| 12 | +# contributors may be used to endorse or promote products derived from |
| 13 | +# this software without specific prior written permission. |
| 14 | +# |
| 15 | +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 16 | +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 17 | +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 18 | +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 19 | +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 20 | +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 21 | +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 22 | +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 23 | +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 24 | +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 25 | +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 26 | + |
| 27 | +""" |
| 28 | +
|
| 29 | +This script shows an example of running a full system Ubuntu boot simulation |
| 30 | +using the gem5 library. This simulation boots Ubuntu 18.04 using 2 KVM CPU |
| 31 | +cores. The simulation then switches to 2 Timing CPU cores before running an |
| 32 | +echo statement. |
| 33 | +
|
| 34 | +Usage |
| 35 | +----- |
| 36 | +
|
| 37 | +``` |
| 38 | +scons build/X86/gem5.opt |
| 39 | +./build/X86/gem5.opt configs/example/gem5_library/x86-ubuntu-run-with-kvm.py |
| 40 | +``` |
| 41 | +""" |
| 42 | + |
| 43 | +import os |
| 44 | +from gem5.resources.resource import CustomResource, CustomDiskImageResource |
| 45 | +from gem5.utils.requires import requires |
| 46 | +from gem5.components.boards.x86_board import X86Board |
| 47 | +from gem5.components.memory.single_channel import SingleChannelDDR3_1600 |
| 48 | +from gem5.components.processors.simple_switchable_processor import ( |
| 49 | + SimpleSwitchableProcessor, |
| 50 | +) |
| 51 | +from gem5.components.processors.cpu_types import CPUTypes |
| 52 | +from gem5.isas import ISA |
| 53 | +from gem5.coherence_protocol import CoherenceProtocol |
| 54 | +from gem5.resources.resource import Resource |
| 55 | +from gem5.simulate.simulator import Simulator |
| 56 | +from gem5.simulate.exit_event import ExitEvent |
| 57 | + |
| 58 | +# This runs a check to ensure the gem5 binary is compiled to X86 and to the |
| 59 | +# MESI Two Level coherence protocol. |
| 60 | +requires(isa_required=ISA.X86, kvm_required=True) |
| 61 | + |
| 62 | +from gem5.components.cachehierarchies.classic.private_l1_private_l2_cache_hierarchy import ( |
| 63 | + PrivateL1PrivateL2CacheHierarchy, |
| 64 | +) |
| 65 | + |
| 66 | +# Here we setup a MESI Two Level Cache Hierarchy. |
| 67 | +cache_hierarchy = PrivateL1PrivateL2CacheHierarchy( |
| 68 | + l1d_size="16kB", l1i_size="16kB", l2_size="256kB" |
| 69 | +) |
| 70 | + |
| 71 | +# Setup the system memory. |
| 72 | +memory = SingleChannelDDR3_1600(size="3GB") |
| 73 | + |
| 74 | +# Here we setup the processor. This is a special switchable processor in which |
| 75 | +# a starting core type and a switch core type must be specified. Once a |
| 76 | +# configuration is instantiated a user may call `processor.switch()` to switch |
| 77 | +# from the starting core types to the switch core types. In this simulation |
| 78 | +# we start with KVM cores to simulate the OS boot, then switch to the Timing |
| 79 | +# cores for the command we wish to run after boot. |
| 80 | +processor = SimpleSwitchableProcessor( |
| 81 | + starting_core_type=CPUTypes.KVM, |
| 82 | + switch_core_type=CPUTypes.TIMING, |
| 83 | + num_cores=2, |
| 84 | +) |
| 85 | + |
| 86 | +# Here we setup the board. The X86Board allows for Full-System X86 simulations. |
| 87 | +board = X86Board( |
| 88 | + clk_freq="3GHz", |
| 89 | + processor=processor, |
| 90 | + memory=memory, |
| 91 | + cache_hierarchy=cache_hierarchy, |
| 92 | +) |
| 93 | + |
| 94 | +# Here we set the Full System workload. |
| 95 | +# The `set_kernel_disk_workload` function for the X86Board takes a kernel, a |
| 96 | +# disk image, and, optionally, a command to run. |
| 97 | + |
| 98 | +# This is the command to run after the system has booted. The first `m5 exit` |
| 99 | +# will stop the simulation so we can switch the CPU cores from KVM to timing |
| 100 | +# and continue the simulation to run the echo command, sleep for a second, |
| 101 | +# then, again, call `m5 exit` to terminate the simulation. After simulation |
| 102 | +# has ended you may inspect `m5out/system.pc.com_1.device` to see the echo |
| 103 | +# output. |
| 104 | +command = "rowhammer_test" |
| 105 | +# + "echo 'This is running on Timing CPU cores.';" \ |
| 106 | +# + "sleep 1;" |
| 107 | +# + "m5 exit;" |
| 108 | + |
| 109 | +board.set_kernel_disk_workload( |
| 110 | + # The x86 linux kernel will be automatically downloaded to the if not |
| 111 | + # already present. |
| 112 | + kernel=CustomResource( |
| 113 | + os.path.join( |
| 114 | + os.path.expanduser("~"), ".cache/gem5/x86-linux-kernel-5.4.49" |
| 115 | + ) |
| 116 | + ), |
| 117 | + # The x86 ubuntu image will be automatically downloaded to the if not |
| 118 | + # already present. |
| 119 | + disk_image=CustomDiskImageResource( |
| 120 | + os.path.join(os.getcwd(), "rh.img"), disk_root_partition="1" |
| 121 | + ), |
| 122 | + readfile_contents=command, |
| 123 | +) |
| 124 | + |
| 125 | +simulator = Simulator( |
| 126 | + board=board, |
| 127 | + on_exit_event={ |
| 128 | + # Here we want override the default behavior for the first m5 exit |
| 129 | + # exit event. Instead of exiting the simulator, we just want to |
| 130 | + # switch the processor. The 2nd m5 exit after will revert to using |
| 131 | + # default behavior where the simulator run will exit. |
| 132 | + ExitEvent.EXIT: (func() for func in [processor.switch]), |
| 133 | + }, |
| 134 | +) |
| 135 | +simulator.run() |
| 136 | +simulator.run() |
0 commit comments