1
0
mirror of synced 2026-03-09 20:01:42 +00:00

various updates, and prom driver for sdcard

This commit is contained in:
Romain Dolbeau
2021-11-17 19:19:32 +01:00
parent a3d210b27f
commit c9fbaf61f8
8 changed files with 720 additions and 72 deletions

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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,

View 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

View 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