various updates, and prom driver for sdcard
This commit is contained in:
@@ -59,6 +59,7 @@ __KERNEL_RCSID(0, "$NetBSD$");
|
||||
int sbusfpga_sd_match(device_t, cfdata_t, void *);
|
||||
void sbusfpga_sd_attach(device_t, device_t, void *);
|
||||
|
||||
extern struct cfdriver sbusfpga_sd_cd;
|
||||
CFATTACH_DECL_NEW(sbusfpga_sd, sizeof(struct sbusfpga_sd_softc),
|
||||
sbusfpga_sd_match, sbusfpga_sd_attach, NULL, NULL);
|
||||
|
||||
@@ -93,7 +94,7 @@ const struct cdevsw sbusfpga_sd_cdevsw = {
|
||||
.d_mmap = nommap,
|
||||
.d_kqfilter = nokqfilter,
|
||||
.d_discard = nodiscard,
|
||||
.d_flag = 0
|
||||
.d_flag = D_DISK
|
||||
};
|
||||
|
||||
|
||||
@@ -107,9 +108,6 @@ struct dkdriver sbusfpga_sd_dkdriver = {
|
||||
.d_diskstart = sbusfpga_sd_diskstart
|
||||
};
|
||||
|
||||
extern struct cfdriver sbusfpga_sd_cd;
|
||||
|
||||
|
||||
static int sdcard_init(struct sbusfpga_sd_softc *sc);
|
||||
static int dma_init(struct sbusfpga_sd_softc *sc);
|
||||
static void sdcard_read(struct sbusfpga_sd_softc *sc, uint32_t block, uint32_t count, uint8_t* buf);
|
||||
|
||||
@@ -176,6 +176,11 @@ sbusfpga_stat_ioctl (dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
|
||||
struct sbusfpga_sbus_bus_stat_softc *sc = device_lookup_private(&sbusfpga_stat_cd, minor(dev));
|
||||
int err = 0;
|
||||
|
||||
if (sc == NULL) {
|
||||
err = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case SBUSFPGA_STAT_ON:
|
||||
if (!sc->sc_enable) {
|
||||
@@ -193,7 +198,8 @@ sbusfpga_stat_ioctl (dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
|
||||
err = ENOTTY;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -138,13 +138,14 @@ headerless
|
||||
|
||||
openbios-video-height encode-int " height" property
|
||||
openbios-video-width encode-int " width" property
|
||||
depth-bits encode-int " depth" property
|
||||
line-bytes encode-int " linebytes" property
|
||||
|
||||
h# 39 encode-int 0 encode-int encode+ " intr" property
|
||||
|
||||
\ Monitor sense. Some searching suggests that this is
|
||||
\ 5 for 1024x768 and 7 for 1152x900
|
||||
h# 5 encode-int " monitor-sense" property
|
||||
h# 7 encode-int " monitor-sense" property
|
||||
|
||||
" RDOL" encode-string " manufacturer" property
|
||||
" ISO8859-1" encode-string " character-set" property
|
||||
|
||||
@@ -154,9 +154,13 @@ fload fbc_init.fth
|
||||
|
||||
openbios-video-height encode-int " height" property
|
||||
openbios-video-width encode-int " width" property
|
||||
openbios-video-width encode-int " awidth" property
|
||||
depth-bits encode-int " depth" property
|
||||
line-bytes encode-int " linebytes" property
|
||||
|
||||
h# b encode-int " chiprev" property \ rev 11
|
||||
/cg6-off-fb h# a >> encode-int " vmsize" property
|
||||
0 encode-int " dblbuf" property
|
||||
|
||||
h# 39 encode-int 0 encode-int encode+ " intr" property
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ def get_header_mapx_stuff(gname, names, sizes, types):
|
||||
|
||||
def get_prom(soc,
|
||||
version="V1.0",
|
||||
trng=False,
|
||||
usb=False,
|
||||
sdram=True,
|
||||
engine=False,
|
||||
@@ -112,19 +113,22 @@ def get_prom(soc,
|
||||
|
||||
r += "\" RDOL,sbusstat\" device-name\n"
|
||||
r += get_header_map_stuff("sbus_bus_stat", "sbus_bus_stat", 256)
|
||||
r += "finish-device\nnew-device\n"
|
||||
|
||||
r += "\" RDOL,neorv32trng\" device-name\n"
|
||||
r += get_header_map_stuff("trng", "trng", 8)
|
||||
r += ": disabletrng! ( -- )\n"
|
||||
r += " map-in-trng\n"
|
||||
r += " 1 trng-virt l! ( pattern virt -- )\n"
|
||||
r += " map-out-trng\n"
|
||||
r += ";\n"
|
||||
r += "disabletrng!\n"
|
||||
if (usb or sdram or engine or i2c or cg3 or cg6 or sdcard):
|
||||
|
||||
if (trng or usb or (sdram or not sdram) or engine or i2c or cg3 or cg6 or sdcard):
|
||||
r += "finish-device\nnew-device\n"
|
||||
|
||||
if (trng):
|
||||
r += "\" RDOL,neorv32trng\" device-name\n"
|
||||
r += get_header_map_stuff("trng", "trng", 8)
|
||||
r += ": disabletrng! ( -- )\n"
|
||||
r += " map-in-trng\n"
|
||||
r += " 1 trng-virt l! ( pattern virt -- )\n"
|
||||
r += " map-out-trng\n"
|
||||
r += ";\n"
|
||||
r += "disabletrng!\n"
|
||||
if (usb or (sdram or not sdram) or engine or i2c or cg3 or cg6 or sdcard):
|
||||
r += "finish-device\nnew-device\n"
|
||||
|
||||
if (usb):
|
||||
r += "\" generic-ohci\" device-name\n"
|
||||
r += "sbusfpga_irq_usb_host encode-int \" interrupts\" property\n"
|
||||
@@ -142,7 +146,7 @@ def get_prom(soc,
|
||||
r += " map-out-usb_host_ctrl\n"
|
||||
r += ";\n"
|
||||
r += "my-reset!\n"
|
||||
if (sdram or engine or i2c or cg3 or cg6 or sdcard):
|
||||
if ((sdram or not sdram) or engine or i2c or cg3 or cg6 or sdcard):
|
||||
r += "finish-device\nnew-device\n"
|
||||
|
||||
if (sdram):
|
||||
@@ -150,9 +154,13 @@ def get_prom(soc,
|
||||
r += get_header_mapx_stuff("mregs", [ "ddrphy", "sdram", "exchange_with_mem" ], [ 4096, 4096, 4096 ], [ "csr", "csr", "csr" ])
|
||||
r += "sbusfpga_irq_sdram encode-int \" interrupts\" property\n"
|
||||
r += "fload sdram_init.fth\ninit!\n"
|
||||
if (engine or i2c or cg3 or cg6 or sdcard):
|
||||
r += "finish-device\nnew-device\n"
|
||||
|
||||
else:
|
||||
r += "\" RDOL,hidden_sdram\" device-name\n"
|
||||
r += get_header_mapx_stuff("mregs", [ "ddrphy", "sdram" ], [ 4096, 4096 ], [ "csr", "csr" ])
|
||||
r += "fload sdram_init.fth\ninit!\n"
|
||||
if (engine or i2c or cg3 or cg6 or sdcard):
|
||||
r += "finish-device\nnew-device\n"
|
||||
|
||||
if (engine):
|
||||
r += "\" betrustedc25519e\" device-name\n"
|
||||
r += ": sbusfpga_regionaddr_curve25519engine-microcode sbusfpga_regionaddr_curve25519engine ;\n"
|
||||
|
||||
@@ -50,16 +50,14 @@ class _CRG(Module):
|
||||
def __init__(self, platform, sys_clk_freq,
|
||||
usb=False,
|
||||
usb_clk_freq=48e6,
|
||||
sdram=True,
|
||||
engine=False,
|
||||
i2c=False,
|
||||
cg3=False,
|
||||
pix_clk=0):
|
||||
self.clock_domains.cd_sys = ClockDomain() # 100 MHz PLL, reset'ed by SBus (via pll), SoC/Wishbone main clock
|
||||
if (sdram):
|
||||
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
|
||||
self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True)
|
||||
self.clock_domains.cd_idelay = ClockDomain()
|
||||
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
|
||||
self.clock_domains.cd_sys4x_dqs = ClockDomain(reset_less=True)
|
||||
self.clock_domains.cd_idelay = ClockDomain()
|
||||
## self.clock_domains.cd_sys = ClockDomain() # 16.67-25 MHz SBus, reset'ed by SBus, native SBus & SYS clock domain
|
||||
self.clock_domains.cd_native = ClockDomain(reset_less=True) # 48MHz native, non-reset'ed (for power-on long delay, never reset, we don't want the delay after a warm reset)
|
||||
self.clock_domains.cd_sbus = ClockDomain() # 16.67-25 MHz SBus, reset'ed by SBus, native SBus clock domain
|
||||
@@ -110,13 +108,12 @@ class _CRG(Module):
|
||||
pll.create_clkout(self.cd_sys, sys_clk_freq, gated_replicas={self.cd_clk100_gated : pll.locked & self.curve25519_on})
|
||||
platform.add_platform_command("create_generated_clock -name sysclk [get_pins {{{{MMCME2_ADV/CLKOUT{}}}}}]".format(num_clk))
|
||||
num_clk = num_clk + 1
|
||||
if (sdram):
|
||||
pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq)
|
||||
platform.add_platform_command("create_generated_clock -name sys4xclk [get_pins {{{{MMCME2_ADV/CLKOUT{}}}}}]".format(num_clk))
|
||||
num_clk = num_clk + 1
|
||||
pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90)
|
||||
platform.add_platform_command("create_generated_clock -name sys4x90clk [get_pins {{{{MMCME2_ADV/CLKOUT{}}}}}]".format(num_clk))
|
||||
num_clk = num_clk + 1
|
||||
pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq)
|
||||
platform.add_platform_command("create_generated_clock -name sys4xclk [get_pins {{{{MMCME2_ADV/CLKOUT{}}}}}]".format(num_clk))
|
||||
num_clk = num_clk + 1
|
||||
pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90)
|
||||
platform.add_platform_command("create_generated_clock -name sys4x90clk [get_pins {{{{MMCME2_ADV/CLKOUT{}}}}}]".format(num_clk))
|
||||
num_clk = num_clk + 1
|
||||
self.comb += pll.reset.eq(~rst_sbus) # | ~por_done
|
||||
platform.add_false_path_constraints(self.cd_native.clk, self.cd_sbus.clk) # FIXME?
|
||||
platform.add_false_path_constraints(self.cd_sbus.clk, self.cd_native.clk) # FIXME?
|
||||
@@ -176,18 +173,17 @@ class _CRG(Module):
|
||||
num_adv = num_adv + 1
|
||||
num_clk = 0
|
||||
|
||||
if (sdram):
|
||||
self.submodules.pll_idelay = pll_idelay = S7MMCM(speedgrade=platform.speedgrade)
|
||||
#pll_idelay.register_clkin(clk48, 48e6)
|
||||
pll_idelay.register_clkin(self.clk48_bufg, 48e6)
|
||||
pll_idelay.create_clkout(self.cd_idelay, 200e6, margin = 0)
|
||||
platform.add_platform_command("create_generated_clock -name idelayclk [get_pins {{{{MMCME2_ADV_{}/CLKOUT{}}}}}]".format(num_adv, num_clk))
|
||||
num_clk = num_clk + 1
|
||||
self.comb += pll_idelay.reset.eq(~rst_sbus) # | ~por_done
|
||||
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
|
||||
num_adv = num_adv + 1
|
||||
num_clk = 0
|
||||
|
||||
self.submodules.pll_idelay = pll_idelay = S7MMCM(speedgrade=platform.speedgrade)
|
||||
#pll_idelay.register_clkin(clk48, 48e6)
|
||||
pll_idelay.register_clkin(self.clk48_bufg, 48e6)
|
||||
pll_idelay.create_clkout(self.cd_idelay, 200e6, margin = 0)
|
||||
platform.add_platform_command("create_generated_clock -name idelayclk [get_pins {{{{MMCME2_ADV_{}/CLKOUT{}}}}}]".format(num_adv, num_clk))
|
||||
num_clk = num_clk + 1
|
||||
self.comb += pll_idelay.reset.eq(~rst_sbus) # | ~por_done
|
||||
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
|
||||
num_adv = num_adv + 1
|
||||
num_clk = 0
|
||||
|
||||
if (cg3):
|
||||
self.submodules.video_pll = video_pll = S7MMCM(speedgrade=platform.speedgrade)
|
||||
video_pll.register_clkin(self.clk48_bufg, 48e6)
|
||||
@@ -215,7 +211,7 @@ class SBusFPGA(SoCCore):
|
||||
#if self.irq.enabled:
|
||||
#self.irq.add(name, use_loc_if_exists=True)
|
||||
|
||||
def __init__(self, variant, version, sys_clk_freq, usb, sdram, engine, i2c, cg3, cg6, cg3_res, sdcard, **kwargs):
|
||||
def __init__(self, variant, version, sys_clk_freq, trng, usb, sdram, engine, i2c, cg3, cg6, cg3_res, sdcard, **kwargs):
|
||||
print(f"Building SBusFPGA for board version {version}")
|
||||
|
||||
kwargs["cpu_type"] = "None"
|
||||
@@ -288,7 +284,7 @@ class SBusFPGA(SoCCore):
|
||||
"dvma_bridge": 0xfc000000, # 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, sdram=sdram, engine=engine, cg3=(cg3 or cg6), pix_clk=litex.soc.cores.video.video_timings[cg3_res]["pix_clk"])
|
||||
self.submodules.crg = _CRG(platform=platform, sys_clk_freq=sys_clk_freq, usb=usb, usb_clk_freq=48e6, engine=engine, cg3=(cg3 or cg6), pix_clk=litex.soc.cores.video.video_timings[cg3_res]["pix_clk"])
|
||||
#self.platform.add_period_constraint(self.platform.lookup_request("SBUS_3V3_CLK", loose=True), 1e9/25e6) # SBus max
|
||||
|
||||
## add our custom timings after the clocks have been defined
|
||||
@@ -345,19 +341,16 @@ class SBusFPGA(SoCCore):
|
||||
#getattr(self,"prom").mem.init = prom_data
|
||||
#getattr(self,"prom").mem.depth = 2**14
|
||||
|
||||
if (sdram):
|
||||
self.submodules.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"),
|
||||
memtype = "DDR3",
|
||||
nphases = 4,
|
||||
sys_clk_freq = sys_clk_freq)
|
||||
self.add_sdram("sdram",
|
||||
phy = self.ddrphy,
|
||||
module = MT41J128M16(sys_clk_freq, "1:4"),
|
||||
l2_cache_size = 0,
|
||||
)
|
||||
avail_sdram = self.bus.regions["main_ram"].size
|
||||
else:
|
||||
avail_sdram = 0
|
||||
self.submodules.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"),
|
||||
memtype = "DDR3",
|
||||
nphases = 4,
|
||||
sys_clk_freq = sys_clk_freq)
|
||||
self.add_sdram("sdram",
|
||||
phy = self.ddrphy,
|
||||
module = MT41J128M16(sys_clk_freq, "1:4"),
|
||||
l2_cache_size = 0,
|
||||
)
|
||||
avail_sdram = self.bus.regions["main_ram"].size
|
||||
|
||||
base_fb = self.wb_mem_map["main_ram"] + avail_sdram - 1048576 # placeholder
|
||||
if (cg3 or cg6):
|
||||
@@ -390,10 +383,10 @@ class SBusFPGA(SoCCore):
|
||||
# burst_size=16 should work on Ultra systems, but then they probably should go for 64-bits ET as well...
|
||||
# Older systems are probably limited to burst_size=4, (it should always be available)
|
||||
burst_size=8
|
||||
self.submodules.tosbus_fifo = ClockDomainsRenamer({"read": "sbus", "write": "sys"})(AsyncFIFOBuffered(width=(32+burst_size*32), depth=burst_size))
|
||||
self.submodules.fromsbus_fifo = ClockDomainsRenamer({"write": "sbus", "read": "sys"})(AsyncFIFOBuffered(width=((30-log2_int(burst_size))+burst_size*32), depth=burst_size))
|
||||
self.submodules.fromsbus_req_fifo = ClockDomainsRenamer({"read": "sbus", "write": "sys"})(AsyncFIFOBuffered(width=((30-log2_int(burst_size))+32), depth=burst_size))
|
||||
if (sdram):
|
||||
self.submodules.tosbus_fifo = ClockDomainsRenamer({"read": "sbus", "write": "sys"})(AsyncFIFOBuffered(width=(32+burst_size*32), depth=burst_size))
|
||||
self.submodules.fromsbus_fifo = ClockDomainsRenamer({"write": "sbus", "read": "sys"})(AsyncFIFOBuffered(width=((30-log2_int(burst_size))+burst_size*32), depth=burst_size))
|
||||
self.submodules.fromsbus_req_fifo = ClockDomainsRenamer({"read": "sbus", "write": "sys"})(AsyncFIFOBuffered(width=((30-log2_int(burst_size))+32), depth=burst_size))
|
||||
self.submodules.dram_dma_writer = LiteDRAMDMAWriter(port=self.sdram.crossbar.get_port(mode="write", data_width=burst_size*32),
|
||||
fifo_depth=4,
|
||||
fifo_buffered=True)
|
||||
@@ -420,10 +413,6 @@ class SBusFPGA(SoCCore):
|
||||
# the 74LVC2G07 takes care of the Z state: 1 -> Z on the bus, 0 -> 0 on the bus (asserted interrupt)
|
||||
self.comb += pad_sdram_interrupt.eq(sig_sdram_interrupt)
|
||||
self.comb += sig_sdram_interrupt.eq(~self.exchange_with_mem.irq) ##
|
||||
else:
|
||||
self.submodules.tosbus_fifo = None
|
||||
self.submodules.fromsbus_fifo = None
|
||||
self.submodules.fromsbus_req_fifo = None
|
||||
|
||||
_sbus_bus = SBusFPGABus(platform=self.platform,
|
||||
hold_reset=hold_reset,
|
||||
@@ -461,7 +450,8 @@ class SBusFPGA(SoCCore):
|
||||
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.submodules.trng = NeoRV32TrngWrapper(platform=platform)
|
||||
if (trng):
|
||||
self.submodules.trng = NeoRV32TrngWrapper(platform=platform)
|
||||
|
||||
# beware the naming, as 'clk50' 'sysclk' 'clk200' are used in the original platform constraints
|
||||
# the local engine.py was slightly modified to have configurable names, so we can have 'clk50', 'clk100', 'clk200'
|
||||
@@ -521,7 +511,8 @@ def main():
|
||||
parser.add_argument("--variant", default="ztex2.13a", help="ZTex board variant (default ztex2.13a)")
|
||||
parser.add_argument("--version", default="V1.2", help="SBusFPGA board version (default V1.2)")
|
||||
parser.add_argument("--sys-clk-freq", default=100e6, help="SBusFPGA system clock (default 100e6 = 100 MHz)")
|
||||
parser.add_argument("--sdram", action="store_true", help="add a SDRAM controller (mandatory) [all]")
|
||||
parser.add_argument("--trng", action="store_true", help="add true random number generator [all]")
|
||||
parser.add_argument("--sdram", action="store_true", help="expose the sdram to the host [all]")
|
||||
parser.add_argument("--usb", action="store_true", help="add a USB OHCI controller [V1.2]")
|
||||
parser.add_argument("--engine", action="store_true", help="add a Engine crypto core [all]")
|
||||
parser.add_argument("--i2c", action="store_true", help="add an I2C bus [none, placeholder]")
|
||||
@@ -534,8 +525,7 @@ def main():
|
||||
args = parser.parse_args()
|
||||
|
||||
if (args.sdram == False):
|
||||
print(" ***** ERROR ***** : disabling the SDRAM doesn't actually work (too integrated in the SBus FSM...)\n")
|
||||
assert(False)
|
||||
print(" ***** WARNING ***** : not enablling the SDRAM still adds a controller, but doesn't add the DMA engines\n")
|
||||
if (args.usb and (args.version == "V1.0")):
|
||||
print(" ***** WARNING ***** : USB on V1.0 is an ugly hack \n");
|
||||
if (args.i2c):
|
||||
@@ -551,6 +541,7 @@ def main():
|
||||
variant=args.variant,
|
||||
version=args.version,
|
||||
sys_clk_freq=int(float(args.sys_clk_freq)),
|
||||
trng=args.trng,
|
||||
sdram=args.sdram,
|
||||
usb=args.usb,
|
||||
engine=args.engine,
|
||||
@@ -596,7 +587,8 @@ def main():
|
||||
csr_base = soc.mem_regions['csr'].origin)
|
||||
write_to_file(os.path.join(f"prom_csr_{version_for_filename}.fth"), csr_forth_contents)
|
||||
|
||||
prom_content = sbus_to_fpga_prom.get_prom(soc=soc, version=args.version,
|
||||
prom_content = sbus_to_fpga_prom.get_prom(soc=soc, version=args.version,
|
||||
trng=args.trng,
|
||||
usb=args.usb,
|
||||
sdram=args.sdram,
|
||||
engine=args.engine,
|
||||
|
||||
310
sbus-to-ztex-gateware-migen/sdcard.fth
Normal file
310
sbus-to-ztex-gateware-migen/sdcard.fth
Normal file
@@ -0,0 +1,310 @@
|
||||
\ SDCORE
|
||||
|
||||
: sdcore_cmd_argument_write! ( val -- )
|
||||
sdcore-virt h# 0 + l!
|
||||
;
|
||||
: sdcore_cmd_command_write! ( val -- )
|
||||
sdcore-virt h# 4 + l!
|
||||
;
|
||||
: sdcore_cmd_send_write! ( val -- )
|
||||
sdcore-virt h# 8 + l!
|
||||
;
|
||||
\ 0c, 10, 14, 18 : response
|
||||
: sdcore_cmd_event_read@ ( -- val )
|
||||
sdcore-virt h# 1c + l@
|
||||
;
|
||||
: sdcore_data_event_read@ ( -- val )
|
||||
sdcore-virt h# 20 + l@
|
||||
;
|
||||
: sdcore_block_length_write! ( val -- )
|
||||
sdcore-virt h# 24 + l!
|
||||
;
|
||||
: sdcore_block_count_write! ( val -- )
|
||||
sdcore-virt h# 28 + l!
|
||||
;
|
||||
|
||||
\ SDPHY
|
||||
\ 0 : card detect
|
||||
: sdphy_clocker_divider_write! ( val -- )
|
||||
sdphy-virt h# 4 + l!
|
||||
;
|
||||
: sdphy_init_initialize_write! ( val -- )
|
||||
sdphy-virt h# 8 + l!
|
||||
;
|
||||
\ c : dataw status
|
||||
|
||||
\ HELPERS
|
||||
|
||||
: sdcard_wait_cmd_done ( -- res )
|
||||
0 ( dummy result )
|
||||
begin
|
||||
drop ( drop previous result )
|
||||
sdcore_cmd_event_read@
|
||||
1 ms \ should be 10 us
|
||||
dup h# 1 and 0<>
|
||||
until
|
||||
dup h# 4 and 0<> if drop h# 2 else
|
||||
dup h# 8 and 0<> if drop h# 1 else
|
||||
drop 0
|
||||
then
|
||||
then
|
||||
;
|
||||
|
||||
: sdcard_wait_data_done ( -- res )
|
||||
0 ( dummy result )
|
||||
begin
|
||||
drop ( drop previous result )
|
||||
sdcore_data_event_read@
|
||||
1 ms \ should be 10 us
|
||||
dup h# 1 and 0<>
|
||||
until
|
||||
dup h# 4 and 0<> if drop h# 2 else
|
||||
dup h# 8 and 0<> if drop h# 1 else
|
||||
drop 0
|
||||
then
|
||||
then
|
||||
;
|
||||
|
||||
: sdcard_send_command ( arg cmd rsp -- res )
|
||||
rot ( arg cmd rsp -- cmd rsp arg )
|
||||
sdcore_cmd_argument_write!
|
||||
swap ( cmd rsp -- rsp cmd )
|
||||
h# 8 <<
|
||||
or
|
||||
sdcore_cmd_command_write!
|
||||
h# 1 sdcore_cmd_send_write!
|
||||
sdcard_wait_cmd_done
|
||||
;
|
||||
|
||||
: sdcard_go_idle ( -- res )
|
||||
0 0 0 sdcard_send_command
|
||||
;
|
||||
|
||||
: sdcard_send_ext_csd ( -- res )
|
||||
h# 01aa h# 8 h# 1 sdcard_send_command
|
||||
;
|
||||
|
||||
: sdcard_all_send_cid ( -- res)
|
||||
h# 0 h# 2 h# 2 sdcard_send_command
|
||||
;
|
||||
|
||||
: sdcard_send_cid ( rca -- res )
|
||||
h# 10 << h# a h# 2 sdcard_send_command
|
||||
;
|
||||
|
||||
: sdcard_send_csd ( rca -- res )
|
||||
h# 10 << h# 9 h# 2 sdcard_send_command
|
||||
;
|
||||
|
||||
: sdcard_select_card ( rca -- res )
|
||||
h# 10 << h# 7 h# 3 sdcard_send_command
|
||||
;
|
||||
|
||||
: sdcard_app_set_bus_width ( -- res )
|
||||
h# 2 h# 6 h# 1 sdcard_send_command
|
||||
;
|
||||
|
||||
: sdcard_app_cmd ( rca -- res )
|
||||
h# 10 << h# 37 h# 1 sdcard_send_command
|
||||
;
|
||||
|
||||
: sdcard_app_send_op_cond ( hcs -- res )
|
||||
0<> if h# 60000000 else h# 0 then
|
||||
h# 10ff8000 or
|
||||
h# 29 h# 3 sdcard_send_command
|
||||
;
|
||||
|
||||
: sdcard_set_relative_address ( -- res )
|
||||
0 3 1 sdcard_send_command
|
||||
;
|
||||
|
||||
: sdcard_decode_cid ( -- ) \ finish me
|
||||
sdcore-virt h# 0c + l@ ( 0:3p )
|
||||
sdcore-virt h# 10 + l@ ( 1:2p )
|
||||
sdcore-virt h# 14 + l@ ( 2:over )
|
||||
sdcore-virt h# 18 + l@ ( 3:dup )
|
||||
\ .( CID registers, current stack: ) .s cr
|
||||
\ 3 pick h# 10 >> h# ffff and
|
||||
\ .( Mfr id: ) . cr
|
||||
\ 3 pick h# ffff and
|
||||
\ .( App id: ) . cr
|
||||
2drop
|
||||
2drop
|
||||
;
|
||||
|
||||
: sdcard_switch ( mode group value -- res )
|
||||
rot ( mode group value -- group value mode )
|
||||
h# 1f << h# ffffff or
|
||||
2 pick ( group value arg -- group value arg group )
|
||||
h# 4 * h# f swap << h# ffffffff xor
|
||||
and
|
||||
swap ( group value arg -- group arg value )
|
||||
rot ( group arg value -- arg value group )
|
||||
h# 4 * <<
|
||||
or
|
||||
\ .( Switch arg, current stack: ) .s cr
|
||||
h# 40 sdcore_block_length_write!
|
||||
h# 1 sdcore_block_count_write!
|
||||
begin
|
||||
dup h# 6 h# 21 sdcard_send_command
|
||||
0=
|
||||
until
|
||||
drop
|
||||
sdcard_wait_data_done
|
||||
;
|
||||
|
||||
: sdcard_app_send_scr ( -- res )
|
||||
h# 8 sdcore_block_length_write!
|
||||
h# 1 sdcore_block_count_write!
|
||||
begin
|
||||
0 h# 33 h# 21 sdcard_send_command
|
||||
0<>
|
||||
until
|
||||
sdcard_wait_data_done
|
||||
;
|
||||
|
||||
: sdcard_app_set_blocklen ( blklen -- res )
|
||||
h# 10 h# 1 sdcard_send_command
|
||||
;
|
||||
|
||||
\ VARIABLE
|
||||
|
||||
-1 instance value sdcard-good
|
||||
-1 instance value rca
|
||||
-1 instance value max_rd_blk_len
|
||||
-1 instance value max_size_in_blk
|
||||
|
||||
\ MORE HELPERS
|
||||
|
||||
: sdcard_decode_rca ( -- )
|
||||
sdcore-virt h# 18 + l@
|
||||
h# 10 >> h# ffff and
|
||||
to rca
|
||||
;
|
||||
|
||||
: sdcard_decode_csd ( -- )
|
||||
sdcore-virt h# 0c + l@ ( 0:3p )
|
||||
sdcore-virt h# 10 + l@ ( 1:2p )
|
||||
sdcore-virt h# 14 + l@ ( 2:over )
|
||||
sdcore-virt h# 18 + l@ ( 3:dup )
|
||||
\ .( CSD registers, current stack: ) .s cr
|
||||
2 pick h# 10 >> h# f and h# 1 swap <<
|
||||
to max_rd_blk_len
|
||||
over h# 10 >>
|
||||
3 pick ( one deeper as we have an extra element on the stack )
|
||||
h# ff and h# 10 <<
|
||||
+ 1+ h# 400 *
|
||||
to max_size_in_blk
|
||||
2drop
|
||||
2drop
|
||||
;
|
||||
|
||||
\ INIT
|
||||
|
||||
\ CID Register: 0x1b534d45_42315154_309d595f_40014947 Manufacturer ID: 0x1b53 Application ID 0x4d45 Product name: B1QT0 CRC: 47 Production date(m/yy): 9/20 PSN: 9d595f40 OID: SM
|
||||
\ CSD Register: 0x400e0032_5b590000_ee7f7f80_0a404055 Max data transfer rate: 64 MB/s Max read block length: 512 bytes Device size: 29 GiB
|
||||
\ rca is 0x00000001
|
||||
\ switch arg is 0x80fffff1
|
||||
|
||||
: sdcard-init-full ( -- )
|
||||
0 to sdcard-good
|
||||
h# 100 sdphy_clocker_divider_write!
|
||||
1 ms
|
||||
|
||||
0 ( timeout )
|
||||
begin
|
||||
1+
|
||||
( Set SDCard in SPI Mode [generate 80 dummy clocks] )
|
||||
h# 1 sdphy_init_initialize_write!
|
||||
1 ms
|
||||
( Set SDCard in Idle state )
|
||||
sdcard_go_idle
|
||||
1 ms
|
||||
0=
|
||||
over 1000 >=
|
||||
or
|
||||
until
|
||||
\ .( After first timeout loop stack is: ) .s cr
|
||||
1000 >= if
|
||||
\ .( sdcard timeout 1 ) cr
|
||||
exit
|
||||
then
|
||||
|
||||
( Set SDCard voltages, only supported by ver2.00+ SDCards )
|
||||
sdcard_send_ext_csd
|
||||
dup 0<> if .( sdcard_send_ext_csd failed ) . cr exit then drop
|
||||
|
||||
( Set SD clk freq to Operational frequency )
|
||||
h# 4 sdphy_clocker_divider_write!
|
||||
1 ms
|
||||
|
||||
( Set SDCard in Operational state )
|
||||
0 ( timeout )
|
||||
begin
|
||||
1+
|
||||
0 sdcard_app_cmd
|
||||
drop
|
||||
1 sdcard_app_send_op_cond
|
||||
1 ms
|
||||
0<>
|
||||
over 1000 >=
|
||||
or
|
||||
until
|
||||
\ .( After second timeout loop stack is: ) .s cr
|
||||
1000 >= if
|
||||
\ .( sdcard timeout 2 ) cr
|
||||
exit
|
||||
then
|
||||
|
||||
( Send identification )
|
||||
sdcard_all_send_cid
|
||||
dup 0<> if .( sdcard_all_send_cid failed ) . cr exit then drop
|
||||
sdcard_decode_cid
|
||||
|
||||
( Set Relative Card Address )
|
||||
sdcard_set_relative_address
|
||||
dup 0<> if .( sdcard_set_relative_address failed ) . cr exit then drop
|
||||
sdcard_decode_rca
|
||||
rca sdcard_send_cid
|
||||
dup 0<> if .( sdcard_send_cid failed ) . cr exit then drop
|
||||
rca sdcard_send_csd
|
||||
dup 0<> if .( sdcard_send_csd failed ) . cr exit then drop
|
||||
sdcard_decode_csd
|
||||
\ .( Max read block length: ) max_rd_blk_len . cr
|
||||
\ .( Max size in block: ) max_size_in_blk . cr
|
||||
|
||||
( Select card )
|
||||
rca sdcard_select_card
|
||||
dup 0<> if .( sdcard_select_card failed ) . cr exit then drop
|
||||
|
||||
( Set bus width )
|
||||
rca sdcard_app_cmd
|
||||
dup 0<> if .( sdcard_app_cmd failed ) . cr exit then drop
|
||||
sdcard_app_set_bus_width
|
||||
dup 0<> if .( sdcard_app_set_bus_width failed ) . cr exit then drop
|
||||
|
||||
( Switch speed )
|
||||
h# 1 h# 0 h# 1 sdcard_switch
|
||||
dup 0<> if .( sdcard_switch failed ) . cr exit then drop
|
||||
|
||||
\ .( after switch speed stack is ) .s cr
|
||||
|
||||
( Send SCR )
|
||||
rca sdcard_app_cmd
|
||||
dup 0<> if .( sdcard_app_cmd failed ) . cr exit then drop
|
||||
sdcard_app_send_scr
|
||||
dup 0<> if .( sdcard_app_send_scr failed ) . cr exit then drop
|
||||
|
||||
\ .( after send scr stack is ) .s cr
|
||||
|
||||
( Set block length )
|
||||
h# 200 sdcard_app_set_blocklen
|
||||
dup 0<> if .( sdcard_app_set_blocklen failed ) . cr exit then drop
|
||||
1 to sdcard-good
|
||||
|
||||
\ .( at the end stack is ) .s cr
|
||||
;
|
||||
|
||||
map-in-sdcard
|
||||
sdcard-init-full
|
||||
map-out-sdcard
|
||||
329
sbus-to-ztex-gateware-migen/sdcard_access.fth
Normal file
329
sbus-to-ztex-gateware-migen/sdcard_access.fth
Normal file
@@ -0,0 +1,329 @@
|
||||
\ DMA BLOCK2MEM (read)
|
||||
|
||||
headers
|
||||
|
||||
" block" encode-string " device_type" property \ underscore in the peoprtye name...
|
||||
|
||||
0 instance value offset-low
|
||||
0 instance value offset-high
|
||||
0 instance value label-package
|
||||
0 value deblocker-package
|
||||
|
||||
h# 10000 constant maxdmasize
|
||||
-1 instance value dmasize
|
||||
-1 instance value dmaaddr
|
||||
-1 instance value dmadev
|
||||
|
||||
: sdblock2mem_dma_base_write! ( val -- )
|
||||
0 sdblock2mem-virt h# 0 + l! ( MSB )
|
||||
sdblock2mem-virt h# 4 + l! ( LSB )
|
||||
;
|
||||
: sdblock2mem_dma_length_write! ( val -- )
|
||||
sdblock2mem-virt h# 8 + l!
|
||||
;
|
||||
: sdblock2mem_dma_enable_write! ( val -- )
|
||||
sdblock2mem-virt h# c + l!
|
||||
;
|
||||
: sdblock2mem_dma_done_read@ ( -- val )
|
||||
sdblock2mem-virt h# 10 + l@
|
||||
;
|
||||
|
||||
: sdcard_read_single_block ( block# -- res )
|
||||
h# 200 sdcore_block_length_write!
|
||||
1 sdcore_block_count_write!
|
||||
begin
|
||||
dup h# 11 h# 21 sdcard_send_command
|
||||
0=
|
||||
until
|
||||
drop
|
||||
sdcard_wait_data_done
|
||||
;
|
||||
: sdcard_read_multiple_blocks ( block# #blocks -- res )
|
||||
\ .( sdcard_read_multiple_blocks: stack is ) .s cr
|
||||
h# 200 sdcore_block_length_write!
|
||||
dup sdcore_block_count_write!
|
||||
begin
|
||||
over h# 12 h# 21 sdcard_send_command
|
||||
0=
|
||||
until
|
||||
2drop
|
||||
sdcard_wait_data_done
|
||||
\ .( sdcard_read_multiple_blocks: END stack is ) .s cr
|
||||
;
|
||||
|
||||
: sdcard_write_single_block ( block# -- res )
|
||||
h# 200 sdcore_block_length_write!
|
||||
1 sdcore_block_count_write!
|
||||
begin
|
||||
dup h# 18 h# 41 sdcard_send_command
|
||||
0=
|
||||
until
|
||||
drop
|
||||
sdcard_wait_data_done
|
||||
;
|
||||
: sdcard_write_multiple_blocks ( block# #blocks -- res )
|
||||
h# 200 sdcore_block_length_write!
|
||||
dup sdcore_block_count_write!
|
||||
begin
|
||||
over h# 19 h# 41 sdcard_send_command
|
||||
0=
|
||||
until
|
||||
2drop
|
||||
sdcard_wait_data_done
|
||||
;
|
||||
|
||||
: sdcard_stop_transmission ( -- res )
|
||||
h# 0 h# c h# 3 sdcard_send_command
|
||||
;
|
||||
|
||||
external
|
||||
|
||||
: dma-alloc ( n -- vaddr )
|
||||
\ .( dma-alloc: stack is ) .s cr
|
||||
" dma-alloc" $call-parent
|
||||
\ .( dma-alloc: END stack is ) .s cr
|
||||
;
|
||||
: dma-free ( vaddr n -- )
|
||||
\ .( dma-free: stack is ) .s cr
|
||||
" dma-free" $call-parent
|
||||
;
|
||||
: dma-map-in ( vaddr n cache? -- devaddr )
|
||||
\ .( dma-map-in: stack is ) .s cr
|
||||
" dma-map-in" $call-parent
|
||||
\ .( dma-map-in: END stack is ) .s cr
|
||||
;
|
||||
: dma-map-out ( vaddr devaddr n -- )
|
||||
\ .( dma-map-out: stack is ) .s cr
|
||||
" dma-map-out" $call-parent
|
||||
;
|
||||
\ dma-sync could be dummy routine if parent device doesn't support.
|
||||
: dma-sync ( virt-addr dev-addr size -- )
|
||||
" dma-sync" my-parent ['] $call-method catch if
|
||||
2drop 2drop 2drop
|
||||
then
|
||||
;
|
||||
|
||||
: dma-setup ( adr #bytes -- )
|
||||
to dmasize
|
||||
to dmaaddr
|
||||
dmaaddr dmasize false " dma-map-in" $call-parent to dmadev
|
||||
;
|
||||
: dma-release ( -- )
|
||||
dmaaddr dmadev dmasize " dma-map-out" $call-parent
|
||||
;
|
||||
|
||||
\ : get-dmabuf ( -- )
|
||||
\ dmasize dma-alloc to dmaaddr
|
||||
\ dmaaddr dmasize false dma-map-in to dmadev
|
||||
\ ;
|
||||
|
||||
\ : drop-dmabuf ( -- )
|
||||
\ dmaaddr dmadev dmasize dma-map-out
|
||||
\ -1 to dmadev
|
||||
\ dmaaddr dmasize dma-free
|
||||
\ -1 to dmaaddr
|
||||
\ ;
|
||||
|
||||
external
|
||||
|
||||
: read-blocks ( adr block# #blocks -- #done)
|
||||
\ .( read-blocks: stack is ) .s cr
|
||||
\ .( RB: ) .s cr
|
||||
|
||||
\ h# 80 0 do
|
||||
\ 2 pick i 4 * + h# deadbeef swap l!
|
||||
\ loop
|
||||
|
||||
2 pick over h# 200 * dma-setup
|
||||
|
||||
dmaaddr dmadev dmasize dma-sync
|
||||
|
||||
0 sdblock2mem_dma_enable_write!
|
||||
\ 2 pick sdblock2mem_dma_base_write!
|
||||
dmadev sdblock2mem_dma_base_write!
|
||||
dup h# 200 * sdblock2mem_dma_length_write!
|
||||
1 sdblock2mem_dma_enable_write!
|
||||
|
||||
2dup sdcard_read_multiple_blocks
|
||||
dup 0<> if .( sdcard_read_multiple_blocks failed ) . cr 0 exit then drop
|
||||
begin
|
||||
1 ms
|
||||
sdblock2mem_dma_done_read@
|
||||
1 and 0<>
|
||||
until
|
||||
dup 1 > if sdcard_stop_transmission drop then
|
||||
|
||||
dmaaddr dmadev dmasize dma-sync
|
||||
|
||||
dma-release
|
||||
|
||||
\ dup h# 80 * 0 do
|
||||
\ dmaaddr i 4 * + l@
|
||||
\ 3 pick i 4 * + l!
|
||||
\ loop
|
||||
|
||||
nip
|
||||
|
||||
\ h# 80 h# 70 do
|
||||
\ over i 4 * dup .( @ ) . + l@ .( : ) . .( , )
|
||||
\ loop cr
|
||||
|
||||
nip
|
||||
\ .( read-blocks: END stack is ) .s cr
|
||||
;
|
||||
|
||||
headers
|
||||
|
||||
\ -1 instance value cur_adr
|
||||
\ -1 instance value cur_block#
|
||||
\ -1 instance value cur_#blocks
|
||||
\ -1 instance value cur_#blocks_i
|
||||
\ -1 instance value cur_#blocks_done
|
||||
|
||||
external
|
||||
|
||||
\ : read-blocks-wra ( adr block# #blocks -- #done)
|
||||
\ .( read-blocks: stack is ) .s cr
|
||||
\ to cur_#blocks
|
||||
\ to cur_block#
|
||||
\ to cur_adr
|
||||
\ 0 to cur_#blocks_i
|
||||
\ 0 to cur_#blocks_done
|
||||
\ begin
|
||||
\ cur_adr
|
||||
\ cur_block#
|
||||
\ cur_#blocks 128 > if 128 else cur_#blocks then
|
||||
\ dup to cur_#blocks_i
|
||||
\ \ sd-r-blocks-basic
|
||||
\ read-blocks
|
||||
\ drop
|
||||
\ cur_adr cur_#blocks_i h# 200 * + to cur_adr
|
||||
\ cur_block# cur_#blocks_i + to cur_block#
|
||||
\ cur_#blocks cur_#blocks_i - to cur_#blocks
|
||||
\ cur_#blocks_done cur_#blocks_i + to cur_#blocks_done
|
||||
\ cur_#blocks 0=
|
||||
\ until
|
||||
\ cur_#blocks_done
|
||||
\ ;
|
||||
|
||||
: block-size ( -- val )
|
||||
h# 200
|
||||
;
|
||||
|
||||
: max-transfer ( -- val )
|
||||
maxdmasize
|
||||
;
|
||||
|
||||
: write-blocks ( adr block# #blocks -- #done )
|
||||
\ .( write-blocks: stack is ) .s cr
|
||||
nip nip \ FIXME
|
||||
;
|
||||
|
||||
: selftest ( -- fail? )
|
||||
false \ FIXME
|
||||
;
|
||||
: reset ( -- )
|
||||
\ FIXME
|
||||
;
|
||||
: seek ( offset.low offset.high -- okay? )
|
||||
\ .( seek: stack is ) .s cr
|
||||
\ .( S: ) .s cr
|
||||
offset-low offset-high d+ " seek" deblocker-package $call-method
|
||||
;
|
||||
: read ( adr len -- actual-len )
|
||||
\ .( read: stack is ) .s cr
|
||||
\ .( R: ) .s cr
|
||||
" read" deblocker-package $call-method
|
||||
;
|
||||
: write ( adr len -- actual-len )
|
||||
\ .( write: stack is ) .s cr
|
||||
\ .( W: ) .s cr
|
||||
" write" deblocker-package $call-method
|
||||
;
|
||||
: load ( adr -- size )
|
||||
\ .( load: stack is ) .s cr
|
||||
\ .( L: ) .s cr
|
||||
" load" label-package $call-method
|
||||
;
|
||||
|
||||
: init-label-package ( -- okay? )
|
||||
\ .( init-label-package: stack is ) .s cr
|
||||
\ 0 to offset-high
|
||||
\ 0 to offset-low
|
||||
my-args " disk-label" $open-package to label-package
|
||||
label-package if
|
||||
0 0 " offset" label-package $call-method
|
||||
to offset-high
|
||||
to offset-low
|
||||
\ .( offset is: ) offset-high . offset-low . cr
|
||||
true
|
||||
else
|
||||
." Can't open disk label package" cr
|
||||
false
|
||||
then
|
||||
;
|
||||
: init-deblocker ( -- okay? )
|
||||
\ .( init-deblocker: stack is ) .s cr
|
||||
" " " deblocker" $open-package to deblocker-package
|
||||
deblocker-package if
|
||||
true
|
||||
else
|
||||
." Can't open deblocker package" cr false
|
||||
then
|
||||
;
|
||||
|
||||
0 value open-count
|
||||
|
||||
: open ( -- ok? )
|
||||
\ .( open: stack is ) .s cr
|
||||
\ .( O: ) open-count .s cr
|
||||
open-count 0= if
|
||||
init-deblocker 0= if
|
||||
false
|
||||
exit
|
||||
then
|
||||
then
|
||||
map-in-sdcard
|
||||
init-label-package 0= if
|
||||
open-count 0= if
|
||||
deblocker-package close-package
|
||||
then
|
||||
map-out-sdcard
|
||||
false
|
||||
exit
|
||||
then
|
||||
open-count 1+ to open-count
|
||||
true
|
||||
\ .( open: END stack is ) .s cr
|
||||
;
|
||||
: close ( -- )
|
||||
\ .( close: stack is ) .s cr
|
||||
\ .( C: ) .s cr
|
||||
open-count 0 > if
|
||||
label-package close-package 0 to label-package
|
||||
map-out-sdcard
|
||||
open-count 1- to open-count
|
||||
open-count 0= if
|
||||
deblocker-package close-package 0 to deblocker-package
|
||||
then
|
||||
then
|
||||
;
|
||||
|
||||
headers
|
||||
|
||||
\ map-in-sdcard
|
||||
\ -1 instance value dmaaddr
|
||||
\ -1 instance value dmadev
|
||||
\ 4096 dma-alloc to dmaaddr
|
||||
\ dmaaddr 4096 false dma-map-in to dmadev
|
||||
\ h# 80 h# 0 do h# deadbeef dmaaddr i 4 * + l! loop
|
||||
\ dmaaddr dmadev h# 10000 dma-sync
|
||||
\ .( we have as addresses ) dmaaddr . dmadev . cr
|
||||
\ dmadev 0 h# 80 read-blocks
|
||||
\ .( we have read ) . ( blocks ) cr
|
||||
\ dmaaddr dmadev 4090 dma-sync
|
||||
\ h# 80 h# 70 do dmaaddr i 4 * + l@ .( @ ) i 4 * . .( : ) . .( , ) loop
|
||||
\ dmaaddr dmadev 4096 dma-map-out
|
||||
\ dmaaddr 4096 dma-free
|
||||
\ map-out-sdcard
|
||||
|
||||
Reference in New Issue
Block a user