mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
Merge pull request #474 from fjullien/term_hist_auto_compl
Terminal: add history and auto completion
This commit is contained in:
commit
705d388745
22 changed files with 1916 additions and 624 deletions
|
@ -49,7 +49,8 @@ class Builder:
|
|||
csr_json = None,
|
||||
csr_csv = None,
|
||||
csr_svd = None,
|
||||
memory_x = None):
|
||||
memory_x = None,
|
||||
bios_options = None):
|
||||
self.soc = soc
|
||||
|
||||
# From Python doc: makedirs() will become confused if the path
|
||||
|
@ -66,6 +67,7 @@ class Builder:
|
|||
self.csr_json = csr_json
|
||||
self.csr_svd = csr_svd
|
||||
self.memory_x = memory_x
|
||||
self.bios_options = bios_options
|
||||
|
||||
self.software_packages = []
|
||||
for name in soc_software_packages:
|
||||
|
@ -110,6 +112,10 @@ class Builder:
|
|||
for name, src_dir in self.software_packages:
|
||||
define(name.upper() + "_DIRECTORY", src_dir)
|
||||
|
||||
if self.bios_options is not None:
|
||||
for option in self.bios_options:
|
||||
define(option, "1")
|
||||
|
||||
write_to_file(
|
||||
os.path.join(self.generated_dir, "variables.mak"),
|
||||
"".join(variables_contents))
|
||||
|
|
|
@ -2,7 +2,7 @@ include ../include/generated/variables.mak
|
|||
include $(SOC_DIRECTORY)/software/common.mak
|
||||
|
||||
ifeq ($(CPU),blackparrot)
|
||||
BP_LIBS = -L$(BP_EXTERNAL_DIR)/lib/gcc/riscv64-unknown-elf/8.3.0
|
||||
BP_LIBS = -L$(BP_EXTERNAL_DIR)/lib/gcc/riscv64-unknown-elf/8.3.0
|
||||
BP_FLAGS = -lgcc
|
||||
endif
|
||||
# Permit TFTP_SERVER_PORT override from shell environment / command line
|
||||
|
@ -10,7 +10,38 @@ ifdef TFTP_SERVER_PORT
|
|||
CFLAGS += -DTFTP_SERVER_PORT=$(TFTP_SERVER_PORT)
|
||||
endif
|
||||
|
||||
OBJECTS=isr.o sdram.o sdcard.o main.o boot-helper.o boot.o
|
||||
OBJECTS = isr.o \
|
||||
sdram.o \
|
||||
sdcard.o \
|
||||
main.o \
|
||||
boot-helper.o \
|
||||
boot.o \
|
||||
helpers.o \
|
||||
cmd_bios.o \
|
||||
cmd_boot.o \
|
||||
cmd_dram.o \
|
||||
cmd_mdio.o \
|
||||
cmd_mem_access.o \
|
||||
cmd_sdcard.o \
|
||||
cmd_spi_flash.o \
|
||||
cmd_usddrphy.o
|
||||
|
||||
ifneq "$(or $(TERM_NO_COMPLETE),$(TERM_MINI))" ""
|
||||
CFLAGS += -DTERM_NO_COMPLETE
|
||||
else
|
||||
OBJECTS += complete.o
|
||||
endif
|
||||
|
||||
ifdef TERM_NO_HIST
|
||||
CFLAGS += -DTERM_NO_HIST
|
||||
endif
|
||||
|
||||
ifdef TERM_MINI
|
||||
CFLAGS += -DTERM_MINI
|
||||
OBJECTS += readline_simple.o
|
||||
else
|
||||
OBJECTS += readline.o
|
||||
endif
|
||||
|
||||
all: bios.bin
|
||||
$(PYTHON) -m litex.soc.software.memusage bios.elf $(CURDIR)/../include/generated/regions.ld $(TRIPLE)
|
||||
|
@ -39,7 +70,7 @@ bios.elf: $(BIOS_DIRECTORY)/linker.ld $(OBJECTS)
|
|||
$(BP_LIBS) \
|
||||
-lnet -lbase-nofloat -lcompiler_rt \
|
||||
$(BP_FLAGS)
|
||||
|
||||
|
||||
ifneq ($(OS),Windows_NT)
|
||||
chmod -x $@
|
||||
endif
|
||||
|
@ -50,6 +81,9 @@ endif
|
|||
%.o: $(BIOS_DIRECTORY)/%.c
|
||||
$(compile)
|
||||
|
||||
%.o: $(BIOS_DIRECTORY)/commands/%.c
|
||||
$(compile)
|
||||
|
||||
%.o: $(BIOS_DIRECTORY)/%.S
|
||||
$(assemble)
|
||||
|
||||
|
|
49
litex/soc/software/bios/command.h
Normal file
49
litex/soc/software/bios/command.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
// This file is Copyright (c) 2020 Franck Jullien <franck.jullien@gmail.com>
|
||||
|
||||
// SPDX-License-Identifier: BSD-Source-Code
|
||||
|
||||
#ifndef __COMMAND_H__
|
||||
#define __COMMAND_H__
|
||||
|
||||
#define MAX_PARAM 8
|
||||
|
||||
#define HIST_DEPTH 10 /* Used in string list, complete.c */
|
||||
|
||||
#define MISC_CMDS 0
|
||||
#define SYSTEM_CMDS 1
|
||||
#define CACHE_CMDS 2
|
||||
#define BOOT_CMDS 3
|
||||
#define DRAM_CMDS 4
|
||||
#define MDIO_CMDS 5
|
||||
#define MEM_CMDS 6
|
||||
#define SD_CMDS 7
|
||||
#define SPIFLASH_CMDS 8
|
||||
#define DDR_CMDS 9
|
||||
#define NB_OF_GROUPS 10
|
||||
|
||||
typedef void (*cmd_handler)(int nb_params, char **params);
|
||||
|
||||
struct command_struct {
|
||||
void (*func)(int nb_params, char **params);
|
||||
const char *name;
|
||||
const char *help;
|
||||
int group;
|
||||
};
|
||||
|
||||
extern struct command_struct *const __bios_cmd_start[];
|
||||
extern struct command_struct *const __bios_cmd_end[];
|
||||
|
||||
#define define_command(cmd_name, handler, help_txt, group_id) \
|
||||
struct command_struct s_##cmd_name = { \
|
||||
.func = (cmd_handler)handler, \
|
||||
.name = #cmd_name, \
|
||||
.help = help_txt, \
|
||||
.group = group_id, \
|
||||
}; \
|
||||
const struct command_struct *__bios_cmd_##cmd_name __attribute__((__used__)) \
|
||||
__attribute__((__section__(".bios_cmd"))) = &s_##cmd_name
|
||||
|
||||
|
||||
struct command_struct *command_dispatcher(char *command, int nb_params, char **params);
|
||||
|
||||
#endif
|
125
litex/soc/software/bios/commands/cmd_bios.c
Normal file
125
litex/soc/software/bios/commands/cmd_bios.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
// SPDX-License-Identifier: BSD-Source-Code
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <id.h>
|
||||
#include <generated/csr.h>
|
||||
#include <crc.h>
|
||||
#include <system.h>
|
||||
|
||||
#include "../command.h"
|
||||
#include "../helpers.h"
|
||||
|
||||
/**
|
||||
* Command "help"
|
||||
*
|
||||
* Print a list of available commands with their help text
|
||||
*
|
||||
*/
|
||||
static void help_handler(int nb_params, char **params)
|
||||
{
|
||||
struct command_struct * const *cmd;
|
||||
int i, not_empty;
|
||||
|
||||
puts("\nLiteX BIOS, available commands:\n");
|
||||
|
||||
for (i = 0; i < NB_OF_GROUPS; i++) {
|
||||
not_empty = 0;
|
||||
for (cmd = __bios_cmd_start; cmd != __bios_cmd_end; cmd++) {
|
||||
if ((*cmd)->group == i) {
|
||||
printf("%-16s - %s\n", (*cmd)->name, (*cmd)->help ? (*cmd)->help : "-");
|
||||
not_empty = 1;
|
||||
}
|
||||
}
|
||||
if (not_empty)
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
define_command(help, help_handler, "Print this help", MISC_CMDS);
|
||||
|
||||
/**
|
||||
* Command "ident"
|
||||
*
|
||||
* Print SoC identyifier if available
|
||||
*
|
||||
*/
|
||||
static void ident_helper(int nb_params, char **params)
|
||||
{
|
||||
char buffer[IDENT_SIZE];
|
||||
|
||||
get_ident(buffer);
|
||||
printf("Ident: %s", *buffer ? buffer : "-");
|
||||
}
|
||||
|
||||
define_command(ident, ident_helper, "Display identifier", SYSTEM_CMDS);
|
||||
|
||||
/**
|
||||
* Command "reboot"
|
||||
*
|
||||
* Reboot the system
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_CTRL_BASE
|
||||
static void reboot(int nb_params, char **params)
|
||||
{
|
||||
ctrl_reset_write(1);
|
||||
}
|
||||
|
||||
define_command(reboot, reboot, "Reset processor", SYSTEM_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "crc"
|
||||
*
|
||||
* Compute CRC32 over an address range
|
||||
*
|
||||
*/
|
||||
static void crc(int nb_params, char **params)
|
||||
{
|
||||
char *c;
|
||||
unsigned int addr;
|
||||
unsigned int length;
|
||||
|
||||
if (nb_params < 2) {
|
||||
printf("crc <address> <length>");
|
||||
return;
|
||||
}
|
||||
|
||||
addr = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect address");
|
||||
return;
|
||||
}
|
||||
|
||||
length = strtoul(params[1], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect length");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("CRC32: %08x", crc32((unsigned char *)addr, length));
|
||||
}
|
||||
|
||||
define_command(crc, crc, "Compute CRC32 of a part of the address space", MISC_CMDS);
|
||||
|
||||
/**
|
||||
* Command "flush_cpu_dcache"
|
||||
*
|
||||
* Flush CPU data cache
|
||||
*
|
||||
*/
|
||||
|
||||
define_command(flush_cpu_dcache, flush_cpu_dcache, "Flush CPU data cache", CACHE_CMDS);
|
||||
|
||||
/**
|
||||
* Command "flush_l2_cache"
|
||||
*
|
||||
* Flush L2 cache
|
||||
*
|
||||
*/
|
||||
#ifdef CONFIG_L2_SIZE
|
||||
define_command(flush_l2_cache, flush_l2_cache, "Flush L2 cache", CACHE_CMDS);
|
||||
#endif
|
||||
|
59
litex/soc/software/bios/commands/cmd_boot.c
Normal file
59
litex/soc/software/bios/commands/cmd_boot.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
// SPDX-License-Identifier: BSD-Source-Code
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <generated/csr.h>
|
||||
|
||||
#include "../command.h"
|
||||
#include "../helpers.h"
|
||||
#include "../boot.h"
|
||||
|
||||
/**
|
||||
* Command "flashboot"
|
||||
*
|
||||
* Boot software from flash
|
||||
*
|
||||
*/
|
||||
#ifdef FLASH_BOOT_ADDRESS
|
||||
define_command(flashboot, flashboot, "Boot from flash", BOOT_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "romboot"
|
||||
*
|
||||
* Boot software from embedded rom
|
||||
*
|
||||
*/
|
||||
#ifdef ROM_BOOT_ADDRESS
|
||||
define_command(romboot, romboot, "Boot from embedded rom", BOOT_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "serialboot"
|
||||
*
|
||||
* Boot software from serial interface
|
||||
*
|
||||
*/
|
||||
define_command(serialboot, serialboot, "Boot via SFL", BOOT_CMDS);
|
||||
|
||||
/**
|
||||
* Command "netboot"
|
||||
*
|
||||
* Boot software from TFTP server
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_ETHMAC_BASE
|
||||
define_command(netboot, netboot, "Boot via TFTP", BOOT_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "spisdcardboot"
|
||||
*
|
||||
* Boot software from SDcard
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_SPISDCARD_BASE
|
||||
define_command(spisdcardboot, spisdcardboot, "Boot from SDCard via SPI hardware bitbang", BOOT_CMDS);
|
||||
#endif
|
||||
|
222
litex/soc/software/bios/commands/cmd_dram.c
Normal file
222
litex/soc/software/bios/commands/cmd_dram.c
Normal file
|
@ -0,0 +1,222 @@
|
|||
// SPDX-License-Identifier: BSD-Source-Code
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <generated/csr.h>
|
||||
|
||||
#include "../command.h"
|
||||
#include "../helpers.h"
|
||||
#include "../sdram.h"
|
||||
|
||||
/**
|
||||
* Command "sdrrow"
|
||||
*
|
||||
* Precharge/Activate row
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_SDRAM_BASE
|
||||
static void sdrrow_handler(int nb_params, char **params)
|
||||
{
|
||||
char *c;
|
||||
unsigned int row;
|
||||
|
||||
if (nb_params < 1) {
|
||||
sdrrow(0);
|
||||
printf("Precharged");
|
||||
}
|
||||
|
||||
row = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect row");
|
||||
return;
|
||||
}
|
||||
|
||||
sdrrow(row);
|
||||
printf("Activated row %d", row);
|
||||
}
|
||||
define_command(sdrrow, sdrrow_handler, "Precharge/Activate row", DRAM_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdrsw"
|
||||
*
|
||||
* Gives SDRAM control to SW
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_SDRAM_BASE
|
||||
define_command(sdrsw, sdrsw, "Gives SDRAM control to SW", DRAM_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdrhw"
|
||||
*
|
||||
* Gives SDRAM control to HW
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_SDRAM_BASE
|
||||
define_command(sdrhw, sdrhw, "Gives SDRAM control to HW", DRAM_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdrrdbuf"
|
||||
*
|
||||
* Dump SDRAM read buffer
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_SDRAM_BASE
|
||||
static void sdrrdbuf_handler(int nb_params, char **params)
|
||||
{
|
||||
sdrrdbuf(-1);
|
||||
}
|
||||
|
||||
define_command(sdrrdbuf, sdrrdbuf_handler, "Dump SDRAM read buffer", DRAM_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdrrd"
|
||||
*
|
||||
* Read SDRAM data
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_SDRAM_BASE
|
||||
static void sdrrd_handler(int nb_params, char **params)
|
||||
{
|
||||
unsigned int addr;
|
||||
int dq;
|
||||
char *c;
|
||||
|
||||
if (nb_params < 1) {
|
||||
printf("sdrrd <address>");
|
||||
return;
|
||||
}
|
||||
|
||||
addr = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect address");
|
||||
return;
|
||||
}
|
||||
|
||||
if (nb_params < 2)
|
||||
dq = -1;
|
||||
else {
|
||||
dq = strtoul(params[1], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect DQ");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sdrrd(addr, dq);
|
||||
}
|
||||
|
||||
define_command(sdrrd, sdrrd_handler, "Read SDRAM data", DRAM_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdrrderr"
|
||||
*
|
||||
* Print SDRAM read errors
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_SDRAM_BASE
|
||||
static void sdrrderr_handler(int nb_params, char **params)
|
||||
{
|
||||
int count;
|
||||
char *c;
|
||||
|
||||
if (nb_params < 1) {
|
||||
printf("sdrrderr <count>");
|
||||
return;
|
||||
}
|
||||
|
||||
count = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect count");
|
||||
return;
|
||||
}
|
||||
|
||||
sdrrderr(count);
|
||||
}
|
||||
|
||||
define_command(sdrrderr, sdrrderr_handler, "Print SDRAM read errors", DRAM_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdrwr"
|
||||
*
|
||||
* Write SDRAM test data
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_SDRAM_BASE
|
||||
static void sdrwr_handler(int nb_params, char **params)
|
||||
{
|
||||
unsigned int addr;
|
||||
char *c;
|
||||
|
||||
if (nb_params < 1) {
|
||||
printf("sdrwr <address>");
|
||||
return;
|
||||
}
|
||||
|
||||
addr = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect address");
|
||||
return;
|
||||
}
|
||||
|
||||
sdrwr(addr);
|
||||
}
|
||||
|
||||
define_command(sdrwr, sdrwr_handler, "Write SDRAM test data", DRAM_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdrinit"
|
||||
*
|
||||
* Start SDRAM initialisation
|
||||
*
|
||||
*/
|
||||
#if defined(CSR_SDRAM_BASE) && defined(CSR_DDRPHY_BASE)
|
||||
define_command(sdrinit, sdrinit, "Start SDRAM initialisation", DRAM_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdrwlon"
|
||||
*
|
||||
* Write leveling ON
|
||||
*
|
||||
*/
|
||||
#if defined(CSR_DDRPHY_BASE) && defined(SDRAM_PHY_WRITE_LEVELING_CAPABLE) && defined(CSR_SDRAM_BASE)
|
||||
define_command(sdrwlon, sdrwlon, "Enable write leveling", DRAM_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdrwloff"
|
||||
*
|
||||
* Write leveling OFF
|
||||
*
|
||||
*/
|
||||
#if defined(CSR_DDRPHY_BASE) && defined(SDRAM_PHY_WRITE_LEVELING_CAPABLE) && defined(CSR_SDRAM_BASE)
|
||||
define_command(sdrwloff, sdrwloff, "Disable write leveling", DRAM_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdrlevel"
|
||||
*
|
||||
* Perform read/write leveling
|
||||
*
|
||||
*/
|
||||
#if defined(CSR_DDRPHY_BASE) && defined(CSR_SDRAM_BASE)
|
||||
define_command(sdrlevel, sdrlevel, "Perform read/write leveling", DRAM_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "memtest"
|
||||
*
|
||||
* Run a memory test
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_SDRAM_BASE
|
||||
define_command(memtest, memtest, "Run a memory test", DRAM_CMDS);
|
||||
#endif
|
132
litex/soc/software/bios/commands/cmd_mdio.c
Normal file
132
litex/soc/software/bios/commands/cmd_mdio.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
// SPDX-License-Identifier: BSD-Source-Code
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <generated/csr.h>
|
||||
|
||||
#include "../command.h"
|
||||
#include "../helpers.h"
|
||||
|
||||
/**
|
||||
* Command "mdiow"
|
||||
*
|
||||
* Write MDIO register
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_ETHPHY_MDIO_W_ADDR
|
||||
static void mdiow(int nb_params, char **params)
|
||||
{
|
||||
char *c;
|
||||
unsigned int phyadr2;
|
||||
unsigned int reg2;
|
||||
unsigned int val2;
|
||||
|
||||
if (nb_params < 3) {
|
||||
printf("mdiow <phyadr> <reg> <value>");
|
||||
return;
|
||||
}
|
||||
|
||||
phyadr2 = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect phyadr");
|
||||
return;
|
||||
}
|
||||
|
||||
reg2 = strtoul(params[1], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect reg");
|
||||
return;
|
||||
}
|
||||
|
||||
val2 = strtoul(params[2], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect val");
|
||||
return;
|
||||
}
|
||||
|
||||
mdio_write(phyadr2, reg2, val2);
|
||||
}
|
||||
|
||||
define_command(mdiow, mdiow, "Write MDIO register", MDIO_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "mdior"
|
||||
*
|
||||
* Read MDIO register
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_ETHPHY_MDIO_W_ADDR
|
||||
static void mdior(int nb_params, char **params)
|
||||
{
|
||||
char *c;
|
||||
unsigned int phyadr2;
|
||||
unsigned int reg2;
|
||||
unsigned int val;
|
||||
|
||||
if (nb_params < 2) {
|
||||
printf("mdior <phyadr> <reg>");
|
||||
return;
|
||||
}
|
||||
|
||||
phyadr2 = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect phyadr");
|
||||
return;
|
||||
}
|
||||
|
||||
reg2 = strtoul(params[1], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect reg");
|
||||
return;
|
||||
}
|
||||
|
||||
val = mdio_read(phyadr2, reg2);
|
||||
printf("Reg %d: 0x%04x", reg2, val);
|
||||
}
|
||||
|
||||
define_command(mdior, mdior, "Read MDIO register", MDIO_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "mdiod"
|
||||
*
|
||||
* Dump MDIO registers
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_ETHPHY_MDIO_W_ADDR
|
||||
static void mdiod(int nb_params, char **params)
|
||||
{
|
||||
char *c;
|
||||
unsigned int phyadr;
|
||||
unsigned int count;
|
||||
unsigned int val;
|
||||
int i;
|
||||
|
||||
if (nb_params < 2) {
|
||||
printf("mdiod <phyadr> <count>");
|
||||
return;
|
||||
}
|
||||
|
||||
phyadr = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect phyadr");
|
||||
return;
|
||||
}
|
||||
|
||||
count = strtoul(params[1], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect count");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("MDIO dump @0x%x:\n", phyadr);
|
||||
for (i = 0; i < count; i++) {
|
||||
val = mdio_read(phyadr, i);
|
||||
printf("reg %d: 0x%04x", i, val);
|
||||
}
|
||||
}
|
||||
|
||||
define_command(mdiod, mdiod, "Dump MDIO registers", MDIO_CMDS);
|
||||
#endif
|
137
litex/soc/software/bios/commands/cmd_mem_access.c
Normal file
137
litex/soc/software/bios/commands/cmd_mem_access.c
Normal file
|
@ -0,0 +1,137 @@
|
|||
// SPDX-License-Identifier: BSD-Source-Code
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../command.h"
|
||||
#include "../helpers.h"
|
||||
|
||||
/**
|
||||
* Command "mr"
|
||||
*
|
||||
* Memory read
|
||||
*
|
||||
*/
|
||||
static void mr(int nb_params, char **params)
|
||||
{
|
||||
char *c;
|
||||
unsigned int *addr;
|
||||
unsigned int length;
|
||||
|
||||
if (nb_params < 1) {
|
||||
printf("mr <address> [length]");
|
||||
return;
|
||||
}
|
||||
addr = (unsigned int *)strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect address");
|
||||
return;
|
||||
}
|
||||
if (nb_params == 1) {
|
||||
length = 4;
|
||||
} else {
|
||||
length = strtoul(params[1], &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("\nIncorrect length");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dump_bytes(addr, length, (unsigned long)addr);
|
||||
}
|
||||
|
||||
define_command(mr, mr, "Read address space", MEM_CMDS);
|
||||
|
||||
/**
|
||||
* Command "mw"
|
||||
*
|
||||
* Memory write
|
||||
*
|
||||
*/
|
||||
static void mw(int nb_params, char **params)
|
||||
{
|
||||
char *c;
|
||||
unsigned int *addr;
|
||||
unsigned int value;
|
||||
unsigned int count;
|
||||
unsigned int i;
|
||||
|
||||
if (nb_params < 2) {
|
||||
printf("mw <address> <value> [count]");
|
||||
return;
|
||||
}
|
||||
|
||||
addr = (unsigned int *)strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect address");
|
||||
return;
|
||||
}
|
||||
|
||||
value = strtoul(params[1], &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("Incorrect value");
|
||||
return;
|
||||
}
|
||||
|
||||
if (nb_params == 2) {
|
||||
count = 1;
|
||||
} else {
|
||||
count = strtoul(params[2], &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("Incorrect count");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
*addr++ = value;
|
||||
}
|
||||
|
||||
define_command(mw, mw, "Write address space", MEM_CMDS);
|
||||
|
||||
/**
|
||||
* Command "mc"
|
||||
*
|
||||
* Memory copy
|
||||
*
|
||||
*/
|
||||
static void mc(int nb_params, char **params)
|
||||
{
|
||||
char *c;
|
||||
unsigned int *dstaddr;
|
||||
unsigned int *srcaddr;
|
||||
unsigned int count;
|
||||
unsigned int i;
|
||||
|
||||
if (nb_params < 2) {
|
||||
printf("mc <dst> <src> [count]");
|
||||
return;
|
||||
}
|
||||
|
||||
dstaddr = (unsigned int *)strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect destination address");
|
||||
return;
|
||||
}
|
||||
|
||||
srcaddr = (unsigned int *)strtoul(params[1], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect source address");
|
||||
return;
|
||||
}
|
||||
|
||||
if (nb_params == 2) {
|
||||
count = 1;
|
||||
} else {
|
||||
count = strtoul(params[2], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect count");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
*dstaddr++ = *srcaddr++;
|
||||
}
|
||||
|
||||
define_command(mc, mc, "Copy address space", MEM_CMDS);
|
85
litex/soc/software/bios/commands/cmd_sdcard.c
Normal file
85
litex/soc/software/bios/commands/cmd_sdcard.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
// SPDX-License-Identifier: BSD-Source-Code
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <generated/csr.h>
|
||||
|
||||
#include "../command.h"
|
||||
#include "../helpers.h"
|
||||
#include "../sdcard.h"
|
||||
|
||||
/**
|
||||
* Command "sdclk"
|
||||
*
|
||||
* Configure SDcard clock frequency
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_SDCORE_BASE
|
||||
static void sdclk(int nb_params, char **params)
|
||||
{
|
||||
unsigned int frequ;
|
||||
char *c;
|
||||
|
||||
if (nb_params < 1) {
|
||||
printf("sdclk <frequ>");
|
||||
return;
|
||||
}
|
||||
|
||||
frequ = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect frequency");
|
||||
return;
|
||||
}
|
||||
|
||||
sdclk_set_clk(frequ);
|
||||
}
|
||||
|
||||
struct command_struct cmd_sdclk =
|
||||
{
|
||||
.func = sdclk,
|
||||
.name = "sdclk",
|
||||
.help = "SDCard set clk frequency (Mhz)",
|
||||
};
|
||||
|
||||
define_command(sdclk, sdclk, "SDCard set clk frequency (Mhz)", SD_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdinit"
|
||||
*
|
||||
* Initialize SDcard
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_SDCORE_BASE
|
||||
define_command(sdinit, sdinit, "SDCard initialization", SD_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdtest"
|
||||
*
|
||||
* Perform SDcard access tests
|
||||
*
|
||||
*/
|
||||
#ifdef CSR_SDCORE_BASE
|
||||
static void sdtest(int nb_params, char **params)
|
||||
{
|
||||
unsigned int loops;
|
||||
char *c;
|
||||
|
||||
if (nb_params < 1) {
|
||||
printf("sdtest <loops>");
|
||||
return;
|
||||
}
|
||||
|
||||
loops = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect number of loops");
|
||||
return;
|
||||
}
|
||||
|
||||
sdcard_test(loops);
|
||||
}
|
||||
|
||||
define_command(sdtest, sdtest, "SDCard test", SD_CMDS);
|
||||
#endif
|
75
litex/soc/software/bios/commands/cmd_spi_flash.c
Normal file
75
litex/soc/software/bios/commands/cmd_spi_flash.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
// SPDX-License-Identifier: BSD-Source-Code
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <generated/csr.h>
|
||||
|
||||
#include "../command.h"
|
||||
#include "../helpers.h"
|
||||
|
||||
/**
|
||||
* Command "fw"
|
||||
*
|
||||
* Write data from a memory buffer to SPI flash
|
||||
*
|
||||
*/
|
||||
#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
|
||||
static void fw(int nb_params, char **params)
|
||||
{
|
||||
char *c;
|
||||
unsigned int addr;
|
||||
unsigned int value;
|
||||
unsigned int count;
|
||||
unsigned int i;
|
||||
|
||||
if (nb_params < 2) {
|
||||
printf("fw <offset> <value> [count]");
|
||||
return;
|
||||
}
|
||||
|
||||
addr = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect offset");
|
||||
return;
|
||||
}
|
||||
|
||||
value = strtoul(params[1], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect value");
|
||||
return;
|
||||
}
|
||||
|
||||
if (nb_params == 2) {
|
||||
count = 1;
|
||||
} else {
|
||||
count = strtoul(count, &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect count");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
write_to_flash(addr + i * 4, (unsigned char *)&value, 4);
|
||||
}
|
||||
|
||||
define_command(fw, fw, "Write to flash", SPIFLASH_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "fe"
|
||||
*
|
||||
* Flash erase
|
||||
*
|
||||
*/
|
||||
#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
|
||||
static void fe(int nb_params, char **params)
|
||||
{
|
||||
erase_flash();
|
||||
printf("Flash erased\n");
|
||||
}
|
||||
|
||||
define_command(fe, fe, "Erase whole flash", SPIFLASH_CMDS);
|
||||
#endif
|
||||
|
128
litex/soc/software/bios/commands/cmd_usddrphy.c
Normal file
128
litex/soc/software/bios/commands/cmd_usddrphy.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
// SPDX-License-Identifier: BSD-Source-Code
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <generated/csr.h>
|
||||
|
||||
#include "../command.h"
|
||||
#include "../helpers.h"
|
||||
#include "../sdram.h"
|
||||
|
||||
/**
|
||||
* Command "sdram_cdly"
|
||||
*
|
||||
* Set SDRAM clk/cmd delay
|
||||
*
|
||||
*/
|
||||
#ifdef USDDRPHY_DEBUG
|
||||
static void sdram_cdly(int nb_params, char **params)
|
||||
{
|
||||
unsigned int delay;
|
||||
char *c;
|
||||
|
||||
if (nb_params < 1) {
|
||||
printf("sdram_cdly <delay>");
|
||||
return;
|
||||
}
|
||||
|
||||
delay = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect delay");
|
||||
return;
|
||||
}
|
||||
|
||||
ddrphy_cdly(delay);
|
||||
}
|
||||
|
||||
define_command(sdram_cdly, sdram_cdly, "Set SDRAM clk/cmd delay", DDR_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdram_cdly"
|
||||
*
|
||||
* Run SDRAM calibration
|
||||
*
|
||||
*/
|
||||
#ifdef USDDRPHY_DEBUG
|
||||
define_command(sdram_cal, sdram_cal, "Run SDRAM calibration", DDR_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdram_mpr"
|
||||
*
|
||||
* Read SDRAM MPR
|
||||
*
|
||||
*/
|
||||
#ifdef USDDRPHY_DEBUG
|
||||
define_command(sdram_mpr, sdram_mpr, "Read SDRAM MPR", DDR_CMDS);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Command "sdram_mrwr"
|
||||
*
|
||||
* Write SDRAM mode registers
|
||||
*
|
||||
*/
|
||||
#ifdef USDDRPHY_DEBUG
|
||||
static void sdram_mrwr(int nb_params, char **params)
|
||||
{
|
||||
unsigned int reg;
|
||||
unsigned int value;
|
||||
char *c;
|
||||
|
||||
if (nb_params < 2) {
|
||||
printf("sdram_mrwr <reg> <value>");
|
||||
return;
|
||||
}
|
||||
|
||||
reg = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect register value");
|
||||
return;
|
||||
}
|
||||
|
||||
value = strtoul(params[1], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect value");
|
||||
return;
|
||||
}
|
||||
|
||||
sdrsw();
|
||||
printf("Writing 0x%04x to SDRAM mode register %d\n", value, reg);
|
||||
sdrmrwr(reg, value);
|
||||
sdrhw();
|
||||
}
|
||||
|
||||
define_command(sdram_mrwr, sdram_mrwr, "Write SDRAM mode registers", DDR_CMDS);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Command "sdram_cdly_scan"
|
||||
*
|
||||
* Enable/disable cdly scan
|
||||
*
|
||||
*/
|
||||
#ifdef USDDRPHY_DEBUG
|
||||
static void sdram_cdly_scan(int nb_params, char **params)
|
||||
{
|
||||
unsigned int value;
|
||||
char *c;
|
||||
|
||||
if (nb_params < 1) {
|
||||
printf("sdram_cdly_scan <value>");
|
||||
return;
|
||||
}
|
||||
|
||||
value = strtoul(params[0], &c, 0);
|
||||
if (*c != 0) {
|
||||
printf("Incorrect value");
|
||||
return;
|
||||
}
|
||||
|
||||
sdr_cdly_scan(value);
|
||||
}
|
||||
|
||||
define_command(sdram_cdly_scan, sdram_cdly_scan, "Enable/disable cdly scan", DDR_CMDS);
|
||||
#endif
|
174
litex/soc/software/bios/complete.c
Normal file
174
litex/soc/software/bios/complete.c
Normal file
|
@ -0,0 +1,174 @@
|
|||
// This file is Copyright (c) 2020 Franck Jullien <franck.jullien@gmail.com>
|
||||
//
|
||||
// Largely inspired/copied from U-boot and Barebox projects wich are:
|
||||
// Sascha Hauer, Pengutronix, <s.hauer@pengutronix.de>
|
||||
|
||||
// License: BSD
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "readline.h"
|
||||
#include "helpers.h"
|
||||
#include "command.h"
|
||||
#include "complete.h"
|
||||
|
||||
static int tab_pressed = 0;
|
||||
|
||||
char sl[HIST_DEPTH][CMD_LINE_BUFFER_SIZE];
|
||||
int sl_idx = 0;
|
||||
|
||||
char out[CMD_LINE_BUFFER_SIZE];
|
||||
|
||||
static void string_list_init(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < HIST_DEPTH; i++)
|
||||
sl[i][0] = 0;
|
||||
}
|
||||
|
||||
static int string_list_add(const char *string)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < HIST_DEPTH; i++) {
|
||||
if (sl[i][0] == 0) {
|
||||
strncpy(&sl[i][0], string, CMD_LINE_BUFFER_SIZE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int string_list_empty(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < HIST_DEPTH; i++)
|
||||
if (sl[i][0] != 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int string_list_count(void)
|
||||
{
|
||||
int i, count = 0;
|
||||
for (i = 0; i < HIST_DEPTH; i++)
|
||||
if (sl[i][0] != 0)
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
static char *list_first_entry(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < HIST_DEPTH; i++)
|
||||
if (sl[i][0] != 0)
|
||||
return &sl[i][0];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void string_list_print_by_column(void)
|
||||
{
|
||||
int len = 0, num, i, j;
|
||||
|
||||
for (i = 0; i < HIST_DEPTH; i++) {
|
||||
if (sl[i][0] != 0) {
|
||||
int l = strlen(&sl[i][0]) + 4;
|
||||
if (l > len)
|
||||
len = l;
|
||||
}
|
||||
}
|
||||
|
||||
if (!len)
|
||||
return;
|
||||
|
||||
num = 80 / (len + 1);
|
||||
|
||||
for (j = 0; j < HIST_DEPTH; j++) {
|
||||
if (sl[j][0] != 0) {
|
||||
if (!(++i % num))
|
||||
printf("%s\n", &sl[j][0]);
|
||||
else
|
||||
printf("%-*s", len, &sl[j][0]);
|
||||
}
|
||||
}
|
||||
if (i % num)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void command_complete(char *instr)
|
||||
{
|
||||
struct command_struct * const *cmd;
|
||||
|
||||
for (cmd = __bios_cmd_start; cmd != __bios_cmd_end; cmd++)
|
||||
if (!strncmp(instr, (*cmd)->name, strlen(instr)))
|
||||
string_list_add((*cmd)->name);
|
||||
}
|
||||
|
||||
int complete(char *instr, char **outstr)
|
||||
{
|
||||
int pos;
|
||||
char ch;
|
||||
int changed;
|
||||
int outpos = 0;
|
||||
int reprint = 0;
|
||||
char *first_entry;
|
||||
char *entry;
|
||||
int i;
|
||||
|
||||
string_list_init();
|
||||
command_complete(instr);
|
||||
|
||||
pos = strlen(instr);
|
||||
|
||||
*outstr = "";
|
||||
if (string_list_empty())
|
||||
reprint = 0;
|
||||
else
|
||||
{
|
||||
out[0] = 0;
|
||||
|
||||
first_entry = list_first_entry();
|
||||
|
||||
while (1) {
|
||||
entry = first_entry;
|
||||
ch = entry[pos];
|
||||
if (!ch)
|
||||
break;
|
||||
|
||||
changed = 0;
|
||||
for (i = 0; i < HIST_DEPTH; i++) {
|
||||
if (sl[i][0] != 0) {
|
||||
if (!sl[i][pos])
|
||||
break;
|
||||
if (ch != sl[i][pos]) {
|
||||
changed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
break;
|
||||
out[outpos++] = ch;
|
||||
pos++;
|
||||
}
|
||||
|
||||
if ((string_list_count() != 1) && !outpos && tab_pressed) {
|
||||
printf("\n");
|
||||
string_list_print_by_column();
|
||||
reprint = 1;
|
||||
tab_pressed = 0;
|
||||
}
|
||||
|
||||
out[outpos++] = 0;
|
||||
*outstr = out;
|
||||
|
||||
if (*out == 0)
|
||||
tab_pressed = 1;
|
||||
else
|
||||
tab_pressed = 0;
|
||||
}
|
||||
|
||||
return reprint;
|
||||
}
|
6
litex/soc/software/bios/complete.h
Normal file
6
litex/soc/software/bios/complete.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef __COMPLETE_H__
|
||||
#define __COMPLETE_H__
|
||||
|
||||
int complete(char *instr, char **outstr);
|
||||
|
||||
#endif
|
128
litex/soc/software/bios/helpers.c
Normal file
128
litex/soc/software/bios/helpers.c
Normal file
|
@ -0,0 +1,128 @@
|
|||
// This file is Copyright (c) 2017 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
|
||||
// SPDX-License-Identifier: BSD-Source-Code
|
||||
|
||||
#include <stdio.h>
|
||||
#include <console.h>
|
||||
#include <crc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "readline.h"
|
||||
#include "helpers.h"
|
||||
#include "command.h"
|
||||
|
||||
extern unsigned int _ftext, _edata;
|
||||
|
||||
#define NUMBER_OF_BYTES_ON_A_LINE 16
|
||||
void dump_bytes(unsigned int *ptr, int count, unsigned long addr)
|
||||
{
|
||||
char *data = (char *)ptr;
|
||||
int line_bytes = 0, i = 0;
|
||||
|
||||
putsnonl("Memory dump:");
|
||||
while (count > 0) {
|
||||
line_bytes =
|
||||
(count > NUMBER_OF_BYTES_ON_A_LINE)?
|
||||
NUMBER_OF_BYTES_ON_A_LINE : count;
|
||||
|
||||
printf("\n0x%08x ", addr);
|
||||
for (i = 0; i < line_bytes; i++)
|
||||
printf("%02x ", *(unsigned char *)(data+i));
|
||||
|
||||
for (; i < NUMBER_OF_BYTES_ON_A_LINE; i++)
|
||||
printf(" ");
|
||||
|
||||
printf(" ");
|
||||
|
||||
for (i = 0; i<line_bytes; i++) {
|
||||
if ((*(data+i) < 0x20) || (*(data+i) > 0x7e))
|
||||
printf(".");
|
||||
else
|
||||
printf("%c", *(data+i));
|
||||
}
|
||||
|
||||
for (; i < NUMBER_OF_BYTES_ON_A_LINE; i++)
|
||||
printf(" ");
|
||||
|
||||
data += (char)line_bytes;
|
||||
count -= line_bytes;
|
||||
addr += line_bytes;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void crcbios(void)
|
||||
{
|
||||
unsigned long offset_bios;
|
||||
unsigned long length;
|
||||
unsigned int expected_crc;
|
||||
unsigned int actual_crc;
|
||||
|
||||
/*
|
||||
* _edata is located right after the end of the flat
|
||||
* binary image. The CRC tool writes the 32-bit CRC here.
|
||||
* We also use the address of _edata to know the length
|
||||
* of our code.
|
||||
*/
|
||||
offset_bios = (unsigned long)&_ftext;
|
||||
expected_crc = _edata;
|
||||
length = (unsigned long)&_edata - offset_bios;
|
||||
actual_crc = crc32((unsigned char *)offset_bios, length);
|
||||
if (expected_crc == actual_crc)
|
||||
printf(" BIOS CRC passed (%08x)\n", actual_crc);
|
||||
else {
|
||||
printf(" BIOS CRC failed (expected %08x, got %08x)\n", expected_crc, actual_crc);
|
||||
printf(" The system will continue, but expect problems.\n");
|
||||
}
|
||||
}
|
||||
|
||||
int get_param(char *buf, char **cmd, char **params)
|
||||
{
|
||||
int nb_param = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_PARAM; i++)
|
||||
params[i] = NULL;
|
||||
|
||||
*cmd = buf;
|
||||
|
||||
while ((*buf != ' ') && (*buf !=0))
|
||||
buf++;
|
||||
|
||||
if (*buf == 0)
|
||||
return nb_param;
|
||||
|
||||
*buf++ = 0;
|
||||
|
||||
while (1) {
|
||||
while ((*buf == ' ') && (*buf !=0))
|
||||
buf++;
|
||||
|
||||
|
||||
if (*buf == 0)
|
||||
return nb_param;
|
||||
|
||||
params[nb_param++] = buf;
|
||||
|
||||
while ((*buf != ' ') && (*buf !=0))
|
||||
buf++;
|
||||
|
||||
if (*buf == 0)
|
||||
return nb_param;
|
||||
*buf++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct command_struct *command_dispatcher(char *command, int nb_params, char **params)
|
||||
{
|
||||
struct command_struct * const *cmd;
|
||||
|
||||
for (cmd = __bios_cmd_start; cmd != __bios_cmd_end; cmd++) {
|
||||
if (!strcmp(command, (*cmd)->name)) {
|
||||
(*cmd)->func(nb_params, params);
|
||||
return (*cmd);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
9
litex/soc/software/bios/helpers.h
Normal file
9
litex/soc/software/bios/helpers.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef __HELPERS_H__
|
||||
#define __HELPERS_H__
|
||||
|
||||
void dump_bytes(unsigned int *ptr, int count, unsigned long addr);
|
||||
void crcbios(void);
|
||||
int get_param(char *buf, char **cmd, char **params);
|
||||
struct command_struct *command_dispatcher(char *command, int nb_params, char **params);
|
||||
|
||||
#endif
|
|
@ -26,6 +26,13 @@ SECTIONS
|
|||
_erodata = .;
|
||||
} > rom
|
||||
|
||||
.commands :
|
||||
{
|
||||
PROVIDE_HIDDEN (__bios_cmd_start = .);
|
||||
KEEP(*(.bios_cmd))
|
||||
PROVIDE_HIDDEN (__bios_cmd_end = .);
|
||||
} > rom
|
||||
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
// This file is Copyright (c) 2018 Jean-François Nguyen <jf@lambdaconcept.fr>
|
||||
// This file is Copyright (c) 2018 Sergiusz Bazanski <q3k@q3k.org>
|
||||
// This file is Copyright (c) 2016 Tim 'mithro' Ansell <mithro@mithis.com>
|
||||
// This file is Copyright (c) 2020 Franck Jullien <franck.jullien@gmail.com>
|
||||
|
||||
// License: BSD
|
||||
|
||||
|
@ -42,553 +43,9 @@
|
|||
#include "sdram.h"
|
||||
#include "sdcard.h"
|
||||
#include "boot.h"
|
||||
|
||||
/* General address space functions */
|
||||
|
||||
#define NUMBER_OF_BYTES_ON_A_LINE 16
|
||||
static void dump_bytes(unsigned int *ptr, int count, unsigned long addr)
|
||||
{
|
||||
char *data = (char *)ptr;
|
||||
int line_bytes = 0, i = 0;
|
||||
|
||||
putsnonl("Memory dump:");
|
||||
while(count > 0){
|
||||
line_bytes =
|
||||
(count > NUMBER_OF_BYTES_ON_A_LINE)?
|
||||
NUMBER_OF_BYTES_ON_A_LINE : count;
|
||||
|
||||
printf("\n0x%08x ", addr);
|
||||
for(i=0;i<line_bytes;i++)
|
||||
printf("%02x ", *(unsigned char *)(data+i));
|
||||
|
||||
for(;i<NUMBER_OF_BYTES_ON_A_LINE;i++)
|
||||
printf(" ");
|
||||
|
||||
printf(" ");
|
||||
|
||||
for(i=0;i<line_bytes;i++) {
|
||||
if((*(data+i) < 0x20) || (*(data+i) > 0x7e))
|
||||
printf(".");
|
||||
else
|
||||
printf("%c", *(data+i));
|
||||
}
|
||||
|
||||
for(;i<NUMBER_OF_BYTES_ON_A_LINE;i++)
|
||||
printf(" ");
|
||||
|
||||
data += (char)line_bytes;
|
||||
count -= line_bytes;
|
||||
addr += line_bytes;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void mr(char *startaddr, char *len)
|
||||
{
|
||||
char *c;
|
||||
unsigned int *addr;
|
||||
unsigned int length;
|
||||
|
||||
if(*startaddr == 0) {
|
||||
printf("mr <address> [length]\n");
|
||||
return;
|
||||
}
|
||||
addr = (unsigned *)strtoul(startaddr, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect address\n");
|
||||
return;
|
||||
}
|
||||
if(*len == 0) {
|
||||
length = 4;
|
||||
} else {
|
||||
length = strtoul(len, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect length\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dump_bytes(addr, length, (unsigned long)addr);
|
||||
}
|
||||
|
||||
static void mw(char *addr, char *value, char *count)
|
||||
{
|
||||
char *c;
|
||||
unsigned int *addr2;
|
||||
unsigned int value2;
|
||||
unsigned int count2;
|
||||
unsigned int i;
|
||||
|
||||
if((*addr == 0) || (*value == 0)) {
|
||||
printf("mw <address> <value> [count]\n");
|
||||
return;
|
||||
}
|
||||
addr2 = (unsigned int *)strtoul(addr, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect address\n");
|
||||
return;
|
||||
}
|
||||
value2 = strtoul(value, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect value\n");
|
||||
return;
|
||||
}
|
||||
if(*count == 0) {
|
||||
count2 = 1;
|
||||
} else {
|
||||
count2 = strtoul(count, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect count\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (i=0;i<count2;i++) *addr2++ = value2;
|
||||
}
|
||||
|
||||
static void mc(char *dstaddr, char *srcaddr, char *count)
|
||||
{
|
||||
char *c;
|
||||
unsigned int *dstaddr2;
|
||||
unsigned int *srcaddr2;
|
||||
unsigned int count2;
|
||||
unsigned int i;
|
||||
|
||||
if((*dstaddr == 0) || (*srcaddr == 0)) {
|
||||
printf("mc <dst> <src> [count]\n");
|
||||
return;
|
||||
}
|
||||
dstaddr2 = (unsigned int *)strtoul(dstaddr, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect destination address\n");
|
||||
return;
|
||||
}
|
||||
srcaddr2 = (unsigned int *)strtoul(srcaddr, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect source address\n");
|
||||
return;
|
||||
}
|
||||
if(*count == 0) {
|
||||
count2 = 1;
|
||||
} else {
|
||||
count2 = strtoul(count, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect count\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (i=0;i<count2;i++) *dstaddr2++ = *srcaddr2++;
|
||||
}
|
||||
|
||||
#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
|
||||
static void fw(char *addr, char *value, char *count)
|
||||
{
|
||||
char *c;
|
||||
unsigned int addr2;
|
||||
unsigned int value2;
|
||||
unsigned int count2;
|
||||
unsigned int i;
|
||||
|
||||
if((*addr == 0) || (*value == 0)) {
|
||||
printf("fw <offset> <value> [count]\n");
|
||||
return;
|
||||
}
|
||||
addr2 = strtoul(addr, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect offset\n");
|
||||
return;
|
||||
}
|
||||
value2 = strtoul(value, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect value\n");
|
||||
return;
|
||||
}
|
||||
if(*count == 0) {
|
||||
count2 = 1;
|
||||
} else {
|
||||
count2 = strtoul(count, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect count\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (i=0;i<count2;i++) write_to_flash(addr2 + i * 4, (unsigned char *)&value2, 4);
|
||||
}
|
||||
|
||||
static void fe(void)
|
||||
{
|
||||
erase_flash();
|
||||
printf("flash erased\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CSR_ETHPHY_MDIO_W_ADDR
|
||||
static void mdiow(char *phyadr, char *reg, char *val)
|
||||
{
|
||||
char *c;
|
||||
unsigned int phyadr2;
|
||||
unsigned int reg2;
|
||||
unsigned int val2;
|
||||
|
||||
if((*phyadr == 0) || (*reg == 0) || (*val == 0)) {
|
||||
printf("mdiow <phyadr> <reg> <value>\n");
|
||||
return;
|
||||
}
|
||||
phyadr2 = strtoul(phyadr, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect phyadr\n");
|
||||
return;
|
||||
}
|
||||
reg2 = strtoul(reg, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect reg\n");
|
||||
return;
|
||||
}
|
||||
val2 = strtoul(val, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect val\n");
|
||||
return;
|
||||
}
|
||||
mdio_write(phyadr2, reg2, val2);
|
||||
}
|
||||
|
||||
static void mdior(char *phyadr, char *reg)
|
||||
{
|
||||
char *c;
|
||||
unsigned int phyadr2;
|
||||
unsigned int reg2;
|
||||
unsigned int val;
|
||||
|
||||
if((*phyadr == 0) || (*reg == 0)) {
|
||||
printf("mdior <phyadr> <reg>\n");
|
||||
return;
|
||||
}
|
||||
phyadr2 = strtoul(phyadr, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect phyadr\n");
|
||||
return;
|
||||
}
|
||||
reg2 = strtoul(reg, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect reg\n");
|
||||
return;
|
||||
}
|
||||
val = mdio_read(phyadr2, reg2);
|
||||
printf("reg %d: 0x%04x\n", reg2, val);
|
||||
}
|
||||
|
||||
static void mdiod(char *phyadr, char *count)
|
||||
{
|
||||
char *c;
|
||||
unsigned int phyadr2;
|
||||
unsigned int count2;
|
||||
unsigned int val;
|
||||
int i;
|
||||
|
||||
if((*phyadr == 0) || (*count == 0)) {
|
||||
printf("mdiod <phyadr> <count>\n");
|
||||
return;
|
||||
}
|
||||
phyadr2 = strtoul(phyadr, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect phyadr\n");
|
||||
return;
|
||||
}
|
||||
count2 = strtoul(count, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect count\n");
|
||||
return;
|
||||
}
|
||||
printf("MDIO dump @0x%x:\n", phyadr2);
|
||||
for (i=0; i<count2; i++) {
|
||||
val = mdio_read(phyadr2, i);
|
||||
printf("reg %d: 0x%04x\n", i, val);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void crc(char *startaddr, char *len)
|
||||
{
|
||||
char *c;
|
||||
char *addr;
|
||||
unsigned int length;
|
||||
|
||||
if((*startaddr == 0)||(*len == 0)) {
|
||||
printf("crc <address> <length>\n");
|
||||
return;
|
||||
}
|
||||
addr = (char *)strtoul(startaddr, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect address\n");
|
||||
return;
|
||||
}
|
||||
length = strtoul(len, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect length\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("CRC32: %08x\n", crc32((unsigned char *)addr, length));
|
||||
}
|
||||
|
||||
static void ident(void)
|
||||
{
|
||||
char buffer[IDENT_SIZE];
|
||||
|
||||
get_ident(buffer);
|
||||
printf("Ident: %s\n", buffer);
|
||||
}
|
||||
|
||||
/* Init + command line */
|
||||
|
||||
static void help(void)
|
||||
{
|
||||
puts("LiteX BIOS, available commands:");
|
||||
puts("mr - read address space");
|
||||
puts("mw - write address space");
|
||||
puts("mc - copy address space");
|
||||
#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
|
||||
puts("fe - erase whole flash");
|
||||
puts("fw - write to flash");
|
||||
|
||||
#endif
|
||||
#ifdef CSR_ETHPHY_MDIO_W_ADDR
|
||||
puts("mdiow - write MDIO register");
|
||||
puts("mdior - read MDIO register");
|
||||
puts("mdiod - dump MDIO registers");
|
||||
#endif
|
||||
puts("");
|
||||
puts("crc - compute CRC32 of a part of the address space");
|
||||
puts("ident - display identifier");
|
||||
puts("");
|
||||
puts("flush_cpu_dcache - flush CPU data cache");
|
||||
#ifdef CONFIG_L2_SIZE
|
||||
puts("flush_l2_cache - flush L2 cache");
|
||||
#endif
|
||||
puts("");
|
||||
#ifdef CSR_CTRL_BASE
|
||||
puts("reboot - reset processor");
|
||||
#endif
|
||||
#ifdef CSR_ETHMAC_BASE
|
||||
puts("netboot - boot via TFTP");
|
||||
#endif
|
||||
puts("serialboot - boot via SFL");
|
||||
#ifdef FLASH_BOOT_ADDRESS
|
||||
puts("flashboot - boot from flash");
|
||||
#endif
|
||||
#ifdef ROM_BOOT_ADDRESS
|
||||
puts("romboot - boot from embedded rom");
|
||||
#endif
|
||||
puts("");
|
||||
#ifdef CSR_SDRAM_BASE
|
||||
puts("memtest - run a memory test");
|
||||
#endif
|
||||
puts("");
|
||||
#ifdef CSR_SDCORE_BASE
|
||||
puts("sdclk <freq> - SDCard set clk frequency (Mhz)");
|
||||
puts("sdinit - SDCard initialization");
|
||||
puts("sdtest <loops> - SDCard test");
|
||||
#endif
|
||||
#ifdef USDDRPHY_DEBUG
|
||||
puts("");
|
||||
puts("sdram_cdly value - Set SDRAM clk/cmd delay");
|
||||
puts("sdram_cal - run SDRAM calibration");
|
||||
puts("sdram_mpr - read SDRAM MPR");
|
||||
puts("sdram_mrwr reg value - write SDRAM mode registers");
|
||||
puts("sdram_cdly_scan enabled - enable/disable cdly scan");
|
||||
#endif
|
||||
#ifdef CSR_SPISDCARD_BASE
|
||||
puts("spisdcardboot - boot from SDCard via SPI hardware bitbang");
|
||||
#endif
|
||||
}
|
||||
|
||||
static char *get_token(char **str)
|
||||
{
|
||||
char *c, *d;
|
||||
|
||||
c = (char *)strchr(*str, ' ');
|
||||
if(c == NULL) {
|
||||
d = *str;
|
||||
*str = *str+strlen(*str);
|
||||
return d;
|
||||
}
|
||||
*c = 0;
|
||||
d = *str;
|
||||
*str = c+1;
|
||||
return d;
|
||||
}
|
||||
|
||||
#ifdef CSR_CTRL_BASE
|
||||
static void reboot(void)
|
||||
{
|
||||
ctrl_reset_write(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void do_command(char *c)
|
||||
{
|
||||
char *token;
|
||||
|
||||
token = get_token(&c);
|
||||
|
||||
if(strcmp(token, "mr") == 0) mr(get_token(&c), get_token(&c));
|
||||
else if(strcmp(token, "mw") == 0) mw(get_token(&c), get_token(&c), get_token(&c));
|
||||
else if(strcmp(token, "mc") == 0) mc(get_token(&c), get_token(&c), get_token(&c));
|
||||
#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
|
||||
else if(strcmp(token, "fw") == 0) fw(get_token(&c), get_token(&c), get_token(&c));
|
||||
else if(strcmp(token, "fe") == 0) fe();
|
||||
#endif
|
||||
#ifdef CSR_ETHPHY_MDIO_W_ADDR
|
||||
else if(strcmp(token, "mdiow") == 0) mdiow(get_token(&c), get_token(&c), get_token(&c));
|
||||
else if(strcmp(token, "mdior") == 0) mdior(get_token(&c), get_token(&c));
|
||||
else if(strcmp(token, "mdiod") == 0) mdiod(get_token(&c), get_token(&c));
|
||||
#endif
|
||||
else if(strcmp(token, "crc") == 0) crc(get_token(&c), get_token(&c));
|
||||
else if(strcmp(token, "ident") == 0) ident();
|
||||
|
||||
else if(strcmp(token, "flush_cpu_dcache") == 0) flush_cpu_dcache();
|
||||
#ifdef CONFIG_L2_SIZE
|
||||
else if(strcmp(token, "flush_l2_cache") == 0) flush_l2_cache();
|
||||
#endif
|
||||
|
||||
#ifdef CSR_CTRL_BASE
|
||||
else if(strcmp(token, "reboot") == 0) reboot();
|
||||
#endif
|
||||
#ifdef FLASH_BOOT_ADDRESS
|
||||
else if(strcmp(token, "flashboot") == 0) flashboot();
|
||||
#endif
|
||||
#ifdef ROM_BOOT_ADDRESS
|
||||
else if(strcmp(token, "romboot") == 0) romboot();
|
||||
#endif
|
||||
else if(strcmp(token, "serialboot") == 0) serialboot();
|
||||
#ifdef CSR_ETHMAC_BASE
|
||||
else if(strcmp(token, "netboot") == 0) netboot();
|
||||
#endif
|
||||
|
||||
else if(strcmp(token, "help") == 0) help();
|
||||
|
||||
#ifdef CSR_SDRAM_BASE
|
||||
else if(strcmp(token, "sdrrow") == 0) sdrrow(get_token(&c));
|
||||
else if(strcmp(token, "sdrsw") == 0) sdrsw();
|
||||
else if(strcmp(token, "sdrhw") == 0) sdrhw();
|
||||
else if(strcmp(token, "sdrrdbuf") == 0) sdrrdbuf(-1);
|
||||
else if(strcmp(token, "sdrrd") == 0) sdrrd(get_token(&c), get_token(&c));
|
||||
else if(strcmp(token, "sdrrderr") == 0) sdrrderr(get_token(&c));
|
||||
else if(strcmp(token, "sdrwr") == 0) sdrwr(get_token(&c));
|
||||
#ifdef CSR_DDRPHY_BASE
|
||||
else if(strcmp(token, "sdrinit") == 0) sdrinit();
|
||||
#ifdef SDRAM_PHY_WRITE_LEVELING_CAPABLE
|
||||
else if(strcmp(token, "sdrwlon") == 0) sdrwlon();
|
||||
else if(strcmp(token, "sdrwloff") == 0) sdrwloff();
|
||||
#endif
|
||||
else if(strcmp(token, "sdrlevel") == 0) sdrlevel();
|
||||
#endif
|
||||
else if(strcmp(token, "memtest") == 0) memtest();
|
||||
#endif
|
||||
|
||||
#ifdef CSR_SDCORE_BASE
|
||||
else if(strcmp(token, "sdclk") == 0) sdclk_set_clk(atoi(get_token(&c)));
|
||||
else if(strcmp(token, "sdinit") == 0) sdcard_init();
|
||||
else if(strcmp(token, "sdtest") == 0) sdcard_test(atoi(get_token(&c)));
|
||||
#endif
|
||||
#ifdef USDDRPHY_DEBUG
|
||||
else if(strcmp(token, "sdram_cdly") == 0)
|
||||
ddrphy_cdly(atoi(get_token(&c)));
|
||||
else if(strcmp(token, "sdram_cal") == 0)
|
||||
sdrcal();
|
||||
else if(strcmp(token, "sdram_mpr") == 0)
|
||||
sdrmpr();
|
||||
else if(strcmp(token, "sdram_mrwr") == 0) {
|
||||
unsigned int reg;
|
||||
unsigned int value;
|
||||
reg = atoi(get_token(&c));
|
||||
value = atoi(get_token(&c));
|
||||
sdrsw();
|
||||
printf("Writing 0x%04x to SDRAM mode register %d\n", value, reg);
|
||||
sdrmrwr(reg, value);
|
||||
sdrhw();
|
||||
}
|
||||
else if(strcmp(token, "sdram_cdly_scan") == 0) {
|
||||
unsigned int enabled;
|
||||
enabled = atoi(get_token(&c));
|
||||
sdr_cdly_scan(enabled);
|
||||
}
|
||||
#endif
|
||||
#ifdef CSR_SPISDCARD_BASE
|
||||
else if(strcmp(token, "spisdcardboot") == 0) spisdcardboot();
|
||||
#endif
|
||||
|
||||
else if(strcmp(token, "") != 0)
|
||||
printf("Command not found\n");
|
||||
}
|
||||
|
||||
extern unsigned int _ftext, _edata;
|
||||
|
||||
static void crcbios(void)
|
||||
{
|
||||
unsigned long offset_bios;
|
||||
unsigned long length;
|
||||
unsigned int expected_crc;
|
||||
unsigned int actual_crc;
|
||||
|
||||
/*
|
||||
* _edata is located right after the end of the flat
|
||||
* binary image. The CRC tool writes the 32-bit CRC here.
|
||||
* We also use the address of _edata to know the length
|
||||
* of our code.
|
||||
*/
|
||||
offset_bios = (unsigned long)&_ftext;
|
||||
expected_crc = _edata;
|
||||
length = (unsigned long)&_edata - offset_bios;
|
||||
actual_crc = crc32((unsigned char *)offset_bios, length);
|
||||
if(expected_crc == actual_crc)
|
||||
printf(" BIOS CRC passed (%08x)\n", actual_crc);
|
||||
else {
|
||||
printf(" BIOS CRC failed (expected %08x, got %08x)\n", expected_crc, actual_crc);
|
||||
printf(" The system will continue, but expect problems.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void readstr(char *s, int size)
|
||||
{
|
||||
static char skip = 0;
|
||||
char c[2];
|
||||
int ptr;
|
||||
|
||||
c[1] = 0;
|
||||
ptr = 0;
|
||||
while(1) {
|
||||
c[0] = readchar();
|
||||
if (c[0] == skip)
|
||||
continue;
|
||||
skip = 0;
|
||||
switch(c[0]) {
|
||||
case 0x7f:
|
||||
case 0x08:
|
||||
if(ptr > 0) {
|
||||
ptr--;
|
||||
putsnonl("\x08 \x08");
|
||||
}
|
||||
break;
|
||||
case 0x07:
|
||||
break;
|
||||
case '\r':
|
||||
skip = '\n';
|
||||
s[ptr] = 0x00;
|
||||
putsnonl("\n");
|
||||
return;
|
||||
case '\n':
|
||||
skip = '\r';
|
||||
s[ptr] = 0x00;
|
||||
putsnonl("\n");
|
||||
return;
|
||||
default:
|
||||
putsnonl(c);
|
||||
s[ptr] = c[0];
|
||||
ptr++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "readline.h"
|
||||
#include "helpers.h"
|
||||
#include "command.h"
|
||||
|
||||
static void boot_sequence(void)
|
||||
{
|
||||
|
@ -614,8 +71,13 @@ static void boot_sequence(void)
|
|||
|
||||
int main(int i, char **c)
|
||||
{
|
||||
char buffer[64];
|
||||
char buffer[CMD_LINE_BUFFER_SIZE];
|
||||
char *params[MAX_PARAM];
|
||||
char *command;
|
||||
struct command_struct *cmd;
|
||||
int nb_params;
|
||||
int sdr_ok;
|
||||
|
||||
#ifdef CONFIG_CPU_HAS_INTERRUPT
|
||||
irq_setmask(0);
|
||||
irq_setie(1);
|
||||
|
@ -696,10 +158,20 @@ int main(int i, char **c)
|
|||
}
|
||||
|
||||
printf("--============= \e[1mConsole\e[0m ================--\n");
|
||||
while(1) {
|
||||
putsnonl("\e[92;1mlitex\e[0m> ");
|
||||
readstr(buffer, 64);
|
||||
do_command(buffer);
|
||||
#if !defined(TERM_MINI) && !defined(TERM_NO_HIST)
|
||||
hist_init();
|
||||
#endif
|
||||
printf("\n%s", PROMPT);
|
||||
while(1) {
|
||||
readline(buffer, CMD_LINE_BUFFER_SIZE);
|
||||
if (buffer[0] != 0) {
|
||||
printf("\n");
|
||||
nb_params = get_param(buffer, &command, params);
|
||||
cmd = command_dispatcher(command, nb_params, params);
|
||||
if (!cmd)
|
||||
printf("Command not found");
|
||||
}
|
||||
printf("\n%s", PROMPT);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
359
litex/soc/software/bios/readline.c
Normal file
359
litex/soc/software/bios/readline.c
Normal file
|
@ -0,0 +1,359 @@
|
|||
// This file is Copyright (c) 2020 Franck Jullien <franck.jullien@gmail.com>
|
||||
//
|
||||
// Largely inspired/copied from U-boot and Barebox projects wich are:
|
||||
// Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
|
||||
// Sascha Hauer, Pengutronix, <s.hauer@pengutronix.de>
|
||||
// cmdline-editing related codes from vivi
|
||||
// Author: Janghoon Lyu <nandy@mizi.com>
|
||||
|
||||
// SPDX-License-Identifier: BSD-Source-Code
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <console.h>
|
||||
#include <uart.h>
|
||||
|
||||
#include "readline.h"
|
||||
#include "complete.h"
|
||||
|
||||
#ifndef TERM_NO_HIST
|
||||
static int hist_max = 0;
|
||||
static int hist_add_idx = 0;
|
||||
static int hist_cur = 0;
|
||||
static int hist_num = 0;
|
||||
static char hist_lines[HIST_MAX][CMD_LINE_BUFFER_SIZE];
|
||||
#endif
|
||||
|
||||
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
|
||||
|
||||
static const struct esc_cmds esccmds[] = {
|
||||
{"OA", KEY_UP}, // cursor key Up
|
||||
{"OB", KEY_DOWN}, // cursor key Down
|
||||
{"OC", KEY_RIGHT}, // Cursor Key Right
|
||||
{"OD", KEY_LEFT}, // cursor key Left
|
||||
{"OH", KEY_HOME}, // Cursor Key Home
|
||||
{"OF", KEY_END}, // Cursor Key End
|
||||
{"[A", KEY_UP}, // cursor key Up
|
||||
{"[B", KEY_DOWN}, // cursor key Down
|
||||
{"[C", KEY_RIGHT}, // Cursor Key Right
|
||||
{"[D", KEY_LEFT}, // cursor key Left
|
||||
{"[H", KEY_HOME}, // Cursor Key Home
|
||||
{"[F", KEY_END}, // Cursor Key End
|
||||
{"[1~", KEY_HOME}, // Cursor Key Home
|
||||
{"[2~", KEY_INSERT}, // Cursor Key Insert
|
||||
{"[3~", KEY_DEL}, // Cursor Key Delete
|
||||
{"[4~", KEY_END}, // Cursor Key End
|
||||
{"[5~", KEY_PAGEUP}, // Cursor Key Page Up
|
||||
{"[6~", KEY_PAGEDOWN},// Cursor Key Page Down
|
||||
};
|
||||
|
||||
static int read_key(void)
|
||||
{
|
||||
char c;
|
||||
char esc[5];
|
||||
c = readchar();
|
||||
|
||||
if (c == 27) {
|
||||
int i = 0;
|
||||
esc[i++] = readchar();
|
||||
esc[i++] = readchar();
|
||||
if (isdigit(esc[1])) {
|
||||
while(1) {
|
||||
esc[i] = readchar();
|
||||
if (esc[i++] == '~')
|
||||
break;
|
||||
if (i == ARRAY_SIZE(esc))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
esc[i] = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(esccmds); i++){
|
||||
if (!strcmp(esc, esccmds[i].seq))
|
||||
return esccmds[i].val;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
#ifndef TERM_NO_HIST
|
||||
static void cread_add_to_hist(char *line)
|
||||
{
|
||||
strcpy(&hist_lines[hist_add_idx][0], line);
|
||||
|
||||
if (++hist_add_idx >= HIST_MAX)
|
||||
hist_add_idx = 0;
|
||||
|
||||
if (hist_add_idx > hist_max)
|
||||
hist_max = hist_add_idx;
|
||||
|
||||
hist_num++;
|
||||
}
|
||||
|
||||
static char* hist_prev(void)
|
||||
{
|
||||
char *ret;
|
||||
int old_cur;
|
||||
|
||||
if (hist_cur < 0)
|
||||
return NULL;
|
||||
|
||||
old_cur = hist_cur;
|
||||
if (--hist_cur < 0)
|
||||
hist_cur = hist_max;
|
||||
|
||||
if (hist_cur == hist_add_idx) {
|
||||
hist_cur = old_cur;
|
||||
ret = NULL;
|
||||
} else {
|
||||
ret = &hist_lines[hist_cur][0];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char* hist_next(void)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
if (hist_cur < 0)
|
||||
return NULL;
|
||||
|
||||
if (hist_cur == hist_add_idx)
|
||||
return NULL;
|
||||
|
||||
if (++hist_cur > hist_max)
|
||||
hist_cur = 0;
|
||||
|
||||
if (hist_cur == hist_add_idx)
|
||||
ret = "";
|
||||
else
|
||||
ret = &hist_lines[hist_cur][0];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void hist_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
hist_max = 0;
|
||||
hist_add_idx = 0;
|
||||
hist_cur = -1;
|
||||
hist_num = 0;
|
||||
|
||||
for (i = 0; i < HIST_MAX; i++)
|
||||
hist_lines[i][0] = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
static void cread_add_char(char ichar, int insert, unsigned long *num,
|
||||
unsigned long *eol_num, char *buf, unsigned long len)
|
||||
{
|
||||
unsigned long wlen;
|
||||
|
||||
if (insert || *num == *eol_num) {
|
||||
if (*eol_num > len - 1) {
|
||||
getcmd_cbeep();
|
||||
return;
|
||||
}
|
||||
(*eol_num)++;
|
||||
}
|
||||
|
||||
if (insert) {
|
||||
wlen = *eol_num - *num;
|
||||
if (wlen > 1) {
|
||||
memmove(&buf[*num+1], &buf[*num], wlen-1);
|
||||
}
|
||||
|
||||
buf[*num] = ichar;
|
||||
putnstr(buf + *num, wlen);
|
||||
(*num)++;
|
||||
while (--wlen) {
|
||||
getcmd_putch(CTL_BACKSPACE);
|
||||
}
|
||||
} else {
|
||||
/* echo the character */
|
||||
wlen = 1;
|
||||
buf[*num] = ichar;
|
||||
putnstr(buf + *num, wlen);
|
||||
(*num)++;
|
||||
}
|
||||
}
|
||||
|
||||
int readline(char *buf, int len)
|
||||
{
|
||||
unsigned long num = 0;
|
||||
unsigned long eol_num = 0;
|
||||
unsigned long wlen;
|
||||
int insert = 1;
|
||||
char ichar;
|
||||
|
||||
#ifndef TERM_NO_COMPLETE
|
||||
char tmp;
|
||||
int reprint, i;
|
||||
char *completestr;
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
|
||||
ichar = read_key();
|
||||
|
||||
if ((ichar == '\n') || (ichar == '\r'))
|
||||
break;
|
||||
|
||||
switch (ichar) {
|
||||
case '\t':
|
||||
#ifndef TERM_NO_COMPLETE
|
||||
buf[eol_num] = 0;
|
||||
tmp = buf[num];
|
||||
|
||||
buf[num] = 0;
|
||||
reprint = complete(buf, &completestr);
|
||||
buf[num] = tmp;
|
||||
|
||||
if (reprint) {
|
||||
printf("%s%s", PROMPT, buf);
|
||||
|
||||
if (tmp)
|
||||
for (i = 0; i < eol_num - num; i++)
|
||||
getcmd_putch(CTL_BACKSPACE);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (completestr[i])
|
||||
cread_add_char(completestr[i++], insert, &num,
|
||||
&eol_num, buf, len);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case KEY_HOME:
|
||||
BEGINNING_OF_LINE();
|
||||
break;
|
||||
case CTL_CH('c'): /* ^C - break */
|
||||
*buf = 0; /* discard input */
|
||||
return -1;
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
if (num < eol_num) {
|
||||
getcmd_putch(buf[num]);
|
||||
num++;
|
||||
}
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
if (num) {
|
||||
getcmd_putch(CTL_BACKSPACE);
|
||||
num--;
|
||||
}
|
||||
break;
|
||||
case CTL_CH('d'):
|
||||
if (num < eol_num) {
|
||||
wlen = eol_num - num - 1;
|
||||
if (wlen) {
|
||||
memmove(&buf[num], &buf[num+1], wlen);
|
||||
putnstr(buf + num, (int)wlen);
|
||||
}
|
||||
|
||||
getcmd_putch(' ');
|
||||
do {
|
||||
getcmd_putch(CTL_BACKSPACE);
|
||||
} while (wlen--);
|
||||
eol_num--;
|
||||
}
|
||||
break;
|
||||
case KEY_ERASE_TO_EOL:
|
||||
ERASE_TO_EOL();
|
||||
break;
|
||||
case KEY_REFRESH_TO_EOL:
|
||||
case KEY_END:
|
||||
REFRESH_TO_EOL();
|
||||
break;
|
||||
case KEY_INSERT:
|
||||
insert = !insert;
|
||||
break;
|
||||
case KEY_ERASE_LINE:
|
||||
BEGINNING_OF_LINE();
|
||||
ERASE_TO_EOL();
|
||||
break;
|
||||
case DEL:
|
||||
case KEY_DEL7:
|
||||
case 8:
|
||||
if (num) {
|
||||
wlen = eol_num - num;
|
||||
num--;
|
||||
memmove(buf + num, buf + num + 1, wlen);
|
||||
getcmd_putch(CTL_BACKSPACE);
|
||||
putnstr(buf + num, (int)wlen);
|
||||
getcmd_putch(' ');
|
||||
do {
|
||||
getcmd_putch(CTL_BACKSPACE);
|
||||
} while (wlen--);
|
||||
eol_num--;
|
||||
}
|
||||
break;
|
||||
case KEY_DEL:
|
||||
if (num < eol_num) {
|
||||
wlen = eol_num - num;
|
||||
memmove(buf + num, buf + num + 1, wlen);
|
||||
putnstr(buf + num, (int)(wlen - 1));
|
||||
getcmd_putch(' ');
|
||||
do {
|
||||
getcmd_putch(CTL_BACKSPACE);
|
||||
} while (--wlen);
|
||||
eol_num--;
|
||||
}
|
||||
break;
|
||||
case KEY_UP:
|
||||
case KEY_DOWN:
|
||||
{
|
||||
#ifndef TERM_NO_HIST
|
||||
char * hline;
|
||||
if (ichar == KEY_UP)
|
||||
hline = hist_prev();
|
||||
else
|
||||
hline = hist_next();
|
||||
|
||||
if (!hline) {
|
||||
getcmd_cbeep();
|
||||
break;
|
||||
}
|
||||
|
||||
/* nuke the current line */
|
||||
/* first, go home */
|
||||
BEGINNING_OF_LINE();
|
||||
|
||||
/* erase to end of line */
|
||||
ERASE_TO_EOL();
|
||||
|
||||
/* copy new line into place and display */
|
||||
strcpy(buf, hline);
|
||||
eol_num = strlen(buf);
|
||||
REFRESH_TO_EOL();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
if (isascii(ichar) && isprint(ichar))
|
||||
cread_add_char (ichar, insert, &num, &eol_num, buf, len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
len = eol_num;
|
||||
buf[eol_num] = '\0';
|
||||
|
||||
#ifndef TERM_NO_HIST
|
||||
if (buf[0] && buf[0] != CREAD_HIST_CHAR)
|
||||
cread_add_to_hist(buf);
|
||||
hist_cur = hist_add_idx;
|
||||
#endif
|
||||
|
||||
num = 0;
|
||||
eol_num = 0;
|
||||
|
||||
return len;
|
||||
}
|
83
litex/soc/software/bios/readline.h
Normal file
83
litex/soc/software/bios/readline.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
#ifndef __READLINE_H__
|
||||
#define __READLINE_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define CMD_LINE_BUFFER_SIZE 64
|
||||
|
||||
#define PROMPT "\e[92;1mlitex\e[0m> "
|
||||
|
||||
#define ESC 27
|
||||
|
||||
struct esc_cmds {
|
||||
const char *seq;
|
||||
char val;
|
||||
};
|
||||
|
||||
#define CTL_CH(c) ((c) - 'a' + 1)
|
||||
|
||||
/* Misc. non-Ascii keys */
|
||||
#define KEY_UP CTL_CH('p') /* cursor key Up */
|
||||
#define KEY_DOWN CTL_CH('n') /* cursor key Down */
|
||||
#define KEY_RIGHT CTL_CH('f') /* Cursor Key Right */
|
||||
#define KEY_LEFT CTL_CH('b') /* cursor key Left */
|
||||
#define KEY_HOME CTL_CH('a') /* Cursor Key Home */
|
||||
#define KEY_ERASE_TO_EOL CTL_CH('k')
|
||||
#define KEY_REFRESH_TO_EOL CTL_CH('e')
|
||||
#define KEY_ERASE_LINE CTL_CH('x')
|
||||
#define KEY_INSERT CTL_CH('o')
|
||||
#define KEY_CLEAR_SCREEN CTL_CH('l')
|
||||
#define KEY_DEL7 127
|
||||
#define KEY_END 133 /* Cursor Key End */
|
||||
#define KEY_PAGEUP 135 /* Cursor Key Page Up */
|
||||
#define KEY_PAGEDOWN 136 /* Cursor Key Page Down */
|
||||
#define KEY_DEL 137 /* Cursor Key Del */
|
||||
|
||||
#define MAX_CMDBUF_SIZE 256
|
||||
|
||||
#define CTL_BACKSPACE ('\b')
|
||||
#define DEL 255
|
||||
#define DEL7 127
|
||||
#define CREAD_HIST_CHAR ('!')
|
||||
|
||||
#define HIST_MAX 10
|
||||
|
||||
#define putnstr(str,n) do { \
|
||||
printf ("%.*s", n, str); \
|
||||
} while (0)
|
||||
|
||||
#define getcmd_putch(ch) putchar(ch)
|
||||
#define getcmd_cbeep() getcmd_putch('\a')
|
||||
#define ANSI_CLEAR_SCREEN "\e[2J\e[;H"
|
||||
|
||||
#define BEGINNING_OF_LINE() { \
|
||||
while (num) { \
|
||||
getcmd_putch(CTL_BACKSPACE); \
|
||||
num--; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ERASE_TO_EOL() { \
|
||||
if (num < eol_num) { \
|
||||
int t; \
|
||||
for (t = num; t < eol_num; t++) \
|
||||
getcmd_putch(' '); \
|
||||
while (t-- > num) \
|
||||
getcmd_putch(CTL_BACKSPACE); \
|
||||
eol_num = num; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define REFRESH_TO_EOL() { \
|
||||
if (num < eol_num) { \
|
||||
wlen = eol_num - num; \
|
||||
putnstr(buf + num, (int)wlen); \
|
||||
num = eol_num; \
|
||||
} \
|
||||
}
|
||||
|
||||
int readline(char *buf, int len);
|
||||
void hist_init(void);
|
||||
|
||||
#endif /* READLINE_H_ */
|
59
litex/soc/software/bios/readline_simple.c
Normal file
59
litex/soc/software/bios/readline_simple.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
// This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq <sb@m-labs.hk>
|
||||
// This file is Copyright (c) 2014-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
|
||||
// SPDX-License-Identifier: BSD-Source-Code
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <console.h>
|
||||
#include <uart.h>
|
||||
|
||||
#include "readline.h"
|
||||
|
||||
int readline(char *s, int size)
|
||||
{
|
||||
static char skip = 0;
|
||||
char c[2];
|
||||
int ptr;
|
||||
|
||||
c[1] = 0;
|
||||
ptr = 0;
|
||||
while(1) {
|
||||
c[0] = readchar();
|
||||
if (c[0] == skip)
|
||||
continue;
|
||||
skip = 0;
|
||||
switch(c[0]) {
|
||||
case 0x7f:
|
||||
case 0x08:
|
||||
if(ptr > 0) {
|
||||
ptr--;
|
||||
putsnonl("\x08 \x08");
|
||||
}
|
||||
break;
|
||||
case 0x07:
|
||||
break;
|
||||
case '\r':
|
||||
skip = '\n';
|
||||
s[ptr] = 0x00;
|
||||
putsnonl("\n");
|
||||
return 0;
|
||||
case '\n':
|
||||
skip = '\r';
|
||||
s[ptr] = 0x00;
|
||||
putsnonl("\n");
|
||||
return 0;
|
||||
default:
|
||||
putsnonl(c);
|
||||
s[ptr] = c[0];
|
||||
ptr++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -78,28 +78,18 @@ void sdrhw(void)
|
|||
printf("SDRAM now under hardware control\n");
|
||||
}
|
||||
|
||||
void sdrrow(char *_row)
|
||||
void sdrrow(unsigned int row)
|
||||
{
|
||||
char *c;
|
||||
unsigned int row;
|
||||
|
||||
if(*_row == 0) {
|
||||
if(row == 0) {
|
||||
sdram_dfii_pi0_address_write(0x0000);
|
||||
sdram_dfii_pi0_baddress_write(0);
|
||||
command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
|
||||
cdelay(15);
|
||||
printf("Precharged\n");
|
||||
} else {
|
||||
row = strtoul(_row, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect row\n");
|
||||
return;
|
||||
}
|
||||
sdram_dfii_pi0_address_write(row);
|
||||
sdram_dfii_pi0_baddress_write(0);
|
||||
command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CS);
|
||||
cdelay(15);
|
||||
printf("Activated row %d\n", row);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,58 +116,23 @@ void sdrrdbuf(int dq)
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
void sdrrd(char *startaddr, char *dq)
|
||||
void sdrrd(unsigned int addr, int dq)
|
||||
{
|
||||
char *c;
|
||||
unsigned int addr;
|
||||
int _dq;
|
||||
|
||||
if(*startaddr == 0) {
|
||||
printf("sdrrd <address>\n");
|
||||
return;
|
||||
}
|
||||
addr = strtoul(startaddr, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect address\n");
|
||||
return;
|
||||
}
|
||||
if(*dq == 0)
|
||||
_dq = -1;
|
||||
else {
|
||||
_dq = strtoul(dq, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect DQ\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sdram_dfii_pird_address_write(addr);
|
||||
sdram_dfii_pird_baddress_write(0);
|
||||
command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
|
||||
cdelay(15);
|
||||
sdrrdbuf(_dq);
|
||||
sdrrdbuf(dq);
|
||||
}
|
||||
|
||||
void sdrrderr(char *count)
|
||||
void sdrrderr(int count)
|
||||
{
|
||||
int addr;
|
||||
char *c;
|
||||
int _count;
|
||||
int i, j, p;
|
||||
unsigned char prev_data[SDRAM_PHY_PHASES][DFII_PIX_DATA_BYTES];
|
||||
unsigned char errs[SDRAM_PHY_PHASES][DFII_PIX_DATA_BYTES];
|
||||
unsigned char new_data[DFII_PIX_DATA_BYTES];
|
||||
|
||||
if(*count == 0) {
|
||||
printf("sdrrderr <count>\n");
|
||||
return;
|
||||
}
|
||||
_count = strtoul(count, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect count\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for(p=0;p<SDRAM_PHY_PHASES;p++)
|
||||
for(i=0;i<DFII_PIX_DATA_BYTES;i++)
|
||||
errs[p][i] = 0;
|
||||
|
@ -191,7 +146,7 @@ void sdrrderr(char *count)
|
|||
csr_rd_buf_uint8(sdram_dfii_pix_rddata_addr[p],
|
||||
prev_data[p], DFII_PIX_DATA_BYTES);
|
||||
|
||||
for(j=0;j<_count;j++) {
|
||||
for(j=0;j<count;j++) {
|
||||
command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
|
||||
cdelay(15);
|
||||
for(p=0;p<SDRAM_PHY_PHASES;p++) {
|
||||
|
@ -215,23 +170,11 @@ void sdrrderr(char *count)
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
void sdrwr(char *startaddr)
|
||||
void sdrwr(unsigned int addr)
|
||||
{
|
||||
int i, p;
|
||||
char *c;
|
||||
unsigned int addr;
|
||||
unsigned char buf[DFII_PIX_DATA_BYTES];
|
||||
|
||||
if(*startaddr == 0) {
|
||||
printf("sdrwr <address>\n");
|
||||
return;
|
||||
}
|
||||
addr = strtoul(startaddr, &c, 0);
|
||||
if(*c != 0) {
|
||||
printf("incorrect address\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for(p=0;p<SDRAM_PHY_PHASES;p++) {
|
||||
for(i=0;i<DFII_PIX_DATA_BYTES;i++)
|
||||
buf[i] = 0x10*p + i;
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
|
||||
void sdrsw(void);
|
||||
void sdrhw(void);
|
||||
void sdrrow(char *_row);
|
||||
void sdrrow(unsigned int row);
|
||||
void sdrrdbuf(int dq);
|
||||
void sdrrd(char *startaddr, char *dq);
|
||||
void sdrrderr(char *count);
|
||||
void sdrwr(char *startaddr);
|
||||
void sdrrd(unsigned int addr, int dq);
|
||||
void sdrrderr(int count);
|
||||
void sdrwr(unsigned int addr);
|
||||
|
||||
void sdrwlon(void);
|
||||
void sdrwloff(void);
|
||||
|
|
Loading…
Reference in a new issue