Merge pull request #474 from fjullien/term_hist_auto_compl

Terminal: add history and auto completion
This commit is contained in:
enjoy-digital 2020-05-02 10:45:12 +02:00 committed by GitHub
commit 705d388745
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 1916 additions and 624 deletions

View file

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

View file

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

View 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

View 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

View 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

View 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

View 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

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

View 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

View 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

View 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

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

View file

@ -0,0 +1,6 @@
#ifndef __COMPLETE_H__
#define __COMPLETE_H__
int complete(char *instr, char **outstr);
#endif

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

View 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

View file

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

View file

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

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

View 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_ */

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

View file

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

View file

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