From 0bd3099e40b9b1ddba43c83edf666ae401b2605c Mon Sep 17 00:00:00 2001 From: Romain Dolbeau Date: Sat, 3 Sep 2022 11:28:42 +0200 Subject: [PATCH] fix (probably partial) to support SS IPX (and probably other similar sun4c) --- README.md | 6 +++++- sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6e89362..38513d7 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Master access to the SBus by the host are routed to the Wishbone to access the v The ROM exposes the devices' existence and specifications to the host, initializes the embedded SDRAM controller (but assuming known values, the NetBSD driver can also optionally initialize the SDRAM via proper calibration), enables FB support on the bw2/cg3/cg6 (last one with accelerated scrolling), and has support for RO access to the sdcard such enabling booting. -The USB OHCI DMA (USB 1.1) is bridged from the Wishbone to the SBus by having the physical addresses of the Wishbone (that match the virtual addresses from NetBSD DVMA allocations) to the bridge. Reads are buffered by block of 16 bytes; currently writes are unbuffered (and somewhat slow, as they need a full SBus master cycle for every transaction of 32 bits or less). The standard NetBSD OHCI driver is used, with just a small custom SBus-OHCI driver mirroring the PCI-OHCI one. It uses the interrupt level 4 by default. It connects to the micro-B USB connector, an a cable such as [this one](https://www.startech.com/en-us/cables/uusbotgra) allows to expose a conventional USB type A connector for either an external (preferably self-powered) USB Hub or a single low-power device. +The USB OHCI DMA (USB 1.1) is bridged from the Wishbone to the SBus by having the physical addresses of the Wishbone (that match the virtual addresses from NetBSD DVMA allocations) to the bridge (see also 'Sun4m vs. Sun4c' below). Reads are buffered by block of 16 bytes; currently writes are unbuffered (and somewhat slow, as they need a full SBus master cycle for every transaction of 32 bits or less). The standard NetBSD OHCI driver is used, with just a small custom SBus-OHCI driver mirroring the PCI-OHCI one. It uses the interrupt level 4 by default. It connects to the micro-B USB connector, an a cable such as [this one](https://www.startech.com/en-us/cables/uusbotgra) allows to expose a conventional USB type A connector for either an external (preferably self-powered) USB Hub or a single low-power device. The SDRAM has its own custom DMA controller, using native Litedram interface to the memory, and some FIFO to/from the SBus. A custom NetBSD driver exposes it as a drive on which you can swap. It's also usable as a 'fast', volatile disk (for e.g. /tmp or similar temporary filesystem). It can use a interrupt line, but software support isn't there yet (only synchronous polling). @@ -65,3 +65,7 @@ As not everything lives in the same clock domain, the design also use a Wishbone Directory 'NetBSD' Some basic drivers for NetBSD 9.0/sparc to enable the devices as described above. bw2/cg3/cg6 uses unmodifed NetBSD drivers. USB OHCI needs only a SBus-OHCI layer, the NetBSD OHCI driver and USB stack are used unmodified. + +## Sun4m vs. Sun4c + +The current DMA scheme for Wishbone devices (USB OHCI, micro-sd, ...) works fine on sun4m machine with an IOMMU (SPARCstation 4, 5, 10, 20 ...). NetBSD will always allocate the DVMA buffers in the range from IOMMU_DVMA_BASE to the end of the memory space (IOMMU_DVMA_BASE is 0xFC000000 by default, and that must include 0xFF000000 to the end which are the only virtual addresses accessible by some legacy devices used in some SPARCstation). However, sun4c machine (SPARCstation 1, 2, IPC, IPX, ...) do not have an IOMMU, and have no virtual address restriction for non-legacy device. And the NetBSD kernel takes advantage of this, I have observed DVMA buffers mapped to prefix 0xF4 and 0xF3. Extending the mapping for the DVMA bridge in Wishbone to the full 0xF prefix enable booting from sd-card on an IPX, but I'm not sure this is reliable. diff --git a/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py b/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py index 58997b1..7428129 100644 --- a/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py +++ b/sbus-to-ztex-gateware-migen/sbus_to_fpga_soc.py @@ -272,6 +272,8 @@ class SBusFPGA(SoCCore): # The position of the 'dvma_bridge' is so it overlaps # the virtual address space used by NetBSD DMA allocators # (themselves constrained by the SBus MMU capabilities) + # ... on the SS20. It seems NetBSD 9.0 on the SS IPX behave + # differently. self.wb_mem_map = wb_mem_map = { "prom": 0x00000000, # 256 Kib ought to be enough for anybody (we're using < 8 Kib now...) "csr" : 0x00040000, @@ -293,7 +295,7 @@ class SBusFPGA(SoCCore): "goblin_pixels": 0x01000000, # base address for 16 MiB Goblin Framebuffer "main_ram": 0x80000000, # not directly reachable from SBus mapping (only 0x0 - 0x10000000 is accessible), "video_framebuffer":0x80000000 + 0x10000000 - cg3_fb_size, # Updated later - "dvma_bridge": 0xfc000000, # required to match DVMA virtual addresses + "dvma_bridge": 0xf0000000, # required to match DVMA virtual addresses } self.mem_map.update(wb_mem_map) self.submodules.crg = _CRG(platform=platform, sys_clk_freq=sys_clk_freq, usb=usb, usb_clk_freq=48e6, engine=engine, framebuffer=framebuffer, pix_clk=litex.soc.cores.video.video_timings[cg3_res]["pix_clk"]) @@ -412,6 +414,7 @@ class SBusFPGA(SoCCore): data_width = burst_size * 4 data_width_bits = burst_size * 32 blk_addr_width = 32 - log2_int(data_width) + print(f"Burst configuration for DMA: burst_size = {burst_size} data_width = {data_width} data_width_bits = {data_width_bits} blk_addr_width = {blk_addr_width}\n"); self.tosbus_layout = [ ("address", 32), @@ -497,7 +500,7 @@ class SBusFPGA(SoCCore): if (usb or engine or sdcard or jareth): # jareth only for testing if (not single_dvma_master): - self.bus.add_slave(name="dvma_bridge", slave=self.wishbone_slave_sys, region=SoCRegion(origin=self.mem_map.get("dvma_bridge", None), size=0x03ffffff, cached=False)) + self.bus.add_slave(name="dvma_bridge", slave=self.wishbone_slave_sys, region=SoCRegion(origin=self.mem_map.get("dvma_bridge", None), size=0x0fffffff, cached=False)) if (trng): self.submodules.trng = NeoRV32TrngWrapper(platform=platform)