runtime: load support code into kernel CPU

This commit is contained in:
Sebastien Bourdeauducq 2015-04-03 17:44:56 +08:00
parent c6d3750076
commit 21a0919ddc
7 changed files with 143 additions and 34 deletions

View File

@ -3,7 +3,7 @@ include $(MSCDIR)/software/common.mak
BOARD=papilio_pro BOARD=papilio_pro
SERIAL=/dev/ttyUSB1 SERIAL=/dev/ttyUSB1
OBJECTS=isr.o elf_loader.o exception_jmp.o exceptions.o services.o comm_serial.o gpio.o rtio.o dds.o test_mode.o main.o OBJECTS=isr.o elf_loader.o kernelcpu.o exception_jmp.o exceptions.o services.o comm_serial.o gpio.o rtio.o dds.o ksupport_data.o test_mode.o main.o
all: runtime.bin all: runtime.bin
@ -12,7 +12,7 @@ all: runtime.bin
%.bin: %.elf %.bin: %.elf
$(OBJCOPY) -O binary $< $@ $(OBJCOPY) -O binary $< $@
chmod -x $@ @chmod -x $@
%.fbi: %.bin %.fbi: %.bin
$(MSCDIR)/mkmscimg.py -f -o $@ $< $(MSCDIR)/mkmscimg.py -f -o $@ $<
@ -28,7 +28,18 @@ runtime.elf: $(OBJECTS) libs
-L$(MSCDIR)/software/libbase \ -L$(MSCDIR)/software/libbase \
-L$(MSCDIR)/software/libcompiler-rt \ -L$(MSCDIR)/software/libcompiler-rt \
-lbase -lcompiler-rt -lbase -lcompiler-rt
chmod -x $@ @chmod -x $@
ksupport.elf: ksupport.o
$(LD) $(LDFLAGS) \
-T ksupport.ld \
-N -o $@ \
$(MSCDIR)/software/libbase/crt0-$(CPU).o \
ksupport.o
@chmod -x $@
ksupport_data.o: ksupport.bin
$(LD) -r -b binary -o $@ $<
main.o: main.c main.o: main.c
$(compile-dep) $(compile-dep)
@ -52,5 +63,6 @@ flash: runtime.fbi
clean: clean:
$(RM) $(OBJECTS) $(OBJECTS:.o=.d) runtime.elf runtime.bin runtime.fbi .*~ *~ $(RM) $(OBJECTS) $(OBJECTS:.o=.d) runtime.elf runtime.bin runtime.fbi .*~ *~
$(RM) ksupport.d ksupport.o ksupport.elf ksupport.bin
.PHONY: all main.o clean libs load .PHONY: all main.o clean libs load

27
soc/runtime/kernelcpu.c Normal file
View File

@ -0,0 +1,27 @@
#include <generated/csr.h>
#ifdef CSR_KERNEL_CPU_BASE
#include <stdio.h>
#include <string.h>
#include <system.h>
#include "kernelcpu.h"
extern char _binary_ksupport_bin_start;
extern char _binary_ksupport_bin_end;
void kernelcpu_start(void)
{
memcpy((void *)KERNELCPU_EXEC_ADDRESS, &_binary_ksupport_bin_start,
&_binary_ksupport_bin_end - &_binary_ksupport_bin_start);
flush_l2_cache();
kernel_cpu_reset_write(0);
}
void kernelcpu_stop(void)
{
kernel_cpu_reset_write(1);
}
#endif /* CSR_KERNEL_CPU_BASE */

14
soc/runtime/kernelcpu.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef __KERNELCPU_H
#define __KERNELCPU_H
#include <hw/common.h>
#define KERNELCPU_EXEC_ADDRESS 0x40020000
#define KERNELCPU_KMAIN_ADDRESS 0x40022000
#define KERNELCPU_MAILBOX MMPTR(0xd0000000)
void kernelcpu_start(void);
void kernelcpu_stop(void);
#endif /* __KERNELCPU_H */

16
soc/runtime/ksupport.c Normal file
View File

@ -0,0 +1,16 @@
void exception_handler(unsigned long vect, unsigned long *sp);
void exception_handler(unsigned long vect, unsigned long *sp)
{
/* TODO: report hardware exception to comm CPU */
for(;;);
}
extern void kmain(void);
int main(void);
int main(void)
{
kmain();
/* TODO: report end of kernel to comm CPU */
return 0;
}

65
soc/runtime/ksupport.ld Normal file
View File

@ -0,0 +1,65 @@
INCLUDE generated/output_format.ld
ENTRY(_start)
INCLUDE generated/regions.ld
/* First 128K of main memory are reserved for runtime code/data
* then comes kernel memory. First 8K of kernel memory are for support code.
*/
MEMORY {
ksupport : ORIGIN = 0x40020000, LENGTH = 0x2000
}
/* Then comes the payload. */
PROVIDE(kmain = ORIGIN(ksupport) + LENGTH(ksupport));
/* On biprocessor systems, kernel stack is at the end of main RAM,
* before the runtime stack. Leave 1M for runtime stack.
*/
PROVIDE(_fstack = 0x40000000 + LENGTH(main_ram) - 1024*1024 - 4);
SECTIONS
{
.text :
{
_ftext = .;
*(.text .stub .text.* .gnu.linkonce.t.*)
_etext = .;
} > ksupport
.rodata :
{
. = ALIGN(4);
_frodata = .;
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
_erodata = .;
} > ksupport
.data :
{
. = ALIGN(4);
_fdata = .;
*(.data .data.* .gnu.linkonce.d.*)
*(.data1)
_gp = ALIGN(16);
*(.sdata .sdata.* .gnu.linkonce.s.*)
_edata = .;
} > ksupport
.bss :
{
. = ALIGN(4);
_fbss = .;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
. = ALIGN(8);
_heapstart = .;
} > ksupport
}

View File

@ -10,18 +10,17 @@
#include "test_mode.h" #include "test_mode.h"
#include "comm.h" #include "comm.h"
#include "elf_loader.h" #include "elf_loader.h"
#include "kernelcpu.h"
#include "exceptions.h" #include "exceptions.h"
#include "services.h" #include "services.h"
#include "rtio.h" #include "rtio.h"
#include "dds.h" #include "dds.h"
static struct symbol symtab[128]; static struct symbol symtab[128];
static int _symtab_count; static int _symtab_count;
static char _symtab_strings[128*16]; static char _symtab_strings[128*16];
static char *_symtab_strptr; static char *_symtab_strptr;
static void symtab_init(void) static void symtab_init(void)
{ {
memset(symtab, 0, sizeof(symtab)); memset(symtab, 0, sizeof(symtab));
@ -132,7 +131,11 @@ int main(void)
irq_setie(1); irq_setie(1);
uart_init(); uart_init();
puts("ARTIQ runtime built "__DATE__" "__TIME__"\n"); #ifdef CSR_KERNEL_CPU_BASE
puts("ARTIQ runtime built "__DATE__" "__TIME__" for biprocessor systems\n");
#else
puts("ARTIQ runtime built "__DATE__" "__TIME__" for uniprocessor systems\n");
#endif
blink_led(); blink_led();
if(check_test_mode()) { if(check_test_mode()) {

View File

@ -305,30 +305,6 @@ static char *get_token(char **str)
return d; return d;
} }
#ifdef CSR_KERNEL_CPU_BASE
static const unsigned int test_program[] = {
0x1860dead, // l.movhi r3,0xdead
0x1880d000, // l.movhi r4,0xd000
0xa863beef, // l.ori r3,r3,0xbeef
0xd4041800, // l.sw 0(r4),r3
0x00000000, // l.j +0
0x15000000, // l.nop
};
static void cputest(void)
{
int i;
kernel_cpu_reset_write(1);
MMPTR(0xd0000000) = 0;
memcpy((void *)0x41000000, test_program, sizeof(test_program));
flush_l2_cache();
kernel_cpu_reset_write(0);
for(i=0;i<10;i++)
printf("%08x\n", MMPTR(0xd0000000));
}
#endif
static void do_command(char *c) static void do_command(char *c)
{ {
char *token; char *token;
@ -351,10 +327,6 @@ static void do_command(char *c)
else if(strcmp(token, "ddsftw") == 0) ddsftw(get_token(&c), get_token(&c)); else if(strcmp(token, "ddsftw") == 0) ddsftw(get_token(&c), get_token(&c));
else if(strcmp(token, "ddstest") == 0) ddstest(get_token(&c)); else if(strcmp(token, "ddstest") == 0) ddstest(get_token(&c));
#ifdef CSR_KERNEL_CPU_BASE
else if(strcmp(token, "cputest") == 0) cputest();
#endif
else if(strcmp(token, "") != 0) else if(strcmp(token, "") != 0)
printf("Command not found\n"); printf("Command not found\n");
} }