demo: cleanup software

parent da943185
......@@ -369,10 +369,10 @@ lm32_top cpu(
//---------------------------------------------------------------------------
bram #(
.adr_width(14),
.init0("../../../software/bios/bios.h0"),
.init1("../../../software/bios/bios.h1"),
.init2("../../../software/bios/bios.h2"),
.init3("../../../software/bios/bios.h3")
.init0("../../../software/demo/demo.h0"),
.init1("../../../software/demo/demo.h1"),
.init2("../../../software/demo/demo.h2"),
.init3("../../../software/demo/demo.h3")
) bram (
.sys_clk(sys_clk),
.sys_rst(sys_rst),
......
/*
* Milkymist SoC (Software)
* Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <console.h>
#include <uart.h>
#include <system.h>
#include <board.h>
#include <crc.h>
#include <sfl.h>
#include "boot.h"
extern const struct board_desc *brd_desc;
/*
* HACK: by defining this function as not inlinable, GCC will automatically
* put the values we want into the good registers because it has to respect
* the LM32 calling conventions.
*/
static void __attribute__((noinline)) __attribute__((noreturn)) boot(unsigned int r1, unsigned int r2, unsigned int r3, unsigned int addr)
{
asm volatile( /* Invalidate instruction cache */
"wcsr ICC, r0\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"call r4\n"
);
}
/* Note that we do not use the hw timer so that this function works
* even if the system controller has been disabled at synthesis.
*/
static int check_ack()
{
int timeout;
int recognized;
static const char str[SFL_MAGIC_LEN] = SFL_MAGIC_ACK;
timeout = 4500000;
recognized = 0;
while(timeout > 0) {
if(readchar_nonblock()) {
char c;
c = readchar();
if(c == str[recognized]) {
recognized++;
if(recognized == SFL_MAGIC_LEN)
return 1;
} else {
if(c == str[0])
recognized = 1;
else
recognized = 0;
}
}
timeout--;
}
return 0;
}
#define MAX_FAILED 5
void serialboot()
{
struct sfl_frame frame;
int failed;
unsigned int cmdline_adr, initrdstart_adr, initrdend_adr;
printf("I: Attempting serial firmware loading\n");
putsnonl(SFL_MAGIC_REQ);
if(!check_ack()) {
printf("E: Timeout\n");
return;
}
failed = 0;
cmdline_adr = initrdstart_adr = initrdend_adr = 0;
while(1) {
int i;
int actualcrc;
int goodcrc;
/* Grab one frame */
frame.length = readchar();
frame.crc[0] = readchar();
frame.crc[1] = readchar();
frame.cmd = readchar();
for(i=0;i<frame.length;i++)
frame.payload[i] = readchar();
/* Check CRC */
actualcrc = ((int)frame.crc[0] << 8)|(int)frame.crc[1];
goodcrc = crc16(&frame.cmd, frame.length+1);
if(actualcrc != goodcrc) {
failed++;
if(failed == MAX_FAILED) {
printf("E: Too many consecutive errors, aborting");
return;
}
writechar(SFL_ACK_CRCERROR);
continue;
}
/* CRC OK */
switch(frame.cmd) {
case SFL_CMD_ABORT:
failed = 0;
writechar(SFL_ACK_SUCCESS);
return;
case SFL_CMD_LOAD: {
char *writepointer;
failed = 0;
writepointer = (char *)(
((unsigned int)frame.payload[0] << 24)
|((unsigned int)frame.payload[1] << 16)
|((unsigned int)frame.payload[2] << 8)
|((unsigned int)frame.payload[3] << 0));
for(i=4;i<frame.length;i++)
*(writepointer++) = frame.payload[i];
writechar(SFL_ACK_SUCCESS);
break;
}
case SFL_CMD_JUMP: {
unsigned int addr;
failed = 0;
addr = ((unsigned int)frame.payload[0] << 24)
|((unsigned int)frame.payload[1] << 16)
|((unsigned int)frame.payload[2] << 8)
|((unsigned int)frame.payload[3] << 0);
writechar(SFL_ACK_SUCCESS);
boot(cmdline_adr, initrdstart_adr, initrdend_adr, addr);
break;
}
case SFL_CMD_CMDLINE:
failed = 0;
cmdline_adr = ((unsigned int)frame.payload[0] << 24)
|((unsigned int)frame.payload[1] << 16)
|((unsigned int)frame.payload[2] << 8)
|((unsigned int)frame.payload[3] << 0);
writechar(SFL_ACK_SUCCESS);
break;
case SFL_CMD_INITRDSTART:
failed = 0;
initrdstart_adr = ((unsigned int)frame.payload[0] << 24)
|((unsigned int)frame.payload[1] << 16)
|((unsigned int)frame.payload[2] << 8)
|((unsigned int)frame.payload[3] << 0);
writechar(SFL_ACK_SUCCESS);
break;
case SFL_CMD_INITRDEND:
failed = 0;
initrdend_adr = ((unsigned int)frame.payload[0] << 24)
|((unsigned int)frame.payload[1] << 16)
|((unsigned int)frame.payload[2] << 8)
|((unsigned int)frame.payload[3] << 0);
writechar(SFL_ACK_SUCCESS);
break;
default:
failed++;
if(failed == MAX_FAILED) {
printf("E: Too many consecutive errors, aborting");
return;
}
writechar(SFL_ACK_UNKNOWN);
break;
}
}
}
/*
* Milkymist SoC (Software)
* Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BOOT_H
#define __BOOT_H
void cardboot(int alt);
void serialboot();
#endif /* __BOOT_H */
MMDIR=../..
include $(MMDIR)/software/include.mak
OBJECTS=crt0.o main.o boot.o
OBJECTS=crt0.o main.o
SEGMENTS=-j .text -j .data -j .rodata
all: bios.bin bios.h0 bios.h1 bios.h2 bios.h3
all: demo.bin demo.h0 demo.h1 demo.h2 demo.h3
bios.h0: bios.bin
demo.h0: demo.bin
$(MMDIR)/tools/bin2hex $< $@ 4096 4
bios.h1: bios.bin
demo.h1: demo.bin
$(MMDIR)/tools/bin2hex $< $@ 4096 3
bios.h2: bios.bin
demo.h2: demo.bin
$(MMDIR)/tools/bin2hex $< $@ 4096 2
bios.h3: bios.bin
demo.h3: demo.bin
$(MMDIR)/tools/bin2hex $< $@ 4096 1
%.bin: %.elf
......@@ -23,7 +23,7 @@ bios.h3: bios.bin
chmod -x $@
$(MMDIR)/tools/crc32 $@ write
bios.elf: linker.ld $(OBJECTS)
demo.elf: linker.ld $(OBJECTS)
$(LD) $(LDFLAGS) -T linker.ld -N -o $@ $(OBJECTS) -L$(MMDIR)/software/libbase -lbase
chmod -x $@
......@@ -33,18 +33,13 @@ depend:
makedepend -Y -- $(CFLAGS) -- *.c
clean:
rm -f *.o bios.elf bios.bin bios.h0 bios.h1 bios.h2 bios.h3 .*~ *~ Makefile.bak
rm -f *.o demo.elf demo.bin demo.h0 demo.h1 demo.h2 demo.h3 .*~ *~ Makefile.bak
# DO NOT DELETE
boot.o: ../../software/include/stdio.h ../../software/include/stdlib.h
boot.o: ../../software/include/console.h ../../software/include/uart.h
boot.o: ../../software/include/system.h ../../software/include/board.h
boot.o: ../../software/include/crc.h ../../tools/sfl.h boot.h
main.o: ../../software/include/stdio.h ../../software/include/stdlib.h
main.o: ../../software/include/console.h ../../software/include/string.h
main.o: ../../software/include/uart.h ../../software/include/crc.h
main.o: ../../software/include/system.h ../../software/include/board.h
main.o: ../../software/include/version.h ../../software/include/hw/sysctl.h
main.o: ../../software/include/system.h ../../software/include/hw/sysctl.h
main.o: ../../software/include/hw/common.h ../../software/include/hw/gpio.h
main.o: ../../software/include/hw/uart.h boot.h
main.o: ../../software/include/hw/uart.h
......@@ -21,16 +21,10 @@
#include <uart.h>
#include <crc.h>
#include <system.h>
#include <board.h>
#include <version.h>
#include <hw/sysctl.h>
#include <hw/gpio.h>
#include <hw/uart.h>
#include "boot.h"
const struct board_desc *brd_desc;
/* General address space functions */
#define NUMBER_OF_BYTES_ON_A_LINE 16
......@@ -193,18 +187,6 @@ static void crc(char *startaddr, char *len)
/* Init + command line */
static void help()
{
puts("This is the Milkymist BIOS debug shell.");
puts("Available commands:");
puts("mr - read address space");
puts("mw - write address space");
puts("mc - copy address space");
puts("crc - compute CRC32 of a part of the address space");
puts("serialboot - attempt SFL boot");
puts("reboot - system reset");
}
static char *get_token(char **str)
{
char *c, *d;
......@@ -232,37 +214,15 @@ static void do_command(char *c)
else if(strcmp(token, "mc") == 0) mc(get_token(&c), get_token(&c), get_token(&c));
else if(strcmp(token, "crc") == 0) crc(get_token(&c), get_token(&c));
else if(strcmp(token, "serialboot") == 0) serialboot();
else if(strcmp(token, "reboot") == 0) reboot();
else if(strcmp(token, "help") == 0) help();
else if(strcmp(token, "") != 0)
printf("Command not found\n");
}
static int test_user_abort()
{
unsigned int i;
char c;
puts("I: Press Q to abort boot");
for(i=0;i<4000000;i++) {
if(readchar_nonblock()) {
c = readchar();
if(c == 'Q') {
puts("I: Aborted boot on user request");
return 0;
}
}
}
return 1;
}
extern unsigned int _edata;
static void crcbios()
static void crcsw()
{
unsigned int length;
unsigned int expected_crc;
......@@ -278,53 +238,27 @@ static void crcbios()
length = (unsigned int)&_edata;
actual_crc = crc32((unsigned char *)0, length);
if(expected_crc == actual_crc)
printf("I: BIOS CRC passed (%08x)\n", actual_crc);
printf("I: SW CRC passed (%08x)\n", actual_crc);
else {
printf("W: BIOS CRC failed (expected %08x, got %08x)\n", expected_crc, actual_crc);
printf("W: SW CRC failed (expected %08x, got %08x)\n", expected_crc, actual_crc);
printf("W: The system will continue, but expect problems.\n");
}
}
static void display_board()
{
if(brd_desc == NULL) {
printf("E: Running on unknown board (ID=0x%08x), startup aborted.\n", CSR_SYSTEM_ID);
while(1);
}
printf("I: Running on %s\n", brd_desc->name);
}
static const char banner[] =
"\nMILKYMIST(tm) v"VERSION" BIOS\thttp://www.milkymist.org\n"
"(c) 2007, 2008, 2009, 2011 Sebastien Bourdeauducq\n\n"
"This program is free software: you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License as published by\n"
"the Free Software Foundation, version 3 of the License.\n\n";
static void boot_sequence()
{
if(test_user_abort()) {
serialboot(1);
printf("E: No boot medium found\n");
}
}
"\nTime to Digital Converter demo\n\n";
int main(int i, char **c)
{
char buffer[64];
brd_desc = get_board_desc();
/* Display a banner as soon as possible to show that the system is alive */
putsnonl(banner);
crcbios();
display_board();
boot_sequence();
crcsw();
while(1) {
putsnonl("\e[1mBIOS>\e[0m ");
putsnonl("\e[1mTDC>\e[0m ");
readstr(buffer, 64);
do_command(buffer);
}
......
/*
* Milkymist SoC (Software)
* Copyright (C) 2007, 2008, 2009, 2011 Sebastien Bourdeauducq
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __BOARD_H
#define __BOARD_H
#define BOARD_NAME_LEN 32
struct board_desc {
unsigned int id;
char name[BOARD_NAME_LEN];
unsigned int clk_frequency;
};
const struct board_desc *get_board_desc_id(unsigned int id);
const struct board_desc *get_board_desc();
#endif /* __BOARD_H */
#ifndef __VERSION_H
#define __VERSION_H
#define VERSION "0.2-tdc"
#endif /* __VERSION_H */
......@@ -2,7 +2,7 @@ MMDIR=../..
include $(MMDIR)/software/include.mak
OBJECTS=_ashlsi3.o _divsi3.o _modsi3.o _udivmodsi4.o _umodsi3.o _ashrsi3.o _lshrsi3.o _mulsi3.o _udivsi3.o
OBJECTS+=libc.o crc16.o crc32.o console.o system.o board.o irq.o vsnprintf-nofloat.o uart.o
OBJECTS+=libc.o crc16.o crc32.o console.o system.o irq.o vsnprintf-nofloat.o uart.o
all: libbase.a
......@@ -20,9 +20,6 @@ clean:
# DO NOT DELETE
board.o: ../../software/include/hw/sysctl.h
board.o: ../../software/include/hw/common.h ../../software/include/stdlib.h
board.o: ../../software/include/board.h
console.o: ../../software/include/uart.h ../../software/include/console.h
console.o: ../../software/include/stdio.h ../../software/include/stdlib.h
console.o: ../../software/include/stdarg.h
......
/*
* Milkymist SoC (Software)
* Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
* Copyright (C) 2011 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <hw/sysctl.h>
#include <stdlib.h>
#include <board.h>
static const struct board_desc boards[1] = {
{
.id = 0x53504543, /* SPEC */
.name = "SPEC",
.clk_frequency = 125000000,
},
};
const struct board_desc *get_board_desc_id(unsigned int id)
{
unsigned int i;
for(i=0;i<sizeof(boards)/sizeof(boards[0]);i++)
if(boards[i].id == id)
return &boards[i];
return NULL;
}
const struct board_desc *get_board_desc()
{
return get_board_desc_id(CSR_SYSTEM_ID);
}
#!/bin/bash
make -C libbase depend
make -C bios depend
make -C demo depend
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment