예제 #1
0
    def __init__(self, kernel, disk, cpu_type, mem_sys, num_cpus, opts):
        super(MyRubySystem, self).__init__()
        self._opts = opts

        self._host_parallel = cpu_type == "kvm"

        # Set up the clock domain and the voltage domain
        self.clk_domain = SrcClockDomain()
        self.clk_domain.clock = '3GHz'
        self.clk_domain.voltage_domain = VoltageDomain()

        self.mem_ranges = [
            AddrRange(Addr('3GB')),  # All data
            AddrRange(0xC0000000, size=0x100000),  # For I/0
        ]

        self.initFS(num_cpus)

        # Replace these paths with the path to your disk images.
        # The first disk is the root disk. The second could be used for swap
        # or anything else.
        self.setDiskImages(disk, disk)

        # Change this path to point to the kernel you want to use
        self.workload.object_file = kernel
        # Options specified on the kernel command line
        boot_options = [
            'earlyprintk=ttyS0', 'console=ttyS0', 'lpj=7999923',
            'root=/dev/hda1'
        ]

        self.workload.command_line = ' '.join(boot_options)

        # Create the CPUs for our system.
        self.createCPU(cpu_type, num_cpus)

        self.createMemoryControllersDDR3()

        # Create the cache hierarchy for the system.
        if mem_sys == 'MI_example':
            from MI_example_caches import MIExampleSystem
            self.caches = MIExampleSystem()
        elif mem_sys == 'MESI_Two_Level':
            from MESI_Two_Level import MESITwoLevelCache
            self.caches = MESITwoLevelCache()
        elif mem_sys == 'MOESI_CMP_directory':
            from MOESI_CMP_directory import MOESICMPDirCache
            self.caches = MOESICMPDirCache()
        self.caches.setup(self, self.cpu, self.mem_cntrls,
                          [self.pc.south_bridge.ide.dma, self.iobus.master],
                          self.iobus)

        if self._host_parallel:
            # To get the KVM CPUs to run on different host CPUs
            # Specify a different event queue for each CPU
            for i, cpu in enumerate(self.cpu):
                for obj in cpu.descendants():
                    obj.eventq_index = 0
                cpu.eventq_index = i + 1
예제 #2
0
class MyRubySystem(System):
    def __init__(self, kernel, disk, cpu_type, mem_sys, num_cpus, opts):
        super(MyRubySystem, self).__init__()
        self._opts = opts

        self._host_parallel = cpu_type == "kvm"

        # Set up the clock domain and the voltage domain
        self.clk_domain = SrcClockDomain()
        self.clk_domain.clock = '3GHz'
        self.clk_domain.voltage_domain = VoltageDomain()

        self.mem_ranges = [
            AddrRange(Addr('3GB')),  # All data
            AddrRange(0xC0000000, size=0x100000),  # For I/0
        ]

        self.initFS(num_cpus)

        # Replace these paths with the path to your disk images.
        # The first disk is the root disk. The second could be used for swap
        # or anything else.
        self.setDiskImages(disk, disk)

        # Change this path to point to the kernel you want to use
        self.workload.object_file = kernel
        # Options specified on the kernel command line
        boot_options = [
            'earlyprintk=ttyS0', 'console=ttyS0', 'lpj=7999923',
            'root=/dev/hda1'
        ]

        self.workload.command_line = ' '.join(boot_options)

        # Create the CPUs for our system.
        self.createCPU(cpu_type, num_cpus)

        self.createMemoryControllersDDR3()

        # Create the cache hierarchy for the system.
        if mem_sys == 'MI_example':
            from MI_example_caches import MIExampleSystem
            self.caches = MIExampleSystem()
        elif mem_sys == 'MESI_Two_Level':
            from MESI_Two_Level import MESITwoLevelCache
            self.caches = MESITwoLevelCache()
        elif mem_sys == 'MOESI_CMP_directory':
            from MOESI_CMP_directory import MOESICMPDirCache
            self.caches = MOESICMPDirCache()
        self.caches.setup(self, self.cpu, self.mem_cntrls,
                          [self.pc.south_bridge.ide.dma, self.iobus.master],
                          self.iobus)

        if self._host_parallel:
            # To get the KVM CPUs to run on different host CPUs
            # Specify a different event queue for each CPU
            for i, cpu in enumerate(self.cpu):
                for obj in cpu.descendants():
                    obj.eventq_index = 0
                cpu.eventq_index = i + 1

    def getHostParallel(self):
        return self._host_parallel

    def totalInsts(self):
        return sum([cpu.totalInsts() for cpu in self.cpu])

    def createCPU(self, cpu_type, num_cpus):
        if cpu_type == "atomic":
            self.cpu = [AtomicSimpleCPU(cpu_id=i) for i in range(num_cpus)]
            self.mem_mode = 'atomic'
        elif cpu_type == "kvm":
            # Note KVM needs a VM and atomic_noncaching
            self.cpu = [X86KvmCPU(cpu_id=i) for i in range(num_cpus)]
            self.kvm_vm = KvmVM()
            self.mem_mode = 'atomic_noncaching'
        elif cpu_type == "o3":
            self.cpu = [DerivO3CPU(cpu_id=i) for i in range(num_cpus)]
            self.mem_mode = 'timing'
        elif cpu_type == "simple":
            self.cpu = [TimingSimpleCPU(cpu_id=i) for i in range(num_cpus)]
            self.mem_mode = 'timing'
        else:
            m5.fatal("No CPU type {}".format(cpu_type))

        map(lambda c: c.createThreads(), self.cpu)
        map(lambda c: c.createInterruptController(), self.cpu)

    def setDiskImages(self, img_path_1, img_path_2):
        disk0 = CowDisk(img_path_1)
        disk2 = CowDisk(img_path_2)
        self.pc.south_bridge.ide.disks = [disk0, disk2]

    def createMemoryControllersDDR3(self):
        self._createMemoryControllers(1, DDR3_1600_8x8)

    def _createMemoryControllers(self, num, cls):
        self.mem_cntrls = [cls(range=self.mem_ranges[0]) for i in range(num)]

    def initFS(self, cpus):
        self.pc = Pc()

        self.workload = X86FsLinux()

        # North Bridge
        self.iobus = IOXBar()

        # connect the io bus
        # Note: pass in a reference to where Ruby will connect to in the future
        # so the port isn't connected twice.
        self.pc.attachIO(self.iobus, [self.pc.south_bridge.ide.dma])

        self.intrctrl = IntrControl()

        ###############################################

        # Add in a Bios information structure.
        self.workload.smbios_table.structures = [X86SMBiosBiosInformation()]

        # Set up the Intel MP table
        base_entries = []
        ext_entries = []
        for i in range(cpus):
            bp = X86IntelMPProcessor(local_apic_id=i,
                                     local_apic_version=0x14,
                                     enable=True,
                                     bootstrap=(i == 0))
            base_entries.append(bp)
        io_apic = X86IntelMPIOAPIC(id=cpus,
                                   version=0x11,
                                   enable=True,
                                   address=0xfec00000)
        self.pc.south_bridge.io_apic.apic_id = io_apic.id
        base_entries.append(io_apic)
        pci_bus = X86IntelMPBus(bus_id=0, bus_type='PCI   ')
        base_entries.append(pci_bus)
        isa_bus = X86IntelMPBus(bus_id=1, bus_type='ISA   ')
        base_entries.append(isa_bus)
        connect_busses = X86IntelMPBusHierarchy(bus_id=1,
                                                subtractive_decode=True,
                                                parent_bus=0)
        ext_entries.append(connect_busses)
        pci_dev4_inta = X86IntelMPIOIntAssignment(interrupt_type='INT',
                                                  polarity='ConformPolarity',
                                                  trigger='ConformTrigger',
                                                  source_bus_id=0,
                                                  source_bus_irq=0 + (4 << 2),
                                                  dest_io_apic_id=io_apic.id,
                                                  dest_io_apic_intin=16)
        base_entries.append(pci_dev4_inta)

        def assignISAInt(irq, apicPin):
            assign_8259_to_apic = X86IntelMPIOIntAssignment(
                interrupt_type='ExtInt',
                polarity='ConformPolarity',
                trigger='ConformTrigger',
                source_bus_id=1,
                source_bus_irq=irq,
                dest_io_apic_id=io_apic.id,
                dest_io_apic_intin=0)
            base_entries.append(assign_8259_to_apic)
            assign_to_apic = X86IntelMPIOIntAssignment(
                interrupt_type='INT',
                polarity='ConformPolarity',
                trigger='ConformTrigger',
                source_bus_id=1,
                source_bus_irq=irq,
                dest_io_apic_id=io_apic.id,
                dest_io_apic_intin=apicPin)
            base_entries.append(assign_to_apic)

        assignISAInt(0, 2)
        assignISAInt(1, 1)
        for i in range(3, 15):
            assignISAInt(i, i)
        self.workload.intel_mp_table.base_entries = base_entries
        self.workload.intel_mp_table.ext_entries = ext_entries

        entries = \
           [
            # Mark the first megabyte of memory as reserved
            X86E820Entry(addr = 0, size = '639kB', range_type = 1),
            X86E820Entry(addr = 0x9fc00, size = '385kB', range_type = 2),
            # Mark the rest of physical memory as available
            X86E820Entry(addr = 0x100000,
                    size = '%dB' % (self.mem_ranges[0].size() - 0x100000),
                    range_type = 1),
            ]

        # Reserve the last 16kB of the 32-bit address space for m5ops
        entries.append(X86E820Entry(addr=0xFFFF0000, size='64kB',
                                    range_type=2))

        self.workload.e820_table.entries = entries