diff --git a/soc/runtime/Makefile b/soc/runtime/Makefile index 03b096b8e..a4513cb4a 100644 --- a/soc/runtime/Makefile +++ b/soc/runtime/Makefile @@ -3,7 +3,7 @@ include $(MSCDIR)/software/common.mak BOARD=papilio_pro 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 @@ -12,7 +12,7 @@ all: runtime.bin %.bin: %.elf $(OBJCOPY) -O binary $< $@ - chmod -x $@ + @chmod -x $@ %.fbi: %.bin $(MSCDIR)/mkmscimg.py -f -o $@ $< @@ -28,7 +28,18 @@ runtime.elf: $(OBJECTS) libs -L$(MSCDIR)/software/libbase \ -L$(MSCDIR)/software/libcompiler-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 $(compile-dep) @@ -52,5 +63,6 @@ flash: runtime.fbi clean: $(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 diff --git a/soc/runtime/kernelcpu.c b/soc/runtime/kernelcpu.c new file mode 100644 index 000000000..671e3eae2 --- /dev/null +++ b/soc/runtime/kernelcpu.c @@ -0,0 +1,27 @@ +#include + +#ifdef CSR_KERNEL_CPU_BASE + +#include +#include +#include + +#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 */ diff --git a/soc/runtime/kernelcpu.h b/soc/runtime/kernelcpu.h new file mode 100644 index 000000000..5b64ff0d7 --- /dev/null +++ b/soc/runtime/kernelcpu.h @@ -0,0 +1,14 @@ +#ifndef __KERNELCPU_H +#define __KERNELCPU_H + +#include + +#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 */ diff --git a/soc/runtime/ksupport.c b/soc/runtime/ksupport.c new file mode 100644 index 000000000..08d74fe10 --- /dev/null +++ b/soc/runtime/ksupport.c @@ -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; +} diff --git a/soc/runtime/ksupport.ld b/soc/runtime/ksupport.ld new file mode 100644 index 000000000..723b1bd0c --- /dev/null +++ b/soc/runtime/ksupport.ld @@ -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 +} diff --git a/soc/runtime/main.c b/soc/runtime/main.c index 587e3e453..47f21e4ac 100644 --- a/soc/runtime/main.c +++ b/soc/runtime/main.c @@ -10,18 +10,17 @@ #include "test_mode.h" #include "comm.h" #include "elf_loader.h" +#include "kernelcpu.h" #include "exceptions.h" #include "services.h" #include "rtio.h" #include "dds.h" - static struct symbol symtab[128]; static int _symtab_count; static char _symtab_strings[128*16]; static char *_symtab_strptr; - static void symtab_init(void) { memset(symtab, 0, sizeof(symtab)); @@ -132,7 +131,11 @@ int main(void) irq_setie(1); 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(); if(check_test_mode()) { diff --git a/soc/runtime/test_mode.c b/soc/runtime/test_mode.c index 8df03c313..f132e1092 100644 --- a/soc/runtime/test_mode.c +++ b/soc/runtime/test_mode.c @@ -305,30 +305,6 @@ static char *get_token(char **str) 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) { 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, "ddstest") == 0) ddstest(get_token(&c)); -#ifdef CSR_KERNEL_CPU_BASE - else if(strcmp(token, "cputest") == 0) cputest(); -#endif - else if(strcmp(token, "") != 0) printf("Command not found\n"); }