class VExpress_GEM5_Base(RealView): """ The VExpress gem5 memory map is loosely based on a modified Versatile Express RS1 memory map. The gem5 platform has been designed to implement a subset of the original Versatile Express RS1 memory map. Off-chip peripherals should, when possible, adhere to the Versatile Express memory map. Non-PCI off-chip devices that are gem5-specific should live in the CS5 memory space to avoid conflicts with existing devices that we might want to model in the future. Such devices should normally have interrupts in the gem5-specific SPI range. On-chip peripherals are loosely modeled after the ARM CoreTile Express A15x2 memory and interrupt map. In particular, the GIC and Generic Timer have the same interrupt lines and base addresses. Other on-chip devices are gem5 specific. Unlike the original Versatile Express RS2 extended platform, gem5 implements a large contigious DRAM space, without aliases or holes, starting at the 2GiB boundary. This means that PCI memory is limited to 1GiB. References: Technical Reference Manuals: Arm Motherboard Express uATX (V2M-P1) - ARM DUI 0447J Arm CoreTile Express A15x2 (V2P-CA15) - ARM DUI 0604E Official Linux device tree specifications: V2M-P1 - arch/arm/boot/dts/vexpress-v2m-rs1.dtsi V2P-CA15 - arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts Memory map: Arm CoreTile Express A15x2 (V2P-CA15) - ARM DUI 0604E Daughterboard (global) Section 3.2.1 - Table 3-1 - Daughterboard memory map On-chip Section 3.2.3 - Table 3-2 - Cortex-A15 MPCore on-chip peripheral memory map Interrupts: Arm CoreTile Express A15x2 (V2P-CA15) - ARM DUI 0604E Section 2.8.2 - Test chip interrupts Memory map: 0x00000000-0x03ffffff: Boot memory (CS0) 0x04000000-0x07ffffff: Reserved 0x08000000-0x0bffffff: Reserved (CS0 alias) 0x0c000000-0x0fffffff: Reserved (Off-chip, CS4) 0x10000000-0x13ffffff: gem5-specific peripherals (Off-chip, CS5) 0x10000000-0x1000ffff: gem5 energy controller 0x10010000-0x1001ffff: gem5 pseudo-ops 0x14000000-0x17ffffff: Reserved (Off-chip, PSRAM, CS1) 0x18000000-0x1bffffff: Reserved (Off-chip, Peripherals, CS2) 0x1c000000-0x1fffffff: Peripheral block 1 (Off-chip, CS3): 0x1c010000-0x1c01ffff: realview_io (VE system control regs.) 0x1c060000-0x1c06ffff: KMI0 (keyboard) 0x1c070000-0x1c07ffff: KMI1 (mouse) 0x1c090000-0x1c09ffff: UART0 0x1c0a0000-0x1c0affff: UART1 (reserved) 0x1c0b0000-0x1c0bffff: UART2 (reserved) 0x1c0c0000-0x1c0cffff: UART3 (reserved) 0x1c130000-0x1c13ffff: VirtIO (gem5/FM extension) 0x1c140000-0x1c14ffff: VirtIO (gem5/FM extension) 0x1c170000-0x1c17ffff: RTC 0x20000000-0x3fffffff: On-chip peripherals: 0x2b000000-0x2b00ffff: HDLCD 0x2b400000-0x2b41ffff: SMMUv3 0x2c001000-0x2c001fff: GIC (distributor) 0x2c002000-0x2c003fff: GIC (CPU interface) 0x2c004000-0x2c005fff: vGIC (HV) 0x2c006000-0x2c007fff: vGIC (VCPU) 0x2c1c0000-0x2c1cffff: GICv2m MSI frame 0 0x2d000000-0x2d00ffff: GPU (reserved) 0x2f000000-0x2fffffff: PCI IO space 0x30000000-0x3fffffff: PCI config space 0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory 0x80000000-X: DRAM Interrupts: 0- 15: Software generated interrupts (SGIs) 16- 31: On-chip private peripherals (PPIs) 25 : vgic 26 : generic_timer (hyp) 27 : generic_timer (virt) 28 : Reserved (Legacy FIQ) 29 : generic_timer (phys, sec) 30 : generic_timer (phys, non-sec) 31 : Reserved (Legacy IRQ) 32- 95: Mother board peripherals (SPIs) 32 : Reserved (SP805) 33 : Reserved (IOFPGA SW int) 34-35: Reserved (SP804) 36 : RTC 37-40: uart0-uart3 41-42: Reserved (PL180) 43 : Reserved (AACI) 44-45: kmi0-kmi1 46 : Reserved (CLCD) 47 : Reserved (Ethernet) 48 : Reserved (USB) 95-255: On-chip interrupt sources (we use these for gem5-specific devices, SPIs) 74 : VirtIO (gem5/FM extension) 75 : VirtIO (gem5/FM extension) 95 : HDLCD 96- 98: GPU (reserved) 100-103: PCI 256-319: MSI frame 0 (gem5-specific, SPIs) 320-511: Unused """ # Everything above 2GiB is memory _mem_regions = [ AddrRange('2GB', size='510GB') ] _off_chip_ranges = [ # CS1-CS5 AddrRange(0x0c000000, 0x20000000), # External AXI interface (PCI) AddrRange(0x2f000000, 0x80000000), ] bootmem = SimpleMemory(range=AddrRange(0, size='64MB'), conf_table_reported=False) # Platform control device (off-chip) realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000, idreg=0x02250000, pio_addr=0x1c010000) mcc = VExpressMCC() dcc = CoreTile2A15DCC() ### On-chip devices ### generic_timer = GenericTimer(int_phys_s=ArmPPI(num=29), int_phys_ns=ArmPPI(num=30), int_virt=ArmPPI(num=27), int_hyp=ArmPPI(num=26)) def _on_chip_devices(self): return [ self.generic_timer, ] def _on_chip_memory(self): memories = [ self.bootmem, ] return memories ### Off-chip devices ### clock24MHz = SrcClockDomain(clock="24MHz", voltage_domain=VoltageDomain(voltage="3.3V")) uart = [ Pl011(pio_addr=0x1c090000, int_num=37), ] kmi0 = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard()) kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit()) rtc = PL031(pio_addr=0x1c170000, int_num=36) ### gem5-specific off-chip devices ### pci_host = GenericArmPciHost( conf_base=0x30000000, conf_size='256MB', conf_device_bits=12, pci_pio_base=0x2f000000, int_policy="ARM_PCI_INT_DEV", int_base=100, int_count=4) energy_ctrl = EnergyCtrl(pio_addr=0x10000000) vio = [ MmioVirtIO(pio_addr=0x1c130000, pio_size=0x1000, interrupt=ArmSPI(num=74)), MmioVirtIO(pio_addr=0x1c140000, pio_size=0x1000, interrupt=ArmSPI(num=75)), ] def _off_chip_devices(self): return [ self.realview_io, self.uart[0], self.kmi0, self.kmi1, self.rtc, self.pci_host, self.energy_ctrl, self.clock24MHz, self.vio[0], self.vio[1], ] def attachPciDevice(self, device, *args, **kwargs): device.host = self.pci_host self._num_pci_dev += 1 device.pci_bus = 0 device.pci_dev = self._num_pci_dev device.pci_func = 0 self._attach_device(device, *args, **kwargs) def attachSmmu(self, devices, bus): """ Instantiate a single SMMU and attach a group of client devices to it. The devices' dma port is wired to the SMMU and the SMMU's dma port (master) is attached to the bus. In order to make it work, the list of clients shouldn't contain any device part of the _off_chip_devices or _on_chip_devices. This method should be called only once. Parameters: devices (list): List of devices which will be using the SMMU bus (Bus): The bus downstream of the SMMU. Its slave port will receive memory requests from the SMMU, and its master port will forward accesses to the memory mapped devices """ if hasattr(self, 'smmu'): m5.fatal("A SMMU has already been instantiated\n") self.smmu = SMMUv3(reg_map=AddrRange(0x2b400000, size=0x00020000)) dma_ports = [] for dev in devices: self._attach_device(dev, bus, dma_ports) self.smmu.connect(dev, bus) def setupBootLoader(self, cur_sys, loc): if not cur_sys.boot_loader: cur_sys.boot_loader = [ loc('boot.arm64'), loc('boot.arm') ] cur_sys.atags_addr = 0x8000000 cur_sys.load_offset = 0x80000000 # Setup m5ops. It's technically not a part of the boot # loader, but this is the only place we can configure the # system. cur_sys.m5ops_base = 0x10010000 def generateDeviceTree(self, state): # Generate using standard RealView function dt = list(super(VExpress_GEM5_Base, self).generateDeviceTree(state)) if len(dt) > 1: raise Exception("System returned too many DT nodes") node = dt[0] node.appendCompatible(["arm,vexpress"]) node.append(FdtPropertyStrings("model", ["V2P-CA15"])) node.append(FdtPropertyWords("arm,hbi", [0x0])) node.append(FdtPropertyWords("arm,vexpress,site", [0xf])) yield node
class VExpress_GEM5_Base(RealView): """ The VExpress gem5 memory map is loosely based on a modified Versatile Express RS1 memory map. The gem5 platform has been designed to implement a subset of the original Versatile Express RS1 memory map. Off-chip peripherals should, when possible, adhere to the Versatile Express memory map. Non-PCI off-chip devices that are gem5-specific should live in the CS5 memory space to avoid conflicts with existing devices that we might want to model in the future. Such devices should normally have interrupts in the gem5-specific SPI range. On-chip peripherals are loosely modeled after the ARM CoreTile Express A15x2 A7x3 memory and interrupt map. In particular, the GIC and Generic Timer have the same interrupt lines and base addresses. Other on-chip devices are gem5 specific. Unlike the original Versatile Express RS2 extended platform, gem5 implements a large contigious DRAM space, without aliases or holes, starting at the 2GiB boundary. This means that PCI memory is limited to 1GiB. Memory map: 0x00000000-0x03ffffff: Boot memory (CS0) 0x04000000-0x07ffffff: Reserved 0x08000000-0x0bffffff: Reserved (CS0 alias) 0x0c000000-0x0fffffff: Reserved (Off-chip, CS4) 0x10000000-0x13ffffff: gem5-specific peripherals (Off-chip, CS5) 0x10000000-0x1000ffff: gem5 energy controller 0x10010000-0x1001ffff: gem5 pseudo-ops 0x14000000-0x17ffffff: Reserved (Off-chip, PSRAM, CS1) 0x18000000-0x1bffffff: Reserved (Off-chip, Peripherals, CS2) 0x1c000000-0x1fffffff: Peripheral block 1 (Off-chip, CS3): 0x1c010000-0x1c01ffff: realview_io (VE system control regs.) 0x1c060000-0x1c06ffff: KMI0 (keyboard) 0x1c070000-0x1c07ffff: KMI1 (mouse) 0x1c090000-0x1c09ffff: UART0 0x1c0a0000-0x1c0affff: UART1 (reserved) 0x1c0b0000-0x1c0bffff: UART2 (reserved) 0x1c0c0000-0x1c0cffff: UART3 (reserved) 0x1c130000-0x1c13ffff: VirtIO (gem5/FM extension) 0x1c140000-0x1c14ffff: VirtIO (gem5/FM extension) 0x1c170000-0x1c17ffff: RTC 0x20000000-0x3fffffff: On-chip peripherals: 0x2b000000-0x2b00ffff: HDLCD 0x2c001000-0x2c001fff: GIC (distributor) 0x2c002000-0x2c003fff: GIC (CPU interface) 0x2c004000-0x2c005fff: vGIC (HV) 0x2c006000-0x2c007fff: vGIC (VCPU) 0x2c1c0000-0x2c1cffff: GICv2m MSI frame 0 0x2d000000-0x2d00ffff: GPU (reserved) 0x2f000000-0x2fffffff: PCI IO space 0x30000000-0x3fffffff: PCI config space 0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory 0x80000000-X: DRAM Interrupts: 0- 15: Software generated interrupts (SGIs) 16- 31: On-chip private peripherals (PPIs) 25 : vgic 26 : generic_timer (hyp) 27 : generic_timer (virt) 28 : Reserved (Legacy FIQ) 29 : generic_timer (phys, sec) 30 : generic_timer (phys, non-sec) 31 : Reserved (Legacy IRQ) 32- 95: Mother board peripherals (SPIs) 32 : Reserved (SP805) 33 : Reserved (IOFPGA SW int) 34-35: Reserved (SP804) 36 : RTC 37-40: uart0-uart3 41-42: Reserved (PL180) 43 : Reserved (AACI) 44-45: kmi0-kmi1 46 : Reserved (CLCD) 47 : Reserved (Ethernet) 48 : Reserved (USB) 95-255: On-chip interrupt sources (we use these for gem5-specific devices, SPIs) 74 : VirtIO (gem5/FM extension) 75 : VirtIO (gem5/FM extension) 95 : HDLCD 96- 98: GPU (reserved) 100-103: PCI 256-319: MSI frame 0 (gem5-specific, SPIs) 320-511: Unused """ # Everything above 2GiB is memory _mem_regions = [ AddrRange('2GB', size='510GB') ] _off_chip_ranges = [ # CS1-CS5 AddrRange(0x0c000000, 0x1fffffff), # External AXI interface (PCI) AddrRange(0x2f000000, 0x7fffffff), ] # Platform control device (off-chip) realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000, idreg=0x02250000, pio_addr=0x1c010000) mcc = VExpressMCC() dcc = CoreTile2A15DCC() ### On-chip devices ### generic_timer = GenericTimer(int_phys_s=ArmPPI(num=29), int_phys_ns=ArmPPI(num=30), int_virt=ArmPPI(num=27), int_hyp=ArmPPI(num=26)) def _on_chip_devices(self): return [ self.generic_timer, ] ### Off-chip devices ### clock24MHz = SrcClockDomain(clock="24MHz", voltage_domain=VoltageDomain(voltage="3.3V")) uart = [ Pl011(pio_addr=0x1c090000, int_num=37), ] kmi0 = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard()) kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit()) rtc = PL031(pio_addr=0x1c170000, int_num=36) ### gem5-specific off-chip devices ### pci_host = GenericArmPciHost( conf_base=0x30000000, conf_size='256MB', conf_device_bits=12, pci_pio_base=0x2f000000, int_policy="ARM_PCI_INT_DEV", int_base=100, int_count=4) energy_ctrl = EnergyCtrl(pio_addr=0x10000000) vio = [ MmioVirtIO(pio_addr=0x1c130000, pio_size=0x1000, interrupt=ArmSPI(num=74)), MmioVirtIO(pio_addr=0x1c140000, pio_size=0x1000, interrupt=ArmSPI(num=75)), ] def _off_chip_devices(self): return [ self.realview_io, self.uart[0], self.kmi0, self.kmi1, self.rtc, self.pci_host, self.energy_ctrl, self.clock24MHz, self.vio[0], self.vio[1], ] def attachPciDevice(self, device, *args, **kwargs): device.host = self.pci_host self._attach_device(device, *args, **kwargs) def setupBootLoader(self, mem_bus, cur_sys, loc): cur_sys.bootmem = SimpleMemory(range=AddrRange(0, size='64MB'), conf_table_reported=False) if mem_bus is not None: cur_sys.bootmem.port = mem_bus.master if not cur_sys.boot_loader: cur_sys.boot_loader = [ loc('boot_emm.arm64'), loc('boot_emm.arm') ] cur_sys.atags_addr = 0x8000000 cur_sys.load_offset = 0x80000000 # Setup m5ops. It's technically not a part of the boot # loader, but this is the only place we can configure the # system. cur_sys.m5ops_base = 0x10010000 def generateDeviceTree(self, state): # Generate using standard RealView function dt = list(super(VExpress_GEM5_Base, self).generateDeviceTree(state)) if len(dt) > 1: raise Exception("System returned too many DT nodes") node = dt[0] node.appendCompatible(["arm,vexpress"]) node.append(FdtPropertyStrings("model", ["V2P-CA15"])) node.append(FdtPropertyWords("arm,hbi", [0x0])) node.append(FdtPropertyWords("arm,vexpress,site", [0xf])) yield node