mirror of
https://github.com/m-labs/artiq.git
synced 2024-12-25 03:08:27 +08:00
runtime: biprocessor support (incomplete, WIP)
This commit is contained in:
parent
277e038569
commit
cbdc1ba46f
@ -1,9 +1,21 @@
|
||||
include $(MSCDIR)/software/common.mak
|
||||
|
||||
BOARD=papilio_pro
|
||||
SERIAL=/dev/ttyUSB1
|
||||
OBJECTS_SERVICES=exception_jmp.o exceptions.o rtio.o dds.o
|
||||
OBJECTS=isr.o elf_loader.o services.o comm_serial.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
|
||||
UNIPROCESSOR := $(shell echo -e "\#include <generated/csr.h>\nCSR_KERNEL_CPU_BASE" | $(CC_normal) $(CFLAGS) -E - | tail -n 1 | grep -c CSR_KERNEL_CPU_BASE)
|
||||
|
||||
ifeq ($(UNIPROCESSOR),0)
|
||||
OBJECTS += kernelcpu.o ksupport_data.o
|
||||
CFLAGS += -DARTIQ_BIPROCESSOR
|
||||
SERVICE_TABLE_INPUT = ksupport.elf
|
||||
else
|
||||
ifeq ($(UNIPROCESSOR),1)
|
||||
OBJECTS += $(OBJECTS_SERVICES)
|
||||
else
|
||||
$(error failed to determine uniprocessor/biprocessor build)
|
||||
endif
|
||||
endif
|
||||
|
||||
all: runtime.bin
|
||||
|
||||
@ -30,17 +42,22 @@ runtime.elf: $(OBJECTS) libs
|
||||
-lbase -lcompiler-rt
|
||||
@chmod -x $@
|
||||
|
||||
ksupport.elf: ksupport.o
|
||||
ksupport.elf: $(OBJECTS_SERVICES) 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 $@ $<
|
||||
|
||||
service_table.h: $(SERVICE_TABLE_INPUT)
|
||||
@echo " GEN " $@ && ./gen_service_table.py $(SERVICE_TABLE_INPUT) > $@
|
||||
|
||||
services.c: service_table.h
|
||||
|
||||
main.o: main.c
|
||||
$(compile-dep)
|
||||
|
||||
@ -54,15 +71,9 @@ libs:
|
||||
$(MAKE) -C $(MSCDIR)/software/libcompiler-rt
|
||||
$(MAKE) -C $(MSCDIR)/software/libbase
|
||||
|
||||
load: runtime.bin
|
||||
$(MAKE) -C $(MSCDIR)/tools
|
||||
$(MSCDIR)/tools/flterm --port $(SERIAL) --kernel runtime.bin
|
||||
|
||||
flash: runtime.fbi
|
||||
$(MSCDIR)/flash_extra.py $(BOARD) runtime.fbi 0x70000
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJECTS) $(OBJECTS:.o=.d) runtime.elf runtime.bin runtime.fbi .*~ *~
|
||||
$(RM) ksupport.d ksupport.o ksupport.elf ksupport.bin
|
||||
$(RM) $(OBJECTS) $(OBJECTS:.o=.d) $(OBJECTS_SERVICES) $(OBJECTS_SERVICES:.o=.d)
|
||||
$(RM) runtime.elf runtime.bin runtime.fbi .*~ *~
|
||||
$(RM) service_table.h ksupport.d ksupport.o ksupport.elf ksupport.bin
|
||||
|
||||
.PHONY: all main.o clean libs load
|
||||
|
@ -151,7 +151,12 @@ static void receive_and_run_kernel(kernel_runner run_kernel)
|
||||
send_char(MSGTYPE_KERNEL_EXCEPTION);
|
||||
send_int(eid);
|
||||
for(i=0;i<3;i++)
|
||||
#ifdef ARTIQ_BIPROCESSOR
|
||||
#warning TODO
|
||||
send_llint(0LL);
|
||||
#else
|
||||
send_llint(exception_params[i]);
|
||||
#endif
|
||||
break;
|
||||
case KERNEL_RUN_STARTUP_FAILED:
|
||||
send_char(MSGTYPE_KERNEL_STARTUP_FAILED);
|
||||
@ -172,9 +177,16 @@ void comm_serve(object_loader load_object, kernel_runner run_kernel)
|
||||
if(msgtype == MSGTYPE_REQUEST_IDENT) {
|
||||
send_char(MSGTYPE_IDENT);
|
||||
send_int(0x41524f52); /* "AROR" - ARTIQ runtime on OpenRISC */
|
||||
#ifdef ARTIQ_BIPROCESSOR
|
||||
#warning TODO
|
||||
send_int(125*1000*1000);
|
||||
send_char(0);
|
||||
send_char(1);
|
||||
#else
|
||||
send_int(rtio_frequency_i_read());
|
||||
send_char(rtio_frequency_fn_read());
|
||||
send_char(rtio_frequency_fd_read());
|
||||
#endif
|
||||
} else if(msgtype == MSGTYPE_LOAD_OBJECT)
|
||||
receive_and_load_object(load_object);
|
||||
else if(msgtype == MSGTYPE_RUN_KERNEL)
|
||||
@ -253,8 +265,12 @@ int comm_rpc(int rpc_num, ...)
|
||||
eid = receive_int();
|
||||
retval = receive_int();
|
||||
|
||||
#ifdef ARTIQ_BIPROCESSOR
|
||||
#warning TODO
|
||||
#else
|
||||
if(eid != EID_NONE)
|
||||
exception_raise(eid);
|
||||
#endif
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
#include <generated/csr.h>
|
||||
|
||||
#include "exceptions.h"
|
||||
#ifndef ARTIQ_BIPROCESSOR
|
||||
#include "comm.h"
|
||||
#endif
|
||||
|
||||
#define MAX_EXCEPTION_CONTEXTS 64
|
||||
|
||||
@ -45,7 +49,11 @@ void exception_raise_params(int id,
|
||||
exception_params[2] = p2;
|
||||
exception_longjmp(exception_contexts[--ec_top].jb);
|
||||
} else {
|
||||
#ifdef ARTIQ_BIPROCESSOR
|
||||
#warning TODO
|
||||
#else
|
||||
comm_log("ERROR: uncaught exception, ID=%d\n", id);
|
||||
#endif
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
62
soc/runtime/gen_service_table.py
Executable file
62
soc/runtime/gen_service_table.py
Executable file
@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
services = [
|
||||
("syscalls", [
|
||||
("rpc", "comm_rpc"),
|
||||
("rtio_oe", "rtio_oe"),
|
||||
("rtio_set", "rtio_set"),
|
||||
("rtio_get_counter", "rtio_get_counter"),
|
||||
("rtio_get", "rtio_get"),
|
||||
("rtio_pileup_count", "rtio_pileup_count"),
|
||||
("dds_phase_clear_en", "dds_phase_clear_en"),
|
||||
("dds_program", "dds_program"),
|
||||
]),
|
||||
("eh", [
|
||||
("setjmp", "exception_setjmp"),
|
||||
("push", "exception_push"),
|
||||
("pop", "exception_pop"),
|
||||
("getid", "exception_getid"),
|
||||
("raise", "exception_raise"),
|
||||
])
|
||||
]
|
||||
|
||||
|
||||
def print_uniprocessor():
|
||||
for name, contents in services:
|
||||
print("static const struct symbol {}[] = {{".format(name))
|
||||
for name, value in contents:
|
||||
print(" {{\"{}\", {}}},".format(name, value))
|
||||
print(" {NULL, NULL}")
|
||||
print("};")
|
||||
|
||||
|
||||
def print_biprocessor(ksupport_elf_filename):
|
||||
from elftools.elf.elffile import ELFFile
|
||||
with open(ksupport_elf_filename, "rb") as f:
|
||||
elf = ELFFile(f)
|
||||
symtab = elf.get_section_by_name(b".symtab")
|
||||
symbols = {symbol.name: symbol.entry.st_value
|
||||
for symbol in symtab.iter_symbols()}
|
||||
for name, contents in services:
|
||||
print("static const struct symbol {}[] = {{".format(name))
|
||||
for name, value in contents:
|
||||
print(" {{\"{}\", (void *)0x{:08x}}},"
|
||||
.format(name, symbols[bytes(value, "ascii")]))
|
||||
print(" {NULL, NULL}")
|
||||
print("};")
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) == 1:
|
||||
print_uniprocessor()
|
||||
elif len(sys.argv) == 2:
|
||||
print_biprocessor(sys.argv[1])
|
||||
else:
|
||||
print("Incorrect number of command line arguments")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,14 +0,0 @@
|
||||
#include <generated/csr.h>
|
||||
|
||||
#include "gpio.h"
|
||||
|
||||
void gpio_set(int channel, int value)
|
||||
{
|
||||
static int csr_value;
|
||||
|
||||
if(value)
|
||||
csr_value |= 1 << channel;
|
||||
else
|
||||
csr_value &= ~(1 << channel);
|
||||
leds_out_write(csr_value);
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#ifndef __GPIO_H
|
||||
#define __GPIO_H
|
||||
|
||||
void gpio_set(int channel, int value);
|
||||
|
||||
#endif /* __GPIO_H */
|
@ -1,20 +1,19 @@
|
||||
#include <generated/csr.h>
|
||||
|
||||
#ifdef CSR_KERNEL_CPU_BASE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <system.h>
|
||||
|
||||
#include <generated/csr.h>
|
||||
|
||||
#include "kernelcpu.h"
|
||||
|
||||
extern char _binary_ksupport_bin_start;
|
||||
extern char _binary_ksupport_bin_end;
|
||||
|
||||
void kernelcpu_start(void)
|
||||
void kernelcpu_start(void *addr)
|
||||
{
|
||||
memcpy((void *)KERNELCPU_EXEC_ADDRESS, &_binary_ksupport_bin_start,
|
||||
&_binary_ksupport_bin_end - &_binary_ksupport_bin_start);
|
||||
KERNELCPU_MAILBOX = (unsigned int)addr;
|
||||
flush_l2_cache();
|
||||
kernel_cpu_reset_write(0);
|
||||
}
|
||||
@ -23,5 +22,3 @@ void kernelcpu_stop(void)
|
||||
{
|
||||
kernel_cpu_reset_write(1);
|
||||
}
|
||||
|
||||
#endif /* CSR_KERNEL_CPU_BASE */
|
||||
|
@ -4,11 +4,11 @@
|
||||
#include <hw/common.h>
|
||||
|
||||
#define KERNELCPU_EXEC_ADDRESS 0x40020000
|
||||
#define KERNELCPU_KMAIN_ADDRESS 0x40022000
|
||||
#define KERNELCPU_PAYLOAD_ADDRESS 0x40024000
|
||||
|
||||
#define KERNELCPU_MAILBOX MMPTR(0xd0000000)
|
||||
|
||||
void kernelcpu_start(void);
|
||||
void kernelcpu_start(void *addr);
|
||||
void kernelcpu_stop(void);
|
||||
|
||||
#endif /* __KERNELCPU_H */
|
||||
|
@ -1,3 +1,9 @@
|
||||
#include "kernelcpu.h"
|
||||
#include "exceptions.h"
|
||||
#include "comm.h"
|
||||
#include "rtio.h"
|
||||
#include "dds.h"
|
||||
|
||||
void exception_handler(unsigned long vect, unsigned long *sp);
|
||||
void exception_handler(unsigned long vect, unsigned long *sp)
|
||||
{
|
||||
@ -5,12 +11,32 @@ void exception_handler(unsigned long vect, unsigned long *sp)
|
||||
for(;;);
|
||||
}
|
||||
|
||||
extern void kmain(void);
|
||||
typedef void (*kernel_function)(void);
|
||||
|
||||
int main(void);
|
||||
int main(void)
|
||||
{
|
||||
kmain();
|
||||
/* TODO: report end of kernel to comm CPU */
|
||||
kernel_function k;
|
||||
void *jb;
|
||||
|
||||
k = (kernel_function)KERNELCPU_MAILBOX;
|
||||
|
||||
jb = exception_push();
|
||||
if(exception_setjmp(jb))
|
||||
KERNELCPU_MAILBOX = KERNEL_RUN_EXCEPTION;
|
||||
else {
|
||||
dds_init();
|
||||
rtio_init();
|
||||
k();
|
||||
exception_pop(1);
|
||||
KERNELCPU_MAILBOX = KERNEL_RUN_FINISHED;
|
||||
}
|
||||
while(1);
|
||||
}
|
||||
|
||||
int comm_rpc(int rpc_num, ...);
|
||||
int comm_rpc(int rpc_num, ...)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
@ -4,15 +4,12 @@ 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.
|
||||
* then comes kernel memory. First 16K of kernel memory are for support code.
|
||||
*/
|
||||
MEMORY {
|
||||
ksupport : ORIGIN = 0x40020000, LENGTH = 0x2000
|
||||
ksupport : ORIGIN = 0x40020000, LENGTH = 0x4000
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
@ -12,10 +12,7 @@ MEMORY {
|
||||
|
||||
/* Kernel memory space start right after the runtime,
|
||||
* and ends before the runtime stack.
|
||||
*/
|
||||
PROVIDE(_kmem = 0x40020000);
|
||||
|
||||
/* Runtime stack is always at the end of main_ram.
|
||||
* Runtime stack is always at the end of main_ram.
|
||||
* This stack is shared with the kernel on uniprocessor systems.
|
||||
*/
|
||||
PROVIDE(_fstack = 0x40000000 + LENGTH(main_ram) - 4);
|
||||
|
@ -55,14 +55,12 @@ static int symtab_add(const char *name, void *target)
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern int _kmem;
|
||||
|
||||
static int load_object(void *buffer, int length)
|
||||
{
|
||||
symtab_init();
|
||||
return load_elf(
|
||||
resolve_service_symbol, symtab_add,
|
||||
buffer, length, &_kmem, 2*1024*1024);
|
||||
buffer, length, (void *)KERNELCPU_PAYLOAD_ADDRESS, 4*1024*1024);
|
||||
}
|
||||
|
||||
typedef void (*kernel_function)(void);
|
||||
@ -70,7 +68,9 @@ typedef void (*kernel_function)(void);
|
||||
static int run_kernel(const char *kernel_name, int *eid)
|
||||
{
|
||||
kernel_function k;
|
||||
#ifndef ARTIQ_BIPROCESSOR
|
||||
void *jb;
|
||||
#endif
|
||||
|
||||
k = find_symbol(symtab, kernel_name);
|
||||
if(k == NULL) {
|
||||
@ -78,17 +78,32 @@ static int run_kernel(const char *kernel_name, int *eid)
|
||||
return KERNEL_RUN_STARTUP_FAILED;
|
||||
}
|
||||
|
||||
#ifdef ARTIQ_BIPROCESSOR
|
||||
kernelcpu_start(k);
|
||||
*eid = 0;
|
||||
while(1) {
|
||||
unsigned int r;
|
||||
|
||||
r = KERNELCPU_MAILBOX;
|
||||
if(r < 0x40000000) {
|
||||
kernelcpu_stop();
|
||||
return r;
|
||||
}
|
||||
}
|
||||
#else
|
||||
jb = exception_push();
|
||||
if(exception_setjmp(jb)) {
|
||||
*eid = exception_getid();
|
||||
return KERNEL_RUN_EXCEPTION;
|
||||
} else {
|
||||
dds_init();
|
||||
rtio_init();
|
||||
flush_cpu_icache();
|
||||
k();
|
||||
exception_pop(1);
|
||||
return KERNEL_RUN_FINISHED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void blink_led(void)
|
||||
@ -131,7 +146,7 @@ int main(void)
|
||||
irq_setie(1);
|
||||
uart_init();
|
||||
|
||||
#ifdef CSR_KERNEL_CPU_BASE
|
||||
#ifdef ARTIQ_BIPROCESSOR
|
||||
puts("ARTIQ runtime built "__DATE__" "__TIME__" for biprocessor systems\n");
|
||||
#else
|
||||
puts("ARTIQ runtime built "__DATE__" "__TIME__" for uniprocessor systems\n");
|
||||
@ -143,7 +158,6 @@ int main(void)
|
||||
test_main();
|
||||
} else {
|
||||
puts("Entering regular mode.");
|
||||
dds_init();
|
||||
comm_serve(load_object, run_kernel);
|
||||
}
|
||||
return 0;
|
||||
|
19
soc/runtime/service_table.h
Normal file
19
soc/runtime/service_table.h
Normal file
@ -0,0 +1,19 @@
|
||||
static const struct symbol syscalls[] = {
|
||||
{"rpc", (void *)0x40021ab0},
|
||||
{"rtio_oe", (void *)0x40021478},
|
||||
{"rtio_set", (void *)0x400214d4},
|
||||
{"rtio_get_counter", (void *)0x400214a0},
|
||||
{"rtio_get", (void *)0x400215ec},
|
||||
{"rtio_pileup_count", (void *)0x400216f4},
|
||||
{"dds_phase_clear_en", (void *)0x400218a4},
|
||||
{"dds_program", (void *)0x40021960},
|
||||
{NULL, NULL}
|
||||
};
|
||||
static const struct symbol eh[] = {
|
||||
{"setjmp", (void *)0x40021248},
|
||||
{"push", (void *)0x400213c8},
|
||||
{"pop", (void *)0x400212c0},
|
||||
{"getid", (void *)0x400212e8},
|
||||
{"raise", (void *)0x4002139c},
|
||||
{NULL, NULL}
|
||||
};
|
@ -2,33 +2,12 @@
|
||||
|
||||
#include "elf_loader.h"
|
||||
#include "comm.h"
|
||||
#include "gpio.h"
|
||||
#include "rtio.h"
|
||||
#include "dds.h"
|
||||
#include "exceptions.h"
|
||||
#include "services.h"
|
||||
|
||||
static const struct symbol syscalls[] = {
|
||||
{"rpc", comm_rpc},
|
||||
{"gpio_set", gpio_set},
|
||||
{"rtio_oe", rtio_oe},
|
||||
{"rtio_set", rtio_set},
|
||||
{"rtio_get_counter", rtio_get_counter},
|
||||
{"rtio_get", rtio_get},
|
||||
{"rtio_pileup_count", rtio_pileup_count},
|
||||
{"dds_phase_clear_en", dds_phase_clear_en},
|
||||
{"dds_program", dds_program},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static const struct symbol eh[] = {
|
||||
{"setjmp", exception_setjmp},
|
||||
{"push", exception_push},
|
||||
{"pop", exception_pop},
|
||||
{"getid", exception_getid},
|
||||
{"raise", exception_raise},
|
||||
{NULL, NULL}
|
||||
};
|
||||
#include "service_table.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wimplicit-int"
|
||||
|
@ -11,6 +11,17 @@
|
||||
#include "rtio.h"
|
||||
#include "dds.h"
|
||||
|
||||
#ifdef ARTIQ_BIPROCESSOR
|
||||
|
||||
#warning TODO
|
||||
|
||||
void test_main(void)
|
||||
{
|
||||
printf("Not implemented yet for biprocessor systems\n");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void leds(char *value)
|
||||
{
|
||||
char *c;
|
||||
@ -341,3 +352,5 @@ void test_main(void)
|
||||
do_command(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ARTIQ_BIPROCESSOR */
|
||||
|
Loading…
Reference in New Issue
Block a user